{
  "scope": "Verbatim complete source files containing copyright/licensing indicators. Includes inactive package sources conservatively; source comments are not rewritten or treated as new grants.",
  "sources": [
    {
      "package": "adler32@1.2.0",
      "sourcePath": "src/lib.rs",
      "sha256": "4f203fd48b12052f950213249a55db0b1c6cde93fe3bdf26b70a6eb42c6c9dee",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "//! A minimal implementation of Adler32 for Rust.\n//!\n//! This provides the simple method adler32(), that exhausts a Read and\n//! computes the Adler32 hash, as well as the RollingAdler32 struct, that can\n//! build a hash byte-by-byte, allowing to 'forget' past bytes in a rolling\n//! fashion.\n//!\n//! The adler32 code has been translated (as accurately as I could manage) from\n//! the zlib implementation.\n\n#![forbid(unsafe_code)]\n#![cfg_attr(not(feature = \"std\"), no_std)]\n\n\n// adler32 algorithm and implementation taken from zlib; http://www.zlib.net/\n// It was translated into Rust as accurately as I could manage\n// The (slow) reference was taken from Wikipedia; https://en.wikipedia.org/\n\n/* zlib.h -- interface of the 'zlib' general purpose compression library\n  version 1.2.8, April 28th, 2013\n\n  Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Jean-loup Gailly        Mark Adler\n  jloup@gzip.org          madler@alumni.caltech.edu\n\n*/\n\n// largest prime smaller than 65536\nconst BASE: u32 = 65521;\n\n// NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1\nconst NMAX: usize = 5552;\n\n#[inline(always)]\nfn do1(adler: &mut u32, sum2: &mut u32, buf: &[u8]) {\n    *adler += u32::from(buf[0]);\n    *sum2 += *adler;\n}\n\n#[inline(always)]\nfn do2(adler: &mut u32, sum2: &mut u32, buf: &[u8]) {\n    do1(adler, sum2, &buf[0..1]);\n    do1(adler, sum2, &buf[1..2]);\n}\n\n#[inline(always)]\nfn do4(adler: &mut u32, sum2: &mut u32, buf: &[u8]) {\n    do2(adler, sum2, &buf[0..2]);\n    do2(adler, sum2, &buf[2..4]);\n}\n\n#[inline(always)]\nfn do8(adler: &mut u32, sum2: &mut u32, buf: &[u8]) {\n    do4(adler, sum2, &buf[0..4]);\n    do4(adler, sum2, &buf[4..8]);\n}\n\n#[inline(always)]\nfn do16(adler: &mut u32, sum2: &mut u32, buf: &[u8]) {\n    do8(adler, sum2, &buf[0..8]);\n    do8(adler, sum2, &buf[8..16]);\n}\n\n/// A rolling version of the Adler32 hash, which can 'forget' past bytes.\n///\n/// Calling remove() will update the hash to the value it would have if that\n/// past byte had never been fed to the algorithm. This allows you to get the\n/// hash of a rolling window very efficiently.\n#[derive(Clone)]\npub struct RollingAdler32 {\n    a: u32,\n    b: u32,\n}\n\nimpl Default for RollingAdler32 {\n    fn default() -> RollingAdler32 {\n        RollingAdler32::new()\n    }\n}\n\nimpl RollingAdler32 {\n    /// Creates an empty Adler32 context (with hash 1).\n    pub fn new() -> RollingAdler32 {\n        Self::from_value(1)\n    }\n\n    /// Creates an Adler32 context with the given initial value.\n    pub fn from_value(adler32: u32) -> RollingAdler32 {\n        let a = adler32 & 0xFFFF;\n        let b = adler32 >> 16;\n        RollingAdler32 { a, b }\n    }\n\n    /// Convenience function initializing a context from the hash of a buffer.\n    pub fn from_buffer(buffer: &[u8]) -> RollingAdler32 {\n        let mut hash = RollingAdler32::new();\n        hash.update_buffer(buffer);\n        hash\n    }\n\n    /// Returns the current hash.\n    pub fn hash(&self) -> u32 {\n        (self.b << 16) | self.a\n    }\n\n    /// Removes the given `byte` that was fed to the algorithm `size` bytes ago.\n    pub fn remove(&mut self, size: usize, byte: u8) {\n        let byte = u32::from(byte);\n        self.a = (self.a + BASE - byte) % BASE;\n        self.b = ((self.b + BASE - 1)\n            .wrapping_add(BASE.wrapping_sub(size as u32).wrapping_mul(byte)))\n            % BASE;\n    }\n\n    /// Feeds a new `byte` to the algorithm to update the hash.\n    pub fn update(&mut self, byte: u8) {\n        let byte = u32::from(byte);\n        self.a = (self.a + byte) % BASE;\n        self.b = (self.b + self.a) % BASE;\n    }\n\n    /// Feeds a vector of bytes to the algorithm to update the hash.\n    pub fn update_buffer(&mut self, buffer: &[u8]) {\n        let len = buffer.len();\n\n        // in case user likes doing a byte at a time, keep it fast\n        if len == 1 {\n            self.update(buffer[0]);\n            return;\n        }\n\n        // in case short lengths are provided, keep it somewhat fast\n        if len < 16 {\n            for byte in buffer.iter().take(len) {\n                self.a += u32::from(*byte);\n                self.b += self.a;\n            }\n            if self.a >= BASE {\n                self.a -= BASE;\n            }\n            self.b %= BASE;\n            return;\n        }\n\n        let mut pos = 0;\n\n        // do length NMAX blocks -- requires just one modulo operation;\n        while pos + NMAX <= len {\n            let end = pos + NMAX;\n            while pos < end {\n                // 16 sums unrolled\n                do16(&mut self.a, &mut self.b, &buffer[pos..pos + 16]);\n                pos += 16;\n            }\n            self.a %= BASE;\n            self.b %= BASE;\n        }\n\n        // do remaining bytes (less than NMAX, still just one modulo)\n        if pos < len {\n            // avoid modulos if none remaining\n            while len - pos >= 16 {\n                do16(&mut self.a, &mut self.b, &buffer[pos..pos + 16]);\n                pos += 16;\n            }\n            while len - pos > 0 {\n                self.a += u32::from(buffer[pos]);\n                self.b += self.a;\n                pos += 1;\n            }\n            self.a %= BASE;\n            self.b %= BASE;\n        }\n    }\n}\n\n/// Consume a Read object and returns the Adler32 hash.\n#[cfg(feature = \"std\")]\npub fn adler32<R: std::io::Read>(mut reader: R) -> std::io::Result<u32> {\n    let mut hash = RollingAdler32::new();\n    let mut buffer = [0u8; NMAX];\n    let mut read = reader.read(&mut buffer)?;\n    while read > 0 {\n        hash.update_buffer(&buffer[..read]);\n        read = reader.read(&mut buffer)?;\n    }\n    Ok(hash.hash())\n}\n\n#[cfg(test)]\nmod test {\n    use rand::Rng;\n    use std::io;\n    #[cfg(target_arch = \"wasm32\")]\n    use wasm_bindgen_test::wasm_bindgen_test;\n\n    use super::{adler32, RollingAdler32, BASE};\n\n    fn adler32_slow<R: io::Read>(reader: R) -> io::Result<u32> {\n        let mut a: u32 = 1;\n        let mut b: u32 = 0;\n\n        for byte in reader.bytes() {\n            let byte = byte? as u32;\n            a = (a + byte) % BASE;\n            b = (b + a) % BASE;\n        }\n\n        Ok((b << 16) | a)\n    }\n\n    #[test]\n    #[cfg_attr(target_arch = \"wasm32\", wasm_bindgen_test)]\n    fn testvectors() {\n        fn do_test(v: u32, bytes: &[u8]) {\n            let mut hash = RollingAdler32::new();\n            hash.update_buffer(&bytes);\n            assert_eq!(hash.hash(), v);\n\n            let r = io::Cursor::new(bytes);\n            assert_eq!(adler32(r).unwrap(), v);\n        }\n        do_test(0x00000001, b\"\");\n        do_test(0x00620062, b\"a\");\n        do_test(0x024d0127, b\"abc\");\n        do_test(0x29750586, b\"message digest\");\n        do_test(0x90860b20, b\"abcdefghijklmnopqrstuvwxyz\");\n        do_test(\n            0x8adb150c,\n            b\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\\\n                              abcdefghijklmnopqrstuvwxyz\\\n                              0123456789\",\n        );\n        do_test(\n            0x97b61069,\n            b\"1234567890123456789012345678901234567890\\\n                              1234567890123456789012345678901234567890\",\n        );\n        do_test(0xD6251498, &[255; 64000]);\n    }\n\n    #[test]\n    #[cfg_attr(target_arch = \"wasm32\", wasm_bindgen_test)]\n    fn compare() {\n        let mut rng = rand::thread_rng();\n        let mut data = vec![0u8; 5589];\n        for size in [\n            0, 1, 3, 4, 5, 31, 32, 33, 67, 5550, 5552, 5553, 5568, 5584, 5589,\n        ]\n        .iter()\n        .cloned()\n        {\n            rng.fill(&mut data[..size]);\n            let r1 = io::Cursor::new(&data[..size]);\n            let r2 = r1.clone();\n            if adler32_slow(r1).unwrap() != adler32(r2).unwrap() {\n                panic!(\"Comparison failed, size={}\", size);\n            }\n        }\n    }\n\n    #[test]\n    #[cfg_attr(target_arch = \"wasm32\", wasm_bindgen_test)]\n    fn rolling() {\n        assert_eq!(RollingAdler32::from_value(0x01020304).hash(), 0x01020304);\n\n        fn do_test(a: &[u8], b: &[u8]) {\n            let mut total = Vec::with_capacity(a.len() + b.len());\n            total.extend(a);\n            total.extend(b);\n            let mut h = RollingAdler32::from_buffer(&total[..(b.len())]);\n            for i in 0..(a.len()) {\n                h.remove(b.len(), a[i]);\n                h.update(total[b.len() + i]);\n            }\n            assert_eq!(h.hash(), adler32(b).unwrap());\n        }\n        do_test(b\"a\", b\"b\");\n        do_test(b\"\", b\"this a test\");\n        do_test(b\"th\", b\"is a test\");\n        do_test(b\"this a \", b\"test\");\n    }\n\n    #[test]\n    #[cfg_attr(target_arch = \"wasm32\", wasm_bindgen_test)]\n    fn long_window_remove() {\n        let mut hash = RollingAdler32::new();\n        let w = 65536;\n        assert!(w as u32 > BASE);\n\n        let mut bytes = vec![0; w * 3];\n        for (i, b) in bytes.iter_mut().enumerate() {\n            *b = i as u8;\n        }\n\n        for (i, b) in bytes.iter().enumerate() {\n            if i >= w {\n                hash.remove(w, bytes[i - w]);\n            }\n            hash.update(*b);\n            if i > 0 && i % w == 0 {\n                assert_eq!(hash.hash(), 0x433a8772);\n            }\n        }\n        assert_eq!(hash.hash(), 0xbbba8772);\n    }\n}\n"
    },
    {
      "package": "aho-corasick@1.1.5",
      "sourcePath": "README.md",
      "sha256": "afc4d559a98cf190029af0bf320fc0022725e349cd2a303aac860254e28f3c53",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "aho-corasick\n============\nA library for finding occurrences of many patterns at once with SIMD\nacceleration in some cases. This library provides multiple pattern\nsearch principally through an implementation of the\n[Aho-Corasick algorithm](https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm),\nwhich builds a finite state machine for executing searches in linear time.\nFeatures include case insensitive matching, overlapping matches, fast searching\nvia SIMD and optional full DFA construction and search & replace in streams.\n\n[![Build status](https://github.com/BurntSushi/aho-corasick/workflows/ci/badge.svg)](https://github.com/BurntSushi/aho-corasick/actions)\n[![crates.io](https://img.shields.io/crates/v/aho-corasick.svg)](https://crates.io/crates/aho-corasick)\n\nDual-licensed under MIT or the [UNLICENSE](https://unlicense.org/).\n\n\n### Documentation\n\nhttps://docs.rs/aho-corasick\n\n\n### Usage\n\nRun `cargo add aho-corasick` to automatically add this crate as a dependency\nin your `Cargo.toml` file.\n\n\n### Example: basic searching\n\nThis example shows how to search for occurrences of multiple patterns\nsimultaneously. Each match includes the pattern that matched along with the\nbyte offsets of the match.\n\n```rust\nuse aho_corasick::{AhoCorasick, PatternID};\n\nlet patterns = &[\"apple\", \"maple\", \"Snapple\"];\nlet haystack = \"Nobody likes maple in their apple flavored Snapple.\";\n\nlet ac = AhoCorasick::new(patterns).unwrap();\nlet mut matches = vec![];\nfor mat in ac.find_iter(haystack) {\n    matches.push((mat.pattern(), mat.start(), mat.end()));\n}\nassert_eq!(matches, vec![\n    (PatternID::must(1), 13, 18),\n    (PatternID::must(0), 28, 33),\n    (PatternID::must(2), 43, 50),\n]);\n```\n\n\n### Example: ASCII case insensitivity\n\nThis is like the previous example, but matches `Snapple` case insensitively\nusing `AhoCorasickBuilder`:\n\n```rust\nuse aho_corasick::{AhoCorasick, PatternID};\n\nlet patterns = &[\"apple\", \"maple\", \"snapple\"];\nlet haystack = \"Nobody likes maple in their apple flavored Snapple.\";\n\nlet ac = AhoCorasick::builder()\n    .ascii_case_insensitive(true)\n    .build(patterns)\n    .unwrap();\nlet mut matches = vec![];\nfor mat in ac.find_iter(haystack) {\n    matches.push((mat.pattern(), mat.start(), mat.end()));\n}\nassert_eq!(matches, vec![\n    (PatternID::must(1), 13, 18),\n    (PatternID::must(0), 28, 33),\n    (PatternID::must(2), 43, 50),\n]);\n```\n\n\n### Example: replacing matches in a stream\n\nThis example shows how to execute a search and replace on a stream without\nloading the entire stream into memory first.\n\n```rust,ignore\nuse aho_corasick::AhoCorasick;\n\nlet patterns = &[\"fox\", \"brown\", \"quick\"];\nlet replace_with = &[\"sloth\", \"grey\", \"slow\"];\n\n// In a real example, these might be `std::fs::File`s instead. All you need to\n// do is supply a pair of `std::io::Read` and `std::io::Write` implementations.\nlet rdr = \"The quick brown fox.\";\nlet mut wtr = vec![];\n\nlet ac = AhoCorasick::new(patterns).unwrap();\nac.stream_replace_all(rdr.as_bytes(), &mut wtr, replace_with)\n    .expect(\"stream_replace_all failed\");\nassert_eq!(b\"The slow grey sloth.\".to_vec(), wtr);\n```\n\n\n### Example: finding the leftmost first match\n\nIn the textbook description of Aho-Corasick, its formulation is typically\nstructured such that it reports all possible matches, even when they overlap\nwith another. In many cases, overlapping matches may not be desired, such as\nthe case of finding all successive non-overlapping matches like you might with\na standard regular expression.\n\nUnfortunately the \"obvious\" way to modify the Aho-Corasick algorithm to do\nthis doesn't always work in the expected way, since it will report matches as\nsoon as they are seen. For example, consider matching the regex `Samwise|Sam`\nagainst the text `Samwise`. Most regex engines (that are Perl-like, or\nnon-POSIX) will report `Samwise` as a match, but the standard Aho-Corasick\nalgorithm modified for reporting non-overlapping matches will report `Sam`.\n\nA novel contribution of this library is the ability to change the match\nsemantics of Aho-Corasick (without additional search time overhead) such that\n`Samwise` is reported instead. For example, here's the standard approach:\n\n```rust\nuse aho_corasick::AhoCorasick;\n\nlet patterns = &[\"Samwise\", \"Sam\"];\nlet haystack = \"Samwise\";\n\nlet ac = AhoCorasick::new(patterns).unwrap();\nlet mat = ac.find(haystack).expect(\"should have a match\");\nassert_eq!(\"Sam\", &haystack[mat.start()..mat.end()]);\n```\n\nAnd now here's the leftmost-first version, which matches how a Perl-like\nregex will work:\n\n```rust\nuse aho_corasick::{AhoCorasick, MatchKind};\n\nlet patterns = &[\"Samwise\", \"Sam\"];\nlet haystack = \"Samwise\";\n\nlet ac = AhoCorasick::builder()\n    .match_kind(MatchKind::LeftmostFirst)\n    .build(patterns)\n    .unwrap();\nlet mat = ac.find(haystack).expect(\"should have a match\");\nassert_eq!(\"Samwise\", &haystack[mat.start()..mat.end()]);\n```\n\nIn addition to leftmost-first semantics, this library also supports\nleftmost-longest semantics, which match the POSIX behavior of a regular\nexpression alternation. See `MatchKind` in the docs for more details.\n\n\n### Minimum Rust version policy\n\nThis crate's minimum supported `rustc` version is `1.60.0`.\n\nThe current policy is that the minimum Rust version required to use this crate\ncan be increased in minor version updates. For example, if `crate 1.0` requires\nRust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust\n1.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum\nversion of Rust.\n\nIn general, this crate will be conservative with respect to the minimum\nsupported version of Rust.\n\n\n### FFI bindings\n\n* [G-Research/ahocorasick_rs](https://github.com/G-Research/ahocorasick_rs/)\nis a Python wrapper for this library.\n* [tmikus/ahocorasick_rs](https://github.com/tmikus/ahocorasick_rs) is a Go\n    wrapper for this library.\n"
    },
    {
      "package": "anstream@1.0.0",
      "sourcePath": "README.md",
      "sha256": "7e90b134ad15dc4368d2a27efeb8db9d155dcd0886b72a032ffb367616255807",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# anstream\n\n> A simple cross platform library for writing colored text to a terminal.\n\n*A portmanteau of \"ansi stream\"*\n\n[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation]\n![License](https://img.shields.io/crates/l/anstream.svg)\n[![Crates Status](https://img.shields.io/crates/v/anstream.svg)](https://crates.io/crates/anstream)\n\nSpecialized `stdout` and `stderr` that accept ANSI escape codes and adapt them\nbased on the terminal's capabilities.\n\n`anstream::adapter::strip_str` may also be of interest on its own for low\noverhead stripping of ANSI escape codes.\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/license/mit>)\n\nat your option.\n\n## [Contribute](../../CONTRIBUTING.md)\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual-licensed as above, without any additional terms or\nconditions.\n\n[Crates.io]: https://crates.io/crates/anstream\n[Documentation]: https://docs.rs/anstream\n"
    },
    {
      "package": "anstyle@1.0.14",
      "sourcePath": "README.md",
      "sha256": "015245c48ad8fb28bc4b2ed85a992a6e1182aa7fd633ecaac8f69b229d2aacab",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# anstyle\n\n> ANSI text styling\n\n*A portmanteau of \"ansi style\"*\n\n[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation]\n![License](https://img.shields.io/crates/l/anstyle.svg)\n[![Crates Status](https://img.shields.io/crates/v/anstyle.svg)](https://crates.io/crates/anstyle)\n\n`anstyle` provides core types describing [ANSI styling escape\ncodes](https://en.wikipedia.org/wiki/ANSI_escape_code) for interoperability\nbetween crates.  For example, this would allow a crate to provide an API for\ncustomizing the colors used without putting the underlying text styling crate\nin the API.\n\nFor integration with your text styling crate, see:\n- [anstyle-termcolor](crates/termcolor)\n- [anstyle-owo-colors](crates/owo)\n- [anstyle-yansi](crates/yansi)\n\nGeneral utilities:\n- [anstyle-git](crates/git): Parse Git style descriptions\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/license/mit>)\n\nat your option.\n\n## [Contribute](../../CONTRIBUTING.md)\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual-licensed as above, without any additional terms or\nconditions.\n\n[Crates.io]: https://crates.io/crates/anstyle\n[Documentation]: https://docs.rs/anstyle\n"
    },
    {
      "package": "anstyle-parse@1.0.0",
      "sourcePath": "README.md",
      "sha256": "85c374ff51508a4847ade385c727d5b3d593e374a36e66606543cee390e54963",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# anstyle-parse\n\n> Parse [Parse ANSI Style Escapes](https://vt100.net/emu/dec_ansi_parser)\n\n[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation]\n![License](https://img.shields.io/crates/l/anstyle-parse.svg)\n[![Crates Status](https://img.shields.io/crates/v/anstyle-parse.svg)](https://crates.io/crates/anstyle-parse)\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/license/mit>)\n\nat your option.\n\n## [Contribute](../../CONTRIBUTING.md)\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual-licensed as above, without any additional terms or\nconditions.\n\n### Special Thanks\n\n[chrisduerr](https://github.com/alacritty/vte/commits?author=chrisduerr) and the\n[alacritty project](https://github.com/alacritty/alacritty) for\n[vte](https://crates.io/crates/vte) which\n[this was forked from](https://github.com/alacritty/vte/issues/82)\n\n[Crates.io]: https://crates.io/crates/anstyle-parse\n[Documentation]: https://docs.rs/anstyle-parse\n"
    },
    {
      "package": "anstyle-query@1.1.5",
      "sourcePath": "README.md",
      "sha256": "9ed87a71a298ed4925210e66dd06c69f40600c1df97fd082d1763c2220c9f2f1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# anstyle-query\n\n> **Low level terminal capability lookups**\n\n[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation]\n![License](https://img.shields.io/crates/l/anstyle-query.svg)\n[![Crates Status](https://img.shields.io/crates/v/anstyle-query.svg)](https://crates.io/crates/anstyle-query)\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/license/mit>)\n\nat your option.\n\n## [Contribute](../../CONTRIBUTING.md)\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual-licensed as above, without any additional terms or\nconditions.\n\n[Documentation]: https://docs.rs/anstyle-query\n"
    },
    {
      "package": "anstyle-wincon@3.0.11",
      "sourcePath": "README.md",
      "sha256": "b979881246703593aad26da21f5d467c03c35142d6f5965f7e7253cb89695c9f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# anstyle-wincon\n\n> Styling legacy Windows terminals\n\n[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation]\n![License](https://img.shields.io/crates/l/anstyle-wincon.svg)\n[![Crates Status](https://img.shields.io/crates/v/anstyle-wincon.svg)](https://crates.io/crates/anstyle-wincon)\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/license/mit>)\n\nat your option.\n\n## [Contribute](../../CONTRIBUTING.md)\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual-licensed as above, without any additional terms or\nconditions.\n\n### Special Thanks\n\n[burntsushi](https://github.com/burntsushi) for [termcolor](https://github.com/burntsushi/termcolor) as I don't know Windows either :)\n\n[Crates.io]: https://crates.io/crates/anstyle-wincon\n[Documentation]: https://docs.rs/anstyle-wincon\n"
    },
    {
      "package": "arrayvec@0.5.2",
      "sourcePath": "README.md",
      "sha256": "f42eb73acbc7729825a836a532d1c8c6b71e006e0d87e549ea7a483da7472425",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "\narrayvec\n========\n[![Crates.io: arrayvec](https://img.shields.io/crates/v/arrayvec.svg)](https://crates.io/crates/arrayvec)\n[![Crates.io: nodrop](https://img.shields.io/crates/v/nodrop.svg)](https://crates.io/crates/nodrop)\n[![Documentation](https://docs.rs/arrayvec/badge.svg)](https://docs.rs/arrayvec)\n[![Build Status](https://travis-ci.org/bluss/arrayvec.svg?branch=master)](https://travis-ci.org/bluss/arrayvec)\n[![License: Apache](https://img.shields.io/badge/License-Apache%202.0-red.svg)](LICENSE-APACHE)\nOR\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\nA vector with fixed capacity.\n\nPlease read the [`API documentation here`](https://docs.rs/arrayvec)\n\n# License\n\nDual-licensed to be compatible with the Rust project.\n\nLicensed under the Apache License, Version 2.0\nhttp://www.apache.org/licenses/LICENSE-2.0 or the MIT license\nhttp://opensource.org/licenses/MIT, at your\noption. This file may not be copied, modified, or distributed\nexcept according to those terms.\n"
    },
    {
      "package": "arrayvec@0.5.2",
      "sourcePath": "src/char.rs",
      "sha256": "3fe9e9cc68fc7cedb238d53924b552b876a60c4fea85935d2f5d1ca0d41ffa3e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n//\n// Original authors: alexchrichton, bluss\n\nuse std::ptr;\n\n// UTF-8 ranges and tags for encoding characters\nconst TAG_CONT: u8    = 0b1000_0000;\nconst TAG_TWO_B: u8   = 0b1100_0000;\nconst TAG_THREE_B: u8 = 0b1110_0000;\nconst TAG_FOUR_B: u8  = 0b1111_0000;\nconst MAX_ONE_B: u32   =     0x80;\nconst MAX_TWO_B: u32   =    0x800;\nconst MAX_THREE_B: u32 =  0x10000;\n\n/// Placeholder\npub struct EncodeUtf8Error;\n\n#[inline]\nunsafe fn write(ptr: *mut u8, index: usize, byte: u8) {\n    ptr::write(ptr.add(index), byte)\n}\n\n/// Encode a char into buf using UTF-8.\n///\n/// On success, return the byte length of the encoding (1, 2, 3 or 4).<br>\n/// On error, return `EncodeUtf8Error` if the buffer was too short for the char.\n///\n/// Safety: `ptr` must be writable for `len` bytes.\n#[inline]\npub unsafe fn encode_utf8(ch: char, ptr: *mut u8, len: usize) -> Result<usize, EncodeUtf8Error>\n{\n    let code = ch as u32;\n    if code < MAX_ONE_B && len >= 1 {\n        write(ptr, 0, code as u8);\n        return Ok(1);\n    } else if code < MAX_TWO_B && len >= 2 {\n        write(ptr, 0, (code >> 6 & 0x1F) as u8 | TAG_TWO_B);\n        write(ptr, 1, (code & 0x3F) as u8 | TAG_CONT);\n        return Ok(2);\n    } else if code < MAX_THREE_B && len >= 3 {\n        write(ptr, 0, (code >> 12 & 0x0F) as u8 | TAG_THREE_B);\n        write(ptr, 1, (code >>  6 & 0x3F) as u8 | TAG_CONT);\n        write(ptr, 2, (code & 0x3F) as u8 | TAG_CONT);\n        return Ok(3);\n    } else if len >= 4 {\n        write(ptr, 0, (code >> 18 & 0x07) as u8 | TAG_FOUR_B);\n        write(ptr, 1, (code >> 12 & 0x3F) as u8 | TAG_CONT);\n        write(ptr, 2, (code >>  6 & 0x3F) as u8 | TAG_CONT);\n        write(ptr, 3, (code & 0x3F) as u8 | TAG_CONT);\n        return Ok(4);\n    };\n    Err(EncodeUtf8Error)\n}\n\n\n#[test]\n#[cfg_attr(miri, ignore)] // Miri is too slow\nfn test_encode_utf8() {\n    // Test that all codepoints are encoded correctly\n    let mut data = [0u8; 16];\n    for codepoint in 0..=(std::char::MAX as u32) {\n        if let Some(ch) = std::char::from_u32(codepoint) {\n            for elt in &mut data { *elt = 0; }\n            let ptr = data.as_mut_ptr();\n            let len = data.len();\n            unsafe {\n                let res = encode_utf8(ch, ptr, len).ok().unwrap();\n                assert_eq!(res, ch.len_utf8());\n            }\n            let string = std::str::from_utf8(&data).unwrap();\n            assert_eq!(string.chars().next(), Some(ch));\n        }\n    }\n}\n\n#[test]\nfn test_encode_utf8_oob() {\n    // test that we report oob if the buffer is too short\n    let mut data = [0u8; 16];\n    let chars = ['a', 'α', '�', '𐍈'];\n    for (len, &ch) in (1..=4).zip(&chars) {\n        assert_eq!(len, ch.len_utf8(), \"Len of ch={}\", ch);\n        let ptr = data.as_mut_ptr();\n        unsafe {\n            assert!(matches::matches!(encode_utf8(ch, ptr, len - 1), Err(_)));\n            assert!(matches::matches!(encode_utf8(ch, ptr, len), Ok(_)));\n        }\n    }\n}\n\n"
    },
    {
      "package": "arrayvec@0.7.8",
      "sourcePath": "README.md",
      "sha256": "2264c34c62ea4c617d72047b00749b4786dfb9dff2fac24e0320170ee0cd19c8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "\narrayvec\n========\n[![Crates.io: arrayvec](https://img.shields.io/crates/v/arrayvec.svg)](https://crates.io/crates/arrayvec)\n[![Documentation](https://docs.rs/arrayvec/badge.svg)](https://docs.rs/arrayvec)\n[![Build Status](https://github.com/bluss/arrayvec/workflows/Continuous%20integration/badge.svg?branch=master)](https://github.com/bluss/arrayvec/actions)\n\n\n\n\n[![License: Apache](https://img.shields.io/badge/License-Apache%202.0-red.svg)](LICENSE-APACHE)\nOR\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\nA vector with fixed capacity.\n\nPlease read the [`API documentation here`](https://docs.rs/arrayvec)\n\n# License\n\nDual-licensed to be compatible with the Rust project.\n\nLicensed under the Apache License, Version 2.0\nhttp://www.apache.org/licenses/LICENSE-2.0 or the MIT license\nhttp://opensource.org/licenses/MIT, at your\noption. This file may not be copied, modified, or distributed\nexcept according to those terms.\n"
    },
    {
      "package": "arrayvec@0.7.8",
      "sourcePath": "src/char.rs",
      "sha256": "1de50e1d6045af2b3496426492315ba774986f9bc8301ffa391de861a08cc9cb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n//\n// Original authors: alexchrichton, bluss\n\n// UTF-8 ranges and tags for encoding characters\nconst TAG_CONT: u8    = 0b1000_0000;\nconst TAG_TWO_B: u8   = 0b1100_0000;\nconst TAG_THREE_B: u8 = 0b1110_0000;\nconst TAG_FOUR_B: u8  = 0b1111_0000;\nconst MAX_ONE_B: u32   =     0x80;\nconst MAX_TWO_B: u32   =    0x800;\nconst MAX_THREE_B: u32 =  0x10000;\n\n/// Placeholder\npub struct EncodeUtf8Error;\n\n/// Encode a char into buf using UTF-8.\n///\n/// On success, return the byte length of the encoding (1, 2, 3 or 4).<br>\n/// On error, return `EncodeUtf8Error` if the buffer was too short for the char.\n///\n/// Safety: `ptr` must be writable for `len` bytes.\n#[inline]\npub unsafe fn encode_utf8(ch: char, ptr: *mut u8, len: usize) -> Result<usize, EncodeUtf8Error>\n{\n    let code = ch as u32;\n    if code < MAX_ONE_B && len >= 1 {\n        ptr.add(0).write(code as u8);\n        return Ok(1);\n    } else if code < MAX_TWO_B && len >= 2 {\n        ptr.add(0).write((code >> 6 & 0x1F) as u8 | TAG_TWO_B);\n        ptr.add(1).write((code & 0x3F) as u8 | TAG_CONT);\n        return Ok(2);\n    } else if code < MAX_THREE_B && len >= 3 {\n        ptr.add(0).write((code >> 12 & 0x0F) as u8 | TAG_THREE_B);\n        ptr.add(1).write((code >>  6 & 0x3F) as u8 | TAG_CONT);\n        ptr.add(2).write((code & 0x3F) as u8 | TAG_CONT);\n        return Ok(3);\n    } else if len >= 4 {\n        ptr.add(0).write((code >> 18 & 0x07) as u8 | TAG_FOUR_B);\n        ptr.add(1).write((code >> 12 & 0x3F) as u8 | TAG_CONT);\n        ptr.add(2).write((code >>  6 & 0x3F) as u8 | TAG_CONT);\n        ptr.add(3).write((code & 0x3F) as u8 | TAG_CONT);\n        return Ok(4);\n    };\n    Err(EncodeUtf8Error)\n}\n\n\n#[test]\n#[cfg_attr(miri, ignore)] // Miri is too slow\nfn test_encode_utf8() {\n    // Test that all codepoints are encoded correctly\n    let mut data = [0u8; 16];\n    for codepoint in 0..=(std::char::MAX as u32) {\n        if let Some(ch) = std::char::from_u32(codepoint) {\n            for elt in &mut data { *elt = 0; }\n            let ptr = data.as_mut_ptr();\n            let len = data.len();\n            unsafe {\n                let res = encode_utf8(ch, ptr, len).ok().unwrap();\n                assert_eq!(res, ch.len_utf8());\n            }\n            let string = std::str::from_utf8(&data).unwrap();\n            assert_eq!(string.chars().next(), Some(ch));\n        }\n    }\n}\n\n#[test]\nfn test_encode_utf8_oob() {\n    // test that we report oob if the buffer is too short\n    let mut data = [0u8; 16];\n    let chars = ['a', 'α', '�', '𐍈'];\n    for (len, &ch) in (1..=4).zip(&chars) {\n        assert_eq!(len, ch.len_utf8(), \"Len of ch={}\", ch);\n        let ptr = data.as_mut_ptr();\n        unsafe {\n            assert!(matches::matches!(encode_utf8(ch, ptr, len - 1), Err(_)));\n            assert!(matches::matches!(encode_utf8(ch, ptr, len), Ok(_)));\n        }\n    }\n}\n\n"
    },
    {
      "package": "base64@0.21.7",
      "sourcePath": "README.md",
      "sha256": "df01f5b4317d601e7de86743f9818aec9196abf9e298f5e47679b7a966ecd945",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# [base64](https://crates.io/crates/base64)\n\n[![](https://img.shields.io/crates/v/base64.svg)](https://crates.io/crates/base64) [![Docs](https://docs.rs/base64/badge.svg)](https://docs.rs/base64) [![CircleCI](https://circleci.com/gh/marshallpierce/rust-base64/tree/master.svg?style=shield)](https://circleci.com/gh/marshallpierce/rust-base64/tree/master) [![codecov](https://codecov.io/gh/marshallpierce/rust-base64/branch/master/graph/badge.svg)](https://codecov.io/gh/marshallpierce/rust-base64) [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/)\n\n<a href=\"https://www.jetbrains.com/?from=rust-base64\"><img src=\"/icon_CLion.svg\" height=\"40px\"/></a>\n\nMade with CLion. Thanks to JetBrains for supporting open source!\n\nIt's base64. What more could anyone want?\n\nThis library's goals are to be *correct* and *fast*. It's thoroughly tested and widely used. It exposes functionality at\nmultiple levels of abstraction so you can choose the level of convenience vs performance that you want,\ne.g. `decode_engine_slice` decodes into an existing `&mut [u8]` and is pretty fast (2.6GiB/s for a 3 KiB input),\nwhereas `decode_engine` allocates a new `Vec<u8>` and returns it, which might be more convenient in some cases, but is\nslower (although still fast enough for almost any purpose) at 2.1 GiB/s.\n\nSee the [docs](https://docs.rs/base64) for all the details.\n\n## FAQ\n\n### I need to decode base64 with whitespace/null bytes/other random things interspersed in it. What should I do?\n\nRemove non-base64 characters from your input before decoding.\n\nIf you have a `Vec` of base64, [retain](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain) can be used to\nstrip out whatever you need removed.\n\nIf you have a `Read` (e.g. reading a file or network socket), there are various approaches.\n\n- Use [iter_read](https://crates.io/crates/iter-read) together with `Read`'s `bytes()` to filter out unwanted bytes.\n- Implement `Read` with a `read()` impl that delegates to your actual `Read`, and then drops any bytes you don't want.\n\n### I need to line-wrap base64, e.g. for MIME/PEM.\n\n[line-wrap](https://crates.io/crates/line-wrap) does just that.\n\n### I want canonical base64 encoding/decoding.\n\nFirst, don't do this. You should no more expect Base64 to be canonical than you should expect compression algorithms to\nproduce canonical output across all usage in the wild (hint: they don't).\nHowever, [people are drawn to their own destruction like moths to a flame](https://eprint.iacr.org/2022/361), so here we\nare.\n\nThere are two opportunities for non-canonical encoding (and thus, detection of the same during decoding): the final bits\nof the last encoded token in two or three token suffixes, and the `=` token used to inflate the suffix to a full four\ntokens.\n\nThe trailing bits issue is unavoidable: with 6 bits available in each encoded token, 1 input byte takes 2 tokens,\nwith the second one having some bits unused. Same for two input bytes: 16 bits, but 3 tokens have 18 bits. Unless we\ndecide to stop shipping whole bytes around, we're stuck with those extra bits that a sneaky or buggy encoder might set\nto 1 instead of 0.\n\nThe `=` pad bytes, on the other hand, are entirely a self-own by the Base64 standard. They do not affect decoding other\nthan to provide an opportunity to say \"that padding is incorrect\". Exabytes of storage and transfer have no doubt been\nwasted on pointless `=` bytes. Somehow we all seem to be quite comfortable with, say, hex-encoded data just stopping\nwhen it's done rather than requiring a confirmation that the author of the encoder could count to four. Anyway, there\nare two ways to make pad bytes predictable: require canonical padding to the next multiple of four bytes as per the RFC,\nor, if you control all producers and consumers, save a few bytes by requiring no padding (especially applicable to the\nurl-safe alphabet).\n\nAll `Engine` implementations must at a minimum support treating non-canonical padding of both types as an error, and\noptionally may allow other behaviors.\n\n## Rust version compatibility\n\nThe minimum supported Rust version is 1.48.0.\n\n# Contributing\n\nContributions are very welcome. However, because this library is used widely, and in security-sensitive contexts, all\nPRs will be carefully scrutinized. Beyond that, this sort of low level library simply needs to be 100% correct. Nobody\nwants to chase bugs in encoding of any sort.\n\nAll this means that it takes me a fair amount of time to review each PR, so it might take quite a while to carve out the\nfree time to give each PR the attention it deserves. I will get to everyone eventually!\n\n## Developing\n\nBenchmarks are in `benches/`.\n\n```bash\ncargo bench\n```\n\n## no_std\n\nThis crate supports no_std. By default the crate targets std via the `std` feature. You can deactivate\nthe `default-features` to target `core` instead. In that case you lose out on all the functionality revolving\naround `std::io`, `std::error::Error`, and heap allocations. There is an additional `alloc` feature that you can activate\nto bring back the support for heap allocations.\n\n## Profiling\n\nOn Linux, you can use [perf](https://perf.wiki.kernel.org/index.php/Main_Page) for profiling. Then compile the\nbenchmarks with `cargo bench --no-run`.\n\nRun the benchmark binary with `perf` (shown here filtering to one particular benchmark, which will make the results\neasier to read). `perf` is only available to the root user on most systems as it fiddles with event counters in your\nCPU, so use `sudo`. We need to run the actual benchmark binary, hence the path into `target`. You can see the actual\nfull path with `cargo bench -v`; it will print out the commands it runs. If you use the exact path\nthat `bench` outputs, make sure you get the one that's for the benchmarks, not the tests. You may also want\nto `cargo clean` so you have only one `benchmarks-` binary (they tend to accumulate).\n\n```bash\nsudo perf record target/release/deps/benchmarks-* --bench decode_10mib_reuse\n```\n\nThen analyze the results, again with perf:\n\n```bash\nsudo perf annotate -l\n```\n\nYou'll see a bunch of interleaved rust source and assembly like this. The section with `lib.rs:327` is telling us that\n4.02% of samples saw the `movzbl` aka bit shift as the active instruction. However, this percentage is not as exact as\nit seems due to a phenomenon called *skid*. Basically, a consequence of how fancy modern CPUs are is that this sort of\ninstruction profiling is inherently inaccurate, especially in branch-heavy code.\n\n```text\n lib.rs:322    0.70 :     10698:       mov    %rdi,%rax\n    2.82 :        1069b:       shr    $0x38,%rax\n         :                  if morsel == decode_tables::INVALID_VALUE {\n         :                      bad_byte_index = input_index;\n         :                      break;\n         :                  };\n         :                  accum = (morsel as u64) << 58;\n lib.rs:327    4.02 :     1069f:       movzbl (%r9,%rax,1),%r15d\n         :              // fast loop of 8 bytes at a time\n         :              while input_index < length_of_full_chunks {\n         :                  let mut accum: u64;\n         :\n         :                  let input_chunk = BigEndian::read_u64(&input_bytes[input_index..(input_index + 8)]);\n         :                  morsel = decode_table[(input_chunk >> 56) as usize];\n lib.rs:322    3.68 :     106a4:       cmp    $0xff,%r15\n         :                  if morsel == decode_tables::INVALID_VALUE {\n    0.00 :        106ab:       je     1090e <base64::decode_config_buf::hbf68a45fefa299c1+0x46e>\n```\n\n## Fuzzing\n\nThis uses [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz). See `fuzz/fuzzers` for the available fuzzing scripts.\nTo run, use an invocation like these:\n\n```bash\ncargo +nightly fuzz run roundtrip\ncargo +nightly fuzz run roundtrip_no_pad\ncargo +nightly fuzz run roundtrip_random_config -- -max_len=10240\ncargo +nightly fuzz run decode_random\n```\n\n## License\n\nThis project is dual-licensed under MIT and Apache 2.0.\n\n"
    },
    {
      "package": "bitflags@1.3.2",
      "sourcePath": "src/lib.rs",
      "sha256": "e6477688535ee326d27238aeedc9cb4320ac35b9d17a4deda09e0587b0ccdbd4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! A typesafe bitmask flag generator useful for sets of C-style bitmask flags.\n//! It can be used for creating typesafe wrappers around C APIs.\n//!\n//! The `bitflags!` macro generates `struct`s that manage a set of flags. The\n//! flags should only be defined for integer types, otherwise unexpected type\n//! errors may occur at compile time.\n//!\n//! # Example\n//!\n//! ```\n//! use bitflags::bitflags;\n//!\n//! bitflags! {\n//!     struct Flags: u32 {\n//!         const A = 0b00000001;\n//!         const B = 0b00000010;\n//!         const C = 0b00000100;\n//!         const ABC = Self::A.bits | Self::B.bits | Self::C.bits;\n//!     }\n//! }\n//!\n//! fn main() {\n//!     let e1 = Flags::A | Flags::C;\n//!     let e2 = Flags::B | Flags::C;\n//!     assert_eq!((e1 | e2), Flags::ABC);   // union\n//!     assert_eq!((e1 & e2), Flags::C);     // intersection\n//!     assert_eq!((e1 - e2), Flags::A);     // set difference\n//!     assert_eq!(!e2, Flags::A);           // set complement\n//! }\n//! ```\n//!\n//! See [`example_generated::Flags`](./example_generated/struct.Flags.html) for documentation of code\n//! generated by the above `bitflags!` expansion.\n//!\n//! The generated `struct`s can also be extended with type and trait\n//! implementations:\n//!\n//! ```\n//! use std::fmt;\n//!\n//! use bitflags::bitflags;\n//!\n//! bitflags! {\n//!     struct Flags: u32 {\n//!         const A = 0b00000001;\n//!         const B = 0b00000010;\n//!     }\n//! }\n//!\n//! impl Flags {\n//!     pub fn clear(&mut self) {\n//!         self.bits = 0;  // The `bits` field can be accessed from within the\n//!                         // same module where the `bitflags!` macro was invoked.\n//!     }\n//! }\n//!\n//! impl fmt::Display for Flags {\n//!     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n//!         write!(f, \"hi!\")\n//!     }\n//! }\n//!\n//! fn main() {\n//!     let mut flags = Flags::A | Flags::B;\n//!     flags.clear();\n//!     assert!(flags.is_empty());\n//!     assert_eq!(format!(\"{}\", flags), \"hi!\");\n//!     assert_eq!(format!(\"{:?}\", Flags::A | Flags::B), \"A | B\");\n//!     assert_eq!(format!(\"{:?}\", Flags::B), \"B\");\n//! }\n//! ```\n//!\n//! # Visibility\n//!\n//! The generated structs and their associated flag constants are not exported\n//! out of the current module by default. A definition can be exported out of\n//! the current module by adding `pub` before `struct`:\n//!\n//! ```\n//! mod example {\n//!     use bitflags::bitflags;\n//!\n//!     bitflags! {\n//!         pub struct Flags1: u32 {\n//!             const A = 0b00000001;\n//!         }\n//!\n//! #       pub\n//!         struct Flags2: u32 {\n//!             const B = 0b00000010;\n//!         }\n//!     }\n//! }\n//!\n//! fn main() {\n//!     let flag1 = example::Flags1::A;\n//!     let flag2 = example::Flags2::B; // error: const `B` is private\n//! }\n//! ```\n//!\n//! # Attributes\n//!\n//! Attributes can be attached to the generated `struct`s by placing them\n//! before the `struct` keyword.\n//!\n//! ## Representations\n//!\n//! It's valid to add a `#[repr(C)]` or `#[repr(transparent)]` attribute to a type\n//! generated by `bitflags!`. In these cases, the type is guaranteed to be a newtype.\n//!\n//! ```\n//! use bitflags::bitflags;\n//!\n//! bitflags! {\n//!     #[repr(transparent)]\n//!     struct Flags: u32 {\n//!         const A = 0b00000001;\n//!         const B = 0b00000010;\n//!         const C = 0b00000100;\n//!     }\n//! }\n//! ```\n//!\n//! # Trait implementations\n//!\n//! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`\n//! traits are automatically derived for the `struct`s using the `derive` attribute.\n//! Additional traits can be derived by providing an explicit `derive`\n//! attribute on `struct`.\n//!\n//! The `Extend` and `FromIterator` traits are implemented for the `struct`s,\n//! too: `Extend` adds the union of the instances of the `struct` iterated over,\n//! while `FromIterator` calculates the union.\n//!\n//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` traits are also\n//! implemented by displaying the bits value of the internal struct.\n//!\n//! ## Operators\n//!\n//! The following operator traits are implemented for the generated `struct`s:\n//!\n//! - `BitOr` and `BitOrAssign`: union\n//! - `BitAnd` and `BitAndAssign`: intersection\n//! - `BitXor` and `BitXorAssign`: toggle\n//! - `Sub` and `SubAssign`: set difference\n//! - `Not`: set complement\n//!\n//! # Methods\n//!\n//! The following methods are defined for the generated `struct`s:\n//!\n//! - `empty`: an empty set of flags\n//! - `all`: the set of all defined flags\n//! - `bits`: the raw value of the flags currently stored\n//! - `from_bits`: convert from underlying bit representation, unless that\n//!                representation contains bits that do not correspond to a\n//!                defined flag\n//! - `from_bits_truncate`: convert from underlying bit representation, dropping\n//!                         any bits that do not correspond to defined flags\n//! - `from_bits_unchecked`: convert from underlying bit representation, keeping\n//!                          all bits (even those not corresponding to defined\n//!                          flags)\n//! - `is_empty`: `true` if no flags are currently stored\n//! - `is_all`: `true` if currently set flags exactly equal all defined flags\n//! - `intersects`: `true` if there are flags common to both `self` and `other`\n//! - `contains`: `true` if all of the flags in `other` are contained within `self`\n//! - `insert`: inserts the specified flags in-place\n//! - `remove`: removes the specified flags in-place\n//! - `toggle`: the specified flags will be inserted if not present, and removed\n//!             if they are.\n//! - `set`: inserts or removes the specified flags depending on the passed value\n//! - `intersection`: returns a new set of flags, containing only the flags present\n//!                   in both `self` and `other` (the argument to the function).\n//! - `union`: returns a new set of flags, containing any flags present in\n//!            either `self` or `other` (the argument to the function).\n//! - `difference`: returns a new set of flags, containing all flags present in\n//!                 `self` without any of the flags present in `other` (the\n//!                 argument to the function).\n//! - `symmetric_difference`: returns a new set of flags, containing all flags\n//!                           present in either `self` or `other` (the argument\n//!                           to the function), but not both.\n//! - `complement`: returns a new set of flags, containing all flags which are\n//!                 not set in `self`, but which are allowed for this type.\n//!\n//! ## Default\n//!\n//! The `Default` trait is not automatically implemented for the generated structs.\n//!\n//! If your default value is equal to `0` (which is the same value as calling `empty()`\n//! on the generated struct), you can simply derive `Default`:\n//!\n//! ```\n//! use bitflags::bitflags;\n//!\n//! bitflags! {\n//!     // Results in default value with bits: 0\n//!     #[derive(Default)]\n//!     struct Flags: u32 {\n//!         const A = 0b00000001;\n//!         const B = 0b00000010;\n//!         const C = 0b00000100;\n//!     }\n//! }\n//!\n//! fn main() {\n//!     let derived_default: Flags = Default::default();\n//!     assert_eq!(derived_default.bits(), 0);\n//! }\n//! ```\n//!\n//! If your default value is not equal to `0` you need to implement `Default` yourself:\n//!\n//! ```\n//! use bitflags::bitflags;\n//!\n//! bitflags! {\n//!     struct Flags: u32 {\n//!         const A = 0b00000001;\n//!         const B = 0b00000010;\n//!         const C = 0b00000100;\n//!     }\n//! }\n//!\n//! // explicit `Default` implementation\n//! impl Default for Flags {\n//!     fn default() -> Flags {\n//!         Flags::A | Flags::C\n//!     }\n//! }\n//!\n//! fn main() {\n//!     let implemented_default: Flags = Default::default();\n//!     assert_eq!(implemented_default, (Flags::A | Flags::C));\n//! }\n//! ```\n//!\n//! # Zero Flags\n//!\n//! Flags with a value equal to zero will have some strange behavior that one should be aware of.\n//!\n//! ```\n//! use bitflags::bitflags;\n//!\n//! bitflags! {\n//!     struct Flags: u32 {\n//!         const NONE = 0b00000000;\n//!         const SOME = 0b00000001;\n//!     }\n//! }\n//!\n//! fn main() {\n//!     let empty = Flags::empty();\n//!     let none = Flags::NONE;\n//!     let some = Flags::SOME;\n//!\n//!     // Zero flags are treated as always present\n//!     assert!(empty.contains(Flags::NONE));\n//!     assert!(none.contains(Flags::NONE));\n//!     assert!(some.contains(Flags::NONE));\n//!\n//!     // Zero flags will be ignored when testing for emptiness\n//!     assert!(none.is_empty());\n//! }\n//! ```\n//!\n//! Users should generally avoid defining a flag with a value of zero.\n\n#![cfg_attr(not(test), no_std)]\n#![doc(html_root_url = \"https://docs.rs/bitflags/1.3.2\")]\n\n#[doc(hidden)]\npub extern crate core as _core;\n\n/// The macro used to generate the flag structures.\n///\n/// See the [crate level docs](../bitflags/index.html) for complete documentation.\n///\n/// # Example\n///\n/// ```\n/// use bitflags::bitflags;\n///\n/// bitflags! {\n///     struct Flags: u32 {\n///         const A = 0b00000001;\n///         const B = 0b00000010;\n///         const C = 0b00000100;\n///         const ABC = Self::A.bits | Self::B.bits | Self::C.bits;\n///     }\n/// }\n///\n/// fn main() {\n///     let e1 = Flags::A | Flags::C;\n///     let e2 = Flags::B | Flags::C;\n///     assert_eq!((e1 | e2), Flags::ABC);   // union\n///     assert_eq!((e1 & e2), Flags::C);     // intersection\n///     assert_eq!((e1 - e2), Flags::A);     // set difference\n///     assert_eq!(!e2, Flags::A);           // set complement\n/// }\n/// ```\n///\n/// The generated `struct`s can also be extended with type and trait\n/// implementations:\n///\n/// ```\n/// use std::fmt;\n///\n/// use bitflags::bitflags;\n///\n/// bitflags! {\n///     struct Flags: u32 {\n///         const A = 0b00000001;\n///         const B = 0b00000010;\n///     }\n/// }\n///\n/// impl Flags {\n///     pub fn clear(&mut self) {\n///         self.bits = 0;  // The `bits` field can be accessed from within the\n///                         // same module where the `bitflags!` macro was invoked.\n///     }\n/// }\n///\n/// impl fmt::Display for Flags {\n///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n///         write!(f, \"hi!\")\n///     }\n/// }\n///\n/// fn main() {\n///     let mut flags = Flags::A | Flags::B;\n///     flags.clear();\n///     assert!(flags.is_empty());\n///     assert_eq!(format!(\"{}\", flags), \"hi!\");\n///     assert_eq!(format!(\"{:?}\", Flags::A | Flags::B), \"A | B\");\n///     assert_eq!(format!(\"{:?}\", Flags::B), \"B\");\n/// }\n/// ```\n#[macro_export(local_inner_macros)]\nmacro_rules! bitflags {\n    (\n        $(#[$outer:meta])*\n        $vis:vis struct $BitFlags:ident: $T:ty {\n            $(\n                $(#[$inner:ident $($args:tt)*])*\n                const $Flag:ident = $value:expr;\n            )*\n        }\n\n        $($t:tt)*\n    ) => {\n        $(#[$outer])*\n        #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]\n        $vis struct $BitFlags {\n            bits: $T,\n        }\n\n        __impl_bitflags! {\n            $BitFlags: $T {\n                $(\n                    $(#[$inner $($args)*])*\n                    $Flag = $value;\n                )*\n            }\n        }\n\n        bitflags! {\n            $($t)*\n        }\n    };\n    () => {};\n}\n\n// A helper macro to implement the `all` function.\n#[macro_export(local_inner_macros)]\n#[doc(hidden)]\nmacro_rules! __impl_all_bitflags {\n    (\n        $BitFlags:ident: $T:ty {\n            $(\n                $(#[$attr:ident $($args:tt)*])*\n                $Flag:ident = $value:expr;\n            )+\n        }\n    ) => {\n        // See `Debug::fmt` for why this approach is taken.\n        #[allow(non_snake_case)]\n        trait __BitFlags {\n            $(\n                const $Flag: $T = 0;\n            )+\n        }\n        #[allow(non_snake_case)]\n        impl __BitFlags for $BitFlags {\n            $(\n                __impl_bitflags! {\n                    #[allow(deprecated)]\n                    $(? #[$attr $($args)*])*\n                    const $Flag: $T = Self::$Flag.bits;\n                }\n            )+\n        }\n        Self { bits: $(<Self as __BitFlags>::$Flag)|+ }\n    };\n    (\n        $BitFlags:ident: $T:ty { }\n    ) => {\n        Self { bits: 0 }\n    };\n}\n\n#[macro_export(local_inner_macros)]\n#[doc(hidden)]\nmacro_rules! __impl_bitflags {\n    (\n        $BitFlags:ident: $T:ty {\n            $(\n                $(#[$attr:ident $($args:tt)*])*\n                $Flag:ident = $value:expr;\n            )*\n        }\n    ) => {\n        impl $crate::_core::fmt::Debug for $BitFlags {\n            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {\n                // This convoluted approach is to handle #[cfg]-based flag\n                // omission correctly. For example it needs to support:\n                //\n                //    #[cfg(unix)] const A: Flag = /* ... */;\n                //    #[cfg(windows)] const B: Flag = /* ... */;\n\n                // Unconditionally define a check for every flag, even disabled\n                // ones.\n                #[allow(non_snake_case)]\n                trait __BitFlags {\n                    $(\n                        #[inline]\n                        fn $Flag(&self) -> bool { false }\n                    )*\n                }\n\n                // Conditionally override the check for just those flags that\n                // are not #[cfg]ed away.\n                #[allow(non_snake_case)]\n                impl __BitFlags for $BitFlags {\n                    $(\n                        __impl_bitflags! {\n                            #[allow(deprecated)]\n                            #[inline]\n                            $(? #[$attr $($args)*])*\n                            fn $Flag(&self) -> bool {\n                                if Self::$Flag.bits == 0 && self.bits != 0 {\n                                    false\n                                } else {\n                                    self.bits & Self::$Flag.bits == Self::$Flag.bits\n                                }\n                            }\n                        }\n                    )*\n                }\n\n                let mut first = true;\n                $(\n                    if <Self as __BitFlags>::$Flag(self) {\n                        if !first {\n                            f.write_str(\" | \")?;\n                        }\n                        first = false;\n                        f.write_str($crate::_core::stringify!($Flag))?;\n                    }\n                )*\n                let extra_bits = self.bits & !Self::all().bits();\n                if extra_bits != 0 {\n                    if !first {\n                        f.write_str(\" | \")?;\n                    }\n                    first = false;\n                    f.write_str(\"0x\")?;\n                    $crate::_core::fmt::LowerHex::fmt(&extra_bits, f)?;\n                }\n                if first {\n                    f.write_str(\"(empty)\")?;\n                }\n                Ok(())\n            }\n        }\n        impl $crate::_core::fmt::Binary for $BitFlags {\n            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {\n                $crate::_core::fmt::Binary::fmt(&self.bits, f)\n            }\n        }\n        impl $crate::_core::fmt::Octal for $BitFlags {\n            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {\n                $crate::_core::fmt::Octal::fmt(&self.bits, f)\n            }\n        }\n        impl $crate::_core::fmt::LowerHex for $BitFlags {\n            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {\n                $crate::_core::fmt::LowerHex::fmt(&self.bits, f)\n            }\n        }\n        impl $crate::_core::fmt::UpperHex for $BitFlags {\n            fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {\n                $crate::_core::fmt::UpperHex::fmt(&self.bits, f)\n            }\n        }\n\n        #[allow(dead_code)]\n        impl $BitFlags {\n            $(\n                $(#[$attr $($args)*])*\n                pub const $Flag: Self = Self { bits: $value };\n            )*\n\n            /// Returns an empty set of flags.\n            #[inline]\n            pub const fn empty() -> Self {\n                Self { bits: 0 }\n            }\n\n            /// Returns the set containing all flags.\n            #[inline]\n            pub const fn all() -> Self {\n                __impl_all_bitflags! {\n                    $BitFlags: $T {\n                        $(\n                            $(#[$attr $($args)*])*\n                            $Flag = $value;\n                        )*\n                    }\n                }\n            }\n\n            /// Returns the raw value of the flags currently stored.\n            #[inline]\n            pub const fn bits(&self) -> $T {\n                self.bits\n            }\n\n            /// Convert from underlying bit representation, unless that\n            /// representation contains bits that do not correspond to a flag.\n            #[inline]\n            pub const fn from_bits(bits: $T) -> $crate::_core::option::Option<Self> {\n                if (bits & !Self::all().bits()) == 0 {\n                    $crate::_core::option::Option::Some(Self { bits })\n                } else {\n                    $crate::_core::option::Option::None\n                }\n            }\n\n            /// Convert from underlying bit representation, dropping any bits\n            /// that do not correspond to flags.\n            #[inline]\n            pub const fn from_bits_truncate(bits: $T) -> Self {\n                Self { bits: bits & Self::all().bits }\n            }\n\n            /// Convert from underlying bit representation, preserving all\n            /// bits (even those not corresponding to a defined flag).\n            ///\n            /// # Safety\n            ///\n            /// The caller of the `bitflags!` macro can chose to allow or\n            /// disallow extra bits for their bitflags type.\n            ///\n            /// The caller of `from_bits_unchecked()` has to ensure that\n            /// all bits correspond to a defined flag or that extra bits\n            /// are valid for this bitflags type.\n            #[inline]\n            pub const unsafe fn from_bits_unchecked(bits: $T) -> Self {\n                Self { bits }\n            }\n\n            /// Returns `true` if no flags are currently stored.\n            #[inline]\n            pub const fn is_empty(&self) -> bool {\n                self.bits() == Self::empty().bits()\n            }\n\n            /// Returns `true` if all flags are currently set.\n            #[inline]\n            pub const fn is_all(&self) -> bool {\n                Self::all().bits | self.bits == self.bits\n            }\n\n            /// Returns `true` if there are flags common to both `self` and `other`.\n            #[inline]\n            pub const fn intersects(&self, other: Self) -> bool {\n                !(Self { bits: self.bits & other.bits}).is_empty()\n            }\n\n            /// Returns `true` if all of the flags in `other` are contained within `self`.\n            #[inline]\n            pub const fn contains(&self, other: Self) -> bool {\n                (self.bits & other.bits) == other.bits\n            }\n\n            /// Inserts the specified flags in-place.\n            #[inline]\n            pub fn insert(&mut self, other: Self) {\n                self.bits |= other.bits;\n            }\n\n            /// Removes the specified flags in-place.\n            #[inline]\n            pub fn remove(&mut self, other: Self) {\n                self.bits &= !other.bits;\n            }\n\n            /// Toggles the specified flags in-place.\n            #[inline]\n            pub fn toggle(&mut self, other: Self) {\n                self.bits ^= other.bits;\n            }\n\n            /// Inserts or removes the specified flags depending on the passed value.\n            #[inline]\n            pub fn set(&mut self, other: Self, value: bool) {\n                if value {\n                    self.insert(other);\n                } else {\n                    self.remove(other);\n                }\n            }\n\n            /// Returns the intersection between the flags in `self` and\n            /// `other`.\n            ///\n            /// Specifically, the returned set contains only the flags which are\n            /// present in *both* `self` *and* `other`.\n            ///\n            /// This is equivalent to using the `&` operator (e.g.\n            /// [`ops::BitAnd`]), as in `flags & other`.\n            ///\n            /// [`ops::BitAnd`]: https://doc.rust-lang.org/std/ops/trait.BitAnd.html\n            #[inline]\n            #[must_use]\n            pub const fn intersection(self, other: Self) -> Self {\n                Self { bits: self.bits & other.bits }\n            }\n\n            /// Returns the union of between the flags in `self` and `other`.\n            ///\n            /// Specifically, the returned set contains all flags which are\n            /// present in *either* `self` *or* `other`, including any which are\n            /// present in both (see [`Self::symmetric_difference`] if that\n            /// is undesirable).\n            ///\n            /// This is equivalent to using the `|` operator (e.g.\n            /// [`ops::BitOr`]), as in `flags | other`.\n            ///\n            /// [`ops::BitOr`]: https://doc.rust-lang.org/std/ops/trait.BitOr.html\n            #[inline]\n            #[must_use]\n            pub const fn union(self, other: Self) -> Self {\n                Self { bits: self.bits | other.bits }\n            }\n\n            /// Returns the difference between the flags in `self` and `other`.\n            ///\n            /// Specifically, the returned set contains all flags present in\n            /// `self`, except for the ones present in `other`.\n            ///\n            /// It is also conceptually equivalent to the \"bit-clear\" operation:\n            /// `flags & !other` (and this syntax is also supported).\n            ///\n            /// This is equivalent to using the `-` operator (e.g.\n            /// [`ops::Sub`]), as in `flags - other`.\n            ///\n            /// [`ops::Sub`]: https://doc.rust-lang.org/std/ops/trait.Sub.html\n            #[inline]\n            #[must_use]\n            pub const fn difference(self, other: Self) -> Self {\n                Self { bits: self.bits & !other.bits }\n            }\n\n            /// Returns the [symmetric difference][sym-diff] between the flags\n            /// in `self` and `other`.\n            ///\n            /// Specifically, the returned set contains the flags present which\n            /// are present in `self` or `other`, but that are not present in\n            /// both. Equivalently, it contains the flags present in *exactly\n            /// one* of the sets `self` and `other`.\n            ///\n            /// This is equivalent to using the `^` operator (e.g.\n            /// [`ops::BitXor`]), as in `flags ^ other`.\n            ///\n            /// [sym-diff]: https://en.wikipedia.org/wiki/Symmetric_difference\n            /// [`ops::BitXor`]: https://doc.rust-lang.org/std/ops/trait.BitXor.html\n            #[inline]\n            #[must_use]\n            pub const fn symmetric_difference(self, other: Self) -> Self {\n                Self { bits: self.bits ^ other.bits }\n            }\n\n            /// Returns the complement of this set of flags.\n            ///\n            /// Specifically, the returned set contains all the flags which are\n            /// not set in `self`, but which are allowed for this type.\n            ///\n            /// Alternatively, it can be thought of as the set difference\n            /// between [`Self::all()`] and `self` (e.g. `Self::all() - self`)\n            ///\n            /// This is equivalent to using the `!` operator (e.g.\n            /// [`ops::Not`]), as in `!flags`.\n            ///\n            /// [`Self::all()`]: Self::all\n            /// [`ops::Not`]: https://doc.rust-lang.org/std/ops/trait.Not.html\n            #[inline]\n            #[must_use]\n            pub const fn complement(self) -> Self {\n                Self::from_bits_truncate(!self.bits)\n            }\n\n        }\n\n        impl $crate::_core::ops::BitOr for $BitFlags {\n            type Output = Self;\n\n            /// Returns the union of the two sets of flags.\n            #[inline]\n            fn bitor(self, other: $BitFlags) -> Self {\n                Self { bits: self.bits | other.bits }\n            }\n        }\n\n        impl $crate::_core::ops::BitOrAssign for $BitFlags {\n            /// Adds the set of flags.\n            #[inline]\n            fn bitor_assign(&mut self, other: Self) {\n                self.bits |= other.bits;\n            }\n        }\n\n        impl $crate::_core::ops::BitXor for $BitFlags {\n            type Output = Self;\n\n            /// Returns the left flags, but with all the right flags toggled.\n            #[inline]\n            fn bitxor(self, other: Self) -> Self {\n                Self { bits: self.bits ^ other.bits }\n            }\n        }\n\n        impl $crate::_core::ops::BitXorAssign for $BitFlags {\n            /// Toggles the set of flags.\n            #[inline]\n            fn bitxor_assign(&mut self, other: Self) {\n                self.bits ^= other.bits;\n            }\n        }\n\n        impl $crate::_core::ops::BitAnd for $BitFlags {\n            type Output = Self;\n\n            /// Returns the intersection between the two sets of flags.\n            #[inline]\n            fn bitand(self, other: Self) -> Self {\n                Self { bits: self.bits & other.bits }\n            }\n        }\n\n        impl $crate::_core::ops::BitAndAssign for $BitFlags {\n            /// Disables all flags disabled in the set.\n            #[inline]\n            fn bitand_assign(&mut self, other: Self) {\n                self.bits &= other.bits;\n            }\n        }\n\n        impl $crate::_core::ops::Sub for $BitFlags {\n            type Output = Self;\n\n            /// Returns the set difference of the two sets of flags.\n            #[inline]\n            fn sub(self, other: Self) -> Self {\n                Self { bits: self.bits & !other.bits }\n            }\n        }\n\n        impl $crate::_core::ops::SubAssign for $BitFlags {\n            /// Disables all flags enabled in the set.\n            #[inline]\n            fn sub_assign(&mut self, other: Self) {\n                self.bits &= !other.bits;\n            }\n        }\n\n        impl $crate::_core::ops::Not for $BitFlags {\n            type Output = Self;\n\n            /// Returns the complement of this set of flags.\n            #[inline]\n            fn not(self) -> Self {\n                Self { bits: !self.bits } & Self::all()\n            }\n        }\n\n        impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags {\n            fn extend<T: $crate::_core::iter::IntoIterator<Item=Self>>(&mut self, iterator: T) {\n                for item in iterator {\n                    self.insert(item)\n                }\n            }\n        }\n\n        impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags {\n            fn from_iter<T: $crate::_core::iter::IntoIterator<Item=Self>>(iterator: T) -> Self {\n                let mut result = Self::empty();\n                result.extend(iterator);\n                result\n            }\n        }\n    };\n\n    // Every attribute that the user writes on a const is applied to the\n    // corresponding const that we generate, but within the implementation of\n    // Debug and all() we want to ignore everything but #[cfg] attributes. In\n    // particular, including a #[deprecated] attribute on those items would fail\n    // to compile.\n    // https://github.com/bitflags/bitflags/issues/109\n    //\n    // Input:\n    //\n    //     ? #[cfg(feature = \"advanced\")]\n    //     ? #[deprecated(note = \"Use something else.\")]\n    //     ? #[doc = r\"High quality documentation.\"]\n    //     fn f() -> i32 { /* ... */ }\n    //\n    // Output:\n    //\n    //     #[cfg(feature = \"advanced\")]\n    //     fn f() -> i32 { /* ... */ }\n    (\n        $(#[$filtered:meta])*\n        ? #[cfg $($cfgargs:tt)*]\n        $(? #[$rest:ident $($restargs:tt)*])*\n        fn $($item:tt)*\n    ) => {\n        __impl_bitflags! {\n            $(#[$filtered])*\n            #[cfg $($cfgargs)*]\n            $(? #[$rest $($restargs)*])*\n            fn $($item)*\n        }\n    };\n    (\n        $(#[$filtered:meta])*\n        // $next != `cfg`\n        ? #[$next:ident $($nextargs:tt)*]\n        $(? #[$rest:ident $($restargs:tt)*])*\n        fn $($item:tt)*\n    ) => {\n        __impl_bitflags! {\n            $(#[$filtered])*\n            // $next filtered out\n            $(? #[$rest $($restargs)*])*\n            fn $($item)*\n        }\n    };\n    (\n        $(#[$filtered:meta])*\n        fn $($item:tt)*\n    ) => {\n        $(#[$filtered])*\n        fn $($item)*\n    };\n\n    // Every attribute that the user writes on a const is applied to the\n    // corresponding const that we generate, but within the implementation of\n    // Debug and all() we want to ignore everything but #[cfg] attributes. In\n    // particular, including a #[deprecated] attribute on those items would fail\n    // to compile.\n    // https://github.com/bitflags/bitflags/issues/109\n    //\n    // const version\n    //\n    // Input:\n    //\n    //     ? #[cfg(feature = \"advanced\")]\n    //     ? #[deprecated(note = \"Use something else.\")]\n    //     ? #[doc = r\"High quality documentation.\"]\n    //     const f: i32 { /* ... */ }\n    //\n    // Output:\n    //\n    //     #[cfg(feature = \"advanced\")]\n    //     const f: i32 { /* ... */ }\n    (\n        $(#[$filtered:meta])*\n        ? #[cfg $($cfgargs:tt)*]\n        $(? #[$rest:ident $($restargs:tt)*])*\n        const $($item:tt)*\n    ) => {\n        __impl_bitflags! {\n            $(#[$filtered])*\n            #[cfg $($cfgargs)*]\n            $(? #[$rest $($restargs)*])*\n            const $($item)*\n        }\n    };\n    (\n        $(#[$filtered:meta])*\n        // $next != `cfg`\n        ? #[$next:ident $($nextargs:tt)*]\n        $(? #[$rest:ident $($restargs:tt)*])*\n        const $($item:tt)*\n    ) => {\n        __impl_bitflags! {\n            $(#[$filtered])*\n            // $next filtered out\n            $(? #[$rest $($restargs)*])*\n            const $($item)*\n        }\n    };\n    (\n        $(#[$filtered:meta])*\n        const $($item:tt)*\n    ) => {\n        $(#[$filtered])*\n        const $($item)*\n    };\n}\n\n#[cfg(feature = \"example_generated\")]\npub mod example_generated;\n\n#[cfg(test)]\nmod tests {\n    use std::collections::hash_map::DefaultHasher;\n    use std::hash::{Hash, Hasher};\n\n    bitflags! {\n        #[doc = \"> The first principle is that you must not fool yourself — and\"]\n        #[doc = \"> you are the easiest person to fool.\"]\n        #[doc = \"> \"]\n        #[doc = \"> - Richard Feynman\"]\n        #[derive(Default)]\n        struct Flags: u32 {\n            const A = 0b00000001;\n            #[doc = \"<pcwalton> macros are way better at generating code than trans is\"]\n            const B = 0b00000010;\n            const C = 0b00000100;\n            #[doc = \"* cmr bed\"]\n            #[doc = \"* strcat table\"]\n            #[doc = \"<strcat> wait what?\"]\n            const ABC = Self::A.bits | Self::B.bits | Self::C.bits;\n        }\n\n        struct _CfgFlags: u32 {\n            #[cfg(unix)]\n            const _CFG_A = 0b01;\n            #[cfg(windows)]\n            const _CFG_B = 0b01;\n            #[cfg(unix)]\n            const _CFG_C = Self::_CFG_A.bits | 0b10;\n        }\n\n        struct AnotherSetOfFlags: i8 {\n            const ANOTHER_FLAG = -1_i8;\n        }\n\n        struct LongFlags: u32 {\n            const LONG_A = 0b1111111111111111;\n        }\n    }\n\n    bitflags! {\n        struct EmptyFlags: u32 {\n        }\n    }\n\n    #[test]\n    fn test_bits() {\n        assert_eq!(Flags::empty().bits(), 0b00000000);\n        assert_eq!(Flags::A.bits(), 0b00000001);\n        assert_eq!(Flags::ABC.bits(), 0b00000111);\n\n        assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);\n        assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8);\n\n        assert_eq!(EmptyFlags::empty().bits(), 0b00000000);\n    }\n\n    #[test]\n    fn test_from_bits() {\n        assert_eq!(Flags::from_bits(0), Some(Flags::empty()));\n        assert_eq!(Flags::from_bits(0b1), Some(Flags::A));\n        assert_eq!(Flags::from_bits(0b10), Some(Flags::B));\n        assert_eq!(Flags::from_bits(0b11), Some(Flags::A | Flags::B));\n        assert_eq!(Flags::from_bits(0b1000), None);\n\n        assert_eq!(\n            AnotherSetOfFlags::from_bits(!0_i8),\n            Some(AnotherSetOfFlags::ANOTHER_FLAG)\n        );\n\n        assert_eq!(EmptyFlags::from_bits(0), Some(EmptyFlags::empty()));\n        assert_eq!(EmptyFlags::from_bits(0b1), None);\n    }\n\n    #[test]\n    fn test_from_bits_truncate() {\n        assert_eq!(Flags::from_bits_truncate(0), Flags::empty());\n        assert_eq!(Flags::from_bits_truncate(0b1), Flags::A);\n        assert_eq!(Flags::from_bits_truncate(0b10), Flags::B);\n        assert_eq!(Flags::from_bits_truncate(0b11), (Flags::A | Flags::B));\n        assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty());\n        assert_eq!(Flags::from_bits_truncate(0b1001), Flags::A);\n\n        assert_eq!(\n            AnotherSetOfFlags::from_bits_truncate(0_i8),\n            AnotherSetOfFlags::empty()\n        );\n\n        assert_eq!(EmptyFlags::from_bits_truncate(0), EmptyFlags::empty());\n        assert_eq!(EmptyFlags::from_bits_truncate(0b1), EmptyFlags::empty());\n    }\n\n    #[test]\n    fn test_from_bits_unchecked() {\n        let extra = unsafe { Flags::from_bits_unchecked(0b1000) };\n        assert_eq!(unsafe { Flags::from_bits_unchecked(0) }, Flags::empty());\n        assert_eq!(unsafe { Flags::from_bits_unchecked(0b1) }, Flags::A);\n        assert_eq!(unsafe { Flags::from_bits_unchecked(0b10) }, Flags::B);\n\n        assert_eq!(\n            unsafe { Flags::from_bits_unchecked(0b11) },\n            (Flags::A | Flags::B)\n        );\n        assert_eq!(\n            unsafe { Flags::from_bits_unchecked(0b1000) },\n            (extra | Flags::empty())\n        );\n        assert_eq!(\n            unsafe { Flags::from_bits_unchecked(0b1001) },\n            (extra | Flags::A)\n        );\n\n        let extra = unsafe { EmptyFlags::from_bits_unchecked(0b1000) };\n        assert_eq!(\n            unsafe { EmptyFlags::from_bits_unchecked(0b1000) },\n            (extra | EmptyFlags::empty())\n        );\n    }\n\n    #[test]\n    fn test_is_empty() {\n        assert!(Flags::empty().is_empty());\n        assert!(!Flags::A.is_empty());\n        assert!(!Flags::ABC.is_empty());\n\n        assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty());\n\n        assert!(EmptyFlags::empty().is_empty());\n        assert!(EmptyFlags::all().is_empty());\n    }\n\n    #[test]\n    fn test_is_all() {\n        assert!(Flags::all().is_all());\n        assert!(!Flags::A.is_all());\n        assert!(Flags::ABC.is_all());\n\n        let extra = unsafe { Flags::from_bits_unchecked(0b1000) };\n        assert!(!extra.is_all());\n        assert!(!(Flags::A | extra).is_all());\n        assert!((Flags::ABC | extra).is_all());\n\n        assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all());\n\n        assert!(EmptyFlags::all().is_all());\n        assert!(EmptyFlags::empty().is_all());\n    }\n\n    #[test]\n    fn test_two_empties_do_not_intersect() {\n        let e1 = Flags::empty();\n        let e2 = Flags::empty();\n        assert!(!e1.intersects(e2));\n\n        assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG));\n    }\n\n    #[test]\n    fn test_empty_does_not_intersect_with_full() {\n        let e1 = Flags::empty();\n        let e2 = Flags::ABC;\n        assert!(!e1.intersects(e2));\n    }\n\n    #[test]\n    fn test_disjoint_intersects() {\n        let e1 = Flags::A;\n        let e2 = Flags::B;\n        assert!(!e1.intersects(e2));\n    }\n\n    #[test]\n    fn test_overlapping_intersects() {\n        let e1 = Flags::A;\n        let e2 = Flags::A | Flags::B;\n        assert!(e1.intersects(e2));\n    }\n\n    #[test]\n    fn test_contains() {\n        let e1 = Flags::A;\n        let e2 = Flags::A | Flags::B;\n        assert!(!e1.contains(e2));\n        assert!(e2.contains(e1));\n        assert!(Flags::ABC.contains(e2));\n\n        assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG));\n\n        assert!(EmptyFlags::empty().contains(EmptyFlags::empty()));\n    }\n\n    #[test]\n    fn test_insert() {\n        let mut e1 = Flags::A;\n        let e2 = Flags::A | Flags::B;\n        e1.insert(e2);\n        assert_eq!(e1, e2);\n\n        let mut e3 = AnotherSetOfFlags::empty();\n        e3.insert(AnotherSetOfFlags::ANOTHER_FLAG);\n        assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG);\n    }\n\n    #[test]\n    fn test_remove() {\n        let mut e1 = Flags::A | Flags::B;\n        let e2 = Flags::A | Flags::C;\n        e1.remove(e2);\n        assert_eq!(e1, Flags::B);\n\n        let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG;\n        e3.remove(AnotherSetOfFlags::ANOTHER_FLAG);\n        assert_eq!(e3, AnotherSetOfFlags::empty());\n    }\n\n    #[test]\n    fn test_operators() {\n        let e1 = Flags::A | Flags::C;\n        let e2 = Flags::B | Flags::C;\n        assert_eq!((e1 | e2), Flags::ABC); // union\n        assert_eq!((e1 & e2), Flags::C); // intersection\n        assert_eq!((e1 - e2), Flags::A); // set difference\n        assert_eq!(!e2, Flags::A); // set complement\n        assert_eq!(e1 ^ e2, Flags::A | Flags::B); // toggle\n        let mut e3 = e1;\n        e3.toggle(e2);\n        assert_eq!(e3, Flags::A | Flags::B);\n\n        let mut m4 = AnotherSetOfFlags::empty();\n        m4.toggle(AnotherSetOfFlags::empty());\n        assert_eq!(m4, AnotherSetOfFlags::empty());\n    }\n\n    #[test]\n    fn test_operators_unchecked() {\n        let extra = unsafe { Flags::from_bits_unchecked(0b1000) };\n        let e1 = Flags::A | Flags::C | extra;\n        let e2 = Flags::B | Flags::C;\n        assert_eq!((e1 | e2), (Flags::ABC | extra)); // union\n        assert_eq!((e1 & e2), Flags::C); // intersection\n        assert_eq!((e1 - e2), (Flags::A | extra)); // set difference\n        assert_eq!(!e2, Flags::A); // set complement\n        assert_eq!(!e1, Flags::B); // set complement\n        assert_eq!(e1 ^ e2, Flags::A | Flags::B | extra); // toggle\n        let mut e3 = e1;\n        e3.toggle(e2);\n        assert_eq!(e3, Flags::A | Flags::B | extra);\n    }\n\n    #[test]\n    fn test_set_ops_basic() {\n        let ab = Flags::A.union(Flags::B);\n        let ac = Flags::A.union(Flags::C);\n        let bc = Flags::B.union(Flags::C);\n        assert_eq!(ab.bits, 0b011);\n        assert_eq!(bc.bits, 0b110);\n        assert_eq!(ac.bits, 0b101);\n\n        assert_eq!(ab, Flags::B.union(Flags::A));\n        assert_eq!(ac, Flags::C.union(Flags::A));\n        assert_eq!(bc, Flags::C.union(Flags::B));\n\n        assert_eq!(ac, Flags::A | Flags::C);\n        assert_eq!(bc, Flags::B | Flags::C);\n        assert_eq!(ab.union(bc), Flags::ABC);\n\n        assert_eq!(ac, Flags::A | Flags::C);\n        assert_eq!(bc, Flags::B | Flags::C);\n\n        assert_eq!(ac.union(bc), ac | bc);\n        assert_eq!(ac.union(bc), Flags::ABC);\n        assert_eq!(bc.union(ac), Flags::ABC);\n\n        assert_eq!(ac.intersection(bc), ac & bc);\n        assert_eq!(ac.intersection(bc), Flags::C);\n        assert_eq!(bc.intersection(ac), Flags::C);\n\n        assert_eq!(ac.difference(bc), ac - bc);\n        assert_eq!(bc.difference(ac), bc - ac);\n        assert_eq!(ac.difference(bc), Flags::A);\n        assert_eq!(bc.difference(ac), Flags::B);\n\n        assert_eq!(bc.complement(), !bc);\n        assert_eq!(bc.complement(), Flags::A);\n        assert_eq!(ac.symmetric_difference(bc), Flags::A.union(Flags::B));\n        assert_eq!(bc.symmetric_difference(ac), Flags::A.union(Flags::B));\n    }\n\n    #[test]\n    fn test_set_ops_const() {\n        // These just test that these compile and don't cause use-site panics\n        // (would be possible if we had some sort of UB)\n        const INTERSECT: Flags = Flags::all().intersection(Flags::C);\n        const UNION: Flags = Flags::A.union(Flags::C);\n        const DIFFERENCE: Flags = Flags::all().difference(Flags::A);\n        const COMPLEMENT: Flags = Flags::C.complement();\n        const SYM_DIFFERENCE: Flags = UNION.symmetric_difference(DIFFERENCE);\n        assert_eq!(INTERSECT, Flags::C);\n        assert_eq!(UNION, Flags::A | Flags::C);\n        assert_eq!(DIFFERENCE, Flags::all() - Flags::A);\n        assert_eq!(COMPLEMENT, !Flags::C);\n        assert_eq!(SYM_DIFFERENCE, (Flags::A | Flags::C) ^ (Flags::all() - Flags::A));\n    }\n\n    #[test]\n    fn test_set_ops_unchecked() {\n        let extra = unsafe { Flags::from_bits_unchecked(0b1000) };\n        let e1 = Flags::A.union(Flags::C).union(extra);\n        let e2 = Flags::B.union(Flags::C);\n        assert_eq!(e1.bits, 0b1101);\n        assert_eq!(e1.union(e2), (Flags::ABC | extra));\n        assert_eq!(e1.intersection(e2), Flags::C);\n        assert_eq!(e1.difference(e2), Flags::A | extra);\n        assert_eq!(e2.difference(e1), Flags::B);\n        assert_eq!(e2.complement(), Flags::A);\n        assert_eq!(e1.complement(), Flags::B);\n        assert_eq!(e1.symmetric_difference(e2), Flags::A | Flags::B | extra); // toggle\n    }\n\n    #[test]\n    fn test_set_ops_exhaustive() {\n        // Define a flag that contains gaps to help exercise edge-cases,\n        // especially around \"unknown\" flags (e.g. ones outside of `all()`\n        // `from_bits_unchecked`).\n        // - when lhs and rhs both have different sets of unknown flags.\n        // - unknown flags at both ends, and in the middle\n        // - cases with \"gaps\".\n        bitflags! {\n            struct Test: u16 {\n                // Intentionally no `A`\n                const B = 0b000000010;\n                // Intentionally no `C`\n                const D = 0b000001000;\n                const E = 0b000010000;\n                const F = 0b000100000;\n                const G = 0b001000000;\n                // Intentionally no `H`\n                const I = 0b100000000;\n            }\n        }\n        let iter_test_flags =\n            || (0..=0b111_1111_1111).map(|bits| unsafe { Test::from_bits_unchecked(bits) });\n\n        for a in iter_test_flags() {\n            assert_eq!(\n                a.complement(),\n                Test::from_bits_truncate(!a.bits),\n                \"wrong result: !({:?})\",\n                a,\n            );\n            assert_eq!(a.complement(), !a, \"named != op: !({:?})\", a);\n            for b in iter_test_flags() {\n                // Check that the named operations produce the expected bitwise\n                // values.\n                assert_eq!(\n                    a.union(b).bits,\n                    a.bits | b.bits,\n                    \"wrong result: `{:?}` | `{:?}`\",\n                    a,\n                    b,\n                );\n                assert_eq!(\n                    a.intersection(b).bits,\n                    a.bits & b.bits,\n                    \"wrong result: `{:?}` & `{:?}`\",\n                    a,\n                    b,\n                );\n                assert_eq!(\n                    a.symmetric_difference(b).bits,\n                    a.bits ^ b.bits,\n                    \"wrong result: `{:?}` ^ `{:?}`\",\n                    a,\n                    b,\n                );\n                assert_eq!(\n                    a.difference(b).bits,\n                    a.bits & !b.bits,\n                    \"wrong result: `{:?}` - `{:?}`\",\n                    a,\n                    b,\n                );\n                // Note: Difference is checked as both `a - b` and `b - a`\n                assert_eq!(\n                    b.difference(a).bits,\n                    b.bits & !a.bits,\n                    \"wrong result: `{:?}` - `{:?}`\",\n                    b,\n                    a,\n                );\n                // Check that the named set operations are equivalent to the\n                // bitwise equivalents\n                assert_eq!(a.union(b), a | b, \"named != op: `{:?}` | `{:?}`\", a, b,);\n                assert_eq!(\n                    a.intersection(b),\n                    a & b,\n                    \"named != op: `{:?}` & `{:?}`\",\n                    a,\n                    b,\n                );\n                assert_eq!(\n                    a.symmetric_difference(b),\n                    a ^ b,\n                    \"named != op: `{:?}` ^ `{:?}`\",\n                    a,\n                    b,\n                );\n                assert_eq!(a.difference(b), a - b, \"named != op: `{:?}` - `{:?}`\", a, b,);\n                // Note: Difference is checked as both `a - b` and `b - a`\n                assert_eq!(b.difference(a), b - a, \"named != op: `{:?}` - `{:?}`\", b, a,);\n                // Verify that the operations which should be symmetric are\n                // actually symmetric.\n                assert_eq!(a.union(b), b.union(a), \"asymmetry: `{:?}` | `{:?}`\", a, b,);\n                assert_eq!(\n                    a.intersection(b),\n                    b.intersection(a),\n                    \"asymmetry: `{:?}` & `{:?}`\",\n                    a,\n                    b,\n                );\n                assert_eq!(\n                    a.symmetric_difference(b),\n                    b.symmetric_difference(a),\n                    \"asymmetry: `{:?}` ^ `{:?}`\",\n                    a,\n                    b,\n                );\n            }\n        }\n    }\n\n    #[test]\n    fn test_set() {\n        let mut e1 = Flags::A | Flags::C;\n        e1.set(Flags::B, true);\n        e1.set(Flags::C, false);\n\n        assert_eq!(e1, Flags::A | Flags::B);\n    }\n\n    #[test]\n    fn test_assignment_operators() {\n        let mut m1 = Flags::empty();\n        let e1 = Flags::A | Flags::C;\n        // union\n        m1 |= Flags::A;\n        assert_eq!(m1, Flags::A);\n        // intersection\n        m1 &= e1;\n        assert_eq!(m1, Flags::A);\n        // set difference\n        m1 -= m1;\n        assert_eq!(m1, Flags::empty());\n        // toggle\n        m1 ^= e1;\n        assert_eq!(m1, e1);\n    }\n\n    #[test]\n    fn test_const_fn() {\n        const _M1: Flags = Flags::empty();\n\n        const M2: Flags = Flags::A;\n        assert_eq!(M2, Flags::A);\n\n        const M3: Flags = Flags::C;\n        assert_eq!(M3, Flags::C);\n    }\n\n    #[test]\n    fn test_extend() {\n        let mut flags;\n\n        flags = Flags::empty();\n        flags.extend([].iter().cloned());\n        assert_eq!(flags, Flags::empty());\n\n        flags = Flags::empty();\n        flags.extend([Flags::A, Flags::B].iter().cloned());\n        assert_eq!(flags, Flags::A | Flags::B);\n\n        flags = Flags::A;\n        flags.extend([Flags::A, Flags::B].iter().cloned());\n        assert_eq!(flags, Flags::A | Flags::B);\n\n        flags = Flags::B;\n        flags.extend([Flags::A, Flags::ABC].iter().cloned());\n        assert_eq!(flags, Flags::ABC);\n    }\n\n    #[test]\n    fn test_from_iterator() {\n        assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty());\n        assert_eq!(\n            [Flags::A, Flags::B].iter().cloned().collect::<Flags>(),\n            Flags::A | Flags::B\n        );\n        assert_eq!(\n            [Flags::A, Flags::ABC].iter().cloned().collect::<Flags>(),\n            Flags::ABC\n        );\n    }\n\n    #[test]\n    fn test_lt() {\n        let mut a = Flags::empty();\n        let mut b = Flags::empty();\n\n        assert!(!(a < b) && !(b < a));\n        b = Flags::B;\n        assert!(a < b);\n        a = Flags::C;\n        assert!(!(a < b) && b < a);\n        b = Flags::C | Flags::B;\n        assert!(a < b);\n    }\n\n    #[test]\n    fn test_ord() {\n        let mut a = Flags::empty();\n        let mut b = Flags::empty();\n\n        assert!(a <= b && a >= b);\n        a = Flags::A;\n        assert!(a > b && a >= b);\n        assert!(b < a && b <= a);\n        b = Flags::B;\n        assert!(b > a && b >= a);\n        assert!(a < b && a <= b);\n    }\n\n    fn hash<T: Hash>(t: &T) -> u64 {\n        let mut s = DefaultHasher::new();\n        t.hash(&mut s);\n        s.finish()\n    }\n\n    #[test]\n    fn test_hash() {\n        let mut x = Flags::empty();\n        let mut y = Flags::empty();\n        assert_eq!(hash(&x), hash(&y));\n        x = Flags::all();\n        y = Flags::ABC;\n        assert_eq!(hash(&x), hash(&y));\n    }\n\n    #[test]\n    fn test_default() {\n        assert_eq!(Flags::empty(), Flags::default());\n    }\n\n    #[test]\n    fn test_debug() {\n        assert_eq!(format!(\"{:?}\", Flags::A | Flags::B), \"A | B\");\n        assert_eq!(format!(\"{:?}\", Flags::empty()), \"(empty)\");\n        assert_eq!(format!(\"{:?}\", Flags::ABC), \"A | B | C | ABC\");\n        let extra = unsafe { Flags::from_bits_unchecked(0xb8) };\n        assert_eq!(format!(\"{:?}\", extra), \"0xb8\");\n        assert_eq!(format!(\"{:?}\", Flags::A | extra), \"A | 0xb8\");\n\n        assert_eq!(\n            format!(\"{:?}\", Flags::ABC | extra),\n            \"A | B | C | ABC | 0xb8\"\n        );\n\n        assert_eq!(format!(\"{:?}\", EmptyFlags::empty()), \"(empty)\");\n    }\n\n    #[test]\n    fn test_binary() {\n        assert_eq!(format!(\"{:b}\", Flags::ABC), \"111\");\n        assert_eq!(format!(\"{:#b}\", Flags::ABC), \"0b111\");\n        let extra = unsafe { Flags::from_bits_unchecked(0b1010000) };\n        assert_eq!(format!(\"{:b}\", Flags::ABC | extra), \"1010111\");\n        assert_eq!(format!(\"{:#b}\", Flags::ABC | extra), \"0b1010111\");\n    }\n\n    #[test]\n    fn test_octal() {\n        assert_eq!(format!(\"{:o}\", LongFlags::LONG_A), \"177777\");\n        assert_eq!(format!(\"{:#o}\", LongFlags::LONG_A), \"0o177777\");\n        let extra = unsafe { LongFlags::from_bits_unchecked(0o5000000) };\n        assert_eq!(format!(\"{:o}\", LongFlags::LONG_A | extra), \"5177777\");\n        assert_eq!(format!(\"{:#o}\", LongFlags::LONG_A | extra), \"0o5177777\");\n    }\n\n    #[test]\n    fn test_lowerhex() {\n        assert_eq!(format!(\"{:x}\", LongFlags::LONG_A), \"ffff\");\n        assert_eq!(format!(\"{:#x}\", LongFlags::LONG_A), \"0xffff\");\n        let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) };\n        assert_eq!(format!(\"{:x}\", LongFlags::LONG_A | extra), \"e0ffff\");\n        assert_eq!(format!(\"{:#x}\", LongFlags::LONG_A | extra), \"0xe0ffff\");\n    }\n\n    #[test]\n    fn test_upperhex() {\n        assert_eq!(format!(\"{:X}\", LongFlags::LONG_A), \"FFFF\");\n        assert_eq!(format!(\"{:#X}\", LongFlags::LONG_A), \"0xFFFF\");\n        let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) };\n        assert_eq!(format!(\"{:X}\", LongFlags::LONG_A | extra), \"E0FFFF\");\n        assert_eq!(format!(\"{:#X}\", LongFlags::LONG_A | extra), \"0xE0FFFF\");\n    }\n\n    mod submodule {\n        bitflags! {\n            pub struct PublicFlags: i8 {\n                const X = 0;\n            }\n\n            struct PrivateFlags: i8 {\n                const Y = 0;\n            }\n        }\n\n        #[test]\n        fn test_private() {\n            let _ = PrivateFlags::Y;\n        }\n    }\n\n    #[test]\n    fn test_public() {\n        let _ = submodule::PublicFlags::X;\n    }\n\n    mod t1 {\n        mod foo {\n            pub type Bar = i32;\n        }\n\n        bitflags! {\n            /// baz\n            struct Flags: foo::Bar {\n                const A = 0b00000001;\n                #[cfg(foo)]\n                const B = 0b00000010;\n                #[cfg(foo)]\n                const C = 0b00000010;\n            }\n        }\n    }\n\n    #[test]\n    fn test_in_function() {\n        bitflags! {\n           struct Flags: u8 {\n                const A = 1;\n                #[cfg(any())] // false\n                const B = 2;\n            }\n        }\n        assert_eq!(Flags::all(), Flags::A);\n        assert_eq!(format!(\"{:?}\", Flags::A), \"A\");\n    }\n\n    #[test]\n    fn test_deprecated() {\n        bitflags! {\n            pub struct TestFlags: u32 {\n                #[deprecated(note = \"Use something else.\")]\n                const ONE = 1;\n            }\n        }\n    }\n\n    #[test]\n    fn test_pub_crate() {\n        mod module {\n            bitflags! {\n                pub (crate) struct Test: u8 {\n                    const FOO = 1;\n                }\n            }\n        }\n\n        assert_eq!(module::Test::FOO.bits(), 1);\n    }\n\n    #[test]\n    fn test_pub_in_module() {\n        mod module {\n            mod submodule {\n                bitflags! {\n                    // `pub (in super)` means only the module `module` will\n                    // be able to access this.\n                    pub (in super) struct Test: u8 {\n                        const FOO = 1;\n                    }\n                }\n            }\n\n            mod test {\n                // Note: due to `pub (in super)`,\n                // this cannot be accessed directly by the testing code.\n                pub(super) fn value() -> u8 {\n                    super::submodule::Test::FOO.bits()\n                }\n            }\n\n            pub fn value() -> u8 {\n                test::value()\n            }\n        }\n\n        assert_eq!(module::value(), 1)\n    }\n\n    #[test]\n    fn test_zero_value_flags() {\n        bitflags! {\n            struct Flags: u32 {\n                const NONE = 0b0;\n                const SOME = 0b1;\n            }\n        }\n\n        assert!(Flags::empty().contains(Flags::NONE));\n        assert!(Flags::SOME.contains(Flags::NONE));\n        assert!(Flags::NONE.is_empty());\n\n        assert_eq!(format!(\"{:?}\", Flags::empty()), \"NONE\");\n        assert_eq!(format!(\"{:?}\", Flags::SOME), \"SOME\");\n    }\n\n    #[test]\n    fn test_empty_bitflags() {\n        bitflags! {}\n    }\n\n    #[test]\n    fn test_u128_bitflags() {\n        bitflags! {\n            struct Flags128: u128 {\n                const A = 0x0000_0000_0000_0000_0000_0000_0000_0001;\n                const B = 0x0000_0000_0000_1000_0000_0000_0000_0000;\n                const C = 0x8000_0000_0000_0000_0000_0000_0000_0000;\n                const ABC = Self::A.bits | Self::B.bits | Self::C.bits;\n            }\n        }\n\n        assert_eq!(Flags128::ABC, Flags128::A | Flags128::B | Flags128::C);\n        assert_eq!(Flags128::A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001);\n        assert_eq!(Flags128::B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000);\n        assert_eq!(Flags128::C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000);\n        assert_eq!(\n            Flags128::ABC.bits,\n            0x8000_0000_0000_1000_0000_0000_0000_0001\n        );\n        assert_eq!(format!(\"{:?}\", Flags128::A), \"A\");\n        assert_eq!(format!(\"{:?}\", Flags128::B), \"B\");\n        assert_eq!(format!(\"{:?}\", Flags128::C), \"C\");\n        assert_eq!(format!(\"{:?}\", Flags128::ABC), \"A | B | C | ABC\");\n    }\n\n    #[test]\n    fn test_serde_bitflags_serialize() {\n        let flags = SerdeFlags::A | SerdeFlags::B;\n\n        let serialized = serde_json::to_string(&flags).unwrap();\n\n        assert_eq!(serialized, r#\"{\"bits\":3}\"#);\n    }\n\n    #[test]\n    fn test_serde_bitflags_deserialize() {\n        let deserialized: SerdeFlags = serde_json::from_str(r#\"{\"bits\":12}\"#).unwrap();\n\n        let expected = SerdeFlags::C | SerdeFlags::D;\n\n        assert_eq!(deserialized.bits, expected.bits);\n    }\n\n    #[test]\n    fn test_serde_bitflags_roundtrip() {\n        let flags = SerdeFlags::A | SerdeFlags::B;\n\n        let deserialized: SerdeFlags = serde_json::from_str(&serde_json::to_string(&flags).unwrap()).unwrap();\n\n        assert_eq!(deserialized.bits, flags.bits);\n    }\n\n    bitflags! {\n        #[derive(serde::Serialize, serde::Deserialize)]\n        struct SerdeFlags: u32 {\n            const A = 1;\n            const B = 2;\n            const C = 4;\n            const D = 8;\n        }\n    }\n}\n"
    },
    {
      "package": "bitflags@2.13.2",
      "sourcePath": "src/lib.rs",
      "sha256": "f8d141a1ba6b1996b33eb34669786ef389d4d5226edad46cec22a561588c324b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n/*!\nGenerate types for C-style flags with ergonomic APIs.\n\n# Getting started\n\nAdd `bitflags` to your `Cargo.toml`:\n\n```toml\n[dependencies.bitflags]\nversion = \"2.13.2\"\n```\n\n## Crate features\n\nThe `bitflags` library defines a few Cargo features that you can opt-in to:\n\n- `std`: Implement the `Error` trait on error types used by `bitflags`.\n- `serde`: Support deriving `serde` traits on generated flags types.\n- `arbitrary`: Support deriving `arbitrary` traits on generated flags types.\n- `bytemuck`: Support deriving `bytemuck` traits on generated flags types.\n\n## Generating flags types\n\nUse the [`bitflags`] macro to generate flags types:\n\n```rust\nuse bitflags::bitflags;\n\nbitflags! {\n    pub struct Flags: u32 {\n        const A = 0b00000001;\n        const B = 0b00000010;\n        const C = 0b00000100;\n    }\n}\n```\n\nSee the docs for the `bitflags` macro for the full syntax.\n\nAlso see the [`example_generated`](./example_generated/index.html) module for an example of what the `bitflags` macro generates for a flags type.\n\n### Externally defined flags\n\nIf you're generating flags types for an external source, such as a C API, you can define\nan extra unnamed flag as a mask of all bits the external source may ever set. Usually this would be all bits (`!0`):\n\n```rust\n# use bitflags::bitflags;\nbitflags! {\n    pub struct Flags: u32 {\n        const A = 0b00000001;\n        const B = 0b00000010;\n        const C = 0b00000100;\n\n        // The source may set any bits\n        const _ = !0;\n    }\n}\n```\n\nWhy should you do this? Generated methods like `all` and truncating operators like `!` only consider\nbits in defined flags. Adding an unnamed flag makes those methods consider additional bits,\nwithout generating additional constants for them. It helps compatibility when the external source\nmay start setting additional bits at any time. The [known and unknown bits](#known-and-unknown-bits)\nsection has more details on this behavior.\n\n### Custom derives\n\nYou can derive some traits on generated flags types if you enable Cargo features. The following\nlibraries are currently supported:\n\n- `serde`: Support `#[derive(Serialize, Deserialize)]`, using text for human-readable formats,\n  and a raw number for binary formats.\n- `arbitrary`: Support `#[derive(Arbitrary)]`, only generating flags values with known bits.\n- `bytemuck`: Support `#[derive(Pod, Zeroable)]`, for casting between flags values and their\n  underlying bits values.\n\nYou can also define your own flags type outside of the [`bitflags`] macro and then use it to generate methods.\nThis can be useful if you need a custom `#[derive]` attribute for a library that `bitflags` doesn't\nnatively support:\n\n```rust\n# use std::fmt::Debug as SomeTrait;\n# use bitflags::bitflags;\n#[derive(SomeTrait)]\npub struct Flags(u32);\n\nbitflags! {\n    impl Flags: u32 {\n        const A = 0b00000001;\n        const B = 0b00000010;\n        const C = 0b00000100;\n    }\n}\n```\n\n### Adding custom methods\n\nThe [`bitflags`] macro supports attributes on generated flags types within the macro itself, while\n`impl` blocks can be added outside of it:\n\n```rust\n# use bitflags::bitflags;\nbitflags! {\n    // Attributes can be applied to flags types\n    #[repr(transparent)]\n    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]\n    pub struct Flags: u32 {\n        const A = 0b00000001;\n        const B = 0b00000010;\n        const C = 0b00000100;\n    }\n}\n\n// Impl blocks can be added to flags types\nimpl Flags {\n    pub fn as_u64(&self) -> u64 {\n        self.bits() as u64\n    }\n}\n```\n\n### Renaming flags\n\nThe [`bitflags`] macro recognizes a special `#[bitflags(flag_name = \"<value>\")]` attribute on flags values to rename them:\n\n```rust\n# use bitflags::bitflags;\nbitflags! {\n    pub struct Flags: u32 {\n        // Add the attribute to a flag to change its name\n        #[bitflags(flag_name = \"a\")]\n        const A = 0b00000001;\n        #[bitflags(flag_name = \"b\")]\n        const B = 0b00000010;\n        #[bitflags(flag_name = \"c\")]\n        const C = 0b00000100;\n    }\n}\n```\n\nWhen applied to a flag value, instead of using its identifier, like `A` as the name, it'll use the given string. This\ndoesn't affect the identifier of the constant itself, just the name recognized when parsing and formatting.\n\n## Working with flags values\n\nUse generated constants and standard bitwise operators to interact with flags values:\n\n```rust\n# use bitflags::bitflags;\n# bitflags! {\n#     #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]\n#     pub struct Flags: u32 {\n#         const A = 0b00000001;\n#         const B = 0b00000010;\n#         const C = 0b00000100;\n#     }\n# }\n// union\nlet ab = Flags::A | Flags::B;\n\n// intersection\nlet a = ab & Flags::A;\n\n// difference\nlet b = ab - Flags::A;\n\n// complement\nlet c = !ab;\n```\n\nSee the docs for the [`Flags`] trait for more details on operators and how they behave.\n\n# Formatting and parsing\n\n`bitflags` defines a text format that can be used to convert any flags value to and from strings.\n\nSee the [`parser`] module for more details.\n\n# Specification\n\nThe terminology and behavior of generated flags types is\n[specified in the source repository](https://github.com/bitflags/bitflags/blob/main/spec.md).\nDetails are repeated in these docs where appropriate, but is exhaustively listed in the spec. Some\nthings are worth calling out explicitly here.\n\n## Flags types, flags values, flags\n\nThe spec and these docs use consistent terminology to refer to things in the bitflags domain:\n\n- **Bits type**: A type that defines a fixed number of bits at specific locations.\n- **Flag**: A set of bits in a bits type that may have a unique name.\n- **Flags type**: A set of defined flags over a specific bits type.\n- **Flags value**: An instance of a flags type using its specific bits value for storage.\n\n```\n# use bitflags::bitflags;\nbitflags! {\n    struct FlagsType: u8 {\n//                    -- Bits type\n//         --------- Flags type\n        const A = 1;\n//            ----- Flag\n    }\n}\n\nlet flag = FlagsType::A;\n//  ---- Flags value\n```\n\n## Known and unknown bits\n\nAny bits in a flag you define are called _known bits_. Any other bits are _unknown bits_.\nIn the following flags type:\n\n```\n# use bitflags::bitflags;\nbitflags! {\n    struct Flags: u8 {\n        const A = 1;\n        const B = 1 << 1;\n        const C = 1 << 2;\n    }\n}\n```\n\nThe known bits are `0b0000_0111` and the unknown bits are `0b1111_1000`.\n\n`bitflags` doesn't guarantee that a flags value will only ever have known bits set, but some operators\nwill unset any unknown bits they encounter. In a future version of `bitflags`, all operators will\nunset unknown bits.\n\nIf you're using `bitflags` for flags types defined externally, such as from C, you probably want all\nbits to be considered known, in case that external source changes. You can do this using an unnamed\nflag, as described in [externally defined flags](#externally-defined-flags).\n\n## Zero-bit flags\n\nFlags with no bits set should be avoided because they interact strangely with [`Flags::contains`]\nand [`Flags::intersects`]. A zero-bit flag is always contained, but is never intersected. The\nnames of zero-bit flags can be parsed, but are never formatted.\n\n## Multi-bit flags\n\nFlags that set multiple bits should be avoided unless each bit is also in a single-bit flag.\nTake the following flags type as an example:\n\n```\n# use bitflags::bitflags;\nbitflags! {\n    struct Flags: u8 {\n        const A = 1;\n        const B = 1 | 1 << 1;\n    }\n}\n```\n\nThe result of `Flags::A ^ Flags::B` is `0b0000_0010`, which doesn't correspond to either\n`Flags::A` or `Flags::B` even though it's still a known bit.\n*/\n\n#![cfg_attr(not(any(feature = \"std\", test)), no_std)]\n#![cfg_attr(not(test), forbid(unsafe_code))]\n#![cfg_attr(test, allow(mixed_script_confusables))]\n\n#[doc(inline)]\npub use traits::{Bits, Flag, Flags};\n\npub mod iter;\npub mod parser;\n\nmod traits;\n\n#[doc(hidden)]\npub mod __private {\n    #[allow(unused_imports)]\n    // Easier than conditionally checking any optional external dependencies\n    pub use crate::{external::__private::*, traits::__private::*};\n\n    pub use core;\n}\n\n#[allow(unused_imports)]\npub use external::*;\n\n#[allow(deprecated)]\npub use traits::BitFlags;\n\n/*\nHow does the bitflags crate work?\n\nThis library generates a `struct` in the end-user's crate with a bunch of constants on it that represent flags.\nThe difference between `bitflags` and a lot of other libraries is that we don't actually control the generated `struct` in the end.\nIt's part of the end-user's crate, so it belongs to them. That makes it difficult to extend `bitflags` with new functionality\nbecause we could end up breaking valid code that was already written.\n\nOur solution is to split the type we generate into two: the public struct owned by the end-user, and an internal struct owned by `bitflags` (us).\nTo give you an example, let's say we had a crate that called `bitflags!`:\n\n```rust\nbitflags! {\n    pub struct MyFlags: u32 {\n        const A = 1;\n        const B = 2;\n    }\n}\n```\n\nWhat they'd end up with looks something like this:\n\n```rust\npub struct MyFlags(<MyFlags as PublicFlags>::InternalBitFlags);\n\nconst _: () = {\n    #[repr(transparent)]\n    #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]\n    pub struct MyInternalBitFlags {\n        bits: u32,\n    }\n\n    impl PublicFlags for MyFlags {\n        type Internal = InternalBitFlags;\n    }\n};\n```\n\nIf we want to expose something like a new trait impl for generated flags types, we add it to our generated `MyInternalBitFlags`,\nand let `#[derive]` on `MyFlags` pick up that implementation, if an end-user chooses to add one.\n\nThe public API is generated in the `__impl_public_flags!` macro, and the internal API is generated in\nthe `__impl_internal_flags!` macro.\n\nThe macros are split into 3 modules:\n\n- `public`: where the user-facing flags types are generated.\n- `internal`: where the `bitflags`-facing flags types are generated.\n- `external`: where external library traits are implemented conditionally.\n*/\n\n/**\nGenerate a flags type.\n\n# `struct` mode\n\nA declaration that begins with `$vis struct` will generate a `struct` for a flags type, along with\nmethods and trait implementations for it. The body of the declaration defines flags as constants,\nwhere each constant is a flags value of the generated flags type.\n\n## Examples\n\nGenerate a flags type using `u8` as the bits type:\n\n```\n# use bitflags::bitflags;\nbitflags! {\n    struct Flags: u8 {\n        const A = 1;\n        const B = 1 << 1;\n        const C = 0b0000_0100;\n    }\n}\n```\n\nFlags types are private by default and accept standard visibility modifiers. Flags themselves\nare always public:\n\n```\n# use bitflags::bitflags;\nbitflags! {\n    pub struct Flags: u8 {\n        // Constants are always `pub`\n        const A = 1;\n    }\n}\n```\n\nFlags may refer to other flags using their [`Flags::bits`] value:\n\n```\n# use bitflags::bitflags;\nbitflags! {\n    struct Flags: u8 {\n        const A = 1;\n        const B = 1 << 1;\n        const AB = Flags::A.bits() | Flags::B.bits();\n    }\n}\n```\n\nA single `bitflags` invocation may include zero or more flags type declarations:\n\n```\n# use bitflags::bitflags;\nbitflags! {}\n\nbitflags! {\n    struct Flags1: u8 {\n        const A = 1;\n    }\n\n    struct Flags2: u8 {\n        const A = 1;\n    }\n}\n```\n\n# `impl` mode\n\nA declaration that begins with `impl` will only generate methods and trait implementations for the\n`struct` defined outside of the `bitflags` macro.\n\nThe struct itself must be a newtype using the bits type as its field.\n\nThe syntax for `impl` mode is identical to `struct` mode besides the starting token.\n\n## Examples\n\nImplement flags methods and traits for a custom flags type using `u8` as its underlying bits type:\n\n```\n# use bitflags::bitflags;\nstruct Flags(u8);\n\nbitflags! {\n    impl Flags: u8 {\n        const A = 1;\n        const B = 1 << 1;\n        const C = 0b0000_0100;\n    }\n}\n```\n\n# Named and unnamed flags\n\nConstants in the body of a declaration are flags. The identifier of the constant is the name of\nthe flag. If the identifier is `_`, then the flag is unnamed. Unnamed flags don't appear in the\ngenerated API, but affect how bits are truncated.\n\n## Examples\n\nAdding an unnamed flag that makes all bits known:\n\n```\n# use bitflags::bitflags;\nbitflags! {\n    struct Flags: u8 {\n        const A = 1;\n        const B = 1 << 1;\n\n        const _ = !0;\n    }\n}\n```\n\nFlags types may define multiple unnamed flags:\n\n```\n# use bitflags::bitflags;\nbitflags! {\n    struct Flags: u8 {\n        const _ = 1;\n        const _ = 1 << 1;\n    }\n}\n```\n*/\n#[macro_export]\nmacro_rules! bitflags {\n    (\n        $(#[$outer:meta])*\n        $vis:vis struct $BitFlags:ident: $T:ty {\n            $(\n                $(#[$inner:ident $($args:tt)*])*\n                const $Flag:tt = $value:expr;\n            )*\n        }\n\n        $($t:tt)*\n    ) => {\n        // Declared in the scope of the `bitflags!` call\n        // This type appears in the end-user's API\n        $crate::__declare_public_bitflags! {\n            $(#[$outer])*\n            $vis struct $BitFlags\n        }\n\n        // Workaround for: https://github.com/bitflags/bitflags/issues/320\n        // Pulled outside of the `const _: () = {}` block to avoid triggering an ICE\n        $crate::__impl_public_bitflags_consts! {\n            #[allow(\n                dead_code,\n                deprecated,\n                unused_doc_comments,\n                unused_attributes,\n                unused_mut,\n                unused_imports,\n                non_upper_case_globals,\n                clippy::min_ident_chars,\n                clippy::assign_op_pattern,\n                clippy::indexing_slicing,\n                clippy::same_name_method,\n                clippy::iter_without_into_iter,\n            )]\n            $BitFlags: $T {\n                $(\n                    $(#[$inner $($args)*])*\n                    const $Flag = $value;\n                )*\n            }\n        }\n\n        #[allow(\n            dead_code,\n            deprecated,\n            unused_doc_comments,\n            unused_attributes,\n            unused_mut,\n            unused_imports,\n            non_upper_case_globals,\n            clippy::min_ident_chars,\n            clippy::assign_op_pattern,\n            clippy::indexing_slicing,\n            clippy::same_name_method,\n            clippy::iter_without_into_iter,\n        )]\n        const _: () = {\n            // Declared in a \"hidden\" scope that can't be reached directly\n            // These types don't appear in the end-user's API\n            $crate::__declare_internal_bitflags! {\n                $vis struct InternalBitFlags: $T\n            }\n\n            $crate::__impl_internal_bitflags! {\n                InternalBitFlags: $T, $BitFlags {\n                    $(\n                        $(#[$inner $($args)*])*\n                        const $Flag = $value;\n                    )*\n                }\n            }\n\n            // This is where new library trait implementations can be added\n            $crate::__impl_external_bitflags! {\n                InternalBitFlags: $T, $BitFlags {\n                    $(\n                        $(#[$inner $($args)*])*\n                        const $Flag;\n                    )*\n                }\n            }\n\n            $crate::__impl_public_bitflags_forward! {\n                $BitFlags: $T, InternalBitFlags\n            }\n\n            $crate::__impl_public_bitflags_ops! {\n                $BitFlags\n            }\n\n            $crate::__impl_public_bitflags_iter! {\n                $BitFlags: $T, $BitFlags\n            }\n        };\n\n        $crate::bitflags! {\n            $($t)*\n        }\n    };\n    (\n        $(#[$outer:meta])*\n        impl $BitFlags:ident: $T:ty {\n            $(\n                $(#[$inner:ident $($args:tt)*])*\n                const $Flag:tt = $value:expr;\n            )*\n        }\n\n        $($t:tt)*\n    ) => {\n        // Workaround for: https://github.com/bitflags/bitflags/issues/320\n        // Pulled outside of the `const _: () = {}` block to avoid triggering an ICE\n        $crate::__impl_public_bitflags_consts! {\n            #[allow(\n                dead_code,\n                deprecated,\n                unused_doc_comments,\n                unused_attributes,\n                unused_mut,\n                unused_imports,\n                non_upper_case_globals,\n                clippy::min_ident_chars,\n                clippy::assign_op_pattern,\n                clippy::iter_without_into_iter,\n            )]\n            $BitFlags: $T {\n                $(\n                    $(#[$inner $($args)*])*\n                    const $Flag = $value;\n                )*\n            }\n        }\n\n        #[allow(\n            dead_code,\n            deprecated,\n            unused_doc_comments,\n            unused_attributes,\n            unused_mut,\n            unused_imports,\n            non_upper_case_globals,\n            clippy::min_ident_chars,\n            clippy::assign_op_pattern,\n            clippy::iter_without_into_iter,\n        )]\n        const _: () = {\n            $crate::__impl_public_bitflags! {\n                $(#[$outer])*\n                $BitFlags: $T, $BitFlags {\n                    $(\n                        $(#[$inner $($args)*])*\n                        const $Flag = $value;\n                    )*\n                }\n            }\n\n            $crate::__impl_public_bitflags_ops! {\n                $BitFlags\n            }\n\n            $crate::__impl_public_bitflags_iter! {\n                $BitFlags: $T, $BitFlags\n            }\n        };\n\n        $crate::bitflags! {\n            $($t)*\n        }\n    };\n    () => {};\n}\n\n/// Implement functions on bitflags types.\n///\n/// We need to be careful about adding new methods and trait implementations here because they\n/// could conflict with items added by the end-user.\n#[macro_export]\n#[doc(hidden)]\nmacro_rules! __impl_bitflags {\n    (\n        // These param names must be passed in to make the macro work.\n        // Just use `params: self, bits, name, other, value;`.\n        params: $self:ident, $bits:ident, $name:ident, $other:ident, $value:ident;\n        $(#[$outer:meta])*\n        $PublicBitFlags:ident: $T:ty {\n            fn empty() $empty_body:block\n            fn all() $all_body:block\n            fn bits(&self) $bits_body:block\n            fn from_bits(bits) $from_bits_body:block\n            fn from_bits_truncate(bits) $from_bits_truncate_body:block\n            fn from_bits_retain(bits) $from_bits_retain_body:block\n            fn from_name(name) $from_name_body:block\n            fn is_empty(&self) $is_empty_body:block\n            fn is_all(&self) $is_all_body:block\n            fn intersects(&self, other) $intersects_body:block\n            fn contains(&self, other) $contains_body:block\n            fn insert(&mut self, other) $insert_body:block\n            fn remove(&mut self, other) $remove_body:block\n            fn toggle(&mut self, other) $toggle_body:block\n            fn set(&mut self, other, value) $set_body:block\n            fn intersection(self, other) $intersection_body:block\n            fn union(self, other) $union_body:block\n            fn difference(self, other) $difference_body:block\n            fn symmetric_difference(self, other) $symmetric_difference_body:block\n            fn complement(self) $complement_body:block\n        }\n    ) => {\n        $(#[$outer])*\n        impl $PublicBitFlags {\n            /// Get a flags value with all bits unset.\n            #[inline]\n            pub const fn empty() -> Self\n                $empty_body\n\n            /// Get a flags value with all known bits set.\n            #[inline]\n            pub const fn all() -> Self\n                $all_body\n\n            /// Get the underlying bits value.\n            ///\n            /// The returned value is exactly the bits set in this flags value.\n            #[inline]\n            pub const fn bits(&$self) -> $T\n                $bits_body\n\n            /// Convert from a bits value.\n            ///\n            /// This method will return `None` if any unknown bits are set.\n            #[inline]\n            pub const fn from_bits($bits: $T) -> $crate::__private::core::option::Option<Self>\n                $from_bits_body\n\n            /// Convert from a bits value, unsetting any unknown bits.\n            #[inline]\n            pub const fn from_bits_truncate($bits: $T) -> Self\n                $from_bits_truncate_body\n\n            /// Convert from a bits value exactly.\n            #[inline]\n            pub const fn from_bits_retain($bits: $T) -> Self\n                $from_bits_retain_body\n\n            /// Get a flags value with the bits of a flag with the given name set.\n            ///\n            /// This method will return `None` if `name` is empty or doesn't\n            /// correspond to any named flag.\n            #[inline]\n            pub fn from_name($name: &str) -> $crate::__private::core::option::Option<Self>\n                $from_name_body\n\n            /// Whether all bits in `self` are unset.\n            #[inline]\n            pub const fn is_empty(&$self) -> bool\n                $is_empty_body\n\n            /// Whether all known bits in this flags value are set.\n            #[inline]\n            pub const fn is_all(&$self) -> bool\n                $is_all_body\n\n            /// Whether any set bits in `other` are also set in `self`.\n            #[inline]\n            pub const fn intersects(&$self, $other: Self) -> bool\n                $intersects_body\n\n            /// Whether all set bits in `other` are also set in `self`.\n            #[inline]\n            pub const fn contains(&$self, $other: Self) -> bool\n                $contains_body\n\n            /// The bitwise or (`|`) of the bits in `self` and `other`.\n            #[inline]\n            pub fn insert(&mut $self, $other: Self)\n                $insert_body\n\n            /// The intersection of `self` with the complement of `other` (`&!`).\n            ///\n            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.\n            /// `remove` won't truncate `other`, but the `!` operator will.\n            #[inline]\n            pub fn remove(&mut $self, $other: Self)\n                $remove_body\n\n            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.\n            #[inline]\n            pub fn toggle(&mut $self, $other: Self)\n                $toggle_body\n\n            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.\n            #[inline]\n            pub fn set(&mut $self, $other: Self, $value: bool)\n                $set_body\n\n            /// The bitwise and (`&`) of the bits in `self` and `other`.\n            #[inline]\n            #[must_use]\n            pub const fn intersection($self, $other: Self) -> Self\n                $intersection_body\n\n            /// The bitwise or (`|`) of the bits in `self` and `other`.\n            #[inline]\n            #[must_use]\n            pub const fn union($self, $other: Self) -> Self\n                $union_body\n\n            /// The intersection of `self` with the complement of `other` (`&!`).\n            ///\n            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.\n            /// `difference` won't truncate `other`, but the `!` operator will.\n            #[inline]\n            #[must_use]\n            pub const fn difference($self, $other: Self) -> Self\n                $difference_body\n\n            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.\n            #[inline]\n            #[must_use]\n            pub const fn symmetric_difference($self, $other: Self) -> Self\n                $symmetric_difference_body\n\n            /// The bitwise negation (`!`) of the bits in `self`, truncating the result.\n            #[inline]\n            #[must_use]\n            pub const fn complement($self) -> Self\n                $complement_body\n        }\n    };\n}\n\n/// A macro that matches flags values, similar to Rust's `match` statement.\n///\n/// In a regular `match` statement, the syntax `Flag::A | Flag::B` is interpreted as an or-pattern,\n/// instead of the bitwise-or of `Flag::A` and `Flag::B`. This can be surprising when combined with flags types\n/// because `Flag::A | Flag::B` won't match the pattern `Flag::A | Flag::B`. This macro is an alternative to\n/// `match` for flags values that doesn't have this issue.\n///\n/// # Syntax\n///\n/// ```ignore\n/// bitflags_match!(expression, {\n///     pattern1 => result1,\n///     pattern2 => result2,\n///     ..\n///     _ => default_result,\n/// })\n/// ```\n///\n/// The final `_ => default_result` arm is required, otherwise the macro will fail to compile.\n///\n/// # Examples\n///\n/// ```rust\n/// use bitflags::{bitflags, bitflags_match};\n///\n/// bitflags! {\n///     #[derive(PartialEq)]\n///     struct Flags: u8 {\n///         const A = 1 << 0;\n///         const B = 1 << 1;\n///         const C = 1 << 2;\n///     }\n/// }\n///\n/// let flags = Flags::A | Flags::B;\n///\n/// // Prints `the value is A and B`\n/// bitflags_match!(flags, {\n///     Flags::A | Flags::B => println!(\"the value is A and B\"),\n///     _ => println!(\"the value is not A and B\"),\n/// });\n///\n/// // Prints `the value is not A`\n/// bitflags_match!(flags, {\n///     Flags::A => println!(\"the value is A\"),\n///     _ => println!(\"the value is not A\"),\n/// });\n/// ```\n///\n/// # How it works\n///\n/// The macro expands to a series of `if` statements, **checking equality** between the input expression\n/// and each pattern. This allows for correct matching of bitflag combinations, which is not possible\n/// with a regular match expression due to the way bitflags are implemented.\n///\n/// Patterns are evaluated in the order they appear in the macro.\n#[macro_export]\nmacro_rules! bitflags_match {\n    ($operation:expr, {\n        $($t:tt)*\n    }) => {\n        // Expand to a closure so we can use `return`\n        // This makes it possible to apply attributes to the \"match arms\"\n        (|| {\n            $crate::__bitflags_match!($operation, { $($t)* })\n        })()\n    };\n}\n\n/// Expand the `bitflags_match` macro\n#[macro_export]\n#[doc(hidden)]\nmacro_rules! __bitflags_match {\n    // Eat an optional `,` following a block match arm\n    ($operation:expr, { $pattern:expr => { $($body:tt)* } , $($t:tt)+ }) => {\n        $crate::__bitflags_match!($operation, { $pattern => { $($body)* } $($t)+ })\n    };\n    // Expand a block match arm `A => { .. }`\n    ($operation:expr, { $pattern:expr => { $($body:tt)* } $($t:tt)+ }) => {\n        {\n            if $operation == $pattern {\n                return {\n                    $($body)*\n                };\n            }\n\n            $crate::__bitflags_match!($operation, { $($t)+ })\n        }\n    };\n    // Expand an expression match arm `A => x,`\n    ($operation:expr, { $pattern:expr => $body:expr , $($t:tt)+ }) => {\n        {\n            if $operation == $pattern {\n                return $body;\n            }\n\n            $crate::__bitflags_match!($operation, { $($t)+ })\n        }\n    };\n    // Expand the default case\n    ($operation:expr, { _ => $default:expr $(,)? }) => {\n        $default\n    }\n}\n\n/// Implement a flag, which may be a wildcard `_`.\n///\n/// Named flags will emit the `named` block, and unnamed flags will emit the `unnamed` block.\n#[macro_export]\n#[doc(hidden)]\nmacro_rules! __bitflags_flag {\n    (\n        {\n            name: _,\n            named: { $($named:tt)* },\n            unnamed: { $($unnamed:tt)* },\n        }\n    ) => {\n        $($unnamed)*\n    };\n    (\n        {\n            name: $Flag:ident,\n            named: { $($named:tt)* },\n            unnamed: { $($unnamed:tt)* },\n        }\n    ) => {\n        $($named)*\n    };\n}\n\n/*\nAttribute inspection macros\n\nThe following macros all use the same pattern for searching for specific attributes and transforming\na target token tree. They're implementations of _token-tree munchers_, where each token from a source\nset is matched one-at-a-time until the input is exhausted, at which point the final result is emitted.\n\nThe first match is the entrypoint for the macro with user syntax.\n\nSubsequent matches pull tokens from `unprocessed` and do something with them. That might be moving\nthem into `processed` to be emitted later, or manipulating a target item/expression. The logic of\nthe macro is implemented in these middle matches.\n\nThe final match is the exitpoint, where `unprocessed` is empty.\n*/\n\n/// A macro that processes the input to `bitflags!` and shuffles attributes around\n/// based on whether or not they're \"expression-safe\".\n///\n/// This macro is a token-tree muncher that works on 2 levels:\n///\n/// For each attribute, we explicitly match on its identifier, like `cfg` to determine\n/// whether or not it should be considered expression-safe.\n///\n/// If you find yourself with an attribute that should be considered expression-safe\n/// and isn't, it can be added here.\n#[macro_export]\n#[doc(hidden)]\nmacro_rules! __bitflags_expr_safe_attrs {\n    (\n        $(#[$inner:ident $($args:tt)*])*\n        { $e:expr }\n    ) => {\n        $crate::__bitflags_expr_safe_attrs! {\n            expr: { $e },\n            attrs: {\n                // All attributes start here\n                unprocessed: [$(#[$inner $($args)*])*],\n                // Attributes that are safe on expressions go here\n                processed: [],\n            },\n        }\n    };\n    // `cfg`: propagate\n    (\n        expr: { $e:expr },\n        attrs: {\n            unprocessed: [\n                #[cfg $($args:tt)*]\n                $($attrs_rest:tt)*\n            ],\n            processed: [$($expr:tt)*],\n        },\n    ) => {\n        $crate::__bitflags_expr_safe_attrs! {\n            expr: { $e },\n            attrs: {\n                unprocessed: [\n                    $($attrs_rest)*\n                ],\n                processed: [\n                    $($expr)*\n                    #[cfg $($args)*]\n                ],\n            },\n        }\n    };\n    // Other: discard\n    (\n        expr: { $e:expr },\n        attrs: {\n            unprocessed: [\n                #[$other:ident $($args:tt)*]\n                $($attrs_rest:tt)*\n            ],\n            processed: [$($expr:tt)*],\n        },\n    ) => {\n        $crate::__bitflags_expr_safe_attrs! {\n            expr: { $e },\n                attrs: {\n                unprocessed: [\n                    $($attrs_rest)*\n                ],\n                processed: [\n                    $($expr)*\n                ],\n            },\n        }\n    };\n    // Finished\n    (\n        expr: { $e:expr },\n        attrs: {\n            unprocessed: [],\n            processed: [$(#[$expr:ident $($exprargs:tt)*])*],\n        },\n    ) => {\n        $(#[$expr $($exprargs)*])*\n        { $e }\n    }\n}\n\n/// A macro that processes the input to `bitflags!` and shuffles attributes around\n/// based on whether or not they're \"item-safe\".\n///\n/// This macro follows the same pattern as expr-safe above, but assumes all attributes\n/// are safe on items. It only filters out any `bitflags`-defined attributes.\n#[macro_export]\n#[doc(hidden)]\nmacro_rules! __bitflags_item_safe_attrs {\n    (\n        $(#[$inner:ident $($args:tt)*])*\n        { $i:item }\n    ) => {\n        $crate::__bitflags_item_safe_attrs! {\n            item: { $i },\n            attrs: {\n                // All attributes start here\n                unprocessed: [$(#[$inner $($args)*])*],\n                // Attributes that are safe on items go here\n                processed: [],\n            },\n        }\n    };\n    // `bitflags`: discard\n    (\n        item: { $i:item },\n        attrs: {\n            unprocessed: [\n                #[bitflags $($args:tt)*]\n                $($attrs_rest:tt)*\n            ],\n            processed: [$($item:tt)*],\n        },\n    ) => {\n        $crate::__bitflags_item_safe_attrs! {\n            item: { $i },\n            attrs: {\n                unprocessed: [\n                    $($attrs_rest)*\n                ],\n                processed: [\n                    $($item)*\n                ],\n            },\n        }\n    };\n    // Other: propagate\n    (\n        item: { $i:item },\n        attrs: {\n            unprocessed: [\n                // $other matched here\n                #[$other:ident $($args:tt)*]\n                $($attrs_rest:tt)*\n            ],\n            processed: [$($item:tt)*],\n        },\n    ) => {\n        $crate::__bitflags_item_safe_attrs! {\n            item: { $i },\n                attrs: {\n                unprocessed: [\n                    $($attrs_rest)*\n                ],\n                processed: [\n                    $($item)*\n                    #[$other $($args)*]\n                ],\n            },\n        }\n    };\n    // Finished\n    (\n        item: { $i:item },\n        attrs: {\n            unprocessed: [],\n            processed: [$(#[$item:ident $($itemargs:tt)*])*],\n        },\n    ) => {\n        $(#[$item $($itemargs)*])*\n        $i\n    }\n}\n\n/// Determine the name to assign to a flag.\n#[macro_export]\n#[doc(hidden)]\nmacro_rules! __bitflags_flag_name {\n    // Unnamed\n    (\n        $(#[$inner:ident $($args:tt)*])*\n        { $vis:vis const _ = _ }\n    ) => {\n\n    };\n    (\n        $(#[$inner:ident $($args:tt)*])*\n        { $vis:vis const $binding:ident = $name:expr }\n    ) => {\n        $crate::__bitflags_flag_name! {\n            item: { $vis const $binding = $crate::__private::core::stringify!($name) },\n            attrs: {\n                // All attributes start here\n                unprocessed: [$(#[$inner $($args)*])*],\n                // Attributes that are safe on the flag name go here\n                processed: [],\n            },\n        }\n    };\n    // `bitflags(flag_name)`: set the name\n    (\n        item: { $vis:vis const $binding:ident = $name:expr },\n        attrs: {\n            unprocessed: [\n                #[bitflags(flag_name = $flag_name:expr)]\n                $($attrs_rest:tt)*\n            ],\n            processed: [$($item:tt)*],\n        },\n    ) => {\n        $crate::__bitflags_flag_name! {\n            item: { $vis const $binding = $flag_name },\n            attrs: {\n                unprocessed: [\n                    $($attrs_rest)*\n                ],\n                processed: [\n                    $($item)*\n                ],\n            },\n        }\n    };\n    // `cfg`: propagate\n    (\n        item: { $vis:vis const $binding:ident = $name:expr },\n        attrs: {\n            unprocessed: [\n                #[cfg $($args:tt)*]\n                $($attrs_rest:tt)*\n            ],\n            processed: [$($item:tt)*],\n        },\n    ) => {\n        $crate::__bitflags_flag_name! {\n            item: { $vis const $binding = $name },\n            attrs: {\n                unprocessed: [\n                    $($attrs_rest)*\n                ],\n                processed: [\n                    $($item)*\n                    #[cfg $($args)*]\n                ],\n            },\n        }\n    };\n    // Other: discard\n    (\n        item: { $vis:vis const $binding:ident = $name:expr },\n        attrs: {\n            unprocessed: [\n                #[$other:ident $($args:tt)*]\n                $($attrs_rest:tt)*\n            ],\n            processed: [$($item:tt)*],\n        },\n    ) => {\n        $crate::__bitflags_flag_name! {\n            item: { $vis const $binding = $name },\n            attrs: {\n                unprocessed: [\n                    $($attrs_rest)*\n                ],\n                processed: [$($item)*],\n            },\n        }\n    };\n    // Finished\n    (\n        item: { $vis:vis const $binding:ident = $name:expr },\n        attrs: {\n            unprocessed: [],\n            processed: [$(#[$item:ident $($itemargs:tt)*])*],\n        },\n    ) => {\n        $(#[$item $($itemargs)*])*\n        $vis const $binding: &'static str = $name;\n    }\n}\n\n#[macro_use]\nmod public;\n#[macro_use]\nmod internal;\n#[macro_use]\nmod external;\n\n#[cfg(feature = \"example_generated\")]\npub mod example_generated;\n\n#[cfg(test)]\nmod tests;\n"
    },
    {
      "package": "bitvec@1.1.1",
      "sourcePath": "LICENSE.txt",
      "sha256": "411781fd38700f2357a14126d0ab048164ab881f1dcb335c1bb932e232c9a2f5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "MIT License\n\nCopyright (c) 2018 myrrlyn (Alexander Payne)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
    },
    {
      "package": "brotli@3.5.0",
      "sourcePath": "src/enc/entropy_encode.rs",
      "sha256": "46fe7c70f68ed2146933ddc63d9c5bbe40ff53c62b5d1c19e4ffdc32b9421197",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* Copyright 2010 Google Inc. All Rights Reserved.\n\n   Distributed under MIT license.\n   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT\n*/\n\n/* Entropy encoding (Huffman) utilities. */\n#![allow(dead_code)]\nuse super::util::brotli_max_uint32_t;\n\n#[derive(Clone, Copy, Default)]\npub struct HuffmanTree {\n    pub total_count_: u32,\n    pub index_left_: i16,\n    pub index_right_or_value_: i16,\n}\n\npub fn NewHuffmanTree(count: u32, left: i16, right: i16) -> HuffmanTree {\n    HuffmanTree {\n        total_count_: count,\n        index_left_: left,\n        index_right_or_value_: right,\n    }\n}\npub fn InitHuffmanTree(xself: &mut HuffmanTree, count: u32, left: i16, right: i16) {\n    *xself = NewHuffmanTree(count, left, right);\n}\n\npub fn BrotliSetDepth(p0: i32, pool: &mut [HuffmanTree], depth: &mut [u8], max_depth: i32) -> bool {\n    let mut stack: [i32; 16] = [0; 16];\n    let mut level: i32 = 0i32;\n    let mut p: i32 = p0;\n    0i32;\n    stack[0] = -1i32;\n    loop {\n        if (pool[(p as usize)]).index_left_ as i32 >= 0i32 {\n            level += 1;\n            if level > max_depth {\n                return false;\n            }\n            stack[level as usize] = (pool[(p as usize)]).index_right_or_value_ as i32;\n            p = (pool[(p as usize)]).index_left_ as i32;\n            {\n                {\n                    continue;\n                }\n            }\n        } else {\n            let pp = pool[(p as usize)];\n            depth[((pp).index_right_or_value_ as usize)] = level as u8;\n        }\n        while level >= 0i32 && (stack[level as usize] == -1i32) {\n            level -= 1;\n        }\n        if level < 0i32 {\n            return true;\n        }\n        p = stack[level as usize];\n        stack[level as usize] = -1i32;\n    }\n}\n\npub trait HuffmanComparator {\n    fn Cmp(&self, a: &HuffmanTree, b: &HuffmanTree) -> bool;\n}\npub struct SortHuffmanTree {}\nimpl HuffmanComparator for SortHuffmanTree {\n    fn Cmp(&self, v0: &HuffmanTree, v1: &HuffmanTree) -> bool {\n        if v0.total_count_ != v1.total_count_ {\n            v0.total_count_ < v1.total_count_\n        } else {\n            v0.index_right_or_value_ > v1.index_right_or_value_\n        }\n    }\n}\npub fn SortHuffmanTreeItems<Comparator: HuffmanComparator>(\n    items: &mut [HuffmanTree],\n    n: usize,\n    comparator: Comparator,\n) {\n    static gaps: [usize; 6] = [132, 57, 23, 10, 4, 1];\n    if n < 13usize {\n        let mut i: usize;\n        i = 1;\n        while i < n {\n            {\n                let mut tmp: HuffmanTree = items[i];\n                let mut k: usize = i;\n                let mut j: usize = i.wrapping_sub(1);\n                while comparator.Cmp(&mut tmp, &mut items[j]) {\n                    items[k] = items[j];\n                    k = j;\n                    if {\n                        let _old = j;\n                        j = j.wrapping_sub(1);\n                        _old\n                    } == 0\n                    {\n                        {\n                            break;\n                        }\n                    }\n                }\n                items[k] = tmp;\n            }\n            i = i.wrapping_add(1);\n        }\n    } else {\n        let mut g: i32 = if n < 57usize { 2i32 } else { 0i32 };\n        while g < 6i32 {\n            {\n                let gap: usize = gaps[g as usize];\n                let mut i: usize;\n                i = gap;\n                while i < n {\n                    {\n                        let mut j: usize = i;\n                        let mut tmp: HuffmanTree = items[i];\n                        while j >= gap\n                            && (comparator.Cmp(&mut tmp, &mut items[j.wrapping_sub(gap)]))\n                        {\n                            {\n                                items[j] = items[j.wrapping_sub(gap)];\n                            }\n                            j = j.wrapping_sub(gap);\n                        }\n                        items[j] = tmp;\n                    }\n                    i = i.wrapping_add(1);\n                }\n            }\n            g += 1;\n        }\n    }\n}\n\n/* This function will create a Huffman tree.\n\nThe catch here is that the tree cannot be arbitrarily deep.\nBrotli specifies a maximum depth of 15 bits for \"code trees\"\nand 7 bits for \"code length code trees.\"\n\ncount_limit is the value that is to be faked as the minimum value\nand this minimum value is raised until the tree matches the\nmaximum length requirement.\n\nThis algorithm is not of excellent performance for very long data blocks,\nespecially when population counts are longer than 2**tree_limit, but\nwe are not planning to use this with extremely long blocks.\n\nSee https://en.wikipedia.org/wiki/Huffman_coding */\npub fn BrotliCreateHuffmanTree(\n    data: &[u32],\n    length: usize,\n    tree_limit: i32,\n    tree: &mut [HuffmanTree],\n    depth: &mut [u8],\n) {\n    let mut count_limit: u32;\n    let mut sentinel: HuffmanTree = HuffmanTree {\n        total_count_: 0,\n        index_left_: 0,\n        index_right_or_value_: 0,\n    };\n    InitHuffmanTree(&mut sentinel, !(0u32), -1i16, -1i16);\n    count_limit = 1u32;\n    'break1: loop {\n        {\n            let mut n: usize = 0usize;\n            let mut i: usize;\n            let mut j: usize;\n            let mut k: usize;\n            i = length;\n            while i != 0usize {\n                i = i.wrapping_sub(1);\n                if data[i] != 0 {\n                    let count: u32 = brotli_max_uint32_t(data[i], count_limit);\n                    InitHuffmanTree(&mut tree[n], count, -1i16, i as i16);\n                    n = n.wrapping_add(1);\n                }\n            }\n            if n == 1 {\n                depth[((tree[0]).index_right_or_value_ as usize)] = 1u8;\n                {\n                    {\n                        break 'break1;\n                    }\n                }\n            }\n            SortHuffmanTreeItems(tree, n, SortHuffmanTree {});\n            tree[n] = sentinel;\n            tree[n.wrapping_add(1)] = sentinel;\n            i = 0usize;\n            j = n.wrapping_add(1);\n            k = n.wrapping_sub(1);\n            while k != 0usize {\n                {\n                    let left: usize;\n                    let right: usize;\n                    if (tree[i]).total_count_ <= (tree[j]).total_count_ {\n                        left = i;\n                        i = i.wrapping_add(1);\n                    } else {\n                        left = j;\n                        j = j.wrapping_add(1);\n                    }\n                    if (tree[i]).total_count_ <= (tree[j]).total_count_ {\n                        right = i;\n                        i = i.wrapping_add(1);\n                    } else {\n                        right = j;\n                        j = j.wrapping_add(1);\n                    }\n                    {\n                        let j_end: usize = (2usize).wrapping_mul(n).wrapping_sub(k);\n                        (tree[j_end]).total_count_ = (tree[left])\n                            .total_count_\n                            .wrapping_add((tree[right]).total_count_);\n                        (tree[j_end]).index_left_ = left as i16;\n                        (tree[j_end]).index_right_or_value_ = right as i16;\n                        tree[j_end.wrapping_add(1)] = sentinel;\n                    }\n                }\n                k = k.wrapping_sub(1);\n            }\n            if BrotliSetDepth(\n                (2usize).wrapping_mul(n).wrapping_sub(1) as i32,\n                tree,\n                depth,\n                tree_limit,\n            ) {\n                {\n                    break 'break1;\n                }\n            }\n        }\n        count_limit = count_limit.wrapping_mul(2);\n    }\n}\npub fn BrotliOptimizeHuffmanCountsForRle(\n    mut length: usize,\n    counts: &mut [u32],\n    good_for_rle: &mut [u8],\n) {\n    let mut nonzero_count: usize = 0usize;\n    let mut stride: usize;\n    let mut limit: usize;\n    let mut sum: usize;\n    let streak_limit: usize = 1240usize;\n    let mut i: usize;\n    i = 0usize;\n    while i < length {\n        {\n            if counts[i] != 0 {\n                nonzero_count = nonzero_count.wrapping_add(1);\n            }\n        }\n        i = i.wrapping_add(1);\n    }\n    if nonzero_count < 16usize {\n        return;\n    }\n    while length != 0usize && (counts[length.wrapping_sub(1)] == 0u32) {\n        length = length.wrapping_sub(1);\n    }\n    if length == 0usize {\n        return;\n    }\n    {\n        let mut nonzeros: usize = 0usize;\n        let mut smallest_nonzero: u32 = (1i32 << 30) as u32;\n        i = 0usize;\n        while i < length {\n            {\n                if counts[i] != 0u32 {\n                    nonzeros = nonzeros.wrapping_add(1);\n                    if smallest_nonzero > counts[i] {\n                        smallest_nonzero = counts[i];\n                    }\n                }\n            }\n            i = i.wrapping_add(1);\n        }\n        if nonzeros < 5usize {\n            return;\n        }\n        if smallest_nonzero < 4u32 {\n            let zeros: usize = length.wrapping_sub(nonzeros);\n            if zeros < 6usize {\n                i = 1;\n                while i < length.wrapping_sub(1) {\n                    {\n                        if counts[i.wrapping_sub(1)] != 0u32\n                            && (counts[i] == 0u32)\n                            && (counts[i.wrapping_add(1)] != 0u32)\n                        {\n                            counts[i] = 1u32;\n                        }\n                    }\n                    i = i.wrapping_add(1);\n                }\n            }\n        }\n        if nonzeros < 28usize {\n            return;\n        }\n    }\n    for rle_item in good_for_rle.iter_mut() {\n        *rle_item = 0;\n    }\n    {\n        let mut symbol: u32 = counts[0];\n        let mut step: usize = 0usize;\n        i = 0usize;\n        while i <= length {\n            {\n                if i == length || counts[i] != symbol {\n                    if symbol == 0u32 && (step >= 5usize) || symbol != 0u32 && (step >= 7usize) {\n                        let mut k: usize;\n                        k = 0usize;\n                        while k < step {\n                            {\n                                good_for_rle[i.wrapping_sub(k).wrapping_sub(1)] = 1u8;\n                            }\n                            k = k.wrapping_add(1);\n                        }\n                    }\n                    step = 1;\n                    if i != length {\n                        symbol = counts[i];\n                    }\n                } else {\n                    step = step.wrapping_add(1);\n                }\n            }\n            i = i.wrapping_add(1);\n        }\n    }\n    stride = 0usize;\n    limit = (256u32)\n        .wrapping_mul((counts[0]).wrapping_add(counts[1]).wrapping_add(counts[2]))\n        .wrapping_div(3)\n        .wrapping_add(420) as usize;\n    sum = 0usize;\n    i = 0usize;\n    while i <= length {\n        {\n            if i == length\n                || good_for_rle[i] != 0\n                || i != 0usize && (good_for_rle[i.wrapping_sub(1)] != 0)\n                || ((256u32).wrapping_mul(counts[i]) as usize)\n                    .wrapping_sub(limit)\n                    .wrapping_add(streak_limit)\n                    >= (2usize).wrapping_mul(streak_limit)\n            {\n                if stride >= 4usize || stride >= 3usize && (sum == 0usize) {\n                    let mut k: usize;\n                    let mut count: usize = sum\n                        .wrapping_add(stride.wrapping_div(2))\n                        .wrapping_div(stride);\n                    if count == 0usize {\n                        count = 1;\n                    }\n                    if sum == 0usize {\n                        count = 0usize;\n                    }\n                    k = 0usize;\n                    while k < stride {\n                        {\n                            counts[i.wrapping_sub(k).wrapping_sub(1)] = count as u32;\n                        }\n                        k = k.wrapping_add(1);\n                    }\n                }\n                stride = 0usize;\n                sum = 0usize;\n                if i < length.wrapping_sub(2) {\n                    limit = (256u32)\n                        .wrapping_mul(\n                            (counts[i])\n                                .wrapping_add(counts[i.wrapping_add(1)])\n                                .wrapping_add(counts[i.wrapping_add(2)]),\n                        )\n                        .wrapping_div(3)\n                        .wrapping_add(420) as usize;\n                } else if i < length {\n                    limit = (256u32).wrapping_mul(counts[i]) as usize;\n                } else {\n                    limit = 0usize;\n                }\n            }\n            stride = stride.wrapping_add(1);\n            if i != length {\n                sum = sum.wrapping_add(counts[i] as usize);\n                if stride >= 4usize {\n                    limit = (256usize)\n                        .wrapping_mul(sum)\n                        .wrapping_add(stride.wrapping_div(2))\n                        .wrapping_div(stride);\n                }\n                if stride == 4usize {\n                    limit = limit.wrapping_add(120);\n                }\n            }\n        }\n        i = i.wrapping_add(1);\n    }\n}\n\npub fn DecideOverRleUse(\n    depth: &[u8],\n    length: usize,\n    use_rle_for_non_zero: &mut i32,\n    use_rle_for_zero: &mut i32,\n) {\n    let mut total_reps_zero: usize = 0usize;\n    let mut total_reps_non_zero: usize = 0usize;\n    let mut count_reps_zero: usize = 1;\n    let mut count_reps_non_zero: usize = 1;\n    let mut i: usize;\n    i = 0usize;\n    while i < length {\n        let value: u8 = depth[i];\n        let mut reps: usize = 1;\n        let mut k: usize;\n        k = i.wrapping_add(1);\n        while k < length && (depth[k] as i32 == value as i32) {\n            {\n                reps = reps.wrapping_add(1);\n            }\n            k = k.wrapping_add(1);\n        }\n        if reps >= 3usize && (value as i32 == 0i32) {\n            total_reps_zero = total_reps_zero.wrapping_add(reps);\n            count_reps_zero = count_reps_zero.wrapping_add(1);\n        }\n        if reps >= 4usize && (value as i32 != 0i32) {\n            total_reps_non_zero = total_reps_non_zero.wrapping_add(reps);\n            count_reps_non_zero = count_reps_non_zero.wrapping_add(1);\n        }\n        i = i.wrapping_add(reps);\n    }\n    *use_rle_for_non_zero = if total_reps_non_zero > count_reps_non_zero.wrapping_mul(2) {\n        1i32\n    } else {\n        0i32\n    };\n    *use_rle_for_zero = if total_reps_zero > count_reps_zero.wrapping_mul(2) {\n        1i32\n    } else {\n        0i32\n    };\n}\n\nfn Reverse(v: &mut [u8], mut start: usize, mut end: usize) {\n    end = end.wrapping_sub(1);\n    while start < end {\n        v.swap(start, end);\n        start = start.wrapping_add(1);\n        end = end.wrapping_sub(1);\n    }\n}\n\nfn BrotliWriteHuffmanTreeRepetitions(\n    previous_value: u8,\n    value: u8,\n    mut repetitions: usize,\n    tree_size: &mut usize,\n    tree: &mut [u8],\n    extra_bits_data: &mut [u8],\n) {\n    0i32;\n    if previous_value as i32 != value as i32 {\n        tree[*tree_size] = value;\n        extra_bits_data[*tree_size] = 0u8;\n        *tree_size = tree_size.wrapping_add(1);\n        repetitions = repetitions.wrapping_sub(1);\n    }\n    if repetitions == 7usize {\n        tree[*tree_size] = value;\n        extra_bits_data[*tree_size] = 0u8;\n        *tree_size = tree_size.wrapping_add(1);\n        repetitions = repetitions.wrapping_sub(1);\n    }\n    if repetitions < 3usize {\n        let mut i: usize;\n        i = 0usize;\n        while i < repetitions {\n            {\n                tree[*tree_size] = value;\n                extra_bits_data[*tree_size] = 0u8;\n                *tree_size = tree_size.wrapping_add(1);\n            }\n            i = i.wrapping_add(1);\n        }\n    } else {\n        let start: usize = *tree_size;\n        repetitions = repetitions.wrapping_sub(3);\n        loop {\n            tree[*tree_size] = 16u8;\n            extra_bits_data[*tree_size] = (repetitions & 0x3usize) as u8;\n            *tree_size = tree_size.wrapping_add(1);\n            repetitions >>= 2i32;\n            if repetitions == 0usize {\n                {\n                    break;\n                }\n            }\n            repetitions = repetitions.wrapping_sub(1);\n        }\n        Reverse(tree, start, *tree_size);\n        Reverse(extra_bits_data, start, *tree_size);\n    }\n}\n\nfn BrotliWriteHuffmanTreeRepetitionsZeros(\n    mut repetitions: usize,\n    tree_size: &mut usize,\n    tree: &mut [u8],\n    extra_bits_data: &mut [u8],\n) {\n    if repetitions == 11 {\n        tree[*tree_size] = 0u8;\n        extra_bits_data[*tree_size] = 0u8;\n        *tree_size = tree_size.wrapping_add(1);\n        repetitions = repetitions.wrapping_sub(1);\n    }\n    if repetitions < 3usize {\n        let mut i: usize;\n        i = 0usize;\n        while i < repetitions {\n            {\n                tree[*tree_size] = 0u8;\n                extra_bits_data[*tree_size] = 0u8;\n                *tree_size = tree_size.wrapping_add(1);\n            }\n            i = i.wrapping_add(1);\n        }\n    } else {\n        let start: usize = *tree_size;\n        repetitions = repetitions.wrapping_sub(3);\n        loop {\n            tree[*tree_size] = 17u8;\n            extra_bits_data[*tree_size] = (repetitions & 0x7usize) as u8;\n            *tree_size = tree_size.wrapping_add(1);\n            repetitions >>= 3i32;\n            if repetitions == 0usize {\n                {\n                    break;\n                }\n            }\n            repetitions = repetitions.wrapping_sub(1);\n        }\n        Reverse(tree, start, *tree_size);\n        Reverse(extra_bits_data, start, *tree_size);\n    }\n}\n\npub fn BrotliWriteHuffmanTree(\n    depth: &[u8],\n    length: usize,\n    tree_size: &mut usize,\n    tree: &mut [u8],\n    extra_bits_data: &mut [u8],\n) {\n    let mut previous_value: u8 = 8u8;\n    let mut i: usize;\n    let mut use_rle_for_non_zero: i32 = 0i32;\n    let mut use_rle_for_zero: i32 = 0i32;\n    let mut new_length: usize = length;\n    i = 0usize;\n    'break27: while i < length {\n        {\n            if depth[length.wrapping_sub(i).wrapping_sub(1)] as i32 == 0i32 {\n                new_length = new_length.wrapping_sub(1);\n            } else {\n                break 'break27;\n            }\n        }\n        i = i.wrapping_add(1);\n    }\n    if length > 50usize {\n        DecideOverRleUse(\n            depth,\n            new_length,\n            &mut use_rle_for_non_zero,\n            &mut use_rle_for_zero,\n        );\n    }\n    i = 0usize;\n    while i < new_length {\n        let value: u8 = depth[i];\n        let mut reps: usize = 1;\n        if value as i32 != 0i32 && (use_rle_for_non_zero != 0)\n            || value as i32 == 0i32 && (use_rle_for_zero != 0)\n        {\n            let mut k: usize;\n            k = i.wrapping_add(1);\n            while k < new_length && (depth[k] as i32 == value as i32) {\n                {\n                    reps = reps.wrapping_add(1);\n                }\n                k = k.wrapping_add(1);\n            }\n        }\n        if value as i32 == 0i32 {\n            BrotliWriteHuffmanTreeRepetitionsZeros(reps, tree_size, tree, extra_bits_data);\n        } else {\n            BrotliWriteHuffmanTreeRepetitions(\n                previous_value,\n                value,\n                reps,\n                tree_size,\n                tree,\n                extra_bits_data,\n            );\n            previous_value = value;\n        }\n        i = i.wrapping_add(reps);\n    }\n}\n\nfn BrotliReverseBits(num_bits: usize, mut bits: u16) -> u16 {\n    static kLut: [usize; 16] = [\n        0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf,\n    ];\n    let mut retval: usize = kLut[(bits as i32 & 0xfi32) as usize];\n    let mut i: usize;\n    i = 4usize;\n    while i < num_bits {\n        {\n            retval <<= 4i32;\n            bits = (bits as i32 >> 4) as u16;\n            retval |= kLut[(bits as i32 & 0xfi32) as usize];\n        }\n        i = i.wrapping_add(4);\n    }\n    retval >>= (0usize.wrapping_sub(num_bits) & 0x3usize);\n    retval as u16\n}\nconst MAX_HUFFMAN_BITS: usize = 16;\npub fn BrotliConvertBitDepthsToSymbols(depth: &[u8], len: usize, bits: &mut [u16]) {\n    /* In Brotli, all bit depths are [1..15]\n    0 bit depth means that the symbol does not exist. */\n\n    let mut bl_count: [u16; MAX_HUFFMAN_BITS] = [0; MAX_HUFFMAN_BITS];\n    let mut next_code: [u16; MAX_HUFFMAN_BITS] = [0; MAX_HUFFMAN_BITS];\n    let mut i: usize;\n    let mut code: i32 = 0i32;\n    i = 0usize;\n    while i < len {\n        {\n            let _rhs = 1;\n            let _lhs = &mut bl_count[depth[i] as usize];\n            *_lhs = (*_lhs as i32 + _rhs) as u16;\n        }\n        i = i.wrapping_add(1);\n    }\n    bl_count[0] = 0u16;\n    next_code[0] = 0u16;\n    i = 1;\n    while i < MAX_HUFFMAN_BITS {\n        {\n            code = (code + bl_count[i.wrapping_sub(1)] as i32) << 1;\n            next_code[i] = code as u16;\n        }\n        i = i.wrapping_add(1);\n    }\n    i = 0usize;\n    while i < len {\n        {\n            if depth[i] != 0 {\n                bits[i] = BrotliReverseBits(depth[i] as usize, {\n                    let _rhs = 1;\n                    let _lhs = &mut next_code[depth[i] as usize];\n                    let _old = *_lhs;\n                    *_lhs = (*_lhs as i32 + _rhs) as u16;\n                    _old\n                });\n            }\n        }\n        i = i.wrapping_add(1);\n    }\n}\n"
    },
    {
      "package": "brotli-decompressor@2.5.1",
      "sourcePath": "src/context.rs",
      "sha256": "8fe7865962916fa7ce820b9fb407e6a2dd9b9c373191ad4a41c507b6be373e40",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "#![allow(non_snake_case)]\n#![allow(non_upper_case_globals)]\n#![allow(non_camel_case_types)]\n\n// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Distributed under MIT license.\n// See file LICENSE for detail or copy at https://opensource.org/licenses/MIT\n//\n\n// Lookup table to map the previous two bytes to a context id.\n//\n// There are four different context modeling modes defined here:\n// CONTEXT_LSB6: context id is the least significant 6 bits of the last byte,\n// CONTEXT_MSB6: context id is the most significant 6 bits of the last byte,\n// CONTEXT_UTF8: second-order context model tuned for UTF8-encoded text,\n// CONTEXT_SIGNED: second-order context model tuned for signed integers.\n//\n// The context id for the UTF8 context model is calculated as follows. If p1\n// and p2 are the previous two bytes, we calculate the context as\n//\n// context = kContextLookup[p1] | kContextLookup[p2 + 256].\n//\n// If the previous two bytes are ASCII characters (i.e. < 128), this will be\n// equivalent to\n//\n// context = 4 * context1(p1) + context2(p2),\n//\n// where context1 is based on the previous byte in the following way:\n//\n// 0  : non-ASCII control\n// 1  : \\t, \\n, \\r\n// 2  : space\n// 3  : other punctuation\n// 4  : \" '\n// 5  : %\n// 6  : ( < [ {\n// 7  : ) > ] }\n// 8  : , ; :\n// 9  : .\n// 10 : =\n// 11 : number\n// 12 : upper-case vowel\n// 13 : upper-case consonant\n// 14 : lower-case vowel\n// 15 : lower-case consonant\n//\n// and context2 is based on the second last byte:\n//\n// 0 : control, space\n// 1 : punctuation\n// 2 : upper-case letter, number\n// 3 : lower-case letter\n//\n// If the last byte is ASCII, and the second last byte is not (in a valid UTF8\n// stream it will be a continuation byte, value between 128 and 191), the\n// context is the same as if the second last byte was an ASCII control or space.\n//\n// If the last byte is a UTF8 lead byte (value >= 192), then the next byte will\n// be a continuation byte and the context id is 2 or 3 depending on the LSB of\n// the last byte and to a lesser extent on the second last byte if it is ASCII.\n//\n// If the last byte is a UTF8 continuation byte, the second last byte can be:\n// - continuation byte: the next byte is probably ASCII or lead byte (assuming\n// 4-byte UTF8 characters are rare) and the context id is 0 or 1.\n// - lead byte (192 - 207): next byte is ASCII or lead byte, context is 0 or 1\n// - lead byte (208 - 255): next byte is continuation byte, context is 2 or 3\n//\n// The possible value combinations of the previous two bytes, the range of\n// context ids and the type of the next byte is summarized in the table below:\n//\n// |--------\\-----------------------------------------------------------------|\n// |         \\                         Last byte                              |\n// | Second   \\---------------------------------------------------------------|\n// | last byte \\    ASCII            |   cont. byte        |   lead byte      |\n// |            \\   (0-127)          |   (128-191)         |   (192-)         |\n// |=============|===================|=====================|==================|\n// |  ASCII      | next: ASCII/lead  |  not valid          |  next: cont.     |\n// |  (0-127)    | context: 4 - 63   |                     |  context: 2 - 3  |\n// |-------------|-------------------|---------------------|------------------|\n// |  cont. byte | next: ASCII/lead  |  next: ASCII/lead   |  next: cont.     |\n// |  (128-191)  | context: 4 - 63   |  context: 0 - 1     |  context: 2 - 3  |\n// |-------------|-------------------|---------------------|------------------|\n// |  lead byte  | not valid         |  next: ASCII/lead   |  not valid       |\n// |  (192-207)  |                   |  context: 0 - 1     |                  |\n// |-------------|-------------------|---------------------|------------------|\n// |  lead byte  | not valid         |  next: cont.        |  not valid       |\n// |  (208-)     |                   |  context: 2 - 3     |                  |\n// |-------------|-------------------|---------------------|------------------|\n//\n// The context id for the signed context mode is calculated as:\n//\n// context = (kContextLookup[512 + p1] << 3) | kContextLookup[512 + p2].\n//\n// For any context modeling modes, the context ids can be calculated by |-ing\n// together two lookups from one table using context model dependent offsets:\n//\n// context = kContextLookup[offset1 + p1] | kContextLookup[offset2 + p2].\n//\n// where offset1 and offset2 are dependent on the context mode.\n//\n\n#[allow(dead_code)]\npub enum ContextType {\n  CONTEXT_LSB6,\n  CONTEXT_MSB6,\n  CONTEXT_UTF8,\n  CONTEXT_SIGNED,\n}\n\n/* Common context lookup table for all context modes. */\npub static kContextLookup:[[u8;512];4] = [\n[\n/* CONTEXT_LSB6, last byte. */\n   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\n   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\n   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\n   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\n\n  /* CONTEXT_LSB6, second last byte, */\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n],[\n  /* CONTEXT_MSB6, last byte. */\n   0,  0,  0,  0,  1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,\n   4,  4,  4,  4,  5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,\n   8,  8,  8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11, 11, 11, 11,\n  12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,\n  16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,\n  20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,\n  24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27,\n  28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31,\n  32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35,\n  36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39,\n  40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43,\n  44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47,\n  48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51,\n  52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55,\n  56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59,\n  60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63,\n\n  /* CONTEXT_MSB6, second last byte, */\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n],[\n  /* CONTEXT_UTF8, last byte. */\n  /* ASCII range. */\n   0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  4,  0,  0,  4,  0,  0,\n   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n   8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12,\n  44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12,\n  12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48,\n  52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12,\n  12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56,\n  60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12,  0,\n  /* UTF8 continuation byte range. */\n  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,\n  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,\n  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,\n  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,\n  /* UTF8 lead byte range. */\n  2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,\n  2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,\n  2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,\n  2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,\n\n  /* CONTEXT_UTF8 second last byte. */\n  /* ASCII range. */\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,\n  1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,\n  1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0,\n  /* UTF8 continuation byte range. */\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  /* UTF8 lead byte range. */\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n],[\n  /* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */\n   0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,\n  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n  24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n  32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n  32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n  32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n  32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,\n  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56,\n\n  /* CONTEXT_SIGNED, second last byte. */\n  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,\n]\n];\n\n"
    },
    {
      "package": "bumpalo@3.20.3",
      "sourcePath": "src/alloc.rs",
      "sha256": "3a9645d9e8db1f2a8549ee928cafa5263a828f25c88ce4d2b07996ecc14bfa81",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n#![allow(unstable_name_collisions)]\n#![allow(dead_code)]\n#![allow(deprecated)]\n\n//! Memory allocation APIs\n\nuse core::cmp;\nuse core::fmt;\nuse core::mem;\nuse core::ptr::{self, NonNull};\nuse core::usize;\n\npub use core::alloc::{Layout, LayoutErr};\n\nfn new_layout_err() -> LayoutErr {\n    Layout::from_size_align(1, 3).unwrap_err()\n}\n\npub fn handle_alloc_error(layout: Layout) -> ! {\n    panic!(\"encountered allocation error: {:?}\", layout)\n}\n\npub trait UnstableLayoutMethods {\n    fn padding_needed_for(&self, align: usize) -> usize;\n    fn repeat(&self, n: usize) -> Result<(Layout, usize), LayoutErr>;\n    fn array<T>(n: usize) -> Result<Layout, LayoutErr>;\n}\n\nimpl UnstableLayoutMethods for Layout {\n    fn padding_needed_for(&self, align: usize) -> usize {\n        let len = self.size();\n\n        // Rounded up value is:\n        //   len_rounded_up = (len + align - 1) & !(align - 1);\n        // and then we return the padding difference: `len_rounded_up - len`.\n        //\n        // We use modular arithmetic throughout:\n        //\n        // 1. align is guaranteed to be > 0, so align - 1 is always\n        //    valid.\n        //\n        // 2. `len + align - 1` can overflow by at most `align - 1`,\n        //    so the &-mask with `!(align - 1)` will ensure that in the\n        //    case of overflow, `len_rounded_up` will itself be 0.\n        //    Thus the returned padding, when added to `len`, yields 0,\n        //    which trivially satisfies the alignment `align`.\n        //\n        // (Of course, attempts to allocate blocks of memory whose\n        // size and padding overflow in the above manner should cause\n        // the allocator to yield an error anyway.)\n\n        let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);\n        len_rounded_up.wrapping_sub(len)\n    }\n\n    fn repeat(&self, n: usize) -> Result<(Layout, usize), LayoutErr> {\n        let padded_size = self\n            .size()\n            .checked_add(self.padding_needed_for(self.align()))\n            .ok_or_else(new_layout_err)?;\n        let alloc_size = padded_size.checked_mul(n).ok_or_else(new_layout_err)?;\n\n        unsafe {\n            // self.align is already known to be valid and alloc_size has been\n            // padded already.\n            Ok((\n                Layout::from_size_align_unchecked(alloc_size, self.align()),\n                padded_size,\n            ))\n        }\n    }\n\n    fn array<T>(n: usize) -> Result<Layout, LayoutErr> {\n        Layout::new::<T>().repeat(n).map(|(k, offs)| {\n            debug_assert!(offs == mem::size_of::<T>());\n            k\n        })\n    }\n}\n\n/// Represents the combination of a starting address and\n/// a total capacity of the returned block.\n// #[unstable(feature = \"allocator_api\", issue = \"32838\")]\n#[derive(Debug)]\npub struct Excess(pub NonNull<u8>, pub usize);\n\nfn size_align<T>() -> (usize, usize) {\n    (mem::size_of::<T>(), mem::align_of::<T>())\n}\n\n/// The `AllocErr` error indicates an allocation failure\n/// that may be due to resource exhaustion or to\n/// something wrong when combining the given input arguments with this\n/// allocator.\n// #[unstable(feature = \"allocator_api\", issue = \"32838\")]\n#[derive(Clone, PartialEq, Eq, Debug)]\npub struct AllocErr;\n\n// (we need this for downstream impl of trait Error)\n// #[unstable(feature = \"allocator_api\", issue = \"32838\")]\nimpl fmt::Display for AllocErr {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.write_str(\"memory allocation failed\")\n    }\n}\n\n/// The `CannotReallocInPlace` error is used when `grow_in_place` or\n/// `shrink_in_place` were unable to reuse the given memory block for\n/// a requested layout.\n// #[unstable(feature = \"allocator_api\", issue = \"32838\")]\n#[derive(Clone, PartialEq, Eq, Debug)]\npub struct CannotReallocInPlace;\n\n// #[unstable(feature = \"allocator_api\", issue = \"32838\")]\nimpl CannotReallocInPlace {\n    pub fn description(&self) -> &str {\n        \"cannot reallocate allocator's memory in place\"\n    }\n}\n\n// (we need this for downstream impl of trait Error)\n// #[unstable(feature = \"allocator_api\", issue = \"32838\")]\nimpl fmt::Display for CannotReallocInPlace {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"{}\", self.description())\n    }\n}\n\n/// An implementation of `Alloc` can allocate, reallocate, and\n/// deallocate arbitrary blocks of data described via `Layout`.\n///\n/// Some of the methods require that a memory block be *currently\n/// allocated* via an allocator. This means that:\n///\n/// * the starting address for that memory block was previously\n///   returned by a previous call to an allocation method (`alloc`,\n///   `alloc_zeroed`, `alloc_excess`, `alloc_one`, `alloc_array`) or\n///   reallocation method (`realloc`, `realloc_excess`, or\n///   `realloc_array`), and\n///\n/// * the memory block has not been subsequently deallocated, where\n///   blocks are deallocated either by being passed to a deallocation\n///   method (`dealloc`, `dealloc_one`, `dealloc_array`) or by being\n///   passed to a reallocation method (see above) that returns `Ok`.\n///\n/// A note regarding zero-sized types and zero-sized layouts: many\n/// methods in the `Alloc` trait state that allocation requests\n/// must be non-zero size, or else undefined behavior can result.\n///\n/// * However, some higher-level allocation methods (`alloc_one`,\n///   `alloc_array`) are well-defined on zero-sized types and can\n///   optionally support them: it is left up to the implementor\n///   whether to return `Err`, or to return `Ok` with some pointer.\n///\n/// * If an `Alloc` implementation chooses to return `Ok` in this\n///   case (i.e. the pointer denotes a zero-sized inaccessible block)\n///   then that returned pointer must be considered \"currently\n///   allocated\". On such an allocator, *all* methods that take\n///   currently-allocated pointers as inputs must accept these\n///   zero-sized pointers, *without* causing undefined behavior.\n///\n/// * In other words, if a zero-sized pointer can flow out of an\n///   allocator, then that allocator must likewise accept that pointer\n///   flowing back into its deallocation and reallocation methods.\n///\n/// Some of the methods require that a layout *fit* a memory block.\n/// What it means for a layout to \"fit\" a memory block means (or\n/// equivalently, for a memory block to \"fit\" a layout) is that the\n/// following two conditions must hold:\n///\n/// 1. The block's starting address must be aligned to `layout.align()`.\n///\n/// 2. The block's size must fall in the range `[use_min, use_max]`, where:\n///\n///    * `use_min` is `self.usable_size(layout).0`, and\n///\n///    * `use_max` is the capacity that was (or would have been)\n///      returned when (if) the block was allocated via a call to\n///      `alloc_excess` or `realloc_excess`.\n///\n/// Note that:\n///\n///  * the size of the layout most recently used to allocate the block\n///    is guaranteed to be in the range `[use_min, use_max]`, and\n///\n///  * a lower-bound on `use_max` can be safely approximated by a call to\n///    `usable_size`.\n///\n///  * if a layout `k` fits a memory block (denoted by `ptr`)\n///    currently allocated via an allocator `a`, then it is legal to\n///    use that layout to deallocate it, i.e. `a.dealloc(ptr, k);`.\n///\n/// # Unsafety\n///\n/// The `Alloc` trait is an `unsafe` trait for a number of reasons, and\n/// implementors must ensure that they adhere to these contracts:\n///\n/// * Pointers returned from allocation functions must point to valid memory and\n///   retain their validity until at least the instance of `Alloc` is dropped\n///   itself.\n///\n/// * `Layout` queries and calculations in general must be correct. Callers of\n///   this trait are allowed to rely on the contracts defined on each method,\n///   and implementors must ensure such contracts remain true.\n///\n/// Note that this list may get tweaked over time as clarifications are made in\n/// the future.\n// #[unstable(feature = \"allocator_api\", issue = \"32838\")]\npub unsafe trait Alloc {\n    // (Note: some existing allocators have unspecified but well-defined\n    // behavior in response to a zero size allocation request ;\n    // e.g. in C, `malloc` of 0 will either return a null pointer or a\n    // unique pointer, but will not have arbitrary undefined\n    // behavior.\n    // However in jemalloc for example,\n    // `mallocx(0)` is documented as undefined behavior.)\n\n    /// Returns a pointer meeting the size and alignment guarantees of\n    /// `layout`.\n    ///\n    /// If this method returns an `Ok(addr)`, then the `addr` returned\n    /// will be non-null address pointing to a block of storage\n    /// suitable for holding an instance of `layout`.\n    ///\n    /// The returned block of storage may or may not have its contents\n    /// initialized. (Extension subtraits might restrict this\n    /// behavior, e.g. to ensure initialization to particular sets of\n    /// bit patterns.)\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because undefined behavior can result\n    /// if the caller does not ensure that `layout` has non-zero size.\n    ///\n    /// (Extension subtraits might provide more specific bounds on\n    /// behavior, e.g. guarantee a sentinel address or a null pointer\n    /// in response to a zero-size allocation request.)\n    ///\n    /// # Errors\n    ///\n    /// Returning `Err` indicates that either memory is exhausted or\n    /// `layout` does not meet allocator's size or alignment\n    /// constraints.\n    ///\n    /// Implementations are encouraged to return `Err` on memory\n    /// exhaustion rather than panicking or aborting, but this is not\n    /// a strict requirement. (Specifically: it is *legal* to\n    /// implement this trait atop an underlying native allocation\n    /// library that aborts on memory exhaustion.)\n    ///\n    /// Clients wishing to abort computation in response to an\n    /// allocation error are encouraged to call the [`handle_alloc_error`] function,\n    /// rather than directly invoking `panic!` or similar.\n    ///\n    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html\n    unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr>;\n\n    /// Deallocate the memory referenced by `ptr`.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because undefined behavior can result\n    /// if the caller does not ensure all of the following:\n    ///\n    /// * `ptr` must denote a block of memory currently allocated via\n    ///   this allocator,\n    ///\n    /// * `layout` must *fit* that block of memory,\n    ///\n    /// * In addition to fitting the block of memory `layout`, the\n    ///   alignment of the `layout` must match the alignment used\n    ///   to allocate that block of memory.\n    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout);\n\n    // == ALLOCATOR-SPECIFIC QUANTITIES AND LIMITS ==\n    // usable_size\n\n    /// Returns bounds on the guaranteed usable size of a successful\n    /// allocation created with the specified `layout`.\n    ///\n    /// In particular, if one has a memory block allocated via a given\n    /// allocator `a` and layout `k` where `a.usable_size(k)` returns\n    /// `(l, u)`, then one can pass that block to `a.dealloc()` with a\n    /// layout in the size range [l, u].\n    ///\n    /// (All implementors of `usable_size` must ensure that\n    /// `l <= k.size() <= u`)\n    ///\n    /// Both the lower- and upper-bounds (`l` and `u` respectively)\n    /// are provided, because an allocator based on size classes could\n    /// misbehave if one attempts to deallocate a block without\n    /// providing a correct value for its size (i.e., one within the\n    /// range `[l, u]`).\n    ///\n    /// Clients who wish to make use of excess capacity are encouraged\n    /// to use the `alloc_excess` and `realloc_excess` instead, as\n    /// this method is constrained to report conservative values that\n    /// serve as valid bounds for *all possible* allocation method\n    /// calls.\n    ///\n    /// However, for clients that do not wish to track the capacity\n    /// returned by `alloc_excess` locally, this method is likely to\n    /// produce useful results.\n    #[inline]\n    fn usable_size(&self, layout: &Layout) -> (usize, usize) {\n        (layout.size(), layout.size())\n    }\n\n    // == METHODS FOR MEMORY REUSE ==\n    // realloc. alloc_excess, realloc_excess\n\n    /// Returns a pointer suitable for holding data described by\n    /// a new layout with `layout`’s alignment and a size given\n    /// by `new_size`. To\n    /// accomplish this, this may extend or shrink the allocation\n    /// referenced by `ptr` to fit the new layout.\n    ///\n    /// If this returns `Ok`, then ownership of the memory block\n    /// referenced by `ptr` has been transferred to this\n    /// allocator. The memory may or may not have been freed, and\n    /// should be considered unusable (unless of course it was\n    /// transferred back to the caller again via the return value of\n    /// this method).\n    ///\n    /// If this method returns `Err`, then ownership of the memory\n    /// block has not been transferred to this allocator, and the\n    /// contents of the memory block are unaltered.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because undefined behavior can result\n    /// if the caller does not ensure all of the following:\n    ///\n    /// * `ptr` must be currently allocated via this allocator,\n    ///\n    /// * `layout` must *fit* the `ptr` (see above). (The `new_size`\n    ///   argument need not fit it.)\n    ///\n    /// * `new_size` must be greater than zero.\n    ///\n    /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,\n    ///   must not overflow (i.e. the rounded value must be less than `usize::MAX`).\n    ///\n    /// (Extension subtraits might provide more specific bounds on\n    /// behavior, e.g. guarantee a sentinel address or a null pointer\n    /// in response to a zero-size allocation request.)\n    ///\n    /// # Errors\n    ///\n    /// Returns `Err` only if the new layout\n    /// does not meet the allocator's size\n    /// and alignment constraints of the allocator, or if reallocation\n    /// otherwise fails.\n    ///\n    /// Implementations are encouraged to return `Err` on memory\n    /// exhaustion rather than panicking or aborting, but this is not\n    /// a strict requirement. (Specifically: it is *legal* to\n    /// implement this trait atop an underlying native allocation\n    /// library that aborts on memory exhaustion.)\n    ///\n    /// Clients wishing to abort computation in response to a\n    /// reallocation error are encouraged to call the [`handle_alloc_error`] function,\n    /// rather than directly invoking `panic!` or similar.\n    ///\n    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html\n    unsafe fn realloc(\n        &mut self,\n        ptr: NonNull<u8>,\n        layout: Layout,\n        new_size: usize,\n    ) -> Result<NonNull<u8>, AllocErr> {\n        let old_size = layout.size();\n\n        if new_size >= old_size {\n            if let Ok(()) = self.grow_in_place(ptr, layout, new_size) {\n                return Ok(ptr);\n            }\n        } else if new_size < old_size {\n            if let Ok(()) = self.shrink_in_place(ptr, layout, new_size) {\n                return Ok(ptr);\n            }\n        }\n\n        // otherwise, fall back on alloc + copy + dealloc.\n        let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());\n        let result = self.alloc(new_layout);\n        if let Ok(new_ptr) = result {\n            ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr(), cmp::min(old_size, new_size));\n            self.dealloc(ptr, layout);\n        }\n        result\n    }\n\n    /// Behaves like `alloc`, but also ensures that the contents\n    /// are set to zero before being returned.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe for the same reasons that `alloc` is.\n    ///\n    /// # Errors\n    ///\n    /// Returning `Err` indicates that either memory is exhausted or\n    /// `layout` does not meet allocator's size or alignment\n    /// constraints, just as in `alloc`.\n    ///\n    /// Clients wishing to abort computation in response to an\n    /// allocation error are encouraged to call the [`handle_alloc_error`] function,\n    /// rather than directly invoking `panic!` or similar.\n    ///\n    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html\n    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {\n        let size = layout.size();\n        let p = self.alloc(layout);\n        if let Ok(p) = p {\n            ptr::write_bytes(p.as_ptr(), 0, size);\n        }\n        p\n    }\n\n    /// Behaves like `alloc`, but also returns the whole size of\n    /// the returned block. For some `layout` inputs, like arrays, this\n    /// may include extra storage usable for additional data.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe for the same reasons that `alloc` is.\n    ///\n    /// # Errors\n    ///\n    /// Returning `Err` indicates that either memory is exhausted or\n    /// `layout` does not meet allocator's size or alignment\n    /// constraints, just as in `alloc`.\n    ///\n    /// Clients wishing to abort computation in response to an\n    /// allocation error are encouraged to call the [`handle_alloc_error`] function,\n    /// rather than directly invoking `panic!` or similar.\n    ///\n    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html\n    unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {\n        let usable_size = self.usable_size(&layout);\n        self.alloc(layout).map(|p| Excess(p, usable_size.1))\n    }\n\n    /// Behaves like `realloc`, but also returns the whole size of\n    /// the returned block. For some `layout` inputs, like arrays, this\n    /// may include extra storage usable for additional data.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe for the same reasons that `realloc` is.\n    ///\n    /// # Errors\n    ///\n    /// Returning `Err` indicates that either memory is exhausted or\n    /// `layout` does not meet allocator's size or alignment\n    /// constraints, just as in `realloc`.\n    ///\n    /// Clients wishing to abort computation in response to a\n    /// reallocation error are encouraged to call the [`handle_alloc_error`] function,\n    /// rather than directly invoking `panic!` or similar.\n    ///\n    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html\n    unsafe fn realloc_excess(\n        &mut self,\n        ptr: NonNull<u8>,\n        layout: Layout,\n        new_size: usize,\n    ) -> Result<Excess, AllocErr> {\n        let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());\n        let usable_size = self.usable_size(&new_layout);\n        self.realloc(ptr, layout, new_size)\n            .map(|p| Excess(p, usable_size.1))\n    }\n\n    /// Attempts to extend the allocation referenced by `ptr` to fit `new_size`.\n    ///\n    /// If this returns `Ok`, then the allocator has asserted that the\n    /// memory block referenced by `ptr` now fits `new_size`, and thus can\n    /// be used to carry data of a layout of that size and same alignment as\n    /// `layout`. (The allocator is allowed to\n    /// expend effort to accomplish this, such as extending the memory block to\n    /// include successor blocks, or virtual memory tricks.)\n    ///\n    /// Regardless of what this method returns, ownership of the\n    /// memory block referenced by `ptr` has not been transferred, and\n    /// the contents of the memory block are unaltered.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because undefined behavior can result\n    /// if the caller does not ensure all of the following:\n    ///\n    /// * `ptr` must be currently allocated via this allocator,\n    ///\n    /// * `layout` must *fit* the `ptr` (see above); note the\n    ///   `new_size` argument need not fit it,\n    ///\n    /// * `new_size` must not be less than `layout.size()`,\n    ///\n    /// # Errors\n    ///\n    /// Returns `Err(CannotReallocInPlace)` when the allocator is\n    /// unable to assert that the memory block referenced by `ptr`\n    /// could fit `layout`.\n    ///\n    /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`\n    /// function; clients are expected either to be able to recover from\n    /// `grow_in_place` failures without aborting, or to fall back on\n    /// another reallocation method before resorting to an abort.\n    unsafe fn grow_in_place(\n        &mut self,\n        ptr: NonNull<u8>,\n        layout: Layout,\n        new_size: usize,\n    ) -> Result<(), CannotReallocInPlace> {\n        let _ = ptr; // this default implementation doesn't care about the actual address.\n        debug_assert!(new_size >= layout.size());\n        let (_l, u) = self.usable_size(&layout);\n        // _l <= layout.size()                       [guaranteed by usable_size()]\n        //       layout.size() <= new_layout.size()  [required by this method]\n        if new_size <= u {\n            Ok(())\n        } else {\n            Err(CannotReallocInPlace)\n        }\n    }\n\n    /// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`.\n    ///\n    /// If this returns `Ok`, then the allocator has asserted that the\n    /// memory block referenced by `ptr` now fits `new_size`, and\n    /// thus can only be used to carry data of that smaller\n    /// layout. (The allocator is allowed to take advantage of this,\n    /// carving off portions of the block for reuse elsewhere.) The\n    /// truncated contents of the block within the smaller layout are\n    /// unaltered, and ownership of block has not been transferred.\n    ///\n    /// If this returns `Err`, then the memory block is considered to\n    /// still represent the original (larger) `layout`. None of the\n    /// block has been carved off for reuse elsewhere, ownership of\n    /// the memory block has not been transferred, and the contents of\n    /// the memory block are unaltered.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because undefined behavior can result\n    /// if the caller does not ensure all of the following:\n    ///\n    /// * `ptr` must be currently allocated via this allocator,\n    ///\n    /// * `layout` must *fit* the `ptr` (see above); note the\n    ///   `new_size` argument need not fit it,\n    ///\n    /// * `new_size` must not be greater than `layout.size()`\n    ///   (and must be greater than zero),\n    ///\n    /// # Errors\n    ///\n    /// Returns `Err(CannotReallocInPlace)` when the allocator is\n    /// unable to assert that the memory block referenced by `ptr`\n    /// could fit `layout`.\n    ///\n    /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`\n    /// function; clients are expected either to be able to recover from\n    /// `shrink_in_place` failures without aborting, or to fall back\n    /// on another reallocation method before resorting to an abort.\n    unsafe fn shrink_in_place(\n        &mut self,\n        ptr: NonNull<u8>,\n        layout: Layout,\n        new_size: usize,\n    ) -> Result<(), CannotReallocInPlace> {\n        let _ = ptr; // this default implementation doesn't care about the actual address.\n        debug_assert!(new_size <= layout.size());\n        let (l, _u) = self.usable_size(&layout);\n        //                      layout.size() <= _u  [guaranteed by usable_size()]\n        // new_layout.size() <= layout.size()        [required by this method]\n        if l <= new_size {\n            Ok(())\n        } else {\n            Err(CannotReallocInPlace)\n        }\n    }\n\n    // == COMMON USAGE PATTERNS ==\n    // alloc_one, dealloc_one, alloc_array, realloc_array. dealloc_array\n\n    /// Allocates a block suitable for holding an instance of `T`.\n    ///\n    /// Captures a common usage pattern for allocators.\n    ///\n    /// The returned block is suitable for passing to the\n    /// `alloc`/`realloc` methods of this allocator.\n    ///\n    /// Note to implementors: If this returns `Ok(ptr)`, then `ptr`\n    /// must be considered \"currently allocated\" and must be\n    /// acceptable input to methods such as `realloc` or `dealloc`,\n    /// *even if* `T` is a zero-sized type. In other words, if your\n    /// `Alloc` implementation overrides this method in a manner\n    /// that can return a zero-sized `ptr`, then all reallocation and\n    /// deallocation methods need to be similarly overridden to accept\n    /// such values as input.\n    ///\n    /// # Errors\n    ///\n    /// Returning `Err` indicates that either memory is exhausted or\n    /// `T` does not meet allocator's size or alignment constraints.\n    ///\n    /// For zero-sized `T`, may return either of `Ok` or `Err`, but\n    /// will *not* yield undefined behavior.\n    ///\n    /// Clients wishing to abort computation in response to an\n    /// allocation error are encouraged to call the [`handle_alloc_error`] function,\n    /// rather than directly invoking `panic!` or similar.\n    ///\n    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html\n    fn alloc_one<T>(&mut self) -> Result<NonNull<T>, AllocErr>\n    where\n        Self: Sized,\n    {\n        let k = Layout::new::<T>();\n        if k.size() > 0 {\n            unsafe { self.alloc(k).map(|p| p.cast()) }\n        } else {\n            Err(AllocErr)\n        }\n    }\n\n    /// Deallocates a block suitable for holding an instance of `T`.\n    ///\n    /// The given block must have been produced by this allocator,\n    /// and must be suitable for storing a `T` (in terms of alignment\n    /// as well as minimum and maximum size); otherwise yields\n    /// undefined behavior.\n    ///\n    /// Captures a common usage pattern for allocators.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because undefined behavior can result\n    /// if the caller does not ensure both:\n    ///\n    /// * `ptr` must denote a block of memory currently allocated via this allocator\n    ///\n    /// * the layout of `T` must *fit* that block of memory.\n    unsafe fn dealloc_one<T>(&mut self, ptr: NonNull<T>)\n    where\n        Self: Sized,\n    {\n        let k = Layout::new::<T>();\n        if k.size() > 0 {\n            self.dealloc(ptr.cast(), k);\n        }\n    }\n\n    /// Allocates a block suitable for holding `n` instances of `T`.\n    ///\n    /// Captures a common usage pattern for allocators.\n    ///\n    /// The returned block is suitable for passing to the\n    /// `alloc`/`realloc` methods of this allocator.\n    ///\n    /// Note to implementors: If this returns `Ok(ptr)`, then `ptr`\n    /// must be considered \"currently allocated\" and must be\n    /// acceptable input to methods such as `realloc` or `dealloc`,\n    /// *even if* `T` is a zero-sized type. In other words, if your\n    /// `Alloc` implementation overrides this method in a manner\n    /// that can return a zero-sized `ptr`, then all reallocation and\n    /// deallocation methods need to be similarly overridden to accept\n    /// such values as input.\n    ///\n    /// # Errors\n    ///\n    /// Returning `Err` indicates that either memory is exhausted or\n    /// `[T; n]` does not meet allocator's size or alignment\n    /// constraints.\n    ///\n    /// For zero-sized `T` or `n == 0`, may return either of `Ok` or\n    /// `Err`, but will *not* yield undefined behavior.\n    ///\n    /// Always returns `Err` on arithmetic overflow.\n    ///\n    /// Clients wishing to abort computation in response to an\n    /// allocation error are encouraged to call the [`handle_alloc_error`] function,\n    /// rather than directly invoking `panic!` or similar.\n    ///\n    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html\n    fn alloc_array<T>(&mut self, n: usize) -> Result<NonNull<T>, AllocErr>\n    where\n        Self: Sized,\n    {\n        match Layout::array::<T>(n) {\n            Ok(layout) if layout.size() > 0 => unsafe { self.alloc(layout).map(|p| p.cast()) },\n            _ => Err(AllocErr),\n        }\n    }\n\n    /// Reallocates a block previously suitable for holding `n_old`\n    /// instances of `T`, returning a block suitable for holding\n    /// `n_new` instances of `T`.\n    ///\n    /// Captures a common usage pattern for allocators.\n    ///\n    /// The returned block is suitable for passing to the\n    /// `alloc`/`realloc` methods of this allocator.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because undefined behavior can result\n    /// if the caller does not ensure all of the following:\n    ///\n    /// * `ptr` must be currently allocated via this allocator,\n    ///\n    /// * the layout of `[T; n_old]` must *fit* that block of memory.\n    ///\n    /// # Errors\n    ///\n    /// Returning `Err` indicates that either memory is exhausted or\n    /// `[T; n_new]` does not meet allocator's size or alignment\n    /// constraints.\n    ///\n    /// For zero-sized `T` or `n_new == 0`, may return either of `Ok` or\n    /// `Err`, but will *not* yield undefined behavior.\n    ///\n    /// Always returns `Err` on arithmetic overflow.\n    ///\n    /// Clients wishing to abort computation in response to a\n    /// reallocation error are encouraged to call the [`handle_alloc_error`] function,\n    /// rather than directly invoking `panic!` or similar.\n    ///\n    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html\n    unsafe fn realloc_array<T>(\n        &mut self,\n        ptr: NonNull<T>,\n        n_old: usize,\n        n_new: usize,\n    ) -> Result<NonNull<T>, AllocErr>\n    where\n        Self: Sized,\n    {\n        match (Layout::array::<T>(n_old), Layout::array::<T>(n_new)) {\n            (Ok(ref k_old), Ok(ref k_new)) if k_old.size() > 0 && k_new.size() > 0 => {\n                debug_assert!(k_old.align() == k_new.align());\n                self.realloc(ptr.cast(), *k_old, k_new.size())\n                    .map(NonNull::cast)\n            }\n            _ => Err(AllocErr),\n        }\n    }\n\n    /// Deallocates a block suitable for holding `n` instances of `T`.\n    ///\n    /// Captures a common usage pattern for allocators.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because undefined behavior can result\n    /// if the caller does not ensure both:\n    ///\n    /// * `ptr` must denote a block of memory currently allocated via this allocator\n    ///\n    /// * the layout of `[T; n]` must *fit* that block of memory.\n    ///\n    /// # Errors\n    ///\n    /// Returning `Err` indicates that either `[T; n]` or the given\n    /// memory block does not meet allocator's size or alignment\n    /// constraints.\n    ///\n    /// Always returns `Err` on arithmetic overflow.\n    unsafe fn dealloc_array<T>(&mut self, ptr: NonNull<T>, n: usize) -> Result<(), AllocErr>\n    where\n        Self: Sized,\n    {\n        match Layout::array::<T>(n) {\n            Ok(k) if k.size() > 0 => {\n                self.dealloc(ptr.cast(), k);\n                Ok(())\n            }\n            _ => Err(AllocErr),\n        }\n    }\n}\n"
    },
    {
      "package": "bumpalo@3.20.3",
      "sourcePath": "src/collections/mod.rs",
      "sha256": "d58dc46eb4f9fcdde574f09bc5b8646f53e42d49c169561d98e0c23e5b36848a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Collection types that allocate inside a [`Bump`] arena.\n//!\n//! [`Bump`]: ../struct.Bump.html\n\n#![allow(deprecated)]\n\nmod raw_vec;\n\npub mod vec;\npub use self::vec::Vec;\n\nmod str;\npub mod string;\npub use self::string::String;\n\nmod collect_in;\npub use collect_in::{CollectIn, FromIteratorIn};\n\n// pub mod binary_heap;\n// mod btree;\n// pub mod linked_list;\n// pub mod vec_deque;\n\n// pub mod btree_map {\n//     //! A map based on a B-Tree.\n//     pub use super::btree::map::*;\n// }\n\n// pub mod btree_set {\n//     //! A set based on a B-Tree.\n//     pub use super::btree::set::*;\n// }\n\n// #[doc(no_inline)]\n// pub use self::binary_heap::BinaryHeap;\n\n// #[doc(no_inline)]\n// pub use self::btree_map::BTreeMap;\n\n// #[doc(no_inline)]\n// pub use self::btree_set::BTreeSet;\n\n// #[doc(no_inline)]\n// pub use self::linked_list::LinkedList;\n\n// #[doc(no_inline)]\n// pub use self::vec_deque::VecDeque;\n\nuse crate::alloc::{AllocErr, LayoutErr};\n\n/// Augments `AllocErr` with a `CapacityOverflow` variant.\n#[derive(Clone, PartialEq, Eq, Debug)]\n// #[unstable(feature = \"try_reserve\", reason = \"new API\", issue=\"48043\")]\npub enum CollectionAllocErr {\n    /// Error due to the computed capacity exceeding the collection's maximum\n    /// (usually `isize::MAX` bytes).\n    CapacityOverflow,\n    /// Error due to the allocator (see the documentation for the [`AllocErr`] type).\n    AllocErr,\n}\n\n// #[unstable(feature = \"try_reserve\", reason = \"new API\", issue=\"48043\")]\nimpl From<AllocErr> for CollectionAllocErr {\n    #[inline]\n    fn from(AllocErr: AllocErr) -> Self {\n        CollectionAllocErr::AllocErr\n    }\n}\n\n// #[unstable(feature = \"try_reserve\", reason = \"new API\", issue=\"48043\")]\nimpl From<LayoutErr> for CollectionAllocErr {\n    #[inline]\n    fn from(_: LayoutErr) -> Self {\n        CollectionAllocErr::CapacityOverflow\n    }\n}\n\n// /// An intermediate trait for specialization of `Extend`.\n// #[doc(hidden)]\n// trait SpecExtend<I: IntoIterator> {\n//     /// Extends `self` with the contents of the given iterator.\n//     fn spec_extend(&mut self, iter: I);\n// }\n"
    },
    {
      "package": "bumpalo@3.20.3",
      "sourcePath": "src/collections/raw_vec.rs",
      "sha256": "c045b13f3ac191f1c597f87a7385f59078a3d091f7888d8449d65b9e6f67e315",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n#![allow(unstable_name_collisions)]\n#![allow(dead_code)]\n\nuse crate::Bump;\n\nuse core::cmp;\nuse core::mem;\nuse core::ptr::{self, NonNull};\n\nuse crate::alloc::{handle_alloc_error, Alloc, Layout, UnstableLayoutMethods};\nuse crate::collections::CollectionAllocErr;\nuse crate::collections::CollectionAllocErr::*;\n// use boxed::Box;\n\n/// A low-level utility for more ergonomically allocating, reallocating, and deallocating\n/// a buffer of memory on the heap without having to worry about all the corner cases\n/// involved. This type is excellent for building your own data structures like Vec and VecDeque.\n/// In particular:\n///\n/// * Produces Unique::empty() on zero-sized types\n/// * Produces Unique::empty() on zero-length allocations\n/// * Catches all overflows in capacity computations (promotes them to \"capacity overflow\" panics)\n/// * Guards against 32-bit systems allocating more than isize::MAX bytes\n/// * Guards against overflowing your length\n/// * Aborts on OOM\n/// * Avoids freeing Unique::empty()\n/// * Contains a ptr::Unique and thus endows the user with all related benefits\n///\n/// This type does not in anyway inspect the memory that it manages. When dropped it *will*\n/// free its memory, but it *won't* try to Drop its contents. It is up to the user of RawVec\n/// to handle the actual things *stored* inside of a RawVec.\n///\n/// Note that a RawVec always forces its capacity to be usize::MAX for zero-sized types.\n/// This enables you to use capacity growing logic catch the overflows in your length\n/// that might occur with zero-sized types.\n///\n/// However this means that you need to be careful when round-tripping this type\n/// with a `Box<[T]>`: `cap()` won't yield the len. However `with_capacity`,\n/// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity\n/// field. This allows zero-sized types to not be special-cased by consumers of\n/// this type.\n#[allow(missing_debug_implementations)]\npub struct RawVec<'a, T> {\n    ptr: NonNull<T>,\n    cap: usize,\n    a: &'a Bump,\n}\n\nimpl<'a, T> RawVec<'a, T> {\n    /// Like `new` but parameterized over the choice of allocator for\n    /// the returned RawVec.\n    pub fn new_in(a: &'a Bump) -> Self {\n        // `cap: 0` means \"unallocated\". zero-sized types are ignored.\n        RawVec {\n            ptr: NonNull::dangling(),\n            cap: 0,\n            a,\n        }\n    }\n\n    /// Like `with_capacity` but parameterized over the choice of\n    /// allocator for the returned RawVec.\n    #[inline]\n    pub fn with_capacity_in(cap: usize, a: &'a Bump) -> Self {\n        RawVec::allocate_in(cap, false, a)\n    }\n\n    /// Like `with_capacity_zeroed` but parameterized over the choice\n    /// of allocator for the returned RawVec.\n    #[inline]\n    pub fn with_capacity_zeroed_in(cap: usize, a: &'a Bump) -> Self {\n        RawVec::allocate_in(cap, true, a)\n    }\n\n    fn allocate_in(cap: usize, zeroed: bool, mut a: &'a Bump) -> Self {\n        unsafe {\n            let elem_size = mem::size_of::<T>();\n\n            let alloc_size = cap\n                .checked_mul(elem_size)\n                .unwrap_or_else(|| capacity_overflow());\n            alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow());\n\n            // handles ZSTs and `cap = 0` alike\n            let ptr = if alloc_size == 0 {\n                NonNull::<T>::dangling()\n            } else {\n                let align = mem::align_of::<T>();\n                let layout = Layout::from_size_align(alloc_size, align).unwrap();\n                let result = if zeroed {\n                    a.alloc_zeroed(layout)\n                } else {\n                    Alloc::alloc(&mut a, layout)\n                };\n                match result {\n                    Ok(ptr) => ptr.cast(),\n                    Err(_) => handle_alloc_error(layout),\n                }\n            };\n\n            RawVec { ptr, cap, a }\n        }\n    }\n}\n\nimpl<'a, T> RawVec<'a, T> {\n    /// Reconstitutes a RawVec from a pointer, capacity, and allocator.\n    ///\n    /// # Undefined Behavior\n    ///\n    /// The ptr must be allocated (via the given allocator `a`), and with the given capacity. The\n    /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).\n    /// If the ptr and capacity come from a RawVec created via `a`, then this is guaranteed.\n    pub unsafe fn from_raw_parts_in(ptr: *mut T, cap: usize, a: &'a Bump) -> Self {\n        RawVec {\n            ptr: NonNull::new_unchecked(ptr),\n            cap,\n            a,\n        }\n    }\n}\n\nimpl<'a, T> RawVec<'a, T> {\n    /// Gets a raw pointer to the start of the allocation. Note that this is\n    /// Unique::empty() if `cap = 0` or T is zero-sized. In the former case, you must\n    /// be careful.\n    pub fn ptr(&self) -> *mut T {\n        self.ptr.as_ptr()\n    }\n\n    /// Gets the capacity of the allocation.\n    ///\n    /// This will always be `usize::MAX` if `T` is zero-sized.\n    #[inline(always)]\n    pub fn cap(&self) -> usize {\n        if mem::size_of::<T>() == 0 {\n            !0\n        } else {\n            self.cap\n        }\n    }\n\n    /// Returns a shared reference to the allocator backing this RawVec.\n    pub fn bump(&self) -> &'a Bump {\n        self.a\n    }\n\n    fn current_layout(&self) -> Option<Layout> {\n        if self.cap == 0 {\n            None\n        } else {\n            // We have an allocated chunk of memory, so we can bypass runtime\n            // checks to get our current layout.\n            unsafe {\n                let align = mem::align_of::<T>();\n                let size = mem::size_of::<T>() * self.cap;\n                Some(Layout::from_size_align_unchecked(size, align))\n            }\n        }\n    }\n\n    /// Doubles the size of the type's backing allocation. This is common enough\n    /// to want to do that it's easiest to just have a dedicated method. Slightly\n    /// more efficient logic can be provided for this than the general case.\n    ///\n    /// This function is ideal for when pushing elements one-at-a-time because\n    /// you don't need to incur the costs of the more general computations\n    /// reserve needs to do to guard against overflow. You do however need to\n    /// manually check if your `len == cap`.\n    ///\n    /// # Panics\n    ///\n    /// * Panics if T is zero-sized on the assumption that you managed to exhaust\n    ///   all `usize::MAX` slots in your imaginary buffer.\n    /// * Panics on 32-bit platforms if the requested capacity exceeds\n    ///   `isize::MAX` bytes.\n    ///\n    /// # Aborts\n    ///\n    /// Aborts on OOM\n    ///\n    /// # Examples\n    ///\n    /// ```ignore\n    /// # #![feature(alloc, raw_vec_internals)]\n    /// # extern crate alloc;\n    /// # use std::ptr;\n    /// # use alloc::raw_vec::RawVec;\n    /// struct MyVec<T> {\n    ///     buf: RawVec<T>,\n    ///     len: usize,\n    /// }\n    ///\n    /// impl<T> MyVec<T> {\n    ///     pub fn push(&mut self, elem: T) {\n    ///         if self.len == self.buf.cap() { self.buf.double(); }\n    ///         // double would have aborted or panicked if the len exceeded\n    ///         // `isize::MAX` so this is safe to do unchecked now.\n    ///         unsafe {\n    ///             ptr::write(self.buf.ptr().add(self.len), elem);\n    ///         }\n    ///         self.len += 1;\n    ///     }\n    /// }\n    /// # fn main() {\n    /// #   let mut vec = MyVec { buf: RawVec::new(), len: 0 };\n    /// #   vec.push(1);\n    /// # }\n    /// ```\n    #[inline(never)]\n    #[cold]\n    pub fn double(&mut self) {\n        unsafe {\n            let elem_size = mem::size_of::<T>();\n\n            // since we set the capacity to usize::MAX when elem_size is\n            // 0, getting to here necessarily means the RawVec is overfull.\n            assert!(elem_size != 0, \"capacity overflow\");\n\n            let (new_cap, uniq) = match self.current_layout() {\n                Some(cur) => {\n                    // Since we guarantee that we never allocate more than\n                    // isize::MAX bytes, `elem_size * self.cap <= isize::MAX` as\n                    // a precondition, so this can't overflow. Additionally the\n                    // alignment will never be too large as to \"not be\n                    // satisfiable\", so `Layout::from_size_align` will always\n                    // return `Some`.\n                    //\n                    // tl;dr; we bypass runtime checks due to dynamic assertions\n                    // in this module, allowing us to use\n                    // `from_size_align_unchecked`.\n                    let new_cap = 2 * self.cap;\n                    let new_size = new_cap * elem_size;\n                    alloc_guard(new_size).unwrap_or_else(|_| capacity_overflow());\n                    let ptr_res = self.a.realloc(self.ptr.cast(), cur, new_size);\n                    match ptr_res {\n                        Ok(ptr) => (new_cap, ptr.cast()),\n                        Err(_) => handle_alloc_error(Layout::from_size_align_unchecked(\n                            new_size,\n                            cur.align(),\n                        )),\n                    }\n                }\n                None => {\n                    // skip to 4 because tiny Vec's are dumb; but not if that\n                    // would cause overflow\n                    let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 };\n                    match self.a.alloc_array::<T>(new_cap) {\n                        Ok(ptr) => (new_cap, ptr),\n                        Err(_) => handle_alloc_error(Layout::array::<T>(new_cap).unwrap()),\n                    }\n                }\n            };\n            self.ptr = uniq;\n            self.cap = new_cap;\n        }\n    }\n\n    /// Attempts to double the size of the type's backing allocation in place. This is common\n    /// enough to want to do that it's easiest to just have a dedicated method. Slightly\n    /// more efficient logic can be provided for this than the general case.\n    ///\n    /// Returns true if the reallocation attempt has succeeded, or false otherwise.\n    ///\n    /// # Panics\n    ///\n    /// * Panics if T is zero-sized on the assumption that you managed to exhaust\n    ///   all `usize::MAX` slots in your imaginary buffer.\n    /// * Panics on 32-bit platforms if the requested capacity exceeds\n    ///   `isize::MAX` bytes.\n    #[inline(never)]\n    #[cold]\n    pub fn double_in_place(&mut self) -> bool {\n        unsafe {\n            let elem_size = mem::size_of::<T>();\n            let old_layout = match self.current_layout() {\n                Some(layout) => layout,\n                None => return false, // nothing to double\n            };\n\n            // since we set the capacity to usize::MAX when elem_size is\n            // 0, getting to here necessarily means the RawVec is overfull.\n            assert!(elem_size != 0, \"capacity overflow\");\n\n            // Since we guarantee that we never allocate more than isize::MAX\n            // bytes, `elem_size * self.cap <= isize::MAX` as a precondition, so\n            // this can't overflow.\n            //\n            // Similarly like with `double` above we can go straight to\n            // `Layout::from_size_align_unchecked` as we know this won't\n            // overflow and the alignment is sufficiently small.\n            let new_cap = 2 * self.cap;\n            let new_size = new_cap * elem_size;\n            alloc_guard(new_size).unwrap_or_else(|_| capacity_overflow());\n            match self.a.grow_in_place(self.ptr.cast(), old_layout, new_size) {\n                Ok(_) => {\n                    // We can't directly divide `size`.\n                    self.cap = new_cap;\n                    true\n                }\n                Err(_) => false,\n            }\n        }\n    }\n\n    /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting.\n    pub fn try_reserve_exact(\n        &mut self,\n        used_cap: usize,\n        needed_extra_cap: usize,\n    ) -> Result<(), CollectionAllocErr> {\n        self.fallible_reserve_internal(used_cap, needed_extra_cap, Exact)\n    }\n\n    /// Ensures that the buffer contains at least enough space to hold\n    /// `used_cap + needed_extra_cap` elements. If it doesn't already,\n    /// will reallocate the minimum possible amount of memory necessary.\n    /// Generally this will be exactly the amount of memory necessary,\n    /// but in principle the allocator is free to give back more than\n    /// we asked for.\n    ///\n    /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate\n    /// the requested space. This is not really unsafe, but the unsafe\n    /// code *you* write that relies on the behavior of this function may break.\n    ///\n    /// # Panics\n    ///\n    /// * Panics if the requested capacity exceeds `usize::MAX` bytes.\n    /// * Panics on 32-bit platforms if the requested capacity exceeds\n    ///   `isize::MAX` bytes.\n    ///\n    /// # Aborts\n    ///\n    /// Aborts on OOM\n    pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) {\n        self.infallible_reserve_internal(used_cap, needed_extra_cap, Exact)\n    }\n\n    /// Calculates the buffer's new size given that it'll hold `used_cap +\n    /// needed_extra_cap` elements. This logic is used in amortized reserve methods.\n    /// Returns `(new_capacity, new_alloc_size)`.\n    fn amortized_new_size(\n        &self,\n        used_cap: usize,\n        needed_extra_cap: usize,\n    ) -> Result<usize, CollectionAllocErr> {\n        // Nothing we can really do about these checks :(\n        let required_cap = used_cap\n            .checked_add(needed_extra_cap)\n            .ok_or(CapacityOverflow)?;\n        // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.\n        let double_cap = self.cap * 2;\n        // `double_cap` guarantees exponential growth.\n        Ok(cmp::max(double_cap, required_cap))\n    }\n\n    /// The same as `reserve`, but returns on errors instead of panicking or aborting.\n    pub fn try_reserve(\n        &mut self,\n        used_cap: usize,\n        needed_extra_cap: usize,\n    ) -> Result<(), CollectionAllocErr> {\n        self.fallible_reserve_internal(used_cap, needed_extra_cap, Amortized)\n    }\n\n    /// Ensures that the buffer contains at least enough space to hold\n    /// `used_cap + needed_extra_cap` elements. If it doesn't already have\n    /// enough capacity, will reallocate enough space plus comfortable slack\n    /// space to get amortized `O(1)` behavior. Will limit this behavior\n    /// if it would needlessly cause itself to panic.\n    ///\n    /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate\n    /// the requested space. This is not really unsafe, but the unsafe\n    /// code *you* write that relies on the behavior of this function may break.\n    ///\n    /// This is ideal for implementing a bulk-push operation like `extend`.\n    ///\n    /// # Panics\n    ///\n    /// * Panics if the requested capacity exceeds `usize::MAX` bytes.\n    /// * Panics on 32-bit platforms if the requested capacity exceeds\n    ///   `isize::MAX` bytes.\n    ///\n    /// # Aborts\n    ///\n    /// Aborts on OOM\n    ///\n    /// # Examples\n    ///\n    /// ```ignore\n    /// # #![feature(alloc, raw_vec_internals)]\n    /// # extern crate alloc;\n    /// # use std::ptr;\n    /// # use alloc::raw_vec::RawVec;\n    /// struct MyVec<T> {\n    ///     buf: RawVec<T>,\n    ///     len: usize,\n    /// }\n    ///\n    /// impl<T: Clone> MyVec<T> {\n    ///     pub fn push_all(&mut self, elems: &[T]) {\n    ///         self.buf.reserve(self.len, elems.len());\n    ///         // reserve would have aborted or panicked if the len exceeded\n    ///         // `isize::MAX` so this is safe to do unchecked now.\n    ///         for x in elems {\n    ///             unsafe {\n    ///                 ptr::write(self.buf.ptr().add(self.len), x.clone());\n    ///             }\n    ///             self.len += 1;\n    ///         }\n    ///     }\n    /// }\n    /// # fn main() {\n    /// #   let mut vector = MyVec { buf: RawVec::new(), len: 0 };\n    /// #   vector.push_all(&[1, 3, 5, 7, 9]);\n    /// # }\n    /// ```\n    #[inline(always)]\n    pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {\n        self.infallible_reserve_internal(used_cap, needed_extra_cap, Amortized)\n    }\n\n    /// Attempts to ensure that the buffer contains at least enough space to hold\n    /// `used_cap + needed_extra_cap` elements. If it doesn't already have\n    /// enough capacity, will reallocate in place enough space plus comfortable slack\n    /// space to get amortized `O(1)` behavior. Will limit this behaviour\n    /// if it would needlessly cause itself to panic.\n    ///\n    /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate\n    /// the requested space. This is not really unsafe, but the unsafe\n    /// code *you* write that relies on the behavior of this function may break.\n    ///\n    /// Returns true if the reallocation attempt has succeeded, or false otherwise.\n    ///\n    /// # Panics\n    ///\n    /// * Panics if the requested capacity exceeds `usize::MAX` bytes.\n    /// * Panics on 32-bit platforms if the requested capacity exceeds\n    ///   `isize::MAX` bytes.\n    pub fn reserve_in_place(&mut self, used_cap: usize, needed_extra_cap: usize) -> bool {\n        unsafe {\n            // NOTE: we don't early branch on ZSTs here because we want this\n            // to actually catch \"asking for more than usize::MAX\" in that case.\n            // If we make it past the first branch then we are guaranteed to\n            // panic.\n\n            // Don't actually need any more capacity. If the current `cap` is 0, we can't\n            // reallocate in place.\n            // Wrapping in case they give a bad `used_cap`\n            let old_layout = match self.current_layout() {\n                Some(layout) => layout,\n                None => return false,\n            };\n            if self.cap().wrapping_sub(used_cap) >= needed_extra_cap {\n                return false;\n            }\n\n            let new_cap = self\n                .amortized_new_size(used_cap, needed_extra_cap)\n                .unwrap_or_else(|_| capacity_overflow());\n\n            // Here, `cap < used_cap + needed_extra_cap <= new_cap`\n            // (regardless of whether `self.cap - used_cap` wrapped).\n            // Therefore we can safely call grow_in_place.\n\n            let new_layout = Layout::new::<T>().repeat(new_cap).unwrap().0;\n            // FIXME: may crash and burn on over-reserve\n            alloc_guard(new_layout.size()).unwrap_or_else(|_| capacity_overflow());\n            match self\n                .a\n                .grow_in_place(self.ptr.cast(), old_layout, new_layout.size())\n            {\n                Ok(_) => {\n                    self.cap = new_cap;\n                    true\n                }\n                Err(_) => false,\n            }\n        }\n    }\n\n    /// Shrinks the allocation down to the specified amount. If the given amount\n    /// is 0, actually completely deallocates.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the given amount is *larger* than the current capacity.\n    ///\n    /// # Aborts\n    ///\n    /// Aborts on OOM.\n    pub fn shrink_to_fit(&mut self, amount: usize) {\n        let elem_size = mem::size_of::<T>();\n\n        // Set the `cap` because they might be about to promote to a `Box<[T]>`\n        if elem_size == 0 {\n            self.cap = amount;\n            return;\n        }\n\n        // This check is my waterloo; it's the only thing Vec wouldn't have to do.\n        assert!(self.cap >= amount, \"Tried to shrink to a larger capacity\");\n\n        if amount == 0 {\n            // We want to create a new zero-length vector within the\n            // same allocator.  We use ptr::write to avoid an\n            // erroneous attempt to drop the contents, and we use\n            // ptr::read to sidestep condition against destructuring\n            // types that implement Drop.\n\n            unsafe {\n                let a = self.a;\n                self.dealloc_buffer();\n                ptr::write(self, RawVec::new_in(a));\n            }\n        } else if self.cap != amount {\n            unsafe {\n                // We know here that our `amount` is greater than zero. This\n                // implies, via the assert above, that capacity is also greater\n                // than zero, which means that we've got a current layout that\n                // \"fits\"\n                //\n                // We also know that `self.cap` is greater than `amount`, and\n                // consequently we don't need runtime checks for creating either\n                // layout\n                let old_size = elem_size * self.cap;\n                let new_size = elem_size * amount;\n                let align = mem::align_of::<T>();\n                let old_layout = Layout::from_size_align_unchecked(old_size, align);\n                match self.a.realloc(self.ptr.cast(), old_layout, new_size) {\n                    Ok(p) => self.ptr = p.cast(),\n                    Err(_) => {\n                        handle_alloc_error(Layout::from_size_align_unchecked(new_size, align))\n                    }\n                }\n            }\n            self.cap = amount;\n        }\n    }\n}\n\n#[cfg(feature = \"boxed\")]\nimpl<'a, T> RawVec<'a, T> {\n    /// Converts the entire buffer into `Box<[T]>`.\n    ///\n    /// Note that this will correctly reconstitute any `cap` changes\n    /// that may have been performed. (See description of type for details.)\n    ///\n    /// # Undefined Behavior\n    ///\n    /// All elements of `RawVec<T>` must be initialized. Notice that\n    /// the rules around uninitialized boxed values are not finalized yet,\n    /// but until they are, it is advisable to avoid them.\n    pub unsafe fn into_box(self) -> crate::boxed::Box<'a, [T]> {\n        use crate::boxed::Box;\n\n        // NOTE: not calling `cap()` here; actually using the real `cap` field!\n        let slice = core::slice::from_raw_parts_mut(self.ptr(), self.cap);\n        let output: Box<'a, [T]> = Box::from_raw(slice);\n        mem::forget(self);\n        output\n    }\n}\n\nenum Fallibility {\n    Fallible,\n    Infallible,\n}\n\nuse self::Fallibility::*;\n\nenum ReserveStrategy {\n    Exact,\n    Amortized,\n}\n\nuse self::ReserveStrategy::*;\n\nimpl<'a, T> RawVec<'a, T> {\n    #[inline(always)]\n    fn fallible_reserve_internal(\n        &mut self,\n        used_cap: usize,\n        needed_extra_cap: usize,\n        strategy: ReserveStrategy,\n    ) -> Result<(), CollectionAllocErr> {\n        // This portion of the method should always be inlined.\n        if self.cap().wrapping_sub(used_cap) >= needed_extra_cap {\n            return Ok(());\n        }\n        // This portion of the method should never be inlined, and will only be called when\n        // the check above has confirmed that it is necessary.\n        self.reserve_internal_or_error(used_cap, needed_extra_cap, Fallible, strategy)\n    }\n\n    #[inline(always)]\n    fn infallible_reserve_internal(\n        &mut self,\n        used_cap: usize,\n        needed_extra_cap: usize,\n        strategy: ReserveStrategy,\n    ) {\n        // This portion of the method should always be inlined.\n        if self.cap().wrapping_sub(used_cap) >= needed_extra_cap {\n            return;\n        }\n        // This portion of the method should never be inlined, and will only be called when\n        // the check above has confirmed that it is necessary.\n        self.reserve_internal_or_panic(used_cap, needed_extra_cap, strategy)\n    }\n\n    #[inline(never)]\n    fn reserve_internal_or_panic(\n        &mut self,\n        used_cap: usize,\n        needed_extra_cap: usize,\n        strategy: ReserveStrategy,\n    ) {\n        // Delegates the call to `reserve_internal_or_error` and panics in the event of an error.\n        // This allows the method to have a return type of `()`, simplifying the assembly at the\n        // call site.\n        match self.reserve_internal(used_cap, needed_extra_cap, Infallible, strategy) {\n            Err(CapacityOverflow) => capacity_overflow(),\n            Err(AllocErr) => unreachable!(),\n            Ok(()) => { /* yay */ }\n        }\n    }\n\n    #[inline(never)]\n    fn reserve_internal_or_error(\n        &mut self,\n        used_cap: usize,\n        needed_extra_cap: usize,\n        fallibility: Fallibility,\n        strategy: ReserveStrategy,\n    ) -> Result<(), CollectionAllocErr> {\n        // Delegates the call to `reserve_internal`, which can be inlined.\n        self.reserve_internal(used_cap, needed_extra_cap, fallibility, strategy)\n    }\n\n    /// Helper method to reserve additional space, reallocating the backing memory.\n    /// The caller is responsible for confirming that there is not already enough space available.\n    fn reserve_internal(\n        &mut self,\n        used_cap: usize,\n        needed_extra_cap: usize,\n        fallibility: Fallibility,\n        strategy: ReserveStrategy,\n    ) -> Result<(), CollectionAllocErr> {\n        unsafe {\n            use crate::AllocErr;\n\n            // NOTE: we don't early branch on ZSTs here because we want this\n            // to actually catch \"asking for more than usize::MAX\" in that case.\n            // If we make it past the first branch then we are guaranteed to\n            // panic.\n\n            // Nothing we can really do about these checks :(\n            let new_cap = match strategy {\n                Exact => used_cap\n                    .checked_add(needed_extra_cap)\n                    .ok_or(CapacityOverflow)?,\n                Amortized => self.amortized_new_size(used_cap, needed_extra_cap)?,\n            };\n            let new_layout = Layout::array::<T>(new_cap).map_err(|_| CapacityOverflow)?;\n\n            alloc_guard(new_layout.size())?;\n\n            let res = match self.current_layout() {\n                Some(layout) => {\n                    debug_assert!(new_layout.align() == layout.align());\n                    self.a.realloc(self.ptr.cast(), layout, new_layout.size())\n                }\n                None => Alloc::alloc(&mut self.a, new_layout),\n            };\n\n            if let (Err(AllocErr), Infallible) = (&res, fallibility) {\n                handle_alloc_error(new_layout);\n            }\n\n            self.ptr = res?.cast();\n            self.cap = new_cap;\n\n            Ok(())\n        }\n    }\n}\n\nimpl<'a, T> RawVec<'a, T> {\n    /// Frees the memory owned by the RawVec *without* trying to Drop its contents.\n    pub unsafe fn dealloc_buffer(&mut self) {\n        let elem_size = mem::size_of::<T>();\n        if elem_size != 0 {\n            if let Some(layout) = self.current_layout() {\n                self.a.dealloc(self.ptr.cast(), layout);\n            }\n        }\n    }\n}\n\nimpl<'a, T> Drop for RawVec<'a, T> {\n    /// Frees the memory owned by the RawVec *without* trying to Drop its contents.\n    fn drop(&mut self) {\n        unsafe {\n            self.dealloc_buffer();\n        }\n    }\n}\n\n// We need to guarantee the following:\n// * We don't ever allocate `> isize::MAX` byte-size objects\n// * We don't overflow `usize::MAX` and actually allocate too little\n//\n// On 64-bit we just need to check for overflow since trying to allocate\n// `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add\n// an extra guard for this in case we're running on a platform which can use\n// all 4GB in user-space. e.g. PAE or x32\n\n#[inline]\nfn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> {\n    if mem::size_of::<usize>() < 8 && alloc_size > ::core::isize::MAX as usize {\n        Err(CapacityOverflow)\n    } else {\n        Ok(())\n    }\n}\n\n// One central function responsible for reporting capacity overflows. This'll\n// ensure that the code generation related to these panics is minimal as there's\n// only one location which panics rather than a bunch throughout the module.\nfn capacity_overflow() -> ! {\n    panic!(\"capacity overflow\")\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn reserve_does_not_overallocate() {\n        let bump = Bump::new();\n        {\n            let mut v: RawVec<u32> = RawVec::new_in(&bump);\n            // First `reserve` allocates like `reserve_exact`\n            v.reserve(0, 9);\n            assert_eq!(9, v.cap());\n        }\n\n        {\n            let mut v: RawVec<u32> = RawVec::new_in(&bump);\n            v.reserve(0, 7);\n            assert_eq!(7, v.cap());\n            // 97 if more than double of 7, so `reserve` should work\n            // like `reserve_exact`.\n            v.reserve(7, 90);\n            assert_eq!(97, v.cap());\n        }\n\n        {\n            let mut v: RawVec<u32> = RawVec::new_in(&bump);\n            v.reserve(0, 12);\n            assert_eq!(12, v.cap());\n            v.reserve(12, 3);\n            // 3 is less than half of 12, so `reserve` must grow\n            // exponentially. At the time of writing this test grow\n            // factor is 2, so new capacity is 24, however, grow factor\n            // of 1.5 is OK too. Hence `>= 18` in assert.\n            assert!(v.cap() >= 12 + 12 / 2);\n        }\n    }\n}\n"
    },
    {
      "package": "bumpalo@3.20.3",
      "sourcePath": "src/collections/str/lossy.rs",
      "sha256": "c5d62b16e01071e2a574ae41ef6693ad12f1e6c786c5d38f7a13ebd6cb23c088",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::collections::str as core_str;\nuse core::char;\nuse core::fmt;\nuse core::fmt::Write;\nuse core::str;\n\n/// Lossy UTF-8 string.\npub struct Utf8Lossy<'a> {\n    bytes: &'a [u8],\n}\n\nimpl<'a> Utf8Lossy<'a> {\n    pub fn from_bytes(bytes: &'a [u8]) -> Utf8Lossy<'a> {\n        Utf8Lossy { bytes }\n    }\n\n    pub fn chunks(&self) -> Utf8LossyChunksIter<'a> {\n        Utf8LossyChunksIter {\n            source: &self.bytes,\n        }\n    }\n}\n\n/// Iterator over lossy UTF-8 string\n#[allow(missing_debug_implementations)]\npub struct Utf8LossyChunksIter<'a> {\n    source: &'a [u8],\n}\n\n#[derive(PartialEq, Eq, Debug)]\npub struct Utf8LossyChunk<'a> {\n    /// Sequence of valid chars.\n    /// Can be empty between broken UTF-8 chars.\n    pub valid: &'a str,\n    /// Single broken char, empty if none.\n    /// Empty iff iterator item is last.\n    pub broken: &'a [u8],\n}\n\nimpl<'a> Iterator for Utf8LossyChunksIter<'a> {\n    type Item = Utf8LossyChunk<'a>;\n\n    fn next(&mut self) -> Option<Utf8LossyChunk<'a>> {\n        if self.source.is_empty() {\n            return None;\n        }\n\n        const TAG_CONT_U8: u8 = 128;\n        fn unsafe_get(xs: &[u8], i: usize) -> u8 {\n            unsafe { *xs.get_unchecked(i) }\n        }\n        fn safe_get(xs: &[u8], i: usize) -> u8 {\n            if i >= xs.len() {\n                0\n            } else {\n                unsafe_get(xs, i)\n            }\n        }\n\n        let mut i = 0;\n        while i < self.source.len() {\n            let i_ = i;\n\n            let byte = unsafe_get(self.source, i);\n            i += 1;\n\n            if byte < 128 {\n            } else {\n                let w = core_str::utf8_char_width(byte);\n\n                macro_rules! error {\n                    () => {{\n                        unsafe {\n                            let r = Utf8LossyChunk {\n                                valid: str::from_utf8_unchecked(&self.source[0..i_]),\n                                broken: &self.source[i_..i],\n                            };\n                            self.source = &self.source[i..];\n                            return Some(r);\n                        }\n                    }};\n                }\n\n                match w {\n                    2 => {\n                        if safe_get(self.source, i) & 192 != TAG_CONT_U8 {\n                            error!();\n                        }\n                        i += 1;\n                    }\n                    3 => {\n                        match (byte, safe_get(self.source, i)) {\n                            (0xE0, 0xA0..=0xBF) => (),\n                            (0xE1..=0xEC, 0x80..=0xBF) => (),\n                            (0xED, 0x80..=0x9F) => (),\n                            (0xEE..=0xEF, 0x80..=0xBF) => (),\n                            _ => {\n                                error!();\n                            }\n                        }\n                        i += 1;\n                        if safe_get(self.source, i) & 192 != TAG_CONT_U8 {\n                            error!();\n                        }\n                        i += 1;\n                    }\n                    4 => {\n                        match (byte, safe_get(self.source, i)) {\n                            (0xF0, 0x90..=0xBF) => (),\n                            (0xF1..=0xF3, 0x80..=0xBF) => (),\n                            (0xF4, 0x80..=0x8F) => (),\n                            _ => {\n                                error!();\n                            }\n                        }\n                        i += 1;\n                        if safe_get(self.source, i) & 192 != TAG_CONT_U8 {\n                            error!();\n                        }\n                        i += 1;\n                        if safe_get(self.source, i) & 192 != TAG_CONT_U8 {\n                            error!();\n                        }\n                        i += 1;\n                    }\n                    _ => {\n                        error!();\n                    }\n                }\n            }\n        }\n\n        let r = Utf8LossyChunk {\n            valid: unsafe { str::from_utf8_unchecked(self.source) },\n            broken: &[],\n        };\n        self.source = &[];\n        Some(r)\n    }\n}\n\nimpl<'a> fmt::Display for Utf8Lossy<'a> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        // If we're the empty string then our iterator won't actually yield\n        // anything, so perform the formatting manually\n        if self.bytes.is_empty() {\n            return \"\".fmt(f);\n        }\n\n        for Utf8LossyChunk { valid, broken } in self.chunks() {\n            // If we successfully decoded the whole chunk as a valid string then\n            // we can return a direct formatting of the string which will also\n            // respect various formatting flags if possible.\n            if valid.len() == self.bytes.len() {\n                assert!(broken.is_empty());\n                return valid.fmt(f);\n            }\n\n            f.write_str(valid)?;\n            if !broken.is_empty() {\n                f.write_char(char::REPLACEMENT_CHARACTER)?;\n            }\n        }\n        Ok(())\n    }\n}\n\nimpl<'a> fmt::Debug for Utf8Lossy<'a> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.write_char('\"')?;\n\n        for Utf8LossyChunk { valid, broken } in self.chunks() {\n            // Valid part.\n            // Here we partially parse UTF-8 again which is suboptimal.\n            {\n                let mut from = 0;\n                for (i, c) in valid.char_indices() {\n                    let esc = c.escape_debug();\n                    // If char needs escaping, flush backlog so far and write, else skip\n                    if esc.len() != 1 {\n                        f.write_str(&valid[from..i])?;\n                        for c in esc {\n                            f.write_char(c)?;\n                        }\n                        from = i + c.len_utf8();\n                    }\n                }\n                f.write_str(&valid[from..])?;\n            }\n\n            // Broken parts of string as hex escape.\n            for &b in broken {\n                write!(f, \"\\\\x{:02x}\", b)?;\n            }\n        }\n\n        f.write_char('\"')\n    }\n}\n"
    },
    {
      "package": "bumpalo@3.20.3",
      "sourcePath": "src/collections/str/mod.rs",
      "sha256": "d82a8bd417fbf52a589d89a16ea2a0ac4f6ac920c3976ab1f5b6ac0c8493c4f2",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! String manipulation\n//!\n//! For more details, see std::str\n\n#[allow(missing_docs)]\npub mod lossy;\n\n// https://tools.ietf.org/html/rfc3629\n#[rustfmt::skip]\nstatic UTF8_CHAR_WIDTH: [u8; 256] = [\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF\n0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,\n2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF\n3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF\n4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF\n];\n\n/// Given a first byte, determines how many bytes are in this UTF-8 character.\n#[inline]\npub fn utf8_char_width(b: u8) -> usize {\n    UTF8_CHAR_WIDTH[b as usize] as usize\n}\n"
    },
    {
      "package": "bumpalo@3.20.3",
      "sourcePath": "src/collections/string.rs",
      "sha256": "9cbca6a0c6ae8b9c961d7a140d5146ba4c1f2e7a317c33e2e693911f2848044d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! A UTF-8 encoded, growable string.\n//!\n//! This module contains the [`String`] type and several error types that may\n//! result from working with [`String`]s.\n//!\n//! This module is a fork of the [`std::string`] module, that uses a bump allocator.\n//!\n//! [`std::string`]: https://doc.rust-lang.org/std/string/index.html\n//!\n//! # Examples\n//!\n//! You can create a new [`String`] from a string literal with [`String::from_str_in`]:\n//!\n//! ```\n//! use bumpalo::{Bump, collections::String};\n//!\n//! let b = Bump::new();\n//!\n//! let s = String::from_str_in(\"world\", &b);\n//! ```\n//!\n//! [`String`]: struct.String.html\n//! [`String::from_str_in`]: struct.String.html#method.from_str_in\n//!\n//! If you have a vector of valid UTF-8 bytes, you can make a [`String`] out of\n//! it. You can do the reverse too.\n//!\n//! ```\n//! use bumpalo::{Bump, collections::String};\n//!\n//! let b = Bump::new();\n//!\n//! let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];\n//!\n//! // We know these bytes are valid, so we'll use `unwrap()`.\n//! let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();\n//!\n//! assert_eq!(\"💖\", sparkle_heart);\n//!\n//! let bytes = sparkle_heart.into_bytes();\n//!\n//! assert_eq!(bytes, [240, 159, 146, 150]);\n//! ```\n\nuse crate::collections::str::lossy;\nuse crate::collections::vec::Vec;\nuse crate::Bump;\nuse core::borrow::{Borrow, BorrowMut};\nuse core::char::decode_utf16;\nuse core::fmt;\nuse core::hash;\nuse core::iter::FusedIterator;\nuse core::mem;\nuse core::ops::Bound::{Excluded, Included, Unbounded};\nuse core::ops::{self, Add, AddAssign, Index, IndexMut, RangeBounds};\nuse core::ptr;\nuse core::str::{self, Chars, Utf8Error};\nuse core_alloc::borrow::Cow;\n\n/// Like the [`format!`] macro, but for creating [`bumpalo::collections::String`]s.\n///\n/// [`format!`]: https://doc.rust-lang.org/std/macro.format.html\n/// [`bumpalo::collections::String`]: collections/string/struct.String.html\n///\n/// # Examples\n///\n/// ```\n/// use bumpalo::Bump;\n///\n/// let b = Bump::new();\n///\n/// let who = \"World\";\n/// let s = bumpalo::format!(in &b, \"Hello, {}!\", who);\n/// assert_eq!(s, \"Hello, World!\")\n/// ```\n#[macro_export]\nmacro_rules! format {\n    ( in $bump:expr, $fmt:expr, $($args:expr),* ) => {{\n        use $crate::core_alloc::fmt::Write;\n        let bump = $bump;\n        let mut s = $crate::collections::String::new_in(bump);\n        let _ = write!(&mut s, $fmt, $($args),*);\n        s\n    }};\n\n    ( in $bump:expr, $fmt:expr, $($args:expr,)* ) => {\n        $crate::format!(in $bump, $fmt, $($args),*)\n    };\n}\n\n/// A UTF-8 encoded, growable string.\n///\n/// The `String` type is the most common string type that has ownership over the\n/// contents of the string. It has a close relationship with its borrowed\n/// counterpart, the primitive [`str`].\n///\n/// [`str`]: https://doc.rust-lang.org/std/primitive.str.html\n///\n/// # Examples\n///\n/// You can create a `String` from a literal string with [`String::from_str_in`]:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let b = Bump::new();\n///\n/// let hello = String::from_str_in(\"Hello, world!\", &b);\n/// ```\n///\n/// You can append a [`char`] to a `String` with the [`push`] method, and\n/// append a [`&str`] with the [`push_str`] method:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let b = Bump::new();\n///\n/// let mut hello = String::from_str_in(\"Hello, \", &b);\n///\n/// hello.push('w');\n/// hello.push_str(\"orld!\");\n/// ```\n///\n/// [`char`]: https://doc.rust-lang.org/std/primitive.char.html\n/// [`push`]: #method.push\n/// [`push_str`]: #method.push_str\n///\n/// If you have a vector of UTF-8 bytes, you can create a `String` from it with\n/// the [`from_utf8`] method:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let b = Bump::new();\n///\n/// // some bytes, in a vector\n/// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];\n///\n/// // We know these bytes are valid, so we'll use `unwrap()`.\n/// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();\n///\n/// assert_eq!(\"💖\", sparkle_heart);\n/// ```\n///\n/// [`from_utf8`]: #method.from_utf8\n///\n/// # Deref\n///\n/// `String`s implement <code>[`Deref`]<Target = [`str`]></code>, and so inherit all of [`str`]'s\n/// methods. In addition, this means that you can pass a `String` to a\n/// function which takes a [`&str`] by using an ampersand (`&`):\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let b = Bump::new();\n///\n/// fn takes_str(s: &str) { }\n///\n/// let s = String::from_str_in(\"Hello\", &b);\n///\n/// takes_str(&s);\n/// ```\n///\n/// This will create a [`&str`] from the `String` and pass it in. This\n/// conversion is very inexpensive, and so generally, functions will accept\n/// [`&str`]s as arguments unless they need a `String` for some specific\n/// reason.\n///\n/// In certain cases Rust doesn't have enough information to make this\n/// conversion, known as [`Deref`] coercion. In the following example a string\n/// slice [`&'a str`][`&str`] implements the trait `TraitExample`, and the function\n/// `example_func` takes anything that implements the trait. In this case Rust\n/// would need to make two implicit conversions, which Rust doesn't have the\n/// means to do. For that reason, the following example will not compile.\n///\n/// ```compile_fail,E0277\n/// use bumpalo::{Bump, collections::String};\n///\n/// trait TraitExample {}\n///\n/// impl<'a> TraitExample for &'a str {}\n///\n/// fn example_func<A: TraitExample>(example_arg: A) {}\n///\n/// let b = Bump::new();\n/// let example_string = String::from_str_in(\"example_string\", &b);\n/// example_func(&example_string);\n/// ```\n///\n/// There are two options that would work instead. The first would be to\n/// change the line `example_func(&example_string);` to\n/// `example_func(example_string.as_str());`, using the method [`as_str()`]\n/// to explicitly extract the string slice containing the string. The second\n/// way changes `example_func(&example_string);` to\n/// `example_func(&*example_string);`. In this case we are dereferencing a\n/// `String` to a [`str`][`&str`], then referencing the [`str`][`&str`] back to\n/// [`&str`]. The second way is more idiomatic, however both work to do the\n/// conversion explicitly rather than relying on the implicit conversion.\n///\n/// # Representation\n///\n/// A `String` is made up of three components: a pointer to some bytes, a\n/// length, and a capacity. The pointer points to an internal buffer `String`\n/// uses to store its data. The length is the number of bytes currently stored\n/// in the buffer, and the capacity is the size of the buffer in bytes. As such,\n/// the length will always be less than or equal to the capacity.\n///\n/// This buffer is always stored on the heap.\n///\n/// You can look at these with the [`as_ptr`], [`len`], and [`capacity`]\n/// methods:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n/// use std::mem;\n///\n/// let b = Bump::new();\n///\n/// let mut story = String::from_str_in(\"Once upon a time...\", &b);\n///\n/// let ptr = story.as_mut_ptr();\n/// let len = story.len();\n/// let capacity = story.capacity();\n///\n/// // story has nineteen bytes\n/// assert_eq!(19, len);\n///\n/// // Now that we have our parts, we throw the story away.\n/// mem::forget(story);\n///\n/// // We can re-build a String out of ptr, len, and capacity. This is all\n/// // unsafe because we are responsible for making sure the components are\n/// // valid:\n/// let s = unsafe { String::from_raw_parts_in(ptr, len, capacity, &b) } ;\n///\n/// assert_eq!(String::from_str_in(\"Once upon a time...\", &b), s);\n/// ```\n///\n/// [`as_ptr`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_ptr\n/// [`len`]: #method.len\n/// [`capacity`]: #method.capacity\n///\n/// If a `String` has enough capacity, adding elements to it will not\n/// re-allocate. For example, consider this program:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let b = Bump::new();\n///\n/// let mut s = String::new_in(&b);\n///\n/// println!(\"{}\", s.capacity());\n///\n/// for _ in 0..5 {\n///     s.push_str(\"hello\");\n///     println!(\"{}\", s.capacity());\n/// }\n/// ```\n///\n/// This will output the following:\n///\n/// ```text\n/// 0\n/// 5\n/// 10\n/// 20\n/// 20\n/// 40\n/// ```\n///\n/// At first, we have no memory allocated at all, but as we append to the\n/// string, it increases its capacity appropriately. If we instead use the\n/// [`with_capacity_in`] method to allocate the correct capacity initially:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let b = Bump::new();\n///\n/// let mut s = String::with_capacity_in(25, &b);\n///\n/// println!(\"{}\", s.capacity());\n///\n/// for _ in 0..5 {\n///     s.push_str(\"hello\");\n///     println!(\"{}\", s.capacity());\n/// }\n/// ```\n///\n/// [`with_capacity_in`]: #method.with_capacity_in\n///\n/// We end up with a different output:\n///\n/// ```text\n/// 25\n/// 25\n/// 25\n/// 25\n/// 25\n/// 25\n/// ```\n///\n/// Here, there's no need to allocate more memory inside the loop.\n///\n/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html\n/// [`Deref`]: https://doc.rust-lang.org/std/ops/trait.Deref.html\n/// [`as_str()`]: struct.String.html#method.as_str\n#[derive(PartialOrd, Eq, Ord)]\npub struct String<'bump> {\n    vec: Vec<'bump, u8>,\n}\n\n/// A possible error value when converting a `String` from a UTF-8 byte vector.\n///\n/// This type is the error type for the [`from_utf8`] method on [`String`]. It\n/// is designed in such a way to carefully avoid reallocations: the\n/// [`into_bytes`] method will give back the byte vector that was used in the\n/// conversion attempt.\n///\n/// [`from_utf8`]: struct.String.html#method.from_utf8\n/// [`String`]: struct.String.html\n/// [`into_bytes`]: struct.FromUtf8Error.html#method.into_bytes\n///\n/// The [`Utf8Error`] type provided by [`std::str`] represents an error that may\n/// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's\n/// an analogue to `FromUtf8Error`, and you can get one from a `FromUtf8Error`\n/// through the [`utf8_error`] method.\n///\n/// [`Utf8Error`]: https://doc.rust-lang.org/std/str/struct.Utf8Error.html\n/// [`std::str`]: https://doc.rust-lang.org/std/str/index.html\n/// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html\n/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html\n/// [`utf8_error`]: #method.utf8_error\n///\n/// # Examples\n///\n/// Basic usage:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let b = Bump::new();\n///\n/// // some invalid bytes, in a vector\n/// let bytes = bumpalo::vec![in &b; 0, 159];\n///\n/// let value = String::from_utf8(bytes);\n///\n/// assert!(value.is_err());\n/// assert_eq!(bumpalo::vec![in &b; 0, 159], value.unwrap_err().into_bytes());\n/// ```\n#[derive(Debug)]\npub struct FromUtf8Error<'bump> {\n    bytes: Vec<'bump, u8>,\n    error: Utf8Error,\n}\n\n/// A possible error value when converting a `String` from a UTF-16 byte slice.\n///\n/// This type is the error type for the [`from_utf16_in`] method on [`String`].\n///\n/// [`from_utf16_in`]: struct.String.html#method.from_utf16_in\n/// [`String`]: struct.String.html\n///\n/// # Examples\n///\n/// Basic usage:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let b = Bump::new();\n///\n/// // 𝄞mu<invalid>ic\n/// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063];\n///\n/// assert!(String::from_utf16_in(v, &b).is_err());\n/// ```\n#[derive(Debug)]\npub struct FromUtf16Error(());\n\nimpl<'bump> String<'bump> {\n    /// Creates a new empty `String`.\n    ///\n    /// Given that the `String` is empty, this will not allocate any initial\n    /// buffer. While that means that this initial operation is very\n    /// inexpensive, it may cause excessive allocation later when you add\n    /// data. If you have an idea of how much data the `String` will hold,\n    /// consider the [`with_capacity_in`] method to prevent excessive\n    /// re-allocation.\n    ///\n    /// [`with_capacity_in`]: #method.with_capacity_in\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let s = String::new_in(&b);\n    /// ```\n    #[inline]\n    pub fn new_in(bump: &'bump Bump) -> String<'bump> {\n        String {\n            vec: Vec::new_in(bump),\n        }\n    }\n\n    /// Creates a new empty `String` with a particular capacity.\n    ///\n    /// `String`s have an internal buffer to hold their data. The capacity is\n    /// the length of that buffer, and can be queried with the [`capacity`]\n    /// method. This method creates an empty `String`, but one with an initial\n    /// buffer that can hold `capacity` bytes. This is useful when you may be\n    /// appending a bunch of data to the `String`, reducing the number of\n    /// reallocations it needs to do.\n    ///\n    /// [`capacity`]: #method.capacity\n    ///\n    /// If the given capacity is `0`, no allocation will occur, and this method\n    /// is identical to the [`new_in`] method.\n    ///\n    /// [`new_in`]: #method.new\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::with_capacity_in(10, &b);\n    ///\n    /// // The String contains no chars, even though it has capacity for more\n    /// assert_eq!(s.len(), 0);\n    ///\n    /// // These are all done without reallocating...\n    /// let cap = s.capacity();\n    /// for _ in 0..10 {\n    ///     s.push('a');\n    /// }\n    ///\n    /// assert_eq!(s.capacity(), cap);\n    ///\n    /// // ...but this may make the vector reallocate\n    /// s.push('a');\n    /// ```\n    #[inline]\n    pub fn with_capacity_in(capacity: usize, bump: &'bump Bump) -> String<'bump> {\n        String {\n            vec: Vec::with_capacity_in(capacity, bump),\n        }\n    }\n\n    /// Converts a vector of bytes to a `String`.\n    ///\n    /// A string (`String`) is made of bytes ([`u8`]), and a vector of bytes\n    /// ([`Vec<u8>`]) is made of bytes, so this function converts between the\n    /// two. Not all byte slices are valid `String`s, however: `String`\n    /// requires that it is valid UTF-8. `from_utf8()` checks to ensure that\n    /// the bytes are valid UTF-8, and then does the conversion.\n    ///\n    /// If you are sure that the byte slice is valid UTF-8, and you don't want\n    /// to incur the overhead of the validity check, there is an unsafe version\n    /// of this function, [`from_utf8_unchecked`], which has the same behavior\n    /// but skips the check.\n    ///\n    /// This method will take care to not copy the vector, for efficiency's\n    /// sake.\n    ///\n    /// If you need a [`&str`] instead of a `String`, consider\n    /// [`str::from_utf8`].\n    ///\n    /// The inverse of this method is [`into_bytes`].\n    ///\n    /// # Errors\n    ///\n    /// Returns [`Err`] if the slice is not UTF-8 with a description as to why the\n    /// provided bytes are not UTF-8. The vector you moved in is also included.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// // some bytes, in a vector\n    /// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];\n    ///\n    /// // We know these bytes are valid, so we'll use `unwrap()`.\n    /// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();\n    ///\n    /// assert_eq!(\"💖\", sparkle_heart);\n    /// ```\n    ///\n    /// Incorrect bytes:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// // some invalid bytes, in a vector\n    /// let sparkle_heart = bumpalo::vec![in &b; 0, 159, 146, 150];\n    ///\n    /// assert!(String::from_utf8(sparkle_heart).is_err());\n    /// ```\n    ///\n    /// See the docs for [`FromUtf8Error`] for more details on what you can do\n    /// with this error.\n    ///\n    /// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked\n    /// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html\n    /// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html\n    /// [`Vec<u8>`]: ../vec/struct.Vec.html\n    /// [`str::from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html\n    /// [`into_bytes`]: struct.String.html#method.into_bytes\n    /// [`FromUtf8Error`]: struct.FromUtf8Error.html\n    /// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err\n    #[inline]\n    pub fn from_utf8(vec: Vec<'bump, u8>) -> Result<String<'bump>, FromUtf8Error<'bump>> {\n        match str::from_utf8(&vec) {\n            Ok(..) => Ok(String { vec }),\n            Err(e) => Err(FromUtf8Error {\n                bytes: vec,\n                error: e,\n            }),\n        }\n    }\n\n    /// Converts a slice of bytes to a string, including invalid characters.\n    ///\n    /// Strings are made of bytes ([`u8`]), and a slice of bytes\n    /// ([`&[u8]`][slice]) is made of bytes, so this function converts\n    /// between the two. Not all byte slices are valid strings, however: strings\n    /// are required to be valid UTF-8. During this conversion,\n    /// `from_utf8_lossy_in()` will replace any invalid UTF-8 sequences with\n    /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD], which looks like this: �\n    ///\n    /// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html\n    /// [slice]: https://doc.rust-lang.org/std/primitive.slice.html\n    /// [U+FFFD]: https://doc.rust-lang.org/std/char/constant.REPLACEMENT_CHARACTER.html\n    ///\n    /// If you are sure that the byte slice is valid UTF-8, and you don't want\n    /// to incur the overhead of the conversion, there is an unsafe version\n    /// of this function, [`from_utf8_unchecked`], which has the same behavior\n    /// but skips the checks.\n    ///\n    /// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{collections::String, Bump, vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// // some bytes, in a vector\n    /// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];\n    ///\n    /// let sparkle_heart = String::from_utf8_lossy_in(&sparkle_heart, &b);\n    ///\n    /// assert_eq!(\"💖\", sparkle_heart);\n    /// ```\n    ///\n    /// Incorrect bytes:\n    ///\n    /// ```\n    /// use bumpalo::{collections::String, Bump, vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// // some invalid bytes\n    /// let input = b\"Hello \\xF0\\x90\\x80World\";\n    /// let output = String::from_utf8_lossy_in(input, &b);\n    ///\n    /// assert_eq!(\"Hello �World\", output);\n    /// ```\n    pub fn from_utf8_lossy_in(v: &[u8], bump: &'bump Bump) -> String<'bump> {\n        let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks();\n\n        let (first_valid, first_broken) = if let Some(chunk) = iter.next() {\n            let lossy::Utf8LossyChunk { valid, broken } = chunk;\n            if valid.len() == v.len() {\n                debug_assert!(broken.is_empty());\n                unsafe {\n                    return String::from_utf8_unchecked(Vec::from_iter_in(v.iter().cloned(), bump));\n                }\n            }\n            (valid, broken)\n        } else {\n            return String::from_str_in(\"\", bump);\n        };\n\n        const REPLACEMENT: &str = \"\\u{FFFD}\";\n\n        let mut res = String::with_capacity_in(v.len(), bump);\n        res.push_str(first_valid);\n        if !first_broken.is_empty() {\n            res.push_str(REPLACEMENT);\n        }\n\n        for lossy::Utf8LossyChunk { valid, broken } in iter {\n            res.push_str(valid);\n            if !broken.is_empty() {\n                res.push_str(REPLACEMENT);\n            }\n        }\n\n        res\n    }\n\n    /// Decode a UTF-16 encoded slice `v` into a `String`, returning [`Err`]\n    /// if `v` contains any invalid data.\n    ///\n    /// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// // 𝄞music\n    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0x0069, 0x0063];\n    /// assert_eq!(String::from_str_in(\"𝄞music\", &b), String::from_utf16_in(v, &b).unwrap());\n    ///\n    /// // 𝄞mu<invalid>ic\n    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063];\n    /// assert!(String::from_utf16_in(v, &b).is_err());\n    /// ```\n    pub fn from_utf16_in(v: &[u16], bump: &'bump Bump) -> Result<String<'bump>, FromUtf16Error> {\n        let mut ret = String::with_capacity_in(v.len(), bump);\n        for c in decode_utf16(v.iter().cloned()) {\n            if let Ok(c) = c {\n                ret.push(c);\n            } else {\n                return Err(FromUtf16Error(()));\n            }\n        }\n        Ok(ret)\n    }\n\n    /// Construct a new `String<'bump>` from a string slice.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let s = String::from_str_in(\"hello\", &b);\n    /// assert_eq!(s, \"hello\");\n    /// ```\n    #[inline]\n    pub fn from_str_in(s: &str, bump: &'bump Bump) -> String<'bump> {\n        let len = s.len();\n        let mut t = String::with_capacity_in(len, bump);\n        // SAFETY:\n        // * `src` is valid for reads of `s.len()` bytes by virtue of being an allocated `&str`.\n        // * `dst` is valid for writes of `s.len()` bytes as `String::with_capacity_in(s.len(), bump)`\n        //   above guarantees that.\n        // * Alignment is not relevant as `u8` has no alignment requirements.\n        // * Source and destination ranges cannot overlap as we just reserved the destination\n        //   range from the bump.\n        unsafe { ptr::copy_nonoverlapping(s.as_ptr(), t.vec.as_mut_ptr(), len) };\n        // SAFETY: We reserved sufficent capacity for the string above.\n        // The elements at `0..len` were initialized by `copy_nonoverlapping` above.\n        unsafe { t.vec.set_len(len) };\n        t\n    }\n\n    /// Construct a new `String<'bump>` from an iterator of `char`s.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let s = String::from_iter_in(['h', 'e', 'l', 'l', 'o'].iter().cloned(), &b);\n    /// assert_eq!(s, \"hello\");\n    /// ```\n    pub fn from_iter_in<I: IntoIterator<Item = char>>(iter: I, bump: &'bump Bump) -> String<'bump> {\n        let mut s = String::new_in(bump);\n        for c in iter {\n            s.push(c);\n        }\n        s\n    }\n\n    /// Creates a new `String` from a length, capacity, and pointer.\n    ///\n    /// # Safety\n    ///\n    /// This is highly unsafe, due to the number of invariants that aren't\n    /// checked:\n    ///\n    /// * The memory at `ptr` needs to have been previously allocated by the\n    ///   same allocator the standard library uses.\n    /// * `length` needs to be less than or equal to `capacity`.\n    /// * `capacity` needs to be the correct value.\n    ///\n    /// Violating these may cause problems like corrupting the allocator's\n    /// internal data structures.\n    ///\n    /// The ownership of `ptr` is effectively transferred to the\n    /// `String` which may then deallocate, reallocate or change the\n    /// contents of memory pointed to by the pointer at will. Ensure\n    /// that nothing else uses the pointer after calling this\n    /// function.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    /// use std::mem;\n    ///\n    /// let b = Bump::new();\n    ///\n    /// unsafe {\n    ///     let mut s = String::from_str_in(\"hello\", &b);\n    ///     let ptr = s.as_mut_ptr();\n    ///     let len = s.len();\n    ///     let capacity = s.capacity();\n    ///\n    ///     mem::forget(s);\n    ///\n    ///     let s = String::from_raw_parts_in(ptr, len, capacity, &b);\n    ///\n    ///     assert_eq!(s, \"hello\");\n    /// }\n    /// ```\n    #[inline]\n    pub unsafe fn from_raw_parts_in(\n        buf: *mut u8,\n        length: usize,\n        capacity: usize,\n        bump: &'bump Bump,\n    ) -> String<'bump> {\n        String {\n            vec: Vec::from_raw_parts_in(buf, length, capacity, bump),\n        }\n    }\n\n    /// Converts a vector of bytes to a `String` without checking that the\n    /// string contains valid UTF-8.\n    ///\n    /// See the safe version, [`from_utf8`], for more details.\n    ///\n    /// [`from_utf8`]: struct.String.html#method.from_utf8\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because it does not check that the bytes passed\n    /// to it are valid UTF-8. If this constraint is violated, it may cause\n    /// memory unsafety issues with future users of the `String`,\n    /// as it is assumed that `String`s are valid UTF-8.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// // some bytes, in a vector\n    /// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];\n    ///\n    /// let sparkle_heart = unsafe {\n    ///     String::from_utf8_unchecked(sparkle_heart)\n    /// };\n    ///\n    /// assert_eq!(\"💖\", sparkle_heart);\n    /// ```\n    #[inline]\n    pub unsafe fn from_utf8_unchecked(bytes: Vec<'bump, u8>) -> String<'bump> {\n        String { vec: bytes }\n    }\n\n    /// Returns a shared reference to the allocator backing this `String`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// // uses the same allocator as the provided `String`\n    /// fn copy_string<'bump>(s: &String<'bump>) -> &'bump str {\n    ///     s.bump().alloc_str(s.as_str())\n    /// }\n    /// ```\n    #[inline]\n    #[must_use]\n    pub fn bump(&self) -> &'bump Bump {\n        self.vec.bump()\n    }\n\n    /// Converts a `String` into a byte vector.\n    ///\n    /// This consumes the `String`, so we do not need to copy its contents.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let s = String::from_str_in(\"hello\", &b);\n    ///\n    /// assert_eq!(s.into_bytes(), [104, 101, 108, 108, 111]);\n    /// ```\n    #[inline]\n    pub fn into_bytes(self) -> Vec<'bump, u8> {\n        self.vec\n    }\n\n    /// Convert this `String<'bump>` into a `&'bump str`. This is analogous to\n    /// [`std::string::String::into_boxed_str`][into_boxed_str].\n    ///\n    /// [into_boxed_str]: https://doc.rust-lang.org/std/string/struct.String.html#method.into_boxed_str\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let s = String::from_str_in(\"foo\", &b);\n    ///\n    /// assert_eq!(s.into_bump_str(), \"foo\");\n    /// ```\n    pub fn into_bump_str(self) -> &'bump str {\n        let s = unsafe {\n            let s = self.as_str();\n            mem::transmute(s)\n        };\n        mem::forget(self);\n        s\n    }\n\n    /// Extracts a string slice containing the entire `String`.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let s = String::from_str_in(\"foo\", &b);\n    ///\n    /// assert_eq!(\"foo\", s.as_str());\n    /// ```\n    #[inline]\n    pub fn as_str(&self) -> &str {\n        self\n    }\n\n    /// Converts a `String` into a mutable string slice.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"foobar\", &b);\n    /// let s_mut_str = s.as_mut_str();\n    ///\n    /// s_mut_str.make_ascii_uppercase();\n    ///\n    /// assert_eq!(\"FOOBAR\", s_mut_str);\n    /// ```\n    #[inline]\n    pub fn as_mut_str(&mut self) -> &mut str {\n        self\n    }\n\n    /// Appends a given string slice onto the end of this `String`.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"foo\", &b);\n    ///\n    /// s.push_str(\"bar\");\n    ///\n    /// assert_eq!(\"foobar\", s);\n    /// ```\n    #[inline]\n    pub fn push_str(&mut self, string: &str) {\n        self.vec.extend_from_slice_copy(string.as_bytes())\n    }\n\n    /// Returns this `String`'s capacity, in bytes.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let s = String::with_capacity_in(10, &b);\n    ///\n    /// assert!(s.capacity() >= 10);\n    /// ```\n    #[inline]\n    pub fn capacity(&self) -> usize {\n        self.vec.capacity()\n    }\n\n    /// Ensures that this `String`'s capacity is at least `additional` bytes\n    /// larger than its length.\n    ///\n    /// The capacity may be increased by more than `additional` bytes if it\n    /// chooses, to prevent frequent reallocations.\n    ///\n    /// If you do not want this \"at least\" behavior, see the [`reserve_exact`]\n    /// method.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the new capacity overflows [`usize`].\n    ///\n    /// [`reserve_exact`]: struct.String.html#method.reserve_exact\n    /// [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::new_in(&b);\n    ///\n    /// s.reserve(10);\n    ///\n    /// assert!(s.capacity() >= 10);\n    /// ```\n    ///\n    /// This may not actually increase the capacity:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::with_capacity_in(10, &b);\n    /// s.push('a');\n    /// s.push('b');\n    ///\n    /// // s now has a length of 2 and a capacity of 10\n    /// assert_eq!(2, s.len());\n    /// assert_eq!(10, s.capacity());\n    ///\n    /// // Since we already have an extra 8 capacity, calling this...\n    /// s.reserve(8);\n    ///\n    /// // ... doesn't actually increase.\n    /// assert_eq!(10, s.capacity());\n    /// ```\n    #[inline]\n    pub fn reserve(&mut self, additional: usize) {\n        self.vec.reserve(additional)\n    }\n\n    /// Ensures that this `String`'s capacity is `additional` bytes\n    /// larger than its length.\n    ///\n    /// Consider using the [`reserve`] method unless you absolutely know\n    /// better than the allocator.\n    ///\n    /// [`reserve`]: #method.reserve\n    ///\n    /// # Panics\n    ///\n    /// Panics if the new capacity overflows `usize`.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::new_in(&b);\n    ///\n    /// s.reserve_exact(10);\n    ///\n    /// assert!(s.capacity() >= 10);\n    /// ```\n    ///\n    /// This may not actually increase the capacity:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::with_capacity_in(10, &b);\n    /// s.push('a');\n    /// s.push('b');\n    ///\n    /// // s now has a length of 2 and a capacity of 10\n    /// assert_eq!(2, s.len());\n    /// assert_eq!(10, s.capacity());\n    ///\n    /// // Since we already have an extra 8 capacity, calling this...\n    /// s.reserve_exact(8);\n    ///\n    /// // ... doesn't actually increase.\n    /// assert_eq!(10, s.capacity());\n    /// ```\n    #[inline]\n    pub fn reserve_exact(&mut self, additional: usize) {\n        self.vec.reserve_exact(additional)\n    }\n\n    /// Shrinks the capacity of this `String` to match its length.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"foo\", &b);\n    ///\n    /// s.reserve(100);\n    /// assert!(s.capacity() >= 100);\n    ///\n    /// s.shrink_to_fit();\n    /// assert_eq!(3, s.capacity());\n    /// ```\n    #[inline]\n    pub fn shrink_to_fit(&mut self) {\n        self.vec.shrink_to_fit()\n    }\n\n    /// Appends the given [`char`] to the end of this `String`.\n    ///\n    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"abc\", &b);\n    ///\n    /// s.push('1');\n    /// s.push('2');\n    /// s.push('3');\n    ///\n    /// assert_eq!(\"abc123\", s);\n    /// ```\n    #[inline]\n    pub fn push(&mut self, ch: char) {\n        match ch.len_utf8() {\n            1 => self.vec.push(ch as u8),\n            _ => self\n                .vec\n                .extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()),\n        }\n    }\n\n    /// Returns a byte slice of this `String`'s contents.\n    ///\n    /// The inverse of this method is [`from_utf8`].\n    ///\n    /// [`from_utf8`]: #method.from_utf8\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let s = String::from_str_in(\"hello\", &b);\n    ///\n    /// assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());\n    /// ```\n    #[inline]\n    pub fn as_bytes(&self) -> &[u8] {\n        &self.vec\n    }\n\n    /// Shortens this `String` to the specified length.\n    ///\n    /// If `new_len` is greater than the string's current length, this has no\n    /// effect.\n    ///\n    /// Note that this method has no effect on the allocated capacity\n    /// of the string.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `new_len` does not lie on a [`char`] boundary.\n    ///\n    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"hello\", &b);\n    ///\n    /// s.truncate(2);\n    ///\n    /// assert_eq!(\"he\", s);\n    /// ```\n    #[inline]\n    pub fn truncate(&mut self, new_len: usize) {\n        if new_len <= self.len() {\n            assert!(self.is_char_boundary(new_len));\n            self.vec.truncate(new_len)\n        }\n    }\n\n    /// Removes the last character from the string buffer and returns it.\n    ///\n    /// Returns [`None`] if this `String` is empty.\n    ///\n    /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"foo\", &b);\n    ///\n    /// assert_eq!(s.pop(), Some('o'));\n    /// assert_eq!(s.pop(), Some('o'));\n    /// assert_eq!(s.pop(), Some('f'));\n    ///\n    /// assert_eq!(s.pop(), None);\n    /// ```\n    #[inline]\n    pub fn pop(&mut self) -> Option<char> {\n        let ch = self.chars().rev().next()?;\n        let newlen = self.len() - ch.len_utf8();\n        unsafe {\n            self.vec.set_len(newlen);\n        }\n        Some(ch)\n    }\n\n    /// Removes a [`char`] from this `String` at a byte position and returns it.\n    ///\n    /// This is an `O(n)` operation, as it requires copying every element in the\n    /// buffer.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `idx` is larger than or equal to the `String`'s length,\n    /// or if it does not lie on a [`char`] boundary.\n    ///\n    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"foo\", &b);\n    ///\n    /// assert_eq!(s.remove(0), 'f');\n    /// assert_eq!(s.remove(1), 'o');\n    /// assert_eq!(s.remove(0), 'o');\n    /// ```\n    #[inline]\n    pub fn remove(&mut self, idx: usize) -> char {\n        let ch = match self[idx..].chars().next() {\n            Some(ch) => ch,\n            None => panic!(\"cannot remove a char from the end of a string\"),\n        };\n\n        let next = idx + ch.len_utf8();\n        let len = self.len();\n        unsafe {\n            ptr::copy(\n                self.vec.as_ptr().add(next),\n                self.vec.as_mut_ptr().add(idx),\n                len - next,\n            );\n            self.vec.set_len(len - (next - idx));\n        }\n        ch\n    }\n\n    /// Retains only the characters specified by the predicate.\n    ///\n    /// In other words, remove all characters `c` such that `f(c)` returns `false`.\n    /// This method operates in place and preserves the order of the retained\n    /// characters.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"f_o_ob_ar\", &b);\n    ///\n    /// s.retain(|c| c != '_');\n    ///\n    /// assert_eq!(s, \"foobar\");\n    /// ```\n    #[inline]\n    pub fn retain<F>(&mut self, mut f: F)\n    where\n        F: FnMut(char) -> bool,\n    {\n        struct SetLenOnDrop<'a, 'bump> {\n            s: &'a mut String<'bump>,\n            idx: usize,\n            del_bytes: usize,\n        }\n\n        impl<'a, 'bump> Drop for SetLenOnDrop<'a, 'bump> {\n            fn drop(&mut self) {\n                let new_len = self.idx - self.del_bytes;\n                debug_assert!(new_len <= self.s.len());\n                unsafe { self.s.vec.set_len(new_len) };\n            }\n        }\n\n        let len = self.len();\n        let mut guard = SetLenOnDrop {\n            s: self,\n            idx: 0,\n            del_bytes: 0,\n        };\n\n        while guard.idx < len {\n            let ch =\n                // SAFETY: `guard.idx` is positive-or-zero and less that len so the `get_unchecked`\n                // is in bound. `self` is valid UTF-8 like string and the returned slice starts at\n                // a unicode code point so the `Chars` always return one character.\n                unsafe { guard.s.get_unchecked(guard.idx..len).chars().next().unwrap_unchecked() };\n            let ch_len = ch.len_utf8();\n\n            if !f(ch) {\n                guard.del_bytes += ch_len;\n            } else if guard.del_bytes > 0 {\n                // SAFETY: `guard.idx` is in bound and `guard.del_bytes` represent the number of\n                // bytes that are erased from the string so the resulting `guard.idx -\n                // guard.del_bytes` always represent a valid unicode code point.\n                //\n                // `guard.del_bytes` >= `ch.len_utf8()`, so taking a slice with `ch.len_utf8()` len\n                // is safe.\n                ch.encode_utf8(unsafe {\n                    core::slice::from_raw_parts_mut(\n                        guard.s.as_mut_ptr().add(guard.idx - guard.del_bytes),\n                        ch.len_utf8(),\n                    )\n                });\n            }\n\n            // Point idx to the next char\n            guard.idx += ch_len;\n        }\n\n        drop(guard);\n    }\n\n    /// Inserts a character into this `String` at a byte position.\n    ///\n    /// This is an `O(n)` operation as it requires copying every element in the\n    /// buffer.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `idx` is larger than the `String`'s length, or if it does not\n    /// lie on a [`char`] boundary.\n    ///\n    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::with_capacity_in(3, &b);\n    ///\n    /// s.insert(0, 'f');\n    /// s.insert(1, 'o');\n    /// s.insert(2, 'o');\n    ///\n    /// assert_eq!(\"foo\", s);\n    /// ```\n    #[inline]\n    pub fn insert(&mut self, idx: usize, ch: char) {\n        assert!(self.is_char_boundary(idx));\n        let mut bits = [0; 4];\n        let bits = ch.encode_utf8(&mut bits).as_bytes();\n\n        unsafe {\n            self.insert_bytes(idx, bits);\n        }\n    }\n\n    unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {\n        let len = self.len();\n        let amt = bytes.len();\n        self.vec.reserve(amt);\n\n        ptr::copy(\n            self.vec.as_ptr().add(idx),\n            self.vec.as_mut_ptr().add(idx + amt),\n            len - idx,\n        );\n        ptr::copy(bytes.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);\n        self.vec.set_len(len + amt);\n    }\n\n    /// Inserts a string slice into this `String` at a byte position.\n    ///\n    /// This is an `O(n)` operation as it requires copying every element in the\n    /// buffer.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `idx` is larger than the `String`'s length, or if it does not\n    /// lie on a [`char`] boundary.\n    ///\n    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"bar\", &b);\n    ///\n    /// s.insert_str(0, \"foo\");\n    ///\n    /// assert_eq!(\"foobar\", s);\n    /// ```\n    #[inline]\n    pub fn insert_str(&mut self, idx: usize, string: &str) {\n        assert!(self.is_char_boundary(idx));\n\n        unsafe {\n            self.insert_bytes(idx, string.as_bytes());\n        }\n    }\n\n    /// Returns a mutable reference to the contents of this `String`.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because the returned `&mut Vec` allows writing\n    /// bytes which are not valid UTF-8. If this constraint is violated, using\n    /// the original `String` after dropping the `&mut Vec` may violate memory\n    /// safety, as it is assumed that `String`s are valid UTF-8.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"hello\", &b);\n    ///\n    /// unsafe {\n    ///     let vec = s.as_mut_vec();\n    ///     assert_eq!(vec, &[104, 101, 108, 108, 111]);\n    ///\n    ///     vec.reverse();\n    /// }\n    /// assert_eq!(s, \"olleh\");\n    /// ```\n    #[inline]\n    pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<'bump, u8> {\n        &mut self.vec\n    }\n\n    /// Returns the length of this `String`, in bytes.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let a = String::from_str_in(\"foo\", &b);\n    ///\n    /// assert_eq!(a.len(), 3);\n    /// ```\n    #[inline]\n    pub fn len(&self) -> usize {\n        self.vec.len()\n    }\n\n    /// Returns `true` if this `String` has a length of zero.\n    ///\n    /// Returns `false` otherwise.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut v = String::new_in(&b);\n    /// assert!(v.is_empty());\n    ///\n    /// v.push('a');\n    /// assert!(!v.is_empty());\n    /// ```\n    #[inline]\n    pub fn is_empty(&self) -> bool {\n        self.len() == 0\n    }\n\n    /// Splits the string into two at the given index.\n    ///\n    /// Returns a newly allocated `String`. `self` contains bytes `[0, at)`, and\n    /// the returned `String` contains bytes `[at, len)`. `at` must be on the\n    /// boundary of a UTF-8 code point.\n    ///\n    /// Note that the capacity of `self` does not change.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `at` is not on a UTF-8 code point boundary, or if it is beyond the last\n    /// code point of the string.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut hello = String::from_str_in(\"Hello, World!\", &b);\n    /// let world = hello.split_off(7);\n    /// assert_eq!(hello, \"Hello, \");\n    /// assert_eq!(world, \"World!\");\n    /// ```\n    #[inline]\n    pub fn split_off(&mut self, at: usize) -> String<'bump> {\n        assert!(self.is_char_boundary(at));\n        let other = self.vec.split_off(at);\n        unsafe { String::from_utf8_unchecked(other) }\n    }\n\n    /// Truncates this `String`, removing all contents.\n    ///\n    /// While this means the `String` will have a length of zero, it does not\n    /// touch its capacity.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"foo\", &b);\n    ///\n    /// s.clear();\n    ///\n    /// assert!(s.is_empty());\n    /// assert_eq!(0, s.len());\n    /// assert_eq!(3, s.capacity());\n    /// ```\n    #[inline]\n    pub fn clear(&mut self) {\n        self.vec.clear()\n    }\n\n    /// Creates a draining iterator that removes the specified range in the `String`\n    /// and yields the removed `chars`.\n    ///\n    /// Note: The element range is removed even if the iterator is not\n    /// consumed until the end.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the starting point or end point do not lie on a [`char`]\n    /// boundary, or if they're out of bounds.\n    ///\n    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"α is alpha, β is beta\", &b);\n    /// let beta_offset = s.find('β').unwrap_or(s.len());\n    ///\n    /// // Remove the range up until the β from the string\n    /// let t = String::from_iter_in(s.drain(..beta_offset), &b);\n    /// assert_eq!(t, \"α is alpha, \");\n    /// assert_eq!(s, \"β is beta\");\n    ///\n    /// // A full range clears the string\n    /// drop(s.drain(..));\n    /// assert_eq!(s, \"\");\n    /// ```\n    pub fn drain<'a, R>(&'a mut self, range: R) -> Drain<'a, 'bump>\n    where\n        R: RangeBounds<usize>,\n    {\n        // Memory safety\n        //\n        // The String version of Drain does not have the memory safety issues\n        // of the vector version. The data is just plain bytes.\n        // Because the range removal happens in Drop, if the Drain iterator is leaked,\n        // the removal will not happen.\n        let len = self.len();\n        let start = match range.start_bound() {\n            Included(&n) => n,\n            Excluded(&n) => n + 1,\n            Unbounded => 0,\n        };\n        let end = match range.end_bound() {\n            Included(&n) => n + 1,\n            Excluded(&n) => n,\n            Unbounded => len,\n        };\n\n        // Take out two simultaneous borrows. The &mut String won't be accessed\n        // until iteration is over, in Drop.\n        let self_ptr = self as *mut _;\n        // slicing does the appropriate bounds checks\n        let chars_iter = self[start..end].chars();\n\n        Drain {\n            start,\n            end,\n            iter: chars_iter,\n            string: self_ptr,\n        }\n    }\n\n    /// Removes the specified range in the string,\n    /// and replaces it with the given string.\n    /// The given string doesn't need to be the same length as the range.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the starting point or end point do not lie on a [`char`]\n    /// boundary, or if they're out of bounds.\n    ///\n    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html\n    /// [`Vec::splice`]: ../vec/struct.Vec.html#method.splice\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut s = String::from_str_in(\"α is alpha, β is beta\", &b);\n    /// let beta_offset = s.find('β').unwrap_or(s.len());\n    ///\n    /// // Replace the range up until the β from the string\n    /// s.replace_range(..beta_offset, \"Α is capital alpha; \");\n    /// assert_eq!(s, \"Α is capital alpha; β is beta\");\n    /// ```\n    pub fn replace_range<R>(&mut self, range: R, replace_with: &str)\n    where\n        R: RangeBounds<usize>,\n    {\n        // Memory safety\n        //\n        // Replace_range does not have the memory safety issues of a vector Splice.\n        // of the vector version. The data is just plain bytes.\n\n        match range.start_bound() {\n            Included(&n) => assert!(self.is_char_boundary(n)),\n            Excluded(&n) => assert!(self.is_char_boundary(n + 1)),\n            Unbounded => {}\n        };\n        match range.end_bound() {\n            Included(&n) => assert!(self.is_char_boundary(n + 1)),\n            Excluded(&n) => assert!(self.is_char_boundary(n)),\n            Unbounded => {}\n        };\n\n        unsafe { self.as_mut_vec() }.splice(range, replace_with.bytes());\n    }\n}\n\nimpl<'bump> FromUtf8Error<'bump> {\n    /// Returns a slice of bytes that were attempted to convert to a `String`.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// // some invalid bytes, in a vector\n    /// let bytes = bumpalo::vec![in &b; 0, 159];\n    ///\n    /// let value = String::from_utf8(bytes);\n    ///\n    /// assert_eq!(&[0, 159], value.unwrap_err().as_bytes());\n    /// ```\n    pub fn as_bytes(&self) -> &[u8] {\n        &self.bytes[..]\n    }\n\n    /// Returns the bytes that were attempted to convert to a `String`.\n    ///\n    /// This method is carefully constructed to avoid allocation. It will\n    /// consume the error, moving out the bytes, so that a copy of the bytes\n    /// does not need to be made.\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// // some invalid bytes, in a vector\n    /// let bytes = bumpalo::vec![in &b; 0, 159];\n    ///\n    /// let value = String::from_utf8(bytes);\n    ///\n    /// assert_eq!(bumpalo::vec![in &b; 0, 159], value.unwrap_err().into_bytes());\n    /// ```\n    pub fn into_bytes(self) -> Vec<'bump, u8> {\n        self.bytes\n    }\n\n    /// Fetch a `Utf8Error` to get more details about the conversion failure.\n    ///\n    /// The [`Utf8Error`] type provided by [`std::str`] represents an error that may\n    /// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's\n    /// an analogue to `FromUtf8Error`. See its documentation for more details\n    /// on using it.\n    ///\n    /// [`Utf8Error`]: https://doc.rust-lang.org/std/str/struct.Utf8Error.html\n    /// [`std::str`]: https://doc.rust-lang.org/std/str/index.html\n    /// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html\n    /// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html\n    ///\n    /// # Examples\n    ///\n    /// Basic usage:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::String};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// // some invalid bytes, in a vector\n    /// let bytes = bumpalo::vec![in &b; 0, 159];\n    ///\n    /// let error = String::from_utf8(bytes).unwrap_err().utf8_error();\n    ///\n    /// // the first byte is invalid here\n    /// assert_eq!(1, error.valid_up_to());\n    /// ```\n    pub fn utf8_error(&self) -> Utf8Error {\n        self.error\n    }\n}\n\nimpl<'bump> fmt::Display for FromUtf8Error<'bump> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        fmt::Display::fmt(&self.error, f)\n    }\n}\n\nimpl fmt::Display for FromUtf16Error {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        fmt::Display::fmt(\"invalid utf-16: lone surrogate found\", f)\n    }\n}\n\nimpl<'bump> Clone for String<'bump> {\n    fn clone(&self) -> Self {\n        String {\n            vec: self.vec.clone(),\n        }\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        self.vec.clone_from(&source.vec);\n    }\n}\n\nimpl<'bump> Extend<char> for String<'bump> {\n    fn extend<I: IntoIterator<Item = char>>(&mut self, iter: I) {\n        let iterator = iter.into_iter();\n        let (lower_bound, _) = iterator.size_hint();\n        self.reserve(lower_bound);\n        for ch in iterator {\n            self.push(ch)\n        }\n    }\n}\n\nimpl<'a, 'bump> Extend<&'a char> for String<'bump> {\n    fn extend<I: IntoIterator<Item = &'a char>>(&mut self, iter: I) {\n        self.extend(iter.into_iter().cloned());\n    }\n}\n\nimpl<'a, 'bump> Extend<&'a str> for String<'bump> {\n    fn extend<I: IntoIterator<Item = &'a str>>(&mut self, iter: I) {\n        for s in iter {\n            self.push_str(s)\n        }\n    }\n}\n\nimpl<'bump> Extend<String<'bump>> for String<'bump> {\n    fn extend<I: IntoIterator<Item = String<'bump>>>(&mut self, iter: I) {\n        for s in iter {\n            self.push_str(&s)\n        }\n    }\n}\n\nimpl<'bump> Extend<core_alloc::string::String> for String<'bump> {\n    fn extend<I: IntoIterator<Item = core_alloc::string::String>>(&mut self, iter: I) {\n        for s in iter {\n            self.push_str(&s)\n        }\n    }\n}\n\nimpl<'a, 'bump> Extend<Cow<'a, str>> for String<'bump> {\n    fn extend<I: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: I) {\n        for s in iter {\n            self.push_str(&s)\n        }\n    }\n}\n\nimpl<'bump> PartialEq for String<'bump> {\n    #[inline]\n    fn eq(&self, other: &String) -> bool {\n        PartialEq::eq(&self[..], &other[..])\n    }\n}\n\nmacro_rules! impl_eq {\n    ($lhs:ty, $rhs: ty) => {\n        impl<'a, 'bump> PartialEq<$rhs> for $lhs {\n            #[inline]\n            fn eq(&self, other: &$rhs) -> bool {\n                PartialEq::eq(&self[..], &other[..])\n            }\n        }\n\n        impl<'a, 'b, 'bump> PartialEq<$lhs> for $rhs {\n            #[inline]\n            fn eq(&self, other: &$lhs) -> bool {\n                PartialEq::eq(&self[..], &other[..])\n            }\n        }\n    };\n}\n\nimpl_eq! { String<'bump>, str }\nimpl_eq! { String<'bump>, &'a str }\nimpl_eq! { Cow<'a, str>, String<'bump> }\nimpl_eq! { core_alloc::string::String, String<'bump> }\n\nimpl<'bump> fmt::Display for String<'bump> {\n    #[inline]\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        fmt::Display::fmt(&**self, f)\n    }\n}\n\nimpl<'bump> fmt::Debug for String<'bump> {\n    #[inline]\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        fmt::Debug::fmt(&**self, f)\n    }\n}\n\nimpl<'bump> hash::Hash for String<'bump> {\n    #[inline]\n    fn hash<H: hash::Hasher>(&self, hasher: &mut H) {\n        (**self).hash(hasher)\n    }\n}\n\n/// Implements the `+` operator for concatenating two strings.\n///\n/// This consumes the `String<'bump>` on the left-hand side and re-uses its buffer (growing it if\n/// necessary). This is done to avoid allocating a new `String<'bump>` and copying the entire contents on\n/// every operation, which would lead to `O(n^2)` running time when building an `n`-byte string by\n/// repeated concatenation.\n///\n/// The string on the right-hand side is only borrowed; its contents are copied into the returned\n/// `String<'bump>`.\n///\n/// # Examples\n///\n/// Concatenating two `String<'bump>`s takes the first by value and borrows the second:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let bump = Bump::new();\n///\n/// let a = String::from_str_in(\"hello\", &bump);\n/// let b = String::from_str_in(\" world\", &bump);\n/// let c = a + &b;\n/// // `a` is moved and can no longer be used here.\n/// ```\n///\n/// If you want to keep using the first `String`, you can clone it and append to the clone instead:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let bump = Bump::new();\n///\n/// let a = String::from_str_in(\"hello\", &bump);\n/// let b = String::from_str_in(\" world\", &bump);\n/// let c = a.clone() + &b;\n/// // `a` is still valid here.\n/// ```\n///\n/// Concatenating `&str` slices can be done by converting the first to a `String`:\n///\n/// ```\n/// use bumpalo::{Bump, collections::String};\n///\n/// let bump = Bump::new();\n///\n/// let a = \"hello\";\n/// let b = \" world\";\n/// let c = String::from_str_in(a, &bump) + b;\n/// ```\nimpl<'a, 'bump> Add<&'a str> for String<'bump> {\n    type Output = String<'bump>;\n\n    #[inline]\n    fn add(mut self, other: &str) -> String<'bump> {\n        self.push_str(other);\n        self\n    }\n}\n\n/// Implements the `+=` operator for appending to a `String<'bump>`.\n///\n/// This has the same behavior as the [`push_str`][String::push_str] method.\nimpl<'a, 'bump> AddAssign<&'a str> for String<'bump> {\n    #[inline]\n    fn add_assign(&mut self, other: &str) {\n        self.push_str(other);\n    }\n}\n\nimpl<'bump> ops::Index<ops::Range<usize>> for String<'bump> {\n    type Output = str;\n\n    #[inline]\n    fn index(&self, index: ops::Range<usize>) -> &str {\n        &self[..][index]\n    }\n}\nimpl<'bump> ops::Index<ops::RangeTo<usize>> for String<'bump> {\n    type Output = str;\n\n    #[inline]\n    fn index(&self, index: ops::RangeTo<usize>) -> &str {\n        &self[..][index]\n    }\n}\nimpl<'bump> ops::Index<ops::RangeFrom<usize>> for String<'bump> {\n    type Output = str;\n\n    #[inline]\n    fn index(&self, index: ops::RangeFrom<usize>) -> &str {\n        &self[..][index]\n    }\n}\nimpl<'bump> ops::Index<ops::RangeFull> for String<'bump> {\n    type Output = str;\n\n    #[inline]\n    fn index(&self, _index: ops::RangeFull) -> &str {\n        unsafe { str::from_utf8_unchecked(&self.vec) }\n    }\n}\nimpl<'bump> ops::Index<ops::RangeInclusive<usize>> for String<'bump> {\n    type Output = str;\n\n    #[inline]\n    fn index(&self, index: ops::RangeInclusive<usize>) -> &str {\n        Index::index(&**self, index)\n    }\n}\nimpl<'bump> ops::Index<ops::RangeToInclusive<usize>> for String<'bump> {\n    type Output = str;\n\n    #[inline]\n    fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {\n        Index::index(&**self, index)\n    }\n}\n\nimpl<'bump> ops::IndexMut<ops::Range<usize>> for String<'bump> {\n    #[inline]\n    fn index_mut(&mut self, index: ops::Range<usize>) -> &mut str {\n        &mut self[..][index]\n    }\n}\nimpl<'bump> ops::IndexMut<ops::RangeTo<usize>> for String<'bump> {\n    #[inline]\n    fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut str {\n        &mut self[..][index]\n    }\n}\nimpl<'bump> ops::IndexMut<ops::RangeFrom<usize>> for String<'bump> {\n    #[inline]\n    fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str {\n        &mut self[..][index]\n    }\n}\nimpl<'bump> ops::IndexMut<ops::RangeFull> for String<'bump> {\n    #[inline]\n    fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str {\n        unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }\n    }\n}\nimpl<'bump> ops::IndexMut<ops::RangeInclusive<usize>> for String<'bump> {\n    #[inline]\n    fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {\n        IndexMut::index_mut(&mut **self, index)\n    }\n}\nimpl<'bump> ops::IndexMut<ops::RangeToInclusive<usize>> for String<'bump> {\n    #[inline]\n    fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {\n        IndexMut::index_mut(&mut **self, index)\n    }\n}\n\nimpl<'bump> ops::Deref for String<'bump> {\n    type Target = str;\n\n    #[inline]\n    fn deref(&self) -> &str {\n        unsafe { str::from_utf8_unchecked(&self.vec) }\n    }\n}\n\nimpl<'bump> ops::DerefMut for String<'bump> {\n    #[inline]\n    fn deref_mut(&mut self) -> &mut str {\n        unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }\n    }\n}\n\nimpl<'bump> AsRef<str> for String<'bump> {\n    #[inline]\n    fn as_ref(&self) -> &str {\n        self\n    }\n}\n\nimpl<'bump> AsRef<[u8]> for String<'bump> {\n    #[inline]\n    fn as_ref(&self) -> &[u8] {\n        self.as_bytes()\n    }\n}\n\nimpl<'bump> fmt::Write for String<'bump> {\n    #[inline]\n    fn write_str(&mut self, s: &str) -> fmt::Result {\n        self.push_str(s);\n        Ok(())\n    }\n\n    #[inline]\n    fn write_char(&mut self, c: char) -> fmt::Result {\n        self.push(c);\n        Ok(())\n    }\n}\n\nimpl<'bump> Borrow<str> for String<'bump> {\n    #[inline]\n    fn borrow(&self) -> &str {\n        &self[..]\n    }\n}\n\nimpl<'bump> BorrowMut<str> for String<'bump> {\n    #[inline]\n    fn borrow_mut(&mut self) -> &mut str {\n        &mut self[..]\n    }\n}\n\n/// A draining iterator for `String`.\n///\n/// This struct is created by the [`String::drain`] method. See its\n/// documentation for more information.\npub struct Drain<'a, 'bump> {\n    /// Will be used as &'a mut String in the destructor\n    string: *mut String<'bump>,\n    /// Start of part to remove\n    start: usize,\n    /// End of part to remove\n    end: usize,\n    /// Current remaining range to remove\n    iter: Chars<'a>,\n}\n\nimpl<'a, 'bump> fmt::Debug for Drain<'a, 'bump> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.pad(\"Drain { .. }\")\n    }\n}\n\nunsafe impl<'a, 'bump> Sync for Drain<'a, 'bump> {}\nunsafe impl<'a, 'bump> Send for Drain<'a, 'bump> {}\n\nimpl<'a, 'bump> Drop for Drain<'a, 'bump> {\n    fn drop(&mut self) {\n        unsafe {\n            // Use Vec::drain. \"Reaffirm\" the bounds checks to avoid\n            // panic code being inserted again.\n            let self_vec = (*self.string).as_mut_vec();\n            if self.start <= self.end && self.end <= self_vec.len() {\n                self_vec.drain(self.start..self.end);\n            }\n        }\n    }\n}\n\n// TODO: implement `AsRef<str/[u8]>` and `as_str`\n\nimpl<'a, 'bump> Iterator for Drain<'a, 'bump> {\n    type Item = char;\n\n    #[inline]\n    fn next(&mut self) -> Option<char> {\n        self.iter.next()\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.iter.size_hint()\n    }\n}\n\nimpl<'a, 'bump> DoubleEndedIterator for Drain<'a, 'bump> {\n    #[inline]\n    fn next_back(&mut self) -> Option<char> {\n        self.iter.next_back()\n    }\n}\n\nimpl<'a, 'bump> FusedIterator for Drain<'a, 'bump> {}\n\n#[cfg(feature = \"serde\")]\nmod serialize {\n    use super::*;\n\n    use serde::{Serialize, Serializer};\n\n    impl<'bump> Serialize for String<'bump> {\n        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n        where\n            S: Serializer,\n        {\n            serializer.serialize_str(&self)\n        }\n    }\n}\n"
    },
    {
      "package": "bumpalo@3.20.3",
      "sourcePath": "src/collections/vec.rs",
      "sha256": "ebb91c051e92c00c192c7b25eea9a5961ff9895a4fe195b29a2d71d0422b4a8c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n//! A contiguous growable array type with heap-allocated contents, written\n//! [`Vec<'bump, T>`].\n//!\n//! Vectors have `O(1)` indexing, amortized `O(1)` push (to the end) and\n//! `O(1)` pop (from the end).\n//!\n//! This module is a fork of the [`std::vec`] module, that uses a bump allocator.\n//!\n//! [`std::vec`]: https://doc.rust-lang.org/std/vec/index.html\n//!\n//! # Examples\n//!\n//! You can explicitly create a [`Vec<'bump, T>`] with [`new_in`]:\n//!\n//! ```\n//! use bumpalo::{Bump, collections::Vec};\n//!\n//! let b = Bump::new();\n//! let v: Vec<i32> = Vec::new_in(&b);\n//! ```\n//!\n//! ... or by using the [`vec!`] macro:\n//!\n//! ```\n//! use bumpalo::{Bump, collections::Vec};\n//!\n//! let b = Bump::new();\n//!\n//! let v: Vec<i32> = bumpalo::vec![in &b];\n//!\n//! let v = bumpalo::vec![in &b; 1, 2, 3, 4, 5];\n//!\n//! let v = bumpalo::vec![in &b; 0; 10]; // ten zeroes\n//! ```\n//!\n//! You can [`push`] values onto the end of a vector (which will grow the vector\n//! as needed):\n//!\n//! ```\n//! use bumpalo::{Bump, collections::Vec};\n//!\n//! let b = Bump::new();\n//!\n//! let mut v = bumpalo::vec![in &b; 1, 2];\n//!\n//! v.push(3);\n//! ```\n//!\n//! Popping values works in much the same way:\n//!\n//! ```\n//! use bumpalo::{Bump, collections::Vec};\n//!\n//! let b = Bump::new();\n//!\n//! let mut v = bumpalo::vec![in &b; 1, 2];\n//!\n//! assert_eq!(v.pop(), Some(2));\n//! ```\n//!\n//! Vectors also support indexing (through the [`Index`] and [`IndexMut`] traits):\n//!\n//! ```\n//! use bumpalo::{Bump, collections::Vec};\n//!\n//! let b = Bump::new();\n//!\n//! let mut v = bumpalo::vec![in &b; 1, 2, 3];\n//! assert_eq!(v[2], 3);\n//! v[1] += 5;\n//! assert_eq!(v, [1, 7, 3]);\n//! ```\n//!\n//! [`Vec<'bump, T>`]: struct.Vec.html\n//! [`new_in`]: struct.Vec.html#method.new_in\n//! [`push`]: struct.Vec.html#method.push\n//! [`Index`]: https://doc.rust-lang.org/std/ops/trait.Index.html\n//! [`IndexMut`]: https://doc.rust-lang.org/std/ops/trait.IndexMut.html\n//! [`vec!`]: ../../macro.vec.html\n\nuse super::raw_vec::RawVec;\nuse crate::collections::CollectionAllocErr;\nuse crate::Bump;\nuse core::borrow::{Borrow, BorrowMut};\nuse core::cmp::Ordering;\nuse core::fmt;\nuse core::hash::{self, Hash};\nuse core::iter::FusedIterator;\nuse core::marker::PhantomData;\nuse core::mem;\nuse core::ops;\nuse core::ops::Bound::{Excluded, Included, Unbounded};\nuse core::ops::{Index, IndexMut, RangeBounds};\nuse core::ptr;\nuse core::ptr::NonNull;\nuse core::slice;\n#[cfg(feature = \"std\")]\nuse std::io;\n\nunsafe fn arith_offset<T>(p: *const T, offset: isize) -> *const T {\n    p.offset(offset)\n}\n\nfn partition_dedup_by<T, F>(s: &mut [T], mut same_bucket: F) -> (&mut [T], &mut [T])\nwhere\n    F: FnMut(&mut T, &mut T) -> bool,\n{\n    // Although we have a mutable reference to `s`, we cannot make\n    // *arbitrary* changes. The `same_bucket` calls could panic, so we\n    // must ensure that the slice is in a valid state at all times.\n    //\n    // The way that we handle this is by using swaps; we iterate\n    // over all the elements, swapping as we go so that at the end\n    // the elements we wish to keep are in the front, and those we\n    // wish to reject are at the back. We can then split the slice.\n    // This operation is still O(n).\n    //\n    // Example: We start in this state, where `r` represents \"next\n    // read\" and `w` represents \"next_write`.\n    //\n    //           r\n    //     +---+---+---+---+---+---+\n    //     | 0 | 1 | 1 | 2 | 3 | 3 |\n    //     +---+---+---+---+---+---+\n    //           w\n    //\n    // Comparing s[r] against s[w-1], this is not a duplicate, so\n    // we swap s[r] and s[w] (no effect as r==w) and then increment both\n    // r and w, leaving us with:\n    //\n    //               r\n    //     +---+---+---+---+---+---+\n    //     | 0 | 1 | 1 | 2 | 3 | 3 |\n    //     +---+---+---+---+---+---+\n    //               w\n    //\n    // Comparing s[r] against s[w-1], this value is a duplicate,\n    // so we increment `r` but leave everything else unchanged:\n    //\n    //                   r\n    //     +---+---+---+---+---+---+\n    //     | 0 | 1 | 1 | 2 | 3 | 3 |\n    //     +---+---+---+---+---+---+\n    //               w\n    //\n    // Comparing s[r] against s[w-1], this is not a duplicate,\n    // so swap s[r] and s[w] and advance r and w:\n    //\n    //                       r\n    //     +---+---+---+---+---+---+\n    //     | 0 | 1 | 2 | 1 | 3 | 3 |\n    //     +---+---+---+---+---+---+\n    //                   w\n    //\n    // Not a duplicate, repeat:\n    //\n    //                           r\n    //     +---+---+---+---+---+---+\n    //     | 0 | 1 | 2 | 3 | 1 | 3 |\n    //     +---+---+---+---+---+---+\n    //                       w\n    //\n    // Duplicate, advance r. End of slice. Split at w.\n\n    let len = s.len();\n    if len <= 1 {\n        return (s, &mut []);\n    }\n\n    let ptr = s.as_mut_ptr();\n    let mut next_read: usize = 1;\n    let mut next_write: usize = 1;\n\n    unsafe {\n        // Avoid bounds checks by using raw pointers.\n        while next_read < len {\n            let ptr_read = ptr.add(next_read);\n            let prev_ptr_write = ptr.add(next_write - 1);\n            if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) {\n                if next_read != next_write {\n                    let ptr_write = prev_ptr_write.offset(1);\n                    mem::swap(&mut *ptr_read, &mut *ptr_write);\n                }\n                next_write += 1;\n            }\n            next_read += 1;\n        }\n    }\n\n    s.split_at_mut(next_write)\n}\n\nunsafe fn offset_from<T>(p: *const T, origin: *const T) -> isize\nwhere\n    T: Sized,\n{\n    let pointee_size = mem::size_of::<T>();\n    assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);\n\n    // This is the same sequence that Clang emits for pointer subtraction.\n    // It can be neither `nsw` nor `nuw` because the input is treated as\n    // unsigned but then the output is treated as signed, so neither works.\n    let d = isize::wrapping_sub(p as _, origin as _);\n    d / (pointee_size as isize)\n}\n\n/// Creates a [`Vec`] containing the arguments.\n///\n/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.\n/// There are two forms of this macro:\n///\n/// - Create a [`Vec`] containing a given list of elements:\n///\n/// ```\n/// use bumpalo::Bump;\n///\n/// let b = Bump::new();\n/// let v = bumpalo::vec![in &b; 1, 2, 3];\n/// assert_eq!(v, [1, 2, 3]);\n/// ```\n///\n/// - Create a [`Vec`] from a given element and size:\n///\n/// ```\n/// use bumpalo::Bump;\n///\n/// let b = Bump::new();\n/// let v = bumpalo::vec![in &b; 1; 3];\n/// assert_eq!(v, [1, 1, 1]);\n/// ```\n///\n/// Note that unlike array expressions, this syntax supports all elements\n/// which implement [`Clone`] and the number of elements doesn't have to be\n/// a constant.\n///\n/// This will use `clone` to duplicate an expression, so one should be careful\n/// using this with types having a non-standard `Clone` implementation. For\n/// example, `bumpalo::vec![in &bump; Rc::new(1); 5]` will create a vector of five references\n/// to the same boxed integer value, not five references pointing to independently\n/// boxed integers.\n///\n/// [`Vec`]: collections/vec/struct.Vec.html\n/// [`Clone`]: https://doc.rust-lang.org/std/clone/trait.Clone.html\n#[macro_export]\nmacro_rules! vec {\n    (in $bump:expr; $elem:expr; $n:expr) => {{\n        let n = $n;\n        let mut v = $crate::collections::Vec::with_capacity_in(n, $bump);\n        if n > 0 {\n            let elem = $elem;\n            for _ in 0..n - 1 {\n                v.push(elem.clone());\n            }\n            v.push(elem);\n        }\n        v\n    }};\n    (in $bump:expr) => { $crate::collections::Vec::new_in($bump) };\n    (in $bump:expr; $($x:expr),*) => {{\n        let mut v = $crate::collections::Vec::new_in($bump);\n        $( v.push($x); )*\n        v\n    }};\n    (in $bump:expr; $($x:expr,)*) => (bumpalo::vec![in $bump; $($x),*])\n}\n\n/// A contiguous growable array type, written `Vec<'bump, T>` but pronounced 'vector'.\n///\n/// # Examples\n///\n/// ```\n/// use bumpalo::{Bump, collections::Vec};\n///\n/// let b = Bump::new();\n///\n/// let mut vec = Vec::new_in(&b);\n/// vec.push(1);\n/// vec.push(2);\n///\n/// assert_eq!(vec.len(), 2);\n/// assert_eq!(vec[0], 1);\n///\n/// assert_eq!(vec.pop(), Some(2));\n/// assert_eq!(vec.len(), 1);\n///\n/// vec[0] = 7;\n/// assert_eq!(vec[0], 7);\n///\n/// vec.extend([1, 2, 3].iter().cloned());\n///\n/// for x in &vec {\n///     println!(\"{}\", x);\n/// }\n/// assert_eq!(vec, [7, 1, 2, 3]);\n/// ```\n///\n/// The [`vec!`] macro is provided to make initialization more convenient:\n///\n/// ```\n/// use bumpalo::{Bump, collections::Vec};\n///\n/// let b = Bump::new();\n///\n/// let mut vec = bumpalo::vec![in &b; 1, 2, 3];\n/// vec.push(4);\n/// assert_eq!(vec, [1, 2, 3, 4]);\n/// ```\n///\n/// It can also initialize each element of a `Vec<'bump, T>` with a given value.\n/// This may be more efficient than performing allocation and initialization\n/// in separate steps, especially when initializing a vector of zeros:\n///\n/// ```\n/// use bumpalo::{Bump, collections::Vec};\n///\n/// let b = Bump::new();\n///\n/// let vec = bumpalo::vec![in &b; 0; 5];\n/// assert_eq!(vec, [0, 0, 0, 0, 0]);\n///\n/// // The following is equivalent, but potentially slower:\n/// let mut vec1 = Vec::with_capacity_in(5, &b);\n/// vec1.resize(5, 0);\n/// ```\n///\n/// Use a `Vec<'bump, T>` as an efficient stack:\n///\n/// ```\n/// use bumpalo::{Bump, collections::Vec};\n///\n/// let b = Bump::new();\n///\n/// let mut stack = Vec::new_in(&b);\n///\n/// stack.push(1);\n/// stack.push(2);\n/// stack.push(3);\n///\n/// while let Some(top) = stack.pop() {\n///     // Prints 3, 2, 1\n///     println!(\"{}\", top);\n/// }\n/// ```\n///\n/// # Indexing\n///\n/// The `Vec` type allows to access values by index, because it implements the\n/// [`Index`] trait. An example will be more explicit:\n///\n/// ```\n/// use bumpalo::{Bump, collections::Vec};\n///\n/// let b = Bump::new();\n///\n/// let v = bumpalo::vec![in &b; 0, 2, 4, 6];\n/// println!(\"{}\", v[1]); // it will display '2'\n/// ```\n///\n/// However be careful: if you try to access an index which isn't in the `Vec`,\n/// your software will panic! You cannot do this:\n///\n/// ```should_panic\n/// use bumpalo::{Bump, collections::Vec};\n///\n/// let b = Bump::new();\n///\n/// let v = bumpalo::vec![in &b; 0, 2, 4, 6];\n/// println!(\"{}\", v[6]); // it will panic!\n/// ```\n///\n/// In conclusion: always check if the index you want to get really exists\n/// before doing it.\n///\n/// # Slicing\n///\n/// A `Vec` can be mutable. Slices, on the other hand, are read-only objects.\n/// To get a slice, use `&`. Example:\n///\n/// ```\n/// use bumpalo::{Bump, collections::Vec};\n///\n/// fn read_slice(slice: &[usize]) {\n///     // ...\n/// }\n///\n/// let b = Bump::new();\n///\n/// let v = bumpalo::vec![in &b; 0, 1];\n/// read_slice(&v);\n///\n/// // ... and that's all!\n/// // you can also do it like this:\n/// let x : &[usize] = &v;\n/// ```\n///\n/// In Rust, it's more common to pass slices as arguments rather than vectors\n/// when you just want to provide a read access. The same goes for [`String`] and\n/// [`&str`].\n///\n/// # Capacity and reallocation\n///\n/// The capacity of a vector is the amount of space allocated for any future\n/// elements that will be added onto the vector. This is not to be confused with\n/// the *length* of a vector, which specifies the number of actual elements\n/// within the vector. If a vector's length exceeds its capacity, its capacity\n/// will automatically be increased, but its elements will have to be\n/// reallocated.\n///\n/// For example, a vector with capacity 10 and length 0 would be an empty vector\n/// with space for 10 more elements. Pushing 10 or fewer elements onto the\n/// vector will not change its capacity or cause reallocation to occur. However,\n/// if the vector's length is increased to 11, it will have to reallocate, which\n/// can be slow. For this reason, it is recommended to use [`Vec::with_capacity_in`]\n/// whenever possible to specify how big the vector is expected to get.\n///\n/// # Guarantees\n///\n/// Due to its incredibly fundamental nature, `Vec` makes a lot of guarantees\n/// about its design. This ensures that it's as low-overhead as possible in\n/// the general case, and can be correctly manipulated in primitive ways\n/// by unsafe code. Note that these guarantees refer to an unqualified `Vec<'bump, T>`.\n/// If additional type parameters are added (e.g. to support custom allocators),\n/// overriding their defaults may change the behavior.\n///\n/// Most fundamentally, `Vec` is and always will be a (pointer, capacity, length)\n/// triplet. No more, no less. The order of these fields is completely\n/// unspecified, and you should use the appropriate methods to modify these.\n/// The pointer will never be null, so this type is null-pointer-optimized.\n///\n/// However, the pointer may not actually point to allocated memory. In particular,\n/// if you construct a `Vec` with capacity 0 via [`Vec::new_in`], [`bumpalo::vec![in bump]`][`vec!`],\n/// [`Vec::with_capacity_in(0)`][`Vec::with_capacity_in`], or by calling [`shrink_to_fit`]\n/// on an empty Vec, it will not allocate memory. Similarly, if you store zero-sized\n/// types inside a `Vec`, it will not allocate space for them. *Note that in this case\n/// the `Vec` may not report a [`capacity`] of 0*. `Vec` will allocate if and only\n/// if <code>[`mem::size_of::<T>`]\\() * capacity() > 0</code>. In general, `Vec`'s allocation\n/// details are very subtle &mdash; if you intend to allocate memory using a `Vec`\n/// and use it for something else (either to pass to unsafe code, or to build your\n/// own memory-backed collection), be sure to deallocate this memory by using\n/// `from_raw_parts` to recover the `Vec` and then dropping it.\n///\n/// If a `Vec` *has* allocated memory, then the memory it points to is\n/// in the [`Bump`] arena used to construct it, and its\n/// pointer points to [`len`] initialized, contiguous elements in order (what\n/// you would see if you coerced it to a slice), followed by <code>[`capacity`] -\n/// [`len`]</code> logically uninitialized, contiguous elements.\n///\n/// `Vec` will never perform a \"small optimization\" where elements are actually\n/// stored on the stack for two reasons:\n///\n/// * It would make it more difficult for unsafe code to correctly manipulate\n///   a `Vec`. The contents of a `Vec` wouldn't have a stable address if it were\n///   only moved, and it would be more difficult to determine if a `Vec` had\n///   actually allocated memory.\n///\n/// * It would penalize the general case, incurring an additional branch\n///   on every access.\n///\n/// `Vec` will never automatically shrink itself, even if completely empty. This\n/// ensures no unnecessary allocations or deallocations occur. Emptying a `Vec`\n/// and then filling it back up to the same [`len`] should incur no calls to\n/// the allocator. If you wish to free up unused memory, use\n/// [`shrink_to_fit`][`shrink_to_fit`].\n///\n/// [`push`] and [`insert`] will never (re)allocate if the reported capacity is\n/// sufficient. [`push`] and [`insert`] *will* (re)allocate if\n/// <code>[`len`] == [`capacity`]</code>. That is, the reported capacity is completely\n/// accurate, and can be relied on. It can even be used to manually free the memory\n/// allocated by a `Vec` if desired. Bulk insertion methods *may* reallocate, even\n/// when not necessary.\n///\n/// `Vec` does not guarantee any particular growth strategy when reallocating\n/// when full, nor when [`reserve`] is called. The current strategy is basic\n/// and it may prove desirable to use a non-constant growth factor. Whatever\n/// strategy is used will of course guarantee `O(1)` amortized [`push`].\n///\n/// `bumpalo::vec![in bump; x; n]`, `bumpalo::vec![in bump; a, b, c, d]`, and\n/// [`Vec::with_capacity_in(n)`][`Vec::with_capacity_in`], will all produce a\n/// `Vec` with exactly the requested capacity. If <code>[`len`] == [`capacity`]</code>, (as\n/// is the case for the [`vec!`] macro), then a `Vec<'bump, T>` can be converted\n/// to and from a [`Box<[T]>`][owned slice] without reallocating or moving the\n/// elements.\n///\n/// `Vec` will not specifically overwrite any data that is removed from it,\n/// but also won't specifically preserve it. Its uninitialized memory is\n/// scratch space that it may use however it wants. It will generally just do\n/// whatever is most efficient or otherwise easy to implement. Do not rely on\n/// removed data to be erased for security purposes. Even if you drop a `Vec`, its\n/// buffer may simply be reused by another `Vec`. Even if you zero a `Vec`'s memory\n/// first, that may not actually happen because the optimizer does not consider\n/// this a side-effect that must be preserved. There is one case which we will\n/// not break, however: using `unsafe` code to write to the excess capacity,\n/// and then increasing the length to match, is always valid.\n///\n/// `Vec` does not currently guarantee the order in which elements are dropped.\n/// The order has changed in the past and may change again.\n///\n/// [`vec!`]: ../../macro.vec.html\n/// [`Index`]: https://doc.rust-lang.org/std/ops/trait.Index.html\n/// [`String`]: ../string/struct.String.html\n/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html\n/// [`Vec::with_capacity_in`]: struct.Vec.html#method.with_capacity_in\n/// [`Vec::new_in`]: struct.Vec.html#method.new_in\n/// [`shrink_to_fit`]: struct.Vec.html#method.shrink_to_fit\n/// [`capacity`]: struct.Vec.html#method.capacity\n/// [`mem::size_of::<T>`]: https://doc.rust-lang.org/std/mem/fn.size_of.html\n/// [`len`]: struct.Vec.html#method.len\n/// [`push`]: struct.Vec.html#method.push\n/// [`insert`]: struct.Vec.html#method.insert\n/// [`reserve`]: struct.Vec.html#method.reserve\n/// [owned slice]: https://doc.rust-lang.org/std/boxed/struct.Box.html\npub struct Vec<'bump, T: 'bump> {\n    buf: RawVec<'bump, T>,\n    len: usize,\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Inherent methods\n////////////////////////////////////////////////////////////////////////////////\n\nimpl<'bump, T: 'bump> Vec<'bump, T> {\n    /// Constructs a new, empty `Vec<'bump, T>`.\n    ///\n    /// The vector will not allocate until elements are pushed onto it.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unused_mut)]\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    /// let mut vec: Vec<i32> = Vec::new_in(&b);\n    /// ```\n    #[inline]\n    pub fn new_in(bump: &'bump Bump) -> Vec<'bump, T> {\n        Vec {\n            buf: RawVec::new_in(bump),\n            len: 0,\n        }\n    }\n\n    /// Constructs a new, empty `Vec<'bump, T>` with the specified capacity.\n    ///\n    /// The vector will be able to hold exactly `capacity` elements without\n    /// reallocating. If `capacity` is 0, the vector will not allocate.\n    ///\n    /// It is important to note that although the returned vector has the\n    /// *capacity* specified, the vector will have a zero *length*. For an\n    /// explanation of the difference between length and capacity, see\n    /// *[Capacity and reallocation]*.\n    ///\n    /// [Capacity and reallocation]: #capacity-and-reallocation\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = Vec::with_capacity_in(10, &b);\n    ///\n    /// // The vector contains no items, even though it has capacity for more\n    /// assert_eq!(vec.len(), 0);\n    ///\n    /// // These are all done without reallocating...\n    /// for i in 0..10 {\n    ///     vec.push(i);\n    /// }\n    ///\n    /// // ...but this may make the vector reallocate\n    /// vec.push(11);\n    /// ```\n    #[inline]\n    pub fn with_capacity_in(capacity: usize, bump: &'bump Bump) -> Vec<'bump, T> {\n        Vec {\n            buf: RawVec::with_capacity_in(capacity, bump),\n            len: 0,\n        }\n    }\n\n    /// Construct a new `Vec` from the given iterator's items.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    /// use std::iter;\n    ///\n    /// let b = Bump::new();\n    /// let v = Vec::from_iter_in(iter::repeat(7).take(3), &b);\n    /// assert_eq!(v, [7, 7, 7]);\n    /// ```\n    pub fn from_iter_in<I: IntoIterator<Item = T>>(iter: I, bump: &'bump Bump) -> Vec<'bump, T> {\n        let mut v = Vec::new_in(bump);\n        v.extend(iter);\n        v\n    }\n\n    /// Creates a `Vec<'bump, T>` directly from the raw components of another vector.\n    ///\n    /// # Safety\n    ///\n    /// This is highly unsafe, due to the number of invariants that aren't\n    /// checked:\n    ///\n    /// * `ptr` needs to have been previously allocated via [`String`]/`Vec<'bump, T>`\n    ///   (at least, it's highly likely to be incorrect if it wasn't).\n    /// * `ptr`'s `T` needs to have the same size and alignment as it was allocated with.\n    /// * `length` needs to be less than or equal to `capacity`.\n    /// * `capacity` needs to be the capacity that the pointer was allocated with.\n    ///\n    /// Violating these may cause problems like corrupting the allocator's\n    /// internal data structures. For example it is **not** safe\n    /// to build a `Vec<u8>` from a pointer to a C `char` array and a `size_t`.\n    ///\n    /// The ownership of `ptr` is effectively transferred to the\n    /// `Vec<'bump, T>` which may then deallocate, reallocate or change the\n    /// contents of memory pointed to by the pointer at will. Ensure\n    /// that nothing else uses the pointer after calling this\n    /// function.\n    ///\n    /// [`String`]: ../string/struct.String.html\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// use std::ptr;\n    /// use std::mem;\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut v = bumpalo::vec![in &b; 1, 2, 3];\n    ///\n    /// // Pull out the various important pieces of information about `v`\n    /// let p = v.as_mut_ptr();\n    /// let len = v.len();\n    /// let cap = v.capacity();\n    ///\n    /// unsafe {\n    ///     // Cast `v` into the void: no destructor run, so we are in\n    ///     // complete control of the allocation to which `p` points.\n    ///     mem::forget(v);\n    ///\n    ///     // Overwrite memory with 4, 5, 6\n    ///     for i in 0..len as isize {\n    ///         ptr::write(p.offset(i), 4 + i);\n    ///     }\n    ///\n    ///     // Put everything back together into a Vec\n    ///     let rebuilt = Vec::from_raw_parts_in(p, len, cap, &b);\n    ///     assert_eq!(rebuilt, [4, 5, 6]);\n    /// }\n    /// ```\n    pub unsafe fn from_raw_parts_in(\n        ptr: *mut T,\n        length: usize,\n        capacity: usize,\n        bump: &'bump Bump,\n    ) -> Vec<'bump, T> {\n        Vec {\n            buf: RawVec::from_raw_parts_in(ptr, capacity, bump),\n            len: length,\n        }\n    }\n\n    /// Returns a shared reference to the allocator backing this `Vec`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// // uses the same allocator as the provided `Vec`\n    /// fn add_strings<'bump>(vec: &mut Vec<'bump, &'bump str>) {\n    ///     for string in [\"foo\", \"bar\", \"baz\"] {\n    ///         vec.push(vec.bump().alloc_str(string));\n    ///     }\n    /// }\n    /// ```\n    #[inline]\n    #[must_use]\n    pub fn bump(&self) -> &'bump Bump {\n        self.buf.bump()\n    }\n\n    /// Returns the number of elements the vector can hold without\n    /// reallocating.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    /// let vec: Vec<i32> = Vec::with_capacity_in(10, &b);\n    /// assert_eq!(vec.capacity(), 10);\n    /// ```\n    #[inline]\n    pub fn capacity(&self) -> usize {\n        self.buf.cap()\n    }\n\n    /// Reserves capacity for at least `additional` more elements to be inserted\n    /// in the given `Vec<'bump, T>`. The collection may reserve more space to avoid\n    /// frequent reallocations. After calling `reserve`, capacity will be\n    /// greater than or equal to `self.len() + additional`. Does nothing if\n    /// capacity is already sufficient.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the new capacity overflows `usize`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    /// let mut vec = bumpalo::vec![in &b; 1];\n    /// vec.reserve(10);\n    /// assert!(vec.capacity() >= 11);\n    /// ```\n    pub fn reserve(&mut self, additional: usize) {\n        self.buf.reserve(self.len, additional);\n    }\n\n    /// Reserves the minimum capacity for exactly `additional` more elements to\n    /// be inserted in the given `Vec<'bump, T>`. After calling `reserve_exact`,\n    /// capacity will be greater than or equal to `self.len() + additional`.\n    /// Does nothing if the capacity is already sufficient.\n    ///\n    /// Note that the allocator may give the collection more space than it\n    /// requests. Therefore capacity can not be relied upon to be precisely\n    /// minimal. Prefer `reserve` if future insertions are expected.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the new capacity overflows `usize`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    /// let mut vec = bumpalo::vec![in &b; 1];\n    /// vec.reserve_exact(10);\n    /// assert!(vec.capacity() >= 11);\n    /// ```\n    pub fn reserve_exact(&mut self, additional: usize) {\n        self.buf.reserve_exact(self.len, additional);\n    }\n\n    /// Attempts to reserve capacity for at least `additional` more elements to be inserted\n    /// in the given `Vec<'bump, T>`. The collection may reserve more space to avoid\n    /// frequent reallocations. After calling `try_reserve`, capacity will be\n    /// greater than or equal to `self.len() + additional`. Does nothing if\n    /// capacity is already sufficient.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the new capacity overflows `usize`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    /// let mut vec = bumpalo::vec![in &b; 1];\n    /// vec.try_reserve(10).unwrap();\n    /// assert!(vec.capacity() >= 11);\n    /// ```\n    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {\n        self.buf.try_reserve(self.len, additional)\n    }\n\n    /// Attempts to reserve the minimum capacity for exactly `additional` more elements to\n    /// be inserted in the given `Vec<'bump, T>`. After calling `try_reserve_exact`,\n    /// capacity will be greater than or equal to `self.len() + additional`.\n    /// Does nothing if the capacity is already sufficient.\n    ///\n    /// Note that the allocator may give the collection more space than it\n    /// requests. Therefore capacity can not be relied upon to be precisely\n    /// minimal. Prefer `try_reserve` if future insertions are expected.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the new capacity overflows `usize`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    /// let mut vec = bumpalo::vec![in &b; 1];\n    /// vec.try_reserve_exact(10).unwrap();\n    /// assert!(vec.capacity() >= 11);\n    /// ```\n    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {\n        self.buf.try_reserve_exact(self.len, additional)\n    }\n\n    /// Shrinks the capacity of the vector as much as possible.\n    ///\n    /// It will drop down as close as possible to the length but the allocator\n    /// may still inform the vector that there is space for a few more elements.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = Vec::with_capacity_in(10, &b);\n    /// vec.extend([1, 2, 3].iter().cloned());\n    /// assert_eq!(vec.capacity(), 10);\n    /// vec.shrink_to_fit();\n    /// assert!(vec.capacity() >= 3);\n    /// ```\n    pub fn shrink_to_fit(&mut self) {\n        if self.capacity() != self.len {\n            self.buf.shrink_to_fit(self.len);\n        }\n    }\n\n    /// Converts the vector into `&'bump [T]`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    /// let v = bumpalo::vec![in &b; 1, 2, 3];\n    ///\n    /// let slice = v.into_bump_slice();\n    /// assert_eq!(slice, [1, 2, 3]);\n    /// ```\n    pub fn into_bump_slice(self) -> &'bump [T] {\n        unsafe {\n            let ptr = self.as_ptr();\n            let len = self.len();\n            mem::forget(self);\n            slice::from_raw_parts(ptr, len)\n        }\n    }\n\n    /// Converts the vector into `&'bump mut [T]`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    /// let v = bumpalo::vec![in &b; 1, 2, 3];\n    ///\n    /// let mut slice = v.into_bump_slice_mut();\n    ///\n    /// slice[0] = 3;\n    /// slice[2] = 1;\n    ///\n    /// assert_eq!(slice, [3, 2, 1]);\n    /// ```\n    pub fn into_bump_slice_mut(mut self) -> &'bump mut [T] {\n        let ptr = self.as_mut_ptr();\n        let len = self.len();\n        mem::forget(self);\n\n        unsafe { slice::from_raw_parts_mut(ptr, len) }\n    }\n\n    /// Shortens the vector, keeping the first `len` elements and dropping\n    /// the rest.\n    ///\n    /// If `len` is greater than the vector's current length, this has no\n    /// effect.\n    ///\n    /// The [`drain`] method can emulate `truncate`, but causes the excess\n    /// elements to be returned instead of dropped.\n    ///\n    /// Note that this method has no effect on the allocated capacity\n    /// of the vector.\n    ///\n    /// # Examples\n    ///\n    /// Truncating a five element vector to two elements:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3, 4, 5];\n    /// vec.truncate(2);\n    /// assert_eq!(vec, [1, 2]);\n    /// ```\n    ///\n    /// No truncation occurs when `len` is greater than the vector's current\n    /// length:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3];\n    /// vec.truncate(8);\n    /// assert_eq!(vec, [1, 2, 3]);\n    /// ```\n    ///\n    /// Truncating when `len == 0` is equivalent to calling the [`clear`]\n    /// method.\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3];\n    /// vec.truncate(0);\n    /// assert_eq!(vec, []);\n    /// ```\n    ///\n    /// [`clear`]: #method.clear\n    /// [`drain`]: #method.drain\n    pub fn truncate(&mut self, len: usize) {\n        let current_len = self.len;\n        unsafe {\n            let mut ptr = self.as_mut_ptr().add(self.len);\n            // Set the final length at the end, keeping in mind that\n            // dropping an element might panic. Works around a missed\n            // optimization, as seen in the following issue:\n            // https://github.com/rust-lang/rust/issues/51802\n            let mut local_len = SetLenOnDrop::new(&mut self.len);\n\n            // drop any extra elements\n            for _ in len..current_len {\n                local_len.decrement_len(1);\n                ptr = ptr.offset(-1);\n                ptr::drop_in_place(ptr);\n            }\n        }\n    }\n\n    /// Extracts a slice containing the entire vector.\n    ///\n    /// Equivalent to `&s[..]`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    /// use std::io::{self, Write};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let buffer = bumpalo::vec![in &b; 1, 2, 3, 5, 8];\n    /// io::sink().write(buffer.as_slice()).unwrap();\n    /// ```\n    #[inline]\n    pub fn as_slice(&self) -> &[T] {\n        self\n    }\n\n    /// Extracts a mutable slice of the entire vector.\n    ///\n    /// Equivalent to `&mut s[..]`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    /// use std::io::{self, Read};\n    ///\n    /// let b = Bump::new();\n    /// let mut buffer = bumpalo::vec![in &b; 0; 3];\n    /// io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();\n    /// ```\n    #[inline]\n    pub fn as_mut_slice(&mut self) -> &mut [T] {\n        self\n    }\n\n    /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer\n    /// valid for zero sized reads if the vector didn't allocate.\n    ///\n    /// The caller must ensure that the vector outlives the pointer this\n    /// function returns, or else it will end up pointing to garbage.\n    /// Modifying the vector may cause its buffer to be reallocated,\n    /// which would also make any pointers to it invalid.\n    ///\n    /// The caller must also ensure that the memory the pointer (non-transitively) points to\n    /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer\n    /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let bump = Bump::new();\n    ///\n    /// let x = bumpalo::vec![in &bump; 1, 2, 4];\n    /// let x_ptr = x.as_ptr();\n    ///\n    /// unsafe {\n    ///     for i in 0..x.len() {\n    ///         assert_eq!(*x_ptr.add(i), 1 << i);\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// [`as_mut_ptr`]: Vec::as_mut_ptr\n    #[inline]\n    pub fn as_ptr(&self) -> *const T {\n        // We shadow the slice method of the same name to avoid going through\n        // `deref`, which creates an intermediate reference.\n        let ptr = self.buf.ptr();\n        unsafe {\n            if ptr.is_null() {\n                core::hint::unreachable_unchecked();\n            }\n        }\n        ptr\n    }\n\n    /// Returns an unsafe mutable pointer to the vector's buffer, or a dangling\n    /// raw pointer valid for zero sized reads if the vector didn't allocate.\n    ///\n    /// The caller must ensure that the vector outlives the pointer this\n    /// function returns, or else it will end up pointing to garbage.\n    /// Modifying the vector may cause its buffer to be reallocated,\n    /// which would also make any pointers to it invalid.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let bump = Bump::new();\n    ///\n    /// // Allocate vector big enough for 4 elements.\n    /// let size = 4;\n    /// let mut x: Vec<i32> = Vec::with_capacity_in(size, &bump);\n    /// let x_ptr = x.as_mut_ptr();\n    ///\n    /// // Initialize elements via raw pointer writes, then set length.\n    /// unsafe {\n    ///     for i in 0..size {\n    ///         x_ptr.add(i).write(i as i32);\n    ///     }\n    ///     x.set_len(size);\n    /// }\n    /// assert_eq!(&*x, &[0, 1, 2, 3]);\n    /// ```\n    #[inline]\n    pub fn as_mut_ptr(&mut self) -> *mut T {\n        // We shadow the slice method of the same name to avoid going through\n        // `deref_mut`, which creates an intermediate reference.\n        let ptr = self.buf.ptr();\n        unsafe {\n            if ptr.is_null() {\n                core::hint::unreachable_unchecked();\n            }\n        }\n        ptr\n    }\n\n    /// Sets the length of a vector.\n    ///\n    /// This will explicitly set the size of the vector, without actually\n    /// modifying its buffers, so it is up to the caller to ensure that the\n    /// vector is actually the specified size.\n    ///\n    /// # Safety\n    ///\n    /// - `new_len` must be less than or equal to [`capacity()`].\n    /// - The elements at `old_len..new_len` must be initialized.\n    ///\n    /// [`capacity()`]: struct.Vec.html#method.capacity\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// use std::ptr;\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 'r', 'u', 's', 't'];\n    ///\n    /// unsafe {\n    ///     ptr::drop_in_place(&mut vec[3]);\n    ///     vec.set_len(3);\n    /// }\n    /// assert_eq!(vec, ['r', 'u', 's']);\n    /// ```\n    ///\n    /// In this example, there is a memory leak since the memory locations\n    /// owned by the inner vectors were not freed prior to the `set_len` call:\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b;\n    ///                             bumpalo::vec![in &b; 1, 0, 0],\n    ///                             bumpalo::vec![in &b; 0, 1, 0],\n    ///                             bumpalo::vec![in &b; 0, 0, 1]];\n    /// unsafe {\n    ///     vec.set_len(0);\n    /// }\n    /// ```\n    ///\n    /// In this example, the vector gets expanded from zero to four items\n    /// but we directly initialize uninitialized memory:\n    ///\n    // TODO: rely upon `spare_capacity_mut`\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let len = 4;\n    /// let b = Bump::new();\n    ///\n    /// let mut vec: Vec<u8> = Vec::with_capacity_in(len, &b);\n    ///\n    /// for i in 0..len {\n    ///     // SAFETY: we initialize memory via `pointer::write`\n    ///     unsafe { vec.as_mut_ptr().add(i).write(b'a') }\n    /// }\n    ///\n    /// unsafe {\n    ///     vec.set_len(len);\n    /// }\n    ///\n    /// assert_eq!(b\"aaaa\", &*vec);\n    /// ```\n    #[inline]\n    pub unsafe fn set_len(&mut self, new_len: usize) {\n        self.len = new_len;\n    }\n\n    /// Removes an element from the vector and returns it.\n    ///\n    /// The removed element is replaced by the last element of the vector.\n    ///\n    /// This does not preserve ordering, but is O(1).\n    ///\n    /// # Panics\n    ///\n    /// Panics if `index` is out of bounds.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut v = bumpalo::vec![in &b; \"foo\", \"bar\", \"baz\", \"qux\"];\n    ///\n    /// assert_eq!(v.swap_remove(1), \"bar\");\n    /// assert_eq!(v, [\"foo\", \"qux\", \"baz\"]);\n    ///\n    /// assert_eq!(v.swap_remove(0), \"foo\");\n    /// assert_eq!(v, [\"baz\", \"qux\"]);\n    /// ```\n    #[inline]\n    pub fn swap_remove(&mut self, index: usize) -> T {\n        unsafe {\n            // We replace self[index] with the last element. Note that if the\n            // bounds check on hole succeeds there must be a last element (which\n            // can be self[index] itself).\n            let hole: *mut T = &mut self[index];\n            let last = ptr::read(self.get_unchecked(self.len - 1));\n            self.len -= 1;\n            ptr::replace(hole, last)\n        }\n    }\n\n    /// Inserts an element at position `index` within the vector, shifting all\n    /// elements after it to the right.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `index > len`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3];\n    /// vec.insert(1, 4);\n    /// assert_eq!(vec, [1, 4, 2, 3]);\n    /// vec.insert(4, 5);\n    /// assert_eq!(vec, [1, 4, 2, 3, 5]);\n    /// ```\n    pub fn insert(&mut self, index: usize, element: T) {\n        let len = self.len();\n        assert!(index <= len);\n\n        // space for the new element\n        if len == self.buf.cap() {\n            self.reserve(1);\n        }\n\n        unsafe {\n            // infallible\n            // The spot to put the new value\n            {\n                let p = self.as_mut_ptr().add(index);\n                // Shift everything over to make space. (Duplicating the\n                // `index`th element into two consecutive places.)\n                ptr::copy(p, p.offset(1), len - index);\n                // Write it in, overwriting the first copy of the `index`th\n                // element.\n                ptr::write(p, element);\n            }\n            self.set_len(len + 1);\n        }\n    }\n\n    /// Removes and returns the element at position `index` within the vector,\n    /// shifting all elements after it to the left.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `index` is out of bounds.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut v = bumpalo::vec![in &b; 1, 2, 3];\n    /// assert_eq!(v.remove(1), 2);\n    /// assert_eq!(v, [1, 3]);\n    /// ```\n    pub fn remove(&mut self, index: usize) -> T {\n        let len = self.len();\n        assert!(index < len);\n        unsafe {\n            // infallible\n            let ret;\n            {\n                // the place we are taking from.\n                let ptr = self.as_mut_ptr().add(index);\n                // copy it out, unsafely having a copy of the value on\n                // the stack and in the vector at the same time.\n                ret = ptr::read(ptr);\n\n                // Shift everything down to fill in that spot.\n                ptr::copy(ptr.offset(1), ptr, len - index - 1);\n            }\n            self.set_len(len - 1);\n            ret\n        }\n    }\n\n    /// Retains only the elements specified by the predicate.\n    ///\n    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.\n    /// This method operates in place and preserves the order of the retained\n    /// elements.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3, 4];\n    /// vec.retain(|x: &i32| *x % 2 == 0);\n    /// assert_eq!(vec, [2, 4]);\n    /// ```\n    pub fn retain<F>(&mut self, mut f: F)\n    where\n        F: FnMut(&T) -> bool,\n    {\n        self.drain_filter(|x| !f(x));\n    }\n\n    /// Retains only the elements specified by the predicate.\n    ///\n    /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.\n    /// This method operates in place and preserves the order of the retained\n    /// elements.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3, 4];\n    /// vec.retain_mut(|x: &mut i32| *x % 2 == 0);\n    /// assert_eq!(vec, [2, 4]);\n    /// ```\n    pub fn retain_mut<F>(&mut self, mut f: F)\n    where\n        F: FnMut(&mut T) -> bool,\n    {\n        self.drain_filter(|x| !f(x));\n    }\n\n    /// Creates an iterator that removes the elements in the vector\n    /// for which the predicate returns `true` and yields the removed items.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::Bump;\n    /// use bumpalo::collections::{CollectIn, Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut numbers = bumpalo::vec![in &b; 1, 2, 3, 4, 5];\n    ///\n    /// let evens: Vec<_> = numbers.drain_filter(|x| *x % 2 == 0).collect_in(&b);\n    ///\n    /// assert_eq!(numbers, &[1, 3, 5]);\n    /// assert_eq!(evens, &[2, 4]);\n    /// ```\n    pub fn drain_filter<'a, F>(&'a mut self, filter: F) -> DrainFilter<'a, 'bump, T, F>\n    where\n        F: FnMut(&mut T) -> bool,\n    {\n        let old_len = self.len();\n\n        // Guard against us getting leaked (leak amplification)\n        unsafe {\n            self.set_len(0);\n        }\n\n        DrainFilter {\n            vec: self,\n            idx: 0,\n            write: 0,\n            old_len,\n            pred: filter,\n        }\n    }\n\n    /// Removes all but the first of consecutive elements in the vector that resolve to the same\n    /// key.\n    ///\n    /// If the vector is sorted, this removes all duplicates.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 10, 20, 21, 30, 20];\n    ///\n    /// vec.dedup_by_key(|i| *i / 10);\n    ///\n    /// assert_eq!(vec, [10, 20, 30, 20]);\n    /// ```\n    #[inline]\n    pub fn dedup_by_key<F, K>(&mut self, mut key: F)\n    where\n        F: FnMut(&mut T) -> K,\n        K: PartialEq,\n    {\n        self.dedup_by(|a, b| key(a) == key(b))\n    }\n\n    /// Removes all but the first of consecutive elements in the vector satisfying a given equality\n    /// relation.\n    ///\n    /// The `same_bucket` function is passed references to two elements from the vector and\n    /// must determine if the elements compare equal. The elements are passed in opposite order\n    /// from their order in the slice, so if `same_bucket(a, b)` returns `true`, `a` is removed.\n    ///\n    /// If the vector is sorted, this removes all duplicates.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; \"foo\", \"bar\", \"Bar\", \"baz\", \"bar\"];\n    ///\n    /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));\n    ///\n    /// assert_eq!(vec, [\"foo\", \"bar\", \"baz\", \"bar\"]);\n    /// ```\n    pub fn dedup_by<F>(&mut self, same_bucket: F)\n    where\n        F: FnMut(&mut T, &mut T) -> bool,\n    {\n        let len = {\n            let (dedup, _) = partition_dedup_by(self.as_mut_slice(), same_bucket);\n            dedup.len()\n        };\n        self.truncate(len);\n    }\n\n    // Proven specification with verus, converted to comments.\n    /// # Preconditions\n    ///\n    /// - old(self).len() < old(self).capacity(),\n    ///\n    /// # Postconditions\n    ///\n    /// - self.get_unchecked(old(self).len()) == value,\n    /// - self.len()      == old(self).len() + 1,\n    /// - self.capacity() == old(self).capacity(),\n    /// - forall|i: usize| implies(\n    ///       i < old(self).len(),\n    ///       self.get_unchecked(i) == old(self).get_unchecked(i)\n    ///   )\n    #[allow(clippy::inline_always)]\n    #[inline(always)]\n    unsafe fn push_unchecked(&mut self, value: T) {\n        debug_assert!(self.len() < self.capacity());\n\n        // Divergence from verified impl:\n        //   Verified implementation has special handling for ZSTs\n        //   as ZSTs do not play nicely with separation logic.\n        ptr::write(self.buf.ptr().add(self.len), value);\n\n        self.len = self.len + 1;\n    }\n\n    /// Appends an element to the back of a vector.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the number of elements in the vector overflows a `usize`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2];\n    /// vec.push(3);\n    /// assert_eq!(vec, [1, 2, 3]);\n    /// ```\n    #[inline]\n    pub fn push(&mut self, value: T) {\n        // This will panic or abort if we would allocate > isize::MAX bytes\n        // or if the length increment would overflow for zero-sized types.\n        if self.len == self.buf.cap() {\n            self.reserve(1);\n        }\n        unsafe {\n            self.push_unchecked(value);\n        }\n    }\n\n    /// Removes the last element from a vector and returns it, or [`None`] if it\n    /// is empty.\n    ///\n    /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3];\n    /// assert_eq!(vec.pop(), Some(3));\n    /// assert_eq!(vec, [1, 2]);\n    /// ```\n    #[inline]\n    pub fn pop(&mut self) -> Option<T> {\n        if self.len == 0 {\n            None\n        } else {\n            unsafe {\n                self.len -= 1;\n                Some(ptr::read(self.as_ptr().add(self.len())))\n            }\n        }\n    }\n\n    /// Removes and returns the last element from a vector if the predicate\n    /// returns `true`, or [`None`] if the predicate returns false or the vector\n    /// is empty (the predicate will not be called in that case).\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3, 4];\n    /// let pred = |x: &mut i32| *x % 2 == 0;\n    ///\n    /// assert_eq!(vec.pop_if(pred), Some(4));\n    /// assert_eq!(vec, [1, 2, 3]);\n    /// assert_eq!(vec.pop_if(pred), None);\n    /// ```\n    #[inline]\n    pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {\n        let last = self.last_mut()?;\n        if predicate(last) {\n            self.pop()\n        } else {\n            None\n        }\n    }\n\n    /// Moves all the elements of `other` into `Self`, leaving `other` empty.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the number of elements in the vector overflows a `usize`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3];\n    /// let mut vec2 = bumpalo::vec![in &b; 4, 5, 6];\n    /// vec.append(&mut vec2);\n    /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]);\n    /// assert_eq!(vec2, []);\n    /// ```\n    #[inline]\n    pub fn append(&mut self, other: &mut Self) {\n        unsafe {\n            self.append_elements(other.as_slice() as _);\n            other.set_len(0);\n        }\n    }\n\n    /// Appends elements to `Self` from other buffer.\n    #[inline]\n    unsafe fn append_elements(&mut self, other: *const [T]) {\n        let count = (&(*other)).len();\n        self.reserve(count);\n        let len = self.len();\n        ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count);\n        self.len += count;\n    }\n\n    /// Creates a draining iterator that removes the specified range in the vector\n    /// and yields the removed items.\n    ///\n    /// Note 1: The element range is removed even if the iterator is only\n    /// partially consumed or not consumed at all.\n    ///\n    /// Note 2: It is unspecified how many elements are removed from the vector\n    /// if the `Drain` value is leaked.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the starting point is greater than the end point or if\n    /// the end point is greater than the length of the vector.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::Bump;\n    /// use bumpalo::collections::{CollectIn, Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut v = bumpalo::vec![in &b; 1, 2, 3];\n    ///\n    /// let u: Vec<_> = v.drain(1..).collect_in(&b);\n    ///\n    /// assert_eq!(v, &[1]);\n    /// assert_eq!(u, &[2, 3]);\n    ///\n    /// // A full range clears the vector\n    /// v.drain(..);\n    /// assert_eq!(v, &[]);\n    /// ```\n    pub fn drain<'a, R>(&'a mut self, range: R) -> Drain<'a, 'bump, T>\n    where\n        R: RangeBounds<usize>,\n    {\n        // Memory safety\n        //\n        // When the Drain is first created, it shortens the length of\n        // the source vector to make sure no uninitialized or moved-from elements\n        // are accessible at all if the Drain's destructor never gets to run.\n        //\n        // Drain will ptr::read out the values to remove.\n        // When finished, remaining tail of the vec is copied back to cover\n        // the hole, and the vector length is restored to the new length.\n        //\n        let len = self.len();\n        let start = match range.start_bound() {\n            Included(&n) => n,\n            Excluded(&n) => n + 1,\n            Unbounded => 0,\n        };\n        let end = match range.end_bound() {\n            Included(&n) => n + 1,\n            Excluded(&n) => n,\n            Unbounded => len,\n        };\n        assert!(start <= end);\n        assert!(end <= len);\n\n        unsafe {\n            // set self.vec length's to start, to be safe in case Drain is leaked\n            self.set_len(start);\n            // Use the borrow in the IterMut to indicate borrowing behavior of the\n            // whole Drain iterator (like &mut T).\n            let range_slice = slice::from_raw_parts_mut(self.as_mut_ptr().add(start), end - start);\n            Drain {\n                tail_start: end,\n                tail_len: len - end,\n                iter: range_slice.iter(),\n                vec: NonNull::from(self),\n            }\n        }\n    }\n\n    /// Clears the vector, removing all values.\n    ///\n    /// Note that this method has no effect on the allocated capacity\n    /// of the vector.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut v = bumpalo::vec![in &b; 1, 2, 3];\n    ///\n    /// v.clear();\n    ///\n    /// assert!(v.is_empty());\n    /// ```\n    #[inline]\n    pub fn clear(&mut self) {\n        self.truncate(0)\n    }\n\n    /// Returns the number of elements in the vector, also referred to\n    /// as its 'length'.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let a = bumpalo::vec![in &b; 1, 2, 3];\n    /// assert_eq!(a.len(), 3);\n    /// ```\n    #[inline]\n    pub fn len(&self) -> usize {\n        self.len\n    }\n\n    /// Returns `true` if the vector contains no elements.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut v = Vec::new_in(&b);\n    /// assert!(v.is_empty());\n    ///\n    /// v.push(1);\n    /// assert!(!v.is_empty());\n    /// ```\n    pub fn is_empty(&self) -> bool {\n        self.len() == 0\n    }\n\n    /// Splits the collection into two at the given index.\n    ///\n    /// Returns a newly allocated vector. `self` contains elements `[0, at)`,\n    /// and the returned vector contains elements `[at, len)`.\n    ///\n    /// Note that the capacity of `self` does not change.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `at > len`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3];\n    /// let vec2 = vec.split_off(1);\n    /// assert_eq!(vec, [1]);\n    /// assert_eq!(vec2, [2, 3]);\n    /// ```\n    #[inline]\n    pub fn split_off(&mut self, at: usize) -> Self {\n        assert!(at <= self.len(), \"`at` out of bounds\");\n\n        let other_len = self.len - at;\n        let mut other = Vec::with_capacity_in(other_len, self.buf.bump());\n\n        // Unsafely `set_len` and copy items to `other`.\n        unsafe {\n            self.set_len(at);\n            other.set_len(other_len);\n\n            ptr::copy_nonoverlapping(self.as_ptr().add(at), other.as_mut_ptr(), other.len());\n        }\n        other\n    }\n}\n\n#[cfg(feature = \"boxed\")]\nimpl<'bump, T> Vec<'bump, T> {\n    /// Converts the vector into [`Box<[T]>`][owned slice].\n    ///\n    /// Note that this will drop any excess capacity.\n    ///\n    /// [owned slice]: ../../boxed/struct.Box.html\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec, vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let v = vec![in &b; 1, 2, 3];\n    ///\n    /// let slice = v.into_boxed_slice();\n    /// ```\n    pub fn into_boxed_slice(mut self) -> crate::boxed::Box<'bump, [T]> {\n        use crate::boxed::Box;\n\n        // Unlike `alloc::vec::Vec` shrinking here isn't necessary as `bumpalo::boxed::Box` doesn't own memory.\n        unsafe {\n            let slice = slice::from_raw_parts_mut(self.as_mut_ptr(), self.len);\n            let output: Box<'bump, [T]> = Box::from_raw(slice);\n            mem::forget(self);\n            output\n        }\n    }\n}\n\nimpl<'bump, T: 'bump + Clone> Vec<'bump, T> {\n    /// Resizes the `Vec` in-place so that `len` is equal to `new_len`.\n    ///\n    /// If `new_len` is greater than `len`, the `Vec` is extended by the\n    /// difference, with each additional slot filled with `value`.\n    /// If `new_len` is less than `len`, the `Vec` is simply truncated.\n    ///\n    /// This method requires [`Clone`] to be able clone the passed value. If\n    /// you need more flexibility (or want to rely on [`Default`] instead of\n    /// [`Clone`]), use [`resize_with`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; \"hello\"];\n    /// vec.resize(3, \"world\");\n    /// assert_eq!(vec, [\"hello\", \"world\", \"world\"]);\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 3, 4];\n    /// vec.resize(2, 0);\n    /// assert_eq!(vec, [1, 2]);\n    /// ```\n    ///\n    /// [`Clone`]: https://doc.rust-lang.org/std/clone/trait.Clone.html\n    /// [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html\n    /// [`resize_with`]: #method.resize_with\n    pub fn resize(&mut self, new_len: usize, value: T) {\n        let len = self.len();\n\n        if new_len > len {\n            self.extend_with(new_len - len, ExtendElement(value))\n        } else {\n            self.truncate(new_len);\n        }\n    }\n\n    // Proven specification with verus, converted to comments.\n    /// # Preconditions\n    ///\n    /// - old(self).len() + slice.len() <= old(self).capacity(),\n    ///\n    /// # Postconditions\n    ///\n    /// - forall|i: usize| implies(\n    ///       i < old(self).len(),\n    ///       self.get_unchecked(i) == old(self).get_unchecked(i)\n    ///   ),\n    /// - forall|i: usize| implies(\n    ///       i < slice.len(),\n    ///       self.get_unchecked((old(self).len() + i) as usize)\n    ///           == clone(slice.get_unchecked(i))\n    ///   ),\n    /// - self.len()      == old(self).len() + slice.len(),\n    /// - self.capacity() == old(self).capacity(),\n    #[inline]\n    unsafe fn extend_from_slice_unchecked(&mut self, slice: &[T]) {\n        // Guaranteed never to overflow for non ZSTs\n        //   size_of::<T>() <= isize::MAX - (isize::MAX % align_of::<T>()))\n        //   isize::MAX + isize::MAX < usize::MAX\n        debug_assert!(\n            core::mem::size_of::<T>() == 0 || self.capacity() >= self.len() + slice.len()\n        );\n        debug_assert!(\n            // is_zst::<T>() ==> capacity >= slen + slice.len()\n            core::mem::size_of::<T>() != 0\n            // Capacity is usize::MAX for ZSTs\n            || self.len() <= usize::MAX - slice.len()\n        );\n\n        let mut pos = 0usize;\n\n        loop\n        /*\n        invariants\n            pos <= slice.len(),\n            self.len() + (slice.len() - pos) <= old(self).capacity(),\n            old(self).capacity() == self.capacity(),\n\n            self.len() == old(self).len() + pos,\n\n            forall|i: usize| implies(\n                i < old(self).len(),\n                self.get_unchecked(i) == old(self).get_unchecked(i)\n            ),\n            forall|i: usize| implies(\n                i < pos,\n                self.get_unchecked((old(self).len() + i) as usize)\n                    == clone(slice.get_unchecked(i))\n            )\n        */\n        {\n            if pos == slice.len() {\n                /*\n                pos = slice.len(),\n                self.len() = old(self).len() + slice.len(),\n\n                forall|i: usize| i < slice.len() implies {\n                    self.get_unchecked((old(self).len() + i) as usize)\n                        == clone(slice.get_unchecked(i))\n                }\n                by {\n                    i < pos\n                }\n                */\n                return;\n            }\n\n            /*\n            pos < slice.len(),\n            self.len() < self.capacity()\n            */\n\n            let elem = slice.get_unchecked(pos);\n            self.push_unchecked(elem.clone());\n\n            /*\n            ghost prev_pos = pos\n            */\n\n            pos = pos + 1;\n\n            /*\n            forall|i: usize| i < pos implies {\n                self.get_unchecked((old(self).len() + i) as usize)\n                    == clone(slice.get_unchecked(i))\n            }\n            by {\n                if i < pos - 1 {\n                    // By invariant\n                }\n                else {\n                    i == prev_pos\n                }\n            }\n            */\n        }\n    }\n\n    /// Clones and appends all elements in a slice to the `Vec`.\n    ///\n    /// Iterates over the slice `other`, clones each element, and then appends\n    /// it to this `Vec`. The `other` vector is traversed in-order.\n    ///\n    /// Note that this function is same as [`extend`] except that it is\n    /// specialized to work with slices instead. If and when Rust gets\n    /// specialization this function will likely be deprecated (but still\n    /// available).\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1];\n    /// vec.extend_from_slice(&[2, 3, 4]);\n    /// assert_eq!(vec, [1, 2, 3, 4]);\n    /// ```\n    ///\n    /// [`extend`]: #method.extend\n    pub fn extend_from_slice(&mut self, other: &[T]) {\n        let capacity = self.capacity();\n\n        /*\n        Cannot underflow via invariant of the Vec (capacity >= length).\n\n        This also holds for ZSTs, as capacity is usize::MAX\n        */\n        let remaining_cap = capacity - self.len;\n\n        /*\n            self.len() + other.len() <= self.capacity(),\n                <==>\n            other.len() <= self.capacity() - self.len()\n        */\n\n        if other.len() > remaining_cap {\n            /*\n            Divergence from verified impl:\n              Verified implementation's reserve is not the same\n              as bumpalo's. Verified implementation reserves with\n              respect to capacity, not length. Thus this is equivalent\n              to the verified implementation's:\n\n                self.buf.reserve(other.len() - remaining_cap)\n\n            */\n            self.reserve(other.len());\n        }\n\n        /*\n        self.capacity() >= self.len() + other.len()\n        */\n\n        unsafe {\n            self.extend_from_slice_unchecked(other);\n        }\n    }\n}\n\nimpl<'bump, T: 'bump + Copy> Vec<'bump, T> {\n    /// Helper method to copy all of the items in `other` and append them to the end of `self`.\n    ///\n    /// SAFETY:\n    ///   * The caller is responsible for:\n    ///       * calling [`reserve`](Self::reserve) beforehand to guarantee that there is enough\n    ///         capacity to store `other.len()` more items.\n    ///       * guaranteeing that `self` and `other` do not overlap.\n    unsafe fn extend_from_slice_copy_unchecked(&mut self, other: &[T]) {\n        let old_len = self.len();\n        debug_assert!(old_len + other.len() <= self.capacity());\n\n        // SAFETY:\n        // * `src` is valid for reads of `other.len()` values by virtue of being a `&[T]`.\n        // * `dst` is valid for writes of `other.len()` bytes because the caller of this\n        //   method is required to `reserve` capacity to store at least `other.len()` items\n        //   beforehand.\n        // * Because `src` is a `&[T]` and dst is a `&[T]` within the `Vec<T>`,\n        //   `copy_nonoverlapping`'s alignment requirements are met.\n        // * Caller is required to guarantee that the source and destination ranges cannot overlap\n        unsafe {\n            let src = other.as_ptr();\n            let dst = self.as_mut_ptr().add(old_len);\n            ptr::copy_nonoverlapping(src, dst, other.len());\n            self.set_len(old_len + other.len());\n        }\n    }\n\n    /// Copies all elements in the slice `other` and appends them to the `Vec`.\n    ///\n    /// Note that this function is same as [`extend_from_slice`] except that it is optimized for\n    /// slices of types that implement the `Copy` trait. If and when Rust gets specialization\n    /// this function will likely be deprecated (but still available).\n    ///\n    /// To copy and append the data from multiple source slices at once, see\n    /// [`extend_from_slices_copy`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1];\n    /// vec.extend_from_slice_copy(&[2, 3, 4]);\n    /// assert_eq!(vec, [1, 2, 3, 4]);\n    /// ```\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 'H' as u8];\n    /// vec.extend_from_slice_copy(\"ello, world!\".as_bytes());\n    /// assert_eq!(vec, \"Hello, world!\".as_bytes());\n    /// ```\n    ///\n    /// [`extend_from_slice`]: #method.extend_from_slice\n    /// [`extend_from_slices`]: #method.extend_from_slices\n    pub fn extend_from_slice_copy(&mut self, other: &[T]) {\n        // Reserve space in the Vec for the values to be added\n        self.reserve(other.len());\n\n        // Copy values into the space that was just reserved\n        // SAFETY:\n        // * `self` has enough capacity to store `other.len()` more items as `self.reserve(other.len())`\n        //   above guarantees that.\n        // * Source and destination data ranges cannot overlap as we just reserved the destination\n        //   range from the bump.\n        unsafe {\n            self.extend_from_slice_copy_unchecked(other);\n        }\n    }\n\n    /// For each slice in `slices`, copies all elements in the slice and appends them to the `Vec`.\n    ///\n    /// This method is equivalent to calling [`extend_from_slice_copy`] in a loop, but is able\n    /// to precompute the total amount of space to reserve in advance. This reduces the potential\n    /// maximum number of reallocations needed from one-per-slice to just one.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1];\n    /// vec.extend_from_slices_copy(&[&[2, 3], &[], &[4]]);\n    /// assert_eq!(vec, [1, 2, 3, 4]);\n    /// ```\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 'H' as u8];\n    /// vec.extend_from_slices_copy(&[\"ello,\".as_bytes(), &[], \" world!\".as_bytes()]);\n    /// assert_eq!(vec, \"Hello, world!\".as_bytes());\n    /// ```\n    ///\n    /// [`extend_from_slice_copy`]: #method.extend_from_slice_copy\n    pub fn extend_from_slices_copy(&mut self, slices: &[&[T]]) {\n        // Reserve the total amount of capacity we'll need to safely append the aggregated contents\n        // of each slice in `slices`.\n        let capacity_to_reserve: usize = slices.iter().map(|slice| slice.len()).sum();\n        self.reserve(capacity_to_reserve);\n\n        // SAFETY:\n        // * `dst` is valid for writes of `capacity_to_reserve` items as\n        //   `self.reserve(capacity_to_reserve)` above guarantees that.\n        // * Source and destination ranges cannot overlap as we just reserved the destination\n        //   range from the bump.\n        unsafe {\n            // Copy the contents of each slice onto the end of `self`\n            slices.iter().for_each(|slice| {\n                self.extend_from_slice_copy_unchecked(slice);\n            });\n        }\n    }\n}\n\n// This code generalises `extend_with_{element,default}`.\ntrait ExtendWith<T> {\n    fn next(&mut self) -> T;\n    fn last(self) -> T;\n}\n\nstruct ExtendElement<T>(T);\nimpl<T: Clone> ExtendWith<T> for ExtendElement<T> {\n    fn next(&mut self) -> T {\n        self.0.clone()\n    }\n    fn last(self) -> T {\n        self.0\n    }\n}\n\nimpl<'bump, T: 'bump> Vec<'bump, T> {\n    /// Extend the vector by `n` values, using the given generator.\n    fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, mut value: E) {\n        self.reserve(n);\n\n        unsafe {\n            let mut ptr = self.as_mut_ptr().add(self.len());\n            // Use SetLenOnDrop to work around bug where compiler\n            // may not realize the store through `ptr` through self.set_len()\n            // don't alias.\n            let mut local_len = SetLenOnDrop::new(&mut self.len);\n\n            // Write all elements except the last one\n            for _ in 1..n {\n                ptr::write(ptr, value.next());\n                ptr = ptr.offset(1);\n                // Increment the length in every step in case next() panics\n                local_len.increment_len(1);\n            }\n\n            if n > 0 {\n                // We can write the last element directly without cloning needlessly\n                ptr::write(ptr, value.last());\n                local_len.increment_len(1);\n            }\n\n            // len set by scope guard\n        }\n    }\n}\n\n// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.\n//\n// The idea is: The length field in SetLenOnDrop is a local variable\n// that the optimizer will see does not alias with any stores through the Vec's data\n// pointer. This is a workaround for alias analysis issue #32155\nstruct SetLenOnDrop<'a> {\n    len: &'a mut usize,\n    local_len: usize,\n}\n\nimpl<'a> SetLenOnDrop<'a> {\n    #[inline]\n    fn new(len: &'a mut usize) -> Self {\n        SetLenOnDrop {\n            local_len: *len,\n            len,\n        }\n    }\n\n    #[inline]\n    fn increment_len(&mut self, increment: usize) {\n        self.local_len += increment;\n    }\n\n    #[inline]\n    fn decrement_len(&mut self, decrement: usize) {\n        self.local_len -= decrement;\n    }\n}\n\nimpl<'a> Drop for SetLenOnDrop<'a> {\n    #[inline]\n    fn drop(&mut self) {\n        *self.len = self.local_len;\n    }\n}\n\nimpl<'bump, T: 'bump + PartialEq> Vec<'bump, T> {\n    /// Removes consecutive repeated elements in the vector according to the\n    /// [`PartialEq`] trait implementation.\n    ///\n    /// If the vector is sorted, this removes all duplicates.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut vec = bumpalo::vec![in &b; 1, 2, 2, 3, 2];\n    ///\n    /// vec.dedup();\n    ///\n    /// assert_eq!(vec, [1, 2, 3, 2]);\n    /// ```\n    #[inline]\n    pub fn dedup(&mut self) {\n        self.dedup_by(|a, b| a == b)\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Common trait implementations for Vec\n////////////////////////////////////////////////////////////////////////////////\n\nimpl<'bump, T: 'bump + Clone> Clone for Vec<'bump, T> {\n    #[cfg(not(test))]\n    fn clone(&self) -> Vec<'bump, T> {\n        let mut v = Vec::with_capacity_in(self.len(), self.buf.bump());\n        v.extend(self.iter().cloned());\n        v\n    }\n\n    // HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is\n    // required for this method definition, is not available. Instead use the\n    // `slice::to_vec`  function which is only available with cfg(test)\n    // NB see the slice::hack module in slice.rs for more information\n    #[cfg(test)]\n    fn clone(&self) -> Vec<'bump, T> {\n        let mut v = Vec::new_in(self.buf.bump());\n        v.extend(self.iter().cloned());\n        v\n    }\n}\n\nimpl<'bump, T: 'bump + Hash> Hash for Vec<'bump, T> {\n    #[inline]\n    fn hash<H: hash::Hasher>(&self, state: &mut H) {\n        Hash::hash(&**self, state)\n    }\n}\n\nimpl<'bump, T, I> Index<I> for Vec<'bump, T>\nwhere\n    I: ::core::slice::SliceIndex<[T]>,\n{\n    type Output = I::Output;\n\n    #[inline]\n    fn index(&self, index: I) -> &Self::Output {\n        Index::index(&**self, index)\n    }\n}\n\nimpl<'bump, T, I> IndexMut<I> for Vec<'bump, T>\nwhere\n    I: ::core::slice::SliceIndex<[T]>,\n{\n    #[inline]\n    fn index_mut(&mut self, index: I) -> &mut Self::Output {\n        IndexMut::index_mut(&mut **self, index)\n    }\n}\n\nimpl<'bump, T: 'bump> ops::Deref for Vec<'bump, T> {\n    type Target = [T];\n\n    fn deref(&self) -> &[T] {\n        unsafe {\n            let p = self.buf.ptr();\n            // assume(!p.is_null());\n            slice::from_raw_parts(p, self.len)\n        }\n    }\n}\n\nimpl<'bump, T: 'bump> ops::DerefMut for Vec<'bump, T> {\n    fn deref_mut(&mut self) -> &mut [T] {\n        unsafe {\n            let ptr = self.buf.ptr();\n            // assume(!ptr.is_null());\n            slice::from_raw_parts_mut(ptr, self.len)\n        }\n    }\n}\n\nimpl<'bump, T: 'bump> IntoIterator for Vec<'bump, T> {\n    type Item = T;\n    type IntoIter = IntoIter<'bump, T>;\n\n    /// Creates a consuming iterator, that is, one that moves each value out of\n    /// the vector (from start to end). The vector cannot be used after calling\n    /// this.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let v = bumpalo::vec![in &b; \"a\".to_string(), \"b\".to_string()];\n    /// for s in v.into_iter() {\n    ///     // s has type String, not &String\n    ///     println!(\"{}\", s);\n    /// }\n    /// ```\n    #[inline]\n    fn into_iter(mut self) -> IntoIter<'bump, T> {\n        unsafe {\n            let begin = self.as_mut_ptr();\n            // assume(!begin.is_null());\n            let end = if mem::size_of::<T>() == 0 {\n                arith_offset(begin as *const i8, self.len() as isize) as *const T\n            } else {\n                begin.add(self.len()) as *const T\n            };\n            mem::forget(self);\n            IntoIter {\n                phantom: PhantomData,\n                ptr: begin,\n                end,\n            }\n        }\n    }\n}\n\nimpl<'a, 'bump, T> IntoIterator for &'a Vec<'bump, T> {\n    type Item = &'a T;\n    type IntoIter = slice::Iter<'a, T>;\n\n    fn into_iter(self) -> slice::Iter<'a, T> {\n        self.iter()\n    }\n}\n\nimpl<'a, 'bump, T> IntoIterator for &'a mut Vec<'bump, T> {\n    type Item = &'a mut T;\n    type IntoIter = slice::IterMut<'a, T>;\n\n    fn into_iter(self) -> slice::IterMut<'a, T> {\n        self.iter_mut()\n    }\n}\n\nimpl<'bump, T: 'bump> Extend<T> for Vec<'bump, T> {\n    #[inline]\n    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {\n        let iter = iter.into_iter();\n        self.reserve(iter.size_hint().0);\n\n        for t in iter {\n            self.push(t);\n        }\n    }\n}\n\nimpl<'bump, T: 'bump> Vec<'bump, T> {\n    /// Creates a splicing iterator that replaces the specified range in the vector\n    /// with the given `replace_with` iterator and yields the removed items.\n    /// `replace_with` does not need to be the same length as `range`.\n    ///\n    /// Note 1: The element range is removed even if the iterator is not\n    /// consumed until the end.\n    ///\n    /// Note 2: It is unspecified how many elements are removed from the vector,\n    /// if the `Splice` value is leaked.\n    ///\n    /// Note 3: The input iterator `replace_with` is only consumed\n    /// when the `Splice` value is dropped.\n    ///\n    /// Note 4: This is optimal if:\n    ///\n    /// * The tail (elements in the vector after `range`) is empty,\n    /// * or `replace_with` yields fewer elements than `range`’s length\n    /// * or the lower bound of its `size_hint()` is exact.\n    ///\n    /// Otherwise, a temporary vector is allocated and the tail is moved twice.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the starting point is greater than the end point or if\n    /// the end point is greater than the length of the vector.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let mut v = bumpalo::vec![in &b; 1, 2, 3];\n    /// let new = [7, 8];\n    /// let u: Vec<_> = Vec::from_iter_in(v.splice(..2, new.iter().cloned()), &b);\n    /// assert_eq!(v, &[7, 8, 3]);\n    /// assert_eq!(u, &[1, 2]);\n    /// ```\n    #[inline]\n    pub fn splice<'a, R, I>(\n        &'a mut self,\n        range: R,\n        replace_with: I,\n    ) -> Splice<'a, 'bump, I::IntoIter>\n    where\n        R: RangeBounds<usize>,\n        I: IntoIterator<Item = T>,\n    {\n        Splice {\n            drain: self.drain(range),\n            replace_with: replace_with.into_iter(),\n        }\n    }\n}\n\n/// Extend implementation that copies elements out of references before pushing them onto the Vec.\n///\n/// This implementation is specialized for slice iterators, where it uses [`copy_from_slice`] to\n/// append the entire slice at once.\n///\n/// [`copy_from_slice`]: https://doc.rust-lang.org/std/primitive.slice.html#method.copy_from_slice\nimpl<'a, 'bump, T: 'a + Copy> Extend<&'a T> for Vec<'bump, T> {\n    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {\n        self.extend(iter.into_iter().cloned())\n    }\n}\n\nmacro_rules! __impl_slice_eq1 {\n    ($Lhs: ty, $Rhs: ty) => {\n        __impl_slice_eq1! { $Lhs, $Rhs, Sized }\n    };\n    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {\n        impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs\n        where\n            A: PartialEq<B>,\n        {\n            #[inline]\n            fn eq(&self, other: &$Rhs) -> bool {\n                self[..] == other[..]\n            }\n        }\n    };\n}\n\n__impl_slice_eq1! { Vec<'a, A>, Vec<'b, B> }\n__impl_slice_eq1! { Vec<'a, A>, &'b [B] }\n__impl_slice_eq1! { Vec<'a, A>, &'b mut [B] }\n// __impl_slice_eq1! { Cow<'a, [A]>, Vec<'b, B>, Clone }\n\nmacro_rules! __impl_slice_eq1_array {\n    ($Lhs: ty, $Rhs: ty) => {\n        impl<'a, 'b, A, B, const N: usize> PartialEq<$Rhs> for $Lhs\n        where\n            A: PartialEq<B>,\n        {\n            #[inline]\n            fn eq(&self, other: &$Rhs) -> bool {\n                self[..] == other[..]\n            }\n        }\n    };\n}\n\n__impl_slice_eq1_array! { Vec<'a, A>, [B; N] }\n__impl_slice_eq1_array! { Vec<'a, A>, &'b [B; N] }\n__impl_slice_eq1_array! { Vec<'a, A>, &'b mut [B; N] }\n\n/// Implements comparison of vectors, lexicographically.\nimpl<'bump, T: 'bump + PartialOrd> PartialOrd for Vec<'bump, T> {\n    #[inline]\n    fn partial_cmp(&self, other: &Vec<'bump, T>) -> Option<Ordering> {\n        PartialOrd::partial_cmp(&**self, &**other)\n    }\n}\n\nimpl<'bump, T: 'bump + Eq> Eq for Vec<'bump, T> {}\n\n/// Implements ordering of vectors, lexicographically.\nimpl<'bump, T: 'bump + Ord> Ord for Vec<'bump, T> {\n    #[inline]\n    fn cmp(&self, other: &Vec<'bump, T>) -> Ordering {\n        Ord::cmp(&**self, &**other)\n    }\n}\n\nimpl<'bump, T: 'bump + fmt::Debug> fmt::Debug for Vec<'bump, T> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        fmt::Debug::fmt(&**self, f)\n    }\n}\n\nimpl<'bump, T: 'bump> AsRef<Vec<'bump, T>> for Vec<'bump, T> {\n    fn as_ref(&self) -> &Vec<'bump, T> {\n        self\n    }\n}\n\nimpl<'bump, T: 'bump> AsMut<Vec<'bump, T>> for Vec<'bump, T> {\n    fn as_mut(&mut self) -> &mut Vec<'bump, T> {\n        self\n    }\n}\n\nimpl<'bump, T: 'bump> AsRef<[T]> for Vec<'bump, T> {\n    fn as_ref(&self) -> &[T] {\n        self\n    }\n}\n\nimpl<'bump, T: 'bump> AsMut<[T]> for Vec<'bump, T> {\n    fn as_mut(&mut self) -> &mut [T] {\n        self\n    }\n}\n\n#[cfg(feature = \"boxed\")]\nimpl<'bump, T: 'bump> From<Vec<'bump, T>> for crate::boxed::Box<'bump, [T]> {\n    fn from(v: Vec<'bump, T>) -> crate::boxed::Box<'bump, [T]> {\n        v.into_boxed_slice()\n    }\n}\n\nimpl<'bump, T: 'bump> Borrow<[T]> for Vec<'bump, T> {\n    #[inline]\n    fn borrow(&self) -> &[T] {\n        &self[..]\n    }\n}\n\nimpl<'bump, T: 'bump> BorrowMut<[T]> for Vec<'bump, T> {\n    #[inline]\n    fn borrow_mut(&mut self) -> &mut [T] {\n        &mut self[..]\n    }\n}\n\nimpl<'bump, T> Drop for Vec<'bump, T> {\n    fn drop(&mut self) {\n        unsafe {\n            // use drop for [T]\n            // use a raw slice to refer to the elements of the vector as weakest necessary type;\n            // could avoid questions of validity in certain cases\n            ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len))\n        }\n        // RawVec handles deallocation\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Clone-on-write\n////////////////////////////////////////////////////////////////////////////////\n\n// impl<'a, 'bump, T: Clone> From<Vec<'bump, T>> for Cow<'a, [T]> {\n//     fn from(v: Vec<'bump, T>) -> Cow<'a, [T]> {\n//         Cow::Owned(v)\n//     }\n// }\n\n// impl<'a, 'bump, T: Clone> From<&'a Vec<'bump, T>> for Cow<'a, [T]> {\n//     fn from(v: &'a Vec<'bump, T>) -> Cow<'a, [T]> {\n//         Cow::Borrowed(v.as_slice())\n//     }\n// }\n\n////////////////////////////////////////////////////////////////////////////////\n// Iterators\n////////////////////////////////////////////////////////////////////////////////\n\n/// An iterator that moves out of a vector.\n///\n/// This `struct` is created by the [`Vec::into_iter`] method\n/// (provided by the [`IntoIterator`] trait).\n///\n/// [`IntoIterator`]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html\npub struct IntoIter<'bump, T> {\n    phantom: PhantomData<&'bump [T]>,\n    ptr: *const T,\n    end: *const T,\n}\n\nimpl<'bump, T: fmt::Debug> fmt::Debug for IntoIter<'bump, T> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.debug_tuple(\"IntoIter\").field(&self.as_slice()).finish()\n    }\n}\n\nimpl<'bump, T: 'bump> IntoIter<'bump, T> {\n    /// Returns the remaining items of this iterator as a slice.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let vec = bumpalo::vec![in &b; 'a', 'b', 'c'];\n    /// let mut into_iter = vec.into_iter();\n    /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);\n    /// let _ = into_iter.next().unwrap();\n    /// assert_eq!(into_iter.as_slice(), &['b', 'c']);\n    /// ```\n    pub fn as_slice(&self) -> &[T] {\n        unsafe { slice::from_raw_parts(self.ptr, self.len()) }\n    }\n\n    /// Returns the remaining items of this iterator as a mutable slice.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use bumpalo::{Bump, collections::Vec};\n    ///\n    /// let b = Bump::new();\n    ///\n    /// let vec = bumpalo::vec![in &b; 'a', 'b', 'c'];\n    /// let mut into_iter = vec.into_iter();\n    /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);\n    /// into_iter.as_mut_slice()[2] = 'z';\n    /// assert_eq!(into_iter.next().unwrap(), 'a');\n    /// assert_eq!(into_iter.next().unwrap(), 'b');\n    /// assert_eq!(into_iter.next().unwrap(), 'z');\n    /// ```\n    pub fn as_mut_slice(&mut self) -> &mut [T] {\n        unsafe { slice::from_raw_parts_mut(self.ptr as *mut T, self.len()) }\n    }\n}\n\nunsafe impl<'bump, T: Send> Send for IntoIter<'bump, T> {}\nunsafe impl<'bump, T: Sync> Sync for IntoIter<'bump, T> {}\n\nimpl<'bump, T: 'bump> Iterator for IntoIter<'bump, T> {\n    type Item = T;\n\n    #[inline]\n    fn next(&mut self) -> Option<T> {\n        unsafe {\n            if self.ptr as *const _ == self.end {\n                None\n            } else if mem::size_of::<T>() == 0 {\n                // purposefully don't use 'ptr.offset' because for\n                // vectors with 0-size elements this would return the\n                // same pointer.\n                self.ptr = arith_offset(self.ptr as *const i8, 1) as *mut T;\n\n                // Make up a value of this ZST.\n                Some(mem::zeroed())\n            } else {\n                let old = self.ptr;\n                self.ptr = self.ptr.offset(1);\n\n                Some(ptr::read(old))\n            }\n        }\n    }\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let exact = if mem::size_of::<T>() == 0 {\n            (self.end as usize).wrapping_sub(self.ptr as usize)\n        } else {\n            unsafe { offset_from(self.end, self.ptr) as usize }\n        };\n        (exact, Some(exact))\n    }\n\n    #[inline]\n    fn count(self) -> usize {\n        self.len()\n    }\n}\n\nimpl<'bump, T: 'bump> DoubleEndedIterator for IntoIter<'bump, T> {\n    #[inline]\n    fn next_back(&mut self) -> Option<T> {\n        unsafe {\n            if self.end == self.ptr {\n                None\n            } else if mem::size_of::<T>() == 0 {\n                // See above for why 'ptr.offset' isn't used\n                self.end = arith_offset(self.end as *const i8, -1) as *mut T;\n\n                // Make up a value of this ZST.\n                Some(mem::zeroed())\n            } else {\n                self.end = self.end.offset(-1);\n\n                Some(ptr::read(self.end))\n            }\n        }\n    }\n}\n\nimpl<'bump, T: 'bump> ExactSizeIterator for IntoIter<'bump, T> {}\n\nimpl<'bump, T: 'bump> FusedIterator for IntoIter<'bump, T> {}\n\nimpl<'bump, T> Drop for IntoIter<'bump, T> {\n    fn drop(&mut self) {\n        // drop all remaining elements\n        self.for_each(drop);\n    }\n}\n\n/// A draining iterator for `Vec<'bump, T>`.\n///\n/// This `struct` is created by the [`Vec::drain`] method.\npub struct Drain<'a, 'bump, T: 'a + 'bump> {\n    /// Index of tail to preserve\n    tail_start: usize,\n    /// Length of tail\n    tail_len: usize,\n    /// Current remaining range to remove\n    iter: slice::Iter<'a, T>,\n    vec: NonNull<Vec<'bump, T>>,\n}\n\nimpl<'a, 'bump, T: 'a + 'bump + fmt::Debug> fmt::Debug for Drain<'a, 'bump, T> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.debug_tuple(\"Drain\").field(&self.iter.as_slice()).finish()\n    }\n}\n\nunsafe impl<'a, 'bump, T: Sync> Sync for Drain<'a, 'bump, T> {}\nunsafe impl<'a, 'bump, T: Send> Send for Drain<'a, 'bump, T> {}\n\nimpl<'a, 'bump, T> Iterator for Drain<'a, 'bump, T> {\n    type Item = T;\n\n    #[inline]\n    fn next(&mut self) -> Option<T> {\n        self.iter\n            .next()\n            .map(|elt| unsafe { ptr::read(elt as *const _) })\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.iter.size_hint()\n    }\n}\n\nimpl<'a, 'bump, T> DoubleEndedIterator for Drain<'a, 'bump, T> {\n    #[inline]\n    fn next_back(&mut self) -> Option<T> {\n        self.iter\n            .next_back()\n            .map(|elt| unsafe { ptr::read(elt as *const _) })\n    }\n}\n\nimpl<'a, 'bump, T> Drop for Drain<'a, 'bump, T> {\n    fn drop(&mut self) {\n        // exhaust self first\n        self.for_each(drop);\n\n        if self.tail_len > 0 {\n            unsafe {\n                let source_vec = self.vec.as_mut();\n                // memmove back untouched tail, update to new length\n                let start = source_vec.len();\n                let tail = self.tail_start;\n                if tail != start {\n                    let src = source_vec.as_ptr().add(tail);\n                    let dst = source_vec.as_mut_ptr().add(start);\n                    ptr::copy(src, dst, self.tail_len);\n                }\n                source_vec.set_len(start + self.tail_len);\n            }\n        }\n    }\n}\n\nimpl<'a, 'bump, T> ExactSizeIterator for Drain<'a, 'bump, T> {}\n\nimpl<'a, 'bump, T> FusedIterator for Drain<'a, 'bump, T> {}\n\n/// A splicing iterator for `Vec`.\n///\n/// This struct is created by the [`Vec::splice`] method. See its\n/// documentation for more information.\n#[derive(Debug)]\npub struct Splice<'a, 'bump, I>\nwhere\n    I: Iterator,\n    I::Item: 'a + 'bump,\n{\n    drain: Drain<'a, 'bump, I::Item>,\n    replace_with: I,\n}\n\nimpl<'a, 'bump, I: Iterator> Iterator for Splice<'a, 'bump, I> {\n    type Item = I::Item;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.drain.next()\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.drain.size_hint()\n    }\n}\n\nimpl<'a, 'bump, I: Iterator> DoubleEndedIterator for Splice<'a, 'bump, I> {\n    fn next_back(&mut self) -> Option<Self::Item> {\n        self.drain.next_back()\n    }\n}\n\nimpl<'a, 'bump, I: Iterator> ExactSizeIterator for Splice<'a, 'bump, I> {}\n\nimpl<'a, 'bump, I: Iterator> Drop for Splice<'a, 'bump, I> {\n    fn drop(&mut self) {\n        self.drain.by_ref().for_each(drop);\n\n        unsafe {\n            if self.drain.tail_len == 0 {\n                self.drain.vec.as_mut().extend(self.replace_with.by_ref());\n                return;\n            }\n\n            // First fill the range left by drain().\n            if !self.drain.fill(&mut self.replace_with) {\n                return;\n            }\n\n            // There may be more elements. Use the lower bound as an estimate.\n            // FIXME: Is the upper bound a better guess? Or something else?\n            let (lower_bound, _upper_bound) = self.replace_with.size_hint();\n            if lower_bound > 0 {\n                self.drain.move_tail(lower_bound);\n                if !self.drain.fill(&mut self.replace_with) {\n                    return;\n                }\n            }\n\n            // Collect any remaining elements.\n            // This is a zero-length vector which does not allocate if `lower_bound` was exact.\n            let mut collected = Vec::new_in(self.drain.vec.as_ref().buf.bump());\n            collected.extend(self.replace_with.by_ref());\n            let mut collected = collected.into_iter();\n            // Now we have an exact count.\n            if collected.len() > 0 {\n                self.drain.move_tail(collected.len());\n                let filled = self.drain.fill(&mut collected);\n                debug_assert!(filled);\n                debug_assert_eq!(collected.len(), 0);\n            }\n        }\n        // Let `Drain::drop` move the tail back if necessary and restore `vec.len`.\n    }\n}\n\n/// Private helper methods for `Splice::drop`\nimpl<'a, 'bump, T> Drain<'a, 'bump, T> {\n    /// The range from `self.vec.len` to `self.tail_start` contains elements\n    /// that have been moved out.\n    /// Fill that range as much as possible with new elements from the `replace_with` iterator.\n    /// Return whether we filled the entire range. (`replace_with.next()` didn’t return `None`.)\n    unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {\n        let vec = self.vec.as_mut();\n        let range_start = vec.len;\n        let range_end = self.tail_start;\n        let range_slice =\n            slice::from_raw_parts_mut(vec.as_mut_ptr().add(range_start), range_end - range_start);\n\n        for place in range_slice {\n            if let Some(new_item) = replace_with.next() {\n                ptr::write(place, new_item);\n                vec.len += 1;\n            } else {\n                return false;\n            }\n        }\n        true\n    }\n\n    /// Make room for inserting more elements before the tail.\n    unsafe fn move_tail(&mut self, extra_capacity: usize) {\n        let vec = self.vec.as_mut();\n        let used_capacity = self.tail_start + self.tail_len;\n        vec.buf.reserve(used_capacity, extra_capacity);\n\n        let new_tail_start = self.tail_start + extra_capacity;\n        let src = vec.as_ptr().add(self.tail_start);\n        let dst = vec.as_mut_ptr().add(new_tail_start);\n        ptr::copy(src, dst, self.tail_len);\n        self.tail_start = new_tail_start;\n    }\n}\n\n/// An iterator produced by calling [`Vec::drain_filter`].\n#[derive(Debug)]\npub struct DrainFilter<'a, 'bump: 'a, T: 'a + 'bump, F>\nwhere\n    F: FnMut(&mut T) -> bool,\n{\n    vec: &'a mut Vec<'bump, T>,\n    pred: F,\n\n    // Iteration index.\n    idx: usize,\n    // Index to write kept items into.\n    write: usize,\n    // The original length.\n    old_len: usize,\n}\n\nimpl<'a, 'bump, T, F> Iterator for DrainFilter<'a, 'bump, T, F>\nwhere\n    F: FnMut(&mut T) -> bool,\n{\n    type Item = T;\n\n    fn next(&mut self) -> Option<T> {\n        debug_assert_eq!(self.vec.len(), 0);\n        debug_assert!(self.write <= self.idx);\n        unsafe {\n            while self.idx != self.old_len {\n                let i = self.idx;\n                self.idx += 1;\n                let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len);\n                if (self.pred)(&mut v[i]) {\n                    return Some(ptr::read(&v[i]));\n                } else {\n                    if i != self.write {\n                        let src: *const T = &v[i];\n                        let dst: *mut T = &mut v[self.write];\n                        ptr::copy_nonoverlapping(src, dst, 1);\n                    }\n                    self.write += 1;\n                }\n            }\n            None\n        }\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        (0, Some(self.old_len - self.idx))\n    }\n}\n\nimpl<'a, 'bump, T, F> Drop for DrainFilter<'a, 'bump, T, F>\nwhere\n    F: FnMut(&mut T) -> bool,\n{\n    fn drop(&mut self) {\n        /// Guard to shift the trailing items into place if the `DrainFilter`'s\n        /// predicate panics, leaving it in a valid state.\n        struct BackshiftOnDrop<'a, 'bump, T> {\n            vec: &'a mut Vec<'bump, T>,\n            idx: usize,\n            write: usize,\n            old_len: usize,\n        }\n\n        impl<T> Drop for BackshiftOnDrop<'_, '_, T> {\n            fn drop(&mut self) {\n                unsafe {\n                    let tail_len = self.old_len - self.idx;\n                    if tail_len > 0 && self.write < self.idx {\n                        let ptr = self.vec.as_mut_ptr();\n                        ptr::copy(ptr.add(self.idx), ptr.add(self.write), tail_len);\n                    }\n                    self.vec.set_len(self.write + tail_len);\n                }\n            }\n        }\n\n        let mut guard = BackshiftOnDrop {\n            vec: self.vec,\n            idx: self.idx,\n            write: self.write,\n            old_len: self.old_len,\n        };\n\n        unsafe {\n            while guard.idx < guard.old_len {\n                let i = guard.idx;\n                let v = slice::from_raw_parts_mut(guard.vec.as_mut_ptr(), guard.old_len);\n                let drained = (self.pred)(&mut v[i]);\n                guard.idx += 1;\n                if drained {\n                    ptr::drop_in_place(&mut v[i]);\n                } else {\n                    if i != guard.write {\n                        let src: *const T = &v[i];\n                        let dst: *mut T = &mut v[guard.write];\n                        ptr::copy_nonoverlapping(src, dst, 1);\n                    }\n                    guard.write += 1;\n                }\n            }\n        }\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl<'bump> io::Write for Vec<'bump, u8> {\n    #[inline]\n    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n        self.extend_from_slice_copy(buf);\n        Ok(buf.len())\n    }\n\n    #[inline]\n    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {\n        self.extend_from_slice_copy(buf);\n        Ok(())\n    }\n\n    #[inline]\n    fn flush(&mut self) -> io::Result<()> {\n        Ok(())\n    }\n}\n\n#[cfg(feature = \"serde\")]\nmod serialize {\n    use super::*;\n\n    use serde::{ser::SerializeSeq, Serialize, Serializer};\n\n    impl<'a, T> Serialize for Vec<'a, T>\n    where\n        T: Serialize,\n    {\n        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n        where\n            S: Serializer,\n        {\n            let mut seq = serializer.serialize_seq(Some(self.len))?;\n            for e in self.iter() {\n                seq.serialize_element(e)?;\n            }\n            seq.end()\n        }\n    }\n}\n"
    },
    {
      "package": "bytes@1.5.0",
      "sourcePath": "README.md",
      "sha256": "c1b2b54999d4829f9f64fb41cbdf05a72d565be0dd078a8633d34631147498a1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# Bytes\n\nA utility library for working with bytes.\n\n[![Crates.io][crates-badge]][crates-url]\n[![Build Status][ci-badge]][ci-url]\n\n[crates-badge]: https://img.shields.io/crates/v/bytes.svg\n[crates-url]: https://crates.io/crates/bytes\n[ci-badge]: https://github.com/tokio-rs/bytes/workflows/CI/badge.svg\n[ci-url]: https://github.com/tokio-rs/bytes/actions\n\n[Documentation](https://docs.rs/bytes)\n\n## Usage\n\nTo use `bytes`, first add this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nbytes = \"1\"\n```\n\nNext, add this to your crate:\n\n```rust\nuse bytes::{Bytes, BytesMut, Buf, BufMut};\n```\n\n## Serde support\n\nSerde support is optional and disabled by default. To enable use the feature `serde`.\n\n```toml\n[dependencies]\nbytes = { version = \"1\", features = [\"serde\"] }\n```\n\n## Building documentation\n\nWhen building the `bytes` documentation the `docsrs` option should be used, otherwise\nfeature gates will not be shown. This requires a nightly toolchain:\n\n```\nRUSTDOCFLAGS=\"--cfg docsrs\" cargo +nightly doc\n```\n\n## License\n\nThis project is licensed under the [MIT license](LICENSE).\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in `bytes` by you, shall be licensed as MIT, without any additional\nterms or conditions.\n"
    },
    {
      "package": "cc@1.4.7",
      "sourcePath": "README.md",
      "sha256": "cc952a506dc726eed3e128d47d62defbac4470bbb0e465f6a043ae8bf0c96d19",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# cc-rs\n\nA library for\n[Cargo build scripts](https://doc.rust-lang.org/cargo/reference/build-scripts.html)\nto compile a set of C/C++/assembly/CUDA files into a static archive for Cargo to\nlink into the crate being built. This crate does not compile code itself; it\ncalls out to the default compiler for the platform. This crate will\nautomatically detect situations such as cross compilation and various\nenvironment variables and will build code appropriately.\n\nRefer to the [documentation](https://docs.rs/cc) for detailed usage\ninstructions.\n\n## License\n\nThis project is licensed under either of\n\n * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\n   https://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or\n   https://opensource.org/license/mit)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in cc-rs by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "cfg-if@1.0.5",
      "sourcePath": "README.md",
      "sha256": "d16553c2dc0028d196c2ceb82e1685932061daacd3e0240339d9e393695c1e71",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# cfg-if\n\n> [!WARNING]\n> This crate has been \"replaced\" by the [`cfg_select!`] macro, which is stable since Rust 1.95.0 with a slightly different syntax. Barring breakages and security fixes, this crate will no longer be updated.\n\n[`cfg_select!`]: https://doc.rust-lang.org/std/macro.cfg_select.html\n\n[Documentation](https://docs.rs/cfg-if)\n\nA macro to ergonomically define an item depending on a large number of #[cfg]\nparameters. Structured like an if-else chain, the first matching branch is the\nitem that gets emitted.\n\n```toml\n[dependencies]\ncfg-if = \"1.0\"\n```\n\n## Example\n\n```rust\ncfg_if::cfg_if! {\n    if #[cfg(unix)] {\n        fn foo() { /* unix specific functionality */ }\n    } else if #[cfg(target_pointer_width = \"32\")] {\n        fn foo() { /* non-unix, 32-bit functionality */ }\n    } else {\n        fn foo() { /* fallback implementation */ }\n    }\n}\n\nfn main() {\n    foo();\n}\n```\nThe `cfg_if!` block above is expanded to:\n```rust\n#[cfg(unix)]\nfn foo() { /* unix specific functionality */ }\n#[cfg(all(target_pointer_width = \"32\", not(unix)))]\nfn foo() { /* non-unix, 32-bit functionality */ }\n#[cfg(not(any(unix, target_pointer_width = \"32\")))]\nfn foo() { /* fallback implementation */ }\n```\n\n# License\n\nThis project is licensed under either of\n\n * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\n   https://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or\n   https://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in `cfg-if` by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "color_quant@1.1.0",
      "sourcePath": "src/lib.rs",
      "sha256": "17a7ed7a6c994b475976558f3492c8890d089c1ee19f4ea3cd246c28145c895a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/*\nNeuQuant Neural-Net Quantization Algorithm by Anthony Dekker, 1994.\nSee \"Kohonen neural networks for optimal colour quantization\"\nin \"Network: Computation in Neural Systems\" Vol. 5 (1994) pp 351-367.\nfor a discussion of the algorithm.\nSee also http://members.ozemail.com.au/~dekker/NEUQUANT.HTML\n\nIncorporated bugfixes and alpha channel handling from pngnq\nhttp://pngnq.sourceforge.net\n\nCopyright (c) 2014 The Piston Developers\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\nNeuQuant Neural-Net Quantization Algorithm\n------------------------------------------\n\nCopyright (c) 1994 Anthony Dekker\n\nNEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.\nSee \"Kohonen neural networks for optimal colour quantization\"\nin \"Network: Computation in Neural Systems\" Vol. 5 (1994) pp 351-367.\nfor a discussion of the algorithm.\nSee also  http://members.ozemail.com.au/~dekker/NEUQUANT.HTML\n\nAny party obtaining a copy of these files from the author, directly or\nindirectly, is granted, free of charge, a full and unrestricted irrevocable,\nworld-wide, paid up, royalty-free, nonexclusive right and license to deal\nin this software and documentation files (the \"Software\"), including without\nlimitation the rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons who receive\ncopies from any such party to do so, with the only requirement being\nthat this copyright notice remain intact.\n\n*/\n\n//! # Color quantization library\n//!\n//! This library provides a color quantizer based on the [NEUQUANT](http://members.ozemail.com.au/~dekker/NEUQUANT.HTML)\n//!\n//! Original literature: Dekker, A. H. (1994). Kohonen neural networks for\n//! optimal colour quantization. *Network: Computation in Neural Systems*, 5(3), 351-367.\n//! [doi: 10.1088/0954-898X_5_3_003](https://doi.org/10.1088/0954-898X_5_3_003)\n//!\n//! See also <https://scientificgems.wordpress.com/stuff/neuquant-fast-high-quality-image-quantization/>\n//!\n//! ## Usage\n//!\n//! ```\n//! let data = vec![0; 40];\n//! let nq = color_quant::NeuQuant::new(10, 256, &data);\n//! let indixes: Vec<u8> = data.chunks(4).map(|pix| nq.index_of(pix) as u8).collect();\n//! let color_map = nq.color_map_rgba();\n//! ```\n\nmod math;\nuse crate::math::clamp;\n\nuse std::cmp::{max, min};\n\nconst CHANNELS: usize = 4;\n\nconst RADIUS_DEC: i32 = 30; // factor of 1/30 each cycle\n\nconst ALPHA_BIASSHIFT: i32 = 10; // alpha starts at 1\nconst INIT_ALPHA: i32 = 1 << ALPHA_BIASSHIFT; // biased by 10 bits\n\nconst GAMMA: f64 = 1024.0;\nconst BETA: f64 = 1.0 / GAMMA;\nconst BETAGAMMA: f64 = BETA * GAMMA;\n\n// four primes near 500 - assume no image has a length so large\n// that it is divisible by all four primes\nconst PRIMES: [usize; 4] = [499, 491, 478, 503];\n\n#[derive(Clone, Copy)]\nstruct Quad<T> {\n    r: T,\n    g: T,\n    b: T,\n    a: T,\n}\n\ntype Neuron = Quad<f64>;\ntype Color = Quad<i32>;\n\npub struct NeuQuant {\n    network: Vec<Neuron>,\n    colormap: Vec<Color>,\n    netindex: Vec<usize>,\n    bias: Vec<f64>, // bias and freq arrays for learning\n    freq: Vec<f64>,\n    samplefac: i32,\n    netsize: usize,\n}\n\nimpl NeuQuant {\n    /// Creates a new neuronal network and trains it with the supplied data.\n    ///\n    /// Pixels are assumed to be in RGBA format.\n    /// `colors` should be $>=64$. `samplefac` determines the faction of\n    /// the sample that will be used to train the network. Its value must be in the\n    /// range $[1, 30]$. A value of $1$ thus produces the best result but is also\n    /// slowest. $10$ is a good compromise between speed and quality.\n    pub fn new(samplefac: i32, colors: usize, pixels: &[u8]) -> Self {\n        let netsize = colors;\n        let mut this = NeuQuant {\n            network: Vec::with_capacity(netsize),\n            colormap: Vec::with_capacity(netsize),\n            netindex: vec![0; 256],\n            bias: Vec::with_capacity(netsize),\n            freq: Vec::with_capacity(netsize),\n            samplefac: samplefac,\n            netsize: colors,\n        };\n        this.init(pixels);\n        this\n    }\n\n    /// Initializes the neuronal network and trains it with the supplied data.\n    ///\n    /// This method gets called by `Self::new`.\n    pub fn init(&mut self, pixels: &[u8]) {\n        self.network.clear();\n        self.colormap.clear();\n        self.bias.clear();\n        self.freq.clear();\n        let freq = (self.netsize as f64).recip();\n        for i in 0..self.netsize {\n            let tmp = (i as f64) * 256.0 / (self.netsize as f64);\n            // Sets alpha values at 0 for dark pixels.\n            let a = if i < 16 { i as f64 * 16.0 } else { 255.0 };\n            self.network.push(Neuron {\n                r: tmp,\n                g: tmp,\n                b: tmp,\n                a: a,\n            });\n            self.colormap.push(Color {\n                r: 0,\n                g: 0,\n                b: 0,\n                a: 255,\n            });\n            self.freq.push(freq);\n            self.bias.push(0.0);\n        }\n        self.learn(pixels);\n        self.build_colormap();\n        self.build_netindex();\n    }\n\n    /// Maps the rgba-pixel in-place to the best-matching color in the color map.\n    #[inline(always)]\n    pub fn map_pixel(&self, pixel: &mut [u8]) {\n        assert!(pixel.len() == 4);\n        let (r, g, b, a) = (pixel[0], pixel[1], pixel[2], pixel[3]);\n        let i = self.search_netindex(b, g, r, a);\n        pixel[0] = self.colormap[i].r as u8;\n        pixel[1] = self.colormap[i].g as u8;\n        pixel[2] = self.colormap[i].b as u8;\n        pixel[3] = self.colormap[i].a as u8;\n    }\n\n    /// Finds the best-matching index in the color map.\n    ///\n    /// `pixel` is assumed to be in RGBA format.\n    #[inline(always)]\n    pub fn index_of(&self, pixel: &[u8]) -> usize {\n        assert!(pixel.len() == 4);\n        let (r, g, b, a) = (pixel[0], pixel[1], pixel[2], pixel[3]);\n        self.search_netindex(b, g, r, a)\n    }\n\n    /// Lookup pixel values for color at `idx` in the colormap.\n    pub fn lookup(&self, idx: usize) -> Option<[u8; 4]> {\n        self.colormap\n            .get(idx)\n            .map(|p| [p.r as u8, p.g as u8, p.b as u8, p.a as u8])\n    }\n\n    /// Returns the RGBA color map calculated from the sample.\n    pub fn color_map_rgba(&self) -> Vec<u8> {\n        let mut map = Vec::with_capacity(self.netsize * 4);\n        for entry in &self.colormap {\n            map.push(entry.r as u8);\n            map.push(entry.g as u8);\n            map.push(entry.b as u8);\n            map.push(entry.a as u8);\n        }\n        map\n    }\n\n    /// Returns the RGBA color map calculated from the sample.\n    pub fn color_map_rgb(&self) -> Vec<u8> {\n        let mut map = Vec::with_capacity(self.netsize * 3);\n        for entry in &self.colormap {\n            map.push(entry.r as u8);\n            map.push(entry.g as u8);\n            map.push(entry.b as u8);\n        }\n        map\n    }\n\n    /// Move neuron i towards biased (a,b,g,r) by factor alpha\n    fn salter_single(&mut self, alpha: f64, i: i32, quad: Quad<f64>) {\n        let n = &mut self.network[i as usize];\n        n.b -= alpha * (n.b - quad.b);\n        n.g -= alpha * (n.g - quad.g);\n        n.r -= alpha * (n.r - quad.r);\n        n.a -= alpha * (n.a - quad.a);\n    }\n\n    /// Move neuron adjacent neurons towards biased (a,b,g,r) by factor alpha\n    fn alter_neighbour(&mut self, alpha: f64, rad: i32, i: i32, quad: Quad<f64>) {\n        let lo = max(i - rad, 0);\n        let hi = min(i + rad, self.netsize as i32);\n        let mut j = i + 1;\n        let mut k = i - 1;\n        let mut q = 0;\n\n        while (j < hi) || (k > lo) {\n            let rad_sq = rad as f64 * rad as f64;\n            let alpha = (alpha * (rad_sq - q as f64 * q as f64)) / rad_sq;\n            q += 1;\n            if j < hi {\n                let p = &mut self.network[j as usize];\n                p.b -= alpha * (p.b - quad.b);\n                p.g -= alpha * (p.g - quad.g);\n                p.r -= alpha * (p.r - quad.r);\n                p.a -= alpha * (p.a - quad.a);\n                j += 1;\n            }\n            if k > lo {\n                let p = &mut self.network[k as usize];\n                p.b -= alpha * (p.b - quad.b);\n                p.g -= alpha * (p.g - quad.g);\n                p.r -= alpha * (p.r - quad.r);\n                p.a -= alpha * (p.a - quad.a);\n                k -= 1;\n            }\n        }\n    }\n\n    /// Search for biased BGR values\n    /// finds closest neuron (min dist) and updates freq\n    /// finds best neuron (min dist-bias) and returns position\n    /// for frequently chosen neurons, freq[i] is high and bias[i] is negative\n    /// bias[i] = gamma*((1/self.netsize)-freq[i])\n    fn contest(&mut self, b: f64, g: f64, r: f64, a: f64) -> i32 {\n        use std::f64;\n\n        let mut bestd = f64::MAX;\n        let mut bestbiasd: f64 = bestd;\n        let mut bestpos = -1;\n        let mut bestbiaspos: i32 = bestpos;\n\n        for i in 0..self.netsize {\n            let bestbiasd_biased = bestbiasd + self.bias[i];\n            let mut dist;\n            let n = &self.network[i];\n            dist = (n.b - b).abs();\n            dist += (n.r - r).abs();\n            if dist < bestd || dist < bestbiasd_biased {\n                dist += (n.g - g).abs();\n                dist += (n.a - a).abs();\n                if dist < bestd {\n                    bestd = dist;\n                    bestpos = i as i32;\n                }\n                let biasdist = dist - self.bias[i];\n                if biasdist < bestbiasd {\n                    bestbiasd = biasdist;\n                    bestbiaspos = i as i32;\n                }\n            }\n            self.freq[i] -= BETA * self.freq[i];\n            self.bias[i] += BETAGAMMA * self.freq[i];\n        }\n        self.freq[bestpos as usize] += BETA;\n        self.bias[bestpos as usize] -= BETAGAMMA;\n        return bestbiaspos;\n    }\n\n    /// Main learning loop\n    /// Note: the number of learning cycles is crucial and the parameters are not\n    /// optimized for net sizes < 26 or > 256. 1064 colors seems to work fine\n    fn learn(&mut self, pixels: &[u8]) {\n        let initrad: i32 = self.netsize as i32 / 8; // for 256 cols, radius starts at 32\n        let radiusbiasshift: i32 = 6;\n        let radiusbias: i32 = 1 << radiusbiasshift;\n        let init_bias_radius: i32 = initrad * radiusbias;\n        let mut bias_radius = init_bias_radius;\n        let alphadec = 30 + ((self.samplefac - 1) / 3);\n        let lengthcount = pixels.len() / CHANNELS;\n        let samplepixels = lengthcount / self.samplefac as usize;\n        // learning cycles\n        let n_cycles = match self.netsize >> 1 {\n            n if n <= 100 => 100,\n            n => n,\n        };\n        let delta = match samplepixels / n_cycles {\n            0 => 1,\n            n => n,\n        };\n        let mut alpha = INIT_ALPHA;\n\n        let mut rad = bias_radius >> radiusbiasshift;\n        if rad <= 1 {\n            rad = 0\n        };\n\n        let mut pos = 0;\n        let step = *PRIMES\n            .iter()\n            .find(|&&prime| lengthcount % prime != 0)\n            .unwrap_or(&PRIMES[3]);\n\n        let mut i = 0;\n        while i < samplepixels {\n            let (r, g, b, a) = {\n                let p = &pixels[CHANNELS * pos..][..CHANNELS];\n                (p[0] as f64, p[1] as f64, p[2] as f64, p[3] as f64)\n            };\n\n            let j = self.contest(b, g, r, a);\n\n            let alpha_ = (1.0 * alpha as f64) / INIT_ALPHA as f64;\n            self.salter_single(alpha_, j, Quad { b, g, r, a });\n            if rad > 0 {\n                self.alter_neighbour(alpha_, rad, j, Quad { b, g, r, a })\n            };\n\n            pos += step;\n            while pos >= lengthcount {\n                pos -= lengthcount\n            }\n\n            i += 1;\n            if i % delta == 0 {\n                alpha -= alpha / alphadec;\n                bias_radius -= bias_radius / RADIUS_DEC;\n                rad = bias_radius >> radiusbiasshift;\n                if rad <= 1 {\n                    rad = 0\n                };\n            }\n        }\n    }\n\n    /// initializes the color map\n    fn build_colormap(&mut self) {\n        for i in 0usize..self.netsize {\n            self.colormap[i].b = clamp(self.network[i].b.round() as i32);\n            self.colormap[i].g = clamp(self.network[i].g.round() as i32);\n            self.colormap[i].r = clamp(self.network[i].r.round() as i32);\n            self.colormap[i].a = clamp(self.network[i].a.round() as i32);\n        }\n    }\n\n    /// Insertion sort of network and building of netindex[0..255]\n    fn build_netindex(&mut self) {\n        let mut previouscol = 0;\n        let mut startpos = 0;\n\n        for i in 0..self.netsize {\n            let mut p = self.colormap[i];\n            let mut q;\n            let mut smallpos = i;\n            let mut smallval = p.g as usize; // index on g\n                                             // find smallest in i..netsize-1\n            for j in (i + 1)..self.netsize {\n                q = self.colormap[j];\n                if (q.g as usize) < smallval {\n                    // index on g\n                    smallpos = j;\n                    smallval = q.g as usize; // index on g\n                }\n            }\n            q = self.colormap[smallpos];\n            // swap p (i) and q (smallpos) entries\n            if i != smallpos {\n                ::std::mem::swap(&mut p, &mut q);\n                self.colormap[i] = p;\n                self.colormap[smallpos] = q;\n            }\n            // smallval entry is now in position i\n            if smallval != previouscol {\n                self.netindex[previouscol] = (startpos + i) >> 1;\n                for j in (previouscol + 1)..smallval {\n                    self.netindex[j] = i\n                }\n                previouscol = smallval;\n                startpos = i;\n            }\n        }\n        let max_netpos = self.netsize - 1;\n        self.netindex[previouscol] = (startpos + max_netpos) >> 1;\n        for j in (previouscol + 1)..256 {\n            self.netindex[j] = max_netpos\n        } // really 256\n    }\n\n    /// Search for best matching color\n    fn search_netindex(&self, b: u8, g: u8, r: u8, a: u8) -> usize {\n        let mut bestd = 1 << 30; // ~ 1_000_000\n        let mut best = 0;\n        // start at netindex[g] and work outwards\n        let mut i = self.netindex[g as usize];\n        let mut j = if i > 0 { i - 1 } else { 0 };\n\n        while (i < self.netsize) || (j > 0) {\n            if i < self.netsize {\n                let p = self.colormap[i];\n                let mut e = p.g - g as i32;\n                let mut dist = e * e; // inx key\n                if dist >= bestd {\n                    break;\n                } else {\n                    e = p.b - b as i32;\n                    dist += e * e;\n                    if dist < bestd {\n                        e = p.r - r as i32;\n                        dist += e * e;\n                        if dist < bestd {\n                            e = p.a - a as i32;\n                            dist += e * e;\n                            if dist < bestd {\n                                bestd = dist;\n                                best = i;\n                            }\n                        }\n                    }\n                    i += 1;\n                }\n            }\n            if j > 0 {\n                let p = self.colormap[j];\n                let mut e = p.g - g as i32;\n                let mut dist = e * e; // inx key\n                if dist >= bestd {\n                    break;\n                } else {\n                    e = p.b - b as i32;\n                    dist += e * e;\n                    if dist < bestd {\n                        e = p.r - r as i32;\n                        dist += e * e;\n                        if dist < bestd {\n                            e = p.a - a as i32;\n                            dist += e * e;\n                            if dist < bestd {\n                                bestd = dist;\n                                best = j;\n                            }\n                        }\n                    }\n                    j -= 1;\n                }\n            }\n        }\n        best\n    }\n}\n"
    },
    {
      "package": "colorchoice@1.0.5",
      "sourcePath": "README.md",
      "sha256": "fc9b47302f5a3244b4e447e5bf6f86a35c64a16bd1abef8c27f31c4b5abac7a2",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# colorchoice\n\n> Global override of color control\n\n[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation]\n![License](https://img.shields.io/crates/l/colorchoice.svg)\n[![Crates Status](https://img.shields.io/crates/v/colorchoice.svg)](https://crates.io/crates/colorchoice)\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/license/mit>)\n\nat your option.\n\n## [Contribute](../../CONTRIBUTING.md)\n\nSpecial note: to be successful, this crate **cannot** break compatibility or\nelse different crates in the hierarchy will be reading different globals.\nWhile end users can work around this, it isn't ideal.    If we need a new API, we can make\nthe old API an adapter to the new logic.\n\nSimilarly, we should strive to reduce **risk** of breaking compatibility by\nexposing as little as possible.  Anything more should be broken out into a\nseparate crate that this crate can call into.\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual-licensed as above, without any additional terms or\nconditions.\n\n[Documentation]: https://docs.rs/colorchoice\n"
    },
    {
      "package": "convert_case@0.6.0",
      "sourcePath": "README.md",
      "sha256": "6bb2369385222ffa8bb09c5e70e8e58fda1b3d46ee165749f15bcffc3da415f4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# Convert Case\n\nConverts to and from various cases.\n\n## Rust Library `convert_case`\n\nConvert case was written in Rust and is ready to be used inline with your rust code as a library.\n```{rust}\nuse convert_case::{Case, Casing};\n\nassert_eq!(\"ronnieJamesDio\", \"Ronnie_James_dio\".to_case(Case::Camel));\nassert_eq!(\"io_stream\", \"IOStream\".to_case(Case::Snake));\nassert_eq!(\n    \"2020-04-16 My Cat Cali\",\n    \"2020-04-16_my_cat_cali\".from_case(Case::Snake).to_case(Case::Title)\n);\n```\nYou can read the API documentation on [docs.rs](https://docs.rs/convert_case/) for a list of all features and read lots of examples.\n\n## Command Line Utility `ccase`\n\nThe command line utility `ccase` was made to leverage the tools in the `convert_case` library.\n```\n$ ccase -t title super_mario_64\nSuper Mario 64\n\n$ ccase -f snake -t title 2020-04-15_my_cat_cali\n2020-04-16 My Cat Cali\n\n$ ccase -t camel \"convert to camel\"\nconvertToCamel\n```\n\nYou can read more about the `ccase` executable in the [`ccase` directory](https://github.com/rutrum/convert-case/tree/master/ccase) within this repository.\n\n## Links\n\n| | `convert_case` | `ccase` |\n| --- | --- | --- |\n| Repository | [github](https://github.com/rutrum/convert-case) | [github](https://github.com/rutrum/convert-case/tree/master/ccase) |\n| Crate | [crates.io](https://crates.io/crates/convert_case) | [crates.io](https://crates.io/crates/ccase) |\n| Documentation | [docs.rs](https://docs.rs/convert_case) | |\n\n## Cases\n\nThis is list of cases that convert\\_case supports.  Some cases are simply aliases of others.  The \"Random\" and \"PseudoRandom\" cases are provided in the `convert_case` library with the \"random\" feature, and are automatically provided in the `ccase` binary.\n\n| Case | Example |\n| ---- | ------- |\n| Upper | MY VARIABLE NAME |\n| Lower | my variable name |\n| Title | My Variable Name |\n| Toggle | mY vARIABLE nAME |\n| Alternating | mY vArIaBlE nAmE |\n| Camel | myVariableName |\n| Pascal | MyVariableName |\n| UpperCamel | MyVariableName |\n| Snake | my\\_variable\\_name |\n| UpperSnake | MY\\_VARIABLE\\_NAME |\n| ScreamingSnake | MY\\_VARIABLE\\_NAME |\n| Kebab | my-variable-name |\n| Cobol | MY-VARIABLE-NAME |\n| Train | My-Variable-Name |\n| Flat | myvariablename |\n| UpperFlat | MYVARIABLENAME |\n| Random | MY vaRiabLe nAME |\n| PseudoRandom | mY VaRiAblE nAMe |\n\n## License\n\nLicensed under [MIT License](./LICENSE).\n"
    },
    {
      "package": "crc32fast@1.5.2",
      "sourcePath": "README.md",
      "sha256": "cc3944235f56e3fa42d98197f4a461ebeb0cd46bcb5a4d0f1506079c93d43c34",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# crc32fast [![Build Status][build-img]][build] [![Crates.io][crates-img]][crates] [![Documentation][docs-img]][docs]\n\n[build-img]: https://github.com/srijs/rust-crc32fast/actions/workflows/ci.yml/badge.svg\n[build]: https://github.com/srijs/rust-crc32fast/actions/workflows/ci.yml\n[crates-img]: https://img.shields.io/crates/v/crc32fast.svg\n[crates]: https://crates.io/crates/crc32fast\n[docs-img]: https://docs.rs/crc32fast/badge.svg\n[docs]: https://docs.rs/crc32fast\n\n_Fast, SIMD-accelerated CRC32 (IEEE) checksum computation_\n\n## Usage\n\n### Simple usage\n\nFor simple use-cases, you can call the `hash` convenience function to\ndirectly compute the CRC32 checksum for a given byte slice:\n\n```rust\nlet checksum = crc32fast::hash(b\"foo bar baz\");\n```\n\n### Advanced usage\n\nFor use-cases that require more flexibility or performance, for example when\nprocessing large amounts of data, you can create and manipulate a `Hasher`:\n\n```rust\nuse crc32fast::Hasher;\n\nlet mut hasher = Hasher::new();\nhasher.update(b\"foo bar baz\");\nlet checksum = hasher.finalize();\n```\n\n## Performance\n\nThis crate contains multiple CRC32 implementations:\n\n- A fast baseline implementation which processes up to 16 bytes per iteration\n- An optimized implementation for modern `x86` using `sse` and `pclmulqdq` instructions\n- Wider `x86` implementations using `vpclmulqdq` on 256-bit (`avx2`) and 512-bit (`avx512f`)\n  registers, folding many independent streams per instruction (compiled with Rust 1.89+; the\n  crate's minimum supported Rust version is otherwise unchanged)\n- An optimized implementation for `aarch64` using `crc32` instructions, with a 3-way interleaved\n  variant that hides instruction latency on larger inputs\n\nCalling the `Hasher::new` constructor at runtime will perform a feature detection to select the most\noptimal implementation for the current CPU feature set.\n\n| crate                               | version | variant   | ns/iter | MB/s |\n| ----------------------------------- | ------- | --------- | ------- | ---- |\n| [crc](https://crates.io/crates/crc) | 1.8.1   | n/a       | 4,926   | 207  |\n| crc32fast (this crate)              | 1.0.0   | baseline  | 683     | 1499 |\n| crc32fast (this crate)              | 1.0.0   | pclmulqdq | 140     | 7314 |\n\n## Memory Safety\n\nDue to the use of SIMD intrinsics for the optimized implementations, this crate contains some amount of `unsafe` code.\n\nIn order to ensure memory safety, the relevant code has been fuzz tested using `libFuzzer` (via [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz)) with millions of iterations in both `debug` and `release` build settings. You can inspect the test setup in the `fuzz` sub-directory, which also has instructions on how to run the tests yourself.\n\nOn top of that, every commit is tested using an address sanitizer in CI to catch any out of bounds memory accesses.\n\nEven though neither fuzzing nor sanitization has revealed any safety bugs yet, please don't hesitate to file an issue if you run into any crashes or other unexpected behaviour.\n\n## Available feature flags\n\n### `std` (default: enabled)\n\nThis library supports being built without the Rust `std` library, which is useful for low-level use-cases such as embedded where no operating system is available. To build the crate in a `no_std` context, disable the default `std` feature.\n\nNote: Because runtime CPU feature detection requires OS support, the specialized SIMD implementations will be unavailable when the `std` feature is disabled.\n\n### `nightly` (default: disabled)\n\nThis feature flag enables unstable features that are only available on the `nightly` channel. Keep in mind that when enabling this feature flag, you\nmight experience breaking changes when updating compiler versions.\n\n## License\n\nThis project is licensed under either of\n\n- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\n  https://www.apache.org/licenses/LICENSE-2.0)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or\n  https://opensource.org/license/mit)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this project by you, as defined in the Apache-2.0 license,\nshall be dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "deflate@1.0.0",
      "sourcePath": "src/bitstream.rs",
      "sha256": "5bdde1cdbc1d29ee2bbfb3040c0f5fcc06599c9ff464cdb6b360cdfa9fed0b9b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// This was originally based on code from: https://github.com/nwin/lzw\n// Copyright (c) 2015 nwin\n// which is under both Apache 2.0 and MIT\n\n//! This module provides a bit writer\nuse std::io::{self, Write};\n\n#[cfg(target_pointer_width = \"64\")]\n#[macro_use]\nmod arch_dep {\n    /// The data type of the accumulator.\n    /// a 64-bit value allows us to store more before\n    /// each push to the vector, but is sub-optimal\n    /// on 32-bit platforms.\n    pub type AccType = u64;\n    pub const FLUSH_AT: u8 = 48;\n    /// Push pending bits to vector.\n    /// Using a macro here since an inline function.\n    /// didn't optimise properly.\n    /// TODO June 2019: See if it's still needed.\n    macro_rules! push {\n        ($s:ident) => {\n            $s.w.extend_from_slice(\n                &[\n                    $s.acc as u8,\n                    ($s.acc >> 8) as u8,\n                    ($s.acc >> 16) as u8,\n                    ($s.acc >> 24) as u8,\n                    ($s.acc >> 32) as u8,\n                    ($s.acc >> 40) as u8,\n                ][..],\n            )\n        };\n    }\n}\n#[cfg(not(target_pointer_width = \"64\"))]\n#[macro_use]\nmod arch_dep {\n    pub type AccType = u32;\n    pub const FLUSH_AT: u8 = 16;\n    macro_rules! push {\n        ($s:ident) => {\n            // Unlike the 64-bit case, using copy_from_slice seemed to worsen performance here.\n            // TODO: Needs benching on a 32-bit system to see what works best.\n            $s.w.push($s.acc as u8);\n            $s.w.push(($s.acc >> 8) as u8);\n        };\n    }\n}\n\nuse self::arch_dep::*;\n\n/// Writes bits to a byte stream, LSB first.\npub struct LsbWriter {\n    // Public for now so it can be replaced after initialization.\n    pub w: Vec<u8>,\n    bits: u8,\n    acc: AccType,\n}\n\nimpl LsbWriter {\n    /// Creates a new bit reader\n    pub const fn new(writer: Vec<u8>) -> LsbWriter {\n        LsbWriter {\n            w: writer,\n            bits: 0,\n            acc: 0,\n        }\n    }\n\n    pub const fn pending_bits(&self) -> u8 {\n        self.bits\n    }\n\n    /// Buffer n number of bits, and write them to the vec if there are enough pending bits.\n    pub fn write_bits(&mut self, v: u16, n: u8) {\n        // NOTE: This outputs garbage data if n is 0, but v is not 0\n        self.acc |= (AccType::from(v)) << self.bits;\n        self.bits += n;\n        // Waiting until we have FLUSH_AT bits and pushing them all in one batch.\n        while self.bits >= FLUSH_AT {\n            push!(self);\n            self.acc >>= FLUSH_AT;\n            self.bits -= FLUSH_AT;\n        }\n    }\n\n    fn write_bits_finish(&mut self, v: u16, n: u8) {\n        // NOTE: This outputs garbage data if n is 0, but v is not 0\n        self.acc |= (AccType::from(v)) << self.bits;\n        self.bits += n % 8;\n        while self.bits >= 8 {\n            self.w.push(self.acc as u8);\n            self.acc >>= 8;\n            self.bits -= 8;\n        }\n    }\n\n    pub fn flush_raw(&mut self) {\n        let missing = FLUSH_AT - self.bits;\n        // Have to test for self.bits > 0 here,\n        // otherwise flush would output an extra byte when flush was called at a byte boundary\n        if missing > 0 && self.bits > 0 {\n            self.write_bits_finish(0, missing);\n        }\n    }\n}\n\nimpl Write for LsbWriter {\n    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n        if self.acc == 0 {\n            self.w.extend_from_slice(buf)\n        } else {\n            for &byte in buf.iter() {\n                self.write_bits(u16::from(byte), 8)\n            }\n        }\n        Ok(buf.len())\n    }\n\n    fn flush(&mut self) -> io::Result<()> {\n        self.flush_raw();\n        Ok(())\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::LsbWriter;\n\n    #[test]\n    fn write_bits() {\n        let input = [\n            (3, 3),\n            (10, 8),\n            (88, 7),\n            (0, 2),\n            (0, 5),\n            (0, 0),\n            (238, 8),\n            (126, 8),\n            (161, 8),\n            (10, 8),\n            (238, 8),\n            (174, 8),\n            (126, 8),\n            (174, 8),\n            (65, 8),\n            (142, 8),\n            (62, 8),\n            (10, 8),\n            (1, 8),\n            (161, 8),\n            (78, 8),\n            (62, 8),\n            (158, 8),\n            (206, 8),\n            (10, 8),\n            (64, 7),\n            (0, 0),\n            (24, 5),\n            (0, 0),\n            (174, 8),\n            (126, 8),\n            (193, 8),\n            (174, 8),\n        ];\n        let expected = [\n            83, 192, 2, 220, 253, 66, 21, 220, 93, 253, 92, 131, 28, 125, 20, 2, 66, 157, 124, 60,\n            157, 21, 128, 216, 213, 47, 216, 21,\n        ];\n        let mut writer = LsbWriter::new(Vec::new());\n        for v in input.iter() {\n            writer.write_bits(v.0, v.1);\n        }\n        writer.flush_raw();\n        assert_eq!(writer.w, expected);\n    }\n}\n\n#[cfg(all(test, feature = \"benchmarks\"))]\nmod bench {\n    use super::LsbWriter;\n    use test_std::Bencher;\n    #[bench]\n    fn bit_writer(b: &mut Bencher) {\n        let input = [\n            (3, 3),\n            (10, 8),\n            (88, 7),\n            (0, 2),\n            (0, 5),\n            (0, 0),\n            (238, 8),\n            (126, 8),\n            (161, 8),\n            (10, 8),\n            (238, 8),\n            (174, 8),\n            (126, 8),\n            (174, 8),\n            (65, 8),\n            (142, 8),\n            (62, 8),\n            (10, 8),\n            (1, 8),\n            (161, 8),\n            (78, 8),\n            (62, 8),\n            (158, 8),\n            (206, 8),\n            (10, 8),\n            (64, 7),\n            (0, 0),\n            (24, 5),\n            (0, 0),\n            (174, 8),\n            (126, 8),\n            (193, 8),\n            (174, 8),\n        ];\n        let mut writer = LsbWriter::new(Vec::with_capacity(100));\n        b.iter(|| {\n            for v in input.iter() {\n                let _ = writer.write_bits(v.0, v.1);\n            }\n        });\n    }\n}\n"
    },
    {
      "package": "defmt@1.1.1",
      "sourcePath": "README.md",
      "sha256": "0869dedb2a47f8ea123e19ad3b68fb56d1be253016687f03d74b5c693416aae4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# `defmt`\n\n`defmt` (\"de format\", short for \"deferred formatting\") is a highly efficient logging framework that targets resource-constrained devices, like microcontrollers.\n\nFor more details about the framework check the book at <https://defmt.ferrous-systems.com>.\n\n## Setup\n\n### New project\n\nThe fastest way to get started with `defmt` is to use our [app-template] to set up a new Cortex-M embedded project.\n\n[app-template]: https://github.com/knurling-rs/app-template\n\n### Existing project\n\nTo include `defmt` in your existing project, follow our [Application Setup guide].\n\n[Application Setup guide]: https://defmt.ferrous-systems.com/setup.html\n\n## MSRV\n\nThe minimum supported Rust version is 1.76 (or Ferrocene 24.05). This crate is tested against the latest stable Rust version and the MSRV.\n\n## Support\n\n`defmt` is part of the [Knurling] project, [Ferrous Systems]' effort at\nimproving tooling used to develop for embedded systems.\n\nIf you think that our work is useful, consider sponsoring it via [GitHub\nSponsors].\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or\n  <http://www.apache.org/licenses/LICENSE-2.0>)\n\n- MIT license ([LICENSE-MIT](../LICENSE-MIT) or <http://opensource.org/licenses/MIT>)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\nlicensed as above, without any additional terms or conditions.\n\n[Knurling]: https://knurling.ferrous-systems.com/\n[Ferrous Systems]: https://ferrous-systems.com/\n[GitHub Sponsors]: https://github.com/sponsors/knurling-rs\n"
    },
    {
      "package": "defmt-macros@1.1.1",
      "sourcePath": "README.md",
      "sha256": "54bca1c967197f21a24c9a6989a67574780aad189149aa21aa363058b5351af5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# `defmt-macros`\n\n`defmt` (\"de format\", short for \"deferred formatting\") is a highly efficient logging framework that targets resource-constrained devices, like microcontrollers.\n\nFor more details about the framework check the book at <https://defmt.ferrous-systems.com>.\n\nThis library contains the proc macros used by\n[`defmt`](https://crates.io/crates/defmt).\n\n## MSRV\n\nThe minimum supported Rust version is 1.76 (or Ferrocene 24.05). This crate is tested against the latest stable Rust version and the MSRV.\n\n## Support\n\n`defmt` is part of the [Knurling] project, [Ferrous Systems]' effort at\nimproving tooling used to develop for embedded systems.\n\nIf you think that our work is useful, consider sponsoring it via [GitHub\nSponsors].\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or\n  <http://www.apache.org/licenses/LICENSE-2.0>)\n\n- MIT license ([LICENSE-MIT](../LICENSE-MIT) or <http://opensource.org/licenses/MIT>)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\nlicensed as above, without any additional terms or conditions.\n\n[Knurling]: https://knurling.ferrous-systems.com/\n[Ferrous Systems]: https://ferrous-systems.com/\n[GitHub Sponsors]: https://github.com/sponsors/knurling-rs\n"
    },
    {
      "package": "defmt-parser@1.0.0",
      "sourcePath": "README.md",
      "sha256": "a40aae66ea32ccd2b2c30ea976d4ac02fab1025a8dece8bfae6aa83bdcfd9c0e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# `defmt-parser`\n\n`defmt` (\"de format\", short for \"deferred formatting\") is a highly efficient logging framework that targets resource-constrained devices, like microcontrollers.\n\nFor more details about the framework check the book at <https://defmt.ferrous-systems.com>.\n\nThis library decodes `defmt` frames into Rust structures. It is mainly used by\n[`defmt-decoder`](https://crates.io/crates/defmt-decoder), and you should prefer\nusing that crate to this one.\n\n## MSRV\n\nThe minimum supported Rust version is 1.76 (or Ferrocene 24.05). `defmt` is tested against the latest stable Rust version and the MSRV.\n\n## Support\n\n`defmt` is part of the [Knurling] project, [Ferrous Systems]' effort at\nimproving tooling used to develop for embedded systems.\n\nIf you think that our work is useful, consider sponsoring it via [GitHub\nSponsors].\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or\n  <http://www.apache.org/licenses/LICENSE-2.0>)\n\n- MIT license ([LICENSE-MIT](../LICENSE-MIT) or <http://opensource.org/licenses/MIT>)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\nlicensed as above, without any additional terms or conditions.\n\n[Knurling]: https://knurling.ferrous-systems.com/\n[Ferrous Systems]: https://ferrous-systems.com/\n[GitHub Sponsors]: https://github.com/sponsors/knurling-rs\n"
    },
    {
      "package": "env_logger@0.11.11",
      "sourcePath": "src/lib.rs",
      "sha256": "ad6c81c8ff53ef7a07a3ff4dda4cf16a55ad58cd4275df96bbab3aaf4990500c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! A simple logger that can be configured via environment variables, for use\n//! with the logging facade exposed by the [`log` crate][log-crate-url].\n//!\n//! Despite having \"env\" in its name, **`env_logger`** can also be configured by\n//! other means besides environment variables. See [the examples][gh-repo-examples]\n//! in the source repository for more approaches.\n//!\n//! By default, `env_logger` writes logs to `stderr`, but can be configured to\n//! instead write them to `stdout`.\n//!\n//! ## Example\n//!\n//! ```\n//! use log::{debug, error, log_enabled, info, Level};\n//!\n//! env_logger::init();\n//!\n//! debug!(\"this is a debug {}\", \"message\");\n//! error!(\"this is printed by default\");\n//!\n//! if log_enabled!(Level::Info) {\n//!     let x = 3 * 4; // expensive computation\n//!     info!(\"the answer was: {}\", x);\n//! }\n//! ```\n//!\n//! Assumes the binary is `main`:\n//!\n//! ```console\n//! $ RUST_LOG=error ./main\n//! [2017-11-09T02:12:24Z ERROR main] this is printed by default\n//! ```\n//!\n//! ```console\n//! $ RUST_LOG=info ./main\n//! [2017-11-09T02:12:24Z ERROR main] this is printed by default\n//! [2017-11-09T02:12:24Z INFO main] the answer was: 12\n//! ```\n//!\n//! ```console\n//! $ RUST_LOG=debug ./main\n//! [2017-11-09T02:12:24Z DEBUG main] this is a debug message\n//! [2017-11-09T02:12:24Z ERROR main] this is printed by default\n//! [2017-11-09T02:12:24Z INFO main] the answer was: 12\n//! ```\n//!\n//! You can also set the log level on a per module basis:\n//!\n//! ```console\n//! $ RUST_LOG=main=info ./main\n//! [2017-11-09T02:12:24Z ERROR main] this is printed by default\n//! [2017-11-09T02:12:24Z INFO main] the answer was: 12\n//! ```\n//!\n//! And enable all logging:\n//!\n//! ```console\n//! $ RUST_LOG=main ./main\n//! [2017-11-09T02:12:24Z DEBUG main] this is a debug message\n//! [2017-11-09T02:12:24Z ERROR main] this is printed by default\n//! [2017-11-09T02:12:24Z INFO main] the answer was: 12\n//! ```\n//!\n//! If the binary name contains hyphens, you will need to replace\n//! them with underscores:\n//!\n//! ```console\n//! $ RUST_LOG=my_app ./my-app\n//! [2017-11-09T02:12:24Z DEBUG my_app] this is a debug message\n//! [2017-11-09T02:12:24Z ERROR my_app] this is printed by default\n//! [2017-11-09T02:12:24Z INFO my_app] the answer was: 12\n//! ```\n//!\n//! This is because Rust modules and crates cannot contain hyphens\n//! in their name, although `cargo` continues to accept them.\n//!\n//! See the documentation for the [`log` crate][log-crate-url] for more\n//! information about its API.\n//!\n//! ## Enabling logging\n//!\n//! **By default all logging is disabled except for the `error` level**\n//!\n//! The **`RUST_LOG`** environment variable controls logging with the syntax:\n//! ```console\n//! RUST_LOG=[target][=][level][,...]\n//! ```\n//! Or in other words, its a comma-separated list of directives.\n//! Directives can filter by **target**, by **level**, or both (using `=`).\n//!\n//! For example,\n//! ```console\n//! RUST_LOG=data=debug,hardware=debug\n//! ```\n//!\n//! **target** is typically the path of the module the message\n//! in question originated from, though it can be overridden.\n//! The path is rooted in the name of the crate it was compiled for, so if\n//! your program is in a file called, for example, `hello.rs`, the path would\n//! simply be `hello`.\n//!\n//! Furthermore, the log can be filtered using prefix-search based on the\n//! specified log target.\n//!\n//! For example, `RUST_LOG=example` would match the following targets:\n//! - `example`\n//! - `example::test`\n//! - `example::test::module::submodule`\n//! - `examples::and_more_examples`\n//!\n//! When providing the crate name or a module path, explicitly specifying the\n//! log level is optional. If omitted, all logging for the item will be\n//! enabled.\n//!\n//! **level** is the maximum [`log::Level`][level-enum] to be shown and includes:\n//! - `error`\n//! - `warn`\n//! - `info`\n//! - `debug`\n//! - `trace`\n//! - `off` (pseudo level to disable all logging for the target)\n//!\n//! Logging level names are case-insensitive; e.g.,\n//! `debug`, `DEBUG`, and `dEbuG` all represent the same logging level. For\n//! consistency, our convention is to use the lower case names. Where our docs\n//! do use other forms, they do so in the context of specific examples, so you\n//! won't be surprised if you see similar usage in the wild.\n//!\n//! Some examples of valid values of `RUST_LOG` are:\n//!\n//! - `RUST_LOG=hello` turns on all logging for the `hello` module\n//! - `RUST_LOG=trace` turns on all logging for the application, regardless of its name\n//! - `RUST_LOG=TRACE` turns on all logging for the application, regardless of its name (same as previous)\n//! - `RUST_LOG=info` turns on all info logging\n//! - `RUST_LOG=INFO` turns on all info logging (same as previous)\n//! - `RUST_LOG=hello=debug` turns on debug logging for `hello`\n//! - `RUST_LOG=hello=DEBUG` turns on debug logging for `hello` (same as previous)\n//! - `RUST_LOG=hello,std::option` turns on `hello`, and std's option logging\n//! - `RUST_LOG=error,hello=warn` turn on global error logging and also warn for `hello`\n//! - `RUST_LOG=error,hello=off`  turn on global error logging, but turn off logging for `hello`\n//! - `RUST_LOG=off` turns off all logging for the application\n//! - `RUST_LOG=OFF` turns off all logging for the application (same as previous)\n//!\n//! ## Filtering results\n//!\n//! A `RUST_LOG` directive may include a regex filter. The syntax is to append `/`\n//! followed by a regex. Each message is checked against the regex, and is only\n//! logged if it matches. Note that the matching is done after formatting the\n//! log string but before adding any logging meta-data. There is a single filter\n//! for all modules.\n//!\n//! Some examples:\n//!\n//! * `hello/foo` turns on all logging for the 'hello' module where the log\n//!   message includes 'foo'.\n//! * `info/f.o` turns on all info logging where the log message includes 'foo',\n//!   'f1o', 'fao', etc.\n//! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the log\n//!   message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc.\n//! * `error,hello=warn/[0-9]scopes` turn on global error logging and also\n//!   warn for hello. In both cases the log message must include a single digit\n//!   number followed by 'scopes'.\n//!\n//! ## Capturing logs in tests\n//!\n//! Records logged during `cargo test` will not be captured by the test harness by default.\n//! The [`Builder::is_test`] method can be used in unit tests to ensure logs will be captured:\n//!\n//! ```test_harness\n//! #[cfg(test)]\n//! mod tests {\n//!     use log::info;\n//!\n//!     fn init() {\n//!         let _ = env_logger::builder().is_test(true).try_init();\n//!     }\n//!\n//!     #[test]\n//!     fn it_works() {\n//!         init();\n//!\n//!         info!(\"This record will be captured by `cargo test`\");\n//!\n//!         assert_eq!(2, 1 + 1);\n//!     }\n//! }\n//! ```\n//!\n//! Enabling test capturing comes at the expense of color and other style support\n//! and may have performance implications.\n//!\n//! ## Colors\n//!\n//! Outputting of colors and other styles can be controlled by the `RUST_LOG_STYLE`\n//! environment variable. It accepts the following [values][fmt::WriteStyle]:\n//!\n//! * `auto` (default) will attempt to print style characters, but don't force the issue.\n//!   If the console isn't available on Windows, or if TERM=dumb, for example, then don't print colors.\n//! * `always` will always print style characters even if they aren't supported by the terminal.\n//!   This includes emitting ANSI colors on Windows if the console API is unavailable.\n//! * `never` will never print style characters.\n//!\n//! Color may be applied in the logged message or a [custom formatter][fmt].\n//!\n//! <div class=\"warning\">\n//!\n//! Logging of untrusted inputs can cause unexpected behavior as they may include ANSI escape codes which\n//! will be forwarded to the users terminal as part of \"Weaponizing ANSI Escape Sequences\".\n//!\n//! Mitigations include:\n//! - Setting `RUST_LOG_STYLE=never` to have all ANSI escape codes stripped\n//! - In the application, calling [`Builder::write_style(Never)`][Builder::write_style] to have all ANSI escape codes stripped\n//! - In the application, [stripping ANSI escape codes](https://docs.rs/anstream/latest/anstream/adapter/fn.strip_str.html)\n//!   from user inputs\n//!\n//! Note: deactivating the build-time feature `color` is not a mitigation as that removes all ANSI escape code\n//! stripping from `env_logger`.\n//!\n//! </div>\n//!\n//! ## Tweaking the default format\n//!\n//! Parts of the default format can be excluded from the log output using the [`Builder`].\n//! The following example excludes the timestamp from the log output:\n//!\n//! ```\n//! env_logger::builder()\n//!     .format_timestamp(None)\n//!     .init();\n//! ```\n//!\n//! ### Stability of the default format\n//!\n//! The default format won't optimise for long-term stability, and explicitly makes no\n//! guarantees about the stability of its output across major, minor or patch version\n//! bumps during `0.x`.\n//!\n//! If you want to capture or interpret the output of `env_logger` programmatically\n//! then you should use a custom format.\n//!\n//! ### Using a custom format\n//!\n//! Custom formats can be provided as closures to the [`Builder`].\n//! These closures take a [`Formatter`][crate::fmt::Formatter] and `log::Record` as arguments:\n//!\n//! ```\n//! use std::io::Write;\n//!\n//! env_logger::builder()\n//!     .format(|buf, record| {\n//!         writeln!(buf, \"{}: {}\", record.level(), record.args())\n//!     })\n//!     .init();\n//! ```\n//!\n//! See the [`fmt`] module for more details about custom formats.\n//!\n//! ## Specifying defaults for environment variables\n//!\n//! `env_logger` can read configuration from environment variables.\n//! If these variables aren't present, the default value to use can be tweaked with the [`Env`] type.\n//! The following example defaults to log `warn` and above if the `RUST_LOG` environment variable\n//! isn't set:\n//!\n//! ```\n//! use env_logger::Env;\n//!\n//! env_logger::Builder::from_env(Env::default().default_filter_or(\"warn\")).init();\n//! ```\n//!\n//! [gh-repo-examples]: https://github.com/rust-cli/env_logger/tree/main/examples\n//! [level-enum]: https://docs.rs/log/latest/log/enum.Level.html\n//! [log-crate-url]: https://docs.rs/log\n\n#![cfg_attr(docsrs, feature(doc_cfg))]\n#![warn(clippy::print_stderr)]\n#![warn(clippy::print_stdout)]\n#![allow(clippy::test_attr_in_doctest)]\n\nmod logger;\nmod writer;\n\npub mod fmt;\n\npub use self::fmt::{Target, TimestampPrecision, WriteStyle};\npub use self::logger::*;\n\n#[doc = include_str!(\"../README.md\")]\n#[cfg(doctest)]\npub struct ReadmeDoctests;\n"
    },
    {
      "package": "find-msvc-tools@0.1.13",
      "sourcePath": "README.md",
      "sha256": "5e7b2b1f5ffc1da7695d3e151a2d4d0b8f681e65a24ddf85a353d4bcfa81967a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# find-msvc-tools \n\n> This crate is maintained by the library team, primarily for use by the `cc`\n> crate and not intended for external use (except as a transitive dependency).\n> This crate may make major changes to its APIs or be deprecated without\n> warning.\n\nAn internal use library for finding windows-specific tools, reading MSVC\nversions from the registry and from COM interfaces.\n\nRefer to the [documentation](https://docs.rs/find-msvc-tools) for detailed usage\ninstructions.\n\n## License\n\nThis project is licensed under either of\n\n * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\n   https://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or\n   https://opensource.org/license/mit)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution transitively\nintentionally submitted for inclusion in find-msvc-tools by you, as defined in\nthe Apache-2.0 license, shall be dual licensed as above, without any additional\nterms or conditions."
    },
    {
      "package": "find-msvc-tools@0.1.13",
      "sourcePath": "src/com.rs",
      "sha256": "6706eb2a4d8d1920b66759776a78ab054b493a81dca99a90f96f9e53c0cd1852",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright © 2017 winapi-rs developers\n// Licensed under the Apache License, Version 2.0\n// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.\n// All files in the project carrying such notice may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::{\n    winapi::{IUnknown, Interface},\n    windows_sys::{\n        CoInitializeEx, SysFreeString, SysStringLen, BSTR, COINIT_MULTITHREADED, HRESULT, S_FALSE,\n        S_OK,\n    },\n};\nuse std::{\n    convert::TryInto,\n    ffi::OsString,\n    ops::Deref,\n    os::windows::ffi::OsStringExt,\n    ptr::{null, null_mut},\n    slice::from_raw_parts,\n};\n\npub fn initialize() -> Result<(), HRESULT> {\n    let err = unsafe { CoInitializeEx(null(), COINIT_MULTITHREADED.try_into().unwrap()) };\n    if err != S_OK && err != S_FALSE {\n        // S_FALSE just means COM is already initialized\n        Err(err)\n    } else {\n        Ok(())\n    }\n}\n\npub struct ComPtr<T>(*mut T)\nwhere\n    T: Interface;\nimpl<T> ComPtr<T>\nwhere\n    T: Interface,\n{\n    /// Creates a `ComPtr` to wrap a raw pointer.\n    /// It takes ownership over the pointer which means it does __not__ call `AddRef`.\n    /// `T` __must__ be a COM interface that inherits from `IUnknown`.\n    pub unsafe fn from_raw(ptr: *mut T) -> ComPtr<T> {\n        assert!(!ptr.is_null());\n        ComPtr(ptr)\n    }\n    /// For internal use only.\n    fn as_unknown(&self) -> &IUnknown {\n        unsafe { &*self.0.cast() }\n    }\n    /// Performs `QueryInterface` fun.\n    pub fn cast<U>(&self) -> Result<ComPtr<U>, i32>\n    where\n        U: Interface,\n    {\n        let mut obj = null_mut();\n        let err = unsafe { self.as_unknown().QueryInterface(&U::uuidof(), &mut obj) };\n        if err < 0 {\n            return Err(err);\n        }\n        Ok(unsafe { ComPtr::from_raw(obj.cast()) })\n    }\n}\nimpl<T> Deref for ComPtr<T>\nwhere\n    T: Interface,\n{\n    type Target = T;\n    fn deref(&self) -> &T {\n        unsafe { &*self.0 }\n    }\n}\nimpl<T> Clone for ComPtr<T>\nwhere\n    T: Interface,\n{\n    fn clone(&self) -> Self {\n        unsafe {\n            self.as_unknown().AddRef();\n            ComPtr::from_raw(self.0)\n        }\n    }\n}\nimpl<T> Drop for ComPtr<T>\nwhere\n    T: Interface,\n{\n    fn drop(&mut self) {\n        unsafe {\n            self.as_unknown().Release();\n        }\n    }\n}\npub struct BStr(BSTR);\nimpl BStr {\n    pub unsafe fn from_raw(s: BSTR) -> BStr {\n        BStr(s)\n    }\n    pub fn to_osstring(&self) -> OsString {\n        let len = unsafe { SysStringLen(self.0) };\n        let slice = unsafe { from_raw_parts(self.0, len as usize) };\n        OsStringExt::from_wide(slice)\n    }\n}\nimpl Drop for BStr {\n    fn drop(&mut self) {\n        unsafe { SysFreeString(self.0) };\n    }\n}\n"
    },
    {
      "package": "find-msvc-tools@0.1.13",
      "sourcePath": "src/find_tools.rs",
      "sha256": "62862c642802e52167a1d916538cfd165e088bda9bce851522da4405af3b2d4b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! An internal use crate to looking for windows-specific tools:\n//! 1. On Windows host, probe the Windows Registry if needed;\n//! 2. On non-Windows host, check specified environment variables.\n\n#![allow(missing_docs)]\n#![allow(clippy::upper_case_acronyms)]\n\nuse std::{\n    env,\n    ffi::{OsStr, OsString},\n    ops::Deref,\n    path::{Path, PathBuf},\n    process::Command,\n    sync::Arc,\n};\n\nuse crate::Tool;\n\n/// The target provided by the user.\n#[derive(Copy, Clone, PartialEq, Eq)]\nenum TargetArch {\n    X86,\n    X64,\n    Arm,\n    Arm64,\n    Arm64ec,\n}\nimpl TargetArch {\n    /// Parse the `TargetArch` from a str. Returns `None` if the arch is unrecognized.\n    fn new(arch: &str) -> Option<Self> {\n        // NOTE: Keep up to date with docs in [`find`].\n        match arch {\n            \"x64\" | \"x86_64\" => Some(Self::X64),\n            \"arm64\" | \"aarch64\" => Some(Self::Arm64),\n            \"arm64ec\" => Some(Self::Arm64ec),\n            \"x86\" | \"i686\" | \"i586\" => Some(Self::X86),\n            \"arm\" | \"thumbv7a\" => Some(Self::Arm),\n            _ => None,\n        }\n    }\n\n    #[cfg(windows)]\n    /// Gets the Visual Studio name for the architecture.\n    fn as_vs_arch(&self) -> &'static str {\n        match self {\n            Self::X64 => \"x64\",\n            Self::Arm64 | Self::Arm64ec => \"arm64\",\n            Self::X86 => \"x86\",\n            Self::Arm => \"arm\",\n        }\n    }\n}\n\n#[derive(Debug, Clone)]\n#[non_exhaustive]\npub enum Env {\n    Owned(OsString),\n    Arced(Arc<OsStr>),\n}\n\nimpl AsRef<OsStr> for Env {\n    fn as_ref(&self) -> &OsStr {\n        self.deref()\n    }\n}\n\nimpl Deref for Env {\n    type Target = OsStr;\n\n    fn deref(&self) -> &Self::Target {\n        match self {\n            Env::Owned(os_str) => os_str,\n            Env::Arced(os_str) => os_str,\n        }\n    }\n}\n\nimpl From<Env> for PathBuf {\n    fn from(env: Env) -> Self {\n        match env {\n            Env::Owned(os_str) => PathBuf::from(os_str),\n            Env::Arced(os_str) => PathBuf::from(os_str.deref()),\n        }\n    }\n}\n\npub trait EnvGetter {\n    fn get_env(&self, name: &'static str) -> Option<Env>;\n}\n\nstruct StdEnvGetter;\n\nimpl EnvGetter for StdEnvGetter {\n    #[allow(clippy::disallowed_methods)]\n    fn get_env(&self, name: &'static str) -> Option<Env> {\n        env::var_os(name).map(Env::Owned)\n    }\n}\n\n/// Attempts to find a tool within an MSVC installation using the Windows\n/// registry as a point to search from.\n///\n/// The `arch_or_target` argument is the architecture or the Rust target name\n/// that the tool should work for (e.g. compile or link for). The supported\n/// architecture names are:\n/// - `\"x64\"` or `\"x86_64\"`\n/// - `\"arm64\"` or `\"aarch64\"`\n/// - `\"arm64ec\"`\n/// - `\"x86\"`, `\"i586\"` or `\"i686\"`\n/// - `\"arm\"` or `\"thumbv7a\"`\n///\n/// The `tool` argument is the tool to find. Supported tools include:\n/// - MSVC tools: `cl.exe`, `link.exe`, `lib.exe`, etc.\n/// - `MSBuild`: `msbuild.exe`\n/// - Visual Studio IDE: `devenv.exe`\n/// - Clang/LLVM tools: `clang.exe`, `clang++.exe`, `clang-*.exe`, `llvm-*.exe`, `lld.exe`, etc.\n///\n/// This function will return `None` if the tool could not be found, or it will\n/// return `Some(cmd)` which represents a command that's ready to execute the\n/// tool with the appropriate environment variables set.\n///\n/// To find MSVC tools, this function will first attempt to detect if we are\n/// running in the context of a developer command prompt, and then use the tools\n/// as found in the current `PATH`. If that fails, it will attempt to locate\n/// the newest MSVC toolset in the newest installed version of Visual Studio.\n/// To limit the search to a specific version of the MSVC toolset, set the\n/// `VCToolsVersion` environment variable to the desired version (e.g. \"14.44.35207\").\n///\n/// Note that this function always returns `None` for non-MSVC targets (if a\n/// full target name was specified).\npub fn find(arch_or_target: &str, tool: &str) -> Option<Command> {\n    find_tool(arch_or_target, tool).map(|c| c.to_command())\n}\n\n/// Similar to the `find` function above, this function will attempt the same\n/// operation (finding a MSVC tool in a local install) but instead returns a\n/// `Tool` which may be introspected.\npub fn find_tool(arch_or_target: &str, tool: &str) -> Option<Tool> {\n    let full_arch = if let Some((full_arch, rest)) = arch_or_target.split_once(\"-\") {\n        // The logic is all tailored for MSVC, if the target is not that then\n        // bail out early.\n        if !rest.contains(\"msvc\") {\n            return None;\n        }\n        full_arch\n    } else {\n        arch_or_target\n    };\n    find_tool_with_env(full_arch, tool, &StdEnvGetter)\n}\n\npub fn find_tool_with_env(full_arch: &str, tool: &str, env_getter: &dyn EnvGetter) -> Option<Tool> {\n    // We only need the arch.\n    let target = TargetArch::new(full_arch)?;\n\n    // Looks like msbuild isn't located in the same location as other tools like\n    // cl.exe and lib.exe.\n    if tool.contains(\"msbuild\") {\n        return impl_::find_msbuild(target, env_getter);\n    }\n\n    // Looks like devenv isn't located in the same location as other tools like\n    // cl.exe and lib.exe.\n    if tool.contains(\"devenv\") {\n        return impl_::find_devenv(target, env_getter);\n    }\n\n    // Clang/LLVM isn't located in the same location as other tools like\n    // cl.exe and lib.exe.\n    if [\"clang\", \"lldb\", \"llvm\", \"ld\", \"lld\"]\n        .iter()\n        .any(|&t| tool.contains(t))\n    {\n        return impl_::find_llvm_tool(tool, target, env_getter);\n    }\n\n    // Ok, if we're here, now comes the fun part of the probing. Default shells\n    // or shells like MSYS aren't really configured to execute `cl.exe` and the\n    // various compiler tools shipped as part of Visual Studio. Here we try to\n    // first find the relevant tool, then we also have to be sure to fill in\n    // environment variables like `LIB`, `INCLUDE`, and `PATH` to ensure that\n    // the tool is actually usable.\n\n    impl_::find_msvc_environment(tool, target, env_getter)\n        .or_else(|| impl_::find_msvc_15plus(tool, target, env_getter))\n        .or_else(|| impl_::find_msvc_14(tool, target, env_getter))\n}\n\n/// An SDK found by [`find_windows_sdk`]\n#[derive(Default)]\npub struct Sdk {\n    libs: Vec<PathBuf>,\n    path: Vec<PathBuf>,\n    include: Vec<PathBuf>,\n    version: String,\n}\n\nimpl Sdk {\n    /// Directories containing static libraries (e.g. `.lib` files).\n    pub fn libs(&self) -> impl Iterator<Item = &Path> {\n        self.libs.iter().map(PathBuf::as_path)\n    }\n\n    /// Directories containing binaries (`.exe` and `.dll` files).\n    pub fn path(&self) -> impl Iterator<Item = &Path> {\n        self.path.iter().map(PathBuf::as_path)\n    }\n\n    /// Directories containing source headers (e.g. `.h` files)\n    pub fn include(&self) -> impl Iterator<Item = &Path> {\n        self.include.iter().map(PathBuf::as_path)\n    }\n\n    /// The Windows SDK version that was found.\n    pub fn sdk_version(&self) -> &str {\n        &self.version\n    }\n}\n\n/// Find the directories of the latest installed Windows SDK.\n///\n/// It's not necessary to call this if using [`find`] or [`find_tool`] as they will populate the relvant\n/// environment variables with the SDK directories.\npub fn find_windows_sdk(full_arch: &str) -> Option<Sdk> {\n    let target = TargetArch::new(full_arch)?;\n    impl_::get_sdks(target, &StdEnvGetter)\n}\n\n/// A version of Visual Studio\n#[derive(Debug, PartialEq, Eq, Copy, Clone)]\n#[non_exhaustive]\npub enum VsVers {\n    /// Visual Studio 12 (2013)\n    #[deprecated(\n        note = \"Visual Studio 12 is no longer supported. cc will never return this value.\"\n    )]\n    Vs12,\n    /// Visual Studio 14 (2015)\n    Vs14,\n    /// Visual Studio 15 (2017)\n    Vs15,\n    /// Visual Studio 16 (2019)\n    Vs16,\n    /// Visual Studio 17 (2022)\n    Vs17,\n    /// Visual Studio 18 (2026)\n    Vs18,\n}\n\n/// Find the most recent installed version of Visual Studio\n///\n/// This is used by the cmake crate to figure out the correct\n/// generator.\n#[allow(clippy::disallowed_methods)]\npub fn find_vs_version() -> Result<VsVers, String> {\n    fn has_msbuild_version(version: &str) -> bool {\n        impl_::has_msbuild_version(version, &StdEnvGetter)\n    }\n\n    match std::env::var(\"VisualStudioVersion\") {\n        Ok(version) => match &version[..] {\n            \"18.0\" => Ok(VsVers::Vs18),\n            \"17.0\" => Ok(VsVers::Vs17),\n            \"16.0\" => Ok(VsVers::Vs16),\n            \"15.0\" => Ok(VsVers::Vs15),\n            \"14.0\" => Ok(VsVers::Vs14),\n            vers => Err(format!(\n                \"\\n\\n\\\n                 unsupported or unknown VisualStudio version: {vers}\\n\\\n                 if another version is installed consider running \\\n                 the appropriate vcvars script before building this \\\n                 crate\\n\\\n                 \"\n            )),\n        },\n        _ => {\n            // Check for the presence of a specific registry key\n            // that indicates visual studio is installed.\n            if has_msbuild_version(\"18.0\") {\n                Ok(VsVers::Vs18)\n            } else if has_msbuild_version(\"17.0\") {\n                Ok(VsVers::Vs17)\n            } else if has_msbuild_version(\"16.0\") {\n                Ok(VsVers::Vs16)\n            } else if has_msbuild_version(\"15.0\") {\n                Ok(VsVers::Vs15)\n            } else if has_msbuild_version(\"14.0\") {\n                Ok(VsVers::Vs14)\n            } else {\n                Err(\"\\n\\n\\\n                     couldn't determine visual studio generator\\n\\\n                     if VisualStudio is installed, however, consider \\\n                     running the appropriate vcvars script before building \\\n                     this crate\\n\\\n                     \"\n                .to_string())\n            }\n        }\n    }\n}\n\n/// To find the Universal CRT we look in a specific registry key for where\n/// all the Universal CRTs are located and then sort them asciibetically to\n/// find the newest version. While this sort of sorting isn't ideal,  it is\n/// what vcvars does so that's good enough for us.\n///\n/// Returns a pair of (root, version) for the ucrt dir if found\npub fn get_ucrt_dir() -> Option<(PathBuf, String)> {\n    impl_::get_ucrt_dir()\n}\n\n/// Windows Implementation.\n#[cfg(windows)]\nmod impl_ {\n    use crate::com;\n    use crate::registry::{RegistryKey, LOCAL_MACHINE};\n    use crate::setup_config::SetupConfiguration;\n    use crate::vs_instances::{VsInstances, VswhereInstance};\n    use crate::windows_sys::{\n        GetMachineTypeAttributes, GetProcAddress, LoadLibraryA, UserEnabled, HMODULE,\n        IMAGE_FILE_MACHINE_AMD64, MACHINE_ATTRIBUTES, S_OK,\n    };\n    use std::convert::TryFrom;\n    use std::env;\n    use std::ffi::OsString;\n    use std::fs::File;\n    use std::io::Read;\n    use std::iter;\n    use std::mem;\n    use std::path::{Path, PathBuf};\n    use std::process::Command;\n    use std::str::FromStr;\n    use std::sync::atomic::{AtomicBool, Ordering};\n    use std::sync::Once;\n\n    use super::{EnvGetter, Sdk, TargetArch};\n    use crate::Tool;\n\n    struct MsvcTool {\n        tool: PathBuf,\n        libs: Vec<PathBuf>,\n        path: Vec<PathBuf>,\n        include: Vec<PathBuf>,\n    }\n\n    struct LibraryHandle(HMODULE);\n\n    impl LibraryHandle {\n        fn new(name: &[u8]) -> Option<Self> {\n            let handle = unsafe { LoadLibraryA(name.as_ptr().cast()) };\n            (!handle.is_null()).then_some(Self(handle))\n        }\n\n        /// Get a function pointer to a function in the library.\n        /// # SAFETY\n        ///\n        /// The caller must ensure that the function signature matches the actual function.\n        /// The easiest way to do this is to add an entry to `windows_sys_no_link.list` and use the\n        /// generated function for `func_signature`.\n        ///\n        /// The function returned cannot be used after the handle is dropped.\n        unsafe fn get_proc_address<F>(&self, name: &[u8]) -> Option<F> {\n            let symbol = GetProcAddress(self.0, name.as_ptr().cast());\n            symbol.map(|symbol| mem::transmute_copy(&symbol))\n        }\n    }\n\n    type GetMachineTypeAttributesFuncType =\n        unsafe extern \"system\" fn(u16, *mut MACHINE_ATTRIBUTES) -> i32;\n    const _: () = {\n        // Ensure that our hand-written signature matches the actual function signature.\n        // We can't use `GetMachineTypeAttributes` outside of a const scope otherwise we'll end up statically linking to\n        // it, which will fail to load on older versions of Windows.\n        let _: GetMachineTypeAttributesFuncType = GetMachineTypeAttributes;\n    };\n\n    fn is_amd64_emulation_supported_inner() -> Option<bool> {\n        // GetMachineTypeAttributes is only available on Win11 22000+, so dynamically load it.\n        let kernel32 = LibraryHandle::new(b\"kernel32.dll\\0\")?;\n        // SAFETY: GetMachineTypeAttributesFuncType is checked to match the real function signature.\n        let get_machine_type_attributes = unsafe {\n            kernel32\n                .get_proc_address::<GetMachineTypeAttributesFuncType>(b\"GetMachineTypeAttributes\\0\")\n        }?;\n        let mut attributes = Default::default();\n        if unsafe {\n            get_machine_type_attributes(\n                IMAGE_FILE_MACHINE_AMD64.try_into().unwrap(),\n                &mut attributes,\n            )\n        } == S_OK\n        {\n            Some((attributes & UserEnabled) != 0)\n        } else {\n            Some(false)\n        }\n    }\n\n    fn is_amd64_emulation_supported() -> bool {\n        // TODO: Replace with a OnceLock once MSRV is 1.70.\n        static LOAD_VALUE: Once = Once::new();\n        static IS_SUPPORTED: AtomicBool = AtomicBool::new(false);\n\n        // Using Relaxed ordering since the Once is providing synchronization.\n        LOAD_VALUE.call_once(|| {\n            IS_SUPPORTED.store(\n                is_amd64_emulation_supported_inner().unwrap_or(false),\n                Ordering::Relaxed,\n            );\n        });\n        IS_SUPPORTED.load(Ordering::Relaxed)\n    }\n\n    impl MsvcTool {\n        fn new(tool: PathBuf) -> MsvcTool {\n            MsvcTool {\n                tool,\n                libs: Vec::new(),\n                path: Vec::new(),\n                include: Vec::new(),\n            }\n        }\n\n        fn add_sdk(&mut self, sdk_info: Sdk) {\n            self.libs.extend(sdk_info.libs);\n            self.path.extend(sdk_info.path);\n            self.include.extend(sdk_info.include);\n        }\n\n        fn into_tool(self, env_getter: &dyn EnvGetter) -> Tool {\n            let MsvcTool {\n                tool,\n                libs,\n                path,\n                include,\n            } = self;\n            let mut tool = Tool {\n                tool,\n                is_clang_cl: false,\n                env: Vec::new(),\n            };\n            add_env(&mut tool, \"LIB\", libs, env_getter);\n            add_env(&mut tool, \"PATH\", path, env_getter);\n            add_env(&mut tool, \"INCLUDE\", include, env_getter);\n            tool\n        }\n    }\n\n    impl Sdk {\n        fn find_tool(&self, tool: &str) -> Option<PathBuf> {\n            self.path.iter().map(|p| p.join(tool)).find_map(|mut p| {\n                (p.exists() || (p.set_extension(env::consts::EXE_SUFFIX) && p.exists()))\n                    .then_some(p)\n            })\n        }\n    }\n\n    /// Checks to see if the target's arch matches the VS environment. Returns `None` if the\n    /// environment is unknown.\n    fn is_vscmd_target(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<bool> {\n        is_vscmd_target_env(target, env_getter).or_else(|| is_vscmd_target_cl(target, env_getter))\n    }\n\n    /// Checks to see if the `VSCMD_ARG_TGT_ARCH` environment variable matches the\n    /// given target's arch. Returns `None` if the variable does not exist.\n    fn is_vscmd_target_env(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<bool> {\n        let vscmd_arch = env_getter.get_env(\"VSCMD_ARG_TGT_ARCH\")?;\n        Some(target.as_vs_arch() == vscmd_arch.as_ref())\n    }\n\n    /// Checks if the cl.exe target matches the given target's arch. Returns `None` if anything\n    /// fails.\n    fn is_vscmd_target_cl(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<bool> {\n        let cmd_target = vscmd_target_cl(env_getter)?;\n        Some(target.as_vs_arch() == cmd_target)\n    }\n\n    /// Detect the target architecture of `cl.exe` in the current path, and return `None` if this\n    /// fails for any reason.\n    fn vscmd_target_cl(env_getter: &dyn EnvGetter) -> Option<&'static str> {\n        let cl_exe = env_getter.get_env(\"PATH\").and_then(|path| {\n            env::split_paths(&path)\n                .map(|p| p.join(\"cl.exe\"))\n                .find(|p| p.exists())\n        })?;\n        let mut cl = Command::new(cl_exe);\n        cl.stderr(std::process::Stdio::piped())\n            .stdout(std::process::Stdio::null());\n\n        let out = cl.output().ok()?;\n        let cl_arch = out\n            .stderr\n            .split(|&b| b == b'\\n' || b == b'\\r')\n            .next()?\n            .rsplit(|&b| b == b' ')\n            .next()?;\n\n        match cl_arch {\n            b\"x64\" => Some(\"x64\"),\n            b\"x86\" => Some(\"x86\"),\n            b\"ARM64\" => Some(\"arm64\"),\n            b\"ARM\" => Some(\"arm\"),\n            _ => None,\n        }\n    }\n\n    /// Attempt to find the tool using environment variables set by vcvars.\n    pub(super) fn find_msvc_environment(\n        tool: &str,\n        target: TargetArch,\n        env_getter: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        // Early return if the environment isn't one that is known to have compiler toolsets in PATH\n        // `VCINSTALLDIR` is set from vcvarsall.bat (developer command prompt)\n        // `VSTEL_MSBuildProjectFullPath` is set by msbuild when invoking custom build steps\n        // NOTE: `VisualStudioDir` used to be used but this isn't set when invoking msbuild from the commandline\n        if env_getter.get_env(\"VCINSTALLDIR\").is_none()\n            && env_getter.get_env(\"VSTEL_MSBuildProjectFullPath\").is_none()\n        {\n            return None;\n        }\n\n        // If the vscmd target differs from the requested target then\n        // attempt to get the tool using the VS install directory.\n        if is_vscmd_target(target, env_getter) == Some(false) {\n            // We will only get here with versions 15+.\n            let vs_install_dir: PathBuf = env_getter.get_env(\"VSINSTALLDIR\")?.into();\n            tool_from_vs15plus_instance(tool, target, &vs_install_dir, env_getter)\n        } else {\n            // Fallback to simply using the current environment.\n            env_getter\n                .get_env(\"PATH\")\n                .and_then(|path| {\n                    env::split_paths(&path)\n                        .map(|p| p.join(tool))\n                        .find(|p| p.exists())\n                })\n                .map(|path| Tool {\n                    tool: path,\n                    is_clang_cl: false,\n                    env: Vec::new(),\n                })\n        }\n    }\n\n    fn find_msbuild_vs18(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<Tool> {\n        find_tool_in_vs16plus_path(r\"MSBuild\\Current\\Bin\\MSBuild.exe\", target, \"18\", env_getter)\n    }\n\n    fn find_msbuild_vs17(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<Tool> {\n        find_tool_in_vs16plus_path(r\"MSBuild\\Current\\Bin\\MSBuild.exe\", target, \"17\", env_getter)\n    }\n\n    #[allow(bare_trait_objects)]\n    fn vs16plus_instances(\n        target: TargetArch,\n        version: &'static str,\n        env_getter: &dyn EnvGetter,\n    ) -> Box<dyn Iterator<Item = PathBuf>> {\n        Box::new(\n            vs15plus_instances(target, env_getter)\n                .into_iter()\n                .flatten()\n                .filter_map(move |instance| {\n                    instance\n                        .installation_name()\n                        .filter(|name| {\n                            [\"VisualStudio\", \"VisualStudioPreview\"]\n                                .into_iter()\n                                .any(|kind| name.starts_with(&format!(\"{kind}/{version}.\")))\n                        })\n                        .and_then(|_| instance.installation_path())\n                }),\n        )\n    }\n\n    fn find_tool_in_vs16plus_path(\n        tool: &str,\n        target: TargetArch,\n        version: &'static str,\n        env_getter: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        vs16plus_instances(target, version, env_getter)\n            .filter_map(|path| {\n                let path = path.join(tool);\n                if !path.is_file() {\n                    return None;\n                }\n                let mut tool = Tool {\n                    tool: path,\n                    is_clang_cl: false,\n                    env: Vec::new(),\n                };\n                if target == TargetArch::X64 {\n                    tool.env.push((\"Platform\".into(), \"X64\".into()));\n                }\n                if matches!(target, TargetArch::Arm64 | TargetArch::Arm64ec) {\n                    tool.env.push((\"Platform\".into(), \"ARM64\".into()));\n                }\n                Some(tool)\n            })\n            .next()\n    }\n\n    fn find_msbuild_vs16(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<Tool> {\n        find_tool_in_vs16plus_path(r\"MSBuild\\Current\\Bin\\MSBuild.exe\", target, \"16\", env_getter)\n    }\n\n    pub(super) fn find_llvm_tool(\n        tool: &str,\n        target: TargetArch,\n        env_getter: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        find_llvm_tool_vs17plus(tool, target, env_getter, \"18\")\n            .or_else(|| find_llvm_tool_vs17plus(tool, target, env_getter, \"17\"))\n    }\n\n    fn find_llvm_tool_vs17plus(\n        tool: &str,\n        target: TargetArch,\n        env_getter: &dyn EnvGetter,\n        version: &'static str,\n    ) -> Option<Tool> {\n        vs16plus_instances(target, version, env_getter)\n            .filter_map(|mut base_path| {\n                base_path.push(r\"VC\\Tools\\LLVM\");\n                let host_folder = match host_arch() {\n                    // The default LLVM bin folder is x86, and there's separate subfolders\n                    // for the x64 and ARM64 host tools.\n                    X86 => \"\",\n                    X86_64 => \"x64\",\n                    AARCH64 => \"ARM64\",\n                    _ => return None,\n                };\n                if !host_folder.is_empty() {\n                    // E.g. C:\\...\\VC\\Tools\\LLVM\\x64\n                    base_path.push(host_folder);\n                }\n                // E.g. C:\\...\\VC\\Tools\\LLVM\\x64\\bin\\clang.exe\n                base_path.push(\"bin\");\n                base_path.push(tool);\n                let is_clang_cl = tool.contains(\"clang-cl\");\n                base_path.is_file().then(|| Tool {\n                    tool: base_path,\n                    is_clang_cl,\n                    env: Vec::new(),\n                })\n            })\n            .next()\n    }\n\n    // In MSVC 15 (2017) MS once again changed the scheme for locating\n    // the tooling.  Now we must go through some COM interfaces, which\n    // is super fun for Rust.\n    //\n    // Note that much of this logic can be found [online] wrt paths, COM, etc.\n    //\n    // [online]: https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/\n    //\n    // Returns MSVC 15+ instances (15, 16 right now), the order should be consider undefined.\n    //\n    // However, on ARM64 this method doesn't work because VS Installer fails to register COM component on ARM64.\n    // Hence, as the last resort we try to use vswhere.exe to list available instances.\n    fn vs15plus_instances(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<VsInstances> {\n        vs15plus_instances_using_com()\n            .or_else(|| vs15plus_instances_using_vswhere(target, env_getter))\n    }\n\n    fn vs15plus_instances_using_com() -> Option<VsInstances> {\n        com::initialize().ok()?;\n\n        let config = SetupConfiguration::new().ok()?;\n        let enum_setup_instances = config.enum_all_instances().ok()?;\n\n        Some(VsInstances::ComBased(enum_setup_instances))\n    }\n\n    fn vs15plus_instances_using_vswhere(\n        target: TargetArch,\n        env_getter: &dyn EnvGetter,\n    ) -> Option<VsInstances> {\n        let program_files_path = env_getter\n            .get_env(\"ProgramFiles(x86)\")\n            .or_else(|| env_getter.get_env(\"ProgramFiles\"))?;\n\n        let program_files_path = Path::new(program_files_path.as_ref());\n\n        let vswhere_path =\n            program_files_path.join(r\"Microsoft Visual Studio\\Installer\\vswhere.exe\");\n\n        if !vswhere_path.exists() {\n            return None;\n        }\n\n        let tools_arch = match target {\n            TargetArch::X86 | TargetArch::X64 => Some(\"x86.x64\"),\n            TargetArch::Arm => Some(\"ARM\"),\n            TargetArch::Arm64 | TargetArch::Arm64ec => Some(\"ARM64\"),\n        };\n\n        let vswhere_output = Command::new(vswhere_path)\n            .args([\n                \"-latest\",\n                \"-products\",\n                \"*\",\n                \"-requires\",\n                &format!(\"Microsoft.VisualStudio.Component.VC.Tools.{}\", tools_arch?),\n                \"-format\",\n                \"text\",\n                \"-nologo\",\n            ])\n            .stderr(std::process::Stdio::inherit())\n            .output()\n            .ok()?;\n\n        let vs_instances =\n            VsInstances::VswhereBased(VswhereInstance::try_from(&vswhere_output.stdout).ok()?);\n\n        Some(vs_instances)\n    }\n\n    // Inspired from official microsoft/vswhere ParseVersionString\n    // i.e. at most four u16 numbers separated by '.'\n    fn parse_version(version: &str) -> Option<[u16; 4]> {\n        let mut iter = version.split('.').map(u16::from_str).fuse();\n        let mut get_next_number = move || match iter.next() {\n            Some(Ok(version_part)) => Some(version_part),\n            Some(Err(_)) => None,\n            None => Some(0),\n        };\n        Some([\n            get_next_number()?,\n            get_next_number()?,\n            get_next_number()?,\n            get_next_number()?,\n        ])\n    }\n\n    pub(super) fn find_msvc_15plus(\n        tool: &str,\n        target: TargetArch,\n        env_getter: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        let iter = vs15plus_instances(target, env_getter)?;\n        iter.into_iter()\n            .filter_map(|instance| {\n                let version = parse_version(&instance.installation_version()?)?;\n                let instance_path = instance.installation_path()?;\n                let tool = tool_from_vs15plus_instance(tool, target, &instance_path, env_getter)?;\n                Some((version, tool))\n            })\n            .max_by_key(|(version, _)| *version)\n            .map(|(_version, tool)| tool)\n    }\n\n    // While the paths to Visual Studio 2017's devenv and MSBuild could\n    // potentially be retrieved from the registry, finding them via\n    // SetupConfiguration has shown to be [more reliable], and is preferred\n    // according to Microsoft. To help head off potential regressions though,\n    // we keep the registry method as a fallback option.\n    //\n    // [more reliable]: https://github.com/rust-lang/cc-rs/pull/331\n    fn find_tool_in_vs15_path(\n        tool: &str,\n        target: TargetArch,\n        env_getter: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        let mut path = match vs15plus_instances(target, env_getter) {\n            Some(instances) => instances\n                .into_iter()\n                .filter_map(|instance| instance.installation_path())\n                .map(|path| path.join(tool))\n                .find(|path| path.is_file()),\n            None => None,\n        };\n\n        if path.is_none() {\n            let key = r\"SOFTWARE\\WOW6432Node\\Microsoft\\VisualStudio\\SxS\\VS7\";\n            path = LOCAL_MACHINE\n                .open(key.as_ref())\n                .ok()\n                .and_then(|key| key.query_str(\"15.0\").ok())\n                .map(|path| PathBuf::from(path).join(tool))\n                .filter(|path| path.is_file());\n        }\n\n        path.map(|path| {\n            let mut tool = Tool {\n                tool: path,\n                is_clang_cl: false,\n                env: Vec::new(),\n            };\n            if target == TargetArch::X64 {\n                tool.env.push((\"Platform\".into(), \"X64\".into()));\n            } else if matches!(target, TargetArch::Arm64 | TargetArch::Arm64ec) {\n                tool.env.push((\"Platform\".into(), \"ARM64\".into()));\n            }\n            tool\n        })\n    }\n\n    fn tool_from_vs15plus_instance(\n        tool: &str,\n        target: TargetArch,\n        instance_path: &Path,\n        env_getter: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        let (root_path, bin_path, host_dylib_path, lib_path, alt_lib_path, include_path) =\n            vs15plus_vc_paths(target, instance_path, env_getter)?;\n        let sdk_info = get_sdks(target, env_getter)?;\n        let mut tool_path = bin_path.join(tool);\n        if !tool_path.exists() {\n            tool_path = sdk_info.find_tool(tool)?;\n        };\n\n        let mut tool = MsvcTool::new(tool_path);\n        tool.path.push(bin_path.clone());\n        tool.path.push(host_dylib_path);\n        if let Some(alt_lib_path) = alt_lib_path {\n            tool.libs.push(alt_lib_path);\n        }\n        tool.libs.push(lib_path);\n        tool.include.push(include_path);\n\n        if let Some((atl_lib_path, atl_include_path)) = atl_paths(target, &root_path) {\n            tool.libs.push(atl_lib_path);\n            tool.include.push(atl_include_path);\n        }\n\n        tool.add_sdk(sdk_info);\n\n        Some(tool.into_tool(env_getter))\n    }\n\n    fn vs15plus_vc_paths(\n        target_arch: TargetArch,\n        instance_path: &Path,\n        env_getter: &dyn EnvGetter,\n    ) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf, Option<PathBuf>, PathBuf)> {\n        let version = vs15plus_vc_read_version(instance_path, env_getter)?;\n\n        let hosts = match host_arch() {\n            X86 => &[\"X86\"],\n            X86_64 => &[\"X64\"],\n            // Starting with VS 17.4, there is a natively hosted compiler on ARM64:\n            // https://devblogs.microsoft.com/visualstudio/arm64-visual-studio-is-officially-here/\n            // On older versions of VS, we use x64 if running under emulation is supported,\n            // otherwise use x86.\n            AARCH64 => {\n                if is_amd64_emulation_supported() {\n                    &[\"ARM64\", \"X64\", \"X86\"][..]\n                } else {\n                    &[\"ARM64\", \"X86\"]\n                }\n            }\n            _ => return None,\n        };\n        let target_dir = target_arch.as_vs_arch();\n        // The directory layout here is MSVC/bin/Host$host/$target/\n        let path = instance_path.join(r\"VC\\Tools\\MSVC\").join(version);\n        // We use the first available host architecture that can build for the target\n        let (host_path, host) = hosts.iter().find_map(|&x| {\n            let candidate = path.join(\"bin\").join(format!(\"Host{}\", x));\n            candidate\n                .join(target_dir)\n                .exists()\n                .then_some((candidate, x))\n        })?;\n        // This is the path to the toolchain for a particular target, running\n        // on a given host\n        let bin_path = host_path.join(target_dir);\n        // But! we also need PATH to contain the target directory for the host\n        // architecture, because it contains dlls like mspdb140.dll compiled for\n        // the host architecture.\n        let host_dylib_path = host_path.join(host.to_lowercase());\n        let lib_fragment = if use_spectre_mitigated_libs(env_getter) {\n            r\"lib\\spectre\"\n        } else {\n            \"lib\"\n        };\n        let lib_path = path.join(lib_fragment).join(target_dir);\n        let alt_lib_path =\n            (target_arch == TargetArch::Arm64ec).then(|| path.join(lib_fragment).join(\"arm64ec\"));\n        let include_path = path.join(\"include\");\n        Some((\n            path,\n            bin_path,\n            host_dylib_path,\n            lib_path,\n            alt_lib_path,\n            include_path,\n        ))\n    }\n\n    fn vs15plus_vc_read_version(dir: &Path, env_getter: &dyn EnvGetter) -> Option<String> {\n        if let Some(version) = env_getter.get_env(\"VCToolsVersion\") {\n            // Restrict the search to a specific msvc version; if it doesn't exist then\n            // our caller will fail to find the tool for this instance and move on.\n            return version.to_str().map(ToString::to_string);\n        }\n\n        // Try to open the default version file.\n        let mut version_path: PathBuf =\n            dir.join(r\"VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt\");\n        let mut version_file = if let Ok(f) = File::open(&version_path) {\n            f\n        } else {\n            // If the default doesn't exist, search for other version files.\n            // These are in the form Microsoft.VCToolsVersion.v143.default.txt\n            // where `143` is any three decimal digit version number.\n            // This sorts versions by lexical order and selects the highest version.\n            let mut version_file = String::new();\n            version_path.pop();\n            for file in version_path.read_dir().ok()? {\n                let name = file.ok()?.file_name();\n                let name = name.to_str()?;\n                if name.starts_with(\"Microsoft.VCToolsVersion.v\")\n                    && name.ends_with(\".default.txt\")\n                    && name > &version_file\n                {\n                    version_file.replace_range(.., name);\n                }\n            }\n            if version_file.is_empty() {\n                // If all else fails, manually search for bin directories.\n                let tools_dir: PathBuf = dir.join(r\"VC\\Tools\\MSVC\");\n                return tools_dir\n                    .read_dir()\n                    .ok()?\n                    .filter_map(|file| {\n                        let file = file.ok()?;\n                        let name = file.file_name().into_string().ok()?;\n\n                        file.path().join(\"bin\").exists().then(|| {\n                            let version = parse_version(&name);\n                            (name, version)\n                        })\n                    })\n                    .max_by_key(|(_, version)| *version)\n                    .map(|(name, _)| name);\n            }\n            version_path.push(version_file);\n            File::open(version_path).ok()?\n        };\n\n        // Get the version string from the file we found.\n        let mut version = String::new();\n        version_file.read_to_string(&mut version).ok()?;\n        version.truncate(version.trim_end().len());\n        Some(version)\n    }\n\n    fn use_spectre_mitigated_libs(env_getter: &dyn EnvGetter) -> bool {\n        env_getter\n            .get_env(\"VSCMD_ARG_VCVARS_SPECTRE\")\n            .map(|env| env.as_ref() == \"spectre\")\n            .unwrap_or_default()\n    }\n\n    fn atl_paths(target: TargetArch, path: &Path) -> Option<(PathBuf, PathBuf)> {\n        let atl_path = path.join(\"atlmfc\");\n        atl_path.exists().then(|| {\n            let sub = target.as_vs_arch();\n            (atl_path.join(\"lib\").join(sub), atl_path.join(\"include\"))\n        })\n    }\n\n    // For MSVC 14 we need to find the Universal CRT as well as either\n    // the Windows 10 SDK or Windows 8.1 SDK.\n    pub(super) fn find_msvc_14(\n        tool: &str,\n        target: TargetArch,\n        env_getter: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        if env_getter.get_env(\"VCToolsVersion\").is_some() {\n            // VCToolsVersion is not set/supported for MSVC 14\n            return None;\n        }\n\n        let vcdir = get_vc_dir(\"14.0\")?;\n        let sdk_info = get_sdks(target, env_getter)?;\n        let mut tool = get_tool(tool, &vcdir, target, &sdk_info)?;\n        tool.add_sdk(sdk_info);\n        Some(tool.into_tool(env_getter))\n    }\n\n    pub(super) fn get_sdks(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<Sdk> {\n        let sub = target.as_vs_arch();\n        let (ucrt, ucrt_version) = get_ucrt_dir()?;\n\n        let host = match host_arch() {\n            X86 => \"x86\",\n            X86_64 => \"x64\",\n            AARCH64 => \"arm64\",\n            _ => return None,\n        };\n\n        let mut info = Sdk::default();\n\n        info.path\n            .push(ucrt.join(\"bin\").join(&ucrt_version).join(host));\n\n        let ucrt_include = ucrt.join(\"include\").join(&ucrt_version);\n        info.include.push(ucrt_include.join(\"ucrt\"));\n\n        let ucrt_lib = ucrt.join(\"lib\").join(&ucrt_version);\n        info.libs.push(ucrt_lib.join(\"ucrt\").join(sub));\n\n        if let Some((sdk, version)) = get_sdk10_dir(env_getter) {\n            info.path.push(sdk.join(\"bin\").join(host));\n            let sdk_lib = sdk.join(\"lib\").join(&version);\n            info.libs.push(sdk_lib.join(\"um\").join(sub));\n            let sdk_include = sdk.join(\"include\").join(&version);\n            info.include.push(sdk_include.join(\"um\"));\n            info.include.push(sdk_include.join(\"cppwinrt\"));\n            info.include.push(sdk_include.join(\"winrt\"));\n            info.include.push(sdk_include.join(\"shared\"));\n            info.version = version;\n        } else if let Some(sdk) = get_sdk81_dir() {\n            info.path.push(sdk.join(\"bin\").join(host));\n            let sdk_lib = sdk.join(\"lib\").join(\"winv6.3\");\n            info.libs.push(sdk_lib.join(\"um\").join(sub));\n            let sdk_include = sdk.join(\"include\");\n            info.include.push(sdk_include.join(\"um\"));\n            info.include.push(sdk_include.join(\"winrt\"));\n            info.include.push(sdk_include.join(\"shared\"));\n            info.version = \"8.1\".into();\n        }\n\n        Some(info)\n    }\n\n    fn add_env(\n        tool: &mut Tool,\n        env: &'static str,\n        paths: Vec<PathBuf>,\n        env_getter: &dyn EnvGetter,\n    ) {\n        let prev = env_getter.get_env(env);\n        let prev = prev.as_ref().map(AsRef::as_ref).unwrap_or_default();\n        let prev = env::split_paths(&prev);\n        let new = paths.into_iter().chain(prev);\n        tool.env\n            .push((env.to_string().into(), env::join_paths(new).unwrap()));\n    }\n\n    // Given a possible MSVC installation directory, we look for the linker and\n    // then add the MSVC library path.\n    fn get_tool(tool: &str, path: &Path, target: TargetArch, sdk_info: &Sdk) -> Option<MsvcTool> {\n        bin_subdir(target)\n            .into_iter()\n            .map(|(sub, host)| {\n                (\n                    path.join(\"bin\").join(sub).join(tool),\n                    Some(path.join(\"bin\").join(host)),\n                )\n            })\n            .filter(|(path, _)| path.is_file())\n            .chain(iter::once_with(|| Some((sdk_info.find_tool(tool)?, None))).flatten())\n            .map(|(tool_path, host)| {\n                let mut tool = MsvcTool::new(tool_path);\n                tool.path.extend(host);\n                let sub = vc_lib_subdir(target);\n                tool.libs.push(path.join(\"lib\").join(sub));\n                tool.include.push(path.join(\"include\"));\n                let atlmfc_path = path.join(\"atlmfc\");\n                if atlmfc_path.exists() {\n                    tool.libs.push(atlmfc_path.join(\"lib\").join(sub));\n                    tool.include.push(atlmfc_path.join(\"include\"));\n                }\n                tool\n            })\n            .next()\n    }\n\n    // To find MSVC we look in a specific registry key for the version we are\n    // trying to find.\n    fn get_vc_dir(ver: &str) -> Option<PathBuf> {\n        let key = r\"SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7\";\n        let key = LOCAL_MACHINE.open(key.as_ref()).ok()?;\n        let path = key.query_str(ver).ok()?;\n        Some(path.into())\n    }\n\n    // To find the Universal CRT we look in a specific registry key for where\n    // all the Universal CRTs are located and then sort them asciibetically to\n    // find the newest version. While this sort of sorting isn't ideal,  it is\n    // what vcvars does so that's good enough for us.\n    //\n    // Returns a pair of (root, version) for the ucrt dir if found\n    pub(super) fn get_ucrt_dir() -> Option<(PathBuf, String)> {\n        let key = r\"SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots\";\n        let key = LOCAL_MACHINE.open(key.as_ref()).ok()?;\n        let root = key.query_str(\"KitsRoot10\").ok()?;\n        let readdir = Path::new(&root).join(\"lib\").read_dir().ok()?;\n        let max_libdir = readdir\n            .filter_map(|dir| dir.ok())\n            .map(|dir| dir.path())\n            .filter(|dir| {\n                dir.components()\n                    .next_back()\n                    .and_then(|c| c.as_os_str().to_str())\n                    .map(|c| c.starts_with(\"10.\") && dir.join(\"ucrt\").is_dir())\n                    .unwrap_or(false)\n            })\n            .max()?;\n        let version = max_libdir.components().next_back().unwrap();\n        let version = version.as_os_str().to_str().unwrap().to_string();\n        Some((root.into(), version))\n    }\n\n    // Vcvars finds the correct version of the Windows 10 SDK by looking\n    // for the include `um\\Windows.h` because sometimes a given version will\n    // only have UCRT bits without the rest of the SDK. Since we only care about\n    // libraries and not includes, we instead look for `um\\x64\\kernel32.lib`.\n    // Since the 32-bit and 64-bit libraries are always installed together we\n    // only need to bother checking x64, making this code a tiny bit simpler.\n    // Like we do for the Universal CRT, we sort the possibilities\n    // asciibetically to find the newest one as that is what vcvars does.\n    // Before doing that, we check the \"WindowsSdkDir\" and \"WindowsSDKVersion\"\n    // environment variables set by vcvars to use the environment sdk version\n    // if one is already configured.\n    fn get_sdk10_dir(env_getter: &dyn EnvGetter) -> Option<(PathBuf, String)> {\n        if let (Some(root), Some(version)) = (\n            env_getter.get_env(\"WindowsSdkDir\"),\n            env_getter\n                .get_env(\"WindowsSDKVersion\")\n                .as_ref()\n                .and_then(|version| version.as_ref().to_str()),\n        ) {\n            return Some((\n                PathBuf::from(root),\n                version.trim_end_matches('\\\\').to_string(),\n            ));\n        }\n\n        let key = r\"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v10.0\";\n        let key = LOCAL_MACHINE.open(key.as_ref()).ok()?;\n        let root = key.query_str(\"InstallationFolder\").ok()?;\n        let readdir = Path::new(&root).join(\"lib\").read_dir().ok()?;\n        let mut dirs = readdir\n            .filter_map(|dir| dir.ok())\n            .map(|dir| dir.path())\n            .collect::<Vec<_>>();\n        dirs.sort();\n        let dir = dirs\n            .into_iter()\n            .rev()\n            .find(|dir| dir.join(\"um\").join(\"x64\").join(\"kernel32.lib\").is_file())?;\n        let version = dir.components().next_back().unwrap();\n        let version = version.as_os_str().to_str().unwrap().to_string();\n        Some((root.into(), version))\n    }\n\n    // Interestingly there are several subdirectories, `win7` `win8` and\n    // `winv6.3`. Vcvars seems to only care about `winv6.3` though, so the same\n    // applies to us. Note that if we were targeting kernel mode drivers\n    // instead of user mode applications, we would care.\n    fn get_sdk81_dir() -> Option<PathBuf> {\n        let key = r\"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v8.1\";\n        let key = LOCAL_MACHINE.open(key.as_ref()).ok()?;\n        let root = key.query_str(\"InstallationFolder\").ok()?;\n        Some(root.into())\n    }\n\n    const PROCESSOR_ARCHITECTURE_INTEL: u16 = 0;\n    const PROCESSOR_ARCHITECTURE_AMD64: u16 = 9;\n    const PROCESSOR_ARCHITECTURE_ARM64: u16 = 12;\n    const X86: u16 = PROCESSOR_ARCHITECTURE_INTEL;\n    const X86_64: u16 = PROCESSOR_ARCHITECTURE_AMD64;\n    const AARCH64: u16 = PROCESSOR_ARCHITECTURE_ARM64;\n\n    // When choosing the tool to use, we have to choose the one which matches\n    // the target architecture. Otherwise we end up in situations where someone\n    // on 32-bit Windows is trying to cross compile to 64-bit and it tries to\n    // invoke the native 64-bit compiler which won't work.\n    //\n    // For the return value of this function, the first member of the tuple is\n    // the folder of the tool we will be invoking, while the second member is\n    // the folder of the host toolchain for that tool which is essential when\n    // using a cross linker. We return a Vec since on x64 there are often two\n    // linkers that can target the architecture we desire. The 64-bit host\n    // linker is preferred, and hence first, due to 64-bit allowing it more\n    // address space to work with and potentially being faster.\n    fn bin_subdir(target: TargetArch) -> Vec<(&'static str, &'static str)> {\n        match (target, host_arch()) {\n            (TargetArch::X86, X86) => vec![(\"\", \"\")],\n            (TargetArch::X86, X86_64) => vec![(\"amd64_x86\", \"amd64\"), (\"\", \"\")],\n            (TargetArch::X64, X86) => vec![(\"x86_amd64\", \"\")],\n            (TargetArch::X64, X86_64) => vec![(\"amd64\", \"amd64\"), (\"x86_amd64\", \"\")],\n            (TargetArch::Arm, X86) => vec![(\"x86_arm\", \"\")],\n            (TargetArch::Arm, X86_64) => vec![(\"amd64_arm\", \"amd64\"), (\"x86_arm\", \"\")],\n            _ => vec![],\n        }\n    }\n\n    // MSVC's x86 libraries are not in a subfolder\n    fn vc_lib_subdir(target: TargetArch) -> &'static str {\n        match target {\n            TargetArch::X86 => \"\",\n            TargetArch::X64 => \"amd64\",\n            TargetArch::Arm => \"arm\",\n            TargetArch::Arm64 | TargetArch::Arm64ec => \"arm64\",\n        }\n    }\n\n    #[allow(bad_style)]\n    fn host_arch() -> u16 {\n        type DWORD = u32;\n        type WORD = u16;\n        type LPVOID = *mut u8;\n        type DWORD_PTR = usize;\n\n        #[repr(C)]\n        struct SYSTEM_INFO {\n            wProcessorArchitecture: WORD,\n            _wReserved: WORD,\n            _dwPageSize: DWORD,\n            _lpMinimumApplicationAddress: LPVOID,\n            _lpMaximumApplicationAddress: LPVOID,\n            _dwActiveProcessorMask: DWORD_PTR,\n            _dwNumberOfProcessors: DWORD,\n            _dwProcessorType: DWORD,\n            _dwAllocationGranularity: DWORD,\n            _wProcessorLevel: WORD,\n            _wProcessorRevision: WORD,\n        }\n\n        extern \"system\" {\n            fn GetNativeSystemInfo(lpSystemInfo: *mut SYSTEM_INFO);\n        }\n\n        unsafe {\n            let mut info = mem::zeroed();\n            GetNativeSystemInfo(&mut info);\n            info.wProcessorArchitecture\n        }\n    }\n\n    // Given a registry key, look at all the sub keys and find the one which has\n    // the maximal numeric value.\n    //\n    // Returns the name of the maximal key as well as the opened maximal key.\n    fn max_version(key: &RegistryKey) -> Option<(OsString, RegistryKey)> {\n        let mut max_vers = 0;\n        let mut max_key = None;\n        for subkey in key.iter().filter_map(|k| k.ok()) {\n            let val = subkey\n                .to_str()\n                .and_then(|s| s.trim_start_matches('v').replace('.', \"\").parse().ok());\n            let Some(val) = val else { continue };\n            if val > max_vers {\n                if let Ok(k) = key.open(&subkey) {\n                    max_vers = val;\n                    max_key = Some((subkey, k));\n                }\n            }\n        }\n        max_key\n    }\n\n    #[inline(always)]\n    pub(super) fn has_msbuild_version(version: &str, env_getter: &dyn EnvGetter) -> bool {\n        match version {\n            \"18.0\" => {\n                find_msbuild_vs18(TargetArch::X64, env_getter).is_some()\n                    || find_msbuild_vs18(TargetArch::X86, env_getter).is_some()\n                    || find_msbuild_vs18(TargetArch::Arm64, env_getter).is_some()\n            }\n            \"17.0\" => {\n                find_msbuild_vs17(TargetArch::X64, env_getter).is_some()\n                    || find_msbuild_vs17(TargetArch::X86, env_getter).is_some()\n                    || find_msbuild_vs17(TargetArch::Arm64, env_getter).is_some()\n            }\n            \"16.0\" => {\n                find_msbuild_vs16(TargetArch::X64, env_getter).is_some()\n                    || find_msbuild_vs16(TargetArch::X86, env_getter).is_some()\n                    || find_msbuild_vs16(TargetArch::Arm64, env_getter).is_some()\n            }\n            \"15.0\" => {\n                find_msbuild_vs15(TargetArch::X64, env_getter).is_some()\n                    || find_msbuild_vs15(TargetArch::X86, env_getter).is_some()\n                    || find_msbuild_vs15(TargetArch::Arm64, env_getter).is_some()\n            }\n            \"14.0\" => LOCAL_MACHINE\n                .open(&OsString::from(format!(\n                    \"SOFTWARE\\\\Microsoft\\\\MSBuild\\\\ToolsVersions\\\\{}\",\n                    version\n                )))\n                .is_ok(),\n            _ => false,\n        }\n    }\n\n    pub(super) fn find_devenv(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<Tool> {\n        find_devenv_vs15(target, env_getter)\n    }\n\n    fn find_devenv_vs15(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<Tool> {\n        find_tool_in_vs15_path(r\"Common7\\IDE\\devenv.exe\", target, env_getter)\n    }\n\n    // see http://stackoverflow.com/questions/328017/path-to-msbuild\n    pub(super) fn find_msbuild(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<Tool> {\n        // VS 15 (2017) changed how to locate msbuild\n        if let Some(r) = find_msbuild_vs18(target, env_getter) {\n            Some(r)\n        } else if let Some(r) = find_msbuild_vs17(target, env_getter) {\n            Some(r)\n        } else if let Some(r) = find_msbuild_vs16(target, env_getter) {\n            Some(r)\n        } else if let Some(r) = find_msbuild_vs15(target, env_getter) {\n            Some(r)\n        } else {\n            find_old_msbuild(target)\n        }\n    }\n\n    fn find_msbuild_vs15(target: TargetArch, env_getter: &dyn EnvGetter) -> Option<Tool> {\n        find_tool_in_vs15_path(r\"MSBuild\\15.0\\Bin\\MSBuild.exe\", target, env_getter)\n    }\n\n    fn find_old_msbuild(target: TargetArch) -> Option<Tool> {\n        let key = r\"SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\";\n        LOCAL_MACHINE\n            .open(key.as_ref())\n            .ok()\n            .and_then(|key| {\n                max_version(&key).and_then(|(_vers, key)| key.query_str(\"MSBuildToolsPath\").ok())\n            })\n            .map(|path| {\n                let mut path = PathBuf::from(path);\n                path.push(\"MSBuild.exe\");\n                let mut tool = Tool {\n                    tool: path,\n                    is_clang_cl: false,\n                    env: Vec::new(),\n                };\n                if target == TargetArch::X64 {\n                    tool.env.push((\"Platform\".into(), \"X64\".into()));\n                }\n                tool\n            })\n    }\n\n    #[cfg(test)]\n    mod tests {\n        use super::*;\n        use std::path::Path;\n        // Import the find function from the module level\n        use crate::find_tools::find;\n\n        fn host_arch_to_string(host_arch_value: u16) -> &'static str {\n            match host_arch_value {\n                X86 => \"x86\",\n                X86_64 => \"x64\",\n                AARCH64 => \"arm64\",\n                _ => panic!(\"Unsupported host architecture: {}\", host_arch_value),\n            }\n        }\n\n        #[test]\n        fn test_find_cl_exe() {\n            // Test that we can find cl.exe for common target architectures\n            // and validate the correct host-target combination paths\n            // This should pass on Windows CI with Visual Studio installed\n\n            let target_architectures = [\"x64\", \"x86\", \"arm64\"];\n            let mut found_any = false;\n\n            // Determine the host architecture\n            let host_arch_value = host_arch();\n            let host_name = host_arch_to_string(host_arch_value);\n\n            for &target_arch in &target_architectures {\n                if let Some(cmd) = find(target_arch, \"cl.exe\") {\n                    // Verify the command looks valid\n                    assert!(\n                        !cmd.get_program().is_empty(),\n                        \"cl.exe program path should not be empty\"\n                    );\n                    assert!(\n                        Path::new(cmd.get_program()).exists(),\n                        \"cl.exe should exist at: {:?}\",\n                        cmd.get_program()\n                    );\n\n                    // Verify the path contains the correct host-target combination\n                    // Use case-insensitive comparison since VS IDE uses \"Hostx64\" while Build Tools use \"HostX64\"\n                    let path_str = cmd.get_program().to_string_lossy();\n                    let path_str_lower = path_str.to_lowercase();\n                    let expected_host_target_path =\n                        format!(\"\\\\bin\\\\host{host_name}\\\\{target_arch}\");\n                    let expected_host_target_path_unix =\n                        expected_host_target_path.replace(\"\\\\\", \"/\");\n\n                    assert!(\n                        path_str_lower.contains(&expected_host_target_path) || path_str_lower.contains(&expected_host_target_path_unix),\n                        \"cl.exe path should contain host-target combination (case-insensitive) '{}' for {} host targeting {}, but found: {}\",\n                        expected_host_target_path,\n                        host_name,\n                        target_arch,\n                        path_str\n                    );\n\n                    found_any = true;\n                }\n            }\n\n            assert!(found_any, \"Expected to find cl.exe for at least one target architecture (x64, x86, or arm64) on Windows CI with Visual Studio installed\");\n        }\n\n        #[test]\n        #[cfg(not(disable_clang_cl_tests))]\n        fn test_find_llvm_tools() {\n            // Import StdEnvGetter from the parent module\n            use crate::find_tools::StdEnvGetter;\n\n            // Test the actual find_llvm_tool function with various LLVM tools\n            // This test assumes CI environment has Visual Studio + Clang installed\n            // We test against x64 target since clang can cross-compile to any target\n            let target_arch = TargetArch::new(\"x64\").expect(\"Should support x64 architecture\");\n            let llvm_tools = [\"clang.exe\", \"clang++.exe\", \"lld.exe\", \"llvm-ar.exe\"];\n\n            // Determine expected host-specific path based on host architecture\n            let host_arch_value = host_arch();\n            let expected_host_path = match host_arch_value {\n                X86 => \"LLVM\\\\bin\",            // x86 host\n                X86_64 => \"LLVM\\\\x64\\\\bin\",    // x64 host\n                AARCH64 => \"LLVM\\\\ARM64\\\\bin\", // arm64 host\n                _ => panic!(\"Unsupported host architecture: {}\", host_arch_value),\n            };\n\n            let host_name = host_arch_to_string(host_arch_value);\n\n            let mut found_tools_count = 0;\n\n            for &tool in &llvm_tools {\n                // Test finding LLVM tools using the standard environment getter\n                let env_getter = StdEnvGetter;\n                let result = find_llvm_tool(tool, target_arch, &env_getter);\n\n                if let Some(found_tool) = result {\n                    found_tools_count += 1;\n\n                    // Verify the found tool has a valid, non-empty path\n                    assert!(\n                        !found_tool.path().as_os_str().is_empty(),\n                        \"Found LLVM tool '{}' should have a non-empty path\",\n                        tool\n                    );\n\n                    // Verify the tool path actually exists on filesystem\n                    assert!(\n                        found_tool.path().exists(),\n                        \"LLVM tool '{}' path should exist: {:?}\",\n                        tool,\n                        found_tool.path()\n                    );\n\n                    // Verify the tool path contains the expected tool name\n                    let path_str = found_tool.path().to_string_lossy();\n                    assert!(\n                        path_str.contains(tool.trim_end_matches(\".exe\")),\n                        \"Tool path '{}' should contain tool name '{}'\",\n                        path_str,\n                        tool\n                    );\n\n                    // Verify it's in the correct host-specific VS LLVM directory\n                    assert!(\n                        path_str.contains(expected_host_path) || path_str.contains(&expected_host_path.replace(\"\\\\\", \"/\")),\n                        \"LLVM tool should be in host-specific VS LLVM directory '{}' for {} host, but found: {}\",\n                        expected_host_path,\n                        host_name,\n                        path_str\n                    );\n                }\n            }\n\n            // On CI with VS + Clang installed, we should find at least some LLVM tools\n            assert!(\n                found_tools_count > 0,\n                \"Expected to find at least one LLVM tool on CI with Visual Studio + Clang installed for {} host. Found: {}\",\n                host_name,\n                found_tools_count\n            );\n        }\n    }\n}\n\n/// Non-Windows Implementation.\n#[cfg(not(windows))]\nmod impl_ {\n    use std::{env, ffi::OsStr, path::PathBuf};\n\n    use super::{EnvGetter, Sdk, TargetArch};\n    use crate::Tool;\n\n    /// Finding msbuild.exe tool under unix system is not currently supported.\n    /// Maybe can check it using an environment variable looks like `MSBUILD_BIN`.\n    #[inline(always)]\n    pub(super) fn find_msbuild(_target: TargetArch, _: &dyn EnvGetter) -> Option<Tool> {\n        None\n    }\n\n    // Finding devenv.exe tool under unix system is not currently supported.\n    // Maybe can check it using an environment variable looks like `DEVENV_BIN`.\n    #[inline(always)]\n    pub(super) fn find_devenv(_target: TargetArch, _: &dyn EnvGetter) -> Option<Tool> {\n        None\n    }\n\n    // Finding Clang/LLVM-related tools on unix systems is not currently supported.\n    #[inline(always)]\n    pub(super) fn find_llvm_tool(\n        _tool: &str,\n        _target: TargetArch,\n        _: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        None\n    }\n\n    /// Attempt to find the tool using environment variables set by vcvars.\n    pub(super) fn find_msvc_environment(\n        tool: &str,\n        _target: TargetArch,\n        env_getter: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        // Early return if the environment doesn't contain a VC install.\n        let vc_install_dir = env_getter.get_env(\"VCINSTALLDIR\")?;\n        let vs_install_dir = env_getter.get_env(\"VSINSTALLDIR\")?;\n\n        let get_tool = |install_dir: &OsStr| {\n            env::split_paths(install_dir)\n                .map(|p| p.join(tool))\n                .find(|p| p.exists())\n                .map(|path| Tool {\n                    tool: path,\n                    is_clang_cl: false,\n                    env: Vec::new(),\n                })\n        };\n\n        // Take the path of tool for the vc install directory.\n        get_tool(vc_install_dir.as_ref())\n            // Take the path of tool for the vs install directory.\n            .or_else(|| get_tool(vs_install_dir.as_ref()))\n            // Take the path of tool for the current path environment.\n            .or_else(|| {\n                env_getter\n                    .get_env(\"PATH\")\n                    .as_ref()\n                    .map(|path| path.as_ref())\n                    .and_then(get_tool)\n            })\n    }\n\n    #[inline(always)]\n    pub(super) fn find_msvc_15plus(\n        _tool: &str,\n        _target: TargetArch,\n        _: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        None\n    }\n\n    // For MSVC 14 we need to find the Universal CRT as well as either\n    // the Windows 10 SDK or Windows 8.1 SDK.\n    #[inline(always)]\n    pub(super) fn find_msvc_14(\n        _tool: &str,\n        _target: TargetArch,\n        _: &dyn EnvGetter,\n    ) -> Option<Tool> {\n        None\n    }\n\n    #[inline(always)]\n    pub(super) fn has_msbuild_version(_version: &str, _: &dyn EnvGetter) -> bool {\n        false\n    }\n\n    #[inline(always)]\n    pub(super) fn get_ucrt_dir() -> Option<(PathBuf, String)> {\n        None\n    }\n\n    #[inline(always)]\n    pub(super) fn get_sdks(_target: TargetArch, _env_getter: &dyn EnvGetter) -> Option<Sdk> {\n        None\n    }\n}\n"
    },
    {
      "package": "find-msvc-tools@0.1.13",
      "sourcePath": "src/registry.rs",
      "sha256": "2c8f7ed919377df32ab5e55c1af438c542da8d1f6a4f7c9ebf337839d3fd96f5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::windows_sys::{\n    RegCloseKey, RegEnumKeyExW, RegOpenKeyExW, RegQueryValueExW, ERROR_NO_MORE_ITEMS,\n    ERROR_SUCCESS, HKEY, HKEY_LOCAL_MACHINE, KEY_READ, KEY_WOW64_32KEY, REG_SZ,\n};\nuse std::{\n    ffi::{OsStr, OsString},\n    io,\n    ops::RangeFrom,\n    os::windows::prelude::*,\n    ptr::null_mut,\n};\n\n/// Must never be `HKEY_PERFORMANCE_DATA`.\npub(crate) struct RegistryKey(Repr);\n\n#[allow(clippy::upper_case_acronyms)]\ntype DWORD = u32;\n\nstruct OwnedKey(HKEY);\n\n/// Note: must not encode `HKEY_PERFORMANCE_DATA` or one of its subkeys.\nenum Repr {\n    /// `HKEY_LOCAL_MACHINE`.\n    LocalMachine,\n    /// A subkey of `HKEY_LOCAL_MACHINE`.\n    Owned(OwnedKey),\n}\n\npub struct Iter<'a> {\n    idx: RangeFrom<DWORD>,\n    key: &'a RegistryKey,\n}\n\nunsafe impl Sync for Repr {}\nunsafe impl Send for Repr {}\n\npub(crate) const LOCAL_MACHINE: RegistryKey = RegistryKey(Repr::LocalMachine);\n\nimpl RegistryKey {\n    fn raw(&self) -> HKEY {\n        match self.0 {\n            Repr::LocalMachine => HKEY_LOCAL_MACHINE,\n            Repr::Owned(ref val) => val.0,\n        }\n    }\n\n    /// Open a sub-key of `self`.\n    pub fn open(&self, key: &OsStr) -> io::Result<RegistryKey> {\n        let key = key.encode_wide().chain(Some(0)).collect::<Vec<_>>();\n        let mut ret = null_mut();\n        let err = unsafe {\n            RegOpenKeyExW(\n                self.raw(),\n                key.as_ptr(),\n                0,\n                (KEY_READ | KEY_WOW64_32KEY).try_into().unwrap(),\n                &mut ret,\n            )\n        };\n        if err == ERROR_SUCCESS {\n            Ok(RegistryKey(Repr::Owned(OwnedKey(ret))))\n        } else {\n            Err(io::Error::from_raw_os_error(err as i32))\n        }\n    }\n\n    pub fn iter(&self) -> Iter<'_> {\n        Iter {\n            idx: 0..,\n            key: self,\n        }\n    }\n\n    pub fn query_str(&self, name: &str) -> io::Result<OsString> {\n        let name: &OsStr = name.as_ref();\n        let name = name.encode_wide().chain(Some(0)).collect::<Vec<_>>();\n        let mut len = 0;\n        let mut kind = 0;\n        unsafe {\n            let err = RegQueryValueExW(\n                self.raw(),\n                name.as_ptr(),\n                null_mut(),\n                &mut kind,\n                null_mut(),\n                &mut len,\n            );\n            if err != ERROR_SUCCESS {\n                return Err(io::Error::from_raw_os_error(err as i32));\n            }\n            if kind != REG_SZ {\n                return Err(io::Error::new(\n                    io::ErrorKind::Other,\n                    \"registry key wasn't a string\",\n                ));\n            }\n\n            // The length here is the length in bytes, but we're using wide\n            // characters so we need to be sure to halve it for the length\n            // passed in.\n            assert!(len % 2 == 0, \"impossible wide string size: {} bytes\", len);\n            let vlen = len as usize / 2;\n            // Defensively initialized, see comment about\n            // `HKEY_PERFORMANCE_DATA` below.\n            let mut v = vec![0u16; vlen];\n            let err = RegQueryValueExW(\n                self.raw(),\n                name.as_ptr(),\n                null_mut(),\n                null_mut(),\n                v.as_mut_ptr().cast(),\n                &mut len,\n            );\n            // We don't check for `ERROR_MORE_DATA` (which would if the value\n            // grew between the first and second call to `RegQueryValueExW`),\n            // both because it's extremely unlikely, and this is a bit more\n            // defensive more defensive against weird types of registry keys.\n            if err != ERROR_SUCCESS {\n                return Err(io::Error::from_raw_os_error(err as i32));\n            }\n            // The length is allowed to change, but should still be even, as\n            // well as smaller.\n            assert!(len % 2 == 0, \"impossible wide string size: {} bytes\", len);\n            // If the length grew but returned a success code, it *probably*\n            // indicates we're `HKEY_PERFORMANCE_DATA` or a subkey(?). We\n            // consider this UB, since those keys write \"undefined\" or\n            // \"unpredictable\" values to len, and need to use a completely\n            // different loop structure. This should be impossible (and enforce\n            // it in the API to the best of our ability), but to mitigate the\n            // damage we do some smoke-checks on the len, and ensure `v` has\n            // been fully initialized (rather than trusting the result of\n            // `RegQueryValueExW`).\n            let actual_len = len as usize / 2;\n            assert!(actual_len <= v.len());\n            v.truncate(actual_len);\n            // Some registry keys may have a terminating nul character, but\n            // we're not interested in that, so chop it off if it's there.\n            if !v.is_empty() && v[v.len() - 1] == 0 {\n                v.pop();\n            }\n            Ok(OsString::from_wide(&v))\n        }\n    }\n}\n\nimpl Drop for OwnedKey {\n    fn drop(&mut self) {\n        unsafe {\n            RegCloseKey(self.0);\n        }\n    }\n}\n\nimpl<'a> Iterator for Iter<'a> {\n    type Item = io::Result<OsString>;\n\n    fn next(&mut self) -> Option<io::Result<OsString>> {\n        self.idx.next().and_then(|i| unsafe {\n            let mut v = Vec::with_capacity(256);\n            let mut len = v.capacity() as DWORD;\n            let ret = RegEnumKeyExW(\n                self.key.raw(),\n                i,\n                v.as_mut_ptr(),\n                &mut len,\n                null_mut(),\n                null_mut(),\n                null_mut(),\n                null_mut(),\n            );\n            if ret == ERROR_NO_MORE_ITEMS {\n                None\n            } else if ret != ERROR_SUCCESS {\n                Some(Err(io::Error::from_raw_os_error(ret as i32)))\n            } else {\n                v.set_len(len as usize);\n                Some(Ok(OsString::from_wide(&v)))\n            }\n        })\n    }\n}\n"
    },
    {
      "package": "find-msvc-tools@0.1.13",
      "sourcePath": "src/setup_config.rs",
      "sha256": "397bd3c353a22edc4dfa8651b97cdf20e36f70526fda78d9bbf5dced3048f6d1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright © 2017 winapi-rs developers\n// Licensed under the Apache License, Version 2.0\n// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.\n// All files in the project carrying such notice may not be copied, modified, or distributed\n// except according to those terms.\n\n#![allow(bad_style)]\n#![allow(unused)]\n\nuse crate::{\n    com::{BStr, ComPtr},\n    winapi::{\n        IUnknown, IUnknownVtbl, Interface, LCID, LPCOLESTR, LPCWSTR, LPFILETIME, LPSAFEARRAY,\n        PULONGLONG, ULONG,\n    },\n    windows_sys::{CoCreateInstance, BSTR, CLSCTX_ALL, HRESULT, S_FALSE},\n};\n\nuse std::{\n    ffi::OsString,\n    ptr::{null, null_mut},\n};\n\n// Bindings to the Setup.Configuration stuff\npub type InstanceState = u32;\n\npub const eNone: InstanceState = 0;\npub const eLocal: InstanceState = 1;\npub const eRegistered: InstanceState = 2;\npub const eNoRebootRequired: InstanceState = 4;\npub const eComplete: InstanceState = -1i32 as u32;\n\nRIDL! {#[uuid(0xb41463c3, 0x8866, 0x43b5, 0xbc, 0x33, 0x2b, 0x06, 0x76, 0xf7, 0xf4, 0x2e)]\ninterface ISetupInstance(ISetupInstanceVtbl): IUnknown(IUnknownVtbl) {\n    fn GetInstanceId(\n        pbstrInstanceId: *mut BSTR,\n    ) -> HRESULT,\n    fn GetInstallDate(\n        pInstallDate: LPFILETIME,\n    ) -> HRESULT,\n    fn GetInstallationName(\n        pbstrInstallationName: *mut BSTR,\n    ) -> HRESULT,\n    fn GetInstallationPath(\n        pbstrInstallationPath: *mut BSTR,\n    ) -> HRESULT,\n    fn GetInstallationVersion(\n        pbstrInstallationVersion: *mut BSTR,\n    ) -> HRESULT,\n    fn GetDisplayName(\n        lcid: LCID,\n        pbstrDisplayName: *mut BSTR,\n    ) -> HRESULT,\n    fn GetDescription(\n        lcid: LCID,\n        pbstrDescription: *mut BSTR,\n    ) -> HRESULT,\n    fn ResolvePath(\n        pwszRelativePath: LPCOLESTR,\n        pbstrAbsolutePath: *mut BSTR,\n    ) -> HRESULT,\n}}\n\nRIDL! {#[uuid(0x89143c9a, 0x05af, 0x49b0, 0xb7, 0x17, 0x72, 0xe2, 0x18, 0xa2, 0x18, 0x5c)]\ninterface ISetupInstance2(ISetupInstance2Vtbl): ISetupInstance(ISetupInstanceVtbl) {\n    fn GetState(\n        pState: *mut InstanceState,\n    ) -> HRESULT,\n    fn GetPackages(\n        ppsaPackages: *mut LPSAFEARRAY,\n    ) -> HRESULT,\n    fn GetProduct(\n        ppPackage: *mut *mut ISetupPackageReference,\n    ) -> HRESULT,\n    fn GetProductPath(\n        pbstrProductPath: *mut BSTR,\n    ) -> HRESULT,\n}}\n\nRIDL! {#[uuid(0x6380bcff, 0x41d3, 0x4b2e, 0x8b, 0x2e, 0xbf, 0x8a, 0x68, 0x10, 0xc8, 0x48)]\ninterface IEnumSetupInstances(IEnumSetupInstancesVtbl): IUnknown(IUnknownVtbl) {\n    fn Next(\n        celt: ULONG,\n        rgelt: *mut *mut ISetupInstance,\n        pceltFetched: *mut ULONG,\n    ) -> HRESULT,\n    fn Skip(\n        celt: ULONG,\n    ) -> HRESULT,\n    fn Reset() -> HRESULT,\n    fn Clone(\n        ppenum: *mut *mut IEnumSetupInstances,\n    ) -> HRESULT,\n}}\n\nRIDL! {#[uuid(0x42843719, 0xdb4c, 0x46c2, 0x8e, 0x7c, 0x64, 0xf1, 0x81, 0x6e, 0xfd, 0x5b)]\ninterface ISetupConfiguration(ISetupConfigurationVtbl): IUnknown(IUnknownVtbl) {\n    fn EnumInstances(\n        ppEnumInstances: *mut *mut IEnumSetupInstances,\n    ) -> HRESULT,\n    fn GetInstanceForCurrentProcess(\n        ppInstance: *mut *mut ISetupInstance,\n    ) -> HRESULT,\n    fn GetInstanceForPath(\n        wzPath: LPCWSTR,\n        ppInstance: *mut *mut ISetupInstance,\n    ) -> HRESULT,\n}}\n\nRIDL! {#[uuid(0x26aab78c, 0x4a60, 0x49d6, 0xaf, 0x3b, 0x3c, 0x35, 0xbc, 0x93, 0x36, 0x5d)]\ninterface ISetupConfiguration2(ISetupConfiguration2Vtbl):\n    ISetupConfiguration(ISetupConfigurationVtbl) {\n    fn EnumAllInstances(\n        ppEnumInstances: *mut *mut IEnumSetupInstances,\n    ) -> HRESULT,\n}}\n\nRIDL! {#[uuid(0xda8d8a16, 0xb2b6, 0x4487, 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5)]\ninterface ISetupPackageReference(ISetupPackageReferenceVtbl): IUnknown(IUnknownVtbl) {\n    fn GetId(\n        pbstrId: *mut BSTR,\n    ) -> HRESULT,\n    fn GetVersion(\n        pbstrVersion: *mut BSTR,\n    ) -> HRESULT,\n    fn GetChip(\n        pbstrChip: *mut BSTR,\n    ) -> HRESULT,\n    fn GetLanguage(\n        pbstrLanguage: *mut BSTR,\n    ) -> HRESULT,\n    fn GetBranch(\n        pbstrBranch: *mut BSTR,\n    ) -> HRESULT,\n    fn GetType(\n        pbstrType: *mut BSTR,\n    ) -> HRESULT,\n    fn GetUniqueId(\n        pbstrUniqueId: *mut BSTR,\n    ) -> HRESULT,\n}}\n\nRIDL! {#[uuid(0x42b21b78, 0x6192, 0x463e, 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c)]\ninterface ISetupHelper(ISetupHelperVtbl): IUnknown(IUnknownVtbl) {\n    fn ParseVersion(\n        pwszVersion: LPCOLESTR,\n        pullVersion: PULONGLONG,\n    ) -> HRESULT,\n    fn ParseVersionRange(\n        pwszVersionRange: LPCOLESTR,\n        pullMinVersion: PULONGLONG,\n        pullMaxVersion: PULONGLONG,\n    ) -> HRESULT,\n}}\n\nDEFINE_GUID! {CLSID_SetupConfiguration,\n0x177f0c4a, 0x1cd3, 0x4de7, 0xa3, 0x2c, 0x71, 0xdb, 0xbb, 0x9f, 0xa3, 0x6d}\n\n// Safe wrapper around the COM interfaces\npub struct SetupConfiguration(ComPtr<ISetupConfiguration>);\n\nimpl SetupConfiguration {\n    pub fn new() -> Result<SetupConfiguration, i32> {\n        let mut obj = null_mut();\n        let err = unsafe {\n            CoCreateInstance(\n                &CLSID_SetupConfiguration,\n                null_mut(),\n                CLSCTX_ALL.try_into().unwrap(),\n                &ISetupConfiguration::uuidof(),\n                &mut obj,\n            )\n        };\n        if err < 0 {\n            return Err(err);\n        }\n        let obj = unsafe { ComPtr::from_raw(obj.cast()) };\n        Ok(SetupConfiguration(obj))\n    }\n    pub fn get_instance_for_current_process(&self) -> Result<SetupInstance, i32> {\n        let mut obj = null_mut();\n        let err = unsafe { self.0.GetInstanceForCurrentProcess(&mut obj) };\n        if err < 0 {\n            return Err(err);\n        }\n        Ok(unsafe { SetupInstance::from_raw(obj) })\n    }\n    pub fn enum_instances(&self) -> Result<EnumSetupInstances, i32> {\n        let mut obj = null_mut();\n        let err = unsafe { self.0.EnumInstances(&mut obj) };\n        if err < 0 {\n            return Err(err);\n        }\n        Ok(unsafe { EnumSetupInstances::from_raw(obj) })\n    }\n    pub fn enum_all_instances(&self) -> Result<EnumSetupInstances, i32> {\n        let mut obj = null_mut();\n        let this = self.0.cast::<ISetupConfiguration2>()?;\n        let err = unsafe { this.EnumAllInstances(&mut obj) };\n        if err < 0 {\n            return Err(err);\n        }\n        Ok(unsafe { EnumSetupInstances::from_raw(obj) })\n    }\n}\n\npub struct SetupInstance(ComPtr<ISetupInstance>);\n\nimpl SetupInstance {\n    pub unsafe fn from_raw(obj: *mut ISetupInstance) -> SetupInstance {\n        SetupInstance(ComPtr::from_raw(obj))\n    }\n    pub fn instance_id(&self) -> Result<OsString, i32> {\n        let mut s = null();\n        let err = unsafe { self.0.GetInstanceId(&mut s) };\n        let bstr = unsafe { BStr::from_raw(s) };\n        if err < 0 {\n            return Err(err);\n        }\n        Ok(bstr.to_osstring())\n    }\n    pub fn installation_name(&self) -> Result<OsString, i32> {\n        let mut s = null();\n        let err = unsafe { self.0.GetInstallationName(&mut s) };\n        let bstr = unsafe { BStr::from_raw(s) };\n        if err < 0 {\n            return Err(err);\n        }\n        Ok(bstr.to_osstring())\n    }\n    pub fn installation_path(&self) -> Result<OsString, i32> {\n        let mut s = null();\n        let err = unsafe { self.0.GetInstallationPath(&mut s) };\n        let bstr = unsafe { BStr::from_raw(s) };\n        if err < 0 {\n            return Err(err);\n        }\n        Ok(bstr.to_osstring())\n    }\n    pub fn installation_version(&self) -> Result<OsString, i32> {\n        let mut s = null();\n        let err = unsafe { self.0.GetInstallationVersion(&mut s) };\n        let bstr = unsafe { BStr::from_raw(s) };\n        if err < 0 {\n            return Err(err);\n        }\n        Ok(bstr.to_osstring())\n    }\n    pub fn product_path(&self) -> Result<OsString, i32> {\n        let mut s = null();\n        let this = self.0.cast::<ISetupInstance2>()?;\n        let err = unsafe { this.GetProductPath(&mut s) };\n        let bstr = unsafe { BStr::from_raw(s) };\n        if err < 0 {\n            return Err(err);\n        }\n        Ok(bstr.to_osstring())\n    }\n}\n\npub struct EnumSetupInstances(ComPtr<IEnumSetupInstances>);\n\nimpl EnumSetupInstances {\n    pub unsafe fn from_raw(obj: *mut IEnumSetupInstances) -> EnumSetupInstances {\n        EnumSetupInstances(ComPtr::from_raw(obj))\n    }\n}\n\nimpl Iterator for EnumSetupInstances {\n    type Item = Result<SetupInstance, i32>;\n    fn next(&mut self) -> Option<Result<SetupInstance, i32>> {\n        let mut obj = null_mut();\n        let err = unsafe { self.0.Next(1, &mut obj, null_mut()) };\n        if err < 0 {\n            return Some(Err(err));\n        }\n        if err == S_FALSE {\n            return None;\n        }\n        Some(Ok(unsafe { SetupInstance::from_raw(obj) }))\n    }\n}\n"
    },
    {
      "package": "find-msvc-tools@0.1.13",
      "sourcePath": "src/winapi.rs",
      "sha256": "cfb3bae7f2fa9e1d91f813e3b6b66ede7a3822787d10b716189a46f14f31f24a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright © 2015-2017 winapi-rs developers\n// Licensed under the Apache License, Version 2.0\n// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.\n// All files in the project carrying such notice may not be copied, modified, or distributed\n// except according to those terms.\n\n#![allow(bad_style, clippy::upper_case_acronyms)]\n\npub type wchar_t = u16;\n\npub use crate::windows_sys::{FILETIME, GUID, HRESULT, SAFEARRAY};\n\npub type REFIID = *const IID;\npub type IID = GUID;\npub type ULONG = core::ffi::c_ulong;\npub type DWORD = u32;\npub type LPFILETIME = *mut FILETIME;\npub type OLECHAR = WCHAR;\npub type WCHAR = wchar_t;\npub type LPCOLESTR = *const OLECHAR;\npub type LCID = DWORD;\npub type LPCWSTR = *const WCHAR;\npub type PULONGLONG = *mut ULONGLONG;\npub type ULONGLONG = u64;\n\npub trait Interface {\n    fn uuidof() -> GUID;\n}\n\npub type LPSAFEARRAY = *mut SAFEARRAY;\n\nmacro_rules! DEFINE_GUID {\n    (\n        $name:ident, $l:expr, $w1:expr, $w2:expr,\n        $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr\n    ) => {\n        pub const $name: $crate::winapi::GUID = $crate::winapi::GUID {\n            data1: $l,\n            data2: $w1,\n            data3: $w2,\n            data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],\n        };\n    };\n}\n\nmacro_rules! RIDL {\n    (#[uuid($($uuid:expr),+)]\n    interface $interface:ident ($vtbl:ident) {$(\n        fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,\n    )+}) => (\n        #[repr(C)]\n        pub struct $vtbl {\n            $(pub $method: unsafe extern \"system\" fn(\n                This: *mut $interface,\n                $($p: $t),*\n            ) -> $rtr,)+\n        }\n        #[repr(C)]\n        pub struct $interface {\n            pub lpVtbl: *const $vtbl,\n        }\n        RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}}\n        RIDL!{@uuid $interface $($uuid),+}\n    );\n    (#[uuid($($uuid:expr),+)]\n    interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {\n    }) => (\n        #[repr(C)]\n        pub struct $vtbl {\n            pub parent: $pvtbl,\n        }\n        #[repr(C)]\n        pub struct $interface {\n            pub lpVtbl: *const $vtbl,\n        }\n        RIDL!{@deref $interface $pinterface}\n        RIDL!{@uuid $interface $($uuid),+}\n    );\n    (#[uuid($($uuid:expr),+)]\n    interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {$(\n        fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,\n    )+}) => (\n        #[repr(C)]\n        pub struct $vtbl {\n            pub parent: $pvtbl,\n            $(pub $method: unsafe extern \"system\" fn(\n                This: *mut $interface,\n                $($p: $t,)*\n            ) -> $rtr,)+\n        }\n        #[repr(C)]\n        pub struct $interface {\n            pub lpVtbl: *const $vtbl,\n        }\n        RIDL!{@impl $interface {$(fn $method($($p: $t,)*) -> $rtr,)+}}\n        RIDL!{@deref $interface $pinterface}\n        RIDL!{@uuid $interface $($uuid),+}\n    );\n    (@deref $interface:ident $pinterface:ident) => (\n        impl ::std::ops::Deref for $interface {\n            type Target = $pinterface;\n            #[inline]\n            fn deref(&self) -> &$pinterface {\n                unsafe { &*(self as *const Self).cast() }\n            }\n        }\n    );\n    (@impl $interface:ident {$(\n        fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,\n    )+}) => (\n        impl $interface {\n            $(#[inline] pub unsafe fn $method(&self, $($p: $t,)*) -> $rtr {\n                ((*self.lpVtbl).$method)(\n                    (self as *const Self).cast_mut(),\n                    $($p,)*\n                )\n            })+\n        }\n    );\n    (@uuid $interface:ident\n        $l:expr, $w1:expr, $w2:expr,\n        $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr\n    ) => (\n        impl $crate::winapi::Interface for $interface {\n            #[inline]\n            fn uuidof() -> $crate::winapi::GUID {\n                $crate::winapi::GUID {\n                    data1: $l,\n                    data2: $w1,\n                    data3: $w2,\n                    data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8],\n                }\n            }\n        }\n    );\n}\n\nRIDL! {#[uuid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)]\ninterface IUnknown(IUnknownVtbl) {\n    fn QueryInterface(\n        riid: REFIID,\n        ppvObject: *mut *mut core::ffi::c_void,\n    ) -> HRESULT,\n    fn AddRef() -> ULONG,\n    fn Release() -> ULONG,\n}}\n"
    },
    {
      "package": "flate2@1.1.10",
      "sourcePath": "README.md",
      "sha256": "f14e438f37a22eb8b81a1160b7dd15b8e37a2fdbcb32e729e00b9e639b370a66",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# flate2\n\n[![Crates.io](https://img.shields.io/crates/v/flate2.svg?maxAge=2592000)](https://crates.io/crates/flate2)\n[![Documentation](https://docs.rs/flate2/badge.svg)](https://docs.rs/flate2)\n\nA streaming compression/decompression library DEFLATE-based streams in Rust.\n\nThis crate by default uses the `miniz_oxide` crate, a port of `miniz.c` to pure\nRust. This crate also supports other [backends](#backends), such as the widely\navailable zlib library or the high-performance zlib-ng library.\n\nSupported formats:\n\n* deflate\n* zlib\n* gzip\n\n```toml\n# Cargo.toml\n[dependencies]\nflate2 = \"1.0\"\n```\n\n## MSRV (Minimum Supported Rust Version) Policy\n\nThis crate supports the current and previous stable versions of the Rust compiler.\nFor example, if the current stable is 1.80, this crate supports 1.80 and 1.79.\n\nOther compiler versions may work, but failures may not be treated as a `flate2` bug.\n\nThe `Cargo.toml` file specifies a `rust-version` for which builds of the current version\npassed at some point. This value is indicative only, and may change at any time.\n\nThe `rust-version` is a best-effort measured value and is different to the MSRV. The\n`rust-version` can be incremented by a PR in order to pass tests, as long as the MSRV\ncontinues to hold. When the `rust-version` increases, the next release should be a minor\nversion, to allow any affected users to pin to a previous minor version.\n\n## Compression\n\n```rust\nuse std::io::prelude::*;\nuse flate2::Compression;\nuse flate2::write::ZlibEncoder;\n\nfn main() {\n    let mut e = ZlibEncoder::new(Vec::new(), Compression::default());\n    e.write_all(b\"foo\");\n    e.write_all(b\"bar\");\n    let compressed_bytes = e.finish();\n}\n```\n\n## Decompression\n\n```rust,no_run\nuse std::io::prelude::*;\nuse flate2::read::GzDecoder;\n\nfn main() {\n    let mut d = GzDecoder::new(\"...\".as_bytes());\n    let mut s = String::new();\n    d.read_to_string(&mut s).unwrap();\n    println!(\"{}\", s);\n}\n```\n\n## Backends\n\nThe default `miniz_oxide` backend has the advantage of only using safe Rust.\n\nIf you want maximum performance while still benefiting from a Rust\nimplementation at the cost of some `unsafe`, you can use `zlib-rs`:\n\n```toml\n[dependencies]\nflate2 = { version = \"1.0.17\", features = [\"zlib-rs\"], default-features = false }\n```\n\n### C backends\n\nWhile zlib-rs is [the fastest overall](https://trifectatech.org/blog/zlib-rs-is-faster-than-c/),\nthe zlib-ng C library can be slightly faster in certain cases:\n\n```toml\n[dependencies]\nflate2 = { version = \"1.0.17\", features = [\"zlib-ng\"], default-features = false }\n```\n\nNote that the `\"zlib-ng\"` feature works even if some other part of your crate\ngraph depends on zlib.\n\nHowever, if you're already using another C or Rust library that depends on\nzlib, and you want to avoid including both zlib and zlib-ng, you can use that\nfor Rust code as well:\n\n```toml\n[dependencies]\nflate2 = { version = \"1.0.17\", features = [\"zlib\"], default-features = false }\n```\n\nOr, if you have C or Rust code that depends on zlib and you want to use zlib-ng\nvia libz-sys in zlib-compat mode, use:\n\n```toml\n[dependencies]\nflate2 = { version = \"1.0.17\", features = [\"zlib-ng-compat\"], default-features = false }\n```\n\nNote that when using the `\"zlib-ng-compat\"` feature, if any crate in your\ndependency graph explicitly requests stock zlib, or uses libz-sys directly\nwithout `default-features = false`, you'll get stock zlib rather than zlib-ng.\nSee [the libz-sys\nREADME](https://github.com/rust-lang/libz-sys/blob/main/README.md) for details.\nTo avoid that, use the `\"zlib-ng\"` feature instead.\n\n# License\n\nThis project is licensed under either of\n\n * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\n   https://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or\n   https://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this project by you, as defined in the Apache-2.0 license,\nshall be dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "flate2@1.1.10",
      "sourcePath": "src/bufreader.rs",
      "sha256": "20ffc9cb16f0b01ae50be49aaf33f3592e2805b7d6bd76b7ea04da72c428d281",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2013 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// <https://github.com/rust-lang/rust/blob/HEAD/COPYRIGHT>.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::io;\nuse crate::io::{BufRead, Read};\nuse alloc::boxed::Box;\nuse alloc::vec::Vec;\nuse core::cmp;\nuse core::mem;\n\npub struct BufReader<R> {\n    inner: R,\n    buf: Box<[u8]>,\n    pos: usize,\n    cap: usize,\n}\n\nimpl<R> ::core::fmt::Debug for BufReader<R>\nwhere\n    R: ::core::fmt::Debug,\n{\n    fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {\n        fmt.debug_struct(\"BufReader\")\n            .field(\"reader\", &self.inner)\n            .field(\n                \"buffer\",\n                &format_args!(\"{}/{}\", self.cap - self.pos, self.buf.len()),\n            )\n            .finish()\n    }\n}\n\nimpl<R: Read> BufReader<R> {\n    pub fn new(inner: R) -> BufReader<R> {\n        BufReader::with_buf(vec![0; 32 * 1024], inner)\n    }\n\n    pub fn with_buf(buf: Vec<u8>, inner: R) -> BufReader<R> {\n        BufReader {\n            inner,\n            buf: buf.into_boxed_slice(),\n            pos: 0,\n            cap: 0,\n        }\n    }\n}\n\nimpl<R> BufReader<R> {\n    pub fn get_ref(&self) -> &R {\n        &self.inner\n    }\n\n    pub fn get_mut(&mut self) -> &mut R {\n        &mut self.inner\n    }\n\n    pub fn into_inner(self) -> R {\n        self.inner\n    }\n\n    pub fn reset(&mut self, inner: R) -> R {\n        self.pos = 0;\n        self.cap = 0;\n        mem::replace(&mut self.inner, inner)\n    }\n}\n\nimpl<R: Read> Read for BufReader<R> {\n    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n        // If we don't have any buffered data and we're doing a massive read\n        // (larger than our internal buffer), bypass our internal buffer\n        // entirely.\n        if self.pos == self.cap && buf.len() >= self.buf.len() {\n            return self.inner.read(buf);\n        }\n        let nread = {\n            let mut rem = self.fill_buf()?;\n            rem.read(buf)?\n        };\n        self.consume(nread);\n        Ok(nread)\n    }\n}\n\nimpl<R: Read> BufRead for BufReader<R> {\n    fn fill_buf(&mut self) -> io::Result<&[u8]> {\n        // If we've reached the end of our internal buffer then we need to fetch\n        // some more data from the underlying reader.\n        if self.pos == self.cap {\n            self.cap = self.inner.read(&mut self.buf)?;\n            self.pos = 0;\n        }\n        Ok(&self.buf[self.pos..self.cap])\n    }\n\n    fn consume(&mut self, amt: usize) {\n        self.pos = cmp::min(self.pos + amt, self.cap);\n    }\n}\n"
    },
    {
      "package": "float-cmp@0.9.0",
      "sourcePath": "src/eq.rs",
      "sha256": "63978ad73d7144c3371491fd459d7e2ce9bdb672d121d9cb900556c5efd4cf92",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014-2020 Optimal Computing (NZ) Ltd.\n// Licensed under the MIT license.  See LICENSE for details.\n\nuse core::{f32, f64};\n#[cfg(feature = \"num-traits\")]\n#[allow(unused_imports)]\nuse num_traits::float::FloatCore;\nuse super::Ulps;\n\n/// A trait for approximate equality comparisons.\npub trait ApproxEq: Sized {\n    /// This type type defines a margin within which two values are to be\n    /// considered approximately equal. It must implement `Default` so that\n    /// `approx_eq()` can be called on unknown types.\n    type Margin: Copy + Default;\n\n    /// This method tests that the `self` and `other` values are equal within `margin`\n    /// of each other.\n    fn approx_eq<M: Into<Self::Margin>>(self, other: Self, margin: M) -> bool;\n\n    /// This method tests that the `self` and `other` values are not within `margin`\n    /// of each other.\n    fn approx_ne<M: Into<Self::Margin>>(self, other: Self, margin: M) -> bool {\n        !self.approx_eq(other, margin)\n    }\n}\n\n/// This type defines a margin within two `f32` values might be considered equal,\n/// and is intended as the associated type for the `ApproxEq` trait.\n///\n/// Two tests are used to determine approximate equality.\n///\n/// The first test considers two values approximately equal if they differ by <=\n/// `epsilon`. This will only succeed for very small numbers. Note that it may\n/// succeed even if the parameters are of differing signs, straddling zero.\n///\n/// The second test considers how many ULPs (units of least precision, units in\n/// the last place, which is the integer number of floating-point representations\n/// that the parameters are separated by) different the parameters are and considers\n/// them approximately equal if this is <= `ulps`. For large floating-point numbers,\n/// an ULP can be a rather large gap, but this kind of comparison is necessary\n/// because floating-point operations must round to the nearest representable value\n/// and so larger floating-point values accumulate larger errors.\n#[repr(C)]\n#[derive(Debug, Clone, Copy)]\npub struct F32Margin {\n    pub epsilon: f32,\n    pub ulps: i32\n}\nimpl Default for F32Margin {\n    #[inline]\n    fn default() -> F32Margin {\n        F32Margin {\n            epsilon: f32::EPSILON,\n            ulps: 4\n        }\n    }\n}\nimpl F32Margin {\n    #[inline]\n    pub fn zero() -> F32Margin {\n        F32Margin {\n            epsilon: 0.0,\n            ulps: 0\n        }\n    }\n    pub fn epsilon(self, epsilon: f32) -> Self {\n        F32Margin {\n            epsilon,\n            ..self\n        }\n    }\n    pub fn ulps(self, ulps: i32) -> Self {\n        F32Margin {\n            ulps,\n            ..self\n        }\n    }\n}\nimpl From<(f32, i32)> for F32Margin {\n    fn from(m: (f32, i32)) -> F32Margin {\n        F32Margin {\n            epsilon: m.0,\n            ulps: m.1\n        }\n    }\n}\n\nimpl ApproxEq for f32 {\n    type Margin = F32Margin;\n\n    fn approx_eq<M: Into<Self::Margin>>(self, other: f32, margin: M) -> bool {\n        let margin = margin.into();\n\n        // Check for exact equality first. This is often true, and so we get the\n        // performance benefit of only doing one compare in most cases.\n        self==other ||\n\n        // Perform epsilon comparison next\n            ((self - other).abs() <= margin.epsilon) ||\n\n        {\n            // Perform ulps comparion last\n            let diff: i32 = self.ulps(&other);\n            saturating_abs_i32!(diff) <= margin.ulps\n        }\n    }\n}\n\n#[test]\nfn f32_approx_eq_test1() {\n    let f: f32 = 0.0_f32;\n    let g: f32 = -0.0000000000000005551115123125783_f32;\n    assert!(f != g); // Should not be directly equal\n    assert!(f.approx_eq(g, (f32::EPSILON, 0)) == true);\n}\n#[test]\nfn f32_approx_eq_test2() {\n    let f: f32 = 0.0_f32;\n    let g: f32 = -0.0_f32;\n    assert!(f.approx_eq(g, (f32::EPSILON, 0)) == true);\n}\n#[test]\nfn f32_approx_eq_test3() {\n    let f: f32 = 0.0_f32;\n    let g: f32 = 0.00000000000000001_f32;\n    assert!(f.approx_eq(g, (f32::EPSILON, 0)) == true);\n}\n#[test]\nfn f32_approx_eq_test4() {\n    let f: f32 = 0.00001_f32;\n    let g: f32 = 0.00000000000000001_f32;\n    assert!(f.approx_eq(g, (f32::EPSILON, 0)) == false);\n}\n#[test]\nfn f32_approx_eq_test5() {\n    let f: f32 = 0.1_f32;\n    let mut sum: f32 = 0.0_f32;\n    for _ in 0_isize..10_isize { sum += f; }\n    let product: f32 = f * 10.0_f32;\n    assert!(sum != product); // Should not be directly equal:\n    assert!(sum.approx_eq(product, (f32::EPSILON, 1)) == true);\n    assert!(sum.approx_eq(product, F32Margin::zero()) == false);\n}\n#[test]\nfn f32_approx_eq_test6() {\n    let x: f32 = 1000000_f32;\n    let y: f32 = 1000000.1_f32;\n    assert!(x != y); // Should not be directly equal\n    assert!(x.approx_eq(y, (0.0, 2)) == true); // 2 ulps does it\n    // epsilon method no good here:\n    assert!(x.approx_eq(y, (1000.0 * f32::EPSILON, 0)) == false);\n}\n\n/// This type defines a margin within two `f64` values might be considered equal,\n/// and is intended as the associated type for the `ApproxEq` trait.\n///\n/// Two tests are used to determine approximate equality.\n///\n/// The first test considers two values approximately equal if they differ by <=\n/// `epsilon`. This will only succeed for very small numbers. Note that it may\n/// succeed even if the parameters are of differing signs, straddling zero.\n///\n/// The second test considers how many ULPs (units of least precision, units in\n/// the last place, which is the integer number of floating-point representations\n/// that the parameters are separated by) different the parameters are and considers\n/// them approximately equal if this is <= `ulps`. For large floating-point numbers,\n/// an ULP can be a rather large gap, but this kind of comparison is necessary\n/// because floating-point operations must round to the nearest representable value\n/// and so larger floating-point values accumulate larger errors.\n#[derive(Debug, Clone, Copy)]\npub struct F64Margin {\n    pub epsilon: f64,\n    pub ulps: i64\n}\nimpl Default for F64Margin {\n    #[inline]\n    fn default() -> F64Margin {\n        F64Margin {\n            epsilon: f64::EPSILON,\n            ulps: 4\n        }\n    }\n}\nimpl F64Margin {\n    #[inline]\n    pub fn zero() -> F64Margin {\n        F64Margin {\n            epsilon: 0.0,\n            ulps: 0\n        }\n    }\n    pub fn epsilon(self, epsilon: f64) -> Self {\n        F64Margin {\n            epsilon,\n            ..self\n        }\n    }\n    pub fn ulps(self, ulps: i64) -> Self {\n        F64Margin {\n            ulps,\n            ..self\n        }\n    }\n}\nimpl From<(f64, i64)> for F64Margin {\n    fn from(m: (f64, i64)) -> F64Margin {\n        F64Margin {\n            epsilon: m.0,\n            ulps: m.1\n        }\n    }\n}\n\nimpl ApproxEq for f64 {\n    type Margin = F64Margin;\n\n    fn approx_eq<M: Into<Self::Margin>>(self, other: f64, margin: M) -> bool {\n        let margin = margin.into();\n\n        // Check for exact equality first. This is often true, and so we get the\n        // performance benefit of only doing one compare in most cases.\n        self == other ||\n\n        // Perform epsilon comparison next\n            ((self - other).abs() <= margin.epsilon) ||\n\n        {\n            // Perform ulps comparion last\n            let diff: i64 = self.ulps(&other);\n            saturating_abs_i64!(diff) <= margin.ulps\n        }\n    }\n}\n\n#[test]\nfn f64_approx_eq_test1() {\n    let f: f64 = 0.0_f64;\n    let g: f64 = -0.0000000000000005551115123125783_f64;\n    assert!(f != g); // Should not be precisely equal.\n    assert!(f.approx_eq(g, (3.0 * f64::EPSILON, 0)) == true); // 3e is enough.\n    // ULPs test won't ever call these equal.\n}\n#[test]\nfn f64_approx_eq_test2() {\n    let f: f64 = 0.0_f64;\n    let g: f64 = -0.0_f64;\n    assert!(f.approx_eq(g, (f64::EPSILON, 0)) == true);\n}\n#[test]\nfn f64_approx_eq_test3() {\n    let f: f64 = 0.0_f64;\n    let g: f64 = 1e-17_f64;\n    assert!(f.approx_eq(g, (f64::EPSILON, 0)) == true);\n}\n#[test]\nfn f64_approx_eq_test4() {\n    let f: f64 = 0.00001_f64;\n    let g: f64 = 0.00000000000000001_f64;\n    assert!(f.approx_eq(g, (f64::EPSILON, 0)) == false);\n}\n#[test]\nfn f64_approx_eq_test5() {\n    let f: f64 = 0.1_f64;\n    let mut sum: f64 = 0.0_f64;\n    for _ in 0_isize..10_isize { sum += f; }\n    let product: f64 = f * 10.0_f64;\n    assert!(sum != product); // Should not be precisely equaly.\n    assert!(sum.approx_eq(product, (f64::EPSILON, 0)) == true);\n    assert!(sum.approx_eq(product, (0.0, 1)) == true);\n}\n#[test]\nfn f64_approx_eq_test6() {\n    let x: f64 = 1000000_f64;\n    let y: f64 = 1000000.0000000003_f64;\n    assert!(x != y); // Should not be precisely equal.\n    assert!(x.approx_eq(y, (0.0, 3)) == true);\n}\n#[test]\nfn f64_code_triggering_issue_20() {\n    assert_eq!((-25.0f64).approx_eq(25.0, (0.00390625, 1)), false);\n}\n\nimpl<T> ApproxEq for &[T]\nwhere T: Copy + ApproxEq {\n    type Margin = <T as ApproxEq>::Margin;\n\n    fn approx_eq<M: Into<Self::Margin>>(self, other: Self, margin: M) -> bool {\n        let margin = margin.into();\n        if self.len() != other.len() { return false; }\n        self.iter().zip(other.iter()).all(|(a,b)| {\n            a.approx_eq(*b, margin)\n        })\n    }\n}\n\n#[test]\nfn test_slices() {\n    assert!( [1.33, 2.4, 2.5].approx_eq(&[1.33, 2.4, 2.5], (0.0, 0_i64)) );\n    assert!( !  [1.33, 2.4, 2.6].approx_eq(&[1.33, 2.4, 2.5], (0.0, 0_i64)) );\n    assert!( !  [1.33, 2.4].approx_eq(&[1.33, 2.4, 2.5], (0.0, 0_i64)) );\n    assert!( !  [1.33, 2.4, 2.5].approx_eq(&[1.33, 2.4], (0.0, 0_i64)) );\n}\n\n"
    },
    {
      "package": "float-cmp@0.9.0",
      "sourcePath": "src/lib.rs",
      "sha256": "0be2c16ab1ca344bf8448e983e91b3ae41507d2e90e390433832ea83fdafb404",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014-2020 Optimal Computing (NZ) Ltd.\n// Licensed under the MIT license.  See LICENSE for details.\n\n//! # float-cmp\n//!\n//! float-cmp defines and implements traits for approximate comparison of floating point types\n//! which have fallen away from exact equality due to the limited precision available within\n//! floating point representations. Implementations of these traits are provided for `f32`\n//! and `f64` types.\n//!\n//! When I was a kid in the '80s, the programming rule was \"Never compare floating point\n//! numbers\". If you can follow that rule and still get the outcome you desire, then more\n//! power to you. However, if you really do need to compare them, this crate provides a\n//! reasonable way to do so.\n//!\n//! Another crate `efloat` offers another solution by providing a floating point type that\n//! tracks its error bounds as operations are performed on it, and thus can implement the\n//! `ApproxEq` trait in this crate more accurately, without specifying a `Margin`.\n//!\n//! The recommended go-to solution (although it may not be appropriate in all cases) is the\n//! `approx_eq()` function in the `ApproxEq` trait (or better yet, the macros).  For `f32`\n//! and `f64`, the `F32Margin` and `F64Margin` types are provided for specifying margins as\n//! both an epsilon value and an ULPs value, and defaults are provided via `Default`\n//! (although there is no perfect default value that is always appropriate, so beware).\n//!\n//! Several other traits are provided including `Ulps`, `ApproxEqUlps`, `ApproxOrdUlps`, and\n//! `ApproxEqRatio`.\n//!\n//! ## The problem\n//!\n//! Floating point operations must round answers to the nearest representable number. Multiple\n//! operations may result in an answer different from what you expect. In the following example,\n//! the assert will fail, even though the printed output says \"0.45 == 0.45\":\n//!\n//! ```should_panic\n//!   # extern crate float_cmp;\n//!   # use float_cmp::ApproxEq;\n//!   # fn main() {\n//!   let a: f32 = 0.15 + 0.15 + 0.15;\n//!   let b: f32 = 0.1 + 0.1 + 0.25;\n//!   println!(\"{} == {}\", a, b);\n//!   assert!(a==b)  // Fails, because they are not exactly equal\n//!   # }\n//! ```\n//!\n//! This fails because the correct answer to most operations isn't exactly representable, and so\n//! your computer's processor chooses to represent the answer with the closest value it has\n//! available. This introduces error, and this error can accumulate as multiple operations are\n//! performed.\n//!\n//! ## The solution\n//!\n//! With `ApproxEq`, we can get the answer we intend:\n//!\n//! ```\n//!   # #[macro_use]\n//!   # extern crate float_cmp;\n//!   # use float_cmp::{ApproxEq, F32Margin};\n//!   # fn main() {\n//!   let a: f32 = 0.15 + 0.15 + 0.15;\n//!   let b: f32 = 0.1 + 0.1 + 0.25;\n//!   println!(\"{} == {}\", a, b);\n//!   // They are equal, within 2 ulps\n//!   assert!( approx_eq!(f32, a, b, ulps = 2) );\n//!   # }\n//! ```\n//!\n//! ## Some explanation\n//!\n//! We use the term ULP (units of least precision, or units in the last place) to mean the\n//! difference between two adjacent floating point representations (adjacent meaning that there is\n//! no floating point number between them). This term is borrowed from prior work (personally I\n//! would have chosen \"quanta\"). The size of an ULP (measured as a float) varies\n//! depending on the exponents of the floating point numbers in question. That is a good thing,\n//! because as numbers fall away from equality due to the imprecise nature of their representation,\n//! they fall away in ULPs terms, not in absolute terms.  Pure epsilon-based comparisons are\n//! absolute and thus don't map well to the nature of the additive error issue. They work fine\n//! for many ranges of numbers, but not for others (consider comparing -0.0000000028\n//! to +0.00000097).\n//!\n//! ## Using this crate\n//!\n//! By default this crate enables the `ratio` module providing the `ApproxEqRatio` trait.  This\n//! feature pulls in `num-traits`.  If you disable this feature, you'll need to either enable\n//! `num-traits` directly or else enable the `std` feature; otherwise it won't compile. This crate\n//! is `#![no_std]` unless you enable the `std` feature.\n//!\n//! You can use the `ApproxEq` trait directly like so:\n//!\n//! ```\n//!   # extern crate float_cmp;\n//!   # use float_cmp::{ApproxEq, F32Margin};\n//!   # fn main() {\n//!   # let a: f32 = 0.15 + 0.15 + 0.15;\n//!   # let b: f32 = 0.1 + 0.1 + 0.25;\n//!     assert!( a.approx_eq(b, F32Margin { ulps: 2, epsilon: 0.0 }) );\n//!   # }\n//! ```\n//!\n//! We have implemented `From<(f32,i32)>` for `F32Margin` (and similarly for `F64Margin`)\n//! so you can use this shorthand:\n//!\n//! ```\n//!   # extern crate float_cmp;\n//!   # use float_cmp::{ApproxEq, F32Margin};\n//!   # fn main() {\n//!   # let a: f32 = 0.15 + 0.15 + 0.15;\n//!   # let b: f32 = 0.1 + 0.1 + 0.25;\n//!     assert!( a.approx_eq(b, (0.0, 2)) );\n//!   # }\n//! ```\n//!\n//! With macros, it is easier to be explicit about which type of margin you wish to set,\n//! without mentioning the other one (the other one will be zero). But the downside is\n//! that you have to specify the type you are dealing with:\n//!\n//! ```\n//!   # #[macro_use]\n//!   # extern crate float_cmp;\n//!   # use float_cmp::{ApproxEq, F32Margin};\n//!   # fn main() {\n//!   # let a: f32 = 0.15 + 0.15 + 0.15;\n//!   # let b: f32 = 0.1 + 0.1 + 0.25;\n//!     assert!( approx_eq!(f32, a, b, ulps = 2) );\n//!     assert!( approx_eq!(f32, a, b, epsilon = 0.00000003) );\n//!     assert!( approx_eq!(f32, a, b, epsilon = 0.00000003, ulps = 2) );\n//!     assert!( approx_eq!(f32, a, b, (0.0, 2)) );\n//!     assert!( approx_eq!(f32, a, b, F32Margin { epsilon: 0.0, ulps: 2 }) );\n//!     assert!( approx_eq!(f32, a, b, F32Margin::default()) );\n//!     assert!( approx_eq!(f32, a, b) ); // uses the default\n//!   # }\n//! ```\n//!\n//! For most cases, I recommend you use a smallish integer for the `ulps` parameter (1 to 5\n//! or so), and a similar small multiple of the floating point's EPSILON constant (1.0 to 5.0\n//! or so), but there are *plenty* of cases where this is insufficient.\n//!\n//! ## Implementing these traits\n//!\n//! You can implement `ApproxEq` for your own complex types like shown below.\n//! The floating point type `F` must be `Copy`, but for large types you can implement\n//! it for references to your type as shown.\n//!\n//! ```\n//! use float_cmp::ApproxEq;\n//!\n//! pub struct Vec2<F> {\n//!   pub x: F,\n//!   pub y: F,\n//! }\n//!\n//! impl<'a, M: Copy + Default, F: Copy + ApproxEq<Margin=M>> ApproxEq for &'a Vec2<F> {\n//!   type Margin = M;\n//!\n//!   fn approx_eq<T: Into<Self::Margin>>(self, other: Self, margin: T) -> bool {\n//!     let margin = margin.into();\n//!     self.x.approx_eq(other.x, margin)\n//!       && self.y.approx_eq(other.y, margin)\n//!   }\n//! }\n//! ```\n//!\n//! ## Non floating-point types\n//!\n//! `ApproxEq` can be implemented for non floating-point types as well, since `Margin` is\n//! an associated type.\n//!\n//! The `efloat` crate implements (or soon will implement) `ApproxEq` for a compound type\n//! that tracks floating point error bounds by checking if the error bounds overlap.\n//! In that case `type Margin = ()`.\n//!\n//! ## Inspiration\n//!\n//! This crate was inspired by this Random ASCII blog post:\n//!\n//! [https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/)\n\n#![cfg_attr(not(feature = \"std\"), no_std)]\n\n#[macro_use]\nmod macros;\n\nmod ulps;\npub use self::ulps::Ulps;\n\nmod ulps_eq;\npub use self::ulps_eq::ApproxEqUlps;\n\nmod eq;\npub use self::eq::{ApproxEq, F32Margin, F64Margin};\n\n#[cfg(feature=\"ratio\")]\nmod ratio;\n#[cfg(feature=\"ratio\")]\npub use self::ratio::ApproxEqRatio;\n"
    },
    {
      "package": "float-cmp@0.9.0",
      "sourcePath": "src/ratio.rs",
      "sha256": "ec6c8338c1c45d49b9df2748069dba883105730a7bb6542dfeaac1b778c16feb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014-2020 Optimal Computing (NZ) Ltd.\n// Licensed under the MIT license.  See LICENSE for details.\n\nuse core::cmp::PartialOrd;\nuse core::ops::{Sub, Div, Neg};\nuse num_traits::Zero;\n\n/// ApproxEqRatio is a trait for approximate equality comparisons bounding the ratio\n/// of the difference to the larger.\npub trait ApproxEqRatio : Div<Output = Self> + Sub<Output = Self> + Neg<Output = Self>\n    + PartialOrd + Zero + Sized + Copy\n{\n    /// This method tests if `self` and `other` are nearly equal by bounding the\n    /// difference between them to some number much less than the larger of the two.\n    /// This bound is set as the ratio of the difference to the larger.\n    fn approx_eq_ratio(&self, other: &Self, ratio: Self) -> bool {\n\n        // Not equal if signs are not equal\n        if *self < Self::zero() && *other > Self::zero() { return false; }\n        if *self > Self::zero() && *other < Self::zero() { return false; }\n\n        // Handle all zero cases\n        match (*self == Self::zero(), *other == Self::zero()) {\n            (true,true) => return true,\n            (true,false) => return false,\n            (false,true) => return false,\n            _ => { }\n        }\n\n        // abs\n        let (s,o) = if *self < Self::zero() {\n            (-*self, -*other)\n        } else {\n            (*self, *other)\n        };\n\n        let (smaller,larger) = if s < o {\n            (s,o)\n        } else {\n            (o,s)\n        };\n        let difference: Self = larger.sub(smaller);\n        let actual_ratio: Self = difference.div(larger);\n        actual_ratio < ratio\n    }\n\n    /// This method tests if `self` and `other` are not nearly equal by bounding the\n    /// difference between them to some number much less than the larger of the two.\n    /// This bound is set as the ratio of the difference to the larger.\n    #[inline]\n    fn approx_ne_ratio(&self, other: &Self, ratio: Self) -> bool {\n        !self.approx_eq_ratio(other, ratio)\n    }\n}\n\nimpl ApproxEqRatio for f32 { }\n\n#[test]\nfn f32_approx_eq_ratio_test1() {\n    let x: f32 = 0.00004_f32;\n    let y: f32 = 0.00004001_f32;\n    assert!(x.approx_eq_ratio(&y, 0.00025));\n    assert!(y.approx_eq_ratio(&x, 0.00025));\n    assert!(x.approx_ne_ratio(&y, 0.00024));\n    assert!(y.approx_ne_ratio(&x, 0.00024));\n}\n\n#[test]\nfn f32_approx_eq_ratio_test2() {\n    let x: f32 = 0.00000000001_f32;\n    let y: f32 = 0.00000000005_f32;\n    assert!(x.approx_eq_ratio(&y, 0.81));\n    assert!(y.approx_ne_ratio(&x, 0.79));\n}\n\n#[test]\nfn f32_approx_eq_ratio_test_zero_eq_zero_returns_true() {\n    let x: f32 = 0.0_f32;\n    assert!(x.approx_eq_ratio(&x,0.1) == true);\n}\n\n#[test]\nfn f32_approx_eq_ratio_test_zero_ne_zero_returns_false() {\n    let x: f32 = 0.0_f32;\n    assert!(x.approx_ne_ratio(&x,0.1) == false);\n}\n\n#[test]\nfn f32_approx_eq_ratio_test_against_a_zero_is_false() {\n    let x: f32 = 0.0_f32;\n    let y: f32 = 0.1_f32;\n    assert!(x.approx_eq_ratio(&y,0.1) == false);\n    assert!(y.approx_eq_ratio(&x,0.1) == false);\n}\n\n#[test]\nfn f32_approx_eq_ratio_test_negative_numbers() {\n    let x: f32 = -3.0_f32;\n    let y: f32 = -4.0_f32;\n    // -3 and -4 should not be equal at a ratio of 0.1\n    assert!(x.approx_eq_ratio(&y,0.1) == false);\n}\n\nimpl ApproxEqRatio for f64 { }\n\n#[test]\nfn f64_approx_eq_ratio_test1() {\n    let x: f64 = 0.000000004_f64;\n    let y: f64 = 0.000000004001_f64;\n    assert!(x.approx_eq_ratio(&y, 0.00025));\n    assert!(y.approx_eq_ratio(&x, 0.00025));\n    assert!(x.approx_ne_ratio(&y, 0.00024));\n    assert!(y.approx_ne_ratio(&x, 0.00024));\n}\n\n#[test]\nfn f64_approx_eq_ratio_test2() {\n    let x: f64 = 0.0000000000000001_f64;\n    let y: f64 = 0.0000000000000005_f64;\n    assert!(x.approx_eq_ratio(&y, 0.81));\n    assert!(y.approx_ne_ratio(&x, 0.79));\n}\n\n#[test]\nfn f64_approx_eq_ratio_test_zero_eq_zero_returns_true() {\n    let x: f64 = 0.0_f64;\n    assert!(x.approx_eq_ratio(&x,0.1) == true);\n}\n\n#[test]\nfn f64_approx_eq_ratio_test_zero_ne_zero_returns_false() {\n    let x: f64 = 0.0_f64;\n    assert!(x.approx_ne_ratio(&x,0.1) == false);\n}\n\n#[test]\nfn f64_approx_eq_ratio_test_negative_numbers() {\n    let x: f64 = -3.0_f64;\n    let y: f64 = -4.0_f64;\n    // -3 and -4 should not be equal at a ratio of 0.1\n    assert!(x.approx_eq_ratio(&y,0.1) == false);\n}\n"
    },
    {
      "package": "float-cmp@0.9.0",
      "sourcePath": "src/ulps.rs",
      "sha256": "15528c3b0007b9f8b588f9113040973e819adf6245fa99da1497ec153e62c7a0",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014-2020 Optimal Computing (NZ) Ltd.\n// Licensed under the MIT license.  See LICENSE for details.\n\n#[cfg(feature=\"num_traits\")]\nuse num_traits::NumCast;\n\n/// A trait for floating point numbers which computes the number of representable\n/// values or ULPs (Units of Least Precision) that separate the two given values.\n#[cfg(feature=\"num_traits\")]\npub trait Ulps {\n    type U: Copy + NumCast;\n\n    /// The number of representable values or ULPs (Units of Least Precision) that\n    /// separate `self` and `other`.  The result `U` is an integral value, and will\n    /// be zero if `self` and `other` are exactly equal.\n    fn ulps(&self, other: &Self) -> <Self as Ulps>::U;\n\n    /// The next representable number above this one\n    fn next(&self) -> Self;\n\n    /// The previous representable number below this one\n    fn prev(&self) -> Self;\n}\n\n#[cfg(not(feature=\"num_traits\"))]\npub trait Ulps {\n    type U: Copy;\n\n    /// The number of representable values or ULPs (Units of Least Precision) that\n    /// separate `self` and `other`.  The result `U` is an integral value, and will\n    /// be zero if `self` and `other` are exactly equal.\n    fn ulps(&self, other: &Self) -> <Self as Ulps>::U;\n\n    /// The next representable number above this one\n    fn next(&self) -> Self;\n\n    /// The previous representable number below this one\n    fn prev(&self) -> Self;\n}\n\nimpl Ulps for f32 {\n    type U = i32;\n\n    fn ulps(&self, other: &f32) -> i32 {\n\n        // IEEE754 defined floating point storage representation to\n        // maintain their order when their bit patterns are interpreted as\n        // integers.  This is a huge boon to the task at hand, as we can\n        // reinterpret them as integers to find out how many ULPs apart any\n        // two floats are\n\n        // Setup integer representations of the input\n        let ai32: i32 = self.to_bits() as i32;\n        let bi32: i32 = other.to_bits() as i32;\n\n        ai32.wrapping_sub(bi32)\n    }\n\n    fn next(&self) -> Self {\n        if self.is_infinite() && *self > 0.0 {\n            *self\n        } else if *self == -0.0 && self.is_sign_negative() {\n            0.0\n        } else {\n            let mut u = self.to_bits();\n            if *self >= 0.0 {\n                u += 1;\n            } else {\n                u -= 1;\n            }\n            f32::from_bits(u)\n        }\n    }\n\n    fn prev(&self) -> Self {\n        if self.is_infinite() && *self < 0.0 {\n            *self\n        } else if *self == 0.0 && self.is_sign_positive() {\n            -0.0\n        } else {\n            let mut u = self.to_bits();\n            if *self <= -0.0 {\n                u += 1;\n            } else {\n                u -= 1;\n            }\n            f32::from_bits(u)\n        }\n    }\n}\n\n#[test]\nfn f32_ulps_test1() {\n    let x: f32 = 1000000_f32;\n    let y: f32 = 1000000.1_f32;\n    assert!(x.ulps(&y) == -2);\n}\n\n#[test]\nfn f32_ulps_test2() {\n    let pzero: f32 = f32::from_bits(0x00000000_u32);\n    let nzero: f32 = f32::from_bits(0x80000000_u32);\n    assert!(pzero.ulps(&nzero) == -2147483648);\n}\n#[test]\nfn f32_ulps_test3() {\n    let pinf: f32 = f32::from_bits(0x7f800000_u32);\n    let ninf: f32 = f32::from_bits(0xff800000_u32);\n    assert!(pinf.ulps(&ninf) == -2147483648);\n}\n\n#[test]\nfn f32_ulps_test4() {\n    let x: f32 = f32::from_bits(0x63a7f026_u32);\n    let y: f32 = f32::from_bits(0x63a7f023_u32);\n    assert!(x.ulps(&y) == 3);\n}\n\n#[test]\nfn f32_ulps_test5() {\n    let x: f32 = 2.0;\n    let ulps: i32 = x.to_bits() as i32;\n    let x2: f32 = <f32>::from_bits(ulps as u32);\n    assert_eq!(x, x2);\n}\n\n#[test]\nfn f32_ulps_test6() {\n    let negzero: f32 = -0.;\n    let zero: f32 = 0.;\n    assert_eq!(negzero.next(), zero);\n    assert_eq!(zero.prev(), negzero);\n    assert!(negzero.prev() < 0.0);\n    assert!(zero.next() > 0.0);\n}\n\nimpl Ulps for f64 {\n    type U = i64;\n\n    fn ulps(&self, other: &f64) -> i64 {\n\n        // IEEE754 defined floating point storage representation to\n        // maintain their order when their bit patterns are interpreted as\n        // integers.  This is a huge boon to the task at hand, as we can\n        // reinterpret them as integers to find out how many ULPs apart any\n        // two floats are\n\n        // Setup integer representations of the input\n        let ai64: i64 = self.to_bits() as i64;\n        let bi64: i64 = other.to_bits() as i64;\n\n        ai64.wrapping_sub(bi64)\n    }\n\n    fn next(&self) -> Self {\n        if self.is_infinite() && *self > 0.0 {\n            *self\n        } else if *self == -0.0 && self.is_sign_negative() {\n            0.0\n        } else {\n            let mut u = self.to_bits();\n            if *self >= 0.0 {\n                u += 1;\n            } else {\n                u -= 1;\n            }\n            f64::from_bits(u)\n        }\n    }\n\n    fn prev(&self) -> Self {\n        if self.is_infinite() && *self < 0.0 {\n            *self\n        } else if *self == 0.0 && self.is_sign_positive() {\n            -0.0\n        } else {\n            let mut u = self.to_bits();\n            if *self <= -0.0 {\n                u += 1;\n            } else {\n                u -= 1;\n            }\n            f64::from_bits(u)\n        }\n    }\n}\n\n#[test]\nfn f64_ulps_test1() {\n    let x: f64 = 1000000_f64;\n    let y: f64 = 1000000.00000001_f64;\n    assert!(x.ulps(&y) == -86);\n}\n\n#[test]\nfn f64_ulps_test2() {\n    let pzero: f64 = f64::from_bits(0x0000000000000000_u64);\n    let nzero: f64 = f64::from_bits(0x8000000000000000_u64);\n    assert!(pzero.ulps(&nzero) == -9223372036854775808i64);\n}\n#[test]\nfn f64_ulps_test3() {\n    let pinf: f64 = f64::from_bits(0x7f80000000000000_u64);\n    let ninf: f64 = f64::from_bits(0xff80000000000000_u64);\n    assert!(pinf.ulps(&ninf) == -9223372036854775808i64);\n}\n\n#[test]\nfn f64_ulps_test4() {\n    let x: f64 = f64::from_bits(0xd017f6cc63a7f026_u64);\n    let y: f64 = f64::from_bits(0xd017f6cc63a7f023_u64);\n    assert!(x.ulps(&y) == 3);\n}\n\n#[test]\nfn f64_ulps_test5() {\n    let x: f64 = 2.0;\n    let ulps: i64 = x.to_bits() as i64;\n    let x2: f64 = <f64>::from_bits(ulps as u64);\n    assert_eq!(x, x2);\n}\n\n#[test]\nfn f64_ulps_test6() {\n    let negzero: f64 = -0.;\n    let zero: f64 = 0.;\n    assert_eq!(negzero.next(), zero);\n    assert_eq!(zero.prev(), negzero);\n    assert!(negzero.prev() < 0.0);\n    assert!(zero.next() > 0.0);\n}\n\n"
    },
    {
      "package": "float-cmp@0.9.0",
      "sourcePath": "src/ulps_eq.rs",
      "sha256": "87ad38eb13c31304962b29511d6f8215ab0b9f3b2b51545844678f81f83fb688",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014-2020 Optimal Computing (NZ) Ltd.\n// Licensed under the MIT license.  See LICENSE for details.\n\n#[cfg(feature = \"num-traits\")]\n#[allow(unused_imports)]\nuse num_traits::float::FloatCore;\nuse super::Ulps;\n\n/// ApproxEqUlps is a trait for approximate equality comparisons.\n/// The associated type Flt is a floating point type which implements Ulps, and is\n/// required so that this trait can be implemented for compound types (e.g. vectors),\n/// not just for the floats themselves.\npub trait ApproxEqUlps {\n    type Flt: Ulps;\n\n    /// This method tests for `self` and `other` values to be approximately equal\n    /// within ULPs (Units of Least Precision) floating point representations.\n    /// Differing signs are always unequal with this method, and zeroes are only\n    /// equal to zeroes. Use approx_eq() from the ApproxEq trait if that is more\n    /// appropriate.\n    fn approx_eq_ulps(&self, other: &Self, ulps: <Self::Flt as Ulps>::U) -> bool;\n\n    /// This method tests for `self` and `other` values to be not approximately\n    /// equal within ULPs (Units of Least Precision) floating point representations.\n    /// Differing signs are always unequal with this method, and zeroes are only\n    /// equal to zeroes. Use approx_eq() from the ApproxEq trait if that is more\n    /// appropriate.\n    #[inline]\n    fn approx_ne_ulps(&self, other: &Self, ulps: <Self::Flt as Ulps>::U) -> bool {\n        !self.approx_eq_ulps(other, ulps)\n    }\n}\n\nimpl ApproxEqUlps for f32 {\n    type Flt = f32;\n\n    fn approx_eq_ulps(&self, other: &f32, ulps: i32) -> bool {\n        // -0 and +0 are drastically far in ulps terms, so\n        // we need a special case for that.\n        if *self==*other { return true; }\n\n        // Handle differing signs as a special case, even if\n        // they are very close, most people consider them\n        // unequal.\n        if self.is_sign_positive() != other.is_sign_positive() { return false; }\n\n        let diff: i32 = self.ulps(other);\n        diff >= -ulps && diff <= ulps\n    }\n}\n\n#[test]\nfn f32_approx_eq_ulps_test1() {\n    let f: f32 = 0.1_f32;\n    let mut sum: f32 = 0.0_f32;\n    for _ in 0_isize..10_isize { sum += f; }\n    let product: f32 = f * 10.0_f32;\n    assert!(sum != product); // Should not be directly equal:\n    assert!(sum.approx_eq_ulps(&product,1) == true); // But should be close\n    assert!(sum.approx_eq_ulps(&product,0) == false);\n}\n#[test]\nfn f32_approx_eq_ulps_test2() {\n    let x: f32 = 1000000_f32;\n    let y: f32 = 1000000.1_f32;\n    assert!(x != y); // Should not be directly equal\n    assert!(x.approx_eq_ulps(&y,2) == true);\n    assert!(x.approx_eq_ulps(&y,1) == false);\n}\n#[test]\nfn f32_approx_eq_ulps_test_zeroes() {\n    let x: f32 = 0.0_f32;\n    let y: f32 = -0.0_f32;\n    assert!(x.approx_eq_ulps(&y,0) == true);\n}\n\nimpl ApproxEqUlps for f64 {\n    type Flt = f64;\n\n    fn approx_eq_ulps(&self, other: &f64, ulps: i64) -> bool {\n        // -0 and +0 are drastically far in ulps terms, so\n        // we need a special case for that.\n        if *self==*other { return true; }\n\n        // Handle differing signs as a special case, even if\n        // they are very close, most people consider them\n        // unequal.\n        if self.is_sign_positive() != other.is_sign_positive() { return false; }\n\n        let diff: i64 = self.ulps(other);\n        diff >= -ulps && diff <= ulps\n    }\n}\n\n#[test]\nfn f64_approx_eq_ulps_test1() {\n    let f: f64 = 0.1_f64;\n    let mut sum: f64 = 0.0_f64;\n    for _ in 0_isize..10_isize { sum += f; }\n    let product: f64 = f * 10.0_f64;\n    assert!(sum != product); // Should not be directly equal:\n    assert!(sum.approx_eq_ulps(&product,1) == true); // But should be close\n    assert!(sum.approx_eq_ulps(&product,0) == false);\n}\n#[test]\nfn f64_approx_eq_ulps_test2() {\n    let x: f64 = 1000000_f64;\n    let y: f64 = 1000000.0000000003_f64;\n    assert!(x != y); // Should not be directly equal\n    assert!(x.approx_eq_ulps(&y,3) == true);\n    assert!(x.approx_eq_ulps(&y,2) == false);\n}\n#[test]\nfn f64_approx_eq_ulps_test_zeroes() {\n    let x: f64 = 0.0_f64;\n    let y: f64 = -0.0_f64;\n    assert!(x.approx_eq_ulps(&y,0) == true);\n}\n"
    },
    {
      "package": "fontdb@0.14.1",
      "sourcePath": "tests/fonts/LICENSE.txt",
      "sha256": "b84fdd2c3da5db56385cdbb639795e90aa3e035c53bc3591135f18df3331451f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "We, the copyright holders of this work, hereby release it into the\npublic domain. This applies worldwide.\n\nIn case this is not legally possible,\n\nWe grant any entity the right to use this work for any purpose, without\nany conditions, unless such conditions are required by law.\n\nThatcher Ulrich <tu@tulrich.com> http://tulrich.com\nKaroly Barta bartakarcsi@gmail.com\nMichael Evans http://www.evertype.com\n"
    },
    {
      "package": "funty@2.0.0",
      "sourcePath": "LICENSE.txt",
      "sha256": "f790cc576999f5998c766d3d26d7d64dc368e805a98461484f65e8d961ec6d9f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "MIT License\n\nCopyright (c) 2020 myrrlyn (Alexander Payne)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
    },
    {
      "package": "futures@0.3.34",
      "sourcePath": "README.md",
      "sha256": "260fb7aba3cb6a6410da78f717172a96ab7b03ddc99beb8d78b107ffc3e5a6ae",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "<p align=\"center\">\n  <img alt=\"futures-rs\" src=\"https://raw.githubusercontent.com/rust-lang/futures-rs/gh-pages/assets/images/futures-rs-logo.svg?sanitize=true\" width=\"400\">\n</p>\n\n<p align=\"center\">\n  Zero-cost asynchronous programming in Rust\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/rust-lang/futures-rs/actions?query=branch%3Amain\">\n    <img alt=\"Build Status\" src=\"https://img.shields.io/github/actions/workflow/status/rust-lang/futures-rs/ci.yml?branch=main\">\n  </a>\n\n  <a href=\"https://crates.io/crates/futures\">\n    <img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/futures.svg\">\n  </a>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://docs.rs/futures\">\n    Documentation\n  </a> | <a href=\"https://rust-lang.github.io/futures-rs/\">\n    Website\n  </a>\n</p>\n\n`futures-rs` is a library providing the foundations for asynchronous programming in Rust.\nIt includes key trait definitions like `Stream`, as well as utilities like `join!`,\n`select!`, and various futures combinator methods which enable expressive asynchronous\ncontrol flow.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfutures = \"0.3\"\n```\n\nThe current `futures` requires Rust 1.71 or later.\n\n### Feature `std`\n\nFutures-rs works without the standard library, such as in bare metal environments.\nHowever, it has a significantly reduced API surface. To use futures-rs in\na `#[no_std]` environment, use:\n\n```toml\n[dependencies]\nfutures = { version = \"0.3\", default-features = false }\n```\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "futures-channel@0.3.34",
      "sourcePath": "README.md",
      "sha256": "76d57b08b50a525e00265477b582a6bbcf82ec17bdce3a808f55f70358a83552",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# futures-channel\n\nChannels for asynchronous communication using futures-rs.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfutures-channel = \"0.3\"\n```\n\nThe current `futures-channel` requires Rust 1.71 or later.\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "futures-channel@0.3.34",
      "sourcePath": "src/mpsc/queue.rs",
      "sha256": "22034085dc22050b708a37854e215fc7cbb16d65edc60370cb5d8f4b7faca18e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n *    1. Redistributions of source code must retain the above copyright notice,\n *       this list of conditions and the following disclaimer.\n *\n *    2. Redistributions in binary form must reproduce the above copyright\n *       notice, this list of conditions and the following disclaimer in the\n *       documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV \"AS IS\" AND ANY EXPRESS OR IMPLIED\n * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * The views and conclusions contained in the software and documentation are\n * those of the authors and should not be interpreted as representing official\n * policies, either expressed or implied, of Dmitry Vyukov.\n */\n\n//! A mostly lock-free multi-producer, single consumer queue for sending\n//! messages between asynchronous tasks.\n//!\n//! The queue implementation is essentially the same one used for mpsc channels\n//! in the standard library.\n//!\n//! Note that the current implementation of this queue has a caveat of the `pop`\n//! method, and see the method for more information about it. Due to this\n//! caveat, this queue may not be appropriate for all use-cases.\n\n// http://www.1024cores.net/home/lock-free-algorithms\n//                         /queues/non-intrusive-mpsc-node-based-queue\n\n// NOTE: this implementation is lifted from the standard library and only\n//       slightly modified\n\npub(super) use self::PopResult::*;\n\nuse std::boxed::Box;\nuse std::cell::UnsafeCell;\nuse std::ptr;\nuse std::sync::atomic::{AtomicPtr, Ordering};\nuse std::thread;\n\n/// A result of the `pop` function.\npub(super) enum PopResult<T> {\n    /// Some data has been popped\n    Data(T),\n    /// The queue is empty\n    Empty,\n    /// The queue is in an inconsistent state. Popping data should succeed, but\n    /// some pushers have yet to make enough progress in order allow a pop to\n    /// succeed. It is recommended that a pop() occur \"in the near future\" in\n    /// order to see if the sender has made progress or not\n    Inconsistent,\n}\n\nstruct Node<T> {\n    next: AtomicPtr<Self>,\n    value: Option<T>,\n}\n\n/// The multi-producer single-consumer structure. This is not cloneable, but it\n/// may be safely shared so long as it is guaranteed that there is only one\n/// popper at a time (many pushers are allowed).\npub(super) struct Queue<T> {\n    head: AtomicPtr<Node<T>>,\n    tail: UnsafeCell<*mut Node<T>>,\n}\n\nunsafe impl<T: Send> Send for Queue<T> {}\nunsafe impl<T: Send> Sync for Queue<T> {}\n\nimpl<T> Node<T> {\n    unsafe fn new(v: Option<T>) -> *mut Self {\n        Box::into_raw(Box::new(Self { next: AtomicPtr::new(ptr::null_mut()), value: v }))\n    }\n}\n\nimpl<T> Queue<T> {\n    /// Creates a new queue that is safe to share among multiple producers and\n    /// one consumer.\n    pub(super) fn new() -> Self {\n        let stub = unsafe { Node::new(None) };\n        Self { head: AtomicPtr::new(stub), tail: UnsafeCell::new(stub) }\n    }\n\n    /// Pushes a new value onto this queue.\n    pub(super) fn push(&self, t: T) {\n        unsafe {\n            let n = Node::new(Some(t));\n            let prev = self.head.swap(n, Ordering::AcqRel);\n            (*prev).next.store(n, Ordering::Release);\n        }\n    }\n\n    /// Pops some data from this queue.\n    ///\n    /// Note that the current implementation means that this function cannot\n    /// return `Option<T>`. It is possible for this queue to be in an\n    /// inconsistent state where many pushes have succeeded and completely\n    /// finished, but pops cannot return `Some(t)`. This inconsistent state\n    /// happens when a pusher is preempted at an inopportune moment.\n    ///\n    /// This inconsistent state means that this queue does indeed have data, but\n    /// it does not currently have access to it at this time.\n    ///\n    /// This function is unsafe because only one thread can call it at a time.\n    pub(super) unsafe fn pop(&self) -> PopResult<T> {\n        unsafe {\n            let tail = *self.tail.get();\n            let next = (*tail).next.load(Ordering::Acquire);\n\n            if !next.is_null() {\n                *self.tail.get() = next;\n                assert!((*tail).value.is_none());\n                assert!((*next).value.is_some());\n                let ret = (*next).value.take().unwrap();\n                drop(Box::from_raw(tail));\n                return Data(ret);\n            }\n\n            if self.head.load(Ordering::Acquire) == tail {\n                Empty\n            } else {\n                Inconsistent\n            }\n        }\n    }\n\n    /// Pop an element similarly to `pop` function, but spin-wait on inconsistent\n    /// queue state instead of returning `Inconsistent`.\n    ///\n    /// This function is unsafe because only one thread can call it at a time.\n    pub(super) unsafe fn pop_spin(&self) -> Option<T> {\n        loop {\n            match unsafe { self.pop() } {\n                Empty => return None,\n                Data(t) => return Some(t),\n                // Inconsistent means that there will be a message to pop\n                // in a short time. This branch can only be reached if\n                // values are being produced from another thread, so there\n                // are a few ways that we can deal with this:\n                //\n                // 1) Spin\n                // 2) thread::yield_now()\n                // 3) task::current().unwrap() & return Pending\n                //\n                // For now, thread::yield_now() is used, but it would\n                // probably be better to spin a few times then yield.\n                Inconsistent => {\n                    thread::yield_now();\n                }\n            }\n        }\n    }\n}\n\nimpl<T> Drop for Queue<T> {\n    fn drop(&mut self) {\n        unsafe {\n            let mut cur = *self.tail.get();\n            while !cur.is_null() {\n                let next = (*cur).next.load(Ordering::Relaxed);\n                drop(Box::from_raw(cur));\n                cur = next;\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "futures-core@0.3.34",
      "sourcePath": "README.md",
      "sha256": "e8258273fed6f1796485777655118f2369fd3f000191e9d8cdbd10bf052946a9",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# futures-core\n\nThe core traits and types in for the `futures` library.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfutures-core = \"0.3\"\n```\n\nThe current `futures-core` requires Rust 1.36 or later.\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "futures-executor@0.3.34",
      "sourcePath": "README.md",
      "sha256": "c245377709f81e8d92d5e162c3b28131294c0c0452bd69bee8df68777d23b2ac",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# futures-executor\n\nExecutors for asynchronous tasks based on the futures-rs library.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfutures-executor = \"0.3\"\n```\n\nThe current `futures-executor` requires Rust 1.71 or later.\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "futures-io@0.3.34",
      "sourcePath": "README.md",
      "sha256": "575430be5c47352d85f36b44dcc2c2851a6a19e2384593415c4af22c6654cee7",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# futures-io\n\nThe `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and `AsyncBufRead` traits for the futures-rs library.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfutures-io = \"0.3\"\n```\n\nThe current `futures-io` requires Rust 1.36 or later.\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "futures-sink@0.3.34",
      "sourcePath": "README.md",
      "sha256": "a509e1ce84f285190130def6d2b9e3861988f9be725f7697f09fba347601d86f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# futures-sink\n\nThe asynchronous `Sink` trait for the futures-rs library.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfutures-sink = \"0.3\"\n```\n\nThe current `futures-sink` requires Rust 1.36 or later.\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "futures-task@0.3.34",
      "sourcePath": "README.md",
      "sha256": "7a458e69ff008c35cffbbbcd2a14ad3ba7ad75201ce74df2d8f8d0fdcf6c4a89",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# futures-task\n\nTools for working with tasks.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfutures-task = \"0.3\"\n```\n\nThe current `futures-task` requires Rust 1.71 or later.\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "futures-util@0.3.34",
      "sourcePath": "README.md",
      "sha256": "00510d047b36feb45db9034bf5f07a049a99b51d6b8c40d028cb35977baeb723",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# futures-util\n\nCommon utilities and extension traits for the futures-rs library.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfutures-util = \"0.3\"\n```\n\nThe current `futures-util` requires Rust 1.71 or later.\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "is_terminal_polyfill@1.70.2",
      "sourcePath": "README.md",
      "sha256": "edcbd294340511763ef2f1d7b96434e822afa48fcb6dd712aaf9498afe06ea3f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# is_terminal_polyfill\n\n> Polyfill for `is_terminal` stdlib feature for use with older MSRVs\n\n[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation]\n![License](https://img.shields.io/crates/l/is_terminal_polyfill.svg)\n[![Crates Status](https://img.shields.io/crates/v/is_terminal_polyfill.svg)][Crates.io]\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual licensed as above, without any additional terms or\nconditions.\n\n[Crates.io]: https://crates.io/crates/is_terminal_polyfill\n[Documentation]: https://docs.rs/is_terminal_polyfill\n"
    },
    {
      "package": "itoa@1.0.18",
      "sourcePath": "README.md",
      "sha256": "1305bd79675db0194915d9bc91bd0b3cf9487bc1126e05bf46b48ab43edce44b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "itoa\n====\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/itoa-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/itoa)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/itoa.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/itoa)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-itoa-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/itoa)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/itoa/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/itoa/actions?query=branch%3Amaster)\n\nThis crate provides a fast conversion of integer primitives to decimal strings.\nThe implementation comes straight from [libcore] but avoids the performance\npenalty of going through [`core::fmt::Formatter`].\n\nSee also [`zmij`] for printing floating point primitives.\n\n[libcore]: https://github.com/rust-lang/rust/blob/1.92.0/library/core/src/fmt/num.rs#L190-L253\n[`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html\n[`zmij`]: https://github.com/dtolnay/zmij\n\n```toml\n[dependencies]\nitoa = \"1.0\"\n```\n\n<br>\n\n## Example\n\n```rust\nfn main() {\n    let mut buffer = itoa::Buffer::new();\n    let printed = buffer.format(128u64);\n    assert_eq!(printed, \"128\");\n}\n```\n\n<br>\n\n## Performance\n\nThe [itoa-benchmark] compares this library and other Rust integer formatting\nimplementations across a range of integer sizes. The vertical axis in this chart\nshows nanoseconds taken by a single execution of\n`itoa::Buffer::new().format(value)` so a lower result indicates a faster\nlibrary.\n\n[itoa-benchmark]: https://github.com/dtolnay/itoa-benchmark\n\n![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/itoa-benchmark.png)\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "benches/cubic_arclen.rs",
      "sha256": "edb2707abacaf15261cfa6b546c2e35c57b805b2d9ff96b464cceff98ca40e05",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Benchmarks of cubic arclength approaches.\r\n\r\n#![cfg(nightly)]\r\n#![feature(test)]\r\nextern crate test;\r\nuse test::Bencher;\r\n\r\nuse kurbo::{CubicBez, ParamCurveArclen};\r\n\r\n#[bench]\r\nfn bench_cubic_arclen_1e_4(b: &mut Bencher) {\r\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\r\n    b.iter(|| test::black_box(c).arclen(1e-4))\r\n}\r\n\r\n#[bench]\r\nfn bench_cubic_arclen_1e_5(b: &mut Bencher) {\r\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\r\n    b.iter(|| test::black_box(c).arclen(1e-5))\r\n}\r\n\r\n#[bench]\r\nfn bench_cubic_arclen_1e_6(b: &mut Bencher) {\r\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\r\n    b.iter(|| test::black_box(c).arclen(1e-6))\r\n}\r\n\r\n#[bench]\r\nfn bench_cubic_arclen_degenerate(b: &mut Bencher) {\r\n    let c = CubicBez::new((0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0));\r\n    b.iter(|| test::black_box(c).arclen(1e-6))\r\n}\r\n\r\n#[bench]\r\nfn bench_cubic_arclen_1e_7(b: &mut Bencher) {\r\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\r\n    b.iter(|| test::black_box(c).arclen(1e-7))\r\n}\r\n\r\n#[bench]\r\nfn bench_cubic_arclen_1e_8(b: &mut Bencher) {\r\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\r\n    b.iter(|| test::black_box(c).arclen(1e-8))\r\n}\r\n\r\n#[bench]\r\nfn bench_cubic_arclen_1e_9(b: &mut Bencher) {\r\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\r\n    b.iter(|| test::black_box(c).arclen(1e-9))\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "benches/quad_arclen.rs",
      "sha256": "17be81efcdf2beb5d117de12babc046f25cf89ca835def28c240e79f4f008aaf",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Benchmarks of quadratic arclength approaches.\r\n\r\n// TODO: organize so there's less cut'n'paste from arclen_accuracy example.\r\n\r\n#![cfg(nightly)]\r\n#![feature(test)]\r\nextern crate test;\r\nuse test::Bencher;\r\n\r\nuse kurbo::{ParamCurve, ParamCurveArclen, ParamCurveDeriv, QuadBez};\r\n\r\n// Based on http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/\r\nfn quad_arclen_analytical(q: QuadBez) -> f64 {\r\n    let d2 = q.p0.to_vec2() - 2.0 * q.p1.to_vec2() + q.p2.to_vec2();\r\n    let a = d2.hypot2();\r\n    let d1 = q.p1 - q.p0;\r\n    let b = 2.0 * d2.dot(d1);\r\n    let c = d1.hypot2();\r\n\r\n    let sabc = (a + b + c).sqrt();\r\n    let a2 = a.powf(-0.5);\r\n    let a32 = a2.powi(3);\r\n    let c2 = 2.0 * c.sqrt();\r\n    let ba = b * a2;\r\n\r\n    sabc + 0.25\r\n        * (a2 * a2 * b * (2.0 * sabc - c2)\r\n            + a32 * (4.0 * c * a - b * b) * (((2.0 * a + b) * a2 + 2.0 * sabc) / (ba + c2)).ln())\r\n}\r\n\r\n/// Calculate arclength using Gauss-Legendre quadrature using formula from Behdad\r\n/// in https://github.com/Pomax/BezierInfo-2/issues/77\r\nfn gauss_arclen_3(q: QuadBez) -> f64 {\r\n    let v0 = (-0.492943519233745 * q.p0.to_vec2()\r\n        + 0.430331482911935 * q.p1.to_vec2()\r\n        + 0.0626120363218102 * q.p2.to_vec2())\r\n    .hypot();\r\n    let v1 = ((q.p2 - q.p0) * 0.4444444444444444).hypot();\r\n    let v2 = (-0.0626120363218102 * q.p0.to_vec2() - 0.430331482911935 * q.p1.to_vec2()\r\n        + 0.492943519233745 * q.p2.to_vec2())\r\n    .hypot();\r\n    v0 + v1 + v2\r\n}\r\n\r\nfn awesome_quad_arclen3(q: QuadBez, accuracy: f64, depth: usize) -> f64 {\r\n    let pm = q.p0.midpoint(q.p2);\r\n    let d1 = q.p1 - pm;\r\n    let d = q.p2 - q.p0;\r\n    let dhypot2 = d.hypot2();\r\n    let x = 2.0 * d.dot(d1) / dhypot2;\r\n    let y = 2.0 * d.cross(d1) / dhypot2;\r\n    let lc = (q.p2 - q.p0).hypot();\r\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\r\n    let est_err = 0.06 * (lp - lc) * (x * x + y * y).powf(2.0);\r\n    if est_err < accuracy || depth == 16 {\r\n        gauss_arclen_3(q)\r\n    } else {\r\n        let (q0, q1) = q.subdivide();\r\n        awesome_quad_arclen3(q0, accuracy * 0.5, depth + 1)\r\n            + awesome_quad_arclen3(q1, accuracy * 0.5, depth + 1)\r\n    }\r\n}\r\n\r\n/// Another implementation, using weights from\r\n/// https://pomax.github.io/bezierinfo/legendre-gauss.html\r\nfn gauss_arclen_n(q: QuadBez, coeffs: &[(f64, f64)]) -> f64 {\r\n    let d = q.deriv();\r\n    coeffs\r\n        .iter()\r\n        .map(|(wi, xi)| wi * d.eval(0.5 * (xi + 1.0)).to_vec2().hypot())\r\n        .sum::<f64>()\r\n        * 0.5\r\n}\r\n\r\nfn gauss_arclen_7(q: QuadBez) -> f64 {\r\n    gauss_arclen_n(\r\n        q,\r\n        &[\r\n            (0.4179591836734694, 0.0000000000000000),\r\n            (0.3818300505051189, 0.4058451513773972),\r\n            (0.3818300505051189, -0.4058451513773972),\r\n            (0.2797053914892766, -0.7415311855993945),\r\n            (0.2797053914892766, 0.7415311855993945),\r\n            (0.1294849661688697, -0.9491079123427585),\r\n            (0.1294849661688697, 0.9491079123427585),\r\n        ],\r\n    )\r\n}\r\n\r\nfn gauss_arclen_24(q: QuadBez) -> f64 {\r\n    gauss_arclen_n(\r\n        q,\r\n        &[\r\n            (0.1279381953467522, -0.0640568928626056),\r\n            (0.1279381953467522, 0.0640568928626056),\r\n            (0.1258374563468283, -0.1911188674736163),\r\n            (0.1258374563468283, 0.1911188674736163),\r\n            (0.1216704729278034, -0.3150426796961634),\r\n            (0.1216704729278034, 0.3150426796961634),\r\n            (0.1155056680537256, -0.4337935076260451),\r\n            (0.1155056680537256, 0.4337935076260451),\r\n            (0.1074442701159656, -0.5454214713888396),\r\n            (0.1074442701159656, 0.5454214713888396),\r\n            (0.0976186521041139, -0.6480936519369755),\r\n            (0.0976186521041139, 0.6480936519369755),\r\n            (0.0861901615319533, -0.7401241915785544),\r\n            (0.0861901615319533, 0.7401241915785544),\r\n            (0.0733464814110803, -0.8200019859739029),\r\n            (0.0733464814110803, 0.8200019859739029),\r\n            (0.0592985849154368, -0.8864155270044011),\r\n            (0.0592985849154368, 0.8864155270044011),\r\n            (0.0442774388174198, -0.9382745520027328),\r\n            (0.0442774388174198, 0.9382745520027328),\r\n            (0.0285313886289337, -0.9747285559713095),\r\n            (0.0285313886289337, 0.9747285559713095),\r\n            (0.0123412297999872, -0.9951872199970213),\r\n            (0.0123412297999872, 0.9951872199970213),\r\n        ],\r\n    )\r\n}\r\n\r\nfn awesome_quad_arclen7(q: QuadBez, accuracy: f64, depth: usize) -> f64 {\r\n    let pm = q.p0.midpoint(q.p2);\r\n    let d1 = q.p1 - pm;\r\n    let d = q.p2 - q.p0;\r\n    let dhypot2 = d.hypot2();\r\n    let x = 2.0 * d.dot(d1) / dhypot2;\r\n    let y = 2.0 * d.cross(d1) / dhypot2;\r\n    let lc = dhypot2.sqrt();\r\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\r\n    let est_err = 2.5e-2 * (lp - lc) * (x * x + y * y).powf(8.0).tanh();\r\n    if est_err < accuracy || depth == 16 {\r\n        gauss_arclen_7(q)\r\n    } else {\r\n        let (q0, q1) = q.subdivide();\r\n        awesome_quad_arclen7(q0, accuracy * 0.5, depth + 1)\r\n            + awesome_quad_arclen7(q1, accuracy * 0.5, depth + 1)\r\n    }\r\n}\r\n\r\n#[bench]\r\nfn bench_quad_arclen_analytical(b: &mut Bencher) {\r\n    // Analytical solution is not sensitive to exact shape.\r\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\r\n    b.iter(|| quad_arclen_analytical(test::black_box(q)))\r\n}\r\n\r\nconst ACCURACY: f64 = 1e-6;\r\n\r\n#[bench]\r\nfn bench_quad_arclen(b: &mut Bencher) {\r\n    // This is a pretty easy case.\r\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\r\n    b.iter(|| (test::black_box(q).arclen(ACCURACY)))\r\n}\r\n\r\n#[bench]\r\nfn bench_quad_arclen_gauss3(b: &mut Bencher) {\r\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\r\n    b.iter(|| awesome_quad_arclen3(test::black_box(q), ACCURACY, 0))\r\n}\r\n\r\n#[bench]\r\nfn bench_quad_arclen_gauss7(b: &mut Bencher) {\r\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\r\n    b.iter(|| awesome_quad_arclen7(test::black_box(q), ACCURACY, 0))\r\n}\r\n\r\n#[bench]\r\nfn bench_quad_arclen_gauss3_one(b: &mut Bencher) {\r\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\r\n    b.iter(|| gauss_arclen_3(test::black_box(q)))\r\n}\r\n\r\n#[bench]\r\nfn bench_quad_arclen_gauss7_one(b: &mut Bencher) {\r\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\r\n    b.iter(|| gauss_arclen_7(test::black_box(q)))\r\n}\r\n\r\n#[bench]\r\nfn bench_quad_arclen_gauss24_one(b: &mut Bencher) {\r\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\r\n    b.iter(|| gauss_arclen_24(test::black_box(q)))\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "benches/quartic.rs",
      "sha256": "d660a15c24cb93fe2761d9faf138a8b37ef4e0de9415d95682b1df900078da1c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Benchmarks of the quartic equation solver.\r\n\r\n#![cfg(nightly)]\r\n#![feature(test)]\r\nextern crate test;\r\nuse kurbo::common::solve_quartic;\r\nuse test::Bencher;\r\n\r\n#[bench]\r\nfn bench_quartic(bb: &mut Bencher) {\r\n    let (x1, x2, x3, x4) = (1.0, 2.0, 3.0, 4.0);\r\n    let a = -(x1 + x2 + x3 + x4);\r\n    let b = x1 * (x2 + x3) + x2 * (x3 + x4) + x4 * (x1 + x3);\r\n    let c = -x1 * x2 * (x3 + x4) - x3 * x4 * (x1 + x2);\r\n    let d = x1 * x2 * x3 * x4;\r\n\r\n    bb.iter(|| {\r\n        solve_quartic(\r\n            test::black_box(d),\r\n            test::black_box(c),\r\n            test::black_box(b),\r\n            test::black_box(a),\r\n            1.0,\r\n        )\r\n    })\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "benches/rect_expand.rs",
      "sha256": "deb2fa69284b7895722bf4001bef7603e4ebdb5f6cbb76b8c8e1cd205673b5fd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n#![cfg(nightly)]\r\n#![feature(test)]\r\nextern crate test;\r\nuse test::Bencher;\r\n\r\nuse kurbo::Rect;\r\n\r\n// In positive space\r\nstatic RECT_POS: Rect = Rect::new(3.3, 3.6, 5.6, 4.1);\r\n// In both positive and negative space\r\nstatic RECT_PAN: Rect = Rect::new(-3.3, -3.6, 5.6, 4.1);\r\n// In negative space\r\nstatic RECT_NEG: Rect = Rect::new(-5.6, -4.1, -3.3, -3.6);\r\n// In positive space reverse\r\nstatic RECT_POR: Rect = Rect::new(5.6, 4.1, 3.3, 3.6);\r\n// In both positive and negative space reverse\r\nstatic RECT_PNR: Rect = Rect::new(5.6, 4.1, -3.3, -3.6);\r\n// In negative space reverse\r\nstatic RECT_NER: Rect = Rect::new(-3.3, -3.6, -5.6, -4.1);\r\n// In positive space mixed\r\nstatic RECT_POM: Rect = Rect::new(3.3, 4.1, 5.6, 3.6);\r\n// In both positive and negative space mixed\r\nstatic RECT_PNM: Rect = Rect::new(-3.3, 4.1, 5.6, -3.6);\r\n// In negative space mixed\r\nstatic RECT_NEM: Rect = Rect::new(-5.6, -3.6, -3.3, -4.1);\r\n\r\n#[inline]\r\nfn expand(rects: &[Rect; 9]) {\r\n    test::black_box(rects[0].expand());\r\n    test::black_box(rects[1].expand());\r\n    test::black_box(rects[2].expand());\r\n\r\n    test::black_box(rects[3].expand());\r\n    test::black_box(rects[4].expand());\r\n    test::black_box(rects[5].expand());\r\n\r\n    test::black_box(rects[6].expand());\r\n    test::black_box(rects[7].expand());\r\n    test::black_box(rects[8].expand());\r\n}\r\n\r\n#[bench]\r\nfn bench_expand(b: &mut Bencher) {\r\n    // Creating the array here to prevent the compiler from optimizing all of it to NOP.\r\n    let rects: [Rect; 9] = [\r\n        RECT_POS, RECT_PAN, RECT_NEG, RECT_POR, RECT_PNR, RECT_NER, RECT_POM, RECT_PNM, RECT_NEM,\r\n    ];\r\n    b.iter(|| expand(&rects));\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "examples/arclen_accuracy.rs",
      "sha256": "2e7bd497685563b67363e53fe788391f4b48b40edd067951c0447a5ded76daf7",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A test program to plot the error of arclength approximation.\r\n\r\n// Lots of stuff is commented out or was just something to try.\r\n#![allow(unused)]\r\n#![allow(clippy::unreadable_literal)]\r\n#![allow(clippy::many_single_char_names)]\r\n\r\n// TODO: make more functionality accessible from command line rather than uncommenting.\r\n\r\nuse std::env;\r\nuse std::time::{Duration, Instant};\r\n\r\nuse kurbo::{ParamCurve, ParamCurveArclen, ParamCurveDeriv, QuadBez};\r\n\r\nuse kurbo::common::{GAUSS_LEGENDRE_COEFFS_24, GAUSS_LEGENDRE_COEFFS_5, GAUSS_LEGENDRE_COEFFS_7};\r\n\r\n/// Calculate arclength using Gauss-Legendre quadrature using formula from Behdad\r\n/// in https://github.com/Pomax/BezierInfo-2/issues/77\r\nfn gauss_arclen_3(q: QuadBez) -> f64 {\r\n    let v0 = (-0.492943519233745 * q.p0.to_vec2()\r\n        + 0.430331482911935 * q.p1.to_vec2()\r\n        + 0.0626120363218102 * q.p2.to_vec2())\r\n    .hypot();\r\n    let v1 = ((q.p2 - q.p0) * 0.4444444444444444).hypot();\r\n    let v2 = (-0.0626120363218102 * q.p0.to_vec2() - 0.430331482911935 * q.p1.to_vec2()\r\n        + 0.492943519233745 * q.p2.to_vec2())\r\n    .hypot();\r\n    v0 + v1 + v2\r\n}\r\n\r\nfn awesome_quad_arclen(q: QuadBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\r\n    let pm = q.p0.midpoint(q.p2);\r\n    let d1 = q.p1 - pm;\r\n    let d = q.p2 - q.p0;\r\n    let dhypot2 = d.hypot2();\r\n    let x = 2.0 * d.dot(d1) / dhypot2;\r\n    let y = 2.0 * d.cross(d1) / dhypot2;\r\n    let lc = (q.p2 - q.p0).hypot();\r\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\r\n    let est_err = 0.06 * (lp - lc) * (x * x + y * y).powf(2.0);\r\n    if est_err < accuracy || depth == 16 {\r\n        *count += 1;\r\n        gauss_arclen_3(q)\r\n    } else {\r\n        let (q0, q1) = q.subdivide();\r\n        awesome_quad_arclen(q0, accuracy * 0.5, depth + 1, count)\r\n            + awesome_quad_arclen(q1, accuracy * 0.5, depth + 1, count)\r\n    }\r\n}\r\n\r\nconst MAX_DEPTH: usize = 16;\r\nfn gravesen_rec(q: &QuadBez, l0: f64, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\r\n    let (q0, q1) = q.subdivide();\r\n    let l0_q0 = calc_l0(q0);\r\n    let l0_q1 = calc_l0(q1);\r\n    let l1 = l0_q0 + l0_q1;\r\n    let error = (l0 - l1) * (1.0 / 15.0);\r\n    if error.abs() < accuracy || depth == MAX_DEPTH {\r\n        *count += 1;\r\n        l1 - error\r\n    } else {\r\n        gravesen_rec(&q0, l0_q0, accuracy * 0.5, depth + 1, count)\r\n            + gravesen_rec(&q1, l0_q1, accuracy * 0.5, depth + 1, count)\r\n    }\r\n}\r\n\r\nfn gauss_arclen_5(q: QuadBez) -> f64 {\r\n    q.gauss_arclen(GAUSS_LEGENDRE_COEFFS_5)\r\n}\r\n\r\nfn gauss_arclen_7(q: QuadBez) -> f64 {\r\n    q.gauss_arclen(GAUSS_LEGENDRE_COEFFS_7)\r\n}\r\n\r\nfn gauss_arclen_24(q: QuadBez) -> f64 {\r\n    q.gauss_arclen(GAUSS_LEGENDRE_COEFFS_24)\r\n}\r\n\r\nfn awesome_quad_arclen7(q: QuadBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\r\n    let pm = q.p0.midpoint(q.p2);\r\n    let d1 = q.p1 - pm;\r\n    let d = q.p2 - q.p0;\r\n    let dhypot2 = d.hypot2();\r\n    let x = 2.0 * d.dot(d1) / dhypot2;\r\n    let y = 2.0 * d.cross(d1) / dhypot2;\r\n    let lc = (q.p2 - q.p0).hypot();\r\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\r\n    let est_err = 2.5e-2 * (lp - lc) * (x * x + y * y).powf(8.0).tanh();\r\n    // Increase depth, so we can be an accurate baseline for comparison.\r\n    if est_err < accuracy || depth == 22 {\r\n        *count += 1;\r\n        gauss_arclen_7(q)\r\n    } else {\r\n        let (q0, q1) = q.subdivide();\r\n        awesome_quad_arclen7(q0, accuracy * 0.5, depth + 1, count)\r\n            + awesome_quad_arclen7(q1, accuracy * 0.5, depth + 1, count)\r\n    }\r\n}\r\n\r\nfn awesome_quad_arclen24(q: QuadBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\r\n    let pm = q.p0.midpoint(q.p2);\r\n    let d1 = q.p1 - pm;\r\n    let d = q.p2 - q.p0;\r\n    let dhypot2 = d.hypot2();\r\n    let x = 2.0 * d.dot(d1) / dhypot2;\r\n    let y = 2.0 * d.cross(d1) / dhypot2;\r\n    let lc = (q.p2 - q.p0).hypot();\r\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\r\n    // This isn't quite right near (1.1, 0)\r\n    let est_err = 1.0 * (lp - lc) * (0.5 * x * x + 0.1 * y * y).powf(16.0).tanh();\r\n    if est_err < accuracy || depth == 16 {\r\n        *count += 1;\r\n        gauss_arclen_24(q)\r\n    } else {\r\n        let (q0, q1) = q.subdivide();\r\n        awesome_quad_arclen24(q0, accuracy * 0.5, depth + 1, count)\r\n            + awesome_quad_arclen24(q1, accuracy * 0.5, depth + 1, count)\r\n    }\r\n}\r\n\r\n// Based on http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/\r\nfn quad_arclen_analytical(q: QuadBez) -> f64 {\r\n    let d2 = q.p0.to_vec2() - 2.0 * q.p1.to_vec2() + q.p2.to_vec2();\r\n    let a = d2.hypot2();\r\n    let d1 = q.p1 - q.p0;\r\n    let c = d1.hypot2();\r\n    if a < 5e-4 * c {\r\n        return gauss_arclen_3(q);\r\n    }\r\n    let b = 2.0 * d2.dot(d1);\r\n\r\n    let sabc = (a + b + c).sqrt();\r\n    let a2 = a.powf(-0.5);\r\n    let a32 = a2.powi(3);\r\n    let c2 = 2.0 * c.sqrt();\r\n    let ba_c2 = b * a2 + c2;\r\n\r\n    let v0 = 0.25 * a2 * a2 * b * (2.0 * sabc - c2) + sabc;\r\n    // TODO: justify and fine-tune this exact constant.\r\n    if ba_c2 < 1e-13 {\r\n        // This case happens for Béziers with a sharp kink.\r\n        v0\r\n    } else {\r\n        v0 + 0.25 * a32 * (4.0 * c * a - b * b) * (((2.0 * a + b) * a2 + 2.0 * sabc) / ba_c2).ln()\r\n    }\r\n}\r\n\r\n/// Calculate the L0 metric from \"Adaptive subdivision and the length and\r\n/// energy of Bézier curves\" by Jens Gravesen.\r\nfn calc_l0(q: QuadBez) -> f64 {\r\n    let lc = (q.p2 - q.p0).hypot();\r\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\r\n    (2.0 / 3.0) * lc + (1.0 / 3.0) * lp\r\n}\r\n\r\nfn with_subdiv(q: QuadBez, f: &dyn Fn(QuadBez) -> f64, depth: usize) -> f64 {\r\n    if depth == 0 {\r\n        f(q)\r\n    } else {\r\n        let (q0, q1) = q.subdivide();\r\n        with_subdiv(q0, f, depth - 1) + with_subdiv(q1, f, depth - 1)\r\n    }\r\n}\r\n\r\nfn duration_to_time(d: Duration) -> f64 {\r\n    1e-9 * (d.subsec_nanos() as f64) + (d.as_secs() as f64)\r\n}\r\n\r\nfn run_simple() {\r\n    let q = QuadBez::new((0.0, 0.0), (0.0, 0.5), (1.0, 1.0));\r\n    let true_len = q.arclen(1e-13);\r\n    for i in 0..20 {\r\n        let n = 1 << i;\r\n        let start_time = Instant::now();\r\n        let mut est = 0.0;\r\n        let mut last = q.start();\r\n        let dt = (n as f64).recip();\r\n        for j in 0..n {\r\n            let t = ((j + 1) as f64) * dt;\r\n            let p = q.eval(t);\r\n            est += (p - last).hypot();\r\n            last = p;\r\n        }\r\n        let elapsed = duration_to_time(start_time.elapsed());\r\n        let err = true_len - est;\r\n        if i > 0 {\r\n            println!(\"{elapsed} {err}\");\r\n        }\r\n    }\r\n}\r\n\r\n/// Generate map data suitable for plotting in Gnuplot.\r\nfn main() {\r\n    let mut n_subdiv = 0;\r\n    let mut func: &dyn Fn(QuadBez) -> f64 = &gauss_arclen_3;\r\n    for arg in env::args().skip(1) {\r\n        if arg == \"gauss3\" {\r\n            func = &gauss_arclen_3;\r\n        } else if arg == \"gauss5\" {\r\n            func = &gauss_arclen_5;\r\n        } else if arg == \"gauss7\" {\r\n            func = &gauss_arclen_7;\r\n        } else if arg == \"gauss24\" {\r\n            func = &gauss_arclen_24;\r\n        } else if arg == \"l0\" {\r\n            func = &calc_l0;\r\n        } else if arg == \"simple\" {\r\n            run_simple();\r\n            return;\r\n        } else if let Ok(n) = arg.parse() {\r\n            n_subdiv = n;\r\n        } else {\r\n            println!(\"usage: arclen_accuracy [func] n_subdiv\");\r\n            std::process::exit(1);\r\n        }\r\n    }\r\n    let n = 400;\r\n    let accuracy = 1e-6;\r\n    for i in 0..=n {\r\n        let x = 2.0 * (i as f64) * (n as f64).recip();\r\n        for j in 0..=n {\r\n            let y = 2.0 * (j as f64) * (n as f64).recip();\r\n            let q = QuadBez::new((-1.0, 0.0), (x, y), (1.0, 0.0));\r\n            let mut count = 0;\r\n            let accurate_arclen = awesome_quad_arclen7(q, 1e-15, 0, &mut count);\r\n            //count = 0;\r\n            let start_time = Instant::now();\r\n            //let est = awesome_quad_arclen7(q, accuracy, 0, &mut count);\r\n            let est = quad_arclen_analytical(q);\r\n            let elapsed = start_time.elapsed();\r\n            //let est = gravesen_rec(&q, calc_l0(q), accuracy, 0, &mut count);\r\n            //let est = with_subdiv(q, func, n_subdiv);\r\n            let error = est - accurate_arclen;\r\n            println!(\"{} {} {}\", x, y, (error.abs() + 1e-18).log10());\r\n            //println!(\"{} {} {}\", x, y, count);\r\n            //println!(\"{} {} {}\", x, y, elapsed.subsec_nanos());\r\n            //let accurate_arclen = with_subdiv(q, &gauss_arclen_5, 8);\r\n            //let error = est - accurate_arclen;\r\n            /*\r\n            let lc = (q.p2 - q.p0).hypot();\r\n            let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\r\n            let est_err = 1.0 * (lp - lc) * (0.5 * x * x + 0.1 * y * y).powf(16.0).tanh();\r\n            println!(\"{} {} {}\", x, y, (est_err/error.abs() + 1e-15).log10());\r\n            */\r\n        }\r\n        println!();\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "examples/circle.rs",
      "sha256": "509aeddeeb953066afe1219f683b9efe72d94109b3a29739e6b00b9ccc6c012a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Example of circle\r\n\r\n#[cfg(feature = \"std\")]\r\nfn main() {\r\n    use kurbo::{Circle, Shape};\r\n\r\n    let circle = Circle::new((400.0, 400.0), 380.0);\r\n    println!(\"<!DOCTYPE html>\");\r\n    println!(\"<html>\");\r\n    println!(\"<body>\");\r\n    println!(\"<svg height=\\\"800\\\" width=\\\"800\\\">\");\r\n    let path = circle.to_path(1e-3).to_svg();\r\n    println!(\"  <path d=\\\"{}\\\" stroke=\\\"black\\\" fill=\\\"none\\\" />\", path);\r\n    let path = circle.to_path(1.0).to_svg();\r\n    println!(\"  <path d=\\\"{}\\\" stroke=\\\"red\\\" fill=\\\"none\\\" />\", path);\r\n    println!(\"</svg>\");\r\n    println!(\"</body>\");\r\n    println!(\"</html>\");\r\n}\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nfn main() {\r\n    println!(\"This example requires the standard library\");\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "examples/cubic_arclen.rs",
      "sha256": "c25b3359ecebe925c10817c7a3a2d059e35f7ccb6b5ddf8fb12660a6b6e2f4d1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Research testbed for arclengths of cubic Bézier segments.\r\n\r\n// Lots of stuff is commented out or was just something to try.\r\n#![allow(unused)]\r\n#![allow(clippy::unreadable_literal)]\r\n#![allow(clippy::many_single_char_names)]\r\n\r\nuse kurbo::common::*;\r\nuse kurbo::{\r\n    CubicBez, ParamCurve, ParamCurveArclen, ParamCurveCurvature, ParamCurveDeriv, Point, Vec2,\r\n};\r\n\r\n/// Calculate arclength using Gauss-Legendre quadrature using formula from Behdad\r\n/// in https://github.com/Pomax/BezierInfo-2/issues/77\r\nfn gauss_arclen_5(c: CubicBez) -> f64 {\r\n    let v0 = (c.p1 - c.p0).hypot() * 0.15;\r\n    let v1 = (-0.558983582205757 * c.p0.to_vec2()\r\n        + 0.325650248872424 * c.p1.to_vec2()\r\n        + 0.208983582205757 * c.p2.to_vec2()\r\n        + 0.024349751127576 * c.p3.to_vec2())\r\n    .hypot();\r\n    let v2 = (c.p3 - c.p0 + (c.p2 - c.p1)).hypot() * 0.26666666666666666;\r\n    let v3 = (-0.024349751127576 * c.p0.to_vec2()\r\n        - 0.208983582205757 * c.p1.to_vec2()\r\n        - 0.325650248872424 * c.p2.to_vec2()\r\n        + 0.558983582205757 * c.p3.to_vec2())\r\n    .hypot();\r\n    let v4 = (c.p3 - c.p2).hypot() * 0.15;\r\n\r\n    v0 + v1 + v2 + v3 + v4\r\n}\r\n\r\nfn gauss_arclen_7<C: ParamCurveDeriv>(c: C) -> f64 {\r\n    c.gauss_arclen(GAUSS_LEGENDRE_COEFFS_7)\r\n}\r\n\r\nfn est_gauss5_error(c: CubicBez) -> f64 {\r\n    let lc = (c.p3 - c.p0).hypot();\r\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\r\n\r\n    let d2 = c.deriv().deriv();\r\n    let d3 = d2.deriv();\r\n    let lmi = 2.0 / (lp + lc);\r\n    7e-8 * (d3.eval(0.5).to_vec2().hypot() * lmi + 5.0 * d2.eval(0.5).to_vec2().hypot() * lmi)\r\n        .powi(5)\r\n        * lp\r\n}\r\n\r\nfn gauss_errnorm_n<C: ParamCurveDeriv>(c: C, coeffs: &[(f64, f64)]) -> f64\r\nwhere\r\n    C::DerivResult: ParamCurveDeriv,\r\n{\r\n    let d = c.deriv().deriv();\r\n    coeffs\r\n        .iter()\r\n        .map(|(wi, xi)| wi * d.eval(0.5 * (xi + 1.0)).to_vec2().hypot2())\r\n        .sum::<f64>()\r\n}\r\n\r\n// Squared L2 norm of the second derivative of the cubic.\r\nfn cubic_errnorm(c: CubicBez) -> f64 {\r\n    let d = c.deriv().deriv();\r\n    let dd = d.end() - d.start();\r\n    d.start().to_vec2().hypot2() + d.start().to_vec2().dot(dd) + dd.hypot2() * (1.0 / 3.0)\r\n}\r\n\r\nfn est_gauss7_error(c: CubicBez) -> f64 {\r\n    let lc = (c.p3 - c.p0).hypot();\r\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\r\n\r\n    8e-9 * (2.0 * cubic_errnorm(c) / lc.powi(2)).powi(6) * lp\r\n}\r\n\r\nfn gauss_arclen_9<C: ParamCurveDeriv>(c: C) -> f64 {\r\n    c.gauss_arclen(GAUSS_LEGENDRE_COEFFS_9)\r\n}\r\n\r\nfn gauss_arclen_11<C: ParamCurveDeriv>(c: C) -> f64 {\r\n    c.gauss_arclen(GAUSS_LEGENDRE_COEFFS_11)\r\n}\r\n\r\nfn est_gauss9_error(c: CubicBez) -> f64 {\r\n    let lc = (c.p3 - c.p0).hypot();\r\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\r\n\r\n    1e-10 * (2.0 * cubic_errnorm(c) / lc.powi(2)).powi(8) * lp\r\n}\r\n\r\nfn est_gauss11_error(c: CubicBez) -> f64 {\r\n    let lc = (c.p3 - c.p0).hypot();\r\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\r\n\r\n    1e-12 * (2.0 * cubic_errnorm(c) / lc.powi(2)).powi(11) * lp\r\n}\r\n\r\n// A new approach based on integrating local error.\r\nfn est_gauss11_error_2(c: CubicBez) -> f64 {\r\n    let d = c.deriv();\r\n    let d2 = d.deriv();\r\n    GAUSS_LEGENDRE_COEFFS_11\r\n        .iter()\r\n        .map(|(wi, xi)| {\r\n            wi * {\r\n                let t = 0.5 * (xi + 1.0);\r\n                let v = d.eval(t).to_vec2().hypot();\r\n                let a2 = d2.eval(t).to_vec2().hypot2();\r\n                a2.powi(3) / v.powi(5)\r\n            }\r\n        })\r\n        .sum::<f64>()\r\n}\r\n\r\n#[allow(clippy::neg_cmp_op_on_partial_ord)]\r\nfn est_max_curvature(c: CubicBez) -> f64 {\r\n    let n = 100;\r\n    let mut max = 0.0;\r\n    for i in 0..=n {\r\n        let t = (i as f64) * (n as f64).recip();\r\n        let k = c.curvature(t).abs();\r\n        if !(k < max) {\r\n            max = k;\r\n        }\r\n    }\r\n    max\r\n}\r\n\r\nfn est_min_deriv_norm2(c: CubicBez) -> f64 {\r\n    let d = c.deriv();\r\n    let n = 100;\r\n    let mut min = d.eval(1.0).to_vec2().hypot2();\r\n    for i in 0..n {\r\n        let t = (i as f64) * (n as f64).recip();\r\n        min = min.min(d.eval(t).to_vec2().hypot2())\r\n    }\r\n    min\r\n}\r\n\r\nfn est_gauss11_error_3(c: CubicBez) -> f64 {\r\n    let lc = (c.p3 - c.p0).hypot();\r\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\r\n    let pc_err = (lp - lc) * 0.02;\r\n    let ks = est_max_curvature(c) * lp;\r\n    let est = ks.powi(3) * lp * 8e-9;\r\n    if est < pc_err {\r\n        est\r\n    } else {\r\n        pc_err\r\n    }\r\n}\r\n\r\nfn est_gauss9_error_3(c: CubicBez) -> f64 {\r\n    let lc = (c.p3 - c.p0).hypot();\r\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\r\n    let pc_err = (lp - lc) * 0.02;\r\n    let ks = est_max_curvature(c) * lp;\r\n    let est = ks.powi(3) * lp * 5e-8;\r\n    if est < pc_err {\r\n        est\r\n    } else {\r\n        pc_err\r\n    }\r\n}\r\n\r\n// A new approach based on integrating local error; the cost of evaluating the\r\n// error metric is likely to dominate unless the accuracy buys a lot of subdivisions.\r\nfn est_gauss9_error_2(c: CubicBez) -> f64 {\r\n    let d = c.deriv();\r\n    let d2 = d.deriv();\r\n    let p = 10;\r\n    GAUSS_LEGENDRE_COEFFS_9\r\n        .iter()\r\n        .map(|(wi, xi)| {\r\n            wi * {\r\n                let t = 0.5 * (xi + 1.0);\r\n                let v = d.eval(t).to_vec2().hypot();\r\n                let a = d2.eval(t).to_vec2().hypot();\r\n                (1.0e-1 * a / v).tanh().powi(p) * v\r\n            }\r\n        })\r\n        .sum::<f64>()\r\n        * 3.0\r\n}\r\n\r\nfn my_arclen(c: CubicBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\r\n    if depth == 16 || est_gauss5_error(c) < accuracy {\r\n        *count += 1;\r\n        gauss_arclen_5(c)\r\n    } else {\r\n        let (c0, c1) = c.subdivide();\r\n        my_arclen(c0, accuracy * 0.5, depth + 1, count)\r\n            + my_arclen(c1, accuracy * 0.5, depth + 1, count)\r\n    }\r\n}\r\n\r\nfn my_arclen7(c: CubicBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\r\n    if depth == 16 || est_gauss7_error(c) < accuracy {\r\n        *count += 1;\r\n        gauss_arclen_7(c)\r\n    } else {\r\n        let (c0, c1) = c.subdivide();\r\n        my_arclen7(c0, accuracy * 0.5, depth + 1, count)\r\n            + my_arclen7(c1, accuracy * 0.5, depth + 1, count)\r\n    }\r\n}\r\n\r\n// Should make this generic instead of copy+paste, but we need only one when we're done.\r\nfn my_arclen9(c: CubicBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\r\n    if depth == 16 || est_gauss9_error(c) < accuracy {\r\n        *count += 1;\r\n        gauss_arclen_9(c)\r\n    } else {\r\n        let (c0, c1) = c.subdivide();\r\n        my_arclen9(c0, accuracy * 0.5, depth + 1, count)\r\n            + my_arclen9(c1, accuracy * 0.5, depth + 1, count)\r\n    }\r\n}\r\n\r\n// This doesn't help; we can't really get a more accurate error bound, so all this\r\n// does is overkill the accuracy.\r\nfn my_arclen11(c: CubicBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\r\n    if depth == 16 || est_gauss9_error(c) < accuracy {\r\n        *count += 1;\r\n        gauss_arclen_11(c)\r\n    } else {\r\n        let (c0, c1) = c.subdivide();\r\n        my_arclen11(c0, accuracy * 0.5, depth + 1, count)\r\n            + my_arclen11(c1, accuracy * 0.5, depth + 1, count)\r\n    }\r\n}\r\n\r\nfn randpt() -> Point {\r\n    Point::new(rand::random(), rand::random())\r\n}\r\n\r\nfn randbez() -> CubicBez {\r\n    CubicBez::new(randpt(), randpt(), randpt(), randpt())\r\n}\r\n\r\nfn main() {\r\n    let accuracy = 1e-4;\r\n    for _ in 0..10_000 {\r\n        let c = randbez();\r\n        let t: f64 = rand::random();\r\n        let c = c.subsegment(0.0..t);\r\n        //let accurate_arclen = c.arclen(1e-12);\r\n        let mut count = 0;\r\n        let accurate_arclen = my_arclen9(c, 1e-15, 0, &mut count);\r\n\r\n        let est = gauss_arclen_9(c);\r\n        let est_err = est_gauss9_error_3(c);\r\n        let err = (accurate_arclen - est).abs();\r\n        println!(\"{est_err} {err}\");\r\n\r\n        /*\r\n        let mut count = 0;\r\n        let est = my_arclen9(c, accuracy, 0, &mut count);\r\n        let err = (accurate_arclen - est).abs();\r\n        println!(\"{err} {count}\");\r\n        */\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "examples/ellipse.rs",
      "sha256": "be0cd0a6291a9600c98f25195597da74fa623a77f6c45433c9e68005835c3cc9",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Example of ellipse\r\n\r\n#[cfg(feature = \"std\")]\r\nfn main() {\r\n    use kurbo::{Ellipse, Shape};\r\n    use std::f64::consts::PI;\r\n\r\n    let ellipse = Ellipse::new((400.0, 400.0), (200.0, 100.0), 0.25 * PI);\r\n    println!(\"<!DOCTYPE html>\");\r\n    println!(\"<html>\");\r\n    println!(\"<body>\");\r\n    println!(\"<svg height=\\\"800\\\" width=\\\"800\\\" style=\\\"background-color: #999\\\">\");\r\n    let path = ellipse.to_path(1e-3).to_svg();\r\n    println!(\"  <path d=\\\"{}\\\" stroke=\\\"black\\\" fill=\\\"none\\\" />\", path);\r\n    let path = ellipse.to_path(1.0).to_svg();\r\n    println!(\"  <path d=\\\"{}\\\" stroke=\\\"red\\\" fill=\\\"none\\\" />\", path);\r\n    println!(\"</svg>\");\r\n    println!(\"</body>\");\r\n    println!(\"</html>\");\r\n}\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nfn main() {\r\n    println!(\"This example requires the standard library\");\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "examples/fit_poly.rs",
      "sha256": "19cf29a6a9720c0c88320ee0abd3fbf3e4d83834433b103b8b5833dd76589548",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A test case for the cubic Bézier path simplifier, generating a very\r\n//! efficient and accurate SVG file to plot a quartic polynomial. This\r\n//! file was used to generate the image for the Wikipedia article on\r\n//! quartic polynomials.\r\n\r\nuse std::{io::Write, ops::Range};\r\n\r\nuse kurbo::{BezPath, CurveFitSample, ParamCurveFit, PathEl, Point, Vec2};\r\n\r\nstruct MyPoly;\r\n\r\nfn eval_mypoly(x: f64) -> f64 {\r\n    (x + 4.) * (x + 1.) * (x - 1.) * (x - 3.) / 14. + 0.5\r\n}\r\n\r\nfn eval_mypoly_deriv(x: f64) -> f64 {\r\n    (((4. * x + 3.) * x - 26.) * x - 1.) / 14.\r\n}\r\n\r\nimpl ParamCurveFit for MyPoly {\r\n    fn sample_pt_deriv(&self, t: f64) -> (Point, Vec2) {\r\n        const S: f64 = 336.;\r\n        let x = 37. + t * S;\r\n        let math_x = (x - 220.) / 40.;\r\n        let y = -eval_mypoly(math_x) * 40. + 260.;\r\n        let dx = S;\r\n        let dy = -dx * eval_mypoly_deriv(math_x);\r\n        (Point::new(x, y), Vec2::new(dx, dy))\r\n    }\r\n\r\n    fn sample_pt_tangent(&self, t: f64, _: f64) -> CurveFitSample {\r\n        let (p, tangent) = self.sample_pt_deriv(t);\r\n        CurveFitSample { p, tangent }\r\n    }\r\n\r\n    fn break_cusp(&self, _: Range<f64>) -> Option<f64> {\r\n        None\r\n    }\r\n}\r\n\r\npub fn to_svg_economical(path: &BezPath) -> String {\r\n    let mut buffer = Vec::new();\r\n    write_to(path, &mut buffer).unwrap();\r\n    String::from_utf8(buffer).unwrap()\r\n}\r\n\r\n/// Write the SVG representation of this path to the provided buffer.\r\npub fn write_to<W: Write>(path: &BezPath, mut writer: W) -> std::io::Result<()> {\r\n    for el in path.elements() {\r\n        match *el {\r\n            PathEl::MoveTo(p) => write!(writer, \"M{:.2} {:.2}\", p.x, p.y)?,\r\n            PathEl::LineTo(p) => write!(writer, \"L{} {}\", p.x, p.y)?,\r\n            PathEl::QuadTo(p1, p2) => write!(writer, \"Q{} {} {} {}\", p1.x, p1.y, p2.x, p2.y)?,\r\n            PathEl::CurveTo(p1, p2, p3) => write!(\r\n                writer,\r\n                \"C{:.2} {:.2} {:.2} {:.2} {:.2} {:.2}\",\r\n                p1.x, p1.y, p2.x, p2.y, p3.x, p3.y\r\n            )?,\r\n            PathEl::ClosePath => write!(writer, \"Z\")?,\r\n        }\r\n    }\r\n    Ok(())\r\n}\r\n\r\nfn main() {\r\n    println!(\"<svg width='800' height='600' xmlns='http://www.w3.org/2000/svg'>\");\r\n    let path = kurbo::fit_to_bezpath_opt(&MyPoly, 0.1);\r\n    println!(\r\n        \"  <path d='{}' stroke='#008' fill='none' stroke-width='2.0'/>\",\r\n        to_svg_economical(&path)\r\n    );\r\n    println!(\"</svg>\");\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "examples/offset.rs",
      "sha256": "450e161a17ece9269a8a6828c7e986b5bfbce2487511491d0b9e4ca90e4c80d6",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A simple example to show an offset curve of a cubic Bézier segment.\r\n\r\nuse kurbo::{offset::CubicOffset, CubicBez, Shape};\r\n\r\nfn main() {\r\n    println!(\"<svg width='800' height='600' xmlns='http://www.w3.org/2000/svg'>\");\r\n    let c = CubicBez::new((100., 100.), (150., 75.), (300., 50.), (400., 200.));\r\n    println!(\r\n        \"  <path d='{}' stroke='#000' fill='none' />\",\r\n        c.to_path(1e-9).to_svg()\r\n    );\r\n    for i in 1..=80 {\r\n        let co = CubicOffset::new(c, i as f64 * 4.0);\r\n        let path = kurbo::fit_to_bezpath_opt(&co, 1e-3);\r\n        println!(\r\n            \"  <path d='{}' stroke='#008' fill='none' stroke-width='0.2'/>\",\r\n            path.to_svg()\r\n        );\r\n    }\r\n    println!(\"</svg>\");\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "examples/quad_intersect.rs",
      "sha256": "1232d45f11b3bcabe836670bee040e8aaf21ac376d64c2a330361d14f3119899",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Test case that demonstrates quadratic/quadratic intersection using\r\n//! new quartic solver.\r\n\r\nuse arrayvec::ArrayVec;\r\nuse kurbo::{common::solve_quartic, ParamCurve, Point, QuadBez, Shape};\r\nuse rand::{thread_rng, Rng};\r\n\r\nfn rand_point() -> Point {\r\n    let mut rng = thread_rng();\r\n    Point::new(rng.gen_range(0.0..500.0), rng.gen_range(0.0..500.0))\r\n}\r\n\r\nfn rand_quad() -> QuadBez {\r\n    QuadBez::new(rand_point(), rand_point(), rand_point())\r\n}\r\n\r\nstruct ImplicitQuad {\r\n    x2: f64,\r\n    xy: f64,\r\n    y2: f64,\r\n    x: f64,\r\n    y: f64,\r\n    c: f64,\r\n}\r\n\r\nimpl ImplicitQuad {\r\n    fn from_quad(q: QuadBez) -> Self {\r\n        let Point { x: ax, y: ay } = q.p0;\r\n        let Point { x: bx, y: by } = q.p1;\r\n        let Point { x: cx, y: cy } = q.p2;\r\n        let (u0, u1, u2) = (by - cy, cx - bx, bx * cy - by * cx);\r\n        let (v0, v1, v2) = (cy - ay, ax - cx, cx * ay - cy * ax);\r\n        let (w0, w1, w2) = (ay - by, bx - ax, ax * by - ay * bx);\r\n        ImplicitQuad {\r\n            x2: 4. * u0 * w0 - v0 * v0,\r\n            xy: 4. * (u0 * w1 + u1 * w0) - 2. * v0 * v1,\r\n            y2: 4. * u1 * w1 - v1 * v1,\r\n            x: 4. * (u0 * w2 + u2 * w0) - 2. * v0 * v2,\r\n            y: 4. * (u1 * w2 + u2 * w1) - 2. * v1 * v2,\r\n            c: 4. * u2 * w2 - v2 * v2,\r\n        }\r\n    }\r\n\r\n    fn eval(&self, x: f64, y: f64) -> f64 {\r\n        self.x2 * x * x + self.xy * x * y + self.y2 * y * y + self.x * x + self.y * y + self.c\r\n    }\r\n}\r\n\r\nfn intersect_quads(q0: QuadBez, q1: QuadBez) -> ArrayVec<f64, 4> {\r\n    let iq = ImplicitQuad::from_quad(q0);\r\n    let c = q1.p0.to_vec2();\r\n    let b = (q1.p1 - q1.p0) * 2.0;\r\n    let a = c - q1.p1.to_vec2() * 2.0 + q1.p2.to_vec2();\r\n    let c0 = iq.eval(c.x, c.y);\r\n    let c1 = iq.x * b.x\r\n        + iq.y * b.y\r\n        + 2. * iq.x2 * (b.x * c.x)\r\n        + 2. * iq.y2 * (b.y * c.y)\r\n        + iq.xy * (b.x * c.y + b.y * c.x);\r\n    let c2 = iq.x * a.x\r\n        + iq.y * a.y\r\n        + iq.x2 * (2. * a.x * c.x + b.x * b.x)\r\n        + iq.xy * (a.x * c.y + b.x * b.y + a.y * c.x)\r\n        + iq.y2 * (2. * a.y * c.y + b.y * b.y);\r\n    let c3 = iq.x2 * 2. * a.x * b.x + iq.xy * (a.x * b.y + b.x * a.y) + iq.y2 * 2. * a.y * b.y;\r\n    let c4 = iq.x2 * a.x * a.x + iq.xy * a.x * a.y + iq.y2 * a.y * a.y;\r\n    let ts = solve_quartic(c0, c1, c2, c3, c4);\r\n    println!(\"ts: {:?}\", ts);\r\n    ts\r\n}\r\n\r\nfn main() {\r\n    let q0 = rand_quad();\r\n    let q1 = rand_quad();\r\n    println!(\r\n        \"  <path d='{}' stroke='#000' fill='none' />\",\r\n        q0.to_path(1e-9).to_svg()\r\n    );\r\n    println!(\r\n        \"  <path d='{}' stroke='#008' fill='none' />\",\r\n        q1.to_path(1e-9).to_svg()\r\n    );\r\n    for t in intersect_quads(q0, q1) {\r\n        if (0.0..=1.0).contains(&t) {\r\n            let p = q1.eval(t);\r\n            println!(\"  <circle cx='{}' cy='{}' r='3' />\", p.x, p.y);\r\n        }\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "examples/simplify.rs",
      "sha256": "87b273a11bb4a4128f36fe50e18c38afeeef62d8691ab038af147af1db276ccc",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Test case showing simplification of a Bézier path. In this case, the\r\n//! source path is a simple mathematical function, but it should work for\r\n//! more general cases as well.\r\n\r\nuse kurbo::{BezPath, Point};\r\n\r\nfn plot_fn(f: &dyn Fn(f64) -> f64, d: &dyn Fn(f64) -> f64, xa: f64, xb: f64, n: usize) -> BezPath {\r\n    let width = 800.;\r\n    let dx = (xb - xa) / n as f64;\r\n    let xs = width / (xb - xa);\r\n    let ys = 250.;\r\n    let y_origin = 300.;\r\n    let plot = |x, y| Point::new((x - xa) * xs, y_origin - y * ys);\r\n    let mut x0 = xa;\r\n    let mut y0 = f(xa);\r\n    let mut d0 = d(xa);\r\n    let mut path = BezPath::new();\r\n    path.move_to(plot(x0, y0));\r\n    for i in 0..n {\r\n        let x3 = xa + dx * (i + 1) as f64;\r\n        let y3 = f(x3);\r\n        let d3 = d(x3);\r\n        let x1 = x0 + (1. / 3.) * dx;\r\n        let x2 = x3 - (1. / 3.) * dx;\r\n        let y1 = y0 + d0 * (1. / 3.) * dx;\r\n        let y2 = y3 - d3 * (1. / 3.) * dx;\r\n        path.curve_to(plot(x1, y1), plot(x2, y2), plot(x3, y3));\r\n        x0 = x3;\r\n        y0 = y3;\r\n        d0 = d3;\r\n    }\r\n    path\r\n}\r\n\r\nfn main() {\r\n    println!(\"<svg width='800' height='600' xmlns='http://www.w3.org/2000/svg'>\");\r\n    let path = plot_fn(&|x| x.sin(), &|x| x.cos(), -8., 8., 20);\r\n    println!(\r\n        \"  <path d='{}' stroke='#8c8' fill='none' stroke-width='5'/>\",\r\n        path.to_svg()\r\n    );\r\n    let simpl = kurbo::simplify::SimplifyBezPath::new(path);\r\n    let simplified_path = kurbo::fit_to_bezpath_opt(&simpl, 0.1);\r\n    println!(\r\n        \"  <path d='{}' stroke='#000' fill='none' stroke-width='1'/>\",\r\n        simplified_path.to_svg()\r\n    );\r\n    println!(\"</svg>\");\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/affine.rs",
      "sha256": "7d9dfd98195bb4561a6aa85df1f7d39468b69bba67710ebb3402bc89556ef4d5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Affine transforms.\r\n\r\nuse core::ops::{Mul, MulAssign};\r\n\r\nuse crate::{Point, Rect, Vec2};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A 2D affine transform.\r\n#[derive(Clone, Copy, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct Affine([f64; 6]);\r\n\r\nimpl Affine {\r\n    /// The identity transform.\r\n    pub const IDENTITY: Affine = Affine::scale(1.0);\r\n\r\n    /// A transform that is flipped on the y-axis. Useful for converting between\r\n    /// y-up and y-down spaces.\r\n    pub const FLIP_Y: Affine = Affine::new([1.0, 0., 0., -1.0, 0., 0.]);\r\n\r\n    /// A transform that is flipped on the x-axis.\r\n    pub const FLIP_X: Affine = Affine::new([-1.0, 0., 0., 1.0, 0., 0.]);\r\n\r\n    /// Construct an affine transform from coefficients.\r\n    ///\r\n    /// If the coefficients are `(a, b, c, d, e, f)`, then the resulting\r\n    /// transformation represents this augmented matrix:\r\n    ///\r\n    /// ```text\r\n    /// | a c e |\r\n    /// | b d f |\r\n    /// | 0 0 1 |\r\n    /// ```\r\n    ///\r\n    /// Note that this convention is transposed from PostScript and\r\n    /// Direct2D, but is consistent with the\r\n    /// [Wikipedia](https://en.wikipedia.org/wiki/Affine_transformation)\r\n    /// formulation of affine transformation as augmented matrix. The\r\n    /// idea is that `(A * B) * v == A * (B * v)`, where `*` is the\r\n    /// [`Mul`](std::ops::Mul) trait.\r\n    #[inline]\r\n    pub const fn new(c: [f64; 6]) -> Affine {\r\n        Affine(c)\r\n    }\r\n\r\n    /// An affine transform representing uniform scaling.\r\n    #[inline]\r\n    pub const fn scale(s: f64) -> Affine {\r\n        Affine([s, 0.0, 0.0, s, 0.0, 0.0])\r\n    }\r\n\r\n    /// An affine transform representing non-uniform scaling\r\n    /// with different scale values for x and y\r\n    #[inline]\r\n    pub const fn scale_non_uniform(s_x: f64, s_y: f64) -> Affine {\r\n        Affine([s_x, 0.0, 0.0, s_y, 0.0, 0.0])\r\n    }\r\n\r\n    /// An affine transform representing rotation.\r\n    ///\r\n    /// The convention for rotation is that a positive angle rotates a\r\n    /// positive X direction into positive Y. Thus, in a Y-down coordinate\r\n    /// system (as is common for graphics), it is a clockwise rotation, and\r\n    /// in Y-up (traditional for math), it is anti-clockwise.\r\n    ///\r\n    /// The angle, `th`, is expressed in radians.\r\n    #[inline]\r\n    pub fn rotate(th: f64) -> Affine {\r\n        let (s, c) = th.sin_cos();\r\n        Affine([c, s, -s, c, 0.0, 0.0])\r\n    }\r\n\r\n    /// An affine transform representing a rotation of `th` radians about `center`.\r\n    ///\r\n    /// See [Affine::rotate] for more info.\r\n    #[inline]\r\n    pub fn rotate_about(th: f64, center: Point) -> Affine {\r\n        let center = center.to_vec2();\r\n        Self::translate(-center)\r\n            .then_rotate(th)\r\n            .then_translate(center)\r\n    }\r\n\r\n    /// An affine transform representing translation.\r\n    #[inline]\r\n    pub fn translate<V: Into<Vec2>>(p: V) -> Affine {\r\n        let p = p.into();\r\n        Affine([1.0, 0.0, 0.0, 1.0, p.x, p.y])\r\n    }\r\n\r\n    /// An affine transformation representing a skew.\r\n    ///\r\n    /// The skew_x and skew_y parameters represent skew factors for the\r\n    /// horizontal and vertical directions, respectively.\r\n    ///\r\n    /// This is commonly used to generate a faux oblique transform for\r\n    /// font rendering. In this case, you can slant the glyph 20 degrees\r\n    /// clockwise in the horizontal direction (assuming a Y-up coordinate\r\n    /// system):\r\n    ///\r\n    /// ```\r\n    /// let oblique_transform = kurbo::Affine::skew(20f64.to_radians().tan(), 0.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn skew(skew_x: f64, skew_y: f64) -> Affine {\r\n        Affine([1.0, skew_y, skew_x, 1.0, 0.0, 0.0])\r\n    }\r\n\r\n    /// A rotation by `th` followed by `self`.\r\n    ///\r\n    /// Equivalent to `self * Affine::rotate(th)`\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn pre_rotate(self, th: f64) -> Self {\r\n        self * Affine::rotate(th)\r\n    }\r\n\r\n    /// A rotation by `th` about `center` followed by `self`.\r\n    ///\r\n    /// Equivalent to `self * Affine::rotate_about(th)`\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn pre_rotate_about(self, th: f64, center: Point) -> Self {\r\n        Affine::rotate_about(th, center) * self\r\n    }\r\n\r\n    /// A scale by `scale` followed by `self`.\r\n    ///\r\n    /// Equivalent to `self * Affine::scale(scale)`\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn pre_scale(self, scale: f64) -> Self {\r\n        self * Affine::scale(scale)\r\n    }\r\n\r\n    /// A scale by `(scale_x, scale_y)` followed by `self`.\r\n    ///\r\n    /// Equivalent to `self * Affine::scale_non_uniform(scale_x, scale_y)`\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn pre_scale_non_uniform(self, scale_x: f64, scale_y: f64) -> Self {\r\n        self * Affine::scale_non_uniform(scale_x, scale_y)\r\n    }\r\n\r\n    /// A translation of `trans` followed by `self`.\r\n    ///\r\n    /// Equivalent to `self * Affine::translate(trans)`\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn pre_translate(self, trans: Vec2) -> Self {\r\n        self * Affine::translate(trans)\r\n    }\r\n\r\n    /// `self` followed by a rotation of `th`.\r\n    ///\r\n    /// Equivalent to `Affine::rotate(th) * self`\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn then_rotate(self, th: f64) -> Self {\r\n        Affine::rotate(th) * self\r\n    }\r\n\r\n    /// `self` followed by a rotation of `th` about `center.\r\n    ///\r\n    /// Equivalent to `Affine::rotate_about(th, center) * self`\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn then_rotate_about(self, th: f64, center: Point) -> Self {\r\n        Affine::rotate_about(th, center) * self\r\n    }\r\n\r\n    /// `self` followed by a scale of `scale`.\r\n    ///\r\n    /// Equivalent to `Affine::scale(scale) * self`\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn then_scale(self, scale: f64) -> Self {\r\n        Affine::scale(scale) * self\r\n    }\r\n\r\n    /// `self` followed by a scale of `(scale_x, scale_y)`.\r\n    ///\r\n    /// Equivalent to `Affine::scale_non_uniform(scale_x, scale_y) * self`\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn then_scale_non_uniform(self, scale_x: f64, scale_y: f64) -> Self {\r\n        Affine::scale_non_uniform(scale_x, scale_y) * self\r\n    }\r\n\r\n    /// `self` followed by a translation of `trans`.\r\n    ///\r\n    /// Equivalent to `Affine::translate(trans) * self`\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn then_translate(mut self, trans: Vec2) -> Self {\r\n        self.0[4] += trans.x;\r\n        self.0[5] += trans.y;\r\n        self\r\n    }\r\n\r\n    /// Creates an affine transformation that takes the unit square to the given rectangle.\r\n    ///\r\n    /// Useful when you want to draw into the unit square but have your output fill any rectangle.\r\n    /// In this case push the `Affine` onto the transform stack.\r\n    pub fn map_unit_square(rect: Rect) -> Affine {\r\n        Affine([rect.width(), 0., 0., rect.height(), rect.x0, rect.y0])\r\n    }\r\n\r\n    /// Get the coefficients of the transform.\r\n    #[inline]\r\n    pub fn as_coeffs(self) -> [f64; 6] {\r\n        self.0\r\n    }\r\n\r\n    /// Compute the determinant of this transform.\r\n    pub fn determinant(self) -> f64 {\r\n        self.0[0] * self.0[3] - self.0[1] * self.0[2]\r\n    }\r\n\r\n    /// Compute the inverse transform.\r\n    ///\r\n    /// Produces NaN values when the determinant is zero.\r\n    pub fn inverse(self) -> Affine {\r\n        let inv_det = self.determinant().recip();\r\n        Affine([\r\n            inv_det * self.0[3],\r\n            -inv_det * self.0[1],\r\n            -inv_det * self.0[2],\r\n            inv_det * self.0[0],\r\n            inv_det * (self.0[2] * self.0[5] - self.0[3] * self.0[4]),\r\n            inv_det * (self.0[1] * self.0[4] - self.0[0] * self.0[5]),\r\n        ])\r\n    }\r\n\r\n    /// Compute the bounding box of a transformed rectangle.\r\n    ///\r\n    /// Returns the minimal `Rect` that encloses the given `Rect` after affine transformation.\r\n    /// If the transform is axis-aligned, then this bounding box is \"tight\", in other words the\r\n    /// returned `Rect` is the transformed rectangle.\r\n    ///\r\n    /// The returned rectangle always has non-negative width and height.\r\n    pub fn transform_rect_bbox(self, rect: Rect) -> Rect {\r\n        let p00 = self * Point::new(rect.x0, rect.y0);\r\n        let p01 = self * Point::new(rect.x0, rect.y1);\r\n        let p10 = self * Point::new(rect.x1, rect.y0);\r\n        let p11 = self * Point::new(rect.x1, rect.y1);\r\n        Rect::from_points(p00, p01).union(Rect::from_points(p10, p11))\r\n    }\r\n\r\n    /// Is this map finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.0[0].is_finite()\r\n            && self.0[1].is_finite()\r\n            && self.0[2].is_finite()\r\n            && self.0[3].is_finite()\r\n            && self.0[4].is_finite()\r\n            && self.0[5].is_finite()\r\n    }\r\n\r\n    /// Is this map NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.0[0].is_nan()\r\n            || self.0[1].is_nan()\r\n            || self.0[2].is_nan()\r\n            || self.0[3].is_nan()\r\n            || self.0[4].is_nan()\r\n            || self.0[5].is_nan()\r\n    }\r\n\r\n    /// Compute the singular value decomposition of the linear transformation (ignoring the\r\n    /// translation).\r\n    ///\r\n    /// All non-degenerate linear transformations can be represented as\r\n    ///\r\n    ///  1. a rotation about the origin.\r\n    ///  2. a scaling along the x and y axes\r\n    ///  3. another rotation about the origin\r\n    ///\r\n    /// composed together. Decomposing a 2x2 matrix in this way is called a \"singular value\r\n    /// decomposition\" and is written `U Σ V^T`, where U and V^T are orthogonal (rotations) and Σ\r\n    /// is a diagonal matrix (a scaling).\r\n    ///\r\n    /// Since currently this function is used to calculate ellipse radii and rotation from an\r\n    /// affine map on the unit circle, we don't calculate V^T, since a rotation of the unit (or\r\n    /// any) circle about its center always results in the same circle. This is the reason that an\r\n    /// ellipse mapped using an affine map is always an ellipse.\r\n    ///\r\n    /// Will return NaNs if the matrix (or equivalently the linear map) is singular.\r\n    ///\r\n    /// First part of the return tuple is the scaling, second part is the angle of rotation (in\r\n    /// radians)\r\n    #[inline]\r\n    pub(crate) fn svd(self) -> (Vec2, f64) {\r\n        let a = self.0[0];\r\n        let a2 = a * a;\r\n        let b = self.0[1];\r\n        let b2 = b * b;\r\n        let c = self.0[2];\r\n        let c2 = c * c;\r\n        let d = self.0[3];\r\n        let d2 = d * d;\r\n        let ab = a * b;\r\n        let cd = c * d;\r\n        let angle = 0.5 * (2.0 * (ab + cd)).atan2(a2 - b2 + c2 - d2);\r\n        let s1 = a2 + b2 + c2 + d2;\r\n        let s2 = ((a2 - b2 + c2 - d2).powi(2) + 4.0 * (ab + cd).powi(2)).sqrt();\r\n        (\r\n            Vec2 {\r\n                x: (0.5 * (s1 + s2)).sqrt(),\r\n                y: (0.5 * (s1 - s2)).sqrt(),\r\n            },\r\n            angle,\r\n        )\r\n    }\r\n\r\n    /// Returns the translation part of this affine map (`(self.0[4], self.0[5])`).\r\n    #[inline]\r\n    pub fn translation(self) -> Vec2 {\r\n        Vec2 {\r\n            x: self.0[4],\r\n            y: self.0[5],\r\n        }\r\n    }\r\n\r\n    /// Replaces the translation portion of this affine map\r\n    ///\r\n    /// The translation can be seen as being applied after the linear part of the map.\r\n    #[must_use]\r\n    #[inline]\r\n    pub fn with_translation(mut self, trans: Vec2) -> Affine {\r\n        self.0[4] = trans.x;\r\n        self.0[5] = trans.y;\r\n        self\r\n    }\r\n}\r\n\r\nimpl Default for Affine {\r\n    #[inline]\r\n    fn default() -> Affine {\r\n        Affine::IDENTITY\r\n    }\r\n}\r\n\r\nimpl Mul<Point> for Affine {\r\n    type Output = Point;\r\n\r\n    #[inline]\r\n    fn mul(self, other: Point) -> Point {\r\n        Point::new(\r\n            self.0[0] * other.x + self.0[2] * other.y + self.0[4],\r\n            self.0[1] * other.x + self.0[3] * other.y + self.0[5],\r\n        )\r\n    }\r\n}\r\n\r\nimpl Mul for Affine {\r\n    type Output = Affine;\r\n\r\n    #[inline]\r\n    fn mul(self, other: Affine) -> Affine {\r\n        Affine([\r\n            self.0[0] * other.0[0] + self.0[2] * other.0[1],\r\n            self.0[1] * other.0[0] + self.0[3] * other.0[1],\r\n            self.0[0] * other.0[2] + self.0[2] * other.0[3],\r\n            self.0[1] * other.0[2] + self.0[3] * other.0[3],\r\n            self.0[0] * other.0[4] + self.0[2] * other.0[5] + self.0[4],\r\n            self.0[1] * other.0[4] + self.0[3] * other.0[5] + self.0[5],\r\n        ])\r\n    }\r\n}\r\n\r\nimpl MulAssign for Affine {\r\n    #[inline]\r\n    fn mul_assign(&mut self, other: Affine) {\r\n        *self = self.mul(other);\r\n    }\r\n}\r\n\r\nimpl Mul<Affine> for f64 {\r\n    type Output = Affine;\r\n\r\n    #[inline]\r\n    fn mul(self, other: Affine) -> Affine {\r\n        Affine([\r\n            self * other.0[0],\r\n            self * other.0[1],\r\n            self * other.0[2],\r\n            self * other.0[3],\r\n            self * other.0[4],\r\n            self * other.0[5],\r\n        ])\r\n    }\r\n}\r\n\r\n// Conversions to and from mint\r\n#[cfg(feature = \"mint\")]\r\nimpl From<Affine> for mint::ColumnMatrix2x3<f64> {\r\n    #[inline]\r\n    fn from(a: Affine) -> mint::ColumnMatrix2x3<f64> {\r\n        mint::ColumnMatrix2x3 {\r\n            x: mint::Vector2 {\r\n                x: a.0[0],\r\n                y: a.0[1],\r\n            },\r\n            y: mint::Vector2 {\r\n                x: a.0[2],\r\n                y: a.0[3],\r\n            },\r\n            z: mint::Vector2 {\r\n                x: a.0[4],\r\n                y: a.0[5],\r\n            },\r\n        }\r\n    }\r\n}\r\n\r\n#[cfg(feature = \"mint\")]\r\nimpl From<mint::ColumnMatrix2x3<f64>> for Affine {\r\n    #[inline]\r\n    fn from(m: mint::ColumnMatrix2x3<f64>) -> Affine {\r\n        Affine([m.x.x, m.x.y, m.y.x, m.y.y, m.z.x, m.z.y])\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{Affine, Point};\r\n    use std::f64::consts::PI;\r\n\r\n    fn assert_near(p0: Point, p1: Point) {\r\n        assert!((p1 - p0).hypot() < 1e-9, \"{p0:?} != {p1:?}\");\r\n    }\r\n\r\n    #[test]\r\n    fn affine_basic() {\r\n        let p = Point::new(3.0, 4.0);\r\n\r\n        assert_near(Affine::default() * p, p);\r\n        assert_near(Affine::scale(2.0) * p, Point::new(6.0, 8.0));\r\n        assert_near(Affine::rotate(0.0) * p, p);\r\n        assert_near(Affine::rotate(PI / 2.0) * p, Point::new(-4.0, 3.0));\r\n        assert_near(Affine::translate((5.0, 6.0)) * p, Point::new(8.0, 10.0));\r\n        assert_near(Affine::skew(0.0, 0.0) * p, p);\r\n        assert_near(Affine::skew(2.0, 4.0) * p, Point::new(11.0, 16.0));\r\n    }\r\n\r\n    #[test]\r\n    fn affine_mul() {\r\n        let a1 = Affine::new([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);\r\n        let a2 = Affine::new([0.1, 1.2, 2.3, 3.4, 4.5, 5.6]);\r\n\r\n        let px = Point::new(1.0, 0.0);\r\n        let py = Point::new(0.0, 1.0);\r\n        let pxy = Point::new(1.0, 1.0);\r\n        assert_near(a1 * (a2 * px), (a1 * a2) * px);\r\n        assert_near(a1 * (a2 * py), (a1 * a2) * py);\r\n        assert_near(a1 * (a2 * pxy), (a1 * a2) * pxy);\r\n    }\r\n\r\n    #[test]\r\n    fn affine_inv() {\r\n        let a = Affine::new([0.1, 1.2, 2.3, 3.4, 4.5, 5.6]);\r\n        let a_inv = a.inverse();\r\n\r\n        let px = Point::new(1.0, 0.0);\r\n        let py = Point::new(0.0, 1.0);\r\n        let pxy = Point::new(1.0, 1.0);\r\n        assert_near(a * (a_inv * px), px);\r\n        assert_near(a * (a_inv * py), py);\r\n        assert_near(a * (a_inv * pxy), pxy);\r\n        assert_near(a_inv * (a * px), px);\r\n        assert_near(a_inv * (a * py), py);\r\n        assert_near(a_inv * (a * pxy), pxy);\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/arc.rs",
      "sha256": "0810fdbce31e6647603415622b017b4b0c5661d225d89eee9282f9f63a162e02",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! An ellipse arc.\r\n\r\nuse crate::{Affine, Ellipse, PathEl, Point, Rect, Shape, Vec2};\r\nuse core::{\r\n    f64::consts::{FRAC_PI_2, PI},\r\n    iter,\r\n    ops::Mul,\r\n};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A single arc segment.\r\n#[derive(Clone, Copy, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct Arc {\r\n    /// The arc's centre point.\r\n    pub center: Point,\r\n    /// The arc's radii, where the vector's x-component is the radius in the\r\n    /// positive x direction after applying `x_rotation`.\r\n    pub radii: Vec2,\r\n    /// The start angle in radians.\r\n    pub start_angle: f64,\r\n    /// The angle between the start and end of the arc, in radians.\r\n    pub sweep_angle: f64,\r\n    /// How much the arc is rotated, in radians.\r\n    pub x_rotation: f64,\r\n}\r\n\r\nimpl Arc {\r\n    /// Create a new `Arc`.\r\n    pub fn new(\r\n        center: impl Into<Point>,\r\n        radii: impl Into<Vec2>,\r\n        start_angle: f64,\r\n        sweep_angle: f64,\r\n        x_rotation: f64,\r\n    ) -> Self {\r\n        Self {\r\n            center: center.into(),\r\n            radii: radii.into(),\r\n            start_angle,\r\n            sweep_angle,\r\n            x_rotation,\r\n        }\r\n    }\r\n\r\n    /// Create an iterator generating Bezier path elements.\r\n    ///\r\n    /// The generated elements can be appended to an existing bezier path.\r\n    pub fn append_iter(&self, tolerance: f64) -> ArcAppendIter {\r\n        let sign = self.sweep_angle.signum();\r\n        let scaled_err = self.radii.x.max(self.radii.y) / tolerance;\r\n        // Number of subdivisions per ellipse based on error tolerance.\r\n        // Note: this may slightly underestimate the error for quadrants.\r\n        let n_err = (1.1163 * scaled_err).powf(1.0 / 6.0).max(3.999_999);\r\n        let n = (n_err * self.sweep_angle.abs() * (1.0 / (2.0 * PI))).ceil();\r\n        let angle_step = self.sweep_angle / n;\r\n        let n = n as usize;\r\n        let arm_len = (4.0 / 3.0) * (0.25 * angle_step).abs().tan() * sign;\r\n        let angle0 = self.start_angle;\r\n        let p0 = sample_ellipse(self.radii, self.x_rotation, angle0);\r\n\r\n        ArcAppendIter {\r\n            idx: 0,\r\n\r\n            center: self.center,\r\n            radii: self.radii,\r\n            x_rotation: self.x_rotation,\r\n            n,\r\n            arm_len,\r\n            angle_step,\r\n\r\n            p0,\r\n            angle0,\r\n        }\r\n    }\r\n\r\n    /// Converts an Arc into a series of cubic bezier segments.\r\n    ///\r\n    /// Closure will be invoked for each segment.\r\n    pub fn to_cubic_beziers<P>(self, tolerance: f64, mut p: P)\r\n    where\r\n        P: FnMut(Point, Point, Point),\r\n    {\r\n        let mut path = self.append_iter(tolerance);\r\n        while let Some(PathEl::CurveTo(p1, p2, p3)) = path.next() {\r\n            p(p1, p2, p3);\r\n        }\r\n    }\r\n}\r\n\r\n#[doc(hidden)]\r\npub struct ArcAppendIter {\r\n    idx: usize,\r\n\r\n    center: Point,\r\n    radii: Vec2,\r\n    x_rotation: f64,\r\n    n: usize,\r\n    arm_len: f64,\r\n    angle_step: f64,\r\n\r\n    p0: Vec2,\r\n    angle0: f64,\r\n}\r\n\r\nimpl Iterator for ArcAppendIter {\r\n    type Item = PathEl;\r\n\r\n    fn next(&mut self) -> Option<Self::Item> {\r\n        if self.idx >= self.n {\r\n            return None;\r\n        }\r\n\r\n        let angle1 = self.angle0 + self.angle_step;\r\n        let p0 = self.p0;\r\n        let p1 = p0\r\n            + self.arm_len * sample_ellipse(self.radii, self.x_rotation, self.angle0 + FRAC_PI_2);\r\n        let p3 = sample_ellipse(self.radii, self.x_rotation, angle1);\r\n        let p2 =\r\n            p3 - self.arm_len * sample_ellipse(self.radii, self.x_rotation, angle1 + FRAC_PI_2);\r\n\r\n        self.angle0 = angle1;\r\n        self.p0 = p3;\r\n        self.idx += 1;\r\n\r\n        Some(PathEl::CurveTo(\r\n            self.center + p1,\r\n            self.center + p2,\r\n            self.center + p3,\r\n        ))\r\n    }\r\n}\r\n\r\n/// Take the ellipse radii, how the radii are rotated, and the sweep angle, and return a point on\r\n/// the ellipse.\r\nfn sample_ellipse(radii: Vec2, x_rotation: f64, angle: f64) -> Vec2 {\r\n    let (angle_sin, angle_cos) = angle.sin_cos();\r\n    let u = radii.x * angle_cos;\r\n    let v = radii.y * angle_sin;\r\n    rotate_pt(Vec2::new(u, v), x_rotation)\r\n}\r\n\r\n/// Rotate `pt` about the origin by `angle` radians.\r\nfn rotate_pt(pt: Vec2, angle: f64) -> Vec2 {\r\n    let (angle_sin, angle_cos) = angle.sin_cos();\r\n    Vec2::new(\r\n        pt.x * angle_cos - pt.y * angle_sin,\r\n        pt.x * angle_sin + pt.y * angle_cos,\r\n    )\r\n}\r\n\r\nimpl Shape for Arc {\r\n    type PathElementsIter<'iter> = iter::Chain<iter::Once<PathEl>, ArcAppendIter>;\r\n\r\n    fn path_elements(&self, tolerance: f64) -> Self::PathElementsIter<'_> {\r\n        let p0 = sample_ellipse(self.radii, self.x_rotation, self.start_angle);\r\n        iter::once(PathEl::MoveTo(self.center + p0)).chain(self.append_iter(tolerance))\r\n    }\r\n\r\n    /// Note: shape isn't closed so area is not well defined.\r\n    #[inline]\r\n    fn area(&self) -> f64 {\r\n        let Vec2 { x, y } = self.radii;\r\n        PI * x * y\r\n    }\r\n\r\n    /// The perimeter of the ellipse.\r\n    ///\r\n    /// Note: Finding the perimeter of an ellipse is [fairly involved][wikipedia],\r\n    /// so for now we just approximate by using the bezier curve representation.\r\n    ///\r\n    /// [wikipedia]: https://en.wikipedia.org/wiki/Ellipse#Circumference\r\n    #[inline]\r\n    fn perimeter(&self, accuracy: f64) -> f64 {\r\n        self.path_segments(0.1).perimeter(accuracy)\r\n    }\r\n\r\n    /// Note: shape isn't closed, so a point's winding number is not well defined.\r\n    #[inline]\r\n    fn winding(&self, pt: Point) -> i32 {\r\n        self.path_segments(0.1).winding(pt)\r\n    }\r\n\r\n    #[inline]\r\n    fn bounding_box(&self) -> Rect {\r\n        self.path_segments(0.1).bounding_box()\r\n    }\r\n}\r\n\r\nimpl Mul<Arc> for Affine {\r\n    type Output = Arc;\r\n\r\n    fn mul(self, arc: Arc) -> Self::Output {\r\n        let ellipse = self * Ellipse::new(arc.center, arc.radii, arc.x_rotation);\r\n        let center = ellipse.center();\r\n        let (radii, rotation) = ellipse.radii_and_rotation();\r\n        Arc {\r\n            center,\r\n            radii,\r\n            x_rotation: rotation,\r\n            start_angle: arc.start_angle,\r\n            sweep_angle: arc.sweep_angle,\r\n        }\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/bezpath.rs",
      "sha256": "35012ab6b710873b0f9f70cbaac470f080da518548b943387c5db0d7c9537d29",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Bézier paths (up to cubic).\r\n\r\n#![allow(clippy::many_single_char_names)]\r\n\r\nuse core::iter::{Extend, FromIterator};\r\nuse core::mem;\r\nuse core::ops::{Mul, Range};\r\n\r\nuse alloc::vec::Vec;\r\n\r\nuse arrayvec::ArrayVec;\r\n\r\nuse crate::common::{solve_cubic, solve_quadratic};\r\nuse crate::MAX_EXTREMA;\r\nuse crate::{\r\n    Affine, CubicBez, Line, Nearest, ParamCurve, ParamCurveArclen, ParamCurveArea,\r\n    ParamCurveExtrema, ParamCurveNearest, Point, QuadBez, Rect, Shape, TranslateScale, Vec2,\r\n};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A Bézier path.\r\n///\r\n/// These docs assume basic familiarity with Bézier curves; for an introduction,\r\n/// see Pomax's wonderful [A Primer on Bézier Curves].\r\n///\r\n/// This path can contain lines, quadratics ([`QuadBez`]) and cubics\r\n/// ([`CubicBez`]), and may contain multiple subpaths.\r\n///\r\n/// # Elements and Segments\r\n///\r\n/// A Bézier path can be represented in terms of either 'elements' ([`PathEl`])\r\n/// or 'segments' ([`PathSeg`]). Elements map closely to how Béziers are\r\n/// generally used in PostScript-style drawing APIs; they can be thought of as\r\n/// instructions for drawing the path. Segments more directly describe the\r\n/// path itself, with each segment being an independent line or curve.\r\n///\r\n/// These different representations are useful in different contexts.\r\n/// For tasks like drawing, elements are a natural fit, but when doing\r\n/// hit-testing or subdividing, we need to have access to the segments.\r\n///\r\n/// Conceptually, a `BezPath` contains zero or more subpaths. Each subpath\r\n/// *always* begins with a `MoveTo`, then has zero or more `LineTo`, `QuadTo`,\r\n/// and `CurveTo` elements, and optionally ends with a `ClosePath`.\r\n///\r\n/// Internally, a `BezPath` is a list of [`PathEl`]s; as such it implements\r\n/// [`FromIterator<PathEl>`] and [`Extend<PathEl>`]:\r\n///\r\n/// ```\r\n/// use kurbo::{BezPath, Rect, Shape, Vec2};\r\n/// let accuracy = 0.1;\r\n/// let rect = Rect::from_origin_size((0., 0.,), (10., 10.));\r\n/// // these are equivalent\r\n/// let path1 = rect.to_path(accuracy);\r\n/// let path2: BezPath = rect.path_elements(accuracy).collect();\r\n///\r\n/// // extend a path with another path:\r\n/// let mut path = rect.to_path(accuracy);\r\n/// let shifted_rect = rect + Vec2::new(5.0, 10.0);\r\n/// path.extend(shifted_rect.to_path(accuracy));\r\n/// ```\r\n///\r\n/// You can iterate the elements of a `BezPath` with the [`iter`] method,\r\n/// and the segments with the [`segments`] method:\r\n///\r\n/// ```\r\n/// use kurbo::{BezPath, Line, PathEl, PathSeg, Point, Rect, Shape};\r\n/// let accuracy = 0.1;\r\n/// let rect = Rect::from_origin_size((0., 0.,), (10., 10.));\r\n/// // these are equivalent\r\n/// let path = rect.to_path(accuracy);\r\n/// let first_el = PathEl::MoveTo(Point::ZERO);\r\n/// let first_seg = PathSeg::Line(Line::new((0., 0.), (10., 0.)));\r\n/// assert_eq!(path.iter().next(), Some(first_el));\r\n/// assert_eq!(path.segments().next(), Some(first_seg));\r\n/// ```\r\n/// In addition, if you have some other type that implements\r\n/// `Iterator<Item=PathEl>`, you can adapt that to an iterator of segments with\r\n/// the [`segments` free function].\r\n///\r\n/// # Advanced functionality\r\n///\r\n/// In addition to the basic API, there are several useful pieces of advanced\r\n/// functionality available on `BezPath`:\r\n///\r\n/// - [`flatten`] does Bézier flattening, converting a curve to a series of\r\n/// line segments\r\n/// - [`intersect_line`] computes intersections of a path with a line, useful\r\n/// for things like subdividing\r\n///\r\n/// [A Primer on Bézier Curves]: https://pomax.github.io/bezierinfo/\r\n/// [`iter`]: BezPath::iter\r\n/// [`segments`]: BezPath::segments\r\n/// [`flatten`]: BezPath::flatten\r\n/// [`intersect_line`]: PathSeg::intersect_line\r\n/// [`segments` free function]: segments\r\n/// [`FromIterator<PathEl>`]: std::iter::FromIterator\r\n/// [`Extend<PathEl>`]: std::iter::Extend\r\n#[derive(Clone, Default, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct BezPath(Vec<PathEl>);\r\n\r\n/// The element of a Bézier path.\r\n///\r\n/// A valid path has `MoveTo` at the beginning of each subpath.\r\n#[derive(Clone, Copy, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub enum PathEl {\r\n    /// Move directly to the point without drawing anything, starting a new\r\n    /// subpath.\r\n    MoveTo(Point),\r\n    /// Draw a line from the current location to the point.\r\n    LineTo(Point),\r\n    /// Draw a quadratic bezier using the current location and the two points.\r\n    QuadTo(Point, Point),\r\n    /// Draw a cubic bezier using the current location and the three points.\r\n    CurveTo(Point, Point, Point),\r\n    /// Close off the path.\r\n    ClosePath,\r\n}\r\n\r\n/// A segment of a Bézier path.\r\n#[derive(Clone, Copy, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub enum PathSeg {\r\n    /// A line segment.\r\n    Line(Line),\r\n    /// A quadratic bezier segment.\r\n    Quad(QuadBez),\r\n    /// A cubic bezier segment.\r\n    Cubic(CubicBez),\r\n}\r\n\r\n/// An intersection of a [`Line`] and a [`PathSeg`].\r\n///\r\n/// This can be generated with the [`PathSeg::intersect_line`] method.\r\n#[derive(Debug, Clone, Copy)]\r\npub struct LineIntersection {\r\n    /// The 'time' that the intersection occurs, on the line.\r\n    ///\r\n    /// This value is in the range 0..1.\r\n    pub line_t: f64,\r\n\r\n    /// The 'time' that the intersection occurs, on the path segment.\r\n    ///\r\n    /// This value is nominally in the range 0..1, although it may slightly exceed\r\n    /// that range at the boundaries of segments.\r\n    pub segment_t: f64,\r\n}\r\n\r\n/// The minimum distance between two Bézier curves.\r\npub struct MinDistance {\r\n    /// The shortest distance between any two points on the two curves.\r\n    pub distance: f64,\r\n    /// The position of the nearest point on the first curve, as a parameter.\r\n    ///\r\n    /// To resolve this to a [`Point`], use [`ParamCurve::eval`].\r\n    ///\r\n    /// [`ParamCurve::eval`]: crate::ParamCurve::eval\r\n    pub t1: f64,\r\n    /// The position of the nearest point on the second curve, as a parameter.\r\n    ///\r\n    /// To resolve this to a [`Point`], use [`ParamCurve::eval`].\r\n    ///\r\n    /// [`ParamCurve::eval`]: crate::ParamCurve::eval\r\n    pub t2: f64,\r\n}\r\n\r\nimpl BezPath {\r\n    /// Create a new path.\r\n    pub fn new() -> BezPath {\r\n        Default::default()\r\n    }\r\n\r\n    /// Create a path from a vector of path elements.\r\n    ///\r\n    /// `BezPath` also implements `FromIterator<PathEl>`, so it works with `collect`:\r\n    ///\r\n    /// ```\r\n    /// // a very contrived example:\r\n    /// use kurbo::{BezPath, PathEl};\r\n    ///\r\n    /// let path = BezPath::new();\r\n    /// let as_vec: Vec<PathEl> = path.into_iter().collect();\r\n    /// let back_to_path: BezPath = as_vec.into_iter().collect();\r\n    /// ```\r\n    pub fn from_vec(v: Vec<PathEl>) -> BezPath {\r\n        debug_assert!(\r\n            v.first().is_none() || matches!(v.first(), Some(PathEl::MoveTo(_))),\r\n            \"BezPath must begin with MoveTo\"\r\n        );\r\n        BezPath(v)\r\n    }\r\n\r\n    /// Removes the last [`PathEl`] from the path and returns it, or `None` if the path is empty.\r\n    pub fn pop(&mut self) -> Option<PathEl> {\r\n        self.0.pop()\r\n    }\r\n\r\n    /// Push a generic path element onto the path.\r\n    pub fn push(&mut self, el: PathEl) {\r\n        self.0.push(el);\r\n        debug_assert!(\r\n            matches!(self.0.first(), Some(PathEl::MoveTo(_))),\r\n            \"BezPath must begin with MoveTo\"\r\n        )\r\n    }\r\n\r\n    /// Push a \"move to\" element onto the path.\r\n    pub fn move_to<P: Into<Point>>(&mut self, p: P) {\r\n        self.push(PathEl::MoveTo(p.into()));\r\n    }\r\n\r\n    /// Push a \"line to\" element onto the path.\r\n    ///\r\n    /// Will panic with a debug assert when the current subpath does not\r\n    /// start with `move_to`.\r\n    pub fn line_to<P: Into<Point>>(&mut self, p: P) {\r\n        debug_assert!(self.is_open_subpath(), \"no open subpath (missing MoveTo)\");\r\n        self.push(PathEl::LineTo(p.into()));\r\n    }\r\n\r\n    /// Push a \"quad to\" element onto the path.\r\n    ///\r\n    /// Will panic with a debug assert when the current subpath does not\r\n    /// start with `move_to`.\r\n    pub fn quad_to<P: Into<Point>>(&mut self, p1: P, p2: P) {\r\n        debug_assert!(self.is_open_subpath(), \"no open subpath (missing MoveTo)\");\r\n        self.push(PathEl::QuadTo(p1.into(), p2.into()));\r\n    }\r\n\r\n    /// Push a \"curve to\" element onto the path.\r\n    ///\r\n    /// Will panic with a debug assert when the current subpath does not\r\n    /// start with `move_to`.\r\n    pub fn curve_to<P: Into<Point>>(&mut self, p1: P, p2: P, p3: P) {\r\n        debug_assert!(self.is_open_subpath(), \"no open subpath (missing MoveTo)\");\r\n        self.push(PathEl::CurveTo(p1.into(), p2.into(), p3.into()));\r\n    }\r\n\r\n    /// Push a \"close path\" element onto the path.\r\n    ///\r\n    /// Will panic with a debug assert when the current subpath does not\r\n    /// start with `move_to`.\r\n    pub fn close_path(&mut self) {\r\n        debug_assert!(self.is_open_subpath(), \"no open subpath (missing MoveTo)\");\r\n        self.push(PathEl::ClosePath);\r\n    }\r\n\r\n    fn is_open_subpath(&self) -> bool {\r\n        !self.0.is_empty() && self.0.last() != Some(&PathEl::ClosePath)\r\n    }\r\n\r\n    /// Get the path elements.\r\n    pub fn elements(&self) -> &[PathEl] {\r\n        &self.0\r\n    }\r\n\r\n    /// Get the path elements (mut version).\r\n    pub fn elements_mut(&mut self) -> &mut [PathEl] {\r\n        &mut self.0\r\n    }\r\n\r\n    /// Returns an iterator over the path's elements.\r\n    pub fn iter(&self) -> impl Iterator<Item = PathEl> + Clone + '_ {\r\n        self.0.iter().copied()\r\n    }\r\n\r\n    /// Iterate over the path segments.\r\n    pub fn segments(&self) -> impl Iterator<Item = PathSeg> + Clone + '_ {\r\n        segments(self.iter())\r\n    }\r\n\r\n    /// Shorten the path, keeping the first `len` elements.\r\n    pub fn truncate(&mut self, len: usize) {\r\n        self.0.truncate(len);\r\n    }\r\n\r\n    /// Flatten the path, invoking the callback repeatedly.\r\n    ///\r\n    /// Flattening is the action of approximating a curve with a succession of line segments.\r\n    ///\r\n    /// <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 120 30\" height=\"30mm\" width=\"120mm\">\r\n    ///   <path d=\"M26.7 24.94l.82-11.15M44.46 5.1L33.8 7.34\" fill=\"none\" stroke=\"#55d400\" stroke-width=\".5\"/>\r\n    ///   <path d=\"M26.7 24.94c.97-11.13 7.17-17.6 17.76-19.84M75.27 24.94l1.13-5.5 2.67-5.48 4-4.42L88 6.7l5.02-1.6\" fill=\"none\" stroke=\"#000\"/>\r\n    ///   <path d=\"M77.57 19.37a1.1 1.1 0 0 1-1.08 1.08 1.1 1.1 0 0 1-1.1-1.08 1.1 1.1 0 0 1 1.08-1.1 1.1 1.1 0 0 1 1.1 1.1\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M77.57 19.37a1.1 1.1 0 0 1-1.08 1.08 1.1 1.1 0 0 1-1.1-1.08 1.1 1.1 0 0 1 1.08-1.1 1.1 1.1 0 0 1 1.1 1.1\" color=\"#000\" fill=\"#fff\"/>\r\n    ///   <path d=\"M80.22 13.93a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.08 1.1 1.1 0 0 1 1.08 1.08\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M80.22 13.93a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.08 1.1 1.1 0 0 1 1.08 1.08\" color=\"#000\" fill=\"#fff\"/>\r\n    ///   <path d=\"M84.08 9.55a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.1-1.1 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M84.08 9.55a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.1-1.1 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"#fff\"/>\r\n    ///   <path d=\"M89.1 6.66a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.08-1.08 1.1 1.1 0 0 1 1.1 1.08\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M89.1 6.66a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.08-1.08 1.1 1.1 0 0 1 1.1 1.08\" color=\"#000\" fill=\"#fff\"/>\r\n    ///   <path d=\"M94.4 5a1.1 1.1 0 0 1-1.1 1.1A1.1 1.1 0 0 1 92.23 5a1.1 1.1 0 0 1 1.08-1.08A1.1 1.1 0 0 1 94.4 5\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M94.4 5a1.1 1.1 0 0 1-1.1 1.1A1.1 1.1 0 0 1 92.23 5a1.1 1.1 0 0 1 1.08-1.08A1.1 1.1 0 0 1 94.4 5\" color=\"#000\" fill=\"#fff\"/>\r\n    ///   <path d=\"M76.44 25.13a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M76.44 25.13a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"#fff\"/>\r\n    ///   <path d=\"M27.78 24.9a1.1 1.1 0 0 1-1.08 1.08 1.1 1.1 0 0 1-1.1-1.08 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M27.78 24.9a1.1 1.1 0 0 1-1.08 1.08 1.1 1.1 0 0 1-1.1-1.08 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"#fff\"/>\r\n    ///   <path d=\"M45.4 5.14a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.1-1.1 1.1 1.1 0 0 1 1.1-1.08 1.1 1.1 0 0 1 1.1 1.08\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M45.4 5.14a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.1-1.1 1.1 1.1 0 0 1 1.1-1.08 1.1 1.1 0 0 1 1.1 1.08\" color=\"#000\" fill=\"#fff\"/>\r\n    ///   <path d=\"M28.67 13.8a1.1 1.1 0 0 1-1.1 1.08 1.1 1.1 0 0 1-1.08-1.08 1.1 1.1 0 0 1 1.08-1.1 1.1 1.1 0 0 1 1.1 1.1\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M28.67 13.8a1.1 1.1 0 0 1-1.1 1.08 1.1 1.1 0 0 1-1.08-1.08 1.1 1.1 0 0 1 1.08-1.1 1.1 1.1 0 0 1 1.1 1.1\" color=\"#000\" fill=\"#fff\"/>\r\n    ///   <path d=\"M35 7.32a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.1A1.1 1.1 0 0 1 35 7.33\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M35 7.32a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.1A1.1 1.1 0 0 1 35 7.33\" color=\"#000\" fill=\"#fff\"/>\r\n    ///   <text style=\"line-height:6.61458302px\" x=\"35.74\" y=\"284.49\" font-size=\"5.29\" font-family=\"Sans\" letter-spacing=\"0\" word-spacing=\"0\" fill=\"#b3b3b3\" stroke-width=\".26\" transform=\"translate(19.595 -267)\">\r\n    ///     <tspan x=\"35.74\" y=\"284.49\" font-size=\"10.58\">→</tspan>\r\n    ///   </text>\r\n    /// </svg>\r\n    ///\r\n    /// The tolerance value controls the maximum distance between the curved input\r\n    /// segments and their polyline approximations. (In technical terms, this is the\r\n    /// Hausdorff distance). The algorithm attempts to bound this distance between\r\n    /// by `tolerance` but this is not absolutely guaranteed. The appropriate value\r\n    /// depends on the use, but for antialiased rendering, a value of 0.25 has been\r\n    /// determined to give good results. The number of segments tends to scale as the\r\n    /// inverse square root of tolerance.\r\n    ///\r\n    /// <svg viewBox=\"0 0 47.5 13.2\" height=\"100\" width=\"350\" xmlns=\"http://www.w3.org/2000/svg\">\r\n    ///   <path d=\"M-2.44 9.53c16.27-8.5 39.68-7.93 52.13 1.9\" fill=\"none\" stroke=\"#dde9af\" stroke-width=\"4.6\"/>\r\n    ///   <path d=\"M-1.97 9.3C14.28 1.03 37.36 1.7 49.7 11.4\" fill=\"none\" stroke=\"#00d400\" stroke-width=\".57\" stroke-linecap=\"round\" stroke-dasharray=\"4.6, 2.291434\"/>\r\n    ///   <path d=\"M-1.94 10.46L6.2 6.08l28.32-1.4 15.17 6.74\" fill=\"none\" stroke=\"#000\" stroke-width=\".6\"/>\r\n    ///   <path d=\"M6.83 6.57a.9.9 0 0 1-1.25.15.9.9 0 0 1-.15-1.25.9.9 0 0 1 1.25-.15.9.9 0 0 1 .15 1.25\" color=\"#000\" stroke=\"#000\" stroke-width=\".57\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\r\n    ///   <path d=\"M35.35 5.3a.9.9 0 0 1-1.25.15.9.9 0 0 1-.15-1.25.9.9 0 0 1 1.25-.15.9.9 0 0 1 .15 1.24\" color=\"#000\" stroke=\"#000\" stroke-width=\".6\" stroke-opacity=\".5\"/>\r\n    ///   <g fill=\"none\" stroke=\"#ff7f2a\" stroke-width=\".26\">\r\n    ///     <path d=\"M20.4 3.8l.1 1.83M19.9 4.28l.48-.56.57.52M21.02 5.18l-.5.56-.6-.53\" stroke-width=\".2978872\"/>\r\n    ///   </g>\r\n    /// </svg>\r\n    ///\r\n    /// The callback will be called in order with each element of the generated\r\n    /// path. Because the result is made of polylines, these will be straight-line\r\n    /// path elements only, no curves.\r\n    ///\r\n    /// This algorithm is based on the blog post [Flattening quadratic Béziers]\r\n    /// but with some refinements. For one, there is a more careful approximation\r\n    /// at cusps. For two, the algorithm is extended to work with cubic Béziers\r\n    /// as well, by first subdividing into quadratics and then computing the\r\n    /// subdivision of each quadratic. However, as a clever trick, these quadratics\r\n    /// are subdivided fractionally, and their endpoints are not included.\r\n    ///\r\n    /// TODO: write a paper explaining this in more detail.\r\n    ///\r\n    /// Note: the [`flatten`] function provides the same\r\n    /// functionality but works with slices and other [`PathEl`] iterators.\r\n    ///\r\n    /// [Flattening quadratic Béziers]: https://raphlinus.github.io/graphics/curves/2019/12/23/flatten-quadbez.html\r\n    pub fn flatten(&self, tolerance: f64, callback: impl FnMut(PathEl)) {\r\n        flatten(self, tolerance, callback);\r\n    }\r\n\r\n    /// Get the segment at the given element index.\r\n    ///\r\n    /// If you need to access all segments, [`segments`] provides a better\r\n    /// API. This is intended for random access of specific elements, for clients\r\n    /// that require this specifically.\r\n    ///\r\n    /// **note**: This returns the segment that ends at the provided element\r\n    /// index. In effect this means it is *1-indexed*: since no segment ends at\r\n    /// the first element (which is presumed to be a `MoveTo`) `get_seg(0)` will\r\n    /// always return `None`.\r\n    pub fn get_seg(&self, ix: usize) -> Option<PathSeg> {\r\n        if ix == 0 || ix >= self.0.len() {\r\n            return None;\r\n        }\r\n        let last = match self.0[ix - 1] {\r\n            PathEl::MoveTo(p) => p,\r\n            PathEl::LineTo(p) => p,\r\n            PathEl::QuadTo(_, p2) => p2,\r\n            PathEl::CurveTo(_, _, p3) => p3,\r\n            _ => return None,\r\n        };\r\n        match self.0[ix] {\r\n            PathEl::LineTo(p) => Some(PathSeg::Line(Line::new(last, p))),\r\n            PathEl::QuadTo(p1, p2) => Some(PathSeg::Quad(QuadBez::new(last, p1, p2))),\r\n            PathEl::CurveTo(p1, p2, p3) => Some(PathSeg::Cubic(CubicBez::new(last, p1, p2, p3))),\r\n            PathEl::ClosePath => self.0[..ix].iter().rev().find_map(|el| match *el {\r\n                PathEl::MoveTo(start) if start != last => {\r\n                    Some(PathSeg::Line(Line::new(last, start)))\r\n                }\r\n                _ => None,\r\n            }),\r\n            _ => None,\r\n        }\r\n    }\r\n\r\n    /// Returns `true` if the path contains no segments.\r\n    pub fn is_empty(&self) -> bool {\r\n        self.0\r\n            .iter()\r\n            .all(|el| matches!(el, PathEl::MoveTo(..) | PathEl::ClosePath))\r\n    }\r\n\r\n    /// Apply an affine transform to the path.\r\n    pub fn apply_affine(&mut self, affine: Affine) {\r\n        for el in self.0.iter_mut() {\r\n            *el = affine * (*el);\r\n        }\r\n    }\r\n\r\n    /// Is this path finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.0.iter().all(|v| v.is_finite())\r\n    }\r\n\r\n    /// Is this path NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.0.iter().any(|v| v.is_nan())\r\n    }\r\n}\r\n\r\nimpl FromIterator<PathEl> for BezPath {\r\n    fn from_iter<T: IntoIterator<Item = PathEl>>(iter: T) -> Self {\r\n        let el_vec: Vec<_> = iter.into_iter().collect();\r\n        BezPath::from_vec(el_vec)\r\n    }\r\n}\r\n\r\n/// Allow iteration over references to `BezPath`.\r\n///\r\n/// Note: the semantics are slightly different from simply iterating over the\r\n/// slice, as it returns `PathEl` items, rather than references.\r\nimpl<'a> IntoIterator for &'a BezPath {\r\n    type Item = PathEl;\r\n    type IntoIter = core::iter::Cloned<core::slice::Iter<'a, PathEl>>;\r\n\r\n    fn into_iter(self) -> Self::IntoIter {\r\n        self.elements().iter().cloned()\r\n    }\r\n}\r\n\r\nimpl IntoIterator for BezPath {\r\n    type Item = PathEl;\r\n    type IntoIter = alloc::vec::IntoIter<PathEl>;\r\n\r\n    fn into_iter(self) -> Self::IntoIter {\r\n        self.0.into_iter()\r\n    }\r\n}\r\n\r\nimpl Extend<PathEl> for BezPath {\r\n    fn extend<I: IntoIterator<Item = PathEl>>(&mut self, iter: I) {\r\n        self.0.extend(iter);\r\n    }\r\n}\r\n\r\n/// Proportion of tolerance budget that goes to cubic to quadratic conversion.\r\nconst TO_QUAD_TOL: f64 = 0.1;\r\n\r\n/// Flatten the path, invoking the callback repeatedly.\r\n///\r\n/// See [`BezPath::flatten`] for more discussion.\r\n/// This signature is a bit more general, allowing flattening of `&[PathEl]` slices\r\n/// and other iterators yielding `PathEl`.\r\npub fn flatten(\r\n    path: impl IntoIterator<Item = PathEl>,\r\n    tolerance: f64,\r\n    mut callback: impl FnMut(PathEl),\r\n) {\r\n    let sqrt_tol = tolerance.sqrt();\r\n    let mut last_pt = None;\r\n    let mut quad_buf = Vec::new();\r\n    for el in path {\r\n        match el {\r\n            PathEl::MoveTo(p) => {\r\n                last_pt = Some(p);\r\n                callback(PathEl::MoveTo(p));\r\n            }\r\n            PathEl::LineTo(p) => {\r\n                last_pt = Some(p);\r\n                callback(PathEl::LineTo(p));\r\n            }\r\n            PathEl::QuadTo(p1, p2) => {\r\n                if let Some(p0) = last_pt {\r\n                    let q = QuadBez::new(p0, p1, p2);\r\n                    let params = q.estimate_subdiv(sqrt_tol);\r\n                    let n = ((0.5 * params.val / sqrt_tol).ceil() as usize).max(1);\r\n                    let step = 1.0 / (n as f64);\r\n                    for i in 1..n {\r\n                        let u = (i as f64) * step;\r\n                        let t = q.determine_subdiv_t(&params, u);\r\n                        let p = q.eval(t);\r\n                        callback(PathEl::LineTo(p));\r\n                    }\r\n                    callback(PathEl::LineTo(p2));\r\n                }\r\n                last_pt = Some(p2);\r\n            }\r\n            PathEl::CurveTo(p1, p2, p3) => {\r\n                if let Some(p0) = last_pt {\r\n                    let c = CubicBez::new(p0, p1, p2, p3);\r\n\r\n                    // Subdivide into quadratics, and estimate the number of\r\n                    // subdivisions required for each, summing to arrive at an\r\n                    // estimate for the number of subdivisions for the cubic.\r\n                    // Also retain these parameters for later.\r\n                    let iter = c.to_quads(tolerance * TO_QUAD_TOL);\r\n                    quad_buf.clear();\r\n                    quad_buf.reserve(iter.size_hint().0);\r\n                    let sqrt_remain_tol = sqrt_tol * (1.0 - TO_QUAD_TOL).sqrt();\r\n                    let mut sum = 0.0;\r\n                    for (_, _, q) in iter {\r\n                        let params = q.estimate_subdiv(sqrt_remain_tol);\r\n                        sum += params.val;\r\n                        quad_buf.push((q, params));\r\n                    }\r\n                    let n = ((0.5 * sum / sqrt_remain_tol).ceil() as usize).max(1);\r\n\r\n                    // Iterate through the quadratics, outputting the points of\r\n                    // subdivisions that fall within that quadratic.\r\n                    let step = sum / (n as f64);\r\n                    let mut i = 1;\r\n                    let mut val_sum = 0.0;\r\n                    for (q, params) in &quad_buf {\r\n                        let mut target = (i as f64) * step;\r\n                        let recip_val = params.val.recip();\r\n                        while target < val_sum + params.val {\r\n                            let u = (target - val_sum) * recip_val;\r\n                            let t = q.determine_subdiv_t(params, u);\r\n                            let p = q.eval(t);\r\n                            callback(PathEl::LineTo(p));\r\n                            i += 1;\r\n                            if i == n + 1 {\r\n                                break;\r\n                            }\r\n                            target = (i as f64) * step;\r\n                        }\r\n                        val_sum += params.val;\r\n                    }\r\n                    callback(PathEl::LineTo(p3));\r\n                }\r\n                last_pt = Some(p3);\r\n            }\r\n            PathEl::ClosePath => {\r\n                last_pt = None;\r\n                callback(PathEl::ClosePath);\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nimpl Mul<PathEl> for Affine {\r\n    type Output = PathEl;\r\n\r\n    fn mul(self, other: PathEl) -> PathEl {\r\n        match other {\r\n            PathEl::MoveTo(p) => PathEl::MoveTo(self * p),\r\n            PathEl::LineTo(p) => PathEl::LineTo(self * p),\r\n            PathEl::QuadTo(p1, p2) => PathEl::QuadTo(self * p1, self * p2),\r\n            PathEl::CurveTo(p1, p2, p3) => PathEl::CurveTo(self * p1, self * p2, self * p3),\r\n            PathEl::ClosePath => PathEl::ClosePath,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Mul<PathSeg> for Affine {\r\n    type Output = PathSeg;\r\n\r\n    fn mul(self, other: PathSeg) -> PathSeg {\r\n        match other {\r\n            PathSeg::Line(line) => PathSeg::Line(self * line),\r\n            PathSeg::Quad(quad) => PathSeg::Quad(self * quad),\r\n            PathSeg::Cubic(cubic) => PathSeg::Cubic(self * cubic),\r\n        }\r\n    }\r\n}\r\n\r\nimpl Mul<BezPath> for Affine {\r\n    type Output = BezPath;\r\n\r\n    fn mul(self, other: BezPath) -> BezPath {\r\n        BezPath(other.0.iter().map(|&el| self * el).collect())\r\n    }\r\n}\r\n\r\nimpl<'a> Mul<&'a BezPath> for Affine {\r\n    type Output = BezPath;\r\n\r\n    fn mul(self, other: &BezPath) -> BezPath {\r\n        BezPath(other.0.iter().map(|&el| self * el).collect())\r\n    }\r\n}\r\n\r\nimpl Mul<PathEl> for TranslateScale {\r\n    type Output = PathEl;\r\n\r\n    fn mul(self, other: PathEl) -> PathEl {\r\n        match other {\r\n            PathEl::MoveTo(p) => PathEl::MoveTo(self * p),\r\n            PathEl::LineTo(p) => PathEl::LineTo(self * p),\r\n            PathEl::QuadTo(p1, p2) => PathEl::QuadTo(self * p1, self * p2),\r\n            PathEl::CurveTo(p1, p2, p3) => PathEl::CurveTo(self * p1, self * p2, self * p3),\r\n            PathEl::ClosePath => PathEl::ClosePath,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Mul<PathSeg> for TranslateScale {\r\n    type Output = PathSeg;\r\n\r\n    fn mul(self, other: PathSeg) -> PathSeg {\r\n        match other {\r\n            PathSeg::Line(line) => PathSeg::Line(self * line),\r\n            PathSeg::Quad(quad) => PathSeg::Quad(self * quad),\r\n            PathSeg::Cubic(cubic) => PathSeg::Cubic(self * cubic),\r\n        }\r\n    }\r\n}\r\n\r\nimpl Mul<BezPath> for TranslateScale {\r\n    type Output = BezPath;\r\n\r\n    fn mul(self, other: BezPath) -> BezPath {\r\n        BezPath(other.0.iter().map(|&el| self * el).collect())\r\n    }\r\n}\r\n\r\nimpl<'a> Mul<&'a BezPath> for TranslateScale {\r\n    type Output = BezPath;\r\n\r\n    fn mul(self, other: &BezPath) -> BezPath {\r\n        BezPath(other.0.iter().map(|&el| self * el).collect())\r\n    }\r\n}\r\n\r\n/// Transform an iterator over path elements into one over path\r\n/// segments.\r\n///\r\n/// See also [`BezPath::segments`].\r\n/// This signature is a bit more general, allowing `&[PathEl]` slices\r\n/// and other iterators yielding `PathEl`.\r\npub fn segments<I>(elements: I) -> Segments<I::IntoIter>\r\nwhere\r\n    I: IntoIterator<Item = PathEl>,\r\n{\r\n    Segments {\r\n        elements: elements.into_iter(),\r\n        start_last: None,\r\n    }\r\n}\r\n\r\n/// An iterator that transforms path elements to path segments.\r\n///\r\n/// This struct is created by the [`segments`] function.\r\n#[derive(Clone)]\r\npub struct Segments<I: Iterator<Item = PathEl>> {\r\n    elements: I,\r\n    start_last: Option<(Point, Point)>,\r\n}\r\n\r\nimpl<I: Iterator<Item = PathEl>> Iterator for Segments<I> {\r\n    type Item = PathSeg;\r\n\r\n    fn next(&mut self) -> Option<PathSeg> {\r\n        for el in &mut self.elements {\r\n            // We first need to check whether this is the first\r\n            // path element we see to fill in the start position.\r\n            let (start, last) = self.start_last.get_or_insert_with(|| {\r\n                let point = match el {\r\n                    PathEl::MoveTo(p) => p,\r\n                    PathEl::LineTo(p) => p,\r\n                    PathEl::QuadTo(_, p2) => p2,\r\n                    PathEl::CurveTo(_, _, p3) => p3,\r\n                    PathEl::ClosePath => panic!(\"Can't start a segment on a ClosePath\"),\r\n                };\r\n                (point, point)\r\n            });\r\n\r\n            return Some(match el {\r\n                PathEl::MoveTo(p) => {\r\n                    *start = p;\r\n                    *last = p;\r\n                    continue;\r\n                }\r\n                PathEl::LineTo(p) => PathSeg::Line(Line::new(mem::replace(last, p), p)),\r\n                PathEl::QuadTo(p1, p2) => {\r\n                    PathSeg::Quad(QuadBez::new(mem::replace(last, p2), p1, p2))\r\n                }\r\n                PathEl::CurveTo(p1, p2, p3) => {\r\n                    PathSeg::Cubic(CubicBez::new(mem::replace(last, p3), p1, p2, p3))\r\n                }\r\n                PathEl::ClosePath => {\r\n                    if *last != *start {\r\n                        PathSeg::Line(Line::new(mem::replace(last, *start), *start))\r\n                    } else {\r\n                        continue;\r\n                    }\r\n                }\r\n            });\r\n        }\r\n\r\n        None\r\n    }\r\n}\r\n\r\nimpl<I: Iterator<Item = PathEl>> Segments<I> {\r\n    /// Here, `accuracy` specifies the accuracy for each Bézier segment. At worst,\r\n    /// the total error is `accuracy` times the number of Bézier segments.\r\n\r\n    // TODO: pub? Or is this subsumed by method of &[PathEl]?\r\n    pub(crate) fn perimeter(self, accuracy: f64) -> f64 {\r\n        self.map(|seg| seg.arclen(accuracy)).sum()\r\n    }\r\n\r\n    // Same\r\n    pub(crate) fn area(self) -> f64 {\r\n        self.map(|seg| seg.signed_area()).sum()\r\n    }\r\n\r\n    // Same\r\n    pub(crate) fn winding(self, p: Point) -> i32 {\r\n        self.map(|seg| seg.winding(p)).sum()\r\n    }\r\n\r\n    // Same\r\n    pub(crate) fn bounding_box(self) -> Rect {\r\n        let mut bbox: Option<Rect> = None;\r\n        for seg in self {\r\n            let seg_bb = ParamCurveExtrema::bounding_box(&seg);\r\n            if let Some(bb) = bbox {\r\n                bbox = Some(bb.union(seg_bb));\r\n            } else {\r\n                bbox = Some(seg_bb)\r\n            }\r\n        }\r\n        bbox.unwrap_or_default()\r\n    }\r\n}\r\n\r\nimpl ParamCurve for PathSeg {\r\n    fn eval(&self, t: f64) -> Point {\r\n        match *self {\r\n            PathSeg::Line(line) => line.eval(t),\r\n            PathSeg::Quad(quad) => quad.eval(t),\r\n            PathSeg::Cubic(cubic) => cubic.eval(t),\r\n        }\r\n    }\r\n\r\n    fn subsegment(&self, range: Range<f64>) -> PathSeg {\r\n        match *self {\r\n            PathSeg::Line(line) => PathSeg::Line(line.subsegment(range)),\r\n            PathSeg::Quad(quad) => PathSeg::Quad(quad.subsegment(range)),\r\n            PathSeg::Cubic(cubic) => PathSeg::Cubic(cubic.subsegment(range)),\r\n        }\r\n    }\r\n}\r\n\r\nimpl ParamCurveArclen for PathSeg {\r\n    fn arclen(&self, accuracy: f64) -> f64 {\r\n        match *self {\r\n            PathSeg::Line(line) => line.arclen(accuracy),\r\n            PathSeg::Quad(quad) => quad.arclen(accuracy),\r\n            PathSeg::Cubic(cubic) => cubic.arclen(accuracy),\r\n        }\r\n    }\r\n\r\n    fn inv_arclen(&self, arclen: f64, accuracy: f64) -> f64 {\r\n        match *self {\r\n            PathSeg::Line(line) => line.inv_arclen(arclen, accuracy),\r\n            PathSeg::Quad(quad) => quad.inv_arclen(arclen, accuracy),\r\n            PathSeg::Cubic(cubic) => cubic.inv_arclen(arclen, accuracy),\r\n        }\r\n    }\r\n}\r\n\r\nimpl ParamCurveArea for PathSeg {\r\n    fn signed_area(&self) -> f64 {\r\n        match *self {\r\n            PathSeg::Line(line) => line.signed_area(),\r\n            PathSeg::Quad(quad) => quad.signed_area(),\r\n            PathSeg::Cubic(cubic) => cubic.signed_area(),\r\n        }\r\n    }\r\n}\r\n\r\nimpl ParamCurveNearest for PathSeg {\r\n    fn nearest(&self, p: Point, accuracy: f64) -> Nearest {\r\n        match *self {\r\n            PathSeg::Line(line) => line.nearest(p, accuracy),\r\n            PathSeg::Quad(quad) => quad.nearest(p, accuracy),\r\n            PathSeg::Cubic(cubic) => cubic.nearest(p, accuracy),\r\n        }\r\n    }\r\n}\r\n\r\nimpl ParamCurveExtrema for PathSeg {\r\n    fn extrema(&self) -> ArrayVec<f64, MAX_EXTREMA> {\r\n        match *self {\r\n            PathSeg::Line(line) => line.extrema(),\r\n            PathSeg::Quad(quad) => quad.extrema(),\r\n            PathSeg::Cubic(cubic) => cubic.extrema(),\r\n        }\r\n    }\r\n}\r\n\r\nimpl PathSeg {\r\n    /// Get the [`PathEl`] that is equivalent to discarding the segment start point.\r\n    pub fn as_path_el(&self) -> PathEl {\r\n        match self {\r\n            PathSeg::Line(line) => PathEl::LineTo(line.p1),\r\n            PathSeg::Quad(q) => PathEl::QuadTo(q.p1, q.p2),\r\n            PathSeg::Cubic(c) => PathEl::CurveTo(c.p1, c.p2, c.p3),\r\n        }\r\n    }\r\n\r\n    /// Returns a new `PathSeg` describing the same path as `self`, but with\r\n    /// the points reversed.\r\n    pub fn reverse(&self) -> PathSeg {\r\n        match self {\r\n            PathSeg::Line(Line { p0, p1 }) => PathSeg::Line(Line::new(*p1, *p0)),\r\n            PathSeg::Quad(q) => PathSeg::Quad(QuadBez::new(q.p2, q.p1, q.p0)),\r\n            PathSeg::Cubic(c) => PathSeg::Cubic(CubicBez::new(c.p3, c.p2, c.p1, c.p0)),\r\n        }\r\n    }\r\n\r\n    /// Convert this segment to a cubic bezier.\r\n    pub fn to_cubic(&self) -> CubicBez {\r\n        match *self {\r\n            PathSeg::Line(Line { p0, p1 }) => CubicBez::new(p0, p0, p1, p1),\r\n            PathSeg::Cubic(c) => c,\r\n            PathSeg::Quad(q) => q.raise(),\r\n        }\r\n    }\r\n\r\n    // Assumes split at extrema.\r\n    fn winding_inner(&self, p: Point) -> i32 {\r\n        let start = self.start();\r\n        let end = self.end();\r\n        let sign = if end.y > start.y {\r\n            if p.y < start.y || p.y >= end.y {\r\n                return 0;\r\n            }\r\n            -1\r\n        } else if end.y < start.y {\r\n            if p.y < end.y || p.y >= start.y {\r\n                return 0;\r\n            }\r\n            1\r\n        } else {\r\n            return 0;\r\n        };\r\n        match *self {\r\n            PathSeg::Line(_line) => {\r\n                if p.x < start.x.min(end.x) {\r\n                    return 0;\r\n                }\r\n                if p.x >= start.x.max(end.x) {\r\n                    return sign;\r\n                }\r\n                // line equation ax + by = c\r\n                let a = end.y - start.y;\r\n                let b = start.x - end.x;\r\n                let c = a * start.x + b * start.y;\r\n                if (a * p.x + b * p.y - c) * (sign as f64) <= 0.0 {\r\n                    sign\r\n                } else {\r\n                    0\r\n                }\r\n            }\r\n            PathSeg::Quad(quad) => {\r\n                let p1 = quad.p1;\r\n                if p.x < start.x.min(end.x).min(p1.x) {\r\n                    return 0;\r\n                }\r\n                if p.x >= start.x.max(end.x).max(p1.x) {\r\n                    return sign;\r\n                }\r\n                let a = end.y - 2.0 * p1.y + start.y;\r\n                let b = 2.0 * (p1.y - start.y);\r\n                let c = start.y - p.y;\r\n                for t in solve_quadratic(c, b, a) {\r\n                    if (0.0..=1.0).contains(&t) {\r\n                        let x = quad.eval(t).x;\r\n                        if p.x >= x {\r\n                            return sign;\r\n                        } else {\r\n                            return 0;\r\n                        }\r\n                    }\r\n                }\r\n                0\r\n            }\r\n            PathSeg::Cubic(cubic) => {\r\n                let p1 = cubic.p1;\r\n                let p2 = cubic.p2;\r\n                if p.x < start.x.min(end.x).min(p1.x).min(p2.x) {\r\n                    return 0;\r\n                }\r\n                if p.x >= start.x.max(end.x).max(p1.x).max(p2.x) {\r\n                    return sign;\r\n                }\r\n                let a = end.y - 3.0 * p2.y + 3.0 * p1.y - start.y;\r\n                let b = 3.0 * (p2.y - 2.0 * p1.y + start.y);\r\n                let c = 3.0 * (p1.y - start.y);\r\n                let d = start.y - p.y;\r\n                for t in solve_cubic(d, c, b, a) {\r\n                    if (0.0..=1.0).contains(&t) {\r\n                        let x = cubic.eval(t).x;\r\n                        if p.x >= x {\r\n                            return sign;\r\n                        } else {\r\n                            return 0;\r\n                        }\r\n                    }\r\n                }\r\n                0\r\n            }\r\n        }\r\n    }\r\n\r\n    /// Compute the winding number contribution of a single segment.\r\n    ///\r\n    /// Cast a ray to the left and count intersections.\r\n    fn winding(&self, p: Point) -> i32 {\r\n        self.extrema_ranges()\r\n            .into_iter()\r\n            .map(|range| self.subsegment(range).winding_inner(p))\r\n            .sum()\r\n    }\r\n\r\n    /// Compute intersections against a line.\r\n    ///\r\n    /// Returns a vector of the intersections. For each intersection,\r\n    /// the `t` value of the segment and line are given.\r\n    ///\r\n    /// Note: This test is designed to be inclusive of points near the endpoints\r\n    /// of the segment. This is so that testing a line against multiple\r\n    /// contiguous segments of a path will be guaranteed to catch at least one\r\n    /// of them. In such cases, use higher level logic to coalesce the hits\r\n    /// (the `t` value may be slightly outside the range of 0..1).\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// # use kurbo::*;\r\n    /// let seg = PathSeg::Line(Line::new((0.0, 0.0), (2.0, 0.0)));\r\n    /// let line = Line::new((1.0, 2.0), (1.0, -2.0));\r\n    /// let intersection = seg.intersect_line(line);\r\n    /// assert_eq!(intersection.len(), 1);\r\n    /// let intersection = intersection[0];\r\n    /// assert_eq!(intersection.segment_t, 0.5);\r\n    /// assert_eq!(intersection.line_t, 0.5);\r\n    ///\r\n    /// let point = seg.eval(intersection.segment_t);\r\n    /// assert_eq!(point, Point::new(1.0, 0.0));\r\n    /// ```\r\n    pub fn intersect_line(&self, line: Line) -> ArrayVec<LineIntersection, 3> {\r\n        const EPSILON: f64 = 1e-9;\r\n        let p0 = line.p0;\r\n        let p1 = line.p1;\r\n        let dx = p1.x - p0.x;\r\n        let dy = p1.y - p0.y;\r\n        let mut result = ArrayVec::new();\r\n        match self {\r\n            PathSeg::Line(l) => {\r\n                let det = dx * (l.p1.y - l.p0.y) - dy * (l.p1.x - l.p0.x);\r\n                if det.abs() < EPSILON {\r\n                    // Lines are coincident (or nearly so).\r\n                    return result;\r\n                }\r\n                let t = dx * (p0.y - l.p0.y) - dy * (p0.x - l.p0.x);\r\n                // t = position on self\r\n                let t = t / det;\r\n                if (-EPSILON..=(1.0 + EPSILON)).contains(&t) {\r\n                    // u = position on probe line\r\n                    let u =\r\n                        (l.p0.x - p0.x) * (l.p1.y - l.p0.y) - (l.p0.y - p0.y) * (l.p1.x - l.p0.x);\r\n                    let u = u / det;\r\n                    if (0.0..=1.0).contains(&u) {\r\n                        result.push(LineIntersection::new(u, t));\r\n                    }\r\n                }\r\n            }\r\n            PathSeg::Quad(q) => {\r\n                // The basic technique here is to determine x and y as a quadratic polynomial\r\n                // as a function of t. Then plug those values into the line equation for the\r\n                // probe line (giving a sort of signed distance from the probe line) and solve\r\n                // that for t.\r\n                let (px0, px1, px2) = quadratic_bez_coefs(q.p0.x, q.p1.x, q.p2.x);\r\n                let (py0, py1, py2) = quadratic_bez_coefs(q.p0.y, q.p1.y, q.p2.y);\r\n                let c0 = dy * (px0 - p0.x) - dx * (py0 - p0.y);\r\n                let c1 = dy * px1 - dx * py1;\r\n                let c2 = dy * px2 - dx * py2;\r\n                let invlen2 = (dx * dx + dy * dy).recip();\r\n                for t in crate::common::solve_quadratic(c0, c1, c2) {\r\n                    if (-EPSILON..=(1.0 + EPSILON)).contains(&t) {\r\n                        let x = px0 + t * px1 + t * t * px2;\r\n                        let y = py0 + t * py1 + t * t * py2;\r\n                        let u = ((x - p0.x) * dx + (y - p0.y) * dy) * invlen2;\r\n                        if (0.0..=1.0).contains(&u) {\r\n                            result.push(LineIntersection::new(u, t));\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            PathSeg::Cubic(c) => {\r\n                // Same technique as above, but cubic polynomial.\r\n                let (px0, px1, px2, px3) = cubic_bez_coefs(c.p0.x, c.p1.x, c.p2.x, c.p3.x);\r\n                let (py0, py1, py2, py3) = cubic_bez_coefs(c.p0.y, c.p1.y, c.p2.y, c.p3.y);\r\n                let c0 = dy * (px0 - p0.x) - dx * (py0 - p0.y);\r\n                let c1 = dy * px1 - dx * py1;\r\n                let c2 = dy * px2 - dx * py2;\r\n                let c3 = dy * px3 - dx * py3;\r\n                let invlen2 = (dx * dx + dy * dy).recip();\r\n                for t in crate::common::solve_cubic(c0, c1, c2, c3) {\r\n                    if (-EPSILON..=(1.0 + EPSILON)).contains(&t) {\r\n                        let x = px0 + t * px1 + t * t * px2 + t * t * t * px3;\r\n                        let y = py0 + t * py1 + t * t * py2 + t * t * t * py3;\r\n                        let u = ((x - p0.x) * dx + (y - p0.y) * dy) * invlen2;\r\n                        if (0.0..=1.0).contains(&u) {\r\n                            result.push(LineIntersection::new(u, t));\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        result\r\n    }\r\n\r\n    /// Is this Bezier path finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        match self {\r\n            PathSeg::Line(line) => line.is_finite(),\r\n            PathSeg::Quad(quad_bez) => quad_bez.is_finite(),\r\n            PathSeg::Cubic(cubic_bez) => cubic_bez.is_finite(),\r\n        }\r\n    }\r\n\r\n    /// Is this Bezier path NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        match self {\r\n            PathSeg::Line(line) => line.is_nan(),\r\n            PathSeg::Quad(quad_bez) => quad_bez.is_nan(),\r\n            PathSeg::Cubic(cubic_bez) => cubic_bez.is_nan(),\r\n        }\r\n    }\r\n\r\n    #[inline]\r\n    fn as_vec2_vec(&self) -> ArrayVec<Vec2, 4> {\r\n        let mut a = ArrayVec::new();\r\n        match self {\r\n            PathSeg::Line(l) => {\r\n                a.push(l.p0.to_vec2());\r\n                a.push(l.p1.to_vec2());\r\n            }\r\n            PathSeg::Quad(q) => {\r\n                a.push(q.p0.to_vec2());\r\n                a.push(q.p1.to_vec2());\r\n                a.push(q.p2.to_vec2());\r\n            }\r\n            PathSeg::Cubic(c) => {\r\n                a.push(c.p0.to_vec2());\r\n                a.push(c.p1.to_vec2());\r\n                a.push(c.p2.to_vec2());\r\n                a.push(c.p3.to_vec2());\r\n            }\r\n        };\r\n        a\r\n    }\r\n\r\n    /// Minimum distance between two PathSegs\r\n    ///\r\n    /// Returns a tuple of the distance, the path time `t1` of the closest point\r\n    /// on the first PathSeg, and the path time `t2` of the closest point on the\r\n    /// second PathSeg.\r\n    pub fn min_dist(&self, other: PathSeg, accuracy: f64) -> MinDistance {\r\n        let (distance, t1, t2) = crate::mindist::min_dist_param(\r\n            &self.as_vec2_vec(),\r\n            &other.as_vec2_vec(),\r\n            (0.0, 1.0),\r\n            (0.0, 1.0),\r\n            accuracy,\r\n            None,\r\n        );\r\n        MinDistance {\r\n            distance: distance.sqrt(),\r\n            t1,\r\n            t2,\r\n        }\r\n    }\r\n\r\n    /// Compute endpoint tangents of a path segment.\r\n    ///\r\n    /// This version is robust to the path segment not being a regular curve.\r\n    pub(crate) fn tangents(&self) -> (Vec2, Vec2) {\r\n        const EPS: f64 = 1e-12;\r\n        match self {\r\n            PathSeg::Line(l) => {\r\n                let d = l.p1 - l.p0;\r\n                (d, d)\r\n            }\r\n            PathSeg::Quad(q) => {\r\n                let d01 = q.p1 - q.p0;\r\n                let d0 = if d01.hypot2() > EPS { d01 } else { q.p2 - q.p0 };\r\n                let d12 = q.p2 - q.p1;\r\n                let d1 = if d12.hypot2() > EPS { d12 } else { q.p2 - q.p0 };\r\n                (d0, d1)\r\n            }\r\n            PathSeg::Cubic(c) => {\r\n                let d01 = c.p1 - c.p0;\r\n                let d0 = if d01.hypot2() > EPS {\r\n                    d01\r\n                } else {\r\n                    let d02 = c.p2 - c.p0;\r\n                    if d02.hypot2() > EPS {\r\n                        d02\r\n                    } else {\r\n                        c.p3 - c.p0\r\n                    }\r\n                };\r\n                let d23 = c.p3 - c.p2;\r\n                let d1 = if d23.hypot2() > EPS {\r\n                    d23\r\n                } else {\r\n                    let d13 = c.p3 - c.p1;\r\n                    if d13.hypot2() > EPS {\r\n                        d13\r\n                    } else {\r\n                        c.p3 - c.p0\r\n                    }\r\n                };\r\n                (d0, d1)\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nimpl LineIntersection {\r\n    fn new(line_t: f64, segment_t: f64) -> Self {\r\n        LineIntersection { line_t, segment_t }\r\n    }\r\n\r\n    /// Is this line intersection finite?\r\n    #[inline]\r\n    pub fn is_finite(self) -> bool {\r\n        self.line_t.is_finite() && self.segment_t.is_finite()\r\n    }\r\n\r\n    /// Is this line intersection NaN?\r\n    #[inline]\r\n    pub fn is_nan(self) -> bool {\r\n        self.line_t.is_nan() || self.segment_t.is_nan()\r\n    }\r\n}\r\n\r\n// Return polynomial coefficients given cubic bezier coordinates.\r\nfn quadratic_bez_coefs(x0: f64, x1: f64, x2: f64) -> (f64, f64, f64) {\r\n    let p0 = x0;\r\n    let p1 = 2.0 * x1 - 2.0 * x0;\r\n    let p2 = x2 - 2.0 * x1 + x0;\r\n    (p0, p1, p2)\r\n}\r\n\r\n// Return polynomial coefficients given cubic bezier coordinates.\r\nfn cubic_bez_coefs(x0: f64, x1: f64, x2: f64, x3: f64) -> (f64, f64, f64, f64) {\r\n    let p0 = x0;\r\n    let p1 = 3.0 * x1 - 3.0 * x0;\r\n    let p2 = 3.0 * x2 - 6.0 * x1 + 3.0 * x0;\r\n    let p3 = x3 - 3.0 * x2 + 3.0 * x1 - x0;\r\n    (p0, p1, p2, p3)\r\n}\r\n\r\nimpl From<CubicBez> for PathSeg {\r\n    fn from(cubic_bez: CubicBez) -> PathSeg {\r\n        PathSeg::Cubic(cubic_bez)\r\n    }\r\n}\r\n\r\nimpl From<Line> for PathSeg {\r\n    fn from(line: Line) -> PathSeg {\r\n        PathSeg::Line(line)\r\n    }\r\n}\r\n\r\nimpl From<QuadBez> for PathSeg {\r\n    fn from(quad_bez: QuadBez) -> PathSeg {\r\n        PathSeg::Quad(quad_bez)\r\n    }\r\n}\r\n\r\nimpl Shape for BezPath {\r\n    type PathElementsIter<'iter> = core::iter::Copied<core::slice::Iter<'iter, PathEl>>;\r\n\r\n    fn path_elements(&self, _tolerance: f64) -> Self::PathElementsIter<'_> {\r\n        self.0.iter().copied()\r\n    }\r\n\r\n    fn to_path(&self, _tolerance: f64) -> BezPath {\r\n        self.clone()\r\n    }\r\n\r\n    fn into_path(self, _tolerance: f64) -> BezPath {\r\n        self\r\n    }\r\n\r\n    /// Signed area.\r\n    fn area(&self) -> f64 {\r\n        self.elements().area()\r\n    }\r\n\r\n    fn perimeter(&self, accuracy: f64) -> f64 {\r\n        self.elements().perimeter(accuracy)\r\n    }\r\n\r\n    /// Winding number of point.\r\n    fn winding(&self, pt: Point) -> i32 {\r\n        self.elements().winding(pt)\r\n    }\r\n\r\n    fn bounding_box(&self) -> Rect {\r\n        self.elements().bounding_box()\r\n    }\r\n\r\n    fn as_path_slice(&self) -> Option<&[PathEl]> {\r\n        Some(&self.0)\r\n    }\r\n}\r\n\r\nimpl PathEl {\r\n    /// Is this path element finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        match self {\r\n            PathEl::MoveTo(p) => p.is_finite(),\r\n            PathEl::LineTo(p) => p.is_finite(),\r\n            PathEl::QuadTo(p, p2) => p.is_finite() && p2.is_finite(),\r\n            PathEl::CurveTo(p, p2, p3) => p.is_finite() && p2.is_finite() && p3.is_finite(),\r\n            PathEl::ClosePath => true,\r\n        }\r\n    }\r\n\r\n    /// Is this path element NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        match self {\r\n            PathEl::MoveTo(p) => p.is_nan(),\r\n            PathEl::LineTo(p) => p.is_nan(),\r\n            PathEl::QuadTo(p, p2) => p.is_nan() || p2.is_nan(),\r\n            PathEl::CurveTo(p, p2, p3) => p.is_nan() || p2.is_nan() || p3.is_nan(),\r\n            PathEl::ClosePath => false,\r\n        }\r\n    }\r\n}\r\n\r\n/// Implements [`Shape`] for a slice of [`PathEl`], provided that the first element of the slice is\r\n/// not a `PathEl::ClosePath`. If it is, several of these functions will panic.\r\n///\r\n/// If the slice starts with `LineTo`, `QuadTo`, or `CurveTo`, it will be treated as a `MoveTo`.\r\nimpl<'a> Shape for &'a [PathEl] {\r\n    type PathElementsIter<'iter>\r\n\r\n    = core::iter::Copied<core::slice::Iter<'a, PathEl>> where 'a: 'iter;\r\n\r\n    #[inline]\r\n    fn path_elements(&self, _tolerance: f64) -> Self::PathElementsIter<'_> {\r\n        self.iter().copied()\r\n    }\r\n\r\n    fn to_path(&self, _tolerance: f64) -> BezPath {\r\n        BezPath::from_vec(self.to_vec())\r\n    }\r\n\r\n    /// Signed area.\r\n    fn area(&self) -> f64 {\r\n        segments(self.iter().copied()).area()\r\n    }\r\n\r\n    fn perimeter(&self, accuracy: f64) -> f64 {\r\n        segments(self.iter().copied()).perimeter(accuracy)\r\n    }\r\n\r\n    /// Winding number of point.\r\n    fn winding(&self, pt: Point) -> i32 {\r\n        segments(self.iter().copied()).winding(pt)\r\n    }\r\n\r\n    fn bounding_box(&self) -> Rect {\r\n        segments(self.iter().copied()).bounding_box()\r\n    }\r\n\r\n    #[inline]\r\n    fn as_path_slice(&self) -> Option<&[PathEl]> {\r\n        Some(self)\r\n    }\r\n}\r\n\r\n/// Implements [`Shape`] for an array of [`PathEl`], provided that the first element of the array is\r\n/// not a `PathEl::ClosePath`. If it is, several of these functions will panic.\r\n///\r\n/// If the array starts with `LineTo`, `QuadTo`, or `CurveTo`, it will be treated as a `MoveTo`.\r\nimpl<const N: usize> Shape for [PathEl; N] {\r\n    type PathElementsIter<'iter> = core::iter::Copied<core::slice::Iter<'iter, PathEl>>;\r\n\r\n    #[inline]\r\n    fn path_elements(&self, _tolerance: f64) -> Self::PathElementsIter<'_> {\r\n        self.iter().copied()\r\n    }\r\n\r\n    fn to_path(&self, _tolerance: f64) -> BezPath {\r\n        BezPath::from_vec(self.to_vec())\r\n    }\r\n\r\n    /// Signed area.\r\n    fn area(&self) -> f64 {\r\n        segments(self.iter().copied()).area()\r\n    }\r\n\r\n    fn perimeter(&self, accuracy: f64) -> f64 {\r\n        segments(self.iter().copied()).perimeter(accuracy)\r\n    }\r\n\r\n    /// Winding number of point.\r\n    fn winding(&self, pt: Point) -> i32 {\r\n        segments(self.iter().copied()).winding(pt)\r\n    }\r\n\r\n    fn bounding_box(&self) -> Rect {\r\n        segments(self.iter().copied()).bounding_box()\r\n    }\r\n\r\n    #[inline]\r\n    fn as_path_slice(&self) -> Option<&[PathEl]> {\r\n        Some(self)\r\n    }\r\n}\r\n\r\n/// An iterator for path segments.\r\npub struct PathSegIter {\r\n    seg: PathSeg,\r\n    ix: usize,\r\n}\r\n\r\nimpl Shape for PathSeg {\r\n    type PathElementsIter<'iter> = PathSegIter;\r\n\r\n    #[inline]\r\n    fn path_elements(&self, _tolerance: f64) -> PathSegIter {\r\n        PathSegIter { seg: *self, ix: 0 }\r\n    }\r\n\r\n    /// The area under the curve.\r\n    ///\r\n    /// We could just return 0, but this seems more useful.\r\n    fn area(&self) -> f64 {\r\n        self.signed_area()\r\n    }\r\n\r\n    #[inline]\r\n    fn perimeter(&self, accuracy: f64) -> f64 {\r\n        self.arclen(accuracy)\r\n    }\r\n\r\n    fn winding(&self, _pt: Point) -> i32 {\r\n        0\r\n    }\r\n\r\n    #[inline]\r\n    fn bounding_box(&self) -> Rect {\r\n        ParamCurveExtrema::bounding_box(self)\r\n    }\r\n\r\n    fn as_line(&self) -> Option<Line> {\r\n        if let PathSeg::Line(line) = self {\r\n            Some(*line)\r\n        } else {\r\n            None\r\n        }\r\n    }\r\n}\r\n\r\nimpl Iterator for PathSegIter {\r\n    type Item = PathEl;\r\n\r\n    fn next(&mut self) -> Option<PathEl> {\r\n        self.ix += 1;\r\n        match (self.ix, self.seg) {\r\n            // yes I could do some fancy bindings thing here but... :shrug:\r\n            (1, PathSeg::Line(seg)) => Some(PathEl::MoveTo(seg.p0)),\r\n            (1, PathSeg::Quad(seg)) => Some(PathEl::MoveTo(seg.p0)),\r\n            (1, PathSeg::Cubic(seg)) => Some(PathEl::MoveTo(seg.p0)),\r\n            (2, PathSeg::Line(seg)) => Some(PathEl::LineTo(seg.p1)),\r\n            (2, PathSeg::Quad(seg)) => Some(PathEl::QuadTo(seg.p1, seg.p2)),\r\n            (2, PathSeg::Cubic(seg)) => Some(PathEl::CurveTo(seg.p1, seg.p2, seg.p3)),\r\n            _ => None,\r\n        }\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{Circle, DEFAULT_ACCURACY};\r\n\r\n    use super::*;\r\n\r\n    fn assert_approx_eq(x: f64, y: f64) {\r\n        assert!((x - y).abs() < 1e-8, \"{x} != {y}\");\r\n    }\r\n\r\n    #[test]\r\n    #[should_panic(expected = \"no open subpath\")]\r\n    fn test_elements_to_segments_starts_on_closepath() {\r\n        let mut path = BezPath::new();\r\n        path.close_path();\r\n        path.segments().next();\r\n    }\r\n\r\n    #[test]\r\n    fn test_elements_to_segments_closepath_refers_to_last_moveto() {\r\n        let mut path = BezPath::new();\r\n        path.move_to((5.0, 5.0));\r\n        path.line_to((15.0, 15.0));\r\n        path.move_to((10.0, 10.0));\r\n        path.line_to((15.0, 15.0));\r\n        path.close_path();\r\n        assert_eq!(\r\n            path.segments().collect::<Vec<_>>().last(),\r\n            Some(&Line::new((15.0, 15.0), (10.0, 10.0)).into()),\r\n        );\r\n    }\r\n\r\n    #[test]\r\n    #[should_panic(expected = \"no open subpath\")]\r\n    fn test_must_not_start_on_quad() {\r\n        let mut path = BezPath::new();\r\n        path.quad_to((5.0, 5.0), (10.0, 10.0));\r\n        path.line_to((15.0, 15.0));\r\n        path.close_path();\r\n    }\r\n\r\n    #[test]\r\n    fn test_intersect_line() {\r\n        let h_line = Line::new((0.0, 0.0), (100.0, 0.0));\r\n        let v_line = Line::new((10.0, -10.0), (10.0, 10.0));\r\n        let intersection = PathSeg::Line(h_line).intersect_line(v_line)[0];\r\n        assert_approx_eq(intersection.segment_t, 0.1);\r\n        assert_approx_eq(intersection.line_t, 0.5);\r\n\r\n        let v_line = Line::new((-10.0, -10.0), (-10.0, 10.0));\r\n        assert!(PathSeg::Line(h_line).intersect_line(v_line).is_empty());\r\n\r\n        let v_line = Line::new((10.0, 10.0), (10.0, 20.0));\r\n        assert!(PathSeg::Line(h_line).intersect_line(v_line).is_empty());\r\n    }\r\n\r\n    #[test]\r\n    fn test_intersect_qad() {\r\n        let q = QuadBez::new((0.0, -10.0), (10.0, 20.0), (20.0, -10.0));\r\n        let v_line = Line::new((10.0, -10.0), (10.0, 10.0));\r\n        assert_eq!(PathSeg::Quad(q).intersect_line(v_line).len(), 1);\r\n        let intersection = PathSeg::Quad(q).intersect_line(v_line)[0];\r\n        assert_approx_eq(intersection.segment_t, 0.5);\r\n        assert_approx_eq(intersection.line_t, 0.75);\r\n\r\n        let h_line = Line::new((0.0, 0.0), (100.0, 0.0));\r\n        assert_eq!(PathSeg::Quad(q).intersect_line(h_line).len(), 2);\r\n    }\r\n\r\n    #[test]\r\n    fn test_intersect_cubic() {\r\n        let c = CubicBez::new((0.0, -10.0), (10.0, 20.0), (20.0, -20.0), (30.0, 10.0));\r\n        let v_line = Line::new((10.0, -10.0), (10.0, 10.0));\r\n        assert_eq!(PathSeg::Cubic(c).intersect_line(v_line).len(), 1);\r\n        let intersection = PathSeg::Cubic(c).intersect_line(v_line)[0];\r\n        assert_approx_eq(intersection.segment_t, 0.333333333);\r\n        assert_approx_eq(intersection.line_t, 0.592592592);\r\n\r\n        let h_line = Line::new((0.0, 0.0), (100.0, 0.0));\r\n        assert_eq!(PathSeg::Cubic(c).intersect_line(h_line).len(), 3);\r\n    }\r\n\r\n    #[test]\r\n    fn test_contains() {\r\n        let mut path = BezPath::new();\r\n        path.move_to((0.0, 0.0));\r\n        path.line_to((1.0, 1.0));\r\n        path.line_to((2.0, 0.0));\r\n        path.close_path();\r\n        assert_eq!(path.winding(Point::new(1.0, 0.5)), -1);\r\n        assert!(path.contains(Point::new(1.0, 0.5)));\r\n    }\r\n\r\n    // get_seg(i) should produce the same results as path_segments().nth(i - 1).\r\n    #[test]\r\n    fn test_get_seg() {\r\n        let circle = Circle::new((10.0, 10.0), 2.0).to_path(DEFAULT_ACCURACY);\r\n        let segments = circle.path_segments(DEFAULT_ACCURACY).collect::<Vec<_>>();\r\n        let get_segs = (1..usize::MAX)\r\n            .map_while(|i| circle.get_seg(i))\r\n            .collect::<Vec<_>>();\r\n        assert_eq!(segments, get_segs);\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/circle.rs",
      "sha256": "9903550ae098c18380e1e4c34f3b3782ac1ba671a69e59b9331287ad1ab06d92",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Implementation of circle shape.\r\n\r\nuse core::{\r\n    f64::consts::{FRAC_PI_2, PI},\r\n    iter,\r\n    ops::{Add, Mul, Sub},\r\n};\r\n\r\nuse crate::{Affine, Arc, ArcAppendIter, Ellipse, PathEl, Point, Rect, Shape, Vec2};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A circle.\r\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct Circle {\r\n    /// The center.\r\n    pub center: Point,\r\n    /// The radius.\r\n    pub radius: f64,\r\n}\r\n\r\nimpl Circle {\r\n    /// A new circle from center and radius.\r\n    #[inline]\r\n    pub fn new(center: impl Into<Point>, radius: f64) -> Circle {\r\n        Circle {\r\n            center: center.into(),\r\n            radius,\r\n        }\r\n    }\r\n\r\n    /// Create a [`CircleSegment`] by cutting out parts of this circle.\r\n    pub fn segment(self, inner_radius: f64, start_angle: f64, sweep_angle: f64) -> CircleSegment {\r\n        CircleSegment {\r\n            center: self.center,\r\n            outer_radius: self.radius,\r\n            inner_radius,\r\n            start_angle,\r\n            sweep_angle,\r\n        }\r\n    }\r\n\r\n    /// Is this circle finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.center.is_finite() && self.radius.is_finite()\r\n    }\r\n\r\n    /// Is this circle NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.center.is_nan() || self.radius.is_nan()\r\n    }\r\n}\r\n\r\nimpl Add<Vec2> for Circle {\r\n    type Output = Circle;\r\n\r\n    #[inline]\r\n    fn add(self, v: Vec2) -> Circle {\r\n        Circle {\r\n            center: self.center + v,\r\n            radius: self.radius,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Sub<Vec2> for Circle {\r\n    type Output = Circle;\r\n\r\n    #[inline]\r\n    fn sub(self, v: Vec2) -> Circle {\r\n        Circle {\r\n            center: self.center - v,\r\n            radius: self.radius,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Mul<Circle> for Affine {\r\n    type Output = Ellipse;\r\n    fn mul(self, other: Circle) -> Self::Output {\r\n        self * Ellipse::from(other)\r\n    }\r\n}\r\n\r\n#[doc(hidden)]\r\npub struct CirclePathIter {\r\n    circle: Circle,\r\n    delta_th: f64,\r\n    arm_len: f64,\r\n    ix: usize,\r\n    n: usize,\r\n}\r\n\r\nimpl Shape for Circle {\r\n    type PathElementsIter<'iter> = CirclePathIter;\r\n\r\n    fn path_elements(&self, tolerance: f64) -> CirclePathIter {\r\n        let scaled_err = self.radius.abs() / tolerance;\r\n        let (n, arm_len) = if scaled_err < 1.0 / 1.9608e-4 {\r\n            // Solution from http://spencermortensen.com/articles/bezier-circle/\r\n            (4, 0.551915024494)\r\n        } else {\r\n            // This is empirically determined to fall within error tolerance.\r\n            let n = (1.1163 * scaled_err).powf(1.0 / 6.0).ceil() as usize;\r\n            // Note: this isn't minimum error, but it is simple and we can easily\r\n            // estimate the error.\r\n            let arm_len = (4.0 / 3.0) * (FRAC_PI_2 / (n as f64)).tan();\r\n            (n, arm_len)\r\n        };\r\n        CirclePathIter {\r\n            circle: *self,\r\n            delta_th: 2.0 * PI / (n as f64),\r\n            arm_len,\r\n            ix: 0,\r\n            n,\r\n        }\r\n    }\r\n\r\n    #[inline]\r\n    fn area(&self) -> f64 {\r\n        PI * self.radius.powi(2)\r\n    }\r\n\r\n    #[inline]\r\n    fn perimeter(&self, _accuracy: f64) -> f64 {\r\n        (2.0 * PI * self.radius).abs()\r\n    }\r\n\r\n    fn winding(&self, pt: Point) -> i32 {\r\n        if (pt - self.center).hypot2() < self.radius.powi(2) {\r\n            1\r\n        } else {\r\n            0\r\n        }\r\n    }\r\n\r\n    #[inline]\r\n    fn bounding_box(&self) -> Rect {\r\n        let r = self.radius.abs();\r\n        let (x, y) = self.center.into();\r\n        Rect::new(x - r, y - r, x + r, y + r)\r\n    }\r\n\r\n    fn as_circle(&self) -> Option<Circle> {\r\n        Some(*self)\r\n    }\r\n}\r\n\r\nimpl Iterator for CirclePathIter {\r\n    type Item = PathEl;\r\n\r\n    fn next(&mut self) -> Option<PathEl> {\r\n        let a = self.arm_len;\r\n        let r = self.circle.radius;\r\n        let (x, y) = self.circle.center.into();\r\n        let ix = self.ix;\r\n        self.ix += 1;\r\n        if ix == 0 {\r\n            Some(PathEl::MoveTo(Point::new(x + r, y)))\r\n        } else if ix <= self.n {\r\n            let th1 = self.delta_th * (ix as f64);\r\n            let th0 = th1 - self.delta_th;\r\n            let (s0, c0) = th0.sin_cos();\r\n            let (s1, c1) = if ix == self.n {\r\n                (0.0, 1.0)\r\n            } else {\r\n                th1.sin_cos()\r\n            };\r\n            Some(PathEl::CurveTo(\r\n                Point::new(x + r * (c0 - a * s0), y + r * (s0 + a * c0)),\r\n                Point::new(x + r * (c1 + a * s1), y + r * (s1 - a * c1)),\r\n                Point::new(x + r * c1, y + r * s1),\r\n            ))\r\n        } else if ix == self.n + 1 {\r\n            Some(PathEl::ClosePath)\r\n        } else {\r\n            None\r\n        }\r\n    }\r\n}\r\n\r\n/// A segment of a circle.\r\n///\r\n/// If `inner_radius > 0`, then the shape will be a doughnut segment.\r\npub struct CircleSegment {\r\n    /// The center.\r\n    pub center: Point,\r\n    /// The outer radius.\r\n    pub outer_radius: f64,\r\n    /// The inner radius.\r\n    pub inner_radius: f64,\r\n    /// The angle to start drawing the segment (in radians).\r\n    pub start_angle: f64,\r\n    /// The arc length of the segment (in radians).\r\n    pub sweep_angle: f64,\r\n}\r\n\r\nimpl CircleSegment {\r\n    /// Create a `CircleSegment` out of its constituent parts.\r\n    pub fn new(\r\n        center: impl Into<Point>,\r\n        outer_radius: f64,\r\n        inner_radius: f64,\r\n        start_angle: f64,\r\n        sweep_angle: f64,\r\n    ) -> Self {\r\n        CircleSegment {\r\n            center: center.into(),\r\n            outer_radius,\r\n            inner_radius,\r\n            start_angle,\r\n            sweep_angle,\r\n        }\r\n    }\r\n\r\n    /// Is this circle segment finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.center.is_finite()\r\n            && self.outer_radius.is_finite()\r\n            && self.inner_radius.is_finite()\r\n            && self.start_angle.is_finite()\r\n            && self.sweep_angle.is_finite()\r\n    }\r\n\r\n    /// Is this circle segment NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.center.is_nan()\r\n            || self.outer_radius.is_nan()\r\n            || self.inner_radius.is_nan()\r\n            || self.start_angle.is_nan()\r\n            || self.sweep_angle.is_nan()\r\n    }\r\n}\r\n\r\nimpl Add<Vec2> for CircleSegment {\r\n    type Output = CircleSegment;\r\n\r\n    #[inline]\r\n    fn add(self, v: Vec2) -> Self {\r\n        Self {\r\n            center: self.center + v,\r\n            ..self\r\n        }\r\n    }\r\n}\r\n\r\nimpl Sub<Vec2> for CircleSegment {\r\n    type Output = CircleSegment;\r\n\r\n    #[inline]\r\n    fn sub(self, v: Vec2) -> Self {\r\n        Self {\r\n            center: self.center - v,\r\n            ..self\r\n        }\r\n    }\r\n}\r\n\r\ntype CircleSegmentPathIter = iter::Chain<\r\n    iter::Chain<\r\n        iter::Chain<iter::Chain<iter::Once<PathEl>, iter::Once<PathEl>>, ArcAppendIter>,\r\n        iter::Once<PathEl>,\r\n    >,\r\n    ArcAppendIter,\r\n>;\r\n\r\nimpl Shape for CircleSegment {\r\n    type PathElementsIter<'iter> = CircleSegmentPathIter;\r\n\r\n    fn path_elements(&self, tolerance: f64) -> CircleSegmentPathIter {\r\n        iter::once(PathEl::MoveTo(point_on_circle(\r\n            self.center,\r\n            self.inner_radius,\r\n            self.start_angle,\r\n        )))\r\n        // First radius\r\n        .chain(iter::once(PathEl::LineTo(point_on_circle(\r\n            self.center,\r\n            self.outer_radius,\r\n            self.start_angle,\r\n        ))))\r\n        // outer arc\r\n        .chain(\r\n            Arc {\r\n                center: self.center,\r\n                radii: Vec2::new(self.outer_radius, self.outer_radius),\r\n                start_angle: self.start_angle,\r\n                sweep_angle: self.sweep_angle,\r\n                x_rotation: 0.0,\r\n            }\r\n            .append_iter(tolerance),\r\n        )\r\n        // second radius\r\n        .chain(iter::once(PathEl::LineTo(point_on_circle(\r\n            self.center,\r\n            self.inner_radius,\r\n            self.start_angle + self.sweep_angle,\r\n        ))))\r\n        // inner arc\r\n        .chain(\r\n            Arc {\r\n                center: self.center,\r\n                radii: Vec2::new(self.inner_radius, self.inner_radius),\r\n                start_angle: self.start_angle + self.sweep_angle,\r\n                sweep_angle: -self.sweep_angle,\r\n                x_rotation: 0.0,\r\n            }\r\n            .append_iter(tolerance),\r\n        )\r\n    }\r\n\r\n    #[inline]\r\n    fn area(&self) -> f64 {\r\n        0.5 * (self.outer_radius.powi(2) - self.inner_radius.powi(2)).abs() * self.sweep_angle\r\n    }\r\n\r\n    #[inline]\r\n    fn perimeter(&self, _accuracy: f64) -> f64 {\r\n        2.0 * (self.outer_radius - self.inner_radius).abs()\r\n            + self.sweep_angle * (self.inner_radius + self.outer_radius)\r\n    }\r\n\r\n    fn winding(&self, pt: Point) -> i32 {\r\n        let angle = (pt - self.center).atan2();\r\n        if angle < self.start_angle || angle > self.start_angle + self.sweep_angle {\r\n            return 0;\r\n        }\r\n        let dist2 = (pt - self.center).hypot2();\r\n        if (dist2 < self.outer_radius.powi(2) && dist2 > self.inner_radius.powi(2)) ||\r\n            // case where outer_radius < inner_radius\r\n            (dist2 < self.inner_radius.powi(2) && dist2 > self.outer_radius.powi(2))\r\n        {\r\n            1\r\n        } else {\r\n            0\r\n        }\r\n    }\r\n\r\n    #[inline]\r\n    fn bounding_box(&self) -> Rect {\r\n        // todo this is currently not tight\r\n        let r = self.inner_radius.max(self.outer_radius);\r\n        let (x, y) = self.center.into();\r\n        Rect::new(x - r, y - r, x + r, y + r)\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{Circle, Point, Shape};\r\n    use std::f64::consts::PI;\r\n\r\n    fn assert_approx_eq(x: f64, y: f64) {\r\n        // Note: we might want to be more rigorous in testing the accuracy\r\n        // of the conversion into Béziers. But this seems good enough.\r\n        assert!((x - y).abs() < 1e-7, \"{x} != {y}\");\r\n    }\r\n\r\n    #[test]\r\n    fn area_sign() {\r\n        let center = Point::new(5.0, 5.0);\r\n        let c = Circle::new(center, 5.0);\r\n        assert_approx_eq(c.area(), 25.0 * PI);\r\n\r\n        assert_eq!(c.winding(center), 1);\r\n\r\n        let p = c.to_path(1e-9);\r\n        assert_approx_eq(c.area(), p.area());\r\n        assert_eq!(c.winding(center), p.winding(center));\r\n\r\n        let c_neg_radius = Circle::new(center, -5.0);\r\n        assert_approx_eq(c_neg_radius.area(), 25.0 * PI);\r\n\r\n        assert_eq!(c_neg_radius.winding(center), 1);\r\n\r\n        let p_neg_radius = c_neg_radius.to_path(1e-9);\r\n        assert_approx_eq(c_neg_radius.area(), p_neg_radius.area());\r\n        assert_eq!(c_neg_radius.winding(center), p_neg_radius.winding(center));\r\n    }\r\n}\r\n\r\n#[inline]\r\nfn point_on_circle(center: Point, radius: f64, angle: f64) -> Point {\r\n    let (angle_sin, angle_cos) = angle.sin_cos();\r\n    center\r\n        + Vec2 {\r\n            x: angle_cos * radius,\r\n            y: angle_sin * radius,\r\n        }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/common.rs",
      "sha256": "5ebc1a293896953d44bc3c242c8fe7157b45d0a1434af9d1f67def00d8b865ca",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Common mathematical operations\r\n\r\n#![allow(missing_docs)]\r\n\r\nuse arrayvec::ArrayVec;\r\n\r\n/// Defines a trait that chooses between libstd or libm implementations of float methods.\r\nmacro_rules! define_float_funcs {\r\n    ($(\r\n        fn $name:ident(self $(,$arg:ident: $arg_ty:ty)*) -> $ret:ty\r\n        => $lname:ident/$lfname:ident;\r\n    )+) => {\r\n        #[cfg(not(feature = \"std\"))]\r\n        pub(crate) trait FloatFuncs : Sized {\r\n            /// Special implementation for signum, because libm doesn't have it.\r\n            fn signum(self) -> Self;\r\n\r\n            $(fn $name(self $(,$arg: $arg_ty)*) -> $ret;)+\r\n        }\r\n\r\n        #[cfg(not(feature = \"std\"))]\r\n        impl FloatFuncs for f32 {\r\n            #[inline]\r\n            fn signum(self) -> f32 {\r\n                if self.is_nan() {\r\n                    f32::NAN\r\n                } else {\r\n                    1.0_f32.copysign(self)\r\n                }\r\n            }\r\n\r\n            $(fn $name(self $(,$arg: $arg_ty)*) -> $ret {\r\n                #[cfg(feature = \"libm\")]\r\n                return libm::$lfname(self $(,$arg as _)*);\r\n\r\n                #[cfg(not(feature = \"libm\"))]\r\n                compile_error!(\"kurbo requires either the `std` or `libm` feature\")\r\n            })+\r\n        }\r\n\r\n        #[cfg(not(feature = \"std\"))]\r\n        impl FloatFuncs for f64 {\r\n            #[inline]\r\n            fn signum(self) -> f64 {\r\n                if self.is_nan() {\r\n                    f64::NAN\r\n                } else {\r\n                    1.0_f64.copysign(self)\r\n                }\r\n            }\r\n\r\n            $(fn $name(self $(,$arg: $arg_ty)*) -> $ret {\r\n                #[cfg(feature = \"libm\")]\r\n                return libm::$lname(self $(,$arg as _)*);\r\n\r\n                #[cfg(not(feature = \"libm\"))]\r\n                compile_error!(\"kurbo requires either the `std` or `libm` feature\")\r\n            })+\r\n        }\r\n    }\r\n}\r\n\r\ndefine_float_funcs! {\r\n    fn abs(self) -> Self => fabs/fabsf;\r\n    fn acos(self) -> Self => acos/acosf;\r\n    fn atan2(self, other: Self) -> Self => atan2/atan2f;\r\n    fn cbrt(self) -> Self => cbrt/cbrtf;\r\n    fn ceil(self) -> Self => ceil/ceilf;\r\n    fn cos(self) -> Self => cos/cosf;\r\n    fn copysign(self, sign: Self) -> Self => copysign/copysignf;\r\n    fn floor(self) -> Self => floor/floorf;\r\n    fn hypot(self, other: Self) -> Self => hypot/hypotf;\r\n    fn ln(self) -> Self => log/logf;\r\n    fn log2(self) -> Self => log2/log2f;\r\n    fn mul_add(self, a: Self, b: Self) -> Self => fma/fmaf;\r\n    fn powi(self, n: i32) -> Self => pow/powf;\r\n    fn powf(self, n: Self) -> Self => pow/powf;\r\n    fn round(self) -> Self => round/roundf;\r\n    fn sin_cos(self) -> (Self, Self) => sincos/sincosf;\r\n    fn sqrt(self) -> Self => sqrt/sqrtf;\r\n    fn tan(self) -> Self => tan/tanf;\r\n    fn trunc(self) -> Self => trunc/truncf;\r\n}\r\n\r\n/// Adds convenience methods to `f32` and `f64`.\r\npub trait FloatExt<T> {\r\n    /// Rounds to the nearest integer away from zero,\r\n    /// unless the provided value is already an integer.\r\n    ///\r\n    /// It is to `ceil` what `trunc` is to `floor`.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::common::FloatExt;\r\n    ///\r\n    /// let f = 3.7_f64;\r\n    /// let g = 3.0_f64;\r\n    /// let h = -3.7_f64;\r\n    /// let i = -5.1_f32;\r\n    ///\r\n    /// assert_eq!(f.expand(), 4.0);\r\n    /// assert_eq!(g.expand(), 3.0);\r\n    /// assert_eq!(h.expand(), -4.0);\r\n    /// assert_eq!(i.expand(), -6.0);\r\n    /// ```\r\n    fn expand(&self) -> T;\r\n}\r\n\r\nimpl FloatExt<f64> for f64 {\r\n    #[inline]\r\n    fn expand(&self) -> f64 {\r\n        self.abs().ceil().copysign(*self)\r\n    }\r\n}\r\n\r\nimpl FloatExt<f32> for f32 {\r\n    #[inline]\r\n    fn expand(&self) -> f32 {\r\n        self.abs().ceil().copysign(*self)\r\n    }\r\n}\r\n\r\n/// Find real roots of cubic equation.\r\n///\r\n/// The implementation is not (yet) fully robust, but it does handle the case\r\n/// where `c3` is zero (in that case, solving the quadratic equation).\r\n///\r\n/// See: <https://momentsingraphics.de/CubicRoots.html>\r\n///\r\n/// That implementation is in turn based on Jim Blinn's \"How to Solve a Cubic\r\n/// Equation\", which is masterful.\r\n///\r\n/// Return values of x for which c0 + c1 x + c2 x² + c3 x³ = 0.\r\npub fn solve_cubic(c0: f64, c1: f64, c2: f64, c3: f64) -> ArrayVec<f64, 3> {\r\n    let mut result = ArrayVec::new();\r\n    let c3_recip = c3.recip();\r\n    const ONETHIRD: f64 = 1. / 3.;\r\n    let scaled_c2 = c2 * (ONETHIRD * c3_recip);\r\n    let scaled_c1 = c1 * (ONETHIRD * c3_recip);\r\n    let scaled_c0 = c0 * c3_recip;\r\n    if !(scaled_c0.is_finite() && scaled_c1.is_finite() && scaled_c2.is_finite()) {\r\n        // cubic coefficient is zero or nearly so.\r\n        return solve_quadratic(c0, c1, c2).iter().copied().collect();\r\n    }\r\n    let (c0, c1, c2) = (scaled_c0, scaled_c1, scaled_c2);\r\n    // (d0, d1, d2) is called \"Delta\" in article\r\n    let d0 = (-c2).mul_add(c2, c1);\r\n    let d1 = (-c1).mul_add(c2, c0);\r\n    let d2 = c2 * c0 - c1 * c1;\r\n    // d is called \"Discriminant\"\r\n    let d = 4.0 * d0 * d2 - d1 * d1;\r\n    // de is called \"Depressed.x\", Depressed.y = d0\r\n    let de = (-2.0 * c2).mul_add(d0, d1);\r\n    // TODO: handle the cases where these intermediate results overflow.\r\n    if d < 0.0 {\r\n        let sq = (-0.25 * d).sqrt();\r\n        let r = -0.5 * de;\r\n        let t1 = (r + sq).cbrt() + (r - sq).cbrt();\r\n        result.push(t1 - c2);\r\n    } else if d == 0.0 {\r\n        let t1 = (-d0).sqrt().copysign(de);\r\n        result.push(t1 - c2);\r\n        result.push(-2.0 * t1 - c2);\r\n    } else {\r\n        let th = d.sqrt().atan2(-de) * ONETHIRD;\r\n        // (th_cos, th_sin) is called \"CubicRoot\"\r\n        let (th_sin, th_cos) = th.sin_cos();\r\n        // (r0, r1, r2) is called \"Root\"\r\n        let r0 = th_cos;\r\n        let ss3 = th_sin * 3.0f64.sqrt();\r\n        let r1 = 0.5 * (-th_cos + ss3);\r\n        let r2 = 0.5 * (-th_cos - ss3);\r\n        let t = 2.0 * (-d0).sqrt();\r\n        result.push(t.mul_add(r0, -c2));\r\n        result.push(t.mul_add(r1, -c2));\r\n        result.push(t.mul_add(r2, -c2));\r\n    }\r\n    result\r\n}\r\n\r\n/// Find real roots of quadratic equation.\r\n///\r\n/// Return values of x for which c0 + c1 x + c2 x² = 0.\r\n///\r\n/// This function tries to be quite numerically robust. If the equation\r\n/// is nearly linear, it will return the root ignoring the quadratic term;\r\n/// the other root might be out of representable range. In the degenerate\r\n/// case where all coefficients are zero, so that all values of x satisfy\r\n/// the equation, a single `0.0` is returned.\r\npub fn solve_quadratic(c0: f64, c1: f64, c2: f64) -> ArrayVec<f64, 2> {\r\n    let mut result = ArrayVec::new();\r\n    let sc0 = c0 * c2.recip();\r\n    let sc1 = c1 * c2.recip();\r\n    if !sc0.is_finite() || !sc1.is_finite() {\r\n        // c2 is zero or very small, treat as linear eqn\r\n        let root = -c0 / c1;\r\n        if root.is_finite() {\r\n            result.push(root);\r\n        } else if c0 == 0.0 && c1 == 0.0 {\r\n            // Degenerate case\r\n            result.push(0.0);\r\n        }\r\n        return result;\r\n    }\r\n    let arg = sc1 * sc1 - 4. * sc0;\r\n    let root1 = if !arg.is_finite() {\r\n        // Likely, calculation of sc1 * sc1 overflowed. Find one root\r\n        // using sc1 x + x² = 0, other root as sc0 / root1.\r\n        -sc1\r\n    } else {\r\n        if arg < 0.0 {\r\n            return result;\r\n        } else if arg == 0.0 {\r\n            result.push(-0.5 * sc1);\r\n            return result;\r\n        }\r\n        // See https://math.stackexchange.com/questions/866331\r\n        -0.5 * (sc1 + arg.sqrt().copysign(sc1))\r\n    };\r\n    let root2 = sc0 / root1;\r\n    if root2.is_finite() {\r\n        // Sort just to be friendly and make results deterministic.\r\n        if root2 > root1 {\r\n            result.push(root1);\r\n            result.push(root2);\r\n        } else {\r\n            result.push(root2);\r\n            result.push(root1);\r\n        }\r\n    } else {\r\n        result.push(root1);\r\n    }\r\n    result\r\n}\r\n\r\n/// Compute epsilon relative to coefficient.\r\n///\r\n/// A helper function from the Orellana and De Michele paper.\r\nfn eps_rel(raw: f64, a: f64) -> f64 {\r\n    if a == 0.0 {\r\n        raw.abs()\r\n    } else {\r\n        ((raw - a) / a).abs()\r\n    }\r\n}\r\n\r\n/// Find real roots of a quartic equation.\r\n///\r\n/// This is a fairly literal implementation of the method described in:\r\n/// Algorithm 1010: Boosting Efficiency in Solving Quartic Equations with\r\n/// No Compromise in Accuracy, Orellana and De Michele, ACM\r\n/// Transactions on Mathematical Software, Vol. 46, No. 2, May 2020.\r\npub fn solve_quartic(c0: f64, c1: f64, c2: f64, c3: f64, c4: f64) -> ArrayVec<f64, 4> {\r\n    if c4 == 0.0 {\r\n        return solve_cubic(c0, c1, c2, c3).iter().copied().collect();\r\n    }\r\n    if c0 == 0.0 {\r\n        // Note: appends 0 root at end, doesn't sort. We might want to do that.\r\n        return solve_cubic(c1, c2, c3, c4)\r\n            .iter()\r\n            .copied()\r\n            .chain(Some(0.0))\r\n            .collect();\r\n    }\r\n    let a = c3 / c4;\r\n    let b = c2 / c4;\r\n    let c = c1 / c4;\r\n    let d = c0 / c4;\r\n    if let Some(result) = solve_quartic_inner(a, b, c, d, false) {\r\n        return result;\r\n    }\r\n    // Do polynomial rescaling\r\n    const K_Q: f64 = 7.16e76;\r\n    for rescale in [false, true] {\r\n        if let Some(result) = solve_quartic_inner(\r\n            a / K_Q,\r\n            b / K_Q.powi(2),\r\n            c / K_Q.powi(3),\r\n            d / K_Q.powi(4),\r\n            rescale,\r\n        ) {\r\n            return result.iter().map(|x| x * K_Q).collect();\r\n        }\r\n    }\r\n    // Overflow happened, just return no roots.\r\n    //println!(\"overflow, no roots returned\");\r\n    Default::default()\r\n}\r\n\r\nfn solve_quartic_inner(a: f64, b: f64, c: f64, d: f64, rescale: bool) -> Option<ArrayVec<f64, 4>> {\r\n    factor_quartic_inner(a, b, c, d, rescale).map(|quadratics| {\r\n        quadratics\r\n            .iter()\r\n            .flat_map(|(a, b)| solve_quadratic(*b, *a, 1.0))\r\n            .collect()\r\n    })\r\n}\r\n\r\n/// Factor a quartic into two quadratics.\r\n///\r\n/// Attempt to factor a quartic equation into two quadratic equations. Returns None either if there\r\n/// is overflow (in which case rescaling might succeed) or the factorization would result in\r\n/// complex coefficients.\r\n///\r\n/// Discussion question: distinguish the two cases in return value?\r\npub fn factor_quartic_inner(\r\n    a: f64,\r\n    b: f64,\r\n    c: f64,\r\n    d: f64,\r\n    rescale: bool,\r\n) -> Option<ArrayVec<(f64, f64), 2>> {\r\n    let calc_eps_q = |a1, b1, a2, b2| {\r\n        let eps_a = eps_rel(a1 + a2, a);\r\n        let eps_b = eps_rel(b1 + a1 * a2 + b2, b);\r\n        let eps_c = eps_rel(b1 * a2 + a1 * b2, c);\r\n        eps_a + eps_b + eps_c\r\n    };\r\n    let calc_eps_t = |a1, b1, a2, b2| calc_eps_q(a1, b1, a2, b2) + eps_rel(b1 * b2, d);\r\n    let disc = 9. * a * a - 24. * b;\r\n    let s = if disc >= 0.0 {\r\n        -2. * b / (3. * a + disc.sqrt().copysign(a))\r\n    } else {\r\n        -0.25 * a\r\n    };\r\n    let a_prime = a + 4. * s;\r\n    let b_prime = b + 3. * s * (a + 2. * s);\r\n    let c_prime = c + s * (2. * b + s * (3. * a + 4. * s));\r\n    let d_prime = d + s * (c + s * (b + s * (a + s)));\r\n    let g_prime;\r\n    let h_prime;\r\n    const K_C: f64 = 3.49e102;\r\n    if rescale {\r\n        let a_prime_s = a_prime / K_C;\r\n        let b_prime_s = b_prime / K_C;\r\n        let c_prime_s = c_prime / K_C;\r\n        let d_prime_s = d_prime / K_C;\r\n        g_prime = a_prime_s * c_prime_s - (4. / K_C) * d_prime_s - (1. / 3.) * b_prime_s.powi(2);\r\n        h_prime = (a_prime_s * c_prime_s + (8. / K_C) * d_prime_s - (2. / 9.) * b_prime_s.powi(2))\r\n            * (1. / 3.)\r\n            * b_prime_s\r\n            - c_prime_s * (c_prime_s / K_C)\r\n            - a_prime_s.powi(2) * d_prime_s;\r\n    } else {\r\n        g_prime = a_prime * c_prime - 4. * d_prime - (1. / 3.) * b_prime.powi(2);\r\n        h_prime =\r\n            (a_prime * c_prime + 8. * d_prime - (2. / 9.) * b_prime.powi(2)) * (1. / 3.) * b_prime\r\n                - c_prime.powi(2)\r\n                - a_prime.powi(2) * d_prime;\r\n    }\r\n    if !(g_prime.is_finite() && h_prime.is_finite()) {\r\n        return None;\r\n    }\r\n    let phi = depressed_cubic_dominant(g_prime, h_prime);\r\n    let phi = if rescale { phi * K_C } else { phi };\r\n    let l_1 = a * 0.5;\r\n    let l_3 = (1. / 6.) * b + 0.5 * phi;\r\n    let delt_2 = c - a * l_3;\r\n    let d_2_cand_1 = (2. / 3.) * b - phi - l_1 * l_1;\r\n    let l_2_cand_1 = 0.5 * delt_2 / d_2_cand_1;\r\n    let l_2_cand_2 = 2. * (d - l_3 * l_3) / delt_2;\r\n    let d_2_cand_2 = 0.5 * delt_2 / l_2_cand_2;\r\n    let d_2_cand_3 = d_2_cand_1;\r\n    let l_2_cand_3 = l_2_cand_2;\r\n    let mut d_2_best = 0.0;\r\n    let mut l_2_best = 0.0;\r\n    let mut eps_l_best = 0.0;\r\n    for (i, (d_2, l_2)) in [\r\n        (d_2_cand_1, l_2_cand_1),\r\n        (d_2_cand_2, l_2_cand_2),\r\n        (d_2_cand_3, l_2_cand_3),\r\n    ]\r\n    .iter()\r\n    .enumerate()\r\n    {\r\n        let eps_0 = eps_rel(d_2 + l_1 * l_1 + 2. * l_3, b);\r\n        let eps_1 = eps_rel(2. * (d_2 * l_2 + l_1 * l_3), c);\r\n        let eps_2 = eps_rel(d_2 * l_2 * l_2 + l_3 * l_3, d);\r\n        let eps_l = eps_0 + eps_1 + eps_2;\r\n        if i == 0 || eps_l < eps_l_best {\r\n            d_2_best = *d_2;\r\n            l_2_best = *l_2;\r\n            eps_l_best = eps_l;\r\n        }\r\n    }\r\n    let d_2 = d_2_best;\r\n    let l_2 = l_2_best;\r\n    let mut alpha_1;\r\n    let mut beta_1;\r\n    let mut alpha_2;\r\n    let mut beta_2;\r\n    //println!(\"phi = {}, d_2 = {}\", phi, d_2);\r\n    if d_2 < 0.0 {\r\n        let sq = (-d_2).sqrt();\r\n        alpha_1 = l_1 + sq;\r\n        beta_1 = l_3 + sq * l_2;\r\n        alpha_2 = l_1 - sq;\r\n        beta_2 = l_3 - sq * l_2;\r\n        if beta_2.abs() < beta_1.abs() {\r\n            beta_2 = d / beta_1;\r\n        } else if beta_2.abs() > beta_1.abs() {\r\n            beta_1 = d / beta_2;\r\n        }\r\n        let cands;\r\n        if alpha_1.abs() != alpha_2.abs() {\r\n            if alpha_1.abs() < alpha_2.abs() {\r\n                let a1_cand_1 = (c - beta_1 * alpha_2) / beta_2;\r\n                let a1_cand_2 = (b - beta_2 - beta_1) / alpha_2;\r\n                let a1_cand_3 = a - alpha_2;\r\n                // Note: cand 3 is first because it is infallible, simplifying logic\r\n                cands = [\r\n                    (a1_cand_3, alpha_2),\r\n                    (a1_cand_1, alpha_2),\r\n                    (a1_cand_2, alpha_2),\r\n                ];\r\n            } else {\r\n                let a2_cand_1 = (c - alpha_1 * beta_2) / beta_1;\r\n                let a2_cand_2 = (b - beta_2 - beta_1) / alpha_1;\r\n                let a2_cand_3 = a - alpha_1;\r\n                cands = [\r\n                    (alpha_1, a2_cand_3),\r\n                    (alpha_1, a2_cand_1),\r\n                    (alpha_1, a2_cand_2),\r\n                ];\r\n            }\r\n            let mut eps_q_best = 0.0;\r\n            for (i, (a1, a2)) in cands.iter().enumerate() {\r\n                if a1.is_finite() && a2.is_finite() {\r\n                    let eps_q = calc_eps_q(*a1, beta_1, *a2, beta_2);\r\n                    if i == 0 || eps_q < eps_q_best {\r\n                        alpha_1 = *a1;\r\n                        alpha_2 = *a2;\r\n                        eps_q_best = eps_q;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    } else if d_2 == 0.0 {\r\n        let d_3 = d - l_3 * l_3;\r\n        alpha_1 = l_1;\r\n        beta_1 = l_3 + (-d_3).sqrt();\r\n        alpha_2 = l_1;\r\n        beta_2 = l_3 - (-d_3).sqrt();\r\n        if beta_1.abs() > beta_2.abs() {\r\n            beta_2 = d / beta_1;\r\n        } else if beta_2.abs() > beta_1.abs() {\r\n            beta_1 = d / beta_2;\r\n        }\r\n        // TODO: handle case d_2 is very small?\r\n    } else {\r\n        // This case means no real roots; in the most general case we might want\r\n        // to factor into quadratic equations with complex coefficients.\r\n        return None;\r\n    }\r\n    // Newton-Raphson iteration on alpha/beta coeff's.\r\n    let mut eps_t = calc_eps_t(alpha_1, beta_1, alpha_2, beta_2);\r\n    for _ in 0..8 {\r\n        //println!(\"a1 {} b1 {} a2 {} b2 {}\", alpha_1, beta_1, alpha_2, beta_2);\r\n        //println!(\"eps_t = {:e}\", eps_t);\r\n        if eps_t == 0.0 {\r\n            break;\r\n        }\r\n        let f_0 = beta_1 * beta_2 - d;\r\n        let f_1 = beta_1 * alpha_2 + alpha_1 * beta_2 - c;\r\n        let f_2 = beta_1 + alpha_1 * alpha_2 + beta_2 - b;\r\n        let f_3 = alpha_1 + alpha_2 - a;\r\n        let c_1 = alpha_1 - alpha_2;\r\n        let det_j = beta_1 * beta_1 - beta_1 * (alpha_2 * c_1 + 2. * beta_2)\r\n            + beta_2 * (alpha_1 * c_1 + beta_2);\r\n        if det_j == 0.0 {\r\n            break;\r\n        }\r\n        let inv = det_j.recip();\r\n        let c_2 = beta_2 - beta_1;\r\n        let c_3 = beta_1 * alpha_2 - alpha_1 * beta_2;\r\n        let dz_0 = c_1 * f_0 + c_2 * f_1 + c_3 * f_2 - (beta_1 * c_2 + alpha_1 * c_3) * f_3;\r\n        let dz_1 = (alpha_1 * c_1 + c_2) * f_0\r\n            - beta_1 * c_1 * f_1\r\n            - beta_1 * c_2 * f_2\r\n            - beta_1 * c_3 * f_3;\r\n        let dz_2 = -c_1 * f_0 - c_2 * f_1 - c_3 * f_2 + (alpha_2 * c_3 + beta_2 * c_2) * f_3;\r\n        let dz_3 = -(alpha_2 * c_1 + c_2) * f_0\r\n            + beta_2 * c_1 * f_1\r\n            + beta_2 * c_2 * f_2\r\n            + beta_2 * c_3 * f_3;\r\n        let a1 = alpha_1 - inv * dz_0;\r\n        let b1 = beta_1 - inv * dz_1;\r\n        let a2 = alpha_2 - inv * dz_2;\r\n        let b2 = beta_2 - inv * dz_3;\r\n        let new_eps_t = calc_eps_t(a1, b1, a2, b2);\r\n        // We break if the new eps is equal, paper keeps going\r\n        if new_eps_t < eps_t {\r\n            alpha_1 = a1;\r\n            beta_1 = b1;\r\n            alpha_2 = a2;\r\n            beta_2 = b2;\r\n            eps_t = new_eps_t;\r\n        } else {\r\n            //println!(\"new_eps_t got worse: {:e}\", new_eps_t);\r\n            break;\r\n        }\r\n    }\r\n    Some([(alpha_1, beta_1), (alpha_2, beta_2)].into())\r\n}\r\n\r\n/// Dominant root of depressed cubic x^3 + gx + h = 0.\r\n///\r\n/// Section 2.2 of Orellana and De Michele.\r\n// Note: some of the techniques in here might be useful to improve the\r\n// cubic solver, and vice versa.\r\nfn depressed_cubic_dominant(g: f64, h: f64) -> f64 {\r\n    let q = (-1. / 3.) * g;\r\n    let r = 0.5 * h;\r\n    let phi_0;\r\n    let k = if q.abs() < 1e102 && r.abs() < 1e154 {\r\n        None\r\n    } else if q.abs() < r.abs() {\r\n        Some(1. - q * (q / r).powi(2))\r\n    } else {\r\n        Some(q.signum() * ((r / q).powi(2) / q - 1.0))\r\n    };\r\n    if k.is_some() && r == 0.0 {\r\n        if g > 0.0 {\r\n            phi_0 = 0.0;\r\n        } else {\r\n            phi_0 = (-g).sqrt();\r\n        }\r\n    } else if k.map(|k| k < 0.0).unwrap_or_else(|| r * r < q.powi(3)) {\r\n        let t = if k.is_some() {\r\n            r / q / q.sqrt()\r\n        } else {\r\n            r / q.powi(3).sqrt()\r\n        };\r\n        phi_0 = -2. * q.sqrt() * (t.abs().acos() * (1. / 3.)).cos().copysign(t);\r\n    } else {\r\n        let a = if let Some(k) = k {\r\n            if q.abs() < r.abs() {\r\n                -r * (1. + k.sqrt())\r\n            } else {\r\n                -r - (q.abs().sqrt() * q * k.sqrt()).copysign(r)\r\n            }\r\n        } else {\r\n            -r - (r * r - q.powi(3)).sqrt().copysign(r)\r\n        }\r\n        .cbrt();\r\n        let b = if a == 0.0 { 0.0 } else { q / a };\r\n        phi_0 = a + b;\r\n    }\r\n    // Refine with Newton-Raphson iteration\r\n    let mut x = phi_0;\r\n    let mut f = (x * x + g) * x + h;\r\n    //println!(\"g = {:e}, h = {:e}, x = {:e}, f = {:e}\", g, h, x, f);\r\n    const EPS_M: f64 = 2.22045e-16;\r\n    if f.abs() < EPS_M * x.powi(3).max(g * x).max(h) {\r\n        return x;\r\n    }\r\n    for _ in 0..8 {\r\n        let delt_f = 3. * x * x + g;\r\n        if delt_f == 0.0 {\r\n            break;\r\n        }\r\n        let new_x = x - f / delt_f;\r\n        let new_f = (new_x * new_x + g) * new_x + h;\r\n        //println!(\"delt_f = {:e}, new_f = {:e}\", delt_f, new_f);\r\n        if new_f == 0.0 {\r\n            return new_x;\r\n        }\r\n        if new_f.abs() >= f.abs() {\r\n            break;\r\n        }\r\n        x = new_x;\r\n        f = new_f;\r\n    }\r\n    x\r\n}\r\n\r\n/// Solve an arbitrary function for a zero-crossing.\r\n///\r\n/// This uses the [ITP method], as described in the paper\r\n/// [An Enhancement of the Bisection Method Average Performance Preserving Minmax Optimality].\r\n///\r\n/// The values of `ya` and `yb` are given as arguments rather than\r\n/// computed from `f`, as the values may already be known, or they may\r\n/// be less expensive to compute as special cases.\r\n///\r\n/// It is assumed that `ya < 0.0` and `yb > 0.0`, otherwise unexpected\r\n/// results may occur.\r\n///\r\n/// The value of `epsilon` must be larger than 2^-63 times `b - a`,\r\n/// otherwise integer overflow may occur. The `a` and `b` parameters\r\n/// represent the lower and upper bounds of the bracket searched for a\r\n/// solution.\r\n///\r\n/// The ITP method has tuning parameters. This implementation hardwires\r\n/// k2 to 2, both because it avoids an expensive floating point\r\n/// exponentiation, and because this value has been tested to work well\r\n/// with curve fitting problems.\r\n///\r\n/// The `n0` parameter controls the relative impact of the bisection and\r\n/// secant components. When it is 0, the number of iterations is\r\n/// guaranteed to be no more than the number required by bisection (thus,\r\n/// this method is strictly superior to bisection). However, when the\r\n/// function is smooth, a value of 1 gives the secant method more of a\r\n/// chance to engage, so the average number of iterations is likely\r\n/// lower, though there can be one more iteration than bisection in the\r\n/// worst case.\r\n///\r\n/// The `k1` parameter is harder to characterize, and interested users\r\n/// are referred to the paper, as well as encouraged to do empirical\r\n/// testing. To match the paper, a value of `0.2 / (b - a)` is\r\n/// suggested, and this is confirmed to give good results.\r\n///\r\n/// When the function is monotonic, the returned result is guaranteed to\r\n/// be within `epsilon` of the zero crossing. For more detailed analysis,\r\n/// again see the paper.\r\n///\r\n/// [ITP method]: https://en.wikipedia.org/wiki/ITP_Method\r\n/// [An Enhancement of the Bisection Method Average Performance Preserving Minmax Optimality]: https://dl.acm.org/doi/10.1145/3423597\r\n#[allow(clippy::too_many_arguments)]\r\npub fn solve_itp(\r\n    mut f: impl FnMut(f64) -> f64,\r\n    mut a: f64,\r\n    mut b: f64,\r\n    epsilon: f64,\r\n    n0: usize,\r\n    k1: f64,\r\n    mut ya: f64,\r\n    mut yb: f64,\r\n) -> f64 {\r\n    let n1_2 = (((b - a) / epsilon).log2().ceil() - 1.0).max(0.0) as usize;\r\n    let nmax = n0 + n1_2;\r\n    let mut scaled_epsilon = epsilon * (1u64 << nmax) as f64;\r\n    while b - a > 2.0 * epsilon {\r\n        let x1_2 = 0.5 * (a + b);\r\n        let r = scaled_epsilon - 0.5 * (b - a);\r\n        let xf = (yb * a - ya * b) / (yb - ya);\r\n        let sigma = x1_2 - xf;\r\n        // This has k2 = 2 hardwired for efficiency.\r\n        let delta = k1 * (b - a).powi(2);\r\n        let xt = if delta <= (x1_2 - xf).abs() {\r\n            xf + delta.copysign(sigma)\r\n        } else {\r\n            x1_2\r\n        };\r\n        let xitp = if (xt - x1_2).abs() <= r {\r\n            xt\r\n        } else {\r\n            x1_2 - r.copysign(sigma)\r\n        };\r\n        let yitp = f(xitp);\r\n        if yitp > 0.0 {\r\n            b = xitp;\r\n            yb = yitp;\r\n        } else if yitp < 0.0 {\r\n            a = xitp;\r\n            ya = yitp;\r\n        } else {\r\n            return xitp;\r\n        }\r\n        scaled_epsilon *= 0.5;\r\n    }\r\n    0.5 * (a + b)\r\n}\r\n\r\n/// A variant ITP solver that allows fallible functions.\r\n///\r\n/// Another difference: it returns the bracket that contains the root,\r\n/// which may be important if the function has a discontinuity.\r\n#[allow(clippy::too_many_arguments)]\r\npub(crate) fn solve_itp_fallible<E>(\r\n    mut f: impl FnMut(f64) -> Result<f64, E>,\r\n    mut a: f64,\r\n    mut b: f64,\r\n    epsilon: f64,\r\n    n0: usize,\r\n    k1: f64,\r\n    mut ya: f64,\r\n    mut yb: f64,\r\n) -> Result<(f64, f64), E> {\r\n    let n1_2 = (((b - a) / epsilon).log2().ceil() - 1.0).max(0.0) as usize;\r\n    let nmax = n0 + n1_2;\r\n    let mut scaled_epsilon = epsilon * (1u64 << nmax) as f64;\r\n    while b - a > 2.0 * epsilon {\r\n        let x1_2 = 0.5 * (a + b);\r\n        let r = scaled_epsilon - 0.5 * (b - a);\r\n        let xf = (yb * a - ya * b) / (yb - ya);\r\n        let sigma = x1_2 - xf;\r\n        // This has k2 = 2 hardwired for efficiency.\r\n        let delta = k1 * (b - a).powi(2);\r\n        let xt = if delta <= (x1_2 - xf).abs() {\r\n            xf + delta.copysign(sigma)\r\n        } else {\r\n            x1_2\r\n        };\r\n        let xitp = if (xt - x1_2).abs() <= r {\r\n            xt\r\n        } else {\r\n            x1_2 - r.copysign(sigma)\r\n        };\r\n        let yitp = f(xitp)?;\r\n        if yitp > 0.0 {\r\n            b = xitp;\r\n            yb = yitp;\r\n        } else if yitp < 0.0 {\r\n            a = xitp;\r\n            ya = yitp;\r\n        } else {\r\n            return Ok((xitp, xitp));\r\n        }\r\n        scaled_epsilon *= 0.5;\r\n    }\r\n    Ok((a, b))\r\n}\r\n\r\n// Tables of Legendre-Gauss quadrature coefficients, adapted from:\r\n// <https://pomax.github.io/bezierinfo/legendre-gauss.html>\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_3: &[(f64, f64)] = &[\r\n    (0.8888888888888888, 0.0000000000000000),\r\n    (0.5555555555555556, -0.7745966692414834),\r\n    (0.5555555555555556, 0.7745966692414834),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_4: &[(f64, f64)] = &[\r\n    (0.6521451548625461, -0.3399810435848563),\r\n    (0.6521451548625461, 0.3399810435848563),\r\n    (0.3478548451374538, -0.8611363115940526),\r\n    (0.3478548451374538, 0.8611363115940526),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_5: &[(f64, f64)] = &[\r\n    (0.5688888888888889, 0.0000000000000000),\r\n    (0.4786286704993665, -0.5384693101056831),\r\n    (0.4786286704993665, 0.5384693101056831),\r\n    (0.2369268850561891, -0.9061798459386640),\r\n    (0.2369268850561891, 0.9061798459386640),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_6: &[(f64, f64)] = &[\r\n    (0.3607615730481386, 0.6612093864662645),\r\n    (0.3607615730481386, -0.6612093864662645),\r\n    (0.4679139345726910, -0.2386191860831969),\r\n    (0.4679139345726910, 0.2386191860831969),\r\n    (0.1713244923791704, -0.9324695142031521),\r\n    (0.1713244923791704, 0.9324695142031521),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_7: &[(f64, f64)] = &[\r\n    (0.4179591836734694, 0.0000000000000000),\r\n    (0.3818300505051189, 0.4058451513773972),\r\n    (0.3818300505051189, -0.4058451513773972),\r\n    (0.2797053914892766, -0.7415311855993945),\r\n    (0.2797053914892766, 0.7415311855993945),\r\n    (0.1294849661688697, -0.9491079123427585),\r\n    (0.1294849661688697, 0.9491079123427585),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_8: &[(f64, f64)] = &[\r\n    (0.3626837833783620, -0.1834346424956498),\r\n    (0.3626837833783620, 0.1834346424956498),\r\n    (0.3137066458778873, -0.5255324099163290),\r\n    (0.3137066458778873, 0.5255324099163290),\r\n    (0.2223810344533745, -0.7966664774136267),\r\n    (0.2223810344533745, 0.7966664774136267),\r\n    (0.1012285362903763, -0.9602898564975363),\r\n    (0.1012285362903763, 0.9602898564975363),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_8_HALF: &[(f64, f64)] = &[\r\n    (0.3626837833783620, 0.1834346424956498),\r\n    (0.3137066458778873, 0.5255324099163290),\r\n    (0.2223810344533745, 0.7966664774136267),\r\n    (0.1012285362903763, 0.9602898564975363),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_9: &[(f64, f64)] = &[\r\n    (0.3302393550012598, 0.0000000000000000),\r\n    (0.1806481606948574, -0.8360311073266358),\r\n    (0.1806481606948574, 0.8360311073266358),\r\n    (0.0812743883615744, -0.9681602395076261),\r\n    (0.0812743883615744, 0.9681602395076261),\r\n    (0.3123470770400029, -0.3242534234038089),\r\n    (0.3123470770400029, 0.3242534234038089),\r\n    (0.2606106964029354, -0.6133714327005904),\r\n    (0.2606106964029354, 0.6133714327005904),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_11: &[(f64, f64)] = &[\r\n    (0.2729250867779006, 0.0000000000000000),\r\n    (0.2628045445102467, -0.2695431559523450),\r\n    (0.2628045445102467, 0.2695431559523450),\r\n    (0.2331937645919905, -0.5190961292068118),\r\n    (0.2331937645919905, 0.5190961292068118),\r\n    (0.1862902109277343, -0.7301520055740494),\r\n    (0.1862902109277343, 0.7301520055740494),\r\n    (0.1255803694649046, -0.8870625997680953),\r\n    (0.1255803694649046, 0.8870625997680953),\r\n    (0.0556685671161737, -0.9782286581460570),\r\n    (0.0556685671161737, 0.9782286581460570),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_16: &[(f64, f64)] = &[\r\n    (0.1894506104550685, -0.0950125098376374),\r\n    (0.1894506104550685, 0.0950125098376374),\r\n    (0.1826034150449236, -0.2816035507792589),\r\n    (0.1826034150449236, 0.2816035507792589),\r\n    (0.1691565193950025, -0.4580167776572274),\r\n    (0.1691565193950025, 0.4580167776572274),\r\n    (0.1495959888165767, -0.6178762444026438),\r\n    (0.1495959888165767, 0.6178762444026438),\r\n    (0.1246289712555339, -0.7554044083550030),\r\n    (0.1246289712555339, 0.7554044083550030),\r\n    (0.0951585116824928, -0.8656312023878318),\r\n    (0.0951585116824928, 0.8656312023878318),\r\n    (0.0622535239386479, -0.9445750230732326),\r\n    (0.0622535239386479, 0.9445750230732326),\r\n    (0.0271524594117541, -0.9894009349916499),\r\n    (0.0271524594117541, 0.9894009349916499),\r\n];\r\n\r\n// Just the positive x_i values.\r\npub const GAUSS_LEGENDRE_COEFFS_16_HALF: &[(f64, f64)] = &[\r\n    (0.1894506104550685, 0.0950125098376374),\r\n    (0.1826034150449236, 0.2816035507792589),\r\n    (0.1691565193950025, 0.4580167776572274),\r\n    (0.1495959888165767, 0.6178762444026438),\r\n    (0.1246289712555339, 0.7554044083550030),\r\n    (0.0951585116824928, 0.8656312023878318),\r\n    (0.0622535239386479, 0.9445750230732326),\r\n    (0.0271524594117541, 0.9894009349916499),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_24: &[(f64, f64)] = &[\r\n    (0.1279381953467522, -0.0640568928626056),\r\n    (0.1279381953467522, 0.0640568928626056),\r\n    (0.1258374563468283, -0.1911188674736163),\r\n    (0.1258374563468283, 0.1911188674736163),\r\n    (0.1216704729278034, -0.3150426796961634),\r\n    (0.1216704729278034, 0.3150426796961634),\r\n    (0.1155056680537256, -0.4337935076260451),\r\n    (0.1155056680537256, 0.4337935076260451),\r\n    (0.1074442701159656, -0.5454214713888396),\r\n    (0.1074442701159656, 0.5454214713888396),\r\n    (0.0976186521041139, -0.6480936519369755),\r\n    (0.0976186521041139, 0.6480936519369755),\r\n    (0.0861901615319533, -0.7401241915785544),\r\n    (0.0861901615319533, 0.7401241915785544),\r\n    (0.0733464814110803, -0.8200019859739029),\r\n    (0.0733464814110803, 0.8200019859739029),\r\n    (0.0592985849154368, -0.8864155270044011),\r\n    (0.0592985849154368, 0.8864155270044011),\r\n    (0.0442774388174198, -0.9382745520027328),\r\n    (0.0442774388174198, 0.9382745520027328),\r\n    (0.0285313886289337, -0.9747285559713095),\r\n    (0.0285313886289337, 0.9747285559713095),\r\n    (0.0123412297999872, -0.9951872199970213),\r\n    (0.0123412297999872, 0.9951872199970213),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_24_HALF: &[(f64, f64)] = &[\r\n    (0.1279381953467522, 0.0640568928626056),\r\n    (0.1258374563468283, 0.1911188674736163),\r\n    (0.1216704729278034, 0.3150426796961634),\r\n    (0.1155056680537256, 0.4337935076260451),\r\n    (0.1074442701159656, 0.5454214713888396),\r\n    (0.0976186521041139, 0.6480936519369755),\r\n    (0.0861901615319533, 0.7401241915785544),\r\n    (0.0733464814110803, 0.8200019859739029),\r\n    (0.0592985849154368, 0.8864155270044011),\r\n    (0.0442774388174198, 0.9382745520027328),\r\n    (0.0285313886289337, 0.9747285559713095),\r\n    (0.0123412297999872, 0.9951872199970213),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_32: &[(f64, f64)] = &[\r\n    (0.0965400885147278, -0.0483076656877383),\r\n    (0.0965400885147278, 0.0483076656877383),\r\n    (0.0956387200792749, -0.1444719615827965),\r\n    (0.0956387200792749, 0.1444719615827965),\r\n    (0.0938443990808046, -0.2392873622521371),\r\n    (0.0938443990808046, 0.2392873622521371),\r\n    (0.0911738786957639, -0.3318686022821277),\r\n    (0.0911738786957639, 0.3318686022821277),\r\n    (0.0876520930044038, -0.4213512761306353),\r\n    (0.0876520930044038, 0.4213512761306353),\r\n    (0.0833119242269467, -0.5068999089322294),\r\n    (0.0833119242269467, 0.5068999089322294),\r\n    (0.0781938957870703, -0.5877157572407623),\r\n    (0.0781938957870703, 0.5877157572407623),\r\n    (0.0723457941088485, -0.6630442669302152),\r\n    (0.0723457941088485, 0.6630442669302152),\r\n    (0.0658222227763618, -0.7321821187402897),\r\n    (0.0658222227763618, 0.7321821187402897),\r\n    (0.0586840934785355, -0.7944837959679424),\r\n    (0.0586840934785355, 0.7944837959679424),\r\n    (0.0509980592623762, -0.8493676137325700),\r\n    (0.0509980592623762, 0.8493676137325700),\r\n    (0.0428358980222267, -0.8963211557660521),\r\n    (0.0428358980222267, 0.8963211557660521),\r\n    (0.0342738629130214, -0.9349060759377397),\r\n    (0.0342738629130214, 0.9349060759377397),\r\n    (0.0253920653092621, -0.9647622555875064),\r\n    (0.0253920653092621, 0.9647622555875064),\r\n    (0.0162743947309057, -0.9856115115452684),\r\n    (0.0162743947309057, 0.9856115115452684),\r\n    (0.0070186100094701, -0.9972638618494816),\r\n    (0.0070186100094701, 0.9972638618494816),\r\n];\r\n\r\npub const GAUSS_LEGENDRE_COEFFS_32_HALF: &[(f64, f64)] = &[\r\n    (0.0965400885147278, 0.0483076656877383),\r\n    (0.0956387200792749, 0.1444719615827965),\r\n    (0.0938443990808046, 0.2392873622521371),\r\n    (0.0911738786957639, 0.3318686022821277),\r\n    (0.0876520930044038, 0.4213512761306353),\r\n    (0.0833119242269467, 0.5068999089322294),\r\n    (0.0781938957870703, 0.5877157572407623),\r\n    (0.0723457941088485, 0.6630442669302152),\r\n    (0.0658222227763618, 0.7321821187402897),\r\n    (0.0586840934785355, 0.7944837959679424),\r\n    (0.0509980592623762, 0.8493676137325700),\r\n    (0.0428358980222267, 0.8963211557660521),\r\n    (0.0342738629130214, 0.9349060759377397),\r\n    (0.0253920653092621, 0.9647622555875064),\r\n    (0.0162743947309057, 0.9856115115452684),\r\n    (0.0070186100094701, 0.9972638618494816),\r\n];\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::common::*;\r\n    use arrayvec::ArrayVec;\r\n\r\n    fn verify<const N: usize>(mut roots: ArrayVec<f64, N>, expected: &[f64]) {\r\n        assert_eq!(expected.len(), roots.len());\r\n        let epsilon = 1e-12;\r\n        roots.sort_by(|a, b| a.partial_cmp(b).unwrap());\r\n        for i in 0..expected.len() {\r\n            assert!((roots[i] - expected[i]).abs() < epsilon);\r\n        }\r\n    }\r\n\r\n    #[test]\r\n    fn test_solve_cubic() {\r\n        verify(solve_cubic(-5.0, 0.0, 0.0, 1.0), &[5.0f64.cbrt()]);\r\n        verify(solve_cubic(-5.0, -1.0, 0.0, 1.0), &[1.90416085913492]);\r\n        verify(solve_cubic(0.0, -1.0, 0.0, 1.0), &[-1.0, 0.0, 1.0]);\r\n        verify(solve_cubic(-2.0, -3.0, 0.0, 1.0), &[-1.0, 2.0]);\r\n        verify(solve_cubic(2.0, -3.0, 0.0, 1.0), &[-2.0, 1.0]);\r\n        verify(\r\n            solve_cubic(2.0 - 1e-12, 5.0, 4.0, 1.0),\r\n            &[\r\n                -1.9999999999989995,\r\n                -1.0000010000848456,\r\n                -0.9999989999161546,\r\n            ],\r\n        );\r\n        verify(solve_cubic(2.0 + 1e-12, 5.0, 4.0, 1.0), &[-2.0]);\r\n    }\r\n\r\n    #[test]\r\n    fn test_solve_quadratic() {\r\n        verify(\r\n            solve_quadratic(-5.0, 0.0, 1.0),\r\n            &[-(5.0f64.sqrt()), 5.0f64.sqrt()],\r\n        );\r\n        verify(solve_quadratic(5.0, 0.0, 1.0), &[]);\r\n        verify(solve_quadratic(5.0, 1.0, 0.0), &[-5.0]);\r\n        verify(solve_quadratic(1.0, 2.0, 1.0), &[-1.0]);\r\n    }\r\n\r\n    #[test]\r\n    fn test_solve_quartic() {\r\n        // These test cases are taken from Orellana and De Michele paper (Table 1).\r\n        fn test_with_roots(coeffs: [f64; 4], roots: &[f64], rel_err: f64) {\r\n            // Note: in paper, coefficients are in decreasing order.\r\n            let mut actual = solve_quartic(coeffs[3], coeffs[2], coeffs[1], coeffs[0], 1.0);\r\n            actual.sort_by(f64::total_cmp);\r\n            assert_eq!(actual.len(), roots.len());\r\n            for (actual, expected) in actual.iter().zip(roots) {\r\n                assert!(\r\n                    (actual - expected).abs() < rel_err * expected.abs(),\r\n                    \"actual {:e}, expected {:e}, err {:e}\",\r\n                    actual,\r\n                    expected,\r\n                    actual - expected\r\n                );\r\n            }\r\n        }\r\n\r\n        fn test_vieta_roots(x1: f64, x2: f64, x3: f64, x4: f64, roots: &[f64], rel_err: f64) {\r\n            let a = -(x1 + x2 + x3 + x4);\r\n            let b = x1 * (x2 + x3) + x2 * (x3 + x4) + x4 * (x1 + x3);\r\n            let c = -x1 * x2 * (x3 + x4) - x3 * x4 * (x1 + x2);\r\n            let d = x1 * x2 * x3 * x4;\r\n            test_with_roots([a, b, c, d], roots, rel_err);\r\n        }\r\n\r\n        fn test_vieta(x1: f64, x2: f64, x3: f64, x4: f64, rel_err: f64) {\r\n            test_vieta_roots(x1, x2, x3, x4, &[x1, x2, x3, x4], rel_err);\r\n        }\r\n\r\n        // case 1\r\n        test_vieta(1., 1e3, 1e6, 1e9, 1e-16);\r\n        // case 2\r\n        test_vieta(2., 2.001, 2.002, 2.003, 1e-6);\r\n        // case 3\r\n        test_vieta(1e47, 1e49, 1e50, 1e53, 2e-16);\r\n        // case 4\r\n        test_vieta(-1., 1., 2., 1e14, 1e-16);\r\n        // case 5\r\n        test_vieta(-2e7, -1., 1., 1e7, 1e-16);\r\n        // case 6\r\n        test_with_roots(\r\n            [-9000002.0, -9999981999998.0, 19999982e6, -2e13],\r\n            &[-1e6, 1e7],\r\n            1e-16,\r\n        );\r\n        // case 7\r\n        test_with_roots(\r\n            [2000011.0, 1010022000028.0, 11110056e6, 2828e10],\r\n            &[-7., -4.],\r\n            1e-16,\r\n        );\r\n        // case 8\r\n        test_with_roots(\r\n            [-100002011.0, 201101022001.0, -102200111000011.0, 11000011e8],\r\n            &[11., 1e8],\r\n            1e-16,\r\n        );\r\n        // cases 9-13 have no real roots\r\n        // case 14\r\n        test_vieta_roots(1000., 1000., 1000., 1000., &[1000., 1000.], 1e-16);\r\n        // case 15\r\n        test_vieta_roots(1e-15, 1000., 1000., 1000., &[1e-15, 1000., 1000.], 1e-15);\r\n        // case 16 no real roots\r\n        // case 17\r\n        test_vieta(10000., 10001., 10010., 10100., 1e-6);\r\n        // case 19\r\n        test_vieta_roots(1., 1e30, 1e30, 1e44, &[1., 1e30, 1e44], 1e-16);\r\n        // case 20\r\n        // FAILS, error too big\r\n        test_vieta(1., 1e7, 1e7, 1e14, 1e-7);\r\n        // case 21 doesn't pick up double root\r\n        // case 22\r\n        test_vieta(1., 10., 1e152, 1e154, 3e-16);\r\n        // case 23\r\n        test_with_roots(\r\n            [1., 1., 3. / 8., 1e-3],\r\n            &[-0.497314148060048, -0.00268585193995149],\r\n            2e-15,\r\n        );\r\n        // case 24\r\n        const S: f64 = 1e30;\r\n        test_with_roots(\r\n            [-(1. + 1. / S), 1. / S - S * S, S * S + S, -S],\r\n            &[-S, 1e-30, 1., S],\r\n            2e-16,\r\n        );\r\n    }\r\n\r\n    #[test]\r\n    fn test_solve_itp() {\r\n        let f = |x: f64| x.powi(3) - x - 2.0;\r\n        let x = solve_itp(f, 1., 2., 1e-12, 0, 0.2, f(1.), f(2.));\r\n        assert!(f(x).abs() < 6e-12);\r\n    }\r\n\r\n    #[test]\r\n    fn test_inv_arclen() {\r\n        use crate::{ParamCurve, ParamCurveArclen};\r\n        let c = crate::CubicBez::new(\r\n            (0.0, 0.0),\r\n            (100.0 / 3.0, 0.0),\r\n            (200.0 / 3.0, 100.0 / 3.0),\r\n            (100.0, 100.0),\r\n        );\r\n        let target = 100.0;\r\n        let _ = solve_itp(\r\n            |t| c.subsegment(0.0..t).arclen(1e-9) - target,\r\n            0.,\r\n            1.,\r\n            1e-6,\r\n            1,\r\n            0.2,\r\n            -target,\r\n            c.arclen(1e-9) - target,\r\n        );\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/cubicbez.rs",
      "sha256": "c56c0d65e352dc3174bbbcf10f11f7560e037016db181703bbee84384b33a3d2",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Cubic Bézier segments.\r\n\r\nuse alloc::vec;\r\nuse alloc::vec::Vec;\r\nuse core::ops::{Mul, Range};\r\n\r\nuse crate::MAX_EXTREMA;\r\nuse crate::{Line, QuadSpline, Vec2};\r\nuse arrayvec::ArrayVec;\r\n\r\nuse crate::common::{\r\n    solve_quadratic, GAUSS_LEGENDRE_COEFFS_16_HALF, GAUSS_LEGENDRE_COEFFS_24_HALF,\r\n    GAUSS_LEGENDRE_COEFFS_8, GAUSS_LEGENDRE_COEFFS_8_HALF,\r\n};\r\nuse crate::{\r\n    Affine, Nearest, ParamCurve, ParamCurveArclen, ParamCurveArea, ParamCurveCurvature,\r\n    ParamCurveDeriv, ParamCurveExtrema, ParamCurveNearest, PathEl, Point, QuadBez, Rect, Shape,\r\n};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\nconst MAX_SPLINE_SPLIT: usize = 100;\r\n\r\n/// A single cubic Bézier segment.\r\n#[derive(Clone, Copy, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\n#[allow(missing_docs)]\r\npub struct CubicBez {\r\n    pub p0: Point,\r\n    pub p1: Point,\r\n    pub p2: Point,\r\n    pub p3: Point,\r\n}\r\n\r\n/// An iterator which produces quadratic Bézier segments.\r\nstruct ToQuads {\r\n    c: CubicBez,\r\n    i: usize,\r\n    n: usize,\r\n}\r\n\r\nimpl CubicBez {\r\n    /// Create a new cubic Bézier segment.\r\n    #[inline]\r\n    pub fn new<P: Into<Point>>(p0: P, p1: P, p2: P, p3: P) -> CubicBez {\r\n        CubicBez {\r\n            p0: p0.into(),\r\n            p1: p1.into(),\r\n            p2: p2.into(),\r\n            p3: p3.into(),\r\n        }\r\n    }\r\n\r\n    /// Convert to quadratic Béziers.\r\n    ///\r\n    /// The iterator returns the start and end parameter in the cubic of each quadratic\r\n    /// segment, along with the quadratic.\r\n    ///\r\n    /// Note that the resulting quadratic Béziers are not in general G1 continuous;\r\n    /// they are optimized for minimizing distance error.\r\n    ///\r\n    /// This iterator will always produce at least one `QuadBez`.\r\n    #[inline]\r\n    pub fn to_quads(&self, accuracy: f64) -> impl Iterator<Item = (f64, f64, QuadBez)> {\r\n        // The maximum error, as a vector from the cubic to the best approximating\r\n        // quadratic, is proportional to the third derivative, which is constant\r\n        // across the segment. Thus, the error scales down as the third power of\r\n        // the number of subdivisions. Our strategy then is to subdivide `t` evenly.\r\n        //\r\n        // This is an overestimate of the error because only the component\r\n        // perpendicular to the first derivative is important. But the simplicity is\r\n        // appealing.\r\n\r\n        // This magic number is the square of 36 / sqrt(3).\r\n        // See: http://caffeineowl.com/graphics/2d/vectorial/cubic2quad01.html\r\n        let max_hypot2 = 432.0 * accuracy * accuracy;\r\n        let p1x2 = 3.0 * self.p1.to_vec2() - self.p0.to_vec2();\r\n        let p2x2 = 3.0 * self.p2.to_vec2() - self.p3.to_vec2();\r\n        let err = (p2x2 - p1x2).hypot2();\r\n        let n = ((err / max_hypot2).powf(1. / 6.0).ceil() as usize).max(1);\r\n\r\n        ToQuads { c: *self, n, i: 0 }\r\n    }\r\n\r\n    /// Return a [`QuadSpline`] approximating this cubic Bézier.\r\n    ///\r\n    /// Returns `None` if no suitable approximation is found within the given\r\n    /// tolerance.\r\n    pub fn approx_spline(&self, accuracy: f64) -> Option<QuadSpline> {\r\n        (1..=MAX_SPLINE_SPLIT).find_map(|n| self.approx_spline_n(n, accuracy))\r\n    }\r\n\r\n    // Approximate a cubic curve with a quadratic spline of `n` curves\r\n    fn approx_spline_n(&self, n: usize, accuracy: f64) -> Option<QuadSpline> {\r\n        if n == 1 {\r\n            return self\r\n                .try_approx_quadratic(accuracy)\r\n                .map(|quad| QuadSpline::new(vec![quad.p0, quad.p1, quad.p2]));\r\n        }\r\n        let mut cubics = self.split_into_n(n);\r\n\r\n        // The above function guarantees that the iterator returns n items,\r\n        // which is why we're unwrapping things with wild abandon.\r\n        let mut next_cubic = cubics.next().unwrap();\r\n        let mut next_q1: Point = next_cubic.approx_quad_control(0.0);\r\n        let mut q2 = self.p0;\r\n        let mut d1 = Vec2::ZERO;\r\n        let mut spline = vec![self.p0, next_q1];\r\n        for i in 1..=n {\r\n            let current_cubic: CubicBez = next_cubic;\r\n            let q0 = q2;\r\n            let q1 = next_q1;\r\n            q2 = if i < n {\r\n                next_cubic = cubics.next().unwrap();\r\n                next_q1 = next_cubic.approx_quad_control(i as f64 / (n - 1) as f64);\r\n\r\n                spline.push(next_q1);\r\n                q1.midpoint(next_q1)\r\n            } else {\r\n                current_cubic.p3\r\n            };\r\n            let d0 = d1;\r\n            d1 = q2.to_vec2() - current_cubic.p3.to_vec2();\r\n\r\n            if d1.hypot() > accuracy\r\n                || !CubicBez::new(\r\n                    d0.to_point(),\r\n                    q0.lerp(q1, 2.0 / 3.0) - current_cubic.p1.to_vec2(),\r\n                    q2.lerp(q1, 2.0 / 3.0) - current_cubic.p2.to_vec2(),\r\n                    d1.to_point(),\r\n                )\r\n                .fit_inside(accuracy)\r\n            {\r\n                return None;\r\n            }\r\n        }\r\n        spline.push(self.p3);\r\n        Some(QuadSpline::new(spline))\r\n    }\r\n\r\n    fn approx_quad_control(&self, t: f64) -> Point {\r\n        let p1 = self.p0 + (self.p1 - self.p0) * 1.5;\r\n        let p2 = self.p3 + (self.p2 - self.p3) * 1.5;\r\n        p1.lerp(p2, t)\r\n    }\r\n\r\n    /// Approximate a cubic with a single quadratic\r\n    ///\r\n    /// Returns a quadratic approximating the given cubic that maintains\r\n    /// endpoint tangents if that is within tolerance, or None otherwise.\r\n    fn try_approx_quadratic(&self, accuracy: f64) -> Option<QuadBez> {\r\n        if let Some(q1) = Line::new(self.p0, self.p1).crossing_point(Line::new(self.p2, self.p3)) {\r\n            let c1 = self.p0.lerp(q1, 2.0 / 3.0);\r\n            let c2 = self.p3.lerp(q1, 2.0 / 3.0);\r\n            if !CubicBez::new(\r\n                Point::ZERO,\r\n                c1 - self.p1.to_vec2(),\r\n                c2 - self.p2.to_vec2(),\r\n                Point::ZERO,\r\n            )\r\n            .fit_inside(accuracy)\r\n            {\r\n                return None;\r\n            }\r\n            return Some(QuadBez::new(self.p0, q1, self.p3));\r\n        }\r\n        None\r\n    }\r\n\r\n    fn split_into_n(&self, n: usize) -> impl Iterator<Item = CubicBez> {\r\n        // for certain small values of `n` we precompute all our values.\r\n        // if we have six or fewer items we precompute them.\r\n        let mut storage = ArrayVec::<_, 6>::new();\r\n\r\n        match n {\r\n            1 => storage.push(*self),\r\n            2 => {\r\n                let (l, r) = self.subdivide();\r\n                storage.try_extend_from_slice(&[r, l]).unwrap();\r\n            }\r\n            3 => {\r\n                let (left, mid, right) = self.subdivide_3();\r\n                storage.try_extend_from_slice(&[right, mid, left]).unwrap();\r\n            }\r\n            4 => {\r\n                let (l, r) = self.subdivide();\r\n                let (ll, lr) = l.subdivide();\r\n                let (rl, rr) = r.subdivide();\r\n                storage.try_extend_from_slice(&[rr, rl, lr, ll]).unwrap();\r\n            }\r\n            6 => {\r\n                let (l, r) = self.subdivide();\r\n                let (l1, l2, l3) = l.subdivide_3();\r\n                let (r1, r2, r3) = r.subdivide_3();\r\n                storage\r\n                    .try_extend_from_slice(&[r3, r2, r1, l3, l2, l1])\r\n                    .unwrap();\r\n            }\r\n            _ => (),\r\n        }\r\n\r\n        // a limitation of returning 'impl Trait' is that the implementation\r\n        // can only return a single concrete type; that is you cannot return\r\n        // Vec::into_iter() from one branch, and then HashSet::into_iter from\r\n        // another branch.\r\n        //\r\n        // This means we have to get a bit fancy, and have a single concrete\r\n        // type that represents both of our possible cases.\r\n\r\n        let mut storage = if storage.is_empty() {\r\n            None\r\n        } else {\r\n            Some(storage)\r\n        };\r\n\r\n        // used in the fallback case\r\n        let mut i = 0;\r\n        let (a, b, c, d) = self.parameters();\r\n        let dt = 1.0 / n as f64;\r\n        let delta_2 = dt * dt;\r\n        let delta_3 = dt * delta_2;\r\n\r\n        core::iter::from_fn(move || {\r\n            // if storage exists, we use it exclusively\r\n            if let Some(storage) = storage.as_mut() {\r\n                return storage.pop();\r\n            }\r\n\r\n            // if storage does not exist, we are exclusively working down here.\r\n            if i >= n {\r\n                return None;\r\n            }\r\n\r\n            let t1 = i as f64 * dt;\r\n            let t1_2 = t1 * t1;\r\n            let a1 = a * delta_3;\r\n            let b1 = (3.0 * a * t1 + b) * delta_2;\r\n            let c1 = (2.0 * b * t1 + c + 3.0 * a * t1_2) * dt;\r\n            let d1 = a * t1 * t1_2 + b * t1_2 + c * t1 + d;\r\n            let result = CubicBez::from_parameters(a1, b1, c1, d1);\r\n            i += 1;\r\n            Some(result)\r\n        })\r\n    }\r\n\r\n    fn parameters(&self) -> (Vec2, Vec2, Vec2, Vec2) {\r\n        let c = (self.p1 - self.p0) * 3.0;\r\n        let b = (self.p2 - self.p1) * 3.0 - c;\r\n        let d = self.p0.to_vec2();\r\n        let a = self.p3.to_vec2() - d - c - b;\r\n        (a, b, c, d)\r\n    }\r\n\r\n    /// Rust port of cu2qu [calc_cubic_points](https://github.com/fonttools/fonttools/blob/3b9a73ff8379ab49d3ce35aaaaf04b3a7d9d1655/Lib/fontTools/cu2qu/cu2qu.py#L63-L68)\r\n    fn from_parameters(a: Vec2, b: Vec2, c: Vec2, d: Vec2) -> Self {\r\n        let p0 = d.to_point();\r\n        let p1 = c.div_exact(3.0).to_point() + d;\r\n        let p2 = (b + c).div_exact(3.0).to_point() + p1.to_vec2();\r\n        let p3 = (a + d + c + b).to_point();\r\n        CubicBez::new(p0, p1, p2, p3)\r\n    }\r\n\r\n    fn subdivide_3(&self) -> (CubicBez, CubicBez, CubicBez) {\r\n        let (p0, p1, p2, p3) = (\r\n            self.p0.to_vec2(),\r\n            self.p1.to_vec2(),\r\n            self.p2.to_vec2(),\r\n            self.p3.to_vec2(),\r\n        );\r\n        // The original Python cu2qu code here does not use division operator to divide by 27 but\r\n        // instead uses multiplication by the reciprocal 1 / 27. We want to match it exactly\r\n        // to avoid any floating point differences, hence in this particular case we do not use div_exact.\r\n        // I could directly use the Vec2 Div trait (also implemented as multiplication by reciprocal)\r\n        // but I prefer to be explicit here.\r\n        // Source: https://github.com/fonttools/fonttools/blob/85c80be/Lib/fontTools/cu2qu/cu2qu.py#L215-L218\r\n        // See also: https://github.com/linebender/kurbo/issues/272\r\n        let one_27th = 27.0_f64.recip();\r\n        let mid1 = ((8.0 * p0 + 12.0 * p1 + 6.0 * p2 + p3) * one_27th).to_point();\r\n        let deriv1 = (p3 + 3.0 * p2 - 4.0 * p0) * one_27th;\r\n        let mid2 = ((p0 + 6.0 * p1 + 12.0 * p2 + 8.0 * p3) * one_27th).to_point();\r\n        let deriv2 = (4.0 * p3 - 3.0 * p1 - p0) * one_27th;\r\n\r\n        let left = CubicBez::new(\r\n            self.p0,\r\n            (2.0 * p0 + p1).div_exact(3.0).to_point(),\r\n            mid1 - deriv1,\r\n            mid1,\r\n        );\r\n        let mid = CubicBez::new(mid1, mid1 + deriv1, mid2 - deriv2, mid2);\r\n        let right = CubicBez::new(\r\n            mid2,\r\n            mid2 + deriv2,\r\n            (p2 + 2.0 * p3).div_exact(3.0).to_point(),\r\n            self.p3,\r\n        );\r\n        (left, mid, right)\r\n    }\r\n\r\n    /// Does this curve fit inside the given distance from the origin?\r\n    ///\r\n    /// Rust port of cu2qu [cubic_farthest_fit_inside](https://github.com/fonttools/fonttools/blob/3b9a73ff8379ab49d3ce35aaaaf04b3a7d9d1655/Lib/fontTools/cu2qu/cu2qu.py#L281)\r\n    fn fit_inside(&self, distance: f64) -> bool {\r\n        if self.p2.to_vec2().hypot() <= distance && self.p1.to_vec2().hypot() <= distance {\r\n            return true;\r\n        }\r\n        let mid =\r\n            (self.p0.to_vec2() + 3.0 * (self.p1.to_vec2() + self.p2.to_vec2()) + self.p3.to_vec2())\r\n                * 0.125;\r\n        if mid.hypot() > distance {\r\n            return false;\r\n        }\r\n        // Split in two. Note that cu2qu here uses a 3/8 subdivision. I don't know why.\r\n        let (left, right) = self.subdivide();\r\n        left.fit_inside(distance) && right.fit_inside(distance)\r\n    }\r\n\r\n    /// Is this cubic Bezier curve finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.p0.is_finite() && self.p1.is_finite() && self.p2.is_finite() && self.p3.is_finite()\r\n    }\r\n\r\n    /// Is this cubic Bezier curve NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.p0.is_nan() || self.p1.is_nan() || self.p2.is_nan() || self.p3.is_nan()\r\n    }\r\n\r\n    /// Determine the inflection points.\r\n    ///\r\n    /// Return value is t parameter for the inflection points of the curve segment.\r\n    /// There are a maximum of two for a cubic Bézier.\r\n    ///\r\n    /// See <https://www.caffeineowl.com/graphics/2d/vectorial/cubic-inflexion.html>\r\n    /// for the theory.\r\n    pub fn inflections(&self) -> ArrayVec<f64, 2> {\r\n        let a = self.p1 - self.p0;\r\n        let b = (self.p2 - self.p1) - a;\r\n        let c = (self.p3 - self.p0) - 3. * (self.p2 - self.p1);\r\n        solve_quadratic(a.cross(b), a.cross(c), b.cross(c))\r\n            .iter()\r\n            .copied()\r\n            .filter(|t| *t >= 0.0 && *t <= 1.0)\r\n            .collect()\r\n    }\r\n}\r\n\r\n/// An iterator for cubic beziers.\r\npub struct CubicBezIter {\r\n    cubic: CubicBez,\r\n    ix: usize,\r\n}\r\n\r\nimpl Shape for CubicBez {\r\n    type PathElementsIter<'iter> = CubicBezIter;\r\n\r\n    #[inline]\r\n    fn path_elements(&self, _tolerance: f64) -> CubicBezIter {\r\n        CubicBezIter {\r\n            cubic: *self,\r\n            ix: 0,\r\n        }\r\n    }\r\n\r\n    fn area(&self) -> f64 {\r\n        0.0\r\n    }\r\n\r\n    #[inline]\r\n    fn perimeter(&self, accuracy: f64) -> f64 {\r\n        self.arclen(accuracy)\r\n    }\r\n\r\n    fn winding(&self, _pt: Point) -> i32 {\r\n        0\r\n    }\r\n\r\n    #[inline]\r\n    fn bounding_box(&self) -> Rect {\r\n        ParamCurveExtrema::bounding_box(self)\r\n    }\r\n}\r\n\r\nimpl Iterator for CubicBezIter {\r\n    type Item = PathEl;\r\n\r\n    fn next(&mut self) -> Option<PathEl> {\r\n        self.ix += 1;\r\n        match self.ix {\r\n            1 => Some(PathEl::MoveTo(self.cubic.p0)),\r\n            2 => Some(PathEl::CurveTo(self.cubic.p1, self.cubic.p2, self.cubic.p3)),\r\n            _ => None,\r\n        }\r\n    }\r\n}\r\n\r\nimpl ParamCurve for CubicBez {\r\n    #[inline]\r\n    fn eval(&self, t: f64) -> Point {\r\n        let mt = 1.0 - t;\r\n        let v = self.p0.to_vec2() * (mt * mt * mt)\r\n            + (self.p1.to_vec2() * (mt * mt * 3.0)\r\n                + (self.p2.to_vec2() * (mt * 3.0) + self.p3.to_vec2() * t) * t)\r\n                * t;\r\n        v.to_point()\r\n    }\r\n\r\n    fn subsegment(&self, range: Range<f64>) -> CubicBez {\r\n        let (t0, t1) = (range.start, range.end);\r\n        let p0 = self.eval(t0);\r\n        let p3 = self.eval(t1);\r\n        let d = self.deriv();\r\n        let scale = (t1 - t0) * (1.0 / 3.0);\r\n        let p1 = p0 + scale * d.eval(t0).to_vec2();\r\n        let p2 = p3 - scale * d.eval(t1).to_vec2();\r\n        CubicBez { p0, p1, p2, p3 }\r\n    }\r\n\r\n    /// Subdivide into halves, using de Casteljau.\r\n    #[inline]\r\n    fn subdivide(&self) -> (CubicBez, CubicBez) {\r\n        let pm = self.eval(0.5);\r\n        (\r\n            CubicBez::new(\r\n                self.p0,\r\n                self.p0.midpoint(self.p1),\r\n                ((self.p0.to_vec2() + self.p1.to_vec2() * 2.0 + self.p2.to_vec2()) * 0.25)\r\n                    .to_point(),\r\n                pm,\r\n            ),\r\n            CubicBez::new(\r\n                pm,\r\n                ((self.p1.to_vec2() + self.p2.to_vec2() * 2.0 + self.p3.to_vec2()) * 0.25)\r\n                    .to_point(),\r\n                self.p2.midpoint(self.p3),\r\n                self.p3,\r\n            ),\r\n        )\r\n    }\r\n\r\n    #[inline]\r\n    fn start(&self) -> Point {\r\n        self.p0\r\n    }\r\n\r\n    #[inline]\r\n    fn end(&self) -> Point {\r\n        self.p3\r\n    }\r\n}\r\n\r\nimpl ParamCurveDeriv for CubicBez {\r\n    type DerivResult = QuadBez;\r\n\r\n    #[inline]\r\n    fn deriv(&self) -> QuadBez {\r\n        QuadBez::new(\r\n            (3.0 * (self.p1 - self.p0)).to_point(),\r\n            (3.0 * (self.p2 - self.p1)).to_point(),\r\n            (3.0 * (self.p3 - self.p2)).to_point(),\r\n        )\r\n    }\r\n}\r\n\r\nfn arclen_quadrature_core(coeffs: &[(f64, f64)], dm: Vec2, dm1: Vec2, dm2: Vec2) -> f64 {\r\n    coeffs\r\n        .iter()\r\n        .map(|&(wi, xi)| {\r\n            let d = dm + dm2 * (xi * xi);\r\n            let dpx = (d + dm1 * xi).hypot();\r\n            let dmx = (d - dm1 * xi).hypot();\r\n            (2.25f64.sqrt() * wi) * (dpx + dmx)\r\n        })\r\n        .sum::<f64>()\r\n}\r\n\r\nfn arclen_rec(c: &CubicBez, accuracy: f64, depth: usize) -> f64 {\r\n    let d03 = c.p3 - c.p0;\r\n    let d01 = c.p1 - c.p0;\r\n    let d12 = c.p2 - c.p1;\r\n    let d23 = c.p3 - c.p2;\r\n    let lp_lc = d01.hypot() + d12.hypot() + d23.hypot() - d03.hypot();\r\n    let dd1 = d12 - d01;\r\n    let dd2 = d23 - d12;\r\n    // It might be faster to do direct multiplies, the data dependencies would be shorter.\r\n    // The following values don't have the factor of 3 for first deriv\r\n    let dm = 0.25 * (d01 + d23) + 0.5 * d12; // first derivative at midpoint\r\n    let dm1 = 0.5 * (dd2 + dd1); // second derivative at midpoint\r\n    let dm2 = 0.25 * (dd2 - dd1); // 0.5 * (third derivative at midpoint)\r\n\r\n    let est = GAUSS_LEGENDRE_COEFFS_8\r\n        .iter()\r\n        .map(|&(wi, xi)| {\r\n            wi * {\r\n                let d_norm2 = (dm + dm1 * xi + dm2 * (xi * xi)).hypot2();\r\n                let dd_norm2 = (dm1 + dm2 * (2.0 * xi)).hypot2();\r\n                dd_norm2 / d_norm2\r\n            }\r\n        })\r\n        .sum::<f64>();\r\n    let est_gauss8_error = (est.powi(3) * 2.5e-6).min(3e-2) * lp_lc;\r\n    if est_gauss8_error < accuracy {\r\n        return arclen_quadrature_core(GAUSS_LEGENDRE_COEFFS_8_HALF, dm, dm1, dm2);\r\n    }\r\n    let est_gauss16_error = (est.powi(6) * 1.5e-11).min(9e-3) * lp_lc;\r\n    if est_gauss16_error < accuracy {\r\n        return arclen_quadrature_core(GAUSS_LEGENDRE_COEFFS_16_HALF, dm, dm1, dm2);\r\n    }\r\n    let est_gauss24_error = (est.powi(9) * 3.5e-16).min(3.5e-3) * lp_lc;\r\n    if est_gauss24_error < accuracy || depth >= 20 {\r\n        return arclen_quadrature_core(GAUSS_LEGENDRE_COEFFS_24_HALF, dm, dm1, dm2);\r\n    }\r\n    let (c0, c1) = c.subdivide();\r\n    arclen_rec(&c0, accuracy * 0.5, depth + 1) + arclen_rec(&c1, accuracy * 0.5, depth + 1)\r\n}\r\n\r\nimpl ParamCurveArclen for CubicBez {\r\n    /// Arclength of a cubic Bézier segment.\r\n    ///\r\n    /// This is an adaptive subdivision approach using Legendre-Gauss quadrature\r\n    /// in the base case, and an error estimate to decide when to subdivide.\r\n    fn arclen(&self, accuracy: f64) -> f64 {\r\n        arclen_rec(self, accuracy, 0)\r\n    }\r\n}\r\n\r\nimpl ParamCurveArea for CubicBez {\r\n    #[inline]\r\n    fn signed_area(&self) -> f64 {\r\n        (self.p0.x * (6.0 * self.p1.y + 3.0 * self.p2.y + self.p3.y)\r\n            + 3.0\r\n                * (self.p1.x * (-2.0 * self.p0.y + self.p2.y + self.p3.y)\r\n                    - self.p2.x * (self.p0.y + self.p1.y - 2.0 * self.p3.y))\r\n            - self.p3.x * (self.p0.y + 3.0 * self.p1.y + 6.0 * self.p2.y))\r\n            * (1.0 / 20.0)\r\n    }\r\n}\r\n\r\nimpl ParamCurveNearest for CubicBez {\r\n    /// Find the nearest point, using subdivision.\r\n    fn nearest(&self, p: Point, accuracy: f64) -> Nearest {\r\n        let mut best_r = None;\r\n        let mut best_t = 0.0;\r\n        for (t0, t1, q) in self.to_quads(accuracy) {\r\n            let nearest = q.nearest(p, accuracy);\r\n            if best_r\r\n                .map(|best_r| nearest.distance_sq < best_r)\r\n                .unwrap_or(true)\r\n            {\r\n                best_t = t0 + nearest.t * (t1 - t0);\r\n                best_r = Some(nearest.distance_sq);\r\n            }\r\n        }\r\n        Nearest {\r\n            t: best_t,\r\n            distance_sq: best_r.unwrap(),\r\n        }\r\n    }\r\n}\r\n\r\nimpl ParamCurveCurvature for CubicBez {}\r\n\r\nimpl ParamCurveExtrema for CubicBez {\r\n    fn extrema(&self) -> ArrayVec<f64, MAX_EXTREMA> {\r\n        fn one_coord(result: &mut ArrayVec<f64, MAX_EXTREMA>, d0: f64, d1: f64, d2: f64) {\r\n            let a = d0 - 2.0 * d1 + d2;\r\n            let b = 2.0 * (d1 - d0);\r\n            let c = d0;\r\n            let roots = solve_quadratic(c, b, a);\r\n            for &t in &roots {\r\n                if t > 0.0 && t < 1.0 {\r\n                    result.push(t);\r\n                }\r\n            }\r\n        }\r\n        let mut result = ArrayVec::new();\r\n        let d0 = self.p1 - self.p0;\r\n        let d1 = self.p2 - self.p1;\r\n        let d2 = self.p3 - self.p2;\r\n        one_coord(&mut result, d0.x, d1.x, d2.x);\r\n        one_coord(&mut result, d0.y, d1.y, d2.y);\r\n        result.sort_by(|a, b| a.partial_cmp(b).unwrap());\r\n        result\r\n    }\r\n}\r\n\r\nimpl Mul<CubicBez> for Affine {\r\n    type Output = CubicBez;\r\n\r\n    #[inline]\r\n    fn mul(self, c: CubicBez) -> CubicBez {\r\n        CubicBez {\r\n            p0: self * c.p0,\r\n            p1: self * c.p1,\r\n            p2: self * c.p2,\r\n            p3: self * c.p3,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Iterator for ToQuads {\r\n    type Item = (f64, f64, QuadBez);\r\n\r\n    fn next(&mut self) -> Option<(f64, f64, QuadBez)> {\r\n        if self.i == self.n {\r\n            return None;\r\n        }\r\n        let t0 = self.i as f64 / self.n as f64;\r\n        let t1 = (self.i + 1) as f64 / self.n as f64;\r\n        let seg = self.c.subsegment(t0..t1);\r\n        let p1x2 = 3.0 * seg.p1.to_vec2() - seg.p0.to_vec2();\r\n        let p2x2 = 3.0 * seg.p2.to_vec2() - seg.p3.to_vec2();\r\n        let result = QuadBez::new(seg.p0, ((p1x2 + p2x2) / 4.0).to_point(), seg.p3);\r\n        self.i += 1;\r\n        Some((t0, t1, result))\r\n    }\r\n\r\n    fn size_hint(&self) -> (usize, Option<usize>) {\r\n        let remaining = self.n - self.i;\r\n        (remaining, Some(remaining))\r\n    }\r\n}\r\n\r\n/// Convert multiple cubic Bézier curves to quadratic splines.\r\n///\r\n/// Ensures that the resulting splines have the same number of control points.\r\n///\r\n/// Rust port of cu2qu [cubic_approx_quadratic](https://github.com/fonttools/fonttools/blob/3b9a73ff8379ab49d3ce35aaaaf04b3a7d9d1655/Lib/fontTools/cu2qu/cu2qu.py#L322)\r\npub fn cubics_to_quadratic_splines(curves: &[CubicBez], accuracy: f64) -> Option<Vec<QuadSpline>> {\r\n    let mut result = Vec::new();\r\n    let mut split_order = 0;\r\n\r\n    while split_order <= MAX_SPLINE_SPLIT {\r\n        split_order += 1;\r\n        result.clear();\r\n\r\n        for curve in curves {\r\n            match curve.approx_spline_n(split_order, accuracy) {\r\n                Some(spline) => result.push(spline),\r\n                None => break,\r\n            }\r\n        }\r\n\r\n        if result.len() == curves.len() {\r\n            return Some(result);\r\n        }\r\n    }\r\n    None\r\n}\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{\r\n        cubics_to_quadratic_splines, Affine, CubicBez, Nearest, ParamCurve, ParamCurveArclen,\r\n        ParamCurveArea, ParamCurveDeriv, ParamCurveExtrema, ParamCurveNearest, Point, QuadBez,\r\n        QuadSpline,\r\n    };\r\n\r\n    #[test]\r\n    fn cubicbez_deriv() {\r\n        // y = x^2\r\n        let c = CubicBez::new(\r\n            (0.0, 0.0),\r\n            (1.0 / 3.0, 0.0),\r\n            (2.0 / 3.0, 1.0 / 3.0),\r\n            (1.0, 1.0),\r\n        );\r\n        let deriv = c.deriv();\r\n\r\n        let n = 10;\r\n        for i in 0..=n {\r\n            let t = (i as f64) * (n as f64).recip();\r\n            let delta = 1e-6;\r\n            let p = c.eval(t);\r\n            let p1 = c.eval(t + delta);\r\n            let d_approx = (p1 - p) * delta.recip();\r\n            let d = deriv.eval(t).to_vec2();\r\n            assert!((d - d_approx).hypot() < delta * 2.0);\r\n        }\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_arclen() {\r\n        // y = x^2\r\n        let c = CubicBez::new(\r\n            (0.0, 0.0),\r\n            (1.0 / 3.0, 0.0),\r\n            (2.0 / 3.0, 1.0 / 3.0),\r\n            (1.0, 1.0),\r\n        );\r\n        let true_arclen = 0.5 * 5.0f64.sqrt() + 0.25 * (2.0 + 5.0f64.sqrt()).ln();\r\n        for i in 0..12 {\r\n            let accuracy = 0.1f64.powi(i);\r\n            let error = c.arclen(accuracy) - true_arclen;\r\n            assert!(error.abs() < accuracy);\r\n        }\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_inv_arclen() {\r\n        // y = x^2 / 100\r\n        let c = CubicBez::new(\r\n            (0.0, 0.0),\r\n            (100.0 / 3.0, 0.0),\r\n            (200.0 / 3.0, 100.0 / 3.0),\r\n            (100.0, 100.0),\r\n        );\r\n        let true_arclen = 100.0 * (0.5 * 5.0f64.sqrt() + 0.25 * (2.0 + 5.0f64.sqrt()).ln());\r\n        for i in 0..12 {\r\n            let accuracy = 0.1f64.powi(i);\r\n            let n = 10;\r\n            for j in 0..=n {\r\n                let arc = (j as f64) * ((n as f64).recip() * true_arclen);\r\n                let t = c.inv_arclen(arc, accuracy * 0.5);\r\n                let actual_arc = c.subsegment(0.0..t).arclen(accuracy * 0.5);\r\n                assert!(\r\n                    (arc - actual_arc).abs() < accuracy,\r\n                    \"at accuracy {accuracy:e}, wanted {actual_arc} got {arc}\"\r\n                );\r\n            }\r\n        }\r\n        // corner case: user passes accuracy larger than total arc length\r\n        let accuracy = true_arclen * 1.1;\r\n        let arc = true_arclen * 0.5;\r\n        let t = c.inv_arclen(arc, accuracy);\r\n        let actual_arc = c.subsegment(0.0..t).arclen(accuracy);\r\n        assert!(\r\n            (arc - actual_arc).abs() < 2.0 * accuracy,\r\n            \"at accuracy {accuracy:e}, want {actual_arc} got {arc}\"\r\n        );\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_inv_arclen_accuracy() {\r\n        let c = CubicBez::new((0.2, 0.73), (0.35, 1.08), (0.85, 1.08), (1.0, 0.73));\r\n        let true_t = c.inv_arclen(0.5, 1e-12);\r\n        for i in 1..12 {\r\n            let accuracy = (0.1f64).powi(i);\r\n            let approx_t = c.inv_arclen(0.5, accuracy);\r\n            assert!((approx_t - true_t).abs() <= accuracy);\r\n        }\r\n    }\r\n\r\n    #[test]\r\n    #[allow(clippy::float_cmp)]\r\n    fn cubicbez_signed_area_linear() {\r\n        // y = 1 - x\r\n        let c = CubicBez::new(\r\n            (1.0, 0.0),\r\n            (2.0 / 3.0, 1.0 / 3.0),\r\n            (1.0 / 3.0, 2.0 / 3.0),\r\n            (0.0, 1.0),\r\n        );\r\n        let epsilon = 1e-12;\r\n        assert_eq!((Affine::rotate(0.5) * c).signed_area(), 0.5);\r\n        assert!(((Affine::rotate(0.5) * c).signed_area() - 0.5).abs() < epsilon);\r\n        assert!(((Affine::translate((0.0, 1.0)) * c).signed_area() - 1.0).abs() < epsilon);\r\n        assert!(((Affine::translate((1.0, 0.0)) * c).signed_area() - 1.0).abs() < epsilon);\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_signed_area() {\r\n        // y = 1 - x^3\r\n        let c = CubicBez::new((1.0, 0.0), (2.0 / 3.0, 1.0), (1.0 / 3.0, 1.0), (0.0, 1.0));\r\n        let epsilon = 1e-12;\r\n        assert!((c.signed_area() - 0.75).abs() < epsilon);\r\n        assert!(((Affine::rotate(0.5) * c).signed_area() - 0.75).abs() < epsilon);\r\n        assert!(((Affine::translate((0.0, 1.0)) * c).signed_area() - 1.25).abs() < epsilon);\r\n        assert!(((Affine::translate((1.0, 0.0)) * c).signed_area() - 1.25).abs() < epsilon);\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_nearest() {\r\n        fn verify(result: Nearest, expected: f64) {\r\n            assert!(\r\n                (result.t - expected).abs() < 1e-6,\r\n                \"got {result:?} expected {expected}\"\r\n            );\r\n        }\r\n        // y = x^3\r\n        let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 0.0), (1.0, 1.0));\r\n        verify(c.nearest((0.1, 0.001).into(), 1e-6), 0.1);\r\n        verify(c.nearest((0.2, 0.008).into(), 1e-6), 0.2);\r\n        verify(c.nearest((0.3, 0.027).into(), 1e-6), 0.3);\r\n        verify(c.nearest((0.4, 0.064).into(), 1e-6), 0.4);\r\n        verify(c.nearest((0.5, 0.125).into(), 1e-6), 0.5);\r\n        verify(c.nearest((0.6, 0.216).into(), 1e-6), 0.6);\r\n        verify(c.nearest((0.7, 0.343).into(), 1e-6), 0.7);\r\n        verify(c.nearest((0.8, 0.512).into(), 1e-6), 0.8);\r\n        verify(c.nearest((0.9, 0.729).into(), 1e-6), 0.9);\r\n        verify(c.nearest((1.0, 1.0).into(), 1e-6), 1.0);\r\n        verify(c.nearest((1.1, 1.1).into(), 1e-6), 1.0);\r\n        verify(c.nearest((-0.1, 0.0).into(), 1e-6), 0.0);\r\n        let a = Affine::rotate(0.5);\r\n        verify((a * c).nearest(a * Point::new(0.1, 0.001), 1e-6), 0.1);\r\n    }\r\n\r\n    // ensure to_quads returns something given colinear points\r\n    #[test]\r\n    fn degenerate_to_quads() {\r\n        let c = CubicBez::new((0., 9.), (6., 6.), (12., 3.0), (18., 0.0));\r\n        let quads = c.to_quads(1e-6).collect::<Vec<_>>();\r\n        assert_eq!(quads.len(), 1, \"{:?}\", &quads);\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_extrema() {\r\n        // y = x^2\r\n        let q = CubicBez::new((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0));\r\n        let extrema = q.extrema();\r\n        assert_eq!(extrema.len(), 1);\r\n        assert!((extrema[0] - 0.5).abs() < 1e-6);\r\n\r\n        let q = CubicBez::new((0.4, 0.5), (0.0, 1.0), (1.0, 0.0), (0.5, 0.4));\r\n        let extrema = q.extrema();\r\n        assert_eq!(extrema.len(), 4);\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_toquads() {\r\n        // y = x^3\r\n        let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 0.0), (1.0, 1.0));\r\n        for i in 0..10 {\r\n            let accuracy = 0.1f64.powi(i);\r\n            let mut worst: f64 = 0.0;\r\n            for (_count, (t0, t1, q)) in c.to_quads(accuracy).enumerate() {\r\n                let epsilon = 1e-12;\r\n                assert!((q.start() - c.eval(t0)).hypot() < epsilon);\r\n                assert!((q.end() - c.eval(t1)).hypot() < epsilon);\r\n                let n = 4;\r\n                for j in 0..=n {\r\n                    let t = (j as f64) * (n as f64).recip();\r\n                    let p = q.eval(t);\r\n                    let err = (p.y - p.x.powi(3)).abs();\r\n                    worst = worst.max(err);\r\n                    assert!(err < accuracy, \"got {err} wanted {accuracy}\");\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_approx_spline() {\r\n        let c1 = CubicBez::new(\r\n            (550.0, 258.0),\r\n            (1044.0, 482.0),\r\n            (2029.0, 1841.0),\r\n            (1934.0, 1554.0),\r\n        );\r\n\r\n        let quad = c1.try_approx_quadratic(344.0);\r\n        let expected = QuadBez::new(\r\n            Point::new(550.0, 258.0),\r\n            Point::new(1673.665720592873, 767.5164401068898),\r\n            Point::new(1934.0, 1554.0),\r\n        );\r\n        assert!(quad.is_some());\r\n        assert_eq!(quad.unwrap(), expected);\r\n\r\n        let quad = c1.try_approx_quadratic(343.0);\r\n        assert!(quad.is_none());\r\n\r\n        let spline = c1.approx_spline_n(2, 343.0);\r\n        assert!(spline.is_some());\r\n        let spline = spline.unwrap();\r\n        let expected = vec![\r\n            Point::new(550.0, 258.0),\r\n            Point::new(920.5, 426.0),\r\n            Point::new(2005.25, 1769.25),\r\n            Point::new(1934.0, 1554.0),\r\n        ];\r\n        assert_eq!(spline.points().len(), expected.len());\r\n        for (got, &wanted) in spline.points().iter().zip(expected.iter()) {\r\n            assert!(got.distance(wanted) < 5.0)\r\n        }\r\n\r\n        let spline = c1.approx_spline(5.0);\r\n        let expected = vec![\r\n            Point::new(550.0, 258.0),\r\n            Point::new(673.5, 314.0),\r\n            Point::new(984.8777777777776, 584.2666666666667),\r\n            Point::new(1312.6305555555557, 927.825),\r\n            Point::new(1613.1194444444443, 1267.425),\r\n            Point::new(1842.7055555555555, 1525.8166666666666),\r\n            Point::new(1957.75, 1625.75),\r\n            Point::new(1934.0, 1554.0),\r\n        ];\r\n        assert!(spline.is_some());\r\n        let spline = spline.unwrap();\r\n        assert_eq!(spline.points().len(), expected.len());\r\n        for (got, &wanted) in spline.points().iter().zip(expected.iter()) {\r\n            assert!(got.distance(wanted) < 5.0)\r\n        }\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_cubics_to_quadratic_splines() {\r\n        let curves = vec![\r\n            CubicBez::new(\r\n                (550.0, 258.0),\r\n                (1044.0, 482.0),\r\n                (2029.0, 1841.0),\r\n                (1934.0, 1554.0),\r\n            ),\r\n            CubicBez::new(\r\n                (859.0, 384.0),\r\n                (1998.0, 116.0),\r\n                (1596.0, 1772.0),\r\n                (8.0, 1824.0),\r\n            ),\r\n            CubicBez::new(\r\n                (1090.0, 937.0),\r\n                (418.0, 1300.0),\r\n                (125.0, 91.0),\r\n                (104.0, 37.0),\r\n            ),\r\n        ];\r\n        let converted = cubics_to_quadratic_splines(&curves, 5.0);\r\n        assert!(converted.is_some());\r\n        let converted = converted.unwrap();\r\n        assert_eq!(converted[0].points().len(), 8);\r\n        assert_eq!(converted[1].points().len(), 8);\r\n        assert_eq!(converted[2].points().len(), 8);\r\n        assert!(converted[0].points()[1].distance(Point::new(673.5, 314.0)) < 0.0001);\r\n        assert!(\r\n            converted[0].points()[2].distance(Point::new(88639.0 / 90.0, 52584.0 / 90.0)) < 0.0001\r\n        );\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_approx_spline_div_exact() {\r\n        // Ensure rounding behavior for division matches fonttools\r\n        // cu2qu.\r\n        // See <https://github.com/linebender/kurbo/issues/272>\r\n        let cubic = CubicBez::new(\r\n            Point::new(408.0, 321.0),\r\n            Point::new(408.0, 452.0),\r\n            Point::new(342.0, 560.0),\r\n            Point::new(260.0, 560.0),\r\n        );\r\n        let spline = cubic.approx_spline(1.0).unwrap();\r\n        assert_eq!(\r\n            spline.points(),\r\n            &[\r\n                Point::new(408.0, 321.0),\r\n                // Previous behavior produced 386.49999999999994 for the\r\n                // y coordinate leading to inconsistent rounding.\r\n                Point::new(408.0, 386.5),\r\n                Point::new(368.16666666666663, 495.0833333333333),\r\n                Point::new(301.0, 560.0),\r\n                Point::new(260.0, 560.0)\r\n            ]\r\n        )\r\n    }\r\n\r\n    #[test]\r\n    fn cubicbez_inflections() {\r\n        let c = CubicBez::new((0., 0.), (0.8, 1.), (0.2, 1.), (1., 0.));\r\n        let inflections = c.inflections();\r\n        assert_eq!(inflections.len(), 2);\r\n        assert!((inflections[0] - 0.311018).abs() < 1e-6);\r\n        assert!((inflections[1] - 0.688982).abs() < 1e-6);\r\n        let c = CubicBez::new((0., 0.), (1., 1.), (2., -1.), (3., 0.));\r\n        let inflections = c.inflections();\r\n        assert_eq!(inflections.len(), 1);\r\n        assert!((inflections[0] - 0.5).abs() < 1e-6);\r\n        let c = CubicBez::new((0., 0.), (1., 1.), (2., 1.), (3., 0.));\r\n        let inflections = c.inflections();\r\n        assert_eq!(inflections.len(), 0);\r\n    }\r\n\r\n    #[test]\r\n    fn cubic_to_quadratic_matches_python() {\r\n        // from https://github.com/googlefonts/fontmake-rs/issues/217\r\n        let cubic = CubicBez {\r\n            p0: (796.0, 319.0).into(),\r\n            p1: (727.0, 314.0).into(),\r\n            p2: (242.0, 303.0).into(),\r\n            p3: (106.0, 303.0).into(),\r\n        };\r\n\r\n        // FontTools can approximate this curve successfully in 7 splits, we can too\r\n        assert!(cubic.approx_spline_n(7, 1.0).is_some());\r\n\r\n        // FontTools can solve this with accuracy 0.001, we can too\r\n        assert!(cubics_to_quadratic_splines(&[cubic], 0.001).is_some());\r\n    }\r\n\r\n    #[test]\r\n    fn cubics_to_quadratic_splines_matches_python() {\r\n        // https://github.com/linebender/kurbo/pull/273\r\n        let light = CubicBez::new((378., 608.), (378., 524.), (355., 455.), (266., 455.));\r\n        let regular = CubicBez::new((367., 607.), (367., 511.), (338., 472.), (243., 472.));\r\n        let bold = CubicBez::new(\r\n            (372.425, 593.05),\r\n            (372.425, 524.95),\r\n            (355.05, 485.95),\r\n            (274., 485.95),\r\n        );\r\n        let qsplines = cubics_to_quadratic_splines(&[light, regular, bold], 1.0).unwrap();\r\n        assert_eq!(\r\n            qsplines,\r\n            [\r\n                QuadSpline::new(vec![\r\n                    (378.0, 608.0).into(),\r\n                    (378.0, 566.0).into(),\r\n                    (359.0833333333333, 496.5).into(),\r\n                    (310.5, 455.0).into(),\r\n                    (266.0, 455.0).into(),\r\n                ]),\r\n                QuadSpline::new(vec![\r\n                    (367.0, 607.0).into(),\r\n                    (367.0, 559.0).into(),\r\n                    // Previous behavior produced 496.5 for the y coordinate\r\n                    (344.5833333333333, 499.49999999999994).into(),\r\n                    (290.5, 472.0).into(),\r\n                    (243.0, 472.0).into(),\r\n                ]),\r\n                QuadSpline::new(vec![\r\n                    (372.425, 593.05).into(),\r\n                    (372.425, 559.0).into(),\r\n                    (356.98333333333335, 511.125).into(),\r\n                    (314.525, 485.95).into(),\r\n                    (274.0, 485.95).into(),\r\n                ]),\r\n            ]\r\n        )\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/ellipse.rs",
      "sha256": "908b1a43b6c9c5ed7e2a26fa10e4a1e97fb3fb6951c24f549eea71857f1b5aee",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Implementation of ellipse shape.\r\n\r\nuse core::f64::consts::PI;\r\nuse core::{\r\n    iter,\r\n    ops::{Add, Mul, Sub},\r\n};\r\n\r\nuse crate::{Affine, Arc, ArcAppendIter, Circle, PathEl, Point, Rect, Shape, Size, Vec2};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// An ellipse.\r\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct Ellipse {\r\n    /// All ellipses can be represented as an affine map of the unit circle,\r\n    /// centred at (0, 0). Therefore we can store the ellipse as an affine map,\r\n    /// with the implication that it be applied to the unit circle to recover the\r\n    /// actual shape.\r\n    inner: Affine,\r\n}\r\n\r\nimpl Ellipse {\r\n    /// Create A new ellipse with a given center, radii, and rotation.\r\n    ///\r\n    /// The returned ellipse will be the result of taking a circle, stretching\r\n    /// it by the `radii` along the x and y axes, then rotating it from the\r\n    /// x asix by `rotation` radians, before finally translating the center\r\n    /// to `center`.\r\n    ///\r\n    /// Rotation is clockwise in a y-down coordinate system. For more on\r\n    /// rotation, see [`Affine::rotate`].\r\n    #[inline]\r\n    pub fn new(center: impl Into<Point>, radii: impl Into<Vec2>, x_rotation: f64) -> Ellipse {\r\n        let Point { x: cx, y: cy } = center.into();\r\n        let Vec2 { x: rx, y: ry } = radii.into();\r\n        Ellipse::private_new(Vec2 { x: cx, y: cy }, rx, ry, x_rotation)\r\n    }\r\n\r\n    /// Returns the largest ellipse that can be bounded by this [`Rect`].\r\n    ///\r\n    /// This uses the absolute width and height of the rectangle.\r\n    ///\r\n    /// This ellipse is always axis-aligned; to apply rotation you can call\r\n    /// [`with_rotation`] with the result.\r\n    ///\r\n    /// [`with_rotation`]: Ellipse::with_rotation\r\n    #[inline]\r\n    pub fn from_rect(rect: Rect) -> Self {\r\n        let center = rect.center().to_vec2();\r\n        let Size { width, height } = rect.size() / 2.0;\r\n        Ellipse::private_new(center, width, height, 0.0)\r\n    }\r\n\r\n    /// Create an ellipse from an affine transformation of the unit circle.\r\n    #[inline]\r\n    pub fn from_affine(affine: Affine) -> Self {\r\n        Ellipse { inner: affine }\r\n    }\r\n\r\n    /// Create a new `Ellipse` centered on the provided point.\r\n    #[inline]\r\n    #[must_use]\r\n    pub fn with_center(self, new_center: Point) -> Ellipse {\r\n        let Point { x: cx, y: cy } = new_center;\r\n        Ellipse {\r\n            inner: self.inner.with_translation(Vec2 { x: cx, y: cy }),\r\n        }\r\n    }\r\n\r\n    /// Create a new `Ellipse` with the provided radii.\r\n    #[must_use]\r\n    pub fn with_radii(self, new_radii: Vec2) -> Ellipse {\r\n        let rotation = self.inner.svd().1;\r\n        let translation = self.inner.translation();\r\n        Ellipse::private_new(translation, new_radii.x, new_radii.y, rotation)\r\n    }\r\n\r\n    /// Create a new `Ellipse`, with the rotation replaced by `rotation`\r\n    /// radians.\r\n    ///\r\n    /// The rotation is clockwise, for a y-down coordinate system. For more\r\n    /// on rotation, See [`Affine::rotate`].\r\n    #[must_use]\r\n    pub fn with_rotation(self, rotation: f64) -> Ellipse {\r\n        let scale = self.inner.svd().0;\r\n        let translation = self.inner.translation();\r\n        Ellipse::private_new(translation, scale.x, scale.y, rotation)\r\n    }\r\n\r\n    #[deprecated(since = \"0.7.0\", note = \"use with_rotation instead\")]\r\n    #[must_use]\r\n    #[doc(hidden)]\r\n    pub fn with_x_rotation(self, rotation_radians: f64) -> Ellipse {\r\n        self.with_rotation(rotation_radians)\r\n    }\r\n\r\n    /// This gives us an internal method without any type conversions.\r\n    #[inline]\r\n    fn private_new(center: Vec2, scale_x: f64, scale_y: f64, x_rotation: f64) -> Ellipse {\r\n        // Since the circle is symmetric about the x and y axes, using absolute values for the\r\n        // radii results in the same ellipse. For simplicity we make this change here.\r\n        Ellipse {\r\n            inner: Affine::translate(center)\r\n                * Affine::rotate(x_rotation)\r\n                * Affine::scale_non_uniform(scale_x.abs(), scale_y.abs()),\r\n        }\r\n    }\r\n\r\n    // Getters and setters.\r\n\r\n    /// Returns the center of this ellipse.\r\n    #[inline]\r\n    pub fn center(&self) -> Point {\r\n        let Vec2 { x: cx, y: cy } = self.inner.translation();\r\n        Point { x: cx, y: cy }\r\n    }\r\n\r\n    /// Returns the two radii of this ellipse.\r\n    ///\r\n    /// The first number is the horizontal radius and the second is the vertical\r\n    /// radius, before rotation.\r\n    pub fn radii(&self) -> Vec2 {\r\n        self.inner.svd().0\r\n    }\r\n\r\n    /// The ellipse's rotation, in radians.\r\n    ///\r\n    /// This allows all possible ellipses to be drawn by always starting with\r\n    /// an ellipse with the two radii on the x and y axes.\r\n    pub fn rotation(&self) -> f64 {\r\n        self.inner.svd().1\r\n    }\r\n\r\n    /// Returns the radii and the rotation of this ellipse.\r\n    ///\r\n    /// Equivalent to `(self.radii(), self.rotation())` but more efficient.\r\n    pub fn radii_and_rotation(&self) -> (Vec2, f64) {\r\n        self.inner.svd()\r\n    }\r\n\r\n    /// Is this ellipse finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.inner.is_finite()\r\n    }\r\n\r\n    /// Is this ellipse NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.inner.is_nan()\r\n    }\r\n\r\n    #[doc(hidden)]\r\n    #[deprecated(since = \"0.7.0\", note = \"use rotation() instead\")]\r\n    pub fn x_rotation(&self) -> f64 {\r\n        self.rotation()\r\n    }\r\n}\r\n\r\nimpl Add<Vec2> for Ellipse {\r\n    type Output = Ellipse;\r\n\r\n    /// In this context adding a `Vec2` applies the corresponding translation to the ellipse.\r\n    #[inline]\r\n    #[allow(clippy::suspicious_arithmetic_impl)]\r\n    fn add(self, v: Vec2) -> Ellipse {\r\n        Ellipse {\r\n            inner: Affine::translate(v) * self.inner,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Sub<Vec2> for Ellipse {\r\n    type Output = Ellipse;\r\n\r\n    /// In this context subtracting a `Vec2` applies the corresponding translation to the ellipse.\r\n    #[inline]\r\n    fn sub(self, v: Vec2) -> Ellipse {\r\n        Ellipse {\r\n            inner: Affine::translate(-v) * self.inner,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Mul<Ellipse> for Affine {\r\n    type Output = Ellipse;\r\n    fn mul(self, other: Ellipse) -> Self::Output {\r\n        Ellipse {\r\n            inner: self * other.inner,\r\n        }\r\n    }\r\n}\r\n\r\nimpl From<Circle> for Ellipse {\r\n    fn from(circle: Circle) -> Self {\r\n        Ellipse::new(circle.center, Vec2::splat(circle.radius), 0.0)\r\n    }\r\n}\r\n\r\nimpl Shape for Ellipse {\r\n    type PathElementsIter<'iter> = iter::Chain<iter::Once<PathEl>, ArcAppendIter>;\r\n\r\n    fn path_elements(&self, tolerance: f64) -> Self::PathElementsIter<'_> {\r\n        let (radii, x_rotation) = self.inner.svd();\r\n        Arc {\r\n            center: self.center(),\r\n            radii,\r\n            start_angle: 0.0,\r\n            sweep_angle: 2.0 * PI,\r\n            x_rotation,\r\n        }\r\n        .path_elements(tolerance)\r\n    }\r\n\r\n    #[inline]\r\n    fn area(&self) -> f64 {\r\n        let Vec2 { x, y } = self.radii();\r\n        PI * x * y\r\n    }\r\n\r\n    #[inline]\r\n    fn perimeter(&self, accuracy: f64) -> f64 {\r\n        // TODO rather than delegate to the bezier path, it is possible to use various series\r\n        // expansions to compute the perimeter to any accuracy. I believe Ramanujan authored the\r\n        // quickest to converge. See\r\n        // https://www.mathematica-journal.com/2009/11/23/on-the-perimeter-of-an-ellipse/\r\n        // and https://en.wikipedia.org/wiki/Ellipse#Circumference\r\n        //\r\n        self.path_segments(0.1).perimeter(accuracy)\r\n    }\r\n\r\n    fn winding(&self, pt: Point) -> i32 {\r\n        // Strategy here is to apply the inverse map to the point and see if it is in the unit\r\n        // circle.\r\n        let inv = self.inner.inverse();\r\n        if (inv * pt).to_vec2().hypot2() < 1.0 {\r\n            1\r\n        } else {\r\n            0\r\n        }\r\n    }\r\n\r\n    // Compute a tight bounding box of the ellipse.\r\n    //\r\n    // See https://www.iquilezles.org/www/articles/ellipses/ellipses.htm. We can get the two\r\n    // radius vectors by applying the affine map to the two impulses (1, 0) and (0, 1) which gives\r\n    // (a, b) and (c, d) if the affine map is\r\n    //\r\n    //  a | c | e\r\n    // -----------\r\n    //  b | d | f\r\n    //\r\n    //  We can then use the method in the link with the translation to get the bounding box.\r\n    #[inline]\r\n    fn bounding_box(&self) -> Rect {\r\n        let aff = self.inner.as_coeffs();\r\n        let a2 = aff[0] * aff[0];\r\n        let b2 = aff[1] * aff[1];\r\n        let c2 = aff[2] * aff[2];\r\n        let d2 = aff[3] * aff[3];\r\n        let cx = aff[4];\r\n        let cy = aff[5];\r\n        let range_x = (a2 + c2).sqrt();\r\n        let range_y = (b2 + d2).sqrt();\r\n        Rect {\r\n            x0: cx - range_x,\r\n            y0: cy - range_y,\r\n            x1: cx + range_x,\r\n            y1: cy + range_y,\r\n        }\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{Ellipse, Point, Shape};\r\n    use std::f64::consts::PI;\r\n\r\n    fn assert_approx_eq(x: f64, y: f64) {\r\n        // Note: we might want to be more rigorous in testing the accuracy\r\n        // of the conversion into Béziers. But this seems good enough.\r\n        assert!((x - y).abs() < 1e-7, \"{x} != {y}\");\r\n    }\r\n\r\n    #[test]\r\n    fn area_sign() {\r\n        let center = Point::new(5.0, 5.0);\r\n        let e = Ellipse::new(center, (5.0, 5.0), 1.0);\r\n        assert_approx_eq(e.area(), 25.0 * PI);\r\n        let e = Ellipse::new(center, (5.0, 10.0), 1.0);\r\n        assert_approx_eq(e.area(), 50.0 * PI);\r\n\r\n        assert_eq!(e.winding(center), 1);\r\n\r\n        let p = e.to_path(1e-9);\r\n        assert_approx_eq(e.area(), p.area());\r\n        assert_eq!(e.winding(center), p.winding(center));\r\n\r\n        let e_neg_radius = Ellipse::new(center, (-5.0, 10.0), 1.0);\r\n        assert_approx_eq(e_neg_radius.area(), 50.0 * PI);\r\n\r\n        assert_eq!(e_neg_radius.winding(center), 1);\r\n\r\n        let p_neg_radius = e_neg_radius.to_path(1e-9);\r\n        assert_approx_eq(e_neg_radius.area(), p_neg_radius.area());\r\n        assert_eq!(e_neg_radius.winding(center), p_neg_radius.winding(center));\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/fit.rs",
      "sha256": "2eded2d6b2bc5e18c563b224fc805c49fb0915dc87369ea8ba47b0647444343e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! An implementation of cubic Bézier curve fitting based on a quartic\r\n//! solver making signed area and moment match the source curve.\r\n\r\nuse core::ops::Range;\r\n\r\nuse alloc::vec::Vec;\r\n\r\nuse arrayvec::ArrayVec;\r\n\r\nuse crate::{\r\n    common::{\r\n        factor_quartic_inner, solve_cubic, solve_itp_fallible, solve_quadratic,\r\n        GAUSS_LEGENDRE_COEFFS_16,\r\n    },\r\n    Affine, BezPath, CubicBez, ParamCurve, ParamCurveArclen, Point, Vec2,\r\n};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// The source curve for curve fitting.\r\n///\r\n/// This trait is a general representation of curves to be used as input to a curve\r\n/// fitting process. It can represent source curves with cusps and corners, though\r\n/// if the corners are known in advance, it may be better to run curve fitting on\r\n/// subcurves bounded by the corners.\r\n///\r\n/// The trait primarily works by sampling the source curve and computing the position\r\n/// and derivative at each sample. Those derivatives are then used for multiple\r\n/// sub-tasks, including ensuring G1 continuity at subdivision points, computing the\r\n/// area and moment of the curve for curve fitting, and casting rays for evaluation\r\n/// of a distance metric to test accuracy.\r\n///\r\n/// A major motivation is computation of offset curves, which often have cusps, but\r\n/// the presence and location of those cusps is not generally known. It is also\r\n/// intended for conversion between curve types (for example, piecewise Euler spiral\r\n/// or NURBS), and distortion effects such as perspective transform.\r\n///\r\n/// Note general similarities to [`ParamCurve`] but also important differences.\r\n/// Instead of separate [`eval`] and evaluation of derivative, have a single\r\n/// [`sample_pt_deriv`] method which can be more efficient and also handles cusps more\r\n/// robustly. Also there is no method for subsegment, as that is not needed and\r\n/// would be annoying to implement.\r\n///\r\n/// [`ParamCurve`]: crate::ParamCurve\r\n/// [`eval`]: crate::ParamCurve::eval\r\n/// [`sample_pt_deriv`]: ParamCurveFit::sample_pt_deriv\r\npub trait ParamCurveFit {\r\n    /// Evaluate the curve and its tangent at parameter `t`.\r\n    ///\r\n    /// For a regular curve (one not containing a cusp or corner), the\r\n    /// derivative is a good choice for the tangent vector and the `sign`\r\n    /// parameter can be ignored. Otherwise, the `sign` parameter selects which\r\n    /// side of the discontinuity the tangent will be sampled from.\r\n    ///\r\n    /// Generally `t` is in the range [0..1].\r\n    fn sample_pt_tangent(&self, t: f64, sign: f64) -> CurveFitSample;\r\n\r\n    /// Evaluate the point and derivative at parameter `t`.\r\n    ///\r\n    /// In curves with cusps, the derivative can go to zero.\r\n    fn sample_pt_deriv(&self, t: f64) -> (Point, Vec2);\r\n\r\n    /// Compute moment integrals.\r\n    ///\r\n    /// This method computes the integrals of y dx, x y dx, and y^2 dx over the\r\n    /// length of this curve. From these integrals it is fairly straightforward\r\n    /// to derive the moments needed for curve fitting.\r\n    ///\r\n    /// A default implementation is proved which does quadrature integration\r\n    /// with Green's theorem, in terms of samples evaulated with\r\n    /// [`sample_pt_deriv`].\r\n    ///\r\n    /// [`sample_pt_deriv`]: ParamCurveFit::sample_pt_deriv\r\n    fn moment_integrals(&self, range: Range<f64>) -> (f64, f64, f64) {\r\n        let t0 = 0.5 * (range.start + range.end);\r\n        let dt = 0.5 * (range.end - range.start);\r\n        let (a, x, y) = GAUSS_LEGENDRE_COEFFS_16\r\n            .iter()\r\n            .map(|(wi, xi)| {\r\n                let t = t0 + xi * dt;\r\n                let (p, d) = self.sample_pt_deriv(t);\r\n                let a = wi * d.x * p.y;\r\n                let x = p.x * a;\r\n                let y = p.y * a;\r\n                (a, x, y)\r\n            })\r\n            .fold((0.0, 0.0, 0.0), |(a0, x0, y0), (a1, x1, y1)| {\r\n                (a0 + a1, x0 + x1, y0 + y1)\r\n            });\r\n        (a * dt, x * dt, y * dt)\r\n    }\r\n\r\n    /// Find a cusp or corner within the given range.\r\n    ///\r\n    /// If the range contains a corner or cusp, return it. If there is more\r\n    /// than one such discontinuity, any can be reported, as the function will\r\n    /// be called repeatedly after subdivision of the range.\r\n    ///\r\n    /// Do not report cusps at the endpoints of the range, as this may cause\r\n    /// potentially infinite subdivision. In particular, when a cusp is reported\r\n    /// and this method is called on a subdivided range bounded by the reported\r\n    /// cusp, then the subsequent call should not report a cusp there.\r\n    ///\r\n    /// The definition of what exactly constitutes a cusp is somewhat loose.\r\n    /// If a cusp is missed, then the curve fitting algorithm will attempt to\r\n    /// fit the curve with a smooth curve, which is generally not a disaster\r\n    /// will usually result in more subdivision. Conversely, it might be useful\r\n    /// to report near-cusps, specifically points of curvature maxima where the\r\n    /// curvature is large but still mathematically finite.\r\n    fn break_cusp(&self, range: Range<f64>) -> Option<f64>;\r\n}\r\n\r\n/// A sample point of a curve for fitting.\r\npub struct CurveFitSample {\r\n    /// A point on the curve at the sample location.\r\n    pub p: Point,\r\n    /// A vector tangent to the curve at the sample location.\r\n    pub tangent: Vec2,\r\n}\r\n\r\nimpl CurveFitSample {\r\n    /// Intersect a ray orthogonal to the tangent with the given cubic.\r\n    ///\r\n    /// Returns a vector of `t` values on the cubic.\r\n    fn intersect(&self, c: CubicBez) -> ArrayVec<f64, 3> {\r\n        let p1 = 3.0 * (c.p1 - c.p0);\r\n        let p2 = 3.0 * c.p2.to_vec2() - 6.0 * c.p1.to_vec2() + 3.0 * c.p0.to_vec2();\r\n        let p3 = (c.p3 - c.p0) - 3.0 * (c.p2 - c.p1);\r\n        let c0 = (c.p0 - self.p).dot(self.tangent);\r\n        let c1 = p1.dot(self.tangent);\r\n        let c2 = p2.dot(self.tangent);\r\n        let c3 = p3.dot(self.tangent);\r\n        solve_cubic(c0, c1, c2, c3)\r\n            .into_iter()\r\n            .filter(|t| (0.0..=1.0).contains(t))\r\n            .collect()\r\n    }\r\n}\r\n\r\n/// Generate a Bézier path that fits the source curve.\r\n///\r\n/// This function is still experimental and the signature might change; it's possible\r\n/// it might become a method on the [`ParamCurveFit`] trait.\r\n///\r\n/// This function recursively subdivides the curve in half by the parameter when the\r\n/// accuracy is not met. That gives a reasonably optimized result but not necessarily\r\n/// the minimum number of segments.\r\n///\r\n/// In general, the resulting Bézier path should have a Fréchet distance less than\r\n/// the provided `accuracy` parameter. However, this is not a rigorous guarantee, as\r\n/// the error metric is computed approximately.\r\n///\r\n/// When a higher degree of optimization is desired (at considerably more runtime cost),\r\n/// consider [`fit_to_bezpath_opt`] instead.\r\npub fn fit_to_bezpath(source: &impl ParamCurveFit, accuracy: f64) -> BezPath {\r\n    let mut path = BezPath::new();\r\n    fit_to_bezpath_rec(source, 0.0..1.0, accuracy, &mut path);\r\n    path\r\n}\r\n\r\n// Discussion question: possibly should take endpoint samples, to avoid\r\n// duplication of that work.\r\nfn fit_to_bezpath_rec(\r\n    source: &impl ParamCurveFit,\r\n    range: Range<f64>,\r\n    accuracy: f64,\r\n    path: &mut BezPath,\r\n) {\r\n    let start = range.start;\r\n    let end = range.end;\r\n    if let Some(t) = source.break_cusp(start..end) {\r\n        fit_to_bezpath_rec(source, start..t, accuracy, path);\r\n        fit_to_bezpath_rec(source, t..end, accuracy, path);\r\n    } else if let Some((c, _)) = fit_to_cubic(source, start..end, accuracy) {\r\n        if path.is_empty() {\r\n            path.move_to(c.p0);\r\n        }\r\n        path.curve_to(c.p1, c.p2, c.p3);\r\n    } else {\r\n        // A smarter approach is possible than midpoint subdivision, but would be\r\n        // a significant increase in complexity.\r\n        let t = 0.5 * (start + end);\r\n        fit_to_bezpath_rec(source, start..t, accuracy, path);\r\n        fit_to_bezpath_rec(source, t..end, accuracy, path);\r\n    }\r\n}\r\n\r\nconst N_SAMPLE: usize = 20;\r\n\r\n/// An acceleration structure for estimating curve distance\r\nstruct CurveDist {\r\n    samples: ArrayVec<CurveFitSample, N_SAMPLE>,\r\n    arcparams: ArrayVec<f64, N_SAMPLE>,\r\n    range: Range<f64>,\r\n    /// A \"spicy\" curve is one with potentially extreme curvature variation,\r\n    /// so use arc length measurement for better accuracy.\r\n    spicy: bool,\r\n}\r\n\r\nimpl CurveDist {\r\n    fn from_curve(source: &impl ParamCurveFit, range: Range<f64>) -> Self {\r\n        let step = (range.end - range.start) * (1.0 / (N_SAMPLE + 1) as f64);\r\n        let mut last_tan = None;\r\n        let mut spicy = false;\r\n        const SPICY_THRESH: f64 = 0.2;\r\n        let mut samples = ArrayVec::new();\r\n        for i in 0..N_SAMPLE + 2 {\r\n            let sample = source.sample_pt_tangent(range.start + i as f64 * step, 1.0);\r\n            if let Some(last_tan) = last_tan {\r\n                let cross = sample.tangent.cross(last_tan);\r\n                let dot = sample.tangent.dot(last_tan);\r\n                if cross.abs() > SPICY_THRESH * dot.abs() {\r\n                    spicy = true;\r\n                }\r\n            }\r\n            last_tan = Some(sample.tangent);\r\n            if i > 0 && i < N_SAMPLE + 1 {\r\n                samples.push(sample);\r\n            }\r\n        }\r\n        CurveDist {\r\n            samples,\r\n            arcparams: Default::default(),\r\n            range,\r\n            spicy,\r\n        }\r\n    }\r\n\r\n    fn compute_arc_params(&mut self, source: &impl ParamCurveFit) {\r\n        const N_SUBSAMPLE: usize = 10;\r\n        let (start, end) = (self.range.start, self.range.end);\r\n        let dt = (end - start) * (1.0 / ((N_SAMPLE + 1) * N_SUBSAMPLE) as f64);\r\n        let mut arclen = 0.0;\r\n        for i in 0..N_SAMPLE + 1 {\r\n            for j in 0..N_SUBSAMPLE {\r\n                let t = start + dt * ((i * N_SUBSAMPLE + j) as f64 + 0.5);\r\n                let (_, deriv) = source.sample_pt_deriv(t);\r\n                arclen += deriv.hypot();\r\n            }\r\n            if i < N_SAMPLE {\r\n                self.arcparams.push(arclen);\r\n            }\r\n        }\r\n        let arclen_inv = arclen.recip();\r\n        for x in &mut self.arcparams {\r\n            *x *= arclen_inv;\r\n        }\r\n    }\r\n\r\n    /// Evaluate distance based on arc length parametrization\r\n    fn eval_arc(&self, c: CubicBez, acc2: f64) -> Option<f64> {\r\n        // TODO: this could perhaps be tuned.\r\n        const EPS: f64 = 1e-9;\r\n        let c_arclen = c.arclen(EPS);\r\n        let mut max_err2 = 0.0;\r\n        for (sample, s) in self.samples.iter().zip(&self.arcparams) {\r\n            let t = c.inv_arclen(c_arclen * s, EPS);\r\n            let err = sample.p.distance_squared(c.eval(t));\r\n            max_err2 = err.max(max_err2);\r\n            if max_err2 > acc2 {\r\n                return None;\r\n            }\r\n        }\r\n        Some(max_err2)\r\n    }\r\n\r\n    /// Evaluate distance to a cubic approximation.\r\n    ///\r\n    /// If distance exceeds stated accuracy, can return None. Note that\r\n    /// `acc2` is the square of the target.\r\n    ///\r\n    /// Returns the squre of the error, which is intended to be a good\r\n    /// approximation of the Fréchet distance.\r\n    fn eval_ray(&self, c: CubicBez, acc2: f64) -> Option<f64> {\r\n        let mut max_err2 = 0.0;\r\n        for sample in &self.samples {\r\n            let mut best = acc2 + 1.0;\r\n            for t in sample.intersect(c) {\r\n                let err = sample.p.distance_squared(c.eval(t));\r\n                best = best.min(err);\r\n            }\r\n            max_err2 = best.max(max_err2);\r\n            if max_err2 > acc2 {\r\n                return None;\r\n            }\r\n        }\r\n        Some(max_err2)\r\n    }\r\n\r\n    fn eval_dist(&mut self, source: &impl ParamCurveFit, c: CubicBez, acc2: f64) -> Option<f64> {\r\n        // Always compute cheaper distance, hoping for early-out.\r\n        let ray_dist = self.eval_ray(c, acc2)?;\r\n        if !self.spicy {\r\n            return Some(ray_dist);\r\n        }\r\n        if self.arcparams.is_empty() {\r\n            self.compute_arc_params(source);\r\n        }\r\n        self.eval_arc(c, acc2)\r\n    }\r\n}\r\n\r\n/// As described in [Simplifying Bézier paths], strictly optimizing for\r\n/// Fréchet distance can create bumps. The problem is curves with long\r\n/// control arms (distance from the control point to the corresponding\r\n/// endpoint). We mitigate that by applying a penalty as a multiplier to\r\n/// the measured error (approximate Fréchet distance). This is ReLU-like,\r\n/// with a value of 1.0 below the elbow, and a given slope above it. The\r\n/// values here have been determined empirically to give good results.\r\n///\r\n/// [Simplifying Bézier paths]:\r\n/// https://raphlinus.github.io/curves/2023/04/18/bezpath-simplify.html\r\nconst D_PENALTY_ELBOW: f64 = 0.65;\r\nconst D_PENALTY_SLOPE: f64 = 2.0;\r\n\r\n/// Fit a single cubic to a range of the source curve.\r\n///\r\n/// Returns the cubic segment and the square of the error.\r\n/// Discussion question: should this be a method on the trait instead?\r\npub fn fit_to_cubic(\r\n    source: &impl ParamCurveFit,\r\n    range: Range<f64>,\r\n    accuracy: f64,\r\n) -> Option<(CubicBez, f64)> {\r\n    // TODO: handle case where chord is short; return `None` if subdivision\r\n    // will be useful (ie resulting chord is longer), otherwise simple short\r\n    // cubic (maybe raised line).\r\n\r\n    let start = source.sample_pt_tangent(range.start, 1.0);\r\n    let end = source.sample_pt_tangent(range.end, -1.0);\r\n    let d = end.p - start.p;\r\n    let th = d.atan2();\r\n    let chord2 = d.hypot2();\r\n    fn mod_2pi(th: f64) -> f64 {\r\n        let th_scaled = th * core::f64::consts::FRAC_1_PI * 0.5;\r\n        core::f64::consts::PI * 2.0 * (th_scaled - th_scaled.round())\r\n    }\r\n    let th0 = mod_2pi(start.tangent.atan2() - th);\r\n    let th1 = mod_2pi(th - end.tangent.atan2());\r\n\r\n    let (mut area, mut x, mut y) = source.moment_integrals(range.clone());\r\n    let (x0, y0) = (start.p.x, start.p.y);\r\n    let (dx, dy) = (d.x, d.y);\r\n    // Subtract off area of chord\r\n    area -= dx * (y0 + 0.5 * dy);\r\n    // `area` is signed area of closed curve segment.\r\n    // This quantity is invariant to translation and rotation.\r\n\r\n    // Subtract off moment of chord\r\n    let dy_3 = dy * (1. / 3.);\r\n    x -= dx * (x0 * y0 + 0.5 * (x0 * dy + y0 * dx) + dy_3 * dx);\r\n    y -= dx * (y0 * y0 + y0 * dy + dy_3 * dy);\r\n    // Translate start point to origin; convert raw integrals to moments.\r\n    x -= x0 * area;\r\n    y = 0.5 * y - y0 * area;\r\n    // Rotate into place (this also scales up by chordlength for efficiency).\r\n    let moment = d.x * x + d.y * y;\r\n    // `moment` is the chordlength times the x moment of the curve translated\r\n    // so its start point is on the origin, and rotated so its end point is on the\r\n    // x axis.\r\n\r\n    let chord2_inv = chord2.recip();\r\n    let unit_area = area * chord2_inv;\r\n    let mx = moment * chord2_inv.powi(2);\r\n    // `unit_area` is signed area scaled to unit chord; `mx` is scaled x moment\r\n\r\n    let chord = chord2.sqrt();\r\n    let aff = Affine::translate(start.p.to_vec2()) * Affine::rotate(th) * Affine::scale(chord);\r\n    let mut curve_dist = CurveDist::from_curve(source, range);\r\n    let acc2 = accuracy * accuracy;\r\n    let mut best_c = None;\r\n    let mut best_err2 = None;\r\n    for (cand, d0, d1) in cubic_fit(th0, th1, unit_area, mx) {\r\n        let c = aff * cand;\r\n        if let Some(err2) = curve_dist.eval_dist(source, c, acc2) {\r\n            fn scale_f(d: f64) -> f64 {\r\n                1.0 + (d - D_PENALTY_ELBOW).max(0.0) * D_PENALTY_SLOPE\r\n            }\r\n            let scale = scale_f(d0).max(scale_f(d1)).powi(2);\r\n            let err2 = err2 * scale;\r\n            if err2 < acc2 && best_err2.map(|best| err2 < best).unwrap_or(true) {\r\n                best_c = Some(c);\r\n                best_err2 = Some(err2);\r\n            }\r\n        }\r\n    }\r\n    match (best_c, best_err2) {\r\n        (Some(c), Some(err2)) => Some((c, err2)),\r\n        _ => None,\r\n    }\r\n}\r\n\r\n/// Returns curves matching area and moment, given unit chord.\r\nfn cubic_fit(th0: f64, th1: f64, area: f64, mx: f64) -> ArrayVec<(CubicBez, f64, f64), 4> {\r\n    // Note: maybe we want to take unit vectors instead of angle? Shouldn't\r\n    // matter much either way though.\r\n    let (s0, c0) = th0.sin_cos();\r\n    let (s1, c1) = th1.sin_cos();\r\n    let a4 = -9.\r\n        * c0\r\n        * (((2. * s1 * c1 * c0 + s0 * (2. * c1 * c1 - 1.)) * c0 - 2. * s1 * c1) * c0\r\n            - c1 * c1 * s0);\r\n    let a3 = 12.\r\n        * ((((c1 * (30. * area * c1 - s1) - 15. * area) * c0 + 2. * s0\r\n            - c1 * s0 * (c1 + 30. * area * s1))\r\n            * c0\r\n            + c1 * (s1 - 15. * area * c1))\r\n            * c0\r\n            - s0 * c1 * c1);\r\n    let a2 = 12.\r\n        * ((((70. * mx + 15. * area) * s1 * s1 + c1 * (9. * s1 - 70. * c1 * mx - 5. * c1 * area))\r\n            * c0\r\n            - 5. * s0 * s1 * (3. * s1 - 4. * c1 * (7. * mx + area)))\r\n            * c0\r\n            - c1 * (9. * s1 - 70. * c1 * mx - 5. * c1 * area));\r\n    let a1 = 16.\r\n        * (((12. * s0 - 5. * c0 * (42. * mx - 17. * area)) * s1\r\n            - 70. * c1 * (3. * mx - area) * s0\r\n            - 75. * c0 * c1 * area * area)\r\n            * s1\r\n            - 75. * c1 * c1 * area * area * s0);\r\n    let a0 = 80. * s1 * (42. * s1 * mx - 25. * area * (s1 - c1 * area));\r\n    // TODO: \"roots\" is not a good name for this variable, as it also contains\r\n    // the real part of complex conjugate pairs.\r\n    let mut roots = ArrayVec::<f64, 4>::new();\r\n    const EPS: f64 = 1e-12;\r\n    if a4.abs() > EPS {\r\n        let a = a3 / a4;\r\n        let b = a2 / a4;\r\n        let c = a1 / a4;\r\n        let d = a0 / a4;\r\n        if let Some(quads) = factor_quartic_inner(a, b, c, d, false) {\r\n            for (qc1, qc0) in quads {\r\n                let qroots = solve_quadratic(qc0, qc1, 1.0);\r\n                if qroots.is_empty() {\r\n                    // Real part of pair of complex roots\r\n                    roots.push(-0.5 * qc1);\r\n                } else {\r\n                    roots.extend(qroots);\r\n                }\r\n            }\r\n        }\r\n    } else if a3.abs() > EPS {\r\n        roots.extend(solve_cubic(a0, a1, a2, a3));\r\n    } else {\r\n        roots.extend(solve_quadratic(a0, a1, a2));\r\n    }\r\n\r\n    let s01 = s0 * c1 + s1 * c0;\r\n    roots\r\n        .iter()\r\n        .filter_map(|&d0| {\r\n            let (d0, d1) = if d0 > 0.0 {\r\n                let d1 = (d0 * s0 - area * (10. / 3.)) / (0.5 * d0 * s01 - s1);\r\n                if d1 > 0.0 {\r\n                    (d0, d1)\r\n                } else {\r\n                    (s1 / s01, 0.0)\r\n                }\r\n            } else {\r\n                (0.0, s0 / s01)\r\n            };\r\n            // We could implement a maximum d value here.\r\n            if d0 >= 0.0 && d1 >= 0.0 {\r\n                Some((\r\n                    CubicBez::new(\r\n                        (0.0, 0.0),\r\n                        (d0 * c0, d0 * s0),\r\n                        (1.0 - d1 * c1, d1 * s1),\r\n                        (1.0, 0.0),\r\n                    ),\r\n                    d0,\r\n                    d1,\r\n                ))\r\n            } else {\r\n                None\r\n            }\r\n        })\r\n        .collect()\r\n}\r\n\r\n/// Generate a highly optimized Bézier path that fits the source curve.\r\n///\r\n/// This function is still experimental and the signature might change; it's possible\r\n/// it might become a method on the [`ParamCurveFit`] trait.\r\n///\r\n/// This function is considerably slower than [`fit_to_bezpath`], as it computes\r\n/// optimal subdivision points. Its result is expected to be very close to the optimum\r\n/// possible Bézier path for the source curve, in that it has a minimal number of curve\r\n/// segments, and a minimal error over all paths with that number of segments.\r\n///\r\n/// See [`fit_to_bezpath`] for an explanation of the `accuracy` parameter.\r\npub fn fit_to_bezpath_opt(source: &impl ParamCurveFit, accuracy: f64) -> BezPath {\r\n    let mut cusps = Vec::new();\r\n    let mut path = BezPath::new();\r\n    let mut t0 = 0.0;\r\n    loop {\r\n        let t1 = cusps.last().copied().unwrap_or(1.0);\r\n        match fit_to_bezpath_opt_inner(source, accuracy, t0..t1, &mut path) {\r\n            Some(t) => cusps.push(t),\r\n            None => match cusps.pop() {\r\n                Some(t) => t0 = t,\r\n                None => break,\r\n            },\r\n        }\r\n    }\r\n    path\r\n}\r\n\r\n/// Fit a range without cusps.\r\n///\r\n/// On Ok return, range has been added to the path. On Err return, report a cusp (and don't\r\n/// mutate path).\r\nfn fit_to_bezpath_opt_inner(\r\n    source: &impl ParamCurveFit,\r\n    accuracy: f64,\r\n    range: Range<f64>,\r\n    path: &mut BezPath,\r\n) -> Option<f64> {\r\n    if let Some(t) = source.break_cusp(range.clone()) {\r\n        return Some(t);\r\n    }\r\n    let err;\r\n    if let Some((c, err2)) = fit_to_cubic(source, range.clone(), accuracy) {\r\n        err = err2.sqrt();\r\n        if err < accuracy {\r\n            if range.start == 0.0 {\r\n                path.move_to(c.p0);\r\n            }\r\n            path.curve_to(c.p1, c.p2, c.p3);\r\n            return None;\r\n        }\r\n    } else {\r\n        err = 2.0 * accuracy;\r\n    }\r\n    let (mut t0, t1) = (range.start, range.end);\r\n    let mut n = 0;\r\n    let last_err;\r\n    loop {\r\n        n += 1;\r\n        match fit_opt_segment(source, accuracy, t0..t1) {\r\n            FitResult::ParamVal(t) => t0 = t,\r\n            FitResult::SegmentError(err) => {\r\n                last_err = err;\r\n                break;\r\n            }\r\n            FitResult::CuspFound(t) => return Some(t),\r\n        }\r\n    }\r\n    t0 = range.start;\r\n    const EPS: f64 = 1e-9;\r\n    let f = |x| fit_opt_err_delta(source, x, accuracy, t0..t1, n);\r\n    let k1 = 0.2 / accuracy;\r\n    let ya = -err;\r\n    let yb = accuracy - last_err;\r\n    let (_, x) = match solve_itp_fallible(f, 0.0, accuracy, EPS, 1, k1, ya, yb) {\r\n        Ok(x) => x,\r\n        Err(t) => return Some(t),\r\n    };\r\n    //println!(\"got fit with n={}, err={}\", n, x);\r\n    let path_len = path.elements().len();\r\n    for i in 0..n {\r\n        let t1 = if i < n - 1 {\r\n            match fit_opt_segment(source, x, t0..range.end) {\r\n                FitResult::ParamVal(t1) => t1,\r\n                FitResult::SegmentError(_) => range.end,\r\n                FitResult::CuspFound(t) => {\r\n                    path.truncate(path_len);\r\n                    return Some(t);\r\n                }\r\n            }\r\n        } else {\r\n            range.end\r\n        };\r\n        let (c, _) = fit_to_cubic(source, t0..t1, accuracy).unwrap();\r\n        if i == 0 && range.start == 0.0 {\r\n            path.move_to(c.p0);\r\n        }\r\n        path.curve_to(c.p1, c.p2, c.p3);\r\n        t0 = t1;\r\n        if t0 == range.end {\r\n            // This is unlikely but could happen when not monotonic.\r\n            break;\r\n        }\r\n    }\r\n    None\r\n}\r\n\r\nfn measure_one_seg(source: &impl ParamCurveFit, range: Range<f64>, limit: f64) -> Option<f64> {\r\n    fit_to_cubic(source, range, limit).map(|(_, err2)| err2.sqrt())\r\n}\r\n\r\nenum FitResult {\r\n    /// The parameter (`t`) value that meets the desired accuracy.\r\n    ParamVal(f64),\r\n    /// Error of the measured segment.\r\n    SegmentError(f64),\r\n    /// The parameter value where a cusp was found.\r\n    CuspFound(f64),\r\n}\r\n\r\nfn fit_opt_segment(source: &impl ParamCurveFit, accuracy: f64, range: Range<f64>) -> FitResult {\r\n    if let Some(t) = source.break_cusp(range.clone()) {\r\n        return FitResult::CuspFound(t);\r\n    }\r\n    let missing_err = accuracy * 2.0;\r\n    let err = measure_one_seg(source, range.clone(), accuracy).unwrap_or(missing_err);\r\n    if err <= accuracy {\r\n        return FitResult::SegmentError(err);\r\n    }\r\n    let (t0, t1) = (range.start, range.end);\r\n    let f = |x| {\r\n        if let Some(t) = source.break_cusp(range.clone()) {\r\n            return Err(t);\r\n        }\r\n        let err = measure_one_seg(source, t0..x, accuracy).unwrap_or(missing_err);\r\n        Ok(err - accuracy)\r\n    };\r\n    const EPS: f64 = 1e-9;\r\n    let k1 = 2.0 / (t1 - t0);\r\n    match solve_itp_fallible(f, t0, t1, EPS, 1, k1, -accuracy, err - accuracy) {\r\n        Ok((t1, _)) => FitResult::ParamVal(t1),\r\n        Err(t) => FitResult::CuspFound(t),\r\n    }\r\n}\r\n\r\n// Ok result is delta error (accuracy - error of last seg).\r\n// Err result is a cusp.\r\nfn fit_opt_err_delta(\r\n    source: &impl ParamCurveFit,\r\n    accuracy: f64,\r\n    limit: f64,\r\n    range: Range<f64>,\r\n    n: usize,\r\n) -> Result<f64, f64> {\r\n    let (mut t0, t1) = (range.start, range.end);\r\n    for _ in 0..n - 1 {\r\n        t0 = match fit_opt_segment(source, accuracy, t0..t1) {\r\n            FitResult::ParamVal(t0) => t0,\r\n            // In this case, n - 1 will work, which of course means the error is highly\r\n            // non-monotonic. We should probably harvest that solution.\r\n            FitResult::SegmentError(_) => return Ok(accuracy),\r\n            FitResult::CuspFound(t) => return Err(t),\r\n        }\r\n    }\r\n    let err = measure_one_seg(source, t0..t1, limit).unwrap_or(accuracy * 2.0);\r\n    Ok(accuracy - err)\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/insets.rs",
      "sha256": "2a6f573577bf95f89964f0b85c2c2da271853caf8ccc1db7f14f3ec8378374ce",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A description of the distances between the edges of two rectangles.\r\n\r\nuse core::ops::{Add, Neg, Sub};\r\n\r\nuse crate::{Rect, Size};\r\n\r\n/// Insets from the edges of a rectangle.\r\n///\r\n///\r\n/// The inset value for each edge can be thought of as a delta computed from\r\n/// the center of the rect to that edge. For instance, with an inset of `2.0` on\r\n/// the x-axis, a rectangle with the origin `(0.0, 0.0)` with that inset added\r\n/// will have the new origin at `(-2.0, 0.0)`.\r\n///\r\n/// Put alternatively, a positive inset represents increased distance from center,\r\n/// and a negative inset represents decreased distance from center.\r\n///\r\n/// # Examples\r\n///\r\n/// Positive insets added to a [`Rect`] produce a larger [`Rect`]:\r\n/// ```\r\n/// # use kurbo::{Insets, Rect};\r\n/// let rect = Rect::from_origin_size((0., 0.,), (10., 10.,));\r\n/// let insets = Insets::uniform_xy(3., 0.,);\r\n///\r\n/// let inset_rect = rect + insets;\r\n/// assert_eq!(inset_rect.width(), 16.0, \"10.0 + 3.0 × 2\");\r\n/// assert_eq!(inset_rect.x0, -3.0);\r\n/// ```\r\n///\r\n/// Negative insets added to a [`Rect`] produce a smaller [`Rect`]:\r\n///\r\n/// ```\r\n/// # use kurbo::{Insets, Rect};\r\n/// let rect = Rect::from_origin_size((0., 0.,), (10., 10.,));\r\n/// let insets = Insets::uniform_xy(-3., 0.,);\r\n///\r\n/// let inset_rect = rect + insets;\r\n/// assert_eq!(inset_rect.width(), 4.0, \"10.0 - 3.0 × 2\");\r\n/// assert_eq!(inset_rect.x0, 3.0);\r\n/// ```\r\n///\r\n/// [`Insets`] operate on the absolute rectangle [`Rect::abs`], and so ignore\r\n/// existing negative widths and heights.\r\n///\r\n/// ```\r\n/// # use kurbo::{Insets, Rect};\r\n/// let rect = Rect::new(7., 11., 0., 0.,);\r\n/// let insets = Insets::uniform_xy(0., 1.,);\r\n///\r\n/// assert_eq!(rect.width(), -7.0);\r\n///\r\n/// let inset_rect = rect + insets;\r\n/// assert_eq!(inset_rect.width(), 7.0);\r\n/// assert_eq!(inset_rect.x0, 0.0);\r\n/// assert_eq!(inset_rect.height(), 13.0);\r\n/// ```\r\n///\r\n/// The width and height of an inset operation can still be negative if the\r\n/// [`Insets`]' dimensions are greater than the dimensions of the original [`Rect`].\r\n///\r\n/// ```\r\n/// # use kurbo::{Insets, Rect};\r\n/// let rect = Rect::new(0., 0., 3., 5.);\r\n/// let insets = Insets::uniform_xy(0., 7.,);\r\n///\r\n/// let inset_rect = rect - insets;\r\n/// assert_eq!(inset_rect.height(), -9., \"5 - 7 × 2\")\r\n/// ```\r\n///\r\n/// `Rect - Rect = Insets`:\r\n///\r\n///\r\n/// ```\r\n/// # use kurbo::{Insets, Rect};\r\n/// let rect = Rect::new(0., 0., 5., 11.);\r\n/// let insets = Insets::uniform_xy(1., 7.,);\r\n///\r\n/// let inset_rect = rect + insets;\r\n/// let insets2 = inset_rect - rect;\r\n///\r\n/// assert_eq!(insets2.x0, insets.x0);\r\n/// assert_eq!(insets2.y1, insets.y1);\r\n/// assert_eq!(insets2.x_value(), insets.x_value());\r\n/// assert_eq!(insets2.y_value(), insets.y_value());\r\n/// ```\r\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct Insets {\r\n    /// The minimum x coordinate (left edge).\r\n    pub x0: f64,\r\n    /// The minimum y coordinate (top edge in y-down spaces).\r\n    pub y0: f64,\r\n    /// The maximum x coordinate (right edge).\r\n    pub x1: f64,\r\n    /// The maximum y coordinate (bottom edge in y-down spaces).\r\n    pub y1: f64,\r\n}\r\n\r\nimpl Insets {\r\n    /// Zeroed insets.\r\n    pub const ZERO: Insets = Insets::uniform(0.);\r\n\r\n    /// New uniform insets.\r\n    #[inline]\r\n    pub const fn uniform(d: f64) -> Insets {\r\n        Insets {\r\n            x0: d,\r\n            y0: d,\r\n            x1: d,\r\n            y1: d,\r\n        }\r\n    }\r\n\r\n    /// New insets with uniform values along each axis.\r\n    #[inline]\r\n    pub const fn uniform_xy(x: f64, y: f64) -> Insets {\r\n        Insets {\r\n            x0: x,\r\n            y0: y,\r\n            x1: x,\r\n            y1: y,\r\n        }\r\n    }\r\n\r\n    /// New insets. The ordering of the arguments is \"left, top, right, bottom\",\r\n    /// assuming a y-down coordinate space.\r\n    #[inline]\r\n    pub const fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Insets {\r\n        Insets { x0, y0, x1, y1 }\r\n    }\r\n\r\n    /// The total delta on the x-axis represented by these insets.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Insets;\r\n    ///\r\n    /// let insets = Insets::uniform_xy(3., 8.);\r\n    /// assert_eq!(insets.x_value(), 6.);\r\n    ///\r\n    /// let insets = Insets::new(5., 0., -12., 0.,);\r\n    /// assert_eq!(insets.x_value(), -7.);\r\n    /// ```\r\n    #[inline]\r\n    pub fn x_value(self) -> f64 {\r\n        self.x0 + self.x1\r\n    }\r\n\r\n    /// The total delta on the y-axis represented by these insets.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Insets;\r\n    ///\r\n    /// let insets = Insets::uniform_xy(3., 7.);\r\n    /// assert_eq!(insets.y_value(), 14.);\r\n    ///\r\n    /// let insets = Insets::new(5., 10., -12., 4.,);\r\n    /// assert_eq!(insets.y_value(), 14.);\r\n    /// ```\r\n    #[inline]\r\n    pub fn y_value(self) -> f64 {\r\n        self.y0 + self.y1\r\n    }\r\n\r\n    /// Returns the total delta represented by these insets as a [`Size`].\r\n    ///\r\n    /// This is equivalent to creating a [`Size`] from the values returned by\r\n    /// [`x_value`] and [`y_value`].\r\n    ///\r\n    /// This function may return a size with negative values.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::{Insets, Size};\r\n    ///\r\n    /// let insets = Insets::new(11.1, -43.3, 3.333, -0.0);\r\n    /// assert_eq!(insets.size(), Size::new(insets.x_value(), insets.y_value()));\r\n    /// ```\r\n    ///\r\n    /// [`x_value`]: Insets::x_value\r\n    /// [`y_value`]: Insets::y_value\r\n    pub fn size(self) -> Size {\r\n        Size::new(self.x_value(), self.y_value())\r\n    }\r\n\r\n    /// Return `true` iff all values are nonnegative.\r\n    pub fn are_nonnegative(self) -> bool {\r\n        let Insets { x0, y0, x1, y1 } = self;\r\n        x0 >= 0.0 && y0 >= 0.0 && x1 >= 0.0 && y1 >= 0.0\r\n    }\r\n\r\n    /// Return new `Insets` with all negative values replaced with `0.0`.\r\n    ///\r\n    /// This is provided as a convenience for applications where negative insets\r\n    /// are not meaningful.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Insets;\r\n    ///\r\n    /// let insets = Insets::new(-10., 3., -0.2, 4.);\r\n    /// let nonnegative = insets.nonnegative();\r\n    /// assert_eq!(nonnegative.x_value(), 0.0);\r\n    /// assert_eq!(nonnegative.y_value(), 7.0);\r\n    /// ```\r\n    pub fn nonnegative(self) -> Insets {\r\n        let Insets { x0, y0, x1, y1 } = self;\r\n        Insets {\r\n            x0: x0.max(0.0),\r\n            y0: y0.max(0.0),\r\n            x1: x1.max(0.0),\r\n            y1: y1.max(0.0),\r\n        }\r\n    }\r\n\r\n    /// Are these insets finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.x0.is_finite() && self.y0.is_finite() && self.x1.is_finite() && self.y1.is_finite()\r\n    }\r\n\r\n    /// Are these insets NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.x0.is_nan() || self.y0.is_nan() || self.x1.is_nan() || self.y1.is_nan()\r\n    }\r\n}\r\n\r\nimpl Neg for Insets {\r\n    type Output = Insets;\r\n\r\n    #[inline]\r\n    fn neg(self) -> Insets {\r\n        Insets::new(-self.x0, -self.y0, -self.x1, -self.y1)\r\n    }\r\n}\r\n\r\nimpl Add<Rect> for Insets {\r\n    type Output = Rect;\r\n\r\n    #[inline]\r\n    #[allow(clippy::suspicious_arithmetic_impl)]\r\n    fn add(self, other: Rect) -> Rect {\r\n        let other = other.abs();\r\n        Rect::new(\r\n            other.x0 - self.x0,\r\n            other.y0 - self.y0,\r\n            other.x1 + self.x1,\r\n            other.y1 + self.y1,\r\n        )\r\n    }\r\n}\r\n\r\nimpl Add<Insets> for Rect {\r\n    type Output = Rect;\r\n\r\n    #[inline]\r\n    fn add(self, other: Insets) -> Rect {\r\n        other + self\r\n    }\r\n}\r\n\r\nimpl Sub<Rect> for Insets {\r\n    type Output = Rect;\r\n\r\n    #[inline]\r\n    fn sub(self, other: Rect) -> Rect {\r\n        other + -self\r\n    }\r\n}\r\n\r\nimpl Sub<Insets> for Rect {\r\n    type Output = Rect;\r\n\r\n    #[inline]\r\n    fn sub(self, other: Insets) -> Rect {\r\n        other - self\r\n    }\r\n}\r\n\r\nimpl From<f64> for Insets {\r\n    fn from(src: f64) -> Insets {\r\n        Insets::uniform(src)\r\n    }\r\n}\r\n\r\nimpl From<(f64, f64)> for Insets {\r\n    fn from(src: (f64, f64)) -> Insets {\r\n        Insets::uniform_xy(src.0, src.1)\r\n    }\r\n}\r\n\r\nimpl From<(f64, f64, f64, f64)> for Insets {\r\n    fn from(src: (f64, f64, f64, f64)) -> Insets {\r\n        Insets::new(src.0, src.1, src.2, src.3)\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/lib.rs",
      "sha256": "24bb8d407efa405b1b4d4efae668cf39f05a2d2777a981bc2201213d924f887c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! 2D geometry, with a focus on curves.\r\n//!\r\n//! The kurbo library contains data structures and algorithms for curves and\r\n//! vector paths. It was designed to serve the needs of 2D graphics applications,\r\n//! but it is intended to be general enough to be useful for other applications.\r\n//!\r\n//! Kurbo is designed to be used by [`Piet`], a crate for drawing 2D graphics,\r\n//! and is in turn used by [`Druid`], a cross-platform GUI toolkit.\r\n//!\r\n//! # Examples\r\n//!\r\n//! Basic UI-style geometry:\r\n//! ```\r\n//! use kurbo::{Insets, Point, Rect, Size, Vec2};\r\n//!\r\n//! let pt = Point::new(10.0, 10.0);\r\n//! let vector = Vec2::new(5.0, -5.0);\r\n//! let pt2 = pt + vector;\r\n//! assert_eq!(pt2, Point::new(15.0, 5.0));\r\n//!\r\n//! let rect = Rect::from_points(pt, pt2);\r\n//! assert_eq!(rect, Rect::from_origin_size((10.0, 5.0), (5.0, 5.0)));\r\n//!\r\n//! let insets = Insets::uniform(1.0);\r\n//! let inset_rect = rect - insets;\r\n//! assert_eq!(inset_rect.size(), Size::new(3.0, 3.0));\r\n//! ```\r\n//!\r\n//! Finding the closest position on a [`Shape`]'s perimeter to a [`Point`]:\r\n//!\r\n//! ```\r\n//! use kurbo::{Circle, ParamCurve, ParamCurveNearest, Point, Shape};\r\n//!\r\n//! const DESIRED_ACCURACY: f64 = 0.1;\r\n//!\r\n//! /// Given a shape and a point, returns the closest position on the shape's\r\n//! /// perimeter, or `None` if the shape is malformed.\r\n//! fn closest_perimeter_point(shape: impl Shape, pt: Point) -> Option<Point> {\r\n//!     let mut best: Option<(Point, f64)> = None;\r\n//!     for segment in shape.path_segments(DESIRED_ACCURACY) {\r\n//!         let nearest = segment.nearest(pt, DESIRED_ACCURACY);\r\n//!         if best.map(|(_, best_d)| nearest.distance_sq < best_d).unwrap_or(true) {\r\n//!             best = Some((segment.eval(nearest.t), nearest.distance_sq))\r\n//!         }\r\n//!     }\r\n//!     best.map(|(point, _)| point)\r\n//! }\r\n//!\r\n//! let circle = Circle::new((5.0, 5.0), 5.0);\r\n//! let hit_point = Point::new(5.0, -2.0);\r\n//! let expectation = Point::new(5.0, 0.0);\r\n//! let hit = closest_perimeter_point(circle, hit_point).unwrap();\r\n//! assert!(hit.distance(expectation) <= DESIRED_ACCURACY);\r\n//! ```\r\n//!\r\n//! # Features\r\n//!\r\n//! This crate either uses the standard library or the [`libm`] crate for\r\n//! math functionality. The `std` feature is enabled by default, but can be\r\n//! disabled, as long as the `libm` feature is enabled. This is useful for\r\n//! `no_std` environments. However, note that the `libm` crate is not as\r\n//! efficient as the standard library, and that this crate still uses the\r\n//! `alloc` crate regardless.\r\n//!\r\n//! [`Piet`]: https://docs.rs/piet\r\n//! [`Druid`]: https://docs.rs/druid\r\n//! [`libm`]: https://docs.rs/libm\r\n\r\n#![forbid(unsafe_code)]\r\n#![deny(missing_docs, clippy::trivially_copy_pass_by_ref)]\r\n#![warn(rustdoc::broken_intra_doc_links)]\r\n#![allow(\r\n    clippy::unreadable_literal,\r\n    clippy::many_single_char_names,\r\n    clippy::excessive_precision,\r\n    clippy::bool_to_int_with_if\r\n)]\r\n#![cfg_attr(all(not(feature = \"std\"), not(test)), no_std)]\r\n\r\n#[cfg(not(any(feature = \"std\", feature = \"libm\")))]\r\ncompile_error!(\"kurbo requires either the `std` or `libm` feature\");\r\n\r\nextern crate alloc;\r\n\r\nmod affine;\r\nmod arc;\r\nmod bezpath;\r\nmod circle;\r\npub mod common;\r\nmod cubicbez;\r\nmod ellipse;\r\nmod fit;\r\nmod insets;\r\nmod line;\r\nmod mindist;\r\npub mod offset;\r\nmod param_curve;\r\nmod point;\r\nmod quadbez;\r\nmod quadspline;\r\nmod rect;\r\nmod rounded_rect;\r\nmod rounded_rect_radii;\r\nmod shape;\r\npub mod simplify;\r\nmod size;\r\n#[cfg(feature = \"std\")]\r\nmod svg;\r\nmod translate_scale;\r\nmod vec2;\r\n\r\npub use crate::affine::*;\r\npub use crate::arc::*;\r\npub use crate::bezpath::*;\r\npub use crate::circle::*;\r\npub use crate::cubicbez::*;\r\npub use crate::ellipse::*;\r\npub use crate::fit::*;\r\npub use crate::insets::*;\r\npub use crate::line::*;\r\npub use crate::param_curve::*;\r\npub use crate::point::*;\r\npub use crate::quadbez::*;\r\npub use crate::quadspline::*;\r\npub use crate::rect::*;\r\npub use crate::rounded_rect::*;\r\npub use crate::rounded_rect_radii::*;\r\npub use crate::shape::*;\r\npub use crate::size::*;\r\n#[cfg(feature = \"std\")]\r\npub use crate::svg::*;\r\npub use crate::translate_scale::*;\r\npub use crate::vec2::*;\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/line.rs",
      "sha256": "f940db57e9fe5407433b3ea6c9dea6d001ca6874d08002a93945e60d3cd47d2c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Lines.\r\n\r\nuse core::ops::{Add, Mul, Range, Sub};\r\n\r\nuse arrayvec::ArrayVec;\r\n\r\nuse crate::{\r\n    Affine, Nearest, ParamCurve, ParamCurveArclen, ParamCurveArea, ParamCurveCurvature,\r\n    ParamCurveDeriv, ParamCurveExtrema, ParamCurveNearest, PathEl, Point, Rect, Shape, Vec2,\r\n    DEFAULT_ACCURACY, MAX_EXTREMA,\r\n};\r\n\r\n/// A single line.\r\n#[derive(Clone, Copy, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct Line {\r\n    /// The line's start point.\r\n    pub p0: Point,\r\n    /// The line's end point.\r\n    pub p1: Point,\r\n}\r\n\r\nimpl Line {\r\n    /// Create a new line.\r\n    #[inline]\r\n    pub fn new(p0: impl Into<Point>, p1: impl Into<Point>) -> Line {\r\n        Line {\r\n            p0: p0.into(),\r\n            p1: p1.into(),\r\n        }\r\n    }\r\n\r\n    /// The length of the line.\r\n    #[inline]\r\n    pub fn length(self) -> f64 {\r\n        self.arclen(DEFAULT_ACCURACY)\r\n    }\r\n\r\n    /// Computes the point where two lines, if extended to infinity, would cross.\r\n    pub fn crossing_point(self, other: Line) -> Option<Point> {\r\n        let ab = self.p1 - self.p0;\r\n        let cd = other.p1 - other.p0;\r\n        let pcd = ab.cross(cd);\r\n        if pcd == 0.0 {\r\n            return None;\r\n        }\r\n        let h = ab.cross(self.p0 - other.p0) / pcd;\r\n        Some(other.p0 + cd * h)\r\n    }\r\n\r\n    /// Is this line finite?\r\n    #[inline]\r\n    pub fn is_finite(self) -> bool {\r\n        self.p0.is_finite() && self.p1.is_finite()\r\n    }\r\n\r\n    /// Is this line NaN?\r\n    #[inline]\r\n    pub fn is_nan(self) -> bool {\r\n        self.p0.is_nan() || self.p1.is_nan()\r\n    }\r\n}\r\n\r\nimpl ParamCurve for Line {\r\n    #[inline]\r\n    fn eval(&self, t: f64) -> Point {\r\n        self.p0.lerp(self.p1, t)\r\n    }\r\n\r\n    #[inline]\r\n    fn subsegment(&self, range: Range<f64>) -> Line {\r\n        Line {\r\n            p0: self.eval(range.start),\r\n            p1: self.eval(range.end),\r\n        }\r\n    }\r\n\r\n    #[inline]\r\n    fn start(&self) -> Point {\r\n        self.p0\r\n    }\r\n\r\n    #[inline]\r\n    fn end(&self) -> Point {\r\n        self.p1\r\n    }\r\n}\r\n\r\nimpl ParamCurveDeriv for Line {\r\n    type DerivResult = ConstPoint;\r\n\r\n    #[inline]\r\n    fn deriv(&self) -> ConstPoint {\r\n        ConstPoint((self.p1 - self.p0).to_point())\r\n    }\r\n}\r\n\r\nimpl ParamCurveArclen for Line {\r\n    #[inline]\r\n    fn arclen(&self, _accuracy: f64) -> f64 {\r\n        (self.p1 - self.p0).hypot()\r\n    }\r\n\r\n    #[inline]\r\n    fn inv_arclen(&self, arclen: f64, _accuracy: f64) -> f64 {\r\n        arclen / (self.p1 - self.p0).hypot()\r\n    }\r\n}\r\n\r\nimpl ParamCurveArea for Line {\r\n    #[inline]\r\n    fn signed_area(&self) -> f64 {\r\n        self.p0.to_vec2().cross(self.p1.to_vec2()) * 0.5\r\n    }\r\n}\r\n\r\nimpl ParamCurveNearest for Line {\r\n    fn nearest(&self, p: Point, _accuracy: f64) -> Nearest {\r\n        let d = self.p1 - self.p0;\r\n        let dotp = d.dot(p - self.p0);\r\n        let d_squared = d.dot(d);\r\n        let (t, distance_sq) = if dotp <= 0.0 {\r\n            (0.0, (p - self.p0).hypot2())\r\n        } else if dotp >= d_squared {\r\n            (1.0, (p - self.p1).hypot2())\r\n        } else {\r\n            let t = dotp / d_squared;\r\n            let dist = (p - self.eval(t)).hypot2();\r\n            (t, dist)\r\n        };\r\n        Nearest { distance_sq, t }\r\n    }\r\n}\r\n\r\nimpl ParamCurveCurvature for Line {\r\n    #[inline]\r\n    fn curvature(&self, _t: f64) -> f64 {\r\n        0.0\r\n    }\r\n}\r\n\r\nimpl ParamCurveExtrema for Line {\r\n    #[inline]\r\n    fn extrema(&self) -> ArrayVec<f64, MAX_EXTREMA> {\r\n        ArrayVec::new()\r\n    }\r\n}\r\n\r\n/// A trivial \"curve\" that is just a constant.\r\n#[derive(Clone, Copy, Debug)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct ConstPoint(Point);\r\n\r\nimpl ConstPoint {\r\n    /// Is this point finite?\r\n    #[inline]\r\n    pub fn is_finite(self) -> bool {\r\n        self.0.is_finite()\r\n    }\r\n\r\n    /// Is this point NaN?\r\n    #[inline]\r\n    pub fn is_nan(self) -> bool {\r\n        self.0.is_nan()\r\n    }\r\n}\r\n\r\nimpl ParamCurve for ConstPoint {\r\n    #[inline]\r\n    fn eval(&self, _t: f64) -> Point {\r\n        self.0\r\n    }\r\n\r\n    #[inline]\r\n    fn subsegment(&self, _range: Range<f64>) -> ConstPoint {\r\n        *self\r\n    }\r\n}\r\n\r\nimpl ParamCurveDeriv for ConstPoint {\r\n    type DerivResult = ConstPoint;\r\n\r\n    #[inline]\r\n    fn deriv(&self) -> ConstPoint {\r\n        ConstPoint(Point::new(0.0, 0.0))\r\n    }\r\n}\r\n\r\nimpl ParamCurveArclen for ConstPoint {\r\n    #[inline]\r\n    fn arclen(&self, _accuracy: f64) -> f64 {\r\n        0.0\r\n    }\r\n\r\n    #[inline]\r\n    fn inv_arclen(&self, _arclen: f64, _accuracy: f64) -> f64 {\r\n        0.0\r\n    }\r\n}\r\n\r\nimpl Mul<Line> for Affine {\r\n    type Output = Line;\r\n\r\n    #[inline]\r\n    fn mul(self, other: Line) -> Line {\r\n        Line {\r\n            p0: self * other.p0,\r\n            p1: self * other.p1,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Add<Vec2> for Line {\r\n    type Output = Line;\r\n\r\n    #[inline]\r\n    fn add(self, v: Vec2) -> Line {\r\n        Line::new(self.p0 + v, self.p1 + v)\r\n    }\r\n}\r\n\r\nimpl Sub<Vec2> for Line {\r\n    type Output = Line;\r\n\r\n    #[inline]\r\n    fn sub(self, v: Vec2) -> Line {\r\n        Line::new(self.p0 - v, self.p1 - v)\r\n    }\r\n}\r\n\r\n/// An iterator yielding the path for a single line.\r\n#[doc(hidden)]\r\npub struct LinePathIter {\r\n    line: Line,\r\n    ix: usize,\r\n}\r\n\r\nimpl Shape for Line {\r\n    type PathElementsIter<'iter> = LinePathIter;\r\n\r\n    #[inline]\r\n    fn path_elements(&self, _tolerance: f64) -> LinePathIter {\r\n        LinePathIter { line: *self, ix: 0 }\r\n    }\r\n\r\n    /// Returning zero here is consistent with the contract (area is\r\n    /// only meaningful for closed shapes), but an argument can be made\r\n    /// that the contract should be tightened to include the Green's\r\n    /// theorem contribution.\r\n    fn area(&self) -> f64 {\r\n        0.0\r\n    }\r\n\r\n    #[inline]\r\n    fn perimeter(&self, _accuracy: f64) -> f64 {\r\n        (self.p1 - self.p0).hypot()\r\n    }\r\n\r\n    /// Same consideration as `area`.\r\n    fn winding(&self, _pt: Point) -> i32 {\r\n        0\r\n    }\r\n\r\n    #[inline]\r\n    fn bounding_box(&self) -> Rect {\r\n        Rect::from_points(self.p0, self.p1)\r\n    }\r\n\r\n    #[inline]\r\n    fn as_line(&self) -> Option<Line> {\r\n        Some(*self)\r\n    }\r\n}\r\n\r\nimpl Iterator for LinePathIter {\r\n    type Item = PathEl;\r\n\r\n    fn next(&mut self) -> Option<PathEl> {\r\n        self.ix += 1;\r\n        match self.ix {\r\n            1 => Some(PathEl::MoveTo(self.line.p0)),\r\n            2 => Some(PathEl::LineTo(self.line.p1)),\r\n            _ => None,\r\n        }\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{Line, ParamCurveArclen, Point};\r\n\r\n    #[test]\r\n    fn line_arclen() {\r\n        let l = Line::new((0.0, 0.0), (1.0, 1.0));\r\n        let true_len = 2.0f64.sqrt();\r\n        let epsilon = 1e-9;\r\n        assert!(l.arclen(epsilon) - true_len < epsilon);\r\n\r\n        let t = l.inv_arclen(true_len / 3.0, epsilon);\r\n        assert!((t - 1.0 / 3.0).abs() < epsilon);\r\n    }\r\n\r\n    #[test]\r\n    fn line_is_finite() {\r\n        assert!((Line {\r\n            p0: Point { x: 0., y: 0. },\r\n            p1: Point { x: 1., y: 1. }\r\n        })\r\n        .is_finite());\r\n\r\n        assert!(!(Line {\r\n            p0: Point { x: 0., y: 0. },\r\n            p1: Point {\r\n                x: f64::INFINITY,\r\n                y: 1.\r\n            }\r\n        })\r\n        .is_finite());\r\n\r\n        assert!(!(Line {\r\n            p0: Point { x: 0., y: 0. },\r\n            p1: Point {\r\n                x: 0.,\r\n                y: f64::INFINITY\r\n            }\r\n        })\r\n        .is_finite());\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/mindist.rs",
      "sha256": "8ba69c3e551c6e7ab5383dcfdb1055a680205078b818c18457083ecda801fca2",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2021 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Minimum distance between two Bézier curves\r\n//!\r\n//! This implements the algorithm in \"Computing the minimum distance between\r\n//! two Bézier curves\", Chen et al., *Journal of Computational and Applied\r\n//! Mathematics* 229(2009), 294-301\r\n\r\nuse crate::Vec2;\r\nuse core::cmp::Ordering;\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\npub(crate) fn min_dist_param(\r\n    bez1: &[Vec2],\r\n    bez2: &[Vec2],\r\n    u: (f64, f64),\r\n    v: (f64, f64),\r\n    epsilon: f64,\r\n    best_alpha: Option<f64>,\r\n) -> (f64, f64, f64) {\r\n    assert!(!bez1.is_empty() && !bez2.is_empty());\r\n    let n = bez1.len() - 1;\r\n    let m = bez2.len() - 1;\r\n    let (umin, umax) = u;\r\n    let (vmin, vmax) = v;\r\n    let umid = (umin + umax) / 2.0;\r\n    let vmid = (vmin + vmax) / 2.0;\r\n    let svalues: [(f64, f64, f64); 4] = [\r\n        (S(umin, vmin, bez1, bez2), umin, vmin),\r\n        (S(umin, vmax, bez1, bez2), umin, vmax),\r\n        (S(umax, vmin, bez1, bez2), umax, vmin),\r\n        (S(umax, vmax, bez1, bez2), umax, vmax),\r\n    ];\r\n    let alpha: f64 = svalues.iter().map(|(a, _, _)| *a).reduce(f64::min).unwrap();\r\n    if let Some(best) = best_alpha {\r\n        if alpha > best {\r\n            return (alpha, umid, vmid);\r\n        }\r\n    }\r\n\r\n    if (umax - umin).abs() < epsilon || (vmax - vmin).abs() < epsilon {\r\n        return (alpha, umid, vmid);\r\n    }\r\n\r\n    // Property one: D(r>k) > alpha\r\n    let mut is_outside = true;\r\n    let mut min_drk = None;\r\n    let mut min_ij = None;\r\n    for r in 0..(2 * n) {\r\n        for k in 0..(2 * m) {\r\n            let d_rk = D_rk(r, k, bez1, bez2);\r\n            if d_rk < alpha {\r\n                is_outside = false;\r\n            }\r\n            if min_drk.is_none() || Some(d_rk) < min_drk {\r\n                min_drk = Some(d_rk);\r\n                min_ij = Some((r, k));\r\n            }\r\n        }\r\n    }\r\n    if is_outside {\r\n        return (alpha, umid, vmid);\r\n    }\r\n\r\n    // Property two: boundary check\r\n    let mut at_boundary0on_bez1 = true;\r\n    let mut at_boundary1on_bez1 = true;\r\n    let mut at_boundary0on_bez2 = true;\r\n    let mut at_boundary1on_bez2 = true;\r\n    for i in 0..2 * n {\r\n        for j in 0..2 * m {\r\n            let dij = D_rk(i, j, bez1, bez2);\r\n            let dkj = D_rk(0, j, bez1, bez2);\r\n            if dij < dkj {\r\n                at_boundary0on_bez1 = false\r\n            }\r\n            let dkj = D_rk(2 * n, j, bez1, bez2);\r\n            if dij < dkj {\r\n                at_boundary1on_bez1 = false\r\n            }\r\n            let dkj = D_rk(i, 0, bez1, bez2);\r\n            if dij < dkj {\r\n                at_boundary0on_bez2 = false\r\n            }\r\n            let dkj = D_rk(i, 2 * n, bez1, bez2);\r\n            if dij < dkj {\r\n                at_boundary1on_bez2 = false\r\n            }\r\n        }\r\n    }\r\n    if at_boundary0on_bez1 && at_boundary0on_bez2 {\r\n        return svalues[0];\r\n    }\r\n    if at_boundary0on_bez1 && at_boundary1on_bez2 {\r\n        return svalues[1];\r\n    }\r\n    if at_boundary1on_bez1 && at_boundary0on_bez2 {\r\n        return svalues[2];\r\n    }\r\n    if at_boundary1on_bez1 && at_boundary1on_bez2 {\r\n        return svalues[3];\r\n    }\r\n\r\n    let (min_i, min_j) = min_ij.unwrap();\r\n    let new_umid = umin + (umax - umin) * (min_i as f64 / (2 * n) as f64);\r\n    let new_vmid = vmin + (vmax - vmin) * (min_j as f64 / (2 * m) as f64);\r\n\r\n    // Subdivide\r\n    let results = [\r\n        min_dist_param(\r\n            bez1,\r\n            bez2,\r\n            (umin, new_umid),\r\n            (vmin, new_vmid),\r\n            epsilon,\r\n            Some(alpha),\r\n        ),\r\n        min_dist_param(\r\n            bez1,\r\n            bez2,\r\n            (umin, new_umid),\r\n            (new_vmid, vmax),\r\n            epsilon,\r\n            Some(alpha),\r\n        ),\r\n        min_dist_param(\r\n            bez1,\r\n            bez2,\r\n            (new_umid, umax),\r\n            (vmin, new_vmid),\r\n            epsilon,\r\n            Some(alpha),\r\n        ),\r\n        min_dist_param(\r\n            bez1,\r\n            bez2,\r\n            (new_umid, umax),\r\n            (new_vmid, vmax),\r\n            epsilon,\r\n            Some(alpha),\r\n        ),\r\n    ];\r\n\r\n    *results\r\n        .iter()\r\n        .min_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Less))\r\n        .unwrap()\r\n}\r\n\r\n// $ S(u,v)=\\sum_{r=0}^{2n} \\sum _{k=0}^{2m} D_{r,k} B_{2n}^r(u) B_{2m}^k(v) $\r\n\r\n#[allow(non_snake_case)]\r\nfn S(u: f64, v: f64, bez1: &[Vec2], bez2: &[Vec2]) -> f64 {\r\n    let n = bez1.len() - 1;\r\n    let m = bez2.len() - 1;\r\n    let mut summand = 0.0;\r\n    for r in 0..=2 * n {\r\n        for k in 0..=2 * m {\r\n            summand +=\r\n                D_rk(r, k, bez1, bez2) * basis_function(2 * n, r, u) * basis_function(2 * m, k, v)\r\n        }\r\n    }\r\n    summand\r\n}\r\n\r\n// $ C_{r,k} = ( \\sum_{i=\\theta}^\\upsilon P_i C_n^i C_n^{r-i} / C_{2n}^r ) \\cdot (\\sum_{j=\\sigma}^\\varsigma Q_j C_m^j C_m^{k-j} / C_{2m}^k ) $\r\n#[allow(non_snake_case)]\r\nfn C_rk(r: usize, k: usize, bez1: &[Vec2], bez2: &[Vec2]) -> f64 {\r\n    let n = bez1.len() - 1;\r\n    let upsilon = r.min(n);\r\n    let theta = r - n.min(r);\r\n    let mut left: Vec2 = Vec2::ZERO;\r\n    for (i, &item) in bez1.iter().enumerate().take(upsilon + 1).skip(theta) {\r\n        left += item * (choose(n, i) * choose(n, r - i)) as f64 / (choose(2 * n, r) as f64);\r\n    }\r\n\r\n    let m = bez2.len() - 1;\r\n    let varsigma = k.min(m);\r\n    let sigma = k - m.min(k);\r\n    let mut right: Vec2 = Vec2::ZERO;\r\n    for (j, &item) in bez2.iter().enumerate().take(varsigma + 1).skip(sigma) {\r\n        right += item * (choose(m, j) * choose(m, k - j)) as f64 / (choose(2 * m, k) as f64);\r\n    }\r\n    left.dot(right)\r\n}\r\n\r\n// $ A_r=\\sum _{i=\\theta} ^\\upsilon (P_i \\cdot P_{r-i}) C_n^i C_n^{r-i} / C_{2n}^r $\r\n// ($ B_k $ is just the same as $ A_r $ but for the other curve.)\r\n\r\n#[allow(non_snake_case)]\r\nfn A_r(r: usize, p: &[Vec2]) -> f64 {\r\n    let n = p.len() - 1;\r\n    let upsilon = r.min(n);\r\n    let theta = r - n.min(r);\r\n    (theta..=upsilon)\r\n        .map(|i| {\r\n            let dot = p[i].dot(p[r - i]); // These are bounds checked by the sum limits\r\n            let factor = (choose(n, i) * choose(n, r - i)) as f64 / (choose(2 * n, r) as f64);\r\n            dot * factor\r\n        })\r\n        .sum()\r\n}\r\n\r\n#[allow(non_snake_case)]\r\nfn D_rk(r: usize, k: usize, bez1: &[Vec2], bez2: &[Vec2]) -> f64 {\r\n    // In the paper, B_k is used for the second factor, but it's the same thing\r\n    A_r(r, bez1) + A_r(k, bez2) - 2.0 * C_rk(r, k, bez1, bez2)\r\n}\r\n\r\n// Bezier basis function\r\nfn basis_function(n: usize, i: usize, u: f64) -> f64 {\r\n    choose(n, i) as f64 * (1.0 - u).powi((n - i) as i32) * u.powi(i as i32)\r\n}\r\n\r\n// Binomial co-efficient, but returning zeros for values outside of domain\r\nfn choose(n: usize, k: usize) -> u32 {\r\n    let mut n = n;\r\n    if k > n {\r\n        return 0;\r\n    }\r\n    let mut p = 1;\r\n    for i in 1..=(n - k) {\r\n        p *= n;\r\n        p /= i;\r\n        n -= 1;\r\n    }\r\n    p as u32\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::mindist::A_r;\r\n    use crate::mindist::{choose, D_rk};\r\n    use crate::{CubicBez, Line, PathSeg, Vec2};\r\n\r\n    #[test]\r\n    fn test_choose() {\r\n        assert_eq!(choose(6, 0), 1);\r\n        assert_eq!(choose(6, 1), 6);\r\n        assert_eq!(choose(6, 2), 15);\r\n    }\r\n\r\n    #[test]\r\n    fn test_d_rk() {\r\n        let bez1 = vec![\r\n            Vec2::new(129.0, 139.0),\r\n            Vec2::new(190.0, 139.0),\r\n            Vec2::new(201.0, 364.0),\r\n            Vec2::new(90.0, 364.0),\r\n        ];\r\n        let bez2 = vec![\r\n            Vec2::new(309.0, 159.0),\r\n            Vec2::new(178.0, 159.0),\r\n            Vec2::new(215.0, 408.0),\r\n            Vec2::new(309.0, 408.0),\r\n        ];\r\n        let b = A_r(1, &bez2);\r\n        assert!((b - 80283.0).abs() < 0.005, \"B_1(Q)={b:?}\");\r\n        let d = D_rk(0, 1, &bez1, &bez2);\r\n        assert!((d - 9220.0).abs() < 0.005, \"D={d:?}\");\r\n    }\r\n\r\n    #[test]\r\n    fn test_mindist() {\r\n        let bez1 = PathSeg::Cubic(CubicBez::new(\r\n            (129.0, 139.0),\r\n            (190.0, 139.0),\r\n            (201.0, 364.0),\r\n            (90.0, 364.0),\r\n        ));\r\n        let bez2 = PathSeg::Cubic(CubicBez::new(\r\n            (309.0, 159.0),\r\n            (178.0, 159.0),\r\n            (215.0, 408.0),\r\n            (309.0, 408.0),\r\n        ));\r\n        let mindist = bez1.min_dist(bez2, 0.001);\r\n        assert!((mindist.distance - 50.9966).abs() < 0.5);\r\n    }\r\n\r\n    #[test]\r\n    fn test_overflow() {\r\n        let bez1 = PathSeg::Cubic(CubicBez::new(\r\n            (232.0, 126.0),\r\n            (134.0, 126.0),\r\n            (139.0, 232.0),\r\n            (141.0, 301.0),\r\n        ));\r\n        let bez2 = PathSeg::Line(Line::new((359.0, 416.0), (367.0, 755.0)));\r\n        let mindist = bez1.min_dist(bez2, 0.001);\r\n        assert!((mindist.distance - 246.4731222669117).abs() < 0.5);\r\n    }\r\n\r\n    #[test]\r\n    fn test_out_of_order() {\r\n        let bez1 = PathSeg::Cubic(CubicBez::new(\r\n            (287.0, 182.0),\r\n            (346.0, 277.0),\r\n            (356.0, 299.0),\r\n            (359.0, 416.0),\r\n        ));\r\n        let bez2 = PathSeg::Line(Line::new((141.0, 301.0), (152.0, 709.0)));\r\n        let mindist1 = bez1.min_dist(bez2, 0.5);\r\n        let mindist2 = bez2.min_dist(bez1, 0.5);\r\n        assert!((mindist1.distance - mindist2.distance).abs() < 0.5);\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/offset.rs",
      "sha256": "4b21d1112f959eb3815b0ed6120db5784c7ac4d070929eecdf82ee59d7ea957b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 The Kurbo Authors\r\n//\r\n// Licensed under the Apache License, Version 2.0 (the \"License\");\r\n// you may not use this file except in compliance with the License.\r\n// You may obtain a copy of the License at\r\n//\r\n// https://www.apache.org/licenses/LICENSE-2.0\r\n//\r\n// Unless required by applicable law or agreed to in writing, software\r\n// distributed under the License is distributed on an \"AS IS\" BASIS,\r\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n// See the License for the specific language governing permissions and\r\n// limitations under the License.\r\n\r\n//! Computation of offset curves of cubic Béziers, based on a curve fitting\r\n//! approach.\r\n//!\r\n//! See the [Parallel curves of cubic Béziers] blog post for a discussion of how\r\n//! this algorithm works and what kind of results can be expected. In general, it\r\n//! is expected to perform much better than most published algorithms. The number\r\n//! of curve segments needed to attain a given accuracy scales as O(n^6) with\r\n//! accuracy.\r\n//!\r\n//! In general, to compute the offset curve (also known as parallel curve) of\r\n//! a cubic Bézier segment, create a [`CubicOffset`] struct with the curve\r\n//! segment and offset, then use [`fit_to_bezpath`] or [`fit_to_bezpath_opt`]\r\n//! depending on how much time to spend optimizing the resulting path.\r\n//!\r\n//! [`fit_to_bezpath`]: crate::fit_to_bezpath\r\n//! [`fit_to_bezpath_opt`]: crate::fit_to_bezpath_opt\r\n//! [Parallel curves of cubic Béziers]: https://raphlinus.github.io/curves/2022/09/09/parallel-beziers.html\r\nuse core::ops::Range;\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\nuse crate::{\r\n    common::solve_itp, CubicBez, CurveFitSample, ParamCurve, ParamCurveDeriv, ParamCurveFit, Point,\r\n    QuadBez, Vec2,\r\n};\r\n\r\n/// The offset curve of a cubic Bézier.\r\n///\r\n/// This is a representation of the offset curve of a cubic Bézier segment, for\r\n/// purposes of curve fitting.\r\n///\r\n/// See the [module-level documentation] for a bit more discussion of the approach,\r\n/// and how this struct is to be used.\r\n///\r\n/// [module-level documentation]: crate::offset\r\npub struct CubicOffset {\r\n    /// Source curve.\r\n    c: CubicBez,\r\n    /// Derivative of source curve.\r\n    q: QuadBez,\r\n    /// Offset.\r\n    d: f64,\r\n    // c0 + c1 t + c2 t^2 is the cross product of second and first\r\n    // derivatives of the underlying cubic, multiplied by offset (for\r\n    // computing cusp).\r\n    c0: f64,\r\n    c1: f64,\r\n    c2: f64,\r\n}\r\n\r\nimpl CubicOffset {\r\n    /// Create a new curve from Bézier segment and offset.\r\n    pub fn new(c: CubicBez, d: f64) -> Self {\r\n        let q = c.deriv();\r\n        let d0 = q.p0.to_vec2();\r\n        let d1 = 2.0 * (q.p1 - q.p0);\r\n        let d2 = q.p0.to_vec2() - 2.0 * q.p1.to_vec2() + q.p2.to_vec2();\r\n        CubicOffset {\r\n            c,\r\n            q,\r\n            d,\r\n            c0: d * d1.cross(d0),\r\n            c1: d * 2.0 * d2.cross(d0),\r\n            c2: d * d2.cross(d1),\r\n        }\r\n    }\r\n\r\n    fn eval_offset(&self, t: f64) -> Vec2 {\r\n        let dp = self.q.eval(t).to_vec2();\r\n        let norm = Vec2::new(-dp.y, dp.x);\r\n        // TODO: deal with hypot = 0\r\n        norm * self.d / dp.hypot()\r\n    }\r\n\r\n    fn eval(&self, t: f64) -> Point {\r\n        // Point on source curve.\r\n        self.c.eval(t) + self.eval_offset(t)\r\n    }\r\n\r\n    /// Evaluate derivative of curve.\r\n    fn eval_deriv(&self, t: f64) -> Vec2 {\r\n        self.cusp_sign(t) * self.q.eval(t).to_vec2()\r\n    }\r\n\r\n    // Compute a function which has a zero-crossing at cusps, and is\r\n    // positive at low curvatures on the source curve.\r\n    fn cusp_sign(&self, t: f64) -> f64 {\r\n        let ds2 = self.q.eval(t).to_vec2().hypot2();\r\n        ((self.c2 * t + self.c1) * t + self.c0) / (ds2 * ds2.sqrt()) + 1.0\r\n    }\r\n}\r\n\r\nimpl ParamCurveFit for CubicOffset {\r\n    fn sample_pt_tangent(&self, t: f64, sign: f64) -> CurveFitSample {\r\n        let p = self.eval(t);\r\n        const CUSP_EPS: f64 = 1e-8;\r\n        let mut cusp = self.cusp_sign(t);\r\n        if cusp.abs() < CUSP_EPS {\r\n            // This is a numerical derivative, which is probably good enough\r\n            // for all practical purposes, but an analytical derivative would\r\n            // be more elegant.\r\n            //\r\n            // Also, we're not dealing with second or higher order cusps.\r\n            cusp = sign * (self.cusp_sign(t + CUSP_EPS) - self.cusp_sign(t - CUSP_EPS));\r\n        }\r\n        let tangent = self.q.eval(t).to_vec2() * cusp.signum();\r\n        CurveFitSample { p, tangent }\r\n    }\r\n\r\n    fn sample_pt_deriv(&self, t: f64) -> (Point, Vec2) {\r\n        (self.eval(t), self.eval_deriv(t))\r\n    }\r\n\r\n    fn break_cusp(&self, range: Range<f64>) -> Option<f64> {\r\n        const CUSP_EPS: f64 = 1e-8;\r\n        // When an endpoint is on (or very near) a cusp, move just far enough\r\n        // away from the cusp that we're confident we have the right sign.\r\n        let break_cusp_help = |mut x, mut d| {\r\n            let mut cusp = self.cusp_sign(x);\r\n            while cusp.abs() < CUSP_EPS && d < 1.0 {\r\n                x += d;\r\n                let old_cusp = cusp;\r\n                cusp = self.cusp_sign(x);\r\n                if cusp.abs() > old_cusp.abs() {\r\n                    break;\r\n                }\r\n                d *= 2.0;\r\n            }\r\n            (x, cusp)\r\n        };\r\n        let (a, cusp0) = break_cusp_help(range.start, 1e-12);\r\n        let (b, cusp1) = break_cusp_help(range.end, -1e-12);\r\n        if a >= b || cusp0 * cusp1 >= 0.0 {\r\n            // Discussion point: maybe we should search for double cusps in the interior\r\n            // of the range.\r\n            return None;\r\n        }\r\n        let s = cusp1.signum();\r\n        let f = |t| s * self.cusp_sign(t);\r\n        let k1 = 0.2 / (b - a);\r\n        const ITP_EPS: f64 = 1e-12;\r\n        let x = solve_itp(f, a, b, ITP_EPS, 1, k1, s * cusp0, s * cusp1);\r\n        Some(x)\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/param_curve.rs",
      "sha256": "26cb79035285a4e164b17ead95848f4388b47f3b772c7e1ea1c18364c29fdf54",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A trait for curves parametrized by a scalar.\r\n\r\nuse core::ops::Range;\r\n\r\nuse arrayvec::ArrayVec;\r\n\r\nuse crate::{common, Point, Rect};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A default value for methods that take an 'accuracy' argument.\r\n///\r\n/// This value is intended to be suitable for general-purpose use, such as\r\n/// 2d graphics.\r\npub const DEFAULT_ACCURACY: f64 = 1e-6;\r\n\r\n/// A curve parametrized by a scalar.\r\n///\r\n/// If the result is interpreted as a point, this represents a curve.\r\n/// But the result can be interpreted as a vector as well.\r\npub trait ParamCurve: Sized {\r\n    /// Evaluate the curve at parameter `t`.\r\n    ///\r\n    /// Generally `t` is in the range [0..1].\r\n    fn eval(&self, t: f64) -> Point;\r\n\r\n    /// Get a subsegment of the curve for the given parameter range.\r\n    fn subsegment(&self, range: Range<f64>) -> Self;\r\n\r\n    /// Subdivide into (roughly) halves.\r\n    #[inline]\r\n    fn subdivide(&self) -> (Self, Self) {\r\n        (self.subsegment(0.0..0.5), self.subsegment(0.5..1.0))\r\n    }\r\n\r\n    /// The start point.\r\n    fn start(&self) -> Point {\r\n        self.eval(0.0)\r\n    }\r\n\r\n    /// The end point.\r\n    fn end(&self) -> Point {\r\n        self.eval(1.0)\r\n    }\r\n}\r\n\r\n// TODO: I might not want to have separate traits for all these.\r\n\r\n/// A differentiable parametrized curve.\r\npub trait ParamCurveDeriv {\r\n    /// The parametric curve obtained by taking the derivative of this one.\r\n    type DerivResult: ParamCurve;\r\n\r\n    /// The derivative of the curve.\r\n    ///\r\n    /// Note that the type of the return value is somewhat inaccurate, as\r\n    /// the derivative of a curve (mapping of param to point) is a mapping\r\n    /// of param to vector. We choose to accept this rather than have a\r\n    /// more complex type scheme.\r\n    fn deriv(&self) -> Self::DerivResult;\r\n\r\n    /// Estimate arclength using Gaussian quadrature.\r\n    ///\r\n    /// The coefficients are assumed to cover the range (-1..1), which is\r\n    /// traditional.\r\n    #[inline]\r\n    fn gauss_arclen(&self, coeffs: &[(f64, f64)]) -> f64 {\r\n        let d = self.deriv();\r\n        coeffs\r\n            .iter()\r\n            .map(|(wi, xi)| wi * d.eval(0.5 * (xi + 1.0)).to_vec2().hypot())\r\n            .sum::<f64>()\r\n            * 0.5\r\n    }\r\n}\r\n\r\n/// A parametrized curve that can have its arc length measured.\r\npub trait ParamCurveArclen: ParamCurve {\r\n    /// The arc length of the curve.\r\n    ///\r\n    /// The result is accurate to the given accuracy (subject to\r\n    /// roundoff errors for ridiculously low values). Compute time\r\n    /// may vary with accuracy, if the curve needs to be subdivided.\r\n    fn arclen(&self, accuracy: f64) -> f64;\r\n\r\n    /// Solve for the parameter that has the given arc length from the start.\r\n    ///\r\n    /// This implementation uses the IPT method, as provided by\r\n    /// [`common::solve_itp`]. This is as robust as bisection but\r\n    /// typically converges faster. In addition, the method takes\r\n    /// care to compute arc lengths of increasingly smaller segments\r\n    /// of the curve, as that is likely faster than repeatedly\r\n    /// computing the arc length of the segment starting at t=0.\r\n    fn inv_arclen(&self, arclen: f64, accuracy: f64) -> f64 {\r\n        if arclen <= 0.0 {\r\n            return 0.0;\r\n        }\r\n        let total_arclen = self.arclen(accuracy);\r\n        if arclen >= total_arclen {\r\n            return 1.0;\r\n        }\r\n        let mut t_last = 0.0;\r\n        let mut arclen_last = 0.0;\r\n        let epsilon = accuracy / total_arclen;\r\n        let n = 1.0 - epsilon.log2().ceil().min(0.0);\r\n        let inner_accuracy = accuracy / n;\r\n        let f = |t: f64| {\r\n            let (range, dir) = if t > t_last {\r\n                (t_last..t, 1.0)\r\n            } else {\r\n                (t..t_last, -1.0)\r\n            };\r\n            let arc = self.subsegment(range).arclen(inner_accuracy);\r\n            arclen_last += arc * dir;\r\n            t_last = t;\r\n            arclen_last - arclen\r\n        };\r\n        common::solve_itp(f, 0.0, 1.0, epsilon, 1, 0.2, -arclen, total_arclen - arclen)\r\n    }\r\n}\r\n\r\n/// A parametrized curve that can have its signed area measured.\r\npub trait ParamCurveArea {\r\n    /// Compute the signed area under the curve.\r\n    ///\r\n    /// For a closed path, the signed area of the path is the sum of signed\r\n    /// areas of the segments. This is a variant of the \"shoelace formula.\"\r\n    /// See:\r\n    /// <https://github.com/Pomax/bezierinfo/issues/44> and\r\n    /// <http://ich.deanmcnamee.com/graphics/2016/03/30/CurveArea.html>\r\n    ///\r\n    /// This can be computed exactly for Béziers thanks to Green's theorem,\r\n    /// and also for simple curves such as circular arcs. For more exotic\r\n    /// curves, it's probably best to subdivide to cubics. We leave that\r\n    /// to the caller, which is why we don't give an accuracy param here.\r\n    fn signed_area(&self) -> f64;\r\n}\r\n\r\n/// The nearest position on a curve to some point.\r\n///\r\n/// This is returned by [`ParamCurveNearest::nearest`]\r\n#[derive(Debug, Clone, Copy)]\r\npub struct Nearest {\r\n    /// The square of the distance from the nearest position on the curve\r\n    /// to the given point.\r\n    pub distance_sq: f64,\r\n    /// The position on the curve of the nearest point, as a parameter.\r\n    ///\r\n    /// To resolve this to a [`Point`], use [`ParamCurve::eval`].\r\n    pub t: f64,\r\n}\r\n\r\n/// A parametrized curve that reports the nearest point.\r\npub trait ParamCurveNearest {\r\n    /// Find the position on the curve that is nearest to the given point.\r\n    ///\r\n    /// This returns a [`Nearest`] struct that contains information about\r\n    /// the position.\r\n    fn nearest(&self, p: Point, accuracy: f64) -> Nearest;\r\n}\r\n\r\n/// A parametrized curve that reports its curvature.\r\npub trait ParamCurveCurvature: ParamCurveDeriv\r\nwhere\r\n    Self::DerivResult: ParamCurveDeriv,\r\n{\r\n    /// Compute the signed curvature at parameter `t`.\r\n    #[inline]\r\n    fn curvature(&self, t: f64) -> f64 {\r\n        let deriv = self.deriv();\r\n        let deriv2 = deriv.deriv();\r\n        let d = deriv.eval(t).to_vec2();\r\n        let d2 = deriv2.eval(t).to_vec2();\r\n        // TODO: What's the convention for sign? I think it should match signed\r\n        // area - a positive area curve should have positive curvature.\r\n        d2.cross(d) * d.hypot2().powf(-1.5)\r\n    }\r\n}\r\n\r\n/// The maximum number of extrema that can be reported in the `ParamCurveExtrema` trait.\r\n///\r\n/// This is 4 to support cubic Béziers. If other curves are used, they should be\r\n/// subdivided to limit the number of extrema.\r\npub const MAX_EXTREMA: usize = 4;\r\n\r\n/// A parametrized curve that reports its extrema.\r\npub trait ParamCurveExtrema: ParamCurve {\r\n    /// Compute the extrema of the curve.\r\n    ///\r\n    /// Only extrema within the interior of the curve count.\r\n    /// At most four extrema can be reported, which is sufficient for\r\n    /// cubic Béziers.\r\n    ///\r\n    /// The extrema should be reported in increasing parameter order.\r\n    fn extrema(&self) -> ArrayVec<f64, MAX_EXTREMA>;\r\n\r\n    /// Return parameter ranges, each of which is monotonic within the range.\r\n    fn extrema_ranges(&self) -> ArrayVec<Range<f64>, { MAX_EXTREMA + 1 }> {\r\n        let mut result = ArrayVec::new();\r\n        let mut t0 = 0.0;\r\n        for t in self.extrema() {\r\n            result.push(t0..t);\r\n            t0 = t;\r\n        }\r\n        result.push(t0..1.0);\r\n        result\r\n    }\r\n\r\n    /// The smallest rectangle that encloses the curve in the range (0..1).\r\n    fn bounding_box(&self) -> Rect {\r\n        let mut bbox = Rect::from_points(self.start(), self.end());\r\n        for t in self.extrema() {\r\n            bbox = bbox.union_pt(self.eval(t))\r\n        }\r\n        bbox\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/point.rs",
      "sha256": "42977c1c6a9be6d591e46456d48d648d41e1259b3877949a07566b9d0d0250ee",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A 2D point.\r\n\r\nuse core::fmt;\r\nuse core::ops::{Add, AddAssign, Sub, SubAssign};\r\n\r\nuse crate::common::FloatExt;\r\nuse crate::Vec2;\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A 2D point.\r\n///\r\n/// This type represents a point in 2D space. It has the same layout as [`Vec2`][crate::Vec2], but\r\n/// its meaning is different: `Vec2` represents a change in location (for example velocity).\r\n///\r\n/// In general, `kurbo` overloads math operators where it makes sense, for example implementing\r\n/// `Affine * Point` as the point under the affine transformation. However `Point + Point` and\r\n/// `f64 * Point` are not implemented, because the operations do not make geometric sense. If you\r\n/// need to apply these operations, then 1) check what you're doing makes geometric sense, then 2)\r\n/// use [`Point::to_vec2`] to convert the point to a `Vec2`.\r\n#[derive(Clone, Copy, Default, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct Point {\r\n    /// The x coordinate.\r\n    pub x: f64,\r\n    /// The y coordinate.\r\n    pub y: f64,\r\n}\r\n\r\nimpl Point {\r\n    /// The point (0, 0).\r\n    pub const ZERO: Point = Point::new(0., 0.);\r\n\r\n    /// The point at the origin; (0, 0).\r\n    pub const ORIGIN: Point = Point::new(0., 0.);\r\n\r\n    /// Create a new `Point` with the provided `x` and `y` coordinates.\r\n    #[inline]\r\n    pub const fn new(x: f64, y: f64) -> Self {\r\n        Point { x, y }\r\n    }\r\n\r\n    /// Convert this point into a `Vec2`.\r\n    #[inline]\r\n    pub const fn to_vec2(self) -> Vec2 {\r\n        Vec2::new(self.x, self.y)\r\n    }\r\n\r\n    /// Linearly interpolate between two points.\r\n    #[inline]\r\n    pub fn lerp(self, other: Point, t: f64) -> Point {\r\n        self.to_vec2().lerp(other.to_vec2(), t).to_point()\r\n    }\r\n\r\n    /// Determine the midpoint of two points.\r\n    #[inline]\r\n    pub fn midpoint(self, other: Point) -> Point {\r\n        Point::new(0.5 * (self.x + other.x), 0.5 * (self.y + other.y))\r\n    }\r\n\r\n    /// Euclidean distance.\r\n    #[inline]\r\n    pub fn distance(self, other: Point) -> f64 {\r\n        (self - other).hypot()\r\n    }\r\n\r\n    /// Squared Euclidean distance.\r\n    #[inline]\r\n    pub fn distance_squared(self, other: Point) -> f64 {\r\n        (self - other).hypot2()\r\n    }\r\n\r\n    /// Returns a new `Point`,\r\n    /// with `x` and `y` rounded to the nearest integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Point;\r\n    /// let a = Point::new(3.3, 3.6).round();\r\n    /// let b = Point::new(3.0, -3.1).round();\r\n    /// assert_eq!(a.x, 3.0);\r\n    /// assert_eq!(a.y, 4.0);\r\n    /// assert_eq!(b.x, 3.0);\r\n    /// assert_eq!(b.y, -3.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn round(self) -> Point {\r\n        Point::new(self.x.round(), self.y.round())\r\n    }\r\n\r\n    /// Returns a new `Point`,\r\n    /// with `x` and `y` rounded up to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Point;\r\n    /// let a = Point::new(3.3, 3.6).ceil();\r\n    /// let b = Point::new(3.0, -3.1).ceil();\r\n    /// assert_eq!(a.x, 4.0);\r\n    /// assert_eq!(a.y, 4.0);\r\n    /// assert_eq!(b.x, 3.0);\r\n    /// assert_eq!(b.y, -3.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn ceil(self) -> Point {\r\n        Point::new(self.x.ceil(), self.y.ceil())\r\n    }\r\n\r\n    /// Returns a new `Point`,\r\n    /// with `x` and `y` rounded down to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Point;\r\n    /// let a = Point::new(3.3, 3.6).floor();\r\n    /// let b = Point::new(3.0, -3.1).floor();\r\n    /// assert_eq!(a.x, 3.0);\r\n    /// assert_eq!(a.y, 3.0);\r\n    /// assert_eq!(b.x, 3.0);\r\n    /// assert_eq!(b.y, -4.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn floor(self) -> Point {\r\n        Point::new(self.x.floor(), self.y.floor())\r\n    }\r\n\r\n    /// Returns a new `Point`,\r\n    /// with `x` and `y` rounded away from zero to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Point;\r\n    /// let a = Point::new(3.3, 3.6).expand();\r\n    /// let b = Point::new(3.0, -3.1).expand();\r\n    /// assert_eq!(a.x, 4.0);\r\n    /// assert_eq!(a.y, 4.0);\r\n    /// assert_eq!(b.x, 3.0);\r\n    /// assert_eq!(b.y, -4.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn expand(self) -> Point {\r\n        Point::new(self.x.expand(), self.y.expand())\r\n    }\r\n\r\n    /// Returns a new `Point`,\r\n    /// with `x` and `y` rounded towards zero to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Point;\r\n    /// let a = Point::new(3.3, 3.6).trunc();\r\n    /// let b = Point::new(3.0, -3.1).trunc();\r\n    /// assert_eq!(a.x, 3.0);\r\n    /// assert_eq!(a.y, 3.0);\r\n    /// assert_eq!(b.x, 3.0);\r\n    /// assert_eq!(b.y, -3.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn trunc(self) -> Point {\r\n        Point::new(self.x.trunc(), self.y.trunc())\r\n    }\r\n\r\n    /// Is this point finite?\r\n    #[inline]\r\n    pub fn is_finite(self) -> bool {\r\n        self.x.is_finite() && self.y.is_finite()\r\n    }\r\n\r\n    /// Is this point NaN?\r\n    #[inline]\r\n    pub fn is_nan(self) -> bool {\r\n        self.x.is_nan() || self.y.is_nan()\r\n    }\r\n}\r\n\r\nimpl From<(f64, f64)> for Point {\r\n    #[inline]\r\n    fn from(v: (f64, f64)) -> Point {\r\n        Point { x: v.0, y: v.1 }\r\n    }\r\n}\r\n\r\nimpl From<Point> for (f64, f64) {\r\n    #[inline]\r\n    fn from(v: Point) -> (f64, f64) {\r\n        (v.x, v.y)\r\n    }\r\n}\r\n\r\nimpl Add<Vec2> for Point {\r\n    type Output = Point;\r\n\r\n    #[inline]\r\n    fn add(self, other: Vec2) -> Self {\r\n        Point::new(self.x + other.x, self.y + other.y)\r\n    }\r\n}\r\n\r\nimpl AddAssign<Vec2> for Point {\r\n    #[inline]\r\n    fn add_assign(&mut self, other: Vec2) {\r\n        *self = Point::new(self.x + other.x, self.y + other.y)\r\n    }\r\n}\r\n\r\nimpl Sub<Vec2> for Point {\r\n    type Output = Point;\r\n\r\n    #[inline]\r\n    fn sub(self, other: Vec2) -> Self {\r\n        Point::new(self.x - other.x, self.y - other.y)\r\n    }\r\n}\r\n\r\nimpl SubAssign<Vec2> for Point {\r\n    #[inline]\r\n    fn sub_assign(&mut self, other: Vec2) {\r\n        *self = Point::new(self.x - other.x, self.y - other.y)\r\n    }\r\n}\r\n\r\nimpl Add<(f64, f64)> for Point {\r\n    type Output = Point;\r\n\r\n    #[inline]\r\n    fn add(self, (x, y): (f64, f64)) -> Self {\r\n        Point::new(self.x + x, self.y + y)\r\n    }\r\n}\r\n\r\nimpl AddAssign<(f64, f64)> for Point {\r\n    #[inline]\r\n    fn add_assign(&mut self, (x, y): (f64, f64)) {\r\n        *self = Point::new(self.x + x, self.y + y)\r\n    }\r\n}\r\n\r\nimpl Sub<(f64, f64)> for Point {\r\n    type Output = Point;\r\n\r\n    #[inline]\r\n    fn sub(self, (x, y): (f64, f64)) -> Self {\r\n        Point::new(self.x - x, self.y - y)\r\n    }\r\n}\r\n\r\nimpl SubAssign<(f64, f64)> for Point {\r\n    #[inline]\r\n    fn sub_assign(&mut self, (x, y): (f64, f64)) {\r\n        *self = Point::new(self.x - x, self.y - y)\r\n    }\r\n}\r\n\r\nimpl Sub<Point> for Point {\r\n    type Output = Vec2;\r\n\r\n    #[inline]\r\n    fn sub(self, other: Point) -> Vec2 {\r\n        Vec2::new(self.x - other.x, self.y - other.y)\r\n    }\r\n}\r\n\r\nimpl fmt::Debug for Point {\r\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\r\n        write!(f, \"({:?}, {:?})\", self.x, self.y)\r\n    }\r\n}\r\n\r\nimpl fmt::Display for Point {\r\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\r\n        write!(formatter, \"(\")?;\r\n        fmt::Display::fmt(&self.x, formatter)?;\r\n        write!(formatter, \", \")?;\r\n        fmt::Display::fmt(&self.y, formatter)?;\r\n        write!(formatter, \")\")\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use super::*;\r\n    #[test]\r\n    fn point_arithmetic() {\r\n        assert_eq!(\r\n            Point::new(0., 0.) - Vec2::new(10., 0.),\r\n            Point::new(-10., 0.)\r\n        );\r\n        assert_eq!(\r\n            Point::new(0., 0.) - Point::new(-5., 101.),\r\n            Vec2::new(5., -101.)\r\n        );\r\n    }\r\n\r\n    #[test]\r\n    #[allow(clippy::float_cmp)]\r\n    fn distance() {\r\n        let p1 = Point::new(0., 10.);\r\n        let p2 = Point::new(0., 5.);\r\n        assert_eq!(p1.distance(p2), 5.);\r\n\r\n        let p1 = Point::new(-11., 1.);\r\n        let p2 = Point::new(-7., -2.);\r\n        assert_eq!(p1.distance(p2), 5.);\r\n    }\r\n\r\n    #[test]\r\n    fn display() {\r\n        let p = Point::new(0.12345, 9.87654);\r\n        assert_eq!(format!(\"{p}\"), \"(0.12345, 9.87654)\");\r\n\r\n        let p = Point::new(0.12345, 9.87654);\r\n        assert_eq!(format!(\"{p:.2}\"), \"(0.12, 9.88)\");\r\n    }\r\n}\r\n\r\n#[cfg(feature = \"mint\")]\r\nimpl From<Point> for mint::Point2<f64> {\r\n    #[inline]\r\n    fn from(p: Point) -> mint::Point2<f64> {\r\n        mint::Point2 { x: p.x, y: p.y }\r\n    }\r\n}\r\n\r\n#[cfg(feature = \"mint\")]\r\nimpl From<mint::Point2<f64>> for Point {\r\n    #[inline]\r\n    fn from(p: mint::Point2<f64>) -> Point {\r\n        Point { x: p.x, y: p.y }\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/quadbez.rs",
      "sha256": "deb6971c8a0403ac9a1a9a84f40b0c630b056f9edd75aea74b062eae555b9903",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Quadratic Bézier segments.\r\n\r\nuse core::ops::{Mul, Range};\r\n\r\nuse arrayvec::ArrayVec;\r\n\r\nuse crate::common::solve_cubic;\r\nuse crate::MAX_EXTREMA;\r\nuse crate::{\r\n    Affine, CubicBez, Line, Nearest, ParamCurve, ParamCurveArclen, ParamCurveArea,\r\n    ParamCurveCurvature, ParamCurveDeriv, ParamCurveExtrema, ParamCurveNearest, PathEl, Point,\r\n    Rect, Shape,\r\n};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A single quadratic Bézier segment.\r\n#[derive(Clone, Copy, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\n#[allow(missing_docs)]\r\npub struct QuadBez {\r\n    pub p0: Point,\r\n    pub p1: Point,\r\n    pub p2: Point,\r\n}\r\n\r\nimpl QuadBez {\r\n    /// Create a new quadratic Bézier segment.\r\n    #[inline]\r\n    pub fn new<V: Into<Point>>(p0: V, p1: V, p2: V) -> QuadBez {\r\n        QuadBez {\r\n            p0: p0.into(),\r\n            p1: p1.into(),\r\n            p2: p2.into(),\r\n        }\r\n    }\r\n\r\n    /// Raise the order by 1.\r\n    ///\r\n    /// Returns a cubic Bézier segment that exactly represents this quadratic.\r\n    #[inline]\r\n    pub fn raise(&self) -> CubicBez {\r\n        CubicBez::new(\r\n            self.p0,\r\n            self.p0 + (2.0 / 3.0) * (self.p1 - self.p0),\r\n            self.p2 + (2.0 / 3.0) * (self.p1 - self.p2),\r\n            self.p2,\r\n        )\r\n    }\r\n\r\n    /// Estimate the number of subdivisions for flattening.\r\n    pub(crate) fn estimate_subdiv(&self, sqrt_tol: f64) -> FlattenParams {\r\n        // Determine transformation to $y = x^2$ parabola.\r\n        let d01 = self.p1 - self.p0;\r\n        let d12 = self.p2 - self.p1;\r\n        let dd = d01 - d12;\r\n        let cross = (self.p2 - self.p0).cross(dd);\r\n        let x0 = d01.dot(dd) * cross.recip();\r\n        let x2 = d12.dot(dd) * cross.recip();\r\n        let scale = (cross / (dd.hypot() * (x2 - x0))).abs();\r\n\r\n        // Compute number of subdivisions needed.\r\n        let a0 = approx_parabola_integral(x0);\r\n        let a2 = approx_parabola_integral(x2);\r\n        let val = if scale.is_finite() {\r\n            let da = (a2 - a0).abs();\r\n            let sqrt_scale = scale.sqrt();\r\n            if x0.signum() == x2.signum() {\r\n                da * sqrt_scale\r\n            } else {\r\n                // Handle cusp case (segment contains curvature maximum)\r\n                let xmin = sqrt_tol / sqrt_scale;\r\n                sqrt_tol * da / approx_parabola_integral(xmin)\r\n            }\r\n        } else {\r\n            0.0\r\n        };\r\n        let u0 = approx_parabola_inv_integral(a0);\r\n        let u2 = approx_parabola_inv_integral(a2);\r\n        let uscale = (u2 - u0).recip();\r\n        FlattenParams {\r\n            a0,\r\n            a2,\r\n            u0,\r\n            uscale,\r\n            val,\r\n        }\r\n    }\r\n\r\n    // Maps a value from 0..1 to 0..1.\r\n    pub(crate) fn determine_subdiv_t(&self, params: &FlattenParams, x: f64) -> f64 {\r\n        let a = params.a0 + (params.a2 - params.a0) * x;\r\n        let u = approx_parabola_inv_integral(a);\r\n        (u - params.u0) * params.uscale\r\n    }\r\n\r\n    /// Is this quadratic Bezier curve finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.p0.is_finite() && self.p1.is_finite() && self.p2.is_finite()\r\n    }\r\n\r\n    /// Is this quadratic Bezier curve NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.p0.is_nan() || self.p1.is_nan() || self.p2.is_nan()\r\n    }\r\n}\r\n\r\n/// An iterator for quadratic beziers.\r\npub struct QuadBezIter {\r\n    quad: QuadBez,\r\n    ix: usize,\r\n}\r\n\r\nimpl Shape for QuadBez {\r\n    type PathElementsIter<'iter> = QuadBezIter;\r\n\r\n    #[inline]\r\n    fn path_elements(&self, _tolerance: f64) -> QuadBezIter {\r\n        QuadBezIter { quad: *self, ix: 0 }\r\n    }\r\n\r\n    fn area(&self) -> f64 {\r\n        0.0\r\n    }\r\n\r\n    #[inline]\r\n    fn perimeter(&self, accuracy: f64) -> f64 {\r\n        self.arclen(accuracy)\r\n    }\r\n\r\n    fn winding(&self, _pt: Point) -> i32 {\r\n        0\r\n    }\r\n\r\n    #[inline]\r\n    fn bounding_box(&self) -> Rect {\r\n        ParamCurveExtrema::bounding_box(self)\r\n    }\r\n}\r\n\r\nimpl Iterator for QuadBezIter {\r\n    type Item = PathEl;\r\n\r\n    fn next(&mut self) -> Option<PathEl> {\r\n        self.ix += 1;\r\n        match self.ix {\r\n            1 => Some(PathEl::MoveTo(self.quad.p0)),\r\n            2 => Some(PathEl::QuadTo(self.quad.p1, self.quad.p2)),\r\n            _ => None,\r\n        }\r\n    }\r\n}\r\n\r\npub(crate) struct FlattenParams {\r\n    a0: f64,\r\n    a2: f64,\r\n    u0: f64,\r\n    uscale: f64,\r\n    /// The number of subdivisions * 2 * sqrt_tol.\r\n    pub(crate) val: f64,\r\n}\r\n\r\n/// An approximation to $\\int (1 + 4x^2) ^ -0.25 dx$\r\n///\r\n/// This is used for flattening curves.\r\nfn approx_parabola_integral(x: f64) -> f64 {\r\n    const D: f64 = 0.67;\r\n    x / (1.0 - D + (D.powi(4) + 0.25 * x * x).sqrt().sqrt())\r\n}\r\n\r\n/// An approximation to the inverse parabola integral.\r\nfn approx_parabola_inv_integral(x: f64) -> f64 {\r\n    const B: f64 = 0.39;\r\n    x * (1.0 - B + (B * B + 0.25 * x * x).sqrt())\r\n}\r\n\r\nimpl ParamCurve for QuadBez {\r\n    #[inline]\r\n    fn eval(&self, t: f64) -> Point {\r\n        let mt = 1.0 - t;\r\n        (self.p0.to_vec2() * (mt * mt)\r\n            + (self.p1.to_vec2() * (mt * 2.0) + self.p2.to_vec2() * t) * t)\r\n            .to_point()\r\n    }\r\n\r\n    fn subsegment(&self, range: Range<f64>) -> QuadBez {\r\n        let (t0, t1) = (range.start, range.end);\r\n        let p0 = self.eval(t0);\r\n        let p2 = self.eval(t1);\r\n        let p1 = p0 + (self.p1 - self.p0).lerp(self.p2 - self.p1, t0) * (t1 - t0);\r\n        QuadBez { p0, p1, p2 }\r\n    }\r\n\r\n    /// Subdivide into halves, using de Casteljau.\r\n    #[inline]\r\n    fn subdivide(&self) -> (QuadBez, QuadBez) {\r\n        let pm = self.eval(0.5);\r\n        (\r\n            QuadBez::new(self.p0, self.p0.midpoint(self.p1), pm),\r\n            QuadBez::new(pm, self.p1.midpoint(self.p2), self.p2),\r\n        )\r\n    }\r\n\r\n    #[inline]\r\n    fn start(&self) -> Point {\r\n        self.p0\r\n    }\r\n\r\n    #[inline]\r\n    fn end(&self) -> Point {\r\n        self.p2\r\n    }\r\n}\r\n\r\nimpl ParamCurveDeriv for QuadBez {\r\n    type DerivResult = Line;\r\n\r\n    #[inline]\r\n    fn deriv(&self) -> Line {\r\n        Line::new(\r\n            (2.0 * (self.p1.to_vec2() - self.p0.to_vec2())).to_point(),\r\n            (2.0 * (self.p2.to_vec2() - self.p1.to_vec2())).to_point(),\r\n        )\r\n    }\r\n}\r\n\r\nimpl ParamCurveArclen for QuadBez {\r\n    /// Arclength of a quadratic Bézier segment.\r\n    ///\r\n    /// This computation is based on an analytical formula. Since that formula suffers\r\n    /// from numerical instability when the curve is very close to a straight line, we\r\n    /// detect that case and fall back to Legendre-Gauss quadrature.\r\n    ///\r\n    /// Accuracy should be better than 1e-13 over the entire range.\r\n    ///\r\n    /// Adapted from <http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/>\r\n    /// with permission.\r\n    fn arclen(&self, _accuracy: f64) -> f64 {\r\n        let d2 = self.p0.to_vec2() - 2.0 * self.p1.to_vec2() + self.p2.to_vec2();\r\n        let a = d2.hypot2();\r\n        let d1 = self.p1 - self.p0;\r\n        let c = d1.hypot2();\r\n        if a < 5e-4 * c {\r\n            // This case happens for nearly straight Béziers.\r\n            //\r\n            // Calculate arclength using Legendre-Gauss quadrature using formula from Behdad\r\n            // in https://github.com/Pomax/BezierInfo-2/issues/77\r\n            let v0 = (-0.492943519233745 * self.p0.to_vec2()\r\n                + 0.430331482911935 * self.p1.to_vec2()\r\n                + 0.0626120363218102 * self.p2.to_vec2())\r\n            .hypot();\r\n            let v1 = ((self.p2 - self.p0) * 0.4444444444444444).hypot();\r\n            let v2 = (-0.0626120363218102 * self.p0.to_vec2()\r\n                - 0.430331482911935 * self.p1.to_vec2()\r\n                + 0.492943519233745 * self.p2.to_vec2())\r\n            .hypot();\r\n            return v0 + v1 + v2;\r\n        }\r\n        let b = 2.0 * d2.dot(d1);\r\n\r\n        let sabc = (a + b + c).sqrt();\r\n        let a2 = a.powf(-0.5);\r\n        let a32 = a2.powi(3);\r\n        let c2 = 2.0 * c.sqrt();\r\n        let ba_c2 = b * a2 + c2;\r\n\r\n        let v0 = 0.25 * a2 * a2 * b * (2.0 * sabc - c2) + sabc;\r\n        // TODO: justify and fine-tune this exact constant.\r\n        if ba_c2 < 1e-13 {\r\n            // This case happens for Béziers with a sharp kink.\r\n            v0\r\n        } else {\r\n            v0 + 0.25\r\n                * a32\r\n                * (4.0 * c * a - b * b)\r\n                * (((2.0 * a + b) * a2 + 2.0 * sabc) / ba_c2).ln()\r\n        }\r\n    }\r\n}\r\n\r\nimpl ParamCurveArea for QuadBez {\r\n    #[inline]\r\n    fn signed_area(&self) -> f64 {\r\n        (self.p0.x * (2.0 * self.p1.y + self.p2.y) + 2.0 * self.p1.x * (self.p2.y - self.p0.y)\r\n            - self.p2.x * (self.p0.y + 2.0 * self.p1.y))\r\n            * (1.0 / 6.0)\r\n    }\r\n}\r\n\r\nimpl ParamCurveNearest for QuadBez {\r\n    /// Find the nearest point, using analytical algorithm based on cubic root finding.\r\n    fn nearest(&self, p: Point, _accuracy: f64) -> Nearest {\r\n        fn eval_t(p: Point, t_best: &mut f64, r_best: &mut Option<f64>, t: f64, p0: Point) {\r\n            let r = (p0 - p).hypot2();\r\n            if r_best.map(|r_best| r < r_best).unwrap_or(true) {\r\n                *r_best = Some(r);\r\n                *t_best = t;\r\n            }\r\n        }\r\n        fn try_t(\r\n            q: &QuadBez,\r\n            p: Point,\r\n            t_best: &mut f64,\r\n            r_best: &mut Option<f64>,\r\n            t: f64,\r\n        ) -> bool {\r\n            if !(0.0..=1.0).contains(&t) {\r\n                return true;\r\n            }\r\n            eval_t(p, t_best, r_best, t, q.eval(t));\r\n            false\r\n        }\r\n        let d0 = self.p1 - self.p0;\r\n        let d1 = self.p0.to_vec2() + self.p2.to_vec2() - 2.0 * self.p1.to_vec2();\r\n        let d = self.p0 - p;\r\n        let c0 = d.dot(d0);\r\n        let c1 = 2.0 * d0.hypot2() + d.dot(d1);\r\n        let c2 = 3.0 * d1.dot(d0);\r\n        let c3 = d1.hypot2();\r\n        let roots = solve_cubic(c0, c1, c2, c3);\r\n        let mut r_best = None;\r\n        let mut t_best = 0.0;\r\n        let mut need_ends = false;\r\n        for &t in &roots {\r\n            need_ends |= try_t(self, p, &mut t_best, &mut r_best, t);\r\n        }\r\n        if need_ends {\r\n            eval_t(p, &mut t_best, &mut r_best, 0.0, self.p0);\r\n            eval_t(p, &mut t_best, &mut r_best, 1.0, self.p2);\r\n        }\r\n\r\n        Nearest {\r\n            t: t_best,\r\n            distance_sq: r_best.unwrap(),\r\n        }\r\n    }\r\n}\r\n\r\nimpl ParamCurveCurvature for QuadBez {}\r\n\r\nimpl ParamCurveExtrema for QuadBez {\r\n    fn extrema(&self) -> ArrayVec<f64, MAX_EXTREMA> {\r\n        let mut result = ArrayVec::new();\r\n        let d0 = self.p1 - self.p0;\r\n        let d1 = self.p2 - self.p1;\r\n        let dd = d1 - d0;\r\n        if dd.x != 0.0 {\r\n            let t = -d0.x / dd.x;\r\n            if t > 0.0 && t < 1.0 {\r\n                result.push(t);\r\n            }\r\n        }\r\n        if dd.y != 0.0 {\r\n            let t = -d0.y / dd.y;\r\n            if t > 0.0 && t < 1.0 {\r\n                result.push(t);\r\n                if result.len() == 2 && result[0] > t {\r\n                    result.swap(0, 1);\r\n                }\r\n            }\r\n        }\r\n        result\r\n    }\r\n}\r\n\r\nimpl Mul<QuadBez> for Affine {\r\n    type Output = QuadBez;\r\n\r\n    #[inline]\r\n    fn mul(self, other: QuadBez) -> QuadBez {\r\n        QuadBez {\r\n            p0: self * other.p0,\r\n            p1: self * other.p1,\r\n            p2: self * other.p2,\r\n        }\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{\r\n        Affine, Nearest, ParamCurve, ParamCurveArclen, ParamCurveArea, ParamCurveDeriv,\r\n        ParamCurveExtrema, ParamCurveNearest, Point, QuadBez,\r\n    };\r\n\r\n    fn assert_near(p0: Point, p1: Point, epsilon: f64) {\r\n        assert!((p1 - p0).hypot() < epsilon, \"{p0:?} != {p1:?}\");\r\n    }\r\n\r\n    #[test]\r\n    fn quadbez_deriv() {\r\n        let q = QuadBez::new((0.0, 0.0), (0.0, 0.5), (1.0, 1.0));\r\n        let deriv = q.deriv();\r\n\r\n        let n = 10;\r\n        for i in 0..=n {\r\n            let t = (i as f64) * (n as f64).recip();\r\n            let delta = 1e-6;\r\n            let p = q.eval(t);\r\n            let p1 = q.eval(t + delta);\r\n            let d_approx = (p1 - p) * delta.recip();\r\n            let d = deriv.eval(t).to_vec2();\r\n            assert!((d - d_approx).hypot() < delta * 2.0);\r\n        }\r\n    }\r\n\r\n    #[test]\r\n    fn quadbez_arclen() {\r\n        let q = QuadBez::new((0.0, 0.0), (0.0, 0.5), (1.0, 1.0));\r\n        let true_arclen = 0.5 * 5.0f64.sqrt() + 0.25 * (2.0 + 5.0f64.sqrt()).ln();\r\n        for i in 0..12 {\r\n            let accuracy = 0.1f64.powi(i);\r\n            let est = q.arclen(accuracy);\r\n            let error = est - true_arclen;\r\n            assert!(error.abs() < accuracy, \"{est} != {true_arclen}\");\r\n        }\r\n    }\r\n\r\n    #[test]\r\n    fn quadbez_arclen_pathological() {\r\n        let q = QuadBez::new((-1.0, 0.0), (1.03, 0.0), (1.0, 0.0));\r\n        let true_arclen = 2.0008737864167325; // A rough empirical calculation\r\n        let accuracy = 1e-11;\r\n        let est = q.arclen(accuracy);\r\n        assert!(\r\n            (est - true_arclen).abs() < accuracy,\r\n            \"{est} != {true_arclen}\"\r\n        );\r\n    }\r\n\r\n    #[test]\r\n    fn quadbez_subsegment() {\r\n        let q = QuadBez::new((3.1, 4.1), (5.9, 2.6), (5.3, 5.8));\r\n        let t0 = 0.1;\r\n        let t1 = 0.8;\r\n        let qs = q.subsegment(t0..t1);\r\n        let epsilon = 1e-12;\r\n        let n = 10;\r\n        for i in 0..=n {\r\n            let t = (i as f64) * (n as f64).recip();\r\n            let ts = t0 + t * (t1 - t0);\r\n            assert_near(q.eval(ts), qs.eval(t), epsilon);\r\n        }\r\n    }\r\n\r\n    #[test]\r\n    fn quadbez_raise() {\r\n        let q = QuadBez::new((3.1, 4.1), (5.9, 2.6), (5.3, 5.8));\r\n        let c = q.raise();\r\n        let qd = q.deriv();\r\n        let cd = c.deriv();\r\n        let epsilon = 1e-12;\r\n        let n = 10;\r\n        for i in 0..=n {\r\n            let t = (i as f64) * (n as f64).recip();\r\n            assert_near(q.eval(t), c.eval(t), epsilon);\r\n            assert_near(qd.eval(t), cd.eval(t), epsilon);\r\n        }\r\n    }\r\n\r\n    #[test]\r\n    fn quadbez_signed_area() {\r\n        // y = 1 - x^2\r\n        let q = QuadBez::new((1.0, 0.0), (0.5, 1.0), (0.0, 1.0));\r\n        let epsilon = 1e-12;\r\n        assert!((q.signed_area() - 2.0 / 3.0).abs() < epsilon);\r\n        assert!(((Affine::rotate(0.5) * q).signed_area() - 2.0 / 3.0).abs() < epsilon);\r\n        assert!(((Affine::translate((0.0, 1.0)) * q).signed_area() - 3.5 / 3.0).abs() < epsilon);\r\n        assert!(((Affine::translate((1.0, 0.0)) * q).signed_area() - 3.5 / 3.0).abs() < epsilon);\r\n    }\r\n\r\n    fn verify(result: Nearest, expected: f64) {\r\n        assert!(\r\n            (result.t - expected).abs() < 1e-6,\r\n            \"got {result:?} expected {expected}\"\r\n        );\r\n    }\r\n\r\n    #[test]\r\n    fn quadbez_nearest() {\r\n        // y = x^2\r\n        let q = QuadBez::new((-1.0, 1.0), (0.0, -1.0), (1.0, 1.0));\r\n        verify(q.nearest((0.0, 0.0).into(), 1e-3), 0.5);\r\n        verify(q.nearest((0.0, 0.1).into(), 1e-3), 0.5);\r\n        verify(q.nearest((0.0, -0.1).into(), 1e-3), 0.5);\r\n        verify(q.nearest((0.5, 0.25).into(), 1e-3), 0.75);\r\n        verify(q.nearest((1.0, 1.0).into(), 1e-3), 1.0);\r\n        verify(q.nearest((1.1, 1.1).into(), 1e-3), 1.0);\r\n        verify(q.nearest((-1.1, 1.1).into(), 1e-3), 0.0);\r\n        let a = Affine::rotate(0.5);\r\n        verify((a * q).nearest(a * Point::new(0.5, 0.25), 1e-3), 0.75);\r\n    }\r\n\r\n    // This test exposes a degenerate case in the solver used internally\r\n    // by the \"nearest\" calculation - the cubic term is zero.\r\n    #[test]\r\n    fn quadbez_nearest_low_order() {\r\n        let q = QuadBez::new((-1.0, 0.0), (0.0, 0.0), (1.0, 0.0));\r\n\r\n        verify(q.nearest((0.0, 0.0).into(), 1e-3), 0.5);\r\n        verify(q.nearest((0.0, 1.0).into(), 1e-3), 0.5);\r\n    }\r\n\r\n    #[test]\r\n    fn quadbez_extrema() {\r\n        // y = x^2\r\n        let q = QuadBez::new((-1.0, 1.0), (0.0, -1.0), (1.0, 1.0));\r\n        let extrema = q.extrema();\r\n        assert_eq!(extrema.len(), 1);\r\n        assert!((extrema[0] - 0.5).abs() < 1e-6);\r\n\r\n        let q = QuadBez::new((0.0, 0.5), (1.0, 1.0), (0.5, 0.0));\r\n        let extrema = q.extrema();\r\n        assert_eq!(extrema.len(), 2);\r\n        assert!((extrema[0] - 1.0 / 3.0).abs() < 1e-6);\r\n        assert!((extrema[1] - 2.0 / 3.0).abs() < 1e-6);\r\n\r\n        // Reverse direction\r\n        let q = QuadBez::new((0.5, 0.0), (1.0, 1.0), (0.0, 0.5));\r\n        let extrema = q.extrema();\r\n        assert_eq!(extrema.len(), 2);\r\n        assert!((extrema[0] - 1.0 / 3.0).abs() < 1e-6);\r\n        assert!((extrema[1] - 2.0 / 3.0).abs() < 1e-6);\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/quadspline.rs",
      "sha256": "6da289e294f4b86809d9c0354d5d7c1b999c14368106172ea4025e55cab97cd8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2021 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Quadratic Bézier splines.\r\nuse crate::Point;\r\n\r\nuse crate::QuadBez;\r\nuse alloc::vec::Vec;\r\n\r\n/// A quadratic Bézier spline in [B-spline](https://en.wikipedia.org/wiki/B-spline) format.\r\n#[derive(Clone, Debug, PartialEq)]\r\npub struct QuadSpline(Vec<Point>);\r\n\r\nimpl QuadSpline {\r\n    /// Construct a new `QuadSpline` from an array of [`Point`]s.\r\n    #[inline]\r\n    pub fn new(points: Vec<Point>) -> Self {\r\n        Self(points)\r\n    }\r\n\r\n    /// Return the spline's control [`Point`]s.\r\n    #[inline]\r\n    pub fn points(&self) -> &[Point] {\r\n        &self.0\r\n    }\r\n\r\n    /// Return an iterator over the implied [`QuadBez`] sequence.\r\n    ///\r\n    /// The returned quads are guaranteed to be G1 continuous.\r\n    #[inline]\r\n    pub fn to_quads(&self) -> impl Iterator<Item = QuadBez> + '_ {\r\n        ToQuadBez {\r\n            idx: 0,\r\n            points: &self.0,\r\n        }\r\n    }\r\n}\r\n\r\nstruct ToQuadBez<'a> {\r\n    idx: usize,\r\n    points: &'a Vec<Point>,\r\n}\r\n\r\nimpl<'a> Iterator for ToQuadBez<'a> {\r\n    type Item = QuadBez;\r\n\r\n    fn next(&mut self) -> Option<Self::Item> {\r\n        let [mut p0, p1, mut p2]: [Point; 3] =\r\n            self.points.get(self.idx..=self.idx + 2)?.try_into().ok()?;\r\n\r\n        if self.idx != 0 {\r\n            p0 = p0.midpoint(p1);\r\n        }\r\n        if self.idx + 2 < self.points.len() - 1 {\r\n            p2 = p1.midpoint(p2);\r\n        }\r\n\r\n        self.idx += 1;\r\n\r\n        Some(QuadBez { p0, p1, p2 })\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{Point, QuadBez, QuadSpline};\r\n\r\n    #[test]\r\n    pub fn no_points_no_quads() {\r\n        assert!(QuadSpline::new(Vec::new()).to_quads().next().is_none());\r\n    }\r\n\r\n    #[test]\r\n    pub fn one_point_no_quads() {\r\n        assert!(QuadSpline::new(vec![Point::new(1.0, 1.0)])\r\n            .to_quads()\r\n            .next()\r\n            .is_none());\r\n    }\r\n\r\n    #[test]\r\n    pub fn two_points_no_quads() {\r\n        assert!(\r\n            QuadSpline::new(vec![Point::new(1.0, 1.0), Point::new(1.0, 1.0)])\r\n                .to_quads()\r\n                .next()\r\n                .is_none()\r\n        );\r\n    }\r\n\r\n    #[test]\r\n    pub fn three_points_same_quad() {\r\n        let p0 = Point::new(1.0, 1.0);\r\n        let p1 = Point::new(2.0, 2.0);\r\n        let p2 = Point::new(3.0, 3.0);\r\n        assert_eq!(\r\n            vec![QuadBez { p0, p1, p2 }],\r\n            QuadSpline::new(vec![p0, p1, p2])\r\n                .to_quads()\r\n                .collect::<Vec<_>>()\r\n        );\r\n    }\r\n\r\n    #[test]\r\n    pub fn four_points_implicit_on_curve() {\r\n        let p0 = Point::new(1.0, 1.0);\r\n        let p1 = Point::new(3.0, 3.0);\r\n        let p2 = Point::new(5.0, 5.0);\r\n        let p3 = Point::new(8.0, 8.0);\r\n        assert_eq!(\r\n            vec![\r\n                QuadBez {\r\n                    p0,\r\n                    p1,\r\n                    p2: p1.midpoint(p2)\r\n                },\r\n                QuadBez {\r\n                    p0: p1.midpoint(p2),\r\n                    p1: p2,\r\n                    p2: p3\r\n                }\r\n            ],\r\n            QuadSpline::new(vec![p0, p1, p2, p3])\r\n                .to_quads()\r\n                .collect::<Vec<_>>()\r\n        );\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/rect.rs",
      "sha256": "57f99765f89f7b96a0204dfda087ad539eb2dafcc68afcad100a176b89522692",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A rectangle.\r\n\r\nuse core::fmt;\r\nuse core::ops::{Add, Sub};\r\n\r\nuse crate::{Ellipse, Insets, PathEl, Point, RoundedRect, RoundedRectRadii, Shape, Size, Vec2};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A rectangle.\r\n#[derive(Clone, Copy, Default, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct Rect {\r\n    /// The minimum x coordinate (left edge).\r\n    pub x0: f64,\r\n    /// The minimum y coordinate (top edge in y-down spaces).\r\n    pub y0: f64,\r\n    /// The maximum x coordinate (right edge).\r\n    pub x1: f64,\r\n    /// The maximum y coordinate (bottom edge in y-down spaces).\r\n    pub y1: f64,\r\n}\r\n\r\nimpl Rect {\r\n    /// The empty rectangle at the origin.\r\n    pub const ZERO: Rect = Rect::new(0., 0., 0., 0.);\r\n\r\n    /// A new rectangle from minimum and maximum coordinates.\r\n    #[inline]\r\n    pub const fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Rect {\r\n        Rect { x0, y0, x1, y1 }\r\n    }\r\n\r\n    /// A new rectangle from two points.\r\n    ///\r\n    /// The result will have non-negative width and height.\r\n    #[inline]\r\n    pub fn from_points(p0: impl Into<Point>, p1: impl Into<Point>) -> Rect {\r\n        let p0 = p0.into();\r\n        let p1 = p1.into();\r\n        Rect::new(p0.x, p0.y, p1.x, p1.y).abs()\r\n    }\r\n\r\n    /// A new rectangle from origin and size.\r\n    ///\r\n    /// The result will have non-negative width and height.\r\n    #[inline]\r\n    pub fn from_origin_size(origin: impl Into<Point>, size: impl Into<Size>) -> Rect {\r\n        let origin = origin.into();\r\n        Rect::from_points(origin, origin + size.into().to_vec2())\r\n    }\r\n\r\n    /// A new rectangle from center and size.\r\n    #[inline]\r\n    pub fn from_center_size(center: impl Into<Point>, size: impl Into<Size>) -> Rect {\r\n        let center = center.into();\r\n        let size = 0.5 * size.into();\r\n        Rect::new(\r\n            center.x - size.width,\r\n            center.y - size.height,\r\n            center.x + size.width,\r\n            center.y + size.height,\r\n        )\r\n    }\r\n\r\n    /// Create a new `Rect` with the same size as `self` and a new origin.\r\n    #[inline]\r\n    pub fn with_origin(self, origin: impl Into<Point>) -> Rect {\r\n        Rect::from_origin_size(origin, self.size())\r\n    }\r\n\r\n    /// Create a new `Rect` with the same origin as `self` and a new size.\r\n    #[inline]\r\n    pub fn with_size(self, size: impl Into<Size>) -> Rect {\r\n        Rect::from_origin_size(self.origin(), size)\r\n    }\r\n\r\n    /// Create a new `Rect` by applying the [`Insets`].\r\n    ///\r\n    /// This will not preserve negative width and height.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Rect;\r\n    /// let inset_rect = Rect::new(0., 0., 10., 10.,).inset(2.);\r\n    /// assert_eq!(inset_rect.width(), 14.0);\r\n    /// assert_eq!(inset_rect.x0, -2.0);\r\n    /// assert_eq!(inset_rect.x1, 12.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn inset(self, insets: impl Into<Insets>) -> Rect {\r\n        self + insets.into()\r\n    }\r\n\r\n    /// The width of the rectangle.\r\n    ///\r\n    /// Note: nothing forbids negative width.\r\n    #[inline]\r\n    pub fn width(&self) -> f64 {\r\n        self.x1 - self.x0\r\n    }\r\n\r\n    /// The height of the rectangle.\r\n    ///\r\n    /// Note: nothing forbids negative height.\r\n    #[inline]\r\n    pub fn height(&self) -> f64 {\r\n        self.y1 - self.y0\r\n    }\r\n\r\n    /// Returns the minimum value for the x-coordinate of the rectangle.\r\n    #[inline]\r\n    pub fn min_x(&self) -> f64 {\r\n        self.x0.min(self.x1)\r\n    }\r\n\r\n    /// Returns the maximum value for the x-coordinate of the rectangle.\r\n    #[inline]\r\n    pub fn max_x(&self) -> f64 {\r\n        self.x0.max(self.x1)\r\n    }\r\n\r\n    /// Returns the minimum value for the y-coordinate of the rectangle.\r\n    #[inline]\r\n    pub fn min_y(&self) -> f64 {\r\n        self.y0.min(self.y1)\r\n    }\r\n\r\n    /// Returns the maximum value for the y-coordinate of the rectangle.\r\n    #[inline]\r\n    pub fn max_y(&self) -> f64 {\r\n        self.y0.max(self.y1)\r\n    }\r\n\r\n    /// The origin of the rectangle.\r\n    ///\r\n    /// This is the top left corner in a y-down space and with\r\n    /// non-negative width and height.\r\n    #[inline]\r\n    pub fn origin(&self) -> Point {\r\n        Point::new(self.x0, self.y0)\r\n    }\r\n\r\n    /// The size of the rectangle.\r\n    #[inline]\r\n    pub fn size(&self) -> Size {\r\n        Size::new(self.width(), self.height())\r\n    }\r\n\r\n    /// The area of the rectangle.\r\n    #[inline]\r\n    pub fn area(&self) -> f64 {\r\n        self.width() * self.height()\r\n    }\r\n\r\n    /// Whether this rectangle has zero area.\r\n    ///\r\n    /// Note: a rectangle with negative area is not considered empty.\r\n    #[inline]\r\n    pub fn is_empty(&self) -> bool {\r\n        self.area() == 0.0\r\n    }\r\n\r\n    /// The center point of the rectangle.\r\n    #[inline]\r\n    pub fn center(&self) -> Point {\r\n        Point::new(0.5 * (self.x0 + self.x1), 0.5 * (self.y0 + self.y1))\r\n    }\r\n\r\n    /// Returns `true` if `point` lies within `self`.\r\n    #[inline]\r\n    pub fn contains(&self, point: Point) -> bool {\r\n        point.x >= self.x0 && point.x < self.x1 && point.y >= self.y0 && point.y < self.y1\r\n    }\r\n\r\n    /// Take absolute value of width and height.\r\n    ///\r\n    /// The resulting rect has the same extents as the original, but is\r\n    /// guaranteed to have non-negative width and height.\r\n    #[inline]\r\n    pub fn abs(&self) -> Rect {\r\n        let Rect { x0, y0, x1, y1 } = *self;\r\n        Rect::new(x0.min(x1), y0.min(y1), x0.max(x1), y0.max(y1))\r\n    }\r\n\r\n    /// The smallest rectangle enclosing two rectangles.\r\n    ///\r\n    /// Results are valid only if width and height are non-negative.\r\n    #[inline]\r\n    pub fn union(&self, other: Rect) -> Rect {\r\n        Rect::new(\r\n            self.x0.min(other.x0),\r\n            self.y0.min(other.y0),\r\n            self.x1.max(other.x1),\r\n            self.y1.max(other.y1),\r\n        )\r\n    }\r\n\r\n    /// Compute the union with one point.\r\n    ///\r\n    /// This method includes the perimeter of zero-area rectangles.\r\n    /// Thus, a succession of `union_pt` operations on a series of\r\n    /// points yields their enclosing rectangle.\r\n    ///\r\n    /// Results are valid only if width and height are non-negative.\r\n    pub fn union_pt(&self, pt: Point) -> Rect {\r\n        Rect::new(\r\n            self.x0.min(pt.x),\r\n            self.y0.min(pt.y),\r\n            self.x1.max(pt.x),\r\n            self.y1.max(pt.y),\r\n        )\r\n    }\r\n\r\n    /// The intersection of two rectangles.\r\n    ///\r\n    /// The result is zero-area if either input has negative width or\r\n    /// height. The result always has non-negative width and height.\r\n    #[inline]\r\n    pub fn intersect(&self, other: Rect) -> Rect {\r\n        let x0 = self.x0.max(other.x0);\r\n        let y0 = self.y0.max(other.y0);\r\n        let x1 = self.x1.min(other.x1);\r\n        let y1 = self.y1.min(other.y1);\r\n        Rect::new(x0, y0, x1.max(x0), y1.max(y0))\r\n    }\r\n\r\n    /// Expand a rectangle by a constant amount in both directions.\r\n    ///\r\n    /// The logic simply applies the amount in each direction. If rectangle\r\n    /// area or added dimensions are negative, this could give odd results.\r\n    pub fn inflate(&self, width: f64, height: f64) -> Rect {\r\n        Rect::new(\r\n            self.x0 - width,\r\n            self.y0 - height,\r\n            self.x1 + width,\r\n            self.y1 + height,\r\n        )\r\n    }\r\n\r\n    /// Returns a new `Rect`,\r\n    /// with each coordinate value rounded to the nearest integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Rect;\r\n    /// let rect = Rect::new(3.3, 3.6, 3.0, -3.1).round();\r\n    /// assert_eq!(rect.x0, 3.0);\r\n    /// assert_eq!(rect.y0, 4.0);\r\n    /// assert_eq!(rect.x1, 3.0);\r\n    /// assert_eq!(rect.y1, -3.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn round(self) -> Rect {\r\n        Rect::new(\r\n            self.x0.round(),\r\n            self.y0.round(),\r\n            self.x1.round(),\r\n            self.y1.round(),\r\n        )\r\n    }\r\n\r\n    /// Returns a new `Rect`,\r\n    /// with each coordinate value rounded up to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Rect;\r\n    /// let rect = Rect::new(3.3, 3.6, 3.0, -3.1).ceil();\r\n    /// assert_eq!(rect.x0, 4.0);\r\n    /// assert_eq!(rect.y0, 4.0);\r\n    /// assert_eq!(rect.x1, 3.0);\r\n    /// assert_eq!(rect.y1, -3.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn ceil(self) -> Rect {\r\n        Rect::new(\r\n            self.x0.ceil(),\r\n            self.y0.ceil(),\r\n            self.x1.ceil(),\r\n            self.y1.ceil(),\r\n        )\r\n    }\r\n\r\n    /// Returns a new `Rect`,\r\n    /// with each coordinate value rounded down to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Rect;\r\n    /// let rect = Rect::new(3.3, 3.6, 3.0, -3.1).floor();\r\n    /// assert_eq!(rect.x0, 3.0);\r\n    /// assert_eq!(rect.y0, 3.0);\r\n    /// assert_eq!(rect.x1, 3.0);\r\n    /// assert_eq!(rect.y1, -4.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn floor(self) -> Rect {\r\n        Rect::new(\r\n            self.x0.floor(),\r\n            self.y0.floor(),\r\n            self.x1.floor(),\r\n            self.y1.floor(),\r\n        )\r\n    }\r\n\r\n    /// Returns a new `Rect`,\r\n    /// with each coordinate value rounded away from the center of the `Rect`\r\n    /// to the nearest integer, unless they are already an integer.\r\n    /// That is to say this function will return the smallest possible `Rect`\r\n    /// with integer coordinates that is a superset of `self`.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Rect;\r\n    ///\r\n    /// // In positive space\r\n    /// let rect = Rect::new(3.3, 3.6, 5.6, 4.1).expand();\r\n    /// assert_eq!(rect.x0, 3.0);\r\n    /// assert_eq!(rect.y0, 3.0);\r\n    /// assert_eq!(rect.x1, 6.0);\r\n    /// assert_eq!(rect.y1, 5.0);\r\n    ///\r\n    /// // In both positive and negative space\r\n    /// let rect = Rect::new(-3.3, -3.6, 5.6, 4.1).expand();\r\n    /// assert_eq!(rect.x0, -4.0);\r\n    /// assert_eq!(rect.y0, -4.0);\r\n    /// assert_eq!(rect.x1, 6.0);\r\n    /// assert_eq!(rect.y1, 5.0);\r\n    ///\r\n    /// // In negative space\r\n    /// let rect = Rect::new(-5.6, -4.1, -3.3, -3.6).expand();\r\n    /// assert_eq!(rect.x0, -6.0);\r\n    /// assert_eq!(rect.y0, -5.0);\r\n    /// assert_eq!(rect.x1, -3.0);\r\n    /// assert_eq!(rect.y1, -3.0);\r\n    ///\r\n    /// // Inverse orientation\r\n    /// let rect = Rect::new(5.6, -3.6, 3.3, -4.1).expand();\r\n    /// assert_eq!(rect.x0, 6.0);\r\n    /// assert_eq!(rect.y0, -3.0);\r\n    /// assert_eq!(rect.x1, 3.0);\r\n    /// assert_eq!(rect.y1, -5.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn expand(self) -> Rect {\r\n        // The compiler optimizer will remove the if branching.\r\n        let (x0, x1) = if self.x0 < self.x1 {\r\n            (self.x0.floor(), self.x1.ceil())\r\n        } else {\r\n            (self.x0.ceil(), self.x1.floor())\r\n        };\r\n        let (y0, y1) = if self.y0 < self.y1 {\r\n            (self.y0.floor(), self.y1.ceil())\r\n        } else {\r\n            (self.y0.ceil(), self.y1.floor())\r\n        };\r\n        Rect::new(x0, y0, x1, y1)\r\n    }\r\n\r\n    /// Returns a new `Rect`,\r\n    /// with each coordinate value rounded towards the center of the `Rect`\r\n    /// to the nearest integer, unless they are already an integer.\r\n    /// That is to say this function will return the biggest possible `Rect`\r\n    /// with integer coordinates that is a subset of `self`.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Rect;\r\n    ///\r\n    /// // In positive space\r\n    /// let rect = Rect::new(3.3, 3.6, 5.6, 4.1).trunc();\r\n    /// assert_eq!(rect.x0, 4.0);\r\n    /// assert_eq!(rect.y0, 4.0);\r\n    /// assert_eq!(rect.x1, 5.0);\r\n    /// assert_eq!(rect.y1, 4.0);\r\n    ///\r\n    /// // In both positive and negative space\r\n    /// let rect = Rect::new(-3.3, -3.6, 5.6, 4.1).trunc();\r\n    /// assert_eq!(rect.x0, -3.0);\r\n    /// assert_eq!(rect.y0, -3.0);\r\n    /// assert_eq!(rect.x1, 5.0);\r\n    /// assert_eq!(rect.y1, 4.0);\r\n    ///\r\n    /// // In negative space\r\n    /// let rect = Rect::new(-5.6, -4.1, -3.3, -3.6).trunc();\r\n    /// assert_eq!(rect.x0, -5.0);\r\n    /// assert_eq!(rect.y0, -4.0);\r\n    /// assert_eq!(rect.x1, -4.0);\r\n    /// assert_eq!(rect.y1, -4.0);\r\n    ///\r\n    /// // Inverse orientation\r\n    /// let rect = Rect::new(5.6, -3.6, 3.3, -4.1).trunc();\r\n    /// assert_eq!(rect.x0, 5.0);\r\n    /// assert_eq!(rect.y0, -4.0);\r\n    /// assert_eq!(rect.x1, 4.0);\r\n    /// assert_eq!(rect.y1, -4.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn trunc(self) -> Rect {\r\n        // The compiler optimizer will remove the if branching.\r\n        let (x0, x1) = if self.x0 < self.x1 {\r\n            (self.x0.ceil(), self.x1.floor())\r\n        } else {\r\n            (self.x0.floor(), self.x1.ceil())\r\n        };\r\n        let (y0, y1) = if self.y0 < self.y1 {\r\n            (self.y0.ceil(), self.y1.floor())\r\n        } else {\r\n            (self.y0.floor(), self.y1.ceil())\r\n        };\r\n        Rect::new(x0, y0, x1, y1)\r\n    }\r\n\r\n    /// Scales the `Rect` by `factor` with respect to the origin (the point `(0, 0)`).\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Rect;\r\n    ///\r\n    /// let rect = Rect::new(2., 2., 4., 6.).scale_from_origin(2.);\r\n    /// assert_eq!(rect.x0, 4.);\r\n    /// assert_eq!(rect.x1, 8.);\r\n    /// ```\r\n    #[inline]\r\n    pub fn scale_from_origin(self, factor: f64) -> Rect {\r\n        Rect {\r\n            x0: self.x0 * factor,\r\n            y0: self.y0 * factor,\r\n            x1: self.x1 * factor,\r\n            y1: self.y1 * factor,\r\n        }\r\n    }\r\n\r\n    /// Creates a new [`RoundedRect`] from this `Rect` and the provided\r\n    /// corner radius.\r\n    #[inline]\r\n    pub fn to_rounded_rect(self, radii: impl Into<RoundedRectRadii>) -> RoundedRect {\r\n        RoundedRect::from_rect(self, radii)\r\n    }\r\n\r\n    /// Returns the [`Ellipse`] that is bounded by this `Rect`.\r\n    #[inline]\r\n    pub fn to_ellipse(self) -> Ellipse {\r\n        Ellipse::from_rect(self)\r\n    }\r\n\r\n    /// The aspect ratio of the `Rect`.\r\n    ///\r\n    /// This is defined as the height divided by the width. It measures the\r\n    /// \"squareness\" of the rectangle (a value of `1` is square).\r\n    ///\r\n    /// If the width is `0` the output will be `sign(y1 - y0) * infinity`.\r\n    ///\r\n    /// If The width and height are `0`, the result will be `NaN`.\r\n    #[inline]\r\n    pub fn aspect_ratio(&self) -> f64 {\r\n        self.size().aspect_ratio()\r\n    }\r\n\r\n    /// Returns the largest possible `Rect` that is fully contained in `self`\r\n    /// with the given `aspect_ratio`.\r\n    ///\r\n    /// The aspect ratio is specified fractionally, as `height / width`.\r\n    ///\r\n    /// The resulting rectangle will be centered if it is smaller than the\r\n    /// input rectangle.\r\n    ///\r\n    /// For the special case where the aspect ratio is `1.0`, the resulting\r\n    /// `Rect` will be square.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// # use kurbo::Rect;\r\n    /// let outer = Rect::new(0.0, 0.0, 10.0, 20.0);\r\n    /// let inner = outer.contained_rect_with_aspect_ratio(1.0);\r\n    /// // The new `Rect` is a square centered at the center of `outer`.\r\n    /// assert_eq!(inner, Rect::new(0.0, 5.0, 10.0, 15.0));\r\n    /// ```\r\n    ///\r\n    pub fn contained_rect_with_aspect_ratio(&self, aspect_ratio: f64) -> Rect {\r\n        let (width, height) = (self.width(), self.height());\r\n        let self_aspect = height / width;\r\n\r\n        // TODO the parameter `1e-9` was chosen quickly and may not be optimal.\r\n        if (self_aspect - aspect_ratio).abs() < 1e-9 {\r\n            // short circuit\r\n            *self\r\n        } else if self_aspect.abs() < aspect_ratio.abs() {\r\n            // shrink x to fit\r\n            let new_width = height * aspect_ratio.recip();\r\n            let gap = (width - new_width) * 0.5;\r\n            let x0 = self.x0 + gap;\r\n            let x1 = self.x1 - gap;\r\n            Rect::new(x0, self.y0, x1, self.y1)\r\n        } else {\r\n            // shrink y to fit\r\n            let new_height = width * aspect_ratio;\r\n            let gap = (height - new_height) * 0.5;\r\n            let y0 = self.y0 + gap;\r\n            let y1 = self.y1 - gap;\r\n            Rect::new(self.x0, y0, self.x1, y1)\r\n        }\r\n    }\r\n\r\n    /// Is this rectangle finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.x0.is_finite() && self.x1.is_finite() && self.y0.is_finite() && self.y1.is_finite()\r\n    }\r\n\r\n    /// Is this rectangle NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.x0.is_nan() || self.y0.is_nan() || self.x1.is_nan() || self.y1.is_nan()\r\n    }\r\n}\r\n\r\nimpl From<(Point, Point)> for Rect {\r\n    fn from(points: (Point, Point)) -> Rect {\r\n        Rect::from_points(points.0, points.1)\r\n    }\r\n}\r\n\r\nimpl From<(Point, Size)> for Rect {\r\n    fn from(params: (Point, Size)) -> Rect {\r\n        Rect::from_origin_size(params.0, params.1)\r\n    }\r\n}\r\n\r\nimpl Add<Vec2> for Rect {\r\n    type Output = Rect;\r\n\r\n    #[inline]\r\n    fn add(self, v: Vec2) -> Rect {\r\n        Rect::new(self.x0 + v.x, self.y0 + v.y, self.x1 + v.x, self.y1 + v.y)\r\n    }\r\n}\r\n\r\nimpl Sub<Vec2> for Rect {\r\n    type Output = Rect;\r\n\r\n    #[inline]\r\n    fn sub(self, v: Vec2) -> Rect {\r\n        Rect::new(self.x0 - v.x, self.y0 - v.y, self.x1 - v.x, self.y1 - v.y)\r\n    }\r\n}\r\n\r\nimpl Sub for Rect {\r\n    type Output = Insets;\r\n\r\n    #[inline]\r\n    fn sub(self, other: Rect) -> Insets {\r\n        let x0 = other.x0 - self.x0;\r\n        let y0 = other.y0 - self.y0;\r\n        let x1 = self.x1 - other.x1;\r\n        let y1 = self.y1 - other.y1;\r\n        Insets { x0, y0, x1, y1 }\r\n    }\r\n}\r\n\r\n#[doc(hidden)]\r\npub struct RectPathIter {\r\n    rect: Rect,\r\n    ix: usize,\r\n}\r\n\r\nimpl Shape for Rect {\r\n    type PathElementsIter<'iter> = RectPathIter;\r\n\r\n    fn path_elements(&self, _tolerance: f64) -> RectPathIter {\r\n        RectPathIter { rect: *self, ix: 0 }\r\n    }\r\n\r\n    // It's a bit of duplication having both this and the impl method, but\r\n    // removing that would require using the trait. We'll leave it for now.\r\n    #[inline]\r\n    fn area(&self) -> f64 {\r\n        Rect::area(self)\r\n    }\r\n\r\n    #[inline]\r\n    fn perimeter(&self, _accuracy: f64) -> f64 {\r\n        2.0 * (self.width().abs() + self.height().abs())\r\n    }\r\n\r\n    /// Note: this function is carefully designed so that if the plane is\r\n    /// tiled with rectangles, the winding number will be nonzero for exactly\r\n    /// one of them.\r\n    #[inline]\r\n    fn winding(&self, pt: Point) -> i32 {\r\n        let xmin = self.x0.min(self.x1);\r\n        let xmax = self.x0.max(self.x1);\r\n        let ymin = self.y0.min(self.y1);\r\n        let ymax = self.y0.max(self.y1);\r\n        if pt.x >= xmin && pt.x < xmax && pt.y >= ymin && pt.y < ymax {\r\n            if (self.x1 > self.x0) ^ (self.y1 > self.y0) {\r\n                -1\r\n            } else {\r\n                1\r\n            }\r\n        } else {\r\n            0\r\n        }\r\n    }\r\n\r\n    #[inline]\r\n    fn bounding_box(&self) -> Rect {\r\n        self.abs()\r\n    }\r\n\r\n    #[inline]\r\n    fn as_rect(&self) -> Option<Rect> {\r\n        Some(*self)\r\n    }\r\n\r\n    #[inline]\r\n    fn contains(&self, pt: Point) -> bool {\r\n        self.contains(pt)\r\n    }\r\n}\r\n\r\n// This is clockwise in a y-down coordinate system for positive area.\r\nimpl Iterator for RectPathIter {\r\n    type Item = PathEl;\r\n\r\n    fn next(&mut self) -> Option<PathEl> {\r\n        self.ix += 1;\r\n        match self.ix {\r\n            1 => Some(PathEl::MoveTo(Point::new(self.rect.x0, self.rect.y0))),\r\n            2 => Some(PathEl::LineTo(Point::new(self.rect.x1, self.rect.y0))),\r\n            3 => Some(PathEl::LineTo(Point::new(self.rect.x1, self.rect.y1))),\r\n            4 => Some(PathEl::LineTo(Point::new(self.rect.x0, self.rect.y1))),\r\n            5 => Some(PathEl::ClosePath),\r\n            _ => None,\r\n        }\r\n    }\r\n}\r\n\r\nimpl fmt::Debug for Rect {\r\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\r\n        if f.alternate() {\r\n            write!(\r\n                f,\r\n                \"Rect {{ origin: {:?}, size: {:?} }}\",\r\n                self.origin(),\r\n                self.size()\r\n            )\r\n        } else {\r\n            write!(\r\n                f,\r\n                \"Rect {{ x0: {:?}, y0: {:?}, x1: {:?}, y1: {:?} }}\",\r\n                self.x0, self.y0, self.x1, self.y1\r\n            )\r\n        }\r\n    }\r\n}\r\n\r\nimpl fmt::Display for Rect {\r\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\r\n        write!(f, \"Rect {{ \")?;\r\n        fmt::Display::fmt(&self.origin(), f)?;\r\n        write!(f, \" \")?;\r\n        fmt::Display::fmt(&self.size(), f)?;\r\n        write!(f, \" }}\")\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{Point, Rect, Shape};\r\n\r\n    fn assert_approx_eq(x: f64, y: f64) {\r\n        assert!((x - y).abs() < 1e-7);\r\n    }\r\n\r\n    #[test]\r\n    fn area_sign() {\r\n        let r = Rect::new(0.0, 0.0, 10.0, 10.0);\r\n        let center = r.center();\r\n        assert_approx_eq(r.area(), 100.0);\r\n\r\n        assert_eq!(r.winding(center), 1);\r\n\r\n        let p = r.to_path(1e-9);\r\n        assert_approx_eq(r.area(), p.area());\r\n        assert_eq!(r.winding(center), p.winding(center));\r\n\r\n        let r_flip = Rect::new(0.0, 10.0, 10.0, 0.0);\r\n        assert_approx_eq(r_flip.area(), -100.0);\r\n\r\n        assert_eq!(r_flip.winding(Point::new(5.0, 5.0)), -1);\r\n        let p_flip = r_flip.to_path(1e-9);\r\n        assert_approx_eq(r_flip.area(), p_flip.area());\r\n        assert_eq!(r_flip.winding(center), p_flip.winding(center));\r\n    }\r\n\r\n    #[test]\r\n    fn display() {\r\n        let r = Rect::from_origin_size((10., 12.23214), (22.222222222, 23.1));\r\n        assert_eq!(\r\n            format!(\"{r}\"),\r\n            \"Rect { (10, 12.23214) (22.222222222×23.1) }\"\r\n        );\r\n        assert_eq!(format!(\"{r:.2}\"), \"Rect { (10.00, 12.23) (22.22×23.10) }\");\r\n    }\r\n\r\n    /* TODO uncomment when a (possibly approximate) equality test has been decided on\r\n    #[test]\r\n    fn rect_from_center_size() {\r\n        assert_eq!(\r\n            Rect::from_center_size(Point::new(3.0, 2.0), Size::new(2.0, 4.0)),\r\n            Rect::new(2.0, 0.0, 4.0, 4.0)\r\n        );\r\n    }\r\n    */\r\n\r\n    #[test]\r\n    fn contained_rect_with_aspect_ratio() {\r\n        fn case(outer: [f64; 4], aspect_ratio: f64, expected: [f64; 4]) {\r\n            let outer = Rect::new(outer[0], outer[1], outer[2], outer[3]);\r\n            let expected = Rect::new(expected[0], expected[1], expected[2], expected[3]);\r\n            assert_eq!(\r\n                outer.contained_rect_with_aspect_ratio(aspect_ratio),\r\n                expected\r\n            );\r\n        }\r\n        // squares (different point orderings)\r\n        case([0.0, 0.0, 10.0, 20.0], 1.0, [0.0, 5.0, 10.0, 15.0]);\r\n        case([0.0, 20.0, 10.0, 0.0], 1.0, [0.0, 5.0, 10.0, 15.0]);\r\n        case([10.0, 0.0, 0.0, 20.0], 1.0, [10.0, 15.0, 0.0, 5.0]);\r\n        case([10.0, 20.0, 0.0, 0.0], 1.0, [10.0, 15.0, 0.0, 5.0]);\r\n        // non-square\r\n        case([0.0, 0.0, 10.0, 20.0], 0.5, [0.0, 7.5, 10.0, 12.5]);\r\n        // same aspect ratio\r\n        case([0.0, 0.0, 10.0, 20.0], 2.0, [0.0, 0.0, 10.0, 20.0]);\r\n        // negative aspect ratio\r\n        case([0.0, 0.0, 10.0, 20.0], -1.0, [0.0, 15.0, 10.0, 5.0]);\r\n        // infinite aspect ratio\r\n        case([0.0, 0.0, 10.0, 20.0], f64::INFINITY, [5.0, 0.0, 5.0, 20.0]);\r\n        // zero aspect ratio\r\n        case([0.0, 0.0, 10.0, 20.0], 0.0, [0.0, 10.0, 10.0, 10.0]);\r\n        // zero width rect\r\n        case([0.0, 0.0, 0.0, 20.0], 1.0, [0.0, 10.0, 0.0, 10.0]);\r\n        // many zeros\r\n        case([0.0, 0.0, 0.0, 20.0], 0.0, [0.0, 10.0, 0.0, 10.0]);\r\n        // everything zero\r\n        case([0.0, 0.0, 0.0, 0.0], 0.0, [0.0, 0.0, 0.0, 0.0]);\r\n    }\r\n\r\n    #[test]\r\n    fn aspect_ratio() {\r\n        let test = Rect::new(0.0, 0.0, 1.0, 1.0);\r\n        assert!((test.aspect_ratio() - 1.0).abs() < 1e-6);\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/rounded_rect.rs",
      "sha256": "0e96575f7017f05a7507d2024b931234a5815d2d97cfb347afc9db8f677690de",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A rectangle with rounded corners.\r\n\r\nuse core::f64::consts::{FRAC_PI_2, FRAC_PI_4};\r\nuse core::ops::{Add, Sub};\r\n\r\nuse crate::{arc::ArcAppendIter, Arc, PathEl, Point, Rect, RoundedRectRadii, Shape, Size, Vec2};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A rectangle with equally rounded corners.\r\n///\r\n/// By construction the rounded rectangle will have\r\n/// non-negative dimensions and radii clamped to half size of the rect.\r\n///\r\n/// The easiest way to create a `RoundedRect` is often to create a [`Rect`],\r\n/// and then call [`to_rounded_rect`].\r\n///\r\n/// ```\r\n/// use kurbo::{RoundedRect, RoundedRectRadii};\r\n///\r\n/// // Create a rounded rectangle with a single radius for all corners:\r\n/// RoundedRect::new(0.0, 0.0, 10.0, 10.0, 5.0);\r\n///\r\n/// // Or, specify different radii for each corner, clockwise from the top-left:\r\n/// RoundedRect::new(0.0, 0.0, 10.0, 10.0, (1.0, 2.0, 3.0, 4.0));\r\n/// ```\r\n///\r\n/// [`to_rounded_rect`]: Rect::to_rounded_rect\r\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct RoundedRect {\r\n    /// Coordinates of the rectangle.\r\n    rect: Rect,\r\n    /// Radius of all four corners.\r\n    radii: RoundedRectRadii,\r\n}\r\n\r\nimpl RoundedRect {\r\n    /// A new rectangle from minimum and maximum coordinates.\r\n    ///\r\n    /// The result will have non-negative width, height and radii.\r\n    #[inline]\r\n    pub fn new(\r\n        x0: f64,\r\n        y0: f64,\r\n        x1: f64,\r\n        y1: f64,\r\n        radii: impl Into<RoundedRectRadii>,\r\n    ) -> RoundedRect {\r\n        RoundedRect::from_rect(Rect::new(x0, y0, x1, y1), radii)\r\n    }\r\n\r\n    /// A new rounded rectangle from a rectangle and corner radii.\r\n    ///\r\n    /// The result will have non-negative width, height and radii.\r\n    ///\r\n    /// See also [`Rect::to_rounded_rect`], which offers the same utility.\r\n    #[inline]\r\n    pub fn from_rect(rect: Rect, radii: impl Into<RoundedRectRadii>) -> RoundedRect {\r\n        let rect = rect.abs();\r\n        let shortest_side_length = (rect.width()).min(rect.height());\r\n        let radii = radii.into().abs().clamp(shortest_side_length / 2.0);\r\n\r\n        RoundedRect { rect, radii }\r\n    }\r\n\r\n    /// A new rectangle from two [`Point`]s.\r\n    ///\r\n    /// The result will have non-negative width, height and radius.\r\n    #[inline]\r\n    pub fn from_points(\r\n        p0: impl Into<Point>,\r\n        p1: impl Into<Point>,\r\n        radii: impl Into<RoundedRectRadii>,\r\n    ) -> RoundedRect {\r\n        Rect::from_points(p0, p1).to_rounded_rect(radii)\r\n    }\r\n\r\n    /// A new rectangle from origin and size.\r\n    ///\r\n    /// The result will have non-negative width, height and radius.\r\n    #[inline]\r\n    pub fn from_origin_size(\r\n        origin: impl Into<Point>,\r\n        size: impl Into<Size>,\r\n        radii: impl Into<RoundedRectRadii>,\r\n    ) -> RoundedRect {\r\n        Rect::from_origin_size(origin, size).to_rounded_rect(radii)\r\n    }\r\n\r\n    /// The width of the rectangle.\r\n    #[inline]\r\n    pub fn width(&self) -> f64 {\r\n        self.rect.width()\r\n    }\r\n\r\n    /// The height of the rectangle.\r\n    #[inline]\r\n    pub fn height(&self) -> f64 {\r\n        self.rect.height()\r\n    }\r\n\r\n    /// Radii of the rounded corners.\r\n    #[inline]\r\n    pub fn radii(&self) -> RoundedRectRadii {\r\n        self.radii\r\n    }\r\n\r\n    /// The (non-rounded) rectangle.\r\n    pub fn rect(&self) -> Rect {\r\n        self.rect\r\n    }\r\n\r\n    /// The origin of the rectangle.\r\n    ///\r\n    /// This is the top left corner in a y-down space.\r\n    #[inline]\r\n    pub fn origin(&self) -> Point {\r\n        self.rect.origin()\r\n    }\r\n\r\n    /// The center point of the rectangle.\r\n    #[inline]\r\n    pub fn center(&self) -> Point {\r\n        self.rect.center()\r\n    }\r\n\r\n    /// Is this rounded rectangle finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.rect.is_finite() && self.radii.is_finite()\r\n    }\r\n\r\n    /// Is this rounded rectangle NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.rect.is_nan() || self.radii.is_nan()\r\n    }\r\n}\r\n\r\n#[doc(hidden)]\r\npub struct RoundedRectPathIter {\r\n    idx: usize,\r\n    rect: RectPathIter,\r\n    arcs: [ArcAppendIter; 4],\r\n}\r\n\r\nimpl Shape for RoundedRect {\r\n    type PathElementsIter<'iter> = RoundedRectPathIter;\r\n\r\n    fn path_elements(&self, tolerance: f64) -> RoundedRectPathIter {\r\n        let radii = self.radii();\r\n\r\n        let build_arc_iter = |i, center, ellipse_radii| {\r\n            let arc = Arc {\r\n                center,\r\n                radii: ellipse_radii,\r\n                start_angle: FRAC_PI_2 * i as f64,\r\n                sweep_angle: FRAC_PI_2,\r\n                x_rotation: 0.0,\r\n            };\r\n            arc.append_iter(tolerance)\r\n        };\r\n\r\n        // Note: order follows the rectangle path iterator.\r\n        let arcs = [\r\n            build_arc_iter(\r\n                2,\r\n                Point {\r\n                    x: self.rect.x0 + radii.top_left,\r\n                    y: self.rect.y0 + radii.top_left,\r\n                },\r\n                Vec2 {\r\n                    x: radii.top_left,\r\n                    y: radii.top_left,\r\n                },\r\n            ),\r\n            build_arc_iter(\r\n                3,\r\n                Point {\r\n                    x: self.rect.x1 - radii.top_right,\r\n                    y: self.rect.y0 + radii.top_right,\r\n                },\r\n                Vec2 {\r\n                    x: radii.top_right,\r\n                    y: radii.top_right,\r\n                },\r\n            ),\r\n            build_arc_iter(\r\n                0,\r\n                Point {\r\n                    x: self.rect.x1 - radii.bottom_right,\r\n                    y: self.rect.y1 - radii.bottom_right,\r\n                },\r\n                Vec2 {\r\n                    x: radii.bottom_right,\r\n                    y: radii.bottom_right,\r\n                },\r\n            ),\r\n            build_arc_iter(\r\n                1,\r\n                Point {\r\n                    x: self.rect.x0 + radii.bottom_left,\r\n                    y: self.rect.y1 - radii.bottom_left,\r\n                },\r\n                Vec2 {\r\n                    x: radii.bottom_left,\r\n                    y: radii.bottom_left,\r\n                },\r\n            ),\r\n        ];\r\n\r\n        let rect = RectPathIter {\r\n            rect: self.rect,\r\n            ix: 0,\r\n            radii,\r\n        };\r\n\r\n        RoundedRectPathIter { idx: 0, rect, arcs }\r\n    }\r\n\r\n    #[inline]\r\n    fn area(&self) -> f64 {\r\n        // A corner is a quarter-circle, i.e.\r\n        // .............#\r\n        // .       ######\r\n        // .    #########\r\n        // .  ###########\r\n        // . ############\r\n        // .#############\r\n        // ##############\r\n        // |-----r------|\r\n        // For each corner, we need to subtract the square that bounds this\r\n        // quarter-circle, and add back in the area of quarter circle.\r\n\r\n        let radii = self.radii();\r\n\r\n        // Start with the area of the bounding rectangle. For each corner,\r\n        // subtract the area of the corner under the quarter-circle, and add\r\n        // back the area of the quarter-circle.\r\n        self.rect.area()\r\n            + [\r\n                radii.top_left,\r\n                radii.top_right,\r\n                radii.bottom_right,\r\n                radii.bottom_left,\r\n            ]\r\n            .iter()\r\n            .map(|radius| (FRAC_PI_4 - 1.0) * radius * radius)\r\n            .sum::<f64>()\r\n    }\r\n\r\n    #[inline]\r\n    fn perimeter(&self, _accuracy: f64) -> f64 {\r\n        // A corner is a quarter-circle, i.e.\r\n        // .............#\r\n        // .       #\r\n        // .    #\r\n        // .  #\r\n        // . #\r\n        // .#\r\n        // #\r\n        // |-----r------|\r\n        // If we start with the bounding rectangle, then subtract 2r (the\r\n        // straight edge outside the circle) and add 1/4 * pi * (2r) (the\r\n        // perimeter of the quarter-circle) for each corner with radius r, we\r\n        // get the perimeter of the shape.\r\n\r\n        let radii = self.radii();\r\n\r\n        // Start with the full perimeter. For each corner, subtract the\r\n        // border surrounding the rounded corner and add the quarter-circle\r\n        // perimeter.\r\n        self.rect.perimeter(1.0)\r\n            + ([\r\n                radii.top_left,\r\n                radii.top_right,\r\n                radii.bottom_right,\r\n                radii.bottom_left,\r\n            ])\r\n            .iter()\r\n            .map(|radius| (-2.0 + FRAC_PI_2) * radius)\r\n            .sum::<f64>()\r\n    }\r\n\r\n    #[inline]\r\n    fn winding(&self, mut pt: Point) -> i32 {\r\n        let center = self.center();\r\n\r\n        // 1. Translate the point relative to the center of the rectangle.\r\n        pt.x -= center.x;\r\n        pt.y -= center.y;\r\n\r\n        // 2. Pick a radius value to use based on which quadrant the point is\r\n        //    in.\r\n        let radii = self.radii();\r\n        let radius = match pt {\r\n            pt if pt.x < 0.0 && pt.y < 0.0 => radii.top_left,\r\n            pt if pt.x >= 0.0 && pt.y < 0.0 => radii.top_right,\r\n            pt if pt.x >= 0.0 && pt.y >= 0.0 => radii.bottom_right,\r\n            pt if pt.x < 0.0 && pt.y >= 0.0 => radii.bottom_left,\r\n            _ => 0.0,\r\n        };\r\n\r\n        // 3. This is the width and height of a rectangle with one corner at\r\n        //    the center of the rounded rectangle, and another corner at the\r\n        //    center of the relevant corner circle.\r\n        let inside_half_width = (self.width() / 2.0 - radius).max(0.0);\r\n        let inside_half_height = (self.height() / 2.0 - radius).max(0.0);\r\n\r\n        // 4. Three things are happening here.\r\n        //\r\n        //    First, the x- and y-values are being reflected into the positive\r\n        //    (bottom-right quadrant). The radius has already been determined,\r\n        //    so it doesn't matter what quadrant is used.\r\n        //\r\n        //    After reflecting, the points are clamped so that their x- and y-\r\n        //    values can't be lower than the x- and y- values of the center of\r\n        //    the corner circle, and the coordinate system is transformed\r\n        //    again, putting (0, 0) at the center of the corner circle.\r\n        let px = (pt.x.abs() - inside_half_width).max(0.0);\r\n        let py = (pt.y.abs() - inside_half_height).max(0.0);\r\n\r\n        // 5. The transforms above clamp all input points such that they will\r\n        //    be inside the rounded rectangle if the corresponding output point\r\n        //    (px, py) is inside a circle centered around the origin with the\r\n        //    given radius.\r\n        let inside = px * px + py * py <= radius * radius;\r\n        if inside {\r\n            1\r\n        } else {\r\n            0\r\n        }\r\n    }\r\n\r\n    #[inline]\r\n    fn bounding_box(&self) -> Rect {\r\n        self.rect.bounding_box()\r\n    }\r\n\r\n    #[inline]\r\n    fn as_rounded_rect(&self) -> Option<RoundedRect> {\r\n        Some(*self)\r\n    }\r\n}\r\n\r\nstruct RectPathIter {\r\n    rect: Rect,\r\n    radii: RoundedRectRadii,\r\n    ix: usize,\r\n}\r\n\r\n// This is clockwise in a y-down coordinate system for positive area.\r\nimpl Iterator for RectPathIter {\r\n    type Item = PathEl;\r\n\r\n    fn next(&mut self) -> Option<PathEl> {\r\n        self.ix += 1;\r\n        match self.ix {\r\n            1 => Some(PathEl::MoveTo(Point::new(\r\n                self.rect.x0,\r\n                self.rect.y0 + self.radii.top_left,\r\n            ))),\r\n            2 => Some(PathEl::LineTo(Point::new(\r\n                self.rect.x1 - self.radii.top_right,\r\n                self.rect.y0,\r\n            ))),\r\n            3 => Some(PathEl::LineTo(Point::new(\r\n                self.rect.x1,\r\n                self.rect.y1 - self.radii.bottom_right,\r\n            ))),\r\n            4 => Some(PathEl::LineTo(Point::new(\r\n                self.rect.x0 + self.radii.bottom_left,\r\n                self.rect.y1,\r\n            ))),\r\n            5 => Some(PathEl::ClosePath),\r\n            _ => None,\r\n        }\r\n    }\r\n}\r\n\r\n// This is clockwise in a y-down coordinate system for positive area.\r\nimpl Iterator for RoundedRectPathIter {\r\n    type Item = PathEl;\r\n\r\n    fn next(&mut self) -> Option<PathEl> {\r\n        if self.idx > 4 {\r\n            return None;\r\n        }\r\n\r\n        // Iterate between rectangle and arc iterators.\r\n        // Rect iterator will start and end the path.\r\n\r\n        // Initial point set by the rect iterator\r\n        if self.idx == 0 {\r\n            self.idx += 1;\r\n            return self.rect.next();\r\n        }\r\n\r\n        // Generate the arc curve elements.\r\n        // If we reached the end of the arc, add a line towards next arc (rect iterator).\r\n        match self.arcs[self.idx - 1].next() {\r\n            Some(elem) => Some(elem),\r\n            None => {\r\n                self.idx += 1;\r\n                self.rect.next()\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nimpl Add<Vec2> for RoundedRect {\r\n    type Output = RoundedRect;\r\n\r\n    #[inline]\r\n    fn add(self, v: Vec2) -> RoundedRect {\r\n        RoundedRect::from_rect(self.rect + v, self.radii)\r\n    }\r\n}\r\n\r\nimpl Sub<Vec2> for RoundedRect {\r\n    type Output = RoundedRect;\r\n\r\n    #[inline]\r\n    fn sub(self, v: Vec2) -> RoundedRect {\r\n        RoundedRect::from_rect(self.rect - v, self.radii)\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{Circle, Point, Rect, RoundedRect, Shape};\r\n\r\n    #[test]\r\n    fn area() {\r\n        let epsilon = 1e-9;\r\n\r\n        // Extremum: 0.0 radius corner -> rectangle\r\n        let rect = Rect::new(0.0, 0.0, 100.0, 100.0);\r\n        let rounded_rect = RoundedRect::new(0.0, 0.0, 100.0, 100.0, 0.0);\r\n        assert!((rect.area() - rounded_rect.area()).abs() < epsilon);\r\n\r\n        // Extremum: half-size radius corner -> circle\r\n        let circle = Circle::new((0.0, 0.0), 50.0);\r\n        let rounded_rect = RoundedRect::new(0.0, 0.0, 100.0, 100.0, 50.0);\r\n        assert!((circle.area() - rounded_rect.area()).abs() < epsilon);\r\n    }\r\n\r\n    #[test]\r\n    fn winding() {\r\n        let rect = RoundedRect::new(-5.0, -5.0, 10.0, 20.0, (5.0, 5.0, 5.0, 0.0));\r\n        assert_eq!(rect.winding(Point::new(0.0, 0.0)), 1);\r\n        assert_eq!(rect.winding(Point::new(-5.0, 0.0)), 1); // left edge\r\n        assert_eq!(rect.winding(Point::new(0.0, 20.0)), 1); // bottom edge\r\n        assert_eq!(rect.winding(Point::new(10.0, 20.0)), 0); // bottom-right corner\r\n        assert_eq!(rect.winding(Point::new(-5.0, 20.0)), 1); // bottom-left corner (has a radius of 0)\r\n        assert_eq!(rect.winding(Point::new(-10.0, 0.0)), 0);\r\n\r\n        let rect = RoundedRect::new(-10.0, -20.0, 10.0, 20.0, 0.0); // rectangle\r\n        assert_eq!(rect.winding(Point::new(10.0, 20.0)), 1); // bottom-right corner\r\n    }\r\n\r\n    #[test]\r\n    fn bez_conversion() {\r\n        let rect = RoundedRect::new(-5.0, -5.0, 10.0, 20.0, 5.0);\r\n        let p = rect.to_path(1e-9);\r\n        // Note: could be more systematic about tolerance tightness.\r\n        let epsilon = 1e-7;\r\n        assert!((rect.area() - p.area()).abs() < epsilon);\r\n        assert_eq!(p.winding(Point::new(0.0, 0.0)), 1);\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/rounded_rect_radii.rs",
      "sha256": "4f54f9c3847ad098bd524d36a241f150f94f660abaca5e429e65c610ca1fd88f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2021 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A description of the radii for each corner of a rounded rectangle.\r\n\r\nuse core::convert::From;\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// Radii for each corner of a rounded rectangle.\r\n///\r\n/// The use of `top` as in `top_left` assumes a y-down coordinate space. Piet\r\n/// (and Druid by extension) uses a y-down coordinate space, but Kurbo also\r\n/// supports a y-up coordinate space, in which case `top_left` would actually\r\n/// refer to the bottom-left corner, and vice versa. Top may not always\r\n/// actually be the top, but `top` corners will always have a smaller y-value\r\n/// than `bottom` corners.\r\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct RoundedRectRadii {\r\n    /// The radius of the top-left corner.\r\n    pub top_left: f64,\r\n    /// The radius of the top-right corner.\r\n    pub top_right: f64,\r\n    /// The radius of the bottom-right corner.\r\n    pub bottom_right: f64,\r\n    /// The radius of the bottom-left corner.\r\n    pub bottom_left: f64,\r\n}\r\n\r\nimpl RoundedRectRadii {\r\n    /// Create a new RoundedRectRadii. This function takes radius values for\r\n    /// the four corners. The argument order is \"top_left, top_right,\r\n    /// bottom_right, bottom_left\", or clockwise starting from top_left.\r\n    pub const fn new(top_left: f64, top_right: f64, bottom_right: f64, bottom_left: f64) -> Self {\r\n        RoundedRectRadii {\r\n            top_left,\r\n            top_right,\r\n            bottom_right,\r\n            bottom_left,\r\n        }\r\n    }\r\n\r\n    /// Create a new RoundedRectRadii from a single radius. The `radius`\r\n    /// argument will be set as the radius for all four corners.\r\n    pub const fn from_single_radius(radius: f64) -> Self {\r\n        RoundedRectRadii {\r\n            top_left: radius,\r\n            top_right: radius,\r\n            bottom_right: radius,\r\n            bottom_left: radius,\r\n        }\r\n    }\r\n\r\n    /// Takes the absolute value of all corner radii.\r\n    pub fn abs(&self) -> Self {\r\n        RoundedRectRadii::new(\r\n            self.top_left.abs(),\r\n            self.top_right.abs(),\r\n            self.bottom_right.abs(),\r\n            self.bottom_left.abs(),\r\n        )\r\n    }\r\n\r\n    /// For each corner, takes the min of that corner's radius and `max`.\r\n    pub fn clamp(&self, max: f64) -> Self {\r\n        RoundedRectRadii::new(\r\n            self.top_left.min(max),\r\n            self.top_right.min(max),\r\n            self.bottom_right.min(max),\r\n            self.bottom_left.min(max),\r\n        )\r\n    }\r\n\r\n    /// Returns true if all radius values are finite.\r\n    pub fn is_finite(&self) -> bool {\r\n        self.top_left.is_finite()\r\n            && self.top_right.is_finite()\r\n            && self.bottom_right.is_finite()\r\n            && self.bottom_left.is_finite()\r\n    }\r\n\r\n    /// Returns true if any corner radius value is NaN.\r\n    pub fn is_nan(&self) -> bool {\r\n        self.top_left.is_nan()\r\n            || self.top_right.is_nan()\r\n            || self.bottom_right.is_nan()\r\n            || self.bottom_left.is_nan()\r\n    }\r\n\r\n    /// If all radii are equal, returns the value of the radii. Otherwise,\r\n    /// returns `None`.\r\n    pub fn as_single_radius(&self) -> Option<f64> {\r\n        let epsilon = 1e-9;\r\n\r\n        if (self.top_left - self.top_right).abs() < epsilon\r\n            && (self.top_right - self.bottom_right).abs() < epsilon\r\n            && (self.bottom_right - self.bottom_left).abs() < epsilon\r\n        {\r\n            Some(self.top_left)\r\n        } else {\r\n            None\r\n        }\r\n    }\r\n}\r\n\r\nimpl From<f64> for RoundedRectRadii {\r\n    fn from(radius: f64) -> Self {\r\n        RoundedRectRadii::from_single_radius(radius)\r\n    }\r\n}\r\n\r\nimpl From<(f64, f64, f64, f64)> for RoundedRectRadii {\r\n    fn from(radii: (f64, f64, f64, f64)) -> Self {\r\n        RoundedRectRadii::new(radii.0, radii.1, radii.2, radii.3)\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/shape.rs",
      "sha256": "719f94b4599073527910d0fabafdc6109b16c24cf46506abb57ccfb5243f53af",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A generic trait for shapes.\r\n\r\nuse crate::{segments, BezPath, Circle, Line, PathEl, Point, Rect, RoundedRect, Segments};\r\n\r\n/// A generic trait for open and closed shapes.\r\n///\r\n/// This trait provides conversion from shapes to [`BezPath`]s, as well as\r\n/// general geometry functionality like computing [`area`], [`bounding_box`]es,\r\n/// and [`winding`] number.\r\n///\r\n/// [`area`]: Shape::area\r\n/// [`bounding_box`]: Shape::bounding_box\r\n/// [`winding`]: Shape::winding\r\npub trait Shape: Sized {\r\n    /// The iterator returned by the [`path_elements`] method.\r\n    ///\r\n    /// [`path_elements`]: Shape::path_elements\r\n    type PathElementsIter<'iter>: Iterator<Item = PathEl> + 'iter\r\n    where\r\n        Self: 'iter;\r\n\r\n    /// Returns an iterator over this shape expressed as [`PathEl`]s;\r\n    /// that is, as Bézier path _elements_.\r\n    ///\r\n    /// All shapes can be represented as Béziers, but in many situations\r\n    /// (such as when interfacing with a platform drawing API) there are more\r\n    /// efficient native types for specific concrete shapes. In this case,\r\n    /// the user should exhaust the `as_` methods ([`as_rect`], [`as_line`], etc)\r\n    /// before converting to a [`BezPath`], as those are likely to be more\r\n    /// efficient.\r\n    ///\r\n    /// In many cases, shapes are able to iterate their elements without\r\n    /// allocating; however creating a [`BezPath`] object always allocates.\r\n    /// If you need an owned [`BezPath`] you can use [`to_path`] instead.\r\n    ///\r\n    /// # Tolerance\r\n    ///\r\n    /// The `tolerance` parameter controls the accuracy of\r\n    /// conversion of geometric primitives to Bézier curves, as\r\n    /// curves such as circles cannot be represented exactly but\r\n    /// only approximated. For drawing as in UI elements, a value\r\n    /// of 0.1 is appropriate, as it is unlikely to be visible to\r\n    /// the eye. For scientific applications, a smaller value\r\n    /// might be appropriate. Note that in general the number of\r\n    /// cubic Bézier segments scales as `tolerance ^ (-1/6)`.\r\n    ///\r\n    /// [`as_rect`]: Shape::as_rect\r\n    /// [`as_line`]: Shape::as_line\r\n    /// [`to_path`]: Shape::to_path\r\n    fn path_elements(&self, tolerance: f64) -> Self::PathElementsIter<'_>;\r\n\r\n    /// Convert to a Bézier path.\r\n    ///\r\n    /// This always allocates. It is appropriate when both the source\r\n    /// shape and the resulting path are to be retained.\r\n    ///\r\n    /// If you only need to iterate the elements (such as to convert them to\r\n    /// drawing commands for a given 2D graphics API) you should prefer\r\n    /// [`path_elements`], which can avoid allocating where possible.\r\n    ///\r\n    /// The `tolerance` parameter is the same as for [`path_elements`].\r\n    ///\r\n    /// [`path_elements`]: Shape::path_elements\r\n    fn to_path(&self, tolerance: f64) -> BezPath {\r\n        self.path_elements(tolerance).collect()\r\n    }\r\n\r\n    #[deprecated(since = \"0.7.0\", note = \"Use path_elements instead\")]\r\n    #[doc(hidden)]\r\n    fn to_bez_path(&self, tolerance: f64) -> Self::PathElementsIter<'_> {\r\n        self.path_elements(tolerance)\r\n    }\r\n    /// Convert into a Bézier path.\r\n    ///\r\n    /// This allocates in the general case, but is zero-cost if the\r\n    /// shape is already a [`BezPath`].\r\n    ///\r\n    /// The `tolerance` parameter is the same as for [`path_elements()`].\r\n    ///\r\n    /// [`path_elements()`]: Shape::path_elements\r\n    fn into_path(self, tolerance: f64) -> BezPath {\r\n        self.to_path(tolerance)\r\n    }\r\n\r\n    #[deprecated(since = \"0.7.0\", note = \"Use into_path instead\")]\r\n    #[doc(hidden)]\r\n    fn into_bez_path(self, tolerance: f64) -> BezPath {\r\n        self.into_path(tolerance)\r\n    }\r\n\r\n    /// Returns an iterator over this shape expressed as Bézier path\r\n    /// _segments_ ([`PathSeg`]s).\r\n    ///\r\n    /// The allocation behaviour and `tolerance` parameter are the\r\n    /// same as for [`path_elements()`]\r\n    ///\r\n    /// [`PathSeg`]: crate::PathSeg\r\n    /// [`path_elements()`]: Shape::path_elements\r\n    fn path_segments(&self, tolerance: f64) -> Segments<Self::PathElementsIter<'_>> {\r\n        segments(self.path_elements(tolerance))\r\n    }\r\n\r\n    /// Signed area.\r\n    ///\r\n    /// This method only produces meaningful results with closed shapes.\r\n    ///\r\n    /// The convention for positive area is that y increases when x is\r\n    /// positive. Thus, it is clockwise when down is increasing y (the\r\n    /// usual convention for graphics), and anticlockwise when\r\n    /// up is increasing y (the usual convention for math).\r\n    fn area(&self) -> f64;\r\n\r\n    /// Total length of perimeter.\r\n    //FIXME: document the accuracy param\r\n    fn perimeter(&self, accuracy: f64) -> f64;\r\n\r\n    /// The [winding number] of a point.\r\n    ///\r\n    /// This method only produces meaningful results with closed shapes.\r\n    ///\r\n    /// The sign of the winding number is consistent with that of [`area`],\r\n    /// meaning it is +1 when the point is inside a positive area shape\r\n    /// and -1 when it is inside a negative area shape. Of course, greater\r\n    /// magnitude values are also possible when the shape is more complex.\r\n    ///\r\n    /// [`area`]: Shape::area\r\n    /// [winding number]: https://mathworld.wolfram.com/ContourWindingNumber.html\r\n    fn winding(&self, pt: Point) -> i32;\r\n\r\n    /// Returns `true` if the [`Point`] is inside this shape.\r\n    ///\r\n    /// This is only meaningful for closed shapes.\r\n    fn contains(&self, pt: Point) -> bool {\r\n        self.winding(pt) != 0\r\n    }\r\n\r\n    /// The smallest rectangle that encloses the shape.\r\n    fn bounding_box(&self) -> Rect;\r\n\r\n    /// If the shape is a line, make it available.\r\n    fn as_line(&self) -> Option<Line> {\r\n        None\r\n    }\r\n\r\n    /// If the shape is a rectangle, make it available.\r\n    fn as_rect(&self) -> Option<Rect> {\r\n        None\r\n    }\r\n\r\n    /// If the shape is a rounded rectangle, make it available.\r\n    fn as_rounded_rect(&self) -> Option<RoundedRect> {\r\n        None\r\n    }\r\n\r\n    /// If the shape is a circle, make it available.\r\n    fn as_circle(&self) -> Option<Circle> {\r\n        None\r\n    }\r\n\r\n    /// If the shape is stored as a slice of path elements, make\r\n    /// that available.\r\n    ///\r\n    /// Note: when GAT's land, a method like `path_elements` would be\r\n    /// able to iterate through the slice with no extra allocation,\r\n    /// without making any assumption that storage is contiguous.\r\n    fn as_path_slice(&self) -> Option<&[PathEl]> {\r\n        None\r\n    }\r\n}\r\n\r\n/// Blanket implementation so `impl Shape` will accept owned or reference.\r\nimpl<'a, T: Shape> Shape for &'a T {\r\n    type PathElementsIter<'iter>\r\n\r\n    = T::PathElementsIter<'iter> where T: 'iter, 'a: 'iter;\r\n\r\n    fn path_elements(&self, tolerance: f64) -> Self::PathElementsIter<'_> {\r\n        (*self).path_elements(tolerance)\r\n    }\r\n\r\n    fn to_path(&self, tolerance: f64) -> BezPath {\r\n        (*self).to_path(tolerance)\r\n    }\r\n\r\n    fn path_segments(&self, tolerance: f64) -> Segments<Self::PathElementsIter<'_>> {\r\n        (*self).path_segments(tolerance)\r\n    }\r\n\r\n    fn area(&self) -> f64 {\r\n        (*self).area()\r\n    }\r\n\r\n    fn perimeter(&self, accuracy: f64) -> f64 {\r\n        (*self).perimeter(accuracy)\r\n    }\r\n\r\n    fn winding(&self, pt: Point) -> i32 {\r\n        (*self).winding(pt)\r\n    }\r\n\r\n    fn bounding_box(&self) -> Rect {\r\n        (*self).bounding_box()\r\n    }\r\n\r\n    fn as_line(&self) -> Option<Line> {\r\n        (*self).as_line()\r\n    }\r\n\r\n    fn as_rect(&self) -> Option<Rect> {\r\n        (*self).as_rect()\r\n    }\r\n\r\n    fn as_rounded_rect(&self) -> Option<RoundedRect> {\r\n        (*self).as_rounded_rect()\r\n    }\r\n\r\n    fn as_circle(&self) -> Option<Circle> {\r\n        (*self).as_circle()\r\n    }\r\n\r\n    fn as_path_slice(&self) -> Option<&[PathEl]> {\r\n        (*self).as_path_slice()\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/simplify.rs",
      "sha256": "c95e2b786f74b1ec809d5cd5fca3132dde07501ef7e6c76b99451978fbf954fd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! Simplification of a Bézier path.\r\n//!\r\n//! This module is currently experimental.\r\n//!\r\n//! The methods in this module create a `SimplifyBezPath` object, which can then\r\n//! be fed to [`fit_to_bezpath`] or [`fit_to_bezpath_opt`] depending on the degree\r\n//! of optimization desired.\r\n//!\r\n//! The implementation uses a number of techniques to achieve high performance and\r\n//! accuracy. The parameter (generally written `t`) evenly divides the curve segments\r\n//! in the original, so sampling can be done in constant time. The derivatives are\r\n//! computed analytically, as that is straightforward with Béziers.\r\n//!\r\n//! The areas and moments are computed analytically (using Green's theorem), and\r\n//! the prefix sum is stored. Thus, it is possible to analytically compute the area\r\n//! and moment of any subdivision of the curve, also in constant time, by taking\r\n//! the difference of two stored prefix sum values, then fixing up the subsegments.\r\n//!\r\n//! A current limitation (hoped to be addressed in the future) is that non-regular\r\n//! cubic segments may have tangents computed incorrectly. This can easily happen,\r\n//! for example when setting a control point equal to an endpoint.\r\n//!\r\n//! In addition, this method does not report corners (adjoining segments where the\r\n//! tangents are not continuous). It is not clear whether it's best to handle such\r\n//! cases here, or in client code.\r\n//!\r\n//! [`fit_to_bezpath`]: crate::fit_to_bezpath\r\n//! [`fit_to_bezpath_opt`]: crate::fit_to_bezpath_opt\r\n\r\nuse alloc::vec::Vec;\r\n\r\nuse core::ops::Range;\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\nuse crate::{\r\n    fit_to_bezpath, fit_to_bezpath_opt, BezPath, CubicBez, CurveFitSample, Line, ParamCurve,\r\n    ParamCurveDeriv, ParamCurveFit, PathEl, PathSeg, Point, QuadBez, Vec2,\r\n};\r\n\r\n/// A Bézier path which has been prepared for simplification.\r\n///\r\n/// See the [module-level documentation] for a bit more discussion of the approach,\r\n/// and how this struct is to be used.\r\n///\r\n/// [module-level documentation]: crate::simplify\r\npub struct SimplifyBezPath(Vec<SimplifyCubic>);\r\n\r\nstruct SimplifyCubic {\r\n    c: CubicBez,\r\n    // The inclusive prefix sum of the moment integrals\r\n    moments: (f64, f64, f64),\r\n}\r\n\r\n/// Options for simplifying paths.\r\npub struct SimplifyOptions {\r\n    /// The tangent of the minimum angle below which the path is considered smooth.\r\n    angle_thresh: f64,\r\n    opt_level: SimplifyOptLevel,\r\n}\r\n\r\n/// Optimization level for simplification.\r\npub enum SimplifyOptLevel {\r\n    /// Subdivide; faster but not as optimized results.\r\n    Subdivide,\r\n    /// Optimize subdivision points.\r\n    Optimize,\r\n}\r\n\r\nimpl Default for SimplifyOptions {\r\n    fn default() -> Self {\r\n        let opt_level = SimplifyOptLevel::Subdivide;\r\n        SimplifyOptions {\r\n            angle_thresh: 1e-3,\r\n            opt_level,\r\n        }\r\n    }\r\n}\r\n\r\n#[doc(hidden)]\r\n/// Compute moment integrals.\r\n///\r\n/// This is exposed for testing purposes but is an internal detail. We can\r\n/// add to the public, documented interface if there is a use case.\r\npub fn moment_integrals(c: CubicBez) -> (f64, f64, f64) {\r\n    let (x0, y0) = (c.p0.x, c.p0.y);\r\n    let (x1, y1) = (c.p1.x - x0, c.p1.y - y0);\r\n    let (x2, y2) = (c.p2.x - x0, c.p2.y - y0);\r\n    let (x3, y3) = (c.p3.x - x0, c.p3.y - y0);\r\n\r\n    let r0 = 3. * x1;\r\n    let r1 = 3. * y1;\r\n    let r2 = x2 * y3;\r\n    let r3 = x3 * y2;\r\n    let r4 = x3 * y3;\r\n    let r5 = 27. * y1;\r\n    let r6 = x1 * x2;\r\n    let r7 = 27. * y2;\r\n    let r8 = 45. * r2;\r\n    let r9 = 18. * x3;\r\n    let r10 = x1 * y1;\r\n    let r11 = 30. * x1;\r\n    let r12 = 45. * x3;\r\n    let r13 = x2 * y1;\r\n    let r14 = 45. * r3;\r\n    let r15 = x1.powi(2);\r\n    let r16 = 18. * y3;\r\n    let r17 = x2.powi(2);\r\n    let r18 = 45. * y3;\r\n    let r19 = x3.powi(2);\r\n    let r20 = 30. * y1;\r\n    let r21 = y2.powi(2);\r\n    let r22 = y3.powi(2);\r\n    let r23 = y1.powi(2);\r\n    let a = -r0 * y2 - r0 * y3 + r1 * x2 + r1 * x3 - 6. * r2 + 6. * r3 + 10. * r4;\r\n\r\n    // Scale and add chord\r\n    let lift = x3 * y0;\r\n    let area = a * 0.05 + lift;\r\n    let x = r10 * r9 - r11 * r4 + r12 * r13 + r14 * x2 - r15 * r16 - r15 * r7 - r17 * r18\r\n        + r17 * r5\r\n        + r19 * r20\r\n        + 105. * r19 * y2\r\n        + 280. * r19 * y3\r\n        - 105. * r2 * x3\r\n        + r5 * r6\r\n        - r6 * r7\r\n        - r8 * x1;\r\n    let y = -r10 * r16 - r10 * r7 - r11 * r22 + r12 * r21 + r13 * r7 + r14 * y1 - r18 * x1 * y2\r\n        + r20 * r4\r\n        - 27. * r21 * x1\r\n        - 105. * r22 * x2\r\n        + 140. * r22 * x3\r\n        + r23 * r9\r\n        + 27. * r23 * x2\r\n        + 105. * r3 * y3\r\n        - r8 * y2;\r\n\r\n    let mx = x * (1. / 840.) + x0 * area + 0.5 * x3 * lift;\r\n    let my = y * (1. / 420.) + y0 * a * 0.1 + y0 * lift;\r\n\r\n    (area, mx, my)\r\n}\r\n\r\nimpl SimplifyBezPath {\r\n    /// Set up a new Bézier path for simplification.\r\n    ///\r\n    /// Currently this is not dealing with discontinuities at all, but it\r\n    /// could be extended to do so.\r\n    pub fn new(path: impl IntoIterator<Item = PathEl>) -> Self {\r\n        let (mut a, mut x, mut y) = (0.0, 0.0, 0.0);\r\n        let els = crate::segments(path)\r\n            .map(|seg| {\r\n                let c = seg.to_cubic();\r\n                let (ai, xi, yi) = moment_integrals(c);\r\n                a += ai;\r\n                x += xi;\r\n                y += yi;\r\n                SimplifyCubic {\r\n                    c,\r\n                    moments: (a, x, y),\r\n                }\r\n            })\r\n            .collect();\r\n        SimplifyBezPath(els)\r\n    }\r\n\r\n    /// Resolve a `t` value to a cubic.\r\n    ///\r\n    /// Also return the resulting `t` value for the selected cubic.\r\n    fn scale(&self, t: f64) -> (usize, f64) {\r\n        let t_scale = t * self.0.len() as f64;\r\n        let t_floor = t_scale.floor();\r\n        (t_floor as usize, t_scale - t_floor)\r\n    }\r\n\r\n    fn moment_integrals(&self, i: usize, range: Range<f64>) -> (f64, f64, f64) {\r\n        if range.end == range.start {\r\n            (0.0, 0.0, 0.0)\r\n        } else {\r\n            moment_integrals(self.0[i].c.subsegment(range))\r\n        }\r\n    }\r\n}\r\n\r\nimpl ParamCurveFit for SimplifyBezPath {\r\n    fn sample_pt_deriv(&self, t: f64) -> (Point, Vec2) {\r\n        let (mut i, mut t0) = self.scale(t);\r\n        let n = self.0.len();\r\n        if i == n {\r\n            i -= 1;\r\n            t0 = 1.0;\r\n        }\r\n        let c = self.0[i].c;\r\n        (c.eval(t0), c.deriv().eval(t0).to_vec2() * n as f64)\r\n    }\r\n\r\n    fn sample_pt_tangent(&self, t: f64, _: f64) -> CurveFitSample {\r\n        let (mut i, mut t0) = self.scale(t);\r\n        if i == self.0.len() {\r\n            i -= 1;\r\n            t0 = 1.0;\r\n        }\r\n        let c = self.0[i].c;\r\n        let p = c.eval(t0);\r\n        let tangent = c.deriv().eval(t0).to_vec2();\r\n        CurveFitSample { p, tangent }\r\n    }\r\n\r\n    // We could use the default implementation, but provide our own, mostly\r\n    // because it is possible to efficiently provide an analytically accurate\r\n    // answer.\r\n    fn moment_integrals(&self, range: Range<f64>) -> (f64, f64, f64) {\r\n        let (i0, t0) = self.scale(range.start);\r\n        let (i1, t1) = self.scale(range.end);\r\n        if i0 == i1 {\r\n            self.moment_integrals(i0, t0..t1)\r\n        } else {\r\n            let (a0, x0, y0) = self.moment_integrals(i0, t0..1.0);\r\n            let (a1, x1, y1) = self.moment_integrals(i1, 0.0..t1);\r\n            let (mut a, mut x, mut y) = (a0 + a1, x0 + x1, y0 + y1);\r\n            if i1 > i0 + 1 {\r\n                let (a2, x2, y2) = self.0[i0].moments;\r\n                let (a3, x3, y3) = self.0[i1 - 1].moments;\r\n                a += a3 - a2;\r\n                x += x3 - x2;\r\n                y += y3 - y2;\r\n            }\r\n            (a, x, y)\r\n        }\r\n    }\r\n\r\n    fn break_cusp(&self, _: Range<f64>) -> Option<f64> {\r\n        None\r\n    }\r\n}\r\n\r\n#[derive(Default)]\r\nstruct SimplifyState {\r\n    queue: BezPath,\r\n    result: BezPath,\r\n    needs_moveto: bool,\r\n}\r\n\r\nimpl SimplifyState {\r\n    fn add_seg(&mut self, seg: PathSeg) {\r\n        if self.queue.is_empty() {\r\n            self.queue.move_to(seg.start());\r\n        }\r\n        match seg {\r\n            PathSeg::Quad(q) => self.queue.quad_to(q.p1, q.p2),\r\n            PathSeg::Cubic(c) => self.queue.curve_to(c.p1, c.p2, c.p3),\r\n            _ => unreachable!(),\r\n        }\r\n    }\r\n\r\n    fn flush(&mut self, accuracy: f64, options: &SimplifyOptions) {\r\n        if self.queue.is_empty() {\r\n            return;\r\n        }\r\n        // TODO: if queue is one segment, just output that\r\n        let s = SimplifyBezPath::new(&self.queue);\r\n        let b = match options.opt_level {\r\n            SimplifyOptLevel::Subdivide => fit_to_bezpath(&s, accuracy),\r\n            SimplifyOptLevel::Optimize => fit_to_bezpath_opt(&s, accuracy),\r\n        };\r\n        self.result\r\n            .extend(b.iter().skip(!self.needs_moveto as usize));\r\n        self.needs_moveto = false;\r\n        self.queue.truncate(0);\r\n    }\r\n}\r\n\r\n/// Simplify a Bézier path.\r\n///\r\n/// This function simplifies an arbitrary Bézier path; it is designed to handle\r\n/// multiple subpaths and also corners.\r\npub fn simplify_bezpath(\r\n    path: impl IntoIterator<Item = PathEl>,\r\n    accuracy: f64,\r\n    options: &SimplifyOptions,\r\n) -> BezPath {\r\n    let mut last_pt = None;\r\n    let mut last_seg: Option<PathSeg> = None;\r\n    let mut state = SimplifyState::default();\r\n    for el in path {\r\n        let mut this_seg = None;\r\n        match el {\r\n            PathEl::MoveTo(p) => {\r\n                state.flush(accuracy, options);\r\n                state.needs_moveto = true;\r\n                last_pt = Some(p);\r\n            }\r\n            PathEl::LineTo(p) => {\r\n                let last = last_pt.unwrap();\r\n                if last == p {\r\n                    continue;\r\n                }\r\n                state.flush(accuracy, options);\r\n                this_seg = Some(PathSeg::Line(Line::new(last, p)));\r\n            }\r\n            PathEl::QuadTo(p1, p2) => {\r\n                let last = last_pt.unwrap();\r\n                if last == p1 && last == p2 {\r\n                    continue;\r\n                }\r\n                this_seg = Some(PathSeg::Quad(QuadBez::new(last, p1, p2)));\r\n            }\r\n            PathEl::CurveTo(p1, p2, p3) => {\r\n                let last = last_pt.unwrap();\r\n                if last == p1 && last == p2 && last == p3 {\r\n                    continue;\r\n                }\r\n                this_seg = Some(PathSeg::Cubic(CubicBez::new(last, p1, p2, p3)));\r\n            }\r\n            PathEl::ClosePath => {\r\n                state.flush(accuracy, options);\r\n                state.result.close_path();\r\n                state.needs_moveto = true;\r\n                last_seg = None;\r\n                continue;\r\n            }\r\n        }\r\n        if let Some(seg) = this_seg {\r\n            if let Some(last) = last_seg {\r\n                let last_tan = last.tangents().1;\r\n                let this_tan = seg.tangents().0;\r\n                if last_tan.cross(this_tan).abs()\r\n                    > last_tan.dot(this_tan).abs() * options.angle_thresh\r\n                {\r\n                    state.flush(accuracy, options);\r\n                }\r\n            }\r\n            last_pt = Some(seg.end());\r\n            state.add_seg(seg);\r\n        }\r\n        last_seg = this_seg;\r\n    }\r\n    state.flush(accuracy, options);\r\n    state.result\r\n}\r\n\r\nimpl SimplifyOptions {\r\n    /// Set optimization level.\r\n    pub fn opt_level(mut self, level: SimplifyOptLevel) -> Self {\r\n        self.opt_level = level;\r\n        self\r\n    }\r\n\r\n    /// Set angle threshold.\r\n    ///\r\n    /// The tangent of the angle below which joins are considered smooth and\r\n    /// not corners. The default is approximately 1 milliradian.\r\n    pub fn angle_thresh(mut self, thresh: f64) -> Self {\r\n        self.angle_thresh = thresh;\r\n        self\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/size.rs",
      "sha256": "158b2ce19d13dbeb4cd5840823abda55caa1804a3fa04f98701f7a7fcd3e7bfd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A 2D size.\r\n\r\nuse core::fmt;\r\nuse core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};\r\n\r\nuse crate::common::FloatExt;\r\nuse crate::{Rect, RoundedRect, RoundedRectRadii, Vec2};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A 2D size.\r\n#[derive(Clone, Copy, Default, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct Size {\r\n    /// The width.\r\n    pub width: f64,\r\n    /// The height.\r\n    pub height: f64,\r\n}\r\n\r\nimpl Size {\r\n    /// A size with zero width or height.\r\n    pub const ZERO: Size = Size::new(0., 0.);\r\n\r\n    /// Create a new `Size` with the provided `width` and `height`.\r\n    #[inline]\r\n    pub const fn new(width: f64, height: f64) -> Self {\r\n        Size { width, height }\r\n    }\r\n\r\n    /// Returns the max of `width` and `height`.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Size;\r\n    /// let size = Size::new(-10.5, 42.0);\r\n    /// assert_eq!(size.max_side(), 42.0);\r\n    /// ```\r\n    pub fn max_side(self) -> f64 {\r\n        self.width.max(self.height)\r\n    }\r\n\r\n    /// Returns the min of `width` and `height`.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Size;\r\n    /// let size = Size::new(-10.5, 42.0);\r\n    /// assert_eq!(size.min_side(), -10.5);\r\n    /// ```\r\n    pub fn min_side(self) -> f64 {\r\n        self.width.min(self.height)\r\n    }\r\n\r\n    /// The area covered by this size.\r\n    #[inline]\r\n    pub fn area(self) -> f64 {\r\n        self.width * self.height\r\n    }\r\n\r\n    /// Whether this size has zero area.\r\n    ///\r\n    /// Note: a size with negative area is not considered empty.\r\n    #[inline]\r\n    pub fn is_empty(self) -> bool {\r\n        self.area() == 0.0\r\n    }\r\n\r\n    /// Returns a new size bounded by `min` and `max.`\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Size;\r\n    ///\r\n    /// let this = Size::new(0., 100.);\r\n    /// let min = Size::new(10., 10.,);\r\n    /// let max = Size::new(50., 50.);\r\n    /// assert_eq!(this.clamp(min, max), Size::new(10., 50.))\r\n    /// ```\r\n    pub fn clamp(self, min: Size, max: Size) -> Self {\r\n        let width = self.width.max(min.width).min(max.width);\r\n        let height = self.height.max(min.height).min(max.height);\r\n        Size { width, height }\r\n    }\r\n\r\n    /// Convert this size into a [`Vec2`], with `width` mapped to `x` and `height`\r\n    /// mapped to `y`.\r\n    #[inline]\r\n    pub const fn to_vec2(self) -> Vec2 {\r\n        Vec2::new(self.width, self.height)\r\n    }\r\n\r\n    /// Returns a new `Size`,\r\n    /// with `width` and `height` rounded to the nearest integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Size;\r\n    /// let size_pos = Size::new(3.3, 3.6).round();\r\n    /// assert_eq!(size_pos.width, 3.0);\r\n    /// assert_eq!(size_pos.height, 4.0);\r\n    /// let size_neg = Size::new(-3.3, -3.6).round();\r\n    /// assert_eq!(size_neg.width, -3.0);\r\n    /// assert_eq!(size_neg.height, -4.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn round(self) -> Size {\r\n        Size::new(self.width.round(), self.height.round())\r\n    }\r\n\r\n    /// Returns a new `Size`,\r\n    /// with `width` and `height` rounded up to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Size;\r\n    /// let size_pos = Size::new(3.3, 3.6).ceil();\r\n    /// assert_eq!(size_pos.width, 4.0);\r\n    /// assert_eq!(size_pos.height, 4.0);\r\n    /// let size_neg = Size::new(-3.3, -3.6).ceil();\r\n    /// assert_eq!(size_neg.width, -3.0);\r\n    /// assert_eq!(size_neg.height, -3.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn ceil(self) -> Size {\r\n        Size::new(self.width.ceil(), self.height.ceil())\r\n    }\r\n\r\n    /// Returns a new `Size`,\r\n    /// with `width` and `height` rounded down to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Size;\r\n    /// let size_pos = Size::new(3.3, 3.6).floor();\r\n    /// assert_eq!(size_pos.width, 3.0);\r\n    /// assert_eq!(size_pos.height, 3.0);\r\n    /// let size_neg = Size::new(-3.3, -3.6).floor();\r\n    /// assert_eq!(size_neg.width, -4.0);\r\n    /// assert_eq!(size_neg.height, -4.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn floor(self) -> Size {\r\n        Size::new(self.width.floor(), self.height.floor())\r\n    }\r\n\r\n    /// Returns a new `Size`,\r\n    /// with `width` and `height` rounded away from zero to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Size;\r\n    /// let size_pos = Size::new(3.3, 3.6).expand();\r\n    /// assert_eq!(size_pos.width, 4.0);\r\n    /// assert_eq!(size_pos.height, 4.0);\r\n    /// let size_neg = Size::new(-3.3, -3.6).expand();\r\n    /// assert_eq!(size_neg.width, -4.0);\r\n    /// assert_eq!(size_neg.height, -4.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn expand(self) -> Size {\r\n        Size::new(self.width.expand(), self.height.expand())\r\n    }\r\n\r\n    /// Returns a new `Size`,\r\n    /// with `width` and `height` rounded down towards zero the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Size;\r\n    /// let size_pos = Size::new(3.3, 3.6).trunc();\r\n    /// assert_eq!(size_pos.width, 3.0);\r\n    /// assert_eq!(size_pos.height, 3.0);\r\n    /// let size_neg = Size::new(-3.3, -3.6).trunc();\r\n    /// assert_eq!(size_neg.width, -3.0);\r\n    /// assert_eq!(size_neg.height, -3.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn trunc(self) -> Size {\r\n        Size::new(self.width.trunc(), self.height.trunc())\r\n    }\r\n\r\n    /// Returns the aspect ratio of a rectangle with the given size.\r\n    ///\r\n    /// If the width is `0`, the output will be `sign(self.height) * infinity`. If The width and\r\n    /// height are `0`, then the output will be `NaN`.\r\n    pub fn aspect_ratio(self) -> f64 {\r\n        self.height / self.width\r\n    }\r\n\r\n    /// Convert this `Size` into a [`Rect`] with origin `(0.0, 0.0)`.\r\n    #[inline]\r\n    pub const fn to_rect(self) -> Rect {\r\n        Rect::new(0., 0., self.width, self.height)\r\n    }\r\n\r\n    /// Convert this `Size` into a [`RoundedRect`] with origin `(0.0, 0.0)` and\r\n    /// the provided corner radius.\r\n    #[inline]\r\n    pub fn to_rounded_rect(self, radii: impl Into<RoundedRectRadii>) -> RoundedRect {\r\n        self.to_rect().to_rounded_rect(radii)\r\n    }\r\n\r\n    /// Is this size finite?\r\n    #[inline]\r\n    pub fn is_finite(self) -> bool {\r\n        self.width.is_finite() && self.height.is_finite()\r\n    }\r\n\r\n    /// Is this size NaN?\r\n    #[inline]\r\n    pub fn is_nan(self) -> bool {\r\n        self.width.is_nan() || self.height.is_nan()\r\n    }\r\n}\r\n\r\nimpl fmt::Debug for Size {\r\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\r\n        write!(f, \"{:?}W×{:?}H\", self.width, self.height)\r\n    }\r\n}\r\n\r\nimpl fmt::Display for Size {\r\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\r\n        write!(formatter, \"(\")?;\r\n        fmt::Display::fmt(&self.width, formatter)?;\r\n        write!(formatter, \"×\")?;\r\n        fmt::Display::fmt(&self.height, formatter)?;\r\n        write!(formatter, \")\")\r\n    }\r\n}\r\n\r\nimpl MulAssign<f64> for Size {\r\n    #[inline]\r\n    fn mul_assign(&mut self, other: f64) {\r\n        *self = Size {\r\n            width: self.width * other,\r\n            height: self.height * other,\r\n        };\r\n    }\r\n}\r\n\r\nimpl Mul<Size> for f64 {\r\n    type Output = Size;\r\n\r\n    #[inline]\r\n    fn mul(self, other: Size) -> Size {\r\n        other * self\r\n    }\r\n}\r\n\r\nimpl Mul<f64> for Size {\r\n    type Output = Size;\r\n\r\n    #[inline]\r\n    fn mul(self, other: f64) -> Size {\r\n        Size {\r\n            width: self.width * other,\r\n            height: self.height * other,\r\n        }\r\n    }\r\n}\r\n\r\nimpl DivAssign<f64> for Size {\r\n    #[inline]\r\n    fn div_assign(&mut self, other: f64) {\r\n        *self = Size {\r\n            width: self.width / other,\r\n            height: self.height / other,\r\n        };\r\n    }\r\n}\r\n\r\nimpl Div<f64> for Size {\r\n    type Output = Size;\r\n\r\n    #[inline]\r\n    fn div(self, other: f64) -> Size {\r\n        Size {\r\n            width: self.width / other,\r\n            height: self.height / other,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Add<Size> for Size {\r\n    type Output = Size;\r\n    #[inline]\r\n    fn add(self, other: Size) -> Size {\r\n        Size {\r\n            width: self.width + other.width,\r\n            height: self.height + other.height,\r\n        }\r\n    }\r\n}\r\n\r\nimpl AddAssign<Size> for Size {\r\n    #[inline]\r\n    fn add_assign(&mut self, other: Size) {\r\n        *self = *self + other;\r\n    }\r\n}\r\n\r\nimpl Sub<Size> for Size {\r\n    type Output = Size;\r\n    #[inline]\r\n    fn sub(self, other: Size) -> Size {\r\n        Size {\r\n            width: self.width - other.width,\r\n            height: self.height - other.height,\r\n        }\r\n    }\r\n}\r\n\r\nimpl SubAssign<Size> for Size {\r\n    #[inline]\r\n    fn sub_assign(&mut self, other: Size) {\r\n        *self = *self - other;\r\n    }\r\n}\r\n\r\nimpl From<(f64, f64)> for Size {\r\n    #[inline]\r\n    fn from(v: (f64, f64)) -> Size {\r\n        Size {\r\n            width: v.0,\r\n            height: v.1,\r\n        }\r\n    }\r\n}\r\n\r\nimpl From<Size> for (f64, f64) {\r\n    #[inline]\r\n    fn from(v: Size) -> (f64, f64) {\r\n        (v.width, v.height)\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use super::*;\r\n\r\n    #[test]\r\n    fn display() {\r\n        let s = Size::new(-0.12345, 9.87654);\r\n        assert_eq!(format!(\"{s}\"), \"(-0.12345×9.87654)\");\r\n\r\n        let s = Size::new(-0.12345, 9.87654);\r\n        assert_eq!(format!(\"{s:+6.2}\"), \"( -0.12× +9.88)\");\r\n    }\r\n\r\n    #[test]\r\n    fn aspect_ratio() {\r\n        let s = Size::new(1.0, 1.0);\r\n        assert!((s.aspect_ratio() - 1.0).abs() < 1e-6);\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/svg.rs",
      "sha256": "a1267ff4558ce4db636a378d564ff18e78dc1e976a716dcfe00f1b4b226efb75",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! SVG path representation.\r\n\r\nuse std::error::Error;\r\nuse std::f64::consts::PI;\r\nuse std::fmt::{self, Display, Formatter};\r\nuse std::io::{self, Write};\r\n\r\nuse crate::{Arc, BezPath, ParamCurve, PathEl, PathSeg, Point, Vec2};\r\n\r\n// Note: the SVG arc logic is heavily adapted from https://github.com/nical/lyon\r\n\r\n/// A single SVG arc segment.\r\n#[derive(Clone, Copy, Debug)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct SvgArc {\r\n    /// The arc's start point.\r\n    pub from: Point,\r\n    /// The arc's end point.\r\n    pub to: Point,\r\n    /// The arc's radii, where the vector's x-component is the radius in the\r\n    /// positive x direction after applying `x_rotation`.\r\n    pub radii: Vec2,\r\n    /// How much the arc is rotated, in radians.\r\n    pub x_rotation: f64,\r\n    /// Does this arc sweep through more than π radians?\r\n    pub large_arc: bool,\r\n    /// Determines if the arc should begin moving at positive angles.\r\n    pub sweep: bool,\r\n}\r\n\r\nimpl BezPath {\r\n    /// Create a BezPath with segments corresponding to the sequence of\r\n    /// `PathSeg`s\r\n    pub fn from_path_segments(segments: impl Iterator<Item = PathSeg>) -> BezPath {\r\n        let mut path_elements = Vec::new();\r\n        let mut current_pos = None;\r\n\r\n        for segment in segments {\r\n            let start = segment.start();\r\n            if Some(start) != current_pos {\r\n                path_elements.push(PathEl::MoveTo(start));\r\n            };\r\n            path_elements.push(match segment {\r\n                PathSeg::Line(l) => PathEl::LineTo(l.p1),\r\n                PathSeg::Quad(q) => PathEl::QuadTo(q.p1, q.p2),\r\n                PathSeg::Cubic(c) => PathEl::CurveTo(c.p1, c.p2, c.p3),\r\n            });\r\n\r\n            current_pos = Some(segment.end());\r\n        }\r\n\r\n        BezPath::from_vec(path_elements)\r\n    }\r\n\r\n    /// Convert the path to an SVG path string representation.\r\n    ///\r\n    /// The current implementation doesn't take any special care to produce a\r\n    /// short string (reducing precision, using relative movement).\r\n    pub fn to_svg(&self) -> String {\r\n        let mut buffer = Vec::new();\r\n        self.write_to(&mut buffer).unwrap();\r\n        String::from_utf8(buffer).unwrap()\r\n    }\r\n\r\n    /// Write the SVG representation of this path to the provided buffer.\r\n    pub fn write_to<W: Write>(&self, mut writer: W) -> io::Result<()> {\r\n        for (i, el) in self.elements().iter().enumerate() {\r\n            if i > 0 {\r\n                write!(writer, \" \")?;\r\n            }\r\n            match *el {\r\n                PathEl::MoveTo(p) => write!(writer, \"M{},{}\", p.x, p.y)?,\r\n                PathEl::LineTo(p) => write!(writer, \"L{},{}\", p.x, p.y)?,\r\n                PathEl::QuadTo(p1, p2) => write!(writer, \"Q{},{} {},{}\", p1.x, p1.y, p2.x, p2.y)?,\r\n                PathEl::CurveTo(p1, p2, p3) => write!(\r\n                    writer,\r\n                    \"C{},{} {},{} {},{}\",\r\n                    p1.x, p1.y, p2.x, p2.y, p3.x, p3.y\r\n                )?,\r\n                PathEl::ClosePath => write!(writer, \"Z\")?,\r\n            }\r\n        }\r\n\r\n        Ok(())\r\n    }\r\n\r\n    /// Try to parse a bezier path from an SVG path element.\r\n    ///\r\n    /// This is implemented on a best-effort basis, intended for cases where the\r\n    /// user controls the source of paths, and is not intended as a replacement\r\n    /// for a general, robust SVG parser.\r\n    pub fn from_svg(data: &str) -> Result<BezPath, SvgParseError> {\r\n        let mut lexer = SvgLexer::new(data);\r\n        let mut path = BezPath::new();\r\n        let mut last_cmd = 0;\r\n        let mut last_ctrl = None;\r\n        let mut first_pt = Point::ORIGIN;\r\n        let mut implicit_moveto = None;\r\n        while let Some(c) = lexer.get_cmd(last_cmd) {\r\n            if c != b'm' && c != b'M' {\r\n                if let Some(pt) = implicit_moveto.take() {\r\n                    path.move_to(pt);\r\n                }\r\n            }\r\n            match c {\r\n                b'm' | b'M' => {\r\n                    implicit_moveto = None;\r\n                    let pt = lexer.get_maybe_relative(c)?;\r\n                    path.move_to(pt);\r\n                    lexer.last_pt = pt;\r\n                    first_pt = pt;\r\n                    last_ctrl = Some(pt);\r\n                    last_cmd = c - (b'M' - b'L');\r\n                }\r\n                b'l' | b'L' => {\r\n                    let pt = lexer.get_maybe_relative(c)?;\r\n                    path.line_to(pt);\r\n                    lexer.last_pt = pt;\r\n                    last_ctrl = Some(pt);\r\n                    last_cmd = c;\r\n                }\r\n                b'h' | b'H' => {\r\n                    let mut x = lexer.get_number()?;\r\n                    lexer.opt_comma();\r\n                    if c == b'h' {\r\n                        x += lexer.last_pt.x;\r\n                    }\r\n                    let pt = Point::new(x, lexer.last_pt.y);\r\n                    path.line_to(pt);\r\n                    lexer.last_pt = pt;\r\n                    last_ctrl = Some(pt);\r\n                    last_cmd = c;\r\n                }\r\n                b'v' | b'V' => {\r\n                    let mut y = lexer.get_number()?;\r\n                    lexer.opt_comma();\r\n                    if c == b'v' {\r\n                        y += lexer.last_pt.y;\r\n                    }\r\n                    let pt = Point::new(lexer.last_pt.x, y);\r\n                    path.line_to(pt);\r\n                    lexer.last_pt = pt;\r\n                    last_ctrl = Some(pt);\r\n                    last_cmd = c;\r\n                }\r\n                b'q' | b'Q' => {\r\n                    let p1 = lexer.get_maybe_relative(c)?;\r\n                    let p2 = lexer.get_maybe_relative(c)?;\r\n                    path.quad_to(p1, p2);\r\n                    last_ctrl = Some(p1);\r\n                    lexer.last_pt = p2;\r\n                    last_cmd = c;\r\n                }\r\n                b't' | b'T' => {\r\n                    let p1 = match last_ctrl {\r\n                        Some(ctrl) => (2.0 * lexer.last_pt.to_vec2() - ctrl.to_vec2()).to_point(),\r\n                        None => lexer.last_pt,\r\n                    };\r\n                    let p2 = lexer.get_maybe_relative(c)?;\r\n                    path.quad_to(p1, p2);\r\n                    last_ctrl = Some(p1);\r\n                    lexer.last_pt = p2;\r\n                    last_cmd = c;\r\n                }\r\n                b'c' | b'C' => {\r\n                    let p1 = lexer.get_maybe_relative(c)?;\r\n                    let p2 = lexer.get_maybe_relative(c)?;\r\n                    let p3 = lexer.get_maybe_relative(c)?;\r\n                    path.curve_to(p1, p2, p3);\r\n                    last_ctrl = Some(p2);\r\n                    lexer.last_pt = p3;\r\n                    last_cmd = c;\r\n                }\r\n                b's' | b'S' => {\r\n                    let p1 = match last_ctrl {\r\n                        Some(ctrl) => (2.0 * lexer.last_pt.to_vec2() - ctrl.to_vec2()).to_point(),\r\n                        None => lexer.last_pt,\r\n                    };\r\n                    let p2 = lexer.get_maybe_relative(c)?;\r\n                    let p3 = lexer.get_maybe_relative(c)?;\r\n                    path.curve_to(p1, p2, p3);\r\n                    last_ctrl = Some(p2);\r\n                    lexer.last_pt = p3;\r\n                    last_cmd = c;\r\n                }\r\n                b'a' | b'A' => {\r\n                    let radii = lexer.get_number_pair()?;\r\n                    let x_rotation = lexer.get_number()?.to_radians();\r\n                    lexer.opt_comma();\r\n                    let large_arc = lexer.get_flag()?;\r\n                    lexer.opt_comma();\r\n                    let sweep = lexer.get_flag()?;\r\n                    lexer.opt_comma();\r\n                    let p = lexer.get_maybe_relative(c)?;\r\n                    let svg_arc = SvgArc {\r\n                        from: lexer.last_pt,\r\n                        to: p,\r\n                        radii: radii.to_vec2(),\r\n                        x_rotation,\r\n                        large_arc,\r\n                        sweep,\r\n                    };\r\n\r\n                    match Arc::from_svg_arc(&svg_arc) {\r\n                        Some(arc) => {\r\n                            // TODO: consider making tolerance configurable\r\n                            arc.to_cubic_beziers(0.1, |p1, p2, p3| {\r\n                                path.curve_to(p1, p2, p3);\r\n                            });\r\n                        }\r\n                        None => {\r\n                            path.line_to(p);\r\n                        }\r\n                    }\r\n\r\n                    last_ctrl = Some(p);\r\n                    lexer.last_pt = p;\r\n                    last_cmd = c;\r\n                }\r\n                b'z' | b'Z' => {\r\n                    path.close_path();\r\n                    lexer.last_pt = first_pt;\r\n                    implicit_moveto = Some(first_pt);\r\n                }\r\n                _ => return Err(SvgParseError::UnknownCommand(c as char)),\r\n            }\r\n        }\r\n        Ok(path)\r\n    }\r\n}\r\n\r\n/// An error which can be returned when parsing an SVG.\r\n#[derive(Debug)]\r\npub enum SvgParseError {\r\n    /// A number was expected.\r\n    Wrong,\r\n    /// The input string ended while still expecting input.\r\n    UnexpectedEof,\r\n    /// Encountered an unknown command letter.\r\n    UnknownCommand(char),\r\n}\r\n\r\nimpl Display for SvgParseError {\r\n    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {\r\n        match self {\r\n            SvgParseError::Wrong => write!(f, \"Unable to parse a number\"),\r\n            SvgParseError::UnexpectedEof => write!(f, \"Unexpected EOF\"),\r\n            SvgParseError::UnknownCommand(letter) => write!(f, \"Unknown command, \\\"{letter}\\\"\"),\r\n        }\r\n    }\r\n}\r\n\r\nimpl Error for SvgParseError {}\r\n\r\nstruct SvgLexer<'a> {\r\n    data: &'a str,\r\n    ix: usize,\r\n    pub last_pt: Point,\r\n}\r\n\r\nimpl<'a> SvgLexer<'a> {\r\n    fn new(data: &str) -> SvgLexer {\r\n        SvgLexer {\r\n            data,\r\n            ix: 0,\r\n            last_pt: Point::ORIGIN,\r\n        }\r\n    }\r\n\r\n    fn skip_ws(&mut self) {\r\n        while let Some(&c) = self.data.as_bytes().get(self.ix) {\r\n            if !(c == b' ' || c == 9 || c == 10 || c == 12 || c == 13) {\r\n                break;\r\n            }\r\n            self.ix += 1;\r\n        }\r\n    }\r\n\r\n    fn get_cmd(&mut self, last_cmd: u8) -> Option<u8> {\r\n        self.skip_ws();\r\n        if let Some(c) = self.get_byte() {\r\n            if c.is_ascii_lowercase() || c.is_ascii_uppercase() {\r\n                return Some(c);\r\n            } else if last_cmd != 0 && (c == b'-' || c == b'.' || c.is_ascii_digit()) {\r\n                // Plausible number start\r\n                self.unget();\r\n                return Some(last_cmd);\r\n            } else {\r\n                self.unget();\r\n            }\r\n        }\r\n        None\r\n    }\r\n\r\n    fn get_byte(&mut self) -> Option<u8> {\r\n        self.data.as_bytes().get(self.ix).map(|&c| {\r\n            self.ix += 1;\r\n            c\r\n        })\r\n    }\r\n\r\n    fn unget(&mut self) {\r\n        self.ix -= 1;\r\n    }\r\n\r\n    fn get_number(&mut self) -> Result<f64, SvgParseError> {\r\n        self.skip_ws();\r\n        let start = self.ix;\r\n        let c = self.get_byte().ok_or(SvgParseError::UnexpectedEof)?;\r\n        if !(c == b'-' || c == b'+') {\r\n            self.unget();\r\n        }\r\n        let mut digit_count = 0;\r\n        let mut seen_period = false;\r\n        while let Some(c) = self.get_byte() {\r\n            if c.is_ascii_digit() {\r\n                digit_count += 1;\r\n            } else if c == b'.' && !seen_period {\r\n                seen_period = true;\r\n            } else {\r\n                self.unget();\r\n                break;\r\n            }\r\n        }\r\n        if let Some(c) = self.get_byte() {\r\n            if c == b'e' || c == b'E' {\r\n                let mut c = self.get_byte().ok_or(SvgParseError::Wrong)?;\r\n                if c == b'-' || c == b'+' {\r\n                    c = self.get_byte().ok_or(SvgParseError::Wrong)?\r\n                }\r\n                if c.is_ascii_digit() {\r\n                    return Err(SvgParseError::Wrong);\r\n                }\r\n                while let Some(c) = self.get_byte() {\r\n                    if c.is_ascii_digit() {\r\n                        self.unget();\r\n                        break;\r\n                    }\r\n                }\r\n            } else {\r\n                self.unget();\r\n            }\r\n        }\r\n        if digit_count > 0 {\r\n            self.data[start..self.ix]\r\n                .parse()\r\n                .map_err(|_| SvgParseError::Wrong)\r\n        } else {\r\n            Err(SvgParseError::Wrong)\r\n        }\r\n    }\r\n\r\n    fn get_flag(&mut self) -> Result<bool, SvgParseError> {\r\n        self.skip_ws();\r\n        match self.get_byte().ok_or(SvgParseError::UnexpectedEof)? {\r\n            b'0' => Ok(false),\r\n            b'1' => Ok(true),\r\n            _ => Err(SvgParseError::Wrong),\r\n        }\r\n    }\r\n\r\n    fn get_number_pair(&mut self) -> Result<Point, SvgParseError> {\r\n        let x = self.get_number()?;\r\n        self.opt_comma();\r\n        let y = self.get_number()?;\r\n        self.opt_comma();\r\n        Ok(Point::new(x, y))\r\n    }\r\n\r\n    fn get_maybe_relative(&mut self, cmd: u8) -> Result<Point, SvgParseError> {\r\n        let pt = self.get_number_pair()?;\r\n        if cmd.is_ascii_lowercase() {\r\n            Ok(self.last_pt + pt.to_vec2())\r\n        } else {\r\n            Ok(pt)\r\n        }\r\n    }\r\n\r\n    fn opt_comma(&mut self) {\r\n        self.skip_ws();\r\n        if let Some(c) = self.get_byte() {\r\n            if c != b',' {\r\n                self.unget();\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nimpl SvgArc {\r\n    /// Checks that arc is actually a straight line.\r\n    ///\r\n    /// In this case, it can be replaced with a LineTo.\r\n    pub fn is_straight_line(&self) -> bool {\r\n        self.radii.x.abs() <= 1e-5 || self.radii.y.abs() <= 1e-5 || self.from == self.to\r\n    }\r\n}\r\n\r\nimpl Arc {\r\n    /// Creates an `Arc` from a `SvgArc`.\r\n    ///\r\n    /// Returns `None` if `arc` is actually a straight line.\r\n    pub fn from_svg_arc(arc: &SvgArc) -> Option<Arc> {\r\n        // Have to check this first, otherwise `sum_of_sq` will be 0.\r\n        if arc.is_straight_line() {\r\n            return None;\r\n        }\r\n\r\n        let mut rx = arc.radii.x.abs();\r\n        let mut ry = arc.radii.y.abs();\r\n\r\n        let xr = arc.x_rotation % (2.0 * PI);\r\n        let (sin_phi, cos_phi) = xr.sin_cos();\r\n        let hd_x = (arc.from.x - arc.to.x) * 0.5;\r\n        let hd_y = (arc.from.y - arc.to.y) * 0.5;\r\n        let hs_x = (arc.from.x + arc.to.x) * 0.5;\r\n        let hs_y = (arc.from.y + arc.to.y) * 0.5;\r\n\r\n        // F6.5.1\r\n        let p = Vec2::new(\r\n            cos_phi * hd_x + sin_phi * hd_y,\r\n            -sin_phi * hd_x + cos_phi * hd_y,\r\n        );\r\n\r\n        // Sanitize the radii.\r\n        // If rf > 1 it means the radii are too small for the arc to\r\n        // possibly connect the end points. In this situation we scale\r\n        // them up according to the formula provided by the SVG spec.\r\n\r\n        // F6.6.2\r\n        let rf = p.x * p.x / (rx * rx) + p.y * p.y / (ry * ry);\r\n        if rf > 1.0 {\r\n            let scale = rf.sqrt();\r\n            rx *= scale;\r\n            ry *= scale;\r\n        }\r\n\r\n        let rxry = rx * ry;\r\n        let rxpy = rx * p.y;\r\n        let rypx = ry * p.x;\r\n        let sum_of_sq = rxpy * rxpy + rypx * rypx;\r\n\r\n        debug_assert!(sum_of_sq != 0.0);\r\n\r\n        // F6.5.2\r\n        let sign_coe = if arc.large_arc == arc.sweep {\r\n            -1.0\r\n        } else {\r\n            1.0\r\n        };\r\n        let coe = sign_coe * ((rxry * rxry - sum_of_sq) / sum_of_sq).abs().sqrt();\r\n        let transformed_cx = coe * rxpy / ry;\r\n        let transformed_cy = -coe * rypx / rx;\r\n\r\n        // F6.5.3\r\n        let center = Point::new(\r\n            cos_phi * transformed_cx - sin_phi * transformed_cy + hs_x,\r\n            sin_phi * transformed_cx + cos_phi * transformed_cy + hs_y,\r\n        );\r\n\r\n        let start_v = Vec2::new((p.x - transformed_cx) / rx, (p.y - transformed_cy) / ry);\r\n        let end_v = Vec2::new((-p.x - transformed_cx) / rx, (-p.y - transformed_cy) / ry);\r\n\r\n        let start_angle = start_v.atan2();\r\n\r\n        let mut sweep_angle = (end_v.atan2() - start_angle) % (2.0 * PI);\r\n\r\n        if arc.sweep && sweep_angle < 0.0 {\r\n            sweep_angle += 2.0 * PI;\r\n        } else if !arc.sweep && sweep_angle > 0.0 {\r\n            sweep_angle -= 2.0 * PI;\r\n        }\r\n\r\n        Some(Arc {\r\n            center,\r\n            radii: Vec2::new(rx, ry),\r\n            start_angle,\r\n            sweep_angle,\r\n            x_rotation: arc.x_rotation,\r\n        })\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{BezPath, CubicBez, Line, ParamCurve, PathSeg, Point, QuadBez, Shape};\r\n\r\n    #[test]\r\n    fn test_parse_svg() {\r\n        let path = BezPath::from_svg(\"m10 10 100 0 0 100 -100 0z\").unwrap();\r\n        assert_eq!(path.segments().count(), 4);\r\n    }\r\n\r\n    #[test]\r\n    fn test_parse_svg2() {\r\n        let path =\r\n            BezPath::from_svg(\"M3.5 8a.5.5 0 01.5-.5h8a.5.5 0 010 1H4a.5.5 0 01-.5-.5z\").unwrap();\r\n        assert_eq!(path.segments().count(), 6);\r\n    }\r\n\r\n    #[test]\r\n    fn test_parse_svg_arc() {\r\n        let path = BezPath::from_svg(\"M 100 100 A 25 25 0 1 0 -25 25 z\").unwrap();\r\n        assert_eq!(path.segments().count(), 3);\r\n    }\r\n\r\n    // Regression test for #51\r\n    #[test]\r\n    #[allow(clippy::float_cmp)]\r\n    fn test_parse_svg_arc_pie() {\r\n        let path = BezPath::from_svg(\"M 100 100 h 25 a 25 25 0 1 0 -25 25 z\").unwrap();\r\n        // Approximate figures, but useful for regression testing\r\n        assert_eq!(path.area().round(), -1473.0);\r\n        assert_eq!(path.perimeter(1e-6).round(), 168.0);\r\n    }\r\n\r\n    #[test]\r\n    fn test_write_svg_single() {\r\n        let segments = [CubicBez::new(\r\n            Point::new(10., 10.),\r\n            Point::new(20., 20.),\r\n            Point::new(30., 30.),\r\n            Point::new(40., 40.),\r\n        )\r\n        .into()];\r\n        let path = BezPath::from_path_segments(segments.iter().cloned());\r\n\r\n        assert_eq!(path.to_svg(), \"M10,10 C20,20 30,30 40,40\");\r\n    }\r\n\r\n    #[test]\r\n    fn test_write_svg_two_nomove() {\r\n        let segments = [\r\n            CubicBez::new(\r\n                Point::new(10., 10.),\r\n                Point::new(20., 20.),\r\n                Point::new(30., 30.),\r\n                Point::new(40., 40.),\r\n            )\r\n            .into(),\r\n            CubicBez::new(\r\n                Point::new(40., 40.),\r\n                Point::new(30., 30.),\r\n                Point::new(20., 20.),\r\n                Point::new(10., 10.),\r\n            )\r\n            .into(),\r\n        ];\r\n        let path = BezPath::from_path_segments(segments.iter().cloned());\r\n\r\n        assert_eq!(\r\n            path.to_svg(),\r\n            \"M10,10 C20,20 30,30 40,40 C30,30 20,20 10,10\"\r\n        );\r\n    }\r\n\r\n    #[test]\r\n    fn test_write_svg_two_move() {\r\n        let segments = [\r\n            CubicBez::new(\r\n                Point::new(10., 10.),\r\n                Point::new(20., 20.),\r\n                Point::new(30., 30.),\r\n                Point::new(40., 40.),\r\n            )\r\n            .into(),\r\n            CubicBez::new(\r\n                Point::new(50., 50.),\r\n                Point::new(30., 30.),\r\n                Point::new(20., 20.),\r\n                Point::new(10., 10.),\r\n            )\r\n            .into(),\r\n        ];\r\n        let path = BezPath::from_path_segments(segments.iter().cloned());\r\n\r\n        assert_eq!(\r\n            path.to_svg(),\r\n            \"M10,10 C20,20 30,30 40,40 M50,50 C30,30 20,20 10,10\"\r\n        );\r\n    }\r\n\r\n    use rand::prelude::*;\r\n\r\n    fn gen_random_path_sequence(rng: &mut impl Rng) -> Vec<PathSeg> {\r\n        const MAX_LENGTH: u32 = 10;\r\n\r\n        let mut elements = vec![];\r\n        let mut position = None;\r\n\r\n        let length = rng.gen_range(0..MAX_LENGTH);\r\n        for _ in 0..length {\r\n            let should_follow: bool = rand::random();\r\n            let kind = rng.gen_range(0..3);\r\n\r\n            let first = position\r\n                .filter(|_| should_follow)\r\n                .unwrap_or_else(|| Point::new(rng.gen(), rng.gen()));\r\n\r\n            let element: PathSeg = match kind {\r\n                0 => Line::new(first, Point::new(rng.gen(), rng.gen())).into(),\r\n\r\n                1 => QuadBez::new(\r\n                    first,\r\n                    Point::new(rng.gen(), rng.gen()),\r\n                    Point::new(rng.gen(), rng.gen()),\r\n                )\r\n                .into(),\r\n\r\n                2 => CubicBez::new(\r\n                    first,\r\n                    Point::new(rng.gen(), rng.gen()),\r\n                    Point::new(rng.gen(), rng.gen()),\r\n                    Point::new(rng.gen(), rng.gen()),\r\n                )\r\n                .into(),\r\n\r\n                _ => unreachable!(),\r\n            };\r\n\r\n            position = Some(element.end());\r\n            elements.push(element);\r\n        }\r\n\r\n        elements\r\n    }\r\n\r\n    #[test]\r\n    fn test_serialize_deserialize() {\r\n        const N_TESTS: u32 = 100;\r\n        let mut rng = rand::thread_rng();\r\n\r\n        for _ in 0..N_TESTS {\r\n            let vec = gen_random_path_sequence(&mut rng);\r\n            let ser = BezPath::from_path_segments(vec.iter().cloned()).to_svg();\r\n            let deser = BezPath::from_svg(&ser).expect(\"failed deserialization\");\r\n\r\n            let deser_vec = deser.segments().collect::<Vec<PathSeg>>();\r\n\r\n            assert_eq!(vec, deser_vec);\r\n        }\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/translate_scale.rs",
      "sha256": "8b6b3efbbaffc68994d548f39743c8b7b0a806f55d230ef26ec510bf037776a3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A transformation that includes both scale and translation.\r\n\r\nuse core::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};\r\n\r\nuse crate::{\r\n    Affine, Circle, CubicBez, Line, Point, QuadBez, Rect, RoundedRect, RoundedRectRadii, Vec2,\r\n};\r\n\r\n/// A transformation including scaling and translation.\r\n///\r\n/// If the translation is `(x, y)` and the scale is `s`, then this\r\n/// transformation represents this augmented matrix:\r\n///\r\n/// ```text\r\n/// | s 0 x |\r\n/// | 0 s y |\r\n/// | 0 0 1 |\r\n/// ```\r\n///\r\n/// See [`Affine`] for more details about the\r\n/// equivalence with augmented matrices.\r\n///\r\n/// Various multiplication ops are defined, and these are all defined\r\n/// to be consistent with matrix multiplication. Therefore,\r\n/// `TranslateScale * Point` is defined but not the other way around.\r\n///\r\n/// Also note that multiplication is not commutative. Thus,\r\n/// `TranslateScale::scale(2.0) * TranslateScale::translate(Vec2::new(1.0, 0.0))`\r\n/// has a translation of (2, 0), while\r\n/// `TranslateScale::translate(Vec2::new(1.0, 0.0)) * TranslateScale::scale(2.0)`\r\n/// has a translation of (1, 0). (Both have a scale of 2; also note that\r\n/// the first case can be written\r\n/// `2.0 * TranslateScale::translate(Vec2::new(1.0, 0.0))` as this case\r\n/// has an implicit conversion).\r\n///\r\n/// This transformation is less powerful than `Affine`, but can be applied\r\n/// to more primitives, especially including [`Rect`].\r\n#[derive(Clone, Copy, Debug)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct TranslateScale {\r\n    translation: Vec2,\r\n    scale: f64,\r\n}\r\n\r\nimpl TranslateScale {\r\n    /// Create a new transformation from translation and scale.\r\n    #[inline]\r\n    pub const fn new(translation: Vec2, scale: f64) -> TranslateScale {\r\n        TranslateScale { translation, scale }\r\n    }\r\n\r\n    /// Create a new transformation with scale only.\r\n    #[inline]\r\n    pub const fn scale(s: f64) -> TranslateScale {\r\n        TranslateScale::new(Vec2::ZERO, s)\r\n    }\r\n\r\n    /// Create a new transformation with translation only.\r\n    #[inline]\r\n    pub const fn translate(t: Vec2) -> TranslateScale {\r\n        TranslateScale::new(t, 1.0)\r\n    }\r\n\r\n    /// Decompose transformation into translation and scale.\r\n    pub fn as_tuple(self) -> (Vec2, f64) {\r\n        (self.translation, self.scale)\r\n    }\r\n\r\n    /// Compute the inverse transform.\r\n    ///\r\n    /// Multiplying a transform with its inverse (either on the\r\n    /// left or right) results in the identity transform\r\n    /// (modulo floating point rounding errors).\r\n    ///\r\n    /// Produces NaN values when scale is zero.\r\n    pub fn inverse(self) -> TranslateScale {\r\n        let scale_recip = self.scale.recip();\r\n        TranslateScale {\r\n            translation: self.translation * -scale_recip,\r\n            scale: scale_recip,\r\n        }\r\n    }\r\n\r\n    /// Is this translate/scale finite?\r\n    #[inline]\r\n    pub fn is_finite(&self) -> bool {\r\n        self.translation.is_finite() && self.scale.is_finite()\r\n    }\r\n\r\n    /// Is this translate/scale NaN?\r\n    #[inline]\r\n    pub fn is_nan(&self) -> bool {\r\n        self.translation.is_nan() || self.scale.is_nan()\r\n    }\r\n}\r\n\r\nimpl Default for TranslateScale {\r\n    #[inline]\r\n    fn default() -> TranslateScale {\r\n        TranslateScale::scale(1.0)\r\n    }\r\n}\r\n\r\nimpl From<TranslateScale> for Affine {\r\n    fn from(ts: TranslateScale) -> Affine {\r\n        let TranslateScale { translation, scale } = ts;\r\n        Affine::new([scale, 0.0, 0.0, scale, translation.x, translation.y])\r\n    }\r\n}\r\n\r\nimpl Mul<Point> for TranslateScale {\r\n    type Output = Point;\r\n\r\n    #[inline]\r\n    fn mul(self, other: Point) -> Point {\r\n        (self.scale * other.to_vec2()).to_point() + self.translation\r\n    }\r\n}\r\n\r\nimpl Mul for TranslateScale {\r\n    type Output = TranslateScale;\r\n\r\n    #[inline]\r\n    fn mul(self, other: TranslateScale) -> TranslateScale {\r\n        TranslateScale {\r\n            translation: self.translation + self.scale * other.translation,\r\n            scale: self.scale * other.scale,\r\n        }\r\n    }\r\n}\r\n\r\nimpl MulAssign for TranslateScale {\r\n    #[inline]\r\n    fn mul_assign(&mut self, other: TranslateScale) {\r\n        *self = self.mul(other);\r\n    }\r\n}\r\n\r\nimpl Mul<TranslateScale> for f64 {\r\n    type Output = TranslateScale;\r\n\r\n    #[inline]\r\n    fn mul(self, other: TranslateScale) -> TranslateScale {\r\n        TranslateScale {\r\n            translation: other.translation * self,\r\n            scale: other.scale * self,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Add<Vec2> for TranslateScale {\r\n    type Output = TranslateScale;\r\n\r\n    #[inline]\r\n    fn add(self, other: Vec2) -> TranslateScale {\r\n        TranslateScale {\r\n            translation: self.translation + other,\r\n            scale: self.scale,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Add<TranslateScale> for Vec2 {\r\n    type Output = TranslateScale;\r\n\r\n    #[inline]\r\n    fn add(self, other: TranslateScale) -> TranslateScale {\r\n        other + self\r\n    }\r\n}\r\n\r\nimpl AddAssign<Vec2> for TranslateScale {\r\n    #[inline]\r\n    fn add_assign(&mut self, other: Vec2) {\r\n        *self = self.add(other);\r\n    }\r\n}\r\n\r\nimpl Sub<Vec2> for TranslateScale {\r\n    type Output = TranslateScale;\r\n\r\n    #[inline]\r\n    fn sub(self, other: Vec2) -> TranslateScale {\r\n        TranslateScale {\r\n            translation: self.translation - other,\r\n            scale: self.scale,\r\n        }\r\n    }\r\n}\r\n\r\nimpl SubAssign<Vec2> for TranslateScale {\r\n    #[inline]\r\n    fn sub_assign(&mut self, other: Vec2) {\r\n        *self = self.sub(other);\r\n    }\r\n}\r\n\r\nimpl Mul<Circle> for TranslateScale {\r\n    type Output = Circle;\r\n\r\n    #[inline]\r\n    fn mul(self, other: Circle) -> Circle {\r\n        Circle::new(self * other.center, self.scale * other.radius)\r\n    }\r\n}\r\n\r\nimpl Mul<Line> for TranslateScale {\r\n    type Output = Line;\r\n\r\n    #[inline]\r\n    fn mul(self, other: Line) -> Line {\r\n        Line::new(self * other.p0, self * other.p1)\r\n    }\r\n}\r\n\r\nimpl Mul<Rect> for TranslateScale {\r\n    type Output = Rect;\r\n\r\n    #[inline]\r\n    fn mul(self, other: Rect) -> Rect {\r\n        let pt0 = self * Point::new(other.x0, other.y0);\r\n        let pt1 = self * Point::new(other.x1, other.y1);\r\n        (pt0, pt1).into()\r\n    }\r\n}\r\n\r\nimpl Mul<RoundedRect> for TranslateScale {\r\n    type Output = RoundedRect;\r\n\r\n    #[inline]\r\n    fn mul(self, other: RoundedRect) -> RoundedRect {\r\n        RoundedRect::from_rect(self * other.rect(), self * other.radii())\r\n    }\r\n}\r\n\r\nimpl Mul<RoundedRectRadii> for TranslateScale {\r\n    type Output = RoundedRectRadii;\r\n\r\n    #[inline]\r\n    fn mul(self, other: RoundedRectRadii) -> RoundedRectRadii {\r\n        RoundedRectRadii::new(\r\n            self.scale * other.top_left,\r\n            self.scale * other.top_right,\r\n            self.scale * other.bottom_right,\r\n            self.scale * other.bottom_left,\r\n        )\r\n    }\r\n}\r\n\r\nimpl Mul<QuadBez> for TranslateScale {\r\n    type Output = QuadBez;\r\n\r\n    #[inline]\r\n    fn mul(self, other: QuadBez) -> QuadBez {\r\n        QuadBez::new(self * other.p0, self * other.p1, self * other.p2)\r\n    }\r\n}\r\n\r\nimpl Mul<CubicBez> for TranslateScale {\r\n    type Output = CubicBez;\r\n\r\n    #[inline]\r\n    fn mul(self, other: CubicBez) -> CubicBez {\r\n        CubicBez::new(\r\n            self * other.p0,\r\n            self * other.p1,\r\n            self * other.p2,\r\n            self * other.p3,\r\n        )\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use crate::{Affine, Point, TranslateScale, Vec2};\r\n\r\n    fn assert_near(p0: Point, p1: Point) {\r\n        assert!((p1 - p0).hypot() < 1e-9, \"{p0:?} != {p1:?}\");\r\n    }\r\n\r\n    #[test]\r\n    fn translate_scale() {\r\n        let p = Point::new(3.0, 4.0);\r\n        let ts = TranslateScale::new(Vec2::new(5.0, 6.0), 2.0);\r\n\r\n        assert_near(ts * p, Point::new(11.0, 14.0));\r\n    }\r\n\r\n    #[test]\r\n    fn conversions() {\r\n        let p = Point::new(3.0, 4.0);\r\n        let s = 2.0;\r\n        let t = Vec2::new(5.0, 6.0);\r\n        let ts = TranslateScale::new(t, s);\r\n\r\n        // Test that conversion to affine is consistent.\r\n        let a: Affine = ts.into();\r\n        assert_near(ts * p, a * p);\r\n\r\n        assert_near((s * p.to_vec2()).to_point(), TranslateScale::scale(s) * p);\r\n        assert_near(p + t, TranslateScale::translate(t) * p);\r\n    }\r\n\r\n    #[test]\r\n    fn inverse() {\r\n        let p = Point::new(3.0, 4.0);\r\n        let ts = TranslateScale::new(Vec2::new(5.0, 6.0), 2.0);\r\n\r\n        assert_near(p, (ts * ts.inverse()) * p);\r\n        assert_near(p, (ts.inverse() * ts) * p);\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.9.5",
      "sourcePath": "src/vec2.rs",
      "sha256": "1d7b9f5132f6b68d70bc94f9547e65fd033ba5cd877207d888e378f392529736",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\r\n// SPDX-License-Identifier: Apache-2.0 OR MIT\r\n\r\n//! A simple 2D vector.\r\n\r\nuse core::fmt;\r\nuse core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};\r\n\r\nuse crate::common::FloatExt;\r\nuse crate::{Point, Size};\r\n\r\n#[cfg(not(feature = \"std\"))]\r\nuse crate::common::FloatFuncs;\r\n\r\n/// A 2D vector.\r\n///\r\n/// This is intended primarily for a vector in the mathematical sense,\r\n/// but it can be interpreted as a translation, and converted to and\r\n/// from a point (vector relative to the origin) and size.\r\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\r\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\r\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\r\npub struct Vec2 {\r\n    /// The x-coordinate.\r\n    pub x: f64,\r\n    /// The y-coordinate.\r\n    pub y: f64,\r\n}\r\n\r\nimpl Vec2 {\r\n    /// The vector (0, 0).\r\n    pub const ZERO: Vec2 = Vec2::new(0., 0.);\r\n\r\n    /// Create a new vector.\r\n    #[inline]\r\n    pub const fn new(x: f64, y: f64) -> Vec2 {\r\n        Vec2 { x, y }\r\n    }\r\n\r\n    /// Convert this vector into a `Point`.\r\n    #[inline]\r\n    pub const fn to_point(self) -> Point {\r\n        Point::new(self.x, self.y)\r\n    }\r\n\r\n    /// Convert this vector into a `Size`.\r\n    #[inline]\r\n    pub const fn to_size(self) -> Size {\r\n        Size::new(self.x, self.y)\r\n    }\r\n\r\n    /// Create a `Vec2` with the same value for x and y\r\n    pub(crate) const fn splat(v: f64) -> Self {\r\n        Vec2 { x: v, y: v }\r\n    }\r\n\r\n    /// Dot product of two vectors.\r\n    #[inline]\r\n    pub fn dot(self, other: Vec2) -> f64 {\r\n        self.x * other.x + self.y * other.y\r\n    }\r\n\r\n    /// Cross product of two vectors.\r\n    ///\r\n    /// This is signed so that (0, 1) × (1, 0) = 1.\r\n    #[inline]\r\n    pub fn cross(self, other: Vec2) -> f64 {\r\n        self.x * other.y - self.y * other.x\r\n    }\r\n\r\n    /// Magnitude of vector.\r\n    ///\r\n    /// This is similar to `self.hypot2().sqrt()` but defers to the platform `hypot` method, which\r\n    /// in general will handle the case where `self.hypot2() > f64::MAX`.\r\n    #[inline]\r\n    pub fn hypot(self) -> f64 {\r\n        self.x.hypot(self.y)\r\n    }\r\n\r\n    /// Magnitude of vector.\r\n    ///\r\n    /// This is an alias for [`Vec2::hypot`].\r\n    #[inline]\r\n    pub fn length(self) -> f64 {\r\n        self.hypot()\r\n    }\r\n\r\n    /// Magnitude squared of vector.\r\n    #[inline]\r\n    pub fn hypot2(self) -> f64 {\r\n        self.dot(self)\r\n    }\r\n\r\n    /// Magnitude squared of vector.\r\n    ///\r\n    /// This is an alias for [`Vec2::hypot2`].\r\n    #[inline]\r\n    pub fn length_squared(self) -> f64 {\r\n        self.hypot2()\r\n    }\r\n\r\n    /// Find the angle in radians between this vector and the vector `Vec2 { x: 1.0, y: 0.0 }`\r\n    /// in the positive `y` direction.\r\n    ///\r\n    /// If the vector is interpreted as a complex number, this is the argument.\r\n    /// The angle is expressed in radians.\r\n    #[inline]\r\n    pub fn atan2(self) -> f64 {\r\n        self.y.atan2(self.x)\r\n    }\r\n\r\n    /// Find the angle in radians between this vector and the vector `Vec2 { x: 1.0, y: 0.0 }`\r\n    /// in the positive `y` direction.\r\n    ///\r\n    /// This is an alias for [`Vec2::atan2`].\r\n    #[inline]\r\n    pub fn angle(self) -> f64 {\r\n        self.atan2()\r\n    }\r\n\r\n    /// A unit vector of the given angle.\r\n    ///\r\n    /// With `th` at zero, the result is the positive X unit vector, and\r\n    /// at π/2, it is the positive Y unit vector. The angle is expressed\r\n    /// in radians.\r\n    ///\r\n    /// Thus, in a Y-down coordinate system (as is common for graphics),\r\n    /// it is a clockwise rotation, and in Y-up (traditional for math), it\r\n    /// is anti-clockwise. This convention is consistent with\r\n    /// [`Affine::rotate`].\r\n    ///\r\n    /// [`Affine::rotate`]: crate::Affine::rotate\r\n    #[inline]\r\n    pub fn from_angle(th: f64) -> Vec2 {\r\n        let (th_sin, th_cos) = th.sin_cos();\r\n        Vec2 {\r\n            x: th_cos,\r\n            y: th_sin,\r\n        }\r\n    }\r\n\r\n    /// Linearly interpolate between two vectors.\r\n    #[inline]\r\n    pub fn lerp(self, other: Vec2, t: f64) -> Vec2 {\r\n        self + t * (other - self)\r\n    }\r\n\r\n    /// Returns a vector of magnitude 1.0 with the same angle as `self`; i.e.\r\n    /// a unit/direction vector.\r\n    ///\r\n    /// This produces `NaN` values when the magnitude is `0`.\r\n    #[inline]\r\n    pub fn normalize(self) -> Vec2 {\r\n        self / self.hypot()\r\n    }\r\n\r\n    /// Returns a new `Vec2`,\r\n    /// with `x` and `y` rounded to the nearest integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Vec2;\r\n    /// let a = Vec2::new(3.3, 3.6).round();\r\n    /// let b = Vec2::new(3.0, -3.1).round();\r\n    /// assert_eq!(a.x, 3.0);\r\n    /// assert_eq!(a.y, 4.0);\r\n    /// assert_eq!(b.x, 3.0);\r\n    /// assert_eq!(b.y, -3.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn round(self) -> Vec2 {\r\n        Vec2::new(self.x.round(), self.y.round())\r\n    }\r\n\r\n    /// Returns a new `Vec2`,\r\n    /// with `x` and `y` rounded up to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Vec2;\r\n    /// let a = Vec2::new(3.3, 3.6).ceil();\r\n    /// let b = Vec2::new(3.0, -3.1).ceil();\r\n    /// assert_eq!(a.x, 4.0);\r\n    /// assert_eq!(a.y, 4.0);\r\n    /// assert_eq!(b.x, 3.0);\r\n    /// assert_eq!(b.y, -3.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn ceil(self) -> Vec2 {\r\n        Vec2::new(self.x.ceil(), self.y.ceil())\r\n    }\r\n\r\n    /// Returns a new `Vec2`,\r\n    /// with `x` and `y` rounded down to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Vec2;\r\n    /// let a = Vec2::new(3.3, 3.6).floor();\r\n    /// let b = Vec2::new(3.0, -3.1).floor();\r\n    /// assert_eq!(a.x, 3.0);\r\n    /// assert_eq!(a.y, 3.0);\r\n    /// assert_eq!(b.x, 3.0);\r\n    /// assert_eq!(b.y, -4.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn floor(self) -> Vec2 {\r\n        Vec2::new(self.x.floor(), self.y.floor())\r\n    }\r\n\r\n    /// Returns a new `Vec2`,\r\n    /// with `x` and `y` rounded away from zero to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Vec2;\r\n    /// let a = Vec2::new(3.3, 3.6).expand();\r\n    /// let b = Vec2::new(3.0, -3.1).expand();\r\n    /// assert_eq!(a.x, 4.0);\r\n    /// assert_eq!(a.y, 4.0);\r\n    /// assert_eq!(b.x, 3.0);\r\n    /// assert_eq!(b.y, -4.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn expand(self) -> Vec2 {\r\n        Vec2::new(self.x.expand(), self.y.expand())\r\n    }\r\n\r\n    /// Returns a new `Vec2`,\r\n    /// with `x` and `y` rounded towards zero to the nearest integer,\r\n    /// unless they are already an integer.\r\n    ///\r\n    /// # Examples\r\n    ///\r\n    /// ```\r\n    /// use kurbo::Vec2;\r\n    /// let a = Vec2::new(3.3, 3.6).trunc();\r\n    /// let b = Vec2::new(3.0, -3.1).trunc();\r\n    /// assert_eq!(a.x, 3.0);\r\n    /// assert_eq!(a.y, 3.0);\r\n    /// assert_eq!(b.x, 3.0);\r\n    /// assert_eq!(b.y, -3.0);\r\n    /// ```\r\n    #[inline]\r\n    pub fn trunc(self) -> Vec2 {\r\n        Vec2::new(self.x.trunc(), self.y.trunc())\r\n    }\r\n\r\n    /// Is this Vec2 finite?\r\n    #[inline]\r\n    pub fn is_finite(self) -> bool {\r\n        self.x.is_finite() && self.y.is_finite()\r\n    }\r\n\r\n    /// Is this Vec2 NaN?\r\n    #[inline]\r\n    pub fn is_nan(self) -> bool {\r\n        self.x.is_nan() || self.y.is_nan()\r\n    }\r\n\r\n    /// Divides this Vec2 by a scalar.\r\n    ///\r\n    /// Unlike the division by scalar operator, which multiplies by the\r\n    /// reciprocal for performance, this performs the division\r\n    /// per-component for consistent rounding behavior.\r\n    pub(crate) fn div_exact(self, divisor: f64) -> Vec2 {\r\n        Vec2 {\r\n            x: self.x / divisor,\r\n            y: self.y / divisor,\r\n        }\r\n    }\r\n}\r\n\r\nimpl From<(f64, f64)> for Vec2 {\r\n    #[inline]\r\n    fn from(v: (f64, f64)) -> Vec2 {\r\n        Vec2 { x: v.0, y: v.1 }\r\n    }\r\n}\r\n\r\nimpl From<Vec2> for (f64, f64) {\r\n    #[inline]\r\n    fn from(v: Vec2) -> (f64, f64) {\r\n        (v.x, v.y)\r\n    }\r\n}\r\n\r\nimpl Add for Vec2 {\r\n    type Output = Vec2;\r\n\r\n    #[inline]\r\n    fn add(self, other: Vec2) -> Vec2 {\r\n        Vec2 {\r\n            x: self.x + other.x,\r\n            y: self.y + other.y,\r\n        }\r\n    }\r\n}\r\n\r\nimpl AddAssign for Vec2 {\r\n    #[inline]\r\n    fn add_assign(&mut self, other: Vec2) {\r\n        *self = Vec2 {\r\n            x: self.x + other.x,\r\n            y: self.y + other.y,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Sub for Vec2 {\r\n    type Output = Vec2;\r\n\r\n    #[inline]\r\n    fn sub(self, other: Vec2) -> Vec2 {\r\n        Vec2 {\r\n            x: self.x - other.x,\r\n            y: self.y - other.y,\r\n        }\r\n    }\r\n}\r\n\r\nimpl SubAssign for Vec2 {\r\n    #[inline]\r\n    fn sub_assign(&mut self, other: Vec2) {\r\n        *self = Vec2 {\r\n            x: self.x - other.x,\r\n            y: self.y - other.y,\r\n        }\r\n    }\r\n}\r\n\r\nimpl Mul<f64> for Vec2 {\r\n    type Output = Vec2;\r\n\r\n    #[inline]\r\n    fn mul(self, other: f64) -> Vec2 {\r\n        Vec2 {\r\n            x: self.x * other,\r\n            y: self.y * other,\r\n        }\r\n    }\r\n}\r\n\r\nimpl MulAssign<f64> for Vec2 {\r\n    #[inline]\r\n    fn mul_assign(&mut self, other: f64) {\r\n        *self = Vec2 {\r\n            x: self.x * other,\r\n            y: self.y * other,\r\n        };\r\n    }\r\n}\r\n\r\nimpl Mul<Vec2> for f64 {\r\n    type Output = Vec2;\r\n\r\n    #[inline]\r\n    fn mul(self, other: Vec2) -> Vec2 {\r\n        other * self\r\n    }\r\n}\r\n\r\nimpl Div<f64> for Vec2 {\r\n    type Output = Vec2;\r\n\r\n    /// Note: division by a scalar is implemented by multiplying by the reciprocal.\r\n    ///\r\n    /// This is more efficient but has different roundoff behavior than division.\r\n    #[inline]\r\n    #[allow(clippy::suspicious_arithmetic_impl)]\r\n    fn div(self, other: f64) -> Vec2 {\r\n        self * other.recip()\r\n    }\r\n}\r\n\r\nimpl DivAssign<f64> for Vec2 {\r\n    #[inline]\r\n    fn div_assign(&mut self, other: f64) {\r\n        self.mul_assign(other.recip());\r\n    }\r\n}\r\n\r\nimpl Neg for Vec2 {\r\n    type Output = Vec2;\r\n\r\n    #[inline]\r\n    fn neg(self) -> Vec2 {\r\n        Vec2 {\r\n            x: -self.x,\r\n            y: -self.y,\r\n        }\r\n    }\r\n}\r\n\r\nimpl fmt::Display for Vec2 {\r\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\r\n        write!(formatter, \"𝐯=(\")?;\r\n        fmt::Display::fmt(&self.x, formatter)?;\r\n        write!(formatter, \", \")?;\r\n        fmt::Display::fmt(&self.y, formatter)?;\r\n        write!(formatter, \")\")\r\n    }\r\n}\r\n\r\n// Conversions to and from mint\r\n#[cfg(feature = \"mint\")]\r\nimpl From<Vec2> for mint::Vector2<f64> {\r\n    #[inline]\r\n    fn from(p: Vec2) -> mint::Vector2<f64> {\r\n        mint::Vector2 { x: p.x, y: p.y }\r\n    }\r\n}\r\n\r\n#[cfg(feature = \"mint\")]\r\nimpl From<mint::Vector2<f64>> for Vec2 {\r\n    #[inline]\r\n    fn from(p: mint::Vector2<f64>) -> Vec2 {\r\n        Vec2 { x: p.x, y: p.y }\r\n    }\r\n}\r\n\r\n#[cfg(test)]\r\nmod tests {\r\n    use super::*;\r\n    #[test]\r\n    fn display() {\r\n        let v = Vec2::new(1.2332421, 532.10721213123);\r\n        let s = format!(\"{v:.2}\");\r\n        assert_eq!(s.as_str(), \"𝐯=(1.23, 532.11)\");\r\n    }\r\n}\r\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "benches/cubic_arclen.rs",
      "sha256": "4e5071f1ee932b0185957b44d51285d2bc7336c0d2b39d50e69b278e8838b62f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Benchmarks of cubic arclength approaches.\n\n#![cfg(nightly)]\n#![feature(test)]\nextern crate test;\nuse test::Bencher;\n\nuse kurbo::{CubicBez, ParamCurveArclen};\n\n#[bench]\nfn bench_cubic_arclen_1e_4(b: &mut Bencher) {\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\n    b.iter(|| test::black_box(c).arclen(1e-4))\n}\n\n#[bench]\nfn bench_cubic_arclen_1e_5(b: &mut Bencher) {\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\n    b.iter(|| test::black_box(c).arclen(1e-5))\n}\n\n#[bench]\nfn bench_cubic_arclen_1e_6(b: &mut Bencher) {\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\n    b.iter(|| test::black_box(c).arclen(1e-6))\n}\n\n#[bench]\nfn bench_cubic_arclen_degenerate(b: &mut Bencher) {\n    let c = CubicBez::new((0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0));\n    b.iter(|| test::black_box(c).arclen(1e-6))\n}\n\n#[bench]\nfn bench_cubic_arclen_1e_7(b: &mut Bencher) {\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\n    b.iter(|| test::black_box(c).arclen(1e-7))\n}\n\n#[bench]\nfn bench_cubic_arclen_1e_8(b: &mut Bencher) {\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\n    b.iter(|| test::black_box(c).arclen(1e-8))\n}\n\n#[bench]\nfn bench_cubic_arclen_1e_9(b: &mut Bencher) {\n    let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 1.0), (1.0, 1.0));\n    b.iter(|| test::black_box(c).arclen(1e-9))\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "benches/quad_arclen.rs",
      "sha256": "c6828b1c2eaa63a9d9ff99e20808d1905c5fef7891c8c5df44cb2f88a89a403d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Benchmarks of quadratic arclength approaches.\n\n// TODO: organize so there's less cut'n'paste from arclen_accuracy example.\n\n#![cfg(nightly)]\n#![feature(test)]\nextern crate test;\nuse test::Bencher;\n\nuse kurbo::{ParamCurve, ParamCurveArclen, ParamCurveDeriv, QuadBez};\n\n// Based on http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/\nfn quad_arclen_analytical(q: QuadBez) -> f64 {\n    let d2 = q.p0.to_vec2() - 2.0 * q.p1.to_vec2() + q.p2.to_vec2();\n    let a = d2.hypot2();\n    let d1 = q.p1 - q.p0;\n    let b = 2.0 * d2.dot(d1);\n    let c = d1.hypot2();\n\n    let sabc = (a + b + c).sqrt();\n    let a2 = a.powf(-0.5);\n    let a32 = a2.powi(3);\n    let c2 = 2.0 * c.sqrt();\n    let ba = b * a2;\n\n    sabc + 0.25\n        * (a2 * a2 * b * (2.0 * sabc - c2)\n            + a32 * (4.0 * c * a - b * b) * (((2.0 * a + b) * a2 + 2.0 * sabc) / (ba + c2)).ln())\n}\n\n/// Calculate arclength using Gauss-Legendre quadrature using formula from Behdad\n/// in https://github.com/Pomax/BezierInfo-2/issues/77\nfn gauss_arclen_3(q: QuadBez) -> f64 {\n    let v0 = (-0.492943519233745 * q.p0.to_vec2()\n        + 0.430331482911935 * q.p1.to_vec2()\n        + 0.0626120363218102 * q.p2.to_vec2())\n    .hypot();\n    let v1 = ((q.p2 - q.p0) * 0.4444444444444444).hypot();\n    let v2 = (-0.0626120363218102 * q.p0.to_vec2() - 0.430331482911935 * q.p1.to_vec2()\n        + 0.492943519233745 * q.p2.to_vec2())\n    .hypot();\n    v0 + v1 + v2\n}\n\nfn awesome_quad_arclen3(q: QuadBez, accuracy: f64, depth: usize) -> f64 {\n    let pm = q.p0.midpoint(q.p2);\n    let d1 = q.p1 - pm;\n    let d = q.p2 - q.p0;\n    let dhypot2 = d.hypot2();\n    let x = 2.0 * d.dot(d1) / dhypot2;\n    let y = 2.0 * d.cross(d1) / dhypot2;\n    let lc = (q.p2 - q.p0).hypot();\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\n    let est_err = 0.06 * (lp - lc) * (x * x + y * y).powf(2.0);\n    if est_err < accuracy || depth == 16 {\n        gauss_arclen_3(q)\n    } else {\n        let (q0, q1) = q.subdivide();\n        awesome_quad_arclen3(q0, accuracy * 0.5, depth + 1)\n            + awesome_quad_arclen3(q1, accuracy * 0.5, depth + 1)\n    }\n}\n\n/// Another implementation, using weights from\n/// https://pomax.github.io/bezierinfo/legendre-gauss.html\nfn gauss_arclen_n(q: QuadBez, coeffs: &[(f64, f64)]) -> f64 {\n    let d = q.deriv();\n    coeffs\n        .iter()\n        .map(|(wi, xi)| wi * d.eval(0.5 * (xi + 1.0)).to_vec2().hypot())\n        .sum::<f64>()\n        * 0.5\n}\n\nfn gauss_arclen_7(q: QuadBez) -> f64 {\n    gauss_arclen_n(\n        q,\n        &[\n            (0.4179591836734694, 0.0000000000000000),\n            (0.3818300505051189, 0.4058451513773972),\n            (0.3818300505051189, -0.4058451513773972),\n            (0.2797053914892766, -0.7415311855993945),\n            (0.2797053914892766, 0.7415311855993945),\n            (0.1294849661688697, -0.9491079123427585),\n            (0.1294849661688697, 0.9491079123427585),\n        ],\n    )\n}\n\nfn gauss_arclen_24(q: QuadBez) -> f64 {\n    gauss_arclen_n(\n        q,\n        &[\n            (0.1279381953467522, -0.0640568928626056),\n            (0.1279381953467522, 0.0640568928626056),\n            (0.1258374563468283, -0.1911188674736163),\n            (0.1258374563468283, 0.1911188674736163),\n            (0.1216704729278034, -0.3150426796961634),\n            (0.1216704729278034, 0.3150426796961634),\n            (0.1155056680537256, -0.4337935076260451),\n            (0.1155056680537256, 0.4337935076260451),\n            (0.1074442701159656, -0.5454214713888396),\n            (0.1074442701159656, 0.5454214713888396),\n            (0.0976186521041139, -0.6480936519369755),\n            (0.0976186521041139, 0.6480936519369755),\n            (0.0861901615319533, -0.7401241915785544),\n            (0.0861901615319533, 0.7401241915785544),\n            (0.0733464814110803, -0.8200019859739029),\n            (0.0733464814110803, 0.8200019859739029),\n            (0.0592985849154368, -0.8864155270044011),\n            (0.0592985849154368, 0.8864155270044011),\n            (0.0442774388174198, -0.9382745520027328),\n            (0.0442774388174198, 0.9382745520027328),\n            (0.0285313886289337, -0.9747285559713095),\n            (0.0285313886289337, 0.9747285559713095),\n            (0.0123412297999872, -0.9951872199970213),\n            (0.0123412297999872, 0.9951872199970213),\n        ],\n    )\n}\n\nfn awesome_quad_arclen7(q: QuadBez, accuracy: f64, depth: usize) -> f64 {\n    let pm = q.p0.midpoint(q.p2);\n    let d1 = q.p1 - pm;\n    let d = q.p2 - q.p0;\n    let dhypot2 = d.hypot2();\n    let x = 2.0 * d.dot(d1) / dhypot2;\n    let y = 2.0 * d.cross(d1) / dhypot2;\n    let lc = dhypot2.sqrt();\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\n    let est_err = 2.5e-2 * (lp - lc) * (x * x + y * y).powf(8.0).tanh();\n    if est_err < accuracy || depth == 16 {\n        gauss_arclen_7(q)\n    } else {\n        let (q0, q1) = q.subdivide();\n        awesome_quad_arclen7(q0, accuracy * 0.5, depth + 1)\n            + awesome_quad_arclen7(q1, accuracy * 0.5, depth + 1)\n    }\n}\n\n#[bench]\nfn bench_quad_arclen_analytical(b: &mut Bencher) {\n    // Analytical solution is not sensitive to exact shape.\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\n    b.iter(|| quad_arclen_analytical(test::black_box(q)))\n}\n\nconst ACCURACY: f64 = 1e-6;\n\n#[bench]\nfn bench_quad_arclen(b: &mut Bencher) {\n    // This is a pretty easy case.\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\n    b.iter(|| (test::black_box(q).arclen(ACCURACY)))\n}\n\n#[bench]\nfn bench_quad_arclen_gauss3(b: &mut Bencher) {\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\n    b.iter(|| awesome_quad_arclen3(test::black_box(q), ACCURACY, 0))\n}\n\n#[bench]\nfn bench_quad_arclen_gauss7(b: &mut Bencher) {\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\n    b.iter(|| awesome_quad_arclen7(test::black_box(q), ACCURACY, 0))\n}\n\n#[bench]\nfn bench_quad_arclen_gauss3_one(b: &mut Bencher) {\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\n    b.iter(|| gauss_arclen_3(test::black_box(q)))\n}\n\n#[bench]\nfn bench_quad_arclen_gauss7_one(b: &mut Bencher) {\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\n    b.iter(|| gauss_arclen_7(test::black_box(q)))\n}\n\n#[bench]\nfn bench_quad_arclen_gauss24_one(b: &mut Bencher) {\n    let q = QuadBez::new((0.0, 0.0), (1.0, 0.0), (1.0, 1.0));\n    b.iter(|| gauss_arclen_24(test::black_box(q)))\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "benches/quartic.rs",
      "sha256": "d5e857f92418cd16db26ed27b29692af8c0fe6d228fe8acc29e3e1b2a51334ab",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Benchmarks of the quartic equation solver.\n\n#![cfg(nightly)]\n#![feature(test)]\nextern crate test;\nuse kurbo::common::solve_quartic;\nuse test::Bencher;\n\n#[bench]\nfn bench_quartic(bb: &mut Bencher) {\n    let (x1, x2, x3, x4) = (1.0, 2.0, 3.0, 4.0);\n    let a = -(x1 + x2 + x3 + x4);\n    let b = x1 * (x2 + x3) + x2 * (x3 + x4) + x4 * (x1 + x3);\n    let c = -x1 * x2 * (x3 + x4) - x3 * x4 * (x1 + x2);\n    let d = x1 * x2 * x3 * x4;\n\n    bb.iter(|| {\n        solve_quartic(\n            test::black_box(d),\n            test::black_box(c),\n            test::black_box(b),\n            test::black_box(a),\n            1.0,\n        )\n    })\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "benches/rect_expand.rs",
      "sha256": "64e066afc1e03e3464b6653390b8ce1bfe047aa048ff673657797b89c46ee831",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![cfg(nightly)]\n#![feature(test)]\nextern crate test;\nuse test::Bencher;\n\nuse kurbo::Rect;\n\n// In positive space\nstatic RECT_POS: Rect = Rect::new(3.3, 3.6, 5.6, 4.1);\n// In both positive and negative space\nstatic RECT_PAN: Rect = Rect::new(-3.3, -3.6, 5.6, 4.1);\n// In negative space\nstatic RECT_NEG: Rect = Rect::new(-5.6, -4.1, -3.3, -3.6);\n// In positive space reverse\nstatic RECT_POR: Rect = Rect::new(5.6, 4.1, 3.3, 3.6);\n// In both positive and negative space reverse\nstatic RECT_PNR: Rect = Rect::new(5.6, 4.1, -3.3, -3.6);\n// In negative space reverse\nstatic RECT_NER: Rect = Rect::new(-3.3, -3.6, -5.6, -4.1);\n// In positive space mixed\nstatic RECT_POM: Rect = Rect::new(3.3, 4.1, 5.6, 3.6);\n// In both positive and negative space mixed\nstatic RECT_PNM: Rect = Rect::new(-3.3, 4.1, 5.6, -3.6);\n// In negative space mixed\nstatic RECT_NEM: Rect = Rect::new(-5.6, -3.6, -3.3, -4.1);\n\n#[inline]\nfn expand(rects: &[Rect; 9]) {\n    test::black_box(rects[0].expand());\n    test::black_box(rects[1].expand());\n    test::black_box(rects[2].expand());\n\n    test::black_box(rects[3].expand());\n    test::black_box(rects[4].expand());\n    test::black_box(rects[5].expand());\n\n    test::black_box(rects[6].expand());\n    test::black_box(rects[7].expand());\n    test::black_box(rects[8].expand());\n}\n\n#[bench]\nfn bench_expand(b: &mut Bencher) {\n    // Creating the array here to prevent the compiler from optimizing all of it to NOP.\n    let rects: [Rect; 9] = [\n        RECT_POS, RECT_PAN, RECT_NEG, RECT_POR, RECT_PNR, RECT_NER, RECT_POM, RECT_PNM, RECT_NEM,\n    ];\n    b.iter(|| expand(&rects));\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "examples/arclen_accuracy.rs",
      "sha256": "20a190ab7ae1d36a098b3b209f9b216aa95fa4654e62bb2375748c67b483ebc1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A test program to plot the error of arclength approximation.\n\n// Lots of stuff is commented out or was just something to try.\n#![allow(unused)]\n#![allow(clippy::unreadable_literal)]\n#![allow(clippy::many_single_char_names)]\n\n// TODO: make more functionality accessible from command line rather than uncommenting.\n\nuse std::env;\nuse std::time::{Duration, Instant};\n\nuse kurbo::{ParamCurve, ParamCurveArclen, ParamCurveDeriv, QuadBez};\n\nuse kurbo::common::{GAUSS_LEGENDRE_COEFFS_24, GAUSS_LEGENDRE_COEFFS_5, GAUSS_LEGENDRE_COEFFS_7};\n\n/// Calculate arclength using Gauss-Legendre quadrature using formula from Behdad\n/// in https://github.com/Pomax/BezierInfo-2/issues/77\nfn gauss_arclen_3(q: QuadBez) -> f64 {\n    let v0 = (-0.492943519233745 * q.p0.to_vec2()\n        + 0.430331482911935 * q.p1.to_vec2()\n        + 0.0626120363218102 * q.p2.to_vec2())\n    .hypot();\n    let v1 = ((q.p2 - q.p0) * 0.4444444444444444).hypot();\n    let v2 = (-0.0626120363218102 * q.p0.to_vec2() - 0.430331482911935 * q.p1.to_vec2()\n        + 0.492943519233745 * q.p2.to_vec2())\n    .hypot();\n    v0 + v1 + v2\n}\n\nfn awesome_quad_arclen(q: QuadBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\n    let pm = q.p0.midpoint(q.p2);\n    let d1 = q.p1 - pm;\n    let d = q.p2 - q.p0;\n    let dhypot2 = d.hypot2();\n    let x = 2.0 * d.dot(d1) / dhypot2;\n    let y = 2.0 * d.cross(d1) / dhypot2;\n    let lc = (q.p2 - q.p0).hypot();\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\n    let est_err = 0.06 * (lp - lc) * (x * x + y * y).powf(2.0);\n    if est_err < accuracy || depth == 16 {\n        *count += 1;\n        gauss_arclen_3(q)\n    } else {\n        let (q0, q1) = q.subdivide();\n        awesome_quad_arclen(q0, accuracy * 0.5, depth + 1, count)\n            + awesome_quad_arclen(q1, accuracy * 0.5, depth + 1, count)\n    }\n}\n\nconst MAX_DEPTH: usize = 16;\nfn gravesen_rec(q: &QuadBez, l0: f64, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\n    let (q0, q1) = q.subdivide();\n    let l0_q0 = calc_l0(q0);\n    let l0_q1 = calc_l0(q1);\n    let l1 = l0_q0 + l0_q1;\n    let error = (l0 - l1) * (1.0 / 15.0);\n    if error.abs() < accuracy || depth == MAX_DEPTH {\n        *count += 1;\n        l1 - error\n    } else {\n        gravesen_rec(&q0, l0_q0, accuracy * 0.5, depth + 1, count)\n            + gravesen_rec(&q1, l0_q1, accuracy * 0.5, depth + 1, count)\n    }\n}\n\nfn gauss_arclen_5(q: QuadBez) -> f64 {\n    q.gauss_arclen(GAUSS_LEGENDRE_COEFFS_5)\n}\n\nfn gauss_arclen_7(q: QuadBez) -> f64 {\n    q.gauss_arclen(GAUSS_LEGENDRE_COEFFS_7)\n}\n\nfn gauss_arclen_24(q: QuadBez) -> f64 {\n    q.gauss_arclen(GAUSS_LEGENDRE_COEFFS_24)\n}\n\nfn awesome_quad_arclen7(q: QuadBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\n    let pm = q.p0.midpoint(q.p2);\n    let d1 = q.p1 - pm;\n    let d = q.p2 - q.p0;\n    let dhypot2 = d.hypot2();\n    let x = 2.0 * d.dot(d1) / dhypot2;\n    let y = 2.0 * d.cross(d1) / dhypot2;\n    let lc = (q.p2 - q.p0).hypot();\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\n    let est_err = 2.5e-2 * (lp - lc) * (x * x + y * y).powf(8.0).tanh();\n    // Increase depth, so we can be an accurate baseline for comparison.\n    if est_err < accuracy || depth == 22 {\n        *count += 1;\n        gauss_arclen_7(q)\n    } else {\n        let (q0, q1) = q.subdivide();\n        awesome_quad_arclen7(q0, accuracy * 0.5, depth + 1, count)\n            + awesome_quad_arclen7(q1, accuracy * 0.5, depth + 1, count)\n    }\n}\n\nfn awesome_quad_arclen24(q: QuadBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\n    let pm = q.p0.midpoint(q.p2);\n    let d1 = q.p1 - pm;\n    let d = q.p2 - q.p0;\n    let dhypot2 = d.hypot2();\n    let x = 2.0 * d.dot(d1) / dhypot2;\n    let y = 2.0 * d.cross(d1) / dhypot2;\n    let lc = (q.p2 - q.p0).hypot();\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\n    // This isn't quite right near (1.1, 0)\n    let est_err = 1.0 * (lp - lc) * (0.5 * x * x + 0.1 * y * y).powf(16.0).tanh();\n    if est_err < accuracy || depth == 16 {\n        *count += 1;\n        gauss_arclen_24(q)\n    } else {\n        let (q0, q1) = q.subdivide();\n        awesome_quad_arclen24(q0, accuracy * 0.5, depth + 1, count)\n            + awesome_quad_arclen24(q1, accuracy * 0.5, depth + 1, count)\n    }\n}\n\n// Based on http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/\nfn quad_arclen_analytical(q: QuadBez) -> f64 {\n    let d2 = q.p0.to_vec2() - 2.0 * q.p1.to_vec2() + q.p2.to_vec2();\n    let a = d2.hypot2();\n    let d1 = q.p1 - q.p0;\n    let c = d1.hypot2();\n    if a < 5e-4 * c {\n        return gauss_arclen_3(q);\n    }\n    let b = 2.0 * d2.dot(d1);\n\n    let sabc = (a + b + c).sqrt();\n    let a2 = a.powf(-0.5);\n    let a32 = a2.powi(3);\n    let c2 = 2.0 * c.sqrt();\n    let ba_c2 = b * a2 + c2;\n\n    let v0 = 0.25 * a2 * a2 * b * (2.0 * sabc - c2) + sabc;\n    // TODO: justify and fine-tune this exact constant.\n    if ba_c2 < 1e-13 {\n        // This case happens for Béziers with a sharp kink.\n        v0\n    } else {\n        v0 + 0.25 * a32 * (4.0 * c * a - b * b) * (((2.0 * a + b) * a2 + 2.0 * sabc) / ba_c2).ln()\n    }\n}\n\n/// Calculate the L0 metric from \"Adaptive subdivision and the length and\n/// energy of Bézier curves\" by Jens Gravesen.\nfn calc_l0(q: QuadBez) -> f64 {\n    let lc = (q.p2 - q.p0).hypot();\n    let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\n    (2.0 / 3.0) * lc + (1.0 / 3.0) * lp\n}\n\nfn with_subdiv(q: QuadBez, f: &dyn Fn(QuadBez) -> f64, depth: usize) -> f64 {\n    if depth == 0 {\n        f(q)\n    } else {\n        let (q0, q1) = q.subdivide();\n        with_subdiv(q0, f, depth - 1) + with_subdiv(q1, f, depth - 1)\n    }\n}\n\nfn duration_to_time(d: Duration) -> f64 {\n    1e-9 * (d.subsec_nanos() as f64) + (d.as_secs() as f64)\n}\n\nfn run_simple() {\n    let q = QuadBez::new((0.0, 0.0), (0.0, 0.5), (1.0, 1.0));\n    let true_len = q.arclen(1e-13);\n    for i in 0..20 {\n        let n = 1 << i;\n        let start_time = Instant::now();\n        let mut est = 0.0;\n        let mut last = q.start();\n        let dt = (n as f64).recip();\n        for j in 0..n {\n            let t = ((j + 1) as f64) * dt;\n            let p = q.eval(t);\n            est += (p - last).hypot();\n            last = p;\n        }\n        let elapsed = duration_to_time(start_time.elapsed());\n        let err = true_len - est;\n        if i > 0 {\n            println!(\"{elapsed} {err}\");\n        }\n    }\n}\n\n/// Generate map data suitable for plotting in Gnuplot.\nfn main() {\n    let mut n_subdiv = 0;\n    let mut func: &dyn Fn(QuadBez) -> f64 = &gauss_arclen_3;\n    for arg in env::args().skip(1) {\n        if arg == \"gauss3\" {\n            func = &gauss_arclen_3;\n        } else if arg == \"gauss5\" {\n            func = &gauss_arclen_5;\n        } else if arg == \"gauss7\" {\n            func = &gauss_arclen_7;\n        } else if arg == \"gauss24\" {\n            func = &gauss_arclen_24;\n        } else if arg == \"l0\" {\n            func = &calc_l0;\n        } else if arg == \"simple\" {\n            run_simple();\n            return;\n        } else if let Ok(n) = arg.parse() {\n            n_subdiv = n;\n        } else {\n            println!(\"usage: arclen_accuracy [func] n_subdiv\");\n            std::process::exit(1);\n        }\n    }\n    let n = 400;\n    let accuracy = 1e-6;\n    for i in 0..=n {\n        let x = 2.0 * (i as f64) * (n as f64).recip();\n        for j in 0..=n {\n            let y = 2.0 * (j as f64) * (n as f64).recip();\n            let q = QuadBez::new((-1.0, 0.0), (x, y), (1.0, 0.0));\n            let mut count = 0;\n            let accurate_arclen = awesome_quad_arclen7(q, 1e-15, 0, &mut count);\n            //count = 0;\n            let start_time = Instant::now();\n            //let est = awesome_quad_arclen7(q, accuracy, 0, &mut count);\n            let est = quad_arclen_analytical(q);\n            let elapsed = start_time.elapsed();\n            //let est = gravesen_rec(&q, calc_l0(q), accuracy, 0, &mut count);\n            //let est = with_subdiv(q, func, n_subdiv);\n            let error = est - accurate_arclen;\n            println!(\"{} {} {}\", x, y, (error.abs() + 1e-18).log10());\n            //println!(\"{} {} {}\", x, y, count);\n            //println!(\"{} {} {}\", x, y, elapsed.subsec_nanos());\n            //let accurate_arclen = with_subdiv(q, &gauss_arclen_5, 8);\n            //let error = est - accurate_arclen;\n            /*\n            let lc = (q.p2 - q.p0).hypot();\n            let lp = (q.p1 - q.p0).hypot() + (q.p2 - q.p1).hypot();\n            let est_err = 1.0 * (lp - lc) * (0.5 * x * x + 0.1 * y * y).powf(16.0).tanh();\n            println!(\"{} {} {}\", x, y, (est_err/error.abs() + 1e-15).log10());\n            */\n        }\n        println!();\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "examples/circle.rs",
      "sha256": "bed0de2cc5e772ad9b6558ad75437b46a309b743475aa65d1b903abe88e32cc1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Example of circle\n\n#[cfg(feature = \"std\")]\nfn main() {\n    use kurbo::{Circle, Shape};\n\n    let circle = Circle::new((400.0, 400.0), 380.0);\n    println!(\"<!DOCTYPE html>\");\n    println!(\"<html>\");\n    println!(\"<body>\");\n    println!(\"<svg height=\\\"800\\\" width=\\\"800\\\">\");\n    let path = circle.to_path(1e-3).to_svg();\n    println!(\"  <path d=\\\"{}\\\" stroke=\\\"black\\\" fill=\\\"none\\\" />\", path);\n    let path = circle.to_path(1.0).to_svg();\n    println!(\"  <path d=\\\"{}\\\" stroke=\\\"red\\\" fill=\\\"none\\\" />\", path);\n    println!(\"</svg>\");\n    println!(\"</body>\");\n    println!(\"</html>\");\n}\n\n#[cfg(not(feature = \"std\"))]\nfn main() {\n    println!(\"This example requires the standard library\");\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "examples/cubic_arclen.rs",
      "sha256": "8ce8010e0f46347db366b666c253db6d3550e64c0993c615029d408d6bfd5462",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Research testbed for arclengths of cubic Bézier segments.\n\n// Lots of stuff is commented out or was just something to try.\n#![allow(unused)]\n#![allow(clippy::unreadable_literal)]\n#![allow(clippy::many_single_char_names)]\n\nuse kurbo::common::*;\nuse kurbo::{\n    CubicBez, ParamCurve, ParamCurveArclen, ParamCurveCurvature, ParamCurveDeriv, Point, Vec2,\n};\n\n/// Calculate arclength using Gauss-Legendre quadrature using formula from Behdad\n/// in https://github.com/Pomax/BezierInfo-2/issues/77\nfn gauss_arclen_5(c: CubicBez) -> f64 {\n    let v0 = (c.p1 - c.p0).hypot() * 0.15;\n    let v1 = (-0.558983582205757 * c.p0.to_vec2()\n        + 0.325650248872424 * c.p1.to_vec2()\n        + 0.208983582205757 * c.p2.to_vec2()\n        + 0.024349751127576 * c.p3.to_vec2())\n    .hypot();\n    let v2 = (c.p3 - c.p0 + (c.p2 - c.p1)).hypot() * 0.26666666666666666;\n    let v3 = (-0.024349751127576 * c.p0.to_vec2()\n        - 0.208983582205757 * c.p1.to_vec2()\n        - 0.325650248872424 * c.p2.to_vec2()\n        + 0.558983582205757 * c.p3.to_vec2())\n    .hypot();\n    let v4 = (c.p3 - c.p2).hypot() * 0.15;\n\n    v0 + v1 + v2 + v3 + v4\n}\n\nfn gauss_arclen_7<C: ParamCurveDeriv>(c: C) -> f64 {\n    c.gauss_arclen(GAUSS_LEGENDRE_COEFFS_7)\n}\n\nfn est_gauss5_error(c: CubicBez) -> f64 {\n    let lc = (c.p3 - c.p0).hypot();\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\n\n    let d2 = c.deriv().deriv();\n    let d3 = d2.deriv();\n    let lmi = 2.0 / (lp + lc);\n    7e-8 * (d3.eval(0.5).to_vec2().hypot() * lmi + 5.0 * d2.eval(0.5).to_vec2().hypot() * lmi)\n        .powi(5)\n        * lp\n}\n\nfn gauss_errnorm_n<C: ParamCurveDeriv>(c: C, coeffs: &[(f64, f64)]) -> f64\nwhere\n    C::DerivResult: ParamCurveDeriv,\n{\n    let d = c.deriv().deriv();\n    coeffs\n        .iter()\n        .map(|(wi, xi)| wi * d.eval(0.5 * (xi + 1.0)).to_vec2().hypot2())\n        .sum::<f64>()\n}\n\n// Squared L2 norm of the second derivative of the cubic.\nfn cubic_errnorm(c: CubicBez) -> f64 {\n    let d = c.deriv().deriv();\n    let dd = d.end() - d.start();\n    d.start().to_vec2().hypot2() + d.start().to_vec2().dot(dd) + dd.hypot2() * (1.0 / 3.0)\n}\n\nfn est_gauss7_error(c: CubicBez) -> f64 {\n    let lc = (c.p3 - c.p0).hypot();\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\n\n    8e-9 * (2.0 * cubic_errnorm(c) / lc.powi(2)).powi(6) * lp\n}\n\nfn gauss_arclen_9<C: ParamCurveDeriv>(c: C) -> f64 {\n    c.gauss_arclen(GAUSS_LEGENDRE_COEFFS_9)\n}\n\nfn gauss_arclen_11<C: ParamCurveDeriv>(c: C) -> f64 {\n    c.gauss_arclen(GAUSS_LEGENDRE_COEFFS_11)\n}\n\nfn est_gauss9_error(c: CubicBez) -> f64 {\n    let lc = (c.p3 - c.p0).hypot();\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\n\n    1e-10 * (2.0 * cubic_errnorm(c) / lc.powi(2)).powi(8) * lp\n}\n\nfn est_gauss11_error(c: CubicBez) -> f64 {\n    let lc = (c.p3 - c.p0).hypot();\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\n\n    1e-12 * (2.0 * cubic_errnorm(c) / lc.powi(2)).powi(11) * lp\n}\n\n// A new approach based on integrating local error.\nfn est_gauss11_error_2(c: CubicBez) -> f64 {\n    let d = c.deriv();\n    let d2 = d.deriv();\n    GAUSS_LEGENDRE_COEFFS_11\n        .iter()\n        .map(|(wi, xi)| {\n            wi * {\n                let t = 0.5 * (xi + 1.0);\n                let v = d.eval(t).to_vec2().hypot();\n                let a2 = d2.eval(t).to_vec2().hypot2();\n                a2.powi(3) / v.powi(5)\n            }\n        })\n        .sum::<f64>()\n}\n\n#[allow(clippy::neg_cmp_op_on_partial_ord)]\nfn est_max_curvature(c: CubicBez) -> f64 {\n    let n = 100;\n    let mut max = 0.0;\n    for i in 0..=n {\n        let t = (i as f64) * (n as f64).recip();\n        let k = c.curvature(t).abs();\n        if !(k < max) {\n            max = k;\n        }\n    }\n    max\n}\n\nfn est_min_deriv_norm2(c: CubicBez) -> f64 {\n    let d = c.deriv();\n    let n = 100;\n    let mut min = d.eval(1.0).to_vec2().hypot2();\n    for i in 0..n {\n        let t = (i as f64) * (n as f64).recip();\n        min = min.min(d.eval(t).to_vec2().hypot2())\n    }\n    min\n}\n\nfn est_gauss11_error_3(c: CubicBez) -> f64 {\n    let lc = (c.p3 - c.p0).hypot();\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\n    let pc_err = (lp - lc) * 0.02;\n    let ks = est_max_curvature(c) * lp;\n    let est = ks.powi(3) * lp * 8e-9;\n    if est < pc_err {\n        est\n    } else {\n        pc_err\n    }\n}\n\nfn est_gauss9_error_3(c: CubicBez) -> f64 {\n    let lc = (c.p3 - c.p0).hypot();\n    let lp = (c.p1 - c.p0).hypot() + (c.p2 - c.p1).hypot() + (c.p3 - c.p2).hypot();\n    let pc_err = (lp - lc) * 0.02;\n    let ks = est_max_curvature(c) * lp;\n    let est = ks.powi(3) * lp * 5e-8;\n    if est < pc_err {\n        est\n    } else {\n        pc_err\n    }\n}\n\n// A new approach based on integrating local error; the cost of evaluating the\n// error metric is likely to dominate unless the accuracy buys a lot of subdivisions.\nfn est_gauss9_error_2(c: CubicBez) -> f64 {\n    let d = c.deriv();\n    let d2 = d.deriv();\n    let p = 10;\n    GAUSS_LEGENDRE_COEFFS_9\n        .iter()\n        .map(|(wi, xi)| {\n            wi * {\n                let t = 0.5 * (xi + 1.0);\n                let v = d.eval(t).to_vec2().hypot();\n                let a = d2.eval(t).to_vec2().hypot();\n                (1.0e-1 * a / v).tanh().powi(p) * v\n            }\n        })\n        .sum::<f64>()\n        * 3.0\n}\n\nfn my_arclen(c: CubicBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\n    if depth == 16 || est_gauss5_error(c) < accuracy {\n        *count += 1;\n        gauss_arclen_5(c)\n    } else {\n        let (c0, c1) = c.subdivide();\n        my_arclen(c0, accuracy * 0.5, depth + 1, count)\n            + my_arclen(c1, accuracy * 0.5, depth + 1, count)\n    }\n}\n\nfn my_arclen7(c: CubicBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\n    if depth == 16 || est_gauss7_error(c) < accuracy {\n        *count += 1;\n        gauss_arclen_7(c)\n    } else {\n        let (c0, c1) = c.subdivide();\n        my_arclen7(c0, accuracy * 0.5, depth + 1, count)\n            + my_arclen7(c1, accuracy * 0.5, depth + 1, count)\n    }\n}\n\n// Should make this generic instead of copy+paste, but we need only one when we're done.\nfn my_arclen9(c: CubicBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\n    if depth == 16 || est_gauss9_error(c) < accuracy {\n        *count += 1;\n        gauss_arclen_9(c)\n    } else {\n        let (c0, c1) = c.subdivide();\n        my_arclen9(c0, accuracy * 0.5, depth + 1, count)\n            + my_arclen9(c1, accuracy * 0.5, depth + 1, count)\n    }\n}\n\n// This doesn't help; we can't really get a more accurate error bound, so all this\n// does is overkill the accuracy.\nfn my_arclen11(c: CubicBez, accuracy: f64, depth: usize, count: &mut usize) -> f64 {\n    if depth == 16 || est_gauss9_error(c) < accuracy {\n        *count += 1;\n        gauss_arclen_11(c)\n    } else {\n        let (c0, c1) = c.subdivide();\n        my_arclen11(c0, accuracy * 0.5, depth + 1, count)\n            + my_arclen11(c1, accuracy * 0.5, depth + 1, count)\n    }\n}\n\nfn randpt() -> Point {\n    Point::new(rand::random(), rand::random())\n}\n\nfn randbez() -> CubicBez {\n    CubicBez::new(randpt(), randpt(), randpt(), randpt())\n}\n\nfn main() {\n    let accuracy = 1e-4;\n    for _ in 0..10_000 {\n        let c = randbez();\n        let t: f64 = rand::random();\n        let c = c.subsegment(0.0..t);\n        //let accurate_arclen = c.arclen(1e-12);\n        let mut count = 0;\n        let accurate_arclen = my_arclen9(c, 1e-15, 0, &mut count);\n\n        let est = gauss_arclen_9(c);\n        let est_err = est_gauss9_error_3(c);\n        let err = (accurate_arclen - est).abs();\n        println!(\"{est_err} {err}\");\n\n        /*\n        let mut count = 0;\n        let est = my_arclen9(c, accuracy, 0, &mut count);\n        let err = (accurate_arclen - est).abs();\n        println!(\"{err} {count}\");\n        */\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "examples/ellipse.rs",
      "sha256": "d737bac238376779127fd7adb889a8a96a4423fed6f24c5bec7f66707c14a7b7",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Example of ellipse\n\n#[cfg(feature = \"std\")]\nfn main() {\n    use kurbo::{Ellipse, Shape};\n    use std::f64::consts::PI;\n\n    let ellipse = Ellipse::new((400.0, 400.0), (200.0, 100.0), 0.25 * PI);\n    println!(\"<!DOCTYPE html>\");\n    println!(\"<html>\");\n    println!(\"<body>\");\n    println!(\"<svg height=\\\"800\\\" width=\\\"800\\\" style=\\\"background-color: #999\\\">\");\n    let path = ellipse.to_path(1e-3).to_svg();\n    println!(\"  <path d=\\\"{}\\\" stroke=\\\"black\\\" fill=\\\"none\\\" />\", path);\n    let path = ellipse.to_path(1.0).to_svg();\n    println!(\"  <path d=\\\"{}\\\" stroke=\\\"red\\\" fill=\\\"none\\\" />\", path);\n    println!(\"</svg>\");\n    println!(\"</body>\");\n    println!(\"</html>\");\n}\n\n#[cfg(not(feature = \"std\"))]\nfn main() {\n    println!(\"This example requires the standard library\");\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "examples/fit_poly.rs",
      "sha256": "9a313d3b6cc01b38cb9a8e00943a7b81debd7ecbe456527b0c74e1e747c58cea",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A test case for the cubic Bézier path simplifier, generating a very\n//! efficient and accurate SVG file to plot a quartic polynomial. This\n//! file was used to generate the image for the Wikipedia article on\n//! quartic polynomials.\n\nuse std::{io::Write, ops::Range};\n\nuse kurbo::{BezPath, CurveFitSample, ParamCurveFit, PathEl, Point, Vec2};\n\nstruct MyPoly;\n\nfn eval_mypoly(x: f64) -> f64 {\n    (x + 4.) * (x + 1.) * (x - 1.) * (x - 3.) / 14. + 0.5\n}\n\nfn eval_mypoly_deriv(x: f64) -> f64 {\n    (((4. * x + 3.) * x - 26.) * x - 1.) / 14.\n}\n\nimpl ParamCurveFit for MyPoly {\n    fn sample_pt_deriv(&self, t: f64) -> (Point, Vec2) {\n        const S: f64 = 336.;\n        let x = 37. + t * S;\n        let math_x = (x - 220.) / 40.;\n        let y = -eval_mypoly(math_x) * 40. + 260.;\n        let dx = S;\n        let dy = -dx * eval_mypoly_deriv(math_x);\n        (Point::new(x, y), Vec2::new(dx, dy))\n    }\n\n    fn sample_pt_tangent(&self, t: f64, _: f64) -> CurveFitSample {\n        let (p, tangent) = self.sample_pt_deriv(t);\n        CurveFitSample { p, tangent }\n    }\n\n    fn break_cusp(&self, _: Range<f64>) -> Option<f64> {\n        None\n    }\n}\n\npub fn to_svg_economical(path: &BezPath) -> String {\n    let mut buffer = Vec::new();\n    write_to(path, &mut buffer).unwrap();\n    String::from_utf8(buffer).unwrap()\n}\n\n/// Write the SVG representation of this path to the provided buffer.\npub fn write_to<W: Write>(path: &BezPath, mut writer: W) -> std::io::Result<()> {\n    for el in path.elements() {\n        match *el {\n            PathEl::MoveTo(p) => write!(writer, \"M{:.2} {:.2}\", p.x, p.y)?,\n            PathEl::LineTo(p) => write!(writer, \"L{} {}\", p.x, p.y)?,\n            PathEl::QuadTo(p1, p2) => write!(writer, \"Q{} {} {} {}\", p1.x, p1.y, p2.x, p2.y)?,\n            PathEl::CurveTo(p1, p2, p3) => write!(\n                writer,\n                \"C{:.2} {:.2} {:.2} {:.2} {:.2} {:.2}\",\n                p1.x, p1.y, p2.x, p2.y, p3.x, p3.y\n            )?,\n            PathEl::ClosePath => write!(writer, \"Z\")?,\n        }\n    }\n    Ok(())\n}\n\nfn main() {\n    println!(\"<svg width='800' height='600' xmlns='http://www.w3.org/2000/svg'>\");\n    let path = kurbo::fit_to_bezpath_opt(&MyPoly, 0.1);\n    println!(\n        \"  <path d='{}' stroke='#008' fill='none' stroke-width='2.0'/>\",\n        to_svg_economical(&path)\n    );\n    println!(\"</svg>\");\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "examples/moment.rs",
      "sha256": "f4da88da1cbc91d85e58b28aad0aadc0c036510ca8e37671154f33fbd179dc3a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Test case for checking whether numeric and analytic computations of\n//! moments for cubic Béziers match each other.\n\nuse kurbo::{common::GAUSS_LEGENDRE_COEFFS_16, CubicBez, ParamCurve, ParamCurveDeriv};\n\nfn main() {\n    let c = CubicBez::new(\n        (0.0, 547.3395616558455),\n        (266.66666666666663, 741.3396067339968),\n        (533.3333333333334, -141.33960673399685),\n        (800.0, 52.66043834415456),\n    );\n    let q = c.deriv();\n    let numeric = GAUSS_LEGENDRE_COEFFS_16\n        .iter()\n        .map(|(wi, xi)| {\n            let t = 0.5 + xi * 0.5;\n            let p = c.eval(t);\n            let d = q.eval(t);\n            let a = (0.5 * wi) * d.x * p.y;\n            p.y * a\n        })\n        .sum::<f64>();\n    println!(\"{:?} {}\", kurbo::simplify::moment_integrals(c), numeric);\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "examples/offset.rs",
      "sha256": "8f15459091f2223ad5ff647fdca7ba168cbf013030f05f629a7ffb69ba8b15ef",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A simple example to show an offset curve of a cubic Bézier segment.\n\nuse kurbo::{offset::CubicOffset, CubicBez, Shape};\n\nfn main() {\n    println!(\"<svg width='800' height='600' xmlns='http://www.w3.org/2000/svg'>\");\n    let c = CubicBez::new((100., 100.), (150., 75.), (300., 50.), (400., 200.));\n    println!(\n        \"  <path d='{}' stroke='#000' fill='none' />\",\n        c.to_path(1e-9).to_svg()\n    );\n    for i in 1..=80 {\n        let co = CubicOffset::new(c, i as f64 * 4.0);\n        let path = kurbo::fit_to_bezpath_opt(&co, 1e-3);\n        println!(\n            \"  <path d='{}' stroke='#008' fill='none' stroke-width='0.2'/>\",\n            path.to_svg()\n        );\n    }\n    println!(\"</svg>\");\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "examples/quad_intersect.rs",
      "sha256": "03def9282c4d50afa4e5d7d19b341ff8970459083bf0dc16c53ad44bdf2f4594",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Test case that demonstrates quadratic/quadratic intersection using\n//! new quartic solver.\n\nuse arrayvec::ArrayVec;\nuse kurbo::{common::solve_quartic, ParamCurve, Point, QuadBez, Shape};\nuse rand::{thread_rng, Rng};\n\nfn rand_point() -> Point {\n    let mut rng = thread_rng();\n    Point::new(rng.gen_range(0.0..500.0), rng.gen_range(0.0..500.0))\n}\n\nfn rand_quad() -> QuadBez {\n    QuadBez::new(rand_point(), rand_point(), rand_point())\n}\n\nstruct ImplicitQuad {\n    x2: f64,\n    xy: f64,\n    y2: f64,\n    x: f64,\n    y: f64,\n    c: f64,\n}\n\nimpl ImplicitQuad {\n    fn from_quad(q: QuadBez) -> Self {\n        let Point { x: ax, y: ay } = q.p0;\n        let Point { x: bx, y: by } = q.p1;\n        let Point { x: cx, y: cy } = q.p2;\n        let (u0, u1, u2) = (by - cy, cx - bx, bx * cy - by * cx);\n        let (v0, v1, v2) = (cy - ay, ax - cx, cx * ay - cy * ax);\n        let (w0, w1, w2) = (ay - by, bx - ax, ax * by - ay * bx);\n        ImplicitQuad {\n            x2: 4. * u0 * w0 - v0 * v0,\n            xy: 4. * (u0 * w1 + u1 * w0) - 2. * v0 * v1,\n            y2: 4. * u1 * w1 - v1 * v1,\n            x: 4. * (u0 * w2 + u2 * w0) - 2. * v0 * v2,\n            y: 4. * (u1 * w2 + u2 * w1) - 2. * v1 * v2,\n            c: 4. * u2 * w2 - v2 * v2,\n        }\n    }\n\n    fn eval(&self, x: f64, y: f64) -> f64 {\n        self.x2 * x * x + self.xy * x * y + self.y2 * y * y + self.x * x + self.y * y + self.c\n    }\n}\n\nfn intersect_quads(q0: QuadBez, q1: QuadBez) -> ArrayVec<f64, 4> {\n    let iq = ImplicitQuad::from_quad(q0);\n    let c = q1.p0.to_vec2();\n    let b = (q1.p1 - q1.p0) * 2.0;\n    let a = c - q1.p1.to_vec2() * 2.0 + q1.p2.to_vec2();\n    let c0 = iq.eval(c.x, c.y);\n    let c1 = iq.x * b.x\n        + iq.y * b.y\n        + 2. * iq.x2 * (b.x * c.x)\n        + 2. * iq.y2 * (b.y * c.y)\n        + iq.xy * (b.x * c.y + b.y * c.x);\n    let c2 = iq.x * a.x\n        + iq.y * a.y\n        + iq.x2 * (2. * a.x * c.x + b.x * b.x)\n        + iq.xy * (a.x * c.y + b.x * b.y + a.y * c.x)\n        + iq.y2 * (2. * a.y * c.y + b.y * b.y);\n    let c3 = iq.x2 * 2. * a.x * b.x + iq.xy * (a.x * b.y + b.x * a.y) + iq.y2 * 2. * a.y * b.y;\n    let c4 = iq.x2 * a.x * a.x + iq.xy * a.x * a.y + iq.y2 * a.y * a.y;\n    let ts = solve_quartic(c0, c1, c2, c3, c4);\n    println!(\"ts: {:?}\", ts);\n    ts\n}\n\nfn main() {\n    let q0 = rand_quad();\n    let q1 = rand_quad();\n    println!(\n        \"  <path d='{}' stroke='#000' fill='none' />\",\n        q0.to_path(1e-9).to_svg()\n    );\n    println!(\n        \"  <path d='{}' stroke='#008' fill='none' />\",\n        q1.to_path(1e-9).to_svg()\n    );\n    for t in intersect_quads(q0, q1) {\n        if (0.0..=1.0).contains(&t) {\n            let p = q1.eval(t);\n            println!(\"  <circle cx='{}' cy='{}' r='3' />\", p.x, p.y);\n        }\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "examples/simplify.rs",
      "sha256": "7bd3fdcfd60fe9094b9f5da51be4a70061f3df760a62a0ae62e7e8c77f649558",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Test case showing simplification of a Bézier path. In this case, the\n//! source path is a simple mathematical function, but it should work for\n//! more general cases as well.\n\nuse kurbo::{BezPath, Point};\n\nfn plot_fn(f: &dyn Fn(f64) -> f64, d: &dyn Fn(f64) -> f64, xa: f64, xb: f64, n: usize) -> BezPath {\n    let width = 800.;\n    let dx = (xb - xa) / n as f64;\n    let xs = width / (xb - xa);\n    let ys = 250.;\n    let y_origin = 300.;\n    let plot = |x, y| Point::new((x - xa) * xs, y_origin - y * ys);\n    let mut x0 = xa;\n    let mut y0 = f(xa);\n    let mut d0 = d(xa);\n    let mut path = BezPath::new();\n    path.move_to(plot(x0, y0));\n    for i in 0..n {\n        let x3 = xa + dx * (i + 1) as f64;\n        let y3 = f(x3);\n        let d3 = d(x3);\n        let x1 = x0 + (1. / 3.) * dx;\n        let x2 = x3 - (1. / 3.) * dx;\n        let y1 = y0 + d0 * (1. / 3.) * dx;\n        let y2 = y3 - d3 * (1. / 3.) * dx;\n        path.curve_to(plot(x1, y1), plot(x2, y2), plot(x3, y3));\n        x0 = x3;\n        y0 = y3;\n        d0 = d3;\n    }\n    path\n}\n\nfn main() {\n    println!(\"<svg width='800' height='600' xmlns='http://www.w3.org/2000/svg'>\");\n    let path = plot_fn(&|x| x.sin(), &|x| x.cos(), -8., 8., 20);\n    println!(\n        \"  <path d='{}' stroke='#8c8' fill='none' stroke-width='5'/>\",\n        path.to_svg()\n    );\n    let simpl = kurbo::simplify::SimplifyBezPath::new(path);\n    let simplified_path = kurbo::fit_to_bezpath_opt(&simpl, 0.1);\n    println!(\n        \"  <path d='{}' stroke='#000' fill='none' stroke-width='1'/>\",\n        simplified_path.to_svg()\n    );\n    println!(\"</svg>\");\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "examples_save/stroke.rs",
      "sha256": "d1afc41f85c92bbfe2bed70c18dbc47ed8d4d961c8e2b9a5730165897fbdc48d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2023 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse kurbo::{stroke, BezPath, Cap, Join, Shape, Stroke};\n\nfn main() {\n    let d = \"M100 100 Q150 150 190 110L 50 50\";\n    let p = BezPath::from_svg(d).unwrap();\n    let style = Stroke::new(5.0)\n        .with_caps(Cap::Butt)\n        .with_join(Join::Round)\n        .with_dashes(15.0, &[10.0, 1.0, 2.0]);\n    let s = stroke(p, &style, 1e-1);\n    println!(\"{}\", s.to_svg());\n    println!(\"area = {}\", s.area())\n    /*\n    let mut dashed = BezPath::new();\n    for el in kurbo::DashIterator::new(p.elements().iter().cloned(), &[10.0]) {\n        println!(\"{el:?}\");\n        dashed.push(el);\n    }\n    let s = stroke(dashed, &style, 1e-1);\n    println!(\"{}\", s.to_svg());\n    */\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/affine.rs",
      "sha256": "3c50c0e2a5987ed9ccd27761f9d0d36ab98819286dd1659e10253f4b5aa1715c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Affine transforms.\n\nuse core::ops::{Mul, MulAssign};\n\nuse crate::{Point, Rect, Vec2};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A 2D affine transform.\n#[derive(Clone, Copy, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Affine([f64; 6]);\n\nimpl Affine {\n    /// The identity transform.\n    pub const IDENTITY: Affine = Affine::scale(1.0);\n\n    /// A transform that is flipped on the y-axis. Useful for converting between\n    /// y-up and y-down spaces.\n    pub const FLIP_Y: Affine = Affine::new([1.0, 0., 0., -1.0, 0., 0.]);\n\n    /// A transform that is flipped on the x-axis.\n    pub const FLIP_X: Affine = Affine::new([-1.0, 0., 0., 1.0, 0., 0.]);\n\n    /// Construct an affine transform from coefficients.\n    ///\n    /// If the coefficients are `(a, b, c, d, e, f)`, then the resulting\n    /// transformation represents this augmented matrix:\n    ///\n    /// ```text\n    /// | a c e |\n    /// | b d f |\n    /// | 0 0 1 |\n    /// ```\n    ///\n    /// Note that this convention is transposed from PostScript and\n    /// Direct2D, but is consistent with the\n    /// [Wikipedia](https://en.wikipedia.org/wiki/Affine_transformation)\n    /// formulation of affine transformation as augmented matrix. The\n    /// idea is that `(A * B) * v == A * (B * v)`, where `*` is the\n    /// [`Mul`](std::ops::Mul) trait.\n    #[inline]\n    pub const fn new(c: [f64; 6]) -> Affine {\n        Affine(c)\n    }\n\n    /// An affine transform representing uniform scaling.\n    #[inline]\n    pub const fn scale(s: f64) -> Affine {\n        Affine([s, 0.0, 0.0, s, 0.0, 0.0])\n    }\n\n    /// An affine transform representing non-uniform scaling\n    /// with different scale values for x and y\n    #[inline]\n    pub const fn scale_non_uniform(s_x: f64, s_y: f64) -> Affine {\n        Affine([s_x, 0.0, 0.0, s_y, 0.0, 0.0])\n    }\n\n    /// An affine transform representing rotation.\n    ///\n    /// The convention for rotation is that a positive angle rotates a\n    /// positive X direction into positive Y. Thus, in a Y-down coordinate\n    /// system (as is common for graphics), it is a clockwise rotation, and\n    /// in Y-up (traditional for math), it is anti-clockwise.\n    ///\n    /// The angle, `th`, is expressed in radians.\n    #[inline]\n    pub fn rotate(th: f64) -> Affine {\n        let (s, c) = th.sin_cos();\n        Affine([c, s, -s, c, 0.0, 0.0])\n    }\n\n    /// An affine transform representing a rotation of `th` radians about `center`.\n    ///\n    /// See [`Affine::rotate()`] for more info.\n    #[inline]\n    pub fn rotate_about(th: f64, center: Point) -> Affine {\n        let center = center.to_vec2();\n        Self::translate(-center)\n            .then_rotate(th)\n            .then_translate(center)\n    }\n\n    /// An affine transform representing translation.\n    #[inline]\n    pub fn translate<V: Into<Vec2>>(p: V) -> Affine {\n        let p = p.into();\n        Affine([1.0, 0.0, 0.0, 1.0, p.x, p.y])\n    }\n\n    /// An affine transformation representing a skew.\n    ///\n    /// The `skew_x` and `skew_y` parameters represent skew factors for the\n    /// horizontal and vertical directions, respectively.\n    ///\n    /// This is commonly used to generate a faux oblique transform for\n    /// font rendering. In this case, you can slant the glyph 20 degrees\n    /// clockwise in the horizontal direction (assuming a Y-up coordinate\n    /// system):\n    ///\n    /// ```\n    /// let oblique_transform = kurbo::Affine::skew(20f64.to_radians().tan(), 0.0);\n    /// ```\n    #[inline]\n    pub fn skew(skew_x: f64, skew_y: f64) -> Affine {\n        Affine([1.0, skew_y, skew_x, 1.0, 0.0, 0.0])\n    }\n\n    /// Create an affine transform that represents reflection about the line `point + direction * t, t in (-infty, infty)`\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use kurbo::{Point, Vec2, Affine};\n    /// # fn assert_near(p0: Point, p1: Point) {\n    /// #     assert!((p1 - p0).hypot() < 1e-9, \"{p0:?} != {p1:?}\");\n    /// # }\n    /// let point = Point::new(1., 0.);\n    /// let vec = Vec2::new(1., 1.);\n    /// let map = Affine::reflect(point, vec);\n    /// assert_near(map * Point::new(1., 0.), Point::new(1., 0.));\n    /// assert_near(map * Point::new(2., 1.), Point::new(2., 1.));\n    /// assert_near(map * Point::new(2., 2.), Point::new(3., 1.));\n    /// ```\n    #[inline]\n    #[must_use]\n    pub fn reflect(point: impl Into<Point>, direction: impl Into<Vec2>) -> Self {\n        let point = point.into();\n        let direction = direction.into();\n\n        let n = Vec2 {\n            x: direction.y,\n            y: -direction.x,\n        }\n        .normalize();\n\n        // Compute Householder reflection matrix\n        let x2 = n.x * n.x;\n        let xy = n.x * n.y;\n        let y2 = n.y * n.y;\n        // Here we also add in the post translation, because it doesn't require any further calc.\n        let aff = Affine::new([\n            1. - 2. * x2,\n            -2. * xy,\n            -2. * xy,\n            1. - 2. * y2,\n            point.x,\n            point.y,\n        ]);\n        aff.pre_translate(-point.to_vec2())\n    }\n\n    /// A rotation by `th` followed by `self`.\n    ///\n    /// Equivalent to `self * Affine::rotate(th)`\n    #[inline]\n    #[must_use]\n    pub fn pre_rotate(self, th: f64) -> Self {\n        self * Affine::rotate(th)\n    }\n\n    /// A rotation by `th` about `center` followed by `self`.\n    ///\n    /// Equivalent to `self * Affine::rotate_about(th)`\n    #[inline]\n    #[must_use]\n    pub fn pre_rotate_about(self, th: f64, center: Point) -> Self {\n        Affine::rotate_about(th, center) * self\n    }\n\n    /// A scale by `scale` followed by `self`.\n    ///\n    /// Equivalent to `self * Affine::scale(scale)`\n    #[inline]\n    #[must_use]\n    pub fn pre_scale(self, scale: f64) -> Self {\n        self * Affine::scale(scale)\n    }\n\n    /// A scale by `(scale_x, scale_y)` followed by `self`.\n    ///\n    /// Equivalent to `self * Affine::scale_non_uniform(scale_x, scale_y)`\n    #[inline]\n    #[must_use]\n    pub fn pre_scale_non_uniform(self, scale_x: f64, scale_y: f64) -> Self {\n        self * Affine::scale_non_uniform(scale_x, scale_y)\n    }\n\n    /// A translation of `trans` followed by `self`.\n    ///\n    /// Equivalent to `self * Affine::translate(trans)`\n    #[inline]\n    #[must_use]\n    pub fn pre_translate(self, trans: Vec2) -> Self {\n        self * Affine::translate(trans)\n    }\n\n    /// `self` followed by a rotation of `th`.\n    ///\n    /// Equivalent to `Affine::rotate(th) * self`\n    #[inline]\n    #[must_use]\n    pub fn then_rotate(self, th: f64) -> Self {\n        Affine::rotate(th) * self\n    }\n\n    /// `self` followed by a rotation of `th` about `center`.\n    ///\n    /// Equivalent to `Affine::rotate_about(th, center) * self`\n    #[inline]\n    #[must_use]\n    pub fn then_rotate_about(self, th: f64, center: Point) -> Self {\n        Affine::rotate_about(th, center) * self\n    }\n\n    /// `self` followed by a scale of `scale`.\n    ///\n    /// Equivalent to `Affine::scale(scale) * self`\n    #[inline]\n    #[must_use]\n    pub fn then_scale(self, scale: f64) -> Self {\n        Affine::scale(scale) * self\n    }\n\n    /// `self` followed by a scale of `(scale_x, scale_y)`.\n    ///\n    /// Equivalent to `Affine::scale_non_uniform(scale_x, scale_y) * self`\n    #[inline]\n    #[must_use]\n    pub fn then_scale_non_uniform(self, scale_x: f64, scale_y: f64) -> Self {\n        Affine::scale_non_uniform(scale_x, scale_y) * self\n    }\n\n    /// `self` followed by a translation of `trans`.\n    ///\n    /// Equivalent to `Affine::translate(trans) * self`\n    #[inline]\n    #[must_use]\n    pub fn then_translate(mut self, trans: Vec2) -> Self {\n        self.0[4] += trans.x;\n        self.0[5] += trans.y;\n        self\n    }\n\n    /// Creates an affine transformation that takes the unit square to the given rectangle.\n    ///\n    /// Useful when you want to draw into the unit square but have your output fill any rectangle.\n    /// In this case push the `Affine` onto the transform stack.\n    pub fn map_unit_square(rect: Rect) -> Affine {\n        Affine([rect.width(), 0., 0., rect.height(), rect.x0, rect.y0])\n    }\n\n    /// Get the coefficients of the transform.\n    #[inline]\n    pub fn as_coeffs(self) -> [f64; 6] {\n        self.0\n    }\n\n    /// Compute the determinant of this transform.\n    pub fn determinant(self) -> f64 {\n        self.0[0] * self.0[3] - self.0[1] * self.0[2]\n    }\n\n    /// Compute the inverse transform.\n    ///\n    /// Produces NaN values when the determinant is zero.\n    pub fn inverse(self) -> Affine {\n        let inv_det = self.determinant().recip();\n        Affine([\n            inv_det * self.0[3],\n            -inv_det * self.0[1],\n            -inv_det * self.0[2],\n            inv_det * self.0[0],\n            inv_det * (self.0[2] * self.0[5] - self.0[3] * self.0[4]),\n            inv_det * (self.0[1] * self.0[4] - self.0[0] * self.0[5]),\n        ])\n    }\n\n    /// Compute the bounding box of a transformed rectangle.\n    ///\n    /// Returns the minimal `Rect` that encloses the given `Rect` after affine transformation.\n    /// If the transform is axis-aligned, then this bounding box is \"tight\", in other words the\n    /// returned `Rect` is the transformed rectangle.\n    ///\n    /// The returned rectangle always has non-negative width and height.\n    pub fn transform_rect_bbox(self, rect: Rect) -> Rect {\n        let p00 = self * Point::new(rect.x0, rect.y0);\n        let p01 = self * Point::new(rect.x0, rect.y1);\n        let p10 = self * Point::new(rect.x1, rect.y0);\n        let p11 = self * Point::new(rect.x1, rect.y1);\n        Rect::from_points(p00, p01).union(Rect::from_points(p10, p11))\n    }\n\n    /// Is this map finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.0[0].is_finite()\n            && self.0[1].is_finite()\n            && self.0[2].is_finite()\n            && self.0[3].is_finite()\n            && self.0[4].is_finite()\n            && self.0[5].is_finite()\n    }\n\n    /// Is this map NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.0[0].is_nan()\n            || self.0[1].is_nan()\n            || self.0[2].is_nan()\n            || self.0[3].is_nan()\n            || self.0[4].is_nan()\n            || self.0[5].is_nan()\n    }\n\n    /// Compute the singular value decomposition of the linear transformation (ignoring the\n    /// translation).\n    ///\n    /// All non-degenerate linear transformations can be represented as\n    ///\n    ///  1. a rotation about the origin.\n    ///  2. a scaling along the x and y axes\n    ///  3. another rotation about the origin\n    ///\n    /// composed together. Decomposing a 2x2 matrix in this way is called a \"singular value\n    /// decomposition\" and is written `U Σ V^T`, where U and V^T are orthogonal (rotations) and Σ\n    /// is a diagonal matrix (a scaling).\n    ///\n    /// Since currently this function is used to calculate ellipse radii and rotation from an\n    /// affine map on the unit circle, we don't calculate V^T, since a rotation of the unit (or\n    /// any) circle about its center always results in the same circle. This is the reason that an\n    /// ellipse mapped using an affine map is always an ellipse.\n    ///\n    /// Will return NaNs if the matrix (or equivalently the linear map) is singular.\n    ///\n    /// First part of the return tuple is the scaling, second part is the angle of rotation (in\n    /// radians)\n    #[inline]\n    pub(crate) fn svd(self) -> (Vec2, f64) {\n        let a = self.0[0];\n        let a2 = a * a;\n        let b = self.0[1];\n        let b2 = b * b;\n        let c = self.0[2];\n        let c2 = c * c;\n        let d = self.0[3];\n        let d2 = d * d;\n        let ab = a * b;\n        let cd = c * d;\n        let angle = 0.5 * (2.0 * (ab + cd)).atan2(a2 - b2 + c2 - d2);\n        let s1 = a2 + b2 + c2 + d2;\n        let s2 = ((a2 - b2 + c2 - d2).powi(2) + 4.0 * (ab + cd).powi(2)).sqrt();\n        (\n            Vec2 {\n                x: (0.5 * (s1 + s2)).sqrt(),\n                y: (0.5 * (s1 - s2)).sqrt(),\n            },\n            angle,\n        )\n    }\n\n    /// Returns the translation part of this affine map (`(self.0[4], self.0[5])`).\n    #[inline]\n    pub fn translation(self) -> Vec2 {\n        Vec2 {\n            x: self.0[4],\n            y: self.0[5],\n        }\n    }\n\n    /// Replaces the translation portion of this affine map\n    ///\n    /// The translation can be seen as being applied after the linear part of the map.\n    #[must_use]\n    #[inline]\n    pub fn with_translation(mut self, trans: Vec2) -> Affine {\n        self.0[4] = trans.x;\n        self.0[5] = trans.y;\n        self\n    }\n}\n\nimpl Default for Affine {\n    #[inline]\n    fn default() -> Affine {\n        Affine::IDENTITY\n    }\n}\n\nimpl Mul<Point> for Affine {\n    type Output = Point;\n\n    #[inline]\n    fn mul(self, other: Point) -> Point {\n        Point::new(\n            self.0[0] * other.x + self.0[2] * other.y + self.0[4],\n            self.0[1] * other.x + self.0[3] * other.y + self.0[5],\n        )\n    }\n}\n\nimpl Mul for Affine {\n    type Output = Affine;\n\n    #[inline]\n    fn mul(self, other: Affine) -> Affine {\n        Affine([\n            self.0[0] * other.0[0] + self.0[2] * other.0[1],\n            self.0[1] * other.0[0] + self.0[3] * other.0[1],\n            self.0[0] * other.0[2] + self.0[2] * other.0[3],\n            self.0[1] * other.0[2] + self.0[3] * other.0[3],\n            self.0[0] * other.0[4] + self.0[2] * other.0[5] + self.0[4],\n            self.0[1] * other.0[4] + self.0[3] * other.0[5] + self.0[5],\n        ])\n    }\n}\n\nimpl MulAssign for Affine {\n    #[inline]\n    fn mul_assign(&mut self, other: Affine) {\n        *self = self.mul(other);\n    }\n}\n\nimpl Mul<Affine> for f64 {\n    type Output = Affine;\n\n    #[inline]\n    fn mul(self, other: Affine) -> Affine {\n        Affine([\n            self * other.0[0],\n            self * other.0[1],\n            self * other.0[2],\n            self * other.0[3],\n            self * other.0[4],\n            self * other.0[5],\n        ])\n    }\n}\n\n// Conversions to and from mint\n#[cfg(feature = \"mint\")]\nimpl From<Affine> for mint::ColumnMatrix2x3<f64> {\n    #[inline]\n    fn from(a: Affine) -> mint::ColumnMatrix2x3<f64> {\n        mint::ColumnMatrix2x3 {\n            x: mint::Vector2 {\n                x: a.0[0],\n                y: a.0[1],\n            },\n            y: mint::Vector2 {\n                x: a.0[2],\n                y: a.0[3],\n            },\n            z: mint::Vector2 {\n                x: a.0[4],\n                y: a.0[5],\n            },\n        }\n    }\n}\n\n#[cfg(feature = \"mint\")]\nimpl From<mint::ColumnMatrix2x3<f64>> for Affine {\n    #[inline]\n    fn from(m: mint::ColumnMatrix2x3<f64>) -> Affine {\n        Affine([m.x.x, m.x.y, m.y.x, m.y.y, m.z.x, m.z.y])\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Affine, Point, Vec2};\n    use std::f64::consts::PI;\n\n    fn assert_near(p0: Point, p1: Point) {\n        assert!((p1 - p0).hypot() < 1e-9, \"{p0:?} != {p1:?}\");\n    }\n\n    fn affine_assert_near(a0: Affine, a1: Affine) {\n        for i in 0..6 {\n            assert!((a0.0[i] - a1.0[i]).abs() < 1e-9, \"{a0:?} != {a1:?}\");\n        }\n    }\n\n    #[test]\n    fn affine_basic() {\n        let p = Point::new(3.0, 4.0);\n\n        assert_near(Affine::default() * p, p);\n        assert_near(Affine::scale(2.0) * p, Point::new(6.0, 8.0));\n        assert_near(Affine::rotate(0.0) * p, p);\n        assert_near(Affine::rotate(PI / 2.0) * p, Point::new(-4.0, 3.0));\n        assert_near(Affine::translate((5.0, 6.0)) * p, Point::new(8.0, 10.0));\n        assert_near(Affine::skew(0.0, 0.0) * p, p);\n        assert_near(Affine::skew(2.0, 4.0) * p, Point::new(11.0, 16.0));\n    }\n\n    #[test]\n    fn affine_mul() {\n        let a1 = Affine::new([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);\n        let a2 = Affine::new([0.1, 1.2, 2.3, 3.4, 4.5, 5.6]);\n\n        let px = Point::new(1.0, 0.0);\n        let py = Point::new(0.0, 1.0);\n        let pxy = Point::new(1.0, 1.0);\n        assert_near(a1 * (a2 * px), (a1 * a2) * px);\n        assert_near(a1 * (a2 * py), (a1 * a2) * py);\n        assert_near(a1 * (a2 * pxy), (a1 * a2) * pxy);\n    }\n\n    #[test]\n    fn affine_inv() {\n        let a = Affine::new([0.1, 1.2, 2.3, 3.4, 4.5, 5.6]);\n        let a_inv = a.inverse();\n\n        let px = Point::new(1.0, 0.0);\n        let py = Point::new(0.0, 1.0);\n        let pxy = Point::new(1.0, 1.0);\n        assert_near(a * (a_inv * px), px);\n        assert_near(a * (a_inv * py), py);\n        assert_near(a * (a_inv * pxy), pxy);\n        assert_near(a_inv * (a * px), px);\n        assert_near(a_inv * (a * py), py);\n        assert_near(a_inv * (a * pxy), pxy);\n    }\n\n    #[test]\n    fn reflection() {\n        affine_assert_near(\n            Affine::reflect(Point::ZERO, (1., 0.)),\n            Affine::new([1., 0., 0., -1., 0., 0.]),\n        );\n        affine_assert_near(\n            Affine::reflect(Point::ZERO, (0., 1.)),\n            Affine::new([-1., 0., 0., 1., 0., 0.]),\n        );\n        // y = x\n        affine_assert_near(\n            Affine::reflect(Point::ZERO, (1., 1.)),\n            Affine::new([0., 1., 1., 0., 0., 0.]),\n        );\n\n        // no translate\n        let point = Point::new(0., 0.);\n        let vec = Vec2::new(1., 1.);\n        let map = Affine::reflect(point, vec);\n        assert_near(map * Point::new(0., 0.), Point::new(0., 0.));\n        assert_near(map * Point::new(1., 1.), Point::new(1., 1.));\n        assert_near(map * Point::new(1., 2.), Point::new(2., 1.));\n\n        // with translate\n        let point = Point::new(1., 0.);\n        let vec = Vec2::new(1., 1.);\n        let map = Affine::reflect(point, vec);\n        assert_near(map * Point::new(1., 0.), Point::new(1., 0.));\n        assert_near(map * Point::new(2., 1.), Point::new(2., 1.));\n        assert_near(map * Point::new(2., 2.), Point::new(3., 1.));\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/arc.rs",
      "sha256": "65d2e066ab2eb4e7210f4a961967406f6c2a15806fa5bdab8928c709ed062777",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! An ellipse arc.\n\nuse crate::{Affine, Ellipse, PathEl, Point, Rect, Shape, Vec2};\nuse core::{\n    f64::consts::{FRAC_PI_2, PI},\n    iter,\n    ops::Mul,\n};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A single arc segment.\n#[derive(Clone, Copy, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Arc {\n    /// The arc's centre point.\n    pub center: Point,\n    /// The arc's radii, where the vector's x-component is the radius in the\n    /// positive x direction after applying `x_rotation`.\n    pub radii: Vec2,\n    /// The start angle in radians.\n    pub start_angle: f64,\n    /// The angle between the start and end of the arc, in radians.\n    pub sweep_angle: f64,\n    /// How much the arc is rotated, in radians.\n    pub x_rotation: f64,\n}\n\nimpl Arc {\n    /// Create a new `Arc`.\n    pub fn new(\n        center: impl Into<Point>,\n        radii: impl Into<Vec2>,\n        start_angle: f64,\n        sweep_angle: f64,\n        x_rotation: f64,\n    ) -> Self {\n        Self {\n            center: center.into(),\n            radii: radii.into(),\n            start_angle,\n            sweep_angle,\n            x_rotation,\n        }\n    }\n\n    /// Create an iterator generating Bezier path elements.\n    ///\n    /// The generated elements can be appended to an existing bezier path.\n    pub fn append_iter(&self, tolerance: f64) -> ArcAppendIter {\n        let sign = self.sweep_angle.signum();\n        let scaled_err = self.radii.x.max(self.radii.y) / tolerance;\n        // Number of subdivisions per ellipse based on error tolerance.\n        // Note: this may slightly underestimate the error for quadrants.\n        let n_err = (1.1163 * scaled_err).powf(1.0 / 6.0).max(3.999_999);\n        let n = (n_err * self.sweep_angle.abs() * (1.0 / (2.0 * PI))).ceil();\n        let angle_step = self.sweep_angle / n;\n        let n = n as usize;\n        let arm_len = (4.0 / 3.0) * (0.25 * angle_step).abs().tan() * sign;\n        let angle0 = self.start_angle;\n        let p0 = sample_ellipse(self.radii, self.x_rotation, angle0);\n\n        ArcAppendIter {\n            idx: 0,\n\n            center: self.center,\n            radii: self.radii,\n            x_rotation: self.x_rotation,\n            n,\n            arm_len,\n            angle_step,\n\n            p0,\n            angle0,\n        }\n    }\n\n    /// Converts an Arc into a series of cubic bezier segments.\n    ///\n    /// Closure will be invoked for each segment.\n    pub fn to_cubic_beziers<P>(self, tolerance: f64, mut p: P)\n    where\n        P: FnMut(Point, Point, Point),\n    {\n        let mut path = self.append_iter(tolerance);\n        while let Some(PathEl::CurveTo(p1, p2, p3)) = path.next() {\n            p(p1, p2, p3);\n        }\n    }\n}\n\n#[doc(hidden)]\npub struct ArcAppendIter {\n    idx: usize,\n\n    center: Point,\n    radii: Vec2,\n    x_rotation: f64,\n    n: usize,\n    arm_len: f64,\n    angle_step: f64,\n\n    p0: Vec2,\n    angle0: f64,\n}\n\nimpl Iterator for ArcAppendIter {\n    type Item = PathEl;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.idx >= self.n {\n            return None;\n        }\n\n        let angle1 = self.angle0 + self.angle_step;\n        let p0 = self.p0;\n        let p1 = p0\n            + self.arm_len * sample_ellipse(self.radii, self.x_rotation, self.angle0 + FRAC_PI_2);\n        let p3 = sample_ellipse(self.radii, self.x_rotation, angle1);\n        let p2 =\n            p3 - self.arm_len * sample_ellipse(self.radii, self.x_rotation, angle1 + FRAC_PI_2);\n\n        self.angle0 = angle1;\n        self.p0 = p3;\n        self.idx += 1;\n\n        Some(PathEl::CurveTo(\n            self.center + p1,\n            self.center + p2,\n            self.center + p3,\n        ))\n    }\n}\n\n/// Take the ellipse radii, how the radii are rotated, and the sweep angle, and return a point on\n/// the ellipse.\nfn sample_ellipse(radii: Vec2, x_rotation: f64, angle: f64) -> Vec2 {\n    let (angle_sin, angle_cos) = angle.sin_cos();\n    let u = radii.x * angle_cos;\n    let v = radii.y * angle_sin;\n    rotate_pt(Vec2::new(u, v), x_rotation)\n}\n\n/// Rotate `pt` about the origin by `angle` radians.\nfn rotate_pt(pt: Vec2, angle: f64) -> Vec2 {\n    let (angle_sin, angle_cos) = angle.sin_cos();\n    Vec2::new(\n        pt.x * angle_cos - pt.y * angle_sin,\n        pt.x * angle_sin + pt.y * angle_cos,\n    )\n}\n\nimpl Shape for Arc {\n    type PathElementsIter<'iter> = iter::Chain<iter::Once<PathEl>, ArcAppendIter>;\n\n    fn path_elements(&self, tolerance: f64) -> Self::PathElementsIter<'_> {\n        let p0 = sample_ellipse(self.radii, self.x_rotation, self.start_angle);\n        iter::once(PathEl::MoveTo(self.center + p0)).chain(self.append_iter(tolerance))\n    }\n\n    /// Note: shape isn't closed so area is not well defined.\n    #[inline]\n    fn area(&self) -> f64 {\n        let Vec2 { x, y } = self.radii;\n        PI * x * y\n    }\n\n    /// The perimeter of the ellipse.\n    ///\n    /// Note: Finding the perimeter of an ellipse is [fairly involved][wikipedia],\n    /// so for now we just approximate by using the bezier curve representation.\n    ///\n    /// [wikipedia]: https://en.wikipedia.org/wiki/Ellipse#Circumference\n    #[inline]\n    fn perimeter(&self, accuracy: f64) -> f64 {\n        self.path_segments(0.1).perimeter(accuracy)\n    }\n\n    /// Note: shape isn't closed, so a point's winding number is not well defined.\n    #[inline]\n    fn winding(&self, pt: Point) -> i32 {\n        self.path_segments(0.1).winding(pt)\n    }\n\n    #[inline]\n    fn bounding_box(&self) -> Rect {\n        self.path_segments(0.1).bounding_box()\n    }\n}\n\nimpl Mul<Arc> for Affine {\n    type Output = Arc;\n\n    fn mul(self, arc: Arc) -> Self::Output {\n        let ellipse = self * Ellipse::new(arc.center, arc.radii, arc.x_rotation);\n        let center = ellipse.center();\n        let (radii, rotation) = ellipse.radii_and_rotation();\n        Arc {\n            center,\n            radii,\n            x_rotation: rotation,\n            start_angle: arc.start_angle,\n            sweep_angle: arc.sweep_angle,\n        }\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/bezpath.rs",
      "sha256": "4fbcf9706515be23ff81171b26c436d4fef864c1069122666ed061c5e362a9f7",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Bézier paths (up to cubic).\n\n#![allow(clippy::many_single_char_names)]\n\nuse core::iter::{Extend, FromIterator};\nuse core::mem;\nuse core::ops::{Mul, Range};\n\nuse alloc::vec::Vec;\n\nuse arrayvec::ArrayVec;\n\nuse crate::common::{solve_cubic, solve_quadratic};\nuse crate::MAX_EXTREMA;\nuse crate::{\n    Affine, CubicBez, Line, Nearest, ParamCurve, ParamCurveArclen, ParamCurveArea,\n    ParamCurveExtrema, ParamCurveNearest, Point, QuadBez, Rect, Shape, TranslateScale, Vec2,\n};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A Bézier path.\n///\n/// These docs assume basic familiarity with Bézier curves; for an introduction,\n/// see Pomax's wonderful [A Primer on Bézier Curves].\n///\n/// This path can contain lines, quadratics ([`QuadBez`]) and cubics\n/// ([`CubicBez`]), and may contain multiple subpaths.\n///\n/// # Elements and Segments\n///\n/// A Bézier path can be represented in terms of either 'elements' ([`PathEl`])\n/// or 'segments' ([`PathSeg`]). Elements map closely to how Béziers are\n/// generally used in PostScript-style drawing APIs; they can be thought of as\n/// instructions for drawing the path. Segments more directly describe the\n/// path itself, with each segment being an independent line or curve.\n///\n/// These different representations are useful in different contexts.\n/// For tasks like drawing, elements are a natural fit, but when doing\n/// hit-testing or subdividing, we need to have access to the segments.\n///\n/// Conceptually, a `BezPath` contains zero or more subpaths. Each subpath\n/// *always* begins with a `MoveTo`, then has zero or more `LineTo`, `QuadTo`,\n/// and `CurveTo` elements, and optionally ends with a `ClosePath`.\n///\n/// Internally, a `BezPath` is a list of [`PathEl`]s; as such it implements\n/// [`FromIterator<PathEl>`] and [`Extend<PathEl>`]:\n///\n/// ```\n/// use kurbo::{BezPath, Rect, Shape, Vec2};\n/// let accuracy = 0.1;\n/// let rect = Rect::from_origin_size((0., 0.,), (10., 10.));\n/// // these are equivalent\n/// let path1 = rect.to_path(accuracy);\n/// let path2: BezPath = rect.path_elements(accuracy).collect();\n///\n/// // extend a path with another path:\n/// let mut path = rect.to_path(accuracy);\n/// let shifted_rect = rect + Vec2::new(5.0, 10.0);\n/// path.extend(shifted_rect.to_path(accuracy));\n/// ```\n///\n/// You can iterate the elements of a `BezPath` with the [`iter`] method,\n/// and the segments with the [`segments`] method:\n///\n/// ```\n/// use kurbo::{BezPath, Line, PathEl, PathSeg, Point, Rect, Shape};\n/// let accuracy = 0.1;\n/// let rect = Rect::from_origin_size((0., 0.,), (10., 10.));\n/// // these are equivalent\n/// let path = rect.to_path(accuracy);\n/// let first_el = PathEl::MoveTo(Point::ZERO);\n/// let first_seg = PathSeg::Line(Line::new((0., 0.), (10., 0.)));\n/// assert_eq!(path.iter().next(), Some(first_el));\n/// assert_eq!(path.segments().next(), Some(first_seg));\n/// ```\n/// In addition, if you have some other type that implements\n/// `Iterator<Item=PathEl>`, you can adapt that to an iterator of segments with\n/// the [`segments` free function].\n///\n/// # Advanced functionality\n///\n/// In addition to the basic API, there are several useful pieces of advanced\n/// functionality available on `BezPath`:\n///\n/// - [`flatten`] does Bézier flattening, converting a curve to a series of\n/// line segments\n/// - [`intersect_line`] computes intersections of a path with a line, useful\n/// for things like subdividing\n///\n/// [A Primer on Bézier Curves]: https://pomax.github.io/bezierinfo/\n/// [`iter`]: BezPath::iter\n/// [`segments`]: BezPath::segments\n/// [`flatten`]: BezPath::flatten\n/// [`intersect_line`]: PathSeg::intersect_line\n/// [`segments` free function]: segments\n/// [`FromIterator<PathEl>`]: std::iter::FromIterator\n/// [`Extend<PathEl>`]: std::iter::Extend\n#[derive(Clone, Default, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct BezPath(Vec<PathEl>);\n\n/// The element of a Bézier path.\n///\n/// A valid path has `MoveTo` at the beginning of each subpath.\n#[derive(Clone, Copy, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub enum PathEl {\n    /// Move directly to the point without drawing anything, starting a new\n    /// subpath.\n    MoveTo(Point),\n    /// Draw a line from the current location to the point.\n    LineTo(Point),\n    /// Draw a quadratic bezier using the current location and the two points.\n    QuadTo(Point, Point),\n    /// Draw a cubic bezier using the current location and the three points.\n    CurveTo(Point, Point, Point),\n    /// Close off the path.\n    ClosePath,\n}\n\n/// A segment of a Bézier path.\n#[derive(Clone, Copy, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub enum PathSeg {\n    /// A line segment.\n    Line(Line),\n    /// A quadratic bezier segment.\n    Quad(QuadBez),\n    /// A cubic bezier segment.\n    Cubic(CubicBez),\n}\n\n/// An intersection of a [`Line`] and a [`PathSeg`].\n///\n/// This can be generated with the [`PathSeg::intersect_line`] method.\n#[derive(Debug, Clone, Copy)]\npub struct LineIntersection {\n    /// The 'time' that the intersection occurs, on the line.\n    ///\n    /// This value is in the range 0..1.\n    pub line_t: f64,\n\n    /// The 'time' that the intersection occurs, on the path segment.\n    ///\n    /// This value is nominally in the range 0..1, although it may slightly exceed\n    /// that range at the boundaries of segments.\n    pub segment_t: f64,\n}\n\n/// The minimum distance between two Bézier curves.\npub struct MinDistance {\n    /// The shortest distance between any two points on the two curves.\n    pub distance: f64,\n    /// The position of the nearest point on the first curve, as a parameter.\n    ///\n    /// To resolve this to a [`Point`], use [`ParamCurve::eval`].\n    ///\n    /// [`ParamCurve::eval`]: crate::ParamCurve::eval\n    pub t1: f64,\n    /// The position of the nearest point on the second curve, as a parameter.\n    ///\n    /// To resolve this to a [`Point`], use [`ParamCurve::eval`].\n    ///\n    /// [`ParamCurve::eval`]: crate::ParamCurve::eval\n    pub t2: f64,\n}\n\nimpl BezPath {\n    /// Create a new path.\n    pub fn new() -> BezPath {\n        Default::default()\n    }\n\n    /// Create a path from a vector of path elements.\n    ///\n    /// `BezPath` also implements `FromIterator<PathEl>`, so it works with `collect`:\n    ///\n    /// ```\n    /// // a very contrived example:\n    /// use kurbo::{BezPath, PathEl};\n    ///\n    /// let path = BezPath::new();\n    /// let as_vec: Vec<PathEl> = path.into_iter().collect();\n    /// let back_to_path: BezPath = as_vec.into_iter().collect();\n    /// ```\n    pub fn from_vec(v: Vec<PathEl>) -> BezPath {\n        debug_assert!(\n            v.first().is_none() || matches!(v.first(), Some(PathEl::MoveTo(_))),\n            \"BezPath must begin with MoveTo\"\n        );\n        BezPath(v)\n    }\n\n    /// Removes the last [`PathEl`] from the path and returns it, or `None` if the path is empty.\n    pub fn pop(&mut self) -> Option<PathEl> {\n        self.0.pop()\n    }\n\n    /// Push a generic path element onto the path.\n    pub fn push(&mut self, el: PathEl) {\n        self.0.push(el);\n        debug_assert!(\n            matches!(self.0.first(), Some(PathEl::MoveTo(_))),\n            \"BezPath must begin with MoveTo\"\n        )\n    }\n\n    /// Push a \"move to\" element onto the path.\n    pub fn move_to<P: Into<Point>>(&mut self, p: P) {\n        self.push(PathEl::MoveTo(p.into()));\n    }\n\n    /// Push a \"line to\" element onto the path.\n    ///\n    /// Will panic with a debug assert when the current subpath does not\n    /// start with `move_to`.\n    pub fn line_to<P: Into<Point>>(&mut self, p: P) {\n        debug_assert!(self.is_open_subpath(), \"no open subpath (missing MoveTo)\");\n        self.push(PathEl::LineTo(p.into()));\n    }\n\n    /// Push a \"quad to\" element onto the path.\n    ///\n    /// Will panic with a debug assert when the current subpath does not\n    /// start with `move_to`.\n    pub fn quad_to<P: Into<Point>>(&mut self, p1: P, p2: P) {\n        debug_assert!(self.is_open_subpath(), \"no open subpath (missing MoveTo)\");\n        self.push(PathEl::QuadTo(p1.into(), p2.into()));\n    }\n\n    /// Push a \"curve to\" element onto the path.\n    ///\n    /// Will panic with a debug assert when the current subpath does not\n    /// start with `move_to`.\n    pub fn curve_to<P: Into<Point>>(&mut self, p1: P, p2: P, p3: P) {\n        debug_assert!(self.is_open_subpath(), \"no open subpath (missing MoveTo)\");\n        self.push(PathEl::CurveTo(p1.into(), p2.into(), p3.into()));\n    }\n\n    /// Push a \"close path\" element onto the path.\n    ///\n    /// Will panic with a debug assert when the current subpath does not\n    /// start with `move_to`.\n    pub fn close_path(&mut self) {\n        debug_assert!(self.is_open_subpath(), \"no open subpath (missing MoveTo)\");\n        self.push(PathEl::ClosePath);\n    }\n\n    fn is_open_subpath(&self) -> bool {\n        !self.0.is_empty() && self.0.last() != Some(&PathEl::ClosePath)\n    }\n\n    /// Get the path elements.\n    pub fn elements(&self) -> &[PathEl] {\n        &self.0\n    }\n\n    /// Get the path elements (mut version).\n    pub fn elements_mut(&mut self) -> &mut [PathEl] {\n        &mut self.0\n    }\n\n    /// Returns an iterator over the path's elements.\n    pub fn iter(&self) -> impl Iterator<Item = PathEl> + Clone + '_ {\n        self.0.iter().copied()\n    }\n\n    /// Iterate over the path segments.\n    pub fn segments(&self) -> impl Iterator<Item = PathSeg> + Clone + '_ {\n        segments(self.iter())\n    }\n\n    /// Shorten the path, keeping the first `len` elements.\n    pub fn truncate(&mut self, len: usize) {\n        self.0.truncate(len);\n    }\n\n    /// Flatten the path, invoking the callback repeatedly.\n    ///\n    /// Flattening is the action of approximating a curve with a succession of line segments.\n    ///\n    /// <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 120 30\" height=\"30mm\" width=\"120mm\">\n    ///   <path d=\"M26.7 24.94l.82-11.15M44.46 5.1L33.8 7.34\" fill=\"none\" stroke=\"#55d400\" stroke-width=\".5\"/>\n    ///   <path d=\"M26.7 24.94c.97-11.13 7.17-17.6 17.76-19.84M75.27 24.94l1.13-5.5 2.67-5.48 4-4.42L88 6.7l5.02-1.6\" fill=\"none\" stroke=\"#000\"/>\n    ///   <path d=\"M77.57 19.37a1.1 1.1 0 0 1-1.08 1.08 1.1 1.1 0 0 1-1.1-1.08 1.1 1.1 0 0 1 1.08-1.1 1.1 1.1 0 0 1 1.1 1.1\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M77.57 19.37a1.1 1.1 0 0 1-1.08 1.08 1.1 1.1 0 0 1-1.1-1.08 1.1 1.1 0 0 1 1.08-1.1 1.1 1.1 0 0 1 1.1 1.1\" color=\"#000\" fill=\"#fff\"/>\n    ///   <path d=\"M80.22 13.93a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.08 1.1 1.1 0 0 1 1.08 1.08\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M80.22 13.93a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.08 1.1 1.1 0 0 1 1.08 1.08\" color=\"#000\" fill=\"#fff\"/>\n    ///   <path d=\"M84.08 9.55a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.1-1.1 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M84.08 9.55a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.1-1.1 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"#fff\"/>\n    ///   <path d=\"M89.1 6.66a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.08-1.08 1.1 1.1 0 0 1 1.1 1.08\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M89.1 6.66a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.08-1.08 1.1 1.1 0 0 1 1.1 1.08\" color=\"#000\" fill=\"#fff\"/>\n    ///   <path d=\"M94.4 5a1.1 1.1 0 0 1-1.1 1.1A1.1 1.1 0 0 1 92.23 5a1.1 1.1 0 0 1 1.08-1.08A1.1 1.1 0 0 1 94.4 5\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M94.4 5a1.1 1.1 0 0 1-1.1 1.1A1.1 1.1 0 0 1 92.23 5a1.1 1.1 0 0 1 1.08-1.08A1.1 1.1 0 0 1 94.4 5\" color=\"#000\" fill=\"#fff\"/>\n    ///   <path d=\"M76.44 25.13a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M76.44 25.13a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"#fff\"/>\n    ///   <path d=\"M27.78 24.9a1.1 1.1 0 0 1-1.08 1.08 1.1 1.1 0 0 1-1.1-1.08 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M27.78 24.9a1.1 1.1 0 0 1-1.08 1.08 1.1 1.1 0 0 1-1.1-1.08 1.1 1.1 0 0 1 1.1-1.1 1.1 1.1 0 0 1 1.08 1.1\" color=\"#000\" fill=\"#fff\"/>\n    ///   <path d=\"M45.4 5.14a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.1-1.1 1.1 1.1 0 0 1 1.1-1.08 1.1 1.1 0 0 1 1.1 1.08\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M45.4 5.14a1.1 1.1 0 0 1-1.08 1.1 1.1 1.1 0 0 1-1.1-1.1 1.1 1.1 0 0 1 1.1-1.08 1.1 1.1 0 0 1 1.1 1.08\" color=\"#000\" fill=\"#fff\"/>\n    ///   <path d=\"M28.67 13.8a1.1 1.1 0 0 1-1.1 1.08 1.1 1.1 0 0 1-1.08-1.08 1.1 1.1 0 0 1 1.08-1.1 1.1 1.1 0 0 1 1.1 1.1\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M28.67 13.8a1.1 1.1 0 0 1-1.1 1.08 1.1 1.1 0 0 1-1.08-1.08 1.1 1.1 0 0 1 1.08-1.1 1.1 1.1 0 0 1 1.1 1.1\" color=\"#000\" fill=\"#fff\"/>\n    ///   <path d=\"M35 7.32a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.1A1.1 1.1 0 0 1 35 7.33\" color=\"#000\" fill=\"none\" stroke=\"#030303\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M35 7.32a1.1 1.1 0 0 1-1.1 1.1 1.1 1.1 0 0 1-1.08-1.1 1.1 1.1 0 0 1 1.1-1.1A1.1 1.1 0 0 1 35 7.33\" color=\"#000\" fill=\"#fff\"/>\n    ///   <text style=\"line-height:6.61458302px\" x=\"35.74\" y=\"284.49\" font-size=\"5.29\" font-family=\"Sans\" letter-spacing=\"0\" word-spacing=\"0\" fill=\"#b3b3b3\" stroke-width=\".26\" transform=\"translate(19.595 -267)\">\n    ///     <tspan x=\"35.74\" y=\"284.49\" font-size=\"10.58\">→</tspan>\n    ///   </text>\n    /// </svg>\n    ///\n    /// The tolerance value controls the maximum distance between the curved input\n    /// segments and their polyline approximations. (In technical terms, this is the\n    /// Hausdorff distance). The algorithm attempts to bound this distance between\n    /// by `tolerance` but this is not absolutely guaranteed. The appropriate value\n    /// depends on the use, but for antialiased rendering, a value of 0.25 has been\n    /// determined to give good results. The number of segments tends to scale as the\n    /// inverse square root of tolerance.\n    ///\n    /// <svg viewBox=\"0 0 47.5 13.2\" height=\"100\" width=\"350\" xmlns=\"http://www.w3.org/2000/svg\">\n    ///   <path d=\"M-2.44 9.53c16.27-8.5 39.68-7.93 52.13 1.9\" fill=\"none\" stroke=\"#dde9af\" stroke-width=\"4.6\"/>\n    ///   <path d=\"M-1.97 9.3C14.28 1.03 37.36 1.7 49.7 11.4\" fill=\"none\" stroke=\"#00d400\" stroke-width=\".57\" stroke-linecap=\"round\" stroke-dasharray=\"4.6, 2.291434\"/>\n    ///   <path d=\"M-1.94 10.46L6.2 6.08l28.32-1.4 15.17 6.74\" fill=\"none\" stroke=\"#000\" stroke-width=\".6\"/>\n    ///   <path d=\"M6.83 6.57a.9.9 0 0 1-1.25.15.9.9 0 0 1-.15-1.25.9.9 0 0 1 1.25-.15.9.9 0 0 1 .15 1.25\" color=\"#000\" stroke=\"#000\" stroke-width=\".57\" stroke-linecap=\"round\" stroke-opacity=\".5\"/>\n    ///   <path d=\"M35.35 5.3a.9.9 0 0 1-1.25.15.9.9 0 0 1-.15-1.25.9.9 0 0 1 1.25-.15.9.9 0 0 1 .15 1.24\" color=\"#000\" stroke=\"#000\" stroke-width=\".6\" stroke-opacity=\".5\"/>\n    ///   <g fill=\"none\" stroke=\"#ff7f2a\" stroke-width=\".26\">\n    ///     <path d=\"M20.4 3.8l.1 1.83M19.9 4.28l.48-.56.57.52M21.02 5.18l-.5.56-.6-.53\" stroke-width=\".2978872\"/>\n    ///   </g>\n    /// </svg>\n    ///\n    /// The callback will be called in order with each element of the generated\n    /// path. Because the result is made of polylines, these will be straight-line\n    /// path elements only, no curves.\n    ///\n    /// This algorithm is based on the blog post [Flattening quadratic Béziers]\n    /// but with some refinements. For one, there is a more careful approximation\n    /// at cusps. For two, the algorithm is extended to work with cubic Béziers\n    /// as well, by first subdividing into quadratics and then computing the\n    /// subdivision of each quadratic. However, as a clever trick, these quadratics\n    /// are subdivided fractionally, and their endpoints are not included.\n    ///\n    /// TODO: write a paper explaining this in more detail.\n    ///\n    /// Note: the [`flatten`] function provides the same\n    /// functionality but works with slices and other [`PathEl`] iterators.\n    ///\n    /// [Flattening quadratic Béziers]: https://raphlinus.github.io/graphics/curves/2019/12/23/flatten-quadbez.html\n    pub fn flatten(&self, tolerance: f64, callback: impl FnMut(PathEl)) {\n        flatten(self, tolerance, callback);\n    }\n\n    /// Get the segment at the given element index.\n    ///\n    /// If you need to access all segments, [`segments`] provides a better\n    /// API. This is intended for random access of specific elements, for clients\n    /// that require this specifically.\n    ///\n    /// **note**: This returns the segment that ends at the provided element\n    /// index. In effect this means it is *1-indexed*: since no segment ends at\n    /// the first element (which is presumed to be a `MoveTo`) `get_seg(0)` will\n    /// always return `None`.\n    pub fn get_seg(&self, ix: usize) -> Option<PathSeg> {\n        if ix == 0 || ix >= self.0.len() {\n            return None;\n        }\n        let last = match self.0[ix - 1] {\n            PathEl::MoveTo(p) => p,\n            PathEl::LineTo(p) => p,\n            PathEl::QuadTo(_, p2) => p2,\n            PathEl::CurveTo(_, _, p3) => p3,\n            _ => return None,\n        };\n        match self.0[ix] {\n            PathEl::LineTo(p) => Some(PathSeg::Line(Line::new(last, p))),\n            PathEl::QuadTo(p1, p2) => Some(PathSeg::Quad(QuadBez::new(last, p1, p2))),\n            PathEl::CurveTo(p1, p2, p3) => Some(PathSeg::Cubic(CubicBez::new(last, p1, p2, p3))),\n            PathEl::ClosePath => self.0[..ix].iter().rev().find_map(|el| match *el {\n                PathEl::MoveTo(start) if start != last => {\n                    Some(PathSeg::Line(Line::new(last, start)))\n                }\n                _ => None,\n            }),\n            _ => None,\n        }\n    }\n\n    /// Returns `true` if the path contains no segments.\n    pub fn is_empty(&self) -> bool {\n        self.0\n            .iter()\n            .all(|el| matches!(el, PathEl::MoveTo(..) | PathEl::ClosePath))\n    }\n\n    /// Apply an affine transform to the path.\n    pub fn apply_affine(&mut self, affine: Affine) {\n        for el in self.0.iter_mut() {\n            *el = affine * (*el);\n        }\n    }\n\n    /// Is this path finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.0.iter().all(|v| v.is_finite())\n    }\n\n    /// Is this path NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.0.iter().any(|v| v.is_nan())\n    }\n\n    /// Returns a rectangle that conservatively encloses the path.\n    ///\n    /// Unlike the `bounding_box` method, this uses control points directly\n    /// rather than computing tight bounds for curve elements.\n    pub fn control_box(&self) -> Rect {\n        let mut cbox: Option<Rect> = None;\n        let mut add_pts = |pts: &[Point]| {\n            for pt in pts {\n                cbox = match cbox {\n                    Some(cbox) => Some(cbox.union_pt(*pt)),\n                    _ => Some(Rect::from_points(*pt, *pt)),\n                };\n            }\n        };\n        for &el in self.elements() {\n            match el {\n                PathEl::MoveTo(p0) | PathEl::LineTo(p0) => add_pts(&[p0]),\n                PathEl::QuadTo(p0, p1) => add_pts(&[p0, p1]),\n                PathEl::CurveTo(p0, p1, p2) => add_pts(&[p0, p1, p2]),\n                PathEl::ClosePath => {}\n            }\n        }\n        cbox.unwrap_or_default()\n    }\n\n    /// Returns a new path with the winding direction of all subpaths reversed.\n    pub fn reverse_subpaths(&self) -> BezPath {\n        let elements = self.elements();\n        let mut start_ix = 1;\n        let mut start_pt = Point::default();\n        let mut reversed = BezPath(Vec::with_capacity(elements.len()));\n        // Pending move is used to capture degenerate subpaths that should\n        // remain in the reversed output.\n        let mut pending_move = false;\n        for (ix, el) in elements.iter().enumerate() {\n            match el {\n                PathEl::MoveTo(pt) => {\n                    if pending_move {\n                        reversed.push(PathEl::MoveTo(start_pt));\n                    }\n                    if start_ix < ix {\n                        reverse_subpath(start_pt, &elements[start_ix..ix], &mut reversed);\n                    }\n                    pending_move = true;\n                    start_pt = *pt;\n                    start_ix = ix + 1;\n                }\n                PathEl::ClosePath => {\n                    if start_ix <= ix {\n                        reverse_subpath(start_pt, &elements[start_ix..ix], &mut reversed);\n                    }\n                    reversed.push(PathEl::ClosePath);\n                    start_ix = ix + 1;\n                    pending_move = false;\n                }\n                _ => {\n                    pending_move = false;\n                }\n            }\n        }\n        if start_ix < elements.len() {\n            reverse_subpath(start_pt, &elements[start_ix..], &mut reversed);\n        } else if pending_move {\n            reversed.push(PathEl::MoveTo(start_pt));\n        }\n        reversed\n    }\n}\n\n/// Helper for reversing a subpath.\n///\n/// The `els` parameter must not contain any `MoveTo` or `ClosePath` elements.\nfn reverse_subpath(start_pt: Point, els: &[PathEl], reversed: &mut BezPath) {\n    let end_pt = els.last().and_then(|el| el.end_point()).unwrap_or(start_pt);\n    reversed.push(PathEl::MoveTo(end_pt));\n    for (ix, el) in els.iter().enumerate().rev() {\n        let end_pt = if ix > 0 {\n            els[ix - 1].end_point().unwrap()\n        } else {\n            start_pt\n        };\n        match el {\n            PathEl::LineTo(_) => reversed.push(PathEl::LineTo(end_pt)),\n            PathEl::QuadTo(c0, _) => reversed.push(PathEl::QuadTo(*c0, end_pt)),\n            PathEl::CurveTo(c0, c1, _) => reversed.push(PathEl::CurveTo(*c1, *c0, end_pt)),\n            _ => panic!(\"reverse_subpath expects MoveTo and ClosePath to be removed\"),\n        }\n    }\n}\n\nimpl FromIterator<PathEl> for BezPath {\n    fn from_iter<T: IntoIterator<Item = PathEl>>(iter: T) -> Self {\n        let el_vec: Vec<_> = iter.into_iter().collect();\n        BezPath::from_vec(el_vec)\n    }\n}\n\n/// Allow iteration over references to `BezPath`.\n///\n/// Note: the semantics are slightly different from simply iterating over the\n/// slice, as it returns `PathEl` items, rather than references.\nimpl<'a> IntoIterator for &'a BezPath {\n    type Item = PathEl;\n    type IntoIter = core::iter::Cloned<core::slice::Iter<'a, PathEl>>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        self.elements().iter().cloned()\n    }\n}\n\nimpl IntoIterator for BezPath {\n    type Item = PathEl;\n    type IntoIter = alloc::vec::IntoIter<PathEl>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        self.0.into_iter()\n    }\n}\n\nimpl Extend<PathEl> for BezPath {\n    fn extend<I: IntoIterator<Item = PathEl>>(&mut self, iter: I) {\n        self.0.extend(iter);\n    }\n}\n\n/// Proportion of tolerance budget that goes to cubic to quadratic conversion.\nconst TO_QUAD_TOL: f64 = 0.1;\n\n/// Flatten the path, invoking the callback repeatedly.\n///\n/// See [`BezPath::flatten`] for more discussion.\n/// This signature is a bit more general, allowing flattening of `&[PathEl]` slices\n/// and other iterators yielding `PathEl`.\npub fn flatten(\n    path: impl IntoIterator<Item = PathEl>,\n    tolerance: f64,\n    mut callback: impl FnMut(PathEl),\n) {\n    let sqrt_tol = tolerance.sqrt();\n    let mut last_pt = None;\n    let mut quad_buf = Vec::new();\n    for el in path {\n        match el {\n            PathEl::MoveTo(p) => {\n                last_pt = Some(p);\n                callback(PathEl::MoveTo(p));\n            }\n            PathEl::LineTo(p) => {\n                last_pt = Some(p);\n                callback(PathEl::LineTo(p));\n            }\n            PathEl::QuadTo(p1, p2) => {\n                if let Some(p0) = last_pt {\n                    let q = QuadBez::new(p0, p1, p2);\n                    let params = q.estimate_subdiv(sqrt_tol);\n                    let n = ((0.5 * params.val / sqrt_tol).ceil() as usize).max(1);\n                    let step = 1.0 / (n as f64);\n                    for i in 1..n {\n                        let u = (i as f64) * step;\n                        let t = q.determine_subdiv_t(&params, u);\n                        let p = q.eval(t);\n                        callback(PathEl::LineTo(p));\n                    }\n                    callback(PathEl::LineTo(p2));\n                }\n                last_pt = Some(p2);\n            }\n            PathEl::CurveTo(p1, p2, p3) => {\n                if let Some(p0) = last_pt {\n                    let c = CubicBez::new(p0, p1, p2, p3);\n\n                    // Subdivide into quadratics, and estimate the number of\n                    // subdivisions required for each, summing to arrive at an\n                    // estimate for the number of subdivisions for the cubic.\n                    // Also retain these parameters for later.\n                    let iter = c.to_quads(tolerance * TO_QUAD_TOL);\n                    quad_buf.clear();\n                    quad_buf.reserve(iter.size_hint().0);\n                    let sqrt_remain_tol = sqrt_tol * (1.0 - TO_QUAD_TOL).sqrt();\n                    let mut sum = 0.0;\n                    for (_, _, q) in iter {\n                        let params = q.estimate_subdiv(sqrt_remain_tol);\n                        sum += params.val;\n                        quad_buf.push((q, params));\n                    }\n                    let n = ((0.5 * sum / sqrt_remain_tol).ceil() as usize).max(1);\n\n                    // Iterate through the quadratics, outputting the points of\n                    // subdivisions that fall within that quadratic.\n                    let step = sum / (n as f64);\n                    let mut i = 1;\n                    let mut val_sum = 0.0;\n                    for (q, params) in &quad_buf {\n                        let mut target = (i as f64) * step;\n                        let recip_val = params.val.recip();\n                        while target < val_sum + params.val {\n                            let u = (target - val_sum) * recip_val;\n                            let t = q.determine_subdiv_t(params, u);\n                            let p = q.eval(t);\n                            callback(PathEl::LineTo(p));\n                            i += 1;\n                            if i == n + 1 {\n                                break;\n                            }\n                            target = (i as f64) * step;\n                        }\n                        val_sum += params.val;\n                    }\n                    callback(PathEl::LineTo(p3));\n                }\n                last_pt = Some(p3);\n            }\n            PathEl::ClosePath => {\n                last_pt = None;\n                callback(PathEl::ClosePath);\n            }\n        }\n    }\n}\n\nimpl Mul<PathEl> for Affine {\n    type Output = PathEl;\n\n    fn mul(self, other: PathEl) -> PathEl {\n        match other {\n            PathEl::MoveTo(p) => PathEl::MoveTo(self * p),\n            PathEl::LineTo(p) => PathEl::LineTo(self * p),\n            PathEl::QuadTo(p1, p2) => PathEl::QuadTo(self * p1, self * p2),\n            PathEl::CurveTo(p1, p2, p3) => PathEl::CurveTo(self * p1, self * p2, self * p3),\n            PathEl::ClosePath => PathEl::ClosePath,\n        }\n    }\n}\n\nimpl Mul<PathSeg> for Affine {\n    type Output = PathSeg;\n\n    fn mul(self, other: PathSeg) -> PathSeg {\n        match other {\n            PathSeg::Line(line) => PathSeg::Line(self * line),\n            PathSeg::Quad(quad) => PathSeg::Quad(self * quad),\n            PathSeg::Cubic(cubic) => PathSeg::Cubic(self * cubic),\n        }\n    }\n}\n\nimpl Mul<BezPath> for Affine {\n    type Output = BezPath;\n\n    fn mul(self, other: BezPath) -> BezPath {\n        BezPath(other.0.iter().map(|&el| self * el).collect())\n    }\n}\n\nimpl<'a> Mul<&'a BezPath> for Affine {\n    type Output = BezPath;\n\n    fn mul(self, other: &BezPath) -> BezPath {\n        BezPath(other.0.iter().map(|&el| self * el).collect())\n    }\n}\n\nimpl Mul<PathEl> for TranslateScale {\n    type Output = PathEl;\n\n    fn mul(self, other: PathEl) -> PathEl {\n        match other {\n            PathEl::MoveTo(p) => PathEl::MoveTo(self * p),\n            PathEl::LineTo(p) => PathEl::LineTo(self * p),\n            PathEl::QuadTo(p1, p2) => PathEl::QuadTo(self * p1, self * p2),\n            PathEl::CurveTo(p1, p2, p3) => PathEl::CurveTo(self * p1, self * p2, self * p3),\n            PathEl::ClosePath => PathEl::ClosePath,\n        }\n    }\n}\n\nimpl Mul<PathSeg> for TranslateScale {\n    type Output = PathSeg;\n\n    fn mul(self, other: PathSeg) -> PathSeg {\n        match other {\n            PathSeg::Line(line) => PathSeg::Line(self * line),\n            PathSeg::Quad(quad) => PathSeg::Quad(self * quad),\n            PathSeg::Cubic(cubic) => PathSeg::Cubic(self * cubic),\n        }\n    }\n}\n\nimpl Mul<BezPath> for TranslateScale {\n    type Output = BezPath;\n\n    fn mul(self, other: BezPath) -> BezPath {\n        BezPath(other.0.iter().map(|&el| self * el).collect())\n    }\n}\n\nimpl<'a> Mul<&'a BezPath> for TranslateScale {\n    type Output = BezPath;\n\n    fn mul(self, other: &BezPath) -> BezPath {\n        BezPath(other.0.iter().map(|&el| self * el).collect())\n    }\n}\n\n/// Transform an iterator over path elements into one over path\n/// segments.\n///\n/// See also [`BezPath::segments`].\n/// This signature is a bit more general, allowing `&[PathEl]` slices\n/// and other iterators yielding `PathEl`.\npub fn segments<I>(elements: I) -> Segments<I::IntoIter>\nwhere\n    I: IntoIterator<Item = PathEl>,\n{\n    Segments {\n        elements: elements.into_iter(),\n        start_last: None,\n    }\n}\n\n/// An iterator that transforms path elements to path segments.\n///\n/// This struct is created by the [`segments`] function.\n#[derive(Clone)]\npub struct Segments<I: Iterator<Item = PathEl>> {\n    elements: I,\n    start_last: Option<(Point, Point)>,\n}\n\nimpl<I: Iterator<Item = PathEl>> Iterator for Segments<I> {\n    type Item = PathSeg;\n\n    fn next(&mut self) -> Option<PathSeg> {\n        for el in &mut self.elements {\n            // We first need to check whether this is the first\n            // path element we see to fill in the start position.\n            let (start, last) = self.start_last.get_or_insert_with(|| {\n                let point = match el {\n                    PathEl::MoveTo(p) => p,\n                    PathEl::LineTo(p) => p,\n                    PathEl::QuadTo(_, p2) => p2,\n                    PathEl::CurveTo(_, _, p3) => p3,\n                    PathEl::ClosePath => panic!(\"Can't start a segment on a ClosePath\"),\n                };\n                (point, point)\n            });\n\n            return Some(match el {\n                PathEl::MoveTo(p) => {\n                    *start = p;\n                    *last = p;\n                    continue;\n                }\n                PathEl::LineTo(p) => PathSeg::Line(Line::new(mem::replace(last, p), p)),\n                PathEl::QuadTo(p1, p2) => {\n                    PathSeg::Quad(QuadBez::new(mem::replace(last, p2), p1, p2))\n                }\n                PathEl::CurveTo(p1, p2, p3) => {\n                    PathSeg::Cubic(CubicBez::new(mem::replace(last, p3), p1, p2, p3))\n                }\n                PathEl::ClosePath => {\n                    if *last != *start {\n                        PathSeg::Line(Line::new(mem::replace(last, *start), *start))\n                    } else {\n                        continue;\n                    }\n                }\n            });\n        }\n\n        None\n    }\n}\n\nimpl<I: Iterator<Item = PathEl>> Segments<I> {\n    /// Here, `accuracy` specifies the accuracy for each Bézier segment. At worst,\n    /// the total error is `accuracy` times the number of Bézier segments.\n\n    // TODO: pub? Or is this subsumed by method of &[PathEl]?\n    pub(crate) fn perimeter(self, accuracy: f64) -> f64 {\n        self.map(|seg| seg.arclen(accuracy)).sum()\n    }\n\n    // Same\n    pub(crate) fn area(self) -> f64 {\n        self.map(|seg| seg.signed_area()).sum()\n    }\n\n    // Same\n    pub(crate) fn winding(self, p: Point) -> i32 {\n        self.map(|seg| seg.winding(p)).sum()\n    }\n\n    // Same\n    pub(crate) fn bounding_box(self) -> Rect {\n        let mut bbox: Option<Rect> = None;\n        for seg in self {\n            let seg_bb = ParamCurveExtrema::bounding_box(&seg);\n            if let Some(bb) = bbox {\n                bbox = Some(bb.union(seg_bb));\n            } else {\n                bbox = Some(seg_bb)\n            }\n        }\n        bbox.unwrap_or_default()\n    }\n}\n\nimpl ParamCurve for PathSeg {\n    fn eval(&self, t: f64) -> Point {\n        match *self {\n            PathSeg::Line(line) => line.eval(t),\n            PathSeg::Quad(quad) => quad.eval(t),\n            PathSeg::Cubic(cubic) => cubic.eval(t),\n        }\n    }\n\n    fn subsegment(&self, range: Range<f64>) -> PathSeg {\n        match *self {\n            PathSeg::Line(line) => PathSeg::Line(line.subsegment(range)),\n            PathSeg::Quad(quad) => PathSeg::Quad(quad.subsegment(range)),\n            PathSeg::Cubic(cubic) => PathSeg::Cubic(cubic.subsegment(range)),\n        }\n    }\n}\n\nimpl ParamCurveArclen for PathSeg {\n    fn arclen(&self, accuracy: f64) -> f64 {\n        match *self {\n            PathSeg::Line(line) => line.arclen(accuracy),\n            PathSeg::Quad(quad) => quad.arclen(accuracy),\n            PathSeg::Cubic(cubic) => cubic.arclen(accuracy),\n        }\n    }\n\n    fn inv_arclen(&self, arclen: f64, accuracy: f64) -> f64 {\n        match *self {\n            PathSeg::Line(line) => line.inv_arclen(arclen, accuracy),\n            PathSeg::Quad(quad) => quad.inv_arclen(arclen, accuracy),\n            PathSeg::Cubic(cubic) => cubic.inv_arclen(arclen, accuracy),\n        }\n    }\n}\n\nimpl ParamCurveArea for PathSeg {\n    fn signed_area(&self) -> f64 {\n        match *self {\n            PathSeg::Line(line) => line.signed_area(),\n            PathSeg::Quad(quad) => quad.signed_area(),\n            PathSeg::Cubic(cubic) => cubic.signed_area(),\n        }\n    }\n}\n\nimpl ParamCurveNearest for PathSeg {\n    fn nearest(&self, p: Point, accuracy: f64) -> Nearest {\n        match *self {\n            PathSeg::Line(line) => line.nearest(p, accuracy),\n            PathSeg::Quad(quad) => quad.nearest(p, accuracy),\n            PathSeg::Cubic(cubic) => cubic.nearest(p, accuracy),\n        }\n    }\n}\n\nimpl ParamCurveExtrema for PathSeg {\n    fn extrema(&self) -> ArrayVec<f64, MAX_EXTREMA> {\n        match *self {\n            PathSeg::Line(line) => line.extrema(),\n            PathSeg::Quad(quad) => quad.extrema(),\n            PathSeg::Cubic(cubic) => cubic.extrema(),\n        }\n    }\n}\n\nimpl PathSeg {\n    /// Get the [`PathEl`] that is equivalent to discarding the segment start point.\n    pub fn as_path_el(&self) -> PathEl {\n        match self {\n            PathSeg::Line(line) => PathEl::LineTo(line.p1),\n            PathSeg::Quad(q) => PathEl::QuadTo(q.p1, q.p2),\n            PathSeg::Cubic(c) => PathEl::CurveTo(c.p1, c.p2, c.p3),\n        }\n    }\n\n    /// Returns a new `PathSeg` describing the same path as `self`, but with\n    /// the points reversed.\n    pub fn reverse(&self) -> PathSeg {\n        match self {\n            PathSeg::Line(Line { p0, p1 }) => PathSeg::Line(Line::new(*p1, *p0)),\n            PathSeg::Quad(q) => PathSeg::Quad(QuadBez::new(q.p2, q.p1, q.p0)),\n            PathSeg::Cubic(c) => PathSeg::Cubic(CubicBez::new(c.p3, c.p2, c.p1, c.p0)),\n        }\n    }\n\n    /// Convert this segment to a cubic bezier.\n    pub fn to_cubic(&self) -> CubicBez {\n        match *self {\n            PathSeg::Line(Line { p0, p1 }) => CubicBez::new(p0, p0, p1, p1),\n            PathSeg::Cubic(c) => c,\n            PathSeg::Quad(q) => q.raise(),\n        }\n    }\n\n    // Assumes split at extrema.\n    fn winding_inner(&self, p: Point) -> i32 {\n        let start = self.start();\n        let end = self.end();\n        let sign = if end.y > start.y {\n            if p.y < start.y || p.y >= end.y {\n                return 0;\n            }\n            -1\n        } else if end.y < start.y {\n            if p.y < end.y || p.y >= start.y {\n                return 0;\n            }\n            1\n        } else {\n            return 0;\n        };\n        match *self {\n            PathSeg::Line(_line) => {\n                if p.x < start.x.min(end.x) {\n                    return 0;\n                }\n                if p.x >= start.x.max(end.x) {\n                    return sign;\n                }\n                // line equation ax + by = c\n                let a = end.y - start.y;\n                let b = start.x - end.x;\n                let c = a * start.x + b * start.y;\n                if (a * p.x + b * p.y - c) * (sign as f64) <= 0.0 {\n                    sign\n                } else {\n                    0\n                }\n            }\n            PathSeg::Quad(quad) => {\n                let p1 = quad.p1;\n                if p.x < start.x.min(end.x).min(p1.x) {\n                    return 0;\n                }\n                if p.x >= start.x.max(end.x).max(p1.x) {\n                    return sign;\n                }\n                let a = end.y - 2.0 * p1.y + start.y;\n                let b = 2.0 * (p1.y - start.y);\n                let c = start.y - p.y;\n                for t in solve_quadratic(c, b, a) {\n                    if (0.0..=1.0).contains(&t) {\n                        let x = quad.eval(t).x;\n                        if p.x >= x {\n                            return sign;\n                        } else {\n                            return 0;\n                        }\n                    }\n                }\n                0\n            }\n            PathSeg::Cubic(cubic) => {\n                let p1 = cubic.p1;\n                let p2 = cubic.p2;\n                if p.x < start.x.min(end.x).min(p1.x).min(p2.x) {\n                    return 0;\n                }\n                if p.x >= start.x.max(end.x).max(p1.x).max(p2.x) {\n                    return sign;\n                }\n                let a = end.y - 3.0 * p2.y + 3.0 * p1.y - start.y;\n                let b = 3.0 * (p2.y - 2.0 * p1.y + start.y);\n                let c = 3.0 * (p1.y - start.y);\n                let d = start.y - p.y;\n                for t in solve_cubic(d, c, b, a) {\n                    if (0.0..=1.0).contains(&t) {\n                        let x = cubic.eval(t).x;\n                        if p.x >= x {\n                            return sign;\n                        } else {\n                            return 0;\n                        }\n                    }\n                }\n                0\n            }\n        }\n    }\n\n    /// Compute the winding number contribution of a single segment.\n    ///\n    /// Cast a ray to the left and count intersections.\n    fn winding(&self, p: Point) -> i32 {\n        self.extrema_ranges()\n            .into_iter()\n            .map(|range| self.subsegment(range).winding_inner(p))\n            .sum()\n    }\n\n    /// Compute intersections against a line.\n    ///\n    /// Returns a vector of the intersections. For each intersection,\n    /// the `t` value of the segment and line are given.\n    ///\n    /// Note: This test is designed to be inclusive of points near the endpoints\n    /// of the segment. This is so that testing a line against multiple\n    /// contiguous segments of a path will be guaranteed to catch at least one\n    /// of them. In such cases, use higher level logic to coalesce the hits\n    /// (the `t` value may be slightly outside the range of 0..1).\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use kurbo::*;\n    /// let seg = PathSeg::Line(Line::new((0.0, 0.0), (2.0, 0.0)));\n    /// let line = Line::new((1.0, 2.0), (1.0, -2.0));\n    /// let intersection = seg.intersect_line(line);\n    /// assert_eq!(intersection.len(), 1);\n    /// let intersection = intersection[0];\n    /// assert_eq!(intersection.segment_t, 0.5);\n    /// assert_eq!(intersection.line_t, 0.5);\n    ///\n    /// let point = seg.eval(intersection.segment_t);\n    /// assert_eq!(point, Point::new(1.0, 0.0));\n    /// ```\n    pub fn intersect_line(&self, line: Line) -> ArrayVec<LineIntersection, 3> {\n        const EPSILON: f64 = 1e-9;\n        let p0 = line.p0;\n        let p1 = line.p1;\n        let dx = p1.x - p0.x;\n        let dy = p1.y - p0.y;\n        let mut result = ArrayVec::new();\n        match self {\n            PathSeg::Line(l) => {\n                let det = dx * (l.p1.y - l.p0.y) - dy * (l.p1.x - l.p0.x);\n                if det.abs() < EPSILON {\n                    // Lines are coincident (or nearly so).\n                    return result;\n                }\n                let t = dx * (p0.y - l.p0.y) - dy * (p0.x - l.p0.x);\n                // t = position on self\n                let t = t / det;\n                if (-EPSILON..=(1.0 + EPSILON)).contains(&t) {\n                    // u = position on probe line\n                    let u =\n                        (l.p0.x - p0.x) * (l.p1.y - l.p0.y) - (l.p0.y - p0.y) * (l.p1.x - l.p0.x);\n                    let u = u / det;\n                    if (0.0..=1.0).contains(&u) {\n                        result.push(LineIntersection::new(u, t));\n                    }\n                }\n            }\n            PathSeg::Quad(q) => {\n                // The basic technique here is to determine x and y as a quadratic polynomial\n                // as a function of t. Then plug those values into the line equation for the\n                // probe line (giving a sort of signed distance from the probe line) and solve\n                // that for t.\n                let (px0, px1, px2) = quadratic_bez_coefs(q.p0.x, q.p1.x, q.p2.x);\n                let (py0, py1, py2) = quadratic_bez_coefs(q.p0.y, q.p1.y, q.p2.y);\n                let c0 = dy * (px0 - p0.x) - dx * (py0 - p0.y);\n                let c1 = dy * px1 - dx * py1;\n                let c2 = dy * px2 - dx * py2;\n                let invlen2 = (dx * dx + dy * dy).recip();\n                for t in crate::common::solve_quadratic(c0, c1, c2) {\n                    if (-EPSILON..=(1.0 + EPSILON)).contains(&t) {\n                        let x = px0 + t * px1 + t * t * px2;\n                        let y = py0 + t * py1 + t * t * py2;\n                        let u = ((x - p0.x) * dx + (y - p0.y) * dy) * invlen2;\n                        if (0.0..=1.0).contains(&u) {\n                            result.push(LineIntersection::new(u, t));\n                        }\n                    }\n                }\n            }\n            PathSeg::Cubic(c) => {\n                // Same technique as above, but cubic polynomial.\n                let (px0, px1, px2, px3) = cubic_bez_coefs(c.p0.x, c.p1.x, c.p2.x, c.p3.x);\n                let (py0, py1, py2, py3) = cubic_bez_coefs(c.p0.y, c.p1.y, c.p2.y, c.p3.y);\n                let c0 = dy * (px0 - p0.x) - dx * (py0 - p0.y);\n                let c1 = dy * px1 - dx * py1;\n                let c2 = dy * px2 - dx * py2;\n                let c3 = dy * px3 - dx * py3;\n                let invlen2 = (dx * dx + dy * dy).recip();\n                for t in crate::common::solve_cubic(c0, c1, c2, c3) {\n                    if (-EPSILON..=(1.0 + EPSILON)).contains(&t) {\n                        let x = px0 + t * px1 + t * t * px2 + t * t * t * px3;\n                        let y = py0 + t * py1 + t * t * py2 + t * t * t * py3;\n                        let u = ((x - p0.x) * dx + (y - p0.y) * dy) * invlen2;\n                        if (0.0..=1.0).contains(&u) {\n                            result.push(LineIntersection::new(u, t));\n                        }\n                    }\n                }\n            }\n        }\n        result\n    }\n\n    /// Is this Bezier path finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        match self {\n            PathSeg::Line(line) => line.is_finite(),\n            PathSeg::Quad(quad_bez) => quad_bez.is_finite(),\n            PathSeg::Cubic(cubic_bez) => cubic_bez.is_finite(),\n        }\n    }\n\n    /// Is this Bezier path NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        match self {\n            PathSeg::Line(line) => line.is_nan(),\n            PathSeg::Quad(quad_bez) => quad_bez.is_nan(),\n            PathSeg::Cubic(cubic_bez) => cubic_bez.is_nan(),\n        }\n    }\n\n    #[inline]\n    fn as_vec2_vec(&self) -> ArrayVec<Vec2, 4> {\n        let mut a = ArrayVec::new();\n        match self {\n            PathSeg::Line(l) => {\n                a.push(l.p0.to_vec2());\n                a.push(l.p1.to_vec2());\n            }\n            PathSeg::Quad(q) => {\n                a.push(q.p0.to_vec2());\n                a.push(q.p1.to_vec2());\n                a.push(q.p2.to_vec2());\n            }\n            PathSeg::Cubic(c) => {\n                a.push(c.p0.to_vec2());\n                a.push(c.p1.to_vec2());\n                a.push(c.p2.to_vec2());\n                a.push(c.p3.to_vec2());\n            }\n        };\n        a\n    }\n\n    /// Minimum distance between two [`PathSeg`]s.\n    ///\n    /// Returns a tuple of the distance, the path time `t1` of the closest point\n    /// on the first `PathSeg`, and the path time `t2` of the closest point on the\n    /// second `PathSeg`.\n    pub fn min_dist(&self, other: PathSeg, accuracy: f64) -> MinDistance {\n        let (distance, t1, t2) = crate::mindist::min_dist_param(\n            &self.as_vec2_vec(),\n            &other.as_vec2_vec(),\n            (0.0, 1.0),\n            (0.0, 1.0),\n            accuracy,\n            None,\n        );\n        MinDistance {\n            distance: distance.sqrt(),\n            t1,\n            t2,\n        }\n    }\n\n    /// Compute endpoint tangents of a path segment.\n    ///\n    /// This version is robust to the path segment not being a regular curve.\n    pub(crate) fn tangents(&self) -> (Vec2, Vec2) {\n        const EPS: f64 = 1e-12;\n        match self {\n            PathSeg::Line(l) => {\n                let d = l.p1 - l.p0;\n                (d, d)\n            }\n            PathSeg::Quad(q) => {\n                let d01 = q.p1 - q.p0;\n                let d0 = if d01.hypot2() > EPS { d01 } else { q.p2 - q.p0 };\n                let d12 = q.p2 - q.p1;\n                let d1 = if d12.hypot2() > EPS { d12 } else { q.p2 - q.p0 };\n                (d0, d1)\n            }\n            PathSeg::Cubic(c) => {\n                let d01 = c.p1 - c.p0;\n                let d0 = if d01.hypot2() > EPS {\n                    d01\n                } else {\n                    let d02 = c.p2 - c.p0;\n                    if d02.hypot2() > EPS {\n                        d02\n                    } else {\n                        c.p3 - c.p0\n                    }\n                };\n                let d23 = c.p3 - c.p2;\n                let d1 = if d23.hypot2() > EPS {\n                    d23\n                } else {\n                    let d13 = c.p3 - c.p1;\n                    if d13.hypot2() > EPS {\n                        d13\n                    } else {\n                        c.p3 - c.p0\n                    }\n                };\n                (d0, d1)\n            }\n        }\n    }\n}\n\nimpl LineIntersection {\n    fn new(line_t: f64, segment_t: f64) -> Self {\n        LineIntersection { line_t, segment_t }\n    }\n\n    /// Is this line intersection finite?\n    #[inline]\n    pub fn is_finite(self) -> bool {\n        self.line_t.is_finite() && self.segment_t.is_finite()\n    }\n\n    /// Is this line intersection NaN?\n    #[inline]\n    pub fn is_nan(self) -> bool {\n        self.line_t.is_nan() || self.segment_t.is_nan()\n    }\n}\n\n// Return polynomial coefficients given cubic bezier coordinates.\nfn quadratic_bez_coefs(x0: f64, x1: f64, x2: f64) -> (f64, f64, f64) {\n    let p0 = x0;\n    let p1 = 2.0 * x1 - 2.0 * x0;\n    let p2 = x2 - 2.0 * x1 + x0;\n    (p0, p1, p2)\n}\n\n// Return polynomial coefficients given cubic bezier coordinates.\nfn cubic_bez_coefs(x0: f64, x1: f64, x2: f64, x3: f64) -> (f64, f64, f64, f64) {\n    let p0 = x0;\n    let p1 = 3.0 * x1 - 3.0 * x0;\n    let p2 = 3.0 * x2 - 6.0 * x1 + 3.0 * x0;\n    let p3 = x3 - 3.0 * x2 + 3.0 * x1 - x0;\n    (p0, p1, p2, p3)\n}\n\nimpl From<CubicBez> for PathSeg {\n    fn from(cubic_bez: CubicBez) -> PathSeg {\n        PathSeg::Cubic(cubic_bez)\n    }\n}\n\nimpl From<Line> for PathSeg {\n    fn from(line: Line) -> PathSeg {\n        PathSeg::Line(line)\n    }\n}\n\nimpl From<QuadBez> for PathSeg {\n    fn from(quad_bez: QuadBez) -> PathSeg {\n        PathSeg::Quad(quad_bez)\n    }\n}\n\nimpl Shape for BezPath {\n    type PathElementsIter<'iter> = core::iter::Copied<core::slice::Iter<'iter, PathEl>>;\n\n    fn path_elements(&self, _tolerance: f64) -> Self::PathElementsIter<'_> {\n        self.0.iter().copied()\n    }\n\n    fn to_path(&self, _tolerance: f64) -> BezPath {\n        self.clone()\n    }\n\n    fn into_path(self, _tolerance: f64) -> BezPath {\n        self\n    }\n\n    /// Signed area.\n    fn area(&self) -> f64 {\n        self.elements().area()\n    }\n\n    fn perimeter(&self, accuracy: f64) -> f64 {\n        self.elements().perimeter(accuracy)\n    }\n\n    /// Winding number of point.\n    fn winding(&self, pt: Point) -> i32 {\n        self.elements().winding(pt)\n    }\n\n    fn bounding_box(&self) -> Rect {\n        self.elements().bounding_box()\n    }\n\n    fn as_path_slice(&self) -> Option<&[PathEl]> {\n        Some(&self.0)\n    }\n}\n\nimpl PathEl {\n    /// Is this path element finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        match self {\n            PathEl::MoveTo(p) => p.is_finite(),\n            PathEl::LineTo(p) => p.is_finite(),\n            PathEl::QuadTo(p, p2) => p.is_finite() && p2.is_finite(),\n            PathEl::CurveTo(p, p2, p3) => p.is_finite() && p2.is_finite() && p3.is_finite(),\n            PathEl::ClosePath => true,\n        }\n    }\n\n    /// Is this path element NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        match self {\n            PathEl::MoveTo(p) => p.is_nan(),\n            PathEl::LineTo(p) => p.is_nan(),\n            PathEl::QuadTo(p, p2) => p.is_nan() || p2.is_nan(),\n            PathEl::CurveTo(p, p2, p3) => p.is_nan() || p2.is_nan() || p3.is_nan(),\n            PathEl::ClosePath => false,\n        }\n    }\n\n    /// Get the end point of the path element, if it exists.\n    pub fn end_point(&self) -> Option<Point> {\n        match self {\n            PathEl::MoveTo(p) => Some(*p),\n            PathEl::LineTo(p1) => Some(*p1),\n            PathEl::QuadTo(_, p2) => Some(*p2),\n            PathEl::CurveTo(_, _, p3) => Some(*p3),\n            _ => None,\n        }\n    }\n}\n\n/// Implements [`Shape`] for a slice of [`PathEl`], provided that the first element of the slice is\n/// not a `PathEl::ClosePath`. If it is, several of these functions will panic.\n///\n/// If the slice starts with `LineTo`, `QuadTo`, or `CurveTo`, it will be treated as a `MoveTo`.\nimpl<'a> Shape for &'a [PathEl] {\n    type PathElementsIter<'iter>\n\n    = core::iter::Copied<core::slice::Iter<'a, PathEl>> where 'a: 'iter;\n\n    #[inline]\n    fn path_elements(&self, _tolerance: f64) -> Self::PathElementsIter<'_> {\n        self.iter().copied()\n    }\n\n    fn to_path(&self, _tolerance: f64) -> BezPath {\n        BezPath::from_vec(self.to_vec())\n    }\n\n    /// Signed area.\n    fn area(&self) -> f64 {\n        segments(self.iter().copied()).area()\n    }\n\n    fn perimeter(&self, accuracy: f64) -> f64 {\n        segments(self.iter().copied()).perimeter(accuracy)\n    }\n\n    /// Winding number of point.\n    fn winding(&self, pt: Point) -> i32 {\n        segments(self.iter().copied()).winding(pt)\n    }\n\n    fn bounding_box(&self) -> Rect {\n        segments(self.iter().copied()).bounding_box()\n    }\n\n    #[inline]\n    fn as_path_slice(&self) -> Option<&[PathEl]> {\n        Some(self)\n    }\n}\n\n/// Implements [`Shape`] for an array of [`PathEl`], provided that the first element of the array is\n/// not a `PathEl::ClosePath`. If it is, several of these functions will panic.\n///\n/// If the array starts with `LineTo`, `QuadTo`, or `CurveTo`, it will be treated as a `MoveTo`.\nimpl<const N: usize> Shape for [PathEl; N] {\n    type PathElementsIter<'iter> = core::iter::Copied<core::slice::Iter<'iter, PathEl>>;\n\n    #[inline]\n    fn path_elements(&self, _tolerance: f64) -> Self::PathElementsIter<'_> {\n        self.iter().copied()\n    }\n\n    fn to_path(&self, _tolerance: f64) -> BezPath {\n        BezPath::from_vec(self.to_vec())\n    }\n\n    /// Signed area.\n    fn area(&self) -> f64 {\n        segments(self.iter().copied()).area()\n    }\n\n    fn perimeter(&self, accuracy: f64) -> f64 {\n        segments(self.iter().copied()).perimeter(accuracy)\n    }\n\n    /// Winding number of point.\n    fn winding(&self, pt: Point) -> i32 {\n        segments(self.iter().copied()).winding(pt)\n    }\n\n    fn bounding_box(&self) -> Rect {\n        segments(self.iter().copied()).bounding_box()\n    }\n\n    #[inline]\n    fn as_path_slice(&self) -> Option<&[PathEl]> {\n        Some(self)\n    }\n}\n\n/// An iterator for path segments.\npub struct PathSegIter {\n    seg: PathSeg,\n    ix: usize,\n}\n\nimpl Shape for PathSeg {\n    type PathElementsIter<'iter> = PathSegIter;\n\n    #[inline]\n    fn path_elements(&self, _tolerance: f64) -> PathSegIter {\n        PathSegIter { seg: *self, ix: 0 }\n    }\n\n    /// The area under the curve.\n    ///\n    /// We could just return `0`, but this seems more useful.\n    fn area(&self) -> f64 {\n        self.signed_area()\n    }\n\n    #[inline]\n    fn perimeter(&self, accuracy: f64) -> f64 {\n        self.arclen(accuracy)\n    }\n\n    fn winding(&self, _pt: Point) -> i32 {\n        0\n    }\n\n    #[inline]\n    fn bounding_box(&self) -> Rect {\n        ParamCurveExtrema::bounding_box(self)\n    }\n\n    fn as_line(&self) -> Option<Line> {\n        if let PathSeg::Line(line) = self {\n            Some(*line)\n        } else {\n            None\n        }\n    }\n}\n\nimpl Iterator for PathSegIter {\n    type Item = PathEl;\n\n    fn next(&mut self) -> Option<PathEl> {\n        self.ix += 1;\n        match (self.ix, self.seg) {\n            // yes I could do some fancy bindings thing here but... :shrug:\n            (1, PathSeg::Line(seg)) => Some(PathEl::MoveTo(seg.p0)),\n            (1, PathSeg::Quad(seg)) => Some(PathEl::MoveTo(seg.p0)),\n            (1, PathSeg::Cubic(seg)) => Some(PathEl::MoveTo(seg.p0)),\n            (2, PathSeg::Line(seg)) => Some(PathEl::LineTo(seg.p1)),\n            (2, PathSeg::Quad(seg)) => Some(PathEl::QuadTo(seg.p1, seg.p2)),\n            (2, PathSeg::Cubic(seg)) => Some(PathEl::CurveTo(seg.p1, seg.p2, seg.p3)),\n            _ => None,\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Circle, DEFAULT_ACCURACY};\n\n    use super::*;\n\n    fn assert_approx_eq(x: f64, y: f64) {\n        assert!((x - y).abs() < 1e-8, \"{x} != {y}\");\n    }\n\n    #[test]\n    #[should_panic(expected = \"no open subpath\")]\n    fn test_elements_to_segments_starts_on_closepath() {\n        let mut path = BezPath::new();\n        path.close_path();\n        path.segments().next();\n    }\n\n    #[test]\n    fn test_elements_to_segments_closepath_refers_to_last_moveto() {\n        let mut path = BezPath::new();\n        path.move_to((5.0, 5.0));\n        path.line_to((15.0, 15.0));\n        path.move_to((10.0, 10.0));\n        path.line_to((15.0, 15.0));\n        path.close_path();\n        assert_eq!(\n            path.segments().collect::<Vec<_>>().last(),\n            Some(&Line::new((15.0, 15.0), (10.0, 10.0)).into()),\n        );\n    }\n\n    #[test]\n    #[should_panic(expected = \"no open subpath\")]\n    fn test_must_not_start_on_quad() {\n        let mut path = BezPath::new();\n        path.quad_to((5.0, 5.0), (10.0, 10.0));\n        path.line_to((15.0, 15.0));\n        path.close_path();\n    }\n\n    #[test]\n    fn test_intersect_line() {\n        let h_line = Line::new((0.0, 0.0), (100.0, 0.0));\n        let v_line = Line::new((10.0, -10.0), (10.0, 10.0));\n        let intersection = PathSeg::Line(h_line).intersect_line(v_line)[0];\n        assert_approx_eq(intersection.segment_t, 0.1);\n        assert_approx_eq(intersection.line_t, 0.5);\n\n        let v_line = Line::new((-10.0, -10.0), (-10.0, 10.0));\n        assert!(PathSeg::Line(h_line).intersect_line(v_line).is_empty());\n\n        let v_line = Line::new((10.0, 10.0), (10.0, 20.0));\n        assert!(PathSeg::Line(h_line).intersect_line(v_line).is_empty());\n    }\n\n    #[test]\n    fn test_intersect_qad() {\n        let q = QuadBez::new((0.0, -10.0), (10.0, 20.0), (20.0, -10.0));\n        let v_line = Line::new((10.0, -10.0), (10.0, 10.0));\n        assert_eq!(PathSeg::Quad(q).intersect_line(v_line).len(), 1);\n        let intersection = PathSeg::Quad(q).intersect_line(v_line)[0];\n        assert_approx_eq(intersection.segment_t, 0.5);\n        assert_approx_eq(intersection.line_t, 0.75);\n\n        let h_line = Line::new((0.0, 0.0), (100.0, 0.0));\n        assert_eq!(PathSeg::Quad(q).intersect_line(h_line).len(), 2);\n    }\n\n    #[test]\n    fn test_intersect_cubic() {\n        let c = CubicBez::new((0.0, -10.0), (10.0, 20.0), (20.0, -20.0), (30.0, 10.0));\n        let v_line = Line::new((10.0, -10.0), (10.0, 10.0));\n        assert_eq!(PathSeg::Cubic(c).intersect_line(v_line).len(), 1);\n        let intersection = PathSeg::Cubic(c).intersect_line(v_line)[0];\n        assert_approx_eq(intersection.segment_t, 0.333333333);\n        assert_approx_eq(intersection.line_t, 0.592592592);\n\n        let h_line = Line::new((0.0, 0.0), (100.0, 0.0));\n        assert_eq!(PathSeg::Cubic(c).intersect_line(h_line).len(), 3);\n    }\n\n    #[test]\n    fn test_contains() {\n        let mut path = BezPath::new();\n        path.move_to((0.0, 0.0));\n        path.line_to((1.0, 1.0));\n        path.line_to((2.0, 0.0));\n        path.close_path();\n        assert_eq!(path.winding(Point::new(1.0, 0.5)), -1);\n        assert!(path.contains(Point::new(1.0, 0.5)));\n    }\n\n    // get_seg(i) should produce the same results as path_segments().nth(i - 1).\n    #[test]\n    fn test_get_seg() {\n        let circle = Circle::new((10.0, 10.0), 2.0).to_path(DEFAULT_ACCURACY);\n        let segments = circle.path_segments(DEFAULT_ACCURACY).collect::<Vec<_>>();\n        let get_segs = (1..usize::MAX)\n            .map_while(|i| circle.get_seg(i))\n            .collect::<Vec<_>>();\n        assert_eq!(segments, get_segs);\n    }\n\n    #[test]\n    fn test_control_box() {\n        // a sort of map ping looking thing drawn with a single cubic\n        // cbox is wildly different than tight box\n        let path = BezPath::from_svg(\"M200,300 C50,50 350,50 200,300\").unwrap();\n        assert_eq!(Rect::new(50.0, 50.0, 350.0, 300.0), path.control_box());\n        assert!(path.control_box().area() > path.bounding_box().area());\n    }\n\n    #[test]\n    fn test_reverse_unclosed() {\n        let path = BezPath::from_svg(\"M10,10 Q40,40 60,10 L100,10 C125,10 150,50 125,60\").unwrap();\n        let reversed = path.reverse_subpaths();\n        assert_eq!(\n            \"M125,60 C150,50 125,10 100,10 L60,10 Q40,40 10,10\",\n            reversed.to_svg()\n        );\n    }\n\n    #[test]\n    fn test_reverse_closed_triangle() {\n        let path = BezPath::from_svg(\"M100,100 L150,200 L50,200 Z\").unwrap();\n        let reversed = path.reverse_subpaths();\n        assert_eq!(\"M50,200 L150,200 L100,100 Z\", reversed.to_svg());\n    }\n\n    #[test]\n    fn test_reverse_closed_shape() {\n        let path = BezPath::from_svg(\n            \"M125,100 Q200,150 175,300 C150,150 50,150 25,300 Q0,150 75,100 L100,50 Z\",\n        )\n        .unwrap();\n        let reversed = path.reverse_subpaths();\n        assert_eq!(\n            \"M100,50 L75,100 Q0,150 25,300 C50,150 150,150 175,300 Q200,150 125,100 Z\",\n            reversed.to_svg()\n        );\n    }\n\n    #[test]\n    fn test_reverse_multiple_subpaths() {\n        let svg = \"M10,10 Q40,40 60,10 L100,10 C125,10 150,50 125,60 M100,100 L150,200 L50,200 Z M125,100 Q200,150 175,300 C150,150 50,150 25,300 Q0,150 75,100 L100,50 Z\";\n        let expected_svg = \"M125,60 C150,50 125,10 100,10 L60,10 Q40,40 10,10 M50,200 L150,200 L100,100 Z M100,50 L75,100 Q0,150 25,300 C50,150 150,150 175,300 Q200,150 125,100 Z\";\n        let path = BezPath::from_svg(svg).unwrap();\n        let reversed = path.reverse_subpaths();\n        assert_eq!(expected_svg, reversed.to_svg());\n    }\n\n    // https://github.com/fonttools/fonttools/blob/bf265ce49e0cae6f032420a4c80c31d8e16285b8/Tests/pens/reverseContourPen_test.py#L7\n    #[test]\n    fn test_reverse_lines() {\n        let mut path = BezPath::new();\n        path.move_to((0.0, 0.0));\n        path.line_to((1.0, 1.0));\n        path.line_to((2.0, 2.0));\n        path.line_to((3.0, 3.0));\n        path.close_path();\n        let rev = path.reverse_subpaths();\n        assert_eq!(\"M3,3 L2,2 L1,1 L0,0 Z\", rev.to_svg());\n    }\n\n    #[test]\n    fn test_reverse_multiple_moves() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((2.0, 2.0).into()),\n                PathEl::MoveTo((3.0, 3.0).into()),\n                PathEl::ClosePath,\n                PathEl::MoveTo((4.0, 4.0).into()),\n            ],\n            vec![\n                PathEl::MoveTo((2.0, 2.0).into()),\n                PathEl::MoveTo((3.0, 3.0).into()),\n                PathEl::ClosePath,\n                PathEl::MoveTo((4.0, 4.0).into()),\n            ],\n        )\n    }\n\n    // The following are direct port of fonttools'\n    // reverseContourPen_test.py::test_reverse_pen, adapted to rust, excluding\n    // test cases that don't apply because we don't implement\n    // outputImpliedClosingLine=False.\n    // https://github.com/fonttools/fonttools/blob/85c80be/Tests/pens/reverseContourPen_test.py#L6-L467\n\n    #[test]\n    fn test_reverse_closed_last_line_not_on_move() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()),\n                PathEl::LineTo((2.0, 2.0).into()),\n                PathEl::LineTo((3.0, 3.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((3.0, 3.0).into()),\n                PathEl::LineTo((2.0, 2.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()),\n                PathEl::LineTo((0.0, 0.0).into()), // closing line NOT implied\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_closed_last_line_overlaps_move() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()),\n                PathEl::LineTo((2.0, 2.0).into()),\n                PathEl::LineTo((0.0, 0.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::LineTo((2.0, 2.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()),\n                PathEl::LineTo((0.0, 0.0).into()), // closing line NOT implied\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_closed_duplicate_line_following_move() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::LineTo((0.0, 0.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()),\n                PathEl::LineTo((2.0, 2.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((2.0, 2.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()),\n                PathEl::LineTo((0.0, 0.0).into()), // duplicate line retained\n                PathEl::LineTo((0.0, 0.0).into()),\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_closed_two_lines() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((1.0, 1.0).into()),\n                PathEl::LineTo((0.0, 0.0).into()), // closing line NOT implied\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_closed_last_curve_overlaps_move() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::CurveTo((1.0, 1.0).into(), (2.0, 2.0).into(), (3.0, 3.0).into()),\n                PathEl::CurveTo((4.0, 4.0).into(), (5.0, 5.0).into(), (0.0, 0.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()), // no extra lineTo added here\n                PathEl::CurveTo((5.0, 5.0).into(), (4.0, 4.0).into(), (3.0, 3.0).into()),\n                PathEl::CurveTo((2.0, 2.0).into(), (1.0, 1.0).into(), (0.0, 0.0).into()),\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_closed_last_curve_not_on_move() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::CurveTo((1.0, 1.0).into(), (2.0, 2.0).into(), (3.0, 3.0).into()),\n                PathEl::CurveTo((4.0, 4.0).into(), (5.0, 5.0).into(), (6.0, 6.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((6.0, 6.0).into()), // the previously implied line\n                PathEl::CurveTo((5.0, 5.0).into(), (4.0, 4.0).into(), (3.0, 3.0).into()),\n                PathEl::CurveTo((2.0, 2.0).into(), (1.0, 1.0).into(), (0.0, 0.0).into()),\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_closed_line_curve_line() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()), // this line...\n                PathEl::CurveTo((2.0, 2.0).into(), (3.0, 3.0).into(), (4.0, 4.0).into()),\n                PathEl::CurveTo((5.0, 5.0).into(), (6.0, 6.0).into(), (7.0, 7.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((7.0, 7.0).into()),\n                PathEl::CurveTo((6.0, 6.0).into(), (5.0, 5.0).into(), (4.0, 4.0).into()),\n                PathEl::CurveTo((3.0, 3.0).into(), (2.0, 2.0).into(), (1.0, 1.0).into()),\n                PathEl::LineTo((0.0, 0.0).into()), // ... does NOT become implied\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_closed_last_quad_overlaps_move() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::QuadTo((1.0, 1.0).into(), (2.0, 2.0).into()),\n                PathEl::QuadTo((3.0, 3.0).into(), (0.0, 0.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()), // no extra lineTo added here\n                PathEl::QuadTo((3.0, 3.0).into(), (2.0, 2.0).into()),\n                PathEl::QuadTo((1.0, 1.0).into(), (0.0, 0.0).into()),\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_closed_last_quad_not_on_move() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::QuadTo((1.0, 1.0).into(), (2.0, 2.0).into()),\n                PathEl::QuadTo((3.0, 3.0).into(), (4.0, 4.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((4.0, 4.0).into()), // the previously implied line\n                PathEl::QuadTo((3.0, 3.0).into(), (2.0, 2.0).into()),\n                PathEl::QuadTo((1.0, 1.0).into(), (0.0, 0.0).into()),\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_closed_line_quad_line() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()), // this line...\n                PathEl::QuadTo((2.0, 2.0).into(), (3.0, 3.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((3.0, 3.0).into()),\n                PathEl::QuadTo((2.0, 2.0).into(), (1.0, 1.0).into()),\n                PathEl::LineTo((0.0, 0.0).into()), // ... does NOT become implied\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_empty() {\n        reverse_test_helper(vec![], vec![])\n    }\n\n    #[test]\n    fn test_reverse_single_point() {\n        reverse_test_helper(\n            vec![PathEl::MoveTo((0.0, 0.0).into())],\n            vec![PathEl::MoveTo((0.0, 0.0).into())],\n        )\n    }\n\n    #[test]\n    fn test_reverse_single_point_closed() {\n        reverse_test_helper(\n            vec![PathEl::MoveTo((0.0, 0.0).into()), PathEl::ClosePath],\n            vec![PathEl::MoveTo((0.0, 0.0).into()), PathEl::ClosePath],\n        )\n    }\n\n    #[test]\n    fn test_reverse_single_line_open() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()),\n            ],\n            vec![\n                PathEl::MoveTo((1.0, 1.0).into()),\n                PathEl::LineTo((0.0, 0.0).into()),\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_single_curve_open() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::CurveTo((1.0, 1.0).into(), (2.0, 2.0).into(), (3.0, 3.0).into()),\n            ],\n            vec![\n                PathEl::MoveTo((3.0, 3.0).into()),\n                PathEl::CurveTo((2.0, 2.0).into(), (1.0, 1.0).into(), (0.0, 0.0).into()),\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_curve_line_open() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::CurveTo((1.0, 1.0).into(), (2.0, 2.0).into(), (3.0, 3.0).into()),\n                PathEl::LineTo((4.0, 4.0).into()),\n            ],\n            vec![\n                PathEl::MoveTo((4.0, 4.0).into()),\n                PathEl::LineTo((3.0, 3.0).into()),\n                PathEl::CurveTo((2.0, 2.0).into(), (1.0, 1.0).into(), (0.0, 0.0).into()),\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_line_curve_open() {\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 0.0).into()),\n                PathEl::LineTo((1.0, 1.0).into()),\n                PathEl::CurveTo((2.0, 2.0).into(), (3.0, 3.0).into(), (4.0, 4.0).into()),\n            ],\n            vec![\n                PathEl::MoveTo((4.0, 4.0).into()),\n                PathEl::CurveTo((3.0, 3.0).into(), (2.0, 2.0).into(), (1.0, 1.0).into()),\n                PathEl::LineTo((0.0, 0.0).into()),\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_duplicate_point_after_move() {\n        // Test case from: https://github.com/googlei18n/cu2qu/issues/51#issue-179370514\n        // Simplified to only use atomic PathEl::QuadTo (no QuadSplines).\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((848.0, 348.0).into()),\n                PathEl::LineTo((848.0, 348.0).into()),\n                PathEl::QuadTo((848.0, 526.0).into(), (449.0, 704.0).into()),\n                PathEl::QuadTo((848.0, 171.0).into(), (848.0, 348.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((848.0, 348.0).into()),\n                PathEl::QuadTo((848.0, 171.0).into(), (449.0, 704.0).into()),\n                PathEl::QuadTo((848.0, 526.0).into(), (848.0, 348.0).into()),\n                PathEl::LineTo((848.0, 348.0).into()),\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    #[test]\n    fn test_reverse_duplicate_point_at_end() {\n        // Test case from: https://github.com/googlefonts/fontmake/issues/572\n        reverse_test_helper(\n            vec![\n                PathEl::MoveTo((0.0, 651.0).into()),\n                PathEl::LineTo((0.0, 101.0).into()),\n                PathEl::LineTo((0.0, 101.0).into()),\n                PathEl::LineTo((0.0, 651.0).into()),\n                PathEl::LineTo((0.0, 651.0).into()),\n                PathEl::ClosePath,\n            ],\n            vec![\n                PathEl::MoveTo((0.0, 651.0).into()),\n                PathEl::LineTo((0.0, 651.0).into()),\n                PathEl::LineTo((0.0, 101.0).into()),\n                PathEl::LineTo((0.0, 101.0).into()),\n                PathEl::LineTo((0.0, 651.0).into()),\n                PathEl::ClosePath,\n            ],\n        )\n    }\n\n    fn reverse_test_helper(contour: Vec<PathEl>, expected: Vec<PathEl>) {\n        assert_eq!(BezPath(contour).reverse_subpaths().0, expected);\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/circle.rs",
      "sha256": "cedf586b744630a3b745b4025157df8f10d7de9540c4090d8a41e57fbbb105ab",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Implementation of circle shape.\n\nuse core::{\n    f64::consts::{FRAC_PI_2, PI},\n    iter,\n    ops::{Add, Mul, Sub},\n};\n\nuse crate::{Affine, Arc, ArcAppendIter, Ellipse, PathEl, Point, Rect, Shape, Vec2};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A circle.\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Circle {\n    /// The center.\n    pub center: Point,\n    /// The radius.\n    pub radius: f64,\n}\n\nimpl Circle {\n    /// A new circle from center and radius.\n    #[inline]\n    pub fn new(center: impl Into<Point>, radius: f64) -> Circle {\n        Circle {\n            center: center.into(),\n            radius,\n        }\n    }\n\n    /// Create a [`CircleSegment`] by cutting out parts of this circle.\n    pub fn segment(self, inner_radius: f64, start_angle: f64, sweep_angle: f64) -> CircleSegment {\n        CircleSegment {\n            center: self.center,\n            outer_radius: self.radius,\n            inner_radius,\n            start_angle,\n            sweep_angle,\n        }\n    }\n\n    /// Is this circle finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.center.is_finite() && self.radius.is_finite()\n    }\n\n    /// Is this circle NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.center.is_nan() || self.radius.is_nan()\n    }\n}\n\nimpl Add<Vec2> for Circle {\n    type Output = Circle;\n\n    #[inline]\n    fn add(self, v: Vec2) -> Circle {\n        Circle {\n            center: self.center + v,\n            radius: self.radius,\n        }\n    }\n}\n\nimpl Sub<Vec2> for Circle {\n    type Output = Circle;\n\n    #[inline]\n    fn sub(self, v: Vec2) -> Circle {\n        Circle {\n            center: self.center - v,\n            radius: self.radius,\n        }\n    }\n}\n\nimpl Mul<Circle> for Affine {\n    type Output = Ellipse;\n    fn mul(self, other: Circle) -> Self::Output {\n        self * Ellipse::from(other)\n    }\n}\n\n#[doc(hidden)]\npub struct CirclePathIter {\n    circle: Circle,\n    delta_th: f64,\n    arm_len: f64,\n    ix: usize,\n    n: usize,\n}\n\nimpl Shape for Circle {\n    type PathElementsIter<'iter> = CirclePathIter;\n\n    fn path_elements(&self, tolerance: f64) -> CirclePathIter {\n        let scaled_err = self.radius.abs() / tolerance;\n        let (n, arm_len) = if scaled_err < 1.0 / 1.9608e-4 {\n            // Solution from http://spencermortensen.com/articles/bezier-circle/\n            (4, 0.551915024494)\n        } else {\n            // This is empirically determined to fall within error tolerance.\n            let n = (1.1163 * scaled_err).powf(1.0 / 6.0).ceil() as usize;\n            // Note: this isn't minimum error, but it is simple and we can easily\n            // estimate the error.\n            let arm_len = (4.0 / 3.0) * (FRAC_PI_2 / (n as f64)).tan();\n            (n, arm_len)\n        };\n        CirclePathIter {\n            circle: *self,\n            delta_th: 2.0 * PI / (n as f64),\n            arm_len,\n            ix: 0,\n            n,\n        }\n    }\n\n    #[inline]\n    fn area(&self) -> f64 {\n        PI * self.radius.powi(2)\n    }\n\n    #[inline]\n    fn perimeter(&self, _accuracy: f64) -> f64 {\n        (2.0 * PI * self.radius).abs()\n    }\n\n    fn winding(&self, pt: Point) -> i32 {\n        if (pt - self.center).hypot2() < self.radius.powi(2) {\n            1\n        } else {\n            0\n        }\n    }\n\n    #[inline]\n    fn bounding_box(&self) -> Rect {\n        let r = self.radius.abs();\n        let (x, y) = self.center.into();\n        Rect::new(x - r, y - r, x + r, y + r)\n    }\n\n    fn as_circle(&self) -> Option<Circle> {\n        Some(*self)\n    }\n}\n\nimpl Iterator for CirclePathIter {\n    type Item = PathEl;\n\n    fn next(&mut self) -> Option<PathEl> {\n        let a = self.arm_len;\n        let r = self.circle.radius;\n        let (x, y) = self.circle.center.into();\n        let ix = self.ix;\n        self.ix += 1;\n        if ix == 0 {\n            Some(PathEl::MoveTo(Point::new(x + r, y)))\n        } else if ix <= self.n {\n            let th1 = self.delta_th * (ix as f64);\n            let th0 = th1 - self.delta_th;\n            let (s0, c0) = th0.sin_cos();\n            let (s1, c1) = if ix == self.n {\n                (0.0, 1.0)\n            } else {\n                th1.sin_cos()\n            };\n            Some(PathEl::CurveTo(\n                Point::new(x + r * (c0 - a * s0), y + r * (s0 + a * c0)),\n                Point::new(x + r * (c1 + a * s1), y + r * (s1 - a * c1)),\n                Point::new(x + r * c1, y + r * s1),\n            ))\n        } else if ix == self.n + 1 {\n            Some(PathEl::ClosePath)\n        } else {\n            None\n        }\n    }\n}\n\n/// A segment of a circle.\n///\n/// If `inner_radius > 0`, then the shape will be a doughnut segment.\npub struct CircleSegment {\n    /// The center.\n    pub center: Point,\n    /// The outer radius.\n    pub outer_radius: f64,\n    /// The inner radius.\n    pub inner_radius: f64,\n    /// The angle to start drawing the segment (in radians).\n    pub start_angle: f64,\n    /// The arc length of the segment (in radians).\n    pub sweep_angle: f64,\n}\n\nimpl CircleSegment {\n    /// Create a `CircleSegment` out of its constituent parts.\n    pub fn new(\n        center: impl Into<Point>,\n        outer_radius: f64,\n        inner_radius: f64,\n        start_angle: f64,\n        sweep_angle: f64,\n    ) -> Self {\n        CircleSegment {\n            center: center.into(),\n            outer_radius,\n            inner_radius,\n            start_angle,\n            sweep_angle,\n        }\n    }\n\n    /// Is this circle segment finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.center.is_finite()\n            && self.outer_radius.is_finite()\n            && self.inner_radius.is_finite()\n            && self.start_angle.is_finite()\n            && self.sweep_angle.is_finite()\n    }\n\n    /// Is this circle segment NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.center.is_nan()\n            || self.outer_radius.is_nan()\n            || self.inner_radius.is_nan()\n            || self.start_angle.is_nan()\n            || self.sweep_angle.is_nan()\n    }\n}\n\nimpl Add<Vec2> for CircleSegment {\n    type Output = CircleSegment;\n\n    #[inline]\n    fn add(self, v: Vec2) -> Self {\n        Self {\n            center: self.center + v,\n            ..self\n        }\n    }\n}\n\nimpl Sub<Vec2> for CircleSegment {\n    type Output = CircleSegment;\n\n    #[inline]\n    fn sub(self, v: Vec2) -> Self {\n        Self {\n            center: self.center - v,\n            ..self\n        }\n    }\n}\n\ntype CircleSegmentPathIter = iter::Chain<\n    iter::Chain<\n        iter::Chain<iter::Chain<iter::Once<PathEl>, iter::Once<PathEl>>, ArcAppendIter>,\n        iter::Once<PathEl>,\n    >,\n    ArcAppendIter,\n>;\n\nimpl Shape for CircleSegment {\n    type PathElementsIter<'iter> = CircleSegmentPathIter;\n\n    fn path_elements(&self, tolerance: f64) -> CircleSegmentPathIter {\n        iter::once(PathEl::MoveTo(point_on_circle(\n            self.center,\n            self.inner_radius,\n            self.start_angle,\n        )))\n        // First radius\n        .chain(iter::once(PathEl::LineTo(point_on_circle(\n            self.center,\n            self.outer_radius,\n            self.start_angle,\n        ))))\n        // outer arc\n        .chain(\n            Arc {\n                center: self.center,\n                radii: Vec2::new(self.outer_radius, self.outer_radius),\n                start_angle: self.start_angle,\n                sweep_angle: self.sweep_angle,\n                x_rotation: 0.0,\n            }\n            .append_iter(tolerance),\n        )\n        // second radius\n        .chain(iter::once(PathEl::LineTo(point_on_circle(\n            self.center,\n            self.inner_radius,\n            self.start_angle + self.sweep_angle,\n        ))))\n        // inner arc\n        .chain(\n            Arc {\n                center: self.center,\n                radii: Vec2::new(self.inner_radius, self.inner_radius),\n                start_angle: self.start_angle + self.sweep_angle,\n                sweep_angle: -self.sweep_angle,\n                x_rotation: 0.0,\n            }\n            .append_iter(tolerance),\n        )\n    }\n\n    #[inline]\n    fn area(&self) -> f64 {\n        0.5 * (self.outer_radius.powi(2) - self.inner_radius.powi(2)).abs() * self.sweep_angle\n    }\n\n    #[inline]\n    fn perimeter(&self, _accuracy: f64) -> f64 {\n        2.0 * (self.outer_radius - self.inner_radius).abs()\n            + self.sweep_angle * (self.inner_radius + self.outer_radius)\n    }\n\n    fn winding(&self, pt: Point) -> i32 {\n        let angle = (pt - self.center).atan2();\n        if angle < self.start_angle || angle > self.start_angle + self.sweep_angle {\n            return 0;\n        }\n        let dist2 = (pt - self.center).hypot2();\n        if (dist2 < self.outer_radius.powi(2) && dist2 > self.inner_radius.powi(2)) ||\n            // case where outer_radius < inner_radius\n            (dist2 < self.inner_radius.powi(2) && dist2 > self.outer_radius.powi(2))\n        {\n            1\n        } else {\n            0\n        }\n    }\n\n    #[inline]\n    fn bounding_box(&self) -> Rect {\n        // todo this is currently not tight\n        let r = self.inner_radius.max(self.outer_radius);\n        let (x, y) = self.center.into();\n        Rect::new(x - r, y - r, x + r, y + r)\n    }\n}\n\n#[inline]\nfn point_on_circle(center: Point, radius: f64, angle: f64) -> Point {\n    let (angle_sin, angle_cos) = angle.sin_cos();\n    center\n        + Vec2 {\n            x: angle_cos * radius,\n            y: angle_sin * radius,\n        }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Circle, Point, Shape};\n    use std::f64::consts::PI;\n\n    fn assert_approx_eq(x: f64, y: f64) {\n        // Note: we might want to be more rigorous in testing the accuracy\n        // of the conversion into Béziers. But this seems good enough.\n        assert!((x - y).abs() < 1e-7, \"{x} != {y}\");\n    }\n\n    #[test]\n    fn area_sign() {\n        let center = Point::new(5.0, 5.0);\n        let c = Circle::new(center, 5.0);\n        assert_approx_eq(c.area(), 25.0 * PI);\n\n        assert_eq!(c.winding(center), 1);\n\n        let p = c.to_path(1e-9);\n        assert_approx_eq(c.area(), p.area());\n        assert_eq!(c.winding(center), p.winding(center));\n\n        let c_neg_radius = Circle::new(center, -5.0);\n        assert_approx_eq(c_neg_radius.area(), 25.0 * PI);\n\n        assert_eq!(c_neg_radius.winding(center), 1);\n\n        let p_neg_radius = c_neg_radius.to_path(1e-9);\n        assert_approx_eq(c_neg_radius.area(), p_neg_radius.area());\n        assert_eq!(c_neg_radius.winding(center), p_neg_radius.winding(center));\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/common.rs",
      "sha256": "8a90e233ad3fcaeb2fe0fd73f65b6e8dd77bc7e97c6db6a8cc9fdb1d486a6b9f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Common mathematical operations\n\n#![allow(missing_docs)]\n\nuse arrayvec::ArrayVec;\n\n/// Defines a trait that chooses between libstd or libm implementations of float methods.\nmacro_rules! define_float_funcs {\n    ($(\n        fn $name:ident(self $(,$arg:ident: $arg_ty:ty)*) -> $ret:ty\n        => $lname:ident/$lfname:ident;\n    )+) => {\n        #[cfg(not(feature = \"std\"))]\n        pub(crate) trait FloatFuncs : Sized {\n            /// Special implementation for signum, because libm doesn't have it.\n            fn signum(self) -> Self;\n\n            $(fn $name(self $(,$arg: $arg_ty)*) -> $ret;)+\n        }\n\n        #[cfg(not(feature = \"std\"))]\n        impl FloatFuncs for f32 {\n            #[inline]\n            fn signum(self) -> f32 {\n                if self.is_nan() {\n                    f32::NAN\n                } else {\n                    1.0_f32.copysign(self)\n                }\n            }\n\n            $(fn $name(self $(,$arg: $arg_ty)*) -> $ret {\n                #[cfg(feature = \"libm\")]\n                return libm::$lfname(self $(,$arg as _)*);\n\n                #[cfg(not(feature = \"libm\"))]\n                compile_error!(\"kurbo requires either the `std` or `libm` feature\")\n            })+\n        }\n\n        #[cfg(not(feature = \"std\"))]\n        impl FloatFuncs for f64 {\n            #[inline]\n            fn signum(self) -> f64 {\n                if self.is_nan() {\n                    f64::NAN\n                } else {\n                    1.0_f64.copysign(self)\n                }\n            }\n\n            $(fn $name(self $(,$arg: $arg_ty)*) -> $ret {\n                #[cfg(feature = \"libm\")]\n                return libm::$lname(self $(,$arg as _)*);\n\n                #[cfg(not(feature = \"libm\"))]\n                compile_error!(\"kurbo requires either the `std` or `libm` feature\")\n            })+\n        }\n    }\n}\n\ndefine_float_funcs! {\n    fn abs(self) -> Self => fabs/fabsf;\n    fn acos(self) -> Self => acos/acosf;\n    fn atan2(self, other: Self) -> Self => atan2/atan2f;\n    fn cbrt(self) -> Self => cbrt/cbrtf;\n    fn ceil(self) -> Self => ceil/ceilf;\n    fn cos(self) -> Self => cos/cosf;\n    fn copysign(self, sign: Self) -> Self => copysign/copysignf;\n    fn floor(self) -> Self => floor/floorf;\n    fn hypot(self, other: Self) -> Self => hypot/hypotf;\n    fn ln(self) -> Self => log/logf;\n    fn log2(self) -> Self => log2/log2f;\n    fn mul_add(self, a: Self, b: Self) -> Self => fma/fmaf;\n    fn powi(self, n: i32) -> Self => pow/powf;\n    fn powf(self, n: Self) -> Self => pow/powf;\n    fn round(self) -> Self => round/roundf;\n    fn sin_cos(self) -> (Self, Self) => sincos/sincosf;\n    fn sqrt(self) -> Self => sqrt/sqrtf;\n    fn tan(self) -> Self => tan/tanf;\n    fn trunc(self) -> Self => trunc/truncf;\n}\n\n/// Adds convenience methods to `f32` and `f64`.\npub trait FloatExt<T> {\n    /// Rounds to the nearest integer away from zero,\n    /// unless the provided value is already an integer.\n    ///\n    /// It is to `ceil` what `trunc` is to `floor`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::common::FloatExt;\n    ///\n    /// let f = 3.7_f64;\n    /// let g = 3.0_f64;\n    /// let h = -3.7_f64;\n    /// let i = -5.1_f32;\n    ///\n    /// assert_eq!(f.expand(), 4.0);\n    /// assert_eq!(g.expand(), 3.0);\n    /// assert_eq!(h.expand(), -4.0);\n    /// assert_eq!(i.expand(), -6.0);\n    /// ```\n    fn expand(&self) -> T;\n}\n\nimpl FloatExt<f64> for f64 {\n    #[inline]\n    fn expand(&self) -> f64 {\n        self.abs().ceil().copysign(*self)\n    }\n}\n\nimpl FloatExt<f32> for f32 {\n    #[inline]\n    fn expand(&self) -> f32 {\n        self.abs().ceil().copysign(*self)\n    }\n}\n\n/// Find real roots of cubic equation.\n///\n/// The implementation is not (yet) fully robust, but it does handle the case\n/// where `c3` is zero (in that case, solving the quadratic equation).\n///\n/// See: <https://momentsingraphics.de/CubicRoots.html>\n///\n/// That implementation is in turn based on Jim Blinn's \"How to Solve a Cubic\n/// Equation\", which is masterful.\n///\n/// Return values of x for which c0 + c1 x + c2 x² + c3 x³ = 0.\npub fn solve_cubic(c0: f64, c1: f64, c2: f64, c3: f64) -> ArrayVec<f64, 3> {\n    let mut result = ArrayVec::new();\n    let c3_recip = c3.recip();\n    const ONETHIRD: f64 = 1. / 3.;\n    let scaled_c2 = c2 * (ONETHIRD * c3_recip);\n    let scaled_c1 = c1 * (ONETHIRD * c3_recip);\n    let scaled_c0 = c0 * c3_recip;\n    if !(scaled_c0.is_finite() && scaled_c1.is_finite() && scaled_c2.is_finite()) {\n        // cubic coefficient is zero or nearly so.\n        return solve_quadratic(c0, c1, c2).iter().copied().collect();\n    }\n    let (c0, c1, c2) = (scaled_c0, scaled_c1, scaled_c2);\n    // (d0, d1, d2) is called \"Delta\" in article\n    let d0 = (-c2).mul_add(c2, c1);\n    let d1 = (-c1).mul_add(c2, c0);\n    let d2 = c2 * c0 - c1 * c1;\n    // d is called \"Discriminant\"\n    let d = 4.0 * d0 * d2 - d1 * d1;\n    // de is called \"Depressed.x\", Depressed.y = d0\n    let de = (-2.0 * c2).mul_add(d0, d1);\n    // TODO: handle the cases where these intermediate results overflow.\n    if d < 0.0 {\n        let sq = (-0.25 * d).sqrt();\n        let r = -0.5 * de;\n        let t1 = (r + sq).cbrt() + (r - sq).cbrt();\n        result.push(t1 - c2);\n    } else if d == 0.0 {\n        let t1 = (-d0).sqrt().copysign(de);\n        result.push(t1 - c2);\n        result.push(-2.0 * t1 - c2);\n    } else {\n        let th = d.sqrt().atan2(-de) * ONETHIRD;\n        // (th_cos, th_sin) is called \"CubicRoot\"\n        let (th_sin, th_cos) = th.sin_cos();\n        // (r0, r1, r2) is called \"Root\"\n        let r0 = th_cos;\n        let ss3 = th_sin * 3.0f64.sqrt();\n        let r1 = 0.5 * (-th_cos + ss3);\n        let r2 = 0.5 * (-th_cos - ss3);\n        let t = 2.0 * (-d0).sqrt();\n        result.push(t.mul_add(r0, -c2));\n        result.push(t.mul_add(r1, -c2));\n        result.push(t.mul_add(r2, -c2));\n    }\n    result\n}\n\n/// Find real roots of quadratic equation.\n///\n/// Return values of x for which c0 + c1 x + c2 x² = 0.\n///\n/// This function tries to be quite numerically robust. If the equation\n/// is nearly linear, it will return the root ignoring the quadratic term;\n/// the other root might be out of representable range. In the degenerate\n/// case where all coefficients are zero, so that all values of x satisfy\n/// the equation, a single `0.0` is returned.\npub fn solve_quadratic(c0: f64, c1: f64, c2: f64) -> ArrayVec<f64, 2> {\n    let mut result = ArrayVec::new();\n    let sc0 = c0 * c2.recip();\n    let sc1 = c1 * c2.recip();\n    if !sc0.is_finite() || !sc1.is_finite() {\n        // c2 is zero or very small, treat as linear eqn\n        let root = -c0 / c1;\n        if root.is_finite() {\n            result.push(root);\n        } else if c0 == 0.0 && c1 == 0.0 {\n            // Degenerate case\n            result.push(0.0);\n        }\n        return result;\n    }\n    let arg = sc1 * sc1 - 4. * sc0;\n    let root1 = if !arg.is_finite() {\n        // Likely, calculation of sc1 * sc1 overflowed. Find one root\n        // using sc1 x + x² = 0, other root as sc0 / root1.\n        -sc1\n    } else {\n        if arg < 0.0 {\n            return result;\n        } else if arg == 0.0 {\n            result.push(-0.5 * sc1);\n            return result;\n        }\n        // See https://math.stackexchange.com/questions/866331\n        -0.5 * (sc1 + arg.sqrt().copysign(sc1))\n    };\n    let root2 = sc0 / root1;\n    if root2.is_finite() {\n        // Sort just to be friendly and make results deterministic.\n        if root2 > root1 {\n            result.push(root1);\n            result.push(root2);\n        } else {\n            result.push(root2);\n            result.push(root1);\n        }\n    } else {\n        result.push(root1);\n    }\n    result\n}\n\n/// Compute epsilon relative to coefficient.\n///\n/// A helper function from the Orellana and De Michele paper.\nfn eps_rel(raw: f64, a: f64) -> f64 {\n    if a == 0.0 {\n        raw.abs()\n    } else {\n        ((raw - a) / a).abs()\n    }\n}\n\n/// Find real roots of a quartic equation.\n///\n/// This is a fairly literal implementation of the method described in:\n/// Algorithm 1010: Boosting Efficiency in Solving Quartic Equations with\n/// No Compromise in Accuracy, Orellana and De Michele, ACM\n/// Transactions on Mathematical Software, Vol. 46, No. 2, May 2020.\npub fn solve_quartic(c0: f64, c1: f64, c2: f64, c3: f64, c4: f64) -> ArrayVec<f64, 4> {\n    if c4 == 0.0 {\n        return solve_cubic(c0, c1, c2, c3).iter().copied().collect();\n    }\n    if c0 == 0.0 {\n        // Note: appends 0 root at end, doesn't sort. We might want to do that.\n        return solve_cubic(c1, c2, c3, c4)\n            .iter()\n            .copied()\n            .chain(Some(0.0))\n            .collect();\n    }\n    let a = c3 / c4;\n    let b = c2 / c4;\n    let c = c1 / c4;\n    let d = c0 / c4;\n    if let Some(result) = solve_quartic_inner(a, b, c, d, false) {\n        return result;\n    }\n    // Do polynomial rescaling\n    const K_Q: f64 = 7.16e76;\n    for rescale in [false, true] {\n        if let Some(result) = solve_quartic_inner(\n            a / K_Q,\n            b / K_Q.powi(2),\n            c / K_Q.powi(3),\n            d / K_Q.powi(4),\n            rescale,\n        ) {\n            return result.iter().map(|x| x * K_Q).collect();\n        }\n    }\n    // Overflow happened, just return no roots.\n    //println!(\"overflow, no roots returned\");\n    Default::default()\n}\n\nfn solve_quartic_inner(a: f64, b: f64, c: f64, d: f64, rescale: bool) -> Option<ArrayVec<f64, 4>> {\n    factor_quartic_inner(a, b, c, d, rescale).map(|quadratics| {\n        quadratics\n            .iter()\n            .flat_map(|(a, b)| solve_quadratic(*b, *a, 1.0))\n            .collect()\n    })\n}\n\n/// Factor a quartic into two quadratics.\n///\n/// Attempt to factor a quartic equation into two quadratic equations. Returns `None` either if there\n/// is overflow (in which case rescaling might succeed) or the factorization would result in\n/// complex coefficients.\n///\n/// Discussion question: distinguish the two cases in return value?\npub fn factor_quartic_inner(\n    a: f64,\n    b: f64,\n    c: f64,\n    d: f64,\n    rescale: bool,\n) -> Option<ArrayVec<(f64, f64), 2>> {\n    let calc_eps_q = |a1, b1, a2, b2| {\n        let eps_a = eps_rel(a1 + a2, a);\n        let eps_b = eps_rel(b1 + a1 * a2 + b2, b);\n        let eps_c = eps_rel(b1 * a2 + a1 * b2, c);\n        eps_a + eps_b + eps_c\n    };\n    let calc_eps_t = |a1, b1, a2, b2| calc_eps_q(a1, b1, a2, b2) + eps_rel(b1 * b2, d);\n    let disc = 9. * a * a - 24. * b;\n    let s = if disc >= 0.0 {\n        -2. * b / (3. * a + disc.sqrt().copysign(a))\n    } else {\n        -0.25 * a\n    };\n    let a_prime = a + 4. * s;\n    let b_prime = b + 3. * s * (a + 2. * s);\n    let c_prime = c + s * (2. * b + s * (3. * a + 4. * s));\n    let d_prime = d + s * (c + s * (b + s * (a + s)));\n    let g_prime;\n    let h_prime;\n    const K_C: f64 = 3.49e102;\n    if rescale {\n        let a_prime_s = a_prime / K_C;\n        let b_prime_s = b_prime / K_C;\n        let c_prime_s = c_prime / K_C;\n        let d_prime_s = d_prime / K_C;\n        g_prime = a_prime_s * c_prime_s - (4. / K_C) * d_prime_s - (1. / 3.) * b_prime_s.powi(2);\n        h_prime = (a_prime_s * c_prime_s + (8. / K_C) * d_prime_s - (2. / 9.) * b_prime_s.powi(2))\n            * (1. / 3.)\n            * b_prime_s\n            - c_prime_s * (c_prime_s / K_C)\n            - a_prime_s.powi(2) * d_prime_s;\n    } else {\n        g_prime = a_prime * c_prime - 4. * d_prime - (1. / 3.) * b_prime.powi(2);\n        h_prime =\n            (a_prime * c_prime + 8. * d_prime - (2. / 9.) * b_prime.powi(2)) * (1. / 3.) * b_prime\n                - c_prime.powi(2)\n                - a_prime.powi(2) * d_prime;\n    }\n    if !(g_prime.is_finite() && h_prime.is_finite()) {\n        return None;\n    }\n    let phi = depressed_cubic_dominant(g_prime, h_prime);\n    let phi = if rescale { phi * K_C } else { phi };\n    let l_1 = a * 0.5;\n    let l_3 = (1. / 6.) * b + 0.5 * phi;\n    let delt_2 = c - a * l_3;\n    let d_2_cand_1 = (2. / 3.) * b - phi - l_1 * l_1;\n    let l_2_cand_1 = 0.5 * delt_2 / d_2_cand_1;\n    let l_2_cand_2 = 2. * (d - l_3 * l_3) / delt_2;\n    let d_2_cand_2 = 0.5 * delt_2 / l_2_cand_2;\n    let d_2_cand_3 = d_2_cand_1;\n    let l_2_cand_3 = l_2_cand_2;\n    let mut d_2_best = 0.0;\n    let mut l_2_best = 0.0;\n    let mut eps_l_best = 0.0;\n    for (i, (d_2, l_2)) in [\n        (d_2_cand_1, l_2_cand_1),\n        (d_2_cand_2, l_2_cand_2),\n        (d_2_cand_3, l_2_cand_3),\n    ]\n    .iter()\n    .enumerate()\n    {\n        let eps_0 = eps_rel(d_2 + l_1 * l_1 + 2. * l_3, b);\n        let eps_1 = eps_rel(2. * (d_2 * l_2 + l_1 * l_3), c);\n        let eps_2 = eps_rel(d_2 * l_2 * l_2 + l_3 * l_3, d);\n        let eps_l = eps_0 + eps_1 + eps_2;\n        if i == 0 || eps_l < eps_l_best {\n            d_2_best = *d_2;\n            l_2_best = *l_2;\n            eps_l_best = eps_l;\n        }\n    }\n    let d_2 = d_2_best;\n    let l_2 = l_2_best;\n    let mut alpha_1;\n    let mut beta_1;\n    let mut alpha_2;\n    let mut beta_2;\n    //println!(\"phi = {}, d_2 = {}\", phi, d_2);\n    if d_2 < 0.0 {\n        let sq = (-d_2).sqrt();\n        alpha_1 = l_1 + sq;\n        beta_1 = l_3 + sq * l_2;\n        alpha_2 = l_1 - sq;\n        beta_2 = l_3 - sq * l_2;\n        if beta_2.abs() < beta_1.abs() {\n            beta_2 = d / beta_1;\n        } else if beta_2.abs() > beta_1.abs() {\n            beta_1 = d / beta_2;\n        }\n        let cands;\n        if alpha_1.abs() != alpha_2.abs() {\n            if alpha_1.abs() < alpha_2.abs() {\n                let a1_cand_1 = (c - beta_1 * alpha_2) / beta_2;\n                let a1_cand_2 = (b - beta_2 - beta_1) / alpha_2;\n                let a1_cand_3 = a - alpha_2;\n                // Note: cand 3 is first because it is infallible, simplifying logic\n                cands = [\n                    (a1_cand_3, alpha_2),\n                    (a1_cand_1, alpha_2),\n                    (a1_cand_2, alpha_2),\n                ];\n            } else {\n                let a2_cand_1 = (c - alpha_1 * beta_2) / beta_1;\n                let a2_cand_2 = (b - beta_2 - beta_1) / alpha_1;\n                let a2_cand_3 = a - alpha_1;\n                cands = [\n                    (alpha_1, a2_cand_3),\n                    (alpha_1, a2_cand_1),\n                    (alpha_1, a2_cand_2),\n                ];\n            }\n            let mut eps_q_best = 0.0;\n            for (i, (a1, a2)) in cands.iter().enumerate() {\n                if a1.is_finite() && a2.is_finite() {\n                    let eps_q = calc_eps_q(*a1, beta_1, *a2, beta_2);\n                    if i == 0 || eps_q < eps_q_best {\n                        alpha_1 = *a1;\n                        alpha_2 = *a2;\n                        eps_q_best = eps_q;\n                    }\n                }\n            }\n        }\n    } else if d_2 == 0.0 {\n        let d_3 = d - l_3 * l_3;\n        alpha_1 = l_1;\n        beta_1 = l_3 + (-d_3).sqrt();\n        alpha_2 = l_1;\n        beta_2 = l_3 - (-d_3).sqrt();\n        if beta_1.abs() > beta_2.abs() {\n            beta_2 = d / beta_1;\n        } else if beta_2.abs() > beta_1.abs() {\n            beta_1 = d / beta_2;\n        }\n        // TODO: handle case d_2 is very small?\n    } else {\n        // This case means no real roots; in the most general case we might want\n        // to factor into quadratic equations with complex coefficients.\n        return None;\n    }\n    // Newton-Raphson iteration on alpha/beta coeff's.\n    let mut eps_t = calc_eps_t(alpha_1, beta_1, alpha_2, beta_2);\n    for _ in 0..8 {\n        //println!(\"a1 {} b1 {} a2 {} b2 {}\", alpha_1, beta_1, alpha_2, beta_2);\n        //println!(\"eps_t = {:e}\", eps_t);\n        if eps_t == 0.0 {\n            break;\n        }\n        let f_0 = beta_1 * beta_2 - d;\n        let f_1 = beta_1 * alpha_2 + alpha_1 * beta_2 - c;\n        let f_2 = beta_1 + alpha_1 * alpha_2 + beta_2 - b;\n        let f_3 = alpha_1 + alpha_2 - a;\n        let c_1 = alpha_1 - alpha_2;\n        let det_j = beta_1 * beta_1 - beta_1 * (alpha_2 * c_1 + 2. * beta_2)\n            + beta_2 * (alpha_1 * c_1 + beta_2);\n        if det_j == 0.0 {\n            break;\n        }\n        let inv = det_j.recip();\n        let c_2 = beta_2 - beta_1;\n        let c_3 = beta_1 * alpha_2 - alpha_1 * beta_2;\n        let dz_0 = c_1 * f_0 + c_2 * f_1 + c_3 * f_2 - (beta_1 * c_2 + alpha_1 * c_3) * f_3;\n        let dz_1 = (alpha_1 * c_1 + c_2) * f_0\n            - beta_1 * c_1 * f_1\n            - beta_1 * c_2 * f_2\n            - beta_1 * c_3 * f_3;\n        let dz_2 = -c_1 * f_0 - c_2 * f_1 - c_3 * f_2 + (alpha_2 * c_3 + beta_2 * c_2) * f_3;\n        let dz_3 = -(alpha_2 * c_1 + c_2) * f_0\n            + beta_2 * c_1 * f_1\n            + beta_2 * c_2 * f_2\n            + beta_2 * c_3 * f_3;\n        let a1 = alpha_1 - inv * dz_0;\n        let b1 = beta_1 - inv * dz_1;\n        let a2 = alpha_2 - inv * dz_2;\n        let b2 = beta_2 - inv * dz_3;\n        let new_eps_t = calc_eps_t(a1, b1, a2, b2);\n        // We break if the new eps is equal, paper keeps going\n        if new_eps_t < eps_t {\n            alpha_1 = a1;\n            beta_1 = b1;\n            alpha_2 = a2;\n            beta_2 = b2;\n            eps_t = new_eps_t;\n        } else {\n            //println!(\"new_eps_t got worse: {:e}\", new_eps_t);\n            break;\n        }\n    }\n    Some([(alpha_1, beta_1), (alpha_2, beta_2)].into())\n}\n\n/// Dominant root of depressed cubic x^3 + gx + h = 0.\n///\n/// Section 2.2 of Orellana and De Michele.\n// Note: some of the techniques in here might be useful to improve the\n// cubic solver, and vice versa.\nfn depressed_cubic_dominant(g: f64, h: f64) -> f64 {\n    let q = (-1. / 3.) * g;\n    let r = 0.5 * h;\n    let phi_0;\n    let k = if q.abs() < 1e102 && r.abs() < 1e154 {\n        None\n    } else if q.abs() < r.abs() {\n        Some(1. - q * (q / r).powi(2))\n    } else {\n        Some(q.signum() * ((r / q).powi(2) / q - 1.0))\n    };\n    if k.is_some() && r == 0.0 {\n        if g > 0.0 {\n            phi_0 = 0.0;\n        } else {\n            phi_0 = (-g).sqrt();\n        }\n    } else if k.map(|k| k < 0.0).unwrap_or_else(|| r * r < q.powi(3)) {\n        let t = if k.is_some() {\n            r / q / q.sqrt()\n        } else {\n            r / q.powi(3).sqrt()\n        };\n        phi_0 = -2. * q.sqrt() * (t.abs().acos() * (1. / 3.)).cos().copysign(t);\n    } else {\n        let a = if let Some(k) = k {\n            if q.abs() < r.abs() {\n                -r * (1. + k.sqrt())\n            } else {\n                -r - (q.abs().sqrt() * q * k.sqrt()).copysign(r)\n            }\n        } else {\n            -r - (r * r - q.powi(3)).sqrt().copysign(r)\n        }\n        .cbrt();\n        let b = if a == 0.0 { 0.0 } else { q / a };\n        phi_0 = a + b;\n    }\n    // Refine with Newton-Raphson iteration\n    let mut x = phi_0;\n    let mut f = (x * x + g) * x + h;\n    //println!(\"g = {:e}, h = {:e}, x = {:e}, f = {:e}\", g, h, x, f);\n    const EPS_M: f64 = 2.22045e-16;\n    if f.abs() < EPS_M * x.powi(3).max(g * x).max(h) {\n        return x;\n    }\n    for _ in 0..8 {\n        let delt_f = 3. * x * x + g;\n        if delt_f == 0.0 {\n            break;\n        }\n        let new_x = x - f / delt_f;\n        let new_f = (new_x * new_x + g) * new_x + h;\n        //println!(\"delt_f = {:e}, new_f = {:e}\", delt_f, new_f);\n        if new_f == 0.0 {\n            return new_x;\n        }\n        if new_f.abs() >= f.abs() {\n            break;\n        }\n        x = new_x;\n        f = new_f;\n    }\n    x\n}\n\n/// Solve an arbitrary function for a zero-crossing.\n///\n/// This uses the [ITP method], as described in the paper\n/// [An Enhancement of the Bisection Method Average Performance Preserving Minmax Optimality].\n///\n/// The values of `ya` and `yb` are given as arguments rather than\n/// computed from `f`, as the values may already be known, or they may\n/// be less expensive to compute as special cases.\n///\n/// It is assumed that `ya < 0.0` and `yb > 0.0`, otherwise unexpected\n/// results may occur.\n///\n/// The value of `epsilon` must be larger than 2^-63 times `b - a`,\n/// otherwise integer overflow may occur. The `a` and `b` parameters\n/// represent the lower and upper bounds of the bracket searched for a\n/// solution.\n///\n/// The ITP method has tuning parameters. This implementation hardwires\n/// k2 to 2, both because it avoids an expensive floating point\n/// exponentiation, and because this value has been tested to work well\n/// with curve fitting problems.\n///\n/// The `n0` parameter controls the relative impact of the bisection and\n/// secant components. When it is 0, the number of iterations is\n/// guaranteed to be no more than the number required by bisection (thus,\n/// this method is strictly superior to bisection). However, when the\n/// function is smooth, a value of 1 gives the secant method more of a\n/// chance to engage, so the average number of iterations is likely\n/// lower, though there can be one more iteration than bisection in the\n/// worst case.\n///\n/// The `k1` parameter is harder to characterize, and interested users\n/// are referred to the paper, as well as encouraged to do empirical\n/// testing. To match the paper, a value of `0.2 / (b - a)` is\n/// suggested, and this is confirmed to give good results.\n///\n/// When the function is monotonic, the returned result is guaranteed to\n/// be within `epsilon` of the zero crossing. For more detailed analysis,\n/// again see the paper.\n///\n/// [ITP method]: https://en.wikipedia.org/wiki/ITP_Method\n/// [An Enhancement of the Bisection Method Average Performance Preserving Minmax Optimality]: https://dl.acm.org/doi/10.1145/3423597\n#[allow(clippy::too_many_arguments)]\npub fn solve_itp(\n    mut f: impl FnMut(f64) -> f64,\n    mut a: f64,\n    mut b: f64,\n    epsilon: f64,\n    n0: usize,\n    k1: f64,\n    mut ya: f64,\n    mut yb: f64,\n) -> f64 {\n    let n1_2 = (((b - a) / epsilon).log2().ceil() - 1.0).max(0.0) as usize;\n    let nmax = n0 + n1_2;\n    let mut scaled_epsilon = epsilon * (1u64 << nmax) as f64;\n    while b - a > 2.0 * epsilon {\n        let x1_2 = 0.5 * (a + b);\n        let r = scaled_epsilon - 0.5 * (b - a);\n        let xf = (yb * a - ya * b) / (yb - ya);\n        let sigma = x1_2 - xf;\n        // This has k2 = 2 hardwired for efficiency.\n        let delta = k1 * (b - a).powi(2);\n        let xt = if delta <= (x1_2 - xf).abs() {\n            xf + delta.copysign(sigma)\n        } else {\n            x1_2\n        };\n        let xitp = if (xt - x1_2).abs() <= r {\n            xt\n        } else {\n            x1_2 - r.copysign(sigma)\n        };\n        let yitp = f(xitp);\n        if yitp > 0.0 {\n            b = xitp;\n            yb = yitp;\n        } else if yitp < 0.0 {\n            a = xitp;\n            ya = yitp;\n        } else {\n            return xitp;\n        }\n        scaled_epsilon *= 0.5;\n    }\n    0.5 * (a + b)\n}\n\n/// A variant ITP solver that allows fallible functions.\n///\n/// Another difference: it returns the bracket that contains the root,\n/// which may be important if the function has a discontinuity.\n#[allow(clippy::too_many_arguments)]\npub(crate) fn solve_itp_fallible<E>(\n    mut f: impl FnMut(f64) -> Result<f64, E>,\n    mut a: f64,\n    mut b: f64,\n    epsilon: f64,\n    n0: usize,\n    k1: f64,\n    mut ya: f64,\n    mut yb: f64,\n) -> Result<(f64, f64), E> {\n    let n1_2 = (((b - a) / epsilon).log2().ceil() - 1.0).max(0.0) as usize;\n    let nmax = n0 + n1_2;\n    let mut scaled_epsilon = epsilon * (1u64 << nmax) as f64;\n    while b - a > 2.0 * epsilon {\n        let x1_2 = 0.5 * (a + b);\n        let r = scaled_epsilon - 0.5 * (b - a);\n        let xf = (yb * a - ya * b) / (yb - ya);\n        let sigma = x1_2 - xf;\n        // This has k2 = 2 hardwired for efficiency.\n        let delta = k1 * (b - a).powi(2);\n        let xt = if delta <= (x1_2 - xf).abs() {\n            xf + delta.copysign(sigma)\n        } else {\n            x1_2\n        };\n        let xitp = if (xt - x1_2).abs() <= r {\n            xt\n        } else {\n            x1_2 - r.copysign(sigma)\n        };\n        let yitp = f(xitp)?;\n        if yitp > 0.0 {\n            b = xitp;\n            yb = yitp;\n        } else if yitp < 0.0 {\n            a = xitp;\n            ya = yitp;\n        } else {\n            return Ok((xitp, xitp));\n        }\n        scaled_epsilon *= 0.5;\n    }\n    Ok((a, b))\n}\n\n// Tables of Legendre-Gauss quadrature coefficients, adapted from:\n// <https://pomax.github.io/bezierinfo/legendre-gauss.html>\n\npub const GAUSS_LEGENDRE_COEFFS_3: &[(f64, f64)] = &[\n    (0.8888888888888888, 0.0000000000000000),\n    (0.5555555555555556, -0.7745966692414834),\n    (0.5555555555555556, 0.7745966692414834),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_4: &[(f64, f64)] = &[\n    (0.6521451548625461, -0.3399810435848563),\n    (0.6521451548625461, 0.3399810435848563),\n    (0.3478548451374538, -0.8611363115940526),\n    (0.3478548451374538, 0.8611363115940526),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_5: &[(f64, f64)] = &[\n    (0.5688888888888889, 0.0000000000000000),\n    (0.4786286704993665, -0.5384693101056831),\n    (0.4786286704993665, 0.5384693101056831),\n    (0.2369268850561891, -0.9061798459386640),\n    (0.2369268850561891, 0.9061798459386640),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_6: &[(f64, f64)] = &[\n    (0.3607615730481386, 0.6612093864662645),\n    (0.3607615730481386, -0.6612093864662645),\n    (0.4679139345726910, -0.2386191860831969),\n    (0.4679139345726910, 0.2386191860831969),\n    (0.1713244923791704, -0.9324695142031521),\n    (0.1713244923791704, 0.9324695142031521),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_7: &[(f64, f64)] = &[\n    (0.4179591836734694, 0.0000000000000000),\n    (0.3818300505051189, 0.4058451513773972),\n    (0.3818300505051189, -0.4058451513773972),\n    (0.2797053914892766, -0.7415311855993945),\n    (0.2797053914892766, 0.7415311855993945),\n    (0.1294849661688697, -0.9491079123427585),\n    (0.1294849661688697, 0.9491079123427585),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_8: &[(f64, f64)] = &[\n    (0.3626837833783620, -0.1834346424956498),\n    (0.3626837833783620, 0.1834346424956498),\n    (0.3137066458778873, -0.5255324099163290),\n    (0.3137066458778873, 0.5255324099163290),\n    (0.2223810344533745, -0.7966664774136267),\n    (0.2223810344533745, 0.7966664774136267),\n    (0.1012285362903763, -0.9602898564975363),\n    (0.1012285362903763, 0.9602898564975363),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_8_HALF: &[(f64, f64)] = &[\n    (0.3626837833783620, 0.1834346424956498),\n    (0.3137066458778873, 0.5255324099163290),\n    (0.2223810344533745, 0.7966664774136267),\n    (0.1012285362903763, 0.9602898564975363),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_9: &[(f64, f64)] = &[\n    (0.3302393550012598, 0.0000000000000000),\n    (0.1806481606948574, -0.8360311073266358),\n    (0.1806481606948574, 0.8360311073266358),\n    (0.0812743883615744, -0.9681602395076261),\n    (0.0812743883615744, 0.9681602395076261),\n    (0.3123470770400029, -0.3242534234038089),\n    (0.3123470770400029, 0.3242534234038089),\n    (0.2606106964029354, -0.6133714327005904),\n    (0.2606106964029354, 0.6133714327005904),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_11: &[(f64, f64)] = &[\n    (0.2729250867779006, 0.0000000000000000),\n    (0.2628045445102467, -0.2695431559523450),\n    (0.2628045445102467, 0.2695431559523450),\n    (0.2331937645919905, -0.5190961292068118),\n    (0.2331937645919905, 0.5190961292068118),\n    (0.1862902109277343, -0.7301520055740494),\n    (0.1862902109277343, 0.7301520055740494),\n    (0.1255803694649046, -0.8870625997680953),\n    (0.1255803694649046, 0.8870625997680953),\n    (0.0556685671161737, -0.9782286581460570),\n    (0.0556685671161737, 0.9782286581460570),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_16: &[(f64, f64)] = &[\n    (0.1894506104550685, -0.0950125098376374),\n    (0.1894506104550685, 0.0950125098376374),\n    (0.1826034150449236, -0.2816035507792589),\n    (0.1826034150449236, 0.2816035507792589),\n    (0.1691565193950025, -0.4580167776572274),\n    (0.1691565193950025, 0.4580167776572274),\n    (0.1495959888165767, -0.6178762444026438),\n    (0.1495959888165767, 0.6178762444026438),\n    (0.1246289712555339, -0.7554044083550030),\n    (0.1246289712555339, 0.7554044083550030),\n    (0.0951585116824928, -0.8656312023878318),\n    (0.0951585116824928, 0.8656312023878318),\n    (0.0622535239386479, -0.9445750230732326),\n    (0.0622535239386479, 0.9445750230732326),\n    (0.0271524594117541, -0.9894009349916499),\n    (0.0271524594117541, 0.9894009349916499),\n];\n\n// Just the positive x_i values.\npub const GAUSS_LEGENDRE_COEFFS_16_HALF: &[(f64, f64)] = &[\n    (0.1894506104550685, 0.0950125098376374),\n    (0.1826034150449236, 0.2816035507792589),\n    (0.1691565193950025, 0.4580167776572274),\n    (0.1495959888165767, 0.6178762444026438),\n    (0.1246289712555339, 0.7554044083550030),\n    (0.0951585116824928, 0.8656312023878318),\n    (0.0622535239386479, 0.9445750230732326),\n    (0.0271524594117541, 0.9894009349916499),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_24: &[(f64, f64)] = &[\n    (0.1279381953467522, -0.0640568928626056),\n    (0.1279381953467522, 0.0640568928626056),\n    (0.1258374563468283, -0.1911188674736163),\n    (0.1258374563468283, 0.1911188674736163),\n    (0.1216704729278034, -0.3150426796961634),\n    (0.1216704729278034, 0.3150426796961634),\n    (0.1155056680537256, -0.4337935076260451),\n    (0.1155056680537256, 0.4337935076260451),\n    (0.1074442701159656, -0.5454214713888396),\n    (0.1074442701159656, 0.5454214713888396),\n    (0.0976186521041139, -0.6480936519369755),\n    (0.0976186521041139, 0.6480936519369755),\n    (0.0861901615319533, -0.7401241915785544),\n    (0.0861901615319533, 0.7401241915785544),\n    (0.0733464814110803, -0.8200019859739029),\n    (0.0733464814110803, 0.8200019859739029),\n    (0.0592985849154368, -0.8864155270044011),\n    (0.0592985849154368, 0.8864155270044011),\n    (0.0442774388174198, -0.9382745520027328),\n    (0.0442774388174198, 0.9382745520027328),\n    (0.0285313886289337, -0.9747285559713095),\n    (0.0285313886289337, 0.9747285559713095),\n    (0.0123412297999872, -0.9951872199970213),\n    (0.0123412297999872, 0.9951872199970213),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_24_HALF: &[(f64, f64)] = &[\n    (0.1279381953467522, 0.0640568928626056),\n    (0.1258374563468283, 0.1911188674736163),\n    (0.1216704729278034, 0.3150426796961634),\n    (0.1155056680537256, 0.4337935076260451),\n    (0.1074442701159656, 0.5454214713888396),\n    (0.0976186521041139, 0.6480936519369755),\n    (0.0861901615319533, 0.7401241915785544),\n    (0.0733464814110803, 0.8200019859739029),\n    (0.0592985849154368, 0.8864155270044011),\n    (0.0442774388174198, 0.9382745520027328),\n    (0.0285313886289337, 0.9747285559713095),\n    (0.0123412297999872, 0.9951872199970213),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_32: &[(f64, f64)] = &[\n    (0.0965400885147278, -0.0483076656877383),\n    (0.0965400885147278, 0.0483076656877383),\n    (0.0956387200792749, -0.1444719615827965),\n    (0.0956387200792749, 0.1444719615827965),\n    (0.0938443990808046, -0.2392873622521371),\n    (0.0938443990808046, 0.2392873622521371),\n    (0.0911738786957639, -0.3318686022821277),\n    (0.0911738786957639, 0.3318686022821277),\n    (0.0876520930044038, -0.4213512761306353),\n    (0.0876520930044038, 0.4213512761306353),\n    (0.0833119242269467, -0.5068999089322294),\n    (0.0833119242269467, 0.5068999089322294),\n    (0.0781938957870703, -0.5877157572407623),\n    (0.0781938957870703, 0.5877157572407623),\n    (0.0723457941088485, -0.6630442669302152),\n    (0.0723457941088485, 0.6630442669302152),\n    (0.0658222227763618, -0.7321821187402897),\n    (0.0658222227763618, 0.7321821187402897),\n    (0.0586840934785355, -0.7944837959679424),\n    (0.0586840934785355, 0.7944837959679424),\n    (0.0509980592623762, -0.8493676137325700),\n    (0.0509980592623762, 0.8493676137325700),\n    (0.0428358980222267, -0.8963211557660521),\n    (0.0428358980222267, 0.8963211557660521),\n    (0.0342738629130214, -0.9349060759377397),\n    (0.0342738629130214, 0.9349060759377397),\n    (0.0253920653092621, -0.9647622555875064),\n    (0.0253920653092621, 0.9647622555875064),\n    (0.0162743947309057, -0.9856115115452684),\n    (0.0162743947309057, 0.9856115115452684),\n    (0.0070186100094701, -0.9972638618494816),\n    (0.0070186100094701, 0.9972638618494816),\n];\n\npub const GAUSS_LEGENDRE_COEFFS_32_HALF: &[(f64, f64)] = &[\n    (0.0965400885147278, 0.0483076656877383),\n    (0.0956387200792749, 0.1444719615827965),\n    (0.0938443990808046, 0.2392873622521371),\n    (0.0911738786957639, 0.3318686022821277),\n    (0.0876520930044038, 0.4213512761306353),\n    (0.0833119242269467, 0.5068999089322294),\n    (0.0781938957870703, 0.5877157572407623),\n    (0.0723457941088485, 0.6630442669302152),\n    (0.0658222227763618, 0.7321821187402897),\n    (0.0586840934785355, 0.7944837959679424),\n    (0.0509980592623762, 0.8493676137325700),\n    (0.0428358980222267, 0.8963211557660521),\n    (0.0342738629130214, 0.9349060759377397),\n    (0.0253920653092621, 0.9647622555875064),\n    (0.0162743947309057, 0.9856115115452684),\n    (0.0070186100094701, 0.9972638618494816),\n];\n\n#[cfg(test)]\nmod tests {\n    use crate::common::*;\n    use arrayvec::ArrayVec;\n\n    fn verify<const N: usize>(mut roots: ArrayVec<f64, N>, expected: &[f64]) {\n        assert_eq!(expected.len(), roots.len());\n        let epsilon = 1e-12;\n        roots.sort_by(|a, b| a.partial_cmp(b).unwrap());\n        for i in 0..expected.len() {\n            assert!((roots[i] - expected[i]).abs() < epsilon);\n        }\n    }\n\n    #[test]\n    fn test_solve_cubic() {\n        verify(solve_cubic(-5.0, 0.0, 0.0, 1.0), &[5.0f64.cbrt()]);\n        verify(solve_cubic(-5.0, -1.0, 0.0, 1.0), &[1.90416085913492]);\n        verify(solve_cubic(0.0, -1.0, 0.0, 1.0), &[-1.0, 0.0, 1.0]);\n        verify(solve_cubic(-2.0, -3.0, 0.0, 1.0), &[-1.0, 2.0]);\n        verify(solve_cubic(2.0, -3.0, 0.0, 1.0), &[-2.0, 1.0]);\n        verify(\n            solve_cubic(2.0 - 1e-12, 5.0, 4.0, 1.0),\n            &[\n                -1.9999999999989995,\n                -1.0000010000848456,\n                -0.9999989999161546,\n            ],\n        );\n        verify(solve_cubic(2.0 + 1e-12, 5.0, 4.0, 1.0), &[-2.0]);\n    }\n\n    #[test]\n    fn test_solve_quadratic() {\n        verify(\n            solve_quadratic(-5.0, 0.0, 1.0),\n            &[-(5.0f64.sqrt()), 5.0f64.sqrt()],\n        );\n        verify(solve_quadratic(5.0, 0.0, 1.0), &[]);\n        verify(solve_quadratic(5.0, 1.0, 0.0), &[-5.0]);\n        verify(solve_quadratic(1.0, 2.0, 1.0), &[-1.0]);\n    }\n\n    #[test]\n    fn test_solve_quartic() {\n        // These test cases are taken from Orellana and De Michele paper (Table 1).\n        fn test_with_roots(coeffs: [f64; 4], roots: &[f64], rel_err: f64) {\n            // Note: in paper, coefficients are in decreasing order.\n            let mut actual = solve_quartic(coeffs[3], coeffs[2], coeffs[1], coeffs[0], 1.0);\n            actual.sort_by(f64::total_cmp);\n            assert_eq!(actual.len(), roots.len());\n            for (actual, expected) in actual.iter().zip(roots) {\n                assert!(\n                    (actual - expected).abs() < rel_err * expected.abs(),\n                    \"actual {:e}, expected {:e}, err {:e}\",\n                    actual,\n                    expected,\n                    actual - expected\n                );\n            }\n        }\n\n        fn test_vieta_roots(x1: f64, x2: f64, x3: f64, x4: f64, roots: &[f64], rel_err: f64) {\n            let a = -(x1 + x2 + x3 + x4);\n            let b = x1 * (x2 + x3) + x2 * (x3 + x4) + x4 * (x1 + x3);\n            let c = -x1 * x2 * (x3 + x4) - x3 * x4 * (x1 + x2);\n            let d = x1 * x2 * x3 * x4;\n            test_with_roots([a, b, c, d], roots, rel_err);\n        }\n\n        fn test_vieta(x1: f64, x2: f64, x3: f64, x4: f64, rel_err: f64) {\n            test_vieta_roots(x1, x2, x3, x4, &[x1, x2, x3, x4], rel_err);\n        }\n\n        // case 1\n        test_vieta(1., 1e3, 1e6, 1e9, 1e-16);\n        // case 2\n        test_vieta(2., 2.001, 2.002, 2.003, 1e-6);\n        // case 3\n        test_vieta(1e47, 1e49, 1e50, 1e53, 2e-16);\n        // case 4\n        test_vieta(-1., 1., 2., 1e14, 1e-16);\n        // case 5\n        test_vieta(-2e7, -1., 1., 1e7, 1e-16);\n        // case 6\n        test_with_roots(\n            [-9000002.0, -9999981999998.0, 19999982e6, -2e13],\n            &[-1e6, 1e7],\n            1e-16,\n        );\n        // case 7\n        test_with_roots(\n            [2000011.0, 1010022000028.0, 11110056e6, 2828e10],\n            &[-7., -4.],\n            1e-16,\n        );\n        // case 8\n        test_with_roots(\n            [-100002011.0, 201101022001.0, -102200111000011.0, 11000011e8],\n            &[11., 1e8],\n            1e-16,\n        );\n        // cases 9-13 have no real roots\n        // case 14\n        test_vieta_roots(1000., 1000., 1000., 1000., &[1000., 1000.], 1e-16);\n        // case 15\n        test_vieta_roots(1e-15, 1000., 1000., 1000., &[1e-15, 1000., 1000.], 1e-15);\n        // case 16 no real roots\n        // case 17\n        test_vieta(10000., 10001., 10010., 10100., 1e-6);\n        // case 19\n        test_vieta_roots(1., 1e30, 1e30, 1e44, &[1., 1e30, 1e44], 1e-16);\n        // case 20\n        // FAILS, error too big\n        test_vieta(1., 1e7, 1e7, 1e14, 1e-7);\n        // case 21 doesn't pick up double root\n        // case 22\n        test_vieta(1., 10., 1e152, 1e154, 3e-16);\n        // case 23\n        test_with_roots(\n            [1., 1., 3. / 8., 1e-3],\n            &[-0.497314148060048, -0.00268585193995149],\n            2e-15,\n        );\n        // case 24\n        const S: f64 = 1e30;\n        test_with_roots(\n            [-(1. + 1. / S), 1. / S - S * S, S * S + S, -S],\n            &[-S, 1e-30, 1., S],\n            2e-16,\n        );\n    }\n\n    #[test]\n    fn test_solve_itp() {\n        let f = |x: f64| x.powi(3) - x - 2.0;\n        let x = solve_itp(f, 1., 2., 1e-12, 0, 0.2, f(1.), f(2.));\n        assert!(f(x).abs() < 6e-12);\n    }\n\n    #[test]\n    fn test_inv_arclen() {\n        use crate::{ParamCurve, ParamCurveArclen};\n        let c = crate::CubicBez::new(\n            (0.0, 0.0),\n            (100.0 / 3.0, 0.0),\n            (200.0 / 3.0, 100.0 / 3.0),\n            (100.0, 100.0),\n        );\n        let target = 100.0;\n        let _ = solve_itp(\n            |t| c.subsegment(0.0..t).arclen(1e-9) - target,\n            0.,\n            1.,\n            1e-6,\n            1,\n            0.2,\n            -target,\n            c.arclen(1e-9) - target,\n        );\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/cubicbez.rs",
      "sha256": "b0131f5f61f94dbc85e374c7aefc6b09961621a74aa9a08d914e8de0acf92b8f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Cubic Bézier segments.\n\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse core::ops::{Mul, Range};\n\nuse crate::MAX_EXTREMA;\nuse crate::{Line, QuadSpline, Vec2};\nuse arrayvec::ArrayVec;\n\nuse crate::common::{\n    solve_quadratic, GAUSS_LEGENDRE_COEFFS_16_HALF, GAUSS_LEGENDRE_COEFFS_24_HALF,\n    GAUSS_LEGENDRE_COEFFS_8, GAUSS_LEGENDRE_COEFFS_8_HALF,\n};\nuse crate::{\n    Affine, Nearest, ParamCurve, ParamCurveArclen, ParamCurveArea, ParamCurveCurvature,\n    ParamCurveDeriv, ParamCurveExtrema, ParamCurveNearest, PathEl, Point, QuadBez, Rect, Shape,\n};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\nconst MAX_SPLINE_SPLIT: usize = 100;\n\n/// A single cubic Bézier segment.\n#[derive(Clone, Copy, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\n#[allow(missing_docs)]\npub struct CubicBez {\n    pub p0: Point,\n    pub p1: Point,\n    pub p2: Point,\n    pub p3: Point,\n}\n\n/// An iterator which produces quadratic Bézier segments.\nstruct ToQuads {\n    c: CubicBez,\n    i: usize,\n    n: usize,\n}\n\n/// Classification result for cusp detection.\n#[derive(Debug)]\npub enum CuspType {\n    /// Cusp is a loop.\n    Loop,\n    /// Cusp has two closely spaced inflection points.\n    DoubleInflection,\n}\n\nimpl CubicBez {\n    /// Create a new cubic Bézier segment.\n    #[inline]\n    pub fn new<P: Into<Point>>(p0: P, p1: P, p2: P, p3: P) -> CubicBez {\n        CubicBez {\n            p0: p0.into(),\n            p1: p1.into(),\n            p2: p2.into(),\n            p3: p3.into(),\n        }\n    }\n\n    /// Convert to quadratic Béziers.\n    ///\n    /// The iterator returns the start and end parameter in the cubic of each quadratic\n    /// segment, along with the quadratic.\n    ///\n    /// Note that the resulting quadratic Béziers are not in general G1 continuous;\n    /// they are optimized for minimizing distance error.\n    ///\n    /// This iterator will always produce at least one `QuadBez`.\n    #[inline]\n    pub fn to_quads(&self, accuracy: f64) -> impl Iterator<Item = (f64, f64, QuadBez)> {\n        // The maximum error, as a vector from the cubic to the best approximating\n        // quadratic, is proportional to the third derivative, which is constant\n        // across the segment. Thus, the error scales down as the third power of\n        // the number of subdivisions. Our strategy then is to subdivide `t` evenly.\n        //\n        // This is an overestimate of the error because only the component\n        // perpendicular to the first derivative is important. But the simplicity is\n        // appealing.\n\n        // This magic number is the square of 36 / sqrt(3).\n        // See: http://caffeineowl.com/graphics/2d/vectorial/cubic2quad01.html\n        let max_hypot2 = 432.0 * accuracy * accuracy;\n        let p1x2 = 3.0 * self.p1.to_vec2() - self.p0.to_vec2();\n        let p2x2 = 3.0 * self.p2.to_vec2() - self.p3.to_vec2();\n        let err = (p2x2 - p1x2).hypot2();\n        let n = ((err / max_hypot2).powf(1. / 6.0).ceil() as usize).max(1);\n\n        ToQuads { c: *self, n, i: 0 }\n    }\n\n    /// Return a [`QuadSpline`] approximating this cubic Bézier.\n    ///\n    /// Returns `None` if no suitable approximation is found within the given\n    /// tolerance.\n    pub fn approx_spline(&self, accuracy: f64) -> Option<QuadSpline> {\n        (1..=MAX_SPLINE_SPLIT).find_map(|n| self.approx_spline_n(n, accuracy))\n    }\n\n    // Approximate a cubic curve with a quadratic spline of `n` curves\n    fn approx_spline_n(&self, n: usize, accuracy: f64) -> Option<QuadSpline> {\n        if n == 1 {\n            return self\n                .try_approx_quadratic(accuracy)\n                .map(|quad| QuadSpline::new(vec![quad.p0, quad.p1, quad.p2]));\n        }\n        let mut cubics = self.split_into_n(n);\n\n        // The above function guarantees that the iterator returns n items,\n        // which is why we're unwrapping things with wild abandon.\n        let mut next_cubic = cubics.next().unwrap();\n        let mut next_q1: Point = next_cubic.approx_quad_control(0.0);\n        let mut q2 = self.p0;\n        let mut d1 = Vec2::ZERO;\n        let mut spline = vec![self.p0, next_q1];\n        for i in 1..=n {\n            let current_cubic: CubicBez = next_cubic;\n            let q0 = q2;\n            let q1 = next_q1;\n            q2 = if i < n {\n                next_cubic = cubics.next().unwrap();\n                next_q1 = next_cubic.approx_quad_control(i as f64 / (n - 1) as f64);\n\n                spline.push(next_q1);\n                q1.midpoint(next_q1)\n            } else {\n                current_cubic.p3\n            };\n            let d0 = d1;\n            d1 = q2.to_vec2() - current_cubic.p3.to_vec2();\n\n            if d1.hypot() > accuracy\n                || !CubicBez::new(\n                    d0.to_point(),\n                    q0.lerp(q1, 2.0 / 3.0) - current_cubic.p1.to_vec2(),\n                    q2.lerp(q1, 2.0 / 3.0) - current_cubic.p2.to_vec2(),\n                    d1.to_point(),\n                )\n                .fit_inside(accuracy)\n            {\n                return None;\n            }\n        }\n        spline.push(self.p3);\n        Some(QuadSpline::new(spline))\n    }\n\n    fn approx_quad_control(&self, t: f64) -> Point {\n        let p1 = self.p0 + (self.p1 - self.p0) * 1.5;\n        let p2 = self.p3 + (self.p2 - self.p3) * 1.5;\n        p1.lerp(p2, t)\n    }\n\n    /// Approximate a cubic with a single quadratic\n    ///\n    /// Returns a quadratic approximating the given cubic that maintains\n    /// endpoint tangents if that is within tolerance, or `None` otherwise.\n    fn try_approx_quadratic(&self, accuracy: f64) -> Option<QuadBez> {\n        if let Some(q1) = Line::new(self.p0, self.p1).crossing_point(Line::new(self.p2, self.p3)) {\n            let c1 = self.p0.lerp(q1, 2.0 / 3.0);\n            let c2 = self.p3.lerp(q1, 2.0 / 3.0);\n            if !CubicBez::new(\n                Point::ZERO,\n                c1 - self.p1.to_vec2(),\n                c2 - self.p2.to_vec2(),\n                Point::ZERO,\n            )\n            .fit_inside(accuracy)\n            {\n                return None;\n            }\n            return Some(QuadBez::new(self.p0, q1, self.p3));\n        }\n        None\n    }\n\n    fn split_into_n(&self, n: usize) -> impl Iterator<Item = CubicBez> {\n        // for certain small values of `n` we precompute all our values.\n        // if we have six or fewer items we precompute them.\n        let mut storage = ArrayVec::<_, 6>::new();\n\n        match n {\n            1 => storage.push(*self),\n            2 => {\n                let (l, r) = self.subdivide();\n                storage.try_extend_from_slice(&[r, l]).unwrap();\n            }\n            3 => {\n                let (left, mid, right) = self.subdivide_3();\n                storage.try_extend_from_slice(&[right, mid, left]).unwrap();\n            }\n            4 => {\n                let (l, r) = self.subdivide();\n                let (ll, lr) = l.subdivide();\n                let (rl, rr) = r.subdivide();\n                storage.try_extend_from_slice(&[rr, rl, lr, ll]).unwrap();\n            }\n            6 => {\n                let (l, r) = self.subdivide();\n                let (l1, l2, l3) = l.subdivide_3();\n                let (r1, r2, r3) = r.subdivide_3();\n                storage\n                    .try_extend_from_slice(&[r3, r2, r1, l3, l2, l1])\n                    .unwrap();\n            }\n            _ => (),\n        }\n\n        // a limitation of returning 'impl Trait' is that the implementation\n        // can only return a single concrete type; that is you cannot return\n        // Vec::into_iter() from one branch, and then HashSet::into_iter from\n        // another branch.\n        //\n        // This means we have to get a bit fancy, and have a single concrete\n        // type that represents both of our possible cases.\n\n        let mut storage = if storage.is_empty() {\n            None\n        } else {\n            Some(storage)\n        };\n\n        // used in the fallback case\n        let mut i = 0;\n        let (a, b, c, d) = self.parameters();\n        let dt = 1.0 / n as f64;\n        let delta_2 = dt * dt;\n        let delta_3 = dt * delta_2;\n\n        core::iter::from_fn(move || {\n            // if storage exists, we use it exclusively\n            if let Some(storage) = storage.as_mut() {\n                return storage.pop();\n            }\n\n            // if storage does not exist, we are exclusively working down here.\n            if i >= n {\n                return None;\n            }\n\n            let t1 = i as f64 * dt;\n            let t1_2 = t1 * t1;\n            let a1 = a * delta_3;\n            let b1 = (3.0 * a * t1 + b) * delta_2;\n            let c1 = (2.0 * b * t1 + c + 3.0 * a * t1_2) * dt;\n            let d1 = a * t1 * t1_2 + b * t1_2 + c * t1 + d;\n            let result = CubicBez::from_parameters(a1, b1, c1, d1);\n            i += 1;\n            Some(result)\n        })\n    }\n\n    fn parameters(&self) -> (Vec2, Vec2, Vec2, Vec2) {\n        let c = (self.p1 - self.p0) * 3.0;\n        let b = (self.p2 - self.p1) * 3.0 - c;\n        let d = self.p0.to_vec2();\n        let a = self.p3.to_vec2() - d - c - b;\n        (a, b, c, d)\n    }\n\n    /// Rust port of cu2qu [calc_cubic_points](https://github.com/fonttools/fonttools/blob/3b9a73ff8379ab49d3ce35aaaaf04b3a7d9d1655/Lib/fontTools/cu2qu/cu2qu.py#L63-L68)\n    fn from_parameters(a: Vec2, b: Vec2, c: Vec2, d: Vec2) -> Self {\n        let p0 = d.to_point();\n        let p1 = c.div_exact(3.0).to_point() + d;\n        let p2 = (b + c).div_exact(3.0).to_point() + p1.to_vec2();\n        let p3 = (a + d + c + b).to_point();\n        CubicBez::new(p0, p1, p2, p3)\n    }\n\n    fn subdivide_3(&self) -> (CubicBez, CubicBez, CubicBez) {\n        let (p0, p1, p2, p3) = (\n            self.p0.to_vec2(),\n            self.p1.to_vec2(),\n            self.p2.to_vec2(),\n            self.p3.to_vec2(),\n        );\n        // The original Python cu2qu code here does not use division operator to divide by 27 but\n        // instead uses multiplication by the reciprocal 1 / 27. We want to match it exactly\n        // to avoid any floating point differences, hence in this particular case we do not use div_exact.\n        // I could directly use the Vec2 Div trait (also implemented as multiplication by reciprocal)\n        // but I prefer to be explicit here.\n        // Source: https://github.com/fonttools/fonttools/blob/85c80be/Lib/fontTools/cu2qu/cu2qu.py#L215-L218\n        // See also: https://github.com/linebender/kurbo/issues/272\n        let one_27th = 27.0_f64.recip();\n        let mid1 = ((8.0 * p0 + 12.0 * p1 + 6.0 * p2 + p3) * one_27th).to_point();\n        let deriv1 = (p3 + 3.0 * p2 - 4.0 * p0) * one_27th;\n        let mid2 = ((p0 + 6.0 * p1 + 12.0 * p2 + 8.0 * p3) * one_27th).to_point();\n        let deriv2 = (4.0 * p3 - 3.0 * p1 - p0) * one_27th;\n\n        let left = CubicBez::new(\n            self.p0,\n            (2.0 * p0 + p1).div_exact(3.0).to_point(),\n            mid1 - deriv1,\n            mid1,\n        );\n        let mid = CubicBez::new(mid1, mid1 + deriv1, mid2 - deriv2, mid2);\n        let right = CubicBez::new(\n            mid2,\n            mid2 + deriv2,\n            (p2 + 2.0 * p3).div_exact(3.0).to_point(),\n            self.p3,\n        );\n        (left, mid, right)\n    }\n\n    /// Does this curve fit inside the given distance from the origin?\n    ///\n    /// Rust port of cu2qu [cubic_farthest_fit_inside](https://github.com/fonttools/fonttools/blob/3b9a73ff8379ab49d3ce35aaaaf04b3a7d9d1655/Lib/fontTools/cu2qu/cu2qu.py#L281)\n    fn fit_inside(&self, distance: f64) -> bool {\n        if self.p2.to_vec2().hypot() <= distance && self.p1.to_vec2().hypot() <= distance {\n            return true;\n        }\n        let mid =\n            (self.p0.to_vec2() + 3.0 * (self.p1.to_vec2() + self.p2.to_vec2()) + self.p3.to_vec2())\n                * 0.125;\n        if mid.hypot() > distance {\n            return false;\n        }\n        // Split in two. Note that cu2qu here uses a 3/8 subdivision. I don't know why.\n        let (left, right) = self.subdivide();\n        left.fit_inside(distance) && right.fit_inside(distance)\n    }\n\n    /// Is this cubic Bezier curve finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.p0.is_finite() && self.p1.is_finite() && self.p2.is_finite() && self.p3.is_finite()\n    }\n\n    /// Is this cubic Bezier curve NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.p0.is_nan() || self.p1.is_nan() || self.p2.is_nan() || self.p3.is_nan()\n    }\n\n    /// Determine the inflection points.\n    ///\n    /// Return value is t parameter for the inflection points of the curve segment.\n    /// There are a maximum of two for a cubic Bézier.\n    ///\n    /// See <https://www.caffeineowl.com/graphics/2d/vectorial/cubic-inflexion.html>\n    /// for the theory.\n    pub fn inflections(&self) -> ArrayVec<f64, 2> {\n        let a = self.p1 - self.p0;\n        let b = (self.p2 - self.p1) - a;\n        let c = (self.p3 - self.p0) - 3. * (self.p2 - self.p1);\n        solve_quadratic(a.cross(b), a.cross(c), b.cross(c))\n            .iter()\n            .copied()\n            .filter(|t| *t >= 0.0 && *t <= 1.0)\n            .collect()\n    }\n\n    /// Preprocess a cubic Bézier to ease numerical robustness.\n    ///\n    /// If the cubic Bézier segment has zero or near-zero derivatives, perturb\n    /// the control points to make it easier to process (especially offset and\n    /// stroke), avoiding numerical robustness problems.\n    pub(crate) fn regularize(&self, dimension: f64) -> CubicBez {\n        let mut c = *self;\n        // First step: if control point is too near the endpoint, nudge it away\n        // along the tangent.\n        let dim2 = dimension * dimension;\n        if c.p0.distance_squared(c.p1) < dim2 {\n            let d02 = c.p0.distance_squared(c.p2);\n            if d02 >= dim2 {\n                // TODO: moderate if this would move closer to p3\n                c.p1 = c.p0.lerp(c.p2, (dim2 / d02).sqrt());\n            } else {\n                c.p1 = c.p0.lerp(c.p3, 1.0 / 3.0);\n                c.p2 = c.p3.lerp(c.p0, 1.0 / 3.0);\n                return c;\n            }\n        }\n        if c.p3.distance_squared(c.p2) < dim2 {\n            let d13 = c.p1.distance_squared(c.p2);\n            if d13 >= dim2 {\n                // TODO: moderate if this would move closer to p0\n                c.p2 = c.p3.lerp(c.p1, (dim2 / d13).sqrt());\n            } else {\n                c.p1 = c.p0.lerp(c.p3, 1.0 / 3.0);\n                c.p2 = c.p3.lerp(c.p0, 1.0 / 3.0);\n                return c;\n            }\n        }\n        if let Some(cusp_type) = self.detect_cusp(dimension) {\n            let d01 = c.p1 - c.p0;\n            let d01h = d01.hypot();\n            let d23 = c.p3 - c.p2;\n            let d23h = d23.hypot();\n            match cusp_type {\n                CuspType::Loop => {\n                    c.p1 += (dimension / d01h) * d01;\n                    c.p2 -= (dimension / d23h) * d23;\n                }\n                CuspType::DoubleInflection => {\n                    // Avoid making control distance smaller than dimension\n                    if d01h > 2.0 * dimension {\n                        c.p1 -= (dimension / d01h) * d01;\n                    }\n                    if d23h > 2.0 * dimension {\n                        c.p2 += (dimension / d23h) * d23;\n                    }\n                }\n            }\n        }\n        c\n    }\n\n    /// Detect whether there is a cusp.\n    ///\n    /// Return a cusp classification if there is a cusp with curvature greater than\n    /// the reciprocal of the given dimension.\n    fn detect_cusp(&self, dimension: f64) -> Option<CuspType> {\n        let d01 = self.p1 - self.p0;\n        let d02 = self.p2 - self.p0;\n        let d03 = self.p3 - self.p0;\n        let d12 = self.p2 - self.p1;\n        let d23 = self.p3 - self.p2;\n        let det_012 = d01.cross(d02);\n        let det_123 = d12.cross(d23);\n        let det_013 = d01.cross(d03);\n        let det_023 = d02.cross(d03);\n        if det_012 * det_123 > 0.0 && det_012 * det_013 < 0.0 && det_012 * det_023 < 0.0 {\n            let q = self.deriv();\n            // accuracy isn't used for quadratic nearest\n            let nearest = q.nearest(Point::ORIGIN, 1e-9);\n            // detect whether curvature at minimum derivative exceeds 1/dimension,\n            // without division.\n            let d = q.eval(nearest.t);\n            let d2 = q.deriv().eval(nearest.t);\n            let cross = d.to_vec2().cross(d2.to_vec2());\n            if nearest.distance_sq.powi(3) <= (cross * dimension).powi(2) {\n                let a = 3. * det_012 + det_023 - 2. * det_013;\n                let b = -3. * det_012 + det_013;\n                let c = det_012;\n                let d = b * b - 4. * a * c;\n                if d > 0.0 {\n                    return Some(CuspType::DoubleInflection);\n                } else {\n                    return Some(CuspType::Loop);\n                }\n            }\n        }\n        None\n    }\n}\n\n/// An iterator for cubic beziers.\npub struct CubicBezIter {\n    cubic: CubicBez,\n    ix: usize,\n}\n\nimpl Shape for CubicBez {\n    type PathElementsIter<'iter> = CubicBezIter;\n\n    #[inline]\n    fn path_elements(&self, _tolerance: f64) -> CubicBezIter {\n        CubicBezIter {\n            cubic: *self,\n            ix: 0,\n        }\n    }\n\n    fn area(&self) -> f64 {\n        0.0\n    }\n\n    #[inline]\n    fn perimeter(&self, accuracy: f64) -> f64 {\n        self.arclen(accuracy)\n    }\n\n    fn winding(&self, _pt: Point) -> i32 {\n        0\n    }\n\n    #[inline]\n    fn bounding_box(&self) -> Rect {\n        ParamCurveExtrema::bounding_box(self)\n    }\n}\n\nimpl Iterator for CubicBezIter {\n    type Item = PathEl;\n\n    fn next(&mut self) -> Option<PathEl> {\n        self.ix += 1;\n        match self.ix {\n            1 => Some(PathEl::MoveTo(self.cubic.p0)),\n            2 => Some(PathEl::CurveTo(self.cubic.p1, self.cubic.p2, self.cubic.p3)),\n            _ => None,\n        }\n    }\n}\n\nimpl ParamCurve for CubicBez {\n    #[inline]\n    fn eval(&self, t: f64) -> Point {\n        let mt = 1.0 - t;\n        let v = self.p0.to_vec2() * (mt * mt * mt)\n            + (self.p1.to_vec2() * (mt * mt * 3.0)\n                + (self.p2.to_vec2() * (mt * 3.0) + self.p3.to_vec2() * t) * t)\n                * t;\n        v.to_point()\n    }\n\n    fn subsegment(&self, range: Range<f64>) -> CubicBez {\n        let (t0, t1) = (range.start, range.end);\n        let p0 = self.eval(t0);\n        let p3 = self.eval(t1);\n        let d = self.deriv();\n        let scale = (t1 - t0) * (1.0 / 3.0);\n        let p1 = p0 + scale * d.eval(t0).to_vec2();\n        let p2 = p3 - scale * d.eval(t1).to_vec2();\n        CubicBez { p0, p1, p2, p3 }\n    }\n\n    /// Subdivide into halves, using de Casteljau.\n    #[inline]\n    fn subdivide(&self) -> (CubicBez, CubicBez) {\n        let pm = self.eval(0.5);\n        (\n            CubicBez::new(\n                self.p0,\n                self.p0.midpoint(self.p1),\n                ((self.p0.to_vec2() + self.p1.to_vec2() * 2.0 + self.p2.to_vec2()) * 0.25)\n                    .to_point(),\n                pm,\n            ),\n            CubicBez::new(\n                pm,\n                ((self.p1.to_vec2() + self.p2.to_vec2() * 2.0 + self.p3.to_vec2()) * 0.25)\n                    .to_point(),\n                self.p2.midpoint(self.p3),\n                self.p3,\n            ),\n        )\n    }\n\n    #[inline]\n    fn start(&self) -> Point {\n        self.p0\n    }\n\n    #[inline]\n    fn end(&self) -> Point {\n        self.p3\n    }\n}\n\nimpl ParamCurveDeriv for CubicBez {\n    type DerivResult = QuadBez;\n\n    #[inline]\n    fn deriv(&self) -> QuadBez {\n        QuadBez::new(\n            (3.0 * (self.p1 - self.p0)).to_point(),\n            (3.0 * (self.p2 - self.p1)).to_point(),\n            (3.0 * (self.p3 - self.p2)).to_point(),\n        )\n    }\n}\n\nfn arclen_quadrature_core(coeffs: &[(f64, f64)], dm: Vec2, dm1: Vec2, dm2: Vec2) -> f64 {\n    coeffs\n        .iter()\n        .map(|&(wi, xi)| {\n            let d = dm + dm2 * (xi * xi);\n            let dpx = (d + dm1 * xi).hypot();\n            let dmx = (d - dm1 * xi).hypot();\n            (2.25f64.sqrt() * wi) * (dpx + dmx)\n        })\n        .sum::<f64>()\n}\n\nfn arclen_rec(c: &CubicBez, accuracy: f64, depth: usize) -> f64 {\n    let d03 = c.p3 - c.p0;\n    let d01 = c.p1 - c.p0;\n    let d12 = c.p2 - c.p1;\n    let d23 = c.p3 - c.p2;\n    let lp_lc = d01.hypot() + d12.hypot() + d23.hypot() - d03.hypot();\n    let dd1 = d12 - d01;\n    let dd2 = d23 - d12;\n    // It might be faster to do direct multiplies, the data dependencies would be shorter.\n    // The following values don't have the factor of 3 for first deriv\n    let dm = 0.25 * (d01 + d23) + 0.5 * d12; // first derivative at midpoint\n    let dm1 = 0.5 * (dd2 + dd1); // second derivative at midpoint\n    let dm2 = 0.25 * (dd2 - dd1); // 0.5 * (third derivative at midpoint)\n\n    let est = GAUSS_LEGENDRE_COEFFS_8\n        .iter()\n        .map(|&(wi, xi)| {\n            wi * {\n                let d_norm2 = (dm + dm1 * xi + dm2 * (xi * xi)).hypot2();\n                let dd_norm2 = (dm1 + dm2 * (2.0 * xi)).hypot2();\n                dd_norm2 / d_norm2\n            }\n        })\n        .sum::<f64>();\n    let est_gauss8_error = (est.powi(3) * 2.5e-6).min(3e-2) * lp_lc;\n    if est_gauss8_error < accuracy {\n        return arclen_quadrature_core(GAUSS_LEGENDRE_COEFFS_8_HALF, dm, dm1, dm2);\n    }\n    let est_gauss16_error = (est.powi(6) * 1.5e-11).min(9e-3) * lp_lc;\n    if est_gauss16_error < accuracy {\n        return arclen_quadrature_core(GAUSS_LEGENDRE_COEFFS_16_HALF, dm, dm1, dm2);\n    }\n    let est_gauss24_error = (est.powi(9) * 3.5e-16).min(3.5e-3) * lp_lc;\n    if est_gauss24_error < accuracy || depth >= 20 {\n        return arclen_quadrature_core(GAUSS_LEGENDRE_COEFFS_24_HALF, dm, dm1, dm2);\n    }\n    let (c0, c1) = c.subdivide();\n    arclen_rec(&c0, accuracy * 0.5, depth + 1) + arclen_rec(&c1, accuracy * 0.5, depth + 1)\n}\n\nimpl ParamCurveArclen for CubicBez {\n    /// Arclength of a cubic Bézier segment.\n    ///\n    /// This is an adaptive subdivision approach using Legendre-Gauss quadrature\n    /// in the base case, and an error estimate to decide when to subdivide.\n    fn arclen(&self, accuracy: f64) -> f64 {\n        arclen_rec(self, accuracy, 0)\n    }\n}\n\nimpl ParamCurveArea for CubicBez {\n    #[inline]\n    fn signed_area(&self) -> f64 {\n        (self.p0.x * (6.0 * self.p1.y + 3.0 * self.p2.y + self.p3.y)\n            + 3.0\n                * (self.p1.x * (-2.0 * self.p0.y + self.p2.y + self.p3.y)\n                    - self.p2.x * (self.p0.y + self.p1.y - 2.0 * self.p3.y))\n            - self.p3.x * (self.p0.y + 3.0 * self.p1.y + 6.0 * self.p2.y))\n            * (1.0 / 20.0)\n    }\n}\n\nimpl ParamCurveNearest for CubicBez {\n    /// Find the nearest point, using subdivision.\n    fn nearest(&self, p: Point, accuracy: f64) -> Nearest {\n        let mut best_r = None;\n        let mut best_t = 0.0;\n        for (t0, t1, q) in self.to_quads(accuracy) {\n            let nearest = q.nearest(p, accuracy);\n            if best_r\n                .map(|best_r| nearest.distance_sq < best_r)\n                .unwrap_or(true)\n            {\n                best_t = t0 + nearest.t * (t1 - t0);\n                best_r = Some(nearest.distance_sq);\n            }\n        }\n        Nearest {\n            t: best_t,\n            distance_sq: best_r.unwrap(),\n        }\n    }\n}\n\nimpl ParamCurveCurvature for CubicBez {}\n\nimpl ParamCurveExtrema for CubicBez {\n    fn extrema(&self) -> ArrayVec<f64, MAX_EXTREMA> {\n        fn one_coord(result: &mut ArrayVec<f64, MAX_EXTREMA>, d0: f64, d1: f64, d2: f64) {\n            let a = d0 - 2.0 * d1 + d2;\n            let b = 2.0 * (d1 - d0);\n            let c = d0;\n            let roots = solve_quadratic(c, b, a);\n            for &t in &roots {\n                if t > 0.0 && t < 1.0 {\n                    result.push(t);\n                }\n            }\n        }\n        let mut result = ArrayVec::new();\n        let d0 = self.p1 - self.p0;\n        let d1 = self.p2 - self.p1;\n        let d2 = self.p3 - self.p2;\n        one_coord(&mut result, d0.x, d1.x, d2.x);\n        one_coord(&mut result, d0.y, d1.y, d2.y);\n        result.sort_by(|a, b| a.partial_cmp(b).unwrap());\n        result\n    }\n}\n\nimpl Mul<CubicBez> for Affine {\n    type Output = CubicBez;\n\n    #[inline]\n    fn mul(self, c: CubicBez) -> CubicBez {\n        CubicBez {\n            p0: self * c.p0,\n            p1: self * c.p1,\n            p2: self * c.p2,\n            p3: self * c.p3,\n        }\n    }\n}\n\nimpl Iterator for ToQuads {\n    type Item = (f64, f64, QuadBez);\n\n    fn next(&mut self) -> Option<(f64, f64, QuadBez)> {\n        if self.i == self.n {\n            return None;\n        }\n        let t0 = self.i as f64 / self.n as f64;\n        let t1 = (self.i + 1) as f64 / self.n as f64;\n        let seg = self.c.subsegment(t0..t1);\n        let p1x2 = 3.0 * seg.p1.to_vec2() - seg.p0.to_vec2();\n        let p2x2 = 3.0 * seg.p2.to_vec2() - seg.p3.to_vec2();\n        let result = QuadBez::new(seg.p0, ((p1x2 + p2x2) / 4.0).to_point(), seg.p3);\n        self.i += 1;\n        Some((t0, t1, result))\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let remaining = self.n - self.i;\n        (remaining, Some(remaining))\n    }\n}\n\n/// Convert multiple cubic Bézier curves to quadratic splines.\n///\n/// Ensures that the resulting splines have the same number of control points.\n///\n/// Rust port of cu2qu [cubic_approx_quadratic](https://github.com/fonttools/fonttools/blob/3b9a73ff8379ab49d3ce35aaaaf04b3a7d9d1655/Lib/fontTools/cu2qu/cu2qu.py#L322)\npub fn cubics_to_quadratic_splines(curves: &[CubicBez], accuracy: f64) -> Option<Vec<QuadSpline>> {\n    let mut result = Vec::new();\n    let mut split_order = 0;\n\n    while split_order <= MAX_SPLINE_SPLIT {\n        split_order += 1;\n        result.clear();\n\n        for curve in curves {\n            match curve.approx_spline_n(split_order, accuracy) {\n                Some(spline) => result.push(spline),\n                None => break,\n            }\n        }\n\n        if result.len() == curves.len() {\n            return Some(result);\n        }\n    }\n    None\n}\n#[cfg(test)]\nmod tests {\n    use crate::{\n        cubics_to_quadratic_splines, Affine, CubicBez, Nearest, ParamCurve, ParamCurveArclen,\n        ParamCurveArea, ParamCurveDeriv, ParamCurveExtrema, ParamCurveNearest, Point, QuadBez,\n        QuadSpline,\n    };\n\n    #[test]\n    fn cubicbez_deriv() {\n        // y = x^2\n        let c = CubicBez::new(\n            (0.0, 0.0),\n            (1.0 / 3.0, 0.0),\n            (2.0 / 3.0, 1.0 / 3.0),\n            (1.0, 1.0),\n        );\n        let deriv = c.deriv();\n\n        let n = 10;\n        for i in 0..=n {\n            let t = (i as f64) * (n as f64).recip();\n            let delta = 1e-6;\n            let p = c.eval(t);\n            let p1 = c.eval(t + delta);\n            let d_approx = (p1 - p) * delta.recip();\n            let d = deriv.eval(t).to_vec2();\n            assert!((d - d_approx).hypot() < delta * 2.0);\n        }\n    }\n\n    #[test]\n    fn cubicbez_arclen() {\n        // y = x^2\n        let c = CubicBez::new(\n            (0.0, 0.0),\n            (1.0 / 3.0, 0.0),\n            (2.0 / 3.0, 1.0 / 3.0),\n            (1.0, 1.0),\n        );\n        let true_arclen = 0.5 * 5.0f64.sqrt() + 0.25 * (2.0 + 5.0f64.sqrt()).ln();\n        for i in 0..12 {\n            let accuracy = 0.1f64.powi(i);\n            let error = c.arclen(accuracy) - true_arclen;\n            assert!(error.abs() < accuracy);\n        }\n    }\n\n    #[test]\n    fn cubicbez_inv_arclen() {\n        // y = x^2 / 100\n        let c = CubicBez::new(\n            (0.0, 0.0),\n            (100.0 / 3.0, 0.0),\n            (200.0 / 3.0, 100.0 / 3.0),\n            (100.0, 100.0),\n        );\n        let true_arclen = 100.0 * (0.5 * 5.0f64.sqrt() + 0.25 * (2.0 + 5.0f64.sqrt()).ln());\n        for i in 0..12 {\n            let accuracy = 0.1f64.powi(i);\n            let n = 10;\n            for j in 0..=n {\n                let arc = (j as f64) * ((n as f64).recip() * true_arclen);\n                let t = c.inv_arclen(arc, accuracy * 0.5);\n                let actual_arc = c.subsegment(0.0..t).arclen(accuracy * 0.5);\n                assert!(\n                    (arc - actual_arc).abs() < accuracy,\n                    \"at accuracy {accuracy:e}, wanted {actual_arc} got {arc}\"\n                );\n            }\n        }\n        // corner case: user passes accuracy larger than total arc length\n        let accuracy = true_arclen * 1.1;\n        let arc = true_arclen * 0.5;\n        let t = c.inv_arclen(arc, accuracy);\n        let actual_arc = c.subsegment(0.0..t).arclen(accuracy);\n        assert!(\n            (arc - actual_arc).abs() < 2.0 * accuracy,\n            \"at accuracy {accuracy:e}, want {actual_arc} got {arc}\"\n        );\n    }\n\n    #[test]\n    fn cubicbez_inv_arclen_accuracy() {\n        let c = CubicBez::new((0.2, 0.73), (0.35, 1.08), (0.85, 1.08), (1.0, 0.73));\n        let true_t = c.inv_arclen(0.5, 1e-12);\n        for i in 1..12 {\n            let accuracy = (0.1f64).powi(i);\n            let approx_t = c.inv_arclen(0.5, accuracy);\n            assert!((approx_t - true_t).abs() <= accuracy);\n        }\n    }\n\n    #[test]\n    #[allow(clippy::float_cmp)]\n    fn cubicbez_signed_area_linear() {\n        // y = 1 - x\n        let c = CubicBez::new(\n            (1.0, 0.0),\n            (2.0 / 3.0, 1.0 / 3.0),\n            (1.0 / 3.0, 2.0 / 3.0),\n            (0.0, 1.0),\n        );\n        let epsilon = 1e-12;\n        assert_eq!((Affine::rotate(0.5) * c).signed_area(), 0.5);\n        assert!(((Affine::rotate(0.5) * c).signed_area() - 0.5).abs() < epsilon);\n        assert!(((Affine::translate((0.0, 1.0)) * c).signed_area() - 1.0).abs() < epsilon);\n        assert!(((Affine::translate((1.0, 0.0)) * c).signed_area() - 1.0).abs() < epsilon);\n    }\n\n    #[test]\n    fn cubicbez_signed_area() {\n        // y = 1 - x^3\n        let c = CubicBez::new((1.0, 0.0), (2.0 / 3.0, 1.0), (1.0 / 3.0, 1.0), (0.0, 1.0));\n        let epsilon = 1e-12;\n        assert!((c.signed_area() - 0.75).abs() < epsilon);\n        assert!(((Affine::rotate(0.5) * c).signed_area() - 0.75).abs() < epsilon);\n        assert!(((Affine::translate((0.0, 1.0)) * c).signed_area() - 1.25).abs() < epsilon);\n        assert!(((Affine::translate((1.0, 0.0)) * c).signed_area() - 1.25).abs() < epsilon);\n    }\n\n    #[test]\n    fn cubicbez_nearest() {\n        fn verify(result: Nearest, expected: f64) {\n            assert!(\n                (result.t - expected).abs() < 1e-6,\n                \"got {result:?} expected {expected}\"\n            );\n        }\n        // y = x^3\n        let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 0.0), (1.0, 1.0));\n        verify(c.nearest((0.1, 0.001).into(), 1e-6), 0.1);\n        verify(c.nearest((0.2, 0.008).into(), 1e-6), 0.2);\n        verify(c.nearest((0.3, 0.027).into(), 1e-6), 0.3);\n        verify(c.nearest((0.4, 0.064).into(), 1e-6), 0.4);\n        verify(c.nearest((0.5, 0.125).into(), 1e-6), 0.5);\n        verify(c.nearest((0.6, 0.216).into(), 1e-6), 0.6);\n        verify(c.nearest((0.7, 0.343).into(), 1e-6), 0.7);\n        verify(c.nearest((0.8, 0.512).into(), 1e-6), 0.8);\n        verify(c.nearest((0.9, 0.729).into(), 1e-6), 0.9);\n        verify(c.nearest((1.0, 1.0).into(), 1e-6), 1.0);\n        verify(c.nearest((1.1, 1.1).into(), 1e-6), 1.0);\n        verify(c.nearest((-0.1, 0.0).into(), 1e-6), 0.0);\n        let a = Affine::rotate(0.5);\n        verify((a * c).nearest(a * Point::new(0.1, 0.001), 1e-6), 0.1);\n    }\n\n    // ensure to_quads returns something given colinear points\n    #[test]\n    fn degenerate_to_quads() {\n        let c = CubicBez::new((0., 9.), (6., 6.), (12., 3.0), (18., 0.0));\n        let quads = c.to_quads(1e-6).collect::<Vec<_>>();\n        assert_eq!(quads.len(), 1, \"{:?}\", &quads);\n    }\n\n    #[test]\n    fn cubicbez_extrema() {\n        // y = x^2\n        let q = CubicBez::new((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0));\n        let extrema = q.extrema();\n        assert_eq!(extrema.len(), 1);\n        assert!((extrema[0] - 0.5).abs() < 1e-6);\n\n        let q = CubicBez::new((0.4, 0.5), (0.0, 1.0), (1.0, 0.0), (0.5, 0.4));\n        let extrema = q.extrema();\n        assert_eq!(extrema.len(), 4);\n    }\n\n    #[test]\n    fn cubicbez_toquads() {\n        // y = x^3\n        let c = CubicBez::new((0.0, 0.0), (1.0 / 3.0, 0.0), (2.0 / 3.0, 0.0), (1.0, 1.0));\n        for i in 0..10 {\n            let accuracy = 0.1f64.powi(i);\n            let mut worst: f64 = 0.0;\n            for (_count, (t0, t1, q)) in c.to_quads(accuracy).enumerate() {\n                let epsilon = 1e-12;\n                assert!((q.start() - c.eval(t0)).hypot() < epsilon);\n                assert!((q.end() - c.eval(t1)).hypot() < epsilon);\n                let n = 4;\n                for j in 0..=n {\n                    let t = (j as f64) * (n as f64).recip();\n                    let p = q.eval(t);\n                    let err = (p.y - p.x.powi(3)).abs();\n                    worst = worst.max(err);\n                    assert!(err < accuracy, \"got {err} wanted {accuracy}\");\n                }\n            }\n        }\n    }\n\n    #[test]\n    fn cubicbez_approx_spline() {\n        let c1 = CubicBez::new(\n            (550.0, 258.0),\n            (1044.0, 482.0),\n            (2029.0, 1841.0),\n            (1934.0, 1554.0),\n        );\n\n        let quad = c1.try_approx_quadratic(344.0);\n        let expected = QuadBez::new(\n            Point::new(550.0, 258.0),\n            Point::new(1673.665720592873, 767.5164401068898),\n            Point::new(1934.0, 1554.0),\n        );\n        assert!(quad.is_some());\n        assert_eq!(quad.unwrap(), expected);\n\n        let quad = c1.try_approx_quadratic(343.0);\n        assert!(quad.is_none());\n\n        let spline = c1.approx_spline_n(2, 343.0);\n        assert!(spline.is_some());\n        let spline = spline.unwrap();\n        let expected = [\n            Point::new(550.0, 258.0),\n            Point::new(920.5, 426.0),\n            Point::new(2005.25, 1769.25),\n            Point::new(1934.0, 1554.0),\n        ];\n        assert_eq!(spline.points().len(), expected.len());\n        for (got, &wanted) in spline.points().iter().zip(expected.iter()) {\n            assert!(got.distance(wanted) < 5.0)\n        }\n\n        let spline = c1.approx_spline(5.0);\n        let expected = [\n            Point::new(550.0, 258.0),\n            Point::new(673.5, 314.0),\n            Point::new(984.8777777777776, 584.2666666666667),\n            Point::new(1312.6305555555557, 927.825),\n            Point::new(1613.1194444444443, 1267.425),\n            Point::new(1842.7055555555555, 1525.8166666666666),\n            Point::new(1957.75, 1625.75),\n            Point::new(1934.0, 1554.0),\n        ];\n        assert!(spline.is_some());\n        let spline = spline.unwrap();\n        assert_eq!(spline.points().len(), expected.len());\n        for (got, &wanted) in spline.points().iter().zip(expected.iter()) {\n            assert!(got.distance(wanted) < 5.0)\n        }\n    }\n\n    #[test]\n    fn cubicbez_cubics_to_quadratic_splines() {\n        let curves = vec![\n            CubicBez::new(\n                (550.0, 258.0),\n                (1044.0, 482.0),\n                (2029.0, 1841.0),\n                (1934.0, 1554.0),\n            ),\n            CubicBez::new(\n                (859.0, 384.0),\n                (1998.0, 116.0),\n                (1596.0, 1772.0),\n                (8.0, 1824.0),\n            ),\n            CubicBez::new(\n                (1090.0, 937.0),\n                (418.0, 1300.0),\n                (125.0, 91.0),\n                (104.0, 37.0),\n            ),\n        ];\n        let converted = cubics_to_quadratic_splines(&curves, 5.0);\n        assert!(converted.is_some());\n        let converted = converted.unwrap();\n        assert_eq!(converted[0].points().len(), 8);\n        assert_eq!(converted[1].points().len(), 8);\n        assert_eq!(converted[2].points().len(), 8);\n        assert!(converted[0].points()[1].distance(Point::new(673.5, 314.0)) < 0.0001);\n        assert!(\n            converted[0].points()[2].distance(Point::new(88639.0 / 90.0, 52584.0 / 90.0)) < 0.0001\n        );\n    }\n\n    #[test]\n    fn cubicbez_approx_spline_div_exact() {\n        // Ensure rounding behavior for division matches fonttools\n        // cu2qu.\n        // See <https://github.com/linebender/kurbo/issues/272>\n        let cubic = CubicBez::new(\n            Point::new(408.0, 321.0),\n            Point::new(408.0, 452.0),\n            Point::new(342.0, 560.0),\n            Point::new(260.0, 560.0),\n        );\n        let spline = cubic.approx_spline(1.0).unwrap();\n        assert_eq!(\n            spline.points(),\n            &[\n                Point::new(408.0, 321.0),\n                // Previous behavior produced 386.49999999999994 for the\n                // y coordinate leading to inconsistent rounding.\n                Point::new(408.0, 386.5),\n                Point::new(368.16666666666663, 495.0833333333333),\n                Point::new(301.0, 560.0),\n                Point::new(260.0, 560.0)\n            ]\n        )\n    }\n\n    #[test]\n    fn cubicbez_inflections() {\n        let c = CubicBez::new((0., 0.), (0.8, 1.), (0.2, 1.), (1., 0.));\n        let inflections = c.inflections();\n        assert_eq!(inflections.len(), 2);\n        assert!((inflections[0] - 0.311018).abs() < 1e-6);\n        assert!((inflections[1] - 0.688982).abs() < 1e-6);\n        let c = CubicBez::new((0., 0.), (1., 1.), (2., -1.), (3., 0.));\n        let inflections = c.inflections();\n        assert_eq!(inflections.len(), 1);\n        assert!((inflections[0] - 0.5).abs() < 1e-6);\n        let c = CubicBez::new((0., 0.), (1., 1.), (2., 1.), (3., 0.));\n        let inflections = c.inflections();\n        assert_eq!(inflections.len(), 0);\n    }\n\n    #[test]\n    fn cubic_to_quadratic_matches_python() {\n        // from https://github.com/googlefonts/fontmake-rs/issues/217\n        let cubic = CubicBez {\n            p0: (796.0, 319.0).into(),\n            p1: (727.0, 314.0).into(),\n            p2: (242.0, 303.0).into(),\n            p3: (106.0, 303.0).into(),\n        };\n\n        // FontTools can approximate this curve successfully in 7 splits, we can too\n        assert!(cubic.approx_spline_n(7, 1.0).is_some());\n\n        // FontTools can solve this with accuracy 0.001, we can too\n        assert!(cubics_to_quadratic_splines(&[cubic], 0.001).is_some());\n    }\n\n    #[test]\n    fn cubics_to_quadratic_splines_matches_python() {\n        // https://github.com/linebender/kurbo/pull/273\n        let light = CubicBez::new((378., 608.), (378., 524.), (355., 455.), (266., 455.));\n        let regular = CubicBez::new((367., 607.), (367., 511.), (338., 472.), (243., 472.));\n        let bold = CubicBez::new(\n            (372.425, 593.05),\n            (372.425, 524.95),\n            (355.05, 485.95),\n            (274., 485.95),\n        );\n        let qsplines = cubics_to_quadratic_splines(&[light, regular, bold], 1.0).unwrap();\n        assert_eq!(\n            qsplines,\n            [\n                QuadSpline::new(vec![\n                    (378.0, 608.0).into(),\n                    (378.0, 566.0).into(),\n                    (359.0833333333333, 496.5).into(),\n                    (310.5, 455.0).into(),\n                    (266.0, 455.0).into(),\n                ]),\n                QuadSpline::new(vec![\n                    (367.0, 607.0).into(),\n                    (367.0, 559.0).into(),\n                    // Previous behavior produced 496.5 for the y coordinate\n                    (344.5833333333333, 499.49999999999994).into(),\n                    (290.5, 472.0).into(),\n                    (243.0, 472.0).into(),\n                ]),\n                QuadSpline::new(vec![\n                    (372.425, 593.05).into(),\n                    (372.425, 559.0).into(),\n                    (356.98333333333335, 511.125).into(),\n                    (314.525, 485.95).into(),\n                    (274.0, 485.95).into(),\n                ]),\n            ]\n        )\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/ellipse.rs",
      "sha256": "d018c98ec9893a1e88b44142b77282a8bea680087a1df5347ff8647c2d8ba6cd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Implementation of ellipse shape.\n\nuse core::f64::consts::PI;\nuse core::{\n    iter,\n    ops::{Add, Mul, Sub},\n};\n\nuse crate::{Affine, Arc, ArcAppendIter, Circle, PathEl, Point, Rect, Shape, Size, Vec2};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// An ellipse.\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Ellipse {\n    /// All ellipses can be represented as an affine map of the unit circle,\n    /// centred at (0, 0). Therefore we can store the ellipse as an affine map,\n    /// with the implication that it be applied to the unit circle to recover the\n    /// actual shape.\n    inner: Affine,\n}\n\nimpl Ellipse {\n    /// Create A new ellipse with a given center, radii, and rotation.\n    ///\n    /// The returned ellipse will be the result of taking a circle, stretching\n    /// it by the `radii` along the x and y axes, then rotating it from the\n    /// x axis by `rotation` radians, before finally translating the center\n    /// to `center`.\n    ///\n    /// Rotation is clockwise in a y-down coordinate system. For more on\n    /// rotation, see [`Affine::rotate`].\n    #[inline]\n    pub fn new(center: impl Into<Point>, radii: impl Into<Vec2>, x_rotation: f64) -> Ellipse {\n        let Point { x: cx, y: cy } = center.into();\n        let Vec2 { x: rx, y: ry } = radii.into();\n        Ellipse::private_new(Vec2 { x: cx, y: cy }, rx, ry, x_rotation)\n    }\n\n    /// Returns the largest ellipse that can be bounded by this [`Rect`].\n    ///\n    /// This uses the absolute width and height of the rectangle.\n    ///\n    /// This ellipse is always axis-aligned; to apply rotation you can call\n    /// [`with_rotation`] with the result.\n    ///\n    /// [`with_rotation`]: Ellipse::with_rotation\n    #[inline]\n    pub fn from_rect(rect: Rect) -> Self {\n        let center = rect.center().to_vec2();\n        let Size { width, height } = rect.size() / 2.0;\n        Ellipse::private_new(center, width, height, 0.0)\n    }\n\n    /// Create an ellipse from an affine transformation of the unit circle.\n    #[inline]\n    pub fn from_affine(affine: Affine) -> Self {\n        Ellipse { inner: affine }\n    }\n\n    /// Create a new `Ellipse` centered on the provided point.\n    #[inline]\n    #[must_use]\n    pub fn with_center(self, new_center: Point) -> Ellipse {\n        let Point { x: cx, y: cy } = new_center;\n        Ellipse {\n            inner: self.inner.with_translation(Vec2 { x: cx, y: cy }),\n        }\n    }\n\n    /// Create a new `Ellipse` with the provided radii.\n    #[must_use]\n    pub fn with_radii(self, new_radii: Vec2) -> Ellipse {\n        let rotation = self.inner.svd().1;\n        let translation = self.inner.translation();\n        Ellipse::private_new(translation, new_radii.x, new_radii.y, rotation)\n    }\n\n    /// Create a new `Ellipse`, with the rotation replaced by `rotation`\n    /// radians.\n    ///\n    /// The rotation is clockwise, for a y-down coordinate system. For more\n    /// on rotation, See [`Affine::rotate`].\n    #[must_use]\n    pub fn with_rotation(self, rotation: f64) -> Ellipse {\n        let scale = self.inner.svd().0;\n        let translation = self.inner.translation();\n        Ellipse::private_new(translation, scale.x, scale.y, rotation)\n    }\n\n    #[deprecated(since = \"0.7.0\", note = \"use with_rotation instead\")]\n    #[must_use]\n    #[doc(hidden)]\n    pub fn with_x_rotation(self, rotation_radians: f64) -> Ellipse {\n        self.with_rotation(rotation_radians)\n    }\n\n    /// This gives us an internal method without any type conversions.\n    #[inline]\n    fn private_new(center: Vec2, scale_x: f64, scale_y: f64, x_rotation: f64) -> Ellipse {\n        // Since the circle is symmetric about the x and y axes, using absolute values for the\n        // radii results in the same ellipse. For simplicity we make this change here.\n        Ellipse {\n            inner: Affine::translate(center)\n                * Affine::rotate(x_rotation)\n                * Affine::scale_non_uniform(scale_x.abs(), scale_y.abs()),\n        }\n    }\n\n    // Getters and setters.\n\n    /// Returns the center of this ellipse.\n    #[inline]\n    pub fn center(&self) -> Point {\n        let Vec2 { x: cx, y: cy } = self.inner.translation();\n        Point { x: cx, y: cy }\n    }\n\n    /// Returns the two radii of this ellipse.\n    ///\n    /// The first number is the horizontal radius and the second is the vertical\n    /// radius, before rotation.\n    pub fn radii(&self) -> Vec2 {\n        self.inner.svd().0\n    }\n\n    /// The ellipse's rotation, in radians.\n    ///\n    /// This allows all possible ellipses to be drawn by always starting with\n    /// an ellipse with the two radii on the x and y axes.\n    pub fn rotation(&self) -> f64 {\n        self.inner.svd().1\n    }\n\n    /// Returns the radii and the rotation of this ellipse.\n    ///\n    /// Equivalent to `(self.radii(), self.rotation())` but more efficient.\n    pub fn radii_and_rotation(&self) -> (Vec2, f64) {\n        self.inner.svd()\n    }\n\n    /// Is this ellipse finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.inner.is_finite()\n    }\n\n    /// Is this ellipse NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.inner.is_nan()\n    }\n\n    #[doc(hidden)]\n    #[deprecated(since = \"0.7.0\", note = \"use rotation() instead\")]\n    pub fn x_rotation(&self) -> f64 {\n        self.rotation()\n    }\n}\n\nimpl Add<Vec2> for Ellipse {\n    type Output = Ellipse;\n\n    /// In this context adding a `Vec2` applies the corresponding translation to the ellipse.\n    #[inline]\n    #[allow(clippy::suspicious_arithmetic_impl)]\n    fn add(self, v: Vec2) -> Ellipse {\n        Ellipse {\n            inner: Affine::translate(v) * self.inner,\n        }\n    }\n}\n\nimpl Sub<Vec2> for Ellipse {\n    type Output = Ellipse;\n\n    /// In this context subtracting a `Vec2` applies the corresponding translation to the ellipse.\n    #[inline]\n    fn sub(self, v: Vec2) -> Ellipse {\n        Ellipse {\n            inner: Affine::translate(-v) * self.inner,\n        }\n    }\n}\n\nimpl Mul<Ellipse> for Affine {\n    type Output = Ellipse;\n    fn mul(self, other: Ellipse) -> Self::Output {\n        Ellipse {\n            inner: self * other.inner,\n        }\n    }\n}\n\nimpl From<Circle> for Ellipse {\n    fn from(circle: Circle) -> Self {\n        Ellipse::new(circle.center, Vec2::splat(circle.radius), 0.0)\n    }\n}\n\nimpl Shape for Ellipse {\n    type PathElementsIter<'iter> = iter::Chain<iter::Once<PathEl>, ArcAppendIter>;\n\n    fn path_elements(&self, tolerance: f64) -> Self::PathElementsIter<'_> {\n        let (radii, x_rotation) = self.inner.svd();\n        Arc {\n            center: self.center(),\n            radii,\n            start_angle: 0.0,\n            sweep_angle: 2.0 * PI,\n            x_rotation,\n        }\n        .path_elements(tolerance)\n    }\n\n    #[inline]\n    fn area(&self) -> f64 {\n        let Vec2 { x, y } = self.radii();\n        PI * x * y\n    }\n\n    #[inline]\n    fn perimeter(&self, accuracy: f64) -> f64 {\n        // TODO rather than delegate to the bezier path, it is possible to use various series\n        // expansions to compute the perimeter to any accuracy. I believe Ramanujan authored the\n        // quickest to converge. See\n        // https://www.mathematica-journal.com/2009/11/23/on-the-perimeter-of-an-ellipse/\n        // and https://en.wikipedia.org/wiki/Ellipse#Circumference\n        //\n        self.path_segments(0.1).perimeter(accuracy)\n    }\n\n    fn winding(&self, pt: Point) -> i32 {\n        // Strategy here is to apply the inverse map to the point and see if it is in the unit\n        // circle.\n        let inv = self.inner.inverse();\n        if (inv * pt).to_vec2().hypot2() < 1.0 {\n            1\n        } else {\n            0\n        }\n    }\n\n    // Compute a tight bounding box of the ellipse.\n    //\n    // See https://www.iquilezles.org/www/articles/ellipses/ellipses.htm. We can get the two\n    // radius vectors by applying the affine map to the two impulses (1, 0) and (0, 1) which gives\n    // (a, b) and (c, d) if the affine map is\n    //\n    //  a | c | e\n    // -----------\n    //  b | d | f\n    //\n    //  We can then use the method in the link with the translation to get the bounding box.\n    #[inline]\n    fn bounding_box(&self) -> Rect {\n        let aff = self.inner.as_coeffs();\n        let a2 = aff[0] * aff[0];\n        let b2 = aff[1] * aff[1];\n        let c2 = aff[2] * aff[2];\n        let d2 = aff[3] * aff[3];\n        let cx = aff[4];\n        let cy = aff[5];\n        let range_x = (a2 + c2).sqrt();\n        let range_y = (b2 + d2).sqrt();\n        Rect {\n            x0: cx - range_x,\n            y0: cy - range_y,\n            x1: cx + range_x,\n            y1: cy + range_y,\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Ellipse, Point, Shape};\n    use std::f64::consts::PI;\n\n    fn assert_approx_eq(x: f64, y: f64) {\n        // Note: we might want to be more rigorous in testing the accuracy\n        // of the conversion into Béziers. But this seems good enough.\n        assert!((x - y).abs() < 1e-7, \"{x} != {y}\");\n    }\n\n    #[test]\n    fn area_sign() {\n        let center = Point::new(5.0, 5.0);\n        let e = Ellipse::new(center, (5.0, 5.0), 1.0);\n        assert_approx_eq(e.area(), 25.0 * PI);\n        let e = Ellipse::new(center, (5.0, 10.0), 1.0);\n        assert_approx_eq(e.area(), 50.0 * PI);\n\n        assert_eq!(e.winding(center), 1);\n\n        let p = e.to_path(1e-9);\n        assert_approx_eq(e.area(), p.area());\n        assert_eq!(e.winding(center), p.winding(center));\n\n        let e_neg_radius = Ellipse::new(center, (-5.0, 10.0), 1.0);\n        assert_approx_eq(e_neg_radius.area(), 50.0 * PI);\n\n        assert_eq!(e_neg_radius.winding(center), 1);\n\n        let p_neg_radius = e_neg_radius.to_path(1e-9);\n        assert_approx_eq(e_neg_radius.area(), p_neg_radius.area());\n        assert_eq!(e_neg_radius.winding(center), p_neg_radius.winding(center));\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/fit.rs",
      "sha256": "d03b17ca74b5eaa3cecfe30bf92b2f2bc29b11bb05e7551652045b3f3ed21a97",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! An implementation of cubic Bézier curve fitting based on a quartic\n//! solver making signed area and moment match the source curve.\n\nuse core::ops::Range;\n\nuse alloc::vec::Vec;\n\nuse arrayvec::ArrayVec;\n\nuse crate::{\n    common::{\n        factor_quartic_inner, solve_cubic, solve_itp_fallible, solve_quadratic,\n        GAUSS_LEGENDRE_COEFFS_16,\n    },\n    Affine, BezPath, CubicBez, Line, ParamCurve, ParamCurveArclen, ParamCurveNearest, Point, Vec2,\n};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// The source curve for curve fitting.\n///\n/// This trait is a general representation of curves to be used as input to a curve\n/// fitting process. It can represent source curves with cusps and corners, though\n/// if the corners are known in advance, it may be better to run curve fitting on\n/// subcurves bounded by the corners.\n///\n/// The trait primarily works by sampling the source curve and computing the position\n/// and derivative at each sample. Those derivatives are then used for multiple\n/// sub-tasks, including ensuring G1 continuity at subdivision points, computing the\n/// area and moment of the curve for curve fitting, and casting rays for evaluation\n/// of a distance metric to test accuracy.\n///\n/// A major motivation is computation of offset curves, which often have cusps, but\n/// the presence and location of those cusps is not generally known. It is also\n/// intended for conversion between curve types (for example, piecewise Euler spiral\n/// or NURBS), and distortion effects such as perspective transform.\n///\n/// Note general similarities to [`ParamCurve`] but also important differences.\n/// Instead of separate [`eval`] and evaluation of derivative, have a single\n/// [`sample_pt_deriv`] method which can be more efficient and also handles cusps more\n/// robustly. Also there is no method for subsegment, as that is not needed and\n/// would be annoying to implement.\n///\n/// [`ParamCurve`]: crate::ParamCurve\n/// [`eval`]: crate::ParamCurve::eval\n/// [`sample_pt_deriv`]: ParamCurveFit::sample_pt_deriv\npub trait ParamCurveFit {\n    /// Evaluate the curve and its tangent at parameter `t`.\n    ///\n    /// For a regular curve (one not containing a cusp or corner), the\n    /// derivative is a good choice for the tangent vector and the `sign`\n    /// parameter can be ignored. Otherwise, the `sign` parameter selects which\n    /// side of the discontinuity the tangent will be sampled from.\n    ///\n    /// Generally `t` is in the range [0..1].\n    fn sample_pt_tangent(&self, t: f64, sign: f64) -> CurveFitSample;\n\n    /// Evaluate the point and derivative at parameter `t`.\n    ///\n    /// In curves with cusps, the derivative can go to zero.\n    fn sample_pt_deriv(&self, t: f64) -> (Point, Vec2);\n\n    /// Compute moment integrals.\n    ///\n    /// This method computes the integrals of y dx, x y dx, and y^2 dx over the\n    /// length of this curve. From these integrals it is fairly straightforward\n    /// to derive the moments needed for curve fitting.\n    ///\n    /// A default implementation is proved which does quadrature integration\n    /// with Green's theorem, in terms of samples evaluated with\n    /// [`sample_pt_deriv`].\n    ///\n    /// [`sample_pt_deriv`]: ParamCurveFit::sample_pt_deriv\n    fn moment_integrals(&self, range: Range<f64>) -> (f64, f64, f64) {\n        let t0 = 0.5 * (range.start + range.end);\n        let dt = 0.5 * (range.end - range.start);\n        let (a, x, y) = GAUSS_LEGENDRE_COEFFS_16\n            .iter()\n            .map(|(wi, xi)| {\n                let t = t0 + xi * dt;\n                let (p, d) = self.sample_pt_deriv(t);\n                let a = wi * d.x * p.y;\n                let x = p.x * a;\n                let y = p.y * a;\n                (a, x, y)\n            })\n            .fold((0.0, 0.0, 0.0), |(a0, x0, y0), (a1, x1, y1)| {\n                (a0 + a1, x0 + x1, y0 + y1)\n            });\n        (a * dt, x * dt, y * dt)\n    }\n\n    /// Find a cusp or corner within the given range.\n    ///\n    /// If the range contains a corner or cusp, return it. If there is more\n    /// than one such discontinuity, any can be reported, as the function will\n    /// be called repeatedly after subdivision of the range.\n    ///\n    /// Do not report cusps at the endpoints of the range, as this may cause\n    /// potentially infinite subdivision. In particular, when a cusp is reported\n    /// and this method is called on a subdivided range bounded by the reported\n    /// cusp, then the subsequent call should not report a cusp there.\n    ///\n    /// The definition of what exactly constitutes a cusp is somewhat loose.\n    /// If a cusp is missed, then the curve fitting algorithm will attempt to\n    /// fit the curve with a smooth curve, which is generally not a disaster\n    /// will usually result in more subdivision. Conversely, it might be useful\n    /// to report near-cusps, specifically points of curvature maxima where the\n    /// curvature is large but still mathematically finite.\n    fn break_cusp(&self, range: Range<f64>) -> Option<f64>;\n}\n\n/// A sample point of a curve for fitting.\npub struct CurveFitSample {\n    /// A point on the curve at the sample location.\n    pub p: Point,\n    /// A vector tangent to the curve at the sample location.\n    pub tangent: Vec2,\n}\n\nimpl CurveFitSample {\n    /// Intersect a ray orthogonal to the tangent with the given cubic.\n    ///\n    /// Returns a vector of `t` values on the cubic.\n    fn intersect(&self, c: CubicBez) -> ArrayVec<f64, 3> {\n        let p1 = 3.0 * (c.p1 - c.p0);\n        let p2 = 3.0 * c.p2.to_vec2() - 6.0 * c.p1.to_vec2() + 3.0 * c.p0.to_vec2();\n        let p3 = (c.p3 - c.p0) - 3.0 * (c.p2 - c.p1);\n        let c0 = (c.p0 - self.p).dot(self.tangent);\n        let c1 = p1.dot(self.tangent);\n        let c2 = p2.dot(self.tangent);\n        let c3 = p3.dot(self.tangent);\n        solve_cubic(c0, c1, c2, c3)\n            .into_iter()\n            .filter(|t| (0.0..=1.0).contains(t))\n            .collect()\n    }\n}\n\n/// Generate a Bézier path that fits the source curve.\n///\n/// This function is still experimental and the signature might change; it's possible\n/// it might become a method on the [`ParamCurveFit`] trait.\n///\n/// This function recursively subdivides the curve in half by the parameter when the\n/// accuracy is not met. That gives a reasonably optimized result but not necessarily\n/// the minimum number of segments.\n///\n/// In general, the resulting Bézier path should have a Fréchet distance less than\n/// the provided `accuracy` parameter. However, this is not a rigorous guarantee, as\n/// the error metric is computed approximately.\n///\n/// This function is intended for use when the source curve is piecewise continuous,\n/// with the discontinuities reported by the cusp method. In applications (such as\n/// stroke expansion) where this property may not hold, it is up to the client to\n/// detect and handle such cases. Even so, best effort is made to avoid infinite\n/// subdivision.\n///\n/// When a higher degree of optimization is desired (at considerably more runtime cost),\n/// consider [`fit_to_bezpath_opt`] instead.\npub fn fit_to_bezpath(source: &impl ParamCurveFit, accuracy: f64) -> BezPath {\n    let mut path = BezPath::new();\n    fit_to_bezpath_rec(source, 0.0..1.0, accuracy, &mut path);\n    path\n}\n\n// Discussion question: possibly should take endpoint samples, to avoid\n// duplication of that work.\nfn fit_to_bezpath_rec(\n    source: &impl ParamCurveFit,\n    range: Range<f64>,\n    accuracy: f64,\n    path: &mut BezPath,\n) {\n    let start = range.start;\n    let end = range.end;\n    let start_p = source.sample_pt_tangent(range.start, 1.0).p;\n    let end_p = source.sample_pt_tangent(range.end, -1.0).p;\n    if start_p.distance_squared(end_p) <= accuracy * accuracy {\n        if let Some((c, _)) = try_fit_line(source, accuracy, range, start_p, end_p) {\n            if path.is_empty() {\n                path.move_to(c.p0);\n            }\n            path.curve_to(c.p1, c.p2, c.p3);\n            return;\n        }\n    }\n    let t = if let Some(t) = source.break_cusp(start..end) {\n        t\n    } else if let Some((c, _)) = fit_to_cubic(source, start..end, accuracy) {\n        if path.is_empty() {\n            path.move_to(c.p0);\n        }\n        path.curve_to(c.p1, c.p2, c.p3);\n        return;\n    } else {\n        // A smarter approach is possible than midpoint subdivision, but would be\n        // a significant increase in complexity.\n        0.5 * (start + end)\n    };\n    if t == start || t == end {\n        // infinite recursion, just draw a line\n        let p1 = start_p.lerp(end_p, 1.0 / 3.0);\n        let p2 = end_p.lerp(start_p, 1.0 / 3.0);\n        if path.is_empty() {\n            path.move_to(start_p);\n        }\n        path.curve_to(p1, p2, end_p);\n        return;\n    }\n    fit_to_bezpath_rec(source, start..t, accuracy, path);\n    fit_to_bezpath_rec(source, t..end, accuracy, path);\n}\n\nconst N_SAMPLE: usize = 20;\n\n/// An acceleration structure for estimating curve distance\nstruct CurveDist {\n    samples: ArrayVec<CurveFitSample, N_SAMPLE>,\n    arcparams: ArrayVec<f64, N_SAMPLE>,\n    range: Range<f64>,\n    /// A \"spicy\" curve is one with potentially extreme curvature variation,\n    /// so use arc length measurement for better accuracy.\n    spicy: bool,\n}\n\nimpl CurveDist {\n    fn from_curve(source: &impl ParamCurveFit, range: Range<f64>) -> Self {\n        let step = (range.end - range.start) * (1.0 / (N_SAMPLE + 1) as f64);\n        let mut last_tan = None;\n        let mut spicy = false;\n        const SPICY_THRESH: f64 = 0.2;\n        let mut samples = ArrayVec::new();\n        for i in 0..N_SAMPLE + 2 {\n            let sample = source.sample_pt_tangent(range.start + i as f64 * step, 1.0);\n            if let Some(last_tan) = last_tan {\n                let cross = sample.tangent.cross(last_tan);\n                let dot = sample.tangent.dot(last_tan);\n                if cross.abs() > SPICY_THRESH * dot.abs() {\n                    spicy = true;\n                }\n            }\n            last_tan = Some(sample.tangent);\n            if i > 0 && i < N_SAMPLE + 1 {\n                samples.push(sample);\n            }\n        }\n        CurveDist {\n            samples,\n            arcparams: Default::default(),\n            range,\n            spicy,\n        }\n    }\n\n    fn compute_arc_params(&mut self, source: &impl ParamCurveFit) {\n        const N_SUBSAMPLE: usize = 10;\n        let (start, end) = (self.range.start, self.range.end);\n        let dt = (end - start) * (1.0 / ((N_SAMPLE + 1) * N_SUBSAMPLE) as f64);\n        let mut arclen = 0.0;\n        for i in 0..N_SAMPLE + 1 {\n            for j in 0..N_SUBSAMPLE {\n                let t = start + dt * ((i * N_SUBSAMPLE + j) as f64 + 0.5);\n                let (_, deriv) = source.sample_pt_deriv(t);\n                arclen += deriv.hypot();\n            }\n            if i < N_SAMPLE {\n                self.arcparams.push(arclen);\n            }\n        }\n        let arclen_inv = arclen.recip();\n        for x in &mut self.arcparams {\n            *x *= arclen_inv;\n        }\n    }\n\n    /// Evaluate distance based on arc length parametrization\n    fn eval_arc(&self, c: CubicBez, acc2: f64) -> Option<f64> {\n        // TODO: this could perhaps be tuned.\n        const EPS: f64 = 1e-9;\n        let c_arclen = c.arclen(EPS);\n        let mut max_err2 = 0.0;\n        for (sample, s) in self.samples.iter().zip(&self.arcparams) {\n            let t = c.inv_arclen(c_arclen * s, EPS);\n            let err = sample.p.distance_squared(c.eval(t));\n            max_err2 = err.max(max_err2);\n            if max_err2 > acc2 {\n                return None;\n            }\n        }\n        Some(max_err2)\n    }\n\n    /// Evaluate distance to a cubic approximation.\n    ///\n    /// If distance exceeds stated accuracy, can return `None`. Note that\n    /// `acc2` is the square of the target.\n    ///\n    /// Returns the square of the error, which is intended to be a good\n    /// approximation of the Fréchet distance.\n    fn eval_ray(&self, c: CubicBez, acc2: f64) -> Option<f64> {\n        let mut max_err2 = 0.0;\n        for sample in &self.samples {\n            let mut best = acc2 + 1.0;\n            for t in sample.intersect(c) {\n                let err = sample.p.distance_squared(c.eval(t));\n                best = best.min(err);\n            }\n            max_err2 = best.max(max_err2);\n            if max_err2 > acc2 {\n                return None;\n            }\n        }\n        Some(max_err2)\n    }\n\n    fn eval_dist(&mut self, source: &impl ParamCurveFit, c: CubicBez, acc2: f64) -> Option<f64> {\n        // Always compute cheaper distance, hoping for early-out.\n        let ray_dist = self.eval_ray(c, acc2)?;\n        if !self.spicy {\n            return Some(ray_dist);\n        }\n        if self.arcparams.is_empty() {\n            self.compute_arc_params(source);\n        }\n        self.eval_arc(c, acc2)\n    }\n}\n\n/// As described in [Simplifying Bézier paths], strictly optimizing for\n/// Fréchet distance can create bumps. The problem is curves with long\n/// control arms (distance from the control point to the corresponding\n/// endpoint). We mitigate that by applying a penalty as a multiplier to\n/// the measured error (approximate Fréchet distance). This is ReLU-like,\n/// with a value of 1.0 below the elbow, and a given slope above it. The\n/// values here have been determined empirically to give good results.\n///\n/// [Simplifying Bézier paths]:\n/// https://raphlinus.github.io/curves/2023/04/18/bezpath-simplify.html\nconst D_PENALTY_ELBOW: f64 = 0.65;\nconst D_PENALTY_SLOPE: f64 = 2.0;\n\n/// Try fitting a line.\n///\n/// This is especially useful for very short chords, in which the standard\n/// cubic fit is not numerically stable. The tangents are not considered, so\n/// it's useful in cusp and near-cusp situations where the tangents are not\n/// reliable, as well.\n///\n/// Returns the line raised to a cubic and the error, if within tolerance.\nfn try_fit_line(\n    source: &impl ParamCurveFit,\n    accuracy: f64,\n    range: Range<f64>,\n    start: Point,\n    end: Point,\n) -> Option<(CubicBez, f64)> {\n    let acc2 = accuracy * accuracy;\n    let chord_l = Line::new(start, end);\n    const SHORT_N: usize = 7;\n    let mut max_err2 = 0.0;\n    let dt = (range.end - range.start) / (SHORT_N + 1) as f64;\n    for i in 0..SHORT_N {\n        let t = range.start + (i + 1) as f64 * dt;\n        let p = source.sample_pt_deriv(t).0;\n        let err2 = chord_l.nearest(p, accuracy).distance_sq;\n        if err2 > acc2 {\n            // Not in tolerance; likely subdivision will help.\n            return None;\n        }\n        max_err2 = err2.max(max_err2);\n    }\n    let p1 = start.lerp(end, 1.0 / 3.0);\n    let p2 = end.lerp(start, 1.0 / 3.0);\n    let c = CubicBez::new(start, p1, p2, end);\n    Some((c, max_err2))\n}\n\n/// Fit a single cubic to a range of the source curve.\n///\n/// Returns the cubic segment and the square of the error.\n/// Discussion question: should this be a method on the trait instead?\npub fn fit_to_cubic(\n    source: &impl ParamCurveFit,\n    range: Range<f64>,\n    accuracy: f64,\n) -> Option<(CubicBez, f64)> {\n    let start = source.sample_pt_tangent(range.start, 1.0);\n    let end = source.sample_pt_tangent(range.end, -1.0);\n    let d = end.p - start.p;\n    let chord2 = d.hypot2();\n    let acc2 = accuracy * accuracy;\n    if chord2 <= acc2 {\n        // Special case very short chords; try to fit a line.\n        return try_fit_line(source, accuracy, range, start.p, end.p);\n    }\n    let th = d.atan2();\n    fn mod_2pi(th: f64) -> f64 {\n        let th_scaled = th * core::f64::consts::FRAC_1_PI * 0.5;\n        core::f64::consts::PI * 2.0 * (th_scaled - th_scaled.round())\n    }\n    let th0 = mod_2pi(start.tangent.atan2() - th);\n    let th1 = mod_2pi(th - end.tangent.atan2());\n\n    let (mut area, mut x, mut y) = source.moment_integrals(range.clone());\n    let (x0, y0) = (start.p.x, start.p.y);\n    let (dx, dy) = (d.x, d.y);\n    // Subtract off area of chord\n    area -= dx * (y0 + 0.5 * dy);\n    // `area` is signed area of closed curve segment.\n    // This quantity is invariant to translation and rotation.\n\n    // Subtract off moment of chord\n    let dy_3 = dy * (1. / 3.);\n    x -= dx * (x0 * y0 + 0.5 * (x0 * dy + y0 * dx) + dy_3 * dx);\n    y -= dx * (y0 * y0 + y0 * dy + dy_3 * dy);\n    // Translate start point to origin; convert raw integrals to moments.\n    x -= x0 * area;\n    y = 0.5 * y - y0 * area;\n    // Rotate into place (this also scales up by chordlength for efficiency).\n    let moment = d.x * x + d.y * y;\n    // `moment` is the chordlength times the x moment of the curve translated\n    // so its start point is on the origin, and rotated so its end point is on the\n    // x axis.\n\n    let chord2_inv = chord2.recip();\n    let unit_area = area * chord2_inv;\n    let mx = moment * chord2_inv.powi(2);\n    // `unit_area` is signed area scaled to unit chord; `mx` is scaled x moment\n\n    let chord = chord2.sqrt();\n    let aff = Affine::translate(start.p.to_vec2()) * Affine::rotate(th) * Affine::scale(chord);\n    let mut curve_dist = CurveDist::from_curve(source, range);\n    let mut best_c = None;\n    let mut best_err2 = None;\n    for (cand, d0, d1) in cubic_fit(th0, th1, unit_area, mx) {\n        let c = aff * cand;\n        if let Some(err2) = curve_dist.eval_dist(source, c, acc2) {\n            fn scale_f(d: f64) -> f64 {\n                1.0 + (d - D_PENALTY_ELBOW).max(0.0) * D_PENALTY_SLOPE\n            }\n            let scale = scale_f(d0).max(scale_f(d1)).powi(2);\n            let err2 = err2 * scale;\n            if err2 < acc2 && best_err2.map(|best| err2 < best).unwrap_or(true) {\n                best_c = Some(c);\n                best_err2 = Some(err2);\n            }\n        }\n    }\n    match (best_c, best_err2) {\n        (Some(c), Some(err2)) => Some((c, err2)),\n        _ => None,\n    }\n}\n\n/// Returns curves matching area and moment, given unit chord.\nfn cubic_fit(th0: f64, th1: f64, area: f64, mx: f64) -> ArrayVec<(CubicBez, f64, f64), 4> {\n    // Note: maybe we want to take unit vectors instead of angle? Shouldn't\n    // matter much either way though.\n    let (s0, c0) = th0.sin_cos();\n    let (s1, c1) = th1.sin_cos();\n    let a4 = -9.\n        * c0\n        * (((2. * s1 * c1 * c0 + s0 * (2. * c1 * c1 - 1.)) * c0 - 2. * s1 * c1) * c0\n            - c1 * c1 * s0);\n    let a3 = 12.\n        * ((((c1 * (30. * area * c1 - s1) - 15. * area) * c0 + 2. * s0\n            - c1 * s0 * (c1 + 30. * area * s1))\n            * c0\n            + c1 * (s1 - 15. * area * c1))\n            * c0\n            - s0 * c1 * c1);\n    let a2 = 12.\n        * ((((70. * mx + 15. * area) * s1 * s1 + c1 * (9. * s1 - 70. * c1 * mx - 5. * c1 * area))\n            * c0\n            - 5. * s0 * s1 * (3. * s1 - 4. * c1 * (7. * mx + area)))\n            * c0\n            - c1 * (9. * s1 - 70. * c1 * mx - 5. * c1 * area));\n    let a1 = 16.\n        * (((12. * s0 - 5. * c0 * (42. * mx - 17. * area)) * s1\n            - 70. * c1 * (3. * mx - area) * s0\n            - 75. * c0 * c1 * area * area)\n            * s1\n            - 75. * c1 * c1 * area * area * s0);\n    let a0 = 80. * s1 * (42. * s1 * mx - 25. * area * (s1 - c1 * area));\n    // TODO: \"roots\" is not a good name for this variable, as it also contains\n    // the real part of complex conjugate pairs.\n    let mut roots = ArrayVec::<f64, 4>::new();\n    const EPS: f64 = 1e-12;\n    if a4.abs() > EPS {\n        let a = a3 / a4;\n        let b = a2 / a4;\n        let c = a1 / a4;\n        let d = a0 / a4;\n        if let Some(quads) = factor_quartic_inner(a, b, c, d, false) {\n            for (qc1, qc0) in quads {\n                let qroots = solve_quadratic(qc0, qc1, 1.0);\n                if qroots.is_empty() {\n                    // Real part of pair of complex roots\n                    roots.push(-0.5 * qc1);\n                } else {\n                    roots.extend(qroots);\n                }\n            }\n        }\n    } else if a3.abs() > EPS {\n        roots.extend(solve_cubic(a0, a1, a2, a3));\n    } else {\n        roots.extend(solve_quadratic(a0, a1, a2));\n    }\n\n    let s01 = s0 * c1 + s1 * c0;\n    roots\n        .iter()\n        .filter_map(|&d0| {\n            let (d0, d1) = if d0 > 0.0 {\n                let d1 = (d0 * s0 - area * (10. / 3.)) / (0.5 * d0 * s01 - s1);\n                if d1 > 0.0 {\n                    (d0, d1)\n                } else {\n                    (s1 / s01, 0.0)\n                }\n            } else {\n                (0.0, s0 / s01)\n            };\n            // We could implement a maximum d value here.\n            if d0 >= 0.0 && d1 >= 0.0 {\n                Some((\n                    CubicBez::new(\n                        (0.0, 0.0),\n                        (d0 * c0, d0 * s0),\n                        (1.0 - d1 * c1, d1 * s1),\n                        (1.0, 0.0),\n                    ),\n                    d0,\n                    d1,\n                ))\n            } else {\n                None\n            }\n        })\n        .collect()\n}\n\n/// Generate a highly optimized Bézier path that fits the source curve.\n///\n/// This function is still experimental and the signature might change; it's possible\n/// it might become a method on the [`ParamCurveFit`] trait.\n///\n/// This function is considerably slower than [`fit_to_bezpath`], as it computes\n/// optimal subdivision points. Its result is expected to be very close to the optimum\n/// possible Bézier path for the source curve, in that it has a minimal number of curve\n/// segments, and a minimal error over all paths with that number of segments.\n///\n/// See [`fit_to_bezpath`] for an explanation of the `accuracy` parameter.\npub fn fit_to_bezpath_opt(source: &impl ParamCurveFit, accuracy: f64) -> BezPath {\n    let mut cusps = Vec::new();\n    let mut path = BezPath::new();\n    let mut t0 = 0.0;\n    loop {\n        let t1 = cusps.last().copied().unwrap_or(1.0);\n        match fit_to_bezpath_opt_inner(source, accuracy, t0..t1, &mut path) {\n            Some(t) => cusps.push(t),\n            None => match cusps.pop() {\n                Some(t) => t0 = t,\n                None => break,\n            },\n        }\n    }\n    path\n}\n\n/// Fit a range without cusps.\n///\n/// On Ok return, range has been added to the path. On Err return, report a cusp (and don't\n/// mutate path).\nfn fit_to_bezpath_opt_inner(\n    source: &impl ParamCurveFit,\n    accuracy: f64,\n    range: Range<f64>,\n    path: &mut BezPath,\n) -> Option<f64> {\n    if let Some(t) = source.break_cusp(range.clone()) {\n        return Some(t);\n    }\n    let err;\n    if let Some((c, err2)) = fit_to_cubic(source, range.clone(), accuracy) {\n        err = err2.sqrt();\n        if err < accuracy {\n            if range.start == 0.0 {\n                path.move_to(c.p0);\n            }\n            path.curve_to(c.p1, c.p2, c.p3);\n            return None;\n        }\n    } else {\n        err = 2.0 * accuracy;\n    }\n    let (mut t0, t1) = (range.start, range.end);\n    let mut n = 0;\n    let last_err;\n    loop {\n        n += 1;\n        match fit_opt_segment(source, accuracy, t0..t1) {\n            FitResult::ParamVal(t) => t0 = t,\n            FitResult::SegmentError(err) => {\n                last_err = err;\n                break;\n            }\n            FitResult::CuspFound(t) => return Some(t),\n        }\n    }\n    t0 = range.start;\n    const EPS: f64 = 1e-9;\n    let f = |x| fit_opt_err_delta(source, x, accuracy, t0..t1, n);\n    let k1 = 0.2 / accuracy;\n    let ya = -err;\n    let yb = accuracy - last_err;\n    let (_, x) = match solve_itp_fallible(f, 0.0, accuracy, EPS, 1, k1, ya, yb) {\n        Ok(x) => x,\n        Err(t) => return Some(t),\n    };\n    //println!(\"got fit with n={}, err={}\", n, x);\n    let path_len = path.elements().len();\n    for i in 0..n {\n        let t1 = if i < n - 1 {\n            match fit_opt_segment(source, x, t0..range.end) {\n                FitResult::ParamVal(t1) => t1,\n                FitResult::SegmentError(_) => range.end,\n                FitResult::CuspFound(t) => {\n                    path.truncate(path_len);\n                    return Some(t);\n                }\n            }\n        } else {\n            range.end\n        };\n        let (c, _) = fit_to_cubic(source, t0..t1, accuracy).unwrap();\n        if i == 0 && range.start == 0.0 {\n            path.move_to(c.p0);\n        }\n        path.curve_to(c.p1, c.p2, c.p3);\n        t0 = t1;\n        if t0 == range.end {\n            // This is unlikely but could happen when not monotonic.\n            break;\n        }\n    }\n    None\n}\n\nfn measure_one_seg(source: &impl ParamCurveFit, range: Range<f64>, limit: f64) -> Option<f64> {\n    fit_to_cubic(source, range, limit).map(|(_, err2)| err2.sqrt())\n}\n\nenum FitResult {\n    /// The parameter (`t`) value that meets the desired accuracy.\n    ParamVal(f64),\n    /// Error of the measured segment.\n    SegmentError(f64),\n    /// The parameter value where a cusp was found.\n    CuspFound(f64),\n}\n\nfn fit_opt_segment(source: &impl ParamCurveFit, accuracy: f64, range: Range<f64>) -> FitResult {\n    if let Some(t) = source.break_cusp(range.clone()) {\n        return FitResult::CuspFound(t);\n    }\n    let missing_err = accuracy * 2.0;\n    let err = measure_one_seg(source, range.clone(), accuracy).unwrap_or(missing_err);\n    if err <= accuracy {\n        return FitResult::SegmentError(err);\n    }\n    let (t0, t1) = (range.start, range.end);\n    let f = |x| {\n        if let Some(t) = source.break_cusp(range.clone()) {\n            return Err(t);\n        }\n        let err = measure_one_seg(source, t0..x, accuracy).unwrap_or(missing_err);\n        Ok(err - accuracy)\n    };\n    const EPS: f64 = 1e-9;\n    let k1 = 2.0 / (t1 - t0);\n    match solve_itp_fallible(f, t0, t1, EPS, 1, k1, -accuracy, err - accuracy) {\n        Ok((t1, _)) => FitResult::ParamVal(t1),\n        Err(t) => FitResult::CuspFound(t),\n    }\n}\n\n// Ok result is delta error (accuracy - error of last seg).\n// Err result is a cusp.\nfn fit_opt_err_delta(\n    source: &impl ParamCurveFit,\n    accuracy: f64,\n    limit: f64,\n    range: Range<f64>,\n    n: usize,\n) -> Result<f64, f64> {\n    let (mut t0, t1) = (range.start, range.end);\n    for _ in 0..n - 1 {\n        t0 = match fit_opt_segment(source, accuracy, t0..t1) {\n            FitResult::ParamVal(t0) => t0,\n            // In this case, n - 1 will work, which of course means the error is highly\n            // non-monotonic. We should probably harvest that solution.\n            FitResult::SegmentError(_) => return Ok(accuracy),\n            FitResult::CuspFound(t) => return Err(t),\n        }\n    }\n    let err = measure_one_seg(source, t0..t1, limit).unwrap_or(accuracy * 2.0);\n    Ok(accuracy - err)\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/insets.rs",
      "sha256": "120fd9f31eea4391d5ac3b4bd2fcc03ef8ca3c2f3fc6f7ae3f2cde6d04484cc8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A description of the distances between the edges of two rectangles.\n\nuse core::ops::{Add, Neg, Sub};\n\nuse crate::{Rect, Size};\n\n/// Insets from the edges of a rectangle.\n///\n///\n/// The inset value for each edge can be thought of as a delta computed from\n/// the center of the rect to that edge. For instance, with an inset of `2.0` on\n/// the x-axis, a rectangle with the origin `(0.0, 0.0)` with that inset added\n/// will have the new origin at `(-2.0, 0.0)`.\n///\n/// Put alternatively, a positive inset represents increased distance from center,\n/// and a negative inset represents decreased distance from center.\n///\n/// # Examples\n///\n/// Positive insets added to a [`Rect`] produce a larger [`Rect`]:\n/// ```\n/// # use kurbo::{Insets, Rect};\n/// let rect = Rect::from_origin_size((0., 0.,), (10., 10.,));\n/// let insets = Insets::uniform_xy(3., 0.,);\n///\n/// let inset_rect = rect + insets;\n/// assert_eq!(inset_rect.width(), 16.0, \"10.0 + 3.0 × 2\");\n/// assert_eq!(inset_rect.x0, -3.0);\n/// ```\n///\n/// Negative insets added to a [`Rect`] produce a smaller [`Rect`]:\n///\n/// ```\n/// # use kurbo::{Insets, Rect};\n/// let rect = Rect::from_origin_size((0., 0.,), (10., 10.,));\n/// let insets = Insets::uniform_xy(-3., 0.,);\n///\n/// let inset_rect = rect + insets;\n/// assert_eq!(inset_rect.width(), 4.0, \"10.0 - 3.0 × 2\");\n/// assert_eq!(inset_rect.x0, 3.0);\n/// ```\n///\n/// [`Insets`] operate on the absolute rectangle [`Rect::abs`], and so ignore\n/// existing negative widths and heights.\n///\n/// ```\n/// # use kurbo::{Insets, Rect};\n/// let rect = Rect::new(7., 11., 0., 0.,);\n/// let insets = Insets::uniform_xy(0., 1.,);\n///\n/// assert_eq!(rect.width(), -7.0);\n///\n/// let inset_rect = rect + insets;\n/// assert_eq!(inset_rect.width(), 7.0);\n/// assert_eq!(inset_rect.x0, 0.0);\n/// assert_eq!(inset_rect.height(), 13.0);\n/// ```\n///\n/// The width and height of an inset operation can still be negative if the\n/// [`Insets`]' dimensions are greater than the dimensions of the original [`Rect`].\n///\n/// ```\n/// # use kurbo::{Insets, Rect};\n/// let rect = Rect::new(0., 0., 3., 5.);\n/// let insets = Insets::uniform_xy(0., 7.,);\n///\n/// let inset_rect = rect - insets;\n/// assert_eq!(inset_rect.height(), -9., \"5 - 7 × 2\")\n/// ```\n///\n/// `Rect - Rect = Insets`:\n///\n///\n/// ```\n/// # use kurbo::{Insets, Rect};\n/// let rect = Rect::new(0., 0., 5., 11.);\n/// let insets = Insets::uniform_xy(1., 7.,);\n///\n/// let inset_rect = rect + insets;\n/// let insets2 = inset_rect - rect;\n///\n/// assert_eq!(insets2.x0, insets.x0);\n/// assert_eq!(insets2.y1, insets.y1);\n/// assert_eq!(insets2.x_value(), insets.x_value());\n/// assert_eq!(insets2.y_value(), insets.y_value());\n/// ```\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Insets {\n    /// The minimum x coordinate (left edge).\n    pub x0: f64,\n    /// The minimum y coordinate (top edge in y-down spaces).\n    pub y0: f64,\n    /// The maximum x coordinate (right edge).\n    pub x1: f64,\n    /// The maximum y coordinate (bottom edge in y-down spaces).\n    pub y1: f64,\n}\n\nimpl Insets {\n    /// Zeroed insets.\n    pub const ZERO: Insets = Insets::uniform(0.);\n\n    /// New uniform insets.\n    #[inline]\n    pub const fn uniform(d: f64) -> Insets {\n        Insets {\n            x0: d,\n            y0: d,\n            x1: d,\n            y1: d,\n        }\n    }\n\n    /// New insets with uniform values along each axis.\n    #[inline]\n    pub const fn uniform_xy(x: f64, y: f64) -> Insets {\n        Insets {\n            x0: x,\n            y0: y,\n            x1: x,\n            y1: y,\n        }\n    }\n\n    /// New insets. The ordering of the arguments is \"left, top, right, bottom\",\n    /// assuming a y-down coordinate space.\n    #[inline]\n    pub const fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Insets {\n        Insets { x0, y0, x1, y1 }\n    }\n\n    /// The total delta on the x-axis represented by these insets.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Insets;\n    ///\n    /// let insets = Insets::uniform_xy(3., 8.);\n    /// assert_eq!(insets.x_value(), 6.);\n    ///\n    /// let insets = Insets::new(5., 0., -12., 0.,);\n    /// assert_eq!(insets.x_value(), -7.);\n    /// ```\n    #[inline]\n    pub fn x_value(self) -> f64 {\n        self.x0 + self.x1\n    }\n\n    /// The total delta on the y-axis represented by these insets.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Insets;\n    ///\n    /// let insets = Insets::uniform_xy(3., 7.);\n    /// assert_eq!(insets.y_value(), 14.);\n    ///\n    /// let insets = Insets::new(5., 10., -12., 4.,);\n    /// assert_eq!(insets.y_value(), 14.);\n    /// ```\n    #[inline]\n    pub fn y_value(self) -> f64 {\n        self.y0 + self.y1\n    }\n\n    /// Returns the total delta represented by these insets as a [`Size`].\n    ///\n    /// This is equivalent to creating a [`Size`] from the values returned by\n    /// [`x_value`] and [`y_value`].\n    ///\n    /// This function may return a size with negative values.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::{Insets, Size};\n    ///\n    /// let insets = Insets::new(11.1, -43.3, 3.333, -0.0);\n    /// assert_eq!(insets.size(), Size::new(insets.x_value(), insets.y_value()));\n    /// ```\n    ///\n    /// [`x_value`]: Insets::x_value\n    /// [`y_value`]: Insets::y_value\n    pub fn size(self) -> Size {\n        Size::new(self.x_value(), self.y_value())\n    }\n\n    /// Return `true` iff all values are nonnegative.\n    pub fn are_nonnegative(self) -> bool {\n        let Insets { x0, y0, x1, y1 } = self;\n        x0 >= 0.0 && y0 >= 0.0 && x1 >= 0.0 && y1 >= 0.0\n    }\n\n    /// Return new `Insets` with all negative values replaced with `0.0`.\n    ///\n    /// This is provided as a convenience for applications where negative insets\n    /// are not meaningful.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Insets;\n    ///\n    /// let insets = Insets::new(-10., 3., -0.2, 4.);\n    /// let nonnegative = insets.nonnegative();\n    /// assert_eq!(nonnegative.x_value(), 0.0);\n    /// assert_eq!(nonnegative.y_value(), 7.0);\n    /// ```\n    pub fn nonnegative(self) -> Insets {\n        let Insets { x0, y0, x1, y1 } = self;\n        Insets {\n            x0: x0.max(0.0),\n            y0: y0.max(0.0),\n            x1: x1.max(0.0),\n            y1: y1.max(0.0),\n        }\n    }\n\n    /// Are these insets finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.x0.is_finite() && self.y0.is_finite() && self.x1.is_finite() && self.y1.is_finite()\n    }\n\n    /// Are these insets NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.x0.is_nan() || self.y0.is_nan() || self.x1.is_nan() || self.y1.is_nan()\n    }\n}\n\nimpl Neg for Insets {\n    type Output = Insets;\n\n    #[inline]\n    fn neg(self) -> Insets {\n        Insets::new(-self.x0, -self.y0, -self.x1, -self.y1)\n    }\n}\n\nimpl Add<Rect> for Insets {\n    type Output = Rect;\n\n    #[inline]\n    #[allow(clippy::suspicious_arithmetic_impl)]\n    fn add(self, other: Rect) -> Rect {\n        let other = other.abs();\n        Rect::new(\n            other.x0 - self.x0,\n            other.y0 - self.y0,\n            other.x1 + self.x1,\n            other.y1 + self.y1,\n        )\n    }\n}\n\nimpl Add<Insets> for Rect {\n    type Output = Rect;\n\n    #[inline]\n    fn add(self, other: Insets) -> Rect {\n        other + self\n    }\n}\n\nimpl Sub<Rect> for Insets {\n    type Output = Rect;\n\n    #[inline]\n    fn sub(self, other: Rect) -> Rect {\n        other + -self\n    }\n}\n\nimpl Sub<Insets> for Rect {\n    type Output = Rect;\n\n    #[inline]\n    fn sub(self, other: Insets) -> Rect {\n        other - self\n    }\n}\n\nimpl From<f64> for Insets {\n    fn from(src: f64) -> Insets {\n        Insets::uniform(src)\n    }\n}\n\nimpl From<(f64, f64)> for Insets {\n    fn from(src: (f64, f64)) -> Insets {\n        Insets::uniform_xy(src.0, src.1)\n    }\n}\n\nimpl From<(f64, f64, f64, f64)> for Insets {\n    fn from(src: (f64, f64, f64, f64)) -> Insets {\n        Insets::new(src.0, src.1, src.2, src.3)\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/lib.rs",
      "sha256": "67cff58c27c0852496a841a9f507347b63d5d00313ea2cd60b6df7d3345b0751",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! 2D geometry, with a focus on curves.\n//!\n//! The kurbo library contains data structures and algorithms for curves and\n//! vector paths. It was designed to serve the needs of 2D graphics applications,\n//! but it is intended to be general enough to be useful for other applications.\n//! It can be used as \"vocabulary types\" for representing curves and paths, and\n//! also contains a number of computational geometry methods.\n//!\n//! # Examples\n//!\n//! Basic UI-style geometry:\n//! ```\n//! use kurbo::{Insets, Point, Rect, Size, Vec2};\n//!\n//! let pt = Point::new(10.0, 10.0);\n//! let vector = Vec2::new(5.0, -5.0);\n//! let pt2 = pt + vector;\n//! assert_eq!(pt2, Point::new(15.0, 5.0));\n//!\n//! let rect = Rect::from_points(pt, pt2);\n//! assert_eq!(rect, Rect::from_origin_size((10.0, 5.0), (5.0, 5.0)));\n//!\n//! let insets = Insets::uniform(1.0);\n//! let inset_rect = rect - insets;\n//! assert_eq!(inset_rect.size(), Size::new(3.0, 3.0));\n//! ```\n//!\n//! Finding the closest position on a [`Shape`]'s perimeter to a [`Point`]:\n//!\n//! ```\n//! use kurbo::{Circle, ParamCurve, ParamCurveNearest, Point, Shape};\n//!\n//! const DESIRED_ACCURACY: f64 = 0.1;\n//!\n//! /// Given a shape and a point, returns the closest position on the shape's\n//! /// perimeter, or `None` if the shape is malformed.\n//! fn closest_perimeter_point(shape: impl Shape, pt: Point) -> Option<Point> {\n//!     let mut best: Option<(Point, f64)> = None;\n//!     for segment in shape.path_segments(DESIRED_ACCURACY) {\n//!         let nearest = segment.nearest(pt, DESIRED_ACCURACY);\n//!         if best.map(|(_, best_d)| nearest.distance_sq < best_d).unwrap_or(true) {\n//!             best = Some((segment.eval(nearest.t), nearest.distance_sq))\n//!         }\n//!     }\n//!     best.map(|(point, _)| point)\n//! }\n//!\n//! let circle = Circle::new((5.0, 5.0), 5.0);\n//! let hit_point = Point::new(5.0, -2.0);\n//! let expectation = Point::new(5.0, 0.0);\n//! let hit = closest_perimeter_point(circle, hit_point).unwrap();\n//! assert!(hit.distance(expectation) <= DESIRED_ACCURACY);\n//! ```\n//!\n//! # Features\n//!\n//! This crate either uses the standard library or the [`libm`] crate for\n//! math functionality. The `std` feature is enabled by default, but can be\n//! disabled, as long as the `libm` feature is enabled. This is useful for\n//! `no_std` environments. However, note that the `libm` crate is not as\n//! efficient as the standard library, and that this crate still uses the\n//! `alloc` crate regardless.\n//!\n//! [`Piet`]: https://docs.rs/piet\n//! [`Druid`]: https://docs.rs/druid\n//! [`libm`]: https://docs.rs/libm\n\n#![forbid(unsafe_code)]\n#![deny(missing_docs, clippy::trivially_copy_pass_by_ref)]\n#![warn(clippy::doc_markdown, rustdoc::broken_intra_doc_links)]\n#![allow(\n    clippy::unreadable_literal,\n    clippy::many_single_char_names,\n    clippy::excessive_precision,\n    clippy::bool_to_int_with_if\n)]\n#![cfg_attr(all(not(feature = \"std\"), not(test)), no_std)]\n\n#[cfg(not(any(feature = \"std\", feature = \"libm\")))]\ncompile_error!(\"kurbo requires either the `std` or `libm` feature\");\n\nextern crate alloc;\n\nmod affine;\nmod arc;\nmod bezpath;\nmod circle;\npub mod common;\nmod cubicbez;\nmod ellipse;\nmod fit;\nmod insets;\nmod line;\nmod mindist;\npub mod offset;\nmod param_curve;\nmod point;\nmod quadbez;\nmod quadspline;\nmod rect;\nmod rounded_rect;\nmod rounded_rect_radii;\nmod shape;\npub mod simplify;\nmod size;\nmod stroke;\n#[cfg(feature = \"std\")]\nmod svg;\nmod translate_scale;\nmod vec2;\n\npub use crate::affine::*;\npub use crate::arc::*;\npub use crate::bezpath::*;\npub use crate::circle::*;\npub use crate::cubicbez::*;\npub use crate::ellipse::*;\npub use crate::fit::*;\npub use crate::insets::*;\npub use crate::line::*;\npub use crate::param_curve::*;\npub use crate::point::*;\npub use crate::quadbez::*;\npub use crate::quadspline::*;\npub use crate::rect::*;\npub use crate::rounded_rect::*;\npub use crate::rounded_rect_radii::*;\npub use crate::shape::*;\npub use crate::size::*;\npub use crate::stroke::*;\n#[cfg(feature = \"std\")]\npub use crate::svg::*;\npub use crate::translate_scale::*;\npub use crate::vec2::*;\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/line.rs",
      "sha256": "496292c066a56bfd7f49f3b28c5cd38b94b53a4f9c97b985d783dea5078ed54c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Lines.\n\nuse core::ops::{Add, Mul, Range, Sub};\n\nuse arrayvec::ArrayVec;\n\nuse crate::{\n    Affine, Nearest, ParamCurve, ParamCurveArclen, ParamCurveArea, ParamCurveCurvature,\n    ParamCurveDeriv, ParamCurveExtrema, ParamCurveNearest, PathEl, Point, Rect, Shape, Vec2,\n    DEFAULT_ACCURACY, MAX_EXTREMA,\n};\n\n/// A single line.\n#[derive(Clone, Copy, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Line {\n    /// The line's start point.\n    pub p0: Point,\n    /// The line's end point.\n    pub p1: Point,\n}\n\nimpl Line {\n    /// Create a new line.\n    #[inline]\n    pub fn new(p0: impl Into<Point>, p1: impl Into<Point>) -> Line {\n        Line {\n            p0: p0.into(),\n            p1: p1.into(),\n        }\n    }\n\n    /// The length of the line.\n    #[inline]\n    pub fn length(self) -> f64 {\n        self.arclen(DEFAULT_ACCURACY)\n    }\n\n    /// Computes the point where two lines, if extended to infinity, would cross.\n    pub fn crossing_point(self, other: Line) -> Option<Point> {\n        let ab = self.p1 - self.p0;\n        let cd = other.p1 - other.p0;\n        let pcd = ab.cross(cd);\n        if pcd == 0.0 {\n            return None;\n        }\n        let h = ab.cross(self.p0 - other.p0) / pcd;\n        Some(other.p0 + cd * h)\n    }\n\n    /// Is this line finite?\n    #[inline]\n    pub fn is_finite(self) -> bool {\n        self.p0.is_finite() && self.p1.is_finite()\n    }\n\n    /// Is this line NaN?\n    #[inline]\n    pub fn is_nan(self) -> bool {\n        self.p0.is_nan() || self.p1.is_nan()\n    }\n}\n\nimpl ParamCurve for Line {\n    #[inline]\n    fn eval(&self, t: f64) -> Point {\n        self.p0.lerp(self.p1, t)\n    }\n\n    #[inline]\n    fn subsegment(&self, range: Range<f64>) -> Line {\n        Line {\n            p0: self.eval(range.start),\n            p1: self.eval(range.end),\n        }\n    }\n\n    #[inline]\n    fn start(&self) -> Point {\n        self.p0\n    }\n\n    #[inline]\n    fn end(&self) -> Point {\n        self.p1\n    }\n}\n\nimpl ParamCurveDeriv for Line {\n    type DerivResult = ConstPoint;\n\n    #[inline]\n    fn deriv(&self) -> ConstPoint {\n        ConstPoint((self.p1 - self.p0).to_point())\n    }\n}\n\nimpl ParamCurveArclen for Line {\n    #[inline]\n    fn arclen(&self, _accuracy: f64) -> f64 {\n        (self.p1 - self.p0).hypot()\n    }\n\n    #[inline]\n    fn inv_arclen(&self, arclen: f64, _accuracy: f64) -> f64 {\n        arclen / (self.p1 - self.p0).hypot()\n    }\n}\n\nimpl ParamCurveArea for Line {\n    #[inline]\n    fn signed_area(&self) -> f64 {\n        self.p0.to_vec2().cross(self.p1.to_vec2()) * 0.5\n    }\n}\n\nimpl ParamCurveNearest for Line {\n    fn nearest(&self, p: Point, _accuracy: f64) -> Nearest {\n        let d = self.p1 - self.p0;\n        let dotp = d.dot(p - self.p0);\n        let d_squared = d.dot(d);\n        let (t, distance_sq) = if dotp <= 0.0 {\n            (0.0, (p - self.p0).hypot2())\n        } else if dotp >= d_squared {\n            (1.0, (p - self.p1).hypot2())\n        } else {\n            let t = dotp / d_squared;\n            let dist = (p - self.eval(t)).hypot2();\n            (t, dist)\n        };\n        Nearest { distance_sq, t }\n    }\n}\n\nimpl ParamCurveCurvature for Line {\n    #[inline]\n    fn curvature(&self, _t: f64) -> f64 {\n        0.0\n    }\n}\n\nimpl ParamCurveExtrema for Line {\n    #[inline]\n    fn extrema(&self) -> ArrayVec<f64, MAX_EXTREMA> {\n        ArrayVec::new()\n    }\n}\n\n/// A trivial \"curve\" that is just a constant.\n#[derive(Clone, Copy, Debug)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct ConstPoint(Point);\n\nimpl ConstPoint {\n    /// Is this point finite?\n    #[inline]\n    pub fn is_finite(self) -> bool {\n        self.0.is_finite()\n    }\n\n    /// Is this point NaN?\n    #[inline]\n    pub fn is_nan(self) -> bool {\n        self.0.is_nan()\n    }\n}\n\nimpl ParamCurve for ConstPoint {\n    #[inline]\n    fn eval(&self, _t: f64) -> Point {\n        self.0\n    }\n\n    #[inline]\n    fn subsegment(&self, _range: Range<f64>) -> ConstPoint {\n        *self\n    }\n}\n\nimpl ParamCurveDeriv for ConstPoint {\n    type DerivResult = ConstPoint;\n\n    #[inline]\n    fn deriv(&self) -> ConstPoint {\n        ConstPoint(Point::new(0.0, 0.0))\n    }\n}\n\nimpl ParamCurveArclen for ConstPoint {\n    #[inline]\n    fn arclen(&self, _accuracy: f64) -> f64 {\n        0.0\n    }\n\n    #[inline]\n    fn inv_arclen(&self, _arclen: f64, _accuracy: f64) -> f64 {\n        0.0\n    }\n}\n\nimpl Mul<Line> for Affine {\n    type Output = Line;\n\n    #[inline]\n    fn mul(self, other: Line) -> Line {\n        Line {\n            p0: self * other.p0,\n            p1: self * other.p1,\n        }\n    }\n}\n\nimpl Add<Vec2> for Line {\n    type Output = Line;\n\n    #[inline]\n    fn add(self, v: Vec2) -> Line {\n        Line::new(self.p0 + v, self.p1 + v)\n    }\n}\n\nimpl Sub<Vec2> for Line {\n    type Output = Line;\n\n    #[inline]\n    fn sub(self, v: Vec2) -> Line {\n        Line::new(self.p0 - v, self.p1 - v)\n    }\n}\n\n/// An iterator yielding the path for a single line.\n#[doc(hidden)]\npub struct LinePathIter {\n    line: Line,\n    ix: usize,\n}\n\nimpl Shape for Line {\n    type PathElementsIter<'iter> = LinePathIter;\n\n    #[inline]\n    fn path_elements(&self, _tolerance: f64) -> LinePathIter {\n        LinePathIter { line: *self, ix: 0 }\n    }\n\n    /// Returning zero here is consistent with the contract (area is\n    /// only meaningful for closed shapes), but an argument can be made\n    /// that the contract should be tightened to include the Green's\n    /// theorem contribution.\n    fn area(&self) -> f64 {\n        0.0\n    }\n\n    #[inline]\n    fn perimeter(&self, _accuracy: f64) -> f64 {\n        (self.p1 - self.p0).hypot()\n    }\n\n    /// Same consideration as `area`.\n    fn winding(&self, _pt: Point) -> i32 {\n        0\n    }\n\n    #[inline]\n    fn bounding_box(&self) -> Rect {\n        Rect::from_points(self.p0, self.p1)\n    }\n\n    #[inline]\n    fn as_line(&self) -> Option<Line> {\n        Some(*self)\n    }\n}\n\nimpl Iterator for LinePathIter {\n    type Item = PathEl;\n\n    fn next(&mut self) -> Option<PathEl> {\n        self.ix += 1;\n        match self.ix {\n            1 => Some(PathEl::MoveTo(self.line.p0)),\n            2 => Some(PathEl::LineTo(self.line.p1)),\n            _ => None,\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Line, ParamCurveArclen, Point};\n\n    #[test]\n    fn line_arclen() {\n        let l = Line::new((0.0, 0.0), (1.0, 1.0));\n        let true_len = 2.0f64.sqrt();\n        let epsilon = 1e-9;\n        assert!(l.arclen(epsilon) - true_len < epsilon);\n\n        let t = l.inv_arclen(true_len / 3.0, epsilon);\n        assert!((t - 1.0 / 3.0).abs() < epsilon);\n    }\n\n    #[test]\n    fn line_is_finite() {\n        assert!((Line {\n            p0: Point { x: 0., y: 0. },\n            p1: Point { x: 1., y: 1. }\n        })\n        .is_finite());\n\n        assert!(!(Line {\n            p0: Point { x: 0., y: 0. },\n            p1: Point {\n                x: f64::INFINITY,\n                y: 1.\n            }\n        })\n        .is_finite());\n\n        assert!(!(Line {\n            p0: Point { x: 0., y: 0. },\n            p1: Point {\n                x: 0.,\n                y: f64::INFINITY\n            }\n        })\n        .is_finite());\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/mindist.rs",
      "sha256": "ca09ddd52dd46a872e6feb9d4036d12823f673ee2dc81854aa20d051fb4c83b6",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2021 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Minimum distance between two Bézier curves\n//!\n//! This implements the algorithm in \"Computing the minimum distance between\n//! two Bézier curves\", Chen et al., *Journal of Computational and Applied\n//! Mathematics* 229(2009), 294-301\n\nuse crate::Vec2;\nuse core::cmp::Ordering;\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\npub(crate) fn min_dist_param(\n    bez1: &[Vec2],\n    bez2: &[Vec2],\n    u: (f64, f64),\n    v: (f64, f64),\n    epsilon: f64,\n    best_alpha: Option<f64>,\n) -> (f64, f64, f64) {\n    assert!(!bez1.is_empty() && !bez2.is_empty());\n    let n = bez1.len() - 1;\n    let m = bez2.len() - 1;\n    let (umin, umax) = u;\n    let (vmin, vmax) = v;\n    let umid = (umin + umax) / 2.0;\n    let vmid = (vmin + vmax) / 2.0;\n    let svalues: [(f64, f64, f64); 4] = [\n        (S(umin, vmin, bez1, bez2), umin, vmin),\n        (S(umin, vmax, bez1, bez2), umin, vmax),\n        (S(umax, vmin, bez1, bez2), umax, vmin),\n        (S(umax, vmax, bez1, bez2), umax, vmax),\n    ];\n    let alpha: f64 = svalues.iter().map(|(a, _, _)| *a).reduce(f64::min).unwrap();\n    if let Some(best) = best_alpha {\n        if alpha > best {\n            return (alpha, umid, vmid);\n        }\n    }\n\n    if (umax - umin).abs() < epsilon || (vmax - vmin).abs() < epsilon {\n        return (alpha, umid, vmid);\n    }\n\n    // Property one: D(r>k) > alpha\n    let mut is_outside = true;\n    let mut min_drk = None;\n    let mut min_ij = None;\n    for r in 0..(2 * n) {\n        for k in 0..(2 * m) {\n            let d_rk = D_rk(r, k, bez1, bez2);\n            if d_rk < alpha {\n                is_outside = false;\n            }\n            if min_drk.is_none() || Some(d_rk) < min_drk {\n                min_drk = Some(d_rk);\n                min_ij = Some((r, k));\n            }\n        }\n    }\n    if is_outside {\n        return (alpha, umid, vmid);\n    }\n\n    // Property two: boundary check\n    let mut at_boundary0on_bez1 = true;\n    let mut at_boundary1on_bez1 = true;\n    let mut at_boundary0on_bez2 = true;\n    let mut at_boundary1on_bez2 = true;\n    for i in 0..2 * n {\n        for j in 0..2 * m {\n            let dij = D_rk(i, j, bez1, bez2);\n            let dkj = D_rk(0, j, bez1, bez2);\n            if dij < dkj {\n                at_boundary0on_bez1 = false\n            }\n            let dkj = D_rk(2 * n, j, bez1, bez2);\n            if dij < dkj {\n                at_boundary1on_bez1 = false\n            }\n            let dkj = D_rk(i, 0, bez1, bez2);\n            if dij < dkj {\n                at_boundary0on_bez2 = false\n            }\n            let dkj = D_rk(i, 2 * n, bez1, bez2);\n            if dij < dkj {\n                at_boundary1on_bez2 = false\n            }\n        }\n    }\n    if at_boundary0on_bez1 && at_boundary0on_bez2 {\n        return svalues[0];\n    }\n    if at_boundary0on_bez1 && at_boundary1on_bez2 {\n        return svalues[1];\n    }\n    if at_boundary1on_bez1 && at_boundary0on_bez2 {\n        return svalues[2];\n    }\n    if at_boundary1on_bez1 && at_boundary1on_bez2 {\n        return svalues[3];\n    }\n\n    let (min_i, min_j) = min_ij.unwrap();\n    let new_umid = umin + (umax - umin) * (min_i as f64 / (2 * n) as f64);\n    let new_vmid = vmin + (vmax - vmin) * (min_j as f64 / (2 * m) as f64);\n\n    // Subdivide\n    let results = [\n        min_dist_param(\n            bez1,\n            bez2,\n            (umin, new_umid),\n            (vmin, new_vmid),\n            epsilon,\n            Some(alpha),\n        ),\n        min_dist_param(\n            bez1,\n            bez2,\n            (umin, new_umid),\n            (new_vmid, vmax),\n            epsilon,\n            Some(alpha),\n        ),\n        min_dist_param(\n            bez1,\n            bez2,\n            (new_umid, umax),\n            (vmin, new_vmid),\n            epsilon,\n            Some(alpha),\n        ),\n        min_dist_param(\n            bez1,\n            bez2,\n            (new_umid, umax),\n            (new_vmid, vmax),\n            epsilon,\n            Some(alpha),\n        ),\n    ];\n\n    *results\n        .iter()\n        .min_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Less))\n        .unwrap()\n}\n\n// $ S(u,v)=\\sum_{r=0}^{2n} \\sum _{k=0}^{2m} D_{r,k} B_{2n}^r(u) B_{2m}^k(v) $\n\n#[allow(non_snake_case)]\nfn S(u: f64, v: f64, bez1: &[Vec2], bez2: &[Vec2]) -> f64 {\n    let n = bez1.len() - 1;\n    let m = bez2.len() - 1;\n    let mut summand = 0.0;\n    for r in 0..=2 * n {\n        for k in 0..=2 * m {\n            summand +=\n                D_rk(r, k, bez1, bez2) * basis_function(2 * n, r, u) * basis_function(2 * m, k, v)\n        }\n    }\n    summand\n}\n\n// $ C_{r,k} = ( \\sum_{i=\\theta}^\\upsilon P_i C_n^i C_n^{r-i} / C_{2n}^r ) \\cdot (\\sum_{j=\\sigma}^\\varsigma Q_j C_m^j C_m^{k-j} / C_{2m}^k ) $\n#[allow(non_snake_case)]\nfn C_rk(r: usize, k: usize, bez1: &[Vec2], bez2: &[Vec2]) -> f64 {\n    let n = bez1.len() - 1;\n    let upsilon = r.min(n);\n    let theta = r - n.min(r);\n    let mut left: Vec2 = Vec2::ZERO;\n    for (i, &item) in bez1.iter().enumerate().take(upsilon + 1).skip(theta) {\n        left += item * (choose(n, i) * choose(n, r - i)) as f64 / (choose(2 * n, r) as f64);\n    }\n\n    let m = bez2.len() - 1;\n    let varsigma = k.min(m);\n    let sigma = k - m.min(k);\n    let mut right: Vec2 = Vec2::ZERO;\n    for (j, &item) in bez2.iter().enumerate().take(varsigma + 1).skip(sigma) {\n        right += item * (choose(m, j) * choose(m, k - j)) as f64 / (choose(2 * m, k) as f64);\n    }\n    left.dot(right)\n}\n\n// $ A_r=\\sum _{i=\\theta} ^\\upsilon (P_i \\cdot P_{r-i}) C_n^i C_n^{r-i} / C_{2n}^r $\n// ($ B_k $ is just the same as $ A_r $ but for the other curve.)\n\n#[allow(non_snake_case)]\nfn A_r(r: usize, p: &[Vec2]) -> f64 {\n    let n = p.len() - 1;\n    let upsilon = r.min(n);\n    let theta = r - n.min(r);\n    (theta..=upsilon)\n        .map(|i| {\n            let dot = p[i].dot(p[r - i]); // These are bounds checked by the sum limits\n            let factor = (choose(n, i) * choose(n, r - i)) as f64 / (choose(2 * n, r) as f64);\n            dot * factor\n        })\n        .sum()\n}\n\n#[allow(non_snake_case)]\nfn D_rk(r: usize, k: usize, bez1: &[Vec2], bez2: &[Vec2]) -> f64 {\n    // In the paper, B_k is used for the second factor, but it's the same thing\n    A_r(r, bez1) + A_r(k, bez2) - 2.0 * C_rk(r, k, bez1, bez2)\n}\n\n// Bezier basis function\nfn basis_function(n: usize, i: usize, u: f64) -> f64 {\n    choose(n, i) as f64 * (1.0 - u).powi((n - i) as i32) * u.powi(i as i32)\n}\n\n// Binomial co-efficient, but returning zeros for values outside of domain\nfn choose(n: usize, k: usize) -> u32 {\n    let mut n = n;\n    if k > n {\n        return 0;\n    }\n    let mut p = 1;\n    for i in 1..=(n - k) {\n        p *= n;\n        p /= i;\n        n -= 1;\n    }\n    p as u32\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::mindist::A_r;\n    use crate::mindist::{choose, D_rk};\n    use crate::{CubicBez, Line, PathSeg, Vec2};\n\n    #[test]\n    fn test_choose() {\n        assert_eq!(choose(6, 0), 1);\n        assert_eq!(choose(6, 1), 6);\n        assert_eq!(choose(6, 2), 15);\n    }\n\n    #[test]\n    fn test_d_rk() {\n        let bez1 = vec![\n            Vec2::new(129.0, 139.0),\n            Vec2::new(190.0, 139.0),\n            Vec2::new(201.0, 364.0),\n            Vec2::new(90.0, 364.0),\n        ];\n        let bez2 = vec![\n            Vec2::new(309.0, 159.0),\n            Vec2::new(178.0, 159.0),\n            Vec2::new(215.0, 408.0),\n            Vec2::new(309.0, 408.0),\n        ];\n        let b = A_r(1, &bez2);\n        assert!((b - 80283.0).abs() < 0.005, \"B_1(Q)={b:?}\");\n        let d = D_rk(0, 1, &bez1, &bez2);\n        assert!((d - 9220.0).abs() < 0.005, \"D={d:?}\");\n    }\n\n    #[test]\n    fn test_mindist() {\n        let bez1 = PathSeg::Cubic(CubicBez::new(\n            (129.0, 139.0),\n            (190.0, 139.0),\n            (201.0, 364.0),\n            (90.0, 364.0),\n        ));\n        let bez2 = PathSeg::Cubic(CubicBez::new(\n            (309.0, 159.0),\n            (178.0, 159.0),\n            (215.0, 408.0),\n            (309.0, 408.0),\n        ));\n        let mindist = bez1.min_dist(bez2, 0.001);\n        assert!((mindist.distance - 50.9966).abs() < 0.5);\n    }\n\n    #[test]\n    fn test_overflow() {\n        let bez1 = PathSeg::Cubic(CubicBez::new(\n            (232.0, 126.0),\n            (134.0, 126.0),\n            (139.0, 232.0),\n            (141.0, 301.0),\n        ));\n        let bez2 = PathSeg::Line(Line::new((359.0, 416.0), (367.0, 755.0)));\n        let mindist = bez1.min_dist(bez2, 0.001);\n        assert!((mindist.distance - 246.4731222669117).abs() < 0.5);\n    }\n\n    #[test]\n    fn test_out_of_order() {\n        let bez1 = PathSeg::Cubic(CubicBez::new(\n            (287.0, 182.0),\n            (346.0, 277.0),\n            (356.0, 299.0),\n            (359.0, 416.0),\n        ));\n        let bez2 = PathSeg::Line(Line::new((141.0, 301.0), (152.0, 709.0)));\n        let mindist1 = bez1.min_dist(bez2, 0.5);\n        let mindist2 = bez2.min_dist(bez1, 0.5);\n        assert!((mindist1.distance - mindist2.distance).abs() < 0.5);\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/offset.rs",
      "sha256": "7cfc29fc66af0a9d1e255b576a2d3f247640ce48e5cf2c253730648f8c4951c1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 The Kurbo Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// https://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//! Computation of offset curves of cubic Béziers, based on a curve fitting\n//! approach.\n//!\n//! See the [Parallel curves of cubic Béziers] blog post for a discussion of how\n//! this algorithm works and what kind of results can be expected. In general, it\n//! is expected to perform much better than most published algorithms. The number\n//! of curve segments needed to attain a given accuracy scales as O(n^6) with\n//! accuracy.\n//!\n//! In general, to compute the offset curve (also known as parallel curve) of\n//! a cubic Bézier segment, create a [`CubicOffset`] struct with the curve\n//! segment and offset, then use [`fit_to_bezpath`] or [`fit_to_bezpath_opt`]\n//! depending on how much time to spend optimizing the resulting path.\n//!\n//! [`fit_to_bezpath`]: crate::fit_to_bezpath\n//! [`fit_to_bezpath_opt`]: crate::fit_to_bezpath_opt\n//! [Parallel curves of cubic Béziers]: https://raphlinus.github.io/curves/2022/09/09/parallel-beziers.html\nuse core::ops::Range;\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\nuse crate::{\n    common::solve_itp, CubicBez, CurveFitSample, ParamCurve, ParamCurveDeriv, ParamCurveFit, Point,\n    QuadBez, Vec2,\n};\n\n/// The offset curve of a cubic Bézier.\n///\n/// This is a representation of the offset curve of a cubic Bézier segment, for\n/// purposes of curve fitting.\n///\n/// See the [module-level documentation] for a bit more discussion of the approach,\n/// and how this struct is to be used.\n///\n/// [module-level documentation]: crate::offset\npub struct CubicOffset {\n    /// Source curve.\n    c: CubicBez,\n    /// Derivative of source curve.\n    q: QuadBez,\n    /// Offset.\n    d: f64,\n    // c0 + c1 t + c2 t^2 is the cross product of second and first\n    // derivatives of the underlying cubic, multiplied by offset (for\n    // computing cusp).\n    c0: f64,\n    c1: f64,\n    c2: f64,\n}\n\nimpl CubicOffset {\n    /// Create a new curve from Bézier segment and offset.\n    ///\n    /// This method should only be used if the Bézier is smooth. Use\n    /// [`new_regularized`] instead to deal with a wider range of inputs.\n    ///\n    /// [`new_regularized`]: Self::new_regularized\n    pub fn new(c: CubicBez, d: f64) -> Self {\n        let q = c.deriv();\n        let d0 = q.p0.to_vec2();\n        let d1 = 2.0 * (q.p1 - q.p0);\n        let d2 = q.p0.to_vec2() - 2.0 * q.p1.to_vec2() + q.p2.to_vec2();\n        CubicOffset {\n            c,\n            q,\n            d,\n            c0: d * d1.cross(d0),\n            c1: d * 2.0 * d2.cross(d0),\n            c2: d * d2.cross(d1),\n        }\n    }\n\n    /// Create a new curve from Bézier segment and offset, with numerical robustness tweaks.\n    ///\n    /// The dimension represents a minimum feature size; the regularization is allowed to\n    /// perturb the curve by this amount in order to improve the robustness.\n    pub fn new_regularized(c: CubicBez, d: f64, dimension: f64) -> Self {\n        Self::new(c.regularize(dimension), d)\n    }\n\n    fn eval_offset(&self, t: f64) -> Vec2 {\n        let dp = self.q.eval(t).to_vec2();\n        let norm = Vec2::new(-dp.y, dp.x);\n        // TODO: deal with hypot = 0\n        norm * self.d / dp.hypot()\n    }\n\n    fn eval(&self, t: f64) -> Point {\n        // Point on source curve.\n        self.c.eval(t) + self.eval_offset(t)\n    }\n\n    /// Evaluate derivative of curve.\n    fn eval_deriv(&self, t: f64) -> Vec2 {\n        self.cusp_sign(t) * self.q.eval(t).to_vec2()\n    }\n\n    // Compute a function which has a zero-crossing at cusps, and is\n    // positive at low curvatures on the source curve.\n    fn cusp_sign(&self, t: f64) -> f64 {\n        let ds2 = self.q.eval(t).to_vec2().hypot2();\n        ((self.c2 * t + self.c1) * t + self.c0) / (ds2 * ds2.sqrt()) + 1.0\n    }\n}\n\nimpl ParamCurveFit for CubicOffset {\n    fn sample_pt_tangent(&self, t: f64, sign: f64) -> CurveFitSample {\n        let p = self.eval(t);\n        const CUSP_EPS: f64 = 1e-8;\n        let mut cusp = self.cusp_sign(t);\n        if cusp.abs() < CUSP_EPS {\n            // This is a numerical derivative, which is probably good enough\n            // for all practical purposes, but an analytical derivative would\n            // be more elegant.\n            //\n            // Also, we're not dealing with second or higher order cusps.\n            cusp = sign * (self.cusp_sign(t + CUSP_EPS) - self.cusp_sign(t - CUSP_EPS));\n        }\n        let tangent = self.q.eval(t).to_vec2() * cusp.signum();\n        CurveFitSample { p, tangent }\n    }\n\n    fn sample_pt_deriv(&self, t: f64) -> (Point, Vec2) {\n        (self.eval(t), self.eval_deriv(t))\n    }\n\n    fn break_cusp(&self, range: Range<f64>) -> Option<f64> {\n        const CUSP_EPS: f64 = 1e-8;\n        // When an endpoint is on (or very near) a cusp, move just far enough\n        // away from the cusp that we're confident we have the right sign.\n        let break_cusp_help = |mut x, mut d| {\n            let mut cusp = self.cusp_sign(x);\n            while cusp.abs() < CUSP_EPS && d < 1.0 {\n                x += d;\n                let old_cusp = cusp;\n                cusp = self.cusp_sign(x);\n                if cusp.abs() > old_cusp.abs() {\n                    break;\n                }\n                d *= 2.0;\n            }\n            (x, cusp)\n        };\n        let (a, cusp0) = break_cusp_help(range.start, 1e-12);\n        let (b, cusp1) = break_cusp_help(range.end, -1e-12);\n        if a >= b || cusp0 * cusp1 >= 0.0 {\n            // Discussion point: maybe we should search for double cusps in the interior\n            // of the range.\n            return None;\n        }\n        let s = cusp1.signum();\n        let f = |t| s * self.cusp_sign(t);\n        let k1 = 0.2 / (b - a);\n        const ITP_EPS: f64 = 1e-12;\n        let x = solve_itp(f, a, b, ITP_EPS, 1, k1, s * cusp0, s * cusp1);\n        Some(x)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::CubicOffset;\n    use crate::{fit_to_bezpath, fit_to_bezpath_opt, CubicBez, PathEl};\n\n    // This test tries combinations of parameters that have caused problems in the past.\n    #[test]\n    fn pathological_curves() {\n        let curve = CubicBez {\n            p0: (-1236.3746269978635, 152.17981429574826).into(),\n            p1: (-1175.18662093517, 108.04721798590596).into(),\n            p2: (-1152.142883879584, 105.76260301083356).into(),\n            p3: (-1151.842639804639, 105.73040758939104).into(),\n        };\n        let offset = 3603.7267536453924;\n        let accuracy = 0.1;\n        let offset_path = CubicOffset::new(curve, offset);\n        let path = fit_to_bezpath_opt(&offset_path, accuracy);\n        assert!(matches!(path.iter().next(), Some(PathEl::MoveTo(_))));\n        let path_opt = fit_to_bezpath(&offset_path, accuracy);\n        assert!(matches!(path_opt.iter().next(), Some(PathEl::MoveTo(_))));\n    }\n\n    /// Cubic offset that used to trigger infinite recursion.\n    #[test]\n    fn infinite_recursion() {\n        const DIM_TUNE: f64 = 0.25;\n        const TOLERANCE: f64 = 0.1;\n        let c = CubicBez::new(\n            (1096.2962962962963, 593.90243902439033),\n            (1043.6213991769548, 593.90243902439033),\n            (1030.4526748971193, 593.90243902439033),\n            (1056.7901234567901, 593.90243902439033),\n        );\n        let co = CubicOffset::new_regularized(c, -0.5, DIM_TUNE * TOLERANCE);\n        fit_to_bezpath(&co, TOLERANCE);\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/param_curve.rs",
      "sha256": "5c48fec80c8c67f8e2aa7f23b2d0aece5f90ca2e56579370556eb244a247353f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A trait for curves parametrized by a scalar.\n\nuse core::ops::Range;\n\nuse arrayvec::ArrayVec;\n\nuse crate::{common, Point, Rect};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A default value for methods that take an 'accuracy' argument.\n///\n/// This value is intended to be suitable for general-purpose use, such as\n/// 2d graphics.\npub const DEFAULT_ACCURACY: f64 = 1e-6;\n\n/// A curve parametrized by a scalar.\n///\n/// If the result is interpreted as a point, this represents a curve.\n/// But the result can be interpreted as a vector as well.\npub trait ParamCurve: Sized {\n    /// Evaluate the curve at parameter `t`.\n    ///\n    /// Generally `t` is in the range [0..1].\n    fn eval(&self, t: f64) -> Point;\n\n    /// Get a subsegment of the curve for the given parameter range.\n    fn subsegment(&self, range: Range<f64>) -> Self;\n\n    /// Subdivide into (roughly) halves.\n    #[inline]\n    fn subdivide(&self) -> (Self, Self) {\n        (self.subsegment(0.0..0.5), self.subsegment(0.5..1.0))\n    }\n\n    /// The start point.\n    fn start(&self) -> Point {\n        self.eval(0.0)\n    }\n\n    /// The end point.\n    fn end(&self) -> Point {\n        self.eval(1.0)\n    }\n}\n\n// TODO: I might not want to have separate traits for all these.\n\n/// A differentiable parametrized curve.\npub trait ParamCurveDeriv {\n    /// The parametric curve obtained by taking the derivative of this one.\n    type DerivResult: ParamCurve;\n\n    /// The derivative of the curve.\n    ///\n    /// Note that the type of the return value is somewhat inaccurate, as\n    /// the derivative of a curve (mapping of param to point) is a mapping\n    /// of param to vector. We choose to accept this rather than have a\n    /// more complex type scheme.\n    fn deriv(&self) -> Self::DerivResult;\n\n    /// Estimate arclength using Gaussian quadrature.\n    ///\n    /// The coefficients are assumed to cover the range (-1..1), which is\n    /// traditional.\n    #[inline]\n    fn gauss_arclen(&self, coeffs: &[(f64, f64)]) -> f64 {\n        let d = self.deriv();\n        coeffs\n            .iter()\n            .map(|(wi, xi)| wi * d.eval(0.5 * (xi + 1.0)).to_vec2().hypot())\n            .sum::<f64>()\n            * 0.5\n    }\n}\n\n/// A parametrized curve that can have its arc length measured.\npub trait ParamCurveArclen: ParamCurve {\n    /// The arc length of the curve.\n    ///\n    /// The result is accurate to the given accuracy (subject to\n    /// roundoff errors for ridiculously low values). Compute time\n    /// may vary with accuracy, if the curve needs to be subdivided.\n    fn arclen(&self, accuracy: f64) -> f64;\n\n    /// Solve for the parameter that has the given arc length from the start.\n    ///\n    /// This implementation uses the IPT method, as provided by\n    /// [`common::solve_itp`]. This is as robust as bisection but\n    /// typically converges faster. In addition, the method takes\n    /// care to compute arc lengths of increasingly smaller segments\n    /// of the curve, as that is likely faster than repeatedly\n    /// computing the arc length of the segment starting at t=0.\n    fn inv_arclen(&self, arclen: f64, accuracy: f64) -> f64 {\n        if arclen <= 0.0 {\n            return 0.0;\n        }\n        let total_arclen = self.arclen(accuracy);\n        if arclen >= total_arclen {\n            return 1.0;\n        }\n        let mut t_last = 0.0;\n        let mut arclen_last = 0.0;\n        let epsilon = accuracy / total_arclen;\n        let n = 1.0 - epsilon.log2().ceil().min(0.0);\n        let inner_accuracy = accuracy / n;\n        let f = |t: f64| {\n            let (range, dir) = if t > t_last {\n                (t_last..t, 1.0)\n            } else {\n                (t..t_last, -1.0)\n            };\n            let arc = self.subsegment(range).arclen(inner_accuracy);\n            arclen_last += arc * dir;\n            t_last = t;\n            arclen_last - arclen\n        };\n        common::solve_itp(f, 0.0, 1.0, epsilon, 1, 0.2, -arclen, total_arclen - arclen)\n    }\n}\n\n/// A parametrized curve that can have its signed area measured.\npub trait ParamCurveArea {\n    /// Compute the signed area under the curve.\n    ///\n    /// For a closed path, the signed area of the path is the sum of signed\n    /// areas of the segments. This is a variant of the \"shoelace formula.\"\n    /// See:\n    /// <https://github.com/Pomax/bezierinfo/issues/44> and\n    /// <http://ich.deanmcnamee.com/graphics/2016/03/30/CurveArea.html>\n    ///\n    /// This can be computed exactly for Béziers thanks to Green's theorem,\n    /// and also for simple curves such as circular arcs. For more exotic\n    /// curves, it's probably best to subdivide to cubics. We leave that\n    /// to the caller, which is why we don't give an accuracy param here.\n    fn signed_area(&self) -> f64;\n}\n\n/// The nearest position on a curve to some point.\n///\n/// This is returned by [`ParamCurveNearest::nearest`]\n#[derive(Debug, Clone, Copy)]\npub struct Nearest {\n    /// The square of the distance from the nearest position on the curve\n    /// to the given point.\n    pub distance_sq: f64,\n    /// The position on the curve of the nearest point, as a parameter.\n    ///\n    /// To resolve this to a [`Point`], use [`ParamCurve::eval`].\n    pub t: f64,\n}\n\n/// A parametrized curve that reports the nearest point.\npub trait ParamCurveNearest {\n    /// Find the position on the curve that is nearest to the given point.\n    ///\n    /// This returns a [`Nearest`] struct that contains information about\n    /// the position.\n    fn nearest(&self, p: Point, accuracy: f64) -> Nearest;\n}\n\n/// A parametrized curve that reports its curvature.\npub trait ParamCurveCurvature: ParamCurveDeriv\nwhere\n    Self::DerivResult: ParamCurveDeriv,\n{\n    /// Compute the signed curvature at parameter `t`.\n    #[inline]\n    fn curvature(&self, t: f64) -> f64 {\n        let deriv = self.deriv();\n        let deriv2 = deriv.deriv();\n        let d = deriv.eval(t).to_vec2();\n        let d2 = deriv2.eval(t).to_vec2();\n        // TODO: What's the convention for sign? I think it should match signed\n        // area - a positive area curve should have positive curvature.\n        d2.cross(d) * d.hypot2().powf(-1.5)\n    }\n}\n\n/// The maximum number of extrema that can be reported in the `ParamCurveExtrema` trait.\n///\n/// This is 4 to support cubic Béziers. If other curves are used, they should be\n/// subdivided to limit the number of extrema.\npub const MAX_EXTREMA: usize = 4;\n\n/// A parametrized curve that reports its extrema.\npub trait ParamCurveExtrema: ParamCurve {\n    /// Compute the extrema of the curve.\n    ///\n    /// Only extrema within the interior of the curve count.\n    /// At most four extrema can be reported, which is sufficient for\n    /// cubic Béziers.\n    ///\n    /// The extrema should be reported in increasing parameter order.\n    fn extrema(&self) -> ArrayVec<f64, MAX_EXTREMA>;\n\n    /// Return parameter ranges, each of which is monotonic within the range.\n    fn extrema_ranges(&self) -> ArrayVec<Range<f64>, { MAX_EXTREMA + 1 }> {\n        let mut result = ArrayVec::new();\n        let mut t0 = 0.0;\n        for t in self.extrema() {\n            result.push(t0..t);\n            t0 = t;\n        }\n        result.push(t0..1.0);\n        result\n    }\n\n    /// The smallest rectangle that encloses the curve in the range (0..1).\n    fn bounding_box(&self) -> Rect {\n        let mut bbox = Rect::from_points(self.start(), self.end());\n        for t in self.extrema() {\n            bbox = bbox.union_pt(self.eval(t))\n        }\n        bbox\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/point.rs",
      "sha256": "e686b62dcac07277d6e189bfa570b8b5fffa119a34d970e3e5eae9de466090b0",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A 2D point.\n\nuse core::fmt;\nuse core::ops::{Add, AddAssign, Sub, SubAssign};\n\nuse crate::common::FloatExt;\nuse crate::Vec2;\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A 2D point.\n///\n/// This type represents a point in 2D space. It has the same layout as [`Vec2`][crate::Vec2], but\n/// its meaning is different: `Vec2` represents a change in location (for example velocity).\n///\n/// In general, `kurbo` overloads math operators where it makes sense, for example implementing\n/// `Affine * Point` as the point under the affine transformation. However `Point + Point` and\n/// `f64 * Point` are not implemented, because the operations do not make geometric sense. If you\n/// need to apply these operations, then 1) check what you're doing makes geometric sense, then 2)\n/// use [`Point::to_vec2`] to convert the point to a `Vec2`.\n#[derive(Clone, Copy, Default, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Point {\n    /// The x coordinate.\n    pub x: f64,\n    /// The y coordinate.\n    pub y: f64,\n}\n\nimpl Point {\n    /// The point (0, 0).\n    pub const ZERO: Point = Point::new(0., 0.);\n\n    /// The point at the origin; (0, 0).\n    pub const ORIGIN: Point = Point::new(0., 0.);\n\n    /// Create a new `Point` with the provided `x` and `y` coordinates.\n    #[inline]\n    pub const fn new(x: f64, y: f64) -> Self {\n        Point { x, y }\n    }\n\n    /// Convert this point into a `Vec2`.\n    #[inline]\n    pub const fn to_vec2(self) -> Vec2 {\n        Vec2::new(self.x, self.y)\n    }\n\n    /// Linearly interpolate between two points.\n    #[inline]\n    pub fn lerp(self, other: Point, t: f64) -> Point {\n        self.to_vec2().lerp(other.to_vec2(), t).to_point()\n    }\n\n    /// Determine the midpoint of two points.\n    #[inline]\n    pub fn midpoint(self, other: Point) -> Point {\n        Point::new(0.5 * (self.x + other.x), 0.5 * (self.y + other.y))\n    }\n\n    /// Euclidean distance.\n    #[inline]\n    pub fn distance(self, other: Point) -> f64 {\n        (self - other).hypot()\n    }\n\n    /// Squared Euclidean distance.\n    #[inline]\n    pub fn distance_squared(self, other: Point) -> f64 {\n        (self - other).hypot2()\n    }\n\n    /// Returns a new `Point`,\n    /// with `x` and `y` rounded to the nearest integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Point;\n    /// let a = Point::new(3.3, 3.6).round();\n    /// let b = Point::new(3.0, -3.1).round();\n    /// assert_eq!(a.x, 3.0);\n    /// assert_eq!(a.y, 4.0);\n    /// assert_eq!(b.x, 3.0);\n    /// assert_eq!(b.y, -3.0);\n    /// ```\n    #[inline]\n    pub fn round(self) -> Point {\n        Point::new(self.x.round(), self.y.round())\n    }\n\n    /// Returns a new `Point`,\n    /// with `x` and `y` rounded up to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Point;\n    /// let a = Point::new(3.3, 3.6).ceil();\n    /// let b = Point::new(3.0, -3.1).ceil();\n    /// assert_eq!(a.x, 4.0);\n    /// assert_eq!(a.y, 4.0);\n    /// assert_eq!(b.x, 3.0);\n    /// assert_eq!(b.y, -3.0);\n    /// ```\n    #[inline]\n    pub fn ceil(self) -> Point {\n        Point::new(self.x.ceil(), self.y.ceil())\n    }\n\n    /// Returns a new `Point`,\n    /// with `x` and `y` rounded down to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Point;\n    /// let a = Point::new(3.3, 3.6).floor();\n    /// let b = Point::new(3.0, -3.1).floor();\n    /// assert_eq!(a.x, 3.0);\n    /// assert_eq!(a.y, 3.0);\n    /// assert_eq!(b.x, 3.0);\n    /// assert_eq!(b.y, -4.0);\n    /// ```\n    #[inline]\n    pub fn floor(self) -> Point {\n        Point::new(self.x.floor(), self.y.floor())\n    }\n\n    /// Returns a new `Point`,\n    /// with `x` and `y` rounded away from zero to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Point;\n    /// let a = Point::new(3.3, 3.6).expand();\n    /// let b = Point::new(3.0, -3.1).expand();\n    /// assert_eq!(a.x, 4.0);\n    /// assert_eq!(a.y, 4.0);\n    /// assert_eq!(b.x, 3.0);\n    /// assert_eq!(b.y, -4.0);\n    /// ```\n    #[inline]\n    pub fn expand(self) -> Point {\n        Point::new(self.x.expand(), self.y.expand())\n    }\n\n    /// Returns a new `Point`,\n    /// with `x` and `y` rounded towards zero to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Point;\n    /// let a = Point::new(3.3, 3.6).trunc();\n    /// let b = Point::new(3.0, -3.1).trunc();\n    /// assert_eq!(a.x, 3.0);\n    /// assert_eq!(a.y, 3.0);\n    /// assert_eq!(b.x, 3.0);\n    /// assert_eq!(b.y, -3.0);\n    /// ```\n    #[inline]\n    pub fn trunc(self) -> Point {\n        Point::new(self.x.trunc(), self.y.trunc())\n    }\n\n    /// Is this point finite?\n    #[inline]\n    pub fn is_finite(self) -> bool {\n        self.x.is_finite() && self.y.is_finite()\n    }\n\n    /// Is this point NaN?\n    #[inline]\n    pub fn is_nan(self) -> bool {\n        self.x.is_nan() || self.y.is_nan()\n    }\n}\n\nimpl From<(f64, f64)> for Point {\n    #[inline]\n    fn from(v: (f64, f64)) -> Point {\n        Point { x: v.0, y: v.1 }\n    }\n}\n\nimpl From<Point> for (f64, f64) {\n    #[inline]\n    fn from(v: Point) -> (f64, f64) {\n        (v.x, v.y)\n    }\n}\n\nimpl Add<Vec2> for Point {\n    type Output = Point;\n\n    #[inline]\n    fn add(self, other: Vec2) -> Self {\n        Point::new(self.x + other.x, self.y + other.y)\n    }\n}\n\nimpl AddAssign<Vec2> for Point {\n    #[inline]\n    fn add_assign(&mut self, other: Vec2) {\n        *self = Point::new(self.x + other.x, self.y + other.y)\n    }\n}\n\nimpl Sub<Vec2> for Point {\n    type Output = Point;\n\n    #[inline]\n    fn sub(self, other: Vec2) -> Self {\n        Point::new(self.x - other.x, self.y - other.y)\n    }\n}\n\nimpl SubAssign<Vec2> for Point {\n    #[inline]\n    fn sub_assign(&mut self, other: Vec2) {\n        *self = Point::new(self.x - other.x, self.y - other.y)\n    }\n}\n\nimpl Add<(f64, f64)> for Point {\n    type Output = Point;\n\n    #[inline]\n    fn add(self, (x, y): (f64, f64)) -> Self {\n        Point::new(self.x + x, self.y + y)\n    }\n}\n\nimpl AddAssign<(f64, f64)> for Point {\n    #[inline]\n    fn add_assign(&mut self, (x, y): (f64, f64)) {\n        *self = Point::new(self.x + x, self.y + y)\n    }\n}\n\nimpl Sub<(f64, f64)> for Point {\n    type Output = Point;\n\n    #[inline]\n    fn sub(self, (x, y): (f64, f64)) -> Self {\n        Point::new(self.x - x, self.y - y)\n    }\n}\n\nimpl SubAssign<(f64, f64)> for Point {\n    #[inline]\n    fn sub_assign(&mut self, (x, y): (f64, f64)) {\n        *self = Point::new(self.x - x, self.y - y)\n    }\n}\n\nimpl Sub<Point> for Point {\n    type Output = Vec2;\n\n    #[inline]\n    fn sub(self, other: Point) -> Vec2 {\n        Vec2::new(self.x - other.x, self.y - other.y)\n    }\n}\n\nimpl fmt::Debug for Point {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"({:?}, {:?})\", self.x, self.y)\n    }\n}\n\nimpl fmt::Display for Point {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        write!(formatter, \"(\")?;\n        fmt::Display::fmt(&self.x, formatter)?;\n        write!(formatter, \", \")?;\n        fmt::Display::fmt(&self.y, formatter)?;\n        write!(formatter, \")\")\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    #[test]\n    fn point_arithmetic() {\n        assert_eq!(\n            Point::new(0., 0.) - Vec2::new(10., 0.),\n            Point::new(-10., 0.)\n        );\n        assert_eq!(\n            Point::new(0., 0.) - Point::new(-5., 101.),\n            Vec2::new(5., -101.)\n        );\n    }\n\n    #[test]\n    #[allow(clippy::float_cmp)]\n    fn distance() {\n        let p1 = Point::new(0., 10.);\n        let p2 = Point::new(0., 5.);\n        assert_eq!(p1.distance(p2), 5.);\n\n        let p1 = Point::new(-11., 1.);\n        let p2 = Point::new(-7., -2.);\n        assert_eq!(p1.distance(p2), 5.);\n    }\n\n    #[test]\n    fn display() {\n        let p = Point::new(0.12345, 9.87654);\n        assert_eq!(format!(\"{p}\"), \"(0.12345, 9.87654)\");\n\n        let p = Point::new(0.12345, 9.87654);\n        assert_eq!(format!(\"{p:.2}\"), \"(0.12, 9.88)\");\n    }\n}\n\n#[cfg(feature = \"mint\")]\nimpl From<Point> for mint::Point2<f64> {\n    #[inline]\n    fn from(p: Point) -> mint::Point2<f64> {\n        mint::Point2 { x: p.x, y: p.y }\n    }\n}\n\n#[cfg(feature = \"mint\")]\nimpl From<mint::Point2<f64>> for Point {\n    #[inline]\n    fn from(p: mint::Point2<f64>) -> Point {\n        Point { x: p.x, y: p.y }\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/quadbez.rs",
      "sha256": "0faf471969966e1659da6af2ac28359f690b8e41f52aced64b53b19865329945",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Quadratic Bézier segments.\n\nuse core::ops::{Mul, Range};\n\nuse arrayvec::ArrayVec;\n\nuse crate::common::solve_cubic;\nuse crate::MAX_EXTREMA;\nuse crate::{\n    Affine, CubicBez, Line, Nearest, ParamCurve, ParamCurveArclen, ParamCurveArea,\n    ParamCurveCurvature, ParamCurveDeriv, ParamCurveExtrema, ParamCurveNearest, PathEl, Point,\n    Rect, Shape,\n};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A single quadratic Bézier segment.\n#[derive(Clone, Copy, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\n#[allow(missing_docs)]\npub struct QuadBez {\n    pub p0: Point,\n    pub p1: Point,\n    pub p2: Point,\n}\n\nimpl QuadBez {\n    /// Create a new quadratic Bézier segment.\n    #[inline]\n    pub fn new<V: Into<Point>>(p0: V, p1: V, p2: V) -> QuadBez {\n        QuadBez {\n            p0: p0.into(),\n            p1: p1.into(),\n            p2: p2.into(),\n        }\n    }\n\n    /// Raise the order by 1.\n    ///\n    /// Returns a cubic Bézier segment that exactly represents this quadratic.\n    #[inline]\n    pub fn raise(&self) -> CubicBez {\n        CubicBez::new(\n            self.p0,\n            self.p0 + (2.0 / 3.0) * (self.p1 - self.p0),\n            self.p2 + (2.0 / 3.0) * (self.p1 - self.p2),\n            self.p2,\n        )\n    }\n\n    /// Estimate the number of subdivisions for flattening.\n    pub(crate) fn estimate_subdiv(&self, sqrt_tol: f64) -> FlattenParams {\n        // Determine transformation to $y = x^2$ parabola.\n        let d01 = self.p1 - self.p0;\n        let d12 = self.p2 - self.p1;\n        let dd = d01 - d12;\n        let cross = (self.p2 - self.p0).cross(dd);\n        let x0 = d01.dot(dd) * cross.recip();\n        let x2 = d12.dot(dd) * cross.recip();\n        let scale = (cross / (dd.hypot() * (x2 - x0))).abs();\n\n        // Compute number of subdivisions needed.\n        let a0 = approx_parabola_integral(x0);\n        let a2 = approx_parabola_integral(x2);\n        let val = if scale.is_finite() {\n            let da = (a2 - a0).abs();\n            let sqrt_scale = scale.sqrt();\n            if x0.signum() == x2.signum() {\n                da * sqrt_scale\n            } else {\n                // Handle cusp case (segment contains curvature maximum)\n                let xmin = sqrt_tol / sqrt_scale;\n                sqrt_tol * da / approx_parabola_integral(xmin)\n            }\n        } else {\n            0.0\n        };\n        let u0 = approx_parabola_inv_integral(a0);\n        let u2 = approx_parabola_inv_integral(a2);\n        let uscale = (u2 - u0).recip();\n        FlattenParams {\n            a0,\n            a2,\n            u0,\n            uscale,\n            val,\n        }\n    }\n\n    // Maps a value from 0..1 to 0..1.\n    pub(crate) fn determine_subdiv_t(&self, params: &FlattenParams, x: f64) -> f64 {\n        let a = params.a0 + (params.a2 - params.a0) * x;\n        let u = approx_parabola_inv_integral(a);\n        (u - params.u0) * params.uscale\n    }\n\n    /// Is this quadratic Bezier curve finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.p0.is_finite() && self.p1.is_finite() && self.p2.is_finite()\n    }\n\n    /// Is this quadratic Bezier curve NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.p0.is_nan() || self.p1.is_nan() || self.p2.is_nan()\n    }\n}\n\n/// An iterator for quadratic beziers.\npub struct QuadBezIter {\n    quad: QuadBez,\n    ix: usize,\n}\n\nimpl Shape for QuadBez {\n    type PathElementsIter<'iter> = QuadBezIter;\n\n    #[inline]\n    fn path_elements(&self, _tolerance: f64) -> QuadBezIter {\n        QuadBezIter { quad: *self, ix: 0 }\n    }\n\n    fn area(&self) -> f64 {\n        0.0\n    }\n\n    #[inline]\n    fn perimeter(&self, accuracy: f64) -> f64 {\n        self.arclen(accuracy)\n    }\n\n    fn winding(&self, _pt: Point) -> i32 {\n        0\n    }\n\n    #[inline]\n    fn bounding_box(&self) -> Rect {\n        ParamCurveExtrema::bounding_box(self)\n    }\n}\n\nimpl Iterator for QuadBezIter {\n    type Item = PathEl;\n\n    fn next(&mut self) -> Option<PathEl> {\n        self.ix += 1;\n        match self.ix {\n            1 => Some(PathEl::MoveTo(self.quad.p0)),\n            2 => Some(PathEl::QuadTo(self.quad.p1, self.quad.p2)),\n            _ => None,\n        }\n    }\n}\n\npub(crate) struct FlattenParams {\n    a0: f64,\n    a2: f64,\n    u0: f64,\n    uscale: f64,\n    /// The number of subdivisions * 2 * sqrt_tol.\n    pub(crate) val: f64,\n}\n\n/// An approximation to $\\int (1 + 4x^2) ^ -0.25 dx$\n///\n/// This is used for flattening curves.\nfn approx_parabola_integral(x: f64) -> f64 {\n    const D: f64 = 0.67;\n    x / (1.0 - D + (D.powi(4) + 0.25 * x * x).sqrt().sqrt())\n}\n\n/// An approximation to the inverse parabola integral.\nfn approx_parabola_inv_integral(x: f64) -> f64 {\n    const B: f64 = 0.39;\n    x * (1.0 - B + (B * B + 0.25 * x * x).sqrt())\n}\n\nimpl ParamCurve for QuadBez {\n    #[inline]\n    fn eval(&self, t: f64) -> Point {\n        let mt = 1.0 - t;\n        (self.p0.to_vec2() * (mt * mt)\n            + (self.p1.to_vec2() * (mt * 2.0) + self.p2.to_vec2() * t) * t)\n            .to_point()\n    }\n\n    fn subsegment(&self, range: Range<f64>) -> QuadBez {\n        let (t0, t1) = (range.start, range.end);\n        let p0 = self.eval(t0);\n        let p2 = self.eval(t1);\n        let p1 = p0 + (self.p1 - self.p0).lerp(self.p2 - self.p1, t0) * (t1 - t0);\n        QuadBez { p0, p1, p2 }\n    }\n\n    /// Subdivide into halves, using de Casteljau.\n    #[inline]\n    fn subdivide(&self) -> (QuadBez, QuadBez) {\n        let pm = self.eval(0.5);\n        (\n            QuadBez::new(self.p0, self.p0.midpoint(self.p1), pm),\n            QuadBez::new(pm, self.p1.midpoint(self.p2), self.p2),\n        )\n    }\n\n    #[inline]\n    fn start(&self) -> Point {\n        self.p0\n    }\n\n    #[inline]\n    fn end(&self) -> Point {\n        self.p2\n    }\n}\n\nimpl ParamCurveDeriv for QuadBez {\n    type DerivResult = Line;\n\n    #[inline]\n    fn deriv(&self) -> Line {\n        Line::new(\n            (2.0 * (self.p1.to_vec2() - self.p0.to_vec2())).to_point(),\n            (2.0 * (self.p2.to_vec2() - self.p1.to_vec2())).to_point(),\n        )\n    }\n}\n\nimpl ParamCurveArclen for QuadBez {\n    /// Arclength of a quadratic Bézier segment.\n    ///\n    /// This computation is based on an analytical formula. Since that formula suffers\n    /// from numerical instability when the curve is very close to a straight line, we\n    /// detect that case and fall back to Legendre-Gauss quadrature.\n    ///\n    /// Accuracy should be better than 1e-13 over the entire range.\n    ///\n    /// Adapted from <http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/>\n    /// with permission.\n    fn arclen(&self, _accuracy: f64) -> f64 {\n        let d2 = self.p0.to_vec2() - 2.0 * self.p1.to_vec2() + self.p2.to_vec2();\n        let a = d2.hypot2();\n        let d1 = self.p1 - self.p0;\n        let c = d1.hypot2();\n        if a < 5e-4 * c {\n            // This case happens for nearly straight Béziers.\n            //\n            // Calculate arclength using Legendre-Gauss quadrature using formula from Behdad\n            // in https://github.com/Pomax/BezierInfo-2/issues/77\n            let v0 = (-0.492943519233745 * self.p0.to_vec2()\n                + 0.430331482911935 * self.p1.to_vec2()\n                + 0.0626120363218102 * self.p2.to_vec2())\n            .hypot();\n            let v1 = ((self.p2 - self.p0) * 0.4444444444444444).hypot();\n            let v2 = (-0.0626120363218102 * self.p0.to_vec2()\n                - 0.430331482911935 * self.p1.to_vec2()\n                + 0.492943519233745 * self.p2.to_vec2())\n            .hypot();\n            return v0 + v1 + v2;\n        }\n        let b = 2.0 * d2.dot(d1);\n\n        let sabc = (a + b + c).sqrt();\n        let a2 = a.powf(-0.5);\n        let a32 = a2.powi(3);\n        let c2 = 2.0 * c.sqrt();\n        let ba_c2 = b * a2 + c2;\n\n        let v0 = 0.25 * a2 * a2 * b * (2.0 * sabc - c2) + sabc;\n        // TODO: justify and fine-tune this exact constant.\n        if ba_c2 < 1e-13 {\n            // This case happens for Béziers with a sharp kink.\n            v0\n        } else {\n            v0 + 0.25\n                * a32\n                * (4.0 * c * a - b * b)\n                * (((2.0 * a + b) * a2 + 2.0 * sabc) / ba_c2).ln()\n        }\n    }\n}\n\nimpl ParamCurveArea for QuadBez {\n    #[inline]\n    fn signed_area(&self) -> f64 {\n        (self.p0.x * (2.0 * self.p1.y + self.p2.y) + 2.0 * self.p1.x * (self.p2.y - self.p0.y)\n            - self.p2.x * (self.p0.y + 2.0 * self.p1.y))\n            * (1.0 / 6.0)\n    }\n}\n\nimpl ParamCurveNearest for QuadBez {\n    /// Find the nearest point, using analytical algorithm based on cubic root finding.\n    fn nearest(&self, p: Point, _accuracy: f64) -> Nearest {\n        fn eval_t(p: Point, t_best: &mut f64, r_best: &mut Option<f64>, t: f64, p0: Point) {\n            let r = (p0 - p).hypot2();\n            if r_best.map(|r_best| r < r_best).unwrap_or(true) {\n                *r_best = Some(r);\n                *t_best = t;\n            }\n        }\n        fn try_t(\n            q: &QuadBez,\n            p: Point,\n            t_best: &mut f64,\n            r_best: &mut Option<f64>,\n            t: f64,\n        ) -> bool {\n            if !(0.0..=1.0).contains(&t) {\n                return true;\n            }\n            eval_t(p, t_best, r_best, t, q.eval(t));\n            false\n        }\n        let d0 = self.p1 - self.p0;\n        let d1 = self.p0.to_vec2() + self.p2.to_vec2() - 2.0 * self.p1.to_vec2();\n        let d = self.p0 - p;\n        let c0 = d.dot(d0);\n        let c1 = 2.0 * d0.hypot2() + d.dot(d1);\n        let c2 = 3.0 * d1.dot(d0);\n        let c3 = d1.hypot2();\n        let roots = solve_cubic(c0, c1, c2, c3);\n        let mut r_best = None;\n        let mut t_best = 0.0;\n        let mut need_ends = false;\n        if roots.is_empty() {\n            need_ends = true;\n        }\n        for &t in &roots {\n            need_ends |= try_t(self, p, &mut t_best, &mut r_best, t);\n        }\n        if need_ends {\n            eval_t(p, &mut t_best, &mut r_best, 0.0, self.p0);\n            eval_t(p, &mut t_best, &mut r_best, 1.0, self.p2);\n        }\n\n        Nearest {\n            t: t_best,\n            distance_sq: r_best.unwrap(),\n        }\n    }\n}\n\nimpl ParamCurveCurvature for QuadBez {}\n\nimpl ParamCurveExtrema for QuadBez {\n    fn extrema(&self) -> ArrayVec<f64, MAX_EXTREMA> {\n        let mut result = ArrayVec::new();\n        let d0 = self.p1 - self.p0;\n        let d1 = self.p2 - self.p1;\n        let dd = d1 - d0;\n        if dd.x != 0.0 {\n            let t = -d0.x / dd.x;\n            if t > 0.0 && t < 1.0 {\n                result.push(t);\n            }\n        }\n        if dd.y != 0.0 {\n            let t = -d0.y / dd.y;\n            if t > 0.0 && t < 1.0 {\n                result.push(t);\n                if result.len() == 2 && result[0] > t {\n                    result.swap(0, 1);\n                }\n            }\n        }\n        result\n    }\n}\n\nimpl Mul<QuadBez> for Affine {\n    type Output = QuadBez;\n\n    #[inline]\n    fn mul(self, other: QuadBez) -> QuadBez {\n        QuadBez {\n            p0: self * other.p0,\n            p1: self * other.p1,\n            p2: self * other.p2,\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        Affine, Nearest, ParamCurve, ParamCurveArclen, ParamCurveArea, ParamCurveDeriv,\n        ParamCurveExtrema, ParamCurveNearest, Point, QuadBez,\n    };\n\n    fn assert_near(p0: Point, p1: Point, epsilon: f64) {\n        assert!((p1 - p0).hypot() < epsilon, \"{p0:?} != {p1:?}\");\n    }\n\n    #[test]\n    fn quadbez_deriv() {\n        let q = QuadBez::new((0.0, 0.0), (0.0, 0.5), (1.0, 1.0));\n        let deriv = q.deriv();\n\n        let n = 10;\n        for i in 0..=n {\n            let t = (i as f64) * (n as f64).recip();\n            let delta = 1e-6;\n            let p = q.eval(t);\n            let p1 = q.eval(t + delta);\n            let d_approx = (p1 - p) * delta.recip();\n            let d = deriv.eval(t).to_vec2();\n            assert!((d - d_approx).hypot() < delta * 2.0);\n        }\n    }\n\n    #[test]\n    fn quadbez_arclen() {\n        let q = QuadBez::new((0.0, 0.0), (0.0, 0.5), (1.0, 1.0));\n        let true_arclen = 0.5 * 5.0f64.sqrt() + 0.25 * (2.0 + 5.0f64.sqrt()).ln();\n        for i in 0..12 {\n            let accuracy = 0.1f64.powi(i);\n            let est = q.arclen(accuracy);\n            let error = est - true_arclen;\n            assert!(error.abs() < accuracy, \"{est} != {true_arclen}\");\n        }\n    }\n\n    #[test]\n    fn quadbez_arclen_pathological() {\n        let q = QuadBez::new((-1.0, 0.0), (1.03, 0.0), (1.0, 0.0));\n        let true_arclen = 2.0008737864167325; // A rough empirical calculation\n        let accuracy = 1e-11;\n        let est = q.arclen(accuracy);\n        assert!(\n            (est - true_arclen).abs() < accuracy,\n            \"{est} != {true_arclen}\"\n        );\n    }\n\n    #[test]\n    fn quadbez_subsegment() {\n        let q = QuadBez::new((3.1, 4.1), (5.9, 2.6), (5.3, 5.8));\n        let t0 = 0.1;\n        let t1 = 0.8;\n        let qs = q.subsegment(t0..t1);\n        let epsilon = 1e-12;\n        let n = 10;\n        for i in 0..=n {\n            let t = (i as f64) * (n as f64).recip();\n            let ts = t0 + t * (t1 - t0);\n            assert_near(q.eval(ts), qs.eval(t), epsilon);\n        }\n    }\n\n    #[test]\n    fn quadbez_raise() {\n        let q = QuadBez::new((3.1, 4.1), (5.9, 2.6), (5.3, 5.8));\n        let c = q.raise();\n        let qd = q.deriv();\n        let cd = c.deriv();\n        let epsilon = 1e-12;\n        let n = 10;\n        for i in 0..=n {\n            let t = (i as f64) * (n as f64).recip();\n            assert_near(q.eval(t), c.eval(t), epsilon);\n            assert_near(qd.eval(t), cd.eval(t), epsilon);\n        }\n    }\n\n    #[test]\n    fn quadbez_signed_area() {\n        // y = 1 - x^2\n        let q = QuadBez::new((1.0, 0.0), (0.5, 1.0), (0.0, 1.0));\n        let epsilon = 1e-12;\n        assert!((q.signed_area() - 2.0 / 3.0).abs() < epsilon);\n        assert!(((Affine::rotate(0.5) * q).signed_area() - 2.0 / 3.0).abs() < epsilon);\n        assert!(((Affine::translate((0.0, 1.0)) * q).signed_area() - 3.5 / 3.0).abs() < epsilon);\n        assert!(((Affine::translate((1.0, 0.0)) * q).signed_area() - 3.5 / 3.0).abs() < epsilon);\n    }\n\n    fn verify(result: Nearest, expected: f64) {\n        assert!(\n            (result.t - expected).abs() < 1e-6,\n            \"got {result:?} expected {expected}\"\n        );\n    }\n\n    #[test]\n    fn quadbez_nearest() {\n        // y = x^2\n        let q = QuadBez::new((-1.0, 1.0), (0.0, -1.0), (1.0, 1.0));\n        verify(q.nearest((0.0, 0.0).into(), 1e-3), 0.5);\n        verify(q.nearest((0.0, 0.1).into(), 1e-3), 0.5);\n        verify(q.nearest((0.0, -0.1).into(), 1e-3), 0.5);\n        verify(q.nearest((0.5, 0.25).into(), 1e-3), 0.75);\n        verify(q.nearest((1.0, 1.0).into(), 1e-3), 1.0);\n        verify(q.nearest((1.1, 1.1).into(), 1e-3), 1.0);\n        verify(q.nearest((-1.1, 1.1).into(), 1e-3), 0.0);\n        let a = Affine::rotate(0.5);\n        verify((a * q).nearest(a * Point::new(0.5, 0.25), 1e-3), 0.75);\n    }\n\n    // This test exposes a degenerate case in the solver used internally\n    // by the \"nearest\" calculation - the cubic term is zero.\n    #[test]\n    fn quadbez_nearest_low_order() {\n        let q = QuadBez::new((-1.0, 0.0), (0.0, 0.0), (1.0, 0.0));\n\n        verify(q.nearest((0.0, 0.0).into(), 1e-3), 0.5);\n        verify(q.nearest((0.0, 1.0).into(), 1e-3), 0.5);\n    }\n\n    #[test]\n    fn quadbez_nearest_rounding_panic() {\n        let quad = QuadBez::new(\n            (-1.0394736842105263, 0.0),\n            (0.8210526315789474, -1.511111111111111),\n            (0.0, 1.9333333333333333),\n        );\n        let test = Point::new(-1.7976931348623157e308, 0.8571428571428571);\n        // accuracy ignored\n        let _res = quad.nearest(test, 1e-6);\n        // if we got here then we didn't panic\n    }\n\n    #[test]\n    fn quadbez_extrema() {\n        // y = x^2\n        let q = QuadBez::new((-1.0, 1.0), (0.0, -1.0), (1.0, 1.0));\n        let extrema = q.extrema();\n        assert_eq!(extrema.len(), 1);\n        assert!((extrema[0] - 0.5).abs() < 1e-6);\n\n        let q = QuadBez::new((0.0, 0.5), (1.0, 1.0), (0.5, 0.0));\n        let extrema = q.extrema();\n        assert_eq!(extrema.len(), 2);\n        assert!((extrema[0] - 1.0 / 3.0).abs() < 1e-6);\n        assert!((extrema[1] - 2.0 / 3.0).abs() < 1e-6);\n\n        // Reverse direction\n        let q = QuadBez::new((0.5, 0.0), (1.0, 1.0), (0.0, 0.5));\n        let extrema = q.extrema();\n        assert_eq!(extrema.len(), 2);\n        assert!((extrema[0] - 1.0 / 3.0).abs() < 1e-6);\n        assert!((extrema[1] - 2.0 / 3.0).abs() < 1e-6);\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/quadspline.rs",
      "sha256": "33051e7f381f729f89af925b6f40faa1e766b4787bba768177046fb6b699fe60",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2021 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Quadratic Bézier splines.\nuse crate::Point;\n\nuse crate::QuadBez;\nuse alloc::vec::Vec;\n\n/// A quadratic Bézier spline in [B-spline](https://en.wikipedia.org/wiki/B-spline) format.\n#[derive(Clone, Debug, PartialEq)]\npub struct QuadSpline(Vec<Point>);\n\nimpl QuadSpline {\n    /// Construct a new `QuadSpline` from an array of [`Point`]s.\n    #[inline]\n    pub fn new(points: Vec<Point>) -> Self {\n        Self(points)\n    }\n\n    /// Return the spline's control [`Point`]s.\n    #[inline]\n    pub fn points(&self) -> &[Point] {\n        &self.0\n    }\n\n    /// Return an iterator over the implied [`QuadBez`] sequence.\n    ///\n    /// The returned quads are guaranteed to be G1 continuous.\n    #[inline]\n    pub fn to_quads(&self) -> impl Iterator<Item = QuadBez> + '_ {\n        ToQuadBez {\n            idx: 0,\n            points: &self.0,\n        }\n    }\n}\n\nstruct ToQuadBez<'a> {\n    idx: usize,\n    points: &'a Vec<Point>,\n}\n\nimpl<'a> Iterator for ToQuadBez<'a> {\n    type Item = QuadBez;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let [mut p0, p1, mut p2]: [Point; 3] =\n            self.points.get(self.idx..=self.idx + 2)?.try_into().ok()?;\n\n        if self.idx != 0 {\n            p0 = p0.midpoint(p1);\n        }\n        if self.idx + 2 < self.points.len() - 1 {\n            p2 = p1.midpoint(p2);\n        }\n\n        self.idx += 1;\n\n        Some(QuadBez { p0, p1, p2 })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Point, QuadBez, QuadSpline};\n\n    #[test]\n    pub fn no_points_no_quads() {\n        assert!(QuadSpline::new(Vec::new()).to_quads().next().is_none());\n    }\n\n    #[test]\n    pub fn one_point_no_quads() {\n        assert!(QuadSpline::new(vec![Point::new(1.0, 1.0)])\n            .to_quads()\n            .next()\n            .is_none());\n    }\n\n    #[test]\n    pub fn two_points_no_quads() {\n        assert!(\n            QuadSpline::new(vec![Point::new(1.0, 1.0), Point::new(1.0, 1.0)])\n                .to_quads()\n                .next()\n                .is_none()\n        );\n    }\n\n    #[test]\n    pub fn three_points_same_quad() {\n        let p0 = Point::new(1.0, 1.0);\n        let p1 = Point::new(2.0, 2.0);\n        let p2 = Point::new(3.0, 3.0);\n        assert_eq!(\n            vec![QuadBez { p0, p1, p2 }],\n            QuadSpline::new(vec![p0, p1, p2])\n                .to_quads()\n                .collect::<Vec<_>>()\n        );\n    }\n\n    #[test]\n    pub fn four_points_implicit_on_curve() {\n        let p0 = Point::new(1.0, 1.0);\n        let p1 = Point::new(3.0, 3.0);\n        let p2 = Point::new(5.0, 5.0);\n        let p3 = Point::new(8.0, 8.0);\n        assert_eq!(\n            vec![\n                QuadBez {\n                    p0,\n                    p1,\n                    p2: p1.midpoint(p2)\n                },\n                QuadBez {\n                    p0: p1.midpoint(p2),\n                    p1: p2,\n                    p2: p3\n                }\n            ],\n            QuadSpline::new(vec![p0, p1, p2, p3])\n                .to_quads()\n                .collect::<Vec<_>>()\n        );\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/rect.rs",
      "sha256": "23a2fd89a0cd527c71f764840f14a152f349e8bd161ceee64ec8e038ef24e87d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A rectangle.\n\nuse core::fmt;\nuse core::ops::{Add, Sub};\n\nuse crate::{Ellipse, Insets, PathEl, Point, RoundedRect, RoundedRectRadii, Shape, Size, Vec2};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A rectangle.\n#[derive(Clone, Copy, Default, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Rect {\n    /// The minimum x coordinate (left edge).\n    pub x0: f64,\n    /// The minimum y coordinate (top edge in y-down spaces).\n    pub y0: f64,\n    /// The maximum x coordinate (right edge).\n    pub x1: f64,\n    /// The maximum y coordinate (bottom edge in y-down spaces).\n    pub y1: f64,\n}\n\nimpl Rect {\n    /// The empty rectangle at the origin.\n    pub const ZERO: Rect = Rect::new(0., 0., 0., 0.);\n\n    /// A new rectangle from minimum and maximum coordinates.\n    #[inline]\n    pub const fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Rect {\n        Rect { x0, y0, x1, y1 }\n    }\n\n    /// A new rectangle from two points.\n    ///\n    /// The result will have non-negative width and height.\n    #[inline]\n    pub fn from_points(p0: impl Into<Point>, p1: impl Into<Point>) -> Rect {\n        let p0 = p0.into();\n        let p1 = p1.into();\n        Rect::new(p0.x, p0.y, p1.x, p1.y).abs()\n    }\n\n    /// A new rectangle from origin and size.\n    ///\n    /// The result will have non-negative width and height.\n    #[inline]\n    pub fn from_origin_size(origin: impl Into<Point>, size: impl Into<Size>) -> Rect {\n        let origin = origin.into();\n        Rect::from_points(origin, origin + size.into().to_vec2())\n    }\n\n    /// A new rectangle from center and size.\n    #[inline]\n    pub fn from_center_size(center: impl Into<Point>, size: impl Into<Size>) -> Rect {\n        let center = center.into();\n        let size = 0.5 * size.into();\n        Rect::new(\n            center.x - size.width,\n            center.y - size.height,\n            center.x + size.width,\n            center.y + size.height,\n        )\n    }\n\n    /// Create a new `Rect` with the same size as `self` and a new origin.\n    #[inline]\n    pub fn with_origin(self, origin: impl Into<Point>) -> Rect {\n        Rect::from_origin_size(origin, self.size())\n    }\n\n    /// Create a new `Rect` with the same origin as `self` and a new size.\n    #[inline]\n    pub fn with_size(self, size: impl Into<Size>) -> Rect {\n        Rect::from_origin_size(self.origin(), size)\n    }\n\n    /// Create a new `Rect` by applying the [`Insets`].\n    ///\n    /// This will not preserve negative width and height.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Rect;\n    /// let inset_rect = Rect::new(0., 0., 10., 10.,).inset(2.);\n    /// assert_eq!(inset_rect.width(), 14.0);\n    /// assert_eq!(inset_rect.x0, -2.0);\n    /// assert_eq!(inset_rect.x1, 12.0);\n    /// ```\n    #[inline]\n    pub fn inset(self, insets: impl Into<Insets>) -> Rect {\n        self + insets.into()\n    }\n\n    /// The width of the rectangle.\n    ///\n    /// Note: nothing forbids negative width.\n    #[inline]\n    pub fn width(&self) -> f64 {\n        self.x1 - self.x0\n    }\n\n    /// The height of the rectangle.\n    ///\n    /// Note: nothing forbids negative height.\n    #[inline]\n    pub fn height(&self) -> f64 {\n        self.y1 - self.y0\n    }\n\n    /// Returns the minimum value for the x-coordinate of the rectangle.\n    #[inline]\n    pub fn min_x(&self) -> f64 {\n        self.x0.min(self.x1)\n    }\n\n    /// Returns the maximum value for the x-coordinate of the rectangle.\n    #[inline]\n    pub fn max_x(&self) -> f64 {\n        self.x0.max(self.x1)\n    }\n\n    /// Returns the minimum value for the y-coordinate of the rectangle.\n    #[inline]\n    pub fn min_y(&self) -> f64 {\n        self.y0.min(self.y1)\n    }\n\n    /// Returns the maximum value for the y-coordinate of the rectangle.\n    #[inline]\n    pub fn max_y(&self) -> f64 {\n        self.y0.max(self.y1)\n    }\n\n    /// The origin of the rectangle.\n    ///\n    /// This is the top left corner in a y-down space and with\n    /// non-negative width and height.\n    #[inline]\n    pub fn origin(&self) -> Point {\n        Point::new(self.x0, self.y0)\n    }\n\n    /// The size of the rectangle.\n    #[inline]\n    pub fn size(&self) -> Size {\n        Size::new(self.width(), self.height())\n    }\n\n    /// The area of the rectangle.\n    #[inline]\n    pub fn area(&self) -> f64 {\n        self.width() * self.height()\n    }\n\n    /// Whether this rectangle has zero area.\n    ///\n    /// Note: a rectangle with negative area is not considered empty.\n    #[inline]\n    pub fn is_empty(&self) -> bool {\n        self.area() == 0.0\n    }\n\n    /// The center point of the rectangle.\n    #[inline]\n    pub fn center(&self) -> Point {\n        Point::new(0.5 * (self.x0 + self.x1), 0.5 * (self.y0 + self.y1))\n    }\n\n    /// Returns `true` if `point` lies within `self`.\n    #[inline]\n    pub fn contains(&self, point: Point) -> bool {\n        point.x >= self.x0 && point.x < self.x1 && point.y >= self.y0 && point.y < self.y1\n    }\n\n    /// Take absolute value of width and height.\n    ///\n    /// The resulting rect has the same extents as the original, but is\n    /// guaranteed to have non-negative width and height.\n    #[inline]\n    pub fn abs(&self) -> Rect {\n        let Rect { x0, y0, x1, y1 } = *self;\n        Rect::new(x0.min(x1), y0.min(y1), x0.max(x1), y0.max(y1))\n    }\n\n    /// The smallest rectangle enclosing two rectangles.\n    ///\n    /// Results are valid only if width and height are non-negative.\n    #[inline]\n    pub fn union(&self, other: Rect) -> Rect {\n        Rect::new(\n            self.x0.min(other.x0),\n            self.y0.min(other.y0),\n            self.x1.max(other.x1),\n            self.y1.max(other.y1),\n        )\n    }\n\n    /// Compute the union with one point.\n    ///\n    /// This method includes the perimeter of zero-area rectangles.\n    /// Thus, a succession of `union_pt` operations on a series of\n    /// points yields their enclosing rectangle.\n    ///\n    /// Results are valid only if width and height are non-negative.\n    pub fn union_pt(&self, pt: Point) -> Rect {\n        Rect::new(\n            self.x0.min(pt.x),\n            self.y0.min(pt.y),\n            self.x1.max(pt.x),\n            self.y1.max(pt.y),\n        )\n    }\n\n    /// The intersection of two rectangles.\n    ///\n    /// The result is zero-area if either input has negative width or\n    /// height. The result always has non-negative width and height.\n    #[inline]\n    pub fn intersect(&self, other: Rect) -> Rect {\n        let x0 = self.x0.max(other.x0);\n        let y0 = self.y0.max(other.y0);\n        let x1 = self.x1.min(other.x1);\n        let y1 = self.y1.min(other.y1);\n        Rect::new(x0, y0, x1.max(x0), y1.max(y0))\n    }\n\n    /// Expand a rectangle by a constant amount in both directions.\n    ///\n    /// The logic simply applies the amount in each direction. If rectangle\n    /// area or added dimensions are negative, this could give odd results.\n    pub fn inflate(&self, width: f64, height: f64) -> Rect {\n        Rect::new(\n            self.x0 - width,\n            self.y0 - height,\n            self.x1 + width,\n            self.y1 + height,\n        )\n    }\n\n    /// Returns a new `Rect`,\n    /// with each coordinate value rounded to the nearest integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Rect;\n    /// let rect = Rect::new(3.3, 3.6, 3.0, -3.1).round();\n    /// assert_eq!(rect.x0, 3.0);\n    /// assert_eq!(rect.y0, 4.0);\n    /// assert_eq!(rect.x1, 3.0);\n    /// assert_eq!(rect.y1, -3.0);\n    /// ```\n    #[inline]\n    pub fn round(self) -> Rect {\n        Rect::new(\n            self.x0.round(),\n            self.y0.round(),\n            self.x1.round(),\n            self.y1.round(),\n        )\n    }\n\n    /// Returns a new `Rect`,\n    /// with each coordinate value rounded up to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Rect;\n    /// let rect = Rect::new(3.3, 3.6, 3.0, -3.1).ceil();\n    /// assert_eq!(rect.x0, 4.0);\n    /// assert_eq!(rect.y0, 4.0);\n    /// assert_eq!(rect.x1, 3.0);\n    /// assert_eq!(rect.y1, -3.0);\n    /// ```\n    #[inline]\n    pub fn ceil(self) -> Rect {\n        Rect::new(\n            self.x0.ceil(),\n            self.y0.ceil(),\n            self.x1.ceil(),\n            self.y1.ceil(),\n        )\n    }\n\n    /// Returns a new `Rect`,\n    /// with each coordinate value rounded down to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Rect;\n    /// let rect = Rect::new(3.3, 3.6, 3.0, -3.1).floor();\n    /// assert_eq!(rect.x0, 3.0);\n    /// assert_eq!(rect.y0, 3.0);\n    /// assert_eq!(rect.x1, 3.0);\n    /// assert_eq!(rect.y1, -4.0);\n    /// ```\n    #[inline]\n    pub fn floor(self) -> Rect {\n        Rect::new(\n            self.x0.floor(),\n            self.y0.floor(),\n            self.x1.floor(),\n            self.y1.floor(),\n        )\n    }\n\n    /// Returns a new `Rect`,\n    /// with each coordinate value rounded away from the center of the `Rect`\n    /// to the nearest integer, unless they are already an integer.\n    /// That is to say this function will return the smallest possible `Rect`\n    /// with integer coordinates that is a superset of `self`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Rect;\n    ///\n    /// // In positive space\n    /// let rect = Rect::new(3.3, 3.6, 5.6, 4.1).expand();\n    /// assert_eq!(rect.x0, 3.0);\n    /// assert_eq!(rect.y0, 3.0);\n    /// assert_eq!(rect.x1, 6.0);\n    /// assert_eq!(rect.y1, 5.0);\n    ///\n    /// // In both positive and negative space\n    /// let rect = Rect::new(-3.3, -3.6, 5.6, 4.1).expand();\n    /// assert_eq!(rect.x0, -4.0);\n    /// assert_eq!(rect.y0, -4.0);\n    /// assert_eq!(rect.x1, 6.0);\n    /// assert_eq!(rect.y1, 5.0);\n    ///\n    /// // In negative space\n    /// let rect = Rect::new(-5.6, -4.1, -3.3, -3.6).expand();\n    /// assert_eq!(rect.x0, -6.0);\n    /// assert_eq!(rect.y0, -5.0);\n    /// assert_eq!(rect.x1, -3.0);\n    /// assert_eq!(rect.y1, -3.0);\n    ///\n    /// // Inverse orientation\n    /// let rect = Rect::new(5.6, -3.6, 3.3, -4.1).expand();\n    /// assert_eq!(rect.x0, 6.0);\n    /// assert_eq!(rect.y0, -3.0);\n    /// assert_eq!(rect.x1, 3.0);\n    /// assert_eq!(rect.y1, -5.0);\n    /// ```\n    #[inline]\n    pub fn expand(self) -> Rect {\n        // The compiler optimizer will remove the if branching.\n        let (x0, x1) = if self.x0 < self.x1 {\n            (self.x0.floor(), self.x1.ceil())\n        } else {\n            (self.x0.ceil(), self.x1.floor())\n        };\n        let (y0, y1) = if self.y0 < self.y1 {\n            (self.y0.floor(), self.y1.ceil())\n        } else {\n            (self.y0.ceil(), self.y1.floor())\n        };\n        Rect::new(x0, y0, x1, y1)\n    }\n\n    /// Returns a new `Rect`,\n    /// with each coordinate value rounded towards the center of the `Rect`\n    /// to the nearest integer, unless they are already an integer.\n    /// That is to say this function will return the biggest possible `Rect`\n    /// with integer coordinates that is a subset of `self`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Rect;\n    ///\n    /// // In positive space\n    /// let rect = Rect::new(3.3, 3.6, 5.6, 4.1).trunc();\n    /// assert_eq!(rect.x0, 4.0);\n    /// assert_eq!(rect.y0, 4.0);\n    /// assert_eq!(rect.x1, 5.0);\n    /// assert_eq!(rect.y1, 4.0);\n    ///\n    /// // In both positive and negative space\n    /// let rect = Rect::new(-3.3, -3.6, 5.6, 4.1).trunc();\n    /// assert_eq!(rect.x0, -3.0);\n    /// assert_eq!(rect.y0, -3.0);\n    /// assert_eq!(rect.x1, 5.0);\n    /// assert_eq!(rect.y1, 4.0);\n    ///\n    /// // In negative space\n    /// let rect = Rect::new(-5.6, -4.1, -3.3, -3.6).trunc();\n    /// assert_eq!(rect.x0, -5.0);\n    /// assert_eq!(rect.y0, -4.0);\n    /// assert_eq!(rect.x1, -4.0);\n    /// assert_eq!(rect.y1, -4.0);\n    ///\n    /// // Inverse orientation\n    /// let rect = Rect::new(5.6, -3.6, 3.3, -4.1).trunc();\n    /// assert_eq!(rect.x0, 5.0);\n    /// assert_eq!(rect.y0, -4.0);\n    /// assert_eq!(rect.x1, 4.0);\n    /// assert_eq!(rect.y1, -4.0);\n    /// ```\n    #[inline]\n    pub fn trunc(self) -> Rect {\n        // The compiler optimizer will remove the if branching.\n        let (x0, x1) = if self.x0 < self.x1 {\n            (self.x0.ceil(), self.x1.floor())\n        } else {\n            (self.x0.floor(), self.x1.ceil())\n        };\n        let (y0, y1) = if self.y0 < self.y1 {\n            (self.y0.ceil(), self.y1.floor())\n        } else {\n            (self.y0.floor(), self.y1.ceil())\n        };\n        Rect::new(x0, y0, x1, y1)\n    }\n\n    /// Scales the `Rect` by `factor` with respect to the origin (the point `(0, 0)`).\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Rect;\n    ///\n    /// let rect = Rect::new(2., 2., 4., 6.).scale_from_origin(2.);\n    /// assert_eq!(rect.x0, 4.);\n    /// assert_eq!(rect.x1, 8.);\n    /// ```\n    #[inline]\n    pub fn scale_from_origin(self, factor: f64) -> Rect {\n        Rect {\n            x0: self.x0 * factor,\n            y0: self.y0 * factor,\n            x1: self.x1 * factor,\n            y1: self.y1 * factor,\n        }\n    }\n\n    /// Creates a new [`RoundedRect`] from this `Rect` and the provided\n    /// corner radius.\n    #[inline]\n    pub fn to_rounded_rect(self, radii: impl Into<RoundedRectRadii>) -> RoundedRect {\n        RoundedRect::from_rect(self, radii)\n    }\n\n    /// Returns the [`Ellipse`] that is bounded by this `Rect`.\n    #[inline]\n    pub fn to_ellipse(self) -> Ellipse {\n        Ellipse::from_rect(self)\n    }\n\n    /// The aspect ratio of the `Rect`.\n    ///\n    /// This is defined as the height divided by the width. It measures the\n    /// \"squareness\" of the rectangle (a value of `1` is square).\n    ///\n    /// If the width is `0` the output will be `sign(y1 - y0) * infinity`.\n    ///\n    /// If The width and height are `0`, the result will be `NaN`.\n    #[inline]\n    pub fn aspect_ratio(&self) -> f64 {\n        self.size().aspect_ratio()\n    }\n\n    /// Returns the largest possible `Rect` that is fully contained in `self`\n    /// with the given `aspect_ratio`.\n    ///\n    /// The aspect ratio is specified fractionally, as `height / width`.\n    ///\n    /// The resulting rectangle will be centered if it is smaller than the\n    /// input rectangle.\n    ///\n    /// For the special case where the aspect ratio is `1.0`, the resulting\n    /// `Rect` will be square.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use kurbo::Rect;\n    /// let outer = Rect::new(0.0, 0.0, 10.0, 20.0);\n    /// let inner = outer.contained_rect_with_aspect_ratio(1.0);\n    /// // The new `Rect` is a square centered at the center of `outer`.\n    /// assert_eq!(inner, Rect::new(0.0, 5.0, 10.0, 15.0));\n    /// ```\n    ///\n    pub fn contained_rect_with_aspect_ratio(&self, aspect_ratio: f64) -> Rect {\n        let (width, height) = (self.width(), self.height());\n        let self_aspect = height / width;\n\n        // TODO the parameter `1e-9` was chosen quickly and may not be optimal.\n        if (self_aspect - aspect_ratio).abs() < 1e-9 {\n            // short circuit\n            *self\n        } else if self_aspect.abs() < aspect_ratio.abs() {\n            // shrink x to fit\n            let new_width = height * aspect_ratio.recip();\n            let gap = (width - new_width) * 0.5;\n            let x0 = self.x0 + gap;\n            let x1 = self.x1 - gap;\n            Rect::new(x0, self.y0, x1, self.y1)\n        } else {\n            // shrink y to fit\n            let new_height = width * aspect_ratio;\n            let gap = (height - new_height) * 0.5;\n            let y0 = self.y0 + gap;\n            let y1 = self.y1 - gap;\n            Rect::new(self.x0, y0, self.x1, y1)\n        }\n    }\n\n    /// Is this rectangle finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.x0.is_finite() && self.x1.is_finite() && self.y0.is_finite() && self.y1.is_finite()\n    }\n\n    /// Is this rectangle NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.x0.is_nan() || self.y0.is_nan() || self.x1.is_nan() || self.y1.is_nan()\n    }\n}\n\nimpl From<(Point, Point)> for Rect {\n    fn from(points: (Point, Point)) -> Rect {\n        Rect::from_points(points.0, points.1)\n    }\n}\n\nimpl From<(Point, Size)> for Rect {\n    fn from(params: (Point, Size)) -> Rect {\n        Rect::from_origin_size(params.0, params.1)\n    }\n}\n\nimpl Add<Vec2> for Rect {\n    type Output = Rect;\n\n    #[inline]\n    fn add(self, v: Vec2) -> Rect {\n        Rect::new(self.x0 + v.x, self.y0 + v.y, self.x1 + v.x, self.y1 + v.y)\n    }\n}\n\nimpl Sub<Vec2> for Rect {\n    type Output = Rect;\n\n    #[inline]\n    fn sub(self, v: Vec2) -> Rect {\n        Rect::new(self.x0 - v.x, self.y0 - v.y, self.x1 - v.x, self.y1 - v.y)\n    }\n}\n\nimpl Sub for Rect {\n    type Output = Insets;\n\n    #[inline]\n    fn sub(self, other: Rect) -> Insets {\n        let x0 = other.x0 - self.x0;\n        let y0 = other.y0 - self.y0;\n        let x1 = self.x1 - other.x1;\n        let y1 = self.y1 - other.y1;\n        Insets { x0, y0, x1, y1 }\n    }\n}\n\n#[doc(hidden)]\npub struct RectPathIter {\n    rect: Rect,\n    ix: usize,\n}\n\nimpl Shape for Rect {\n    type PathElementsIter<'iter> = RectPathIter;\n\n    fn path_elements(&self, _tolerance: f64) -> RectPathIter {\n        RectPathIter { rect: *self, ix: 0 }\n    }\n\n    // It's a bit of duplication having both this and the impl method, but\n    // removing that would require using the trait. We'll leave it for now.\n    #[inline]\n    fn area(&self) -> f64 {\n        Rect::area(self)\n    }\n\n    #[inline]\n    fn perimeter(&self, _accuracy: f64) -> f64 {\n        2.0 * (self.width().abs() + self.height().abs())\n    }\n\n    /// Note: this function is carefully designed so that if the plane is\n    /// tiled with rectangles, the winding number will be nonzero for exactly\n    /// one of them.\n    #[inline]\n    fn winding(&self, pt: Point) -> i32 {\n        let xmin = self.x0.min(self.x1);\n        let xmax = self.x0.max(self.x1);\n        let ymin = self.y0.min(self.y1);\n        let ymax = self.y0.max(self.y1);\n        if pt.x >= xmin && pt.x < xmax && pt.y >= ymin && pt.y < ymax {\n            if (self.x1 > self.x0) ^ (self.y1 > self.y0) {\n                -1\n            } else {\n                1\n            }\n        } else {\n            0\n        }\n    }\n\n    #[inline]\n    fn bounding_box(&self) -> Rect {\n        self.abs()\n    }\n\n    #[inline]\n    fn as_rect(&self) -> Option<Rect> {\n        Some(*self)\n    }\n\n    #[inline]\n    fn contains(&self, pt: Point) -> bool {\n        self.contains(pt)\n    }\n}\n\n// This is clockwise in a y-down coordinate system for positive area.\nimpl Iterator for RectPathIter {\n    type Item = PathEl;\n\n    fn next(&mut self) -> Option<PathEl> {\n        self.ix += 1;\n        match self.ix {\n            1 => Some(PathEl::MoveTo(Point::new(self.rect.x0, self.rect.y0))),\n            2 => Some(PathEl::LineTo(Point::new(self.rect.x1, self.rect.y0))),\n            3 => Some(PathEl::LineTo(Point::new(self.rect.x1, self.rect.y1))),\n            4 => Some(PathEl::LineTo(Point::new(self.rect.x0, self.rect.y1))),\n            5 => Some(PathEl::ClosePath),\n            _ => None,\n        }\n    }\n}\n\nimpl fmt::Debug for Rect {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        if f.alternate() {\n            write!(\n                f,\n                \"Rect {{ origin: {:?}, size: {:?} }}\",\n                self.origin(),\n                self.size()\n            )\n        } else {\n            write!(\n                f,\n                \"Rect {{ x0: {:?}, y0: {:?}, x1: {:?}, y1: {:?} }}\",\n                self.x0, self.y0, self.x1, self.y1\n            )\n        }\n    }\n}\n\nimpl fmt::Display for Rect {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"Rect {{ \")?;\n        fmt::Display::fmt(&self.origin(), f)?;\n        write!(f, \" \")?;\n        fmt::Display::fmt(&self.size(), f)?;\n        write!(f, \" }}\")\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Point, Rect, Shape};\n\n    fn assert_approx_eq(x: f64, y: f64) {\n        assert!((x - y).abs() < 1e-7);\n    }\n\n    #[test]\n    fn area_sign() {\n        let r = Rect::new(0.0, 0.0, 10.0, 10.0);\n        let center = r.center();\n        assert_approx_eq(r.area(), 100.0);\n\n        assert_eq!(r.winding(center), 1);\n\n        let p = r.to_path(1e-9);\n        assert_approx_eq(r.area(), p.area());\n        assert_eq!(r.winding(center), p.winding(center));\n\n        let r_flip = Rect::new(0.0, 10.0, 10.0, 0.0);\n        assert_approx_eq(r_flip.area(), -100.0);\n\n        assert_eq!(r_flip.winding(Point::new(5.0, 5.0)), -1);\n        let p_flip = r_flip.to_path(1e-9);\n        assert_approx_eq(r_flip.area(), p_flip.area());\n        assert_eq!(r_flip.winding(center), p_flip.winding(center));\n    }\n\n    #[test]\n    fn display() {\n        let r = Rect::from_origin_size((10., 12.23214), (22.222222222, 23.1));\n        assert_eq!(\n            format!(\"{r}\"),\n            \"Rect { (10, 12.23214) (22.222222222×23.1) }\"\n        );\n        assert_eq!(format!(\"{r:.2}\"), \"Rect { (10.00, 12.23) (22.22×23.10) }\");\n    }\n\n    /* TODO uncomment when a (possibly approximate) equality test has been decided on\n    #[test]\n    fn rect_from_center_size() {\n        assert_eq!(\n            Rect::from_center_size(Point::new(3.0, 2.0), Size::new(2.0, 4.0)),\n            Rect::new(2.0, 0.0, 4.0, 4.0)\n        );\n    }\n    */\n\n    #[test]\n    fn contained_rect_with_aspect_ratio() {\n        fn case(outer: [f64; 4], aspect_ratio: f64, expected: [f64; 4]) {\n            let outer = Rect::new(outer[0], outer[1], outer[2], outer[3]);\n            let expected = Rect::new(expected[0], expected[1], expected[2], expected[3]);\n            assert_eq!(\n                outer.contained_rect_with_aspect_ratio(aspect_ratio),\n                expected\n            );\n        }\n        // squares (different point orderings)\n        case([0.0, 0.0, 10.0, 20.0], 1.0, [0.0, 5.0, 10.0, 15.0]);\n        case([0.0, 20.0, 10.0, 0.0], 1.0, [0.0, 5.0, 10.0, 15.0]);\n        case([10.0, 0.0, 0.0, 20.0], 1.0, [10.0, 15.0, 0.0, 5.0]);\n        case([10.0, 20.0, 0.0, 0.0], 1.0, [10.0, 15.0, 0.0, 5.0]);\n        // non-square\n        case([0.0, 0.0, 10.0, 20.0], 0.5, [0.0, 7.5, 10.0, 12.5]);\n        // same aspect ratio\n        case([0.0, 0.0, 10.0, 20.0], 2.0, [0.0, 0.0, 10.0, 20.0]);\n        // negative aspect ratio\n        case([0.0, 0.0, 10.0, 20.0], -1.0, [0.0, 15.0, 10.0, 5.0]);\n        // infinite aspect ratio\n        case([0.0, 0.0, 10.0, 20.0], f64::INFINITY, [5.0, 0.0, 5.0, 20.0]);\n        // zero aspect ratio\n        case([0.0, 0.0, 10.0, 20.0], 0.0, [0.0, 10.0, 10.0, 10.0]);\n        // zero width rect\n        case([0.0, 0.0, 0.0, 20.0], 1.0, [0.0, 10.0, 0.0, 10.0]);\n        // many zeros\n        case([0.0, 0.0, 0.0, 20.0], 0.0, [0.0, 10.0, 0.0, 10.0]);\n        // everything zero\n        case([0.0, 0.0, 0.0, 0.0], 0.0, [0.0, 0.0, 0.0, 0.0]);\n    }\n\n    #[test]\n    fn aspect_ratio() {\n        let test = Rect::new(0.0, 0.0, 1.0, 1.0);\n        assert!((test.aspect_ratio() - 1.0).abs() < 1e-6);\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/rounded_rect.rs",
      "sha256": "33f2a8ff36d011546680eb25d1b596de53afb01d9ff81a17966d225f0cdf71da",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A rectangle with rounded corners.\n\nuse core::f64::consts::{FRAC_PI_2, FRAC_PI_4};\nuse core::ops::{Add, Sub};\n\nuse crate::{arc::ArcAppendIter, Arc, PathEl, Point, Rect, RoundedRectRadii, Shape, Size, Vec2};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A rectangle with equally rounded corners.\n///\n/// By construction the rounded rectangle will have\n/// non-negative dimensions and radii clamped to half size of the rect.\n///\n/// The easiest way to create a `RoundedRect` is often to create a [`Rect`],\n/// and then call [`to_rounded_rect`].\n///\n/// ```\n/// use kurbo::{RoundedRect, RoundedRectRadii};\n///\n/// // Create a rounded rectangle with a single radius for all corners:\n/// RoundedRect::new(0.0, 0.0, 10.0, 10.0, 5.0);\n///\n/// // Or, specify different radii for each corner, clockwise from the top-left:\n/// RoundedRect::new(0.0, 0.0, 10.0, 10.0, (1.0, 2.0, 3.0, 4.0));\n/// ```\n///\n/// [`to_rounded_rect`]: Rect::to_rounded_rect\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct RoundedRect {\n    /// Coordinates of the rectangle.\n    rect: Rect,\n    /// Radius of all four corners.\n    radii: RoundedRectRadii,\n}\n\nimpl RoundedRect {\n    /// A new rectangle from minimum and maximum coordinates.\n    ///\n    /// The result will have non-negative width, height and radii.\n    #[inline]\n    pub fn new(\n        x0: f64,\n        y0: f64,\n        x1: f64,\n        y1: f64,\n        radii: impl Into<RoundedRectRadii>,\n    ) -> RoundedRect {\n        RoundedRect::from_rect(Rect::new(x0, y0, x1, y1), radii)\n    }\n\n    /// A new rounded rectangle from a rectangle and corner radii.\n    ///\n    /// The result will have non-negative width, height and radii.\n    ///\n    /// See also [`Rect::to_rounded_rect`], which offers the same utility.\n    #[inline]\n    pub fn from_rect(rect: Rect, radii: impl Into<RoundedRectRadii>) -> RoundedRect {\n        let rect = rect.abs();\n        let shortest_side_length = (rect.width()).min(rect.height());\n        let radii = radii.into().abs().clamp(shortest_side_length / 2.0);\n\n        RoundedRect { rect, radii }\n    }\n\n    /// A new rectangle from two [`Point`]s.\n    ///\n    /// The result will have non-negative width, height and radius.\n    #[inline]\n    pub fn from_points(\n        p0: impl Into<Point>,\n        p1: impl Into<Point>,\n        radii: impl Into<RoundedRectRadii>,\n    ) -> RoundedRect {\n        Rect::from_points(p0, p1).to_rounded_rect(radii)\n    }\n\n    /// A new rectangle from origin and size.\n    ///\n    /// The result will have non-negative width, height and radius.\n    #[inline]\n    pub fn from_origin_size(\n        origin: impl Into<Point>,\n        size: impl Into<Size>,\n        radii: impl Into<RoundedRectRadii>,\n    ) -> RoundedRect {\n        Rect::from_origin_size(origin, size).to_rounded_rect(radii)\n    }\n\n    /// The width of the rectangle.\n    #[inline]\n    pub fn width(&self) -> f64 {\n        self.rect.width()\n    }\n\n    /// The height of the rectangle.\n    #[inline]\n    pub fn height(&self) -> f64 {\n        self.rect.height()\n    }\n\n    /// Radii of the rounded corners.\n    #[inline]\n    pub fn radii(&self) -> RoundedRectRadii {\n        self.radii\n    }\n\n    /// The (non-rounded) rectangle.\n    pub fn rect(&self) -> Rect {\n        self.rect\n    }\n\n    /// The origin of the rectangle.\n    ///\n    /// This is the top left corner in a y-down space.\n    #[inline]\n    pub fn origin(&self) -> Point {\n        self.rect.origin()\n    }\n\n    /// The center point of the rectangle.\n    #[inline]\n    pub fn center(&self) -> Point {\n        self.rect.center()\n    }\n\n    /// Is this rounded rectangle finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.rect.is_finite() && self.radii.is_finite()\n    }\n\n    /// Is this rounded rectangle NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.rect.is_nan() || self.radii.is_nan()\n    }\n}\n\n#[doc(hidden)]\npub struct RoundedRectPathIter {\n    idx: usize,\n    rect: RectPathIter,\n    arcs: [ArcAppendIter; 4],\n}\n\nimpl Shape for RoundedRect {\n    type PathElementsIter<'iter> = RoundedRectPathIter;\n\n    fn path_elements(&self, tolerance: f64) -> RoundedRectPathIter {\n        let radii = self.radii();\n\n        let build_arc_iter = |i, center, ellipse_radii| {\n            let arc = Arc {\n                center,\n                radii: ellipse_radii,\n                start_angle: FRAC_PI_2 * i as f64,\n                sweep_angle: FRAC_PI_2,\n                x_rotation: 0.0,\n            };\n            arc.append_iter(tolerance)\n        };\n\n        // Note: order follows the rectangle path iterator.\n        let arcs = [\n            build_arc_iter(\n                2,\n                Point {\n                    x: self.rect.x0 + radii.top_left,\n                    y: self.rect.y0 + radii.top_left,\n                },\n                Vec2 {\n                    x: radii.top_left,\n                    y: radii.top_left,\n                },\n            ),\n            build_arc_iter(\n                3,\n                Point {\n                    x: self.rect.x1 - radii.top_right,\n                    y: self.rect.y0 + radii.top_right,\n                },\n                Vec2 {\n                    x: radii.top_right,\n                    y: radii.top_right,\n                },\n            ),\n            build_arc_iter(\n                0,\n                Point {\n                    x: self.rect.x1 - radii.bottom_right,\n                    y: self.rect.y1 - radii.bottom_right,\n                },\n                Vec2 {\n                    x: radii.bottom_right,\n                    y: radii.bottom_right,\n                },\n            ),\n            build_arc_iter(\n                1,\n                Point {\n                    x: self.rect.x0 + radii.bottom_left,\n                    y: self.rect.y1 - radii.bottom_left,\n                },\n                Vec2 {\n                    x: radii.bottom_left,\n                    y: radii.bottom_left,\n                },\n            ),\n        ];\n\n        let rect = RectPathIter {\n            rect: self.rect,\n            ix: 0,\n            radii,\n        };\n\n        RoundedRectPathIter { idx: 0, rect, arcs }\n    }\n\n    #[inline]\n    fn area(&self) -> f64 {\n        // A corner is a quarter-circle, i.e.\n        // .............#\n        // .       ######\n        // .    #########\n        // .  ###########\n        // . ############\n        // .#############\n        // ##############\n        // |-----r------|\n        // For each corner, we need to subtract the square that bounds this\n        // quarter-circle, and add back in the area of quarter circle.\n\n        let radii = self.radii();\n\n        // Start with the area of the bounding rectangle. For each corner,\n        // subtract the area of the corner under the quarter-circle, and add\n        // back the area of the quarter-circle.\n        self.rect.area()\n            + [\n                radii.top_left,\n                radii.top_right,\n                radii.bottom_right,\n                radii.bottom_left,\n            ]\n            .iter()\n            .map(|radius| (FRAC_PI_4 - 1.0) * radius * radius)\n            .sum::<f64>()\n    }\n\n    #[inline]\n    fn perimeter(&self, _accuracy: f64) -> f64 {\n        // A corner is a quarter-circle, i.e.\n        // .............#\n        // .       #\n        // .    #\n        // .  #\n        // . #\n        // .#\n        // #\n        // |-----r------|\n        // If we start with the bounding rectangle, then subtract 2r (the\n        // straight edge outside the circle) and add 1/4 * pi * (2r) (the\n        // perimeter of the quarter-circle) for each corner with radius r, we\n        // get the perimeter of the shape.\n\n        let radii = self.radii();\n\n        // Start with the full perimeter. For each corner, subtract the\n        // border surrounding the rounded corner and add the quarter-circle\n        // perimeter.\n        self.rect.perimeter(1.0)\n            + ([\n                radii.top_left,\n                radii.top_right,\n                radii.bottom_right,\n                radii.bottom_left,\n            ])\n            .iter()\n            .map(|radius| (-2.0 + FRAC_PI_2) * radius)\n            .sum::<f64>()\n    }\n\n    #[inline]\n    fn winding(&self, mut pt: Point) -> i32 {\n        let center = self.center();\n\n        // 1. Translate the point relative to the center of the rectangle.\n        pt.x -= center.x;\n        pt.y -= center.y;\n\n        // 2. Pick a radius value to use based on which quadrant the point is\n        //    in.\n        let radii = self.radii();\n        let radius = match pt {\n            pt if pt.x < 0.0 && pt.y < 0.0 => radii.top_left,\n            pt if pt.x >= 0.0 && pt.y < 0.0 => radii.top_right,\n            pt if pt.x >= 0.0 && pt.y >= 0.0 => radii.bottom_right,\n            pt if pt.x < 0.0 && pt.y >= 0.0 => radii.bottom_left,\n            _ => 0.0,\n        };\n\n        // 3. This is the width and height of a rectangle with one corner at\n        //    the center of the rounded rectangle, and another corner at the\n        //    center of the relevant corner circle.\n        let inside_half_width = (self.width() / 2.0 - radius).max(0.0);\n        let inside_half_height = (self.height() / 2.0 - radius).max(0.0);\n\n        // 4. Three things are happening here.\n        //\n        //    First, the x- and y-values are being reflected into the positive\n        //    (bottom-right quadrant). The radius has already been determined,\n        //    so it doesn't matter what quadrant is used.\n        //\n        //    After reflecting, the points are clamped so that their x- and y-\n        //    values can't be lower than the x- and y- values of the center of\n        //    the corner circle, and the coordinate system is transformed\n        //    again, putting (0, 0) at the center of the corner circle.\n        let px = (pt.x.abs() - inside_half_width).max(0.0);\n        let py = (pt.y.abs() - inside_half_height).max(0.0);\n\n        // 5. The transforms above clamp all input points such that they will\n        //    be inside the rounded rectangle if the corresponding output point\n        //    (px, py) is inside a circle centered around the origin with the\n        //    given radius.\n        let inside = px * px + py * py <= radius * radius;\n        if inside {\n            1\n        } else {\n            0\n        }\n    }\n\n    #[inline]\n    fn bounding_box(&self) -> Rect {\n        self.rect.bounding_box()\n    }\n\n    #[inline]\n    fn as_rounded_rect(&self) -> Option<RoundedRect> {\n        Some(*self)\n    }\n}\n\nstruct RectPathIter {\n    rect: Rect,\n    radii: RoundedRectRadii,\n    ix: usize,\n}\n\n// This is clockwise in a y-down coordinate system for positive area.\nimpl Iterator for RectPathIter {\n    type Item = PathEl;\n\n    fn next(&mut self) -> Option<PathEl> {\n        self.ix += 1;\n        match self.ix {\n            1 => Some(PathEl::MoveTo(Point::new(\n                self.rect.x0,\n                self.rect.y0 + self.radii.top_left,\n            ))),\n            2 => Some(PathEl::LineTo(Point::new(\n                self.rect.x1 - self.radii.top_right,\n                self.rect.y0,\n            ))),\n            3 => Some(PathEl::LineTo(Point::new(\n                self.rect.x1,\n                self.rect.y1 - self.radii.bottom_right,\n            ))),\n            4 => Some(PathEl::LineTo(Point::new(\n                self.rect.x0 + self.radii.bottom_left,\n                self.rect.y1,\n            ))),\n            5 => Some(PathEl::ClosePath),\n            _ => None,\n        }\n    }\n}\n\n// This is clockwise in a y-down coordinate system for positive area.\nimpl Iterator for RoundedRectPathIter {\n    type Item = PathEl;\n\n    fn next(&mut self) -> Option<PathEl> {\n        if self.idx > 4 {\n            return None;\n        }\n\n        // Iterate between rectangle and arc iterators.\n        // Rect iterator will start and end the path.\n\n        // Initial point set by the rect iterator\n        if self.idx == 0 {\n            self.idx += 1;\n            return self.rect.next();\n        }\n\n        // Generate the arc curve elements.\n        // If we reached the end of the arc, add a line towards next arc (rect iterator).\n        match self.arcs[self.idx - 1].next() {\n            Some(elem) => Some(elem),\n            None => {\n                self.idx += 1;\n                self.rect.next()\n            }\n        }\n    }\n}\n\nimpl Add<Vec2> for RoundedRect {\n    type Output = RoundedRect;\n\n    #[inline]\n    fn add(self, v: Vec2) -> RoundedRect {\n        RoundedRect::from_rect(self.rect + v, self.radii)\n    }\n}\n\nimpl Sub<Vec2> for RoundedRect {\n    type Output = RoundedRect;\n\n    #[inline]\n    fn sub(self, v: Vec2) -> RoundedRect {\n        RoundedRect::from_rect(self.rect - v, self.radii)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Circle, Point, Rect, RoundedRect, Shape};\n\n    #[test]\n    fn area() {\n        let epsilon = 1e-9;\n\n        // Extremum: 0.0 radius corner -> rectangle\n        let rect = Rect::new(0.0, 0.0, 100.0, 100.0);\n        let rounded_rect = RoundedRect::new(0.0, 0.0, 100.0, 100.0, 0.0);\n        assert!((rect.area() - rounded_rect.area()).abs() < epsilon);\n\n        // Extremum: half-size radius corner -> circle\n        let circle = Circle::new((0.0, 0.0), 50.0);\n        let rounded_rect = RoundedRect::new(0.0, 0.0, 100.0, 100.0, 50.0);\n        assert!((circle.area() - rounded_rect.area()).abs() < epsilon);\n    }\n\n    #[test]\n    fn winding() {\n        let rect = RoundedRect::new(-5.0, -5.0, 10.0, 20.0, (5.0, 5.0, 5.0, 0.0));\n        assert_eq!(rect.winding(Point::new(0.0, 0.0)), 1);\n        assert_eq!(rect.winding(Point::new(-5.0, 0.0)), 1); // left edge\n        assert_eq!(rect.winding(Point::new(0.0, 20.0)), 1); // bottom edge\n        assert_eq!(rect.winding(Point::new(10.0, 20.0)), 0); // bottom-right corner\n        assert_eq!(rect.winding(Point::new(-5.0, 20.0)), 1); // bottom-left corner (has a radius of 0)\n        assert_eq!(rect.winding(Point::new(-10.0, 0.0)), 0);\n\n        let rect = RoundedRect::new(-10.0, -20.0, 10.0, 20.0, 0.0); // rectangle\n        assert_eq!(rect.winding(Point::new(10.0, 20.0)), 1); // bottom-right corner\n    }\n\n    #[test]\n    fn bez_conversion() {\n        let rect = RoundedRect::new(-5.0, -5.0, 10.0, 20.0, 5.0);\n        let p = rect.to_path(1e-9);\n        // Note: could be more systematic about tolerance tightness.\n        let epsilon = 1e-7;\n        assert!((rect.area() - p.area()).abs() < epsilon);\n        assert_eq!(p.winding(Point::new(0.0, 0.0)), 1);\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/rounded_rect_radii.rs",
      "sha256": "649cd2f42d454e8c159626285730210ddc6a457b6ea78dcb4d299fbd8d897830",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2021 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A description of the radii for each corner of a rounded rectangle.\n\nuse core::convert::From;\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// Radii for each corner of a rounded rectangle.\n///\n/// The use of `top` as in `top_left` assumes a y-down coordinate space. Piet\n/// (and Druid by extension) uses a y-down coordinate space, but Kurbo also\n/// supports a y-up coordinate space, in which case `top_left` would actually\n/// refer to the bottom-left corner, and vice versa. Top may not always\n/// actually be the top, but `top` corners will always have a smaller y-value\n/// than `bottom` corners.\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct RoundedRectRadii {\n    /// The radius of the top-left corner.\n    pub top_left: f64,\n    /// The radius of the top-right corner.\n    pub top_right: f64,\n    /// The radius of the bottom-right corner.\n    pub bottom_right: f64,\n    /// The radius of the bottom-left corner.\n    pub bottom_left: f64,\n}\n\nimpl RoundedRectRadii {\n    /// Create a new `RoundedRectRadii`. This function takes radius values for\n    /// the four corners. The argument order is `top_left`, `top_right`,\n    /// `bottom_right`, `bottom_left`, or clockwise starting from `top_left`.\n    pub const fn new(top_left: f64, top_right: f64, bottom_right: f64, bottom_left: f64) -> Self {\n        RoundedRectRadii {\n            top_left,\n            top_right,\n            bottom_right,\n            bottom_left,\n        }\n    }\n\n    /// Create a new `RoundedRectRadii` from a single radius. The `radius`\n    /// argument will be set as the radius for all four corners.\n    pub const fn from_single_radius(radius: f64) -> Self {\n        RoundedRectRadii {\n            top_left: radius,\n            top_right: radius,\n            bottom_right: radius,\n            bottom_left: radius,\n        }\n    }\n\n    /// Takes the absolute value of all corner radii.\n    pub fn abs(&self) -> Self {\n        RoundedRectRadii::new(\n            self.top_left.abs(),\n            self.top_right.abs(),\n            self.bottom_right.abs(),\n            self.bottom_left.abs(),\n        )\n    }\n\n    /// For each corner, takes the min of that corner's radius and `max`.\n    pub fn clamp(&self, max: f64) -> Self {\n        RoundedRectRadii::new(\n            self.top_left.min(max),\n            self.top_right.min(max),\n            self.bottom_right.min(max),\n            self.bottom_left.min(max),\n        )\n    }\n\n    /// Returns `true` if all radius values are finite.\n    pub fn is_finite(&self) -> bool {\n        self.top_left.is_finite()\n            && self.top_right.is_finite()\n            && self.bottom_right.is_finite()\n            && self.bottom_left.is_finite()\n    }\n\n    /// Returns `true` if any corner radius value is NaN.\n    pub fn is_nan(&self) -> bool {\n        self.top_left.is_nan()\n            || self.top_right.is_nan()\n            || self.bottom_right.is_nan()\n            || self.bottom_left.is_nan()\n    }\n\n    /// If all radii are equal, returns the value of the radii. Otherwise,\n    /// returns `None`.\n    pub fn as_single_radius(&self) -> Option<f64> {\n        let epsilon = 1e-9;\n\n        if (self.top_left - self.top_right).abs() < epsilon\n            && (self.top_right - self.bottom_right).abs() < epsilon\n            && (self.bottom_right - self.bottom_left).abs() < epsilon\n        {\n            Some(self.top_left)\n        } else {\n            None\n        }\n    }\n}\n\nimpl From<f64> for RoundedRectRadii {\n    fn from(radius: f64) -> Self {\n        RoundedRectRadii::from_single_radius(radius)\n    }\n}\n\nimpl From<(f64, f64, f64, f64)> for RoundedRectRadii {\n    fn from(radii: (f64, f64, f64, f64)) -> Self {\n        RoundedRectRadii::new(radii.0, radii.1, radii.2, radii.3)\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/shape.rs",
      "sha256": "c94af4bbeea5a3df2f54198754919b211b512773e8c5bdcf0003c80036dc5d9e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A generic trait for shapes.\n\nuse crate::{segments, BezPath, Circle, Line, PathEl, Point, Rect, RoundedRect, Segments};\n\n/// A generic trait for open and closed shapes.\n///\n/// This trait provides conversion from shapes to [`BezPath`]s, as well as\n/// general geometry functionality like computing [`area`], [`bounding_box`]es,\n/// and [`winding`] number.\n///\n/// [`area`]: Shape::area\n/// [`bounding_box`]: Shape::bounding_box\n/// [`winding`]: Shape::winding\npub trait Shape: Sized {\n    /// The iterator returned by the [`path_elements`] method.\n    ///\n    /// [`path_elements`]: Shape::path_elements\n    type PathElementsIter<'iter>: Iterator<Item = PathEl> + 'iter\n    where\n        Self: 'iter;\n\n    /// Returns an iterator over this shape expressed as [`PathEl`]s;\n    /// that is, as Bézier path _elements_.\n    ///\n    /// All shapes can be represented as Béziers, but in many situations\n    /// (such as when interfacing with a platform drawing API) there are more\n    /// efficient native types for specific concrete shapes. In this case,\n    /// the user should exhaust the `as_` methods ([`as_rect`], [`as_line`], etc)\n    /// before converting to a [`BezPath`], as those are likely to be more\n    /// efficient.\n    ///\n    /// In many cases, shapes are able to iterate their elements without\n    /// allocating; however creating a [`BezPath`] object always allocates.\n    /// If you need an owned [`BezPath`] you can use [`to_path`] instead.\n    ///\n    /// # Tolerance\n    ///\n    /// The `tolerance` parameter controls the accuracy of\n    /// conversion of geometric primitives to Bézier curves, as\n    /// curves such as circles cannot be represented exactly but\n    /// only approximated. For drawing as in UI elements, a value\n    /// of 0.1 is appropriate, as it is unlikely to be visible to\n    /// the eye. For scientific applications, a smaller value\n    /// might be appropriate. Note that in general the number of\n    /// cubic Bézier segments scales as `tolerance ^ (-1/6)`.\n    ///\n    /// [`as_rect`]: Shape::as_rect\n    /// [`as_line`]: Shape::as_line\n    /// [`to_path`]: Shape::to_path\n    fn path_elements(&self, tolerance: f64) -> Self::PathElementsIter<'_>;\n\n    /// Convert to a Bézier path.\n    ///\n    /// This always allocates. It is appropriate when both the source\n    /// shape and the resulting path are to be retained.\n    ///\n    /// If you only need to iterate the elements (such as to convert them to\n    /// drawing commands for a given 2D graphics API) you should prefer\n    /// [`path_elements`], which can avoid allocating where possible.\n    ///\n    /// The `tolerance` parameter is the same as for [`path_elements`].\n    ///\n    /// [`path_elements`]: Shape::path_elements\n    fn to_path(&self, tolerance: f64) -> BezPath {\n        self.path_elements(tolerance).collect()\n    }\n\n    #[deprecated(since = \"0.7.0\", note = \"Use path_elements instead\")]\n    #[doc(hidden)]\n    fn to_bez_path(&self, tolerance: f64) -> Self::PathElementsIter<'_> {\n        self.path_elements(tolerance)\n    }\n    /// Convert into a Bézier path.\n    ///\n    /// This allocates in the general case, but is zero-cost if the\n    /// shape is already a [`BezPath`].\n    ///\n    /// The `tolerance` parameter is the same as for [`path_elements()`].\n    ///\n    /// [`path_elements()`]: Shape::path_elements\n    fn into_path(self, tolerance: f64) -> BezPath {\n        self.to_path(tolerance)\n    }\n\n    #[deprecated(since = \"0.7.0\", note = \"Use into_path instead\")]\n    #[doc(hidden)]\n    fn into_bez_path(self, tolerance: f64) -> BezPath {\n        self.into_path(tolerance)\n    }\n\n    /// Returns an iterator over this shape expressed as Bézier path\n    /// _segments_ ([`PathSeg`]s).\n    ///\n    /// The allocation behaviour and `tolerance` parameter are the\n    /// same as for [`path_elements()`]\n    ///\n    /// [`PathSeg`]: crate::PathSeg\n    /// [`path_elements()`]: Shape::path_elements\n    fn path_segments(&self, tolerance: f64) -> Segments<Self::PathElementsIter<'_>> {\n        segments(self.path_elements(tolerance))\n    }\n\n    /// Signed area.\n    ///\n    /// This method only produces meaningful results with closed shapes.\n    ///\n    /// The convention for positive area is that y increases when x is\n    /// positive. Thus, it is clockwise when down is increasing y (the\n    /// usual convention for graphics), and anticlockwise when\n    /// up is increasing y (the usual convention for math).\n    fn area(&self) -> f64;\n\n    /// Total length of perimeter.\n    //FIXME: document the accuracy param\n    fn perimeter(&self, accuracy: f64) -> f64;\n\n    /// The [winding number] of a point.\n    ///\n    /// This method only produces meaningful results with closed shapes.\n    ///\n    /// The sign of the winding number is consistent with that of [`area`],\n    /// meaning it is +1 when the point is inside a positive area shape\n    /// and -1 when it is inside a negative area shape. Of course, greater\n    /// magnitude values are also possible when the shape is more complex.\n    ///\n    /// [`area`]: Shape::area\n    /// [winding number]: https://mathworld.wolfram.com/ContourWindingNumber.html\n    fn winding(&self, pt: Point) -> i32;\n\n    /// Returns `true` if the [`Point`] is inside this shape.\n    ///\n    /// This is only meaningful for closed shapes.\n    fn contains(&self, pt: Point) -> bool {\n        self.winding(pt) != 0\n    }\n\n    /// The smallest rectangle that encloses the shape.\n    fn bounding_box(&self) -> Rect;\n\n    /// If the shape is a line, make it available.\n    fn as_line(&self) -> Option<Line> {\n        None\n    }\n\n    /// If the shape is a rectangle, make it available.\n    fn as_rect(&self) -> Option<Rect> {\n        None\n    }\n\n    /// If the shape is a rounded rectangle, make it available.\n    fn as_rounded_rect(&self) -> Option<RoundedRect> {\n        None\n    }\n\n    /// If the shape is a circle, make it available.\n    fn as_circle(&self) -> Option<Circle> {\n        None\n    }\n\n    /// If the shape is stored as a slice of path elements, make\n    /// that available.\n    ///\n    /// Note: when GAT's land, a method like `path_elements` would be\n    /// able to iterate through the slice with no extra allocation,\n    /// without making any assumption that storage is contiguous.\n    fn as_path_slice(&self) -> Option<&[PathEl]> {\n        None\n    }\n}\n\n/// Blanket implementation so `impl Shape` will accept owned or reference.\nimpl<'a, T: Shape> Shape for &'a T {\n    type PathElementsIter<'iter>\n\n    = T::PathElementsIter<'iter> where T: 'iter, 'a: 'iter;\n\n    fn path_elements(&self, tolerance: f64) -> Self::PathElementsIter<'_> {\n        (*self).path_elements(tolerance)\n    }\n\n    fn to_path(&self, tolerance: f64) -> BezPath {\n        (*self).to_path(tolerance)\n    }\n\n    fn path_segments(&self, tolerance: f64) -> Segments<Self::PathElementsIter<'_>> {\n        (*self).path_segments(tolerance)\n    }\n\n    fn area(&self) -> f64 {\n        (*self).area()\n    }\n\n    fn perimeter(&self, accuracy: f64) -> f64 {\n        (*self).perimeter(accuracy)\n    }\n\n    fn winding(&self, pt: Point) -> i32 {\n        (*self).winding(pt)\n    }\n\n    fn bounding_box(&self) -> Rect {\n        (*self).bounding_box()\n    }\n\n    fn as_line(&self) -> Option<Line> {\n        (*self).as_line()\n    }\n\n    fn as_rect(&self) -> Option<Rect> {\n        (*self).as_rect()\n    }\n\n    fn as_rounded_rect(&self) -> Option<RoundedRect> {\n        (*self).as_rounded_rect()\n    }\n\n    fn as_circle(&self) -> Option<Circle> {\n        (*self).as_circle()\n    }\n\n    fn as_path_slice(&self) -> Option<&[PathEl]> {\n        (*self).as_path_slice()\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/simplify.rs",
      "sha256": "0de5659f1102dd22ff312e7ba1cefa5e1e9fc030df71ff619ca5c4ec94282cd1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2022 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Simplification of a Bézier path.\n//!\n//! This module is currently experimental.\n//!\n//! The methods in this module create a `SimplifyBezPath` object, which can then\n//! be fed to [`fit_to_bezpath`] or [`fit_to_bezpath_opt`] depending on the degree\n//! of optimization desired.\n//!\n//! The implementation uses a number of techniques to achieve high performance and\n//! accuracy. The parameter (generally written `t`) evenly divides the curve segments\n//! in the original, so sampling can be done in constant time. The derivatives are\n//! computed analytically, as that is straightforward with Béziers.\n//!\n//! The areas and moments are computed analytically (using Green's theorem), and\n//! the prefix sum is stored. Thus, it is possible to analytically compute the area\n//! and moment of any subdivision of the curve, also in constant time, by taking\n//! the difference of two stored prefix sum values, then fixing up the subsegments.\n//!\n//! A current limitation (hoped to be addressed in the future) is that non-regular\n//! cubic segments may have tangents computed incorrectly. This can easily happen,\n//! for example when setting a control point equal to an endpoint.\n//!\n//! In addition, this method does not report corners (adjoining segments where the\n//! tangents are not continuous). It is not clear whether it's best to handle such\n//! cases here, or in client code.\n//!\n//! [`fit_to_bezpath`]: crate::fit_to_bezpath\n//! [`fit_to_bezpath_opt`]: crate::fit_to_bezpath_opt\n\nuse alloc::vec::Vec;\n\nuse core::ops::Range;\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\nuse crate::{\n    fit_to_bezpath, fit_to_bezpath_opt, BezPath, CubicBez, CurveFitSample, Line, ParamCurve,\n    ParamCurveDeriv, ParamCurveFit, PathEl, PathSeg, Point, QuadBez, Vec2,\n};\n\n/// A Bézier path which has been prepared for simplification.\n///\n/// See the [module-level documentation] for a bit more discussion of the approach,\n/// and how this struct is to be used.\n///\n/// [module-level documentation]: crate::simplify\npub struct SimplifyBezPath(Vec<SimplifyCubic>);\n\nstruct SimplifyCubic {\n    c: CubicBez,\n    // The inclusive prefix sum of the moment integrals\n    moments: (f64, f64, f64),\n}\n\n/// Options for simplifying paths.\npub struct SimplifyOptions {\n    /// The tangent of the minimum angle below which the path is considered smooth.\n    angle_thresh: f64,\n    opt_level: SimplifyOptLevel,\n}\n\n/// Optimization level for simplification.\npub enum SimplifyOptLevel {\n    /// Subdivide; faster but not as optimized results.\n    Subdivide,\n    /// Optimize subdivision points.\n    Optimize,\n}\n\nimpl Default for SimplifyOptions {\n    fn default() -> Self {\n        let opt_level = SimplifyOptLevel::Subdivide;\n        SimplifyOptions {\n            angle_thresh: 1e-3,\n            opt_level,\n        }\n    }\n}\n\n#[doc(hidden)]\n/// Compute moment integrals.\n///\n/// This is exposed for testing purposes but is an internal detail. We can\n/// add to the public, documented interface if there is a use case.\npub fn moment_integrals(c: CubicBez) -> (f64, f64, f64) {\n    let (x0, y0) = (c.p0.x, c.p0.y);\n    let (x1, y1) = (c.p1.x - x0, c.p1.y - y0);\n    let (x2, y2) = (c.p2.x - x0, c.p2.y - y0);\n    let (x3, y3) = (c.p3.x - x0, c.p3.y - y0);\n\n    let r0 = 3. * x1;\n    let r1 = 3. * y1;\n    let r2 = x2 * y3;\n    let r3 = x3 * y2;\n    let r4 = x3 * y3;\n    let r5 = 27. * y1;\n    let r6 = x1 * x2;\n    let r7 = 27. * y2;\n    let r8 = 45. * r2;\n    let r9 = 18. * x3;\n    let r10 = x1 * y1;\n    let r11 = 30. * x1;\n    let r12 = 45. * x3;\n    let r13 = x2 * y1;\n    let r14 = 45. * r3;\n    let r15 = x1.powi(2);\n    let r16 = 18. * y3;\n    let r17 = x2.powi(2);\n    let r18 = 45. * y3;\n    let r19 = x3.powi(2);\n    let r20 = 30. * y1;\n    let r21 = y2.powi(2);\n    let r22 = y3.powi(2);\n    let r23 = y1.powi(2);\n    let a = -r0 * y2 - r0 * y3 + r1 * x2 + r1 * x3 - 6. * r2 + 6. * r3 + 10. * r4;\n\n    // Scale and add chord\n    let lift = x3 * y0;\n    let area = a * 0.05 + lift;\n    let x = r10 * r9 - r11 * r4 + r12 * r13 + r14 * x2 - r15 * r16 - r15 * r7 - r17 * r18\n        + r17 * r5\n        + r19 * r20\n        + 105. * r19 * y2\n        + 280. * r19 * y3\n        - 105. * r2 * x3\n        + r5 * r6\n        - r6 * r7\n        - r8 * x1;\n    let y = -r10 * r16 - r10 * r7 - r11 * r22 + r12 * r21 + r13 * r7 + r14 * y1 - r18 * x1 * y2\n        + r20 * r4\n        - 27. * r21 * x1\n        - 105. * r22 * x2\n        + 140. * r22 * x3\n        + r23 * r9\n        + 27. * r23 * x2\n        + 105. * r3 * y3\n        - r8 * y2;\n\n    let mx = x * (1. / 840.) + x0 * area + 0.5 * x3 * lift;\n    let my = y * (1. / 420.) + y0 * a * 0.1 + y0 * lift;\n\n    (area, mx, my)\n}\n\nimpl SimplifyBezPath {\n    /// Set up a new Bézier path for simplification.\n    ///\n    /// Currently this is not dealing with discontinuities at all, but it\n    /// could be extended to do so.\n    pub fn new(path: impl IntoIterator<Item = PathEl>) -> Self {\n        let (mut a, mut x, mut y) = (0.0, 0.0, 0.0);\n        let els = crate::segments(path)\n            .map(|seg| {\n                let c = seg.to_cubic();\n                let (ai, xi, yi) = moment_integrals(c);\n                a += ai;\n                x += xi;\n                y += yi;\n                SimplifyCubic {\n                    c,\n                    moments: (a, x, y),\n                }\n            })\n            .collect();\n        SimplifyBezPath(els)\n    }\n\n    /// Resolve a `t` value to a cubic.\n    ///\n    /// Also return the resulting `t` value for the selected cubic.\n    fn scale(&self, t: f64) -> (usize, f64) {\n        let t_scale = t * self.0.len() as f64;\n        let t_floor = t_scale.floor();\n        (t_floor as usize, t_scale - t_floor)\n    }\n\n    fn moment_integrals(&self, i: usize, range: Range<f64>) -> (f64, f64, f64) {\n        if range.end == range.start {\n            (0.0, 0.0, 0.0)\n        } else {\n            moment_integrals(self.0[i].c.subsegment(range))\n        }\n    }\n}\n\nimpl ParamCurveFit for SimplifyBezPath {\n    fn sample_pt_deriv(&self, t: f64) -> (Point, Vec2) {\n        let (mut i, mut t0) = self.scale(t);\n        let n = self.0.len();\n        if i == n {\n            i -= 1;\n            t0 = 1.0;\n        }\n        let c = self.0[i].c;\n        (c.eval(t0), c.deriv().eval(t0).to_vec2() * n as f64)\n    }\n\n    fn sample_pt_tangent(&self, t: f64, _: f64) -> CurveFitSample {\n        let (mut i, mut t0) = self.scale(t);\n        if i == self.0.len() {\n            i -= 1;\n            t0 = 1.0;\n        }\n        let c = self.0[i].c;\n        let p = c.eval(t0);\n        let tangent = c.deriv().eval(t0).to_vec2();\n        CurveFitSample { p, tangent }\n    }\n\n    // We could use the default implementation, but provide our own, mostly\n    // because it is possible to efficiently provide an analytically accurate\n    // answer.\n    fn moment_integrals(&self, range: Range<f64>) -> (f64, f64, f64) {\n        let (i0, t0) = self.scale(range.start);\n        let (i1, t1) = self.scale(range.end);\n        if i0 == i1 {\n            self.moment_integrals(i0, t0..t1)\n        } else {\n            let (a0, x0, y0) = self.moment_integrals(i0, t0..1.0);\n            let (a1, x1, y1) = self.moment_integrals(i1, 0.0..t1);\n            let (mut a, mut x, mut y) = (a0 + a1, x0 + x1, y0 + y1);\n            if i1 > i0 + 1 {\n                let (a2, x2, y2) = self.0[i0].moments;\n                let (a3, x3, y3) = self.0[i1 - 1].moments;\n                a += a3 - a2;\n                x += x3 - x2;\n                y += y3 - y2;\n            }\n            (a, x, y)\n        }\n    }\n\n    fn break_cusp(&self, _: Range<f64>) -> Option<f64> {\n        None\n    }\n}\n\n#[derive(Default)]\nstruct SimplifyState {\n    queue: BezPath,\n    result: BezPath,\n    needs_moveto: bool,\n}\n\nimpl SimplifyState {\n    fn add_seg(&mut self, seg: PathSeg) {\n        if self.queue.is_empty() {\n            self.queue.move_to(seg.start());\n        }\n        match seg {\n            PathSeg::Quad(q) => self.queue.quad_to(q.p1, q.p2),\n            PathSeg::Cubic(c) => self.queue.curve_to(c.p1, c.p2, c.p3),\n            _ => unreachable!(),\n        }\n    }\n\n    fn flush(&mut self, accuracy: f64, options: &SimplifyOptions) {\n        if self.queue.is_empty() {\n            return;\n        }\n        // TODO: if queue is one segment, just output that\n        let s = SimplifyBezPath::new(&self.queue);\n        let b = match options.opt_level {\n            SimplifyOptLevel::Subdivide => fit_to_bezpath(&s, accuracy),\n            SimplifyOptLevel::Optimize => fit_to_bezpath_opt(&s, accuracy),\n        };\n        self.result\n            .extend(b.iter().skip(!self.needs_moveto as usize));\n        self.needs_moveto = false;\n        self.queue.truncate(0);\n    }\n}\n\n/// Simplify a Bézier path.\n///\n/// This function simplifies an arbitrary Bézier path; it is designed to handle\n/// multiple subpaths and also corners.\npub fn simplify_bezpath(\n    path: impl IntoIterator<Item = PathEl>,\n    accuracy: f64,\n    options: &SimplifyOptions,\n) -> BezPath {\n    let mut last_pt = None;\n    let mut last_seg: Option<PathSeg> = None;\n    let mut state = SimplifyState::default();\n    for el in path {\n        let mut this_seg = None;\n        match el {\n            PathEl::MoveTo(p) => {\n                state.flush(accuracy, options);\n                state.needs_moveto = true;\n                last_pt = Some(p);\n            }\n            PathEl::LineTo(p) => {\n                let last = last_pt.unwrap();\n                if last == p {\n                    continue;\n                }\n                state.flush(accuracy, options);\n                this_seg = Some(PathSeg::Line(Line::new(last, p)));\n            }\n            PathEl::QuadTo(p1, p2) => {\n                let last = last_pt.unwrap();\n                if last == p1 && last == p2 {\n                    continue;\n                }\n                this_seg = Some(PathSeg::Quad(QuadBez::new(last, p1, p2)));\n            }\n            PathEl::CurveTo(p1, p2, p3) => {\n                let last = last_pt.unwrap();\n                if last == p1 && last == p2 && last == p3 {\n                    continue;\n                }\n                this_seg = Some(PathSeg::Cubic(CubicBez::new(last, p1, p2, p3)));\n            }\n            PathEl::ClosePath => {\n                state.flush(accuracy, options);\n                state.result.close_path();\n                state.needs_moveto = true;\n                last_seg = None;\n                continue;\n            }\n        }\n        if let Some(seg) = this_seg {\n            if let Some(last) = last_seg {\n                let last_tan = last.tangents().1;\n                let this_tan = seg.tangents().0;\n                if last_tan.cross(this_tan).abs()\n                    > last_tan.dot(this_tan).abs() * options.angle_thresh\n                {\n                    state.flush(accuracy, options);\n                }\n            }\n            last_pt = Some(seg.end());\n            state.add_seg(seg);\n        }\n        last_seg = this_seg;\n    }\n    state.flush(accuracy, options);\n    state.result\n}\n\nimpl SimplifyOptions {\n    /// Set optimization level.\n    pub fn opt_level(mut self, level: SimplifyOptLevel) -> Self {\n        self.opt_level = level;\n        self\n    }\n\n    /// Set angle threshold.\n    ///\n    /// The tangent of the angle below which joins are considered smooth and\n    /// not corners. The default is approximately 1 milliradian.\n    pub fn angle_thresh(mut self, thresh: f64) -> Self {\n        self.angle_thresh = thresh;\n        self\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/size.rs",
      "sha256": "f4a47d98e75782f200e40e968a176406b4438f67d87ae3c9256a511a0500b3e0",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A 2D size.\n\nuse core::fmt;\nuse core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};\n\nuse crate::common::FloatExt;\nuse crate::{Rect, RoundedRect, RoundedRectRadii, Vec2};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A 2D size.\n#[derive(Clone, Copy, Default, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Size {\n    /// The width.\n    pub width: f64,\n    /// The height.\n    pub height: f64,\n}\n\nimpl Size {\n    /// A size with zero width or height.\n    pub const ZERO: Size = Size::new(0., 0.);\n\n    /// Create a new `Size` with the provided `width` and `height`.\n    #[inline]\n    pub const fn new(width: f64, height: f64) -> Self {\n        Size { width, height }\n    }\n\n    /// Returns the max of `width` and `height`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Size;\n    /// let size = Size::new(-10.5, 42.0);\n    /// assert_eq!(size.max_side(), 42.0);\n    /// ```\n    pub fn max_side(self) -> f64 {\n        self.width.max(self.height)\n    }\n\n    /// Returns the min of `width` and `height`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Size;\n    /// let size = Size::new(-10.5, 42.0);\n    /// assert_eq!(size.min_side(), -10.5);\n    /// ```\n    pub fn min_side(self) -> f64 {\n        self.width.min(self.height)\n    }\n\n    /// The area covered by this size.\n    #[inline]\n    pub fn area(self) -> f64 {\n        self.width * self.height\n    }\n\n    /// Whether this size has zero area.\n    ///\n    /// Note: a size with negative area is not considered empty.\n    #[inline]\n    pub fn is_empty(self) -> bool {\n        self.area() == 0.0\n    }\n\n    /// Returns a new size bounded by `min` and `max.`\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Size;\n    ///\n    /// let this = Size::new(0., 100.);\n    /// let min = Size::new(10., 10.,);\n    /// let max = Size::new(50., 50.);\n    /// assert_eq!(this.clamp(min, max), Size::new(10., 50.))\n    /// ```\n    pub fn clamp(self, min: Size, max: Size) -> Self {\n        let width = self.width.max(min.width).min(max.width);\n        let height = self.height.max(min.height).min(max.height);\n        Size { width, height }\n    }\n\n    /// Convert this size into a [`Vec2`], with `width` mapped to `x` and `height`\n    /// mapped to `y`.\n    #[inline]\n    pub const fn to_vec2(self) -> Vec2 {\n        Vec2::new(self.width, self.height)\n    }\n\n    /// Returns a new `Size`,\n    /// with `width` and `height` rounded to the nearest integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Size;\n    /// let size_pos = Size::new(3.3, 3.6).round();\n    /// assert_eq!(size_pos.width, 3.0);\n    /// assert_eq!(size_pos.height, 4.0);\n    /// let size_neg = Size::new(-3.3, -3.6).round();\n    /// assert_eq!(size_neg.width, -3.0);\n    /// assert_eq!(size_neg.height, -4.0);\n    /// ```\n    #[inline]\n    pub fn round(self) -> Size {\n        Size::new(self.width.round(), self.height.round())\n    }\n\n    /// Returns a new `Size`,\n    /// with `width` and `height` rounded up to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Size;\n    /// let size_pos = Size::new(3.3, 3.6).ceil();\n    /// assert_eq!(size_pos.width, 4.0);\n    /// assert_eq!(size_pos.height, 4.0);\n    /// let size_neg = Size::new(-3.3, -3.6).ceil();\n    /// assert_eq!(size_neg.width, -3.0);\n    /// assert_eq!(size_neg.height, -3.0);\n    /// ```\n    #[inline]\n    pub fn ceil(self) -> Size {\n        Size::new(self.width.ceil(), self.height.ceil())\n    }\n\n    /// Returns a new `Size`,\n    /// with `width` and `height` rounded down to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Size;\n    /// let size_pos = Size::new(3.3, 3.6).floor();\n    /// assert_eq!(size_pos.width, 3.0);\n    /// assert_eq!(size_pos.height, 3.0);\n    /// let size_neg = Size::new(-3.3, -3.6).floor();\n    /// assert_eq!(size_neg.width, -4.0);\n    /// assert_eq!(size_neg.height, -4.0);\n    /// ```\n    #[inline]\n    pub fn floor(self) -> Size {\n        Size::new(self.width.floor(), self.height.floor())\n    }\n\n    /// Returns a new `Size`,\n    /// with `width` and `height` rounded away from zero to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Size;\n    /// let size_pos = Size::new(3.3, 3.6).expand();\n    /// assert_eq!(size_pos.width, 4.0);\n    /// assert_eq!(size_pos.height, 4.0);\n    /// let size_neg = Size::new(-3.3, -3.6).expand();\n    /// assert_eq!(size_neg.width, -4.0);\n    /// assert_eq!(size_neg.height, -4.0);\n    /// ```\n    #[inline]\n    pub fn expand(self) -> Size {\n        Size::new(self.width.expand(), self.height.expand())\n    }\n\n    /// Returns a new `Size`,\n    /// with `width` and `height` rounded down towards zero the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Size;\n    /// let size_pos = Size::new(3.3, 3.6).trunc();\n    /// assert_eq!(size_pos.width, 3.0);\n    /// assert_eq!(size_pos.height, 3.0);\n    /// let size_neg = Size::new(-3.3, -3.6).trunc();\n    /// assert_eq!(size_neg.width, -3.0);\n    /// assert_eq!(size_neg.height, -3.0);\n    /// ```\n    #[inline]\n    pub fn trunc(self) -> Size {\n        Size::new(self.width.trunc(), self.height.trunc())\n    }\n\n    /// Returns the aspect ratio of a rectangle with the given size.\n    ///\n    /// If the width is `0`, the output will be `sign(self.height) * infinity`. If The width and\n    /// height are `0`, then the output will be `NaN`.\n    pub fn aspect_ratio(self) -> f64 {\n        self.height / self.width\n    }\n\n    /// Convert this `Size` into a [`Rect`] with origin `(0.0, 0.0)`.\n    #[inline]\n    pub const fn to_rect(self) -> Rect {\n        Rect::new(0., 0., self.width, self.height)\n    }\n\n    /// Convert this `Size` into a [`RoundedRect`] with origin `(0.0, 0.0)` and\n    /// the provided corner radius.\n    #[inline]\n    pub fn to_rounded_rect(self, radii: impl Into<RoundedRectRadii>) -> RoundedRect {\n        self.to_rect().to_rounded_rect(radii)\n    }\n\n    /// Is this size finite?\n    #[inline]\n    pub fn is_finite(self) -> bool {\n        self.width.is_finite() && self.height.is_finite()\n    }\n\n    /// Is this size NaN?\n    #[inline]\n    pub fn is_nan(self) -> bool {\n        self.width.is_nan() || self.height.is_nan()\n    }\n}\n\nimpl fmt::Debug for Size {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"{:?}W×{:?}H\", self.width, self.height)\n    }\n}\n\nimpl fmt::Display for Size {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        write!(formatter, \"(\")?;\n        fmt::Display::fmt(&self.width, formatter)?;\n        write!(formatter, \"×\")?;\n        fmt::Display::fmt(&self.height, formatter)?;\n        write!(formatter, \")\")\n    }\n}\n\nimpl MulAssign<f64> for Size {\n    #[inline]\n    fn mul_assign(&mut self, other: f64) {\n        *self = Size {\n            width: self.width * other,\n            height: self.height * other,\n        };\n    }\n}\n\nimpl Mul<Size> for f64 {\n    type Output = Size;\n\n    #[inline]\n    fn mul(self, other: Size) -> Size {\n        other * self\n    }\n}\n\nimpl Mul<f64> for Size {\n    type Output = Size;\n\n    #[inline]\n    fn mul(self, other: f64) -> Size {\n        Size {\n            width: self.width * other,\n            height: self.height * other,\n        }\n    }\n}\n\nimpl DivAssign<f64> for Size {\n    #[inline]\n    fn div_assign(&mut self, other: f64) {\n        *self = Size {\n            width: self.width / other,\n            height: self.height / other,\n        };\n    }\n}\n\nimpl Div<f64> for Size {\n    type Output = Size;\n\n    #[inline]\n    fn div(self, other: f64) -> Size {\n        Size {\n            width: self.width / other,\n            height: self.height / other,\n        }\n    }\n}\n\nimpl Add<Size> for Size {\n    type Output = Size;\n    #[inline]\n    fn add(self, other: Size) -> Size {\n        Size {\n            width: self.width + other.width,\n            height: self.height + other.height,\n        }\n    }\n}\n\nimpl AddAssign<Size> for Size {\n    #[inline]\n    fn add_assign(&mut self, other: Size) {\n        *self = *self + other;\n    }\n}\n\nimpl Sub<Size> for Size {\n    type Output = Size;\n    #[inline]\n    fn sub(self, other: Size) -> Size {\n        Size {\n            width: self.width - other.width,\n            height: self.height - other.height,\n        }\n    }\n}\n\nimpl SubAssign<Size> for Size {\n    #[inline]\n    fn sub_assign(&mut self, other: Size) {\n        *self = *self - other;\n    }\n}\n\nimpl From<(f64, f64)> for Size {\n    #[inline]\n    fn from(v: (f64, f64)) -> Size {\n        Size {\n            width: v.0,\n            height: v.1,\n        }\n    }\n}\n\nimpl From<Size> for (f64, f64) {\n    #[inline]\n    fn from(v: Size) -> (f64, f64) {\n        (v.width, v.height)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn display() {\n        let s = Size::new(-0.12345, 9.87654);\n        assert_eq!(format!(\"{s}\"), \"(-0.12345×9.87654)\");\n\n        let s = Size::new(-0.12345, 9.87654);\n        assert_eq!(format!(\"{s:+6.2}\"), \"( -0.12× +9.88)\");\n    }\n\n    #[test]\n    fn aspect_ratio() {\n        let s = Size::new(1.0, 1.0);\n        assert!((s.aspect_ratio() - 1.0).abs() < 1e-6);\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/stroke.rs",
      "sha256": "90c99b353f122b5f745f62d54cd77b9904d8ab7c26b8545d734de05b664c4576",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2023 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse core::{borrow::Borrow, f64::consts::PI};\n\nuse alloc::vec::Vec;\n\nuse smallvec::SmallVec;\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\nuse crate::{\n    common::solve_quadratic, fit_to_bezpath, fit_to_bezpath_opt, offset::CubicOffset, Affine, Arc,\n    BezPath, CubicBez, Line, ParamCurve, ParamCurveArclen, PathEl, PathSeg, Point, QuadBez, Vec2,\n};\n\n/// Defines the connection between two segments of a stroke.\n#[derive(Copy, Clone, PartialEq, Eq, Debug)]\npub enum Join {\n    /// A straight line connecting the segments.\n    Bevel,\n    /// The segments are extended to their natural intersection point.\n    Miter,\n    /// An arc between the segments.\n    Round,\n}\n\n/// Defines the shape to be drawn at the ends of a stroke.\n#[derive(Copy, Clone, PartialEq, Eq, Debug)]\npub enum Cap {\n    /// Flat cap.\n    Butt,\n    /// Square cap with dimensions equal to half the stroke width.\n    Square,\n    /// Rounded cap with radius equal to half the stroke width.\n    Round,\n}\n\n/// Describes the visual style of a stroke.\n#[derive(Clone, Debug)]\npub struct Stroke {\n    /// Width of the stroke.\n    pub width: f64,\n    /// Style for connecting segments of the stroke.\n    pub join: Join,\n    /// Limit for miter joins.\n    pub miter_limit: f64,\n    /// Style for capping the beginning of an open subpath.\n    pub start_cap: Cap,\n    /// Style for capping the end of an open subpath.\n    pub end_cap: Cap,\n    /// Lengths of dashes in alternating on/off order.\n    pub dash_pattern: Dashes,\n    /// Offset of the first dash.\n    pub dash_offset: f64,\n}\n\n/// Options for path stroking.\npub struct StrokeOpts {\n    opt_level: StrokeOptLevel,\n}\n\n/// Optimization level for computing\npub enum StrokeOptLevel {\n    /// Adaptively subdivide segments in half.\n    Subdivide,\n    /// Compute optimized subdivision points to minimize error.\n    Optimized,\n}\n\nimpl Default for StrokeOpts {\n    fn default() -> Self {\n        let opt_level = StrokeOptLevel::Subdivide;\n        StrokeOpts { opt_level }\n    }\n}\n\nimpl Default for Stroke {\n    fn default() -> Self {\n        Self {\n            width: 1.0,\n            join: Join::Round,\n            miter_limit: 4.0,\n            start_cap: Cap::Round,\n            end_cap: Cap::Round,\n            dash_pattern: Default::default(),\n            dash_offset: 0.0,\n        }\n    }\n}\n\nimpl Stroke {\n    /// Creates a new stroke with the specified width.\n    pub fn new(width: f64) -> Self {\n        Self {\n            width,\n            ..Default::default()\n        }\n    }\n\n    /// Builder method for setting the join style.\n    pub fn with_join(mut self, join: Join) -> Self {\n        self.join = join;\n        self\n    }\n\n    /// Builder method for setting the limit for miter joins.\n    pub fn with_miter_limit(mut self, limit: f64) -> Self {\n        self.miter_limit = limit;\n        self\n    }\n\n    /// Builder method for setting the cap style for the start of the stroke.\n    pub fn with_start_cap(mut self, cap: Cap) -> Self {\n        self.start_cap = cap;\n        self\n    }\n\n    /// Builder method for setting the cap style for the end of the stroke.\n    pub fn with_end_cap(mut self, cap: Cap) -> Self {\n        self.end_cap = cap;\n        self\n    }\n\n    /// Builder method for setting the cap style.\n    pub fn with_caps(mut self, cap: Cap) -> Self {\n        self.start_cap = cap;\n        self.end_cap = cap;\n        self\n    }\n\n    /// Builder method for setting the dashing parameters.\n    pub fn with_dashes<P>(mut self, offset: f64, pattern: P) -> Self\n    where\n        P: IntoIterator,\n        P::Item: Borrow<f64>,\n    {\n        self.dash_offset = offset;\n        self.dash_pattern.clear();\n        self.dash_pattern\n            .extend(pattern.into_iter().map(|dash| *dash.borrow()));\n        self\n    }\n}\n\nimpl StrokeOpts {\n    /// Set optimization level for computing stroke outlines.\n    pub fn opt_level(mut self, opt_level: StrokeOptLevel) -> Self {\n        self.opt_level = opt_level;\n        self\n    }\n}\n\n/// Collection of values representing lengths in a dash pattern.\npub type Dashes = SmallVec<[f64; 4]>;\n\n/// Internal structure used for creating strokes.\n#[derive(Default)]\nstruct StrokeCtx {\n    // As a possible future optimization, we might not need separate storage\n    // for forward and backward paths, we can add forward to the output in-place.\n    // However, this structure is clearer and the cost fairly modest.\n    output: BezPath,\n    forward_path: BezPath,\n    backward_path: BezPath,\n    start_pt: Point,\n    start_norm: Vec2,\n    start_tan: Vec2,\n    last_pt: Point,\n    last_tan: Vec2,\n    // Precomputation of the join threshold, to optimize per-join logic.\n    // If hypot < (hypot + dot) * join_thresh, omit join altogether.\n    join_thresh: f64,\n}\n\n/// Expand a stroke into a fill.\n///\n/// The `tolerance` parameter controls the accuracy of the result. In general,\n/// the number of subdivisions in the output scales to the -1/6 power of the\n/// parameter, for example making it 1/64 as big generates twice as many\n/// segments. The appropriate value depends on the application; if the result\n/// of the stroke will be scaled up, a smaller value is needed.\n///\n/// This method attempts a fairly high degree of correctness, but ultimately\n/// is based on computing parallel curves and adding joins and caps, rather than\n/// computing the rigorously correct parallel sweep (which requires evolutes in\n/// the general case). See [Nehab 2020] for more discussion.\n///\n/// [Nehab 2020]: https://dl.acm.org/doi/10.1145/3386569.3392392\npub fn stroke(\n    path: impl IntoIterator<Item = PathEl>,\n    style: &Stroke,\n    opts: &StrokeOpts,\n    tolerance: f64,\n) -> BezPath {\n    if style.dash_pattern.is_empty() {\n        stroke_undashed(path, style, tolerance, opts)\n    } else {\n        let dashed = dash(path.into_iter(), style.dash_offset, &style.dash_pattern);\n        stroke_undashed(dashed, style, tolerance, opts)\n    }\n}\n\n/// Version of stroke expansion for styles with no dashes.\nfn stroke_undashed(\n    path: impl IntoIterator<Item = PathEl>,\n    style: &Stroke,\n    tolerance: f64,\n    opts: &StrokeOpts,\n) -> BezPath {\n    let mut ctx = StrokeCtx {\n        join_thresh: 2.0 * tolerance / style.width,\n        ..Default::default()\n    };\n    for el in path {\n        let p0 = ctx.last_pt;\n        match el {\n            PathEl::MoveTo(p) => {\n                ctx.finish(style);\n                ctx.start_pt = p;\n                ctx.last_pt = p;\n            }\n            PathEl::LineTo(p1) => {\n                if p1 != p0 {\n                    let tangent = p1 - p0;\n                    ctx.do_join(style, tangent);\n                    ctx.last_tan = tangent;\n                    ctx.do_line(style, tangent, p1);\n                }\n            }\n            PathEl::QuadTo(p1, p2) => {\n                if p1 != p0 || p2 != p0 {\n                    let q = QuadBez::new(p0, p1, p2);\n                    let (tan0, tan1) = PathSeg::Quad(q).tangents();\n                    ctx.do_join(style, tan0);\n                    ctx.do_cubic(style, q.raise(), tolerance, opts);\n                    ctx.last_tan = tan1;\n                }\n            }\n            PathEl::CurveTo(p1, p2, p3) => {\n                if p1 != p0 || p2 != p0 || p3 != p0 {\n                    let c = CubicBez::new(p0, p1, p2, p3);\n                    let (tan0, tan1) = PathSeg::Cubic(c).tangents();\n                    ctx.do_join(style, tan0);\n                    ctx.do_cubic(style, c, tolerance, opts);\n                    ctx.last_tan = tan1;\n                }\n            }\n            PathEl::ClosePath => {\n                if p0 != ctx.start_pt {\n                    let tangent = ctx.start_pt - p0;\n                    ctx.do_join(style, tangent);\n                    ctx.last_tan = tangent;\n                    ctx.do_line(style, tangent, ctx.start_pt);\n                }\n                ctx.finish_closed(style);\n            }\n        }\n    }\n    ctx.finish(style);\n    ctx.output\n}\n\nfn round_cap(out: &mut BezPath, tolerance: f64, center: Point, norm: Vec2) {\n    round_join(out, tolerance, center, norm, PI);\n}\n\nfn round_join(out: &mut BezPath, tolerance: f64, center: Point, norm: Vec2, angle: f64) {\n    let a = Affine::new([norm.x, norm.y, -norm.y, norm.x, center.x, center.y]);\n    let arc = Arc::new(Point::ORIGIN, (1.0, 1.0), PI - angle, angle, 0.0);\n    arc.to_cubic_beziers(tolerance, |p1, p2, p3| out.curve_to(a * p1, a * p2, a * p3));\n}\n\nfn round_join_rev(out: &mut BezPath, tolerance: f64, center: Point, norm: Vec2, angle: f64) {\n    let a = Affine::new([norm.x, norm.y, norm.y, -norm.x, center.x, center.y]);\n    let arc = Arc::new(Point::ORIGIN, (1.0, 1.0), PI - angle, angle, 0.0);\n    arc.to_cubic_beziers(tolerance, |p1, p2, p3| out.curve_to(a * p1, a * p2, a * p3));\n}\n\nfn square_cap(out: &mut BezPath, close: bool, center: Point, norm: Vec2) {\n    let a = Affine::new([norm.x, norm.y, -norm.y, norm.x, center.x, center.y]);\n    out.line_to(a * Point::new(1.0, 1.0));\n    out.line_to(a * Point::new(-1.0, 1.0));\n    if close {\n        out.close_path();\n    } else {\n        out.line_to(a * Point::new(-1.0, 0.0));\n    }\n}\n\nfn extend_reversed(out: &mut BezPath, elements: &[PathEl]) {\n    for i in (1..elements.len()).rev() {\n        let end = elements[i - 1].end_point().unwrap();\n        match elements[i] {\n            PathEl::LineTo(_) => out.line_to(end),\n            PathEl::QuadTo(p1, _) => out.quad_to(p1, end),\n            PathEl::CurveTo(p1, p2, _) => out.curve_to(p2, p1, end),\n            _ => unreachable!(),\n        }\n    }\n}\n\nfn fit_with_opts(co: &CubicOffset, tolerance: f64, opts: &StrokeOpts) -> BezPath {\n    match opts.opt_level {\n        StrokeOptLevel::Subdivide => fit_to_bezpath(co, tolerance),\n        StrokeOptLevel::Optimized => fit_to_bezpath_opt(co, tolerance),\n    }\n}\n\nimpl StrokeCtx {\n    /// Append forward and backward paths to output.\n    fn finish(&mut self, style: &Stroke) {\n        // TODO: scale\n        let tolerance = 1e-3;\n        if self.forward_path.is_empty() {\n            return;\n        }\n        self.output.extend(&self.forward_path);\n        let back_els = self.backward_path.elements();\n        let return_p = back_els[back_els.len() - 1].end_point().unwrap();\n        let d = self.last_pt - return_p;\n        match style.end_cap {\n            Cap::Butt => self.output.line_to(return_p),\n            Cap::Round => round_cap(&mut self.output, tolerance, self.last_pt, d),\n            Cap::Square => square_cap(&mut self.output, false, self.last_pt, d),\n        }\n        extend_reversed(&mut self.output, back_els);\n        match style.start_cap {\n            Cap::Butt => self.output.close_path(),\n            Cap::Round => round_cap(&mut self.output, tolerance, self.start_pt, self.start_norm),\n            Cap::Square => square_cap(&mut self.output, true, self.start_pt, self.start_norm),\n        }\n\n        self.forward_path.truncate(0);\n        self.backward_path.truncate(0);\n    }\n\n    /// Finish a closed path\n    fn finish_closed(&mut self, style: &Stroke) {\n        self.do_join(style, self.start_tan);\n        self.output.extend(&self.forward_path);\n        self.output.close_path();\n        let back_els = self.backward_path.elements();\n        let last_pt = back_els[back_els.len() - 1].end_point().unwrap();\n        self.output.move_to(last_pt);\n        extend_reversed(&mut self.output, back_els);\n        self.output.close_path();\n        self.forward_path.truncate(0);\n        self.backward_path.truncate(0);\n    }\n\n    fn do_join(&mut self, style: &Stroke, tan0: Vec2) {\n        // TODO: scale\n        let tolerance = 1e-3;\n        let scale = 0.5 * style.width / tan0.hypot();\n        let norm = scale * Vec2::new(-tan0.y, tan0.x);\n        let p0 = self.last_pt;\n        if self.forward_path.elements().is_empty() {\n            self.forward_path.move_to(p0 - norm);\n            self.backward_path.move_to(p0 + norm);\n            self.start_tan = tan0;\n            self.start_norm = norm;\n        } else {\n            let ab = self.last_tan;\n            let cd = tan0;\n            let cross = ab.cross(cd);\n            let dot = ab.dot(cd);\n            let hypot = cross.hypot(dot);\n            // possible TODO: a minor speedup could be squaring both sides\n            if dot <= 0.0 || cross.abs() >= hypot * self.join_thresh {\n                match style.join {\n                    Join::Bevel => {\n                        self.forward_path.line_to(p0 - norm);\n                        self.backward_path.line_to(p0 + norm);\n                    }\n                    Join::Miter => {\n                        if 2.0 * hypot < (hypot + dot) * style.miter_limit.powi(2) {\n                            // TODO: maybe better to store last_norm or derive from path?\n                            let last_scale = 0.5 * style.width / ab.hypot();\n                            let last_norm = last_scale * Vec2::new(-ab.y, ab.x);\n                            if cross > 0.0 {\n                                let fp_last = p0 - last_norm;\n                                let fp_this = p0 - norm;\n                                let h = ab.cross(fp_this - fp_last) / cross;\n                                let miter_pt = fp_this - cd * h;\n                                self.forward_path.line_to(miter_pt);\n                            } else if cross < 0.0 {\n                                let fp_last = p0 + last_norm;\n                                let fp_this = p0 + norm;\n                                let h = ab.cross(fp_this - fp_last) / cross;\n                                let miter_pt = fp_this - cd * h;\n                                self.backward_path.line_to(miter_pt);\n                            }\n                        }\n                        self.forward_path.line_to(p0 - norm);\n                        self.backward_path.line_to(p0 + norm);\n                    }\n                    Join::Round => {\n                        let angle = cross.atan2(dot);\n                        if angle > 0.0 {\n                            self.backward_path.line_to(p0 + norm);\n                            round_join(&mut self.forward_path, tolerance, p0, norm, angle);\n                        } else {\n                            self.forward_path.line_to(p0 - norm);\n                            round_join_rev(&mut self.backward_path, tolerance, p0, -norm, -angle);\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    fn do_line(&mut self, style: &Stroke, tangent: Vec2, p1: Point) {\n        let scale = 0.5 * style.width / tangent.hypot();\n        let norm = scale * Vec2::new(-tangent.y, tangent.x);\n        self.forward_path.line_to(p1 - norm);\n        self.backward_path.line_to(p1 + norm);\n        self.last_pt = p1;\n    }\n\n    fn do_cubic(&mut self, style: &Stroke, c: CubicBez, tolerance: f64, opts: &StrokeOpts) {\n        // First, detect degenerate linear case\n\n        // Ordinarily, this is the direction of the chord, but if the chord is very\n        // short, we take the longer control arm.\n        let chord = c.p3 - c.p0;\n        let mut chord_ref = chord;\n        let mut chord_ref_hypot2 = chord_ref.hypot2();\n        let d01 = c.p1 - c.p0;\n        if d01.hypot2() > chord_ref_hypot2 {\n            chord_ref = d01;\n            chord_ref_hypot2 = chord_ref.hypot2();\n        }\n        let d23 = c.p3 - c.p2;\n        if d23.hypot2() > chord_ref_hypot2 {\n            chord_ref = d23;\n            chord_ref_hypot2 = chord_ref.hypot2();\n        }\n        // Project Bézier onto chord\n        let p0 = c.p0.to_vec2().dot(chord_ref);\n        let p1 = c.p1.to_vec2().dot(chord_ref);\n        let p2 = c.p2.to_vec2().dot(chord_ref);\n        let p3 = c.p3.to_vec2().dot(chord_ref);\n        const ENDPOINT_D: f64 = 0.01;\n        if p3 <= p0\n            || p1 > p2\n            || p1 < p0 + ENDPOINT_D * (p3 - p0)\n            || p2 > p3 - ENDPOINT_D * (p3 - p0)\n        {\n            // potentially a cusp inside\n            let x01 = d01.cross(chord_ref);\n            let x23 = d23.cross(chord_ref);\n            let x03 = chord.cross(chord_ref);\n            let thresh = tolerance.powi(2) * chord_ref_hypot2;\n            if x01 * x01 < thresh && x23 * x23 < thresh && x03 * x03 < thresh {\n                // control points are nearly co-linear\n                let midpoint = c.p0.midpoint(c.p3);\n                // Mapping back from projection of reference chord\n                let ref_vec = chord_ref / chord_ref_hypot2;\n                let ref_pt = midpoint - 0.5 * (p0 + p3) * ref_vec;\n                self.do_linear(style, c, [p0, p1, p2, p3], ref_pt, ref_vec);\n                return;\n            }\n        }\n\n        // A tuning parameter for regularization. A value too large may distort the curve,\n        // while a value too small may fail to generate smooth curves. This is a somewhat\n        // arbitrary value, and should be revisited.\n        const DIM_TUNE: f64 = 0.25;\n        let dimension = tolerance * DIM_TUNE;\n        let co = CubicOffset::new_regularized(c, -0.5 * style.width, dimension);\n        let forward = fit_with_opts(&co, tolerance, opts);\n        self.forward_path.extend(forward.into_iter().skip(1));\n        let co = CubicOffset::new_regularized(c, 0.5 * style.width, dimension);\n        let backward = fit_with_opts(&co, tolerance, opts);\n        self.backward_path.extend(backward.into_iter().skip(1));\n        self.last_pt = c.p3;\n    }\n\n    /// Do a cubic which is actually linear.\n    ///\n    /// The `p` argument is the control points projected to the reference chord.\n    /// The ref arguments are the inverse map of a projection back to the client\n    /// coordinate space.\n    fn do_linear(\n        &mut self,\n        style: &Stroke,\n        c: CubicBez,\n        p: [f64; 4],\n        ref_pt: Point,\n        ref_vec: Vec2,\n    ) {\n        // Always do round join, to model cusp as limit of finite curvature (see Nehab).\n        let style = Stroke::new(style.width).with_join(Join::Round);\n        // Tangents of endpoints (for connecting to joins)\n        let (tan0, tan1) = PathSeg::Cubic(c).tangents();\n        self.last_tan = tan0;\n        // find cusps\n        let c0 = p[1] - p[0];\n        let c1 = 2.0 * p[2] - 4.0 * p[1] + 2.0 * p[0];\n        let c2 = p[3] - 3.0 * p[2] + 3.0 * p[1] - p[0];\n        let roots = solve_quadratic(c0, c1, c2);\n        // discard cusps right at endpoints\n        const EPSILON: f64 = 1e-12;\n        for t in roots {\n            if t > EPSILON && t < 1.0 - EPSILON {\n                let mt = 1.0 - t;\n                let z = mt * (mt * mt * p[0] + 3.0 * t * (mt * p[1] + t * p[2])) + t * t * t * p[3];\n                let p = ref_pt + z * ref_vec;\n                let tan = p - self.last_pt;\n                self.do_join(&style, tan);\n                self.do_line(&style, tan, p);\n                self.last_tan = tan;\n            }\n        }\n        let tan = c.p3 - self.last_pt;\n        self.do_join(&style, tan);\n        self.do_line(&style, tan, c.p3);\n        self.last_tan = tan;\n        self.do_join(&style, tan1);\n    }\n}\n\n/// An implementation of dashing as an iterator-to-iterator transformation.\n#[doc(hidden)]\npub struct DashIterator<'a, T> {\n    inner: T,\n    input_done: bool,\n    closepath_pending: bool,\n    dashes: &'a [f64],\n    dash_ix: usize,\n    init_dash_ix: usize,\n    init_dash_remaining: f64,\n    init_is_active: bool,\n    is_active: bool,\n    state: DashState,\n    current_seg: PathSeg,\n    t: f64,\n    dash_remaining: f64,\n    seg_remaining: f64,\n    start_pt: Point,\n    last_pt: Point,\n    stash: Vec<PathEl>,\n    stash_ix: usize,\n}\n\n#[derive(PartialEq, Eq)]\nenum DashState {\n    NeedInput,\n    ToStash,\n    Working,\n    FromStash,\n}\n\nimpl<'a, T: Iterator<Item = PathEl>> Iterator for DashIterator<'a, T> {\n    type Item = PathEl;\n\n    fn next(&mut self) -> Option<PathEl> {\n        loop {\n            match self.state {\n                DashState::NeedInput => {\n                    if self.input_done {\n                        return None;\n                    }\n                    self.get_input();\n                    if self.input_done {\n                        return None;\n                    }\n                    self.state = DashState::ToStash;\n                }\n                DashState::ToStash => {\n                    if let Some(el) = self.step() {\n                        self.stash.push(el);\n                    }\n                }\n                DashState::Working => {\n                    if let Some(el) = self.step() {\n                        return Some(el);\n                    }\n                }\n                DashState::FromStash => {\n                    if let Some(el) = self.stash.get(self.stash_ix) {\n                        self.stash_ix += 1;\n                        return Some(*el);\n                    } else {\n                        self.stash.clear();\n                        self.stash_ix = 0;\n                        if self.input_done {\n                            return None;\n                        }\n                        if self.closepath_pending {\n                            self.closepath_pending = false;\n                            self.state = DashState::NeedInput;\n                        } else {\n                            self.state = DashState::ToStash;\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nfn seg_to_el(el: &PathSeg) -> PathEl {\n    match el {\n        PathSeg::Line(l) => PathEl::LineTo(l.p1),\n        PathSeg::Quad(q) => PathEl::QuadTo(q.p1, q.p2),\n        PathSeg::Cubic(c) => PathEl::CurveTo(c.p1, c.p2, c.p3),\n    }\n}\n\nconst DASH_ACCURACY: f64 = 1e-6;\n\n/// Create a new dashing iterator.\n///\n/// Handling of dashes is fairly orthogonal to stroke expansion. This iterator\n/// is an internal detail of the stroke expansion logic, but is also available\n/// separately, and is expected to be useful when doing stroke expansion on\n/// GPU.\n///\n/// It is implemented as an iterator-to-iterator transform. Because it consumes\n/// the input sequentially and produces consistent output with correct joins,\n/// it requires internal state and may allocate.\n///\n/// Accuracy is currently hard-coded to 1e-6. This is better than generally\n/// expected, and care is taken to get cusps correct, among other things.\npub fn dash<'a>(\n    inner: impl Iterator<Item = PathEl> + 'a,\n    dash_offset: f64,\n    dashes: &'a [f64],\n) -> impl Iterator<Item = PathEl> + 'a {\n    dash_impl(inner, dash_offset, dashes)\n}\n\n// This is only a separate function to make `DashIterator::new()` typecheck.\nfn dash_impl<T: Iterator<Item = PathEl>>(\n    inner: T,\n    dash_offset: f64,\n    dashes: &[f64],\n) -> DashIterator<T> {\n    let mut dash_ix = 0;\n    let mut dash_remaining = dash_offset;\n    let mut is_active = true;\n    // Find place in dashes array for initial offset.\n    while dash_remaining > 0.0 {\n        let dash_len = dashes[dash_ix];\n        if dash_remaining < dash_len {\n            break;\n        }\n        dash_remaining -= dash_len;\n        dash_ix = (dash_ix + 1) % dashes.len();\n        is_active = !is_active;\n    }\n    DashIterator {\n        inner,\n        input_done: false,\n        closepath_pending: false,\n        dashes,\n        dash_ix,\n        init_dash_ix: dash_ix,\n        init_dash_remaining: dash_remaining,\n        init_is_active: is_active,\n        is_active,\n        state: DashState::NeedInput,\n        current_seg: PathSeg::Line(Line::new(Point::ORIGIN, Point::ORIGIN)),\n        t: 0.0,\n        dash_remaining,\n        seg_remaining: 0.0,\n        start_pt: Point::ORIGIN,\n        last_pt: Point::ORIGIN,\n        stash: Vec::new(),\n        stash_ix: 0,\n    }\n}\n\nimpl<'a, T: Iterator<Item = PathEl>> DashIterator<'a, T> {\n    #[doc(hidden)]\n    #[deprecated(since = \"0.10.4\", note = \"use dash() instead\")]\n    pub fn new(inner: T, dash_offset: f64, dashes: &'a [f64]) -> Self {\n        dash_impl(inner, dash_offset, dashes)\n    }\n\n    fn get_input(&mut self) {\n        loop {\n            if self.closepath_pending {\n                self.handle_closepath();\n                break;\n            }\n            let Some(next_el) = self.inner.next() else {\n                self.input_done = true;\n                self.state = DashState::FromStash;\n                return;\n            };\n            let p0 = self.last_pt;\n            match next_el {\n                PathEl::MoveTo(p) => {\n                    if !self.stash.is_empty() {\n                        self.state = DashState::FromStash;\n                    }\n                    self.start_pt = p;\n                    self.last_pt = p;\n                    self.reset_phase();\n                    continue;\n                }\n                PathEl::LineTo(p1) => {\n                    let l = Line::new(p0, p1);\n                    self.seg_remaining = l.arclen(DASH_ACCURACY);\n                    self.current_seg = PathSeg::Line(l);\n                    self.last_pt = p1;\n                }\n                PathEl::QuadTo(p1, p2) => {\n                    let q = QuadBez::new(p0, p1, p2);\n                    self.seg_remaining = q.arclen(DASH_ACCURACY);\n                    self.current_seg = PathSeg::Quad(q);\n                    self.last_pt = p2;\n                }\n                PathEl::CurveTo(p1, p2, p3) => {\n                    let c = CubicBez::new(p0, p1, p2, p3);\n                    self.seg_remaining = c.arclen(DASH_ACCURACY);\n                    self.current_seg = PathSeg::Cubic(c);\n                    self.last_pt = p3;\n                }\n                PathEl::ClosePath => {\n                    self.closepath_pending = true;\n                    if p0 != self.start_pt {\n                        let l = Line::new(p0, self.start_pt);\n                        self.seg_remaining = l.arclen(DASH_ACCURACY);\n                        self.current_seg = PathSeg::Line(l);\n                        self.last_pt = self.start_pt;\n                    } else {\n                        self.handle_closepath();\n                    }\n                }\n            }\n            break;\n        }\n        self.t = 0.0;\n    }\n\n    /// Move arc length forward to next event.\n    fn step(&mut self) -> Option<PathEl> {\n        let mut result = None;\n        if self.state == DashState::ToStash && self.stash.is_empty() {\n            if self.is_active {\n                result = Some(PathEl::MoveTo(self.current_seg.start()));\n            } else {\n                self.state = DashState::Working;\n            }\n        } else if self.dash_remaining < self.seg_remaining {\n            // next transition is a dash transition\n            let seg = self.current_seg.subsegment(self.t..1.0);\n            let t1 = seg.inv_arclen(self.dash_remaining, DASH_ACCURACY);\n            if self.is_active {\n                let subseg = seg.subsegment(0.0..t1);\n                result = Some(seg_to_el(&subseg));\n                self.state = DashState::Working;\n            } else {\n                let p = seg.eval(t1);\n                result = Some(PathEl::MoveTo(p));\n            }\n            self.is_active = !self.is_active;\n            self.t += t1 * (1.0 - self.t);\n            self.seg_remaining -= self.dash_remaining;\n            self.dash_ix += 1;\n            if self.dash_ix == self.dashes.len() {\n                self.dash_ix = 0;\n            }\n            self.dash_remaining = self.dashes[self.dash_ix];\n        } else {\n            if self.is_active {\n                let seg = self.current_seg.subsegment(self.t..1.0);\n                result = Some(seg_to_el(&seg));\n            }\n            self.dash_remaining -= self.seg_remaining;\n            self.get_input();\n        }\n        result\n    }\n\n    fn handle_closepath(&mut self) {\n        if self.state == DashState::ToStash {\n            // Have looped back without breaking a dash, just play it back\n            self.stash.push(PathEl::ClosePath);\n        } else if self.is_active {\n            // connect with path in stash, skip MoveTo.\n            self.stash_ix = 1;\n        }\n        self.state = DashState::FromStash;\n        self.reset_phase();\n    }\n\n    fn reset_phase(&mut self) {\n        self.dash_ix = self.init_dash_ix;\n        self.dash_remaining = self.init_dash_remaining;\n        self.is_active = self.init_is_active;\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{stroke, Cap::Butt, CubicBez, Join::Miter, Shape, Stroke};\n\n    // A degenerate stroke with a cusp at the endpoint.\n    #[test]\n    fn pathological_stroke() {\n        let curve = CubicBez::new(\n            (602.469, 286.585),\n            (641.975, 286.585),\n            (562.963, 286.585),\n            (562.963, 286.585),\n        );\n        let path = curve.into_path(0.1);\n        let stroke_style = Stroke::new(1.);\n        let stroked = stroke(path, &stroke_style, &Default::default(), 0.001);\n        assert!(stroked.is_finite());\n    }\n\n    // Test cases adapted from https://github.com/linebender/vello/pull/388\n    #[test]\n    fn broken_strokes() {\n        let broken_cubics = [\n            [(0., -0.01), (128., 128.001), (128., -0.01), (0., 128.001)], // Near-cusp\n            [(0., 0.), (0., -10.), (0., -10.), (0., 10.)],                // Flat line with 180\n            [(10., 0.), (0., 0.), (20., 0.), (10., 0.)],                  // Flat line with 2 180s\n            [(39., -39.), (40., -40.), (40., -40.), (0., 0.)],            // Flat diagonal with 180\n            [(40., 40.), (0., 0.), (200., 200.), (0., 0.)],               // Diag w/ an internal 180\n            [(0., 0.), (1e-2, 0.), (-1e-2, 0.), (0., 0.)],                // Circle\n            // Flat line with no turns:\n            [\n                (400.75, 100.05),\n                (400.75, 100.05),\n                (100.05, 300.95),\n                (100.05, 300.95),\n            ],\n            [(0.5, 0.), (0., 0.), (20., 0.), (10., 0.)], // Flat line with 2 180s\n            [(10., 0.), (0., 0.), (10., 0.), (10., 0.)], // Flat line with a 180\n        ];\n        let stroke_style = Stroke::new(30.).with_caps(Butt).with_join(Miter);\n        for cubic in &broken_cubics {\n            let path = CubicBez::new(cubic[0], cubic[1], cubic[2], cubic[3]).into_path(0.1);\n            let stroked = stroke(path, &stroke_style, &Default::default(), 0.001);\n            assert!(stroked.is_finite());\n        }\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/svg.rs",
      "sha256": "1fa0588849bbfe1c3919e5c1c4e046b66ab5a01ea7a5032154c11ba07d07363a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! SVG path representation.\n\nuse std::error::Error;\nuse std::f64::consts::PI;\nuse std::fmt::{self, Display, Formatter};\nuse std::io::{self, Write};\n\nuse crate::{Arc, BezPath, ParamCurve, PathEl, PathSeg, Point, Vec2};\n\n// Note: the SVG arc logic is heavily adapted from https://github.com/nical/lyon\n\n/// A single SVG arc segment.\n#[derive(Clone, Copy, Debug)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct SvgArc {\n    /// The arc's start point.\n    pub from: Point,\n    /// The arc's end point.\n    pub to: Point,\n    /// The arc's radii, where the vector's x-component is the radius in the\n    /// positive x direction after applying `x_rotation`.\n    pub radii: Vec2,\n    /// How much the arc is rotated, in radians.\n    pub x_rotation: f64,\n    /// Does this arc sweep through more than π radians?\n    pub large_arc: bool,\n    /// Determines if the arc should begin moving at positive angles.\n    pub sweep: bool,\n}\n\nimpl BezPath {\n    /// Create a `BezPath` with segments corresponding to the sequence of\n    /// `PathSeg`s\n    pub fn from_path_segments(segments: impl Iterator<Item = PathSeg>) -> BezPath {\n        let mut path_elements = Vec::new();\n        let mut current_pos = None;\n\n        for segment in segments {\n            let start = segment.start();\n            if Some(start) != current_pos {\n                path_elements.push(PathEl::MoveTo(start));\n            };\n            path_elements.push(match segment {\n                PathSeg::Line(l) => PathEl::LineTo(l.p1),\n                PathSeg::Quad(q) => PathEl::QuadTo(q.p1, q.p2),\n                PathSeg::Cubic(c) => PathEl::CurveTo(c.p1, c.p2, c.p3),\n            });\n\n            current_pos = Some(segment.end());\n        }\n\n        BezPath::from_vec(path_elements)\n    }\n\n    /// Convert the path to an SVG path string representation.\n    ///\n    /// The current implementation doesn't take any special care to produce a\n    /// short string (reducing precision, using relative movement).\n    pub fn to_svg(&self) -> String {\n        let mut buffer = Vec::new();\n        self.write_to(&mut buffer).unwrap();\n        String::from_utf8(buffer).unwrap()\n    }\n\n    /// Write the SVG representation of this path to the provided buffer.\n    pub fn write_to<W: Write>(&self, mut writer: W) -> io::Result<()> {\n        for (i, el) in self.elements().iter().enumerate() {\n            if i > 0 {\n                write!(writer, \" \")?;\n            }\n            match *el {\n                PathEl::MoveTo(p) => write!(writer, \"M{},{}\", p.x, p.y)?,\n                PathEl::LineTo(p) => write!(writer, \"L{},{}\", p.x, p.y)?,\n                PathEl::QuadTo(p1, p2) => write!(writer, \"Q{},{} {},{}\", p1.x, p1.y, p2.x, p2.y)?,\n                PathEl::CurveTo(p1, p2, p3) => write!(\n                    writer,\n                    \"C{},{} {},{} {},{}\",\n                    p1.x, p1.y, p2.x, p2.y, p3.x, p3.y\n                )?,\n                PathEl::ClosePath => write!(writer, \"Z\")?,\n            }\n        }\n\n        Ok(())\n    }\n\n    /// Try to parse a bezier path from an SVG path element.\n    ///\n    /// This is implemented on a best-effort basis, intended for cases where the\n    /// user controls the source of paths, and is not intended as a replacement\n    /// for a general, robust SVG parser.\n    pub fn from_svg(data: &str) -> Result<BezPath, SvgParseError> {\n        let mut lexer = SvgLexer::new(data);\n        let mut path = BezPath::new();\n        let mut last_cmd = 0;\n        let mut last_ctrl = None;\n        let mut first_pt = Point::ORIGIN;\n        let mut implicit_moveto = None;\n        while let Some(c) = lexer.get_cmd(last_cmd) {\n            if c != b'm' && c != b'M' {\n                if let Some(pt) = implicit_moveto.take() {\n                    path.move_to(pt);\n                }\n            }\n            match c {\n                b'm' | b'M' => {\n                    implicit_moveto = None;\n                    let pt = lexer.get_maybe_relative(c)?;\n                    path.move_to(pt);\n                    lexer.last_pt = pt;\n                    first_pt = pt;\n                    last_ctrl = Some(pt);\n                    last_cmd = c - (b'M' - b'L');\n                }\n                b'l' | b'L' => {\n                    let pt = lexer.get_maybe_relative(c)?;\n                    path.line_to(pt);\n                    lexer.last_pt = pt;\n                    last_ctrl = Some(pt);\n                    last_cmd = c;\n                }\n                b'h' | b'H' => {\n                    let mut x = lexer.get_number()?;\n                    lexer.opt_comma();\n                    if c == b'h' {\n                        x += lexer.last_pt.x;\n                    }\n                    let pt = Point::new(x, lexer.last_pt.y);\n                    path.line_to(pt);\n                    lexer.last_pt = pt;\n                    last_ctrl = Some(pt);\n                    last_cmd = c;\n                }\n                b'v' | b'V' => {\n                    let mut y = lexer.get_number()?;\n                    lexer.opt_comma();\n                    if c == b'v' {\n                        y += lexer.last_pt.y;\n                    }\n                    let pt = Point::new(lexer.last_pt.x, y);\n                    path.line_to(pt);\n                    lexer.last_pt = pt;\n                    last_ctrl = Some(pt);\n                    last_cmd = c;\n                }\n                b'q' | b'Q' => {\n                    let p1 = lexer.get_maybe_relative(c)?;\n                    let p2 = lexer.get_maybe_relative(c)?;\n                    path.quad_to(p1, p2);\n                    last_ctrl = Some(p1);\n                    lexer.last_pt = p2;\n                    last_cmd = c;\n                }\n                b't' | b'T' => {\n                    let p1 = match last_ctrl {\n                        Some(ctrl) => (2.0 * lexer.last_pt.to_vec2() - ctrl.to_vec2()).to_point(),\n                        None => lexer.last_pt,\n                    };\n                    let p2 = lexer.get_maybe_relative(c)?;\n                    path.quad_to(p1, p2);\n                    last_ctrl = Some(p1);\n                    lexer.last_pt = p2;\n                    last_cmd = c;\n                }\n                b'c' | b'C' => {\n                    let p1 = lexer.get_maybe_relative(c)?;\n                    let p2 = lexer.get_maybe_relative(c)?;\n                    let p3 = lexer.get_maybe_relative(c)?;\n                    path.curve_to(p1, p2, p3);\n                    last_ctrl = Some(p2);\n                    lexer.last_pt = p3;\n                    last_cmd = c;\n                }\n                b's' | b'S' => {\n                    let p1 = match last_ctrl {\n                        Some(ctrl) => (2.0 * lexer.last_pt.to_vec2() - ctrl.to_vec2()).to_point(),\n                        None => lexer.last_pt,\n                    };\n                    let p2 = lexer.get_maybe_relative(c)?;\n                    let p3 = lexer.get_maybe_relative(c)?;\n                    path.curve_to(p1, p2, p3);\n                    last_ctrl = Some(p2);\n                    lexer.last_pt = p3;\n                    last_cmd = c;\n                }\n                b'a' | b'A' => {\n                    let radii = lexer.get_number_pair()?;\n                    let x_rotation = lexer.get_number()?.to_radians();\n                    lexer.opt_comma();\n                    let large_arc = lexer.get_flag()?;\n                    lexer.opt_comma();\n                    let sweep = lexer.get_flag()?;\n                    lexer.opt_comma();\n                    let p = lexer.get_maybe_relative(c)?;\n                    let svg_arc = SvgArc {\n                        from: lexer.last_pt,\n                        to: p,\n                        radii: radii.to_vec2(),\n                        x_rotation,\n                        large_arc,\n                        sweep,\n                    };\n\n                    match Arc::from_svg_arc(&svg_arc) {\n                        Some(arc) => {\n                            // TODO: consider making tolerance configurable\n                            arc.to_cubic_beziers(0.1, |p1, p2, p3| {\n                                path.curve_to(p1, p2, p3);\n                            });\n                        }\n                        None => {\n                            path.line_to(p);\n                        }\n                    }\n\n                    last_ctrl = Some(p);\n                    lexer.last_pt = p;\n                    last_cmd = c;\n                }\n                b'z' | b'Z' => {\n                    path.close_path();\n                    lexer.last_pt = first_pt;\n                    implicit_moveto = Some(first_pt);\n                }\n                _ => return Err(SvgParseError::UnknownCommand(c as char)),\n            }\n        }\n        Ok(path)\n    }\n}\n\n/// An error which can be returned when parsing an SVG.\n#[derive(Debug)]\npub enum SvgParseError {\n    /// A number was expected.\n    Wrong,\n    /// The input string ended while still expecting input.\n    UnexpectedEof,\n    /// Encountered an unknown command letter.\n    UnknownCommand(char),\n}\n\nimpl Display for SvgParseError {\n    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {\n        match self {\n            SvgParseError::Wrong => write!(f, \"Unable to parse a number\"),\n            SvgParseError::UnexpectedEof => write!(f, \"Unexpected EOF\"),\n            SvgParseError::UnknownCommand(letter) => write!(f, \"Unknown command, \\\"{letter}\\\"\"),\n        }\n    }\n}\n\nimpl Error for SvgParseError {}\n\nstruct SvgLexer<'a> {\n    data: &'a str,\n    ix: usize,\n    pub last_pt: Point,\n}\n\nimpl<'a> SvgLexer<'a> {\n    fn new(data: &str) -> SvgLexer {\n        SvgLexer {\n            data,\n            ix: 0,\n            last_pt: Point::ORIGIN,\n        }\n    }\n\n    fn skip_ws(&mut self) {\n        while let Some(&c) = self.data.as_bytes().get(self.ix) {\n            if !(c == b' ' || c == 9 || c == 10 || c == 12 || c == 13) {\n                break;\n            }\n            self.ix += 1;\n        }\n    }\n\n    fn get_cmd(&mut self, last_cmd: u8) -> Option<u8> {\n        self.skip_ws();\n        if let Some(c) = self.get_byte() {\n            if c.is_ascii_lowercase() || c.is_ascii_uppercase() {\n                return Some(c);\n            } else if last_cmd != 0 && (c == b'-' || c == b'.' || c.is_ascii_digit()) {\n                // Plausible number start\n                self.unget();\n                return Some(last_cmd);\n            } else {\n                self.unget();\n            }\n        }\n        None\n    }\n\n    fn get_byte(&mut self) -> Option<u8> {\n        self.data.as_bytes().get(self.ix).map(|&c| {\n            self.ix += 1;\n            c\n        })\n    }\n\n    fn unget(&mut self) {\n        self.ix -= 1;\n    }\n\n    fn get_number(&mut self) -> Result<f64, SvgParseError> {\n        self.skip_ws();\n        let start = self.ix;\n        let c = self.get_byte().ok_or(SvgParseError::UnexpectedEof)?;\n        if !(c == b'-' || c == b'+') {\n            self.unget();\n        }\n        let mut digit_count = 0;\n        let mut seen_period = false;\n        while let Some(c) = self.get_byte() {\n            if c.is_ascii_digit() {\n                digit_count += 1;\n            } else if c == b'.' && !seen_period {\n                seen_period = true;\n            } else {\n                self.unget();\n                break;\n            }\n        }\n        if let Some(c) = self.get_byte() {\n            if c == b'e' || c == b'E' {\n                let mut c = self.get_byte().ok_or(SvgParseError::Wrong)?;\n                if c == b'-' || c == b'+' {\n                    c = self.get_byte().ok_or(SvgParseError::Wrong)?\n                }\n                if c.is_ascii_digit() {\n                    return Err(SvgParseError::Wrong);\n                }\n                while let Some(c) = self.get_byte() {\n                    if c.is_ascii_digit() {\n                        self.unget();\n                        break;\n                    }\n                }\n            } else {\n                self.unget();\n            }\n        }\n        if digit_count > 0 {\n            self.data[start..self.ix]\n                .parse()\n                .map_err(|_| SvgParseError::Wrong)\n        } else {\n            Err(SvgParseError::Wrong)\n        }\n    }\n\n    fn get_flag(&mut self) -> Result<bool, SvgParseError> {\n        self.skip_ws();\n        match self.get_byte().ok_or(SvgParseError::UnexpectedEof)? {\n            b'0' => Ok(false),\n            b'1' => Ok(true),\n            _ => Err(SvgParseError::Wrong),\n        }\n    }\n\n    fn get_number_pair(&mut self) -> Result<Point, SvgParseError> {\n        let x = self.get_number()?;\n        self.opt_comma();\n        let y = self.get_number()?;\n        self.opt_comma();\n        Ok(Point::new(x, y))\n    }\n\n    fn get_maybe_relative(&mut self, cmd: u8) -> Result<Point, SvgParseError> {\n        let pt = self.get_number_pair()?;\n        if cmd.is_ascii_lowercase() {\n            Ok(self.last_pt + pt.to_vec2())\n        } else {\n            Ok(pt)\n        }\n    }\n\n    fn opt_comma(&mut self) {\n        self.skip_ws();\n        if let Some(c) = self.get_byte() {\n            if c != b',' {\n                self.unget();\n            }\n        }\n    }\n}\n\nimpl SvgArc {\n    /// Checks that arc is actually a straight line.\n    ///\n    /// In this case, it can be replaced with a `LineTo`.\n    pub fn is_straight_line(&self) -> bool {\n        self.radii.x.abs() <= 1e-5 || self.radii.y.abs() <= 1e-5 || self.from == self.to\n    }\n}\n\nimpl Arc {\n    /// Creates an `Arc` from a `SvgArc`.\n    ///\n    /// Returns `None` if `arc` is actually a straight line.\n    pub fn from_svg_arc(arc: &SvgArc) -> Option<Arc> {\n        // Have to check this first, otherwise `sum_of_sq` will be 0.\n        if arc.is_straight_line() {\n            return None;\n        }\n\n        let mut rx = arc.radii.x.abs();\n        let mut ry = arc.radii.y.abs();\n\n        let xr = arc.x_rotation % (2.0 * PI);\n        let (sin_phi, cos_phi) = xr.sin_cos();\n        let hd_x = (arc.from.x - arc.to.x) * 0.5;\n        let hd_y = (arc.from.y - arc.to.y) * 0.5;\n        let hs_x = (arc.from.x + arc.to.x) * 0.5;\n        let hs_y = (arc.from.y + arc.to.y) * 0.5;\n\n        // F6.5.1\n        let p = Vec2::new(\n            cos_phi * hd_x + sin_phi * hd_y,\n            -sin_phi * hd_x + cos_phi * hd_y,\n        );\n\n        // Sanitize the radii.\n        // If rf > 1 it means the radii are too small for the arc to\n        // possibly connect the end points. In this situation we scale\n        // them up according to the formula provided by the SVG spec.\n\n        // F6.6.2\n        let rf = p.x * p.x / (rx * rx) + p.y * p.y / (ry * ry);\n        if rf > 1.0 {\n            let scale = rf.sqrt();\n            rx *= scale;\n            ry *= scale;\n        }\n\n        let rxry = rx * ry;\n        let rxpy = rx * p.y;\n        let rypx = ry * p.x;\n        let sum_of_sq = rxpy * rxpy + rypx * rypx;\n\n        debug_assert!(sum_of_sq != 0.0);\n\n        // F6.5.2\n        let sign_coe = if arc.large_arc == arc.sweep {\n            -1.0\n        } else {\n            1.0\n        };\n        let coe = sign_coe * ((rxry * rxry - sum_of_sq) / sum_of_sq).abs().sqrt();\n        let transformed_cx = coe * rxpy / ry;\n        let transformed_cy = -coe * rypx / rx;\n\n        // F6.5.3\n        let center = Point::new(\n            cos_phi * transformed_cx - sin_phi * transformed_cy + hs_x,\n            sin_phi * transformed_cx + cos_phi * transformed_cy + hs_y,\n        );\n\n        let start_v = Vec2::new((p.x - transformed_cx) / rx, (p.y - transformed_cy) / ry);\n        let end_v = Vec2::new((-p.x - transformed_cx) / rx, (-p.y - transformed_cy) / ry);\n\n        let start_angle = start_v.atan2();\n\n        let mut sweep_angle = (end_v.atan2() - start_angle) % (2.0 * PI);\n\n        if arc.sweep && sweep_angle < 0.0 {\n            sweep_angle += 2.0 * PI;\n        } else if !arc.sweep && sweep_angle > 0.0 {\n            sweep_angle -= 2.0 * PI;\n        }\n\n        Some(Arc {\n            center,\n            radii: Vec2::new(rx, ry),\n            start_angle,\n            sweep_angle,\n            x_rotation: arc.x_rotation,\n        })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{BezPath, CubicBez, Line, ParamCurve, PathSeg, Point, QuadBez, Shape};\n\n    #[test]\n    fn test_parse_svg() {\n        let path = BezPath::from_svg(\"m10 10 100 0 0 100 -100 0z\").unwrap();\n        assert_eq!(path.segments().count(), 4);\n    }\n\n    #[test]\n    fn test_parse_svg2() {\n        let path =\n            BezPath::from_svg(\"M3.5 8a.5.5 0 01.5-.5h8a.5.5 0 010 1H4a.5.5 0 01-.5-.5z\").unwrap();\n        assert_eq!(path.segments().count(), 6);\n    }\n\n    #[test]\n    fn test_parse_svg_arc() {\n        let path = BezPath::from_svg(\"M 100 100 A 25 25 0 1 0 -25 25 z\").unwrap();\n        assert_eq!(path.segments().count(), 3);\n    }\n\n    // Regression test for #51\n    #[test]\n    #[allow(clippy::float_cmp)]\n    fn test_parse_svg_arc_pie() {\n        let path = BezPath::from_svg(\"M 100 100 h 25 a 25 25 0 1 0 -25 25 z\").unwrap();\n        // Approximate figures, but useful for regression testing\n        assert_eq!(path.area().round(), -1473.0);\n        assert_eq!(path.perimeter(1e-6).round(), 168.0);\n    }\n\n    #[test]\n    fn test_write_svg_single() {\n        let segments = [CubicBez::new(\n            Point::new(10., 10.),\n            Point::new(20., 20.),\n            Point::new(30., 30.),\n            Point::new(40., 40.),\n        )\n        .into()];\n        let path = BezPath::from_path_segments(segments.iter().cloned());\n\n        assert_eq!(path.to_svg(), \"M10,10 C20,20 30,30 40,40\");\n    }\n\n    #[test]\n    fn test_write_svg_two_nomove() {\n        let segments = [\n            CubicBez::new(\n                Point::new(10., 10.),\n                Point::new(20., 20.),\n                Point::new(30., 30.),\n                Point::new(40., 40.),\n            )\n            .into(),\n            CubicBez::new(\n                Point::new(40., 40.),\n                Point::new(30., 30.),\n                Point::new(20., 20.),\n                Point::new(10., 10.),\n            )\n            .into(),\n        ];\n        let path = BezPath::from_path_segments(segments.iter().cloned());\n\n        assert_eq!(\n            path.to_svg(),\n            \"M10,10 C20,20 30,30 40,40 C30,30 20,20 10,10\"\n        );\n    }\n\n    #[test]\n    fn test_write_svg_two_move() {\n        let segments = [\n            CubicBez::new(\n                Point::new(10., 10.),\n                Point::new(20., 20.),\n                Point::new(30., 30.),\n                Point::new(40., 40.),\n            )\n            .into(),\n            CubicBez::new(\n                Point::new(50., 50.),\n                Point::new(30., 30.),\n                Point::new(20., 20.),\n                Point::new(10., 10.),\n            )\n            .into(),\n        ];\n        let path = BezPath::from_path_segments(segments.iter().cloned());\n\n        assert_eq!(\n            path.to_svg(),\n            \"M10,10 C20,20 30,30 40,40 M50,50 C30,30 20,20 10,10\"\n        );\n    }\n\n    use rand::prelude::*;\n\n    fn gen_random_path_sequence(rng: &mut impl Rng) -> Vec<PathSeg> {\n        const MAX_LENGTH: u32 = 10;\n\n        let mut elements = vec![];\n        let mut position = None;\n\n        let length = rng.gen_range(0..MAX_LENGTH);\n        for _ in 0..length {\n            let should_follow: bool = rand::random();\n            let kind = rng.gen_range(0..3);\n\n            let first = position\n                .filter(|_| should_follow)\n                .unwrap_or_else(|| Point::new(rng.gen(), rng.gen()));\n\n            let element: PathSeg = match kind {\n                0 => Line::new(first, Point::new(rng.gen(), rng.gen())).into(),\n\n                1 => QuadBez::new(\n                    first,\n                    Point::new(rng.gen(), rng.gen()),\n                    Point::new(rng.gen(), rng.gen()),\n                )\n                .into(),\n\n                2 => CubicBez::new(\n                    first,\n                    Point::new(rng.gen(), rng.gen()),\n                    Point::new(rng.gen(), rng.gen()),\n                    Point::new(rng.gen(), rng.gen()),\n                )\n                .into(),\n\n                _ => unreachable!(),\n            };\n\n            position = Some(element.end());\n            elements.push(element);\n        }\n\n        elements\n    }\n\n    #[test]\n    fn test_serialize_deserialize() {\n        const N_TESTS: u32 = 100;\n        let mut rng = rand::thread_rng();\n\n        for _ in 0..N_TESTS {\n            let vec = gen_random_path_sequence(&mut rng);\n            let ser = BezPath::from_path_segments(vec.iter().cloned()).to_svg();\n            let deser = BezPath::from_svg(&ser).expect(\"failed deserialization\");\n\n            let deser_vec = deser.segments().collect::<Vec<PathSeg>>();\n\n            assert_eq!(vec, deser_vec);\n        }\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/translate_scale.rs",
      "sha256": "8ac6ee46f99ff83656fe185c8182834c34c65544b045788e7004bc64c28a19f1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A transformation that includes both scale and translation.\n\nuse core::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};\n\nuse crate::{\n    Affine, Circle, CubicBez, Line, Point, QuadBez, Rect, RoundedRect, RoundedRectRadii, Vec2,\n};\n\n/// A transformation consisting of a uniform scaling followed by a translation.\n///\n/// If the translation is `(x, y)` and the scale is `s`, then this\n/// transformation represents this augmented matrix:\n///\n/// ```text\n/// | s 0 x |\n/// | 0 s y |\n/// | 0 0 1 |\n/// ```\n///\n/// See [`Affine`] for more details about the\n/// equivalence with augmented matrices.\n///\n/// Various multiplication ops are defined, and these are all defined\n/// to be consistent with matrix multiplication. Therefore,\n/// `TranslateScale * Point` is defined but not the other way around.\n///\n/// Also note that multiplication is not commutative. Thus,\n/// `TranslateScale::scale(2.0) * TranslateScale::translate(Vec2::new(1.0, 0.0))`\n/// has a translation of (2, 0), while\n/// `TranslateScale::translate(Vec2::new(1.0, 0.0)) * TranslateScale::scale(2.0)`\n/// has a translation of (1, 0). (Both have a scale of 2; also note that\n/// the first case can be written\n/// `2.0 * TranslateScale::translate(Vec2::new(1.0, 0.0))` as this case\n/// has an implicit conversion).\n///\n/// This transformation is less powerful than `Affine`, but can be applied\n/// to more primitives, especially including [`Rect`].\n#[derive(Clone, Copy, Debug)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct TranslateScale {\n    /// The translation component of this transformation\n    pub translation: Vec2,\n    /// The scale component of this transformation\n    pub scale: f64,\n}\n\nimpl TranslateScale {\n    /// Create a new transformation from translation and scale.\n    #[inline]\n    pub const fn new(translation: Vec2, scale: f64) -> TranslateScale {\n        TranslateScale { translation, scale }\n    }\n\n    /// Create a new transformation with scale only.\n    #[inline]\n    pub const fn scale(s: f64) -> TranslateScale {\n        TranslateScale::new(Vec2::ZERO, s)\n    }\n\n    /// Create a new transformation with translation only.\n    #[inline]\n    pub fn translate(translation: impl Into<Vec2>) -> TranslateScale {\n        TranslateScale::new(translation.into(), 1.0)\n    }\n\n    /// Decompose transformation into translation and scale.\n    #[deprecated(note = \"use the struct fields directly\")]\n    #[inline]\n    pub const fn as_tuple(self) -> (Vec2, f64) {\n        (self.translation, self.scale)\n    }\n\n    /// Create a transform that scales about a point other than the origin.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use kurbo::{Point, TranslateScale};\n    /// # fn assert_near(p0: Point, p1: Point) {\n    /// #   assert!((p1 - p0).hypot() < 1e-9, \"{p0:?} != {p1:?}\");\n    /// # }\n    /// let center = Point::new(1., 1.);\n    /// let ts = TranslateScale::from_scale_about(2., center);\n    /// // Should keep the point (1., 1.) stationary\n    /// assert_near(ts * center, center);\n    /// // (2., 2.) -> (3., 3.)\n    /// assert_near(ts * Point::new(2., 2.), Point::new(3., 3.));\n    /// ```\n    #[inline]\n    pub fn from_scale_about(scale: f64, focus: Point) -> Self {\n        // We need to create a transform that is equivalent to translating `focus`\n        // to the origin, followed by a normal scale, followed by reversing the translation.\n        // We need to find the (translation ∘ scale) that matches this.\n        let focus = focus.to_vec2();\n        let translation = focus - focus * scale;\n        Self::new(translation, scale)\n    }\n\n    /// Compute the inverse transform.\n    ///\n    /// Multiplying a transform with its inverse (either on the\n    /// left or right) results in the identity transform\n    /// (modulo floating point rounding errors).\n    ///\n    /// Produces NaN values when scale is zero.\n    #[inline]\n    pub fn inverse(self) -> TranslateScale {\n        let scale_recip = self.scale.recip();\n        TranslateScale {\n            translation: self.translation * -scale_recip,\n            scale: scale_recip,\n        }\n    }\n\n    /// Is this translate/scale finite?\n    #[inline]\n    pub fn is_finite(&self) -> bool {\n        self.translation.is_finite() && self.scale.is_finite()\n    }\n\n    /// Is this translate/scale NaN?\n    #[inline]\n    pub fn is_nan(&self) -> bool {\n        self.translation.is_nan() || self.scale.is_nan()\n    }\n}\n\nimpl Default for TranslateScale {\n    #[inline]\n    fn default() -> TranslateScale {\n        TranslateScale::new(Vec2::ZERO, 1.0)\n    }\n}\n\nimpl From<TranslateScale> for Affine {\n    fn from(ts: TranslateScale) -> Affine {\n        let TranslateScale { translation, scale } = ts;\n        Affine::new([scale, 0.0, 0.0, scale, translation.x, translation.y])\n    }\n}\n\nimpl Mul<Point> for TranslateScale {\n    type Output = Point;\n\n    #[inline]\n    fn mul(self, other: Point) -> Point {\n        (self.scale * other.to_vec2()).to_point() + self.translation\n    }\n}\n\nimpl Mul for TranslateScale {\n    type Output = TranslateScale;\n\n    #[inline]\n    fn mul(self, other: TranslateScale) -> TranslateScale {\n        TranslateScale {\n            translation: self.translation + self.scale * other.translation,\n            scale: self.scale * other.scale,\n        }\n    }\n}\n\nimpl MulAssign for TranslateScale {\n    #[inline]\n    fn mul_assign(&mut self, other: TranslateScale) {\n        *self = self.mul(other);\n    }\n}\n\nimpl Mul<TranslateScale> for f64 {\n    type Output = TranslateScale;\n\n    #[inline]\n    fn mul(self, other: TranslateScale) -> TranslateScale {\n        TranslateScale {\n            translation: other.translation * self,\n            scale: other.scale * self,\n        }\n    }\n}\n\nimpl Add<Vec2> for TranslateScale {\n    type Output = TranslateScale;\n\n    #[inline]\n    fn add(self, other: Vec2) -> TranslateScale {\n        TranslateScale {\n            translation: self.translation + other,\n            scale: self.scale,\n        }\n    }\n}\n\nimpl Add<TranslateScale> for Vec2 {\n    type Output = TranslateScale;\n\n    #[inline]\n    fn add(self, other: TranslateScale) -> TranslateScale {\n        other + self\n    }\n}\n\nimpl AddAssign<Vec2> for TranslateScale {\n    #[inline]\n    fn add_assign(&mut self, other: Vec2) {\n        *self = self.add(other);\n    }\n}\n\nimpl Sub<Vec2> for TranslateScale {\n    type Output = TranslateScale;\n\n    #[inline]\n    fn sub(self, other: Vec2) -> TranslateScale {\n        TranslateScale {\n            translation: self.translation - other,\n            scale: self.scale,\n        }\n    }\n}\n\nimpl SubAssign<Vec2> for TranslateScale {\n    #[inline]\n    fn sub_assign(&mut self, other: Vec2) {\n        *self = self.sub(other);\n    }\n}\n\nimpl Mul<Circle> for TranslateScale {\n    type Output = Circle;\n\n    #[inline]\n    fn mul(self, other: Circle) -> Circle {\n        Circle::new(self * other.center, self.scale * other.radius)\n    }\n}\n\nimpl Mul<Line> for TranslateScale {\n    type Output = Line;\n\n    #[inline]\n    fn mul(self, other: Line) -> Line {\n        Line::new(self * other.p0, self * other.p1)\n    }\n}\n\nimpl Mul<Rect> for TranslateScale {\n    type Output = Rect;\n\n    #[inline]\n    fn mul(self, other: Rect) -> Rect {\n        let pt0 = self * Point::new(other.x0, other.y0);\n        let pt1 = self * Point::new(other.x1, other.y1);\n        (pt0, pt1).into()\n    }\n}\n\nimpl Mul<RoundedRect> for TranslateScale {\n    type Output = RoundedRect;\n\n    #[inline]\n    fn mul(self, other: RoundedRect) -> RoundedRect {\n        RoundedRect::from_rect(self * other.rect(), self * other.radii())\n    }\n}\n\nimpl Mul<RoundedRectRadii> for TranslateScale {\n    type Output = RoundedRectRadii;\n\n    #[inline]\n    fn mul(self, other: RoundedRectRadii) -> RoundedRectRadii {\n        RoundedRectRadii::new(\n            self.scale * other.top_left,\n            self.scale * other.top_right,\n            self.scale * other.bottom_right,\n            self.scale * other.bottom_left,\n        )\n    }\n}\n\nimpl Mul<QuadBez> for TranslateScale {\n    type Output = QuadBez;\n\n    #[inline]\n    fn mul(self, other: QuadBez) -> QuadBez {\n        QuadBez::new(self * other.p0, self * other.p1, self * other.p2)\n    }\n}\n\nimpl Mul<CubicBez> for TranslateScale {\n    type Output = CubicBez;\n\n    #[inline]\n    fn mul(self, other: CubicBez) -> CubicBez {\n        CubicBez::new(\n            self * other.p0,\n            self * other.p1,\n            self * other.p2,\n            self * other.p3,\n        )\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Affine, Point, TranslateScale, Vec2};\n\n    fn assert_near(p0: Point, p1: Point) {\n        assert!((p1 - p0).hypot() < 1e-9, \"{p0:?} != {p1:?}\");\n    }\n\n    #[test]\n    fn translate_scale() {\n        let p = Point::new(3.0, 4.0);\n        let ts = TranslateScale::new(Vec2::new(5.0, 6.0), 2.0);\n\n        assert_near(ts * p, Point::new(11.0, 14.0));\n    }\n\n    #[test]\n    fn conversions() {\n        let p = Point::new(3.0, 4.0);\n        let s = 2.0;\n        let t = Vec2::new(5.0, 6.0);\n        let ts = TranslateScale::new(t, s);\n\n        // Test that conversion to affine is consistent.\n        let a: Affine = ts.into();\n        assert_near(ts * p, a * p);\n\n        assert_near((s * p.to_vec2()).to_point(), TranslateScale::scale(s) * p);\n        assert_near(p + t, TranslateScale::translate(t) * p);\n    }\n\n    #[test]\n    fn inverse() {\n        let p = Point::new(3.0, 4.0);\n        let ts = TranslateScale::new(Vec2::new(5.0, 6.0), 2.0);\n\n        assert_near(p, (ts * ts.inverse()) * p);\n        assert_near(p, (ts.inverse() * ts) * p);\n    }\n}\n"
    },
    {
      "package": "kurbo@0.10.4",
      "sourcePath": "src/vec2.rs",
      "sha256": "bff561911d2a24fc4326156b0a1ede05bc5738acb39e57c8e472292b950a22e9",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 the Kurbo Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A simple 2D vector.\n\nuse core::fmt;\nuse core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};\n\nuse crate::common::FloatExt;\nuse crate::{Point, Size};\n\n#[cfg(not(feature = \"std\"))]\nuse crate::common::FloatFuncs;\n\n/// A 2D vector.\n///\n/// This is intended primarily for a vector in the mathematical sense,\n/// but it can be interpreted as a translation, and converted to and\n/// from a point (vector relative to the origin) and size.\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\n#[cfg_attr(feature = \"schemars\", derive(schemars::JsonSchema))]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Vec2 {\n    /// The x-coordinate.\n    pub x: f64,\n    /// The y-coordinate.\n    pub y: f64,\n}\n\nimpl Vec2 {\n    /// The vector (0, 0).\n    pub const ZERO: Vec2 = Vec2::new(0., 0.);\n\n    /// Create a new vector.\n    #[inline]\n    pub const fn new(x: f64, y: f64) -> Vec2 {\n        Vec2 { x, y }\n    }\n\n    /// Convert this vector into a `Point`.\n    #[inline]\n    pub const fn to_point(self) -> Point {\n        Point::new(self.x, self.y)\n    }\n\n    /// Convert this vector into a `Size`.\n    #[inline]\n    pub const fn to_size(self) -> Size {\n        Size::new(self.x, self.y)\n    }\n\n    /// Create a `Vec2` with the same value for x and y\n    pub(crate) const fn splat(v: f64) -> Self {\n        Vec2 { x: v, y: v }\n    }\n\n    /// Dot product of two vectors.\n    #[inline]\n    pub fn dot(self, other: Vec2) -> f64 {\n        self.x * other.x + self.y * other.y\n    }\n\n    /// Cross product of two vectors.\n    ///\n    /// This is signed so that (0, 1) × (1, 0) = 1.\n    #[inline]\n    pub fn cross(self, other: Vec2) -> f64 {\n        self.x * other.y - self.y * other.x\n    }\n\n    /// Magnitude of vector.\n    ///\n    /// This is similar to `self.hypot2().sqrt()` but defers to the platform `hypot` method, which\n    /// in general will handle the case where `self.hypot2() > f64::MAX`.\n    #[inline]\n    pub fn hypot(self) -> f64 {\n        self.x.hypot(self.y)\n    }\n\n    /// Magnitude of vector.\n    ///\n    /// This is an alias for [`Vec2::hypot`].\n    #[inline]\n    pub fn length(self) -> f64 {\n        self.hypot()\n    }\n\n    /// Magnitude squared of vector.\n    #[inline]\n    pub fn hypot2(self) -> f64 {\n        self.dot(self)\n    }\n\n    /// Magnitude squared of vector.\n    ///\n    /// This is an alias for [`Vec2::hypot2`].\n    #[inline]\n    pub fn length_squared(self) -> f64 {\n        self.hypot2()\n    }\n\n    /// Find the angle in radians between this vector and the vector `Vec2 { x: 1.0, y: 0.0 }`\n    /// in the positive `y` direction.\n    ///\n    /// If the vector is interpreted as a complex number, this is the argument.\n    /// The angle is expressed in radians.\n    #[inline]\n    pub fn atan2(self) -> f64 {\n        self.y.atan2(self.x)\n    }\n\n    /// Find the angle in radians between this vector and the vector `Vec2 { x: 1.0, y: 0.0 }`\n    /// in the positive `y` direction.\n    ///\n    /// This is an alias for [`Vec2::atan2`].\n    #[inline]\n    pub fn angle(self) -> f64 {\n        self.atan2()\n    }\n\n    /// A unit vector of the given angle.\n    ///\n    /// With `th` at zero, the result is the positive X unit vector, and\n    /// at π/2, it is the positive Y unit vector. The angle is expressed\n    /// in radians.\n    ///\n    /// Thus, in a Y-down coordinate system (as is common for graphics),\n    /// it is a clockwise rotation, and in Y-up (traditional for math), it\n    /// is anti-clockwise. This convention is consistent with\n    /// [`Affine::rotate`].\n    ///\n    /// [`Affine::rotate`]: crate::Affine::rotate\n    #[inline]\n    pub fn from_angle(th: f64) -> Vec2 {\n        let (th_sin, th_cos) = th.sin_cos();\n        Vec2 {\n            x: th_cos,\n            y: th_sin,\n        }\n    }\n\n    /// Linearly interpolate between two vectors.\n    #[inline]\n    pub fn lerp(self, other: Vec2, t: f64) -> Vec2 {\n        self + t * (other - self)\n    }\n\n    /// Returns a vector of magnitude 1.0 with the same angle as `self`; i.e.\n    /// a unit/direction vector.\n    ///\n    /// This produces `NaN` values when the magnitude is `0`.\n    #[inline]\n    pub fn normalize(self) -> Vec2 {\n        self / self.hypot()\n    }\n\n    /// Returns a new `Vec2`,\n    /// with `x` and `y` rounded to the nearest integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Vec2;\n    /// let a = Vec2::new(3.3, 3.6).round();\n    /// let b = Vec2::new(3.0, -3.1).round();\n    /// assert_eq!(a.x, 3.0);\n    /// assert_eq!(a.y, 4.0);\n    /// assert_eq!(b.x, 3.0);\n    /// assert_eq!(b.y, -3.0);\n    /// ```\n    #[inline]\n    pub fn round(self) -> Vec2 {\n        Vec2::new(self.x.round(), self.y.round())\n    }\n\n    /// Returns a new `Vec2`,\n    /// with `x` and `y` rounded up to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Vec2;\n    /// let a = Vec2::new(3.3, 3.6).ceil();\n    /// let b = Vec2::new(3.0, -3.1).ceil();\n    /// assert_eq!(a.x, 4.0);\n    /// assert_eq!(a.y, 4.0);\n    /// assert_eq!(b.x, 3.0);\n    /// assert_eq!(b.y, -3.0);\n    /// ```\n    #[inline]\n    pub fn ceil(self) -> Vec2 {\n        Vec2::new(self.x.ceil(), self.y.ceil())\n    }\n\n    /// Returns a new `Vec2`,\n    /// with `x` and `y` rounded down to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Vec2;\n    /// let a = Vec2::new(3.3, 3.6).floor();\n    /// let b = Vec2::new(3.0, -3.1).floor();\n    /// assert_eq!(a.x, 3.0);\n    /// assert_eq!(a.y, 3.0);\n    /// assert_eq!(b.x, 3.0);\n    /// assert_eq!(b.y, -4.0);\n    /// ```\n    #[inline]\n    pub fn floor(self) -> Vec2 {\n        Vec2::new(self.x.floor(), self.y.floor())\n    }\n\n    /// Returns a new `Vec2`,\n    /// with `x` and `y` rounded away from zero to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Vec2;\n    /// let a = Vec2::new(3.3, 3.6).expand();\n    /// let b = Vec2::new(3.0, -3.1).expand();\n    /// assert_eq!(a.x, 4.0);\n    /// assert_eq!(a.y, 4.0);\n    /// assert_eq!(b.x, 3.0);\n    /// assert_eq!(b.y, -4.0);\n    /// ```\n    #[inline]\n    pub fn expand(self) -> Vec2 {\n        Vec2::new(self.x.expand(), self.y.expand())\n    }\n\n    /// Returns a new `Vec2`,\n    /// with `x` and `y` rounded towards zero to the nearest integer,\n    /// unless they are already an integer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use kurbo::Vec2;\n    /// let a = Vec2::new(3.3, 3.6).trunc();\n    /// let b = Vec2::new(3.0, -3.1).trunc();\n    /// assert_eq!(a.x, 3.0);\n    /// assert_eq!(a.y, 3.0);\n    /// assert_eq!(b.x, 3.0);\n    /// assert_eq!(b.y, -3.0);\n    /// ```\n    #[inline]\n    pub fn trunc(self) -> Vec2 {\n        Vec2::new(self.x.trunc(), self.y.trunc())\n    }\n\n    /// Is this Vec2 finite?\n    #[inline]\n    pub fn is_finite(self) -> bool {\n        self.x.is_finite() && self.y.is_finite()\n    }\n\n    /// Is this Vec2 NaN?\n    #[inline]\n    pub fn is_nan(self) -> bool {\n        self.x.is_nan() || self.y.is_nan()\n    }\n\n    /// Divides this Vec2 by a scalar.\n    ///\n    /// Unlike the division by scalar operator, which multiplies by the\n    /// reciprocal for performance, this performs the division\n    /// per-component for consistent rounding behavior.\n    pub(crate) fn div_exact(self, divisor: f64) -> Vec2 {\n        Vec2 {\n            x: self.x / divisor,\n            y: self.y / divisor,\n        }\n    }\n}\n\nimpl From<(f64, f64)> for Vec2 {\n    #[inline]\n    fn from(v: (f64, f64)) -> Vec2 {\n        Vec2 { x: v.0, y: v.1 }\n    }\n}\n\nimpl From<Vec2> for (f64, f64) {\n    #[inline]\n    fn from(v: Vec2) -> (f64, f64) {\n        (v.x, v.y)\n    }\n}\n\nimpl Add for Vec2 {\n    type Output = Vec2;\n\n    #[inline]\n    fn add(self, other: Vec2) -> Vec2 {\n        Vec2 {\n            x: self.x + other.x,\n            y: self.y + other.y,\n        }\n    }\n}\n\nimpl AddAssign for Vec2 {\n    #[inline]\n    fn add_assign(&mut self, other: Vec2) {\n        *self = Vec2 {\n            x: self.x + other.x,\n            y: self.y + other.y,\n        }\n    }\n}\n\nimpl Sub for Vec2 {\n    type Output = Vec2;\n\n    #[inline]\n    fn sub(self, other: Vec2) -> Vec2 {\n        Vec2 {\n            x: self.x - other.x,\n            y: self.y - other.y,\n        }\n    }\n}\n\nimpl SubAssign for Vec2 {\n    #[inline]\n    fn sub_assign(&mut self, other: Vec2) {\n        *self = Vec2 {\n            x: self.x - other.x,\n            y: self.y - other.y,\n        }\n    }\n}\n\nimpl Mul<f64> for Vec2 {\n    type Output = Vec2;\n\n    #[inline]\n    fn mul(self, other: f64) -> Vec2 {\n        Vec2 {\n            x: self.x * other,\n            y: self.y * other,\n        }\n    }\n}\n\nimpl MulAssign<f64> for Vec2 {\n    #[inline]\n    fn mul_assign(&mut self, other: f64) {\n        *self = Vec2 {\n            x: self.x * other,\n            y: self.y * other,\n        };\n    }\n}\n\nimpl Mul<Vec2> for f64 {\n    type Output = Vec2;\n\n    #[inline]\n    fn mul(self, other: Vec2) -> Vec2 {\n        other * self\n    }\n}\n\nimpl Div<f64> for Vec2 {\n    type Output = Vec2;\n\n    /// Note: division by a scalar is implemented by multiplying by the reciprocal.\n    ///\n    /// This is more efficient but has different roundoff behavior than division.\n    #[inline]\n    #[allow(clippy::suspicious_arithmetic_impl)]\n    fn div(self, other: f64) -> Vec2 {\n        self * other.recip()\n    }\n}\n\nimpl DivAssign<f64> for Vec2 {\n    #[inline]\n    fn div_assign(&mut self, other: f64) {\n        self.mul_assign(other.recip());\n    }\n}\n\nimpl Neg for Vec2 {\n    type Output = Vec2;\n\n    #[inline]\n    fn neg(self) -> Vec2 {\n        Vec2 {\n            x: -self.x,\n            y: -self.y,\n        }\n    }\n}\n\nimpl fmt::Display for Vec2 {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        write!(formatter, \"𝐯=(\")?;\n        fmt::Display::fmt(&self.x, formatter)?;\n        write!(formatter, \", \")?;\n        fmt::Display::fmt(&self.y, formatter)?;\n        write!(formatter, \")\")\n    }\n}\n\n// Conversions to and from mint\n#[cfg(feature = \"mint\")]\nimpl From<Vec2> for mint::Vector2<f64> {\n    #[inline]\n    fn from(p: Vec2) -> mint::Vector2<f64> {\n        mint::Vector2 { x: p.x, y: p.y }\n    }\n}\n\n#[cfg(feature = \"mint\")]\nimpl From<mint::Vector2<f64>> for Vec2 {\n    #[inline]\n    fn from(p: mint::Vector2<f64>) -> Vec2 {\n        Vec2 { x: p.x, y: p.y }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    #[test]\n    fn display() {\n        let v = Vec2::new(1.2332421, 532.10721213123);\n        let s = format!(\"{v:.2}\");\n        assert_eq!(s.as_str(), \"𝐯=(1.23, 532.11)\");\n    }\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "LICENSE.txt",
      "sha256": "a08554fab028af3af047e8588d32d019662c1b1bf07959a195a2f75fe340726b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Copyright 2019 Octavian Oncescu\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the\nSoftware without restriction, including without\nlimitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software\nis furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice\nshall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\nSHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\nIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE."
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/include/mimalloc-new-delete.h",
      "sha256": "dd4f25cae53209d45d73f8e6a2b9c219e8fc7434d97f20eba9af1a8b850030fd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2020 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_NEW_DELETE_H\n#define MIMALLOC_NEW_DELETE_H\n\n// ----------------------------------------------------------------------------\n// This header provides convenient overrides for the new and\n// delete operations in C++.\n//\n// This header should be included in only one source file!\n//\n// On Windows, or when linking dynamically with mimalloc, these\n// can be more performant than the standard new-delete operations.\n// See <https://en.cppreference.com/w/cpp/memory/new/operator_new>\n// ---------------------------------------------------------------------------\n#if defined(__cplusplus)\n  #include <new>\n  #include <mimalloc.h>\n\n  #if defined(_MSC_VER) && defined(_Ret_notnull_) && defined(_Post_writable_byte_size_)\n  // stay consistent with VCRT definitions\n  #define mi_decl_new(n)          mi_decl_nodiscard mi_decl_restrict _Ret_notnull_ _Post_writable_byte_size_(n)\n  #define mi_decl_new_nothrow(n)  mi_decl_nodiscard mi_decl_restrict _Ret_maybenull_ _Success_(return != NULL) _Post_writable_byte_size_(n)\n  #else\n  #define mi_decl_new(n)          mi_decl_nodiscard mi_decl_restrict\n  #define mi_decl_new_nothrow(n)  mi_decl_nodiscard mi_decl_restrict\n  #endif\n\n  void operator delete(void* p) noexcept              { mi_free(p); };\n  void operator delete[](void* p) noexcept            { mi_free(p); };\n\n  void operator delete  (void* p, const std::nothrow_t&) noexcept { mi_free(p); }\n  void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); }\n\n  mi_decl_new(n) void* operator new(std::size_t n) noexcept(false) { return mi_new(n); }\n  mi_decl_new(n) void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); }\n\n  mi_decl_new_nothrow(n) void* operator new  (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }\n  mi_decl_new_nothrow(n) void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }\n\n  #if (__cplusplus >= 201402L || _MSC_VER >= 1916)\n  void operator delete  (void* p, std::size_t n) noexcept { mi_free_size(p,n); };\n  void operator delete[](void* p, std::size_t n) noexcept { mi_free_size(p,n); };\n  #endif\n\n  #if (__cplusplus > 201402L || defined(__cpp_aligned_new))\n  void operator delete  (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete  (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };\n  void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };\n  void operator delete  (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n\n  void* operator new  (std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }\n  void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }\n  void* operator new  (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }\n  void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }\n  #endif\n#endif\n\n#endif // MIMALLOC_NEW_DELETE_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/include/mimalloc-override.h",
      "sha256": "21fcf61c4443341ac6bf6ea528af31dc7267e8e3456fc64bfd07704503032175",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2020 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_OVERRIDE_H\n#define MIMALLOC_OVERRIDE_H\n\n/* ----------------------------------------------------------------------------\nThis header can be used to statically redirect malloc/free and new/delete\nto the mimalloc variants. This can be useful if one can include this file on\neach source file in a project (but be careful when using external code to\nnot accidentally mix pointers from different allocators).\n-----------------------------------------------------------------------------*/\n\n#include <mimalloc.h>\n\n// Standard C allocation\n#define malloc(n)               mi_malloc(n)\n#define calloc(c,n)             mi_calloc(c,n)\n#define realloc(p,n)            mi_realloc(p,n)\n#define free(p)                 mi_free(p)\n\n#define strdup(s)               mi_strdup(s)\n#define strndup(s,n)            mi_strndup(s,n)\n#define realpath(f,n)           mi_realpath(f,n)\n\n// Microsoft extensions\n#define _expand(p,n)            mi_expand(p,n)\n#define _msize(p)               mi_usable_size(p)\n#define _recalloc(p,c,n)        mi_recalloc(p,c,n)\n\n#define _strdup(s)              mi_strdup(s)\n#define _strndup(s,n)           mi_strndup(s,n)\n#define _wcsdup(s)              mi_wcsdup(s)\n#define _mbsdup(s)              mi_mbsdup(s)\n#define _dupenv_s(buf,n,nm)     mi_dupenv_s(buf,n,nm)\n#define _wdupenv_s(buf,n,nm)    mi_wdupenv_s(buf,n,nm)\n\n// Various Posix and Unix variants\n#define reallocf(p,n)           mi_reallocf(p,n)\n#define malloc_size(p)          mi_usable_size(p)\n#define malloc_usable_size(p)   mi_usable_size(p)\n#define malloc_good_size(n)     mi_malloc_good_size(n)\n#define cfree(p)                mi_free(p)\n\n#define valloc(n)               mi_valloc(n)\n#define pvalloc(n)              mi_pvalloc(n)\n#define reallocarray(p,c,n)     mi_reallocarray(p,c,n)\n#define reallocarr(ptrp,c,n)    mi_reallocarr(ptrp,c,n)\n#define memalign(a,n)           mi_memalign(a,n)\n#define aligned_alloc(a,n)      mi_aligned_alloc(a,n)\n#define posix_memalign(p,a,n)   mi_posix_memalign(p,a,n)\n#define _posix_memalign(p,a,n)  mi_posix_memalign(p,a,n)\n\n// Microsoft aligned variants\n#define _aligned_malloc(n,a)                  mi_malloc_aligned(n,a)\n#define _aligned_realloc(p,n,a)               mi_realloc_aligned(p,n,a)\n#define _aligned_recalloc(p,c,n,a)            mi_aligned_recalloc(p,c,n,a)\n#define _aligned_msize(p,a,o)                 mi_usable_size(p)\n#define _aligned_free(p)                      mi_free(p)\n#define _aligned_offset_malloc(n,a,o)         mi_malloc_aligned_at(n,a,o)\n#define _aligned_offset_realloc(p,n,a,o)      mi_realloc_aligned_at(p,n,a,o)\n#define _aligned_offset_recalloc(p,c,n,a,o)   mi_recalloc_aligned_at(p,c,n,a,o)\n\n#endif // MIMALLOC_OVERRIDE_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/include/mimalloc-stats.h",
      "sha256": "95b4e031c2e8ec1e4abff7d904b90ae47f9bef8adcbafeacf911f43fa981cc94",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_STATS_H\n#define MIMALLOC_STATS_H\n\n#include <mimalloc.h>\n#include <stdint.h>\n\n#define MI_STAT_VERSION   4  // increased on every backward incompatible change\n\n// count allocation over time\ntypedef struct mi_stat_count_s {\n  int64_t total;                              // total allocated\n  int64_t peak;                               // peak allocation\n  int64_t current;                            // current allocation\n} mi_stat_count_t;\n\n// counters only increase\ntypedef struct mi_stat_counter_s {\n  int64_t total;                              // total count\n} mi_stat_counter_t;\n\n#define MI_STAT_FIELDS() \\\n  MI_STAT_COUNT(pages)                      /* count of mimalloc pages */ \\\n  MI_STAT_COUNT(reserved)                   /* reserved memory bytes */ \\\n  MI_STAT_COUNT(committed)                  /* committed bytes */ \\\n  MI_STAT_COUNTER(reset)                    /* reset bytes */ \\\n  MI_STAT_COUNTER(purged)                   /* purged bytes */ \\\n  MI_STAT_COUNT(page_committed)             /* committed memory inside pages */ \\\n  MI_STAT_COUNT(pages_abandoned)            /* abandoned pages count */ \\\n  MI_STAT_COUNT(threads)                    /* number of threads */ \\\n  MI_STAT_COUNT(malloc_normal)              /* allocated bytes <= MI_LARGE_OBJ_SIZE_MAX */ \\\n  MI_STAT_COUNT(malloc_huge)                /* allocated bytes in huge pages */ \\\n  MI_STAT_COUNT(malloc_requested)           /* malloc requested bytes */ \\\n  \\\n  MI_STAT_COUNTER(mmap_calls) \\\n  MI_STAT_COUNTER(commit_calls) \\\n  MI_STAT_COUNTER(reset_calls) \\\n  MI_STAT_COUNTER(purge_calls) \\\n  MI_STAT_COUNTER(arena_count)              /* number of memory arena's */ \\\n  MI_STAT_COUNTER(malloc_normal_count)      /* number of blocks <= MI_LARGE_OBJ_SIZE_MAX */ \\\n  MI_STAT_COUNTER(malloc_huge_count)        /* number of huge bloks */ \\\n  MI_STAT_COUNTER(malloc_guarded_count)     /* number of allocations with guard pages */ \\\n  \\\n  /* internal statistics */ \\\n  MI_STAT_COUNTER(arena_rollback_count) \\\n  MI_STAT_COUNTER(arena_purges) \\\n  MI_STAT_COUNTER(pages_extended)           /* number of page extensions */ \\\n  MI_STAT_COUNTER(pages_retire)             /* number of pages that are retired */ \\\n  MI_STAT_COUNTER(page_searches)            /* total pages searched for a fresh page */ \\\n  MI_STAT_COUNTER(page_searches_count)      /* searched count for a fresh page */ \\\n  /* only on v1 and v2 */ \\\n  MI_STAT_COUNT(segments) \\\n  MI_STAT_COUNT(segments_abandoned) \\\n  MI_STAT_COUNT(segments_cache) \\\n  MI_STAT_COUNT(_segments_reserved) \\\n  /* only on v3 */ \\\n  MI_STAT_COUNTER(pages_reclaim_on_alloc) \\\n  MI_STAT_COUNTER(pages_reclaim_on_free) \\\n  MI_STAT_COUNTER(pages_reabandon_full) \\\n  MI_STAT_COUNTER(pages_unabandon_busy_wait) \\\n\n\n// Define the statistics structure\n#define MI_BIN_HUGE             (73U)   // see types.h\n#define MI_STAT_COUNT(stat)     mi_stat_count_t stat;\n#define MI_STAT_COUNTER(stat)   mi_stat_counter_t stat;\n\ntypedef struct mi_stats_s\n{\n  size_t size;          // size of the mi_stats_t structure \n  size_t version;       \n\n  MI_STAT_FIELDS()\n\n  // future extension\n  mi_stat_count_t   _stat_reserved[4];\n  mi_stat_counter_t _stat_counter_reserved[4];\n\n  // size segregated statistics\n  mi_stat_count_t   malloc_bins[MI_BIN_HUGE+1];   // allocation per size bin\n  mi_stat_count_t   page_bins[MI_BIN_HUGE+1];     // pages allocated per size bin\n} mi_stats_t;\n\n#undef MI_STAT_COUNT\n#undef MI_STAT_COUNTER\n\n// helper\n#define mi_stats_t_decl(name)  mi_stats_t name = { 0 }; name.size = sizeof(mi_stats_t); name.version = MI_STAT_VERSION;\n\n// Exported definitions\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nmi_decl_export bool  mi_stats_get( mi_stats_t* stats ) mi_attr_noexcept;\nmi_decl_export char* mi_stats_get_json( size_t buf_size, char* buf ) mi_attr_noexcept;    // use mi_free to free the result if the input buf == NULL\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // MIMALLOC_STATS_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/include/mimalloc.h",
      "sha256": "ba52ce5c7708d8d54d4ffee372c5bac0921f5ac22e16445ca862818be1e7075f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2026, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_H\n#define MIMALLOC_H\n\n#define MI_MALLOC_VERSION 20302  // major + 2 digits minor + 2 digits patch\n\n// ------------------------------------------------------\n// Compiler specific attributes\n// ------------------------------------------------------\n\n#ifdef __cplusplus\n  #if (__cplusplus >= 201103L) || (_MSC_VER > 1900)  // C++11\n    #define mi_attr_noexcept   noexcept\n  #else\n    #define mi_attr_noexcept   throw()\n  #endif\n#else\n  #define mi_attr_noexcept\n#endif\n\n#if defined(__cplusplus) && (__cplusplus >= 201703)\n  #define mi_decl_nodiscard    [[nodiscard]]\n#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)  // includes clang, icc, and clang-cl\n  #define mi_decl_nodiscard    __attribute__((warn_unused_result))\n#elif defined(_HAS_NODISCARD)\n  #define mi_decl_nodiscard    _NODISCARD\n#elif (_MSC_VER >= 1700)\n  #define mi_decl_nodiscard    _Check_return_\n#else\n  #define mi_decl_nodiscard\n#endif\n\n#if defined(_MSC_VER) || defined(__MINGW32__)\n  #if !defined(MI_SHARED_LIB)\n    #define mi_decl_export\n  #elif defined(MI_SHARED_LIB_EXPORT)\n    #define mi_decl_export              __declspec(dllexport)\n  #else\n    #define mi_decl_export              __declspec(dllimport)\n  #endif\n  #if defined(__MINGW32__)\n    #define mi_decl_restrict\n    #define mi_attr_malloc              __attribute__((malloc))\n  #else\n    #if (_MSC_VER >= 1900) && !defined(__EDG__)\n      #define mi_decl_restrict          __declspec(allocator) __declspec(restrict)\n    #else\n      #define mi_decl_restrict          __declspec(restrict)\n    #endif\n    #define mi_attr_malloc\n  #endif\n  #define mi_cdecl                      __cdecl\n  #define mi_attr_alloc_size(s)\n  #define mi_attr_alloc_size2(s1,s2)\n  #define mi_attr_alloc_align(p)\n#elif defined(__GNUC__)                 // includes clang and icc\n  #if defined(MI_SHARED_LIB) && defined(MI_SHARED_LIB_EXPORT)\n    #define mi_decl_export              __attribute__((visibility(\"default\")))\n  #else\n    #define mi_decl_export\n  #endif\n  #define mi_cdecl                      // leads to warnings... __attribute__((cdecl))\n  #define mi_decl_restrict\n  #define mi_attr_malloc                __attribute__((malloc))\n  #if (defined(__clang_major__) && (__clang_major__ < 4)) || (__GNUC__ < 5)\n    #define mi_attr_alloc_size(s)\n    #define mi_attr_alloc_size2(s1,s2)\n    #define mi_attr_alloc_align(p)\n  #elif defined(__INTEL_COMPILER)\n    #define mi_attr_alloc_size(s)       __attribute__((alloc_size(s)))\n    #define mi_attr_alloc_size2(s1,s2)  __attribute__((alloc_size(s1,s2)))\n    #define mi_attr_alloc_align(p)\n  #else\n    #define mi_attr_alloc_size(s)       __attribute__((alloc_size(s)))\n    #define mi_attr_alloc_size2(s1,s2)  __attribute__((alloc_size(s1,s2)))\n    #define mi_attr_alloc_align(p)      __attribute__((alloc_align(p)))\n  #endif\n#else\n  #define mi_cdecl\n  #define mi_decl_export\n  #define mi_decl_restrict\n  #define mi_attr_malloc\n  #define mi_attr_alloc_size(s)\n  #define mi_attr_alloc_size2(s1,s2)\n  #define mi_attr_alloc_align(p)\n#endif\n\n// ------------------------------------------------------\n// Includes\n// ------------------------------------------------------\n\n#include <stddef.h>     // size_t\n#include <stdbool.h>    // bool\n#include <stdint.h>     // INTPTR_MAX\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// ------------------------------------------------------\n// Standard malloc interface\n// ------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc(size_t size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc(size_t count, size_t size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);\nmi_decl_nodiscard mi_decl_export void* mi_realloc(void* p, size_t newsize)      mi_attr_noexcept mi_attr_alloc_size(2);\nmi_decl_export void* mi_expand(void* p, size_t newsize)                         mi_attr_noexcept mi_attr_alloc_size(2);\n\nmi_decl_export void mi_free(void* p) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept mi_attr_malloc;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept mi_attr_malloc;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept;\n\n// ------------------------------------------------------\n// Extended functionality\n// ------------------------------------------------------\n#define MI_SMALL_WSIZE_MAX  (128)\n#define MI_SMALL_SIZE_MAX   (MI_SMALL_WSIZE_MAX*sizeof(void*))\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc(size_t size)       mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);\nmi_decl_nodiscard mi_decl_export void* mi_reallocn(void* p, size_t count, size_t size)        mi_attr_noexcept mi_attr_alloc_size2(2,3);\nmi_decl_nodiscard mi_decl_export void* mi_reallocf(void* p, size_t newsize)                   mi_attr_noexcept mi_attr_alloc_size(2);\n\nmi_decl_nodiscard mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export size_t mi_good_size(size_t size)     mi_attr_noexcept;\n\n// for compat with v3.\nmi_decl_export void mi_free_small(void* p) mi_attr_noexcept;\n\n// ------------------------------------------------------\n// Internals\n// ------------------------------------------------------\n\ntypedef void (mi_cdecl mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg);\nmi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg) mi_attr_noexcept;\n\ntypedef void (mi_cdecl mi_output_fun)(const char* msg, void* arg);\nmi_decl_export void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept;\n\ntypedef void (mi_cdecl mi_error_fun)(int err, void* arg);\nmi_decl_export void mi_register_error(mi_error_fun* fun, void* arg);\n\nmi_decl_export void mi_collect(bool force)    mi_attr_noexcept;\nmi_decl_export int  mi_version(void)          mi_attr_noexcept;\nmi_decl_export void mi_stats_reset(void)      mi_attr_noexcept;\nmi_decl_export void mi_stats_merge(void)      mi_attr_noexcept;\nmi_decl_export void mi_stats_print(void* out) mi_attr_noexcept;  // backward compatibility: `out` is ignored and should be NULL\nmi_decl_export void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept;\nmi_decl_export void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept;\nmi_decl_export void mi_options_print(void)    mi_attr_noexcept;\n\nmi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs,\n                                    size_t* current_rss, size_t* peak_rss,\n                                    size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept;\n\n\n// Generally do not use the following as these are usually called automatically\nmi_decl_export void mi_process_init(void)     mi_attr_noexcept;\nmi_decl_export void mi_cdecl mi_process_done(void) mi_attr_noexcept;\nmi_decl_export void mi_thread_init(void)      mi_attr_noexcept;\nmi_decl_export void mi_thread_done(void)      mi_attr_noexcept;\n\n\n// -------------------------------------------------------------------------------------\n// Aligned allocation\n// Note that `alignment` always follows `size` for consistency with unaligned\n// allocation, but unfortunately this differs from `posix_memalign` and `aligned_alloc`.\n// -------------------------------------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);\nmi_decl_nodiscard mi_decl_export void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2);\n\n\n// -----------------------------------------------------------------\n// Return allocated block size (if the return value is not NULL)\n// -----------------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_umalloc(size_t size, size_t* block_size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_ucalloc(size_t count, size_t size, size_t* block_size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);\nmi_decl_nodiscard mi_decl_export void* mi_urealloc(void* p, size_t newsize, size_t* block_size_pre, size_t* block_size_post) mi_attr_noexcept mi_attr_alloc_size(2);\nmi_decl_export void mi_ufree(void* p, size_t* block_size) mi_attr_noexcept;\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_umalloc_aligned(size_t size, size_t alignment, size_t* block_size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_uzalloc_aligned(size_t size, size_t alignment, size_t* block_size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_umalloc_small(size_t size, size_t* block_size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_uzalloc_small(size_t size, size_t* block_size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\n\n\n// -------------------------------------------------------------------------------------\n// Heaps: first-class, but can only allocate from the same thread that created it.\n// -------------------------------------------------------------------------------------\n\nstruct mi_heap_s;\ntypedef struct mi_heap_s mi_heap_t;\n\nmi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new(void);\nmi_decl_export void       mi_heap_delete(mi_heap_t* heap);\nmi_decl_export void       mi_heap_destroy(mi_heap_t* heap);\nmi_decl_export mi_heap_t* mi_heap_set_default(mi_heap_t* heap);\nmi_decl_export mi_heap_t* mi_heap_get_default(void);\nmi_decl_export mi_heap_t* mi_heap_get_backing(void);\nmi_decl_export void       mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept;\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\n\nmi_decl_nodiscard mi_decl_export void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize)              mi_attr_noexcept mi_attr_alloc_size(3);\nmi_decl_nodiscard mi_decl_export void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size)  mi_attr_noexcept mi_attr_alloc_size2(3,4);\nmi_decl_nodiscard mi_decl_export void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize)             mi_attr_noexcept mi_attr_alloc_size(3);\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s)            mi_attr_noexcept mi_attr_malloc;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept mi_attr_malloc;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept;\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3) mi_attr_alloc_align(4);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);\nmi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4);\nmi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3);\n\n\n// --------------------------------------------------------------------------------\n// Zero initialized re-allocation.\n// Only valid on memory that was originally allocated with zero initialization too.\n// e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc.\n// see <https://github.com/microsoft/mimalloc/issues/63#issuecomment-508272992>\n// --------------------------------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_export void* mi_rezalloc(void* p, size_t newsize)                mi_attr_noexcept mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export void* mi_recalloc(void* p, size_t newcount, size_t size)  mi_attr_noexcept mi_attr_alloc_size2(2,3);\n\nmi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(2,3) mi_attr_alloc_align(4);\nmi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(2,3);\n\nmi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize)                mi_attr_noexcept mi_attr_alloc_size(3);\nmi_decl_nodiscard mi_decl_export void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size)  mi_attr_noexcept mi_attr_alloc_size2(3,4);\n\nmi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4);\nmi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3);\nmi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(3,4) mi_attr_alloc_align(5);\nmi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(3,4);\n\n\n// ------------------------------------------------------\n// Analysis\n// ------------------------------------------------------\n\nmi_decl_export bool mi_heap_contains_block(mi_heap_t* heap, const void* p);\nmi_decl_export bool mi_heap_check_owned(mi_heap_t* heap, const void* p);\nmi_decl_export bool mi_check_owned(const void* p);\n\n// An area of heap space contains blocks of a single size.\ntypedef struct mi_heap_area_s {\n  void*  blocks;      // start of the area containing heap blocks\n  size_t reserved;    // bytes reserved for this area (virtual)\n  size_t committed;   // current available bytes for this area\n  size_t used;        // number of allocated blocks\n  size_t block_size;  // size in bytes of each block\n  size_t full_block_size; // size in bytes of a full block including padding and metadata.\n  int    heap_tag;    // heap tag associated with this area\n} mi_heap_area_t;\n\ntypedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg);\n\nmi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg);\n\n// Experimental\nmi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export bool mi_is_redirected(void) mi_attr_noexcept;\n\nmi_decl_export int   mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept;\nmi_decl_export int   mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept;\n\nmi_decl_export int   mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept;\nmi_decl_export bool  mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept;\n\nmi_decl_export void  mi_debug_show_arenas(void) mi_attr_noexcept;\nmi_decl_export void  mi_arenas_print(void) mi_attr_noexcept;\n\n// Experimental: heaps associated with specific memory arena's\ntypedef int mi_arena_id_t;\nmi_decl_export void* mi_arena_area(mi_arena_id_t arena_id, size_t* size);\nmi_decl_export int   mi_reserve_huge_os_pages_at_ex(size_t pages, int numa_node, size_t timeout_msecs, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept;\nmi_decl_export int   mi_reserve_os_memory_ex(size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept;\nmi_decl_export bool  mi_manage_os_memory_ex(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept;\n\n#if MI_MALLOC_VERSION >= 182\n// Create a heap that only allocates in the specified arena\nmi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new_in_arena(mi_arena_id_t arena_id);\n#endif\n\n\n// Experimental: allow sub-processes whose memory areas stay separated (and no reclamation between them)\n// Used for example for separate interpreters in one process.\ntypedef void* mi_subproc_id_t;\nmi_decl_export mi_subproc_id_t mi_subproc_main(void);\nmi_decl_export mi_subproc_id_t mi_subproc_new(void);\nmi_decl_export void mi_subproc_delete(mi_subproc_id_t subproc);\nmi_decl_export void mi_subproc_add_current_thread(mi_subproc_id_t subproc); // this should be called right after a thread is created (and no allocation has taken place yet)\n\n// Experimental: visit abandoned heap areas (that are not owned by a specific heap)\nmi_decl_export bool mi_abandoned_visit_blocks(mi_subproc_id_t subproc_id, int heap_tag, bool visit_blocks, mi_block_visit_fun* visitor, void* arg);\n\n// Experimental: objects followed by a guard page.\n// A sample rate of 0 disables guarded objects, while 1 uses a guard page for every object.\n// A seed of 0 uses a random start point. Only objects within the size bound are eligable for guard pages.\nmi_decl_export void mi_heap_guarded_set_sample_rate(mi_heap_t* heap, size_t sample_rate, size_t seed);\nmi_decl_export void mi_heap_guarded_set_size_bound(mi_heap_t* heap, size_t min, size_t max);\n\n// Experimental: communicate that the thread is part of a threadpool\nmi_decl_export void mi_thread_set_in_threadpool(void) mi_attr_noexcept;\n\n// Experimental: create a new heap with a specified heap tag. Set `allow_destroy` to false to allow the thread\n// to reclaim abandoned memory (with a compatible heap_tag and arena_id) but in that case `mi_heap_destroy` will\n// fall back to `mi_heap_delete`.\nmi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new_ex(int heap_tag, bool allow_destroy, mi_arena_id_t arena_id);\n\n// Experimental and unsafe: assumes the page of `p` is only accessed by the calling thread\nmi_decl_nodiscard mi_decl_export bool mi_unsafe_heap_page_is_under_utilized(mi_heap_t* heap, void* p, size_t perc_threshold) mi_attr_noexcept;\n\n// deprecated\nmi_decl_export int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept;\nmi_decl_export void mi_collect_reduce(size_t target_thread_owned) mi_attr_noexcept;\n\n\n\n// ------------------------------------------------------\n// Convenience\n// ------------------------------------------------------\n\n#define mi_malloc_tp(tp)                ((tp*)mi_malloc(sizeof(tp)))\n#define mi_zalloc_tp(tp)                ((tp*)mi_zalloc(sizeof(tp)))\n#define mi_calloc_tp(tp,n)              ((tp*)mi_calloc(n,sizeof(tp)))\n#define mi_mallocn_tp(tp,n)             ((tp*)mi_mallocn(n,sizeof(tp)))\n#define mi_reallocn_tp(p,tp,n)          ((tp*)mi_reallocn(p,n,sizeof(tp)))\n#define mi_recalloc_tp(p,tp,n)          ((tp*)mi_recalloc(p,n,sizeof(tp)))\n\n#define mi_heap_malloc_tp(hp,tp)        ((tp*)mi_heap_malloc(hp,sizeof(tp)))\n#define mi_heap_zalloc_tp(hp,tp)        ((tp*)mi_heap_zalloc(hp,sizeof(tp)))\n#define mi_heap_calloc_tp(hp,tp,n)      ((tp*)mi_heap_calloc(hp,n,sizeof(tp)))\n#define mi_heap_mallocn_tp(hp,tp,n)     ((tp*)mi_heap_mallocn(hp,n,sizeof(tp)))\n#define mi_heap_reallocn_tp(hp,p,tp,n)  ((tp*)mi_heap_reallocn(hp,p,n,sizeof(tp)))\n#define mi_heap_recalloc_tp(hp,p,tp,n)  ((tp*)mi_heap_recalloc(hp,p,n,sizeof(tp)))\n\n\n// ------------------------------------------------------\n// Compatibility with v3\n// ------------------------------------------------------\n\ntypedef mi_heap_t  mi_theap_t;\n\n#define mi_theap_get_default()            mi_heap_get_default()      \n#define mi_theap_set_default(hp)          mi_heap_set_default(hp)      \n#define mi_theap_collect(hp,force)        mi_heap_collect(hp,force)\n#define mi_theap_malloc(hp,sz)            mi_heap_malloc(hp,sz)\n#define mi_theap_zalloc(hp,sz)            mi_heap_zalloc(hp,sz)\n#define mi_theap_calloc(hp,cnt,sz)        mi_heap_calloc(hp,cnt,sz)\n#define mi_theap_malloc_small(hp,sz)      mi_heap_malloc_small(hp,sz)\n#define mi_theap_malloc_aligned(hp,sz,a)  mi_heap_malloc_aligned(hp,sz,a)\n#define mi_theap_realloc(hp,p,newsz)      mi_heap_realloc(hp,p,newsz)\n\n\n// ------------------------------------------------------\n// Options\n// ------------------------------------------------------\n\ntypedef enum mi_option_e {\n  // stable options\n  mi_option_show_errors,                // print error messages\n  mi_option_show_stats,                 // print statistics on termination\n  mi_option_verbose,                    // print verbose messages\n  // advanced options\n  mi_option_eager_commit,               // eager commit segments? (after `eager_commit_delay` segments) (=1)\n  mi_option_arena_eager_commit,         // eager commit arenas? Use 2 to enable just on overcommit systems (=2)\n  mi_option_purge_decommits,            // should a memory purge decommit? (=1). Set to 0 to use memory reset on a purge (instead of decommit)\n  mi_option_allow_large_os_pages,       // allow use of large (2 or 4 MiB) OS pages, implies eager commit.\n  mi_option_reserve_huge_os_pages,      // reserve N huge OS pages (1GiB pages) at startup\n  mi_option_reserve_huge_os_pages_at,   // reserve huge OS pages at a specific NUMA node\n  mi_option_reserve_os_memory,          // reserve specified amount of OS memory in an arena at startup (internally, this value is in KiB; use `mi_option_get_size`)\n  mi_option_deprecated_segment_cache,\n  mi_option_deprecated_page_reset,\n  mi_option_abandoned_page_purge,       // immediately purge delayed purges on thread termination\n  mi_option_deprecated_segment_reset,\n  mi_option_eager_commit_delay,         // the first N segments per thread are not eagerly committed (but per page in the segment on demand)\n  mi_option_purge_delay,                // memory purging is delayed by N milli seconds; use 0 for immediate purging or -1 for no purging at all. (=10)\n  mi_option_use_numa_nodes,             // 0 = use all available numa nodes, otherwise use at most N nodes.\n  mi_option_disallow_os_alloc,          // 1 = do not use OS memory for allocation (but only programmatically reserved arenas)\n  mi_option_os_tag,                     // tag used for OS logging (macOS only for now) (=100)\n  mi_option_max_errors,                 // issue at most N error messages\n  mi_option_max_warnings,               // issue at most N warning messages\n  mi_option_max_segment_reclaim,        // max. percentage of the abandoned segments can be reclaimed per try (=10%)\n  mi_option_destroy_on_exit,            // if set, release all memory on exit; sometimes used for dynamic unloading but can be unsafe\n  mi_option_arena_reserve,              // initial memory size for arena reservation (= 1 GiB on 64-bit) (internally, this value is in KiB; use `mi_option_get_size`)\n  mi_option_arena_purge_mult,           // multiplier for `purge_delay` for the purging delay for arenas (=10)\n  mi_option_purge_extend_delay,\n  mi_option_abandoned_reclaim_on_free,  // allow to reclaim an abandoned segment on a free (=1)\n  mi_option_disallow_arena_alloc,       // 1 = do not use arena's for allocation (except if using specific arena id's)\n  mi_option_retry_on_oom,               // retry on out-of-memory for N milli seconds (=400), set to 0 to disable retries. (only on windows)\n  mi_option_visit_abandoned,            // allow visiting heap blocks from abandoned threads (=0)\n  mi_option_guarded_min,                // only used when building with MI_GUARDED: minimal rounded object size for guarded objects (=0)\n  mi_option_guarded_max,                // only used when building with MI_GUARDED: maximal rounded object size for guarded objects (=0)\n  mi_option_guarded_precise,            // disregard minimal alignment requirement to always place guarded blocks exactly in front of a guard page (=0)\n  mi_option_guarded_sample_rate,        // 1 out of N allocations in the min/max range will be guarded (=1000)\n  mi_option_guarded_sample_seed,        // can be set to allow for a (more) deterministic re-execution when a guard page is triggered (=0)\n  mi_option_target_segments_per_thread, // experimental (=0)\n  mi_option_generic_collect,            // collect heaps every N (=10000) generic allocation calls\n  mi_option_allow_thp,                  // allow transparent huge pages? (=1) (on Android =0 by default). Set to 0 to disable THP for the process.\n  _mi_option_last,\n  // legacy option names\n  mi_option_large_os_pages = mi_option_allow_large_os_pages,\n  mi_option_eager_region_commit = mi_option_arena_eager_commit,\n  mi_option_reset_decommits = mi_option_purge_decommits,\n  mi_option_reset_delay = mi_option_purge_delay,\n  mi_option_abandoned_page_reset = mi_option_abandoned_page_purge,\n  mi_option_limit_os_alloc = mi_option_disallow_os_alloc\n} mi_option_t;\n\n\nmi_decl_nodiscard mi_decl_export bool mi_option_is_enabled(mi_option_t option);\nmi_decl_export void mi_option_enable(mi_option_t option);\nmi_decl_export void mi_option_disable(mi_option_t option);\nmi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable);\nmi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable);\n\nmi_decl_nodiscard mi_decl_export long   mi_option_get(mi_option_t option);\nmi_decl_nodiscard mi_decl_export long   mi_option_get_clamp(mi_option_t option, long min, long max);\nmi_decl_nodiscard mi_decl_export size_t mi_option_get_size(mi_option_t option);\nmi_decl_export void mi_option_set(mi_option_t option, long value);\nmi_decl_export void mi_option_set_default(mi_option_t option, long value);\n\n\n// -------------------------------------------------------------------------------------------------------\n// \"mi\" prefixed implementations of various posix, Unix, Windows, and C++ allocation functions.\n// (This can be convenient when providing overrides of these functions as done in `mimalloc-override.h`.)\n// note: we use `mi_cfree` as \"checked free\" and it checks if the pointer is in our heap before free-ing.\n// -------------------------------------------------------------------------------------------------------\n\nmi_decl_export void  mi_cfree(void* p) mi_attr_noexcept;\nmi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export size_t mi_malloc_size(const void* p)        mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export size_t mi_malloc_good_size(size_t size)     mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept;\n\nmi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size)   mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_valloc(size_t size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1);\n\nmi_decl_nodiscard mi_decl_export void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3);\nmi_decl_nodiscard mi_decl_export int   mi_reallocarr(void* ptrp, size_t count, size_t size) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept;\n\nmi_decl_export void mi_free_size(void* p, size_t size)                           mi_attr_noexcept;\nmi_decl_export void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept;\nmi_decl_export void mi_free_aligned(void* p, size_t alignment)                   mi_attr_noexcept;\nmi_decl_export int  mi_dupenv_s(char** buf, size_t* size, const char* name)      mi_attr_noexcept;\n\n// wide characters\n#include <wchar.h>  // wchar_t\nmi_decl_export int mi_wdupenv_s(wchar_t** buf, size_t* size, const wchar_t* name)       mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict wchar_t* mi_wcsdup(const wchar_t* s)  mi_attr_noexcept mi_attr_malloc;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s)  mi_attr_noexcept mi_attr_malloc;\n\n// The `mi_new` wrappers implement C++ semantics on out-of-memory instead of directly returning `NULL`.\n// (and call `std::get_new_handler` and potentially raise a `std::bad_alloc` exception).\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new(size_t size)                   mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_nothrow(size_t size)           mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_n(size_t count, size_t size)   mi_attr_malloc mi_attr_alloc_size2(1, 2);\nmi_decl_nodiscard mi_decl_export void* mi_new_realloc(void* p, size_t newsize)                mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export void* mi_new_reallocn(void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3);\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_alloc_new(mi_heap_t* heap, size_t size)                mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_alloc_new_n(mi_heap_t* heap, size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(2, 3);\n\n#ifdef __cplusplus\n}\n#endif\n\n// ---------------------------------------------------------------------------------------------\n// Implement the C++ std::allocator interface for use in STL containers.\n// (note: see `mimalloc-new-delete.h` for overriding the new/delete operators globally)\n// ---------------------------------------------------------------------------------------------\n#ifdef __cplusplus\n\n#include <cstddef>     // std::size_t\n#include <cstdint>     // PTRDIFF_MAX\n#if (__cplusplus >= 201103L) || (_MSC_VER > 1900)  // C++11\n#include <type_traits> // std::true_type\n#include <utility>     // std::forward\n#endif\n\ntemplate<class T> struct _mi_stl_allocator_common {\n  typedef T                 value_type;\n  typedef std::size_t       size_type;\n  typedef std::ptrdiff_t    difference_type;\n  typedef value_type&       reference;\n  typedef value_type const& const_reference;\n  typedef value_type*       pointer;\n  typedef value_type const* const_pointer;\n\n  #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900))  // C++11\n  using propagate_on_container_copy_assignment = std::true_type;\n  using propagate_on_container_move_assignment = std::true_type;\n  using propagate_on_container_swap            = std::true_type;\n  template <class U, class ...Args> void construct(U* p, Args&& ...args) { ::new(p) U(std::forward<Args>(args)...); }\n  template <class U> void destroy(U* p) mi_attr_noexcept { p->~U(); }\n  #else\n  void construct(pointer p, value_type const& val) { ::new(p) value_type(val); }\n  void destroy(pointer p) { p->~value_type(); }\n  #endif\n\n  size_type     max_size() const mi_attr_noexcept { return (PTRDIFF_MAX/sizeof(value_type)); }\n  pointer       address(reference x) const        { return &x; }\n  const_pointer address(const_reference x) const  { return &x; }\n};\n\ntemplate<class T> struct mi_stl_allocator : public _mi_stl_allocator_common<T> {\n  using typename _mi_stl_allocator_common<T>::size_type;\n  using typename _mi_stl_allocator_common<T>::value_type;\n  using typename _mi_stl_allocator_common<T>::pointer;\n  template <class U> struct rebind { typedef mi_stl_allocator<U> other; };\n\n  mi_stl_allocator()                                             mi_attr_noexcept = default;\n  mi_stl_allocator(const mi_stl_allocator&)                      mi_attr_noexcept = default;\n  template<class U> mi_stl_allocator(const mi_stl_allocator<U>&) mi_attr_noexcept { }\n  mi_stl_allocator  select_on_container_copy_construction() const { return *this; }\n  void              deallocate(T* p, size_type) { mi_free(p); }\n\n  #if (__cplusplus >= 201703L)  // C++17\n  mi_decl_nodiscard T* allocate(size_type count) { return static_cast<T*>(mi_new_n(count, sizeof(T))); }\n  mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); }\n  #else\n  mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast<pointer>(mi_new_n(count, sizeof(value_type))); }\n  #endif\n\n  #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900))  // C++11\n  using is_always_equal = std::true_type;\n  #endif\n};\n\ntemplate<class T1,class T2> bool operator==(const mi_stl_allocator<T1>& , const mi_stl_allocator<T2>& ) mi_attr_noexcept { return true; }\ntemplate<class T1,class T2> bool operator!=(const mi_stl_allocator<T1>& , const mi_stl_allocator<T2>& ) mi_attr_noexcept { return false; }\n\n\n#if (__cplusplus >= 201103L) || (_MSC_VER >= 1900)  // C++11\n#define MI_HAS_HEAP_STL_ALLOCATOR 1\n\n#include <memory>      // std::shared_ptr\n\n// Common base class for STL allocators in a specific heap\ntemplate<class T, bool _mi_destroy> struct _mi_heap_stl_allocator_common : public _mi_stl_allocator_common<T> {\n  using typename _mi_stl_allocator_common<T>::size_type;\n  using typename _mi_stl_allocator_common<T>::value_type;\n  using typename _mi_stl_allocator_common<T>::pointer;\n\n  _mi_heap_stl_allocator_common(mi_heap_t* hp) : heap(hp, [](mi_heap_t*) {}) {}    /* will not delete nor destroy the passed in heap */\n\n  #if (__cplusplus >= 201703L)  // C++17\n  mi_decl_nodiscard T* allocate(size_type count) { return static_cast<T*>(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(T))); }\n  mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); }\n  #else\n  mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast<pointer>(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(value_type))); }\n  #endif\n\n  #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900))  // C++11\n  using is_always_equal = std::false_type;\n  #endif\n\n  void collect(bool force) { mi_heap_collect(this->heap.get(), force); }\n  template<class U> bool is_equal(const _mi_heap_stl_allocator_common<U, _mi_destroy>& x) const { return (this->heap == x.heap); }\n\nprotected:\n  std::shared_ptr<mi_heap_t> heap;\n  template<class U, bool D> friend struct _mi_heap_stl_allocator_common;\n\n  _mi_heap_stl_allocator_common() {\n    mi_heap_t* hp = mi_heap_new();\n    this->heap.reset(hp, (_mi_destroy ? &heap_destroy : &heap_delete));  /* calls heap_delete/destroy when the refcount drops to zero */\n  }\n  _mi_heap_stl_allocator_common(const _mi_heap_stl_allocator_common& x) mi_attr_noexcept : heap(x.heap) { }\n  template<class U> _mi_heap_stl_allocator_common(const _mi_heap_stl_allocator_common<U, _mi_destroy>& x) mi_attr_noexcept : heap(x.heap) { }\n\nprivate:\n  static void heap_delete(mi_heap_t* hp)  { if (hp != NULL) { mi_heap_delete(hp); } }\n  static void heap_destroy(mi_heap_t* hp) { if (hp != NULL) { mi_heap_destroy(hp); } }\n};\n\n// STL allocator allocation in a specific heap\ntemplate<class T> struct mi_heap_stl_allocator : public _mi_heap_stl_allocator_common<T, false> {\n  using typename _mi_heap_stl_allocator_common<T, false>::size_type;\n  mi_heap_stl_allocator() : _mi_heap_stl_allocator_common<T, false>() { } // creates fresh heap that is deleted when the destructor is called\n  mi_heap_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, false>(hp) { }  // no delete nor destroy on the passed in heap\n  template<class U> mi_heap_stl_allocator(const mi_heap_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, false>(x) { }\n\n  mi_heap_stl_allocator select_on_container_copy_construction() const { return *this; }\n  void deallocate(T* p, size_type) { mi_free(p); }\n  template<class U> struct rebind { typedef mi_heap_stl_allocator<U> other; };\n};\n\ntemplate<class T1, class T2> bool operator==(const mi_heap_stl_allocator<T1>& x, const mi_heap_stl_allocator<T2>& y) mi_attr_noexcept { return (x.is_equal(y)); }\ntemplate<class T1, class T2> bool operator!=(const mi_heap_stl_allocator<T1>& x, const mi_heap_stl_allocator<T2>& y) mi_attr_noexcept { return (!x.is_equal(y)); }\n\n\n// STL allocator allocation in a specific heap, where `free` does nothing and\n// the heap is destroyed in one go on destruction -- use with care!\ntemplate<class T> struct mi_heap_destroy_stl_allocator : public _mi_heap_stl_allocator_common<T, true> {\n  using typename _mi_heap_stl_allocator_common<T, true>::size_type;\n  mi_heap_destroy_stl_allocator() : _mi_heap_stl_allocator_common<T, true>() { } // creates fresh heap that is destroyed when the destructor is called\n  mi_heap_destroy_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, true>(hp) { }  // no delete nor destroy on the passed in heap\n  template<class U> mi_heap_destroy_stl_allocator(const mi_heap_destroy_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, true>(x) { }\n\n  mi_heap_destroy_stl_allocator select_on_container_copy_construction() const { return *this; }\n  void deallocate(T*, size_type) { /* do nothing as we destroy the heap on destruct. */ }\n  template<class U> struct rebind { typedef mi_heap_destroy_stl_allocator<U> other; };\n};\n\ntemplate<class T1, class T2> bool operator==(const mi_heap_destroy_stl_allocator<T1>& x, const mi_heap_destroy_stl_allocator<T2>& y) mi_attr_noexcept { return (x.is_equal(y)); }\ntemplate<class T1, class T2> bool operator!=(const mi_heap_destroy_stl_allocator<T1>& x, const mi_heap_destroy_stl_allocator<T2>& y) mi_attr_noexcept { return (!x.is_equal(y)); }\n\n#endif // C++11\n\n#endif // __cplusplus\n\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/include/mimalloc/atomic.h",
      "sha256": "3a4f1df56ec523bb59e0de2bceccf8d0aa2f1465fcf1fd694000e7a4aa601287",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2024 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_ATOMIC_H\n#define MIMALLOC_ATOMIC_H\n\n// include windows.h or pthreads.h\n#if defined(_WIN32)\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#include <windows.h>\n#elif !defined(__wasi__) && (!defined(__EMSCRIPTEN__) || defined(__EMSCRIPTEN_PTHREADS__))\n#define  MI_USE_PTHREADS\n#include <pthread.h>\n#endif\n\n// --------------------------------------------------------------------------------------------\n// Atomics\n// We need to be portable between C, C++, and MSVC.\n// We base the primitives on the C/C++ atomics and create a minimal wrapper for MSVC in C compilation mode.\n// This is why we try to use only `uintptr_t` and `<type>*` as atomic types.\n// To gain better insight in the range of used atomics, we use explicitly named memory order operations\n// instead of passing the memory order as a parameter.\n// -----------------------------------------------------------------------------------------------\n\n#if defined(__cplusplus)\n// Use C++ atomics\n#include <atomic>\n#define  _Atomic(tp)              std::atomic<tp>\n#define  mi_atomic(name)          std::atomic_##name\n#define  mi_memory_order(name)    std::memory_order_##name\n#if (__cplusplus >= 202002L)      // c++20, see issue #571\n #define MI_ATOMIC_VAR_INIT(x)    x\n#elif !defined(ATOMIC_VAR_INIT)\n #define MI_ATOMIC_VAR_INIT(x)    x\n#else\n #define MI_ATOMIC_VAR_INIT(x)    ATOMIC_VAR_INIT(x)\n#endif\n#elif defined(_MSC_VER)\n// Use MSVC C wrapper for C11 atomics\n#define  _Atomic(tp)              tp\n#define  MI_ATOMIC_VAR_INIT(x)    x\n#define  mi_atomic(name)          mi_atomic_##name\n#define  mi_memory_order(name)    mi_memory_order_##name\n#else\n// Use C11 atomics\n#include <stdatomic.h>\n#define  mi_atomic(name)          atomic_##name\n#define  mi_memory_order(name)    memory_order_##name\n#if (__STDC_VERSION__ >= 201710L) // c17, see issue #735\n #define MI_ATOMIC_VAR_INIT(x)    x\n#elif !defined(ATOMIC_VAR_INIT)\n #define MI_ATOMIC_VAR_INIT(x)    x\n#else\n #define MI_ATOMIC_VAR_INIT(x)    ATOMIC_VAR_INIT(x)\n#endif\n#endif\n\n// Various defines for all used memory orders in mimalloc\n#define mi_atomic_cas_weak(p,expected,desired,mem_success,mem_fail)  \\\n  mi_atomic(compare_exchange_weak_explicit)(p,expected,desired,mem_success,mem_fail)\n\n#define mi_atomic_cas_strong(p,expected,desired,mem_success,mem_fail)  \\\n  mi_atomic(compare_exchange_strong_explicit)(p,expected,desired,mem_success,mem_fail)\n\n#define mi_atomic_load_acquire(p)                mi_atomic(load_explicit)(p,mi_memory_order(acquire))\n#define mi_atomic_load_relaxed(p)                mi_atomic(load_explicit)(p,mi_memory_order(relaxed))\n#define mi_atomic_store_release(p,x)             mi_atomic(store_explicit)(p,x,mi_memory_order(release))\n#define mi_atomic_store_relaxed(p,x)             mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed))\n#define mi_atomic_exchange_relaxed(p,x)          mi_atomic(exchange_explicit)(p,x,mi_memory_order(relaxed))\n#define mi_atomic_exchange_release(p,x)          mi_atomic(exchange_explicit)(p,x,mi_memory_order(release))\n#define mi_atomic_exchange_acq_rel(p,x)          mi_atomic(exchange_explicit)(p,x,mi_memory_order(acq_rel))\n#define mi_atomic_cas_weak_release(p,exp,des)    mi_atomic_cas_weak(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed))\n#define mi_atomic_cas_weak_acq_rel(p,exp,des)    mi_atomic_cas_weak(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire))\n#define mi_atomic_cas_strong_release(p,exp,des)  mi_atomic_cas_strong(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed))\n#define mi_atomic_cas_strong_acq_rel(p,exp,des)  mi_atomic_cas_strong(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire))\n\n#define mi_atomic_add_relaxed(p,x)               mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(relaxed))\n#define mi_atomic_sub_relaxed(p,x)               mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(relaxed))\n#define mi_atomic_add_acq_rel(p,x)               mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(acq_rel))\n#define mi_atomic_sub_acq_rel(p,x)               mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(acq_rel))\n#define mi_atomic_and_acq_rel(p,x)               mi_atomic(fetch_and_explicit)(p,x,mi_memory_order(acq_rel))\n#define mi_atomic_or_acq_rel(p,x)                mi_atomic(fetch_or_explicit)(p,x,mi_memory_order(acq_rel))\n\n#define mi_atomic_increment_relaxed(p)           mi_atomic_add_relaxed(p,(uintptr_t)1)\n#define mi_atomic_decrement_relaxed(p)           mi_atomic_sub_relaxed(p,(uintptr_t)1)\n#define mi_atomic_increment_acq_rel(p)           mi_atomic_add_acq_rel(p,(uintptr_t)1)\n#define mi_atomic_decrement_acq_rel(p)           mi_atomic_sub_acq_rel(p,(uintptr_t)1)\n\nstatic inline void mi_atomic_yield(void);\nstatic inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add);\nstatic inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub);\n\n\n#if defined(__cplusplus) || !defined(_MSC_VER)\n\n// In C++/C11 atomics we have polymorphic atomics so can use the typed `ptr` variants (where `tp` is the type of atomic value)\n// We use these macros so we can provide a typed wrapper in MSVC in C compilation mode as well\n#define mi_atomic_load_ptr_acquire(tp,p)                mi_atomic_load_acquire(p)\n#define mi_atomic_load_ptr_relaxed(tp,p)                mi_atomic_load_relaxed(p)\n\n// In C++ we need to add casts to help resolve templates if NULL is passed\n#if defined(__cplusplus)\n#define mi_atomic_store_ptr_release(tp,p,x)             mi_atomic_store_release(p,(tp*)x)\n#define mi_atomic_store_ptr_relaxed(tp,p,x)             mi_atomic_store_relaxed(p,(tp*)x)\n#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des)    mi_atomic_cas_weak_release(p,exp,(tp*)des)\n#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des)    mi_atomic_cas_weak_acq_rel(p,exp,(tp*)des)\n#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des)  mi_atomic_cas_strong_release(p,exp,(tp*)des)\n#define mi_atomic_cas_ptr_strong_acq_rel(tp,p,exp,des)  mi_atomic_cas_strong_acq_rel(p,exp,(tp*)des)\n#define mi_atomic_exchange_ptr_relaxed(tp,p,x)          mi_atomic_exchange_relaxed(p,(tp*)x)\n#define mi_atomic_exchange_ptr_release(tp,p,x)          mi_atomic_exchange_release(p,(tp*)x)\n#define mi_atomic_exchange_ptr_acq_rel(tp,p,x)          mi_atomic_exchange_acq_rel(p,(tp*)x)\n#else\n#define mi_atomic_store_ptr_release(tp,p,x)             mi_atomic_store_release(p,x)\n#define mi_atomic_store_ptr_relaxed(tp,p,x)             mi_atomic_store_relaxed(p,x)\n#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des)    mi_atomic_cas_weak_release(p,exp,des)\n#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des)    mi_atomic_cas_weak_acq_rel(p,exp,des)\n#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des)  mi_atomic_cas_strong_release(p,exp,des)\n#define mi_atomic_cas_ptr_strong_acq_rel(tp,p,exp,des)  mi_atomic_cas_strong_acq_rel(p,exp,des)\n#define mi_atomic_exchange_ptr_relaxed(tp,p,x)          mi_atomic_exchange_relaxed(p,x)\n#define mi_atomic_exchange_ptr_release(tp,p,x)          mi_atomic_exchange_release(p,x)\n#define mi_atomic_exchange_ptr_acq_rel(tp,p,x)          mi_atomic_exchange_acq_rel(p,x)\n#endif\n\n// These are used by the statistics\nstatic inline int64_t mi_atomic_addi64_relaxed(volatile int64_t* p, int64_t add) {\n  return mi_atomic(fetch_add_explicit)((_Atomic(int64_t)*)p, add, mi_memory_order(relaxed));\n}\nstatic inline void mi_atomic_void_addi64_relaxed(volatile int64_t* p, const volatile int64_t* padd) {\n  const int64_t add = mi_atomic_load_relaxed((_Atomic(int64_t)*)padd);\n  if (add != 0) {\n    mi_atomic(fetch_add_explicit)((_Atomic(int64_t)*)p, add, mi_memory_order(relaxed));\n  }\n}\nstatic inline void mi_atomic_maxi64_relaxed(volatile int64_t* p, int64_t x) {\n  int64_t current = mi_atomic_load_relaxed((_Atomic(int64_t)*)p);\n  while (current < x && !mi_atomic_cas_weak_release((_Atomic(int64_t)*)p, &current, x)) { /* nothing */ };\n}\n\n// Used by timers\n#define mi_atomic_loadi64_acquire(p)            mi_atomic(load_explicit)(p,mi_memory_order(acquire))\n#define mi_atomic_loadi64_relaxed(p)            mi_atomic(load_explicit)(p,mi_memory_order(relaxed))\n#define mi_atomic_storei64_release(p,x)         mi_atomic(store_explicit)(p,x,mi_memory_order(release))\n#define mi_atomic_storei64_relaxed(p,x)         mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed))\n\n#define mi_atomic_casi64_strong_acq_rel(p,e,d)  mi_atomic_cas_strong_acq_rel(p,e,d)\n#define mi_atomic_addi64_acq_rel(p,i)           mi_atomic_add_acq_rel(p,i)\n\n\n#elif defined(_MSC_VER)\n\n// Deprecated: MSVC plain C compilation wrapper that uses Interlocked operations to model C11 atomics.\n// It is recommended to always compile as C++ when using MSVC.\n\n#include <intrin.h>\n#ifdef _WIN64\ntypedef LONG64        msc_intptr_t;\n#define MI_MSC_64(f)  f##64\n#define MI_MSC_XX(f)  f##64\n#else\ntypedef LONG          msc_intptr_t;\n#define MI_MSC_64(f)  f\n#define MI_MSC_XX(f)  f##32\n#endif\n\ntypedef enum mi_memory_order_e {\n  mi_memory_order_relaxed,\n  mi_memory_order_consume,\n  mi_memory_order_acquire,\n  mi_memory_order_release,\n  mi_memory_order_acq_rel,\n  mi_memory_order_seq_cst\n} mi_memory_order;\n\nstatic inline uintptr_t mi_atomic_fetch_add_explicit(_Atomic(uintptr_t)*p, uintptr_t add, mi_memory_order mo) {\n  (void)(mo);\n  return (uintptr_t)MI_MSC_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, (msc_intptr_t)add);\n}\nstatic inline uintptr_t mi_atomic_fetch_sub_explicit(_Atomic(uintptr_t)*p, uintptr_t sub, mi_memory_order mo) {\n  (void)(mo);\n  return (uintptr_t)MI_MSC_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, -((msc_intptr_t)sub));\n}\nstatic inline uintptr_t mi_atomic_fetch_and_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {\n  (void)(mo);\n  return (uintptr_t)MI_MSC_64(_InterlockedAnd)((volatile msc_intptr_t*)p, (msc_intptr_t)x);\n}\nstatic inline uintptr_t mi_atomic_fetch_or_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {\n  (void)(mo);\n  return (uintptr_t)MI_MSC_64(_InterlockedOr)((volatile msc_intptr_t*)p, (msc_intptr_t)x);\n}\nstatic inline bool mi_atomic_compare_exchange_strong_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) {\n  (void)(mo1); (void)(mo2);\n  const uintptr_t read = (uintptr_t)MI_MSC_64(_InterlockedCompareExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)desired, (msc_intptr_t)(*expected));\n  if (read == *expected) {\n    return true;\n  }\n  else {\n    *expected = read;\n    return false;\n  }\n}\nstatic inline bool mi_atomic_compare_exchange_weak_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) {\n  return mi_atomic_compare_exchange_strong_explicit(p, expected, desired, mo1, mo2);\n}\nstatic inline uintptr_t mi_atomic_exchange_explicit(_Atomic(uintptr_t)*p, uintptr_t exchange, mi_memory_order mo) {\n  (void)(mo);\n  return (uintptr_t)MI_MSC_64(_InterlockedExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)exchange);\n}\nstatic inline void mi_atomic_thread_fence(mi_memory_order mo) {\n  (void)(mo);\n  _Atomic(uintptr_t) x = 0;\n  mi_atomic_exchange_explicit(&x, 1, mo);\n}\n\nstatic inline uintptr_t mi_atomic_load_explicit(_Atomic(uintptr_t) const* p, mi_memory_order mo) {\n  (void)(mo);\n  // assert(mo<=mi_memory_order_acquire); // others are not used by mimalloc\n  #if defined(_M_IX86) || defined(_M_X64)\n    return (uintptr_t)MI_MSC_XX(__iso_volatile_load)((volatile const intptr_t*)p);\n  #elif defined(_M_ARM) || defined(_M_ARM64)\n    if (mo == mi_memory_order_relaxed) {\n      return (uintptr_t)MI_MSC_XX(__iso_volatile_load)((volatile const intptr_t*)p);\n    }\n    else if (mo <= mi_memory_order_acquire) {\n      return MI_MSC_XX(__ldar)((volatile const uintptr_t*)p);\n    }\n    else {\n      const uintptr_t u = (uintptr_t)MI_MSC_XX(__iso_volatile_load)((volatile const intptr_t*)p);\n      __dmb(15);  // _ARM(64)_BARRIER_SY\n      return u;\n    }\n  #else\n    #warning \"define mi_atomic_load_explicit for MSVC C compilation on this platform (which should be readonly, see issue #1277)\"\n    return MI_MSC_XX(__iso_volatile_load)((volatile const intptr_t*)p);\n  #endif\n}\nstatic inline void mi_atomic_store_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {\n  (void)(mo);\n  // assert(mo<=mi_memory_order_release); // others are not used by mimalloc\n  #if defined(_M_IX86) || defined(_M_X64)\n    MI_MSC_XX(__iso_volatile_store)((volatile intptr_t*)p, x);\n  #elif defined(_M_ARM) || defined(_M_ARM64)\n    if (mo == mi_memory_order_relaxed) {\n      MI_MSC_XX(__iso_volatile_store)((volatile intptr_t*)p, x);\n    }\n    else if (mo <= mi_memory_order_release) {\n      MI_MSC_XX(__stlr)((volatile uintptr_t*)p,x);\n    }\n    else {\n      mi_atomic_exchange_explicit(p, x, mo);\n    }\n  #else\n    mi_atomic_exchange_explicit(p, x, mo);\n  #endif\n}\n\nstatic inline int64_t mi_atomic_loadi64_explicit(_Atomic(int64_t)*p, mi_memory_order mo) {\n  (void)(mo);\n  // assert(mo<=mi_memory_order_acquire); // others are not used by mimalloc\n  #if defined(_M_IX86) || defined(_M_X64)\n    return __iso_volatile_load64((volatile const int64_t*)p);\n  #elif defined(_M_ARM) || defined(_M_ARM64)\n    if (mo == mi_memory_order_relaxed) {\n      return __iso_volatile_load64((volatile const int64_t*)p);\n    }\n    #if defined(_M_ARM64)\n    else if (mo <= mi_memory_order_acquire) {\n      return __ldar64((volatile const uintptr_t*)p);\n    }\n    #endif\n    else {\n      const int64_t i = __iso_volatile_load64((volatile const int64_t*)p);\n      __dmb(15);  // _ARM(64)_BARRIER_SY\n      return i;\n    }\n  #else\n    #warning \"define mi_atomic_loadi64_explicit for MSVC C compilation on this platform (which should be readonly, see issue #1277)\"\n    return __iso_volatile_load64((volatile const int64_t*)p);\n  #endif\n}\n\nstatic inline void mi_atomic_storei64_explicit(_Atomic(int64_t)*p, int64_t x, mi_memory_order mo) {\n  (void)(mo);\n  // assert(mo<=mi_memory_order_release); // others are not used by mimalloc\n  #if defined(_M_IX86) || defined(_M_X64)\n    __iso_volatile_store64((volatile int64_t*)p,x);\n  #elif defined(_M_ARM) || defined(_M_ARM64)\n    if (mo == mi_memory_order_relaxed) {\n      __iso_volatile_store64((volatile int64_t*)p,x);\n    }\n    #if defined(_M_ARM64)\n    else if (mo == mi_memory_order_release) {\n      __stlr64((volatile uint64_t*)p, (uint64_t)x);\n    }\n    #endif\n    else {\n      InterlockedExchange64(p, x);\n    }\n  #else\n    InterlockedExchange64(p, x);\n  #endif\n}\n\n// These are used by the statistics\nstatic inline int64_t mi_atomic_addi64_relaxed(volatile _Atomic(int64_t)*p, int64_t add) {\n  #ifdef _WIN64\n    return (int64_t)mi_atomic_addi((int64_t*)p, add);\n  #elif defined(_M_ARM)\n    return _InterlockedExchangeAdd64(p, add);\n  #else\n    // x86\n    int64_t current;\n    int64_t sum;\n    do {\n      current = __iso_volatile_load64((volatile const int64_t*)p);\n      sum = current + add;\n    } while (_InterlockedCompareExchange64(p, sum, current) != current);\n    return current;\n  #endif\n}\nstatic inline void mi_atomic_void_addi64_relaxed(volatile int64_t* p, const volatile int64_t* padd) {\n  const int64_t add = *padd;\n  if (add != 0) {\n    mi_atomic_addi64_relaxed((volatile _Atomic(int64_t)*)p, add);\n  }\n}\n\nstatic inline void mi_atomic_maxi64_relaxed(volatile _Atomic(int64_t)*p, int64_t x) {\n  int64_t current;\n  do {\n    current = *p;\n  } while (current < x && _InterlockedCompareExchange64(p, x, current) != current);\n}\n\nstatic inline void mi_atomic_addi64_acq_rel(volatile _Atomic(int64_t*)p, int64_t i) {\n  mi_atomic_addi64_relaxed(p, i);\n}\n\nstatic inline bool mi_atomic_casi64_strong_acq_rel(volatile _Atomic(int64_t*)p, int64_t* exp, int64_t des) {\n  const int64_t read = _InterlockedCompareExchange64(p, des, *exp);\n  if (read == *exp) {\n    return true;\n  }\n  else {\n    *exp = read;\n    return false;\n  }\n}\n\n// The pointer macros cast to `uintptr_t`.\n#define mi_atomic_load_ptr_acquire(tp,p)                (tp*)mi_atomic_load_acquire((_Atomic(uintptr_t)*)(p))\n#define mi_atomic_load_ptr_relaxed(tp,p)                (tp*)mi_atomic_load_relaxed((_Atomic(uintptr_t)*)(p))\n#define mi_atomic_store_ptr_release(tp,p,x)             mi_atomic_store_release((_Atomic(uintptr_t)*)(p),(uintptr_t)(x))\n#define mi_atomic_store_ptr_relaxed(tp,p,x)             mi_atomic_store_relaxed((_Atomic(uintptr_t)*)(p),(uintptr_t)(x))\n#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des)    mi_atomic_cas_weak_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)\n#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des)    mi_atomic_cas_weak_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)\n#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des)  mi_atomic_cas_strong_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)\n#define mi_atomic_cas_ptr_strong_acq_rel(tp,p,exp,des)  mi_atomic_cas_strong_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)\n#define mi_atomic_exchange_ptr_relaxed(tp,p,x)          (tp*)mi_atomic_exchange_relaxed((_Atomic(uintptr_t)*)(p),(uintptr_t)x)\n#define mi_atomic_exchange_ptr_release(tp,p,x)          (tp*)mi_atomic_exchange_release((_Atomic(uintptr_t)*)(p),(uintptr_t)x)\n#define mi_atomic_exchange_ptr_acq_rel(tp,p,x)          (tp*)mi_atomic_exchange_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t)x)\n\n#define mi_atomic_loadi64_acquire(p)    mi_atomic(loadi64_explicit)(p,mi_memory_order(acquire))\n#define mi_atomic_loadi64_relaxed(p)    mi_atomic(loadi64_explicit)(p,mi_memory_order(relaxed))\n#define mi_atomic_storei64_release(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(release))\n#define mi_atomic_storei64_relaxed(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(relaxed))\n\n\n#endif\n\n\n// Atomically add a signed value; returns the previous value.\nstatic inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add) {\n  return (intptr_t)mi_atomic_add_acq_rel((_Atomic(uintptr_t)*)p, (uintptr_t)add);\n}\n\n// Atomically subtract a signed value; returns the previous value.\nstatic inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub) {\n  return (intptr_t)mi_atomic_addi(p, -sub);\n}\n\n\n// ----------------------------------------------------------------------\n// Once and Guard\n// ----------------------------------------------------------------------\n\ntypedef _Atomic(uintptr_t) mi_atomic_guard_t;\n\n// Allows only one thread to execute at a time (without blocking anyone)\n#define mi_atomic_guard(guard) \\\n  uintptr_t _mi_guard_expected = 0; \\\n  for(bool _mi_guard_once = true; \\\n      _mi_guard_once && mi_atomic_cas_strong_acq_rel(guard,&_mi_guard_expected,(uintptr_t)1); \\\n      (mi_atomic_store_release(guard,(uintptr_t)0), _mi_guard_once = false) )\n\n\n\n// ----------------------------------------------------------------------\n// Yield\n// ----------------------------------------------------------------------\n\n#if defined(_WIN32)\nstatic inline void mi_atomic_yield(void) {\n  YieldProcessor();  // see issue #1215 and #1225 why this is preferred over __yield or SwitchToThread\n}\n#elif defined(__SSE2__)\n#include <emmintrin.h>\nstatic inline void mi_atomic_yield(void) {\n  _mm_pause();\n}\n#elif (defined(__GNUC__) || defined(__clang__)) && \\\n      (defined(__x86_64__) || defined(__i386__) || \\\n       defined(__aarch64__) || defined(__arm__) || \\\n       defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__POWERPC__))\n#if defined(__x86_64__) || defined(__i386__)\nstatic inline void mi_atomic_yield(void) {\n  __asm__ volatile (\"pause\" ::: \"memory\");\n}\n#elif defined(__aarch64__)\nstatic inline void mi_atomic_yield(void) {\n  __asm__ volatile(\"isb\");\n}\n#elif defined(__arm__)\n#if __ARM_ARCH >= 7\nstatic inline void mi_atomic_yield(void) {\n  __asm__ volatile(\"yield\" ::: \"memory\");\n}\n#else\nstatic inline void mi_atomic_yield(void) {\n  __asm__ volatile (\"nop\" ::: \"memory\");\n}\n#endif\n#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__POWERPC__)\n#ifdef __APPLE__\nstatic inline void mi_atomic_yield(void) {\n  __asm__ volatile (\"or r27,r27,r27\" ::: \"memory\");\n}\n#else\nstatic inline void mi_atomic_yield(void) {\n  __asm__ __volatile__ (\"or 27,27,27\" ::: \"memory\");\n}\n#endif\n#endif\n#elif defined(__sun)\n#include <synch.h>\nstatic inline void mi_atomic_yield(void) {\n  smt_pause();\n}\n#elif defined(__wasi__)\n#include <sched.h>\nstatic inline void mi_atomic_yield(void) {\n  sched_yield();\n}\n// Fallback for other archs\n#elif defined(__cplusplus)\n#include <thread>\nstatic inline void mi_atomic_yield(void) {\n  std::this_thread::yield();\n}\n#else\n#include <unistd.h>\nstatic inline void mi_atomic_yield(void) {\n  sleep(0);\n}\n#endif\n\n\n// ----------------------------------------------------------------------\n// Locks\n// These should be light-weight in-process only locks.\n// Only used for reserving arena's and to maintain the abandoned list.\n// ----------------------------------------------------------------------\n#if _MSC_VER\n#pragma warning(disable:26110)  // unlock with holding lock\n#endif\n\n#define mi_lock(lock)                  for(bool _mi_go = (mi_lock_acquire(lock),true); _mi_go; (mi_lock_release(lock), _mi_go=false) )\n#define mi_lock_maybe(lock,acquire)    for(bool _mi_go = (acquire ? (mi_lock_acquire(lock),true) : true); _mi_go; _mi_go = (acquire ? (mi_lock_release(lock),false) : false) )\n\n\n#if defined(_WIN32)\n\ntypedef struct mi_lock_s {\n  SRWLOCK mutex;    // slim reader-writer lock\n} mi_lock_t;\n\n#define MI_LOCK_INITIALIZER   { SRWLOCK_INIT }\n\nstatic inline bool mi_lock_try_acquire(mi_lock_t* lock) {\n  return TryAcquireSRWLockExclusive(&lock->mutex);\n}\nstatic inline void mi_lock_acquire(mi_lock_t* lock) {\n  AcquireSRWLockExclusive(&lock->mutex);\n}\nstatic inline void mi_lock_release(mi_lock_t* lock) {\n  ReleaseSRWLockExclusive(&lock->mutex);\n}\nstatic inline void mi_lock_init(mi_lock_t* lock) {\n  InitializeSRWLock(&lock->mutex);\n}\nstatic inline void mi_lock_done(mi_lock_t* lock) {\n  (void)(lock);\n}\n\n#elif defined(MI_USE_PTHREADS)\n\n#include <string.h> // memcpy\nvoid _mi_error_message(int err, const char* fmt, ...);\n\ntypedef struct mi_lock_s {\n  pthread_mutex_t mutex;\n} mi_lock_t;\n\n#define MI_LOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }\n\nstatic inline bool mi_lock_try_acquire(mi_lock_t* lock) {\n  return (pthread_mutex_trylock(&lock->mutex) == 0);\n}\nstatic inline void mi_lock_acquire(mi_lock_t* lock) {\n  const int err = pthread_mutex_lock(&lock->mutex);\n  if (err != 0) {\n    _mi_error_message(err, \"internal error: lock cannot be acquired (err %i)\\n\", err);\n  }\n}\nstatic inline void mi_lock_release(mi_lock_t* lock) {\n  pthread_mutex_unlock(&lock->mutex);\n}\nstatic inline void mi_lock_init(mi_lock_t* lock) {\n  if(lock==NULL) return;\n  // use this instead of pthread_mutex_init since that can cause allocation on some platforms (and recursively initialize)\n  const pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;\n  memcpy(&lock->mutex,&mutex,sizeof(mutex));\n}\nstatic inline void mi_lock_done(mi_lock_t* lock) {\n  pthread_mutex_destroy(&lock->mutex);\n}\n\n#elif defined(__cplusplus)\n\n#include <thread>\n#include <mutex>\n#include <new>\n\ntypedef struct mi_lock_s {\n  std::mutex mutex;\n} mi_lock_t;\n\n#define MI_LOCK_INITIALIZER   { }\n\nstatic inline bool mi_lock_try_acquire(mi_lock_t* lock) {\n  return lock->mutex.try_lock();\n}\nstatic inline void mi_lock_acquire(mi_lock_t* lock) {\n  lock->mutex.lock();\n}\nstatic inline void mi_lock_release(mi_lock_t* lock) {\n  lock->mutex.unlock();\n}\nstatic inline void mi_lock_init(mi_lock_t* lock) {\n  new(&lock->mutex) std::mutex();\n}\nstatic inline void mi_lock_done(mi_lock_t* lock) {\n  (void)(lock);\n}\n\n#else\n\n// fall back to poor man's locks.\n// this should only be the case in a single-threaded environment (like __wasi__)\n#include <errno.h>\n#ifndef EFAULT\n#define EFAULT (14)\n#endif\nvoid _mi_error_message(int err, const char* fmt, ...);\n\ntypedef struct mi_lock_s {\n  _Atomic(uintptr_t) mutex;\n} mi_lock_t;\n\n#define MI_LOCK_INITIALIZER  { MI_ATOMIC_VAR_INIT(0) }\n\nstatic inline bool mi_lock_try_acquire(mi_lock_t* lock) {\n  uintptr_t expected = 0;\n  return mi_atomic_cas_strong_acq_rel(&lock->mutex, &expected, (uintptr_t)1);\n}\nstatic inline void mi_lock_acquire(mi_lock_t* lock) {\n  for (int i = 0; i < 10000; i++) {  // for at most 10000 tries?\n    if (mi_lock_try_acquire(lock)) return;\n    mi_atomic_yield();\n  }\n  _mi_error_message(EFAULT, \"internal error: lock cannot be acquired (due to lack of native lock primitives)\\n\");\n}\nstatic inline void mi_lock_release(mi_lock_t* lock) {\n  mi_atomic_store_release(&lock->mutex, (uintptr_t)0);\n}\nstatic inline void mi_lock_init(mi_lock_t* lock) {\n  mi_lock_release(lock);\n}\nstatic inline void mi_lock_done(mi_lock_t* lock) {\n  (void)(lock);\n}\n\n#endif\n\n\ntypedef struct mi_atomic_once_s {\n  _Atomic(uintptr_t) tid;\n  mi_lock_t          lock;\n} mi_atomic_once_t;\n\n// Returns `true` only on the first invocation, signifying we can execute an action once.\n// If it returns `true`, the caller should call `_mi_atomic_once_release` after performing the action.\n// Other threads (than the initial thread that entered) will block until `_mi_atomic_once_release` has been called.\nbool _mi_atomic_once_enter(mi_atomic_once_t* once);        // defined in `libc.c`\nvoid _mi_atomic_once_release(mi_atomic_once_t* once);      // defined in `libc.c`\n\n#define mi_atomic_do_once  \\\n  static mi_atomic_once_t _mi_once = { MI_ATOMIC_VAR_INIT(0), MI_LOCK_INITIALIZER }; \\\n  for(bool _mi_exec = _mi_atomic_once_enter(&_mi_once); _mi_exec; (_mi_atomic_once_release(&_mi_once),_mi_exec=false))\n\n\n#endif // __MIMALLOC_ATOMIC_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/include/mimalloc/internal.h",
      "sha256": "def781a5e62b35de55c2a9ddd667b5329bb6875b91c514ee63af55c978c1fb5e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_INTERNAL_H\n#define MIMALLOC_INTERNAL_H\n\n// --------------------------------------------------------------------------\n// This file contains the internal API's of mimalloc and various utility\n// functions and macros.\n// --------------------------------------------------------------------------\n\n#include \"types.h\"\n#include \"track.h\"\n\n\n// --------------------------------------------------------------------------\n// Compiler defines\n// --------------------------------------------------------------------------\n\n#if (MI_DEBUG>0)\n#define mi_trace_message(...)  _mi_trace_message(__VA_ARGS__)\n#else\n#define mi_trace_message(...)\n#endif\n\n#define mi_decl_cache_align     mi_decl_align(64)\n\n#if defined(_MSC_VER)\n#pragma warning(disable:4127)   // suppress constant conditional warning (due to MI_SECURE paths)\n#pragma warning(disable:26812)  // unscoped enum warning\n#define mi_decl_noinline        __declspec(noinline)\n#define mi_decl_thread          __declspec(thread)\n#define mi_decl_align(a)        __declspec(align(a))\n#define mi_decl_noreturn        __declspec(noreturn)\n#define mi_decl_weak\n#define mi_decl_hidden\n#define mi_decl_cold\n#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) // includes clang and icc\n#define mi_decl_noinline        __attribute__((noinline))\n#define mi_decl_thread          __thread\n#define mi_decl_align(a)        __attribute__((aligned(a)))\n#define mi_decl_noreturn        __attribute__((noreturn))\n#define mi_decl_weak            __attribute__((weak))\n#define mi_decl_hidden          __attribute__((visibility(\"hidden\")))\n#if (__GNUC__ >= 4) || defined(__clang__)\n#define mi_decl_cold            __attribute__((cold))\n#else\n#define mi_decl_cold\n#endif\n#elif __cplusplus >= 201103L    // c++11\n#define mi_decl_noinline\n#define mi_decl_thread          thread_local\n#define mi_decl_align(a)        alignas(a)\n#define mi_decl_noreturn        [[noreturn]]\n#define mi_decl_weak\n#define mi_decl_hidden\n#define mi_decl_cold\n#else\n#define mi_decl_noinline\n#define mi_decl_thread          __thread        // hope for the best :-)\n#define mi_decl_align(a)\n#define mi_decl_noreturn\n#define mi_decl_weak\n#define mi_decl_hidden\n#define mi_decl_cold\n#endif\n\n#if defined(__GNUC__) || defined(__clang__)\n#define mi_unlikely(x)     (__builtin_expect(!!(x),false))\n#define mi_likely(x)       (__builtin_expect(!!(x),true))\n#elif (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)\n#define mi_unlikely(x)     (x) [[unlikely]]\n#define mi_likely(x)       (x) [[likely]]\n#else\n#define mi_unlikely(x)     (x)\n#define mi_likely(x)       (x)\n#endif\n\n#ifndef __has_builtin\n#define __has_builtin(x)    0\n#endif\n\n#if defined(__cplusplus)\n#define mi_decl_externc     extern \"C\"\n#else\n#define mi_decl_externc\n#endif\n\n#if defined(__EMSCRIPTEN__) && !defined(__wasi__)\n#define __wasi__\n#endif\n\n\n// --------------------------------------------------------------------------\n// Internal functions\n// --------------------------------------------------------------------------\n\n// \"libc.c\"\n#include    <stdarg.h>\nint         _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args);\nint         _mi_snprintf(char* buf, size_t buflen, const char* fmt, ...);\nchar        _mi_toupper(char c);\nint         _mi_strnicmp(const char* s, const char* t, size_t n);\nvoid        _mi_strlcpy(char* dest, const char* src, size_t dest_size);\nvoid        _mi_strlcat(char* dest, const char* src, size_t dest_size);\nsize_t      _mi_strlen(const char* s);\nsize_t      _mi_strnlen(const char* s, size_t max_len);\nbool        _mi_streq(const char* s, const char* t);\nbool        _mi_getenv(const char* name, char* result, size_t result_size);\n\n// \"options.c\"\nvoid        _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message);\nvoid        _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...);\nvoid        _mi_message(const char* fmt, ...);\nvoid        _mi_warning_message(const char* fmt, ...);\nvoid        _mi_verbose_message(const char* fmt, ...);\nvoid        _mi_trace_message(const char* fmt, ...);\nvoid        _mi_options_init(void);\nlong        _mi_option_get_fast(mi_option_t option);\nvoid        _mi_error_message(int err, const char* fmt, ...);\n\n// random.c\nvoid        _mi_random_init(mi_random_ctx_t* ctx);\nvoid        _mi_random_init_weak(mi_random_ctx_t* ctx);\nvoid        _mi_random_reinit_if_weak(mi_random_ctx_t * ctx);\nvoid        _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx);\nuintptr_t   _mi_random_next(mi_random_ctx_t* ctx);\nuintptr_t   _mi_heap_random_next(mi_heap_t* heap);\nuintptr_t   _mi_os_random_weak(uintptr_t extra_seed);\nstatic inline uintptr_t _mi_random_shuffle(uintptr_t x);\n\n// init.c\nextern mi_decl_hidden mi_decl_cache_align mi_stats_t       _mi_stats_main;\nextern mi_decl_hidden mi_decl_cache_align const mi_page_t  _mi_page_empty;\nvoid        _mi_auto_process_init(void);\nvoid mi_cdecl _mi_auto_process_done(void) mi_attr_noexcept;\nbool        _mi_is_redirected(void);\nbool        _mi_allocator_init(const char** message);\nvoid        _mi_allocator_done(void);\nbool        _mi_is_main_thread(void);\nsize_t      _mi_current_thread_count(void);\nbool        _mi_preloading(void);           // true while the C runtime is not initialized yet\nvoid        _mi_thread_done(mi_heap_t* heap);\nvoid        _mi_thread_data_collect(void);\nvoid        _mi_tld_init(mi_tld_t* tld, mi_heap_t* bheap);\nmi_threadid_t _mi_thread_id(void) mi_attr_noexcept;\nmi_heap_t*    _mi_heap_main_get(void);     // statically allocated main backing heap\nmi_subproc_t* _mi_subproc_from_id(mi_subproc_id_t subproc_id);\nvoid        _mi_heap_guarded_init(mi_heap_t* heap);\n\n// os.c\nvoid        _mi_os_init(void);                                            // called from process init\nvoid*       _mi_os_alloc(size_t size, mi_memid_t* memid);\nvoid*       _mi_os_zalloc(size_t size, mi_memid_t* memid);\nvoid        _mi_os_free(void* p, size_t size, mi_memid_t memid);\nvoid        _mi_os_free_ex(void* p, size_t size, bool still_committed, mi_memid_t memid);\n\nsize_t      _mi_os_page_size(void);\nsize_t      _mi_os_good_alloc_size(size_t size);\nbool        _mi_os_has_overcommit(void);\nbool        _mi_os_has_virtual_reserve(void);\n\nbool        _mi_os_reset(void* addr, size_t size);\nbool        _mi_os_decommit(void* addr, size_t size);\nbool        _mi_os_unprotect(void* addr, size_t size);\nbool        _mi_os_purge(void* p, size_t size);\nbool        _mi_os_purge_ex(void* p, size_t size, bool allow_reset, size_t stat_size);\nvoid        _mi_os_reuse(void* p, size_t size);\nmi_decl_nodiscard bool _mi_os_commit(void* p, size_t size, bool* is_zero);\nmi_decl_nodiscard bool _mi_os_commit_ex(void* addr, size_t size, bool* is_zero, size_t stat_size);\nbool        _mi_os_protect(void* addr, size_t size);\n\nvoid*       _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid);\nvoid*       _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t* memid);\n\nvoid*       _mi_os_get_aligned_hint(size_t try_alignment, size_t size);\nbool        _mi_os_canuse_large_page(size_t size, size_t alignment);\nsize_t      _mi_os_large_page_size(void);\nvoid*       _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_secs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid);\n\nint         _mi_os_numa_node_count(void);\nint         _mi_os_numa_node(void);\n\n// arena.c\nmi_arena_id_t _mi_arena_id_none(void);\nvoid        _mi_arena_free(void* p, size_t size, size_t still_committed_size, mi_memid_t memid);\nvoid*       _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid);\nvoid*       _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid);\nbool        _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_id_t request_arena_id);\nbool        _mi_arena_contains(const void* p);\nvoid        _mi_arenas_collect(bool force_purge);\nvoid        _mi_arena_unsafe_destroy_all(void);\n\nbool        _mi_arena_segment_clear_abandoned(mi_segment_t* segment);\nvoid        _mi_arena_segment_mark_abandoned(mi_segment_t* segment);\n\nvoid*       _mi_arena_meta_zalloc(size_t size, mi_memid_t* memid);\nvoid        _mi_arena_meta_free(void* p, mi_memid_t memid, size_t size);\n\ntypedef struct mi_arena_field_cursor_s { // abstract struct\n  size_t         os_list_count;           // max entries to visit in the OS abandoned list\n  size_t         start;                   // start arena idx (may need to be wrapped)\n  size_t         end;                     // end arena idx (exclusive, may need to be wrapped)\n  size_t         bitmap_idx;              // current bit idx for an arena\n  mi_subproc_t*  subproc;                 // only visit blocks in this sub-process\n  bool           visit_all;               // ensure all abandoned blocks are seen (blocking)\n  bool           hold_visit_lock;         // if the subproc->abandoned_os_visit_lock is held\n} mi_arena_field_cursor_t;\nvoid          _mi_arena_field_cursor_init(mi_heap_t* heap, mi_subproc_t* subproc, bool visit_all, mi_arena_field_cursor_t* current);\nmi_segment_t* _mi_arena_segment_clear_abandoned_next(mi_arena_field_cursor_t* previous);\nvoid          _mi_arena_field_cursor_done(mi_arena_field_cursor_t* current);\n\n// \"segment-map.c\"\nvoid        _mi_segment_map_allocated_at(const mi_segment_t* segment);\nvoid        _mi_segment_map_freed_at(const mi_segment_t* segment);\nvoid        _mi_segment_map_unsafe_destroy(void);\n\n// \"segment.c\"\nmi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld);\nvoid       _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld);\nvoid       _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld);\nbool       _mi_segment_try_reclaim_abandoned( mi_heap_t* heap, bool try_all, mi_segments_tld_t* tld);\nvoid       _mi_segment_collect(mi_segment_t* segment, bool force);\n\n#if MI_HUGE_PAGE_ABANDON\nvoid        _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block);\n#else\nvoid        _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_block_t* block);\n#endif\n\nuint8_t*   _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size); // page start for any page\nvoid       _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld);\nvoid       _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld);\nbool       _mi_segment_attempt_reclaim(mi_heap_t* heap, mi_segment_t* segment);\nbool       _mi_segment_visit_blocks(mi_segment_t* segment, int heap_tag, bool visit_blocks, mi_block_visit_fun* visitor, void* arg);\n\n// \"page.c\"\nvoid*       _mi_malloc_generic(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment, size_t* usable)  mi_attr_noexcept mi_attr_malloc;\n\nvoid        _mi_page_retire(mi_page_t* page) mi_attr_noexcept;                  // free the page if there are no other pages with many free blocks\nvoid        _mi_page_unfull(mi_page_t* page);\nvoid        _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force);   // free the page\nvoid        _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq);            // abandon the page, to be picked up by another thread...\nvoid        _mi_page_force_abandon(mi_page_t* page);\n\nvoid        _mi_heap_delayed_free_all(mi_heap_t* heap);\nbool        _mi_heap_delayed_free_partial(mi_heap_t* heap);\nvoid        _mi_heap_collect_retired(mi_heap_t* heap, bool force);\n\nvoid        _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never);\nbool        _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never);\nsize_t      _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append);\nvoid        _mi_deferred_free(mi_heap_t* heap, bool force);\n\nvoid        _mi_page_free_collect(mi_page_t* page,bool force);\nvoid        _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page);   // callback from segments\n\nsize_t      _mi_page_stats_bin(const mi_page_t* page); // for stats\nsize_t      _mi_bin_size(size_t bin);                  // for stats\nsize_t      _mi_bin(size_t size);                      // for stats\n\n// \"heap.c\"\nvoid        _mi_heap_init(mi_heap_t* heap, mi_tld_t* tld, mi_arena_id_t arena_id, bool noreclaim, uint8_t tag);\nvoid        _mi_heap_destroy_pages(mi_heap_t* heap);\nvoid        _mi_heap_collect_abandon(mi_heap_t* heap);\nvoid        _mi_heap_set_default_direct(mi_heap_t* heap);\nbool        _mi_heap_memid_is_suitable(mi_heap_t* heap, mi_memid_t memid);\nvoid        _mi_heap_unsafe_destroy_all(mi_heap_t* heap);\nmi_heap_t*  _mi_heap_by_tag(mi_heap_t* heap, uint8_t tag);\nvoid        _mi_heap_area_init(mi_heap_area_t* area, mi_page_t* page);\nbool        _mi_heap_area_visit_blocks(const mi_heap_area_t* area, mi_page_t* page, mi_block_visit_fun* visitor, void* arg);\n\n// \"stats.c\"\nvoid        _mi_stats_done(mi_stats_t* stats);\nvoid        _mi_stats_merge_thread(mi_tld_t* tld);\nmi_msecs_t  _mi_clock_now(void);\nmi_msecs_t  _mi_clock_end(mi_msecs_t start);\nmi_msecs_t  _mi_clock_start(void);\n\n// \"alloc.c\"\nvoid*       _mi_page_malloc_zero(mi_heap_t* heap, mi_page_t* page, size_t size, bool zero, size_t* usable) mi_attr_noexcept;  // called from `_mi_malloc_generic`\nvoid*       _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept;                  // called from `_mi_heap_malloc_aligned`\nvoid*       _mi_page_malloc_zeroed(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept;           // called from `_mi_heap_malloc_aligned`\nvoid*       _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept;\nvoid*       _mi_heap_malloc_zero_ex(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment, size_t* usable) mi_attr_noexcept;     // called from `_mi_heap_malloc_aligned`\nvoid*       _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero, size_t* usable_pre, size_t* usable_post) mi_attr_noexcept;\nmi_block_t* _mi_page_ptr_unalign(const mi_page_t* page, const void* p);\nbool        _mi_free_delayed_block(mi_block_t* block);\nvoid        _mi_free_generic(mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept;  // for runtime integration\nvoid        _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size);\n\n#if MI_DEBUG>1\nbool        _mi_page_is_valid(mi_page_t* page);\n#endif\n\n\n/* -----------------------------------------------------------\n  Error codes passed to `_mi_fatal_error`\n  All are recoverable but EFAULT is a serious error and aborts by default in secure mode.\n  For portability define undefined error codes using common Unix codes:\n  <https://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html>\n----------------------------------------------------------- */\n#include <errno.h>\n#ifndef EAGAIN         // double free\n#define EAGAIN (11)\n#endif\n#ifndef ENOMEM         // out of memory\n#define ENOMEM (12)\n#endif\n#ifndef EFAULT         // corrupted free-list or meta-data\n#define EFAULT (14)\n#endif\n#ifndef EINVAL         // trying to free an invalid pointer\n#define EINVAL (22)\n#endif\n#ifndef EOVERFLOW      // count*size overflow\n#define EOVERFLOW (75)\n#endif\n\n\n// ------------------------------------------------------\n// Assertions\n// ------------------------------------------------------\n\n#if (MI_DEBUG)\n// use our own assertion to print without memory allocation\nmi_decl_noreturn mi_decl_cold void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func) mi_attr_noexcept;\n#define mi_assert(expr)     ((expr) ? (void)0 : _mi_assert_fail(#expr,__FILE__,__LINE__,__func__))\n#else\n#define mi_assert(x)\n#endif\n\n#if (MI_DEBUG>1)\n#define mi_assert_internal    mi_assert\n#else\n#define mi_assert_internal(x)\n#endif\n\n#if (MI_DEBUG>2)\n#define mi_assert_expensive   mi_assert\n#else\n#define mi_assert_expensive(x)\n#endif\n\n\n\n/* -----------------------------------------------------------\n  Inlined definitions\n----------------------------------------------------------- */\n#define MI_UNUSED(x)     (void)(x)\n#if (MI_DEBUG>1)\n#define MI_UNUSED_RELEASE(x)\n#else\n#define MI_UNUSED_RELEASE(x)  MI_UNUSED(x)\n#endif\n\n#define MI_INIT4(x)   x(),x(),x(),x()\n#define MI_INIT8(x)   MI_INIT4(x),MI_INIT4(x)\n#define MI_INIT16(x)  MI_INIT8(x),MI_INIT8(x)\n#define MI_INIT32(x)  MI_INIT16(x),MI_INIT16(x)\n#define MI_INIT64(x)  MI_INIT32(x),MI_INIT32(x)\n#define MI_INIT128(x) MI_INIT64(x),MI_INIT64(x)\n#define MI_INIT256(x) MI_INIT128(x),MI_INIT128(x)\n#define MI_INIT74(x)  MI_INIT64(x),MI_INIT8(x),x(),x()\n\n#include <string.h>\n// initialize a local variable to zero; use memset as compilers optimize constant sized memset's\n#define _mi_memzero_var(x)  memset(&x,0,sizeof(x))\n\n// Is `x` a power of two? (0 is considered a power of two)\nstatic inline bool _mi_is_power_of_two(uintptr_t x) {\n  return ((x & (x - 1)) == 0);\n}\n\n// Is a pointer aligned?\nstatic inline bool _mi_is_aligned(void* p, size_t alignment) {\n  return (alignment==0 || ((uintptr_t)p % alignment) == 0);\n}\n\n// Align upwards\nstatic inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) {\n  mi_assert_internal(alignment != 0);\n  uintptr_t mask = alignment - 1;\n  if ((alignment & mask) == 0) {  // power of two?\n    return ((sz + mask) & ~mask);\n  }\n  else {\n    return (((sz + mask)/alignment)*alignment);\n  }\n}\n\n// Align downwards\nstatic inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) {\n  mi_assert_internal(alignment != 0);\n  uintptr_t mask = alignment - 1;\n  if ((alignment & mask) == 0) { // power of two?\n    return (sz & ~mask);\n  }\n  else {\n    return ((sz / alignment) * alignment);\n  }\n}\n\n// Align a pointer upwards\nstatic inline void* _mi_align_up_ptr(const void* p, size_t alignment) {\n  return (void*)_mi_align_up((uintptr_t)p, alignment);\n}\n\n// Align a pointer downwards\nstatic inline void* _mi_align_down_ptr(void* p, size_t alignment) {\n  return (void*)_mi_align_down((uintptr_t)p, alignment);\n}\n\n\n// Divide upwards: `s <= _mi_divide_up(s,d)*d < s+d`.\nstatic inline uintptr_t _mi_divide_up(uintptr_t size, size_t divider) {\n  mi_assert_internal(divider != 0);\n  return (divider == 0 ? size : ((size + divider - 1) / divider));\n}\n\n\n// clamp an integer\nstatic inline size_t _mi_clamp(size_t sz, size_t min, size_t max) {\n  if (sz < min) return min;\n  else if (sz > max) return max;\n  else return sz;\n}\n\n// Is memory zero initialized?\nstatic inline bool mi_mem_is_zero(const void* p, size_t size) {\n  for (size_t i = 0; i < size; i++) {\n    if (((uint8_t*)p)[i] != 0) return false;\n  }\n  return true;\n}\n\n\n// Align a byte size to a size in _machine words_,\n// i.e. byte size == `wsize*sizeof(void*)`.\nstatic inline size_t _mi_wsize_from_size(size_t size) {\n  mi_assert_internal(size <= SIZE_MAX - sizeof(uintptr_t));\n  return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);\n}\n\n// Overflow detecting multiply\n#if __has_builtin(__builtin_umul_overflow) || (defined(__GNUC__) && (__GNUC__ >= 5))\n#include <limits.h>      // UINT_MAX, ULONG_MAX\n#if defined(_CLOCK_T)    // for Illumos\n#undef _CLOCK_T\n#endif\nstatic inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) {\n  #if (SIZE_MAX == ULONG_MAX)\n    return __builtin_umull_overflow(count, size, (unsigned long *)total);\n  #elif (SIZE_MAX == UINT_MAX)\n    return __builtin_umul_overflow(count, size, (unsigned int *)total);\n  #else\n    return __builtin_umulll_overflow(count, size, (unsigned long long *)total);\n  #endif\n}\n#else /* __builtin_umul_overflow is unavailable */\nstatic inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) {\n  #define MI_MUL_COULD_OVERFLOW ((size_t)1 << (4*sizeof(size_t)))  // sqrt(SIZE_MAX)\n  *total = count * size;\n  // note: gcc/clang optimize this to directly check the overflow flag\n  return ((size >= MI_MUL_COULD_OVERFLOW || count >= MI_MUL_COULD_OVERFLOW) && size > 0 && (SIZE_MAX / size) < count);\n}\n#endif\n\n// Safe multiply `count*size` into `total`; return `true` on overflow.\nstatic inline bool mi_count_size_overflow(size_t count, size_t size, size_t* total) {\n  if (count==1) {  // quick check for the case where count is one (common for C++ allocators)\n    *total = size;\n    return false;\n  }\n  else if mi_unlikely(mi_mul_overflow(count, size, total)) {\n    #if MI_DEBUG > 0\n    _mi_error_message(EOVERFLOW, \"allocation request is too large (%zu * %zu bytes)\\n\", count, size);\n    #endif\n    *total = SIZE_MAX;\n    return true;\n  }\n  else return false;\n}\n\n\n/*----------------------------------------------------------------------------------------\n  Heap functions\n------------------------------------------------------------------------------------------- */\n\nextern mi_decl_hidden const mi_heap_t _mi_heap_empty;  // read-only empty heap, initial value of the thread local default heap\n\nstatic inline bool mi_heap_is_backing(const mi_heap_t* heap) {\n  return (heap->tld->heap_backing == heap);\n}\n\nstatic inline bool mi_heap_is_initialized(mi_heap_t* heap) {\n  mi_assert_internal(heap != NULL);\n  return (heap != NULL && heap != &_mi_heap_empty);\n}\n\nstatic inline uintptr_t _mi_ptr_cookie(const void* p) {\n  extern mi_decl_hidden mi_heap_t _mi_heap_main;\n  mi_assert_internal(_mi_heap_main.cookie != 0);\n  return ((uintptr_t)p ^ _mi_heap_main.cookie);\n}\n\n/* -----------------------------------------------------------\n  Pages\n----------------------------------------------------------- */\n\nstatic inline mi_page_t* _mi_heap_get_free_small_page(mi_heap_t* heap, size_t size) {\n  mi_assert_internal(size <= (MI_SMALL_SIZE_MAX + MI_PADDING_SIZE));\n  const size_t idx = _mi_wsize_from_size(size);\n  mi_assert_internal(idx < MI_PAGES_DIRECT);\n  return heap->pages_free_direct[idx];\n}\n\n// Segment that contains the pointer\n// Large aligned blocks may be aligned at N*MI_SEGMENT_SIZE (inside a huge segment > MI_SEGMENT_SIZE),\n// and we need align \"down\" to the segment info which is `MI_SEGMENT_SIZE` bytes before it;\n// therefore we align one byte before `p`.\n// We check for NULL afterwards on 64-bit systems to improve codegen for `mi_free`.\nstatic inline mi_segment_t* _mi_ptr_segment(const void* p) {\n  mi_segment_t* const segment = (mi_segment_t*)(((uintptr_t)p - 1) & ~MI_SEGMENT_MASK);\n  #if MI_INTPTR_SIZE <= 4\n  return (p==NULL ? NULL : segment);\n  #else\n  return ((intptr_t)segment <= 0 ? NULL : segment);\n  #endif\n}\n\nstatic inline mi_page_t* mi_slice_to_page(mi_slice_t* s) {\n  mi_assert_internal(s->slice_offset== 0 && s->slice_count > 0);\n  return (mi_page_t*)(s);\n}\n\nstatic inline mi_slice_t* mi_page_to_slice(mi_page_t* p) {\n  mi_assert_internal(p->slice_offset== 0 && p->slice_count > 0);\n  return (mi_slice_t*)(p);\n}\n\n// Segment belonging to a page\nstatic inline mi_segment_t* _mi_page_segment(const mi_page_t* page) {\n  mi_assert_internal(page!=NULL);\n  mi_segment_t* segment = _mi_ptr_segment(page);\n  mi_assert_internal(segment == NULL || ((mi_slice_t*)page >= segment->slices && (mi_slice_t*)page < segment->slices + segment->slice_entries));\n  return segment;\n}\n\nstatic inline mi_slice_t* mi_slice_first(const mi_slice_t* slice) {\n  mi_slice_t* start = (mi_slice_t*)((uint8_t*)slice - slice->slice_offset);\n  mi_assert_internal(start >= _mi_ptr_segment(slice)->slices);\n  mi_assert_internal(start->slice_offset == 0);\n  mi_assert_internal(start + start->slice_count > slice);\n  return start;\n}\n\n// Get the page containing the pointer (performance critical as it is called in mi_free)\nstatic inline mi_page_t* _mi_segment_page_of(const mi_segment_t* segment, const void* p) {\n  mi_assert_internal(p > (void*)segment);\n  ptrdiff_t diff = (uint8_t*)p - (uint8_t*)segment;\n  mi_assert_internal(diff > 0 && diff <= (ptrdiff_t)MI_SEGMENT_SIZE);\n  size_t idx = (size_t)diff >> MI_SEGMENT_SLICE_SHIFT;\n  mi_assert_internal(idx <= segment->slice_entries);\n  mi_slice_t* slice0 = (mi_slice_t*)&segment->slices[idx];\n  mi_slice_t* slice = mi_slice_first(slice0);  // adjust to the block that holds the page data\n  mi_assert_internal(slice->slice_offset == 0);\n  mi_assert_internal(slice >= segment->slices && slice < segment->slices + segment->slice_entries);\n  return mi_slice_to_page(slice);\n}\n\n// Quick page start for initialized pages\nstatic inline uint8_t* mi_page_start(const mi_page_t* page) {\n  mi_assert_internal(page->page_start != NULL);\n  mi_assert_expensive(_mi_segment_page_start(_mi_page_segment(page),page,NULL) == page->page_start);\n  return page->page_start;\n}\n\n// Get the page containing the pointer\nstatic inline mi_page_t* _mi_ptr_page(void* p) {\n  mi_assert_internal(p!=NULL);\n  return _mi_segment_page_of(_mi_ptr_segment(p), p);\n}\n\n// Get the block size of a page (special case for huge objects)\nstatic inline size_t mi_page_block_size(const mi_page_t* page) {\n  mi_assert_internal(page->block_size > 0);\n  return page->block_size;\n}\n\nstatic inline bool mi_page_is_huge(const mi_page_t* page) {\n  mi_assert_internal((page->is_huge && _mi_page_segment(page)->kind == MI_SEGMENT_HUGE) ||\n                     (!page->is_huge && _mi_page_segment(page)->kind != MI_SEGMENT_HUGE));\n  return page->is_huge;\n}\n\n// Get the usable block size of a page without fixed padding.\n// This may still include internal padding due to alignment and rounding up size classes.\nstatic inline size_t mi_page_usable_block_size(const mi_page_t* page) {\n  return mi_page_block_size(page) - MI_PADDING_SIZE;\n}\n\n// size of a segment\nstatic inline size_t mi_segment_size(mi_segment_t* segment) {\n  return segment->segment_slices * MI_SEGMENT_SLICE_SIZE;\n}\n\nstatic inline uint8_t* mi_segment_end(mi_segment_t* segment) {\n  return (uint8_t*)segment + mi_segment_size(segment);\n}\n\n// Thread free access\nstatic inline mi_block_t* mi_page_thread_free(const mi_page_t* page) {\n  return (mi_block_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & ~3);\n}\n\nstatic inline mi_delayed_t mi_page_thread_free_flag(const mi_page_t* page) {\n  return (mi_delayed_t)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & 3);\n}\n\n// Heap access\nstatic inline mi_heap_t* mi_page_heap(const mi_page_t* page) {\n  return (mi_heap_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xheap));\n}\n\nstatic inline void mi_page_set_heap(mi_page_t* page, mi_heap_t* heap) {\n  mi_assert_internal(mi_page_thread_free_flag(page) != MI_DELAYED_FREEING);\n  mi_atomic_store_release(&page->xheap,(uintptr_t)heap);\n  if (heap != NULL) { page->heap_tag = heap->tag; }\n}\n\n// Thread free flag helpers\nstatic inline mi_block_t* mi_tf_block(mi_thread_free_t tf) {\n  return (mi_block_t*)(tf & ~0x03);\n}\nstatic inline mi_delayed_t mi_tf_delayed(mi_thread_free_t tf) {\n  return (mi_delayed_t)(tf & 0x03);\n}\nstatic inline mi_thread_free_t mi_tf_make(mi_block_t* block, mi_delayed_t delayed) {\n  return (mi_thread_free_t)((uintptr_t)block | (uintptr_t)delayed);\n}\nstatic inline mi_thread_free_t mi_tf_set_delayed(mi_thread_free_t tf, mi_delayed_t delayed) {\n  return mi_tf_make(mi_tf_block(tf),delayed);\n}\nstatic inline mi_thread_free_t mi_tf_set_block(mi_thread_free_t tf, mi_block_t* block) {\n  return mi_tf_make(block, mi_tf_delayed(tf));\n}\n\n// are all blocks in a page freed?\n// note: needs up-to-date used count, (as the `xthread_free` list may not be empty). see `_mi_page_collect_free`.\nstatic inline bool mi_page_all_free(const mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  return (page->used == 0);\n}\n\n// are there any available blocks?\nstatic inline bool mi_page_has_any_available(const mi_page_t* page) {\n  mi_assert_internal(page != NULL && page->reserved > 0);\n  return (page->used < page->reserved || (mi_page_thread_free(page) != NULL));\n}\n\n// are there immediately available blocks, i.e. blocks available on the free list.\nstatic inline bool mi_page_immediate_available(const mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  return (page->free != NULL);\n}\n\n// is more than 7/8th of a page in use?\nstatic inline bool mi_page_is_mostly_used(const mi_page_t* page) {\n  if (page==NULL) return true;\n  uint16_t frac = page->reserved / 8U;\n  return (page->reserved - page->used <= frac);\n}\n\nstatic inline mi_page_queue_t* mi_page_queue(const mi_heap_t* heap, size_t size) {\n  return &((mi_heap_t*)heap)->pages[_mi_bin(size)];\n}\n\n\n\n//-----------------------------------------------------------\n// Page flags\n//-----------------------------------------------------------\nstatic inline bool mi_page_is_in_full(const mi_page_t* page) {\n  return page->flags.x.in_full;\n}\n\nstatic inline void mi_page_set_in_full(mi_page_t* page, bool in_full) {\n  if (page->flags.x.in_full != in_full) {\n    // optimize: maintain pages_full_size to avoid visiting the full queue (issue #1220)\n    mi_heap_t* const heap = mi_page_heap(page);\n    const size_t size = page->capacity * mi_page_block_size(page);\n    if (in_full) { heap->pages_full_size += size; }\n            else { mi_assert_internal(size <= heap->pages_full_size); heap->pages_full_size -= size; }\n  }\n  page->flags.x.in_full = in_full;\n}\n\nstatic inline bool mi_page_has_aligned(const mi_page_t* page) {\n  return page->flags.x.has_aligned;\n}\n\nstatic inline void mi_page_set_has_aligned(mi_page_t* page, bool has_aligned) {\n  page->flags.x.has_aligned = has_aligned;\n}\n\n/* -------------------------------------------------------------------\n  Guarded objects\n------------------------------------------------------------------- */\nstatic inline bool mi_block_ptr_is_guarded(const mi_block_t* block, const void* p) {\n#if MI_GUARDED\n  const ptrdiff_t offset = (uint8_t*)p - (uint8_t*)block;\n  return (offset >= (ptrdiff_t)(sizeof(mi_block_t)) && block->next == MI_BLOCK_TAG_GUARDED);\n#else\n  MI_UNUSED(block); MI_UNUSED(p);\n  return false;\n#endif  \n}\n\n#if MI_GUARDED\nstatic inline bool mi_heap_malloc_use_guarded(mi_heap_t* heap, size_t size) {\n  // this code is written to result in fast assembly as it is on the hot path for allocation\n  const size_t count = heap->guarded_sample_count - 1;  // if the rate was 0, this will underflow and count for a long time..\n  if mi_likely(count != 0) {\n    // no sample\n    heap->guarded_sample_count = count;\n    return false;\n  }\n  else if (size >= heap->guarded_size_min && size <= heap->guarded_size_max) {\n    // use guarded allocation\n    heap->guarded_sample_count = heap->guarded_sample_rate;  // reset\n    return (heap->guarded_sample_rate != 0);\n  }\n  else {\n    // failed size criteria, rewind count (but don't write to an empty heap)\n    if (heap->guarded_sample_rate != 0) { heap->guarded_sample_count = 1; }\n    return false;\n  }\n}\n\nmi_decl_restrict void* _mi_heap_malloc_guarded(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept;\n\n#endif\n\n\n/* -------------------------------------------------------------------\nEncoding/Decoding the free list next pointers\n\nThis is to protect against buffer overflow exploits where the\nfree list is mutated. Many hardened allocators xor the next pointer `p`\nwith a secret key `k1`, as `p^k1`. This prevents overwriting with known\nvalues but might be still too weak: if the attacker can guess\nthe pointer `p` this  can reveal `k1` (since `p^k1^p == k1`).\nMoreover, if multiple blocks can be read as well, the attacker can\nxor both as `(p1^k1) ^ (p2^k1) == p1^p2` which may reveal a lot\nabout the pointers (and subsequently `k1`).\n\nInstead mimalloc uses an extra key `k2` and encodes as `((p^k2)<<<k1)+k1`.\nSince these operations are not associative, the above approaches do not\nwork so well any more even if the `p` can be guesstimated. For example,\nfor the read case we can subtract two entries to discard the `+k1` term,\nbut that leads to `((p1^k2)<<<k1) - ((p2^k2)<<<k1)` at best.\nWe include the left-rotation since xor and addition are otherwise linear\nin the lowest bit. Finally, both keys are unique per page which reduces\nthe re-use of keys by a large factor.\n\nWe also pass a separate `null` value to be used as `NULL` or otherwise\n`(k2<<<k1)+k1` would appear (too) often as a sentinel value.\n------------------------------------------------------------------- */\n\nstatic inline bool mi_is_in_same_segment(const void* p, const void* q) {\n  return (_mi_ptr_segment(p) == _mi_ptr_segment(q));\n}\n\nstatic inline bool mi_is_in_same_page(const void* p, const void* q) {\n  mi_segment_t* segment = _mi_ptr_segment(p);\n  if (_mi_ptr_segment(q) != segment) return false;\n  // assume q may be invalid // return (_mi_segment_page_of(segment, p) == _mi_segment_page_of(segment, q));\n  mi_page_t* page = _mi_segment_page_of(segment, p);\n  size_t psize;\n  uint8_t* start = _mi_segment_page_start(segment, page, &psize);\n  return (start <= (uint8_t*)q && (uint8_t*)q < start + psize);\n}\n\nstatic inline uintptr_t mi_rotl(uintptr_t x, uintptr_t shift) {\n  shift %= MI_INTPTR_BITS;\n  return (shift==0 ? x : ((x << shift) | (x >> (MI_INTPTR_BITS - shift))));\n}\nstatic inline uintptr_t mi_rotr(uintptr_t x, uintptr_t shift) {\n  shift %= MI_INTPTR_BITS;\n  return (shift==0 ? x : ((x >> shift) | (x << (MI_INTPTR_BITS - shift))));\n}\n\nstatic inline void* mi_ptr_decode(const void* null, const mi_encoded_t x, const uintptr_t* keys) {\n  void* p = (void*)(mi_rotr(x - keys[0], keys[0]) ^ keys[1]);\n  return (p==null ? NULL : p);\n}\n\nstatic inline mi_encoded_t mi_ptr_encode(const void* null, const void* p, const uintptr_t* keys) {\n  uintptr_t x = (uintptr_t)(p==NULL ? null : p);\n  return mi_rotl(x ^ keys[1], keys[0]) + keys[0];\n}\n\nstatic inline uint32_t mi_ptr_encode_canary(const void* null, const void* p, const uintptr_t* keys) {\n  const uint32_t x = (uint32_t)(mi_ptr_encode(null,p,keys));\n  // make the lowest byte 0 to prevent spurious read overflows which could be a security issue (issue #951)\n  #ifdef MI_BIG_ENDIAN\n  return (x & 0x00FFFFFF);\n  #else\n  return (x & 0xFFFFFF00);\n  #endif\n}\n\nstatic inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* block, const uintptr_t* keys ) {\n  mi_track_mem_defined(block,sizeof(mi_block_t));\n  mi_block_t* next;\n  #ifdef MI_ENCODE_FREELIST\n  next = (mi_block_t*)mi_ptr_decode(null, block->next, keys);\n  #else\n  MI_UNUSED(keys); MI_UNUSED(null);\n  next = (mi_block_t*)block->next;\n  #endif\n  mi_track_mem_noaccess(block,sizeof(mi_block_t));\n  return next;\n}\n\nstatic inline void mi_block_set_nextx(const void* null, mi_block_t* block, const mi_block_t* next, const uintptr_t* keys) {\n  mi_track_mem_undefined(block,sizeof(mi_block_t));\n  #ifdef MI_ENCODE_FREELIST\n  block->next = mi_ptr_encode(null, next, keys);\n  #else\n  MI_UNUSED(keys); MI_UNUSED(null);\n  block->next = (mi_encoded_t)next;\n  #endif\n  mi_track_mem_noaccess(block,sizeof(mi_block_t));\n}\n\nstatic inline mi_block_t* mi_block_next(const mi_page_t* page, const mi_block_t* block) {\n  #ifdef MI_ENCODE_FREELIST\n  mi_block_t* next = mi_block_nextx(page,block,page->keys);\n  // check for free list corruption: is `next` at least in the same page?\n  // TODO: check if `next` is `page->block_size` aligned?\n  if mi_unlikely(next!=NULL && !mi_is_in_same_page(block, next)) {\n    _mi_error_message(EFAULT, \"corrupted free list entry of size %zub at %p: value 0x%zx\\n\", mi_page_block_size(page), block, (uintptr_t)next);\n    next = NULL;\n  }\n  return next;\n  #else\n  MI_UNUSED(page);\n  return mi_block_nextx(page,block,NULL);\n  #endif\n}\n\nstatic inline void mi_block_set_next(const mi_page_t* page, mi_block_t* block, const mi_block_t* next) {\n  #ifdef MI_ENCODE_FREELIST\n  mi_block_set_nextx(page,block,next, page->keys);\n  #else\n  MI_UNUSED(page);\n  mi_block_set_nextx(page,block,next,NULL);\n  #endif\n}\n\n\n// -------------------------------------------------------------------\n// commit mask\n// -------------------------------------------------------------------\n\nstatic inline void mi_commit_mask_create_empty(mi_commit_mask_t* cm) {\n  for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {\n    cm->mask[i] = 0;\n  }\n}\n\nstatic inline void mi_commit_mask_create_full(mi_commit_mask_t* cm) {\n  for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {\n    cm->mask[i] = ~((size_t)0);\n  }\n}\n\nstatic inline bool mi_commit_mask_is_empty(const mi_commit_mask_t* cm) {\n  for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {\n    if (cm->mask[i] != 0) return false;\n  }\n  return true;\n}\n\nstatic inline bool mi_commit_mask_is_full(const mi_commit_mask_t* cm) {\n  for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {\n    if (cm->mask[i] != ~((size_t)0)) return false;\n  }\n  return true;\n}\n\n// defined in `segment.c`:\nsize_t _mi_commit_mask_committed_size(const mi_commit_mask_t* cm, size_t total);\nsize_t _mi_commit_mask_next_run(const mi_commit_mask_t* cm, size_t* idx);\n\n#define mi_commit_mask_foreach(cm,idx,count) \\\n  idx = 0; \\\n  while ((count = _mi_commit_mask_next_run(cm,&idx)) > 0) {\n\n#define mi_commit_mask_foreach_end() \\\n    idx += count; \\\n  }\n\n\n\n/* -----------------------------------------------------------\n  memory id's\n----------------------------------------------------------- */\n\nstatic inline mi_memid_t _mi_memid_create(mi_memkind_t memkind) {\n  mi_memid_t memid;\n  _mi_memzero_var(memid);\n  memid.memkind = memkind;\n  return memid;\n}\n\nstatic inline mi_memid_t _mi_memid_none(void) {\n  return _mi_memid_create(MI_MEM_NONE);\n}\n\nstatic inline mi_memid_t _mi_memid_create_os(void* base, size_t size, bool committed, bool is_zero, bool is_large) {\n  mi_memid_t memid = _mi_memid_create(MI_MEM_OS);\n  memid.mem.os.base = base;\n  memid.mem.os.size = size;\n  memid.initially_committed = committed;\n  memid.initially_zero = is_zero;\n  memid.is_pinned = is_large;\n  return memid;\n}\n\n\n// -------------------------------------------------------------------\n// Fast \"random\" shuffle\n// -------------------------------------------------------------------\n\nstatic inline uintptr_t _mi_random_shuffle(uintptr_t x) {\n  if (x==0) { x = 17; }   // ensure we don't get stuck in generating zeros\n#if (MI_INTPTR_SIZE>=8)\n  // by Sebastiano Vigna, see: <http://xoshiro.di.unimi.it/splitmix64.c>\n  x ^= x >> 30;\n  x *= 0xbf58476d1ce4e5b9UL;\n  x ^= x >> 27;\n  x *= 0x94d049bb133111ebUL;\n  x ^= x >> 31;\n#elif (MI_INTPTR_SIZE==4)\n  // by Chris Wellons, see: <https://nullprogram.com/blog/2018/07/31/>\n  x ^= x >> 16;\n  x *= 0x7feb352dUL;\n  x ^= x >> 15;\n  x *= 0x846ca68bUL;\n  x ^= x >> 16;\n#endif\n  return x;\n}\n\n\n\n// -----------------------------------------------------------------------\n// Count bits: trailing or leading zeros (with MI_INTPTR_BITS on all zero)\n// -----------------------------------------------------------------------\n\n#if defined(__GNUC__)\n\n#include <limits.h>       // LONG_MAX\n#define MI_HAVE_FAST_BITSCAN\nstatic inline size_t mi_clz(size_t x) {\n  if (x==0) return MI_SIZE_BITS;\n  #if (SIZE_MAX == ULONG_MAX)\n    return __builtin_clzl(x);\n  #else\n    return __builtin_clzll(x);\n  #endif\n}\nstatic inline size_t mi_ctz(size_t x) {\n  if (x==0) return MI_SIZE_BITS;\n  #if (SIZE_MAX == ULONG_MAX)\n    return __builtin_ctzl(x);\n  #else\n    return __builtin_ctzll(x);\n  #endif\n}\n\n#elif defined(_MSC_VER)\n\n#include <limits.h>       // LONG_MAX\n#include <intrin.h>       // BitScanReverse64\n#define MI_HAVE_FAST_BITSCAN\nstatic inline size_t mi_clz(size_t x) {\n  if (x==0) return MI_SIZE_BITS;\n  unsigned long idx;\n  #if (SIZE_MAX == ULONG_MAX)\n    _BitScanReverse(&idx, x);\n  #else\n    _BitScanReverse64(&idx, x);\n  #endif\n  return ((MI_SIZE_BITS - 1) - (size_t)idx);\n}\nstatic inline size_t mi_ctz(size_t x) {\n  if (x==0) return MI_SIZE_BITS;\n  unsigned long idx;\n  #if (SIZE_MAX == ULONG_MAX)\n    _BitScanForward(&idx, x);\n  #else\n    _BitScanForward64(&idx, x);\n  #endif\n  return (size_t)idx;\n}\n\n#else\n\nstatic inline size_t mi_ctz_generic32(uint32_t x) {\n  // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>\n  static const uint8_t debruijn[32] = {\n    0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,\n    31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9\n  };\n  if (x==0) return 32;\n  return debruijn[(uint32_t)((x & -(int32_t)x) * (uint32_t)(0x077CB531U)) >> 27];\n}\n\nstatic inline size_t mi_clz_generic32(uint32_t x) {\n  // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>\n  static const uint8_t debruijn[32] = {\n    31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1,\n    23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0\n  };\n  if (x==0) return 32;\n  x |= x >> 1;\n  x |= x >> 2;\n  x |= x >> 4;\n  x |= x >> 8;\n  x |= x >> 16;\n  return debruijn[(uint32_t)(x * (uint32_t)(0x07C4ACDDU)) >> 27];\n}\n\nstatic inline size_t mi_ctz(size_t x) {\n  if (x==0) return MI_SIZE_BITS;\n  #if (MI_SIZE_BITS <= 32)\n    return mi_ctz_generic32((uint32_t)x);\n  #else\n    const uint32_t lo = (uint32_t)x;\n    if (lo != 0) {\n      return mi_ctz_generic32(lo);\n    }\n    else {\n      return (32 + mi_ctz_generic32((uint32_t)(x>>32)));\n    }\n  #endif\n}\n\nstatic inline size_t mi_clz(size_t x) {\n  if (x==0) return MI_SIZE_BITS;\n  #if (MI_SIZE_BITS <= 32)\n    return mi_clz_generic32((uint32_t)x);\n  #else\n    const uint32_t hi = (uint32_t)(x>>32);\n    if (hi != 0) {\n      return mi_clz_generic32(hi);\n    }\n    else {\n      return 32 + mi_clz_generic32((uint32_t)x);\n    }\n  #endif\n}\n\n#endif\n\n// \"bit scan reverse\": Return index of the highest bit (or MI_SIZE_BITS if `x` is zero)\nstatic inline size_t mi_bsr(size_t x) {\n  return (x==0 ? MI_SIZE_BITS : MI_SIZE_BITS - 1 - mi_clz(x));\n}\n\nsize_t _mi_popcount_generic(size_t x);\n\nstatic inline size_t mi_popcount(size_t x) {\n  if (x<=1) return x;\n  if (x==SIZE_MAX) return MI_SIZE_BITS;\n  #if defined(__GNUC__)\n    #if (SIZE_MAX == ULONG_MAX)\n      return __builtin_popcountl(x);\n    #else\n      return __builtin_popcountll(x);\n    #endif\n  #else\n    return _mi_popcount_generic(x);\n  #endif\n}\n\n// ---------------------------------------------------------------------------------\n// Provide our own `_mi_memcpy` for potential performance optimizations.\n//\n// For now, only on Windows with msvc/clang-cl we optimize to `rep movsb` if\n// we happen to run on x86/x64 cpu's that have \"fast short rep movsb\" (FSRM) support\n// (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017). See also issue #201 and pr #253.\n// ---------------------------------------------------------------------------------\n\n#if !MI_TRACK_ENABLED && defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))\n#include <intrin.h>\nextern mi_decl_hidden bool _mi_cpu_has_fsrm;\nextern mi_decl_hidden bool _mi_cpu_has_erms;\nstatic inline void _mi_memcpy(void* dst, const void* src, size_t n) {\n  if (_mi_cpu_has_fsrm && n <= 127) { // || (_mi_cpu_has_erms && n > 128)) {\n    __movsb((unsigned char*)dst, (const unsigned char*)src, n);\n  }\n  else {\n    memcpy(dst, src, n);\n  }\n}\nstatic inline void _mi_memzero(void* dst, size_t n) {\n  if (_mi_cpu_has_fsrm && n <= 127) { // || (_mi_cpu_has_erms && n > 128)) {\n    __stosb((unsigned char*)dst, 0, n);\n  }\n  else {\n    memset(dst, 0, n);\n  }\n}\n#else\nstatic inline void _mi_memcpy(void* dst, const void* src, size_t n) {\n  memcpy(dst, src, n);\n}\nstatic inline void _mi_memzero(void* dst, size_t n) {\n  memset(dst, 0, n);\n}\n#endif\n\n// -------------------------------------------------------------------------------\n// The `_mi_memcpy_aligned` can be used if the pointers are machine-word aligned\n// This is used for example in `mi_realloc`.\n// -------------------------------------------------------------------------------\n\n#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)\n// On GCC/CLang we provide a hint that the pointers are word aligned.\nstatic inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) {\n  mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0));\n  void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE);\n  const void* asrc = __builtin_assume_aligned(src, MI_INTPTR_SIZE);\n  _mi_memcpy(adst, asrc, n);\n}\n\nstatic inline void _mi_memzero_aligned(void* dst, size_t n) {\n  mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0);\n  void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE);\n  _mi_memzero(adst, n);\n}\n#else\n// Default fallback on `_mi_memcpy`\nstatic inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) {\n  mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0));\n  _mi_memcpy(dst, src, n);\n}\n\nstatic inline void _mi_memzero_aligned(void* dst, size_t n) {\n  mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0);\n  _mi_memzero(dst, n);\n}\n#endif\n\n\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/include/mimalloc/prim.h",
      "sha256": "98c53e031ef97d47729889423d8861956006afd50d77f426a5f5982a152521e8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_PRIM_H\n#define MIMALLOC_PRIM_H\n#include \"internal.h\"             // mi_decl_hidden\n\n// --------------------------------------------------------------------------\n// This file specifies the primitive portability API.\n// Each OS/host needs to implement these primitives, see `src/prim`\n// for implementations on Window, macOS, WASI, and Linux/Unix.\n//\n// note: on all primitive functions, we always have result parameters != NULL, and:\n//  addr != NULL and page aligned\n//  size > 0     and page aligned\n//  the return value is an error code as an `int` where 0 is success\n// --------------------------------------------------------------------------\n\n// OS memory configuration\ntypedef struct mi_os_mem_config_s {\n  size_t  page_size;              // default to 4KiB\n  size_t  large_page_size;        // 0 if not supported, usually 2MiB (4MiB on Windows)\n  size_t  alloc_granularity;      // smallest allocation size (usually 4KiB, on Windows 64KiB)\n  size_t  physical_memory_in_kib; // physical memory size in KiB\n  size_t  virtual_address_bits;   // usually 48 or 56 bits on 64-bit systems. (used to determine secure randomization)\n  bool    has_overcommit;         // can we reserve more memory than can be actually committed?\n  bool    has_partial_free;       // can allocated blocks be freed partially? (true for mmap, false for VirtualAlloc)\n  bool    has_virtual_reserve;    // supports virtual address space reservation? (if true we can reserve virtual address space without using commit or physical memory)\n} mi_os_mem_config_t;\n\n// Initialize\nvoid _mi_prim_mem_init( mi_os_mem_config_t* config );\n\n// Free OS memory\nint _mi_prim_free(void* addr, size_t size );\n\n// Allocate OS memory. Return NULL on error.\n// The `try_alignment` is just a hint and the returned pointer does not have to be aligned.\n// If `commit` is false, the virtual memory range only needs to be reserved (with no access)\n// which will later be committed explicitly using `_mi_prim_commit`.\n// `is_zero` is set to true if the memory was zero initialized (as on most OS's)\n// The `hint_addr` address is either `NULL` or a preferred allocation address but can be ignored.\n// pre: !commit => !allow_large\n//      try_alignment >= _mi_os_page_size() and a power of 2\nint _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr);\n\n// Commit memory. Returns error code or 0 on success.\n// For example, on Linux this would make the memory PROT_READ|PROT_WRITE.\n// `is_zero` is set to true if the memory was zero initialized (e.g. on Windows)\nint _mi_prim_commit(void* addr, size_t size, bool* is_zero);\n\n// Decommit memory. Returns error code or 0 on success. The `needs_recommit` result is true\n// if the memory would need to be re-committed. For example, on Windows this is always true,\n// but on Linux we could use MADV_DONTNEED to decommit which does not need a recommit.\n// pre: needs_recommit != NULL\nint _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit);\n\n// Reset memory. The range keeps being accessible but the content might be reset to zero at any moment.\n// Returns error code or 0 on success.\nint _mi_prim_reset(void* addr, size_t size);\n\n// Reuse memory. This is called for memory that is already committed but\n// may have been reset (`_mi_prim_reset`) or decommitted (`_mi_prim_decommit`) where `needs_recommit` was false.\n// Returns error code or 0 on success. On most platforms this is a no-op.\nint _mi_prim_reuse(void* addr, size_t size);\n\n// Protect memory. Returns error code or 0 on success.\nint _mi_prim_protect(void* addr, size_t size, bool protect);\n\n// Allocate huge (1GiB) pages possibly associated with a NUMA node.\n// `is_zero` is set to true if the memory was zero initialized (as on most OS's)\n// pre: size > 0  and a multiple of 1GiB.\n//      numa_node is either negative (don't care), or a numa node number.\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr);\n\n// Return the current NUMA node\nsize_t _mi_prim_numa_node(void);\n\n// Return the number of logical NUMA nodes\nsize_t _mi_prim_numa_node_count(void);\n\n// Clock ticks\nmi_msecs_t _mi_prim_clock_now(void);\n\n// Return process information (only for statistics)\ntypedef struct mi_process_info_s {\n  mi_msecs_t  elapsed;\n  mi_msecs_t  utime;\n  mi_msecs_t  stime;\n  size_t      current_rss;\n  size_t      peak_rss;\n  size_t      current_commit;\n  size_t      peak_commit;\n  size_t      page_faults;\n} mi_process_info_t;\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo);\n\n// Default stderr output. (only for warnings etc. with verbose enabled)\n// msg != NULL && _mi_strlen(msg) > 0\nvoid _mi_prim_out_stderr( const char* msg );\n\n// Get an environment variable. (only for options)\n// name != NULL, result != NULL, result_size >= 64\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size);\n\n\n// Fill a buffer with strong randomness; return `false` on error or if\n// there is no strong randomization available.\nbool _mi_prim_random_buf(void* buf, size_t buf_len);\n\n// Called on the first thread start, and should ensure `_mi_thread_done` is called on thread termination.\nvoid _mi_prim_thread_init_auto_done(void);\n\n// Called on process exit and may take action to clean up resources associated with the thread auto done.\nvoid _mi_prim_thread_done_auto_done(void);\n\n// Called when the default heap for a thread changes\nvoid _mi_prim_thread_associate_default_heap(mi_heap_t* heap);\n\n\n//-------------------------------------------------------------------\n// Access to TLS (thread local storage) slots.\n// We need fast access to both a unique thread id (in `free.c:mi_free`) and\n// to a thread-local heap pointer (in `alloc.c:mi_malloc`).\n// To achieve this we use specialized code for various platforms.\n//-------------------------------------------------------------------\n\n// On some libc + platform combinations we can directly access a thread-local storage (TLS) slot.\n// The TLS layout depends on both the OS and libc implementation so we use specific tests for each main platform.\n// If you test on another platform and it works please send a PR :-)\n// see also https://akkadia.org/drepper/tls.pdf for more info on the TLS register.\n//\n// Note: we would like to prefer `__builtin_thread_pointer()` nowadays instead of using assembly,\n// but unfortunately we can not detect support reliably (see issue #883)\n// We also use it on Apple OS as we use a TLS slot for the default heap there.\n#if defined(__GNUC__) && ( \\\n           (defined(__GLIBC__)   && (defined(__x86_64__) || defined(__i386__) || (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__))) \\\n        || (defined(__APPLE__)   && (defined(__x86_64__) || defined(__aarch64__) || defined(__POWERPC__))) \\\n        || (defined(__BIONIC__)  && (defined(__x86_64__) || defined(__i386__) || (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__))) \\\n        || (defined(__FreeBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \\\n        || (defined(__OpenBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \\\n      )\n\n#define MI_HAS_TLS_SLOT    1\n\nstatic inline void* mi_prim_tls_slot(size_t slot) mi_attr_noexcept {\n  void* res;\n  const size_t ofs = (slot*sizeof(void*));\n  #if defined(__i386__)\n    __asm__(\"movl %%gs:%1, %0\" : \"=r\" (res) : \"m\" (*((void**)ofs)) : );  // x86 32-bit always uses GS\n  #elif defined(__APPLE__) && defined(__x86_64__)\n    __asm__(\"movq %%gs:%1, %0\" : \"=r\" (res) : \"m\" (*((void**)ofs)) : );  // x86_64 macOSX uses GS\n  #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4)\n    __asm__(\"movl %%fs:%1, %0\" : \"=r\" (res) : \"m\" (*((void**)ofs)) : );  // x32 ABI\n  #elif defined(__x86_64__)\n    __asm__(\"movq %%fs:%1, %0\" : \"=r\" (res) : \"m\" (*((void**)ofs)) : );  // x86_64 Linux, BSD uses FS\n  #elif defined(__arm__)\n    void** tcb; MI_UNUSED(ofs);\n    __asm__ volatile (\"mrc p15, 0, %0, c13, c0, 3\\nbic %0, %0, #3\" : \"=r\" (tcb));\n    res = tcb[slot];\n  #elif defined(__aarch64__)\n    void** tcb; MI_UNUSED(ofs);\n    #if defined(__APPLE__) // M1, issue #343\n    __asm__ volatile (\"mrs %0, tpidrro_el0\\nbic %0, %0, #7\" : \"=r\" (tcb));\n    #else\n    __asm__ volatile (\"mrs %0, tpidr_el0\" : \"=r\" (tcb));\n    #endif\n    res = tcb[slot];\n  #elif defined(__APPLE__) && defined(__POWERPC__) // ppc, issue #781\n    MI_UNUSED(ofs);\n    res = pthread_getspecific(slot);\n  #endif\n  return res;\n}\n\n// setting a tls slot is only used on macOS for now\nstatic inline void mi_prim_tls_slot_set(size_t slot, void* value) mi_attr_noexcept {\n  const size_t ofs = (slot*sizeof(void*));\n  #if defined(__i386__)\n    __asm__(\"movl %1,%%gs:%0\" : \"=m\" (*((void**)ofs)) : \"rn\" (value) : );  // 32-bit always uses GS\n  #elif defined(__APPLE__) && defined(__x86_64__)\n    __asm__(\"movq %1,%%gs:%0\" : \"=m\" (*((void**)ofs)) : \"rn\" (value) : );  // x86_64 macOS uses GS\n  #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4)\n    __asm__(\"movl %1,%%fs:%0\" : \"=m\" (*((void**)ofs)) : \"rn\" (value) : );  // x32 ABI\n  #elif defined(__x86_64__)\n    __asm__(\"movq %1,%%fs:%0\" : \"=m\" (*((void**)ofs)) : \"rn\" (value) : );  // x86_64 Linux, BSD uses FS\n  #elif defined(__arm__)\n    void** tcb; MI_UNUSED(ofs);\n    __asm__ volatile (\"mrc p15, 0, %0, c13, c0, 3\\nbic %0, %0, #3\" : \"=r\" (tcb));\n    tcb[slot] = value;\n  #elif defined(__aarch64__)\n    void** tcb; MI_UNUSED(ofs);\n    #if defined(__APPLE__) // M1, issue #343\n    __asm__ volatile (\"mrs %0, tpidrro_el0\\nbic %0, %0, #7\" : \"=r\" (tcb));\n    #else\n    __asm__ volatile (\"mrs %0, tpidr_el0\" : \"=r\" (tcb));\n    #endif\n    tcb[slot] = value;\n  #elif defined(__APPLE__) && defined(__POWERPC__) // ppc, issue #781\n    MI_UNUSED(ofs);\n    pthread_setspecific(slot, value);\n  #endif\n}\n\n#elif _WIN32 && MI_WIN_USE_FIXED_TLS && !defined(MI_WIN_USE_FLS)\n\n// On windows we can store the thread-local heap at a fixed TLS slot to avoid\n// thread-local initialization checks in the fast path.\n// We allocate a user TLS slot at process initialization (see `windows/prim.c`)\n// and store the offset `_mi_win_tls_offset`.\n#define MI_HAS_TLS_SLOT  1              // 2 = we can reliably initialize the slot (saving a test on each malloc)\n\nextern mi_decl_hidden size_t _mi_win_tls_offset;\n\n#if MI_WIN_USE_FIXED_TLS > 1\n#define MI_TLS_SLOT     (MI_WIN_USE_FIXED_TLS)\n#elif MI_SIZE_SIZE == 4\n#define MI_TLS_SLOT     (0x0E10 + _mi_win_tls_offset)  // User TLS slots <https://en.wikipedia.org/wiki/Win32_Thread_Information_Block>\n#else\n#define MI_TLS_SLOT     (0x1480 + _mi_win_tls_offset)  // User TLS slots <https://en.wikipedia.org/wiki/Win32_Thread_Information_Block>\n#endif\n\nstatic inline void* mi_prim_tls_slot(size_t slot) mi_attr_noexcept {\n  #if (_M_X64 || _M_AMD64) && !defined(_M_ARM64EC)\n  return (void*)__readgsqword((unsigned long)slot);   // direct load at offset from gs\n  #elif _M_IX86 && !defined(_M_ARM64EC)\n  return (void*)__readfsdword((unsigned long)slot);   // direct load at offset from fs\n  #else\n  return ((void**)NtCurrentTeb())[slot / sizeof(void*)];\n  #endif\n}\nstatic inline void mi_prim_tls_slot_set(size_t slot, void* value) mi_attr_noexcept {\n  ((void**)NtCurrentTeb())[slot / sizeof(void*)] = value;\n}\n\n#endif\n\n\n\n//-------------------------------------------------------------------\n// Get a fast unique thread id.\n//\n// Getting the thread id should be performant as it is called in the\n// fast path of `_mi_free` and we specialize for various platforms as\n// inlined definitions. Regular code should call `init.c:_mi_thread_id()`.\n// We only require _mi_prim_thread_id() to return a unique id\n// for each thread (unequal to zero).\n//-------------------------------------------------------------------\n\n\n// Do we have __builtin_thread_pointer? This would be the preferred way to get a unique thread id\n// but unfortunately, it seems we cannot test for this reliably at this time (see issue #883)\n// Nevertheless, it seems needed on older graviton platforms (see issue #851).\n// For now, we only enable this for specific platforms.\n#if !defined(MI_USE_BUILTIN_THREAD_POINTER)   /* allow user override */\n  #if !defined(__APPLE__)  /* on apple (M1) the wrong register is read (tpidr_el0 instead of tpidrro_el0) so fall back to TLS slot assembly (<https://github.com/microsoft/mimalloc/issues/343#issuecomment-763272369>)*/ \\\n      && !defined(__CYGWIN__) \\\n      && !defined(MI_LIBC_MUSL) \\\n      && (!defined(__clang_major__) || __clang_major__ >= 14)  /* older clang versions emit bad code; fall back to using the TLS slot (<https://lore.kernel.org/linux-arm-kernel/202110280952.352F66D8@keescook/T/>) */\n    #if    (defined(__GNUC__) && (__GNUC__ >= 7)  && defined(__aarch64__)) /* aarch64 for older gcc versions (issue #851) */ \\\n        || (defined(__GNUC__) && (__GNUC__ >= 11) && defined(__x86_64__)) \\\n        || (defined(__clang_major__) && (__clang_major__ >= 14) && (defined(__aarch64__) || defined(__x86_64__)))\n      #define MI_USE_BUILTIN_THREAD_POINTER  1\n    #endif\n  #endif\n#endif\n\n\n\n// defined in `init.c`; do not use these directly\nextern mi_decl_hidden mi_decl_thread mi_heap_t* _mi_heap_default;  // default heap to allocate from\nextern mi_decl_hidden bool _mi_process_is_initialized;             // has mi_process_init been called?\n\nstatic inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept;\n\n// Get a unique id for the current thread.\n#if defined(MI_PRIM_THREAD_ID)\n\nstatic inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {\n  const mi_threadid_t tid = MI_PRIM_THREAD_ID();  // used for example by CPython for a free threaded build (see python/cpython#115488)\n  mi_assert_internal( (tid & 0x03) == 0 );        // mimalloc reserves the bottom 2 bits\n  return tid;\n}\n\n#elif defined(_WIN32)\n\nstatic inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {\n  // Windows: works on Intel and ARM in both 32- and 64-bit\n  return (uintptr_t)NtCurrentTeb();\n}\n\n#elif MI_USE_BUILTIN_THREAD_POINTER\n\nstatic inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {\n  // Works on most Unix based platforms with recent compilers\n  return (uintptr_t)__builtin_thread_pointer();\n}\n\n#elif MI_HAS_TLS_SLOT\n\nstatic inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {\n  #if defined(__BIONIC__)\n    // issue #384, #495: on the Bionic libc (Android), slot 1 is the thread id\n    // see: https://github.com/aosp-mirror/platform_bionic/blob/c44b1d0676ded732df4b3b21c5f798eacae93228/libc/platform/bionic/tls_defines.h#L86\n    return (uintptr_t)mi_prim_tls_slot(1);\n  #else\n    // in all our other targets, slot 0 is the thread id\n    // glibc: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=sysdeps/x86_64/nptl/tls.h\n    // apple: https://github.com/apple/darwin-xnu/blob/main/libsyscall/os/tsd.h#L36\n    return (uintptr_t)mi_prim_tls_slot(0);\n  #endif\n}\n\n#else\n\n// otherwise use portable C, taking the address of a thread local variable (this is still very fast on most platforms).\nstatic inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {\n  return (uintptr_t)&_mi_heap_default;\n}\n\n#endif\n\n\n\n/* ----------------------------------------------------------------------------------------\nGet the thread local default heap: `_mi_prim_get_default_heap()`\n\nThis is inlined here as it is on the fast path for allocation functions.\n\nOn most platforms (Windows, Linux, FreeBSD, NetBSD, etc), this just returns a\n__thread local variable (`_mi_heap_default`). With the initial-exec TLS model this ensures\nthat the storage will always be available (allocated on the thread stacks).\n\nOn some platforms though we cannot use that when overriding `malloc` since the underlying\nTLS implementation (or the loader) will call itself `malloc` on a first access and recurse.\nWe try to circumvent this in an efficient way:\n- macOSX : we use an unused TLS slot from the OS allocated slots (MI_TLS_SLOT). On OSX, the\n           loader itself calls `malloc` even before the modules are initialized.\n- OpenBSD: we use an unused slot from the pthread block (MI_TLS_PTHREAD_SLOT_OFS).\n- DragonFly: defaults are working but seem slow compared to freeBSD (see PR #323)\n------------------------------------------------------------------------------------------- */\n\nstatic inline mi_heap_t* mi_prim_get_default_heap(void);\n\n#if defined(MI_MALLOC_OVERRIDE)\n#if defined(__APPLE__) // macOS\n  #define MI_TLS_SLOT               89  // seems unused?\n  // other possible unused ones are 9, 29, __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 (94), __PTK_FRAMEWORK_GC_KEY9 (112) and __PTK_FRAMEWORK_OLDGC_KEY9 (89)\n  // see <https://github.com/rweichler/substrate/blob/master/include/pthread_machdep.h>\n#elif defined(__OpenBSD__)\n  // use end bytes of a name; goes wrong if anyone uses names > 23 characters (ptrhread specifies 16)\n  // see <https://github.com/openbsd/src/blob/master/lib/libc/include/thread_private.h#L371>\n  #define MI_TLS_PTHREAD_SLOT_OFS   (6*sizeof(int) + 4*sizeof(void*) + 24)\n  // #elif defined(__DragonFly__)\n  // #warning \"mimalloc is not working correctly on DragonFly yet.\"\n  // #define MI_TLS_PTHREAD_SLOT_OFS   (4 + 1*sizeof(void*))  // offset `uniqueid` (also used by gdb?) <https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/lib/libthread_xu/thread/thr_private.h#L458>\n#elif defined(__ANDROID__)\n  // See issue #381\n  #define MI_TLS_PTHREAD\n#endif\n#endif\n\n\n#if MI_TLS_SLOT\n# if !defined(MI_HAS_TLS_SLOT)\n#  error \"trying to use a TLS slot for the default heap, but the mi_prim_tls_slot primitives are not defined\"\n# endif\n\nstatic inline mi_heap_t* mi_prim_get_default_heap(void) {\n  mi_heap_t* heap = (mi_heap_t*)mi_prim_tls_slot(MI_TLS_SLOT);\n  #if MI_HAS_TLS_SLOT == 1   // check if the TLS slot is initialized\n  if mi_unlikely(heap == NULL) {\n    #ifdef __GNUC__\n    __asm(\"\"); // prevent conditional load of the address of _mi_heap_empty\n    #endif\n    heap = (mi_heap_t*)&_mi_heap_empty;\n  }\n  #endif\n  return heap;\n}\n\n#elif defined(MI_TLS_PTHREAD_SLOT_OFS)\n\nstatic inline mi_heap_t** mi_prim_tls_pthread_heap_slot(void) {\n  pthread_t self = pthread_self();\n  #if defined(__DragonFly__)\n  if (self==NULL) return NULL;\n  #endif\n  return (mi_heap_t**)((uint8_t*)self + MI_TLS_PTHREAD_SLOT_OFS);\n}\n\nstatic inline mi_heap_t* mi_prim_get_default_heap(void) {\n  mi_heap_t** pheap = mi_prim_tls_pthread_heap_slot();\n  if mi_unlikely(pheap == NULL) return _mi_heap_main_get();\n  mi_heap_t* heap = *pheap;\n  if mi_unlikely(heap == NULL) return (mi_heap_t*)&_mi_heap_empty;\n  return heap;\n}\n\n#elif defined(MI_TLS_PTHREAD)\n\nextern mi_decl_hidden pthread_key_t _mi_heap_default_key;\nstatic inline mi_heap_t* mi_prim_get_default_heap(void) {\n  mi_heap_t* heap = (mi_unlikely(_mi_heap_default_key == (pthread_key_t)(-1)) ? _mi_heap_main_get() : (mi_heap_t*)pthread_getspecific(_mi_heap_default_key));\n  return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap);\n}\n\n#else // default using a thread local variable; used on most platforms.\n\nstatic inline mi_heap_t* mi_prim_get_default_heap(void) {\n  #if defined(MI_TLS_RECURSE_GUARD)\n  if (mi_unlikely(!_mi_process_is_initialized)) return _mi_heap_main_get();\n  #endif\n  return _mi_heap_default;\n}\n\n#endif  // mi_prim_get_default_heap()\n\n\n#endif  // MIMALLOC_PRIM_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/include/mimalloc/track.h",
      "sha256": "4a1587dd06f7600b887b9a19e4103c65e165d680f93a359e47860baf97c7c78f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_TRACK_H\n#define MIMALLOC_TRACK_H\n\n/* ------------------------------------------------------------------------------------------------------\nTrack memory ranges with macros for tools like Valgrind address sanitizer, or other memory checkers.\nThese can be defined for tracking allocation:\n\n  #define mi_track_malloc_size(p,reqsize,size,zero)\n  #define mi_track_free_size(p,_size)\n\nThe macros are set up such that the size passed to `mi_track_free_size`\nalways matches the size of `mi_track_malloc_size`. (currently, `size == mi_usable_size(p)`).\nThe `reqsize` is what the user requested, and `size >= reqsize`.\nThe `size` is either byte precise (and `size==reqsize`) if `MI_PADDING` is enabled,\nor otherwise it is the usable block size which may be larger than the original request.\nUse `_mi_block_size_of(void* p)` to get the full block size that was allocated (including padding etc).\nThe `zero` parameter is `true` if the allocated block is zero initialized.\n\nOptional:\n\n  #define mi_track_align(p,alignedp,offset,size)\n  #define mi_track_resize(p,oldsize,newsize)\n  #define mi_track_init()\n\nThe `mi_track_align` is called right after a `mi_track_malloc` for aligned pointers in a block.\nThe corresponding `mi_track_free` still uses the block start pointer and original size (corresponding to the `mi_track_malloc`).\nThe `mi_track_resize` is currently unused but could be called on reallocations within a block.\n`mi_track_init` is called at program start.\n\nThe following macros are for tools like asan and valgrind to track whether memory is\ndefined, undefined, or not accessible at all:\n\n  #define mi_track_mem_defined(p,size)\n  #define mi_track_mem_undefined(p,size)\n  #define mi_track_mem_noaccess(p,size)\n\n-------------------------------------------------------------------------------------------------------*/\n\n#if MI_TRACK_VALGRIND\n// valgrind tool\n\n#define MI_TRACK_ENABLED      1\n#define MI_TRACK_HEAP_DESTROY 1           // track free of individual blocks on heap_destroy\n#define MI_TRACK_TOOL         \"valgrind\"\n\n#include <valgrind/valgrind.h>\n#include <valgrind/memcheck.h>\n\n#define mi_track_malloc_size(p,reqsize,size,zero) VALGRIND_MALLOCLIKE_BLOCK(p,size,MI_PADDING_SIZE /*red zone*/,zero)\n#define mi_track_free_size(p,_size)               VALGRIND_FREELIKE_BLOCK(p,MI_PADDING_SIZE /*red zone*/)\n#define mi_track_resize(p,oldsize,newsize)        VALGRIND_RESIZEINPLACE_BLOCK(p,oldsize,newsize,MI_PADDING_SIZE /*red zone*/)\n#define mi_track_mem_defined(p,size)              VALGRIND_MAKE_MEM_DEFINED(p,size)\n#define mi_track_mem_undefined(p,size)            VALGRIND_MAKE_MEM_UNDEFINED(p,size)\n#define mi_track_mem_noaccess(p,size)             VALGRIND_MAKE_MEM_NOACCESS(p,size)\n\n#elif MI_TRACK_ASAN\n// address sanitizer\n\n#define MI_TRACK_ENABLED      1\n#define MI_TRACK_HEAP_DESTROY 0\n#define MI_TRACK_TOOL         \"asan\"\n\n#include <sanitizer/asan_interface.h>\n\n#define mi_track_malloc_size(p,reqsize,size,zero) ASAN_UNPOISON_MEMORY_REGION(p,size)\n#define mi_track_free_size(p,size)                ASAN_POISON_MEMORY_REGION(p,size)\n#define mi_track_mem_defined(p,size)              ASAN_UNPOISON_MEMORY_REGION(p,size)\n#define mi_track_mem_undefined(p,size)            ASAN_UNPOISON_MEMORY_REGION(p,size)\n#define mi_track_mem_noaccess(p,size)             ASAN_POISON_MEMORY_REGION(p,size)\n\n#elif MI_TRACK_ETW\n// windows event tracing\n\n#define MI_TRACK_ENABLED      1\n#define MI_TRACK_HEAP_DESTROY 1\n#define MI_TRACK_TOOL         \"ETW\"\n\n#include \"../src/prim/windows/etw.h\"\n\n#define mi_track_init()                           EventRegistermicrosoft_windows_mimalloc()\n#define mi_track_done()                           EventUnregistermicrosoft_windows_mimalloc()\n#define mi_track_malloc_size(p,reqsize,size,zero) EventWriteETW_MI_ALLOC((UINT64)(p), size)\n#define mi_track_free_size(p,size)                EventWriteETW_MI_FREE((UINT64)(p), size)\n\n#else\n// no tracking\n\n#define MI_TRACK_ENABLED      0\n#define MI_TRACK_HEAP_DESTROY 0\n#define MI_TRACK_TOOL         \"none\"\n\n#define mi_track_malloc_size(p,reqsize,size,zero)\n#define mi_track_free_size(p,_size)\n\n#endif\n\n// -------------------\n// Utility definitions\n\n#ifndef mi_track_resize\n#define mi_track_resize(p,oldsize,newsize)      do{ mi_track_free_size(p,oldsize); mi_track_malloc(p,newsize,false); } while(0)\n#endif\n\n#ifndef mi_track_align\n#define mi_track_align(p,alignedp,offset,size)  mi_track_mem_noaccess(p,offset)\n#endif\n\n#ifndef mi_track_init\n#define mi_track_init()\n#endif\n\n#ifndef mi_track_done\n#define mi_track_done()\n#endif\n\n#ifndef mi_track_mem_defined\n#define mi_track_mem_defined(p,size)\n#endif\n\n#ifndef mi_track_mem_undefined\n#define mi_track_mem_undefined(p,size)\n#endif\n\n#ifndef mi_track_mem_noaccess\n#define mi_track_mem_noaccess(p,size)\n#endif\n\n\n#if MI_PADDING\n#define mi_track_malloc(p,reqsize,zero) \\\n  if ((p)!=NULL) { \\\n    mi_assert_internal(mi_usable_size(p)==(reqsize)); \\\n    mi_track_malloc_size(p,reqsize,reqsize,zero); \\\n  }\n#else\n#define mi_track_malloc(p,reqsize,zero) \\\n  if ((p)!=NULL) { \\\n    mi_assert_internal(mi_usable_size(p)>=(reqsize)); \\\n    mi_track_malloc_size(p,reqsize,mi_usable_size(p),zero); \\\n  }\n#endif\n\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/include/mimalloc/types.h",
      "sha256": "449ac01b7e54cc8e350c1fbeaa033e57cab22011cb7ab9be39f86de5a2623671",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_TYPES_H\n#define MIMALLOC_TYPES_H\n\n// --------------------------------------------------------------------------\n// This file contains the main type definitions for mimalloc:\n// mi_heap_t      : all data for a thread-local heap, contains\n//                  lists of all managed heap pages.\n// mi_segment_t   : a larger chunk of memory (32MiB on 64-bit) from where pages\n//                  are allocated. A segment is divided in slices (64KiB) from\n//                  which pages are allocated.\n// mi_page_t      : a \"mimalloc\" page (usually 64KiB or 512KiB) from\n//                  where objects are allocated.\n//                  Note: we write \"OS page\" for OS memory pages while\n//                  using plain \"page\" for mimalloc pages (`mi_page_t`).\n// --------------------------------------------------------------------------\n\n\n#include <mimalloc-stats.h>\n#include <stddef.h>   // ptrdiff_t\n#include <stdint.h>   // uintptr_t, uint16_t, etc\n#include <stdbool.h>  // bool\n#include \"atomic.h\"   // _Atomic\n\n#ifdef _MSC_VER\n#pragma warning(disable:4214) // bitfield is not int\n#endif\n\n// Minimal alignment necessary. On most platforms 16 bytes are needed\n// due to SSE registers for example. This must be at least `sizeof(void*)`\n#ifndef MI_MAX_ALIGN_SIZE\n#define MI_MAX_ALIGN_SIZE  16   // sizeof(max_align_t)\n#endif\n\n// ------------------------------------------------------\n// Variants\n// ------------------------------------------------------\n\n// Define NDEBUG in the release version to disable assertions.\n// #define NDEBUG\n\n// Define MI_TRACK_<tool> to enable tracking support\n// #define MI_TRACK_VALGRIND 1\n// #define MI_TRACK_ASAN     1\n// #define MI_TRACK_ETW      1\n\n// Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance).\n// #define MI_STAT 1\n\n// Define MI_SECURE to enable security mitigations\n// #define MI_SECURE 1  // guard pages around meta data, randomize arena allocation addresses (like ASLR), abort on detected meta data corruption\n// #define MI_SECURE 2  // randomize relative allocation addresses (within mimalloc pages)\n// #define MI_SECURE 3  // encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free)\n// #define MI_SECURE 4  // checks for double free (may be more expensive) (`-DMI_SECURE=ON`)\n// #define MI_SECURE 5  // guard page at the end of each mimalloc page (expensive!) (`-DMI_SECURE_FULL=ON`)\n\n#if !defined(MI_SECURE)\n#define MI_SECURE 0\n#endif\n\n// Define MI_DEBUG for assertion and invariant checking\n// #define MI_DEBUG 1  // basic assertion checks and statistics, check double free, corrupted free list, and invalid pointer free. (cmake -DMI_DEBUG=ON)\n// #define MI_DEBUG 2  // + internal assertion checks (cmake -DMI_DEBUG_INTERNAL=ON)\n// #define MI_DEBUG 3  // + extensive internal invariant checking (cmake -DMI_DEBUG_FULL=ON)\n#if !defined(MI_DEBUG)\n#if defined(MI_BUILD_RELEASE) || defined(NDEBUG)\n#define MI_DEBUG 0\n#else\n#define MI_DEBUG 2\n#endif\n#endif\n\n// Enable guard pages behind objects of a certain size (set by the MIMALLOC_GUARDED_MIN/MAX/SAMPLE_RATE options)\n#if !defined(MI_GUARDED) && MI_DEBUG\n#define MI_GUARDED  1\n#endif\n\n// Reserve extra padding at the end of each block to be more resilient against heap block overflows.\n// The padding can detect buffer overflow on free.\n#if !defined(MI_PADDING) && (MI_SECURE>=3 || MI_DEBUG>=1 || (MI_TRACK_VALGRIND || MI_TRACK_ASAN || MI_TRACK_ETW))\n#define MI_PADDING  1\n#endif\n\n// Check padding bytes; allows byte-precise buffer overflow detection\n#if !defined(MI_PADDING_CHECK) && MI_PADDING && (MI_SECURE>=3 || MI_DEBUG>=1)\n#define MI_PADDING_CHECK 1\n#endif\n\n\n// Encoded free lists allow detection of corrupted free lists\n// and can detect buffer overflows, modify after free, and double `free`s.\n#if (MI_SECURE>=3 || MI_DEBUG>=1)\n#define MI_ENCODE_FREELIST  1\n#endif\n\n\n// We used to abandon huge pages in order to eagerly deallocate it if freed from another thread.\n// Unfortunately, that makes it not possible to visit them during a heap walk or include them in a\n// `mi_heap_destroy`. We therefore instead reset/decommit the huge blocks nowadays if freed from\n// another thread so the memory becomes \"virtually\" available (and eventually gets properly freed by\n// the owning thread).\n// #define MI_HUGE_PAGE_ABANDON 1\n\n\n// ------------------------------------------------------\n// Platform specific values\n// ------------------------------------------------------\n\n// ------------------------------------------------------\n// Size of a pointer.\n// We assume that `sizeof(void*)==sizeof(intptr_t)`\n// and it holds for all platforms we know of.\n//\n// However, the C standard only requires that:\n//  p == (void*)((intptr_t)p))\n// but we also need:\n//  i == (intptr_t)((void*)i)\n// or otherwise one might define an intptr_t type that is larger than a pointer...\n// ------------------------------------------------------\n\n#if INTPTR_MAX > INT64_MAX\n# define MI_INTPTR_SHIFT (4)  // assume 128-bit  (as on arm CHERI for example)\n#elif INTPTR_MAX == INT64_MAX\n# define MI_INTPTR_SHIFT (3)\n#elif INTPTR_MAX == INT32_MAX\n# define MI_INTPTR_SHIFT (2)\n#else\n#error platform pointers must be 32, 64, or 128 bits\n#endif\n\n#if SIZE_MAX == UINT64_MAX\n# define MI_SIZE_SHIFT (3)\ntypedef int64_t  mi_ssize_t;\n#elif SIZE_MAX == UINT32_MAX\n# define MI_SIZE_SHIFT (2)\ntypedef int32_t  mi_ssize_t;\n#else\n#error platform objects must be 32 or 64 bits\n#endif\n\n#if (SIZE_MAX/2) > LONG_MAX\n# define MI_ZU(x)  x##ULL\n# define MI_ZI(x)  x##LL\n#else\n# define MI_ZU(x)  x##UL\n# define MI_ZI(x)  x##L\n#endif\n\n#define MI_INTPTR_SIZE  (1<<MI_INTPTR_SHIFT)\n#define MI_INTPTR_BITS  (MI_INTPTR_SIZE*8)\n\n#define MI_SIZE_SIZE  (1<<MI_SIZE_SHIFT)\n#define MI_SIZE_BITS  (MI_SIZE_SIZE*8)\n\n#define MI_KiB     (MI_ZU(1024))\n#define MI_MiB     (MI_KiB*MI_KiB)\n#define MI_GiB     (MI_MiB*MI_KiB)\n\n\n// ------------------------------------------------------\n// Main internal data-structures\n// ------------------------------------------------------\n\n// Main tuning parameters for segment and page sizes\n// Sizes for 64-bit (usually divide by two for 32-bit)\n#ifndef MI_SEGMENT_SLICE_SHIFT\n#define MI_SEGMENT_SLICE_SHIFT            (13 + MI_INTPTR_SHIFT)         // 64KiB  (32KiB on 32-bit)\n#endif\n\n#ifndef MI_SEGMENT_SHIFT\n#if MI_INTPTR_SIZE > 4\n#define MI_SEGMENT_SHIFT                  ( 9 + MI_SEGMENT_SLICE_SHIFT)  // 32MiB\n#else\n#define MI_SEGMENT_SHIFT                  ( 7 + MI_SEGMENT_SLICE_SHIFT)  // 4MiB on 32-bit\n#endif\n#endif\n\n#ifndef MI_SMALL_PAGE_SHIFT\n#define MI_SMALL_PAGE_SHIFT               (MI_SEGMENT_SLICE_SHIFT)       // 64KiB\n#endif\n#ifndef MI_MEDIUM_PAGE_SHIFT\n#define MI_MEDIUM_PAGE_SHIFT              ( 3 + MI_SMALL_PAGE_SHIFT)     // 512KiB\n#endif\n\n// Derived constants\n#define MI_SEGMENT_SIZE                   (MI_ZU(1)<<MI_SEGMENT_SHIFT)\n#define MI_SEGMENT_ALIGN                  MI_SEGMENT_SIZE\n#define MI_SEGMENT_MASK                   ((uintptr_t)(MI_SEGMENT_ALIGN - 1))\n#define MI_SEGMENT_SLICE_SIZE             (MI_ZU(1)<< MI_SEGMENT_SLICE_SHIFT)\n#define MI_SLICES_PER_SEGMENT             (MI_SEGMENT_SIZE / MI_SEGMENT_SLICE_SIZE) // 512 (128 on 32-bit)\n\n#define MI_SMALL_PAGE_SIZE                (MI_ZU(1)<<MI_SMALL_PAGE_SHIFT)\n#define MI_MEDIUM_PAGE_SIZE               (MI_ZU(1)<<MI_MEDIUM_PAGE_SHIFT)\n\n#define MI_SMALL_OBJ_SIZE_MAX             (MI_SMALL_PAGE_SIZE/8)   // 8 KiB on 64-bit\n#define MI_MEDIUM_OBJ_SIZE_MAX            (MI_MEDIUM_PAGE_SIZE/8)  // 64 KiB on 64-bit\n#define MI_MEDIUM_OBJ_WSIZE_MAX           (MI_MEDIUM_OBJ_SIZE_MAX/MI_INTPTR_SIZE)\n#define MI_LARGE_OBJ_SIZE_MAX             (MI_SEGMENT_SIZE/2)      // 16 MiB on 64-bit\n#define MI_LARGE_OBJ_WSIZE_MAX            (MI_LARGE_OBJ_SIZE_MAX/MI_INTPTR_SIZE)\n\n// Maximum number of size classes. (spaced exponentially in 12.5% increments)\n#if MI_BIN_HUGE != 73U\n#error \"mimalloc internal: expecting 73 bins\"\n#endif\n\n#if (MI_MEDIUM_OBJ_WSIZE_MAX >= 655360)\n#error \"mimalloc internal: define more bins\"\n#endif\n\n// Maximum block size for which blocks are guaranteed to be block size aligned. (see `segment.c:_mi_segment_page_start`)\n#define MI_MAX_ALIGN_GUARANTEE            (MI_MEDIUM_OBJ_SIZE_MAX)\n\n// Alignments over MI_BLOCK_ALIGNMENT_MAX are allocated in dedicated huge page segments\n#define MI_BLOCK_ALIGNMENT_MAX            (MI_SEGMENT_SIZE >> 1)\n\n// Maximum slice count (255) for which we can find the page for interior pointers\n#define MI_MAX_SLICE_OFFSET_COUNT         ((MI_BLOCK_ALIGNMENT_MAX / MI_SEGMENT_SLICE_SIZE) - 1)\n\n// we never allocate more than PTRDIFF_MAX (see also <https://sourceware.org/ml/libc-announce/2019/msg00001.html>)\n// on 64-bit+ systems we also limit the maximum allocation size such that the slice count fits in 32-bits. (issue #877)\n#if (PTRDIFF_MAX > INT32_MAX) && (PTRDIFF_MAX >= (MI_SEGMENT_SLIZE_SIZE * UINT32_MAX))\n#define MI_MAX_ALLOC_SIZE   (MI_SEGMENT_SLICE_SIZE * (UINT32_MAX-1))\n#else\n#define MI_MAX_ALLOC_SIZE   PTRDIFF_MAX\n#endif\n\n\n// ------------------------------------------------------\n// Mimalloc pages contain allocated blocks\n// ------------------------------------------------------\n\n// The free lists use encoded next fields\n// (Only actually encodes when MI_ENCODED_FREELIST is defined.)\ntypedef uintptr_t  mi_encoded_t;\n\n// thread id's\ntypedef size_t     mi_threadid_t;\n\n// free lists contain blocks\ntypedef struct mi_block_s {\n  mi_encoded_t next;\n} mi_block_t;\n\n#if MI_GUARDED\n// we always align guarded pointers in a block at an offset\n// the block `next` field is then used as a tag to distinguish regular offset aligned blocks from guarded ones\n#define MI_BLOCK_TAG_ALIGNED   ((mi_encoded_t)(0))\n#define MI_BLOCK_TAG_GUARDED   (~MI_BLOCK_TAG_ALIGNED)\n#endif\n\n\n// The delayed flags are used for efficient multi-threaded free-ing\ntypedef enum mi_delayed_e {\n  MI_USE_DELAYED_FREE   = 0, // push on the owning heap thread delayed list\n  MI_DELAYED_FREEING    = 1, // temporary: another thread is accessing the owning heap\n  MI_NO_DELAYED_FREE    = 2, // optimize: push on page local thread free queue if another block is already in the heap thread delayed free list\n  MI_NEVER_DELAYED_FREE = 3  // sticky: used for abandoned pages without a owning heap; this only resets on page reclaim\n} mi_delayed_t;\n\n\n// The `in_full` and `has_aligned` page flags are put in a union to efficiently\n// test if both are false (`full_aligned == 0`) in the `mi_free` routine.\n#if !MI_TSAN\ntypedef union mi_page_flags_s {\n  uint8_t full_aligned;\n  struct {\n    uint8_t in_full : 1;\n    uint8_t has_aligned : 1;\n  } x;\n} mi_page_flags_t;\n#else\n// under thread sanitizer, use a byte for each flag to suppress warning, issue #130\ntypedef union mi_page_flags_s {\n  uint32_t full_aligned;\n  struct {\n    uint8_t in_full;\n    uint8_t has_aligned;\n  } x;\n} mi_page_flags_t;\n#endif\n\n// Thread free list.\n// We use the bottom 2 bits of the pointer for mi_delayed_t flags\ntypedef uintptr_t mi_thread_free_t;\n\n// A page contains blocks of one specific size (`block_size`).\n// Each page has three list of free blocks:\n// `free` for blocks that can be allocated,\n// `local_free` for freed blocks that are not yet available to `mi_malloc`\n// `thread_free` for freed blocks by other threads\n// The `local_free` and `thread_free` lists are migrated to the `free` list\n// when it is exhausted. The separate `local_free` list is necessary to\n// implement a monotonic heartbeat. The `thread_free` list is needed for\n// avoiding atomic operations in the common case.\n//\n// `used - |thread_free|` == actual blocks that are in use (alive)\n// `used - |thread_free| + |free| + |local_free| == capacity`\n//\n// We don't count `freed` (as |free|) but use `used` to reduce\n// the number of memory accesses in the `mi_page_all_free` function(s).\n//\n// Notes:\n// - Access is optimized for `free.c:mi_free` and `alloc.c:mi_page_alloc`\n// - Using `uint16_t` does not seem to slow things down\n// - The size is 12 words on 64-bit which helps the page index calculations\n//   (and 14 words on 32-bit, and encoded free lists add 2 words)\n// - `xthread_free` uses the bottom bits as a delayed-free flags to optimize\n//   concurrent frees where only the first concurrent free adds to the owning\n//   heap `thread_delayed_free` list (see `free.c:mi_free_block_mt`).\n//   The invariant is that no-delayed-free is only set if there is\n//   at least one block that will be added, or as already been added, to\n//   the owning heap `thread_delayed_free` list. This guarantees that pages\n//   will be freed correctly even if only other threads free blocks.\ntypedef struct mi_page_s {\n  // \"owned\" by the segment\n  uint32_t              slice_count;       // slices in this page (0 if not a page)\n  uint32_t              slice_offset;      // distance from the actual page data slice (0 if a page)\n  uint8_t               is_committed:1;    // `true` if the page virtual memory is committed\n  uint8_t               is_zero_init:1;    // `true` if the page was initially zero initialized\n  uint8_t               is_huge:1;         // `true` if the page is in a huge segment (`segment->kind == MI_SEGMENT_HUGE`)\n                                           // padding\n  // layout like this to optimize access in `mi_malloc` and `mi_free`\n  uint16_t              capacity;          // number of blocks committed, must be the first field, see `segment.c:page_clear`\n  uint16_t              reserved;          // number of blocks reserved in memory\n  mi_page_flags_t       flags;             // `in_full` and `has_aligned` flags (8 bits)\n  uint8_t               free_is_zero:1;    // `true` if the blocks in the free list are zero initialized\n  uint8_t               retire_expire:7;   // expiration count for retired blocks\n\n  mi_block_t*           free;              // list of available free blocks (`malloc` allocates from this list)\n  mi_block_t*           local_free;        // list of deferred free blocks by this thread (migrates to `free`)\n  uint16_t              used;              // number of blocks in use (including blocks in `thread_free`)\n  uint8_t               block_size_shift;  // if not zero, then `(1 << block_size_shift) == block_size` (only used for fast path in `free.c:_mi_page_ptr_unalign`)\n  uint8_t               heap_tag;          // tag of the owning heap, used to separate heaps by object type\n                                           // padding\n  size_t                block_size;        // size available in each block (always `>0`)\n  uint8_t*              page_start;        // start of the page area containing the blocks\n\n  #if (MI_ENCODE_FREELIST || MI_PADDING)\n  uintptr_t             keys[2];           // two random keys to encode the free lists (see `_mi_block_next`) or padding canary\n  #endif\n\n  _Atomic(mi_thread_free_t) xthread_free;  // list of deferred free blocks freed by other threads\n  _Atomic(uintptr_t)        xheap;\n\n  struct mi_page_s*     next;              // next page owned by this thread with the same `block_size`\n  struct mi_page_s*     prev;              // previous page owned by this thread with the same `block_size`\n\n  // 64-bit 11 words, 32-bit 13 words, (+2 for secure)\n  void* padding[1];\n} mi_page_t;\n\n\n\n// ------------------------------------------------------\n// Mimalloc segments contain mimalloc pages\n// ------------------------------------------------------\n\ntypedef enum mi_page_kind_e {\n  MI_PAGE_SMALL,    // small blocks go into 64KiB pages inside a segment\n  MI_PAGE_MEDIUM,   // medium blocks go into 512KiB pages inside a segment\n  MI_PAGE_LARGE,    // larger blocks go into a single page spanning a whole segment\n  MI_PAGE_HUGE      // a huge page is a single page in a segment of variable size\n                    // used for blocks `> MI_LARGE_OBJ_SIZE_MAX` or an alignment `> MI_BLOCK_ALIGNMENT_MAX`.\n} mi_page_kind_t;\n\ntypedef enum mi_segment_kind_e {\n  MI_SEGMENT_NORMAL, // MI_SEGMENT_SIZE size with pages inside.\n  MI_SEGMENT_HUGE,   // segment with just one huge page inside.\n} mi_segment_kind_t;\n\n// ------------------------------------------------------\n// A segment holds a commit mask where a bit is set if\n// the corresponding MI_COMMIT_SIZE area is committed.\n// The MI_COMMIT_SIZE must be a multiple of the slice\n// size. If it is equal we have the most fine grained\n// decommit (but setting it higher can be more efficient).\n// The MI_MINIMAL_COMMIT_SIZE is the minimal amount that will\n// be committed in one go which can be set higher than\n// MI_COMMIT_SIZE for efficiency (while the decommit mask\n// is still tracked in fine-grained MI_COMMIT_SIZE chunks)\n// ------------------------------------------------------\n\n#define MI_MINIMAL_COMMIT_SIZE      (1*MI_SEGMENT_SLICE_SIZE)\n#define MI_COMMIT_SIZE              (MI_SEGMENT_SLICE_SIZE)              // 64KiB\n#define MI_COMMIT_MASK_BITS         (MI_SEGMENT_SIZE / MI_COMMIT_SIZE)\n#define MI_COMMIT_MASK_FIELD_BITS    MI_SIZE_BITS\n#define MI_COMMIT_MASK_FIELD_COUNT  (MI_COMMIT_MASK_BITS / MI_COMMIT_MASK_FIELD_BITS)\n\n#if (MI_COMMIT_MASK_BITS != (MI_COMMIT_MASK_FIELD_COUNT * MI_COMMIT_MASK_FIELD_BITS))\n#error \"the segment size must be exactly divisible by the (commit size * size_t bits)\"\n#endif\n\ntypedef struct mi_commit_mask_s {\n  size_t mask[MI_COMMIT_MASK_FIELD_COUNT];\n} mi_commit_mask_t;\n\ntypedef mi_page_t  mi_slice_t;\ntypedef int64_t    mi_msecs_t;\n\n\n// ---------------------------------------------------------------\n// a memory id tracks the provenance of arena/OS allocated memory\n// ---------------------------------------------------------------\n\n// Memory can reside in arena's, direct OS allocated, or statically allocated. The memid keeps track of this.\ntypedef enum mi_memkind_e {\n  MI_MEM_NONE,      // not allocated\n  MI_MEM_EXTERNAL,  // not owned by mimalloc but provided externally (via `mi_manage_os_memory` for example)\n  MI_MEM_STATIC,    // allocated in a static area and should not be freed (for arena meta data for example)\n  MI_MEM_OS,        // allocated from the OS\n  MI_MEM_OS_HUGE,   // allocated as huge OS pages (usually 1GiB, pinned to physical memory)\n  MI_MEM_OS_REMAP,  // allocated in a remapable area (i.e. using `mremap`)\n  MI_MEM_ARENA      // allocated from an arena (the usual case)\n} mi_memkind_t;\n\nstatic inline bool mi_memkind_is_os(mi_memkind_t memkind) {\n  return (memkind >= MI_MEM_OS && memkind <= MI_MEM_OS_REMAP);\n}\n\ntypedef struct mi_memid_os_info {\n  void*         base;               // actual base address of the block (used for offset aligned allocations)\n  size_t        size;               // full allocation size\n} mi_memid_os_info_t;\n\ntypedef struct mi_memid_arena_info {\n  size_t        block_index;        // index in the arena\n  mi_arena_id_t id;                 // arena id (>= 1)\n  bool          is_exclusive;       // this arena can only be used for specific arena allocations\n} mi_memid_arena_info_t;\n\ntypedef struct mi_memid_s {\n  union {\n    mi_memid_os_info_t    os;       // only used for MI_MEM_OS\n    mi_memid_arena_info_t arena;    // only used for MI_MEM_ARENA\n  } mem;\n  bool          is_pinned;          // `true` if we cannot decommit/reset/protect in this memory (e.g. when allocated using large (2Mib) or huge (1GiB) OS pages)\n  bool          initially_committed;// `true` if the memory was originally allocated as committed\n  bool          initially_zero;     // `true` if the memory was originally zero initialized\n  mi_memkind_t  memkind;\n} mi_memid_t;\n\n\n// -----------------------------------------------------------------------------------------\n// Segments are large allocated memory blocks (32mb on 64 bit) from arenas or the OS.\n//\n// Inside segments we allocated fixed size mimalloc pages (`mi_page_t`) that contain blocks.\n// The start of a segment is this structure with a fixed number of slice entries (`slices`)\n// usually followed by a guard OS page and the actual allocation area with pages.\n// While a page is not allocated, we view it's data as a `mi_slice_t` (instead of a `mi_page_t`).\n// Of any free area, the first slice has the info and `slice_offset == 0`; for any subsequent\n// slices part of the area, the `slice_offset` is the byte offset back to the first slice\n// (so we can quickly find the page info on a free, `internal.h:_mi_segment_page_of`).\n// For slices, the `block_size` field is repurposed to signify if a slice is used (`1`) or not (`0`).\n// Small and medium pages use a fixed amount of slices to reduce slice fragmentation, while\n// large and huge pages span a variable amount of slices.\n\ntypedef struct mi_subproc_s mi_subproc_t;\n\ntypedef struct mi_segment_s {\n  // constant fields\n  mi_memid_t        memid;              // memory id for arena/OS allocation\n  bool              allow_decommit;     // can we decommmit the memory\n  bool              allow_purge;        // can we purge the memory (reset or decommit)\n  size_t            segment_size;\n  mi_subproc_t*     subproc;            // segment belongs to sub process\n\n  // segment fields\n  mi_msecs_t        purge_expire;       // purge slices in the `purge_mask` after this time\n  mi_commit_mask_t  purge_mask;         // slices that can be purged\n  mi_commit_mask_t  commit_mask;        // slices that are currently committed\n\n  // from here is zero initialized\n  struct mi_segment_s* next;            // the list of freed segments in the cache (must be first field, see `segment.c:mi_segment_init`)\n  bool              was_reclaimed;      // true if it was reclaimed (used to limit on-free reclamation)\n  bool              dont_free;          // can be temporarily true to ensure the segment is not freed\n  bool              free_is_zero;       // if free spans are zero\n\n  size_t            abandoned;          // abandoned pages (i.e. the original owning thread stopped) (`abandoned <= used`)\n  size_t            abandoned_visits;   // count how often this segment is visited during abandoned reclamation (to force reclaim if it takes too long)\n  size_t            used;               // count of pages in use\n  uintptr_t         cookie;             // verify addresses in debug mode: `mi_ptr_cookie(segment) == segment->cookie`\n\n  struct mi_segment_s* abandoned_os_next; // only used for abandoned segments outside arena's, and only if `mi_option_visit_abandoned` is enabled\n  struct mi_segment_s* abandoned_os_prev;\n\n  size_t            segment_slices;      // for huge segments this may be different from `MI_SLICES_PER_SEGMENT`\n  size_t            segment_info_slices; // initial count of slices that we are using for segment info and possible guard pages.\n\n  // layout like this to optimize access in `mi_free`\n  mi_segment_kind_t kind;\n  size_t            slice_entries;       // entries in the `slices` array, at most `MI_SLICES_PER_SEGMENT`\n  _Atomic(mi_threadid_t) thread_id;      // unique id of the thread owning this segment\n\n  mi_slice_t        slices[MI_SLICES_PER_SEGMENT+1];  // one extra final entry for huge blocks with large alignment\n} mi_segment_t;\n\n\n// ------------------------------------------------------\n// Heaps\n// Provide first-class heaps to allocate from.\n// A heap just owns a set of pages for allocation and\n// can only be allocate/reallocate from the thread that created it.\n// Freeing blocks can be done from any thread though.\n// Per thread, the segments are shared among its heaps.\n// Per thread, there is always a default heap that is\n// used for allocation; it is initialized to statically\n// point to an empty heap to avoid initialization checks\n// in the fast path.\n// ------------------------------------------------------\n\n// Thread local data\ntypedef struct mi_tld_s mi_tld_t;\n\n// Pages of a certain block size are held in a queue.\ntypedef struct mi_page_queue_s {\n  mi_page_t* first;\n  mi_page_t* last;\n  size_t     block_size;\n} mi_page_queue_t;\n\n#define MI_BIN_FULL  (MI_BIN_HUGE+1)\n\n// Random context\ntypedef struct mi_random_cxt_s {\n  uint32_t input[16];\n  uint32_t output[16];\n  int      output_available;\n  bool     weak;\n} mi_random_ctx_t;\n\n\n// In debug mode there is a padding structure at the end of the blocks to check for buffer overflows\n#if (MI_PADDING)\ntypedef struct mi_padding_s {\n  uint32_t canary; // encoded block value to check validity of the padding (in case of overflow)\n  uint32_t delta;  // padding bytes before the block. (mi_usable_size(p) - delta == exact allocated bytes)\n} mi_padding_t;\n#define MI_PADDING_SIZE   (sizeof(mi_padding_t))\n#define MI_PADDING_WSIZE  ((MI_PADDING_SIZE + MI_INTPTR_SIZE - 1) / MI_INTPTR_SIZE)\n#else\n#define MI_PADDING_SIZE   0\n#define MI_PADDING_WSIZE  0\n#endif\n\n#define MI_PAGES_DIRECT   (MI_SMALL_WSIZE_MAX + MI_PADDING_WSIZE + 1)\n\n\n// A heap owns a set of pages.\nstruct mi_heap_s {\n  mi_tld_t*             tld;\n  _Atomic(mi_block_t*)  thread_delayed_free;\n  mi_threadid_t         thread_id;                           // thread this heap belongs too\n  mi_arena_id_t         arena_id;                            // arena id if the heap belongs to a specific arena (or 0)\n  uintptr_t             cookie;                              // random cookie to verify pointers (see `_mi_ptr_cookie`)\n  uintptr_t             keys[2];                             // two random keys used to encode the `thread_delayed_free` list\n  mi_random_ctx_t       random;                              // random number context used for secure allocation\n  size_t                page_count;                          // total number of pages in the `pages` queues.\n  size_t                page_retired_min;                    // smallest retired index (retired pages are fully free, but still in the page queues)\n  size_t                page_retired_max;                    // largest retired index into the `pages` array.\n  size_t                pages_full_size;                     // optimization: total size of blocks in the pages of the full queue (issue #1220)\n  long                  generic_count;                       // how often is `_mi_malloc_generic` called?\n  long                  generic_collect_count;               // how often is `_mi_malloc_generic` called without collecting?\n  mi_heap_t*            next;                                // list of heaps per thread\n  bool                  no_reclaim;                          // `true` if this heap should not reclaim abandoned pages\n  uint8_t               tag;                                 // custom tag, can be used for separating heaps based on the object types\n  #if MI_GUARDED\n  size_t                guarded_size_min;                    // minimal size for guarded objects\n  size_t                guarded_size_max;                    // maximal size for guarded objects\n  size_t                guarded_sample_rate;                 // sample rate (set to 0 to disable guarded pages)\n  size_t                guarded_sample_count;                // current sample count (counting down to 0)\n  #endif\n  mi_page_t*            pages_free_direct[MI_PAGES_DIRECT];  // optimize: array where every entry points a page with possibly free blocks in the corresponding queue for that size.\n  mi_page_queue_t       pages[MI_BIN_FULL + 1];              // queue of pages for each size class (or \"bin\")\n};\n\n\n// ------------------------------------------------------\n// Sub processes do not reclaim or visit segments\n// from other sub processes. These are essentially the\n// static variables of a process.\n// ------------------------------------------------------\n\nstruct mi_subproc_s {\n  _Atomic(size_t)    abandoned_count;         // count of abandoned segments for this sub-process\n  _Atomic(size_t)    abandoned_os_list_count; // count of abandoned segments in the os-list\n  mi_lock_t          abandoned_os_lock;       // lock for the abandoned os segment list (outside of arena's) (this lock protect list operations)\n  mi_lock_t          abandoned_os_visit_lock; // ensure only one thread per subproc visits the abandoned os list\n  mi_segment_t*      abandoned_os_list;       // doubly-linked list of abandoned segments outside of arena's (in OS allocated memory)\n  mi_segment_t*      abandoned_os_list_tail;  // the tail-end of the list\n  mi_memid_t         memid;                   // provenance of this memory block\n};\n\n\n// ------------------------------------------------------\n// Thread Local data\n// ------------------------------------------------------\n\n// A \"span\" is is an available range of slices. The span queues keep\n// track of slice spans of at most the given `slice_count` (but more than the previous size class).\ntypedef struct mi_span_queue_s {\n  mi_slice_t* first;\n  mi_slice_t* last;\n  size_t      slice_count;\n} mi_span_queue_t;\n\n#define MI_SEGMENT_BIN_MAX (35)     // 35 == mi_segment_bin(MI_SLICES_PER_SEGMENT)\n\n// Segments thread local data\ntypedef struct mi_segments_tld_s {\n  mi_span_queue_t     spans[MI_SEGMENT_BIN_MAX+1];  // free slice spans inside segments\n  size_t              count;        // current number of segments;\n  size_t              peak_count;   // peak number of segments\n  size_t              current_size; // current size of all segments\n  size_t              peak_size;    // peak size of all segments\n  size_t              reclaim_count;// number of reclaimed (abandoned) segments\n  mi_subproc_t*       subproc;      // sub-process this thread belongs to.\n  mi_stats_t*         stats;        // points to tld stats\n} mi_segments_tld_t;\n\n// Thread local data\nstruct mi_tld_s {\n  unsigned long long  heartbeat;     // monotonic heartbeat count\n  bool                recurse;       // true if deferred was called; used to prevent infinite recursion.\n  mi_heap_t*          heap_backing;  // backing heap of this thread (cannot be deleted)\n  mi_heap_t*          heaps;         // list of heaps in this thread (so we can abandon all when the thread terminates)\n  mi_segments_tld_t   segments;      // segment tld\n  mi_stats_t          stats;         // statistics\n};\n\n\n// ------------------------------------------------------\n// Debug\n// ------------------------------------------------------\n\n#if !defined(MI_DEBUG_UNINIT)\n#define MI_DEBUG_UNINIT     (0xD0)\n#endif\n#if !defined(MI_DEBUG_FREED)\n#define MI_DEBUG_FREED      (0xDF)\n#endif\n#if !defined(MI_DEBUG_PADDING)\n#define MI_DEBUG_PADDING    (0xDE)\n#endif\n\n\n// ------------------------------------------------------\n// Statistics\n// ------------------------------------------------------\n#ifndef MI_STAT\n#if (MI_DEBUG>0)\n#define MI_STAT 2\n#else\n#define MI_STAT 0\n#endif\n#endif\n\n// add to stat keeping track of the peak\nvoid _mi_stat_increase(mi_stat_count_t* stat, size_t amount);\nvoid _mi_stat_decrease(mi_stat_count_t* stat, size_t amount);\nvoid _mi_stat_adjust_decrease(mi_stat_count_t* stat, size_t amount);\n// counters can just be increased\nvoid _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount);\n\n#if (MI_STAT)\n#define mi_stat_increase(stat,amount)         _mi_stat_increase( &(stat), amount)\n#define mi_stat_decrease(stat,amount)         _mi_stat_decrease( &(stat), amount)\n#define mi_stat_adjust_decrease(stat,amount)  _mi_stat_adjust_decrease( &(stat), amount)\n#define mi_stat_counter_increase(stat,amount) _mi_stat_counter_increase( &(stat), amount)\n#else\n#define mi_stat_increase(stat,amount)         ((void)0)\n#define mi_stat_decrease(stat,amount)         ((void)0)\n#define mi_stat_adjust_decrease(stat,amount)  ((void)0)\n#define mi_stat_counter_increase(stat,amount) ((void)0)\n#endif\n\n#define mi_heap_stat_counter_increase(heap,stat,amount)  mi_stat_counter_increase( (heap)->tld->stats.stat, amount)\n#define mi_heap_stat_increase(heap,stat,amount)  mi_stat_increase( (heap)->tld->stats.stat, amount)\n#define mi_heap_stat_decrease(heap,stat,amount)  mi_stat_decrease( (heap)->tld->stats.stat, amount)\n#define mi_heap_stat_adjust_decrease(heap,stat,amount)  mi_stat_adjust_decrease( (heap)->tld->stats.stat, amount)\n\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/alloc-aligned.c",
      "sha256": "09c37411ef1719d263343d215527bfaed257b2a003250897aef1cabb239cb9cb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2021, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"  // mi_prim_get_default_heap\n\n#include <string.h>     // memset\n\n// ------------------------------------------------------\n// Aligned Allocation\n// ------------------------------------------------------\n\nstatic bool mi_malloc_is_naturally_aligned( size_t size, size_t alignment ) {\n  // objects up to `MI_MAX_ALIGN_GUARANTEE` are allocated aligned to their size (see `segment.c:_mi_segment_page_start`).\n  mi_assert_internal(_mi_is_power_of_two(alignment) && (alignment > 0));\n  if (alignment > size) return false;\n  if (alignment <= MI_MAX_ALIGN_SIZE) return true;\n  const size_t bsize = mi_good_size(size);\n  return (bsize <= MI_MAX_ALIGN_GUARANTEE && (bsize & (alignment-1)) == 0);\n}\n\n#if MI_GUARDED\nstatic mi_decl_noinline mi_decl_restrict void* mi_heap_malloc_guarded_aligned(mi_heap_t* heap, size_t size, size_t alignment, bool zero) mi_attr_noexcept {\n  // use over allocation for guarded blocksl\n  mi_assert_internal(alignment > 0 && alignment < MI_BLOCK_ALIGNMENT_MAX);\n  if mi_unlikely(alignment >= MI_BLOCK_ALIGNMENT_MAX || size > (MI_MAX_ALLOC_SIZE - MI_PADDING_SIZE - alignment)) {\n    _mi_error_message(EOVERFLOW, \"(guarded) aligned allocation request is too large (size %zu, alignment %zu)\\n\", size, alignment);\n    return NULL;\n  }\n  const size_t oversize = size + alignment - 1;\n  void* const base = _mi_heap_malloc_guarded(heap, oversize, zero);\n  if (base==NULL) return NULL;\n  void* const p = _mi_align_up_ptr(base, alignment);\n  mi_track_align(base, p, (uint8_t*)p - (uint8_t*)base, size);\n  mi_assert_internal(mi_usable_size(p) >= size);\n  mi_assert_internal(_mi_is_aligned(p, alignment));\n  return p;\n}\n\nstatic void* mi_heap_malloc_zero_no_guarded(mi_heap_t* heap, size_t size, bool zero, size_t* usable) {\n  const size_t rate = heap->guarded_sample_rate;\n  // only write if `rate!=0` so we don't write to the constant `_mi_heap_empty`\n  if (rate != 0) { heap->guarded_sample_rate = 0; }\n  void* p = _mi_heap_malloc_zero_ex(heap, size, zero, 0, usable);\n  if (rate != 0) { heap->guarded_sample_rate = rate; }\n  return p;\n}\n#else\nstatic void* mi_heap_malloc_zero_no_guarded(mi_heap_t* heap, size_t size, bool zero, size_t* usable) {\n  return _mi_heap_malloc_zero_ex(heap, size, zero, 0, usable);\n}\n#endif\n\n// Fallback aligned allocation that over-allocates -- split out for better codegen\nstatic mi_decl_noinline void* mi_heap_malloc_zero_aligned_at_overalloc(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero, size_t* usable) mi_attr_noexcept\n{\n  mi_assert_internal(size <= (MI_MAX_ALLOC_SIZE - MI_PADDING_SIZE));\n  mi_assert_internal(alignment != 0 && _mi_is_power_of_two(alignment));\n\n  void* p;\n  size_t oversize;\n  if mi_unlikely(alignment > MI_BLOCK_ALIGNMENT_MAX) {\n    // use OS allocation for very large alignment and allocate inside a huge page (dedicated segment with 1 page)\n    // This can support alignments >= MI_SEGMENT_SIZE by ensuring the object can be aligned at a point in the\n    // first (and single) page such that the segment info is `MI_SEGMENT_SIZE` bytes before it (so it can be found by aligning the pointer down)\n    if mi_unlikely(offset != 0) {\n      // todo: cannot support offset alignment for very large alignments yet\n      _mi_error_message(EOVERFLOW, \"aligned allocation with a very large alignment cannot be used with an alignment offset (size %zu, alignment %zu, offset %zu)\\n\", size, alignment, offset);\n      return NULL;\n    }\n    oversize = (size <= MI_SMALL_SIZE_MAX ? MI_SMALL_SIZE_MAX + 1 /* ensure we use generic malloc path */ : size);\n    // note: no guarded as alignment > 0\n    p = _mi_heap_malloc_zero_ex(heap, oversize, false, alignment, usable); // the page block size should be large enough to align in the single huge page block\n    // zero afterwards as only the area from the aligned_p may be committed!\n    if (p == NULL) return NULL;\n  }\n  else {\n    // otherwise over-allocate\n    mi_assert_internal(size <= (MI_MAX_ALLOC_SIZE - MI_PADDING_SIZE) && alignment <= MI_BLOCK_ALIGNMENT_MAX);\n    mi_assert_internal(size < SIZE_MAX - alignment); // `oversize` cannot overflow\n    oversize = (size < MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : size) + alignment - 1;  // adjust for size <= 16; with size 0 and alignment 64k, we would allocate a 64k block and pointing just beyond that.\n    p = mi_heap_malloc_zero_no_guarded(heap, oversize, zero, usable);\n    if (p == NULL) return NULL;\n  }\n  mi_page_t* page = _mi_ptr_page(p);\n\n  // .. and align within the allocation\n  const uintptr_t align_mask = alignment - 1;  // for any x, `(x & align_mask) == (x % alignment)`\n  const uintptr_t poffset = ((uintptr_t)p + offset) & align_mask;\n  const uintptr_t adjust  = (poffset == 0 ? 0 : alignment - poffset);\n  mi_assert_internal(adjust < alignment);\n  void* aligned_p = (void*)((uintptr_t)p + adjust);\n  if (aligned_p != p) {\n    mi_page_set_has_aligned(page, true);\n    #if MI_GUARDED\n    // set tag to aligned so mi_usable_size works with guard pages\n    if (adjust >= sizeof(mi_block_t)) {\n      mi_block_t* const block = (mi_block_t*)p;\n      block->next = MI_BLOCK_TAG_ALIGNED;\n    }\n    #endif\n    _mi_padding_shrink(page, (mi_block_t*)p, adjust + size);\n  }\n  // todo: expand padding if overallocated ?\n\n  mi_assert_internal(mi_page_usable_block_size(page) >= adjust + size);\n  mi_assert_internal(((uintptr_t)aligned_p + offset) % alignment == 0);\n  mi_assert_internal(mi_usable_size(aligned_p)>=size);\n  mi_assert_internal(mi_usable_size(p) == mi_usable_size(aligned_p)+adjust);\n  #if MI_DEBUG > 1\n  mi_page_t* const apage = _mi_ptr_page(aligned_p);\n  void* unalign_p = _mi_page_ptr_unalign(apage, aligned_p);\n  mi_assert_internal(p == unalign_p);\n  #endif\n\n  // now zero the block if needed\n  if (alignment > MI_BLOCK_ALIGNMENT_MAX) {\n    // for the tracker, on huge aligned allocations only the memory from the start of the large block is defined\n    mi_track_mem_undefined(aligned_p, size);\n    if (zero) {\n      _mi_memzero_aligned(aligned_p, mi_usable_size(aligned_p));\n    }\n  }\n\n  if (p != aligned_p) {\n    mi_track_align(p,aligned_p,adjust,mi_usable_size(aligned_p));\n    #if MI_GUARDED\n    mi_track_mem_defined(p, sizeof(mi_block_t));\n    #endif\n  }\n  return aligned_p;\n}\n\n// Generic primitive aligned allocation -- split out for better codegen\nstatic mi_decl_noinline void* mi_heap_malloc_zero_aligned_at_generic(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero, size_t* usable) mi_attr_noexcept\n{\n  mi_assert_internal(alignment != 0 && _mi_is_power_of_two(alignment));\n  // we don't allocate more than MI_MAX_ALLOC_SIZE (see <https://sourceware.org/ml/libc-announce/2019/msg00001.html>)\n  if mi_unlikely(size > (MI_MAX_ALLOC_SIZE - MI_PADDING_SIZE)) {\n    _mi_error_message(EOVERFLOW, \"aligned allocation request is too large (size %zu, alignment %zu)\\n\", size, alignment);\n    return NULL;\n  }\n\n  // use regular allocation if it is guaranteed to fit the alignment constraints.\n  // this is important to try as the fast path in `mi_heap_malloc_zero_aligned` only works when there exist\n  // a page with the right block size, and if we always use the over-alloc fallback that would never happen.\n  if (offset == 0 && mi_malloc_is_naturally_aligned(size,alignment)) {\n    void* p = mi_heap_malloc_zero_no_guarded(heap, size, zero, usable);\n    mi_assert_internal(p == NULL || ((uintptr_t)p % alignment) == 0);\n    const bool is_aligned_or_null = (((uintptr_t)p) & (alignment-1))==0;\n    if mi_likely(is_aligned_or_null) {\n      return p;\n    }\n    else {\n      // this should never happen if the `mi_malloc_is_naturally_aligned` check is correct..\n      mi_assert(false);\n      mi_free(p);\n    }\n  }\n\n  // fall back to over-allocation\n  return mi_heap_malloc_zero_aligned_at_overalloc(heap,size,alignment,offset,zero,usable);\n}\n\n\n// Primitive aligned allocation\nstatic void* mi_heap_malloc_zero_aligned_at(mi_heap_t* const heap, const size_t size, \n                                            const size_t alignment, const size_t offset, const bool zero,\n                                            size_t* usable) mi_attr_noexcept\n{\n  // note: we don't require `size > offset`, we just guarantee that the address at offset is aligned regardless of the allocated size.\n  if mi_unlikely(alignment == 0 || !_mi_is_power_of_two(alignment)) { // require power-of-two (see <https://en.cppreference.com/w/c/memory/aligned_alloc>)\n    #if MI_DEBUG > 0\n    _mi_error_message(EOVERFLOW, \"aligned allocation requires the alignment to be a power-of-two (size %zu, alignment %zu)\\n\", size, alignment);\n    #endif\n    return NULL;\n  }\n\n  #if MI_GUARDED\n  if (offset==0 && alignment < MI_BLOCK_ALIGNMENT_MAX && mi_heap_malloc_use_guarded(heap,size)) {\n    return mi_heap_malloc_guarded_aligned(heap, size, alignment, zero);\n  }\n  #endif\n\n  // try first if there happens to be a small block available with just the right alignment\n  if mi_likely(size <= MI_SMALL_SIZE_MAX && alignment <= size) {\n    const uintptr_t align_mask = alignment-1;       // for any x, `(x & align_mask) == (x % alignment)`\n    const size_t padsize = size + MI_PADDING_SIZE;\n    mi_page_t* page = _mi_heap_get_free_small_page(heap, padsize);\n    if mi_likely(page->free != NULL) {\n      const bool is_aligned = (((uintptr_t)page->free + offset) & align_mask)==0;\n      if mi_likely(is_aligned)\n      {\n        if (usable!=NULL) { *usable = mi_page_usable_block_size(page); }\n        void* p = (zero ? _mi_page_malloc_zeroed(heap,page,padsize) : _mi_page_malloc(heap,page,padsize)); // call specific page malloc for better codegen\n        mi_assert_internal(p != NULL);\n        mi_assert_internal(((uintptr_t)p + offset) % alignment == 0);\n        mi_track_malloc(p,size,zero);\n        return p;\n      }\n    }\n  }\n\n  // fallback to generic aligned allocation\n  return mi_heap_malloc_zero_aligned_at_generic(heap, size, alignment, offset, zero, usable);\n}\n\n\n// ------------------------------------------------------\n// Optimized mi_heap_malloc_aligned / mi_malloc_aligned\n// ------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, false, NULL);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_heap_malloc_aligned_at(heap, size, alignment, 0);\n}\n\n// ensure a definition is emitted\n#if defined(__cplusplus)\nvoid* _mi_extern_heap_malloc_aligned = (void*)&mi_heap_malloc_aligned;\n#endif\n\n// ------------------------------------------------------\n// Aligned Allocation\n// ------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, true, NULL);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_heap_zalloc_aligned_at(heap, size, alignment, 0);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count, size, &total)) return NULL;\n  return mi_heap_zalloc_aligned_at(heap, total, alignment, offset);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_heap_calloc_aligned_at(heap,count,size,alignment,0);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_heap_malloc_aligned_at(mi_prim_get_default_heap(), size, alignment, offset);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_heap_malloc_aligned(mi_prim_get_default_heap(), size, alignment);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_umalloc_aligned(size_t size, size_t alignment, size_t* block_size) mi_attr_noexcept {\n  return mi_heap_malloc_zero_aligned_at(mi_prim_get_default_heap(), size, alignment, 0, false, block_size);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_heap_zalloc_aligned_at(mi_prim_get_default_heap(), size, alignment, offset);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_heap_zalloc_aligned(mi_prim_get_default_heap(), size, alignment);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_uzalloc_aligned(size_t size, size_t alignment, size_t* block_size) mi_attr_noexcept {\n  return mi_heap_malloc_zero_aligned_at(mi_prim_get_default_heap(), size, alignment, 0, true, block_size);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_heap_calloc_aligned_at(mi_prim_get_default_heap(), count, size, alignment, offset);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_heap_calloc_aligned(mi_prim_get_default_heap(), count, size, alignment);\n}\n\n\n// ------------------------------------------------------\n// Aligned re-allocation\n// ------------------------------------------------------\n\nstatic void* mi_heap_realloc_zero_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset, bool zero) mi_attr_noexcept {\n  mi_assert(alignment > 0);\n  if (alignment <= sizeof(uintptr_t) && offset==0) return _mi_heap_realloc_zero(heap,p,newsize,zero,NULL,NULL);\n  if (p == NULL) return mi_heap_malloc_zero_aligned_at(heap,newsize,alignment,offset,zero,NULL);\n  size_t size = mi_usable_size(p);\n  if (newsize <= size && newsize >= (size - (size / 2))\n      && (((uintptr_t)p + offset) % alignment) == 0) {\n    return p;  // reallocation still fits, is aligned and not more than 25% waste\n  }\n  else {\n    // note: we don't zero allocate upfront so we only zero initialize the expanded part\n    void* newp = mi_heap_malloc_aligned_at(heap,newsize,alignment,offset);\n    if (newp != NULL) {\n      if (zero && newsize > size) {\n        // also set last word in the previous allocation to zero to ensure any padding is zero-initialized\n        size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0);\n        _mi_memzero((uint8_t*)newp + start, newsize - start);\n      }\n      _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize));\n      mi_free(p); // only free if successful\n    }\n    return newp;\n  }\n}\n\nstatic void* mi_heap_realloc_zero_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, bool zero) mi_attr_noexcept {\n  mi_assert(alignment > 0);\n  if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero,NULL,NULL);\n  return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,0,zero);\n}\n\nmi_decl_nodiscard void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,false);\n}\n\nmi_decl_nodiscard void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept {\n  return mi_heap_realloc_zero_aligned(heap,p,newsize,alignment,false);\n}\n\nmi_decl_nodiscard void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_heap_realloc_zero_aligned_at(heap, p, newsize, alignment, offset, true);\n}\n\nmi_decl_nodiscard void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept {\n  return mi_heap_realloc_zero_aligned(heap, p, newsize, alignment, true);\n}\n\nmi_decl_nodiscard void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(newcount, size, &total)) return NULL;\n  return mi_heap_rezalloc_aligned_at(heap, p, total, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(newcount, size, &total)) return NULL;\n  return mi_heap_rezalloc_aligned(heap, p, total, alignment);\n}\n\nmi_decl_nodiscard void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_heap_realloc_aligned_at(mi_prim_get_default_heap(), p, newsize, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept {\n  return mi_heap_realloc_aligned(mi_prim_get_default_heap(), p, newsize, alignment);\n}\n\nmi_decl_nodiscard void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_heap_rezalloc_aligned_at(mi_prim_get_default_heap(), p, newsize, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept {\n  return mi_heap_rezalloc_aligned(mi_prim_get_default_heap(), p, newsize, alignment);\n}\n\nmi_decl_nodiscard void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_heap_recalloc_aligned_at(mi_prim_get_default_heap(), p, newcount, size, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_heap_recalloc_aligned(mi_prim_get_default_heap(), p, newcount, size, alignment);\n}\n\n\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/alloc-override.c",
      "sha256": "90421ca6a329e6cc2513012508074a24607e92e58f2b41e527a78bfba1f07bed",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2026, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#if !defined(MI_IN_ALLOC_C)\n#error \"this file should be included from 'alloc.c' (so aliases can work)\"\n#endif\n\n\n#if defined(MI_MALLOC_OVERRIDE) && !defined(_DLL)\n\n#if defined(__APPLE__)\n#include <AvailabilityMacros.h>\nmi_decl_externc void   vfree(void* p);\nmi_decl_externc size_t malloc_size(const void* p);\nmi_decl_externc size_t malloc_good_size(size_t size);\n#endif\n\n// helper definition for C override of C++ new\ntypedef void* mi_nothrow_t;\n\n// ------------------------------------------------------\n// Override system malloc\n// ------------------------------------------------------\n\n#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__) && !MI_TRACK_ENABLED\n  // gcc, clang: use aliasing to alias the exported function to one of our `mi_` functions\n  #if (defined(__GNUC__) && __GNUC__ >= 9)\n    #pragma GCC diagnostic ignored \"-Wattributes\"  // or we get warnings that nodiscard is ignored on a forward\n    #define MI_FORWARD(fun)      __attribute__((alias(#fun), used, visibility(\"default\"), copy(fun)));\n  #else\n    #define MI_FORWARD(fun)      __attribute__((alias(#fun), used, visibility(\"default\")));\n  #endif\n  #define MI_FORWARD1(fun,x)      MI_FORWARD(fun)\n  #define MI_FORWARD2(fun,x,y)    MI_FORWARD(fun)\n  #define MI_FORWARD3(fun,x,y,z)  MI_FORWARD(fun)\n  #define MI_FORWARD0(fun,x)      MI_FORWARD(fun)\n  #define MI_FORWARD02(fun,x,y)   MI_FORWARD(fun)\n#else\n  // otherwise use forwarding by calling our `mi_` function\n  #define MI_FORWARD1(fun,x)      { return fun(x); }\n  #define MI_FORWARD2(fun,x,y)    { return fun(x,y); }\n  #define MI_FORWARD3(fun,x,y,z)  { return fun(x,y,z); }\n  #define MI_FORWARD0(fun,x)      { fun(x); }\n  #define MI_FORWARD02(fun,x,y)   { fun(x,y); }\n#endif\n\n\n#if defined(__APPLE__) && defined(MI_SHARED_LIB_EXPORT) && defined(MI_OSX_INTERPOSE)\n  // define MI_OSX_IS_INTERPOSED as we should not provide forwarding definitions for\n  // functions that are interposed (or the interposing does not work)\n  #define MI_OSX_IS_INTERPOSED\n\n  mi_decl_externc size_t mi_malloc_size_checked(void *p) {\n    if (!mi_is_in_heap_region(p)) return 0;\n    return mi_usable_size(p);\n  }\n\n  // use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1`\n  // See: <https://books.google.com/books?id=K8vUkpOXhN4C&pg=PA73>\n  struct mi_interpose_s {\n    const void* replacement;\n    const void* target;\n  };\n  #define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun }\n  #define MI_INTERPOSE_MI(fun)            MI_INTERPOSE_FUN(fun,mi_##fun)\n\n  #define MI_INTERPOSE_DECLS(name)        __attribute__((used)) static struct mi_interpose_s name[]  __attribute__((section(\"__DATA, __interpose\")))\n\n  MI_INTERPOSE_DECLS(_mi_interposes) =\n  {\n    MI_INTERPOSE_MI(malloc),\n    MI_INTERPOSE_MI(calloc),\n    MI_INTERPOSE_MI(realloc),\n    MI_INTERPOSE_MI(strdup),\n    MI_INTERPOSE_MI(realpath),\n    MI_INTERPOSE_MI(posix_memalign),\n    MI_INTERPOSE_MI(reallocf),\n    MI_INTERPOSE_MI(valloc),\n    MI_INTERPOSE_FUN(malloc_size,mi_malloc_size_checked),\n    MI_INTERPOSE_MI(malloc_good_size),\n    #ifdef MI_OSX_ZONE\n    // we interpose malloc_default_zone in alloc-override-osx.c so we can use mi_free safely\n    MI_INTERPOSE_MI(free),\n    MI_INTERPOSE_FUN(vfree,mi_free),\n    #else\n    // sometimes code allocates from default zone but deallocates using plain free :-( (like NxHashResizeToCapacity <https://github.com/nneonneo/osx-10.9-opensource/blob/master/objc4-551.1/runtime/hashtable2.mm>)\n    MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us\n    MI_INTERPOSE_FUN(vfree,mi_cfree),\n    #endif\n  };\n  #if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)\n  MI_INTERPOSE_DECLS(_mi_interposes_10_7)  = { MI_INTERPOSE_MI(strndup) };\n  #endif\n  #if defined(MAC_OS_X_VERSION_10_15) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15)\n  MI_INTERPOSE_DECLS(_mi_interposes_10_15) = { MI_INTERPOSE_MI(aligned_alloc) };\n  #endif\n\n  #ifdef __cplusplus\n  extern \"C\" {\n  #endif\n  void  _ZdlPv(void* p);   // delete\n  void  _ZdaPv(void* p);   // delete[]\n  void  _ZdlPvm(void* p, size_t n);  // delete\n  void  _ZdaPvm(void* p, size_t n);  // delete[]\n  void* _Znwm(size_t n);  // new\n  void* _Znam(size_t n);  // new[]\n  void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new nothrow\n  void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new[] nothrow\n  #ifdef __cplusplus\n  }\n  #endif\n  __attribute__((used)) static struct mi_interpose_s _mi_cxx_interposes[]  __attribute__((section(\"__DATA, __interpose\"))) =\n  {\n    MI_INTERPOSE_FUN(_ZdlPv,mi_free),\n    MI_INTERPOSE_FUN(_ZdaPv,mi_free),\n    MI_INTERPOSE_FUN(_ZdlPvm,mi_free_size),\n    MI_INTERPOSE_FUN(_ZdaPvm,mi_free_size),\n    MI_INTERPOSE_FUN(_Znwm,mi_new),\n    MI_INTERPOSE_FUN(_Znam,mi_new),\n    MI_INTERPOSE_FUN(_ZnwmRKSt9nothrow_t,mi_new_nothrow),\n    MI_INTERPOSE_FUN(_ZnamRKSt9nothrow_t,mi_new_nothrow),\n  };\n\n#elif defined(_MSC_VER)\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRT_HYBRIDPATCHABLE\n  void* __cdecl _expand(_Pre_notnull_ void* _Block, _In_ _CRT_GUARDOVERFLOW size_t _Size) {\n    return mi_expand(_Block, _Size);\n  }\n  _Check_return_ _ACRTIMP \n  size_t __cdecl _msize_base(_Pre_notnull_ void* _Block) _CRT_NOEXCEPT {\n    return mi_malloc_size(_Block);\n  }\n  _Check_return_ _ACRTIMP _CRT_HYBRIDPATCHABLE \n  size_t __cdecl _msize(_Pre_notnull_ void* _Block) {\n    return mi_malloc_size(_Block);\n  }\n  _ACRTIMP \n  void __cdecl _free_base(_Pre_maybenull_ _Post_invalid_ void* _Block) {\n    mi_free(_Block);\n  }\n  _ACRTIMP _CRT_HYBRIDPATCHABLE \n  void __cdecl free(_Pre_maybenull_ _Post_invalid_ void* _Block) {\n    mi_free(_Block);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRT_JIT_INTRINSIC _CRTRESTRICT _CRT_HYBRIDPATCHABLE\n  void* __cdecl malloc(_In_ _CRT_GUARDOVERFLOW size_t _Size) {\n    return mi_malloc(_Size);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _malloc_base(_In_ size_t _Size) {\n    return mi_malloc(_Size);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _realloc_base(_Pre_maybenull_ _Post_invalid_  void*  _Block, _In_ size_t _Size) {\n    return mi_realloc(_Block, _Size);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT _CRT_HYBRIDPATCHABLE\n  void* __cdecl realloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW  size_t _Size) {\n    return mi_realloc(_Block, _Size);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT \n  void* __cdecl _calloc_base(_In_ size_t _Count, _In_ size_t _Size) {\n    return mi_calloc(_Count, _Size);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRT_JIT_INTRINSIC _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl calloc(_In_ _CRT_GUARDOVERFLOW size_t _Count, _In_ _CRT_GUARDOVERFLOW size_t _Size) {\n    return mi_calloc(_Count, _Size);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _recalloc_base(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ size_t _Count, _In_ size_t _Size) {\n    return mi_recalloc(_Block, _Count, _Size);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _recalloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW size_t _Count, _In_ _CRT_GUARDOVERFLOW size_t _Size) {\n    return mi_recalloc(_Block, _Count, _Size);\n  }\n  _ACRTIMP \n  void __cdecl _aligned_free(_Pre_maybenull_ _Post_invalid_ void* _Block) {\n    mi_free(_Block);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_malloc(_In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment) {\n    return mi_malloc_aligned(_Size, _Alignment);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_offset_malloc(_In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment, _In_ size_t _Offset) {\n    return mi_malloc_aligned_at(_Size, _Alignment, _Offset);\n  }\n  _Check_return_ _ACRTIMP \n  size_t __cdecl _aligned_msize(_Pre_notnull_ void*  _Block, _In_ size_t _Alignment, _In_ size_t _Offset) {\n    MI_UNUSED(_Alignment); MI_UNUSED(_Offset); return mi_malloc_size(_Block);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_offset_realloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment, _In_ size_t _Offset) {\n    return mi_realloc_aligned_at(_Block, _Size, _Alignment, _Offset);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_offset_recalloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW size_t _Count, _In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment, _In_ size_t _Offset) {\n    return mi_recalloc_aligned_at(_Block, _Count, _Size, _Alignment, _Offset);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_realloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment) {\n    return mi_realloc_aligned(_Block, _Size, _Alignment);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_recalloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW size_t _Count, _In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment) {\n    return mi_recalloc_aligned(_Block, _Count, _Size, _Alignment);\n  }\n#else\n  // On all other systems forward allocation primitives to our API\n  mi_decl_export void* malloc(size_t size)              MI_FORWARD1(mi_malloc, size)\n  mi_decl_export void* calloc(size_t size, size_t n)    MI_FORWARD2(mi_calloc, size, n)\n  mi_decl_export void* realloc(void* p, size_t newsize) MI_FORWARD2(mi_realloc, p, newsize)\n  mi_decl_export void  free(void* p)                    MI_FORWARD0(mi_free, p)\n  // In principle we do not need to forward `strdup`/`strndup` but on some systems these do not use `malloc` internally (but a more primitive call)\n  // We only override if `strdup` is not a macro (as on some older libc's, see issue #885)\n  #if !defined(strdup)\n  mi_decl_export char* strdup(const char* str)             MI_FORWARD1(mi_strdup, str)\n  #endif\n  #if !defined(strndup) && (!defined(__APPLE__) || (defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7))\n  mi_decl_export char* strndup(const char* str, size_t n)  MI_FORWARD2(mi_strndup, str, n)\n  #endif\n#endif\n\n#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__)\n#pragma GCC visibility push(default)\n#endif\n\n// ------------------------------------------------------\n// Override new/delete\n// This is not really necessary as they usually call\n// malloc/free anyway, but it improves performance.\n// ------------------------------------------------------\n#ifdef __cplusplus\n  // ------------------------------------------------------\n  // With a C++ compiler we override the new/delete operators.\n  // see <https://en.cppreference.com/w/cpp/memory/new/operator_new>\n  // ------------------------------------------------------\n  #include <new>\n\n  #ifndef MI_OSX_IS_INTERPOSED\n    void operator delete(void* p) noexcept              MI_FORWARD0(mi_free,p)\n    void operator delete[](void* p) noexcept            MI_FORWARD0(mi_free,p)\n\n    void* operator new(std::size_t n) noexcept(false)   MI_FORWARD1(mi_new,n)\n    void* operator new[](std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n)\n\n    void* operator new  (std::size_t n, const std::nothrow_t& tag) noexcept { MI_UNUSED(tag); return mi_new_nothrow(n); }\n    void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { MI_UNUSED(tag); return mi_new_nothrow(n); }\n\n    #if (__cplusplus >= 201402L || _MSC_VER >= 1916)\n    void operator delete  (void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n)\n    void operator delete[](void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n)\n    #endif\n  #endif\n\n  #if (__cplusplus > 201402L && defined(__cpp_aligned_new)) && (!defined(__GNUC__) || (__GNUC__ > 5))\n  void operator delete  (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete  (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };\n  void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };\n  void operator delete  (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n\n  void* operator new( std::size_t n, std::align_val_t al)   noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }\n  void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }\n  void* operator new  (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }\n  void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }\n  #endif\n\n#elif (defined(__GNUC__) || defined(__clang__))\n  // ------------------------------------------------------\n  // Override by defining the mangled C++ names of the operators (as\n  // used by GCC and CLang).\n  // See <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling>\n  // ------------------------------------------------------\n\n  void _ZdlPv(void* p)            MI_FORWARD0(mi_free,p) // delete\n  void _ZdaPv(void* p)            MI_FORWARD0(mi_free,p) // delete[]\n  void _ZdlPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n)\n  void _ZdaPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n)\n\n  void _ZdlPvSt11align_val_t(void* p, size_t al)            { mi_free_aligned(p,al); }\n  void _ZdaPvSt11align_val_t(void* p, size_t al)            { mi_free_aligned(p,al); }\n  void _ZdlPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); }\n  void _ZdaPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); }\n\n  void _ZdlPvRKSt9nothrow_t(void* p, mi_nothrow_t tag)      { MI_UNUSED(tag); mi_free(p); }  // operator delete(void*, std::nothrow_t const&)\n  void _ZdaPvRKSt9nothrow_t(void* p, mi_nothrow_t tag)      { MI_UNUSED(tag); mi_free(p); }  // operator delete[](void*, std::nothrow_t const&)\n  void _ZdlPvSt11align_val_tRKSt9nothrow_t(void* p, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); mi_free_aligned(p,al); } // operator delete(void*, std::align_val_t, std::nothrow_t const&)\n  void _ZdaPvSt11align_val_tRKSt9nothrow_t(void* p, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); mi_free_aligned(p,al); } // operator delete[](void*, std::align_val_t, std::nothrow_t const&)\n\n  #if (MI_INTPTR_SIZE==8) || (MI_INTPTR_SIZE==4 && defined(__EMSCRIPTEN__))  // pr #1257\n    void* _Znwm(size_t n)                             MI_FORWARD1(mi_new,n)  // new 64-bit\n    void* _Znam(size_t n)                             MI_FORWARD1(mi_new,n)  // new[] 64-bit\n    void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }\n    void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }\n    void* _ZnwmSt11align_val_t(size_t n, size_t al)   MI_FORWARD2(mi_new_aligned, n, al)\n    void* _ZnamSt11align_val_t(size_t n, size_t al)   MI_FORWARD2(mi_new_aligned, n, al)\n    void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }\n    void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }\n  #elif (MI_INTPTR_SIZE==4)\n    void* _Znwj(size_t n)                             MI_FORWARD1(mi_new,n)  // new 64-bit\n    void* _Znaj(size_t n)                             MI_FORWARD1(mi_new,n)  // new[] 64-bit\n    void* _ZnwjRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }\n    void* _ZnajRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }\n    void* _ZnwjSt11align_val_t(size_t n, size_t al)   MI_FORWARD2(mi_new_aligned, n, al)\n    void* _ZnajSt11align_val_t(size_t n, size_t al)   MI_FORWARD2(mi_new_aligned, n, al)\n    void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }\n    void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }\n  #else\n    #error \"define overloads for new/delete for this platform (just for performance, can be skipped)\"\n  #endif\n#endif // __cplusplus\n\n// ------------------------------------------------------\n// Further Posix & Unix functions definitions\n// ------------------------------------------------------\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef MI_OSX_IS_INTERPOSED\n  // Forward Posix/Unix calls as well\n  void*  reallocf(void* p, size_t newsize) MI_FORWARD2(mi_reallocf,p,newsize)\n  size_t malloc_size(const void* p)        MI_FORWARD1(mi_usable_size,p)\n  #if !defined(__ANDROID__) && !defined(__FreeBSD__) && !defined(__DragonFly__)\n  size_t malloc_usable_size(void *p)       MI_FORWARD1(mi_usable_size,p)\n  #else\n  size_t malloc_usable_size(const void *p) MI_FORWARD1(mi_usable_size,p)\n  #endif\n\n  // No forwarding here due to aliasing/name mangling issues\n  void*  valloc(size_t size)               { return mi_valloc(size); }\n  void   vfree(void* p)                    { mi_free(p); }\n  size_t malloc_good_size(size_t size)     { return mi_malloc_good_size(size); }\n  int    posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p, alignment, size); }\n\n  // `aligned_alloc` is only available when __USE_ISOC11 is defined.\n  // Note: it seems __USE_ISOC11 is not defined in musl (and perhaps other libc's) so we only check\n  // for it if using glibc.\n  // Note: Conda has a custom glibc where `aligned_alloc` is declared `static inline` and we cannot\n  // override it, but both _ISOC11_SOURCE and __USE_ISOC11 are undefined in Conda GCC7 or GCC9.\n  // Fortunately, in the case where `aligned_alloc` is declared as `static inline` it\n  // uses internally `memalign`, `posix_memalign`, or `_aligned_malloc` so we  can avoid overriding it ourselves.\n  #if !defined(__GLIBC__) || __USE_ISOC11\n  void* aligned_alloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); }\n  #endif\n#endif\n\n// no forwarding here due to aliasing/name mangling issues\nvoid  cfree(void* p)                                    { mi_free(p); }\nvoid* pvalloc(size_t size)                              { return mi_pvalloc(size); }\nvoid* memalign(size_t alignment, size_t size)           { return mi_memalign(alignment, size); }\n#if !defined(_WIN32)\nvoid* _aligned_malloc(size_t size, size_t alignment)    { return mi_malloc_aligned(size,alignment); }\n#endif\nvoid* reallocarray(void* p, size_t count, size_t size)  { return mi_reallocarray(p, count, size); }\n// some systems define reallocarr so mark it as a weak symbol (#751)\nmi_decl_weak int reallocarr(void* p, size_t count, size_t size)    { return mi_reallocarr(p, count, size); }\n\n#if defined(__wasi__)\n  // forward __libc interface (see PR #667)\n  void* __libc_malloc(size_t size)                      MI_FORWARD1(mi_malloc, size)\n  void* __libc_calloc(size_t count, size_t size)        MI_FORWARD2(mi_calloc, count, size)\n  void* __libc_realloc(void* p, size_t size)            MI_FORWARD2(mi_realloc, p, size)\n  void  __libc_free(void* p)                            MI_FORWARD0(mi_free, p)\n  void* __libc_memalign(size_t alignment, size_t size)  { return mi_memalign(alignment, size); }\n\n#elif defined(__linux__)\n  // forward __libc interface (needed for glibc-based and musl-based Linux distributions)\n  void* __libc_malloc(size_t size)                      MI_FORWARD1(mi_malloc,size)\n  void* __libc_calloc(size_t count, size_t size)        MI_FORWARD2(mi_calloc,count,size)\n  void* __libc_realloc(void* p, size_t size)            MI_FORWARD2(mi_realloc,p,size)\n  void  __libc_free(void* p)                            MI_FORWARD0(mi_free,p)\n  void  __libc_cfree(void* p)                           MI_FORWARD0(mi_free,p)\n\n  void* __libc_valloc(size_t size)                      { return mi_valloc(size); }\n  void* __libc_pvalloc(size_t size)                     { return mi_pvalloc(size); }\n  void* __libc_memalign(size_t alignment, size_t size)  { return mi_memalign(alignment,size); }\n  int   __posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p,alignment,size); }\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__)\n#pragma GCC visibility pop\n#endif\n\n#endif // MI_MALLOC_OVERRIDE\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/alloc-posix.c",
      "sha256": "98d0eb877d7b9cdf7e9f857aaf3c739b69f746b91221e0e427e82bdd7cec90b3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2021, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// ------------------------------------------------------------------------\n// mi prefixed publi definitions of various Posix, Unix, and C++ functions\n// for convenience and used when overriding these functions.\n// ------------------------------------------------------------------------\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n\n// ------------------------------------------------------\n// Posix & Unix functions definitions\n// ------------------------------------------------------\n\n#include <errno.h>\n#include <string.h>  // memset\n#include <stdlib.h>  // getenv\n\n#ifdef _MSC_VER\n#pragma warning(disable:4996)  // getenv _wgetenv\n#endif\n\n#ifndef EINVAL\n#define EINVAL 22\n#endif\n#ifndef ENOMEM\n#define ENOMEM 12\n#endif\n\n\nmi_decl_nodiscard size_t mi_malloc_size(const void* p) mi_attr_noexcept {\n  // if (!mi_is_in_heap_region(p)) return 0;\n  return mi_usable_size(p);\n}\n\nmi_decl_nodiscard size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept {\n  // if (!mi_is_in_heap_region(p)) return 0;\n  return mi_usable_size(p);\n}\n\nmi_decl_nodiscard size_t mi_malloc_good_size(size_t size) mi_attr_noexcept {\n  return mi_good_size(size);\n}\n\nvoid mi_cfree(void* p) mi_attr_noexcept {\n  if (mi_is_in_heap_region(p)) {\n    mi_free(p);\n  }\n}\n\nint mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept {\n  // Note: The spec dictates we should not modify `*p` on an error. (issue#27)\n  // <http://man7.org/linux/man-pages/man3/posix_memalign.3.html>\n  if (p == NULL) return EINVAL;\n  if ((alignment % sizeof(void*)) != 0) return EINVAL;                 // natural alignment\n  // it is also required that alignment is a power of 2 and > 0; this is checked in `mi_malloc_aligned`\n  if (alignment==0 || !_mi_is_power_of_two(alignment)) return EINVAL;  // not a power of 2\n  void* q = mi_malloc_aligned(size, alignment);\n  if (q==NULL && size != 0) return ENOMEM;\n  mi_assert_internal(_mi_is_aligned(q,alignment));\n  *p = q;\n  return 0;\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept {\n  void* p = mi_malloc_aligned(size, alignment);\n  mi_assert_internal(_mi_is_aligned(p,alignment));\n  return p;\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept {\n  return mi_memalign( _mi_os_page_size(), size );\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept {\n  size_t psize = _mi_os_page_size();\n  if (size >= SIZE_MAX - psize) return NULL; // overflow\n  size_t asize = _mi_align_up(size, psize);\n  return mi_malloc_aligned(asize, psize);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept {\n  // C11 requires the size to be an integral multiple of the alignment, see <https://en.cppreference.com/w/c/memory/aligned_alloc>.\n  // unfortunately, it turns out quite some programs pass a size that is not an integral multiple so skip this check..\n  /* if mi_unlikely((size & (alignment - 1)) != 0) { // C11 requires alignment>0 && integral multiple, see <https://en.cppreference.com/w/c/memory/aligned_alloc>\n      #if MI_DEBUG > 0\n      _mi_error_message(EOVERFLOW, \"(mi_)aligned_alloc requires the size to be an integral multiple of the alignment (size %zu, alignment %zu)\\n\", size, alignment);\n      #endif\n      return NULL;\n    }\n  */\n  // C11 also requires alignment to be a power-of-two (and > 0) which is checked in mi_malloc_aligned\n  void* p = mi_malloc_aligned(size, alignment);\n  mi_assert_internal(_mi_is_aligned(p,alignment));\n  return p;\n}\n\nmi_decl_nodiscard void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept {  // BSD <https://man.freebsd.org/cgi/man.cgi?query=reallocarray>\n  size_t total;\n  if mi_unlikely(mi_count_size_overflow(count, size, &total)) {\n    errno = EOVERFLOW;\n    return NULL;\n  }\n  void* newp = mi_realloc(p,total);\n  if (newp==NULL) { errno = ENOMEM; }\n  return newp;\n}\n\nmi_decl_nodiscard int mi_reallocarr( void* ptrp, size_t count, size_t size ) mi_attr_noexcept { // NetBSD <https://man.netbsd.org/reallocarr.3>\n  mi_assert(size != 0);\n  mi_assert(ptrp != NULL);\n  if (ptrp == NULL || size == 0) {\n    return (errno = EINVAL);\n  }\n  size_t total;\n  if mi_unlikely(mi_count_size_overflow(count, size, &total)) {\n    return (errno = EOVERFLOW);\n  }\n  void** op = (void**)ptrp;\n  if (total == 0) {\n    free(*op);\n    *op = NULL;\n    return 0;\n  }\n  else {\n    void* newp = mi_realloc(*op,total);\n    if (newp == NULL) { return (errno = ENOMEM); }\n    *op = newp;\n    return 0;\n  }\n}\n\nvoid* mi__expand(void* p, size_t newsize) mi_attr_noexcept {  // Microsoft\n  void* res = mi_expand(p, newsize);\n  if (res == NULL) { errno = ENOMEM; }\n  return res;\n}\n\nmi_decl_nodiscard mi_decl_restrict wchar_t* mi_wcsdup(const wchar_t* s) mi_attr_noexcept {\n  if (s==NULL) return NULL;\n  size_t wlen;\n  for(wlen = 0; s[wlen] != 0 && wlen < PTRDIFF_MAX; wlen++) { }  // prevent overflow on wlen+1\n  size_t size; \n  if (mi_mul_overflow(wlen+1, sizeof(wchar_t), &size) || size > PTRDIFF_MAX) return NULL;\n  wchar_t* p = (wchar_t*)mi_malloc(size);\n  if (p != NULL) {\n    _mi_memcpy(p,s,size);\n  }\n  return p;\n}\n\nmi_decl_nodiscard mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s)  mi_attr_noexcept {\n  return (unsigned char*)mi_strdup((const char*)s);\n}\n\nint mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept {\n  if (size != NULL) *size = 0;\n  if (buf==NULL || name==NULL) return EINVAL;\n  char* p = getenv(name);\n  if (p==NULL) {\n    *buf = NULL;\n  }\n  else {\n    *buf = mi_strdup(p);\n    if (*buf==NULL) return ENOMEM;\n    if (size != NULL) { *size = _mi_strlen(p) + 1; }    // cannot overflow as mi_strdup is limited to PTRDIFF_MAX\n  }\n  return 0;\n}\n\nint mi_wdupenv_s(wchar_t** buf, size_t* size, const wchar_t* name) mi_attr_noexcept {\n  if (size != NULL) *size = 0;\n  if (buf==NULL || name==NULL) return EINVAL;  \n#if !defined(_WIN32) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP))\n  // not supported\n  *buf = NULL;\n  return EINVAL;\n#else\n  wchar_t* p = (wchar_t*)_wgetenv(name);\n  if (p==NULL) {\n    *buf = NULL;\n  }\n  else {\n    *buf = mi_wcsdup(p);\n    if (*buf==NULL) return ENOMEM;\n    if (size != NULL) { *size = wcslen(p) + 1; }  // cannot overflow as wcsdup is limited to PTRDIFF_MAX\n  }\n  return 0;\n#endif\n}\n\nmi_decl_nodiscard void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { // Microsoft\n  return mi_recalloc_aligned_at(p, newcount, size, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { // Microsoft\n  return mi_recalloc_aligned(p, newcount, size, alignment);\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/alloc.c",
      "sha256": "78e9dd453356984e63dcd210baa1d4ff8b9b21c1fb5ab2165b593e9b1c4ff856",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#ifndef _DEFAULT_SOURCE\n#define _DEFAULT_SOURCE   // for realpath() on Linux\n#endif\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"   // _mi_prim_thread_id()\n\n#include <string.h>      // memset, strlen (for mi_strdup)\n#include <stdlib.h>      // malloc, abort\n\n#define MI_IN_ALLOC_C\n#include \"alloc-override.c\"\n#include \"free.c\"\n#undef MI_IN_ALLOC_C\n\n// ------------------------------------------------------\n// Allocation\n// ------------------------------------------------------\n\n// Fast allocation in a page: just pop from the free list.\n// Fall back to generic allocation only if the list is empty.\n// Note: in release mode the (inlined) routine is about 7 instructions with a single test.\nextern inline void* _mi_page_malloc_zero(mi_heap_t* heap, mi_page_t* page, size_t size, bool zero, size_t* usable) mi_attr_noexcept\n{\n  mi_assert_internal(size >= MI_PADDING_SIZE);\n  mi_assert_internal(page->block_size == 0 /* empty heap */ || mi_page_block_size(page) >= size);\n\n  // check the free list\n  mi_block_t* const block = page->free;\n  if mi_unlikely(block == NULL) {\n    return _mi_malloc_generic(heap, size, zero, 0, usable);\n  }\n  mi_assert_internal(block != NULL && _mi_ptr_page(block) == page);\n  if (usable != NULL) { *usable = mi_page_usable_block_size(page); };\n  // pop from the free list\n  page->free = mi_block_next(page, block);\n  page->used++;\n  mi_assert_internal(page->free == NULL || _mi_ptr_page(page->free) == page);\n  mi_assert_internal(page->block_size < MI_MAX_ALIGN_SIZE || _mi_is_aligned(block, MI_MAX_ALIGN_SIZE));\n\n  #if MI_DEBUG>3\n  if (page->free_is_zero && size > sizeof(*block)) {\n    mi_assert_expensive(mi_mem_is_zero(block+1,size - sizeof(*block)));\n  }\n  #endif\n\n  // allow use of the block internally\n  // note: when tracking we need to avoid ever touching the MI_PADDING since\n  // that is tracked by valgrind etc. as non-accessible (through the red-zone, see `mimalloc/track.h`)\n  mi_track_mem_undefined(block, mi_page_usable_block_size(page));\n\n  // zero the block? note: we need to zero the full block size (issue #63)\n  if mi_unlikely(zero) {\n    mi_assert_internal(page->block_size != 0); // do not call with zero'ing for huge blocks (see _mi_malloc_generic)\n    #if MI_PADDING\n    mi_assert_internal(page->block_size >= MI_PADDING_SIZE);\n    #endif\n    if (page->free_is_zero) {\n      block->next = 0;\n      mi_track_mem_defined(block, page->block_size - MI_PADDING_SIZE);\n    }\n    else {\n      _mi_memzero_aligned(block, page->block_size - MI_PADDING_SIZE);\n    }\n  }\n\n  #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN\n  if (!zero && !mi_page_is_huge(page)) {\n    memset(block, MI_DEBUG_UNINIT, mi_page_usable_block_size(page));\n  }\n  #elif (MI_SECURE!=0)\n  if (!zero) { block->next = 0; } // don't leak internal data\n  #endif\n\n  #if (MI_STAT>0)\n  const size_t bsize = mi_page_usable_block_size(page);\n  if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) {\n    mi_heap_stat_increase(heap, malloc_normal, bsize);\n    mi_heap_stat_counter_increase(heap, malloc_normal_count, 1);\n    #if (MI_STAT>1)\n    const size_t bin = _mi_bin(bsize);\n    mi_heap_stat_increase(heap, malloc_bins[bin], 1);\n    mi_heap_stat_increase(heap, malloc_requested, size - MI_PADDING_SIZE);\n    #endif\n  }\n  #endif\n\n  #if MI_PADDING // && !MI_TRACK_ENABLED\n    mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + mi_page_usable_block_size(page));\n    ptrdiff_t delta = ((uint8_t*)padding - (uint8_t*)block - (size - MI_PADDING_SIZE));\n    #if (MI_DEBUG>=2)\n    mi_assert_internal(delta >= 0 && mi_page_usable_block_size(page) >= (size - MI_PADDING_SIZE + delta));\n    #endif\n    mi_track_mem_defined(padding,sizeof(mi_padding_t));  // note: re-enable since mi_page_usable_block_size may set noaccess\n    padding->canary = mi_ptr_encode_canary(page,block,page->keys);\n    padding->delta  = (uint32_t)(delta);\n    #if MI_PADDING_CHECK\n    if (!mi_page_is_huge(page)) {\n      uint8_t* fill = (uint8_t*)padding - delta;\n      const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // set at most N initial padding bytes\n      for (size_t i = 0; i < maxpad; i++) { fill[i] = MI_DEBUG_PADDING; }\n    }\n    #endif\n  #endif\n\n  return block;\n}\n\n// extra entries for improved efficiency in `alloc-aligned.c`.\nextern void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept {\n  return _mi_page_malloc_zero(heap,page,size,false,NULL);\n}\nextern void* _mi_page_malloc_zeroed(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept {\n  return _mi_page_malloc_zero(heap,page,size,true,NULL);\n}\n\n#if MI_GUARDED\nmi_decl_restrict void* _mi_heap_malloc_guarded(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept;\n#endif\n\nstatic inline mi_decl_restrict void* mi_heap_malloc_small_zero(mi_heap_t* heap, size_t size, bool zero, size_t* usable) mi_attr_noexcept {\n  mi_assert(heap != NULL);\n  mi_assert(size <= MI_SMALL_SIZE_MAX);\n  #if MI_DEBUG\n  const uintptr_t tid = _mi_thread_id();\n  mi_assert(heap->thread_id == 0 || heap->thread_id == tid); // heaps are thread local\n  #endif\n  #if (MI_PADDING || MI_GUARDED)\n  if (size == 0) { size = sizeof(void*); }\n  #endif\n  #if MI_GUARDED\n  if (mi_heap_malloc_use_guarded(heap,size)) {\n    return _mi_heap_malloc_guarded(heap, size, zero);\n  }\n  #endif\n\n  // get page in constant time, and allocate from it\n  mi_page_t* page = _mi_heap_get_free_small_page(heap, size + MI_PADDING_SIZE);\n  void* const p = _mi_page_malloc_zero(heap, page, size + MI_PADDING_SIZE, zero, usable);\n  mi_track_malloc(p,size,zero);\n\n  #if MI_DEBUG>3\n  if (p != NULL && zero) {\n    mi_assert_expensive(mi_mem_is_zero(p, size));\n  }\n  #endif\n  return p;\n}\n\n// allocate a small block\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept {\n  return mi_heap_malloc_small_zero(heap, size, false, NULL);\n}\n\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_zalloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept {\n  return mi_heap_malloc_small_zero(heap, size, true, NULL);\n}\n\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept {\n  return mi_heap_malloc_small(mi_prim_get_default_heap(), size);\n}\n\n// The main allocation function\nextern inline void* _mi_heap_malloc_zero_ex(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment, size_t* usable) mi_attr_noexcept {\n  // fast path for small objects\n  if mi_likely(size <= MI_SMALL_SIZE_MAX) {\n    mi_assert_internal(huge_alignment == 0);\n    return mi_heap_malloc_small_zero(heap, size, zero, usable);\n  }\n  #if MI_GUARDED\n  else if (huge_alignment==0 && mi_heap_malloc_use_guarded(heap,size)) {\n    return _mi_heap_malloc_guarded(heap, size, zero);\n  }\n  #endif\n  else {\n    // regular allocation\n    mi_assert(heap!=NULL);\n    mi_assert(heap->thread_id == 0 || heap->thread_id == _mi_thread_id());   // heaps are thread local\n    void* const p = _mi_malloc_generic(heap, size + MI_PADDING_SIZE, zero, huge_alignment, usable);  // note: size can overflow but it is detected in malloc_generic\n    mi_track_malloc(p,size,zero);\n\n    #if MI_DEBUG>3\n    if (p != NULL && zero) {\n      mi_assert_expensive(mi_mem_is_zero(p, size));\n    }\n    #endif\n    return p;\n  }\n}\n\nextern inline void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept {\n  return _mi_heap_malloc_zero_ex(heap, size, zero, 0, NULL);\n}\n\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept {\n  return _mi_heap_malloc_zero(heap, size, false);\n}\n\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept {\n  return mi_heap_malloc(mi_prim_get_default_heap(), size);\n}\n\n// zero initialized small block\nmi_decl_nodiscard mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept {\n  return mi_heap_zalloc_small(mi_prim_get_default_heap(), size);\n}\n\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept {\n  return _mi_heap_malloc_zero(heap, size, true);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept {\n  return mi_heap_zalloc(mi_prim_get_default_heap(),size);\n}\n\n\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count,size,&total)) return NULL;\n  return mi_heap_zalloc(heap,total);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept {\n  return mi_heap_calloc(mi_prim_get_default_heap(),count,size);\n}\n\n// Return usable size\nmi_decl_nodiscard mi_decl_restrict void* mi_umalloc_small(size_t size, size_t* usable) mi_attr_noexcept {\n  return mi_heap_malloc_small_zero(mi_prim_get_default_heap(), size, false, usable);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_umalloc(mi_heap_t* heap, size_t size, size_t* usable) mi_attr_noexcept {\n  return _mi_heap_malloc_zero_ex(heap, size, false, 0, usable);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_umalloc(size_t size, size_t* usable) mi_attr_noexcept {\n  return mi_heap_umalloc(mi_prim_get_default_heap(), size, usable);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_uzalloc(size_t size, size_t* usable) mi_attr_noexcept {\n  return _mi_heap_malloc_zero_ex(mi_prim_get_default_heap(), size, true, 0, usable);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_ucalloc(size_t count, size_t size, size_t* usable) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count,size,&total)) return NULL;\n  return mi_uzalloc(total, usable);\n}\n\n// Uninitialized `calloc`\nmi_decl_nodiscard extern mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count, size, &total)) return NULL;\n  return mi_heap_malloc(heap, total);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept {\n  return mi_heap_mallocn(mi_prim_get_default_heap(),count,size);\n}\n\n// Expand (or shrink) in place (or fail)\nvoid* mi_expand(void* p, size_t newsize) mi_attr_noexcept {\n  #if MI_PADDING\n  // we do not shrink/expand with padding enabled\n  MI_UNUSED(p); MI_UNUSED(newsize);\n  return NULL;\n  #else\n  if (p == NULL) return NULL;\n  const mi_page_t* const page = mi_validate_ptr_page(p,\"mi_expand\");  \n  const size_t size = _mi_usable_size(p,page);\n  if (newsize > size) return NULL;\n  return p; // it fits\n  #endif\n}\n\nvoid* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero, size_t* usable_pre, size_t* usable_post) mi_attr_noexcept {\n  // if p == NULL then behave as malloc.\n  // else if size == 0 then reallocate to a zero-sized block (and don't return NULL, just as mi_malloc(0)).\n  // (this means that returning NULL always indicates an error, and `p` will not have been freed in that case.)\n  const mi_page_t* page;\n  size_t size;\n  if (p==NULL) {\n    page = NULL;\n    size = 0;\n    if (usable_pre!=NULL) { *usable_pre = 0; }\n  }\n  else {    \n    page = mi_validate_ptr_page(p,\"mi_realloc\");  \n    size = _mi_usable_size(p,page);\n    if (usable_pre!=NULL) { *usable_pre = mi_page_usable_block_size(page); }    \n  }\n  if mi_unlikely(newsize <= size && newsize >= (size / 2) && newsize > 0) {  // note: newsize must be > 0 or otherwise we return NULL for realloc(NULL,0)\n    mi_assert_internal(p!=NULL);\n    // todo: do not track as the usable size is still the same in the free; adjust potential padding?\n    // mi_track_resize(p,size,newsize)\n    // if (newsize < size) { mi_track_mem_noaccess((uint8_t*)p + newsize, size - newsize); }\n    if (usable_post!=NULL) { *usable_post = mi_page_usable_block_size(page); }\n    return p;  // reallocation still fits and not more than 50% waste\n  }\n  void* newp = mi_heap_umalloc(heap,newsize,usable_post);\n  if mi_likely(newp != NULL) {\n    if (zero && newsize > size) {\n      // also set last word in the previous allocation to zero to ensure any padding is zero-initialized\n      const size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0);\n      _mi_memzero((uint8_t*)newp + start, newsize - start);\n    }\n    else if (newsize == 0) {\n      ((uint8_t*)newp)[0] = 0; // work around for applications that expect zero-reallocation to be zero initialized (issue #725)\n    }\n    if mi_likely(p != NULL) {\n      const size_t copysize = (newsize > size ? size : newsize);\n      mi_track_mem_defined(p,copysize);  // _mi_useable_size may be too large for byte precise memory tracking..\n      _mi_memcpy(newp, p, copysize);\n      mi_free(p); // only free the original pointer if successful\n    }\n  }\n  return newp;\n}\n\nmi_decl_nodiscard void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {\n  return _mi_heap_realloc_zero(heap, p, newsize, false, NULL, NULL);\n}\n\nmi_decl_nodiscard void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count, size, &total)) return NULL;\n  return mi_heap_realloc(heap, p, total);\n}\n\n\n// Reallocate but free `p` on errors\nmi_decl_nodiscard void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {\n  void* newp = mi_heap_realloc(heap, p, newsize);\n  if (newp==NULL && p!=NULL) mi_free(p);\n  return newp;\n}\n\nmi_decl_nodiscard void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {\n  return _mi_heap_realloc_zero(heap, p, newsize, true, NULL, NULL);\n}\n\nmi_decl_nodiscard void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count, size, &total)) return NULL;\n  return mi_heap_rezalloc(heap, p, total);\n}\n\n\nmi_decl_nodiscard void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept {\n  return mi_heap_realloc(mi_prim_get_default_heap(),p,newsize);\n}\n\nmi_decl_nodiscard void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept {\n  return mi_heap_reallocn(mi_prim_get_default_heap(),p,count,size);\n}\n\nmi_decl_nodiscard void* mi_urealloc(void* p, size_t newsize, size_t* usable_pre, size_t* usable_post) mi_attr_noexcept {\n  return _mi_heap_realloc_zero(mi_prim_get_default_heap(),p,newsize, false, usable_pre, usable_post);\n}\n\n// Reallocate but free `p` on errors\nmi_decl_nodiscard void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept {\n  return mi_heap_reallocf(mi_prim_get_default_heap(),p,newsize);\n}\n\nmi_decl_nodiscard void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept {\n  return mi_heap_rezalloc(mi_prim_get_default_heap(), p, newsize);\n}\n\nmi_decl_nodiscard void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept {\n  return mi_heap_recalloc(mi_prim_get_default_heap(), p, count, size);\n}\n\n\n\n// ------------------------------------------------------\n// strdup, strndup, and realpath\n// ------------------------------------------------------\n\n// `strdup` using mi_malloc\nmi_decl_nodiscard mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept {\n  if (s == NULL) return NULL;\n  size_t len = _mi_strlen(s);\n  if (len > MI_MAX_ALLOC_SIZE - 1) return NULL;  // prevent overflow on len+1\n  char* t = (char*)mi_heap_malloc(heap,len+1);\n  if (t == NULL) return NULL;\n  _mi_memcpy(t, s, len);\n  t[len] = 0;\n  return t;\n}\n\nmi_decl_nodiscard mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept {\n  return mi_heap_strdup(mi_prim_get_default_heap(), s);\n}\n\n// `strndup` using mi_malloc\nmi_decl_nodiscard mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept {\n  if (s == NULL) return NULL;\n  const size_t len = _mi_strnlen(s,n);  // len <= n\n  if (len > MI_MAX_ALLOC_SIZE - 1) return NULL;  // prevent overflow on len+1\n  char* t = (char*)mi_heap_malloc(heap, len+1);\n  if (t == NULL) return NULL;\n  _mi_memcpy(t, s, len);\n  t[len] = 0;\n  return t;\n}\n\nmi_decl_nodiscard mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept {\n  return mi_heap_strndup(mi_prim_get_default_heap(),s,n);\n}\n\n#ifndef __wasi__\n// `realpath` using mi_malloc\n#ifdef _WIN32\n#ifndef PATH_MAX\n#define PATH_MAX MAX_PATH\n#endif\n\nmi_decl_nodiscard mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept {\n  // todo: use GetFullPathNameW to allow longer file names\n  char buf[PATH_MAX];\n  DWORD res = GetFullPathNameA(fname, PATH_MAX, (resolved_name == NULL ? buf : resolved_name), NULL);\n  if (res == 0) {\n    errno = GetLastError(); return NULL;\n  }\n  else if (res > PATH_MAX) {\n    errno = EINVAL; return NULL;\n  }\n  else if (resolved_name != NULL) {\n    return resolved_name;\n  }\n  else {\n    return mi_heap_strndup(heap, buf, PATH_MAX);\n  }\n}\n\n#else\n\n#include <unistd.h>  // pathconf\n\nstatic size_t mi_path_max(void) {\n  static _Atomic(size_t) path_max = 0;\n  size_t pmax = mi_atomic_load_acquire(&path_max);\n  if (pmax == 0) {\n    long m = 0;\n    #ifdef _PC_PATH_MAX\n    m = pathconf(\"/\",_PC_PATH_MAX);\n    #endif\n    if (m <= 0) pmax = 4096;      // guess\n    else if (m < 256) pmax = 256; // at least 256\n    else if (m > 64*1024) pmax = 64*1024;  // at most 64 KiB\n    else pmax = m;\n    size_t expected = 0;\n    mi_atomic_cas_strong_acq_rel(&path_max, &expected, pmax);\n  }\n  return pmax;\n}\n\nchar* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept {\n  if (resolved_name != NULL) {\n    return realpath(fname,resolved_name);\n  }\n  else {\n  /*\n    char* rname = realpath(fname, NULL);\n    if (rname == NULL) return NULL;\n    char* result = mi_heap_strdup(heap, rname);\n    mi_cfree(rname);  // note: may leak the original pointer if allocated internally with the system allocator \n    // note: with ASAN realpath is intercepted and mi_cfree may leak the returned pointer :-(\n    return result;  \n  */\n    const size_t n  = mi_path_max();\n    char* const buf = (char*)mi_zalloc(n+1);\n    if (buf == NULL) {\n      errno = ENOMEM;\n      return NULL;\n    }\n    char* rname  = realpath(fname,buf);\n    char* result = mi_heap_strndup(heap,rname,n); // ok if `rname==NULL`\n    mi_free(buf);\n    return result;\n  }\n}\n#endif\n\nmi_decl_nodiscard mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept {\n  return mi_heap_realpath(mi_prim_get_default_heap(),fname,resolved_name);\n}\n#endif\n\n/*-------------------------------------------------------\nC++ new and new_aligned\nThe standard requires calling into `get_new_handler` and\nthrowing the bad_alloc exception on failure. If we compile\nwith a C++ compiler we can implement this precisely. If we\nuse a C compiler we cannot throw a `bad_alloc` exception\nbut we call `exit` instead (i.e. not returning).\n-------------------------------------------------------*/\n\n#ifdef __cplusplus\n#include <new>\nstatic bool mi_try_new_handler(bool nothrow) {\n  #if defined(_MSC_VER) || (__cplusplus >= 201103L)\n    std::new_handler h = std::get_new_handler();\n  #else\n    std::new_handler h = std::set_new_handler();\n    std::set_new_handler(h);\n  #endif\n  if (h==NULL) {\n    _mi_error_message(ENOMEM, \"out of memory in 'new'\");\n    #if defined(_CPPUNWIND) || defined(__cpp_exceptions)  // exceptions are not always enabled\n    if (!nothrow) {\n      throw std::bad_alloc();\n    }\n    #else\n    MI_UNUSED(nothrow);\n    #endif\n    return false;\n  }\n  else {\n    h();\n    return true;\n  }\n}\n#else\ntypedef void (*std_new_handler_t)(void);\n\n#if (defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER)))  // exclude clang-cl, see issue #631\nstd_new_handler_t __attribute__((weak)) _ZSt15get_new_handlerv(void) {\n  return NULL;\n}\nstatic std_new_handler_t mi_get_new_handler(void) {\n  return _ZSt15get_new_handlerv();\n}\n#else\n// note: on windows we could dynamically link to `?get_new_handler@std@@YAP6AXXZXZ`.\nstatic std_new_handler_t mi_get_new_handler(void) {\n  return NULL;\n}\n#endif\n\nstatic bool mi_try_new_handler(bool nothrow) {\n  std_new_handler_t h = mi_get_new_handler();\n  if (h==NULL) {\n    _mi_error_message(ENOMEM, \"out of memory in 'new'\");\n    if (!nothrow) {\n      abort();  // cannot throw in plain C, use abort\n    }\n    return false;\n  }\n  else {\n    h();\n    return true;\n  }\n}\n#endif\n\nmi_decl_export mi_decl_noinline void* mi_heap_try_new(mi_heap_t* heap, size_t size, bool nothrow ) {\n  void* p = NULL;\n  while(p == NULL && mi_try_new_handler(nothrow)) {\n    p = mi_heap_malloc(heap,size);\n  }\n  return p;\n}\n\nstatic mi_decl_noinline void* mi_try_new(size_t size, bool nothrow) {\n  return mi_heap_try_new(mi_prim_get_default_heap(), size, nothrow);\n}\n\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_alloc_new(mi_heap_t* heap, size_t size) {\n  void* p = mi_heap_malloc(heap,size);\n  if mi_unlikely(p == NULL) return mi_heap_try_new(heap, size, false);\n  return p;\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_new(size_t size) {\n  return mi_heap_alloc_new(mi_prim_get_default_heap(), size);\n}\n\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_alloc_new_n(mi_heap_t* heap, size_t count, size_t size) {\n  size_t total;\n  if mi_unlikely(mi_count_size_overflow(count, size, &total)) {\n    mi_try_new_handler(false);  // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc\n    return NULL;\n  }\n  else {\n    return mi_heap_alloc_new(heap,total);\n  }\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_new_n(size_t count, size_t size) {\n  return mi_heap_alloc_new_n(mi_prim_get_default_heap(), count, size);\n}\n\n\nmi_decl_nodiscard mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept {\n  void* p = mi_malloc(size);\n  if mi_unlikely(p == NULL) return mi_try_new(size, true);\n  return p;\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) {\n  void* p;\n  do {\n    p = mi_malloc_aligned(size, alignment);\n  }\n  while(p == NULL && mi_try_new_handler(false));\n  return p;\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept {\n  void* p;\n  do {\n    p = mi_malloc_aligned(size, alignment);\n  }\n  while(p == NULL && mi_try_new_handler(true));\n  return p;\n}\n\nmi_decl_nodiscard void* mi_new_realloc(void* p, size_t newsize) {\n  void* q;\n  do {\n    q = mi_realloc(p, newsize);\n  } while (q == NULL && mi_try_new_handler(false));\n  return q;\n}\n\nmi_decl_nodiscard void* mi_new_reallocn(void* p, size_t newcount, size_t size) {\n  size_t total;\n  if mi_unlikely(mi_count_size_overflow(newcount, size, &total)) {\n    mi_try_new_handler(false);  // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc\n    return NULL;\n  }\n  else {\n    return mi_new_realloc(p, total);\n  }\n}\n\n#if MI_GUARDED\n// We always allocate a guarded allocation at an offset (`mi_page_has_aligned` will be true).\n// We then set the first word of the block to `0` for regular offset aligned allocations (in `alloc-aligned.c`)\n// and the first word to `~0` for guarded allocations to have a correct `mi_usable_size`\n\nstatic void* mi_block_ptr_set_guarded(mi_block_t* block, size_t obj_size) {\n  // TODO: we can still make padding work by moving it out of the guard page area\n  mi_page_t* const page = _mi_ptr_page(block);\n  mi_page_set_has_aligned(page, true);\n  block->next = MI_BLOCK_TAG_GUARDED;\n\n  // set guard page at the end of the block\n  mi_segment_t* const segment = _mi_page_segment(page);\n  const size_t block_size = mi_page_block_size(page);  // must use `block_size` to match `mi_free_local`\n  const size_t os_page_size = _mi_os_page_size();\n  mi_assert_internal(block_size >= obj_size + os_page_size + sizeof(mi_block_t));\n  if (block_size < obj_size + os_page_size + sizeof(mi_block_t)) {\n    // should never happen\n    mi_free(block);\n    return NULL;\n  }\n  uint8_t* guard_page = (uint8_t*)block + block_size - os_page_size;\n  mi_assert_internal(_mi_is_aligned(guard_page, os_page_size));\n  if mi_likely(segment->allow_decommit && _mi_is_aligned(guard_page, os_page_size)) {\n    const bool ok = _mi_os_protect(guard_page, os_page_size);\n    if mi_unlikely(!ok) {\n      _mi_warning_message(\"failed to set a guard page behind an object (object %p of size %zu)\\n\", block, block_size);\n    }\n  }\n  else {\n    _mi_warning_message(\"unable to set a guard page behind an object due to pinned memory (large OS pages?) (object %p of size %zu)\\n\", block, block_size);\n  }\n\n  // align pointer just in front of the guard page\n  size_t offset = block_size - os_page_size - obj_size;\n  mi_assert_internal(offset > sizeof(mi_block_t));\n  if (offset > MI_BLOCK_ALIGNMENT_MAX) {\n    // give up to place it right in front of the guard page if the offset is too large for unalignment\n    offset = MI_BLOCK_ALIGNMENT_MAX;\n  }\n  uint8_t* const p = (uint8_t*)block + offset;\n  mi_assert_internal(p == guard_page - obj_size);\n  mi_track_align(block, p, offset, obj_size);\n  mi_track_mem_defined(block, sizeof(mi_block_t));\n  return p;\n}\n\nmi_decl_restrict void* _mi_heap_malloc_guarded(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept\n{\n  // allocate multiple of page size ending in a guard page\n  // ensure minimal alignment requirement?\n  if mi_unlikely(size >= MI_MAX_ALLOC_SIZE - MI_PADDING_SIZE) {  // check up front so the `req_size` won't overflow    \n    _mi_error_message(EOVERFLOW, \"(guarded) allocation request is too large (%zu bytes)\\n\", size);\n    return NULL;\n  }\n  const size_t os_page_size = _mi_os_page_size();\n  const size_t obj_size = (mi_option_is_enabled(mi_option_guarded_precise) ? size : _mi_align_up(size, MI_MAX_ALIGN_SIZE));\n  const size_t bsize    = _mi_align_up(_mi_align_up(obj_size, MI_MAX_ALIGN_SIZE) + sizeof(mi_block_t), MI_MAX_ALIGN_SIZE);\n  const size_t req_size = _mi_align_up(bsize + os_page_size, os_page_size);\n  mi_block_t* const block = (mi_block_t*)_mi_malloc_generic(heap, req_size, false /* don't zero */, 0 /* huge_alignment */, NULL);\n  if (block==NULL) return NULL;\n  void* const p   = mi_block_ptr_set_guarded(block, obj_size);\n  if (p == NULL) return NULL;  \n  if (zero) {\n    _mi_memzero(p,obj_size);  // we have to zero afterwards as padding might have written inside the block (if the `blocksize > reqsize + os_page_size`)\n  }\n\n  // stats\n  mi_track_malloc(p, obj_size, zero);   \n  if (!mi_heap_is_initialized(heap)) { heap = mi_prim_get_default_heap(); }\n  _mi_stat_counter_increase(&heap->tld->stats.malloc_guarded_count, 1);\n  #if MI_STAT>1\n  // adjust stats to only count the allocated size of the block (and not the guard page)\n  mi_heap_stat_adjust_decrease(heap, malloc_requested, req_size);\n  mi_heap_stat_increase(heap, malloc_requested, size);\n  #endif\n  #if MI_DEBUG>3\n  if (zero) {\n    mi_assert_expensive(mi_mem_is_zero(p, size));\n  }\n  #endif\n  return p;\n}\n#endif\n\n// ------------------------------------------------------\n// ensure explicit external inline definitions are emitted!\n// ------------------------------------------------------\n\n#ifdef __cplusplus\nvoid* _mi_externs[] = {\n  (void*)&_mi_page_malloc,\n  (void*)&_mi_page_malloc_zero,\n  (void*)&_mi_heap_malloc_zero,\n  (void*)&_mi_heap_malloc_zero_ex,\n  (void*)&mi_malloc,\n  (void*)&mi_malloc_small,\n  (void*)&mi_zalloc_small,\n  (void*)&mi_heap_malloc,\n  (void*)&mi_heap_zalloc,\n  (void*)&mi_heap_malloc_small,\n  // (void*)&mi_heap_alloc_new,\n  // (void*)&mi_heap_alloc_new_n\n};\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/arena-abandon.c",
      "sha256": "9a663611e9c73e42f73bbd42ea4c7869099b8e34c7a5968e27b373af8db1e951",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#if !defined(MI_IN_ARENA_C)\n#error \"this file should be included from 'arena.c' (so mi_arena_t is visible)\"\n// add includes help an IDE\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"bitmap.h\"\n#endif\n\n// Minimal exports for arena-abandoned.\nsize_t      mi_arena_id_index(mi_arena_id_t id);\nmi_arena_t* mi_arena_from_index(size_t idx);\nsize_t      mi_arena_get_count(void);\nvoid*       mi_arena_block_start(mi_arena_t* arena, mi_bitmap_index_t bindex);\nbool        mi_arena_memid_indices(mi_memid_t memid, size_t* arena_index, mi_bitmap_index_t* bitmap_index);\n\n/* -----------------------------------------------------------\n  Abandoned blocks/segments:\n\n  _mi_arena_segment_clear_abandoned\n  _mi_arena_segment_mark_abandoned\n\n  This is used to atomically abandon/reclaim segments\n  (and crosses the arena API but it is convenient to have here).\n\n  Abandoned segments still have live blocks; they get reclaimed\n  when a thread frees a block in it, or when a thread needs a fresh\n  segment.\n\n  Abandoned segments are atomically marked in the `block_abandoned`\n  bitmap of arenas. Any segments allocated outside arenas are put\n  in the sub-process `abandoned_os_list`. This list is accessed\n  using locks but this should be uncommon and generally uncontended.\n  Reclaim and visiting either scan through the `block_abandoned`\n  bitmaps of the arena's, or visit the `abandoned_os_list`\n\n  A potentially nicer design is to use arena's for everything\n  and perhaps have virtual arena's to map OS allocated memory\n  but this would lack the \"density\" of our current arena's. TBC.\n----------------------------------------------------------- */\n\n\n// reclaim a specific OS abandoned segment; `true` on success.\n// sets the thread_id.\nstatic bool mi_arena_segment_os_clear_abandoned(mi_segment_t* segment, bool take_lock) {\n  mi_assert(segment->memid.memkind != MI_MEM_ARENA);\n  // not in an arena, remove from list of abandoned os segments\n  mi_subproc_t* const subproc = segment->subproc;\n  if (take_lock && !mi_lock_try_acquire(&subproc->abandoned_os_lock)) {\n    return false;  // failed to acquire the lock, we just give up\n  }\n  // remove atomically from the abandoned os list (if possible!)\n  bool reclaimed = false;\n  mi_segment_t* const next = segment->abandoned_os_next;\n  mi_segment_t* const prev = segment->abandoned_os_prev;\n  if (next != NULL || prev != NULL || subproc->abandoned_os_list == segment) {\n    #if MI_DEBUG>3\n    // find ourselves in the abandoned list (and check the count)\n    bool found = false;\n    size_t count = 0;\n    for (mi_segment_t* current = subproc->abandoned_os_list; current != NULL; current = current->abandoned_os_next) {\n      if (current == segment) { found = true; }\n      count++;\n    }\n    mi_assert_internal(found);\n    mi_assert_internal(count == mi_atomic_load_relaxed(&subproc->abandoned_os_list_count));\n    #endif\n    // remove (atomically) from the list and reclaim\n    if (prev != NULL) { prev->abandoned_os_next = next; }\n    else { subproc->abandoned_os_list = next; }\n    if (next != NULL) { next->abandoned_os_prev = prev; }\n    else { subproc->abandoned_os_list_tail = prev; }\n    segment->abandoned_os_next = NULL;\n    segment->abandoned_os_prev = NULL;\n    mi_atomic_decrement_relaxed(&subproc->abandoned_count);\n    mi_atomic_decrement_relaxed(&subproc->abandoned_os_list_count);\n    if (take_lock) { // don't reset the thread_id when iterating\n      mi_atomic_store_release(&segment->thread_id, _mi_thread_id());\n    }\n    reclaimed = true;\n  }\n  if (take_lock) { mi_lock_release(&segment->subproc->abandoned_os_lock); }\n  return reclaimed;\n}\n\n// reclaim a specific abandoned segment; `true` on success.\n// sets the thread_id.\nbool _mi_arena_segment_clear_abandoned(mi_segment_t* segment) {\n  if mi_unlikely(segment->memid.memkind != MI_MEM_ARENA) {\n    return mi_arena_segment_os_clear_abandoned(segment, true /* take lock */);\n  }\n  // arena segment: use the blocks_abandoned bitmap.\n  size_t arena_idx;\n  size_t bitmap_idx;\n  mi_arena_memid_indices(segment->memid, &arena_idx, &bitmap_idx);\n  mi_arena_t* arena = mi_arena_from_index(arena_idx);\n  mi_assert_internal(arena != NULL);\n  // reclaim atomically\n  bool was_marked = _mi_bitmap_unclaim(arena->blocks_abandoned, arena->field_count, 1, bitmap_idx);\n  if (was_marked) {\n    mi_assert_internal(mi_atomic_load_acquire(&segment->thread_id) == 0);\n    mi_atomic_decrement_relaxed(&segment->subproc->abandoned_count);\n    mi_atomic_store_release(&segment->thread_id, _mi_thread_id());\n  }\n  // mi_assert_internal(was_marked);\n  mi_assert_internal(!was_marked || _mi_bitmap_is_claimed(arena->blocks_inuse, arena->field_count, 1, bitmap_idx));\n  //mi_assert_internal(arena->blocks_committed == NULL || _mi_bitmap_is_claimed(arena->blocks_committed, arena->field_count, 1, bitmap_idx));\n  return was_marked;\n}\n\n\n// mark a specific OS segment as abandoned\nstatic void mi_arena_segment_os_mark_abandoned(mi_segment_t* segment) {\n  mi_assert(segment->memid.memkind != MI_MEM_ARENA);\n  // not in an arena; we use a list of abandoned segments\n  mi_subproc_t* const subproc = segment->subproc;\n  mi_lock(&subproc->abandoned_os_lock) {\n    // push on the tail of the list (important for the visitor)\n    mi_segment_t* prev = subproc->abandoned_os_list_tail;\n    mi_assert_internal(prev == NULL || prev->abandoned_os_next == NULL);\n    mi_assert_internal(segment->abandoned_os_prev == NULL);\n    mi_assert_internal(segment->abandoned_os_next == NULL);\n    if (prev != NULL) { prev->abandoned_os_next = segment; }\n    else { subproc->abandoned_os_list = segment; }\n    subproc->abandoned_os_list_tail = segment;\n    segment->abandoned_os_prev = prev;\n    segment->abandoned_os_next = NULL;\n    mi_atomic_increment_relaxed(&subproc->abandoned_os_list_count);\n    mi_atomic_increment_relaxed(&subproc->abandoned_count);\n    // and release the lock\n  }\n  return;\n}\n\n// mark a specific segment as abandoned\n// clears the thread_id.\nvoid _mi_arena_segment_mark_abandoned(mi_segment_t* segment)\n{\n  mi_assert_internal(segment->used == segment->abandoned);\n  mi_atomic_store_release(&segment->thread_id, (uintptr_t)0);  // mark as abandoned for multi-thread free's\n  if mi_unlikely(segment->memid.memkind != MI_MEM_ARENA) {\n    mi_arena_segment_os_mark_abandoned(segment);\n    return;\n  }\n  // segment is in an arena, mark it in the arena `blocks_abandoned` bitmap\n  size_t arena_idx;\n  size_t bitmap_idx;\n  mi_arena_memid_indices(segment->memid, &arena_idx, &bitmap_idx);\n  mi_arena_t* arena = mi_arena_from_index(arena_idx);\n  mi_assert_internal(arena != NULL);\n  // set abandonment atomically\n  mi_subproc_t* const subproc = segment->subproc; // don't access the segment after setting it abandoned\n  const bool was_unmarked = _mi_bitmap_claim(arena->blocks_abandoned, arena->field_count, 1, bitmap_idx, NULL);\n  if (was_unmarked) { mi_atomic_increment_relaxed(&subproc->abandoned_count); }\n  mi_assert_internal(was_unmarked);\n  mi_assert_internal(_mi_bitmap_is_claimed(arena->blocks_inuse, arena->field_count, 1, bitmap_idx));\n}\n\n\n/* -----------------------------------------------------------\n  Iterate through the abandoned blocks/segments using a cursor.\n  This is used for reclaiming and abandoned block visiting.\n----------------------------------------------------------- */\n\n// start a cursor at a randomized arena\nvoid _mi_arena_field_cursor_init(mi_heap_t* heap, mi_subproc_t* subproc, bool visit_all, mi_arena_field_cursor_t* current) {\n  mi_assert_internal(heap == NULL || heap->tld->segments.subproc == subproc);\n  current->bitmap_idx = 0;\n  current->subproc = subproc;\n  current->visit_all = visit_all;\n  current->hold_visit_lock = false;\n  const size_t abandoned_count = mi_atomic_load_relaxed(&subproc->abandoned_count);\n  const size_t abandoned_list_count = mi_atomic_load_relaxed(&subproc->abandoned_os_list_count);\n  const size_t max_arena = mi_arena_get_count();\n  if (heap != NULL && heap->arena_id != _mi_arena_id_none()) {\n    // for a heap that is bound to one arena, only visit that arena\n    current->start = mi_arena_id_index(heap->arena_id);\n    current->end = current->start + 1;\n    current->os_list_count = 0;\n  }\n  else {\n    // otherwise visit all starting at a random location\n    if (abandoned_count > abandoned_list_count && max_arena > 0) {\n      current->start = (heap == NULL || max_arena == 0 ? 0 : (mi_arena_id_t)(_mi_heap_random_next(heap) % max_arena));\n      current->end = current->start + max_arena;\n    }\n    else {\n      current->start = 0;\n      current->end = 0;\n    }\n    current->os_list_count = abandoned_list_count; // max entries to visit in the os abandoned list\n  }\n  mi_assert_internal(current->start <= max_arena);\n}\n\nvoid _mi_arena_field_cursor_done(mi_arena_field_cursor_t* current) {\n  if (current->hold_visit_lock) {\n    mi_lock_release(&current->subproc->abandoned_os_visit_lock);\n    current->hold_visit_lock = false;\n  }\n}\n\nstatic mi_segment_t* mi_arena_segment_clear_abandoned_at(mi_arena_t* arena, mi_subproc_t* subproc, mi_bitmap_index_t bitmap_idx) {\n  // try to reclaim an abandoned segment in the arena atomically\n  if (!_mi_bitmap_unclaim(arena->blocks_abandoned, arena->field_count, 1, bitmap_idx)) return NULL;\n  mi_assert_internal(_mi_bitmap_is_claimed(arena->blocks_inuse, arena->field_count, 1, bitmap_idx));\n  mi_segment_t* segment = (mi_segment_t*)mi_arena_block_start(arena, bitmap_idx);\n  mi_assert_internal(mi_atomic_load_relaxed(&segment->thread_id) == 0);\n  // check that the segment belongs to our sub-process\n  // note: this is the reason we need the `abandoned_visit` lock in the case abandoned visiting is enabled.\n  //  without the lock an abandoned visit may otherwise fail to visit all abandoned segments in the sub-process.\n  //  for regular reclaim it is fine to miss one sometimes so without abandoned visiting we don't need the `abandoned_visit` lock.\n  if (segment->subproc != subproc) {\n    // it is from another sub-process, re-mark it and continue searching\n    const bool was_zero = _mi_bitmap_claim(arena->blocks_abandoned, arena->field_count, 1, bitmap_idx, NULL);\n    mi_assert_internal(was_zero); MI_UNUSED(was_zero);\n    return NULL;\n  }\n  else {\n    // success, we unabandoned a segment in our sub-process\n    mi_atomic_decrement_relaxed(&subproc->abandoned_count);\n    return segment;\n  }\n}\n\nstatic mi_segment_t* mi_arena_segment_clear_abandoned_next_field(mi_arena_field_cursor_t* previous) {\n  const size_t max_arena = mi_arena_get_count();\n  size_t field_idx = mi_bitmap_index_field(previous->bitmap_idx);\n  size_t bit_idx = mi_bitmap_index_bit_in_field(previous->bitmap_idx);\n  // visit arena's (from the previous cursor)\n  for (; previous->start < previous->end; previous->start++, field_idx = 0, bit_idx = 0) {\n    // index wraps around\n    size_t arena_idx = (previous->start >= max_arena ? previous->start % max_arena : previous->start);\n    mi_arena_t* arena = mi_arena_from_index(arena_idx);\n    if (arena != NULL) {\n      bool has_lock = false;\n      // visit the abandoned fields (starting at previous_idx)\n      for (; field_idx < arena->field_count; field_idx++, bit_idx = 0) {\n        size_t field = mi_atomic_load_relaxed(&arena->blocks_abandoned[field_idx]);\n        if mi_unlikely(field != 0) { // skip zero fields quickly\n          // we only take the arena lock if there are actually abandoned segments present\n          if (!has_lock && mi_option_is_enabled(mi_option_visit_abandoned)) {\n            has_lock = (previous->visit_all ? (mi_lock_acquire(&arena->abandoned_visit_lock),true) : mi_lock_try_acquire(&arena->abandoned_visit_lock));\n            if (!has_lock) {\n              if (previous->visit_all) {\n                _mi_error_message(EFAULT, \"internal error: failed to visit all abandoned segments due to failure to acquire the visitor lock\");\n              }\n              // skip to next arena\n              break;\n            }\n          }\n          mi_assert_internal(has_lock || !mi_option_is_enabled(mi_option_visit_abandoned));\n          // visit each set bit in the field  (todo: maybe use `ctz` here?)\n          for (; bit_idx < MI_BITMAP_FIELD_BITS; bit_idx++) {\n            // pre-check if the bit is set\n            size_t mask = ((size_t)1 << bit_idx);\n            if mi_unlikely((field & mask) == mask) {\n              mi_bitmap_index_t bitmap_idx = mi_bitmap_index_create(field_idx, bit_idx);\n              mi_segment_t* const segment = mi_arena_segment_clear_abandoned_at(arena, previous->subproc, bitmap_idx);\n              if (segment != NULL) {\n                //mi_assert_internal(arena->blocks_committed == NULL || _mi_bitmap_is_claimed(arena->blocks_committed, arena->field_count, 1, bitmap_idx));\n                if (has_lock) { mi_lock_release(&arena->abandoned_visit_lock); }\n                previous->bitmap_idx = mi_bitmap_index_create_ex(field_idx, bit_idx + 1); // start at next one for the next iteration\n                return segment;\n              }\n            }\n          }\n        }\n      }\n      if (has_lock) { mi_lock_release(&arena->abandoned_visit_lock); }\n    }\n  }\n  return NULL;\n}\n\nstatic mi_segment_t* mi_arena_segment_clear_abandoned_next_list(mi_arena_field_cursor_t* previous) {\n  // go through the abandoned_os_list\n  // we only allow one thread per sub-process to do to visit guarded by the `abandoned_os_visit_lock`.\n  // The lock is released when the cursor is released.\n  if (!previous->hold_visit_lock) {\n    previous->hold_visit_lock = (previous->visit_all ? (mi_lock_acquire(&previous->subproc->abandoned_os_visit_lock),true)\n                                                     : mi_lock_try_acquire(&previous->subproc->abandoned_os_visit_lock));\n    if (!previous->hold_visit_lock) {\n      if (previous->visit_all) {\n        _mi_error_message(EFAULT, \"internal error: failed to visit all abandoned segments due to failure to acquire the OS visitor lock\");\n      }\n      return NULL; // we cannot get the lock, give up\n    }\n  }\n  // One list entry at a time\n  while (previous->os_list_count > 0) {\n    previous->os_list_count--;\n    mi_lock_acquire(&previous->subproc->abandoned_os_lock); // this could contend with concurrent OS block abandonment and reclaim from `free`\n    mi_segment_t* segment = previous->subproc->abandoned_os_list;\n    // pop from head of the list, a subsequent mark will push at the end (and thus we iterate through os_list_count entries)\n    if (segment == NULL || mi_arena_segment_os_clear_abandoned(segment, false /* we already have the lock */)) {\n      mi_lock_release(&previous->subproc->abandoned_os_lock);\n      return segment;\n    }\n    // already abandoned, try again\n    mi_lock_release(&previous->subproc->abandoned_os_lock);\n  }\n  // done\n  mi_assert_internal(previous->os_list_count == 0);\n  return NULL;\n}\n\n\n// reclaim abandoned segments\n// this does not set the thread id (so it appears as still abandoned)\nmi_segment_t* _mi_arena_segment_clear_abandoned_next(mi_arena_field_cursor_t* previous) {\n  if (previous->start < previous->end) {\n    // walk the arena\n    mi_segment_t* segment = mi_arena_segment_clear_abandoned_next_field(previous);\n    if (segment != NULL) { return segment; }\n  }\n  // no entries in the arena's anymore, walk the abandoned OS list\n  mi_assert_internal(previous->start == previous->end);\n  return mi_arena_segment_clear_abandoned_next_list(previous);\n}\n\n\nbool mi_abandoned_visit_blocks(mi_subproc_id_t subproc_id, int heap_tag, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) {\n  // (unfortunately) the visit_abandoned option must be enabled from the start.\n  // This is to avoid taking locks if abandoned list visiting is not required (as for most programs)\n  if (!mi_option_is_enabled(mi_option_visit_abandoned)) {\n    _mi_error_message(EFAULT, \"internal error: can only visit abandoned blocks when MIMALLOC_VISIT_ABANDONED=ON\");\n    return false;\n  }\n  mi_arena_field_cursor_t current;\n  _mi_arena_field_cursor_init(NULL, _mi_subproc_from_id(subproc_id), true /* visit all (blocking) */, &current);\n  mi_segment_t* segment;\n  bool ok = true;\n  while (ok && (segment = _mi_arena_segment_clear_abandoned_next(&current)) != NULL) {\n    ok = _mi_segment_visit_blocks(segment, heap_tag, visit_blocks, visitor, arg);\n    _mi_arena_segment_mark_abandoned(segment);\n  }\n  _mi_arena_field_cursor_done(&current);\n  return ok;\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/arena.c",
      "sha256": "029ed6c1f61a943127b90a5e1be5e7217bfac6b905512709dc0a6d0795e98b28",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* ----------------------------------------------------------------------------\n\"Arenas\" are fixed area's of OS memory from which we can allocate\nlarge blocks (>= MI_ARENA_MIN_BLOCK_SIZE, 4MiB).\nIn contrast to the rest of mimalloc, the arenas are shared between\nthreads and need to be accessed using atomic operations.\n\nArenas are also used to for huge OS page (1GiB) reservations or for reserving\nOS memory upfront which can be improve performance or is sometimes needed\non embedded devices. We can also employ this with WASI or `sbrk` systems\nto reserve large arenas upfront and be able to reuse the memory more effectively.\n\nThe arena allocation needs to be thread safe and we use an atomic bitmap to allocate.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"bitmap.h\"\n\n\n/* -----------------------------------------------------------\n  Arena allocation\n----------------------------------------------------------- */\n\n// A memory arena descriptor\ntypedef struct mi_arena_s {\n  mi_arena_id_t       id;                   // arena id; 0 for non-specific\n  mi_memid_t          memid;                // memid of the memory area\n  _Atomic(uint8_t*)   start;                // the start of the memory area\n  size_t              block_count;          // size of the area in arena blocks (of `MI_ARENA_BLOCK_SIZE`)\n  size_t              field_count;          // number of bitmap fields (where `field_count * MI_BITMAP_FIELD_BITS >= block_count`)\n  size_t              meta_size;            // size of the arena structure itself (including its bitmaps)\n  mi_memid_t          meta_memid;           // memid of the arena structure itself (OS or static allocation)\n  int                 numa_node;            // associated NUMA node\n  bool                exclusive;            // only allow allocations if specifically for this arena\n  bool                is_large;             // memory area consists of large- or huge OS pages (always committed)\n  mi_lock_t           abandoned_visit_lock; // lock is only used when abandoned segments are being visited\n  _Atomic(size_t)     search_idx;           // optimization to start the search for free blocks\n  _Atomic(mi_msecs_t) purge_expire;         // expiration time when blocks should be purged from `blocks_purge`.\n\n  mi_bitmap_field_t*  blocks_dirty;         // are the blocks potentially non-zero?\n  mi_bitmap_field_t*  blocks_committed;     // are the blocks committed? (can be NULL for memory that cannot be decommitted)\n  mi_bitmap_field_t*  blocks_purge;         // blocks that can be (reset) decommitted. (can be NULL for memory that cannot be (reset) decommitted)\n  mi_bitmap_field_t*  blocks_abandoned;     // blocks that start with an abandoned segment. (This crosses API's but it is convenient to have here)\n  mi_bitmap_field_t   blocks_inuse[1];      // in-place bitmap of in-use blocks (of size `field_count`)\n  // do not add further fields here as the dirty, committed, purged, and abandoned bitmaps follow the inuse bitmap fields.\n} mi_arena_t;\n\n\n#define MI_ARENA_BLOCK_SIZE   (MI_SEGMENT_SIZE)        // 64MiB  (must be at least MI_SEGMENT_ALIGN)\n#define MI_ARENA_MIN_OBJ_SIZE (MI_ARENA_BLOCK_SIZE/2)  // 32MiB\n#define MI_MAX_ARENAS         (132)                    // Limited as the reservation exponentially increases (and takes up .bss)\n\n// The available arenas\nstatic mi_decl_cache_align _Atomic(mi_arena_t*) mi_arenas[MI_MAX_ARENAS];\nstatic mi_decl_cache_align _Atomic(size_t)      mi_arena_count; // = 0\nstatic mi_decl_cache_align _Atomic(int64_t)     mi_arenas_purge_expire; // set if there exist purgeable arenas\n\n#define MI_IN_ARENA_C\n#include \"arena-abandon.c\"\n#undef MI_IN_ARENA_C\n\n/* -----------------------------------------------------------\n  Arena id's\n  id = arena_index + 1\n----------------------------------------------------------- */\n\nsize_t mi_arena_id_index(mi_arena_id_t id) {\n  return (size_t)(id <= 0 ? MI_MAX_ARENAS : id - 1);\n}\n\nstatic mi_arena_id_t mi_arena_id_create(size_t arena_index) {\n  mi_assert_internal(arena_index < MI_MAX_ARENAS);\n  return (int)arena_index + 1;\n}\n\nmi_arena_id_t _mi_arena_id_none(void) {\n  return 0;\n}\n\nstatic bool mi_arena_id_is_suitable(mi_arena_id_t arena_id, bool arena_is_exclusive, mi_arena_id_t req_arena_id) {\n  return ((!arena_is_exclusive && req_arena_id == _mi_arena_id_none()) ||\n          (arena_id == req_arena_id));\n}\n\nbool _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_id_t request_arena_id) {\n  if (memid.memkind == MI_MEM_ARENA) {\n    return mi_arena_id_is_suitable(memid.mem.arena.id, memid.mem.arena.is_exclusive, request_arena_id);\n  }\n  else {\n    return mi_arena_id_is_suitable(_mi_arena_id_none(), false, request_arena_id);\n  }\n}\n\nbool _mi_arena_memid_is_os_allocated(mi_memid_t memid) {\n  return (memid.memkind == MI_MEM_OS);\n}\n\nsize_t mi_arena_get_count(void) {\n  return mi_atomic_load_relaxed(&mi_arena_count);\n}\n\nmi_arena_t* mi_arena_from_index(size_t idx) {\n  mi_assert_internal(idx < mi_arena_get_count());\n  return mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[idx]);\n}\n\n\n/* -----------------------------------------------------------\n  Arena allocations get a (currently) 16-bit memory id where the\n  lower 8 bits are the arena id, and the upper bits the block index.\n----------------------------------------------------------- */\n\nstatic size_t mi_block_count_of_size(size_t size) {\n  return _mi_divide_up(size, MI_ARENA_BLOCK_SIZE);\n}\n\nstatic size_t mi_arena_block_size(size_t bcount) {\n  return (bcount * MI_ARENA_BLOCK_SIZE);\n}\n\nstatic size_t mi_arena_size(mi_arena_t* arena) {\n  return mi_arena_block_size(arena->block_count);\n}\n\nstatic mi_memid_t mi_memid_create_arena(mi_arena_id_t id, bool is_exclusive, mi_bitmap_index_t bitmap_index) {\n  mi_memid_t memid = _mi_memid_create(MI_MEM_ARENA);\n  memid.mem.arena.id = id;\n  memid.mem.arena.block_index = bitmap_index;\n  memid.mem.arena.is_exclusive = is_exclusive;\n  return memid;\n}\n\nbool mi_arena_memid_indices(mi_memid_t memid, size_t* arena_index, mi_bitmap_index_t* bitmap_index) {\n  mi_assert_internal(memid.memkind == MI_MEM_ARENA);\n  *arena_index = mi_arena_id_index(memid.mem.arena.id);\n  *bitmap_index = memid.mem.arena.block_index;\n  return memid.mem.arena.is_exclusive;\n}\n\n\n\n/* -----------------------------------------------------------\n  Special static area for mimalloc internal structures\n  to avoid OS calls (for example, for the arena metadata (~= 256b))\n----------------------------------------------------------- */\n\n#define MI_ARENA_STATIC_MAX  ((MI_INTPTR_SIZE/2)*MI_KiB)  // 4 KiB on 64-bit\n\nstatic mi_decl_cache_align uint8_t mi_arena_static[MI_ARENA_STATIC_MAX];  // must be cache aligned, see issue #895\nstatic mi_decl_cache_align _Atomic(size_t) mi_arena_static_top;\n\nstatic void* mi_arena_static_zalloc(size_t size, size_t alignment, mi_memid_t* memid) {\n  *memid = _mi_memid_none();\n  if (size == 0 || size > MI_ARENA_STATIC_MAX) return NULL;\n  const size_t toplow = mi_atomic_load_relaxed(&mi_arena_static_top);\n  if ((toplow + size) > MI_ARENA_STATIC_MAX) return NULL;\n\n  // try to claim space\n  if (alignment < MI_MAX_ALIGN_SIZE) { alignment = MI_MAX_ALIGN_SIZE; }\n  const size_t oversize = size + alignment - 1;\n  if (toplow + oversize > MI_ARENA_STATIC_MAX) return NULL;\n  const size_t oldtop = mi_atomic_add_acq_rel(&mi_arena_static_top, oversize);\n  size_t top = oldtop + oversize;\n  if (top > MI_ARENA_STATIC_MAX) {\n    // try to roll back, ok if this fails\n    mi_atomic_cas_strong_acq_rel(&mi_arena_static_top, &top, oldtop);\n    return NULL;\n  }\n\n  // success\n  *memid = _mi_memid_create(MI_MEM_STATIC);\n  memid->initially_zero = true;\n  const size_t start = _mi_align_up(oldtop, alignment);\n  uint8_t* const p = &mi_arena_static[start];\n  _mi_memzero_aligned(p, size);\n  return p;\n}\n\nvoid* _mi_arena_meta_zalloc(size_t size, mi_memid_t* memid) {\n  *memid = _mi_memid_none();\n\n  // try static\n  void* p = mi_arena_static_zalloc(size, MI_MAX_ALIGN_SIZE, memid);\n  if (p != NULL) return p;\n\n  // or fall back to the OS\n  p = _mi_os_zalloc(size, memid);\n  if (p == NULL) return NULL;\n\n  return p;\n}\n\nvoid _mi_arena_meta_free(void* p, mi_memid_t memid, size_t size) {\n  if (mi_memkind_is_os(memid.memkind)) {\n    _mi_os_free(p, size, memid);\n  }\n  else {\n    mi_assert(memid.memkind == MI_MEM_STATIC);\n  }\n}\n\nvoid* mi_arena_block_start(mi_arena_t* arena, mi_bitmap_index_t bindex) {\n  return (arena->start + mi_arena_block_size(mi_bitmap_index_bit(bindex)));\n}\n\n\n/* -----------------------------------------------------------\n  Thread safe allocation in an arena\n----------------------------------------------------------- */\n\n// claim the `blocks_inuse` bits\nstatic bool mi_arena_try_claim(mi_arena_t* arena, size_t blocks, mi_bitmap_index_t* bitmap_idx)\n{\n  size_t idx = 0; // mi_atomic_load_relaxed(&arena->search_idx);  // start from last search; ok to be relaxed as the exact start does not matter\n  if (_mi_bitmap_try_find_from_claim_across(arena->blocks_inuse, arena->field_count, idx, blocks, bitmap_idx)) {\n    mi_atomic_store_relaxed(&arena->search_idx, mi_bitmap_index_field(*bitmap_idx));  // start search from found location next time around\n    return true;\n  };\n  return false;\n}\n\n\n/* -----------------------------------------------------------\n  Arena Allocation\n----------------------------------------------------------- */\n\nstatic mi_decl_noinline void* mi_arena_try_alloc_at(mi_arena_t* arena, size_t arena_index, size_t needed_bcount,\n                                                    bool commit, mi_memid_t* memid)\n{\n  MI_UNUSED(arena_index);\n  mi_assert_internal(mi_arena_id_index(arena->id) == arena_index);\n\n  mi_bitmap_index_t bitmap_index;\n  if (!mi_arena_try_claim(arena, needed_bcount, &bitmap_index)) return NULL;\n\n  // claimed it!\n  void* p = mi_arena_block_start(arena, bitmap_index);\n  *memid = mi_memid_create_arena(arena->id, arena->exclusive, bitmap_index);\n  memid->is_pinned = arena->memid.is_pinned;\n\n  // none of the claimed blocks should be scheduled for a decommit\n  if (arena->blocks_purge != NULL) {\n    // this is thread safe as a potential purge only decommits parts that are not yet claimed as used (in `blocks_inuse`).\n    _mi_bitmap_unclaim_across(arena->blocks_purge, arena->field_count, needed_bcount, bitmap_index);\n  }\n\n  // set the dirty bits (todo: no need for an atomic op here?)\n  if (arena->memid.initially_zero && arena->blocks_dirty != NULL) {\n    memid->initially_zero = _mi_bitmap_claim_across(arena->blocks_dirty, arena->field_count, needed_bcount, bitmap_index, NULL, NULL);\n  }\n\n  // set commit state\n  if (arena->blocks_committed == NULL) {\n    // always committed\n    memid->initially_committed = true;\n  }\n  else if (commit) {\n    // commit requested, but the range may not be committed as a whole: ensure it is committed now\n    memid->initially_committed = true;\n    const size_t commit_size = mi_arena_block_size(needed_bcount);      \n    bool any_uncommitted;\n    size_t already_committed = 0;\n    _mi_bitmap_claim_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &any_uncommitted, &already_committed);\n    if (any_uncommitted) {\n      mi_assert_internal(already_committed < needed_bcount);\n      const size_t stat_commit_size = commit_size - mi_arena_block_size(already_committed);\n      bool commit_zero = false;\n      if (!_mi_os_commit_ex(p, commit_size, &commit_zero, stat_commit_size)) {\n        // set all as uncommitted on commit failure\n        _mi_bitmap_unclaim_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index);\n        memid->initially_committed = false;\n      }\n      else {\n        if (commit_zero) { memid->initially_zero = true; }\n      }\n    }\n    else {\n      // all are already committed: signal that we are reusing memory in case it was purged before\n      _mi_os_reuse( p, commit_size );\n    }\n  }\n  else {\n    // no need to commit, but check if already fully committed\n    size_t already_committed = 0;\n    memid->initially_committed = _mi_bitmap_is_claimed_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &already_committed);\n    if (!memid->initially_committed && already_committed > 0) {\n      // partially committed: as it will be committed at some time, adjust the stats and pretend the range is fully uncommitted.\n      mi_assert_internal(already_committed < needed_bcount);\n      _mi_stat_decrease(&_mi_stats_main.committed, mi_arena_block_size(already_committed));\n      _mi_bitmap_unclaim_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index);\n    }\n  }\n\n  return p;\n}\n\n// allocate in a specific arena\nstatic void* mi_arena_try_alloc_at_id(mi_arena_id_t arena_id, bool match_numa_node, int numa_node, size_t size, size_t alignment,\n                                       bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid )\n{\n  MI_UNUSED_RELEASE(alignment);\n  mi_assert(alignment <= MI_SEGMENT_ALIGN);\n  const size_t bcount = mi_block_count_of_size(size);\n  const size_t arena_index = mi_arena_id_index(arena_id);\n  mi_assert_internal(arena_index < mi_atomic_load_relaxed(&mi_arena_count));\n  mi_assert_internal(size <= mi_arena_block_size(bcount));\n\n  // Check arena suitability\n  mi_arena_t* arena = mi_arena_from_index(arena_index);\n  if (arena == NULL) return NULL;\n  if (!allow_large && arena->is_large) return NULL;\n  if (!mi_arena_id_is_suitable(arena->id, arena->exclusive, req_arena_id)) return NULL;\n  if (req_arena_id == _mi_arena_id_none()) { // in not specific, check numa affinity\n    const bool numa_suitable = (numa_node < 0 || arena->numa_node < 0 || arena->numa_node == numa_node);\n    if (match_numa_node) { if (!numa_suitable) return NULL; }\n                    else { if (numa_suitable) return NULL; }\n  }\n\n  // try to allocate\n  void* p = mi_arena_try_alloc_at(arena, arena_index, bcount, commit, memid);\n  mi_assert_internal(p == NULL || _mi_is_aligned(p, alignment));\n  return p;\n}\n\n\n// allocate from an arena with fallback to the OS\nstatic mi_decl_noinline void* mi_arena_try_alloc(int numa_node, size_t size, size_t alignment,\n                                                  bool commit, bool allow_large,\n                                                  mi_arena_id_t req_arena_id, mi_memid_t* memid )\n{\n  MI_UNUSED(alignment);\n  mi_assert_internal(alignment <= MI_SEGMENT_ALIGN);\n  const size_t max_arena = mi_atomic_load_relaxed(&mi_arena_count);\n  if mi_likely(max_arena == 0) return NULL;\n\n  if (req_arena_id != _mi_arena_id_none()) {\n    // try a specific arena if requested\n    if (mi_arena_id_index(req_arena_id) < max_arena) {\n      void* p = mi_arena_try_alloc_at_id(req_arena_id, true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid);\n      if (p != NULL) return p;\n    }\n  }\n  else {\n    // try numa affine allocation\n    for (size_t i = 0; i < max_arena; i++) {\n      void* p = mi_arena_try_alloc_at_id(mi_arena_id_create(i), true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid);\n      if (p != NULL) return p;\n    }\n\n    // try from another numa node instead..\n    if (numa_node >= 0) {  // if numa_node was < 0 (no specific affinity requested), all arena's have been tried already\n      for (size_t i = 0; i < max_arena; i++) {\n        void* p = mi_arena_try_alloc_at_id(mi_arena_id_create(i), false /* only proceed if not numa local */, numa_node, size, alignment, commit, allow_large, req_arena_id, memid);\n        if (p != NULL) return p;\n      }\n    }\n  }\n  return NULL;\n}\n\n// try to reserve a fresh arena space\nstatic bool mi_arena_reserve(size_t req_size, bool allow_large, mi_arena_id_t *arena_id)\n{\n  if (_mi_preloading()) return false;  // use OS only while pre loading\n\n  const size_t arena_count = mi_atomic_load_acquire(&mi_arena_count);\n  if (arena_count > (MI_MAX_ARENAS - 4)) return false;\n\n  size_t arena_reserve = mi_option_get_size(mi_option_arena_reserve);\n  if (arena_reserve == 0) return false;\n\n  if (!_mi_os_has_virtual_reserve()) {\n    arena_reserve = arena_reserve/4;  // be conservative if virtual reserve is not supported (for WASM for example)\n  }\n  arena_reserve = _mi_align_up(arena_reserve, MI_ARENA_BLOCK_SIZE);\n  arena_reserve = _mi_align_up(arena_reserve, MI_SEGMENT_SIZE);\n  if (arena_count >= 8 && arena_count <= 128) {\n    // scale up the arena sizes exponentially every 8 entries (128 entries get to 589TiB)\n    const size_t multiplier = (size_t)1 << _mi_clamp(arena_count/8, 0, 16 );\n    size_t reserve = 0;\n    if (!mi_mul_overflow(multiplier, arena_reserve, &reserve)) {\n      arena_reserve = reserve;\n    }\n  }\n  if (arena_reserve < req_size) return false;  // should be able to at least handle the current allocation size\n\n  // commit eagerly?\n  bool arena_commit = false;\n  if (mi_option_get(mi_option_arena_eager_commit) == 2)      { arena_commit = _mi_os_has_overcommit() || mi_option_is_enabled(mi_option_allow_large_os_pages); }\n  else if (mi_option_get(mi_option_arena_eager_commit) == 1) { arena_commit = true; }\n\n  return (mi_reserve_os_memory_ex(arena_reserve, arena_commit, allow_large, false /* exclusive? */, arena_id) == 0);\n}\n\n\nvoid* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large,\n                              mi_arena_id_t req_arena_id, mi_memid_t* memid)\n{\n  mi_assert_internal(memid != NULL);\n  mi_assert_internal(size > 0);\n  *memid = _mi_memid_none();\n\n  const int numa_node = _mi_os_numa_node(); // current numa node\n\n  // try to allocate in an arena if the alignment is small enough and the object is not too small (as for heap meta data)\n  if (!mi_option_is_enabled(mi_option_disallow_arena_alloc)) {  // is arena allocation allowed?\n    if (size >= MI_ARENA_MIN_OBJ_SIZE && alignment <= MI_SEGMENT_ALIGN && align_offset == 0)\n    {\n      void* p = mi_arena_try_alloc(numa_node, size, alignment, commit, allow_large, req_arena_id, memid);\n      if (p != NULL) return p;\n\n      // otherwise, try to first eagerly reserve a new arena\n      if (req_arena_id == _mi_arena_id_none()) {\n        mi_arena_id_t arena_id = 0;\n        if (mi_arena_reserve(size, allow_large, &arena_id)) {\n          // and try allocate in there\n          mi_assert_internal(req_arena_id == _mi_arena_id_none());\n          p = mi_arena_try_alloc_at_id(arena_id, true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid);\n          if (p != NULL) return p;\n        }\n      }\n    }\n  }\n\n  // if we cannot use OS allocation, return NULL\n  if (mi_option_is_enabled(mi_option_disallow_os_alloc) || req_arena_id != _mi_arena_id_none()) {\n    errno = ENOMEM;\n    return NULL;\n  }\n\n  // finally, fall back to the OS\n  if (align_offset > 0) {\n    return _mi_os_alloc_aligned_at_offset(size, alignment, align_offset, commit, allow_large, memid);\n  }\n  else {\n    return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid);\n  }\n}\n\nvoid* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid)\n{\n  return _mi_arena_alloc_aligned(size, MI_ARENA_BLOCK_SIZE, 0, commit, allow_large, req_arena_id, memid);\n}\n\n\nvoid* mi_arena_area(mi_arena_id_t arena_id, size_t* size) {\n  if (size != NULL) *size = 0;\n  size_t arena_index = mi_arena_id_index(arena_id);\n  if (arena_index >= MI_MAX_ARENAS) return NULL;\n  mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[arena_index]);\n  if (arena == NULL) return NULL;\n  if (size != NULL) { *size = mi_arena_block_size(arena->block_count); }\n  return arena->start;\n}\n\n\n/* -----------------------------------------------------------\n  Arena purge\n----------------------------------------------------------- */\n\nstatic long mi_arena_purge_delay(void) {\n  // <0 = no purging allowed, 0=immediate purging, >0=milli-second delay\n  return (mi_option_get(mi_option_purge_delay) * mi_option_get(mi_option_arena_purge_mult));\n}\n\n// reset or decommit in an arena and update the committed/decommit bitmaps\n// assumes we own the area (i.e. blocks_in_use is claimed by us)\nstatic void mi_arena_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks) {\n  mi_assert_internal(arena->blocks_committed != NULL);\n  mi_assert_internal(arena->blocks_purge != NULL);\n  mi_assert_internal(!arena->memid.is_pinned);\n  const size_t size = mi_arena_block_size(blocks);\n  void* const p = mi_arena_block_start(arena, bitmap_idx);\n  bool needs_recommit;\n  size_t already_committed = 0;\n  if (_mi_bitmap_is_claimed_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx, &already_committed)) {\n    // all blocks are committed, we can purge freely\n    mi_assert_internal(already_committed == blocks);\n    needs_recommit = _mi_os_purge(p, size);\n  }\n  else {\n    // some blocks are not committed -- this can happen when a partially committed block is freed\n    // in `_mi_arena_free` and it is conservatively marked as uncommitted but still scheduled for a purge\n    // we need to ensure we do not try to reset (as that may be invalid for uncommitted memory).\n    mi_assert_internal(already_committed < blocks);\n    mi_assert_internal(mi_option_is_enabled(mi_option_purge_decommits));\n    needs_recommit = _mi_os_purge_ex(p, size, false /* allow reset? */, mi_arena_block_size(already_committed));\n  }\n\n  // clear the purged blocks\n  _mi_bitmap_unclaim_across(arena->blocks_purge, arena->field_count, blocks, bitmap_idx);\n  // update committed bitmap\n  if (needs_recommit) {\n    _mi_bitmap_unclaim_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx);\n  }\n}\n\n// Schedule a purge. This is usually delayed to avoid repeated decommit/commit calls.\n// Note: assumes we (still) own the area as we may purge immediately\nstatic void mi_arena_schedule_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks) {\n  mi_assert_internal(arena->blocks_purge != NULL);\n  const long delay = mi_arena_purge_delay();\n  if (delay < 0) return;  // is purging allowed at all?\n\n  if (_mi_preloading() || delay == 0) {\n    // decommit directly\n    mi_arena_purge(arena, bitmap_idx, blocks);\n  }\n  else {\n    // schedule purge\n    const mi_msecs_t expire = _mi_clock_now() + delay;\n    mi_msecs_t expire0 = 0;\n    if (mi_atomic_casi64_strong_acq_rel(&arena->purge_expire, &expire0, expire)) {\n      // expiration was not yet set\n      // maybe set the global arenas expire as well (if it wasn't set already)\n      mi_atomic_casi64_strong_acq_rel(&mi_arenas_purge_expire, &expire0, expire);\n    }\n    else {\n      // already an expiration was set\n    }\n    _mi_bitmap_claim_across(arena->blocks_purge, arena->field_count, blocks, bitmap_idx, NULL, NULL);\n  }\n}\n\n// purge a range of blocks\n// return true if the full range was purged.\n// assumes we own the area (i.e. blocks_in_use is claimed by us)\nstatic bool mi_arena_purge_range(mi_arena_t* arena, size_t idx, size_t startidx, size_t bitlen, size_t purge) {\n  const size_t endidx = startidx + bitlen;\n  size_t bitidx = startidx;\n  bool all_purged = false;\n  while (bitidx < endidx) {\n    // count consecutive ones in the purge mask\n    size_t count = 0;\n    while (bitidx + count < endidx && (purge & ((size_t)1 << (bitidx + count))) != 0) {\n      count++;\n    }\n    if (count > 0) {\n      // found range to be purged\n      const mi_bitmap_index_t range_idx = mi_bitmap_index_create(idx, bitidx);\n      mi_arena_purge(arena, range_idx, count);\n      if (count == bitlen) {\n        all_purged = true;\n      }\n    }\n    bitidx += (count+1); // +1 to skip the zero bit (or end)\n  }\n  return all_purged;\n}\n\n// returns \n// -1 = nothing was purged \n// 0  = nothing was purged yet because have not yet reached the expire time\n// 1  = some pages in the arena were purged\nstatic int mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force)\n{\n  // check pre-conditions\n  if (arena->memid.is_pinned) return -1;\n\n  // expired yet?\n  mi_msecs_t expire = mi_atomic_loadi64_relaxed(&arena->purge_expire);\n  if (!force) {\n    if (expire == 0)  return -1;\n    if (expire > now) return 0;\n  }\n  \n  // reset expire (if not already set concurrently)\n  mi_atomic_casi64_strong_acq_rel(&arena->purge_expire, &expire, (mi_msecs_t)0);\n  _mi_stat_counter_increase(&_mi_stats_main.arena_purges, 1);\n\n  // potential purges scheduled, walk through the bitmap\n  bool any_purged = false;\n  bool full_purge = true;\n  for (size_t i = 0; i < arena->field_count; i++) {\n    size_t purge = mi_atomic_load_relaxed(&arena->blocks_purge[i]);\n    if (purge != 0) {\n      size_t bitidx = 0;\n      while (bitidx < MI_BITMAP_FIELD_BITS) {\n        // find consecutive range of ones in the purge mask\n        size_t bitlen = 0;\n        while (bitidx + bitlen < MI_BITMAP_FIELD_BITS && (purge & ((size_t)1 << (bitidx + bitlen))) != 0) {\n          bitlen++;\n        }\n        // temporarily claim the purge range as \"in-use\" to be thread-safe with allocation\n        // try to claim the longest range of corresponding in_use bits\n        const mi_bitmap_index_t bitmap_index = mi_bitmap_index_create(i, bitidx);\n        while( bitlen > 0 ) {\n          if (_mi_bitmap_try_claim(arena->blocks_inuse, arena->field_count, bitlen, bitmap_index)) {\n            break;\n          }\n          bitlen--;\n        }\n        // actual claimed bits at `in_use`\n        if (bitlen > 0) {\n          // read purge again now that we have the in_use bits\n          purge = mi_atomic_load_acquire(&arena->blocks_purge[i]);\n          if (!mi_arena_purge_range(arena, i, bitidx, bitlen, purge)) {\n            full_purge = false;\n          }\n          any_purged = true;\n          // release the claimed `in_use` bits again\n          _mi_bitmap_unclaim(arena->blocks_inuse, arena->field_count, bitlen, bitmap_index);\n        }\n        bitidx += (bitlen+1);  // +1 to skip the zero (or end)\n      } // while bitidx\n    } // purge != 0\n  }\n  // if not fully purged, make sure to purge again in the future\n  if (!full_purge) {\n    const long delay = mi_arena_purge_delay();\n    mi_msecs_t expected = 0;\n    mi_atomic_casi64_strong_acq_rel(&arena->purge_expire,&expected,_mi_clock_now() + delay);\n  }\n  return (any_purged ? 1 : -1);\n}\n\nstatic void mi_arenas_try_purge( bool force, bool visit_all )\n{\n  if (_mi_preloading() || mi_arena_purge_delay() <= 0) return;  // nothing will be scheduled\n\n  // check if any arena needs purging?\n  const mi_msecs_t now = _mi_clock_now();\n  mi_msecs_t arenas_expire = mi_atomic_loadi64_acquire(&mi_arenas_purge_expire);\n  if (!force && (arenas_expire == 0 || arenas_expire > now)) return;\n\n  const size_t max_arena = mi_atomic_load_acquire(&mi_arena_count);\n  if (max_arena == 0) return;\n\n  // allow only one thread to purge at a time\n  static mi_atomic_guard_t purge_guard;\n  mi_atomic_guard(&purge_guard)\n  {\n    // increase global expire: at most one purge per delay cycle\n    mi_atomic_storei64_release(&mi_arenas_purge_expire, now + mi_arena_purge_delay());\n    size_t max_purge_count = (visit_all ? max_arena : 2);\n    bool all_visited = true;\n    bool any_purged = false;\n    for (size_t i = 0; i < max_arena; i++) {\n      mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[i]);\n      if (arena != NULL) {\n        int purged = mi_arena_try_purge(arena, now, force);\n        if (purged >= 0) {    // purged, or not yet the expire-time reached\n          any_purged = true;\n          if (purged >= 1) {  // purged at least one page\n            if (max_purge_count <= 1) {\n              all_visited = false;\n              break;\n            }\n            max_purge_count--;\n          }\n        }\n      }\n    }\n    if (all_visited && !any_purged) {\n      // all arena's were visited and nothing needed to be purged: reset global expire\n      mi_atomic_storei64_release(&mi_arenas_purge_expire, (mi_msecs_t)0);\n    }\n  }\n}\n\n\n/* -----------------------------------------------------------\n  Arena free\n----------------------------------------------------------- */\n\nvoid _mi_arena_free(void* p, size_t size, size_t committed_size, mi_memid_t memid) {\n  mi_assert_internal(size > 0);\n  mi_assert_internal(committed_size <= size);\n  if (p==NULL) return;\n  if (size==0) return;\n  const bool all_committed = (committed_size == size);\n  const size_t decommitted_size = (committed_size <= size ? size - committed_size : 0);\n\n  // need to set all memory to undefined as some parts may still be marked as no_access (like padding etc.)\n  mi_track_mem_undefined(p,size);\n\n  if (mi_memkind_is_os(memid.memkind)) {\n    // was a direct OS allocation, pass through\n    if (!all_committed && decommitted_size > 0) {\n      // if partially committed, adjust the committed stats (as `_mi_os_free` will decrease commit by the full size)\n      _mi_stat_increase(&_mi_stats_main.committed, decommitted_size);\n    }\n    _mi_os_free(p, size, memid);\n  }\n  else if (memid.memkind == MI_MEM_ARENA) {\n    // allocated in an arena\n    size_t arena_idx;\n    size_t bitmap_idx;\n    mi_arena_memid_indices(memid, &arena_idx, &bitmap_idx);\n    mi_assert_internal(arena_idx < MI_MAX_ARENAS);\n    mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t,&mi_arenas[arena_idx]);\n    mi_assert_internal(arena != NULL);\n    const size_t blocks = mi_block_count_of_size(size);\n\n    // checks\n    if (arena == NULL) {\n      _mi_error_message(EINVAL, \"trying to free from an invalid arena: %p, size %zu, memid: 0x%zx\\n\", p, size, memid);\n      return;\n    }\n    mi_assert_internal(arena->field_count > mi_bitmap_index_field(bitmap_idx));\n    if (arena->field_count <= mi_bitmap_index_field(bitmap_idx)) {\n      _mi_error_message(EINVAL, \"trying to free from an invalid arena block: %p, size %zu, memid: 0x%zx\\n\", p, size, memid);\n      return;\n    }\n\n    // potentially decommit\n    if (arena->memid.is_pinned || arena->blocks_committed == NULL) {\n      mi_assert_internal(all_committed);\n    }\n    else {\n      mi_assert_internal(arena->blocks_committed != NULL);\n      mi_assert_internal(arena->blocks_purge != NULL);\n\n      if (!all_committed) {\n        // mark the entire range as no longer committed (so we will recommit the full range when re-using)\n        _mi_bitmap_unclaim_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx);\n        mi_track_mem_noaccess(p,size);\n        //if (committed_size > 0) {\n          // if partially committed, adjust the committed stats (is it will be recommitted when re-using)\n          // in the delayed purge, we do no longer decrease the commit if the range is not marked entirely as committed.\n          _mi_stat_decrease(&_mi_stats_main.committed, committed_size);\n        //}\n        // note: if not all committed, it may be that the purge will reset/decommit the entire range\n        // that contains already decommitted parts. Since purge consistently uses reset or decommit that\n        // works (as we should never reset decommitted parts).\n      }\n      // (delay) purge the entire range\n      mi_arena_schedule_purge(arena, bitmap_idx, blocks);\n    }\n\n    // and make it available to others again\n    bool all_inuse = _mi_bitmap_unclaim_across(arena->blocks_inuse, arena->field_count, blocks, bitmap_idx);\n    if (!all_inuse) {\n      _mi_error_message(EAGAIN, \"trying to free an already freed arena block: %p, size %zu\\n\", p, size);\n      return;\n    };\n  }\n  else {\n    // arena was none, external, or static; nothing to do\n    mi_assert_internal(memid.memkind < MI_MEM_OS);\n  }\n\n  // purge expired decommits\n  mi_arenas_try_purge(false, false);\n}\n\n// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit`\n// for dynamic libraries that are unloaded and need to release all their allocated memory.\nstatic void mi_arenas_unsafe_destroy(void) {\n  const size_t max_arena = mi_atomic_load_relaxed(&mi_arena_count);\n  size_t new_max_arena = 0;\n  for (size_t i = 0; i < max_arena; i++) {\n    mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[i]);\n    if (arena != NULL) {\n      mi_lock_done(&arena->abandoned_visit_lock);\n      if (arena->start != NULL && mi_memkind_is_os(arena->memid.memkind)) {\n        mi_atomic_store_ptr_release(mi_arena_t, &mi_arenas[i], NULL);\n        _mi_os_free(arena->start, mi_arena_size(arena), arena->memid);\n      }\n      else {\n        new_max_arena = i;\n      }\n      _mi_arena_meta_free(arena, arena->meta_memid, arena->meta_size);\n    }\n  }\n\n  // try to lower the max arena.\n  size_t expected = max_arena;\n  mi_atomic_cas_strong_acq_rel(&mi_arena_count, &expected, new_max_arena);\n}\n\n// Purge the arenas; if `force_purge` is true, amenable parts are purged even if not yet expired\nvoid _mi_arenas_collect(bool force_purge) {\n  mi_arenas_try_purge(force_purge, force_purge /* visit all? */);\n}\n\n// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit`\n// for dynamic libraries that are unloaded and need to release all their allocated memory.\nvoid _mi_arena_unsafe_destroy_all(void) {\n  mi_arenas_unsafe_destroy();\n  _mi_arenas_collect(true /* force purge */);  // purge non-owned arenas\n}\n\n// Is a pointer inside any of our arenas?\nbool _mi_arena_contains(const void* p) {\n  const size_t max_arena = mi_atomic_load_relaxed(&mi_arena_count);\n  for (size_t i = 0; i < max_arena; i++) {\n    mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t, &mi_arenas[i]);\n    if (arena != NULL && arena->start <= (const uint8_t*)p && arena->start + mi_arena_block_size(arena->block_count) > (const uint8_t*)p) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/* -----------------------------------------------------------\n  Add an arena.\n----------------------------------------------------------- */\n\nstatic bool mi_arena_add(mi_arena_t* arena, mi_arena_id_t* arena_id, mi_stats_t* stats) {\n  mi_assert_internal(arena != NULL);\n  mi_assert_internal((uintptr_t)mi_atomic_load_ptr_relaxed(uint8_t,&arena->start) % MI_SEGMENT_ALIGN == 0);\n  mi_assert_internal(arena->block_count > 0);\n  if (arena_id != NULL) { *arena_id = -1; }\n\n  size_t i = mi_atomic_load_relaxed(&mi_arena_count);\n  while (i < MI_MAX_ARENAS) {\n    if (mi_atomic_cas_strong_acq_rel(&mi_arena_count, &i, i+1)) {\n      _mi_stat_counter_increase(&stats->arena_count, 1);\n      arena->id = mi_arena_id_create(i);\n      mi_atomic_store_ptr_release(mi_arena_t, &mi_arenas[i], arena);\n      if (arena_id != NULL) { *arena_id = arena->id; }\n      return true;\n    }\n  }\n\n  return false;\n}\n\nstatic bool mi_manage_os_memory_ex2(void* start, size_t size, bool is_large, int numa_node, bool exclusive, mi_memid_t memid, mi_arena_id_t* arena_id) mi_attr_noexcept\n{\n  if (arena_id != NULL) *arena_id = _mi_arena_id_none();\n  if (size < MI_ARENA_BLOCK_SIZE) {\n    _mi_warning_message(\"the arena size is too small (memory at %p with size %zu)\\n\", start, size);\n    return false;\n  }\n  if (is_large) {\n    mi_assert_internal(memid.initially_committed && memid.is_pinned);\n  }\n  if (!_mi_is_aligned(start, MI_SEGMENT_ALIGN)) {\n    void* const aligned_start = _mi_align_up_ptr(start, MI_SEGMENT_ALIGN);\n    const size_t diff = (uint8_t*)aligned_start - (uint8_t*)start;\n    if (diff >= size || (size - diff) < MI_ARENA_BLOCK_SIZE) {\n      _mi_warning_message(\"after alignment, the size of the arena becomes too small (memory at %p with size %zu)\\n\", start, size);\n      return false;\n    }\n    start = aligned_start;\n    size = size - diff;\n  }\n\n  const size_t bcount = size / MI_ARENA_BLOCK_SIZE;\n  const size_t fields = _mi_divide_up(bcount, MI_BITMAP_FIELD_BITS);\n  const size_t bitmaps = (memid.is_pinned ? 3 : 5);\n  const size_t asize  = sizeof(mi_arena_t) + (bitmaps*fields*sizeof(mi_bitmap_field_t));\n  mi_memid_t meta_memid;\n  mi_arena_t* arena   = (mi_arena_t*)_mi_arena_meta_zalloc(asize, &meta_memid);\n  if (arena == NULL) return false;\n\n  // already zero'd due to zalloc\n  // _mi_memzero(arena, asize);\n  arena->id = _mi_arena_id_none();\n  arena->memid = memid;\n  arena->exclusive = exclusive;\n  arena->meta_size = asize;\n  arena->meta_memid = meta_memid;\n  arena->block_count = bcount;\n  arena->field_count = fields;\n  arena->start = (uint8_t*)start;\n  arena->numa_node    = numa_node; // TODO: or get the current numa node if -1? (now it allows anyone to allocate on -1)\n  arena->is_large     = is_large;\n  arena->purge_expire = 0;\n  arena->search_idx   = 0;\n  mi_lock_init(&arena->abandoned_visit_lock);\n  // consecutive bitmaps\n  arena->blocks_dirty     = &arena->blocks_inuse[fields];     // just after inuse bitmap\n  arena->blocks_abandoned = &arena->blocks_inuse[2 * fields]; // just after dirty bitmap\n  arena->blocks_committed = (arena->memid.is_pinned ? NULL : &arena->blocks_inuse[3*fields]); // just after abandoned bitmap\n  arena->blocks_purge     = (arena->memid.is_pinned ? NULL : &arena->blocks_inuse[4*fields]); // just after committed bitmap\n  // initialize committed bitmap?\n  if (arena->blocks_committed != NULL && arena->memid.initially_committed) {\n    memset((void*)arena->blocks_committed, 0xFF, fields*sizeof(mi_bitmap_field_t)); // cast to void* to avoid atomic warning\n  }\n\n  // and claim leftover blocks if needed (so we never allocate there)\n  ptrdiff_t post = (fields * MI_BITMAP_FIELD_BITS) - bcount;\n  mi_assert_internal(post >= 0);\n  if (post > 0) {\n    // don't use leftover bits at the end\n    mi_bitmap_index_t postidx = mi_bitmap_index_create(fields - 1, MI_BITMAP_FIELD_BITS - post);\n    _mi_bitmap_claim(arena->blocks_inuse, fields, post, postidx, NULL);\n  }\n  return mi_arena_add(arena, arena_id, &_mi_stats_main);\n\n}\n\nbool mi_manage_os_memory_ex(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept {\n  mi_memid_t memid = _mi_memid_create(MI_MEM_EXTERNAL);\n  memid.initially_committed = is_committed;\n  memid.initially_zero = is_zero;\n  memid.is_pinned = is_large;\n  return mi_manage_os_memory_ex2(start,size,is_large,numa_node,exclusive,memid, arena_id);\n}\n\n// Reserve a range of regular OS memory\nint mi_reserve_os_memory_ex(size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept {\n  if (arena_id != NULL) *arena_id = _mi_arena_id_none();\n  size = _mi_align_up(size, MI_ARENA_BLOCK_SIZE); // at least one block\n  mi_memid_t memid;\n  void* start = _mi_os_alloc_aligned(size, MI_SEGMENT_ALIGN, commit, allow_large, &memid);\n  if (start == NULL) return ENOMEM;\n  const bool is_large = memid.is_pinned; // todo: use separate is_large field?\n  if (!mi_manage_os_memory_ex2(start, size, is_large, -1 /* numa node */, exclusive, memid, arena_id)) {\n    _mi_os_free_ex(start, size, commit, memid);\n    _mi_verbose_message(\"failed to reserve %zu KiB memory\\n\", _mi_divide_up(size, 1024));\n    return ENOMEM;\n  }\n  _mi_verbose_message(\"reserved %zu KiB memory%s\\n\", _mi_divide_up(size, 1024), is_large ? \" (in large os pages)\" : \"\");\n  return 0;\n}\n\n\n// Manage a range of regular OS memory\nbool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept {\n  return mi_manage_os_memory_ex(start, size, is_committed, is_large, is_zero, numa_node, false /* exclusive? */, NULL);\n}\n\n// Reserve a range of regular OS memory\nint mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept {\n  return mi_reserve_os_memory_ex(size, commit, allow_large, false, NULL);\n}\n\n\n/* -----------------------------------------------------------\n  Debugging\n----------------------------------------------------------- */\n\nstatic size_t mi_debug_show_bitmap(const char* prefix, const char* header, size_t block_count, mi_bitmap_field_t* fields, size_t field_count ) {\n  _mi_message(\"%s%s:\\n\", prefix, header);\n  size_t bcount = 0;\n  size_t inuse_count = 0;\n  for (size_t i = 0; i < field_count; i++) {\n    char buf[MI_BITMAP_FIELD_BITS + 1];\n    uintptr_t field = mi_atomic_load_relaxed(&fields[i]);\n    for (size_t bit = 0; bit < MI_BITMAP_FIELD_BITS; bit++, bcount++) {\n      if (bcount < block_count) {\n        bool inuse = ((((uintptr_t)1 << bit) & field) != 0);\n        if (inuse) inuse_count++;\n        buf[bit] = (inuse ? 'x' : '.');\n      }\n      else {\n        buf[bit] = ' ';\n      }\n    }\n    buf[MI_BITMAP_FIELD_BITS] = 0;\n    _mi_message(\"%s  %s\\n\", prefix, buf);\n  }\n  _mi_message(\"%s  total ('x'): %zu\\n\", prefix, inuse_count);\n  return inuse_count;\n}\n\nvoid mi_debug_show_arenas(void) mi_attr_noexcept {\n  const bool show_inuse = true;\n  size_t max_arenas = mi_atomic_load_relaxed(&mi_arena_count);\n  size_t inuse_total = 0;\n  //size_t abandoned_total = 0;\n  //size_t purge_total = 0;\n  for (size_t i = 0; i < max_arenas; i++) {\n    mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t, &mi_arenas[i]);\n    if (arena == NULL) break;\n    _mi_message(\"arena %zu: %zu blocks of size %zuMiB (in %zu fields) %s\\n\", i, arena->block_count, (size_t)(MI_ARENA_BLOCK_SIZE / MI_MiB), arena->field_count, (arena->memid.is_pinned ? \", pinned\" : \"\"));\n    if (show_inuse) {\n      inuse_total += mi_debug_show_bitmap(\"  \", \"inuse blocks\", arena->block_count, arena->blocks_inuse, arena->field_count);\n    }\n    if (arena->blocks_committed != NULL) {\n      mi_debug_show_bitmap(\"  \", \"committed blocks\", arena->block_count, arena->blocks_committed, arena->field_count);\n    }\n    //if (show_abandoned) {\n    //  abandoned_total += mi_debug_show_bitmap(\"  \", \"abandoned blocks\", arena->block_count, arena->blocks_abandoned, arena->field_count);\n    //}\n    //if (show_purge && arena->blocks_purge != NULL) {\n    //  purge_total += mi_debug_show_bitmap(\"  \", \"purgeable blocks\", arena->block_count, arena->blocks_purge, arena->field_count);\n    //}\n  }\n  if (show_inuse)     _mi_message(\"total inuse blocks    : %zu\\n\", inuse_total);\n  //if (show_abandoned) _mi_message(\"total abandoned blocks: %zu\\n\", abandoned_total);\n  //if (show_purge)     _mi_message(\"total purgeable blocks: %zu\\n\", purge_total);\n}\n\n\nvoid mi_arenas_print(void) mi_attr_noexcept {\n  mi_debug_show_arenas();\n}\n\n\n/* -----------------------------------------------------------\n  Reserve a huge page arena.\n----------------------------------------------------------- */\n// reserve at a specific numa node\nint mi_reserve_huge_os_pages_at_ex(size_t pages, int numa_node, size_t timeout_msecs, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept {\n  if (arena_id != NULL) *arena_id = -1;\n  if (pages==0) return 0;\n  if (numa_node < -1) numa_node = -1;\n  if (numa_node >= 0) numa_node = numa_node % _mi_os_numa_node_count();\n  size_t hsize = 0;\n  size_t pages_reserved = 0;\n  mi_memid_t memid;\n  void* p = _mi_os_alloc_huge_os_pages(pages, numa_node, timeout_msecs, &pages_reserved, &hsize, &memid);\n  if (p==NULL || pages_reserved==0) {\n    _mi_warning_message(\"failed to reserve %zu GiB huge pages\\n\", pages);\n    return ENOMEM;\n  }\n  _mi_verbose_message(\"numa node %i: reserved %zu GiB huge pages (of the %zu GiB requested)\\n\", numa_node, pages_reserved, pages);\n\n  if (!mi_manage_os_memory_ex2(p, hsize, true, numa_node, exclusive, memid, arena_id)) {\n    _mi_os_free(p, hsize, memid);\n    return ENOMEM;\n  }\n  return 0;\n}\n\nint mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept {\n  return mi_reserve_huge_os_pages_at_ex(pages, numa_node, timeout_msecs, false, NULL);\n}\n\n// reserve huge pages evenly among the given number of numa nodes (or use the available ones as detected)\nint mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept {\n  if (pages == 0) return 0;\n\n  // pages per numa node\n  int numa_count = (numa_nodes > 0 && numa_nodes <= INT_MAX ? (int)numa_nodes : _mi_os_numa_node_count());\n  if (numa_count == 0) numa_count = 1;\n  const size_t pages_per = pages / numa_count;\n  const size_t pages_mod = pages % numa_count;\n  const size_t timeout_per = (timeout_msecs==0 ? 0 : (timeout_msecs / numa_count) + 50);\n\n  // reserve evenly among numa nodes\n  for (int numa_node = 0; numa_node < numa_count && pages > 0; numa_node++) {\n    size_t node_pages = pages_per;  // can be 0\n    if ((size_t)numa_node < pages_mod) node_pages++;\n    int err = mi_reserve_huge_os_pages_at(node_pages, numa_node, timeout_per);\n    if (err) return err;\n    if (pages < node_pages) {\n      pages = 0;\n    }\n    else {\n      pages -= node_pages;\n    }\n  }\n\n  return 0;\n}\n\nint mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept {\n  MI_UNUSED(max_secs);\n  _mi_warning_message(\"mi_reserve_huge_os_pages is deprecated: use mi_reserve_huge_os_pages_interleave/at instead\\n\");\n  if (pages_reserved != NULL) *pages_reserved = 0;\n  int err = mi_reserve_huge_os_pages_interleave(pages, 0, (size_t)(max_secs * 1000.0));\n  if (err==0 && pages_reserved!=NULL) *pages_reserved = pages;\n  return err;\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/bitmap.c",
      "sha256": "264bab5a13790372f12cdef044b2b7d3485da779a33eaf3514ccbc7fb08245ba",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2023 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* ----------------------------------------------------------------------------\nConcurrent bitmap that can set/reset sequences of bits atomically,\nrepresented as an array of fields where each field is a machine word (`size_t`)\n\nThere are two api's; the standard one cannot have sequences that cross\nbetween the bitmap fields (and a sequence must be <= MI_BITMAP_FIELD_BITS).\n\nThe `_across` postfixed functions do allow sequences that can cross over\nbetween the fields. (This is used in arena allocation)\n---------------------------------------------------------------------------- */\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"bitmap.h\"\n\n/* -----------------------------------------------------------\n  Bitmap definition\n----------------------------------------------------------- */\n\n// The bit mask for a given number of blocks at a specified bit index.\nstatic inline size_t mi_bitmap_mask_(size_t count, size_t bitidx) {\n  mi_assert_internal(count + bitidx <= MI_BITMAP_FIELD_BITS);\n  mi_assert_internal(count > 0);\n  if (count >= MI_BITMAP_FIELD_BITS) return MI_BITMAP_FIELD_FULL;\n  if (count == 0) return 0;\n  return ((((size_t)1 << count) - 1) << bitidx);\n}\n\n\n/* -----------------------------------------------------------\n  Claim a bit sequence atomically\n----------------------------------------------------------- */\n\n// Try to atomically claim a sequence of `count` bits in a single\n// field at `idx` in `bitmap`. Returns `true` on success.\ninline bool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx)\n{\n  mi_assert_internal(bitmap_idx != NULL);\n  mi_assert_internal(count <= MI_BITMAP_FIELD_BITS);\n  mi_assert_internal(count > 0);\n  mi_bitmap_field_t* field = &bitmap[idx];\n  size_t map  = mi_atomic_load_relaxed(field);\n  if (map==MI_BITMAP_FIELD_FULL) return false; // short cut\n\n  // search for 0-bit sequence of length count\n  const size_t mask = mi_bitmap_mask_(count, 0);\n  const size_t bitidx_max = MI_BITMAP_FIELD_BITS - count;\n\n#ifdef MI_HAVE_FAST_BITSCAN\n  size_t bitidx = mi_ctz(~map);    // quickly find the first zero bit if possible\n#else\n  size_t bitidx = 0;               // otherwise start at 0\n#endif\n  size_t m = (mask << bitidx);     // invariant: m == mask shifted by bitidx\n\n  // scan linearly for a free range of zero bits\n  while (bitidx <= bitidx_max) {\n    const size_t mapm = (map & m);\n    if (mapm == 0) {  // are the mask bits free at bitidx?\n      mi_assert_internal((m >> bitidx) == mask); // no overflow?\n      const size_t newmap = (map | m);\n      mi_assert_internal((newmap^map) >> bitidx == mask);\n      if (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)) {  // TODO: use weak cas here?\n        // no success, another thread claimed concurrently.. keep going (with updated `map`)\n        continue;\n      }\n      else {\n        // success, we claimed the bits!\n        *bitmap_idx = mi_bitmap_index_create(idx, bitidx);\n        return true;\n      }\n    }\n    else {\n      // on to the next bit range\n#ifdef MI_HAVE_FAST_BITSCAN\n      mi_assert_internal(mapm != 0);\n      const size_t shift = (count == 1 ? 1 : (MI_SIZE_BITS - mi_clz(mapm) - bitidx));\n      mi_assert_internal(shift > 0 && shift <= count);\n#else\n      const size_t shift = 1;\n#endif\n      bitidx += shift;\n      m <<= shift;\n    }\n  }\n  // no bits found\n  return false;\n}\n\n// Find `count` bits of 0 and set them to 1 atomically; returns `true` on success.\n// Starts at idx, and wraps around to search in all `bitmap_fields` fields.\n// `count` can be at most MI_BITMAP_FIELD_BITS and will never cross fields.\nbool _mi_bitmap_try_find_from_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) {\n  size_t idx = start_field_idx;\n  for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) {\n    if (idx >= bitmap_fields) { idx = 0; } // wrap\n    if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n// Like _mi_bitmap_try_find_from_claim but with an extra predicate that must be fullfilled\nbool _mi_bitmap_try_find_from_claim_pred(mi_bitmap_t bitmap, const size_t bitmap_fields, \n            const size_t start_field_idx, const size_t count, \n            mi_bitmap_pred_fun_t pred_fun, void* pred_arg,            \n            mi_bitmap_index_t* bitmap_idx) {\n  size_t idx = start_field_idx;\n  for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) {\n    if (idx >= bitmap_fields) idx = 0; // wrap\n    if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) {\n      if (pred_fun == NULL || pred_fun(*bitmap_idx, pred_arg)) { \n        return true;\n      }\n      // predicate returned false, unclaim and look further\n      _mi_bitmap_unclaim(bitmap, bitmap_fields, count, *bitmap_idx);\n    }\n  }\n  return false;\n}\n\n// Set `count` bits at `bitmap_idx` to 0 atomically\n// Returns `true` if all `count` bits were 1 previously.\nbool _mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {\n  const size_t idx = mi_bitmap_index_field(bitmap_idx);\n  const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);\n  const size_t mask = mi_bitmap_mask_(count, bitidx);\n  mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);\n  // mi_assert_internal((bitmap[idx] & mask) == mask);\n  const size_t prev = mi_atomic_and_acq_rel(&bitmap[idx], ~mask);\n  return ((prev & mask) == mask);\n}\n\n\n// Set `count` bits at `bitmap_idx` to 1 atomically\n// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.\nbool _mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero) {\n  const size_t idx = mi_bitmap_index_field(bitmap_idx);\n  const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);\n  const size_t mask = mi_bitmap_mask_(count, bitidx);\n  mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);\n  //mi_assert_internal(any_zero != NULL || (bitmap[idx] & mask) == 0);\n  size_t prev = mi_atomic_or_acq_rel(&bitmap[idx], mask);\n  if (any_zero != NULL) { *any_zero = ((prev & mask) != mask); }\n  return ((prev & mask) == 0);\n}\n\n// Returns `true` if all `count` bits were 1. `any_ones` is `true` if there was at least one bit set to one.\nstatic bool mi_bitmap_is_claimedx(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_ones) {\n  const size_t idx = mi_bitmap_index_field(bitmap_idx);\n  const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);\n  const size_t mask = mi_bitmap_mask_(count, bitidx);\n  mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);\n  const size_t field = mi_atomic_load_relaxed(&bitmap[idx]);\n  if (any_ones != NULL) { *any_ones = ((field & mask) != 0); }\n  return ((field & mask) == mask);\n}\n\n// Try to set `count` bits at `bitmap_idx` from 0 to 1 atomically.\n// Returns `true` if successful when all previous `count` bits were 0.\nbool _mi_bitmap_try_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {\n  const size_t idx = mi_bitmap_index_field(bitmap_idx);\n  const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);\n  const size_t mask = mi_bitmap_mask_(count, bitidx);\n  mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);\n  size_t expected = mi_atomic_load_relaxed(&bitmap[idx]);\n  do  {\n    if ((expected & mask) != 0) return false;\n  }\n  while (!mi_atomic_cas_strong_acq_rel(&bitmap[idx], &expected, expected | mask));\n  mi_assert_internal((expected & mask) == 0);\n  return true;\n}\n\n\nbool _mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {\n  return mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, NULL);\n}\n\nbool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {\n  bool any_ones;\n  mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, &any_ones);\n  return any_ones;\n}\n\n\n//--------------------------------------------------------------------------\n// the `_across` functions work on bitmaps where sequences can cross over\n// between the fields. This is used in arena allocation\n//--------------------------------------------------------------------------\n\n// Try to atomically claim a sequence of `count` bits starting from the field\n// at `idx` in `bitmap` and crossing into subsequent fields. Returns `true` on success.\n// Only needs to consider crossing into the next fields (see `mi_bitmap_try_find_from_claim_across`)\nstatic bool mi_bitmap_try_find_claim_field_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t idx, const size_t count, const size_t retries, mi_bitmap_index_t* bitmap_idx)\n{\n  mi_assert_internal(bitmap_idx != NULL);\n\n  // check initial trailing zeros\n  mi_bitmap_field_t* field = &bitmap[idx];\n  size_t map = mi_atomic_load_relaxed(field);\n  const size_t initial = mi_clz(map);  // count of initial zeros starting at idx\n  mi_assert_internal(initial <= MI_BITMAP_FIELD_BITS);\n  if (initial == 0)     return false;\n  if (initial >= count) return _mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx);    // no need to cross fields (this case won't happen for us)\n  if (_mi_divide_up(count - initial, MI_BITMAP_FIELD_BITS) >= (bitmap_fields - idx)) return false; // not enough entries\n\n  // scan ahead\n  size_t found = initial;\n  size_t mask = 0;     // mask bits for the final field\n  while(found < count) {\n    field++;\n    map = mi_atomic_load_relaxed(field);\n    const size_t mask_bits = (found + MI_BITMAP_FIELD_BITS <= count ? MI_BITMAP_FIELD_BITS : (count - found));\n    mi_assert_internal(mask_bits > 0 && mask_bits <= MI_BITMAP_FIELD_BITS);\n    mask = mi_bitmap_mask_(mask_bits, 0);\n    if ((map & mask) != 0) return false;  // some part is already claimed\n    found += mask_bits;\n  }\n  mi_assert_internal(field < &bitmap[bitmap_fields]);\n\n  // we found a range of contiguous zeros up to the final field; mask contains mask in the final field\n  // now try to claim the range atomically\n  mi_bitmap_field_t* const final_field = field;\n  const size_t final_mask = mask;\n  mi_bitmap_field_t* const initial_field = &bitmap[idx];\n  const size_t initial_idx = MI_BITMAP_FIELD_BITS - initial;\n  const size_t initial_mask = mi_bitmap_mask_(initial, initial_idx);\n\n  // initial field\n  size_t newmap;\n  field = initial_field;\n  map = mi_atomic_load_relaxed(field);\n  do {\n    newmap = (map | initial_mask);\n    if ((map & initial_mask) != 0) { goto rollback; };\n  } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));\n\n  // intermediate fields\n  while (++field < final_field) {\n    newmap = MI_BITMAP_FIELD_FULL;\n    map = 0;\n    if (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)) { goto rollback; }\n  }\n\n  // final field\n  mi_assert_internal(field == final_field);\n  map = mi_atomic_load_relaxed(field);\n  do {\n    newmap = (map | final_mask);\n    if ((map & final_mask) != 0) { goto rollback; }\n  } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));\n\n  // claimed!\n  *bitmap_idx = mi_bitmap_index_create(idx, initial_idx);\n  return true;\n\nrollback:\n  // roll back intermediate fields\n  // (we just failed to claim `field` so decrement first)\n  while (--field > initial_field) {\n    newmap = 0;\n    map = MI_BITMAP_FIELD_FULL;\n    mi_assert_internal(mi_atomic_load_relaxed(field) == map);\n    mi_atomic_store_release(field, newmap);\n  }\n  if (field == initial_field) {               // (if we failed on the initial field, `field + 1 == initial_field`)\n    map = mi_atomic_load_relaxed(field);\n    do {\n      mi_assert_internal((map & initial_mask) == initial_mask);\n      newmap = (map & ~initial_mask);\n    } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));\n  }\n  mi_stat_counter_increase(_mi_stats_main.arena_rollback_count,1);\n  // retry? (we make a recursive call instead of goto to be able to use const declarations)\n  if (retries <= 2) {\n    return mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, retries+1, bitmap_idx);\n  }\n  else {\n    return false;\n  }\n}\n\n\n// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success.\n// Starts at idx, and wraps around to search in all `bitmap_fields` fields.\nbool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) {\n  mi_assert_internal(count > 0);\n  if (count <= 2) {\n    // we don't bother with crossover fields for small counts\n    return _mi_bitmap_try_find_from_claim(bitmap, bitmap_fields, start_field_idx, count, bitmap_idx);\n  }\n\n  // visit the fields\n  size_t idx = start_field_idx;\n  for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) {\n    if (idx >= bitmap_fields) { idx = 0; } // wrap\n    // first try to claim inside a field\n    if (count <= MI_BITMAP_FIELD_BITS) {\n      if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) {\n        return true;\n      }\n    }\n    // if that fails, then try to claim across fields\n    if (mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, 0, bitmap_idx)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n// Helper for masks across fields; returns the mid count, post_mask may be 0\nstatic size_t mi_bitmap_mask_across(mi_bitmap_index_t bitmap_idx, size_t bitmap_fields, size_t count, size_t* pre_mask, size_t* mid_mask, size_t* post_mask) {\n  MI_UNUSED(bitmap_fields);\n  const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);\n  if mi_likely(bitidx + count <= MI_BITMAP_FIELD_BITS) {\n    *pre_mask = mi_bitmap_mask_(count, bitidx);\n    *mid_mask = 0;\n    *post_mask = 0;\n    mi_assert_internal(mi_bitmap_index_field(bitmap_idx) < bitmap_fields);\n    return 0;\n  }\n  else {\n    const size_t pre_bits = MI_BITMAP_FIELD_BITS - bitidx;\n    mi_assert_internal(pre_bits < count);\n    *pre_mask = mi_bitmap_mask_(pre_bits, bitidx);\n    count -= pre_bits;\n    const size_t mid_count = (count / MI_BITMAP_FIELD_BITS);\n    *mid_mask = MI_BITMAP_FIELD_FULL;\n    count %= MI_BITMAP_FIELD_BITS;\n    *post_mask = (count==0 ? 0 : mi_bitmap_mask_(count, 0));\n    mi_assert_internal(mi_bitmap_index_field(bitmap_idx) + mid_count + (count==0 ? 0 : 1) < bitmap_fields);\n    return mid_count;\n  }\n}\n\n// Set `count` bits at `bitmap_idx` to 0 atomically\n// Returns `true` if all `count` bits were 1 previously.\nbool _mi_bitmap_unclaim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {\n  size_t idx = mi_bitmap_index_field(bitmap_idx);\n  size_t pre_mask;\n  size_t mid_mask;\n  size_t post_mask;\n  size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask);\n  bool all_one = true;\n  mi_bitmap_field_t* field = &bitmap[idx];\n  size_t prev = mi_atomic_and_acq_rel(field++, ~pre_mask);   // clear first part\n  if ((prev & pre_mask) != pre_mask) all_one = false;\n  while(mid_count-- > 0) {\n    prev = mi_atomic_and_acq_rel(field++, ~mid_mask);        // clear mid part\n    if ((prev & mid_mask) != mid_mask) all_one = false;\n  }\n  if (post_mask!=0) {\n    prev = mi_atomic_and_acq_rel(field, ~post_mask);         // clear end part\n    if ((prev & post_mask) != post_mask) all_one = false;\n  }\n  return all_one;\n}\n\n// Set `count` bits at `bitmap_idx` to 1 atomically\n// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.\nbool _mi_bitmap_claim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_zero, size_t* already_set) {\n  size_t idx = mi_bitmap_index_field(bitmap_idx);\n  size_t pre_mask;\n  size_t mid_mask;\n  size_t post_mask;\n  size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask);\n  bool all_zero = true;\n  bool any_zero = false;\n  size_t one_count = 0;\n  _Atomic(size_t)*field = &bitmap[idx];\n  size_t prev = mi_atomic_or_acq_rel(field++, pre_mask);\n  if ((prev & pre_mask) != 0) { all_zero = false; one_count += mi_popcount(prev & pre_mask); }\n  if ((prev & pre_mask) != pre_mask) any_zero = true;\n  while (mid_count-- > 0) {\n    prev = mi_atomic_or_acq_rel(field++, mid_mask);\n    if ((prev & mid_mask) != 0) { all_zero = false; one_count += mi_popcount(prev & mid_mask); }\n    if ((prev & mid_mask) != mid_mask) any_zero = true;\n  }\n  if (post_mask!=0) {\n    prev = mi_atomic_or_acq_rel(field, post_mask);\n    if ((prev & post_mask) != 0) { all_zero = false; one_count += mi_popcount(prev & post_mask); }\n    if ((prev & post_mask) != post_mask) any_zero = true;\n  }\n  if (pany_zero != NULL) { *pany_zero = any_zero; }\n  if (already_set != NULL) { *already_set = one_count; };\n  mi_assert_internal(all_zero ? one_count == 0 : one_count <= count);\n  return all_zero;\n}\n\n\n// Returns `true` if all `count` bits were 1.\n// `any_ones` is `true` if there was at least one bit set to one.\nstatic bool mi_bitmap_is_claimedx_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_ones, size_t* already_set) {\n  size_t idx = mi_bitmap_index_field(bitmap_idx);\n  size_t pre_mask;\n  size_t mid_mask;\n  size_t post_mask;\n  size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask);\n  bool all_ones = true;\n  bool any_ones = false;\n  size_t one_count = 0;\n  mi_bitmap_field_t* field = &bitmap[idx];\n  size_t prev = mi_atomic_load_relaxed(field++);\n  if ((prev & pre_mask) != pre_mask) all_ones = false;\n  if ((prev & pre_mask) != 0) { any_ones = true; one_count += mi_popcount(prev & pre_mask); }\n  while (mid_count-- > 0) {\n    prev = mi_atomic_load_relaxed(field++);\n    if ((prev & mid_mask) != mid_mask) all_ones = false;\n    if ((prev & mid_mask) != 0) { any_ones = true; one_count += mi_popcount(prev & mid_mask); }\n  }\n  if (post_mask!=0) {\n    prev = mi_atomic_load_relaxed(field);\n    if ((prev & post_mask) != post_mask) all_ones = false;\n    if ((prev & post_mask) != 0) { any_ones = true; one_count += mi_popcount(prev & post_mask); }\n  }\n  if (pany_ones != NULL) { *pany_ones = any_ones; }\n  if (already_set != NULL) { *already_set = one_count; }\n  mi_assert_internal(all_ones ? one_count == count : one_count < count);\n  return all_ones;\n}\n\nbool _mi_bitmap_is_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, size_t* already_set) {\n  return mi_bitmap_is_claimedx_across(bitmap, bitmap_fields, count, bitmap_idx, NULL, already_set);\n}\n\nbool _mi_bitmap_is_any_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {\n  bool any_ones;\n  mi_bitmap_is_claimedx_across(bitmap, bitmap_fields, count, bitmap_idx, &any_ones, NULL);\n  return any_ones;\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/bitmap.h",
      "sha256": "a1c4d3d6eadfd36e0cd06abddccf54387abd6f43d8b2638cb36bd0f162d560c4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2023 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* ----------------------------------------------------------------------------\nConcurrent bitmap that can set/reset sequences of bits atomically,\nrepresented as an array of fields where each field is a machine word (`size_t`)\n\nThere are two api's; the standard one cannot have sequences that cross\nbetween the bitmap fields (and a sequence must be <= MI_BITMAP_FIELD_BITS).\n(this is used in region allocation)\n\nThe `_across` postfixed functions do allow sequences that can cross over\nbetween the fields. (This is used in arena allocation)\n---------------------------------------------------------------------------- */\n#pragma once\n#ifndef MI_BITMAP_H\n#define MI_BITMAP_H\n\n/* -----------------------------------------------------------\n  Bitmap definition\n----------------------------------------------------------- */\n\n#define MI_BITMAP_FIELD_BITS   (8*MI_SIZE_SIZE)\n#define MI_BITMAP_FIELD_FULL   (~((size_t)0))   // all bits set\n\n// An atomic bitmap of `size_t` fields\ntypedef _Atomic(size_t)  mi_bitmap_field_t;\ntypedef mi_bitmap_field_t*  mi_bitmap_t;\n\n// A bitmap index is the index of the bit in a bitmap.\ntypedef size_t mi_bitmap_index_t;\n\n// Create a bit index.\nstatic inline mi_bitmap_index_t mi_bitmap_index_create_ex(size_t idx, size_t bitidx) {\n  mi_assert_internal(bitidx <= MI_BITMAP_FIELD_BITS);\n  return (idx*MI_BITMAP_FIELD_BITS) + bitidx;\n}\nstatic inline mi_bitmap_index_t mi_bitmap_index_create(size_t idx, size_t bitidx) {\n  mi_assert_internal(bitidx < MI_BITMAP_FIELD_BITS);\n  return mi_bitmap_index_create_ex(idx,bitidx);\n}\n\n// Create a bit index.\nstatic inline mi_bitmap_index_t mi_bitmap_index_create_from_bit(size_t full_bitidx) {  \n  return mi_bitmap_index_create(full_bitidx / MI_BITMAP_FIELD_BITS, full_bitidx % MI_BITMAP_FIELD_BITS);\n}\n\n// Get the field index from a bit index.\nstatic inline size_t mi_bitmap_index_field(mi_bitmap_index_t bitmap_idx) {\n  return (bitmap_idx / MI_BITMAP_FIELD_BITS);\n}\n\n// Get the bit index in a bitmap field\nstatic inline size_t mi_bitmap_index_bit_in_field(mi_bitmap_index_t bitmap_idx) {\n  return (bitmap_idx % MI_BITMAP_FIELD_BITS);\n}\n\n// Get the full bit index\nstatic inline size_t mi_bitmap_index_bit(mi_bitmap_index_t bitmap_idx) {\n  return bitmap_idx;\n}\n\n/* -----------------------------------------------------------\n  Claim a bit sequence atomically\n----------------------------------------------------------- */\n\n// Try to atomically claim a sequence of `count` bits in a single\n// field at `idx` in `bitmap`. Returns `true` on success.\nbool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx);\n\n// Starts at idx, and wraps around to search in all `bitmap_fields` fields.\n// For now, `count` can be at most MI_BITMAP_FIELD_BITS and will never cross fields.\nbool _mi_bitmap_try_find_from_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx);\n\n// Like _mi_bitmap_try_find_from_claim but with an extra predicate that must be fullfilled\ntypedef bool (mi_cdecl *mi_bitmap_pred_fun_t)(mi_bitmap_index_t bitmap_idx, void* pred_arg);\nbool _mi_bitmap_try_find_from_claim_pred(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_pred_fun_t pred_fun, void* pred_arg, mi_bitmap_index_t* bitmap_idx);\n\n// Set `count` bits at `bitmap_idx` to 0 atomically\n// Returns `true` if all `count` bits were 1 previously.\nbool _mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);\n\n// Try to set `count` bits at `bitmap_idx` from 0 to 1 atomically. \n// Returns `true` if successful when all previous `count` bits were 0.\nbool _mi_bitmap_try_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);\n\n// Set `count` bits at `bitmap_idx` to 1 atomically\n// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.\nbool _mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero);\n\nbool _mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);\nbool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);\n\n\n//--------------------------------------------------------------------------\n// the `_across` functions work on bitmaps where sequences can cross over\n// between the fields. This is used in arena allocation\n//--------------------------------------------------------------------------\n\n// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success.\n// Starts at idx, and wraps around to search in all `bitmap_fields` fields.\nbool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx);\n\n// Set `count` bits at `bitmap_idx` to 0 atomically\n// Returns `true` if all `count` bits were 1 previously.\nbool _mi_bitmap_unclaim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);\n\n// Set `count` bits at `bitmap_idx` to 1 atomically\n// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.\nbool _mi_bitmap_claim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_zero, size_t* already_set);\n\nbool _mi_bitmap_is_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, size_t* already_set);\nbool _mi_bitmap_is_any_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);\n\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/free.c",
      "sha256": "da31e9f443f90455689f0a93db61bb2bb72fda240bdcf4c5ffd243dda52cfdf3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#if !defined(MI_IN_ALLOC_C)\n#error \"this file should be included from 'alloc.c' (so aliases can work from alloc-override)\"\n// add includes help an IDE\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"   // _mi_prim_thread_id()\n#endif\n\n// forward declarations\nstatic void   mi_check_padding(const mi_page_t* page, const mi_block_t* block);\nstatic bool   mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block);\nstatic size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block, bool was_guarded);\nstatic void   mi_stat_free(const mi_page_t* page, const mi_block_t* block);\n\n\n// ------------------------------------------------------\n// Free\n// ------------------------------------------------------\n\n// forward declaration of multi-threaded free (`_mt`) (or free in huge block if compiled with MI_HUGE_PAGE_ABANDON)\nstatic mi_decl_noinline void mi_free_block_mt(mi_page_t* page, mi_segment_t* segment, mi_block_t* block, void* p, bool was_guarded);\n\n// regular free of a (thread local) block pointer\n// fast path written carefully to prevent spilling on the stack\nstatic inline void mi_free_block_local(mi_page_t* page, mi_block_t* block, bool was_guarded, bool track_stats, bool check_full)\n{\n  MI_UNUSED(was_guarded);\n  // checks  \n  if mi_unlikely(mi_check_is_double_free(page, block)) return;\n  if (!was_guarded) { mi_check_padding(page, block); }\n  if (track_stats) { mi_stat_free(page, block); }\n  #if (MI_DEBUG>0) && !MI_TRACK_ENABLED  && !MI_TSAN\n  if (!mi_page_is_huge(page)) {   // huge page content may be already decommitted\n    memset(block, MI_DEBUG_FREED, mi_page_block_size(page));\n  }\n  #endif\n  if (track_stats) { mi_track_free_size(block, mi_page_usable_size_of(page, block, was_guarded)); } // faster then mi_usable_size as we already know the page and that p is unaligned\n\n  // actual free: push on the local free list\n  mi_block_set_next(page, block, page->local_free);\n  page->local_free = block;\n  if mi_unlikely(--page->used == 0) {\n    _mi_page_retire(page);\n  }\n  else if mi_unlikely(check_full && mi_page_is_in_full(page)) {\n    _mi_page_unfull(page);\n  }\n}\n\n// Adjust a block that was allocated aligned, to the actual start of the block in the page.\n// note: this can be called from `mi_free_generic_mt` where a non-owning thread accesses the\n// `page_start` and `block_size` fields; however these are constant and the page won't be\n// deallocated (as the block we are freeing keeps it alive) and thus safe to read concurrently.\nmi_block_t* _mi_page_ptr_unalign(const mi_page_t* page, const void* p) {\n  mi_assert_internal(page!=NULL && p!=NULL);\n\n  size_t diff = (uint8_t*)p - page->page_start;\n  size_t adjust = 0;\n  if mi_likely(page->block_size_shift != 0) {\n    adjust = diff & (((size_t)1 << page->block_size_shift) - 1);\n  }\n  else {\n    const size_t block_size = page->block_size;\n    if mi_likely(block_size != 0) {\n      adjust = diff % block_size;\n    }\n    else {\n      _mi_error_message(EFAULT, \"reading from invalid page, possibly corrupted meta-data (address=%p, page=%p)\\n\", p, page);      \n    }\n  }\n\n  return (mi_block_t*)((uintptr_t)p - adjust);\n}\n\n// forward declaration for a MI_GUARDED build\n#if MI_GUARDED\nstatic void mi_block_unguard(mi_page_t* page, mi_block_t* block, void* p); // forward declaration\nstatic inline bool mi_block_check_unguard(mi_page_t* page, mi_block_t* block, void* p) {\n  if (mi_block_ptr_is_guarded(block, p)) { \n    mi_block_unguard(page, block, p); \n    return true;\n  }\n  else {\n    return false;\n  }\n}\n#else\nstatic inline bool mi_block_check_unguard(mi_page_t* page, mi_block_t* block, void* p) {\n  MI_UNUSED(page); MI_UNUSED(block); MI_UNUSED(p);\n  return false;\n}\n#endif\n\n// free a local pointer  (page parameter comes first for better codegen)\nstatic void mi_decl_noinline mi_free_generic_local(mi_page_t* page, mi_segment_t* segment, void* p) mi_attr_noexcept {\n  MI_UNUSED(segment);\n  mi_block_t* const block = (mi_page_has_aligned(page) ? _mi_page_ptr_unalign(page, p) : (mi_block_t*)p);\n  const bool was_guarded = mi_block_check_unguard(page, block, p);\n  mi_free_block_local(page, block, was_guarded, true /* track stats */, true /* check for a full page */);\n}\n\n// free a pointer owned by another thread (page parameter comes first for better codegen)\nstatic void mi_decl_noinline mi_free_generic_mt(mi_page_t* page, mi_segment_t* segment, void* p) mi_attr_noexcept {\n  mi_block_t* const block = _mi_page_ptr_unalign(page, p); // don't check `has_aligned` flag to avoid a race (issue #865)\n  const bool was_guarded = mi_block_check_unguard(page, block, p);\n  mi_free_block_mt(page, segment, block, p, was_guarded);\n}\n\n// generic free (for runtime integration)\nvoid mi_decl_noinline _mi_free_generic(mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept {\n  if (is_local) mi_free_generic_local(page,segment,p);\n           else mi_free_generic_mt(page,segment,p);\n}\n\n// Get the segment data belonging to a pointer\n// This is just a single `and` in release mode but does further checks in debug mode\n// (and secure mode) to see if this was a valid pointer.\nstatic inline mi_segment_t* mi_checked_ptr_segment(const void* p, const char* msg)\n{\n  MI_UNUSED(msg);\n\n  #if (MI_DEBUG>0)\n  if mi_unlikely(((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0 && !mi_option_is_enabled(mi_option_guarded_precise)) {\n    _mi_error_message(EINVAL, \"%s: invalid (unaligned) pointer: %p\\n\", msg, p);\n    return NULL;\n  }\n  #endif\n\n  mi_segment_t* const segment = _mi_ptr_segment(p);\n  if mi_unlikely(segment==NULL) return segment;\n\n  #if (MI_DEBUG>0)\n  if mi_unlikely(!mi_is_in_heap_region(p)) {\n  #if (MI_INTPTR_SIZE == 8 && defined(__linux__))\n    if (((uintptr_t)p >> 40) != 0x7F) { // linux tends to align large blocks above 0x7F000000000 (issue #640)\n  #else\n    {\n  #endif\n      _mi_warning_message(\"%s: pointer might not point to a valid heap region: %p\\n\"\n        \"(this may still be a valid very large allocation (over 64MiB))\\n\", msg, p);\n      if mi_likely(_mi_ptr_cookie(segment) == segment->cookie) {\n        _mi_warning_message(\"(yes, the previous pointer %p was valid after all)\\n\", p);\n      }\n    }\n  }\n  #endif\n  #if (MI_DEBUG>0 || MI_SECURE>=3)\n  if mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie) {\n    _mi_error_message(EINVAL, \"%s: pointer does not point to a valid heap space: %p\\n\", msg, p);\n    return NULL;\n  }\n  #endif\n\n  return segment;\n}\n\n// Free a block\n// Fast path written carefully to prevent register spilling on the stack\nstatic inline void mi_free_ex(void* p, size_t* usable) mi_attr_noexcept\n{\n  mi_segment_t* const segment = mi_checked_ptr_segment(p,\"mi_free\");\n  if mi_unlikely(segment==NULL) return;\n\n  const bool is_local = (_mi_prim_thread_id() == mi_atomic_load_relaxed(&segment->thread_id));\n  mi_page_t* const page = _mi_segment_page_of(segment, p);\n  if (usable!=NULL) { *usable = mi_page_usable_block_size(page); }\n  \n  if mi_likely(is_local) {                        // thread-local free?\n    if mi_likely(page->flags.full_aligned == 0) { // and it is not a full page (full pages need to move from the full bin), nor has aligned blocks (aligned blocks need to be unaligned)\n      // thread-local, aligned, and not a full page\n      mi_block_t* const block = (mi_block_t*)p;\n      mi_free_block_local(page, block, false /* is guarded */, true /* track stats */, false /* no need to check if the page is full */);\n    }\n    else {\n      // page is full or contains (inner) aligned blocks; use generic path\n      mi_free_generic_local(page, segment, p);\n    }\n  }\n  else {\n    // not thread-local; use generic path\n    mi_free_generic_mt(page, segment, p);\n  }\n}\n\nvoid mi_free(void* p) mi_attr_noexcept {\n  mi_free_ex(p,NULL);\n}\n\nvoid mi_ufree(void* p, size_t* usable) mi_attr_noexcept {\n  mi_free_ex(p,usable);\n}\n\nvoid mi_free_small(void* p) mi_attr_noexcept {\n  mi_free(p);\n}\n\n\n// return true if successful\nbool _mi_free_delayed_block(mi_block_t* block) {\n  // get segment and page\n  mi_assert_internal(block!=NULL);\n  const mi_segment_t* const segment = _mi_ptr_segment(block);\n  mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie);\n  mi_assert_internal(_mi_thread_id() == segment->thread_id);\n  mi_page_t* const page = _mi_segment_page_of(segment, block);\n\n  // Clear the no-delayed flag so delayed freeing is used again for this page.\n  // This must be done before collecting the free lists on this page -- otherwise\n  // some blocks may end up in the page `thread_free` list with no blocks in the\n  // heap `thread_delayed_free` list which may cause the page to be never freed!\n  // (it would only be freed if we happen to scan it in `mi_page_queue_find_free_ex`)\n  if (!_mi_page_try_use_delayed_free(page, MI_USE_DELAYED_FREE, false /* dont overwrite never delayed */)) {\n    return false;\n  }\n\n  // collect all other non-local frees (move from `thread_free` to `free`) to ensure up-to-date `used` count\n  _mi_page_free_collect(page, false);\n\n  // and free the block (possibly freeing the page as well since `used` is updated)\n  mi_free_block_local(page, block, false /* is guarded */, false /* stats have already been adjusted */, true /* check for a full page */);\n  return true;\n}\n\n// ------------------------------------------------------\n// Multi-threaded Free (`_mt`)\n// ------------------------------------------------------\n\n// Push a block that is owned by another thread on its page-local thread free\n// list or it's heap delayed free list. Such blocks are later collected by\n// the owning thread in `_mi_free_delayed_block`.\nstatic void mi_decl_noinline mi_free_block_delayed_mt( mi_page_t* page, mi_block_t* block )\n{\n  // Try to put the block on either the page-local thread free list,\n  // or the heap delayed free list (if this is the first non-local free in that page)\n  mi_thread_free_t tfreex;\n  bool use_delayed;\n  mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free);\n  do {\n    use_delayed = (mi_tf_delayed(tfree) == MI_USE_DELAYED_FREE);\n    if mi_unlikely(use_delayed) {\n      // unlikely: this only happens on the first concurrent free in a page that is in the full list\n      tfreex = mi_tf_set_delayed(tfree,MI_DELAYED_FREEING);\n    }\n    else {\n      // usual: directly add to page thread_free list\n      mi_block_set_next(page, block, mi_tf_block(tfree));\n      tfreex = mi_tf_set_block(tfree,block);\n    }\n  } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex));\n\n  // If this was the first non-local free, we need to push it on the heap delayed free list instead\n  if mi_unlikely(use_delayed) {\n    // racy read on `heap`, but ok because MI_DELAYED_FREEING is set (see `mi_heap_delete` and `mi_heap_collect_abandon`)\n    mi_heap_t* const heap = (mi_heap_t*)(mi_atomic_load_acquire(&page->xheap)); //mi_page_heap(page);\n    mi_assert_internal(heap != NULL);\n    if (heap != NULL) {\n      // add to the delayed free list of this heap. (do this atomically as the lock only protects heap memory validity)\n      mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free);\n      do {\n        mi_block_set_nextx(heap,block,dfree, heap->keys);\n      } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block));\n    }\n\n    // and reset the MI_DELAYED_FREEING flag\n    tfree = mi_atomic_load_relaxed(&page->xthread_free);\n    do {\n      tfreex = tfree;\n      mi_assert_internal(mi_tf_delayed(tfree) == MI_DELAYED_FREEING);\n      tfreex = mi_tf_set_delayed(tfree,MI_NO_DELAYED_FREE);\n    } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex));\n  }\n}\n\n// Multi-threaded free (`_mt`) (or free in huge block if compiled with MI_HUGE_PAGE_ABANDON)\nstatic void mi_decl_noinline mi_free_block_mt(mi_page_t* page, mi_segment_t* segment, mi_block_t* block, void* p, bool was_guarded)\n{\n  MI_UNUSED(was_guarded);\n\n  // first see if the segment was abandoned and if we can reclaim it into our thread\n  if (_mi_option_get_fast(mi_option_abandoned_reclaim_on_free) != 0 &&\n      #if MI_HUGE_PAGE_ABANDON\n      segment->page_kind != MI_PAGE_HUGE &&\n      #endif\n      mi_atomic_load_relaxed(&segment->thread_id) == 0 &&  // segment is abandoned?\n      mi_prim_get_default_heap() != (mi_heap_t*)&_mi_heap_empty) // and we did not already exit this thread (without this check, a fresh heap will be initalized (issue #944))\n  {\n    // the segment is abandoned, try to reclaim it into our heap\n    if (_mi_segment_attempt_reclaim(mi_heap_get_default(), segment)) {\n      mi_assert_internal(_mi_thread_id() == mi_atomic_load_relaxed(&segment->thread_id));\n      mi_assert_internal(mi_heap_get_default()->tld->segments.subproc == segment->subproc);\n      mi_free(p);  // recursively free as now it will be a local free in our heap\n      return;\n    }\n  }\n\n  // The padding check may access the non-thread-owned page for the key values.\n  // that is safe as these are constant and the page won't be freed (as the block is not freed yet).\n  if (!was_guarded) { mi_check_padding(page, block); }\n\n  // adjust stats (after padding check and potentially recursive `mi_free` above)\n  mi_stat_free(page, block);    // stat_free may access the padding\n  mi_track_free_size(block, mi_page_usable_size_of(page,block,was_guarded));\n\n  // for small size, ensure we can fit the delayed thread pointers without triggering overflow detection\n  _mi_padding_shrink(page, block, sizeof(mi_block_t));\n\n  if (segment->kind == MI_SEGMENT_HUGE) {\n    #if MI_HUGE_PAGE_ABANDON\n    // huge page segments are always abandoned and can be freed immediately\n    _mi_segment_huge_page_free(segment, page, block);\n    return;\n    #else\n    // huge pages are special as they occupy the entire segment\n    // as these are large we reset the memory occupied by the page so it is available to other threads\n    // (as the owning thread needs to actually free the memory later).\n    _mi_segment_huge_page_reset(segment, page, block);\n    #endif\n  }\n  else {\n    #if (MI_DEBUG>0) && !MI_TRACK_ENABLED  && !MI_TSAN       // note: when tracking, cannot use mi_usable_size with multi-threading\n    memset(block, MI_DEBUG_FREED, mi_usable_size(block));\n    #endif\n  }\n\n  // and finally free the actual block by pushing it on the owning heap\n  // thread_delayed free list (or heap delayed free list)\n  mi_free_block_delayed_mt(page,block);\n}\n\n\n// ------------------------------------------------------\n// Usable size\n// ------------------------------------------------------\n\n// Bytes available in a block\nstatic size_t mi_decl_noinline mi_page_usable_aligned_size_of(const mi_page_t* page, const void* p) mi_attr_noexcept {\n  const mi_block_t* block = _mi_page_ptr_unalign(page, p);\n  const bool is_guarded = mi_block_ptr_is_guarded(block,p);\n  const size_t size = mi_page_usable_size_of(page, block, is_guarded);\n  const ptrdiff_t adjust = (uint8_t*)p - (uint8_t*)block;\n  mi_assert_internal(adjust >= 0 && (size_t)adjust <= size);\n  const size_t aligned_size = (size - adjust);  \n  return aligned_size;\n}\n\nstatic inline mi_page_t* mi_validate_ptr_page(const void* p, const char* msg) {\n  const mi_segment_t* const segment = mi_checked_ptr_segment(p, msg);\n  if mi_unlikely(segment==NULL) return NULL;\n  mi_page_t* const page = _mi_segment_page_of(segment, p);\n  return page;\n}\n\nstatic inline size_t _mi_usable_size(const void* p, const mi_page_t* page) mi_attr_noexcept {\n  if mi_unlikely(page==NULL) return 0;\n  if mi_likely(!mi_page_has_aligned(page)) {\n    const mi_block_t* block = (const mi_block_t*)p;\n    return mi_page_usable_size_of(page, block, false /* is guarded */);\n  }\n  else {\n    // split out to separate routine for improved code generation\n    return mi_page_usable_aligned_size_of(page, p);\n  }\n}\n\nmi_decl_nodiscard size_t mi_usable_size(const void* p) mi_attr_noexcept {\n  const mi_page_t* const page = mi_validate_ptr_page(p,\"mi_usable_size\");\n  return _mi_usable_size(p,page);\n}\n\n\n// ------------------------------------------------------\n// Free variants\n// ------------------------------------------------------\n\nvoid mi_free_size(void* p, size_t size) mi_attr_noexcept {\n  MI_UNUSED_RELEASE(size);\n  #if MI_DEBUG\n  const mi_page_t* const page = mi_validate_ptr_page(p,\"mi_free_size\");  \n  const size_t available = _mi_usable_size(p,page);\n  mi_assert(p == NULL || size <= available || available == 0 /* invalid pointer */ );\n  #endif\n  mi_free(p);\n}\n\nvoid mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept {\n  MI_UNUSED_RELEASE(alignment);\n  mi_assert(((uintptr_t)p % alignment) == 0);\n  mi_free_size(p,size);\n}\n\nvoid mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept {\n  MI_UNUSED_RELEASE(alignment);\n  mi_assert(((uintptr_t)p % alignment) == 0);\n  mi_free(p);\n}\n\n\n// ------------------------------------------------------\n// Check for double free in secure and debug mode\n// This is somewhat expensive so only enabled for secure mode 4\n// ------------------------------------------------------\n\n#if (MI_ENCODE_FREELIST && (MI_SECURE>=4 || MI_DEBUG!=0))\n// linear check if the free list contains a specific element\nstatic bool mi_list_contains(const mi_page_t* page, const mi_block_t* list, const mi_block_t* elem) {\n  while (list != NULL) {\n    if (elem==list) return true;\n    list = mi_block_next(page, list);\n  }\n  return false;\n}\n\nstatic mi_decl_noinline bool mi_check_is_double_freex(const mi_page_t* page, const mi_block_t* block) {\n  // The decoded value is in the same page (or NULL).\n  // Walk the free lists to verify positively if it is already freed\n  if (mi_list_contains(page, page->free, block) ||\n      mi_list_contains(page, page->local_free, block) ||\n      mi_list_contains(page, mi_page_thread_free(page), block))\n  {\n    _mi_error_message(EAGAIN, \"double free detected of block %p with size %zu\\n\", block, mi_page_block_size(page));\n    return true;\n  }\n  return false;\n}\n\n#define mi_track_page(page,access)  { size_t psize; void* pstart = _mi_page_start(_mi_page_segment(page),page,&psize); mi_track_mem_##access( pstart, psize); }\n\nstatic inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) {\n  bool is_double_free = false;\n  mi_block_t* n = mi_block_nextx(page, block, page->keys); // pretend it is freed, and get the decoded first field\n  if (((uintptr_t)n & (MI_INTPTR_SIZE-1))==0 &&  // quick check: aligned pointer?\n      (n==NULL || mi_is_in_same_page(block, n))) // quick check: in same page or NULL?\n  {\n    // Suspicious: decoded value a in block is in the same page (or NULL) -- maybe a double free?\n    // (continue in separate function to improve code generation)\n    is_double_free = mi_check_is_double_freex(page, block);\n  }\n  return is_double_free;\n}\n#else\nstatic inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) {\n  MI_UNUSED(page);\n  MI_UNUSED(block);\n  return false;\n}\n#endif\n\n\n// ---------------------------------------------------------------------------\n// Check for heap block overflow by setting up padding at the end of the block\n// ---------------------------------------------------------------------------\n\n#if MI_PADDING // && !MI_TRACK_ENABLED\nstatic bool mi_page_decode_padding(const mi_page_t* page, const mi_block_t* block, size_t* delta, size_t* bsize) {\n  *bsize = mi_page_usable_block_size(page);\n  const mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + *bsize);\n  mi_track_mem_defined(padding,sizeof(mi_padding_t));\n  *delta = padding->delta;\n  uint32_t canary = padding->canary;\n  uintptr_t keys[2];\n  keys[0] = page->keys[0];\n  keys[1] = page->keys[1];\n  bool ok = (mi_ptr_encode_canary(page,block,keys) == canary && *delta <= *bsize);\n  mi_track_mem_noaccess(padding,sizeof(mi_padding_t));\n  return ok;\n}\n\n// Return the exact usable size of a block.\nstatic size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block, bool is_guarded) {\n  if (is_guarded) {\n    const size_t bsize = mi_page_block_size(page);\n    return (bsize - _mi_os_page_size());\n  }\n  else {\n    size_t bsize;\n    size_t delta;\n    bool ok = mi_page_decode_padding(page, block, &delta, &bsize);\n    mi_assert_internal(ok); mi_assert_internal(delta <= bsize);\n    return (ok ? bsize - delta : 0);\n  }\n}\n\n// When a non-thread-local block is freed, it becomes part of the thread delayed free\n// list that is freed later by the owning heap. If the exact usable size is too small to\n// contain the pointer for the delayed list, then shrink the padding (by decreasing delta)\n// so it will later not trigger an overflow error in `mi_free_block`.\nvoid _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) {\n  size_t bsize;\n  size_t delta;\n  bool ok = mi_page_decode_padding(page, block, &delta, &bsize);\n  mi_assert_internal(ok);\n  if (!ok || (bsize - delta) >= min_size) return;  // usually already enough space\n  mi_assert_internal(bsize >= min_size);\n  if (bsize < min_size) return;  // should never happen\n  size_t new_delta = (bsize - min_size);\n  mi_assert_internal(new_delta < bsize);\n  mi_padding_t* padding = (mi_padding_t*)((uint8_t*)block + bsize);\n  mi_track_mem_defined(padding,sizeof(mi_padding_t));\n  padding->delta = (uint32_t)new_delta;\n  mi_track_mem_noaccess(padding,sizeof(mi_padding_t));\n}\n#else\nstatic size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block, bool is_guarded) {\n  MI_UNUSED(is_guarded); MI_UNUSED(block);\n  return mi_page_usable_block_size(page);\n}\n\nvoid _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) {\n  MI_UNUSED(page); MI_UNUSED(block); MI_UNUSED(min_size);\n}\n#endif\n\n#if MI_PADDING && MI_PADDING_CHECK\n\nstatic bool mi_verify_padding(const mi_page_t* page, const mi_block_t* block, size_t* size, size_t* wrong) {\n  size_t bsize;\n  size_t delta;\n  bool ok = mi_page_decode_padding(page, block, &delta, &bsize);\n  *size = *wrong = bsize;\n  if (!ok) return false;\n  mi_assert_internal(bsize >= delta);\n  *size = bsize - delta;\n  if (!mi_page_is_huge(page)) {\n    uint8_t* fill = (uint8_t*)block + bsize - delta;\n    const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // check at most the first N padding bytes\n    mi_track_mem_defined(fill, maxpad);\n    for (size_t i = 0; i < maxpad; i++) {\n      if (fill[i] != MI_DEBUG_PADDING) {\n        *wrong = bsize - delta + i;\n        ok = false;\n        break;\n      }\n    }\n    mi_track_mem_noaccess(fill, maxpad);\n  }\n  return ok;\n}\n\nstatic void mi_check_padding(const mi_page_t* page, const mi_block_t* block) {\n  size_t size;\n  size_t wrong;\n  if (!mi_verify_padding(page,block,&size,&wrong)) {\n    _mi_error_message(EFAULT, \"buffer overflow in heap block %p of size %zu: write after %zu bytes\\n\", block, size, wrong );\n  }\n}\n\n#else\n\nstatic void mi_check_padding(const mi_page_t* page, const mi_block_t* block) {\n  MI_UNUSED(page);\n  MI_UNUSED(block);\n}\n\n#endif\n\n// only maintain stats for smaller objects if requested\n#if (MI_STAT>0)\nstatic void mi_stat_free(const mi_page_t* page, const mi_block_t* block) {\n  MI_UNUSED(block);\n  mi_heap_t* const heap = mi_heap_get_default();\n  const size_t bsize = mi_page_usable_block_size(page);\n  // #if (MI_STAT>1)\n  // const size_t usize = mi_page_usable_size_of(page, block);\n  // mi_heap_stat_decrease(heap, malloc_requested, usize);\n  // #endif\n  if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) {\n    mi_heap_stat_decrease(heap, malloc_normal, bsize);\n    #if (MI_STAT > 1)\n    mi_heap_stat_decrease(heap, malloc_bins[_mi_bin(bsize)], 1);\n    #endif\n  }\n  //else if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {\n  //  mi_heap_stat_decrease(heap, malloc_large, bsize);\n  //}\n  else {\n    mi_heap_stat_decrease(heap, malloc_huge, bsize);\n  }\n}\n#else\nstatic void mi_stat_free(const mi_page_t* page, const mi_block_t* block) {\n  MI_UNUSED(page); MI_UNUSED(block);\n}\n#endif\n\n\n// Remove guard page when building with MI_GUARDED\n#if MI_GUARDED\nstatic void mi_block_unguard(mi_page_t* page, mi_block_t* block, void* p) {\n  MI_UNUSED(p);\n  mi_assert_internal(mi_block_ptr_is_guarded(block, p));\n  mi_assert_internal(mi_page_has_aligned(page));\n  mi_assert_internal((uint8_t*)p - (uint8_t*)block >= (ptrdiff_t)sizeof(mi_block_t));\n  mi_assert_internal(block->next == MI_BLOCK_TAG_GUARDED);\n\n  const size_t bsize = mi_page_block_size(page);\n  const size_t psize = _mi_os_page_size();\n  mi_assert_internal(bsize > psize);\n  mi_assert_internal(_mi_page_segment(page)->allow_decommit);\n  void* gpage = (uint8_t*)block + bsize - psize;\n  mi_assert_internal(_mi_is_aligned(gpage, psize));\n  _mi_os_unprotect(gpage, psize);\n}\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/heap.c",
      "sha256": "302ef412b4788fff18e44f7b315ac2df78cfd5d22a999e4f9e5c14660d956b06",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/*----------------------------------------------------------------------------\nCopyright (c) 2018-2021, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"  // mi_prim_get_default_heap\n\n#include <string.h>  // memset, memcpy\n\n#if defined(_MSC_VER) && (_MSC_VER < 1920)\n#pragma warning(disable:4204)  // non-constant aggregate initializer\n#endif\n\n/* -----------------------------------------------------------\n  Helpers\n----------------------------------------------------------- */\n\n// return `true` if ok, `false` to break\ntypedef bool (heap_page_visitor_fun)(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2);\n\n// Visit all pages in a heap; returns `false` if break was called.\nstatic bool mi_heap_visit_pages(mi_heap_t* heap, heap_page_visitor_fun* fn, bool include_full, void* arg1, void* arg2)\n{\n  if (heap==NULL || heap->page_count==0) return 0;\n\n  // visit all pages\n  #if MI_DEBUG>1\n  size_t total = heap->page_count;\n  size_t count = 0;\n  #endif\n\n  const size_t max_bin = (include_full ? MI_BIN_FULL : MI_BIN_FULL - 1);\n  for (size_t i = 0; i <= max_bin; i++) {\n    mi_page_queue_t* pq = &heap->pages[i];\n    mi_page_t* page = pq->first;\n    while(page != NULL) {\n      mi_page_t* next = page->next; // save next in case the page gets removed from the queue\n      mi_assert_internal(mi_page_heap(page) == heap);\n      #if MI_DEBUG>1\n      count++;\n      #endif\n      if (!fn(heap, pq, page, arg1, arg2)) return false;\n      page = next; // and continue\n    }\n  }\n  mi_assert_internal(!include_full || count == total);\n  return true;\n}\n\n\n#if MI_DEBUG>=2\nstatic bool mi_heap_page_is_valid(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) {\n  MI_UNUSED(arg1);\n  MI_UNUSED(arg2);\n  MI_UNUSED(pq);\n  mi_assert_internal(mi_page_heap(page) == heap);\n  mi_segment_t* segment = _mi_page_segment(page);\n  mi_assert_internal(mi_atomic_load_relaxed(&segment->thread_id) == heap->thread_id);\n  mi_assert_expensive(_mi_page_is_valid(page));\n  return true;\n}\n#endif\n#if MI_DEBUG>=3\nstatic bool mi_heap_is_valid(mi_heap_t* heap) {\n  mi_assert_internal(heap!=NULL);\n  mi_heap_visit_pages(heap, &mi_heap_page_is_valid, true, NULL, NULL);\n  return true;\n}\n#endif\n\n\n\n\n/* -----------------------------------------------------------\n  \"Collect\" pages by migrating `local_free` and `thread_free`\n  lists and freeing empty pages. This is done when a thread\n  stops (and in that case abandons pages if there are still\n  blocks alive)\n----------------------------------------------------------- */\n\ntypedef enum mi_collect_e {\n  MI_NORMAL,\n  MI_FORCE,\n  MI_ABANDON\n} mi_collect_t;\n\n\nstatic bool mi_heap_page_collect(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg_collect, void* arg2 ) {\n  MI_UNUSED(arg2);\n  MI_UNUSED(heap);\n  mi_assert_internal(mi_heap_page_is_valid(heap, pq, page, NULL, NULL));\n  mi_collect_t collect = *((mi_collect_t*)arg_collect);\n  _mi_page_free_collect(page, collect >= MI_FORCE);\n  if (collect == MI_FORCE) {\n    // note: call before a potential `_mi_page_free` as the segment may be freed if this was the last used page in that segment.\n    mi_segment_t* segment = _mi_page_segment(page);\n    _mi_segment_collect(segment, true /* force? */);\n  }\n  if (mi_page_all_free(page)) {\n    // no more used blocks, free the page.\n    // note: this will free retired pages as well.\n    _mi_page_free(page, pq, collect >= MI_FORCE);\n  }\n  else if (collect == MI_ABANDON) {\n    // still used blocks but the thread is done; abandon the page\n    _mi_page_abandon(page, pq);\n  }\n  return true; // don't break\n}\n\nstatic bool mi_heap_page_never_delayed_free(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) {\n  MI_UNUSED(arg1);\n  MI_UNUSED(arg2);\n  MI_UNUSED(heap);\n  MI_UNUSED(pq);\n  _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false);\n  return true; // don't break\n}\n\nstatic void mi_heap_collect_ex(mi_heap_t* heap, mi_collect_t collect)\n{\n  if (heap==NULL || !mi_heap_is_initialized(heap)) return;\n\n  const bool force = (collect >= MI_FORCE);\n  _mi_deferred_free(heap, force);\n\n  // python/cpython#112532: we may be called from a thread that is not the owner of the heap\n  const bool is_main_thread = (_mi_is_main_thread() && heap->thread_id == _mi_thread_id());\n\n  // note: never reclaim on collect but leave it to threads that need storage to reclaim\n  const bool force_main =\n    #ifdef NDEBUG\n      collect == MI_FORCE\n    #else\n      collect >= MI_FORCE\n    #endif\n      && is_main_thread && mi_heap_is_backing(heap) && !heap->no_reclaim;\n\n  if (force_main) {\n    // the main thread is abandoned (end-of-program), try to reclaim all abandoned segments.\n    // if all memory is freed by now, all segments should be freed.\n    // note: this only collects in the current subprocess\n    _mi_abandoned_reclaim_all(heap, &heap->tld->segments);\n  }\n\n  // if abandoning, mark all pages to no longer add to delayed_free\n  if (collect == MI_ABANDON) {\n    mi_heap_visit_pages(heap, &mi_heap_page_never_delayed_free, true, NULL, NULL);\n  }\n\n  // free all current thread delayed blocks.\n  // (if abandoning, after this there are no more thread-delayed references into the pages.)\n  _mi_heap_delayed_free_all(heap);\n\n  // collect retired pages\n  _mi_heap_collect_retired(heap, force);\n\n  // collect all pages owned by this thread\n  mi_heap_visit_pages(heap, &mi_heap_page_collect, (collect!=MI_NORMAL), &collect, NULL); // normally don't visit full pages, issue #1220\n  mi_assert_internal( collect != MI_ABANDON || mi_atomic_load_ptr_acquire(mi_block_t,&heap->thread_delayed_free) == NULL );\n\n  // collect abandoned segments (in particular, purge expired parts of segments in the abandoned segment list)\n  // note: forced purge can be quite expensive if many threads are created/destroyed so we do not force on abandonment\n  _mi_abandoned_collect(heap, collect == MI_FORCE /* force? */, &heap->tld->segments);\n\n  // if forced, collect thread data cache on program-exit (or shared library unload)\n  if (force && is_main_thread && mi_heap_is_backing(heap)) {\n    _mi_thread_data_collect();  // collect thread data cache\n  }\n\n  // collect arenas (this is program wide so don't force purges on abandonment of threads)\n  _mi_arenas_collect(collect == MI_FORCE /* force purge? */);\n\n  // merge statistics\n  if (collect <= MI_FORCE) { _mi_stats_merge_thread(heap->tld); }\n}\n\nvoid _mi_heap_collect_abandon(mi_heap_t* heap) {\n  mi_heap_collect_ex(heap, MI_ABANDON);\n}\n\nvoid mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept {\n  mi_heap_collect_ex(heap, (force ? MI_FORCE : MI_NORMAL));\n}\n\nvoid mi_collect(bool force) mi_attr_noexcept {\n  mi_heap_collect(mi_prim_get_default_heap(), force);\n}\n\n\n/* -----------------------------------------------------------\n  Heap new\n----------------------------------------------------------- */\n\nmi_heap_t* mi_heap_get_default(void) {\n  mi_thread_init();\n  return mi_prim_get_default_heap();\n}\n\nstatic bool mi_heap_is_default(const mi_heap_t* heap) {\n  return (heap == mi_prim_get_default_heap());\n}\n\n\nmi_heap_t* mi_heap_get_backing(void) {\n  mi_heap_t* heap = mi_heap_get_default();\n  mi_assert_internal(heap!=NULL);\n  mi_heap_t* bheap = heap->tld->heap_backing;\n  mi_assert_internal(bheap!=NULL);\n  mi_assert_internal(bheap->thread_id == _mi_thread_id());\n  return bheap;\n}\n\nvoid _mi_heap_init(mi_heap_t* heap, mi_tld_t* tld, mi_arena_id_t arena_id, bool noreclaim, uint8_t tag) {\n  _mi_memcpy_aligned(heap, &_mi_heap_empty, sizeof(mi_heap_t));\n  heap->tld = tld;\n  heap->thread_id  = _mi_thread_id();\n  heap->arena_id   = arena_id;\n  heap->no_reclaim = noreclaim;\n  heap->tag        = tag;\n  if (heap == tld->heap_backing) {\n    #if defined(_WIN32) && !defined(MI_SHARED_LIB)\n      _mi_random_init_weak(&heap->random);    // prevent allocation failure during bcrypt dll initialization with static linking (issue #1185)\n    #else\n      _mi_random_init(&heap->random);\n    #endif\n  }\n  else {\n    _mi_random_split(&tld->heap_backing->random, &heap->random);\n  }\n  heap->cookie  = _mi_heap_random_next(heap) | 1;\n  heap->keys[0] = _mi_heap_random_next(heap);\n  heap->keys[1] = _mi_heap_random_next(heap);\n  _mi_heap_guarded_init(heap);\n  // push on the thread local heaps list\n  heap->next = heap->tld->heaps;\n  heap->tld->heaps = heap;\n}\n\nmi_decl_nodiscard mi_heap_t* mi_heap_new_ex(int heap_tag, bool allow_destroy, mi_arena_id_t arena_id) {\n  mi_heap_t* bheap = mi_heap_get_backing();\n  mi_heap_t* heap = mi_heap_malloc_tp(bheap, mi_heap_t);  // todo: OS allocate in secure mode?\n  if (heap == NULL) return NULL;\n  mi_assert(heap_tag >= 0 && heap_tag < 256);\n  _mi_heap_init(heap, bheap->tld, arena_id, allow_destroy /* no reclaim? */, (uint8_t)heap_tag /* heap tag */);\n  return heap;\n}\n\nmi_decl_nodiscard mi_heap_t* mi_heap_new_in_arena(mi_arena_id_t arena_id) {\n  return mi_heap_new_ex(0 /* default heap tag */, false /* don't allow `mi_heap_destroy` */, arena_id);\n}\n\nmi_decl_nodiscard mi_heap_t* mi_heap_new(void) {\n  // don't reclaim abandoned memory or otherwise destroy is unsafe\n  return mi_heap_new_ex(0 /* default heap tag */, true /* no reclaim */, _mi_arena_id_none());\n}\n\nbool _mi_heap_memid_is_suitable(mi_heap_t* heap, mi_memid_t memid) {\n  return _mi_arena_memid_is_suitable(memid, heap->arena_id);\n}\n\nuintptr_t _mi_heap_random_next(mi_heap_t* heap) {\n  return _mi_random_next(&heap->random);\n}\n\n// zero out the page queues\nstatic void mi_heap_reset_pages(mi_heap_t* heap) {\n  mi_assert_internal(heap != NULL);\n  mi_assert_internal(mi_heap_is_initialized(heap));\n  // TODO: copy full empty heap instead?\n  memset(&heap->pages_free_direct, 0, sizeof(heap->pages_free_direct));\n  _mi_memcpy_aligned(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages));\n  heap->thread_delayed_free = NULL;\n  heap->page_count = 0;\n}\n\n// called from `mi_heap_destroy` and `mi_heap_delete` to free the internal heap resources.\nstatic void mi_heap_free(mi_heap_t* heap) {\n  mi_assert(heap != NULL);\n  mi_assert_internal(mi_heap_is_initialized(heap));\n  if (heap==NULL || !mi_heap_is_initialized(heap)) return;\n  if (mi_heap_is_backing(heap)) return; // dont free the backing heap\n\n  // reset default\n  if (mi_heap_is_default(heap)) {\n    _mi_heap_set_default_direct(heap->tld->heap_backing);\n  }\n\n  // remove ourselves from the thread local heaps list\n  // linear search but we expect the number of heaps to be relatively small\n  mi_heap_t* prev = NULL;\n  mi_heap_t* curr = heap->tld->heaps;\n  while (curr != heap && curr != NULL) {\n    prev = curr;\n    curr = curr->next;\n  }\n  mi_assert_internal(curr == heap);\n  if (curr == heap) {\n    if (prev != NULL) { prev->next = heap->next; }\n                 else { heap->tld->heaps = heap->next; }\n  }\n  mi_assert_internal(heap->tld->heaps != NULL);\n\n  // and free the used memory\n  mi_free(heap);\n}\n\n// return a heap on the same thread as `heap` specialized for the specified tag (if it exists)\nmi_heap_t* _mi_heap_by_tag(mi_heap_t* heap, uint8_t tag) {\n  if (heap->tag == tag) {\n    return heap;\n  }\n  for (mi_heap_t *curr = heap->tld->heaps; curr != NULL; curr = curr->next) {\n    if (curr->tag == tag) {\n      return curr;\n    }\n  }\n  return NULL;\n}\n\n/* -----------------------------------------------------------\n  Heap destroy\n----------------------------------------------------------- */\n\nstatic bool _mi_heap_page_destroy(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) {\n  MI_UNUSED(arg1);\n  MI_UNUSED(arg2);\n  MI_UNUSED(heap);\n  MI_UNUSED(pq);\n\n  // ensure no more thread_delayed_free will be added\n  _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false);\n\n  // stats\n  const size_t bsize = mi_page_block_size(page);\n  if (bsize > MI_MEDIUM_OBJ_SIZE_MAX) {\n    //if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {\n    //  mi_heap_stat_decrease(heap, malloc_large, bsize);\n    //}\n    //else \n    {\n      mi_heap_stat_decrease(heap, malloc_huge, bsize);\n    }\n  }\n  #if (MI_STAT>0)\n  _mi_page_free_collect(page, false);  // update used count\n  const size_t inuse = page->used;\n  if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {\n    mi_heap_stat_decrease(heap, malloc_normal, bsize * inuse);\n    #if (MI_STAT>1)\n    mi_heap_stat_decrease(heap, malloc_bins[_mi_bin(bsize)], inuse);\n    #endif\n  }\n  // mi_heap_stat_decrease(heap, malloc_requested, bsize * inuse);  // todo: off for aligned blocks...\n  #endif\n\n  /// pretend it is all free now\n  mi_assert_internal(mi_page_thread_free(page) == NULL);\n  page->used = 0;\n\n  // and free the page\n  // mi_page_free(page,false);\n  page->next = NULL;\n  page->prev = NULL;\n  _mi_segment_page_free(page,false /* no force? */, &heap->tld->segments);\n\n  return true; // keep going\n}\n\nvoid _mi_heap_destroy_pages(mi_heap_t* heap) {\n  mi_heap_visit_pages(heap, &_mi_heap_page_destroy, true, NULL, NULL);\n  mi_heap_reset_pages(heap);\n}\n\n#if MI_TRACK_HEAP_DESTROY\nstatic bool mi_cdecl mi_heap_track_block_free(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg) {\n  MI_UNUSED(heap); MI_UNUSED(area);  MI_UNUSED(arg); MI_UNUSED(block_size);\n  mi_track_free_size(block,mi_usable_size(block));\n  return true;\n}\n#endif\n\nvoid mi_heap_destroy(mi_heap_t* heap) {\n  mi_assert(heap != NULL);\n  mi_assert(mi_heap_is_initialized(heap));\n  mi_assert(heap->no_reclaim);\n  mi_assert_expensive(mi_heap_is_valid(heap));\n  if (heap==NULL || !mi_heap_is_initialized(heap)) return;\n  #if MI_GUARDED\n  // _mi_warning_message(\"'mi_heap_destroy' called but MI_GUARDED is enabled -- using `mi_heap_delete` instead (heap at %p)\\n\", heap);\n  mi_heap_delete(heap);\n  return;\n  #else\n  if (!heap->no_reclaim) {\n    _mi_warning_message(\"'mi_heap_destroy' called but ignored as the heap was not created with 'allow_destroy' (heap at %p)\\n\", heap);\n    // don't free in case it may contain reclaimed pages\n    mi_heap_delete(heap);\n  }\n  else {\n    // track all blocks as freed\n    #if MI_TRACK_HEAP_DESTROY\n    mi_heap_visit_blocks(heap, true, mi_heap_track_block_free, NULL);\n    #endif\n    // free all pages\n    _mi_heap_destroy_pages(heap);\n    mi_heap_free(heap);\n  }\n  #endif\n}\n\n// forcefully destroy all heaps in the current thread\nvoid _mi_heap_unsafe_destroy_all(mi_heap_t* heap) {\n  mi_assert_internal(heap != NULL);\n  if (heap == NULL) return;\n  mi_heap_t* curr = heap->tld->heaps;\n  while (curr != NULL) {\n    mi_heap_t* next = curr->next;\n    if (curr->no_reclaim) {\n      mi_heap_destroy(curr);\n    }\n    else {\n      _mi_heap_destroy_pages(curr);\n    }\n    curr = next;\n  }\n}\n\n/* -----------------------------------------------------------\n  Safe Heap delete\n----------------------------------------------------------- */\n\n// Transfer the pages from one heap to the other\nstatic void mi_heap_absorb(mi_heap_t* heap, mi_heap_t* from) {\n  mi_assert_internal(heap!=NULL);\n  if (from==NULL || from->page_count == 0) return;\n\n  // reduce the size of the delayed frees\n  _mi_heap_delayed_free_partial(from);\n\n  // transfer all pages by appending the queues; this will set a new heap field\n  // so threads may do delayed frees in either heap for a while.\n  // note: appending waits for each page to not be in the `MI_DELAYED_FREEING` state\n  // so after this only the new heap will get delayed frees\n  for (size_t i = 0; i <= MI_BIN_FULL; i++) {\n    mi_page_queue_t* pq = &heap->pages[i];\n    mi_page_queue_t* append = &from->pages[i];\n    size_t pcount = _mi_page_queue_append(heap, pq, append);\n    heap->page_count += pcount;\n    from->page_count -= pcount;\n  }\n  mi_assert_internal(from->page_count == 0);\n\n  // and do outstanding delayed frees in the `from` heap\n  // note: be careful here as the `heap` field in all those pages no longer point to `from`,\n  // turns out to be ok as `_mi_heap_delayed_free` only visits the list and calls a\n  // the regular `_mi_free_delayed_block` which is safe.\n  _mi_heap_delayed_free_all(from);\n  #if !defined(_MSC_VER) || (_MSC_VER > 1900) // somehow the following line gives an error in VS2015, issue #353\n  mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_block_t,&from->thread_delayed_free) == NULL);\n  #endif\n\n  // and reset the `from` heap\n  mi_heap_reset_pages(from);\n}\n\n// are two heaps compatible with respect to heap-tag, exclusive arena etc.\nstatic bool mi_heaps_are_compatible(mi_heap_t* heap1, mi_heap_t* heap2) {\n  return (heap1->tag == heap2->tag &&                   // store same kind of objects\n          heap1->arena_id == heap2->arena_id);          // same arena preference\n}\n\n// Safe delete a heap without freeing any still allocated blocks in that heap.\nvoid mi_heap_delete(mi_heap_t* heap)\n{\n  mi_assert(heap != NULL);\n  mi_assert(mi_heap_is_initialized(heap));\n  mi_assert_expensive(mi_heap_is_valid(heap));\n  if (heap==NULL || !mi_heap_is_initialized(heap)) return;\n\n  mi_heap_t* bheap = heap->tld->heap_backing;\n  if (bheap != heap && mi_heaps_are_compatible(bheap,heap)) {\n    // transfer still used pages to the backing heap\n    mi_heap_absorb(bheap, heap);\n  }\n  else {\n    // the backing heap abandons its pages\n    _mi_heap_collect_abandon(heap);\n  }\n  mi_assert_internal(heap->page_count==0);\n  mi_heap_free(heap);\n}\n\nmi_heap_t* mi_heap_set_default(mi_heap_t* heap) {\n  mi_assert(heap != NULL);\n  mi_assert(mi_heap_is_initialized(heap));\n  if (heap==NULL || !mi_heap_is_initialized(heap)) return NULL;\n  mi_assert_expensive(mi_heap_is_valid(heap));\n  mi_heap_t* old = mi_prim_get_default_heap();\n  _mi_heap_set_default_direct(heap);\n  return old;\n}\n\n\n\n\n/* -----------------------------------------------------------\n  Analysis\n----------------------------------------------------------- */\n\n// static since it is not thread safe to access heaps from other threads.\nstatic mi_heap_t* mi_heap_of_block(const void* p) {\n  if (p == NULL) return NULL;\n  mi_segment_t* segment = _mi_ptr_segment(p);\n  bool valid = (_mi_ptr_cookie(segment) == segment->cookie);\n  mi_assert_internal(valid);\n  if mi_unlikely(!valid) return NULL;\n  return mi_page_heap(_mi_segment_page_of(segment,p));\n}\n\nbool mi_heap_contains_block(mi_heap_t* heap, const void* p) {\n  mi_assert(heap != NULL);\n  if (heap==NULL || !mi_heap_is_initialized(heap)) return false;\n  return (heap == mi_heap_of_block(p));\n}\n\n\nstatic bool mi_heap_page_check_owned(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* p, void* vfound) {\n  MI_UNUSED(heap);\n  MI_UNUSED(pq);\n  bool* found = (bool*)vfound;\n  void* start = mi_page_start(page);\n  void* end   = (uint8_t*)start + (page->capacity * mi_page_block_size(page));\n  *found = (p >= start && p < end);\n  return (!*found); // continue if not found\n}\n\nbool mi_heap_check_owned(mi_heap_t* heap, const void* p) {\n  mi_assert(heap != NULL);\n  if (heap==NULL || !mi_heap_is_initialized(heap)) return false;\n  if (((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0) return false;  // only aligned pointers\n  bool found = false;\n  mi_heap_visit_pages(heap, &mi_heap_page_check_owned, true, (void*)p, &found);\n  return found;\n}\n\nbool mi_check_owned(const void* p) {\n  return mi_heap_check_owned(mi_prim_get_default_heap(), p);\n}\n\n/* -----------------------------------------------------------\n  Visit all heap blocks and areas\n  Todo: enable visiting abandoned pages, and\n        enable visiting all blocks of all heaps across threads\n----------------------------------------------------------- */\n\nvoid _mi_heap_area_init(mi_heap_area_t* area, mi_page_t* page) {\n  const size_t bsize = mi_page_block_size(page);\n  const size_t ubsize = mi_page_usable_block_size(page);\n  area->reserved = page->reserved * bsize;\n  area->committed = page->capacity * bsize;\n  area->blocks = mi_page_start(page);\n  area->used = page->used;   // number of blocks in use (#553)\n  area->block_size = ubsize;\n  area->full_block_size = bsize;\n  area->heap_tag = page->heap_tag;\n}\n\n\nstatic void mi_get_fast_divisor(size_t divisor, uint64_t* magic, size_t* shift) {\n  mi_assert_internal(divisor > 0 && divisor <= UINT32_MAX);\n  *shift = MI_SIZE_BITS - mi_clz(divisor - 1);\n  *magic = ((((uint64_t)1 << 32) * (((uint64_t)1 << *shift) - divisor)) / divisor + 1);\n}\n\nstatic size_t mi_fast_divide(size_t n, uint64_t magic, size_t shift) {\n  mi_assert_internal(n <= UINT32_MAX);\n  const uint64_t hi = ((uint64_t)n * magic) >> 32;\n  return (size_t)((hi + n) >> shift);\n}\n\nbool _mi_heap_area_visit_blocks(const mi_heap_area_t* area, mi_page_t* page, mi_block_visit_fun* visitor, void* arg) {\n  mi_assert(area != NULL);\n  if (area==NULL) return true;\n  mi_assert(page != NULL);\n  if (page == NULL) return true;\n\n  // collect early so the page used count is reported correctly\n  // _mi_page_free_collect(page,true);              // collect both thread_delayed and local_free\n  mi_assert_internal(page->local_free == NULL);\n  if (page->used == 0) return true;\n\n  size_t psize;\n  uint8_t* const pstart = _mi_segment_page_start(_mi_page_segment(page), page, &psize);\n  mi_heap_t* const heap = mi_page_heap(page);\n  const size_t bsize    = mi_page_block_size(page);\n  const size_t ubsize   = mi_page_usable_block_size(page); // without padding\n\n  // optimize page with one block\n  if (page->capacity == 1) {\n    mi_assert_internal(page->used == 1 && page->free == NULL);\n    return visitor(mi_page_heap(page), area, pstart, ubsize, arg);\n  }\n  mi_assert(bsize <= UINT32_MAX);\n\n  // optimize full pages\n  if (page->used == page->capacity) {\n    uint8_t* block = pstart;\n    for (size_t i = 0; i < page->capacity; i++) {\n      if (!visitor(heap, area, block, ubsize, arg)) return false;\n      block += bsize;\n    }\n    return true;\n  }\n\n  // create a bitmap of free blocks.\n  #define MI_MAX_BLOCKS   (MI_SMALL_PAGE_SIZE / sizeof(void*))\n  uintptr_t free_map[MI_MAX_BLOCKS / MI_INTPTR_BITS];\n  const uintptr_t bmapsize = _mi_divide_up(page->capacity, MI_INTPTR_BITS);\n  memset(free_map, 0, bmapsize * sizeof(intptr_t));\n  if (page->capacity % MI_INTPTR_BITS != 0) {\n    // mark left-over bits at the end as free\n    size_t shift   = (page->capacity % MI_INTPTR_BITS);\n    uintptr_t mask = (UINTPTR_MAX << shift);\n    free_map[bmapsize - 1] = mask;\n  }\n\n  // fast repeated division by the block size\n  uint64_t magic;\n  size_t   shift;\n  mi_get_fast_divisor(bsize, &magic, &shift);\n\n  #if MI_DEBUG>1\n  size_t free_count = 0;\n  #endif\n  for (mi_block_t* block = page->free; block != NULL; block = mi_block_next(page, block)) {\n    #if MI_DEBUG>1\n    free_count++;\n    #endif\n    mi_assert_internal((uint8_t*)block >= pstart && (uint8_t*)block < (pstart + psize));\n    size_t offset = (uint8_t*)block - pstart;\n    mi_assert_internal(offset % bsize == 0);\n    mi_assert_internal(offset <= UINT32_MAX);\n    size_t blockidx = mi_fast_divide(offset, magic, shift);\n    mi_assert_internal(blockidx == offset / bsize);\n    mi_assert_internal(blockidx < MI_MAX_BLOCKS);\n    size_t bitidx = (blockidx / MI_INTPTR_BITS);\n    size_t bit = blockidx - (bitidx * MI_INTPTR_BITS);\n    free_map[bitidx] |= ((uintptr_t)1 << bit);\n  }\n  mi_assert_internal(page->capacity == (free_count + page->used));\n\n  // walk through all blocks skipping the free ones\n  #if MI_DEBUG>1\n  size_t used_count = 0;\n  #endif\n  uint8_t* block = pstart;\n  for (size_t i = 0; i < bmapsize; i++) {\n    if (free_map[i] == 0) {\n      // every block is in use\n      for (size_t j = 0; j < MI_INTPTR_BITS; j++) {\n        #if MI_DEBUG>1\n        used_count++;\n        #endif\n        if (!visitor(heap, area, block, ubsize, arg)) return false;\n        block += bsize;\n      }\n    }\n    else {\n      // visit the used blocks in the mask\n      uintptr_t m = ~free_map[i];\n      while (m != 0) {\n        #if MI_DEBUG>1\n        used_count++;\n        #endif\n        size_t bitidx = mi_ctz(m);\n        if (!visitor(heap, area, block + (bitidx * bsize), ubsize, arg)) return false;\n        m &= m - 1;  // clear least significant bit\n      }\n      block += bsize * MI_INTPTR_BITS;\n    }\n  }\n  mi_assert_internal(page->used == used_count);\n  return true;\n}\n\n\n\n// Separate struct to keep `mi_page_t` out of the public interface\ntypedef struct mi_heap_area_ex_s {\n  mi_heap_area_t area;\n  mi_page_t* page;\n} mi_heap_area_ex_t;\n\ntypedef bool (mi_heap_area_visit_fun)(const mi_heap_t* heap, const mi_heap_area_ex_t* area, void* arg);\n\nstatic bool mi_heap_visit_areas_page(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* vfun, void* arg) {\n  MI_UNUSED(heap);\n  MI_UNUSED(pq);\n  if (page==NULL) return true;\n  mi_heap_area_visit_fun* fun = (mi_heap_area_visit_fun*)vfun;\n  mi_heap_area_ex_t xarea;\n  xarea.page = page;  \n  _mi_page_free_collect(page,true); // collect early so the page->used is accurate  \n  _mi_heap_area_init(&xarea.area, page);\n  return fun(heap, &xarea, arg);\n}\n\n// Visit all heap pages as areas\nstatic bool mi_heap_visit_areas(const mi_heap_t* heap, mi_heap_area_visit_fun* visitor, void* arg) {\n  if (visitor == NULL) return false;\n  return mi_heap_visit_pages((mi_heap_t*)heap, &mi_heap_visit_areas_page, true, (void*)(visitor), arg); // note: function pointer to void* :-{\n}\n\n// Just to pass arguments\ntypedef struct mi_visit_blocks_args_s {\n  bool  visit_blocks;\n  mi_block_visit_fun* visitor;\n  void* arg;\n} mi_visit_blocks_args_t;\n\nstatic bool mi_heap_area_visitor(const mi_heap_t* heap, const mi_heap_area_ex_t* xarea, void* arg) {\n  mi_visit_blocks_args_t* args = (mi_visit_blocks_args_t*)arg;\n  if (!args->visitor(heap, &xarea->area, NULL, xarea->area.block_size, args->arg)) return false;\n  if (args->visit_blocks) {\n    return _mi_heap_area_visit_blocks(&xarea->area, xarea->page, args->visitor, args->arg);\n  }\n  else {\n    return true;\n  }\n}\n\n// Visit all blocks in a heap\nbool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) {\n  mi_visit_blocks_args_t args = { visit_blocks, visitor, arg };\n  return mi_heap_visit_areas(heap, &mi_heap_area_visitor, &args);\n}\n\n\n\nstatic const mi_page_t* mi_safe_ptr_page(void* p) {\n  const mi_segment_t* const segment = _mi_ptr_segment(p);\n  if mi_unlikely(segment==NULL) return NULL;\n  #ifndef NDEBUG\n  if mi_unlikely(!mi_is_in_heap_region(p)) return NULL;\n  #endif\n  if mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie) return NULL;\n  return _mi_segment_page_of(segment, p);\n}\n\n// unsafe heap utilization function for DragonFly (see issue #1258)\n// If the page of pointer `p` belongs to `heap` (or `heap==NULL`) and has less than `perc_threshold` used blocks in its used area return `true`.\n// This function is unsafe in general as it assumes we are the only thread accessing the page of `p`.\nbool mi_unsafe_heap_page_is_under_utilized(mi_heap_t* heap, void* p, size_t perc_threshold) mi_attr_noexcept {\n  if (p==NULL) return false;\n  const mi_page_t* const page = mi_safe_ptr_page(p);   // Get the page containing this pointer\n  if (page==NULL || page->used==page->capacity || page->capacity < page->reserved) return false;\n  // If the page is the head of the queue, it is currently being used for \n  // allocations; we skip it to avoid immediate thrashing.\n  if (page->prev == NULL)  return false;\n\n  // match heap?\n  const mi_heap_t* const page_heap = mi_page_heap(page);\n  if (page_heap==NULL) return false;\n  if (heap!=NULL && page_heap!=heap) return false;\n    \n  // check utilization\n  if (page->capacity==0)   return false;\n  if (perc_threshold>=100) return true;\n  return (perc_threshold >= ((100UL*page->used) / page->capacity));\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/init.c",
      "sha256": "d1e5df48a718a2f623fb5c0a357793e6ebb70c23cffe0b32f4761a0d72d047eb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2022, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"\n\n#include <string.h>  // memcpy, memset\n#include <stdlib.h>  // atexit\n\n\n// Empty page used to initialize the small free pages array\nconst mi_page_t _mi_page_empty = {\n  0,\n  false, false, false, false,\n  0,       // capacity\n  0,       // reserved capacity\n  { 0 },   // flags\n  false,   // is_zero\n  0,       // retire_expire\n  NULL,    // free\n  NULL,    // local_free\n  0,       // used\n  0,       // block size shift\n  0,       // heap tag\n  0,       // block_size\n  NULL,    // page_start\n  #if (MI_PADDING || MI_ENCODE_FREELIST)\n  { 0, 0 },\n  #endif\n  MI_ATOMIC_VAR_INIT(0), // xthread_free\n  MI_ATOMIC_VAR_INIT(0), // xheap\n  NULL, NULL\n  , { 0 }  // padding\n};\n\n#define MI_PAGE_EMPTY() ((mi_page_t*)&_mi_page_empty)\n\n#if (MI_SMALL_WSIZE_MAX==128)\n#if (MI_PADDING>0) && (MI_INTPTR_SIZE >= 8)\n#define MI_SMALL_PAGES_EMPTY  { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() }\n#elif (MI_PADDING>0)\n#define MI_SMALL_PAGES_EMPTY  { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() }\n#else\n#define MI_SMALL_PAGES_EMPTY  { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY() }\n#endif\n#else\n#error \"define right initialization sizes corresponding to MI_SMALL_WSIZE_MAX\"\n#endif\n\n// Empty page queues for every bin\n#define QNULL(sz)  { NULL, NULL, (sz)*sizeof(uintptr_t) }\n#define MI_PAGE_QUEUES_EMPTY \\\n  { QNULL(1), \\\n    QNULL(     1), QNULL(     2), QNULL(     3), QNULL(     4), QNULL(     5), QNULL(     6), QNULL(     7), QNULL(     8), /* 8 */ \\\n    QNULL(    10), QNULL(    12), QNULL(    14), QNULL(    16), QNULL(    20), QNULL(    24), QNULL(    28), QNULL(    32), /* 16 */ \\\n    QNULL(    40), QNULL(    48), QNULL(    56), QNULL(    64), QNULL(    80), QNULL(    96), QNULL(   112), QNULL(   128), /* 24 */ \\\n    QNULL(   160), QNULL(   192), QNULL(   224), QNULL(   256), QNULL(   320), QNULL(   384), QNULL(   448), QNULL(   512), /* 32 */ \\\n    QNULL(   640), QNULL(   768), QNULL(   896), QNULL(  1024), QNULL(  1280), QNULL(  1536), QNULL(  1792), QNULL(  2048), /* 40 */ \\\n    QNULL(  2560), QNULL(  3072), QNULL(  3584), QNULL(  4096), QNULL(  5120), QNULL(  6144), QNULL(  7168), QNULL(  8192), /* 48 */ \\\n    QNULL( 10240), QNULL( 12288), QNULL( 14336), QNULL( 16384), QNULL( 20480), QNULL( 24576), QNULL( 28672), QNULL( 32768), /* 56 */ \\\n    QNULL( 40960), QNULL( 49152), QNULL( 57344), QNULL( 65536), QNULL( 81920), QNULL( 98304), QNULL(114688), QNULL(131072), /* 64 */ \\\n    QNULL(163840), QNULL(196608), QNULL(229376), QNULL(262144), QNULL(327680), QNULL(393216), QNULL(458752), QNULL(524288), /* 72 */ \\\n    QNULL(MI_MEDIUM_OBJ_WSIZE_MAX + 1  /* 655360, Huge queue */), \\\n    QNULL(MI_MEDIUM_OBJ_WSIZE_MAX + 2) /* Full queue */ }\n\n#define MI_STAT_COUNT_NULL()  {0,0,0}\n\n// Empty statistics\n#define MI_STATS_NULL  \\\n  MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \\\n  { 0 }, { 0 }, \\\n  MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \\\n  MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \\\n  { 0 }, { 0 }, { 0 }, { 0 }, \\\n  { 0 }, { 0 }, { 0 }, { 0 }, \\\n  \\\n  { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, \\\n  MI_INIT4(MI_STAT_COUNT_NULL), \\\n  { 0 }, { 0 }, { 0 }, { 0 },  \\\n  \\\n  { MI_INIT4(MI_STAT_COUNT_NULL) }, \\\n  { { 0 }, { 0 }, { 0 }, { 0 } }, \\\n  \\\n  { MI_INIT74(MI_STAT_COUNT_NULL) }, \\\n  { MI_INIT74(MI_STAT_COUNT_NULL) }\n\n\n// Empty slice span queues for every bin\n#define SQNULL(sz)  { NULL, NULL, sz }\n#define MI_SEGMENT_SPAN_QUEUES_EMPTY \\\n  { SQNULL(1), \\\n    SQNULL(     1), SQNULL(     2), SQNULL(     3), SQNULL(     4), SQNULL(     5), SQNULL(     6), SQNULL(     7), SQNULL(    10), /*  8 */ \\\n    SQNULL(    12), SQNULL(    14), SQNULL(    16), SQNULL(    20), SQNULL(    24), SQNULL(    28), SQNULL(    32), SQNULL(    40), /* 16 */ \\\n    SQNULL(    48), SQNULL(    56), SQNULL(    64), SQNULL(    80), SQNULL(    96), SQNULL(   112), SQNULL(   128), SQNULL(   160), /* 24 */ \\\n    SQNULL(   192), SQNULL(   224), SQNULL(   256), SQNULL(   320), SQNULL(   384), SQNULL(   448), SQNULL(   512), SQNULL(   640), /* 32 */ \\\n    SQNULL(   768), SQNULL(   896), SQNULL(  1024) /* 35 */ }\n\n\n// --------------------------------------------------------\n// Statically allocate an empty heap as the initial\n// thread local value for the default heap,\n// and statically allocate the backing heap for the main\n// thread so it can function without doing any allocation\n// itself (as accessing a thread local for the first time\n// may lead to allocation itself on some platforms)\n// --------------------------------------------------------\n\nmi_decl_cache_align const mi_heap_t _mi_heap_empty = {\n  NULL,\n  MI_ATOMIC_VAR_INIT(NULL),\n  0,                // tid\n  0,                // cookie\n  0,                // arena id\n  { 0, 0 },         // keys\n  { {0}, {0}, 0, true }, // random\n  0,                // page count\n  MI_BIN_FULL, 0,   // page retired min/max\n  0,                // pages_full_size\n  0, 0,             // generic count\n  NULL,             // next\n  false,            // can reclaim\n  0,                // tag\n  #if MI_GUARDED\n  0, 0, 0, 1,       // count is 1 so we never write to it (see `internal.h:mi_heap_malloc_use_guarded`)\n  #endif\n  MI_SMALL_PAGES_EMPTY,\n  MI_PAGE_QUEUES_EMPTY\n};\n\nstatic mi_decl_cache_align mi_subproc_t mi_subproc_default;\n\n#define tld_empty_stats  ((mi_stats_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,stats)))\n\nmi_decl_cache_align static const mi_tld_t tld_empty = {\n  0,\n  false,\n  NULL, NULL,\n  { MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, &mi_subproc_default, tld_empty_stats }, // segments\n  { sizeof(mi_stats_t), MI_STAT_VERSION, MI_STATS_NULL }       // stats\n};\n\nmi_threadid_t _mi_thread_id(void) mi_attr_noexcept {\n  mi_threadid_t tid = _mi_prim_thread_id();\n  mi_assert_internal( (tid & 0x03) == 0 ); // mimalloc reserves the bottom 2 bits\n  return tid;\n}\n\n// the thread-local default heap for allocation\nmi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty;\n\nextern mi_decl_hidden mi_heap_t _mi_heap_main;\n\nstatic mi_decl_cache_align mi_tld_t tld_main = {\n  0, false,\n  &_mi_heap_main, & _mi_heap_main,\n  { MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, &mi_subproc_default, &tld_main.stats }, // segments\n  { sizeof(mi_stats_t), MI_STAT_VERSION, MI_STATS_NULL }       // stats\n};\n\nmi_decl_cache_align mi_heap_t _mi_heap_main = {\n  &tld_main,\n  MI_ATOMIC_VAR_INIT(NULL),\n  0,                // thread id\n  0,                // initial cookie\n  0,                // arena id\n  { 0, 0 },         // the key of the main heap can be fixed (unlike page keys that need to be secure!)\n  { {0x846ca68b}, {0}, 0, true },  // random\n  0,                // page count\n  MI_BIN_FULL, 0,   // page retired min/max\n  0,                // pages_full_size\n  0, 0,             // generic count\n  NULL,             // next heap\n  false,            // can reclaim\n  0,                // tag\n  #if MI_GUARDED\n  0, 0, 0, 0,\n  #endif\n  MI_SMALL_PAGES_EMPTY,\n  MI_PAGE_QUEUES_EMPTY\n};\n\nbool _mi_process_is_initialized = false;  // set to `true` in `mi_process_init`.\n\nmi_stats_t _mi_stats_main = { sizeof(mi_stats_t), MI_STAT_VERSION, MI_STATS_NULL };\n\n#if MI_GUARDED\nmi_decl_export void mi_heap_guarded_set_sample_rate(mi_heap_t* heap, size_t sample_rate, size_t seed) {\n  heap->guarded_sample_rate  = sample_rate;\n  heap->guarded_sample_count = sample_rate;  // count down samples\n  if (heap->guarded_sample_rate > 1) {\n    if (seed == 0) {\n      seed = _mi_heap_random_next(heap);\n    }\n    heap->guarded_sample_count = (seed % heap->guarded_sample_rate) + 1;  // start at random count between 1 and `sample_rate`\n  }\n}\n\nmi_decl_export void mi_heap_guarded_set_size_bound(mi_heap_t* heap, size_t min, size_t max) {\n  heap->guarded_size_min = min;\n  heap->guarded_size_max = (min > max ? min : max);\n}\n\nvoid _mi_heap_guarded_init(mi_heap_t* heap) {\n  mi_heap_guarded_set_sample_rate(heap,\n    (size_t)mi_option_get_clamp(mi_option_guarded_sample_rate, 0, LONG_MAX),\n    (size_t)mi_option_get(mi_option_guarded_sample_seed));\n  mi_heap_guarded_set_size_bound(heap,\n    (size_t)mi_option_get_clamp(mi_option_guarded_min, 0, LONG_MAX),\n    (size_t)mi_option_get_clamp(mi_option_guarded_max, 0, LONG_MAX) );\n}\n#else\nmi_decl_export void mi_heap_guarded_set_sample_rate(mi_heap_t* heap, size_t sample_rate, size_t seed) {\n  MI_UNUSED(heap); MI_UNUSED(sample_rate); MI_UNUSED(seed);\n}\n\nmi_decl_export void mi_heap_guarded_set_size_bound(mi_heap_t* heap, size_t min, size_t max) {\n  MI_UNUSED(heap); MI_UNUSED(min); MI_UNUSED(max);\n}\nvoid _mi_heap_guarded_init(mi_heap_t* heap) {\n  MI_UNUSED(heap);\n}\n#endif\n\n\nstatic void mi_heap_main_init(void) {\n  if (_mi_heap_main.cookie == 0) {\n    _mi_heap_main.thread_id = _mi_thread_id();\n    _mi_heap_main.cookie = 1;\n    #if defined(_WIN32) && !defined(MI_SHARED_LIB)\n      _mi_random_init_weak(&_mi_heap_main.random);    // prevent allocation failure during bcrypt dll initialization with static linking\n    #else\n      _mi_random_init(&_mi_heap_main.random);\n    #endif\n    _mi_heap_main.cookie  = _mi_heap_random_next(&_mi_heap_main);\n    _mi_heap_main.keys[0] = _mi_heap_random_next(&_mi_heap_main);\n    _mi_heap_main.keys[1] = _mi_heap_random_next(&_mi_heap_main);\n    mi_lock_init(&mi_subproc_default.abandoned_os_lock);\n    mi_lock_init(&mi_subproc_default.abandoned_os_visit_lock);\n    _mi_heap_guarded_init(&_mi_heap_main);\n  }\n}\n\nmi_heap_t* _mi_heap_main_get(void) {\n  mi_heap_main_init();\n  return &_mi_heap_main;\n}\n\n/* -----------------------------------------------------------\n  Sub process\n----------------------------------------------------------- */\n\nmi_subproc_id_t mi_subproc_main(void) {\n  return NULL;\n}\n\nmi_subproc_id_t mi_subproc_new(void) {\n  mi_memid_t memid = _mi_memid_none();\n  mi_subproc_t* subproc = (mi_subproc_t*)_mi_arena_meta_zalloc(sizeof(mi_subproc_t), &memid);\n  if (subproc == NULL) return NULL;\n  subproc->memid = memid;\n  subproc->abandoned_os_list = NULL;\n  mi_lock_init(&subproc->abandoned_os_lock);\n  mi_lock_init(&subproc->abandoned_os_visit_lock);\n  return subproc;\n}\n\nmi_subproc_t* _mi_subproc_from_id(mi_subproc_id_t subproc_id) {\n  return (subproc_id == NULL ? &mi_subproc_default : (mi_subproc_t*)subproc_id);\n}\n\nvoid mi_subproc_delete(mi_subproc_id_t subproc_id) {\n  if (subproc_id == NULL) return;\n  mi_subproc_t* subproc = _mi_subproc_from_id(subproc_id);\n  if (subproc==NULL) return;\n  // check if there are no abandoned segments still..\n  bool safe_to_delete = false;\n  mi_lock(&subproc->abandoned_os_lock) {\n    if (subproc->abandoned_os_list == NULL) {\n      safe_to_delete = true;\n    }\n  }\n  if (!safe_to_delete) return;\n  // safe to release\n  // todo: should we refcount subprocesses?\n  mi_lock_done(&subproc->abandoned_os_lock);\n  mi_lock_done(&subproc->abandoned_os_visit_lock);\n  _mi_arena_meta_free(subproc, subproc->memid, sizeof(mi_subproc_t));\n}\n\nvoid mi_subproc_add_current_thread(mi_subproc_id_t subproc_id) {\n  mi_heap_t* heap = mi_heap_get_default();\n  if (heap == NULL) return;\n  mi_assert(heap->tld->segments.subproc == &mi_subproc_default);\n  if (heap->tld->segments.subproc != &mi_subproc_default) return;\n  heap->tld->segments.subproc = _mi_subproc_from_id(subproc_id);\n}\n\n\n\n/* -----------------------------------------------------------\n  Initialization and freeing of the thread local heaps\n----------------------------------------------------------- */\n\n// note: in x64 in release build `sizeof(mi_thread_data_t)` is under 4KiB (= OS page size).\ntypedef struct mi_thread_data_s {\n  mi_heap_t  heap;   // must come first due to cast in `_mi_heap_done`\n  mi_tld_t   tld;\n  mi_memid_t memid;  // must come last due to zero'ing\n} mi_thread_data_t;\n\n\n// Thread meta-data is allocated directly from the OS. For\n// some programs that do not use thread pools and allocate and\n// destroy many OS threads, this may causes too much overhead\n// per thread so we maintain a small cache of recently freed metadata.\n\n#define TD_CACHE_SIZE (32)\nstatic _Atomic(mi_thread_data_t*) td_cache[TD_CACHE_SIZE];\n\nstatic mi_thread_data_t* mi_thread_data_zalloc(void) {\n  // try to find thread metadata in the cache\n  mi_thread_data_t* td = NULL;\n  for (int i = 0; i < TD_CACHE_SIZE; i++) {\n    td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);\n    if (td != NULL) {\n      // found cached allocation, try use it\n      td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL);\n      if (td != NULL) {\n        _mi_memzero(td, offsetof(mi_thread_data_t,memid));\n        return td;\n      }\n    }\n  }\n\n  // if that fails, allocate as meta data\n  mi_memid_t memid;\n  td = (mi_thread_data_t*)_mi_os_zalloc(sizeof(mi_thread_data_t), &memid);\n  if (td == NULL) {\n    // if this fails, try once more. (issue #257)\n    td = (mi_thread_data_t*)_mi_os_zalloc(sizeof(mi_thread_data_t), &memid);\n    if (td == NULL) {\n      // really out of memory\n      _mi_error_message(ENOMEM, \"unable to allocate thread local heap metadata (%zu bytes)\\n\", sizeof(mi_thread_data_t));\n      return NULL;\n    }\n  }\n  td->memid = memid;\n  return td;\n}\n\nstatic void mi_thread_data_free( mi_thread_data_t* tdfree ) {\n  // try to add the thread metadata to the cache\n  for (int i = 0; i < TD_CACHE_SIZE; i++) {\n    mi_thread_data_t* td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);\n    if (td == NULL) {\n      mi_thread_data_t* expected = NULL;\n      if (mi_atomic_cas_ptr_weak_acq_rel(mi_thread_data_t, &td_cache[i], &expected, tdfree)) {\n        return;\n      }\n    }\n  }\n  // if that fails, just free it directly\n  _mi_os_free(tdfree, sizeof(mi_thread_data_t), tdfree->memid);\n}\n\nvoid _mi_thread_data_collect(void) {\n  // free all thread metadata from the cache\n  for (int i = 0; i < TD_CACHE_SIZE; i++) {\n    mi_thread_data_t* td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);\n    if (td != NULL) {\n      td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL);\n      if (td != NULL) {\n        _mi_os_free(td, sizeof(mi_thread_data_t), td->memid);\n      }\n    }\n  }\n}\n\n// Initialize the thread local default heap, called from `mi_thread_init`\nstatic bool _mi_thread_heap_init(void) {\n  if (mi_heap_is_initialized(mi_prim_get_default_heap())) return true;\n  if (_mi_is_main_thread()) {\n    // mi_assert_internal(_mi_heap_main.thread_id != 0);  // can happen on freeBSD where alloc is called before any initialization\n    // the main heap is statically allocated\n    mi_heap_main_init();\n    _mi_heap_set_default_direct(&_mi_heap_main);\n    //mi_assert_internal(_mi_heap_default->tld->heap_backing == mi_prim_get_default_heap());\n  }\n  else {\n    // use `_mi_os_alloc` to allocate directly from the OS\n    mi_thread_data_t* td = mi_thread_data_zalloc();\n    if (td == NULL) return false;\n\n    mi_tld_t*  tld = &td->tld;\n    mi_heap_t* heap = &td->heap;\n    _mi_tld_init(tld, heap);  // must be before `_mi_heap_init`\n    _mi_heap_init(heap, tld, _mi_arena_id_none(), false /* can reclaim */, 0 /* default tag */);\n    _mi_heap_set_default_direct(heap);\n  }\n  return false;\n}\n\n// initialize thread local data\nvoid _mi_tld_init(mi_tld_t* tld, mi_heap_t* bheap) {\n  _mi_memcpy_aligned(tld, &tld_empty, sizeof(mi_tld_t));\n  tld->heap_backing = bheap;\n  tld->heaps = NULL;\n  tld->segments.subproc = &mi_subproc_default;\n  tld->segments.stats = &tld->stats;\n}\n\n// Free the thread local default heap (called from `mi_thread_done`)\nstatic bool _mi_thread_heap_done(mi_heap_t* heap) {\n  if (!mi_heap_is_initialized(heap)) return true;\n\n  // reset default heap\n  _mi_heap_set_default_direct(_mi_is_main_thread() ? &_mi_heap_main : (mi_heap_t*)&_mi_heap_empty);\n\n  // switch to backing heap\n  heap = heap->tld->heap_backing;\n  if (!mi_heap_is_initialized(heap)) return false;\n\n  // delete all non-backing heaps in this thread\n  mi_heap_t* curr = heap->tld->heaps;\n  while (curr != NULL) {\n    mi_heap_t* next = curr->next; // save `next` as `curr` will be freed\n    if (curr != heap) {\n      mi_assert_internal(!mi_heap_is_backing(curr));\n      mi_heap_delete(curr);\n    }\n    curr = next;\n  }\n  mi_assert_internal(heap->tld->heaps == heap && heap->next == NULL);\n  mi_assert_internal(mi_heap_is_backing(heap));\n\n  // collect if not the main thread\n  if (heap != &_mi_heap_main) {\n    _mi_heap_collect_abandon(heap);\n  }\n\n  // merge stats\n  _mi_stats_done(&heap->tld->stats);\n\n  // free if not the main thread\n  if (heap != &_mi_heap_main) {\n    // the following assertion does not always hold for huge segments as those are always treated\n    // as abandoned: one may allocate it in one thread, but deallocate in another in which case\n    // the count can be too large or negative. todo: perhaps not count huge segments? see issue #363\n    // mi_assert_internal(heap->tld->segments.count == 0 || heap->thread_id != _mi_thread_id());\n    mi_thread_data_free((mi_thread_data_t*)heap);\n  }\n  else {\n    #if 0\n    // never free the main thread even in debug mode; if a dll is linked statically with mimalloc,\n    // there may still be delete/free calls after the mi_fls_done is called. Issue #207\n    _mi_heap_destroy_pages(heap);\n    mi_assert_internal(heap->tld->heap_backing == &_mi_heap_main);\n    #endif\n  }\n  return false;\n}\n\n\n\n// --------------------------------------------------------\n// Try to run `mi_thread_done()` automatically so any memory\n// owned by the thread but not yet released can be abandoned\n// and re-owned by another thread.\n//\n// 1. windows dynamic library:\n//     call from DllMain on DLL_THREAD_DETACH\n// 2. windows static library:\n//     use `FlsAlloc` to call a destructor when the thread is done\n// 3. unix, pthreads:\n//     use a pthread key to call a destructor when a pthread is done\n//\n// In the last two cases we also need to call `mi_process_init`\n// to set up the thread local keys.\n// --------------------------------------------------------\n\n// Set up handlers so `mi_thread_done` is called automatically\nstatic void mi_process_setup_auto_thread_done(void) {\n  mi_atomic_do_once {\n    _mi_prim_thread_init_auto_done();\n    _mi_heap_set_default_direct(&_mi_heap_main);\n  }\n}\n\n\nbool _mi_is_main_thread(void) {\n  return (_mi_heap_main.thread_id==0 || _mi_heap_main.thread_id == _mi_thread_id());\n}\n\nstatic _Atomic(size_t) thread_count = MI_ATOMIC_VAR_INIT(1);\n\nsize_t  _mi_current_thread_count(void) {\n  return mi_atomic_load_relaxed(&thread_count);\n}\n\n// This is called from the `mi_malloc_generic`\nvoid mi_thread_init(void) mi_attr_noexcept\n{\n  // ensure our process has started already\n  mi_process_init();\n\n  // initialize the thread local default heap\n  // (this will call `_mi_heap_set_default_direct` and thus set the\n  //  fiber/pthread key to a non-zero value, ensuring `_mi_thread_done` is called)\n  if (_mi_thread_heap_init()) return;  // returns true if already initialized\n\n  _mi_stat_increase(&_mi_stats_main.threads, 1);\n  mi_atomic_increment_relaxed(&thread_count);\n  //_mi_verbose_message(\"thread init: 0x%zx\\n\", _mi_thread_id());\n}\n\nvoid mi_thread_done(void) mi_attr_noexcept {\n  _mi_thread_done(NULL);\n}\n\nvoid _mi_thread_done(mi_heap_t* heap)\n{\n  // calling with NULL implies using the default heap\n  if (heap == NULL) {\n    heap = mi_prim_get_default_heap();\n    if (heap == NULL) return;\n  }\n\n  // prevent re-entrancy through heap_done/heap_set_default_direct (issue #699)\n  if (!mi_heap_is_initialized(heap)) {\n    return;\n  }\n\n  // adjust stats\n  mi_atomic_decrement_relaxed(&thread_count);\n  _mi_stat_decrease(&_mi_stats_main.threads, 1);\n\n  // check thread-id as on Windows shutdown with FLS the main (exit) thread may call this on thread-local heaps...\n  if (heap->thread_id != _mi_thread_id()) return;\n\n  // abandon the thread local heap\n  if (_mi_thread_heap_done(heap)) return;  // returns true if already ran\n}\n\nvoid _mi_heap_set_default_direct(mi_heap_t* heap)  {\n  mi_assert_internal(heap != NULL);\n  #if defined(MI_TLS_SLOT)\n  mi_prim_tls_slot_set(MI_TLS_SLOT,heap);\n  #elif defined(MI_TLS_PTHREAD_SLOT_OFS)\n  *mi_prim_tls_pthread_heap_slot() = heap;\n  #elif defined(MI_TLS_PTHREAD)\n  // we use _mi_heap_default_key\n  #else\n  _mi_heap_default = heap;\n  #endif\n\n  // ensure the default heap is passed to `_mi_thread_done`\n  // setting to a non-NULL value also ensures `mi_thread_done` is called.\n  _mi_prim_thread_associate_default_heap(heap);\n}\n\nvoid mi_thread_set_in_threadpool(void) mi_attr_noexcept {\n  // nothing\n}\n\n// --------------------------------------------------------\n// Run functions on process init/done, and thread init/done\n// --------------------------------------------------------\nstatic bool os_preloading = true;    // true until this module is initialized\n\n// Returns true if this module has not been initialized; Don't use C runtime routines until it returns false.\nbool mi_decl_noinline _mi_preloading(void) {\n  return os_preloading;\n}\n\n// Returns true if mimalloc was redirected\nmi_decl_nodiscard bool mi_is_redirected(void) mi_attr_noexcept {\n  return _mi_is_redirected();\n}\n\n// Called once by the process loader from `src/prim/prim.c`\nvoid _mi_auto_process_init(void) {\n  mi_heap_main_init();\n  #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD)\n  volatile mi_heap_t* dummy = _mi_heap_default; // access TLS to allocate it before setting tls_initialized to true;\n  if (dummy == NULL) return;                    // use dummy or otherwise the access may get optimized away (issue #697)\n  #endif\n  os_preloading = false;\n  mi_assert_internal(_mi_is_main_thread());\n  _mi_options_init();\n  mi_process_setup_auto_thread_done();\n  mi_process_init();\n  if (_mi_is_redirected()) _mi_verbose_message(\"malloc is redirected.\\n\");\n\n  // show message from the redirector (if present)\n  const char* msg = NULL;\n  _mi_allocator_init(&msg);\n  if (msg != NULL && (mi_option_is_enabled(mi_option_verbose) || mi_option_is_enabled(mi_option_show_errors))) {\n    _mi_fputs(NULL,NULL,NULL,msg);\n  }\n\n  // reseed random\n  _mi_random_reinit_if_weak(&_mi_heap_main.random);\n}\n\n#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))\n#include <intrin.h>\nmi_decl_cache_align bool _mi_cpu_has_fsrm = false;\nmi_decl_cache_align bool _mi_cpu_has_erms = false;\n\nstatic void mi_detect_cpu_features(void) {\n  // FSRM for fast short rep movsb/stosb support (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017))\n  // EMRS for fast enhanced rep movsb/stosb support\n  int32_t cpu_info[4];\n  __cpuid(cpu_info, 7);\n  _mi_cpu_has_fsrm = ((cpu_info[3] & (1 << 4)) != 0); // bit 4 of EDX : see <https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features>\n  _mi_cpu_has_erms = ((cpu_info[1] & (1 << 9)) != 0); // bit 9 of EBX : see <https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features>\n}\n#else\nstatic void mi_detect_cpu_features(void) {\n  // nothing\n}\n#endif\n\n// Initialize the process; called by thread_init or the process loader\nstatic void mi_process_init_once(void) mi_attr_noexcept {\n  _mi_process_is_initialized = true;  \n  _mi_verbose_message(\"process init: 0x%zx\\n\", _mi_thread_id());\n  mi_process_setup_auto_thread_done();\n\n  mi_detect_cpu_features();\n  _mi_os_init();\n  mi_heap_main_init();\n  mi_thread_init();\n\n  #if defined(_WIN32)\n  // On windows, when building as a static lib the FLS cleanup happens to early for the main thread.\n  // To avoid this, set the FLS value for the main thread to NULL so the fls cleanup\n  // will not call _mi_thread_done on the (still executing) main thread. See issue #508.\n  _mi_prim_thread_associate_default_heap(NULL);\n  #endif\n\n  mi_stats_reset();  // only call stat reset *after* thread init (or the heap tld == NULL)\n  mi_track_init();\n\n  if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {\n    size_t pages = mi_option_get_clamp(mi_option_reserve_huge_os_pages, 0, 128*1024);\n    int reserve_at  = (int)mi_option_get_clamp(mi_option_reserve_huge_os_pages_at, -1, INT_MAX);\n    if (reserve_at != -1) {\n      mi_reserve_huge_os_pages_at(pages, reserve_at, pages*500);\n    } else {\n      mi_reserve_huge_os_pages_interleave(pages, 0, pages*500);\n    }\n  }\n  if (mi_option_is_enabled(mi_option_reserve_os_memory)) {\n    long ksize = mi_option_get(mi_option_reserve_os_memory);\n    if (ksize > 0) {\n      mi_reserve_os_memory((size_t)ksize*MI_KiB, true /* commit? */, true /* allow large pages? */);\n    }\n  }\n}\n\n// Initialize the process; called by thread_init or the process loader\nvoid mi_process_init(void) mi_attr_noexcept {\n  #if _MSC_VER < 1920\n\tmi_heap_main_init(); // vs2017 can dynamically re-initialize _mi_heap_main\n\t#endif\n  mi_atomic_do_once {\n    mi_process_init_once();\n  }\n}\n\n// Called when the process is done (cdecl as it is used with `at_exit` on some platforms)\nvoid mi_cdecl mi_process_done(void) mi_attr_noexcept {\n  // only shutdown if we were initialized\n  if (!_mi_process_is_initialized) return;\n  // ensure we are called once\n  static bool process_done = false;\n  if (process_done) return;\n  process_done = true;\n\n  // get the default heap so we don't need to acces thread locals anymore\n  mi_heap_t* heap = mi_prim_get_default_heap();  // use prim to not initialize any heap\n  mi_assert_internal(heap != NULL);\n\n  // release any thread specific resources and ensure _mi_thread_done is called on all but the main thread\n  _mi_prim_thread_done_auto_done();\n\n\n  #ifndef MI_SKIP_COLLECT_ON_EXIT\n    #if (MI_DEBUG || !defined(MI_SHARED_LIB))\n    // free all memory if possible on process exit. This is not needed for a stand-alone process\n    // but should be done if mimalloc is statically linked into another shared library which\n    // is repeatedly loaded/unloaded, see issue #281.\n    mi_heap_collect(heap, true /* force */ );\n    #endif\n  #endif\n\n  // done with tracking tools\n  mi_track_done()\n\n  // Forcefully release all retained memory; this can be dangerous in general if overriding regular malloc/free\n  // since after process_done there might still be other code running that calls `free` (like at_exit routines,\n  // or C-runtime termination code.\n  if (mi_option_is_enabled(mi_option_destroy_on_exit)) {\n    mi_heap_collect(heap, true /* force */);\n    _mi_heap_unsafe_destroy_all(heap);     // forcefully release all memory held by all heaps (of this thread only!)\n    _mi_arena_unsafe_destroy_all();\n    _mi_segment_map_unsafe_destroy();\n  }\n\n  if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) {\n    mi_stats_print(NULL);\n  }\n  _mi_allocator_done();\n  _mi_verbose_message(\"process done: 0x%zx\\n\", _mi_heap_main.thread_id);\n  os_preloading = true; // don't call the C runtime anymore\n}\n\nvoid mi_cdecl _mi_auto_process_done(void) mi_attr_noexcept {\n  if (_mi_option_get_fast(mi_option_destroy_on_exit)>1) return;\n  mi_process_done();\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/libc.c",
      "sha256": "b86471b36d9a9e216e29a8575f586c25428f9366975ed4068881e372d64abce3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// --------------------------------------------------------\n// This module defines various std libc functions to reduce\n// the dependency on libc, and also prevent errors caused\n// by some libc implementations when called before `main`\n// executes (due to malloc redirection)\n// --------------------------------------------------------\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"      // mi_prim_getenv\n\nchar _mi_toupper(char c) {\n  if (c >= 'a' && c <= 'z') return (c - 'a' + 'A');\n                       else return c;\n}\n\nint _mi_strnicmp(const char* s, const char* t, size_t n) {\n  mi_assert_internal(s!=NULL && t!=NULL);\n  if (n == 0) return 0;\n  for (; *s != 0 && *t != 0 && n > 0; s++, t++, n--) {\n    if (_mi_toupper(*s) != _mi_toupper(*t)) break;\n  }\n  return (n == 0 ? 0 : *s - *t);\n}\n\nbool _mi_streq(const char* s, const char* t) {\n  if (s==NULL && t==NULL) return true;\n  if (s==NULL || t==NULL) return false;\n  for (; *s != 0 && *t != 0; s++, t++) {\n    if (*s != *t) break;\n  }\n  return (*s == *t);\n}\n\nvoid _mi_strlcpy(char* dest, const char* src, size_t dest_size) {\n  if (dest==NULL || src==NULL || dest_size == 0) return;\n  // copy until end of src, or when dest is (almost) full\n  while (*src != 0 && dest_size > 1) {\n    *dest++ = *src++;\n    dest_size--;\n  }\n  // always zero terminate\n  *dest = 0;\n}\n\nvoid _mi_strlcat(char* dest, const char* src, size_t dest_size) {\n  if (dest==NULL || src==NULL || dest_size == 0) return;\n  // find end of string in the dest buffer\n  while (*dest != 0 && dest_size > 1) {\n    dest++;\n    dest_size--;\n  }\n  // and catenate\n  _mi_strlcpy(dest, src, dest_size);\n}\n\nsize_t _mi_strnlen(const char* s, size_t max_len) {\n  if (s==NULL) return 0;\n  size_t len = 0;\n  while(s[len] != 0 && len < max_len) { len++; }\n  return len;\n}\n\nsize_t _mi_strlen(const char* s) {\n  return _mi_strnlen(s,PTRDIFF_MAX);\n}\n\n#ifdef MI_NO_GETENV\nbool _mi_getenv(const char* name, char* result, size_t result_size) {\n  MI_UNUSED(name);\n  MI_UNUSED(result);\n  MI_UNUSED(result_size);\n  return false;\n}\n#else\nbool _mi_getenv(const char* name, char* result, size_t result_size) {\n  if (name==NULL || result == NULL || result_size < 64) return false;\n  return _mi_prim_getenv(name,result,result_size);\n}\n#endif\n\n\n// --------------------------------------------------------\n// Define our own primitives for doing an action once\n// --------------------------------------------------------\n\n// Returns `true` only on the first invocation, signifying we can execute an action once.\n// If it returns `true`, the caller should call `_mi_atomic_once_release` after performing the action.\n// Other threads (than the initial thread that entered) will block until `_mi_atomic_once_release` has been called.\nbool _mi_atomic_once_enter(mi_atomic_once_t* once) {\n  const uintptr_t once_tid = mi_atomic_load_acquire(&once->tid);\n  if mi_likely(once_tid == 1) {\n    return false; // already executed\n  }\n  const mi_threadid_t current_tid = _mi_thread_id();\n  if (once_tid == current_tid) {\n    return false; // recursive invocation; we need this for process_init for example\n  }  \n\n  mi_lock_acquire(&once->lock);\n  uintptr_t expected = 0;\n  if (mi_atomic_cas_strong_acq_rel(&once->tid, &expected, current_tid)) {  // could use atomic_load/store as well\n    return true;  // should execute and release\n  } \n  else {\n    mi_lock_release(&once->lock);\n    return false; // already another thread entered and released\n  }\n}\n\nvoid _mi_atomic_once_release(mi_atomic_once_t* once) {\n  if (mi_atomic_load_acquire(&once->tid)>1) {  // paranoia\n    mi_atomic_store_release(&once->tid,1);     // done executing\n    mi_lock_release(&once->lock);\n  }  \n}\n\n\n// --------------------------------------------------------\n// Define our own limited `_mi_vsnprintf` and `_mi_snprintf`\n// This is mostly to avoid calling these when libc is not yet\n// initialized (and to reduce dependencies)\n//\n// format:      d i, p x u, s\n// prec:        z l ll L\n// width:       10\n// align-left:  -\n// fill:        0\n// plus:        +\n// --------------------------------------------------------\n\nstatic void mi_outc(char c, char** out, char* end) {\n  char* p = *out;\n  if (p >= end) return;\n  *p = c;\n  *out = p + 1;\n}\n\nstatic void mi_outs(const char* s, char** out, char* end) {\n  if (s == NULL) return;\n  char* p = *out;\n  while (*s != 0 && p < end) {\n    *p++ = *s++;\n  }\n  *out = p;\n}\n\nstatic void mi_out_fill(char fill, size_t len, char** out, char* end) {\n  char* p = *out;\n  for (size_t i = 0; i < len && p < end; i++) {\n    *p++ = fill;\n  }\n  *out = p;\n}\n\nstatic void mi_out_alignright(char fill, char* start, size_t len, size_t extra, char* end) {\n  if (len == 0 || extra == 0) return;\n  if (start + len + extra >= end) return;\n  // move `len` characters to the right (in reverse since it can overlap)\n  for (size_t i = 1; i <= len; i++) {\n    start[len + extra - i] = start[len - i];\n  }\n  // and fill the start\n  for (size_t i = 0; i < extra; i++) {\n    start[i] = fill;\n  }\n}\n\n\nstatic void mi_out_num(uintmax_t x, size_t base, char prefix, char** out, char* end)\n{\n  if (x == 0 || base == 0 || base > 16) {\n    if (prefix != 0) { mi_outc(prefix, out, end); }\n    mi_outc('0',out,end);\n  }\n  else {\n    // output digits in reverse\n    char* start = *out;\n    while (x > 0) {\n      char digit = (char)(x % base);\n      mi_outc((digit <= 9 ? '0' + digit : 'A' + digit - 10),out,end);\n      x = x / base;\n    }\n    if (prefix != 0) {\n      mi_outc(prefix, out, end);\n    }\n    size_t len = *out - start;\n    // and reverse in-place\n    for (size_t i = 0; i < (len / 2); i++) {\n      char c = start[len - i - 1];\n      start[len - i - 1] = start[i];\n      start[i] = c;\n    }\n  }\n}\n\n\n#define MI_NEXTC()  c = *in; if (c==0) break; in++;\n\nint _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args) {\n  if (buf == NULL || bufsize == 0 || fmt == NULL) return 0;\n  buf[bufsize - 1] = 0;\n  char* const end = buf + (bufsize - 1);\n  const char* in = fmt;\n  char* out = buf;\n  while (true) {\n    if (out >= end) break;\n    char c;\n    MI_NEXTC();\n    if (c != '%') {\n      if ((c >= ' ' && c <= '~') || c=='\\n' || c=='\\r' || c=='\\t') { // output visible ascii or standard control only\n        mi_outc(c, &out, end);\n      }\n    }\n    else {\n      MI_NEXTC();\n      char   fill = ' ';\n      size_t width = 0;\n      char   numtype = 'd';\n      char   numplus = 0;\n      bool   alignright = true;\n      if (c == '+' || c == ' ') { numplus = c; MI_NEXTC(); }\n      if (c == '-') { alignright = false; MI_NEXTC(); }\n      if (c == '0') { fill = '0'; MI_NEXTC(); }\n      if (c >= '1' && c <= '9') {\n        width = (c - '0'); MI_NEXTC();\n        while (c >= '0' && c <= '9') {\n          width = (10 * width) + (c - '0'); MI_NEXTC();\n        }\n        if (c == 0) break;  // extra check due to while\n      }\n      if (c == 'z' || c == 't' || c == 'L') { numtype = c; MI_NEXTC(); }\n      else if (c == 'l') {\n        numtype = c; MI_NEXTC();\n        if (c == 'l') { numtype = 'L'; MI_NEXTC(); }\n      }\n\n      char* start = out;\n      if (c == 's') {\n        // string\n        const char* s = va_arg(args, const char*);\n        mi_outs(s, &out, end);\n      }\n      else if (c == 'p' || c == 'x' || c == 'u') {\n        // unsigned\n        uintmax_t x = 0;\n        if (c == 'x' || c == 'u') {\n          if (numtype == 'z')       x = va_arg(args, size_t);\n          else if (numtype == 't')  x = va_arg(args, uintptr_t); // unsigned ptrdiff_t\n          else if (numtype == 'L')  x = va_arg(args, unsigned long long);\n          else if (numtype == 'l')  x = va_arg(args, unsigned long);\n                               else x = va_arg(args, unsigned int);\n        }\n        else if (c == 'p') {\n          void* const p = va_arg(args, void*);\n          x = (uintptr_t)p;\n          mi_outs(\"0x\", &out, end);\n          start = out;\n          width = (width >= 2 ? width - 2 : 0);\n        }\n        if (width == 0 && (c == 'x' || c == 'p')) {\n          if (c == 'p')   { width = 2 * (x <= UINT32_MAX ? 4 : ((x >> 16) <= UINT32_MAX ? 6 : sizeof(void*))); }\n          if (width == 0) { width = 2; }\n          fill = '0';\n        }\n        mi_out_num(x, (c == 'x' || c == 'p' ? 16 : 10), numplus, &out, end);\n      }\n      else if (c == 'i' || c == 'd') {\n        // signed\n        intmax_t x = 0;\n        if (numtype == 'z')       x = va_arg(args, intptr_t );\n        else if (numtype == 't')  x = va_arg(args, ptrdiff_t);\n        else if (numtype == 'L')  x = va_arg(args, long long);\n        else if (numtype == 'l')  x = va_arg(args, long);\n                             else x = va_arg(args, int);\n        char pre = 0;\n        if (x < 0) {\n          pre = '-';\n          if (x > INTMAX_MIN) { x = -x; }\n        }\n        else if (numplus != 0) {\n          pre = numplus;\n        }\n        mi_out_num((uintmax_t)x, 10, pre, &out, end);\n      }\n      else if (c >= ' ' && c <= '~') {\n        // unknown format\n        mi_outc('%', &out, end);\n        mi_outc(c, &out, end);\n      }\n\n      // fill & align\n      mi_assert_internal(out <= end);\n      mi_assert_internal(out >= start);\n      const size_t len = out - start;\n      if (len < width) {\n        mi_out_fill(fill, width - len, &out, end);\n        if (alignright && out <= end) {\n          mi_out_alignright(fill, start, len, width - len, end);\n        }\n      }\n    }\n  }\n  mi_assert_internal(out <= end);\n  *out = 0;\n  return (int)(out - buf);\n}\n\nint _mi_snprintf(char* buf, size_t buflen, const char* fmt, ...) {\n  va_list args;\n  va_start(args, fmt);\n  const int written = _mi_vsnprintf(buf, buflen, fmt, args);\n  va_end(args);\n  return written;\n}\n\n\n#if MI_SIZE_SIZE == 4\n#define mi_mask_even_bits32      (0x55555555)\n#define mi_mask_even_pairs32     (0x33333333)\n#define mi_mask_even_nibbles32   (0x0F0F0F0F)\n\n// sum of all the bytes in `x` if it is guaranteed that the sum < 256!\nstatic size_t mi_byte_sum32(uint32_t x) {\n  // perform `x * 0x01010101`: the highest byte contains the sum of all bytes.\n  x += (x << 8);\n  x += (x << 16);\n  return (size_t)(x >> 24);\n}\n\nstatic size_t mi_popcount_generic32(uint32_t x) {\n  // first count each 2-bit group `a`, where: a==0b00 -> 00, a==0b01 -> 01, a==0b10 -> 01, a==0b11 -> 10\n  // in other words, `a - (a>>1)`; to do this in parallel, we need to mask to prevent spilling a bit pair\n  // into the lower bit-pair:\n  x = x - ((x >> 1) & mi_mask_even_bits32);\n  // add the 2-bit pair results\n  x = (x & mi_mask_even_pairs32) + ((x >> 2) & mi_mask_even_pairs32);\n  // add the 4-bit nibble results\n  x = (x + (x >> 4)) & mi_mask_even_nibbles32;\n  // each byte now has a count of its bits, we can sum them now:\n  return mi_byte_sum32(x);\n}\n\nmi_decl_noinline size_t _mi_popcount_generic(size_t x) {\n  return mi_popcount_generic32(x);\n}\n\n#else\n#define mi_mask_even_bits64      (0x5555555555555555)\n#define mi_mask_even_pairs64     (0x3333333333333333)\n#define mi_mask_even_nibbles64   (0x0F0F0F0F0F0F0F0F)\n\n// sum of all the bytes in `x` if it is guaranteed that the sum < 256!\nstatic size_t mi_byte_sum64(uint64_t x) {\n  x += (x << 8);\n  x += (x << 16);\n  x += (x << 32);\n  return (size_t)(x >> 56);\n}\n\nstatic size_t mi_popcount_generic64(uint64_t x) {\n  x = x - ((x >> 1) & mi_mask_even_bits64);\n  x = (x & mi_mask_even_pairs64) + ((x >> 2) & mi_mask_even_pairs64);\n  x = (x + (x >> 4)) & mi_mask_even_nibbles64;\n  return mi_byte_sum64(x);\n}\n\nmi_decl_noinline size_t _mi_popcount_generic(size_t x) {\n  return mi_popcount_generic64(x);\n}\n#endif\n\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/options.c",
      "sha256": "0efe6854ea11d7ba33d4387abb62f28aef36e494898fd1544383da4945b36d44",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2021, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"  // mi_prim_out_stderr\n\n#include <stdio.h>      // stdin/stdout\n#include <stdlib.h>     // abort\n\n\n\nstatic long mi_max_error_count   = 16; // stop outputting errors after this (use < 0 for no limit)\nstatic long mi_max_warning_count = 16; // stop outputting warnings after this (use < 0 for no limit)\n\nstatic void mi_add_stderr_output(void);\n\nint mi_version(void) mi_attr_noexcept {\n  return MI_MALLOC_VERSION;\n}\n\n\n// --------------------------------------------------------\n// Options\n// These can be accessed by multiple threads and may be\n// concurrently initialized, but an initializing data race\n// is ok since they resolve to the same value.\n// --------------------------------------------------------\ntypedef enum mi_init_e {\n  UNINIT,       // not yet initialized\n  DEFAULTED,    // not found in the environment, use default value\n  INITIALIZED   // found in environment or set explicitly\n} mi_init_t;\n\ntypedef struct mi_option_desc_s {\n  long        value;  // the value\n  mi_init_t   init;   // is it initialized yet? (from the environment)\n  mi_option_t option; // for debugging: the option index should match the option\n  const char* name;   // option name without `mimalloc_` prefix\n  const char* legacy_name; // potential legacy option name\n} mi_option_desc_t;\n\n#define MI_OPTION(opt)                  mi_option_##opt, #opt, NULL\n#define MI_OPTION_LEGACY(opt,legacy)    mi_option_##opt, #opt, #legacy\n\n// Some options can be set at build time for statically linked libraries\n// (use `-DMI_EXTRA_CPPDEFS=\"opt1=val1;opt2=val2\"`)\n//\n// This is useful if we cannot pass them as environment variables\n// (and setting them programmatically would be too late)\n\n#ifndef MI_DEFAULT_VERBOSE\n#define MI_DEFAULT_VERBOSE 0\n#endif\n\n#ifndef MI_DEFAULT_EAGER_COMMIT\n#define MI_DEFAULT_EAGER_COMMIT 1\n#endif\n\n#ifndef MI_DEFAULT_ARENA_EAGER_COMMIT\n#define MI_DEFAULT_ARENA_EAGER_COMMIT 2\n#endif\n\n// in KiB\n#ifndef MI_DEFAULT_ARENA_RESERVE\n #if (MI_INTPTR_SIZE>4)\n  #define MI_DEFAULT_ARENA_RESERVE 1024L*1024L\n #else\n  #define MI_DEFAULT_ARENA_RESERVE 128L*1024L\n #endif\n#endif\n\n#ifndef MI_DEFAULT_DISALLOW_ARENA_ALLOC\n#define MI_DEFAULT_DISALLOW_ARENA_ALLOC 0\n#endif\n\n#ifndef MI_DEFAULT_ALLOW_LARGE_OS_PAGES\n#define MI_DEFAULT_ALLOW_LARGE_OS_PAGES 0\n#endif\n\n#ifndef MI_DEFAULT_RESERVE_HUGE_OS_PAGES\n#define MI_DEFAULT_RESERVE_HUGE_OS_PAGES 0\n#endif\n\n#ifndef MI_DEFAULT_RESERVE_OS_MEMORY\n#define MI_DEFAULT_RESERVE_OS_MEMORY 0\n#endif\n\n#ifndef MI_DEFAULT_GUARDED_SAMPLE_RATE\n#if MI_GUARDED && !MI_DEBUG\n#define MI_DEFAULT_GUARDED_SAMPLE_RATE 4000\n#else\n#define MI_DEFAULT_GUARDED_SAMPLE_RATE 0\n#endif\n#endif\n\n\n#ifndef MI_DEFAULT_ALLOW_THP\n#if defined(__ANDROID__)\n#define MI_DEFAULT_ALLOW_THP  0\n#else\n#define MI_DEFAULT_ALLOW_THP  1\n#endif\n#endif\n\n// Static options\nstatic mi_option_desc_t options[_mi_option_last] =\n{\n  // stable options\n  #if MI_DEBUG || defined(MI_SHOW_ERRORS)\n  { 1, UNINIT, MI_OPTION(show_errors) },\n  #else\n  { 0, UNINIT, MI_OPTION(show_errors) },\n  #endif\n  { 0, UNINIT, MI_OPTION(show_stats) },\n  { MI_DEFAULT_VERBOSE, UNINIT, MI_OPTION(verbose) },\n\n  // some of the following options are experimental and not all combinations are allowed.\n  { MI_DEFAULT_EAGER_COMMIT,\n       UNINIT, MI_OPTION(eager_commit) },               // commit per segment directly (4MiB)  (but see also `eager_commit_delay`)\n  { MI_DEFAULT_ARENA_EAGER_COMMIT,\n       UNINIT, MI_OPTION_LEGACY(arena_eager_commit,eager_region_commit) }, // eager commit arena's? 2 is used to enable this only on an OS that has overcommit (i.e. linux)\n  { 1, UNINIT, MI_OPTION_LEGACY(purge_decommits,reset_decommits) },        // purge decommits memory (instead of reset) (note: on linux this uses MADV_DONTNEED for decommit)\n  { MI_DEFAULT_ALLOW_LARGE_OS_PAGES,\n       UNINIT, MI_OPTION_LEGACY(allow_large_os_pages,large_os_pages) },    // use large OS pages, use only with eager commit to prevent fragmentation of VMA's\n  { MI_DEFAULT_RESERVE_HUGE_OS_PAGES,\n       UNINIT, MI_OPTION(reserve_huge_os_pages) },      // per 1GiB huge pages\n  {-1, UNINIT, MI_OPTION(reserve_huge_os_pages_at) },   // reserve huge pages at node N\n  { MI_DEFAULT_RESERVE_OS_MEMORY,\n       UNINIT, MI_OPTION(reserve_os_memory)     },      // reserve N KiB OS memory in advance (use `option_get_size`)\n  { 0, UNINIT, MI_OPTION(deprecated_segment_cache) },   // cache N segments per thread\n  { 0, UNINIT, MI_OPTION(deprecated_page_reset) },      // reset page memory on free\n  { 0, UNINIT, MI_OPTION_LEGACY(abandoned_page_purge,abandoned_page_reset) },       // reset free page memory when a thread terminates\n  { 0, UNINIT, MI_OPTION(deprecated_segment_reset) },   // reset segment memory on free (needs eager commit)\n#if defined(__NetBSD__)\n  { 0, UNINIT, MI_OPTION(eager_commit_delay) },         // the first N segments per thread are not eagerly committed\n#else\n  { 1, UNINIT, MI_OPTION(eager_commit_delay) },         // the first N segments per thread are not eagerly committed (but per page in the segment on demand)\n#endif\n  { 10,  UNINIT, MI_OPTION_LEGACY(purge_delay,reset_delay) },  // purge delay in milli-seconds\n  { 0,   UNINIT, MI_OPTION(use_numa_nodes) },           // 0 = use available numa nodes, otherwise use at most N nodes.\n  { 0,   UNINIT, MI_OPTION_LEGACY(disallow_os_alloc,limit_os_alloc) },           // 1 = do not use OS memory for allocation (but only reserved arenas)\n  { 100, UNINIT, MI_OPTION(os_tag) },                   // only apple specific for now but might serve more or less related purpose\n  { 32,  UNINIT, MI_OPTION(max_errors) },               // maximum errors that are output\n  { 32,  UNINIT, MI_OPTION(max_warnings) },             // maximum warnings that are output\n  { 10,  UNINIT, MI_OPTION(max_segment_reclaim)},       // max. percentage of the abandoned segments to be reclaimed per try.\n  { 0,   UNINIT, MI_OPTION(destroy_on_exit)},           // release all OS memory on process exit; careful with dangling pointer or after-exit frees!\n  { MI_DEFAULT_ARENA_RESERVE, UNINIT, MI_OPTION(arena_reserve) }, // reserve memory N KiB at a time (=1GiB) (use `option_get_size`)\n  { 10,  UNINIT, MI_OPTION(arena_purge_mult) },         // purge delay multiplier for arena's\n  { 1,   UNINIT, MI_OPTION_LEGACY(purge_extend_delay, decommit_extend_delay) },\n  { 0,   UNINIT, MI_OPTION(abandoned_reclaim_on_free) },// reclaim an abandoned segment on a free\n  { MI_DEFAULT_DISALLOW_ARENA_ALLOC,   UNINIT, MI_OPTION(disallow_arena_alloc) }, // 1 = do not use arena's for allocation (except if using specific arena id's)\n  { 400, UNINIT, MI_OPTION(retry_on_oom) },             // windows only: retry on out-of-memory for N milli seconds (=400), set to 0 to disable retries.\n#if defined(MI_VISIT_ABANDONED)\n  { 1,   INITIALIZED, MI_OPTION(visit_abandoned) },     // allow visiting heap blocks in abandoned segments; requires taking locks during reclaim.\n#else\n  { 0,   UNINIT, MI_OPTION(visit_abandoned) },\n#endif\n  { 0,   UNINIT, MI_OPTION(guarded_min) },              // only used when building with MI_GUARDED: minimal rounded object size for guarded objects\n  { MI_GiB, UNINIT, MI_OPTION(guarded_max) },           // only used when building with MI_GUARDED: maximal rounded object size for guarded objects\n  { 0,   UNINIT, MI_OPTION(guarded_precise) },          // disregard minimal alignment requirement to always place guarded blocks exactly in front of a guard page (=0)\n  { MI_DEFAULT_GUARDED_SAMPLE_RATE,\n         UNINIT, MI_OPTION(guarded_sample_rate)},       // 1 out of N allocations in the min/max range will be guarded (=4000)\n  { 0,   UNINIT, MI_OPTION(guarded_sample_seed)},\n  { 0,   UNINIT, MI_OPTION(target_segments_per_thread) }, // abandon segments beyond this point, or 0 to disable.\n  { 10000, UNINIT, MI_OPTION(generic_collect) },          // collect heaps every N (=10000) generic allocation calls\n  { MI_DEFAULT_ALLOW_THP, \n         UNINIT, MI_OPTION(allow_thp) }                 // allow transparent huge pages?\n};\n\nstatic void mi_option_init(mi_option_desc_t* desc);\n\nstatic bool mi_option_has_size_in_kib(mi_option_t option) {\n  return (option == mi_option_reserve_os_memory || option == mi_option_arena_reserve);\n}\n\nvoid _mi_options_init(void) {\n  // called on process load\n  mi_add_stderr_output(); // now it safe to use stderr for output\n  for(int i = 0; i < _mi_option_last; i++ ) {\n    mi_option_t option = (mi_option_t)i;\n    long l = mi_option_get(option); MI_UNUSED(l); // initialize\n  }\n  mi_max_error_count = mi_option_get(mi_option_max_errors);\n  mi_max_warning_count = mi_option_get(mi_option_max_warnings);\n  #if MI_GUARDED\n  if (mi_option_get(mi_option_guarded_sample_rate) > 0) {\n    if (mi_option_is_enabled(mi_option_allow_large_os_pages)) {\n      mi_option_disable(mi_option_allow_large_os_pages);\n      _mi_warning_message(\"option 'allow_large_os_pages' is disabled to allow for guarded objects\\n\");\n    }\n  }\n  #endif\n  if (mi_option_is_enabled(mi_option_verbose)) { mi_options_print(); }\n}\n\n#define mi_stringifyx(str)  #str                // and stringify\n#define mi_stringify(str)   mi_stringifyx(str)  // expand\n\nvoid mi_options_print(void) mi_attr_noexcept\n{\n  // show version\n  const int vermajor = MI_MALLOC_VERSION/10000;\n  const int verminor = (MI_MALLOC_VERSION%10000)/100;\n  const int verpatch = (MI_MALLOC_VERSION%100);\n  _mi_message(\"v%i.%i.%i%s%s (built on %s, %s)\\n\", vermajor, verminor, verpatch,\n      #if defined(MI_CMAKE_BUILD_TYPE)\n      \", \" mi_stringify(MI_CMAKE_BUILD_TYPE)\n      #else\n      \"\"\n      #endif\n      ,\n      #if defined(MI_GIT_DESCRIBE)\n      \", git \" mi_stringify(MI_GIT_DESCRIBE)\n      #else\n      \"\"\n      #endif\n      , __DATE__, __TIME__);\n\n  // show options\n  for (int i = 0; i < _mi_option_last; i++) {\n    mi_option_t option = (mi_option_t)i;\n    long l = mi_option_get(option); MI_UNUSED(l); // possibly initialize\n    mi_option_desc_t* desc = &options[option];\n    _mi_message(\"option '%s': %ld %s\\n\", desc->name, desc->value, (mi_option_has_size_in_kib(option) ? \"KiB\" : \"\"));\n  }\n\n  // show build configuration\n  _mi_message(\"debug level : %d\\n\", MI_DEBUG );\n  _mi_message(\"secure level: %d\\n\", MI_SECURE );\n  _mi_message(\"mem tracking: %s\\n\", MI_TRACK_TOOL);\n  #if MI_GUARDED\n  _mi_message(\"guarded build: %s\\n\", mi_option_get(mi_option_guarded_sample_rate) != 0 ? \"enabled\" : \"disabled\");\n  #endif\n  #if MI_TSAN\n  _mi_message(\"thread santizer enabled\\n\");\n  #endif\n}\n\nlong _mi_option_get_fast(mi_option_t option) {\n  mi_assert(option >= 0 && option < _mi_option_last);\n  mi_option_desc_t* desc = &options[option];\n  mi_assert(desc->option == option);  // index should match the option\n  //mi_assert(desc->init != UNINIT);\n  return desc->value;\n}\n\n\nmi_decl_nodiscard long mi_option_get(mi_option_t option) {\n  mi_assert(option >= 0 && option < _mi_option_last);\n  if (option < 0 || option >= _mi_option_last) return 0;\n  mi_option_desc_t* desc = &options[option];\n  mi_assert(desc->option == option);  // index should match the option\n  if mi_unlikely(desc->init == UNINIT) {\n    mi_option_init(desc);\n  }\n  return desc->value;\n}\n\nmi_decl_nodiscard long mi_option_get_clamp(mi_option_t option, long min, long max) {\n  long x = mi_option_get(option);\n  return (x < min ? min : (x > max ? max : x));\n}\n\nmi_decl_nodiscard size_t mi_option_get_size(mi_option_t option) {\n  const long x = mi_option_get(option);\n  size_t size = (x < 0 ? 0 : (size_t)x);\n  if (mi_option_has_size_in_kib(option)) {\n    if (mi_mul_overflow(size, MI_KiB, &size)) {\n      size = MI_MAX_ALLOC_SIZE;\n    }\n  }\n  return size;\n}\n\nvoid mi_option_set(mi_option_t option, long value) {\n  mi_assert(option >= 0 && option < _mi_option_last);\n  if (option < 0 || option >= _mi_option_last) return;\n  mi_option_desc_t* desc = &options[option];\n  mi_assert(desc->option == option);  // index should match the option\n  desc->value = value;\n  desc->init = INITIALIZED;\n  // ensure min/max range; be careful to not recurse.\n  if (desc->option == mi_option_guarded_min && _mi_option_get_fast(mi_option_guarded_max) < value) {\n    mi_option_set(mi_option_guarded_max, value);\n  }\n  else if (desc->option == mi_option_guarded_max && _mi_option_get_fast(mi_option_guarded_min) > value) {\n    mi_option_set(mi_option_guarded_min, value);\n  }\n}\n\nvoid mi_option_set_default(mi_option_t option, long value) {\n  mi_assert(option >= 0 && option < _mi_option_last);\n  if (option < 0 || option >= _mi_option_last) return;\n  mi_option_desc_t* desc = &options[option];\n  if (desc->init != INITIALIZED) {\n    desc->value = value;\n  }\n}\n\nmi_decl_nodiscard bool mi_option_is_enabled(mi_option_t option) {\n  return (mi_option_get(option) != 0);\n}\n\nvoid mi_option_set_enabled(mi_option_t option, bool enable) {\n  mi_option_set(option, (enable ? 1 : 0));\n}\n\nvoid mi_option_set_enabled_default(mi_option_t option, bool enable) {\n  mi_option_set_default(option, (enable ? 1 : 0));\n}\n\nvoid mi_option_enable(mi_option_t option) {\n  mi_option_set_enabled(option,true);\n}\n\nvoid mi_option_disable(mi_option_t option) {\n  mi_option_set_enabled(option,false);\n}\n\nstatic void mi_cdecl mi_out_stderr(const char* msg, void* arg) {\n  MI_UNUSED(arg);\n  if (msg != NULL && msg[0] != 0) {\n    _mi_prim_out_stderr(msg);\n  }\n}\n\n// Since an output function can be registered earliest in the `main`\n// function we also buffer output that happens earlier. When\n// an output function is registered it is called immediately with\n// the output up to that point.\n#ifndef MI_MAX_DELAY_OUTPUT\n#define MI_MAX_DELAY_OUTPUT ((size_t)(16*1024))\n#endif\nstatic char out_buf[MI_MAX_DELAY_OUTPUT+1];\nstatic _Atomic(size_t) out_len;\nstatic mi_lock_t out_buf_lock = MI_LOCK_INITIALIZER;\n\nstatic void mi_cdecl mi_out_buf(const char* msg, void* arg) {\n  MI_UNUSED(arg);\n  if (msg==NULL) return;\n  if (mi_atomic_load_acquire(&out_len)>=MI_MAX_DELAY_OUTPUT) return;\n  size_t n = _mi_strlen(msg);\n  if (n==0 || n >= MI_MAX_DELAY_OUTPUT) return;\n  // copy msg into the buffer\n  mi_lock(&out_buf_lock) {\n    const size_t start = mi_atomic_add_acq_rel(&out_len, n);\n    if (start < MI_MAX_DELAY_OUTPUT) {\n      // check bound\n      if (start+n >= MI_MAX_DELAY_OUTPUT) {\n        n = MI_MAX_DELAY_OUTPUT-start-1;\n      }\n      _mi_memcpy(&out_buf[start], msg, n);\n    }\n  }\n}\n\nstatic void mi_out_buf_flush(mi_output_fun* out, bool no_more_buf, void* arg) {\n  if (out==NULL) return;\n  // claim (if `no_more_buf == true`, no more output will be added after this point)\n  mi_lock(&out_buf_lock) {\n    size_t count = mi_atomic_add_acq_rel(&out_len, (no_more_buf ? MI_MAX_DELAY_OUTPUT : 1));\n    // and output the current contents\n    if (count>MI_MAX_DELAY_OUTPUT) count = MI_MAX_DELAY_OUTPUT;\n    out_buf[count] = 0;\n    out(out_buf,arg);\n    if (!no_more_buf) {\n      out_buf[count] = '\\n'; // if continue with the buffer, insert a newline\n    }\n  }\n}\n\n\n// Once this module is loaded, switch to this routine\n// which outputs to stderr and the delayed output buffer.\nstatic void mi_cdecl mi_out_buf_stderr(const char* msg, void* arg) {\n  mi_out_stderr(msg,arg);\n  mi_out_buf(msg,arg);\n}\n\n\n\n// --------------------------------------------------------\n// Default output handler\n// --------------------------------------------------------\n\n// The program should only install a single output handler from a single thread\n// since otherwise the argument and output function may not match.\nstatic _Atomic(void*) mi_out_default; // = // is `mi_output_fun*` (but some platforms don't support atomic function pointers)\nstatic _Atomic(void*) mi_out_arg; // = NULL\n\nstatic mi_output_fun* mi_out_get_default(void** parg) {\n  mi_output_fun* const out = (mi_output_fun*)mi_atomic_load_ptr_acquire(void,&mi_out_default);\n  if (parg != NULL) { *parg = mi_atomic_load_ptr_acquire(void,&mi_out_arg); }\n  return (out == NULL ? &mi_out_buf : out);\n}\n\nvoid mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept {\n  mi_atomic_store_ptr_release(void,&mi_out_default, (void*)(out == NULL ? &mi_out_stderr : out)); // stop using the delayed output buffer\n  mi_atomic_store_ptr_release(void,&mi_out_arg, arg);\n  if (out!=NULL) { mi_out_buf_flush(out,true,arg); }        // output all the delayed output now\n}\n\n// add stderr to the delayed output after the module is loaded\nstatic void mi_add_stderr_output(void) {\n  mi_assert_internal(mi_out_default == NULL);\n  mi_out_buf_flush(&mi_out_stderr, false, NULL); // flush current contents to stderr\n  mi_atomic_store_ptr_release(void,&mi_out_default,(void*)&mi_out_buf_stderr);  // and add stderr to the delayed output\n  mi_atomic_store_ptr_release(void,&mi_out_arg,NULL);\n}\n\n// --------------------------------------------------------\n// Messages, all end up calling `_mi_fputs`.\n// --------------------------------------------------------\nstatic _Atomic(size_t) error_count;   // = 0;  // when >= max_error_count stop emitting errors\nstatic _Atomic(size_t) warning_count; // = 0;  // when >= max_warning_count stop emitting warnings\n\n// When overriding malloc, we may recurse into mi_vfprintf if an allocation\n// inside the C runtime causes another message.\n// In some cases (like on macOS) the loader already allocates which\n// calls into mimalloc; if we then access thread locals (like `recurse`)\n// this may crash as the access may call _tlv_bootstrap that tries to\n// (recursively) invoke malloc again to allocate space for the thread local\n// variables on demand. This is why we use a _mi_preloading test on such\n// platforms. However, C code generator may move the initial thread local address\n// load before the `if` and we therefore split it out in a separate function.\nstatic mi_decl_thread bool recurse = false;\n\nstatic mi_decl_noinline bool mi_recurse_enter_prim(void) {\n  if (recurse) return false;\n  recurse = true;\n  return true;\n}\n\nstatic mi_decl_noinline void mi_recurse_exit_prim(void) {\n  recurse = false;\n}\n\nstatic bool mi_recurse_enter(void) {\n  #if defined(__APPLE__) || defined(__ANDROID__) || defined(MI_TLS_RECURSE_GUARD)\n  if (_mi_preloading()) return false;\n  #endif\n  return mi_recurse_enter_prim();\n}\n\nstatic void mi_recurse_exit(void) {\n  #if defined(__APPLE__) || defined(__ANDROID__) || defined(MI_TLS_RECURSE_GUARD)\n  if (_mi_preloading()) return;\n  #endif\n  mi_recurse_exit_prim();\n}\n\nvoid _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message) {\n  if (out==NULL || (void*)out==(void*)stdout || (void*)out==(void*)stderr) { // TODO: use mi_out_stderr for stderr?\n    if (!mi_recurse_enter()) return;\n    out = mi_out_get_default(&arg);\n    if (prefix != NULL) out(prefix, arg);\n    out(message, arg);\n    mi_recurse_exit();\n  }\n  else {\n    if (prefix != NULL) out(prefix, arg);\n    out(message, arg);\n  }\n}\n\n// Define our own limited `fprintf` that avoids memory allocation.\n// We do this using `_mi_vsnprintf` with a limited buffer.\nstatic void mi_vfprintf( mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args ) {\n  char buf[512];\n  if (fmt==NULL) return;\n  if (!mi_recurse_enter()) return;\n  _mi_vsnprintf(buf, sizeof(buf)-1, fmt, args);\n  mi_recurse_exit();\n  _mi_fputs(out,arg,prefix,buf);\n}\n\nvoid _mi_fprintf( mi_output_fun* out, void* arg, const char* fmt, ... ) {\n  va_list args;\n  va_start(args,fmt);\n  mi_vfprintf(out,arg,NULL,fmt,args);\n  va_end(args);\n}\n\nstatic void mi_vfprintf_thread(mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args) {\n  if (prefix != NULL && _mi_strnlen(prefix,33) <= 32 && !_mi_is_main_thread()) {\n    char tprefix[64];\n    _mi_snprintf(tprefix, sizeof(tprefix), \"%sthread 0x%tx: \", prefix, (uintptr_t)_mi_thread_id());\n    mi_vfprintf(out, arg, tprefix, fmt, args);\n  }\n  else {\n    mi_vfprintf(out, arg, prefix, fmt, args);\n  }\n}\n\nvoid _mi_message(const char* fmt, ...) {\n  va_list args;\n  va_start(args, fmt);\n  mi_vfprintf_thread(NULL, NULL, \"mimalloc: \", fmt, args);\n  va_end(args);\n}\n\nvoid _mi_trace_message(const char* fmt, ...) {\n  if (mi_option_get(mi_option_verbose) <= 1) return;  // only with verbose level 2 or higher\n  va_list args;\n  va_start(args, fmt);\n  mi_vfprintf_thread(NULL, NULL, \"mimalloc: \", fmt, args);\n  va_end(args);\n}\n\nvoid _mi_verbose_message(const char* fmt, ...) {\n  if (!mi_option_is_enabled(mi_option_verbose)) return;\n  va_list args;\n  va_start(args,fmt);\n  mi_vfprintf(NULL, NULL, \"mimalloc: \", fmt, args);\n  va_end(args);\n}\n\nstatic void mi_show_error_message(const char* fmt, va_list args) {\n  if (!mi_option_is_enabled(mi_option_verbose)) {\n    if (!mi_option_is_enabled(mi_option_show_errors)) return;\n    if (mi_max_error_count >= 0 && (long)mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return;\n  }\n  mi_vfprintf_thread(NULL, NULL, \"mimalloc: error: \", fmt, args);\n}\n\nvoid _mi_warning_message(const char* fmt, ...) {\n  if (!mi_option_is_enabled(mi_option_verbose)) {\n    if (!mi_option_is_enabled(mi_option_show_errors)) return;\n    if (mi_max_warning_count >= 0 && (long)mi_atomic_increment_acq_rel(&warning_count) > mi_max_warning_count) return;\n  }\n  va_list args;\n  va_start(args,fmt);\n  mi_vfprintf_thread(NULL, NULL, \"mimalloc: warning: \", fmt, args);\n  va_end(args);\n}\n\n\n#if MI_DEBUG\nmi_decl_noreturn mi_decl_cold void _mi_assert_fail(const char* assertion, const char* fname, unsigned line, const char* func ) mi_attr_noexcept {\n  _mi_fprintf(NULL, NULL, \"mimalloc: assertion failed: at \\\"%s\\\":%u, %s\\n  assertion: \\\"%s\\\"\\n\", fname, line, (func==NULL?\"\":func), assertion);\n  abort();\n}\n#endif\n\n// --------------------------------------------------------\n// Errors\n// --------------------------------------------------------\n\nstatic mi_error_fun* volatile  mi_error_handler; // = NULL\nstatic _Atomic(void*) mi_error_arg;     // = NULL\n\nstatic void mi_error_default(int err) {\n  MI_UNUSED(err);\n#if (MI_DEBUG>0)\n  if (err==EFAULT) {\n    #ifdef _MSC_VER\n    __debugbreak();\n    #endif\n    abort();\n  }\n#endif\n#if (MI_SECURE>0)\n  if (err==EFAULT) {  // abort on serious errors in secure mode (corrupted meta-data)\n    abort();\n  }\n#endif\n#if defined(MI_XMALLOC)\n  if (err==ENOMEM || err==EOVERFLOW) { // abort on memory allocation fails in xmalloc mode\n    abort();\n  }\n#endif\n}\n\nvoid mi_register_error(mi_error_fun* fun, void* arg) {\n  mi_error_handler = fun;  // can be NULL\n  mi_atomic_store_ptr_release(void,&mi_error_arg, arg);\n}\n\nvoid _mi_error_message(int err, const char* fmt, ...) {\n  // show detailed error message\n  va_list args;\n  va_start(args, fmt);\n  mi_show_error_message(fmt, args);\n  va_end(args);\n  // and call the error handler which may abort (or return normally)\n  if (mi_error_handler != NULL) {\n    mi_error_handler(err, mi_atomic_load_ptr_acquire(void,&mi_error_arg));\n  }\n  else {\n    mi_error_default(err);\n  }\n}\n\n// --------------------------------------------------------\n// Initialize options by checking the environment\n// --------------------------------------------------------\n\n// TODO: implement ourselves to reduce dependencies on the C runtime\n#include <stdlib.h> // strtol\n#include <string.h> // strstr\n\n\nstatic void mi_option_init(mi_option_desc_t* desc) {\n  // Read option value from the environment\n  char s[64 + 1];\n  char buf[64+1];\n  _mi_strlcpy(buf, \"mimalloc_\", sizeof(buf));\n  _mi_strlcat(buf, desc->name, sizeof(buf));\n  bool found = _mi_getenv(buf, s, sizeof(s));\n  if (!found && desc->legacy_name != NULL) {\n    _mi_strlcpy(buf, \"mimalloc_\", sizeof(buf));\n    _mi_strlcat(buf, desc->legacy_name, sizeof(buf));\n    found = _mi_getenv(buf, s, sizeof(s));\n    if (found) {\n      _mi_warning_message(\"environment option \\\"mimalloc_%s\\\" is deprecated -- use \\\"mimalloc_%s\\\" instead.\\n\", desc->legacy_name, desc->name);\n    }\n  }\n\n  if (found) {\n    size_t len = _mi_strnlen(s, sizeof(buf) - 1);\n    for (size_t i = 0; i < len; i++) {\n      buf[i] = _mi_toupper(s[i]);\n    }\n    buf[len] = 0;\n    if (buf[0] == 0 || _mi_streq(buf,\"1\") || _mi_streq(buf,\"TRUE\") || _mi_streq(buf,\"YES\") || _mi_streq(buf,\"ON\")) {\n      desc->value = 1;\n      desc->init = INITIALIZED;\n    }\n    else if (_mi_streq(buf,\"0\") || _mi_streq(buf,\"FALSE\") || _mi_streq(buf,\"NO\") || _mi_streq(buf,\"OFF\")) {      \n      desc->value = 0;\n      desc->init = INITIALIZED;\n    }\n    else {\n      char* end = buf;\n      long value = strtol(buf, &end, 10);\n      if (mi_option_has_size_in_kib(desc->option)) {\n        // this option is interpreted in KiB to prevent overflow of `long` for large allocations\n        // (long is 32-bit on 64-bit windows, which allows for 4TiB max.)\n        size_t size = (value < 0 ? 0 : (size_t)value);\n        bool overflow = false;\n        if (*end == 'K') { end++; }\n        else if (*end == 'M') { overflow = mi_mul_overflow(size,MI_KiB,&size); end++; }\n        else if (*end == 'G') { overflow = mi_mul_overflow(size,MI_MiB,&size); end++; }\n        else if (*end == 'T') { overflow = mi_mul_overflow(size,MI_GiB,&size); end++; }\n        else { size = (size + MI_KiB - 1) / MI_KiB; }\n        if (end[0] == 'I' && end[1] == 'B') { end += 2; } // KiB, MiB, GiB, TiB\n        else if (*end == 'B') { end++; }                  // Kb, Mb, Gb, Tb\n        if (overflow || size > (MI_MAX_ALLOC_SIZE / MI_KiB)) { size = (MI_MAX_ALLOC_SIZE / MI_KiB); }\n        value = (size > LONG_MAX ? LONG_MAX : (long)size);\n      }\n      if (*end == 0) {\n        mi_option_set(desc->option, value);\n      }\n      else {\n        // set `init` first to avoid recursion through _mi_warning_message on mimalloc_verbose.\n        desc->init = DEFAULTED;\n        if (desc->option == mi_option_verbose && desc->value == 0) {\n          // if the 'mimalloc_verbose' env var has a bogus value we'd never know\n          // (since the value defaults to 'off') so in that case briefly enable verbose\n          desc->value = 1;\n          _mi_warning_message(\"environment option mimalloc_%s has an invalid value.\\n\", desc->name);\n          desc->value = 0;\n        }\n        else {\n          _mi_warning_message(\"environment option mimalloc_%s has an invalid value.\\n\", desc->name);\n        }\n      }\n    }\n    mi_assert_internal(desc->init != UNINIT);\n  }\n  else if (!_mi_preloading()) {\n    desc->init = DEFAULTED;\n  }\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/os.c",
      "sha256": "1d4da5a55738e6cd324e73772ee663ab4b7f618ff1c54d0d5ed3eb0df575aa3f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"\n\n#define mi_os_stat_increase(stat,amount)      _mi_stat_increase(&_mi_stats_main.stat, amount)\n#define mi_os_stat_decrease(stat,amount)      _mi_stat_decrease(&_mi_stats_main.stat, amount)\n#define mi_os_stat_counter_increase(stat,inc) _mi_stat_counter_increase(&_mi_stats_main.stat, inc)\n\n/* -----------------------------------------------------------\n  Initialization.\n----------------------------------------------------------- */\n#ifndef MI_DEFAULT_VIRTUAL_ADDRESS_BITS\n#if MI_INTPTR_SIZE < 8\n#define MI_DEFAULT_VIRTUAL_ADDRESS_BITS     32\n#else\n#define MI_DEFAULT_VIRTUAL_ADDRESS_BITS     48\n#endif\n#endif\n\n#ifndef MI_DEFAULT_PHYSICAL_MEMORY_IN_KIB\n#if MI_INTPTR_SIZE < 8\n#define MI_DEFAULT_PHYSICAL_MEMORY_IN_KIB   4*MI_MiB    // 4 GiB\n#else\n#define MI_DEFAULT_PHYSICAL_MEMORY_IN_KIB   32*MI_MiB   // 32 GiB\n#endif\n#endif\n\nstatic mi_os_mem_config_t mi_os_mem_config = {\n  4096,     // page size\n  0,        // large page size (usually 2MiB)\n  4096,     // allocation granularity\n  MI_DEFAULT_PHYSICAL_MEMORY_IN_KIB,\n  MI_DEFAULT_VIRTUAL_ADDRESS_BITS,\n  true,     // has overcommit?  (if true we use MAP_NORESERVE on mmap systems)\n  false,    // can we partially free allocated blocks? (on mmap systems we can free anywhere in a mapped range, but on Windows we must free the entire span)\n  true      // has virtual reserve? (if true we can reserve virtual address space without using commit or physical memory)\n};\n\nbool _mi_os_has_overcommit(void) {\n  return mi_os_mem_config.has_overcommit;\n}\n\nbool _mi_os_has_virtual_reserve(void) {\n  return mi_os_mem_config.has_virtual_reserve;\n}\n\n\n// OS (small) page size\nsize_t _mi_os_page_size(void) {\n  return mi_os_mem_config.page_size;\n}\n\n// if large OS pages are supported (2 or 4MiB), then return the size, otherwise return the small page size (4KiB)\nsize_t _mi_os_large_page_size(void) {\n  return (mi_os_mem_config.large_page_size != 0 ? mi_os_mem_config.large_page_size : _mi_os_page_size());\n}\n\nbool _mi_os_canuse_large_page(size_t size, size_t alignment) {\n  // if we have access, check the size and alignment requirements\n  if (mi_os_mem_config.large_page_size == 0) return false;\n  return ((size % mi_os_mem_config.large_page_size) == 0 && (alignment % mi_os_mem_config.large_page_size) == 0);\n}\n\n// round to a good OS allocation size (bounded by max 12.5% waste)\nsize_t _mi_os_good_alloc_size(size_t size) {\n  size_t align_size;\n  if (size < 512*MI_KiB) align_size = _mi_os_page_size();\n  else if (size < 2*MI_MiB) align_size = 64*MI_KiB;\n  else if (size < 8*MI_MiB) align_size = 256*MI_KiB;\n  else if (size < 32*MI_MiB) align_size = 1*MI_MiB;\n  else align_size = 4*MI_MiB;\n  if mi_unlikely(size >= (SIZE_MAX - align_size)) return size; // possible overflow?\n  return _mi_align_up(size, align_size);\n}\n\nvoid _mi_os_init(void) {\n  _mi_prim_mem_init(&mi_os_mem_config);\n}\n\n\n/* -----------------------------------------------------------\n  Util\n-------------------------------------------------------------- */\nbool _mi_os_decommit(void* addr, size_t size);\nbool _mi_os_commit(void* addr, size_t size, bool* is_zero);\n\n\n/* -----------------------------------------------------------\n  aligned hinting\n-------------------------------------------------------------- */\n\n// On systems with enough virtual address bits, we can do efficient aligned allocation by using\n// the 2TiB to 30TiB area to allocate those. If we have at least 46 bits of virtual address\n// space (64TiB) we use this technique. (but see issue #939)\n#if (MI_INTPTR_SIZE >= 8) && !defined(MI_NO_ALIGNED_HINT)\nstatic mi_decl_cache_align _Atomic(uintptr_t)aligned_base;\n\n// Return a MI_SEGMENT_SIZE aligned address that is probably available.\n// If this returns NULL, the OS will determine the address but on some OS's that may not be\n// properly aligned which can be more costly as it needs to be adjusted afterwards.\n// For a size > 1GiB this always returns NULL in order to guarantee good ASLR randomization;\n// (otherwise an initial large allocation of say 2TiB has a 50% chance to include (known) addresses\n//  in the middle of the 2TiB - 6TiB address range (see issue #372))\n\n#define MI_HINT_BASE ((uintptr_t)2 << 40)  // 2TiB start\n#define MI_HINT_AREA ((uintptr_t)4 << 40)  // upto (2+4) 6TiB  (since before win8 there is \"only\" 8TiB available to processes)\n#define MI_HINT_MAX  ((uintptr_t)30 << 40) // wrap after 30TiB (area after 32TiB is used for huge OS pages)\n\nvoid* _mi_os_get_aligned_hint(size_t try_alignment, size_t size)\n{\n  if (try_alignment <= 1 || try_alignment > MI_SEGMENT_SIZE) return NULL;\n  if (mi_os_mem_config.virtual_address_bits < 46) return NULL;  // < 64TiB virtual address space\n  size = _mi_align_up(size, MI_SEGMENT_SIZE);\n  if (size > 1*MI_GiB) return NULL;  // guarantee the chance of fixed valid address is at most 1/(MI_HINT_AREA / 1<<30) = 1/4096.\n  size += MI_SEGMENT_SIZE;           // put in `MI_SEGMENT_SIZE` virtual gaps between hinted blocks; this splits VLA's but increases guarded areas.\n  \n  uintptr_t hint = mi_atomic_add_acq_rel(&aligned_base, size);\n  if (hint == 0 || hint > MI_HINT_MAX) {   // wrap or initialize\n    uintptr_t init = MI_HINT_BASE;\n    #if (MI_SECURE>0 || MI_DEBUG==0)       // security: randomize start of aligned allocations unless in debug mode\n    uintptr_t r = _mi_heap_random_next(mi_prim_get_default_heap());\n    init = init + ((MI_SEGMENT_SIZE * ((r>>17) & 0xFFFFF)) % MI_HINT_AREA);  // (randomly 20 bits)*4MiB == 0 to 4TiB\n    #endif\n    uintptr_t expected = hint + size;\n    mi_atomic_cas_strong_acq_rel(&aligned_base, &expected, init);\n    hint = mi_atomic_add_acq_rel(&aligned_base, size); // this may still give 0 or > MI_HINT_MAX but that is ok, it is a hint after all\n  }\n  if (hint%try_alignment != 0) return NULL;\n  return (void*)hint;\n}\n#else\nvoid* _mi_os_get_aligned_hint(size_t try_alignment, size_t size) {\n  MI_UNUSED(try_alignment); MI_UNUSED(size);\n  return NULL;\n}\n#endif\n\n/* -----------------------------------------------------------\n  Free memory\n-------------------------------------------------------------- */\n\nstatic void mi_os_free_huge_os_pages(void* p, size_t size);\n\nstatic void mi_os_prim_free(void* addr, size_t size, size_t commit_size) {\n  mi_assert_internal((size % _mi_os_page_size()) == 0);\n  if (addr == NULL) return; // || _mi_os_is_huge_reserved(addr)\n  int err = _mi_prim_free(addr, size);  // allow size==0 (issue #1041)\n  if (err != 0) {\n    _mi_warning_message(\"unable to free OS memory (error: %d (0x%x), size: 0x%zx bytes, address: %p)\\n\", err, err, size, addr);\n  }\n  if (commit_size > 0) {\n    mi_os_stat_decrease(committed, commit_size);\n  }\n  mi_os_stat_decrease(reserved, size);\n}\n\nvoid _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t memid) {\n  if (mi_memkind_is_os(memid.memkind)) {\n    size_t csize = memid.mem.os.size;\n    if (csize==0) { csize = _mi_os_good_alloc_size(size); }\n    mi_assert_internal(csize >= size);\n    size_t commit_size = (still_committed ? csize : 0);\n    void* base = addr;\n    // different base? (due to alignment)\n    if (memid.mem.os.base != base) {\n      mi_assert(memid.mem.os.base <= addr);\n      base = memid.mem.os.base;\n      const size_t diff = (uint8_t*)addr - (uint8_t*)memid.mem.os.base;\n      if (memid.mem.os.size==0) {\n        csize += diff;\n      }\n      if (still_committed) {\n        commit_size -= diff;  // the (addr-base) part was already un-committed\n      }\n    }\n    // free it\n    if (memid.memkind == MI_MEM_OS_HUGE) {\n      mi_assert(memid.is_pinned);\n      mi_os_free_huge_os_pages(base, csize);\n    }\n    else {\n      mi_os_prim_free(base, csize, (still_committed ? commit_size : 0));\n    }\n  }\n  else {\n    // nothing to do\n    mi_assert(memid.memkind < MI_MEM_OS);\n  }\n}\n\nvoid  _mi_os_free(void* p, size_t size, mi_memid_t memid) {\n  _mi_os_free_ex(p, size, true, memid);\n}\n\n\n/* -----------------------------------------------------------\n   Primitive allocation from the OS.\n-------------------------------------------------------------- */\n\n// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.\n// Also `hint_addr` is a hint and may be ignored.\nstatic void* mi_os_prim_alloc_at(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero) {\n  mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);\n  mi_assert_internal(is_zero != NULL);\n  mi_assert_internal(is_large != NULL);\n  if (size == 0) return NULL;\n  if (!commit) { allow_large = false; }\n  if (try_alignment == 0) { try_alignment = 1; } // avoid 0 to ensure there will be no divide by zero when aligning\n  \n  // try to align along large OS page size for larger allocations\n  const size_t large_page_size = mi_os_mem_config.large_page_size;\n  if (large_page_size > 0 && hint_addr == NULL && size >= 8*large_page_size && _mi_is_power_of_two(try_alignment) && try_alignment < large_page_size) {\n    try_alignment = large_page_size; \n  }\n\n  *is_zero = false;\n  void* p = NULL;\n  int err = _mi_prim_alloc(hint_addr, size, try_alignment, commit, allow_large, is_large, is_zero, &p);\n  if (err != 0) {\n    _mi_warning_message(\"unable to allocate OS memory (error: %d (0x%x), addr: %p, size: 0x%zx bytes, align: 0x%zx, commit: %d, allow large: %d)\\n\", err, err, hint_addr, size, try_alignment, commit, allow_large);\n  }\n\n\n\n  mi_os_stat_counter_increase(mmap_calls, 1);\n  if (p != NULL) {\n    mi_os_stat_increase(reserved, size);\n    if (commit) {\n      mi_os_stat_increase(committed, size);\n      // seems needed for asan (or `mimalloc-test-api` fails)\n      #ifdef MI_TRACK_ASAN\n      if (*is_zero) { mi_track_mem_defined(p,size); }\n               else { mi_track_mem_undefined(p,size); }\n      #endif\n    }\n  }\n  return p;\n}\n\nstatic void* mi_os_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero) {\n  return mi_os_prim_alloc_at(NULL, size, try_alignment, commit, allow_large, is_large, is_zero);\n}\n\n\n// Primitive aligned allocation from the OS.\n// This function guarantees the allocated memory is aligned.\nstatic void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid) {\n  mi_assert_internal(memid!=NULL);\n  mi_assert_internal(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0));\n  mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);\n  _mi_memzero(memid,sizeof(*memid));\n  if (!commit) allow_large = false;\n  if (!(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0))) return NULL;\n  size = _mi_align_up(size, _mi_os_page_size());\n\n  // try first with a requested alignment hint (this will usually be aligned directly on Win 10+ or BSD)\n  bool os_is_large = false;\n  bool os_is_zero = false;\n  void* os_base = NULL;\n  size_t os_size = size;\n  void* p = mi_os_prim_alloc(size, alignment, commit, allow_large, &os_is_large, &os_is_zero);\n  if (p == NULL) return NULL;\n\n  // aligned already?\n  if (((uintptr_t)p % alignment) == 0) {\n    os_base = p;\n  }\n  else {\n    // if not aligned, free it, overallocate, and unmap around it\n    #if !MI_TRACK_ASAN\n    _mi_warning_message(\"unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x%zx bytes, address: %p, alignment: 0x%zx, commit: %d)\\n\", size, p, alignment, commit);\n    #endif\n    if (p != NULL) { mi_os_prim_free(p, size, (commit ? size : 0)); }\n    if (size >= (SIZE_MAX - alignment)) return NULL; // overflow\n    const size_t over_size = size + alignment;\n\n    if (!mi_os_mem_config.has_partial_free) {  // win32 virtualAlloc cannot free parts of an allocated block\n      // over-allocate uncommitted (virtual) memory\n      p = mi_os_prim_alloc(over_size, 1 /*alignment*/, false /* commit? */, false /* allow_large */, &os_is_large, &os_is_zero);\n      if (p == NULL) return NULL;\n\n      // set p to the aligned part in the full region\n      // note: this is dangerous on Windows as VirtualFree needs the actual base pointer\n      // this is handled though by having the `base` field in the memid's\n      os_base = p; // remember the base\n      os_size = over_size;\n      p = _mi_align_up_ptr(p, alignment);\n\n      // explicitly commit only the aligned part\n      if (commit) {\n        if (!_mi_os_commit(p, size, NULL)) {\n          mi_os_prim_free(os_base, over_size, 0);\n          return NULL;\n        }\n      }\n    }\n    else  { // mmap can free inside an allocation\n      // overallocate...\n      p = mi_os_prim_alloc(over_size, 1, commit, false, &os_is_large, &os_is_zero);\n      if (p == NULL) return NULL;\n\n      // and selectively unmap parts around the over-allocated area.\n      void* const aligned_p = _mi_align_up_ptr(p, alignment);\n      const size_t pre_size = (uint8_t*)aligned_p - (uint8_t*)p;\n      const size_t mid_size = _mi_align_up(size, _mi_os_page_size());\n      const size_t post_size = over_size - pre_size - mid_size;\n      mi_assert_internal(pre_size < over_size&& post_size < over_size&& mid_size >= size);\n      if (pre_size > 0)  { mi_os_prim_free(p, pre_size, (commit ? pre_size : 0)); }\n      if (post_size > 0) { mi_os_prim_free((uint8_t*)aligned_p + mid_size, post_size, (commit ? post_size : 0)); }\n      // we can return the aligned pointer on `mmap` systems\n      p = aligned_p;\n      os_base = aligned_p; // since we freed the pre part, `*base == p`.\n      os_size = mid_size;\n    }\n  }\n\n  mi_assert_internal(p != NULL && os_base != NULL && _mi_is_aligned(p,alignment));\n  mi_assert_internal(os_base <= p && size <= os_size);\n  *memid = _mi_memid_create_os(os_base,os_size,commit,os_is_zero,os_is_large);\n  return p;\n}\n\n\n/* -----------------------------------------------------------\n  OS API: alloc and alloc_aligned\n----------------------------------------------------------- */\n\nvoid* _mi_os_alloc(size_t size, mi_memid_t* memid) {\n  *memid = _mi_memid_none();\n  if (size == 0) return NULL;\n  size = _mi_os_good_alloc_size(size);\n  bool os_is_large = false;\n  bool os_is_zero  = false;\n  void* p = mi_os_prim_alloc(size, 0, true, false, &os_is_large, &os_is_zero);\n  if (p == NULL) return NULL;\n\n  *memid = _mi_memid_create_os(p, size, true, os_is_zero, os_is_large);\n  mi_assert_internal(memid->mem.os.size >= size);\n  mi_assert_internal(memid->initially_committed);\n  return p;\n}\n\nvoid* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid)\n{\n  MI_UNUSED(&_mi_os_get_aligned_hint); // suppress unused warnings\n  *memid = _mi_memid_none();\n  if (size == 0) return NULL;\n  size = _mi_os_good_alloc_size(size);\n  alignment = _mi_align_up(alignment, _mi_os_page_size());\n\n  void* p = mi_os_prim_alloc_aligned(size, alignment, commit, allow_large, memid );\n  if (p == NULL) return NULL;\n\n  mi_assert_internal(memid->mem.os.size >= size);\n  mi_assert_internal(_mi_is_aligned(p,alignment));\n  if (commit) { mi_assert_internal(memid->initially_committed); }\n  return p;\n}\n\n\nmi_decl_nodiscard static void* mi_os_ensure_zero(void* p, size_t size, mi_memid_t* memid) {\n  if (p==NULL || size==0) return p;\n  // ensure committed\n  if (!memid->initially_committed) {\n    bool is_zero = false;\n    if (!_mi_os_commit(p, size, &is_zero)) {\n      _mi_os_free(p, size, *memid);\n      return NULL;\n    }\n    memid->initially_committed = true;\n  }\n  // ensure zero'd\n  if (memid->initially_zero) return p;\n  _mi_memzero_aligned(p,size);\n  memid->initially_zero = true;\n  return p;\n}\n\nvoid*  _mi_os_zalloc(size_t size, mi_memid_t* memid) {\n  void* p = _mi_os_alloc(size,memid);\n  return mi_os_ensure_zero(p, size, memid);\n}\n\n/* -----------------------------------------------------------\n  OS aligned allocation with an offset. This is used\n  for large alignments > MI_BLOCK_ALIGNMENT_MAX. We use a large mimalloc\n  page where the object can be aligned at an offset from the start of the segment.\n  As we may need to overallocate, we need to free such pointers using `mi_free_aligned`\n  to use the actual start of the memory region.\n----------------------------------------------------------- */\n\nvoid* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t offset, bool commit, bool allow_large, mi_memid_t* memid) {\n  mi_assert(offset <= MI_SEGMENT_SIZE);\n  mi_assert(offset <= size);\n  mi_assert((alignment % _mi_os_page_size()) == 0);\n  *memid = _mi_memid_none();\n  if (offset > MI_SEGMENT_SIZE || offset > size) return NULL;\n  if (offset == 0) {\n    // regular aligned allocation\n    return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid);\n  }\n  else {\n    // overallocate to align at an offset\n    const size_t extra = _mi_align_up(offset, alignment) - offset;\n    if (size >= SIZE_MAX - extra) return NULL;  // too large\n    const size_t oversize = size + extra;\n    void* const start = _mi_os_alloc_aligned(oversize, alignment, commit, allow_large, memid);\n    if (start == NULL) return NULL;\n\n    void* const p = (uint8_t*)start + extra;\n    mi_assert(_mi_is_aligned((uint8_t*)p + offset, alignment));\n    // decommit the overallocation at the start\n    if (commit && extra >= _mi_os_page_size()) {\n      _mi_os_decommit(start, extra);\n    }\n    return p;\n  }\n}\n\n/* -----------------------------------------------------------\n  OS memory API: reset, commit, decommit, protect, unprotect.\n----------------------------------------------------------- */\n\n// OS page align within a given area, either conservative (pages inside the area only),\n// or not (straddling pages outside the area is possible)\nstatic void* mi_os_page_align_areax(bool conservative, void* addr, size_t size, size_t* newsize) {\n  mi_assert(addr != NULL && size > 0);\n  if (newsize != NULL) *newsize = 0;\n  if (size == 0 || addr == NULL) return NULL;\n\n  // page align conservatively within the range\n  void* start = (conservative ? _mi_align_up_ptr(addr, _mi_os_page_size())\n                              : _mi_align_down_ptr(addr, _mi_os_page_size()));\n  void* end   = (conservative ? _mi_align_down_ptr((uint8_t*)addr + size, _mi_os_page_size())\n                              : _mi_align_up_ptr((uint8_t*)addr + size, _mi_os_page_size()));\n  ptrdiff_t diff = (uint8_t*)end - (uint8_t*)start;\n  if (diff <= 0) return NULL;\n\n  mi_assert_internal((conservative && (size_t)diff <= size) || (!conservative && (size_t)diff >= size));\n  if (newsize != NULL) *newsize = (size_t)diff;\n  return start;\n}\n\nstatic void* mi_os_page_align_area_conservative(void* addr, size_t size, size_t* newsize) {\n  return mi_os_page_align_areax(true, addr, size, newsize);\n}\n\nbool _mi_os_commit_ex(void* addr, size_t size, bool* is_zero, size_t stat_size) {\n  if (is_zero != NULL) { *is_zero = false; }\n  mi_os_stat_counter_increase(commit_calls, 1);\n\n  // page align range\n  size_t csize;\n  void* start = mi_os_page_align_areax(false /* conservative? */, addr, size, &csize);\n  if (csize == 0) return true;\n\n  // commit\n  bool os_is_zero = false;\n  int err = _mi_prim_commit(start, csize, &os_is_zero);\n  if (err != 0) {\n    _mi_warning_message(\"cannot commit OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\\n\", err, err, start, csize);\n    return false;\n  }\n  if (os_is_zero && is_zero != NULL) {\n    *is_zero = true;\n    mi_assert_expensive(mi_mem_is_zero(start, csize));\n  }\n  // note: the following seems required for asan (otherwise `mimalloc-test-stress` fails)\n  #ifdef MI_TRACK_ASAN\n  if (os_is_zero) { mi_track_mem_defined(start,csize); }\n             else { mi_track_mem_undefined(start,csize); }\n  #endif\n  mi_os_stat_increase(committed, stat_size);  // use size for precise commit vs. decommit\n  return true;\n}\n\nbool _mi_os_commit(void* addr, size_t size, bool* is_zero) {\n  return _mi_os_commit_ex(addr, size, is_zero, size);\n}\n\nstatic bool mi_os_decommit_ex(void* addr, size_t size, bool* needs_recommit, size_t stat_size) {\n  mi_assert_internal(needs_recommit!=NULL);\n  \n  // page align\n  size_t csize;\n  void* start = mi_os_page_align_area_conservative(addr, size, &csize);\n  if (csize == 0) return true;\n\n  // decommit\n  *needs_recommit = true;\n  int err = _mi_prim_decommit(start,csize,needs_recommit);\n  if (err != 0) {\n    _mi_warning_message(\"cannot decommit OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\\n\", err, err, start, csize);\n  }\n  else if (*needs_recommit) {   \n    mi_os_stat_decrease(committed, stat_size);\n  }\n  mi_assert_internal(err == 0);\n  return (err == 0);\n}\n\nbool _mi_os_decommit(void* addr, size_t size) {\n  bool needs_recommit;\n  return mi_os_decommit_ex(addr, size, &needs_recommit, size);\n}\n\n\n// Signal to the OS that the address range is no longer in use\n// but may be used later again. This will release physical memory\n// pages and reduce swapping while keeping the memory committed.\n// We page align to a conservative area inside the range to reset.\nbool _mi_os_reset(void* addr, size_t size) {\n  // page align conservatively within the range\n  size_t csize;\n  void* start = mi_os_page_align_area_conservative(addr, size, &csize);\n  if (csize == 0) return true;  // || _mi_os_is_huge_reserved(addr)\n  mi_os_stat_counter_increase(reset, csize);\n  mi_os_stat_counter_increase(reset_calls, 1);\n\n  #if (MI_DEBUG>1) && !MI_SECURE && !MI_TRACK_ENABLED // && !MI_TSAN\n  memset(start, 0, csize); // pretend it is eagerly reset\n  #endif\n\n  int err = _mi_prim_reset(start, csize);\n  if (err != 0) {\n    _mi_warning_message(\"cannot reset OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\\n\", err, err, start, csize);\n  }\n  return (err == 0);\n}\n\n\nvoid _mi_os_reuse( void* addr, size_t size ) {\n  // page align conservatively within the range\n  size_t csize = 0;\n  void* const start = mi_os_page_align_area_conservative(addr, size, &csize);\n  if (csize == 0) return;\n  const int err = _mi_prim_reuse(start, csize);\n  if (err != 0) {\n    _mi_warning_message(\"cannot reuse OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\\n\", err, err, start, csize);\n  }\n}\n\n// either resets or decommits memory, returns true if the memory needs\n// to be recommitted if it is to be re-used later on.\nbool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, size_t stat_size)\n{\n  if (mi_option_get(mi_option_purge_delay) < 0) return false;  // is purging allowed?\n  mi_os_stat_counter_increase(purge_calls, 1);\n  mi_os_stat_counter_increase(purged, size);\n\n  if (mi_option_is_enabled(mi_option_purge_decommits) &&   // should decommit?\n      !_mi_preloading())                                   // don't decommit during preloading (unsafe)\n  {\n    bool needs_recommit = true;\n    mi_os_decommit_ex(p, size, &needs_recommit, stat_size);\n    return needs_recommit;\n  }\n  else {\n    if (allow_reset) {  // this can sometimes be not allowed if the range is not fully committed\n      _mi_os_reset(p, size);\n    }\n    return false;  // needs no recommit\n  }\n}\n\n// either resets or decommits memory, returns true if the memory needs\n// to be recommitted if it is to be re-used later on.\nbool _mi_os_purge(void* p, size_t size) {\n  return _mi_os_purge_ex(p, size, true, size);\n}\n\n// Protect a region in memory to be not accessible.\nstatic  bool mi_os_protectx(void* addr, size_t size, bool protect) {\n  // page align conservatively within the range\n  size_t csize = 0;\n  void* start = mi_os_page_align_area_conservative(addr, size, &csize);\n  if (csize == 0) return false;\n  /*\n  if (_mi_os_is_huge_reserved(addr)) {\n\t  _mi_warning_message(\"cannot mprotect memory allocated in huge OS pages\\n\");\n  }\n  */\n  int err = _mi_prim_protect(start,csize,protect);\n  if (err != 0) {\n    _mi_warning_message(\"cannot %s OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\\n\", (protect ? \"protect\" : \"unprotect\"), err, err, start, csize);\n  }\n  return (err == 0);\n}\n\nbool _mi_os_protect(void* addr, size_t size) {\n  return mi_os_protectx(addr, size, true);\n}\n\nbool _mi_os_unprotect(void* addr, size_t size) {\n  return mi_os_protectx(addr, size, false);\n}\n\n\n\n/* ----------------------------------------------------------------------------\nSupport for allocating huge OS pages (1Gib) that are reserved up-front\nand possibly associated with a specific NUMA node. (use `numa_node>=0`)\n-----------------------------------------------------------------------------*/\n#define MI_HUGE_OS_PAGE_SIZE  (MI_GiB)\n\n\n#if (MI_INTPTR_SIZE >= 8)\n// To ensure proper alignment, use our own area for huge OS pages\nstatic mi_decl_cache_align _Atomic(uintptr_t)  mi_huge_start; // = 0\n\n// Claim an aligned address range for huge pages\nstatic uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) {\n  if (total_size != NULL) *total_size = 0;\n  const size_t size = pages * MI_HUGE_OS_PAGE_SIZE;\n\n  uintptr_t start = 0;\n  uintptr_t end = 0;\n  uintptr_t huge_start = mi_atomic_load_relaxed(&mi_huge_start);\n  do {\n    start = huge_start;\n    if (start == 0) {\n      // Initialize the start address after the 32TiB area\n      start = ((uintptr_t)32 << 40);  // 32TiB virtual start address\n      #if (MI_SECURE>0 || MI_DEBUG==0)      // security: randomize start of huge pages unless in debug mode\n      uintptr_t r = _mi_heap_random_next(mi_prim_get_default_heap());\n      start = start + ((uintptr_t)MI_HUGE_OS_PAGE_SIZE * ((r>>17) & 0x0FFF));  // (randomly 12bits)*1GiB == between 0 to 4TiB\n      #endif\n    }\n    end = start + size;\n    mi_assert_internal(end % MI_SEGMENT_SIZE == 0);\n  } while (!mi_atomic_cas_strong_acq_rel(&mi_huge_start, &huge_start, end));\n\n  if (total_size != NULL) *total_size = size;\n  return (uint8_t*)start;\n}\n#else\nstatic uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) {\n  MI_UNUSED(pages);\n  if (total_size != NULL) *total_size = 0;\n  return NULL;\n}\n#endif\n\n// Allocate MI_SEGMENT_SIZE aligned huge pages\nvoid* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_msecs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid) {\n  *memid = _mi_memid_none();\n  if (psize != NULL) *psize = 0;\n  if (pages_reserved != NULL) *pages_reserved = 0;\n  size_t size = 0;\n  uint8_t* const start = mi_os_claim_huge_pages(pages, &size);\n  if (start == NULL) return NULL; // or 32-bit systems\n\n  // Allocate one page at the time but try to place them contiguously\n  // We allocate one page at the time to be able to abort if it takes too long\n  // or to at least allocate as many as available on the system.\n  mi_msecs_t start_t = _mi_clock_start();\n  size_t page = 0;\n  bool all_zero = true;\n  while (page < pages) {\n    // allocate a page\n    bool is_zero = false;\n    void* addr = start + (page * MI_HUGE_OS_PAGE_SIZE);\n    void* p = NULL;\n    int err = _mi_prim_alloc_huge_os_pages(addr, MI_HUGE_OS_PAGE_SIZE, numa_node, &is_zero, &p);\n    if (!is_zero) { all_zero = false;  }\n    if (err != 0) {\n      _mi_warning_message(\"unable to allocate huge OS page (error: %d (0x%x), address: %p, size: %zx bytes)\\n\", err, err, addr, MI_HUGE_OS_PAGE_SIZE);\n      break;\n    }\n\n    // Did we succeed at a contiguous address?\n    if (p != addr) {\n      // no success, issue a warning and break\n      if (p != NULL) {\n        _mi_warning_message(\"could not allocate contiguous huge OS page %zu at %p\\n\", page, addr);\n        mi_os_prim_free(p, MI_HUGE_OS_PAGE_SIZE, MI_HUGE_OS_PAGE_SIZE);\n      }\n      break;\n    }\n\n    // success, record it\n    page++;  // increase before timeout check (see issue #711)\n    mi_os_stat_increase(committed, MI_HUGE_OS_PAGE_SIZE);\n    mi_os_stat_increase(reserved, MI_HUGE_OS_PAGE_SIZE);\n\n    // check for timeout\n    if (max_msecs > 0) {\n      mi_msecs_t elapsed = _mi_clock_end(start_t);\n      if (page >= 1) {\n        mi_msecs_t estimate = ((elapsed / (page+1)) * pages);\n        if (estimate > 2*max_msecs) { // seems like we are going to timeout, break\n          elapsed = max_msecs + 1;\n        }\n      }\n      if (elapsed > max_msecs) {\n        _mi_warning_message(\"huge OS page allocation timed out (after allocating %zu page(s))\\n\", page);\n        break;\n      }\n    }\n  }\n  const size_t allocated = page * MI_HUGE_OS_PAGE_SIZE;\n  mi_assert_internal(allocated <= size);\n  if (pages_reserved != NULL) { *pages_reserved = page; }\n  if (psize != NULL) { *psize = allocated; }\n  if (page != 0) {\n    mi_assert(start != NULL);\n    *memid = _mi_memid_create_os(start, allocated, true /* is committed */, all_zero, true /* is_large */);\n    memid->memkind = MI_MEM_OS_HUGE;\n    mi_assert(memid->is_pinned);\n    #ifdef MI_TRACK_ASAN\n    if (all_zero) { mi_track_mem_defined(start,allocated); }\n    #endif\n  }\n  return (page == 0 ? NULL : start);\n}\n\n// free every huge page in a range individually (as we allocated per page)\n// note: needed with VirtualAlloc but could potentially be done in one go on mmap'd systems.\nstatic void mi_os_free_huge_os_pages(void* p, size_t size) {\n  if (p==NULL || size==0) return;\n  uint8_t* base = (uint8_t*)p;\n  while (size >= MI_HUGE_OS_PAGE_SIZE) {\n    mi_os_prim_free(base, MI_HUGE_OS_PAGE_SIZE, MI_HUGE_OS_PAGE_SIZE);\n    size -= MI_HUGE_OS_PAGE_SIZE;\n    base += MI_HUGE_OS_PAGE_SIZE;\n  }\n}\n\n\n/* ----------------------------------------------------------------------------\nSupport NUMA aware allocation\n-----------------------------------------------------------------------------*/\n\nstatic _Atomic(size_t) mi_numa_node_count; // = 0   // cache the node count\n\nint _mi_os_numa_node_count(void) {\n  size_t count = mi_atomic_load_acquire(&mi_numa_node_count);\n  if mi_unlikely(count == 0) {\n    long ncount = mi_option_get(mi_option_use_numa_nodes); // given explicitly?\n    if (ncount > 0 && ncount < INT_MAX) {\n      count = (size_t)ncount;\n    }\n    else {\n      const size_t n = _mi_prim_numa_node_count(); // or detect dynamically\n      if (n == 0 || n > INT_MAX) { count = 1; }\n                            else { count = n; }\n    }\n    mi_atomic_store_release(&mi_numa_node_count, count); // save it\n    _mi_verbose_message(\"using %zd numa regions\\n\", count);\n  }\n  mi_assert_internal(count > 0 && count <= INT_MAX);\n  return (int)count;\n}\n\nstatic int mi_os_numa_node_get(void) {\n  int numa_count = _mi_os_numa_node_count();\n  if (numa_count<=1) return 0; // optimize on single numa node systems: always node 0\n  // never more than the node count and >= 0\n  const size_t n = _mi_prim_numa_node();\n  int numa_node = (n < INT_MAX ? (int)n : 0);\n  if (numa_node >= numa_count) { numa_node = numa_node % numa_count; }\n  return numa_node;\n}\n\nint _mi_os_numa_node(void) {\n  if mi_likely(mi_atomic_load_relaxed(&mi_numa_node_count) == 1) {\n    return 0;\n  }\n  else {\n    return mi_os_numa_node_get();\n  }\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/page-queue.c",
      "sha256": "0e96bf06a55dbcf16008247025d0c9110fca6a41dd9b2c6c85d3d849af337377",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/*----------------------------------------------------------------------------\nCopyright (c) 2018-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* -----------------------------------------------------------\n  Definition of page queues for each block size\n----------------------------------------------------------- */\n\n#ifndef MI_IN_PAGE_C\n#error \"this file should be included from 'page.c'\"\n// include to help an IDE\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#endif\n\n/* -----------------------------------------------------------\n  Minimal alignment in machine words (i.e. `sizeof(void*)`)\n----------------------------------------------------------- */\n\n#if (MI_MAX_ALIGN_SIZE > 4*MI_INTPTR_SIZE)\n  #error \"define alignment for more than 4x word size for this platform\"\n#elif (MI_MAX_ALIGN_SIZE > 2*MI_INTPTR_SIZE)\n  #define MI_ALIGN4W   // 4 machine words minimal alignment\n#elif (MI_MAX_ALIGN_SIZE > MI_INTPTR_SIZE)\n  #define MI_ALIGN2W   // 2 machine words minimal alignment\n#else\n  // ok, default alignment is 1 word\n#endif\n\n\n/* -----------------------------------------------------------\n  Queue query\n----------------------------------------------------------- */\n\n\nstatic inline bool mi_page_queue_is_huge(const mi_page_queue_t* pq) {\n  return (pq->block_size == (MI_MEDIUM_OBJ_SIZE_MAX+sizeof(uintptr_t)));\n}\n\nstatic inline bool mi_page_queue_is_full(const mi_page_queue_t* pq) {\n  return (pq->block_size == (MI_MEDIUM_OBJ_SIZE_MAX+(2*sizeof(uintptr_t))));\n}\n\nstatic inline bool mi_page_queue_is_special(const mi_page_queue_t* pq) {\n  return (pq->block_size > MI_MEDIUM_OBJ_SIZE_MAX);\n}\n\n/* -----------------------------------------------------------\n  Bins\n----------------------------------------------------------- */\n\n// Return the bin for a given field size.\n// Returns MI_BIN_HUGE if the size is too large.\n// We use `wsize` for the size in \"machine word sizes\",\n// i.e. byte size == `wsize*sizeof(void*)`.\nstatic inline size_t mi_bin(size_t size) {\n  size_t wsize = _mi_wsize_from_size(size);\n#if defined(MI_ALIGN4W)\n  if mi_likely(wsize <= 4) {\n    return (wsize <= 1 ? 1 : (wsize+1)&~1); // round to double word sizes\n  }\n#elif defined(MI_ALIGN2W)\n  if mi_likely(wsize <= 8) {\n    return (wsize <= 1 ? 1 : (wsize+1)&~1); // round to double word sizes\n  }\n#else\n  if mi_likely(wsize <= 8) {\n    return (wsize == 0 ? 1 : wsize);\n  }\n#endif\n  else if mi_unlikely(wsize > MI_MEDIUM_OBJ_WSIZE_MAX) {\n    return MI_BIN_HUGE;\n  }\n  else {\n    #if defined(MI_ALIGN4W)\n    if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes\n    #endif\n    wsize--;\n    // find the highest bit\n    const size_t b = (MI_SIZE_BITS - 1 - mi_clz(wsize));  // note: wsize != 0\n    // and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).\n    // - adjust with 3 because we use do not round the first 8 sizes\n    //   which each get an exact bin\n    const size_t bin = ((b << 2) + ((wsize >> (b - 2)) & 0x03)) - 3;\n    mi_assert_internal(bin > 0 && bin < MI_BIN_HUGE);\n    return bin;\n  }\n}\n\n\n\n/* -----------------------------------------------------------\n  Queue of pages with free blocks\n----------------------------------------------------------- */\n\nsize_t _mi_bin(size_t size) {\n  return mi_bin(size);\n}\n\nsize_t _mi_bin_size(size_t bin) {\n  return _mi_heap_empty.pages[bin].block_size;\n}\n\n// Good size for allocation\nsize_t mi_good_size(size_t size) mi_attr_noexcept {\n  if (size <= MI_MEDIUM_OBJ_SIZE_MAX) {\n    return _mi_bin_size(mi_bin(size + MI_PADDING_SIZE));\n  }\n  else if (size <= MI_MAX_ALLOC_SIZE) {\n    return _mi_align_up(size + MI_PADDING_SIZE,_mi_os_page_size());\n  }\n  else {\n    return size;\n  }\n}\n\n#if (MI_DEBUG>1)\nstatic bool mi_page_queue_contains(mi_page_queue_t* queue, const mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_page_t* list = queue->first;\n  while (list != NULL) {\n    mi_assert_internal(list->next == NULL || list->next->prev == list);\n    mi_assert_internal(list->prev == NULL || list->prev->next == list);\n    if (list == page) break;\n    list = list->next;\n  }\n  return (list == page);\n}\n\n#endif\n\n#if (MI_DEBUG>1)\nstatic bool mi_heap_contains_queue(const mi_heap_t* heap, const mi_page_queue_t* pq) {\n  return (pq >= &heap->pages[0] && pq <= &heap->pages[MI_BIN_FULL]);\n}\n#endif\n\nstatic inline bool mi_page_is_large_or_huge(const mi_page_t* page) {\n  return (mi_page_block_size(page) > MI_MEDIUM_OBJ_SIZE_MAX || mi_page_is_huge(page));\n}\n\nstatic size_t mi_page_bin(const mi_page_t* page) {\n  const size_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : (mi_page_is_huge(page) ? MI_BIN_HUGE : mi_bin(mi_page_block_size(page))));\n  mi_assert_internal(bin <= MI_BIN_FULL);\n  return bin;\n}\n\n// returns the page bin without using MI_BIN_FULL for statistics\nsize_t _mi_page_stats_bin(const mi_page_t* page) {\n  const size_t bin = (mi_page_is_huge(page) ? MI_BIN_HUGE : mi_bin(mi_page_block_size(page)));\n  mi_assert_internal(bin <= MI_BIN_HUGE);\n  return bin;\n}\n\nstatic mi_page_queue_t* mi_heap_page_queue_of(mi_heap_t* heap, const mi_page_t* page) {\n  mi_assert_internal(heap!=NULL);\n  const size_t bin = mi_page_bin(page);\n  mi_page_queue_t* pq = &heap->pages[bin];\n  mi_assert_internal((mi_page_block_size(page) == pq->block_size) ||\n                       (mi_page_is_large_or_huge(page) && mi_page_queue_is_huge(pq)) ||\n                         (mi_page_is_in_full(page) && mi_page_queue_is_full(pq)));\n  return pq;\n}\n\nstatic mi_page_queue_t* mi_page_queue_of(const mi_page_t* page) {\n  mi_heap_t* heap = mi_page_heap(page);\n  mi_page_queue_t* pq = mi_heap_page_queue_of(heap, page);\n  mi_assert_expensive(mi_page_queue_contains(pq, page));\n  return pq;\n}\n\n// The current small page array is for efficiency and for each\n// small size (up to 256) it points directly to the page for that\n// size without having to compute the bin. This means when the\n// current free page queue is updated for a small bin, we need to update a\n// range of entries in `_mi_page_small_free`.\nstatic inline void mi_heap_queue_first_update(mi_heap_t* heap, const mi_page_queue_t* pq) {\n  mi_assert_internal(mi_heap_contains_queue(heap,pq));\n  const size_t size = pq->block_size;\n  if (size > MI_SMALL_SIZE_MAX) return;\n\n  mi_page_t* page = pq->first;\n  if (pq->first == NULL) page = (mi_page_t*)&_mi_page_empty;\n\n  // find index in the right direct page array\n  const size_t idx = _mi_wsize_from_size(size);\n  mi_page_t** const pages_free = heap->pages_free_direct;\n  if (pages_free[idx] == page) return;  // already set\n\n  // find start slot\n  size_t start;\n  if (idx<=1) {\n    start = 0;\n  }\n  else {\n    // find previous size; due to minimal alignment upto 3 previous bins may need to be skipped\n    mi_assert_internal(pq > &heap->pages[0]); // since idx > 1    \n    size_t bin = mi_bin(size);\n    const mi_page_queue_t* prev = pq - 1;\n    while( bin == mi_bin(prev->block_size) && prev > &heap->pages[0]) {\n      prev--;\n    }\n    start = 1 + _mi_wsize_from_size(prev->block_size);\n    if (start > idx) start = idx;\n  }\n\n  // set size range to the right page\n  mi_assert(start <= idx);\n  for (size_t sz = start; sz <= idx; sz++) {\n    pages_free[sz] = page;\n  }\n}\n\n/*\nstatic bool mi_page_queue_is_empty(mi_page_queue_t* queue) {\n  return (queue->first == NULL);\n}\n*/\n\nstatic void mi_page_queue_remove(mi_page_queue_t* queue, mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_assert_expensive(mi_page_queue_contains(queue, page));\n  mi_assert_internal(mi_page_block_size(page) == queue->block_size ||\n                      (mi_page_is_large_or_huge(page) && mi_page_queue_is_huge(queue)) ||\n                        (mi_page_is_in_full(page) && mi_page_queue_is_full(queue)));\n  mi_heap_t* heap = mi_page_heap(page);\n\n  if (page->prev != NULL) page->prev->next = page->next;\n  if (page->next != NULL) page->next->prev = page->prev;\n  if (page == queue->last)  queue->last = page->prev;\n  if (page == queue->first) {\n    queue->first = page->next;\n    // update first\n    mi_assert_internal(mi_heap_contains_queue(heap, queue));\n    mi_heap_queue_first_update(heap,queue);\n  }\n  heap->page_count--;\n  page->next = NULL;\n  page->prev = NULL;\n  // mi_atomic_store_ptr_release(mi_atomic_cast(void*, &page->heap), NULL);\n  mi_page_set_in_full(page,false);\n}\n\n\n#if MI_DEBUG >= 3\nstatic bool mi_page_queue_is_consistent(const mi_page_queue_t* queue);\n#endif\n\nstatic void mi_page_queue_push(mi_heap_t* heap, mi_page_queue_t* queue, mi_page_t* page) {\n  mi_assert_internal(mi_page_heap(page) == heap);\n  mi_assert_internal(!mi_page_queue_contains(queue, page));\n  #if MI_HUGE_PAGE_ABANDON\n  mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE);\n  #endif\n  mi_assert_internal(mi_page_block_size(page) == queue->block_size ||\n                      (mi_page_is_large_or_huge(page) && mi_page_queue_is_huge(queue)) ||\n                        (mi_page_is_in_full(page) && mi_page_queue_is_full(queue)));\n\n  mi_page_set_in_full(page, mi_page_queue_is_full(queue));\n  // mi_atomic_store_ptr_release(mi_atomic_cast(void*, &page->heap), heap);\n  page->next = queue->first;\n  page->prev = NULL;\n  if (queue->first != NULL) {\n    mi_assert_internal(queue->first->prev == NULL);\n    queue->first->prev = page;\n    queue->first = page;\n  }\n  else {\n    queue->first = queue->last = page;\n  }\n\n  // update direct\n  mi_heap_queue_first_update(heap, queue);\n  heap->page_count++;\n\n  // [specbot Q-NEW-1] first/last must be both null or both non-null (L1, O(1))\n  mi_assert_internal((queue->first == NULL) == (queue->last == NULL));\n  // [specbot Q-NEW-2] last element must have no next (L1, O(1))\n  mi_assert_internal(queue->last == NULL || queue->last->next == NULL);\n  mi_assert_expensive(mi_page_queue_is_consistent(queue));\n}\n\n#if MI_DEBUG >= 3\n// [specbot Q-NEW-3] Verify doubly-linked list forward/backward consistency (L2, O(n))\nstatic bool mi_page_queue_is_consistent(const mi_page_queue_t* queue) {\n  if (queue->first == NULL) return (queue->last == NULL);\n  if (queue->last == NULL) return false;\n  // forward: first -> ... -> last\n  const mi_page_t* p = queue->first;\n  const mi_page_t* prev = NULL;\n  size_t count = 0;\n  while (p != NULL) {\n    mi_assert_internal(p->prev == prev);\n    prev = p;\n    p = p->next;\n    count++;\n    if (count > 100000) return false; // cycle guard\n  }\n  mi_assert_internal(prev == queue->last);\n  return true;\n}\n#endif\n\nstatic void mi_page_queue_move_to_front(mi_heap_t* heap, mi_page_queue_t* queue, mi_page_t* page) {\n  mi_assert_internal(mi_page_heap(page) == heap);\n  mi_assert_internal(mi_page_queue_contains(queue, page));\n  if (queue->first == page) return;\n  mi_page_queue_remove(queue, page);\n  mi_page_queue_push(heap, queue, page);\n  mi_assert_internal(queue->first == page);\n}\n\nstatic void mi_page_queue_enqueue_from_ex(mi_page_queue_t* to, mi_page_queue_t* from, bool enqueue_at_end, mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_assert_expensive(mi_page_queue_contains(from, page));\n  mi_assert_expensive(!mi_page_queue_contains(to, page));\n  const size_t bsize = mi_page_block_size(page);\n  MI_UNUSED(bsize);\n  mi_assert_internal((bsize == to->block_size && bsize == from->block_size) ||\n                     (bsize == to->block_size && mi_page_queue_is_full(from)) ||\n                     (bsize == from->block_size && mi_page_queue_is_full(to)) ||\n                     (mi_page_is_large_or_huge(page) && mi_page_queue_is_huge(to)) ||\n                     (mi_page_is_large_or_huge(page) && mi_page_queue_is_full(to)));\n\n  mi_heap_t* heap = mi_page_heap(page);\n\n  // delete from `from`\n  if (page->prev != NULL) page->prev->next = page->next;\n  if (page->next != NULL) page->next->prev = page->prev;\n  if (page == from->last)  from->last = page->prev;\n  if (page == from->first) {\n    from->first = page->next;\n    // update first\n    mi_assert_internal(mi_heap_contains_queue(heap, from));\n    mi_heap_queue_first_update(heap, from);\n  }\n\n  // insert into `to`\n  if (enqueue_at_end) {\n    // enqueue at the end\n    page->prev = to->last;\n    page->next = NULL;\n    if (to->last != NULL) {\n      mi_assert_internal(heap == mi_page_heap(to->last));\n      to->last->next = page;\n      to->last = page;\n    }\n    else {\n      to->first = page;\n      to->last = page;\n      mi_heap_queue_first_update(heap, to);\n    }\n  }\n  else {\n    if (to->first != NULL) {\n      // enqueue at 2nd place\n      mi_assert_internal(heap == mi_page_heap(to->first));\n      mi_page_t* next = to->first->next;\n      page->prev = to->first;\n      page->next = next;\n      to->first->next = page;\n      if (next != NULL) {\n        next->prev = page;\n      }\n      else {\n        to->last = page;\n      }\n    }\n    else {\n      // enqueue at the head (singleton list)\n      page->prev = NULL;\n      page->next = NULL;\n      to->first = page;\n      to->last = page;\n      mi_heap_queue_first_update(heap, to);\n    }\n  }\n\n  mi_page_set_in_full(page, mi_page_queue_is_full(to));\n}\n\nstatic void mi_page_queue_enqueue_from(mi_page_queue_t* to, mi_page_queue_t* from, mi_page_t* page) {\n  mi_page_queue_enqueue_from_ex(to, from, true /* enqueue at the end */, page);\n}\n\nstatic void mi_page_queue_enqueue_from_full(mi_page_queue_t* to, mi_page_queue_t* from, mi_page_t* page) {\n  // note: we could insert at the front to increase reuse, but it slows down certain benchmarks (like `alloc-test`)\n  mi_page_queue_enqueue_from_ex(to, from, true /* enqueue at the end of the `to` queue? */, page);\n}\n\n// Only called from `mi_heap_absorb`.\nsize_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append) {\n  mi_assert_internal(mi_heap_contains_queue(heap,pq));\n  mi_assert_internal(pq->block_size == append->block_size);\n\n  if (append->first==NULL) return 0;\n\n  // set append pages to new heap and count\n  size_t count = 0;\n  for (mi_page_t* page = append->first; page != NULL; page = page->next) {\n    // inline `mi_page_set_heap` to avoid wrong assertion during absorption;\n    // in this case it is ok to be delayed freeing since both \"to\" and \"from\" heap are still alive.\n    mi_atomic_store_release(&page->xheap, (uintptr_t)heap);\n    // set the flag to delayed free (not overriding NEVER_DELAYED_FREE) which has as a\n    // side effect that it spins until any DELAYED_FREEING is finished. This ensures\n    // that after appending only the new heap will be used for delayed free operations.\n    _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, false);\n    count++;\n  }\n\n  if (pq->last==NULL) {\n    // take over afresh\n    mi_assert_internal(pq->first==NULL);\n    pq->first = append->first;\n    pq->last = append->last;\n    mi_heap_queue_first_update(heap, pq);\n  }\n  else {\n    // append to end\n    mi_assert_internal(pq->last!=NULL);\n    mi_assert_internal(append->first!=NULL);\n    pq->last->next = append->first;\n    append->first->prev = pq->last;\n    pq->last = append->last;\n  }\n  return count;\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/page.c",
      "sha256": "057eeb7d11821b41ff5bf63fa280795ff15b67403d50221918817ed1180bc485",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/*----------------------------------------------------------------------------\nCopyright (c) 2018-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* -----------------------------------------------------------\n  The core of the allocator. Every segment contains\n  pages of a certain block size. The main function\n  exported is `mi_malloc_generic`.\n----------------------------------------------------------- */\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n\n/* -----------------------------------------------------------\n  Definition of page queues for each block size\n----------------------------------------------------------- */\n\n#define MI_IN_PAGE_C\n#include \"page-queue.c\"\n#undef MI_IN_PAGE_C\n\n\n/* -----------------------------------------------------------\n  Page helpers\n----------------------------------------------------------- */\n\n// Index a block in a page\nstatic inline mi_block_t* mi_page_block_at(const mi_page_t* page, void* page_start, size_t block_size, size_t i) {\n  MI_UNUSED(page);\n  mi_assert_internal(page != NULL);\n  mi_assert_internal(i <= page->reserved);\n  return (mi_block_t*)((uint8_t*)page_start + (i * block_size));\n}\n\nstatic void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t size, mi_tld_t* tld);\nstatic bool mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld);\n\n#if (MI_DEBUG>=3)\nstatic size_t mi_page_list_count(mi_page_t* page, mi_block_t* head) {\n  size_t count = 0;\n  while (head != NULL) {\n    mi_assert_internal(page == _mi_ptr_page(head));\n    count++;\n    head = mi_block_next(page, head);\n  }\n  return count;\n}\n\n/*\n// Start of the page available memory\nstatic inline uint8_t* mi_page_area(const mi_page_t* page) {\n  return _mi_page_start(_mi_page_segment(page), page, NULL);\n}\n*/\n\nstatic bool mi_page_list_is_valid(mi_page_t* page, mi_block_t* p) {\n  size_t psize;\n  uint8_t* page_area = _mi_segment_page_start(_mi_page_segment(page), page, &psize);\n  mi_block_t* start = (mi_block_t*)page_area;\n  mi_block_t* end   = (mi_block_t*)(page_area + psize);\n  while(p != NULL) {\n    if (p < start || p >= end) return false;\n    p = mi_block_next(page, p);\n  }\n#if MI_DEBUG>3 // generally too expensive to check this\n  if (page->free_is_zero) {\n    const size_t ubsize = mi_page_usable_block_size(page);\n    for (mi_block_t* block = page->free; block != NULL; block = mi_block_next(page, block)) {\n      mi_assert_expensive(mi_mem_is_zero(block + 1, ubsize - sizeof(mi_block_t)));\n    }\n  }\n#endif\n  return true;\n}\n\nstatic bool mi_page_is_valid_init(mi_page_t* page) {\n  mi_assert_internal(mi_page_block_size(page) > 0);\n  \n  mi_assert_internal(page->used <= page->capacity);\n  mi_assert_internal(page->capacity <= page->reserved);\n\n  // [specbot P-NEW-1] block_size_shift must be consistent with block_size (L1, O(1))\n  mi_assert_internal(page->block_size_shift == 0 || (mi_page_block_size(page) == ((size_t)1 << page->block_size_shift)));\n  // [specbot P-NEW-2] capacity must be nonzero when blocks are in use (L1, O(1))\n  mi_assert_internal(page->used == 0 || page->capacity > 0);\n  // [specbot P-NEW-4] page_start must be non-null when capacity > 0 (L1, O(1))\n  mi_assert_internal(page->capacity == 0 || mi_page_start(page) != NULL);\n\n  uint8_t* start = mi_page_start(page);\n  mi_assert_internal(start == _mi_segment_page_start(_mi_page_segment(page), page, NULL));\n  mi_assert_internal(page->is_huge == (_mi_page_segment(page)->kind == MI_SEGMENT_HUGE));\n  //mi_assert_internal(start + page->capacity*page->block_size == page->top);\n\n  mi_assert_internal(mi_page_list_is_valid(page,page->free));\n  mi_assert_internal(mi_page_list_is_valid(page,page->local_free));\n\n  // [specbot P-NEW-7] All free list blocks are aligned to block_size (L2, O(n))\n  {\n    size_t bsize = mi_page_block_size(page);\n    uint8_t* pstart = mi_page_start(page);\n    for (mi_block_t* b = page->free; b != NULL; b = mi_block_next(page, b)) {\n      mi_assert_internal(((uint8_t*)b - pstart) % bsize == 0);\n    }\n    for (mi_block_t* b = page->local_free; b != NULL; b = mi_block_next(page, b)) {\n      mi_assert_internal(((uint8_t*)b - pstart) % bsize == 0);\n    }\n  }\n\n  #if MI_DEBUG>3 // generally too expensive to check this\n  if (page->free_is_zero) {\n    const size_t ubsize = mi_page_usable_block_size(page);\n    for(mi_block_t* block = page->free; block != NULL; block = mi_block_next(page,block)) {\n      mi_assert_expensive(mi_mem_is_zero(block + 1, ubsize - sizeof(mi_block_t)));\n    }\n  }\n  #endif\n\n  #if !MI_TRACK_ENABLED && !MI_TSAN\n  mi_block_t* tfree = mi_page_thread_free(page);\n  mi_assert_internal(mi_page_list_is_valid(page, tfree));\n  //size_t tfree_count = mi_page_list_count(page, tfree);\n  //mi_assert_internal(tfree_count <= page->thread_freed + 1);\n  #endif\n\n  size_t free_count = mi_page_list_count(page, page->free) + mi_page_list_count(page, page->local_free);\n  mi_assert_internal(page->used + free_count == page->capacity);\n\n  return true;\n}\n\nextern mi_decl_hidden bool _mi_process_is_initialized;             // has mi_process_init been called?\n\nbool _mi_page_is_valid(mi_page_t* page) {\n  mi_assert_internal(mi_page_is_valid_init(page));\n  #if MI_SECURE\n  mi_assert_internal(page->keys[0] != 0);\n  #endif\n  if (mi_page_heap(page)!=NULL) {\n    mi_segment_t* segment = _mi_page_segment(page);\n\n    // [specbot P-NEW-6] heap_tag must match owning heap's tag (L1, O(1))\n    mi_assert_internal(page->heap_tag == mi_page_heap(page)->tag);\n\n    mi_assert_internal(!_mi_process_is_initialized || segment->thread_id==0 || segment->thread_id == mi_page_heap(page)->thread_id);\n    #if MI_HUGE_PAGE_ABANDON\n    if (segment->kind != MI_SEGMENT_HUGE)\n    #endif\n    {\n      mi_page_queue_t* pq = mi_page_queue_of(page);\n      mi_assert_internal(mi_page_queue_contains(pq, page));\n      mi_assert_internal(pq->block_size==mi_page_block_size(page) || mi_page_block_size(page) > MI_MEDIUM_OBJ_SIZE_MAX || mi_page_is_in_full(page));\n      mi_assert_internal(mi_heap_contains_queue(mi_page_heap(page),pq));\n    }\n  }\n  return true;\n}\n#endif\n\nvoid _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) {\n  while (!_mi_page_try_use_delayed_free(page, delay, override_never)) {\n    mi_atomic_yield();\n  }\n}\n\nbool _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) {\n  mi_thread_free_t tfreex;\n  mi_delayed_t     old_delay;\n  mi_thread_free_t tfree;\n  size_t yield_count = 0;\n  do {\n    tfree = mi_atomic_load_acquire(&page->xthread_free); // note: must acquire as we can break/repeat this loop and not do a CAS;\n    tfreex = mi_tf_set_delayed(tfree, delay);\n    old_delay = mi_tf_delayed(tfree);\n    if mi_unlikely(old_delay == MI_DELAYED_FREEING) {\n      if (yield_count >= 4) return false;  // give up after 4 tries\n      yield_count++;\n      mi_atomic_yield(); // delay until outstanding MI_DELAYED_FREEING are done.\n      // tfree = mi_tf_set_delayed(tfree, MI_NO_DELAYED_FREE); // will cause CAS to busy fail\n    }\n    else if (delay == old_delay) {\n      break; // avoid atomic operation if already equal\n    }\n    else if (!override_never && old_delay == MI_NEVER_DELAYED_FREE) {\n      break; // leave never-delayed flag set\n    }\n  } while ((old_delay == MI_DELAYED_FREEING) ||\n           !mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex));\n\n  return true; // success\n}\n\n/* -----------------------------------------------------------\n  Page collect the `local_free` and `thread_free` lists\n----------------------------------------------------------- */\n\n// Collect the local `thread_free` list using an atomic exchange.\n// Note: The exchange must be done atomically as this is used right after\n// moving to the full list in `mi_page_collect_ex` and we need to\n// ensure that there was no race where the page became unfull just before the move.\nstatic void _mi_page_thread_free_collect(mi_page_t* page)\n{\n  mi_block_t* head;\n  mi_thread_free_t tfreex;\n  mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free);\n  do {\n    head = mi_tf_block(tfree);\n    tfreex = mi_tf_set_block(tfree,NULL);\n  } while (!mi_atomic_cas_weak_acq_rel(&page->xthread_free, &tfree, tfreex));\n\n  // return if the list is empty\n  if (head == NULL) return;\n\n  // find the tail -- also to get a proper count (without data races)\n  size_t max_count = page->capacity; // cannot collect more than capacity\n  size_t count = 1;\n  mi_block_t* tail = head;\n  mi_block_t* next;\n  while ((next = mi_block_next(page,tail)) != NULL && count <= max_count) {\n    count++;\n    tail = next;\n  }\n  // if `count > max_count` there was a memory corruption (possibly infinite list due to double multi-threaded free)\n  if mi_unlikely(count > max_count) {\n    _mi_error_message(EFAULT, \"corrupted thread-free list\\n\");\n    return; // the thread-free items cannot be freed\n  }\n  // if `count > page->used` there was another kind memory corruption (either in the page meta-data or in the linked list)\n  else if mi_unlikely(count > page->used) {\n    _mi_error_message(EFAULT, \"corrupted meta-data in thread-free list\\n\");\n    return; // the thread-free items cannot be freed\n  }\n\n  // and append the current local free list\n  mi_block_set_next(page,tail, page->local_free);\n  page->local_free = head;\n\n  // update counts now\n  mi_assert_internal(count <= UINT16_MAX);\n  mi_assert_internal(page->used >= (uint16_t)count);\n  page->used = page->used - (uint16_t)count;\n}\n\nvoid _mi_page_free_collect(mi_page_t* page, bool force) {\n  mi_assert_internal(page!=NULL);\n\n  // collect the thread free list\n  if (force || mi_page_thread_free(page) != NULL) {  // quick test to avoid an atomic operation\n    _mi_page_thread_free_collect(page);\n  }\n\n  // and the local free list\n  if (page->local_free != NULL) {\n    if mi_likely(page->free == NULL) {\n      // usual case\n      page->free = page->local_free;\n      page->local_free = NULL;\n      page->free_is_zero = false;\n    }\n    else if (force) {\n      // append -- only on shutdown (force) as this is a linear operation\n      mi_block_t* tail = page->local_free;\n      mi_block_t* next;\n      while ((next = mi_block_next(page, tail)) != NULL) {\n        tail = next;\n      }\n      mi_block_set_next(page, tail, page->free);\n      page->free = page->local_free;\n      page->local_free = NULL;\n      page->free_is_zero = false;\n    }\n  }\n\n  mi_assert_internal(!force || page->local_free == NULL);\n}\n\n\n\n/* -----------------------------------------------------------\n  Page fresh and retire\n----------------------------------------------------------- */\n\n// called from segments when reclaiming abandoned pages\nvoid _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page) {\n  mi_assert_expensive(mi_page_is_valid_init(page));\n\n  mi_assert_internal(mi_page_heap(page) == heap);\n  mi_assert_internal(mi_page_thread_free_flag(page) != MI_NEVER_DELAYED_FREE);\n  #if MI_HUGE_PAGE_ABANDON\n  mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE);\n  #endif\n\n  // TODO: push on full queue immediately if it is full?\n  mi_page_queue_t* pq = mi_page_queue(heap, mi_page_block_size(page));\n  mi_page_queue_push(heap, pq, page);\n  mi_assert_expensive(_mi_page_is_valid(page));\n}\n\n// allocate a fresh page from a segment\nstatic mi_page_t* mi_page_fresh_alloc(mi_heap_t* heap, mi_page_queue_t* pq, size_t block_size, size_t page_alignment) {\n  #if !MI_HUGE_PAGE_ABANDON\n  mi_assert_internal(pq != NULL);\n  mi_assert_internal(mi_heap_contains_queue(heap, pq));\n  mi_assert_internal(page_alignment > 0 || block_size > MI_MEDIUM_OBJ_SIZE_MAX || block_size == pq->block_size);\n  #endif\n  mi_page_t* page = _mi_segment_page_alloc(heap, block_size, page_alignment, &heap->tld->segments);\n  if (page == NULL) {\n    // this may be out-of-memory, or an abandoned page was reclaimed (and in our queue)\n    return NULL;\n  }\n  #if MI_HUGE_PAGE_ABANDON\n  mi_assert_internal(pq==NULL || _mi_page_segment(page)->page_kind != MI_PAGE_HUGE);\n  #endif\n  mi_assert_internal(page_alignment >0 || block_size > MI_MEDIUM_OBJ_SIZE_MAX || _mi_page_segment(page)->kind != MI_SEGMENT_HUGE);\n  mi_assert_internal(pq!=NULL || mi_page_block_size(page) >= block_size);\n  // a fresh page was found, initialize it\n  const size_t full_block_size = (pq == NULL || mi_page_is_huge(page) ? mi_page_block_size(page) : block_size); // see also: mi_segment_huge_page_alloc\n  mi_assert_internal(full_block_size >= block_size);\n  mi_page_init(heap, page, full_block_size, heap->tld);\n  mi_heap_stat_increase(heap, pages, 1);\n  mi_heap_stat_increase(heap, page_bins[_mi_page_stats_bin(page)], 1);\n  if (pq != NULL) { mi_page_queue_push(heap, pq, page); }\n  mi_assert_expensive(_mi_page_is_valid(page));\n  return page;\n}\n\n// Get a fresh page to use\nstatic mi_page_t* mi_page_fresh(mi_heap_t* heap, mi_page_queue_t* pq) {\n  mi_assert_internal(mi_heap_contains_queue(heap, pq));\n  mi_page_t* page = mi_page_fresh_alloc(heap, pq, pq->block_size, 0);\n  if (page==NULL) return NULL;\n  mi_assert_internal(pq->block_size==mi_page_block_size(page));\n  mi_assert_internal(pq==mi_page_queue(heap, mi_page_block_size(page)));\n  return page;\n}\n\n/* -----------------------------------------------------------\n   Do any delayed frees\n   (put there by other threads if they deallocated in a full page)\n----------------------------------------------------------- */\nvoid _mi_heap_delayed_free_all(mi_heap_t* heap) {\n  while (!_mi_heap_delayed_free_partial(heap)) {\n    mi_atomic_yield();\n  }\n}\n\n// returns true if all delayed frees were processed\nbool _mi_heap_delayed_free_partial(mi_heap_t* heap) {\n  // take over the list (note: no atomic exchange since it is often NULL)\n  mi_block_t* block = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free);\n  while (block != NULL && !mi_atomic_cas_ptr_weak_acq_rel(mi_block_t, &heap->thread_delayed_free, &block, NULL)) { /* nothing */ };\n  bool all_freed = true;\n\n  // and free them all\n  while(block != NULL) {\n    mi_block_t* next = mi_block_nextx(heap,block, heap->keys);\n    // use internal free instead of regular one to keep stats etc correct\n    if (!_mi_free_delayed_block(block)) {\n      // we might already start delayed freeing while another thread has not yet\n      // reset the delayed_freeing flag; in that case delay it further by reinserting the current block\n      // into the delayed free list\n      all_freed = false;\n      mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free);\n      do {\n        mi_block_set_nextx(heap, block, dfree, heap->keys);\n      } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block));\n    }\n    block = next;\n  }\n  return all_freed;\n}\n\n/* -----------------------------------------------------------\n  Unfull, abandon, free and retire\n----------------------------------------------------------- */\n\n// Move a page from the full list back to a regular list\nvoid _mi_page_unfull(mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_assert_expensive(_mi_page_is_valid(page));\n  mi_assert_internal(mi_page_is_in_full(page));\n  if (!mi_page_is_in_full(page)) return;\n\n  mi_heap_t* heap = mi_page_heap(page);\n  mi_page_queue_t* pqfull = &heap->pages[MI_BIN_FULL];\n  mi_page_set_in_full(page, false); // to get the right queue\n  mi_page_queue_t* pq = mi_heap_page_queue_of(heap, page);\n  mi_page_set_in_full(page, true);\n  mi_page_queue_enqueue_from_full(pq, pqfull, page);\n}\n\nstatic void mi_page_to_full(mi_page_t* page, mi_page_queue_t* pq) {\n  mi_assert_internal(pq == mi_page_queue_of(page));\n  mi_assert_internal(!mi_page_immediate_available(page));\n  mi_assert_internal(!mi_page_is_in_full(page));\n\n  if (mi_page_is_in_full(page)) return;\n  mi_page_queue_enqueue_from(&mi_page_heap(page)->pages[MI_BIN_FULL], pq, page);\n  _mi_page_free_collect(page,false);  // try to collect right away in case another thread freed just before MI_USE_DELAYED_FREE was set\n}\n\n\n// Abandon a page with used blocks at the end of a thread.\n// Note: only call if it is ensured that no references exist from\n// the `page->heap->thread_delayed_free` into this page.\n// Currently only called through `mi_heap_collect_ex` which ensures this.\nvoid _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq) {\n  mi_assert_internal(page != NULL);\n  mi_assert_expensive(_mi_page_is_valid(page));\n  mi_assert_internal(pq == mi_page_queue_of(page));\n  mi_assert_internal(mi_page_heap(page) != NULL);\n\n  mi_heap_t* pheap = mi_page_heap(page);\n\n  // remove from our page list\n  mi_segments_tld_t* segments_tld = &pheap->tld->segments;\n  mi_page_queue_remove(pq, page);\n\n  // page is no longer associated with our heap\n  mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE);\n  mi_page_set_heap(page, NULL);\n\n#if (MI_DEBUG>1) && !MI_TRACK_ENABLED\n  // check there are no references left..\n  for (mi_block_t* block = (mi_block_t*)pheap->thread_delayed_free; block != NULL; block = mi_block_nextx(pheap, block, pheap->keys)) {\n    mi_assert_internal(_mi_ptr_page(block) != page);\n  }\n#endif\n\n  // and abandon it\n  mi_assert_internal(mi_page_heap(page) == NULL);\n  _mi_segment_page_abandon(page,segments_tld);\n}\n\n// force abandon a page\nvoid _mi_page_force_abandon(mi_page_t* page) {\n  mi_heap_t* heap = mi_page_heap(page);\n  // mark page as not using delayed free\n  _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false);\n\n  // ensure this page is no longer in the heap delayed free list\n  _mi_heap_delayed_free_all(heap);\n  // We can still access the page meta-info even if it is freed as we ensure\n  // in `mi_segment_force_abandon` that the segment is not freed (yet)\n  if (page->capacity == 0) return; // it may have been freed now\n\n  // and now unlink it from the page queue and abandon (or free)\n  mi_page_queue_t* pq = mi_heap_page_queue_of(heap, page);\n  if (mi_page_all_free(page)) {\n    _mi_page_free(page, pq, false);\n  }\n  else {\n    _mi_page_abandon(page, pq);\n  }\n}\n\n\n// Free a page with no more free blocks\nvoid _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force) {\n  mi_assert_internal(page != NULL);\n  mi_assert_expensive(_mi_page_is_valid(page));\n  mi_assert_internal(pq == mi_page_queue_of(page));\n  mi_assert_internal(mi_page_all_free(page));\n  mi_assert_internal(mi_page_thread_free_flag(page)!=MI_DELAYED_FREEING);\n\n  // no more aligned blocks in here\n  mi_page_set_has_aligned(page, false);\n\n  // remove from the page list\n  // (no need to do _mi_heap_delayed_free first as all blocks are already free)\n  mi_heap_t* heap = mi_page_heap(page);\n  mi_segments_tld_t* segments_tld = &heap->tld->segments;\n  mi_page_queue_remove(pq, page);\n\n  // and free it  \n  mi_page_set_heap(page,NULL);\n  _mi_segment_page_free(page, force, segments_tld);\n}\n\n#define MI_MAX_RETIRE_SIZE    MI_MEDIUM_OBJ_SIZE_MAX   // should be less than size for MI_BIN_HUGE\n#define MI_RETIRE_CYCLES      (16)\n\n// Retire a page with no more used blocks\n// Important to not retire too quickly though as new\n// allocations might coming.\n// Note: called from `mi_free` and benchmarks often\n// trigger this due to freeing everything and then\n// allocating again so careful when changing this.\nvoid _mi_page_retire(mi_page_t* page) mi_attr_noexcept {\n  mi_assert_internal(page != NULL);\n  mi_assert_expensive(_mi_page_is_valid(page));\n  mi_assert_internal(mi_page_all_free(page));\n\n  mi_page_set_has_aligned(page, false);\n\n  // don't retire too often..\n  // (or we end up retiring and re-allocating most of the time)\n  // NOTE: refine this more: we should not retire if this\n  // is the only page left with free blocks. It is not clear\n  // how to check this efficiently though...\n  // for now, we don't retire if it is the only page left of this size class.\n  mi_page_queue_t* pq = mi_page_queue_of(page);\n  #if MI_RETIRE_CYCLES > 0\n  const size_t bsize = mi_page_block_size(page);\n  if mi_likely( /* bsize < MI_MAX_RETIRE_SIZE && */ !mi_page_queue_is_special(pq)) {  // not full or huge queue?\n    if (pq->last==page && pq->first==page) { // the only page in the queue?\n      mi_stat_counter_increase(_mi_stats_main.pages_retire,1);\n      page->retire_expire = (bsize <= MI_SMALL_OBJ_SIZE_MAX ? MI_RETIRE_CYCLES : MI_RETIRE_CYCLES/4);\n      mi_heap_t* heap = mi_page_heap(page);\n      mi_assert_internal(pq >= heap->pages);\n      const size_t index = pq - heap->pages;\n      mi_assert_internal(index < MI_BIN_FULL && index < MI_BIN_HUGE);\n      if (index < heap->page_retired_min) heap->page_retired_min = index;\n      if (index > heap->page_retired_max) heap->page_retired_max = index;\n      mi_assert_internal(mi_page_all_free(page));\n      return; // don't free after all\n    }\n  }\n  #endif\n  _mi_page_free(page, pq, false);\n}\n\n// free retired pages: we don't need to look at the entire queues\n// since we only retire pages that are at the head position in a queue.\nvoid _mi_heap_collect_retired(mi_heap_t* heap, bool force) {\n  size_t min = MI_BIN_FULL;\n  size_t max = 0;\n  for(size_t bin = heap->page_retired_min; bin <= heap->page_retired_max; bin++) {\n    mi_page_queue_t* pq   = &heap->pages[bin];\n    mi_page_t*       page = pq->first;\n    if (page != NULL && page->retire_expire != 0) {\n      if (mi_page_all_free(page)) {\n        page->retire_expire--;\n        if (force || page->retire_expire == 0) {\n          _mi_page_free(pq->first, pq, force);\n        }\n        else {\n          // keep retired, update min/max\n          if (bin < min) min = bin;\n          if (bin > max) max = bin;\n        }\n      }\n      else {\n        page->retire_expire = 0;\n      }\n    }\n  }\n  heap->page_retired_min = min;\n  heap->page_retired_max = max;\n}\n\n\n/* -----------------------------------------------------------\n  Initialize the initial free list in a page.\n  In secure mode we initialize a randomized list by\n  alternating between slices.\n----------------------------------------------------------- */\n\n#define MI_MAX_SLICE_SHIFT  (6)   // at most 64 slices\n#define MI_MAX_SLICES       (1UL << MI_MAX_SLICE_SHIFT)\n#define MI_MIN_SLICES       (2)\n\nstatic void mi_page_free_list_extend_secure(mi_heap_t* const heap, mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats) {\n  MI_UNUSED(stats);\n  #if (MI_SECURE<=2)\n  mi_assert_internal(page->free == NULL);\n  mi_assert_internal(page->local_free == NULL);\n  #endif\n  mi_assert_internal(page->capacity + extend <= page->reserved);\n  mi_assert_internal(bsize == mi_page_block_size(page));\n  void* const page_area = mi_page_start(page);\n\n  // initialize a randomized free list\n  // set up `slice_count` slices to alternate between\n  size_t shift = MI_MAX_SLICE_SHIFT;\n  while ((extend >> shift) == 0) {\n    shift--;\n  }\n  const size_t slice_count = (size_t)1U << shift;\n  const size_t slice_extend = extend / slice_count;\n  mi_assert_internal(slice_extend >= 1);\n  mi_block_t* blocks[MI_MAX_SLICES];   // current start of the slice\n  size_t      counts[MI_MAX_SLICES];   // available objects in the slice\n  for (size_t i = 0; i < slice_count; i++) {\n    blocks[i] = mi_page_block_at(page, page_area, bsize, page->capacity + i*slice_extend);\n    counts[i] = slice_extend;\n  }\n  counts[slice_count-1] += (extend % slice_count);  // final slice holds the modulus too (todo: distribute evenly?)\n\n  // and initialize the free list by randomly threading through them\n  // set up first element\n  const uintptr_t r = _mi_heap_random_next(heap);\n  size_t current = r % slice_count;\n  counts[current]--;\n  mi_block_t* const free_start = blocks[current];\n  // and iterate through the rest; use `random_shuffle` for performance\n  uintptr_t rnd = _mi_random_shuffle(r|1); // ensure not 0\n  for (size_t i = 1; i < extend; i++) {\n    // call random_shuffle only every INTPTR_SIZE rounds\n    const size_t round = i%MI_INTPTR_SIZE;\n    if (round == 0) rnd = _mi_random_shuffle(rnd);\n    // select a random next slice index\n    size_t next = ((rnd >> 8*round) & (slice_count-1));\n    while (counts[next]==0) {                            // ensure it still has space\n      next++;\n      if (next==slice_count) next = 0;\n    }\n    // and link the current block to it\n    counts[next]--;\n    mi_block_t* const block = blocks[current];\n    blocks[current] = (mi_block_t*)((uint8_t*)block + bsize);  // bump to the following block\n    mi_block_set_next(page, block, blocks[next]);   // and set next; note: we may have `current == next`\n    current = next;\n  }\n  // prepend to the free list (usually NULL)\n  mi_block_set_next(page, blocks[current], page->free);  // end of the list\n  page->free = free_start;\n}\n\nstatic mi_decl_noinline void mi_page_free_list_extend( mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats)\n{\n  MI_UNUSED(stats);\n  #if (MI_SECURE <= 2)\n  mi_assert_internal(page->free == NULL);\n  mi_assert_internal(page->local_free == NULL);\n  #endif\n  mi_assert_internal(page->capacity + extend <= page->reserved);\n  mi_assert_internal(bsize == mi_page_block_size(page));\n  void* const page_area = mi_page_start(page);\n\n  mi_block_t* const start = mi_page_block_at(page, page_area, bsize, page->capacity);\n\n  // initialize a sequential free list\n  mi_block_t* const last = mi_page_block_at(page, page_area, bsize, page->capacity + extend - 1);\n  mi_block_t* block = start;\n  while(block <= last) {\n    mi_block_t* next = (mi_block_t*)((uint8_t*)block + bsize);\n    mi_block_set_next(page,block,next);\n    block = next;\n  }\n  // prepend to free list (usually `NULL`)\n  mi_block_set_next(page, last, page->free);\n  page->free = start;\n}\n\n/* -----------------------------------------------------------\n  Page initialize and extend the capacity\n----------------------------------------------------------- */\n\n#define MI_MAX_EXTEND_SIZE    (4*1024)      // heuristic, one OS page seems to work well.\n#if (MI_SECURE>=2)\n#define MI_MIN_EXTEND         (8*MI_SECURE) // extend at least by this many blocks\n#else\n#define MI_MIN_EXTEND         (4)\n#endif\n\n// Extend the capacity (up to reserved) by initializing a free list\n// We do at most `MI_MAX_EXTEND` to avoid touching too much memory\n// Note: we also experimented with \"bump\" allocation on the first\n// allocations but this did not speed up any benchmark (due to an\n// extra test in malloc? or cache effects?)\nstatic bool mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld) {\n  mi_assert_expensive(mi_page_is_valid_init(page));\n  #if (MI_SECURE<=2)\n  mi_assert(page->free == NULL);\n  mi_assert(page->local_free == NULL);\n  if (page->free != NULL) return true;\n  #endif\n  if (page->capacity >= page->reserved) return true;\n\n  mi_stat_counter_increase(tld->stats.pages_extended, 1);\n\n  // calculate the extend count\n  const size_t bsize = mi_page_block_size(page);\n  size_t extend = page->reserved - page->capacity;\n  mi_assert_internal(extend > 0);\n\n  size_t max_extend = (bsize >= MI_MAX_EXTEND_SIZE ? MI_MIN_EXTEND : MI_MAX_EXTEND_SIZE/bsize);\n  if (max_extend < MI_MIN_EXTEND) { max_extend = MI_MIN_EXTEND; }\n  mi_assert_internal(max_extend > 0);\n\n  if (extend > max_extend) {\n    // ensure we don't touch memory beyond the page to reduce page commit.\n    // the `lean` benchmark tests this. Going from 1 to 8 increases rss by 50%.\n    extend = max_extend;\n  }\n\n  mi_assert_internal(extend > 0 && extend + page->capacity <= page->reserved);\n  mi_assert_internal(extend < (1UL<<16));\n\n  // and append the extend the free list\n  if (extend < MI_MIN_SLICES || MI_SECURE<2) { //!mi_option_is_enabled(mi_option_secure)) {\n    mi_page_free_list_extend(page, bsize, extend, &tld->stats );\n  }\n  else {\n    mi_page_free_list_extend_secure(heap, page, bsize, extend, &tld->stats);\n  }\n  // enable the new free list\n  page->capacity += (uint16_t)extend;\n  mi_stat_increase(tld->stats.page_committed, extend * bsize);\n  mi_assert_expensive(mi_page_is_valid_init(page));\n  return true;\n}\n\n// Initialize a fresh page\nstatic void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t block_size, mi_tld_t* tld) {\n  mi_assert(page != NULL);\n  mi_segment_t* segment = _mi_page_segment(page);\n  mi_assert(segment != NULL);\n  mi_assert_internal(block_size > 0);\n  // set fields\n  mi_page_set_heap(page, heap);\n  page->block_size = block_size;\n  size_t page_size;\n  page->page_start = _mi_segment_page_start(segment, page, &page_size);\n  mi_track_mem_noaccess(page->page_start,page_size);\n  mi_assert_internal(mi_page_block_size(page) <= page_size);\n  mi_assert_internal(page_size <= page->slice_count*MI_SEGMENT_SLICE_SIZE);\n  mi_assert_internal(page_size / block_size < (1L<<16));\n  page->reserved = (uint16_t)(page_size / block_size);\n  mi_assert_internal(page->reserved > 0);\n  #if (MI_PADDING || MI_ENCODE_FREELIST)\n  page->keys[0] = _mi_heap_random_next(heap);\n  page->keys[1] = _mi_heap_random_next(heap);\n  #endif\n  page->free_is_zero = page->is_zero_init;\n  #if MI_DEBUG>2\n  if (page->is_zero_init) {\n    mi_track_mem_defined(page->page_start, page_size);\n    mi_assert_expensive(mi_mem_is_zero(page->page_start, page_size));\n  }\n  #endif\n  mi_assert_internal(page->is_committed);\n  if (block_size > 0 && _mi_is_power_of_two(block_size)) {\n    page->block_size_shift = (uint8_t)(mi_ctz((uintptr_t)block_size));\n  }\n  else {\n    page->block_size_shift = 0;\n  }\n\n  mi_assert_internal(page->capacity == 0);\n  mi_assert_internal(page->free == NULL);\n  mi_assert_internal(page->used == 0);\n  mi_assert_internal(page->xthread_free == 0);\n  mi_assert_internal(page->next == NULL);\n  mi_assert_internal(page->prev == NULL);\n  mi_assert_internal(page->retire_expire == 0);\n  mi_assert_internal(!mi_page_has_aligned(page));\n  #if (MI_PADDING || MI_ENCODE_FREELIST)\n  mi_assert_internal(page->keys[0] != 0);\n  mi_assert_internal(page->keys[1] != 0);\n  #endif\n  mi_assert_internal(page->block_size_shift == 0 || (block_size == ((size_t)1 << page->block_size_shift)));\n  mi_assert_expensive(mi_page_is_valid_init(page));\n\n  // initialize an initial free list\n  if (mi_page_extend_free(heap,page,tld)) {\n    mi_assert(mi_page_immediate_available(page));\n  }\n  return;\n}\n\n\n/* -----------------------------------------------------------\n  Find pages with free blocks\n-------------------------------------------------------------*/\n\n// search for a best next page to use for at most N pages (often cut short if immediate blocks are available)\n#define MI_MAX_CANDIDATE_SEARCH  (4)\n\n// is the page not yet used up to its reserved space?\nstatic bool mi_page_is_expandable(const mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_assert_internal(page->capacity <= page->reserved);\n  return (page->capacity < page->reserved);\n}\n\n\n// Find a page with free blocks of `page->block_size`.\nstatic mi_page_t* mi_page_queue_find_free_ex(mi_heap_t* heap, mi_page_queue_t* pq, bool first_try)\n{\n  // search through the pages in \"next fit\" order\n  #if MI_STAT\n  size_t count = 0;\n  #endif\n  size_t candidate_count = 0;        // we reset this on the first candidate to limit the search\n  mi_page_t* page_candidate = NULL;  // a page with free space\n  mi_page_t* page = pq->first;\n\n  while (page != NULL)\n  {\n    mi_page_t* next = page->next; // remember next\n    #if MI_STAT\n    count++;\n    #endif\n    candidate_count++;\n\n    // collect freed blocks by us and other threads\n    _mi_page_free_collect(page, false);\n\n  #if MI_MAX_CANDIDATE_SEARCH > 1\n    // search up to N pages for a best candidate\n\n    // is the local free list non-empty?\n    const bool immediate_available = mi_page_immediate_available(page);\n\n    // if the page is completely full, move it to the `mi_pages_full`\n    // queue so we don't visit long-lived pages too often.\n    if (!immediate_available && !mi_page_is_expandable(page)) {\n      mi_assert_internal(!mi_page_is_in_full(page) && !mi_page_immediate_available(page));\n      mi_page_to_full(page, pq);\n    }\n    else {\n      // the page has free space, make it a candidate\n      // we prefer non-expandable pages with high usage as candidates (to reduce commit, and increase chances of free-ing up pages)\n      if (page_candidate == NULL) {\n        page_candidate = page;\n        candidate_count = 0;\n      }\n      // prefer to reuse fuller pages (in the hope the less used page gets freed)\n      else if (page->used >= page_candidate->used && !mi_page_is_mostly_used(page) && !mi_page_is_expandable(page)) {\n        page_candidate = page;\n      }\n      // if we find a non-expandable candidate, or searched for N pages, return with the best candidate\n      if (immediate_available || candidate_count > MI_MAX_CANDIDATE_SEARCH) {\n        mi_assert_internal(page_candidate!=NULL);\n        break;\n      }\n    }\n  #else\n    // first-fit algorithm\n    // If the page contains free blocks, we are done\n    if (mi_page_immediate_available(page) || mi_page_is_expandable(page)) {\n      break;  // pick this one\n    }\n\n    // If the page is completely full, move it to the `mi_pages_full`\n    // queue so we don't visit long-lived pages too often.\n    mi_assert_internal(!mi_page_is_in_full(page) && !mi_page_immediate_available(page));\n    mi_page_to_full(page, pq);\n  #endif\n\n    page = next;\n  } // for each page\n\n  mi_heap_stat_counter_increase(heap, page_searches, count);\n  mi_heap_stat_counter_increase(heap, page_searches_count, 1);\n\n  // set the page to the best candidate\n  if (page_candidate != NULL) {\n    page = page_candidate;\n  }\n  if (page != NULL) {\n    if (!mi_page_immediate_available(page)) {\n      mi_assert_internal(mi_page_is_expandable(page));\n      if (!mi_page_extend_free(heap, page, heap->tld)) {\n        page = NULL; // failed to extend\n      }\n    }\n    mi_assert_internal(page == NULL || mi_page_immediate_available(page));\n  }\n\n  if (page == NULL) {\n    _mi_heap_collect_retired(heap, false); // perhaps make a page available?\n    page = mi_page_fresh(heap, pq);\n    if (page == NULL && first_try) {\n      // out-of-memory _or_ an abandoned page with free blocks was reclaimed, try once again\n      page = mi_page_queue_find_free_ex(heap, pq, false);\n    }\n  }\n  else {\n    // move the page to the front of the queue\n    mi_page_queue_move_to_front(heap, pq, page);\n    page->retire_expire = 0;\n    // _mi_heap_collect_retired(heap, false); // update retire counts; note: increases rss on MemoryLoad bench so don't do this\n  }\n  mi_assert_internal(page == NULL || mi_page_immediate_available(page));\n\n\n  return page;\n}\n\n\n\n// Find a page with free blocks of `size`.\nstatic inline mi_page_t* mi_find_free_page(mi_heap_t* heap, size_t size) {\n  mi_page_queue_t* pq = mi_page_queue(heap, size);\n\n  // check the first page: we even do this with candidate search or otherwise we re-search every time\n  mi_page_t* page = pq->first;\n  if (page != NULL) {\n   #if (MI_SECURE>=2) // in secure mode, we extend half the time to increase randomness\n    if (page->capacity < page->reserved && ((_mi_heap_random_next(heap) & 1) == 1)) {\n      mi_page_extend_free(heap, page, heap->tld);\n      mi_assert_internal(mi_page_immediate_available(page));\n    }\n    else\n   #endif\n    {\n      _mi_page_free_collect(page,false);\n    }\n\n    if (mi_page_immediate_available(page)) {\n      page->retire_expire = 0;\n      return page; // fast path\n    }\n  }\n\n  return mi_page_queue_find_free_ex(heap, pq, true);\n}\n\n\n/* -----------------------------------------------------------\n  Users can register a deferred free function called\n  when the `free` list is empty. Since the `local_free`\n  is separate this is deterministically called after\n  a certain number of allocations.\n----------------------------------------------------------- */\n\n// The program should only install a single deferred free handler before doing allocation.\nstatic _Atomic(void*) deferred_free; // is `mi_deferred_free_fun*` (but some platforms don't support atomic function pointers)\nstatic _Atomic(void*) deferred_arg;   \n\nvoid _mi_deferred_free(mi_heap_t* heap, bool force) {\n  heap->tld->heartbeat++;\n  mi_deferred_free_fun* const fun = (mi_deferred_free_fun*)mi_atomic_load_ptr_acquire(void,&deferred_free);\n  if (fun != NULL && !heap->tld->recurse) {\n    heap->tld->recurse = true;\n    void* const arg = mi_atomic_load_ptr_acquire(void,&deferred_arg);  \n    fun(force, heap->tld->heartbeat, arg);\n    heap->tld->recurse = false;\n  }\n}\n\nvoid mi_register_deferred_free(mi_deferred_free_fun* fn, void* arg) mi_attr_noexcept {\n  mi_atomic_store_ptr_release(void,&deferred_arg, arg);\n  mi_atomic_store_ptr_release(void,&deferred_free, (void*)fn);  \n}\n\n\n/* -----------------------------------------------------------\n  General allocation\n----------------------------------------------------------- */\n\n// Large and huge page allocation.\n// Huge pages contain just one block, and the segment contains just that page (as `MI_SEGMENT_HUGE`).\n// Huge pages are also use if the requested alignment is very large (> MI_BLOCK_ALIGNMENT_MAX)\n// so their size is not always `> MI_LARGE_OBJ_SIZE_MAX`.\nstatic mi_page_t* mi_large_huge_page_alloc(mi_heap_t* heap, size_t size, size_t page_alignment) {\n  size_t block_size = _mi_os_good_alloc_size(size);\n  mi_assert_internal(mi_bin(block_size) == MI_BIN_HUGE || page_alignment > 0);\n  bool is_huge = (block_size > MI_LARGE_OBJ_SIZE_MAX || page_alignment > 0);\n  #if MI_HUGE_PAGE_ABANDON\n  mi_page_queue_t* pq = (is_huge ? NULL : mi_page_queue(heap, block_size));\n  #else\n  mi_page_queue_t* pq = mi_page_queue(heap, is_huge ? MI_LARGE_OBJ_SIZE_MAX+1 : block_size);\n  mi_assert_internal(!is_huge || mi_page_queue_is_huge(pq));\n  #endif\n  mi_page_t* page = mi_page_fresh_alloc(heap, pq, block_size, page_alignment);\n  if (page != NULL) {\n    mi_assert_internal(mi_page_immediate_available(page));\n\n    if (is_huge) {\n      mi_assert_internal(mi_page_is_huge(page));\n      mi_assert_internal(_mi_page_segment(page)->kind == MI_SEGMENT_HUGE);\n      mi_assert_internal(_mi_page_segment(page)->used==1);\n      #if MI_HUGE_PAGE_ABANDON\n      mi_assert_internal(_mi_page_segment(page)->thread_id==0); // abandoned, not in the huge queue\n      mi_page_set_heap(page, NULL);\n      #endif\n    }\n    else {\n      mi_assert_internal(!mi_page_is_huge(page));\n    }\n\n    const size_t bsize = mi_page_usable_block_size(page);  // note: not `mi_page_block_size` to account for padding\n    /*if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {\n      mi_heap_stat_increase(heap, malloc_large, bsize);\n      mi_heap_stat_counter_increase(heap, malloc_large_count, 1);\n    }\n    else */\n    {\n      _mi_stat_increase(&heap->tld->stats.malloc_huge, bsize);\n      _mi_stat_counter_increase(&heap->tld->stats.malloc_huge_count, 1);\n    }\n  }\n  return page;\n}\n\n\n// Allocate a page\n// Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed.\nstatic mi_page_t* mi_find_page(mi_heap_t* heap, size_t size, size_t huge_alignment) mi_attr_noexcept {\n  // huge allocation?\n  const size_t req_size = size - MI_PADDING_SIZE;  // correct for padding_size in case of an overflow on `size`\n  if mi_unlikely(req_size > (MI_MEDIUM_OBJ_SIZE_MAX - MI_PADDING_SIZE) || huge_alignment > 0) {\n    if mi_unlikely(req_size > MI_MAX_ALLOC_SIZE) {\n      _mi_error_message(EOVERFLOW, \"allocation request is too large (%zu bytes)\\n\", req_size);\n      return NULL;\n    }\n    else {\n      return mi_large_huge_page_alloc(heap,size,huge_alignment);\n    }\n  }\n  else {\n    // otherwise find a page with free blocks in our size segregated queues\n    #if MI_PADDING\n    mi_assert_internal(size >= MI_PADDING_SIZE);\n    #endif\n    return mi_find_free_page(heap, size);\n  }\n}\n\n// Generic allocation routine if the fast path (`alloc.c:mi_page_malloc`) does not succeed.\n// Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed.\n// The `huge_alignment` is normally 0 but is set to a multiple of MI_SLICE_SIZE for\n// very large requested alignments in which case we use a huge singleton page.\nvoid* _mi_malloc_generic(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment, size_t* usable) mi_attr_noexcept\n{\n  mi_assert_internal(heap != NULL);\n\n  // initialize if necessary\n  if mi_unlikely(!mi_heap_is_initialized(heap)) {\n    heap = mi_heap_get_default(); // calls mi_thread_init\n    if mi_unlikely(!mi_heap_is_initialized(heap)) { return NULL; }\n  }\n  mi_assert_internal(mi_heap_is_initialized(heap));\n\n  // do administrative tasks every N generic mallocs\n  if mi_unlikely(++heap->generic_count >= 100) {\n    heap->generic_collect_count += heap->generic_count;\n    heap->generic_count = 0;\n    // call potential deferred free routines\n    _mi_deferred_free(heap, false);\n\n    // free delayed frees from other threads (but skip contended ones)\n    _mi_heap_delayed_free_partial(heap);\n\n    // collect every once in a while (10000 by default)\n    const long generic_collect = mi_option_get_clamp(mi_option_generic_collect, 1, 1000000L);\n    if (heap->generic_collect_count >= generic_collect) {\n      heap->generic_collect_count = 0;\n      mi_heap_collect(heap, false /* force? */);\n    }\n  }\n\n  // find (or allocate) a page of the right size\n  mi_page_t* page = mi_find_page(heap, size, huge_alignment);\n  if mi_unlikely(page == NULL) { // first time out of memory, try to collect and retry the allocation once more\n    mi_heap_collect(heap, true /* force */);\n    page = mi_find_page(heap, size, huge_alignment);\n  }\n\n  if mi_unlikely(page == NULL) { // out of memory\n    const size_t req_size = size - MI_PADDING_SIZE;  // correct for padding_size in case of an overflow on `size`\n    _mi_error_message(ENOMEM, \"unable to allocate memory (%zu bytes)\\n\", req_size);\n    return NULL;\n  }\n\n  mi_assert_internal(mi_page_immediate_available(page));\n  mi_assert_internal(mi_page_block_size(page) >= size);\n\n  // and try again, this time succeeding! (i.e. this should never recurse through _mi_page_malloc)\n  void* const p = _mi_page_malloc_zero(heap, page, size, zero, usable);\n  mi_assert_internal(p != NULL);\n\n  // move singleton pages to the full queue\n  if (page->reserved == page->used) {\n    mi_page_to_full(page, mi_page_queue_of(page));\n  }\n  return p;\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/prim/emscripten/prim.c",
      "sha256": "fb236c93d69f68ee57afead03b874aa02fbf2efc25ae483fab0d4ff7d71543ad",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen, Alon Zakai\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// This file is included in `src/prim/prim.c`\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"\n\n#include <unistd.h>  // getentropy\n\n// Design\n// ======\n//\n// mimalloc is built on top of emmalloc. emmalloc is a minimal allocator on top\n// of sbrk. The reason for having three layers here is that we want mimalloc to\n// be able to allocate and release system memory properly, the same way it would\n// when using VirtualAlloc on Windows or mmap on POSIX, and sbrk is too limited.\n// Specifically, sbrk can only go up and down, and not \"skip\" over regions, and\n// so we end up either never freeing memory to the system, or we can get stuck\n// with holes.\n//\n// Atm wasm generally does *not* free memory back the system: once grown, we do\n// not shrink back down (https://github.com/WebAssembly/design/issues/1397).\n// However, that is expected to improve\n// (https://github.com/WebAssembly/memory-control/blob/main/proposals/memory-control/Overview.md)\n// and so we do not want to bake those limitations in here.\n//\n// Even without that issue, we want our system allocator to handle holes, that\n// is, it should merge freed regions and allow allocating new content there of\n// the full size, etc., so that we do not waste space. That means that the\n// system allocator really does need to handle the general problem of allocating\n// and freeing variable-sized chunks of memory in a random order, like malloc/\n// free do. And so it makes sense to layer mimalloc on top of such an\n// implementation.\n//\n// emmalloc makes sense for the lower level because it is small and simple while\n// still fully handling merging of holes etc. It is not the most efficient\n// allocator, but our assumption is that mimalloc needs to be fast while the\n// system allocator underneath it is called much less frequently.\n//\n\n//---------------------------------------------\n// init\n//---------------------------------------------\n\nvoid _mi_prim_mem_init( mi_os_mem_config_t* config) {\n  config->page_size = 64*MI_KiB; // WebAssembly has a fixed page size: 64KiB\n  config->alloc_granularity = 16;\n  config->has_overcommit = false;\n  config->has_partial_free = false;\n  config->has_virtual_reserve = false;\n}\n\nextern void emmalloc_free(void*);\n\nint _mi_prim_free(void* addr, size_t size) {\n  if (size==0) return 0;\n  emmalloc_free(addr);\n  return 0;\n}\n\n\n//---------------------------------------------\n// Allocation\n//---------------------------------------------\n\nextern void* emmalloc_memalign(size_t alignment, size_t size);\n\n// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.\nint _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) {\n  MI_UNUSED(try_alignment); MI_UNUSED(allow_large); MI_UNUSED(commit); MI_UNUSED(hint_addr);\n  *is_large = false;\n  // TODO: Track the highest address ever seen; first uses of it are zeroes.\n  //       That assumes no one else uses sbrk but us (they could go up,\n  //       scribble, and then down), but we could assert on that perhaps.\n  *is_zero = false;\n  // emmalloc has a minimum alignment size.\n  #define MIN_EMMALLOC_ALIGN           8\n  if (try_alignment < MIN_EMMALLOC_ALIGN) {\n    try_alignment = MIN_EMMALLOC_ALIGN;\n  }\n  void* p = emmalloc_memalign(try_alignment, size);\n  *addr = p;\n  if (p == 0) {\n    return ENOMEM;\n  }\n  return 0;\n}\n\n\n//---------------------------------------------\n// Commit/Reset\n//---------------------------------------------\n\nint _mi_prim_commit(void* addr, size_t size, bool* is_zero) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  // See TODO above.\n  *is_zero = false;\n  return 0;\n}\n\nint _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  *needs_recommit = false;\n  return 0;\n}\n\nint _mi_prim_reset(void* addr, size_t size) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  return 0;\n}\n\nint _mi_prim_reuse(void* addr, size_t size) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  return 0;\n}\n\nint _mi_prim_protect(void* addr, size_t size, bool protect) {\n  MI_UNUSED(addr); MI_UNUSED(size); MI_UNUSED(protect);\n  return 0;\n}\n\n\n//---------------------------------------------\n// Huge pages and NUMA nodes\n//---------------------------------------------\n\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {\n  MI_UNUSED(hint_addr); MI_UNUSED(size); MI_UNUSED(numa_node);\n  *is_zero = true;\n  *addr = NULL;\n  return ENOSYS;\n}\n\nsize_t _mi_prim_numa_node(void) {\n  return 0;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  return 1;\n}\n\n\n//----------------------------------------------------------------\n// Clock\n//----------------------------------------------------------------\n\n#include <emscripten/html5.h>\n\nmi_msecs_t _mi_prim_clock_now(void) {\n  return emscripten_date_now();\n}\n\n\n//----------------------------------------------------------------\n// Process info\n//----------------------------------------------------------------\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo)\n{\n  // use defaults\n  MI_UNUSED(pinfo);\n}\n\n\n//----------------------------------------------------------------\n// Output\n//----------------------------------------------------------------\n\n#include <emscripten/console.h>\n\nvoid _mi_prim_out_stderr( const char* msg) {\n  emscripten_console_error(msg);\n}\n\n\n//----------------------------------------------------------------\n// Environment\n//----------------------------------------------------------------\n\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size) {\n  // For code size reasons, do not support environ customization for now.\n  MI_UNUSED(name);\n  MI_UNUSED(result);\n  MI_UNUSED(result_size);\n  return false;\n}\n\n\n//----------------------------------------------------------------\n// Random\n//----------------------------------------------------------------\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  int err = getentropy(buf, buf_len);\n  return !err;\n}\n\n\n//----------------------------------------------------------------\n// Thread init/done\n//----------------------------------------------------------------\n\n#if defined(MI_USE_PTHREADS)\n\n// use pthread local storage keys to detect thread ending\n// (and used with MI_TLS_PTHREADS for the default heap)\npthread_key_t _mi_heap_default_key = (pthread_key_t)(-1);\n\nstatic void mi_pthread_done(void* value) {\n  if (value!=NULL) {\n    _mi_thread_done((mi_heap_t*)value);\n  }\n}\n\nvoid _mi_prim_thread_init_auto_done(void) {\n  mi_assert_internal(_mi_heap_default_key == (pthread_key_t)(-1));\n  pthread_key_create(&_mi_heap_default_key, &mi_pthread_done);\n}\n\nvoid _mi_prim_thread_done_auto_done(void) {\n  if (_mi_heap_default_key != (pthread_key_t)(-1)) {  // do not leak the key, see issue #809\n    pthread_key_delete(_mi_heap_default_key);\n  }\n}\n\nvoid _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {\n  if (_mi_heap_default_key != (pthread_key_t)(-1)) {  // can happen during recursive invocation on freeBSD\n    pthread_setspecific(_mi_heap_default_key, heap);\n  }\n}\n\n#else\n\nvoid _mi_prim_thread_init_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_done_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {\n  MI_UNUSED(heap);\n\n}\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/prim/osx/alloc-override-zone.c",
      "sha256": "1d0a5f40f7ab1cf8614cfd71c49d885fd129b9bf17b5ce6da2dcd4bae5880bf0",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2022, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n\n#if defined(MI_MALLOC_OVERRIDE)\n\n#if !defined(__APPLE__)\n#error \"this file should only be included on macOS\"\n#endif\n\n/* ------------------------------------------------------\n   Override system malloc on macOS\n   This is done through the malloc zone interface.\n   It seems to be most robust in combination with interposing\n   though or otherwise we may get zone errors as there are could\n   be allocations done by the time we take over the\n   zone.\n------------------------------------------------------ */\n\n#include <AvailabilityMacros.h>\n#include <malloc/malloc.h>\n#include <string.h>  // memset\n#include <stdlib.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)\n// only available from OSX 10.6\nextern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_import));\n#endif\n\n/* ------------------------------------------------------\n   malloc zone members\n------------------------------------------------------ */\n\nstatic size_t zone_size(malloc_zone_t* zone, const void* p) {\n  MI_UNUSED(zone);\n  if (!mi_is_in_heap_region(p)){ return 0; } // not our pointer, bail out\n  return mi_usable_size(p);\n}\n\nstatic void* zone_malloc(malloc_zone_t* zone, size_t size) {\n  MI_UNUSED(zone);\n  return mi_malloc(size);\n}\n\nstatic void* zone_calloc(malloc_zone_t* zone, size_t count, size_t size) {\n  MI_UNUSED(zone);\n  return mi_calloc(count, size);\n}\n\nstatic void* zone_valloc(malloc_zone_t* zone, size_t size) {\n  MI_UNUSED(zone);\n  return mi_malloc_aligned(size, _mi_os_page_size());\n}\n\nstatic void zone_free(malloc_zone_t* zone, void* p) {\n  MI_UNUSED(zone);\n  mi_cfree(p);\n}\n\nstatic void* zone_realloc(malloc_zone_t* zone, void* p, size_t newsize) {\n  MI_UNUSED(zone);\n  return mi_realloc(p, newsize);\n}\n\nstatic void* zone_memalign(malloc_zone_t* zone, size_t alignment, size_t size) {\n  MI_UNUSED(zone);\n  return mi_malloc_aligned(size,alignment);\n}\n\nstatic void zone_destroy(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  // todo: ignore for now?\n}\n\nstatic unsigned zone_batch_malloc(malloc_zone_t* zone, size_t size, void** ps, unsigned count) {\n  unsigned i;\n  for (i = 0; i < count; i++) {\n    ps[i] = zone_malloc(zone, size);\n    if (ps[i] == NULL) break;\n  }\n  return i;\n}\n\nstatic void zone_batch_free(malloc_zone_t* zone, void** ps, unsigned count) {\n  for(size_t i = 0; i < count; i++) {\n    zone_free(zone, ps[i]);\n    ps[i] = NULL;\n  }\n}\n\nstatic size_t zone_pressure_relief(malloc_zone_t* zone, size_t size) {\n  MI_UNUSED(zone); MI_UNUSED(size);\n  mi_collect(false);\n  return 0;\n}\n\nstatic void zone_free_definite_size(malloc_zone_t* zone, void* p, size_t size) {\n  MI_UNUSED(size);\n  zone_free(zone,p);\n}\n\nstatic boolean_t zone_claimed_address(malloc_zone_t* zone, void* p) {\n  MI_UNUSED(zone);\n  return mi_is_in_heap_region(p);\n}\n\n\n/* ------------------------------------------------------\n   Introspection members\n------------------------------------------------------ */\n\nstatic kern_return_t intro_enumerator(task_t task, void* p,\n                            unsigned type_mask, vm_address_t zone_address,\n                            memory_reader_t reader,\n                            vm_range_recorder_t recorder)\n{\n  // todo: enumerate all memory\n  MI_UNUSED(task); MI_UNUSED(p); MI_UNUSED(type_mask); MI_UNUSED(zone_address);\n  MI_UNUSED(reader); MI_UNUSED(recorder);\n  return KERN_SUCCESS;\n}\n\nstatic size_t intro_good_size(malloc_zone_t* zone, size_t size) {\n  MI_UNUSED(zone);\n  return mi_good_size(size);\n}\n\nstatic boolean_t intro_check(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  return true;\n}\n\nstatic void intro_print(malloc_zone_t* zone, boolean_t verbose) {\n  MI_UNUSED(zone); MI_UNUSED(verbose);\n  mi_stats_print(NULL);\n}\n\nstatic void intro_log(malloc_zone_t* zone, void* p) {\n  MI_UNUSED(zone); MI_UNUSED(p);\n  // todo?\n}\n\nstatic void intro_force_lock(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  // todo?\n}\n\nstatic void intro_force_unlock(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  // todo?\n}\n\nstatic void intro_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) {\n  MI_UNUSED(zone);\n  // todo...\n  stats->blocks_in_use = 0;\n  stats->size_in_use = 0;\n  stats->max_size_in_use = 0;\n  stats->size_allocated = 0;\n}\n\nstatic boolean_t intro_zone_locked(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  return false;\n}\n\n\n/* ------------------------------------------------------\n  At process start, override the default allocator\n------------------------------------------------------ */\n\n#if defined(__GNUC__) && !defined(__clang__)\n#pragma GCC diagnostic ignored \"-Wmissing-field-initializers\"\n#endif\n\n#if defined(__clang__)\n#pragma clang diagnostic ignored \"-Wc99-extensions\"\n#endif\n\nstatic malloc_introspection_t mi_introspect = {\n  .enumerator = &intro_enumerator,\n  .good_size = &intro_good_size,\n  .check = &intro_check,\n  .print = &intro_print,\n  .log = &intro_log,\n  .force_lock = &intro_force_lock,\n  .force_unlock = &intro_force_unlock,\n#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) && !defined(__ppc__)\n  .statistics = &intro_statistics,\n  .zone_locked = &intro_zone_locked,\n#endif\n};\n\nstatic malloc_zone_t mi_malloc_zone = {\n  // note: even with designators, the order is important for C++ compilation\n  //.reserved1 = NULL,\n  //.reserved2 = NULL,\n  .size = &zone_size,\n  .malloc = &zone_malloc,\n  .calloc = &zone_calloc,\n  .valloc = &zone_valloc,\n  .free = &zone_free,\n  .realloc = &zone_realloc,\n  .destroy = &zone_destroy,\n  .zone_name = \"mimalloc\",\n  .batch_malloc = &zone_batch_malloc,\n  .batch_free = &zone_batch_free,\n  .introspect = &mi_introspect,\n#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) && !defined(__ppc__)\n  #if defined(MAC_OS_X_VERSION_10_14) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14)\n  .version = 10,\n  #else\n  .version = 9,\n  #endif\n  // switch to version 9+ on OSX 10.6 to support memalign.\n  .memalign = &zone_memalign,\n  .free_definite_size = &zone_free_definite_size,\n  #if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)\n  .pressure_relief = &zone_pressure_relief,\n  #endif\n  #if defined(MAC_OS_X_VERSION_10_14) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14)\n  .claimed_address = &zone_claimed_address,\n  #endif\n#else\n  .version = 4,\n#endif\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#if defined(MI_OSX_INTERPOSE) && defined(MI_SHARED_LIB_EXPORT)\n\n// ------------------------------------------------------\n// Override malloc_xxx and malloc_zone_xxx api's to use only\n// our mimalloc zone. Since even the loader uses malloc\n// on macOS, this ensures that all allocations go through\n// mimalloc (as all calls are interposed).\n// The main `malloc`, `free`, etc calls are interposed in `alloc-override.c`,\n// Here, we also override macOS specific API's like\n// `malloc_zone_calloc` etc. see <https://github.com/aosm/libmalloc/blob/master/man/malloc_zone_malloc.3>\n// ------------------------------------------------------\n\nstatic inline malloc_zone_t* mi_get_default_zone(void) {\n  mi_atomic_do_once {\n    malloc_zone_register(&mi_malloc_zone);  // by calling register we avoid a zone error on free (see <http://eatmyrandom.blogspot.com/2010/03/mallocfree-interception-on-mac-os-x.html>)\n  }\n  return &mi_malloc_zone;\n}\n\nmi_decl_externc int  malloc_jumpstart(uintptr_t cookie);\nmi_decl_externc void _malloc_fork_prepare(void);\nmi_decl_externc void _malloc_fork_parent(void);\nmi_decl_externc void _malloc_fork_child(void);\n\n\nstatic malloc_zone_t* mi_malloc_create_zone(vm_size_t size, unsigned flags) {\n  MI_UNUSED(size); MI_UNUSED(flags);\n  return mi_get_default_zone();\n}\n\nstatic malloc_zone_t* mi_malloc_default_zone (void) {\n  return mi_get_default_zone();\n}\n\nstatic malloc_zone_t* mi_malloc_default_purgeable_zone(void) {\n  return mi_get_default_zone();\n}\n\nstatic void mi_malloc_destroy_zone(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  // nothing.\n}\n\nstatic kern_return_t mi_malloc_get_all_zones (task_t task, memory_reader_t mr, vm_address_t** addresses, unsigned* count) {\n  MI_UNUSED(task); MI_UNUSED(mr);\n  if (addresses != NULL) *addresses = NULL;\n  if (count != NULL) *count = 0;\n  return KERN_SUCCESS;\n}\n\nstatic const char* mi_malloc_get_zone_name(malloc_zone_t* zone) {\n  return (zone == NULL ? mi_malloc_zone.zone_name : zone->zone_name);\n}\n\nstatic void mi_malloc_set_zone_name(malloc_zone_t* zone, const char* name) {\n  MI_UNUSED(zone); MI_UNUSED(name);\n}\n\nstatic int mi_malloc_jumpstart(uintptr_t cookie) {\n  MI_UNUSED(cookie);\n  return 1; // or 0 for no error?\n}\n\nstatic void mi__malloc_fork_prepare(void) {\n  // nothing\n}\nstatic void mi__malloc_fork_parent(void) {\n  // nothing\n}\nstatic void mi__malloc_fork_child(void) {\n  // nothing\n}\n\nstatic void mi_malloc_printf(const char* fmt, ...) {\n  MI_UNUSED(fmt);\n}\n\nstatic bool zone_check(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  return true;\n}\n\nstatic malloc_zone_t* zone_from_ptr(const void* p) {\n  MI_UNUSED(p);\n  return (mi_is_in_heap_region(p) ? mi_get_default_zone() : NULL);\n}\n\nstatic void zone_log(malloc_zone_t* zone, void* p) {\n  MI_UNUSED(zone); MI_UNUSED(p);\n}\n\nstatic void zone_print(malloc_zone_t* zone, bool b) {\n  MI_UNUSED(zone); MI_UNUSED(b);\n}\n\nstatic void zone_print_ptr_info(void* p) {\n  MI_UNUSED(p);\n}\n\nstatic void zone_register(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n}\n\nstatic void zone_unregister(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n}\n\n// use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1`\n// See: <https://books.google.com/books?id=K8vUkpOXhN4C&pg=PA73>\nstruct mi_interpose_s {\n  const void* replacement;\n  const void* target;\n};\n#define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun }\n#define MI_INTERPOSE_MI(fun)            MI_INTERPOSE_FUN(fun,mi_##fun)\n#define MI_INTERPOSE_ZONE(fun)          MI_INTERPOSE_FUN(malloc_##fun,fun)\n__attribute__((used)) static const struct mi_interpose_s _mi_zone_interposes[]  __attribute__((section(\"__DATA, __interpose\"))) =\n{\n\n  MI_INTERPOSE_MI(malloc_create_zone),\n  MI_INTERPOSE_MI(malloc_default_purgeable_zone),\n  MI_INTERPOSE_MI(malloc_default_zone),\n  MI_INTERPOSE_MI(malloc_destroy_zone),\n  MI_INTERPOSE_MI(malloc_get_all_zones),\n  MI_INTERPOSE_MI(malloc_get_zone_name),\n  MI_INTERPOSE_MI(malloc_jumpstart),\n  MI_INTERPOSE_MI(malloc_printf),\n  MI_INTERPOSE_MI(malloc_set_zone_name),\n  MI_INTERPOSE_MI(_malloc_fork_child),\n  MI_INTERPOSE_MI(_malloc_fork_parent),\n  MI_INTERPOSE_MI(_malloc_fork_prepare),\n\n  MI_INTERPOSE_ZONE(zone_batch_free),\n  MI_INTERPOSE_ZONE(zone_batch_malloc),\n  MI_INTERPOSE_ZONE(zone_calloc),\n  MI_INTERPOSE_ZONE(zone_check),\n  MI_INTERPOSE_ZONE(zone_free),\n  MI_INTERPOSE_ZONE(zone_from_ptr),\n  MI_INTERPOSE_ZONE(zone_log),\n  MI_INTERPOSE_ZONE(zone_malloc),\n  MI_INTERPOSE_ZONE(zone_memalign),\n  MI_INTERPOSE_ZONE(zone_print),\n  MI_INTERPOSE_ZONE(zone_print_ptr_info),\n  MI_INTERPOSE_ZONE(zone_realloc),\n  MI_INTERPOSE_ZONE(zone_register),\n  MI_INTERPOSE_ZONE(zone_unregister),\n  MI_INTERPOSE_ZONE(zone_valloc)\n};\n\n\n#else\n\n// ------------------------------------------------------\n// hook into the zone api's without interposing\n// This is the official way of adding an allocator but\n// it seems less robust than using interpose.\n// ------------------------------------------------------\n\nstatic inline malloc_zone_t* mi_get_default_zone(void)\n{\n  // The first returned zone is the real default\n  malloc_zone_t** zones = NULL;\n  unsigned count = 0;\n  kern_return_t ret = malloc_get_all_zones(0, NULL, (vm_address_t**)&zones, &count);\n  if (ret == KERN_SUCCESS && count > 0) {\n    return zones[0];\n  }\n  else {\n    // fallback\n    return malloc_default_zone();\n  }\n}\n\n#if defined(__clang__)\n__attribute__((constructor(101))) // highest priority\n#else\n__attribute__((constructor))      // priority level is not supported by gcc\n#endif\n__attribute__((used))\nstatic void _mi_macos_override_malloc(void) {\n  malloc_zone_t* purgeable_zone = NULL;\n\n  #if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)\n  // force the purgeable zone to exist to avoid strange bugs\n  if (malloc_default_purgeable_zone) {\n    purgeable_zone = malloc_default_purgeable_zone();\n  }\n  #endif\n\n  // Register our zone.\n  // thomcc: I think this is still needed to put us in the zone list.\n  malloc_zone_register(&mi_malloc_zone);\n  // Unregister the default zone, this makes our zone the new default\n  // as that was the last registered.\n  malloc_zone_t *default_zone = mi_get_default_zone();\n  // thomcc: Unsure if the next test is *always* false or just false in the\n  // cases I've tried. I'm also unsure if the code inside is needed. at all\n  if (default_zone != &mi_malloc_zone) {\n    malloc_zone_unregister(default_zone);\n\n    // Reregister the default zone so free and realloc in that zone keep working.\n    malloc_zone_register(default_zone);\n  }\n\n  // Unregister, and re-register the purgeable_zone to avoid bugs if it occurs\n  // earlier than the default zone.\n  if (purgeable_zone != NULL) {\n    malloc_zone_unregister(purgeable_zone);\n    malloc_zone_register(purgeable_zone);\n  }\n\n}\n#endif  // MI_OSX_INTERPOSE\n\n#endif // MI_MALLOC_OVERRIDE\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/prim/osx/prim.c",
      "sha256": "247a9952465eb105be03a9962e922b085ce5d52034775551a61cd8594275be73",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// We use the unix/prim.c with the mmap API on macOSX\n#include \"../unix/prim.c\"\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/prim/prim.c",
      "sha256": "cc771788e5ba591efb681829a8724f8662a1f50f3db39cf5ebe7738b8ed57e44",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// Select the implementation of the primitives\n// depending on the OS.\n\n#if defined(_WIN32)\n#include \"windows/prim.c\"  // VirtualAlloc (Windows)\n\n#elif defined(__APPLE__)\n#include \"osx/prim.c\"      // macOSX (actually defers to mmap in unix/prim.c)\n\n#elif defined(__wasi__)\n#define MI_USE_SBRK\n#include \"wasi/prim.c\"     // memory-grow or sbrk (Wasm)\n\n#elif defined(__EMSCRIPTEN__)\n#include \"emscripten/prim.c\" // emmalloc_*, + pthread support\n\n#else\n#include \"unix/prim.c\"     // mmap() (Linux, macOSX, BSD, Illumnos, Haiku, DragonFly, etc.)\n\n#endif\n\n// Generic process initialization\n#ifndef MI_PRIM_HAS_PROCESS_ATTACH\n#if defined(__GNUC__) || defined(__clang__)\n  // gcc,clang: use the constructor/destructor attribute\n  // which for both seem to run before regular constructors/destructors\n  #if defined(__clang__)\n    #define mi_attr_constructor __attribute__((constructor(101)))\n    #define mi_attr_destructor  __attribute__((destructor(101)))\n  #else\n    #define mi_attr_constructor __attribute__((constructor))\n    #define mi_attr_destructor  __attribute__((destructor))\n  #endif\n  static void mi_attr_constructor mi_process_attach(void) {\n    _mi_auto_process_init();\n  }\n  static void mi_attr_destructor mi_process_detach(void) {\n    _mi_auto_process_done();\n  }\n#elif defined(__cplusplus)\n  // C++: use static initialization to detect process start/end\n  // This is not guaranteed to be first/last but the best we can generally do?\n  struct mi_init_done_t {\n    mi_init_done_t() {\n      _mi_auto_process_init();\n    }\n    ~mi_init_done_t() {\n      _mi_auto_process_done();\n    }\n  };\n  static mi_init_done_t mi_init_done;\n #else\n  #pragma message(\"define a way to call _mi_auto_process_init/done on your platform\")\n#endif\n#endif\n\n// Generic allocator init/done callback\n#ifndef MI_PRIM_HAS_ALLOCATOR_INIT\nbool _mi_is_redirected(void) {\n  return false;\n}\nbool _mi_allocator_init(const char** message) {\n  if (message != NULL) { *message = NULL; }\n  return true;\n}\nvoid _mi_allocator_done(void) {\n  // nothing to do\n}\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/prim/unix/prim.c",
      "sha256": "0ebab4f3b989fbb347f776a14183d55ee09d05df711815468a7bfb75cc0a5881",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// This file is included in `src/prim/prim.c`\n\n#ifndef _DEFAULT_SOURCE\n#define _DEFAULT_SOURCE   // ensure mmap flags and syscall are defined\n#endif\n\n#if defined(__sun)\n// illumos provides new mman.h api when any of these are defined\n// otherwise the old api based on caddr_t which predates the void pointers one.\n// stock solaris provides only the former, chose to atomically to discard those\n// flags only here rather than project wide tough.\n#undef _XOPEN_SOURCE\n#undef _POSIX_C_SOURCE\n#endif\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"\n\n#include <sys/mman.h>  // mmap\n#include <unistd.h>    // sysconf\n#include <fcntl.h>     // open, close, read, access\n#include <stdlib.h>    // getenv, arc4random_buf\n\n#if defined(__linux__)\n  #include <features.h>\n  #include <sys/prctl.h>    // THP disable, PR_SET_VMA\n  #include <sys/sysinfo.h>  // sysinfo\n  #if defined(__GLIBC__) && !defined(PR_SET_VMA)\n  #include <linux/prctl.h>\n  #endif\n  #if defined(__GLIBC__)\n  #include <linux/mman.h>   // linux mmap flags\n  #else\n  #include <sys/mman.h>\n  #endif\n#elif defined(__APPLE__)\n  #include <AvailabilityMacros.h>\n  #include <TargetConditionals.h>\n  #if !defined(TARGET_OS_OSX) || TARGET_OS_OSX   // see issue #879, used to be (!TARGET_IOS_IPHONE && !TARGET_IOS_SIMULATOR)\n  #include <mach/vm_statistics.h>    // VM_MAKE_TAG, VM_FLAGS_SUPERPAGE_SIZE_2MB, etc.\n  #endif\n  #if !defined(MAC_OS_X_VERSION_10_7)\n  #define MAC_OS_X_VERSION_10_7   1070\n  #endif\n  #include <sys/sysctl.h>\n#elif defined(__FreeBSD__) || defined(__DragonFly__)\n  #include <sys/param.h>\n  #if __FreeBSD_version >= 1200000\n  #include <sys/cpuset.h>\n  #include <sys/domainset.h>\n  #endif\n  #include <sys/sysctl.h>\n#endif\n\n#if (defined(__linux__) && !defined(__ANDROID__)) || defined(__FreeBSD__)\n  #define MI_HAS_SYSCALL_H\n  #include <sys/syscall.h>\n#endif\n\n#if !defined(MADV_DONTNEED) && defined(POSIX_MADV_DONTNEED)  // QNX\n#define MADV_DONTNEED  POSIX_MADV_DONTNEED\n#endif\n#if !defined(MADV_FREE) && defined(POSIX_MADV_FREE)  // QNX\n#define MADV_FREE  POSIX_MADV_FREE\n#endif\n\n#define MI_UNIX_LARGE_PAGE_SIZE (2*MI_MiB) // TODO: can we query the OS for this?\n\n//------------------------------------------------------------------------------------\n// Use syscalls for some primitives to allow for libraries that override open/read/close etc.\n// and do allocation themselves; using syscalls prevents recursion when mimalloc is\n// still initializing (issue #713)\n// Declare inline to avoid unused function warnings.\n//------------------------------------------------------------------------------------\n\n#if defined(MI_HAS_SYSCALL_H) && defined(SYS_open) && defined(SYS_close) && defined(SYS_read) && defined(SYS_access)\n\nstatic inline int mi_prim_open(const char* fpath, int open_flags) {\n  return syscall(SYS_open,fpath,open_flags,0);\n}\nstatic inline ssize_t mi_prim_read(int fd, void* buf, size_t bufsize) {\n  return syscall(SYS_read,fd,buf,bufsize);\n}\nstatic inline int mi_prim_close(int fd) {\n  return syscall(SYS_close,fd);\n}\nstatic inline int mi_prim_access(const char *fpath, int mode) {\n  return syscall(SYS_access,fpath,mode);\n}\n\n#else\n\nstatic inline int mi_prim_open(const char* fpath, int open_flags) {\n  return open(fpath,open_flags);\n}\nstatic inline ssize_t mi_prim_read(int fd, void* buf, size_t bufsize) {\n  return read(fd,buf,bufsize);\n}\nstatic inline int mi_prim_close(int fd) {\n  return close(fd);\n}\nstatic inline int mi_prim_access(const char *fpath, int mode) {\n  return access(fpath,mode);\n}\n\n#endif\n\n\n\n//---------------------------------------------\n// init\n//---------------------------------------------\n\nstatic bool unix_detect_overcommit(void) {\n  bool os_overcommit = true;\n  #if defined(__linux__)\n    int fd = mi_prim_open(\"/proc/sys/vm/overcommit_memory\", O_RDONLY);\n    if (fd >= 0) {\n      char buf[32];\n      ssize_t nread = mi_prim_read(fd, &buf, sizeof(buf));\n      mi_prim_close(fd);\n      // <https://www.kernel.org/doc/Documentation/vm/overcommit-accounting>\n      // 0: heuristic overcommit, 1: always overcommit, 2: never overcommit (ignore NORESERVE)\n      if (nread >= 1) {\n        os_overcommit = (buf[0] == '0' || buf[0] == '1');\n      }\n    }\n  #elif defined(__FreeBSD__)\n    int val = 0;\n    size_t olen = sizeof(val);\n    if (sysctlbyname(\"vm.overcommit\", &val, &olen, NULL, 0) == 0) {\n      os_overcommit = (val != 0);\n    }\n  #else\n    // default: overcommit is true\n  #endif\n  return os_overcommit;\n}\n\n// try to detect the physical memory dynamically (if possible)\nstatic void unix_detect_physical_memory( size_t page_size, size_t* physical_memory_in_kib ) {\n  #if defined(CTL_HW) && (defined(HW_PHYSMEM64) || defined(HW_MEMSIZE))  // freeBSD, macOS\n    MI_UNUSED(page_size);\n    int64_t physical_memory = 0;\n    size_t length = sizeof(int64_t);\n    #if defined(HW_PHYSMEM64)\n    int mib[2] = { CTL_HW, HW_PHYSMEM64 };\n    #else\n    int mib[2] = { CTL_HW, HW_MEMSIZE };\n    #endif\n    const int err = sysctl(mib, 2, &physical_memory, &length, NULL, 0);\n    if (err==0 && physical_memory > 0) {\n      const int64_t phys_in_kib = physical_memory / MI_KiB;\n      if (phys_in_kib > 0 && (uint64_t)phys_in_kib <= SIZE_MAX) {\n        *physical_memory_in_kib = (size_t)phys_in_kib;\n      }\n    }\n  #elif defined(__linux__)\n    MI_UNUSED(page_size);\n    struct sysinfo info; _mi_memzero_var(info);\n    const int err = sysinfo(&info);\n    if (err==0 && info.mem_unit > 0 && info.totalram <= SIZE_MAX) {\n      if (info.mem_unit==MI_KiB) {\n        *physical_memory_in_kib = (size_t)info.totalram;\n      }\n      else {\n        size_t total = 0;\n        if (!mi_mul_overflow((size_t)info.totalram, (size_t)info.mem_unit, &total)) {\n          *physical_memory_in_kib = (total / MI_KiB);\n        }\n      }\n    }\n  #elif defined(_SC_PHYS_PAGES)  // do not use by default as it might cause allocation (by using `fopen` to parse /proc/meminfo) (issue #1100)\n    const long pphys = sysconf(_SC_PHYS_PAGES);\n    const size_t psize_in_kib = page_size / MI_KiB;\n    if (psize_in_kib > 0 && pphys > 0 && (unsigned long)pphys <= SIZE_MAX && (size_t)pphys <= (SIZE_MAX/psize_in_kib)) {\n      *physical_memory_in_kib = (size_t)pphys * psize_in_kib;\n    }\n  #endif\n}\n\nvoid _mi_prim_mem_init( mi_os_mem_config_t* config )\n{\n  long psize = sysconf(_SC_PAGESIZE);\n  if (psize > 0 && (unsigned long)psize < SIZE_MAX) {\n    config->page_size = (size_t)psize;\n    config->alloc_granularity = (size_t)psize;\n    unix_detect_physical_memory(config->page_size, &config->physical_memory_in_kib);\n  }\n  config->large_page_size = MI_UNIX_LARGE_PAGE_SIZE;\n  config->has_overcommit = unix_detect_overcommit();\n  config->has_partial_free = true;    // mmap can free in parts\n  config->has_virtual_reserve = true; // todo: check if this true for NetBSD?  (for anonymous mmap with PROT_NONE)\n\n  // disable transparent huge pages for this process?\n  #if (defined(__linux__) || defined(__ANDROID__)) && defined(PR_GET_THP_DISABLE)\n  if (!mi_option_is_enabled(mi_option_allow_thp)) // disable THP if requested through an option\n  {\n    if (prctl(PR_GET_THP_DISABLE, 0, 0, 0, 0) == 0) {   // -1 on error, 1 if already disabled\n      // Most likely since distros often come with always/madvise settings.\n      // Disabling only for mimalloc process rather than touching system wide settings\n      (void)prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0);\n    }\n  }\n  #endif\n}\n\n\n//---------------------------------------------\n// free\n//---------------------------------------------\n\nint _mi_prim_free(void* addr, size_t size ) {\n  if (size==0) return 0;\n  bool err = (munmap(addr, size) == -1);\n  return (err ? errno : 0);\n}\n\n\n//---------------------------------------------\n// mmap\n//---------------------------------------------\n\n// return errno on failure\nstatic int unix_madvise(void* addr, size_t size, int advice) {\n  #if defined(__sun)\n  const int res = madvise((caddr_t)addr, size, advice);  // Solaris needs cast (issue #520)\n  return (res==0 ? 0 : errno);\n  #elif defined(__QNX__)\n  return posix_madvise(addr, size, advice);              // posix returns errno\n  #else\n  const int res = madvise(addr, size, advice);           // linux returns -1 on failure and sets errno\n  return (res==0 ? 0 : errno);\n  #endif\n}\n\nstatic void* unix_mmap_prim(void* addr, size_t size, int protect_flags, int flags, int fd) {\n  void* p = mmap(addr, size, protect_flags, flags, fd, 0 /* offset */);\n  #if defined(__linux__) && defined(PR_SET_VMA)\n  if (p!=MAP_FAILED && p!=NULL) {\n    prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, p, size, \"mimalloc\");\n  }\n  #endif\n  return p;\n}\n\nstatic void* unix_mmap_prim_aligned(void* addr, size_t size, size_t try_alignment, int protect_flags, int flags, int fd) {\n  MI_UNUSED(try_alignment);\n  void* p = NULL;\n  #if defined(MAP_ALIGNED)  // BSD\n  if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) {\n    size_t n = mi_bsr(try_alignment);\n    if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) {  // alignment is a power of 2 and 4096 <= alignment <= 1GiB\n      p = unix_mmap_prim(addr, size, protect_flags, flags | MAP_ALIGNED(n), fd);\n      if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) {\n        int err = errno;\n        _mi_trace_message(\"unable to directly request aligned OS memory (error: %d (0x%x), size: 0x%zx bytes, alignment: 0x%zx, hint address: %p)\\n\", err, err, size, try_alignment, addr);\n      }\n      if (p!=MAP_FAILED) return p;\n      // fall back to regular mmap\n    }\n  }\n  #elif defined(MAP_ALIGN)  // Solaris\n  if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) {\n    p = unix_mmap_prim((void*)try_alignment, size, protect_flags, flags | MAP_ALIGN, fd);  // addr parameter is the required alignment\n    if (p!=MAP_FAILED) return p;\n    // fall back to regular mmap\n  }\n  #endif\n  #if (MI_INTPTR_SIZE >= 8) && !defined(MAP_ALIGNED)\n  // on 64-bit systems, use the virtual address area after 2TiB for 4MiB aligned allocations\n  if (addr == NULL) {\n    void* hint = _mi_os_get_aligned_hint(try_alignment, size);\n    if (hint != NULL) {\n      p = unix_mmap_prim(hint, size, protect_flags, flags, fd);\n      if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) {\n        #if MI_TRACK_ENABLED  // asan sometimes does not instrument errno correctly?\n        int err = 0;\n        #else\n        int err = errno;\n        #endif\n        _mi_trace_message(\"unable to directly request hinted aligned OS memory (error: %d (0x%x), size: 0x%zx bytes, alignment: 0x%zx, hint address: %p)\\n\", err, err, size, try_alignment, hint);\n      }\n      if (p!=MAP_FAILED) return p;\n      // fall back to regular mmap\n    }\n  }\n  #endif\n  // regular mmap\n  p = unix_mmap_prim(addr, size, protect_flags, flags, fd);\n  if (p!=MAP_FAILED) return p;\n  // failed to allocate\n  return NULL;\n}\n\nstatic int unix_mmap_fd(void) {\n  #if defined(VM_MAKE_TAG)\n  // macOS: tracking anonymous page with a specific ID. (All up to 98 are taken officially but LLVM sanitizers had taken 99)\n  int os_tag = (int)mi_option_get(mi_option_os_tag);\n  if (os_tag < 100 || os_tag > 255) { os_tag = 254; }\n  return VM_MAKE_TAG(os_tag);\n  #else\n  return -1;\n  #endif\n}\n\nstatic void* unix_mmap(void* addr, size_t size, size_t try_alignment, int protect_flags, bool large_only, bool allow_large, bool* is_large) {\n  #if !defined(MAP_ANONYMOUS)\n  #define MAP_ANONYMOUS  MAP_ANON\n  #endif\n  #if !defined(MAP_NORESERVE)\n  #define MAP_NORESERVE  0\n  #endif\n  void* p = NULL;\n  const int fd = unix_mmap_fd();\n  int flags = MAP_PRIVATE | MAP_ANONYMOUS;\n  if (_mi_os_has_overcommit()) {\n    flags |= MAP_NORESERVE;\n  }\n  #if defined(PROT_MAX)\n  protect_flags |= PROT_MAX(PROT_READ | PROT_WRITE); // BSD\n  #endif\n  // huge page allocation\n  if (allow_large && (large_only || (_mi_os_canuse_large_page(size, try_alignment) && mi_option_is_enabled(mi_option_allow_large_os_pages)))) {\n    static _Atomic(size_t) large_page_try_ok; // = 0;\n    size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok);\n    if (!large_only && try_ok > 0) {\n      // If the OS is not configured for large OS pages, or the user does not have\n      // enough permission, the `mmap` will always fail (but it might also fail for other reasons).\n      // Therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times\n      // to avoid too many failing calls to mmap.\n      mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1);\n    }\n    else {\n      int lflags = flags & ~MAP_NORESERVE;  // using NORESERVE on huge pages seems to fail on Linux\n      int lfd = fd;\n      #ifdef MAP_ALIGNED_SUPER\n      lflags |= MAP_ALIGNED_SUPER;\n      #endif\n      #ifdef MAP_HUGETLB\n      lflags |= MAP_HUGETLB;\n      #endif\n      #ifdef MAP_HUGE_1GB\n      static bool mi_huge_pages_available = true;\n      if (large_only && (size % MI_GiB) == 0 && mi_huge_pages_available) {\n        lflags |= MAP_HUGE_1GB;\n      }\n      else\n      #endif\n      {\n        #ifdef MAP_HUGE_2MB\n        lflags |= MAP_HUGE_2MB;\n        #endif\n      }\n      #ifdef VM_FLAGS_SUPERPAGE_SIZE_2MB\n      lfd |= VM_FLAGS_SUPERPAGE_SIZE_2MB;\n      #endif\n      if (large_only || lflags != flags) {\n        // try large OS page allocation\n        *is_large = true;\n        p = unix_mmap_prim_aligned(addr, size, try_alignment, protect_flags, lflags, lfd);\n        #ifdef MAP_HUGE_1GB\n        if (p == NULL && (lflags & MAP_HUGE_1GB) == MAP_HUGE_1GB) {\n          mi_huge_pages_available = false; // don't try huge 1GiB pages again\n          if (large_only) {\n            _mi_warning_message(\"unable to allocate huge (1GiB) page, trying large (2MiB) pages instead (errno: %i)\\n\", errno);\n          }\n          lflags = ((lflags & ~MAP_HUGE_1GB) | MAP_HUGE_2MB);\n          p = unix_mmap_prim_aligned(addr, size, try_alignment, protect_flags, lflags, lfd);\n        }\n        #endif\n        if (large_only) return p;\n        if (p == NULL) {\n          mi_atomic_store_release(&large_page_try_ok, (size_t)8);  // on error, don't try again for the next N allocations\n        }\n      }\n    }\n  }\n  // regular allocation\n  if (p == NULL) {\n    *is_large = false;\n    p = unix_mmap_prim_aligned(addr, size, try_alignment, protect_flags, flags, fd);\n    #if !defined(MI_NO_THP)\n    if (p != NULL && allow_large && mi_option_is_enabled(mi_option_allow_thp) && _mi_os_canuse_large_page(size, try_alignment)) {\n      #if defined(MADV_HUGEPAGE)\n      // Many Linux systems don't allow MAP_HUGETLB but they support instead\n      // transparent huge pages (THP). Generally, it is not required to call `madvise` with MADV_HUGE\n      // though since properly aligned allocations will already use large pages if available\n      // in that case -- in particular for our large regions (in `memory.c`).\n      // However, some systems only allow THP if called with explicit `madvise`, so\n      // when large OS pages are enabled for mimalloc, we call `madvise` anyways.\n      if (unix_madvise(p, size, MADV_HUGEPAGE) == 0) {\n        // *is_large = true; // possibly\n      };\n      #elif defined(__sun)\n      struct memcntl_mha cmd = {0};\n      cmd.mha_pagesize = _mi_os_large_page_size();\n      cmd.mha_cmd = MHA_MAPSIZE_VA;\n      if (memcntl((caddr_t)p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) {\n        // *is_large = true; // possibly\n      }\n      #endif\n    }\n    #endif\n  }\n  return p;\n}\n\n// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.\nint _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) {\n  mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);\n  mi_assert_internal(commit || !allow_large);\n  mi_assert_internal(try_alignment > 0);\n  *is_zero = true;\n  int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : PROT_NONE);\n  *addr = unix_mmap(hint_addr, size, try_alignment, protect_flags, false, allow_large, is_large);\n  return (*addr != NULL ? 0 : errno);\n}\n\n\n//---------------------------------------------\n// Commit/Reset\n//---------------------------------------------\n\nstatic void unix_mprotect_hint(int err) {\n  #if defined(__linux__) && (MI_SECURE>=5) // guard page around every mimalloc page\n  if (err == ENOMEM) {\n    _mi_warning_message(\"The next warning may be caused by a low memory map limit.\\n\"\n                        \"  On Linux this is controlled by the vm.max_map_count -- maybe increase it?\\n\"\n                        \"  For example: sudo sysctl -w vm.max_map_count=262144\\n\");\n  }\n  #else\n  MI_UNUSED(err);\n  #endif\n}\n\nint _mi_prim_commit(void* start, size_t size, bool* is_zero) {\n  // commit: ensure we can access the area\n  // note: we may think that *is_zero can be true since the memory\n  // was either from mmap PROT_NONE, or from decommit MADV_DONTNEED, but\n  // we sometimes call commit on a range with still partially committed\n  // memory and `mprotect` does not zero the range.\n  *is_zero = false;\n  int err = mprotect(start, size, (PROT_READ | PROT_WRITE));\n  if (err != 0) {\n    err = errno;\n    unix_mprotect_hint(err);\n  }\n  return err;\n}\n\nint _mi_prim_reuse(void* start, size_t size) {\n  MI_UNUSED(start); MI_UNUSED(size);\n  #if defined(__APPLE__) && defined(MADV_FREE_REUSE)\n  return unix_madvise(start, size, MADV_FREE_REUSE);\n  #endif\n  return 0;\n}\n\nint _mi_prim_decommit(void* start, size_t size, bool* needs_recommit) {\n  int err = 0;\n  #if defined(__APPLE__) && defined(MADV_FREE_REUSABLE)\n    // decommit on macOS: use MADV_FREE_REUSABLE as it does immediate rss accounting (issue #1097)\n    err = unix_madvise(start, size, MADV_FREE_REUSABLE);\n    if (err) { err = unix_madvise(start, size, MADV_DONTNEED); }\n  #else\n    // decommit: use MADV_DONTNEED as it decreases rss immediately (unlike MADV_FREE)\n    err = unix_madvise(start, size, MADV_DONTNEED);\n  #endif\n  #if !MI_DEBUG && MI_SECURE<=2\n    *needs_recommit = false;\n  #else\n    *needs_recommit = true;\n    mprotect(start, size, PROT_NONE);\n  #endif\n  /*\n  // decommit: use mmap with MAP_FIXED and PROT_NONE to discard the existing memory (and reduce rss)\n  *needs_recommit = true;\n  const int fd = unix_mmap_fd();\n  void* p = mmap(start, size, PROT_NONE, (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE), fd, 0);\n  if (p != start) { err = errno; }\n  */\n  return err;\n}\n\nint _mi_prim_reset(void* start, size_t size) {\n  int err = 0;\n\n  // on macOS can use MADV_FREE_REUSABLE (but we disable this for now as it seems slower)\n  #if 0 && defined(__APPLE__) && defined(MADV_FREE_REUSABLE)\n  err = unix_madvise(start, size, MADV_FREE_REUSABLE);\n  if (err==0) return 0;\n  // fall through\n  #endif\n\n  #if defined(MADV_FREE)\n  // Otherwise, we try to use `MADV_FREE` as that is the fastest. A drawback though is that it\n  // will not reduce the `rss` stats in tools like `top` even though the memory is available\n  // to other processes. With the default `MIMALLOC_PURGE_DECOMMITS=1` we ensure that by\n  // default `MADV_DONTNEED` is used though.\n  static _Atomic(size_t) advice = MI_ATOMIC_VAR_INIT(MADV_FREE);\n  int oadvice = (int)mi_atomic_load_relaxed(&advice);\n  while ((err = unix_madvise(start, size, oadvice)) != 0 && err == EAGAIN) { /* try again */ };\n  if (err == EINVAL && oadvice == MADV_FREE) {\n    // if MADV_FREE is not supported, fall back to MADV_DONTNEED from now on\n    mi_atomic_store_release(&advice, (size_t)MADV_DONTNEED);\n    err = unix_madvise(start, size, MADV_DONTNEED);\n  }\n  #else\n  err = unix_madvise(start, size, MADV_DONTNEED);\n  #endif\n  return err;\n}\n\nint _mi_prim_protect(void* start, size_t size, bool protect) {\n  int err = mprotect(start, size, protect ? PROT_NONE : (PROT_READ | PROT_WRITE));\n  if (err != 0) { err = errno; }\n  unix_mprotect_hint(err);\n  return err;\n}\n\n\n\n//---------------------------------------------\n// Huge page allocation\n//---------------------------------------------\n\n#if (MI_INTPTR_SIZE >= 8) && !defined(__HAIKU__) && !defined(__CYGWIN__)\n\n#ifndef MPOL_PREFERRED\n#define MPOL_PREFERRED 1\n#endif\n\n#if defined(MI_HAS_SYSCALL_H) && defined(SYS_mbind)\nstatic long mi_prim_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) {\n  return syscall(SYS_mbind, start, len, mode, nmask, maxnode, flags);\n}\n#else\nstatic long mi_prim_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) {\n  MI_UNUSED(start); MI_UNUSED(len); MI_UNUSED(mode); MI_UNUSED(nmask); MI_UNUSED(maxnode); MI_UNUSED(flags);\n  return 0;\n}\n#endif\n\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {\n  bool is_large = true;\n  *is_zero = true;\n  *addr = unix_mmap(hint_addr, size, MI_SEGMENT_SIZE, PROT_READ | PROT_WRITE, true, true, &is_large);\n  if (*addr != NULL && numa_node >= 0 && numa_node < 8*MI_INTPTR_SIZE) { // at most 64 nodes\n    unsigned long numa_mask = (1UL << numa_node);\n    // TODO: does `mbind` work correctly for huge OS pages? should we\n    // use `set_mempolicy` before calling mmap instead?\n    // see: <https://lkml.org/lkml/2017/2/9/875>\n    long err = mi_prim_mbind(*addr, size, MPOL_PREFERRED, &numa_mask, 8*MI_INTPTR_SIZE, 0);\n    if (err != 0) {\n      err = errno;\n      _mi_warning_message(\"failed to bind huge (1GiB) pages to numa node %d (error: %d (0x%x))\\n\", numa_node, err, err);\n    }\n  }\n  return (*addr != NULL ? 0 : errno);\n}\n\n#else\n\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {\n  MI_UNUSED(hint_addr); MI_UNUSED(size); MI_UNUSED(numa_node);\n  *is_zero = false;\n  *addr = NULL;\n  return ENOMEM;\n}\n\n#endif\n\n//---------------------------------------------\n// NUMA nodes\n//---------------------------------------------\n\n#if defined(__linux__)\n\nsize_t _mi_prim_numa_node(void) {\n  #if defined(MI_HAS_SYSCALL_H) && defined(SYS_getcpu)\n    unsigned long node = 0;\n    unsigned long ncpu = 0;\n    long err = syscall(SYS_getcpu, &ncpu, &node, NULL);\n    if (err != 0) return 0;\n    return node;\n  #else\n    return 0;\n  #endif\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  char buf[128];\n  unsigned node = 0;\n  for(node = 0; node < 256; node++) {\n    // enumerate node entries -- todo: it there a more efficient way to do this? (but ensure there is no allocation)\n    _mi_snprintf(buf, 127, \"/sys/devices/system/node/node%u\", node + 1);\n    if (mi_prim_access(buf,R_OK) != 0) break;\n  }\n  return (node+1);\n}\n\n#elif defined(__FreeBSD__) && __FreeBSD_version >= 1200000\n\nsize_t _mi_prim_numa_node(void) {\n  domainset_t dom;\n  size_t node;\n  int policy;\n  if (cpuset_getdomain(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, sizeof(dom), &dom, &policy) == -1) return 0ul;\n  for (node = 0; node < MAXMEMDOM; node++) {\n    if (DOMAINSET_ISSET(node, &dom)) return node;\n  }\n  return 0ul;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  size_t ndomains = 0;\n  size_t len = sizeof(ndomains);\n  if (sysctlbyname(\"vm.ndomains\", &ndomains, &len, NULL, 0) == -1) return 0ul;\n  return ndomains;\n}\n\n#elif defined(__DragonFly__)\n\nsize_t _mi_prim_numa_node(void) {\n  // TODO: DragonFly does not seem to provide any userland means to get this information.\n  return 0ul;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  size_t ncpus = 0, nvirtcoresperphys = 0;\n  size_t len = sizeof(size_t);\n  if (sysctlbyname(\"hw.ncpu\", &ncpus, &len, NULL, 0) == -1) return 0ul;\n  if (sysctlbyname(\"hw.cpu_topology_ht_ids\", &nvirtcoresperphys, &len, NULL, 0) == -1) return 0ul;\n  return nvirtcoresperphys * ncpus;\n}\n\n#else\n\nsize_t _mi_prim_numa_node(void) {\n  return 0;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  return 1;\n}\n\n#endif\n\n// ----------------------------------------------------------------\n// Clock\n// ----------------------------------------------------------------\n\n#include <time.h>\n\n#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC)\n\nmi_msecs_t _mi_prim_clock_now(void) {\n  struct timespec t;\n  #ifdef CLOCK_MONOTONIC\n  clock_gettime(CLOCK_MONOTONIC, &t);\n  #else\n  clock_gettime(CLOCK_REALTIME, &t);\n  #endif\n  return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000);\n}\n\n#else\n\n// low resolution timer\nmi_msecs_t _mi_prim_clock_now(void) {\n  #if !defined(CLOCKS_PER_SEC) || (CLOCKS_PER_SEC == 1000) || (CLOCKS_PER_SEC == 0)\n  return (mi_msecs_t)clock();\n  #elif (CLOCKS_PER_SEC < 1000)\n  return (mi_msecs_t)clock() * (1000 / (mi_msecs_t)CLOCKS_PER_SEC);\n  #else\n  return (mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000);\n  #endif\n}\n\n#endif\n\n\n\n\n//----------------------------------------------------------------\n// Process info\n//----------------------------------------------------------------\n\n#if defined(__unix__) || defined(__unix) || defined(unix) || defined(__APPLE__) || defined(__HAIKU__)\n#include <stdio.h>\n#include <unistd.h>\n#include <sys/resource.h>\n\n#if defined(__APPLE__)\n#include <mach/mach.h>\n#endif\n\n#if defined(__HAIKU__)\n#include <kernel/OS.h>\n#endif\n\nstatic mi_msecs_t timeval_secs(const struct timeval* tv) {\n  return ((mi_msecs_t)tv->tv_sec * 1000L) + ((mi_msecs_t)tv->tv_usec / 1000L);\n}\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo)\n{\n  struct rusage rusage;\n  getrusage(RUSAGE_SELF, &rusage);\n  pinfo->utime = timeval_secs(&rusage.ru_utime);\n  pinfo->stime = timeval_secs(&rusage.ru_stime);\n#if !defined(__HAIKU__)\n  pinfo->page_faults = rusage.ru_majflt;\n#endif\n#if defined(__HAIKU__)\n  // Haiku does not have (yet?) a way to\n  // get these stats per process\n  thread_info tid;\n  area_info mem;\n  ssize_t c;\n  get_thread_info(find_thread(0), &tid);\n  while (get_next_area_info(tid.team, &c, &mem) == B_OK) {\n    pinfo->peak_rss += mem.ram_size;\n  }\n  pinfo->page_faults = 0;\n#elif defined(__APPLE__)\n  pinfo->peak_rss = rusage.ru_maxrss;         // macos reports in bytes\n  #ifdef MACH_TASK_BASIC_INFO\n  struct mach_task_basic_info info;\n  mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;\n  if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) {\n    pinfo->current_rss = (size_t)info.resident_size;\n  }\n  #else\n  struct task_basic_info info;\n  mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;\n  if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) {\n    pinfo->current_rss = (size_t)info.resident_size;\n  }\n  #endif\n#else\n  pinfo->peak_rss = rusage.ru_maxrss * 1024;  // Linux/BSD report in KiB\n#endif\n  // use defaults for commit\n}\n\n#else\n\n#ifndef __wasi__\n// WebAssembly instances are not processes\n#pragma message(\"define a way to get process info\")\n#endif\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo)\n{\n  // use defaults\n  MI_UNUSED(pinfo);\n}\n\n#endif\n\n\n//----------------------------------------------------------------\n// Output\n//----------------------------------------------------------------\n\nvoid _mi_prim_out_stderr( const char* msg ) {\n  fputs(msg,stderr);\n}\n\n\n//----------------------------------------------------------------\n// Environment\n//----------------------------------------------------------------\n\n#if !defined(MI_USE_ENVIRON) || (MI_USE_ENVIRON!=0)\n// On Posix systemsr use `environ` to access environment variables\n// even before the C runtime is initialized.\n#if defined(__APPLE__) && defined(__has_include) && __has_include(<crt_externs.h>)\n#include <crt_externs.h>\nstatic char** mi_get_environ(void) {\n  return (*_NSGetEnviron());\n}\n#else\nextern char** environ;\nstatic char** mi_get_environ(void) {\n  return environ;\n}\n#endif\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size) {\n  if (name==NULL) return false;\n  const size_t len = _mi_strlen(name);\n  if (len == 0) return false;\n  char** env = mi_get_environ();\n  if (env == NULL) return false;\n  // compare up to 10000 entries\n  for (int i = 0; i < 10000 && env[i] != NULL; i++) {\n    const char* s = env[i];\n    if (_mi_strnicmp(name, s, len) == 0 && s[len] == '=') { // case insensitive\n      // found it\n      _mi_strlcpy(result, s + len + 1, result_size);\n      return true;\n    }\n  }\n  return false;\n}\n#else\n// fallback: use standard C `getenv` but this cannot be used while initializing the C runtime\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size) {\n  // cannot call getenv() when still initializing the C runtime.\n  if (_mi_preloading()) return false;\n  const char* s = getenv(name);\n  if (s == NULL) {\n    // we check the upper case name too.\n    char buf[64+1];\n    size_t len = _mi_strnlen(name,sizeof(buf)-1);\n    for (size_t i = 0; i < len; i++) {\n      buf[i] = _mi_toupper(name[i]);\n    }\n    buf[len] = 0;\n    s = getenv(buf);\n  }\n  if (s == NULL || _mi_strnlen(s,result_size) >= result_size)  return false;\n  _mi_strlcpy(result, s, result_size);\n  return true;\n}\n#endif  // !MI_USE_ENVIRON\n\n\n//----------------------------------------------------------------\n// Random\n//----------------------------------------------------------------\n\n#if defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_15) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_15)\n#include <CommonCrypto/CommonCryptoError.h>\n#include <CommonCrypto/CommonRandom.h>\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  // We prefer CCRandomGenerateBytes as it returns an error code while arc4random_buf\n  // may fail silently on macOS. See PR #390, and <https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/FreeBSD/arc4random.c.auto.html>\n  return (CCRandomGenerateBytes(buf, buf_len) == kCCSuccess);\n}\n\n#elif defined(__ANDROID__) || defined(__DragonFly__) || \\\n      defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \\\n      defined(__sun) || \\\n      (defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7))\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  arc4random_buf(buf, buf_len);\n  return true;\n}\n\n#elif defined(__APPLE__) || defined(__linux__) || defined(__HAIKU__)   // also for old apple versions < 10.7 (issue #829)\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <errno.h>\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  // Modern Linux provides `getrandom` but different distributions either use `sys/random.h` or `linux/random.h`\n  // and for the latter the actual `getrandom` call is not always defined.\n  // (see <https://stackoverflow.com/questions/45237324/why-doesnt-getrandom-compile>)\n  // We therefore use a syscall directly and fall back dynamically to /dev/urandom when needed.\n  #if defined(MI_HAS_SYSCALL_H) && defined(SYS_getrandom)\n    #ifndef GRND_NONBLOCK\n    #define GRND_NONBLOCK (1)\n    #endif\n    static _Atomic(uintptr_t) no_getrandom; // = 0\n    if (mi_atomic_load_acquire(&no_getrandom)==0) {\n      ssize_t ret = syscall(SYS_getrandom, buf, buf_len, GRND_NONBLOCK);\n      if (ret >= 0) return (buf_len == (size_t)ret);\n      if (errno != ENOSYS) return false;\n      mi_atomic_store_release(&no_getrandom, (uintptr_t)1); // don't call again, and fall back to /dev/urandom\n    }\n  #endif\n  int flags = O_RDONLY;\n  #if defined(O_CLOEXEC)\n  flags |= O_CLOEXEC;\n  #endif\n  int fd = mi_prim_open(\"/dev/urandom\", flags);\n  if (fd < 0) return false;\n  size_t count = 0;\n  while(count < buf_len) {\n    ssize_t ret = mi_prim_read(fd, (char*)buf + count, buf_len - count);\n    if (ret<=0) {\n      if (errno!=EAGAIN && errno!=EINTR) break;\n    }\n    else {\n      count += ret;\n    }\n  }\n  mi_prim_close(fd);\n  return (count==buf_len);\n}\n\n#else\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  return false;\n}\n\n#endif\n\n\n//----------------------------------------------------------------\n// Thread init/done\n//----------------------------------------------------------------\n\n#if defined(MI_USE_PTHREADS)\n\n// use pthread local storage keys to detect thread ending\n// (and used with MI_TLS_PTHREADS for the default heap)\npthread_key_t _mi_heap_default_key = (pthread_key_t)(-1);\n\nstatic void mi_pthread_done(void* value) {\n  if (value!=NULL) {\n    _mi_thread_done((mi_heap_t*)value);\n  }\n}\n\nvoid _mi_prim_thread_init_auto_done(void) {\n  mi_assert_internal(_mi_heap_default_key == (pthread_key_t)(-1));\n  pthread_key_create(&_mi_heap_default_key, &mi_pthread_done);\n}\n\nvoid _mi_prim_thread_done_auto_done(void) {\n  if (_mi_heap_default_key != (pthread_key_t)(-1)) {  // do not leak the key, see issue #809\n    pthread_key_delete(_mi_heap_default_key);\n  }\n}\n\nvoid _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {\n  if (_mi_heap_default_key != (pthread_key_t)(-1)) {  // can happen during recursive invocation on freeBSD\n    pthread_setspecific(_mi_heap_default_key, heap);\n  }\n}\n\n#else\n\nvoid _mi_prim_thread_init_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_done_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {\n  MI_UNUSED(heap);\n}\n\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/prim/wasi/prim.c",
      "sha256": "05a23fbcf2d96c693aaa4d9222780f3551c968356ee19d6d7d5dfdc6242cf049",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// This file is included in `src/prim/prim.c`\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"\n\n#include <stdio.h>   // fputs\n#include <stdlib.h>  // getenv\n\n//---------------------------------------------\n// Initialize\n//---------------------------------------------\n\nvoid _mi_prim_mem_init( mi_os_mem_config_t* config ) {\n  config->page_size = 64*MI_KiB; // WebAssembly has a fixed page size: 64KiB\n  config->alloc_granularity = 16;\n  config->has_overcommit = false;\n  config->has_partial_free = false;\n  config->has_virtual_reserve = false;\n}\n\n//---------------------------------------------\n// Free\n//---------------------------------------------\n\nint _mi_prim_free(void* addr, size_t size ) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  // wasi heap cannot be shrunk\n  return 0;\n}\n\n\n//---------------------------------------------\n// Allocation: sbrk or memory_grow\n//---------------------------------------------\n\n#if defined(MI_USE_SBRK)\n  #include <unistd.h>  // for sbrk\n\n  static void* mi_memory_grow( size_t size ) {\n    void* p = sbrk(size);\n    if (p == (void*)(-1)) return NULL;\n    #if !defined(__wasi__) // on wasi this is always zero initialized already (?)\n    memset(p,0,size);\n    #endif\n    return p;\n  }\n#elif defined(__wasi__)\n  static void* mi_memory_grow( size_t size ) {\n    size_t base = (size > 0 ? __builtin_wasm_memory_grow(0,_mi_divide_up(size, _mi_os_page_size()))\n                            : __builtin_wasm_memory_size(0));\n    if (base == SIZE_MAX) return NULL;\n    return (void*)(base * _mi_os_page_size());\n  }\n#endif\n\n#if defined(MI_USE_PTHREADS)\nstatic pthread_mutex_t mi_heap_grow_mutex = PTHREAD_MUTEX_INITIALIZER;\n#endif\n\nstatic void* mi_prim_mem_grow(size_t size, size_t try_alignment) {\n  void* p = NULL;\n  if (try_alignment <= 1) {\n    // `sbrk` is not thread safe in general so try to protect it (we could skip this on WASM but leave it in for now)\n    #if defined(MI_USE_PTHREADS)\n    pthread_mutex_lock(&mi_heap_grow_mutex);\n    #endif\n    p = mi_memory_grow(size);\n    #if defined(MI_USE_PTHREADS)\n    pthread_mutex_unlock(&mi_heap_grow_mutex);\n    #endif\n  }\n  else {\n    void* base = NULL;\n    size_t alloc_size = 0;\n    // to allocate aligned use a lock to try to avoid thread interaction\n    // between getting the current size and actual allocation\n    // (also, `sbrk` is not thread safe in general)\n    #if defined(MI_USE_PTHREADS)\n    pthread_mutex_lock(&mi_heap_grow_mutex);\n    #endif\n    {\n      void* current = mi_memory_grow(0);  // get current size\n      if (current != NULL) {\n        void* aligned_current = _mi_align_up_ptr(current, try_alignment);  // and align from there to minimize wasted space\n        alloc_size = _mi_align_up( ((uint8_t*)aligned_current - (uint8_t*)current) + size, _mi_os_page_size());\n        base = mi_memory_grow(alloc_size);\n      }\n    }\n    #if defined(MI_USE_PTHREADS)\n    pthread_mutex_unlock(&mi_heap_grow_mutex);\n    #endif\n    if (base != NULL) {\n      p = _mi_align_up_ptr(base, try_alignment);\n      if ((uint8_t*)p + size > (uint8_t*)base + alloc_size) {\n        // another thread used wasm_memory_grow/sbrk in-between and we do not have enough\n        // space after alignment. Give up (and waste the space as we cannot shrink :-( )\n        // (in `mi_os_mem_alloc_aligned` this will fall back to overallocation to align)\n        p = NULL;\n      }\n    }\n  }\n  /*\n  if (p == NULL) {\n    _mi_warning_message(\"unable to allocate sbrk/wasm_memory_grow OS memory (%zu bytes, %zu alignment)\\n\", size, try_alignment);\n    errno = ENOMEM;\n    return NULL;\n  }\n  */\n  mi_assert_internal( p == NULL || try_alignment == 0 || (uintptr_t)p % try_alignment == 0 );\n  return p;\n}\n\n// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.\nint _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) {\n  MI_UNUSED(allow_large); MI_UNUSED(commit); MI_UNUSED(hint_addr);\n  *is_large = false;\n  *is_zero = false;\n  *addr = mi_prim_mem_grow(size, try_alignment);\n  return (*addr != NULL ? 0 : ENOMEM);\n}\n\n\n//---------------------------------------------\n// Commit/Reset/Protect\n//---------------------------------------------\n\nint _mi_prim_commit(void* addr, size_t size, bool* is_zero) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  *is_zero = false;\n  return 0;\n}\n\nint _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  *needs_recommit = false;\n  return 0;\n}\n\nint _mi_prim_reset(void* addr, size_t size) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  return 0;\n}\n\nint _mi_prim_reuse(void* addr, size_t size) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  return 0;\n}\n\nint _mi_prim_protect(void* addr, size_t size, bool protect) {\n  MI_UNUSED(addr); MI_UNUSED(size); MI_UNUSED(protect);\n  return 0;\n}\n\n\n//---------------------------------------------\n// Huge pages and NUMA nodes\n//---------------------------------------------\n\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {\n  MI_UNUSED(hint_addr); MI_UNUSED(size); MI_UNUSED(numa_node);\n  *is_zero = true;\n  *addr = NULL;\n  return ENOSYS;\n}\n\nsize_t _mi_prim_numa_node(void) {\n  return 0;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  return 1;\n}\n\n\n//----------------------------------------------------------------\n// Clock\n//----------------------------------------------------------------\n\n#include <time.h>\n\n#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC)\n\nmi_msecs_t _mi_prim_clock_now(void) {\n  struct timespec t;\n  #ifdef CLOCK_MONOTONIC\n  clock_gettime(CLOCK_MONOTONIC, &t);\n  #else\n  clock_gettime(CLOCK_REALTIME, &t);\n  #endif\n  return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000);\n}\n\n#else\n\n// low resolution timer\nmi_msecs_t _mi_prim_clock_now(void) {\n  #if !defined(CLOCKS_PER_SEC) || (CLOCKS_PER_SEC == 1000) || (CLOCKS_PER_SEC == 0)\n  return (mi_msecs_t)clock();\n  #elif (CLOCKS_PER_SEC < 1000)\n  return (mi_msecs_t)clock() * (1000 / (mi_msecs_t)CLOCKS_PER_SEC);\n  #else\n  return (mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000);\n  #endif\n}\n\n#endif\n\n\n//----------------------------------------------------------------\n// Process info\n//----------------------------------------------------------------\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo)\n{\n  // use defaults\n  MI_UNUSED(pinfo);\n}\n\n\n//----------------------------------------------------------------\n// Output\n//----------------------------------------------------------------\n\nvoid _mi_prim_out_stderr( const char* msg ) {\n  fputs(msg,stderr);\n}\n\n\n//----------------------------------------------------------------\n// Environment\n//----------------------------------------------------------------\n\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size) {\n  // cannot call getenv() when still initializing the C runtime.\n  if (_mi_preloading()) return false;\n  const char* s = getenv(name);\n  if (s == NULL) {\n    // we check the upper case name too.\n    char buf[64+1];\n    size_t len = _mi_strnlen(name,sizeof(buf)-1);\n    for (size_t i = 0; i < len; i++) {\n      buf[i] = _mi_toupper(name[i]);\n    }\n    buf[len] = 0;\n    s = getenv(buf);\n  }\n  if (s == NULL || _mi_strnlen(s,result_size) >= result_size)  return false;\n  _mi_strlcpy(result, s, result_size);\n  return true;\n}\n\n\n//----------------------------------------------------------------\n// Random\n//----------------------------------------------------------------\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  return false;\n}\n\n\n//----------------------------------------------------------------\n// Thread init/done\n//----------------------------------------------------------------\n\nvoid _mi_prim_thread_init_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_done_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {\n  MI_UNUSED(heap);\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/prim/windows/etw.h",
      "sha256": "4f3110ef2054c95cb275be96cb279224d3d46a728c5117bd1435425f382de778",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "//**********************************************************************`\n//* This is an include file generated by Message Compiler.             *`\n//*                                                                    *`\n//* Copyright (c) Microsoft Corporation. All Rights Reserved.          *`\n//**********************************************************************`\n#pragma once\n\n//*****************************************************************************\n//\n// Notes on the ETW event code generated by MC:\n//\n// - Structures and arrays of structures are treated as an opaque binary blob.\n//   The caller is responsible for packing the data for the structure into a\n//   single region of memory, with no padding between values. The macro will\n//   have an extra parameter for the length of the blob.\n// - Arrays of nul-terminated strings must be packed by the caller into a\n//   single binary blob containing the correct number of strings, with a nul\n//   after each string. The size of the blob is specified in characters, and\n//   includes the final nul.\n// - Arrays of SID are treated as a single binary blob. The caller is\n//   responsible for packing the SID values into a single region of memory with\n//   no padding.\n// - The length attribute on the data element in the manifest is significant\n//   for values with intype win:UnicodeString, win:AnsiString, or win:Binary.\n//   The length attribute must be specified for win:Binary, and is optional for\n//   win:UnicodeString and win:AnsiString (if no length is given, the strings\n//   are assumed to be nul-terminated). For win:UnicodeString, the length is\n//   measured in characters, not bytes.\n// - For an array of win:UnicodeString, win:AnsiString, or win:Binary, the\n//   length attribute applies to every value in the array, so every value in\n//   the array must have the same length. The values in the array are provided\n//   to the macro via a single pointer -- the caller is responsible for packing\n//   all of the values into a single region of memory with no padding between\n//   values.\n// - Values of type win:CountedUnicodeString, win:CountedAnsiString, and\n//   win:CountedBinary can be generated and collected on Vista or later.\n//   However, they may not decode properly without the Windows 10 2018 Fall\n//   Update.\n// - Arrays of type win:CountedUnicodeString, win:CountedAnsiString, and\n//   win:CountedBinary must be packed by the caller into a single region of\n//   memory. The format for each item is a UINT16 byte-count followed by that\n//   many bytes of data. When providing the array to the generated macro, you\n//   must provide the total size of the packed array data, including the UINT16\n//   sizes for each item. In the case of win:CountedUnicodeString, the data\n//   size is specified in WCHAR (16-bit) units. In the case of\n//   win:CountedAnsiString and win:CountedBinary, the data size is specified in\n//   bytes.\n//\n//*****************************************************************************\n\n#include <wmistr.h>\n#include <evntrace.h>\n#include <evntprov.h>\n\n#ifndef ETW_INLINE\n  #ifdef _ETW_KM_\n    // In kernel mode, save stack space by never inlining templates.\n    #define ETW_INLINE DECLSPEC_NOINLINE __inline\n  #else\n    // In user mode, save code size by inlining templates as appropriate.\n    #define ETW_INLINE __inline\n  #endif\n#endif // ETW_INLINE\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n//\n// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:\n// Define this macro to have the compiler skip the generated functions in this\n// header.\n//\n#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n//\n// MCGEN_USE_KERNEL_MODE_APIS macro:\n// Controls whether the generated code uses kernel-mode or user-mode APIs.\n// - Set to 0 to use Windows user-mode APIs such as EventRegister.\n// - Set to 1 to use Windows kernel-mode APIs such as EtwRegister.\n// Default is based on whether the _ETW_KM_ macro is defined (i.e. by wdm.h).\n// Note that the APIs can also be overridden directly, e.g. by setting the\n// MCGEN_EVENTWRITETRANSFER or MCGEN_EVENTREGISTER macros.\n//\n#ifndef MCGEN_USE_KERNEL_MODE_APIS\n  #ifdef _ETW_KM_\n    #define MCGEN_USE_KERNEL_MODE_APIS 1\n  #else\n    #define MCGEN_USE_KERNEL_MODE_APIS 0\n  #endif\n#endif // MCGEN_USE_KERNEL_MODE_APIS\n\n//\n// MCGEN_HAVE_EVENTSETINFORMATION macro:\n// Controls how McGenEventSetInformation uses the EventSetInformation API.\n// - Set to 0 to disable the use of EventSetInformation\n//   (McGenEventSetInformation will always return an error).\n// - Set to 1 to directly invoke MCGEN_EVENTSETINFORMATION.\n// - Set to 2 to to locate EventSetInformation at runtime via GetProcAddress\n//   (user-mode) or MmGetSystemRoutineAddress (kernel-mode).\n// Default is determined as follows:\n// - If MCGEN_EVENTSETINFORMATION has been customized, set to 1\n//   (i.e. use MCGEN_EVENTSETINFORMATION).\n// - Else if the target OS version has EventSetInformation, set to 1\n//   (i.e. use MCGEN_EVENTSETINFORMATION).\n// - Else set to 2 (i.e. try to dynamically locate EventSetInformation).\n// Note that an McGenEventSetInformation function will only be generated if one\n// or more provider in a manifest has provider traits.\n//\n#ifndef MCGEN_HAVE_EVENTSETINFORMATION\n  #ifdef MCGEN_EVENTSETINFORMATION             // if MCGEN_EVENTSETINFORMATION has been customized,\n    #define MCGEN_HAVE_EVENTSETINFORMATION   1 //   directly invoke MCGEN_EVENTSETINFORMATION(...).\n  #elif MCGEN_USE_KERNEL_MODE_APIS             // else if using kernel-mode APIs,\n    #if NTDDI_VERSION >= 0x06040000            //   if target OS is Windows 10 or later,\n      #define MCGEN_HAVE_EVENTSETINFORMATION 1 //     directly invoke MCGEN_EVENTSETINFORMATION(...).\n    #else                                      //   else\n      #define MCGEN_HAVE_EVENTSETINFORMATION 2 //     find \"EtwSetInformation\" via MmGetSystemRoutineAddress.\n    #endif                                     // else (using user-mode APIs)\n  #else                                        //   if target OS and SDK is Windows 8 or later,\n    #if WINVER >= 0x0602 && defined(EVENT_FILTER_TYPE_SCHEMATIZED)\n      #define MCGEN_HAVE_EVENTSETINFORMATION 1 //     directly invoke MCGEN_EVENTSETINFORMATION(...).\n    #else                                      //   else\n      #define MCGEN_HAVE_EVENTSETINFORMATION 2 //     find \"EventSetInformation\" via GetModuleHandleExW/GetProcAddress.\n    #endif\n  #endif\n#endif // MCGEN_HAVE_EVENTSETINFORMATION\n\n//\n// MCGEN Override Macros\n//\n// The following override macros may be defined before including this header\n// to control the APIs used by this header:\n//\n// - MCGEN_EVENTREGISTER\n// - MCGEN_EVENTUNREGISTER\n// - MCGEN_EVENTSETINFORMATION\n// - MCGEN_EVENTWRITETRANSFER\n//\n// If the the macro is undefined, the MC implementation will default to the\n// corresponding ETW APIs. For example, if the MCGEN_EVENTREGISTER macro is\n// undefined, the EventRegister[MyProviderName] macro will use EventRegister\n// in user mode and will use EtwRegister in kernel mode.\n//\n// To prevent issues from conflicting definitions of these macros, the value\n// of the override macro will be used as a suffix in certain internal function\n// names. Because of this, the override macros must follow certain rules:\n//\n// - The macro must be defined before any MC-generated header is included and\n//   must not be undefined or redefined after any MC-generated header is\n//   included. Different translation units (i.e. different .c or .cpp files)\n//   may set the macros to different values, but within a translation unit\n//   (within a single .c or .cpp file), the macro must be set once and not\n//   changed.\n// - The override must be an object-like macro, not a function-like macro\n//   (i.e. the override macro must not have a parameter list).\n// - The override macro's value must be a simple identifier, i.e. must be\n//   something that starts with a letter or '_' and contains only letters,\n//   numbers, and '_' characters.\n// - If the override macro's value is the name of a second object-like macro,\n//   the second object-like macro must follow the same rules. (The override\n//   macro's value can also be the name of a function-like macro, in which\n//   case the function-like macro does not need to follow the same rules.)\n//\n// For example, the following will cause compile errors:\n//\n//   #define MCGEN_EVENTWRITETRANSFER MyNamespace::MyClass::MyFunction // Value has non-identifier characters (colon).\n//   #define MCGEN_EVENTWRITETRANSFER GetEventWriteFunctionPointer(7)  // Value has non-identifier characters (parentheses).\n//   #define MCGEN_EVENTWRITETRANSFER(h,e,a,r,c,d) EventWrite(h,e,c,d) // Override is defined as a function-like macro.\n//   #define MY_OBJECT_LIKE_MACRO     MyNamespace::MyClass::MyEventWriteFunction\n//   #define MCGEN_EVENTWRITETRANSFER MY_OBJECT_LIKE_MACRO // Evaluates to something with non-identifier characters (colon).\n//\n// The following would be ok:\n//\n//   #define MCGEN_EVENTWRITETRANSFER  MyEventWriteFunction1  // OK, suffix will be \"MyEventWriteFunction1\".\n//   #define MY_OBJECT_LIKE_MACRO      MyEventWriteFunction2\n//   #define MCGEN_EVENTWRITETRANSFER  MY_OBJECT_LIKE_MACRO   // OK, suffix will be \"MyEventWriteFunction2\".\n//   #define MY_FUNCTION_LIKE_MACRO(h,e,a,r,c,d) MyNamespace::MyClass::MyEventWriteFunction3(h,e,c,d)\n//   #define MCGEN_EVENTWRITETRANSFER  MY_FUNCTION_LIKE_MACRO // OK, suffix will be \"MY_FUNCTION_LIKE_MACRO\".\n//\n#ifndef MCGEN_EVENTREGISTER\n  #if MCGEN_USE_KERNEL_MODE_APIS\n    #define MCGEN_EVENTREGISTER        EtwRegister\n  #else\n    #define MCGEN_EVENTREGISTER        EventRegister\n  #endif\n#endif // MCGEN_EVENTREGISTER\n#ifndef MCGEN_EVENTUNREGISTER\n  #if MCGEN_USE_KERNEL_MODE_APIS\n    #define MCGEN_EVENTUNREGISTER      EtwUnregister\n  #else\n    #define MCGEN_EVENTUNREGISTER      EventUnregister\n  #endif\n#endif // MCGEN_EVENTUNREGISTER\n#ifndef MCGEN_EVENTSETINFORMATION\n  #if MCGEN_USE_KERNEL_MODE_APIS\n    #define MCGEN_EVENTSETINFORMATION  EtwSetInformation\n  #else\n    #define MCGEN_EVENTSETINFORMATION  EventSetInformation\n  #endif\n#endif // MCGEN_EVENTSETINFORMATION\n#ifndef MCGEN_EVENTWRITETRANSFER\n  #if MCGEN_USE_KERNEL_MODE_APIS\n    #define MCGEN_EVENTWRITETRANSFER   EtwWriteTransfer\n  #else\n    #define MCGEN_EVENTWRITETRANSFER   EventWriteTransfer\n  #endif\n#endif // MCGEN_EVENTWRITETRANSFER\n\n//\n// MCGEN_EVENT_ENABLED macro:\n// Override to control how the EventWrite[EventName] macros determine whether\n// an event is enabled. The default behavior is for EventWrite[EventName] to\n// use the EventEnabled[EventName] macros.\n//\n#ifndef MCGEN_EVENT_ENABLED\n#define MCGEN_EVENT_ENABLED(EventName) EventEnabled##EventName()\n#endif\n\n//\n// MCGEN_EVENT_ENABLED_FORCONTEXT macro:\n// Override to control how the EventWrite[EventName]_ForContext macros\n// determine whether an event is enabled. The default behavior is for\n// EventWrite[EventName]_ForContext to use the\n// EventEnabled[EventName]_ForContext macros.\n//\n#ifndef MCGEN_EVENT_ENABLED_FORCONTEXT\n#define MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, EventName) EventEnabled##EventName##_ForContext(pContext)\n#endif\n\n//\n// MCGEN_ENABLE_CHECK macro:\n// Determines whether the specified event would be considered as enabled\n// based on the state of the specified context. Slightly faster than calling\n// McGenEventEnabled directly.\n//\n#ifndef MCGEN_ENABLE_CHECK\n#define MCGEN_ENABLE_CHECK(Context, Descriptor) (Context.IsEnabled && McGenEventEnabled(&Context, &Descriptor))\n#endif\n\n#if !defined(MCGEN_TRACE_CONTEXT_DEF)\n#define MCGEN_TRACE_CONTEXT_DEF\n// This structure is for use by MC-generated code and should not be used directly.\ntypedef struct _MCGEN_TRACE_CONTEXT\n{\n    TRACEHANDLE            RegistrationHandle;\n    TRACEHANDLE            Logger;      // Used as pointer to provider traits.\n    ULONGLONG              MatchAnyKeyword;\n    ULONGLONG              MatchAllKeyword;\n    ULONG                  Flags;\n    ULONG                  IsEnabled;\n    UCHAR                  Level;\n    UCHAR                  Reserve;\n    USHORT                 EnableBitsCount;\n    PULONG                 EnableBitMask;\n    const ULONGLONG*       EnableKeyWords;\n    const UCHAR*           EnableLevel;\n} MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT;\n#endif // MCGEN_TRACE_CONTEXT_DEF\n\n#if !defined(MCGEN_LEVEL_KEYWORD_ENABLED_DEF)\n#define MCGEN_LEVEL_KEYWORD_ENABLED_DEF\n//\n// Determines whether an event with a given Level and Keyword would be\n// considered as enabled based on the state of the specified context.\n// Note that you may want to use MCGEN_ENABLE_CHECK instead of calling this\n// function directly.\n//\nFORCEINLINE\nBOOLEAN\nMcGenLevelKeywordEnabled(\n    _In_ PMCGEN_TRACE_CONTEXT EnableInfo,\n    _In_ UCHAR Level,\n    _In_ ULONGLONG Keyword\n    )\n{\n    //\n    // Check if the event Level is lower than the level at which\n    // the channel is enabled.\n    // If the event Level is 0 or the channel is enabled at level 0,\n    // all levels are enabled.\n    //\n\n    if ((Level <= EnableInfo->Level) || // This also covers the case of Level == 0.\n        (EnableInfo->Level == 0)) {\n\n        //\n        // Check if Keyword is enabled\n        //\n\n        if ((Keyword == (ULONGLONG)0) ||\n            ((Keyword & EnableInfo->MatchAnyKeyword) &&\n             ((Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) {\n            return TRUE;\n        }\n    }\n\n    return FALSE;\n}\n#endif // MCGEN_LEVEL_KEYWORD_ENABLED_DEF\n\n#if !defined(MCGEN_EVENT_ENABLED_DEF)\n#define MCGEN_EVENT_ENABLED_DEF\n//\n// Determines whether the specified event would be considered as enabled based\n// on the state of the specified context. Note that you may want to use\n// MCGEN_ENABLE_CHECK instead of calling this function directly.\n//\nFORCEINLINE\nBOOLEAN\nMcGenEventEnabled(\n    _In_ PMCGEN_TRACE_CONTEXT EnableInfo,\n    _In_ PCEVENT_DESCRIPTOR EventDescriptor\n    )\n{\n    return McGenLevelKeywordEnabled(EnableInfo, EventDescriptor->Level, EventDescriptor->Keyword);\n}\n#endif // MCGEN_EVENT_ENABLED_DEF\n\n#if !defined(MCGEN_CONTROL_CALLBACK)\n#define MCGEN_CONTROL_CALLBACK\n\n// This function is for use by MC-generated code and should not be used directly.\nDECLSPEC_NOINLINE __inline\nVOID\n__stdcall\nMcGenControlCallbackV2(\n    _In_ LPCGUID SourceId,\n    _In_ ULONG ControlCode,\n    _In_ UCHAR Level,\n    _In_ ULONGLONG MatchAnyKeyword,\n    _In_ ULONGLONG MatchAllKeyword,\n    _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,\n    _Inout_opt_ PVOID CallbackContext\n    )\n/*++\n\nRoutine Description:\n\n    This is the notification callback for Windows Vista and later.\n\nArguments:\n\n    SourceId - The GUID that identifies the session that enabled the provider.\n\n    ControlCode - The parameter indicates whether the provider\n                  is being enabled or disabled.\n\n    Level - The level at which the event is enabled.\n\n    MatchAnyKeyword - The bitmask of keywords that the provider uses to\n                      determine the category of events that it writes.\n\n    MatchAllKeyword - This bitmask additionally restricts the category\n                      of events that the provider writes.\n\n    FilterData - The provider-defined data.\n\n    CallbackContext - The context of the callback that is defined when the provider\n                      called EtwRegister to register itself.\n\nRemarks:\n\n    ETW calls this function to notify provider of enable/disable\n\n--*/\n{\n    PMCGEN_TRACE_CONTEXT Ctx = (PMCGEN_TRACE_CONTEXT)CallbackContext;\n    ULONG Ix;\n#ifndef MCGEN_PRIVATE_ENABLE_CALLBACK_V2\n    UNREFERENCED_PARAMETER(SourceId);\n    UNREFERENCED_PARAMETER(FilterData);\n#endif\n\n    if (Ctx == NULL) {\n        return;\n    }\n\n    switch (ControlCode) {\n\n        case EVENT_CONTROL_CODE_ENABLE_PROVIDER:\n            Ctx->Level = Level;\n            Ctx->MatchAnyKeyword = MatchAnyKeyword;\n            Ctx->MatchAllKeyword = MatchAllKeyword;\n            Ctx->IsEnabled = EVENT_CONTROL_CODE_ENABLE_PROVIDER;\n\n            for (Ix = 0; Ix < Ctx->EnableBitsCount; Ix += 1) {\n                if (McGenLevelKeywordEnabled(Ctx, Ctx->EnableLevel[Ix], Ctx->EnableKeyWords[Ix]) != FALSE) {\n                    Ctx->EnableBitMask[Ix >> 5] |= (1 << (Ix % 32));\n                } else {\n                    Ctx->EnableBitMask[Ix >> 5] &= ~(1 << (Ix % 32));\n                }\n            }\n            break;\n\n        case EVENT_CONTROL_CODE_DISABLE_PROVIDER:\n            Ctx->IsEnabled = EVENT_CONTROL_CODE_DISABLE_PROVIDER;\n            Ctx->Level = 0;\n            Ctx->MatchAnyKeyword = 0;\n            Ctx->MatchAllKeyword = 0;\n            if (Ctx->EnableBitsCount > 0) {\n#pragma warning(suppress: 26451) // Arithmetic overflow cannot occur, no matter the value of EnableBitCount\n                RtlZeroMemory(Ctx->EnableBitMask, (((Ctx->EnableBitsCount - 1) / 32) + 1) * sizeof(ULONG));\n            }\n            break;\n\n        default:\n            break;\n    }\n\n#ifdef MCGEN_PRIVATE_ENABLE_CALLBACK_V2\n    //\n    // Call user defined callback\n    //\n    MCGEN_PRIVATE_ENABLE_CALLBACK_V2(\n        SourceId,\n        ControlCode,\n        Level,\n        MatchAnyKeyword,\n        MatchAllKeyword,\n        FilterData,\n        CallbackContext\n        );\n#endif // MCGEN_PRIVATE_ENABLE_CALLBACK_V2\n\n    return;\n}\n\n#endif // MCGEN_CONTROL_CALLBACK\n\n#ifndef _mcgen_PENABLECALLBACK\n  #if MCGEN_USE_KERNEL_MODE_APIS\n    #define _mcgen_PENABLECALLBACK      PETWENABLECALLBACK\n  #else\n    #define _mcgen_PENABLECALLBACK      PENABLECALLBACK\n  #endif\n#endif // _mcgen_PENABLECALLBACK\n\n#if !defined(_mcgen_PASTE2)\n// This macro is for use by MC-generated code and should not be used directly.\n#define _mcgen_PASTE2(a, b) _mcgen_PASTE2_imp(a, b)\n#define _mcgen_PASTE2_imp(a, b) a##b\n#endif // _mcgen_PASTE2\n\n#if !defined(_mcgen_PASTE3)\n// This macro is for use by MC-generated code and should not be used directly.\n#define _mcgen_PASTE3(a, b, c) _mcgen_PASTE3_imp(a, b, c)\n#define _mcgen_PASTE3_imp(a, b, c) a##b##_##c\n#endif // _mcgen_PASTE3\n\n//\n// Macro validation\n//\n\n// Validate MCGEN_EVENTREGISTER:\n\n// Trigger an error if MCGEN_EVENTREGISTER is not an unqualified (simple) identifier:\nstruct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER);\n\n// Trigger an error if MCGEN_EVENTREGISTER is redefined:\ntypedef struct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER)\n    MCGEN_EVENTREGISTER_must_not_be_redefined_between_headers;\n\n// Trigger an error if MCGEN_EVENTREGISTER is defined as a function-like macro:\ntypedef void MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTREGISTER;\ntypedef int _mcgen_PASTE2(MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTREGISTER);\n\n// Validate MCGEN_EVENTUNREGISTER:\n\n// Trigger an error if MCGEN_EVENTUNREGISTER is not an unqualified (simple) identifier:\nstruct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER);\n\n// Trigger an error if MCGEN_EVENTUNREGISTER is redefined:\ntypedef struct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER)\n    MCGEN_EVENTUNREGISTER_must_not_be_redefined_between_headers;\n\n// Trigger an error if MCGEN_EVENTUNREGISTER is defined as a function-like macro:\ntypedef void MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTUNREGISTER;\ntypedef int _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTUNREGISTER);\n\n// Validate MCGEN_EVENTSETINFORMATION:\n\n// Trigger an error if MCGEN_EVENTSETINFORMATION is not an unqualified (simple) identifier:\nstruct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION);\n\n// Trigger an error if MCGEN_EVENTSETINFORMATION is redefined:\ntypedef struct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION)\n    MCGEN_EVENTSETINFORMATION_must_not_be_redefined_between_headers;\n\n// Trigger an error if MCGEN_EVENTSETINFORMATION is defined as a function-like macro:\ntypedef void MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_MCGEN_EVENTSETINFORMATION;\ntypedef int _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_, MCGEN_EVENTSETINFORMATION);\n\n// Validate MCGEN_EVENTWRITETRANSFER:\n\n// Trigger an error if MCGEN_EVENTWRITETRANSFER is not an unqualified (simple) identifier:\nstruct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER);\n\n// Trigger an error if MCGEN_EVENTWRITETRANSFER is redefined:\ntypedef struct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER)\n    MCGEN_EVENTWRITETRANSFER_must_not_be_redefined_between_headers;;\n\n// Trigger an error if MCGEN_EVENTWRITETRANSFER is defined as a function-like macro:\ntypedef void MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_MCGEN_EVENTWRITETRANSFER;\ntypedef int _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_, MCGEN_EVENTWRITETRANSFER);\n\n#ifndef McGenEventWrite_def\n#define McGenEventWrite_def\n\n// This macro is for use by MC-generated code and should not be used directly.\n#define McGenEventWrite _mcgen_PASTE2(McGenEventWrite_, MCGEN_EVENTWRITETRANSFER)\n\n// This function is for use by MC-generated code and should not be used directly.\nDECLSPEC_NOINLINE __inline\nULONG __stdcall\nMcGenEventWrite(\n    _In_ PMCGEN_TRACE_CONTEXT Context,\n    _In_ PCEVENT_DESCRIPTOR Descriptor,\n    _In_opt_ LPCGUID ActivityId,\n    _In_range_(1, 128) ULONG EventDataCount,\n    _Pre_cap_(EventDataCount) EVENT_DATA_DESCRIPTOR* EventData\n    )\n{\n    const USHORT UNALIGNED* Traits;\n\n    // Some customized MCGEN_EVENTWRITETRANSFER macros might ignore ActivityId.\n    UNREFERENCED_PARAMETER(ActivityId);\n\n    Traits = (const USHORT UNALIGNED*)(UINT_PTR)Context->Logger;\n\n    if (Traits == NULL) {\n        EventData[0].Ptr = 0;\n        EventData[0].Size = 0;\n        EventData[0].Reserved = 0;\n    } else {\n        EventData[0].Ptr = (ULONG_PTR)Traits;\n        EventData[0].Size = *Traits;\n        EventData[0].Reserved = 2; // EVENT_DATA_DESCRIPTOR_TYPE_PROVIDER_METADATA\n    }\n\n    return MCGEN_EVENTWRITETRANSFER(\n        Context->RegistrationHandle,\n        Descriptor,\n        ActivityId,\n        NULL,\n        EventDataCount,\n        EventData);\n}\n#endif // McGenEventWrite_def\n\n#if !defined(McGenEventRegisterUnregister)\n#define McGenEventRegisterUnregister\n\n// This macro is for use by MC-generated code and should not be used directly.\n#define McGenEventRegister _mcgen_PASTE2(McGenEventRegister_, MCGEN_EVENTREGISTER)\n\n#pragma warning(push)\n#pragma warning(disable:6103)\n// This function is for use by MC-generated code and should not be used directly.\nDECLSPEC_NOINLINE __inline\nULONG __stdcall\nMcGenEventRegister(\n    _In_ LPCGUID ProviderId,\n    _In_opt_ _mcgen_PENABLECALLBACK EnableCallback,\n    _In_opt_ PVOID CallbackContext,\n    _Inout_ PREGHANDLE RegHandle\n    )\n/*++\n\nRoutine Description:\n\n    This function registers the provider with ETW.\n\nArguments:\n\n    ProviderId - Provider ID to register with ETW.\n\n    EnableCallback - Callback to be used.\n\n    CallbackContext - Context for the callback.\n\n    RegHandle - Pointer to registration handle.\n\nRemarks:\n\n    Should not be called if the provider is already registered (i.e. should not\n    be called if *RegHandle != 0). Repeatedly registering a provider is a bug\n    and may indicate a race condition. However, for compatibility with previous\n    behavior, this function will return SUCCESS in this case.\n\n--*/\n{\n    ULONG Error;\n\n    if (*RegHandle != 0)\n    {\n        Error = 0; // ERROR_SUCCESS\n    }\n    else\n    {\n        Error = MCGEN_EVENTREGISTER(ProviderId, EnableCallback, CallbackContext, RegHandle);\n    }\n\n    return Error;\n}\n#pragma warning(pop)\n\n// This macro is for use by MC-generated code and should not be used directly.\n#define McGenEventUnregister _mcgen_PASTE2(McGenEventUnregister_, MCGEN_EVENTUNREGISTER)\n\n// This function is for use by MC-generated code and should not be used directly.\nDECLSPEC_NOINLINE __inline\nULONG __stdcall\nMcGenEventUnregister(_Inout_ PREGHANDLE RegHandle)\n/*++\n\nRoutine Description:\n\n    Unregister from ETW and set *RegHandle = 0.\n\nArguments:\n\n    RegHandle - the pointer to the provider registration handle\n\nRemarks:\n\n    If provider has not been registered (i.e. if *RegHandle == 0),\n    return SUCCESS. It is safe to call McGenEventUnregister even if the\n    call to McGenEventRegister returned an error.\n\n--*/\n{\n    ULONG Error;\n\n    if(*RegHandle == 0)\n    {\n        Error = 0; // ERROR_SUCCESS\n    }\n    else\n    {\n        Error = MCGEN_EVENTUNREGISTER(*RegHandle);\n        *RegHandle = (REGHANDLE)0;\n    }\n\n    return Error;\n}\n\n#endif // McGenEventRegisterUnregister\n\n#ifndef _mcgen_EVENT_BIT_SET\n  #if defined(_M_IX86) || defined(_M_X64)\n    // This macro is for use by MC-generated code and should not be used directly.\n    #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((((const unsigned char*)EnableBits)[BitPosition >> 3] & (1u << (BitPosition & 7))) != 0)\n  #else // CPU type\n    // This macro is for use by MC-generated code and should not be used directly.\n    #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((EnableBits[BitPosition >> 5] & (1u << (BitPosition & 31))) != 0)\n  #endif // CPU type\n#endif // _mcgen_EVENT_BIT_SET\n\n#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n// Provider \"microsoft-windows-mimalloc\" event count 2\n//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n// Provider GUID = 138f4dbb-ee04-4899-aa0a-572ad4475779\nEXTERN_C __declspec(selectany) const GUID ETW_MI_Provider = {0x138f4dbb, 0xee04, 0x4899, {0xaa, 0x0a, 0x57, 0x2a, 0xd4, 0x47, 0x57, 0x79}};\n\n#ifndef ETW_MI_Provider_Traits\n#define ETW_MI_Provider_Traits NULL\n#endif // ETW_MI_Provider_Traits\n\n//\n// Event Descriptors\n//\nEXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ETW_MI_ALLOC = {0x64, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0};\n#define ETW_MI_ALLOC_value 0x64\nEXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ETW_MI_FREE = {0x65, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0};\n#define ETW_MI_FREE_value 0x65\n\n//\n// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:\n// Define this macro to have the compiler skip the generated functions in this\n// header.\n//\n#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n//\n// Event Enablement Bits\n// These variables are for use by MC-generated code and should not be used directly.\n//\nEXTERN_C __declspec(selectany) DECLSPEC_CACHEALIGN ULONG microsoft_windows_mimallocEnableBits[1];\nEXTERN_C __declspec(selectany) const ULONGLONG microsoft_windows_mimallocKeywords[1] = {0x0};\nEXTERN_C __declspec(selectany) const unsigned char microsoft_windows_mimallocLevels[1] = {4};\n\n//\n// Provider context\n//\nEXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT ETW_MI_Provider_Context = {0, (ULONG_PTR)ETW_MI_Provider_Traits, 0, 0, 0, 0, 0, 0, 1, microsoft_windows_mimallocEnableBits, microsoft_windows_mimallocKeywords, microsoft_windows_mimallocLevels};\n\n//\n// Provider REGHANDLE\n//\n#define microsoft_windows_mimallocHandle (ETW_MI_Provider_Context.RegistrationHandle)\n\n//\n// This macro is set to 0, indicating that the EventWrite[Name] macros do not\n// have an Activity parameter. This is controlled by the -km and -um options.\n//\n#define ETW_MI_Provider_EventWriteActivity 0\n\n//\n// Register with ETW using the control GUID specified in the manifest.\n// Invoke this macro during module initialization (i.e. program startup,\n// DLL process attach, or driver load) to initialize the provider.\n// Note that if this function returns an error, the error means that\n// will not work, but no action needs to be taken -- even if EventRegister\n// returns an error, it is generally safe to use EventWrite and\n// EventUnregister macros (they will be no-ops if EventRegister failed).\n//\n#ifndef EventRegistermicrosoft_windows_mimalloc\n#define EventRegistermicrosoft_windows_mimalloc() McGenEventRegister(&ETW_MI_Provider, McGenControlCallbackV2, &ETW_MI_Provider_Context, &microsoft_windows_mimallocHandle)\n#endif\n\n//\n// Register with ETW using a specific control GUID (i.e. a GUID other than what\n// is specified in the manifest). Advanced scenarios only.\n//\n#ifndef EventRegisterByGuidmicrosoft_windows_mimalloc\n#define EventRegisterByGuidmicrosoft_windows_mimalloc(Guid) McGenEventRegister(&(Guid), McGenControlCallbackV2, &ETW_MI_Provider_Context, &microsoft_windows_mimallocHandle)\n#endif\n\n//\n// Unregister with ETW and close the provider.\n// Invoke this macro during module shutdown (i.e. program exit, DLL process\n// detach, or driver unload) to unregister the provider.\n// Note that you MUST call EventUnregister before DLL or driver unload\n// (not optional): failure to unregister a provider before DLL or driver unload\n// will result in crashes.\n//\n#ifndef EventUnregistermicrosoft_windows_mimalloc\n#define EventUnregistermicrosoft_windows_mimalloc() McGenEventUnregister(&microsoft_windows_mimallocHandle)\n#endif\n\n//\n// MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION macro:\n// Define this macro to enable support for caller-allocated provider context.\n//\n#ifdef MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION\n\n//\n// Advanced scenarios: Caller-allocated provider context.\n// Use when multiple differently-configured provider handles are needed,\n// e.g. for container-aware drivers, one context per container.\n//\n// Usage:\n//\n// - Caller enables the feature before including this header, e.g.\n//   #define MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION 1\n// - Caller allocates memory, e.g. pContext = malloc(sizeof(McGenContext_microsoft_windows_mimalloc));\n// - Caller registers the provider, e.g. EventRegistermicrosoft_windows_mimalloc_ForContext(pContext);\n// - Caller writes events, e.g. EventWriteMyEvent_ForContext(pContext, ...);\n// - Caller unregisters, e.g. EventUnregistermicrosoft_windows_mimalloc_ForContext(pContext);\n// - Caller frees memory, e.g. free(pContext);\n//\n\ntypedef struct tagMcGenContext_microsoft_windows_mimalloc {\n    // The fields of this structure are subject to change and should\n    // not be accessed directly. To access the provider's REGHANDLE,\n    // use microsoft_windows_mimallocHandle_ForContext(pContext).\n    MCGEN_TRACE_CONTEXT Context;\n    ULONG EnableBits[1];\n} McGenContext_microsoft_windows_mimalloc;\n\n#define EventRegistermicrosoft_windows_mimalloc_ForContext(pContext)             _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(&ETW_MI_Provider, pContext)\n#define EventRegisterByGuidmicrosoft_windows_mimalloc_ForContext(Guid, pContext) _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(&(Guid), pContext)\n#define EventUnregistermicrosoft_windows_mimalloc_ForContext(pContext)           McGenEventUnregister(&(pContext)->Context.RegistrationHandle)\n\n//\n// Provider REGHANDLE for caller-allocated context.\n//\n#define microsoft_windows_mimallocHandle_ForContext(pContext) ((pContext)->Context.RegistrationHandle)\n\n// This function is for use by MC-generated code and should not be used directly.\n// Initialize and register the caller-allocated context.\n__inline\nULONG __stdcall\n_mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(\n    _In_ LPCGUID pProviderId,\n    _Out_ McGenContext_microsoft_windows_mimalloc* pContext)\n{\n    RtlZeroMemory(pContext, sizeof(*pContext));\n    pContext->Context.Logger = (ULONG_PTR)ETW_MI_Provider_Traits;\n    pContext->Context.EnableBitsCount = 1;\n    pContext->Context.EnableBitMask = pContext->EnableBits;\n    pContext->Context.EnableKeyWords = microsoft_windows_mimallocKeywords;\n    pContext->Context.EnableLevel = microsoft_windows_mimallocLevels;\n    return McGenEventRegister(\n        pProviderId,\n        McGenControlCallbackV2,\n        &pContext->Context,\n        &pContext->Context.RegistrationHandle);\n}\n\n// This function is for use by MC-generated code and should not be used directly.\n// Trigger a compile error if called with the wrong parameter type.\nFORCEINLINE\n_Ret_ McGenContext_microsoft_windows_mimalloc*\n_mcgen_CheckContextType_microsoft_windows_mimalloc(_In_ McGenContext_microsoft_windows_mimalloc* pContext)\n{\n    return pContext;\n}\n\n#endif // MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION\n\n//\n// Enablement check macro for event \"ETW_MI_ALLOC\"\n//\n#define EventEnabledETW_MI_ALLOC() _mcgen_EVENT_BIT_SET(microsoft_windows_mimallocEnableBits, 0)\n#define EventEnabledETW_MI_ALLOC_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->EnableBits, 0)\n\n//\n// Event write macros for event \"ETW_MI_ALLOC\"\n//\n#define EventWriteETW_MI_ALLOC(Address, Size) \\\n        MCGEN_EVENT_ENABLED(ETW_MI_ALLOC) \\\n        ? _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&ETW_MI_Provider_Context, &ETW_MI_ALLOC, Address, Size) : 0\n#define EventWriteETW_MI_ALLOC_AssumeEnabled(Address, Size) \\\n        _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&ETW_MI_Provider_Context, &ETW_MI_ALLOC, Address, Size)\n#define EventWriteETW_MI_ALLOC_ForContext(pContext, Address, Size) \\\n        MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ETW_MI_ALLOC) \\\n        ? _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&(pContext)->Context, &ETW_MI_ALLOC, Address, Size) : 0\n#define EventWriteETW_MI_ALLOC_ForContextAssumeEnabled(pContext, Address, Size) \\\n        _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->Context, &ETW_MI_ALLOC, Address, Size)\n\n// This macro is for use by MC-generated code and should not be used directly.\n#define _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)\n\n//\n// Enablement check macro for event \"ETW_MI_FREE\"\n//\n#define EventEnabledETW_MI_FREE() _mcgen_EVENT_BIT_SET(microsoft_windows_mimallocEnableBits, 0)\n#define EventEnabledETW_MI_FREE_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->EnableBits, 0)\n\n//\n// Event write macros for event \"ETW_MI_FREE\"\n//\n#define EventWriteETW_MI_FREE(Address, Size) \\\n        MCGEN_EVENT_ENABLED(ETW_MI_FREE) \\\n        ? _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&ETW_MI_Provider_Context, &ETW_MI_FREE, Address, Size) : 0\n#define EventWriteETW_MI_FREE_AssumeEnabled(Address, Size) \\\n        _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&ETW_MI_Provider_Context, &ETW_MI_FREE, Address, Size)\n#define EventWriteETW_MI_FREE_ForContext(pContext, Address, Size) \\\n        MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ETW_MI_FREE) \\\n        ? _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&(pContext)->Context, &ETW_MI_FREE, Address, Size) : 0\n#define EventWriteETW_MI_FREE_ForContextAssumeEnabled(pContext, Address, Size) \\\n        _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->Context, &ETW_MI_FREE, Address, Size)\n\n// This macro is for use by MC-generated code and should not be used directly.\n#define _mcgen_TEMPLATE_FOR_ETW_MI_FREE _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)\n\n#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n//\n// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:\n// Define this macro to have the compiler skip the generated functions in this\n// header.\n//\n#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n//\n// Template Functions\n//\n\n//\n// Function for template \"ETW_CUSTOM_HEAP_ALLOC_DATA\" (and possibly others).\n// This function is for use by MC-generated code and should not be used directly.\n//\n#ifndef McTemplateU0xx_def\n#define McTemplateU0xx_def\nETW_INLINE\nULONG\n_mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)(\n    _In_ PMCGEN_TRACE_CONTEXT Context,\n    _In_ PCEVENT_DESCRIPTOR Descriptor,\n    _In_ const unsigned __int64  _Arg0,\n    _In_ const unsigned __int64  _Arg1\n    )\n{\n#define McTemplateU0xx_ARGCOUNT 2\n\n    EVENT_DATA_DESCRIPTOR EventData[McTemplateU0xx_ARGCOUNT + 1];\n\n    EventDataDescCreate(&EventData[1],&_Arg0, sizeof(const unsigned __int64)  );\n\n    EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned __int64)  );\n\n    return McGenEventWrite(Context, Descriptor, NULL, McTemplateU0xx_ARGCOUNT + 1, EventData);\n}\n#endif // McTemplateU0xx_def\n\n#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n#if defined(__cplusplus)\n}\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/prim/windows/prim.c",
      "sha256": "6de43c6aeb5238017885fa57f96ed0bbc71098503ce8ab5667c73dac1a63454e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// This file is included in `src/prim/prim.c`\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"\n#include <stdio.h>   // fputs, stderr\n#include <stdlib.h>  // atexit\n\n// xbox has no console IO\n#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)\n#define MI_HAS_CONSOLE_IO\n#endif\n\n//---------------------------------------------\n// Dynamically bind Windows API points for portability\n//---------------------------------------------\n\n// We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016.\n// So, we need to look it up dynamically to run on older systems. (use __stdcall for 32-bit compatibility)\n// NtAllocateVirtualAllocEx is used for huge OS page allocation (1GiB)\n// We define a minimal MEM_EXTENDED_PARAMETER ourselves in order to be able to compile with older SDK's.\ntypedef enum MI_MEM_EXTENDED_PARAMETER_TYPE_E {\n  MiMemExtendedParameterInvalidType = 0,\n  MiMemExtendedParameterAddressRequirements,\n  MiMemExtendedParameterNumaNode,\n  MiMemExtendedParameterPartitionHandle,\n  MiMemExtendedParameterUserPhysicalHandle,\n  MiMemExtendedParameterAttributeFlags,\n  MiMemExtendedParameterMax\n} MI_MEM_EXTENDED_PARAMETER_TYPE;\n\ntypedef struct DECLSPEC_ALIGN(8) MI_MEM_EXTENDED_PARAMETER_S {\n  struct { DWORD64 Type : 8; DWORD64 Reserved : 56; } Type;\n  union  { DWORD64 ULong64; PVOID Pointer; SIZE_T Size; HANDLE Handle; DWORD ULong; } Arg;\n} MI_MEM_EXTENDED_PARAMETER;\n\ntypedef struct MI_MEM_ADDRESS_REQUIREMENTS_S {\n  PVOID  LowestStartingAddress;\n  PVOID  HighestEndingAddress;\n  SIZE_T Alignment;\n} MI_MEM_ADDRESS_REQUIREMENTS;\n\n#define MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE   0x00000010\n\n#include <winternl.h>\ntypedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG);\ntypedef LONG  (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG);  // avoid NTSTATUS as it is not defined on xbox (pr #1084)\nstatic PVirtualAlloc2 pVirtualAlloc2 = NULL;\nstatic PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL;\n\n// Similarly, GetNumaProcessorNodeEx is only supported since Windows 7  (and GetNumaNodeProcessorMask is not supported on xbox)\ntypedef struct MI_PROCESSOR_NUMBER_S { WORD Group; BYTE Number; BYTE Reserved; } MI_PROCESSOR_NUMBER;\n\ntypedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(MI_PROCESSOR_NUMBER* ProcNumber);\ntypedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(MI_PROCESSOR_NUMBER* Processor, PUSHORT NodeNumber);\ntypedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask);\ntypedef BOOL (__stdcall *PGetNumaProcessorNode)(UCHAR Processor, PUCHAR NodeNumber);\ntypedef BOOL (__stdcall* PGetNumaNodeProcessorMask)(UCHAR Node, PULONGLONG ProcessorMask);\ntypedef BOOL (__stdcall* PGetNumaHighestNodeNumber)(PULONG Node);\nstatic PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL;\nstatic PGetNumaProcessorNodeEx      pGetNumaProcessorNodeEx = NULL;\nstatic PGetNumaNodeProcessorMaskEx  pGetNumaNodeProcessorMaskEx = NULL;\nstatic PGetNumaProcessorNode        pGetNumaProcessorNode = NULL;\nstatic PGetNumaNodeProcessorMask    pGetNumaNodeProcessorMask = NULL;\nstatic PGetNumaHighestNodeNumber    pGetNumaHighestNodeNumber = NULL;\n\n// Not available on xbox\ntypedef SIZE_T(__stdcall* PGetLargePageMinimum)(VOID);\nstatic PGetLargePageMinimum pGetLargePageMinimum = NULL;\n\n// Available after Windows XP\ntypedef BOOL (__stdcall *PGetPhysicallyInstalledSystemMemory)( PULONGLONG TotalMemoryInKilobytes );\n\n\n//---------------------------------------------\n// Enable large page support dynamically (if possible)\n//---------------------------------------------\n\nstatic bool win_enable_large_os_pages_once(size_t* large_page_size)\n{\n  if (pGetLargePageMinimum==NULL) return false;  // no large page support (xbox etc.)\n\n  // Try to see if large OS pages are supported\n  // To use large pages on Windows, we first need access permission\n  // Set \"Lock pages in memory\" permission in the group policy editor\n  // <https://devblogs.microsoft.com/oldnewthing/20110128-00/?p=11643>\n  unsigned long err = 0;\n  HANDLE token = NULL;\n  BOOL ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);\n  if (ok) {\n    TOKEN_PRIVILEGES tp;\n    ok = LookupPrivilegeValue(NULL, TEXT(\"SeLockMemoryPrivilege\"), &tp.Privileges[0].Luid);\n    if (ok) {\n      tp.PrivilegeCount = 1;\n      tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\n      ok = AdjustTokenPrivileges(token, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);\n      if (ok) {\n        err = GetLastError();\n        ok = (err == ERROR_SUCCESS);\n        if (ok && large_page_size != NULL && pGetLargePageMinimum != NULL) {\n          *large_page_size = (*pGetLargePageMinimum)();\n        }\n      }\n    }\n    CloseHandle(token);\n  }\n  if (!ok) {\n    if (err == 0) err = GetLastError();\n    _mi_warning_message(\"cannot enable large OS page support, error %lu\\n\", err);\n  }\n  return (ok!=0);\n}\n\nstatic bool win_enable_large_os_pages(size_t* large_page_size) {\n  mi_atomic_do_once {\n    win_enable_large_os_pages_once(large_page_size);\n  }\n  return (_mi_os_large_page_size() > 0);\n}\n\n\n//---------------------------------------------\n// Initialize\n//---------------------------------------------\n\nvoid _mi_prim_mem_init( mi_os_mem_config_t* config )\n{\n  config->has_overcommit = false;\n  config->has_partial_free = false;\n  config->has_virtual_reserve = true;\n  // get the page size\n  SYSTEM_INFO si;\n  GetSystemInfo(&si);\n  if (si.dwPageSize > 0) { config->page_size = si.dwPageSize; }\n  if (si.dwAllocationGranularity > 0) { config->alloc_granularity = si.dwAllocationGranularity; }\n  // get virtual address bits\n  if ((uintptr_t)si.lpMaximumApplicationAddress > 0) {\n    const size_t vbits = MI_SIZE_BITS - mi_clz((uintptr_t)si.lpMaximumApplicationAddress);\n    config->virtual_address_bits = vbits;\n  }\n\n  // get the VirtualAlloc2 function\n  HINSTANCE  hDll;\n  hDll = LoadLibrary(TEXT(\"kernelbase.dll\"));\n  if (hDll != NULL) {\n    // use VirtualAlloc2FromApp if possible as it is available to Windows store apps\n    pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, \"VirtualAlloc2FromApp\");\n    if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, \"VirtualAlloc2\");\n    FreeLibrary(hDll);\n  }\n  // NtAllocateVirtualMemoryEx is used for huge page allocation\n  hDll = LoadLibrary(TEXT(\"ntdll.dll\"));\n  if (hDll != NULL) {\n    pNtAllocateVirtualMemoryEx = (PNtAllocateVirtualMemoryEx)(void (*)(void))GetProcAddress(hDll, \"NtAllocateVirtualMemoryEx\");\n    FreeLibrary(hDll);\n  }\n  // Try to use Win7+ numa API\n  hDll = LoadLibrary(TEXT(\"kernel32.dll\"));\n  if (hDll != NULL) {\n    pGetCurrentProcessorNumberEx = (PGetCurrentProcessorNumberEx)(void (*)(void))GetProcAddress(hDll, \"GetCurrentProcessorNumberEx\");\n    pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, \"GetNumaProcessorNodeEx\");\n    pGetNumaNodeProcessorMaskEx = (PGetNumaNodeProcessorMaskEx)(void (*)(void))GetProcAddress(hDll, \"GetNumaNodeProcessorMaskEx\");\n    pGetNumaProcessorNode = (PGetNumaProcessorNode)(void (*)(void))GetProcAddress(hDll, \"GetNumaProcessorNode\");\n    pGetNumaNodeProcessorMask = (PGetNumaNodeProcessorMask)(void (*)(void))GetProcAddress(hDll, \"GetNumaNodeProcessorMask\");\n    pGetNumaHighestNodeNumber = (PGetNumaHighestNodeNumber)(void (*)(void))GetProcAddress(hDll, \"GetNumaHighestNodeNumber\");\n    pGetLargePageMinimum = (PGetLargePageMinimum)(void (*)(void))GetProcAddress(hDll, \"GetLargePageMinimum\");\n    // Get physical memory (not available on XP, so check dynamically)\n    PGetPhysicallyInstalledSystemMemory pGetPhysicallyInstalledSystemMemory = (PGetPhysicallyInstalledSystemMemory)(void (*)(void))GetProcAddress(hDll,\"GetPhysicallyInstalledSystemMemory\");\n    if (pGetPhysicallyInstalledSystemMemory != NULL) {\n      ULONGLONG memInKiB = 0;\n      if ((*pGetPhysicallyInstalledSystemMemory)(&memInKiB)) {\n        if (memInKiB > 0 && memInKiB <= SIZE_MAX) {\n          config->physical_memory_in_kib = (size_t)memInKiB;\n        }\n      }\n    }\n    FreeLibrary(hDll);\n  }\n  // Enable large/huge OS page support?\n  if (mi_option_is_enabled(mi_option_allow_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {\n    win_enable_large_os_pages(&config->large_page_size);\n  }\n}\n\n\n//---------------------------------------------\n// Free\n//---------------------------------------------\n\nint _mi_prim_free(void* addr, size_t size ) {\n  MI_UNUSED(size);\n  DWORD errcode = 0;\n  bool err = (VirtualFree(addr, 0, MEM_RELEASE) == 0);\n  if (err) { errcode = GetLastError(); }\n  if (errcode == ERROR_INVALID_ADDRESS) {\n    // In mi_os_mem_alloc_aligned the fallback path may have returned a pointer inside\n    // the memory region returned by VirtualAlloc; in that case we need to free using\n    // the start of the region.\n    MEMORY_BASIC_INFORMATION info; _mi_memzero_var(info);\n    VirtualQuery(addr, &info, sizeof(info));\n    if (info.AllocationBase < addr && ((uint8_t*)addr - (uint8_t*)info.AllocationBase) < (ptrdiff_t)MI_SEGMENT_SIZE) {\n      errcode = 0;\n      err = (VirtualFree(info.AllocationBase, 0, MEM_RELEASE) == 0);\n      if (err) { errcode = GetLastError(); }\n    }\n  }\n  return (int)errcode;\n}\n\n\n//---------------------------------------------\n// VirtualAlloc\n//---------------------------------------------\n\nstatic void* win_virtual_alloc_prim_once(void* addr, size_t size, size_t try_alignment, DWORD flags) {\n  #if (MI_INTPTR_SIZE >= 8)\n  // on 64-bit systems, try to use the virtual address area after 2TiB for 4MiB aligned allocations\n  if (addr == NULL) {\n    void* hint = _mi_os_get_aligned_hint(try_alignment,size);\n    if (hint != NULL) {\n      void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE);\n      if (p != NULL) return p;\n      _mi_verbose_message(\"warning: unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\\n\", size, GetLastError(), hint, try_alignment, flags);\n      // fall through on error\n    }\n  }\n  #endif\n  // on modern Windows try use VirtualAlloc2 for aligned allocation\n  if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0 && pVirtualAlloc2 != NULL) {\n    MI_MEM_ADDRESS_REQUIREMENTS reqs = { 0, 0, 0 };\n    reqs.Alignment = try_alignment;\n    MI_MEM_EXTENDED_PARAMETER param = { {0, 0}, {0} };\n    param.Type.Type = MiMemExtendedParameterAddressRequirements;\n    param.Arg.Pointer = &reqs;\n    void* p = (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, &param, 1);\n    if (p != NULL) return p;\n    _mi_warning_message(\"unable to allocate aligned OS memory (0x%zx bytes, error code: 0x%x, address: %p, alignment: 0x%zx, flags: 0x%x)\\n\", size, GetLastError(), addr, try_alignment, flags);\n    // fall through on error\n  }\n  // last resort\n  return VirtualAlloc(addr, size, flags, PAGE_READWRITE);\n}\n\nstatic bool win_is_out_of_memory_error(DWORD err) {\n  switch (err) {\n    case ERROR_COMMITMENT_MINIMUM:\n    case ERROR_COMMITMENT_LIMIT:\n    case ERROR_PAGEFILE_QUOTA:\n    case ERROR_NOT_ENOUGH_MEMORY:\n      return true;\n    default:\n      return false;\n  }\n}\n\nstatic void* win_virtual_alloc_prim(void* addr, size_t size, size_t try_alignment, DWORD flags) {\n  long max_retry_msecs = mi_option_get_clamp(mi_option_retry_on_oom, 0, 2000);  // at most 2 seconds\n  if (max_retry_msecs == 1) { max_retry_msecs = 100; }  // if one sets the option to \"true\"\n  for (long tries = 1; tries <= 10; tries++) {          // try at most 10 times (=2200ms)\n    void* p = win_virtual_alloc_prim_once(addr, size, try_alignment, flags);\n    if (p != NULL) {\n      // success, return the address\n      return p;\n    }\n    else if (max_retry_msecs > 0 && (try_alignment <= 2*MI_SEGMENT_ALIGN) &&\n              (flags&MEM_COMMIT) != 0 && (flags&MEM_LARGE_PAGES) == 0 &&\n              win_is_out_of_memory_error(GetLastError())) {\n      // if committing regular memory and being out-of-memory,\n      // keep trying for a bit in case memory frees up after all. See issue #894\n      _mi_warning_message(\"out-of-memory on OS allocation, try again... (attempt %lu, 0x%zx bytes, error code: 0x%x, address: %p, alignment: 0x%zx, flags: 0x%x)\\n\", tries, size, GetLastError(), addr, try_alignment, flags);\n      long sleep_msecs = tries*40;  // increasing waits\n      if (sleep_msecs > max_retry_msecs) { sleep_msecs = max_retry_msecs; }\n      max_retry_msecs -= sleep_msecs;\n      Sleep(sleep_msecs);\n    }\n    else {\n      // otherwise return with an error\n      break;\n    }\n  }\n  return NULL;\n}\n\nstatic void* win_virtual_alloc(void* addr, size_t size, size_t try_alignment, DWORD flags, bool large_only, bool allow_large, bool* is_large) {\n  mi_assert_internal(!(large_only && !allow_large));\n  static _Atomic(size_t) large_page_try_ok; // = 0;\n  void* p = NULL;\n  // Try to allocate large OS pages (2MiB) if allowed or required.\n  if ((large_only || (_mi_os_canuse_large_page(size, try_alignment) && mi_option_is_enabled(mi_option_allow_large_os_pages)))\n      && allow_large && (flags&MEM_COMMIT)!=0 && (flags&MEM_RESERVE)!=0)\n  {\n    size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok);\n    if (!large_only && try_ok > 0) {\n      // if a large page allocation fails, it seems the calls to VirtualAlloc get very expensive.\n      // therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times.\n      mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1);\n    }\n    else {\n      // large OS pages must always reserve and commit.\n      *is_large = true;\n      p = win_virtual_alloc_prim(addr, size, try_alignment, flags | MEM_LARGE_PAGES);\n      if (large_only) return p;\n      // fall back to non-large page allocation on error (`p == NULL`).\n      if (p == NULL) {\n        mi_atomic_store_release(&large_page_try_ok,10UL);  // on error, don't try again for the next N allocations\n      }\n    }\n  }\n  // Fall back to regular page allocation\n  if (p == NULL) {\n    *is_large = ((flags&MEM_LARGE_PAGES) != 0);\n    p = win_virtual_alloc_prim(addr, size, try_alignment, flags);\n  }\n  //if (p == NULL) { _mi_warning_message(\"unable to allocate OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x, large only: %d, allow large: %d)\\n\", size, GetLastError(), addr, try_alignment, flags, large_only, allow_large); }\n  return p;\n}\n\nint _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) {\n  mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);\n  mi_assert_internal(commit || !allow_large);\n  mi_assert_internal(try_alignment > 0);\n  *is_zero = true;\n  int flags = MEM_RESERVE;\n  if (commit) { flags |= MEM_COMMIT; }\n  *addr = win_virtual_alloc(hint_addr, size, try_alignment, flags, false, allow_large, is_large);\n  return (*addr != NULL ? 0 : (int)GetLastError());\n}\n\n\n//---------------------------------------------\n// Commit/Reset/Protect\n//---------------------------------------------\n#ifdef _MSC_VER\n#pragma warning(disable:6250)   // suppress warning calling VirtualFree without MEM_RELEASE (for decommit)\n#endif\n\nint _mi_prim_commit(void* addr, size_t size, bool* is_zero) {\n  *is_zero = false;\n  /*\n  // zero'ing only happens on an initial commit... but checking upfront seems expensive..\n  _MEMORY_BASIC_INFORMATION meminfo; _mi_memzero_var(meminfo);\n  if (VirtualQuery(addr, &meminfo, size) > 0) {\n    if ((meminfo.State & MEM_COMMIT) == 0) {\n      *is_zero = true;\n    }\n  }\n  */\n  // commit\n  void* p = VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE);\n  if (p == NULL) return (int)GetLastError();\n  return 0;\n}\n\nint _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) {\n  BOOL ok = VirtualFree(addr, size, MEM_DECOMMIT);\n  *needs_recommit = true;  // for safety, assume always decommitted even in the case of an error.\n  return (ok ? 0 : (int)GetLastError());\n}\n\nint _mi_prim_reset(void* addr, size_t size) {\n  void* p = VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE);\n  mi_assert_internal(p == addr);\n  #if 0\n  if (p != NULL) {\n    VirtualUnlock(addr,size); // VirtualUnlock after MEM_RESET removes the memory directly from the working set\n  }\n  #endif\n  return (p != NULL ? 0 : (int)GetLastError());\n}\n\nint _mi_prim_reuse(void* addr, size_t size) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  return 0;\n}\n\nint _mi_prim_protect(void* addr, size_t size, bool protect) {\n  DWORD oldprotect = 0;\n  BOOL ok = VirtualProtect(addr, size, protect ? PAGE_NOACCESS : PAGE_READWRITE, &oldprotect);\n  return (ok ? 0 : (int)GetLastError());\n}\n\n\n//---------------------------------------------\n// Huge page allocation\n//---------------------------------------------\n\nstatic void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int numa_node)\n{\n  const DWORD flags = MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE;\n\n  win_enable_large_os_pages(NULL);\n\n  MI_MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} };\n  // on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages\n  static _Atomic(size_t) mi_huge_pages_available = MI_ATOMIC_VAR_INIT(1);\n  if (pNtAllocateVirtualMemoryEx != NULL && mi_atomic_load_acquire(&mi_huge_pages_available) != 0) {\n    params[0].Type.Type = MiMemExtendedParameterAttributeFlags;\n    params[0].Arg.ULong64 = MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE;\n    ULONG param_count = 1;\n    if (numa_node >= 0) {\n      param_count++;\n      params[1].Type.Type = MiMemExtendedParameterNumaNode;\n      params[1].Arg.ULong = (unsigned)numa_node;\n    }\n    SIZE_T psize = size;\n    void* base = hint_addr;\n    LONG err = (*pNtAllocateVirtualMemoryEx)(GetCurrentProcess(), &base, &psize, flags, PAGE_READWRITE, params, param_count);\n    if (err == 0 && base != NULL) {\n      return base;\n    }\n    else {\n      // fall back to regular large pages\n      mi_atomic_store_release(&mi_huge_pages_available,0); // don't try further huge pages\n      _mi_warning_message(\"unable to allocate using huge (1GiB) pages, trying large (2MiB) pages instead (status 0x%lx)\\n\", err);\n    }\n  }\n  // on modern Windows try use VirtualAlloc2 for numa aware large OS page allocation\n  if (pVirtualAlloc2 != NULL && numa_node >= 0) {\n    params[0].Type.Type = MiMemExtendedParameterNumaNode;\n    params[0].Arg.ULong = (unsigned)numa_node;\n    return (*pVirtualAlloc2)(GetCurrentProcess(), hint_addr, size, flags, PAGE_READWRITE, params, 1);\n  }\n\n  // otherwise use regular virtual alloc on older windows\n  return VirtualAlloc(hint_addr, size, flags, PAGE_READWRITE);\n}\n\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {\n  *is_zero = true;\n  *addr = _mi_prim_alloc_huge_os_pagesx(hint_addr,size,numa_node);\n  return (*addr != NULL ? 0 : (int)GetLastError());\n}\n\n\n//---------------------------------------------\n// Numa nodes\n//---------------------------------------------\n\nsize_t _mi_prim_numa_node(void) {\n  USHORT numa_node = 0;\n  if (pGetCurrentProcessorNumberEx != NULL && pGetNumaProcessorNodeEx != NULL) {\n    // Extended API is supported\n    MI_PROCESSOR_NUMBER pnum;\n    (*pGetCurrentProcessorNumberEx)(&pnum);\n    USHORT nnode = 0;\n    BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode);\n    if (ok) { numa_node = nnode; }\n  }\n  else if (pGetNumaProcessorNode != NULL) {\n    // Vista or earlier, use older API that is limited to 64 processors. Issue #277\n    DWORD pnum = GetCurrentProcessorNumber();\n    UCHAR nnode = 0;\n    BOOL ok = pGetNumaProcessorNode((UCHAR)pnum, &nnode);\n    if (ok) { numa_node = nnode; }\n  }\n  return numa_node;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  ULONG numa_max = 0;\n  if (pGetNumaHighestNodeNumber!=NULL) {\n    (*pGetNumaHighestNodeNumber)(&numa_max);\n  }\n  // find the highest node number that has actual processors assigned to it. Issue #282\n  while (numa_max > 0) {\n    if (pGetNumaNodeProcessorMaskEx != NULL) {\n      // Extended API is supported\n      GROUP_AFFINITY affinity;\n      if ((*pGetNumaNodeProcessorMaskEx)((USHORT)numa_max, &affinity)) {\n        if (affinity.Mask != 0) break;  // found the maximum non-empty node\n      }\n    }\n    else {\n      // Vista or earlier, use older API that is limited to 64 processors.\n      ULONGLONG mask;\n      if (pGetNumaNodeProcessorMask != NULL) {\n        if ((*pGetNumaNodeProcessorMask)((UCHAR)numa_max, &mask)) {\n          if (mask != 0) break; // found the maximum non-empty node\n        }\n      };\n    }\n    // max node was invalid or had no processor assigned, try again\n    numa_max--;\n  }\n  return ((size_t)numa_max + 1);\n}\n\n\n//----------------------------------------------------------------\n// Clock\n//----------------------------------------------------------------\n\nstatic mi_msecs_t mi_to_msecs(LARGE_INTEGER t) {\n  static LARGE_INTEGER mfreq; // = 0\n  if (mfreq.QuadPart == 0LL) {\n    LARGE_INTEGER f;\n    QueryPerformanceFrequency(&f);\n    mfreq.QuadPart = f.QuadPart/1000LL;\n    if (mfreq.QuadPart == 0) mfreq.QuadPart = 1;\n  }\n  return (mi_msecs_t)(t.QuadPart / mfreq.QuadPart);\n}\n\nmi_msecs_t _mi_prim_clock_now(void) {\n  LARGE_INTEGER t;\n  QueryPerformanceCounter(&t);\n  return mi_to_msecs(t);\n}\n\n\n//----------------------------------------------------------------\n// Process Info\n//----------------------------------------------------------------\n\n#include <psapi.h>\n\nstatic mi_msecs_t filetime_msecs(const FILETIME* ftime) {\n  ULARGE_INTEGER i;\n  i.LowPart = ftime->dwLowDateTime;\n  i.HighPart = ftime->dwHighDateTime;\n  mi_msecs_t msecs = (i.QuadPart / 10000); // FILETIME is in 100 nano seconds\n  return msecs;\n}\n\ntypedef BOOL (WINAPI *PGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);\nstatic PGetProcessMemoryInfo pGetProcessMemoryInfo = NULL;\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo)\n{\n  FILETIME ct;\n  FILETIME ut;\n  FILETIME st;\n  FILETIME et;\n  GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut);\n  pinfo->utime = filetime_msecs(&ut);\n  pinfo->stime = filetime_msecs(&st);\n\n  // load psapi on demand\n  mi_atomic_do_once {\n    HINSTANCE hDll = LoadLibrary(TEXT(\"psapi.dll\"));\n    if (hDll != NULL) {\n      pGetProcessMemoryInfo = (PGetProcessMemoryInfo)(void (*)(void))GetProcAddress(hDll, \"GetProcessMemoryInfo\");\n      // FreeLibrary(hDll);  // don't free\n    }\n  }\n\n  // get process info\n  PROCESS_MEMORY_COUNTERS info; _mi_memzero_var(info);\n  if (pGetProcessMemoryInfo != NULL) {\n    pGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));\n  }\n  pinfo->current_rss    = (size_t)info.WorkingSetSize;\n  pinfo->peak_rss       = (size_t)info.PeakWorkingSetSize;\n  pinfo->current_commit = (size_t)info.PagefileUsage;\n  pinfo->peak_commit    = (size_t)info.PeakPagefileUsage;\n  pinfo->page_faults    = (size_t)info.PageFaultCount;\n}\n\n//----------------------------------------------------------------\n// Output\n//----------------------------------------------------------------\n\nvoid _mi_prim_out_stderr( const char* msg )\n{\n  // on windows with redirection, the C runtime cannot handle locale dependent output\n  // after the main thread closes so we use direct console output.\n  if (!_mi_preloading()) {\n    // _cputs(msg);  // _cputs cannot be used as it aborts when failing to lock the console\n    static HANDLE hcon = INVALID_HANDLE_VALUE;\n    static bool hconIsConsole = false;\n    if (hcon == INVALID_HANDLE_VALUE) {\n      hcon = GetStdHandle(STD_ERROR_HANDLE);\n      #ifdef MI_HAS_CONSOLE_IO\n      CONSOLE_SCREEN_BUFFER_INFO sbi;\n      hconIsConsole = ((hcon != INVALID_HANDLE_VALUE) && GetConsoleScreenBufferInfo(hcon, &sbi));\n      #endif\n    }\n    const size_t len = _mi_strlen(msg);\n    if (len > 0 && len < UINT32_MAX) {\n      DWORD written = 0;\n      if (hconIsConsole) {\n        #ifdef MI_HAS_CONSOLE_IO\n        WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL);\n        #endif\n      }\n      else if (hcon != INVALID_HANDLE_VALUE) {\n        // use direct write if stderr was redirected\n        WriteFile(hcon, msg, (DWORD)len, &written, NULL);\n      }\n      else {\n        // finally fall back to fputs after all\n        fputs(msg, stderr);\n      }\n    }\n  }\n}\n\n\n//----------------------------------------------------------------\n// Environment\n//----------------------------------------------------------------\n\n// On Windows use GetEnvironmentVariable instead of getenv to work\n// reliably even when this is invoked before the C runtime is initialized.\n// i.e. when `_mi_preloading() == true`.\n// Note: on windows, environment names are not case sensitive.\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size) {\n  result[0] = 0;\n  const size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size);\n  return (len > 0 && len < result_size);\n}\n\n\n//----------------------------------------------------------------\n// Random\n//----------------------------------------------------------------\n\n#if defined(MI_USE_RTLGENRANDOM) // || defined(__cplusplus)\n// We prefer to use BCryptGenRandom instead of (the unofficial) RtlGenRandom but when using\n// dynamic overriding, we observed it can raise an exception when compiled with C++, and\n// sometimes deadlocks when also running under the VS debugger.\n// In contrast, issue #623 implies that on Windows Server 2019 we need to use BCryptGenRandom.\n// To be continued..\n#pragma comment (lib,\"advapi32.lib\")\n#define RtlGenRandom  SystemFunction036\nmi_decl_externc BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  return (RtlGenRandom(buf, (ULONG)buf_len) != 0);\n}\n\n#else\n\n#ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG\n#define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002\n#endif\n\ntypedef LONG (NTAPI *PBCryptGenRandom)(HANDLE, PUCHAR, ULONG, ULONG);\nstatic  PBCryptGenRandom pBCryptGenRandom = NULL;\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  mi_assert(buf_len <= ULONG_MAX);\n  if (buf_len > ULONG_MAX) return false;\n  mi_atomic_do_once {\n    HINSTANCE hDll = LoadLibrary(TEXT(\"bcrypt.dll\"));\n    if (hDll != NULL) {\n      pBCryptGenRandom = (PBCryptGenRandom)(void (*)(void))GetProcAddress(hDll, \"BCryptGenRandom\");\n      // FreeLibrary(hDll);  // don't free\n    }\n  }\n  if (pBCryptGenRandom == NULL) return false;\n  return (pBCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0);\n}\n\n#endif  // MI_USE_RTLGENRANDOM\n\n\n\n//----------------------------------------------------------------\n// Process & Thread Init/Done\n//----------------------------------------------------------------\n\n#if MI_WIN_USE_FIXED_TLS==1\nmi_decl_cache_align size_t _mi_win_tls_offset = 0;\n#endif\n\n//static void mi_debug_out(const char* s) {\n//  HANDLE h = GetStdHandle(STD_ERROR_HANDLE);\n//  WriteConsole(h, s, (DWORD)_mi_strlen(s), NULL, NULL);\n//}\n\nstatic void mi_win_tls_init(DWORD reason) {\n  if (reason==DLL_PROCESS_ATTACH || reason==DLL_THREAD_ATTACH) {\n    #if MI_WIN_USE_FIXED_TLS==1  // we must allocate a TLS slot dynamically\n    if (_mi_win_tls_offset == 0 && reason == DLL_PROCESS_ATTACH) {\n      const DWORD tls_slot = TlsAlloc();  // usually returns slot 1\n      if (tls_slot == TLS_OUT_OF_INDEXES) {\n        _mi_error_message(EFAULT, \"unable to allocate the a TLS slot (rebuild without MI_WIN_USE_FIXED_TLS?)\\n\");\n      }\n      _mi_win_tls_offset = (size_t)tls_slot * sizeof(void*);\n    }\n    #endif\n    #if MI_HAS_TLS_SLOT >= 2  // we must initialize the TLS slot before any allocation\n    if (mi_prim_get_default_heap() == NULL) {\n      _mi_heap_set_default_direct((mi_heap_t*)&_mi_heap_empty);\n      #if MI_DEBUG && MI_WIN_USE_FIXED_TLS==1\n      void* const p = TlsGetValue((DWORD)(_mi_win_tls_offset / sizeof(void*)));\n      mi_assert_internal(p == (void*)&_mi_heap_empty);\n      #endif\n    }\n    #endif\n  }\n}\n\nstatic void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {\n  MI_UNUSED(reserved);\n  MI_UNUSED(module);\n  mi_win_tls_init(reason);\n  if (reason==DLL_PROCESS_ATTACH) {\n    _mi_auto_process_init();\n  }\n  else if (reason==DLL_PROCESS_DETACH) {\n    _mi_auto_process_done();\n  }\n  else if (reason==DLL_THREAD_DETACH && !_mi_is_redirected()) {\n    _mi_thread_done(NULL);\n  }\n}\n\n\n/* -----------------------------------------------------------------------\n   Auto initialize and finalize mimalloc on process and thread start/end.\n   By default we use a combination of CRT init and TLS sections for\n   both static and dynamic linkage (`MI_WIN_INIT_USE_CRT_TLS`).\n------------------------------------------------------------------------- */\n#if !defined(MI_WIN_INIT_USE_CRT_TLS) && !defined(MI_WIN_INIT_USE_RAW_DLLMAIN) && !defined(MI_WIN_INIT_USE_TLS_DLLMAIN) && !defined(MI_WIN_INIT_USE_FLS)\n  #if !defined(__INTEL_LLVM_COMPILER) && !defined(__INTEL_COMPILER)\n    #define MI_WIN_INIT_USE_CRT_TLS      1  \n  #else\n    #define MI_WIN_INIT_USE_TLS_DLLMAIN  1  /* default for Intel ICX, see issue #1268 */  \n  #endif\n#endif\n\n#if defined(MI_WIN_INIT_USE_CRT_TLS)\n  #define MI_PRIM_HAS_PROCESS_ATTACH  1\n  // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.\n  void _mi_prim_thread_init_auto_done(void) {}\n  void _mi_prim_thread_done_auto_done(void) {}\n  void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {\n    MI_UNUSED(heap);\n  }\n\n  static bool mi_module_is_dll(PVOID mod) {\n    if (mod==NULL) return false;\n    PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)mod;\n    PIMAGE_NT_HEADERS imageNtHeaders = (PIMAGE_NT_HEADERS)((unsigned char*)imageDosHeader + imageDosHeader->e_lfanew);\n    return ((imageNtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL);\n  }\n\n  static bool mi_current_module_is_dll(void) {\n    HMODULE mod = NULL;\n    const BOOL ok = GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)mi_current_module_is_dll, &mod);\n    return (ok && mi_module_is_dll(mod));\n  }\n\n  // Hook into CRT initialization and finalization.\n  static void mi_cdecl mi_crt_done(void) {\n    // mi_debug_out(mi_current_module_is_dll() ? \"crt dll done\\n\" : \"crt exe done\\n\");\n    mi_win_main(NULL, DLL_PROCESS_DETACH, 0);\n  }\n\n  static int mi_cdecl mi_crt_init(void) {\n    // mi_debug_out(mi_current_module_is_dll() ? \"crt dll init\\n\" : \"crt exe init\\n\");\n    if (mi_current_module_is_dll()) {\n      // in a dll, atexit (crt_done) is called after tls process detach\n      atexit(&mi_crt_done);\n    }\n    return 0;\n  }\n\n  // We also hook into the Windows loader TLS initialization and finalization.\n  static void NTAPI mi_tls_attach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_THREAD_ATTACH) {\n      //mi_debug_out(\"tls thread attach\\n\");\n      mi_win_main(module, reason, reserved);\n    }\n    else if (reason == DLL_PROCESS_ATTACH) {\n      // mi_debug_out(mi_module_is_dll(module) ? \"tls dll process attach\\n\" : \"tls exe process attach\\n\");\n      // tls process attach is always called before crt init\n      mi_win_main(module, reason, reserved);\n    }\n  }\n\n  static void NTAPI mi_tls_detach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_THREAD_DETACH) {\n      //mi_debug_out(\"tls thread detach\\n\");\n      mi_win_main(module, reason, reserved);\n    }\n    else if (reason == DLL_PROCESS_DETACH) {\n      // mi_debug_out(mi_module_is_dll(module) ? \"tls dll process detach\\n\" : \"tls exe process detach\\n\");\n      if (!mi_module_is_dll(module)) {\n        // in an exe, tls process detach is called after atexit (mi_crt_done)\n        mi_win_main(module, reason, reserved);\n      }\n    }\n  }\n\n  // Set up TLS callbacks in a statically linked library by using special data sections.\n  // See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>\n  // We use 2 entries to ensure we call attach events before constructors\n  // are called, and detach events after destructors are called.\n  // We also set up a CRT initialization callback.\n  #if defined(__cplusplus)\n  extern \"C\" {\n  #endif\n\n  typedef int (mi_cdecl* mi_crt_callback_t)(void);\n  #if defined(_WIN64)\n    #pragma comment(linker, \"/INCLUDE:_tls_used\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_post\")\n    #pragma const_seg(\".CRT$XLB\")\n      extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];\n      const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };\n    #pragma const_seg()\n    #pragma const_seg(\".CRT$XLY\")\n      extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];\n      const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };\n    #pragma const_seg()\n    #pragma const_seg(\".CRT$XIB\")\n      extern const mi_crt_callback_t _mi_crt_callback_init[];\n      const mi_crt_callback_t _mi_crt_callback_init[] = { &mi_crt_init };\n    #pragma const_seg()\n  #else\n    #pragma comment(linker, \"/INCLUDE:__tls_used\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_post\")\n    #pragma data_seg(\".CRT$XLB\")\n      PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };\n    #pragma data_seg()\n    #pragma data_seg(\".CRT$XLY\")\n      PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };\n    #pragma data_seg()\n    #pragma data_seg(\".CRT$XIB\")\n      mi_crt_callback_t _mi_crt_callback_init[] = { &mi_crt_init };\n    #pragma data_seg()\n  #endif\n\n  #if defined(__cplusplus)\n  }\n  #endif\n\n/* ----------------------------------------------------------------\n  Here we use a combination of the raw DLL main and TLS sections for\n  both static and dynamic linkage. This is perhaps the most robust as\n  the raw DLL main ensure we can close mimalloc latest possible.\n  However, it can lead to link errors with on `_pRawDllMain` if other\n  libraries also try to hook into this (like Boost).\n*/\n#elif defined(MI_WIN_INIT_USE_RAW_DLLMAIN)\n  #define MI_PRIM_HAS_PROCESS_ATTACH  1\n  // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.\n  void _mi_prim_thread_init_auto_done(void) {}\n  void _mi_prim_thread_done_auto_done(void) {}\n  void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {\n    MI_UNUSED(heap);\n  }\n\n  // If linked into a DLL module, this raw entry is called before the CRT attach and\n  // after the CRT detach through the CRT _pRawDllMain pointer.\n  static BOOL NTAPI mi_dll_main_raw(PVOID module, DWORD reason, LPVOID reserved) {\n    mi_win_main(module, reason, reserved);\n    return TRUE;\n  }\n\n  // Set the value of the CRT _pRawDllMain pointer\n  #if defined(__cplusplus)\n  extern \"C\"\n  #endif\n  PVOID _pRawDllMain = (PVOID)&mi_dll_main_raw;\n\n  // We also hook into the Windows loader TLS initialization and finalization.\n  // If we are linked into an EXE module we rely on these as `mi_dll_main_raw`\n  // is not called (and otherwise we ignore the TLS callbacks by checking if we are in a DLL).\n  static bool mi_module_is_dll(PVOID mod) {\n    if (mod==NULL) return false;\n    PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)mod;\n    PIMAGE_NT_HEADERS imageNtHeaders = (PIMAGE_NT_HEADERS)((unsigned char*)imageDosHeader + imageDosHeader->e_lfanew);\n    return ((imageNtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL);\n  }\n\n  static void NTAPI mi_tls_attach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_PROCESS_ATTACH || reason == DLL_THREAD_ATTACH) {\n      if (!mi_module_is_dll(module)) {\n        mi_win_main(module, reason, reserved);\n      }\n    }\n  }\n\n  static void NTAPI mi_tls_detach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_PROCESS_DETACH || reason == DLL_THREAD_DETACH) {\n      if (!mi_module_is_dll(module)) {\n        mi_win_main(module, reason, reserved);\n      }\n    }\n  }\n\n  // Set up TLS callbacks in a statically linked library by using special data sections.\n  // See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>\n  // We use 2 entries to ensure we call attach events before constructors\n  // are called, and detach events after destructors are called.\n  #if defined(__cplusplus)\n  extern \"C\" {\n  #endif\n\n  #if defined(_WIN64)\n    #pragma comment(linker, \"/INCLUDE:_tls_used\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_post\")\n    #pragma const_seg(\".CRT$XLB\")\n      extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];\n      const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };\n    #pragma const_seg()\n    #pragma const_seg(\".CRT$XLY\")\n      extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];\n      const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };\n    #pragma const_seg()\n  #else\n    #pragma comment(linker, \"/INCLUDE:__tls_used\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_post\")\n    #pragma data_seg(\".CRT$XLB\")\n      PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };\n    #pragma data_seg()\n    #pragma data_seg(\".CRT$XLY\")\n      PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };\n    #pragma data_seg()\n  #endif\n\n  #if defined(__cplusplus)\n  }\n  #endif\n\n/* --------------------------------------------------------------------\n   Legacy options: DllMain, TLS, and FLS\n   --------------------------------------------------------------------*/\n#elif defined(MI_WIN_INIT_USE_TLS_DLLMAIN) && defined(MI_SHARED_LIB)\n  #define MI_PRIM_HAS_PROCESS_ATTACH  1\n\n  // Windows DLL: easy to hook into process_init and thread_done\n  BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) {\n    mi_win_main((PVOID)inst,reason,reserved);\n    return TRUE;\n  }\n\n  // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.\n  void _mi_prim_thread_init_auto_done(void) { }\n  void _mi_prim_thread_done_auto_done(void) { }\n  void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {\n    MI_UNUSED(heap);\n  }\n\n#elif defined(MI_WIN_INIT_USE_TLS_DLLMAIN)\n  #define MI_PRIM_HAS_PROCESS_ATTACH  1\n\n  static void NTAPI mi_win_main_attach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_PROCESS_ATTACH || reason == DLL_THREAD_ATTACH) {\n      mi_win_main(module, reason, reserved);\n    }\n  }\n  static void NTAPI mi_win_main_detach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_PROCESS_DETACH || reason == DLL_THREAD_DETACH) {\n      mi_win_main(module, reason, reserved);\n    }\n  }\n\n  // Set up TLS callbacks in a statically linked library by using special data sections.\n  // See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>\n  // We use 2 entries to ensure we call attach events before constructors\n  // are called, and detach events after destructors are called.\n  #if defined(__cplusplus)\n  extern \"C\" {\n  #endif\n\n  #if defined(_WIN64)\n    #pragma comment(linker, \"/INCLUDE:_tls_used\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_post\")\n    #pragma const_seg(\".CRT$XLB\")\n    extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];\n    const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_win_main_attach };\n    #pragma const_seg()\n    #pragma const_seg(\".CRT$XLY\")\n    extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];\n    const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_win_main_detach };\n    #pragma const_seg()\n  #else\n    #pragma comment(linker, \"/INCLUDE:__tls_used\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_post\")\n    #pragma data_seg(\".CRT$XLB\")\n    PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_win_main_attach };\n    #pragma data_seg()\n    #pragma data_seg(\".CRT$XIY\")\n    PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_win_main_detach };\n    #pragma data_seg()\n  #endif\n\n  #if defined(__cplusplus)\n  }\n  #endif\n\n  // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.\n  void _mi_prim_thread_init_auto_done(void) { }\n  void _mi_prim_thread_done_auto_done(void) { }\n  void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {\n    MI_UNUSED(heap);\n  }\n\n#elif defined(MI_WIN_INIT_USE_FLS) // deprecated: statically linked, use fiber api\n\n  #if defined(_MSC_VER) // on clang/gcc use the constructor attribute (in `src/prim/prim.c`)\n    // MSVC: use data section magic for static libraries\n    // See <https://www.codeguru.com/cpp/misc/misc/applicationcontrol/article.php/c6945/Running-Code-Before-and-After-Main.htm>\n    #define MI_PRIM_HAS_PROCESS_ATTACH 1\n\n    static int mi_process_attach(void) {\n      mi_win_main(NULL,DLL_PROCESS_ATTACH,NULL);\n      atexit(&_mi_auto_process_done);\n      return 0;\n    }\n    typedef int(*mi_crt_callback_t)(void);\n    #if defined(_WIN64)\n      #pragma comment(linker, \"/INCLUDE:_mi_tls_callback\")\n      #pragma section(\".CRT$XIU\", long, read)\n    #else\n      #pragma comment(linker, \"/INCLUDE:__mi_tls_callback\")\n    #endif\n    #pragma data_seg(\".CRT$XIU\")\n    mi_decl_externc mi_crt_callback_t _mi_tls_callback[] = { &mi_process_attach };\n    #pragma data_seg()\n  #endif\n\n  // use the fiber api for calling `_mi_thread_done`.\n  #include <fibersapi.h>\n  #if (_WIN32_WINNT < 0x600)  // before Windows Vista\n  WINBASEAPI DWORD WINAPI FlsAlloc( _In_opt_ PFLS_CALLBACK_FUNCTION lpCallback );\n  WINBASEAPI PVOID WINAPI FlsGetValue( _In_ DWORD dwFlsIndex );\n  WINBASEAPI BOOL  WINAPI FlsSetValue( _In_ DWORD dwFlsIndex, _In_opt_ PVOID lpFlsData );\n  WINBASEAPI BOOL  WINAPI FlsFree(_In_ DWORD dwFlsIndex);\n  #endif\n\n  static DWORD mi_fls_key = (DWORD)(-1);\n\n  static void NTAPI mi_fls_done(PVOID value) {\n    mi_heap_t* heap = (mi_heap_t*)value;\n    if (heap != NULL) {\n      _mi_thread_done(heap);\n      FlsSetValue(mi_fls_key, NULL);  // prevent recursion as _mi_thread_done may set it back to the main heap, issue #672\n    }\n  }\n\n  void _mi_prim_thread_init_auto_done(void) {\n    mi_fls_key = FlsAlloc(&mi_fls_done);\n  }\n\n  void _mi_prim_thread_done_auto_done(void) {\n    // call thread-done on all threads (except the main thread) to prevent\n    // dangling callback pointer if statically linked with a DLL; Issue #208\n    FlsFree(mi_fls_key);\n  }\n\n  void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {\n    mi_assert_internal(mi_fls_key != (DWORD)(-1));\n    FlsSetValue(mi_fls_key, heap);\n  }\n#else\n#error \"define windows process and thread auto initialization\"\n#endif\n\n// ----------------------------------------------------\n// Communicate with the redirection module on Windows\n// ----------------------------------------------------\n#if defined(MI_SHARED_LIB) && !defined(MI_WIN_NOREDIRECT)\n  #define MI_PRIM_HAS_ALLOCATOR_INIT 1\n\n  static bool mi_redirected = false;   // true if malloc redirects to mi_malloc\n\n  bool _mi_is_redirected(void) {\n    return mi_redirected;\n  }\n\n  #ifdef __cplusplus\n  extern \"C\" {\n  #endif\n  mi_decl_export void _mi_redirect_entry(DWORD reason) {\n    // called on redirection; careful as this may be called before DllMain\n    mi_win_tls_init(reason);\n    if (reason == DLL_PROCESS_ATTACH) {\n      mi_redirected = true;\n    }\n    else if (reason == DLL_PROCESS_DETACH) {\n      mi_redirected = false;\n    }\n    else if (reason == DLL_THREAD_DETACH) {\n      // mi_debug_out(\"redirect thread detach\\n\");\n      _mi_thread_done(NULL);\n    }\n  }\n  __declspec(dllimport) bool mi_cdecl mi_allocator_init(const char** message);\n  __declspec(dllimport) void mi_cdecl mi_allocator_done(void);\n  #ifdef __cplusplus\n  }\n  #endif\n  bool _mi_allocator_init(const char** message) {\n    return mi_allocator_init(message);\n  }\n  void _mi_allocator_done(void) {\n    mi_allocator_done();\n  }\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/random.c",
      "sha256": "a2c4c4cf5cb2476ba3bf6ef55ea8d10e36d4ffce93020012dcf7c1918b3faf1b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2021, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"    // _mi_prim_random_buf\n#include <string.h>       // memset\n\n/* ----------------------------------------------------------------------------\nWe use our own PRNG to keep predictable performance of random number generation\nand to avoid implementations that use a lock. We only use the OS provided\nrandom source to initialize the initial seeds. Since we do not need ultimate\nperformance but we do rely on the security (for secret cookies in secure mode)\nwe use a cryptographically secure generator (chacha20).\n-----------------------------------------------------------------------------*/\n\n#define MI_CHACHA_ROUNDS (20)   // perhaps use 12 for better performance?\n\n\n/* ----------------------------------------------------------------------------\nChacha20 implementation as the original algorithm with a 64-bit nonce\nand counter: https://en.wikipedia.org/wiki/Salsa20\nThe input matrix has sixteen 32-bit values:\nPosition  0 to  3: constant key\nPosition  4 to 11: the key\nPosition 12 to 13: the counter.\nPosition 14 to 15: the nonce.\n\nThe implementation uses regular C code which compiles very well on modern compilers.\n(gcc x64 has no register spills, and clang 6+ uses SSE instructions)\n-----------------------------------------------------------------------------*/\n\nstatic inline uint32_t rotl(uint32_t x, uint32_t shift) {\n  return (x << shift) | (x >> (32 - shift));\n}\n\nstatic inline void qround(uint32_t x[16], size_t a, size_t b, size_t c, size_t d) {\n  x[a] += x[b]; x[d] = rotl(x[d] ^ x[a], 16);\n  x[c] += x[d]; x[b] = rotl(x[b] ^ x[c], 12);\n  x[a] += x[b]; x[d] = rotl(x[d] ^ x[a], 8);\n  x[c] += x[d]; x[b] = rotl(x[b] ^ x[c], 7);\n}\n\nstatic void chacha_block(mi_random_ctx_t* ctx)\n{\n  // scramble into `x`\n  uint32_t x[16];\n  for (size_t i = 0; i < 16; i++) {\n    x[i] = ctx->input[i];\n  }\n  for (size_t i = 0; i < MI_CHACHA_ROUNDS; i += 2) {\n    qround(x, 0, 4,  8, 12);\n    qround(x, 1, 5,  9, 13);\n    qround(x, 2, 6, 10, 14);\n    qround(x, 3, 7, 11, 15);\n    qround(x, 0, 5, 10, 15);\n    qround(x, 1, 6, 11, 12);\n    qround(x, 2, 7,  8, 13);\n    qround(x, 3, 4,  9, 14);\n  }\n\n  // add scrambled data to the initial state\n  for (size_t i = 0; i < 16; i++) {\n    ctx->output[i] = x[i] + ctx->input[i];\n  }\n  ctx->output_available = 16;\n\n  // increment the counter for the next round\n  ctx->input[12] += 1;\n  if (ctx->input[12] == 0) {\n    ctx->input[13] += 1;\n    if (ctx->input[13] == 0) {  // and keep increasing into the nonce\n      ctx->input[14] += 1;\n    }\n  }\n}\n\nstatic uint32_t chacha_next32(mi_random_ctx_t* ctx) {\n  if (ctx->output_available <= 0) {\n    chacha_block(ctx);\n    ctx->output_available = 16; // (assign again to suppress static analysis warning)\n  }\n  const uint32_t x = ctx->output[16 - ctx->output_available];\n  ctx->output[16 - ctx->output_available] = 0; // reset once the data is handed out\n  ctx->output_available--;\n  return x;\n}\n\nstatic inline uint32_t read32(const uint8_t* p, size_t idx32) {\n  const size_t i = 4*idx32;\n  return ((uint32_t)p[i+0] | (uint32_t)p[i+1] << 8 | (uint32_t)p[i+2] << 16 | (uint32_t)p[i+3] << 24);\n}\n\nstatic void chacha_init(mi_random_ctx_t* ctx, const uint8_t key[32], uint64_t nonce)\n{\n  // since we only use chacha for randomness (and not encryption) we\n  // do not _need_ to read 32-bit values as little endian but we do anyways\n  // just for being compatible :-)\n  ctx->output_available = 0;\n  _mi_memzero(ctx->output,sizeof(ctx->output));\n  for (size_t i = 0; i < 4; i++) {\n    const uint8_t* sigma = (uint8_t*)\"expand 32-byte k\";\n    ctx->input[i] = read32(sigma,i);\n  }\n  for (size_t i = 0; i < 8; i++) {\n    ctx->input[i + 4] = read32(key,i);\n  }\n  ctx->input[12] = 0;\n  ctx->input[13] = 0;\n  ctx->input[14] = (uint32_t)nonce;\n  ctx->input[15] = (uint32_t)(nonce >> 32);\n}\n\nstatic void chacha_split(mi_random_ctx_t* ctx, uint64_t nonce, mi_random_ctx_t* ctx_new) {\n  _mi_memzero(ctx_new, sizeof(*ctx_new));\n  ctx_new->weak = ctx->weak;\n  _mi_memcpy(ctx_new->input, ctx->input, sizeof(ctx_new->input));\n  ctx_new->input[12] = 0;\n  ctx_new->input[13] = 0;\n  ctx_new->input[14] = (uint32_t)nonce;\n  ctx_new->input[15] = (uint32_t)(nonce >> 32);\n  mi_assert_internal(ctx->input[14] != ctx_new->input[14] || ctx->input[15] != ctx_new->input[15]); // do not reuse nonces!\n  chacha_block(ctx_new);\n}\n\n\n/* ----------------------------------------------------------------------------\nRandom interface\n-----------------------------------------------------------------------------*/\n\n#if MI_DEBUG>1\nstatic bool mi_random_is_initialized(mi_random_ctx_t* ctx) {\n  return (ctx != NULL && ctx->input[0] != 0);\n}\n#endif\n\nvoid _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* ctx_new) {\n  mi_assert_internal(mi_random_is_initialized(ctx));\n  mi_assert_internal(ctx != ctx_new);\n  chacha_split(ctx, (uintptr_t)ctx_new /*nonce*/, ctx_new);\n}\n\nuintptr_t _mi_random_next(mi_random_ctx_t* ctx) {\n  mi_assert_internal(mi_random_is_initialized(ctx));\n  uintptr_t r;\n  do {\n    #if MI_INTPTR_SIZE <= 4\n    r = chacha_next32(ctx);\n    #elif MI_INTPTR_SIZE == 8\n    r = (((uintptr_t)chacha_next32(ctx) << 32) | chacha_next32(ctx));\n    #else\n    # error \"define mi_random_next for this platform\"\n    #endif\n  } while (r==0);\n  return r;\n}\n\n\n/* ----------------------------------------------------------------------------\nTo initialize a fresh random context.\nIf we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR.\n-----------------------------------------------------------------------------*/\n\nuintptr_t _mi_os_random_weak(uintptr_t extra_seed) {\n  uintptr_t x = (uintptr_t)&_mi_os_random_weak ^ extra_seed; // ASLR makes the address random\n  x ^= _mi_prim_clock_now();  \n  // and do a few randomization steps\n  uintptr_t max = ((x ^ (x >> 17)) & 0x0F) + 1;\n  for (uintptr_t i = 0; i < max || x==0; i++, x++) {\n    x = _mi_random_shuffle(x);\n  }\n  mi_assert_internal(x != 0);\n  return x;\n}\n\nstatic void mi_random_init_ex(mi_random_ctx_t* ctx, bool use_weak) {\n  uint8_t key[32];\n  if (use_weak || !_mi_prim_random_buf(key, sizeof(key))) {\n    // if we fail to get random data from the OS, we fall back to a\n    // weak random source based on the current time\n    #if !defined(__wasi__)\n    if (!use_weak) { _mi_warning_message(\"unable to use secure randomness\\n\"); }\n    #endif\n    uintptr_t x = _mi_os_random_weak(0);\n    for (size_t i = 0; i < 32; i+=4, x++) {  \n      x = _mi_random_shuffle(x);\n      key[i]   = (uint8_t)(x);\n      key[i+1] = (uint8_t)(x>>8);\n      key[i+2] = (uint8_t)(x>>16);\n      key[i+3] = (uint8_t)(x>>24);      \n    }\n    ctx->weak = true;\n  }\n  else {\n    ctx->weak = false;\n  }\n  chacha_init(ctx, key, (uintptr_t)ctx /*nonce*/ );\n}\n\nvoid _mi_random_init(mi_random_ctx_t* ctx) {\n  mi_random_init_ex(ctx, false);\n}\n\nvoid _mi_random_init_weak(mi_random_ctx_t * ctx) {\n  mi_random_init_ex(ctx, true);\n}\n\nvoid _mi_random_reinit_if_weak(mi_random_ctx_t * ctx) {\n  if (ctx->weak) {\n    _mi_random_init(ctx);\n  }\n}\n\n/* --------------------------------------------------------\ntest vectors from <https://tools.ietf.org/html/rfc8439>\n----------------------------------------------------------- */\n/*\nstatic bool array_equals(uint32_t* x, uint32_t* y, size_t n) {\n  for (size_t i = 0; i < n; i++) {\n    if (x[i] != y[i]) return false;\n  }\n  return true;\n}\nstatic void chacha_test(void)\n{\n  uint32_t x[4] = { 0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567 };\n  uint32_t x_out[4] = { 0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb };\n  qround(x, 0, 1, 2, 3);\n  mi_assert_internal(array_equals(x, x_out, 4));\n\n  uint32_t y[16] = {\n       0x879531e0,  0xc5ecf37d,  0x516461b1,  0xc9a62f8a,\n       0x44c20ef3,  0x3390af7f,  0xd9fc690b,  0x2a5f714c,\n       0x53372767,  0xb00a5631,  0x974c541a,  0x359e9963,\n       0x5c971061,  0x3d631689,  0x2098d9d6,  0x91dbd320 };\n  uint32_t y_out[16] = {\n       0x879531e0,  0xc5ecf37d,  0xbdb886dc,  0xc9a62f8a,\n       0x44c20ef3,  0x3390af7f,  0xd9fc690b,  0xcfacafd2,\n       0xe46bea80,  0xb00a5631,  0x974c541a,  0x359e9963,\n       0x5c971061,  0xccc07c79,  0x2098d9d6,  0x91dbd320 };\n  qround(y, 2, 7, 8, 13);\n  mi_assert_internal(array_equals(y, y_out, 16));\n\n  mi_random_ctx_t r = {\n    { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,\n      0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,\n      0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,\n      0x00000001, 0x09000000, 0x4a000000, 0x00000000 },\n    {0},\n    0\n  };\n  uint32_t r_out[16] = {\n       0xe4e7f110, 0x15593bd1, 0x1fdd0f50, 0xc47120a3,\n       0xc7f4d1c7, 0x0368c033, 0x9aaa2204, 0x4e6cd4c3,\n       0x466482d2, 0x09aa9f07, 0x05d7c214, 0xa2028bd9,\n       0xd19c12b5, 0xb94e16de, 0xe883d0cb, 0x4e3c50a2 };\n  chacha_block(&r);\n  mi_assert_internal(array_equals(r.output, r_out, 16));\n}\n*/\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/segment-map.c",
      "sha256": "a4a8e2838cd471920eac30eedc8cb47cd28f820b06b4ee344e2492a9c98a8fb6",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* -----------------------------------------------------------\n  The following functions are to reliably find the segment or\n  block that encompasses any pointer p (or NULL if it is not\n  in any of our segments).\n  We maintain a bitmap of all memory with 1 bit per MI_SEGMENT_SIZE (64MiB)\n  set to 1 if it contains the segment meta data.\n----------------------------------------------------------- */\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n\n// Reduce total address space to reduce .bss  (due to the `mi_segment_map`)\n#if (MI_INTPTR_SIZE > 4) && MI_TRACK_ASAN\n#define MI_SEGMENT_MAP_MAX_ADDRESS    (128*1024ULL*MI_GiB)  // 128 TiB  (see issue #881)\n#elif (MI_INTPTR_SIZE > 4)\n#define MI_SEGMENT_MAP_MAX_ADDRESS    (48*1024ULL*MI_GiB)   // 48 TiB\n#else\n#define MI_SEGMENT_MAP_MAX_ADDRESS    (UINT32_MAX)\n#endif\n\n#define MI_SEGMENT_MAP_PART_SIZE      (MI_INTPTR_SIZE*MI_KiB - 128)      // 128 > sizeof(mi_memid_t) ! \n#define MI_SEGMENT_MAP_PART_BITS      (8*MI_SEGMENT_MAP_PART_SIZE)\n#define MI_SEGMENT_MAP_PART_ENTRIES   (MI_SEGMENT_MAP_PART_SIZE / MI_INTPTR_SIZE)\n#define MI_SEGMENT_MAP_PART_BIT_SPAN  (MI_SEGMENT_ALIGN)                 // memory area covered by 1 bit\n\n#if (MI_SEGMENT_MAP_PART_BITS < (MI_SEGMENT_MAP_MAX_ADDRESS / MI_SEGMENT_MAP_PART_BIT_SPAN)) // prevent overflow on 32-bit (issue #1017)\n#define MI_SEGMENT_MAP_PART_SPAN      (MI_SEGMENT_MAP_PART_BITS * MI_SEGMENT_MAP_PART_BIT_SPAN)\n#else\n#define MI_SEGMENT_MAP_PART_SPAN      MI_SEGMENT_MAP_MAX_ADDRESS\n#endif\n\n#define MI_SEGMENT_MAP_MAX_PARTS      ((MI_SEGMENT_MAP_MAX_ADDRESS / MI_SEGMENT_MAP_PART_SPAN) + 1)\n\n// A part of the segment map.\ntypedef struct mi_segmap_part_s {\n  mi_memid_t memid;\n  _Atomic(uintptr_t) map[MI_SEGMENT_MAP_PART_ENTRIES];\n} mi_segmap_part_t;\n\n// Allocate parts on-demand to reduce .bss footprint\nstatic _Atomic(mi_segmap_part_t*) mi_segment_map[MI_SEGMENT_MAP_MAX_PARTS]; // = { NULL, .. }\n\nstatic mi_segmap_part_t* mi_segment_map_index_of(const mi_segment_t* segment, bool create_on_demand, size_t* idx, size_t* bitidx) {\n  // note: segment can be invalid or NULL.\n  mi_assert_internal(_mi_ptr_segment(segment + 1) == segment); // is it aligned on MI_SEGMENT_SIZE?\n  *idx = 0;\n  *bitidx = 0;  \n  if ((uintptr_t)segment >= MI_SEGMENT_MAP_MAX_ADDRESS) return NULL;\n  const uintptr_t segindex = ((uintptr_t)segment) / MI_SEGMENT_MAP_PART_SPAN;\n  if (segindex >= MI_SEGMENT_MAP_MAX_PARTS) return NULL;\n  mi_segmap_part_t* part = mi_atomic_load_ptr_relaxed(mi_segmap_part_t, &mi_segment_map[segindex]);\n\n  // allocate on demand to reduce .bss footprint\n  if mi_unlikely(part == NULL) {\n    if (!create_on_demand) return NULL;\n    mi_memid_t memid;\n    part = (mi_segmap_part_t*)_mi_os_zalloc(sizeof(mi_segmap_part_t), &memid);\n    if (part == NULL) return NULL;\n    part->memid = memid;\n    mi_segmap_part_t* expected = NULL;\n    if (!mi_atomic_cas_ptr_strong_release(mi_segmap_part_t, &mi_segment_map[segindex], &expected, part)) {\n      _mi_os_free(part, sizeof(mi_segmap_part_t), memid);\n      part = expected;\n      if (part == NULL) return NULL;\n    }\n  }\n  mi_assert(part != NULL);\n  const uintptr_t offset = ((uintptr_t)segment) % MI_SEGMENT_MAP_PART_SPAN;\n  const uintptr_t bitofs = offset / MI_SEGMENT_MAP_PART_BIT_SPAN;\n  *idx = bitofs / MI_INTPTR_BITS;\n  *bitidx = bitofs % MI_INTPTR_BITS;\n  return part;\n}\n\nvoid _mi_segment_map_allocated_at(const mi_segment_t* segment) {\n  if (segment->memid.memkind == MI_MEM_ARENA) return; // we lookup segments first in the arena's and don't need the segment map\n  size_t index;\n  size_t bitidx;\n  mi_segmap_part_t* part = mi_segment_map_index_of(segment, true /* alloc map if needed */, &index, &bitidx);\n  if (part == NULL) return; // outside our address range..\n  uintptr_t mask = mi_atomic_load_relaxed(&part->map[index]);\n  uintptr_t newmask;\n  do {\n    newmask = (mask | ((uintptr_t)1 << bitidx));\n  } while (!mi_atomic_cas_weak_release(&part->map[index], &mask, newmask));\n}\n\nvoid _mi_segment_map_freed_at(const mi_segment_t* segment) {\n  if (segment->memid.memkind == MI_MEM_ARENA) return;\n  size_t index;\n  size_t bitidx;\n  mi_segmap_part_t* part = mi_segment_map_index_of(segment, false /* don't alloc if not present */, &index, &bitidx);\n  if (part == NULL) return; // outside our address range..\n  uintptr_t mask = mi_atomic_load_relaxed(&part->map[index]);\n  uintptr_t newmask;\n  do {\n    newmask = (mask & ~((uintptr_t)1 << bitidx));\n  } while (!mi_atomic_cas_weak_release(&part->map[index], &mask, newmask));\n}\n\n// Determine the segment belonging to a pointer or NULL if it is not in a valid segment.\nstatic mi_segment_t* _mi_segment_of(const void* p) {\n  if (p == NULL) return NULL;\n  mi_segment_t* segment = _mi_ptr_segment(p);  // segment can be NULL  \n  size_t index;\n  size_t bitidx;\n  mi_segmap_part_t* part = mi_segment_map_index_of(segment, false /* dont alloc if not present */, &index, &bitidx);\n  if (part == NULL) return NULL;  \n  const uintptr_t mask = mi_atomic_load_relaxed(&part->map[index]);  \n  if mi_likely((mask & ((uintptr_t)1 << bitidx)) != 0) {\n    // yes, allocated by us\n    const bool cookie_ok = (_mi_ptr_cookie(segment) == segment->cookie);\n    if mi_likely(cookie_ok) {\n      return segment; // yes, allocated by us and valid\n    }\n    else {\n      _mi_error_message(EFAULT, \"segment map found an invalid segment, possibly corrupted meta-data (address=%p, segment=%p)\\n\", p, segment);\n    }\n  }\n  return NULL;\n}\n\n// Is this a valid pointer in our heap?\nstatic bool mi_is_valid_pointer(const void* p) {\n  // first check if it is in an arena, then check if it is OS allocated\n  return (_mi_arena_contains(p) || _mi_segment_of(p) != NULL);\n}\n\nmi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept {\n  return mi_is_valid_pointer(p);\n}\n\nvoid _mi_segment_map_unsafe_destroy(void) {\n  for (size_t i = 0; i < MI_SEGMENT_MAP_MAX_PARTS; i++) {\n    mi_segmap_part_t* part = mi_atomic_exchange_ptr_relaxed(mi_segmap_part_t, &mi_segment_map[i], NULL);\n    if (part != NULL) {\n      _mi_os_free(part, sizeof(mi_segmap_part_t), part->memid);\n    }\n  }\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/segment.c",
      "sha256": "5dd7955307d8dd388ef4a395b9b85b6865774857fcb0d86cf705c2c76f7a2816",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n\n#include <string.h>  // memset\n#include <stdio.h>\n\n// -------------------------------------------------------------------\n// Segments\n// mimalloc pages reside in segments. See `mi_segment_valid` for invariants.\n// -------------------------------------------------------------------\n\n\nstatic void mi_segment_try_purge(mi_segment_t* segment, bool force);\n\n\n// -------------------------------------------------------------------\n// commit mask\n// -------------------------------------------------------------------\n\nstatic bool mi_commit_mask_all_set(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm) {\n  for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {\n    if ((commit->mask[i] & cm->mask[i]) != cm->mask[i]) return false;\n  }\n  return true;\n}\n\nstatic bool mi_commit_mask_any_set(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm) {\n  for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {\n    if ((commit->mask[i] & cm->mask[i]) != 0) return true;\n  }\n  return false;\n}\n\nstatic void mi_commit_mask_create_intersect(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm, mi_commit_mask_t* res) {\n  for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {\n    res->mask[i] = (commit->mask[i] & cm->mask[i]);\n  }\n}\n\nstatic void mi_commit_mask_clear(mi_commit_mask_t* res, const mi_commit_mask_t* cm) {\n  for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {\n    res->mask[i] &= ~(cm->mask[i]);\n  }\n}\n\nstatic void mi_commit_mask_set(mi_commit_mask_t* res, const mi_commit_mask_t* cm) {\n  for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {\n    res->mask[i] |= cm->mask[i];\n  }\n}\n\nstatic void mi_commit_mask_create(size_t bitidx, size_t bitcount, mi_commit_mask_t* cm) {\n  mi_assert_internal(bitidx < MI_COMMIT_MASK_BITS);\n  mi_assert_internal((bitidx + bitcount) <= MI_COMMIT_MASK_BITS);\n  if (bitcount == MI_COMMIT_MASK_BITS) {\n    mi_assert_internal(bitidx==0);\n    mi_commit_mask_create_full(cm);\n  }\n  else if (bitcount == 0) {\n    mi_commit_mask_create_empty(cm);\n  }\n  else {\n    mi_commit_mask_create_empty(cm);\n    size_t i = bitidx / MI_COMMIT_MASK_FIELD_BITS;\n    size_t ofs = bitidx % MI_COMMIT_MASK_FIELD_BITS;\n    while (bitcount > 0) {\n      mi_assert_internal(i < MI_COMMIT_MASK_FIELD_COUNT);\n      size_t avail = MI_COMMIT_MASK_FIELD_BITS - ofs;\n      size_t count = (bitcount > avail ? avail : bitcount);\n      size_t mask = (count >= MI_COMMIT_MASK_FIELD_BITS ? ~((size_t)0) : (((size_t)1 << count) - 1) << ofs);\n      cm->mask[i] = mask;\n      bitcount -= count;\n      ofs = 0;\n      i++;\n    }\n  }\n}\n\nsize_t _mi_commit_mask_committed_size(const mi_commit_mask_t* cm, size_t total) {\n  mi_assert_internal((total%MI_COMMIT_MASK_BITS)==0);\n  size_t count = 0;\n  for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {\n    size_t mask = cm->mask[i];\n    if (~mask == 0) {\n      count += MI_COMMIT_MASK_FIELD_BITS;\n    }\n    else {\n      for (; mask != 0; mask >>= 1) {  // todo: use popcount\n        if ((mask&1)!=0) count++;\n      }\n    }\n  }\n  // we use total since for huge segments each commit bit may represent a larger size\n  return ((total / MI_COMMIT_MASK_BITS) * count);\n}\n\n\nsize_t _mi_commit_mask_next_run(const mi_commit_mask_t* cm, size_t* idx) {\n  size_t i = (*idx) / MI_COMMIT_MASK_FIELD_BITS;\n  size_t ofs = (*idx) % MI_COMMIT_MASK_FIELD_BITS;\n  size_t mask = 0;\n  // find first ones\n  while (i < MI_COMMIT_MASK_FIELD_COUNT) {\n    mask = cm->mask[i];\n    mask >>= ofs;\n    if (mask != 0) {\n      while ((mask&1) == 0) {\n        mask >>= 1;\n        ofs++;\n      }\n      break;\n    }\n    i++;\n    ofs = 0;\n  }\n  if (i >= MI_COMMIT_MASK_FIELD_COUNT) {\n    // not found\n    *idx = MI_COMMIT_MASK_BITS;\n    return 0;\n  }\n  else {\n    // found, count ones\n    size_t count = 0;\n    *idx = (i*MI_COMMIT_MASK_FIELD_BITS) + ofs;\n    do {\n      mi_assert_internal(ofs < MI_COMMIT_MASK_FIELD_BITS && (mask&1) == 1);\n      do {\n        count++;\n        mask >>= 1;\n      } while ((mask&1) == 1);\n      if ((((*idx + count) % MI_COMMIT_MASK_FIELD_BITS) == 0)) {\n        i++;\n        if (i >= MI_COMMIT_MASK_FIELD_COUNT) break;\n        mask = cm->mask[i];\n        ofs = 0;\n      }\n    } while ((mask&1) == 1);\n    mi_assert_internal(count > 0);\n    return count;\n  }\n}\n\n\n/* --------------------------------------------------------------------------------\n  Segment allocation\n  We allocate pages inside bigger \"segments\" (32 MiB on 64-bit). This is to avoid\n  splitting VMA's on Linux and reduce fragmentation on other OS's.\n  Each thread owns its own segments.\n\n  Currently we have:\n  - small pages (64KiB)\n  - medium pages (512KiB)\n  - large pages (4MiB),\n  - huge segments have 1 page in one segment that can be larger than `MI_SEGMENT_SIZE`.\n    it is used for blocks `> MI_LARGE_OBJ_SIZE_MAX` or with alignment `> MI_BLOCK_ALIGNMENT_MAX`.\n\n  The memory for a segment is usually committed on demand.\n  (i.e. we are careful to not touch the memory until we actually allocate a block there)\n\n  If a  thread ends, it \"abandons\" pages that still contain live blocks.\n  Such segments are abandoned and these can be reclaimed by still running threads,\n  (much like work-stealing).\n-------------------------------------------------------------------------------- */\n\n\n/* -----------------------------------------------------------\n   Slices\n----------------------------------------------------------- */\n\n\nstatic const mi_slice_t* mi_segment_slices_end(const mi_segment_t* segment) {\n  return &segment->slices[segment->slice_entries];\n}\n\nstatic uint8_t* mi_slice_start(const mi_slice_t* slice) {\n  mi_segment_t* segment = _mi_ptr_segment(slice);\n  mi_assert_internal(slice >= segment->slices && slice < mi_segment_slices_end(segment));\n  return ((uint8_t*)segment + ((slice - segment->slices)*MI_SEGMENT_SLICE_SIZE));\n}\n\n\n/* -----------------------------------------------------------\n   Bins\n----------------------------------------------------------- */\n// Use bit scan forward to quickly find the first zero bit if it is available\n\nstatic inline size_t mi_slice_bin8(size_t slice_count) {\n  if (slice_count<=1) return slice_count;\n  mi_assert_internal(slice_count <= MI_SLICES_PER_SEGMENT);\n  slice_count--;\n  size_t s = mi_bsr(slice_count);  // slice_count > 1\n  if (s <= 2) return slice_count + 1;\n  size_t bin = ((s << 2) | ((slice_count >> (s - 2))&0x03)) - 4;\n  return bin;\n}\n\nstatic inline size_t mi_slice_bin(size_t slice_count) {\n  mi_assert_internal(slice_count*MI_SEGMENT_SLICE_SIZE <= MI_SEGMENT_SIZE);\n  mi_assert_internal(mi_slice_bin8(MI_SLICES_PER_SEGMENT) <= MI_SEGMENT_BIN_MAX);\n  size_t bin = mi_slice_bin8(slice_count);\n  mi_assert_internal(bin <= MI_SEGMENT_BIN_MAX);\n  return bin;\n}\n\nstatic inline size_t mi_slice_index(const mi_slice_t* slice) {\n  mi_segment_t* segment = _mi_ptr_segment(slice);\n  ptrdiff_t index = slice - segment->slices;\n  mi_assert_internal(index >= 0 && index < (ptrdiff_t)segment->slice_entries);\n  return index;\n}\n\n\n/* -----------------------------------------------------------\n   Slice span queues\n----------------------------------------------------------- */\n\nstatic void mi_span_queue_push(mi_span_queue_t* sq, mi_slice_t* slice) {\n  // todo: or push to the end?\n  mi_assert_internal(slice->prev == NULL && slice->next==NULL);\n  slice->prev = NULL; // paranoia\n  slice->next = sq->first;\n  sq->first = slice;\n  if (slice->next != NULL) slice->next->prev = slice;\n                     else sq->last = slice;\n  slice->block_size = 0; // free\n}\n\nstatic mi_span_queue_t* mi_span_queue_for(size_t slice_count, mi_segments_tld_t* tld) {\n  size_t bin = mi_slice_bin(slice_count);\n  mi_span_queue_t* sq = &tld->spans[bin];\n  mi_assert_internal(sq->slice_count >= slice_count);\n  return sq;\n}\n\nstatic void mi_span_queue_delete(mi_span_queue_t* sq, mi_slice_t* slice) {\n  mi_assert_internal(slice->block_size==0 && slice->slice_count>0 && slice->slice_offset==0);\n  // should work too if the queue does not contain slice (which can happen during reclaim)\n  if (slice->prev != NULL) slice->prev->next = slice->next;\n  if (slice == sq->first) sq->first = slice->next;\n  if (slice->next != NULL) slice->next->prev = slice->prev;\n  if (slice == sq->last) sq->last = slice->prev;\n  slice->prev = NULL;\n  slice->next = NULL;\n  slice->block_size = 1; // no more free\n}\n\n\n/* -----------------------------------------------------------\n Invariant checking\n----------------------------------------------------------- */\n\nstatic bool mi_slice_is_used(const mi_slice_t* slice) {\n  return (slice->block_size > 0);\n}\n\n\n#if (MI_DEBUG>=3)\nstatic bool mi_span_queue_contains(mi_span_queue_t* sq, mi_slice_t* slice) {\n  for (mi_slice_t* s = sq->first; s != NULL; s = s->next) {\n    if (s==slice) return true;\n  }\n  return false;\n}\n\nstatic bool mi_segment_is_valid(mi_segment_t* segment, mi_segments_tld_t* tld) {\n  mi_assert_internal(segment != NULL);\n  mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie);\n  mi_assert_internal(segment->abandoned <= segment->used);\n  mi_assert_internal(segment->thread_id == 0 || segment->thread_id == _mi_thread_id());\n  mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask)); // can only decommit committed blocks\n\n  // [specbot S-NEW-1] segment must have at least one slice (L1, O(1))\n  mi_assert_internal(segment->segment_slices > 0);\n  // [specbot S-NEW-2] info slices must leave room for at least one data slice (L1, O(1))\n  mi_assert_internal(segment->segment_info_slices < segment->segment_slices);\n  // [specbot S-NEW-3] slice_entries must not exceed array bounds (L1, O(1))\n  mi_assert_internal(segment->slice_entries <= MI_SLICES_PER_SEGMENT);\n\n  //mi_assert_internal(segment->segment_info_size % MI_SEGMENT_SLICE_SIZE == 0);\n  mi_slice_t* slice = &segment->slices[0];\n  const mi_slice_t* end = mi_segment_slices_end(segment);\n  size_t used_count = 0;\n  size_t total_slice_count = 0;\n  mi_span_queue_t* sq;\n  while(slice < end) {\n    mi_assert_internal(slice->slice_count > 0);\n    total_slice_count += slice->slice_count;\n    mi_assert_internal(slice->slice_offset == 0);\n    size_t index = mi_slice_index(slice);\n    size_t maxindex = (index + slice->slice_count >= segment->slice_entries ? segment->slice_entries : index + slice->slice_count) - 1;\n    if (mi_slice_is_used(slice)) { // a page in use, we need at least MAX_SLICE_OFFSET_COUNT valid back offsets\n      used_count++;\n      mi_assert_internal(slice->is_huge == (segment->kind == MI_SEGMENT_HUGE));\n      for (size_t i = 0; i <= MI_MAX_SLICE_OFFSET_COUNT && index + i <= maxindex; i++) {\n        mi_assert_internal(segment->slices[index + i].slice_offset == i*sizeof(mi_slice_t));\n        mi_assert_internal(i==0 || segment->slices[index + i].slice_count == 0);\n        mi_assert_internal(i==0 || segment->slices[index + i].block_size == 1);\n      }\n      // and the last entry as well (for coalescing)\n      const mi_slice_t* last = slice + slice->slice_count - 1;\n      if (last > slice && last < mi_segment_slices_end(segment)) {\n        mi_assert_internal(last->slice_offset == (slice->slice_count-1)*sizeof(mi_slice_t));\n        mi_assert_internal(last->slice_count == 0);\n        mi_assert_internal(last->block_size == 1);\n      }\n    }\n    else {  // free range of slices; only last slice needs a valid back offset\n      mi_slice_t* last = &segment->slices[maxindex];\n      if (segment->kind != MI_SEGMENT_HUGE || slice->slice_count <= (segment->slice_entries - segment->segment_info_slices)) {\n        mi_assert_internal((uint8_t*)slice == (uint8_t*)last - last->slice_offset);\n      }\n      mi_assert_internal(slice == last || last->slice_count == 0 );\n      mi_assert_internal(last->block_size == 0 || (segment->kind==MI_SEGMENT_HUGE && last->block_size==1));\n      if (segment->kind != MI_SEGMENT_HUGE && segment->thread_id != 0) { // segment is not huge or abandoned\n        sq = mi_span_queue_for(slice->slice_count,tld);\n        mi_assert_internal(mi_span_queue_contains(sq,slice));\n      }\n    }\n    slice = &segment->slices[maxindex+1];\n  }\n  mi_assert_internal(slice == end);\n  // [specbot S-NEW-5] Total slice counts must sum to segment_slices (L2, O(n))\n  mi_assert_internal(total_slice_count == segment->segment_slices);\n  mi_assert_internal(used_count == segment->used + 1);\n  return true;\n}\n#endif\n\n/* -----------------------------------------------------------\n Segment size calculations\n----------------------------------------------------------- */\n\nstatic size_t mi_segment_info_size(mi_segment_t* segment) {\n  return segment->segment_info_slices * MI_SEGMENT_SLICE_SIZE;\n}\n\nstatic uint8_t* _mi_segment_page_start_from_slice(const mi_segment_t* segment, const mi_slice_t* slice, size_t block_size, size_t* page_size)\n{\n  const ptrdiff_t idx = slice - segment->slices;\n  const size_t psize = (size_t)slice->slice_count * MI_SEGMENT_SLICE_SIZE;\n  uint8_t* const pstart = (uint8_t*)segment + (idx*MI_SEGMENT_SLICE_SIZE);\n  // make the start not OS page aligned for smaller blocks to avoid page/cache effects\n  // note: the offset must always be a block_size multiple since we assume small allocations\n  // are aligned (see `mi_heap_malloc_aligned`).\n  size_t start_offset = 0;\n  if (block_size > 0 && block_size <= MI_MAX_ALIGN_GUARANTEE) {\n    // for small objects, ensure the page start is aligned with the block size (PR#66 by kickunderscore)\n    const size_t adjust = block_size - ((uintptr_t)pstart % block_size);\n    if (adjust < block_size && psize >= block_size + adjust) {\n      start_offset += adjust;\n    }\n  }\n  if (block_size >= MI_INTPTR_SIZE) {\n    if (block_size <= 64) { start_offset += 3*block_size; }\n    else if (block_size <= 512) { start_offset += block_size; }\n  }\n  start_offset = _mi_align_up(start_offset, MI_MAX_ALIGN_SIZE);\n  mi_assert_internal(_mi_is_aligned(pstart + start_offset, MI_MAX_ALIGN_SIZE));\n  mi_assert_internal(block_size == 0 || block_size > MI_MAX_ALIGN_GUARANTEE || _mi_is_aligned(pstart + start_offset,block_size));\n  if (page_size != NULL) { *page_size = psize - start_offset; }\n  return (pstart + start_offset);\n}\n\n// Start of the page available memory; can be used on uninitialized pages\nuint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size)\n{\n  const mi_slice_t* slice = mi_page_to_slice((mi_page_t*)page);\n  uint8_t* p = _mi_segment_page_start_from_slice(segment, slice, mi_page_block_size(page), page_size);\n  mi_assert_internal(mi_page_block_size(page) > 0 || _mi_ptr_page(p) == page);\n  mi_assert_internal(_mi_ptr_segment(p) == segment);\n  return p;\n}\n\n\nstatic size_t mi_segment_calculate_slices(size_t required, size_t* info_slices) {\n  size_t page_size = _mi_os_page_size();\n  size_t isize     = _mi_align_up(sizeof(mi_segment_t), page_size);\n  size_t guardsize = 0;\n\n  if (MI_SECURE>0) {\n    // in secure mode, we set up a protected page in between the segment info\n    // and the page data (and one at the end of the segment)\n    guardsize = page_size;\n    if (required > 0) {\n      required = _mi_align_up(required, MI_SEGMENT_SLICE_SIZE) + page_size;\n    }\n  }\n\n  isize = _mi_align_up(isize + guardsize, MI_SEGMENT_SLICE_SIZE);\n  if (info_slices != NULL) *info_slices = isize / MI_SEGMENT_SLICE_SIZE;\n  size_t segment_size = (required==0 ? MI_SEGMENT_SIZE : _mi_align_up( required + isize + guardsize, MI_SEGMENT_SLICE_SIZE) );\n  mi_assert_internal(segment_size % MI_SEGMENT_SLICE_SIZE == 0);\n  return (segment_size / MI_SEGMENT_SLICE_SIZE);\n}\n\n\n/* ----------------------------------------------------------------------------\nSegment caches\nWe keep a small segment cache per thread to increase local\nreuse and avoid setting/clearing guard pages in secure mode.\n------------------------------------------------------------------------------- */\n\nstatic void mi_segments_track_size(long segment_size, mi_segments_tld_t* tld) {\n  if (segment_size>=0) _mi_stat_increase(&tld->stats->segments,1);\n                  else _mi_stat_decrease(&tld->stats->segments,1);\n  tld->count += (segment_size >= 0 ? 1 : -1);\n  if (tld->count > tld->peak_count) tld->peak_count = tld->count;\n  tld->current_size += segment_size;\n  if (tld->current_size > tld->peak_size) tld->peak_size = tld->current_size;\n}\n\nstatic void mi_segment_os_free(mi_segment_t* segment, mi_segments_tld_t* tld) {\n  segment->thread_id = 0;\n  _mi_segment_map_freed_at(segment);\n  mi_segments_track_size(-((long)mi_segment_size(segment)),tld);\n  if (segment->was_reclaimed) {\n    tld->reclaim_count--;\n    segment->was_reclaimed = false;\n  }\n  if (MI_SECURE>0) {\n    // _mi_os_unprotect(segment, mi_segment_size(segment)); // ensure no more guard pages are set\n    // unprotect the guard pages; we cannot just unprotect the whole segment size as part may be decommitted\n    size_t os_pagesize = _mi_os_page_size();\n    _mi_os_unprotect((uint8_t*)segment + mi_segment_info_size(segment) - os_pagesize, os_pagesize);\n    uint8_t* end = (uint8_t*)segment + mi_segment_size(segment) - os_pagesize;\n    _mi_os_unprotect(end, os_pagesize);\n  }\n\n  // purge delayed decommits now? (no, leave it to the arena)\n  // mi_segment_try_purge(segment,true,tld->stats);\n\n  const size_t size = mi_segment_size(segment);\n  const size_t csize = _mi_commit_mask_committed_size(&segment->commit_mask, size);\n\n  _mi_arena_free(segment, mi_segment_size(segment), csize, segment->memid);\n}\n\n/* -----------------------------------------------------------\n   Commit/Decommit ranges\n----------------------------------------------------------- */\n\nstatic void mi_segment_commit_mask(mi_segment_t* segment, bool conservative, uint8_t* p, size_t size, uint8_t** start_p, size_t* full_size, mi_commit_mask_t* cm) {\n  mi_assert_internal(_mi_ptr_segment(p + 1) == segment);\n  mi_assert_internal(segment->kind != MI_SEGMENT_HUGE);\n  mi_commit_mask_create_empty(cm);\n  if (size == 0 || size > MI_SEGMENT_SIZE || segment->kind == MI_SEGMENT_HUGE) return;\n  const size_t segstart = mi_segment_info_size(segment);\n  const size_t segsize = mi_segment_size(segment);\n  if (p >= (uint8_t*)segment + segsize) return;\n\n  size_t pstart = (p - (uint8_t*)segment);\n  mi_assert_internal(pstart + size <= segsize);\n\n  size_t start;\n  size_t end;\n  if (conservative) {\n    // decommit conservative\n    start = _mi_align_up(pstart, MI_COMMIT_SIZE);\n    end   = _mi_align_down(pstart + size, MI_COMMIT_SIZE);\n    mi_assert_internal(start >= segstart);\n    mi_assert_internal(end <= segsize);\n  }\n  else {\n    // commit liberal\n    start = _mi_align_down(pstart, MI_MINIMAL_COMMIT_SIZE);\n    end   = _mi_align_up(pstart + size, MI_MINIMAL_COMMIT_SIZE);\n  }\n  if (pstart >= segstart && start < segstart) {  // note: the mask is also calculated for an initial commit of the info area\n    start = segstart;\n  }\n  if (end > segsize) {\n    end = segsize;\n  }\n\n  mi_assert_internal(start <= pstart && (pstart + size) <= end);\n  mi_assert_internal(start % MI_COMMIT_SIZE==0 && end % MI_COMMIT_SIZE == 0);\n  *start_p   = (uint8_t*)segment + start;\n  *full_size = (end > start ? end - start : 0);\n  if (*full_size == 0) return;\n\n  size_t bitidx = start / MI_COMMIT_SIZE;\n  mi_assert_internal(bitidx < MI_COMMIT_MASK_BITS);\n\n  size_t bitcount = *full_size / MI_COMMIT_SIZE; // can be 0\n  if (bitidx + bitcount > MI_COMMIT_MASK_BITS) {\n    _mi_warning_message(\"commit mask overflow: idx=%zu count=%zu start=%zx end=%zx p=0x%p size=%zu fullsize=%zu\\n\", bitidx, bitcount, start, end, p, size, *full_size);\n  }\n  mi_assert_internal((bitidx + bitcount) <= MI_COMMIT_MASK_BITS);\n  mi_commit_mask_create(bitidx, bitcount, cm);\n}\n\nstatic bool mi_segment_commit(mi_segment_t* segment, uint8_t* p, size_t size) {\n  mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask));\n\n  // commit liberal\n  uint8_t* start = NULL;\n  size_t   full_size = 0;\n  mi_commit_mask_t mask;\n  mi_segment_commit_mask(segment, false /* conservative? */, p, size, &start, &full_size, &mask);\n  if (mi_commit_mask_is_empty(&mask) || full_size == 0) return true;\n\n  if (!mi_commit_mask_all_set(&segment->commit_mask, &mask)) {\n    // committing\n    bool is_zero = false;\n    mi_commit_mask_t cmask;\n    mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask);\n    _mi_stat_decrease(&_mi_stats_main.committed, _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for overlap\n    if (!_mi_os_commit(start, full_size, &is_zero)) return false;\n    mi_commit_mask_set(&segment->commit_mask, &mask);\n  }\n\n  // increase purge expiration when using part of delayed purges -- we assume more allocations are coming soon.\n  if (mi_commit_mask_any_set(&segment->purge_mask, &mask)) {\n    segment->purge_expire = _mi_clock_now() + mi_option_get(mi_option_purge_delay);\n  }\n\n  // always clear any delayed purges in our range (as they are either committed now)\n  mi_commit_mask_clear(&segment->purge_mask, &mask);\n  return true;\n}\n\nstatic bool mi_segment_ensure_committed(mi_segment_t* segment, uint8_t* p, size_t size) {\n  mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask));\n  // note: assumes commit_mask is always full for huge segments as otherwise the commit mask bits can overflow\n  if (mi_commit_mask_is_full(&segment->commit_mask) && mi_commit_mask_is_empty(&segment->purge_mask)) return true; // fully committed\n  mi_assert_internal(segment->kind != MI_SEGMENT_HUGE);\n  return mi_segment_commit(segment, p, size);\n}\n\nstatic bool mi_segment_purge(mi_segment_t* segment, uint8_t* p, size_t size) {\n  mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask));\n  if (!segment->allow_purge) return true;\n\n  // purge conservative\n  uint8_t* start = NULL;\n  size_t   full_size = 0;\n  mi_commit_mask_t mask;\n  mi_segment_commit_mask(segment, true /* conservative? */, p, size, &start, &full_size, &mask);\n  if (mi_commit_mask_is_empty(&mask) || full_size==0) return true;\n\n  if (mi_commit_mask_any_set(&segment->commit_mask, &mask)) {\n    // purging\n    mi_assert_internal((void*)start != (void*)segment);\n    mi_assert_internal(segment->allow_decommit);\n    const bool decommitted = _mi_os_purge(start, full_size);  // reset or decommit\n    if (decommitted) {\n      mi_commit_mask_t cmask;\n      mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask);\n      _mi_stat_increase(&_mi_stats_main.committed, full_size - _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for double counting\n      mi_commit_mask_clear(&segment->commit_mask, &mask);\n    }\n  }\n\n  // always clear any scheduled purges in our range\n  mi_commit_mask_clear(&segment->purge_mask, &mask);\n  return true;\n}\n\nstatic void mi_segment_schedule_purge(mi_segment_t* segment, uint8_t* p, size_t size) {\n  if (!segment->allow_purge) return;\n\n  if (mi_option_get(mi_option_purge_delay) == 0) {\n    mi_segment_purge(segment, p, size);\n  }\n  else {\n    // register for future purge in the purge mask\n    uint8_t* start = NULL;\n    size_t   full_size = 0;\n    mi_commit_mask_t mask;\n    mi_segment_commit_mask(segment, true /*conservative*/, p, size, &start, &full_size, &mask);\n    if (mi_commit_mask_is_empty(&mask) || full_size==0) return;\n\n    // update delayed commit\n    mi_assert_internal(segment->purge_expire > 0 || mi_commit_mask_is_empty(&segment->purge_mask));\n    mi_commit_mask_t cmask;\n    mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask);  // only purge what is committed; span_free may try to decommit more\n    mi_commit_mask_set(&segment->purge_mask, &cmask);\n    mi_msecs_t now = _mi_clock_now();\n    if (segment->purge_expire == 0) {\n      // no previous purgess, initialize now\n      segment->purge_expire = now + mi_option_get(mi_option_purge_delay);\n    }\n    else if (segment->purge_expire <= now) {\n      // previous purge mask already expired\n      if (segment->purge_expire + mi_option_get(mi_option_purge_extend_delay) <= now) {\n        mi_segment_try_purge(segment, true);\n      }\n      else {\n        segment->purge_expire = now + mi_option_get(mi_option_purge_extend_delay); // (mi_option_get(mi_option_purge_delay) / 8); // wait a tiny bit longer in case there is a series of free's\n      }\n    }\n    else {\n      // previous purge mask is not yet expired, increase the expiration by a bit.\n      segment->purge_expire += mi_option_get(mi_option_purge_extend_delay);\n    }\n  }\n}\n\nstatic void mi_segment_try_purge(mi_segment_t* segment, bool force) {\n  if (!segment->allow_purge || segment->purge_expire == 0 || mi_commit_mask_is_empty(&segment->purge_mask)) return;\n  mi_msecs_t now = _mi_clock_now();\n  if (!force && now < segment->purge_expire) return;\n\n  mi_commit_mask_t mask = segment->purge_mask;\n  segment->purge_expire = 0;\n  mi_commit_mask_create_empty(&segment->purge_mask);\n\n  size_t idx;\n  size_t count;\n  mi_commit_mask_foreach(&mask, idx, count) {\n    // if found, decommit that sequence\n    if (count > 0) {\n      uint8_t* p = (uint8_t*)segment + (idx*MI_COMMIT_SIZE);\n      size_t size = count * MI_COMMIT_SIZE;\n      mi_segment_purge(segment, p, size);\n    }\n  }\n  mi_commit_mask_foreach_end()\n  mi_assert_internal(mi_commit_mask_is_empty(&segment->purge_mask));\n}\n\n// called from `mi_heap_collect_ex`\n// this can be called per-page so it is important that try_purge has fast exit path\nvoid _mi_segment_collect(mi_segment_t* segment, bool force) {\n  mi_segment_try_purge(segment, force);\n}\n\n/* -----------------------------------------------------------\n   Span free\n----------------------------------------------------------- */\n\nstatic bool mi_segment_is_abandoned(mi_segment_t* segment) {\n  return (mi_atomic_load_relaxed(&segment->thread_id) == 0);\n}\n\n// note: can be called on abandoned segments\nstatic void mi_segment_span_free(mi_segment_t* segment, size_t slice_index, size_t slice_count, bool allow_purge, mi_segments_tld_t* tld) {\n  mi_assert_internal(slice_index < segment->slice_entries);\n  mi_span_queue_t* sq = (segment->kind == MI_SEGMENT_HUGE || mi_segment_is_abandoned(segment)\n                          ? NULL : mi_span_queue_for(slice_count,tld));\n  if (slice_count==0) slice_count = 1;\n  mi_assert_internal(slice_index + slice_count - 1 < segment->slice_entries);\n\n  // set first and last slice (the intermediates can be undetermined)\n  mi_slice_t* slice = &segment->slices[slice_index];\n  slice->slice_count = (uint32_t)slice_count;\n  mi_assert_internal(slice->slice_count == slice_count); // no overflow?\n  slice->slice_offset = 0;\n  if (slice_count > 1) {\n    mi_slice_t* last = slice + slice_count - 1;\n    mi_slice_t* end  = (mi_slice_t*)mi_segment_slices_end(segment);\n    if (last > end) { last = end; }\n    last->slice_count = 0;\n    last->slice_offset = (uint32_t)(sizeof(mi_page_t)*(slice_count - 1));\n    last->block_size = 0;\n  }\n\n  // perhaps decommit\n  if (allow_purge) {\n    mi_segment_schedule_purge(segment, mi_slice_start(slice), slice_count * MI_SEGMENT_SLICE_SIZE);\n  }\n\n  // and push it on the free page queue (if it was not a huge page)\n  if (sq != NULL) mi_span_queue_push( sq, slice );\n             else slice->block_size = 0; // mark huge page as free anyways\n}\n\n/*\n// called from reclaim to add existing free spans\nstatic void mi_segment_span_add_free(mi_slice_t* slice, mi_segments_tld_t* tld) {\n  mi_segment_t* segment = _mi_ptr_segment(slice);\n  mi_assert_internal(slice->xblock_size==0 && slice->slice_count>0 && slice->slice_offset==0);\n  size_t slice_index = mi_slice_index(slice);\n  mi_segment_span_free(segment,slice_index,slice->slice_count,tld);\n}\n*/\n\nstatic void mi_segment_span_remove_from_queue(mi_slice_t* slice, mi_segments_tld_t* tld) {\n  mi_assert_internal(slice->slice_count > 0 && slice->slice_offset==0 && slice->block_size==0);\n  mi_assert_internal(_mi_ptr_segment(slice)->kind != MI_SEGMENT_HUGE);\n  mi_span_queue_t* sq = mi_span_queue_for(slice->slice_count, tld);\n  mi_span_queue_delete(sq, slice);\n}\n\n// note: can be called on abandoned segments\nstatic mi_slice_t* mi_segment_span_free_coalesce(mi_slice_t* slice, mi_segments_tld_t* tld) {\n  mi_assert_internal(slice != NULL && slice->slice_count > 0 && slice->slice_offset == 0);\n  mi_segment_t* const segment = _mi_ptr_segment(slice);\n\n  // for huge pages, just mark as free but don't add to the queues\n  if (segment->kind == MI_SEGMENT_HUGE) {\n    // issue #691: segment->used can be 0 if the huge page block was freed while abandoned (reclaim will get here in that case)\n    mi_assert_internal((segment->used==0 && slice->block_size==0) || segment->used == 1);  // decreased right after this call in `mi_segment_page_clear`\n    slice->block_size = 0;  // mark as free anyways\n    // we should mark the last slice `xblock_size=0` now to maintain invariants but we skip it to\n    // avoid a possible cache miss (and the segment is about to be freed)\n    return slice;\n  }\n\n  // otherwise coalesce the span and add to the free span queues\n  const bool is_abandoned = mi_segment_is_abandoned(segment);\n  size_t slice_count = slice->slice_count;\n  mi_slice_t* next = slice + slice->slice_count;\n  mi_assert_internal(next <= mi_segment_slices_end(segment));\n  if (next < mi_segment_slices_end(segment) && next->block_size==0) {\n    // free next block -- remove it from free and merge\n    mi_assert_internal(next->slice_count > 0 && next->slice_offset==0);\n    slice_count += next->slice_count; // extend\n    if (!is_abandoned) { mi_segment_span_remove_from_queue(next, tld); }\n  }\n  if (slice > segment->slices) {\n    mi_slice_t* prev = mi_slice_first(slice - 1);\n    mi_assert_internal(prev >= segment->slices);\n    if (prev->block_size==0) {\n      // free previous slice -- remove it from free and merge\n      mi_assert_internal(prev->slice_count > 0 && prev->slice_offset==0);\n      slice_count += prev->slice_count;\n      slice->slice_count = 0;\n      slice->slice_offset = (uint32_t)((uint8_t*)slice - (uint8_t*)prev); // set the slice offset for `segment_force_abandon` (in case the previous free block is very large).\n      if (!is_abandoned) { mi_segment_span_remove_from_queue(prev, tld); }\n      slice = prev;\n    }\n  }\n\n  // and add the new free page\n  mi_segment_span_free(segment, mi_slice_index(slice), slice_count, true, tld);\n  return slice;\n}\n\n\n\n/* -----------------------------------------------------------\n   Page allocation\n----------------------------------------------------------- */\n\n// Note: may still return NULL if committing the memory failed\nstatic mi_page_t* mi_segment_span_allocate(mi_segment_t* segment, size_t slice_index, size_t slice_count) {\n  mi_assert_internal(slice_index < segment->slice_entries);\n  mi_slice_t* const slice = &segment->slices[slice_index];\n  mi_assert_internal(slice->block_size==0 || slice->block_size==1);\n\n  // commit before changing the slice data\n  if (!mi_segment_ensure_committed(segment, _mi_segment_page_start_from_slice(segment, slice, 0, NULL), slice_count * MI_SEGMENT_SLICE_SIZE)) {\n    return NULL;  // commit failed!\n  }\n\n  // convert the slices to a page\n  slice->slice_offset = 0;\n  slice->slice_count = (uint32_t)slice_count;\n  mi_assert_internal(slice->slice_count == slice_count);\n  const size_t bsize = slice_count * MI_SEGMENT_SLICE_SIZE;\n  slice->block_size = bsize;\n  mi_page_t*  page = mi_slice_to_page(slice);\n  mi_assert_internal(mi_page_block_size(page) == bsize);\n\n  // set slice back pointers for the first MI_MAX_SLICE_OFFSET_COUNT entries\n  size_t extra = slice_count-1;\n  if (extra > MI_MAX_SLICE_OFFSET_COUNT) extra = MI_MAX_SLICE_OFFSET_COUNT;\n  if (slice_index + extra >= segment->slice_entries) extra = segment->slice_entries - slice_index - 1;  // huge objects may have more slices than avaiable entries in the segment->slices\n\n  mi_slice_t* slice_next = slice + 1;\n  for (size_t i = 1; i <= extra; i++, slice_next++) {\n    slice_next->slice_offset = (uint32_t)(sizeof(mi_slice_t)*i);\n    slice_next->slice_count = 0;\n    slice_next->block_size = 1;\n  }\n\n  // and also for the last one (if not set already) (the last one is needed for coalescing and for large alignments)\n  // note: the cast is needed for ubsan since the index can be larger than MI_SLICES_PER_SEGMENT for huge allocations (see #543)\n  mi_slice_t* last = slice + slice_count - 1;\n  mi_slice_t* end = (mi_slice_t*)mi_segment_slices_end(segment);\n  if (last > end) last = end;\n  if (last > slice) {\n    last->slice_offset = (uint32_t)(sizeof(mi_slice_t) * (last - slice));\n    last->slice_count = 0;\n    last->block_size = 1;\n  }\n\n  // and initialize the page\n  page->is_committed = true;\n  page->is_zero_init = segment->free_is_zero;\n  page->is_huge = (segment->kind == MI_SEGMENT_HUGE);\n  segment->used++;\n  return page;\n}\n\nstatic void mi_segment_slice_split(mi_segment_t* segment, mi_slice_t* slice, size_t slice_count, mi_segments_tld_t* tld) {\n  mi_assert_internal(_mi_ptr_segment(slice) == segment);\n  mi_assert_internal(slice->slice_count >= slice_count);\n  mi_assert_internal(slice->block_size > 0); // no more in free queue\n  if (slice->slice_count <= slice_count) return;\n  mi_assert_internal(segment->kind != MI_SEGMENT_HUGE);\n  size_t next_index = mi_slice_index(slice) + slice_count;\n  size_t next_count = slice->slice_count - slice_count;\n  mi_segment_span_free(segment, next_index, next_count, false /* don't purge left-over part */, tld);\n  slice->slice_count = (uint32_t)slice_count;\n}\n\nstatic mi_page_t* mi_segments_page_find_and_allocate(size_t slice_count, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld) {\n  mi_assert_internal(slice_count*MI_SEGMENT_SLICE_SIZE <= MI_LARGE_OBJ_SIZE_MAX);\n  // search from best fit up\n  mi_span_queue_t* sq = mi_span_queue_for(slice_count, tld);\n  if (slice_count == 0) slice_count = 1;\n  while (sq <= &tld->spans[MI_SEGMENT_BIN_MAX]) {\n    for (mi_slice_t* slice = sq->first; slice != NULL; slice = slice->next) {\n      if (slice->slice_count >= slice_count) {\n        // found one\n        mi_segment_t* segment = _mi_ptr_segment(slice);\n        if (_mi_arena_memid_is_suitable(segment->memid, req_arena_id)) {\n          // found a suitable page span\n          mi_span_queue_delete(sq, slice);\n\n          if (slice->slice_count > slice_count) {\n            mi_segment_slice_split(segment, slice, slice_count, tld);\n          }\n          mi_assert_internal(slice != NULL && slice->slice_count == slice_count && slice->block_size > 0);\n          mi_page_t* page = mi_segment_span_allocate(segment, mi_slice_index(slice), slice->slice_count);\n          if (page == NULL) {\n            // commit failed; return NULL but first restore the slice\n            mi_segment_span_free_coalesce(slice, tld);\n            return NULL;\n          }\n          return page;\n        }\n      }\n    }\n    sq++;\n  }\n  // could not find a page..\n  return NULL;\n}\n\n\n/* -----------------------------------------------------------\n   Segment allocation\n----------------------------------------------------------- */\n\nstatic mi_segment_t* mi_segment_os_alloc( size_t required, size_t page_alignment, bool eager_delayed, mi_arena_id_t req_arena_id,\n                                          size_t* psegment_slices, size_t* pinfo_slices,\n                                          bool commit, mi_segments_tld_t* tld)\n\n{\n  mi_memid_t memid;\n  bool   allow_large = (!eager_delayed && (MI_SECURE == 0)); // only allow large OS pages once we are no longer lazy\n  size_t align_offset = 0;\n  size_t alignment = MI_SEGMENT_ALIGN;\n\n  if (page_alignment > 0) {\n    // mi_assert_internal(huge_page != NULL);\n    mi_assert_internal(page_alignment >= MI_SEGMENT_ALIGN);\n    alignment = page_alignment;\n    const size_t info_size = (*pinfo_slices) * MI_SEGMENT_SLICE_SIZE;\n    align_offset = _mi_align_up( info_size, MI_SEGMENT_ALIGN );\n    const size_t extra = align_offset - info_size;\n    // recalculate due to potential guard pages\n    *psegment_slices = mi_segment_calculate_slices(required + extra, pinfo_slices);\n    mi_assert_internal(*psegment_slices > 0 && *psegment_slices <= UINT32_MAX);\n  }\n\n  const size_t segment_size = (*psegment_slices) * MI_SEGMENT_SLICE_SIZE;\n  mi_segment_t* segment = (mi_segment_t*)_mi_arena_alloc_aligned(segment_size, alignment, align_offset, commit, allow_large, req_arena_id, &memid);\n  if (segment == NULL) {\n    return NULL;  // failed to allocate\n  }\n\n  // ensure metadata part of the segment is committed\n  mi_commit_mask_t commit_mask;\n  if (memid.initially_committed) {\n    mi_commit_mask_create_full(&commit_mask);\n  }\n  else {\n    // at least commit the info slices\n    const size_t commit_needed = _mi_divide_up((*pinfo_slices)*MI_SEGMENT_SLICE_SIZE, MI_COMMIT_SIZE);\n    mi_assert_internal(commit_needed>0);\n    mi_commit_mask_create(0, commit_needed, &commit_mask);\n    mi_assert_internal(commit_needed*MI_COMMIT_SIZE >= (*pinfo_slices)*MI_SEGMENT_SLICE_SIZE);\n    if (!_mi_os_commit(segment, commit_needed*MI_COMMIT_SIZE, NULL)) {\n      _mi_arena_free(segment,segment_size,0,memid);\n      return NULL;\n    }\n  }\n  mi_assert_internal(segment != NULL && (uintptr_t)segment % MI_SEGMENT_SIZE == 0);\n\n  segment->memid = memid;\n  segment->allow_decommit = !memid.is_pinned;\n  segment->allow_purge = segment->allow_decommit && (mi_option_get(mi_option_purge_delay) >= 0);\n  segment->segment_size = segment_size;\n  segment->subproc = tld->subproc;\n  segment->commit_mask = commit_mask;\n  segment->purge_expire = 0;\n  segment->free_is_zero = memid.initially_zero;\n  mi_commit_mask_create_empty(&segment->purge_mask);\n\n  mi_segments_track_size((long)(segment_size), tld);\n  _mi_segment_map_allocated_at(segment);\n  return segment;\n}\n\n\n// Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` .\nstatic mi_segment_t* mi_segment_alloc(size_t required, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld, mi_page_t** huge_page)\n{\n  mi_assert_internal((required==0 && huge_page==NULL) || (required>0 && huge_page != NULL));\n\n  // calculate needed sizes first\n  size_t info_slices;\n  size_t segment_slices = mi_segment_calculate_slices(required, &info_slices);\n  mi_assert_internal(segment_slices > 0 && segment_slices <= UINT32_MAX);\n\n  // Commit eagerly only if not the first N lazy segments (to reduce impact of many threads that allocate just a little)\n  const bool eager_delay = (// !_mi_os_has_overcommit() &&             // never delay on overcommit systems\n                            _mi_current_thread_count() > 1 &&       // do not delay for the first N threads\n                            tld->peak_count < (size_t)mi_option_get(mi_option_eager_commit_delay));\n  const bool eager = !eager_delay && mi_option_is_enabled(mi_option_eager_commit);\n  bool commit = eager || (required > 0);\n\n  // Allocate the segment from the OS\n  mi_segment_t* segment = mi_segment_os_alloc(required, page_alignment, eager_delay, req_arena_id,\n                                              &segment_slices, &info_slices, commit, tld);\n  if (segment == NULL) return NULL;\n\n  // zero the segment info? -- not always needed as it may be zero initialized from the OS\n  if (!segment->memid.initially_zero) {\n    ptrdiff_t ofs    = offsetof(mi_segment_t, next);\n    size_t    prefix = offsetof(mi_segment_t, slices) - ofs;\n    size_t    zsize  = prefix + (sizeof(mi_slice_t) * (segment_slices + 1)); // one more\n    _mi_memzero((uint8_t*)segment + ofs, zsize);\n  }\n\n  // initialize the rest of the segment info\n  const size_t slice_entries = (segment_slices > MI_SLICES_PER_SEGMENT ? MI_SLICES_PER_SEGMENT : segment_slices);\n  segment->segment_slices = segment_slices;\n  segment->segment_info_slices = info_slices;\n  segment->thread_id = _mi_thread_id();\n  segment->cookie = _mi_ptr_cookie(segment);\n  segment->slice_entries = slice_entries;\n  segment->kind = (required == 0 ? MI_SEGMENT_NORMAL : MI_SEGMENT_HUGE);\n\n  // _mi_memzero(segment->slices, sizeof(mi_slice_t)*(info_slices+1));\n  _mi_stat_increase(&tld->stats->page_committed, mi_segment_info_size(segment));\n\n  // set up guard pages\n  size_t guard_slices = 0;\n  if (MI_SECURE>0) {\n    // in secure mode, we set up a protected page in between the segment info\n    // and the page data, and at the end of the segment.\n    size_t os_pagesize = _mi_os_page_size();\n    _mi_os_protect((uint8_t*)segment + mi_segment_info_size(segment) - os_pagesize, os_pagesize);\n    uint8_t* end = (uint8_t*)segment + mi_segment_size(segment) - os_pagesize;\n    mi_segment_ensure_committed(segment, end, os_pagesize);\n    _mi_os_protect(end, os_pagesize);\n    if (slice_entries == segment_slices) segment->slice_entries--; // don't use the last slice :-(\n    guard_slices = 1;\n  }\n\n  // reserve first slices for segment info\n  mi_page_t* page0 = mi_segment_span_allocate(segment, 0, info_slices);\n  mi_assert_internal(page0!=NULL); if (page0==NULL) return NULL; // cannot fail as we always commit in advance\n  mi_assert_internal(segment->used == 1);\n  segment->used = 0; // don't count our internal slices towards usage\n\n  // initialize initial free pages\n  if (segment->kind == MI_SEGMENT_NORMAL) { // not a huge page\n    mi_assert_internal(huge_page==NULL);\n    mi_segment_span_free(segment, info_slices, segment->slice_entries - info_slices, false /* don't purge */, tld);\n  }\n  else {\n    mi_assert_internal(huge_page!=NULL);\n    mi_assert_internal(mi_commit_mask_is_empty(&segment->purge_mask));\n    mi_assert_internal(mi_commit_mask_is_full(&segment->commit_mask));\n    *huge_page = mi_segment_span_allocate(segment, info_slices, segment_slices - info_slices - guard_slices);\n    mi_assert_internal(*huge_page != NULL); // cannot fail as we commit in advance\n  }\n\n  mi_assert_expensive(mi_segment_is_valid(segment,tld));\n  return segment;\n}\n\n\nstatic void mi_segment_free(mi_segment_t* segment, bool force, mi_segments_tld_t* tld) {\n  MI_UNUSED(force);\n  mi_assert_internal(segment != NULL);\n  mi_assert_internal(segment->next == NULL);\n  mi_assert_internal(segment->used == 0);\n\n  // in `mi_segment_force_abandon` we set this to true to ensure the segment's memory stays valid\n  if (segment->dont_free) return;\n\n  // Remove the free pages\n  mi_slice_t* slice = &segment->slices[0];\n  const mi_slice_t* end = mi_segment_slices_end(segment);\n  #if MI_DEBUG>1\n  size_t page_count = 0;\n  #endif\n  while (slice < end) {\n    mi_assert_internal(slice->slice_count > 0);\n    mi_assert_internal(slice->slice_offset == 0);\n    mi_assert_internal(mi_slice_index(slice)==0 || slice->block_size == 0); // no more used pages ..\n    if (slice->block_size == 0 && segment->kind != MI_SEGMENT_HUGE) {\n      mi_segment_span_remove_from_queue(slice, tld);\n    }\n    #if MI_DEBUG>1\n    page_count++;\n    #endif\n    slice = slice + slice->slice_count;\n  }\n  mi_assert_internal(page_count == 2); // first page is allocated by the segment itself\n\n  // stats\n  // _mi_stat_decrease(&tld->stats->page_committed, mi_segment_info_size(segment));\n\n  // return it to the OS\n  mi_segment_os_free(segment, tld);\n}\n\n\n/* -----------------------------------------------------------\n   Page Free\n----------------------------------------------------------- */\n\nstatic void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld);\n\n// note: can be called on abandoned pages\nstatic mi_slice_t* mi_segment_page_clear(mi_page_t* page, mi_segments_tld_t* tld) {\n  mi_assert_internal(page->block_size > 0);\n  mi_assert_internal(mi_page_all_free(page));\n  mi_segment_t* segment = _mi_ptr_segment(page);\n  mi_assert_internal(segment->used > 0);\n\n  size_t inuse = page->capacity * mi_page_block_size(page);\n  _mi_stat_decrease(&tld->stats->page_committed, inuse);\n  _mi_stat_decrease(&tld->stats->pages, 1);\n  _mi_stat_decrease(&tld->stats->page_bins[_mi_page_stats_bin(page)], 1);\n  \n  // reset the page memory to reduce memory pressure?\n  if (segment->allow_decommit && mi_option_is_enabled(mi_option_deprecated_page_reset)) {\n    size_t psize;\n    uint8_t* start = _mi_segment_page_start(segment, page, &psize);\n    _mi_os_reset(start, psize);\n  }\n\n  // zero the page data, but not the segment fields and heap tag\n  page->is_zero_init = false;\n  uint8_t heap_tag = page->heap_tag;\n  ptrdiff_t ofs = offsetof(mi_page_t, capacity);\n  _mi_memzero((uint8_t*)page + ofs, sizeof(*page) - ofs);\n  page->block_size = 1;\n  page->heap_tag = heap_tag;\n\n  // and free it\n  mi_slice_t* slice = mi_segment_span_free_coalesce(mi_page_to_slice(page), tld);\n  segment->used--;\n  segment->free_is_zero = false;\n\n  // cannot assert segment valid as it is called during reclaim\n  // mi_assert_expensive(mi_segment_is_valid(segment, tld));\n  return slice;\n}\n\nvoid _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld)\n{\n  mi_assert(page != NULL);\n  mi_segment_t* segment = _mi_page_segment(page);\n  mi_assert_expensive(mi_segment_is_valid(segment,tld));\n\n  // mark it as free now\n  mi_segment_page_clear(page, tld);\n  mi_assert_expensive(mi_segment_is_valid(segment, tld));\n\n  if (segment->used == 0) {\n    // no more used pages; remove from the free list and free the segment\n    mi_segment_free(segment, force, tld);\n  }\n  else if (segment->used == segment->abandoned) {\n    // only abandoned pages; remove from free list and abandon\n    mi_segment_abandon(segment,tld);\n  }\n  else {\n    // perform delayed purges\n    mi_segment_try_purge(segment, false /* force? */);\n  }\n}\n\n\n/* -----------------------------------------------------------\nAbandonment\n\nWhen threads terminate, they can leave segments with\nlive blocks (reachable through other threads). Such segments\nare \"abandoned\" and will be reclaimed by other threads to\nreuse their pages and/or free them eventually. The\n`thread_id` of such segments is 0.\n\nWhen a block is freed in an abandoned segment, the segment\nis reclaimed into that thread.\n\nMoreover, if threads are looking for a fresh segment, they\nwill first consider abandoned segments -- these can be found\nby scanning the arena memory\n(segments outside arena memoryare only reclaimed by a free).\n----------------------------------------------------------- */\n\n/* -----------------------------------------------------------\n   Abandon segment/page\n----------------------------------------------------------- */\n\nstatic void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld) {\n  mi_assert_internal(segment->used == segment->abandoned);\n  mi_assert_internal(segment->used > 0);\n  mi_assert_internal(segment->abandoned_visits == 0);\n  mi_assert_expensive(mi_segment_is_valid(segment,tld));\n\n  // remove the free pages from the free page queues\n  mi_slice_t* slice = &segment->slices[0];\n  const mi_slice_t* end = mi_segment_slices_end(segment);\n  while (slice < end) {\n    mi_assert_internal(slice->slice_count > 0);\n    mi_assert_internal(slice->slice_offset == 0);\n    if (slice->block_size == 0) { // a free page\n      mi_segment_span_remove_from_queue(slice,tld);\n      slice->block_size = 0; // but keep it free\n    }\n    slice = slice + slice->slice_count;\n  }\n\n  // perform delayed decommits (forcing is much slower on mstress)\n  // Only abandoned segments in arena memory can be reclaimed without a free\n  // so if a segment is not from an arena we force purge here to be conservative.\n  const bool force_purge = (segment->memid.memkind != MI_MEM_ARENA) || mi_option_is_enabled(mi_option_abandoned_page_purge);\n  mi_segment_try_purge(segment, force_purge);\n\n  // all pages in the segment are abandoned; add it to the abandoned list\n  _mi_stat_increase(&tld->stats->segments_abandoned, 1);\n  mi_segments_track_size(-((long)mi_segment_size(segment)), tld);\n  segment->thread_id = 0;\n  segment->abandoned_visits = 1;   // from 0 to 1 to signify it is abandoned\n  if (segment->was_reclaimed) {\n    tld->reclaim_count--;\n    segment->was_reclaimed = false;\n  }\n  _mi_arena_segment_mark_abandoned(segment);\n}\n\nvoid _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld) {\n  mi_assert(page != NULL);\n  mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE);\n  mi_assert_internal(mi_page_heap(page) == NULL);\n  mi_segment_t* segment = _mi_page_segment(page);\n\n  mi_assert_expensive(mi_segment_is_valid(segment,tld));\n  segment->abandoned++;\n\n  _mi_stat_increase(&tld->stats->pages_abandoned, 1);\n  mi_assert_internal(segment->abandoned <= segment->used);\n  if (segment->used == segment->abandoned) {\n    // all pages are abandoned, abandon the entire segment\n    mi_segment_abandon(segment, tld);\n  }\n}\n\n/* -----------------------------------------------------------\n  Reclaim abandoned pages\n----------------------------------------------------------- */\n\nstatic mi_slice_t* mi_slices_start_iterate(mi_segment_t* segment, const mi_slice_t** end) {\n  mi_slice_t* slice = &segment->slices[0];\n  *end = mi_segment_slices_end(segment);\n  mi_assert_internal(slice->slice_count>0 && slice->block_size>0); // segment allocated page\n  slice = slice + slice->slice_count; // skip the first segment allocated page\n  return slice;\n}\n\n// Possibly free pages and check if free space is available\nstatic bool mi_segment_check_free(mi_segment_t* segment, size_t slices_needed, size_t block_size, mi_segments_tld_t* tld)\n{\n  mi_assert_internal(mi_segment_is_abandoned(segment));\n  bool has_page = false;\n\n  // for all slices\n  const mi_slice_t* end;\n  mi_slice_t* slice = mi_slices_start_iterate(segment, &end);\n  while (slice < end) {\n    mi_assert_internal(slice->slice_count > 0);\n    mi_assert_internal(slice->slice_offset == 0);\n    if (mi_slice_is_used(slice)) { // used page\n      // ensure used count is up to date and collect potential concurrent frees\n      mi_page_t* const page = mi_slice_to_page(slice);\n      _mi_page_free_collect(page, false);\n      if (mi_page_all_free(page)) {\n        // if this page is all free now, free it without adding to any queues (yet)\n        mi_assert_internal(page->next == NULL && page->prev==NULL);\n        _mi_stat_decrease(&tld->stats->pages_abandoned, 1);\n        segment->abandoned--;\n        slice = mi_segment_page_clear(page, tld); // re-assign slice due to coalesce!\n        mi_assert_internal(!mi_slice_is_used(slice));\n        if (slice->slice_count >= slices_needed) {\n          has_page = true;\n        }\n      }\n      else if (mi_page_block_size(page) == block_size && mi_page_has_any_available(page)) {\n        // a page has available free blocks of the right size\n        has_page = true;\n      }\n    }\n    else {\n      // empty span\n      if (slice->slice_count >= slices_needed) {\n        has_page = true;\n      }\n    }\n    slice = slice + slice->slice_count;\n  }\n  return has_page;\n}\n\n// Reclaim an abandoned segment; returns NULL if the segment was freed\n// set `right_page_reclaimed` to `true` if it reclaimed a page of the right `block_size` that was not full.\nstatic mi_segment_t* mi_segment_reclaim(mi_segment_t* segment, mi_heap_t* heap, size_t requested_block_size, bool* right_page_reclaimed, mi_segments_tld_t* tld) {\n  if (right_page_reclaimed != NULL) { *right_page_reclaimed = false; }\n  // can be 0 still with abandoned_next, or already a thread id for segments outside an arena that are reclaimed on a free.\n  mi_assert_internal(mi_atomic_load_relaxed(&segment->thread_id) == 0 || mi_atomic_load_relaxed(&segment->thread_id) == _mi_thread_id());\n  mi_assert_internal(segment->subproc == heap->tld->segments.subproc); // only reclaim within the same subprocess\n  mi_atomic_store_release(&segment->thread_id, _mi_thread_id());\n  segment->abandoned_visits = 0;\n  segment->was_reclaimed = true;\n  tld->reclaim_count++;\n  mi_segments_track_size((long)mi_segment_size(segment), tld);\n  mi_assert_internal(segment->next == NULL);\n  _mi_stat_decrease(&tld->stats->segments_abandoned, 1);\n\n  // for all slices\n  const mi_slice_t* end;\n  mi_slice_t* slice = mi_slices_start_iterate(segment, &end);\n  while (slice < end) {\n    mi_assert_internal(slice->slice_count > 0);\n    mi_assert_internal(slice->slice_offset == 0);\n    if (mi_slice_is_used(slice)) {\n      // in use: reclaim the page in our heap\n      mi_page_t* page = mi_slice_to_page(slice);\n      mi_assert_internal(page->is_committed);\n      mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE);\n      mi_assert_internal(mi_page_heap(page) == NULL);\n      mi_assert_internal(page->next == NULL && page->prev==NULL);\n      _mi_stat_decrease(&tld->stats->pages_abandoned, 1);\n      segment->abandoned--;\n      // get the target heap for this thread which has a matching heap tag (so we reclaim into a matching heap)\n      mi_heap_t* target_heap = _mi_heap_by_tag(heap, page->heap_tag);  // allow custom heaps to separate objects\n      if (target_heap == NULL) {\n        target_heap = heap;\n        _mi_error_message(EFAULT, \"page with tag %u cannot be reclaimed by a heap with the same tag (using heap tag %u instead)\\n\", page->heap_tag, heap->tag );\n      }\n      // associate the heap with this page, and allow heap thread delayed free again.\n      mi_page_set_heap(page, target_heap);\n      _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, true); // override never (after heap is set)\n      _mi_page_free_collect(page, false); // ensure used count is up to date\n      if (mi_page_all_free(page)) {\n        // if everything free by now, free the page\n        slice = mi_segment_page_clear(page, tld);   // set slice again due to coalesceing\n      }\n      else {\n        // otherwise reclaim it into the heap\n        _mi_page_reclaim(target_heap, page);\n        if (requested_block_size == mi_page_block_size(page) && mi_page_has_any_available(page) && heap == target_heap) {\n          if (right_page_reclaimed != NULL) { *right_page_reclaimed = true; }\n        }\n      }\n    }\n    else {\n      // the span is free, add it to our page queues\n      slice = mi_segment_span_free_coalesce(slice, tld); // set slice again due to coalesceing\n    }\n    mi_assert_internal(slice->slice_count>0 && slice->slice_offset==0);\n    slice = slice + slice->slice_count;\n  }\n\n  mi_assert(segment->abandoned == 0);\n  mi_assert_expensive(mi_segment_is_valid(segment, tld));\n  if (segment->used == 0) {  // due to page_clear\n    mi_assert_internal(right_page_reclaimed == NULL || !(*right_page_reclaimed));\n    mi_segment_free(segment, false, tld);\n    return NULL;\n  }\n  else {\n    return segment;\n  }\n}\n\n\n// attempt to reclaim a particular segment (called from multi threaded free `alloc.c:mi_free_block_mt`)\nbool _mi_segment_attempt_reclaim(mi_heap_t* heap, mi_segment_t* segment) {\n  if (mi_atomic_load_relaxed(&segment->thread_id) != 0) return false;  // it is not abandoned\n  if (segment->subproc != heap->tld->segments.subproc)  return false;  // only reclaim within the same subprocess\n  if (!_mi_heap_memid_is_suitable(heap,segment->memid)) return false;  // don't reclaim between exclusive and non-exclusive arena's\n  const long target = _mi_option_get_fast(mi_option_target_segments_per_thread);\n  if (target > 0 && (size_t)target <= heap->tld->segments.count) return false; // don't reclaim if going above the target count\n\n  // don't reclaim more from a `free` call than half the current segments\n  // this is to prevent a pure free-ing thread to start owning too many segments\n  // (but not for out-of-arena segments as that is the main way to be reclaimed for those)\n  if (segment->memid.memkind == MI_MEM_ARENA && heap->tld->segments.reclaim_count * 2 > heap->tld->segments.count) {\n    return false;\n  }\n  if (_mi_arena_segment_clear_abandoned(segment)) {  // atomically unabandon\n    mi_segment_t* res = mi_segment_reclaim(segment, heap, 0, NULL, &heap->tld->segments);\n    mi_assert_internal(res == segment);\n    return (res != NULL);\n  }\n  return false;\n}\n\nvoid _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld) {\n  mi_segment_t* segment;\n  mi_arena_field_cursor_t current;\n  _mi_arena_field_cursor_init(heap, tld->subproc, true /* visit all, blocking */, &current);\n  while ((segment = _mi_arena_segment_clear_abandoned_next(&current)) != NULL) {\n    mi_segment_reclaim(segment, heap, 0, NULL, tld);\n  }\n  _mi_arena_field_cursor_done(&current);\n}\n\n\nstatic bool segment_count_is_within_target(mi_segments_tld_t* tld, size_t* ptarget) {\n  const size_t target = (size_t)mi_option_get_clamp(mi_option_target_segments_per_thread, 0, 1024);\n  if (ptarget != NULL) { *ptarget = target; }\n  return (target == 0 || tld->count < target);\n}\n\nstatic long mi_segment_get_reclaim_tries(mi_segments_tld_t* tld) {\n  // limit the tries to 10% (default) of the abandoned segments with at least 8 and at most 1024 tries.\n  const size_t perc = (size_t)mi_option_get_clamp(mi_option_max_segment_reclaim, 0, 100);\n  if (perc <= 0) return 0;\n  const size_t total_count = mi_atomic_load_relaxed(&tld->subproc->abandoned_count);\n  if (total_count == 0) return 0;\n  const size_t relative_count = (total_count > 10000 ? (total_count / 100) * perc : (total_count * perc) / 100); // avoid overflow\n  long max_tries = (long)(relative_count <= 1 ? 1 : (relative_count > 1024 ? 1024 : relative_count));\n  if (max_tries < 8 && total_count > 8) { max_tries = 8;  }\n  return max_tries;\n}\n\nstatic mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t needed_slices, size_t block_size, bool* reclaimed, mi_segments_tld_t* tld)\n{\n  *reclaimed = false;\n  long max_tries = mi_segment_get_reclaim_tries(tld);\n  if (max_tries <= 0) return NULL;\n\n  mi_segment_t* result = NULL;\n  mi_segment_t* segment = NULL;\n  mi_arena_field_cursor_t current;\n  _mi_arena_field_cursor_init(heap, tld->subproc, false /* non-blocking */, &current);\n  while (segment_count_is_within_target(tld,NULL) && (max_tries-- > 0) && ((segment = _mi_arena_segment_clear_abandoned_next(&current)) != NULL))\n  {\n    mi_assert(segment->subproc == heap->tld->segments.subproc); // cursor only visits segments in our sub-process\n    segment->abandoned_visits++;\n    // todo: should we respect numa affinity for abandoned reclaim? perhaps only for the first visit?\n    // todo: an arena exclusive heap will potentially visit many abandoned unsuitable segments and use many tries\n    // Perhaps we can skip non-suitable ones in a better way?\n    bool is_suitable = _mi_heap_memid_is_suitable(heap, segment->memid);\n    bool has_page = mi_segment_check_free(segment,needed_slices,block_size,tld); // try to free up pages (due to concurrent frees)\n    if (segment->used == 0) {\n      // free the segment (by forced reclaim) to make it available to other threads.\n      // note1: we prefer to free a segment as that might lead to reclaiming another\n      // segment that is still partially used.\n      // note2: we could in principle optimize this by skipping reclaim and directly\n      // freeing but that would violate some invariants temporarily)\n      mi_segment_reclaim(segment, heap, 0, NULL, tld);\n    }\n    else if (has_page && is_suitable) {\n      // found a large enough free span, or a page of the right block_size with free space\n      // we return the result of reclaim (which is usually `segment`) as it might free\n      // the segment due to concurrent frees (in which case `NULL` is returned).\n      result = mi_segment_reclaim(segment, heap, block_size, reclaimed, tld);\n      break;\n    }\n    else if (segment->abandoned_visits > 3 && is_suitable) {\n      // always reclaim on 3rd visit to limit the abandoned segment count.\n      mi_segment_reclaim(segment, heap, 0, NULL, tld);\n    }\n    else {\n      // otherwise, push on the visited list so it gets not looked at too quickly again\n      max_tries++; // don't count this as a try since it was not suitable\n      mi_segment_try_purge(segment, false /* true force? */); // force purge if needed as we may not visit soon again\n      _mi_arena_segment_mark_abandoned(segment);\n    }\n  }\n  _mi_arena_field_cursor_done(&current);\n  return result;\n}\n\n// collect abandoned segments\nvoid _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld)\n{\n  mi_segment_t* segment;\n  mi_arena_field_cursor_t current; _mi_arena_field_cursor_init(heap, tld->subproc, force /* blocking? */, &current);\n  long max_tries = (force ? (long)mi_atomic_load_relaxed(&tld->subproc->abandoned_count) : 1024);  // limit latency\n  while ((max_tries-- > 0) && ((segment = _mi_arena_segment_clear_abandoned_next(&current)) != NULL)) {\n    mi_segment_check_free(segment,0,0,tld); // try to free up pages (due to concurrent frees)\n    if (segment->used == 0) {\n      // free the segment (by forced reclaim) to make it available to other threads.\n      // note: we could in principle optimize this by skipping reclaim and directly\n      // freeing but that would violate some invariants temporarily)\n      mi_segment_reclaim(segment, heap, 0, NULL, tld);\n    }\n    else {\n      // otherwise, purge if needed and push on the visited list\n      // note: forced purge can be expensive if many threads are destroyed/created as in mstress.\n      mi_segment_try_purge(segment, force);\n      _mi_arena_segment_mark_abandoned(segment);\n    }\n  }\n  _mi_arena_field_cursor_done(&current);\n}\n\n/* -----------------------------------------------------------\n   Force abandon a segment that is in use by our thread\n----------------------------------------------------------- */\n\n// force abandon a segment\nstatic void mi_segment_force_abandon(mi_segment_t* segment, mi_segments_tld_t* tld)\n{\n  mi_assert_internal(!mi_segment_is_abandoned(segment));\n  mi_assert_internal(!segment->dont_free);\n\n  // ensure the segment does not get free'd underneath us (so we can check if a page has been freed in `mi_page_force_abandon`)\n  segment->dont_free = true;\n\n  // for all slices\n  const mi_slice_t* end;\n  mi_slice_t* slice = mi_slices_start_iterate(segment, &end);\n  while (slice < end) {\n    mi_assert_internal(slice->slice_count > 0);\n    mi_assert_internal(slice->slice_offset == 0);\n    if (mi_slice_is_used(slice)) {\n      // ensure used count is up to date and collect potential concurrent frees\n      mi_page_t* const page = mi_slice_to_page(slice);\n      _mi_page_free_collect(page, false);\n      {\n        // abandon the page if it is still in-use (this will free it if possible as well)\n        mi_assert_internal(segment->used > 0);\n        if (segment->used == segment->abandoned+1) {\n          // the last page.. abandon and return as the segment will be abandoned after this\n          // and we should no longer access it.\n          segment->dont_free = false;\n          _mi_page_force_abandon(page);\n          return;\n        }\n        else {\n          // abandon and continue\n          _mi_page_force_abandon(page);\n          // it might be freed, reset the slice (note: relies on coalesce setting the slice_offset)\n          slice = mi_slice_first(slice);\n        }\n      }\n    }\n    slice = slice + slice->slice_count;\n  }\n  segment->dont_free = false;\n  mi_assert(segment->used == segment->abandoned);\n  mi_assert(segment->used == 0);\n  if (segment->used == 0) {  // paranoia\n    // all free now\n    mi_segment_free(segment, false, tld);\n  }\n  else {\n    // perform delayed purges\n    mi_segment_try_purge(segment, false /* force? */);\n  }\n}\n\n\n// try abandon segments.\n// this should be called from `reclaim_or_alloc` so we know all segments are (about) fully in use.\nstatic void mi_segments_try_abandon_to_target(mi_heap_t* heap, size_t target, mi_segments_tld_t* tld) {\n  if (target <= 1) return;\n  const size_t min_target = (target > 4 ? (target*3)/4 : target);  // 75%\n  // todo: we should maintain a list of segments per thread; for now, only consider segments from the heap full pages\n  for (int i = 0; i < 64 && tld->count >= min_target; i++) {\n    mi_page_t* page = heap->pages[MI_BIN_FULL].first;\n    while (page != NULL && mi_page_block_size(page) > MI_LARGE_OBJ_SIZE_MAX) {\n      page = page->next;\n    }\n    if (page==NULL) {\n      break;\n    }\n    mi_segment_t* segment = _mi_page_segment(page);\n    mi_segment_force_abandon(segment, tld);\n    mi_assert_internal(page != heap->pages[MI_BIN_FULL].first); // as it is just abandoned\n  }\n}\n\n// try abandon segments.\n// this should be called from `reclaim_or_alloc` so we know all segments are (about) fully in use.\nstatic void mi_segments_try_abandon(mi_heap_t* heap, mi_segments_tld_t* tld) {\n  // we call this when we are about to add a fresh segment so we should be under our target segment count.\n  size_t target = 0;\n  if (segment_count_is_within_target(tld, &target)) return;\n  mi_segments_try_abandon_to_target(heap, target, tld);\n}\n\nvoid mi_collect_reduce(size_t target_size) mi_attr_noexcept {\n  mi_collect(true);\n  mi_heap_t* heap = mi_heap_get_default();\n  mi_segments_tld_t* tld = &heap->tld->segments;\n  size_t target = target_size / MI_SEGMENT_SIZE;\n  if (target == 0) {\n    target = (size_t)mi_option_get_clamp(mi_option_target_segments_per_thread, 1, 1024);\n  }\n  mi_segments_try_abandon_to_target(heap, target, tld);\n}\n\n/* -----------------------------------------------------------\n   Reclaim or allocate\n----------------------------------------------------------- */\n\nstatic mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t needed_slices, size_t block_size, mi_segments_tld_t* tld)\n{\n  mi_assert_internal(block_size <= MI_LARGE_OBJ_SIZE_MAX);\n\n  // try to abandon some segments to increase reuse between threads\n  mi_segments_try_abandon(heap,tld);\n\n  // 1. try to reclaim an abandoned segment\n  bool reclaimed;\n  mi_segment_t* segment = mi_segment_try_reclaim(heap, needed_slices, block_size, &reclaimed, tld);\n  if (reclaimed) {\n    // reclaimed the right page right into the heap\n    mi_assert_internal(segment != NULL);\n    return NULL; // pretend out-of-memory as the page will be in the page queue of the heap with available blocks\n  }\n  else if (segment != NULL) {\n    // reclaimed a segment with a large enough empty span in it\n    return segment;\n  }\n  // 2. otherwise allocate a fresh segment\n  return mi_segment_alloc(0, 0, heap->arena_id, tld, NULL);\n}\n\n\n/* -----------------------------------------------------------\n   Page allocation\n----------------------------------------------------------- */\n\nstatic mi_page_t* mi_segments_page_alloc(mi_heap_t* heap, mi_page_kind_t page_kind, size_t required, size_t block_size, mi_segments_tld_t* tld)\n{\n  mi_assert_internal(required <= MI_LARGE_OBJ_SIZE_MAX && page_kind <= MI_PAGE_LARGE);\n\n  // find a free page\n  size_t page_size = _mi_align_up(required, (required > MI_MEDIUM_PAGE_SIZE ? MI_MEDIUM_PAGE_SIZE : MI_SEGMENT_SLICE_SIZE));\n  size_t slices_needed = page_size / MI_SEGMENT_SLICE_SIZE;\n  mi_assert_internal(slices_needed * MI_SEGMENT_SLICE_SIZE == page_size);\n  mi_page_t* page = mi_segments_page_find_and_allocate(slices_needed, heap->arena_id, tld); //(required <= MI_SMALL_SIZE_MAX ? 0 : slices_needed), tld);\n  if (page==NULL) {\n    // no free page, allocate a new segment and try again\n    if (mi_segment_reclaim_or_alloc(heap, slices_needed, block_size, tld) == NULL) {\n      // OOM or reclaimed a good page in the heap\n      return NULL;\n    }\n    else {\n      // otherwise try again\n      return mi_segments_page_alloc(heap, page_kind, required, block_size, tld);\n    }\n  }\n  mi_assert_internal(page != NULL && page->slice_count*MI_SEGMENT_SLICE_SIZE == page_size);\n  mi_assert_internal(_mi_ptr_segment(page)->thread_id == _mi_thread_id());\n  mi_segment_try_purge(_mi_ptr_segment(page), false);\n  return page;\n}\n\n\n\n/* -----------------------------------------------------------\n   Huge page allocation\n----------------------------------------------------------- */\n\nstatic mi_page_t* mi_segment_huge_page_alloc(size_t size, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld)\n{\n  mi_page_t* page = NULL;\n  mi_segment_t* segment = mi_segment_alloc(size,page_alignment,req_arena_id,tld,&page);\n  if (segment == NULL || page==NULL) return NULL;\n  mi_assert_internal(segment->used==1);\n  mi_assert_internal(mi_page_block_size(page) >= size);\n  #if MI_HUGE_PAGE_ABANDON\n  segment->thread_id = 0; // huge segments are immediately abandoned\n  #endif\n\n  // for huge pages we initialize the block_size as we may\n  // overallocate to accommodate large alignments.\n  size_t psize;\n  uint8_t* start = _mi_segment_page_start(segment, page, &psize);\n  page->block_size = psize;\n  mi_assert_internal(page->is_huge);\n\n  // decommit the part of the prefix of a page that will not be used; this can be quite large (close to MI_SEGMENT_SIZE)\n  if (page_alignment > 0 && segment->allow_decommit) {\n    uint8_t* aligned_p = (uint8_t*)_mi_align_up((uintptr_t)start, page_alignment);\n    mi_assert_internal(_mi_is_aligned(aligned_p, page_alignment));\n    mi_assert_internal(psize - (aligned_p - start) >= size);\n    uint8_t* decommit_start = start + sizeof(mi_block_t);              // for the free list\n    ptrdiff_t decommit_size = aligned_p - decommit_start;\n    _mi_os_reset(decommit_start, decommit_size);   // note: cannot use segment_decommit on huge segments\n  }\n\n  return page;\n}\n\n#if MI_HUGE_PAGE_ABANDON\n// free huge block from another thread\nvoid _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) {\n  // huge page segments are always abandoned and can be freed immediately by any thread\n  mi_assert_internal(segment->kind==MI_SEGMENT_HUGE);\n  mi_assert_internal(segment == _mi_page_segment(page));\n  mi_assert_internal(mi_atomic_load_relaxed(&segment->thread_id)==0);\n\n  // claim it and free\n  mi_heap_t* heap = mi_heap_get_default(); // issue #221; don't use the internal get_default_heap as we need to ensure the thread is initialized.\n  // paranoia: if this it the last reference, the cas should always succeed\n  size_t expected_tid = 0;\n  if (mi_atomic_cas_strong_acq_rel(&segment->thread_id, &expected_tid, heap->thread_id)) {\n    mi_block_set_next(page, block, page->free);\n    page->free = block;\n    page->used--;\n    page->is_zero_init = false;\n    mi_assert(page->used == 0);\n    mi_tld_t* tld = heap->tld;\n    _mi_segment_page_free(page, true, &tld->segments);\n  }\n#if (MI_DEBUG!=0)\n  else {\n    mi_assert_internal(false);\n  }\n#endif\n}\n\n#else\n// reset memory of a huge block from another thread\nvoid _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) {\n  MI_UNUSED(page);\n  mi_assert_internal(segment->kind == MI_SEGMENT_HUGE);\n  mi_assert_internal(segment == _mi_page_segment(page));\n  mi_assert_internal(page->used == 1); // this is called just before the free\n  mi_assert_internal(page->free == NULL);\n  if (segment->allow_decommit) {\n    size_t csize = mi_usable_size(block);\n    if (csize > sizeof(mi_block_t)) {\n      csize = csize - sizeof(mi_block_t);\n      uint8_t* p = (uint8_t*)block + sizeof(mi_block_t);\n      _mi_os_reset(p, csize);  // note: cannot use segment_decommit on huge segments\n    }\n  }\n}\n#endif\n\n/* -----------------------------------------------------------\n   Page allocation and free\n----------------------------------------------------------- */\nmi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld) {\n  mi_page_t* page;\n  if mi_unlikely(page_alignment > MI_BLOCK_ALIGNMENT_MAX) {\n    mi_assert_internal(_mi_is_power_of_two(page_alignment));\n    mi_assert_internal(page_alignment >= MI_SEGMENT_SIZE);\n    if (page_alignment < MI_SEGMENT_SIZE) { page_alignment = MI_SEGMENT_SIZE; }\n    page = mi_segment_huge_page_alloc(block_size,page_alignment,heap->arena_id,tld);\n  }\n  else if (block_size <= MI_SMALL_OBJ_SIZE_MAX) {\n    page = mi_segments_page_alloc(heap,MI_PAGE_SMALL,block_size,block_size,tld);\n  }\n  else if (block_size <= MI_MEDIUM_OBJ_SIZE_MAX) {\n    page = mi_segments_page_alloc(heap,MI_PAGE_MEDIUM,MI_MEDIUM_PAGE_SIZE,block_size,tld);\n  }\n  else if (block_size <= MI_LARGE_OBJ_SIZE_MAX) {\n    page = mi_segments_page_alloc(heap,MI_PAGE_LARGE,block_size,block_size,tld);\n  }\n  else {\n    page = mi_segment_huge_page_alloc(block_size,page_alignment,heap->arena_id,tld);\n  }\n  mi_assert_internal(page == NULL || _mi_heap_memid_is_suitable(heap, _mi_page_segment(page)->memid));\n  mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld));\n  mi_assert_internal(page == NULL || _mi_page_segment(page)->subproc == tld->subproc);\n  return page;\n}\n\n\n/* -----------------------------------------------------------\n   Visit blocks in a segment (only used for abandoned segments)\n----------------------------------------------------------- */\n\nstatic bool mi_segment_visit_page(mi_page_t* page, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) {\n  mi_heap_area_t area;\n  _mi_heap_area_init(&area, page);\n  if (!visitor(NULL, &area, NULL, area.block_size, arg)) return false;\n  if (visit_blocks) {\n    _mi_page_free_collect(page,true); // collect so the used count is accurate\n    return _mi_heap_area_visit_blocks(&area, page, visitor, arg);\n  }\n  else {\n    return true;\n  }\n}\n\nbool _mi_segment_visit_blocks(mi_segment_t* segment, int heap_tag, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) {\n  const mi_slice_t* end;\n  mi_slice_t* slice = mi_slices_start_iterate(segment, &end);\n  while (slice < end) {\n    if (mi_slice_is_used(slice)) {\n      mi_page_t* const page = mi_slice_to_page(slice);\n      if (heap_tag < 0 || (int)page->heap_tag == heap_tag) {\n        if (!mi_segment_visit_page(page, visit_blocks, visitor, arg)) return false;\n      }\n    }\n    slice = slice + slice->slice_count;\n  }\n  return true;\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/static.c",
      "sha256": "81e27487e494d2b32cb16a2605d61ee64fe3a71c409d5be3a673950ff769bd73",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2020, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#ifndef _DEFAULT_SOURCE\n#define _DEFAULT_SOURCE\n#endif\n#if defined(__sun)\n// same remarks as os.c for the static's context.\n#undef _XOPEN_SOURCE\n#undef _POSIX_C_SOURCE\n#endif\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n\n// For a static override we create a single object file\n// containing the whole library. If it is linked first\n// it will override all the standard library allocation\n// functions (on Unix's).\n#include \"alloc.c\"          // includes alloc-override.c\n#include \"alloc-aligned.c\"\n#include \"alloc-posix.c\"\n#include \"arena.c\"\n#include \"bitmap.c\"\n#include \"heap.c\"\n#include \"init.c\"\n#include \"libc.c\"\n#include \"options.c\"\n#include \"os.c\"\n#include \"page.c\"           // includes page-queue.c\n#include \"random.c\"\n#include \"segment.c\"\n#include \"segment-map.c\"\n#include \"stats.c\"\n#include \"prim/prim.c\"\n#if MI_OSX_ZONE\n#include \"prim/osx/alloc-override-zone.c\"\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v2/src/stats.c",
      "sha256": "7767e241bb0fe702d37083f213b1a194457d4e9ef7fef77f3324a6067b440239",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2021, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"\n\n#include <string.h> // memset\n\n#if defined(_MSC_VER) && (_MSC_VER < 1920)\n#pragma warning(disable:4204)  // non-constant aggregate initializer\n#endif\n\n/* -----------------------------------------------------------\n  Statistics operations\n----------------------------------------------------------- */\n\nstatic bool mi_is_in_main(void* stat) {\n  return ((uint8_t*)stat >= (uint8_t*)&_mi_stats_main\n         && (uint8_t*)stat < ((uint8_t*)&_mi_stats_main + sizeof(mi_stats_t)));\n}\n\nstatic void mi_stat_update(mi_stat_count_t* stat, int64_t amount) {\n  if (amount == 0) return;\n  if mi_unlikely(mi_is_in_main(stat))\n  {\n    // add atomically (for abandoned pages)\n    int64_t current = mi_atomic_addi64_relaxed(&stat->current, amount);\n    // if (stat == &_mi_stats_main.committed) { mi_assert_internal(current + amount >= 0); };\n    mi_atomic_maxi64_relaxed(&stat->peak, current + amount);\n    if (amount > 0) {\n      mi_atomic_addi64_relaxed(&stat->total,amount);\n    }\n  }\n  else {\n    // add thread local\n    stat->current += amount;\n    if (stat->current > stat->peak) { stat->peak = stat->current; }\n    if (amount > 0) { stat->total += amount; }\n  }\n}\n\nvoid _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount) {\n  if (mi_is_in_main(stat)) {\n    mi_atomic_addi64_relaxed( &stat->total, (int64_t)amount );\n  }\n  else {\n    stat->total += amount;\n  }\n}\n\nvoid _mi_stat_increase(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_update(stat, (int64_t)amount);\n}\n\nvoid _mi_stat_decrease(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_update(stat, -((int64_t)amount));\n}\n\n\nstatic void mi_stat_adjust(mi_stat_count_t* stat, int64_t amount) {\n  if (amount == 0) return;\n  if mi_unlikely(mi_is_in_main(stat))\n  {\n    // adjust atomically\n    mi_atomic_addi64_relaxed(&stat->current, amount);\n    mi_atomic_addi64_relaxed(&stat->total,amount);\n  }\n  else {\n    // adjust local\n    stat->current += amount;\n    stat->total += amount;\n  }\n}\n\nvoid _mi_stat_adjust_decrease(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_adjust(stat, -((int64_t)amount));\n}\n\n\n// must be thread safe as it is called from stats_merge\nstatic void mi_stat_count_add_mt(mi_stat_count_t* stat, const mi_stat_count_t* src) {\n  if (stat==src) return;\n  mi_atomic_void_addi64_relaxed(&stat->total, &src->total);\n  const int64_t prev_current = mi_atomic_addi64_relaxed(&stat->current, src->current);\n\n  // Global current plus thread peak approximates new global peak\n  // note: peak scores do really not work across threads.\n  // we used to just add them together but that often overestimates in practice.\n  // similarly, max does not seem to work well. The current approach\n  // by Artem Kharytoniuk (@artem-lunarg) seems to work better, see PR#1112\n  // for a longer description.\n  mi_atomic_maxi64_relaxed(&stat->peak, prev_current + src->peak);\n}\n\nstatic void mi_stat_counter_add_mt(mi_stat_counter_t* stat, const mi_stat_counter_t* src) {\n  if (stat==src) return;\n  mi_atomic_void_addi64_relaxed(&stat->total, &src->total);\n}\n\n#define MI_STAT_COUNT(stat)    mi_stat_count_add_mt(&stats->stat, &src->stat);\n#define MI_STAT_COUNTER(stat)  mi_stat_counter_add_mt(&stats->stat, &src->stat);\n\n// must be thread safe as it is called from stats_merge\nstatic void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) {\n  if (stats==src) return;\n\n  // copy all fields\n  MI_STAT_FIELDS()\n\n  #if MI_STAT>1\n  for (size_t i = 0; i <= MI_BIN_HUGE; i++) {\n    mi_stat_count_add_mt(&stats->malloc_bins[i], &src->malloc_bins[i]);\n  }\n  #endif\n  for (size_t i = 0; i <= MI_BIN_HUGE; i++) {\n    mi_stat_count_add_mt(&stats->page_bins[i], &src->page_bins[i]);\n  }\n}\n\n#undef MI_STAT_COUNT\n#undef MI_STAT_COUNTER\n\n/* -----------------------------------------------------------\n  Display statistics\n----------------------------------------------------------- */\n\n// unit > 0 : size in binary bytes\n// unit == 0: count as decimal\n// unit < 0 : count in binary\nstatic void mi_printf_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg, const char* fmt) {\n  char buf[32]; buf[0] = 0;\n  int  len = 32;\n  const char* suffix = (unit <= 0 ? \" \" : \"B\");\n  const int64_t base = (unit == 0 ? 1000 : 1024);\n  if (unit>0) n *= unit;\n\n  const int64_t pos = (n < 0 ? -n : n);\n  if (pos < base) {\n    if (n!=1 || suffix[0] != 'B') {  // skip printing 1 B for the unit column\n      _mi_snprintf(buf, len, \"%lld   %-3s\", (long long)n, (n==0 ? \"\" : suffix));\n    }\n  }\n  else {\n    int64_t divider = base;\n    const char* magnitude = \"K\";\n    if (pos >= divider*base) { divider *= base; magnitude = \"M\"; }\n    if (pos >= divider*base) { divider *= base; magnitude = \"G\"; }\n    const int64_t tens = (n / (divider/10));\n    const long whole = (long)(tens/10);\n    const long frac1 = (long)(tens%10);\n    char unitdesc[8];\n    _mi_snprintf(unitdesc, 8, \"%s%s%s\", magnitude, (base==1024 ? \"i\" : \"\"), suffix);\n    _mi_snprintf(buf, len, \"%ld.%ld %-3s\", whole, (frac1 < 0 ? -frac1 : frac1), unitdesc);\n  }\n  _mi_fprintf(out, arg, (fmt==NULL ? \"%12s\" : fmt), buf);\n}\n\n\nstatic void mi_print_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg) {\n  mi_printf_amount(n,unit,out,arg,NULL);\n}\n\nstatic void mi_print_count(int64_t n, int64_t unit, mi_output_fun* out, void* arg) {\n  if (unit==1) _mi_fprintf(out, arg, \"%12s\",\" \");\n          else mi_print_amount(n,0,out,arg);\n}\n\nstatic void mi_stat_print_ex(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg, const char* notok ) {\n  _mi_fprintf(out, arg,\"%10s:\", msg);\n  if (unit != 0) {\n    if (unit > 0) {\n      mi_print_amount(stat->peak, unit, out, arg);\n      mi_print_amount(stat->total, unit, out, arg);\n      // mi_print_amount(stat->freed, unit, out, arg);\n      mi_print_amount(stat->current, unit, out, arg);\n      mi_print_amount(unit, 1, out, arg);\n      mi_print_count(stat->total, unit, out, arg);\n    }\n    else {\n      mi_print_amount(stat->peak, -1, out, arg);\n      mi_print_amount(stat->total, -1, out, arg);\n      // mi_print_amount(stat->freed, -1, out, arg);\n      mi_print_amount(stat->current, -1, out, arg);\n      if (unit == -1) {\n        _mi_fprintf(out, arg, \"%24s\", \"\");\n      }\n      else {\n        mi_print_amount(-unit, 1, out, arg);\n        mi_print_count((stat->total / -unit), 0, out, arg);\n      }\n    }\n    if (stat->current != 0) {\n      _mi_fprintf(out, arg, \"  \");\n      _mi_fprintf(out, arg, (notok == NULL ? \"not all freed\" : notok));\n      _mi_fprintf(out, arg, \"\\n\");\n    }\n    else {\n      _mi_fprintf(out, arg, \"  ok\\n\");\n    }\n  }\n  else {\n    mi_print_amount(stat->peak, 0, out, arg);\n    mi_print_amount(stat->total, 0, out, arg);\n    mi_print_amount(stat->current, 0, out, arg);\n    _mi_fprintf(out, arg, \"\\n\");\n  }\n}\n\nstatic void mi_stat_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg) {\n  mi_stat_print_ex(stat, msg, unit, out, arg, NULL);\n}\n\n#if MI_STAT>1\nstatic void mi_stat_total_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg) {\n  _mi_fprintf(out, arg, \"%10s:\", msg);\n  _mi_fprintf(out, arg, \"%12s\", \" \");  // no peak\n  mi_print_amount(stat->total, unit, out, arg);\n  _mi_fprintf(out, arg, \"\\n\");\n}\n#endif\n\nstatic void mi_stat_counter_print(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg ) {\n  _mi_fprintf(out, arg, \"%10s:\", msg);\n  mi_print_amount(stat->total, 0, out, arg);\n  _mi_fprintf(out, arg, \"\\n\");\n}\n\nstatic void mi_stat_counter_print_size(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg ) {\n  _mi_fprintf(out, arg, \"%10s:\", msg);\n  mi_print_amount(stat->total, 1, out, arg);\n  _mi_fprintf(out, arg, \"\\n\");\n}\n\nstatic void mi_stat_average_print(int64_t count, int64_t total, const char* msg, mi_output_fun* out, void* arg) {\n  const int64_t avg_tens = (count == 0 ? 0 : (total*10 / count));\n  const int64_t avg_whole = avg_tens/10;\n  const int64_t avg_frac1 = avg_tens%10;\n  _mi_fprintf(out, arg, \"%10s: %5lld.%lld avg\\n\", msg, avg_whole, avg_frac1);\n}\n\n\nstatic void mi_print_header(mi_output_fun* out, void* arg ) {\n  _mi_fprintf(out, arg, \"%10s: %11s %11s %11s %11s %11s\\n\", \"heap stats\", \"peak   \", \"total   \", \"current   \", \"block   \", \"total#   \");\n}\n\n#if MI_STAT>1\nstatic void mi_stats_print_bins(const mi_stat_count_t* bins, size_t max, const char* fmt, mi_output_fun* out, void* arg) {\n  bool found = false;\n  char buf[64];\n  for (size_t i = 0; i <= max; i++) {\n    if (bins[i].total > 0) {\n      found = true;\n      int64_t unit = _mi_bin_size((uint8_t)i);\n      _mi_snprintf(buf, 64, \"%s %3lu\", fmt, (long)i);\n      mi_stat_print(&bins[i], buf, unit, out, arg);\n    }\n  }\n  if (found) {\n    _mi_fprintf(out, arg, \"\\n\");\n    mi_print_header(out, arg);\n  }\n}\n#endif\n\n\n\n//------------------------------------------------------------\n// Use an output wrapper for line-buffered output\n// (which is nice when using loggers etc.)\n//------------------------------------------------------------\ntypedef struct buffered_s {\n  mi_output_fun* out;   // original output function\n  void*          arg;   // and state\n  char*          buf;   // local buffer of at least size `count+1`\n  size_t         used;  // currently used chars `used <= count`\n  size_t         count; // total chars available for output\n} buffered_t;\n\nstatic void mi_buffered_flush(buffered_t* buf) {\n  buf->buf[buf->used] = 0;\n  _mi_fputs(buf->out, buf->arg, NULL, buf->buf);\n  buf->used = 0;\n}\n\nstatic void mi_cdecl mi_buffered_out(const char* msg, void* arg) {\n  buffered_t* buf = (buffered_t*)arg;\n  if (msg==NULL || buf==NULL) return;\n  for (const char* src = msg; *src != 0; src++) {\n    char c = *src;\n    if (buf->used >= buf->count) mi_buffered_flush(buf);\n    mi_assert_internal(buf->used < buf->count);\n    buf->buf[buf->used++] = c;\n    if (c == '\\n') mi_buffered_flush(buf);\n  }\n}\n\n//------------------------------------------------------------\n// Print statistics\n//------------------------------------------------------------\n\nstatic void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0) mi_attr_noexcept {\n  // wrap the output function to be line buffered\n  char buf[256];\n  buffered_t buffer = { out0, arg0, NULL, 0, 255 };\n  buffer.buf = buf;\n  mi_output_fun* out = &mi_buffered_out;\n  void* arg = &buffer;\n\n  // and print using that\n  mi_print_header(out,arg);\n  #if MI_STAT>1\n  mi_stats_print_bins(stats->malloc_bins, MI_BIN_HUGE, \"bin\",out,arg);\n  #endif\n  #if MI_STAT\n  mi_stat_print(&stats->malloc_normal, \"binned\", (stats->malloc_normal_count.total == 0 ? -1 : 1), out, arg);\n  mi_stat_print(&stats->malloc_huge, \"huge\", (stats->malloc_huge_count.total == 0 ? -1 : 1), out, arg);\n  mi_stat_count_t total = { 0,0,0 };\n  mi_stat_count_add_mt(&total, &stats->malloc_normal);\n  // mi_stat_count_add(&total, &stats->malloc_large);\n  mi_stat_count_add_mt(&total, &stats->malloc_huge);\n  mi_stat_print_ex(&total, \"total\", 1, out, arg, \"\");\n  #endif\n  #if MI_STAT>1\n  mi_stat_total_print(&stats->malloc_requested, \"malloc req\", 1, out, arg);\n  _mi_fprintf(out, arg, \"\\n\");\n  #endif\n  mi_stat_print_ex(&stats->reserved, \"reserved\", 1, out, arg, \"\");\n  mi_stat_print_ex(&stats->committed, \"committed\", 1, out, arg, \"\");\n  mi_stat_counter_print_size(&stats->reset, \"reset\", out, arg );\n  mi_stat_counter_print_size(&stats->purged, \"purged\", out, arg );\n  mi_stat_print_ex(&stats->page_committed, \"touched\", 1, out, arg, \"\");\n  mi_stat_print(&stats->segments, \"segments\", 0, out, arg);\n  mi_stat_print(&stats->segments_abandoned, \"-abandoned\", 0, out, arg);\n  mi_stat_print(&stats->segments_cache, \"-cached\", 0, out, arg);\n  mi_stat_print(&stats->pages, \"pages\", 0, out, arg);\n  mi_stat_print(&stats->pages_abandoned, \"-abandoned\", 0, out, arg);\n  mi_stat_counter_print(&stats->pages_extended, \"-extended\", out, arg);\n  mi_stat_counter_print(&stats->pages_retire, \"-retire\", out, arg);\n  mi_stat_counter_print(&stats->arena_count, \"arenas\", out, arg);\n  // mi_stat_counter_print(&stats->arena_crossover_count, \"-crossover\", out, arg);\n  mi_stat_counter_print(&stats->arena_rollback_count, \"-rollback\", out, arg);\n  mi_stat_counter_print(&stats->mmap_calls, \"mmaps\", out, arg);\n  mi_stat_counter_print(&stats->commit_calls, \"commits\", out, arg);\n  mi_stat_counter_print(&stats->reset_calls, \"resets\", out, arg);\n  mi_stat_counter_print(&stats->purge_calls, \"purges\", out, arg);\n  mi_stat_counter_print(&stats->malloc_guarded_count, \"guarded\", out, arg);\n  mi_stat_print(&stats->threads, \"threads\", 0, out, arg);\n  mi_stat_average_print(stats->page_searches_count.total, stats->page_searches.total, \"searches\", out, arg);\n  _mi_fprintf(out, arg, \"%10s: %5i\\n\", \"numa nodes\", _mi_os_numa_node_count());\n\n  size_t elapsed;\n  size_t user_time;\n  size_t sys_time;\n  size_t current_rss;\n  size_t peak_rss;\n  size_t current_commit;\n  size_t peak_commit;\n  size_t page_faults;\n  mi_process_info(&elapsed, &user_time, &sys_time, &current_rss, &peak_rss, &current_commit, &peak_commit, &page_faults);\n  _mi_fprintf(out, arg, \"%10s: %5zu.%03zu s\\n\", \"elapsed\", elapsed/1000, elapsed%1000);\n  _mi_fprintf(out, arg, \"%10s: user: %zu.%03zu s, system: %zu.%03zu s, faults: %zu, peak rss: \", \"process\",\n              user_time/1000, user_time%1000, sys_time/1000, sys_time%1000, page_faults );\n  mi_printf_amount((int64_t)peak_rss, 1, out, arg, \"%s\");\n  if (peak_commit > 0) {\n    _mi_fprintf(out, arg, \", peak commit: \");\n    mi_printf_amount((int64_t)peak_commit, 1, out, arg, \"%s\");\n  }\n  _mi_fprintf(out, arg, \"\\n\");\n}\n\nstatic mi_msecs_t mi_process_start; // = 0\n\nstatic mi_stats_t* mi_stats_get_default(void) {\n  mi_heap_t* heap = mi_heap_get_default();\n  return &heap->tld->stats;\n}\n\nstatic void mi_stats_merge_from(mi_stats_t* stats) {\n  if (stats != &_mi_stats_main) {\n    mi_stats_add(&_mi_stats_main, stats);\n    memset(stats, 0, sizeof(mi_stats_t));\n  }\n}\n\nvoid mi_stats_reset(void) mi_attr_noexcept {\n  mi_stats_t* stats = mi_stats_get_default();\n  if (stats != &_mi_stats_main) { memset(stats, 0, sizeof(mi_stats_t)); }\n  memset(&_mi_stats_main, 0, sizeof(mi_stats_t));\n  if (mi_process_start == 0) { mi_process_start = _mi_clock_start(); };\n}\n\nvoid mi_stats_merge(void) mi_attr_noexcept {\n  mi_stats_merge_from( mi_stats_get_default() );\n}\n\nvoid _mi_stats_merge_thread(mi_tld_t* tld) {\n  mi_stats_merge_from( &tld->stats );\n}\n\nvoid _mi_stats_done(mi_stats_t* stats) {  // called from `mi_thread_done`\n  mi_stats_merge_from(stats);\n}\n\nvoid mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept {\n  mi_stats_merge_from(mi_stats_get_default());\n  _mi_stats_print(&_mi_stats_main, out, arg);\n}\n\nvoid mi_stats_print(void* out) mi_attr_noexcept {\n  // for compatibility there is an `out` parameter (which can be `stdout` or `stderr`)\n  mi_stats_print_out((mi_output_fun*)out, NULL);\n}\n\nvoid mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept {\n  _mi_stats_print(mi_stats_get_default(), out, arg);\n}\n\n\n// ----------------------------------------------------------------\n// Basic timer for convenience; use milli-seconds to avoid doubles\n// ----------------------------------------------------------------\n\nstatic mi_msecs_t mi_clock_diff;\n\nmi_msecs_t _mi_clock_now(void) {\n  return _mi_prim_clock_now();\n}\n\nmi_msecs_t _mi_clock_start(void) {\n  if (mi_clock_diff == 0.0) {\n    mi_msecs_t t0 = _mi_clock_now();\n    mi_clock_diff = _mi_clock_now() - t0;\n  }\n  return _mi_clock_now();\n}\n\nmi_msecs_t _mi_clock_end(mi_msecs_t start) {\n  mi_msecs_t end = _mi_clock_now();\n  return (end - start - mi_clock_diff);\n}\n\n\n// --------------------------------------------------------\n// Basic process statistics\n// --------------------------------------------------------\n\nmi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept\n{\n  mi_process_info_t pinfo;\n  _mi_memzero_var(pinfo);\n  pinfo.elapsed        = _mi_clock_end(mi_process_start);\n  pinfo.current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current));\n  pinfo.peak_commit    = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak));\n  pinfo.current_rss    = pinfo.current_commit;\n  pinfo.peak_rss       = pinfo.peak_commit;\n  pinfo.utime          = 0;\n  pinfo.stime          = 0;\n  pinfo.page_faults    = 0;\n\n  _mi_prim_process_info(&pinfo);\n\n  if (elapsed_msecs!=NULL)  *elapsed_msecs  = (pinfo.elapsed < 0 ? 0 : (pinfo.elapsed < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.elapsed : PTRDIFF_MAX));\n  if (user_msecs!=NULL)     *user_msecs     = (pinfo.utime < 0 ? 0 : (pinfo.utime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.utime : PTRDIFF_MAX));\n  if (system_msecs!=NULL)   *system_msecs   = (pinfo.stime < 0 ? 0 : (pinfo.stime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.stime : PTRDIFF_MAX));\n  if (current_rss!=NULL)    *current_rss    = pinfo.current_rss;\n  if (peak_rss!=NULL)       *peak_rss       = pinfo.peak_rss;\n  if (current_commit!=NULL) *current_commit = pinfo.current_commit;\n  if (peak_commit!=NULL)    *peak_commit    = pinfo.peak_commit;\n  if (page_faults!=NULL)    *page_faults    = pinfo.page_faults;\n}\n\n\n// --------------------------------------------------------\n// Return statistics\n// --------------------------------------------------------\n\nbool mi_stats_get(mi_stats_t* stats) mi_attr_noexcept {\n  if (stats == NULL || stats->size != sizeof(mi_stats_t) || stats->version != MI_STAT_VERSION) return false;\n  _mi_memzero(stats,stats->size);\n  _mi_memcpy(stats, &_mi_stats_main, sizeof(mi_stats_t));\n  return true;\n}\n\n\n// --------------------------------------------------------\n// Statics in json format\n// --------------------------------------------------------\n\ntypedef struct mi_heap_buf_s {\n  char*   buf;\n  size_t  size;\n  size_t  used;\n  bool    can_realloc;\n} mi_heap_buf_t;\n\nstatic bool mi_heap_buf_expand(mi_heap_buf_t* hbuf) {\n  if (hbuf==NULL) return false;\n  if (hbuf->buf != NULL && hbuf->size>0) {\n    hbuf->buf[hbuf->size-1] = 0;\n  }\n  if (hbuf->size > SIZE_MAX/2 || !hbuf->can_realloc) return false;\n  const size_t newsize = (hbuf->size == 0 ? mi_good_size(12*MI_KiB) : 2*hbuf->size);\n  char* const  newbuf  = (char*)mi_rezalloc(hbuf->buf, newsize);\n  if (newbuf == NULL) return false;\n  hbuf->buf = newbuf;\n  hbuf->size = newsize;\n  return true;\n}\n\nstatic void mi_heap_buf_print(mi_heap_buf_t* hbuf, const char* msg) {\n  if (msg==NULL || hbuf==NULL) return;\n  if (hbuf->used + 1 >= hbuf->size && !hbuf->can_realloc) return;\n  for (const char* src = msg; *src != 0; src++) {\n    char c = *src;\n    if (hbuf->used + 1 >= hbuf->size) {\n      if (!mi_heap_buf_expand(hbuf)) return;\n    }\n    mi_assert_internal(hbuf->used < hbuf->size);\n    hbuf->buf[hbuf->used++] = c;\n  }\n  mi_assert_internal(hbuf->used < hbuf->size);\n  hbuf->buf[hbuf->used] = 0;\n}\n\nstatic void mi_heap_buf_print_count_bin(mi_heap_buf_t* hbuf, const char* prefix, mi_stat_count_t* stat, size_t bin, bool add_comma) {\n  const size_t binsize = _mi_bin_size(bin);\n  const size_t pagesize = (binsize <= MI_SMALL_OBJ_SIZE_MAX ? MI_SMALL_PAGE_SIZE :\n                            (binsize <= MI_MEDIUM_OBJ_SIZE_MAX ? MI_MEDIUM_PAGE_SIZE :\n                              #if MI_LARGE_PAGE_SIZE\n                              (binsize <= MI_LARGE_OBJ_SIZE_MAX ? MI_LARGE_PAGE_SIZE : 0)\n                              #else\n                              0\n                              #endif\n                              ));\n  char buf[128];\n  _mi_snprintf(buf, 128, \"%s{ \\\"total\\\": %lld, \\\"peak\\\": %lld, \\\"current\\\": %lld, \\\"block_size\\\": %zu, \\\"page_size\\\": %zu }%s\\n\", prefix, stat->total, stat->peak, stat->current, binsize, pagesize, (add_comma ? \",\" : \"\"));\n  buf[127] = 0;\n  mi_heap_buf_print(hbuf, buf);\n}\n\nstatic void mi_heap_buf_print_count(mi_heap_buf_t* hbuf, const char* prefix, mi_stat_count_t* stat, bool add_comma) {\n  char buf[128];\n  _mi_snprintf(buf, 128, \"%s{ \\\"total\\\": %lld, \\\"peak\\\": %lld, \\\"current\\\": %lld }%s\\n\", prefix, stat->total, stat->peak, stat->current, (add_comma ? \",\" : \"\"));\n  buf[127] = 0;\n  mi_heap_buf_print(hbuf, buf);\n}\n\nstatic void mi_heap_buf_print_count_value(mi_heap_buf_t* hbuf, const char* name, mi_stat_count_t* stat) {\n  char buf[128];\n  _mi_snprintf(buf, 128, \"  \\\"%s\\\": \", name);\n  buf[127] = 0;\n  mi_heap_buf_print(hbuf, buf);\n  mi_heap_buf_print_count(hbuf, \"\", stat, true);\n}\n\nstatic void mi_heap_buf_print_value(mi_heap_buf_t* hbuf, const char* name, int64_t val) {\n  char buf[128];\n  _mi_snprintf(buf, 128, \"  \\\"%s\\\": %lld,\\n\", name, val);\n  buf[127] = 0;\n  mi_heap_buf_print(hbuf, buf);\n}\n\nstatic void mi_heap_buf_print_size(mi_heap_buf_t* hbuf, const char* name, size_t val, bool add_comma) {\n  char buf[128];\n  _mi_snprintf(buf, 128, \"    \\\"%s\\\": %zu%s\\n\", name, val, (add_comma ? \",\" : \"\"));\n  buf[127] = 0;\n  mi_heap_buf_print(hbuf, buf);\n}\n\nstatic void mi_heap_buf_print_counter_value(mi_heap_buf_t* hbuf, const char* name, mi_stat_counter_t* stat) {\n  mi_heap_buf_print_value(hbuf, name, stat->total);\n}\n\n#define MI_STAT_COUNT(stat)    mi_heap_buf_print_count_value(&hbuf, #stat, &stats->stat);\n#define MI_STAT_COUNTER(stat)  mi_heap_buf_print_counter_value(&hbuf, #stat, &stats->stat);\n\nchar* mi_stats_get_json(size_t output_size, char* output_buf) mi_attr_noexcept {\n  mi_heap_buf_t hbuf = { NULL, 0, 0, true };\n  if (output_size > 0 && output_buf != NULL) {\n    _mi_memzero(output_buf, output_size);\n    hbuf.buf = output_buf;\n    hbuf.size = output_size;\n    hbuf.can_realloc = false;\n  }\n  else {\n    if (!mi_heap_buf_expand(&hbuf)) return NULL;\n  }\n  mi_heap_buf_print(&hbuf, \"{\\n\");\n  mi_heap_buf_print_value(&hbuf, \"stat_version\", MI_STAT_VERSION);\n  mi_heap_buf_print_value(&hbuf, \"mimalloc_version\", MI_MALLOC_VERSION);\n\n  // process info\n  mi_heap_buf_print(&hbuf, \"  \\\"process\\\": {\\n\");\n  size_t elapsed;\n  size_t user_time;\n  size_t sys_time;\n  size_t current_rss;\n  size_t peak_rss;\n  size_t current_commit;\n  size_t peak_commit;\n  size_t page_faults;\n  mi_process_info(&elapsed, &user_time, &sys_time, &current_rss, &peak_rss, &current_commit, &peak_commit, &page_faults);\n  mi_heap_buf_print_size(&hbuf, \"elapsed_msecs\", elapsed, true);\n  mi_heap_buf_print_size(&hbuf, \"user_msecs\", user_time, true);\n  mi_heap_buf_print_size(&hbuf, \"system_msecs\", sys_time, true);\n  mi_heap_buf_print_size(&hbuf, \"page_faults\", page_faults, true);\n  mi_heap_buf_print_size(&hbuf, \"rss_current\", current_rss, true);\n  mi_heap_buf_print_size(&hbuf, \"rss_peak\", peak_rss, true);\n  mi_heap_buf_print_size(&hbuf, \"commit_current\", current_commit, true);\n  mi_heap_buf_print_size(&hbuf, \"commit_peak\", peak_commit, false);\n  mi_heap_buf_print(&hbuf, \"  },\\n\");\n\n  // statistics\n  mi_stats_t* stats = &_mi_stats_main;\n  MI_STAT_FIELDS()\n\n  // size bins\n  mi_heap_buf_print(&hbuf, \"  \\\"malloc_bins\\\": [\\n\");\n  for (size_t i = 0; i <= MI_BIN_HUGE; i++) {\n    mi_heap_buf_print_count_bin(&hbuf, \"    \", &stats->malloc_bins[i], i, i!=MI_BIN_HUGE);\n  }\n  mi_heap_buf_print(&hbuf, \"  ],\\n\");\n  mi_heap_buf_print(&hbuf, \"  \\\"page_bins\\\": [\\n\");\n  for (size_t i = 0; i <= MI_BIN_HUGE; i++) {\n    mi_heap_buf_print_count_bin(&hbuf, \"    \", &stats->page_bins[i], i, i!=MI_BIN_HUGE);\n  }\n  mi_heap_buf_print(&hbuf, \"  ]\\n\");\n  mi_heap_buf_print(&hbuf, \"}\\n\");\n  if (hbuf.used >= hbuf.size) {\n    // failed\n    if (hbuf.can_realloc) { mi_free(hbuf.buf); }\n    return NULL;\n  }\n  else {\n    return hbuf.buf;\n  }\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/include/mimalloc-new-delete.h",
      "sha256": "dd4f25cae53209d45d73f8e6a2b9c219e8fc7434d97f20eba9af1a8b850030fd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2020 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_NEW_DELETE_H\n#define MIMALLOC_NEW_DELETE_H\n\n// ----------------------------------------------------------------------------\n// This header provides convenient overrides for the new and\n// delete operations in C++.\n//\n// This header should be included in only one source file!\n//\n// On Windows, or when linking dynamically with mimalloc, these\n// can be more performant than the standard new-delete operations.\n// See <https://en.cppreference.com/w/cpp/memory/new/operator_new>\n// ---------------------------------------------------------------------------\n#if defined(__cplusplus)\n  #include <new>\n  #include <mimalloc.h>\n\n  #if defined(_MSC_VER) && defined(_Ret_notnull_) && defined(_Post_writable_byte_size_)\n  // stay consistent with VCRT definitions\n  #define mi_decl_new(n)          mi_decl_nodiscard mi_decl_restrict _Ret_notnull_ _Post_writable_byte_size_(n)\n  #define mi_decl_new_nothrow(n)  mi_decl_nodiscard mi_decl_restrict _Ret_maybenull_ _Success_(return != NULL) _Post_writable_byte_size_(n)\n  #else\n  #define mi_decl_new(n)          mi_decl_nodiscard mi_decl_restrict\n  #define mi_decl_new_nothrow(n)  mi_decl_nodiscard mi_decl_restrict\n  #endif\n\n  void operator delete(void* p) noexcept              { mi_free(p); };\n  void operator delete[](void* p) noexcept            { mi_free(p); };\n\n  void operator delete  (void* p, const std::nothrow_t&) noexcept { mi_free(p); }\n  void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); }\n\n  mi_decl_new(n) void* operator new(std::size_t n) noexcept(false) { return mi_new(n); }\n  mi_decl_new(n) void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); }\n\n  mi_decl_new_nothrow(n) void* operator new  (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }\n  mi_decl_new_nothrow(n) void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }\n\n  #if (__cplusplus >= 201402L || _MSC_VER >= 1916)\n  void operator delete  (void* p, std::size_t n) noexcept { mi_free_size(p,n); };\n  void operator delete[](void* p, std::size_t n) noexcept { mi_free_size(p,n); };\n  #endif\n\n  #if (__cplusplus > 201402L || defined(__cpp_aligned_new))\n  void operator delete  (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete  (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };\n  void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };\n  void operator delete  (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n\n  void* operator new  (std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }\n  void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }\n  void* operator new  (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }\n  void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }\n  #endif\n#endif\n\n#endif // MIMALLOC_NEW_DELETE_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/include/mimalloc-override.h",
      "sha256": "21fcf61c4443341ac6bf6ea528af31dc7267e8e3456fc64bfd07704503032175",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2020 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_OVERRIDE_H\n#define MIMALLOC_OVERRIDE_H\n\n/* ----------------------------------------------------------------------------\nThis header can be used to statically redirect malloc/free and new/delete\nto the mimalloc variants. This can be useful if one can include this file on\neach source file in a project (but be careful when using external code to\nnot accidentally mix pointers from different allocators).\n-----------------------------------------------------------------------------*/\n\n#include <mimalloc.h>\n\n// Standard C allocation\n#define malloc(n)               mi_malloc(n)\n#define calloc(c,n)             mi_calloc(c,n)\n#define realloc(p,n)            mi_realloc(p,n)\n#define free(p)                 mi_free(p)\n\n#define strdup(s)               mi_strdup(s)\n#define strndup(s,n)            mi_strndup(s,n)\n#define realpath(f,n)           mi_realpath(f,n)\n\n// Microsoft extensions\n#define _expand(p,n)            mi_expand(p,n)\n#define _msize(p)               mi_usable_size(p)\n#define _recalloc(p,c,n)        mi_recalloc(p,c,n)\n\n#define _strdup(s)              mi_strdup(s)\n#define _strndup(s,n)           mi_strndup(s,n)\n#define _wcsdup(s)              mi_wcsdup(s)\n#define _mbsdup(s)              mi_mbsdup(s)\n#define _dupenv_s(buf,n,nm)     mi_dupenv_s(buf,n,nm)\n#define _wdupenv_s(buf,n,nm)    mi_wdupenv_s(buf,n,nm)\n\n// Various Posix and Unix variants\n#define reallocf(p,n)           mi_reallocf(p,n)\n#define malloc_size(p)          mi_usable_size(p)\n#define malloc_usable_size(p)   mi_usable_size(p)\n#define malloc_good_size(n)     mi_malloc_good_size(n)\n#define cfree(p)                mi_free(p)\n\n#define valloc(n)               mi_valloc(n)\n#define pvalloc(n)              mi_pvalloc(n)\n#define reallocarray(p,c,n)     mi_reallocarray(p,c,n)\n#define reallocarr(ptrp,c,n)    mi_reallocarr(ptrp,c,n)\n#define memalign(a,n)           mi_memalign(a,n)\n#define aligned_alloc(a,n)      mi_aligned_alloc(a,n)\n#define posix_memalign(p,a,n)   mi_posix_memalign(p,a,n)\n#define _posix_memalign(p,a,n)  mi_posix_memalign(p,a,n)\n\n// Microsoft aligned variants\n#define _aligned_malloc(n,a)                  mi_malloc_aligned(n,a)\n#define _aligned_realloc(p,n,a)               mi_realloc_aligned(p,n,a)\n#define _aligned_recalloc(p,c,n,a)            mi_aligned_recalloc(p,c,n,a)\n#define _aligned_msize(p,a,o)                 mi_usable_size(p)\n#define _aligned_free(p)                      mi_free(p)\n#define _aligned_offset_malloc(n,a,o)         mi_malloc_aligned_at(n,a,o)\n#define _aligned_offset_realloc(p,n,a,o)      mi_realloc_aligned_at(p,n,a,o)\n#define _aligned_offset_recalloc(p,c,n,a,o)   mi_recalloc_aligned_at(p,c,n,a,o)\n\n#endif // MIMALLOC_OVERRIDE_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/include/mimalloc-stats.h",
      "sha256": "5260df227ea1612b8678a06b063cc8f48e739b551554541cdeb4d430a7e257b3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2024-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_STATS_H\n#define MIMALLOC_STATS_H\n\n#include <mimalloc.h>\n#include <string.h>   // memset\n#include <stdint.h>   // int64_t\n\n#define MI_STAT_VERSION   5  // increased on every backward incompatible change\n\n// alignment for atomic fields\n#if defined(_MSC_VER)\n#define mi_decl_align(a)        __declspec(align(a))\n#elif defined(__GNUC__)\n#define mi_decl_align(a)        __attribute__((aligned(a)))\n#elif __cplusplus >= 201103L\n#define mi_decl_align(a)        alignas(a)\n#else\n#define mi_decl_align(a)\n#endif\n\n\n// count allocation over time\ntypedef struct mi_stat_count_s {\n  int64_t total;                              // total allocated\n  int64_t peak;                               // peak allocation\n  int64_t current;                            // current allocation\n} mi_stat_count_t;\n\n// counters only increase\ntypedef struct mi_stat_counter_s {\n  int64_t total;                              // total count\n} mi_stat_counter_t;\n\n#define MI_STAT_FIELDS() \\\n  MI_STAT_COUNT(pages)                      /* count of mimalloc pages */ \\\n  MI_STAT_COUNT(reserved)                   /* reserved memory bytes */ \\\n  MI_STAT_COUNT(committed)                  /* committed bytes */ \\\n  MI_STAT_COUNTER(reset)                    /* reset bytes */ \\\n  MI_STAT_COUNTER(purged)                   /* purged bytes */ \\\n  MI_STAT_COUNT(page_committed)             /* committed memory inside pages */ \\\n  MI_STAT_COUNT(pages_abandoned)            /* abandoned pages count */ \\\n  MI_STAT_COUNT(threads)                    /* number of threads */ \\\n  MI_STAT_COUNT(malloc_normal)              /* allocated bytes <= MI_LARGE_OBJ_SIZE_MAX */ \\\n  MI_STAT_COUNT(malloc_huge)                /* allocated bytes in huge pages */ \\\n  MI_STAT_COUNT(malloc_requested)           /* malloc requested bytes */ \\\n  \\\n  MI_STAT_COUNTER(mmap_calls) \\\n  MI_STAT_COUNTER(commit_calls) \\\n  MI_STAT_COUNTER(reset_calls) \\\n  MI_STAT_COUNTER(purge_calls) \\\n  MI_STAT_COUNTER(arena_count)              /* number of memory arena's */ \\\n  MI_STAT_COUNTER(malloc_normal_count)      /* number of blocks <= MI_LARGE_OBJ_SIZE_MAX */ \\\n  MI_STAT_COUNTER(malloc_huge_count)        /* number of huge bloks */ \\\n  MI_STAT_COUNTER(malloc_guarded_count)     /* number of allocations with guard pages */ \\\n  \\\n  /* internal statistics */ \\\n  MI_STAT_COUNTER(arena_rollback_count) \\\n  MI_STAT_COUNTER(arena_purges) \\\n  MI_STAT_COUNTER(pages_extended)           /* number of page extensions */ \\\n  MI_STAT_COUNTER(pages_retire)             /* number of pages that are retired */ \\\n  MI_STAT_COUNTER(page_searches)            /* total pages searched for a fresh page */ \\\n  MI_STAT_COUNTER(page_searches_count)      /* searched count for a fresh page */ \\\n  /* only on v1 and v2 */ \\\n  MI_STAT_COUNT(segments) \\\n  MI_STAT_COUNT(segments_abandoned) \\\n  MI_STAT_COUNT(segments_cache) \\\n  MI_STAT_COUNT(_segments_reserved) \\\n  /* only on v3 */ \\\n  MI_STAT_COUNT(heaps) \\\n  MI_STAT_COUNT(theaps) \\\n  MI_STAT_COUNTER(pages_reclaim_on_alloc) \\\n  MI_STAT_COUNTER(pages_reclaim_on_free) \\\n  MI_STAT_COUNTER(pages_reabandon_full) \\\n  MI_STAT_COUNTER(pages_unabandon_busy_wait) \\\n  MI_STAT_COUNTER(heaps_delete_wait)\n\n// Size bins for chunks\ntypedef enum mi_chunkbin_e {\n  MI_CBIN_SMALL,    // slice_count == 1\n  MI_CBIN_OTHER,    // slice_count: any other from the other bins, and 1 <= slice_count <= MI_BCHUNK_BITS\n  MI_CBIN_MEDIUM,   // slice_count == 8\n  MI_CBIN_LARGE,    // slice_count == MI_SIZE_BITS  (only used if MI_ENABLE_LARGE_PAGES is 1)\n  MI_CBIN_HUGE,     // slice_count > MI_BCHUNK_BITS\n  MI_CBIN_NONE,     // no bin assigned yet (the chunk is completely free)\n  MI_CBIN_COUNT\n} mi_chunkbin_t;\n\n\n// Define the statistics structure\n#define MI_BIN_HUGE             (73U)   // see types.h\n#define MI_STAT_COUNT(stat)     mi_stat_count_t stat;\n#define MI_STAT_COUNTER(stat)   mi_stat_counter_t stat;\n\ntypedef struct mi_stats_s\n{\n  size_t size;          // size of the mi_stats_t structure \n  size_t version;       \n\n  mi_decl_align(8)  MI_STAT_FIELDS()\n\n  // future extension\n  mi_stat_count_t   _stat_reserved[4];\n  mi_stat_counter_t _stat_counter_reserved[4];\n\n  // size segregated statistics\n  mi_stat_count_t   malloc_bins[MI_BIN_HUGE+1];   // allocation per size bin\n  mi_stat_count_t   page_bins[MI_BIN_HUGE+1];     // pages allocated per size bin\n  mi_stat_count_t   chunk_bins[MI_CBIN_COUNT];    // chunks per page sizes\n} mi_stats_t;\n\n#undef MI_STAT_COUNT\n#undef MI_STAT_COUNTER\n\n// Initialization\nstatic inline void mi_stats_header_init(mi_stats_t* stats) {\n  stats->size = sizeof(*stats);\n  stats->version = MI_STAT_VERSION;\n}\nstatic inline void mi_stats_init(mi_stats_t* stats) {\n  memset(stats,0,sizeof(*stats));\n  mi_stats_header_init(stats);\n}\n\n#define mi_stats_t_decl(name)  mi_stats_t name; mi_stats_init(&name);\n\n// Exported definitions\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// stats from a heap\nmi_decl_export bool    mi_heap_stats_get(mi_heap_t* heap, mi_stats_t* stats) mi_attr_noexcept;\nmi_decl_export char*   mi_heap_stats_get_json(mi_heap_t* heap, size_t buf_size, char* buf) mi_attr_noexcept;      // use mi_free to free the result if the input buf == NULL\nmi_decl_export void    mi_heap_stats_print_out(mi_heap_t* heap, mi_output_fun* out, void* arg) mi_attr_noexcept;\n\n// stats from a subprocess and its heaps aggregated\nmi_decl_export bool    mi_subproc_stats_get(mi_subproc_id_t subproc_id, mi_stats_t* stats) mi_attr_noexcept;\nmi_decl_export char*   mi_subproc_stats_get_json(mi_subproc_id_t subproc_id, size_t buf_size, char* buf) mi_attr_noexcept;      // use mi_free to free the result if the input buf == NULL\nmi_decl_export void    mi_subproc_stats_print_out(mi_subproc_id_t subproc_id, mi_output_fun* out, void* arg) mi_attr_noexcept;\n// print subprocess and all its heap stats segregated\nmi_decl_export void    mi_subproc_heap_stats_print_out(mi_subproc_id_t subproc_id, mi_output_fun* out, void* arg) mi_attr_noexcept;\n\n// stats aggregated for the current subprocess and all its heaps.\nmi_decl_export bool    mi_stats_get(mi_stats_t* stats) mi_attr_noexcept;\nmi_decl_export char*   mi_stats_get_json(size_t buf_size, char* buf) mi_attr_noexcept;      // use mi_free to free the result if the input buf == NULL\nmi_decl_export void    mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept;\n\n// add the stats of the heap to the subprocess and clear the heap stats\nmi_decl_export void    mi_heap_stats_merge_to_subproc(mi_heap_t* heap);\n\n// stats from the subprocess without aggregating its heaps\nmi_decl_export bool    mi_subproc_stats_get_exclusive(mi_subproc_id_t subproc_id, mi_stats_t* stats) mi_attr_noexcept;\n\nmi_decl_export char*   mi_stats_as_json(mi_stats_t* stats, size_t buf_size, char* buf) mi_attr_noexcept;      // use mi_free to free the result if the input buf == NULL\nmi_decl_export size_t  mi_stats_get_bin_size(size_t bin) mi_attr_noexcept;\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // MIMALLOC_STATS_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/include/mimalloc.h",
      "sha256": "869161433ab2d807a75752d0762accf5b68b6b24ce67e417af46bf181b9b6c72",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2026, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_H\n#define MIMALLOC_H\n\n#define MI_MALLOC_VERSION 30302   // major + 2 digits minor + 2 digits patch\n\n// ------------------------------------------------------\n// Compiler specific attributes\n// ------------------------------------------------------\n\n#ifdef __cplusplus\n  #if (__cplusplus >= 201103L) || (_MSC_VER > 1900)  // C++11\n    #define mi_attr_noexcept   noexcept\n  #else\n    #define mi_attr_noexcept   throw()\n  #endif\n#else\n  #define mi_attr_noexcept\n#endif\n\n#if defined(__cplusplus) && (__cplusplus >= 201703)\n  #define mi_decl_nodiscard    [[nodiscard]]\n#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)  // includes clang, icc, and clang-cl\n  #define mi_decl_nodiscard    __attribute__((warn_unused_result))\n#elif defined(_HAS_NODISCARD)\n  #define mi_decl_nodiscard    _NODISCARD\n#elif (_MSC_VER >= 1700)\n  #define mi_decl_nodiscard    _Check_return_\n#else\n  #define mi_decl_nodiscard\n#endif\n\n#if defined(_MSC_VER) || defined(__MINGW32__)\n  #if !defined(MI_SHARED_LIB)\n    #define mi_decl_export\n  #elif defined(MI_SHARED_LIB_EXPORT)\n    #define mi_decl_export              __declspec(dllexport)\n  #else\n    #define mi_decl_export              __declspec(dllimport)\n  #endif\n  #if defined(__MINGW32__)\n    #define mi_decl_restrict\n    #define mi_attr_malloc              __attribute__((malloc))\n  #else\n    #if (_MSC_VER >= 1900) && !defined(__EDG__)\n      #define mi_decl_restrict          __declspec(allocator) __declspec(restrict)\n    #else\n      #define mi_decl_restrict          __declspec(restrict)\n    #endif\n    #define mi_attr_malloc\n  #endif\n  #define mi_cdecl                      __cdecl\n  #define mi_attr_alloc_size(s)\n  #define mi_attr_alloc_size2(s1,s2)\n  #define mi_attr_alloc_align(p)\n#elif defined(__GNUC__)                 // includes clang and icc\n  #if defined(MI_SHARED_LIB) && defined(MI_SHARED_LIB_EXPORT)\n    #define mi_decl_export              __attribute__((visibility(\"default\")))\n  #else\n    #define mi_decl_export\n  #endif\n  #define mi_cdecl                      // leads to warnings... __attribute__((cdecl))\n  #define mi_decl_restrict\n  #define mi_attr_malloc                __attribute__((malloc))\n  #if (defined(__clang_major__) && (__clang_major__ < 4)) || (__GNUC__ < 5)\n    #define mi_attr_alloc_size(s)\n    #define mi_attr_alloc_size2(s1,s2)\n    #define mi_attr_alloc_align(p)\n  #elif defined(__INTEL_COMPILER)\n    #define mi_attr_alloc_size(s)       __attribute__((alloc_size(s)))\n    #define mi_attr_alloc_size2(s1,s2)  __attribute__((alloc_size(s1,s2)))\n    #define mi_attr_alloc_align(p)\n  #else\n    #define mi_attr_alloc_size(s)       __attribute__((alloc_size(s)))\n    #define mi_attr_alloc_size2(s1,s2)  __attribute__((alloc_size(s1,s2)))\n    #define mi_attr_alloc_align(p)      __attribute__((alloc_align(p)))\n  #endif\n#else\n  #define mi_cdecl\n  #define mi_decl_export\n  #define mi_decl_restrict\n  #define mi_attr_malloc\n  #define mi_attr_alloc_size(s)\n  #define mi_attr_alloc_size2(s1,s2)\n  #define mi_attr_alloc_align(p)\n#endif\n\n// ------------------------------------------------------\n// Includes\n// ------------------------------------------------------\n\n#include <stddef.h>     // size_t\n#include <stdbool.h>    // bool\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// ------------------------------------------------------\n// Standard malloc interface\n// ------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc(size_t size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc(size_t count, size_t size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);\nmi_decl_nodiscard mi_decl_export void* mi_realloc(void* p, size_t newsize)      mi_attr_noexcept mi_attr_alloc_size(2);\nmi_decl_export void* mi_expand(void* p, size_t newsize)                         mi_attr_noexcept mi_attr_alloc_size(2);\n\nmi_decl_export void mi_free(void* p) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept mi_attr_malloc;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept mi_attr_malloc;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept;\n\n// ------------------------------------------------------\n// Extended allocation functions\n// ------------------------------------------------------\n#define MI_SMALL_WSIZE_MAX  (128)\n#define MI_SMALL_SIZE_MAX   (MI_SMALL_WSIZE_MAX*sizeof(void*))\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc(size_t size)       mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);\nmi_decl_nodiscard mi_decl_export void* mi_reallocn(void* p, size_t count, size_t size)        mi_attr_noexcept mi_attr_alloc_size2(2,3);\nmi_decl_nodiscard mi_decl_export void* mi_reallocf(void* p, size_t newsize)                   mi_attr_noexcept mi_attr_alloc_size(2);\n\nmi_decl_nodiscard mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export size_t mi_good_size(size_t size)     mi_attr_noexcept;\n\n// `mi_free_small` is for special applications like language runtimes.\n// it should only be used to free objects from `mi_(heap_)(m|z)alloc_small` and is potentially a tiny bit faster than `mi_free`\nmi_decl_export void mi_free_small(void* p) mi_attr_noexcept;  \n\n// -------------------------------------------------------------------------------------\n// Aligned allocation\n// Note that `alignment` always follows `size` for consistency with unaligned\n// allocation, but unfortunately this differs from `posix_memalign` and `aligned_alloc`.\n// -------------------------------------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1, 2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1, 2);\nmi_decl_nodiscard mi_decl_export void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2);\n\n\n// ------------------------------------------------------\n// Typed allocation, the type is always the first parameter\n// ------------------------------------------------------\n\n#define mi_malloc_tp(tp)                 ((tp*)mi_malloc(sizeof(tp)))\n#define mi_zalloc_tp(tp)                 ((tp*)mi_zalloc(sizeof(tp)))\n#define mi_calloc_tp(tp,n)               ((tp*)mi_calloc(n,sizeof(tp)))\n#define mi_mallocn_tp(tp,n)              ((tp*)mi_mallocn(n,sizeof(tp)))\n#define mi_reallocn_tp(tp,p,n)           ((tp*)mi_reallocn(p,n,sizeof(tp)))\n#define mi_recalloc_tp(tp,p,n)           ((tp*)mi_recalloc(p,n,sizeof(tp)))\n\n#define mi_heap_malloc_tp(tp,hp)         ((tp*)mi_heap_malloc(hp,sizeof(tp)))\n#define mi_heap_zalloc_tp(tp,hp)         ((tp*)mi_heap_zalloc(hp,sizeof(tp)))\n#define mi_heap_calloc_tp(tp,hp,n)       ((tp*)mi_heap_calloc(hp,n,sizeof(tp)))\n#define mi_heap_mallocn_tp(tp,hp,n)      ((tp*)mi_heap_mallocn(hp,n,sizeof(tp)))\n#define mi_heap_reallocn_tp(tp,hp,p,n)   ((tp*)mi_heap_reallocn(hp,p,n,sizeof(tp)))\n#define mi_heap_recalloc_tp(tp,hp,p,n)   ((tp*)mi_heap_recalloc(hp,p,n,sizeof(tp)))\n\n\n// ------------------------------------------------------\n// Internals\n// See also `mimalloc-stats.h` for statistics\n// ------------------------------------------------------\n\ntypedef void (mi_cdecl mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg);\nmi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg) mi_attr_noexcept;\n\ntypedef void (mi_cdecl mi_output_fun)(const char* msg, void* arg);\nmi_decl_export void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept;\n\ntypedef void (mi_cdecl mi_error_fun)(int err, void* arg);\nmi_decl_export void mi_register_error(mi_error_fun* fun, void* arg);\n\nmi_decl_export void mi_collect(bool force)      mi_attr_noexcept;\nmi_decl_export int  mi_version(void)            mi_attr_noexcept;\nmi_decl_export void mi_options_print(void)      mi_attr_noexcept;\nmi_decl_export void mi_process_info_print(void) mi_attr_noexcept;\nmi_decl_export void mi_options_print_out(mi_output_fun* out, void* arg)      mi_attr_noexcept;\nmi_decl_export void mi_process_info_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept;\nmi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs,\n                                    size_t* current_rss, size_t* peak_rss,\n                                    size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept;\n\n\n\n// Generally do not use the following as these are usually called automatically\nmi_decl_export void mi_process_init(void)     mi_attr_noexcept;\nmi_decl_export void mi_cdecl mi_process_done(void) mi_attr_noexcept;\nmi_decl_export void mi_thread_init(void)      mi_attr_noexcept;\nmi_decl_export void mi_thread_done(void)      mi_attr_noexcept;\nmi_decl_export void mi_thread_set_in_threadpool(void) mi_attr_noexcept; // communicate that a thread is in a threadpool\n\n\n// -----------------------------------------------------------------\n// Return allocated block size (if the return value is not NULL)\n// -----------------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_umalloc(size_t size, size_t* block_size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_ucalloc(size_t count, size_t size, size_t* block_size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);\nmi_decl_nodiscard mi_decl_export void* mi_urealloc(void* p, size_t newsize, size_t* block_size_pre, size_t* block_size_post) mi_attr_noexcept mi_attr_alloc_size(2);\nmi_decl_export void mi_ufree(void* p, size_t* block_size) mi_attr_noexcept;\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_umalloc_aligned(size_t size, size_t alignment, size_t* block_size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_uzalloc_aligned(size_t size, size_t alignment, size_t* block_size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_umalloc_small(size_t size, size_t* block_size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_uzalloc_small(size_t size, size_t* block_size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\n\n\n// -------------------------------------------------------------------------------------\n// Heaps: first-class. Can allocate from any thread (and be free'd from any thread)\n// Heaps keep allocations in separate pages from each other (but share the arena's and free'd pages)\n// -------------------------------------------------------------------------------------\n\nstruct mi_heap_s;\ntypedef struct mi_heap_s mi_heap_t;\n\nmi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new(void);\nmi_decl_export void mi_heap_delete(mi_heap_t* heap);            // move live blocks to the main heap\nmi_decl_export void mi_heap_destroy(mi_heap_t* heap);           // free all live blocks\nmi_decl_export void mi_heap_set_numa_affinity(mi_heap_t* heap, int numa_node);\nmi_decl_export void mi_heap_collect(mi_heap_t* heap, bool force);\n\nmi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_main(void);\nmi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_of(const void* p);\nmi_decl_nodiscard mi_decl_export bool       mi_heap_contains(const mi_heap_t* heap, const void* p);\nmi_decl_nodiscard mi_decl_export bool       mi_any_heap_contains(const void* p);\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc(mi_heap_t* theap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\n\nmi_decl_nodiscard mi_decl_export void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize)              mi_attr_noexcept mi_attr_alloc_size(3);\nmi_decl_nodiscard mi_decl_export void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size)  mi_attr_noexcept mi_attr_alloc_size2(3, 4);\nmi_decl_nodiscard mi_decl_export void* mi_heap_reallocf(mi_heap_t* theap, void* p, size_t newsize)            mi_attr_noexcept mi_attr_alloc_size(3);\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s)            mi_attr_noexcept mi_attr_malloc;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept mi_attr_malloc;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept;\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3) mi_attr_alloc_align(4);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);\nmi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4);\nmi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3);\n\n\n// --------------------------------------------------------------------------------\n// Zero initialized re-allocation.\n// Only valid on memory that was originally allocated with zero initialization too.\n// e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc.\n// see <https://github.com/microsoft/mimalloc/issues/63#issuecomment-508272992>\n// --------------------------------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_export void* mi_rezalloc(void* p, size_t newsize)                mi_attr_noexcept mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export void* mi_recalloc(void* p, size_t newcount, size_t size)  mi_attr_noexcept mi_attr_alloc_size2(2,3);\n\nmi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(2,3) mi_attr_alloc_align(4);\nmi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(2,3);\n\nmi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize)                mi_attr_noexcept mi_attr_alloc_size(3);\nmi_decl_nodiscard mi_decl_export void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size)  mi_attr_noexcept mi_attr_alloc_size2(3, 4);\n\nmi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4);\nmi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3);\nmi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(3, 4) mi_attr_alloc_align(5);\nmi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(3, 4);\n\n\n\n// ------------------------------------------------------\n// Visiting pages and individual blocks in a heap.\n// ------------------------------------------------------\n\n// An area of heap space contains blocks of a single size.\ntypedef struct mi_heap_area_s {\n  void*  blocks;      // start of the area containing theap blocks\n  size_t reserved;    // bytes reserved for this area (virtual)\n  size_t committed;   // current available bytes for this area\n  size_t used;        // number of allocated blocks\n  size_t block_size;  // size in bytes of each block\n  size_t full_block_size; // size in bytes of a full block including padding and metadata.\n  void*  reserved1;   // internal\n} mi_heap_area_t;\n\ntypedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg);\n\nmi_decl_export bool   mi_heap_visit_blocks(mi_heap_t* heap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg);\nmi_decl_export bool   mi_heap_visit_abandoned_blocks(mi_heap_t* heap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg);\n\n\n// ------------------------------------------------------\n// Arena memory management\n// Arena's are larger memory area's provided by the OS or user\n// ------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_export bool mi_is_redirected(void) mi_attr_noexcept;\n\nmi_decl_export int    mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept;\nmi_decl_export int    mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept;\n\nmi_decl_export int    mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept;\nmi_decl_export bool   mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_pinned /* cannot decommit/reset? */, bool is_zero, int numa_node) mi_attr_noexcept;\n\nmi_decl_export void   mi_debug_show_arenas(void) mi_attr_noexcept;\nmi_decl_export void   mi_arenas_print(void) mi_attr_noexcept;\nmi_decl_export size_t mi_arena_min_alignment(void);\nmi_decl_export size_t mi_arena_min_size(void);\n\ntypedef void* mi_arena_id_t;\nmi_decl_export void*  mi_arena_area(mi_arena_id_t arena_id, size_t* size);\nmi_decl_export int    mi_reserve_huge_os_pages_at_ex(size_t pages, int numa_node, size_t timeout_msecs, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept;\nmi_decl_export int    mi_reserve_os_memory_ex(size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept;\nmi_decl_export bool   mi_manage_os_memory_ex(void* start, size_t size, bool is_committed, bool is_pinned, bool is_zero, int numa_node, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept;\nmi_decl_export bool   mi_arena_contains(mi_arena_id_t arena_id, const void* p);\n\n// Create a heap that only allocates in the specified arena\nmi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new_in_arena(mi_arena_id_t arena_id);\n\n\n// ------------------------------------------------------\n// Subprocesses\n// Advanced: allow sub-processes whose memory arena's stay fully separated (and no reclamation between them).\n// Used for example for separate interpreters in one process.\n// ------------------------------------------------------\n\ntypedef struct { void* _mi_subproc_id; } mi_subproc_id_t;  // abstract type\nmi_decl_export mi_subproc_id_t mi_subproc_main(void);\nmi_decl_export mi_subproc_id_t mi_subproc_current(void);\nmi_decl_export mi_subproc_id_t mi_subproc_new(void);\nmi_decl_export void mi_subproc_destroy(mi_subproc_id_t subproc);\nmi_decl_export void mi_subproc_add_current_thread(mi_subproc_id_t subproc); // this should be called right after a thread is created (and no allocation has taken place yet)\n\ntypedef bool (mi_cdecl mi_heap_visit_fun)(mi_heap_t* heap, void* arg);\nmi_decl_export bool mi_subproc_visit_heaps(mi_subproc_id_t subproc, mi_heap_visit_fun* visitor, void* arg);\n\n\n// -------------------------------------------------------------------------------------\n// A \"theap\" is a thread-local heap. This API is only provided for special circumstances like runtimes\n// that already have a thread-local context and can store the theap there for (slightly) faster allocations.\n// This also allows to set a default theap for the current thread so that `malloc` etc. allocate from\n// that theap (instead of the main (t)heap).\n// Theaps are first-class, but can only allocate from the same thread that created it.\n// Allocation through a `theap` may be a tiny bit faster than using plain malloc\n// (as we don't need to lookup the thread local variable).\n// -------------------------------------------------------------------------------------\n\nstruct mi_theap_s;\ntypedef struct mi_theap_s mi_theap_t;\n\nmi_decl_export mi_theap_t* mi_heap_theap(mi_heap_t* heap);\nmi_decl_export mi_theap_t* mi_theap_set_default(mi_theap_t* theap);\nmi_decl_export mi_theap_t* mi_theap_get_default(void);\nmi_decl_export void        mi_theap_collect(mi_theap_t* theap, bool force) mi_attr_noexcept;\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_theap_malloc(mi_theap_t* theap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_theap_zalloc(mi_theap_t* theap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_theap_calloc(mi_theap_t* theap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_theap_malloc_small(mi_theap_t* theap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_theap_zalloc_small(mi_theap_t* theap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_theap_malloc_aligned(mi_theap_t* theap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3);\nmi_decl_nodiscard mi_decl_export                  void* mi_theap_realloc(mi_theap_t* theap, void* p, size_t newsize)              mi_attr_noexcept mi_attr_alloc_size(3);\n\n\n// ------------------------------------------------------\n// Experimental\n// ------------------------------------------------------\n\n// Experimental: objects followed by a guard page.\n// Setting the sample rate on a specific theap can be used to test parts of the program more\n// specifically (in combination with `mi_theap_set_default`).\n// A sample rate of 0 disables guarded objects, while 1 uses a guard page for every object.\n// A seed of 0 uses a random start point. Only objects within the size bound are eligable for guard pages.\nmi_decl_export void mi_theap_guarded_set_sample_rate(mi_theap_t* theap, size_t sample_rate, size_t seed);\nmi_decl_export void mi_theap_guarded_set_size_bound(mi_theap_t* theap, size_t min, size_t max);\n\n// very experimental\ntypedef bool (mi_cdecl mi_commit_fun_t)(bool commit, void* start, size_t size, bool* is_zero, void* user_arg);\nmi_decl_export bool  mi_manage_memory(void* start, size_t size, bool is_committed, bool is_pinned, bool is_zero, int numa_node, bool exclusive,\n                                      mi_commit_fun_t* commit_fun, void* commit_fun_arg, mi_arena_id_t* arena_id) mi_attr_noexcept;\n\n//mi_decl_export bool  mi_arena_unload(mi_arena_id_t arena_id, void** base, size_t* accessed_size, size_t* size);\n//mi_decl_export bool  mi_arena_reload(void* start, size_t size, mi_commit_fun_t* commit_fun, void* commit_fun_arg, mi_arena_id_t* arena_id);\n//mi_decl_export bool  mi_theap_reload(mi_theap_t* theap, mi_arena_id_t arena);\n//mi_decl_export void  mi_theap_unload(mi_theap_t* theap);\n\n// unsafe: assumes the page belonging to `p` is only accessed by the calling thread.\nmi_decl_export bool mi_unsafe_heap_page_is_under_utilized(mi_heap_t* heap, void* p, size_t perc_threshold) mi_attr_noexcept;\n\n// ------------------------------------------------------\n// Deprecated\n// ------------------------------------------------------\n\nmi_decl_export bool mi_check_owned(const void* p);\n\nmi_decl_export void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept;\nmi_decl_export bool mi_theap_visit_blocks(const mi_theap_t* theap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg);\n\nmi_decl_export int  mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept;\nmi_decl_export void mi_collect_reduce(size_t target_thread_owned) mi_attr_noexcept;\n\nmi_decl_export void mi_stats_reset(void)      mi_attr_noexcept;\nmi_decl_export void mi_stats_merge(void)      mi_attr_noexcept;\nmi_decl_export void mi_stats_print(void* out) mi_attr_noexcept;  // backward compatibility: `out` is ignored and should be NULL\n\nmi_decl_export void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept;  // not deprecated but declared in `mimalloc-stats.h` now.\n\n\n// ------------------------------------------------------\n// Options\n// ------------------------------------------------------\n\ntypedef enum mi_option_e {\n  // stable options\n  mi_option_show_errors,                // print error messages\n  mi_option_show_stats,                 // print statistics on termination\n  mi_option_verbose,                    // print verbose messages\n  // advanced options\n  mi_option_deprecated_eager_commit,    \n  mi_option_arena_eager_commit,         // eager commit arenas? Use 2 to enable just on overcommit systems (=2)\n  mi_option_purge_decommits,            // should a memory purge decommit? (=1). Set to 0 to use memory reset on a purge (instead of decommit)\n  mi_option_allow_large_os_pages,       // allow use of large (2 or 4 MiB) OS pages, implies eager commit.\n  mi_option_reserve_huge_os_pages,      // reserve N huge OS pages (1GiB pages) at startup\n  mi_option_reserve_huge_os_pages_at,   // reserve huge OS pages at a specific NUMA node\n  mi_option_reserve_os_memory,          // reserve specified amount of OS memory in an arena at startup (internally, this value is in KiB; use `mi_option_get_size`)\n  mi_option_deprecated_segment_cache,\n  mi_option_deprecated_page_reset,\n  mi_option_deprecated_abandoned_page_purge,\n  mi_option_deprecated_segment_reset,\n  mi_option_deprecated_eager_commit_delay, \n  mi_option_purge_delay,                // memory purging is delayed by N milli seconds; use 0 for immediate purging or -1 for no purging at all. (=10)\n  mi_option_use_numa_nodes,             // 0 = use all available numa nodes, otherwise use at most N nodes.\n  mi_option_disallow_os_alloc,          // 1 = do not use OS memory for allocation (but only programmatically reserved arenas)\n  mi_option_os_tag,                     // tag used for OS logging (macOS only for now) (=100)\n  mi_option_max_errors,                 // issue at most N error messages\n  mi_option_max_warnings,               // issue at most N warning messages\n  mi_option_deprecated_max_segment_reclaim,  // max. percentage of the abandoned segments can be reclaimed per try (=10%)\n  mi_option_destroy_on_exit,            // if set, release all memory on exit; sometimes used for dynamic unloading but can be unsafe\n  mi_option_arena_reserve,              // initial memory size for arena reservation (= 1 GiB on 64-bit) (internally, this value is in KiB; use `mi_option_get_size`)\n  mi_option_arena_purge_mult,           // multiplier for `purge_delay` for the purging delay for arenas (=10)\n  mi_option_deprecated_purge_extend_delay,\n  mi_option_disallow_arena_alloc,       // 1 = do not use arena's for allocation (except if using specific arena id's)\n  mi_option_retry_on_oom,               // retry on out-of-memory for N milli seconds (=400), set to 0 to disable retries. (only on windows)\n  mi_option_visit_abandoned,            // allow visiting theap blocks from abandoned threads (=0)\n  mi_option_guarded_min,                // only used when building with MI_GUARDED: minimal rounded object size for guarded objects (=0)\n  mi_option_guarded_max,                // only used when building with MI_GUARDED: maximal rounded object size for guarded objects (=0)\n  mi_option_guarded_precise,            // disregard minimal alignment requirement to always place guarded blocks exactly in front of a guard page (=0)\n  mi_option_guarded_sample_rate,        // 1 out of N allocations in the min/max range will be guarded (=1000)\n  mi_option_guarded_sample_seed,        // can be set to allow for a (more) deterministic re-execution when a guard page is triggered (=0)\n  mi_option_generic_collect,            // collect theaps every N (=10000) generic allocation calls\n  mi_option_page_reclaim_on_free,       // reclaim abandoned pages on a free (=0). -1 disallowr always, 0 allows if the page originated from the current theap, 1 allow always\n  mi_option_page_full_retain,           // retain N full (small) pages per size class (=2)\n  mi_option_page_max_candidates,        // max candidate pages to consider for allocation (=4)\n  mi_option_max_vabits,                 // max user space virtual address bits to consider (=48)\n  mi_option_pagemap_commit,             // commit the full pagemap (to always catch invalid pointer uses) (=0)\n  mi_option_page_commit_on_demand,      // commit page memory on-demand\n  mi_option_page_max_reclaim,           // don't reclaim pages of the same originating theap if we already own N pages (in that size class) (=-1 (unlimited))\n  mi_option_page_cross_thread_max_reclaim, // don't reclaim pages across threads if we already own N pages (in that size class) (=16)\n  mi_option_allow_thp,                  // allow transparent huge pages? (=1) (on Android =0 by default). Set to 0 to disable THP for the process.\n  mi_option_minimal_purge_size,         // set minimal purge size (in KiB) (=0). By default set to either 64 or 2048 if THP is enabled.\n  mi_option_arena_max_object_size,      // set maximal object size that can be allocated in an arena (in KiB) (=2GiB on 64-bit). \n  mi_option_arena_is_numa_local,        // experimental\n  _mi_option_last,\n  // legacy option names\n  mi_option_large_os_pages = mi_option_allow_large_os_pages,\n  mi_option_eager_region_commit = mi_option_arena_eager_commit,\n  mi_option_reset_decommits = mi_option_purge_decommits,\n  mi_option_reset_delay = mi_option_purge_delay,\n  mi_option_limit_os_alloc = mi_option_disallow_os_alloc\n} mi_option_t;\n\n\nmi_decl_nodiscard mi_decl_export bool mi_option_is_enabled(mi_option_t option);\nmi_decl_export void mi_option_enable(mi_option_t option);\nmi_decl_export void mi_option_disable(mi_option_t option);\nmi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable);\nmi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable);\n\nmi_decl_nodiscard mi_decl_export long   mi_option_get(mi_option_t option);\nmi_decl_nodiscard mi_decl_export long   mi_option_get_clamp(mi_option_t option, long min, long max);\nmi_decl_nodiscard mi_decl_export size_t mi_option_get_size(mi_option_t option);\nmi_decl_export void mi_option_set(mi_option_t option, long value);\nmi_decl_export void mi_option_set_default(mi_option_t option, long value);\n\n\n// -------------------------------------------------------------------------------------------------------\n// \"mi\" prefixed implementations of various posix, Unix, Windows, and C++ allocation functions.\n// (This can be convenient when providing overrides of these functions as done in `mimalloc-override.h`.)\n// note: we use `mi_cfree` as \"checked free\" and it checks if the pointer is in our theap before free-ing.\n// -------------------------------------------------------------------------------------------------------\n\nmi_decl_export void  mi_cfree(void* p) mi_attr_noexcept;\nmi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export size_t mi_malloc_size(const void* p)        mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export size_t mi_malloc_good_size(size_t size)     mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept;\n\nmi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size)   mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_valloc(size_t size)  mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1);\n\nmi_decl_nodiscard mi_decl_export void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3);\nmi_decl_nodiscard mi_decl_export int   mi_reallocarr(void* ptrp, size_t count, size_t size) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept;\n\nmi_decl_export void mi_free_size(void* p, size_t size)                           mi_attr_noexcept;\nmi_decl_export void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept;\nmi_decl_export void mi_free_aligned(void* p, size_t alignment)                   mi_attr_noexcept;\nmi_decl_export int  mi_dupenv_s(char** buf, size_t* size, const char* name)      mi_attr_noexcept;\n\n// wide characters\n#include <wchar.h>  // wchar_t\nmi_decl_export int mi_wdupenv_s(wchar_t** buf, size_t* size, const wchar_t* name)       mi_attr_noexcept;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict wchar_t* mi_wcsdup(const wchar_t* s)  mi_attr_noexcept mi_attr_malloc;\nmi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s)  mi_attr_noexcept mi_attr_malloc;\n\n// The `mi_new` wrappers implement C++ semantics on out-of-memory instead of directly returning `NULL`.\n// (and call `std::get_new_handler` and potentially raise a `std::bad_alloc` exception).\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new(size_t size)                   mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_nothrow(size_t size)           mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_n(size_t count, size_t size)   mi_attr_malloc mi_attr_alloc_size2(1, 2);\nmi_decl_nodiscard mi_decl_export void* mi_new_realloc(void* p, size_t newsize)                mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export void* mi_new_reallocn(void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3);\n\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_alloc_new(mi_heap_t* heap, size_t size)                 mi_attr_malloc mi_attr_alloc_size(2);\nmi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_alloc_new_n(mi_heap_t* heap, size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(2, 3);\n\n#ifdef __cplusplus\n}\n#endif\n\n// ---------------------------------------------------------------------------------------------\n// Implement the C++ std::allocator interface for use in STL containers.\n// (note: see `mimalloc-new-delete.h` for overriding the new/delete operators globally)\n// ---------------------------------------------------------------------------------------------\n#ifdef __cplusplus\n\n#include <cstddef>     // std::size_t\n#include <cstdint>     // PTRDIFF_MAX\n#if (__cplusplus >= 201103L) || (_MSC_VER > 1900)  // C++11\n#include <type_traits> // std::true_type\n#include <utility>     // std::forward\n#endif\n\ntemplate<class T> struct _mi_stl_allocator_common {\n  typedef T                 value_type;\n  typedef std::size_t       size_type;\n  typedef std::ptrdiff_t    difference_type;\n  typedef value_type&       reference;\n  typedef value_type const& const_reference;\n  typedef value_type*       pointer;\n  typedef value_type const* const_pointer;\n\n  #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900))  // C++11\n  using propagate_on_container_copy_assignment = std::true_type;\n  using propagate_on_container_move_assignment = std::true_type;\n  using propagate_on_container_swap            = std::true_type;\n  template <class U, class ...Args> void construct(U* p, Args&& ...args) { ::new(p) U(std::forward<Args>(args)...); }\n  template <class U> void destroy(U* p) mi_attr_noexcept { p->~U(); }\n  #else\n  void construct(pointer p, value_type const& val) { ::new(p) value_type(val); }\n  void destroy(pointer p) { p->~value_type(); }\n  #endif\n\n  size_type     max_size() const mi_attr_noexcept { return (PTRDIFF_MAX/sizeof(value_type)); }\n  pointer       address(reference x) const        { return &x; }\n  const_pointer address(const_reference x) const  { return &x; }\n};\n\ntemplate<class T> struct mi_stl_allocator : public _mi_stl_allocator_common<T> {\n  using typename _mi_stl_allocator_common<T>::size_type;\n  using typename _mi_stl_allocator_common<T>::value_type;\n  using typename _mi_stl_allocator_common<T>::pointer;\n  template <class U> struct rebind { typedef mi_stl_allocator<U> other; };\n\n  mi_stl_allocator()                                             mi_attr_noexcept = default;\n  mi_stl_allocator(const mi_stl_allocator&)                      mi_attr_noexcept = default;\n  template<class U> mi_stl_allocator(const mi_stl_allocator<U>&) mi_attr_noexcept { }\n  mi_stl_allocator  select_on_container_copy_construction() const { return *this; }\n  void              deallocate(T* p, size_type) { mi_free(p); }\n\n  #if (__cplusplus >= 201703L)  // C++17\n  mi_decl_nodiscard T* allocate(size_type count) { return static_cast<T*>(mi_new_n(count, sizeof(T))); }\n  mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); }\n  #else\n  mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast<pointer>(mi_new_n(count, sizeof(value_type))); }\n  #endif\n\n  #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900))  // C++11\n  using is_always_equal = std::true_type;\n  #endif\n};\n\ntemplate<class T1,class T2> bool operator==(const mi_stl_allocator<T1>& , const mi_stl_allocator<T2>& ) mi_attr_noexcept { return true; }\ntemplate<class T1,class T2> bool operator!=(const mi_stl_allocator<T1>& , const mi_stl_allocator<T2>& ) mi_attr_noexcept { return false; }\n\n\n#if (__cplusplus >= 201103L) || (_MSC_VER >= 1900)  // C++11\n#define MI_HAS_HEAP_STL_ALLOCATOR 1\n\n#include <memory>      // std::shared_ptr\n\n// Common base class for STL allocators in a specific theap\ntemplate<class T, bool _mi_destroy> struct _mi_heap_stl_allocator_common : public _mi_stl_allocator_common<T> {\n  using typename _mi_stl_allocator_common<T>::size_type;\n  using typename _mi_stl_allocator_common<T>::value_type;\n  using typename _mi_stl_allocator_common<T>::pointer;\n\n  _mi_heap_stl_allocator_common(mi_heap_t* hp) : heap(hp, [](mi_heap_t*) {}) {}    /* will not delete nor destroy the passed in heap */\n\n  #if (__cplusplus >= 201703L)  // C++17\n  mi_decl_nodiscard T* allocate(size_type count) { return static_cast<T*>(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(T))); }\n  mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); }\n  #else\n  mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast<pointer>(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(value_type))); }\n  #endif\n\n  #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900))  // C++11\n  using is_always_equal = std::false_type;\n  #endif\n\n  void collect(bool force) { mi_heap_collect(this->heap.get(), force); }\n  template<class U> bool is_equal(const _mi_heap_stl_allocator_common<U, _mi_destroy>& x) const { return (this->heap == x.heap); }\n\nprotected:\n  std::shared_ptr<mi_heap_t> heap;\n  template<class U, bool D> friend struct _mi_heap_stl_allocator_common;\n\n  _mi_heap_stl_allocator_common() {\n    mi_heap_t* hp = mi_heap_new();\n    this->heap.reset(hp, (_mi_destroy ? &heap_destroy : &heap_delete));  /* calls heap_delete/destroy when the refcount drops to zero */\n  }\n  _mi_heap_stl_allocator_common(const _mi_heap_stl_allocator_common& x) mi_attr_noexcept : heap(x.heap) { }\n  template<class U> _mi_heap_stl_allocator_common(const _mi_heap_stl_allocator_common<U, _mi_destroy>& x) mi_attr_noexcept : heap(x.heap) { }\n\nprivate:\n  static void heap_delete(mi_heap_t* hp)  { if (hp != NULL) { mi_heap_delete(hp); } }\n  static void heap_destroy(mi_heap_t* hp) { if (hp != NULL) { mi_heap_destroy(hp); } }\n};\n\n// STL allocator allocation in a specific heap\ntemplate<class T> struct mi_heap_stl_allocator : public _mi_heap_stl_allocator_common<T, false> {\n  using typename _mi_heap_stl_allocator_common<T, false>::size_type;\n  mi_heap_stl_allocator() : _mi_heap_stl_allocator_common<T, false>() { } // creates fresh heap that is deleted when the destructor is called\n  mi_heap_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, false>(hp) { }  // no delete nor destroy on the passed in heap\n  template<class U> mi_heap_stl_allocator(const mi_heap_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, false>(x) { }\n\n  mi_heap_stl_allocator select_on_container_copy_construction() const { return *this; }\n  void deallocate(T* p, size_type) { mi_free(p); }\n  template<class U> struct rebind { typedef mi_heap_stl_allocator<U> other; };\n};\n\ntemplate<class T1, class T2> bool operator==(const mi_heap_stl_allocator<T1>& x, const mi_heap_stl_allocator<T2>& y) mi_attr_noexcept { return (x.is_equal(y)); }\ntemplate<class T1, class T2> bool operator!=(const mi_heap_stl_allocator<T1>& x, const mi_heap_stl_allocator<T2>& y) mi_attr_noexcept { return (!x.is_equal(y)); }\n\n\n// STL allocator allocation in a specific heap, where `free` does nothing and\n// the heap is destroyed in one go on destruction -- use with care!\ntemplate<class T> struct mi_heap_destroy_stl_allocator : public _mi_heap_stl_allocator_common<T, true> {\n  using typename _mi_heap_stl_allocator_common<T, true>::size_type;\n  mi_heap_destroy_stl_allocator() : _mi_heap_stl_allocator_common<T, true>() { } // creates fresh heap that is destroyed when the destructor is called\n  mi_heap_destroy_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, true>(hp) { }  // no delete nor destroy on the passed in heap\n  template<class U> mi_heap_destroy_stl_allocator(const mi_heap_destroy_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, true>(x) { }\n\n  mi_heap_destroy_stl_allocator select_on_container_copy_construction() const { return *this; }\n  void deallocate(T*, size_type) { /* do nothing as we destroy the heap on destruct. */ }\n  template<class U> struct rebind { typedef mi_heap_destroy_stl_allocator<U> other; };\n};\n\ntemplate<class T1, class T2> bool operator==(const mi_heap_destroy_stl_allocator<T1>& x, const mi_heap_destroy_stl_allocator<T2>& y) mi_attr_noexcept { return (x.is_equal(y)); }\ntemplate<class T1, class T2> bool operator!=(const mi_heap_destroy_stl_allocator<T1>& x, const mi_heap_destroy_stl_allocator<T2>& y) mi_attr_noexcept { return (!x.is_equal(y)); }\n\n#endif // C++11\n\n#endif // __cplusplus\n\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/include/mimalloc/atomic.h",
      "sha256": "e9512b521a82cc0cbc262f6060dd70bb4243ac4a7d69d6ab8b1ef8e56f181a21",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2024 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MI_ATOMIC_H\n#define MI_ATOMIC_H\n\n// include windows.h or pthreads.h\n#if defined(_WIN32)\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#include <windows.h>\n#elif !defined(__wasi__) && (!defined(__EMSCRIPTEN__) || defined(__EMSCRIPTEN_PTHREADS__))\n#define  MI_USE_PTHREADS\n#include <pthread.h>\n#endif\n\n// --------------------------------------------------------------------------------------------\n// Atomics\n// We need to be portable between C, C++, and MSVC.\n// We base the primitives on the C/C++ atomics and create a minimal wrapper for MSVC in C compilation mode.\n// This is why we try to use only `uintptr_t` and `<type>*` as atomic types.\n// To gain better insight in the range of used atomics, we use explicitly named memory order operations\n// instead of passing the memory order as a parameter.\n// -----------------------------------------------------------------------------------------------\n\n#if defined(__cplusplus)\n// Use C++ atomics\n#include <atomic>\n#define  _Atomic(tp)              std::atomic<tp>\n#define  mi_atomic(name)          std::atomic_##name\n#define  mi_memory_order(name)    std::memory_order_##name\n#if (__cplusplus >= 202002L)      // c++20, see issue #571\n #define MI_ATOMIC_VAR_INIT(x)    x\n#elif !defined(ATOMIC_VAR_INIT)\n #define MI_ATOMIC_VAR_INIT(x)    x\n#else\n #define MI_ATOMIC_VAR_INIT(x)    ATOMIC_VAR_INIT(x)\n#endif\n#elif defined(_MSC_VER)\n// Use MSVC C wrapper for C11 atomics\n#define  _Atomic(tp)              tp\n#define  MI_ATOMIC_VAR_INIT(x)    x\n#define  mi_atomic(name)          mi_atomic_##name\n#define  mi_memory_order(name)    mi_memory_order_##name\n#else\n// Use C11 atomics\n#include <stdatomic.h>\n#define  mi_atomic(name)          atomic_##name\n#define  mi_memory_order(name)    memory_order_##name\n#if (__STDC_VERSION__ >= 201710L) // c17, see issue #735\n #define MI_ATOMIC_VAR_INIT(x)    x\n#elif !defined(ATOMIC_VAR_INIT)\n #define MI_ATOMIC_VAR_INIT(x)    x\n#else\n #define MI_ATOMIC_VAR_INIT(x)    ATOMIC_VAR_INIT(x)\n#endif\n#endif\n\n// Various defines for all used memory orders in mimalloc\n#define mi_atomic_cas_weak(p,expected,desired,mem_success,mem_fail)  \\\n  mi_atomic(compare_exchange_weak_explicit)(p,expected,desired,mem_success,mem_fail)\n\n#define mi_atomic_cas_strong(p,expected,desired,mem_success,mem_fail)  \\\n  mi_atomic(compare_exchange_strong_explicit)(p,expected,desired,mem_success,mem_fail)\n\n#define mi_atomic_load_acquire(p)                mi_atomic(load_explicit)(p,mi_memory_order(acquire))\n#define mi_atomic_load_relaxed(p)                mi_atomic(load_explicit)(p,mi_memory_order(relaxed))\n#define mi_atomic_store_release(p,x)             mi_atomic(store_explicit)(p,x,mi_memory_order(release))\n#define mi_atomic_store_relaxed(p,x)             mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed))\n#define mi_atomic_exchange_relaxed(p,x)          mi_atomic(exchange_explicit)(p,x,mi_memory_order(relaxed))\n#define mi_atomic_exchange_release(p,x)          mi_atomic(exchange_explicit)(p,x,mi_memory_order(release))\n#define mi_atomic_exchange_acq_rel(p,x)          mi_atomic(exchange_explicit)(p,x,mi_memory_order(acq_rel))\n\n#define mi_atomic_cas_weak_relaxed(p,exp,des)    mi_atomic_cas_weak(p,exp,des,mi_memory_order(relaxed),mi_memory_order(relaxed))\n#define mi_atomic_cas_weak_release(p,exp,des)    mi_atomic_cas_weak(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed))\n#define mi_atomic_cas_weak_acq_rel(p,exp,des)    mi_atomic_cas_weak(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire))\n#define mi_atomic_cas_strong_relaxed(p,exp,des)  mi_atomic_cas_strong(p,exp,des,mi_memory_order(relaxed),mi_memory_order(relaxed))\n#define mi_atomic_cas_strong_release(p,exp,des)  mi_atomic_cas_strong(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed))\n#define mi_atomic_cas_strong_acq_rel(p,exp,des)  mi_atomic_cas_strong(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire))\n\n#define mi_atomic_add_relaxed(p,x)               mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(relaxed))\n#define mi_atomic_add_acq_rel(p,x)               mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(acq_rel))\n#define mi_atomic_sub_relaxed(p,x)               mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(relaxed))\n#define mi_atomic_sub_acq_rel(p,x)               mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(acq_rel))\n#define mi_atomic_and_relaxed(p,x)               mi_atomic(fetch_and_explicit)(p,x,mi_memory_order(relaxed))\n#define mi_atomic_and_acq_rel(p,x)               mi_atomic(fetch_and_explicit)(p,x,mi_memory_order(acq_rel))\n#define mi_atomic_or_relaxed(p,x)                mi_atomic(fetch_or_explicit)(p,x,mi_memory_order(relaxed))\n#define mi_atomic_or_acq_rel(p,x)                mi_atomic(fetch_or_explicit)(p,x,mi_memory_order(acq_rel))\n\n#define mi_atomic_increment_relaxed(p)           mi_atomic_add_relaxed(p,(uintptr_t)1)\n#define mi_atomic_decrement_relaxed(p)           mi_atomic_sub_relaxed(p,(uintptr_t)1)\n#define mi_atomic_increment_acq_rel(p)           mi_atomic_add_acq_rel(p,(uintptr_t)1)\n#define mi_atomic_decrement_acq_rel(p)           mi_atomic_sub_acq_rel(p,(uintptr_t)1)\n\nstatic inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add);\nstatic inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub);\n\n\n#if defined(__cplusplus) || !defined(_MSC_VER)\n\n// In C++/C11 atomics we have polymorphic atomics so can use the typed `ptr` variants (where `tp` is the type of atomic value)\n// We use these macros so we can provide a typed wrapper in MSVC in C compilation mode as well\n#define mi_atomic_load_ptr_acquire(tp,p)                mi_atomic_load_acquire(p)\n#define mi_atomic_load_ptr_relaxed(tp,p)                mi_atomic_load_relaxed(p)\n\n// In C++ we need to add casts to help resolve templates if NULL is passed\n#if defined(__cplusplus)\n#define mi_atomic_store_ptr_release(tp,p,x)             mi_atomic_store_release(p,(tp*)x)\n#define mi_atomic_store_ptr_relaxed(tp,p,x)             mi_atomic_store_relaxed(p,(tp*)x)\n#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des)    mi_atomic_cas_weak_release(p,exp,(tp*)des)\n#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des)    mi_atomic_cas_weak_acq_rel(p,exp,(tp*)des)\n#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des)  mi_atomic_cas_strong_release(p,exp,(tp*)des)\n#define mi_atomic_cas_ptr_strong_acq_rel(tp,p,exp,des)  mi_atomic_cas_strong_acq_rel(p,exp,(tp*)des)\n#define mi_atomic_exchange_ptr_relaxed(tp,p,x)          mi_atomic_exchange_relaxed(p,(tp*)x)\n#define mi_atomic_exchange_ptr_release(tp,p,x)          mi_atomic_exchange_release(p,(tp*)x)\n#define mi_atomic_exchange_ptr_acq_rel(tp,p,x)          mi_atomic_exchange_acq_rel(p,(tp*)x)\n#else\n#define mi_atomic_store_ptr_release(tp,p,x)             mi_atomic_store_release(p,x)\n#define mi_atomic_store_ptr_relaxed(tp,p,x)             mi_atomic_store_relaxed(p,x)\n#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des)    mi_atomic_cas_weak_release(p,exp,des)\n#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des)    mi_atomic_cas_weak_acq_rel(p,exp,des)\n#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des)  mi_atomic_cas_strong_release(p,exp,des)\n#define mi_atomic_cas_ptr_strong_acq_rel(tp,p,exp,des)  mi_atomic_cas_strong_acq_rel(p,exp,des)\n#define mi_atomic_exchange_ptr_relaxed(tp,p,x)          mi_atomic_exchange_relaxed(p,x)\n#define mi_atomic_exchange_ptr_release(tp,p,x)          mi_atomic_exchange_release(p,x)\n#define mi_atomic_exchange_ptr_acq_rel(tp,p,x)          mi_atomic_exchange_acq_rel(p,x)\n#endif\n\n// These are used by the statistics\nstatic inline int64_t mi_atomic_addi64_relaxed(volatile int64_t* p, int64_t add) {\n  return mi_atomic(fetch_add_explicit)((_Atomic(int64_t)*)p, add, mi_memory_order(relaxed));\n}\nstatic inline void mi_atomic_void_addi64_relaxed(volatile int64_t* p, const volatile int64_t* padd) {\n  const int64_t add = mi_atomic_load_relaxed((_Atomic(int64_t)*)padd);\n  if (add != 0) {\n    mi_atomic(fetch_add_explicit)((_Atomic(int64_t)*)p, add, mi_memory_order(relaxed));\n  }\n}\nstatic inline void mi_atomic_maxi64_relaxed(volatile int64_t* p, int64_t x) {\n  int64_t current = mi_atomic_load_relaxed((_Atomic(int64_t)*)p);\n  while (current < x && !mi_atomic_cas_weak_release((_Atomic(int64_t)*)p, &current, x)) { /* nothing */ };\n}\n\n// Used by timers\n#define mi_atomic_loadi64_acquire(p)            mi_atomic(load_explicit)(p,mi_memory_order(acquire))\n#define mi_atomic_loadi64_relaxed(p)            mi_atomic(load_explicit)(p,mi_memory_order(relaxed))\n#define mi_atomic_storei64_release(p,x)         mi_atomic(store_explicit)(p,x,mi_memory_order(release))\n#define mi_atomic_storei64_relaxed(p,x)         mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed))\n\n#define mi_atomic_casi64_strong_acq_rel(p,e,d)  mi_atomic_cas_strong_acq_rel(p,e,d)\n#define mi_atomic_addi64_acq_rel(p,i)           mi_atomic_add_acq_rel(p,i)\n\n\n#elif defined(_MSC_VER)\n\n// Deprecated: MSVC plain C compilation wrapper that uses Interlocked operations to model C11 atomics.\n// It is recommended to always compile as C++ when using MSVC.\n\n#include <intrin.h>\n#ifdef _WIN64\ntypedef LONG64        msc_intptr_t;\n#define MI_MSC_64(f)  f##64\n#define MI_MSC_XX(f)  f##64\n#else\ntypedef LONG          msc_intptr_t;\n#define MI_MSC_64(f)  f\n#define MI_MSC_XX(f)  f##32\n#endif\n\ntypedef enum mi_memory_order_e {\n  mi_memory_order_relaxed,\n  mi_memory_order_consume,\n  mi_memory_order_acquire,\n  mi_memory_order_release,\n  mi_memory_order_acq_rel,\n  mi_memory_order_seq_cst\n} mi_memory_order;\n\nstatic inline uintptr_t mi_atomic_fetch_add_explicit(_Atomic(uintptr_t)*p, uintptr_t add, mi_memory_order mo) {\n  (void)(mo);\n  return (uintptr_t)MI_MSC_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, (msc_intptr_t)add);\n}\nstatic inline uintptr_t mi_atomic_fetch_sub_explicit(_Atomic(uintptr_t)*p, uintptr_t sub, mi_memory_order mo) {\n  (void)(mo);\n  return (uintptr_t)MI_MSC_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, -((msc_intptr_t)sub));\n}\nstatic inline uintptr_t mi_atomic_fetch_and_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {\n  (void)(mo);\n  return (uintptr_t)MI_MSC_64(_InterlockedAnd)((volatile msc_intptr_t*)p, (msc_intptr_t)x);\n}\nstatic inline uintptr_t mi_atomic_fetch_or_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {\n  (void)(mo);\n  return (uintptr_t)MI_MSC_64(_InterlockedOr)((volatile msc_intptr_t*)p, (msc_intptr_t)x);\n}\nstatic inline bool mi_atomic_compare_exchange_strong_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) {\n  (void)(mo1); (void)(mo2);\n  const uintptr_t read = (uintptr_t)MI_MSC_64(_InterlockedCompareExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)desired, (msc_intptr_t)(*expected));\n  if (read == *expected) {\n    return true;\n  }\n  else {\n    *expected = read;\n    return false;\n  }\n}\nstatic inline bool mi_atomic_compare_exchange_weak_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) {\n  return mi_atomic_compare_exchange_strong_explicit(p, expected, desired, mo1, mo2);\n}\nstatic inline uintptr_t mi_atomic_exchange_explicit(_Atomic(uintptr_t)*p, uintptr_t exchange, mi_memory_order mo) {\n  (void)(mo);\n  return (uintptr_t)MI_MSC_64(_InterlockedExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)exchange);\n}\nstatic inline void mi_atomic_thread_fence(mi_memory_order mo) {\n  (void)(mo);\n  _Atomic(uintptr_t) x = 0;\n  mi_atomic_exchange_explicit(&x, 1, mo);\n}\n\nstatic inline uintptr_t mi_atomic_load_explicit(_Atomic(uintptr_t) const* p, mi_memory_order mo) {\n  (void)(mo);\n  // assert(mo<=mi_memory_order_acquire); // others are not used by mimalloc\n  #if defined(_M_IX86) || defined(_M_X64)\n    return (uintptr_t)MI_MSC_XX(__iso_volatile_load)((volatile const intptr_t*)p);\n  #elif defined(_M_ARM) || defined(_M_ARM64)\n    if (mo == mi_memory_order_relaxed) {\n      return (uintptr_t)MI_MSC_XX(__iso_volatile_load)((volatile const intptr_t*)p);\n    }\n    else if (mo <= mi_memory_order_acquire) {\n      return MI_MSC_XX(__ldar)((volatile const uintptr_t*)p);\n    }\n    else {\n      const uintptr_t u = (uintptr_t)MI_MSC_XX(__iso_volatile_load)((volatile const intptr_t*)p);\n      __dmb(15);  // _ARM(64)_BARRIER_SY\n      return u;\n    }\n  #else\n    #warning \"define mi_atomic_load_explicit for MSVC C compilation on this platform (which should be readonly, see issue #1277)\"\n    return MI_MSC_XX(__iso_volatile_load)((volatile const intptr_t*)p);\n  #endif\n}\nstatic inline void mi_atomic_store_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {\n  (void)(mo);\n  // assert(mo<=mi_memory_order_release); // others are not used by mimalloc\n  #if defined(_M_IX86) || defined(_M_X64)\n    MI_MSC_XX(__iso_volatile_store)((volatile intptr_t*)p, x);\n  #elif defined(_M_ARM) || defined(_M_ARM64)\n    if (mo == mi_memory_order_relaxed) {\n      MI_MSC_XX(__iso_volatile_store)((volatile intptr_t*)p, x);\n    }\n    else if (mo <= mi_memory_order_release) {\n      MI_MSC_XX(__stlr)((volatile uintptr_t*)p,x);\n    }\n    else {\n      mi_atomic_exchange_explicit(p, x, mo);\n    }\n  #else\n    mi_atomic_exchange_explicit(p, x, mo);\n  #endif\n}\n\nstatic inline int64_t mi_atomic_loadi64_explicit(_Atomic(int64_t)*p, mi_memory_order mo) {\n  (void)(mo);\n  // assert(mo<=mi_memory_order_acquire); // others are not used by mimalloc\n  #if defined(_M_IX86) || defined(_M_X64)\n    return __iso_volatile_load64((volatile const int64_t*)p);\n  #elif defined(_M_ARM) || defined(_M_ARM64)\n    if (mo == mi_memory_order_relaxed) {\n      return __iso_volatile_load64((volatile const int64_t*)p);\n    }\n    #if defined(_M_ARM64)\n    else if (mo <= mi_memory_order_acquire) {\n      return __ldar64((volatile const uintptr_t*)p);\n    }\n    #endif\n    else {\n      const int64_t i = __iso_volatile_load64((volatile const int64_t*)p);\n      __dmb(15);  // _ARM(64)_BARRIER_SY\n      return i;\n    }\n  #else\n    #warning \"define mi_atomic_loadi64_explicit for MSVC C compilation on this platform (which should be readonly, see issue #1277)\"\n    return __iso_volatile_load64((volatile const int64_t*)p);\n  #endif\n}\n\nstatic inline void mi_atomic_storei64_explicit(_Atomic(int64_t)*p, int64_t x, mi_memory_order mo) {\n  (void)(mo);\n  // assert(mo<=mi_memory_order_release); // others are not used by mimalloc\n  #if defined(_M_IX86) || defined(_M_X64)\n    __iso_volatile_store64((volatile int64_t*)p,x);\n  #elif defined(_M_ARM) || defined(_M_ARM64)\n    if (mo == mi_memory_order_relaxed) {\n      __iso_volatile_store64((volatile int64_t*)p,x);\n    }\n    #if defined(_M_ARM64)\n    else if (mo == mi_memory_order_release) {\n      __stlr64((volatile uint64_t*)p, (uint64_t)x);\n    }\n    #endif\n    else {\n      InterlockedExchange64(p, x);\n    }\n  #else\n    InterlockedExchange64(p, x);\n  #endif\n}\n\n// These are used by the statistics\nstatic inline int64_t mi_atomic_addi64_relaxed(volatile _Atomic(int64_t)*p, int64_t add) {\n  #ifdef _WIN64\n    return (int64_t)mi_atomic_addi((int64_t*)p, add);\n  #elif defined(_M_ARM)\n    return _InterlockedExchangeAdd64(p, add);\n  #else\n    // x86\n    int64_t current;\n    int64_t sum;\n    do {\n      current = __iso_volatile_load64((volatile const int64_t*)p);\n      sum = current + add;\n    } while (_InterlockedCompareExchange64(p, sum, current) != current);\n    return current;\n  #endif\n}\n\nstatic inline void mi_atomic_void_addi64_relaxed(volatile int64_t* p, const volatile int64_t* padd) {\n  const int64_t add = *padd;\n  if (add != 0) {\n    mi_atomic_addi64_relaxed((volatile _Atomic(int64_t)*)p, add);\n  }\n}\n\nstatic inline void mi_atomic_maxi64_relaxed(volatile _Atomic(int64_t)*p, int64_t x) {\n  int64_t current;\n  do {\n    current = *p;\n  } while (current < x && _InterlockedCompareExchange64(p, x, current) != current);\n}\n\nstatic inline void mi_atomic_addi64_acq_rel(volatile _Atomic(int64_t*)p, int64_t i) {\n  mi_atomic_addi64_relaxed(p, i);\n}\n\nstatic inline bool mi_atomic_casi64_strong_acq_rel(volatile _Atomic(int64_t*)p, int64_t* exp, int64_t des) {\n  const int64_t read = _InterlockedCompareExchange64(p, des, *exp);\n  if (read == *exp) {\n    return true;\n  }\n  else {\n    *exp = read;\n    return false;\n  }\n}\n\n// The pointer macros cast to `uintptr_t`.\n#define mi_atomic_load_ptr_acquire(tp,p)                (tp*)mi_atomic_load_acquire((_Atomic(uintptr_t)*)(p))\n#define mi_atomic_load_ptr_relaxed(tp,p)                (tp*)mi_atomic_load_relaxed((_Atomic(uintptr_t)*)(p))\n#define mi_atomic_store_ptr_release(tp,p,x)             mi_atomic_store_release((_Atomic(uintptr_t)*)(p),(uintptr_t)(x))\n#define mi_atomic_store_ptr_relaxed(tp,p,x)             mi_atomic_store_relaxed((_Atomic(uintptr_t)*)(p),(uintptr_t)(x))\n#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des)    mi_atomic_cas_weak_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)\n#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des)    mi_atomic_cas_weak_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)\n#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des)  mi_atomic_cas_strong_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)\n#define mi_atomic_cas_ptr_strong_acq_rel(tp,p,exp,des)  mi_atomic_cas_strong_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)\n#define mi_atomic_exchange_ptr_relaxed(tp,p,x)          (tp*)mi_atomic_exchange_relaxed((_Atomic(uintptr_t)*)(p),(uintptr_t)x)\n#define mi_atomic_exchange_ptr_release(tp,p,x)          (tp*)mi_atomic_exchange_release((_Atomic(uintptr_t)*)(p),(uintptr_t)x)\n#define mi_atomic_exchange_ptr_acq_rel(tp,p,x)          (tp*)mi_atomic_exchange_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t)x)\n\n#define mi_atomic_loadi64_acquire(p)    mi_atomic(loadi64_explicit)(p,mi_memory_order(acquire))\n#define mi_atomic_loadi64_relaxed(p)    mi_atomic(loadi64_explicit)(p,mi_memory_order(relaxed))\n#define mi_atomic_storei64_release(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(release))\n#define mi_atomic_storei64_relaxed(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(relaxed))\n\n\n#endif\n\n\n// Atomically add a signed value; returns the previous value.\nstatic inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add) {\n  return (intptr_t)mi_atomic_add_acq_rel((_Atomic(uintptr_t)*)p, (uintptr_t)add);\n}\n\n// Atomically subtract a signed value; returns the previous value.\nstatic inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub) {\n  return (intptr_t)mi_atomic_addi(p, -sub);\n}\n\n\n// ----------------------------------------------------------------------\n// Guard\n// ----------------------------------------------------------------------\n\ntypedef _Atomic(uintptr_t) mi_atomic_guard_t;\n\n// Allows only one thread to execute at a time (without blocking anyone)\n#define mi_atomic_guard(guard) \\\n  uintptr_t _mi_guard_expected = 0; \\\n  for(bool _mi_guard_once = true; \\\n      _mi_guard_once && mi_atomic_cas_strong_acq_rel(guard,&_mi_guard_expected,(uintptr_t)1); \\\n      (mi_atomic_store_release(guard,(uintptr_t)0), _mi_guard_once = false) )\n\n\n// ----------------------------------------------------------------------\n// Locks\n// These should be light-weight in-process only locks.\n// Only used for reserving arena's and to maintain the abandoned list.\n// ----------------------------------------------------------------------\n#if _MSC_VER\n#pragma warning(disable:26110)  // unlock with holding lock\n#endif\n\n#define mi_lock(lock)                  for(bool _mi_go = (mi_lock_acquire(lock),true); _mi_go; (mi_lock_release(lock), _mi_go=false) )\n#define mi_lock_maybe(lock,acquire)    for(bool _mi_go = (acquire ? (mi_lock_acquire(lock),true) : true); _mi_go; _mi_go = (acquire ? (mi_lock_release(lock),false) : false) )\n\n\n#if defined(_WIN32)\n\ntypedef struct mi_lock_s {\n  SRWLOCK mutex;    // slim reader-writer lock\n} mi_lock_t;\n\n#define MI_LOCK_INITIALIZER   { SRWLOCK_INIT }\n\nstatic inline bool mi_lock_try_acquire(mi_lock_t* lock) {\n  return TryAcquireSRWLockExclusive(&lock->mutex);\n}\nstatic inline void mi_lock_acquire(mi_lock_t* lock) {\n  AcquireSRWLockExclusive(&lock->mutex);\n}\nstatic inline void mi_lock_release(mi_lock_t* lock) {\n  ReleaseSRWLockExclusive(&lock->mutex);\n}\nstatic inline void mi_lock_init(mi_lock_t* lock) {\n  InitializeSRWLock(&lock->mutex);\n}\nstatic inline void mi_lock_done(mi_lock_t* lock) {\n  (void)(lock);\n}\n\n#elif defined(MI_USE_PTHREADS)\n\n#include <string.h> // memcpy\nvoid _mi_error_message(int err, const char* fmt, ...);\n\ntypedef struct mi_lock_s {\n  pthread_mutex_t mutex;\n} mi_lock_t;\n\n#define MI_LOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }\n\nstatic inline bool mi_lock_try_acquire(mi_lock_t* lock) {\n  return (pthread_mutex_trylock(&lock->mutex) == 0);\n}\nstatic inline void mi_lock_acquire(mi_lock_t* lock) {\n  const int err = pthread_mutex_lock(&lock->mutex);\n  if (err != 0) {\n    _mi_error_message(err, \"internal error: lock cannot be acquired (err %i)\\n\", err);\n  }\n}\nstatic inline void mi_lock_release(mi_lock_t* lock) {\n  pthread_mutex_unlock(&lock->mutex);\n}\nstatic inline void mi_lock_init(mi_lock_t* lock) {\n  if(lock==NULL) return;\n  // use this instead of pthread_mutex_init since that can cause allocation on some platforms (and recursively initialize)\n  const pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;\n  memcpy(&lock->mutex,&mutex,sizeof(mutex));\n}\nstatic inline void mi_lock_done(mi_lock_t* lock) {\n  pthread_mutex_destroy(&lock->mutex);\n}\n\n#elif defined(__cplusplus)\n\n#include <thread>\n#include <mutex>\n#include <new>\n\ntypedef struct mi_lock_s {\n  std::mutex mutex;\n} mi_lock_t;\n\n#define MI_LOCK_INITIALIZER   { }\n\nstatic inline bool mi_lock_try_acquire(mi_lock_t* lock) {\n  return lock->mutex.try_lock();\n}\nstatic inline void mi_lock_acquire(mi_lock_t* lock) {\n  lock->mutex.lock();\n}\nstatic inline void mi_lock_release(mi_lock_t* lock) {\n  lock->mutex.unlock();\n}\nstatic inline void mi_lock_init(mi_lock_t* lock) {\n  new(&lock->mutex) std::mutex();\n}\nstatic inline void mi_lock_done(mi_lock_t* lock) {\n  (void)(lock);\n}\n\n#else\n\n// fall back to poor man's locks.\n// this should only be the case in a single-threaded environment (like __wasi__)\n#include <errno.h>\n#ifndef EFAULT\n#define EFAULT (14)\n#endif\nvoid _mi_error_message(int err, const char* fmt, ...);\nvoid _mi_prim_thread_yield(void);\n\ntypedef struct mi_lock_s {\n  _Atomic(uintptr_t) mutex;\n} mi_lock_t;\n\n#define MI_LOCK_INITIALIZER  { MI_ATOMIC_VAR_INIT(0) }\n\nstatic inline bool mi_lock_try_acquire(mi_lock_t* lock) {\n  uintptr_t expected = 0;\n  return mi_atomic_cas_strong_acq_rel(&lock->mutex, &expected, (uintptr_t)1);\n}\nstatic inline void mi_lock_acquire(mi_lock_t* lock) {\n  for (int i = 0; i < 10000; i++) {  // for at most 10000 tries?\n    if (mi_lock_try_acquire(lock)) return;\n    _mi_prim_thread_yield();\n  }\n  _mi_error_message(EFAULT, \"internal error: lock cannot be acquired (due to lack of native lock primitives)\\n\");\n}\nstatic inline void mi_lock_release(mi_lock_t* lock) {\n  mi_atomic_store_release(&lock->mutex, (uintptr_t)0);\n}\nstatic inline void mi_lock_init(mi_lock_t* lock) {\n  mi_lock_release(lock);\n}\nstatic inline void mi_lock_done(mi_lock_t* lock) {\n  (void)(lock);\n}\n\n#endif\n\n\ntypedef struct mi_atomic_once_s {\n  _Atomic(uintptr_t) tid;\n  mi_lock_t          lock;\n} mi_atomic_once_t;\n\n// Returns `true` only on the first invocation, signifying we can execute an action once.\n// If it returns `true`, the caller should call `_mi_atomic_once_release` after performing the action.\n// Other threads (than the initial thread that entered) will block until `_mi_atomic_once_release` has been called.\nbool _mi_atomic_once_enter(mi_atomic_once_t* once);        // defined in `libc.c`\nvoid _mi_atomic_once_release(mi_atomic_once_t* once);      // defined in `libc.c`\n\n#define mi_atomic_do_once  \\\n  static mi_atomic_once_t _mi_once = { MI_ATOMIC_VAR_INIT(0), MI_LOCK_INITIALIZER }; \\\n  for(bool _mi_exec = _mi_atomic_once_enter(&_mi_once); _mi_exec; (_mi_atomic_once_release(&_mi_once),_mi_exec=false))\n\n\n#endif // __MIMALLOC_ATOMIC_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/include/mimalloc/bits.h",
      "sha256": "57a7297e18ae464a7bfd3fc25a46229008602385697305c69ed289b89ece7631",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2024 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* ----------------------------------------------------------------------------\n  Bit operation, and platform dependent definition (MI_INTPTR_SIZE etc)\n---------------------------------------------------------------------------- */\n\n#pragma once\n#ifndef MI_BITS_H\n#define MI_BITS_H\n\n#include <stddef.h>   // size_t\n#include <stdint.h>   // int64_t etc\n#include <stdbool.h>  // bool\n\n// ------------------------------------------------------\n// Size of a pointer.\n// We assume that `sizeof(void*)==sizeof(intptr_t)`\n// and it holds for all platforms we know of.\n//\n// However, the C standard only requires that:\n//  p == (void*)((intptr_t)p))\n// but we also need:\n//  i == (intptr_t)((void*)i)\n// or otherwise one might define an intptr_t type that is larger than a pointer...\n// ------------------------------------------------------\n\n#if INTPTR_MAX > INT64_MAX\n# define MI_INTPTR_SHIFT (4)  // assume 128-bit  (as on arm CHERI for example)\n#elif INTPTR_MAX == INT64_MAX\n# define MI_INTPTR_SHIFT (3)\n#elif INTPTR_MAX == INT32_MAX\n# define MI_INTPTR_SHIFT (2)\n#else\n#error platform pointers must be 32, 64, or 128 bits\n#endif\n\n#if (INTPTR_MAX) > LONG_MAX\n# define MI_PU(x)  x##ULL\n#else\n# define MI_PU(x)  x##UL\n#endif\n\n#if SIZE_MAX == UINT64_MAX\n# define MI_SIZE_SHIFT (3)\ntypedef int64_t  mi_ssize_t;\n#elif SIZE_MAX == UINT32_MAX\n# define MI_SIZE_SHIFT (2)\ntypedef int32_t  mi_ssize_t;\n#else\n#error platform objects must be 32 or 64 bits in size\n#endif\n\n#if (SIZE_MAX/2) > LONG_MAX\n# define MI_ZU(x)  x##ULL\n#else\n# define MI_ZU(x)  x##UL\n#endif\n\n#define MI_INTPTR_SIZE  (1<<MI_INTPTR_SHIFT)\n#define MI_INTPTR_BITS  (MI_INTPTR_SIZE*8)\n\n#define MI_SIZE_SIZE  (1<<MI_SIZE_SHIFT)\n#define MI_SIZE_BITS  (MI_SIZE_SIZE*8)\n\n#define MI_KiB     (MI_ZU(1024))\n#define MI_MiB     (MI_KiB*MI_KiB)\n#define MI_GiB     (MI_MiB*MI_KiB)\n\n\n/* --------------------------------------------------------------------------------\n  Architecture\n-------------------------------------------------------------------------------- */\n\n#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC)  // consider arm64ec as arm64\n#define MI_ARCH_ARM64     1\n#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)\n#define MI_ARCH_X64       1\n#elif defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_X86_) || defined(__X86__)\n#define MI_ARCH_X86       1\n#elif defined(__arm__) || defined(_ARM) || defined(_M_ARM)  || defined(_M_ARMT) || defined(__arm)\n#define MI_ARCH_ARM32     1\n#elif defined(__riscv) || defined(_M_RISCV)\n#define MI_ARCH_RISCV     1\n#if (LONG_MAX == INT32_MAX)\n#define MI_ARCH_RISCV32   1\n#else\n#define MI_ARCH_RISCV64   1\n#endif\n#endif\n\n#if MI_ARCH_X64 && defined(__AVX2__)\n#include <immintrin.h>\n#elif MI_ARCH_ARM64 && MI_OPT_SIMD\n#include <arm_neon.h>\n#endif\n#if defined(_MSC_VER) && (MI_ARCH_X64 || MI_ARCH_X86 || MI_ARCH_ARM64 || MI_ARCH_ARM32)\n#include <intrin.h>\n#endif\n\n#if MI_ARCH_X64 && defined(__AVX2__) && !defined(__BMI2__) // msvc\n#define __BMI2__  1\n#endif\n#if MI_ARCH_X64 && (defined(__AVX2__) || defined(__BMI2__)) && !defined(__BMI1__) // msvc\n#define __BMI1__  1\n#endif\n#if MI_ARCH_X64 && defined(__AVX2__) && !defined(__LZCNT__) // msvc\n#define __LZCNT__  1\n#endif\n\n// Define big endian if needed\n// #define MI_BIG_ENDIAN  1\n\n// maximum virtual address bits in a user-space pointer\n#if MI_DEFAULT_VIRTUAL_ADDRESS_BITS > 0 \n#define MI_MAX_VABITS     MI_DEFAULT_VIRTUAL_ADDRESS_BITS\n#elif   MI_ARCH_X64\n#define MI_MAX_VABITS     (47)\n#elif MI_INTPTR_SIZE > 4\n#define MI_MAX_VABITS     (48)\n#else\n#define MI_MAX_VABITS     (32)\n#endif\n\n// use a flat page-map or a 2-level one\n#ifndef MI_PAGE_MAP_FLAT\n#if MI_MAX_VABITS <= 40 && !defined(__APPLE__) && MI_SECURE==0 && !MI_PAGE_META_IS_SEPARATED\n#define MI_PAGE_MAP_FLAT  1\n#else\n#define MI_PAGE_MAP_FLAT  0\n#endif\n#endif\n\n\n/* --------------------------------------------------------------------------------\n  Builtin's\n-------------------------------------------------------------------------------- */\n\n#ifndef __has_builtin\n#define __has_builtin(x)  0\n#endif\n\n#define mi_builtin(name)        __builtin_##name\n#define mi_has_builtin(name)    __has_builtin(__builtin_##name)\n\n#if (LONG_MAX == INT32_MAX)\n#define mi_builtin32(name)       mi_builtin(name##l)\n#define mi_has_builtin32(name)   mi_has_builtin(name##l)\n#else\n#define mi_builtin32(name)       mi_builtin(name)\n#define mi_has_builtin32(name)   mi_has_builtin(name)\n#endif\n#if (LONG_MAX == INT64_MAX)\n#define mi_builtin64(name)       mi_builtin(name##l)\n#define mi_has_builtin64(name)   mi_has_builtin(name##l)\n#else\n#define mi_builtin64(name)       mi_builtin(name##ll)\n#define mi_has_builtin64(name)   mi_has_builtin(name##ll)\n#endif\n\n#if (MI_SIZE_BITS == 32)\n#define mi_builtinz(name)        mi_builtin32(name)\n#define mi_has_builtinz(name)    mi_has_builtin32(name)\n#define mi_msc_builtinz(name)    name\n#elif (MI_SIZE_BITS == 64)\n#define mi_builtinz(name)        mi_builtin64(name)\n#define mi_has_builtinz(name)    mi_has_builtin64(name)\n#define mi_msc_builtinz(name)    name##64\n#endif\n\n/* --------------------------------------------------------------------------------\n  Popcount and count trailing/leading zero's\n-------------------------------------------------------------------------------- */\n\nsize_t _mi_popcount_generic(size_t x);\n\nstatic inline size_t mi_popcount(size_t x) {\n  #if mi_has_builtinz(popcount)\n    return mi_builtinz(popcount)(x);\n  #elif defined(_MSC_VER) && (MI_ARCH_X64 || MI_ARCH_X86 || MI_ARCH_ARM64 || MI_ARCH_ARM32)\n    return mi_msc_builtinz(__popcnt)(x);\n  #elif MI_ARCH_X64 && defined(__BMI1__)\n    return (size_t)_mm_popcnt_u64(x);\n  #else\n    #define MI_HAS_FAST_POPCOUNT  0\n    return (x<=1 ? x : _mi_popcount_generic(x));\n  #endif\n}\n\n#ifndef MI_HAS_FAST_POPCOUNT\n#define MI_HAS_FAST_POPCOUNT 1\n#endif\n\n\n\nsize_t _mi_clz_generic(size_t x);\nsize_t _mi_ctz_generic(size_t x);\n\nstatic inline size_t mi_ctz(size_t x) {\n  #if defined(__GNUC__) && MI_ARCH_X64 && defined(__BMI1__) // on x64 tzcnt is defined for 0\n    size_t r;\n    __asm (\"tzcnt\\t%1, %0\" : \"=r\"(r) : \"r\"(x) : \"cc\");\n    return r;\n  #elif defined(_MSC_VER) && MI_ARCH_X64 && defined(__BMI1__) \n    return _tzcnt_u64(x);\n  #elif defined(_MSC_VER) && (MI_ARCH_X64 || MI_ARCH_X86 || MI_ARCH_ARM64 || MI_ARCH_ARM32)\n    unsigned long idx;\n    return (mi_msc_builtinz(_BitScanForward)(&idx, x) ? (size_t)idx : MI_SIZE_BITS);\n  #elif mi_has_builtinz(ctz)\n    return (x!=0 ? (size_t)mi_builtinz(ctz)(x) : MI_SIZE_BITS);\n  #elif defined(__GNUC__) && (MI_ARCH_X64 || MI_ARCH_X86)\n    size_t r = MI_SIZE_BITS;  // bsf leaves destination unmodified if the argument is 0 (see <https://github.com/llvm/llvm-project/pull/102885>)\n    __asm (\"bsf\\t%1, %0\" : \"+r\"(r) : \"r\"(x) : \"cc\");\n    return r;\n  #elif MI_HAS_FAST_POPCOUNT\n    return (x!=0 ? (mi_popcount(x^(x-1))-1) : MI_SIZE_BITS);\n  #else\n    #define MI_HAS_FAST_BITSCAN  0\n    return (x!=0 ? _mi_ctz_generic(x) : MI_SIZE_BITS);\n  #endif\n}\n\nstatic inline size_t mi_clz(size_t x) {\n  #if defined(__GNUC__) && MI_ARCH_X64 && defined(__LZCNT__) // on x64 lzcnt is defined for 0\n    size_t r;\n    __asm (\"lzcnt\\t%1, %0\" : \"=r\"(r) : \"r\"(x) : \"cc\");\n    return r;\n  #elif defined(_MSC_VER) && MI_ARCH_X64 && defined(__LZCNT__) \n    return _lzcnt_u64(x);\n  #elif defined(_MSC_VER) && (MI_ARCH_X64 || MI_ARCH_X86 || MI_ARCH_ARM64 || MI_ARCH_ARM32)\n    unsigned long idx;\n    return (mi_msc_builtinz(_BitScanReverse)(&idx, x) ? MI_SIZE_BITS - 1 - (size_t)idx : MI_SIZE_BITS);\n  #elif mi_has_builtinz(clz)\n    return (x!=0 ? (size_t)mi_builtinz(clz)(x) : MI_SIZE_BITS);\n  #elif defined(__GNUC__) && (MI_ARCH_X64 || MI_ARCH_X86)\n    if (x==0) return MI_SIZE_BITS;\n    size_t r;\n    __asm (\"bsr\\t%1, %0\" : \"=r\"(r) : \"r\"(x) : \"cc\");\n    return (MI_SIZE_BITS - 1 - r);\n  #else\n    #define MI_HAS_FAST_BITSCAN  0\n    return (x!=0 ? _mi_clz_generic(x) : MI_SIZE_BITS);\n  #endif\n}\n\n#ifndef MI_HAS_FAST_BITSCAN\n#define MI_HAS_FAST_BITSCAN 1\n#endif\n\n/* --------------------------------------------------------------------------------\n  find trailing/leading zero  (bit scan forward/reverse)\n-------------------------------------------------------------------------------- */\n\n// Bit scan forward: find the least significant bit that is set (i.e. count trailing zero's)\n// return false if `x==0` (with `*idx` undefined) and true otherwise,\n// with the `idx` is set to the bit index (`0 <= *idx < MI_BFIELD_BITS`).\nstatic inline bool mi_bsf(size_t x, size_t* idx) {\n  #if defined(__GNUC__) && MI_ARCH_X64 && defined(__BMI1__) && (!defined(__clang_major__) || __clang_major__ >= 9)\n    // on x64 the carry flag is set on zero which gives better codegen\n    bool is_zero;\n    __asm ( \"tzcnt\\t%2, %1\" : \"=@ccc\"(is_zero), \"=r\"(*idx) : \"r\"(x) : \"cc\" );\n    return !is_zero;\n  #elif 0 && defined(_MSC_VER) && (MI_ARCH_X64 || MI_ARCH_X86 || MI_ARCH_ARM64 || MI_ARCH_ARM32)\n    unsigned long i;\n    return (mi_msc_builtinz(_BitScanForward)(&i, x) ? (*idx = (size_t)i, true) : false);\n  #else\n    return (x!=0 ? (*idx = mi_ctz(x), true) : false);\n  #endif\n}\n\n// Bit scan reverse: find the most significant bit that is set\n// return false if `x==0` (with `*idx` undefined) and true otherwise,\n// with the `idx` is set to the bit index (`0 <= *idx < MI_BFIELD_BITS`).\nstatic inline bool mi_bsr(size_t x, size_t* idx) {\n  #if 0 && defined(_MSC_VER) && (MI_ARCH_X64 || MI_ARCH_X86 || MI_ARCH_ARM64 || MI_ARCH_ARM32)\n    unsigned long i;\n    return (mi_msc_builtinz(_BitScanReverse)(&i, x) ? (*idx = (size_t)i, true) : false);\n  #else\n    return (x!=0 ? (*idx = MI_SIZE_BITS - 1 - mi_clz(x), true) : false);\n  #endif\n}\n\n\n/* --------------------------------------------------------------------------------\n  rotate\n-------------------------------------------------------------------------------- */\n\nstatic inline size_t mi_rotr(size_t x, size_t r) {\n  #if (mi_has_builtin(rotateright64) && MI_SIZE_BITS==64)\n    return mi_builtin(rotateright64)(x,r);\n  #elif (mi_has_builtin(rotateright32) && MI_SIZE_BITS==32)\n    return mi_builtin(rotateright32)(x,r);\n  #elif defined(_MSC_VER) && (MI_ARCH_X64 || MI_ARCH_ARM64)\n    return _rotr64(x, (int)r);\n  #elif defined(_MSC_VER) && (MI_ARCH_X86 || MI_ARCH_ARM32)\n    return _lrotr(x,(int)r);\n  #else\n    // The term `(-rshift)&(BITS-1)` is written instead of `BITS - rshift` to\n    // avoid UB when `rshift==0`. See <https://blog.regehr.org/archives/1063>\n    const unsigned int rshift = (unsigned int)(r) & (MI_SIZE_BITS-1);\n    return ((x >> rshift) | (x << ((-rshift) & (MI_SIZE_BITS-1))));\n  #endif\n}\n\nstatic inline size_t mi_rotl(size_t x, size_t r) {\n  #if (mi_has_builtin(rotateleft64) && MI_SIZE_BITS==64)\n    return mi_builtin(rotateleft64)(x,r);\n  #elif (mi_has_builtin(rotateleft32) && MI_SIZE_BITS==32)\n    return mi_builtin(rotateleft32)(x,r);\n  #elif defined(_MSC_VER) && (MI_ARCH_X64 || MI_ARCH_ARM64)\n    return _rotl64(x, (int)r);\n  #elif defined(_MSC_VER) && (MI_ARCH_X86 || MI_ARCH_ARM32)\n    return _lrotl(x, (int)r);\n  #else\n    // The term `(-rshift)&(BITS-1)` is written instead of `BITS - rshift` to\n    // avoid UB when `rshift==0`. See <https://blog.regehr.org/archives/1063>\n    const unsigned int rshift = (unsigned int)(r) & (MI_SIZE_BITS-1);\n    return ((x << rshift) | (x >> ((-rshift) & (MI_SIZE_BITS-1))));\n  #endif\n}\n\nstatic inline uint32_t mi_rotl32(uint32_t x, uint32_t r) {\n  #if mi_has_builtin(rotateleft32)\n    return mi_builtin(rotateleft32)(x,r);\n  #elif defined(_MSC_VER) && (MI_ARCH_X64 || MI_ARCH_X86 || MI_ARCH_ARM64 || MI_ARCH_ARM32)\n    return _lrotl(x, (int)r);\n  #else\n    // The term `(-rshift)&(BITS-1)` is written instead of `BITS - rshift` to\n    // avoid UB when `rshift==0`. See <https://blog.regehr.org/archives/1063>\n    const unsigned int rshift = (unsigned int)(r) & 31;\n    return ((x << rshift) | (x >> ((-rshift) & 31)));\n  #endif\n}\n\n\n#endif // MI_BITS_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/include/mimalloc/internal.h",
      "sha256": "5aeeff21d667daf4aadcc66f634aa957ecd688d15b277828f367c8c2274251a8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MI_INTERNAL_H\n#define MI_INTERNAL_H\n\n// --------------------------------------------------------------------------\n// This file contains the internal API's of mimalloc and various utility\n// functions and macros.\n// --------------------------------------------------------------------------\n\n#include \"types.h\"\n#include \"track.h\"\n#include \"bits.h\"\n\n\n// --------------------------------------------------------------------------\n// Compiler defines\n// --------------------------------------------------------------------------\n\n#if (MI_DEBUG>0)\n#define mi_trace_message(...)  _mi_trace_message(__VA_ARGS__)\n#else\n#define mi_trace_message(...)\n#endif\n\n#define mi_decl_cache_align     mi_decl_align(64)\n\n#if defined(_MSC_VER)\n#pragma warning(disable:4127)   // suppress constant conditional warning (due to MI_SECURE paths)\n#pragma warning(disable:26812)  // unscoped enum warning\n#define mi_decl_forceinline     __forceinline\n#define mi_decl_noinline        __declspec(noinline)\n#define mi_decl_thread          __declspec(thread)\n#define mi_decl_noreturn        __declspec(noreturn)\n#define mi_decl_weak\n#define mi_decl_hidden\n#define mi_decl_cold\n#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) // includes clang and icc\n#if !MI_TRACK_ASAN\n#define mi_decl_forceinline     __attribute__((always_inline)) inline\n#else\n#define mi_decl_forceinline     inline\n#endif\n#define mi_decl_noinline        __attribute__((noinline))\n#define mi_decl_thread          __thread\n#define mi_decl_noreturn        __attribute__((noreturn))\n#define mi_decl_weak            __attribute__((weak))\n#define mi_decl_hidden          __attribute__((visibility(\"hidden\")))\n#if (__GNUC__ >= 4) || defined(__clang__)\n#define mi_decl_cold            __attribute__((cold))\n#else\n#define mi_decl_cold\n#endif\n#elif __cplusplus >= 201103L    // c++11\n#define mi_decl_forceinline     inline\n#define mi_decl_noinline\n#define mi_decl_thread          thread_local\n#define mi_decl_noreturn        [[noreturn]]\n#define mi_decl_weak\n#define mi_decl_hidden\n#define mi_decl_cold\n#else\n#define mi_decl_forceinline     inline\n#define mi_decl_noinline\n#define mi_decl_thread          __thread        // hope for the best :-)\n#define mi_decl_noreturn\n#define mi_decl_weak\n#define mi_decl_hidden\n#define mi_decl_cold\n#endif\n\n#if defined(__GNUC__) || defined(__clang__)\n#define mi_unlikely(x)     (__builtin_expect(!!(x),false))\n#define mi_likely(x)       (__builtin_expect(!!(x),true))\n#elif (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)\n#define mi_unlikely(x)     (x) [[unlikely]]\n#define mi_likely(x)       (x) [[likely]]\n#else\n#define mi_unlikely(x)     (x)\n#define mi_likely(x)       (x)\n#endif\n\n#ifndef __has_builtin\n#define __has_builtin(x)    0\n#endif\n\n#if defined(__cplusplus)\n#define mi_decl_externc     extern \"C\"\n#else\n#define mi_decl_externc\n#endif\n\n#if (defined(__GNUC__) && (__GNUC__ >= 7)) || defined(__clang__) // includes clang and icc\n#define mi_decl_maybe_unused    __attribute__((unused))\n#elif __cplusplus >= 201703L    // c++17\n#define mi_decl_maybe_unused    [[maybe_unused]]\n#else\n#define mi_decl_maybe_unused\n#endif\n\n#if defined(__cplusplus)\n#define mi_decl_externc         extern \"C\"\n#else\n#define mi_decl_externc\n#endif\n\n\n#if defined(__EMSCRIPTEN__) && !defined(__wasi__)\n#define __wasi__\n#endif\n\n\n// --------------------------------------------------------------------------\n// Internal functions\n// --------------------------------------------------------------------------\n\n\n// \"libc.c\"\n#include <stdarg.h>\nint           _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args);\nint           _mi_snprintf(char* buf, size_t buflen, const char* fmt, ...);\nchar          _mi_toupper(char c);\nint           _mi_strnicmp(const char* s, const char* t, size_t n);\nvoid          _mi_strlcpy(char* dest, const char* src, size_t dest_size);\nvoid          _mi_strlcat(char* dest, const char* src, size_t dest_size);\nsize_t        _mi_strlen(const char* s);\nsize_t        _mi_strnlen(const char* s, size_t max_len);\nchar*         _mi_strnstr(char* s, size_t max_len, const char* pat);\nbool          _mi_streq(const char* s, const char* t);\nbool          _mi_getenv(const char* name, char* result, size_t result_size);\n\n// \"options.c\"\nvoid          _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message);\nvoid          _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...);\nvoid          _mi_raw_message(const char* fmt, ...);\nvoid          _mi_message(const char* fmt, ...);\nvoid          _mi_warning_message(const char* fmt, ...);\nvoid          _mi_verbose_message(const char* fmt, ...);\nvoid          _mi_trace_message(const char* fmt, ...);\nvoid          _mi_options_init(void);\nvoid          _mi_options_post_init(void);\nlong          _mi_option_get_fast(mi_option_t option);\nvoid          _mi_error_message(int err, const char* fmt, ...);\n\n// random.c\nvoid          _mi_random_init(mi_random_ctx_t* ctx);\nvoid          _mi_random_init_weak(mi_random_ctx_t* ctx);\nvoid          _mi_random_reinit_if_weak(mi_random_ctx_t * ctx);\nvoid          _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx);\nuintptr_t     _mi_random_next(mi_random_ctx_t* ctx);\nuintptr_t     _mi_theap_random_next(mi_theap_t* theap);\nuintptr_t     _mi_os_random_weak(uintptr_t extra_seed);\nstatic inline uintptr_t _mi_random_shuffle(uintptr_t x);\n\n// init.c\nextern mi_decl_hidden mi_decl_cache_align const mi_page_t  _mi_page_empty;\nvoid          _mi_auto_process_init(void);\nvoid mi_cdecl _mi_auto_process_done(void) mi_attr_noexcept;\nbool          _mi_is_redirected(void);\nbool          _mi_allocator_init(const char** message);\nvoid          _mi_allocator_done(void);\nbool          _mi_is_main_thread(void);\nbool          _mi_preloading(void);           // true while the C runtime is not initialized yet\nvoid          _mi_thread_done(mi_theap_t* theap);\n\nmi_subproc_t* _mi_subproc(void);\nmi_subproc_t* _mi_subproc_main(void);\nmi_heap_t*    _mi_subproc_heap_main(mi_subproc_t* subproc);\nmi_subproc_t* _mi_subproc_from_id(mi_subproc_id_t subproc_id);\n\nmi_threadid_t _mi_thread_id(void) mi_attr_noexcept;\nsize_t        _mi_thread_seq_id(void) mi_attr_noexcept;\nbool          _mi_is_heap_main(const mi_heap_t* heap);\nbool          _mi_is_theap_main(const mi_theap_t* theap);\nvoid          _mi_theap_guarded_init(mi_theap_t* theap);\nvoid          _mi_theap_options_init(mi_theap_t* theap);\nmi_theap_t*   _mi_theap_default_safe(void);             // ensure the returned theap is initialized\nmi_theap_t*   _mi_theap_main_safe(void);\n   \n// os.c\nvoid          _mi_os_init(void);                                            // called from process init\nvoid*         _mi_os_alloc(size_t size, mi_memid_t* memid);\nvoid*         _mi_os_zalloc(size_t size, mi_memid_t* memid);\nvoid          _mi_os_free(void* p, size_t size, mi_memid_t memid);\nvoid          _mi_os_free_ex(void* p, size_t size, bool still_committed, mi_memid_t memid, mi_subproc_t* subproc );\n\nsize_t        _mi_os_page_size(void);\nsize_t        _mi_os_guard_page_size(void);\nsize_t        _mi_os_good_alloc_size(size_t size);\nbool          _mi_os_has_overcommit(void);\nbool          _mi_os_has_virtual_reserve(void);\nsize_t        _mi_os_virtual_address_bits(void);\nsize_t        _mi_os_minimal_purge_size(void);\n\nbool          _mi_os_reset(void* addr, size_t size);\nbool          _mi_os_decommit(void* addr, size_t size);\nvoid          _mi_os_reuse(void* p, size_t size);\nmi_decl_nodiscard bool _mi_os_commit(void* p, size_t size, bool* is_zero);\nmi_decl_nodiscard bool _mi_os_commit_ex(void* addr, size_t size, bool* is_zero, size_t stat_size);\nmi_decl_nodiscard bool _mi_os_protect(void* addr, size_t size);\nbool          _mi_os_unprotect(void* addr, size_t size);\nbool          _mi_os_purge(void* p, size_t size);\nbool          _mi_os_purge_ex(void* p, size_t size, bool allow_reset, size_t stats_size, mi_commit_fun_t* commit_fun, void* commit_fun_arg);\n\nsize_t        _mi_os_secure_guard_page_size(void);\nbool          _mi_os_secure_guard_page_set_at(void* addr, mi_memid_t memid);\nbool          _mi_os_secure_guard_page_set_before(void* addr, mi_memid_t memid);\nbool          _mi_os_secure_guard_page_reset_at(void* addr, mi_memid_t memid);\nbool          _mi_os_secure_guard_page_reset_before(void* addr, mi_memid_t memid);\n\nint           _mi_os_numa_node(void);\nint           _mi_os_numa_node_count(void);\n\nvoid*         _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid);\nvoid*         _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t* memid);\n\nvoid*         _mi_os_get_aligned_hint(size_t try_alignment, size_t size);\nbool          _mi_os_canuse_large_page(size_t size, size_t alignment);\nsize_t        _mi_os_large_page_size(void);\nvoid*         _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_secs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid);\n\n// threadlocal.c\n\nmi_thread_local_t _mi_thread_local_create(void);\nvoid          _mi_thread_local_free( mi_thread_local_t key );\nbool          _mi_thread_local_set(  mi_thread_local_t key, void* val );\nvoid*         _mi_thread_local_get(  mi_thread_local_t key );\nvoid          _mi_thread_locals_init(void);\nvoid          _mi_thread_locals_done(void);\nvoid          _mi_thread_locals_thread_done(void);\n\n// arena.c\nmi_arena_id_t _mi_arena_id_none(void);\nmi_arena_t*   _mi_arena_from_id(mi_arena_id_t id);\nbool          _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_t* request_arena);\n\nvoid*         _mi_arenas_alloc(mi_heap_t* heap, size_t size, bool commit, bool allow_pinned, mi_arena_t* req_arena, size_t tseq, int numa_node, mi_memid_t* memid);\nvoid*         _mi_arenas_alloc_aligned(mi_heap_t* heap, size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_pinned, mi_arena_t* req_arena, size_t tseq, int numa_node, mi_memid_t* memid);\nvoid          _mi_arenas_free(void* p, size_t size, mi_memid_t memid);\nbool          _mi_arenas_contain(const void* p);\nvoid          _mi_arenas_collect(bool force_purge, bool visit_all, mi_tld_t* tld);\nvoid          _mi_arenas_unsafe_destroy_all(mi_subproc_t* subproc);\n\nmi_page_t*    _mi_arenas_page_alloc(mi_theap_t* theap, size_t block_size, size_t page_alignment);\nvoid          _mi_arenas_page_free(mi_page_t* page, mi_theap_t* current_theapx /* can be NULL */);\nvoid          _mi_arenas_page_abandon(mi_page_t* page, mi_theap_t* current_theap);\nvoid          _mi_arenas_page_unabandon(mi_page_t* page, mi_theap_t* current_theapx /* can be NULL */);\nbool          _mi_arenas_page_try_reabandon_to_mapped(mi_page_t* page);\n\n// arena-meta.c\nvoid*         _mi_meta_zalloc( size_t size, mi_memid_t* memid );\nvoid          _mi_meta_free(void* p, size_t size, mi_memid_t memid);\nbool          _mi_meta_is_meta_page(void* p);\n\n// \"page-map.c\"\nbool          _mi_page_map_init(void);\nmi_decl_nodiscard bool _mi_page_map_register(mi_page_t* page);\nvoid          _mi_page_map_unregister(mi_page_t* page);\nvoid          _mi_page_map_unregister_range(void* start, size_t size);\nmi_page_t*    _mi_safe_ptr_page(const void* p);\nvoid          _mi_page_map_unsafe_destroy(mi_subproc_t* subproc);\n\n// \"page.c\"\nvoid*         _mi_malloc_generic(mi_theap_t* theap, size_t size, size_t zero_huge_alignment, size_t* usable)  mi_attr_noexcept mi_attr_malloc;\n\nvoid          _mi_page_retire(mi_page_t* page) mi_attr_noexcept;       // free the page if there are no other pages with many free blocks\nvoid          _mi_page_unfull(mi_page_t* page);\nvoid          _mi_page_free(mi_page_t* page, mi_page_queue_t* pq);     // free the page\nvoid          _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq);  // abandon the page, to be picked up by another thread...\n\nsize_t        _mi_page_queue_append(mi_theap_t* theap, mi_page_queue_t* pq, mi_page_queue_t* append);\nvoid          _mi_deferred_free(mi_theap_t* theap, bool force);\n\nvoid          _mi_page_free_collect(mi_page_t* page, bool force);\nvoid          _mi_page_free_collect_partly(mi_page_t* page, mi_block_t* head);\nmi_decl_nodiscard bool _mi_page_init(mi_theap_t* theap, mi_page_t* page);\nbool          _mi_page_queue_is_valid(mi_theap_t* theap, const mi_page_queue_t* pq);\n\nsize_t        _mi_page_stats_bin(const mi_page_t* page); // for stats\nsize_t        _mi_bin_size(size_t bin);                  // for stats\nsize_t        _mi_bin(size_t size);                      // for stats\n\n// \"theap.c\"\nmi_theap_t*   _mi_theap_create(mi_heap_t* heap, mi_tld_t* tld);\nvoid          _mi_theap_delete(mi_theap_t* theap, bool acquire_tld_theaps_lock);\nvoid          _mi_theap_default_set(mi_theap_t* theap);\nvoid          _mi_theap_cached_set(mi_theap_t* theap);\nvoid          _mi_theap_collect_retired(mi_theap_t* theap, bool force);\nvoid          _mi_theap_collect_abandon(mi_theap_t* theap);\nbool          _mi_theap_area_visit_blocks(const mi_heap_area_t* area, mi_page_t* page, mi_block_visit_fun* visitor, void* arg);\nvoid          _mi_theap_page_reclaim(mi_theap_t* theap, mi_page_t* page);\nbool          _mi_theap_free(mi_theap_t* theap, bool acquire_heap_theaps_lock, bool acquire_tld_theaps_lock);\nvoid          _mi_theap_incref(mi_theap_t* theap);\nvoid          _mi_theap_decref(mi_theap_t* theap);\n\n// \"heap.c\"\nvoid          _mi_heap_area_init(mi_heap_area_t* area, mi_page_t* page);\nmi_decl_cold  mi_theap_t* _mi_heap_theap_get_or_init(const mi_heap_t* heap);  // get (and possible create) the theap belonging to a heap\nmi_decl_cold  mi_theap_t* _mi_heap_theap_get_peek(const mi_heap_t* heap);     // get the theap for a heap without initializing (and return NULL in that case)\nvoid          _mi_heap_move_pages(mi_heap_t* heap_from, mi_heap_t* heap_to);  // in \"arena.c\"\nvoid          _mi_heap_destroy_pages(mi_heap_t* heap_from);                   // in \"arena.c\"\nvoid          _mi_heap_force_destroy(mi_heap_t* heap);                        // allow destroying the main heap\n\n// \"stats.c\"\nvoid          _mi_stats_init(void);\nvoid          _mi_stats_merge_into(mi_stats_t* to, mi_stats_t* from);\n\nmi_msecs_t    _mi_clock_now(void);\nmi_msecs_t    _mi_clock_end(mi_msecs_t start);\nmi_msecs_t    _mi_clock_start(void);\n\n// \"alloc.c\"\nvoid*         _mi_page_malloc_zero(mi_theap_t* theap, mi_page_t* page, size_t size, bool zero) mi_attr_noexcept;                  // called from `_mi_theap_malloc_aligned`\nvoid*         _mi_theap_malloc_zero(mi_theap_t* theap, size_t size, bool zero, size_t* usable) mi_attr_noexcept;\nvoid*         _mi_theap_malloc_zero_ex(mi_theap_t* theap, size_t size, bool zero, size_t huge_alignment, size_t* usable) mi_attr_noexcept;     // called from `_mi_theap_malloc_aligned`\nvoid*         _mi_theap_realloc_zero(mi_theap_t* theap, void* p, size_t newsize, bool zero, size_t* usable_pre, size_t* usable_post) mi_attr_noexcept;\nmi_block_t*   _mi_page_ptr_unalign(const mi_page_t* page, const void* p);\nvoid          _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size);\n\n#if MI_DEBUG>1\nbool          _mi_page_is_valid(mi_page_t* page);\n#endif\n\n\n// ------------------------------------------------------\n// Assertions\n// ------------------------------------------------------\n\n#if (MI_DEBUG)\n// use our own assertion to print without memory allocation\nmi_decl_noreturn mi_decl_cold void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func) mi_attr_noexcept;\n#define mi_assert(expr)     ((expr) ? (void)0 : _mi_assert_fail(#expr,__FILE__,__LINE__,__func__))\n#else\n#define mi_assert(x)\n#endif\n\n#if (MI_DEBUG>1)\n#define mi_assert_internal    mi_assert\n#else\n#define mi_assert_internal(x)\n#endif\n\n#if (MI_DEBUG>2)\n#define mi_assert_expensive   mi_assert\n#else\n#define mi_assert_expensive(x)\n#endif\n\n\n/* -----------------------------------------------------------\n  Statistics (in `stats.c`)\n----------------------------------------------------------- */\n\n// add to stat keeping track of the peak\nvoid __mi_stat_increase(mi_stat_count_t* stat, size_t amount);\nvoid __mi_stat_decrease(mi_stat_count_t* stat, size_t amount);\nvoid __mi_stat_increase_mt(mi_stat_count_t* stat, size_t amount);\nvoid __mi_stat_decrease_mt(mi_stat_count_t* stat, size_t amount);\n\n// adjust stat in special cases to compensate for double counting (and does not adjust peak values and can decrease the total)\nvoid __mi_stat_adjust_increase(mi_stat_count_t* stat, size_t amount);\nvoid __mi_stat_adjust_decrease(mi_stat_count_t* stat, size_t amount);\nvoid __mi_stat_adjust_increase_mt(mi_stat_count_t* stat, size_t amount);\nvoid __mi_stat_adjust_decrease_mt(mi_stat_count_t* stat, size_t amount);\n\n// counters can just be increased\nvoid __mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount);\nvoid __mi_stat_counter_increase_mt(mi_stat_counter_t* stat, size_t amount);\n\n#define mi_heap_stat_counter_increase(heap,stat,amount)         __mi_stat_counter_increase_mt( &(heap)->stats.stat, amount)\n#define mi_heap_stat_increase(heap,stat,amount)                 __mi_stat_increase_mt( &(heap)->stats.stat, amount)\n#define mi_heap_stat_decrease(heap,stat,amount)                 __mi_stat_decrease_mt( &(heap)->stats.stat, amount)\n#define mi_heap_stat_adjust_increase(heap,stat,amnt)            __mi_stat_adjust_increase_mt( &(heap)->stats.stat, amnt)\n#define mi_heap_stat_adjust_decrease(heap,stat,amnt)            __mi_stat_adjust_decrease_mt( &(heap)->stats.stat, amnt)\n\n#define mi_subproc_stat_counter_increase(subproc,stat,amount)   __mi_stat_counter_increase_mt( &(subproc)->stats.stat, amount)\n#define mi_subproc_stat_increase(subproc,stat,amount)           __mi_stat_increase_mt( &(subproc)->stats.stat, amount)\n#define mi_subproc_stat_decrease(subproc,stat,amount)           __mi_stat_decrease_mt( &(subproc)->stats.stat, amount)\n#define mi_subproc_stat_adjust_increase(subproc,stat,amount)    __mi_stat_adjust_increase_mt( &(subproc)->stats.stat, amount)\n#define mi_subproc_stat_adjust_decrease(subproc,stat,amount)    __mi_stat_adjust_decrease_mt( &(subproc)->stats.stat, amount)\n\n#define mi_os_stat_counter_increase(stat,amount)                mi_subproc_stat_counter_increase(_mi_subproc(),stat,amount)\n#define mi_os_stat_increase(stat,amount)                        mi_subproc_stat_increase(_mi_subproc(),stat,amount)\n#define mi_os_stat_decrease(stat,amount)                        mi_subproc_stat_decrease(_mi_subproc(),stat,amount)\n\n#define mi_theap_stat_counter_increase(theap,stat,amount)       __mi_stat_counter_increase( &(theap)->stats.stat, amount)\n#define mi_theap_stat_increase(theap,stat,amount)               __mi_stat_increase( &(theap)->stats.stat, amount)\n#define mi_theap_stat_decrease(theap,stat,amount)               __mi_stat_decrease( &(theap)->stats.stat, amount)\n#define mi_theap_stat_adjust_increase(theap,stat,amnt)          __mi_stat_adjust_increase( &(theap)->stats.stat, amnt)\n#define mi_theap_stat_adjust_decrease(theap,stat,amnt)          __mi_stat_adjust_decrease( &(theap)->stats.stat, amnt)\n\n\n/* -----------------------------------------------------------\n  Options (exposed for the debugger)\n----------------------------------------------------------- */\ntypedef enum mi_option_init_e {\n  MI_OPTION_UNINIT,       // not yet initialized\n  MI_OPTION_DEFAULTED,    // not found in the environment, use default value\n  MI_OPTION_INITIALIZED   // found in environment or set explicitly\n} mi_option_init_t;\n\ntypedef struct mi_option_desc_s {\n  long              value;  // the value\n  mi_option_init_t  init;   // is it initialized yet? (from the environment)\n  mi_option_t       option; // for debugging: the option index should match the option\n  const char*       name;   // option name without `mimalloc_` prefix\n  const char*       legacy_name; // potential legacy option name\n} mi_option_desc_t;\n\n\n\n/* -----------------------------------------------------------\n  Inlined definitions\n----------------------------------------------------------- */\n#define MI_UNUSED(x)     (void)(x)\n#if (MI_DEBUG>1)\n#define MI_UNUSED_RELEASE(x)\n#else\n#define MI_UNUSED_RELEASE(x)  MI_UNUSED(x)\n#endif\n\n#define MI_INIT4(x)   x(),x(),x(),x()\n#define MI_INIT8(x)   MI_INIT4(x),MI_INIT4(x)\n#define MI_INIT16(x)  MI_INIT8(x),MI_INIT8(x)\n#define MI_INIT32(x)  MI_INIT16(x),MI_INIT16(x)\n#define MI_INIT64(x)  MI_INIT32(x),MI_INIT32(x)\n#define MI_INIT128(x) MI_INIT64(x),MI_INIT64(x)\n#define MI_INIT256(x) MI_INIT128(x),MI_INIT128(x)\n\n#define MI_INIT74(x)  MI_INIT64(x),MI_INIT8(x),x(),x()\n#define MI_INIT5(x)   MI_INIT4(x),x()\n#define MI_INIT6(x)   MI_INIT4(x),x(),x()\n\n#include <string.h>\n// initialize a local variable to zero; use memset as compilers optimize constant sized memset's\n#define _mi_memzero_var(x)  memset(&x,0,sizeof(x))\n\n// Is `x` a power of two? (0 is considered a power of two)\nstatic inline bool _mi_is_power_of_two(uintptr_t x) {\n  return ((x & (x - 1)) == 0);\n}\n\n// Is a pointer aligned?\nstatic inline bool _mi_is_aligned(const void* p, size_t alignment) {\n  return (alignment==0 || ((uintptr_t)p % alignment) == 0);\n}\n\n// Align upwards\nstatic inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) {\n  mi_assert_internal(alignment != 0);\n  uintptr_t mask = alignment - 1;\n  if ((alignment & mask) == 0) {  // power of two?\n    return ((sz + mask) & ~mask);\n  }\n  else {\n    return (((sz + mask)/alignment)*alignment);\n  }\n}\n\n// Align a pointer upwards\nstatic inline void* _mi_align_up_ptr(const void* p, size_t alignment) {\n  return (void*)_mi_align_up((uintptr_t)p, alignment);\n}\n\nstatic inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) {\n  mi_assert_internal(alignment != 0);\n  uintptr_t mask = alignment - 1;\n  if ((alignment & mask) == 0) { // power of two?\n    return (sz & ~mask);\n  }\n  else {\n    return ((sz / alignment) * alignment);\n  }\n}\n\n// align a pointer downwards\nstatic inline void* _mi_align_down_ptr(const void* p, size_t alignment) {\n  return (void*)_mi_align_down((uintptr_t)p, alignment);\n}\n\n// Divide upwards: `s <= _mi_divide_up(s,d)*d < s+d`.\nstatic inline uintptr_t _mi_divide_up(uintptr_t size, size_t divider) {\n  mi_assert_internal(divider != 0);\n  return (divider == 0 ? size : ((size + divider - 1) / divider));\n}\n\n\n// clamp an integer\nstatic inline size_t _mi_clamp(size_t sz, size_t min, size_t max) {\n  if (sz < min) return min;\n  else if (sz > max) return max;\n  else return sz;\n}\n\n// Is memory zero initialized?\nstatic inline bool mi_mem_is_zero(const void* p, size_t size) {\n  for (size_t i = 0; i < size; i++) {\n    if (((uint8_t*)p)[i] != 0) return false;\n  }\n  return true;\n}\n\n// Align a byte size to a size in _machine words_,\n// i.e. byte size == `wsize*sizeof(void*)`.\nstatic inline size_t _mi_wsize_from_size(size_t size) {\n  mi_assert_internal(size <= SIZE_MAX - sizeof(uintptr_t));\n  return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);\n}\n\n// Overflow detecting multiply\n#if __has_builtin(__builtin_umul_overflow) || (defined(__GNUC__) && (__GNUC__ >= 5))\n#include <limits.h>      // UINT_MAX, ULONG_MAX\n#if defined(_CLOCK_T)    // for Illumos\n#undef _CLOCK_T\n#endif\nstatic inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) {\n  #if (SIZE_MAX == ULONG_MAX)\n    return __builtin_umull_overflow(count, size, (unsigned long *)total);\n  #elif (SIZE_MAX == UINT_MAX)\n    return __builtin_umul_overflow(count, size, (unsigned int *)total);\n  #else\n    return __builtin_umulll_overflow(count, size, (unsigned long long *)total);\n  #endif\n}\n#else /* __builtin_umul_overflow is unavailable */\nstatic inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) {\n  *total = count*size;\n  if mi_likely(((size|count)>>(4*MI_SIZE_SIZE))==0) {  // did size and count fit both in the lower half bits of a size_t?\n    return false;\n  }\n  else {\n    return (size!=0 && (SIZE_MAX / size) < count);\n  }\n}\n#endif\n\n// Safe multiply `count*size` into `total`; return `true` on overflow.\nstatic inline bool mi_count_size_overflow(size_t count, size_t size, size_t* total) {\n  if (count==1) {  // quick check for the case where count is one (common for C++ allocators)\n    *total = size;\n    return false;\n  }\n  else if mi_likely(!mi_mul_overflow(count, size, total)) {\n    return false;\n  }\n  else {\n    #if MI_DEBUG > 0\n    _mi_error_message(EOVERFLOW, \"allocation request is too large (%zu * %zu bytes)\\n\", count, size);\n    #endif\n    *total = SIZE_MAX;\n    return true;\n  }\n}\n\n\n/*----------------------------------------------------------------------------------------\n  Heap functions\n------------------------------------------------------------------------------------------- */\n\nextern mi_decl_hidden const mi_theap_t _mi_theap_empty;       // read-only empty theap, initial value of the thread local default theap (in the MI_TLS_MODEL_THREAD_LOCAL)\nextern mi_decl_hidden const mi_theap_t _mi_theap_empty_wrong; // read-only empty theap used to signal that a theap for a heap could not be allocated\n\n\nstatic inline mi_heap_t* _mi_theap_heap(const mi_theap_t* theap) {\n  return mi_atomic_load_ptr_acquire(mi_heap_t,&theap->heap);\n}\n\nstatic inline bool mi_theap_is_initialized(const mi_theap_t* theap) {\n  return (theap != NULL && _mi_theap_heap(theap) != NULL);\n}\n\nstatic inline mi_page_t* _mi_theap_get_free_small_page(mi_theap_t* theap, size_t size) {\n  mi_assert_internal(size <= (MI_SMALL_SIZE_MAX + MI_PADDING_SIZE));\n  const size_t idx = _mi_wsize_from_size(size);\n  mi_assert_internal(idx < MI_PAGES_DIRECT);\n  return theap->pages_free_direct[idx];\n}\n\n\n//static inline uintptr_t _mi_ptr_cookie(const void* p) {\n//  extern mi_theap_t _mi_theap_main;\n//  mi_assert_internal(_mi_theap_main.cookie != 0);\n//  return ((uintptr_t)p ^ _mi_theap_main.cookie);\n//}\n\n\n/* -----------------------------------------------------------\n  The page map maps addresses to `mi_page_t` pointers\n----------------------------------------------------------- */\n\n#if MI_PAGE_MAP_FLAT\n\n// flat page-map committed on demand, using one byte per slice (64 KiB).\n// single indirection and low commit, but large initial virtual reserve (4 GiB with 48 bit virtual addresses)\n// used by default on <= 40 bit virtual address spaces.\nextern mi_decl_hidden uint8_t* _mi_page_map;\n\nstatic inline size_t _mi_page_map_index(const void* p) {\n  return (size_t)((uintptr_t)p >> MI_ARENA_SLICE_SHIFT);\n}\n\nstatic inline mi_page_t* _mi_ptr_page_ex(const void* p, bool* valid) {\n  const size_t idx = _mi_page_map_index(p);\n  const size_t ofs = _mi_page_map[idx];\n  if (valid != NULL) { *valid = (ofs != 0); }\n  return (mi_page_t*)((((uintptr_t)p >> MI_ARENA_SLICE_SHIFT) + 1 - ofs) << MI_ARENA_SLICE_SHIFT);\n}\n\nstatic inline mi_page_t* _mi_checked_ptr_page(const void* p) {\n  bool valid;\n  mi_page_t* const page = _mi_ptr_page_ex(p, &valid);\n  return (valid ? page : NULL);\n}\n\nstatic inline mi_page_t* _mi_unchecked_ptr_page(const void* p) {\n  return _mi_ptr_page_ex(p, NULL);\n}\n\n#else\n\n// 2-level page map:\n// double indirection, but low commit and low virtual reserve.\n//\n// the page-map is usually 4 MiB (for 48 bit virtual addresses) and points to sub maps of 64 KiB.\n// the page-map is committed on-demand (in 64 KiB parts) (and sub-maps are committed on-demand as well)\n// one sub page-map = 64 KiB => covers 2^(16-3) * 2^16 = 2^29 = 512 MiB address space\n// the page-map needs 48-(16+13) = 19 bits => 2^19 sub map pointers = 2^22 bytes = 4 MiB reserved size.\n#define MI_PAGE_MAP_SUB_SHIFT     (13)\n#define MI_PAGE_MAP_SUB_COUNT     (MI_ZU(1) << MI_PAGE_MAP_SUB_SHIFT)\n#define MI_PAGE_MAP_SHIFT         (MI_MAX_VABITS - MI_PAGE_MAP_SUB_SHIFT - MI_ARENA_SLICE_SHIFT)\n#define MI_PAGE_MAP_COUNT         (MI_ZU(1) << MI_PAGE_MAP_SHIFT)\n\ntypedef mi_page_t**   mi_submap_t;\nextern mi_decl_hidden _Atomic(mi_submap_t)* _mi_page_map;\n\nstatic inline size_t _mi_page_map_index(const void* p, size_t* sub_idx) {\n  const size_t u = (size_t)((uintptr_t)p / MI_ARENA_SLICE_SIZE);\n  if (sub_idx != NULL) { *sub_idx = u % MI_PAGE_MAP_SUB_COUNT; }\n  return (u / MI_PAGE_MAP_SUB_COUNT);\n}\n\nstatic inline mi_submap_t _mi_page_map_at(size_t idx) {\n  return mi_atomic_load_ptr_relaxed(mi_page_t*, &_mi_page_map[idx]);\n}\n\nstatic inline mi_page_t* _mi_unchecked_ptr_page(const void* p) {\n  size_t sub_idx;\n  const size_t idx = _mi_page_map_index(p, &sub_idx);\n  return (_mi_page_map_at(idx))[sub_idx];  // NULL if p==NULL\n}\n\nstatic inline mi_page_t* _mi_checked_ptr_page(const void* p) {\n  size_t sub_idx;\n  const size_t idx = _mi_page_map_index(p, &sub_idx);\n  mi_submap_t const sub = _mi_page_map_at(idx);\n  if mi_unlikely(sub == NULL) return NULL;\n  return sub[sub_idx];\n}\n\n#endif\n\n\nstatic inline mi_page_t* _mi_ptr_page(const void* p) {\n  mi_assert_internal(p==NULL || mi_is_in_heap_region(p));\n  #if MI_DEBUG || MI_SECURE || defined(__APPLE__)\n  return _mi_checked_ptr_page(p);\n  #else\n  return _mi_unchecked_ptr_page(p);\n  #endif\n}\n\n\n// Get the block size of a page\nstatic inline size_t mi_page_block_size(const mi_page_t* page) {\n  mi_assert_internal(page->block_size > 0);\n  return page->block_size;\n}\n\n// Page start\nstatic inline uint8_t* mi_page_start(const mi_page_t* page) {\n  return page->page_start;\n}\n\nstatic inline size_t mi_page_size(const mi_page_t* page) {\n  return mi_page_block_size(page) * page->reserved;\n}\n\nstatic inline uint8_t* mi_page_area(const mi_page_t* page, size_t* size) {\n  if (size) { *size = mi_page_size(page); }\n  return mi_page_start(page);\n}\n\nstatic inline size_t mi_page_info_size(void) {\n  return _mi_align_up(sizeof(mi_page_t), MI_MAX_ALIGN_SIZE);\n}\n\nstatic inline bool mi_page_contains_address(const mi_page_t* page, const void* p) {\n  size_t psize;\n  uint8_t* start = mi_page_area(page, &psize);\n  return (start <= (uint8_t*)p && (uint8_t*)p < start + psize);\n}\n\nstatic inline bool mi_page_is_in_arena(const mi_page_t* page) {\n  return (page->memid.memkind == MI_MEM_ARENA);\n}\n\nstatic inline bool mi_page_is_singleton(const mi_page_t* page) {\n  return (page->reserved == 1);\n}\n\n// Get the usable block size of a page without fixed padding.\n// This may still include internal padding due to alignment and rounding up size classes.\nstatic inline size_t mi_page_usable_block_size(const mi_page_t* page) {\n  return mi_page_block_size(page) - MI_PADDING_SIZE;\n}\n\nstatic inline bool mi_page_meta_is_separated(const mi_page_t* page) {\n  #if MI_PAGE_META_IS_SEPARATED\n  // usually separated but can still be in front for direct OS allocations (due to size or alignment) or due to MI_PAGE_META_ALIGNED_FREE_SMALL\n  return (page->memid.memkind == MI_MEM_ARENA && page != _mi_align_down_ptr(page->page_start, MI_ARENA_SLICE_ALIGN));\n  #else\n  MI_UNUSED(page);\n  return false;  \n  #endif\n}\n\nstatic inline uint8_t* mi_page_slice_start(const mi_page_t* page) {\n  if (mi_page_meta_is_separated(page)) {  \n    // page meta info is at a separate location (at `arena->pages`)\n    return (uint8_t*)_mi_align_down_ptr(page->page_start, MI_ARENA_SLICE_ALIGN);\n  }\n  else {\n    // page meta info is at the start of the page slices\n    return (uint8_t*)page;\n  }\n}\n\n// This gives the offset relative to the start slice of a page. \nstatic inline size_t mi_page_slice_offset_of(const mi_page_t* page, size_t offset_relative_to_page_start) {\n  return (page->page_start - mi_page_slice_start(page)) + offset_relative_to_page_start;\n}\n\n// Currently committed part of a page\nstatic inline size_t mi_page_committed(const mi_page_t* page) {\n  return (page->slice_committed == 0 ? mi_page_size(page) : page->slice_committed - mi_page_slice_offset_of(page,0));\n}\n\n// are all blocks in a page freed?\n// note: needs up-to-date used count, (as the `xthread_free` list may not be empty). see `_mi_page_collect_free`.\nstatic inline bool mi_page_all_free(const mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  return (page->used == 0);\n}\n\n// are there immediately available blocks, i.e. blocks available on the free list.\nstatic inline bool mi_page_immediate_available(const mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  return (page->free != NULL);\n}\n\n\n// is the page not yet used up to its reserved space?\nstatic inline bool mi_page_is_expandable(const mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_assert_internal(page->capacity <= page->reserved);\n  return (page->capacity < page->reserved);\n}\n\n\nstatic inline bool mi_page_is_full(const mi_page_t* page) {\n  const bool full = (page->reserved == page->used);\n  mi_assert_internal(!full || page->free == NULL);\n  return full;\n}\n\n// is more than 7/8th of a page in use?\nstatic inline bool mi_page_is_mostly_used(const mi_page_t* page) {\n  if (page==NULL) return true;\n  uint16_t frac = page->reserved / 8U;\n  return (page->reserved - page->used <= frac);\n}\n\n// is more than (n-1)/n'th of a page in use?\nstatic inline bool mi_page_is_used_at_frac(const mi_page_t* page, uint16_t n) {\n  if (page==NULL) return true;\n  uint16_t frac = page->reserved / n;\n  return (page->reserved - page->used <= frac);\n}\n\n\nstatic inline bool mi_page_is_huge(const mi_page_t* page) {\n  return (mi_page_is_singleton(page) &&\n          (page->block_size > MI_LARGE_MAX_OBJ_SIZE ||\n           (mi_memkind_is_os(page->memid.memkind) && page->memid.mem.os.base < (void*)page)));\n}\n\nstatic inline mi_page_queue_t* mi_page_queue(const mi_theap_t* theap, size_t size) {\n  mi_page_queue_t* const pq = &((mi_theap_t*)theap)->pages[_mi_bin(size)];\n  if (size <= MI_LARGE_MAX_OBJ_SIZE) { mi_assert_internal(pq->block_size <= MI_LARGE_MAX_OBJ_SIZE); }\n  return pq;\n}\n\n\n//-----------------------------------------------------------\n// Page thread id and flags\n//-----------------------------------------------------------\n\n// Thread id of thread that owns this page (with flags in the bottom 2 bits)\nstatic inline mi_threadid_t mi_page_xthread_id(const mi_page_t* page) {\n  return mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_id);\n}\n\n// Plain thread id of the thread that owns this page\nstatic inline mi_threadid_t mi_page_thread_id(const mi_page_t* page) {\n  return (mi_page_xthread_id(page) & ~MI_PAGE_FLAG_MASK);\n}\n\nstatic inline mi_page_flags_t mi_page_flags(const mi_page_t* page) {\n  return (mi_page_xthread_id(page) & MI_PAGE_FLAG_MASK);\n}\n\nstatic inline bool mi_page_flags_set(mi_page_t* page, bool set, mi_page_flags_t newflag) {\n  mi_page_flags_t old;\n  if (set) { old = mi_atomic_or_relaxed(&page->xthread_id, newflag); }\n      else { old = mi_atomic_and_relaxed(&page->xthread_id, ~newflag); }\n  return ((old & newflag) == newflag);\n}\n\nstatic inline bool mi_page_is_in_full(const mi_page_t* page) {\n  return ((mi_page_flags(page) & MI_PAGE_IN_FULL_QUEUE) != 0);\n}\n\nstatic inline void mi_page_set_in_full(mi_page_t* page, bool in_full) {\n  const bool was_in_full = mi_page_flags_set(page, in_full, MI_PAGE_IN_FULL_QUEUE);\n  if (was_in_full != in_full) {\n    // optimize: maintain pages_full_size to avoid visiting the full queue (issue #1220)\n    mi_theap_t* const theap = page->theap;\n    mi_assert_internal(theap!=NULL);\n    if (theap != NULL) {\n      const size_t size = page->capacity * mi_page_block_size(page);\n      if (in_full) { theap->pages_full_size += size; }\n              else { mi_assert_internal(size <= theap->pages_full_size); theap->pages_full_size -= size; }\n    }\n  }\n}\n\nstatic inline bool mi_page_has_interior_pointers(const mi_page_t* page) {\n  return ((mi_page_flags(page) & MI_PAGE_HAS_INTERIOR_POINTERS) != 0);\n}\n\nstatic inline void mi_page_set_has_interior_pointers(mi_page_t* page, bool has_aligned) {\n  mi_page_flags_set(page, has_aligned, MI_PAGE_HAS_INTERIOR_POINTERS);\n}\n\nstatic inline void mi_page_set_theap(mi_page_t* page, mi_theap_t* theap) {\n  // mi_assert_internal(!mi_page_is_in_full(page));  // can happen when destroying pages on theap_destroy\n  page->theap = theap;\n  const mi_threadid_t tid = (theap == NULL ? MI_THREADID_ABANDONED : theap->tld->thread_id);\n  mi_assert_internal((tid & MI_PAGE_FLAG_MASK) == 0);\n\n  // we need to use an atomic cas since a concurrent thread may still set the MI_PAGE_HAS_INTERIOR_POINTERS flag (see `alloc_aligned.c`).\n  mi_threadid_t xtid_old = mi_page_xthread_id(page);\n  mi_threadid_t xtid;\n  do {\n    xtid = tid | (xtid_old & MI_PAGE_FLAG_MASK);\n  } while (!mi_atomic_cas_weak_release(&page->xthread_id, &xtid_old, xtid));\n}\n\nstatic inline bool mi_page_is_abandoned(const mi_page_t* page) {\n  // note: the xtheap field of an abandoned theap is set to the subproc (for fast reclaim-on-free)\n  return (mi_page_thread_id(page) <= MI_THREADID_ABANDONED_MAPPED);\n}\n\nstatic inline bool mi_page_is_abandoned_mapped(const mi_page_t* page) {\n  return (mi_page_thread_id(page) == MI_THREADID_ABANDONED_MAPPED);\n}\n\nstatic inline void mi_page_set_abandoned_mapped(mi_page_t* page) {\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_atomic_or_relaxed(&page->xthread_id, (mi_threadid_t)MI_THREADID_ABANDONED_MAPPED);\n}\n\nstatic inline void mi_page_clear_abandoned_mapped(mi_page_t* page) {\n  mi_assert_internal(mi_page_is_abandoned_mapped(page));\n  mi_atomic_and_relaxed(&page->xthread_id, (mi_threadid_t)MI_PAGE_FLAG_MASK);\n}\n\n\nstatic inline mi_theap_t* mi_page_theap(const mi_page_t* page) {\n  mi_assert_internal(!mi_page_is_abandoned(page));\n  mi_assert_internal(page->theap != NULL);\n  return page->theap;\n}\n\nstatic inline mi_tld_t* mi_page_tld(const mi_page_t* page) {\n  mi_assert_internal(!mi_page_is_abandoned(page));\n  mi_assert_internal(page->theap != NULL);\n  return page->theap->tld;\n}\n\n\nstatic inline mi_heap_t* mi_page_heap(const mi_page_t* page) {\n  mi_heap_t* heap = page->heap;\n  // we use NULL for the main heap to make `_mi_page_get_associated_theap` fast in `free.c:mi_abandoned_page_try_reclaim`.\n  if mi_likely(heap==NULL) heap = mi_heap_main();\n  mi_assert_internal(heap != NULL);\n  return heap;\n}\n\n//-----------------------------------------------------------\n// Thread free list and ownership\n//-----------------------------------------------------------\n\n// Thread free flag helpers\nstatic inline mi_block_t* mi_tf_block(mi_thread_free_t tf) {\n  return (mi_block_t*)(tf & ~1);\n}\nstatic inline bool mi_tf_is_owned(mi_thread_free_t tf) {\n  return ((tf & 1) == 1);\n}\nstatic inline mi_thread_free_t mi_tf_create(mi_block_t* block, bool owned) {\n  return (mi_thread_free_t)((uintptr_t)block | (owned ? 1 : 0));\n}\n\n// Thread free access\nstatic inline mi_block_t* mi_page_thread_free(const mi_page_t* page) {\n  return mi_tf_block(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free));\n}\n\n// are there any available blocks?\nstatic inline bool mi_page_has_any_available(const mi_page_t* page) {\n  mi_assert_internal(page != NULL && page->reserved > 0);\n  return (page->used < page->reserved || (mi_page_thread_free(page) != NULL));\n}\n\n// Owned?\nstatic inline bool mi_page_is_owned(const mi_page_t* page) {\n  return mi_tf_is_owned(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free));\n}\n\n// get ownership; returns true if the page was not owned before.\nstatic inline bool mi_page_claim_ownership(mi_page_t* page) {\n  const uintptr_t old = mi_atomic_or_acq_rel(&page->xthread_free, (uintptr_t)1);\n  return ((old&1)==0);\n}\n\n\n/* -------------------------------------------------------------------\n  Guarded objects\n------------------------------------------------------------------- */\n#if MI_GUARDED\n// we always align guarded pointers in a block at an offset\n// the block `next` field is then used as a tag to distinguish regular offset aligned blocks from guarded ones\n#define MI_BLOCK_TAG_ALIGNED   ((mi_encoded_t)(0))\n#define MI_BLOCK_TAG_GUARDED   (~MI_BLOCK_TAG_ALIGNED)\n#endif\n\nstatic inline bool mi_block_ptr_is_guarded(const mi_block_t* block, const void* p) {\n#if MI_GUARDED\n  const ptrdiff_t offset = (uint8_t*)p - (uint8_t*)block;\n  return (offset >= (ptrdiff_t)(sizeof(mi_block_t)) && block->next == MI_BLOCK_TAG_GUARDED);\n#else\n  MI_UNUSED(block); MI_UNUSED(p);\n  return false;\n#endif  \n}\n\n#if MI_GUARDED\nstatic inline bool mi_theap_malloc_use_guarded(mi_theap_t* theap, size_t size) {\n  // this code is written to result in fast assembly as it is on the hot path for allocation\n  const size_t count = theap->guarded_sample_count - 1;  // if the rate was 0, this will underflow and count for a long time..\n  if mi_likely(count != 0) {\n    // no sample\n    theap->guarded_sample_count = count;\n    return false;\n  }\n  else if (size >= theap->guarded_size_min && size <= theap->guarded_size_max) {\n    // use guarded allocation\n    theap->guarded_sample_count = theap->guarded_sample_rate;  // reset\n    return (theap->guarded_sample_rate != 0);\n  }\n  else {\n    // failed size criteria, rewind count (but don't write to an empty theap)\n    if (theap->guarded_sample_rate != 0) { theap->guarded_sample_count = 1; }\n    return false;\n  }\n}\n\nmi_decl_restrict void* _mi_theap_malloc_guarded(mi_theap_t* theap, size_t size, bool zero) mi_attr_noexcept;\n\n#endif\n\n\n/* -------------------------------------------------------------------\nEncoding/Decoding the free list next pointers\n\nThis is to protect against buffer overflow exploits where the\nfree list is mutated. Many hardened allocators xor the next pointer `p`\nwith a secret key `k1`, as `p^k1`. This prevents overwriting with known\nvalues but might be still too weak: if the attacker can guess\nthe pointer `p` this  can reveal `k1` (since `p^k1^p == k1`).\nMoreover, if multiple blocks can be read as well, the attacker can\nxor both as `(p1^k1) ^ (p2^k1) == p1^p2` which may reveal a lot\nabout the pointers (and subsequently `k1`).\n\nInstead mimalloc uses an extra key `k2` and encodes as `((p^k2)<<<k1)+k1`.\nSince these operations are not associative, the above approaches do not\nwork so well any more even if the `p` can be guesstimated. For example,\nfor the read case we can subtract two entries to discard the `+k1` term,\nbut that leads to `((p1^k2)<<<k1) - ((p2^k2)<<<k1)` at best.\nWe include the left-rotation since xor and addition are otherwise linear\nin the lowest bit. Finally, both keys are unique per page which reduces\nthe re-use of keys by a large factor.\n\nWe also pass a separate `null` value to be used as `NULL` or otherwise\n`(k2<<<k1)+k1` would appear (too) often as a sentinel value.\n------------------------------------------------------------------- */\n\nstatic inline bool mi_is_in_same_page(const void* p, const void* q) {\n  mi_page_t* page = _mi_ptr_page(p);\n  return mi_page_contains_address(page,q);\n  // return (_mi_ptr_page(p) == _mi_ptr_page(q));\n}\n\nstatic inline void* mi_ptr_decode(const void* null, const mi_encoded_t x, const uintptr_t* keys) {\n  void* p = (void*)(mi_rotr(x - keys[0], keys[0]) ^ keys[1]);\n  return (p==null ? NULL : p);\n}\n\nstatic inline mi_encoded_t mi_ptr_encode(const void* null, const void* p, const uintptr_t* keys) {\n  uintptr_t x = (uintptr_t)(p==NULL ? null : p);\n  return mi_rotl(x ^ keys[1], keys[0]) + keys[0];\n}\n\nstatic inline uint32_t mi_ptr_encode_canary(const void* null, const void* p, const uintptr_t* keys) {\n  const uint32_t x = (uint32_t)(mi_ptr_encode(null,p,keys));\n  // make the lowest byte 0 to prevent spurious read overflows which could be a security issue (issue #951)\n  #if MI_BIG_ENDIAN\n  return (x & 0x00FFFFFF);\n  #else\n  return (x & 0xFFFFFF00);\n  #endif\n}\n\nstatic inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* block, const uintptr_t* keys ) {\n  mi_track_mem_defined(block,sizeof(mi_block_t));\n  mi_block_t* next;\n  #if MI_ENCODE_FREELIST\n  next = (mi_block_t*)mi_ptr_decode(null, block->next, keys);\n  #else\n  MI_UNUSED(keys); MI_UNUSED(null);\n  next = (mi_block_t*)block->next;\n  #endif\n  mi_track_mem_noaccess(block,sizeof(mi_block_t));\n  return next;\n}\n\nstatic inline void mi_block_set_nextx(const void* null, mi_block_t* block, const mi_block_t* next, const uintptr_t* keys) {\n  mi_track_mem_undefined(block,sizeof(mi_block_t));\n  #if MI_ENCODE_FREELIST\n  block->next = mi_ptr_encode(null, next, keys);\n  #else\n  MI_UNUSED(keys); MI_UNUSED(null);\n  block->next = (mi_encoded_t)next;\n  #endif\n  mi_track_mem_noaccess(block,sizeof(mi_block_t));\n}\n\nstatic inline mi_block_t* mi_block_next(const mi_page_t* page, const mi_block_t* block) {\n  #if MI_ENCODE_FREELIST\n  mi_block_t* next = mi_block_nextx(page,block,page->keys);\n  // check for free list corruption: is `next` at least in the same page?\n  // TODO: check if `next` is `page->block_size` aligned?\n  if mi_unlikely(next!=NULL && !mi_is_in_same_page(block, next)) {\n    _mi_error_message(EFAULT, \"corrupted free list entry of size %zub at %p: value 0x%zx\\n\", mi_page_block_size(page), block, (uintptr_t)next);\n    next = NULL;\n  }\n  return next;\n  #else\n  MI_UNUSED(page);\n  return mi_block_nextx(page,block,NULL);\n  #endif\n}\n\nstatic inline void mi_block_set_next(const mi_page_t* page, mi_block_t* block, const mi_block_t* next) {\n  #if MI_ENCODE_FREELIST\n  mi_block_set_nextx(page,block,next, page->keys);\n  #else\n  MI_UNUSED(page);\n  mi_block_set_nextx(page,block,next,NULL);\n  #endif\n}\n\n/* -----------------------------------------------------------\n  arena blocks\n----------------------------------------------------------- */\n\n// Blocks needed for a given byte size\nstatic inline size_t mi_slice_count_of_size(size_t size) {\n  return _mi_divide_up(size, MI_ARENA_SLICE_SIZE);\n}\n\n// Byte size of a number of blocks\nstatic inline size_t mi_size_of_slices(size_t bcount) {\n  return (bcount * MI_ARENA_SLICE_SIZE);\n}\n\n\n/* -----------------------------------------------------------\n  memory id's\n----------------------------------------------------------- */\n\nstatic inline mi_memid_t _mi_memid_create(mi_memkind_t memkind) {\n  mi_memid_t memid;\n  _mi_memzero_var(memid);\n  memid.memkind = memkind;\n  return memid;\n}\n\nstatic inline mi_memid_t _mi_memid_none(void) {\n  return _mi_memid_create(MI_MEM_NONE);\n}\n\nstatic inline mi_memid_t _mi_memid_create_os(void* base, size_t size, bool committed, bool is_zero, bool is_large) {\n  mi_memid_t memid = _mi_memid_create(MI_MEM_OS);\n  memid.mem.os.base = base;\n  memid.mem.os.size = size;\n  memid.initially_committed = committed;\n  memid.initially_zero = is_zero;\n  memid.is_pinned = is_large;\n  return memid;\n}\n\nstatic inline mi_memid_t _mi_memid_create_meta(void* mpage, size_t block_idx, size_t block_count) {\n  mi_memid_t memid = _mi_memid_create(MI_MEM_META);\n  memid.mem.meta.meta_page = mpage;\n  memid.mem.meta.block_index = (uint32_t)block_idx;\n  memid.mem.meta.block_count = (uint32_t)block_count;\n  memid.initially_committed = true;\n  memid.initially_zero = true;\n  memid.is_pinned = true;\n  return memid;\n}\n\n\n// -------------------------------------------------------------------\n// Fast \"random\" shuffle\n// -------------------------------------------------------------------\n\nstatic inline uintptr_t _mi_random_shuffle(uintptr_t x) {\n  if (x==0) { x = 17; }   // ensure we don't get stuck in generating zeros\n#if (MI_INTPTR_SIZE>=8)\n  // by Sebastiano Vigna, see: <http://xoshiro.di.unimi.it/splitmix64.c>\n  x ^= x >> 30;\n  x *= 0xbf58476d1ce4e5b9UL;\n  x ^= x >> 27;\n  x *= 0x94d049bb133111ebUL;\n  x ^= x >> 31;\n#elif (MI_INTPTR_SIZE==4)\n  // by Chris Wellons, see: <https://nullprogram.com/blog/2018/07/31/>\n  x ^= x >> 16;\n  x *= 0x7feb352dUL;\n  x ^= x >> 15;\n  x *= 0x846ca68bUL;\n  x ^= x >> 16;\n#endif\n  return x;\n}\n\n\n// ---------------------------------------------------------------------------------\n// Provide our own `_mi_memcpy/set` for potential performance optimizations.\n//\n// For now, only on x64/x86 we optimize to `rep movsb/stosb`.\n// Generally, we check for \"fast short rep movsb/stosb\" (FSRM/FSRS) or \"fast enhanced rep movsb\" (ERMS) support\n// (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017). See also issue #201 and pr #253.\n// Todo: we see improvements on win32 but less with glibc; we might want to only enable this on windows.\n// ---------------------------------------------------------------------------------\n\n#if !MI_TRACK_ENABLED && (MI_ARCH_X64 || MI_ARCH_X86) && (defined(_WIN32) || defined(__GNUC__))\n\nextern mi_decl_hidden size_t _mi_cpu_movsb_max;  // in init.c\nextern mi_decl_hidden size_t _mi_cpu_stosb_max;\n\nstatic inline void mi_rep_movsb(void* dst, const void* src, size_t n) {\n  #if defined(__GNUC__)\n  __asm volatile(\"rep movsb\" : \"+D\"(dst), \"+c\"(n), \"+S\"(src) : : \"memory\");\n  #else\n  __movsb((unsigned char*)dst, (const unsigned char*)src, n);\n  #endif\n}\n\nstatic inline void mi_rep_stosb(void* dst, uint8_t val, size_t n) {\n  #if defined(__GNUC__)\n  __asm volatile(\"rep stosb\" : \"+D\"(dst), \"+c\"(n) : \"a\"(val) : \"memory\");\n  #else\n  __stosb((unsigned char*)dst, val, n);\n  #endif\n}\n\nstatic inline void _mi_memcpy(void* dst, const void* src, size_t n) {\n  if mi_likely(n <= _mi_cpu_movsb_max) {  // has fsrm && n <= 127  (todo: and maybe has erms?)\n    mi_rep_movsb(dst, src, n);\n  }\n  else {\n    memcpy(dst, src, n);\n  }\n}\n\nstatic inline void _mi_memset(void* dst, int val, size_t n) {\n  if mi_likely(n <= _mi_cpu_stosb_max) {  // has fsrs && n <= 127\n    mi_rep_stosb(dst, (uint8_t)val, n);\n  }\n  else {\n    memset(dst, val, n);\n  }\n}\n\n#else\n\nstatic inline void _mi_memcpy(void* dst, const void* src, size_t n) {\n  memcpy(dst, src, n);\n}\n\nstatic inline void _mi_memset(void* dst, int val, size_t n) {\n  memset(dst, val, n);\n}\n\n#endif\n\n// -------------------------------------------------------------------------------\n// The `_mi_memcpy_aligned` can be used if the pointers are machine-word aligned\n// This is used for example in `mi_realloc`.\n// -------------------------------------------------------------------------------\n\n#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)\n\n// On GCC/CLang we provide a hint that the pointers are word aligned.\nstatic inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) {\n  mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0));\n  void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE);\n  const void* asrc = __builtin_assume_aligned(src, MI_INTPTR_SIZE);\n  _mi_memcpy(adst, asrc, n);\n}\n\nstatic inline void _mi_memset_aligned(void* dst, int val, size_t n) {\n  mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0);\n  void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE);\n  _mi_memset(adst, val, n);\n}\n\n#else\n\n// Default fallback on `_mi_memcpy`\nstatic inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) {\n  mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0));\n  _mi_memcpy(dst, src, n);\n}\n\nstatic inline void _mi_memset_aligned(void* dst, int val, size_t n) {\n  mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0);\n  _mi_memset(dst, val, n);\n}\n\n#endif\n\nstatic inline void _mi_memzero(void* dst, size_t n) {\n  _mi_memset(dst, 0, n);\n}\n\nstatic inline void _mi_memzero_aligned(void* dst, size_t n) {\n  _mi_memset_aligned(dst, 0, n);\n}\n\n\n\n#endif  // MI_INTERNAL_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/include/mimalloc/prim.h",
      "sha256": "555302d2fcd05e974441d0c9c9208c26e860db4b3f17b9025a08f42e0f4807ba",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MIMALLOC_PRIM_H\n#define MIMALLOC_PRIM_H\n#include \"internal.h\"             // mi_decl_hidden\n\n// --------------------------------------------------------------------------\n// This file specifies the primitive portability API.\n// Each OS/host needs to implement these primitives, see `src/prim`\n// for implementations on Window, macOS, WASI, and Linux/Unix.\n//\n// note: on all primitive functions, we always have result parameters != NULL, and:\n//  addr != NULL and page aligned\n//  size > 0     and page aligned\n//  the return value is an error code as an `int` where 0 is success\n// --------------------------------------------------------------------------\n\n// OS memory configuration\ntypedef struct mi_os_mem_config_s {\n  size_t  page_size;              // default to 4KiB\n  size_t  large_page_size;        // 0 if not supported, usually 2MiB (4MiB on Windows)\n  size_t  alloc_granularity;      // smallest allocation size (usually 4KiB, on Windows 64KiB)\n  size_t  physical_memory_in_kib; // physical memory size in KiB\n  size_t  virtual_address_bits;   // usually 48 or 56 bits on 64-bit systems. (used to determine secure randomization)\n  bool    has_overcommit;         // can we reserve more memory than can be actually committed?\n  bool    has_partial_free;       // can allocated blocks be freed partially? (true for mmap, false for VirtualAlloc)\n  bool    has_virtual_reserve;    // supports virtual address space reservation? (if true we can reserve virtual address space without using commit or physical memory)\n  bool    has_transparent_huge_pages;  // true if transparent huge pages are enabled (on Linux)\n} mi_os_mem_config_t;\n\n// Initialize\nvoid _mi_prim_mem_init( mi_os_mem_config_t* config );\n\n// Free OS memory\nint _mi_prim_free(void* addr, size_t size );\n\n// Allocate OS memory. Return NULL on error.\n// The `try_alignment` is just a hint and the returned pointer does not have to be aligned.\n// If `commit` is false, the virtual memory range only needs to be reserved (with no access)\n// which will later be committed explicitly using `_mi_prim_commit`.\n// `is_zero` is set to true if the memory was zero initialized (as on most OS's)\n// The `hint_addr` address is either `NULL` or a preferred allocation address but can be ignored.\n// pre: !commit => !allow_large\n//      try_alignment >= _mi_os_page_size() and a power of 2\nint _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr);\n\n// Commit memory. Returns error code or 0 on success.\n// For example, on Linux this would make the memory PROT_READ|PROT_WRITE.\n// `is_zero` is set to true if the memory was zero initialized (e.g. on Windows)\nint _mi_prim_commit(void* addr, size_t size, bool* is_zero);\n\n// Decommit memory. Returns error code or 0 on success. The `needs_recommit` result is true\n// if the memory would need to be re-committed. For example, on Windows this is always true,\n// but on Linux we could use MADV_DONTNEED to decommit which does not need a recommit.\n// pre: needs_recommit != NULL\nint _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit);\n\n// Reset memory. The range keeps being accessible but the content might be reset to zero at any moment.\n// Returns error code or 0 on success.\nint _mi_prim_reset(void* addr, size_t size);\n\n// Reuse memory. This is called for memory that is already committed but\n// may have been reset (`_mi_prim_reset`) or decommitted (`_mi_prim_decommit`) where `needs_recommit` was false.\n// Returns error code or 0 on success. On most platforms this is a no-op.\nint _mi_prim_reuse(void* addr, size_t size);\n\n// Protect memory. Returns error code or 0 on success.\nint _mi_prim_protect(void* addr, size_t size, bool protect);\n\n// Allocate huge (1GiB) pages possibly associated with a NUMA node.\n// `is_zero` is set to true if the memory was zero initialized (as on most OS's)\n// pre: size > 0  and a multiple of 1GiB.\n//      numa_node is either negative (don't care), or a numa node number.\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr);\n\n// Return the current NUMA node\nsize_t _mi_prim_numa_node(void);\n\n// Return the number of logical NUMA nodes\nsize_t _mi_prim_numa_node_count(void);\n\n// Clock ticks\nmi_msecs_t _mi_prim_clock_now(void);\n\n// Return process information (only for statistics)\ntypedef struct mi_process_info_s {\n  mi_msecs_t  elapsed;\n  mi_msecs_t  utime;\n  mi_msecs_t  stime;\n  size_t      current_rss;\n  size_t      peak_rss;\n  size_t      current_commit;\n  size_t      peak_commit;\n  size_t      page_faults;\n} mi_process_info_t;\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo);\n\n// Default stderr output. (only for warnings etc. with verbose enabled)\n// msg != NULL && _mi_strlen(msg) > 0\nvoid _mi_prim_out_stderr( const char* msg );\n\n// Get an environment variable. (only for options)\n// name != NULL, result != NULL, result_size >= 64\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size);\n\n\n// Fill a buffer with strong randomness; return `false` on error or if\n// there is no strong randomization available.\nbool _mi_prim_random_buf(void* buf, size_t buf_len);\n\n// Called on the first thread start, and should ensure `_mi_thread_done` is called on thread termination.\nvoid _mi_prim_thread_init_auto_done(void);\n\n// Called on process exit and may take action to clean up resources associated with the thread auto done.\nvoid _mi_prim_thread_done_auto_done(void);\n\n// Called when the default theap for a thread changes\nvoid _mi_prim_thread_associate_default_theap(mi_theap_t* theap);\n\n// Is this thread part of a thread pool?\nbool _mi_prim_thread_is_in_threadpool(void);\n\n// Yield to other threads. Should be similar to `sleep(0)`. \n// Is called only in rare situations and does not have to be lightning fast.\nvoid _mi_prim_thread_yield(void);\n\n//-------------------------------------------------------------------\n// Access to TLS (thread local storage) slots.\n// We need fast access to both a unique thread id (in `free.c:mi_free`) and\n// to a thread-local theap pointer (in `alloc.c:mi_malloc`).\n// To achieve this we use specialized code for various platforms.\n//-------------------------------------------------------------------\n\n// On some libc + platform combinations we can directly access a thread-local storage (TLS) slot.\n// The TLS layout depends on both the OS and libc implementation so we use specific tests for each main platform.\n// If you test on another platform and it works please send a PR :-)\n// see also https://akkadia.org/drepper/tls.pdf for more info on the TLS register.\n//\n// Note: we would like to prefer `__builtin_thread_pointer()` nowadays instead of using assembly,\n// but unfortunately we can not detect support reliably (see issue #883)\n// We also use it on Apple OS as we use a TLS slot for the default theap there.\n#if (defined(_WIN32)) || \\\n    (defined(__GNUC__) && ( \\\n           (defined(__GLIBC__)   && (defined(__x86_64__) || defined(__i386__) || (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__))) \\\n        || (defined(__APPLE__)   && (defined(__x86_64__) || defined(__aarch64__) || defined(__POWERPC__))) \\\n        || (defined(__BIONIC__)  && (defined(__x86_64__) || defined(__i386__) || (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__))) \\\n        || (defined(__FreeBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \\\n        || (defined(__OpenBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \\\n      ))\n\nstatic inline void* mi_prim_tls_slot(size_t slot) mi_attr_noexcept {\n  void* res;\n  const size_t ofs = (slot*sizeof(void*));\n  #if defined(_WIN32)\n    #if (_M_X64 || _M_AMD64) && !defined(_M_ARM64EC)\n      res = (void*)__readgsqword((unsigned long)ofs);   // direct load at offset from gs\n    #elif _M_IX86 && !defined(_M_ARM64EC)\n      res = (void*)__readfsdword((unsigned long)ofs);   // direct load at offset from fs\n    #else\n      res = ((void**)NtCurrentTeb())[slot]; MI_UNUSED(ofs);\n    #endif\n  #elif defined(__i386__)\n    __asm__(\"movl %%gs:%1, %0\" : \"=r\" (res) : \"m\" (*((void**)ofs)) : );  // x86 32-bit always uses GS\n  #elif defined(__APPLE__) && defined(__x86_64__)\n    __asm__(\"movq %%gs:%1, %0\" : \"=r\" (res) : \"m\" (*((void**)ofs)) : );  // x86_64 macOSX uses GS\n  #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4)\n    __asm__(\"movl %%fs:%1, %0\" : \"=r\" (res) : \"m\" (*((void**)ofs)) : );  // x32 ABI\n  #elif defined(__x86_64__)\n    __asm__(\"movq %%fs:%1, %0\" : \"=r\" (res) : \"m\" (*((void**)ofs)) : );  // x86_64 Linux, BSD uses FS\n  #elif defined(__arm__)\n    void** tcb; MI_UNUSED(ofs);\n    __asm__ volatile (\"mrc p15, 0, %0, c13, c0, 3\\nbic %0, %0, #3\" : \"=r\" (tcb));\n    res = tcb[slot];\n  #elif defined(__aarch64__)\n    void** tcb; MI_UNUSED(ofs);\n    #if defined(__APPLE__) // M1, issue #343\n    __asm__ volatile (\"mrs %0, tpidrro_el0\\nbic %0, %0, #7\" : \"=r\" (tcb));\n    #else\n    __asm__ volatile (\"mrs %0, tpidr_el0\" : \"=r\" (tcb));\n    #endif\n    res = tcb[slot];\n  #elif defined(__APPLE__) && defined(__POWERPC__) // ppc, issue #781\n    MI_UNUSED(ofs);\n    res = pthread_getspecific(slot);\n  #else\n    #define MI_HAS_TLS_SLOT 0\n    MI_UNUSED(ofs);\n    res = NULL;\n  #endif\n  return res;\n}\n\n#ifndef MI_HAS_TLS_SLOT\n#define MI_HAS_TLS_SLOT 1\n#endif\n\n// setting a tls slot is only used on macOS for now\nstatic inline void mi_prim_tls_slot_set(size_t slot, void* value) mi_attr_noexcept {\n  const size_t ofs = (slot*sizeof(void*));\n  #if defined(_WIN32)\n    ((void**)NtCurrentTeb())[slot] = value; MI_UNUSED(ofs);\n  #elif defined(__i386__)\n    __asm__(\"movl %1,%%gs:%0\" : \"=m\" (*((void**)ofs)) : \"rn\" (value) : );  // 32-bit always uses GS\n  #elif defined(__APPLE__) && defined(__x86_64__)\n    __asm__(\"movq %1,%%gs:%0\" : \"=m\" (*((void**)ofs)) : \"rn\" (value) : );  // x86_64 macOS uses GS\n  #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4)\n    __asm__(\"movl %1,%%fs:%0\" : \"=m\" (*((void**)ofs)) : \"rn\" (value) : );  // x32 ABI\n  #elif defined(__x86_64__)\n    __asm__(\"movq %1,%%fs:%0\" : \"=m\" (*((void**)ofs)) : \"rn\" (value) : );  // x86_64 Linux, BSD uses FS\n  #elif defined(__arm__)\n    void** tcb; MI_UNUSED(ofs);\n    __asm__ volatile (\"mrc p15, 0, %0, c13, c0, 3\\nbic %0, %0, #3\" : \"=r\" (tcb));\n    tcb[slot] = value;\n  #elif defined(__aarch64__)\n    void** tcb; MI_UNUSED(ofs);\n    #if defined(__APPLE__) // M1, issue #343\n    __asm__ volatile (\"mrs %0, tpidrro_el0\\nbic %0, %0, #7\" : \"=r\" (tcb));\n    #else\n    __asm__ volatile (\"mrs %0, tpidr_el0\" : \"=r\" (tcb));\n    #endif\n    tcb[slot] = value;\n  #elif defined(__APPLE__) && defined(__POWERPC__) // ppc, issue #781\n    MI_UNUSED(ofs);\n    pthread_setspecific(slot, value);\n  #else\n    MI_UNUSED(ofs); MI_UNUSED(value);\n  #endif\n}\n\n#endif\n\n\n// defined in `init.c`; do not use these directly\nextern mi_decl_hidden mi_decl_thread mi_theap_t* __mi_theap_main;     // theap belonging to the main heap\nextern mi_decl_hidden bool _mi_process_is_initialized;                // has mi_process_init been called?\n\n\n//-------------------------------------------------------------------\n// Get a fast unique thread id.\n//\n// Getting the thread id should be performant as it is called in the\n// fast path of `_mi_free` and we specialize for various platforms as\n// inlined definitions. Regular code should call `init.c:_mi_thread_id()`.\n// We only require _mi_prim_thread_id() to return a unique id\n// for each thread (unequal to zero).\n//-------------------------------------------------------------------\n\n\n// Do we have __builtin_thread_pointer? This would be the preferred way to get a unique thread id\n// but unfortunately, it seems we cannot test for this reliably at this time (see issue #883)\n// Nevertheless, it seems needed on older graviton platforms (see issue #851).\n// For now, we only enable this for specific platforms.\n#if !defined(MI_USE_BUILTIN_THREAD_POINTER)   /* allow user override */\n  #if !defined(__APPLE__)  /* on apple (M1) the wrong register is read (tpidr_el0 instead of tpidrro_el0) so fall back to TLS slot assembly (<https://github.com/microsoft/mimalloc/issues/343#issuecomment-763272369>)*/ \\\n      && !defined(__CYGWIN__) \\\n      && !defined(MI_LIBC_MUSL) \\\n      && (!defined(__clang_major__) || __clang_major__ >= 14)  /* older clang versions emit bad code; fall back to using the TLS slot (<https://lore.kernel.org/linux-arm-kernel/202110280952.352F66D8@keescook/T/>) */\n    #if    (defined(__GNUC__) && (__GNUC__ >= 7)  && defined(__aarch64__)) /* aarch64 for older gcc versions (issue #851) */ \\\n        || (defined(__GNUC__) && (__GNUC__ >= 11) && defined(__x86_64__)) \\\n        || (defined(__clang_major__) && (__clang_major__ >= 14) && (defined(__aarch64__) || defined(__x86_64__)))\n      #define MI_USE_BUILTIN_THREAD_POINTER  1\n    #endif\n  #endif\n#endif\n\nstatic inline mi_threadid_t __mi_prim_thread_id(void) mi_attr_noexcept;\n\nstatic inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {\n  const mi_threadid_t tid = __mi_prim_thread_id();\n  mi_assert_internal(tid > 1);\n  mi_assert_internal((tid & MI_PAGE_FLAG_MASK) == 0);  // bottom 2 bits are clear?\n  return tid;\n}\n\n// Get a unique id for the current thread.\n#if defined(MI_PRIM_THREAD_ID)\n\nstatic inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {\n  const mi_threadid_t tid = MI_PRIM_THREAD_ID();  // used for example by CPython for a free threaded build (see python/cpython#115488)\n  mi_assert_internal( (tid & 0x03) == 0 );        // mimalloc reserves the bottom 2 bits\n  return tid;\n}\n\n#elif defined(_WIN32)\n\nstatic inline mi_threadid_t __mi_prim_thread_id(void) mi_attr_noexcept {\n  // Windows: works on Intel and ARM in both 32- and 64-bit\n  return (uintptr_t)NtCurrentTeb();\n}\n\n#elif MI_USE_BUILTIN_THREAD_POINTER\n\nstatic inline mi_threadid_t __mi_prim_thread_id(void) mi_attr_noexcept {\n  // Works on most Unix based platforms with recent compilers\n  return (uintptr_t)__builtin_thread_pointer();\n}\n\n#elif MI_HAS_TLS_SLOT\n\nstatic inline mi_threadid_t __mi_prim_thread_id(void) mi_attr_noexcept {\n  #if defined(__BIONIC__)\n    // issue #384, #495: on the Bionic libc (Android), slot 1 is the thread id\n    // see: https://github.com/aosp-mirror/platform_bionic/blob/c44b1d0676ded732df4b3b21c5f798eacae93228/libc/platform/bionic/tls_defines.h#L86\n    return (uintptr_t)mi_prim_tls_slot(1);\n  #else\n    // in all our other targets, slot 0 is the thread id\n    // glibc: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=sysdeps/x86_64/nptl/tls.h\n    // apple: https://github.com/apple/darwin-xnu/blob/main/libsyscall/os/tsd.h#L36\n    return (uintptr_t)mi_prim_tls_slot(0);\n  #endif\n}\n\n#else\n\n// otherwise use portable C, taking the address of a thread local variable (this is still very fast on most platforms).\nstatic inline mi_threadid_t __mi_prim_thread_id(void) mi_attr_noexcept {\n  return (uintptr_t)&__mi_theap_main;\n}\n\n#endif\n\n\n\n/* ----------------------------------------------------------------------------------------\nGet the thread local default theap: `_mi_theap_default()` (and the cached heap `_mi_theap_cached`).\n\nThis is inlined here as it is on the fast path for allocation functions.\nWe have 4 models:\n\n- MI_TLS_MODEL_THREAD_LOCAL: use regular thread local (default on Linux, FreeBSD, etc)\n    On most platforms (Linux, FreeBSD, NetBSD, etc), this just returns a\n    thread local variable (`__mi_theap_default`). With the initial-exec TLS model this ensures\n    that the storage will always be available and properly initialized (with an empty theap).\n\n    On some platforms the underlying TLS implementation (or the loader) will call itself `malloc`\n    on a first access to a thread local and recurse in the MI_TLS_MODEL_THREAD_LOCAL.\n    A way around this is to define MI_TLS_RECURSE_GUARD which adds an extra check if the process\n    is initialized before accessing the thread-local. This is a check in the fast path though\n    so this should be avoided.\n\n- MI_TLS_MODEL_FIXED_SLOT: use a fixed slot in the TLS block (default on macOS)\n    This reserves an unused and fixed TLS slot. This is fast and avoids the problem\n    where the underlying TLS implementation (or the loader) will call itself `malloc`\n    on a first access to a thread local (and recurse in the MI_TLS_MODEL_THREAD_LOCAL).\n    This goes wrong though if the OS or a library uses the same fixed slot.\n\n- MI_TLS_MODEL_DYNAMIC_WIN32: use a dynamically allocated slot with TlsAlloc. (default on Windows)\n    Windows has somewhat slow thread locals so by default we use TlsAlloc'd slots which\n    can be more efficient. First tries to use one of the \"direct\" first 64 slots which \n    are the fastest, but falls back to using \"expansion\" slots when needed (up to 1088 slots).\n    (If the allocated slot happens to always be under 64 for a particular program,\n    one might use cmake with `-DMI_WIN_DIRECT_TLS=ON` to skip the expansion slot test in the fast path.)\n\n- MI_TLS_MODEL_DYNAMIC_PTHREADS: use `pthread_getspecific`. (default on OpenBSD, maybe good for Android as well?)\n    Use pthread local storage. Somewhat slow but can work well depending on the platform.\n\nEach model should define `MI_THEAP_INITASNULL` to signify that the initial value\nreturned from `_mi_theap_default()` can be `NULL` (instead of the address of the empty heap).\nThis incurs an extra check in the fast path (but can often be combined in an existing check).\n------------------------------------------------------------------------------------------- */\n\nstatic inline mi_theap_t* _mi_theap_default(void);\nstatic inline mi_theap_t* _mi_theap_cached(void);\n\n#if defined(_WIN32)\n  #define MI_TLS_MODEL_DYNAMIC_WIN32        1    \n#elif defined(__APPLE__) && MI_HAS_TLS_SLOT && !defined(__POWERPC__)  // macOS on arm64 or x64\n  // #define MI_TLS_MODEL_DYNAMIC_PTHREADS  1    // also works but a bit slower\n  #define MI_TLS_MODEL_FIXED_SLOT           1\n  #define MI_TLS_MODEL_FIXED_SLOT_DEFAULT   108  // seems unused. @apple: it would be great to get 2 official slots for custom allocators :-)\n  #define MI_TLS_MODEL_FIXED_SLOT_CACHED    109\n  // we used before __PTK_FRAMEWORK_OLDGC_KEY9 (89) but that seems used now.\n  // see <https://github.com/rweichler/substrate/blob/master/include/pthread_machdep.h>\n#elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__ANDROID__)\n  #define MI_TLS_MODEL_DYNAMIC_PTHREADS     1\n  // #define MI_TLS_MODEL_DYNAMIC_PTHREADS_DEFAULT_ENTRY_IS_NULL  1\n#else\n  #define MI_TLS_MODEL_THREAD_LOCAL         1\n#endif\n\n// Declared this way to optimize register spills and branches\nmi_decl_cold mi_decl_noinline mi_theap_t* _mi_theap_empty_get(void);\n\nstatic inline mi_theap_t* __mi_theap_empty(void) {\n  #if __GNUC__\n  __asm(\"\");  // prevent conditional load\n  return (mi_theap_t*)&_mi_theap_empty;\n  #else\n  return _mi_theap_empty_get();\n  #endif\n}\n\n#if MI_TLS_MODEL_THREAD_LOCAL\n// Thread local with an initial value (default on Linux). Very efficient.\n\nextern mi_decl_hidden mi_decl_thread mi_theap_t* __mi_theap_default;  // default theap to allocate from\nextern mi_decl_hidden mi_decl_thread mi_theap_t* __mi_theap_cached;   // theap from the last used heap\n\nstatic inline mi_theap_t* _mi_theap_default(void) {\n  #if defined(MI_TLS_RECURSE_GUARD)\n  if (mi_unlikely(!_mi_process_is_initialized)) return _mi_theap_empty_get();\n  #endif\n  return __mi_theap_default;\n}\n\nstatic inline mi_theap_t* _mi_theap_cached(void) {\n  return __mi_theap_cached;\n}\n\n#elif MI_TLS_MODEL_FIXED_SLOT\n// Fixed TLS slot (default on macOS).\n#define MI_THEAP_INITASNULL  1\n\nstatic inline mi_theap_t* _mi_theap_default(void) {\n  return (mi_theap_t*)mi_prim_tls_slot(MI_TLS_MODEL_FIXED_SLOT_DEFAULT);\n}\n\nstatic inline mi_theap_t* _mi_theap_cached(void) {\n  return (mi_theap_t*)mi_prim_tls_slot(MI_TLS_MODEL_FIXED_SLOT_CACHED);\n}\n\n#elif MI_TLS_MODEL_DYNAMIC_WIN32\n// Dynamic TLS slot (default on Windows)\n#define MI_THEAP_INITASNULL  1\n\n// We try to use direct slots (64), but can also use the expansion slots (upto 1024 extra available)\n// See <https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/teb/index.htm> for the offsets.\n#if MI_SIZE_SIZE==4\n#define MI_TLS_EXPANSION_SLOT    (0x0F94 / MI_SIZE_SIZE)\n#else\n#define MI_TLS_EXPANSION_SLOT    (0x1780 / MI_SIZE_SIZE)\n#endif\n\nextern mi_decl_hidden size_t _mi_theap_default_slot;\nextern mi_decl_hidden size_t _mi_theap_cached_slot;\nextern mi_decl_hidden size_t _mi_theap_default_expansion_slot;\nextern mi_decl_hidden size_t _mi_theap_cached_expansion_slot;\n\nstatic inline mi_theap_t* _mi_theap_default(void) {\n  const size_t slot = _mi_theap_default_slot;\n  mi_theap_t* theap  = (mi_theap_t*)mi_prim_tls_slot(slot);\n  #if !MI_WIN_DIRECT_TLS\n  if mi_unlikely(slot==MI_TLS_EXPANSION_SLOT) { // in TlsExpansionSlots ?\n    if mi_likely(theap!=NULL) {                 // initialized (on this thread)?\n      theap = ((mi_theap_t**)theap)[_mi_theap_default_expansion_slot];\n    }\n  }\n  #endif\n  return theap;\n}\n\nstatic inline mi_theap_t* _mi_theap_cached(void) {\n  const size_t slot = _mi_theap_cached_slot;\n  mi_theap_t* theap = (mi_theap_t*)mi_prim_tls_slot(slot);\n  #if !MI_WIN_DIRECT_TLS\n  if mi_unlikely(slot==MI_TLS_EXPANSION_SLOT) { // in TlsExpansionSlots ?\n    if mi_likely(theap!=NULL) {                 // initialized (on this thread)?\n      theap = ((mi_theap_t**)theap)[_mi_theap_cached_expansion_slot];\n    }\n  }\n  #endif\n  return theap;\n}\n\n#elif MI_TLS_MODEL_DYNAMIC_PTHREADS\n// Dynamic pthread slot on less common platforms. This is not too bad. (default on OpenBSD)\n#define MI_THEAP_INITASNULL  1\n\nextern mi_decl_hidden pthread_key_t _mi_theap_default_key;\nextern mi_decl_hidden pthread_key_t _mi_theap_cached_key;\n\nstatic inline mi_theap_t* _mi_theap_default(void) {\n  #if !MI_TLS_MODEL_DYNAMIC_PTHREADS_DEFAULT_ENTRY_IS_NULL\n  // we can skip this check if using the initial key will return NULL from pthread_getspecific\n  if mi_unlikely(_mi_theap_default_key==0) { return NULL; }\n  #endif\n  return (mi_theap_t*)pthread_getspecific(_mi_theap_default_key);\n}\n\nstatic inline mi_theap_t* _mi_theap_cached(void) {\n  #if !MI_TLS_MODEL_DYNAMIC_PTHREADS_DEFAULT_ENTRY_IS_NULL\n  // we can skip this check if using the initial key will return NULL from pthread_getspecific\n  if mi_unlikely(_mi_theap_cached_key==0) { return NULL; }\n  #endif\n  return (mi_theap_t*)pthread_getspecific(_mi_theap_cached_key);\n}\n\n#else\n#error \"no TLS model is defined for this platform?\"\n#endif\n\n\n// Check if a thread is initialized (without using a thread-local if using fixed slots)\nstatic inline bool _mi_thread_is_initialized(void) {\n  return (mi_theap_is_initialized(_mi_theap_default()));\n}\n\n// Get (and possible create) the theap belonging to a heap\n// We cache the last accessed theap in `_mi_theap_cached` for better performance.\nstatic inline mi_theap_t* _mi_heap_theap(const mi_heap_t* heap) {\n  mi_theap_t* theap = _mi_theap_cached();  \n  #if MI_THEAP_INITASNULL\n  if mi_likely(theap!=NULL && _mi_theap_heap(theap)==heap) return theap;\n  #else\n  if mi_likely(_mi_theap_heap(theap)==heap) return theap;\n  #endif\n  return _mi_heap_theap_get_or_init(heap);\n}\n\n// Get the theap belonging to a heap without creating in if it is not yet initialized.\nstatic inline mi_theap_t* _mi_heap_theap_peek(const mi_heap_t* heap) {\n  mi_theap_t* theap = _mi_theap_cached();\n  #if MI_THEAP_INITASNULL\n  if mi_unlikely(theap==NULL || _mi_theap_heap(theap)!=heap)\n  #else\n  if mi_unlikely(_mi_theap_heap(theap)!=heap)\n  #endif\n  {\n    theap = _mi_heap_theap_get_peek(heap);  // don't update the cache on a query (?)\n  }\n  mi_assert(theap==NULL || _mi_theap_heap(theap)==heap);\n  return theap;\n}\n\n// Find the associated theap or NULL if it does not exist (during shutdown)\n// Should be fast as it is called in `free.c:mi_free_try_collect`.\nstatic inline mi_theap_t* _mi_page_associated_theap_peek(mi_page_t* page) {\n  mi_heap_t* const heap = page->heap;\n  mi_theap_t* theap;\n  if mi_likely(heap==NULL) { theap = __mi_theap_main; }  // note: on macOS accessing the thread_local can cause allocation during thread shutdown (and reinitialize the thread)!\n                      else { theap = _mi_heap_theap_peek(heap); }\n  mi_assert_internal(theap==NULL || _mi_thread_id()==theap->tld->thread_id);\n  return theap;\n}\n\n#endif  // MI_PRIM_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/include/mimalloc/track.h",
      "sha256": "1f378b4b6063c078d2aeb5d916c1d30b5db787a44ab9118e7daf673b086882c6",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MI_TRACK_H\n#define MI_TRACK_H\n\n/* ------------------------------------------------------------------------------------------------------\nTrack memory ranges with macros for tools like Valgrind address sanitizer, or other memory checkers.\nThese can be defined for tracking allocation:\n\n  #define mi_track_malloc_size(p,reqsize,size,zero)\n  #define mi_track_free_size(p,_size)\n\nThe macros are set up such that the size passed to `mi_track_free_size`\nalways matches the size of `mi_track_malloc_size`. (currently, `size == mi_usable_size(p)`).\nThe `reqsize` is what the user requested, and `size >= reqsize`.\nThe `size` is either byte precise (and `size==reqsize`) if `MI_PADDING` is enabled,\nor otherwise it is the usable block size which may be larger than the original request.\nUse `_mi_block_size_of(void* p)` to get the full block size that was allocated (including padding etc).\nThe `zero` parameter is `true` if the allocated block is zero initialized.\n\nOptional:\n\n  #define mi_track_align(p,alignedp,offset,size)\n  #define mi_track_resize(p,oldsize,newsize)\n  #define mi_track_init()\n\nThe `mi_track_align` is called right after a `mi_track_malloc` for aligned pointers in a block.\nThe corresponding `mi_track_free` still uses the block start pointer and original size (corresponding to the `mi_track_malloc`).\nThe `mi_track_resize` is currently unused but could be called on reallocations within a block.\n`mi_track_init` is called at program start.\n\nThe following macros are for tools like asan and valgrind to track whether memory is\ndefined, undefined, or not accessible at all:\n\n  #define mi_track_mem_defined(p,size)\n  #define mi_track_mem_undefined(p,size)\n  #define mi_track_mem_noaccess(p,size)\n\n-------------------------------------------------------------------------------------------------------*/\n\n#if MI_TRACK_VALGRIND\n// valgrind tool\n\n#define MI_TRACK_ENABLED      1\n#define MI_TRACK_HEAP_DESTROY 1           // track free of individual blocks on theap_destroy\n#define MI_TRACK_TOOL         \"valgrind\"\n\n#include <valgrind/valgrind.h>\n#include <valgrind/memcheck.h>\n\n#define mi_track_malloc_size(p,reqsize,size,zero) VALGRIND_MALLOCLIKE_BLOCK(p,size,MI_PADDING_SIZE /*red zone*/,zero)\n#define mi_track_free_size(p,_size)               VALGRIND_FREELIKE_BLOCK(p,MI_PADDING_SIZE /*red zone*/)\n#define mi_track_resize(p,oldsize,newsize)        VALGRIND_RESIZEINPLACE_BLOCK(p,oldsize,newsize,MI_PADDING_SIZE /*red zone*/)\n#define mi_track_mem_defined(p,size)              VALGRIND_MAKE_MEM_DEFINED(p,size)\n#define mi_track_mem_undefined(p,size)            VALGRIND_MAKE_MEM_UNDEFINED(p,size)\n#define mi_track_mem_noaccess(p,size)             VALGRIND_MAKE_MEM_NOACCESS(p,size)\n\n#elif MI_TRACK_ASAN\n// address sanitizer\n\n#define MI_TRACK_ENABLED      1\n#define MI_TRACK_HEAP_DESTROY 0\n#define MI_TRACK_TOOL         \"asan\"\n\n#include <sanitizer/asan_interface.h>\n\n#define mi_track_malloc_size(p,reqsize,size,zero) ASAN_UNPOISON_MEMORY_REGION(p,size)\n#define mi_track_free_size(p,size)                ASAN_POISON_MEMORY_REGION(p,size)\n#define mi_track_mem_defined(p,size)              ASAN_UNPOISON_MEMORY_REGION(p,size)\n#define mi_track_mem_undefined(p,size)            ASAN_UNPOISON_MEMORY_REGION(p,size)\n#define mi_track_mem_noaccess(p,size)             ASAN_POISON_MEMORY_REGION(p,size)\n\n#elif MI_TRACK_ETW\n// windows event tracing\n\n#define MI_TRACK_ENABLED      1\n#define MI_TRACK_HEAP_DESTROY 1\n#define MI_TRACK_TOOL         \"ETW\"\n\n#include \"../src/prim/windows/etw.h\"\n\n#define mi_track_init()                           EventRegistermicrosoft_windows_mimalloc()\n#define mi_track_done()                           EventUnregistermicrosoft_windows_mimalloc()\n#define mi_track_malloc_size(p,reqsize,size,zero) EventWriteETW_MI_ALLOC((UINT64)(p), size)\n#define mi_track_free_size(p,size)                EventWriteETW_MI_FREE((UINT64)(p), size)\n\n#else\n// no tracking\n\n#define MI_TRACK_ENABLED      0\n#define MI_TRACK_HEAP_DESTROY 0\n#define MI_TRACK_TOOL         \"none\"\n\n#define mi_track_malloc_size(p,reqsize,size,zero)\n#define mi_track_free_size(p,_size)\n\n#endif\n\n// -------------------\n// Utility definitions\n\n#ifndef mi_track_resize\n#define mi_track_resize(p,oldsize,newsize)      do{ mi_track_free_size(p,oldsize); mi_track_malloc(p,newsize,false); } while(0)\n#endif\n\n#ifndef mi_track_align\n#define mi_track_align(p,alignedp,offset,size)  mi_track_mem_noaccess(p,offset)\n#endif\n\n#ifndef mi_track_init\n#define mi_track_init()\n#endif\n\n#ifndef mi_track_done\n#define mi_track_done()\n#endif\n\n#ifndef mi_track_mem_defined\n#define mi_track_mem_defined(p,size)\n#endif\n\n#ifndef mi_track_mem_undefined\n#define mi_track_mem_undefined(p,size)\n#endif\n\n#ifndef mi_track_mem_noaccess\n#define mi_track_mem_noaccess(p,size)\n#endif\n\n\n#if MI_PADDING\n#define mi_track_malloc(p,reqsize,zero) \\\n  if ((p)!=NULL) { \\\n    mi_assert_internal(mi_usable_size(p)==(reqsize)); \\\n    mi_track_malloc_size(p,reqsize,reqsize,zero); \\\n  }\n#else\n#define mi_track_malloc(p,reqsize,zero) \\\n  if ((p)!=NULL) { \\\n    mi_assert_internal(mi_usable_size(p)>=(reqsize)); \\\n    mi_track_malloc_size(p,reqsize,mi_usable_size(p),zero); \\\n  }\n#endif\n\n#endif // MI_TRACK_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/include/mimalloc/types.h",
      "sha256": "b54e760da2a8d9d8a9cb708e280268c2d194c99bc518b21f72db70100578ad6a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#pragma once\n#ifndef MI_TYPES_H\n#define MI_TYPES_H\n\n// --------------------------------------------------------------------------\n// This file contains the main type definitions for mimalloc:\n// mi_heap_t      : all data for a heap; usually there is just one main default heap.\n// mi_theap_t     : a thread local heap belonging to a specific heap:\n//                  maintains lists of thread-local heap pages that have free space.\n// mi_page_t      : a mimalloc page (usually 64KiB or 512KiB) from\n//                  where objects of a single size are allocated.\n//                  Note: we write \"OS page\" for OS memory pages while\n//                  using plain \"page\" for mimalloc pages (`mi_page_t`).\n// mi_arena_t     : a large memory area where pages are allocated (process shared)\n// mi_tld_t       : thread local data\n// mi_subproc_t   : all heaps belong to a sub-process (usually just the main one)\n// --------------------------------------------------------------------------\n\n\n#include <mimalloc-stats.h>\n#include <stddef.h>   // ptrdiff_t\n#include <stdint.h>   // uintptr_t, uint16_t, etc\n#include <stdbool.h>  // bool\n#include <limits.h>   // SIZE_MAX etc.\n#include <errno.h>    // error codes\n#include \"bits.h\"     // size defines (MI_INTPTR_SIZE etc), bit operations\n#include \"atomic.h\"   // _Atomic primitives\n\n// Minimal alignment necessary. On most platforms 16 bytes are needed\n// due to SSE registers for example. This must be at least `sizeof(void*)`\n#ifndef MI_MAX_ALIGN_SIZE\n#define MI_MAX_ALIGN_SIZE  16   // sizeof(max_align_t)\n#endif\n\n\n// ------------------------------------------------------\n// Variants\n// ------------------------------------------------------\n\n// Define NDEBUG in the release version to disable assertions.\n// #define NDEBUG\n\n// Define MI_TRACK_<tool> to enable tracking support\n// #define MI_TRACK_VALGRIND 1\n// #define MI_TRACK_ASAN     1\n// #define MI_TRACK_ETW      1\n\n// Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance).\n// #define MI_STAT 1\n\n// Define MI_SECURE to enable security mitigations\n// #define MI_SECURE 1  // guard pages around meta data, randomize arena allocation addresses (like ASLR), abort on detected meta data corruption\n// #define MI_SECURE 2  // randomize relative allocation addresses (within mimalloc pages)\n// #define MI_SECURE 3  // encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free)\n// #define MI_SECURE 4  // checks for double free (may be more expensive) (`-DMI_SECURE=ON`)\n// #define MI_SECURE 5  // guard page at the end of each mimalloc page (expensive!) (`-DMI_SECURE_FULL=ON`)\n\n#if !defined(MI_SECURE)\n#define MI_SECURE 0\n#endif\n\n// Define MI_DEBUG for assertion and invariant checking\n// #define MI_DEBUG 1  // basic assertion checks and statistics, check double free, corrupted free list, and invalid pointer free. (cmake -DMI_DEBUG=ON)\n// #define MI_DEBUG 2  // + internal assertion checks (cmake -DMI_DEBUG_INTERNAL=ON)\n// #define MI_DEBUG 3  // + extensive internal invariant checking (cmake -DMI_DEBUG_FULL=ON)\n#if !defined(MI_DEBUG)\n#if defined(MI_BUILD_RELEASE) || defined(NDEBUG)\n#define MI_DEBUG 0\n#else\n#define MI_DEBUG 2\n#endif\n#endif\n\n// Statistics (0=only essential, 1=normal, 2=more fine-grained (expensive) tracking)\n#ifndef MI_STAT\n#if (MI_DEBUG>0)\n#define MI_STAT 2\n#else\n#define MI_STAT 0\n#endif\n#endif\n\n// Enable guard pages behind objects of a certain size (set by the MIMALLOC_GUARDED_MIN/MAX/SAMPLE_RATE options)\n#if !defined(MI_GUARDED) && MI_DEBUG && !defined(NDEBUG) && !MI_PAGE_META_ALIGNED_FREE_SMALL \n#define MI_GUARDED  1\n#endif\n\n// Reserve extra padding at the end of each block to be more resilient against theap block overflows.\n// The padding can detect buffer overflow on free.\n#if !defined(MI_PADDING) && (MI_SECURE>=3 || MI_DEBUG>=1 || (MI_TRACK_VALGRIND || MI_TRACK_ASAN || MI_TRACK_ETW))\n#define MI_PADDING  1\n#endif\n\n// Check padding bytes; allows byte-precise buffer overflow detection\n#if !defined(MI_PADDING_CHECK) && MI_PADDING && (MI_SECURE>=3 || MI_DEBUG>=1)\n#define MI_PADDING_CHECK 1\n#endif\n\n\n// Encoded free lists allow detection of corrupted free lists\n// and can detect buffer overflows, modify after free, and double `free`s.\n#if (MI_SECURE>=3 || MI_DEBUG>=1)\n#define MI_ENCODE_FREELIST  1\n#endif\n\n// Enable large pages for objects between 64KiB and 512KiB.\n// This should perhaps be disabled by default as for many workloads the block sizes above 64 KiB\n// are quite random which can lead to too many partially used large pages (but see issue #1104).\n#ifndef MI_ENABLE_LARGE_PAGES\n#define MI_ENABLE_LARGE_PAGES  1\n#endif\n\n// Place page meta info at the start of the page area or keep it separate? \n// Separate keeps the page info at the arena start (default) which is more secure \n// and reduces wasted space due to alignment and block sizes. \n// (but also reserves more memory up front (about 2MiB per GiB))\n#if !defined(MI_PAGE_META_IS_SEPARATED)\n#if MI_PAGE_MAP_FLAT\n#define MI_PAGE_META_IS_SEPARATED    0\n#else\n#define MI_PAGE_META_IS_SEPARATED    1\n#endif\n#endif\n\n// We can choose to only put page info of small pages at the start of the page area.\n// This can be used to have a slightly faster `mi_free_small` function for specialized\n// cases (like language runtime systems).\n#if !defined(MI_PAGE_META_ALIGNED_FREE_SMALL)\n#define MI_PAGE_META_ALIGNED_FREE_SMALL   0\n#endif\n\n// Configuration checks\n#if !MI_PAGE_META_IS_SEPARATED && MI_SECURE\n#error \"secure mode should use separated page infos\"\n#endif\n#if MI_PAGE_META_ALIGNED_FREE_SMALL && MI_SECURE\n#error \"secure mode cannot use MI_PAGE_META_ALIGNED_FREE_SMALL\"\n#endif\n#if MI_PAGE_META_IS_SEPARATED && MI_PAGE_MAP_FLAT\n#error \"cannot have a flat page map with separated page infos\"\n#endif\n#if MI_DEBUG && NDEBUG\n#warning \"mimalloc assertions enabled in a release build\"\n#endif\n\n\n// --------------------------------------------------------------\n// Sizes of internal data-structures\n// (comments specify sizes on 64-bit, usually 32-bit is halved)\n// --------------------------------------------------------------\n\n// Main size parameter; determines max arena sizes and max arena object sizes etc.\n#ifndef MI_ARENA_SLICE_SHIFT\n  #ifdef  MI_SMALL_PAGE_SHIFT   // backward compatibility\n  #define MI_ARENA_SLICE_SHIFT              MI_SMALL_PAGE_SHIFT\n  #elif MI_SECURE>=5 && __APPLE__ && MI_ARCH_ARM64\n  #define MI_ARENA_SLICE_SHIFT              (17)                        // 128 KiB to not waste too much due to 16 KiB guard pages\n  #else\n  #define MI_ARENA_SLICE_SHIFT              (13 + MI_SIZE_SHIFT)        // 64 KiB (32 KiB on 32-bit)\n  #endif\n#endif\n#if MI_ARENA_SLICE_SHIFT < 12\n#error Arena slices should be at least 4KiB\n#endif\n\n#ifndef MI_BCHUNK_BITS_SHIFT\n  #if MI_ARENA_SLICE_SHIFT <= 13    // <= 8KiB\n  #define MI_BCHUNK_BITS_SHIFT              (7)   // 128 bits\n  #elif MI_ARENA_SLICE_SHIFT < 16   // <= 32KiB\n  #define MI_BCHUNK_BITS_SHIFT              (8)   // 256 bits\n  #else\n  #define MI_BCHUNK_BITS_SHIFT              (6 + MI_SIZE_SHIFT)       // 512 bits (or 256 on 32-bit)\n  #endif\n#endif\n\n#define MI_BCHUNK_BITS                    (1 << MI_BCHUNK_BITS_SHIFT)         // sub-bitmaps in arena's are \"bchunks\" of 512 bits\n#define MI_ARENA_SLICE_SIZE               (MI_ZU(1) << MI_ARENA_SLICE_SHIFT)  // arena's allocate in slices of 64 KiB\n#define MI_ARENA_SLICE_ALIGN              (MI_ARENA_SLICE_SIZE)\n\n#define MI_ARENA_MIN_OBJ_SLICES           (1)\n#define MI_ARENA_MAX_CHUNK_OBJ_SLICES     (MI_BCHUNK_BITS)                    // 32 MiB (or 8 MiB on 32-bit)\n\n#define MI_ARENA_MIN_OBJ_SIZE             (MI_ARENA_MIN_OBJ_SLICES * MI_ARENA_SLICE_SIZE)\n#define MI_ARENA_MAX_CHUNK_OBJ_SIZE       (MI_ARENA_MAX_CHUNK_OBJ_SLICES * MI_ARENA_SLICE_SIZE)\n\n#if MI_ARENA_MAX_CHUNK_OBJ_SIZE < MI_SIZE_SIZE*1024\n#error maximum object size may be too small to hold local thread data\n#endif\n\n#define MI_SMALL_PAGE_SIZE                MI_ARENA_MIN_OBJ_SIZE                    // 64 KiB\n#define MI_MEDIUM_PAGE_SIZE               (8*MI_SMALL_PAGE_SIZE)                   // 512 KiB  (=byte in the bchunk bitmap)\n#define MI_LARGE_PAGE_SIZE                (MI_SIZE_SIZE*MI_MEDIUM_PAGE_SIZE)       // 4 MiB    (=word in the bchunk bitmap)\n\n\n// Maximum number of size classes. (spaced exponentially in 12.5% increments)\n#if MI_BIN_HUGE != 73U\n#error \"mimalloc internal: expecting 73 bins\"\n#endif\n#define MI_BIN_FULL  (MI_BIN_HUGE+1)\n#define MI_BIN_COUNT (MI_BIN_FULL+1)\n\n// We never allocate more than PTRDIFF_MAX (see also <https://sourceware.org/ml/libc-announce/2019/msg00001.html>)\n#define MI_MAX_ALLOC_SIZE        PTRDIFF_MAX\n\n// Minimal commit for a page on-demand commit (should be >= OS page size)\n#define MI_PAGE_MIN_COMMIT_SIZE  MI_ARENA_SLICE_SIZE\n\n\n// ------------------------------------------------------\n// Arena's are large reserved areas of memory allocated from\n// the OS that are managed by mimalloc to efficiently\n// allocate MI_ARENA_SLICE_SIZE slices of memory for the\n// mimalloc pages.\n// ------------------------------------------------------\n\n// A large memory arena where pages are allocated in.\ntypedef struct mi_arena_s mi_arena_t;     // defined below\n\n\n// ------------------------------------------------------\n// Heaps contain allocated blocks. Heaps are self-contained\n// but share the (sub-process) memory in the arena's.\n// ------------------------------------------------------\n\n// A first-class heap.\ntypedef struct mi_heap_s mi_heap_t;       // heaps\n\n// ------------------------------------------------------\n// We can have sub-processes that are fully separated\n// from each other (for running multiple Python interpreters\n// for example). A sub-process holds the memory arenas and heaps.\n// ------------------------------------------------------\n\n// A sub-process\ntypedef struct mi_subproc_s mi_subproc_t;\n\n\n// ---------------------------------------------------------------\n// a memory id tracks the provenance of arena/OS allocated memory\n// ---------------------------------------------------------------\n\n// Memory can reside in arena's, direct OS allocated, meta-data pages, or statically allocated.\n// The memid keeps track of this.\ntypedef enum mi_memkind_e {\n  MI_MEM_NONE,      // not allocated\n  MI_MEM_EXTERNAL,  // not owned by mimalloc but provided externally (via `mi_manage_os_memory` for example)\n  MI_MEM_STATIC,    // allocated in a static area and should not be freed (the initial main theap data for example (`init.c`))\n  MI_MEM_META,      // allocated with the meta data allocator (`arena-meta.c`)\n  MI_MEM_OS,        // allocated from the OS\n  MI_MEM_OS_HUGE,   // allocated as huge OS pages (usually 1GiB, pinned to physical memory)\n  MI_MEM_OS_REMAP,  // allocated in a remapable area (i.e. using `mremap`)\n  MI_MEM_ARENA,     // allocated from an arena (the usual case) (`arena.c`)\n  MI_MEM_HEAP_MAIN  // allocated in the main heap (for theaps)\n} mi_memkind_t;\n\nstatic inline bool mi_memkind_is_os(mi_memkind_t memkind) {\n  return (memkind >= MI_MEM_OS && memkind <= MI_MEM_OS_REMAP);\n}\n\nstatic inline bool mi_memkind_needs_no_free(mi_memkind_t memkind) {\n  return (memkind <= MI_MEM_STATIC);\n}\n\n\ntypedef struct mi_memid_os_info {\n  void*         base;               // actual base address of the block (used for offset aligned allocations)\n  size_t        size;               // allocated full size\n  // size_t        alignment;       // alignment at allocation\n} mi_memid_os_info_t;\n\ntypedef struct mi_memid_arena_info {\n  mi_arena_t*   arena;              // arena that contains this memory\n  uint32_t      slice_index;        // slice index in the arena\n  uint32_t      slice_count;        // allocated slices\n} mi_memid_arena_info_t;\n\ntypedef struct mi_memid_meta_info {\n  void*         meta_page;          // meta-page that contains the block\n  uint32_t      block_index;        // block index in the meta-data page\n  uint32_t      block_count;        // allocated blocks\n} mi_memid_meta_info_t;\n\ntypedef struct mi_memid_s {\n  union {\n    mi_memid_os_info_t    os;       // only used for MI_MEM_OS\n    mi_memid_arena_info_t arena;    // only used for MI_MEM_ARENA\n    mi_memid_meta_info_t  meta;     // only used for MI_MEM_META\n  } mem;\n  mi_memkind_t  memkind;\n  bool          is_pinned;          // `true` if we cannot decommit/reset/protect in this memory (e.g. when allocated using large (2Mib) or huge (1GiB) OS pages)\n  bool          initially_committed;// `true` if the memory was originally allocated as committed\n  bool          initially_zero;     // `true` if the memory was originally zero initialized\n} mi_memid_t;\n\n\nstatic inline bool mi_memid_is_os(mi_memid_t memid) {\n  return mi_memkind_is_os(memid.memkind);\n}\n\nstatic inline bool mi_memid_needs_no_free(mi_memid_t memid) {\n  return mi_memkind_needs_no_free(memid.memkind);\n}\n\nstatic inline mi_arena_t* mi_memid_arena(mi_memid_t memid) {\n  return (memid.memkind == MI_MEM_ARENA ? memid.mem.arena.arena : NULL);\n}\n\n\n// ------------------------------------------------------\n// Mimalloc pages contain allocated blocks\n// ------------------------------------------------------\n\n// The free lists use encoded next fields\n// (Only actually encodes when MI_ENCODED_FREELIST is defined.)\ntypedef uintptr_t  mi_encoded_t;\n\n// thread id's\ntypedef size_t     mi_threadid_t;\n\n// free lists contain blocks\ntypedef struct mi_block_s {\n  mi_encoded_t next;\n} mi_block_t;\n\n\n// The page flags are put in the bottom 2 bits of the thread_id (for a fast test in `mi_free`)\n// If `has_interior_pointers` is true if the page has pointers at an offset in a block (so we have to unalign to the block start before free-ing)\n// `in_full_queue` is true if the page is full and resides in the full queue (so we move it to a regular queue on free-ing)\n#define MI_PAGE_IN_FULL_QUEUE           MI_ZU(0x01)\n#define MI_PAGE_HAS_INTERIOR_POINTERS   MI_ZU(0x02)\n#define MI_PAGE_FLAG_MASK               MI_ZU(0x03)\ntypedef size_t mi_page_flags_t;\n\n// There are two special threadid's: 0 for pages that are abandoned (and not in a theap queue),\n// and 4 for abandoned & mapped threads -- abandoned-mapped pages are abandoned but also mapped\n// in an arena (in `mi_heap_t.arena_pages.pages_abandoned`) so these can be quickly found for reuse.\n// Abandoning partially used pages allows for sharing of this memory between threads (in particular if threads are blocked)\n#define MI_THREADID_ABANDONED           MI_ZU(0)\n#define MI_THREADID_ABANDONED_MAPPED    (MI_PAGE_FLAG_MASK + 1)\n\n// Thread free list.\n// Points to a list of blocks that are freed by other threads.\n// The least-bit is set if the page is owned by the current thread. (`mi_page_is_owned`).\n// Ownership is required before we can read any non-atomic fields in the page.\n// This way we can push a block on the thread free list and try to claim ownership atomically in `free.c:mi_free_block_mt`.\ntypedef uintptr_t mi_thread_free_t;\n\n// A page contains blocks of one specific size (`block_size`).\n// Each page has three list of free blocks:\n// `free` for blocks that can be allocated,\n// `local_free` for freed blocks that are not yet available to `mi_malloc`\n// `thread_free` for freed blocks by other threads\n// The `local_free` and `thread_free` lists are migrated to the `free` list\n// when it is exhausted. The separate `local_free` list is necessary to\n// implement a monotonic heartbeat. The `thread_free` list is needed for\n// avoiding atomic operations when allocating from the owning thread.\n//\n// `used - |thread_free|` == actual blocks that are in use (alive)\n// `used - |thread_free| + |free| + |local_free| == capacity`\n//\n// We don't count \"freed\" (as |free|) but use only the `used` field to reduce\n// the number of memory accesses in the `mi_page_all_free` function(s).\n// Use `_mi_page_free_collect` to collect the thread_free list and update the `used` count.\n//\n// Notes:\n// - Non-atomic fields can only be accessed if having _ownership_ (low bit of `xthread_free` is 1).\n//   Combining the `thread_free` list with an ownership bit allows a concurrent `free` to atomically\n//   free an object and (re)claim ownership if the page was abandoned.\n// - If a page is not part of a theap it is called \"abandoned\"  (`theap==NULL`) -- in\n//   that case the `xthreadid` is 0 or 4 (4 is for abandoned pages that\n//   are in the `pages_abandoned` lists of an arena, these are called \"mapped\" abandoned pages).\n// - page flags are in the bottom 3 bits of `xthread_id` for the fast path in `mi_free`.\n// - The layout is optimized for `free.c:mi_free` and `alloc.c:mi_page_alloc`\n// - Using `uint16_t` does not seem to slow things down\n\ntypedef struct mi_page_s {\n  _Atomic(mi_threadid_t)    xthread_id;        // thread this page belongs to. (= `theap->thread_id (or 0 or 4 if abandoned) | page_flags`)\n\n  mi_block_t*               free;              // list of available free blocks (`malloc` allocates from this list)\n  uint16_t                  used;              // number of blocks in use (including blocks in `thread_free`)\n  uint16_t                  capacity;          // number of blocks committed\n  uint16_t                  reserved;          // number of blocks reserved in memory\n  uint8_t                   retire_expire;     // expiration count for retired blocks\n  bool                      free_is_zero;      // `true` if the blocks in the free list are zero initialized\n\n  mi_block_t*               local_free;        // list of deferred free blocks by this thread (migrates to `free`)\n  _Atomic(mi_thread_free_t) xthread_free;      // list of deferred free blocks freed by other threads (= `mi_block_t* | (1 if owned)`)\n\n  size_t                    block_size;        // const: size available in each block (always `>0`)\n  uint8_t*                  page_start;        // const: start of the blocks\n\n  #if (MI_ENCODE_FREELIST || MI_PADDING)\n  uintptr_t                 keys[2];           // const: two random keys to encode the free lists (see `_mi_block_next`) or padding canary\n  #endif\n\n  mi_theap_t*               theap;             // the theap owning this page (may not be valid or NULL for abandoned pages)\n  mi_heap_t*                heap;              // const: the heap owning this page\n\n  struct mi_page_s*         next;              // next page owned by the theap with the same `block_size`\n  struct mi_page_s*         prev;              // previous page owned by the theap with the same `block_size`\n  size_t                    slice_committed;   // committed size relative to the first arena slice of the page data (or 0 if the page is fully committed already)\n  mi_memid_t                memid;             // const: provenance of the page memory\n} mi_page_t;\n\n\n// ------------------------------------------------------\n// Object sizes\n// ------------------------------------------------------\n\n#define MI_PAGE_ALIGN                     MI_ARENA_SLICE_ALIGN      // pages must be aligned on this for the page map.\n#define MI_PAGE_MIN_START_BLOCK_ALIGN     MI_MAX_ALIGN_SIZE         // minimal block alignment for the first block in a page (16b)\n#define MI_PAGE_MAX_START_BLOCK_ALIGN2    (4*MI_KiB)                // maximal block alignment for \"power of 2\"-sized blocks (such that we guarantee natural alignment)\n#define MI_PAGE_OSPAGE_BLOCK_ALIGN2       (4*MI_KiB)                // also aligns any multiple of this size to avoid TLB misses.\n#define MI_PAGE_MAX_OVERALLOC_ALIGN       MI_ARENA_SLICE_SIZE       // (64 KiB) limit for which we overallocate in arena pages, beyond this use OS allocation\n\n// The max object sizes are intended to not waste more than ~ 12.5% internally over the page sizes.\n#define MI_SMALL_MAX_OBJ_SIZE             ((MI_SMALL_PAGE_SIZE-MI_PAGE_OSPAGE_BLOCK_ALIGN2)/6)   // = 10 KiB\n#if MI_ENABLE_LARGE_PAGES\n#define MI_MEDIUM_MAX_OBJ_SIZE            ((MI_MEDIUM_PAGE_SIZE-MI_PAGE_OSPAGE_BLOCK_ALIGN2)/6)  // ~ 84 KiB\n#define MI_LARGE_MAX_OBJ_SIZE             (MI_LARGE_PAGE_SIZE/8)    // <= 512 KiB // note: this must be a nice power of 2 or we get rounding issues with `_mi_bin`\n#else\n#define MI_MEDIUM_MAX_OBJ_SIZE            (MI_MEDIUM_PAGE_SIZE/8)   // <= 64 KiB\n#define MI_LARGE_MAX_OBJ_SIZE             MI_MEDIUM_MAX_OBJ_SIZE    // note: this must be a nice power of 2 or we get rounding issues with `_mi_bin`\n#endif\n#define MI_LARGE_MAX_OBJ_WSIZE            (MI_LARGE_MAX_OBJ_SIZE/MI_SIZE_SIZE)\n\n#if (MI_LARGE_MAX_OBJ_WSIZE >= 655360)\n#error \"mimalloc internal: define more bins\"\n#endif\n\n\n// ------------------------------------------------------\n// Page kinds\n// ------------------------------------------------------\n\ntypedef enum mi_page_kind_e {\n  MI_PAGE_SMALL,      // small blocks go into 64KiB pages\n  MI_PAGE_MEDIUM,     // medium blocks go into 512KiB pages\n  MI_PAGE_LARGE,      // larger blocks go into 4MiB pages (if `MI_ENABLE_LARGE_PAGES==1`)\n  MI_PAGE_SINGLETON   // page containing a single block.\n                      // used for blocks `> MI_LARGE_MAX_OBJ_SIZE` or an alignment `> MI_PAGE_MAX_OVERALLOC_ALIGN`.\n} mi_page_kind_t;\n\n\n\n// ------------------------------------------------------\n// A \"theap\" is a thread local heap which owns pages.\n// (making them thread-local avoids atomic operations)\n//\n// All theaps belong to a (non-thread-local) heap.\n// A theap just owns a set of pages for allocation and\n// can only be allocate/reallocate from the thread that created it.\n// Freeing blocks can be done from any thread though.\n//\n// Per thread, there is always a default theap that belongs\n// to the default heap. It is initialized to statically\n// point initially to an empty theap to avoid initialization\n// checks in the fast path.\n// ------------------------------------------------------\n\n// Thread local data\ntypedef struct mi_tld_s mi_tld_t;   // defined below\n\n// Pages of a certain block size are held in a queue.\ntypedef struct mi_page_queue_s {\n  mi_page_t* first;\n  mi_page_t* last;\n  size_t     count;\n  size_t     block_size;\n} mi_page_queue_t;\n\n// Random context\ntypedef struct mi_random_cxt_s {\n  uint32_t input[16];\n  uint32_t output[16];\n  int      output_available;\n  bool     weak;\n} mi_random_ctx_t;\n\n\n// In debug mode there is a padding structure at the end of the blocks to check for buffer overflows\n#if MI_PADDING\ntypedef struct mi_padding_s {\n  uint32_t canary; // encoded block value to check validity of the padding (in case of overflow)\n  uint32_t delta;  // padding bytes before the block. (mi_usable_size(p) - delta == exact allocated bytes)\n} mi_padding_t;\n#define MI_PADDING_SIZE   (sizeof(mi_padding_t))\n#define MI_PADDING_WSIZE  ((MI_PADDING_SIZE + MI_INTPTR_SIZE - 1) / MI_INTPTR_SIZE)\n#else\n#define MI_PADDING_SIZE   0\n#define MI_PADDING_WSIZE  0\n#endif\n\n#define MI_PAGES_DIRECT   (MI_SMALL_WSIZE_MAX + MI_PADDING_WSIZE + 1)\n\n\n// A thread-local heap (\"theap\") owns a set of thread-local pages.\nstruct mi_theap_s {\n  mi_tld_t*             tld;                                 // thread-local data\n  _Atomic(mi_heap_t*)   heap;                                // the heap this theap belongs to.\n  _Atomic(size_t)       refcount;                            // reference count\n  unsigned long long    heartbeat;                           // monotonic heartbeat count\n  uintptr_t             cookie;                              // random cookie to verify pointers (see `_mi_ptr_cookie`)\n  mi_random_ctx_t       random;                              // random number context used for secure allocation\n  size_t                page_count;                          // total number of pages in the `pages` queues.\n  size_t                page_retired_min;                    // smallest retired index (retired pages are fully free, but still in the page queues)\n  size_t                page_retired_max;                    // largest retired index into the `pages` array.\n  size_t                pages_full_size;                     // optimization: total size of blocks in the pages of the full queue (issue #1220)\n  long                  generic_count;                       // how often is `_mi_malloc_generic` called?\n  long                  generic_collect_count;               // how often is `_mi_malloc_generic` called without collecting?\n\n  mi_theap_t*           tnext;                               // list of theaps in this thread\n  mi_theap_t*           tprev;  \n  mi_theap_t*           hnext;                               // list of theaps of the owning `heap`\n  mi_theap_t*           hprev;\n  \n  long                  page_full_retain;                    // how many full pages can be retained per queue (before abandoning them)\n  bool                  allow_page_reclaim;                  // `true` if this theap should not reclaim abandoned pages\n  bool                  allow_page_abandon;                  // `true` if this theap can abandon pages to reduce memory footprint\n  #if MI_GUARDED\n  size_t                guarded_size_min;                    // minimal size for guarded objects\n  size_t                guarded_size_max;                    // maximal size for guarded objects\n  size_t                guarded_sample_rate;                 // sample rate (set to 0 to disable guarded pages)\n  size_t                guarded_sample_count;                // current sample count (counting down to 0)\n  #endif\n  mi_page_t*            pages_free_direct[MI_PAGES_DIRECT];  // optimize: array where every entry points a page with possibly free blocks in the corresponding queue for that size.\n  mi_page_queue_t       pages[MI_BIN_COUNT];                 // queue of pages for each size class (or \"bin\")\n  mi_memid_t            memid;                               // provenance of the theap struct itself (meta or os)\n  mi_stats_t            stats;                               // thread-local statistics\n};\n\n\n\n\n// ------------------------------------------------------\n// Heaps contain allocated blocks. Heaps are self-contained\n// but share the (sub-process) memory in the arena's.\n// ------------------------------------------------------\n\n// Keep track of all owned and abandoned pages in the arena's\nstruct mi_arena_pages_s;\ntypedef struct mi_arena_pages_s mi_arena_pages_t;\n\n#define MI_MAX_ARENAS   (160)   // Limited for now (and takes up .bss).. but arena's scale up exponentially (see `mi_arena_reserve`)\n                                // 160 arenas is enough for ~2 TiB memory\n\n// A dynamic thread-local variable; 0 for an invalid thread-local\ntypedef size_t mi_thread_local_t;\n\ntypedef struct mi_heap_s {\n  mi_subproc_t*         subproc;                        // a heap belongs to a subprocess\n  size_t                heap_seq;                       // unique sequence number for heaps in this subprocess\n  mi_heap_t*            next;                           // list of heaps in this subprocess\n  mi_heap_t*            prev;\n  mi_thread_local_t     theap;                          // dynamic thread local for the thread-local theaps of this heap\n\n  mi_arena_t*           exclusive_arena;                // if the heap should only allocate from a specific arena (or NULL)\n  int                   numa_node;                      // if >=0, prefer this numa node for allocations\n\n  mi_theap_t*           theaps;                         // list of all thread-local theaps belonging to this heap (using the `hnext`/`hprev` fields)\n  mi_lock_t             theaps_lock;                    // lock for the theaps list operations\n\n  _Atomic(size_t)       abandoned_count[MI_BIN_COUNT];  // total count of abandoned pages in this heap\n  mi_page_t*            os_abandoned_pages;             // list of pages that are OS allocated and not in an arena\n  mi_lock_t             os_abandoned_pages_lock;        // lock for the os abandoned pages list (this lock protects list operations)\n\n  _Atomic(mi_arena_pages_t*) arena_pages[MI_MAX_ARENAS]; // track owned and abandoned pages in the arenas (entries can be NULL)\n  mi_lock_t             arena_pages_lock;                // lock to update the arena_pages array\n\n  mi_stats_t            stats;                           // statistics for this heap; periodically updated by merging from each theap\n} mi_heap_t;\n\n\n// ------------------------------------------------------\n// Sub processes do not reclaim or visit pages from other sub processes.\n// These are essentially the static variables of a process, and\n// usually there is only one subprocess. This can be used for example\n// by CPython to have separate interpreters within one process.\n// Each thread can only belong to one subprocess\n// (and needs to call `mi_subproc_add_current_thread` before any allocations).\n// ------------------------------------------------------\n\nstruct mi_subproc_s {\n  size_t                subproc_seq;                    // unique id for sub-processes\n  mi_subproc_t*         next;                           // list of all sub-processes\n  mi_subproc_t*         prev;\n\n  _Atomic(size_t)       arena_count;                    // current count of arena's\n  _Atomic(mi_arena_t*)  arenas[MI_MAX_ARENAS];          // arena's of this sub-process\n  mi_lock_t             arena_reserve_lock;             // lock to ensure arena's get reserved one at a time\n  mi_decl_align(8)                                      // needed on some 32-bit platforms\n  _Atomic(int64_t)      purge_expire;                   // expiration is set if any arenas can be purged\n\n  _Atomic(mi_heap_t*)   heap_main;                      // main heap for this sub process\n  mi_heap_t*            heaps;                          // heaps belonging to this sub-process\n  mi_lock_t             heaps_lock;\n\n  _Atomic(size_t)       thread_count;                   // current threads associated with this sub-process\n  _Atomic(size_t)       thread_total_count;             // total created threads associated with this sub-process\n  _Atomic(size_t)       heap_count;                     // current heaps in this sub-process (== |heaps|)\n  _Atomic(size_t)       heap_total_count;               // total created heaps in this sub-process\n\n  mi_memid_t            memid;                          // provenance of this memory block (meta or static)\n  mi_decl_align(8)                                      // needed on some 32-bit platforms\n  mi_stats_t            stats;                          // subprocess statistics; updated for arena/OS stats like committed,\n                                                        // and otherwise merged with heap stats when those are deleted\n};\n\n\n// ------------------------------------------------------\n// Thread Local data\n// ------------------------------------------------------\n\n// Milliseconds as in `int64_t` to avoid overflows\ntypedef int64_t  mi_msecs_t;\n\n// Thread local data\nstruct mi_tld_s {\n  mi_threadid_t         thread_id;            // thread id of this thread\n  size_t                thread_seq;           // thread sequence id (linear count of created threads)\n  int                   numa_node;            // thread preferred numa node\n  mi_subproc_t*         subproc;              // sub-process this thread belongs to.\n  mi_theap_t*           theaps;               // list of theaps in this thread (so we can abandon all when the thread terminates)\n  mi_lock_t             theaps_lock;          // lock as the theaps list is sometimes accessed from another thread (on `mi_heap_free`)\n  bool                  recurse;              // true if deferred was called; used to prevent infinite recursion.\n  bool                  is_in_threadpool;     // true if this thread is part of a threadpool (and can run arbitrary tasks)\n  mi_memid_t            memid;                // provenance of the tld memory itself (meta or OS)\n};\n\n\n/* ----------------------------------------------------------------------------\n  Arenas are fixed area's of OS memory from which we can allocate\n  large blocks (>= MI_ARENA_MIN_BLOCK_SIZE).\n  In contrast to the rest of mimalloc, the arenas are shared between\n  threads and need to be accessed using atomic operations (using atomic `mi_bitmap_t`'s).\n\n  Arenas are also used to for huge OS page (1GiB) reservations or for reserving\n  OS memory upfront which can be improve performance or is sometimes needed\n  on embedded devices. We can also employ this with WASI or `sbrk` systems\n  to reserve large arenas upfront and be able to reuse the memory more effectively.\n-----------------------------------------------------------------------------*/\n\n#define MI_ARENA_BIN_COUNT      (MI_BIN_COUNT)\n#define MI_ARENA_MIN_SIZE       (MI_BCHUNK_BITS * MI_ARENA_SLICE_SIZE)           // 32 MiB (or 8 MiB on 32-bit)\n#define MI_ARENA_MAX_SIZE       (MI_BITMAP_MAX_BIT_COUNT * MI_ARENA_SLICE_SIZE)\n\ntypedef struct mi_bitmap_s  mi_bitmap_t;    // atomic bitmap  (defined in `src/bitmap.h`)\ntypedef struct mi_bbitmap_s mi_bbitmap_t;   // atomic binned bitmap (defined in `src/bitmap.h`)\n\ntypedef struct mi_arena_pages_s {\n  mi_bitmap_t* pages;                // all registered pages (abandoned and owned)\n  mi_bitmap_t* pages_abandoned[MI_ARENA_BIN_COUNT];  // abandoned pages per size bin (a set bit means the start of the page)\n  // followed by the bitmaps (whose siz`es depend on the arena size)\n} mi_arena_pages_t;\n\n\n// A memory arena\ntypedef struct mi_arena_s {\n  mi_memid_t          memid;                // provenance of the memory area\n  mi_subproc_t*       subproc;              // subprocess this arena belongs to (`this 'element-of' this->subproc->arenas`)\n  size_t              arena_idx;            // index in the arenas array\n\n  size_t              slice_count;          // total size of the area in arena slices (of `MI_ARENA_SLICE_SIZE`)\n  size_t              info_slices;          // initial slices reserved for the arena bitmaps\n  int                 numa_node;            // associated NUMA node\n  bool                is_exclusive;         // only allow allocations if specifically for this arena\n  mi_decl_align(8)                          // needed on some 32-bit platforms\n  _Atomic(mi_msecs_t) purge_expire;         // expiration time when slices can be purged from `slices_purge`.\n  mi_commit_fun_t*    commit_fun;           // custom commit/decommit memory\n  void*               commit_fun_arg;       // user argument for a custom commit function\n\n  size_t              total_size;           // for (user given) memory more than MI_ARENA_MAX_SIZE, we use N arena's to cover it. The first (parent) has the total size (and the other sub-arena's 0).\n  mi_arena_t*         parent;               // if this is a sub arena, this points to the first one in the memory area.\n\n  mi_bbitmap_t*       slices_free;          // is the slice free? (a binned bitmap with size classes)\n  mi_bitmap_t*        slices_committed;     // is the slice committed? (i.e. accessible)\n  mi_bitmap_t*        slices_dirty;         // is the slice potentially non-zero?\n  mi_bitmap_t*        slices_purge;         // slices that can be purged\n  mi_page_t*          pages_meta;           // pre-allocated `slice_count` page meta info -- only used if `MI_PAGE_META_IS_SEPARATED!=0`\n  mi_arena_pages_t    pages_main;           // arena page bitmaps for the main heap are allocated up front as well\n\n  // followed by the bitmaps (whose sizes depend on the arena size)\n  // note: when adding bitmaps revise `mi_arena_info_slices_needed`\n} mi_arena_t;\n\n\n\n/* -----------------------------------------------------------\n  Error codes passed to `_mi_fatal_error`\n  All are recoverable but EFAULT is a serious error and aborts by default in secure mode.\n  For portability define undefined error codes using common Unix codes:\n  <https://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html>\n----------------------------------------------------------- */\n\n#ifndef EAGAIN         // double free\n#define EAGAIN (11)\n#endif\n#ifndef ENOMEM         // out of memory\n#define ENOMEM (12)\n#endif\n#ifndef EFAULT         // corrupted free-list or meta-data\n#define EFAULT (14)\n#endif\n#ifndef EINVAL         // trying to free an invalid pointer\n#define EINVAL (22)\n#endif\n#ifndef EOVERFLOW      // count*size overflow\n#define EOVERFLOW (75)\n#endif\n\n/* -----------------------------------------------------------\n  Debug constants\n----------------------------------------------------------- */\n\n#if !defined(MI_DEBUG_UNINIT)\n#define MI_DEBUG_UNINIT     (0xD0)\n#endif\n#if !defined(MI_DEBUG_FREED)\n#define MI_DEBUG_FREED      (0xDF)\n#endif\n#if !defined(MI_DEBUG_PADDING)\n#define MI_DEBUG_PADDING    (0xDE)\n#endif\n\n\n#endif // MI_TYPES_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/alloc-aligned.c",
      "sha256": "70420b4430da4bb6b5197fd27c6c0df485249c53a986bc9536c9fb643fc7613b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"  // _mi_theap_default\n\n#include <string.h>     // memset\n\n// ------------------------------------------------------\n// Aligned Allocation\n// ------------------------------------------------------\n\nstatic bool mi_malloc_is_naturally_aligned( size_t size, size_t alignment ) {\n  // certain blocks are always allocated at a certain natural alignment.\n  // (see also `arena.c:mi_arenas_page_alloc_fresh`).\n  mi_assert_internal(_mi_is_power_of_two(alignment) && (alignment > 0));\n  if (alignment > size) return false;\n  const size_t bsize = mi_good_size(size);\n  const bool ok = (bsize <= MI_PAGE_MAX_START_BLOCK_ALIGN2 && _mi_is_power_of_two(bsize)) ||             // power-of-two under N\n                  (alignment==MI_PAGE_OSPAGE_BLOCK_ALIGN2 && (bsize % MI_PAGE_OSPAGE_BLOCK_ALIGN2)==0);  // or multiple of N\n  if (ok) { mi_assert_internal((bsize & (alignment-1)) == 0); } // since both power of 2 and alignment <= size\n  return ok;\n}\n\n#if MI_GUARDED\nstatic mi_decl_restrict void* mi_theap_malloc_guarded_aligned(mi_theap_t* theap, size_t size, size_t alignment, bool zero) mi_attr_noexcept {\n  // use over allocation for guarded blocksl\n  #if MI_THEAP_INITASNULL\n  if mi_unlikely(theap==NULL) { theap = _mi_theap_empty_get(); }\n  #endif\n  mi_assert_internal(alignment > 0 && alignment < MI_PAGE_MAX_OVERALLOC_ALIGN);\n  if mi_unlikely(alignment >= MI_PAGE_MAX_OVERALLOC_ALIGN || size > (MI_MAX_ALLOC_SIZE - MI_PADDING_SIZE - alignment)) {\n    _mi_error_message(EOVERFLOW, \"(guarded) aligned allocation request is too large (size %zu, alignment %zu)\\n\", size, alignment);\n    return NULL;\n  }\n  const size_t oversize = size + alignment - 1;\n  void* const base = _mi_theap_malloc_guarded(theap, oversize, zero);\n  if (base==NULL) return NULL;\n  void* const p = _mi_align_up_ptr(base, alignment);\n  mi_track_align(base, p, (uint8_t*)p - (uint8_t*)base, size);\n  mi_assert_internal(mi_usable_size(p) >= size);\n  mi_assert_internal(_mi_is_aligned(p, alignment));\n  return p;\n}\n\nstatic void* mi_theap_malloc_zero_no_guarded(mi_theap_t* theap, size_t size, bool zero, size_t* usable) {\n  #if MI_THEAP_INITASNULL\n  if mi_unlikely(theap==NULL) { theap = _mi_theap_empty_get(); }\n  #endif\n  const size_t rate = theap->guarded_sample_rate;\n  // only write if `rate!=0` so we don't write to the constant `_mi_theap_empty`\n  if (rate != 0) { theap->guarded_sample_rate = 0; }\n  void* p = _mi_theap_malloc_zero(theap, size, zero, usable);\n  if (rate != 0) { theap->guarded_sample_rate = rate; }\n  return p;\n}\n#else\nstatic void* mi_theap_malloc_zero_no_guarded(mi_theap_t* theap, size_t size, bool zero, size_t* usable) {\n  return _mi_theap_malloc_zero(theap, size, zero, usable);\n}\n#endif\n\n// Fallback aligned allocation that over-allocates -- split out for better codegen\nstatic mi_decl_noinline void* mi_theap_malloc_zero_aligned_at_overalloc(mi_theap_t* const theap, const size_t size, const size_t alignment, const size_t offset, const bool zero, size_t* usable) mi_attr_noexcept\n{\n  mi_assert_internal(size <= (MI_MAX_ALLOC_SIZE - MI_PADDING_SIZE));\n  mi_assert_internal(alignment != 0 && _mi_is_power_of_two(alignment));\n\n  void* p;\n  size_t oversize;\n  if mi_unlikely(alignment > MI_PAGE_MAX_OVERALLOC_ALIGN) {\n    // use OS allocation for large alignments and allocate inside a singleton page (not in an arena)\n    // This can support alignments >= MI_PAGE_ALIGN by ensuring the object can be aligned\n    // in the first (and single) page such that the page info is `MI_PAGE_ALIGN` bytes before it (and can be found in the _mi_page_map).\n    if mi_unlikely(offset != 0) {\n      // todo: cannot support offset alignment for very large alignments yet\n      _mi_error_message(EOVERFLOW, \"aligned allocation with a large alignment cannot be used with an alignment offset (size %zu, alignment %zu, offset %zu)\\n\", size, alignment, offset);\n      return NULL;\n    }\n    oversize = (size <= MI_SMALL_SIZE_MAX ? MI_SMALL_SIZE_MAX + 1 /* ensure we use generic malloc path */ : size);\n    // note: no guarded as alignment > 0\n    p = _mi_theap_malloc_zero_ex(theap, oversize, zero, alignment, usable); // the page block size should be large enough to align in the single huge page block\n    if (p == NULL) return NULL;\n  }\n  else {\n    // otherwise over-allocate\n    mi_assert_internal(size <= (MI_MAX_ALLOC_SIZE - MI_PADDING_SIZE) && alignment <= MI_PAGE_MAX_OVERALLOC_ALIGN);\n    mi_assert_internal(size < SIZE_MAX - alignment); // `oversize` cannot overflow\n    oversize = (size < MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : size) + alignment - 1;  // adjust for size <= 16; with size 0 and alignment 64k, we would allocate a 64k block and pointing just beyond that.\n    p = mi_theap_malloc_zero_no_guarded(theap, oversize, zero, usable);\n    if (p == NULL) return NULL;\n  }\n\n  // .. and align within the allocation\n  const uintptr_t align_mask = alignment - 1;  // for any x, `(x & align_mask) == (x % alignment)`\n  const uintptr_t poffset = ((uintptr_t)p + offset) & align_mask;\n  const uintptr_t adjust  = (poffset == 0 ? 0 : alignment - poffset);\n  mi_assert_internal(adjust < alignment);\n  void* aligned_p = (void*)((uintptr_t)p + adjust);\n\n  // note: after the above allocation, the page may be abandoned now (as it became full, see `page.c:_mi_malloc_generic`)\n  // and we no longer own it. We should be careful to only read constant fields in the page,\n  // or use safe atomic access as in `mi_page_set_has_interior_pointers`.\n  // (we can access the page though since the just allocated pointer keeps it alive)\n  mi_page_t* page = _mi_ptr_page(p);\n  if (aligned_p != p) {\n    mi_page_set_has_interior_pointers(page, true);\n    #if MI_GUARDED\n    // set tag to aligned so mi_usable_size works with guard pages\n    if (adjust >= sizeof(mi_block_t)) {\n      mi_block_t* const block = (mi_block_t*)p;\n      block->next = MI_BLOCK_TAG_ALIGNED;\n    }\n    #endif\n    _mi_padding_shrink(page, (mi_block_t*)p, adjust + size);\n  }\n  // todo: expand padding if overallocated ?\n\n  mi_assert_internal(mi_page_usable_block_size(page) >= adjust + size);\n  mi_assert_internal(((uintptr_t)aligned_p + offset) % alignment == 0);\n  mi_assert_internal(mi_usable_size(aligned_p)>=size);\n  mi_assert_internal(mi_usable_size(p) == mi_usable_size(aligned_p)+adjust);\n  #if MI_DEBUG > 1\n  mi_page_t* const apage = _mi_ptr_page(aligned_p);\n  void* unalign_p = _mi_page_ptr_unalign(apage, aligned_p);\n  mi_assert_internal(p == unalign_p);\n  #endif\n\n  // now zero the block if needed\n  //if (alignment > MI_PAGE_MAX_OVERALLOC_ALIGN) {\n  //  // for the tracker, on huge aligned allocations only from the start of the large block is defined\n  //  mi_track_mem_undefined(aligned_p, size);\n  //  if (zero) {\n  //    _mi_memzero_aligned(aligned_p, mi_usable_size(aligned_p));\n  //  }\n  //}\n\n  if (p != aligned_p) {\n    mi_track_align(p,aligned_p,adjust,mi_usable_size(aligned_p));\n    #if MI_GUARDED\n    mi_track_mem_defined(p, sizeof(mi_block_t));\n    #endif\n  }\n  return aligned_p;\n}\n\n// Generic primitive aligned allocation -- split out for better codegen\nstatic mi_decl_noinline void* mi_theap_malloc_zero_aligned_at_generic(mi_theap_t* const theap, const size_t size, const size_t alignment, const size_t offset, const bool zero, size_t* usable) mi_attr_noexcept\n{\n  mi_assert_internal(alignment != 0 && _mi_is_power_of_two(alignment));\n  // we don't allocate more than MI_MAX_ALLOC_SIZE (see <https://sourceware.org/ml/libc-announce/2019/msg00001.html>)\n  if mi_unlikely(size > (MI_MAX_ALLOC_SIZE - MI_PADDING_SIZE)) {\n    _mi_error_message(EOVERFLOW, \"aligned allocation request is too large (size %zu, alignment %zu)\\n\", size, alignment);\n    return NULL;\n  }\n\n  // use regular allocation if it is guaranteed to fit the alignment constraints.\n  // this is important to try as the fast path in `mi_theap_malloc_zero_aligned` only works when there exist\n  // a page with the right block size, and if we always use the over-alloc fallback that would never happen.\n  if (offset == 0 && mi_malloc_is_naturally_aligned(size,alignment)) {\n    void* p = mi_theap_malloc_zero_no_guarded(theap, size, zero, usable);\n    mi_assert_internal(p == NULL || ((uintptr_t)p % alignment) == 0);\n    const bool is_aligned_or_null = (((uintptr_t)p) & (alignment-1))==0;\n    if mi_likely(is_aligned_or_null) {\n      return p;\n    }\n    else {\n      // this should never happen if the `mi_malloc_is_naturally_aligned` check is correct..\n      mi_assert(false);\n      mi_free(p);\n    }\n  }\n\n  // fall back to over-allocation\n  return mi_theap_malloc_zero_aligned_at_overalloc(theap,size,alignment,offset,zero,usable);\n}\n\n\n// Primitive aligned allocation\nstatic inline void* mi_theap_malloc_zero_aligned_at(mi_theap_t* const theap, const size_t size, const size_t alignment, const size_t offset, const bool zero, size_t* usable) mi_attr_noexcept\n{\n  // note: we don't require `size > offset`, we just guarantee that the address at offset is aligned regardless of the allocated size.\n  if mi_unlikely(alignment == 0 || !_mi_is_power_of_two(alignment)) { // require power-of-two (see <https://en.cppreference.com/w/c/memory/aligned_alloc>)\n    #if MI_DEBUG > 0\n    _mi_error_message(EOVERFLOW, \"aligned allocation requires the alignment to be a power-of-two (size %zu, alignment %zu)\\n\", size, alignment);\n    #endif\n    return NULL;\n  }\n\n  #if MI_GUARDED\n  #if MI_THEAP_INITASNULL\n  if mi_likely(theap!=NULL)\n  #endif\n  if (offset==0 && alignment < MI_PAGE_MAX_OVERALLOC_ALIGN && mi_theap_malloc_use_guarded(theap,size)) {\n    return mi_theap_malloc_guarded_aligned(theap, size, alignment, zero);\n  }\n  #endif\n\n  // try first if there happens to be a small block available with just the right alignment\n  // since most small power-of-2 blocks (under MI_PAGE_MAX_BLOCK_START_ALIGN2) are already\n  // naturally aligned this can be often the case.\n  #if MI_THEAP_INITASNULL\n  if mi_likely(theap!=NULL)\n  #endif\n  {\n    if mi_likely(size <= MI_SMALL_SIZE_MAX && alignment <= size) {\n      const uintptr_t align_mask = alignment-1;       // for any x, `(x & align_mask) == (x % alignment)`\n      const size_t padsize = size + MI_PADDING_SIZE;\n      mi_page_t* page = _mi_theap_get_free_small_page(theap, padsize);\n      if mi_likely(page->free != NULL) {\n        const bool is_aligned = (((uintptr_t)page->free + offset) & align_mask)==0;\n        if mi_likely(is_aligned)\n        {\n          if (usable!=NULL) { *usable = mi_page_usable_block_size(page); }\n          void* p = _mi_page_malloc_zero(theap, page, padsize, zero);\n          mi_assert_internal(p != NULL);\n          mi_assert_internal(((uintptr_t)p + offset) % alignment == 0);\n          mi_track_malloc(p, size, zero);\n          return p;\n        }\n      }\n    }\n  }\n\n  // fallback to generic aligned allocation\n  return mi_theap_malloc_zero_aligned_at_generic(theap, size, alignment, offset, zero, usable);\n}\n\n\n// ------------------------------------------------------\n// Internal mi_theap_malloc_aligned / mi_malloc_aligned\n// ------------------------------------------------------\n\nstatic mi_decl_restrict void* mi_theap_malloc_aligned_at(mi_theap_t* theap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_malloc_zero_aligned_at(theap, size, alignment, offset, false, NULL);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_theap_malloc_aligned(mi_theap_t* theap, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_malloc_aligned_at(theap, size, alignment, 0);\n}\n\nstatic mi_decl_restrict void* mi_theap_zalloc_aligned_at(mi_theap_t* theap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_malloc_zero_aligned_at(theap, size, alignment, offset, true, NULL);\n}\n\nstatic mi_decl_restrict void* mi_theap_zalloc_aligned(mi_theap_t* theap, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_zalloc_aligned_at(theap, size, alignment, 0);\n}\n\nstatic mi_decl_restrict void* mi_theap_calloc_aligned_at(mi_theap_t* theap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count, size, &total)) return NULL;\n  return mi_theap_zalloc_aligned_at(theap, total, alignment, offset);\n}\n\nstatic mi_decl_restrict void* mi_theap_calloc_aligned(mi_theap_t* theap, size_t count, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_calloc_aligned_at(theap, count, size, alignment, 0);\n}\n\n\n// ------------------------------------------------------\n// Aligned Allocation\n// ------------------------------------------------------\n\nmi_decl_nodiscard mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_malloc_aligned_at(_mi_theap_default(), size, alignment, offset);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_malloc_aligned(_mi_theap_default(), size, alignment);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_umalloc_aligned(size_t size, size_t alignment, size_t* block_size) mi_attr_noexcept {\n  return mi_theap_malloc_zero_aligned_at(_mi_theap_default(), size, alignment, 0, false, block_size);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_zalloc_aligned_at(_mi_theap_default(), size, alignment, offset);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_zalloc_aligned(_mi_theap_default(), size, alignment);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_uzalloc_aligned(size_t size, size_t alignment, size_t* block_size) mi_attr_noexcept {\n  return mi_theap_malloc_zero_aligned_at(_mi_theap_default(), size, alignment, 0, true, block_size);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_calloc_aligned_at(_mi_theap_default(), count, size, alignment, offset);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_calloc_aligned(_mi_theap_default(), count, size, alignment);\n}\n\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_malloc_aligned_at(_mi_heap_theap(heap), size, alignment, offset);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_malloc_aligned(_mi_heap_theap(heap), size, alignment);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_zalloc_aligned_at(_mi_heap_theap(heap), size, alignment, offset);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_zalloc_aligned(_mi_heap_theap(heap), size, alignment);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_calloc_aligned_at(_mi_heap_theap(heap), count, size, alignment, offset);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_calloc_aligned(_mi_heap_theap(heap), count, size, alignment);\n}\n\n\n// ------------------------------------------------------\n// Aligned re-allocation\n// ------------------------------------------------------\n\nstatic void* mi_theap_realloc_zero_aligned_at(mi_theap_t* theap, void* p, size_t newsize, size_t alignment, size_t offset, bool zero) mi_attr_noexcept {\n  mi_assert(alignment > 0);\n  if (alignment <= sizeof(uintptr_t) && offset==0) return _mi_theap_realloc_zero(theap,p,newsize,zero,NULL,NULL);\n  if (p == NULL) return mi_theap_malloc_zero_aligned_at(theap,newsize,alignment,offset,zero,NULL);\n  size_t size = mi_usable_size(p);\n  if (newsize <= size && newsize >= (size - (size / 2))\n      && (((uintptr_t)p + offset) % alignment) == 0) {\n    return p;  // reallocation still fits, is aligned and not more than 25% waste\n  }\n  else {\n    // note: we don't zero allocate upfront so we only zero initialize the expanded part\n    void* newp = mi_theap_malloc_aligned_at(theap,newsize,alignment,offset);\n    if (newp != NULL) {\n      if (zero && newsize > size) {\n        // also set last word in the previous allocation to zero to ensure any padding is zero-initialized\n        size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0);\n        _mi_memzero((uint8_t*)newp + start, newsize - start);\n      }\n      _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize));\n      mi_free(p); // only free if successful\n    }\n    return newp;\n  }\n}\n\nstatic void* mi_theap_realloc_zero_aligned(mi_theap_t* theap, void* p, size_t newsize, size_t alignment, bool zero) mi_attr_noexcept {\n  mi_assert(alignment > 0);\n  if (alignment <= sizeof(uintptr_t)) return _mi_theap_realloc_zero(theap,p,newsize,zero,NULL,NULL);\n  return mi_theap_realloc_zero_aligned_at(theap,p,newsize,alignment,0,zero);\n}\n\nstatic void* mi_theap_realloc_aligned_at(mi_theap_t* theap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_realloc_zero_aligned_at(theap,p,newsize,alignment,offset,false);\n}\n\nstatic void* mi_theap_realloc_aligned(mi_theap_t* theap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept {\n  return mi_theap_realloc_zero_aligned(theap,p,newsize,alignment,false);\n}\n\nstatic void* mi_theap_rezalloc_aligned_at(mi_theap_t* theap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_realloc_zero_aligned_at(theap, p, newsize, alignment, offset, true);\n}\n\nstatic void* mi_theap_rezalloc_aligned(mi_theap_t* theap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept {\n  return mi_theap_realloc_zero_aligned(theap, p, newsize, alignment, true);\n}\n\nstatic void* mi_theap_recalloc_aligned_at(mi_theap_t* theap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(newcount, size, &total)) return NULL;\n  return mi_theap_rezalloc_aligned_at(theap, p, total, alignment, offset);\n}\n\nstatic void* mi_theap_recalloc_aligned(mi_theap_t* theap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(newcount, size, &total)) return NULL;\n  return mi_theap_rezalloc_aligned(theap, p, total, alignment);\n}\n\n\nmi_decl_nodiscard void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_realloc_aligned_at(_mi_theap_default(), p, newsize, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept {\n  return mi_theap_realloc_aligned(_mi_theap_default(), p, newsize, alignment);\n}\n\nmi_decl_nodiscard void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_rezalloc_aligned_at(_mi_theap_default(), p, newsize, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept {\n  return mi_theap_rezalloc_aligned(_mi_theap_default(), p, newsize, alignment);\n}\n\nmi_decl_nodiscard void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_recalloc_aligned_at(_mi_theap_default(), p, newcount, size, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_recalloc_aligned(_mi_theap_default(), p, newcount, size, alignment);\n}\n\n\nmi_decl_nodiscard void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_realloc_aligned_at(_mi_heap_theap(heap), p, newsize, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept {\n  return mi_theap_realloc_aligned(_mi_heap_theap(heap), p, newsize, alignment);\n}\n\nmi_decl_nodiscard void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_rezalloc_aligned_at(_mi_heap_theap(heap), p, newsize, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept {\n  return mi_theap_rezalloc_aligned(_mi_heap_theap(heap), p, newsize, alignment);\n}\n\nmi_decl_nodiscard void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {\n  return mi_theap_recalloc_aligned_at(_mi_heap_theap(heap), p, newcount, size, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept {\n  return mi_theap_recalloc_aligned(_mi_heap_theap(heap), p, newcount, size, alignment);\n}\n\n\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/alloc-override.c",
      "sha256": "6c8e9b0d042481c55791edb7330daec64bedaf26f0e70c9ca40de3cc17a690fe",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2026, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#if !defined(MI_IN_ALLOC_C)\n#error \"this file should be included from 'alloc.c' (so aliases can work)\"\n#endif\n\n\n#if defined(MI_MALLOC_OVERRIDE) && !defined(_DLL)\n\n#if defined(__APPLE__)\n#include <AvailabilityMacros.h>\nmi_decl_externc void   vfree(void* p);\nmi_decl_externc size_t malloc_size(const void* p);\nmi_decl_externc size_t malloc_good_size(size_t size);\n#endif\n\n// helper definition for C override of C++ new\ntypedef void* mi_nothrow_t;\n\n// ------------------------------------------------------\n// Override system malloc\n// ------------------------------------------------------\n\n#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__) && !MI_TRACK_ENABLED\n  // gcc, clang: use aliasing to alias the exported function to one of our `mi_` functions\n  #if (defined(__GNUC__) && __GNUC__ >= 9)\n    #pragma GCC diagnostic ignored \"-Wattributes\"  // or we get warnings that nodiscard is ignored on a forward\n    #define MI_FORWARD(fun)      __attribute__((alias(#fun), used, visibility(\"default\"), copy(fun)));\n  #else\n    #define MI_FORWARD(fun)      __attribute__((alias(#fun), used, visibility(\"default\")));\n  #endif\n  #define MI_FORWARD1(fun,x)      MI_FORWARD(fun)\n  #define MI_FORWARD2(fun,x,y)    MI_FORWARD(fun)\n  #define MI_FORWARD3(fun,x,y,z)  MI_FORWARD(fun)\n  #define MI_FORWARD0(fun,x)      MI_FORWARD(fun)\n  #define MI_FORWARD02(fun,x,y)   MI_FORWARD(fun)\n#else\n  // otherwise use forwarding by calling our `mi_` function\n  #define MI_FORWARD1(fun,x)      { return fun(x); }\n  #define MI_FORWARD2(fun,x,y)    { return fun(x,y); }\n  #define MI_FORWARD3(fun,x,y,z)  { return fun(x,y,z); }\n  #define MI_FORWARD0(fun,x)      { fun(x); }\n  #define MI_FORWARD02(fun,x,y)   { fun(x,y); }\n#endif\n\n#if defined(__APPLE__) && defined(MI_SHARED_LIB_EXPORT) && defined(MI_OSX_INTERPOSE)\n  // define MI_OSX_IS_INTERPOSED as we should not provide forwarding definitions for\n  // functions that are interposed (or the interposing does not work)\n  #define MI_OSX_IS_INTERPOSED\n\n  mi_decl_externc size_t mi_malloc_size_checked(void *p) {\n    if (!mi_is_in_heap_region(p)) return 0;\n    return mi_usable_size(p);\n  }\n\n  // use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1`\n  // See: <https://books.google.com/books?id=K8vUkpOXhN4C&pg=PA73>\n  struct mi_interpose_s {\n    const void* replacement;\n    const void* target;\n  };\n  #define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun }\n  #define MI_INTERPOSE_MI(fun)            MI_INTERPOSE_FUN(fun,mi_##fun)\n\n  #define MI_INTERPOSE_DECLS(name)        __attribute__((used)) static struct mi_interpose_s name[]  __attribute__((section(\"__DATA, __interpose\")))\n\n  MI_INTERPOSE_DECLS(_mi_interposes) =\n  {\n    MI_INTERPOSE_MI(malloc),\n    MI_INTERPOSE_MI(calloc),\n    MI_INTERPOSE_MI(realloc),\n    MI_INTERPOSE_MI(strdup),\n    MI_INTERPOSE_MI(realpath),\n    MI_INTERPOSE_MI(posix_memalign),\n    MI_INTERPOSE_MI(reallocf),\n    MI_INTERPOSE_MI(valloc),\n    MI_INTERPOSE_FUN(malloc_size,mi_malloc_size_checked),\n    MI_INTERPOSE_MI(malloc_good_size),\n    #ifdef MI_OSX_ZONE\n    // we interpose malloc_default_zone in alloc-override-osx.c so we can use mi_free safely\n    MI_INTERPOSE_MI(free),\n    MI_INTERPOSE_FUN(vfree,mi_free),\n    #else\n    // sometimes code allocates from default zone but deallocates using plain free :-( (like NxHashResizeToCapacity <https://github.com/nneonneo/osx-10.9-opensource/blob/master/objc4-551.1/runtime/hashtable2.mm>)\n    MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us\n    MI_INTERPOSE_FUN(vfree,mi_cfree),\n    #endif\n  };\n  #if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)\n  MI_INTERPOSE_DECLS(_mi_interposes_10_7)  = { MI_INTERPOSE_MI(strndup) };\n  #endif\n  #if defined(MAC_OS_X_VERSION_10_15) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15)\n  MI_INTERPOSE_DECLS(_mi_interposes_10_15) = { MI_INTERPOSE_MI(aligned_alloc) };\n  #endif\n\n  #ifdef __cplusplus\n  extern \"C\" {\n  #endif\n  void  _ZdlPv(void* p);   // delete\n  void  _ZdaPv(void* p);   // delete[]\n  void  _ZdlPvm(void* p, size_t n);  // delete\n  void  _ZdaPvm(void* p, size_t n);  // delete[]\n  void* _Znwm(size_t n);  // new\n  void* _Znam(size_t n);  // new[]\n  void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new nothrow\n  void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new[] nothrow\n  #ifdef __cplusplus\n  }\n  #endif\n  __attribute__((used)) static struct mi_interpose_s _mi_cxx_interposes[]  __attribute__((section(\"__DATA, __interpose\"))) =\n  {\n    MI_INTERPOSE_FUN(_ZdlPv,mi_free),\n    MI_INTERPOSE_FUN(_ZdaPv,mi_free),\n    MI_INTERPOSE_FUN(_ZdlPvm,mi_free_size),\n    MI_INTERPOSE_FUN(_ZdaPvm,mi_free_size),\n    MI_INTERPOSE_FUN(_Znwm,mi_new),\n    MI_INTERPOSE_FUN(_Znam,mi_new),\n    MI_INTERPOSE_FUN(_ZnwmRKSt9nothrow_t,mi_new_nothrow),\n    MI_INTERPOSE_FUN(_ZnamRKSt9nothrow_t,mi_new_nothrow),\n  };\n\n#elif defined(_MSC_VER)\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRT_HYBRIDPATCHABLE\n  void* __cdecl _expand(_Pre_notnull_ void* _Block, _In_ _CRT_GUARDOVERFLOW size_t _Size) {\n    return mi_expand(_Block, _Size);\n  }\n  _Check_return_ _ACRTIMP \n  size_t __cdecl _msize_base(_Pre_notnull_ void* _Block) _CRT_NOEXCEPT {\n    return mi_malloc_size(_Block);\n  }\n  _Check_return_ _ACRTIMP _CRT_HYBRIDPATCHABLE \n  size_t __cdecl _msize(_Pre_notnull_ void* _Block) {\n    return mi_malloc_size(_Block);\n  }\n  _ACRTIMP \n  void __cdecl _free_base(_Pre_maybenull_ _Post_invalid_ void* _Block) {\n    mi_free(_Block);\n  }\n  _ACRTIMP _CRT_HYBRIDPATCHABLE \n  void __cdecl free(_Pre_maybenull_ _Post_invalid_ void* _Block) {\n    mi_free(_Block);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRT_JIT_INTRINSIC _CRTRESTRICT _CRT_HYBRIDPATCHABLE\n  void* __cdecl malloc(_In_ _CRT_GUARDOVERFLOW size_t _Size) {\n    return mi_malloc(_Size);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _malloc_base(_In_ size_t _Size) {\n    return mi_malloc(_Size);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _realloc_base(_Pre_maybenull_ _Post_invalid_  void*  _Block, _In_ size_t _Size) {\n    return mi_realloc(_Block, _Size);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT _CRT_HYBRIDPATCHABLE\n  void* __cdecl realloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW  size_t _Size) {\n    return mi_realloc(_Block, _Size);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT \n  void* __cdecl _calloc_base(_In_ size_t _Count, _In_ size_t _Size) {\n    return mi_calloc(_Count, _Size);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRT_JIT_INTRINSIC _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl calloc(_In_ _CRT_GUARDOVERFLOW size_t _Count, _In_ _CRT_GUARDOVERFLOW size_t _Size) {\n    return mi_calloc(_Count, _Size);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _recalloc_base(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ size_t _Count, _In_ size_t _Size) {\n    return mi_recalloc(_Block, _Count, _Size);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _recalloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW size_t _Count, _In_ _CRT_GUARDOVERFLOW size_t _Size) {\n    return mi_recalloc(_Block, _Count, _Size);\n  }\n  _ACRTIMP \n  void __cdecl _aligned_free(_Pre_maybenull_ _Post_invalid_ void* _Block) {\n    mi_free(_Block);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_malloc(_In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment) {\n    return mi_malloc_aligned(_Size, _Alignment);\n  }\n  _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_offset_malloc(_In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment, _In_ size_t _Offset) {\n    return mi_malloc_aligned_at(_Size, _Alignment, _Offset);\n  }\n  _Check_return_ _ACRTIMP \n  size_t __cdecl _aligned_msize(_Pre_notnull_ void*  _Block, _In_ size_t _Alignment, _In_ size_t _Offset) {\n    MI_UNUSED(_Alignment); MI_UNUSED(_Offset); return mi_malloc_size(_Block);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_offset_realloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment, _In_ size_t _Offset) {\n    return mi_realloc_aligned_at(_Block, _Size, _Alignment, _Offset);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_offset_recalloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW size_t _Count, _In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment, _In_ size_t _Offset) {\n    return mi_recalloc_aligned_at(_Block, _Count, _Size, _Alignment, _Offset);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_realloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment) {\n    return mi_realloc_aligned(_Block, _Size, _Alignment);\n  }\n  _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Count * _Size) _ACRTIMP _CRTALLOCATOR _CRTRESTRICT\n  void* __cdecl _aligned_recalloc(_Pre_maybenull_ _Post_invalid_ void*  _Block, _In_ _CRT_GUARDOVERFLOW size_t _Count, _In_ _CRT_GUARDOVERFLOW size_t _Size, _In_ size_t _Alignment) {\n    return mi_recalloc_aligned(_Block, _Count, _Size, _Alignment);\n  }\n#else\n  // On all other systems forward allocation primitives to our API\n  mi_decl_export void* malloc(size_t size)              MI_FORWARD1(mi_malloc, size)\n  mi_decl_export void* calloc(size_t size, size_t n)    MI_FORWARD2(mi_calloc, size, n)\n  mi_decl_export void* realloc(void* p, size_t newsize) MI_FORWARD2(mi_realloc, p, newsize)\n  mi_decl_export void  free(void* p)                    MI_FORWARD0(mi_free, p)\n  // In principle we do not need to forward `strdup`/`strndup` but on some systems these do not use `malloc` internally (but a more primitive call)\n  // We only override if `strdup` is not a macro (as on some older libc's, see issue #885)\n  #if !defined(strdup)\n  mi_decl_export char* strdup(const char* str)             MI_FORWARD1(mi_strdup, str)\n  #endif\n  #if !defined(strndup) && (!defined(__APPLE__) || (defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7))\n  mi_decl_export char* strndup(const char* str, size_t n)  MI_FORWARD2(mi_strndup, str, n)\n  #endif\n#endif\n\n#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__)\n#pragma GCC visibility push(default)\n#endif\n\n// ------------------------------------------------------\n// Override new/delete\n// This is not really necessary as they usually call\n// malloc/free anyway, but it improves performance.\n// ------------------------------------------------------\n#ifdef __cplusplus\n  // ------------------------------------------------------\n  // With a C++ compiler we override the new/delete operators.\n  // see <https://en.cppreference.com/w/cpp/memory/new/operator_new>\n  // ------------------------------------------------------\n  #include <new>\n\n  #ifndef MI_OSX_IS_INTERPOSED\n    void operator delete(void* p) noexcept              MI_FORWARD0(mi_free,p)\n    void operator delete[](void* p) noexcept            MI_FORWARD0(mi_free,p)\n\n    void* operator new(std::size_t n) noexcept(false)   MI_FORWARD1(mi_new,n)\n    void* operator new[](std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n)\n\n    void* operator new  (std::size_t n, const std::nothrow_t& tag) noexcept { MI_UNUSED(tag); return mi_new_nothrow(n); }\n    void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { MI_UNUSED(tag); return mi_new_nothrow(n); }\n\n    #if (__cplusplus >= 201402L || _MSC_VER >= 1916)\n    void operator delete  (void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n)\n    void operator delete[](void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n)\n    #endif\n  #endif\n\n  #if (__cplusplus > 201402L && defined(__cpp_aligned_new)) && (!defined(__GNUC__) || (__GNUC__ > 5))\n  void operator delete  (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete  (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };\n  void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };\n  void operator delete  (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n  void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }\n\n  void* operator new( std::size_t n, std::align_val_t al)   noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }\n  void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }\n  void* operator new  (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }\n  void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }\n  #endif\n\n#elif (defined(__GNUC__) || defined(__clang__))\n  // ------------------------------------------------------\n  // Override by defining the mangled C++ names of the operators (as\n  // used by GCC and CLang).\n  // See <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling>\n  // ------------------------------------------------------\n\n  void _ZdlPv(void* p)            MI_FORWARD0(mi_free,p) // delete\n  void _ZdaPv(void* p)            MI_FORWARD0(mi_free,p) // delete[]\n  void _ZdlPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n)\n  void _ZdaPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n)\n\n  void _ZdlPvSt11align_val_t(void* p, size_t al)            { mi_free_aligned(p,al); }\n  void _ZdaPvSt11align_val_t(void* p, size_t al)            { mi_free_aligned(p,al); }\n  void _ZdlPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); }\n  void _ZdaPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); }\n\n  void _ZdlPvRKSt9nothrow_t(void* p, mi_nothrow_t tag)      { MI_UNUSED(tag); mi_free(p); }  // operator delete(void*, std::nothrow_t const&)\n  void _ZdaPvRKSt9nothrow_t(void* p, mi_nothrow_t tag)      { MI_UNUSED(tag); mi_free(p); }  // operator delete[](void*, std::nothrow_t const&)\n  void _ZdlPvSt11align_val_tRKSt9nothrow_t(void* p, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); mi_free_aligned(p,al); } // operator delete(void*, std::align_val_t, std::nothrow_t const&)\n  void _ZdaPvSt11align_val_tRKSt9nothrow_t(void* p, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); mi_free_aligned(p,al); } // operator delete[](void*, std::align_val_t, std::nothrow_t const&)\n\n  #if (MI_INTPTR_SIZE==8) || (MI_INTPTR_SIZE==4 && defined(__EMSCRIPTEN__))  // pr #1257\n    void* _Znwm(size_t n)                             MI_FORWARD1(mi_new,n)  // new 64-bit\n    void* _Znam(size_t n)                             MI_FORWARD1(mi_new,n)  // new[] 64-bit\n    void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }\n    void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }\n    void* _ZnwmSt11align_val_t(size_t n, size_t al)   MI_FORWARD2(mi_new_aligned, n, al)\n    void* _ZnamSt11align_val_t(size_t n, size_t al)   MI_FORWARD2(mi_new_aligned, n, al)\n    void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }\n    void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }\n  #elif (MI_INTPTR_SIZE==4)\n    void* _Znwj(size_t n)                             MI_FORWARD1(mi_new,n)  // new 64-bit\n    void* _Znaj(size_t n)                             MI_FORWARD1(mi_new,n)  // new[] 64-bit\n    void* _ZnwjRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }\n    void* _ZnajRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); }\n    void* _ZnwjSt11align_val_t(size_t n, size_t al)   MI_FORWARD2(mi_new_aligned, n, al)\n    void* _ZnajSt11align_val_t(size_t n, size_t al)   MI_FORWARD2(mi_new_aligned, n, al)\n    void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }\n    void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); }\n  #else\n    #error \"define overloads for new/delete for this platform (just for performance, can be skipped)\"\n  #endif\n#endif // __cplusplus\n\n// ------------------------------------------------------\n// Further Posix & Unix functions definitions\n// ------------------------------------------------------\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef MI_OSX_IS_INTERPOSED\n  // Forward Posix/Unix calls as well\n  void*  reallocf(void* p, size_t newsize) MI_FORWARD2(mi_reallocf,p,newsize)\n  size_t malloc_size(const void* p)        MI_FORWARD1(mi_usable_size,p)\n  #if !defined(__ANDROID__) && !defined(__FreeBSD__) && !defined(__DragonFly__)\n  size_t malloc_usable_size(void *p)       MI_FORWARD1(mi_usable_size,p)\n  #else\n  size_t malloc_usable_size(const void *p) MI_FORWARD1(mi_usable_size,p)\n  #endif\n\n  // No forwarding here due to aliasing/name mangling issues\n  void*  valloc(size_t size)               { return mi_valloc(size); }\n  void   vfree(void* p)                    { mi_free(p); }\n  size_t malloc_good_size(size_t size)     { return mi_malloc_good_size(size); }\n  int    posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p, alignment, size); }\n\n  // `aligned_alloc` is only available when __USE_ISOC11 is defined.\n  // Note: it seems __USE_ISOC11 is not defined in musl (and perhaps other libc's) so we only check\n  // for it if using glibc.\n  // Note: Conda has a custom glibc where `aligned_alloc` is declared `static inline` and we cannot\n  // override it, but both _ISOC11_SOURCE and __USE_ISOC11 are undefined in Conda GCC7 or GCC9.\n  // Fortunately, in the case where `aligned_alloc` is declared as `static inline` it\n  // uses internally `memalign`, `posix_memalign`, or `_aligned_malloc` so we  can avoid overriding it ourselves.\n  #if !defined(__GLIBC__) || __USE_ISOC11\n  void* aligned_alloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); }\n  #endif\n#endif\n\n// no forwarding here due to aliasing/name mangling issues\nvoid  cfree(void* p)                                    { mi_free(p); }\nvoid* pvalloc(size_t size)                              { return mi_pvalloc(size); }\nvoid* memalign(size_t alignment, size_t size)           { return mi_memalign(alignment, size); }\n#if !defined(_WIN32)\nvoid* _aligned_malloc(size_t size, size_t alignment)    { return mi_malloc_aligned(size,alignment); }\n#endif\nvoid* reallocarray(void* p, size_t count, size_t size)  { return mi_reallocarray(p, count, size); }\n// some systems define reallocarr so mark it as a weak symbol (#751)\nmi_decl_weak int reallocarr(void* p, size_t count, size_t size)    { return mi_reallocarr(p, count, size); }\n\n#if defined(__wasi__)\n  // forward __libc interface (see PR #667)\n  void* __libc_malloc(size_t size)                      MI_FORWARD1(mi_malloc, size)\n  void* __libc_calloc(size_t count, size_t size)        MI_FORWARD2(mi_calloc, count, size)\n  void* __libc_realloc(void* p, size_t size)            MI_FORWARD2(mi_realloc, p, size)\n  void  __libc_free(void* p)                            MI_FORWARD0(mi_free, p)\n  void* __libc_memalign(size_t alignment, size_t size)  { return mi_memalign(alignment, size); }\n\n#elif defined(__linux__)\n  // forward __libc interface (needed for glibc-based and musl-based Linux distributions)\n  void* __libc_malloc(size_t size)                      MI_FORWARD1(mi_malloc,size)\n  void* __libc_calloc(size_t count, size_t size)        MI_FORWARD2(mi_calloc,count,size)\n  void* __libc_realloc(void* p, size_t size)            MI_FORWARD2(mi_realloc,p,size)\n  void  __libc_free(void* p)                            MI_FORWARD0(mi_free,p)\n  void  __libc_cfree(void* p)                           MI_FORWARD0(mi_free,p)\n\n  void* __libc_valloc(size_t size)                      { return mi_valloc(size); }\n  void* __libc_pvalloc(size_t size)                     { return mi_pvalloc(size); }\n  void* __libc_memalign(size_t alignment, size_t size)  { return mi_memalign(alignment,size); }\n  int   __posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p,alignment,size); }\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__)\n#pragma GCC visibility pop\n#endif\n\n#endif // MI_MALLOC_OVERRIDE\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/alloc-posix.c",
      "sha256": "98d0eb877d7b9cdf7e9f857aaf3c739b69f746b91221e0e427e82bdd7cec90b3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2021, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// ------------------------------------------------------------------------\n// mi prefixed publi definitions of various Posix, Unix, and C++ functions\n// for convenience and used when overriding these functions.\n// ------------------------------------------------------------------------\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n\n// ------------------------------------------------------\n// Posix & Unix functions definitions\n// ------------------------------------------------------\n\n#include <errno.h>\n#include <string.h>  // memset\n#include <stdlib.h>  // getenv\n\n#ifdef _MSC_VER\n#pragma warning(disable:4996)  // getenv _wgetenv\n#endif\n\n#ifndef EINVAL\n#define EINVAL 22\n#endif\n#ifndef ENOMEM\n#define ENOMEM 12\n#endif\n\n\nmi_decl_nodiscard size_t mi_malloc_size(const void* p) mi_attr_noexcept {\n  // if (!mi_is_in_heap_region(p)) return 0;\n  return mi_usable_size(p);\n}\n\nmi_decl_nodiscard size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept {\n  // if (!mi_is_in_heap_region(p)) return 0;\n  return mi_usable_size(p);\n}\n\nmi_decl_nodiscard size_t mi_malloc_good_size(size_t size) mi_attr_noexcept {\n  return mi_good_size(size);\n}\n\nvoid mi_cfree(void* p) mi_attr_noexcept {\n  if (mi_is_in_heap_region(p)) {\n    mi_free(p);\n  }\n}\n\nint mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept {\n  // Note: The spec dictates we should not modify `*p` on an error. (issue#27)\n  // <http://man7.org/linux/man-pages/man3/posix_memalign.3.html>\n  if (p == NULL) return EINVAL;\n  if ((alignment % sizeof(void*)) != 0) return EINVAL;                 // natural alignment\n  // it is also required that alignment is a power of 2 and > 0; this is checked in `mi_malloc_aligned`\n  if (alignment==0 || !_mi_is_power_of_two(alignment)) return EINVAL;  // not a power of 2\n  void* q = mi_malloc_aligned(size, alignment);\n  if (q==NULL && size != 0) return ENOMEM;\n  mi_assert_internal(_mi_is_aligned(q,alignment));\n  *p = q;\n  return 0;\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept {\n  void* p = mi_malloc_aligned(size, alignment);\n  mi_assert_internal(_mi_is_aligned(p,alignment));\n  return p;\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept {\n  return mi_memalign( _mi_os_page_size(), size );\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept {\n  size_t psize = _mi_os_page_size();\n  if (size >= SIZE_MAX - psize) return NULL; // overflow\n  size_t asize = _mi_align_up(size, psize);\n  return mi_malloc_aligned(asize, psize);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept {\n  // C11 requires the size to be an integral multiple of the alignment, see <https://en.cppreference.com/w/c/memory/aligned_alloc>.\n  // unfortunately, it turns out quite some programs pass a size that is not an integral multiple so skip this check..\n  /* if mi_unlikely((size & (alignment - 1)) != 0) { // C11 requires alignment>0 && integral multiple, see <https://en.cppreference.com/w/c/memory/aligned_alloc>\n      #if MI_DEBUG > 0\n      _mi_error_message(EOVERFLOW, \"(mi_)aligned_alloc requires the size to be an integral multiple of the alignment (size %zu, alignment %zu)\\n\", size, alignment);\n      #endif\n      return NULL;\n    }\n  */\n  // C11 also requires alignment to be a power-of-two (and > 0) which is checked in mi_malloc_aligned\n  void* p = mi_malloc_aligned(size, alignment);\n  mi_assert_internal(_mi_is_aligned(p,alignment));\n  return p;\n}\n\nmi_decl_nodiscard void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept {  // BSD <https://man.freebsd.org/cgi/man.cgi?query=reallocarray>\n  size_t total;\n  if mi_unlikely(mi_count_size_overflow(count, size, &total)) {\n    errno = EOVERFLOW;\n    return NULL;\n  }\n  void* newp = mi_realloc(p,total);\n  if (newp==NULL) { errno = ENOMEM; }\n  return newp;\n}\n\nmi_decl_nodiscard int mi_reallocarr( void* ptrp, size_t count, size_t size ) mi_attr_noexcept { // NetBSD <https://man.netbsd.org/reallocarr.3>\n  mi_assert(size != 0);\n  mi_assert(ptrp != NULL);\n  if (ptrp == NULL || size == 0) {\n    return (errno = EINVAL);\n  }\n  size_t total;\n  if mi_unlikely(mi_count_size_overflow(count, size, &total)) {\n    return (errno = EOVERFLOW);\n  }\n  void** op = (void**)ptrp;\n  if (total == 0) {\n    free(*op);\n    *op = NULL;\n    return 0;\n  }\n  else {\n    void* newp = mi_realloc(*op,total);\n    if (newp == NULL) { return (errno = ENOMEM); }\n    *op = newp;\n    return 0;\n  }\n}\n\nvoid* mi__expand(void* p, size_t newsize) mi_attr_noexcept {  // Microsoft\n  void* res = mi_expand(p, newsize);\n  if (res == NULL) { errno = ENOMEM; }\n  return res;\n}\n\nmi_decl_nodiscard mi_decl_restrict wchar_t* mi_wcsdup(const wchar_t* s) mi_attr_noexcept {\n  if (s==NULL) return NULL;\n  size_t wlen;\n  for(wlen = 0; s[wlen] != 0 && wlen < PTRDIFF_MAX; wlen++) { }  // prevent overflow on wlen+1\n  size_t size; \n  if (mi_mul_overflow(wlen+1, sizeof(wchar_t), &size) || size > PTRDIFF_MAX) return NULL;\n  wchar_t* p = (wchar_t*)mi_malloc(size);\n  if (p != NULL) {\n    _mi_memcpy(p,s,size);\n  }\n  return p;\n}\n\nmi_decl_nodiscard mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s)  mi_attr_noexcept {\n  return (unsigned char*)mi_strdup((const char*)s);\n}\n\nint mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept {\n  if (size != NULL) *size = 0;\n  if (buf==NULL || name==NULL) return EINVAL;\n  char* p = getenv(name);\n  if (p==NULL) {\n    *buf = NULL;\n  }\n  else {\n    *buf = mi_strdup(p);\n    if (*buf==NULL) return ENOMEM;\n    if (size != NULL) { *size = _mi_strlen(p) + 1; }    // cannot overflow as mi_strdup is limited to PTRDIFF_MAX\n  }\n  return 0;\n}\n\nint mi_wdupenv_s(wchar_t** buf, size_t* size, const wchar_t* name) mi_attr_noexcept {\n  if (size != NULL) *size = 0;\n  if (buf==NULL || name==NULL) return EINVAL;  \n#if !defined(_WIN32) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP))\n  // not supported\n  *buf = NULL;\n  return EINVAL;\n#else\n  wchar_t* p = (wchar_t*)_wgetenv(name);\n  if (p==NULL) {\n    *buf = NULL;\n  }\n  else {\n    *buf = mi_wcsdup(p);\n    if (*buf==NULL) return ENOMEM;\n    if (size != NULL) { *size = wcslen(p) + 1; }  // cannot overflow as wcsdup is limited to PTRDIFF_MAX\n  }\n  return 0;\n#endif\n}\n\nmi_decl_nodiscard void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { // Microsoft\n  return mi_recalloc_aligned_at(p, newcount, size, alignment, offset);\n}\n\nmi_decl_nodiscard void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { // Microsoft\n  return mi_recalloc_aligned(p, newcount, size, alignment);\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/alloc.c",
      "sha256": "a92d58e47220e5b6d138b83d92498771be4195ee59136a134e4461f6f726b9b8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "\n/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#ifndef _DEFAULT_SOURCE\n#define _DEFAULT_SOURCE   // for realpath() on Linux\n#endif\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"   // _mi_prim_thread_id()\n\n#include <string.h>      // memset, strlen (for mi_strdup)\n#include <stdlib.h>      // malloc, abort\n\n#define MI_IN_ALLOC_C\n#include \"alloc-override.c\"\n#include \"free.c\"\n#undef MI_IN_ALLOC_C\n\n// ------------------------------------------------------\n// Allocation\n// ------------------------------------------------------\n\n// Fast allocation in a page: just pop from the free list.\n// Fall back to generic allocation only if the list is empty.\n// Note: in release mode the (inlined) routine is about 7 instructions with a single test.\nstatic mi_decl_forceinline void* mi_page_malloc_zero(mi_theap_t* theap, mi_page_t* page, size_t size, bool zero, size_t* usable) mi_attr_noexcept\n{\n  if (page->block_size != 0) { // not the empty theap\n    mi_assert_internal(mi_page_block_size(page) >= size);\n    mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n    mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);\n  }\n\n  // check the free list\n  mi_block_t* const block = page->free;\n  if mi_unlikely(block == NULL) {\n    return _mi_malloc_generic(theap, size, (zero ? 1 : 0), usable);\n  }\n  mi_assert_internal(block != NULL && _mi_ptr_page(block) == page);\n  if (usable != NULL) { *usable = mi_page_usable_block_size(page); };\n\n  // pop from the free list\n  page->free = mi_block_next(page, block);\n  page->used++;\n  mi_assert_internal(page->free == NULL || _mi_ptr_page(page->free) == page);\n  mi_assert_internal(page->block_size < MI_MAX_ALIGN_SIZE || _mi_is_aligned(block, MI_MAX_ALIGN_SIZE));\n\n  #if MI_DEBUG>3\n  if (page->free_is_zero && size > sizeof(*block)) {\n    mi_assert_expensive(mi_mem_is_zero(block+1,size - sizeof(*block)));\n  }\n  #endif\n\n  // allow use of the block internally\n  // note: when tracking we need to avoid ever touching the MI_PADDING since\n  // that is tracked by valgrind etc. as non-accessible (through the red-zone, see `mimalloc/track.h`)\n  const size_t bsize = mi_page_usable_block_size(page);\n  mi_track_mem_undefined(block, bsize);\n\n  #if (MI_STAT>0)\n  if (bsize <= MI_LARGE_MAX_OBJ_SIZE) {\n    mi_theap_stat_increase(theap, malloc_normal, bsize);\n    #if (MI_STAT>1)\n    mi_theap_stat_counter_increase(theap, malloc_normal_count, 1);\n    const size_t bin = _mi_bin(bsize);\n    mi_theap_stat_increase(theap, malloc_bins[bin], 1);\n    mi_theap_stat_increase(theap, malloc_requested, size - MI_PADDING_SIZE);\n    #endif\n  }\n  #endif\n\n  // zero the block? note: we need to zero the full block size (issue #63)\n  if mi_likely(!zero) {\n    // #if MI_SECURE\n    block->next = 0;  // don't leak internal data\n    // #endif\n    #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN\n      if (!mi_page_is_huge(page)) { memset(block, MI_DEBUG_UNINIT, bsize); }\n    #endif    \n  }\n  else {\n    if (!page->free_is_zero) {\n      _mi_memzero_aligned(block, bsize);\n    }\n    else {\n      block->next = 0;\n      mi_track_mem_defined(block, bsize);\n    }    \n  }\n\n  #if MI_PADDING // && !MI_TRACK_ENABLED\n    mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + bsize);\n    ptrdiff_t delta = ((uint8_t*)padding - (uint8_t*)block - (size - MI_PADDING_SIZE));\n    #if (MI_DEBUG>=2)\n    mi_assert_internal(delta >= 0 && bsize >= (size - MI_PADDING_SIZE + delta));\n    #endif\n    mi_track_mem_defined(padding,sizeof(mi_padding_t));  // note: re-enable since mi_page_usable_block_size may set noaccess\n    padding->canary = mi_ptr_encode_canary(page,block,page->keys);\n    padding->delta  = (uint32_t)(delta);\n    #if MI_PADDING_CHECK\n    if (!mi_page_is_huge(page)) {\n      uint8_t* fill = (uint8_t*)padding - delta;\n      const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // set at most N initial padding bytes\n      for (size_t i = 0; i < maxpad; i++) { fill[i] = MI_DEBUG_PADDING; }\n    }\n    #endif\n  #endif\n\n  return block;\n}\n\n// extra entries for improved efficiency in `alloc-aligned.c` (and in `page.c:mi_malloc_generic`.\nextern void* _mi_page_malloc_zero(mi_theap_t* theap, mi_page_t* page, size_t size, bool zero) mi_attr_noexcept {\n  return mi_page_malloc_zero(theap, page, size, zero, NULL);\n}\n\n#if MI_GUARDED\nmi_decl_restrict void* _mi_theap_malloc_guarded(mi_theap_t* theap, size_t size, bool zero) mi_attr_noexcept;\n#endif\n\n// main allocation primitives for small and generic allocation\n\n// internal small size allocation\nstatic mi_decl_forceinline mi_decl_restrict void* mi_theap_malloc_small_zero_nonnull(mi_theap_t* theap, size_t size, bool zero, size_t* usable) mi_attr_noexcept\n{\n  mi_assert(theap != NULL);\n  mi_assert(size <= MI_SMALL_SIZE_MAX);\n  #if MI_DEBUG\n  const uintptr_t tid = _mi_thread_id();\n  mi_assert(theap->tld->thread_id == 0 || theap->tld->thread_id == tid); // theaps are thread local\n  #endif\n  #if (MI_PADDING || MI_GUARDED)\n  if mi_unlikely(size == 0) { size = sizeof(void*); }\n  #endif\n  #if MI_GUARDED\n  if mi_unlikely(mi_theap_malloc_use_guarded(theap,size)) {\n    return _mi_theap_malloc_guarded(theap, size, zero);\n  }\n  #endif\n\n  // get page in constant time, and allocate from it\n  mi_page_t* page = _mi_theap_get_free_small_page(theap, size + MI_PADDING_SIZE);\n  void* const p = mi_page_malloc_zero(theap, page, size + MI_PADDING_SIZE, zero, usable);\n  mi_track_malloc(p,size,zero);\n\n  #if MI_DEBUG>3\n  if (p != NULL && zero) {\n    mi_assert_expensive(mi_mem_is_zero(p, size));\n  }\n  #endif\n  return p;\n}\n\n// internal generic allocation\nstatic mi_decl_forceinline void* mi_theap_malloc_generic(mi_theap_t* theap, size_t size, bool zero, size_t huge_alignment, size_t* usable) mi_attr_noexcept\n{\n  #if MI_GUARDED\n  #if MI_THEAP_INITASNULL\n  if (theap!=NULL)\n  #endif\n  if (huge_alignment==0 && mi_theap_malloc_use_guarded(theap, size)) {\n    return _mi_theap_malloc_guarded(theap, size, zero);\n  }\n  #endif\n  #if !MI_THEAP_INITASNULL\n  mi_assert(theap!=NULL);\n  #endif\n  mi_assert(theap==NULL || theap->tld->thread_id == 0 || theap->tld->thread_id == _mi_thread_id());   // theaps are thread local\n  mi_assert((huge_alignment & 1)==0);\n  void* const p = _mi_malloc_generic(theap, size + MI_PADDING_SIZE, (zero ? 1 : 0) | huge_alignment, usable);  // note: size can overflow but it is detected in malloc_generic\n  mi_track_malloc(p, size, zero);\n\n  #if MI_DEBUG>3\n  if (p != NULL && zero) {\n    mi_assert_expensive(mi_mem_is_zero(p, size));\n  }\n  #endif\n  return p;\n}\n\n// internal small allocation\nstatic mi_decl_forceinline mi_decl_restrict void* mi_theap_malloc_small_zero(mi_theap_t* theap, size_t size, bool zero, size_t* usable) mi_attr_noexcept {\n  #if MI_THEAP_INITASNULL\n  if (theap!=NULL) {\n    return mi_theap_malloc_small_zero_nonnull(theap, size, zero, usable);\n  }\n  else {\n    return mi_theap_malloc_generic(theap, size, zero, 0, usable); // tailcall\n  }\n  #else\n  return mi_theap_malloc_small_zero_nonnull(theap, size, zero, usable);\n  #endif\n}\n\n\n// allocate a small block\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_theap_malloc_small(mi_theap_t* theap, size_t size) mi_attr_noexcept {\n  return mi_theap_malloc_small_zero(theap, size, false, NULL);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept {\n  return mi_theap_malloc_small(_mi_theap_default(), size);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept {\n  return mi_theap_malloc_small_zero_nonnull(_mi_heap_theap(heap), size, false, NULL);\n}\n\n// The main internal allocation functions\nstatic mi_decl_forceinline void* mi_theap_malloc_zero_nonnull(mi_theap_t* theap, size_t size, bool zero, size_t huge_alignment, size_t* usable) mi_attr_noexcept {\n  // fast path for small objects\n  if mi_likely(size <= MI_SMALL_SIZE_MAX) {\n    mi_assert_internal(huge_alignment == 0);\n    return mi_theap_malloc_small_zero_nonnull(theap, size, zero, usable);\n  }\n  else {\n    return mi_theap_malloc_generic(theap, size, zero, huge_alignment, usable);\n  }\n}\n\nextern mi_decl_forceinline void* _mi_theap_malloc_zero_ex(mi_theap_t* theap, size_t size, bool zero, size_t huge_alignment, size_t* usable) mi_attr_noexcept {\n  // fast path for small objects\n  #if MI_THEAP_INITASNULL\n  if mi_likely(theap!=NULL && size <= MI_SMALL_SIZE_MAX)\n  #else\n  if mi_likely(size <= MI_SMALL_SIZE_MAX)\n  #endif\n  {\n    mi_assert_internal(huge_alignment == 0);\n    return mi_theap_malloc_small_zero_nonnull(theap, size, zero, usable);\n  }\n  else {\n    return mi_theap_malloc_generic(theap, size, zero, huge_alignment, usable);\n  }\n}\n\nvoid* _mi_theap_malloc_zero(mi_theap_t* theap, size_t size, bool zero, size_t* usable) mi_attr_noexcept {\n  return _mi_theap_malloc_zero_ex(theap, size, zero, 0, usable);\n}\n\n\n// Main allocation functions\n\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_theap_malloc(mi_theap_t* theap, size_t size) mi_attr_noexcept {\n  return _mi_theap_malloc_zero(theap, size, false, NULL);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept {\n   return mi_theap_malloc(_mi_theap_default(), size);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept {\n  return mi_theap_malloc_zero_nonnull(_mi_heap_theap(heap), size, false, 0, NULL);\n}\n\n\n// zero initialized small block\nmi_decl_nodiscard mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept {\n  return mi_theap_malloc_small_zero(_mi_theap_default(), size, true, NULL);\n}\n\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_theap_zalloc_small(mi_theap_t* theap, size_t size) mi_attr_noexcept {\n  return mi_theap_malloc_small_zero(theap, size, true, NULL);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_zalloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept {\n  return mi_theap_malloc_small_zero_nonnull(_mi_heap_theap(heap), size, true, NULL);\n}\n\n\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_theap_zalloc(mi_theap_t* theap, size_t size) mi_attr_noexcept {\n  return _mi_theap_malloc_zero(theap, size, true, NULL);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept {\n  return _mi_theap_malloc_zero(_mi_theap_default(), size, true, NULL);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept {\n  return mi_theap_malloc_zero_nonnull(_mi_heap_theap(heap), size, true, 0, NULL);\n}\n\nmi_decl_nodiscard extern inline mi_decl_restrict void* mi_theap_calloc(mi_theap_t* theap, size_t count, size_t size) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count,size,&total)) return NULL;\n  return mi_theap_zalloc(theap,total);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept {\n  return mi_theap_calloc(_mi_theap_default(),count,size);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count, size, &total)) return NULL;\n  return mi_heap_zalloc(heap, total);\n}\n\n// Return usable size\nmi_decl_nodiscard mi_decl_restrict void* mi_umalloc_small(size_t size, size_t* usable) mi_attr_noexcept {\n  return mi_theap_malloc_small_zero(_mi_theap_default(), size, false, usable);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_theap_umalloc(mi_theap_t* theap, size_t size, size_t* usable) mi_attr_noexcept {\n  return _mi_theap_malloc_zero_ex(theap, size, false, 0, usable);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_umalloc(size_t size, size_t* usable) mi_attr_noexcept {\n  return mi_theap_umalloc(_mi_theap_default(), size, usable);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_uzalloc(size_t size, size_t* usable) mi_attr_noexcept {\n  return _mi_theap_malloc_zero_ex(_mi_theap_default(), size, true, 0, usable);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_ucalloc(size_t count, size_t size, size_t* usable) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count,size,&total)) return NULL;\n  return mi_uzalloc(total, usable);\n}\n\n// Uninitialized `calloc`\nstatic mi_decl_restrict void* mi_theap_mallocn(mi_theap_t* theap, size_t count, size_t size) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count, size, &total)) return NULL;\n  return mi_theap_malloc(theap, total);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept {\n  return mi_theap_mallocn(_mi_theap_default(),count,size);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count, size, &total)) return NULL;\n  return mi_heap_malloc(heap, total);\n}\n\n\n// Expand (or shrink) in place (or fail)\nvoid* mi_expand(void* p, size_t newsize) mi_attr_noexcept {\n  #if MI_PADDING\n  // we do not shrink/expand with padding enabled\n  MI_UNUSED(p); MI_UNUSED(newsize);\n  return NULL;\n  #else\n  if (p == NULL) return NULL;\n  const mi_page_t* const page = mi_validate_ptr_page(p,\"mi_expand\");\n  const size_t size = _mi_usable_size(p,page);\n  if (newsize > size) return NULL;\n  return p; // it fits\n  #endif\n}\n\nvoid* _mi_theap_realloc_zero(mi_theap_t* theap, void* p, size_t newsize, bool zero, size_t* usable_pre, size_t* usable_post) mi_attr_noexcept {\n  // if p == NULL then behave as malloc.\n  // else if size == 0 then reallocate to a zero-sized block (and don't return NULL, just as mi_malloc(0)).\n  // (this means that returning NULL always indicates an error, and `p` will not have been freed in that case.)\n  const mi_page_t* page;\n  size_t size;\n  if (p==NULL) {\n    page = NULL;\n    size = 0;\n    if (usable_pre!=NULL) { *usable_pre = 0; }\n  }\n  else {\n    page = mi_validate_ptr_page(p,\"mi_realloc\");\n    size = _mi_usable_size(p,page);\n    if (usable_pre!=NULL) { *usable_pre = mi_page_usable_block_size(page); }\n  }\n  if mi_unlikely(newsize<=size && newsize>=(size/2) && newsize>0  // note: newsize must be > 0 or otherwise we return NULL for realloc(NULL,0)\n                  && mi_page_heap(page)==_mi_theap_heap(theap))             // and within the same heap\n  {\n    mi_assert_internal(p!=NULL);\n    // todo: do not track as the usable size is still the same in the free; adjust potential padding?\n    // mi_track_resize(p,size,newsize)\n    // if (newsize < size) { mi_track_mem_noaccess((uint8_t*)p + newsize, size - newsize); }\n    if (usable_post!=NULL) { *usable_post = mi_page_usable_block_size(page); }\n    return p;  // reallocation still fits and not more than 50% waste\n  }\n  void* newp = mi_theap_umalloc(theap,newsize,usable_post);\n  if mi_likely(newp != NULL) {\n    if (zero && newsize > size) {\n      // also set last word in the previous allocation to zero to ensure any padding is zero-initialized\n      const size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0);\n      _mi_memzero((uint8_t*)newp + start, newsize - start);\n    }\n    else if (newsize == 0) {\n      ((uint8_t*)newp)[0] = 0; // work around for applications that expect zero-reallocation to be zero initialized (issue #725)\n    }\n    if mi_likely(p != NULL) {\n      const size_t copysize = (newsize > size ? size : newsize);\n      mi_track_mem_defined(p,copysize);  // _mi_useable_size may be too large for byte precise memory tracking..\n      _mi_memcpy(newp, p, copysize);\n      mi_free(p); // only free the original pointer if successful  // todo: optimize since page is known?\n    }\n  }\n  return newp;\n}\n\nmi_decl_nodiscard void* mi_theap_realloc(mi_theap_t* theap, void* p, size_t newsize) mi_attr_noexcept {\n  return _mi_theap_realloc_zero(theap, p, newsize, false, NULL, NULL);\n}\n\nstatic void* mi_theap_reallocn(mi_theap_t* theap, void* p, size_t count, size_t size) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count, size, &total)) return NULL;\n  return mi_theap_realloc(theap, p, total);\n}\n\n\n// Reallocate but free `p` on errors\nstatic void* mi_theap_reallocf(mi_theap_t* theap, void* p, size_t newsize) mi_attr_noexcept {\n  void* newp = mi_theap_realloc(theap, p, newsize);\n  if (newp==NULL && p!=NULL) mi_free(p);\n  return newp;\n}\n\nstatic void* mi_theap_rezalloc(mi_theap_t* theap, void* p, size_t newsize) mi_attr_noexcept {\n  return _mi_theap_realloc_zero(theap, p, newsize, true, NULL, NULL);\n}\n\nstatic void* mi_theap_recalloc(mi_theap_t* theap, void* p, size_t count, size_t size) mi_attr_noexcept {\n  size_t total;\n  if (mi_count_size_overflow(count, size, &total)) return NULL;\n  return mi_theap_rezalloc(theap, p, total);\n}\n\n\nmi_decl_nodiscard void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept {\n  return mi_theap_realloc(_mi_theap_default(),p,newsize);\n}\n\nmi_decl_nodiscard void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept {\n  return mi_theap_reallocn(_mi_theap_default(),p,count,size);\n}\n\nmi_decl_nodiscard void* mi_urealloc(void* p, size_t newsize, size_t* usable_pre, size_t* usable_post) mi_attr_noexcept {\n  return _mi_theap_realloc_zero(_mi_theap_default(),p,newsize, false, usable_pre, usable_post);\n}\n\n// Reallocate but free `p` on errors\nmi_decl_nodiscard void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept {\n  return mi_theap_reallocf(_mi_theap_default(),p,newsize);\n}\n\nmi_decl_nodiscard void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept {\n  return mi_theap_rezalloc(_mi_theap_default(), p, newsize);\n}\n\nmi_decl_nodiscard void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept {\n  return mi_theap_recalloc(_mi_theap_default(), p, count, size);\n}\n\n\nmi_decl_nodiscard void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {\n  return mi_theap_realloc(_mi_heap_theap(heap), p, newsize);\n}\n\nmi_decl_nodiscard void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept {\n  return mi_theap_reallocn(_mi_heap_theap(heap), p, count, size);\n}\n\n// Reallocate but free `p` on errors\nmi_decl_nodiscard void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {\n  return mi_theap_reallocf(_mi_heap_theap(heap), p, newsize);\n}\n\nmi_decl_nodiscard void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {\n  return mi_theap_rezalloc(_mi_heap_theap(heap), p, newsize);\n}\n\nmi_decl_nodiscard void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept {\n  return mi_theap_recalloc(_mi_heap_theap(heap), p, count, size);\n}\n\n\n\n// ------------------------------------------------------\n// strdup, strndup, and realpath\n// ------------------------------------------------------\n\n// `strdup` using mi_malloc\nmi_decl_nodiscard static mi_decl_restrict char* mi_theap_strdup(mi_theap_t* theap, const char* s) mi_attr_noexcept {\n  if (s == NULL) return NULL;\n  size_t len = _mi_strlen(s);\n  if (len > MI_MAX_ALLOC_SIZE - 1) return NULL;  // prevent overflow on len+1\n  char* t = (char*)mi_theap_malloc(theap,len+1);\n  if (t == NULL) return NULL;\n  _mi_memcpy(t, s, len);\n  t[len] = 0;\n  return t;\n}\n\nmi_decl_nodiscard mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept {\n  return mi_theap_strdup(_mi_theap_default(), s);\n}\n\nmi_decl_nodiscard mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept {\n  return mi_theap_strdup(_mi_heap_theap(heap), s);\n}\n\n// `strndup` using mi_malloc\nmi_decl_nodiscard static mi_decl_restrict char* mi_theap_strndup(mi_theap_t* theap, const char* s, size_t n) mi_attr_noexcept {\n  if (s == NULL) return NULL;\n  const size_t len = _mi_strnlen(s,n);  // len <= n\n  if (len > MI_MAX_ALLOC_SIZE - 1) return NULL;  // prevent overflow on len+1\n  char* t = (char*)mi_theap_malloc(theap, len+1);\n  if (t == NULL) return NULL;\n  _mi_memcpy(t, s, len);\n  t[len] = 0;\n  return t;\n}\n\nmi_decl_nodiscard mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept {\n  return mi_theap_strndup(_mi_theap_default(),s,n);\n}\n\nmi_decl_nodiscard mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept {\n  return mi_theap_strndup(_mi_heap_theap(heap), s, n);\n}\n\n#ifndef __wasi__\n// `realpath` using mi_malloc\n#ifdef _WIN32\n#ifndef PATH_MAX\n#define PATH_MAX MAX_PATH\n#endif\n\nmi_decl_nodiscard static mi_decl_restrict char* mi_theap_realpath(mi_theap_t* theap, const char* fname, char* resolved_name) mi_attr_noexcept {\n  // todo: use GetFullPathNameW to allow longer file names\n  char buf[PATH_MAX];\n  DWORD res = GetFullPathNameA(fname, PATH_MAX, (resolved_name == NULL ? buf : resolved_name), NULL);\n  if (res == 0) {\n    errno = GetLastError(); return NULL;\n  }\n  else if (res > PATH_MAX) {\n    errno = EINVAL; return NULL;\n  }\n  else if (resolved_name != NULL) {\n    return resolved_name;\n  }\n  else {\n    return mi_theap_strndup(theap, buf, PATH_MAX);\n  }\n}\n\n#else\n\n#include <unistd.h>  // pathconf\n\nstatic size_t mi_path_max(void) {\n  static _Atomic(size_t) path_max = 0;\n  size_t pmax = mi_atomic_load_acquire(&path_max);\n  if (pmax == 0) {\n    long m = 0;\n    #ifdef _PC_PATH_MAX\n    m = pathconf(\"/\",_PC_PATH_MAX);\n    #endif\n    if (m <= 0) pmax = 4096;      // guess\n    else if (m < 256) pmax = 256; // at least 256\n    else if (m > 64*1024) pmax = 64*1024;  // at most 64 KiB\n    else pmax = m;\n    size_t expected = 0;\n    mi_atomic_cas_strong_acq_rel(&path_max, &expected, pmax);\n  }\n  return pmax;\n}\n\nchar* mi_theap_realpath(mi_theap_t* theap, const char* fname, char* resolved_name) mi_attr_noexcept {\n  if (resolved_name != NULL) {\n    return realpath(fname,resolved_name);\n  }\n  else {\n  /*\n    char* rname = realpath(fname, NULL);\n    if (rname == NULL) return NULL;\n    char* result = mi_heap_strdup(heap, rname);\n    mi_cfree(rname);  // note: may leak the original pointer if allocated internally with the system allocator \n    // note: with ASAN realpath is intercepted and mi_cfree may leak the returned pointer :-(\n    return result;  \n  */\n    const size_t n  = mi_path_max();\n    char* const buf = (char*)mi_zalloc(n+1);\n    if (buf == NULL) {\n      errno = ENOMEM;\n      return NULL;\n    }\n    char* rname  = realpath(fname,buf);\n    char* result = mi_theap_strndup(theap,rname,n); // ok if `rname==NULL`\n    mi_free(buf);\n    return result;\n  }\n}\n#endif\n\nmi_decl_nodiscard mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept {\n  return mi_theap_realpath(_mi_theap_default(),fname,resolved_name);\n}\n\nmi_decl_nodiscard mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept {\n  return mi_theap_realpath(_mi_heap_theap(heap), fname, resolved_name);\n}\n#endif\n\n/*-------------------------------------------------------\nC++ new and new_aligned\nThe standard requires calling into `get_new_handler` and\nthrowing the bad_alloc exception on failure. If we compile\nwith a C++ compiler we can implement this precisely. If we\nuse a C compiler we cannot throw a `bad_alloc` exception\nbut we call `exit` instead (i.e. not returning).\n-------------------------------------------------------*/\n\n#ifdef __cplusplus\n#include <new>\nstatic bool mi_try_new_handler(bool nothrow) {\n  #if defined(_MSC_VER) || (__cplusplus >= 201103L)\n    std::new_handler h = std::get_new_handler();\n  #else\n    std::new_handler h = std::set_new_handler();\n    std::set_new_handler(h);\n  #endif\n  if (h==NULL) {\n    _mi_error_message(ENOMEM, \"out of memory in 'new'\");\n    #if defined(_CPPUNWIND) || defined(__cpp_exceptions)  // exceptions are not always enabled\n    if (!nothrow) {\n      throw std::bad_alloc();\n    }\n    #else\n    MI_UNUSED(nothrow);\n    #endif\n    return false;\n  }\n  else {\n    h();\n    return true;\n  }\n}\n#else\ntypedef void (*std_new_handler_t)(void);\n\n#if (defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER)))  // exclude clang-cl, see issue #631\nstd_new_handler_t __attribute__((weak)) _ZSt15get_new_handlerv(void) {\n  return NULL;\n}\nstatic std_new_handler_t mi_get_new_handler(void) {\n  return _ZSt15get_new_handlerv();\n}\n#else\n// note: on windows we could dynamically link to `?get_new_handler@std@@YAP6AXXZXZ`.\nstatic std_new_handler_t mi_get_new_handler(void) {\n  return NULL;\n}\n#endif\n\nstatic bool mi_try_new_handler(bool nothrow) {\n  std_new_handler_t h = mi_get_new_handler();\n  if (h==NULL) {\n    _mi_error_message(ENOMEM, \"out of memory in 'new'\");\n    if (!nothrow) {\n      abort();  // cannot throw in plain C, use abort\n    }\n    return false;\n  }\n  else {\n    h();\n    return true;\n  }\n}\n#endif\n\nstatic mi_decl_noinline void* mi_theap_try_new(mi_theap_t* theap, size_t size, bool nothrow ) {\n  void* p = NULL;\n  while(p == NULL && mi_try_new_handler(nothrow)) {\n    p = mi_theap_malloc(theap,size);\n  }\n  return p;\n}\n\nstatic mi_decl_noinline void* mi_try_new(size_t size, bool nothrow) {\n  return mi_theap_try_new(_mi_theap_default(), size, nothrow);\n}\n\nstatic mi_decl_noinline void* mi_heap_try_new(mi_heap_t* heap, size_t size, bool nothrow) {\n  return mi_theap_try_new(_mi_heap_theap(heap), size, nothrow);\n}\n\n\nmi_decl_nodiscard static mi_decl_restrict void* mi_theap_alloc_new(mi_theap_t* theap, size_t size) {\n  void* p = mi_theap_malloc(theap,size);\n  if mi_unlikely(p == NULL) return mi_theap_try_new(theap, size, false);\n  return p;\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_new(size_t size) {\n  return mi_theap_alloc_new(_mi_theap_default(), size);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_alloc_new(mi_heap_t* heap, size_t size) {\n  void* p = mi_heap_malloc(heap, size);\n  if mi_unlikely(p == NULL) return mi_heap_try_new(heap, size, false);\n  return p;\n}\n\n\nmi_decl_nodiscard static mi_decl_restrict void* mi_theap_alloc_new_n(mi_theap_t* theap, size_t count, size_t size) {\n  size_t total;\n  if mi_unlikely(mi_count_size_overflow(count, size, &total)) {\n    mi_try_new_handler(false);  // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc\n    return NULL;\n  }\n  else {\n    return mi_theap_alloc_new(theap,total);\n  }\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_new_n(size_t count, size_t size) {\n  return mi_theap_alloc_new_n(_mi_theap_default(), count, size);\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_heap_alloc_new_n(mi_heap_t* heap, size_t count, size_t size) {\n  return mi_theap_alloc_new_n(_mi_heap_theap(heap), count, size);\n}\n\n\nmi_decl_nodiscard mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept {\n  void* p = mi_malloc(size);\n  if mi_unlikely(p == NULL) return mi_try_new(size, true);\n  return p;\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) {\n  void* p;\n  do {\n    p = mi_malloc_aligned(size, alignment);\n  }\n  while(p == NULL && mi_try_new_handler(false));\n  return p;\n}\n\nmi_decl_nodiscard mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept {\n  void* p;\n  do {\n    p = mi_malloc_aligned(size, alignment);\n  }\n  while(p == NULL && mi_try_new_handler(true));\n  return p;\n}\n\nmi_decl_nodiscard void* mi_new_realloc(void* p, size_t newsize) {\n  void* q;\n  do {\n    q = mi_realloc(p, newsize);\n  } while (q == NULL && mi_try_new_handler(false));\n  return q;\n}\n\nmi_decl_nodiscard void* mi_new_reallocn(void* p, size_t newcount, size_t size) {\n  size_t total;\n  if mi_unlikely(mi_count_size_overflow(newcount, size, &total)) {\n    mi_try_new_handler(false);  // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc\n    return NULL;\n  }\n  else {\n    return mi_new_realloc(p, total);\n  }\n}\n\n#if MI_GUARDED\n// We always allocate a guarded allocation at an offset (`mi_page_has_interior_pointers` will be true).\n// We then set the first word of the block to `0` for regular offset aligned allocations (in `alloc-aligned.c`)\n// and the first word to `~0` for guarded allocations to have a correct `mi_usable_size`\n\nstatic void* mi_block_ptr_set_guarded(mi_block_t* block, size_t obj_size) {\n  // TODO: we can still make padding work by moving it out of the guard page area\n  mi_page_t* const page = _mi_ptr_page(block);\n  mi_page_set_has_interior_pointers(page, true);\n  block->next = MI_BLOCK_TAG_GUARDED;\n\n  // set guard page at the end of the block\n  const size_t block_size = mi_page_block_size(page);  // must use `block_size` to match `mi_free_local`\n  const size_t os_page_size = _mi_os_page_size();\n  mi_assert_internal(block_size >= obj_size + os_page_size + sizeof(mi_block_t));\n  if (block_size < obj_size + os_page_size + sizeof(mi_block_t)) {\n    // should never happen\n    mi_free(block);\n    return NULL;\n  }\n  uint8_t* guard_page = (uint8_t*)block + block_size - os_page_size;\n  // note: the alignment of the guard page relies on blocks being os_page_size aligned which\n  // is ensured in `mi_arena_page_alloc_fresh`.  \n  mi_assert_internal(_mi_is_aligned(block, os_page_size));\n  mi_assert_internal(_mi_is_aligned(guard_page, os_page_size));\n  if (!page->memid.is_pinned && _mi_is_aligned(guard_page, os_page_size)) {\n    const bool ok = _mi_os_protect(guard_page, os_page_size);\n    if mi_unlikely(!ok) {\n      _mi_warning_message(\"failed to set a guard page behind an object (object %p of size %zu)\\n\", block, block_size);\n    }\n  }\n  else {\n    _mi_warning_message(\"unable to set a guard page behind an object due to pinned memory (large OS pages?) (object %p of size %zu)\\n\", block, block_size);\n  }\n\n  // align pointer just in front of the guard page\n  size_t offset = block_size - os_page_size - obj_size;\n  mi_assert_internal(offset > sizeof(mi_block_t));\n  if (offset > MI_PAGE_MAX_OVERALLOC_ALIGN) {\n    // give up to place it right in front of the guard page if the offset is too large for unalignment\n    offset = MI_PAGE_MAX_OVERALLOC_ALIGN;\n  }\n  uint8_t* const p = (uint8_t*)block + offset;\n  mi_assert_internal(p == guard_page - obj_size);\n  mi_track_align(block, p, offset, obj_size);\n  mi_track_mem_defined(block, sizeof(mi_block_t));\n  return p;\n}\n\nmi_decl_restrict void* _mi_theap_malloc_guarded(mi_theap_t* theap, size_t size, bool zero) mi_attr_noexcept\n{\n  // allocate multiple of page size ending in a guard page\n  // ensure minimal alignment requirement?\n  if mi_unlikely(size >= MI_MAX_ALLOC_SIZE - MI_PADDING_SIZE) {  // check up front so the `req_size` won't overflow    \n    _mi_error_message(EOVERFLOW, \"(guarded) allocation request is too large (%zu bytes)\\n\", size);\n    return NULL;\n  }\n  const size_t os_page_size = _mi_os_page_size();\n  const size_t obj_size = (mi_option_is_enabled(mi_option_guarded_precise) ? size : _mi_align_up(size, MI_MAX_ALIGN_SIZE));\n  const size_t bsize    = _mi_align_up(_mi_align_up(obj_size, MI_MAX_ALIGN_SIZE) + sizeof(mi_block_t), MI_MAX_ALIGN_SIZE);\n  const size_t req_size = _mi_align_up(bsize + os_page_size, os_page_size);  \n  mi_block_t* const block = (mi_block_t*)_mi_malloc_generic(theap, req_size, 0 /* don't zero */, NULL);\n  if (block==NULL) return NULL;\n  void* const p = mi_block_ptr_set_guarded(block, obj_size);\n  if (p == NULL) return p;\n  if (zero) { \n    _mi_memzero_aligned(p,obj_size);  // we have to zero here as padding might have written here (if the blocksize > reqsize + os_page_size)\n  }\n\n  // stats\n  mi_track_malloc(p, obj_size, zero);    \n  if (!mi_theap_is_initialized(theap)) { theap = _mi_theap_default(); }\n  mi_theap_stat_counter_increase(theap, malloc_guarded_count, 1);\n  #if MI_STAT>1\n  // adjust stats to only count the allocated size of the block (and not the guard page)\n  mi_theap_stat_adjust_decrease(theap, malloc_requested, req_size);\n  mi_theap_stat_increase(theap, malloc_requested, size);\n  #endif\n  #if MI_DEBUG>3\n  if (zero) {\n    mi_assert_expensive(mi_mem_is_zero(p, size));\n  }\n  #endif\n  return p;\n}\n#endif\n\n// ------------------------------------------------------\n// ensure explicit external inline definitions are emitted!\n// ------------------------------------------------------\n\n#ifdef __cplusplus\nvoid* _mi_externs[] = {\n  (void*)&_mi_page_malloc_zero,\n  (void*)&_mi_theap_malloc_zero,\n  (void*)&_mi_theap_malloc_zero_ex,\n  (void*)&mi_theap_malloc,\n  (void*)&mi_theap_zalloc,\n  (void*)&mi_theap_malloc_small,\n  (void*)&mi_malloc,\n  (void*)&mi_malloc_small,\n  (void*)&mi_zalloc,\n  (void*)&mi_zalloc_small,\n  (void*)&mi_heap_malloc,\n  (void*)&mi_heap_malloc_small,\n  (void*)&mi_malloc_aligned\n  // (void*)&mi_theap_alloc_new,\n  // (void*)&mi_theap_alloc_new_n\n};\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/arena-meta.c",
      "sha256": "86fde644ede2e8d582e53499568a1713516a20326e0350eaa06a28029cece91b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* ----------------------------------------------------------------------------\n  We have a special \"mini\" allocator just for allocation of meta-data like\n  the theap (`mi_theap_t`) or thread-local data (`mi_tld_t`).\n\n  We reuse the bitmap of the arena's for allocation of 64b blocks inside\n  an arena slice (64KiB).\n  We always ensure that meta data is zero'd (we zero on `free`)\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"bitmap.h\"\n\n/* -----------------------------------------------------------\n  Meta data allocation\n----------------------------------------------------------- */\n\n#define MI_META_PAGE_SIZE         MI_ARENA_SLICE_SIZE\n#define MI_META_PAGE_ALIGN        MI_ARENA_SLICE_ALIGN\n\n// large enough such that META_MAX_SIZE > 4k (even on 32-bit)\n#define MI_META_BLOCK_SIZE        (1 << (16 - MI_BCHUNK_BITS_SHIFT))        // 128 on 64-bit\n#define MI_META_BLOCK_ALIGN       MI_META_BLOCK_SIZE\n#define MI_META_BLOCKS_PER_PAGE   (MI_META_PAGE_SIZE / MI_META_BLOCK_SIZE)  // 512\n#define MI_META_MAX_SIZE          (MI_BCHUNK_SIZE * MI_META_BLOCK_SIZE)\n\n#if MI_META_MAX_SIZE <= 4096\n#error \"max meta object size should be at least 4KiB\"\n#endif\n\ntypedef struct mi_meta_page_s  {\n  _Atomic(struct mi_meta_page_s*)  next;    // a linked list of meta-data pages (never released)\n  mi_memid_t                       memid;   // provenance of the meta-page memory itself\n  mi_bbitmap_t                     blocks_free;  // a small bitmap with 1 bit per block.\n} mi_meta_page_t;\n\nstatic mi_decl_cache_align _Atomic(mi_meta_page_t*)  mi_meta_pages = MI_ATOMIC_VAR_INIT(NULL);\n\n\n#if MI_DEBUG > 1\nstatic mi_meta_page_t* mi_meta_page_of_ptr(void* p, size_t* block_idx) {\n  mi_meta_page_t* mpage = (mi_meta_page_t*)((uint8_t*)_mi_align_down_ptr(p,MI_META_PAGE_ALIGN) + _mi_os_secure_guard_page_size());\n  if (block_idx != NULL) {\n    *block_idx = ((uint8_t*)p - (uint8_t*)mpage) / MI_META_BLOCK_SIZE;\n  }\n  return mpage;\n}\n#endif\n\nstatic mi_meta_page_t* mi_meta_page_next( mi_meta_page_t* mpage ) {\n  return mi_atomic_load_ptr_acquire(mi_meta_page_t, &mpage->next);\n}\n\nstatic void* mi_meta_block_start( mi_meta_page_t* mpage, size_t block_idx ) {\n  mi_assert_internal(_mi_is_aligned((uint8_t*)mpage - _mi_os_secure_guard_page_size(), MI_META_PAGE_ALIGN));\n  mi_assert_internal(block_idx < MI_META_BLOCKS_PER_PAGE);\n  void* p = ((uint8_t*)mpage - _mi_os_secure_guard_page_size() + (block_idx * MI_META_BLOCK_SIZE));\n  mi_assert_internal(mpage == mi_meta_page_of_ptr(p,NULL));\n  return p;\n}\n\n// allocate a fresh meta page and add it to the global list.\nstatic mi_meta_page_t* mi_meta_page_zalloc(void) {\n  // allocate a fresh arena slice\n  // note: careful with _mi_subproc as it may recurse into mi_tld and meta_page_zalloc again.. (same with _mi_os_numa_node()...)\n  mi_memid_t memid;\n  uint8_t* base = (uint8_t*)_mi_arenas_alloc_aligned(mi_heap_main(), MI_META_PAGE_SIZE, MI_META_PAGE_ALIGN, 0,\n                                                                    true /* commit*/, (MI_SECURE==0) /* allow large? */,\n                                                                    NULL /* req arena */, 0 /* thread_seq */, -1 /* numa node */, &memid);\n  if (base == NULL) return NULL;\n  mi_assert_internal(_mi_is_aligned(base,MI_META_PAGE_ALIGN));\n  if (!memid.initially_zero) {\n    _mi_memzero_aligned(base, MI_ARENA_SLICE_SIZE);\n  }\n\n  // guard pages\n  #if MI_SECURE >= 1\n  _mi_os_secure_guard_page_set_at(base, memid);\n  _mi_os_secure_guard_page_set_before(base + MI_META_PAGE_SIZE, memid);\n  #endif\n\n  // initialize the page and free block bitmap\n  mi_meta_page_t* mpage = (mi_meta_page_t*)(base + _mi_os_secure_guard_page_size());\n  mpage->memid = memid;\n  mi_bbitmap_init(&mpage->blocks_free, MI_META_BLOCKS_PER_PAGE, true /* already_zero */);\n  const size_t mpage_size  = offsetof(mi_meta_page_t,blocks_free) + mi_bbitmap_size(MI_META_BLOCKS_PER_PAGE, NULL);\n  const size_t info_blocks = _mi_divide_up(mpage_size,MI_META_BLOCK_SIZE);\n  const size_t guard_blocks = _mi_divide_up(_mi_os_secure_guard_page_size(), MI_META_BLOCK_SIZE);\n  mi_assert_internal(info_blocks + 2*guard_blocks < MI_META_BLOCKS_PER_PAGE);\n  mi_bbitmap_unsafe_setN(&mpage->blocks_free, info_blocks + guard_blocks, MI_META_BLOCKS_PER_PAGE - info_blocks - 2*guard_blocks);\n\n  // push atomically in front of the meta page list\n  // (note: there is no ABA issue since we never free meta-pages)\n  mi_meta_page_t* old = mi_atomic_load_ptr_acquire(mi_meta_page_t,&mi_meta_pages);\n  do {\n    mi_atomic_store_ptr_release(mi_meta_page_t, &mpage->next, old);\n  } while(!mi_atomic_cas_ptr_weak_acq_rel(mi_meta_page_t,&mi_meta_pages,&old,mpage));\n  return mpage;\n}\n\n\n// allocate meta-data\nmi_decl_noinline void* _mi_meta_zalloc( size_t size, mi_memid_t* pmemid )\n{\n  mi_assert_internal(pmemid != NULL);\n  size = _mi_align_up(size,MI_META_BLOCK_SIZE);\n  if (size == 0 || size > MI_META_MAX_SIZE) return NULL;\n  const size_t block_count = _mi_divide_up(size,MI_META_BLOCK_SIZE);\n  mi_assert_internal(block_count > 0 && block_count < MI_BCHUNK_BITS);\n  mi_meta_page_t* mpage0 = mi_atomic_load_ptr_acquire(mi_meta_page_t,&mi_meta_pages);\n  mi_meta_page_t* mpage = mpage0;\n  while (mpage != NULL) {\n    size_t block_idx;\n    if (mi_bbitmap_try_find_and_clearN(&mpage->blocks_free, 0, block_count, &block_idx)) {\n      // found and claimed `block_count` blocks\n      *pmemid = _mi_memid_create_meta(mpage, block_idx, block_count);\n      return mi_meta_block_start(mpage,block_idx);\n    }\n    else {\n      mpage = mi_meta_page_next(mpage);\n    }\n  }\n  // failed to find space in existing pages\n  if (mi_atomic_load_ptr_acquire(mi_meta_page_t,&mi_meta_pages) != mpage0) {\n    // the page list was updated by another thread in the meantime, retry\n    return _mi_meta_zalloc(size,pmemid);\n  }\n  // otherwise, allocate a fresh metapage and try once more\n  mpage = mi_meta_page_zalloc();\n  if (mpage != NULL) {\n    size_t block_idx;\n    if (mi_bbitmap_try_find_and_clearN(&mpage->blocks_free, 0, block_count, &block_idx)) {\n      // found and claimed `block_count` blocks\n      *pmemid = _mi_memid_create_meta(mpage, block_idx, block_count);\n      return mi_meta_block_start(mpage,block_idx);\n    }\n  }\n  // if all this failed, allocate from the OS\n  return _mi_os_alloc(size, pmemid);\n}\n\n// free meta-data\nmi_decl_noinline void _mi_meta_free(void* p, size_t size, mi_memid_t memid) {\n  if (p==NULL) return;\n  if (memid.memkind == MI_MEM_META) {\n    mi_assert_internal(_mi_divide_up(size, MI_META_BLOCK_SIZE) == memid.mem.meta.block_count);\n    const size_t block_count = memid.mem.meta.block_count;\n    const size_t block_idx   = memid.mem.meta.block_index;\n    mi_meta_page_t* mpage = (mi_meta_page_t*)memid.mem.meta.meta_page;\n    mi_assert_internal(mi_meta_page_of_ptr(p,NULL) == mpage);\n    mi_assert_internal(block_idx + block_count <= MI_META_BLOCKS_PER_PAGE);\n    mi_assert_internal(mi_bbitmap_is_clearN(&mpage->blocks_free, block_idx, block_count));\n    // we zero on free (and on the initial page allocation) so we don't need a \"dirty\" map\n    _mi_memzero_aligned(mi_meta_block_start(mpage, block_idx), block_count*MI_META_BLOCK_SIZE);\n    mi_bbitmap_setN(&mpage->blocks_free, block_idx, block_count);\n  }\n  else {\n    _mi_arenas_free(p,size,memid);\n  }\n}\n\n// used for debug output\nbool _mi_meta_is_meta_page(void* p)\n{\n  mi_meta_page_t* mpage0 = mi_atomic_load_ptr_acquire(mi_meta_page_t, &mi_meta_pages);\n  mi_meta_page_t* mpage = mpage0;\n  while (mpage != NULL) {\n    if ((void*)mpage == p) return true;\n    mpage = mi_meta_page_next(mpage);\n  }\n  return false;\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/arena.c",
      "sha256": "a1d6900d2b9a17461aa2a72a7791dfb22f6167b86f7ac6f15f981d9735aa2adb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* ----------------------------------------------------------------------------\n\"Arenas\" are fixed area's of OS memory from which we can allocate\nlarge blocks (>= MI_ARENA_MIN_BLOCK_SIZE, 64KiB).\nIn contrast to the rest of mimalloc, the arenas are shared between\nthreads and need to be accessed using atomic operations.\n\nArenas are also used to for huge OS page (1GiB) reservations or for reserving\nOS memory upfront which can be improve performance or is sometimes needed\non embedded devices. We can also employ this with WASI or `sbrk` systems\nto reserve large arenas upfront and be able to reuse the memory more effectively.\n\nThe arena allocation needs to be thread safe and we use an atomic bitmap to allocate.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"\n#include \"bitmap.h\"\n\n/* -----------------------------------------------------------\n  Arena id's\n----------------------------------------------------------- */\n\nmi_arena_id_t _mi_arena_id_none(void) {\n  return NULL;\n}\n\nmi_arena_t* _mi_arena_from_id(mi_arena_id_t id) {\n  mi_arena_t* const arena = (mi_arena_t*)id;\n  mi_assert_internal(arena==NULL || arena->parent==NULL); // id's should never point to sub-arena's\n  return arena;\n}\n\nmi_arena_id_t mi_arena_id_from_arena(mi_arena_t* arena) {\n  mi_assert_internal(arena==NULL || arena->parent==NULL);\n  return (arena==NULL ? _mi_arena_id_none() : (mi_arena_id_t)arena);\n}\n\n\nstatic bool mi_arena_is_suitable(mi_arena_t* arena, mi_arena_t* req_arena) {\n  if (arena == req_arena) return true;                         // they match\n  if (arena == NULL) return false;\n  if (req_arena == NULL && !arena->is_exclusive) return true;  // or the arena is not exclusive, and we didn't request a specific one\n  if (arena->parent != NULL && arena->parent == req_arena) return true;  // sub-arena? (note that req_arena is never a sub arena)\n  return false;\n}\n\nbool _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_t* request_arena) {\n  if (memid.memkind == MI_MEM_ARENA) {\n    return mi_arena_is_suitable(memid.mem.arena.arena, request_arena);\n  }\n  else {\n    return mi_arena_is_suitable(NULL, request_arena);\n  }\n}\n\nsize_t mi_arenas_get_count(mi_subproc_t* subproc) {\n  return mi_atomic_load_relaxed(&subproc->arena_count);\n}\n\nmi_arena_t* mi_arena_from_index(mi_subproc_t* subproc, size_t idx) {\n  mi_assert_internal(idx < mi_arenas_get_count(subproc));\n  return mi_atomic_load_ptr_acquire(mi_arena_t, &subproc->arenas[idx]);\n}\n\nstatic size_t mi_arena_info_slices(mi_arena_t* arena) {\n  return arena->info_slices;\n}\n\n#if MI_DEBUG > 1\nstatic bool mi_heap_has_page(mi_heap_t* heap, mi_arena_t* arena, mi_page_t* page) {\n  mi_assert(arena->arena_idx < MI_MAX_ARENAS);\n  mi_arena_pages_t* arena_pages = heap->arena_pages[arena->arena_idx];\n  return (page->memid.memkind == MI_MEM_ARENA &&\n          page->memid.mem.arena.arena == arena &&\n          arena_pages != NULL &&\n          mi_bitmap_is_setN(arena_pages->pages, page->memid.mem.arena.slice_index, 1));\n}\n#endif\n\nsize_t mi_arena_min_alignment(void) {\n  return MI_ARENA_SLICE_ALIGN;\n}\n\nsize_t mi_arena_min_size(void) {\n  return MI_ARENA_MIN_SIZE;\n}\n\nstatic size_t mi_arena_max_object_size(void) {\n  size_t max_size = mi_option_get_size(mi_option_arena_max_object_size);\n  max_size = _mi_align_up(max_size, MI_ARENA_SLICE_SIZE);\n  if (max_size <= MI_ARENA_MIN_OBJ_SIZE) {\n    return MI_ARENA_MIN_OBJ_SIZE;\n  }\n  else if (max_size >= MI_ARENA_MAX_SIZE - MI_BCHUNK_SIZE) {  // minus a bchunk to accommodate meta info\n    return (MI_ARENA_MAX_SIZE - MI_BCHUNK_SIZE);\n  }\n  else {\n    return max_size;\n  }\n}\n\nmi_decl_nodiscard static bool mi_arena_commit(mi_arena_t* arena, void* start, size_t size, bool* is_zero, size_t already_committed) {\n  if (arena != NULL && arena->commit_fun != NULL) {\n    return (*arena->commit_fun)(true, start, size, is_zero, arena->commit_fun_arg);\n  }\n  else if (already_committed > 0) {\n    return _mi_os_commit_ex(start, size, is_zero, already_committed);\n  }\n  else {\n    return _mi_os_commit(start, size, is_zero);\n  }\n}\n\n\n\n/* -----------------------------------------------------------\n  Util\n----------------------------------------------------------- */\n\n\n// Size of an arena\nstatic size_t mi_arena_size(mi_arena_t* arena) {\n  return mi_size_of_slices(arena->slice_count);\n}\n\n// Start of the arena memory area\nstatic uint8_t* mi_arena_start(mi_arena_t* arena) {\n  return ((uint8_t*)arena);\n}\n\n// Start of a slice\nuint8_t* mi_arena_slice_start(mi_arena_t* arena, size_t slice_index) {\n  mi_assert_internal(slice_index < arena->slice_count);\n  return (mi_arena_start(arena) + mi_size_of_slices(slice_index));\n}\n\nmi_page_t* mi_arena_page_at_slice(mi_arena_t* arena, size_t slice_index) {\n  mi_assert_internal(slice_index < arena->slice_count);\n  if (arena->pages_meta != NULL) {\n    mi_page_t* const page = &arena->pages_meta[slice_index];\n    #if MI_PAGE_META_ALIGNED_FREE_SMALL\n    // pages with small blocks still have the page at the start of the slice (and set the `block_size` in pages_meta to 0)\n    if (page->block_size>0) return page;\n    #else\n    return page;\n    #endif\n  }\n  // fall through (for MI_PAGE_META_ALIGNED_FREE_SMALL)\n  return (mi_page_t*)mi_arena_slice_start(arena,slice_index);\n}\n\n// Arena area\nvoid* mi_arena_area(mi_arena_id_t arena_id, size_t* size) {\n  if (size != NULL) *size = 0;\n  mi_arena_t* arena = _mi_arena_from_id(arena_id);\n  if (arena == NULL) return NULL;\n  if (size != NULL) {\n    mi_assert_internal(mi_size_of_slices(arena->slice_count) <= arena->total_size);\n    *size = arena->total_size;\n  }\n  return mi_arena_start(arena);\n}\n\n\n// Create an arena memid\nstatic mi_memid_t mi_memid_create_arena(mi_arena_t* arena, size_t slice_index, size_t slice_count) {\n  mi_assert_internal(slice_index < UINT32_MAX);\n  mi_assert_internal(slice_count < UINT32_MAX);\n  mi_assert_internal(slice_count > 0);\n  mi_assert_internal(slice_index < arena->slice_count);\n  mi_memid_t memid = _mi_memid_create(MI_MEM_ARENA);\n  memid.mem.arena.arena = arena;\n  memid.mem.arena.slice_index = (uint32_t)slice_index;\n  memid.mem.arena.slice_count = (uint32_t)slice_count;\n  return memid;\n}\n\n// get the arena and slice span\nstatic mi_arena_t* mi_arena_from_memid(mi_memid_t memid, size_t* slice_index, size_t* slice_count) {\n  mi_assert_internal(memid.memkind == MI_MEM_ARENA);\n  mi_arena_t* arena = memid.mem.arena.arena;\n  if (slice_index!=NULL) { *slice_index = memid.mem.arena.slice_index; }\n  if (slice_count!=NULL) { *slice_count = memid.mem.arena.slice_count; }\n  return arena;\n}\n\nstatic size_t mi_page_full_size(mi_page_t* page) {\n  if (page->memid.memkind == MI_MEM_ARENA) {\n    return page->memid.mem.arena.slice_count * MI_ARENA_SLICE_SIZE;\n  }\n  else if (mi_memid_is_os(page->memid) || page->memid.memkind == MI_MEM_EXTERNAL) {\n    mi_assert_internal((uint8_t*)page->memid.mem.os.base <= (uint8_t*)page);\n    const ptrdiff_t presize = (uint8_t*)page - (uint8_t*)page->memid.mem.os.base;\n    mi_assert_internal((ptrdiff_t)page->memid.mem.os.size >= presize);\n    return (presize > (ptrdiff_t)page->memid.mem.os.size ? 0 : page->memid.mem.os.size - presize);\n  }\n  else {\n    return 0;\n  }\n}\n\n\n/* -----------------------------------------------------------\n  Arena Allocation\n----------------------------------------------------------- */\n\nstatic mi_decl_noinline void* mi_arena_try_alloc_at(\n  mi_arena_t* arena, size_t slice_count, bool commit, size_t tseq, mi_memid_t* memid)\n{\n  size_t slice_index;\n  if (!mi_bbitmap_try_find_and_clearN(arena->slices_free, tseq, slice_count, &slice_index)) return NULL;\n\n  // claimed it!\n  void* p = mi_arena_slice_start(arena, slice_index);\n  *memid = mi_memid_create_arena(arena, slice_index, slice_count);\n  memid->is_pinned = arena->memid.is_pinned;\n\n  // set the dirty bits and track which slices become accessible\n  size_t touched_slices = slice_count;\n  if (arena->memid.initially_zero) {\n    size_t already_dirty = 0;\n    memid->initially_zero = mi_bitmap_setN(arena->slices_dirty, slice_index, slice_count, &already_dirty);\n    mi_assert_internal(already_dirty <= touched_slices);\n    touched_slices -= already_dirty;\n  }\n\n  // set commit state\n  if (commit) {\n    // commit requested, but the range may not be committed as a whole: ensure it is committed now\n    const size_t already_committed = mi_bitmap_popcountN(arena->slices_committed, slice_index, slice_count);\n    if (already_committed < slice_count) {\n      // not all committed, try to commit now\n      bool commit_zero = false;\n      if (!mi_arena_commit(arena, p, mi_size_of_slices(slice_count), &commit_zero, mi_size_of_slices(slice_count - already_committed))) {\n        // if the commit fails, release ownership, and return NULL;\n        // note: this does not roll back dirty bits but that is ok.\n        mi_bbitmap_setN(arena->slices_free, slice_index, slice_count);\n        return NULL;\n      }\n      if (commit_zero) {\n        memid->initially_zero = true;\n      }\n\n      // set the commit bits\n      mi_bitmap_setN(arena->slices_committed, slice_index, slice_count, NULL);\n\n      // committed\n      #if MI_DEBUG > 1\n      if (memid->initially_zero) {\n        if (!mi_mem_is_zero(p, mi_size_of_slices(slice_count))) {\n          _mi_error_message(EFAULT, \"internal error: arena allocation was not zero-initialized!\\n\");\n          memid->initially_zero = false;\n        }\n      }\n      #endif\n    }\n    else {\n      // already fully committed.\n      _mi_os_reuse(p, mi_size_of_slices(slice_count));\n      // if the OS has overcommit, and this is the first time we access these pages, then\n      // count the commit now (as at arena reserve we didn't count those commits as these are on-demand)\n      if (_mi_os_has_overcommit() && touched_slices > 0 && !arena->memid.is_pinned /* huge pages, issue #1236 */) {\n        mi_subproc_stat_increase( arena->subproc, committed, mi_size_of_slices(touched_slices));\n      }\n    }\n\n    mi_assert_internal(mi_bitmap_is_setN(arena->slices_committed, slice_index, slice_count));\n    memid->initially_committed = true;\n\n    // tool support\n    if (memid->initially_zero) {\n      mi_track_mem_defined(p, slice_count * MI_ARENA_SLICE_SIZE);\n    }\n    else {\n      mi_track_mem_undefined(p, slice_count * MI_ARENA_SLICE_SIZE);\n    }\n  }\n  else {\n    // no need to commit, but check if it is already fully committed\n    memid->initially_committed = mi_bitmap_is_setN(arena->slices_committed, slice_index, slice_count);\n    if (!memid->initially_committed) {\n      // partly committed.. adjust stats\n      size_t already_committed_count = 0;\n      mi_bitmap_setN(arena->slices_committed, slice_index, slice_count, &already_committed_count);\n      mi_bitmap_clearN(arena->slices_committed, slice_index, slice_count);\n      mi_subproc_stat_decrease(arena->subproc, committed, mi_size_of_slices(already_committed_count));\n    }\n  }\n\n  mi_assert_internal(mi_bbitmap_is_clearN(arena->slices_free, slice_index, slice_count));\n  if (commit) { mi_assert_internal(mi_bitmap_is_setN(arena->slices_committed, slice_index, slice_count)); }\n  if (commit) { mi_assert_internal(memid->initially_committed); }\n  mi_assert_internal(mi_bitmap_is_setN(arena->slices_dirty, slice_index, slice_count));\n\n  return p;\n}\n\n\nstatic int mi_reserve_os_memory_ex2(mi_subproc_t* subproc, size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id);\n\n// try to reserve a fresh arena space\nstatic bool mi_arena_reserve(mi_subproc_t* subproc, size_t req_size, bool allow_large, mi_arena_id_t* arena_id)\n{\n  const size_t arena_count = mi_arenas_get_count(subproc);\n  if (arena_count > (MI_MAX_ARENAS - 4)) return false;\n\n  // calc reserve\n  size_t arena_reserve = mi_option_get_size(mi_option_arena_reserve);\n  if (arena_reserve == 0) return false;\n\n  if (!_mi_os_has_virtual_reserve()) {\n    arena_reserve = arena_reserve/4;  // be conservative if virtual reserve is not supported (for WASM for example)\n  }\n  arena_reserve = _mi_align_up(arena_reserve, MI_ARENA_SLICE_SIZE);\n\n  if (arena_count >= 1 && arena_count <= 128) {\n    // scale up the arena sizes exponentially every 8 entries\n    const size_t multiplier = (size_t)1 << _mi_clamp(arena_count/8, 0, 16);\n    size_t reserve = 0;\n    if (!mi_mul_overflow(multiplier, arena_reserve, &reserve)) {\n      arena_reserve = reserve;\n    }\n  }\n\n  // try to accommodate the requested size for huge allocations\n  req_size = _mi_align_up(req_size + MI_ARENA_MAX_CHUNK_OBJ_SIZE, MI_ARENA_MAX_CHUNK_OBJ_SIZE); // over-reserve for meta-info\n  if (arena_reserve < req_size) {\n    arena_reserve = req_size;\n  }\n\n  // check arena bounds\n  const size_t min_reserve = MI_ARENA_MIN_SIZE;\n  const size_t max_reserve = MI_ARENA_MAX_SIZE;   // 16 GiB\n  if (arena_reserve < min_reserve) {\n    arena_reserve = min_reserve;\n  }\n  else if (arena_reserve > max_reserve) {\n    arena_reserve = max_reserve;\n  }\n\n  // should be able to at least handle the current allocation size\n  if (arena_reserve < req_size) return false;\n\n  // commit eagerly?\n  bool arena_commit = false;\n  const bool overcommit = _mi_os_has_overcommit();\n  if (mi_option_get(mi_option_arena_eager_commit) == 2) { arena_commit = overcommit || mi_option_is_enabled(mi_option_allow_large_os_pages); }\n  else if (mi_option_get(mi_option_arena_eager_commit) == 1) { arena_commit = true; }\n\n  // on an OS with overcommit (Linux) we don't count the commit yet as it is on-demand. Once a slice\n  // is actually allocated for the first time it will be counted.\n  const bool adjust = (overcommit && arena_commit);\n  if (adjust) { mi_subproc_stat_adjust_decrease( subproc, committed, arena_reserve); }\n  // and try to reserve the arena\n  int err = mi_reserve_os_memory_ex2(subproc, arena_reserve, arena_commit, allow_large, false /* exclusive? */, arena_id);\n  if (err != 0) {\n    if (adjust) { mi_subproc_stat_adjust_increase( subproc, committed, arena_reserve); } // roll back\n    // failed to allocate: try a smaller size arena as fallback?\n    const size_t small_arena_reserve = 4 * MI_ARENA_MIN_SIZE; // 128 MiB (or 32 MiB on 32-bit)\n    if (arena_reserve > small_arena_reserve && small_arena_reserve > req_size) {\n      // try again\n      if (adjust) { mi_subproc_stat_adjust_decrease(subproc, committed, small_arena_reserve); }\n      err = mi_reserve_os_memory_ex2(subproc, small_arena_reserve, arena_commit, allow_large, false /* exclusive? */, arena_id);\n      if (err != 0 && adjust) { mi_subproc_stat_adjust_increase( subproc, committed, small_arena_reserve); } // roll back\n    }\n  }\n  return (err==0);\n}\n\n\n\n\n/* -----------------------------------------------------------\n  Arena iteration\n----------------------------------------------------------- */\n\nstatic inline bool mi_arena_is_suitable_ex(mi_arena_t* arena, mi_arena_t* req_arena, bool match_numa, int numa_node, bool allow_pinned) {\n  if (!allow_pinned && arena->memid.is_pinned) return false;\n  if (!mi_arena_is_suitable(arena, req_arena)) return false;\n  if (req_arena == NULL) { // if not specific, check numa affinity\n    const bool numa_suitable = (numa_node < 0 || arena->numa_node < 0 || arena->numa_node == numa_node);\n    if (match_numa) { if (!numa_suitable) return false; }\n               else { if (numa_suitable)  return false; }\n  }\n  return true;\n}\n\n// determine the start of search; important to keep heaps and threads\n// into their own memory regions to reduce contention.\nstatic size_t mi_arena_start_idx(mi_heap_t* heap, size_t tseq, size_t arena_cycle) {\n  const size_t hseq   = heap->heap_seq;\n  const size_t hcount = mi_atomic_load_relaxed(&heap->subproc->heap_count);\n  if (arena_cycle <= 1)     return 0;\n  if (hseq==0 || hcount<=1 || arena_cycle > 0x8FF) return (tseq % arena_cycle); // common for single heap programs\n\n  // spread heaps evenly among arena's, and then evenly for threads in their fraction\n  size_t start;\n  mi_assert_internal(arena_cycle <= 0x8FF);             // prevent overflow on 32-bit\n  const size_t frac = (arena_cycle * 256) / hcount;     // fraction in the arena_cycle; at most: arena_cycle * 0x100\n  if (frac==0) {\n    // many heaps (> 256 per arena)\n    start = (hseq % arena_cycle);\n  }\n  else {\n    const size_t hspot = (hseq % hcount);  \n    start = (frac * hspot) / 256;           // (arena_cycle * (hseq % hcount)) / hcount\n    if (frac >= 512) {  // at least 2 arena's per heap?\n      start = start + (tseq % (frac/256));\n    }\n  }\n  mi_assert_internal(start < arena_cycle);\n  return start;\n}\n\n#define mi_forall_arenas(heap, req_arena, tseq, name_arena) { \\\n  const size_t _arena_count = mi_arenas_get_count(heap->subproc); \\\n  const size_t _arena_cycle = (_arena_count == 0 ? 0 : _arena_count - 1); /* first search the arenas below the last one */ \\\n  /* always start searching in the arena's below the max */ \\\n  const size_t _start = mi_arena_start_idx(heap,tseq,_arena_cycle); \\\n  for (size_t _i = 0; _i < _arena_count; _i++) { \\\n    mi_arena_t* name_arena; \\\n    if (req_arena != NULL) { \\\n      name_arena = req_arena; /* if there is a specific req_arena, only search that one */\\\n      if (_i > 0) break;      /* only once */ \\\n    } \\\n    else { \\\n      size_t _idx; \\\n      if (_i < _arena_cycle) { \\\n        _idx = _i + _start; \\\n        if (_idx >= _arena_cycle) { _idx -= _arena_cycle; } /* adjust so we rotate through the cycle */ \\\n      } \\\n      else { \\\n        _idx = _i; /* remaining arena's after the cycle */ \\\n      } \\\n      name_arena = mi_arena_from_index(heap->subproc,_idx); \\\n    } \\\n    if (name_arena != NULL) \\\n    {\n\n#define mi_forall_arenas_end()  \\\n    } \\\n  } \\\n  }\n\n#define mi_forall_suitable_arenas(heap, req_arena, tseq, match_numa, numa_node, allow_large, name_arena) \\\n  mi_forall_arenas(heap, req_arena,tseq,name_arena) { \\\n    if (mi_arena_is_suitable_ex(name_arena, req_arena, match_numa, numa_node, allow_large)) { \\\n\n#define mi_forall_suitable_arenas_end() \\\n  }} \\\n  mi_forall_arenas_end()\n\n/* -----------------------------------------------------------\n  Arena allocation\n----------------------------------------------------------- */\n\n// allocate slices from the arenas\nstatic mi_decl_noinline void* mi_arenas_try_find_free(\n  mi_heap_t* heap, size_t slice_count, size_t alignment,\n  bool commit, bool allow_large, mi_arena_t* req_arena, size_t tseq, int numa_node, mi_memid_t* memid)\n{\n  // mi_assert_internal(slice_count <= mi_slice_count_of_size(MI_ARENA_MAX_CHUNK_OBJ_SIZE));\n  mi_assert(alignment <= MI_ARENA_SLICE_ALIGN);\n  if (alignment > MI_ARENA_SLICE_ALIGN) return NULL;\n\n  // search arena's\n  mi_forall_suitable_arenas(heap, req_arena, tseq, true /* only numa matching */, numa_node, allow_large, arena)\n  {\n    void* p = mi_arena_try_alloc_at(arena, slice_count, commit, tseq, memid);\n    if (p != NULL) return p;\n  }\n  mi_forall_suitable_arenas_end();\n  if (numa_node < 0) return NULL;\n\n  // search again but now regardless of preferred numa affinity\n  mi_forall_suitable_arenas(heap, req_arena, tseq, false /* numa non-matching now */, numa_node, allow_large, arena)\n  {\n    void* p = mi_arena_try_alloc_at(arena, slice_count, commit, tseq, memid);\n    if (p != NULL) return p;\n  }\n  mi_forall_suitable_arenas_end();\n  return NULL;\n}\n\n// Allocate slices from the arena's -- potentially allocating a fresh arena\nstatic mi_decl_noinline void* mi_arenas_try_alloc(\n  mi_heap_t* heap,\n  size_t slice_count, size_t alignment,\n  bool commit, bool allow_large,\n  mi_arena_t* req_arena, size_t tseq, int numa_node, mi_memid_t* memid)\n{\n  // mi_assert(slice_count <= MI_ARENA_MAX_CHUNK_OBJ_SLICES);\n  mi_assert(alignment <= MI_ARENA_SLICE_ALIGN);\n  void* p;\n\n  // not too large?\n  if (slice_count * MI_ARENA_SLICE_SIZE > MI_ARENA_MAX_SIZE) return NULL;\n\n  // try to find free slices in the arena's\n  p = mi_arenas_try_find_free(heap, slice_count, alignment, commit, allow_large, req_arena, tseq, numa_node, memid);\n  if (p != NULL) return p;\n\n  // did we need a specific arena?\n  if (req_arena != NULL) return NULL;\n\n  // don't create arena's while preloading (todo: or should we?)\n  if (_mi_preloading()) return NULL;\n\n  // don't create arena's if OS allocation is disallowed\n  if (mi_option_is_enabled(mi_option_disallow_os_alloc)) return NULL;\n\n  // otherwise, try to reserve a new arena -- but one thread at a time.. (todo: allow 2 or 4 to reduce contention?)\n  mi_subproc_t* const subproc = heap->subproc;\n  const size_t arena_count = mi_arenas_get_count(subproc);\n  mi_lock(&subproc->arena_reserve_lock) {\n    if (arena_count == mi_arenas_get_count(subproc)) {\n      // we are the first to enter the lock, reserve a fresh arena\n      mi_arena_id_t arena_id = _mi_arena_id_none();\n      mi_arena_reserve(subproc, mi_size_of_slices(slice_count), allow_large, &arena_id);\n    }\n    else {\n      // another thread already reserved a new arena\n    }\n  }\n  // try once more to allocate in the new arena\n  mi_assert_internal(req_arena == NULL);\n  p = mi_arenas_try_find_free(heap, slice_count, alignment, commit, allow_large, req_arena, tseq, numa_node, memid);\n  if (p != NULL) return p;\n\n  return NULL;\n}\n\n// Allocate from the OS (if allowed)\nstatic void* mi_arena_os_alloc_aligned(\n  size_t size, size_t alignment, size_t align_offset,\n  bool commit, bool allow_large,\n  mi_arena_id_t req_arena_id, mi_memid_t* memid)\n{\n  // if we cannot use OS allocation, return NULL\n  if (mi_option_is_enabled(mi_option_disallow_os_alloc) || req_arena_id != _mi_arena_id_none()) {\n    errno = ENOMEM;\n    return NULL;\n  }\n\n  if (align_offset > 0) {\n    return _mi_os_alloc_aligned_at_offset(size, alignment, align_offset, commit, allow_large, memid);\n  }\n  else {\n    return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid);\n  }\n}\n\n\n// Allocate large sized memory\nvoid* _mi_arenas_alloc_aligned( mi_heap_t* heap,\n  size_t size, size_t alignment, size_t align_offset,\n  bool commit, bool allow_large,\n  mi_arena_t* req_arena, size_t tseq, int numa_node, mi_memid_t* memid)\n{\n  mi_assert_internal(memid != NULL);\n  mi_assert_internal(size > 0);\n\n  // try to allocate in an arena if the alignment is small enough and the object is not too small (as for theap meta data)\n  if (!mi_option_is_enabled(mi_option_disallow_arena_alloc) &&                // is arena allocation allowed?\n      size >= MI_ARENA_MIN_OBJ_SIZE && size <= mi_arena_max_object_size() &&  // and not too small or too large\n      alignment <= MI_ARENA_SLICE_ALIGN && align_offset == 0)                 // and good alignment\n  {\n    const size_t slice_count = mi_slice_count_of_size(size);\n    void* p = mi_arenas_try_alloc(heap, slice_count, alignment, commit, allow_large, req_arena, tseq, numa_node, memid);\n    if (p != NULL) return p;\n  }\n\n  // fall back to the OS\n  void* p = mi_arena_os_alloc_aligned(size, alignment, align_offset, commit, allow_large, req_arena, memid);\n  return p;\n}\n\nvoid* _mi_arenas_alloc(mi_heap_t* heap, size_t size, bool commit, bool allow_large, mi_arena_t* req_arena, size_t tseq, int numa_node, mi_memid_t* memid)\n{\n  return _mi_arenas_alloc_aligned(heap, size, MI_ARENA_SLICE_SIZE, 0, commit, allow_large, req_arena, tseq, numa_node, memid);\n}\n\n\n\n/* -----------------------------------------------------------\n  Arena page allocation\n----------------------------------------------------------- */\n\n// release ownership of a page. This may free the page if all blocks were concurrently\n// freed in the meantime. Returns true if the page was freed.\nstatic bool mi_abandoned_page_unown(mi_page_t* page, mi_theap_t* current_theap) {\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_assert_internal(_mi_thread_id()==current_theap->tld->thread_id);\n  mi_thread_free_t tf_new;\n  mi_thread_free_t tf_old = mi_atomic_load_relaxed(&page->xthread_free);\n  do {\n    mi_assert_internal(mi_tf_is_owned(tf_old));\n    while mi_unlikely(mi_tf_block(tf_old) != NULL) {\n      _mi_page_free_collect(page, false);  // update used\n      if (mi_page_all_free(page)) {        // it may become free just before unowning it\n        _mi_arenas_page_unabandon(page, current_theap);\n        _mi_arenas_page_free(page, current_theap);\n        return true;\n      }\n      tf_old = mi_atomic_load_relaxed(&page->xthread_free);\n    }\n    mi_assert_internal(mi_tf_block(tf_old)==NULL);\n    tf_new = mi_tf_create(NULL, false);\n  } while (!mi_atomic_cas_weak_acq_rel(&page->xthread_free, &tf_old, tf_new));\n  return false;\n}\n\n\nstatic bool mi_arena_try_claim_abandoned(size_t slice_index, mi_arena_t* arena, bool* keep_abandoned) {\n  // found an abandoned page of the right size\n  mi_page_t* const page  = mi_arena_page_at_slice(arena, slice_index);\n  // can we claim ownership?\n  if (!mi_page_claim_ownership(page)) {\n    // there was a concurrent free that reclaims this page ..\n    // we need to keep it in the abandoned map as the free will call `mi_arena_page_unabandon`,\n    // and wait for readers (us!) to finish. This is why it is very important to set the abandoned\n    // bit again (or otherwise the unabandon will never stop waiting).\n    *keep_abandoned = true;\n    return false;\n  }\n  else {\n    // yes, we can reclaim it, keep the abandoned map entry clear\n    *keep_abandoned = false;\n    return true;\n  }\n}\n\n// allocate initial arena_pages from the main heap\nstatic mi_arena_pages_t* mi_arena_pages_alloc(mi_arena_t* arena);\n\nstatic mi_arena_pages_t* mi_heap_arena_pages(mi_heap_t* heap, mi_arena_t* arena) {\n  mi_assert_internal(arena!=NULL);\n  mi_assert_internal(heap!=NULL);\n  mi_assert(arena->arena_idx < MI_MAX_ARENAS);\n  return mi_atomic_load_ptr_acquire(mi_arena_pages_t, &heap->arena_pages[arena->arena_idx]);\n}\n\nstatic mi_arena_t* mi_page_arena_pages(mi_page_t* page, size_t* slice_index, size_t* slice_count, mi_arena_pages_t** parena_pages) {\n  // todo: maybe store the arena* directly in the page?\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_arena_t* const arena = mi_arena_from_memid(page->memid, slice_index, slice_count);\n  mi_assert_internal(arena != NULL);\n  if (parena_pages != NULL) {\n    mi_arena_pages_t* const arena_pages = mi_heap_arena_pages(mi_page_heap(page), arena);\n    mi_assert_internal(arena_pages != NULL);\n    mi_assert_internal(slice_index==NULL || mi_bitmap_is_set(arena_pages->pages, *slice_index));\n    *parena_pages = arena_pages;\n  }\n  return arena;\n}\n\nstatic mi_arena_pages_t* mi_heap_ensure_arena_pages(mi_heap_t* heap, mi_arena_t* arena) {\n  mi_assert_internal(arena!=NULL);\n  mi_assert_internal(heap!=NULL);\n  mi_assert(arena->arena_idx < MI_MAX_ARENAS);\n  mi_arena_pages_t* arena_pages = mi_heap_arena_pages(heap, arena);\n  if (arena_pages==NULL) {\n    mi_lock(&heap->arena_pages_lock) {\n      arena_pages = mi_atomic_load_ptr_acquire(mi_arena_pages_t, &heap->arena_pages[arena->arena_idx]);\n      if (arena_pages == NULL) {  // still NULL?\n        if (_mi_is_heap_main(heap)) {\n          // the page info for the main heap is always allocated as part of an arena\n          arena_pages = &arena->pages_main;\n        }\n        else {\n          // always allocate the arena pages info from the main heap\n          // todo: allocate into the current arena?\n          arena_pages = mi_arena_pages_alloc(arena);\n        }\n        mi_atomic_store_ptr_release(mi_arena_pages_t, &heap->arena_pages[arena->arena_idx], arena_pages);\n      }\n    }\n  }\n  if (_mi_is_heap_main(heap)) { mi_assert(arena_pages != NULL); }  // can never fail\n  return arena_pages;\n}\n\nstatic mi_page_t* mi_arenas_page_try_find_abandoned(mi_theap_t* theap, size_t slice_count, size_t block_size)\n{\n  mi_heap_t* const heap = _mi_theap_heap(theap);\n  const size_t tseq = theap->tld->thread_seq;\n  mi_arena_t* const req_arena = heap->exclusive_arena;\n\n  MI_UNUSED(slice_count);\n  const size_t bin = _mi_bin(block_size);\n  mi_assert_internal(bin < MI_BIN_COUNT);\n\n  // any abandoned in our size class?\n  mi_assert_internal(heap != NULL);\n  if (mi_atomic_load_relaxed(&heap->abandoned_count[bin]) == 0) {\n    return NULL;\n  }\n\n  // search arena's\n  const bool allow_large = true;\n  const int  any_numa = -1;\n  const bool match_numa = true;\n  mi_forall_suitable_arenas(heap, req_arena, tseq, match_numa, any_numa, allow_large, arena)\n  {\n    mi_arena_pages_t* const arena_pages = mi_heap_arena_pages(heap, arena);\n    if (arena_pages != NULL) {\n      size_t slice_index;\n      mi_bitmap_t* const bitmap = arena_pages->pages_abandoned[bin];\n\n      if (mi_bitmap_try_find_and_claim(bitmap, tseq, &slice_index, &mi_arena_try_claim_abandoned, arena)) {\n        // found an abandoned page of the right size\n        // and claimed ownership.\n        mi_page_t* page = mi_arena_page_at_slice(arena, slice_index);\n        mi_assert_internal(mi_page_is_owned(page));\n        mi_assert_internal(mi_page_is_abandoned(page));\n        mi_assert_internal(mi_heap_has_page(heap, arena, page));\n        mi_atomic_decrement_relaxed(&heap->abandoned_count[bin]);\n        mi_theap_stat_decrease(theap, pages_abandoned, 1);\n        mi_theap_stat_counter_increase(theap, pages_reclaim_on_alloc, 1);\n\n        _mi_page_free_collect(page, false);  // update `used` count\n        mi_assert_internal(mi_bbitmap_is_clearN(arena->slices_free, slice_index, slice_count));\n        mi_assert_internal(page->slice_committed > 0 || mi_bitmap_is_setN(arena->slices_committed, slice_index, slice_count));\n        mi_assert_internal(mi_bitmap_is_setN(arena->slices_dirty, slice_index, slice_count));\n        mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n        mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);\n        mi_assert_internal(mi_page_block_size(page) == block_size);\n        mi_assert_internal(!mi_page_is_full(page));\n        return page;\n      }\n    }\n  }\n  mi_forall_suitable_arenas_end();\n  return NULL;\n}\n\nstatic uint8_t* mi_arenas_page_alloc_fresh_area(mi_theap_t* theap, size_t slice_count, size_t block_size, size_t block_alignment, bool os_align, bool commit, mi_memid_t* memid) {\n  MI_UNUSED_RELEASE(block_size);\n  const bool allow_large = (MI_SECURE < 5); // 5 = guard page at end of each arena page\n  const size_t page_alignment = MI_ARENA_SLICE_ALIGN;\n\n  mi_heap_t*  const heap = _mi_theap_heap(theap);\n  mi_tld_t*   const tld  = theap->tld;\n  mi_arena_t* const req_arena = heap->exclusive_arena;\n  const int numa_node = (heap->numa_node >= 0 ? heap->numa_node : tld->numa_node);\n\n  // try to allocate from free space in arena's\n  uint8_t* start = NULL;\n  *memid = _mi_memid_none();\n  const size_t alloc_size = mi_size_of_slices(slice_count);\n  if (!mi_option_is_enabled(mi_option_disallow_arena_alloc) &&       // allowed to allocate from arena's?\n      !os_align &&                                                   // not large alignment\n      slice_count <= mi_arena_max_object_size()/MI_ARENA_SLICE_SIZE) // and not too large\n  {\n    start = (uint8_t*)mi_arenas_try_alloc(heap, slice_count, page_alignment, commit, allow_large, req_arena, tld->thread_seq, numa_node, memid);\n    if (start != NULL) {\n      mi_arena_pages_t* const arena_pages = mi_heap_ensure_arena_pages(heap, memid->mem.arena.arena);\n      if (arena_pages==NULL) {\n        _mi_arenas_free(start, mi_size_of_slices(slice_count), *memid); // roll back\n        start = NULL;\n      }\n      else {\n        // note: the following assert should hold if we could check it atomically, but in a concurrent setting we may already allocate in slice_count\n        // mi_assert_internal(mi_bitmap_is_clearN(arena_pages->pages, memid->mem.arena.slice_index, memid->mem.arena.slice_count));\n        mi_assert_internal(mi_bitmap_is_clear(arena_pages->pages, memid->mem.arena.slice_index));\n        mi_bitmap_set(arena_pages->pages, memid->mem.arena.slice_index);\n      }\n    }\n  }\n\n  // otherwise fall back to the OS\n  if (start == NULL) {\n    if (os_align) {\n      // note: slice_count already includes the page\n      mi_assert_internal(slice_count >= mi_slice_count_of_size(block_size) + mi_slice_count_of_size(page_alignment));\n      start = (uint8_t*)mi_arena_os_alloc_aligned(alloc_size, block_alignment, page_alignment /* align offset */, commit, allow_large, req_arena, memid);\n    }\n    else {\n      start = (uint8_t*)mi_arena_os_alloc_aligned(alloc_size, page_alignment, 0 /* align offset */, commit, allow_large, req_arena, memid);\n    }\n  }\n\n  if (start == NULL) return NULL;\n  mi_assert_internal(_mi_is_aligned(start, MI_PAGE_ALIGN));\n  mi_assert_internal(!os_align || _mi_is_aligned(start + page_alignment, block_alignment));\n  return start;\n}\n\nstatic size_t mi_page_block_start(size_t block_size, bool os_align)\n{\n  #if MI_GUARDED\n  // in a guarded build, we align pages with blocks a multiple of an OS page size, to the OS page size\n  // this ensures that all blocks in such pages are OS page size aligned (which is needed for the guard pages)\n  const size_t os_page_size = _mi_os_page_size();\n  mi_assert_internal(MI_PAGE_ALIGN >= os_page_size);\n  if (!os_align && block_size % os_page_size == 0 && block_size > os_page_size /* at least 2 or more */ ) {\n    return _mi_align_up(mi_page_info_size(), os_page_size);\n  }\n  else\n  #endif\n  if (os_align) {\n    return MI_PAGE_ALIGN;\n  }\n  else if (_mi_is_power_of_two(block_size) && block_size <= MI_PAGE_MAX_START_BLOCK_ALIGN2) {\n    // naturally align power-of-2 blocks up to MI_PAGE_MAX_START_BLOCK_ALIGN2 size (4KiB)\n    return _mi_align_up(mi_page_info_size(), block_size);\n  }\n  else if (block_size != 0 && (block_size % MI_PAGE_OSPAGE_BLOCK_ALIGN2) == 0) {\n    // also align large pages that are a multiple of MI_PAGE_OSPAGE_BLOCK_ALIGN2 (4KiB)\n    return _mi_align_up(mi_page_info_size(), MI_PAGE_OSPAGE_BLOCK_ALIGN2);\n  }\n  else {\n    // otherwise start after the info\n    return mi_page_info_size();\n  }\n}\n\n// Allocate a fresh page\nstatic mi_page_t* mi_arenas_page_alloc_fresh(mi_theap_t* theap, size_t slice_count, size_t block_size, size_t block_alignment, bool commit)\n{\n  const bool os_align        = (block_alignment > MI_PAGE_MAX_OVERALLOC_ALIGN);\n  const size_t alloc_size    = mi_size_of_slices(slice_count);\n  mi_memid_t memid           = _mi_memid_none();\n  uint8_t* const slice_start = mi_arenas_page_alloc_fresh_area(theap,slice_count,block_size,block_alignment,os_align,commit,&memid);\n  if (!slice_start) return NULL;\n\n  // guard page at the end of mimalloc page?\n  #if MI_SECURE>=5\n  mi_assert(alloc_size > _mi_os_secure_guard_page_size());\n  const size_t page_noguard_size = alloc_size - _mi_os_secure_guard_page_size();\n  if (memid.initially_committed) {\n    _mi_os_secure_guard_page_set_at(slice_start + page_noguard_size, memid);\n  }\n  #else\n  const size_t page_noguard_size = alloc_size;\n  #endif\n\n  // allocate the page meta info\n  mi_page_t* page = NULL;\n  bool page_meta_is_separate = false;\n  size_t block_start = 0;\n\n  // allocate page meta info at the arena start?\n  if (memid.memkind == MI_MEM_ARENA) {\n    mi_arena_t* const arena = memid.mem.arena.arena;\n    if (arena->pages_meta != NULL) {\n      mi_assert_internal(MI_PAGE_META_IS_SEPARATED!=0);\n      mi_page_t* const page_meta = &arena->pages_meta[memid.mem.arena.slice_index];\n      mi_assert_internal(page_meta->block_size == 0);\n      #if MI_PAGE_META_ALIGNED_FREE_SMALL\n      // if `block_size <= MI_SMALL_SIZE_MAX` we put the page info in front of the slice,\n      // (note: it is important that `page_meta->block_size == 0` for `mi_arena_page_at_slice`)\n      if (block_size > MI_SMALL_SIZE_MAX)\n      #endif\n      {\n        page = page_meta;\n        page_meta_is_separate = true;\n        block_start = 0;\n        #if !defined(MI_PAGE_BLOCK_START_MAX_OFFSET)\n        #define MI_PAGE_BLOCK_START_MAX_OFFSET  (8*MI_INTPTR_BITS) /* 512 */\n        #endif\n        if (block_size >= MI_INTPTR_SIZE && block_size <= MI_PAGE_BLOCK_START_MAX_OFFSET && _mi_is_power_of_two(block_size)) {\n          block_start += block_size;\n        }\n        mi_assert_internal(page->block_size == 0);\n        _mi_memzero_aligned(page, sizeof(*page));\n      }\n    }\n  }\n  if (page == NULL) {\n    // put page meta info in front of the slice\n    page = (mi_page_t*)slice_start;\n    block_start = mi_page_block_start(block_size, os_align);\n  }\n\n  // commit first block?\n  size_t commit_size = 0;\n  if (!memid.initially_committed) {\n    commit_size = _mi_align_up(block_start + block_size, MI_PAGE_MIN_COMMIT_SIZE);\n    if (commit_size > page_noguard_size) { commit_size = page_noguard_size; }\n    bool is_zero = false;\n    if mi_unlikely(!mi_arena_commit( mi_memid_arena(memid), slice_start, commit_size, &is_zero, 0)) {\n      _mi_arenas_free(slice_start, alloc_size, memid);\n      return NULL;\n    }\n  }\n  if (!memid.initially_zero && !page_meta_is_separate) {\n    _mi_memzero_aligned(page, sizeof(*page));\n  }\n\n  // claimed free slices: initialize the page partly\n  if (!memid.initially_zero && memid.initially_committed) {\n    mi_track_mem_undefined(slice_start, slice_count * MI_ARENA_SLICE_SIZE);\n  }\n  else if (memid.initially_committed) {\n    mi_track_mem_defined(slice_start, slice_count * MI_ARENA_SLICE_SIZE);\n  }\n  #if MI_DEBUG > 1\n  if (memid.initially_zero && memid.initially_committed) {\n    if (!mi_mem_is_zero(slice_start, page_noguard_size)) {\n      _mi_error_message(EFAULT, \"internal error: page memory was not zero initialized.\\n\");\n      memid.initially_zero = false;\n      if (block_start > 0) { _mi_memzero_aligned(page, sizeof(*page)); }\n    }\n  }\n  #endif\n  const size_t reserved = (os_align ? 1 : (page_noguard_size - block_start) / block_size);\n  mi_assert_internal(reserved > 0 && reserved <= UINT16_MAX);\n\n  // initialize\n  page->reserved = (uint16_t)reserved;\n  page->page_start = slice_start + block_start;\n  page->block_size = block_size;\n  page->slice_committed = commit_size;\n  page->memid = memid;\n  page->free_is_zero = memid.initially_zero;\n  mi_assert_internal(page->free==NULL);\n  mi_assert_internal(page_meta_is_separate == mi_page_meta_is_separated(page));\n  mi_assert_internal(mi_page_slice_start(page) == slice_start);\n\n  // and own it\n  mi_page_claim_ownership(page);\n\n  // register in the page map\n  if mi_unlikely(!_mi_page_map_register(page)) {\n    _mi_arenas_free( slice_start, alloc_size, memid );\n    return NULL;\n  }\n\n  // stats\n  mi_theap_stat_increase(theap, pages, 1);\n  mi_theap_stat_increase(theap, page_bins[_mi_page_stats_bin(page)], 1);\n\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page),MI_PAGE_ALIGN));\n  mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);\n  mi_assert_internal(mi_page_block_size(page) == block_size);\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_assert_internal(mi_page_is_owned(page));\n\n  return page;\n}\n\n// Allocate a regular small/medium/large page.\nstatic mi_page_t* mi_arenas_page_regular_alloc(mi_theap_t* theap, size_t slice_count, size_t block_size)\n{\n  // 1. look for an abandoned page\n  mi_page_t* page = mi_arenas_page_try_find_abandoned(theap, slice_count, block_size);\n  if (page != NULL) {\n    return page;  // return as abandoned\n  }\n\n  // 2. find a free block, potentially allocating a new arena\n  const long commit_on_demand = mi_option_get(mi_option_page_commit_on_demand);\n  const bool commit = (slice_count <= mi_slice_count_of_size(MI_PAGE_MIN_COMMIT_SIZE) ||  // always commit small pages\n                       (commit_on_demand == 2 && _mi_os_has_overcommit()) || (commit_on_demand == 0));\n  page = mi_arenas_page_alloc_fresh(theap, slice_count, block_size, 1, commit);\n  if (page == NULL) return NULL;\n\n  mi_assert_internal(page->memid.memkind != MI_MEM_ARENA || page->memid.mem.arena.slice_count == slice_count);\n  if (!_mi_page_init(theap, page)) {\n    _mi_arenas_free( page, mi_page_full_size(page), page->memid);\n    return NULL;\n  }\n\n  return page;\n}\n\n// Allocate a page containing one block (very large, or with large alignment)\nstatic mi_page_t* mi_arenas_page_singleton_alloc(mi_theap_t* theap, size_t block_size, size_t block_alignment)\n{\n  const bool os_align = (block_alignment > MI_PAGE_MAX_OVERALLOC_ALIGN);\n  const size_t info_size = (os_align ? MI_PAGE_ALIGN : mi_page_info_size());\n  #if MI_SECURE < 2\n  const size_t slice_count = mi_slice_count_of_size(info_size + block_size);\n  #else\n  const size_t slice_count = mi_slice_count_of_size(_mi_align_up(info_size + block_size, _mi_os_secure_guard_page_size()) + _mi_os_secure_guard_page_size());\n  #endif\n\n  mi_page_t* page = mi_arenas_page_alloc_fresh(theap, slice_count, block_size, block_alignment, true /* commit singletons always */);\n  if (page == NULL) return NULL;\n\n  mi_assert(page->reserved == 1);\n  if (!_mi_page_init(theap, page)) {\n    _mi_arenas_free( page, mi_page_full_size(page), page->memid);\n    return NULL;\n  }\n\n  return page;\n}\n\n\nmi_page_t* _mi_arenas_page_alloc(mi_theap_t* theap, size_t block_size, size_t block_alignment) {\n  mi_page_t* page;\n  if mi_unlikely(block_alignment > MI_PAGE_MAX_OVERALLOC_ALIGN) {\n    mi_assert_internal(_mi_is_power_of_two(block_alignment));\n    page = mi_arenas_page_singleton_alloc(theap, block_size, block_alignment);\n  }\n  else if (block_size <= MI_SMALL_MAX_OBJ_SIZE) {\n    page = mi_arenas_page_regular_alloc(theap, mi_slice_count_of_size(MI_SMALL_PAGE_SIZE), block_size);\n  }\n  else if (block_size <= MI_MEDIUM_MAX_OBJ_SIZE) {\n    page = mi_arenas_page_regular_alloc(theap, mi_slice_count_of_size(MI_MEDIUM_PAGE_SIZE), block_size);\n  }\n  #if MI_ENABLE_LARGE_PAGES\n  else if (block_size <= MI_LARGE_MAX_OBJ_SIZE) {\n    page = mi_arenas_page_regular_alloc(theap, mi_slice_count_of_size(MI_LARGE_PAGE_SIZE), block_size);\n  }\n  #endif\n  else {\n    page = mi_arenas_page_singleton_alloc(theap, block_size, block_alignment);\n  }\n  if mi_unlikely(page == NULL) {\n    return NULL;\n  }\n  // mi_assert_internal(page == NULL || _mi_page_segment(page)->subproc == tld->subproc);\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n  mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);\n  mi_assert_internal(block_alignment <= MI_PAGE_MAX_OVERALLOC_ALIGN || _mi_is_aligned(mi_page_start(page), block_alignment));\n\n  return page;\n}\n\nvoid _mi_arenas_page_free(mi_page_t* page, mi_theap_t* current_theapx) {\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n  mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_assert_internal(mi_page_all_free(page));\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_assert_internal(page->next==NULL && page->prev==NULL);\n  mi_assert_internal(current_theapx == NULL || _mi_thread_id()==current_theapx->tld->thread_id);\n\n  if (current_theapx != NULL) {\n    mi_theap_stat_decrease(current_theapx, page_bins[_mi_page_stats_bin(page)], 1);\n    mi_theap_stat_decrease(current_theapx, pages, 1);\n  }\n  else {\n    mi_heap_t* const heap = mi_page_heap(page);\n    mi_heap_stat_decrease(heap, page_bins[_mi_page_stats_bin(page)], 1);\n    mi_heap_stat_decrease(heap, pages, 1);\n  }\n\n  #if MI_DEBUG>1\n  if (page->memid.memkind==MI_MEM_ARENA && !mi_page_is_full(page)) {\n    size_t bin = _mi_bin(mi_page_block_size(page));\n    size_t slice_index;\n    size_t slice_count;\n    mi_arena_pages_t* arena_pages = NULL;\n    mi_arena_t* const arena = mi_page_arena_pages(page, &slice_index, &slice_count, &arena_pages);\n    mi_assert_internal(mi_bbitmap_is_clearN(arena->slices_free, slice_index, slice_count));\n    mi_assert_internal(page->slice_committed > 0 || mi_bitmap_is_setN(arena->slices_committed, slice_index, slice_count));\n    mi_assert_internal(mi_bitmap_is_clearN(arena_pages->pages_abandoned[bin], slice_index, 1));\n    mi_assert_internal(mi_bitmap_is_setN(arena_pages->pages, slice_index, 1));\n    // note: we cannot check for `!mi_page_is_abandoned_and_mapped` since that may\n    // be (temporarily) not true if the free happens while trying to reclaim\n    // see `mi_arena_try_claim_abandoned`\n  }\n  #endif\n\n  // recommit guard page at the end?\n  // we must do this since we may later allocate large spans over this page and cannot have a guard page in between\n  #if MI_SECURE >= 5\n  if (!page->memid.is_pinned) {\n    _mi_os_secure_guard_page_reset_before(mi_page_slice_start(page) + mi_page_full_size(page), page->memid);\n  }\n  #endif\n\n  // unregister page\n  _mi_page_map_unregister(page);\n  if (page->memid.memkind == MI_MEM_ARENA) {\n    mi_arena_pages_t* arena_pages;\n    size_t slice_index;\n    size_t slice_count; MI_UNUSED(slice_count);\n    mi_arena_t* const arena = mi_page_arena_pages(page, &slice_index, &slice_count, &arena_pages);\n    mi_assert_internal(arena_pages!=NULL);\n    mi_bitmap_clear(arena_pages->pages, slice_index);\n    if (page->slice_committed > 0) {\n      // if committed on-demand, set the commit bits to account commit properly\n      mi_assert_internal(mi_page_full_size(page) >= page->slice_committed);\n      const size_t total_slices = page->slice_committed / MI_ARENA_SLICE_SIZE;  // conservative\n      //mi_assert_internal(mi_bitmap_is_clearN(arena->slices_committed, slice_index, total_slices));\n      mi_assert_internal(slice_count >= total_slices);\n      if (total_slices > 0) {\n        mi_bitmap_setN(arena->slices_committed, slice_index, total_slices, NULL);\n      }\n      // any left over?\n      const size_t extra = page->slice_committed % MI_ARENA_SLICE_SIZE;\n      if (extra > 0) {\n        // pretend it was decommitted already\n        mi_subproc_stat_decrease(arena->subproc, committed, extra);\n      }\n    }\n    else {\n      mi_assert_internal(mi_bitmap_is_setN(arena->slices_committed, slice_index, slice_count));\n    }\n  }\n  if (mi_page_meta_is_separated(page)) { page->block_size = 0; }  // for assertion checking\n  _mi_arenas_free( mi_page_slice_start(page), mi_page_full_size(page), page->memid);\n}\n\n/* -----------------------------------------------------------\n  Arena abandon\n----------------------------------------------------------- */\n\nvoid _mi_arenas_page_abandon(mi_page_t* page, mi_theap_t* current_theap) {\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n  mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_assert_internal(!mi_page_all_free(page));\n  mi_assert_internal(page->next==NULL && page->prev == NULL);\n  mi_assert_internal(_mi_thread_id()==current_theap->tld->thread_id);\n  // mi_assert_internal(current_theap == _mi_page_associated_theap(page));\n\n  mi_heap_t* heap = mi_page_heap(page); mi_assert_internal(heap==_mi_theap_heap(current_theap));\n  if (page->memid.memkind==MI_MEM_ARENA && !mi_page_is_full(page)) {\n    // make available for allocations\n    size_t bin = _mi_bin(mi_page_block_size(page));\n    size_t slice_index;\n    size_t slice_count;\n    mi_arena_pages_t* arena_pages = NULL;\n    mi_arena_t* const arena = mi_page_arena_pages(page, &slice_index, &slice_count, &arena_pages); MI_UNUSED(arena);\n\n    mi_assert_internal(!mi_page_is_singleton(page));\n    mi_assert_internal(mi_bbitmap_is_clearN(arena->slices_free, slice_index, slice_count));\n    mi_assert_internal(page->slice_committed > 0 || mi_bitmap_is_setN(arena->slices_committed, slice_index, slice_count));\n    mi_assert_internal(mi_bitmap_is_setN(arena->slices_dirty, slice_index, slice_count));\n\n    mi_page_set_abandoned_mapped(page);\n    const bool was_clear = mi_bitmap_set(arena_pages->pages_abandoned[bin], slice_index);\n    MI_UNUSED(was_clear); mi_assert_internal(was_clear);\n    mi_atomic_increment_relaxed(&heap->abandoned_count[bin]);\n    mi_theap_stat_increase(current_theap, pages_abandoned, 1);\n  }\n  else {\n    // page is full (or a singleton), or the page is OS/externally allocated\n    // leave as is; it will be reclaimed when an object is free'd in the page\n    // but for non-arena pages, add to the subproc list so these can be visited\n    if (page->memid.memkind != MI_MEM_ARENA && mi_option_is_enabled(mi_option_visit_abandoned)) {\n      mi_lock(&heap->os_abandoned_pages_lock) {\n        // push in front\n        page->prev = NULL;\n        page->next = heap->os_abandoned_pages;\n        if (page->next != NULL) { page->next->prev = page; }\n        heap->os_abandoned_pages = page;\n      }\n    }\n    mi_theap_stat_increase(current_theap, pages_abandoned, 1);\n  }\n  mi_abandoned_page_unown(page, current_theap);\n}\n\n\n// this is called from `free.c:mi_free_try_collect_mt` only.\nbool _mi_arenas_page_try_reabandon_to_mapped(mi_page_t* page) {\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n  mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_assert_internal(!mi_page_is_abandoned_mapped(page));\n  mi_assert_internal(!mi_page_is_full(page));\n  mi_assert_internal(!mi_page_all_free(page));\n  mi_assert_internal(!mi_page_is_singleton(page));\n  if (mi_page_is_full(page) || mi_page_is_abandoned_mapped(page) || page->memid.memkind != MI_MEM_ARENA) {\n    return false;\n  }\n  else {\n    // do not use _mi_heap_theap as we may call this during shutdown of threads and don't want to reinitialize the theap\n    mi_theap_t* const theap = _mi_page_associated_theap_peek(page);\n    if (theap == NULL) {\n      return false;\n    }\n    else {\n      mi_theap_stat_counter_increase(theap, pages_reabandon_full, 1);\n      mi_theap_stat_adjust_decrease(theap, pages_abandoned, 1);  // adjust as we are not abandoning fresh\n      _mi_arenas_page_abandon(page, theap);\n      return true;\n    }\n  }\n}\n\n// called from `mi_free` if trying to unabandon an abandoned page\nvoid _mi_arenas_page_unabandon(mi_page_t* page, mi_theap_t* current_theapx) {\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n  mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_assert_internal(current_theapx==NULL || _mi_thread_id()==current_theapx->tld->thread_id);\n\n  mi_heap_t* const heap = mi_page_heap(page);\n  if (mi_page_is_abandoned_mapped(page)) {\n    mi_assert_internal(page->memid.memkind==MI_MEM_ARENA);\n    // remove from the abandoned map\n    size_t bin = _mi_bin(mi_page_block_size(page));\n    size_t slice_index;\n    size_t slice_count;\n    mi_arena_pages_t* arena_pages;\n    mi_arena_t* arena = mi_page_arena_pages(page, &slice_index, &slice_count, &arena_pages);  MI_UNUSED(arena);\n\n    mi_assert_internal(mi_bbitmap_is_clearN(arena->slices_free, slice_index, slice_count));\n    mi_assert_internal(page->slice_committed > 0 || mi_bitmap_is_setN(arena->slices_committed, slice_index, slice_count));\n\n    // this busy waits until a concurrent reader (from alloc_abandoned) is done\n    mi_bitmap_clear_once_set(arena_pages->pages_abandoned[bin], slice_index);\n    mi_page_clear_abandoned_mapped(page);\n    mi_atomic_decrement_relaxed(&heap->abandoned_count[bin]);\n  }\n  else {\n    // page is full (or a singleton), page is OS allocated\n    // if not an arena page, remove from the subproc os pages list\n    if (page->memid.memkind != MI_MEM_ARENA && mi_option_is_enabled(mi_option_visit_abandoned)) {\n      mi_lock(&heap->os_abandoned_pages_lock) {\n        if (page->prev != NULL) { page->prev->next = page->next; }\n        if (page->next != NULL) { page->next->prev = page->prev; }\n        if (heap->os_abandoned_pages == page) { heap->os_abandoned_pages = page->next; }\n        page->next = NULL;\n        page->prev = NULL;\n      }\n    }\n  }\n  if (current_theapx!=NULL) {\n    mi_theap_stat_decrease(current_theapx, pages_abandoned, 1);\n  }\n  else {\n    mi_heap_stat_decrease(heap, pages_abandoned, 1);\n  }\n}\n\n\n/* -----------------------------------------------------------\n  Arena free\n----------------------------------------------------------- */\nstatic void mi_arena_schedule_purge(mi_arena_t* arena, size_t slice_index, size_t slices);\nstatic void mi_arenas_try_purge(bool force, bool visit_all, mi_subproc_t* subproc, size_t tseq);\n\nvoid _mi_arenas_free(void* p, size_t size, mi_memid_t memid) {\n  if (p==NULL) return;\n  if (size==0) return;\n\n  // need to set all memory to undefined as some parts may still be marked as no_access (like padding etc.)\n  mi_track_mem_undefined(p, size);\n\n  if (mi_memkind_is_os(memid.memkind)) {\n    // was a direct OS allocation, pass through\n    _mi_os_free(p, size, memid);\n  }\n  else if (memid.memkind == MI_MEM_ARENA) {\n    // allocated in an arena\n    size_t slice_count;\n    size_t slice_index;\n    mi_arena_t* arena = mi_arena_from_memid(memid, &slice_index, &slice_count);\n    mi_assert_internal((size%MI_ARENA_SLICE_SIZE)==0);\n    mi_assert_internal((slice_count*MI_ARENA_SLICE_SIZE)==size);\n    mi_assert_internal(mi_arena_slice_start(arena,slice_index) <= (uint8_t*)p);\n    mi_assert_internal(mi_arena_slice_start(arena,slice_index) + mi_size_of_slices(slice_count) > (uint8_t*)p);\n    // checks\n    if (arena == NULL) {\n      _mi_error_message(EINVAL, \"trying to free from an invalid arena: %p, size %zu, memid: 0x%zx\\n\", p, size, memid);\n      return;\n    }\n    mi_assert_internal(slice_index < arena->slice_count);\n    mi_assert_internal(slice_index >= mi_arena_info_slices(arena));\n    if (slice_index < mi_arena_info_slices(arena) || slice_index >= arena->slice_count) {\n      _mi_error_message(EINVAL, \"trying to free from an invalid arena block: %p, size %zu, memid: 0x%zx\\n\", p, size, memid);\n      return;\n    }\n\n    // potentially decommit\n    if (!arena->memid.is_pinned /* && !arena->memid.initially_committed */) { // todo: allow decommit even if initially committed?\n      // (delay) purge the page\n      mi_arena_schedule_purge(arena, slice_index, slice_count);\n    }\n\n    // and make it available to others again\n    bool all_inuse = mi_bbitmap_setN(arena->slices_free, slice_index, slice_count);\n    if (!all_inuse) {\n      _mi_error_message(EAGAIN, \"trying to free an already freed arena block: %p, size %zu\\n\", mi_arena_slice_start(arena,slice_index), mi_size_of_slices(slice_count));\n      return;\n    };\n  }\n  else if (memid.memkind == MI_MEM_META) {\n    _mi_meta_free(p, size, memid);\n  }\n  else {\n    // arena was none, external, or static; nothing to do\n    mi_assert_internal(mi_memid_needs_no_free(memid));\n  }\n\n  // try to purge expired decommits\n  // mi_arenas_try_purge(false, false, NULL);\n}\n\n// Purge the arenas; if `force_purge` is true, amenable parts are purged even if not yet expired\nvoid _mi_arenas_collect(bool force_purge, bool visit_all, mi_tld_t* tld) {\n  mi_arenas_try_purge(force_purge, visit_all, tld->subproc, tld->thread_seq);\n}\n\n\n// Is a pointer contained in the given arena area?\nstatic bool mi_arena_strictly_contains(mi_arena_t* arena, const void* p) {\n  return (arena != NULL &&\n          mi_arena_start(arena) <= (const uint8_t*)p &&\n          mi_arena_start(arena) + mi_size_of_slices(arena->slice_count) >(const uint8_t*)p);\n}\n\n// Is a pointer inside any of our arenas?\nstatic bool mi_arenas_contain_ex(const void* p, mi_arena_t* parent) {\n  mi_subproc_t* subproc = _mi_subproc();\n  const size_t max_arena = mi_arenas_get_count(subproc);\n  for (size_t i = 0; i < max_arena; i++) {\n    mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &subproc->arenas[i]);\n    if (arena != NULL) {\n      if (parent==NULL || arena==parent || arena->parent==parent) {\n        if (mi_arena_strictly_contains(arena, p)) {\n          return true;\n        }\n      }\n    }\n  }\n  return false;\n}\n\n// Is a pointer inside any of our arenas?\nbool _mi_arenas_contain(const void* p) {\n  return mi_arenas_contain_ex(p, NULL);\n}\n\n// Is a pointer contained in the given arena area?\nbool mi_arena_contains(mi_arena_id_t arena_id, const void* p) {\n  mi_arena_t* arena = _mi_arena_from_id(arena_id);\n  if (arena==NULL) return false;\n  else if (mi_arena_strictly_contains(arena, p)) return true;\n  else return mi_arenas_contain_ex(p, arena);  // maybe a subarena?\n}\n\n\n/* -----------------------------------------------------------\n  Remove an arena.\n----------------------------------------------------------- */\n\n// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit`\n// for dynamic libraries that are unloaded and need to release all their allocated memory.\nstatic void mi_arenas_unsafe_destroy(mi_subproc_t* subproc) {\n  mi_assert_internal(subproc != NULL);\n  const size_t arena_count = mi_arenas_get_count(subproc);\n  for (size_t i = 0; i < arena_count; i++) {\n    mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &subproc->arenas[i]);\n    if (arena != NULL) {\n      // mi_lock_done(&arena->abandoned_visit_lock);\n      mi_atomic_store_ptr_release(mi_arena_t, &subproc->arenas[i], NULL);\n      if (mi_memkind_is_os(arena->memid.memkind)) {\n        _mi_os_free_ex(mi_arena_start(arena), mi_arena_size(arena), true, arena->memid, subproc); // pass `subproc` to avoid accessing the theap pointer (in `_mi_subproc()`)\n      }\n    }\n  }\n  // try to lower the max arena.\n  size_t expected = arena_count;\n  mi_atomic_cas_strong_acq_rel(&subproc->arena_count, &expected, (size_t)0);\n}\n\n\n// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit`\n// for dynamic libraries that are unloaded and need to release all their allocated memory.\nvoid _mi_arenas_unsafe_destroy_all(mi_subproc_t* subproc) {\n  mi_arenas_unsafe_destroy(subproc);\n  // mi_arenas_try_purge(true /* force purge */, true /* visit all*/, subproc, 0 /* thread seq */);  // purge non-owned arenas\n}\n\n\n/* -----------------------------------------------------------\n  Add an arena.\n----------------------------------------------------------- */\n\nstatic bool mi_arenas_add(mi_subproc_t* subproc, mi_arena_t* arena, mi_arena_id_t* arena_id)\n{\n  mi_assert_internal(arena != NULL);\n  mi_assert_internal(arena->slice_count > 0);\n  if (arena_id != NULL) { *arena_id = _mi_arena_id_none(); }\n\n  // try to find a NULL entry\n  mi_arena_t* expected;\n  size_t count = mi_arenas_get_count(subproc);\n  for( size_t i = 0; i < count; i++) {\n    if (mi_arena_from_index(subproc,i) == NULL) {\n      arena->arena_idx = i;\n      expected = NULL;\n      if (mi_atomic_cas_ptr_strong_release(mi_arena_t, &subproc->arenas[i], &expected, arena)) {\n        // success\n        if (arena_id != NULL) { *arena_id = mi_arena_id_from_arena(arena); }\n        return true;\n      }\n    }\n  }\n\n  // otherwise, try to allocate a fresh slot\n  while(count<MI_MAX_ARENAS) {\n    if (mi_atomic_cas_strong_release(&subproc->arena_count, &count, count+1)) {\n      arena->arena_idx = count;\n      expected = NULL;\n      if (mi_atomic_cas_ptr_strong_release(mi_arena_t, &subproc->arenas[count], &expected, arena)) {\n        mi_subproc_stat_counter_increase(arena->subproc, arena_count, 1);\n        if (arena_id != NULL) { *arena_id = mi_arena_id_from_arena(arena); }\n        return true;\n      }\n    }\n  }\n\n  // failed\n  arena->arena_idx = 0;\n  arena->subproc = NULL;\n  return false;\n}\n\nstatic size_t mi_arena_pages_size(size_t slice_count, size_t* bitmap_base) {\n  if (slice_count == 0) slice_count = MI_BCHUNK_BITS;\n  mi_assert_internal((slice_count % MI_BCHUNK_BITS) == 0);\n  const size_t base_size = _mi_align_up(sizeof(mi_arena_pages_t), MI_BCHUNK_SIZE);\n  const size_t bitmaps_count = 1 + MI_ARENA_BIN_COUNT; // pages, and abandoned\n  const size_t bitmaps_size = bitmaps_count * mi_bitmap_size(slice_count, NULL);\n  const size_t size = base_size + bitmaps_size;\n  if (bitmap_base != NULL) *bitmap_base = base_size;\n  return size;\n}\n\nstatic size_t mi_arena_info_slices_needed(size_t slice_count, size_t* bitmap_base) {\n  if (slice_count == 0) slice_count = MI_BCHUNK_BITS;\n  mi_assert_internal((slice_count % MI_BCHUNK_BITS) == 0);\n  const size_t base_size = _mi_align_up(sizeof(mi_arena_t), MI_BCHUNK_SIZE);\n  const size_t bitmaps_count = 4 + MI_ARENA_BIN_COUNT; // commit, dirty, purge, pages, and abandoned\n  const size_t bitmaps_size = bitmaps_count * mi_bitmap_size(slice_count, NULL) + mi_bbitmap_size(slice_count, NULL); // + free\n  #if MI_PAGE_META_IS_SEPARATED\n  const size_t pages_size = slice_count * sizeof(mi_page_t);\n  #else\n  const size_t pages_size = 0;\n  #endif\n  const size_t size = base_size + bitmaps_size + pages_size;\n\n  const size_t os_page_size = _mi_os_page_size();\n  const size_t info_size = _mi_align_up(size, os_page_size) + _mi_os_secure_guard_page_size();\n  const size_t info_slices = mi_slice_count_of_size(info_size);\n\n  if (bitmap_base != NULL) *bitmap_base = base_size;\n  return info_slices;\n}\n\nstatic mi_bitmap_t* mi_arena_bitmap_init(size_t slice_count, uint8_t** base) {\n  mi_bitmap_t* bitmap = (mi_bitmap_t*)(*base);\n  *base = (*base) + mi_bitmap_init(bitmap, slice_count, true /* already zero */);\n  return bitmap;\n}\n\nstatic mi_bbitmap_t* mi_arena_bbitmap_init(size_t slice_count, uint8_t** base) {\n  mi_bbitmap_t* bbitmap = (mi_bbitmap_t*)(*base);\n  *base = (*base) + mi_bbitmap_init(bbitmap, slice_count, true /* already zero */);\n  return bbitmap;\n}\n\nstatic mi_arena_pages_t* mi_arena_pages_alloc(mi_arena_t* arena) {\n  const size_t slice_count = arena->slice_count;\n  size_t bitmap_base = 0;\n  const size_t size = mi_arena_pages_size(slice_count, &bitmap_base);\n  mi_arena_pages_t* arena_pages = (mi_arena_pages_t*)mi_heap_zalloc_aligned(mi_heap_main(), size, MI_BCHUNK_SIZE);\n  if (arena_pages==NULL) return NULL;\n  uint8_t* base = (uint8_t*)arena_pages + bitmap_base;\n  mi_assert_internal(_mi_is_aligned(base, MI_BCHUNK_SIZE));\n  arena_pages->pages = mi_arena_bitmap_init(slice_count, &base);\n  for (size_t i = 0; i < MI_ARENA_BIN_COUNT; i++) {\n    arena_pages->pages_abandoned[i] = mi_arena_bitmap_init(slice_count, &base);\n  }\n  return arena_pages;\n}\n\nstatic mi_arena_t* mi_arena_initialize(mi_subproc_t* subproc, void* start,\n                                        size_t slice_count, mi_arena_t* parent, size_t total_size,\n                                        int numa_node, bool exclusive,\n                                        mi_memid_t memid, mi_commit_fun_t* commit_fun, void* commit_fun_arg, mi_arena_id_t* arena_id)\n{\n  mi_assert_internal(_mi_is_aligned(start,MI_ARENA_SLICE_ALIGN));\n  mi_assert_internal(mi_size_of_slices(slice_count)>=MI_ARENA_MIN_SIZE);\n\n  if (slice_count > MI_BITMAP_MAX_BIT_COUNT) {  // 16 GiB for now\n    // note: this should never happen if called from `mi_manage_os_memory` (as that allocates sub-arenas when needed)\n    _mi_warning_message(\"cannot use OS memory since it is too large (size %zu MiB, maximum is %zu MiB)\", mi_size_of_slices(slice_count)/MI_MiB, mi_size_of_slices(MI_BITMAP_MAX_BIT_COUNT)/MI_MiB);\n    return NULL;\n  }\n\n  size_t bitmap_base;\n  const size_t info_slices = mi_arena_info_slices_needed(slice_count, &bitmap_base);\n  if (slice_count < info_slices+1) {\n    _mi_warning_message(\"cannot use OS memory since it is not large enough (size %zu KiB, minimum required is %zu KiB)\", mi_size_of_slices(slice_count)/MI_KiB, mi_size_of_slices(info_slices+1)/MI_KiB);\n    return NULL;\n  }\n  else if (info_slices >= MI_ARENA_MAX_CHUNK_OBJ_SLICES) {\n    _mi_warning_message(\"cannot use OS memory since it is too large with respect to the maximum object size (size %zu MiB, meta-info slices %zu, maximum object slices are %zu)\", mi_size_of_slices(slice_count)/MI_MiB, info_slices, MI_ARENA_MAX_CHUNK_OBJ_SLICES);\n    return NULL;\n  }\n\n  mi_arena_t* arena = (mi_arena_t*)start;\n\n  // commit & zero if needed\n  if (!memid.initially_committed) {\n    size_t commit_size = mi_size_of_slices(info_slices);\n    // leave a guard OS page decommitted at the end?\n    if (!memid.is_pinned) { commit_size -= _mi_os_secure_guard_page_size(); }\n    bool ok = false;\n    if (commit_fun != NULL) {\n      ok = (*commit_fun)(true /* commit */, arena, commit_size, NULL, commit_fun_arg);\n    }\n    else {\n      ok = _mi_os_commit(arena, commit_size, NULL);\n    }\n    if (!ok) {\n      _mi_warning_message(\"unable to commit meta-data for OS memory\");\n      return NULL;\n    }\n  }\n  else if (!memid.is_pinned) {\n    // if MI_SECURE, set a guard page at the end of the arena info\n    // todo: this does not respect the commit_fun as the memid is of external memory\n    _mi_os_secure_guard_page_set_before((uint8_t*)arena + mi_size_of_slices(info_slices), memid);\n  }\n  if (!memid.initially_zero) {\n    _mi_memzero(arena, mi_size_of_slices(info_slices) - _mi_os_secure_guard_page_size());\n  }\n\n  // init\n  arena->subproc = subproc;\n  arena->memid = memid;\n  arena->is_exclusive = exclusive;\n  arena->slice_count = slice_count;\n  arena->info_slices = info_slices;\n  if (numa_node<0 && mi_option_is_enabled(mi_option_arena_is_numa_local)) {\n    arena->numa_node = _mi_os_numa_node();\n  }\n  else {\n    arena->numa_node = numa_node;\n  }\n  arena->purge_expire = 0;\n  arena->commit_fun = commit_fun;\n  arena->commit_fun_arg = commit_fun_arg;\n  arena->parent = parent;\n  arena->total_size = total_size;\n\n  // init bitmaps\n  uint8_t* base = mi_arena_start(arena) + bitmap_base;\n  arena->slices_free = mi_arena_bbitmap_init(slice_count, &base);\n  arena->slices_committed = mi_arena_bitmap_init(slice_count, &base);\n  arena->slices_dirty = mi_arena_bitmap_init(slice_count, &base);\n  arena->slices_purge = mi_arena_bitmap_init(slice_count, &base);\n  arena->pages_main.pages = mi_arena_bitmap_init(slice_count, &base);\n  for (size_t i = 0; i < MI_ARENA_BIN_COUNT; i++) {\n    arena->pages_main.pages_abandoned[i] = mi_arena_bitmap_init(slice_count, &base);\n  }\n  #if MI_PAGE_META_IS_SEPARATED\n  arena->pages_meta = (mi_page_t*)base;\n  base += (slice_count * sizeof(mi_page_t));\n  #else\n  arena->pages_meta = NULL;\n  #endif\n  mi_assert_internal(mi_size_of_slices(info_slices) >= (size_t)(base - mi_arena_start(arena)));\n\n  // reserve our meta info (and reserve slices outside the memory area)\n  mi_bbitmap_unsafe_setN(arena->slices_free, info_slices /* start */, arena->slice_count - info_slices);\n  if (memid.initially_committed) {\n    mi_bitmap_unsafe_setN(arena->slices_committed, 0, arena->slice_count);\n  }\n  if (!memid.initially_zero) {\n    mi_bitmap_unsafe_setN(arena->slices_dirty, 0, arena->slice_count);\n  }\n\n  if (!mi_arenas_add(subproc, arena, arena_id)) { return NULL;  }\n  return arena;\n}\n\nstatic bool mi_manage_os_memory_ex2(mi_subproc_t* subproc, void* start, size_t size, int numa_node, bool exclusive,\n  mi_memid_t memid, mi_commit_fun_t* commit_fun, void* commit_fun_arg, mi_arena_id_t* arena_id) mi_attr_noexcept\n{\n  // checks\n  mi_assert(_mi_is_aligned(start, MI_ARENA_SLICE_SIZE));\n  mi_assert(start!=NULL);\n  if (arena_id != NULL) { *arena_id = _mi_arena_id_none(); }\n  if (start==NULL) return false;\n  if (!_mi_is_aligned(start, MI_ARENA_SLICE_SIZE)) {\n    // we can align the start since the memid tracks the real base of the memory.\n    void* const aligned_start = _mi_align_up_ptr(start, MI_ARENA_SLICE_SIZE);\n    const size_t diff = (uint8_t*)aligned_start - (uint8_t*)start;\n    if (diff >= size || (size - diff) < MI_ARENA_SLICE_SIZE) {\n      _mi_warning_message(\"after alignment, the size of the arena becomes too small (memory at %p with size %zu)\\n\", start, size);\n      return false;\n    }\n    start = aligned_start;\n    size = size - diff;\n  }\n\n  // allocate enough arena's to span the full memory area\n  // the first arena is the owner, the rest are \"sub-arena\" (with `parent` pointing to the first one)\n  size_t total_slice_count = _mi_align_down(size / MI_ARENA_SLICE_SIZE, MI_BCHUNK_BITS);\n  size_t total_size = mi_size_of_slices(total_slice_count);\n  if (total_size < MI_ARENA_MIN_SIZE) {\n    _mi_warning_message(\"cannot use OS memory since it is not large enough (size %zu KiB, minimum required is %zu KiB)\", size/MI_KiB, MI_ARENA_MIN_SIZE/MI_KiB);\n    return false;\n  }\n\n  mi_arena_t* parent = NULL;\n  do {\n    // counting down on the total_slice_count\n    size_t slice_count = total_slice_count;\n    if (slice_count > MI_BITMAP_MAX_BIT_COUNT) {  // 16 GiB for now (with 64KiB slices)\n      slice_count = MI_BITMAP_MAX_BIT_COUNT;\n    }\n\n    // initialize\n    mi_arena_t* arena = mi_arena_initialize( subproc, start, slice_count, parent,\n                                              (parent==NULL ? total_size : 0), numa_node, exclusive,\n                                              memid, commit_fun, commit_fun_arg,\n                                              (parent==NULL ? arena_id : NULL));\n    if (arena==NULL) {\n      // failed to initialize due to failing commit or too many arena's\n      if (parent==NULL) {\n        return false;\n      }\n      else {\n        // partial success, but failed to use the full area..\n        // todo: roll-back in this case? that requires a lock on the arena's array though\n        mi_assert(mi_size_of_slices(total_slice_count) <= parent->total_size);\n        parent->total_size -= mi_size_of_slices(total_slice_count);\n        return true;\n      }\n    }\n\n    // success\n    if (parent==NULL) {\n      parent = arena;\n      memid.memkind = MI_MEM_NONE;\n    }\n    mi_assert(slice_count <= total_slice_count);\n    total_slice_count -= slice_count;\n    start = (uint8_t*)start + mi_size_of_slices(slice_count);\n  }\n  while (total_slice_count > 0);\n\n  return true;\n}\n\nbool mi_manage_os_memory_ex(void* start, size_t size, bool is_committed, bool is_pinned, bool is_zero, int numa_node, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept {\n  mi_memid_t memid = _mi_memid_create(MI_MEM_EXTERNAL);\n  memid.mem.os.base = start;\n  memid.mem.os.size = size;\n  memid.initially_committed = is_committed;\n  memid.initially_zero = is_zero;\n  memid.is_pinned = is_pinned;\n  return mi_manage_os_memory_ex2(_mi_subproc(), start, size, numa_node, exclusive, memid, NULL, NULL, arena_id);\n}\n\nbool mi_manage_memory(void* start, size_t size, bool is_committed, bool is_pinned, bool is_zero, int numa_node, bool exclusive, mi_commit_fun_t* commit_fun, void* commit_fun_arg, mi_arena_id_t* arena_id) mi_attr_noexcept\n{\n  mi_memid_t memid = _mi_memid_create(MI_MEM_EXTERNAL);\n  memid.mem.os.base = start;\n  memid.mem.os.size = size;\n  memid.initially_committed = is_committed;\n  memid.initially_zero = is_zero;\n  memid.is_pinned = is_pinned;\n  return mi_manage_os_memory_ex2(_mi_subproc(), start, size, numa_node, exclusive, memid, commit_fun, commit_fun_arg, arena_id);\n}\n\n\n// Reserve a range of regular OS memory\nstatic int mi_reserve_os_memory_ex2(mi_subproc_t* subproc, size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id) {\n  if (arena_id != NULL) *arena_id = _mi_arena_id_none();\n  size = _mi_align_up(size, MI_ARENA_SLICE_SIZE); // at least one slice\n  mi_memid_t memid;\n  void* start = _mi_os_alloc_aligned(size, MI_ARENA_SLICE_ALIGN, commit, allow_large, &memid);\n  if (start == NULL) return ENOMEM;\n  if (!mi_manage_os_memory_ex2(subproc, start, size, -1 /* numa node */, exclusive, memid, NULL, NULL, arena_id)) {\n    _mi_os_free_ex(start, size, commit, memid, NULL);\n    _mi_verbose_message(\"failed to reserve %zu KiB memory\\n\", _mi_divide_up(size, 1024));\n    return ENOMEM;\n  }\n  _mi_verbose_message(\"reserved %zu KiB memory%s\\n\", _mi_divide_up(size, 1024), memid.is_pinned ? \" (in large os pages)\" : \"\");\n  // mi_debug_show_arenas(true, true, false);\n\n  return 0;\n}\n\n// Reserve a range of regular OS memory\nint mi_reserve_os_memory_ex(size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept {\n  return mi_reserve_os_memory_ex2(_mi_subproc(), size, commit, allow_large, exclusive, arena_id);\n}\n\n// Manage a range of regular OS memory\nbool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept {\n  return mi_manage_os_memory_ex(start, size, is_committed, is_large, is_zero, numa_node, false /* exclusive? */, NULL);\n}\n\n// Reserve a range of regular OS memory\nint mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept {\n  return mi_reserve_os_memory_ex(size, commit, allow_large, false, NULL);\n}\n\n\n/* -----------------------------------------------------------\n  Debugging\n----------------------------------------------------------- */\n\n// Return idx of the slice past the last used slice\nstatic size_t mi_arena_used_slices(mi_arena_t* arena) {\n  size_t idx;\n  if (mi_bbitmap_bsr_inv(arena->slices_free, &idx)) {\n    return (idx + 1);\n  }\n  else {\n    return mi_arena_info_slices(arena);\n  }\n}\n\nstatic size_t mi_debug_show_bfield(mi_bfield_t field, char* buf, size_t* k) {\n  size_t bit_set_count = 0;\n  for (int bit = 0; bit < MI_BFIELD_BITS; bit++) {\n    bool is_set = ((((mi_bfield_t)1 << bit) & field) != 0);\n    if (is_set) bit_set_count++;\n    buf[*k] = (is_set ? 'x' : '.');\n    *k = *k + 1;\n  }\n  return bit_set_count;\n}\n\ntypedef enum mi_ansi_color_e {\n  MI_BLACK = 30,\n  MI_MAROON,\n  MI_DARKGREEN,\n  MI_ORANGE,\n  MI_NAVY,\n  MI_PURPLE,\n  MI_TEAL,\n  MI_GRAY,\n  MI_DARKGRAY = 90,\n  MI_RED,\n  MI_GREEN,\n  MI_YELLOW,\n  MI_BLUE,\n  MI_MAGENTA,\n  MI_CYAN,\n  MI_WHITE\n} mi_ansi_color_t;\n\nstatic void mi_debug_color(char* buf, size_t* k, mi_ansi_color_t color) {\n  *k += _mi_snprintf(buf + *k, 32, \"\\x1B[%dm\", (int)color);\n}\n\nstatic int mi_page_commit_usage(mi_page_t* page) {\n  // if (mi_page_size(page) <= MI_PAGE_MIN_COMMIT_SIZE) return 100;\n  const size_t committed_size = mi_page_committed(page);\n  const size_t used_size = page->used * mi_page_block_size(page);\n  return (int)(used_size * 100 / committed_size);\n}\n\nstatic size_t mi_debug_show_page_bfield(char* buf, size_t* k, mi_arena_t* arena, size_t slice_index, long* pbit_of_page, mi_ansi_color_t* pcolor_of_page ) {\n  size_t bit_set_count = 0;\n  long bit_of_page = *pbit_of_page;\n  mi_ansi_color_t color = *pcolor_of_page;\n  mi_ansi_color_t prev_color = MI_GRAY;\n  for (int bit = 0; bit < MI_BFIELD_BITS; bit++, bit_of_page--) {\n    // bool is_set = ((((mi_bfield_t)1 << bit) & field) != 0);\n    void* start = mi_arena_slice_start(arena, slice_index + bit);\n    mi_page_t* page = _mi_safe_ptr_page(start);\n    char c = ' ';\n    if (page!=NULL && start==mi_page_slice_start(page)) {\n      mi_assert_internal(bit_of_page <= 0);\n      bit_set_count++;\n      c = 'p';\n      color = MI_GRAY;\n      if (mi_page_is_singleton(page)) { c = 's'; }\n      else if (mi_page_is_full(page)) { c = 'f'; }\n      if (!mi_page_is_abandoned(page)) { c = _mi_toupper(c); }\n      int commit_usage = mi_page_commit_usage(page);\n      if (commit_usage < 25) { color = MI_MAROON; }\n      else if (commit_usage < 50) { color = MI_ORANGE; }\n      else if (commit_usage < 75) { color = MI_TEAL; }\n      else color = MI_DARKGREEN;\n      bit_of_page = (long)page->memid.mem.arena.slice_count;\n    }\n    else {\n      c = '?';\n      if (bit_of_page > 0) { c = '-'; }\n      else if (_mi_meta_is_meta_page(start)) { c = 'm'; color = MI_GRAY; }\n      else if (slice_index + bit < arena->info_slices) { c = 'i'; color = MI_GRAY; }\n      // else if (mi_bitmap_is_setN(arena->pages_purge, slice_index + bit, NULL)) { c = '*'; }\n      else if (mi_bbitmap_is_setN(arena->slices_free, slice_index+bit,1)) {\n        if (mi_bitmap_is_set(arena->slices_purge, slice_index + bit)) { c = '~'; color = MI_ORANGE; }\n        else if (mi_bitmap_is_set(arena->slices_committed, slice_index + bit)) { c = '_'; color = MI_GRAY; }\n        else { c = '.'; color = MI_GRAY; }\n      }\n      if (bit==MI_BFIELD_BITS-1 && bit_of_page > 1) { c = '>'; }\n    }\n    if (color != prev_color) {\n      mi_debug_color(buf, k, color);\n      prev_color = color;\n    }\n    buf[*k] = c; *k += 1;\n  }\n  mi_debug_color(buf, k, MI_GRAY);\n  *pbit_of_page = bit_of_page;\n  *pcolor_of_page = color;\n  return bit_set_count;\n}\n\nstatic size_t mi_debug_show_chunks(const char* header1, const char* header2, const char* header3,\n                                   size_t slice_count, size_t chunk_count,\n                                   mi_bchunk_t* chunks, mi_bchunkmap_t* chunk_bins, bool invert, mi_arena_t* arena, bool narrow)\n{\n  _mi_raw_message(\"\\x1B[37m%s%s%s (use/commit: \\x1B[31m0 - 25%%\\x1B[33m - 50%%\\x1B[36m - 75%%\\x1B[32m - 100%%\\x1B[0m)\\n\", header1, header2, header3);\n  const size_t fields_per_line = (narrow ? 2 : 4);\n  const size_t used_slice_count = mi_arena_used_slices(arena);\n  size_t bit_count = 0;\n  size_t bit_set_count = 0;\n  long bit_of_page = 0;\n  mi_ansi_color_t color_of_page = MI_GRAY;\n  for (size_t i = 0; i < chunk_count && bit_count < slice_count; i++) {\n    char buf[5*MI_BCHUNK_BITS + 64]; _mi_memzero(buf, sizeof(buf));\n    if (bit_count > used_slice_count && i+2 < chunk_count) {\n      const size_t diff = chunk_count - 1 - i;\n      bit_count += diff*MI_BCHUNK_BITS;\n      _mi_raw_message(\"  |\\n\");\n      i = chunk_count-1;\n    }\n\n    size_t k = 0;\n\n    if (i<10)        { buf[k++] = ('0' + (char)i); buf[k++] = ' '; buf[k++] = ' '; }\n    else if (i<100)  { buf[k++] = ('0' + (char)(i/10)); buf[k++] = ('0' + (char)(i%10)); buf[k++] = ' '; }\n    else if (i<1000) { buf[k++] = ('0' + (char)(i/100)); buf[k++] = ('0' + (char)((i%100)/10)); buf[k++] = ('0' + (char)(i%10)); }\n\n    char chunk_kind = ' ';\n    if (chunk_bins != NULL) {\n      switch (mi_bbitmap_debug_get_bin(chunk_bins,i)) {\n        case MI_CBIN_SMALL:  chunk_kind = 'S'; break;\n        case MI_CBIN_MEDIUM: chunk_kind = 'M'; break;\n        case MI_CBIN_LARGE:  chunk_kind = 'L'; break;\n        case MI_CBIN_HUGE:   chunk_kind = 'H'; break;\n        case MI_CBIN_OTHER:  chunk_kind = 'X'; break;\n        default: chunk_kind = ' '; break; // suppress warning\n        // case MI_CBIN_NONE: chunk_kind = 'N'; break;\n      }\n    }\n    buf[k++] = chunk_kind;\n    buf[k++] = ' ';\n\n    for (size_t j = 0; j < MI_BCHUNK_FIELDS; j++) {\n      if (j > 0 && (j % fields_per_line) == 0) {\n        // buf[k++] = '\\n'; _mi_memset(buf+k,' ',7); k += 7;\n        _mi_raw_message(\"  %s\\n\\x1B[37m\", buf);\n        _mi_memzero(buf, sizeof(buf));\n        _mi_memset(buf, ' ', 5); k = 5;\n      }\n      if (bit_count < slice_count) {\n        mi_bfield_t bfield = 0;\n        if (chunks!=NULL) {\n          bfield = chunks[i].bfields[j];\n        }\n        if (invert) bfield = ~bfield;\n        size_t xcount = (chunks==NULL ? mi_debug_show_page_bfield(buf, &k, arena, bit_count, &bit_of_page, &color_of_page)\n                                      : mi_debug_show_bfield(bfield, buf, &k));\n        if (invert) xcount = MI_BFIELD_BITS - xcount;\n        bit_set_count += xcount;\n        buf[k++] = ' ';\n      }\n      else {\n        _mi_memset(buf + k, 'o', MI_BFIELD_BITS);\n        k += MI_BFIELD_BITS;\n      }\n      bit_count += MI_BFIELD_BITS;\n    }\n    _mi_raw_message(\"  %s\\n\\x1B[37m\", buf);\n  }\n  _mi_raw_message(\"\\x1B[0m  total pages: %zu\\n\", bit_set_count);\n  return bit_set_count;\n}\n\n//static size_t mi_debug_show_bitmap_binned(const char* header1, const char* header2, const char* header3, size_t slice_count,\n//                                           mi_bitmap_t* bitmap, mi_bchunkmap_t* chunk_bins, bool invert, mi_arena_t* arena, bool narrow) {\n//  return mi_debug_show_chunks(header1, header2, header3, slice_count, mi_bitmap_chunk_count(bitmap), &bitmap->chunks[0], chunk_bins, invert, arena, narrow);\n//}\n\nstatic void mi_debug_show_arenas_ex(mi_heap_t* heap, bool show_pages, bool narrow) mi_attr_noexcept {\n  mi_subproc_t* subproc = heap->subproc;\n  size_t max_arenas = mi_arenas_get_count(subproc);\n  //size_t free_total = 0;\n  //size_t slice_total = 0;\n  //size_t abandoned_total = 0;\n  size_t page_total = 0;\n  for (size_t i = 0; i < max_arenas; i++) {\n    mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &subproc->arenas[i]);\n    if (arena == NULL) break;\n    mi_assert(arena->subproc == subproc);\n    // slice_total += arena->slice_count;\n    _mi_raw_message(\"%sarena %zu at %p: %zu slices (%zu MiB)%s%s, subproc: %p, numa: %i\\n\",\n        (arena->parent==NULL ? \"\" : \"(sub)\"), i, arena, arena->slice_count, (size_t)(mi_size_of_slices(arena->slice_count)/MI_MiB),\n        (arena->memid.is_pinned ? \", pinned\" : \"\"), (arena->is_exclusive ? \", exclusive\" : \"\"),\n        arena->subproc, arena->numa_node);\n    //if (show_inuse) {\n    //  free_total += mi_debug_show_bbitmap(\"in-use slices\", arena->slice_count, arena->slices_free, true, NULL);\n    //}\n    //if (show_committed) {\n    //  mi_debug_show_bitmap(\"committed slices\", arena->slice_count, arena->slices_committed, false, NULL);\n    //}\n    // todo: abandoned slices\n    //if (show_purge) {\n    //  purge_total += mi_debug_show_bitmap(\"purgeable slices\", arena->slice_count, arena->slices_purge, false, NULL);\n    //}\n    if (show_pages) {\n      // mi_arena_pages_t* arena_pages = mi_heap_arena_pages(heap, arena);\n      // if (arena_pages != NULL)\n      {\n        const char* header1 = \"chunks (p:page, f:full, s:singleton, P,F,S:not abandoned, i:arena-info, m:meta-data, ~:free-purgable, _:free-committed, .:free-reserved)\";\n        const char* header2 = (narrow ? \"\\n       \" : \" \");\n        const char* header3 = \"(chunk bin: S:small, M : medium, L : large, X : other)\";\n        page_total += mi_debug_show_chunks(header1, header2, header3, arena->slice_count,\n                                           mi_bbitmap_chunk_count(arena->slices_free), NULL,\n                                           arena->slices_free->chunkmap_bins, false, arena, narrow);\n      }\n    }\n  }\n  // if (show_inuse)     _mi_raw_message(\"total inuse slices    : %zu\\n\", slice_total - free_total);\n  // if (show_abandoned) _mi_raw_message(\"total abandoned slices: %zu\\n\", abandoned_total);\n  if (show_pages) _mi_raw_message(\"total pages in arenas: %zu\\n\", page_total);\n}\n\nvoid mi_debug_show_arenas(void) mi_attr_noexcept {\n  mi_debug_show_arenas_ex(mi_heap_main(), true /* show pages */, true /* narrow? */);\n}\n\nvoid mi_arenas_print(void) mi_attr_noexcept {\n  mi_debug_show_arenas();\n}\n\n\n/* -----------------------------------------------------------\n  Reserve a huge page arena.\n----------------------------------------------------------- */\n// reserve at a specific numa node\nint mi_reserve_huge_os_pages_at_ex(size_t pages, int numa_node, size_t timeout_msecs, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept {\n  if (arena_id != NULL) *arena_id = NULL;\n  if (pages==0) return 0;\n  if (numa_node < -1) numa_node = -1;\n  if (numa_node >= 0) numa_node = numa_node % _mi_os_numa_node_count();\n  size_t hsize = 0;\n  size_t pages_reserved = 0;\n  mi_memid_t memid;\n  void* p = _mi_os_alloc_huge_os_pages(pages, numa_node, timeout_msecs, &pages_reserved, &hsize, &memid);\n  if (p==NULL || pages_reserved==0) {\n    _mi_warning_message(\"failed to reserve %zu GiB huge pages\\n\", pages);\n    return ENOMEM;\n  }\n  _mi_verbose_message(\"numa node %i: reserved %zu GiB huge pages (of the %zu GiB requested)\\n\", numa_node, pages_reserved, pages);\n\n  if (!mi_manage_os_memory_ex2(_mi_subproc(), p, hsize, numa_node, exclusive, memid, NULL, NULL, arena_id)) {\n    _mi_os_free(p, hsize, memid);\n    return ENOMEM;\n  }\n  return 0;\n}\n\nint mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept {\n  return mi_reserve_huge_os_pages_at_ex(pages, numa_node, timeout_msecs, false, NULL);\n}\n\n// reserve huge pages evenly among the given number of numa nodes (or use the available ones as detected)\nint mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept {\n  if (pages == 0) return 0;\n\n  // pages per numa node\n  int numa_count = (numa_nodes > 0 && numa_nodes <= INT_MAX ? (int)numa_nodes : _mi_os_numa_node_count());\n  if (numa_count <= 0) { numa_count = 1; }\n  const size_t pages_per = pages / numa_count;\n  const size_t pages_mod = pages % numa_count;\n  const size_t timeout_per = (timeout_msecs==0 ? 0 : (timeout_msecs / numa_count) + 50);\n\n  // reserve evenly among numa nodes\n  for (int numa_node = 0; numa_node < numa_count && pages > 0; numa_node++) {\n    size_t node_pages = pages_per;  // can be 0\n    if ((size_t)numa_node < pages_mod) { node_pages++; }\n    int err = mi_reserve_huge_os_pages_at(node_pages, numa_node, timeout_per);\n    if (err) return err;\n    if (pages < node_pages) {\n      pages = 0;\n    }\n    else {\n      pages -= node_pages;\n    }\n  }\n\n  return 0;\n}\n\nint mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept {\n  MI_UNUSED(max_secs);\n  _mi_warning_message(\"mi_reserve_huge_os_pages is deprecated: use mi_reserve_huge_os_pages_interleave/at instead\\n\");\n  if (pages_reserved != NULL) *pages_reserved = 0;\n  int err = mi_reserve_huge_os_pages_interleave(pages, 0, (size_t)(max_secs * 1000.0));\n  if (err==0 && pages_reserved!=NULL) *pages_reserved = pages;\n  return err;\n}\n\n\n\n\n\n/* -----------------------------------------------------------\n  Arena purge\n----------------------------------------------------------- */\n\nstatic long mi_arena_purge_delay(void) {\n  // <0 = no purging allowed, 0=immediate purging, >0=milli-second delay\n  return (mi_option_get(mi_option_purge_delay) * mi_option_get(mi_option_arena_purge_mult));\n}\n\n// reset or decommit in an arena and update the commit bitmap\n// assumes we own the area (i.e. slices_free is claimed by us)\n// returns if the memory is no longer committed (versus reset which keeps the commit)\nstatic bool mi_arena_purge(mi_arena_t* arena, size_t slice_index, size_t slice_count) {\n  mi_assert_internal(!arena->memid.is_pinned);\n  mi_assert_internal(mi_bbitmap_is_clearN(arena->slices_free, slice_index, slice_count));\n\n  const size_t size = mi_size_of_slices(slice_count);\n  void* const p = mi_arena_slice_start(arena, slice_index);\n  //const bool all_committed = mi_bitmap_is_setN(arena->slices_committed, slice_index, slice_count);\n  size_t already_committed;\n  mi_bitmap_setN(arena->slices_committed, slice_index, slice_count, &already_committed); // pretend all committed.. (as we lack a clearN call that counts the already set bits..)\n  const bool all_committed = (already_committed == slice_count);\n  const bool needs_recommit = _mi_os_purge_ex(p, size, all_committed /* allow reset? */, mi_size_of_slices(already_committed), arena->commit_fun, arena->commit_fun_arg);\n\n  if (needs_recommit) {\n    // no longer committed\n    mi_bitmap_clearN(arena->slices_committed, slice_index, slice_count);\n    // we just counted in the purge to decommit all, but the some part was not committed so adjust that here\n    // mi_subproc_stat_decrease(arena->subproc, committed, mi_size_of_slices(slice_count - already_committed));\n  }\n  else if (!all_committed) {\n    // we cannot assume any of these are committed any longer (even with reset since we did setN and may have marked uncommitted slices as committed)\n    mi_bitmap_clearN(arena->slices_committed, slice_index, slice_count);\n    // we adjust the commit count as parts will be re-committed\n    // mi_subproc_stat_decrease(arena->subproc, committed, mi_size_of_slices(already_committed));\n  }\n\n  return needs_recommit;\n}\n\n\n// Schedule a purge. This is usually delayed to avoid repeated decommit/commit calls.\n// Note: assumes we (still) own the area as we may purge immediately\nstatic void mi_arena_schedule_purge(mi_arena_t* arena, size_t slice_index, size_t slice_count) {\n  const long delay = mi_arena_purge_delay();\n  if (arena->memid.is_pinned || delay < 0 || _mi_preloading()) return;  // is purging allowed at all?\n\n  mi_assert_internal(mi_bbitmap_is_clearN(arena->slices_free, slice_index, slice_count));\n  if (delay == 0) {\n    // purge directly\n    mi_arena_purge(arena, slice_index, slice_count);\n  }\n  else {\n    // schedule purge\n    const mi_msecs_t expire = _mi_clock_now() + delay;\n    mi_msecs_t expire0 = 0;\n    if (mi_atomic_casi64_strong_acq_rel(&arena->purge_expire, &expire0, expire)) {\n      // expiration was not yet set\n      // maybe set the global arenas expire as well (if it wasn't set already)\n      mi_assert_internal(expire0==0);\n      mi_atomic_casi64_strong_acq_rel(&arena->subproc->purge_expire, &expire0, expire);\n    }\n    else {\n      // already an expiration was set\n    }\n    mi_bitmap_setN(arena->slices_purge, slice_index, slice_count, NULL);\n  }\n}\n\ntypedef struct mi_purge_visit_info_s {\n  mi_msecs_t now;\n  mi_msecs_t delay;\n  bool all_purged;\n  bool any_purged;\n} mi_purge_visit_info_t;\n\nstatic bool mi_arena_try_purge_range(mi_arena_t* arena, size_t slice_index, size_t slice_count) {\n  mi_assert(slice_count < MI_BCHUNK_BITS);\n  if (mi_bbitmap_try_clearNC(arena->slices_free, slice_index, slice_count)) {\n    // purge\n    bool decommitted = mi_arena_purge(arena, slice_index, slice_count); MI_UNUSED(decommitted);\n    mi_assert_internal(!decommitted || mi_bitmap_is_clearN(arena->slices_committed, slice_index, slice_count));\n    // and reset the free range\n    mi_bbitmap_setN(arena->slices_free, slice_index, slice_count);\n    return true;\n  }\n  else {\n    // was allocated again already\n    return false;\n  }\n}\n\nstatic bool mi_arena_try_purge_visitor(size_t slice_index, size_t slice_count, mi_arena_t* arena, void* arg) {\n  mi_purge_visit_info_t* vinfo = (mi_purge_visit_info_t*)arg;\n  // try to purge: first claim the free blocks\n  if (mi_arena_try_purge_range(arena, slice_index, slice_count)) {\n    vinfo->any_purged = true;\n    vinfo->all_purged = true;\n  }\n  else if (slice_count > 1)\n  {\n    // failed to claim the full range, try per slice instead\n    for (size_t i = 0; i < slice_count; i++) {\n      const bool purged = mi_arena_try_purge_range(arena, slice_index + i, 1);\n      vinfo->any_purged = vinfo->any_purged || purged;\n      vinfo->all_purged = vinfo->all_purged && purged;\n    }\n  }\n  // don't clear the purge bits as that is done atomically be the _bitmap_forall_set_ranges\n  // mi_bitmap_clearN(arena->slices_purge, slice_index, slice_count);\n  return true; // continue\n}\n\n// returns\n// -1 = nothing was purged\n// 0  = nothing was purged yet because have not yet reached the expire time\n// 1  = some pages in the arena were purged\nstatic int mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force)\n{\n  // check pre-conditions\n  if (arena->memid.is_pinned) return -1;\n\n  // expired yet?\n  mi_msecs_t expire = mi_atomic_loadi64_relaxed(&arena->purge_expire);\n  if (!force) {\n    if (expire==0) return -1;\n    if (expire > now) return 0;\n  }\n\n  // reset expire\n  mi_atomic_storei64_release(&arena->purge_expire, (mi_msecs_t)0);\n  mi_subproc_stat_counter_increase(arena->subproc, arena_purges, 1);\n\n  // go through all purge info's  (with max MI_BFIELD_BITS ranges at a time)\n  // this also clears those ranges atomically (so any newly freed blocks will get purged next\n  // time around)\n  mi_purge_visit_info_t vinfo = { now, mi_arena_purge_delay(), true /*all?*/, false /*any?*/};\n\n  // we purge by at least `minslices` to not fragment transparent huge pages for example\n  const size_t minslices = mi_slice_count_of_size(_mi_os_minimal_purge_size());\n  _mi_bitmap_forall_setc_rangesn(arena->slices_purge, minslices, &mi_arena_try_purge_visitor, arena, &vinfo);\n\n  return (vinfo.any_purged ? 1 : -1);\n}\n\n\nstatic void mi_arenas_try_purge(bool force, bool visit_all, mi_subproc_t* subproc, size_t tseq)\n{\n  // try purge can be called often so try to only run when needed\n  const long delay = mi_arena_purge_delay();\n  if (_mi_preloading() || delay <= 0) return;  // nothing will be scheduled\n\n  // check if any arena needs purging?\n  const mi_msecs_t now = _mi_clock_now();\n  const mi_msecs_t arenas_expire = mi_atomic_loadi64_acquire(&subproc->purge_expire);\n  if (!visit_all && !force && (arenas_expire == 0 || arenas_expire > now)) return;\n\n  const size_t max_arena = mi_arenas_get_count(subproc);\n  if (max_arena == 0) return;\n\n  // allow only one thread to purge at a time (todo: allow concurrent purging?)\n  static mi_atomic_guard_t purge_guard;\n  mi_atomic_guard(&purge_guard)\n  {\n    // increase global expire: at most one purge per delay cycle\n    if (arenas_expire > now) { mi_atomic_storei64_release(&subproc->purge_expire, now + (delay/10)); }\n    const size_t arena_start = tseq % max_arena;\n    size_t max_purge_count = (visit_all ? max_arena : (max_arena/4)+1);\n    bool all_visited = true;\n    bool any_purged = false;\n    for (size_t _i = 0; _i < max_arena; _i++) {\n      size_t i = _i + arena_start;\n      if (i >= max_arena) { i -= max_arena; }\n      mi_arena_t* arena = mi_arena_from_index(subproc,i);\n      if (arena != NULL) {\n        const int purged = mi_arena_try_purge(arena, now, force);\n        if (purged >= 0) {      // purged, or arena expire is not yet reached\n          any_purged = true;\n          if (purged >= 1) {    // purged\n            if (max_purge_count <= 1) {\n              all_visited = false;\n              break;\n            }\n            max_purge_count--;\n          }\n        }\n      }\n    }\n    if (all_visited && !any_purged) {\n      mi_atomic_storei64_release(&subproc->purge_expire, (mi_msecs_t)0);\n    }\n  }\n}\n\n\n/* -----------------------------------------------------------\n  Visit all pages and blocks in a heap\n----------------------------------------------------------- */\n\ntypedef struct mi_heap_visit_info_s {\n  mi_heap_t* heap;\n  mi_block_visit_fun* visitor;\n  void* arg;\n  bool visit_blocks;\n} mi_heap_visit_info_t;\n\nstatic bool mi_heap_visit_page(mi_page_t* page, mi_heap_visit_info_t* vinfo) {\n  mi_heap_area_t area;\n  _mi_heap_area_init(&area, page);\n  mi_assert_internal(vinfo->heap == mi_page_heap(page));\n  if (!vinfo->visitor(vinfo->heap, &area, NULL, area.block_size, vinfo->arg)) {\n    return false;\n  }\n  if (vinfo->visit_blocks) {\n    return _mi_theap_area_visit_blocks(&area, page, vinfo->visitor, vinfo->arg);\n  }\n  else {\n    return true;\n  }\n}\n\nstatic bool mi_heap_visit_page_at(size_t slice_index, size_t slice_count, mi_arena_t* arena, void* arg) {\n  MI_UNUSED(slice_count);\n  mi_heap_visit_info_t* vinfo = (mi_heap_visit_info_t*)arg;\n  mi_page_t* page = mi_arena_page_at_slice(arena, slice_index);\n  return mi_heap_visit_page(page, vinfo);\n}\n\nbool _mi_heap_visit_blocks(mi_heap_t* heap, bool abandoned_only, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) {\n  mi_assert(visitor!=NULL);\n  if (visitor==NULL) return false;\n  if (heap==NULL) { heap = mi_heap_main(); }\n  // visit all pages in a heap\n  // we don't have to claim because we assume we are the only thread running (with this heap).\n  // (but we could atomically claim as well by first doing abandoned_reclaim and afterwards reabandoning).\n  mi_heap_visit_info_t visit_info = { heap, visitor, arg, visit_blocks };\n  bool ok = true;\n  mi_forall_arenas(heap, NULL, 0, arena) {\n    mi_arena_pages_t* arena_pages = mi_heap_arena_pages(heap, arena);\n    if (ok && arena_pages != NULL) {\n      if (abandoned_only) {\n        for (size_t bin = 0; ok && bin < MI_BIN_COUNT; bin++) {\n          // todo: if we had a single abandoned page map as well, this can be faster.\n          if (mi_atomic_load_relaxed(&heap->abandoned_count[bin]) > 0) {\n            ok = _mi_bitmap_forall_set(arena_pages->pages_abandoned[bin], &mi_heap_visit_page_at, arena, &visit_info);\n          }\n        }\n      }\n      else {\n        ok = _mi_bitmap_forall_set(arena_pages->pages, &mi_heap_visit_page_at, arena, &visit_info);\n      }\n    }\n  }\n  mi_forall_arenas_end();\n  if (!ok) return false;\n\n  // visit abandoned pages in OS allocated memory\n  // (technically we don't need the initial lock as we assume we are the only thread running in this subproc)\n  mi_page_t* page = NULL;\n  mi_lock(&heap->os_abandoned_pages_lock) {\n    page = heap->os_abandoned_pages;\n  }\n  while (ok && page != NULL) {\n    mi_page_t* next = page->next;  // read upfront in case the visitor frees the page\n    ok = mi_heap_visit_page(page, &visit_info);\n    page = next;\n  }\n\n  return ok;\n}\n\nbool mi_heap_visit_blocks(mi_heap_t* heap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) {\n  return _mi_heap_visit_blocks(heap, false, visit_blocks, visitor, arg);\n}\n\nbool mi_heap_visit_abandoned_blocks(mi_heap_t* heap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) {\n  return _mi_heap_visit_blocks(heap, true, visit_blocks, visitor, arg);\n}\n\n\ntypedef struct mi_heap_delete_visit_info_s {\n  mi_heap_t*  heap_target;\n  mi_theap_t* theap_target;\n  mi_theap_t* theap;\n} mi_heap_delete_visit_info_t;\n\nstatic bool mi_heap_delete_page(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg) {\n  MI_UNUSED(block); MI_UNUSED(block_size); MI_UNUSED(heap);\n  mi_heap_delete_visit_info_t* info = (mi_heap_delete_visit_info_t*)arg;\n  mi_heap_t*  heap_target           = info->heap_target;\n  mi_theap_t* const theap           = NULL; // info->theap;       mi_assert_internal(_mi_theap_heap(theap) == heap);\n  mi_page_t*  const page            = (mi_page_t*)area->reserved1;\n\n  mi_page_claim_ownership(page);       // claim ownership\n  if (mi_page_is_abandoned(page)) {\n    _mi_arenas_page_unabandon(page,theap);\n  }\n  else {\n    page->next = page->prev = NULL;    // yikes.. better not to try to access this from a thread later on..\n    mi_page_set_theap(page,NULL);      // set threadid to abandoned\n  }\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_assert_internal(mi_page_is_owned(page));\n\n  if (page->used==0) {\n    // free the page\n    _mi_arenas_page_free(page, theap);\n  }\n  else if (heap_target==NULL) {\n    // destroy the page\n    page->used=0;                        // note: invariant `|local_free| + |free| == reserved - used`  does not hold in this case\n    _mi_arenas_page_free(page, theap);\n  }\n  else {\n    // move the page to `heap_target` as an abandoned page\n    // first remove it from the current heap\n    const size_t sbin = _mi_page_stats_bin(page);\n    size_t slice_index;\n    size_t slice_count;\n    mi_arena_pages_t* arena_pages = NULL;\n    mi_arena_t* const arena = mi_page_arena_pages(page, &slice_index, &slice_count, &arena_pages);\n    mi_assert_internal(mi_bitmap_is_set(arena_pages->pages, slice_index));\n    mi_bitmap_clear(arena_pages->pages, slice_index);\n    if (theap != NULL) {\n      mi_theap_stat_decrease(theap, page_bins[sbin], 1);\n      mi_theap_stat_decrease(theap, pages, 1);\n    }\n    else {\n      mi_heap_stat_decrease((mi_heap_t*)heap, page_bins[_mi_page_stats_bin(page)], 1);\n      mi_heap_stat_decrease((mi_heap_t*)heap, pages, 1);\n    }\n    mi_theap_t* theap_target = info->theap_target;\n\n    // and then add it to the new target heap\n    mi_arena_pages_t* arena_pages_target = mi_heap_ensure_arena_pages(heap_target, arena);\n    if mi_unlikely(arena_pages_target==NULL) {\n      // if we cannot allocate this, we move it to the main heap instead (which does not require allocation)\n      heap_target = mi_heap_main();\n      theap_target = mi_heap_theap(heap_target);\n      arena_pages_target = mi_heap_ensure_arena_pages(heap_target, arena);\n      mi_assert_internal(arena_pages_target!=NULL);\n    }\n    mi_assert_internal(mi_bitmap_is_clear(arena_pages_target->pages, slice_index));\n    mi_bitmap_set(arena_pages_target->pages, slice_index);\n    page->heap = heap_target;\n    mi_theap_stat_increase(theap_target, page_bins[sbin], 1);\n    mi_theap_stat_increase(theap_target, pages, 1);\n\n    // and abandon in the new heap\n    _mi_arenas_page_abandon(page,theap_target);\n  }\n  return true;\n}\n\nstatic void mi_heap_delete_pages(mi_heap_t* heap, mi_heap_t* heap_target) {\n  mi_theap_t* const theap_target = (heap_target != NULL ? _mi_heap_theap(heap_target) : NULL);\n  // mi_theap_t* const theap = _mi_heap_theap(heap);\n  mi_heap_delete_visit_info_t info = { heap_target, theap_target, NULL };\n  _mi_heap_visit_blocks(heap, false, false, &mi_heap_delete_page, &info);\n  #if MI_DEBUG>1\n  // no more arena pages?\n  for (size_t i = 0; i < MI_ARENA_BIN_COUNT; i++) {\n    mi_arena_pages_t* const arena_pages = mi_atomic_load_ptr_relaxed(mi_arena_pages_t, &heap->arena_pages[i]);\n    if (arena_pages!=NULL) {\n      mi_assert_internal(mi_bitmap_is_all_clear(arena_pages->pages));\n    }\n  }\n  // nor os abandoned pages?\n  mi_lock(&heap->os_abandoned_pages_lock) {\n\n    mi_assert_internal(heap->os_abandoned_pages == NULL);\n  }\n  // nor arena abandoned pages?\n  for (size_t i = 0; i < MI_BIN_COUNT; i++) {\n    mi_assert_internal(mi_atomic_load_relaxed(&heap->abandoned_count[i])==0);\n  }\n  #endif\n}\n\nvoid _mi_heap_move_pages(mi_heap_t* heap_from, mi_heap_t* heap_to) {\n  if (_mi_is_heap_main(heap_from)) return;\n  if (heap_to==NULL) { heap_to = mi_heap_main(); }\n  mi_heap_delete_pages(heap_from, heap_to);\n}\n\nvoid _mi_heap_destroy_pages(mi_heap_t* heap_from) {\n  if (_mi_is_heap_main(heap_from)) return;\n  mi_heap_delete_pages(heap_from, NULL);\n}\n\n/* -----------------------------------------------------------\n  Unloading and reloading an arena.\n----------------------------------------------------------- */\n/*\nstatic bool mi_arena_page_register(size_t slice_index, size_t slice_count, mi_arena_t* arena, void* arg) {\n  MI_UNUSED(arg); MI_UNUSED(slice_count);\n  mi_assert_internal(slice_count == 1);\n  mi_page_t* page = mi_arena_page_at_slice(arena, slice_index);\n  mi_assert_internal(mi_bitmap_is_setN(page->memid.mem.arena.arena->pages, page->memid.mem.arena.slice_index, 1));\n  if (!_mi_page_map_register(page)) return false; // break\n  mi_assert_internal(_mi_ptr_page(page)==page);\n  return true;\n}\n\nmi_decl_nodiscard static bool mi_arena_pages_reregister(mi_arena_t* arena) {\n  return _mi_bitmap_forall_set(arena->pages, &mi_arena_page_register, arena, NULL);\n}\n\nmi_decl_export bool mi_arena_unload(mi_arena_id_t arena_id, void** base, size_t* accessed_size, size_t* full_size) {\n  mi_arena_t* arena = _mi_arena_from_id(arena_id);\n  if (arena==NULL) {\n    return false;\n  }\n  else if (!arena->is_exclusive) {\n    _mi_warning_message(\"cannot unload a non-exclusive arena (id %zu at %p)\\n\", arena_id, arena);\n    return false;\n  }\n  else if (arena->memid.memkind != MI_MEM_EXTERNAL) {\n    _mi_warning_message(\"can only unload managed arena's for external memory (id %zu at %p)\\n\", arena_id, arena);\n    return false;\n  }\n\n  // find accessed size\n  const size_t asize = mi_size_of_slices(mi_arena_used_slices(arena));\n  if (base != NULL) { *base = (void*)arena; }\n  if (full_size != NULL) { *full_size = arena->memid.mem.os.size;  }\n  if (accessed_size != NULL) { *accessed_size = asize; }\n\n  // adjust abandoned page count\n  mi_subproc_t* const subproc = arena->subproc;\n  for (size_t bin = 0; bin < MI_BIN_COUNT; bin++) {\n    const size_t count = mi_bitmap_popcount(arena->pages_abandoned[bin]);\n    if (count > 0) { mi_atomic_decrement_acq_rel(&subproc->abandoned_count[bin]); }\n  }\n\n  // unregister the pages\n  _mi_page_map_unregister_range(arena, asize);\n\n  // set arena entry to NULL\n  const size_t count = mi_arenas_get_count(subproc);\n  for(size_t i = 0; i < count; i++) {\n    if (mi_arena_from_index(subproc, i) == arena) {\n      mi_atomic_store_ptr_release(mi_arena_t, &subproc->arenas[i], NULL);\n      if (i + 1 == count) { // try adjust the count?\n        size_t expected = count;\n        mi_atomic_cas_strong_acq_rel(&subproc->arena_count, &expected, count-1);\n      }\n      break;\n    }\n  }\n  return true;\n}\n\nmi_decl_export bool mi_arena_reload(void* start, size_t size, mi_commit_fun_t* commit_fun, void* commit_fun_arg, mi_arena_id_t* arena_id) {\n  // assume the memory area is already containing the arena\n  if (arena_id != NULL) { *arena_id = _mi_arena_id_none(); }\n  if (start == NULL || size == 0) return false;\n  mi_arena_t* arena = (mi_arena_t*)start;\n  mi_memid_t memid = arena->memid;\n  if (memid.memkind != MI_MEM_EXTERNAL) {\n    _mi_warning_message(\"can only reload arena's from external memory (%p)\\n\", arena);\n    return false;\n  }\n  if (memid.mem.os.base != start) {\n    _mi_warning_message(\"the reloaded arena base address differs from the external memory (arena: %p, external: %p)\\n\", arena, start);\n    return false;\n  }\n  if (memid.mem.os.size != size) {\n    _mi_warning_message(\"the reloaded arena size differs from the external memory (arena size: %zu, external size: %zu)\\n\", arena->memid.mem.os.size, size);\n    return false;\n  }\n  if (!arena->is_exclusive) {\n    _mi_warning_message(\"the reloaded arena is not exclusive\\n\");\n    return false;\n  }\n\n  // re-initialize\n  arena->is_exclusive = true;\n  arena->commit_fun = commit_fun;\n  arena->commit_fun_arg = commit_fun_arg;\n  arena->subproc = _mi_subproc();\n  if (!mi_arenas_add(arena->subproc, arena, arena_id)) {\n    return false;\n  }\n  if (!mi_arena_pages_reregister(arena)) {\n    // todo: clear arena entry in the subproc?\n    return false;\n  }\n\n  // adjust abandoned page count\n  for (size_t bin = 0; bin < MI_BIN_COUNT; bin++) {\n    const size_t count = mi_bitmap_popcount(arena->pages_abandoned[bin]);\n    if (count > 0) { mi_atomic_decrement_acq_rel(&arena->subproc->abandoned_count[bin]); }\n  }\n\n  return true;\n}\n\n*/\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/bitmap.c",
      "sha256": "de16033e029488e9ade4152ea1274e1a5ecbdc2c8a8d8ee50b745fd037ee6f6c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2024 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* ----------------------------------------------------------------------------\nConcurrent bitmap that can set/reset sequences of bits atomically\n---------------------------------------------------------------------------- */\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/bits.h\"\n#include \"mimalloc/prim.h\"  // _mi_prim_thread_yield\n#include \"bitmap.h\"\n\n#ifndef MI_OPT_SIMD\n#define MI_OPT_SIMD   0\n#endif\n\n/* --------------------------------------------------------------------------------\n  bfields\n-------------------------------------------------------------------------------- */\n\nstatic inline size_t mi_bfield_ctz(mi_bfield_t x) {\n  return mi_ctz(x);\n}\n\nstatic inline size_t mi_bfield_clz(mi_bfield_t x) {\n  return mi_clz(x);\n}\n\nstatic inline size_t mi_bfield_popcount(mi_bfield_t x) {\n  return mi_popcount(x);\n}\n\nstatic inline mi_bfield_t mi_bfield_clear_least_bit(mi_bfield_t x) {\n  return (x & (x-1));\n}\n\n// find the least significant bit that is set (i.e. count trailing zero's)\n// return false if `x==0` (with `*idx` undefined) and true otherwise,\n// with the `idx` is set to the bit index (`0 <= *idx < MI_BFIELD_BITS`).\nstatic inline bool mi_bfield_find_least_bit(mi_bfield_t x, size_t* idx) {\n  return mi_bsf(x,idx);\n}\n\n// find the most significant bit that is set.\n// return false if `x==0` (with `*idx` undefined) and true otherwise,\n// with the `idx` is set to the bit index (`0 <= *idx < MI_BFIELD_BITS`).\nstatic inline bool mi_bfield_find_highest_bit(mi_bfield_t x, size_t* idx) {\n  return mi_bsr(x, idx);\n}\n\n\n\n// find each set bit in a bit field `x` and clear it, until it becomes zero.\nstatic inline bool mi_bfield_foreach_bit(mi_bfield_t* x, size_t* idx) {\n  const bool found = mi_bfield_find_least_bit(*x, idx);\n  *x = mi_bfield_clear_least_bit(*x);\n  return found;\n}\n\nstatic inline mi_bfield_t mi_bfield_zero(void) {\n  return 0;\n}\n\nstatic inline mi_bfield_t mi_bfield_one(void) {\n  return 1;\n}\n\nstatic inline mi_bfield_t mi_bfield_all_set(void) {\n  return ~((mi_bfield_t)0);\n}\n\n// mask of `bit_count` bits set shifted to the left by `shiftl`\nstatic inline mi_bfield_t mi_bfield_mask(size_t bit_count, size_t shiftl) {\n  mi_assert_internal(bit_count > 0);\n  mi_assert_internal(bit_count + shiftl <= MI_BFIELD_BITS);\n  mi_assert_internal(shiftl < MI_BFIELD_BITS);\n  const mi_bfield_t mask0 = (bit_count < MI_BFIELD_BITS ? (mi_bfield_one() << bit_count)-1 : mi_bfield_all_set());\n  return (mask0 << shiftl);\n}\n\n\n// ------- mi_bfield_atomic_set ---------------------------------------\n// the `_set` functions return also the count of bits that were already set (for commit statistics)\n// the `_clear` functions return also whether the new bfield is all clear or not (for the chunk_map)\n\n// Set a bit atomically. Returns `true` if the bit transitioned from 0 to 1\nstatic inline bool mi_bfield_atomic_set(_Atomic(mi_bfield_t)*b, size_t idx) {\n  mi_assert_internal(idx < MI_BFIELD_BITS);\n  const mi_bfield_t mask = mi_bfield_mask(1, idx);;\n  const mi_bfield_t old = mi_atomic_or_acq_rel(b, mask);\n  return ((old&mask) == 0);\n}\n\n// Clear a bit atomically. Returns `true` if the bit transitioned from 1 to 0.\n// `all_clear` is set if the new bfield is zero.\nstatic inline bool mi_bfield_atomic_clear(_Atomic(mi_bfield_t)*b, size_t idx, bool* all_clear) {\n  mi_assert_internal(idx < MI_BFIELD_BITS);\n  const mi_bfield_t mask = mi_bfield_mask(1, idx);;\n  mi_bfield_t old = mi_atomic_and_acq_rel(b, ~mask);\n  if (all_clear != NULL) { *all_clear = ((old&~mask)==0); }\n  return ((old&mask) == mask);\n}\n\n// Clear a bit but only when/once it is set. This is used by concurrent free's while\n// the page is abandoned and mapped. This can incure a busy wait :-( but it should\n// happen almost never (and is accounted for in the stats)\nstatic inline void mi_bfield_atomic_clear_once_set(_Atomic(mi_bfield_t)*b, size_t idx) {\n  mi_assert_internal(idx < MI_BFIELD_BITS);\n  const mi_bfield_t mask = mi_bfield_mask(1, idx);;\n  mi_bfield_t old = mi_atomic_load_relaxed(b);\n  do {\n    if mi_unlikely((old&mask) == 0) {\n      old = mi_atomic_load_acquire(b);\n      if ((old&mask)==0) {\n        mi_subproc_stat_counter_increase(_mi_subproc(), pages_unabandon_busy_wait, 1);\n      }\n      while ((old&mask)==0) { // busy wait\n        _mi_prim_thread_yield(); \n        old = mi_atomic_load_acquire(b);\n      }\n    }\n  } while (!mi_atomic_cas_weak_acq_rel(b,&old, (old&~mask)));\n  mi_assert_internal((old&mask)==mask);  // we should only clear when it was set\n}\n\n// Set a mask set of bits atomically, and return true of the mask bits transitioned from all 0's to 1's.\n// `already_set` contains the count of bits that were already set (used when committing ranges to account\n// statistics correctly).\nstatic inline bool mi_bfield_atomic_set_mask(_Atomic(mi_bfield_t)*b, mi_bfield_t mask, size_t* already_set) {\n  mi_assert_internal(mask != 0);\n  mi_bfield_t old = mi_atomic_load_relaxed(b);\n  while (!mi_atomic_cas_weak_acq_rel(b, &old, old|mask)) {};  // try to atomically set the mask bits until success\n  if (already_set!=NULL) { *already_set = mi_bfield_popcount(old&mask); }\n  return ((old&mask) == 0);\n}\n\n// Clear a mask set of bits atomically, and return true of the mask bits transitioned from all 1's to 0's\n// `all_clear` is set to `true` if the new bfield became zero.\nstatic inline bool mi_bfield_atomic_clear_mask(_Atomic(mi_bfield_t)*b, mi_bfield_t mask, bool* all_clear) {\n  mi_assert_internal(mask != 0);\n  mi_bfield_t old = mi_atomic_load_relaxed(b);\n  while (!mi_atomic_cas_weak_acq_rel(b, &old, old&~mask)) {};  // try to atomically clear the mask bits until success\n  if (all_clear != NULL) { *all_clear = ((old&~mask)==0); }\n  return ((old&mask) == mask);\n}\n\nstatic inline bool mi_bfield_atomic_setX(_Atomic(mi_bfield_t)*b, size_t* already_set) {\n  const mi_bfield_t old = mi_atomic_exchange_release(b, mi_bfield_all_set());\n  if (already_set!=NULL) { *already_set = mi_bfield_popcount(old); }\n  return (old==0);\n}\n\n// static inline bool mi_bfield_atomic_clearX(_Atomic(mi_bfield_t)*b, bool* all_clear) {\n//   const mi_bfield_t old = mi_atomic_exchange_release(b, mi_bfield_zero());\n//   if (all_clear!=NULL) { *all_clear = true; }\n//   return (~old==0);\n// }\n\n// ------- mi_bfield_atomic_try_clear ---------------------------------------\n\n\n// Tries to clear a mask atomically, and returns true if the mask bits atomically transitioned from mask to 0\n// and false otherwise (leaving the bit field as is).\n// `all_clear` is set to `true` if the new bfield became zero.\nstatic inline bool mi_bfield_atomic_try_clear_mask_of(_Atomic(mi_bfield_t)*b, mi_bfield_t mask, mi_bfield_t expect, bool* all_clear) {\n  mi_assert_internal(mask != 0);\n  // try to atomically clear the mask bits\n  do {\n    if ((expect & mask) != mask) {  // are all bits still set?\n      if (all_clear != NULL) { *all_clear = (expect == 0); }\n      return false;\n    }\n  } while (!mi_atomic_cas_weak_acq_rel(b, &expect, expect & ~mask));\n  if (all_clear != NULL) { *all_clear = ((expect & ~mask) == 0);  }\n  return true;\n}\n\nstatic inline bool mi_bfield_atomic_try_clear_mask(_Atomic(mi_bfield_t)* b, mi_bfield_t mask, bool* all_clear) {\n  mi_assert_internal(mask != 0);\n  const mi_bfield_t expect = mi_atomic_load_relaxed(b);\n  return mi_bfield_atomic_try_clear_mask_of(b, mask, expect, all_clear);\n}\n\n// Tries to clear a bit atomically. Returns `true` if the bit transitioned from 1 to 0\n// and `false` otherwise leaving the bfield `b` as-is.\n// `all_clear` is set to true if the new bfield became zero (and false otherwise)\nmi_decl_maybe_unused static inline bool mi_bfield_atomic_try_clear(_Atomic(mi_bfield_t)* b, size_t idx, bool* all_clear) {\n  mi_assert_internal(idx < MI_BFIELD_BITS);\n  const mi_bfield_t mask = mi_bfield_one()<<idx;\n  return mi_bfield_atomic_try_clear_mask(b, mask, all_clear);\n}\n\n// Tries to clear a byte atomically, and returns true if the byte atomically transitioned from 0xFF to 0\n// `all_clear` is set to true if the new bfield became zero (and false otherwise)\nmi_decl_maybe_unused static inline bool mi_bfield_atomic_try_clear8(_Atomic(mi_bfield_t)*b, size_t idx, bool* all_clear) {\n  mi_assert_internal(idx < MI_BFIELD_BITS);\n  mi_assert_internal((idx%8)==0);\n  const mi_bfield_t mask = ((mi_bfield_t)0xFF)<<idx;\n  return mi_bfield_atomic_try_clear_mask(b, mask, all_clear);\n}\n\n// Try to clear a full field of bits atomically, and return true all bits transitioned from all 1's to 0's.\n// and false otherwise leaving the bit field as-is.\n// `all_clear` is set to true if the new bfield became zero (which is always the case if successful).\nstatic inline bool mi_bfield_atomic_try_clearX(_Atomic(mi_bfield_t)*b, bool* all_clear) {\n  mi_bfield_t old = mi_bfield_all_set();\n  if (mi_atomic_cas_strong_acq_rel(b, &old, mi_bfield_zero())) {\n    if (all_clear != NULL) { *all_clear = true; }\n    return true;\n  }\n  else return false;\n}\n\n\n// ------- mi_bfield_atomic_is_set ---------------------------------------\n\n// Check if a bit is set\nstatic inline bool mi_bfield_atomic_is_set(const _Atomic(mi_bfield_t)*b, const size_t idx) {\n  const mi_bfield_t x = mi_atomic_load_acquire(b);\n  return ((x & mi_bfield_mask(1,idx)) != 0);\n}\n\n// Check if a bit is clear\nstatic inline bool mi_bfield_atomic_is_clear(const _Atomic(mi_bfield_t)*b, const size_t idx) {\n  const mi_bfield_t x = mi_atomic_load_acquire(b);\n  return ((x & mi_bfield_mask(1, idx)) == 0);\n}\n\n// Check if a bit is xset\nstatic inline bool mi_bfield_atomic_is_xset(mi_xset_t set, const _Atomic(mi_bfield_t)*b, const size_t idx) {\n  if (set) return mi_bfield_atomic_is_set(b, idx);\n      else return mi_bfield_atomic_is_clear(b, idx);\n}\n\n// Check if all bits corresponding to a mask are set.\nstatic inline bool mi_bfield_atomic_is_set_mask(const _Atomic(mi_bfield_t)* b, mi_bfield_t mask) {\n  mi_assert_internal(mask != 0);\n  const mi_bfield_t x = mi_atomic_load_acquire(b);\n  return ((x & mask) == mask);\n}\n\n// Check if all bits corresponding to a mask are clear.\nstatic inline bool mi_bfield_atomic_is_clear_mask(const _Atomic(mi_bfield_t)* b, mi_bfield_t mask) {\n  mi_assert_internal(mask != 0);\n  const mi_bfield_t x = mi_atomic_load_acquire(b);\n  return ((x & mask) == 0);\n}\n\n// Check if all bits corresponding to a mask are set/cleared.\nstatic inline bool mi_bfield_atomic_is_xset_mask(mi_xset_t set, const _Atomic(mi_bfield_t)* b, mi_bfield_t mask) {\n  mi_assert_internal(mask != 0);\n  if (set) return mi_bfield_atomic_is_set_mask(b, mask);\n      else return mi_bfield_atomic_is_clear_mask(b, mask);\n}\n\n// Count bits in a mask\nstatic inline size_t mi_bfield_atomic_popcount_mask(_Atomic(mi_bfield_t)*b, mi_bfield_t mask) {\n  const mi_bfield_t x = mi_atomic_load_acquire(b);\n  return mi_bfield_popcount(x & mask);\n}\n\n\n/* --------------------------------------------------------------------------------\n bitmap chunks\n-------------------------------------------------------------------------------- */\n\n// ------- mi_bchunk_set ---------------------------------------\n\n// Set a single bit\nstatic inline bool mi_bchunk_set(mi_bchunk_t* chunk, size_t cidx, size_t* already_set) {\n  mi_assert_internal(cidx < MI_BCHUNK_BITS);\n  const size_t i = cidx / MI_BFIELD_BITS;\n  const size_t idx = cidx % MI_BFIELD_BITS;\n  const bool was_clear = mi_bfield_atomic_set(&chunk->bfields[i], idx);\n  if (already_set != NULL) { *already_set = (was_clear ? 0 : 1); }\n  return was_clear;\n}\n\n// Set `0 < n <= MI_BFIELD_BITS`, and return true of the mask bits transitioned from all 0's to 1's.\n// `already_set` contains the count of bits that were already set (used when committing ranges to account\n// statistics correctly).\n// Can cross over two bfields.\nstatic inline bool mi_bchunk_setNX(mi_bchunk_t* chunk, size_t cidx, size_t n, size_t* already_set) {\n  mi_assert_internal(cidx < MI_BCHUNK_BITS);\n  mi_assert_internal(n > 0 && n <= MI_BFIELD_BITS);\n  const size_t i = cidx / MI_BFIELD_BITS;\n  const size_t idx = cidx % MI_BFIELD_BITS;\n  if mi_likely(idx + n <= MI_BFIELD_BITS) {\n    // within one field\n    return mi_bfield_atomic_set_mask(&chunk->bfields[i], mi_bfield_mask(n,idx), already_set);\n  }\n  else {\n    // spanning two fields\n    const size_t m = MI_BFIELD_BITS - idx;  // bits to clear in the first field\n    mi_assert_internal(m < n);\n    mi_assert_internal(i < MI_BCHUNK_FIELDS - 1);\n    mi_assert_internal(idx + m <= MI_BFIELD_BITS);\n    size_t already_set1;\n    const bool all_set1 = mi_bfield_atomic_set_mask(&chunk->bfields[i], mi_bfield_mask(m, idx), &already_set1);\n    mi_assert_internal(n - m > 0);\n    mi_assert_internal(n - m < MI_BFIELD_BITS);\n    size_t already_set2;\n    const bool all_set2 = mi_bfield_atomic_set_mask(&chunk->bfields[i+1], mi_bfield_mask(n - m, 0), &already_set2);\n    if (already_set != NULL) { *already_set = already_set1 + already_set2; }\n    return (all_set1 && all_set2);\n  }\n}\n\n// Set a sequence of `n` bits within a chunk.\n// Returns true if all bits transitioned from 0 to 1 (or 1 to 0).\nmi_decl_noinline static bool mi_bchunk_xsetNC(mi_xset_t set, mi_bchunk_t* chunk, size_t cidx, size_t n, size_t* palready_set, bool* pmaybe_all_clear) {\n  mi_assert_internal(cidx + n <= MI_BCHUNK_BITS);\n  mi_assert_internal(n>0);\n  bool all_transition = true;\n  bool maybe_all_clear = true;\n  size_t total_already_set = 0;\n  size_t idx   = cidx % MI_BFIELD_BITS;\n  size_t field = cidx / MI_BFIELD_BITS;\n  while (n > 0) {\n    size_t m = MI_BFIELD_BITS - idx;   // m is the bits to xset in this field\n    if (m > n) { m = n; }\n    mi_assert_internal(idx + m <= MI_BFIELD_BITS);\n    mi_assert_internal(field < MI_BCHUNK_FIELDS);\n    const mi_bfield_t mask = mi_bfield_mask(m, idx);\n    size_t already_set = 0;\n    bool all_clear = false;\n    const bool transition = (set ? mi_bfield_atomic_set_mask(&chunk->bfields[field], mask, &already_set)\n                                 : mi_bfield_atomic_clear_mask(&chunk->bfields[field], mask, &all_clear));\n    mi_assert_internal((transition && already_set == 0) || (!transition && already_set > 0));\n    all_transition = all_transition && transition;\n    total_already_set += already_set;\n    maybe_all_clear = maybe_all_clear && all_clear;\n    // next field\n    field++;\n    idx = 0;\n    mi_assert_internal(m <= n);\n    n -= m;\n  }\n  if (palready_set!=NULL) { *palready_set = total_already_set; }\n  if (pmaybe_all_clear!=NULL) { *pmaybe_all_clear = maybe_all_clear; }\n  return all_transition;\n}\n\nstatic inline bool mi_bchunk_setN(mi_bchunk_t* chunk, size_t cidx, size_t n, size_t* already_set) {\n  mi_assert_internal(n>0 && n <= MI_BCHUNK_BITS);\n  if (n==1) return mi_bchunk_set(chunk, cidx, already_set);\n  // if (n==8 && (cidx%8) == 0) return mi_bchunk_set8(chunk, cidx, already_set);\n  // if (n==MI_BFIELD_BITS) return mi_bchunk_setX(chunk, cidx, already_set);\n  if (n<=MI_BFIELD_BITS) return mi_bchunk_setNX(chunk, cidx, n, already_set);\n  return mi_bchunk_xsetNC(MI_BIT_SET, chunk, cidx, n, already_set, NULL);\n}\n\n// ------- mi_bchunk_clear ---------------------------------------\n\nstatic inline bool mi_bchunk_clear(mi_bchunk_t* chunk, size_t cidx, bool* all_clear) {\n  mi_assert_internal(cidx < MI_BCHUNK_BITS);\n  const size_t i = cidx / MI_BFIELD_BITS;\n  const size_t idx = cidx % MI_BFIELD_BITS;\n  return mi_bfield_atomic_clear(&chunk->bfields[i], idx, all_clear);\n}\n\nstatic inline bool mi_bchunk_clearN(mi_bchunk_t* chunk, size_t cidx, size_t n, bool* maybe_all_clear) {\n  mi_assert_internal(n>0 && n <= MI_BCHUNK_BITS);\n  if (n==1) return mi_bchunk_clear(chunk, cidx, maybe_all_clear);\n  // if (n==8) return mi_bchunk_clear8(chunk, cidx, maybe_all_clear);\n  // if (n==MI_BFIELD_BITS) return mi_bchunk_clearX(chunk, cidx, maybe_all_clear);\n  // TODO: implement mi_bchunk_xsetNX instead of setNX\n  return mi_bchunk_xsetNC(MI_BIT_CLEAR, chunk, cidx, n, NULL, maybe_all_clear);\n}\n\n// Check if a sequence of `n` bits within a chunk are all set/cleared.\n// This can cross bfield's\nmi_decl_noinline static size_t mi_bchunk_popcountNC(mi_bchunk_t* chunk, size_t field_idx, size_t idx, size_t n) {\n  mi_assert_internal((field_idx*MI_BFIELD_BITS) + idx + n <= MI_BCHUNK_BITS);\n  size_t count = 0;\n  while (n > 0) {\n    size_t m = MI_BFIELD_BITS - idx;   // m is the bits to xset in this field\n    if (m > n) { m = n; }\n    mi_assert_internal(idx + m <= MI_BFIELD_BITS);\n    mi_assert_internal(field_idx < MI_BCHUNK_FIELDS);\n    const size_t mask = mi_bfield_mask(m, idx);\n    count += mi_bfield_atomic_popcount_mask(&chunk->bfields[field_idx], mask);\n    // next field\n    field_idx++;\n    idx = 0;\n    n -= m;\n  }\n  return count;\n}\n\n// Count set bits a sequence of `n` bits.\nstatic inline size_t mi_bchunk_popcountN(mi_bchunk_t* chunk, size_t cidx, size_t n) {\n  mi_assert_internal(cidx + n <= MI_BCHUNK_BITS);\n  mi_assert_internal(n>0);\n  if (n==0) return 0;\n  const size_t i = cidx / MI_BFIELD_BITS;\n  const size_t idx = cidx % MI_BFIELD_BITS;\n  if (n==1) { return (mi_bfield_atomic_is_set(&chunk->bfields[i], idx) ? 1 : 0); }\n  if (idx + n <= MI_BFIELD_BITS) { return mi_bfield_atomic_popcount_mask(&chunk->bfields[i], mi_bfield_mask(n, idx)); }\n  return mi_bchunk_popcountNC(chunk, i, idx, n);\n}\n\n\n// ------- mi_bchunk_is_xset ---------------------------------------\n\n// Check if a sequence of `n` bits within a chunk are all set/cleared.\n// This can cross bfield's\nmi_decl_noinline static bool mi_bchunk_is_xsetNC(mi_xset_t set, const mi_bchunk_t* chunk, size_t field_idx, size_t idx, size_t n) {\n  mi_assert_internal((field_idx*MI_BFIELD_BITS) + idx + n <= MI_BCHUNK_BITS);\n  while (n > 0) {\n    size_t m = MI_BFIELD_BITS - idx;   // m is the bits to xset in this field\n    if (m > n) { m = n; }\n    mi_assert_internal(idx + m <= MI_BFIELD_BITS);\n    mi_assert_internal(field_idx < MI_BCHUNK_FIELDS);\n    const size_t mask = mi_bfield_mask(m, idx);\n    if (!mi_bfield_atomic_is_xset_mask(set, &chunk->bfields[field_idx], mask)) {\n      return false;\n    }\n    // next field\n    field_idx++;\n    idx = 0;\n    n -= m;\n  }\n  return true;\n}\n\n// Check if a sequence of `n` bits within a chunk are all set/cleared.\nstatic inline bool mi_bchunk_is_xsetN(mi_xset_t set, const mi_bchunk_t* chunk, size_t cidx, size_t n) {\n  mi_assert_internal(cidx + n <= MI_BCHUNK_BITS);\n  mi_assert_internal(n>0);\n  if (n==0) return true;\n  const size_t i = cidx / MI_BFIELD_BITS;\n  const size_t idx = cidx % MI_BFIELD_BITS;\n  if (n==1) { return mi_bfield_atomic_is_xset(set, &chunk->bfields[i], idx); }\n  if (idx + n <= MI_BFIELD_BITS) { return mi_bfield_atomic_is_xset_mask(set, &chunk->bfields[i], mi_bfield_mask(n, idx)); }\n  return mi_bchunk_is_xsetNC(set, chunk, i, idx, n);\n}\n\n\n// ------- mi_bchunk_try_clear  ---------------------------------------\n\n// Clear `0 < n <= MI_BITFIELD_BITS`. Can cross over a bfield boundary.\nstatic inline bool mi_bchunk_try_clearNX(mi_bchunk_t* chunk, size_t cidx, size_t n, bool* pmaybe_all_clear) {\n  mi_assert_internal(cidx < MI_BCHUNK_BITS);\n  mi_assert_internal(n <= MI_BFIELD_BITS);\n  const size_t i = cidx / MI_BFIELD_BITS;\n  const size_t idx = cidx % MI_BFIELD_BITS;\n  if mi_likely(idx + n <= MI_BFIELD_BITS) {\n    // within one field\n    return mi_bfield_atomic_try_clear_mask(&chunk->bfields[i], mi_bfield_mask(n, idx), pmaybe_all_clear);\n  }\n  else {\n    // spanning two fields (todo: use double-word atomic ops?)\n    const size_t m = MI_BFIELD_BITS - idx;  // bits to clear in the first field\n    mi_assert_internal(m < n);\n    mi_assert_internal(i < MI_BCHUNK_FIELDS - 1);\n    bool field1_is_clear;\n    if (!mi_bfield_atomic_try_clear_mask(&chunk->bfields[i], mi_bfield_mask(m, idx), &field1_is_clear)) return false;\n    // try the second field as well\n    mi_assert_internal(n - m > 0);\n    mi_assert_internal(n - m < MI_BFIELD_BITS);\n    bool field2_is_clear;\n    if (!mi_bfield_atomic_try_clear_mask(&chunk->bfields[i+1], mi_bfield_mask(n - m, 0), &field2_is_clear)) {\n      // we failed to clear the second field, restore the first one\n      mi_bfield_atomic_set_mask(&chunk->bfields[i], mi_bfield_mask(m, idx), NULL);\n      return false;\n    }\n    if (pmaybe_all_clear != NULL) { *pmaybe_all_clear = field1_is_clear && field2_is_clear;  }\n    return true;\n  }\n}\n\n// Clear a full aligned bfield.\n// static inline bool mi_bchunk_try_clearX(mi_bchunk_t* chunk, size_t cidx, bool* pmaybe_all_clear) {\n//   mi_assert_internal(cidx < MI_BCHUNK_BITS);\n//   mi_assert_internal((cidx%MI_BFIELD_BITS) == 0);\n//   const size_t i = cidx / MI_BFIELD_BITS;\n//   return mi_bfield_atomic_try_clearX(&chunk->bfields[i], pmaybe_all_clear);\n// }\n\n// Try to atomically clear a sequence of `n` bits within a chunk.\n// Returns true if all bits transitioned from 1 to 0,\n// and false otherwise leaving all bit fields as is.\n// Note: this is the complex one as we need to unwind partial atomic operations if we fail halfway..\n// `maybe_all_clear` is set to `true` if all the bfields involved become zero.\nmi_decl_noinline static bool mi_bchunk_try_clearNC(mi_bchunk_t* chunk, size_t cidx, size_t n, bool* pmaybe_all_clear) {\n  mi_assert_internal(cidx + n <= MI_BCHUNK_BITS);\n  mi_assert_internal(n>0);\n  if (pmaybe_all_clear != NULL) { *pmaybe_all_clear = true; }\n  if (n==0) return true;\n\n  // first field\n  const size_t start_idx = cidx % MI_BFIELD_BITS;\n  const size_t start_field = cidx / MI_BFIELD_BITS;\n  size_t field = start_field;\n  size_t m = MI_BFIELD_BITS - start_idx;   // m are the bits to clear in this field\n  if (m > n) { m = n; }\n  mi_assert_internal(start_idx + m <= MI_BFIELD_BITS);\n  mi_assert_internal(start_field < MI_BCHUNK_FIELDS);\n  const mi_bfield_t mask_start = mi_bfield_mask(m, start_idx);\n  bool maybe_all_clear;\n  if (!mi_bfield_atomic_try_clear_mask(&chunk->bfields[field], mask_start, &maybe_all_clear)) return false;\n\n  // done?\n  mi_assert_internal(m <= n);\n  n -= m;\n\n  // continue with mid fields and last field: if these fail we need to recover by unsetting previous fields\n  // mid fields?\n  while (n >= MI_BFIELD_BITS) {\n    field++;\n    mi_assert_internal(field < MI_BCHUNK_FIELDS);\n    bool field_is_clear;\n    if (!mi_bfield_atomic_try_clearX(&chunk->bfields[field], &field_is_clear)) goto restore;\n    maybe_all_clear = maybe_all_clear && field_is_clear;\n    n -= MI_BFIELD_BITS;\n  }\n\n  // last field?\n  if (n > 0) {\n    mi_assert_internal(n < MI_BFIELD_BITS);\n    field++;\n    mi_assert_internal(field < MI_BCHUNK_FIELDS);\n    const mi_bfield_t mask_end = mi_bfield_mask(n, 0);\n    bool field_is_clear;\n    if (!mi_bfield_atomic_try_clear_mask(&chunk->bfields[field], mask_end, &field_is_clear)) goto restore;\n    maybe_all_clear = maybe_all_clear && field_is_clear;\n  }\n\n  if (pmaybe_all_clear != NULL) { *pmaybe_all_clear = maybe_all_clear; }\n  return true;\n\nrestore:\n  // `field` is the index of the field that failed to set atomically; we need to restore all previous fields\n  mi_assert_internal(field > start_field);\n  while( field > start_field) {\n    field--;\n    if (field == start_field) {\n      mi_bfield_atomic_set_mask(&chunk->bfields[field], mask_start, NULL);\n    }\n    else {\n      mi_bfield_atomic_setX(&chunk->bfields[field], NULL);  // mid-field: set all bits again\n    }\n  }\n  return false;\n}\n\n\nstatic inline bool mi_bchunk_try_clearN(mi_bchunk_t* chunk, size_t cidx, size_t n, bool* maybe_all_clear) {\n  mi_assert_internal(n>0);\n  // if (n==MI_BFIELD_BITS) return mi_bchunk_try_clearX(chunk, cidx, maybe_all_clear);\n  if (n<=MI_BFIELD_BITS) return mi_bchunk_try_clearNX(chunk, cidx, n, maybe_all_clear);\n  return mi_bchunk_try_clearNC(chunk, cidx, n, maybe_all_clear);\n}\n\n\n// ------- mi_bchunk_try_find_and_clear ---------------------------------------\n\n#if MI_OPT_SIMD && defined(__AVX2__)\nmi_decl_maybe_unused static inline __m256i mi_mm256_zero(void) {\n  return _mm256_setzero_si256();\n}\nmi_decl_maybe_unused static inline __m256i mi_mm256_ones(void) {\n  return _mm256_set1_epi64x(~0);\n}\nmi_decl_maybe_unused static inline bool mi_mm256_is_ones(__m256i vec) {\n  return _mm256_testc_si256(vec, _mm256_cmpeq_epi32(vec, vec));\n}\nmi_decl_maybe_unused static inline bool mi_mm256_is_zero( __m256i vec) {\n  return _mm256_testz_si256(vec,vec);\n}\n#endif\n\nstatic inline bool mi_bchunk_try_find_and_clear_at(mi_bchunk_t* chunk, size_t chunk_idx, size_t* pidx) {\n  mi_assert_internal(chunk_idx < MI_BCHUNK_FIELDS);\n  // note: this must be acquire (and not relaxed), or otherwise the AVX code below can loop forever\n  // as the compiler won't reload the registers vec1 and vec2 from memory again.\n  const mi_bfield_t b = mi_atomic_load_acquire(&chunk->bfields[chunk_idx]);\n  size_t idx;\n  if (mi_bfield_find_least_bit(b, &idx)) {           // find the least bit\n    if mi_likely(mi_bfield_atomic_try_clear_mask_of(&chunk->bfields[chunk_idx], mi_bfield_mask(1,idx), b, NULL)) {  // clear it atomically\n      *pidx = (chunk_idx*MI_BFIELD_BITS) + idx;\n      mi_assert_internal(*pidx < MI_BCHUNK_BITS);\n      return true;\n    }\n  }\n  return false;\n}\n\n// Find least 1-bit in a chunk and try to clear it atomically\n// set `*pidx` to the bit index (0 <= *pidx < MI_BCHUNK_BITS) on success.\n// This is used to find free slices and abandoned pages and should be efficient.\n// todo: try neon version\nstatic inline bool mi_bchunk_try_find_and_clear(mi_bchunk_t* chunk, size_t* pidx) {\n  #if MI_OPT_SIMD && defined(__AVX2__) && (MI_BCHUNK_BITS==256)\n  for(int tries=0; tries<4; tries++) {   // paranoia: at most 4 tries\n    const __m256i vec = _mm256_load_si256((const __m256i*)chunk->bfields);\n    const __m256i vcmp = _mm256_cmpeq_epi64(vec, mi_mm256_zero()); // (elem64 == 0 ? 0xFF  : 0)\n    const uint32_t mask = ~_mm256_movemask_epi8(vcmp);  // mask of most significant bit of each byte (so each 8 bits are all set or clear)\n    // mask is inverted, so each 8-bits is 0xFF iff the corresponding elem64 has a bit set (and thus can be cleared)\n    if (mask==0) return false;\n    mi_assert_internal((_tzcnt_u32(mask)%8) == 0); // tzcnt == 0, 8, 16, or 24\n    const size_t chunk_idx = _tzcnt_u32(mask) / 8;\n    if (mi_bchunk_try_find_and_clear_at(chunk, chunk_idx, pidx)) return true;\n    // try again\n    // note: there must be an atomic release/acquire in between or otherwise the registers may not be reloaded\n    // we add an explicit memory barrier as older gcc compilers do not reload the registers even with an atomic acquire (issue #1206)\n    #if defined(__GNUC__)\n    __asm __volatile (\"\" : : \"g\"(chunk) : \"memory\");\n    #endif\n  }\n  #elif MI_OPT_SIMD && defined(__AVX2__) && (MI_BCHUNK_BITS==512)\n  for(int tries=0; tries<4; tries++) {   // paranoia: at most 4 tries\n    size_t chunk_idx = 0;\n    #if 0\n    // one vector at a time\n    __m256i vec = _mm256_load_si256((const __m256i*)chunk->bfields);\n    if (mi_mm256_is_zero(vec)) {\n      chunk_idx += 4;\n      vec = _mm256_load_si256(((const __m256i*)chunk->bfields) + 1);\n    }\n    const __m256i vcmp = _mm256_cmpeq_epi64(vec, mi_mm256_zero()); // (elem64 == 0 ? 0xFF  : 0)\n    const uint32_t mask = ~_mm256_movemask_epi8(vcmp);  // mask of most significant bit of each byte (so each 8 bits are all set or clear)\n    // mask is inverted, so each 8-bits is 0xFF iff the corresponding elem64 has a bit set (and thus can be cleared)\n    if (mask==0) return false;\n    mi_assert_internal((_tzcnt_u32(mask)%8) == 0); // tzcnt == 0, 8, 16, or 24\n    chunk_idx += _tzcnt_u32(mask) / 8;\n    #else\n    // a cache line is 64b so we can just as well load all at the same time\n    const __m256i vec1  = _mm256_load_si256((const __m256i*)chunk->bfields);\n    const __m256i vec2  = _mm256_load_si256(((const __m256i*)chunk->bfields)+1);\n    const __m256i cmpv  = mi_mm256_zero();\n    const __m256i vcmp1 = _mm256_cmpeq_epi64(vec1, cmpv); // (elem64 == 0 ? 0xFF  : 0)\n    const __m256i vcmp2 = _mm256_cmpeq_epi64(vec2, cmpv); // (elem64 == 0 ? 0xFF  : 0)\n    const uint32_t mask1 = ~_mm256_movemask_epi8(vcmp1);  // mask of most significant bit of each byte (so each 8 bits are all set or clear)\n    const uint32_t mask2 = ~_mm256_movemask_epi8(vcmp2);  // mask of most significant bit of each byte (so each 8 bits are all set or clear)\n    const uint64_t mask = ((uint64_t)mask2 << 32) | mask1;\n    // mask is inverted, so each 8-bits is 0xFF iff the corresponding elem64 has a bit set (and thus can be cleared)\n    if (mask==0) return false;\n    mi_assert_internal((_tzcnt_u64(mask)%8) == 0); // tzcnt == 0, 8, 16, 24 , ..\n    chunk_idx = mi_ctz(mask) / 8;\n    #endif\n    if (mi_bchunk_try_find_and_clear_at(chunk, chunk_idx, pidx)) return true;\n    // try again\n    // note: there must be an atomic release/acquire in between or otherwise the registers may not be reloaded\n    // we add an explicit memory barrier as older gcc compilers do not reload the registers even with an atomic acquire (issue #1206)\n    #if defined(__GNUC__)\n    __asm __volatile (\"\" : : \"g\"(chunk) : \"memory\");\n    #endif\n  }\n  #elif MI_OPT_SIMD && (MI_BCHUNK_BITS==512) && MI_ARCH_ARM64\n  for(int tries=0; tries<4; tries++) {   // paranoia: at most 4 tries\n    // a cache line is 64b so we can just as well load all at the same time (?)\n    const uint64x2_t vzero1_lo = vceqzq_u64(vld1q_u64((uint64_t*)chunk->bfields));        // 2x64 bit is_zero\n    const uint64x2_t vzero1_hi = vceqzq_u64(vld1q_u64((uint64_t*)chunk->bfields + 2));    // 2x64 bit is_zero\n    const uint64x2_t vzero2_lo = vceqzq_u64(vld1q_u64((uint64_t*)chunk->bfields + 4));    // 2x64 bit is_zero\n    const uint64x2_t vzero2_hi = vceqzq_u64(vld1q_u64((uint64_t*)chunk->bfields + 6));    // 2x64 bit is_zero\n    const uint32x4_t vzero1    = vuzp1q_u32(vreinterpretq_u32_u64(vzero1_lo),vreinterpretq_u32_u64(vzero1_hi)); // unzip even elements: narrow to 4x32 bit is_zero ()\n    const uint32x4_t vzero2    = vuzp1q_u32(vreinterpretq_u32_u64(vzero2_lo),vreinterpretq_u32_u64(vzero2_hi)); // unzip even elements: narrow to 4x32 bit is_zero ()\n    const uint32x4_t vzero1x   = vreinterpretq_u32_u64(vshrq_n_u64(vreinterpretq_u64_u32(vzero1), 24));        // shift-right 2x32bit elem by 24: lo 16 bits contain the 2 lo bytes\n    const uint32x4_t vzero2x   = vreinterpretq_u32_u64(vshrq_n_u64(vreinterpretq_u64_u32(vzero2), 24));\n    const uint16x8_t vzero12   = vreinterpretq_u16_u32(vuzp1q_u32(vzero1x,vzero2x));                           // unzip even 32-bit elements into one vector\n    const uint8x8_t  vzero     = vmovn_u16(vzero12);                                                           // narrow the bottom 16-bits\n    const uint64_t mask = ~vget_lane_u64(vreinterpret_u64_u8(vzero), 0);  // 1 byte for each bfield (0xFF => bfield has a bit set)\n    if (mask==0) return false;\n    mi_assert_internal((mi_ctz(mask)%8) == 0); // tzcnt == 0, 8, 16, 24 , ..\n    const size_t chunk_idx = mi_ctz(mask) / 8;\n    if (mi_bchunk_try_find_and_clear_at(chunk, chunk_idx, pidx)) return true;\n    // try again\n    // note: there must be an atomic release/acquire in between or otherwise the registers may not be reloaded\n    // we add an explicit memory barrier as older gcc compilers do not reload the registers even with an atomic acquire (issue #1206)\n    #if defined(__GNUC__)\n    __asm __volatile (\"\" : : \"g\"(chunk) : \"memory\");\n    #endif\n  }\n  #else\n  for (int i = 0; i < MI_BCHUNK_FIELDS; i++) {\n    if (mi_bchunk_try_find_and_clear_at(chunk, i, pidx)) return true;\n  }\n  #endif\n  return false;  \n}\n\nstatic inline bool mi_bchunk_try_find_and_clear_1(mi_bchunk_t* chunk, size_t n, size_t* pidx) {\n  mi_assert_internal(n==1); MI_UNUSED(n);\n  return mi_bchunk_try_find_and_clear(chunk, pidx);\n}\n\nmi_decl_maybe_unused static inline bool mi_bchunk_try_find_and_clear8_at(mi_bchunk_t* chunk, size_t chunk_idx, size_t* pidx) {\n  const mi_bfield_t b = mi_atomic_load_relaxed(&chunk->bfields[chunk_idx]);\n  // has_set8 has low bit in each byte set if the byte in x == 0xFF\n  const mi_bfield_t has_set8 =\n    ((~b - MI_BFIELD_LO_BIT8) &      // high bit set if byte in x is 0xFF or < 0x7F\n     (b  & MI_BFIELD_HI_BIT8))       // high bit set if byte in x is >= 0x80\n     >> 7;                           // shift high bit to low bit\n  size_t idx;\n  if (mi_bfield_find_least_bit(has_set8, &idx)) { // find least 1-bit\n    mi_assert_internal(idx <= (MI_BFIELD_BITS - 8));\n    mi_assert_internal((idx%8)==0);\n    if mi_likely(mi_bfield_atomic_try_clear_mask_of(&chunk->bfields[chunk_idx], (mi_bfield_t)0xFF << idx, b, NULL)) {  // unset the byte atomically\n      *pidx = (chunk_idx*MI_BFIELD_BITS) + idx;\n      mi_assert_internal(*pidx + 8 <= MI_BCHUNK_BITS);\n      return true;\n    }\n  }\n  return false;\n}\n\n// find least aligned byte in a chunk with all bits set, and try unset it atomically\n// set `*pidx` to its bit index (0 <= *pidx < MI_BCHUNK_BITS) on success.\n// Used to find medium size pages in the free blocks.\n// todo: try neon version\nstatic mi_decl_noinline bool mi_bchunk_try_find_and_clear8(mi_bchunk_t* chunk, size_t* pidx) {\n  #if MI_OPT_SIMD && defined(__AVX2__) && (MI_BCHUNK_BITS==512)\n  while (true) {\n    // since a cache-line is 64b, load all at once\n    const __m256i vec1 = _mm256_load_si256((const __m256i*)chunk->bfields);\n    const __m256i vec2 = _mm256_load_si256((const __m256i*)chunk->bfields+1);\n    const __m256i cmpv = mi_mm256_ones();\n    const __m256i vcmp1 = _mm256_cmpeq_epi8(vec1, cmpv); // (byte == ~0 ? 0xFF : 0)\n    const __m256i vcmp2 = _mm256_cmpeq_epi8(vec2, cmpv); // (byte == ~0 ? 0xFF : 0)\n    const uint32_t mask1 = _mm256_movemask_epi8(vcmp1);    // mask of most significant bit of each byte\n    const uint32_t mask2 = _mm256_movemask_epi8(vcmp2);    // mask of most significant bit of each byte\n    const uint64_t mask = ((uint64_t)mask2 << 32) | mask1;\n    // mask is inverted, so each bit is 0xFF iff the corresponding byte has a bit set (and thus can be cleared)\n    if (mask==0) return false;\n    const size_t bidx = _tzcnt_u64(mask);          // byte-idx of the byte in the chunk\n    const size_t chunk_idx = bidx / 8;\n    const size_t idx = (bidx % 8)*8;\n    mi_assert_internal(chunk_idx < MI_BCHUNK_FIELDS);\n    if mi_likely(mi_bfield_atomic_try_clear8(&chunk->bfields[chunk_idx], idx, NULL)) {  // clear it atomically\n      *pidx = (chunk_idx*MI_BFIELD_BITS) + idx;\n      mi_assert_internal(*pidx + 8 <= MI_BCHUNK_BITS);\n      return true;\n    }\n    // try again\n    // note: there must be an atomic release/acquire in between or otherwise the registers may not be reloaded  }\n  }\n  #else\n    for (int i = 0; i < MI_BCHUNK_FIELDS; i++) {\n      if (mi_bchunk_try_find_and_clear8_at(chunk, i, pidx)) return true;\n    }\n    return false;\n  #endif\n}\n\nstatic inline bool mi_bchunk_try_find_and_clear_8(mi_bchunk_t* chunk, size_t n, size_t* pidx) {\n  mi_assert_internal(n==8); MI_UNUSED(n);\n  return mi_bchunk_try_find_and_clear8(chunk, pidx);\n}\n\n\n// find a sequence of `n` bits in a chunk with `0 < n <= MI_BFIELD_BITS` with all bits set,\n// and try to clear them atomically.\n// set `*pidx` to its bit index (0 <= *pidx <= MI_BCHUNK_BITS - n) on success.\n// will cross bfield boundaries.\nmi_decl_noinline static bool mi_bchunk_try_find_and_clearNX(mi_bchunk_t* chunk, size_t n, size_t* pidx) {\n  if (n == 0 || n > MI_BFIELD_BITS) return false;\n  const mi_bfield_t mask = mi_bfield_mask(n, 0);\n  // for all fields in the chunk\n  for (int i = 0; i < MI_BCHUNK_FIELDS; i++) {\n    mi_bfield_t b0 = mi_atomic_load_relaxed(&chunk->bfields[i]);\n    mi_bfield_t b = b0;\n    size_t idx;\n\n    // is there a range inside the field?\n    while (mi_bfield_find_least_bit(b, &idx)) { // find least 1-bit\n      if (idx + n > MI_BFIELD_BITS) break; // too short: maybe cross over, or continue with the next field\n\n      const size_t bmask = mask<<idx;\n      mi_assert_internal(bmask>>idx == mask);\n      if ((b&bmask) == bmask) { // found a match with all bits set, try clearing atomically\n        if mi_likely(mi_bfield_atomic_try_clear_mask_of(&chunk->bfields[i], bmask, b0, NULL)) {\n          *pidx = (i*MI_BFIELD_BITS) + idx;\n          mi_assert_internal(*pidx < MI_BCHUNK_BITS);\n          mi_assert_internal(*pidx + n <= MI_BCHUNK_BITS);\n          return true;\n        }\n        else {\n          // if we failed to atomically commit, reload b and try again from the start\n          b = b0 = mi_atomic_load_acquire(&chunk->bfields[i]);\n        }\n      }\n      else {\n        // advance by clearing the least run of ones, for example, with n>=4, idx=2:\n        // b             = 1111 1101 1010 1100\n        // .. + (1<<idx) = 1111 1101 1011 0000\n        // .. & b        = 1111 1101 1010 0000\n        b = b & (b + (mi_bfield_one() << idx));\n      }\n    }\n\n    // check if we can cross into the next bfield\n    if (b!=0 && i < MI_BCHUNK_FIELDS-1) {\n      const size_t post = mi_bfield_clz(~b);\n      if (post > 0) {\n        const size_t pre = mi_bfield_ctz(~mi_atomic_load_relaxed(&chunk->bfields[i+1]));\n        if (post + pre >= n) {\n          // it fits -- try to claim it atomically\n          const size_t cidx = (i*MI_BFIELD_BITS) + (MI_BFIELD_BITS - post);\n          if (mi_bchunk_try_clearNX(chunk, cidx, n, NULL)) {\n            // we cleared all atomically\n            *pidx = cidx;\n            mi_assert_internal(*pidx < MI_BCHUNK_BITS);\n            mi_assert_internal(*pidx + n <= MI_BCHUNK_BITS);\n            return true;\n          }\n        }\n      }\n    }\n  }\n  return false;\n}\n\n// find a sequence of `n` bits in a chunk with `n <= MI_BCHUNK_BITS` with all bits set,\n// and try to clear them atomically.\n// set `*pidx` to its bit index (0 <= *pidx <= MI_BCHUNK_BITS - n) on success.\n// This can cross bfield boundaries.\nstatic mi_decl_noinline bool mi_bchunk_try_find_and_clearNC(mi_bchunk_t* chunk, size_t n, size_t* pidx) {\n  if (n == 0 || n > MI_BCHUNK_BITS) return false;  // cannot be more than a chunk\n\n  // we first scan ahead to see if there is a range of `n` set bits, and only then try to clear atomically\n  mi_assert_internal(n>0);\n  const size_t skip_count = (n-1)/MI_BFIELD_BITS;\n  size_t cidx;\n  for (size_t i = 0; i < MI_BCHUNK_FIELDS - skip_count; i++)\n  {\n    size_t m = n;   // bits to go\n\n    // first field\n    mi_bfield_t b = mi_atomic_load_relaxed(&chunk->bfields[i]);\n    size_t ones = mi_bfield_clz(~b);\n\n    cidx = (i*MI_BFIELD_BITS) + (MI_BFIELD_BITS - ones);  // start index\n    if (ones >= m) {\n      // we found enough bits already!\n      m = 0;\n    }\n    else if (ones > 0) {\n      // keep scanning further fields until we have enough bits\n      m -= ones;\n      size_t j = 1;   // field count from i\n      while (i+j < MI_BCHUNK_FIELDS) {\n        mi_assert_internal(m > 0);\n        b = mi_atomic_load_relaxed(&chunk->bfields[i+j]);\n        ones = mi_bfield_ctz(~b);\n        if (ones >= m) {\n          // we found enough bits\n          m = 0;\n          break;\n        }\n        else if (ones == MI_BFIELD_BITS) {\n          // not enough yet, proceed to the next field\n          j++;\n          m -= MI_BFIELD_BITS;\n        }\n        else {\n          // the range was not enough, start from scratch\n          i = i + j - 1;  // no need to re-scan previous fields, except the last one (with clz this time)\n          mi_assert_internal(m>0);\n          break;\n        }\n      }\n    }\n\n    // did we find a range?\n    if (m==0) {\n      if (mi_bchunk_try_clearN(chunk, cidx, n, NULL)) {\n        // we cleared all atomically\n        *pidx = cidx;\n        mi_assert_internal(*pidx < MI_BCHUNK_BITS);\n        mi_assert_internal(*pidx + n <= MI_BCHUNK_BITS);\n        return true;\n      }\n      // note: if we fail for a small `n` on the first field, we don't rescan that field (as `i` is incremented)\n    }\n    // otherwise continue searching\n  }\n  return false;\n}\n\n\n\n// ------- mi_bchunk_clear_once_set ---------------------------------------\n\nstatic inline void mi_bchunk_clear_once_set(mi_bchunk_t* chunk, size_t cidx) {\n  mi_assert_internal(cidx < MI_BCHUNK_BITS);\n  const size_t i = cidx / MI_BFIELD_BITS;\n  const size_t idx = cidx % MI_BFIELD_BITS;\n  mi_bfield_atomic_clear_once_set(&chunk->bfields[i], idx);\n}\n\n\n// ------- mi_bitmap_all_are_clear ---------------------------------------\n\n\n// are all bits in a bitmap chunk clear?\nstatic inline bool mi_bchunk_all_are_clear_relaxed(mi_bchunk_t* chunk) {\n  #if MI_OPT_SIMD && defined(__AVX2__) && (MI_BCHUNK_BITS==256)\n  const __m256i vec = _mm256_load_si256((const __m256i*)chunk->bfields);\n  return mi_mm256_is_zero(vec);\n  #elif MI_OPT_SIMD &&  defined(__AVX2__) && (MI_BCHUNK_BITS==512)\n  // a 64b cache-line contains the entire chunk anyway so load both at once\n  const __m256i vec1 = _mm256_load_si256((const __m256i*)chunk->bfields);\n  const __m256i vec2 = _mm256_load_si256(((const __m256i*)chunk->bfields)+1);\n  return (mi_mm256_is_zero(_mm256_or_si256(vec1,vec2)));\n  #elif MI_OPT_SIMD && (MI_BCHUNK_BITS==512) && MI_ARCH_ARM64\n  const uint64x2_t v0 = vld1q_u64((uint64_t*)chunk->bfields);\n  const uint64x2_t v1 = vld1q_u64((uint64_t*)chunk->bfields + 2);\n  const uint64x2_t v2 = vld1q_u64((uint64_t*)chunk->bfields + 4);\n  const uint64x2_t v3 = vld1q_u64((uint64_t*)chunk->bfields + 6);\n  const uint64x2_t v  = vorrq_u64(vorrq_u64(v0,v1),vorrq_u64(v2,v3));\n  return (vmaxvq_u32(vreinterpretq_u32_u64(v)) == 0);\n  #else\n  for (int i = 0; i < MI_BCHUNK_FIELDS; i++) {\n    if (mi_atomic_load_relaxed(&chunk->bfields[i]) != 0) return false;\n  }\n  return true;\n  #endif\n}\n\n// are all bits in a bitmap chunk set?\nstatic inline bool mi_bchunk_all_are_set_relaxed(mi_bchunk_t* chunk) {\n#if MI_OPT_SIMD && defined(__AVX2__) && (MI_BCHUNK_BITS==256)\n  const __m256i vec = _mm256_load_si256((const __m256i*)chunk->bfields);\n  return mi_mm256_is_ones(vec);\n#elif MI_OPT_SIMD &&  defined(__AVX2__) && (MI_BCHUNK_BITS==512)\n  // a 64b cache-line contains the entire chunk anyway so load both at once\n  const __m256i vec1 = _mm256_load_si256((const __m256i*)chunk->bfields);\n  const __m256i vec2 = _mm256_load_si256(((const __m256i*)chunk->bfields)+1);\n  return (mi_mm256_is_ones(_mm256_and_si256(vec1, vec2)));\n#elif MI_OPT_SIMD && (MI_BCHUNK_BITS==512) && MI_ARCH_ARM64\n  const uint64x2_t v0 = vld1q_u64((uint64_t*)chunk->bfields);\n  const uint64x2_t v1 = vld1q_u64((uint64_t*)chunk->bfields + 2);\n  const uint64x2_t v2 = vld1q_u64((uint64_t*)chunk->bfields + 4);\n  const uint64x2_t v3 = vld1q_u64((uint64_t*)chunk->bfields + 6);\n  const uint64x2_t v  = vandq_u64(vandq_u64(v0,v1),vandq_u64(v2,v3));\n  return (vminvq_u32(vreinterpretq_u32_u64(v)) == 0xFFFFFFFFUL);\n#else\n  for (int i = 0; i < MI_BCHUNK_FIELDS; i++) {\n    if (~mi_atomic_load_relaxed(&chunk->bfields[i]) != 0) return false;\n  }\n  return true;\n#endif\n}\n\n\nstatic bool mi_bchunk_bsr(mi_bchunk_t* chunk, size_t* pidx) {\n  for (size_t i = MI_BCHUNK_FIELDS; i > 0; ) {\n    i--;\n    mi_bfield_t b = mi_atomic_load_relaxed(&chunk->bfields[i]);\n    size_t idx;\n    if (mi_bsr(b, &idx)) {\n      *pidx = (i*MI_BFIELD_BITS) + idx;\n      return true;\n    }\n  }\n  return false;\n}\n\nstatic bool mi_bchunk_bsr_inv(mi_bchunk_t* chunk, size_t* pidx) {\n  for (size_t i = MI_BCHUNK_FIELDS; i > 0; ) {\n    i--;\n    mi_bfield_t b = mi_atomic_load_relaxed(&chunk->bfields[i]);\n    size_t idx;\n    if (mi_bsr(~b, &idx)) {\n      *pidx = (i*MI_BFIELD_BITS) + idx;\n      return true;\n    }\n  }\n  return false;\n}\n\nstatic size_t mi_bchunk_popcount(mi_bchunk_t* chunk) {\n  size_t popcount = 0;\n  for (size_t i = 0; i < MI_BCHUNK_FIELDS; i++) {\n    const mi_bfield_t b = mi_atomic_load_relaxed(&chunk->bfields[i]);\n    popcount += mi_bfield_popcount(b);\n  }\n  return popcount;\n}\n\n\n/* --------------------------------------------------------------------------------\n bitmap chunkmap\n-------------------------------------------------------------------------------- */\n\nstatic void mi_bitmap_chunkmap_set(mi_bitmap_t* bitmap, size_t chunk_idx) {\n  mi_assert(chunk_idx < mi_bitmap_chunk_count(bitmap));\n  mi_bchunk_set(&bitmap->chunkmap, chunk_idx, NULL);\n}\n\nstatic bool mi_bitmap_chunkmap_try_clear(mi_bitmap_t* bitmap, size_t chunk_idx) {\n  mi_assert(chunk_idx < mi_bitmap_chunk_count(bitmap));\n  // check if the corresponding chunk is all clear\n  if (!mi_bchunk_all_are_clear_relaxed(&bitmap->chunks[chunk_idx])) return false;\n  // clear the chunkmap bit\n  mi_bchunk_clear(&bitmap->chunkmap, chunk_idx, NULL);\n  // .. but a concurrent set may have happened in between our all-clear test and the clearing of the\n  // bit in the mask. We check again to catch this situation.\n  if (!mi_bchunk_all_are_clear_relaxed(&bitmap->chunks[chunk_idx])) {\n    mi_bchunk_set(&bitmap->chunkmap, chunk_idx, NULL);\n    return false;\n  }\n  return true;\n}\n\n\n/* --------------------------------------------------------------------------------\n  bitmap\n-------------------------------------------------------------------------------- */\n\nsize_t mi_bitmap_size(size_t bit_count, size_t* pchunk_count) {\n  mi_assert_internal((bit_count % MI_BCHUNK_BITS) == 0);\n  bit_count = _mi_align_up(bit_count, MI_BCHUNK_BITS);\n  mi_assert_internal(bit_count <= MI_BITMAP_MAX_BIT_COUNT);\n  mi_assert_internal(bit_count > 0);\n  const size_t chunk_count = bit_count / MI_BCHUNK_BITS;\n  mi_assert_internal(chunk_count >= 1);\n  const size_t size = offsetof(mi_bitmap_t,chunks) + (chunk_count * MI_BCHUNK_SIZE);\n  mi_assert_internal( (size%MI_BCHUNK_SIZE) == 0 );\n  if (pchunk_count != NULL) { *pchunk_count = chunk_count;  }\n  return size;\n}\n\n\n// initialize a bitmap to all unset; avoid a mem_zero if `already_zero` is true\n// returns the size of the bitmap\nsize_t mi_bitmap_init(mi_bitmap_t* bitmap, size_t bit_count, bool already_zero) {\n  size_t chunk_count;\n  const size_t size = mi_bitmap_size(bit_count, &chunk_count);\n  if (!already_zero) {\n    _mi_memzero_aligned(bitmap, size);\n  }\n  mi_atomic_store_release(&bitmap->chunk_count, chunk_count);\n  mi_assert_internal(mi_atomic_load_relaxed(&bitmap->chunk_count) <= MI_BITMAP_MAX_CHUNK_COUNT);\n  return size;\n}\n\n\n// Set a sequence of `n` bits in the bitmap (and can cross chunks). Not atomic so only use if local to a thread.\nstatic void mi_bchunks_unsafe_setN(mi_bchunk_t* chunks, mi_bchunkmap_t* cmap, size_t idx, size_t n) {\n  mi_assert_internal(n>0);\n\n  // start chunk and index\n  size_t chunk_idx = idx / MI_BCHUNK_BITS;\n  const size_t cidx = idx % MI_BCHUNK_BITS;\n  const size_t ccount = _mi_divide_up(n, MI_BCHUNK_BITS);\n\n  // first update the chunkmap\n  mi_bchunk_setN(cmap, chunk_idx, ccount, NULL);\n\n  // first chunk\n  size_t m = MI_BCHUNK_BITS - cidx;\n  if (m > n) { m = n; }\n  mi_bchunk_setN(&chunks[chunk_idx], cidx, m, NULL);\n\n  // n can be large so use memset for efficiency for all in-between chunks\n  chunk_idx++;\n  n -= m;\n  const size_t mid_chunks = n / MI_BCHUNK_BITS;\n  if (mid_chunks > 0) {\n    _mi_memset(&chunks[chunk_idx], ~0, mid_chunks * MI_BCHUNK_SIZE);\n    chunk_idx += mid_chunks;\n    n -= (mid_chunks * MI_BCHUNK_BITS);\n  }\n\n  // last chunk\n  if (n > 0) {\n    mi_assert_internal(n < MI_BCHUNK_BITS);\n    mi_bchunk_setN(&chunks[chunk_idx], 0, n, NULL);\n  }\n}\n\n// Set a sequence of `n` bits in the bitmap (and can cross chunks). Not atomic so only use if local to a thread.\nvoid mi_bitmap_unsafe_setN(mi_bitmap_t* bitmap, size_t idx, size_t n) {\n  mi_assert_internal(n>0);\n  mi_assert_internal(idx + n <= mi_bitmap_max_bits(bitmap));\n  mi_bchunks_unsafe_setN(&bitmap->chunks[0], &bitmap->chunkmap, idx, n);\n}\n\n\n\n\n// ------- mi_bitmap_xset ---------------------------------------\n\n// Set a sequence of `n` bits in the bitmap; returns `true` if atomically transitioned from 0's to 1's (or 1's to 0's).\nbool mi_bitmap_setN(mi_bitmap_t* bitmap, size_t idx, size_t n, size_t* palready_set) {\n  mi_assert_internal(n>0);\n  const size_t maxbits = mi_bitmap_max_bits(bitmap);\n  mi_assert_internal(idx + n <= maxbits);\n  if (idx+n > maxbits) { // paranoia\n    if (idx >= maxbits) return false;\n    n = maxbits - idx;\n  }\n\n  // iterate through the chunks\n  size_t chunk_idx = idx / MI_BCHUNK_BITS;\n  size_t cidx = idx % MI_BCHUNK_BITS;\n  bool were_allclear = true;\n  size_t already_set = 0;\n  while (n > 0) {\n    const size_t m = (cidx + n > MI_BCHUNK_BITS ? MI_BCHUNK_BITS - cidx : n);\n    size_t _already_set = 0;\n    were_allclear = mi_bchunk_setN(&bitmap->chunks[chunk_idx], cidx, m, &_already_set) && were_allclear;\n    already_set += _already_set;\n    mi_bitmap_chunkmap_set(bitmap, chunk_idx); // set afterwards\n    mi_assert_internal(m <= n);\n    n -= m;\n    cidx = 0;\n    chunk_idx++;\n  }\n  if (palready_set != NULL) { *palready_set = already_set;  }\n  return were_allclear;\n}\n\n// Clear a sequence of `n` bits in the bitmap; returns `true` if atomically transitioned from 1's to 0's.\nbool mi_bitmap_clearN(mi_bitmap_t* bitmap, size_t idx, size_t n) {\n  mi_assert_internal(n>0);\n  const size_t maxbits = mi_bitmap_max_bits(bitmap);\n  mi_assert_internal(idx + n <= maxbits);\n  if (idx+n > maxbits) { // paranoia\n    if (idx >= maxbits) return false;\n    n = maxbits - idx;\n  }\n\n  // iterate through the chunks\n  size_t chunk_idx = idx / MI_BCHUNK_BITS;\n  size_t cidx = idx % MI_BCHUNK_BITS;\n  bool were_allset = true;\n  while (n > 0) {\n    const size_t m = (cidx + n > MI_BCHUNK_BITS ? MI_BCHUNK_BITS - cidx : n);\n    bool maybe_all_clear = false;\n    were_allset = mi_bchunk_clearN(&bitmap->chunks[chunk_idx], cidx, m, &maybe_all_clear) && were_allset;\n    if (maybe_all_clear) { mi_bitmap_chunkmap_try_clear(bitmap, chunk_idx); }\n    mi_assert_internal(m <= n);\n    n -= m;\n    cidx = 0;\n    chunk_idx++;\n  }\n  return were_allset;\n}\n\n// Count bits set in a range of `n` bits.\nsize_t mi_bitmap_popcountN( mi_bitmap_t* bitmap, size_t idx, size_t n) {\n  mi_assert_internal(n>0);\n  const size_t maxbits = mi_bitmap_max_bits(bitmap);\n  mi_assert_internal(idx + n <= maxbits);\n  if (idx+n > maxbits) { // paranoia\n    if (idx >= maxbits) return 0;\n    n = maxbits - idx;\n  }\n\n  // iterate through the chunks\n  size_t chunk_idx = idx / MI_BCHUNK_BITS;\n  size_t cidx = idx % MI_BCHUNK_BITS;\n  size_t popcount = 0;\n  while (n > 0) {\n    const size_t m = (cidx + n > MI_BCHUNK_BITS ? MI_BCHUNK_BITS - cidx : n);\n    popcount += mi_bchunk_popcountN(&bitmap->chunks[chunk_idx], cidx, m);\n    mi_assert_internal(m <= n);\n    n -= m;\n    cidx = 0;\n    chunk_idx++;\n  }\n  return popcount;\n}\n\n\n// Set/clear a bit in the bitmap; returns `true` if atomically transitioned from 0 to 1 (or 1 to 0)\nbool mi_bitmap_set(mi_bitmap_t* bitmap, size_t idx) {\n  return mi_bitmap_setN(bitmap, idx, 1, NULL);\n}\n\nbool mi_bitmap_clear(mi_bitmap_t* bitmap, size_t idx) {\n  return mi_bitmap_clearN(bitmap, idx, 1);\n}\n\n\n\n// ------- mi_bitmap_is_xset ---------------------------------------\n\n// Is a sequence of n bits already all set/cleared?\nbool mi_bitmap_is_xsetN(mi_xset_t set, mi_bitmap_t* bitmap, size_t idx, size_t n) {\n  mi_assert_internal(n>0);\n  const size_t maxbits = mi_bitmap_max_bits(bitmap);\n  mi_assert_internal(idx + n <= maxbits);\n  if (idx+n > maxbits) { // paranoia\n    if (idx >= maxbits) return false;\n    n = maxbits - idx;\n  }\n\n  // iterate through the chunks\n  size_t chunk_idx = idx / MI_BCHUNK_BITS;\n  size_t cidx = idx % MI_BCHUNK_BITS;\n  bool xset = true;\n  while (n > 0 && xset) {\n    const size_t m = (cidx + n > MI_BCHUNK_BITS ? MI_BCHUNK_BITS - cidx : n);\n    xset = mi_bchunk_is_xsetN(set, &bitmap->chunks[chunk_idx], cidx, m) && xset;\n    mi_assert_internal(m <= n);\n    n -= m;\n    cidx = 0;\n    chunk_idx++;\n  }\n  return xset;\n}\n\nbool mi_bitmap_is_all_clear(mi_bitmap_t* bitmap) {\n  return mi_bitmap_is_xsetN(MI_BIT_CLEAR, bitmap, 0, mi_bitmap_max_bits(bitmap));\n}\n\n/* --------------------------------------------------------------------------------\n  Iterate through a bfield\n-------------------------------------------------------------------------------- */\n\n// Cycle iteration through a bitfield. This is used to space out threads\n// so there is less chance of contention. When searching for a free page we\n// like to first search only the accessed part (so we reuse better). This\n// high point is called the `cycle`.\n//\n// We then iterate through the bitfield as:\n// first: [start, cycle>\n// then : [0, start>\n// then : [cycle, MI_BFIELD_BITS>\n//\n// The start is determined usually as `tseq % cycle` to have each thread\n// start at a different spot.\n// - We use `popcount` to improve branch prediction (maybe not needed? can we simplify?)\n// - The `cycle_mask` is the part `[start, cycle>`.\n#define mi_bfield_iterate(bfield,start,cycle,name_idx,SUF) { \\\n  mi_assert_internal(start <= cycle); \\\n  mi_assert_internal(start < MI_BFIELD_BITS); \\\n  mi_assert_internal(cycle <= MI_BFIELD_BITS); \\\n  const mi_bfield_t _cycle_mask##SUF = mi_bfield_mask(cycle - start, start); \\\n  size_t _bcount##SUF = mi_bfield_popcount(bfield); \\\n  mi_bfield_t _b##SUF = bfield & _cycle_mask##SUF; /* process [start, cycle> first*/\\\n  while(_bcount##SUF > 0) { \\\n    _bcount##SUF--;\\\n    if (_b##SUF==0) { _b##SUF = bfield & ~_cycle_mask##SUF; } /* process [0,start> + [cycle, MI_BFIELD_BITS> next */ \\\n    /* size_t name_idx; */ \\\n    const bool _found##SUF = mi_bfield_find_least_bit(_b##SUF,&name_idx); \\\n    _b##SUF = mi_bfield_clear_least_bit(_b##SUF); /* clear early so `continue` works */ \\\n    mi_assert_internal(_found##SUF); MI_UNUSED(_found##SUF); \\\n    { \\\n\n#define mi_bfield_iterate_end(SUF) \\\n    } \\\n  } \\\n}\n\n\n#define mi_bfield_cycle_iterate(bfield,tseq,cycle,name_idx,SUF) { \\\n  const size_t _start##SUF = (uint32_t)(tseq) % (uint32_t)(cycle); /* or: 0 to always search from the start? */\\\n  mi_bfield_iterate(bfield,_start##SUF,cycle,name_idx,SUF)\n\n#define mi_bfield_cycle_iterate_end(SUF) \\\n  mi_bfield_iterate_end(SUF); \\\n}\n\n\n/* --------------------------------------------------------------------------------\n  mi_bitmap_find\n  (used to find free pages)\n-------------------------------------------------------------------------------- */\n\ntypedef bool (mi_bitmap_visit_fun_t)(mi_bitmap_t* bitmap, size_t chunk_idx, size_t n, size_t* idx, void* arg1, void* arg2);\n\n// Go through the bitmap and for every sequence of `n` set bits, call the visitor function.\n// If it returns `true` stop the search.\nstatic inline bool mi_bitmap_find(mi_bitmap_t* bitmap, size_t tseq, size_t n, size_t* pidx, mi_bitmap_visit_fun_t* on_find, void* arg1, void* arg2)\n{\n  const size_t chunkmap_max = _mi_divide_up(mi_bitmap_chunk_count(bitmap), MI_BFIELD_BITS);\n  for (size_t i = 0; i < chunkmap_max; i++) {\n    // and for each chunkmap entry we iterate over its bits to find the chunks\n    const mi_bfield_t cmap_entry = mi_atomic_load_relaxed(&bitmap->chunkmap.bfields[i]);\n    size_t hi;\n    if (mi_bfield_find_highest_bit(cmap_entry, &hi)) {\n      size_t eidx = 0;\n      mi_bfield_cycle_iterate(cmap_entry, tseq%8, hi+1, eidx, Y) // reduce the tseq to 8 bins to reduce using extra memory (see `mstress`)\n      {\n        mi_assert_internal(eidx <= MI_BFIELD_BITS);\n        const size_t chunk_idx = i*MI_BFIELD_BITS + eidx;\n        mi_assert_internal(chunk_idx < mi_bitmap_chunk_count(bitmap));\n        if ((*on_find)(bitmap, chunk_idx, n, pidx, arg1, arg2)) {\n          return true;\n        }\n      }\n      mi_bfield_cycle_iterate_end(Y);\n    }\n  }\n  return false;\n}\n\n\n/* --------------------------------------------------------------------------------\n  Bitmap: try_find_and_claim  -- used to allocate abandoned pages\n  note: the compiler will fully inline the indirect function call\n-------------------------------------------------------------------------------- */\n\ntypedef struct mi_claim_fun_data_s {\n  mi_arena_t*   arena;  \n} mi_claim_fun_data_t;\n\nstatic bool mi_bitmap_try_find_and_claim_visit(mi_bitmap_t* bitmap, size_t chunk_idx, size_t n, size_t* pidx, void* arg1, void* arg2)\n{\n  mi_assert_internal(n==1); MI_UNUSED(n);\n  mi_claim_fun_t* claim_fun = (mi_claim_fun_t*)arg1;\n  mi_claim_fun_data_t* claim_data = (mi_claim_fun_data_t*)arg2;\n  size_t cidx;\n  if mi_likely(mi_bchunk_try_find_and_clear(&bitmap->chunks[chunk_idx], &cidx)) {\n    const size_t slice_index = (chunk_idx * MI_BCHUNK_BITS) + cidx;\n    mi_assert_internal(slice_index < mi_bitmap_max_bits(bitmap));\n    bool keep_set = true;\n    if ((*claim_fun)(slice_index, claim_data->arena, &keep_set)) {\n      // success!\n      mi_assert_internal(!keep_set);\n      *pidx = slice_index;\n      return true;\n    }\n    else {\n      // failed to claim it, set abandoned mapping again (unless the page was freed)\n      if (keep_set) {\n        const bool wasclear = mi_bchunk_set(&bitmap->chunks[chunk_idx], cidx, NULL);\n        mi_assert_internal(wasclear); MI_UNUSED(wasclear);\n      }\n    }\n  }\n  else {\n    // we may find that all are cleared only on a second iteration but that is ok as\n    // the chunkmap is a conservative approximation.\n    mi_bitmap_chunkmap_try_clear(bitmap, chunk_idx);\n  }\n  return false;\n}\n\n// Find a set bit in the bitmap and try to atomically clear it and claim it.\n// (Used to find pages in the pages_abandoned bitmaps.)\nmi_decl_nodiscard bool mi_bitmap_try_find_and_claim(mi_bitmap_t* bitmap, size_t tseq, size_t* pidx,\n  mi_claim_fun_t* claim, mi_arena_t* arena )\n{\n  mi_claim_fun_data_t claim_data = { arena };\n  return mi_bitmap_find(bitmap, tseq, 1, pidx, &mi_bitmap_try_find_and_claim_visit, (void*)claim, &claim_data);\n}\n\n\nbool mi_bitmap_bsr(mi_bitmap_t* bitmap, size_t* idx) {\n  const size_t chunkmap_max = _mi_divide_up(mi_bitmap_chunk_count(bitmap), MI_BFIELD_BITS);\n  for (size_t i = chunkmap_max; i > 0; ) {\n    i--;\n    mi_bfield_t cmap = mi_atomic_load_relaxed(&bitmap->chunkmap.bfields[i]);\n    size_t cmap_idx;\n    if (mi_bsr(cmap,&cmap_idx)) {\n      // highest chunk\n      const size_t chunk_idx = i*MI_BFIELD_BITS + cmap_idx;\n      size_t cidx;\n      if (mi_bchunk_bsr(&bitmap->chunks[chunk_idx], &cidx)) {\n        *idx = (chunk_idx * MI_BCHUNK_BITS) + cidx;\n        return true;\n      }\n    }\n  }\n  return false;\n}\n\n// Return count of all set bits in a bitmap.\nsize_t mi_bitmap_popcount(mi_bitmap_t* bitmap) {\n  // for all chunkmap entries\n  size_t popcount = 0;\n  const size_t chunkmap_max = _mi_divide_up(mi_bitmap_chunk_count(bitmap), MI_BFIELD_BITS);\n  for (size_t i = 0; i < chunkmap_max; i++) {\n    mi_bfield_t cmap_entry = mi_atomic_load_relaxed(&bitmap->chunkmap.bfields[i]);\n    size_t cmap_idx;\n    // for each chunk (corresponding to a set bit in a chunkmap entry)\n    while (mi_bfield_foreach_bit(&cmap_entry, &cmap_idx)) {\n      const size_t chunk_idx = i*MI_BFIELD_BITS + cmap_idx;\n      // count bits in a chunk\n      popcount += mi_bchunk_popcount(&bitmap->chunks[chunk_idx]);\n    }\n  }\n  return popcount;\n}\n\n\n\n// Clear a bit once it is set.\nvoid mi_bitmap_clear_once_set(mi_bitmap_t* bitmap, size_t idx) {\n  mi_assert_internal(idx < mi_bitmap_max_bits(bitmap));\n  const size_t chunk_idx = idx / MI_BCHUNK_BITS;\n  const size_t cidx = idx % MI_BCHUNK_BITS;\n  mi_assert_internal(chunk_idx < mi_bitmap_chunk_count(bitmap));\n  mi_bchunk_clear_once_set(&bitmap->chunks[chunk_idx], cidx);\n}\n\n\n// Visit all set bits in a bitmap.\n// todo: optimize further? maybe use avx512 to directly get all indices using a mask_compressstore?\nbool _mi_bitmap_forall_set(mi_bitmap_t* bitmap, mi_forall_set_fun_t* visit, mi_arena_t* arena, void* arg) {\n  // for all chunkmap entries\n  const size_t chunkmap_max = _mi_divide_up(mi_bitmap_chunk_count(bitmap), MI_BFIELD_BITS);\n  for(size_t i = 0; i < chunkmap_max; i++) {\n    mi_bfield_t cmap_entry = mi_atomic_load_relaxed(&bitmap->chunkmap.bfields[i]);\n    size_t cmap_idx;\n    // for each chunk (corresponding to a set bit in a chunkmap entry)\n    while (mi_bfield_foreach_bit(&cmap_entry, &cmap_idx)) {\n      const size_t chunk_idx = i*MI_BFIELD_BITS + cmap_idx;\n      // for each chunk field\n      mi_bchunk_t* const chunk = &bitmap->chunks[chunk_idx];\n      for (size_t j = 0; j < MI_BCHUNK_FIELDS; j++) {\n        const size_t base_idx = (chunk_idx*MI_BCHUNK_BITS) + (j*MI_BFIELD_BITS);\n        mi_bfield_t b = mi_atomic_load_relaxed(&chunk->bfields[j]);\n        size_t bidx;\n        while (mi_bfield_foreach_bit(&b, &bidx)) {\n          const size_t idx = base_idx + bidx;\n          if (!visit(idx, 1, arena, arg)) return false;\n        }\n      }\n    }\n  }\n  return true;\n}\n\n// Visit all set bits in a bitmap but try to return ranges (within bfields) if possible.\n// Also clear those ranges atomically.\n// Used by purging to purge larger ranges when possible\n// todo: optimize further? maybe use avx512 to directly get all indices using a mask_compressstore?\nbool _mi_bitmap_forall_setc_ranges(mi_bitmap_t* bitmap, mi_forall_set_fun_t* visit, mi_arena_t* arena, void* arg) {\n  // for all chunkmap entries\n  const size_t chunkmap_max = _mi_divide_up(mi_bitmap_chunk_count(bitmap), MI_BFIELD_BITS);\n  for (size_t i = 0; i < chunkmap_max; i++) {\n    mi_bfield_t cmap_entry = mi_atomic_load_relaxed(&bitmap->chunkmap.bfields[i]);\n    size_t cmap_idx;\n    // for each chunk (corresponding to a set bit in a chunkmap entry)\n    while (mi_bfield_foreach_bit(&cmap_entry, &cmap_idx)) {\n      const size_t chunk_idx = i*MI_BFIELD_BITS + cmap_idx;\n      // for each chunk field\n      mi_bchunk_t* const chunk = &bitmap->chunks[chunk_idx];\n      for (size_t j = 0; j < MI_BCHUNK_FIELDS; j++) {\n        const size_t base_idx = (chunk_idx*MI_BCHUNK_BITS) + (j*MI_BFIELD_BITS);\n        mi_bfield_t b = mi_atomic_exchange_relaxed(&chunk->bfields[j], (mi_bfield_t)0);\n        #if MI_DEBUG > 1\n        const size_t bpopcount = mi_popcount(b);\n        size_t rngcount = 0;\n        #endif\n        size_t bidx;\n        while (mi_bfield_find_least_bit(b, &bidx)) {\n          size_t rng = mi_ctz(~(b>>bidx)); // all the set bits from bidx\n          #if MI_DEBUG > 1\n          rngcount += rng;\n          #endif\n          const size_t idx = base_idx + bidx;\n          mi_assert_internal(rng>=1 && rng<=MI_BFIELD_BITS);\n          mi_assert_internal((idx % MI_BFIELD_BITS) + rng <= MI_BFIELD_BITS);\n          mi_assert_internal((idx / MI_BCHUNK_BITS) < mi_bitmap_chunk_count(bitmap));\n          if (!visit(idx, rng, arena, arg)) {\n            // break early: reset the non-visited bits\n            if (b!=0) {\n              mi_atomic_or_relaxed(&chunk->bfields[j], b);\n            }\n            return false;\n          }\n          // clear rng bits in b\n          b = b & ~mi_bfield_mask(rng, bidx);\n        }\n        mi_assert_internal(rngcount == bpopcount);\n      }\n    }\n  }\n  return true;\n}\n\n// Visit all set bits in a bitmap but try to return ranges (within bfields) if possible,\n// but only in chunks of at least `rngslices` slices (that are also aligned at `rngslices`)\n// and clear those ranges atomically.\n// However, the `rngslices` are capped at `MI_BFIELD_BITS` at most.\n// Used by purging to purge larger ranges when possible. With transparent huge pages we only\n// want to purge whole huge pages (2 MiB) at a time which is what the `rngslices` parameter achieves.\nbool _mi_bitmap_forall_setc_rangesn(mi_bitmap_t* bitmap, size_t rngslices, mi_forall_set_fun_t* visit, mi_arena_t* arena, void* arg) \n{\n  // use the generic routine for `rngslices<=1` (as that one finds longest ranges at a time)\n  if (rngslices<=1) {\n    return _mi_bitmap_forall_setc_ranges(bitmap, visit, arena, arg);\n  }\n  // mi_assert_internal(rngslices <= MI_BFIELD_BITS);  \n  if (rngslices > MI_BFIELD_BITS) { rngslices = MI_BFIELD_BITS;  } // cap at MI_BFIELD_BITS at most\n\n  // for all chunkmap entries\n  const size_t chunkmap_max = _mi_divide_up(mi_bitmap_chunk_count(bitmap), MI_BFIELD_BITS);\n  for (size_t i = 0; i < chunkmap_max; i++) {\n    mi_bfield_t cmap_entry = mi_atomic_load_relaxed(&bitmap->chunkmap.bfields[i]);\n    size_t cmap_idx;\n    // for each chunk (corresponding to a set bit in a chunkmap entry)\n    while (mi_bfield_foreach_bit(&cmap_entry, &cmap_idx)) {\n      const size_t chunk_idx = i*MI_BFIELD_BITS + cmap_idx;\n      // for each chunk field\n      mi_bchunk_t* const chunk = &bitmap->chunks[chunk_idx];\n      for (size_t j = 0; j < MI_BCHUNK_FIELDS; j++) {\n        const size_t base_idx = (chunk_idx*MI_BCHUNK_BITS) + (j*MI_BFIELD_BITS);\n        mi_bfield_t b = mi_atomic_exchange_relaxed(&chunk->bfields[j], (mi_bfield_t)0);   // atomic clear\n        mi_bfield_t skipped = 0;                                                          // but track which bits we skip so we can restore them\n        for(size_t shift = 0; rngslices + shift <= MI_BFIELD_BITS; shift += rngslices) {  // per `rngslices` to keep alignment\n          const mi_bfield_t rngmask = mi_bfield_mask(rngslices, shift);\n          if ((b & rngmask) == rngmask) {\n            const size_t idx = base_idx + shift;\n            if (!visit(idx, rngslices, arena, arg)) {\n              // break early: restore non-visited entries\n              mi_bfield_t notyet_visited = 0;\n              if (shift + rngslices < MI_BFIELD_BITS) {\n                notyet_visited = (b & (~(mi_bfield_t)0 << (shift + rngslices)));\n              }\n              mi_assert_internal((notyet_visited & skipped) == 0);\n              if ((notyet_visited | skipped) != 0) {\n                mi_atomic_or_relaxed(&chunk->bfields[j], notyet_visited | skipped);\n              }\n              return false;\n            }\n          }\n          else {\n            skipped = skipped | (b & rngmask);\n          }          \n        } \n        \n        if (skipped != 0) {\n          mi_atomic_or_relaxed(&chunk->bfields[j], skipped);\n        }\n      }\n    }\n  }\n  return true;\n}\n\n\n/* --------------------------------------------------------------------------------\n  binned bitmap's\n-------------------------------------------------------------------------------- */\n\n\nsize_t mi_bbitmap_size(size_t bit_count, size_t* pchunk_count) {\n  // mi_assert_internal((bit_count % MI_BCHUNK_BITS) == 0);\n  bit_count = _mi_align_up(bit_count, MI_BCHUNK_BITS);\n  mi_assert_internal(bit_count <= MI_BITMAP_MAX_BIT_COUNT);\n  mi_assert_internal(bit_count > 0);\n  const size_t chunk_count = bit_count / MI_BCHUNK_BITS;\n  mi_assert_internal(chunk_count >= 1);\n  const size_t size = offsetof(mi_bbitmap_t,chunks) + (chunk_count * MI_BCHUNK_SIZE);\n  mi_assert_internal( (size%MI_BCHUNK_SIZE) == 0 );\n  if (pchunk_count != NULL) { *pchunk_count = chunk_count;  }\n  return size;\n}\n\n// initialize a bitmap to all unset; avoid a mem_zero if `already_zero` is true\n// returns the size of the bitmap\nsize_t mi_bbitmap_init(mi_bbitmap_t* bbitmap, size_t bit_count, bool already_zero) {\n  size_t chunk_count;\n  const size_t size = mi_bbitmap_size(bit_count, &chunk_count);\n  if (!already_zero) {\n    _mi_memzero_aligned(bbitmap, size);\n  }\n  mi_atomic_store_release(&bbitmap->chunk_count, chunk_count);\n  mi_assert_internal(mi_atomic_load_relaxed(&bbitmap->chunk_count) <= MI_BITMAP_MAX_CHUNK_COUNT);\n  return size;\n}\n\nvoid mi_bbitmap_unsafe_setN(mi_bbitmap_t* bbitmap, size_t idx, size_t n) {\n  mi_assert_internal(n>0);\n  mi_assert_internal(idx + n <= mi_bbitmap_max_bits(bbitmap));\n  mi_bchunks_unsafe_setN(&bbitmap->chunks[0], &bbitmap->chunkmap, idx, n);\n}\n\nbool mi_bbitmap_bsr_inv(mi_bbitmap_t* bbitmap, size_t* idx) {\n  const size_t chunk_count = mi_bbitmap_chunk_count(bbitmap);\n  const size_t chunkmap_max = _mi_divide_up(chunk_count, MI_BFIELD_BITS);\n  size_t skip_at_top = chunk_count % MI_BFIELD_BITS;\n  for (size_t i = chunkmap_max; i > 0; ) {\n    i--;\n    mi_bfield_t cmap = mi_atomic_load_relaxed(&bbitmap->chunkmap.bfields[i]);\n    size_t cmap_idx;\n    // don't consider top 0 bits; set those to 1 here\n    if (skip_at_top > 0) {\n      const size_t mask_top = (~mi_bfield_zero()) << (MI_BFIELD_BITS - skip_at_top);\n      skip_at_top = 0;   // only for the first iteration\n      cmap |= mask_top;\n    }\n    if (mi_bsr(~cmap, &cmap_idx)) {\n      // highest chunk\n      const size_t chunk_idx = i*MI_BFIELD_BITS + cmap_idx;\n      size_t cidx;\n      if (mi_bchunk_bsr_inv(&bbitmap->chunks[chunk_idx], &cidx)) {\n        *idx = (chunk_idx * MI_BCHUNK_BITS) + cidx;\n        return true;\n      }\n    }\n  }\n  return false;\n}\n\n\n/* --------------------------------------------------------------------------------\n binned bitmap used to track free slices\n-------------------------------------------------------------------------------- */\n\n// Assign a specific size bin to a chunk\nstatic void mi_bbitmap_set_chunk_bin(mi_bbitmap_t* bbitmap, size_t chunk_idx, mi_chunkbin_t bin) {\n  mi_assert_internal(chunk_idx < mi_bbitmap_chunk_count(bbitmap));\n  for (mi_chunkbin_t ibin = MI_CBIN_SMALL; ibin < MI_CBIN_NONE; ibin = mi_chunkbin_inc(ibin)) {\n    if (ibin == bin) {\n      const bool was_clear = mi_bchunk_set(& bbitmap->chunkmap_bins[ibin], chunk_idx, NULL);\n      if (was_clear) { mi_os_stat_increase(chunk_bins[ibin],1); }\n    }\n    else {\n      const bool was_set = mi_bchunk_clear(&bbitmap->chunkmap_bins[ibin], chunk_idx, NULL);\n      if (was_set) { mi_os_stat_decrease(chunk_bins[ibin],1); }\n    }\n  }\n}\n\nmi_chunkbin_t mi_bbitmap_debug_get_bin(const mi_bchunkmap_t* chunkmap_bins, size_t chunk_idx) {\n  for (mi_chunkbin_t ibin = MI_CBIN_SMALL; ibin < MI_CBIN_NONE; ibin = mi_chunkbin_inc(ibin)) {\n    if (mi_bchunk_is_xsetN(MI_BIT_SET, &chunkmap_bins[ibin], chunk_idx, 1)) {\n      return ibin;\n    }\n  }\n  return MI_CBIN_NONE;\n}\n\n// Track the index of the highest chunk that is accessed.\nstatic void mi_bbitmap_chunkmap_set_max(mi_bbitmap_t* bbitmap, size_t chunk_idx) {\n  size_t oldmax = mi_atomic_load_relaxed(&bbitmap->chunk_max_accessed);\n  if mi_unlikely(chunk_idx > oldmax) {\n    mi_atomic_cas_strong_relaxed(&bbitmap->chunk_max_accessed, &oldmax, chunk_idx);\n  }\n}\n\n// Set a bit in the chunkmap\nstatic void mi_bbitmap_chunkmap_set(mi_bbitmap_t* bbitmap, size_t chunk_idx, bool check_all_set) {\n  mi_assert(chunk_idx < mi_bbitmap_chunk_count(bbitmap));\n  if (check_all_set) {\n    if (mi_bchunk_all_are_set_relaxed(&bbitmap->chunks[chunk_idx])) {\n      // all slices are free in this chunk: return back to the NONE bin\n      mi_bbitmap_set_chunk_bin(bbitmap, chunk_idx, MI_CBIN_NONE);\n    }\n  }\n  mi_bchunk_set(&bbitmap->chunkmap, chunk_idx, NULL);\n  mi_bbitmap_chunkmap_set_max(bbitmap, chunk_idx);\n}\n\nstatic bool mi_bbitmap_chunkmap_try_clear(mi_bbitmap_t* bbitmap, size_t chunk_idx) {\n  mi_assert(chunk_idx < mi_bbitmap_chunk_count(bbitmap));\n  // check if the corresponding chunk is all clear\n  if (!mi_bchunk_all_are_clear_relaxed(&bbitmap->chunks[chunk_idx])) return false;\n  // clear the chunkmap bit\n  mi_bchunk_clear(&bbitmap->chunkmap, chunk_idx, NULL);\n  // .. but a concurrent set may have happened in between our all-clear test and the clearing of the\n  // bit in the mask. We check again to catch this situation. (note: mi_bchunk_clear must be acq-rel)\n  if (!mi_bchunk_all_are_clear_relaxed(&bbitmap->chunks[chunk_idx])) {\n    mi_bchunk_set(&bbitmap->chunkmap, chunk_idx, NULL);\n    return false;\n  }\n  mi_bbitmap_chunkmap_set_max(bbitmap, chunk_idx);\n  return true;\n}\n\n\n/* --------------------------------------------------------------------------------\n  mi_bbitmap_setN, try_clearN, and is_xsetN\n  (used to find free pages)\n-------------------------------------------------------------------------------- */\n\n// Set a sequence of `n` bits in the bitmap; returns `true` if atomically transitioned from 0's to 1's (or 1's to 0's).\nbool mi_bbitmap_setN(mi_bbitmap_t* bbitmap, size_t idx, size_t n) {\n  mi_assert_internal(n>0);\n  const size_t maxbits = mi_bbitmap_max_bits(bbitmap);\n  mi_assert_internal(idx + n <= maxbits);\n  if (idx+n > maxbits) { // paranoia\n    if (idx >= maxbits) return false;\n    n = maxbits - idx;\n  }\n\n  // iterate through the chunks\n  size_t chunk_idx = idx / MI_BCHUNK_BITS;\n  size_t cidx = idx % MI_BCHUNK_BITS;\n  bool were_allclear = true;\n  while (n > 0) {\n    const size_t m = (cidx + n > MI_BCHUNK_BITS ? MI_BCHUNK_BITS - cidx : n);\n    were_allclear = mi_bchunk_setN(&bbitmap->chunks[chunk_idx], cidx, m, NULL) && were_allclear;\n    mi_bbitmap_chunkmap_set(bbitmap, chunk_idx, true); // set afterwards\n    mi_assert_internal(m <= n);\n    n -= m;\n    cidx = 0;\n    chunk_idx++;\n  }\n  return were_allclear;\n}\n\n// ------- mi_bbitmap_try_clearNC ---------------------------------------\n\n// Try to clear `n` bits at `idx` where `n <= MI_BCHUNK_BITS`.\nbool mi_bbitmap_try_clearNC(mi_bbitmap_t* bbitmap, size_t idx, size_t n) {\n  mi_assert_internal(n>0);\n  mi_assert_internal(n<=MI_BCHUNK_BITS);\n  mi_assert_internal(idx + n <= mi_bbitmap_max_bits(bbitmap));\n\n  const size_t chunk_idx = idx / MI_BCHUNK_BITS;\n  const size_t cidx = idx % MI_BCHUNK_BITS;\n  mi_assert_internal(cidx + n <= MI_BCHUNK_BITS);  // don't cross chunks (for now)\n  mi_assert_internal(chunk_idx < mi_bbitmap_chunk_count(bbitmap));\n  if (cidx + n > MI_BCHUNK_BITS) return false;\n  bool maybe_all_clear = false;\n  const bool cleared = mi_bchunk_try_clearN(&bbitmap->chunks[chunk_idx], cidx, n, &maybe_all_clear);\n  if (cleared && maybe_all_clear) { mi_bbitmap_chunkmap_try_clear(bbitmap, chunk_idx); }\n  // note: we don't set the size class for an explicit try_clearN (only used by purging)\n  return cleared;\n}\n\n\n\n// ------- mi_bbitmap_is_xset ---------------------------------------\n\n// Is a sequence of n bits already all set/cleared?\nbool mi_bbitmap_is_xsetN(mi_xset_t set, mi_bbitmap_t* bbitmap, size_t idx, size_t n) {\n  mi_assert_internal(n>0);\n  const size_t maxbits = mi_bbitmap_max_bits(bbitmap);\n  mi_assert_internal(idx + n <= maxbits);\n  if (idx+n > maxbits) { // paranoia\n    if (idx >= maxbits) return false;\n    n = maxbits - idx;\n  }\n\n  // iterate through the chunks\n  size_t chunk_idx = idx / MI_BCHUNK_BITS;\n  size_t cidx = idx % MI_BCHUNK_BITS;\n  bool xset = true;\n  while (n > 0 && xset) {\n    const size_t m = (cidx + n > MI_BCHUNK_BITS ? MI_BCHUNK_BITS - cidx : n);\n    xset = mi_bchunk_is_xsetN(set, &bbitmap->chunks[chunk_idx], cidx, m) && xset;\n    mi_assert_internal(m <= n);\n    n -= m;\n    cidx = 0;\n    chunk_idx++;\n  }\n  return xset;\n}\n\n\n\n\n/* --------------------------------------------------------------------------------\n  mi_bbitmap_find\n  (used to find free pages)\n-------------------------------------------------------------------------------- */\n\ntypedef bool (mi_bchunk_try_find_and_clear_fun_t)(mi_bchunk_t* chunk, size_t n, size_t* idx);\n\n// Go through the bbitmap and for every sequence of `n` set bits, call the visitor function.\n// If it returns `true` stop the search.\n//\n// This is used for finding free blocks and it is important to be efficient (with 2-level bitscan)\n// but also reduce fragmentation (through size bins).\nstatic inline bool mi_bbitmap_try_find_and_clear_generic(mi_bbitmap_t* bbitmap, size_t tseq, size_t n, size_t* pidx, mi_bchunk_try_find_and_clear_fun_t* on_find)\n{\n  // we space out threads to reduce contention\n  const size_t cmap_max_count  = _mi_divide_up(mi_bbitmap_chunk_count(bbitmap),MI_BFIELD_BITS);\n  const size_t chunk_acc       = mi_atomic_load_relaxed(&bbitmap->chunk_max_accessed);\n  const size_t cmap_acc        = chunk_acc / MI_BFIELD_BITS;\n  const size_t cmap_acc_bits   = 1 + (chunk_acc % MI_BFIELD_BITS);\n\n  // create a mask over the chunkmap entries to iterate over them efficiently\n  mi_assert_internal(MI_BFIELD_BITS >= MI_BCHUNK_FIELDS);\n  const mi_bfield_t cmap_mask  = mi_bfield_mask(cmap_max_count,0);\n  const size_t cmap_cycle      = cmap_acc+1;\n  const mi_chunkbin_t bbin = mi_chunkbin_of(n);\n  // visit each cmap entry\n  size_t cmap_idx = 0;\n  mi_bfield_cycle_iterate(cmap_mask, tseq, cmap_cycle, cmap_idx, X)\n  {\n    // and for each chunkmap entry we iterate over its bits to find the chunks\n    const mi_bfield_t cmap_entry = mi_atomic_load_relaxed(&bbitmap->chunkmap.bfields[cmap_idx]);\n    const size_t cmap_entry_cycle = (cmap_idx != cmap_acc ? MI_BFIELD_BITS : cmap_acc_bits);\n    if (cmap_entry == 0) {\n      continue;\n    }\n\n    // get size bin masks\n    mi_bfield_t cmap_bins[MI_CBIN_COUNT] = { 0 };\n    cmap_bins[MI_CBIN_NONE] = cmap_entry;\n    for (mi_chunkbin_t ibin = MI_CBIN_SMALL; ibin < MI_CBIN_NONE; ibin = mi_chunkbin_inc(ibin)) {\n      const mi_bfield_t cmap_bin = mi_atomic_load_relaxed(&bbitmap->chunkmap_bins[ibin].bfields[cmap_idx]);\n      cmap_bins[ibin] = cmap_bin & cmap_entry;\n      cmap_bins[MI_CBIN_NONE] &= ~cmap_bin;      // clear bits that are in an assigned size bin\n    }\n\n    // consider only chunks for a particular size bin at a time\n    // this picks the best bin only within a cmap entry (~ 1GiB address space), but avoids multiple\n    // iterations through all entries.\n    mi_assert_internal(bbin < MI_CBIN_NONE);\n    for (mi_chunkbin_t ibin = MI_CBIN_SMALL; ibin <= MI_CBIN_NONE;\n          // skip from bbin to NONE (so, say, a SMALL will never be placed in a OTHER, MEDIUM, or LARGE chunk to reduce fragmentation)\n          ibin = (ibin == bbin ? MI_CBIN_NONE : mi_chunkbin_inc(ibin)))\n    {\n      mi_assert_internal(ibin < MI_CBIN_COUNT);\n      const mi_bfield_t cmap_bin = cmap_bins[ibin];\n      size_t eidx = 0;\n      mi_bfield_cycle_iterate(cmap_bin, tseq, cmap_entry_cycle, eidx, Y)\n      {\n        // assertion doesn't quite hold as the max_accessed may be out-of-date\n        // mi_assert_internal(cmap_entry_cycle > eidx || ibin == MI_CBIN_NONE);\n\n        // get the chunk\n        const size_t chunk_idx = cmap_idx*MI_BFIELD_BITS + eidx;\n        mi_bchunk_t* chunk = &bbitmap->chunks[chunk_idx];\n\n        size_t cidx;\n        if ((*on_find)(chunk, n, &cidx)) {\n          if (cidx==0 && ibin == MI_CBIN_NONE) { // only the first block determines the size bin\n            // this chunk is now reserved for the `bbin` size class\n            mi_bbitmap_set_chunk_bin(bbitmap, chunk_idx, bbin);\n          }\n          *pidx = (chunk_idx * MI_BCHUNK_BITS) + cidx;\n          mi_assert_internal(*pidx + n <= mi_bbitmap_max_bits(bbitmap));\n          return true;\n        }\n        else {\n          // todo: should _on_find_ return a boolean if there is a chance all are clear to avoid calling `try_clear?`\n          // we may find that all are cleared only on a second iteration but that is ok as the chunkmap is a conservative approximation.\n          mi_bbitmap_chunkmap_try_clear(bbitmap, chunk_idx);\n        }\n      }\n      mi_bfield_cycle_iterate_end(Y);\n    }\n  }\n  mi_bfield_cycle_iterate_end(X);\n  return false;\n}\n\n/* --------------------------------------------------------------------------------\n  mi_bbitmap_try_find_and_clear -- used to find free pages\n  note: the compiler will fully inline the indirect function calls\n-------------------------------------------------------------------------------- */\n\nbool mi_bbitmap_try_find_and_clear(mi_bbitmap_t* bbitmap, size_t tseq, size_t* pidx) {\n  return mi_bbitmap_try_find_and_clear_generic(bbitmap, tseq, 1, pidx, &mi_bchunk_try_find_and_clear_1);\n}\n\nbool mi_bbitmap_try_find_and_clear8(mi_bbitmap_t* bbitmap, size_t tseq, size_t* pidx) {\n  return mi_bbitmap_try_find_and_clear_generic(bbitmap, tseq, 8, pidx, &mi_bchunk_try_find_and_clear_8);\n}\n\n// bool mi_bbitmap_try_find_and_clearX(mi_bbitmap_t* bbitmap, size_t tseq, size_t* pidx) {\n//   return mi_bbitmap_try_find_and_clear_generic(bbitmap, tseq, MI_BFIELD_BITS, pidx, &mi_bchunk_try_find_and_clear_X);\n// }\n\nbool mi_bbitmap_try_find_and_clearNX(mi_bbitmap_t* bbitmap, size_t tseq, size_t n, size_t* pidx) {\n  mi_assert_internal(n<=MI_BFIELD_BITS);\n  return mi_bbitmap_try_find_and_clear_generic(bbitmap, tseq, n, pidx, &mi_bchunk_try_find_and_clearNX);\n}\n\nbool mi_bbitmap_try_find_and_clearNC(mi_bbitmap_t* bbitmap, size_t tseq, size_t n, size_t* pidx) {\n  mi_assert_internal(n<=MI_BCHUNK_BITS);\n  return mi_bbitmap_try_find_and_clear_generic(bbitmap, tseq, n, pidx, &mi_bchunk_try_find_and_clearNC);\n}\n\n\n/* --------------------------------------------------------------------------------\n  mi_bbitmap_try_find_and_clear for huge objects spanning multiple chunks\n-------------------------------------------------------------------------------- */\n\n// Try to atomically clear `n` bits starting at `chunk_idx` where `n` can span over multiple chunks\nstatic bool mi_bchunk_try_clearN_(mi_bbitmap_t* bbitmap, size_t chunk_idx, size_t n) {\n  mi_assert_internal((chunk_idx * MI_BCHUNK_BITS) + n <= mi_bbitmap_max_bits(bbitmap));\n\n  size_t m = n;      // bits to go\n  size_t count = 0;  // chunk count\n  while (m > 0) {\n    mi_bchunk_t* chunk = &bbitmap->chunks[chunk_idx + count];\n    if (!mi_bchunk_try_clearN(chunk, 0, (m > MI_BCHUNK_BITS ? MI_BCHUNK_BITS : m), NULL)) {\n      goto rollback;\n    }\n    m = (m <= MI_BCHUNK_BITS ? 0 : m - MI_BCHUNK_BITS);\n    count++;\n  }\n  return true;\n\nrollback:\n  // we only need to reset chunks the we just fully cleared\n  while (count > 0) {\n    count--;\n    mi_bchunk_t* chunk = &bbitmap->chunks[chunk_idx + count];\n    mi_bchunk_setN(chunk, 0, MI_BCHUNK_BITS, NULL);\n  }\n  return false;\n}\n\n// Go through the bbitmap to find a sequence of `n` bits and clear them atomically where `n > MI_ARENA_MAX_CHUNK_OBJ_SIZE`\n// Since these are very large object allocations we always search from the start and only consider starting at the start\n// of a chunk (for fragmentation and efficiency).\n// Todo: for now we try to find full empty chunks to cover `n` but we can allow a partial chunk at the end\n// Todo: This scans directly through the chunks -- we might want to consult the cmap as well?\nbool mi_bbitmap_try_find_and_clearN_(mi_bbitmap_t* bbitmap, size_t tseq, size_t n, size_t* pidx) {\n  MI_UNUSED(tseq);\n  mi_assert(n > 0); if (n==0) { return false; }\n\n  const size_t chunk_max = mi_bbitmap_chunk_count(bbitmap);\n  const size_t chunk_req = _mi_divide_up(n, MI_BCHUNK_BITS);  // minimal number of chunks needed\n  if (chunk_max < chunk_req) { return false; }\n\n  // iterate through the chunks\n  size_t chunk_idx = 0;\n  while (chunk_idx <= chunk_max - chunk_req)\n  {\n    size_t count = 0;  // chunk count\n    do {\n      mi_assert_internal(chunk_idx + count < chunk_max);\n      mi_bchunk_t* const chunk = &bbitmap->chunks[chunk_idx + count];\n      if (!mi_bchunk_all_are_set_relaxed(chunk)) {\n        break;\n      }\n      else {\n        count++;\n      }\n    }\n    while (count < chunk_req);\n\n    // did we find a suitable range?\n    if (count == chunk_req) {\n      // now try to claim it!\n      if (mi_bchunk_try_clearN_(bbitmap, chunk_idx, n)) {\n        *pidx = (chunk_idx * MI_BCHUNK_BITS);\n        for (size_t i = 0; i < count; i++) {\n          mi_bbitmap_set_chunk_bin(bbitmap, chunk_idx + i, MI_CBIN_HUGE);\n        }\n        mi_assert_internal(*pidx + n <= mi_bbitmap_max_bits(bbitmap));\n        return true;\n      }\n    }\n\n    // keep searching but skip the scanned range\n    chunk_idx += count+1;\n  }\n  return false;\n}\n\n\n\n\n\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/bitmap.h",
      "sha256": "2e7a54ff44592a1fe8fe929e691322622f8aa1e0b1e80954781f332a88dd6cd1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2024 Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* ----------------------------------------------------------------------------\nConcurrent bitmap that can set/reset sequences of bits atomically\n---------------------------------------------------------------------------- */\n#pragma once\n#ifndef MI_BITMAP_H\n#define MI_BITMAP_H\n\n/* --------------------------------------------------------------------------------\n  Atomic bitmaps with release/acquire guarantees:\n\n  `mi_bfield_t`: is a single machine word that can efficiently be bit counted (usually `size_t`)\n      each bit usually represents a single MI_ARENA_SLICE_SIZE in an arena (64 KiB).\n      We need 16K bits to represent a 1GiB arena.\n\n  `mi_bchunk_t`: a chunk of bfield's of a total of MI_BCHUNK_BITS (= 512 on 64-bit, 256 on 32-bit)\n      allocations never span across chunks -- so MI_ARENA_MAX_OBJ_SIZE is the number\n      of bits in a chunk times the MI_ARENA_SLICE_SIZE (512 * 64KiB = 32 MiB).\n      These chunks are cache-aligned and we can use AVX2/AVX512/NEON/SVE/SVE2/etc. instructions\n      to scan for bits (perhaps) more efficiently.\n\n      We allocate byte-sized ranges aligned to bytes in the bfield, and bfield-sized\n      ranges aligned to a bfield.\n\n    Searching linearly through the chunks would be too slow (16K bits per GiB).\n    Instead we add a \"chunkmap\" to do a two-level search (more or less a btree of depth 2).\n\n   `mi_bchunkmap_t` (== `mi_bchunk_t`): for each chunk we track if it has (potentially) any bit set.\n      The chunkmap has 1 bit per chunk that is set if the chunk potentially has a bit set.\n      This is used to avoid scanning every chunk. (and thus strictly an optimization)\n      It is conservative: it is fine to set a bit in the chunk map even if the chunk turns out\n      to have no bits set. It is also allowed to briefly have a clear bit even if the\n      chunk has bits set -- as long as we guarantee that the bit will be set later on;\n      (this allows us to set the chunkmap bit right after we set a bit in the corresponding chunk).\n\n      However, when we clear a bit in a chunk, and the chunk is indeed all clear, we\n      cannot safely clear the bit corresponding to the chunk in the chunkmap since it\n      may race with another thread setting a bit in the same chunk. Therefore, when\n      clearing, we first test if a chunk is clear, then clear the chunkmap bit, and\n      then test again to catch any set bits that we may have missed.\n\n      Since the chunkmap may thus be briefly out-of-sync, this means that we may sometimes\n      not find a free page even though it's there (but we accept this as we avoid taking\n      full locks). (Another way to do this is to use an epoch but we like to avoid that complexity\n      for now).\n\n   `mi_bitmap_t`: a bitmap with N chunks. A bitmap has a chunkmap of MI_BCHUNK_BITS (512)\n      and thus has at most 512 chunks (=2^18 bits x 64 KiB slices = 16 GiB max arena size).\n      The minimum is 1 chunk which is a 32 MiB arena.\n\n   For now, the implementation assumes MI_HAS_FAST_BITSCAN and uses trailing-zero-count\n   and pop-count (but we think it can be adapted work reasonably well on older hardware too)\n--------------------------------------------------------------------------------------------- */\n\n// A word-size bit field.\ntypedef size_t mi_bfield_t;\n\n#define MI_BFIELD_BITS_SHIFT         (MI_SIZE_SHIFT+3)\n#define MI_BFIELD_BITS               (1 << MI_BFIELD_BITS_SHIFT)\n#define MI_BFIELD_SIZE               (MI_BFIELD_BITS/8)\n#define MI_BFIELD_LO_BIT8            (((~(mi_bfield_t)0))/0xFF)         // 0x01010101 ..\n#define MI_BFIELD_HI_BIT8            (MI_BFIELD_LO_BIT8 << 7)           // 0x80808080 ..\n\n#define MI_BCHUNK_SIZE               (MI_BCHUNK_BITS / 8)\n#define MI_BCHUNK_FIELDS             (MI_BCHUNK_BITS / MI_BFIELD_BITS)  // 8 on both 64- and 32-bit\n\n\n// some compiler (msvc in C mode) cannot have expressions in the alignment attribute\n#if MI_BCHUNK_SIZE==64\n#define mi_decl_bchunk_align  mi_decl_align(64)\n#elif MI_BCHUNK_SIZE==32\n#define mi_decl_bchunk_align  mi_decl_align(32)\n#else\n#define mi_decl_bchunk_align  mi_decl_align(MI_BCHUNK_SIZE)\n#endif\n\n\n// A bitmap chunk contains 512 bits on 64-bit  (256 on 32-bit)\ntypedef mi_decl_bchunk_align struct mi_bchunk_s {\n  _Atomic(mi_bfield_t) bfields[MI_BCHUNK_FIELDS];\n} mi_bchunk_t;\n\n\n// The chunkmap has one bit per corresponding chunk that is set if the chunk potentially has bits set.\n// The chunkmap is itself a chunk.\ntypedef mi_bchunk_t mi_bchunkmap_t;\n\n#define MI_BCHUNKMAP_BITS             MI_BCHUNK_BITS\n\n#define MI_BITMAP_MAX_CHUNK_COUNT     (MI_BCHUNKMAP_BITS)\n#define MI_BITMAP_MIN_CHUNK_COUNT     (1)\n#if MI_SIZE_BITS > 32\n#define MI_BITMAP_DEFAULT_CHUNK_COUNT     (64)  // 2 GiB on 64-bit -- this is for the page map\n#else\n#define MI_BITMAP_DEFAULT_CHUNK_COUNT      (1)\n#endif\n#define MI_BITMAP_MAX_BIT_COUNT       (MI_BITMAP_MAX_CHUNK_COUNT * MI_BCHUNK_BITS)  // 16 GiB arena\n#define MI_BITMAP_MIN_BIT_COUNT       (MI_BITMAP_MIN_CHUNK_COUNT * MI_BCHUNK_BITS)  // 32 MiB arena\n#define MI_BITMAP_DEFAULT_BIT_COUNT   (MI_BITMAP_DEFAULT_CHUNK_COUNT * MI_BCHUNK_BITS)  // 2 GiB arena\n\n\n// An atomic bitmap\ntypedef mi_decl_bchunk_align struct mi_bitmap_s {\n  _Atomic(size_t)  chunk_count;         // total count of chunks (0 < N <= MI_BCHUNKMAP_BITS)\n  size_t           _padding[MI_BCHUNK_SIZE/MI_SIZE_SIZE - 1];    // suppress warning on msvc\n  mi_bchunkmap_t   chunkmap;\n  mi_bchunk_t      chunks[MI_BITMAP_DEFAULT_CHUNK_COUNT];        // usually dynamic MI_BITMAP_MAX_CHUNK_COUNT\n} mi_bitmap_t;\n\n\nstatic inline size_t mi_bitmap_chunk_count(const mi_bitmap_t* bitmap) {\n  return mi_atomic_load_relaxed(&((mi_bitmap_t*)bitmap)->chunk_count);\n}\n\nstatic inline size_t mi_bitmap_max_bits(const mi_bitmap_t* bitmap) {\n  return (mi_bitmap_chunk_count(bitmap) * MI_BCHUNK_BITS);\n}\n\n\n\n/* --------------------------------------------------------------------------------\n  Atomic bitmap operations\n-------------------------------------------------------------------------------- */\n\n// Many operations are generic over setting or clearing the bit sequence: we use `mi_xset_t` for this (true if setting, false if clearing)\ntypedef bool  mi_xset_t;\n#define MI_BIT_SET    (true)\n#define MI_BIT_CLEAR  (false)\n\n\n// Required size of a bitmap to represent `bit_count` bits.\nsize_t mi_bitmap_size(size_t bit_count, size_t* chunk_count);\n\n// Initialize a bitmap to all clear; avoid a mem_zero if `already_zero` is true\n// returns the size of the bitmap.\nsize_t mi_bitmap_init(mi_bitmap_t* bitmap, size_t bit_count, bool already_zero);\n\n// Set/clear a sequence of `n` bits in the bitmap (and can cross chunks).\n// Not atomic so only use if still local to a thread.\nvoid mi_bitmap_unsafe_setN(mi_bitmap_t* bitmap, size_t idx, size_t n);\n\n\n// Set a bit in the bitmap; returns `true` if it atomically transitioned from 0 to 1\nbool mi_bitmap_set(mi_bitmap_t* bitmap, size_t idx);\n\n// Clear a bit in the bitmap; returns `true` if it atomically transitioned from 1 to 0\nbool mi_bitmap_clear(mi_bitmap_t* bitmap, size_t idx);\n\n// Set a sequence of `n` bits in the bitmap; returns `true` if atomically transitioned from all 0's to 1's\n// If `already_set` is not NULL, it is set to count of bits were already all set.\n// (this is used for correct statistics if commiting over a partially committed area)\nbool mi_bitmap_setN(mi_bitmap_t* bitmap, size_t idx, size_t n, size_t* already_set);\n\n// Clear a sequence of `n` bits in the bitmap; returns `true` if atomically transitioned from all 1's to 0's\nbool mi_bitmap_clearN(mi_bitmap_t* bitmap, size_t idx, size_t n);\n\n\n// Is a sequence of n bits already all set/cleared?\nbool mi_bitmap_is_xsetN(mi_xset_t set, mi_bitmap_t* bitmap, size_t idx, size_t n);\n\n// Is the bitmap completely clear?\nbool mi_bitmap_is_all_clear(mi_bitmap_t* bitmap);\n\n// Is a sequence of n bits already set?\n// (Used to check if a memory range is already committed)\nstatic inline bool mi_bitmap_is_setN(mi_bitmap_t* bitmap, size_t idx, size_t n) {\n  return mi_bitmap_is_xsetN(MI_BIT_SET, bitmap, idx, n);\n}\n\n// Is a sequence of n bits already clear?\nstatic inline bool mi_bitmap_is_clearN(mi_bitmap_t* bitmap, size_t idx, size_t n) {\n  return mi_bitmap_is_xsetN(MI_BIT_CLEAR, bitmap, idx, n);\n}\n\nstatic inline bool mi_bitmap_is_set(mi_bitmap_t* bitmap, size_t idx) {\n  return mi_bitmap_is_setN(bitmap, idx, 1);\n}\n\nstatic inline bool mi_bitmap_is_clear(mi_bitmap_t* bitmap, size_t idx) {\n  return mi_bitmap_is_clearN(bitmap, idx, 1);\n}\n\n// Called once a bit is cleared to see if the memory slice can be claimed.\ntypedef bool (mi_claim_fun_t)(size_t slice_index, mi_arena_t* arena, bool* keep_set);\n\n// Find a set bits in the bitmap, atomically clear it, and check if `claim` returns true.\n// If not claimed, continue on (potentially setting the bit again depending on `keep_set`).\n// Returns true on success, and in that case sets the index: `0 <= *pidx <= MI_BITMAP_MAX_BITS-n`.\nmi_decl_nodiscard bool mi_bitmap_try_find_and_claim(mi_bitmap_t* bitmap, size_t tseq, size_t* pidx,\n                                                    mi_claim_fun_t* claim, mi_arena_t* arena );\n\n\n// Atomically clear a bit but only if it is set. Will block otherwise until the bit is set.\n// This is used to delay free-ing a page that it at the same time being considered to be\n// allocated from `mi_arena_try_abandoned` (and is in the `claim` function of `mi_bitmap_try_find_and_claim`).\nvoid mi_bitmap_clear_once_set(mi_bitmap_t* bitmap, size_t idx);\n\n\n// If a bit is set in the bitmap, return `true` and set `idx` to the index of the highest bit.\n// Otherwise return `false` (and `*idx` is undefined).\n// Used for unloading arena's\nbool mi_bitmap_bsr(mi_bitmap_t* bitmap, size_t* idx);\n\n// Return count of all set bits in a bitmap.\nsize_t mi_bitmap_popcount(mi_bitmap_t* bitmap);\n\n\ntypedef bool (mi_forall_set_fun_t)(size_t slice_index, size_t slice_count, mi_arena_t* arena, void* arg2);\n\n// Visit all set bits in a bitmap (`slice_count == 1`)\nbool _mi_bitmap_forall_set(mi_bitmap_t* bitmap, mi_forall_set_fun_t* visit, mi_arena_t* arena, void* arg);\n\n// Visit all set bits in a bitmap with larger ranges if possible (`slice_count >= 1`)\n// Ranges will never cross chunk boundaries though (and `slice_count <= MI_BCHUNK_BITS`)\nbool _mi_bitmap_forall_setc_ranges(mi_bitmap_t* bitmap, mi_forall_set_fun_t* visit, mi_arena_t* arena, void* arg);\n\n// Visit all set bits in a bitmap with at least `rngslices` at a time (and aligned to `rngslices`). \n// This is used by purging to not break up transparent huge pages for example.\n// Ranges will never cross chunk boundaries (and `slice_count <= MI_BCHUNK_BITS`).\nbool _mi_bitmap_forall_setc_rangesn(mi_bitmap_t* bitmap, size_t rngslices, mi_forall_set_fun_t* visit, mi_arena_t* arena, void* arg);\n\n// Count all set bits in given range in the bitmap.\nsize_t mi_bitmap_popcountN( mi_bitmap_t* bitmap, size_t idx, size_t n);\n\n/* ----------------------------------------------------------------------------\n  Binned concurrent bitmap\n  Assigns a size class to each chunk such that small blocks don't cause too\n  much fragmentation since we keep chunks for larger blocks separate.\n---------------------------------------------------------------------------- */\n\n// mi_chunkbin_t is defined in mimalloc-stats.h\n\nstatic inline mi_chunkbin_t mi_chunkbin_inc(mi_chunkbin_t bbin) {\n  mi_assert_internal(bbin < MI_CBIN_COUNT);\n  return (mi_chunkbin_t)((int)bbin + 1);\n}\n\nstatic inline mi_chunkbin_t mi_chunkbin_dec(mi_chunkbin_t bbin) {\n  mi_assert_internal(bbin > MI_CBIN_NONE);\n  return (mi_chunkbin_t)((int)bbin - 1);\n}\n\nstatic inline mi_chunkbin_t mi_chunkbin_of(size_t slice_count) {\n  if (slice_count==1) return MI_CBIN_SMALL;\n  if (slice_count==8) return MI_CBIN_MEDIUM;\n  #if MI_ENABLE_LARGE_PAGES\n  if (slice_count==MI_BFIELD_BITS) return MI_CBIN_LARGE;\n  #endif\n  if (slice_count > MI_BCHUNK_BITS) return MI_CBIN_HUGE;\n  return MI_CBIN_OTHER;\n}\n\n// An atomic \"binned\" bitmap for the free slices where we keep chunks reserved for particular size classes\ntypedef mi_decl_bchunk_align struct mi_bbitmap_s {\n  _Atomic(size_t)  chunk_count;         // total count of chunks (0 < N <= MI_BCHUNKMAP_BITS)\n  _Atomic(size_t)  chunk_max_accessed;  // max chunk index that was once cleared or set\n  #if (MI_BCHUNK_SIZE / MI_SIZE_SIZE) > 2\n  size_t           _padding[MI_BCHUNK_SIZE/MI_SIZE_SIZE - 2];    // suppress warning on msvc by aligning manually\n  #endif\n  mi_bchunkmap_t   chunkmap;\n  mi_bchunkmap_t   chunkmap_bins[MI_CBIN_COUNT - 1];             // chunkmaps with bit set if the chunk is in that size class (excluding MI_CBIN_NONE)\n  mi_bchunk_t      chunks[MI_BITMAP_DEFAULT_CHUNK_COUNT];        // usually dynamic MI_BITMAP_MAX_CHUNK_COUNT\n} mi_bbitmap_t;\n\n\nstatic inline size_t mi_bbitmap_chunk_count(const mi_bbitmap_t* bbitmap) {\n  return mi_atomic_load_relaxed(&((mi_bbitmap_t*)bbitmap)->chunk_count);\n}\n\nstatic inline size_t mi_bbitmap_max_bits(const mi_bbitmap_t* bbitmap) {\n  return (mi_bbitmap_chunk_count(bbitmap) * MI_BCHUNK_BITS);\n}\n\nmi_chunkbin_t mi_bbitmap_debug_get_bin(const mi_bchunk_t* chunkmap_bins, size_t chunk_idx);\n\nsize_t mi_bbitmap_size(size_t bit_count, size_t* chunk_count);\n\n// If a bit is clear in the bitmap, return `true` and set `idx` to the index of the highest bit that was clear.\n// Otherwise return `false` (and `*idx` is undefined).\n// Used for debug output.\nbool mi_bbitmap_bsr_inv(mi_bbitmap_t* bbitmap, size_t* idx);\n\n// Initialize a bitmap to all clear; avoid a mem_zero if `already_zero` is true\n// returns the size of the bitmap.\nsize_t mi_bbitmap_init(mi_bbitmap_t* bbitmap, size_t bit_count, bool already_zero);\n\n// Set/clear a sequence of `n` bits in the bitmap (and can cross chunks).\n// Not atomic so only use if still local to a thread.\nvoid mi_bbitmap_unsafe_setN(mi_bbitmap_t* bbitmap, size_t idx, size_t n);\n\n\n// Set a sequence of `n` bits in the bbitmap; returns `true` if atomically transitioned from all 0's to 1's\nbool mi_bbitmap_setN(mi_bbitmap_t* bbitmap, size_t idx, size_t n);\n\n\n// Is a sequence of n bits already all set/cleared?\nbool mi_bbitmap_is_xsetN(mi_xset_t set, mi_bbitmap_t* bbitmap, size_t idx, size_t n);\n\n// Is a sequence of n bits already set?\n// (Used to check if a memory range is already committed)\nstatic inline bool mi_bbitmap_is_setN(mi_bbitmap_t* bbitmap, size_t idx, size_t n) {\n  return mi_bbitmap_is_xsetN(MI_BIT_SET, bbitmap, idx, n);\n}\n\n// Is a sequence of n bits already clear?\nstatic inline bool mi_bbitmap_is_clearN(mi_bbitmap_t* bbitmap, size_t idx, size_t n) {\n  return mi_bbitmap_is_xsetN(MI_BIT_CLEAR, bbitmap, idx, n);\n}\n\n\n// Try to atomically transition `n` bits from all set to all clear. Returns `true` on succes.\n// `n` cannot cross chunk boundaries, where `n <= MI_CHUNK_BITS`.\nbool mi_bbitmap_try_clearNC(mi_bbitmap_t* bbitmap, size_t idx, size_t n);\n\n\n// Specialized versions for common bit sequence sizes\nbool mi_bbitmap_try_find_and_clear(mi_bbitmap_t* bbitmap, size_t tseq, size_t* pidx);  // 1-bit\nbool mi_bbitmap_try_find_and_clear8(mi_bbitmap_t* bbitmap, size_t tseq, size_t* pidx); // 8-bits\n// bool mi_bbitmap_try_find_and_clearX(mi_bbitmap_t* bbitmap, size_t tseq, size_t* pidx); // MI_BFIELD_BITS\nbool mi_bbitmap_try_find_and_clearNX(mi_bbitmap_t* bbitmap, size_t tseq, size_t n, size_t* pidx); // < MI_BFIELD_BITS\nbool mi_bbitmap_try_find_and_clearNC(mi_bbitmap_t* bbitmap, size_t tseq, size_t n, size_t* pidx); // > MI_BFIELD_BITS <= MI_BCHUNK_BITS\nbool mi_bbitmap_try_find_and_clearN_(mi_bbitmap_t* bbitmap, size_t tseq, size_t n, size_t* pidx); // > MI_BCHUNK_BITS\n\n// Find a sequence of `n` bits in the bbitmap with all bits set, and try to atomically clear all.\n// Returns true on success, and in that case sets the index: `0 <= *pidx <= MI_BITMAP_MAX_BITS-n`.\nmi_decl_nodiscard static inline bool mi_bbitmap_try_find_and_clearN(mi_bbitmap_t* bbitmap, size_t tseq, size_t n, size_t* pidx) {\n  if (n==1) return mi_bbitmap_try_find_and_clear(bbitmap, tseq, pidx);               // small pages\n  if (n==8) return mi_bbitmap_try_find_and_clear8(bbitmap, tseq, pidx);              // medium pages\n  // if (n==MI_BFIELD_BITS) return mi_bbitmap_try_find_and_clearX(bbitmap, tseq, pidx); // large pages\n  if (n==0) return false;\n  if (n<=MI_BFIELD_BITS) return mi_bbitmap_try_find_and_clearNX(bbitmap, tseq, n, pidx);\n  if (n<=MI_BCHUNK_BITS) return mi_bbitmap_try_find_and_clearNC(bbitmap, tseq, n, pidx);\n  return mi_bbitmap_try_find_and_clearN_(bbitmap, tseq, n, pidx);\n}\n\n\n#endif // MI_BITMAP_H\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/free.c",
      "sha256": "c9a845dd7b9020f26d73761d235fb75e7bc4a3682576de750050ac4098211b43",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#if !defined(MI_IN_ALLOC_C)\n#error \"this file should be included from 'alloc.c' (so aliases can work from alloc-override)\"\n// add includes help an IDE\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"   // _mi_prim_thread_id()\n#endif\n\n// forward declarations\nstatic void   mi_check_padding(const mi_page_t* page, const mi_block_t* block);\nstatic bool   mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block);\nstatic size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block, bool was_guarded);\nstatic void   mi_stat_free(const mi_page_t* page, const mi_block_t* block);\n\n\n// ------------------------------------------------------\n// Free\n// ------------------------------------------------------\n\n// regular free of a (thread local) block pointer\n// fast path written carefully to prevent spilling on the stack\nstatic inline void mi_free_block_local(mi_page_t* page, mi_block_t* block, bool was_guarded, bool track_stats, bool check_full)\n{\n  MI_UNUSED(was_guarded);\n  // checks  \n  if mi_unlikely(mi_check_is_double_free(page, block)) return;\n  if (!was_guarded) { mi_check_padding(page, block); }\n  if (track_stats) { mi_stat_free(page, block); }\n  #if (MI_DEBUG>0) && !MI_TRACK_ENABLED  && !MI_TSAN\n  memset(block, MI_DEBUG_FREED, mi_page_block_size(page));\n  #endif\n  if (track_stats) { mi_track_free_size(block, mi_page_usable_size_of(page, block, was_guarded)); } // faster then mi_usable_size as we already know the page and that p is unaligned\n\n  // actual free: push on the local free list\n  mi_block_set_next(page, block, page->local_free);\n  page->local_free = block;\n  if mi_unlikely(--page->used == 0) {\n    if (page->retire_expire==0) { // no need to re-retire retired pages (happens when we alloc/free one block repeatedly in an empty page)\n      _mi_page_retire(page); \n    }\n  }\n  else if mi_unlikely(check_full && mi_page_is_in_full(page)) {\n    _mi_page_unfull(page);\n  }\n}\n\n// Forward declaration for multi-threaded collect\nstatic void mi_decl_noinline mi_free_try_collect_mt(mi_page_t* page, mi_block_t* mt_free) mi_attr_noexcept;\n\n// Free a block multi-threaded\nstatic inline void mi_free_block_mt(mi_page_t* page, mi_block_t* block, bool was_guarded) mi_attr_noexcept\n{\n  MI_UNUSED(was_guarded);\n  // adjust stats (after padding check and potentially recursive `mi_free` above)\n  mi_stat_free(page, block);    // stat_free may access the padding\n  mi_track_free_size(block, mi_page_usable_size_of(page, block, was_guarded));\n\n  // _mi_padding_shrink(page, block, sizeof(mi_block_t));\n#if (MI_DEBUG>0) && !MI_TRACK_ENABLED  && !MI_TSAN       // note: when tracking, cannot use mi_usable_size with multi-threading\n  if (!was_guarded) {\n    size_t dbgsize = mi_usable_size(block);\n    if (dbgsize > MI_MiB) { dbgsize = MI_MiB; }\n    _mi_memset_aligned(block, MI_DEBUG_FREED, dbgsize);\n  }\n#endif\n\n  // push atomically on the page thread free list\n  mi_thread_free_t tf_new;\n  mi_thread_free_t tf_old = mi_atomic_load_relaxed(&page->xthread_free);\n  do {\n    mi_block_set_next(page, block, mi_tf_block(tf_old));\n    tf_new = mi_tf_create(block, true /* always use owned: try to claim it if the page is abandoned */);\n  } while (!mi_atomic_cas_weak_acq_rel(&page->xthread_free, &tf_old, tf_new)); // todo: release is enough?\n\n  // and atomically try to collect the page if it was abandoned\n  const bool is_owned_now = !mi_tf_is_owned(tf_old);\n  if (is_owned_now) {\n    mi_assert_internal(mi_page_is_abandoned(page));\n    mi_free_try_collect_mt(page,block);\n  }\n}\n\n\n// Adjust a block that was allocated aligned, to the actual start of the block in the page.\n// note: this can be called from `mi_free_generic_mt` where a non-owning thread accesses the\n// `page_start` and `block_size` fields; however these are constant and the page won't be\n// deallocated (as the block we are freeing keeps it alive) and thus safe to read concurrently.\nmi_block_t* _mi_page_ptr_unalign(const mi_page_t* page, const void* p) {\n  mi_assert_internal(page!=NULL && p!=NULL);\n\n  const size_t diff = (uint8_t*)p - mi_page_start(page);\n  const size_t block_size = mi_page_block_size(page);\n  const size_t adjust = (_mi_is_power_of_two(block_size) ? diff & (block_size - 1) : diff % block_size);\n  return (mi_block_t*)((uintptr_t)p - adjust);\n}\n\n// forward declaration for a MI_GUARDED build\n#if MI_GUARDED\nstatic void mi_block_unguard(mi_page_t* page, mi_block_t* block, void* p); // forward declaration\nstatic inline bool mi_block_check_unguard(mi_page_t* page, mi_block_t* block, void* p) {\n  if (mi_block_ptr_is_guarded(block, p)) { \n    mi_block_unguard(page, block, p); \n    return true;\n  }\n  else {\n    return false;\n  }\n}\n#else\nstatic inline bool mi_block_check_unguard(mi_page_t* page, mi_block_t* block, void* p) {\n  MI_UNUSED(page); MI_UNUSED(block); MI_UNUSED(p);\n  return false;\n}\n#endif\n\nstatic inline mi_block_t* mi_validate_block_from_ptr( const mi_page_t* page, void* p ) {\n  mi_assert(_mi_page_ptr_unalign(page,p) == (mi_block_t*)p); // should never be an interior pointer\n  #if MI_SECURE > 0\n  // in secure mode we always unalign to guard against free-ing interior pointers\n  return _mi_page_ptr_unalign(page,p);\n  #else\n  MI_UNUSED(page);\n  return (mi_block_t*)p;\n  #endif\n}\n\n\n// free a local pointer  (page parameter comes first for better codegen)\nstatic void mi_decl_noinline mi_free_generic_local(mi_page_t* page, void* p) mi_attr_noexcept {\n  mi_assert_internal(p!=NULL && page != NULL);\n  mi_block_t* const block = (mi_page_has_interior_pointers(page) ? _mi_page_ptr_unalign(page, p) : mi_validate_block_from_ptr(page,p));\n  const bool was_guarded = mi_block_check_unguard(page, block, p);\n  mi_free_block_local(page, block, was_guarded, true /* track stats */, true /* check for a full page */);\n}\n\n// free a pointer owned by another thread (page parameter comes first for better codegen)\nstatic void mi_decl_noinline mi_free_generic_mt(mi_page_t* page, void* p) mi_attr_noexcept {\n  mi_assert_internal(p!=NULL && page != NULL);\n  mi_block_t* const block = (mi_page_has_interior_pointers(page) ? _mi_page_ptr_unalign(page, p) : mi_validate_block_from_ptr(page,p));\n  const bool was_guarded = mi_block_check_unguard(page, block, p);\n  mi_free_block_mt(page, block, was_guarded);\n}\n\n// generic free (for runtime integration)\nvoid mi_decl_noinline _mi_free_generic(mi_page_t* page, bool is_local, void* p) mi_attr_noexcept {\n  if (is_local) mi_free_generic_local(page,p);\n           else mi_free_generic_mt(page,p);\n}\n\n\n// Get the page belonging to a pointer\n// Does further checks in debug mode to see if this was a valid pointer.\nstatic inline mi_page_t* mi_validate_ptr_page(const void* p, const char* msg)\n{\n  MI_UNUSED_RELEASE(msg);\n  #if MI_DEBUG\n  if mi_unlikely(((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0 && !mi_option_is_enabled(mi_option_guarded_precise)) {\n    _mi_error_message(EINVAL, \"%s: invalid (unaligned) pointer: %p\\n\", msg, p);\n    return NULL;\n  }\n  mi_page_t* page = _mi_safe_ptr_page(p);\n  if (p != NULL && page == NULL) {\n    _mi_error_message(EINVAL, \"%s: invalid pointer: %p\\n\", msg, p);\n  }\n  return page;\n  #else\n  return _mi_ptr_page(p);\n  #endif\n}\n\n// Free a block\n// Fast path written carefully to prevent register spilling on the stack\nstatic mi_decl_forceinline void mi_free_ex(void* p, size_t* usable, mi_page_t* page)  \n{\n  if mi_unlikely(page==NULL) return;  // page will be NULL if p==NULL\n  mi_assert_internal(p!=NULL && page!=NULL);\n  if (usable!=NULL) { *usable = mi_page_usable_block_size(page); }\n\n  const mi_threadid_t xtid = (_mi_prim_thread_id() ^ mi_page_xthread_id(page));\n  if mi_likely(xtid == 0) {                        // `tid == mi_page_thread_id(page) && mi_page_flags(page) == 0`\n    // thread-local, aligned, and not a full page\n    mi_block_t* const block = mi_validate_block_from_ptr(page,p);\n    mi_free_block_local(page, block, false /* was guarded */, true /* track stats */, false /* no need to check if the page is full */);\n  }\n  else if (xtid <= MI_PAGE_FLAG_MASK) {            // `tid == mi_page_thread_id(page) && mi_page_flags(page) != 0`\n    // page is local, but is full or contains (inner) aligned blocks; use generic path\n    mi_free_generic_local(page, p);\n  }\n  // free-ing in a page owned by a theap in another thread, or an abandoned page (not belonging to a theap)\n  else if ((xtid & MI_PAGE_FLAG_MASK) == 0) {      // `tid != mi_page_thread_id(page) && mi_page_flags(page) == 0`\n    // blocks are aligned (and not a full page); push on the thread_free list\n    mi_block_t* const block = mi_validate_block_from_ptr(page,p);\n    mi_free_block_mt(page,block,false /* was_guarded */);\n  }\n  else {\n    // page is full or contains (inner) aligned blocks; use generic multi-thread path\n    mi_free_generic_mt(page, p);\n  }\n}\n\nvoid mi_free(void* p) mi_attr_noexcept {\n  mi_page_t* const page = mi_validate_ptr_page(p,\"mi_free\");  \n  mi_free_ex(p, NULL, page);\n}\n\nvoid mi_ufree(void* p, size_t* usable) mi_attr_noexcept {\n  mi_page_t* const page = mi_validate_ptr_page(p,\"mi_ufree\");  \n  mi_free_ex(p, usable, page);\n}\n\nvoid mi_free_small(void* p) mi_attr_noexcept {\n  // We can only call `mi_free_small` for pointers allocated with `mi_(heap_)malloc_small`.\n  // If we keep page info in front of the page area for small objects, we can find the info\n  // just by aligning down the pointer instead of looking it up in the page map.\n  #if MI_PAGE_META_ALIGNED_FREE_SMALL \n    #if MI_GUARDED \n    #warning \"MI_PAGE_META_ALIGNED_FREE_SMALL ignored as MI_GUARDED is defined\"\n    mi_free(p);\n    #elif MI_ARENA_SLICE_ALIGN < MI_SMALL_PAGE_SIZE\n    #warning \"MI_PAGE_META_ALIGNED_FREE_SMALL ignored as the MI_ARENA_SLICE_ALIGN is less than the small page size\"\n    mi_free(p);\n    #else\n      mi_page_t* const page = (mi_page_t*)_mi_align_down_ptr(p,MI_SMALL_PAGE_SIZE);\n      mi_assert(page == mi_validate_ptr_page(p,\"mi_free_small\"));\n      mi_assert((void*)page == _mi_align_down_ptr(page->page_start,MI_SMALL_PAGE_SIZE));\n      mi_assert(page->block_size <= MI_SMALL_SIZE_MAX);  // note: not `MI_SMALL_MAX_OBJ_SIZE` as we need to match `mi_(heap_)malloc_small`\n      mi_free_ex(p, NULL, page);\n    #endif\n  #else\n  mi_free(p);\n  #endif  \n}\n\n\n// --------------------------------------------------------------------------------------------\n// `mi_free_try_collect_mt`: Potentially collect a page in a free in an abandoned page.\n// 1. if the page becomes empty, free it\n// 2. if it can be reclaimed, reclaim it in our theap\n// 3. if it went to < 7/8th used, re-abandon to be mapped (so it can be found by theaps looking for free pages)\n// --------------------------------------------------------------------------------------------\n\n// Helper for mi_free_try_collect_mt: free if the page has no more used blocks (this is updated by `_mi_page_free_collect(_partly)`)\nstatic bool mi_abandoned_page_try_free(mi_page_t* page)\n{\n  if (!mi_page_all_free(page)) return false;\n  // first remove it from the abandoned pages in the arena (if mapped, this might wait for any readers to finish)\n  _mi_arenas_page_unabandon(page,NULL);\n  _mi_arenas_page_free(page,NULL); // we can now free the page directly\n  return true;\n}\n\n// Helper for mi_free_try_collect_mt: try if we can reabandon a previously abandoned mostly full page to be mapped\nstatic bool mi_abandoned_page_try_reabandon_to_mapped(mi_page_t* page)\n{\n  // if the page is unmapped, try to reabandon so it can possibly be mapped and found for allocations\n  // We only reabandon if a full page starts to have enough blocks available to prevent immediate re-abandon of a full page\n  if (mi_page_is_mostly_used(page)) return false;   // not too full\n  if (page->memid.memkind != MI_MEM_ARENA || mi_page_is_abandoned_mapped(page)) return false;  // and not already mapped (or unmappable)\n\n  mi_assert(!mi_page_is_full(page));\n  return _mi_arenas_page_try_reabandon_to_mapped(page);\n}\n\n// Release ownership of a page. This may free or reabandoned the page if other blocks are concurrently\n// freed in the meantime. Returns `true` if the page was freed.\n// By passing the captured `expected_thread_free`, we can often avoid calling `mi_page_free_collect`.\nstatic void mi_abandoned_page_unown_from_free(mi_page_t* page, mi_block_t* expected_thread_free) {\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_assert_internal(!mi_page_all_free(page));\n  // try to cas atomically the original free list (`mt_free`) back with the ownership cleared.\n  mi_thread_free_t tf_expect = mi_tf_create(expected_thread_free, true);\n  mi_thread_free_t tf_new    = mi_tf_create(expected_thread_free, false);\n  while mi_unlikely(!mi_atomic_cas_weak_acq_rel(&page->xthread_free, &tf_expect, tf_new)) {\n    mi_assert_internal(mi_tf_is_owned(tf_expect));\n    // while the xthread_free list is not empty..\n    while (mi_tf_block(tf_expect) != NULL) {\n      // if there were concurrent updates to the thread-free list, we retry to free or reabandon to mapped (if it became !mosty_used).\n      _mi_page_free_collect(page,false);  // update used count\n      if (mi_abandoned_page_try_free(page)) return;\n      if (mi_abandoned_page_try_reabandon_to_mapped(page)) return;\n      // otherwise continue un-owning\n      tf_expect = mi_atomic_load_relaxed(&page->xthread_free);\n    }\n    // and try again to release ownership\n    mi_assert_internal(mi_tf_block(tf_expect)==NULL);\n    tf_new = mi_tf_create(NULL, false);\n  }\n}\n\nstatic inline bool mi_page_queue_len_is_atmost( mi_theap_t* theap, size_t block_size, long atmost) {\n  if (atmost < 0) return false;\n  mi_page_queue_t* const pq = mi_page_queue(theap,block_size);\n  mi_assert_internal(pq!=NULL);\n  return (pq->count <= (size_t)atmost);\n}\n\n// Helper for mi_free_try_collect_mt:  try to reclaim the page for ourselves\nstatic mi_decl_noinline bool mi_abandoned_page_try_reclaim(mi_page_t* page, long reclaim_on_free) mi_attr_noexcept\n{\n  // note: reclaiming can improve benchmarks like `larson` or `rbtree-ck` a lot even in the single-threaded case,\n  // since free-ing from an owned page avoids atomic operations. However, if we reclaim too eagerly in\n  // a multi-threaded scenario we may start to hold on to too much memory and reduce reuse among threads.\n  // If the current theap is where the page originally came from, we reclaim much more eagerly while\n  // 'cross-thread' reclaiming on free is by default off (and we only 'reclaim' these by finding the abandoned\n  // pages when we allocate a fresh page).\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_assert_internal(!mi_page_all_free(page));\n  mi_assert_internal(page->block_size <= MI_MEDIUM_MAX_OBJ_SIZE);\n  mi_assert_internal(reclaim_on_free >= 0);\n\n  // dont reclaim if we just have terminated this thread and we should\n  // not reinitialize the theap for this thread. (can happen due to thread-local destructors for example -- issue #944)\n  if (!_mi_thread_is_initialized()) return false;\n\n  // get our theap \n  mi_theap_t* const theap = _mi_page_associated_theap_peek(page);\n  if (theap==NULL || !theap->allow_page_reclaim) return false;\n  \n  // todo: cache `is_in_threadpool` and `exclusive_arena` directly in the theap for performance?\n  // set max_reclaim limit\n  long max_reclaim = 0;\n  if mi_likely(theap == page->theap) {  // did this page originate from the current theap? (and thus allocated from this thread)\n    // originating theap\n    max_reclaim = _mi_option_get_fast(theap->tld->is_in_threadpool ? mi_option_page_cross_thread_max_reclaim : mi_option_page_max_reclaim);\n  }\n  else if (reclaim_on_free == 1 &&               // if cross-thread is allowed\n            !theap->tld->is_in_threadpool &&      // and we are not part of a threadpool\n            !mi_page_is_mostly_used(page) &&     // and the page is not too full\n            _mi_arena_memid_is_suitable(page->memid, _mi_theap_heap(theap)->exclusive_arena)) {   // and it fits our memory\n    // across threads\n    max_reclaim = _mi_option_get_fast(mi_option_page_cross_thread_max_reclaim);\n  }\n\n  // are we within the reclaim limit?\n  if (max_reclaim >= 0 && !mi_page_queue_len_is_atmost(theap, page->block_size, max_reclaim)) {\n    return false;\n  }\n\n  // reclaim the page into this theap\n  // first remove it from the abandoned pages in the arena -- this might wait for any readers to finish\n  _mi_arenas_page_unabandon(page, theap);\n  _mi_theap_page_reclaim(theap, page);\n  mi_theap_stat_counter_increase(theap, pages_reclaim_on_free, 1);\n  return true;\n}\n\n\n// We freed a block in an abandoned page (that was not owned). Try to collect\nstatic void mi_decl_noinline mi_free_try_collect_mt(mi_page_t* page, mi_block_t* mt_free) mi_attr_noexcept\n{\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_assert_internal(mi_page_is_abandoned(page));\n  mi_assert_internal(mt_free != NULL);\n  // we own the page now, and it is safe to collect the thread atomic free list\n  if (page->block_size <= MI_SMALL_SIZE_MAX) {\n    // use the `_partly` version to avoid atomic operations since we already have the `mt_free` pointing into the thread free list\n    // (after this the `used` count might be too high (as some blocks may have been concurrently added to the thread free list and are yet uncounted).\n    //  however, if the page became completely free, the used count is guaranteed to be 0.)\n    mi_assert_internal(page->reserved>=16); // below this even one freed block goes from full to no longer mostly used.\n    _mi_page_free_collect_partly(page, mt_free);    \n  }\n  else {\n    // for larger blocks we use the regular collect \n    _mi_page_free_collect(page,false /* no force */);\n    mt_free = NULL; // expected page->xthread_free value after collection\n  }\n  const long reclaim_on_free = _mi_option_get_fast(mi_option_page_reclaim_on_free);\n  #if MI_DEBUG > 1\n  if (mi_page_is_singleton(page)) { mi_assert_internal(mi_page_all_free(page)); }\n  if (mi_page_is_full(page))      { mi_assert(mi_page_is_mostly_used(page)); }\n  #endif\n\n  // try to: 1. free it, 2. reclaim it, or 3. reabandon it to be mapped\n  if (mi_abandoned_page_try_free(page)) return;\n  if (page->block_size <= MI_MEDIUM_MAX_OBJ_SIZE && reclaim_on_free >= 0) {  // early test for better codegen\n    if (mi_abandoned_page_try_reclaim(page, reclaim_on_free)) return;\n  }\n  if (mi_abandoned_page_try_reabandon_to_mapped(page)) return;\n  \n  // otherwise unown the page again\n  mi_abandoned_page_unown_from_free(page, mt_free);\n}\n\n\n// ------------------------------------------------------\n// Usable size\n// ------------------------------------------------------\n\n// Bytes available in a block\nstatic size_t mi_decl_noinline mi_page_usable_aligned_size_of(const mi_page_t* page, const void* p) mi_attr_noexcept {\n  const mi_block_t* block = _mi_page_ptr_unalign(page, p);\n  const bool is_guarded = mi_block_ptr_is_guarded(block,p);\n  const size_t size = mi_page_usable_size_of(page, block, is_guarded);\n  const ptrdiff_t adjust = (uint8_t*)p - (uint8_t*)block;\n  mi_assert_internal(adjust >= 0 && (size_t)adjust <= size);\n  const size_t aligned_size = (size - adjust);  \n  return aligned_size;\n}\n\nstatic inline size_t _mi_usable_size(const void* p, const mi_page_t* page) mi_attr_noexcept {\n  if mi_unlikely(page==NULL) return 0;\n  if mi_likely(!mi_page_has_interior_pointers(page)) {\n    const mi_block_t* block = (const mi_block_t*)p;\n    return mi_page_usable_size_of(page, block, false /* is guarded */);\n  }\n  else {\n    // split out to separate routine for improved code generation\n    return mi_page_usable_aligned_size_of(page, p);\n  }\n}\n\nmi_decl_nodiscard size_t mi_usable_size(const void* p) mi_attr_noexcept {\n  const mi_page_t* const page = mi_validate_ptr_page(p,\"mi_usable_size\");\n  return _mi_usable_size(p,page);\n}\n\n\n// ------------------------------------------------------\n// Free variants\n// ------------------------------------------------------\n\nvoid mi_free_size(void* p, size_t size) mi_attr_noexcept {\n  MI_UNUSED_RELEASE(size);\n  #if MI_DEBUG\n  const mi_page_t* const page = mi_validate_ptr_page(p,\"mi_free_size\");  \n  const size_t available = _mi_usable_size(p,page);\n  mi_assert(p == NULL || size <= available || available == 0 /* invalid pointer */ );\n  #endif\n  mi_free(p);\n}\n\nvoid mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept {\n  MI_UNUSED_RELEASE(alignment);\n  mi_assert(((uintptr_t)p % alignment) == 0);\n  mi_free_size(p,size);\n}\n\nvoid mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept {\n  MI_UNUSED_RELEASE(alignment);\n  mi_assert(((uintptr_t)p % alignment) == 0);\n  mi_free(p);\n}\n\n\n// ------------------------------------------------------\n// Check for double free in secure and debug mode\n// This is somewhat expensive so only enabled for secure mode 4\n// ------------------------------------------------------\n\n#if (MI_ENCODE_FREELIST && (MI_SECURE>=4 || MI_DEBUG!=0))\n// linear check if the free list contains a specific element\nstatic bool mi_list_contains(const mi_page_t* page, const mi_block_t* list, const mi_block_t* elem) {\n  while (list != NULL) {\n    if (elem==list) return true;\n    list = mi_block_next(page, list);\n  }\n  return false;\n}\n\nstatic mi_decl_noinline bool mi_check_is_double_freex(const mi_page_t* page, const mi_block_t* block) {\n  // The decoded value is in the same page (or NULL).\n  // Walk the free lists to verify positively if it is already freed\n  if (mi_list_contains(page, page->free, block) ||\n      mi_list_contains(page, page->local_free, block) ||\n      mi_list_contains(page, mi_page_thread_free(page), block))\n  {\n    _mi_error_message(EAGAIN, \"double free detected of block %p with size %zu\\n\", block, mi_page_block_size(page));\n    return true;\n  }\n  return false;\n}\n\n#define mi_track_page(page,access)  { size_t psize; void* pstart = _mi_page_start(_mi_page_segment(page),page,&psize); mi_track_mem_##access( pstart, psize); }\n\nstatic inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) {\n  bool is_double_free = false;\n  mi_block_t* n = mi_block_nextx(page, block, page->keys); // pretend it is freed, and get the decoded first field\n  if (((uintptr_t)n & (MI_INTPTR_SIZE-1))==0 &&  // quick check: aligned pointer?\n      (n==NULL || mi_is_in_same_page(block, n))) // quick check: in same page or NULL?\n  {\n    // Suspicious: decoded value a in block is in the same page (or NULL) -- maybe a double free?\n    // (continue in separate function to improve code generation)\n    is_double_free = mi_check_is_double_freex(page, block);\n  }\n  return is_double_free;\n}\n#else\nstatic inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) {\n  MI_UNUSED(page);\n  MI_UNUSED(block);\n  return false;\n}\n#endif\n\n\n// ---------------------------------------------------------------------------\n// Check for theap block overflow by setting up padding at the end of the block\n// ---------------------------------------------------------------------------\n\n#if MI_PADDING // && !MI_TRACK_ENABLED\nstatic bool mi_page_decode_padding(const mi_page_t* page, const mi_block_t* block, size_t* delta, size_t* bsize) {\n  *bsize = mi_page_usable_block_size(page);\n  const mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + *bsize);\n  mi_track_mem_defined(padding,sizeof(mi_padding_t));\n  *delta = padding->delta;\n  uint32_t canary = padding->canary;\n  uintptr_t keys[2];\n  keys[0] = page->keys[0];\n  keys[1] = page->keys[1];\n  bool ok = (mi_ptr_encode_canary(page,block,keys) == canary && *delta <= *bsize);\n  mi_track_mem_noaccess(padding,sizeof(mi_padding_t));\n  return ok;\n}\n\n// Return the exact usable size of a block.\nstatic size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block, bool is_guarded) {\n  if (is_guarded) {\n    const size_t bsize = mi_page_block_size(page);\n    return (bsize - _mi_os_page_size());\n  }\n  else {\n    size_t bsize;\n    size_t delta;\n    bool ok = mi_page_decode_padding(page, block, &delta, &bsize);\n    mi_assert_internal(ok); mi_assert_internal(delta <= bsize);\n    return (ok ? bsize - delta : 0);\n  }\n}\n\n// When a non-thread-local block is freed, it becomes part of the thread delayed free\n// list that is freed later by the owning theap. If the exact usable size is too small to\n// contain the pointer for the delayed list, then shrink the padding (by decreasing delta)\n// so it will later not trigger an overflow error in `mi_free_block`.\nvoid _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) {\n  size_t bsize;\n  size_t delta;\n  bool ok = mi_page_decode_padding(page, block, &delta, &bsize);\n  mi_assert_internal(ok);\n  if (!ok || (bsize - delta) >= min_size) return;  // usually already enough space\n  mi_assert_internal(bsize >= min_size);\n  if (bsize < min_size) return;  // should never happen\n  size_t new_delta = (bsize - min_size);\n  mi_assert_internal(new_delta < bsize);\n  mi_padding_t* padding = (mi_padding_t*)((uint8_t*)block + bsize);\n  mi_track_mem_defined(padding,sizeof(mi_padding_t));\n  padding->delta = (uint32_t)new_delta;\n  mi_track_mem_noaccess(padding,sizeof(mi_padding_t));\n}\n#else\nstatic size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block, bool is_guarded) {\n  MI_UNUSED(is_guarded); MI_UNUSED(block);\n  return mi_page_usable_block_size(page);\n}\n\nvoid _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) {\n  MI_UNUSED(page); MI_UNUSED(block); MI_UNUSED(min_size);\n}\n#endif\n\n#if MI_PADDING && MI_PADDING_CHECK\n\nstatic bool mi_verify_padding(const mi_page_t* page, const mi_block_t* block, size_t* size, size_t* wrong) {\n  size_t bsize;\n  size_t delta;\n  bool ok = mi_page_decode_padding(page, block, &delta, &bsize);\n  *size = *wrong = bsize;\n  if (!ok) return false;\n  mi_assert_internal(bsize >= delta);\n  *size = bsize - delta;\n  if (!mi_page_is_huge(page)) {\n    uint8_t* fill = (uint8_t*)block + bsize - delta;\n    const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // check at most the first N padding bytes\n    mi_track_mem_defined(fill, maxpad);\n    for (size_t i = 0; i < maxpad; i++) {\n      if (fill[i] != MI_DEBUG_PADDING) {\n        *wrong = bsize - delta + i;\n        ok = false;\n        break;\n      }\n    }\n    mi_track_mem_noaccess(fill, maxpad);\n  }\n  return ok;\n}\n\nstatic void mi_check_padding(const mi_page_t* page, const mi_block_t* block) {\n  size_t size;\n  size_t wrong;\n  if (!mi_verify_padding(page,block,&size,&wrong)) {\n    _mi_error_message(EFAULT, \"buffer overflow in theap block %p of size %zu: write after %zu bytes\\n\", block, size, wrong );\n  }\n}\n\n#else\n\nstatic void mi_check_padding(const mi_page_t* page, const mi_block_t* block) {\n  MI_UNUSED(page);\n  MI_UNUSED(block);\n}\n\n#endif\n\n// only maintain stats for smaller objects if requested\n#if (MI_STAT>0)\nstatic void mi_stat_free(const mi_page_t* page, const mi_block_t* block) {\n  MI_UNUSED(block);\n  mi_theap_t* const theap = _mi_theap_default();\n  if (!mi_theap_is_initialized(theap)) return; // (for now) skip statistics if free'd after thread_done was called (usually a thread cleanup call by the OS)\n\n  const size_t bsize = mi_page_usable_block_size(page);\n  // #if (MI_STAT>1)\n  // const size_t usize = mi_page_usable_size_of(page, block);\n  // mi_theap_stat_decrease(theap, malloc_requested, usize);\n  // #endif\n  if (bsize <= MI_LARGE_MAX_OBJ_SIZE) {\n    mi_theap_stat_decrease(theap, malloc_normal, bsize);\n    #if (MI_STAT > 1)\n    mi_theap_stat_decrease(theap, malloc_bins[_mi_bin(bsize)], 1);\n    #endif\n  }\n  else {\n    const size_t bpsize = mi_page_block_size(page);  // match stat in page.c:mi_huge_page_alloc\n    mi_theap_stat_decrease(theap, malloc_huge, bpsize);\n  }\n}\n#else\nvoid mi_stat_free(const mi_page_t* page, const mi_block_t* block) {\n  MI_UNUSED(page); MI_UNUSED(block);\n}\n#endif\n\n\n// Remove guard page when building with MI_GUARDED\n#if MI_GUARDED\nstatic void mi_block_unguard(mi_page_t* page, mi_block_t* block, void* p) {\n  MI_UNUSED(p);\n  mi_assert_internal(mi_block_ptr_is_guarded(block, p));\n  mi_assert_internal(mi_page_has_interior_pointers(page));\n  mi_assert_internal((uint8_t*)p - (uint8_t*)block >= (ptrdiff_t)sizeof(mi_block_t));\n  mi_assert_internal(block->next == MI_BLOCK_TAG_GUARDED);\n\n  const size_t bsize = mi_page_block_size(page);\n  const size_t psize = _mi_os_page_size();\n  mi_assert_internal(bsize > psize);\n  mi_assert_internal(!page->memid.is_pinned);\n  void* gpage = (uint8_t*)block + bsize - psize;\n  mi_assert_internal(_mi_is_aligned(gpage, psize));\n  _mi_os_unprotect(gpage, psize);\n}\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/heap.c",
      "sha256": "ae8e88737c9861e8e071fe5f1e7acc52093bcffd136a359a6b473101e968c14f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/*----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"  // _mi_theap_default\n\n\n/* -----------------------------------------------------------\n  Heap's\n----------------------------------------------------------- */\n\nmi_theap_t* mi_heap_theap(mi_heap_t* heap) {\n  return _mi_heap_theap(heap);\n}\n\nvoid mi_heap_set_numa_affinity(mi_heap_t* heap, int numa_node) {\n  if (heap==NULL) { heap = mi_heap_main(); }\n  heap->numa_node = (numa_node < 0 ? -1 : numa_node % _mi_os_numa_node_count());\n}\n\nvoid mi_heap_stats_merge_to_subproc(mi_heap_t* heap) {\n  if (heap==NULL) { heap = mi_heap_main(); }\n  _mi_stats_merge_into(&heap->subproc->stats, &heap->stats);\n}\n\nvoid mi_heap_stats_merge_to_main(mi_heap_t* heap) {\n  if (heap==NULL) return;\n  _mi_stats_merge_into(&mi_heap_main()->stats, &heap->stats);\n}\n\nstatic mi_decl_noinline mi_theap_t* mi_heap_init_theap(const mi_heap_t* const_heap)\n{\n  mi_heap_t* heap = (mi_heap_t*)const_heap;\n  mi_assert_internal(heap!=NULL);\n\n  if (_mi_is_heap_main(heap)) {\n    // this can be called if the (main) thread is not yet initialized (as no allocation happened)\n    // but `theap_main_init_get()` will call `mi_thread_init()`\n    mi_theap_t* const theap = _mi_theap_main_safe();\n    mi_assert_internal(theap!=NULL && _mi_is_heap_main(_mi_theap_heap(theap)));\n    return theap;\n  }\n\n  // otherwise initialize the theap for this heap\n  // get the thread local\n  mi_assert_internal(heap->theap != 0);\n  if (heap->theap==0) {  // paranoia\n    _mi_error_message(EFAULT, \"no thread-local reserved for heap (%p)\\n\", heap);\n    return NULL;\n  }\n  mi_theap_t* theap = (mi_theap_t*)_mi_thread_local_get(heap->theap);\n\n  // create a fresh theap?\n  if (theap==NULL) {\n    // set first an invalid value to ensure the thread local storage is allocated\n    if (!_mi_thread_local_set(heap->theap, (mi_theap_t*)1)) {\n      _mi_error_message(EFAULT, \"unable to allocate memory for thread local storage\\n\");\n      return NULL;\n    }    \n    // then allocate the theap\n    theap = _mi_theap_create(heap, _mi_theap_default_safe()->tld);\n    _mi_thread_local_set(heap->theap, theap);  // Cannot fail now as it was set before. Always set so the local is valid or NULL (and not 1)\n    if (theap==NULL) {\n      _mi_error_message(EFAULT, \"unable to allocate memory for a thread local heap\\n\");\n      return NULL;\n    }    \n  }\n  return theap;\n}\n\n\n// get the theap for a heap without initializing (and return NULL in that case)\nmi_theap_t* _mi_heap_theap_get_peek(const mi_heap_t* heap) {\n  if (heap==NULL || _mi_is_heap_main(heap)) {\n    return _mi_theap_main_safe(); \n  }\n  else {\n    return (mi_theap_t*)_mi_thread_local_get(heap->theap);\n  }\n}\n\n// get (and possibly create) the theap belonging to a heap\nmi_theap_t* _mi_heap_theap_get_or_init(const mi_heap_t* heap)\n{\n  mi_theap_t* theap = _mi_heap_theap_peek(heap);\n  if mi_unlikely(theap==NULL) {\n    theap = mi_heap_init_theap(heap);\n    if (theap==NULL) { return (mi_theap_t*)&_mi_theap_empty_wrong; }  // this will return NULL from page.c:_mi_malloc_generic\n  }\n  _mi_theap_cached_set(theap);\n  return theap;\n}\n\n\nmi_heap_t* mi_heap_new_in_arena(mi_arena_id_t exclusive_arena_id) {\n  // always allocate heap data in the (subprocess) main heap\n  mi_heap_t* const heap_main = mi_heap_main();\n  // todo: allocate heap data in the exclusive arena ?\n  mi_heap_t* const heap = (mi_heap_t*)mi_heap_zalloc( heap_main, sizeof(mi_heap_t) );\n  if (heap==NULL) return NULL;\n\n  // reserve a thread local slot for this heap (see also issue #1230)\n  const mi_thread_local_t theap_slot = _mi_thread_local_create();\n  if (theap_slot == 0) {\n    _mi_error_message(EFAULT, \"unable to dynamically create a thread local for a heap\\n\");\n    mi_free(heap);\n    return NULL;\n  }\n\n  // init fields\n  heap->theap = theap_slot;\n  heap->subproc = heap_main->subproc;\n  heap->heap_seq = mi_atomic_increment_relaxed(&heap_main->subproc->heap_total_count);\n  heap->exclusive_arena = _mi_arena_from_id(exclusive_arena_id);\n  heap->numa_node = -1; // no initial affinity\n  mi_stats_header_init(&heap->stats);\n  mi_lock_init(&heap->theaps_lock);\n  mi_lock_init(&heap->os_abandoned_pages_lock);\n  mi_lock_init(&heap->arena_pages_lock);\n\n  // push onto the subproc heaps\n  mi_lock(&heap->subproc->heaps_lock) {\n    mi_heap_t* head = heap->subproc->heaps;\n    heap->prev = NULL;\n    heap->next = head;\n    if (head!=NULL) { head->prev = heap;  }\n    heap->subproc->heaps = heap;\n  }\n  mi_atomic_increment_relaxed(&heap_main->subproc->heap_count);\n  mi_subproc_stat_increase(heap_main->subproc, heaps, 1);\n  return heap;\n}\n\nmi_heap_t* mi_heap_new(void) {\n  return mi_heap_new_in_arena(0);\n}\n\n// free all theaps belonging to this heap (without deleting their pages as we do this arena wise for efficiency)\nstatic void mi_heap_free_theaps(mi_heap_t* heap) {\n  // This can run concurrently with a thread that terminates (see `init.c:mi_thread_theaps_done`), \n  // and we need to ensure we free theaps atomically.\n  // We do this in a loop where we release the theaps_lock at every potential re-iteration to unblock \n  // potential concurrent thread termination which tries to remove the theap from our theaps list.\n  bool all_freed;\n  do {\n    all_freed = true;\n    mi_theap_t* theap = NULL;\n    mi_lock(&heap->theaps_lock) { \n      theap = heap->theaps; \n      while(theap != NULL) {\n        mi_theap_t* next = theap->hnext;\n        if (!_mi_theap_free(theap, false /* dont re-acquire the heap->theaps_lock */, true /* acquire the tld->theaps_lock though */ )) {\n          all_freed = false;\n        }\n        theap = next;\n      }      \n    }\n    if (!all_freed) { \n      mi_heap_stat_counter_increase(heap,heaps_delete_wait,1); \n      _mi_prim_thread_yield();\n    }\n    else { \n      mi_assert_internal(heap->theaps==NULL); \n    }               \n  }\n  while(!all_freed);\n}\n\n// free the heap resources (assuming the pages are already moved/destroyed, and all theaps have been freed)\nstatic void mi_heap_free(mi_heap_t* heap) {\n  mi_assert_internal(heap!=NULL && !_mi_is_heap_main(heap));\n\n  // free all arena pages infos\n  mi_lock(&heap->arena_pages_lock) {\n    for (size_t i = 0; i < MI_MAX_ARENAS; i++) {\n      mi_arena_pages_t* arena_pages = mi_atomic_load_ptr_relaxed(mi_arena_pages_t, &heap->arena_pages[i]);\n      if (arena_pages!=NULL) {\n        mi_atomic_store_ptr_relaxed(mi_arena_pages_t, &heap->arena_pages[i], NULL);\n        mi_free(arena_pages);\n      }\n    }\n  }\n\n  // remove the heap from the subproc\n  mi_heap_stats_merge_to_main(heap);\n  mi_atomic_decrement_relaxed(&heap->subproc->heap_count);\n  mi_subproc_stat_decrease(heap->subproc, heaps, 1);\n  mi_lock(&heap->subproc->heaps_lock) {\n    if (heap->next!=NULL) { heap->next->prev = heap->prev; }\n    if (heap->prev!=NULL) { heap->prev->next = heap->next; }\n                     else { heap->subproc->heaps = heap->next; }\n  }\n\n  _mi_thread_local_free(heap->theap);\n  mi_lock_done(&heap->theaps_lock);\n  mi_lock_done(&heap->os_abandoned_pages_lock);\n  mi_lock_done(&heap->arena_pages_lock);\n  mi_free(heap);\n}\n\nvoid mi_heap_delete(mi_heap_t* heap) {\n  if (heap==NULL) return;\n  if (_mi_is_heap_main(heap)) {\n    _mi_warning_message(\"cannot delete the main heap\\n\");\n    return;\n  }\n  mi_heap_free_theaps(heap);\n  _mi_heap_move_pages(heap, mi_heap_main());\n  mi_heap_free(heap);\n}\n\nvoid _mi_heap_force_destroy(mi_heap_t* heap) {\n  if (heap==NULL) return;\n  mi_heap_free_theaps(heap);\n  _mi_heap_destroy_pages(heap);\n  if (!_mi_is_heap_main(heap)) { mi_heap_free(heap); }  // todo: release locks of the main heap?\n}\n\nvoid mi_heap_destroy(mi_heap_t* heap) {\n  if (heap==NULL) return;\n  if (_mi_is_heap_main(heap)) {\n    _mi_warning_message(\"cannot destroy the main heap\\n\");\n    return;\n  }\n  _mi_heap_force_destroy(heap);\n}\n\nmi_heap_t* mi_heap_of(const void* p) {\n  mi_page_t* page = _mi_safe_ptr_page(p);\n  if (page==NULL) return NULL;\n  return mi_page_heap(page);\n}\n\nbool mi_any_heap_contains(const void* p) {\n  return (mi_heap_of(p)!=NULL);\n}\n\nbool mi_heap_contains(const mi_heap_t* heap, const void* p) {\n  if (heap==NULL) { heap = mi_heap_main(); }\n  return (heap==mi_heap_of(p));\n}\n\n// deprecated\nbool mi_check_owned(const void* p) {\n  return mi_any_heap_contains(p);\n}\n\n// unsafe heap utilization function for DragonFly (see issue #1258)\n// If the page of pointer `p` belongs to `heap` (or `heap==NULL`) and has less than `perc_threshold` used blocks in its used area return `true`.\n// This function is unsafe in general as it assumes we are the only thread accessing the page of `p`.\nbool mi_unsafe_heap_page_is_under_utilized(mi_heap_t* heap, void* p, size_t perc_threshold) mi_attr_noexcept {\n  if (p==NULL) return false;\n  const mi_page_t* const page = _mi_safe_ptr_page(p);   // Get the page containing this pointer\n  if (page==NULL || page->used==page->capacity || page->capacity < page->reserved) return false;\n  // If the page is the head of the queue, it is currently being used for \n  // allocations; we skip it to avoid immediate thrashing.\n  if (page->prev == NULL)  return false;\n\n  // match heap?\n  const mi_heap_t* const page_heap = mi_page_heap(page);\n  if (page_heap==NULL) return false;\n  if (heap!=NULL && page_heap!=heap) return false;\n    \n  // check utilization\n  if (page->capacity==0)   return false;\n  if (perc_threshold>=100) return true;\n  return (perc_threshold >= ((100UL*page->used) / page->capacity));\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/init.c",
      "sha256": "eca1fe77d72ab2aaccc447c8119056e9c4e8851bda9a95472b573539f76107ad",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"\n\n#include <string.h>  // memcpy, memset\n#include <stdlib.h>  // atexit\n\n#define MI_MEMID_INIT(kind)   {{{NULL,0}}, kind, true /* pinned */, true /* committed */, false /* zero */ }\n#define MI_MEMID_STATIC       MI_MEMID_INIT(MI_MEM_STATIC)\n\n// Empty page used to initialize the small free pages array\nconst mi_page_t _mi_page_empty = {\n  MI_ATOMIC_VAR_INIT(0),  // xthread_id\n  NULL,                   // free\n  0,                      // used\n  0,                      // capacity\n  0,                      // reserved capacity\n  0,                      // retire_expire\n  false,                  // is_zero\n  NULL,                   // local_free\n  MI_ATOMIC_VAR_INIT(0),  // xthread_free\n  0,                      // block_size\n  NULL,                   // page_start\n  #if (MI_PADDING || MI_ENCODE_FREELIST)\n  { 0, 0 },               // keys\n  #endif\n  NULL,                   // theap\n  NULL,                   // heap\n  NULL, NULL,             // next, prev\n  MI_ARENA_SLICE_SIZE,    // page_committed\n  MI_MEMID_STATIC         // memid\n};\n\n#define MI_PAGE_EMPTY() ((mi_page_t*)&_mi_page_empty)\n\n#if (MI_PADDING>0) && (MI_INTPTR_SIZE >= 8)\n#define MI_SMALL_PAGES_EMPTY  { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() }\n#elif (MI_PADDING>0)\n#define MI_SMALL_PAGES_EMPTY  { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() }\n#else\n#define MI_SMALL_PAGES_EMPTY  { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY() }\n#endif\n\n\n// Empty page queues for every bin\n#define QNULL(sz)  { NULL, NULL, 0, (sz)*sizeof(uintptr_t) }\n#define MI_PAGE_QUEUES_EMPTY \\\n  { QNULL(1), \\\n    QNULL(     1), QNULL(     2), QNULL(     3), QNULL(     4), QNULL(     5), QNULL(     6), QNULL(     7), QNULL(     8), /* 8 */ \\\n    QNULL(    10), QNULL(    12), QNULL(    14), QNULL(    16), QNULL(    20), QNULL(    24), QNULL(    28), QNULL(    32), /* 16 */ \\\n    QNULL(    40), QNULL(    48), QNULL(    56), QNULL(    64), QNULL(    80), QNULL(    96), QNULL(   112), QNULL(   128), /* 24 */ \\\n    QNULL(   160), QNULL(   192), QNULL(   224), QNULL(   256), QNULL(   320), QNULL(   384), QNULL(   448), QNULL(   512), /* 32 */ \\\n    QNULL(   640), QNULL(   768), QNULL(   896), QNULL(  1024), QNULL(  1280), QNULL(  1536), QNULL(  1792), QNULL(  2048), /* 40 */ \\\n    QNULL(  2560), QNULL(  3072), QNULL(  3584), QNULL(  4096), QNULL(  5120), QNULL(  6144), QNULL(  7168), QNULL(  8192), /* 48 */ \\\n    QNULL( 10240), QNULL( 12288), QNULL( 14336), QNULL( 16384), QNULL( 20480), QNULL( 24576), QNULL( 28672), QNULL( 32768), /* 56 */ \\\n    QNULL( 40960), QNULL( 49152), QNULL( 57344), QNULL( 65536), QNULL( 81920), QNULL( 98304), QNULL(114688), QNULL(131072), /* 64 */ \\\n    QNULL(163840), QNULL(196608), QNULL(229376), QNULL(262144), QNULL(327680), QNULL(393216), QNULL(458752), QNULL(524288), /* 72 */ \\\n    QNULL(MI_LARGE_MAX_OBJ_WSIZE + 1  /* 655360, Huge queue */), \\\n    QNULL(MI_LARGE_MAX_OBJ_WSIZE + 2) /* Full queue */ }\n\n#define MI_STAT_COUNT_NULL()  {0,0,0}\n\n// Empty statistics\n#define MI_STAT_COUNT(stat)     {0,0,0},\n#define MI_STAT_COUNTER(stat)   {0},\n\n#define MI_STATS_NULL  \\\n  MI_STAT_FIELDS() \\\n  \\\n  { MI_INIT4(MI_STAT_COUNT_NULL) }, \\\n  { { 0 }, { 0 }, { 0 }, { 0 } }, \\\n  \\\n  { MI_INIT74(MI_STAT_COUNT_NULL) }, \\\n  { MI_INIT74(MI_STAT_COUNT_NULL) }, \\\n  { MI_INIT5(MI_STAT_COUNT_NULL) }\n\n// --------------------------------------------------------\n// Statically allocate an empty theap as the initial\n// thread local value for the default theap,\n// and statically allocate the backing theap for the main\n// thread so it can function without doing any allocation\n// itself (as accessing a thread local for the first time\n// may lead to allocation itself on some platforms)\n// --------------------------------------------------------\n\nstatic mi_decl_cache_align mi_subproc_t subproc_main\n#if __cplusplus\n  = { };     // empty initializer to prevent running the constructor (with msvc)\n#else\n  = { 0 };   // C zero initialize\n#endif\n\nstatic mi_subproc_t* subprocs = &subproc_main;\nstatic mi_lock_t     subprocs_lock;\n\nstatic mi_decl_cache_align mi_tld_t tld_empty = {\n  0,                      // thread_id\n  0,                      // thread_seq\n  0,                      // default numa node\n  &subproc_main,          // subproc\n  NULL,                   // theaps list\n  MI_LOCK_INITIALIZER,    // theaps lock\n  false,                  // recurse\n  false,                  // is_in_threadpool\n  MI_MEMID_STATIC         // memid\n};\n\nmi_decl_cache_align const mi_theap_t _mi_theap_empty = {\n  &tld_empty,             // tld\n  MI_ATOMIC_VAR_INIT(NULL), // heap\n  MI_ATOMIC_VAR_INIT(1),  // refcount\n  0,                      // heartbeat\n  0,                      // cookie\n  { {0}, {0}, 0, true },  // random\n  0,                      // page count\n  MI_BIN_FULL, 0,         // page retired min/max\n  0,                      // pages_full_size\n  0, 0,                   // generic count\n  NULL, NULL,             // tnext, tprev\n  NULL, NULL,             // hnext, hprev\n  0,                      // full page retain\n  false,                  // allow reclaim\n  true,                   // allow abandon\n  #if MI_GUARDED\n  0, 0, 0, 1,             // sample count is 1 so we never write to it (see `internal.h:mi_theap_malloc_use_guarded`)\n  #endif\n  MI_SMALL_PAGES_EMPTY,\n  MI_PAGE_QUEUES_EMPTY,\n  MI_MEMID_STATIC,\n  { sizeof(mi_stats_t), MI_STAT_VERSION, MI_STATS_NULL },      // stats\n};\n\nmi_decl_cache_align const mi_theap_t _mi_theap_empty_wrong = {\n  &tld_empty,             // tld\n  MI_ATOMIC_VAR_INIT(NULL), // heap\n  MI_ATOMIC_VAR_INIT(1),  // refcount\n  0,                      // heartbeat\n  0,                      // cookie\n  { {0}, {0}, 0, true },  // random\n  0,                      // page count\n  MI_BIN_FULL, 0,         // page retired min/max\n  0,                      // pages_full_size\n  0, 0,                   // generic count\n  NULL, NULL,             // tnext, tprev\n  NULL, NULL,             // hnext, hprev\n  0,                      // full page retain\n  false,                  // allow reclaim\n  true,                   // allow abandon\n  #if MI_GUARDED\n  0, 0, 0, 1,             // sample count is 1 so we never write to it (see `internal.h:mi_theap_malloc_use_guarded`)\n  #endif\n  MI_SMALL_PAGES_EMPTY,\n  MI_PAGE_QUEUES_EMPTY,\n  MI_MEMID_STATIC,\n  { sizeof(mi_stats_t), MI_STAT_VERSION, MI_STATS_NULL },      // stats\n};\n\n// Heap for the main thread\n\nextern mi_decl_hidden mi_decl_cache_align mi_theap_t theap_main;\nextern mi_decl_hidden mi_decl_cache_align mi_heap_t  heap_main;\n\nstatic mi_decl_cache_align mi_tld_t tld_main = {\n  0,                      // thread_id\n  0,                      // thread_seq\n  0,                      // numa node\n  &subproc_main,          // subproc\n  &theap_main,            // theaps list\n  MI_LOCK_INITIALIZER,    // theaps lock\n  false,                  // recurse\n  false,                  // is_in_threadpool\n  MI_MEMID_STATIC         // memid\n};\n\nmi_decl_cache_align mi_theap_t theap_main = {\n  &tld_main,              // thread local data\n  MI_ATOMIC_VAR_INIT(&heap_main), // main heap\n  MI_ATOMIC_VAR_INIT(1),  // refcount\n  0,                      // heartbeat\n  0,                      // initial cookie\n  { {0x846ca68b}, {0}, 0, true },  // random\n  0,                      // page count\n  MI_BIN_FULL, 0,         // page retired min/max\n  0,                      // pages_full_size\n  0, 0,                   // generic count\n  NULL, NULL,             // tnext, tprev\n  NULL, NULL,             // hnext, hprev\n  2,                      // full page retain\n  true,                   // allow page reclaim\n  true,                   // allow page abandon\n  #if MI_GUARDED\n  0, 0, 0, 0,\n  #endif\n  MI_SMALL_PAGES_EMPTY,\n  MI_PAGE_QUEUES_EMPTY,\n  MI_MEMID_STATIC,\n  { sizeof(mi_stats_t), MI_STAT_VERSION, MI_STATS_NULL },      // stats\n};\n\nmi_decl_cache_align mi_heap_t heap_main\n#if __cplusplus\n  = { };     // empty initializer to prevent running the constructor (with msvc)\n#else\n  = { 0 };   // C zero initialize\n#endif\n\n// the theap belonging to the main heap\nmi_decl_hidden mi_decl_thread mi_theap_t* __mi_theap_main = NULL;\n\nmi_threadid_t _mi_thread_id(void) mi_attr_noexcept {\n  mi_threadid_t tid = _mi_prim_thread_id();\n  mi_assert_internal( (tid & 0x03) == 0 ); // mimalloc reserves the bottom 2 bits\n  return tid;\n}\n\n#if MI_TLS_MODEL_THREAD_LOCAL\n// the thread-local main theap for allocation\nmi_decl_hidden mi_decl_thread mi_theap_t* __mi_theap_default = (mi_theap_t*)&_mi_theap_empty;\n// the last used non-main theap\nmi_decl_hidden mi_decl_thread mi_theap_t* __mi_theap_cached = (mi_theap_t*)&_mi_theap_empty;\n#endif\n\nbool _mi_process_is_initialized = false;  // set to `true` in `mi_process_init`.\n\nmi_stats_t _mi_stats_main = { sizeof(mi_stats_t), MI_STAT_VERSION, MI_STATS_NULL };\n\n#undef MI_STAT_COUNT\n#undef MI_STAT_COUNTER\n\n\n#if MI_GUARDED\nmi_decl_export void mi_theap_guarded_set_sample_rate(mi_theap_t* theap, size_t sample_rate, size_t seed) {\n  theap->guarded_sample_rate  = sample_rate;\n  theap->guarded_sample_count = sample_rate;  // count down samples\n  if (theap->guarded_sample_rate > 1) {\n    if (seed == 0) {\n      seed = _mi_theap_random_next(theap);\n    }\n    theap->guarded_sample_count = (seed % theap->guarded_sample_rate) + 1;  // start at random count between 1 and `sample_rate`\n  }\n}\n\nmi_decl_export void mi_theap_guarded_set_size_bound(mi_theap_t* theap, size_t min, size_t max) {\n  theap->guarded_size_min = min;\n  theap->guarded_size_max = (min > max ? min : max);\n}\n\nvoid _mi_theap_guarded_init(mi_theap_t* theap) {\n  mi_theap_guarded_set_sample_rate(theap,\n    (size_t)mi_option_get_clamp(mi_option_guarded_sample_rate, 0, LONG_MAX),\n    (size_t)mi_option_get(mi_option_guarded_sample_seed));\n  mi_theap_guarded_set_size_bound(theap,\n    (size_t)mi_option_get_clamp(mi_option_guarded_min, 0, LONG_MAX),\n    (size_t)mi_option_get_clamp(mi_option_guarded_max, 0, LONG_MAX) );\n}\n#else\nmi_decl_export void mi_theap_guarded_set_sample_rate(mi_theap_t* theap, size_t sample_rate, size_t seed) {\n  MI_UNUSED(theap); MI_UNUSED(sample_rate); MI_UNUSED(seed);\n}\n\nmi_decl_export void mi_theap_guarded_set_size_bound(mi_theap_t* theap, size_t min, size_t max) {\n  MI_UNUSED(theap); MI_UNUSED(min); MI_UNUSED(max);\n}\nvoid _mi_theap_guarded_init(mi_theap_t* theap) {\n  MI_UNUSED(theap);\n}\n#endif\n\n/* -----------------------------------------------------------\n  Initialization\n  Note: on some platforms lock_init or just a thread local access\n  can cause allocation and induce recursion during initialization.\n----------------------------------------------------------- */\n\n\n// Initialize main subproc\nstatic void mi_subproc_main_init(void) {\n  if (subproc_main.memid.memkind != MI_MEM_STATIC) {\n    subproc_main.memid = _mi_memid_create(MI_MEM_STATIC);\n    subproc_main.heaps = &heap_main;\n    subproc_main.heap_total_count = 1;\n    subproc_main.heap_count = 1;\n    mi_atomic_store_ptr_release(mi_heap_t, &subproc_main.heap_main, &heap_main);\n    __mi_stat_increase_mt(&subproc_main.stats.heaps, 1);\n    mi_stats_header_init(&subproc_main.stats);\n    mi_lock_init(&subproc_main.arena_reserve_lock);\n    mi_lock_init(&subproc_main.heaps_lock);\n    mi_lock_init(&subprocs_lock);\n    mi_lock_init(&tld_empty.theaps_lock); \n  }\n}\n\n// Initialize main tld\nstatic void mi_tld_main_init(void) {\n  if (tld_main.thread_id == 0) {\n    tld_main.thread_id = _mi_prim_thread_id();\n    mi_lock_init(&tld_main.theaps_lock);\n  }\n}\n\nvoid _mi_theap_options_init(mi_theap_t* theap) {\n  theap->allow_page_reclaim = (mi_option_get(mi_option_page_reclaim_on_free) >= 0);\n  theap->allow_page_abandon = (mi_option_get(mi_option_page_full_retain) >= 0);\n  theap->page_full_retain = mi_option_get_clamp(mi_option_page_full_retain, -1, 32);\n}\n\n// Initialization of the (statically allocated) main theap, and the main tld and subproc.\nstatic void mi_theap_main_init(void) {\n  if mi_unlikely(theap_main.memid.memkind != MI_MEM_STATIC) {\n    // theap\n    theap_main.memid = _mi_memid_create(MI_MEM_STATIC);\n    #if defined(__APPLE__) || defined(_WIN32) && !defined(MI_SHARED_LIB)\n      _mi_random_init_weak(&theap_main.random);    // prevent allocation failure during bcrypt dll initialization with static linking (issue #1185)\n    #else\n      _mi_random_init(&theap_main.random);\n    #endif\n    theap_main.cookie  = _mi_theap_random_next(&theap_main);\n    _mi_theap_options_init(&theap_main);\n    _mi_theap_guarded_init(&theap_main);\n  }\n}\n\n// Initialize main heap\nstatic void mi_heap_main_init(void) {\n  if mi_unlikely(heap_main.subproc == NULL) {\n    heap_main.subproc = &subproc_main;\n    heap_main.theaps = &theap_main;\n\n    mi_theap_main_init();\n    mi_subproc_main_init();\n    mi_tld_main_init();\n\n    mi_lock_init(&heap_main.theaps_lock);\n    mi_lock_init(&heap_main.os_abandoned_pages_lock);\n    mi_lock_init(&heap_main.arena_pages_lock);\n  }\n}\n\n\n/* -----------------------------------------------------------\n  Thread local data\n----------------------------------------------------------- */\n\n// Allocate fresh tld\nstatic mi_tld_t* mi_tld_alloc(void) {\n  if (_mi_is_main_thread()) {\n    mi_atomic_increment_relaxed(&tld_main.subproc->thread_count);\n    return &tld_main;\n  }\n  else {\n    // allocate tld meta-data\n    // note: we need to be careful to not access the tld from `_mi_meta_zalloc`\n    // (and in turn from `_mi_arena_alloc_aligned` and `_mi_os_alloc_aligned`).\n    mi_memid_t memid;\n    mi_tld_t* tld = (mi_tld_t*)_mi_meta_zalloc(sizeof(mi_tld_t), &memid);\n    if (tld==NULL) {\n      _mi_error_message(ENOMEM, \"unable to allocate memory for thread local data\\n\");\n      return NULL;\n    }\n    tld->memid = memid;\n    tld->theaps = NULL;\n    mi_lock_init(&tld->theaps_lock);\n    tld->subproc = &subproc_main;\n    tld->numa_node = _mi_os_numa_node();\n    tld->thread_id = _mi_prim_thread_id();\n    tld->thread_seq = mi_atomic_increment_relaxed(&tld->subproc->thread_total_count);\n    tld->is_in_threadpool = _mi_prim_thread_is_in_threadpool();\n    mi_atomic_increment_relaxed(&tld->subproc->thread_count);\n    return tld;\n  }\n}\n\n#define MI_TLD_INVALID  ((mi_tld_t*)1)\n\nmi_decl_noinline static void mi_tld_free(mi_tld_t* tld) {\n  mi_lock_done(&tld->theaps_lock);\n  if (tld != NULL && tld != MI_TLD_INVALID) {\n    mi_atomic_decrement_relaxed(&tld->subproc->thread_count);\n    _mi_meta_free(tld, sizeof(mi_tld_t), tld->memid);\n  }\n  #if 0\n  // do not read/write to `thread_tld` on older macOS <= 14 as that will re-initialize the thread local storage\n  // (since we are calling this during pthread shutdown)\n  // (and this could happen on other systems as well, so let's never do it)\n  thread_tld = MI_TLD_INVALID;\n  #endif\n}\n\n// return the thread local heap ensuring it is initialized (and not `NULL` or `&_mi_theap_empty`);\nmi_theap_t* _mi_theap_default_safe(void) {\n  mi_theap_t* theap = _mi_theap_default();\n  if mi_likely(mi_theap_is_initialized(theap)) return theap;\n  mi_thread_init();\n  mi_assert_internal(mi_theap_is_initialized(_mi_theap_default()));\n  return _mi_theap_default();\n}\n\n// return the main theap ensuring it is initialized. \nmi_theap_t* _mi_theap_main_safe(void) {\n  mi_theap_t* theap = __mi_theap_main;\n  if mi_unlikely(theap==NULL) {  // if thread_init or default_set was never called\n    mi_thread_init();            // sets the default slot to the main theap\n    theap = _mi_theap_default();\n    mi_assert_internal(theap!=NULL);\n    mi_assert_internal(_mi_is_theap_main(theap));\n    if (_mi_is_theap_main(theap)) {\n      __mi_theap_main = theap;\n    }\n  }\n  mi_assert_internal(theap!=NULL && _mi_is_theap_main(theap));    \n  return theap;\n}\n\n\nmi_subproc_t* _mi_subproc_main(void) {\n  return &subproc_main;\n}\n\nmi_subproc_t* _mi_subproc(void) {\n  // should work without doing initialization (as it may be called from `_mi_tld -> mi_tld_alloc ... -> os_alloc -> _mi_subproc()`\n  // todo: this will still fail on OS systems where the first access to a thread-local causes allocation.\n  //       on such systems we can check for this with the _mi_prim_get_default_theap as those are protected (by being\n  //       stored in a TLS slot for example)\n  mi_theap_t* theap = _mi_theap_default();\n  if (theap == NULL) {\n    return _mi_subproc_main();\n  }\n  else {\n    return theap->tld->subproc;  // avoid using thread local storage (`thread_tld`)\n  }\n}\n\nmi_heap_t* _mi_subproc_heap_main(mi_subproc_t* subproc) {\n  mi_heap_t* heap = mi_atomic_load_ptr_relaxed(mi_heap_t,&subproc->heap_main);\n  if mi_likely(heap!=NULL) {\n    return heap;\n  }\n  else {\n    mi_heap_main_init();\n    mi_assert_internal(mi_atomic_load_relaxed(&subproc->heap_main) != NULL);\n    return mi_atomic_load_ptr_relaxed(mi_heap_t,&subproc->heap_main);\n  }\n}\n\nmi_heap_t* mi_heap_main(void) {\n  return _mi_subproc_heap_main(_mi_subproc()); // don't use mi_theap_main_init_get() so this call works during process_init\n}\n\nbool _mi_is_heap_main(const mi_heap_t* heap) {\n  mi_assert_internal(heap!=NULL);\n  return (_mi_subproc_heap_main(heap->subproc) == heap);\n}\n\nbool _mi_is_theap_main(const mi_theap_t* theap) {\n  return (mi_theap_is_initialized(theap) && _mi_is_heap_main(_mi_theap_heap(theap)));\n}\n\n/* -----------------------------------------------------------\n  Sub process\n----------------------------------------------------------- */\n\n\nmi_subproc_t* _mi_subproc_from_id(mi_subproc_id_t subproc_id) {\n  return (mi_subproc_t*)(subproc_id._mi_subproc_id);\n}\n\nmi_subproc_id_t _mi_subproc_to_id(mi_subproc_t* subproc) {\n  mi_subproc_id_t id = { subproc };\n  return id;\n}\n\nmi_subproc_id_t mi_subproc_main(void) {\n  return _mi_subproc_to_id(_mi_subproc_main());\n}\n\nmi_subproc_id_t mi_subproc_current(void) {\n  return _mi_subproc_to_id(_mi_subproc());\n}\n\nmi_subproc_id_t mi_subproc_new(void) {\n  static _Atomic(size_t) subproc_total_count;\n  mi_memid_t memid;\n  mi_subproc_t* subproc = (mi_subproc_t*)_mi_meta_zalloc(sizeof(mi_subproc_t),&memid);\n  if (subproc == NULL) return _mi_subproc_to_id(NULL);\n  subproc->memid = memid;\n  subproc->subproc_seq = mi_atomic_increment_relaxed(&subproc_total_count) + 1;\n  mi_stats_header_init(&subproc->stats);\n  mi_lock_init(&subproc->arena_reserve_lock);\n  mi_lock_init(&subproc->heaps_lock);\n  mi_lock(&subprocs_lock) {\n    // push on subproc list\n    subproc->next = subprocs;\n    if (subprocs!=NULL) { subprocs->prev = subproc; }\n    subprocs = subproc;\n  }\n  return _mi_subproc_to_id(subproc);\n}\n\n// destroy all subproc resources including arena's, heap's etc.\nstatic void mi_subproc_unsafe_destroy(mi_subproc_t* subproc, bool acquire_subprocs_lock)\n{\n  if (subproc==NULL) return;\n\n  // remove from the subproc list\n  mi_lock_maybe(&subprocs_lock, acquire_subprocs_lock) {\n    if (subproc->next!=NULL) { subproc->next->prev = subproc->prev;  }\n    if (subproc->prev!=NULL) { subproc->prev->next = subproc->next;  }\n                        else { mi_assert_internal(subprocs==subproc);  subprocs = subproc->next; }\n  }\n\n  // destroy all subproc heaps\n  mi_lock(&subproc->heaps_lock) {\n    mi_heap_t* heap = subproc->heaps;\n    while (heap != NULL) {\n      mi_heap_t* next = heap->next;\n      if (heap!=subproc->heap_main) { mi_heap_destroy(heap); }\n      heap = next;\n    }\n    mi_assert_internal(subproc->heaps == subproc->heap_main);\n    _mi_heap_force_destroy(subproc->heap_main);  // no warning if destroying the main heap\n  }\n\n  // remove associated arenas\n  _mi_arenas_unsafe_destroy_all(subproc);\n\n  // merge stats back into the main subproc?\n  if (subproc!=&subproc_main) {\n    _mi_stats_merge_into(&subproc_main.stats, &subproc->stats);\n  }\n\n  // safe to release\n  // todo: should we refcount subprocesses?\n  mi_lock_done(&subproc->arena_reserve_lock);\n  mi_lock_done(&subproc->heaps_lock);\n  if (subproc!=&subproc_main) {\n    _mi_meta_free(subproc, sizeof(mi_subproc_t), subproc->memid);\n  }\n  else {\n    // for the main subproc, also release the global page map\n    _mi_page_map_unsafe_destroy(&subproc_main);\n  }\n}\n\nvoid mi_subproc_destroy(mi_subproc_id_t subproc_id) {\n  mi_subproc_t* subproc = _mi_subproc_from_id(subproc_id);\n  if (subproc==NULL || subproc==&subproc_main) return;\n  mi_subproc_unsafe_destroy(subproc, true /* take lock */);\n}\n\nstatic void mi_subprocs_unsafe_destroy_all(void) {\n  mi_lock(&subprocs_lock) {\n    mi_subproc_t* subproc = subprocs;\n    while (subproc!=NULL) {\n      mi_subproc_t* next = subproc->next;\n      if (subproc!=&subproc_main) {\n        mi_subproc_unsafe_destroy(subproc, false /* take subprocs lock */);\n      }\n      subproc = next;\n    }\n  }  \n  mi_subproc_unsafe_destroy(&subproc_main, true /* take subprocs lock */);\n}\n\n\nvoid mi_subproc_add_current_thread(mi_subproc_id_t subproc_id) {\n  mi_subproc_t* subproc = _mi_subproc_from_id(subproc_id);\n  mi_tld_t* const tld = _mi_theap_default_safe()->tld;\n  mi_assert(tld->subproc== &subproc_main);\n  if (tld->subproc != &subproc_main) {\n    _mi_warning_message(\"unable to add thread to the subprocess as it was already in another subprocess (id: %p)\\n\", subproc);\n    return;\n  }\n  tld->subproc = subproc;\n  tld->thread_seq = mi_atomic_increment_relaxed(&subproc->thread_total_count);\n  mi_atomic_decrement_relaxed(&subproc_main.thread_count);\n  mi_atomic_increment_relaxed(&subproc->thread_count);\n}\n\n\nbool mi_subproc_visit_heaps(mi_subproc_id_t subproc_id, mi_heap_visit_fun* visitor, void* arg) {\n  mi_subproc_t* subproc = _mi_subproc_from_id(subproc_id);\n  if (subproc==NULL) return false;\n  bool ok = true;\n  mi_lock(&subproc->heaps_lock) {\n    for (mi_heap_t* heap = subproc->heaps; heap!=NULL && ok; heap = heap->next) {\n      ok = (*visitor)(heap, arg);\n    }\n  }\n  return ok;\n}\n\n\n/* -----------------------------------------------------------\n  Allocate theap data\n----------------------------------------------------------- */\n\n// Initialize the thread local default theap, called from `mi_thread_init`\nstatic mi_theap_t* _mi_thread_init_theap_default(void) {\n  mi_theap_t* theap = _mi_theap_default();\n  if (mi_theap_is_initialized(theap)) return theap;\n  if (_mi_is_main_thread()) {\n    mi_heap_main_init();\n    theap = &theap_main;\n  }\n  else {\n    // allocates tld data\n    // note: we cannot access thread-locals yet as that can cause (recursive) allocation\n    // (on macOS <= 14 for example where the loader allocates thread-local data on demand).\n    mi_tld_t* tld = mi_tld_alloc();\n    if (tld==NULL) return NULL;  // things are very wrong if this fails (out of memory)\n    // allocate and initialize the theap for the main heap\n    theap = _mi_theap_create(mi_heap_main(), tld);\n  }\n  // associate the theap with this thread\n  // (this is safe, on macOS for example, the theap is set in a dedicated TLS slot and thus does not cause recursive allocation)\n  _mi_theap_default_set(theap);\n  return theap;\n}\n\n\n// Free the thread local theaps\nstatic void mi_thread_theaps_done(mi_tld_t* tld)\n{\n  // reset the thread local theaps\n  _mi_theap_default_set((mi_theap_t*)&_mi_theap_empty);\n  _mi_theap_cached_set((mi_theap_t*)&_mi_theap_empty);\n  __mi_theap_main = NULL;\n  \n  // abandon the pages of all theaps in this thread\n  mi_lock(&tld->theaps_lock) {\n    mi_theap_t* theap = tld->theaps;\n    while (theap != NULL) {\n      mi_theap_t* next = theap->tnext; \n      // never destroy theaps; if a dll is linked statically with mimalloc,\n      // there may still be delete/free calls after the mi_fls_done is called. Issue #207\n      _mi_theap_collect_abandon(theap);\n      mi_assert_internal(theap->page_count==0);\n      theap = next;\n    }\n  }\n\n  // free the theaps of this thread.\n  // This can run concurrently with a `mi_heap_free_theaps` and we need to ensure we free theaps atomically.\n  // We do this in a loop where we release the theaps_lock at every potential re-iteration to unblock \n  // potential concurrent `mi_heap_free_theaps` which tries to remove the theap from our theaps list.\n  bool all_freed;\n  do {\n    all_freed = true;\n    mi_lock(&tld->theaps_lock) {\n      mi_theap_t* theap = tld->theaps;\n      while (theap != NULL) {\n        mi_theap_t* next = theap->tnext;\n        mi_assert_internal(theap->page_count==0);\n        if (!_mi_theap_free(theap, true /* acquire heap->theaps_lock */, false /* dont re-acquire the tld->theaps_lock*/ )) {\n          all_freed = false;\n        }\n        theap = next;\n      }\n    }\n    if (!all_freed) { \n      mi_subproc_stat_counter_increase(tld->subproc,heaps_delete_wait,1); \n      _mi_prim_thread_yield(); \n    }\n    else { \n      mi_assert_internal(tld->theaps==NULL); \n    }\n  } while (!all_freed);\n\n  mi_assert(_mi_theap_default()==(mi_theap_t*)&_mi_theap_empty); // careful to not re-initialize the default theap during theap_delete\n  mi_assert(!mi_theap_is_initialized(_mi_theap_default()));\n}\n\n\n\n// --------------------------------------------------------\n// Try to run `mi_thread_done()` automatically so any memory\n// owned by the thread but not yet released can be abandoned\n// and re-owned by another thread.\n//\n// 1. windows dynamic library:\n//     call from DllMain on DLL_THREAD_DETACH\n// 2. windows static library:\n//     use special linker section to call a destructor when the thread is done\n// 3. unix, pthreads:\n//     use a pthread key to call a destructor when a pthread is done\n//\n// In the last two cases we also need to call `mi_process_init`\n// to set up the thread local keys.\n// --------------------------------------------------------\n\n// Set up handlers so `mi_thread_done` is called automatically\nstatic void mi_process_setup_auto_thread_done(void) {\n  mi_atomic_do_once {\n    _mi_prim_thread_init_auto_done();\n    _mi_theap_default_set(&theap_main);\n  }\n}\n\n\nbool _mi_is_main_thread(void) {\n  return (tld_main.thread_id==0 || tld_main.thread_id == _mi_thread_id());\n}\n\n\n// Initialize thread\nvoid mi_thread_init(void) mi_attr_noexcept\n{\n  // ensure our process has started already\n  mi_process_init();\n  // if the theap_default is already set we have already initialized\n  if (_mi_thread_is_initialized()) return;\n\n  // initialize the default theap\n  if (_mi_thread_init_theap_default() == NULL) return; // out-of-memory on tld/theap allocation\n\n  mi_heap_stat_increase(mi_heap_main(), threads, 1);\n  // _mi_verbose_message(\"thread init: 0x%zx\\n\", _mi_thread_id());\n}\n\nvoid mi_thread_done(void) mi_attr_noexcept {\n  _mi_thread_done(NULL);\n}\n\nvoid _mi_thread_done(mi_theap_t* _theap_main)\n{\n  // NULL can be passed on some platforms\n  if (_theap_main==NULL) {\n    _theap_main = __mi_theap_main;  // don't call `mi_theap_main_safe` as that re-initializes the thread\n    if (_theap_main==NULL) {        // can happen if `mi_theap_main_safe` is never called; but then the default is main\n      _theap_main = _mi_theap_default();\n      mi_assert_internal(_theap_main==NULL || _mi_is_theap_main(_theap_main));\n    }\n  }\n\n  // prevent re-entrancy through theap_done/theap_set_default_direct (issue #699)\n  if (!mi_theap_is_initialized(_theap_main)) {\n    return;\n  }\n\n  // release dynamic thread_local's\n  _mi_thread_locals_thread_done();\n\n  // note: we store the tld as we should avoid reading `thread_tld` at this point (to avoid reinitializing the thread local storage)\n  mi_tld_t* const tld = _theap_main->tld;\n\n  // adjust stats\n  mi_heap_stat_decrease(_mi_subproc_heap_main(tld->subproc), threads, 1);  // todo: or `_theap_main->heap`?\n\n  // check thread-id as on Windows shutdown with FLS the main (exit) thread may call this on thread-local theaps...\n  if (tld->thread_id != _mi_prim_thread_id()) return;\n\n  // delete the thread local theaps\n  mi_thread_theaps_done(tld);\n\n  // free thread local data\n  mi_tld_free(tld);\n}\n\n\nmi_decl_cold mi_decl_noinline mi_theap_t* _mi_theap_empty_get(void) {\n  return (mi_theap_t*)&_mi_theap_empty;\n}\n\n#if MI_TLS_MODEL_DYNAMIC_WIN32\n\n// If we can, we use one of the 64 direct TLS slots (but fall back to expansion slots if needed)\n// See <https://en.wikipedia.org/wiki/Win32_Thread_Information_Block> for the offsets.\n#if MI_SIZE_SIZE==4\n#define MI_TLS_DIRECT_FIRST             (0x0E10 / MI_SIZE_SIZE)\n#else\n#define MI_TLS_DIRECT_FIRST             (0x1480 / MI_SIZE_SIZE)\n#endif\n#define MI_TLS_DIRECT_SLOTS             (64)\n#define MI_TLS_EXPANSION_SLOTS          (1024)\n\n#if !MI_WIN_DIRECT_TLS\n#define MI_TLS_INITIAL_SLOT             MI_TLS_EXPANSION_SLOT\n#define MI_TLS_INITIAL_EXPANSION_SLOT   (MI_TLS_EXPANSION_SLOTS-1)\n#else\n// with only direct entries, use the \"arbitrary user data\" field \n// and assume it is NULL (see also <http://www.nynaeve.net/?p=98>)\n#define MI_TLS_INITIAL_SLOT             (5)\n#define MI_TLS_INITIAL_EXPANSION_SLOT   (0)\n#endif\n\n// we initially use the last of the expansion slots as the default NULL.\n// note: this will fail if the program allocates exactly 1024+64 slots with TlsAlloc (which is quite unlikely)\nmi_decl_hidden mi_decl_cache_align size_t _mi_theap_default_slot = MI_TLS_INITIAL_SLOT;\nmi_decl_hidden size_t _mi_theap_default_expansion_slot = MI_TLS_INITIAL_EXPANSION_SLOT;\nmi_decl_hidden size_t _mi_theap_cached_slot            = MI_TLS_INITIAL_SLOT;\nmi_decl_hidden size_t _mi_theap_cached_expansion_slot  = MI_TLS_INITIAL_EXPANSION_SLOT;\n\nstatic DWORD mi_tls_raw_index_default = TLS_OUT_OF_INDEXES;\nstatic DWORD mi_tls_raw_index_cached  = TLS_OUT_OF_INDEXES;\n\nstatic bool mi_win_tls_slot_alloc(size_t* slot, size_t* extended, DWORD* raw_index) {\n  const DWORD index = TlsAlloc();\n  *raw_index = index;\n  if (index==TLS_OUT_OF_INDEXES) {\n    *extended = 0;\n    *slot = 0;\n    return false;\n  }\n  else if (index<MI_TLS_DIRECT_SLOTS) {\n    *extended = 0;\n    *slot = index + MI_TLS_DIRECT_FIRST;\n    return true;\n  }\n  #if !MI_WIN_DIRECT_TLS\n  else if (index < MI_TLS_DIRECT_SLOTS + MI_TLS_EXPANSION_SLOTS - 1) { // check maximum number of expansion slots - 1 (as we use the last one as the default)    \n    *extended = index - MI_TLS_DIRECT_SLOTS;\n    *slot = MI_TLS_EXPANSION_SLOT;\n    return true;\n  }\n  #endif\n  else {\n    // to high an index for us\n    _mi_error_message(EFAULT, \"returned tls index was too high (%u)\\n\", index);\n    TlsFree(index);\n    *raw_index = TLS_OUT_OF_INDEXES; \n    *extended = 0;\n    *slot = 0;\n    return false;\n  }\n}\n\nstatic void mi_win_tls_slot_free(DWORD* raw_index) {\n  if (*raw_index != TLS_OUT_OF_INDEXES) {\n    TlsFree(*raw_index);\n    *raw_index = TLS_OUT_OF_INDEXES;\n  }\n}\n\nstatic void mi_tls_slots_init(void) {\n  mi_atomic_do_once {\n    bool ok = mi_win_tls_slot_alloc(&_mi_theap_default_slot, &_mi_theap_default_expansion_slot, &mi_tls_raw_index_default);\n    if (ok) {\n      ok = mi_win_tls_slot_alloc(&_mi_theap_cached_slot, &_mi_theap_cached_expansion_slot, &mi_tls_raw_index_cached);\n    }\n    if (!ok) {\n      _mi_error_message(EFAULT, \"unable to allocate fast TLS user slot (0x%zx)\\n\", _mi_theap_cached_slot);\n    }\n  }\n}\n\nstatic void mi_tls_slots_done(void) {\n  mi_win_tls_slot_free(&mi_tls_raw_index_default);\n  mi_win_tls_slot_free(&mi_tls_raw_index_cached );\n}\n\nstatic void mi_win_tls_slot_set(size_t slot, size_t extended_slot, void* value) {\n  mi_assert_internal((slot >= MI_TLS_DIRECT_FIRST && slot < MI_TLS_DIRECT_FIRST + MI_TLS_DIRECT_SLOTS) || slot == MI_TLS_EXPANSION_SLOT);\n  if (slot < MI_TLS_DIRECT_FIRST + MI_TLS_DIRECT_SLOTS) {\n    mi_prim_tls_slot_set(slot, value);\n  }\n  else {\n    mi_assert_internal(extended_slot < MI_TLS_EXPANSION_SLOTS);\n    TlsSetValue((DWORD)(extended_slot + MI_TLS_DIRECT_SLOTS), value);  // use TlsSetValue to initialize the TlsExpansion array if needed\n  }\n}\n\n#elif MI_TLS_MODEL_DYNAMIC_PTHREADS\n\n// only for pthreads for now\nmi_decl_hidden pthread_key_t _mi_theap_default_key = 0;\nmi_decl_hidden pthread_key_t _mi_theap_cached_key = 0;\n\n// create a non-zero pthread key\nstatic int mi_pthread_key_create( pthread_key_t* pkey ) {\n  pthread_key_t key;\n  int err = pthread_key_create(&key, NULL);\n  if (err!=0) return err;\n  if (key==0) {\n    // if we get a zero key, create another one as we use 0 for an invalid key\n    pthread_key_t key2;\n    err = pthread_key_create(&key2, NULL);\n    pthread_key_delete(key);  // delete the old key\n    if (err!=0) return err;\n    key = key2;\n  }\n  mi_assert_internal(key!=0);    \n  *pkey = key;\n  return 0;\n}\n\nstatic void mi_tls_slots_init(void) {\n  mi_atomic_do_once {\n    int err = mi_pthread_key_create(&_mi_theap_default_key);\n    if (err==0) {\n      err = mi_pthread_key_create(&_mi_theap_cached_key);\n    }\n    if (err!=0) {\n      _mi_error_message(EFAULT, \"unable to allocate pthread keys (error %d)\\n\", err);\n    }\n  }\n}\n\nstatic void mi_tls_slots_done(void) {\n  if (_mi_theap_default_key != 0) {\n    pthread_key_delete(_mi_theap_default_key);\n    _mi_theap_default_key = 0;\n  }\n  if (_mi_theap_cached_key != 0) {\n    pthread_key_delete(_mi_theap_cached_key);\n    _mi_theap_cached_key = 0;\n  }\n}\n\n#else\n\nstatic void mi_tls_slots_init(void) {\n  // nothing\n}\n\nstatic void mi_tls_slots_done(void) {\n  // nothing\n}\n\n#endif\n\nvoid _mi_theap_cached_set(mi_theap_t* theap) {\n  mi_theap_t* prev = _mi_theap_cached();\n  if (prev==theap) return;\n  // set\n  mi_tls_slots_init();\n  #if MI_TLS_MODEL_THREAD_LOCAL\n    __mi_theap_cached = theap;\n  #elif MI_TLS_MODEL_FIXED_SLOT\n    mi_prim_tls_slot_set(MI_TLS_MODEL_FIXED_SLOT_CACHED, theap);\n  #elif MI_TLS_MODEL_DYNAMIC_WIN32\n    mi_win_tls_slot_set(_mi_theap_cached_slot, _mi_theap_cached_expansion_slot, theap);\n  #elif MI_TLS_MODEL_DYNAMIC_PTHREADS\n    if (_mi_theap_cached_key!=0) pthread_setspecific(_mi_theap_cached_key, theap);\n  #endif\n  // update refcounts (so cached theap memory keeps available until no longer cached)\n  _mi_theap_incref(theap);\n  _mi_theap_decref(prev);    \n}\n\nvoid _mi_theap_default_set(mi_theap_t* theap)  {\n  mi_theap_t* const theap_old = _mi_theap_default();\n  mi_assert_internal(theap != NULL);\n  mi_assert_internal(theap->tld->thread_id==0 || theap->tld->thread_id==_mi_thread_id());\n  mi_tls_slots_init();\n  #if MI_TLS_MODEL_THREAD_LOCAL\n    __mi_theap_default = theap;\n  #elif MI_TLS_MODEL_FIXED_SLOT\n    mi_prim_tls_slot_set(MI_TLS_MODEL_FIXED_SLOT_DEFAULT, theap);\n  #elif MI_TLS_MODEL_DYNAMIC_WIN32\n    mi_win_tls_slot_set(_mi_theap_default_slot, _mi_theap_default_expansion_slot, theap);\n  #elif MI_TLS_MODEL_DYNAMIC_PTHREADS\n    if (_mi_theap_default_key!=0) pthread_setspecific(_mi_theap_default_key, theap);\n  #endif\n\n  // set theap main if needed\n  if (mi_theap_is_initialized(theap)) {\n    // ensure the default theap is passed to `_mi_thread_done` as on some platforms we cannot access TLS at thread termination (as it would allocate again)\n    _mi_prim_thread_associate_default_theap(theap);\n    if (_mi_is_heap_main(_mi_theap_heap(theap))) {\n      __mi_theap_main = theap;\n    }\n  }\n\n  // ensure either the default slot contains the main theap, or __mi_theap_main is initialized \n  if (mi_theap_is_initialized(theap_old) && _mi_is_heap_main(_mi_theap_heap(theap_old))) {\n    __mi_theap_main = theap_old;\n  }\n}\n\nvoid mi_thread_set_in_threadpool(void) mi_attr_noexcept {\n  mi_theap_t* theap = _mi_theap_default_safe();\n  theap->tld->is_in_threadpool = true;\n}\n\n// --------------------------------------------------------\n// Run functions on process init/done, and thread init/done\n// --------------------------------------------------------\nstatic bool os_preloading = true;    // true until this module is initialized\n\n// Returns true if this module has not been initialized; Don't use C runtime routines until it returns false.\nbool mi_decl_noinline _mi_preloading(void) {\n  return os_preloading;\n}\n\n// Returns true if mimalloc was redirected\nmi_decl_nodiscard bool mi_is_redirected(void) mi_attr_noexcept {\n  return _mi_is_redirected();\n}\n\n// Called once by the process loader from `src/prim/prim.c`\nvoid _mi_auto_process_init(void) {\n  // mi_heap_main_init();\n  // #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD)\n  // volatile mi_theap_t* dummy = __mi_theap_default; // access TLS to allocate it before setting tls_initialized to true;\n  // if (dummy == NULL) return;                       // use dummy or otherwise the access may get optimized away (issue #697)\n  // #endif\n\n  os_preloading = false;\n  mi_assert_internal(_mi_is_main_thread());\n\n  mi_process_init();\n  mi_process_setup_auto_thread_done();\n  _mi_thread_locals_init();\n  _mi_options_post_init();  // now we can print to stderr\n  if (_mi_is_redirected()) _mi_verbose_message(\"malloc is redirected.\\n\");\n\n  // show message from the redirector (if present)\n  const char* msg = NULL;\n  _mi_allocator_init(&msg);\n  if (msg != NULL && (mi_option_is_enabled(mi_option_verbose) || mi_option_is_enabled(mi_option_show_errors))) {\n    _mi_fputs(NULL,NULL,NULL,msg);\n  }\n\n  // reseed random\n  _mi_random_reinit_if_weak(&theap_main.random);\n}\n\n// CPU features\nmi_decl_cache_align size_t _mi_cpu_movsb_max = 0;  // for size <= max, rep movsb is fast\nmi_decl_cache_align size_t _mi_cpu_stosb_max = 0;  // for size <= max, rep stosb is fast\nmi_decl_cache_align bool _mi_cpu_has_popcnt = false;\n\n#if (MI_ARCH_X64 || MI_ARCH_X86)\n#if defined(__GNUC__)\n// #include <cpuid.h>\nstatic bool mi_cpuid(uint32_t* regs4, uint32_t level, uint32_t sublevel) {\n  // note: use explicit assembly instead of __get_cpuid as we need the sublevel (in ecx)\n  // (on Ubuntu 22 with WSL the __get_cpuid does not clear ecx for level 7 which is incorrect).\n  uint32_t eax, ebx, ecx, edx;\n  __asm __volatile(\"cpuid\" : \"=a\"(eax), \"=b\"(ebx), \"=c\"(ecx), \"=d\"(edx) : \"a\"(level), \"c\"(sublevel) : );\n  regs4[0] = eax;\n  regs4[1] = ebx;\n  regs4[2] = ecx;\n  regs4[3] = edx;\n  return true;\n}\n\n#elif defined(_MSC_VER)\nstatic bool mi_cpuid(uint32_t* regs4, uint32_t level, uint32_t sublevel) {\n  __cpuidex((int32_t*)regs4, (int32_t)level, (int32_t)sublevel);\n  return true;\n}\n#else\nstatic bool mi_cpuid(uint32_t* regs4, uint32_t level, uint32_t sublevel) {\n  MI_UNUSED(regs4); MI_UNUSED(level); MI_UNUSED(sublevel);\n  return false;\n}\n#endif\n\nstatic void mi_detect_cpu_features(void) {\n  // FSRM for fast short rep movsb support (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017))\n  // EMRS for fast enhanced rep movsb/stosb support (not used at the moment, memcpy always seems faster?)\n  // FSRS for fast short rep stosb\n  bool amd = false;\n  bool fsrm = false;\n  // bool erms = false;\n  bool fsrs = false;\n  uint32_t cpu_info[4];\n  if (mi_cpuid(cpu_info, 0, 0)) {\n    amd = (cpu_info[2]==0x444d4163); // (Auth enti cAMD)\n  }\n  if (mi_cpuid(cpu_info, 7, 0)) {\n    fsrm = ((cpu_info[3] & (1 << 4)) != 0); // bit 4 of EDX : see <https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features>\n    // erms = ((cpu_info[1] & (1 << 9)) != 0); // bit 9 of EBX : see <https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features>\n  }\n  if (mi_cpuid(cpu_info, 7, 1)) {\n    fsrs = ((cpu_info[1] & (1 << 11)) != 0); // bit 11 of EBX: see <https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=1:_Extended_Features>\n  }\n  if (mi_cpuid(cpu_info, 1, 0)) {\n    _mi_cpu_has_popcnt = ((cpu_info[2] & (1 << 23)) != 0); // bit 23 of ECX : see <https://en.wikipedia.org/wiki/CPUID#EAX=1:_Processor_Info_and_Feature_Bits>\n  }\n\n  if (fsrm) {\n    _mi_cpu_movsb_max = 127;\n  }\n  if (fsrs || (amd && fsrm)) {  // fsrm on amd implies fsrs, see: https://marc.info/?l=git-commits-head&m=168186277717803\n    _mi_cpu_stosb_max = 127;\n  }\n}\n\n#else\nstatic void mi_detect_cpu_features(void) {\n  #if MI_ARCH_ARM64\n  _mi_cpu_has_popcnt = true;\n  #endif\n}\n#endif\n\n\n// Initialize the process; called by thread_init or the process loader\nstatic void mi_process_init_once(void) mi_attr_noexcept {\n  _mi_process_is_initialized = true;  \n  _mi_verbose_message(\"process init: 0x%zx\\n\", _mi_thread_id());\n\n  mi_detect_cpu_features();\n  _mi_options_init();\n  _mi_stats_init();\n  _mi_os_init();\n  // the following can potentially allocate (on freeBSD for pthread keys)\n  // todo: do 2-phase so we can use stats at first, then later init the keys?\n  mi_heap_main_init(); // before page_map_init so stats are working\n  _mi_page_map_init(); // todo: this could fail.. should we abort in that case?\n  mi_thread_init();\n  _mi_process_is_initialized = true;\n\n  #if defined(_WIN32) && defined(MI_WIN_USE_FLS)\n  // On windows, when building as a static lib the FLS cleanup happens to early for the main thread.\n  // To avoid this, set the FLS value for the main thread to NULL so the fls cleanup\n  // will not call _mi_thread_done on the (still executing) main thread. See issue #508.\n  _mi_prim_thread_associate_default_theap(NULL);\n  #endif\n\n  // mi_stats_reset();  // only call stat reset *after* thread init (or the theap tld == NULL)\n  mi_track_init();\n  if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {\n    size_t pages = mi_option_get_clamp(mi_option_reserve_huge_os_pages, 0, 128*1024);\n    int reserve_at  = (int)mi_option_get_clamp(mi_option_reserve_huge_os_pages_at, -1, INT_MAX);\n    if (reserve_at != -1) {\n      mi_reserve_huge_os_pages_at(pages, reserve_at, pages*500);\n    } else {\n      mi_reserve_huge_os_pages_interleave(pages, 0, pages*500);\n    }\n  }\n  if (mi_option_is_enabled(mi_option_reserve_os_memory)) {\n    long ksize = mi_option_get(mi_option_reserve_os_memory);\n    if (ksize > 0) {\n      mi_reserve_os_memory((size_t)ksize*MI_KiB, true, true);\n    }\n  }\n}\n\n// Initialize the process; called by thread_init or the process loader\nvoid mi_process_init(void) mi_attr_noexcept {\n  // #if _MSC_VER < 1920\n\t// mi_heap_main_init(); // vs2017 can dynamically re-initialize _mi_heap_main\n\t// #endif\n  mi_atomic_do_once {\n    mi_process_init_once();\n  }\n}\n\n// Called when the process is done (cdecl as it is used with `at_exit` on some platforms)\nvoid mi_cdecl mi_process_done(void) mi_attr_noexcept {\n  // only shutdown if we were initialized\n  if (!_mi_process_is_initialized) return;\n  // ensure we are called once\n  static bool process_done = false;\n  if (process_done) return;\n  process_done = true;\n\n  // free dynamic thread locals (if used at all)\n  _mi_thread_locals_done();\n\n  // release any thread specific resources and ensure _mi_thread_done is called on all but the main thread\n  _mi_prim_thread_done_auto_done();\n\n  #ifndef MI_SKIP_COLLECT_ON_EXIT\n    #if (MI_DEBUG || !defined(MI_SHARED_LIB))\n    // free all memory if possible on process exit. This is not needed for a stand-alone process\n    // but should be done if mimalloc is statically linked into another shared library which\n    // is repeatedly loaded/unloaded, see issue #281.\n    mi_theap_collect(_mi_theap_default(), true /* force */);\n    #endif\n  #endif\n\n  // done with tracking tools\n  mi_track_done()\n\n  // Forcefully release all retained memory; this can be dangerous in general if overriding regular malloc/free\n  // since after process_done there might still be other code running that calls `free` (like at_exit routines,\n  // or C-runtime termination code.\n  if (mi_option_is_enabled(mi_option_destroy_on_exit)) {\n    mi_subprocs_unsafe_destroy_all(); // destroys all subprocs, arenas, and the page_map!    \n  }\n  else {\n    mi_heap_stats_merge_to_subproc(mi_heap_main());\n  }\n  \n  // careful now to no longer access any allocator functionality \n  if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) {\n    mi_subproc_stats_print_out(mi_subproc_main(), NULL, NULL);\n  }\n  mi_lock_done(&subprocs_lock);\n  mi_tls_slots_done();\n  _mi_allocator_done();\n  _mi_verbose_message(\"process done: 0x%zx\\n\", tld_main.thread_id);\n  os_preloading = true; // don't call the C runtime anymore\n}\n\nvoid mi_cdecl _mi_auto_process_done(void) mi_attr_noexcept {\n  if (_mi_option_get_fast(mi_option_destroy_on_exit)>1) return;\n  mi_process_done();\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/libc.c",
      "sha256": "ebd95b475f15d5387e6ef3c88a9cb47b88e64d7e55998ae1dc656614676a443b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// --------------------------------------------------------\n// This module defines various std libc functions to reduce\n// the dependency on libc, and also prevent errors caused\n// by some libc implementations when called before `main`\n// executes (due to malloc redirection)\n// --------------------------------------------------------\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"      // mi_prim_getenv\n\nchar _mi_toupper(char c) {\n  if (c >= 'a' && c <= 'z') return (c - 'a' + 'A');\n                       else return c;\n}\n\nint _mi_strnicmp(const char* s, const char* t, size_t n) {\n  mi_assert_internal(s!=NULL && t!=NULL);\n  if (n == 0) return 0;\n  for (; *s != 0 && *t != 0 && n > 0; s++, t++, n--) {\n    if (_mi_toupper(*s) != _mi_toupper(*t)) break;\n  }\n  return (n == 0 ? 0 : *s - *t);\n}\n\nbool _mi_streq(const char* s, const char* t) {\n  if (s==NULL && t==NULL) return true;\n  if (s==NULL || t==NULL) return false;\n  for (; *s != 0 && *t != 0; s++, t++) {\n    if (*s != *t) break;\n  }\n  return (*s == *t);\n}\n\nvoid _mi_strlcpy(char* dest, const char* src, size_t dest_size) {\n  if (dest==NULL || src==NULL || dest_size == 0) return;\n  // copy until end of src, or when dest is (almost) full\n  while (*src != 0 && dest_size > 1) {\n    *dest++ = *src++;\n    dest_size--;\n  }\n  // always zero terminate\n  *dest = 0;\n}\n\nvoid _mi_strlcat(char* dest, const char* src, size_t dest_size) {\n  if (dest==NULL || src==NULL || dest_size == 0) return;\n  // find end of string in the dest buffer\n  while (*dest != 0 && dest_size > 1) {\n    dest++;\n    dest_size--;\n  }\n  // and catenate\n  _mi_strlcpy(dest, src, dest_size);\n}\n\nsize_t _mi_strnlen(const char* s, size_t max_len) {\n  if (s==NULL) return 0;\n  size_t len = 0;\n  while(s[len] != 0 && len < max_len) { len++; }\n  return len;\n}\n\nsize_t _mi_strlen(const char* s) {\n  return _mi_strnlen(s,PTRDIFF_MAX);\n}\n\nchar* _mi_strnstr(char* s, size_t max_len, const char* pat) {\n  if (s==NULL) return NULL;\n  if (pat==NULL) return s;\n  const size_t m = _mi_strnlen(s, max_len);\n  const size_t n = _mi_strlen(pat);  \n  for (size_t start = 0; start + n <= m; start++) {\n    size_t i = 0;\n    while (i<n && pat[i]==s[start+i]) {\n      i++;\n    }\n    if (i==n) return &s[start];\n  }\n  return NULL;\n}\n\n#ifdef MI_NO_GETENV\nbool _mi_getenv(const char* name, char* result, size_t result_size) {\n  MI_UNUSED(name);\n  MI_UNUSED(result);\n  MI_UNUSED(result_size);\n  return false;\n}\n#else\nbool _mi_getenv(const char* name, char* result, size_t result_size) {\n  if (name==NULL || result == NULL || result_size < 64) return false;\n  return _mi_prim_getenv(name,result,result_size);\n}\n#endif\n\n\n// --------------------------------------------------------\n// Define our own primitives for doing an action once\n// --------------------------------------------------------\n\n// Returns `true` only on the first invocation, signifying we can execute an action once.\n// If it returns `true`, the caller should call `_mi_atomic_once_release` after performing the action.\n// Other threads (than the initial thread that entered) will block until `_mi_atomic_once_release` has been called.\nbool _mi_atomic_once_enter(mi_atomic_once_t* once) {\n  const uintptr_t once_tid = mi_atomic_load_acquire(&once->tid);\n  if mi_likely(once_tid == 1) {\n    return false; // already executed\n  }\n  const mi_threadid_t current_tid = _mi_thread_id();\n  if (once_tid == current_tid) {\n    return false; // recursive invocation; we need this for process_init for example\n  }  \n\n  mi_lock_acquire(&once->lock);\n  uintptr_t expected = 0;\n  if (mi_atomic_cas_strong_acq_rel(&once->tid, &expected, current_tid)) {  // could use atomic_load/store as well\n    return true;  // should execute and release\n  } \n  else {\n    mi_lock_release(&once->lock);\n    return false; // already another thread entered and released\n  }\n}\n\nvoid _mi_atomic_once_release(mi_atomic_once_t* once) {\n  if (mi_atomic_load_acquire(&once->tid)>1) {  // paranoia\n    mi_atomic_store_release(&once->tid,1);     // done executing\n    mi_lock_release(&once->lock);\n  }  \n}\n\n\n// --------------------------------------------------------\n// Define our own limited `_mi_vsnprintf` and `_mi_snprintf`\n// This is mostly to avoid calling these when libc is not yet\n// initialized (and to reduce dependencies)\n//\n// format:      d i, p x u, s\n// prec:        z l ll L\n// width:       10\n// align-left:  -\n// fill:        0\n// plus:        +\n// --------------------------------------------------------\n\nstatic void mi_outc(char c, char** out, char* end) {\n  char* p = *out;\n  if (p >= end) return;\n  *p = c;\n  *out = p + 1;\n}\n\nstatic void mi_outs(const char* s, char** out, char* end) {\n  if (s == NULL) return;\n  char* p = *out;\n  while (*s != 0 && p < end) {\n    *p++ = *s++;\n  }\n  *out = p;\n}\n\nstatic void mi_out_fill(char fill, size_t len, char** out, char* end) {\n  char* p = *out;\n  for (size_t i = 0; i < len && p < end; i++) {\n    *p++ = fill;\n  }\n  *out = p;\n}\n\nstatic void mi_out_alignright(char fill, char* start, size_t len, size_t extra, char* end) {\n  if (len == 0 || extra == 0) return;\n  if (start + len + extra >= end) return;\n  // move `len` characters to the right (in reverse since it can overlap)\n  for (size_t i = 1; i <= len; i++) {\n    start[len + extra - i] = start[len - i];\n  }\n  // and fill the start\n  for (size_t i = 0; i < extra; i++) {\n    start[i] = fill;\n  }\n}\n\n\nstatic void mi_out_num(uintmax_t x, size_t base, char prefix, char** out, char* end)\n{\n  if (x == 0 || base == 0 || base > 16) {\n    if (prefix != 0) { mi_outc(prefix, out, end); }\n    mi_outc('0',out,end);\n  }\n  else {\n    // output digits in reverse\n    char* start = *out;\n    while (x > 0) {\n      char digit = (char)(x % base);\n      mi_outc((digit <= 9 ? '0' + digit : 'A' + digit - 10),out,end);\n      x = x / base;\n    }\n    if (prefix != 0) {\n      mi_outc(prefix, out, end);\n    }\n    size_t len = *out - start;\n    // and reverse in-place\n    for (size_t i = 0; i < (len / 2); i++) {\n      char c = start[len - i - 1];\n      start[len - i - 1] = start[i];\n      start[i] = c;\n    }\n  }\n}\n\n\n#define MI_NEXTC()  c = *in; if (c==0) break; in++;\n\nint _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args) {\n  if (buf == NULL || bufsize == 0 || fmt == NULL) return 0;\n  buf[bufsize - 1] = 0;\n  char* const end = buf + (bufsize - 1);\n  const char* in = fmt;\n  char* out = buf;\n  while (true) {\n    if (out >= end) break;\n    char c;\n    MI_NEXTC();\n    if (c != '%') {\n      if (c == '\\\\') {\n        MI_NEXTC();\n        switch (c) {\n        case 'e': mi_outc('\\x1B', &out, end); break;\n        case 't': mi_outc('\\t', &out, end); break;\n        case 'n': mi_outc('\\n', &out, end); break;\n        case 'r': mi_outc('\\r', &out, end); break;\n        case '\\\\': mi_outc('\\\\', &out, end); break;\n        default: /* ignore */ break;\n        }\n      }\n      else if ((c >= ' ' && c <= '~') || c=='\\n' || c=='\\r' || c=='\\t' || c=='\\x1b') { // output visible ascii or standard control only\n        mi_outc(c, &out, end);\n      }\n    }\n    else {\n      MI_NEXTC();\n      char   fill = ' ';\n      size_t width = 0;\n      char   numtype = 'd';\n      char   numplus = 0;\n      bool   alignright = true;\n      if (c == '+' || c == ' ') { numplus = c; MI_NEXTC(); }\n      if (c == '-') { alignright = false; MI_NEXTC(); }\n      if (c == '0') { fill = '0'; MI_NEXTC(); }\n      if (c >= '1' && c <= '9') {\n        width = (c - '0'); MI_NEXTC();\n        while (c >= '0' && c <= '9') {\n          width = (10 * width) + (c - '0'); MI_NEXTC();\n        }\n        if (c == 0) break;  // extra check due to while\n      }\n      if (c == 'z' || c == 't' || c == 'L') { numtype = c; MI_NEXTC(); }\n      else if (c == 'l') {\n        numtype = c; MI_NEXTC();\n        if (c == 'l') { numtype = 'L'; MI_NEXTC(); }\n      }\n\n      char* start = out;\n      if (c == '%') {\n        mi_outc('%', &out, end);\n      }\n      else if (c == 's') {\n        // string\n        const char* s = va_arg(args, const char*);\n        mi_outs(s, &out, end);\n      }\n      else if (c == 'p' || c == 'x' || c == 'u') {\n        // unsigned\n        uintmax_t x = 0;\n        if (c == 'x' || c == 'u') {\n          if (numtype == 'z')       x = va_arg(args, size_t);\n          else if (numtype == 't')  x = va_arg(args, uintptr_t); // unsigned ptrdiff_t\n          else if (numtype == 'L')  x = va_arg(args, unsigned long long);\n          else if (numtype == 'l')  x = va_arg(args, unsigned long);\n                               else x = va_arg(args, unsigned int);\n        }\n        else if (c == 'p') {\n          void* const p = va_arg(args, void*);\n          x = (uintptr_t)p;\n          mi_outs(\"0x\", &out, end);\n          start = out;\n          width = (width >= 2 ? width - 2 : 0);\n        }\n        if (width == 0 && (c == 'x' || c == 'p')) {\n          if (c == 'p')   { width = 2 * (x <= UINT32_MAX ? 4 : ((x >> 16) <= UINT32_MAX ? 6 : sizeof(void*))); }\n          if (width == 0) { width = 2; }\n          fill = '0';\n        }\n        mi_out_num(x, (c == 'x' || c == 'p' ? 16 : 10), numplus, &out, end);\n      }\n      else if (c == 'i' || c == 'd') {\n        // signed\n        intmax_t x = 0;\n        if (numtype == 'z')       x = va_arg(args, intptr_t );\n        else if (numtype == 't')  x = va_arg(args, ptrdiff_t);\n        else if (numtype == 'L')  x = va_arg(args, long long);\n        else if (numtype == 'l')  x = va_arg(args, long);\n                             else x = va_arg(args, int);\n        char pre = 0;\n        if (x < 0) {\n          pre = '-';\n          if (x > INTMAX_MIN) { x = -x; }\n        }\n        else if (numplus != 0) {\n          pre = numplus;\n        }\n        mi_out_num((uintmax_t)x, 10, pre, &out, end);\n      }\n      else if (c >= ' ' && c <= '~') {\n        // unknown format\n        mi_outc('%', &out, end);\n        mi_outc(c, &out, end);\n      }\n\n      // fill & align\n      mi_assert_internal(out <= end);\n      mi_assert_internal(out >= start);\n      const size_t len = out - start;\n      if (len < width) {\n        mi_out_fill(fill, width - len, &out, end);\n        if (alignright && out <= end) {\n          mi_out_alignright(fill, start, len, width - len, end);\n        }\n      }\n    }\n  }\n  mi_assert_internal(out <= end);\n  *out = 0;\n  return (int)(out - buf);\n}\n\nint _mi_snprintf(char* buf, size_t buflen, const char* fmt, ...) {\n  va_list args;\n  va_start(args, fmt);\n  const int written = _mi_vsnprintf(buf, buflen, fmt, args);\n  va_end(args);\n  return written;\n}\n\n\n\n// --------------------------------------------------------\n// generic trailing and leading zero count, and popcount\n// --------------------------------------------------------\n\n#if !MI_HAS_FAST_BITSCAN\n\nstatic size_t mi_ctz_generic32(uint32_t x) {\n  // de Bruijn multiplication, see <http://keithandkatie.com/keith/papers/debruijn.html>\n  static const uint8_t debruijn[32] = {\n    0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,\n    31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9\n  };\n  if (x==0) return 32;\n  return debruijn[(uint32_t)((x & -(int32_t)x) * (uint32_t)(0x077CB531U)) >> 27];\n}\n\nstatic size_t mi_clz_generic32(uint32_t x) {\n  // de Bruijn multiplication, see <http://keithandkatie.com/keith/papers/debruijn.html>\n  static const uint8_t debruijn[32] = {\n    31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1,\n    23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0\n  };\n  if (x==0) return 32;\n  x |= x >> 1;\n  x |= x >> 2;\n  x |= x >> 4;\n  x |= x >> 8;\n  x |= x >> 16;\n  return debruijn[(uint32_t)(x * (uint32_t)(0x07C4ACDDU)) >> 27];\n}\n\nsize_t _mi_ctz_generic(size_t x) {\n  if (x==0) return MI_SIZE_BITS;\n  #if (MI_SIZE_BITS <= 32)\n    return mi_ctz_generic32((uint32_t)x);\n  #else\n    const uint32_t lo = (uint32_t)x;\n    if (lo != 0) {\n      return mi_ctz_generic32(lo);\n    }\n    else {\n      return (32 + mi_ctz_generic32((uint32_t)(x>>32)));\n    }\n  #endif\n}\n\nsize_t _mi_clz_generic(size_t x) {\n  if (x==0) return MI_SIZE_BITS;\n  #if (MI_SIZE_BITS <= 32)\n    return mi_clz_generic32((uint32_t)x);\n  #else\n    const uint32_t hi = (uint32_t)(x>>32);\n    if (hi != 0) {\n      return mi_clz_generic32(hi);\n    }\n    else {\n      return 32 + mi_clz_generic32((uint32_t)x);\n    }\n  #endif\n}\n\n#endif // bit scan\n\n\n#if MI_SIZE_SIZE == 4\n#define mi_mask_even_bits32      (0x55555555)\n#define mi_mask_even_pairs32     (0x33333333)\n#define mi_mask_even_nibbles32   (0x0F0F0F0F)\n\n// sum of all the bytes in `x` if it is guaranteed that the sum < 256!\nstatic size_t mi_byte_sum32(uint32_t x) {\n  // perform `x * 0x01010101`: the highest byte contains the sum of all bytes.\n  x += (x << 8);\n  x += (x << 16);\n  return (size_t)(x >> 24);\n}\n\nstatic size_t mi_popcount_generic32(uint32_t x) {\n  // first count each 2-bit group `a`, where: a==0b00 -> 00, a==0b01 -> 01, a==0b10 -> 01, a==0b11 -> 10\n  // in other words, `a - (a>>1)`; to do this in parallel, we need to mask to prevent spilling a bit pair\n  // into the lower bit-pair:\n  x = x - ((x >> 1) & mi_mask_even_bits32);\n  // add the 2-bit pair results\n  x = (x & mi_mask_even_pairs32) + ((x >> 2) & mi_mask_even_pairs32);\n  // add the 4-bit nibble results\n  x = (x + (x >> 4)) & mi_mask_even_nibbles32;\n  // each byte now has a count of its bits, we can sum them now:\n  return mi_byte_sum32(x);\n}\n\nmi_decl_noinline size_t _mi_popcount_generic(size_t x) {\n  if (x<=1) return x;\n  if (~x==0) return MI_SIZE_BITS;\n  return mi_popcount_generic32(x);\n}\n\n#else\n#define mi_mask_even_bits64      (0x5555555555555555)\n#define mi_mask_even_pairs64     (0x3333333333333333)\n#define mi_mask_even_nibbles64   (0x0F0F0F0F0F0F0F0F)\n\n// sum of all the bytes in `x` if it is guaranteed that the sum < 256!\nstatic size_t mi_byte_sum64(uint64_t x) {\n  x += (x << 8);\n  x += (x << 16);\n  x += (x << 32);\n  return (size_t)(x >> 56);\n}\n\nstatic size_t mi_popcount_generic64(uint64_t x) {\n  x = x - ((x >> 1) & mi_mask_even_bits64);\n  x = (x & mi_mask_even_pairs64) + ((x >> 2) & mi_mask_even_pairs64);\n  x = (x + (x >> 4)) & mi_mask_even_nibbles64;\n  return mi_byte_sum64(x);\n}\n\nmi_decl_noinline size_t _mi_popcount_generic(size_t x) {\n  if (x<=1) return x;\n  if (~x==0) return MI_SIZE_BITS;\n  return mi_popcount_generic64(x);\n}\n#endif\n\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/options.c",
      "sha256": "96ef01e41f4b3043118e8c801e660b1d3f185d6fb824e5298a038aee89b6a392",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"  // mi_prim_out_stderr\n\n#include <stdio.h>      // stdin/stdout\n#include <stdlib.h>     // abort\n\nstatic long mi_max_error_count   = 16; // stop outputting errors after this (use < 0 for no limit)\nstatic long mi_max_warning_count = 16; // stop outputting warnings after this (use < 0 for no limit)\n\nstatic void mi_add_stderr_output(void);\n\nint mi_version(void) mi_attr_noexcept {\n  return MI_MALLOC_VERSION;\n}\n\n\n// --------------------------------------------------------\n// Options\n// These can be accessed by multiple threads and may be\n// concurrently initialized, but an initializing data race\n// is ok since they resolve to the same value.\n// --------------------------------------------------------\n\n\n#define MI_OPTION(opt)                  mi_option_##opt, #opt, NULL\n#define MI_OPTION_LEGACY(opt,legacy)    mi_option_##opt, #opt, #legacy\n\n// Some options can be set at build time for statically linked libraries\n// (use `-DMI_EXTRA_CPPDEFS=\"opt1=val1;opt2=val2\"`)\n//\n// This is useful if we cannot pass them as environment variables\n// (and setting them programmatically would be too late)\n\n#ifndef MI_DEFAULT_VERBOSE\n#define MI_DEFAULT_VERBOSE 0\n#endif\n\n#ifndef MI_DEFAULT_ARENA_EAGER_COMMIT\n#define MI_DEFAULT_ARENA_EAGER_COMMIT 2\n#endif\n\n// in KiB\n#ifndef MI_DEFAULT_ARENA_RESERVE\n #if (MI_INTPTR_SIZE>4)\n  #define MI_DEFAULT_ARENA_RESERVE 1024L*1024L\n #else\n  #define MI_DEFAULT_ARENA_RESERVE 128L*1024L\n #endif\n#endif\n\n#ifndef MI_DEFAULT_ARENA_MAX_OBJECT_SIZE\n#define MI_DEFAULT_ARENA_MAX_OBJECT_SIZE   ((MI_SIZE_BITS * MI_ARENA_MAX_CHUNK_OBJ_SIZE)/MI_KiB)  /* 2 GiB (or 256 MiB on 32-bit), larger than this is alloc'd by the OS */\n#endif\n\n#ifndef MI_DEFAULT_DISALLOW_ARENA_ALLOC\n#define MI_DEFAULT_DISALLOW_ARENA_ALLOC 0\n#endif\n\n#ifndef MI_DEFAULT_ALLOW_LARGE_OS_PAGES\n#define MI_DEFAULT_ALLOW_LARGE_OS_PAGES 0\n#endif\n\n#ifndef MI_DEFAULT_RESERVE_HUGE_OS_PAGES\n#define MI_DEFAULT_RESERVE_HUGE_OS_PAGES 0\n#endif\n\n#ifndef MI_DEFAULT_RESERVE_OS_MEMORY\n#define MI_DEFAULT_RESERVE_OS_MEMORY 0\n#endif\n\n#ifndef MI_DEFAULT_GUARDED_SAMPLE_RATE\n#if MI_GUARDED && !MI_DEBUG\n#define MI_DEFAULT_GUARDED_SAMPLE_RATE 4000\n#else\n#define MI_DEFAULT_GUARDED_SAMPLE_RATE 0\n#endif\n#endif\n\n#ifndef MI_DEFAULT_PAGEMAP_COMMIT\n#if defined(__APPLE__)  // when overloading malloc, we still get mixed pointers sometimes on macOS; this avoids a bad access\n#define MI_DEFAULT_PAGEMAP_COMMIT 1\n#else\n#define MI_DEFAULT_PAGEMAP_COMMIT 0\n#endif\n#endif\n\n#ifndef MI_DEFAULT_PAGE_MAX_RECLAIM\n#define MI_DEFAULT_PAGE_MAX_RECLAIM  (-1)               // unlimited\n#endif\n\n#ifndef MI_DEFAULT_PAGE_CROSS_THREAD_MAX_RECLAIM\n#define MI_DEFAULT_PAGE_CROSS_THREAD_MAX_RECLAIM  32\n#endif\n\n#ifndef MI_DEFAULT_ALLOW_THP\n#if defined(__ANDROID__)\n#define MI_DEFAULT_ALLOW_THP  0\n#else\n#define MI_DEFAULT_ALLOW_THP  1\n#endif\n#endif\n\n// Static options\nstatic mi_option_desc_t mi_options[_mi_option_last] =\n{\n  // stable options\n#if MI_DEBUG || defined(MI_SHOW_ERRORS)\n  { 1, MI_OPTION_UNINIT, MI_OPTION(show_errors) },\n#else\n  { 0, MI_OPTION_UNINIT, MI_OPTION(show_errors) },\n#endif\n  { 0, MI_OPTION_UNINIT, MI_OPTION(show_stats) },\n  { MI_DEFAULT_VERBOSE, MI_OPTION_UNINIT, MI_OPTION(verbose) },\n\n  // some of the following options are experimental and not all combinations are allowed.\n  { 1, MI_OPTION_UNINIT, MI_OPTION(deprecated_eager_commit) },  \n  { MI_DEFAULT_ARENA_EAGER_COMMIT,\n       MI_OPTION_UNINIT, MI_OPTION_LEGACY(arena_eager_commit,eager_region_commit) }, // eager commit arena's? 2 is used to enable this only on an OS that has overcommit (i.e. linux)\n  { 1, MI_OPTION_UNINIT, MI_OPTION_LEGACY(purge_decommits,reset_decommits) },        // purge decommits memory (instead of reset) (note: on linux this uses MADV_DONTNEED for decommit)\n  { MI_DEFAULT_ALLOW_LARGE_OS_PAGES,\n       MI_OPTION_UNINIT, MI_OPTION_LEGACY(allow_large_os_pages,large_os_pages) },    // use large OS pages, use only with eager commit to prevent fragmentation of VMA's\n  { MI_DEFAULT_RESERVE_HUGE_OS_PAGES,\n       MI_OPTION_UNINIT, MI_OPTION(reserve_huge_os_pages) },      // per 1GiB huge pages\n  {-1, MI_OPTION_UNINIT, MI_OPTION(reserve_huge_os_pages_at) },   // reserve huge pages at node N\n  { MI_DEFAULT_RESERVE_OS_MEMORY,\n       MI_OPTION_UNINIT, MI_OPTION(reserve_os_memory)     },      // reserve N KiB OS memory in advance (use `option_get_size`)\n  { 0, MI_OPTION_UNINIT, MI_OPTION(deprecated_segment_cache) },   // cache N segments per thread\n  { 0, MI_OPTION_UNINIT, MI_OPTION(deprecated_page_reset) },      // reset page memory on free\n  { 0, MI_OPTION_UNINIT, MI_OPTION(deprecated_abandoned_page_purge) }, \n  { 0, MI_OPTION_UNINIT, MI_OPTION(deprecated_segment_reset) },   // reset segment memory on free (needs eager commit)\n  { 1, MI_OPTION_UNINIT, MI_OPTION(deprecated_eager_commit_delay) },  \n  { 1000,MI_OPTION_UNINIT, MI_OPTION_LEGACY(purge_delay,reset_delay) },  // purge delay in milli-seconds\n  { 0,   MI_OPTION_UNINIT, MI_OPTION(use_numa_nodes) },           // 0 = use available numa nodes, otherwise use at most N nodes.\n  { 0,   MI_OPTION_UNINIT, MI_OPTION_LEGACY(disallow_os_alloc,limit_os_alloc) },           // 1 = do not use OS memory for allocation (but only reserved arenas)\n  { 100, MI_OPTION_UNINIT, MI_OPTION(os_tag) },                   // only apple specific for now but might serve more or less related purpose\n  { 32,  MI_OPTION_UNINIT, MI_OPTION(max_errors) },               // maximum errors that are output\n  { 32,  MI_OPTION_UNINIT, MI_OPTION(max_warnings) },             // maximum warnings that are output\n  { 10,  MI_OPTION_UNINIT, MI_OPTION(deprecated_max_segment_reclaim)},       // max. percentage of the abandoned segments to be reclaimed per try.\n  { 0,   MI_OPTION_UNINIT, MI_OPTION(destroy_on_exit)},           // release all OS memory on process exit; careful with dangling pointer or after-exit frees!\n  { MI_DEFAULT_ARENA_RESERVE, MI_OPTION_UNINIT, MI_OPTION(arena_reserve) }, // reserve memory N KiB at a time (=1GiB) (use `option_get_size`)\n  { 1,   MI_OPTION_UNINIT, MI_OPTION(arena_purge_mult) },         // purge delay multiplier for arena's\n  { 1,   MI_OPTION_UNINIT, MI_OPTION_LEGACY(deprecated_purge_extend_delay, decommit_extend_delay) },\n  { MI_DEFAULT_DISALLOW_ARENA_ALLOC,   MI_OPTION_UNINIT, MI_OPTION(disallow_arena_alloc) }, // 1 = do not use arena's for allocation (except if using specific arena id's)\n  { 400, MI_OPTION_UNINIT, MI_OPTION(retry_on_oom) },             // windows only: retry on out-of-memory for N milli seconds (=400), set to 0 to disable retries.\n#if defined(MI_VISIT_ABANDONED)\n  { 1,   MI_OPTION_INITIALIZED, MI_OPTION(visit_abandoned) },     // allow visiting theap blocks in abandoned segments; requires taking locks during reclaim.\n#else\n  { 0,   MI_OPTION_UNINIT, MI_OPTION(visit_abandoned) },\n#endif\n  { 0,   MI_OPTION_UNINIT, MI_OPTION(guarded_min) },              // only used when building with MI_GUARDED: minimal rounded object size for guarded objects\n  { MI_GiB, MI_OPTION_UNINIT, MI_OPTION(guarded_max) },           // only used when building with MI_GUARDED: maximal rounded object size for guarded objects\n  { 0,   MI_OPTION_UNINIT, MI_OPTION(guarded_precise) },          // disregard minimal alignment requirement to always place guarded blocks exactly in front of a guard page (=0)\n  { MI_DEFAULT_GUARDED_SAMPLE_RATE,\n         MI_OPTION_UNINIT, MI_OPTION(guarded_sample_rate)},       // 1 out of N allocations in the min/max range will be guarded (=4000)\n  { 0,   MI_OPTION_UNINIT, MI_OPTION(guarded_sample_seed)},\n  { 10000, MI_OPTION_UNINIT, MI_OPTION(generic_collect) },        // collect theaps every N (=10000) generic allocation calls\n  { 0,   MI_OPTION_UNINIT, MI_OPTION_LEGACY(page_reclaim_on_free, abandoned_reclaim_on_free) },// reclaim abandoned (small) pages on a free: -1 = disable completely, 0 = only reclaim into the originating theap, 1 = reclaim on free across theaps\n  { 2,   MI_OPTION_UNINIT, MI_OPTION(page_full_retain) },         // number of (small) pages to retain in the free page queues\n  { 4,   MI_OPTION_UNINIT, MI_OPTION(page_max_candidates) },      // max search to find a best page candidate\n  { 0,   MI_OPTION_UNINIT, MI_OPTION(max_vabits) },               // max virtual address space bits\n  { MI_DEFAULT_PAGEMAP_COMMIT,\n         MI_OPTION_UNINIT, MI_OPTION(pagemap_commit) },           // commit the full pagemap upfront?\n  { 0,   MI_OPTION_UNINIT, MI_OPTION(page_commit_on_demand) },    // commit pages on-demand (2 disables this only on overcommit systems (like Linux))\n  { MI_DEFAULT_PAGE_MAX_RECLAIM,\n         MI_OPTION_UNINIT, MI_OPTION(page_max_reclaim) },         // don't reclaim (small) pages of the same originating theap if we already own N pages in that size class\n  { MI_DEFAULT_PAGE_CROSS_THREAD_MAX_RECLAIM,\n         MI_OPTION_UNINIT, MI_OPTION(page_cross_thread_max_reclaim) }, // don't reclaim (small) pages across threads if we already own N pages in that size class\n  { MI_DEFAULT_ALLOW_THP,\n         MI_OPTION_UNINIT, MI_OPTION(allow_thp) },                // allow transparent huge pages? (=1) (on Android =0 by default). Set to 0 to disable THP for the process.\n  { 0,   MI_OPTION_UNINIT, MI_OPTION(minimal_purge_size) },       // set minimal purge size (in KiB) (=0). Using 0 resolves to either 64 (or 2048 if `mi_option_allow_thp==2`).\n  { MI_DEFAULT_ARENA_MAX_OBJECT_SIZE,   \n         MI_OPTION_UNINIT, MI_OPTION(arena_max_object_size) },    // set maximal object size that can be allocated in an arena (in KiB) (=2GiB on 64-bit). \n  { 0,   MI_OPTION_UNINIT, MI_OPTION(arena_is_numa_local) },      // associate local numa node with an initial arena allocation\n};\n\nstatic void mi_option_init(mi_option_desc_t* desc);\n\nstatic bool mi_option_has_size_in_kib(mi_option_t option) {\n  return (option == mi_option_reserve_os_memory || option == mi_option_arena_reserve || \n          option == mi_option_minimal_purge_size || option == mi_option_arena_max_object_size);\n}\n\nvoid _mi_options_init(void) {\n  // called on process load\n  for(int i = 0; i < _mi_option_last; i++ ) {\n    mi_option_t option = (mi_option_t)i;\n    long l = mi_option_get(option); MI_UNUSED(l); // initialize\n  }\n  mi_max_error_count = mi_option_get(mi_option_max_errors);\n  mi_max_warning_count = mi_option_get(mi_option_max_warnings);\n  #if MI_GUARDED\n  if (mi_option_get(mi_option_guarded_sample_rate) > 0) {\n    if (mi_option_is_enabled(mi_option_allow_large_os_pages)) {\n      mi_option_disable(mi_option_allow_large_os_pages);\n      _mi_warning_message(\"option 'allow_large_os_pages' is disabled to allow for guarded objects\\n\");\n    }\n  }\n  #endif  \n}\n\n// called at actual process load, it should be safe to print now\nvoid _mi_options_post_init(void) {\n  mi_add_stderr_output(); // now it safe to use stderr for output\n  if (mi_option_is_enabled(mi_option_verbose)) { mi_options_print(); }\n}\n\n#define mi_stringifyx(str)  #str                // and stringify\n#define mi_stringify(str)   mi_stringifyx(str)  // expand\n\nmi_decl_export void mi_options_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept\n{\n  // show version\n  const int vermajor = MI_MALLOC_VERSION/10000;\n  const int verminor = (MI_MALLOC_VERSION%10000)/100;\n  const int verpatch = (MI_MALLOC_VERSION%100);\n  _mi_fprintf(out, arg, \"v%i.%i.%i%s%s (built on %s, %s)\\n\", vermajor, verminor, verpatch,\n      #if defined(MI_CMAKE_BUILD_TYPE)\n      \", \" mi_stringify(MI_CMAKE_BUILD_TYPE)\n      #else\n      \"\"\n      #endif\n      ,\n      #if defined(MI_GIT_DESCRIBE)\n      \", git \" mi_stringify(MI_GIT_DESCRIBE)\n      #else\n      \"\"\n      #endif\n      , __DATE__, __TIME__);\n\n  // show options\n  for (int i = 0; i < _mi_option_last; i++) {\n    mi_option_t option = (mi_option_t)i;\n    long l = mi_option_get(option); MI_UNUSED(l); // possibly initialize\n    mi_option_desc_t* desc = &mi_options[option];\n    _mi_fprintf(out, arg, \"option '%s': %ld %s\\n\", desc->name, desc->value, (mi_option_has_size_in_kib(option) ? \"KiB\" : \"\"));\n  }\n\n  // show build configuration\n  _mi_fprintf(out, arg, \"debug level : %d\\n\", MI_DEBUG );\n  _mi_fprintf(out, arg, \"secure level: %d\\n\", MI_SECURE );\n  _mi_fprintf(out, arg, \"mem tracking: %s\\n\", MI_TRACK_TOOL);\n  #if MI_GUARDED\n  _mi_fprintf(out, arg, \"guarded build: %s\\n\", mi_option_get(mi_option_guarded_sample_rate) != 0 ? \"enabled\" : \"disabled\");\n  #endif\n  #if MI_TSAN\n  _mi_fprintf(out, arg, \"thread santizer enabled\\n\");\n  #endif\n}\n\nmi_decl_export void mi_options_print(void) mi_attr_noexcept {\n  mi_options_print_out(NULL, NULL);\n}\n\nlong _mi_option_get_fast(mi_option_t option) {\n  mi_assert(option >= 0 && option < _mi_option_last);\n  mi_option_desc_t* desc = &mi_options[option];\n  mi_assert(desc->option == option);  // index should match the option\n  //mi_assert(desc->init != MI_OPTION_UNINIT);\n  return desc->value;\n}\n\n\nmi_decl_nodiscard long mi_option_get(mi_option_t option) {\n  mi_assert(option >= 0 && option < _mi_option_last);\n  if (option < 0 || option >= _mi_option_last) return 0;\n  mi_option_desc_t* desc = &mi_options[option];\n  mi_assert(desc->option == option);  // index should match the option\n  if mi_unlikely(desc->init == MI_OPTION_UNINIT) {\n    mi_option_init(desc);\n  }\n  return desc->value;\n}\n\nmi_decl_nodiscard long mi_option_get_clamp(mi_option_t option, long min, long max) {\n  long x = mi_option_get(option);\n  return (x < min ? min : (x > max ? max : x));\n}\n\nmi_decl_nodiscard size_t mi_option_get_size(mi_option_t option) {\n  const long x = mi_option_get(option);\n  size_t size = (x < 0 ? 0 : (size_t)x);\n  if (mi_option_has_size_in_kib(option)) {\n    if (mi_mul_overflow(size, MI_KiB, &size)) {\n      size = MI_MAX_ALLOC_SIZE;\n    }\n  }\n  return size;\n}\n\nvoid mi_option_set(mi_option_t option, long value) {\n  mi_assert(option >= 0 && option < _mi_option_last);\n  if (option < 0 || option >= _mi_option_last) return;\n  mi_option_desc_t* desc = &mi_options[option];\n  mi_assert(desc->option == option);  // index should match the option\n  desc->value = value;\n  desc->init = MI_OPTION_INITIALIZED;\n  // ensure min/max range; be careful to not recurse.\n  if (desc->option == mi_option_guarded_min && _mi_option_get_fast(mi_option_guarded_max) < value) {\n    mi_option_set(mi_option_guarded_max, value);\n  }\n  else if (desc->option == mi_option_guarded_max && _mi_option_get_fast(mi_option_guarded_min) > value) {\n    mi_option_set(mi_option_guarded_min, value);\n  }\n}\n\nvoid mi_option_set_default(mi_option_t option, long value) {\n  mi_assert(option >= 0 && option < _mi_option_last);\n  if (option < 0 || option >= _mi_option_last) return;\n  mi_option_desc_t* desc = &mi_options[option];\n  if (desc->init != MI_OPTION_INITIALIZED) {\n    desc->value = value;\n  }\n}\n\nmi_decl_nodiscard bool mi_option_is_enabled(mi_option_t option) {\n  return (mi_option_get(option) != 0);\n}\n\nvoid mi_option_set_enabled(mi_option_t option, bool enable) {\n  mi_option_set(option, (enable ? 1 : 0));\n}\n\nvoid mi_option_set_enabled_default(mi_option_t option, bool enable) {\n  mi_option_set_default(option, (enable ? 1 : 0));\n}\n\nvoid mi_option_enable(mi_option_t option) {\n  mi_option_set_enabled(option,true);\n}\n\nvoid mi_option_disable(mi_option_t option) {\n  mi_option_set_enabled(option,false);\n}\n\nstatic void mi_cdecl mi_out_stderr(const char* msg, void* arg) {\n  MI_UNUSED(arg);\n  if (msg != NULL && msg[0] != 0) {\n    _mi_prim_out_stderr(msg);\n  }\n}\n\n// Since an output function can be registered earliest in the `main`\n// function we also buffer output that happens earlier. When\n// an output function is registered it is called immediately with\n// the output up to that point.\n#ifndef MI_MAX_DELAY_OUTPUT\n#define MI_MAX_DELAY_OUTPUT ((size_t)(16*1024))\n#endif\nstatic char out_buf[MI_MAX_DELAY_OUTPUT+1];\nstatic _Atomic(size_t) out_len;\nstatic mi_lock_t out_buf_lock = MI_LOCK_INITIALIZER;\n\nstatic void mi_cdecl mi_out_buf(const char* msg, void* arg) {\n  MI_UNUSED(arg);\n  if (msg==NULL) return;\n  if (mi_atomic_load_acquire(&out_len)>=MI_MAX_DELAY_OUTPUT) return;\n  size_t n = _mi_strlen(msg);\n  if (n==0 || n >= MI_MAX_DELAY_OUTPUT) return;\n  // copy msg into the buffer\n  mi_lock(&out_buf_lock) {\n    const size_t start = mi_atomic_add_acq_rel(&out_len, n);\n    if (start < MI_MAX_DELAY_OUTPUT) {\n      // check bound\n      if (start+n >= MI_MAX_DELAY_OUTPUT) {\n        n = MI_MAX_DELAY_OUTPUT-start-1;\n      }\n      _mi_memcpy(&out_buf[start], msg, n);\n    }\n  }\n}\n\nstatic void mi_out_buf_flush(mi_output_fun* out, bool no_more_buf, void* arg) {\n  if (out==NULL) return;\n  // claim (if `no_more_buf == true`, no more output will be added after this point)\n  mi_lock(&out_buf_lock) {\n    size_t count = mi_atomic_add_acq_rel(&out_len, (no_more_buf ? MI_MAX_DELAY_OUTPUT : 1));\n    // and output the current contents\n    if (count>MI_MAX_DELAY_OUTPUT) count = MI_MAX_DELAY_OUTPUT;\n    out_buf[count] = 0;\n    out(out_buf,arg);\n    if (!no_more_buf) {\n      out_buf[count] = '\\n'; // if continue with the buffer, insert a newline\n    }\n  }\n}\n\n\n// Once this module is loaded, switch to this routine\n// which outputs to stderr and the delayed output buffer.\nstatic void mi_cdecl mi_out_buf_stderr(const char* msg, void* arg) {\n  mi_out_stderr(msg,arg);\n  mi_out_buf(msg,arg);\n}\n\n\n\n// --------------------------------------------------------\n// Default output handler\n// --------------------------------------------------------\n\n// The program should only install a single output handler from a single thread\n// since otherwise the argument and output function may not match.\nstatic _Atomic(void*) mi_out_default; // = // is `mi_output_fun*` (but some platforms don't support atomic function pointers)\nstatic _Atomic(void*) mi_out_arg; // = NULL\n\nstatic mi_output_fun* mi_out_get_default(void** parg) {\n  mi_output_fun* const out = (mi_output_fun*)mi_atomic_load_ptr_acquire(void,&mi_out_default);\n  if (parg != NULL) { *parg = mi_atomic_load_ptr_acquire(void,&mi_out_arg); }\n  return (out == NULL ? &mi_out_buf : out);\n}\n\nvoid mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept {\n  mi_atomic_store_ptr_release(void,&mi_out_default, (void*)(out == NULL ? &mi_out_stderr : out)); // stop using the delayed output buffer\n  mi_atomic_store_ptr_release(void,&mi_out_arg, arg);\n  if (out!=NULL) { mi_out_buf_flush(out,true,arg); }        // output all the delayed output now\n}\n\n// add stderr to the delayed output after the module is loaded\nstatic void mi_add_stderr_output(void) {\n  mi_assert_internal(mi_out_default == NULL);\n  mi_out_buf_flush(&mi_out_stderr, false, NULL); // flush current contents to stderr\n  mi_atomic_store_ptr_release(void,&mi_out_default,(void*)&mi_out_buf_stderr);  // and add stderr to the delayed output\n  mi_atomic_store_ptr_release(void,&mi_out_arg,NULL);\n}\n\n// --------------------------------------------------------\n// Messages, all end up calling `_mi_fputs`.\n// --------------------------------------------------------\nstatic _Atomic(size_t) error_count;   // = 0;  // when >= max_error_count stop emitting errors\nstatic _Atomic(size_t) warning_count; // = 0;  // when >= max_warning_count stop emitting warnings\n\n// When overriding malloc, we may recurse into mi_vfprintf if an allocation\n// inside the C runtime causes another message.\n// In some cases (like on macOS) the loader already allocates which\n// calls into mimalloc; if we then access thread locals (like `recurse`)\n// this may crash as the access may call _tlv_bootstrap that tries to\n// (recursively) invoke malloc again to allocate space for the thread local\n// variables on demand. This is why we use a _mi_preloading test on such\n// platforms. However, C code generator may move the initial thread local address\n// load before the `if` and we therefore split it out in a separate function.\nstatic mi_decl_thread bool recurse = false;\n\nstatic mi_decl_noinline bool mi_recurse_enter_prim(void) {\n  if (recurse) return false;\n  recurse = true;\n  return true;\n}\n\nstatic mi_decl_noinline void mi_recurse_exit_prim(void) {\n  recurse = false;\n}\n\nstatic bool mi_recurse_enter(void) {\n  #if defined(__APPLE__) || defined(__ANDROID__) || defined(MI_TLS_RECURSE_GUARD)\n  if (_mi_preloading()) return false;\n  #endif\n  return mi_recurse_enter_prim();\n}\n\nstatic void mi_recurse_exit(void) {\n  #if defined(__APPLE__) || defined(__ANDROID__) || defined(MI_TLS_RECURSE_GUARD)\n  if (_mi_preloading()) return;\n  #endif\n  mi_recurse_exit_prim();\n}\n\nvoid _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message) {\n  if (out==NULL || (void*)out==(void*)stdout || (void*)out==(void*)stderr) { // TODO: use mi_out_stderr for stderr?\n    if (!mi_recurse_enter()) return;\n    out = mi_out_get_default(&arg);\n    if (prefix != NULL) out(prefix, arg);\n    out(message, arg);\n    mi_recurse_exit();\n  }\n  else {\n    if (prefix != NULL) out(prefix, arg);\n    out(message, arg);\n  }\n}\n\n// Define our own limited `fprintf` that avoids memory allocation.\n// We do this using `_mi_vsnprintf` with a limited buffer.\nstatic void mi_vfprintf( mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args ) {\n  char buf[992];\n  if (fmt==NULL) return;\n  if (!mi_recurse_enter()) return;\n  _mi_vsnprintf(buf, sizeof(buf)-1, fmt, args);\n  mi_recurse_exit();\n  _mi_fputs(out,arg,prefix,buf);\n}\n\nvoid _mi_fprintf( mi_output_fun* out, void* arg, const char* fmt, ... ) {\n  va_list args;\n  va_start(args,fmt);\n  mi_vfprintf(out,arg,NULL,fmt,args);\n  va_end(args);\n}\n\nstatic void mi_vfprintf_thread(mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args) {\n  if (prefix != NULL && _mi_strnlen(prefix,33) <= 32 && !_mi_is_main_thread()) {\n    char tprefix[64];\n    _mi_snprintf(tprefix, sizeof(tprefix), \"%sthread 0x%tx: \", prefix, (uintptr_t)_mi_thread_id());\n    mi_vfprintf(out, arg, tprefix, fmt, args);\n  }\n  else {\n    mi_vfprintf(out, arg, prefix, fmt, args);\n  }\n}\n\nvoid _mi_raw_message(const char* fmt, ...) {\n  va_list args;\n  va_start(args, fmt);\n  mi_vfprintf(NULL, NULL, NULL, fmt, args);\n  va_end(args);\n}\n\nvoid _mi_message(const char* fmt, ...) {\n  va_list args;\n  va_start(args, fmt);\n  mi_vfprintf_thread(NULL, NULL, \"mimalloc: \", fmt, args);\n  va_end(args);\n}\n\nvoid _mi_trace_message(const char* fmt, ...) {\n  if (mi_option_get(mi_option_verbose) <= 1) return;  // only with verbose level 2 or higher\n  va_list args;\n  va_start(args, fmt);\n  mi_vfprintf_thread(NULL, NULL, \"mimalloc: \", fmt, args);\n  va_end(args);\n}\n\nvoid _mi_verbose_message(const char* fmt, ...) {\n  if (!mi_option_is_enabled(mi_option_verbose)) return;\n  va_list args;\n  va_start(args,fmt);\n  mi_vfprintf(NULL, NULL, \"mimalloc: \", fmt, args);\n  va_end(args);\n}\n\nstatic void mi_show_error_message(const char* fmt, va_list args) {\n  if (!mi_option_is_enabled(mi_option_verbose)) {\n    if (!mi_option_is_enabled(mi_option_show_errors)) return;\n    if (mi_max_error_count >= 0 && (long)mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return;\n  }\n  mi_vfprintf_thread(NULL, NULL, \"mimalloc: error: \", fmt, args);\n}\n\nvoid _mi_warning_message(const char* fmt, ...) {\n  if (!mi_option_is_enabled(mi_option_verbose)) {\n    if (!mi_option_is_enabled(mi_option_show_errors)) return;\n    if (mi_max_warning_count >= 0 && (long)mi_atomic_increment_acq_rel(&warning_count) > mi_max_warning_count) return;\n  }\n  va_list args;\n  va_start(args,fmt);\n  mi_vfprintf_thread(NULL, NULL, \"mimalloc: warning: \", fmt, args);\n  va_end(args);\n}\n\n\n#if MI_DEBUG\nmi_decl_noreturn mi_decl_cold void _mi_assert_fail(const char* assertion, const char* fname, unsigned line, const char* func ) mi_attr_noexcept {\n  _mi_fprintf(NULL, NULL, \"mimalloc: assertion failed: at \\\"%s\\\":%u, %s\\n  assertion: \\\"%s\\\"\\n\", fname, line, (func==NULL?\"\":func), assertion);\n  abort();\n}\n#endif\n\n// --------------------------------------------------------\n// Errors\n// --------------------------------------------------------\n\nstatic mi_error_fun* volatile  mi_error_handler; // = NULL\nstatic _Atomic(void*) mi_error_arg;     // = NULL\n\nstatic void mi_error_default(int err) {\n  MI_UNUSED(err);\n#if (MI_DEBUG>0)\n  if (err==EFAULT) {\n    #ifdef _MSC_VER\n    __debugbreak();\n    #endif\n    abort();\n  }\n#endif\n#if (MI_SECURE>0)\n  if (err==EFAULT) {  // abort on serious errors in secure mode (corrupted meta-data)\n    abort();\n  }\n#endif\n#if defined(MI_XMALLOC)\n  if (err==ENOMEM || err==EOVERFLOW) { // abort on memory allocation fails in xmalloc mode\n    abort();\n  }\n#endif\n}\n\nvoid mi_register_error(mi_error_fun* fun, void* arg) {\n  mi_error_handler = fun;  // can be NULL\n  mi_atomic_store_ptr_release(void,&mi_error_arg, arg);\n}\n\nvoid _mi_error_message(int err, const char* fmt, ...) {\n  // show detailed error message\n  va_list args;\n  va_start(args, fmt);\n  mi_show_error_message(fmt, args);\n  va_end(args);\n  // and call the error handler which may abort (or return normally)\n  if (mi_error_handler != NULL) {\n    mi_error_handler(err, mi_atomic_load_ptr_acquire(void,&mi_error_arg));\n  }\n  else {\n    mi_error_default(err);\n  }\n}\n\n// --------------------------------------------------------\n// Initialize options by checking the environment\n// --------------------------------------------------------\n\n// TODO: implement ourselves to reduce dependencies on the C runtime\n#include <stdlib.h> // strtol\n#include <string.h> // strstr\n\n\nstatic void mi_option_init(mi_option_desc_t* desc) {\n  // Read option value from the environment\n  char s[64 + 1];\n  char buf[64+1];\n  _mi_strlcpy(buf, \"mimalloc_\", sizeof(buf));\n  _mi_strlcat(buf, desc->name, sizeof(buf));\n  bool found = _mi_getenv(buf, s, sizeof(s));\n  if (!found && desc->legacy_name != NULL) {\n    _mi_strlcpy(buf, \"mimalloc_\", sizeof(buf));\n    _mi_strlcat(buf, desc->legacy_name, sizeof(buf));\n    found = _mi_getenv(buf, s, sizeof(s));\n    if (found) {\n      _mi_warning_message(\"environment option \\\"mimalloc_%s\\\" is deprecated -- use \\\"mimalloc_%s\\\" instead.\\n\", desc->legacy_name, desc->name);\n    }\n  }\n\n  if (found) {\n    size_t len = _mi_strnlen(s, sizeof(buf) - 1);\n    for (size_t i = 0; i < len; i++) {\n      buf[i] = _mi_toupper(s[i]);\n    }\n    buf[len] = 0;\n    if (buf[0] == 0 || _mi_streq(buf,\"1\") || _mi_streq(buf,\"TRUE\") || _mi_streq(buf,\"YES\") || _mi_streq(buf,\"ON\")) {\n      desc->value = 1;\n      desc->init = MI_OPTION_INITIALIZED;\n    }\n    else if (_mi_streq(buf,\"0\") || _mi_streq(buf,\"FALSE\") || _mi_streq(buf,\"NO\") || _mi_streq(buf,\"OFF\")) {      \n      desc->value = 0;\n      desc->init = MI_OPTION_INITIALIZED;\n    }\n    else {\n      char* end = buf;\n      long value = strtol(buf, &end, 10);\n      if (mi_option_has_size_in_kib(desc->option)) {\n        // this option is interpreted in KiB to prevent overflow of `long` for large allocations\n        // (long is 32-bit on 64-bit windows, which allows for 4TiB max.)\n        size_t size = (value < 0 ? 0 : (size_t)value);\n        bool overflow = false;\n        if (*end == 'K') { end++; }\n        else if (*end == 'M') { overflow = mi_mul_overflow(size,MI_KiB,&size); end++; }\n        else if (*end == 'G') { overflow = mi_mul_overflow(size,MI_MiB,&size); end++; }\n        else if (*end == 'T') { overflow = mi_mul_overflow(size,MI_GiB,&size); end++; }\n        else { size = (size + MI_KiB - 1) / MI_KiB; }\n        if (end[0] == 'I' && end[1] == 'B') { end += 2; } // KiB, MiB, GiB, TiB\n        else if (*end == 'B') { end++; }                  // Kb, Mb, Gb, Tb\n        if (overflow || size > (MI_MAX_ALLOC_SIZE / MI_KiB)) { size = (MI_MAX_ALLOC_SIZE / MI_KiB); }\n        value = (size > LONG_MAX ? LONG_MAX : (long)size);\n      }\n      if (*end == 0) {\n        mi_option_set(desc->option, value);\n      }\n      else {\n        // set `init` first to avoid recursion through _mi_warning_message on mimalloc_verbose.\n        desc->init = MI_OPTION_DEFAULTED;\n        if (desc->option == mi_option_verbose && desc->value == 0) {\n          // if the 'mimalloc_verbose' env var has a bogus value we'd never know\n          // (since the value defaults to 'off') so in that case briefly enable verbose\n          desc->value = 1;\n          _mi_warning_message(\"environment option mimalloc_%s has an invalid value.\\n\", desc->name);\n          desc->value = 0;\n        }\n        else {\n          _mi_warning_message(\"environment option mimalloc_%s has an invalid value.\\n\", desc->name);\n        }\n      }\n    }\n    mi_assert_internal(desc->init != MI_OPTION_UNINIT);\n  }\n  else if (!_mi_preloading()) {\n    desc->init = MI_OPTION_DEFAULTED;\n  }\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/os.c",
      "sha256": "011e965f28c0e2c885a6834d51bd756a458dd37ebfed6fd4d9ad6607ce0390ed",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"\n\n/* -----------------------------------------------------------\n  Initialization.\n----------------------------------------------------------- */\n#ifndef MI_DEFAULT_PHYSICAL_MEMORY_IN_KIB\n#if MI_INTPTR_SIZE < 8\n#define MI_DEFAULT_PHYSICAL_MEMORY_IN_KIB   4*MI_MiB    // 4 GiB\n#else\n#define MI_DEFAULT_PHYSICAL_MEMORY_IN_KIB   32*MI_MiB   // 32 GiB\n#endif\n#endif\n\nstatic mi_os_mem_config_t mi_os_mem_config = {\n  4096,     // page size\n  0,        // large page size (usually 2MiB)\n  4096,     // allocation granularity\n  MI_DEFAULT_PHYSICAL_MEMORY_IN_KIB,\n  MI_MAX_VABITS, // in `bits.h`\n  true,     // has overcommit?  (if true we use MAP_NORESERVE on mmap systems)\n  false,    // can we partially free allocated blocks? (on mmap systems we can free anywhere in a mapped range, but on Windows we must free the entire span)\n  true,     // has virtual reserve? (if true we can reserve virtual address space without using commit or physical memory)\n  false     // has transparent huge pages? (if true we purge in (aligned) large page size chunks only to not fragment such pages)\n};\n\nbool _mi_os_has_overcommit(void) {\n  return mi_os_mem_config.has_overcommit;\n}\n\nbool _mi_os_has_virtual_reserve(void) {\n  return mi_os_mem_config.has_virtual_reserve;\n}\n\n\n// OS (small) page size\nsize_t _mi_os_page_size(void) {\n  return mi_os_mem_config.page_size;\n}\n\n// if large OS pages are supported (2 or 4MiB), then return the size, otherwise return the small page size (4KiB)\nsize_t _mi_os_large_page_size(void) {\n  return (mi_os_mem_config.large_page_size != 0 ? mi_os_mem_config.large_page_size : _mi_os_page_size());\n}\n\n// minimal purge size. Can be larger than the page size if transparent huge pages are enabled.\nsize_t _mi_os_minimal_purge_size(void) {\n  size_t minsize = mi_option_get_size(mi_option_minimal_purge_size);\n  if (minsize != 0) {\n    return _mi_align_up(minsize, _mi_os_page_size());\n  }\n  else if (mi_os_mem_config.has_transparent_huge_pages && mi_option_get(mi_option_allow_thp) == 2) {\n    return _mi_os_large_page_size();\n  }\n  else {\n    return _mi_os_page_size();\n  }\n}\n\nsize_t _mi_os_guard_page_size(void) {\n  const size_t gsize = _mi_os_page_size();\n  mi_assert(gsize <= (MI_ARENA_SLICE_SIZE/4)); // issue #1166\n  return gsize;\n}\n\nsize_t _mi_os_virtual_address_bits(void) {\n  const size_t vbits = mi_os_mem_config.virtual_address_bits;\n  mi_assert(vbits <= MI_MAX_VABITS);\n  return vbits;\n}\n\nbool _mi_os_canuse_large_page(size_t size, size_t alignment) {\n  // if we have access, check the size and alignment requirements\n  if (mi_os_mem_config.large_page_size == 0) return false;\n  return ((size % mi_os_mem_config.large_page_size) == 0 && (alignment % mi_os_mem_config.large_page_size) == 0);\n}\n\n// round to a good OS allocation size (bounded by max 12.5% waste)\nsize_t _mi_os_good_alloc_size(size_t size) {\n  size_t align_size;\n  if (size < 512*MI_KiB) align_size = _mi_os_page_size();\n  else if (size < 2*MI_MiB) align_size = 64*MI_KiB;\n  else if (size < 8*MI_MiB) align_size = 256*MI_KiB;\n  else if (size < 32*MI_MiB) align_size = 1*MI_MiB;\n  else align_size = 4*MI_MiB;\n  if mi_unlikely(size >= (SIZE_MAX - align_size)) return size; // possible overflow?\n  return _mi_align_up(size, align_size);\n}\n\nvoid _mi_os_init(void) {\n  _mi_prim_mem_init(&mi_os_mem_config);\n}\n\n\n/* -----------------------------------------------------------\n  Util\n-------------------------------------------------------------- */\nbool _mi_os_decommit(void* addr, size_t size);\nbool _mi_os_commit(void* addr, size_t size, bool* is_zero);\n\n// On systems with enough virtual address bits, we can do efficient aligned allocation by using\n// the 2TiB to 30TiB area to allocate those. If we have at least 46 bits of virtual address\n// space (64TiB) we use this technique. (but see issue #939)\n#if (MI_INTPTR_SIZE >= 8) && !defined(MI_NO_ALIGNED_HINT) // && !defined(WIN32) && !defined(ANDROID)\n\n// Return a MI_HINT_ALIGN (4MiB) aligned address that is probably available.\n// If this returns NULL, the OS will determine the address but on some OS's that may not be\n// properly aligned which can be more costly as it needs to be adjusted afterwards.\n// For a size > 16GiB this always returns NULL in order to guarantee good ASLR randomization;\n// (otherwise an initial large allocation of say 2TiB has a 50% chance to include (known) addresses\n//  in the middle of the 2TiB - 6TiB address range (see issue #372))\n\n#define MI_HINT_ALIGN ((uintptr_t)4 << 20)  // 4MiB alignment\n#define MI_HINT_BASE  ((uintptr_t)2 << 40)  // 2TiB start\n#define MI_HINT_AREA  ((uintptr_t)4 << 40)  // upto (2+4) 6TiB  (since before win8 there is \"only\" 8TiB available to processes)\n#define MI_HINT_MAX   ((uintptr_t)30 << 40) // wrap after 30TiB (area after 32TiB is used for huge OS pages)\n\nvoid* _mi_os_get_aligned_hint(size_t try_alignment, size_t size)\n{\n  static mi_decl_cache_align _Atomic(uintptr_t) aligned_base; // = 0\n\n  // todo: perhaps only do alignment hints if THP is enabled?\n  if (try_alignment <= mi_os_mem_config.alloc_granularity || try_alignment > MI_HINT_ALIGN) return NULL;\n  if (mi_os_mem_config.virtual_address_bits < 46) return NULL;  // < 64TiB virtual address space\n  size = _mi_align_up(size, MI_HINT_ALIGN);\n  if (size > 16*MI_GiB) return NULL;  // guarantee the chance of fixed valid address is at least 1/(MI_HINT_AREA / 1<<34)\n  size += MI_HINT_ALIGN;              // put in virtual gaps between hinted blocks; this splits VLA's but increases guarded areas.\n\n  uintptr_t hint = mi_atomic_add_acq_rel(&aligned_base, size);\n  if (hint == 0 || hint > MI_HINT_MAX) {   // wrap or initialize\n    uintptr_t init = MI_HINT_BASE;\n    #if (MI_SECURE>=1 || defined(NDEBUG))  // security: randomize start of aligned allocations unless in debug mode\n    mi_theap_t* const theap = _mi_theap_default();     // don't use `mi_theap_get_default()` as that can cause allocation recursively (issue #1267)\n    if (!mi_theap_is_initialized(theap)) return NULL;  // no hint as we lack randomness at this point\n    const uintptr_t r = _mi_theap_random_next(theap);\n    init = init + ((MI_HINT_ALIGN * ((r>>17) & 0xFFFFF)) % MI_HINT_AREA);  // (randomly 20 bits)*4MiB == 0 to 4TiB\n    #endif\n    uintptr_t expected = hint + size;\n    mi_atomic_cas_strong_acq_rel(&aligned_base, &expected, init);\n    hint = mi_atomic_add_acq_rel(&aligned_base, size); // this may still give 0 or > MI_HINT_MAX but that is ok, it is a hint after all\n  }\n  mi_assert_internal(hint%MI_HINT_ALIGN == 0);\n  if (hint%try_alignment != 0) return NULL;\n  return (void*)hint;\n}\n#else\nvoid* _mi_os_get_aligned_hint(size_t try_alignment, size_t size) {\n   MI_UNUSED(try_alignment); MI_UNUSED(size);\n   return NULL;\n}\n#endif\n\n\n/* -----------------------------------------------------------\n  Guard page allocation\n----------------------------------------------------------- */\n\n// In secure mode, return the size of a guard page, otherwise 0\nsize_t _mi_os_secure_guard_page_size(void) {\n  #if MI_SECURE > 0\n  return _mi_os_guard_page_size();\n  #else\n  return 0;\n  #endif\n}\n\n// In secure mode, try to decommit an area and output a warning if this fails.\nbool _mi_os_secure_guard_page_set_at(void* addr, mi_memid_t memid) {\n  if (addr == NULL) return true;\n  #if MI_SECURE > 0\n  bool ok = false;\n  if (!memid.is_pinned) {\n    mi_arena_t* const arena = mi_memid_arena(memid);\n    if (arena != NULL && arena->commit_fun != NULL) {\n      ok = (*(arena->commit_fun))(false /* decommit */, addr, _mi_os_secure_guard_page_size(), NULL, arena->commit_fun_arg);\n    }\n    else {\n      ok = _mi_os_decommit(addr, _mi_os_secure_guard_page_size());\n    }\n  }\n  if (!ok) {\n    _mi_error_message(EINVAL, \"secure level %d, but failed to commit guard page (at %p of size %zu)\\n\", MI_SECURE, addr, _mi_os_secure_guard_page_size());\n  }\n  return ok;\n  #else\n  MI_UNUSED(memid);\n  return true;\n  #endif\n}\n\n// In secure mode, try to decommit an area and output a warning if this fails.\nbool _mi_os_secure_guard_page_set_before(void* addr, mi_memid_t memid) {\n  return _mi_os_secure_guard_page_set_at((uint8_t*)addr - _mi_os_secure_guard_page_size(), memid);\n}\n\n// In secure mode, try to recommit an area\nbool _mi_os_secure_guard_page_reset_at(void* addr, mi_memid_t memid) {\n  if (addr == NULL) return true;\n  #if MI_SECURE > 0\n  if (!memid.is_pinned) {\n    mi_arena_t* const arena = mi_memid_arena(memid);\n    if (arena != NULL && arena->commit_fun != NULL) {\n      return (*(arena->commit_fun))(true, addr, _mi_os_secure_guard_page_size(), NULL, arena->commit_fun_arg);\n    }\n    else {\n      return _mi_os_commit(addr, _mi_os_secure_guard_page_size(), NULL);\n    }\n  }\n  #else\n  MI_UNUSED(memid);\n  #endif\n  return true;\n}\n\n// In secure mode, try to recommit an area\nbool _mi_os_secure_guard_page_reset_before(void* addr, mi_memid_t memid) {\n  return _mi_os_secure_guard_page_reset_at((uint8_t*)addr - _mi_os_secure_guard_page_size(), memid);\n}\n\n\n/* -----------------------------------------------------------\n  Free memory\n-------------------------------------------------------------- */\n\nstatic void mi_os_free_huge_os_pages(void* p, size_t size, mi_subproc_t* subproc);\n\nstatic void mi_os_prim_free(void* addr, size_t size, size_t commit_size, mi_subproc_t* subproc) {\n  mi_assert_internal((size % _mi_os_page_size()) == 0);\n  if (addr == NULL) return; // || _mi_os_is_huge_reserved(addr)\n  int err = _mi_prim_free(addr, size);  // allow size==0 (issue #1041)\n  if (err != 0) {\n    _mi_warning_message(\"unable to free OS memory (error: %d (0x%x), size: 0x%zx bytes, address: %p)\\n\", err, err, size, addr);\n  }\n  if (subproc == NULL) { subproc = _mi_subproc(); } // from `mi_arenas_unsafe_destroy` we pass subproc_main explicitly as we can no longer use the theap pointer\n  if (commit_size > 0) {\n    mi_subproc_stat_decrease(subproc, committed, commit_size);\n  }\n  mi_subproc_stat_decrease(subproc, reserved, size);\n}\n\nvoid _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t memid, mi_subproc_t* subproc /* can be NULL */) {\n  if (mi_memkind_is_os(memid.memkind)) {\n    size_t csize = memid.mem.os.size;\n    if (csize==0) { csize = _mi_os_good_alloc_size(size); }\n    mi_assert_internal(csize >= size);\n    size_t commit_size = (still_committed ? csize : 0);\n    void* base = addr;\n    // different base? (due to alignment)\n    if (memid.mem.os.base != base) {\n      mi_assert(memid.mem.os.base <= addr);\n      base = memid.mem.os.base;\n      const size_t diff = (uint8_t*)addr - (uint8_t*)memid.mem.os.base;\n      if (memid.mem.os.size==0) {\n        csize += diff;\n      }\n      if (still_committed) {\n        commit_size -= diff;  // the (addr-base) part was already un-committed\n      }\n    }\n    // free it\n    if (memid.memkind == MI_MEM_OS_HUGE) {\n      mi_assert(memid.is_pinned);\n      mi_os_free_huge_os_pages(base, csize, subproc);\n    }\n    else {\n      mi_os_prim_free(base, csize, (still_committed ? commit_size : 0), subproc);\n    }\n  }\n  else {\n    // nothing to do\n    mi_assert(memid.memkind < MI_MEM_OS);\n  }\n}\n\nvoid  _mi_os_free(void* p, size_t size, mi_memid_t memid) {\n  _mi_os_free_ex(p, size, true, memid, NULL);\n}\n\n\n/* -----------------------------------------------------------\n   Primitive allocation from the OS.\n-------------------------------------------------------------- */\n\n// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.\n// Also `hint_addr` is a hint and may be ignored.\nstatic void* mi_os_prim_alloc_at(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero) {\n  mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);\n  mi_assert_internal(is_zero != NULL);\n  mi_assert_internal(is_large != NULL);\n  if (size == 0) return NULL;\n  if (!commit) { allow_large = false; }\n  if (try_alignment == 0) { try_alignment = 1; } // avoid 0 to ensure there will be no divide by zero when aligning\n\n  // try to align along large OS page size for larger allocations\n  const size_t large_page_size = mi_os_mem_config.large_page_size;\n  if (large_page_size > 0 && hint_addr == NULL && size >= 8*large_page_size && _mi_is_power_of_two(try_alignment) && try_alignment < large_page_size) {\n    try_alignment = large_page_size;\n  }\n\n  *is_zero = false;\n  void* p = NULL;\n  int err = _mi_prim_alloc(hint_addr, size, try_alignment, commit, allow_large, is_large, is_zero, &p);\n  if (err != 0) {\n    _mi_warning_message(\"unable to allocate OS memory (error: %d (0x%x), addr: %p, size: 0x%zx bytes, align: 0x%zx, commit: %d, allow large: %d)\\n\", err, err, hint_addr, size, try_alignment, commit, allow_large);\n  }\n\n  mi_os_stat_counter_increase(mmap_calls, 1);\n  if (p != NULL) {\n    mi_os_stat_increase(reserved, size);\n    if (commit) {\n      mi_os_stat_increase(committed, size);\n      // seems needed for asan (or `mimalloc-test-api` fails)\n      #ifdef MI_TRACK_ASAN\n      if (*is_zero) { mi_track_mem_defined(p,size); }\n               else { mi_track_mem_undefined(p,size); }\n      #endif\n    }\n  }\n  return p;\n}\n\nstatic void* mi_os_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero) {\n  return mi_os_prim_alloc_at(NULL, size, try_alignment, commit, allow_large, is_large, is_zero);\n}\n\n\n// Primitive aligned allocation from the OS.\n// This function guarantees the allocated memory is aligned.\nstatic void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid) {\n  mi_assert_internal(memid!=NULL);\n  mi_assert_internal(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0));\n  mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);\n  *memid = _mi_memid_none();\n  if (!commit) allow_large = false;\n  if (!(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0))) return NULL;\n  size = _mi_align_up(size, _mi_os_page_size());\n\n  // try a direct allocation if the alignment is below the default, or less than or equal to 1/4 fraction of the size.\n  const bool try_direct_alloc = (alignment <= mi_os_mem_config.alloc_granularity || alignment <= size/4);\n\n  bool os_is_large = false;\n  bool os_is_zero = false;\n  void*  os_base = NULL;\n  size_t os_size = size;\n  void* p = NULL;\n  if (try_direct_alloc) {\n    p = mi_os_prim_alloc(size, alignment, commit, allow_large, &os_is_large, &os_is_zero);\n  }\n\n  // aligned already?\n  if (p != NULL && _mi_is_aligned(p,alignment)) {\n    os_base = p;\n  }\n  else {\n    // if not aligned, free it, overallocate, and unmap around it\n    #if !MI_TRACK_ASAN\n    if (try_direct_alloc) {\n      _mi_warning_message(\"unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x%zx bytes, address: %p, alignment: 0x%zx, commit: %d)\\n\", size, p, alignment, commit);\n    }\n    #endif\n    if (p != NULL) { mi_os_prim_free(p, size, (commit ? size : 0), NULL); }\n    if (size >= (SIZE_MAX - alignment)) return NULL; // overflow\n    const size_t over_size = size + alignment;\n\n    if (!mi_os_mem_config.has_partial_free) {  // win32 virtualAlloc cannot free parts of an allocated block\n      // over-allocate uncommitted (virtual) memory\n      p = mi_os_prim_alloc(over_size, 1 /*alignment*/, false /* commit? */, false /* allow_large */, &os_is_large, &os_is_zero);\n      if (p == NULL) return NULL;\n\n      // set p to the aligned part in the full region\n      // note: Windows VirtualFree needs the actual base pointer\n      // this is handled though by having the `base` field in the memid\n      os_base = p; // remember the base\n      os_size = over_size;\n      p = _mi_align_up_ptr(p, alignment);\n\n      // explicitly commit only the aligned part\n      if (commit) {\n        if (!_mi_os_commit(p, size, NULL)) {\n          mi_os_prim_free(os_base, over_size, 0, NULL);\n          return NULL;\n        }\n      }\n    }\n    else  { // mmap can free inside an allocation\n      // overallocate...\n      p = mi_os_prim_alloc(over_size, 1, commit, false, &os_is_large, &os_is_zero);\n      if (p == NULL) return NULL;\n\n      // and selectively unmap parts around the over-allocated area.\n      void* const aligned_p = _mi_align_up_ptr(p, alignment);\n      const size_t pre_size = (uint8_t*)aligned_p - (uint8_t*)p;\n      const size_t mid_size = _mi_align_up(size, _mi_os_page_size());\n      const size_t post_size = over_size - pre_size - mid_size;\n      mi_assert_internal(pre_size < over_size&& post_size < over_size&& mid_size >= size);\n      if (pre_size > 0)  { mi_os_prim_free(p, pre_size, (commit ? pre_size : 0), NULL); }\n      if (post_size > 0) { mi_os_prim_free((uint8_t*)aligned_p + mid_size, post_size, (commit ? post_size : 0), NULL); }\n      // we can return the aligned pointer on `mmap` systems\n      p = aligned_p;\n      os_base = aligned_p; // since we freed the pre part, `*base == p`.\n      os_size = mid_size;\n    }\n  }\n\n  mi_assert_internal(p != NULL && os_base != NULL && _mi_is_aligned(p,alignment));\n  mi_assert_internal(os_base <= p && size <= os_size);\n  *memid = _mi_memid_create_os(os_base,os_size,commit,os_is_zero,os_is_large);\n  return p;\n}\n\n\n/* -----------------------------------------------------------\n  OS API: alloc and alloc_aligned\n----------------------------------------------------------- */\n\nvoid* _mi_os_alloc(size_t size, mi_memid_t* memid) {\n  *memid = _mi_memid_none();\n  if (size == 0) return NULL;\n  size = _mi_os_good_alloc_size(size);\n  bool os_is_large = false;\n  bool os_is_zero  = false;\n  void* p = mi_os_prim_alloc(size, 0, true, false, &os_is_large, &os_is_zero);\n  if (p == NULL) return NULL;\n\n  *memid = _mi_memid_create_os(p, size, true, os_is_zero, os_is_large);\n  mi_assert_internal(memid->mem.os.size >= size);\n  mi_assert_internal(memid->initially_committed);\n  return p;\n}\n\nvoid* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid)\n{\n  MI_UNUSED(&_mi_os_get_aligned_hint); // suppress unused warnings\n  *memid = _mi_memid_none();\n  if (size == 0) return NULL;\n  size = _mi_os_good_alloc_size(size);\n  alignment = _mi_align_up(alignment, _mi_os_page_size());\n\n  void* p = mi_os_prim_alloc_aligned(size, alignment, commit, allow_large, memid );\n  if (p == NULL) return NULL;\n\n  mi_assert_internal(memid->mem.os.size >= size);\n  mi_assert_internal(_mi_is_aligned(p,alignment));\n  if (commit) { mi_assert_internal(memid->initially_committed); }\n  return p;\n}\n\n\nmi_decl_nodiscard static void* mi_os_ensure_zero(void* p, size_t size, mi_memid_t* memid) {\n  if (p==NULL || size==0) return p;\n  // ensure committed\n  if (!memid->initially_committed) {\n    bool is_zero = false;\n    if (!_mi_os_commit(p, size, &is_zero)) {\n      _mi_os_free(p, size, *memid);\n      return NULL;\n    }\n    memid->initially_committed = true;\n  }\n  // ensure zero'd\n  if (memid->initially_zero) return p;\n  _mi_memzero_aligned(p,size);\n  memid->initially_zero = true;\n  return p;\n}\n\nvoid*  _mi_os_zalloc(size_t size, mi_memid_t* memid) {\n  void* p = _mi_os_alloc(size,memid);\n  return mi_os_ensure_zero(p, size, memid);\n}\n\n/* -----------------------------------------------------------\n  OS aligned allocation with an offset. This is used\n  for large alignments > MI_BLOCK_ALIGNMENT_MAX. We use a large mimalloc\n  page where the object can be aligned at an offset from the start of the segment.\n  As we may need to overallocate, we need to free such pointers using `mi_free_aligned`\n  to use the actual start of the memory region.\n----------------------------------------------------------- */\n\nvoid* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t offset, bool commit, bool allow_large, mi_memid_t* memid) {\n  mi_assert(offset <= size);\n  mi_assert((alignment % _mi_os_page_size()) == 0);\n  *memid = _mi_memid_none();\n  if (offset > size) return NULL;\n  if (offset == 0) {\n    // regular aligned allocation\n    return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid);\n  }\n  else {\n    // overallocate to align at an offset\n    const size_t extra = _mi_align_up(offset, alignment) - offset;\n    if (size >= SIZE_MAX - extra) return NULL;  // too large\n    const size_t oversize = size + extra;\n    void* const start = _mi_os_alloc_aligned(oversize, alignment, commit, allow_large, memid);\n    if (start == NULL) return NULL;\n\n    void* const p = (uint8_t*)start + extra;\n    mi_assert(_mi_is_aligned((uint8_t*)p + offset, alignment));\n    // decommit the overallocation at the start\n    if (commit && extra >= _mi_os_page_size()) {\n      _mi_os_decommit(start, extra);\n    }\n    return p;\n  }\n}\n\n/* -----------------------------------------------------------\n  OS memory API: reset, commit, decommit, protect, unprotect.\n----------------------------------------------------------- */\n\n// OS page align within a given area, either conservative (pages inside the area only),\n// or not (straddling pages outside the area is possible)\nstatic void* mi_os_page_align_areax(bool conservative, void* addr, size_t size, size_t* newsize) {\n  mi_assert(addr != NULL && size > 0);\n  if (newsize != NULL) *newsize = 0;\n  if (size == 0 || addr == NULL) return NULL;\n\n  // page align conservatively within the range, or liberally straddling pages outside the range\n  void* start = (conservative ? _mi_align_up_ptr(addr, _mi_os_page_size())\n                              : _mi_align_down_ptr(addr, _mi_os_page_size()));\n  void* end   = (conservative ? _mi_align_down_ptr((uint8_t*)addr + size, _mi_os_page_size())\n                              : _mi_align_up_ptr((uint8_t*)addr + size, _mi_os_page_size()));\n  ptrdiff_t diff = (uint8_t*)end - (uint8_t*)start;\n  if (diff <= 0) return NULL;\n\n  mi_assert_internal((conservative && (size_t)diff <= size) || (!conservative && (size_t)diff >= size));\n  if (newsize != NULL) *newsize = (size_t)diff;\n  return start;\n}\n\nstatic void* mi_os_page_align_area_conservative(void* addr, size_t size, size_t* newsize) {\n  return mi_os_page_align_areax(true, addr, size, newsize);\n}\n\nbool _mi_os_commit_ex(void* addr, size_t size, bool* is_zero, size_t stat_size) {\n  if (is_zero != NULL) { *is_zero = false; }\n  mi_os_stat_counter_increase(commit_calls, 1);\n\n  // page align range\n  size_t csize;\n  void* start = mi_os_page_align_areax(false /* conservative? */, addr, size, &csize);\n  if (csize == 0) return true;\n\n  // commit\n  bool os_is_zero = false;\n  int err = _mi_prim_commit(start, csize, &os_is_zero);\n  if (err != 0) {\n    _mi_warning_message(\"cannot commit OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\\n\", err, err, start, csize);\n    return false;\n  }\n  if (os_is_zero && is_zero != NULL) {\n    *is_zero = true;\n    mi_assert_expensive(mi_mem_is_zero(start, csize));\n  }\n  // note: the following seems required for asan (otherwise `mimalloc-test-stress` fails)\n  #ifdef MI_TRACK_ASAN\n  if (os_is_zero) { mi_track_mem_defined(start,csize); }\n             else { mi_track_mem_undefined(start,csize); }\n  #endif\n  mi_os_stat_increase(committed, stat_size);  // use size for precise commit vs. decommit\n  return true;\n}\n\nbool _mi_os_commit(void* addr, size_t size, bool* is_zero) {\n  return _mi_os_commit_ex(addr, size, is_zero, size);\n}\n\nstatic bool mi_os_decommit_ex(void* addr, size_t size, bool* needs_recommit, size_t stat_size) {\n  mi_assert_internal(needs_recommit!=NULL);\n\n  // page align\n  size_t csize;\n  void* start = mi_os_page_align_area_conservative(addr, size, &csize);\n  if (csize == 0) return true;\n\n  // decommit\n  *needs_recommit = true;\n  int err = _mi_prim_decommit(start,csize,needs_recommit);\n  if (err != 0) {\n    _mi_warning_message(\"cannot decommit OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\\n\", err, err, start, csize);\n  }\n  else if (*needs_recommit) {\n    mi_os_stat_decrease(committed, stat_size);\n  }\n  mi_assert_internal(err == 0);\n  return (err == 0);\n}\n\nbool _mi_os_decommit(void* addr, size_t size) {\n  bool needs_recommit;\n  return mi_os_decommit_ex(addr, size, &needs_recommit, size);\n}\n\n\n// Signal to the OS that the address range is no longer in use\n// but may be used later again. This will release physical memory\n// pages and reduce swapping while keeping the memory committed.\n// We page align to a conservative area inside the range to reset.\nbool _mi_os_reset(void* addr, size_t size) {\n  // page align conservatively within the range\n  size_t csize;\n  void* start = mi_os_page_align_area_conservative(addr, size, &csize);\n  if (csize == 0) return true;  // || _mi_os_is_huge_reserved(addr)\n  mi_os_stat_counter_increase(reset, csize);\n  mi_os_stat_counter_increase(reset_calls, 1);\n\n  #if (MI_DEBUG>1) && !MI_SECURE && !MI_TRACK_ENABLED // && !MI_TSAN\n  memset(start, 0, csize); // pretend it is eagerly reset\n  #endif\n\n  int err = _mi_prim_reset(start, csize);\n  if (err != 0) {\n    _mi_warning_message(\"cannot reset OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\\n\", err, err, start, csize);\n  }\n  return (err == 0);\n}\n\n\nvoid _mi_os_reuse( void* addr, size_t size ) {\n  // page align conservatively within the range\n  size_t csize = 0;\n  void* const start = mi_os_page_align_area_conservative(addr, size, &csize);\n  if (csize == 0) return;\n  const int err = _mi_prim_reuse(start, csize);\n  if (err != 0) {\n    _mi_warning_message(\"cannot reuse OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\\n\", err, err, start, csize);\n  }\n}\n\n// either resets or decommits memory, returns true if the memory needs\n// to be recommitted if it is to be re-used later on.\nbool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, size_t stat_size, mi_commit_fun_t* commit_fun, void* commit_fun_arg)\n{\n  if (mi_option_get(mi_option_purge_delay) < 0) return false;  // is purging allowed?\n  mi_os_stat_counter_increase(purge_calls, 1);\n  mi_os_stat_counter_increase(purged, size);\n\n  if (commit_fun != NULL) {\n    bool decommitted = (*commit_fun)(false, p, size, NULL, commit_fun_arg);\n    return decommitted; // needs_recommit?\n  }\n  else if (mi_option_is_enabled(mi_option_purge_decommits) &&   // should decommit?\n           !_mi_preloading())                                   // don't decommit during preloading (unsafe)\n  {\n    bool needs_recommit = true;\n    mi_os_decommit_ex(p, size, &needs_recommit, stat_size);\n    return needs_recommit;\n  }\n  else {\n    if (allow_reset) {  // this can sometimes be not allowed if the range is not fully committed (on Windows, we cannot reset uncommitted memory)\n      _mi_os_reset(p, size);\n    }\n    return false;  // needs no recommit\n  }\n}\n\n// either resets or decommits memory, returns true if the memory needs\n// to be recommitted if it is to be re-used later on.\nbool _mi_os_purge(void* p, size_t size) {\n  return _mi_os_purge_ex(p, size, true, size, NULL, NULL);\n}\n\n\n// Protect a region in memory to be not accessible.\nstatic  bool mi_os_protectx(void* addr, size_t size, bool protect) {\n  // page align conservatively within the range\n  size_t csize = 0;\n  void* start = mi_os_page_align_area_conservative(addr, size, &csize);\n  if (csize == 0) return false;\n  /*\n  if (_mi_os_is_huge_reserved(addr)) {\n\t  _mi_warning_message(\"cannot mprotect memory allocated in huge OS pages\\n\");\n  }\n  */\n  int err = _mi_prim_protect(start,csize,protect);\n  if (err != 0) {\n    _mi_warning_message(\"cannot %s OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\\n\", (protect ? \"protect\" : \"unprotect\"), err, err, start, csize);\n  }\n  return (err == 0);\n}\n\nbool _mi_os_protect(void* addr, size_t size) {\n  return mi_os_protectx(addr, size, true);\n}\n\nbool _mi_os_unprotect(void* addr, size_t size) {\n  return mi_os_protectx(addr, size, false);\n}\n\n\n\n/* ----------------------------------------------------------------------------\nSupport for allocating huge OS pages (1Gib) that are reserved up-front\nand possibly associated with a specific NUMA node. (use `numa_node>=0`)\n-----------------------------------------------------------------------------*/\n#define MI_HUGE_OS_PAGE_SIZE  (MI_GiB)\n\n\n#if (MI_INTPTR_SIZE >= 8)\n// To ensure proper alignment, use our own area for huge OS pages\nstatic mi_decl_cache_align _Atomic(uintptr_t)  mi_huge_start; // = 0\n\n// Claim an aligned address range for huge pages\nstatic uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) {\n  if (total_size != NULL) *total_size = 0;\n  const size_t size = pages * MI_HUGE_OS_PAGE_SIZE;\n\n  uintptr_t start = 0;\n  uintptr_t end = 0;\n  uintptr_t huge_start = mi_atomic_load_relaxed(&mi_huge_start);\n  do {\n    start = huge_start;\n    if (start == 0) {\n      // Initialize the start address after the 32TiB area\n      start = ((uintptr_t)8 << 40);   // 8TiB virtual start address\n      #if (MI_SECURE>0 || MI_DEBUG==0)  // security: randomize start of huge pages unless in debug mode\n      mi_theap_t* const theap = _mi_theap_default();     // don't use `mi_theap_get_default()` as that can cause allocation recursively (issue #1267)\n      if (mi_theap_is_initialized(theap)) {              // todo: or no hint at all if we lack randomness?\n        const uintptr_t r = _mi_theap_random_next(theap);\n        start = start + ((uintptr_t)MI_HUGE_OS_PAGE_SIZE * ((r>>17) & 0x0FFF));  // (randomly 12bits)*1GiB == between 0 to 4TiB\n      }\n      else {\n        _mi_warning_message(\"failed to randomize the start address of huge pages allocation (%zu bytes at %p)\", size, start);\n      }\n      #endif\n    }\n    end = start + size;\n  } while (!mi_atomic_cas_weak_acq_rel(&mi_huge_start, &huge_start, end));\n\n  if (total_size != NULL) *total_size = size;\n  return (uint8_t*)start;\n}\n#else\nstatic uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) {\n  MI_UNUSED(pages);\n  if (total_size != NULL) *total_size = 0;\n  return NULL;\n}\n#endif\n\n// Allocate MI_ARENA_SLICE_ALIGN aligned huge pages\nvoid* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_msecs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid) {\n  *memid = _mi_memid_none();\n  if (psize != NULL) *psize = 0;\n  if (pages_reserved != NULL) *pages_reserved = 0;\n  size_t size = 0;\n  uint8_t* const start = mi_os_claim_huge_pages(pages, &size);\n  if (start == NULL) return NULL; // or 32-bit systems\n\n  // Allocate one page at the time but try to place them contiguously\n  // We allocate one page at the time to be able to abort if it takes too long\n  // or to at least allocate as many as available on the system.\n  mi_msecs_t start_t = _mi_clock_start();\n  size_t page = 0;\n  bool all_zero = true;\n  while (page < pages) {\n    // allocate a page\n    bool is_zero = false;\n    void* addr = start + (page * MI_HUGE_OS_PAGE_SIZE);\n    void* p = NULL;\n    int err = _mi_prim_alloc_huge_os_pages(addr, MI_HUGE_OS_PAGE_SIZE, numa_node, &is_zero, &p);\n    if (!is_zero) { all_zero = false;  }\n    if (err != 0) {\n      _mi_warning_message(\"unable to allocate huge OS page (error: %d (0x%x), address: %p, size: %zx bytes)\\n\", err, err, addr, MI_HUGE_OS_PAGE_SIZE);\n      break;\n    }\n\n    // Did we succeed at a contiguous address?\n    if (p != addr) {\n      // no success, issue a warning and break\n      if (p != NULL) {\n        _mi_warning_message(\"could not allocate contiguous huge OS page %zu at %p\\n\", page, addr);\n        mi_os_prim_free(p, MI_HUGE_OS_PAGE_SIZE, MI_HUGE_OS_PAGE_SIZE, NULL);\n      }\n      break;\n    }\n\n    // success, record it\n    page++;  // increase before timeout check (see issue #711)\n    mi_os_stat_increase(committed, MI_HUGE_OS_PAGE_SIZE);\n    mi_os_stat_increase(reserved, MI_HUGE_OS_PAGE_SIZE);\n\n    // check for timeout\n    if (max_msecs > 0) {\n      mi_msecs_t elapsed = _mi_clock_end(start_t);\n      if (page >= 1) {\n        mi_msecs_t estimate = ((elapsed / (page+1)) * pages);\n        if (estimate > 2*max_msecs) { // seems like we are going to timeout, break\n          elapsed = max_msecs + 1;\n        }\n      }\n      if (elapsed > max_msecs) {\n        _mi_warning_message(\"huge OS page allocation timed out (after allocating %zu page(s))\\n\", page);\n        break;\n      }\n    }\n  }\n  const size_t allocated = page * MI_HUGE_OS_PAGE_SIZE;\n  mi_assert_internal(allocated <= size);\n  if (pages_reserved != NULL) { *pages_reserved = page; }\n  if (psize != NULL) { *psize = allocated; }\n  if (page != 0) {\n    mi_assert(start != NULL);\n    *memid = _mi_memid_create_os(start, allocated, true /* is committed */, all_zero, true /* is_large */);\n    memid->memkind = MI_MEM_OS_HUGE;\n    mi_assert(memid->is_pinned);\n    #ifdef MI_TRACK_ASAN\n    if (all_zero) { mi_track_mem_defined(start,allocated); }\n    #endif\n  }\n  return (page == 0 ? NULL : start);\n}\n\n// free every huge page in a range individually (as we allocated per page)\n// note: needed with VirtualAlloc but could potentially be done in one go on mmap'd systems.\nstatic void mi_os_free_huge_os_pages(void* p, size_t size, mi_subproc_t* subproc) {\n  if (p==NULL || size==0) return;\n  uint8_t* base = (uint8_t*)p;\n  while (size >= MI_HUGE_OS_PAGE_SIZE) {\n    mi_os_prim_free(base, MI_HUGE_OS_PAGE_SIZE, MI_HUGE_OS_PAGE_SIZE, subproc);\n    size -= MI_HUGE_OS_PAGE_SIZE;\n    base += MI_HUGE_OS_PAGE_SIZE;\n  }\n}\n\n\n/* ----------------------------------------------------------------------------\nSupport NUMA aware allocation\n-----------------------------------------------------------------------------*/\n\nstatic _Atomic(size_t) mi_numa_node_count; // = 0   // cache the node count\n\nint _mi_os_numa_node_count(void) {\n  size_t count = mi_atomic_load_acquire(&mi_numa_node_count);\n  if mi_unlikely(count == 0) {\n    long ncount = mi_option_get(mi_option_use_numa_nodes); // given explicitly?\n    if (ncount > 0 && ncount < INT_MAX) {\n      count = (size_t)ncount;\n    }\n    else {\n      const size_t n = _mi_prim_numa_node_count(); // or detect dynamically\n      if (n == 0 || n > INT_MAX) { count = 1; }\n                            else { count = n; }\n    }\n    mi_atomic_store_release(&mi_numa_node_count, count); // save it\n    if (count>1) { _mi_verbose_message(\"using %zd numa regions\\n\", count); }\n  }\n  mi_assert_internal(count > 0 && count <= INT_MAX);\n  return (int)count;\n}\n\nstatic int mi_os_numa_node_get(void) {\n  int numa_count = _mi_os_numa_node_count();\n  if (numa_count<=1) return 0; // optimize on single numa node systems: always node 0\n  // never more than the node count and >= 0\n  const size_t n = _mi_prim_numa_node();\n  int numa_node = (n < INT_MAX ? (int)n : 0);\n  if (numa_node >= numa_count) { numa_node = numa_node % numa_count; }\n  return numa_node;\n}\n\nint _mi_os_numa_node(void) {\n  if mi_likely(mi_atomic_load_relaxed(&mi_numa_node_count) == 1) {\n    return 0;\n  }\n  else {\n    return mi_os_numa_node_get();\n  }\n}\n\n\n/* ----------------------------------------------------------------------------\n  Public API\n-----------------------------------------------------------------------------*/\n#if 0\nmi_decl_export void* mi_os_alloc(size_t size, bool commit, size_t* full_size) {\n  return mi_os_alloc_aligned(size, mi_os_mem_config.alloc_granularity, commit, NULL, full_size);\n}\n\nstatic void* mi_os_alloc_aligned_ex(size_t size, size_t alignment, bool commit, bool allow_large, bool* is_committed, bool* is_pinned, void** base, size_t* full_size) {\n  mi_memid_t memid = _mi_memid_none();\n  void* p = _mi_os_alloc_aligned(size, alignment, commit, allow_large, &memid);\n  if (p == NULL) return p;\n  if (is_committed != NULL) { *is_committed = memid.initially_committed;  }\n  if (is_pinned != NULL) { *is_pinned = memid.is_pinned;  }\n  if (base != NULL) { *base = memid.mem.os.base;  }\n  if (full_size != NULL) { *full_size = memid.mem.os.size;  }\n  if (!memid.initially_zero && memid.initially_committed) {\n    _mi_memzero_aligned(memid.mem.os.base, memid.mem.os.size);\n  }\n  return p;\n}\n\nmi_decl_export void* mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, void** base, size_t* full_size) {\n  return mi_os_alloc_aligned_ex(size, alignment, commit, false, NULL, NULL, base, full_size);\n}\n\nmi_decl_export void* mi_os_alloc_aligned_allow_large(size_t size, size_t alignment, bool commit, bool* is_committed, bool* is_pinned, void** base, size_t* full_size) {\n  return mi_os_alloc_aligned_ex(size, alignment, commit, true, is_committed, is_pinned, base, full_size);\n}\n\nmi_decl_export void  mi_os_free(void* p, size_t size) {\n  if (p==NULL || size == 0) return;\n  mi_memid_t memid = _mi_memid_create_os(p, size, true, false, false);\n  _mi_os_free(p, size, memid);\n}\n\nmi_decl_export void  mi_os_commit(void* p, size_t size) {\n  _mi_os_commit(p, size, NULL);\n}\n\nmi_decl_export void  mi_os_decommit(void* p, size_t size) {\n  _mi_os_decommit(p, size);\n}\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/page-map.c",
      "sha256": "1be3a208c678fc34187c2a8ffb75f3fe1eecc674bbf8b2af4d1f329506b1fad5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/*----------------------------------------------------------------------------\nCopyright (c) 2023-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"bitmap.h\"\n\nstatic void mi_page_map_cannot_commit(void) {\n  _mi_warning_message(\"unable to commit the allocation page-map on-demand\\n\" );\n}\n\n#if MI_PAGE_MAP_FLAT\n\n// The page-map contains a byte for each 64kb slice in the address space.\n// For an address `a` where `ofs = _mi_page_map[a >> 16]`:\n// 0 = unused\n// 1 = the slice at `a & ~0xFFFF` is a mimalloc page.\n// 1 < ofs <= 127 = the slice is part of a page, starting at `(((a>>16) - ofs - 1) << 16)`.\n//\n// 1 byte per slice => 1 TiB address space needs a 2^14 * 2^16 = 16 MiB page map.\n// A full 256 TiB address space (48 bit) needs a 4 GiB page map.\n// A full 4 GiB address space (32 bit) needs only a 64 KiB page map.\n\nmi_decl_cache_align uint8_t* _mi_page_map = NULL;\nstatic void*        mi_page_map_max_address = NULL;\nstatic mi_memid_t   mi_page_map_memid;\n\n#define MI_PAGE_MAP_ENTRIES_PER_COMMIT_BIT   MI_ARENA_SLICE_SIZE\nstatic mi_bitmap_t* mi_page_map_commit; // one bit per committed 64 KiB entries\n\nmi_decl_nodiscard static bool mi_page_map_ensure_committed(size_t idx, size_t slice_count);\n\nbool _mi_page_map_init(void) {\n  size_t vbits = (size_t)mi_option_get_clamp(mi_option_max_vabits, 0, MI_SIZE_BITS);\n  if (vbits == 0) {\n    vbits = _mi_os_virtual_address_bits();\n    #if MI_ARCH_X64  // canonical address is limited to the first 128 TiB\n    if (vbits >= 48) { vbits = 47; }\n    #endif\n  }\n  if (vbits < MI_ARENA_SLICE_SHIFT) {\n    vbits = MI_ARENA_SLICE_SHIFT;\n  }\n\n  // Allocate the page map and commit bits\n  mi_page_map_max_address = (void*)(vbits >= MI_SIZE_BITS ? (SIZE_MAX - MI_ARENA_SLICE_SIZE + 1) : (MI_PU(1) << vbits));\n  const size_t page_map_size = (MI_ZU(1) << (vbits - MI_ARENA_SLICE_SHIFT));\n  const bool commit = (page_map_size <= 1*MI_MiB || mi_option_is_enabled(mi_option_pagemap_commit)); // _mi_os_has_overcommit(); // commit on-access on Linux systems?\n  const size_t commit_bits = _mi_divide_up(page_map_size, MI_PAGE_MAP_ENTRIES_PER_COMMIT_BIT);\n  const size_t bitmap_size = (commit ? 0 : mi_bitmap_size(commit_bits, NULL));\n  const size_t reserve_size = bitmap_size + page_map_size;\n  uint8_t* const base = (uint8_t*)_mi_os_alloc_aligned(reserve_size, 1, commit, true /* allow large */, &mi_page_map_memid);\n  if (base==NULL) {\n    _mi_error_message(ENOMEM, \"unable to reserve virtual memory for the page map (%zu KiB)\\n\", page_map_size / MI_KiB);\n    return false;\n  }\n  if (mi_page_map_memid.initially_committed && !mi_page_map_memid.initially_zero) {\n    _mi_warning_message(\"internal: the page map was committed but not zero initialized!\\n\");\n    _mi_memzero_aligned(base, reserve_size);\n  }\n  if (bitmap_size > 0) {\n    mi_page_map_commit = (mi_bitmap_t*)base;\n    if (!_mi_os_commit(mi_page_map_commit, bitmap_size, NULL)) {\n      mi_page_map_cannot_commit();\n      return false;\n    }\n    mi_bitmap_init(mi_page_map_commit, commit_bits, true);\n  }\n  _mi_page_map = base + bitmap_size;\n\n  // commit the first part so NULL pointers get resolved without an access violation\n  if (!commit) {\n    if (!mi_page_map_ensure_committed(0, 1)) {\n      mi_page_map_cannot_commit();\n      return false;\n    }\n  }\n  _mi_page_map[0] = 1; // so _mi_ptr_page(NULL) == NULL\n  mi_assert_internal(_mi_ptr_page(NULL)==NULL);\n  return true;\n}\n\nvoid _mi_page_map_unsafe_destroy(mi_subproc_t* subproc) {\n  mi_assert_internal(subproc != NULL);\n  mi_assert_internal(_mi_page_map != NULL);\n  if (_mi_page_map == NULL) return;\n  _mi_os_free_ex(mi_page_map_memid.mem.os.base, mi_page_map_memid.mem.os.size, true, mi_page_map_memid, subproc);\n  _mi_page_map = NULL;\n  mi_page_map_commit = NULL;\n  mi_page_map_max_address = NULL;\n  mi_page_map_memid = _mi_memid_none();\n}\n\n\nstatic bool mi_page_map_ensure_committed(size_t idx, size_t slice_count) {\n  // is the page map area that contains the page address committed?\n  // we always set the commit bits so we can track what ranges are in-use.\n  // we only actually commit if the map wasn't committed fully already.\n  if (mi_page_map_commit != NULL) {\n    const size_t commit_idx = idx / MI_PAGE_MAP_ENTRIES_PER_COMMIT_BIT;\n    const size_t commit_idx_hi = (idx + slice_count - 1) / MI_PAGE_MAP_ENTRIES_PER_COMMIT_BIT;\n    for (size_t i = commit_idx; i <= commit_idx_hi; i++) {  // per bit to avoid crossing over bitmap chunks\n      if (mi_bitmap_is_clear(mi_page_map_commit, i)) {\n        // this may race, in which case we do multiple commits (which is ok)\n        bool is_zero;\n        uint8_t* const start = _mi_page_map + (i * MI_PAGE_MAP_ENTRIES_PER_COMMIT_BIT);\n        const size_t   size  = MI_PAGE_MAP_ENTRIES_PER_COMMIT_BIT;\n        if (!_mi_os_commit(start, size, &is_zero)) {\n          mi_page_map_cannot_commit();\n          return false;\n        }\n        if (!is_zero && !mi_page_map_memid.initially_zero) { _mi_memzero(start, size); }\n        mi_bitmap_set(mi_page_map_commit, i);\n      }\n    }\n  }\n  #if MI_DEBUG > 0\n  _mi_page_map[idx] = 0;\n  _mi_page_map[idx+slice_count-1] = 0;\n  #endif\n  return true;\n}\n\n\nstatic size_t mi_page_map_get_idx(mi_page_t* page, uint8_t** page_start, size_t* slice_count) {\n  size_t page_size;\n  *page_start = mi_page_area(page, &page_size);\n  if (page_size > MI_LARGE_PAGE_SIZE) { page_size = MI_LARGE_PAGE_SIZE - MI_ARENA_SLICE_SIZE; }  // furthest interior pointer\n  *slice_count = mi_slice_count_of_size(page_size) + ((*page_start - mi_page_slice_start(page))/MI_ARENA_SLICE_SIZE); // add for large aligned blocks\n  return _mi_page_map_index(page);\n}\n\nbool _mi_page_map_register(mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n  mi_assert_internal(_mi_page_map != NULL);  // should be initialized before multi-thread access!\n  if mi_unlikely(_mi_page_map == NULL) {\n    if (!_mi_page_map_init()) return false;\n  }\n  mi_assert(_mi_page_map!=NULL);\n  uint8_t* page_start;\n  size_t   slice_count;\n  const size_t idx = mi_page_map_get_idx(page, &page_start, &slice_count);\n\n  if (!mi_page_map_ensure_committed(idx, slice_count)) {\n    return false;\n  }\n\n  // set the offsets\n  for (size_t i = 0; i < slice_count; i++) {\n    mi_assert_internal(i < 128);\n    _mi_page_map[idx + i] = (uint8_t)(i+1);\n  }\n  return true;\n}\n\nvoid _mi_page_map_unregister(mi_page_t* page) {\n  mi_assert_internal(_mi_page_map != NULL);\n  // get index and count\n  uint8_t* page_start;\n  size_t   slice_count;\n  const size_t idx = mi_page_map_get_idx(page, &page_start, &slice_count);\n  // unset the offsets\n  _mi_memzero(_mi_page_map + idx, slice_count);\n}\n\nvoid _mi_page_map_unregister_range(void* start, size_t size) {\n  const size_t slice_count = _mi_divide_up(size, MI_ARENA_SLICE_SIZE);\n  const uintptr_t index = _mi_page_map_index(start);\n  // todo: scan the commit bits and clear only those ranges?\n  if (!mi_page_map_ensure_committed(index, slice_count)) { // we commit the range in total;\n    return;\n  }\n  _mi_memzero(&_mi_page_map[index], slice_count);\n}\n\n\nmi_page_t* _mi_safe_ptr_page(const void* p) {\n  if mi_unlikely(p >= mi_page_map_max_address) return NULL;\n  const uintptr_t idx = _mi_page_map_index(p);\n  if mi_unlikely(mi_page_map_commit != NULL && !mi_bitmap_is_set(mi_page_map_commit, idx/MI_PAGE_MAP_ENTRIES_PER_COMMIT_BIT)) return NULL;\n  const uintptr_t ofs = _mi_page_map[idx];\n  if mi_unlikely(ofs == 0) return NULL;\n  return (mi_page_t*)((((uintptr_t)p >> MI_ARENA_SLICE_SHIFT) - ofs + 1) << MI_ARENA_SLICE_SHIFT);\n}\n\nmi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept {\n  return (_mi_safe_ptr_page(p) != NULL);\n}\n\n#else\n\n// A 2-level page map\n#define MI_PAGE_MAP_SUB_SIZE          (MI_PAGE_MAP_SUB_COUNT * sizeof(mi_page_t*))\n#define MI_PAGE_MAP_ENTRIES_PER_CBIT  (MI_PAGE_MAP_COUNT < MI_BFIELD_BITS ? 1 : (MI_PAGE_MAP_COUNT / MI_BFIELD_BITS))\n\nmi_decl_cache_align _Atomic(mi_submap_t)* _mi_page_map;\nstatic size_t       mi_page_map_count;\nstatic void*        mi_page_map_max_address;\nstatic mi_memid_t   mi_page_map_memid;\nstatic mi_lock_t    mi_page_map_lock;\n\n// divide the main map in 64 (`MI_BFIELD_BITS`) parts commit those parts on demand\nstatic _Atomic(mi_bfield_t)  mi_page_map_commit;\n\nmi_decl_nodiscard static inline bool mi_page_map_is_committed(size_t idx, size_t* pbit_idx) {\n  mi_bfield_t commit = mi_atomic_load_relaxed(&mi_page_map_commit);\n  const size_t bit_idx = idx/MI_PAGE_MAP_ENTRIES_PER_CBIT;\n  mi_assert_internal(bit_idx < MI_BFIELD_BITS);\n  if (pbit_idx != NULL) { *pbit_idx = bit_idx; }\n  return ((commit & (MI_ZU(1) << bit_idx)) != 0);\n}\n\nmi_decl_nodiscard static bool mi_page_map_ensure_committed(size_t idx, mi_submap_t* submap) {\n  mi_assert_internal(submap!=NULL && *submap==NULL);\n  size_t bit_idx;\n  if mi_unlikely(!mi_page_map_is_committed(idx, &bit_idx)) {\n    uint8_t* start = (uint8_t*)&_mi_page_map[bit_idx * MI_PAGE_MAP_ENTRIES_PER_CBIT];\n    if (!_mi_os_commit(start, MI_PAGE_MAP_ENTRIES_PER_CBIT * sizeof(mi_submap_t), NULL)) {\n      mi_page_map_cannot_commit();\n      return false;\n    }\n    mi_atomic_or_acq_rel(&mi_page_map_commit, MI_ZU(1) << bit_idx);\n  }\n  *submap = mi_atomic_load_ptr_acquire(mi_page_t*, &_mi_page_map[idx]); // acquire _mi_page_map_at(idx);\n  return true;\n}\n\n// initialize the page map\nbool _mi_page_map_init(void) {\n  size_t vbits = (size_t)mi_option_get_clamp(mi_option_max_vabits, 0, MI_SIZE_BITS);\n  if (vbits == 0) {\n    vbits = _mi_os_virtual_address_bits();\n    #if MI_ARCH_X64  // canonical address is limited to the first 128 TiB\n    if (vbits >= 48) { vbits = 47; }\n    #endif\n  }\n  if (vbits < MI_PAGE_MAP_SUB_SHIFT + MI_ARENA_SLICE_SHIFT) {\n    vbits = MI_PAGE_MAP_SUB_SHIFT + MI_ARENA_SLICE_SHIFT;\n  }\n\n  // Allocate the page map and commit bits\n  mi_assert(MI_MAX_VABITS >= vbits);\n  mi_page_map_max_address = (void*)(vbits >= MI_SIZE_BITS ? (SIZE_MAX - MI_ARENA_SLICE_SIZE + 1) : (MI_PU(1) << vbits));\n  mi_page_map_count = (MI_ZU(1) << (vbits - MI_PAGE_MAP_SUB_SHIFT - MI_ARENA_SLICE_SHIFT));\n  mi_assert(mi_page_map_count <= MI_PAGE_MAP_COUNT);\n  const size_t os_page_size = _mi_os_page_size();\n  const size_t page_map_size = _mi_align_up( mi_page_map_count * sizeof(mi_page_t**), os_page_size);\n  const size_t submap_size = MI_PAGE_MAP_SUB_SIZE;\n  const size_t reserve_size = page_map_size + submap_size;\n  #if MI_SECURE\n  const bool commit = true;  // the whole page map is valid and we can reliably check any pointer\n  #else\n  const bool commit = page_map_size <= 64*MI_KiB ||\n                      mi_option_is_enabled(mi_option_pagemap_commit) || _mi_os_has_overcommit();\n  #endif\n  _mi_page_map = (_Atomic(mi_page_t**)*)_mi_os_alloc_aligned(reserve_size, 1, commit, true /* allow large */, &mi_page_map_memid);\n  if (_mi_page_map==NULL) {\n    _mi_error_message(ENOMEM, \"unable to reserve virtual memory for the page map (%zu KiB)\\n\", page_map_size / MI_KiB);\n    return false;\n  }\n  if (mi_page_map_memid.initially_committed && !mi_page_map_memid.initially_zero) {\n    _mi_warning_message(\"internal: the page map was committed but not zero initialized!\\n\");\n    _mi_memzero_aligned(_mi_page_map, page_map_size);\n  }\n  mi_atomic_store_release(&mi_page_map_commit, (mi_page_map_memid.initially_committed ? ~MI_ZU(0) : MI_ZU(0)));\n\n  // ensure there is a submap for the NULL address\n  mi_page_t** const sub0 = (mi_page_t**)((uint8_t*)_mi_page_map + page_map_size);  // we reserved a submap part at the end already\n  if (!mi_page_map_memid.initially_committed) {\n    if (!_mi_os_commit(sub0, submap_size, NULL)) {  // commit full submap (issue #1087)\n      mi_page_map_cannot_commit();\n      return false;\n    }\n  }\n  if (!mi_page_map_memid.initially_zero) {     // initialize low addresses with NULL\n    _mi_memzero_aligned(sub0, submap_size);\n  }\n  mi_submap_t nullsub = NULL;\n  if (!mi_page_map_ensure_committed(0,&nullsub)) {\n    mi_page_map_cannot_commit();\n    return false;\n  }\n  mi_atomic_store_ptr_release(mi_page_t*, &_mi_page_map[0], sub0);\n  mi_lock_init(&mi_page_map_lock);             // initialize late in case the lock init causes allocation\n  \n  mi_assert_internal(_mi_ptr_page(NULL)==NULL);\n  return true;\n}\n\n\nvoid _mi_page_map_unsafe_destroy(mi_subproc_t* subproc) {\n  mi_assert_internal(subproc != NULL);\n  mi_assert_internal(_mi_page_map != NULL);\n  if (_mi_page_map == NULL) return;\n  mi_lock_done(&mi_page_map_lock);  \n  for (size_t idx = 1; idx < mi_page_map_count; idx++) {  // skip entry 0 (as we allocate that submap at the end of the page_map)\n    // free all sub-maps\n    if (mi_page_map_is_committed(idx, NULL)) {\n      mi_submap_t sub = _mi_page_map_at(idx);\n      if (sub != NULL) {\n        mi_memid_t memid = _mi_memid_create_os(sub, MI_PAGE_MAP_SUB_SIZE, true, false, false);\n        _mi_os_free_ex(memid.mem.os.base, memid.mem.os.size, true, memid, subproc);\n        mi_atomic_store_ptr_release(mi_page_t*, &_mi_page_map[idx], NULL);\n      }\n    }\n  }\n  _mi_os_free_ex(_mi_page_map, mi_page_map_memid.mem.os.size, true, mi_page_map_memid, subproc);\n  _mi_page_map = NULL;\n  mi_page_map_count = 0;\n  mi_page_map_memid = _mi_memid_none();\n  mi_page_map_max_address = NULL;\n  mi_atomic_store_release(&mi_page_map_commit, (mi_bfield_t)0);\n}\n\n\nmi_decl_nodiscard static bool mi_page_map_ensure_submap_at(size_t idx, mi_submap_t* submap) {\n  mi_assert_internal(submap!=NULL && *submap==NULL);\n  mi_submap_t sub = NULL;\n  if (!mi_page_map_ensure_committed(idx, &sub)) {\n    return false;\n  }\n  if mi_unlikely(sub == NULL) {\n    // sub map not yet allocated, alloc now\n    mi_lock(&mi_page_map_lock) \n    {\n      sub = mi_atomic_load_ptr_acquire(mi_page_t*, &_mi_page_map[idx]); // reload\n      if (sub==NULL) // not yet allocated by another thread?      \n      {\n        mi_memid_t memid;\n        const size_t submap_size = MI_PAGE_MAP_SUB_SIZE;\n        sub = (mi_submap_t)_mi_os_zalloc(submap_size, &memid);        \n        if (sub==NULL) {\n          _mi_warning_message(\"internal error: unable to extend the page map\\n\");          \n        }\n        else {\n          mi_submap_t expect = NULL;\n          if (!mi_atomic_cas_ptr_strong_acq_rel(mi_page_t*, &_mi_page_map[idx], &expect, sub)) {\n            // another thread already allocated it.. free and continue\n            _mi_os_free(sub, submap_size, memid);\n            sub = expect;\n          }\n        }\n      }\n    }\n    if (sub==NULL) return false; // unable to allocate the submap..\n  }\n  mi_assert_internal(sub!=NULL);\n  *submap = sub;\n  return true;\n}\n\nstatic bool mi_page_map_set_range_prim(mi_page_t* page, size_t idx, size_t sub_idx, size_t slice_count) {\n  // is the page map area that contains the page address committed?\n  while (slice_count > 0) {\n    mi_submap_t sub = NULL;\n    if (!mi_page_map_ensure_submap_at(idx, &sub)) {\n      return false;\n    };\n    mi_assert_internal(sub!=NULL);\n    // set the offsets for the page\n    while (slice_count > 0 && sub_idx < MI_PAGE_MAP_SUB_COUNT) {\n      sub[sub_idx] = page;\n      slice_count--;\n      sub_idx++;\n    }\n    idx++; // potentially wrap around to the next idx\n    sub_idx = 0;\n  }\n  return true;\n}\n\nstatic bool mi_page_map_set_range(mi_page_t* page, size_t idx, size_t sub_idx, size_t slice_count) {\n  if mi_unlikely(!mi_page_map_set_range_prim(page,idx,sub_idx,slice_count)) {\n    // failed to commit, call again to reset the page pointer if needed\n    if (page!=NULL) {\n      mi_page_map_set_range_prim(NULL,idx,sub_idx,slice_count);\n    }\n    return false;\n  }\n  return true;\n}\n\nstatic size_t mi_page_map_get_idx(mi_page_t* page, size_t* sub_idx, size_t* slice_count) {\n  size_t page_size;\n  uint8_t* page_start = mi_page_area(page, &page_size);\n  if (page_size > MI_LARGE_PAGE_SIZE) { page_size = MI_LARGE_PAGE_SIZE - MI_ARENA_SLICE_SIZE; }  // furthest interior pointer\n  *slice_count = mi_slice_count_of_size(page_size) + ((page_start - mi_page_slice_start(page))/MI_ARENA_SLICE_SIZE); // add for large aligned blocks\n  return _mi_page_map_index(page_start, sub_idx);\n}\n\nbool _mi_page_map_register(mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n  mi_assert_internal(_mi_page_map != NULL);  // should be initialized before multi-thread access!\n  if mi_unlikely(_mi_page_map == NULL) {\n    if (!_mi_page_map_init()) return false;\n  }\n  mi_assert(_mi_page_map!=NULL);\n  size_t   slice_count;\n  size_t   sub_idx;\n  const size_t idx = mi_page_map_get_idx(page, &sub_idx, &slice_count);\n  return mi_page_map_set_range(page, idx, sub_idx, slice_count);\n}\n\nvoid _mi_page_map_unregister(mi_page_t* page) {\n  mi_assert_internal(_mi_page_map != NULL);\n  mi_assert_internal(page != NULL);\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n  if mi_unlikely(_mi_page_map == NULL) return;\n  // get index and count\n  size_t slice_count;\n  size_t sub_idx;\n  const size_t idx = mi_page_map_get_idx(page, &sub_idx, &slice_count);\n  // unset the offsets\n  mi_page_map_set_range(NULL, idx, sub_idx, slice_count);\n}\n\nvoid _mi_page_map_unregister_range(void* start, size_t size) {\n  if mi_unlikely(_mi_page_map == NULL) return;\n  const size_t slice_count = _mi_divide_up(size, MI_ARENA_SLICE_SIZE);\n  size_t sub_idx;\n  const uintptr_t idx = _mi_page_map_index(start, &sub_idx);\n  mi_page_map_set_range(NULL, idx, sub_idx, slice_count);  // todo: avoid committing if not already committed?\n}\n\n// Return NULL for invalid pointers\nmi_page_t* _mi_safe_ptr_page(const void* p) {\n  if (p==NULL) return NULL;\n  if mi_unlikely(p >= mi_page_map_max_address) return NULL;\n  size_t sub_idx;\n  const size_t idx = _mi_page_map_index(p,&sub_idx);\n  if mi_unlikely(!mi_page_map_is_committed(idx,NULL)) return NULL;\n  mi_page_t** const sub = _mi_page_map[idx];\n  if mi_unlikely(sub==NULL) return NULL;\n  return sub[sub_idx];\n}\n\nmi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept {\n  return (_mi_safe_ptr_page(p) != NULL);\n}\n\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/page-queue.c",
      "sha256": "7ec275805c9f00eb66710ffa99817b3ed1dba9826435d08f4866f7935152f6ae",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/*----------------------------------------------------------------------------\nCopyright (c) 2018-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* -----------------------------------------------------------\n  Definition of page queues for each block size\n----------------------------------------------------------- */\n\n#ifndef MI_IN_PAGE_C\n#error \"this file should be included from 'page.c'\"\n// include to help an IDE\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#endif\n\n/* -----------------------------------------------------------\n  Minimal alignment in machine words (i.e. `sizeof(void*)`)\n----------------------------------------------------------- */\n\n#if (MI_MAX_ALIGN_SIZE > 4*MI_INTPTR_SIZE)\n  #error \"define alignment for more than 4x word size for this platform\"\n#elif (MI_MAX_ALIGN_SIZE > 2*MI_INTPTR_SIZE)\n  #define MI_ALIGN4W   // 4 machine words minimal alignment\n#elif (MI_MAX_ALIGN_SIZE > MI_INTPTR_SIZE)\n  #define MI_ALIGN2W   // 2 machine words minimal alignment\n#else\n  // ok, default alignment is 1 word\n#endif\n\n\n/* -----------------------------------------------------------\n  Queue query\n----------------------------------------------------------- */\n\n\nstatic inline bool mi_page_queue_is_huge(const mi_page_queue_t* pq) {\n  return (pq->block_size == (MI_LARGE_MAX_OBJ_SIZE+sizeof(uintptr_t)));\n}\n\nstatic inline bool mi_page_queue_is_full(const mi_page_queue_t* pq) {\n  return (pq->block_size == (MI_LARGE_MAX_OBJ_SIZE+(2*sizeof(uintptr_t))));\n}\n\nstatic inline bool mi_page_queue_is_special(const mi_page_queue_t* pq) {\n  return (pq->block_size > MI_LARGE_MAX_OBJ_SIZE);\n}\n\nstatic inline size_t mi_page_queue_count(const mi_page_queue_t* pq) {\n  return pq->count;\n}\n\n/* -----------------------------------------------------------\n  Bins\n----------------------------------------------------------- */\n\n// Return the bin for a given field size.\n// Returns MI_BIN_HUGE if the size is too large.\n// We use `wsize` for the size in \"machine word sizes\",\n// i.e. byte size == `wsize*sizeof(void*)`.\nstatic mi_decl_noinline size_t mi_bin(size_t size) {\n  size_t wsize = _mi_wsize_from_size(size);\n#if defined(MI_ALIGN4W)\n  if mi_likely(wsize <= 4) {\n    return (wsize <= 1 ? 1 : (wsize+1)&~1); // round to double word sizes\n  }\n#elif defined(MI_ALIGN2W)\n  if mi_likely(wsize <= 8) {\n    return (wsize <= 1 ? 1 : (wsize+1)&~1); // round to double word sizes\n  }\n#else\n  if mi_likely(wsize <= 8) {\n    return (wsize == 0 ? 1 : wsize);\n  }\n#endif\n  else if mi_unlikely(wsize > MI_LARGE_MAX_OBJ_WSIZE) {\n    return MI_BIN_HUGE;\n  }\n  else {\n    #if defined(MI_ALIGN4W)\n    if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes\n    #endif\n    wsize--;\n    // find the highest bit\n    const size_t b = (MI_SIZE_BITS - 1 - mi_clz(wsize));  // note: wsize != 0\n    // and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).\n    // - adjust with 3 because we use do not round the first 8 sizes\n    //   which each get an exact bin\n    const size_t bin = ((b << 2) + ((wsize >> (b - 2)) & 0x03)) - 3;\n    mi_assert_internal(bin > 0 && bin < MI_BIN_HUGE);\n    return bin;\n  }\n}\n\n\n\n/* -----------------------------------------------------------\n  Queue of pages with free blocks\n----------------------------------------------------------- */\n\nsize_t _mi_bin(size_t size) {\n  return mi_bin(size);\n}\n\nsize_t _mi_bin_size(size_t bin) {\n  mi_assert_internal(bin <= MI_BIN_HUGE);\n  return _mi_theap_empty.pages[bin].block_size;\n}\n\n// Good size for allocation\nmi_decl_nodiscard mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept {\n  if (size <= MI_LARGE_MAX_OBJ_SIZE) {\n    return _mi_bin_size(mi_bin(size + MI_PADDING_SIZE));\n  }\n  else if (size <= MI_MAX_ALLOC_SIZE) {\n    return _mi_align_up(size + MI_PADDING_SIZE,_mi_os_page_size());\n  }\n  else {\n    return size;\n  }\n}\n\n#if (MI_DEBUG>1)\nstatic bool mi_page_queue_contains(mi_page_queue_t* queue, const mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_page_t* list = queue->first;\n  while (list != NULL) {\n    mi_assert_internal(list->next == NULL || list->next->prev == list);\n    mi_assert_internal(list->prev == NULL || list->prev->next == list);\n    if (list == page) break;\n    list = list->next;\n  }\n  return (list == page);\n}\n\n#endif\n\n#if (MI_DEBUG>1)\nstatic bool mi_theap_contains_queue(const mi_theap_t* theap, const mi_page_queue_t* pq) {\n  return (pq >= &theap->pages[0] && pq <= &theap->pages[MI_BIN_FULL]);\n}\n#endif\n\nbool _mi_page_queue_is_valid(mi_theap_t* theap, const mi_page_queue_t* pq) {\n  MI_UNUSED_RELEASE(theap);\n  if (pq==NULL) return false;\n  size_t count = 0; MI_UNUSED_RELEASE(count);\n  mi_page_t* prev = NULL; MI_UNUSED_RELEASE(prev);\n  for (mi_page_t* page = pq->first; page != NULL; page = page->next) {\n    mi_assert_internal(page->prev == prev);\n    if (mi_page_is_in_full(page)) {\n      mi_assert_internal(_mi_wsize_from_size(pq->block_size) == MI_LARGE_MAX_OBJ_WSIZE + 2);\n    }\n    else if (mi_page_is_huge(page)) {\n      mi_assert_internal(_mi_wsize_from_size(pq->block_size) == MI_LARGE_MAX_OBJ_WSIZE + 1);\n    }\n    else {\n      mi_assert_internal(mi_page_block_size(page) == pq->block_size);\n    }\n    mi_assert_internal(page->theap == theap);\n    if (page->next == NULL) {\n      mi_assert_internal(pq->last == page);\n    }\n    count++;\n    prev = page;\n  }\n  mi_assert_internal(pq->count == count);\n  return true;\n}\n\nstatic size_t mi_page_bin(const mi_page_t* page) {\n  const size_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : (mi_page_is_huge(page) ? MI_BIN_HUGE : mi_bin(mi_page_block_size(page))));\n  mi_assert_internal(bin <= MI_BIN_FULL);\n  return bin;\n}\n\n// returns the page bin without using MI_BIN_FULL for statistics\nsize_t _mi_page_stats_bin(const mi_page_t* page) {\n  const size_t bin = (mi_page_is_huge(page) ? MI_BIN_HUGE : mi_bin(mi_page_block_size(page)));\n  mi_assert_internal(bin <= MI_BIN_HUGE);\n  return bin;\n}\n\nstatic mi_page_queue_t* mi_theap_page_queue_of(mi_theap_t* theap, const mi_page_t* page) {\n  mi_assert_internal(theap!=NULL);\n  const size_t bin = mi_page_bin(page);\n  mi_page_queue_t* pq = &theap->pages[bin];\n  mi_assert_internal((mi_page_block_size(page) == pq->block_size) ||\n                       (mi_page_is_huge(page) && mi_page_queue_is_huge(pq)) ||\n                         (mi_page_is_in_full(page) && mi_page_queue_is_full(pq)));\n  return pq;\n}\n\nstatic mi_page_queue_t* mi_page_queue_of(const mi_page_t* page) {\n  mi_theap_t* theap = mi_page_theap(page);\n  mi_page_queue_t* pq = mi_theap_page_queue_of(theap, page);\n  mi_assert_expensive(mi_page_queue_contains(pq, page));\n  return pq;\n}\n\n// The current small page array is for efficiency and for each\n// small size (up to 256) it points directly to the page for that\n// size without having to compute the bin. This means when the\n// current free page queue is updated for a small bin, we need to update a\n// range of entries in `_mi_page_small_free`.\nstatic inline void mi_theap_queue_first_update(mi_theap_t* theap, const mi_page_queue_t* pq) {\n  mi_assert_internal(mi_theap_contains_queue(theap,pq));\n  const size_t size = pq->block_size;\n  if (size > MI_SMALL_SIZE_MAX) return;\n\n  mi_page_t* page = pq->first;\n  if (pq->first == NULL) page = (mi_page_t*)&_mi_page_empty;\n\n  // find index in the right direct page array\n  const size_t idx = _mi_wsize_from_size(size);\n  mi_page_t** const pages_free = theap->pages_free_direct;\n  if (pages_free[idx] == page) return;  // already set\n\n  // find start slot\n  size_t start;\n  if (idx<=1) {\n    start = 0;\n  }\n  else {\n    // find previous size; due to minimal alignment upto 3 previous bins may need to be skipped\n    mi_assert_internal(pq > &theap->pages[0]); // since idx > 1    \n    size_t bin = mi_bin(size);\n    const mi_page_queue_t* prev = pq - 1;\n    while( bin == mi_bin(prev->block_size) && prev > &theap->pages[0]) {\n      prev--;\n    }\n    start = 1 + _mi_wsize_from_size(prev->block_size);\n    if (start > idx) start = idx;\n  }\n\n  // set size range to the right page\n  mi_assert(start <= idx);\n  for (size_t sz = start; sz <= idx; sz++) {\n    pages_free[sz] = page;\n  }\n}\n\n/*\nstatic bool mi_page_queue_is_empty(mi_page_queue_t* queue) {\n  return (queue->first == NULL);\n}\n*/\n\nstatic void mi_page_queue_remove(mi_page_queue_t* queue, mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_assert_expensive(mi_page_queue_contains(queue, page));\n  mi_assert_internal(queue->count >= 1);\n  mi_assert_internal(mi_page_block_size(page) == queue->block_size ||\n                      (mi_page_is_huge(page) && mi_page_queue_is_huge(queue)) ||\n                        (mi_page_is_in_full(page) && mi_page_queue_is_full(queue)));\n  mi_theap_t* theap = mi_page_theap(page);\n  if (page->prev != NULL) page->prev->next = page->next;\n  if (page->next != NULL) page->next->prev = page->prev;\n  if (page == queue->last)  queue->last = page->prev;\n  if (page == queue->first) {\n    queue->first = page->next;\n    // update first\n    mi_assert_internal(mi_theap_contains_queue(theap, queue));\n    mi_theap_queue_first_update(theap,queue);\n  }\n  theap->page_count--;\n  queue->count--;\n  page->next = NULL;\n  page->prev = NULL;\n  mi_page_set_in_full(page,false);\n}\n\n\nstatic void mi_page_queue_push(mi_theap_t* theap, mi_page_queue_t* queue, mi_page_t* page) {\n  mi_assert_internal(mi_page_theap(page) == theap);\n  mi_assert_internal(!mi_page_queue_contains(queue, page));\n  #if MI_HUGE_PAGE_ABANDON\n  mi_assert_internal(_mi_page_segment(page)->page_kind != MI_PAGE_HUGE);\n  #endif\n  mi_assert_internal(mi_page_block_size(page) == queue->block_size ||\n                      (mi_page_is_huge(page) && mi_page_queue_is_huge(queue)) ||\n                        (mi_page_is_in_full(page) && mi_page_queue_is_full(queue)));\n\n  mi_page_set_in_full(page, mi_page_queue_is_full(queue));\n\n  page->next = queue->first;\n  page->prev = NULL;\n  if (queue->first != NULL) {\n    mi_assert_internal(queue->first->prev == NULL);\n    queue->first->prev = page;\n    queue->first = page;\n  }\n  else {\n    queue->first = queue->last = page;\n  }\n  queue->count++;\n\n  // update direct\n  mi_theap_queue_first_update(theap, queue);\n  theap->page_count++;\n}\n\nstatic void mi_page_queue_push_at_end(mi_theap_t* theap, mi_page_queue_t* queue, mi_page_t* page) {\n  mi_assert_internal(mi_page_theap(page) == theap);\n  mi_assert_internal(!mi_page_queue_contains(queue, page));\n\n  mi_assert_internal(mi_page_block_size(page) == queue->block_size ||\n                      (mi_page_is_huge(page) && mi_page_queue_is_huge(queue)) ||\n                       (mi_page_is_in_full(page) && mi_page_queue_is_full(queue)));\n\n  mi_page_set_in_full(page, mi_page_queue_is_full(queue));\n\n  page->prev = queue->last;\n  page->next = NULL;\n  if (queue->last != NULL) {\n    mi_assert_internal(queue->last->next == NULL);\n    queue->last->next = page;\n    queue->last = page;\n  }\n  else {\n    queue->first = queue->last = page;\n  }\n  queue->count++;\n\n  // update direct\n  if (queue->first == page) {\n    mi_theap_queue_first_update(theap, queue);\n  }\n  theap->page_count++;\n}\n\nstatic void mi_page_queue_move_to_front(mi_theap_t* theap, mi_page_queue_t* queue, mi_page_t* page) {\n  mi_assert_internal(mi_page_theap(page) == theap);\n  mi_assert_internal(mi_page_queue_contains(queue, page));\n  if (queue->first == page) return;\n  mi_page_queue_remove(queue, page);\n  mi_page_queue_push(theap, queue, page);\n  mi_assert_internal(queue->first == page);\n}\n\nstatic void mi_page_queue_enqueue_from_ex(mi_page_queue_t* to, mi_page_queue_t* from, bool enqueue_at_end, mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_assert_internal(from->count >= 1);\n  mi_assert_expensive(mi_page_queue_contains(from, page));\n  mi_assert_expensive(!mi_page_queue_contains(to, page));\n  const size_t bsize = mi_page_block_size(page);\n  MI_UNUSED(bsize);\n  mi_assert_internal((bsize == to->block_size && bsize == from->block_size) ||\n                     (bsize == to->block_size && mi_page_queue_is_full(from)) ||\n                     (bsize == from->block_size && mi_page_queue_is_full(to)) ||\n                     (mi_page_is_huge(page) && mi_page_queue_is_huge(to)) ||\n                     (mi_page_is_huge(page) && mi_page_queue_is_full(to)));\n\n  mi_theap_t* theap = mi_page_theap(page);\n\n  // delete from `from`\n  if (page->prev != NULL) page->prev->next = page->next;\n  if (page->next != NULL) page->next->prev = page->prev;\n  if (page == from->last)  from->last = page->prev;\n  if (page == from->first) {\n    from->first = page->next;\n    // update first\n    mi_assert_internal(mi_theap_contains_queue(theap, from));\n    mi_theap_queue_first_update(theap, from);\n  }\n  from->count--;\n\n  // insert into `to`\n  to->count++;\n  if (enqueue_at_end) {\n    // enqueue at the end\n    page->prev = to->last;\n    page->next = NULL;\n    if (to->last != NULL) {\n      mi_assert_internal(theap == mi_page_theap(to->last));\n      to->last->next = page;\n      to->last = page;\n    }\n    else {\n      to->first = page;\n      to->last = page;\n      mi_theap_queue_first_update(theap, to);\n    }\n  }\n  else {\n    if (to->first != NULL) {\n      // enqueue at 2nd place\n      mi_assert_internal(theap == mi_page_theap(to->first));\n      mi_page_t* next = to->first->next;\n      page->prev = to->first;\n      page->next = next;\n      to->first->next = page;\n      if (next != NULL) {\n        next->prev = page;\n      }\n      else {\n        to->last = page;\n      }\n    }\n    else {\n      // enqueue at the head (singleton list)\n      page->prev = NULL;\n      page->next = NULL;\n      to->first = page;\n      to->last = page;\n      mi_theap_queue_first_update(theap, to);\n    }\n  }\n\n  mi_page_set_in_full(page, mi_page_queue_is_full(to));\n}\n\nstatic void mi_page_queue_enqueue_from(mi_page_queue_t* to, mi_page_queue_t* from, mi_page_t* page) {\n  mi_page_queue_enqueue_from_ex(to, from, true /* enqueue at the end */, page);\n}\n\nstatic void mi_page_queue_enqueue_from_full(mi_page_queue_t* to, mi_page_queue_t* from, mi_page_t* page) {\n  // note: we could insert at the front to increase reuse, but it slows down certain benchmarks (like `alloc-test`)\n  mi_page_queue_enqueue_from_ex(to, from, true /* enqueue at the end of the `to` queue? */, page);\n}\n\n// Only called from `mi_theap_absorb`.\nsize_t _mi_page_queue_append(mi_theap_t* theap, mi_page_queue_t* pq, mi_page_queue_t* append) {\n  mi_assert_internal(mi_theap_contains_queue(theap,pq));\n  mi_assert_internal(pq->block_size == append->block_size);\n\n  if (append->first==NULL) return 0;\n\n  // set append pages to new theap and count\n  size_t count = 0;\n  for (mi_page_t* page = append->first; page != NULL; page = page->next) {\n    mi_page_set_theap(page, theap);\n    count++;\n  }\n  mi_assert_internal(count == append->count);\n\n  if (pq->last==NULL) {\n    // take over afresh\n    mi_assert_internal(pq->first==NULL);\n    pq->first = append->first;\n    pq->last = append->last;\n    mi_theap_queue_first_update(theap, pq);\n  }\n  else {\n    // append to end\n    mi_assert_internal(pq->last!=NULL);\n    mi_assert_internal(append->first!=NULL);\n    pq->last->next = append->first;\n    append->first->prev = pq->last;\n    pq->last = append->last;\n  }\n  pq->count += append->count;\n\n  return count;\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/page.c",
      "sha256": "d3614a59f2407a32e75b051deb1aff31b233f587d325dcc5420ba508551b687e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/*----------------------------------------------------------------------------\nCopyright (c) 2018-2024, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* -----------------------------------------------------------\n  The core of the allocator. Every segment contains\n  pages of a certain block size. The main function\n  exported is `mi_malloc_generic`.\n----------------------------------------------------------- */\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"\n\n/* -----------------------------------------------------------\n  Definition of page queues for each block size\n----------------------------------------------------------- */\n\n#define MI_IN_PAGE_C\n#include \"page-queue.c\"\n#undef MI_IN_PAGE_C\n\n\n/* -----------------------------------------------------------\n  Page helpers\n----------------------------------------------------------- */\n\n// Index a block in a page\nstatic inline mi_block_t* mi_page_block_at(const mi_page_t* page, void* page_start, size_t block_size, size_t i) {\n  MI_UNUSED(page);\n  mi_assert_internal(page != NULL);\n  mi_assert_internal(i <= page->reserved);\n  return (mi_block_t*)((uint8_t*)page_start + (i * block_size));\n}\n\nstatic bool mi_page_extend_free(mi_theap_t* theap, mi_page_t* page);\n\n#if (MI_DEBUG>=3)\nstatic size_t mi_page_list_count(mi_page_t* page, mi_block_t* head) {\n  mi_assert_internal(_mi_ptr_page(page->page_start) == page);\n  const uint8_t* slice_start = mi_page_slice_start(page);\n  mi_assert_internal(_mi_is_aligned(slice_start,MI_PAGE_ALIGN));\n  size_t count = 0;\n  while (head != NULL) {\n    mi_assert_internal((uint8_t*)head - slice_start > (ptrdiff_t)MI_LARGE_PAGE_SIZE || page == _mi_ptr_page(head));\n    count++;\n    head = mi_block_next(page, head);\n  }\n  return count;\n}\n\n/*\n// Start of the page available memory\nstatic inline uint8_t* mi_page_area(const mi_page_t* page) {\n  return _mi_page_start(_mi_page_segment(page), page, NULL);\n}\n*/\n\nstatic bool mi_page_list_is_valid(mi_page_t* page, mi_block_t* p) {\n  size_t psize;\n  uint8_t* page_area = mi_page_area(page, &psize);\n  mi_block_t* start = (mi_block_t*)page_area;\n  mi_block_t* end   = (mi_block_t*)(page_area + psize);\n  while(p != NULL) {\n    if (p < start || p >= end) return false;\n    p = mi_block_next(page, p);\n  }\n#if MI_DEBUG>3 // generally too expensive to check this\n  if (page->free_is_zero) {\n    const size_t ubsize = mi_page_usable_block_size(page);\n    for (mi_block_t* block = page->free; block != NULL; block = mi_block_next(page, block)) {\n      mi_assert_expensive(mi_mem_is_zero(block + 1, ubsize - sizeof(mi_block_t)));\n    }\n  }\n#endif\n  return true;\n}\n\nstatic bool mi_page_is_valid_init(mi_page_t* page) {\n  mi_assert_internal(mi_page_block_size(page) > 0);\n  mi_assert_internal(page->used <= page->capacity);\n  mi_assert_internal(page->capacity <= page->reserved);\n\n  // const size_t bsize = mi_page_block_size(page);\n  // uint8_t* start = mi_page_start(page);\n  //mi_assert_internal(start + page->capacity*page->block_size == page->top);\n\n  mi_assert_internal(mi_page_list_is_valid(page,page->free));\n  mi_assert_internal(mi_page_list_is_valid(page,page->local_free));\n\n  #if MI_DEBUG>3 // generally too expensive to check this\n  if (page->free_is_zero) {\n    const size_t ubsize = mi_page_usable_block_size(page);\n    for(mi_block_t* block = page->free; block != NULL; block = mi_block_next(page,block)) {\n      mi_assert_expensive(mi_mem_is_zero(block + 1, ubsize - sizeof(mi_block_t)));\n    }\n  }\n  #endif\n\n  #if !MI_TRACK_ENABLED && !MI_TSAN\n  mi_block_t* tfree = mi_page_thread_free(page);\n  mi_assert_internal(mi_page_list_is_valid(page, tfree));\n  //size_t tfree_count = mi_page_list_count(page, tfree);\n  //mi_assert_internal(tfree_count <= page->thread_freed + 1);\n  #endif\n\n  size_t free_count = mi_page_list_count(page, page->free) + mi_page_list_count(page, page->local_free);\n  mi_assert_internal(page->used + free_count == page->capacity);\n\n  return true;\n}\n\nextern mi_decl_hidden bool _mi_process_is_initialized;             // has mi_process_init been called?\n\nbool _mi_page_is_valid(mi_page_t* page) {\n  mi_assert_internal(mi_page_is_valid_init(page));\n  #if MI_SECURE\n  mi_assert_internal(page->keys[0] != 0);\n  #endif\n  if (!mi_page_is_abandoned(page)) {\n    //mi_assert_internal(!_mi_process_is_initialized);\n    {\n      mi_page_queue_t* pq = mi_page_queue_of(page);\n      mi_assert_internal(mi_page_queue_contains(pq, page));\n      mi_assert_internal(pq->block_size==mi_page_block_size(page) || mi_page_is_huge(page) || mi_page_is_in_full(page));\n      // mi_assert_internal(mi_theap_contains_queue(mi_page_theap(page),pq));\n    }\n  }\n  return true;\n}\n#endif\n\n\n/* -----------------------------------------------------------\n  Page collect the `local_free` and `thread_free` lists\n----------------------------------------------------------- */\n\nstatic void mi_page_thread_collect_to_local(mi_page_t* page, mi_block_t* head)\n{\n  if (head == NULL) return;\n\n  // find the last block in the list -- also to get a proper use count (without data races)\n  size_t max_count = page->capacity; // cannot collect more than capacity\n  size_t count = 1;\n  mi_block_t* last = head;\n  mi_block_t* next;\n  while ((next = mi_block_next(page, last)) != NULL && count <= max_count) {\n    count++;\n    last = next;\n  }\n\n  // if `count > max_count` there was a memory corruption (possibly infinite list due to double multi-threaded free)\n  if mi_unlikely(count > max_count) {\n    _mi_error_message(EFAULT, \"corrupted thread-free list\\n\");\n    return; // the thread-free items cannot be freed\n  }\n  // if `count > page->used` there was another kind memory corruption (either in the page meta-data or in the linked list)\n  else if mi_unlikely(count > page->used) {\n    _mi_error_message(EFAULT, \"corrupted meta-data in thread-free list\\n\");\n    return; // the thread-free items cannot be freed\n  }\n\n  // and append the current local free list\n  mi_block_set_next(page, last, page->local_free);\n  page->local_free = head;\n\n  // update counts now\n  mi_assert_internal(count <= UINT16_MAX);\n  mi_assert_internal(page->used >= (uint16_t)count);\n  page->used = page->used - (uint16_t)count;\n}\n\n// Collect the local `thread_free` list using an atomic exchange.\nstatic void mi_page_thread_free_collect(mi_page_t* page)\n{\n  // atomically capture the thread free list\n  mi_block_t* head;\n  mi_thread_free_t tfreex;\n  mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free);\n  do {\n    head = mi_tf_block(tfree);\n    if mi_likely(head == NULL) return; // return if the list is empty\n    tfreex = mi_tf_create(NULL,mi_tf_is_owned(tfree));  // set the thread free list to NULL\n  } while (!mi_atomic_cas_weak_acq_rel(&page->xthread_free, &tfree, tfreex));  // release is enough?\n  mi_assert_internal(head != NULL);\n\n  // and move it to the local list\n  mi_page_thread_collect_to_local(page, head);\n}\n\n// returns `true` if after collection `mi_page_immediate_available` is true.\nstatic bool mi_page_free_quick_collect(mi_page_t* page) {\n  if (page->free != NULL) return true;\n  if (page->local_free == NULL) return false;\n  // move local_free to free\n  page->free = page->local_free;\n  page->local_free = NULL;\n  page->free_is_zero = false;\n  return true;\n}\n\nvoid _mi_page_free_collect(mi_page_t* page, bool force) {\n  mi_assert_internal(page!=NULL);\n\n  // collect the thread free list\n  mi_page_thread_free_collect(page);\n\n  // and the local free list\n  if (page->local_free != NULL) {\n    if mi_likely(page->free == NULL) {\n      // usual case\n      page->free = page->local_free;\n      page->local_free = NULL;\n      page->free_is_zero = false;\n    }\n    else if (force) {\n      // append -- only on shutdown (force) as this is a linear operation\n      mi_block_t* tail = page->local_free;\n      mi_block_t* next;\n      while ((next = mi_block_next(page, tail)) != NULL) {\n        tail = next;\n      }\n      mi_block_set_next(page, tail, page->free);\n      page->free = page->local_free;\n      page->local_free = NULL;\n      page->free_is_zero = false;\n    }\n  }\n\n  mi_assert_internal(!force || page->local_free == NULL);\n}\n\n// Collect elements in the thread-free list starting at `head`. This is an optimized\n// version of `_mi_page_free_collect` to be used from `free.c:_mi_free_collect_mt` that avoids atomic access to `xthread_free`.\n//\n// `head` must be in the `xthread_free` list. It will not collect `head` itself\n// so the `used` count is not fully updated in general. However, if the `head` is\n// the last remaining element, it will be collected and the used count will become `0` (so `mi_page_all_free` becomes true).\nvoid _mi_page_free_collect_partly(mi_page_t* page, mi_block_t* head) {\n  if (head == NULL) return;\n  mi_block_t* next = mi_block_next(page,head);  // we cannot collect the head element itself as `page->thread_free` may point to it (and we want to avoid atomic ops)\n  if (next != NULL) {\n    mi_block_set_next(page, head, NULL);\n    mi_page_thread_collect_to_local(page, next);\n    if (page->local_free != NULL && page->free == NULL) {\n      page->free = page->local_free;\n      page->local_free = NULL;\n      page->free_is_zero = false;\n    }\n  }\n  if (page->used == 1) {\n    // all elements are free'd since we skipped the `head` element itself\n    mi_assert_internal(mi_tf_block(mi_atomic_load_relaxed(&page->xthread_free)) == head);\n    mi_assert_internal(mi_block_next(page,head) == NULL);\n    _mi_page_free_collect(page, false);  // collect the final element\n  }\n}\n\n\n/* -----------------------------------------------------------\n  Page fresh and retire\n----------------------------------------------------------- */\n\n/*\n// called from segments when reclaiming abandoned pages\nvoid _mi_page_reclaim(mi_theap_t* theap, mi_page_t* page) {\n  // mi_page_set_theap(page, theap);\n  // _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, true); // override never (after theap is set)\n  _mi_page_free_collect(page, false); // ensure used count is up to date\n\n  mi_assert_expensive(mi_page_is_valid_init(page));\n  // mi_assert_internal(mi_page_theap(page) == theap);\n  // mi_assert_internal(mi_page_thread_free_flag(page) != MI_NEVER_DELAYED_FREE);\n\n  // TODO: push on full queue immediately if it is full?\n  mi_page_queue_t* pq = mi_theap_page_queue_of(theap, page);\n  mi_page_queue_push(theap, pq, page);\n  mi_assert_expensive(_mi_page_is_valid(page));\n}\n*/\n\n// called from `mi_free` on a reclaim, and fresh_alloc if we get an abandoned page\nvoid _mi_theap_page_reclaim(mi_theap_t* theap, mi_page_t* page)\n{\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n  mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_assert_internal(mi_page_is_abandoned(page));\n\n  mi_page_set_theap(page,theap);\n  _mi_page_free_collect(page, false); // ensure used count is up to date\n  mi_page_queue_t* pq = mi_theap_page_queue_of(theap, page);\n  mi_page_queue_push_at_end(theap, pq, page);\n  mi_assert_expensive(_mi_page_is_valid(page));\n}\n\nvoid _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq) {\n  _mi_page_free_collect(page, false); // ensure used count is up to date\n  if (mi_page_all_free(page)) {\n    _mi_page_free(page, pq);\n  }\n  else {\n    mi_page_queue_remove(pq, page);\n    mi_theap_t* theap = page->theap;\n    mi_page_set_theap(page, NULL);\n    page->theap = theap; // don't actually set theap to NULL so we can reclaim_on_free within the same theap\n    _mi_arenas_page_abandon(page, theap);\n    _mi_arenas_collect(false, false, theap->tld); // allow purging\n  }\n}\n\n\n// allocate a fresh page from an arena\nstatic mi_page_t* mi_page_fresh_alloc(mi_theap_t* theap, mi_page_queue_t* pq, size_t block_size, size_t page_alignment) {\n  #if !MI_HUGE_PAGE_ABANDON\n  mi_assert_internal(pq != NULL);\n  mi_assert_internal(mi_theap_contains_queue(theap, pq));\n  mi_assert_internal(page_alignment > 0 || block_size > MI_LARGE_MAX_OBJ_SIZE || block_size == pq->block_size);\n  #endif\n  mi_page_t* page = _mi_arenas_page_alloc(theap, block_size, page_alignment);\n  if (page == NULL) {\n    // out-of-memory\n    return NULL;\n  }\n  if (mi_page_is_abandoned(page)) {\n    _mi_theap_page_reclaim(theap, page);\n    if (!mi_page_immediate_available(page)) {\n      if (mi_page_is_expandable(page)) {\n        if (!mi_page_extend_free(theap, page)) {\n          return NULL; // cannot commit\n        };\n      }\n      else {\n        mi_assert(false); // should not happen?\n        return NULL;\n      }\n    }\n  }\n  else if (pq != NULL) {\n    mi_page_queue_push(theap, pq, page);\n  }\n  mi_assert_internal(pq!=NULL || mi_page_block_size(page) >= block_size);\n  mi_assert_expensive(_mi_page_is_valid(page));\n  return page;\n}\n\n// Get a fresh page to use\nstatic mi_page_t* mi_page_fresh(mi_theap_t* theap, mi_page_queue_t* pq) {\n  mi_assert_internal(mi_theap_contains_queue(theap, pq));\n  mi_page_t* page = mi_page_fresh_alloc(theap, pq, pq->block_size, 0);\n  if (page==NULL) return NULL;\n  mi_assert_internal(pq->block_size==mi_page_block_size(page));\n  mi_assert_internal(pq==mi_theap_page_queue_of(theap, page));\n  return page;\n}\n\n\n/* -----------------------------------------------------------\n  Unfull, abandon, free and retire\n----------------------------------------------------------- */\n\n// Move a page from the full list back to a regular list (called from thread-local mi_free)\nvoid _mi_page_unfull(mi_page_t* page) {\n  mi_assert_internal(page != NULL);\n  mi_assert_expensive(_mi_page_is_valid(page));\n  mi_assert_internal(mi_page_is_in_full(page));\n  mi_assert_internal(!mi_page_theap(page)->allow_page_abandon);\n  if (!mi_page_is_in_full(page)) return;\n\n  mi_theap_t* theap = mi_page_theap(page);\n  mi_page_queue_t* pqfull = &theap->pages[MI_BIN_FULL];\n  mi_page_set_in_full(page, false); // to get the right queue\n  mi_page_queue_t* pq = mi_theap_page_queue_of(theap, page);\n  mi_page_set_in_full(page, true);\n  mi_page_queue_enqueue_from_full(pq, pqfull, page);\n}\n\nstatic void mi_page_to_full(mi_page_t* page, mi_page_queue_t* pq) {\n  mi_assert_internal(pq == mi_page_queue_of(page));\n  mi_assert_internal(!mi_page_immediate_available(page));\n  mi_assert_internal(!mi_page_is_in_full(page));\n\n  mi_theap_t* theap = mi_page_theap(page);\n  if (theap->allow_page_abandon) {\n    // abandon full pages (this is the usual case in order to allow for sharing of memory between theaps)\n    _mi_page_abandon(page, pq);\n  }\n  else if (!mi_page_is_in_full(page)) {\n    // put full pages in a theap local queue (this is for theaps that cannot abandon, for example, if the theap can be destroyed)\n    mi_page_queue_enqueue_from(&mi_page_theap(page)->pages[MI_BIN_FULL], pq, page);\n    _mi_page_free_collect(page, false);  // try to collect right away in case another thread freed just before MI_USE_DELAYED_FREE was set\n  }\n}\n\n\n// Free a page with no more free blocks\nvoid _mi_page_free(mi_page_t* page, mi_page_queue_t* pq) {\n  mi_assert_internal(page != NULL);\n  mi_assert_expensive(_mi_page_is_valid(page));\n  mi_assert_internal(pq == mi_page_queue_of(page));\n  mi_assert_internal(mi_page_all_free(page));\n  // mi_assert_internal(mi_page_thread_free_flag(page)!=MI_DELAYED_FREEING);\n\n  // no more aligned blocks in here\n  mi_page_set_has_interior_pointers(page, false);\n\n  // remove from the page list\n  // (no need to do _mi_theap_delayed_free first as all blocks are already free)\n  mi_page_queue_remove(pq, page);\n\n  // and free it\n  mi_theap_t* theap = mi_page_theap(page); mi_assert_internal(theap!=NULL);\n  mi_page_set_theap(page,NULL);\n  _mi_arenas_page_free(page, theap);\n  _mi_arenas_collect(false, false, theap->tld);  // allow purging\n}\n\n#define MI_MAX_RETIRE_SIZE    MI_LARGE_OBJ_SIZE_MAX   // should be less than size for MI_BIN_HUGE\n#define MI_RETIRE_CYCLES      (16)\n\n// Retire a page with no more used blocks\n// Important to not retire too quickly though as new\n// allocations might coming.\n//\n// Note: called from `mi_free` and benchmarks often\n// trigger this due to freeing everything and then\n// allocating again so careful when changing this.\nvoid _mi_page_retire(mi_page_t* page) mi_attr_noexcept {\n  mi_assert_internal(page != NULL);\n  mi_assert_expensive(_mi_page_is_valid(page));\n  mi_assert_internal(mi_page_all_free(page));\n\n  if (page->retire_expire!=0) return;  // already retired, just keep it retired\n  mi_page_set_has_interior_pointers(page, false);\n\n  // don't retire too often..\n  // (or we end up retiring and re-allocating most of the time)\n  // NOTE: refine this more: we should not retire if this\n  // is the only page left with free blocks. It is not clear\n  // how to check this efficiently though...\n  // for now, we don't retire if it is the only page left of this size class.\n  mi_page_queue_t* pq = mi_page_queue_of(page);\n  #if MI_RETIRE_CYCLES > 0\n  const size_t bsize = mi_page_block_size(page);\n  if mi_likely( /* bsize < MI_MAX_RETIRE_SIZE && */ !mi_page_queue_is_special(pq)) {  // not full or huge queue?\n    if (pq->last==page && pq->first==page) { // the only page in the queue?\n      mi_theap_t* theap = mi_page_theap(page);\n      #if MI_STAT>0\n      mi_theap_stat_counter_increase(theap, pages_retire, 1);\n      #endif\n      page->retire_expire = (bsize <= MI_SMALL_MAX_OBJ_SIZE ? MI_RETIRE_CYCLES : MI_RETIRE_CYCLES/4);\n      mi_assert_internal(pq >= theap->pages);\n      const size_t index = pq - theap->pages;\n      mi_assert_internal(index < MI_BIN_FULL && index < MI_BIN_HUGE);\n      if (index < theap->page_retired_min) theap->page_retired_min = index;\n      if (index > theap->page_retired_max) theap->page_retired_max = index;\n      mi_assert_internal(mi_page_all_free(page));\n      return; // don't free after all\n    }\n  }\n  #endif\n  _mi_page_free(page, pq);\n}\n\n// free retired pages: we don't need to look at the entire queues\n// since we only retire pages that are at the head position in a queue.\nvoid _mi_theap_collect_retired(mi_theap_t* theap, bool force) {\n  size_t min = MI_BIN_FULL;\n  size_t max = 0;\n  for(size_t bin = theap->page_retired_min; bin <= theap->page_retired_max; bin++) {\n    mi_page_queue_t* pq   = &theap->pages[bin];\n    mi_page_t*       page = pq->first;\n    if (page != NULL && page->retire_expire != 0) {\n      if (mi_page_all_free(page)) {\n        page->retire_expire--;\n        if (page->retire_expire == 0 || force) {\n          _mi_page_free(page, pq);\n        }\n        else {\n          // keep retired, update min/max\n          if (bin < min) min = bin;\n          if (bin > max) max = bin;\n        }\n      }\n      else {\n        page->retire_expire = 0;\n      }\n    }\n  }\n  theap->page_retired_min = min;\n  theap->page_retired_max = max;\n}\n\n/*\nstatic void mi_theap_collect_full_pages(mi_theap_t* theap) {\n  // note: normally full pages get immediately abandoned and the full queue is always empty\n  // this path is only used if abandoning is disabled due to a destroy-able theap or options\n  // set by the user.\n  mi_page_queue_t* pq = &theap->pages[MI_BIN_FULL];\n  for (mi_page_t* page = pq->first; page != NULL; ) {\n    mi_page_t* next = page->next;         // get next in case we free the page\n    _mi_page_free_collect(page, false);   // register concurrent free's\n    // no longer full?\n    if (!mi_page_is_full(page)) {\n      if (mi_page_all_free(page)) {\n        _mi_page_free(page, pq);\n      }\n      else {\n        _mi_page_unfull(page);\n      }\n    }\n    page = next;\n  }\n}\n*/\n\n\n/* -----------------------------------------------------------\n  Initialize the initial free list in a page.\n  In secure mode we initialize a randomized list by\n  alternating between slices.\n----------------------------------------------------------- */\n\n#define MI_MAX_SLICE_SHIFT  (6)   // at most 64 slices\n#define MI_MAX_SLICES       (1UL << MI_MAX_SLICE_SHIFT)\n#define MI_MIN_SLICES       (2)\n\nstatic void mi_page_free_list_extend_secure(mi_theap_t* const theap, mi_page_t* const page, const size_t bsize, const size_t extend) {\n  #if (MI_SECURE<3)\n  mi_assert_internal(page->free == NULL);\n  mi_assert_internal(page->local_free == NULL);\n  #endif\n  mi_assert_internal(page->capacity + extend <= page->reserved);\n  mi_assert_internal(bsize == mi_page_block_size(page));\n  void* const page_area = mi_page_start(page);\n\n  // initialize a randomized free list\n  // set up `slice_count` slices to alternate between\n  size_t shift = MI_MAX_SLICE_SHIFT;\n  while ((extend >> shift) == 0) {\n    shift--;\n  }\n  const size_t slice_count = (size_t)1U << shift;\n  const size_t slice_extend = extend / slice_count;\n  mi_assert_internal(slice_extend >= 1);\n  mi_block_t* blocks[MI_MAX_SLICES];   // current start of the slice\n  size_t      counts[MI_MAX_SLICES];   // available objects in the slice\n  for (size_t i = 0; i < slice_count; i++) {\n    blocks[i] = mi_page_block_at(page, page_area, bsize, page->capacity + i*slice_extend);\n    counts[i] = slice_extend;\n  }\n  counts[slice_count-1] += (extend % slice_count);  // final slice holds the modulus too (todo: distribute evenly?)\n\n  // and initialize the free list by randomly threading through them\n  // set up first element\n  const uintptr_t r = _mi_theap_random_next(theap);\n  size_t current = r % slice_count;\n  counts[current]--;\n  mi_block_t* const free_start = blocks[current];\n  // and iterate through the rest; use `random_shuffle` for performance\n  uintptr_t rnd = _mi_random_shuffle(r|1); // ensure not 0\n  for (size_t i = 1; i < extend; i++) {\n    // call random_shuffle only every INTPTR_SIZE rounds\n    const size_t round = i%MI_INTPTR_SIZE;\n    if (round == 0) rnd = _mi_random_shuffle(rnd);\n    // select a random next slice index\n    size_t next = ((rnd >> 8*round) & (slice_count-1));\n    while (counts[next]==0) {                            // ensure it still has space\n      next++;\n      if (next==slice_count) next = 0;\n    }\n    // and link the current block to it\n    counts[next]--;\n    mi_block_t* const block = blocks[current];\n    blocks[current] = (mi_block_t*)((uint8_t*)block + bsize);  // bump to the following block\n    mi_block_set_next(page, block, blocks[next]);   // and set next; note: we may have `current == next`\n    current = next;\n  }\n  // prepend to the free list (usually NULL)\n  mi_block_set_next(page, blocks[current], page->free);  // end of the list\n  page->free = free_start;\n}\n\nstatic mi_decl_noinline void mi_page_free_list_extend( mi_page_t* const page, const size_t bsize, const size_t extend)\n{\n  #if (MI_SECURE<3)\n  mi_assert_internal(page->free == NULL);\n  mi_assert_internal(page->local_free == NULL);\n  #endif\n  mi_assert_internal(page->capacity + extend <= page->reserved);\n  mi_assert_internal(bsize == mi_page_block_size(page));\n  void* const page_area = mi_page_start(page);\n\n  mi_block_t* const start = mi_page_block_at(page, page_area, bsize, page->capacity);\n\n  // initialize a sequential free list\n  mi_block_t* const last = mi_page_block_at(page, page_area, bsize, page->capacity + extend - 1);\n  mi_block_t* block = start;\n  while(block <= last) {\n    mi_block_t* next = (mi_block_t*)((uint8_t*)block + bsize);\n    mi_block_set_next(page,block,next);\n    block = next;\n  }\n  // prepend to free list (usually `NULL`)\n  mi_block_set_next(page, last, page->free);\n  page->free = start;\n}\n\n/* -----------------------------------------------------------\n  Page initialize and extend the capacity\n----------------------------------------------------------- */\n\n#define MI_MAX_EXTEND_SIZE    (4*1024)      // heuristic, one OS page seems to work well.\n#if (MI_SECURE>=2)\n#define MI_MIN_EXTEND         (8*MI_SECURE) // extend at least by this many\n#else\n#define MI_MIN_EXTEND         (1)\n#endif\n\n// Extend the capacity (up to reserved) by initializing a free list\n// We do at most `MI_MAX_EXTEND` to avoid touching too much memory\n// Note: we also experimented with \"bump\" allocation on the first\n// allocations but this did not speed up any benchmark (due to an\n// extra test in malloc? or cache effects?)\nstatic bool mi_page_extend_free(mi_theap_t* theap, mi_page_t* page) {\n  mi_assert_expensive(mi_page_is_valid_init(page));\n  #if (MI_SECURE<3)\n  mi_assert(page->free == NULL);\n  mi_assert(page->local_free == NULL);\n  if (page->free != NULL) return true;\n  #endif\n  if (page->capacity >= page->reserved) return true;\n\n  size_t page_size;\n  //uint8_t* page_start =\n  mi_page_area(page, &page_size);\n  #if MI_STAT>0\n  mi_theap_stat_counter_increase(theap, pages_extended, 1);\n  #endif\n\n  // calculate the extend count\n  const size_t bsize = mi_page_block_size(page);\n  size_t extend = (size_t)page->reserved - page->capacity;\n  mi_assert_internal(extend > 0);\n\n  size_t max_extend = (bsize >= MI_MAX_EXTEND_SIZE ? MI_MIN_EXTEND : MI_MAX_EXTEND_SIZE/bsize);\n  if (max_extend < MI_MIN_EXTEND) { max_extend = MI_MIN_EXTEND; }\n  mi_assert_internal(max_extend > 0);\n\n  if (extend > max_extend) {\n    // ensure we don't touch memory beyond the page to reduce page commit.\n    // the `lean` benchmark tests this. Going from 1 to 8 increases rss by 50%.\n    extend = max_extend;\n  }\n\n  mi_assert_internal(extend > 0 && extend + page->capacity <= page->reserved);\n  mi_assert_internal(extend < (1UL<<16));\n\n  // commit on demand?\n  if (page->slice_committed > 0) {\n    const size_t needed_size = (page->capacity + extend)*bsize;\n    const size_t needed_commit = _mi_align_up( mi_page_slice_offset_of(page, needed_size), MI_PAGE_MIN_COMMIT_SIZE );\n    if (needed_commit > page->slice_committed) {\n      mi_assert_internal(((needed_commit - page->slice_committed) % _mi_os_page_size()) == 0);\n      if (!_mi_os_commit(mi_page_slice_start(page) + page->slice_committed, needed_commit - page->slice_committed, NULL)) {\n        return false;\n      }\n      page->slice_committed = needed_commit;\n    }\n  }\n\n  // and append the extend the free list\n  if (extend < MI_MIN_SLICES || MI_SECURE<2) { //!mi_option_is_enabled(mi_option_secure)) {\n    mi_page_free_list_extend(page, bsize, extend );\n  }\n  else {\n    mi_page_free_list_extend_secure(theap, page, bsize, extend);\n  }\n  // enable the new free list\n  page->capacity += (uint16_t)extend;\n  #if MI_STAT>0\n  mi_theap_stat_increase(theap, page_committed, extend * bsize);\n  #endif\n  mi_assert_expensive(mi_page_is_valid_init(page));\n  return true;\n}\n\n// Initialize a fresh page (that is already partially initialized)\nmi_decl_nodiscard bool _mi_page_init(mi_theap_t* theap, mi_page_t* page) {\n  mi_assert(page != NULL);\n  mi_assert(theap!=NULL);\n  page->heap = (_mi_is_heap_main(_mi_theap_heap(theap)) ? NULL : _mi_theap_heap(theap)); // faster for `mi_page_associated_theap`\n  mi_page_set_theap(page, theap);\n\n  size_t page_size;\n  uint8_t* page_start = mi_page_area(page, &page_size); MI_UNUSED(page_start);\n  mi_track_mem_noaccess(page_start,page_size);\n  mi_assert_internal(page_size / mi_page_block_size(page) < (1L<<16));\n  mi_assert_internal(page->reserved > 0);\n  #if (MI_PADDING || MI_ENCODE_FREELIST)\n  page->keys[0] = _mi_theap_random_next(theap);\n  page->keys[1] = _mi_theap_random_next(theap);\n  #endif\n  #if MI_DEBUG>2\n  if (page->memid.initially_zero) {\n    mi_track_mem_defined(page->page_start, mi_page_committed(page));\n    mi_assert_expensive(mi_mem_is_zero(page_start, mi_page_committed(page)));\n  }\n  #endif\n\n  mi_assert_internal(page->theap!=NULL);\n  mi_assert_internal(page->theap == mi_page_theap(page));\n  mi_assert_internal(page->capacity == 0);\n  mi_assert_internal(page->free == NULL);\n  mi_assert_internal(page->used == 0);\n  mi_assert_internal(mi_page_is_owned(page));\n  mi_assert_internal(page->xthread_free == 1);\n  mi_assert_internal(page->next == NULL);\n  mi_assert_internal(page->prev == NULL);\n  mi_assert_internal(page->retire_expire == 0);\n  mi_assert_internal(!mi_page_has_interior_pointers(page));\n  #if (MI_PADDING || MI_ENCODE_FREELIST)\n  mi_assert_internal(page->keys[0] != 0);\n  mi_assert_internal(page->keys[1] != 0);\n  #endif\n  mi_assert_expensive(mi_page_is_valid_init(page));\n\n  // initialize an initial free list\n  if (!mi_page_extend_free(theap,page)) return false;\n  mi_assert(mi_page_immediate_available(page));\n  return true;\n}\n\n\n/* -----------------------------------------------------------\n  Find pages with free blocks\n-------------------------------------------------------------*/\n\n// Find a page with free blocks of `page->block_size`.\nstatic mi_decl_noinline mi_page_t* mi_page_queue_find_free_ex(mi_theap_t* theap, mi_page_queue_t* pq, bool first_try)\n{\n  // search through the pages in \"next fit\" order\n  size_t count = 0;\n  long candidate_limit = 0;          // we reset this on the first candidate to limit the search\n  long page_full_retain = (pq->block_size > MI_SMALL_MAX_OBJ_SIZE ? 0 : theap->page_full_retain); // only retain small pages\n  mi_page_t* page_candidate = NULL;  // a page with free space\n  mi_page_t* page = pq->first;\n\n  while (page != NULL)\n  {\n    mi_page_t* next = page->next; // remember next (as this page can move to another queue)\n    count++;\n    candidate_limit--;\n\n    // search up to N pages for a best candidate\n\n    // is the local free list non-empty?\n    bool immediate_available = mi_page_immediate_available(page);\n    if (!immediate_available) {\n      // collect freed blocks by us and other threads to we get a proper use count\n      _mi_page_free_collect(page, false);\n      immediate_available = mi_page_immediate_available(page);\n    }\n\n    // if the page is completely full, move it to the `mi_pages_full`\n    // queue so we don't visit long-lived pages too often.\n    if (!immediate_available && !mi_page_is_expandable(page)) {\n      page_full_retain--;\n      if (page_full_retain < 0) {\n        mi_assert_internal(!mi_page_is_in_full(page) && !mi_page_immediate_available(page));\n        mi_page_to_full(page, pq);\n      }\n    }\n    else {\n      // the page has free space, make it a candidate\n      // we prefer non-expandable pages with high usage as candidates (to reduce commit, and increase chances of free-ing up pages)\n      if (page_candidate == NULL) {\n        page_candidate = page;\n        candidate_limit = _mi_option_get_fast(mi_option_page_max_candidates);\n      }\n      else if (mi_page_all_free(page_candidate)) {\n        _mi_page_free(page_candidate, pq);\n        page_candidate = page;\n      }\n      // prefer to reuse fuller pages (in the hope the less used page gets freed)\n      else if (page->used >= page_candidate->used && !mi_page_is_mostly_used(page)) { // && !mi_page_is_expandable(page)) {\n        page_candidate = page;\n      }\n      // if we find a non-expandable candidate, or searched for N pages, return with the best candidate\n      if (immediate_available || candidate_limit <= 0) {\n        mi_assert_internal(page_candidate!=NULL);\n        break;\n      }\n    }\n\n  #if 0\n    // first-fit algorithm without candidates\n    // If the page contains free blocks, we are done\n    if (mi_page_immediate_available(page) || mi_page_is_expandable(page)) {\n      break;  // pick this one\n    }\n\n    // If the page is completely full, move it to the `mi_pages_full`\n    // queue so we don't visit long-lived pages too often.\n    mi_assert_internal(!mi_page_is_in_full(page) && !mi_page_immediate_available(page));\n    mi_page_to_full(page, pq);\n  #endif\n\n    page = next;\n  } // for each page\n\n  mi_theap_stat_counter_increase(theap, page_searches, count);\n  mi_theap_stat_counter_increase(theap, page_searches_count, 1);\n\n  // set the page to the best candidate\n  if (page_candidate != NULL) {\n    page = page_candidate;\n  }\n  if (page != NULL) {\n    if (!mi_page_immediate_available(page)) {\n      mi_assert_internal(mi_page_is_expandable(page));\n      if (!mi_page_extend_free(theap, page)) {\n        page = NULL; // failed to extend\n      }\n    }\n    mi_assert_internal(page == NULL || mi_page_immediate_available(page));\n  }\n\n  if (page == NULL) {\n    _mi_theap_collect_retired(theap, false); // perhaps make a page available\n    page = mi_page_fresh(theap, pq);\n    mi_assert_internal(page == NULL || mi_page_immediate_available(page));\n    if (page == NULL && first_try) {\n      // out-of-memory _or_ an abandoned page with free blocks was reclaimed, try once again\n      page = mi_page_queue_find_free_ex(theap, pq, false);\n      mi_assert_internal(page == NULL || mi_page_immediate_available(page));\n    }\n  }\n  else {\n    mi_assert_internal(page == NULL || mi_page_immediate_available(page));\n    // move the page to the front of the queue\n    mi_page_queue_move_to_front(theap, pq, page);\n    page->retire_expire = 0;\n    // _mi_theap_collect_retired(theap, false); // update retire counts; note: increases rss on MemoryLoad bench so don't do this\n  }\n  mi_assert_internal(page == NULL || mi_page_immediate_available(page));\n\n\n  return page;\n}\n\n\n\n// Find a page with free blocks of `size`.\nstatic mi_page_t* mi_find_free_page(mi_theap_t* theap, mi_page_queue_t* pq) {\n  // mi_page_queue_t* pq = mi_page_queue(theap, size);\n  mi_assert_internal(!mi_page_queue_is_huge(pq));\n\n  // check the first page: we even do this with candidate search or otherwise we re-search every time\n  mi_page_t* page = pq->first;\n  if mi_likely(page != NULL && mi_page_free_quick_collect(page)) {\n    #if (MI_SECURE>=2) // in secure mode, we extend half the time to increase randomness\n    if (page->capacity < page->reserved && ((_mi_theap_random_next(theap) & 1) == 1)) {\n      (void)mi_page_extend_free(theap, page);  // ok if this fails\n      mi_assert_internal(mi_page_immediate_available(page));\n    }\n    #endif\n    page->retire_expire = 0;\n    return page; // fast path\n  }\n  else {\n    return mi_page_queue_find_free_ex(theap, pq, true);\n  }\n}\n\n\n/* -----------------------------------------------------------\n  Users can register a deferred free function called\n  when the `free` list is empty. Since the `local_free`\n  is separate this is deterministically called after\n  a certain number of allocations.\n----------------------------------------------------------- */\n\n// The program should only install a single deferred free handler before doing allocation.\nstatic _Atomic(void*) deferred_free; // is `mi_deferred_free_fun*` (but some platforms don't support atomic function pointers)\nstatic _Atomic(void*) deferred_arg;   \n\nvoid _mi_deferred_free(mi_theap_t* theap, bool force) {\n  theap->heartbeat++;\n  mi_deferred_free_fun* const fun = (mi_deferred_free_fun*)mi_atomic_load_ptr_acquire(void,&deferred_free);\n  if (fun != NULL && !theap->tld->recurse) {\n    theap->tld->recurse = true;\n    void* const arg = mi_atomic_load_ptr_acquire(void,&deferred_arg);  \n    fun(force, theap->heartbeat, arg);\n    theap->tld->recurse = false;\n  }\n}\n\nvoid mi_register_deferred_free(mi_deferred_free_fun* fn, void* arg) mi_attr_noexcept {\n  mi_atomic_store_ptr_release(void,&deferred_arg, arg);\n  mi_atomic_store_ptr_release(void,&deferred_free, (void*)fn);  \n}\n\n\n/* -----------------------------------------------------------\n  General allocation\n----------------------------------------------------------- */\n\n// Huge pages contain just one block, and the segment contains just that page.\n// Huge pages are also use if the requested alignment is very large (> MI_BLOCK_ALIGNMENT_MAX)\n// so their size is not always `> MI_LARGE_OBJ_SIZE_MAX`.\nstatic mi_page_t* mi_huge_page_alloc(mi_theap_t* theap, size_t size, size_t page_alignment, mi_page_queue_t* pq) {\n  const size_t block_size = _mi_os_good_alloc_size(size);\n  // mi_assert_internal(mi_bin(block_size) == MI_BIN_HUGE || page_alignment > 0);\n  #if MI_HUGE_PAGE_ABANDON\n  #error todo.\n  #else\n  // mi_page_queue_t* pq = mi_page_queue(theap, MI_LARGE_MAX_OBJ_SIZE+1);  // always in the huge queue regardless of the block size\n  mi_assert_internal(mi_page_queue_is_huge(pq));\n  #endif\n  mi_page_t* page = mi_page_fresh_alloc(theap, pq, block_size, page_alignment);\n  if (page != NULL) {\n    mi_assert_internal(mi_page_block_size(page) >= size);\n    mi_assert_internal(mi_page_immediate_available(page));\n    mi_assert_internal(mi_page_is_huge(page));\n    mi_assert_internal(mi_page_is_singleton(page));\n    #if MI_HUGE_PAGE_ABANDON\n    mi_assert_internal(mi_page_is_abandoned(page));\n    mi_page_set_theap(page, NULL);\n    #endif\n    mi_theap_stat_increase(theap, malloc_huge, mi_page_block_size(page));\n    mi_theap_stat_counter_increase(theap, malloc_huge_count, 1);\n  }\n  return page;\n}\n\n\n// Allocate a page\n// Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed.\nstatic mi_page_t* mi_find_page(mi_theap_t* theap, size_t size, size_t huge_alignment) mi_attr_noexcept {\n  const size_t req_size = size - MI_PADDING_SIZE;  // correct for padding_size in case of an overflow on `size`\n  if mi_unlikely(req_size > MI_MAX_ALLOC_SIZE) {\n    _mi_error_message(EOVERFLOW, \"allocation request is too large (%zu bytes)\\n\", req_size);\n    return NULL;\n  }\n  mi_page_queue_t* pq = mi_page_queue(theap, (huge_alignment > 0 ? MI_LARGE_MAX_OBJ_SIZE+1 : size));\n  // huge allocation?\n  if mi_unlikely(mi_page_queue_is_huge(pq) || req_size > MI_MAX_ALLOC_SIZE) {\n    return mi_huge_page_alloc(theap,size,huge_alignment,pq);\n  }\n  else {\n    // otherwise find a page with free blocks in our size segregated queues\n    #if MI_PADDING\n    mi_assert_internal(size >= MI_PADDING_SIZE);\n    #endif\n    return mi_find_free_page(theap, pq);\n  }\n}\n\n\n// Generic allocation routine if the fast path (`alloc.c:mi_page_malloc`) does not succeed.\n// Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed.\n// The `huge_alignment` is normally 0 but is set to a multiple of MI_SLICE_SIZE for\n// very large requested alignments in which case we use a huge singleton page.\n// Note: we put `bool zero, size_t huge_alignment` into one parameter (with zero in the low bit)\n// to use 4 parameters which compiles better on msvc for the malloc fast path.\nvoid* _mi_malloc_generic(mi_theap_t* theap, size_t size, size_t zero_huge_alignment, size_t* usable) mi_attr_noexcept\n{\n  const bool zero = ((zero_huge_alignment & 1) != 0);\n  const size_t huge_alignment = (zero_huge_alignment & ~1);\n\n  #if !MI_THEAP_INITASNULL\n  mi_assert_internal(theap != NULL);\n  #endif\n\n  // initialize if necessary\n  if mi_unlikely(!mi_theap_is_initialized(theap)) {\n    if (theap==&_mi_theap_empty_wrong) {\n      // we were unable to allocate a theap for a first-class heap\n      return NULL;\n    }\n    // otherwise we initialize the thread and its default theap\n    mi_thread_init();\n    theap = _mi_theap_default();\n    if mi_unlikely(!mi_theap_is_initialized(theap)) { return NULL; }\n    mi_assert_internal(_mi_theap_default()==theap);\n  }\n  mi_assert_internal(mi_theap_is_initialized(theap));\n\n  // do administrative tasks every N generic mallocs\n  if mi_unlikely(++theap->generic_count >= 1000) {\n    theap->generic_collect_count += theap->generic_count;\n    theap->generic_count = 0;\n    // call potential deferred free routines\n    _mi_deferred_free(theap, false);\n    // free retired pages\n    _mi_theap_collect_retired(theap, false);\n\n    // collect every once in a while (10000 by default)\n    const long generic_collect = mi_option_get_clamp(mi_option_generic_collect, 1, 1000000L);\n    if (theap->generic_collect_count >= generic_collect) {\n      theap->generic_collect_count = 0;\n      mi_theap_collect(theap, false /* force? */);\n    }\n  }\n\n  // find (or allocate) a page of the right size\n  mi_page_t* page = mi_find_page(theap, size, huge_alignment);\n  if mi_unlikely(page == NULL) { // first time out of memory, try to collect and retry the allocation once more\n    mi_theap_collect(theap, true /* force? */);\n    page = mi_find_page(theap, size, huge_alignment);\n  }\n\n  if mi_unlikely(page == NULL) { // out of memory\n    const size_t req_size = size - MI_PADDING_SIZE;  // correct for padding_size in case of an overflow on `size`\n    _mi_error_message(ENOMEM, \"unable to allocate memory (%zu bytes)\\n\", req_size);\n    return NULL;\n  }\n\n  mi_assert_internal(mi_page_immediate_available(page));\n  mi_assert_internal(mi_page_block_size(page) >= size);\n  mi_assert_internal(_mi_is_aligned(mi_page_slice_start(page), MI_PAGE_ALIGN));\n  mi_assert_internal(_mi_ptr_page(mi_page_start(page))==page);\n\n  // and try again, this time succeeding! (i.e. this should never recurse through _mi_page_malloc)\n  if (usable!=NULL) { *usable = mi_page_usable_block_size(page); }\n  void* const p = _mi_page_malloc_zero(theap,page,size,zero);\n  mi_assert_internal(p != NULL);\n\n  // move full pages to the full queue\n  if (mi_page_block_size(page) > MI_SMALL_MAX_OBJ_SIZE && mi_page_is_full(page)) {\n    mi_page_to_full(page, mi_page_queue_of(page));\n  }\n  return p;\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/prim/emscripten/prim.c",
      "sha256": "7488e9e562ca85d2d757ec48e4d334935263a2333aa05b6061d8520f427c5890",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen, Alon Zakai\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// This file is included in `src/prim/prim.c`\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"\n\n#include <sched.h>   // sched_yield\n#include <unistd.h>  // getentropy\n\n// Design\n// ======\n//\n// mimalloc is built on top of emmalloc. emmalloc is a minimal allocator on top\n// of sbrk. The reason for having three layers here is that we want mimalloc to\n// be able to allocate and release system memory properly, the same way it would\n// when using VirtualAlloc on Windows or mmap on POSIX, and sbrk is too limited.\n// Specifically, sbrk can only go up and down, and not \"skip\" over regions, and\n// so we end up either never freeing memory to the system, or we can get stuck\n// with holes.\n//\n// Atm wasm generally does *not* free memory back the system: once grown, we do\n// not shrink back down (https://github.com/WebAssembly/design/issues/1397).\n// However, that is expected to improve\n// (https://github.com/WebAssembly/memory-control/blob/main/proposals/memory-control/Overview.md)\n// and so we do not want to bake those limitations in here.\n//\n// Even without that issue, we want our system allocator to handle holes, that\n// is, it should merge freed regions and allow allocating new content there of\n// the full size, etc., so that we do not waste space. That means that the\n// system allocator really does need to handle the general problem of allocating\n// and freeing variable-sized chunks of memory in a random order, like malloc/\n// free do. And so it makes sense to layer mimalloc on top of such an\n// implementation.\n//\n// emmalloc makes sense for the lower level because it is small and simple while\n// still fully handling merging of holes etc. It is not the most efficient\n// allocator, but our assumption is that mimalloc needs to be fast while the\n// system allocator underneath it is called much less frequently.\n//\n\n//---------------------------------------------\n// init\n//---------------------------------------------\n\nvoid _mi_prim_mem_init( mi_os_mem_config_t* config) {\n  config->page_size = 64*MI_KiB; // WebAssembly has a fixed page size: 64KiB\n  config->alloc_granularity = 16;\n  config->has_overcommit = false;\n  config->has_partial_free = false;\n  config->has_virtual_reserve = false;\n}\n\nextern void emmalloc_free(void*);\n\nint _mi_prim_free(void* addr, size_t size) {\n  if (size==0) return 0;\n  emmalloc_free(addr);\n  return 0;\n}\n\n\n//---------------------------------------------\n// Allocation\n//---------------------------------------------\n\nextern void* emmalloc_memalign(size_t alignment, size_t size);\n\n// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.\nint _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) {\n  MI_UNUSED(try_alignment); MI_UNUSED(allow_large); MI_UNUSED(commit); MI_UNUSED(hint_addr);\n  *is_large = false;\n  // TODO: Track the highest address ever seen; first uses of it are zeroes.\n  //       That assumes no one else uses sbrk but us (they could go up,\n  //       scribble, and then down), but we could assert on that perhaps.\n  *is_zero = false;\n  // emmalloc has a minimum alignment size.\n  #define MIN_EMMALLOC_ALIGN           8\n  if (try_alignment < MIN_EMMALLOC_ALIGN) {\n    try_alignment = MIN_EMMALLOC_ALIGN;\n  }\n  void* p = emmalloc_memalign(try_alignment, size);\n  *addr = p;\n  if (p == 0) {\n    return ENOMEM;\n  }\n  return 0;\n}\n\n\n//---------------------------------------------\n// Commit/Reset\n//---------------------------------------------\n\nint _mi_prim_commit(void* addr, size_t size, bool* is_zero) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  // See TODO above.\n  *is_zero = false;\n  return 0;\n}\n\nint _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  *needs_recommit = false;\n  return 0;\n}\n\nint _mi_prim_reset(void* addr, size_t size) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  return 0;\n}\n\nint _mi_prim_reuse(void* addr, size_t size) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  return 0;\n}\n\nint _mi_prim_protect(void* addr, size_t size, bool protect) {\n  MI_UNUSED(addr); MI_UNUSED(size); MI_UNUSED(protect);\n  return 0;\n}\n\n\n//---------------------------------------------\n// Huge pages and NUMA nodes\n//---------------------------------------------\n\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {\n  MI_UNUSED(hint_addr); MI_UNUSED(size); MI_UNUSED(numa_node);\n  *is_zero = true;\n  *addr = NULL;\n  return ENOSYS;\n}\n\nsize_t _mi_prim_numa_node(void) {\n  return 0;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  return 1;\n}\n\n\n//----------------------------------------------------------------\n// Clock\n//----------------------------------------------------------------\n\n#include <emscripten/html5.h>\n\nmi_msecs_t _mi_prim_clock_now(void) {\n  return emscripten_date_now();\n}\n\n\n//----------------------------------------------------------------\n// Process info\n//----------------------------------------------------------------\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo)\n{\n  // use defaults\n  MI_UNUSED(pinfo);\n}\n\n\n//----------------------------------------------------------------\n// Output\n//----------------------------------------------------------------\n\n#include <emscripten/console.h>\n\nvoid _mi_prim_out_stderr( const char* msg) {\n  emscripten_console_error(msg);\n}\n\n\n//----------------------------------------------------------------\n// Environment\n//----------------------------------------------------------------\n\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size) {\n  // For code size reasons, do not support environ customization for now.\n  MI_UNUSED(name);\n  MI_UNUSED(result);\n  MI_UNUSED(result_size);\n  return false;\n}\n\n\n//----------------------------------------------------------------\n// Random\n//----------------------------------------------------------------\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  int err = getentropy(buf, buf_len);\n  return !err;\n}\n\n\n//----------------------------------------------------------------\n// Thread init/done\n//----------------------------------------------------------------\n\n#if defined(MI_USE_PTHREADS)\n\n// use pthread local storage keys to detect thread ending\n// (and used with MI_TLS_PTHREADS for the default theap)\npthread_key_t _mi_heap_default_key = (pthread_key_t)(-1);\n\nstatic void mi_pthread_done(void* value) {\n  if (value!=NULL) {\n    _mi_thread_done((mi_theap_t*)value);\n  }\n}\n\nvoid _mi_prim_thread_init_auto_done(void) {\n  mi_assert_internal(_mi_heap_default_key == (pthread_key_t)(-1));\n  pthread_key_create(&_mi_heap_default_key, &mi_pthread_done);\n}\n\nvoid _mi_prim_thread_done_auto_done(void) {\n  if (_mi_heap_default_key != (pthread_key_t)(-1)) {  // do not leak the key, see issue #809\n    pthread_key_delete(_mi_heap_default_key);\n  }\n}\n\nvoid _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {\n  if (_mi_heap_default_key != (pthread_key_t)(-1)) {  // can happen during recursive invocation on freeBSD\n    pthread_setspecific(_mi_heap_default_key, theap);\n  }\n}\n\n#else\n\nvoid _mi_prim_thread_init_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_done_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {\n  MI_UNUSED(theap);\n}\n#endif\n\nbool _mi_prim_thread_is_in_threadpool(void) {\n  return false;\n}\n\nvoid _mi_prim_thread_yield(void) {\n  sched_yield();\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/prim/osx/alloc-override-zone.c",
      "sha256": "ce14eb6dfd55f241095b55f70983931a2d92f7a6a622a9b360cdd70ab3b53208",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2022, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n\n#if defined(MI_MALLOC_OVERRIDE)\n\n#if !defined(__APPLE__)\n#error \"this file should only be included on macOS\"\n#endif\n\n/* ------------------------------------------------------\n   Override system malloc on macOS\n   This is done through the malloc zone interface.\n   It seems to be most robust in combination with interposing\n   though or otherwise we may get zone errors as there are could\n   be allocations done by the time we take over the\n   zone.\n------------------------------------------------------ */\n\n#include <AvailabilityMacros.h>\n#include <malloc/malloc.h>\n#include <string.h>  // memset\n#include <stdlib.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)\n// only available from OSX 10.6\nextern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_import));\n#endif\n\n/* ------------------------------------------------------\n   malloc zone members\n------------------------------------------------------ */\n\nstatic bool is_mimalloc_zone( malloc_zone_t* zone ); \n\nstatic size_t zone_size(malloc_zone_t* zone, const void* p) {\n  if (mi_any_heap_contains(p)) { \n    return mi_usable_size(p);\n  }\n  else if (!is_mimalloc_zone(zone)) {  // can happen due to interpose\n    return zone->size(zone,p);\n  }\n  else {\n    return 0;\n  }\n}\n\nstatic void* zone_malloc(malloc_zone_t* zone, size_t size) {\n  MI_UNUSED(zone);\n  return mi_malloc(size);\n}\n\nstatic void* zone_calloc(malloc_zone_t* zone, size_t count, size_t size) {\n  MI_UNUSED(zone);\n  return mi_calloc(count, size);\n}\n\nstatic void* zone_valloc(malloc_zone_t* zone, size_t size) {\n  MI_UNUSED(zone);\n  return mi_malloc_aligned(size, _mi_os_page_size());\n}\n\nstatic void zone_free(malloc_zone_t* zone, void* p) {\n  if (mi_any_heap_contains(p)) {\n    mi_free(p); // with the page_map and pagemap_commit=1 we can use the regular free\n  }\n  else if (!is_mimalloc_zone(zone)) {  // can happen due to interpose\n    zone->free(zone,p);\n  }\n}\n\nstatic void* zone_realloc(malloc_zone_t* zone, void* p, size_t newsize) {\n  if (p == NULL || mi_any_heap_contains(p)) {\n    return mi_realloc(p, newsize);\n  }\n  else if (!is_mimalloc_zone(zone)) {  // can happen due to interpose\n    return zone->realloc(zone,p,newsize);\n  }\n  else {\n    return NULL;\n  }\n}\n\nstatic void* zone_memalign(malloc_zone_t* zone, size_t alignment, size_t size) {\n  MI_UNUSED(zone);\n  return mi_malloc_aligned(size,alignment);\n}\n\nstatic void zone_destroy(malloc_zone_t* zone) {\n  if (!is_mimalloc_zone(zone)) {\n    zone->destroy(zone);\n  }\n}\n\nstatic unsigned zone_batch_malloc(malloc_zone_t* zone, size_t size, void** ps, unsigned count) {\n  unsigned i;\n  for (i = 0; i < count; i++) {\n    ps[i] = zone_malloc(zone, size);\n    if (ps[i] == NULL) break;\n  }\n  return i;\n}\n\nstatic void zone_batch_free(malloc_zone_t* zone, void** ps, unsigned count) {\n  for(size_t i = 0; i < count; i++) {\n    zone_free(zone, ps[i]);\n    ps[i] = NULL;\n  }\n}\n\nstatic size_t zone_pressure_relief(malloc_zone_t* zone, size_t size) {\n  MI_UNUSED(zone); MI_UNUSED(size);\n  mi_collect(false);\n  return 0;\n}\n\nstatic void zone_free_definite_size(malloc_zone_t* zone, void* p, size_t size) {\n  MI_UNUSED(size);\n  zone_free(zone,p);\n}\n\nstatic boolean_t zone_claimed_address(malloc_zone_t* zone, void* p) {\n  MI_UNUSED(zone);\n  return mi_is_in_heap_region(p);\n}\n\n\n/* ------------------------------------------------------\n   Introspection members\n------------------------------------------------------ */\n\nstatic kern_return_t intro_enumerator(task_t task, void* p,\n                            unsigned type_mask, vm_address_t zone_address,\n                            memory_reader_t reader,\n                            vm_range_recorder_t recorder)\n{\n  // todo: enumerate all memory\n  MI_UNUSED(task); MI_UNUSED(p); MI_UNUSED(type_mask); MI_UNUSED(zone_address);\n  MI_UNUSED(reader); MI_UNUSED(recorder);\n  return KERN_SUCCESS;\n}\n\nstatic size_t intro_good_size(malloc_zone_t* zone, size_t size) {\n  MI_UNUSED(zone);\n  return mi_good_size(size);\n}\n\nstatic boolean_t intro_check(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  return true;\n}\n\nstatic void intro_print(malloc_zone_t* zone, boolean_t verbose) {\n  MI_UNUSED(zone); MI_UNUSED(verbose);\n  mi_stats_print(NULL);\n}\n\nstatic void intro_log(malloc_zone_t* zone, void* p) {\n  MI_UNUSED(zone); MI_UNUSED(p);\n  // todo?\n}\n\nstatic void intro_force_lock(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  // todo?\n}\n\nstatic void intro_force_unlock(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  // todo?\n}\n\nstatic void intro_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) {\n  MI_UNUSED(zone);\n  // todo...\n  stats->blocks_in_use = 0;\n  stats->size_in_use = 0;\n  stats->max_size_in_use = 0;\n  stats->size_allocated = 0;\n}\n\nstatic boolean_t intro_zone_locked(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  return false;\n}\n\n\n/* ------------------------------------------------------\n  At process start, override the default allocator\n------------------------------------------------------ */\n\n#if defined(__GNUC__) && !defined(__clang__)\n#pragma GCC diagnostic ignored \"-Wmissing-field-initializers\"\n#endif\n\n#if defined(__clang__)\n#pragma clang diagnostic ignored \"-Wc99-extensions\"\n#endif\n\nstatic malloc_introspection_t mi_introspect = {\n  .enumerator = &intro_enumerator,\n  .good_size = &intro_good_size,\n  .check = &intro_check,\n  .print = &intro_print,\n  .log = &intro_log,\n  .force_lock = &intro_force_lock,\n  .force_unlock = &intro_force_unlock,\n#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) && !defined(__ppc__)\n  .statistics = &intro_statistics,\n  .zone_locked = &intro_zone_locked,\n#endif\n};\n\nstatic malloc_zone_t mi_malloc_zone = {\n  // note: even with designators, the order is important for C++ compilation\n  //.reserved1 = NULL,\n  //.reserved2 = NULL,\n  .size = &zone_size,\n  .malloc = &zone_malloc,\n  .calloc = &zone_calloc,\n  .valloc = &zone_valloc,\n  .free = &zone_free,\n  .realloc = &zone_realloc,\n  .destroy = &zone_destroy,\n  .zone_name = \"mimalloc\",\n  .batch_malloc = &zone_batch_malloc,\n  .batch_free = &zone_batch_free,\n  .introspect = &mi_introspect,\n#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) && !defined(__ppc__)\n  #if defined(MAC_OS_X_VERSION_10_14) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14)\n  .version = 10,\n  #else\n  .version = 9,\n  #endif\n  // switch to version 9+ on OSX 10.6 to support memalign.\n  .memalign = &zone_memalign,\n  .free_definite_size = &zone_free_definite_size,\n  #if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)\n  .pressure_relief = &zone_pressure_relief,\n  #endif\n  #if defined(MAC_OS_X_VERSION_10_14) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14)\n  .claimed_address = &zone_claimed_address,\n  #endif\n#else\n  .version = 4,\n#endif\n};\n\n#ifdef __cplusplus\n}\n#endif\n\nstatic bool is_mimalloc_zone( malloc_zone_t* zone ) {\n  return (zone==NULL || zone==&mi_malloc_zone);\n}\n\n#if defined(MI_OSX_INTERPOSE) && defined(MI_SHARED_LIB_EXPORT)\n\n// ------------------------------------------------------\n// Override malloc_xxx and malloc_zone_xxx api's to use only\n// our mimalloc zone. Since even the loader uses malloc\n// on macOS, this ensures that all allocations go through\n// mimalloc (as all calls are interposed).\n// The main `malloc`, `free`, etc calls are interposed in `alloc-override.c`,\n// Here, we also override macOS specific API's like\n// `malloc_zone_calloc` etc. see <https://github.com/aosm/libmalloc/blob/master/man/malloc_zone_malloc.3>\n// ------------------------------------------------------\n\nstatic inline malloc_zone_t* mi_get_default_zone(void) {\n  mi_atomic_do_once {\n    malloc_zone_register(&mi_malloc_zone);  // by calling register we avoid a zone error on free (see <http://eatmyrandom.blogspot.com/2010/03/mallocfree-interception-on-mac-os-x.html>)\n  }\n  return &mi_malloc_zone;\n}\n\nmi_decl_externc int  malloc_jumpstart(uintptr_t cookie);\nmi_decl_externc void _malloc_fork_prepare(void);\nmi_decl_externc void _malloc_fork_parent(void);\nmi_decl_externc void _malloc_fork_child(void);\n\n\nstatic malloc_zone_t* mi_malloc_create_zone(vm_size_t size, unsigned flags) {\n  MI_UNUSED(size); MI_UNUSED(flags);\n  return mi_get_default_zone();\n}\n\nstatic malloc_zone_t* mi_malloc_default_zone (void) {\n  return mi_get_default_zone();\n}\n\nstatic malloc_zone_t* mi_malloc_default_purgeable_zone(void) {\n  return mi_get_default_zone();\n}\n\nstatic void mi_malloc_destroy_zone(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  // nothing.\n}\n\nstatic kern_return_t mi_malloc_get_all_zones (task_t task, memory_reader_t mr, vm_address_t** addresses, unsigned* count) {\n  MI_UNUSED(task); MI_UNUSED(mr);\n  if (addresses != NULL) *addresses = NULL;\n  if (count != NULL) *count = 0;\n  return KERN_SUCCESS;\n}\n\nstatic const char* mi_malloc_get_zone_name(malloc_zone_t* zone) {\n  return (zone == NULL ? mi_malloc_zone.zone_name : zone->zone_name);\n}\n\nstatic void mi_malloc_set_zone_name(malloc_zone_t* zone, const char* name) {\n  MI_UNUSED(zone); MI_UNUSED(name);\n}\n\nstatic int mi_malloc_jumpstart(uintptr_t cookie) {\n  MI_UNUSED(cookie);\n  return 1; // or 0 for no error?\n}\n\nstatic void mi__malloc_fork_prepare(void) {\n  // nothing\n}\nstatic void mi__malloc_fork_parent(void) {\n  // nothing\n}\nstatic void mi__malloc_fork_child(void) {\n  // nothing\n}\n\nstatic void mi_malloc_printf(const char* fmt, ...) {\n  MI_UNUSED(fmt);\n}\n\nstatic bool zone_check(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n  return true;\n}\n\nstatic malloc_zone_t* zone_from_ptr(const void* p) {\n  MI_UNUSED(p);\n  return (mi_any_heap_contains(p) ? mi_get_default_zone() : NULL);\n}\n\nstatic void zone_log(malloc_zone_t* zone, void* p) {\n  MI_UNUSED(zone); MI_UNUSED(p);\n}\n\nstatic void zone_print(malloc_zone_t* zone, bool b) {\n  MI_UNUSED(zone); MI_UNUSED(b);\n}\n\nstatic void zone_print_ptr_info(void* p) {\n  MI_UNUSED(p);\n}\n\nstatic void zone_register(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n}\n\nstatic void zone_unregister(malloc_zone_t* zone) {\n  MI_UNUSED(zone);\n}\n\n// use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1`\n// See: <https://books.google.com/books?id=K8vUkpOXhN4C&pg=PA73>\nstruct mi_interpose_s {\n  const void* replacement;\n  const void* target;\n};\n#define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun }\n#define MI_INTERPOSE_MI(fun)            MI_INTERPOSE_FUN(fun,mi_##fun)\n#define MI_INTERPOSE_ZONE(fun)          MI_INTERPOSE_FUN(malloc_##fun,fun)\n__attribute__((used)) static const struct mi_interpose_s _mi_zone_interposes[]  __attribute__((section(\"__DATA, __interpose\"))) =\n{\n\n  MI_INTERPOSE_MI(malloc_create_zone),\n  MI_INTERPOSE_MI(malloc_default_purgeable_zone),\n  MI_INTERPOSE_MI(malloc_default_zone),\n  MI_INTERPOSE_MI(malloc_destroy_zone),\n  MI_INTERPOSE_MI(malloc_get_all_zones),\n  MI_INTERPOSE_MI(malloc_get_zone_name),\n  MI_INTERPOSE_MI(malloc_jumpstart),\n  MI_INTERPOSE_MI(malloc_printf),\n  MI_INTERPOSE_MI(malloc_set_zone_name),\n  MI_INTERPOSE_MI(_malloc_fork_child),\n  MI_INTERPOSE_MI(_malloc_fork_parent),\n  MI_INTERPOSE_MI(_malloc_fork_prepare),\n\n  MI_INTERPOSE_ZONE(zone_batch_free),\n  MI_INTERPOSE_ZONE(zone_batch_malloc),\n  MI_INTERPOSE_ZONE(zone_calloc),\n  MI_INTERPOSE_ZONE(zone_check),\n  MI_INTERPOSE_ZONE(zone_free),\n  MI_INTERPOSE_ZONE(zone_from_ptr),\n  MI_INTERPOSE_ZONE(zone_log),\n  MI_INTERPOSE_ZONE(zone_malloc),\n  MI_INTERPOSE_ZONE(zone_memalign),\n  MI_INTERPOSE_ZONE(zone_print),\n  MI_INTERPOSE_ZONE(zone_print_ptr_info),\n  MI_INTERPOSE_ZONE(zone_realloc),\n  MI_INTERPOSE_ZONE(zone_register),\n  MI_INTERPOSE_ZONE(zone_unregister),\n  MI_INTERPOSE_ZONE(zone_valloc)\n};\n\n\n#else\n\n// ------------------------------------------------------\n// hook into the zone api's without interposing\n// This is the official way of adding an allocator but\n// it seems less robust than using interpose.\n// ------------------------------------------------------\n\nstatic inline malloc_zone_t* mi_get_default_zone(void)\n{\n  // The first returned zone is the real default\n  malloc_zone_t** zones = NULL;\n  unsigned count = 0;\n  kern_return_t ret = malloc_get_all_zones(0, NULL, (vm_address_t**)&zones, &count);\n  if (ret == KERN_SUCCESS && count > 0) {\n    return zones[0];\n  }\n  else {\n    // fallback\n    return malloc_default_zone();\n  }\n}\n\n#if defined(__clang__)\n__attribute__((constructor(101))) // highest priority\n#else\n__attribute__((constructor))      // priority level is not supported by gcc\n#endif\n__attribute__((used))\nstatic void _mi_macos_override_malloc(void) {\n  malloc_zone_t* purgeable_zone = NULL;\n\n  #if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)\n  // force the purgeable zone to exist to avoid strange bugs\n  if (malloc_default_purgeable_zone) {\n    purgeable_zone = malloc_default_purgeable_zone();\n  }\n  #endif\n\n  // Register our zone.\n  // thomcc: I think this is still needed to put us in the zone list.\n  malloc_zone_register(&mi_malloc_zone);\n  // Unregister the default zone, this makes our zone the new default\n  // as that was the last registered.\n  malloc_zone_t *default_zone = mi_get_default_zone();\n  // thomcc: Unsure if the next test is *always* false or just false in the\n  // cases I've tried. I'm also unsure if the code inside is needed. at all\n  if (default_zone != &mi_malloc_zone) {\n    malloc_zone_unregister(default_zone);\n\n    // Reregister the default zone so free and realloc in that zone keep working.\n    malloc_zone_register(default_zone);\n  }\n\n  // Unregister, and re-register the purgeable_zone to avoid bugs if it occurs\n  // earlier than the default zone.\n  if (purgeable_zone != NULL) {\n    malloc_zone_unregister(purgeable_zone);\n    malloc_zone_register(purgeable_zone);\n  }\n\n}\n#endif  // MI_OSX_INTERPOSE\n\n#endif // MI_MALLOC_OVERRIDE\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/prim/osx/prim.c",
      "sha256": "247a9952465eb105be03a9962e922b085ce5d52034775551a61cd8594275be73",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// We use the unix/prim.c with the mmap API on macOSX\n#include \"../unix/prim.c\"\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/prim/prim.c",
      "sha256": "cc771788e5ba591efb681829a8724f8662a1f50f3db39cf5ebe7738b8ed57e44",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// Select the implementation of the primitives\n// depending on the OS.\n\n#if defined(_WIN32)\n#include \"windows/prim.c\"  // VirtualAlloc (Windows)\n\n#elif defined(__APPLE__)\n#include \"osx/prim.c\"      // macOSX (actually defers to mmap in unix/prim.c)\n\n#elif defined(__wasi__)\n#define MI_USE_SBRK\n#include \"wasi/prim.c\"     // memory-grow or sbrk (Wasm)\n\n#elif defined(__EMSCRIPTEN__)\n#include \"emscripten/prim.c\" // emmalloc_*, + pthread support\n\n#else\n#include \"unix/prim.c\"     // mmap() (Linux, macOSX, BSD, Illumnos, Haiku, DragonFly, etc.)\n\n#endif\n\n// Generic process initialization\n#ifndef MI_PRIM_HAS_PROCESS_ATTACH\n#if defined(__GNUC__) || defined(__clang__)\n  // gcc,clang: use the constructor/destructor attribute\n  // which for both seem to run before regular constructors/destructors\n  #if defined(__clang__)\n    #define mi_attr_constructor __attribute__((constructor(101)))\n    #define mi_attr_destructor  __attribute__((destructor(101)))\n  #else\n    #define mi_attr_constructor __attribute__((constructor))\n    #define mi_attr_destructor  __attribute__((destructor))\n  #endif\n  static void mi_attr_constructor mi_process_attach(void) {\n    _mi_auto_process_init();\n  }\n  static void mi_attr_destructor mi_process_detach(void) {\n    _mi_auto_process_done();\n  }\n#elif defined(__cplusplus)\n  // C++: use static initialization to detect process start/end\n  // This is not guaranteed to be first/last but the best we can generally do?\n  struct mi_init_done_t {\n    mi_init_done_t() {\n      _mi_auto_process_init();\n    }\n    ~mi_init_done_t() {\n      _mi_auto_process_done();\n    }\n  };\n  static mi_init_done_t mi_init_done;\n #else\n  #pragma message(\"define a way to call _mi_auto_process_init/done on your platform\")\n#endif\n#endif\n\n// Generic allocator init/done callback\n#ifndef MI_PRIM_HAS_ALLOCATOR_INIT\nbool _mi_is_redirected(void) {\n  return false;\n}\nbool _mi_allocator_init(const char** message) {\n  if (message != NULL) { *message = NULL; }\n  return true;\n}\nvoid _mi_allocator_done(void) {\n  // nothing to do\n}\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/prim/unix/prim.c",
      "sha256": "c1ae32eaac7ccf18c10058cca99723892f8bd027318590151f5011c929c7e3be",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// This file is included in `src/prim/prim.c`\n\n#ifndef _DEFAULT_SOURCE\n#define _DEFAULT_SOURCE   // ensure mmap flags and syscall are defined\n#endif\n\n#if defined(__sun)\n// illumos provides new mman.h api when any of these are defined\n// otherwise the old api based on caddr_t which predates the void pointers one.\n// stock solaris provides only the former, chose to atomically to discard those\n// flags only here rather than project wide tough.\n#undef _XOPEN_SOURCE\n#undef _POSIX_C_SOURCE\n#endif\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"\n\n#include <sys/mman.h>  // mmap\n#include <unistd.h>    // sysconf, sleep\n#include <fcntl.h>     // open, close, read, access\n#include <stdlib.h>    // getenv, arc4random_buf\n\n#if defined(__linux__)\n  #include <features.h>\n  #include <sys/prctl.h>    // THP disable, PR_SET_VMA\n  #include <sys/sysinfo.h>  // sysinfo\n  #if defined(__GLIBC__) && !defined(PR_SET_VMA)\n  #include <linux/prctl.h>\n  #endif\n  #if defined(__GLIBC__)\n  #include <linux/mman.h>   // linux mmap flags\n  #else\n  #include <sys/mman.h>\n  #endif\n#elif defined(__APPLE__)\n  #include <AvailabilityMacros.h>\n  #include <TargetConditionals.h>\n  #if !defined(TARGET_OS_OSX) || TARGET_OS_OSX   // see issue #879, used to be (!TARGET_IOS_IPHONE && !TARGET_IOS_SIMULATOR)\n  #include <mach/vm_statistics.h>    // VM_MAKE_TAG, VM_FLAGS_SUPERPAGE_SIZE_2MB, etc.\n  #endif\n  #if !defined(MAC_OS_X_VERSION_10_7)\n  #define MAC_OS_X_VERSION_10_7   1070\n  #endif\n  #include <sys/sysctl.h>\n#elif defined(__FreeBSD__) || defined(__DragonFly__)\n  #include <sys/param.h>\n  #if __FreeBSD_version >= 1200000\n  #include <sys/cpuset.h>\n  #include <sys/domainset.h>\n  #endif\n  #include <sys/sysctl.h>\n#endif\n\n#if (defined(__linux__) && !defined(__ANDROID__)) || defined(__FreeBSD__)\n  #define MI_HAS_SYSCALL_H\n  #include <sys/syscall.h>\n#endif\n\n#if !defined(MADV_DONTNEED) && defined(POSIX_MADV_DONTNEED)  // QNX\n#define MADV_DONTNEED  POSIX_MADV_DONTNEED\n#endif\n#if !defined(MADV_FREE) && defined(POSIX_MADV_FREE)  // QNX\n#define MADV_FREE  POSIX_MADV_FREE\n#endif\n\n#define MI_UNIX_LARGE_PAGE_SIZE (2*MI_MiB) // TODO: can we query the OS for this?\n\n//------------------------------------------------------------------------------------\n// Use syscalls for some primitives to allow for libraries that override open/read/close etc.\n// and do allocation themselves; using syscalls prevents recursion when mimalloc is\n// still initializing (issue #713)\n// Declare inline to avoid unused function warnings.\n//------------------------------------------------------------------------------------\n\n#if defined(MI_HAS_SYSCALL_H) && defined(SYS_open) && defined(SYS_close) && defined(SYS_read) && defined(SYS_access)\n\nstatic inline int mi_prim_open(const char* fpath, int open_flags) {\n  return syscall(SYS_open,fpath,open_flags,0);\n}\nstatic inline ssize_t mi_prim_read(int fd, void* buf, size_t bufsize) {\n  return syscall(SYS_read,fd,buf,bufsize);\n}\nstatic inline int mi_prim_close(int fd) {\n  return syscall(SYS_close,fd);\n}\nstatic inline int mi_prim_access(const char *fpath, int mode) {\n  return syscall(SYS_access,fpath,mode);\n}\n\n#else\n\nstatic inline int mi_prim_open(const char* fpath, int open_flags) {\n  return open(fpath,open_flags);\n}\nstatic inline ssize_t mi_prim_read(int fd, void* buf, size_t bufsize) {\n  return read(fd,buf,bufsize);\n}\nstatic inline int mi_prim_close(int fd) {\n  return close(fd);\n}\nstatic inline int mi_prim_access(const char *fpath, int mode) {\n  return access(fpath,mode);\n}\n\n#endif\n\n\n\n//---------------------------------------------\n// init\n//---------------------------------------------\n\nstatic bool unix_detect_overcommit(void) {\n  bool os_overcommit = true;\n  #if defined(__linux__)\n    int fd = mi_prim_open(\"/proc/sys/vm/overcommit_memory\", O_RDONLY);\n    if (fd >= 0) {\n      char buf[32];\n      ssize_t nread = mi_prim_read(fd, &buf, sizeof(buf));\n      mi_prim_close(fd);\n      // <https://www.kernel.org/doc/Documentation/vm/overcommit-accounting>\n      // 0: heuristic overcommit, 1: always overcommit, 2: never overcommit (ignore NORESERVE)\n      if (nread >= 1) {\n        os_overcommit = (buf[0] == '0' || buf[0] == '1');\n      }\n    }\n  #elif defined(__FreeBSD__)\n    int val = 0;\n    size_t olen = sizeof(val);\n    if (sysctlbyname(\"vm.overcommit\", &val, &olen, NULL, 0) == 0) {\n      os_overcommit = (val != 0);\n    }\n  #else\n    // default: overcommit is true\n  #endif\n  return os_overcommit;\n}\n\nstatic bool unix_detect_thp(void) {\n  bool thp_enabled = false;\n  #if defined(__linux__)\n  int fd = mi_prim_open(\"/sys/kernel/mm/transparent_hugepage/enabled\", O_RDONLY);\n  if (fd >= 0) {\n    char buf[32];\n    ssize_t nread = mi_prim_read(fd, &buf, sizeof(buf));\n    mi_prim_close(fd);\n    // <https://www.kernel.org/doc/html/latest/admin-guide/mm/transhuge.html>\n    // between brackets is the current value, for example: always [madvise] never\n    if (nread >= 1) {\n      thp_enabled = (_mi_strnstr(buf,32,\"[never]\") == NULL);\n    }\n  }\n  #endif\n  return thp_enabled;\n}\n\n// try to detect the physical memory dynamically (if possible)\nstatic void unix_detect_physical_memory( size_t page_size, size_t* physical_memory_in_kib ) {\n  #if defined(CTL_HW) && (defined(HW_PHYSMEM64) || defined(HW_MEMSIZE))  // freeBSD, macOS\n    MI_UNUSED(page_size);\n    int64_t physical_memory = 0;\n    size_t length = sizeof(int64_t);\n    #if defined(HW_PHYSMEM64)\n    int mib[2] = { CTL_HW, HW_PHYSMEM64 };\n    #else\n    int mib[2] = { CTL_HW, HW_MEMSIZE };\n    #endif\n    const int err = sysctl(mib, 2, &physical_memory, &length, NULL, 0);\n    if (err==0 && physical_memory > 0) {\n      const int64_t phys_in_kib = physical_memory / MI_KiB;\n      if (phys_in_kib > 0 && (uint64_t)phys_in_kib <= SIZE_MAX) {\n        *physical_memory_in_kib = (size_t)phys_in_kib;\n      }\n    }\n  #elif defined(__linux__)\n    MI_UNUSED(page_size);\n    struct sysinfo info; _mi_memzero_var(info);\n    const int err = sysinfo(&info);\n    if (err==0 && info.mem_unit > 0 && info.totalram <= SIZE_MAX) {\n      if (info.mem_unit==MI_KiB) {\n        *physical_memory_in_kib = (size_t)info.totalram;\n      }\n      else {\n        size_t total = 0;\n        if (!mi_mul_overflow((size_t)info.totalram, (size_t)info.mem_unit, &total)) {\n          *physical_memory_in_kib = (total / MI_KiB);\n        }\n      }\n    }\n  #elif defined(_SC_PHYS_PAGES)  // do not use by default as it might cause allocation (by using `fopen` to parse /proc/meminfo) (issue #1100)\n    const long pphys = sysconf(_SC_PHYS_PAGES);\n    const size_t psize_in_kib = page_size / MI_KiB;\n    if (psize_in_kib > 0 && pphys > 0 && (unsigned long)pphys <= SIZE_MAX && (size_t)pphys <= (SIZE_MAX/psize_in_kib)) {\n      *physical_memory_in_kib = (size_t)pphys * psize_in_kib;\n    }\n  #endif\n}\n\nvoid _mi_prim_mem_init( mi_os_mem_config_t* config )\n{\n  long psize = sysconf(_SC_PAGESIZE);\n  if (psize > 0 && (unsigned long)psize < SIZE_MAX) {\n    config->page_size = (size_t)psize;\n    config->alloc_granularity = (size_t)psize;\n    unix_detect_physical_memory(config->page_size, &config->physical_memory_in_kib);\n  }\n  config->large_page_size = MI_UNIX_LARGE_PAGE_SIZE;\n  config->has_overcommit = unix_detect_overcommit();\n  config->has_partial_free = true;    // mmap can free in parts\n  config->has_virtual_reserve = true; // todo: check if this true for NetBSD?  (for anonymous mmap with PROT_NONE)\n  config->has_transparent_huge_pages = unix_detect_thp();\n\n  // disable transparent huge pages for this process?\n  #if (defined(__linux__) || defined(__ANDROID__)) && defined(PR_GET_THP_DISABLE)\n  if (!mi_option_is_enabled(mi_option_allow_thp)) // disable THP if requested through an option\n  {\n    config->has_transparent_huge_pages = false;\n    if (prctl(PR_GET_THP_DISABLE, 0, 0, 0, 0) == 0) {   // -1 on error, 1 if already disabled\n      // Most likely since distros often come with always/madvise settings.\n      // Disabling only for mimalloc process rather than touching system wide settings\n      (void)prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0);\n    }\n  }\n  #endif\n}\n\n\n//---------------------------------------------\n// free\n//---------------------------------------------\n\nint _mi_prim_free(void* addr, size_t size ) {\n  if (size==0) return 0;\n  bool err = (munmap(addr, size) == -1);\n  return (err ? errno : 0);\n}\n\n\n//---------------------------------------------\n// mmap\n//---------------------------------------------\n\n// return errno on failure\nstatic int unix_madvise(void* addr, size_t size, int advice) {\n  #if defined(__sun)\n  const int res = madvise((caddr_t)addr, size, advice);  // Solaris needs cast (issue #520)\n  return (res==0 ? 0 : errno);\n  #elif defined(__QNX__)\n  return posix_madvise(addr, size, advice);              // posix returns errno\n  #else\n  const int res = madvise(addr, size, advice);           // linux returns -1 on failure and sets errno\n  return (res==0 ? 0 : errno);\n  #endif\n}\n\nstatic void* unix_mmap_prim(void* addr, size_t size, int protect_flags, int flags, int fd) {\n  void* p = mmap(addr, size, protect_flags, flags, fd, 0 /* offset */);\n  #if defined(__linux__) && defined(PR_SET_VMA)\n  if (p!=MAP_FAILED && p!=NULL) {\n    prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, p, size, \"mimalloc\");\n  }\n  #endif\n  return p;\n}\n\nstatic void* unix_mmap_prim_aligned(void* addr, size_t size, size_t try_alignment, int protect_flags, int flags, int fd) {\n  MI_UNUSED(try_alignment);\n  void* p = NULL;\n  #if defined(MAP_ALIGNED)  // BSD\n  if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) {\n    size_t n = 0;\n    mi_bsr(try_alignment, &n);\n    if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) {  // alignment is a power of 2 and 4096 <= alignment <= 1GiB\n      p = unix_mmap_prim(addr, size, protect_flags, flags | MAP_ALIGNED(n), fd);\n      if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) {\n        int err = errno;\n        _mi_trace_message(\"unable to directly request aligned OS memory (error: %d (0x%x), size: 0x%zx bytes, alignment: 0x%zx, hint address: %p)\\n\", err, err, size, try_alignment, addr);\n      }\n      if (p!=MAP_FAILED) return p;\n      // fall back to regular mmap\n    }\n  }\n  #elif defined(MAP_ALIGN)  // Solaris\n  if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) {\n    p = unix_mmap_prim((void*)try_alignment, size, protect_flags, flags | MAP_ALIGN, fd);  // addr parameter is the required alignment\n    if (p!=MAP_FAILED) return p;\n    // fall back to regular mmap\n  }\n  #endif\n  #if (MI_INTPTR_SIZE >= 8) && !defined(MAP_ALIGNED)\n  // on 64-bit systems, use the virtual address area after 2TiB for 4MiB aligned allocations\n  if (addr == NULL) {\n    void* hint = _mi_os_get_aligned_hint(try_alignment, size);\n    if (hint != NULL) {\n      p = unix_mmap_prim(hint, size, protect_flags, flags, fd);\n      if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) {\n        #if MI_TRACK_ENABLED  // asan sometimes does not instrument errno correctly?\n        int err = 0;\n        #else\n        int err = errno;\n        #endif\n        _mi_trace_message(\"unable to directly request hinted aligned OS memory (error: %d (0x%x), size: 0x%zx bytes, alignment: 0x%zx, hint address: %p)\\n\", err, err, size, try_alignment, hint);\n      }\n      if (p!=MAP_FAILED) return p;\n      // fall back to regular mmap\n    }\n  }\n  #endif\n  // regular mmap\n  p = unix_mmap_prim(addr, size, protect_flags, flags, fd);\n  if (p!=MAP_FAILED) return p;\n  // failed to allocate\n  return NULL;\n}\n\nstatic int unix_mmap_fd(void) {\n  #if defined(VM_MAKE_TAG)\n  // macOS: tracking anonymous page with a specific ID. (All up to 98 are taken officially but LLVM sanitizers had taken 99)\n  int os_tag = (int)mi_option_get(mi_option_os_tag);\n  if (os_tag < 100 || os_tag > 255) { os_tag = 254; }\n  return VM_MAKE_TAG(os_tag);\n  #else\n  return -1;\n  #endif\n}\n\nstatic void* unix_mmap(void* addr, size_t size, size_t try_alignment, int protect_flags, bool large_only, bool allow_large, bool* is_large) {\n  #if !defined(MAP_ANONYMOUS)\n  #define MAP_ANONYMOUS  MAP_ANON\n  #endif\n  #if !defined(MAP_NORESERVE)\n  #define MAP_NORESERVE  0\n  #endif\n  void* p = NULL;\n  const int fd = unix_mmap_fd();\n  int flags = MAP_PRIVATE | MAP_ANONYMOUS;\n  if (_mi_os_has_overcommit()) {\n    flags |= MAP_NORESERVE;\n  }\n  #if defined(PROT_MAX)\n  protect_flags |= PROT_MAX(PROT_READ | PROT_WRITE); // BSD\n  #endif\n  // huge page allocation\n  if (allow_large && (large_only || (_mi_os_canuse_large_page(size, try_alignment) && mi_option_is_enabled(mi_option_allow_large_os_pages)))) {\n    static _Atomic(size_t) large_page_try_ok; // = 0;\n    size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok);\n    if (!large_only && try_ok > 0) {\n      // If the OS is not configured for large OS pages, or the user does not have\n      // enough permission, the `mmap` will always fail (but it might also fail for other reasons).\n      // Therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times\n      // to avoid too many failing calls to mmap.\n      mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1);\n    }\n    else {\n      int lflags = flags & ~MAP_NORESERVE;  // using NORESERVE on huge pages seems to fail on Linux\n      int lfd = fd;\n      #ifdef MAP_ALIGNED_SUPER\n      lflags |= MAP_ALIGNED_SUPER;\n      #endif\n      #ifdef MAP_HUGETLB\n      lflags |= MAP_HUGETLB;\n      #endif\n      #ifdef MAP_HUGE_1GB\n      static bool mi_huge_pages_available = true;\n      if (large_only && (size % MI_GiB) == 0 && mi_huge_pages_available) {\n        lflags |= MAP_HUGE_1GB;\n      }\n      else\n      #endif\n      {\n        #ifdef MAP_HUGE_2MB\n        lflags |= MAP_HUGE_2MB;\n        #endif\n      }\n      #ifdef VM_FLAGS_SUPERPAGE_SIZE_2MB\n      lfd |= VM_FLAGS_SUPERPAGE_SIZE_2MB;\n      #endif\n      if (large_only || lflags != flags) {\n        // try large OS page allocation\n        *is_large = true;\n        p = unix_mmap_prim_aligned(addr, size, try_alignment, protect_flags, lflags, lfd);\n        #ifdef MAP_HUGE_1GB\n        if (p == NULL && (lflags & MAP_HUGE_1GB) == MAP_HUGE_1GB) {\n          mi_huge_pages_available = false; // don't try huge 1GiB pages again\n          if (large_only) {\n            _mi_warning_message(\"unable to allocate huge (1GiB) page, trying large (2MiB) pages instead (errno: %i)\\n\", errno);\n          }\n          lflags = ((lflags & ~MAP_HUGE_1GB) | MAP_HUGE_2MB);\n          p = unix_mmap_prim_aligned(addr, size, try_alignment, protect_flags, lflags, lfd);\n        }\n        #endif\n        if (large_only) return p;\n        if (p == NULL) {\n          mi_atomic_store_release(&large_page_try_ok, (size_t)8);  // on error, don't try again for the next N allocations\n        }\n      }\n    }\n  }\n  // regular allocation\n  if (p == NULL) {\n    *is_large = false;\n    p = unix_mmap_prim_aligned(addr, size, try_alignment, protect_flags, flags, fd);\n    #if !defined(MI_NO_THP)\n    if (p != NULL && allow_large && mi_option_is_enabled(mi_option_allow_thp) && _mi_os_canuse_large_page(size, try_alignment)) {\n      #if defined(MADV_HUGEPAGE)\n      // Many Linux systems don't allow MAP_HUGETLB but they support instead\n      // transparent huge pages (THP). Generally, it is not required to call `madvise` with MADV_HUGE\n      // though since properly aligned allocations will already use large pages if available\n      // in that case -- in particular for our large regions (in `memory.c`).\n      // However, some systems only allow THP if called with explicit `madvise`, so\n      // when large OS pages are enabled for mimalloc, we call `madvise` anyways.\n      if (unix_madvise(p, size, MADV_HUGEPAGE) == 0) {\n        // *is_large = true; // possibly\n      };\n      #elif defined(__sun)\n      struct memcntl_mha cmd = {0};\n      cmd.mha_pagesize = _mi_os_large_page_size();\n      cmd.mha_cmd = MHA_MAPSIZE_VA;\n      if (memcntl((caddr_t)p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) {\n        // *is_large = true; // possibly\n      }\n      #endif\n    }\n    #endif\n  }\n  return p;\n}\n\n// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.\nint _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) {\n  mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);\n  mi_assert_internal(commit || !allow_large);\n  mi_assert_internal(try_alignment > 0);\n  *is_zero = true;\n  int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : PROT_NONE);\n  *addr = unix_mmap(hint_addr, size, try_alignment, protect_flags, false, allow_large, is_large);\n  return (*addr != NULL ? 0 : errno);\n}\n\n\n//---------------------------------------------\n// Commit/Reset\n//---------------------------------------------\n\nstatic void unix_mprotect_hint(int err) {\n  #if defined(__linux__) && (MI_SECURE>=5) // guard page around every mimalloc page\n  if (err == ENOMEM) {\n    _mi_warning_message(\"The next warning may be caused by a low memory map limit.\\n\"\n                        \"  On Linux this is controlled by the vm.max_map_count -- maybe increase it?\\n\"\n                        \"  For example: sudo sysctl -w vm.max_map_count=262144\\n\");\n  }\n  #else\n  MI_UNUSED(err);\n  #endif\n}\n\n\n\n\n\nint _mi_prim_commit(void* start, size_t size, bool* is_zero) {\n  // commit: ensure we can access the area\n  // note: we may think that *is_zero can be true since the memory\n  // was either from mmap PROT_NONE, or from decommit MADV_DONTNEED, but\n  // we sometimes call commit on a range with still partially committed\n  // memory and `mprotect` does not zero the range.\n  *is_zero = false;\n  int err = mprotect(start, size, (PROT_READ | PROT_WRITE));\n  if (err != 0) {\n    err = errno;\n    unix_mprotect_hint(err);\n  }\n  return err;\n}\n\nint _mi_prim_reuse(void* start, size_t size) {\n  MI_UNUSED(start); MI_UNUSED(size);\n  #if defined(__APPLE__) && defined(MADV_FREE_REUSE)\n  return unix_madvise(start, size, MADV_FREE_REUSE);\n  #endif\n  return 0;\n}\n\nint _mi_prim_decommit(void* start, size_t size, bool* needs_recommit) {\n  int err = 0;\n  #if defined(__APPLE__) && defined(MADV_FREE_REUSABLE)\n    // decommit on macOS: use MADV_FREE_REUSABLE as it does immediate rss accounting (issue #1097)\n    err = unix_madvise(start, size, MADV_FREE_REUSABLE);\n    if (err) { err = unix_madvise(start, size, MADV_DONTNEED); }\n  #else\n    // decommit: use MADV_DONTNEED as it decreases rss immediately (unlike MADV_FREE)\n    err = unix_madvise(start, size, MADV_DONTNEED);\n  #endif\n  #if !MI_DEBUG && MI_SECURE<=2\n    *needs_recommit = false;\n  #else\n    *needs_recommit = true;\n    mprotect(start, size, PROT_NONE);\n  #endif\n  /*\n  // decommit: use mmap with MAP_FIXED and PROT_NONE to discard the existing memory (and reduce rss)\n  *needs_recommit = true;\n  const int fd = unix_mmap_fd();\n  void* p = mmap(start, size, PROT_NONE, (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE), fd, 0);\n  if (p != start) { err = errno; }\n  */\n  return err;\n}\n\nint _mi_prim_reset(void* start, size_t size) {\n  int err = 0;\n\n  // on macOS can use MADV_FREE_REUSABLE (but we disable this for now as it seems slower)\n  #if 0 && defined(__APPLE__) && defined(MADV_FREE_REUSABLE)\n  err = unix_madvise(start, size, MADV_FREE_REUSABLE);\n  if (err==0) return 0;\n  // fall through\n  #endif\n\n  #if defined(MADV_FREE)\n  // Otherwise, we try to use `MADV_FREE` as that is the fastest. A drawback though is that it\n  // will not reduce the `rss` stats in tools like `top` even though the memory is available\n  // to other processes. With the default `MIMALLOC_PURGE_DECOMMITS=1` we ensure that by\n  // default `MADV_DONTNEED` is used though.\n  static _Atomic(size_t) advice = MI_ATOMIC_VAR_INIT(MADV_FREE);\n  int oadvice = (int)mi_atomic_load_relaxed(&advice);\n  while ((err = unix_madvise(start, size, oadvice)) != 0 && err == EAGAIN) { /* try again */ };\n  if (err == EINVAL && oadvice == MADV_FREE) {\n    // if MADV_FREE is not supported, fall back to MADV_DONTNEED from now on\n    mi_atomic_store_release(&advice, (size_t)MADV_DONTNEED);\n    err = unix_madvise(start, size, MADV_DONTNEED);\n  }\n  #else\n  err = unix_madvise(start, size, MADV_DONTNEED);\n  #endif\n  return err;\n}\n\nint _mi_prim_protect(void* start, size_t size, bool protect) {\n  int err = mprotect(start, size, protect ? PROT_NONE : (PROT_READ | PROT_WRITE));\n  if (err != 0) { err = errno; }\n  unix_mprotect_hint(err);\n  return err;\n}\n\n\n\n//---------------------------------------------\n// Huge page allocation\n//---------------------------------------------\n\n#if (MI_INTPTR_SIZE >= 8) && !defined(__HAIKU__) && !defined(__CYGWIN__)\n\n#ifndef MPOL_PREFERRED\n#define MPOL_PREFERRED 1\n#endif\n\n#if defined(MI_HAS_SYSCALL_H) && defined(SYS_mbind)\nstatic long mi_prim_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) {\n  return syscall(SYS_mbind, start, len, mode, nmask, maxnode, flags);\n}\n#else\nstatic long mi_prim_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) {\n  MI_UNUSED(start); MI_UNUSED(len); MI_UNUSED(mode); MI_UNUSED(nmask); MI_UNUSED(maxnode); MI_UNUSED(flags);\n  return 0;\n}\n#endif\n\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {\n  bool is_large = true;\n  *is_zero = true;\n  *addr = unix_mmap(hint_addr, size, MI_ARENA_SLICE_ALIGN, PROT_READ | PROT_WRITE, true, true, &is_large);\n  if (*addr != NULL && numa_node >= 0 && numa_node < 8*MI_INTPTR_SIZE) { // at most 64 nodes\n    unsigned long numa_mask = (1UL << numa_node);\n    // TODO: does `mbind` work correctly for huge OS pages? should we\n    // use `set_mempolicy` before calling mmap instead?\n    // see: <https://lkml.org/lkml/2017/2/9/875>\n    long err = mi_prim_mbind(*addr, size, MPOL_PREFERRED, &numa_mask, 8*MI_INTPTR_SIZE, 0);\n    if (err != 0) {\n      err = errno;\n      _mi_warning_message(\"failed to bind huge (1GiB) pages to numa node %d (error: %d (0x%x))\\n\", numa_node, err, err);\n    }\n  }\n  return (*addr != NULL ? 0 : errno);\n}\n\n#else\n\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {\n  MI_UNUSED(hint_addr); MI_UNUSED(size); MI_UNUSED(numa_node);\n  *is_zero = false;\n  *addr = NULL;\n  return ENOMEM;\n}\n\n#endif\n\n//---------------------------------------------\n// NUMA nodes\n//---------------------------------------------\n\n#if defined(__linux__)\n\nsize_t _mi_prim_numa_node(void) {\n  #if defined(MI_HAS_SYSCALL_H) && defined(SYS_getcpu)\n    unsigned long node = 0;\n    unsigned long ncpu = 0;\n    long err = syscall(SYS_getcpu, &ncpu, &node, NULL);\n    if (err != 0) return 0;\n    return node;\n  #else\n    return 0;\n  #endif\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  char buf[128];\n  unsigned node = 0;\n  for(node = 0; node < 256; node++) {\n    // enumerate node entries -- todo: it there a more efficient way to do this? (but ensure there is no allocation)\n    _mi_snprintf(buf, 127, \"/sys/devices/system/node/node%u\", node + 1);\n    if (mi_prim_access(buf,R_OK) != 0) break;\n  }\n  return (node+1);\n}\n\n#elif defined(__FreeBSD__) && __FreeBSD_version >= 1200000\n\nsize_t _mi_prim_numa_node(void) {\n  domainset_t dom;\n  size_t node;\n  int policy;\n  if (cpuset_getdomain(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, sizeof(dom), &dom, &policy) == -1) return 0ul;\n  for (node = 0; node < MAXMEMDOM; node++) {\n    if (DOMAINSET_ISSET(node, &dom)) return node;\n  }\n  return 0ul;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  size_t ndomains = 0;\n  size_t len = sizeof(ndomains);\n  if (sysctlbyname(\"vm.ndomains\", &ndomains, &len, NULL, 0) == -1) return 0ul;\n  return ndomains;\n}\n\n#elif defined(__DragonFly__)\n\nsize_t _mi_prim_numa_node(void) {\n  // TODO: DragonFly does not seem to provide any userland means to get this information.\n  return 0ul;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  size_t ncpus = 0, nvirtcoresperphys = 0;\n  size_t len = sizeof(size_t);\n  if (sysctlbyname(\"hw.ncpu\", &ncpus, &len, NULL, 0) == -1) return 0ul;\n  if (sysctlbyname(\"hw.cpu_topology_ht_ids\", &nvirtcoresperphys, &len, NULL, 0) == -1) return 0ul;\n  return nvirtcoresperphys * ncpus;\n}\n\n#else\n\nsize_t _mi_prim_numa_node(void) {\n  return 0;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  return 1;\n}\n\n#endif\n\n// ----------------------------------------------------------------\n// Clock\n// ----------------------------------------------------------------\n\n#include <time.h>\n\n#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC)\n\nmi_msecs_t _mi_prim_clock_now(void) {\n  struct timespec t;\n  #ifdef CLOCK_MONOTONIC\n  clock_gettime(CLOCK_MONOTONIC, &t);\n  #else\n  clock_gettime(CLOCK_REALTIME, &t);\n  #endif\n  return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000);\n}\n\n#else\n\n// low resolution timer\nmi_msecs_t _mi_prim_clock_now(void) {\n  #if !defined(CLOCKS_PER_SEC) || (CLOCKS_PER_SEC == 1000) || (CLOCKS_PER_SEC == 0)\n  return (mi_msecs_t)clock();\n  #elif (CLOCKS_PER_SEC < 1000)\n  return (mi_msecs_t)clock() * (1000 / (mi_msecs_t)CLOCKS_PER_SEC);\n  #else\n  return (mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000);\n  #endif\n}\n\n#endif\n\n\n\n\n//----------------------------------------------------------------\n// Process info\n//----------------------------------------------------------------\n\n#if defined(__unix__) || defined(__unix) || defined(unix) || defined(__APPLE__) || defined(__HAIKU__)\n#include <stdio.h>\n#include <unistd.h>\n#include <sys/resource.h>\n\n#if defined(__APPLE__)\n#include <mach/mach.h>\n#endif\n\n#if defined(__HAIKU__)\n#include <kernel/OS.h>\n#endif\n\nstatic mi_msecs_t timeval_secs(const struct timeval* tv) {\n  return ((mi_msecs_t)tv->tv_sec * 1000L) + ((mi_msecs_t)tv->tv_usec / 1000L);\n}\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo)\n{\n  struct rusage rusage;\n  getrusage(RUSAGE_SELF, &rusage);\n  pinfo->utime = timeval_secs(&rusage.ru_utime);\n  pinfo->stime = timeval_secs(&rusage.ru_stime);\n#if !defined(__HAIKU__)\n  pinfo->page_faults = rusage.ru_majflt;\n#endif\n#if defined(__HAIKU__)\n  // Haiku does not have (yet?) a way to\n  // get these stats per process\n  thread_info tid;\n  area_info mem;\n  ssize_t c;\n  get_thread_info(find_thread(0), &tid);\n  while (get_next_area_info(tid.team, &c, &mem) == B_OK) {\n    pinfo->peak_rss += mem.ram_size;\n  }\n  pinfo->page_faults = 0;\n#elif defined(__APPLE__)\n  pinfo->peak_rss = rusage.ru_maxrss;         // macos reports in bytes\n  #ifdef MACH_TASK_BASIC_INFO\n  struct mach_task_basic_info info;\n  mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;\n  if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) {\n    pinfo->current_rss = (size_t)info.resident_size;\n  }\n  #else\n  struct task_basic_info info;\n  mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;\n  if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) {\n    pinfo->current_rss = (size_t)info.resident_size;\n  }\n  #endif\n#else\n  pinfo->peak_rss = rusage.ru_maxrss * 1024;  // Linux/BSD report in KiB\n#endif\n  // use defaults for commit\n}\n\n#else\n\n#ifndef __wasi__\n// WebAssembly instances are not processes\n#pragma message(\"define a way to get process info\")\n#endif\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo)\n{\n  // use defaults\n  MI_UNUSED(pinfo);\n}\n\n#endif\n\n\n//----------------------------------------------------------------\n// Output\n//----------------------------------------------------------------\n\nvoid _mi_prim_out_stderr( const char* msg ) {\n  fputs(msg,stderr);\n}\n\n\n//----------------------------------------------------------------\n// Environment\n//----------------------------------------------------------------\n\n#if !defined(MI_USE_ENVIRON) || (MI_USE_ENVIRON!=0)\n// On Posix systemsr use `environ` to access environment variables\n// even before the C runtime is initialized.\n#if defined(__APPLE__) && defined(__has_include) && __has_include(<crt_externs.h>)\n#include <crt_externs.h>\nstatic char** mi_get_environ(void) {\n  return (*_NSGetEnviron());\n}\n#else\nextern char** environ;\nstatic char** mi_get_environ(void) {\n  return environ;\n}\n#endif\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size) {\n  if (name==NULL) return false;\n  const size_t len = _mi_strlen(name);\n  if (len == 0) return false;\n  char** env = mi_get_environ();\n  if (env == NULL) return false;\n  // compare up to 10000 entries\n  for (int i = 0; i < 10000 && env[i] != NULL; i++) {\n    const char* s = env[i];\n    if (_mi_strnicmp(name, s, len) == 0 && s[len] == '=') { // case insensitive\n      // found it\n      _mi_strlcpy(result, s + len + 1, result_size);\n      return true;\n    }\n  }\n  return false;\n}\n#else\n// fallback: use standard C `getenv` but this cannot be used while initializing the C runtime\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size) {\n  // cannot call getenv() when still initializing the C runtime.\n  if (_mi_preloading()) return false;\n  const char* s = getenv(name);\n  if (s == NULL) {\n    // we check the upper case name too.\n    char buf[64+1];\n    size_t len = _mi_strnlen(name,sizeof(buf)-1);\n    for (size_t i = 0; i < len; i++) {\n      buf[i] = _mi_toupper(name[i]);\n    }\n    buf[len] = 0;\n    s = getenv(buf);\n  }\n  if (s == NULL || _mi_strnlen(s,result_size) >= result_size)  return false;\n  _mi_strlcpy(result, s, result_size);\n  return true;\n}\n#endif  // !MI_USE_ENVIRON\n\n\n//----------------------------------------------------------------\n// Random\n//----------------------------------------------------------------\n\n#if defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_15) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_15)\n#include <CommonCrypto/CommonCryptoError.h>\n#include <CommonCrypto/CommonRandom.h>\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  // We prefer CCRandomGenerateBytes as it returns an error code while arc4random_buf\n  // may fail silently on macOS. See PR #390, and <https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/FreeBSD/arc4random.c.auto.html>\n  return (CCRandomGenerateBytes(buf, buf_len) == kCCSuccess);\n}\n\n#elif defined(__ANDROID__) || defined(__DragonFly__) || \\\n      defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \\\n      defined(__sun) || \\\n      (defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7))\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  arc4random_buf(buf, buf_len);\n  return true;\n}\n\n#elif defined(__APPLE__) || defined(__linux__) || defined(__HAIKU__)   // also for old apple versions < 10.7 (issue #829)\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <errno.h>\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  // Modern Linux provides `getrandom` but different distributions either use `sys/random.h` or `linux/random.h`\n  // and for the latter the actual `getrandom` call is not always defined.\n  // (see <https://stackoverflow.com/questions/45237324/why-doesnt-getrandom-compile>)\n  // We therefore use a syscall directly and fall back dynamically to /dev/urandom when needed.\n  #if defined(MI_HAS_SYSCALL_H) && defined(SYS_getrandom)\n    #ifndef GRND_NONBLOCK\n    #define GRND_NONBLOCK (1)\n    #endif\n    static _Atomic(uintptr_t) no_getrandom; // = 0\n    if (mi_atomic_load_acquire(&no_getrandom)==0) {\n      ssize_t ret = syscall(SYS_getrandom, buf, buf_len, GRND_NONBLOCK);\n      if (ret >= 0) return (buf_len == (size_t)ret);\n      if (errno != ENOSYS) return false;\n      mi_atomic_store_release(&no_getrandom, (uintptr_t)1); // don't call again, and fall back to /dev/urandom\n    }\n  #endif\n  int flags = O_RDONLY;\n  #if defined(O_CLOEXEC)\n  flags |= O_CLOEXEC;\n  #endif\n  int fd = mi_prim_open(\"/dev/urandom\", flags);\n  if (fd < 0) return false;\n  size_t count = 0;\n  while(count < buf_len) {\n    ssize_t ret = mi_prim_read(fd, (char*)buf + count, buf_len - count);\n    if (ret<=0) {\n      if (errno!=EAGAIN && errno!=EINTR) break;\n    }\n    else {\n      count += ret;\n    }\n  }\n  mi_prim_close(fd);\n  return (count==buf_len);\n}\n\n#else\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  return false;\n}\n\n#endif\n\n\n//----------------------------------------------------------------\n// Thread init/done\n//----------------------------------------------------------------\n\n#if defined(MI_USE_PTHREADS)\n\n// use pthread local storage keys to detect thread ending\n// (and used with MI_TLS_PTHREADS for the default theap)\npthread_key_t _mi_heap_default_key = (pthread_key_t)(-1);\n\nstatic void mi_pthread_done(void* value) {\n  if (value!=NULL) {\n    _mi_thread_done((mi_theap_t*)value);\n  }\n}\n\nvoid _mi_prim_thread_init_auto_done(void) {\n  mi_assert_internal(_mi_heap_default_key == (pthread_key_t)(-1));\n  pthread_key_create(&_mi_heap_default_key, &mi_pthread_done);\n}\n\nvoid _mi_prim_thread_done_auto_done(void) {\n  if (_mi_heap_default_key != (pthread_key_t)(-1)) {  // do not leak the key, see issue #809\n    pthread_key_delete(_mi_heap_default_key);\n  }\n}\n\nvoid _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {\n  if (_mi_heap_default_key != (pthread_key_t)(-1)) {  // can happen during recursive invocation on freeBSD\n    pthread_setspecific(_mi_heap_default_key, theap);\n  }\n}\n\n#else\n\nvoid _mi_prim_thread_init_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_done_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {\n  MI_UNUSED(theap);\n}\n\n#endif\n\nbool _mi_prim_thread_is_in_threadpool(void) {\n  return false;\n}\n\nvoid _mi_prim_thread_yield(void) {\n  sleep(0);\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/prim/wasi/prim.c",
      "sha256": "bee9c655a17e1e93bf4908e0a902fd3b566628447b1446fcbfa92bca2e76ca15",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// This file is included in `src/prim/prim.c`\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"\n\n#include <stdio.h>   // fputs\n#include <stdlib.h>  // getenv\n#include <unistd.h>  // sbrk, sleep\n\n//---------------------------------------------\n// Initialize\n//---------------------------------------------\n\nvoid _mi_prim_mem_init( mi_os_mem_config_t* config ) {\n  config->page_size = 64*MI_KiB; // WebAssembly has a fixed page size: 64KiB\n  config->alloc_granularity = 16;\n  config->has_overcommit = false;\n  config->has_partial_free = false;\n  config->has_virtual_reserve = false;\n}\n\n//---------------------------------------------\n// Free\n//---------------------------------------------\n\nint _mi_prim_free(void* addr, size_t size ) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  // wasi theap cannot be shrunk\n  return 0;\n}\n\n\n//---------------------------------------------\n// Allocation: sbrk or memory_grow\n//---------------------------------------------\n\n#if defined(MI_USE_SBRK)\n  static void* mi_memory_grow( size_t size ) {\n    void* p = sbrk(size);\n    if (p == (void*)(-1)) return NULL;\n    #if !defined(__wasi__) // on wasi this is always zero initialized already (?)\n    memset(p,0,size);\n    #endif\n    return p;\n  }\n#elif defined(__wasi__)\n  static void* mi_memory_grow( size_t size ) {\n    size_t base = (size > 0 ? __builtin_wasm_memory_grow(0,_mi_divide_up(size, _mi_os_page_size()))\n                            : __builtin_wasm_memory_size(0));\n    if (base == SIZE_MAX) return NULL;\n    return (void*)(base * _mi_os_page_size());\n  }\n#endif\n\n#if defined(MI_USE_PTHREADS)\nstatic pthread_mutex_t mi_theap_grow_mutex = PTHREAD_MUTEX_INITIALIZER;\n#endif\n\nstatic void* mi_prim_mem_grow(size_t size, size_t try_alignment) {\n  void* p = NULL;\n  if (try_alignment <= 1) {\n    // `sbrk` is not thread safe in general so try to protect it (we could skip this on WASM but leave it in for now)\n    #if defined(MI_USE_PTHREADS)\n    pthread_mutex_lock(&mi_theap_grow_mutex);\n    #endif\n    p = mi_memory_grow(size);\n    #if defined(MI_USE_PTHREADS)\n    pthread_mutex_unlock(&mi_theap_grow_mutex);\n    #endif\n  }\n  else {\n    void* base = NULL;\n    size_t alloc_size = 0;\n    // to allocate aligned use a lock to try to avoid thread interaction\n    // between getting the current size and actual allocation\n    // (also, `sbrk` is not thread safe in general)\n    #if defined(MI_USE_PTHREADS)\n    pthread_mutex_lock(&mi_theap_grow_mutex);\n    #endif\n    {\n      void* current = mi_memory_grow(0);  // get current size\n      if (current != NULL) {\n        void* aligned_current = _mi_align_up_ptr(current, try_alignment);  // and align from there to minimize wasted space\n        alloc_size = _mi_align_up( ((uint8_t*)aligned_current - (uint8_t*)current) + size, _mi_os_page_size());\n        base = mi_memory_grow(alloc_size);\n      }\n    }\n    #if defined(MI_USE_PTHREADS)\n    pthread_mutex_unlock(&mi_theap_grow_mutex);\n    #endif\n    if (base != NULL) {\n      p = _mi_align_up_ptr(base, try_alignment);\n      if ((uint8_t*)p + size > (uint8_t*)base + alloc_size) {\n        // another thread used wasm_memory_grow/sbrk in-between and we do not have enough\n        // space after alignment. Give up (and waste the space as we cannot shrink :-( )\n        // (in `mi_os_mem_alloc_aligned` this will fall back to overallocation to align)\n        p = NULL;\n      }\n    }\n  }\n  /*\n  if (p == NULL) {\n    _mi_warning_message(\"unable to allocate sbrk/wasm_memory_grow OS memory (%zu bytes, %zu alignment)\\n\", size, try_alignment);\n    errno = ENOMEM;\n    return NULL;\n  }\n  */\n  mi_assert_internal( p == NULL || try_alignment == 0 || (uintptr_t)p % try_alignment == 0 );\n  return p;\n}\n\n// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.\nint _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) {\n  MI_UNUSED(allow_large); MI_UNUSED(commit); MI_UNUSED(hint_addr);\n  *is_large = false;\n  *is_zero = false;\n  *addr = mi_prim_mem_grow(size, try_alignment);\n  return (*addr != NULL ? 0 : ENOMEM);\n}\n\n\n//---------------------------------------------\n// Commit/Reset/Protect\n//---------------------------------------------\n\nint _mi_prim_commit(void* addr, size_t size, bool* is_zero) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  *is_zero = false;\n  return 0;\n}\n\nint _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  *needs_recommit = false;\n  return 0;\n}\n\nint _mi_prim_reset(void* addr, size_t size) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  return 0;\n}\n\nint _mi_prim_reuse(void* addr, size_t size) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  return 0;\n}\n\nint _mi_prim_protect(void* addr, size_t size, bool protect) {\n  MI_UNUSED(addr); MI_UNUSED(size); MI_UNUSED(protect);\n  return 0;\n}\n\n\n//---------------------------------------------\n// Huge pages and NUMA nodes\n//---------------------------------------------\n\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {\n  MI_UNUSED(hint_addr); MI_UNUSED(size); MI_UNUSED(numa_node);\n  *is_zero = true;\n  *addr = NULL;\n  return ENOSYS;\n}\n\nsize_t _mi_prim_numa_node(void) {\n  return 0;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  return 1;\n}\n\n\n//----------------------------------------------------------------\n// Clock\n//----------------------------------------------------------------\n\n#include <time.h>\n\n#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC)\n\nmi_msecs_t _mi_prim_clock_now(void) {\n  struct timespec t;\n  #ifdef CLOCK_MONOTONIC\n  clock_gettime(CLOCK_MONOTONIC, &t);\n  #else\n  clock_gettime(CLOCK_REALTIME, &t);\n  #endif\n  return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000);\n}\n\n#else\n\n// low resolution timer\nmi_msecs_t _mi_prim_clock_now(void) {\n  #if !defined(CLOCKS_PER_SEC) || (CLOCKS_PER_SEC == 1000) || (CLOCKS_PER_SEC == 0)\n  return (mi_msecs_t)clock();\n  #elif (CLOCKS_PER_SEC < 1000)\n  return (mi_msecs_t)clock() * (1000 / (mi_msecs_t)CLOCKS_PER_SEC);\n  #else\n  return (mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000);\n  #endif\n}\n\n#endif\n\n\n//----------------------------------------------------------------\n// Process info\n//----------------------------------------------------------------\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo)\n{\n  // use defaults\n  MI_UNUSED(pinfo);\n}\n\n\n//----------------------------------------------------------------\n// Output\n//----------------------------------------------------------------\n\nvoid _mi_prim_out_stderr( const char* msg ) {\n  fputs(msg,stderr);\n}\n\n\n//----------------------------------------------------------------\n// Environment\n//----------------------------------------------------------------\n\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size) {\n  // cannot call getenv() when still initializing the C runtime.\n  if (_mi_preloading()) return false;\n  const char* s = getenv(name);\n  if (s == NULL) {\n    // we check the upper case name too.\n    char buf[64+1];\n    size_t len = _mi_strnlen(name,sizeof(buf)-1);\n    for (size_t i = 0; i < len; i++) {\n      buf[i] = _mi_toupper(name[i]);\n    }\n    buf[len] = 0;\n    s = getenv(buf);\n  }\n  if (s == NULL || _mi_strnlen(s,result_size) >= result_size)  return false;\n  _mi_strlcpy(result, s, result_size);\n  return true;\n}\n\n\n//----------------------------------------------------------------\n// Random\n//----------------------------------------------------------------\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  return false;\n}\n\n\n//----------------------------------------------------------------\n// Thread init/done\n//----------------------------------------------------------------\n\nvoid _mi_prim_thread_init_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_done_auto_done(void) {\n  // nothing\n}\n\nvoid _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {\n  MI_UNUSED(theap);\n}\n\nbool _mi_prim_thread_is_in_threadpool(void) {\n  return false;\n}\n\nvoid _mi_prim_thread_yield(void) {\n  sleep(0);\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/prim/windows/etw.h",
      "sha256": "4f3110ef2054c95cb275be96cb279224d3d46a728c5117bd1435425f382de778",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "//**********************************************************************`\n//* This is an include file generated by Message Compiler.             *`\n//*                                                                    *`\n//* Copyright (c) Microsoft Corporation. All Rights Reserved.          *`\n//**********************************************************************`\n#pragma once\n\n//*****************************************************************************\n//\n// Notes on the ETW event code generated by MC:\n//\n// - Structures and arrays of structures are treated as an opaque binary blob.\n//   The caller is responsible for packing the data for the structure into a\n//   single region of memory, with no padding between values. The macro will\n//   have an extra parameter for the length of the blob.\n// - Arrays of nul-terminated strings must be packed by the caller into a\n//   single binary blob containing the correct number of strings, with a nul\n//   after each string. The size of the blob is specified in characters, and\n//   includes the final nul.\n// - Arrays of SID are treated as a single binary blob. The caller is\n//   responsible for packing the SID values into a single region of memory with\n//   no padding.\n// - The length attribute on the data element in the manifest is significant\n//   for values with intype win:UnicodeString, win:AnsiString, or win:Binary.\n//   The length attribute must be specified for win:Binary, and is optional for\n//   win:UnicodeString and win:AnsiString (if no length is given, the strings\n//   are assumed to be nul-terminated). For win:UnicodeString, the length is\n//   measured in characters, not bytes.\n// - For an array of win:UnicodeString, win:AnsiString, or win:Binary, the\n//   length attribute applies to every value in the array, so every value in\n//   the array must have the same length. The values in the array are provided\n//   to the macro via a single pointer -- the caller is responsible for packing\n//   all of the values into a single region of memory with no padding between\n//   values.\n// - Values of type win:CountedUnicodeString, win:CountedAnsiString, and\n//   win:CountedBinary can be generated and collected on Vista or later.\n//   However, they may not decode properly without the Windows 10 2018 Fall\n//   Update.\n// - Arrays of type win:CountedUnicodeString, win:CountedAnsiString, and\n//   win:CountedBinary must be packed by the caller into a single region of\n//   memory. The format for each item is a UINT16 byte-count followed by that\n//   many bytes of data. When providing the array to the generated macro, you\n//   must provide the total size of the packed array data, including the UINT16\n//   sizes for each item. In the case of win:CountedUnicodeString, the data\n//   size is specified in WCHAR (16-bit) units. In the case of\n//   win:CountedAnsiString and win:CountedBinary, the data size is specified in\n//   bytes.\n//\n//*****************************************************************************\n\n#include <wmistr.h>\n#include <evntrace.h>\n#include <evntprov.h>\n\n#ifndef ETW_INLINE\n  #ifdef _ETW_KM_\n    // In kernel mode, save stack space by never inlining templates.\n    #define ETW_INLINE DECLSPEC_NOINLINE __inline\n  #else\n    // In user mode, save code size by inlining templates as appropriate.\n    #define ETW_INLINE __inline\n  #endif\n#endif // ETW_INLINE\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n//\n// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:\n// Define this macro to have the compiler skip the generated functions in this\n// header.\n//\n#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n//\n// MCGEN_USE_KERNEL_MODE_APIS macro:\n// Controls whether the generated code uses kernel-mode or user-mode APIs.\n// - Set to 0 to use Windows user-mode APIs such as EventRegister.\n// - Set to 1 to use Windows kernel-mode APIs such as EtwRegister.\n// Default is based on whether the _ETW_KM_ macro is defined (i.e. by wdm.h).\n// Note that the APIs can also be overridden directly, e.g. by setting the\n// MCGEN_EVENTWRITETRANSFER or MCGEN_EVENTREGISTER macros.\n//\n#ifndef MCGEN_USE_KERNEL_MODE_APIS\n  #ifdef _ETW_KM_\n    #define MCGEN_USE_KERNEL_MODE_APIS 1\n  #else\n    #define MCGEN_USE_KERNEL_MODE_APIS 0\n  #endif\n#endif // MCGEN_USE_KERNEL_MODE_APIS\n\n//\n// MCGEN_HAVE_EVENTSETINFORMATION macro:\n// Controls how McGenEventSetInformation uses the EventSetInformation API.\n// - Set to 0 to disable the use of EventSetInformation\n//   (McGenEventSetInformation will always return an error).\n// - Set to 1 to directly invoke MCGEN_EVENTSETINFORMATION.\n// - Set to 2 to to locate EventSetInformation at runtime via GetProcAddress\n//   (user-mode) or MmGetSystemRoutineAddress (kernel-mode).\n// Default is determined as follows:\n// - If MCGEN_EVENTSETINFORMATION has been customized, set to 1\n//   (i.e. use MCGEN_EVENTSETINFORMATION).\n// - Else if the target OS version has EventSetInformation, set to 1\n//   (i.e. use MCGEN_EVENTSETINFORMATION).\n// - Else set to 2 (i.e. try to dynamically locate EventSetInformation).\n// Note that an McGenEventSetInformation function will only be generated if one\n// or more provider in a manifest has provider traits.\n//\n#ifndef MCGEN_HAVE_EVENTSETINFORMATION\n  #ifdef MCGEN_EVENTSETINFORMATION             // if MCGEN_EVENTSETINFORMATION has been customized,\n    #define MCGEN_HAVE_EVENTSETINFORMATION   1 //   directly invoke MCGEN_EVENTSETINFORMATION(...).\n  #elif MCGEN_USE_KERNEL_MODE_APIS             // else if using kernel-mode APIs,\n    #if NTDDI_VERSION >= 0x06040000            //   if target OS is Windows 10 or later,\n      #define MCGEN_HAVE_EVENTSETINFORMATION 1 //     directly invoke MCGEN_EVENTSETINFORMATION(...).\n    #else                                      //   else\n      #define MCGEN_HAVE_EVENTSETINFORMATION 2 //     find \"EtwSetInformation\" via MmGetSystemRoutineAddress.\n    #endif                                     // else (using user-mode APIs)\n  #else                                        //   if target OS and SDK is Windows 8 or later,\n    #if WINVER >= 0x0602 && defined(EVENT_FILTER_TYPE_SCHEMATIZED)\n      #define MCGEN_HAVE_EVENTSETINFORMATION 1 //     directly invoke MCGEN_EVENTSETINFORMATION(...).\n    #else                                      //   else\n      #define MCGEN_HAVE_EVENTSETINFORMATION 2 //     find \"EventSetInformation\" via GetModuleHandleExW/GetProcAddress.\n    #endif\n  #endif\n#endif // MCGEN_HAVE_EVENTSETINFORMATION\n\n//\n// MCGEN Override Macros\n//\n// The following override macros may be defined before including this header\n// to control the APIs used by this header:\n//\n// - MCGEN_EVENTREGISTER\n// - MCGEN_EVENTUNREGISTER\n// - MCGEN_EVENTSETINFORMATION\n// - MCGEN_EVENTWRITETRANSFER\n//\n// If the the macro is undefined, the MC implementation will default to the\n// corresponding ETW APIs. For example, if the MCGEN_EVENTREGISTER macro is\n// undefined, the EventRegister[MyProviderName] macro will use EventRegister\n// in user mode and will use EtwRegister in kernel mode.\n//\n// To prevent issues from conflicting definitions of these macros, the value\n// of the override macro will be used as a suffix in certain internal function\n// names. Because of this, the override macros must follow certain rules:\n//\n// - The macro must be defined before any MC-generated header is included and\n//   must not be undefined or redefined after any MC-generated header is\n//   included. Different translation units (i.e. different .c or .cpp files)\n//   may set the macros to different values, but within a translation unit\n//   (within a single .c or .cpp file), the macro must be set once and not\n//   changed.\n// - The override must be an object-like macro, not a function-like macro\n//   (i.e. the override macro must not have a parameter list).\n// - The override macro's value must be a simple identifier, i.e. must be\n//   something that starts with a letter or '_' and contains only letters,\n//   numbers, and '_' characters.\n// - If the override macro's value is the name of a second object-like macro,\n//   the second object-like macro must follow the same rules. (The override\n//   macro's value can also be the name of a function-like macro, in which\n//   case the function-like macro does not need to follow the same rules.)\n//\n// For example, the following will cause compile errors:\n//\n//   #define MCGEN_EVENTWRITETRANSFER MyNamespace::MyClass::MyFunction // Value has non-identifier characters (colon).\n//   #define MCGEN_EVENTWRITETRANSFER GetEventWriteFunctionPointer(7)  // Value has non-identifier characters (parentheses).\n//   #define MCGEN_EVENTWRITETRANSFER(h,e,a,r,c,d) EventWrite(h,e,c,d) // Override is defined as a function-like macro.\n//   #define MY_OBJECT_LIKE_MACRO     MyNamespace::MyClass::MyEventWriteFunction\n//   #define MCGEN_EVENTWRITETRANSFER MY_OBJECT_LIKE_MACRO // Evaluates to something with non-identifier characters (colon).\n//\n// The following would be ok:\n//\n//   #define MCGEN_EVENTWRITETRANSFER  MyEventWriteFunction1  // OK, suffix will be \"MyEventWriteFunction1\".\n//   #define MY_OBJECT_LIKE_MACRO      MyEventWriteFunction2\n//   #define MCGEN_EVENTWRITETRANSFER  MY_OBJECT_LIKE_MACRO   // OK, suffix will be \"MyEventWriteFunction2\".\n//   #define MY_FUNCTION_LIKE_MACRO(h,e,a,r,c,d) MyNamespace::MyClass::MyEventWriteFunction3(h,e,c,d)\n//   #define MCGEN_EVENTWRITETRANSFER  MY_FUNCTION_LIKE_MACRO // OK, suffix will be \"MY_FUNCTION_LIKE_MACRO\".\n//\n#ifndef MCGEN_EVENTREGISTER\n  #if MCGEN_USE_KERNEL_MODE_APIS\n    #define MCGEN_EVENTREGISTER        EtwRegister\n  #else\n    #define MCGEN_EVENTREGISTER        EventRegister\n  #endif\n#endif // MCGEN_EVENTREGISTER\n#ifndef MCGEN_EVENTUNREGISTER\n  #if MCGEN_USE_KERNEL_MODE_APIS\n    #define MCGEN_EVENTUNREGISTER      EtwUnregister\n  #else\n    #define MCGEN_EVENTUNREGISTER      EventUnregister\n  #endif\n#endif // MCGEN_EVENTUNREGISTER\n#ifndef MCGEN_EVENTSETINFORMATION\n  #if MCGEN_USE_KERNEL_MODE_APIS\n    #define MCGEN_EVENTSETINFORMATION  EtwSetInformation\n  #else\n    #define MCGEN_EVENTSETINFORMATION  EventSetInformation\n  #endif\n#endif // MCGEN_EVENTSETINFORMATION\n#ifndef MCGEN_EVENTWRITETRANSFER\n  #if MCGEN_USE_KERNEL_MODE_APIS\n    #define MCGEN_EVENTWRITETRANSFER   EtwWriteTransfer\n  #else\n    #define MCGEN_EVENTWRITETRANSFER   EventWriteTransfer\n  #endif\n#endif // MCGEN_EVENTWRITETRANSFER\n\n//\n// MCGEN_EVENT_ENABLED macro:\n// Override to control how the EventWrite[EventName] macros determine whether\n// an event is enabled. The default behavior is for EventWrite[EventName] to\n// use the EventEnabled[EventName] macros.\n//\n#ifndef MCGEN_EVENT_ENABLED\n#define MCGEN_EVENT_ENABLED(EventName) EventEnabled##EventName()\n#endif\n\n//\n// MCGEN_EVENT_ENABLED_FORCONTEXT macro:\n// Override to control how the EventWrite[EventName]_ForContext macros\n// determine whether an event is enabled. The default behavior is for\n// EventWrite[EventName]_ForContext to use the\n// EventEnabled[EventName]_ForContext macros.\n//\n#ifndef MCGEN_EVENT_ENABLED_FORCONTEXT\n#define MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, EventName) EventEnabled##EventName##_ForContext(pContext)\n#endif\n\n//\n// MCGEN_ENABLE_CHECK macro:\n// Determines whether the specified event would be considered as enabled\n// based on the state of the specified context. Slightly faster than calling\n// McGenEventEnabled directly.\n//\n#ifndef MCGEN_ENABLE_CHECK\n#define MCGEN_ENABLE_CHECK(Context, Descriptor) (Context.IsEnabled && McGenEventEnabled(&Context, &Descriptor))\n#endif\n\n#if !defined(MCGEN_TRACE_CONTEXT_DEF)\n#define MCGEN_TRACE_CONTEXT_DEF\n// This structure is for use by MC-generated code and should not be used directly.\ntypedef struct _MCGEN_TRACE_CONTEXT\n{\n    TRACEHANDLE            RegistrationHandle;\n    TRACEHANDLE            Logger;      // Used as pointer to provider traits.\n    ULONGLONG              MatchAnyKeyword;\n    ULONGLONG              MatchAllKeyword;\n    ULONG                  Flags;\n    ULONG                  IsEnabled;\n    UCHAR                  Level;\n    UCHAR                  Reserve;\n    USHORT                 EnableBitsCount;\n    PULONG                 EnableBitMask;\n    const ULONGLONG*       EnableKeyWords;\n    const UCHAR*           EnableLevel;\n} MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT;\n#endif // MCGEN_TRACE_CONTEXT_DEF\n\n#if !defined(MCGEN_LEVEL_KEYWORD_ENABLED_DEF)\n#define MCGEN_LEVEL_KEYWORD_ENABLED_DEF\n//\n// Determines whether an event with a given Level and Keyword would be\n// considered as enabled based on the state of the specified context.\n// Note that you may want to use MCGEN_ENABLE_CHECK instead of calling this\n// function directly.\n//\nFORCEINLINE\nBOOLEAN\nMcGenLevelKeywordEnabled(\n    _In_ PMCGEN_TRACE_CONTEXT EnableInfo,\n    _In_ UCHAR Level,\n    _In_ ULONGLONG Keyword\n    )\n{\n    //\n    // Check if the event Level is lower than the level at which\n    // the channel is enabled.\n    // If the event Level is 0 or the channel is enabled at level 0,\n    // all levels are enabled.\n    //\n\n    if ((Level <= EnableInfo->Level) || // This also covers the case of Level == 0.\n        (EnableInfo->Level == 0)) {\n\n        //\n        // Check if Keyword is enabled\n        //\n\n        if ((Keyword == (ULONGLONG)0) ||\n            ((Keyword & EnableInfo->MatchAnyKeyword) &&\n             ((Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) {\n            return TRUE;\n        }\n    }\n\n    return FALSE;\n}\n#endif // MCGEN_LEVEL_KEYWORD_ENABLED_DEF\n\n#if !defined(MCGEN_EVENT_ENABLED_DEF)\n#define MCGEN_EVENT_ENABLED_DEF\n//\n// Determines whether the specified event would be considered as enabled based\n// on the state of the specified context. Note that you may want to use\n// MCGEN_ENABLE_CHECK instead of calling this function directly.\n//\nFORCEINLINE\nBOOLEAN\nMcGenEventEnabled(\n    _In_ PMCGEN_TRACE_CONTEXT EnableInfo,\n    _In_ PCEVENT_DESCRIPTOR EventDescriptor\n    )\n{\n    return McGenLevelKeywordEnabled(EnableInfo, EventDescriptor->Level, EventDescriptor->Keyword);\n}\n#endif // MCGEN_EVENT_ENABLED_DEF\n\n#if !defined(MCGEN_CONTROL_CALLBACK)\n#define MCGEN_CONTROL_CALLBACK\n\n// This function is for use by MC-generated code and should not be used directly.\nDECLSPEC_NOINLINE __inline\nVOID\n__stdcall\nMcGenControlCallbackV2(\n    _In_ LPCGUID SourceId,\n    _In_ ULONG ControlCode,\n    _In_ UCHAR Level,\n    _In_ ULONGLONG MatchAnyKeyword,\n    _In_ ULONGLONG MatchAllKeyword,\n    _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,\n    _Inout_opt_ PVOID CallbackContext\n    )\n/*++\n\nRoutine Description:\n\n    This is the notification callback for Windows Vista and later.\n\nArguments:\n\n    SourceId - The GUID that identifies the session that enabled the provider.\n\n    ControlCode - The parameter indicates whether the provider\n                  is being enabled or disabled.\n\n    Level - The level at which the event is enabled.\n\n    MatchAnyKeyword - The bitmask of keywords that the provider uses to\n                      determine the category of events that it writes.\n\n    MatchAllKeyword - This bitmask additionally restricts the category\n                      of events that the provider writes.\n\n    FilterData - The provider-defined data.\n\n    CallbackContext - The context of the callback that is defined when the provider\n                      called EtwRegister to register itself.\n\nRemarks:\n\n    ETW calls this function to notify provider of enable/disable\n\n--*/\n{\n    PMCGEN_TRACE_CONTEXT Ctx = (PMCGEN_TRACE_CONTEXT)CallbackContext;\n    ULONG Ix;\n#ifndef MCGEN_PRIVATE_ENABLE_CALLBACK_V2\n    UNREFERENCED_PARAMETER(SourceId);\n    UNREFERENCED_PARAMETER(FilterData);\n#endif\n\n    if (Ctx == NULL) {\n        return;\n    }\n\n    switch (ControlCode) {\n\n        case EVENT_CONTROL_CODE_ENABLE_PROVIDER:\n            Ctx->Level = Level;\n            Ctx->MatchAnyKeyword = MatchAnyKeyword;\n            Ctx->MatchAllKeyword = MatchAllKeyword;\n            Ctx->IsEnabled = EVENT_CONTROL_CODE_ENABLE_PROVIDER;\n\n            for (Ix = 0; Ix < Ctx->EnableBitsCount; Ix += 1) {\n                if (McGenLevelKeywordEnabled(Ctx, Ctx->EnableLevel[Ix], Ctx->EnableKeyWords[Ix]) != FALSE) {\n                    Ctx->EnableBitMask[Ix >> 5] |= (1 << (Ix % 32));\n                } else {\n                    Ctx->EnableBitMask[Ix >> 5] &= ~(1 << (Ix % 32));\n                }\n            }\n            break;\n\n        case EVENT_CONTROL_CODE_DISABLE_PROVIDER:\n            Ctx->IsEnabled = EVENT_CONTROL_CODE_DISABLE_PROVIDER;\n            Ctx->Level = 0;\n            Ctx->MatchAnyKeyword = 0;\n            Ctx->MatchAllKeyword = 0;\n            if (Ctx->EnableBitsCount > 0) {\n#pragma warning(suppress: 26451) // Arithmetic overflow cannot occur, no matter the value of EnableBitCount\n                RtlZeroMemory(Ctx->EnableBitMask, (((Ctx->EnableBitsCount - 1) / 32) + 1) * sizeof(ULONG));\n            }\n            break;\n\n        default:\n            break;\n    }\n\n#ifdef MCGEN_PRIVATE_ENABLE_CALLBACK_V2\n    //\n    // Call user defined callback\n    //\n    MCGEN_PRIVATE_ENABLE_CALLBACK_V2(\n        SourceId,\n        ControlCode,\n        Level,\n        MatchAnyKeyword,\n        MatchAllKeyword,\n        FilterData,\n        CallbackContext\n        );\n#endif // MCGEN_PRIVATE_ENABLE_CALLBACK_V2\n\n    return;\n}\n\n#endif // MCGEN_CONTROL_CALLBACK\n\n#ifndef _mcgen_PENABLECALLBACK\n  #if MCGEN_USE_KERNEL_MODE_APIS\n    #define _mcgen_PENABLECALLBACK      PETWENABLECALLBACK\n  #else\n    #define _mcgen_PENABLECALLBACK      PENABLECALLBACK\n  #endif\n#endif // _mcgen_PENABLECALLBACK\n\n#if !defined(_mcgen_PASTE2)\n// This macro is for use by MC-generated code and should not be used directly.\n#define _mcgen_PASTE2(a, b) _mcgen_PASTE2_imp(a, b)\n#define _mcgen_PASTE2_imp(a, b) a##b\n#endif // _mcgen_PASTE2\n\n#if !defined(_mcgen_PASTE3)\n// This macro is for use by MC-generated code and should not be used directly.\n#define _mcgen_PASTE3(a, b, c) _mcgen_PASTE3_imp(a, b, c)\n#define _mcgen_PASTE3_imp(a, b, c) a##b##_##c\n#endif // _mcgen_PASTE3\n\n//\n// Macro validation\n//\n\n// Validate MCGEN_EVENTREGISTER:\n\n// Trigger an error if MCGEN_EVENTREGISTER is not an unqualified (simple) identifier:\nstruct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER);\n\n// Trigger an error if MCGEN_EVENTREGISTER is redefined:\ntypedef struct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER)\n    MCGEN_EVENTREGISTER_must_not_be_redefined_between_headers;\n\n// Trigger an error if MCGEN_EVENTREGISTER is defined as a function-like macro:\ntypedef void MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTREGISTER;\ntypedef int _mcgen_PASTE2(MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTREGISTER);\n\n// Validate MCGEN_EVENTUNREGISTER:\n\n// Trigger an error if MCGEN_EVENTUNREGISTER is not an unqualified (simple) identifier:\nstruct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER);\n\n// Trigger an error if MCGEN_EVENTUNREGISTER is redefined:\ntypedef struct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER)\n    MCGEN_EVENTUNREGISTER_must_not_be_redefined_between_headers;\n\n// Trigger an error if MCGEN_EVENTUNREGISTER is defined as a function-like macro:\ntypedef void MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTUNREGISTER;\ntypedef int _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTUNREGISTER);\n\n// Validate MCGEN_EVENTSETINFORMATION:\n\n// Trigger an error if MCGEN_EVENTSETINFORMATION is not an unqualified (simple) identifier:\nstruct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION);\n\n// Trigger an error if MCGEN_EVENTSETINFORMATION is redefined:\ntypedef struct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION)\n    MCGEN_EVENTSETINFORMATION_must_not_be_redefined_between_headers;\n\n// Trigger an error if MCGEN_EVENTSETINFORMATION is defined as a function-like macro:\ntypedef void MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_MCGEN_EVENTSETINFORMATION;\ntypedef int _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_, MCGEN_EVENTSETINFORMATION);\n\n// Validate MCGEN_EVENTWRITETRANSFER:\n\n// Trigger an error if MCGEN_EVENTWRITETRANSFER is not an unqualified (simple) identifier:\nstruct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER);\n\n// Trigger an error if MCGEN_EVENTWRITETRANSFER is redefined:\ntypedef struct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER)\n    MCGEN_EVENTWRITETRANSFER_must_not_be_redefined_between_headers;;\n\n// Trigger an error if MCGEN_EVENTWRITETRANSFER is defined as a function-like macro:\ntypedef void MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_MCGEN_EVENTWRITETRANSFER;\ntypedef int _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_, MCGEN_EVENTWRITETRANSFER);\n\n#ifndef McGenEventWrite_def\n#define McGenEventWrite_def\n\n// This macro is for use by MC-generated code and should not be used directly.\n#define McGenEventWrite _mcgen_PASTE2(McGenEventWrite_, MCGEN_EVENTWRITETRANSFER)\n\n// This function is for use by MC-generated code and should not be used directly.\nDECLSPEC_NOINLINE __inline\nULONG __stdcall\nMcGenEventWrite(\n    _In_ PMCGEN_TRACE_CONTEXT Context,\n    _In_ PCEVENT_DESCRIPTOR Descriptor,\n    _In_opt_ LPCGUID ActivityId,\n    _In_range_(1, 128) ULONG EventDataCount,\n    _Pre_cap_(EventDataCount) EVENT_DATA_DESCRIPTOR* EventData\n    )\n{\n    const USHORT UNALIGNED* Traits;\n\n    // Some customized MCGEN_EVENTWRITETRANSFER macros might ignore ActivityId.\n    UNREFERENCED_PARAMETER(ActivityId);\n\n    Traits = (const USHORT UNALIGNED*)(UINT_PTR)Context->Logger;\n\n    if (Traits == NULL) {\n        EventData[0].Ptr = 0;\n        EventData[0].Size = 0;\n        EventData[0].Reserved = 0;\n    } else {\n        EventData[0].Ptr = (ULONG_PTR)Traits;\n        EventData[0].Size = *Traits;\n        EventData[0].Reserved = 2; // EVENT_DATA_DESCRIPTOR_TYPE_PROVIDER_METADATA\n    }\n\n    return MCGEN_EVENTWRITETRANSFER(\n        Context->RegistrationHandle,\n        Descriptor,\n        ActivityId,\n        NULL,\n        EventDataCount,\n        EventData);\n}\n#endif // McGenEventWrite_def\n\n#if !defined(McGenEventRegisterUnregister)\n#define McGenEventRegisterUnregister\n\n// This macro is for use by MC-generated code and should not be used directly.\n#define McGenEventRegister _mcgen_PASTE2(McGenEventRegister_, MCGEN_EVENTREGISTER)\n\n#pragma warning(push)\n#pragma warning(disable:6103)\n// This function is for use by MC-generated code and should not be used directly.\nDECLSPEC_NOINLINE __inline\nULONG __stdcall\nMcGenEventRegister(\n    _In_ LPCGUID ProviderId,\n    _In_opt_ _mcgen_PENABLECALLBACK EnableCallback,\n    _In_opt_ PVOID CallbackContext,\n    _Inout_ PREGHANDLE RegHandle\n    )\n/*++\n\nRoutine Description:\n\n    This function registers the provider with ETW.\n\nArguments:\n\n    ProviderId - Provider ID to register with ETW.\n\n    EnableCallback - Callback to be used.\n\n    CallbackContext - Context for the callback.\n\n    RegHandle - Pointer to registration handle.\n\nRemarks:\n\n    Should not be called if the provider is already registered (i.e. should not\n    be called if *RegHandle != 0). Repeatedly registering a provider is a bug\n    and may indicate a race condition. However, for compatibility with previous\n    behavior, this function will return SUCCESS in this case.\n\n--*/\n{\n    ULONG Error;\n\n    if (*RegHandle != 0)\n    {\n        Error = 0; // ERROR_SUCCESS\n    }\n    else\n    {\n        Error = MCGEN_EVENTREGISTER(ProviderId, EnableCallback, CallbackContext, RegHandle);\n    }\n\n    return Error;\n}\n#pragma warning(pop)\n\n// This macro is for use by MC-generated code and should not be used directly.\n#define McGenEventUnregister _mcgen_PASTE2(McGenEventUnregister_, MCGEN_EVENTUNREGISTER)\n\n// This function is for use by MC-generated code and should not be used directly.\nDECLSPEC_NOINLINE __inline\nULONG __stdcall\nMcGenEventUnregister(_Inout_ PREGHANDLE RegHandle)\n/*++\n\nRoutine Description:\n\n    Unregister from ETW and set *RegHandle = 0.\n\nArguments:\n\n    RegHandle - the pointer to the provider registration handle\n\nRemarks:\n\n    If provider has not been registered (i.e. if *RegHandle == 0),\n    return SUCCESS. It is safe to call McGenEventUnregister even if the\n    call to McGenEventRegister returned an error.\n\n--*/\n{\n    ULONG Error;\n\n    if(*RegHandle == 0)\n    {\n        Error = 0; // ERROR_SUCCESS\n    }\n    else\n    {\n        Error = MCGEN_EVENTUNREGISTER(*RegHandle);\n        *RegHandle = (REGHANDLE)0;\n    }\n\n    return Error;\n}\n\n#endif // McGenEventRegisterUnregister\n\n#ifndef _mcgen_EVENT_BIT_SET\n  #if defined(_M_IX86) || defined(_M_X64)\n    // This macro is for use by MC-generated code and should not be used directly.\n    #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((((const unsigned char*)EnableBits)[BitPosition >> 3] & (1u << (BitPosition & 7))) != 0)\n  #else // CPU type\n    // This macro is for use by MC-generated code and should not be used directly.\n    #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((EnableBits[BitPosition >> 5] & (1u << (BitPosition & 31))) != 0)\n  #endif // CPU type\n#endif // _mcgen_EVENT_BIT_SET\n\n#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n// Provider \"microsoft-windows-mimalloc\" event count 2\n//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n// Provider GUID = 138f4dbb-ee04-4899-aa0a-572ad4475779\nEXTERN_C __declspec(selectany) const GUID ETW_MI_Provider = {0x138f4dbb, 0xee04, 0x4899, {0xaa, 0x0a, 0x57, 0x2a, 0xd4, 0x47, 0x57, 0x79}};\n\n#ifndef ETW_MI_Provider_Traits\n#define ETW_MI_Provider_Traits NULL\n#endif // ETW_MI_Provider_Traits\n\n//\n// Event Descriptors\n//\nEXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ETW_MI_ALLOC = {0x64, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0};\n#define ETW_MI_ALLOC_value 0x64\nEXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ETW_MI_FREE = {0x65, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0};\n#define ETW_MI_FREE_value 0x65\n\n//\n// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:\n// Define this macro to have the compiler skip the generated functions in this\n// header.\n//\n#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n//\n// Event Enablement Bits\n// These variables are for use by MC-generated code and should not be used directly.\n//\nEXTERN_C __declspec(selectany) DECLSPEC_CACHEALIGN ULONG microsoft_windows_mimallocEnableBits[1];\nEXTERN_C __declspec(selectany) const ULONGLONG microsoft_windows_mimallocKeywords[1] = {0x0};\nEXTERN_C __declspec(selectany) const unsigned char microsoft_windows_mimallocLevels[1] = {4};\n\n//\n// Provider context\n//\nEXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT ETW_MI_Provider_Context = {0, (ULONG_PTR)ETW_MI_Provider_Traits, 0, 0, 0, 0, 0, 0, 1, microsoft_windows_mimallocEnableBits, microsoft_windows_mimallocKeywords, microsoft_windows_mimallocLevels};\n\n//\n// Provider REGHANDLE\n//\n#define microsoft_windows_mimallocHandle (ETW_MI_Provider_Context.RegistrationHandle)\n\n//\n// This macro is set to 0, indicating that the EventWrite[Name] macros do not\n// have an Activity parameter. This is controlled by the -km and -um options.\n//\n#define ETW_MI_Provider_EventWriteActivity 0\n\n//\n// Register with ETW using the control GUID specified in the manifest.\n// Invoke this macro during module initialization (i.e. program startup,\n// DLL process attach, or driver load) to initialize the provider.\n// Note that if this function returns an error, the error means that\n// will not work, but no action needs to be taken -- even if EventRegister\n// returns an error, it is generally safe to use EventWrite and\n// EventUnregister macros (they will be no-ops if EventRegister failed).\n//\n#ifndef EventRegistermicrosoft_windows_mimalloc\n#define EventRegistermicrosoft_windows_mimalloc() McGenEventRegister(&ETW_MI_Provider, McGenControlCallbackV2, &ETW_MI_Provider_Context, &microsoft_windows_mimallocHandle)\n#endif\n\n//\n// Register with ETW using a specific control GUID (i.e. a GUID other than what\n// is specified in the manifest). Advanced scenarios only.\n//\n#ifndef EventRegisterByGuidmicrosoft_windows_mimalloc\n#define EventRegisterByGuidmicrosoft_windows_mimalloc(Guid) McGenEventRegister(&(Guid), McGenControlCallbackV2, &ETW_MI_Provider_Context, &microsoft_windows_mimallocHandle)\n#endif\n\n//\n// Unregister with ETW and close the provider.\n// Invoke this macro during module shutdown (i.e. program exit, DLL process\n// detach, or driver unload) to unregister the provider.\n// Note that you MUST call EventUnregister before DLL or driver unload\n// (not optional): failure to unregister a provider before DLL or driver unload\n// will result in crashes.\n//\n#ifndef EventUnregistermicrosoft_windows_mimalloc\n#define EventUnregistermicrosoft_windows_mimalloc() McGenEventUnregister(&microsoft_windows_mimallocHandle)\n#endif\n\n//\n// MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION macro:\n// Define this macro to enable support for caller-allocated provider context.\n//\n#ifdef MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION\n\n//\n// Advanced scenarios: Caller-allocated provider context.\n// Use when multiple differently-configured provider handles are needed,\n// e.g. for container-aware drivers, one context per container.\n//\n// Usage:\n//\n// - Caller enables the feature before including this header, e.g.\n//   #define MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION 1\n// - Caller allocates memory, e.g. pContext = malloc(sizeof(McGenContext_microsoft_windows_mimalloc));\n// - Caller registers the provider, e.g. EventRegistermicrosoft_windows_mimalloc_ForContext(pContext);\n// - Caller writes events, e.g. EventWriteMyEvent_ForContext(pContext, ...);\n// - Caller unregisters, e.g. EventUnregistermicrosoft_windows_mimalloc_ForContext(pContext);\n// - Caller frees memory, e.g. free(pContext);\n//\n\ntypedef struct tagMcGenContext_microsoft_windows_mimalloc {\n    // The fields of this structure are subject to change and should\n    // not be accessed directly. To access the provider's REGHANDLE,\n    // use microsoft_windows_mimallocHandle_ForContext(pContext).\n    MCGEN_TRACE_CONTEXT Context;\n    ULONG EnableBits[1];\n} McGenContext_microsoft_windows_mimalloc;\n\n#define EventRegistermicrosoft_windows_mimalloc_ForContext(pContext)             _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(&ETW_MI_Provider, pContext)\n#define EventRegisterByGuidmicrosoft_windows_mimalloc_ForContext(Guid, pContext) _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(&(Guid), pContext)\n#define EventUnregistermicrosoft_windows_mimalloc_ForContext(pContext)           McGenEventUnregister(&(pContext)->Context.RegistrationHandle)\n\n//\n// Provider REGHANDLE for caller-allocated context.\n//\n#define microsoft_windows_mimallocHandle_ForContext(pContext) ((pContext)->Context.RegistrationHandle)\n\n// This function is for use by MC-generated code and should not be used directly.\n// Initialize and register the caller-allocated context.\n__inline\nULONG __stdcall\n_mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(\n    _In_ LPCGUID pProviderId,\n    _Out_ McGenContext_microsoft_windows_mimalloc* pContext)\n{\n    RtlZeroMemory(pContext, sizeof(*pContext));\n    pContext->Context.Logger = (ULONG_PTR)ETW_MI_Provider_Traits;\n    pContext->Context.EnableBitsCount = 1;\n    pContext->Context.EnableBitMask = pContext->EnableBits;\n    pContext->Context.EnableKeyWords = microsoft_windows_mimallocKeywords;\n    pContext->Context.EnableLevel = microsoft_windows_mimallocLevels;\n    return McGenEventRegister(\n        pProviderId,\n        McGenControlCallbackV2,\n        &pContext->Context,\n        &pContext->Context.RegistrationHandle);\n}\n\n// This function is for use by MC-generated code and should not be used directly.\n// Trigger a compile error if called with the wrong parameter type.\nFORCEINLINE\n_Ret_ McGenContext_microsoft_windows_mimalloc*\n_mcgen_CheckContextType_microsoft_windows_mimalloc(_In_ McGenContext_microsoft_windows_mimalloc* pContext)\n{\n    return pContext;\n}\n\n#endif // MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION\n\n//\n// Enablement check macro for event \"ETW_MI_ALLOC\"\n//\n#define EventEnabledETW_MI_ALLOC() _mcgen_EVENT_BIT_SET(microsoft_windows_mimallocEnableBits, 0)\n#define EventEnabledETW_MI_ALLOC_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->EnableBits, 0)\n\n//\n// Event write macros for event \"ETW_MI_ALLOC\"\n//\n#define EventWriteETW_MI_ALLOC(Address, Size) \\\n        MCGEN_EVENT_ENABLED(ETW_MI_ALLOC) \\\n        ? _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&ETW_MI_Provider_Context, &ETW_MI_ALLOC, Address, Size) : 0\n#define EventWriteETW_MI_ALLOC_AssumeEnabled(Address, Size) \\\n        _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&ETW_MI_Provider_Context, &ETW_MI_ALLOC, Address, Size)\n#define EventWriteETW_MI_ALLOC_ForContext(pContext, Address, Size) \\\n        MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ETW_MI_ALLOC) \\\n        ? _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&(pContext)->Context, &ETW_MI_ALLOC, Address, Size) : 0\n#define EventWriteETW_MI_ALLOC_ForContextAssumeEnabled(pContext, Address, Size) \\\n        _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->Context, &ETW_MI_ALLOC, Address, Size)\n\n// This macro is for use by MC-generated code and should not be used directly.\n#define _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)\n\n//\n// Enablement check macro for event \"ETW_MI_FREE\"\n//\n#define EventEnabledETW_MI_FREE() _mcgen_EVENT_BIT_SET(microsoft_windows_mimallocEnableBits, 0)\n#define EventEnabledETW_MI_FREE_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->EnableBits, 0)\n\n//\n// Event write macros for event \"ETW_MI_FREE\"\n//\n#define EventWriteETW_MI_FREE(Address, Size) \\\n        MCGEN_EVENT_ENABLED(ETW_MI_FREE) \\\n        ? _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&ETW_MI_Provider_Context, &ETW_MI_FREE, Address, Size) : 0\n#define EventWriteETW_MI_FREE_AssumeEnabled(Address, Size) \\\n        _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&ETW_MI_Provider_Context, &ETW_MI_FREE, Address, Size)\n#define EventWriteETW_MI_FREE_ForContext(pContext, Address, Size) \\\n        MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ETW_MI_FREE) \\\n        ? _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&(pContext)->Context, &ETW_MI_FREE, Address, Size) : 0\n#define EventWriteETW_MI_FREE_ForContextAssumeEnabled(pContext, Address, Size) \\\n        _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->Context, &ETW_MI_FREE, Address, Size)\n\n// This macro is for use by MC-generated code and should not be used directly.\n#define _mcgen_TEMPLATE_FOR_ETW_MI_FREE _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)\n\n#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n//\n// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:\n// Define this macro to have the compiler skip the generated functions in this\n// header.\n//\n#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n//\n// Template Functions\n//\n\n//\n// Function for template \"ETW_CUSTOM_HEAP_ALLOC_DATA\" (and possibly others).\n// This function is for use by MC-generated code and should not be used directly.\n//\n#ifndef McTemplateU0xx_def\n#define McTemplateU0xx_def\nETW_INLINE\nULONG\n_mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)(\n    _In_ PMCGEN_TRACE_CONTEXT Context,\n    _In_ PCEVENT_DESCRIPTOR Descriptor,\n    _In_ const unsigned __int64  _Arg0,\n    _In_ const unsigned __int64  _Arg1\n    )\n{\n#define McTemplateU0xx_ARGCOUNT 2\n\n    EVENT_DATA_DESCRIPTOR EventData[McTemplateU0xx_ARGCOUNT + 1];\n\n    EventDataDescCreate(&EventData[1],&_Arg0, sizeof(const unsigned __int64)  );\n\n    EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned __int64)  );\n\n    return McGenEventWrite(Context, Descriptor, NULL, McTemplateU0xx_ARGCOUNT + 1, EventData);\n}\n#endif // McTemplateU0xx_def\n\n#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION\n\n#if defined(__cplusplus)\n}\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/prim/windows/prim.c",
      "sha256": "5cde60fcef94cd79ab816030be00f8c1bdf18fab343563508c681ec6e762d1f1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2023, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n// This file is included in `src/prim/prim.c`\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"\n#include <stdio.h>   // fputs, stderr\n#include <stdlib.h>  // atexit\n\n// xbox has no console IO\n#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)\n#define MI_HAS_CONSOLE_IO\n#endif\n\n//---------------------------------------------\n// Dynamically bind Windows API points for portability\n//---------------------------------------------\n\n#if defined(_MSC_VER)\n#pragma warning(disable:4996)   // don't use GetVersionExW\n#endif\n\nstatic DWORD win_major_version = 6;\nstatic DWORD win_minor_version = 0;\n\n// We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016.\n// So, we need to look it up dynamically to run on older systems. (use __stdcall for 32-bit compatibility)\n// NtAllocateVirtualAllocEx is used for huge OS page allocation (1GiB)\n// We define a minimal MEM_EXTENDED_PARAMETER ourselves in order to be able to compile with older SDK's.\ntypedef enum MI_MEM_EXTENDED_PARAMETER_TYPE_E {\n  MiMemExtendedParameterInvalidType = 0,\n  MiMemExtendedParameterAddressRequirements,\n  MiMemExtendedParameterNumaNode,\n  MiMemExtendedParameterPartitionHandle,\n  MiMemExtendedParameterUserPhysicalHandle,\n  MiMemExtendedParameterAttributeFlags,\n  MiMemExtendedParameterMax\n} MI_MEM_EXTENDED_PARAMETER_TYPE;\n\ntypedef struct DECLSPEC_ALIGN(8) MI_MEM_EXTENDED_PARAMETER_S {\n  struct { DWORD64 Type : 8; DWORD64 Reserved : 56; } Type;\n  union  { DWORD64 ULong64; PVOID Pointer; SIZE_T Size; HANDLE Handle; DWORD ULong; } Arg;\n} MI_MEM_EXTENDED_PARAMETER;\n\ntypedef struct MI_MEM_ADDRESS_REQUIREMENTS_S {\n  PVOID  LowestStartingAddress;\n  PVOID  HighestEndingAddress;\n  SIZE_T Alignment;\n} MI_MEM_ADDRESS_REQUIREMENTS;\n\n#define MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE   0x00000010\n\n#include <winternl.h>\ntypedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG);\ntypedef LONG  (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG);  // avoid NTSTATUS as it is not defined on xbox (pr #1084)\nstatic PVirtualAlloc2 pVirtualAlloc2 = NULL;\nstatic PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL;\n\n// Similarly, GetNumaProcessorNodeEx is only supported since Windows 7  (and GetNumaNodeProcessorMask is not supported on xbox)\ntypedef struct MI_PROCESSOR_NUMBER_S { WORD Group; BYTE Number; BYTE Reserved; } MI_PROCESSOR_NUMBER;\n\ntypedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(MI_PROCESSOR_NUMBER* ProcNumber);\ntypedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(MI_PROCESSOR_NUMBER* Processor, PUSHORT NodeNumber);\ntypedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask);\ntypedef BOOL (__stdcall *PGetNumaProcessorNode)(UCHAR Processor, PUCHAR NodeNumber);\ntypedef BOOL (__stdcall* PGetNumaNodeProcessorMask)(UCHAR Node, PULONGLONG ProcessorMask);\ntypedef BOOL (__stdcall* PGetNumaHighestNodeNumber)(PULONG Node);\nstatic PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL;\nstatic PGetNumaProcessorNodeEx      pGetNumaProcessorNodeEx = NULL;\nstatic PGetNumaNodeProcessorMaskEx  pGetNumaNodeProcessorMaskEx = NULL;\nstatic PGetNumaProcessorNode        pGetNumaProcessorNode = NULL;\nstatic PGetNumaNodeProcessorMask    pGetNumaNodeProcessorMask = NULL;\nstatic PGetNumaHighestNodeNumber    pGetNumaHighestNodeNumber = NULL;\n\n// Not available on xbox\ntypedef SIZE_T(__stdcall* PGetLargePageMinimum)(VOID);\nstatic PGetLargePageMinimum pGetLargePageMinimum = NULL;\n\n// Available after Windows XP\ntypedef BOOL (__stdcall *PGetPhysicallyInstalledSystemMemory)( PULONGLONG TotalMemoryInKilobytes );\ntypedef BOOL (__stdcall* PGetVersionExW)(LPOSVERSIONINFOW lpVersionInformation);\n\n\n\n//---------------------------------------------\n// Enable large page support dynamically (if possible)\n//---------------------------------------------\n\nstatic bool win_enable_large_os_pages_once(size_t* large_page_size)\n{\n  if (pGetLargePageMinimum==NULL) return false;  // no large page support (xbox etc.)\n\n  // Try to see if large OS pages are supported\n  // To use large pages on Windows, we first need access permission\n  // Set \"Lock pages in memory\" permission in the group policy editor\n  // <https://devblogs.microsoft.com/oldnewthing/20110128-00/?p=11643>\n  unsigned long err = 0;\n  HANDLE token = NULL;\n  BOOL ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);\n  if (ok) {\n    TOKEN_PRIVILEGES tp;\n    ok = LookupPrivilegeValue(NULL, TEXT(\"SeLockMemoryPrivilege\"), &tp.Privileges[0].Luid);\n    if (ok) {\n      tp.PrivilegeCount = 1;\n      tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\n      ok = AdjustTokenPrivileges(token, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);\n      if (ok) {\n        err = GetLastError();\n        ok = (err == ERROR_SUCCESS);\n        if (ok && large_page_size != NULL && pGetLargePageMinimum != NULL) {\n          *large_page_size = (*pGetLargePageMinimum)();\n        }\n      }\n    }\n    CloseHandle(token);\n  }\n  if (!ok) {\n    if (err == 0) err = GetLastError();\n    _mi_warning_message(\"cannot enable large OS page support, error %lu\\n\", err);\n  }\n  return (ok!=0);\n}\n\nstatic bool win_enable_large_os_pages(size_t* large_page_size) {\n  mi_atomic_do_once {\n    win_enable_large_os_pages_once(large_page_size);\n  }\n  return (_mi_os_large_page_size() > 0);\n}\n\n\n//---------------------------------------------\n// Initialize\n//---------------------------------------------\n\nstatic DWORD win_allocation_granularity = 64*MI_KiB;\n\nvoid _mi_prim_mem_init( mi_os_mem_config_t* config )\n{\n  config->has_overcommit = false;\n  config->has_partial_free = false;\n  config->has_virtual_reserve = true;\n\n  // get the page size\n  SYSTEM_INFO si; _mi_memzero_var(si);\n  GetSystemInfo(&si);\n  if (si.dwPageSize > 0) { config->page_size = si.dwPageSize; }\n  if (si.dwAllocationGranularity > 0) {\n    config->alloc_granularity = si.dwAllocationGranularity;\n    win_allocation_granularity = si.dwAllocationGranularity;\n  }\n  // get virtual address bits\n  if ((uintptr_t)si.lpMaximumApplicationAddress > 0) {\n    const size_t vbits = MI_SIZE_BITS - mi_clz((uintptr_t)si.lpMaximumApplicationAddress);\n    config->virtual_address_bits = vbits;\n  }\n\n  // get the VirtualAlloc2 function\n  HINSTANCE hDll = LoadLibrary(TEXT(\"kernelbase.dll\"));\n  if (hDll != NULL) {\n    // use VirtualAlloc2FromApp if possible as it is available to Windows store apps\n    pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, \"VirtualAlloc2FromApp\");\n    if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, \"VirtualAlloc2\");\n    FreeLibrary(hDll);\n  }\n  // NtAllocateVirtualMemoryEx is used for huge page allocation\n  hDll = LoadLibrary(TEXT(\"ntdll.dll\"));\n  if (hDll != NULL) {\n    pNtAllocateVirtualMemoryEx = (PNtAllocateVirtualMemoryEx)(void (*)(void))GetProcAddress(hDll, \"NtAllocateVirtualMemoryEx\");\n    FreeLibrary(hDll);\n  }\n  // Try to use Win7+ numa API\n  hDll = LoadLibrary(TEXT(\"kernel32.dll\"));\n  if (hDll != NULL) {\n    pGetCurrentProcessorNumberEx = (PGetCurrentProcessorNumberEx)(void (*)(void))GetProcAddress(hDll, \"GetCurrentProcessorNumberEx\");\n    pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, \"GetNumaProcessorNodeEx\");\n    pGetNumaNodeProcessorMaskEx = (PGetNumaNodeProcessorMaskEx)(void (*)(void))GetProcAddress(hDll, \"GetNumaNodeProcessorMaskEx\");\n    pGetNumaProcessorNode = (PGetNumaProcessorNode)(void (*)(void))GetProcAddress(hDll, \"GetNumaProcessorNode\");\n    pGetNumaNodeProcessorMask = (PGetNumaNodeProcessorMask)(void (*)(void))GetProcAddress(hDll, \"GetNumaNodeProcessorMask\");\n    pGetNumaHighestNodeNumber = (PGetNumaHighestNodeNumber)(void (*)(void))GetProcAddress(hDll, \"GetNumaHighestNodeNumber\");\n    pGetLargePageMinimum = (PGetLargePageMinimum)(void (*)(void))GetProcAddress(hDll, \"GetLargePageMinimum\");\n    // Get physical memory (not available on XP, so check dynamically)\n    PGetPhysicallyInstalledSystemMemory pGetPhysicallyInstalledSystemMemory = (PGetPhysicallyInstalledSystemMemory)(void (*)(void))GetProcAddress(hDll,\"GetPhysicallyInstalledSystemMemory\");\n    if (pGetPhysicallyInstalledSystemMemory != NULL) {\n      ULONGLONG memInKiB = 0;\n      if ((*pGetPhysicallyInstalledSystemMemory)(&memInKiB)) {\n        if (memInKiB > 0 && memInKiB <= SIZE_MAX) {\n          config->physical_memory_in_kib = (size_t)memInKiB;\n        }\n      }\n    }\n    // Get Windows version\n    PGetVersionExW pGetVersionExW = (PGetVersionExW)(void (*)(void))GetProcAddress(hDll, \"GetVersionExW\");\n    if (pGetVersionExW != NULL) {\n      OSVERSIONINFOW version; _mi_memzero_var(version);\n      version.dwOSVersionInfoSize = sizeof(version);\n      if ((*pGetVersionExW)(&version)) {\n        win_major_version = version.dwMajorVersion;\n        win_minor_version = version.dwMinorVersion;\n      }\n    }\n    FreeLibrary(hDll);\n  }\n  // Enable large/huge OS page support?\n  if (mi_option_is_enabled(mi_option_allow_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {\n    win_enable_large_os_pages(&config->large_page_size);\n  }\n}\n\n\n//---------------------------------------------\n// Free\n//---------------------------------------------\n\nint _mi_prim_free(void* addr, size_t size ) {\n  MI_UNUSED(size);\n  DWORD errcode = 0;\n  bool err = (VirtualFree(addr, 0, MEM_RELEASE) == 0);\n  if (err) { errcode = GetLastError(); }\n  if (errcode == ERROR_INVALID_ADDRESS) {\n    // In mi_os_mem_alloc_aligned the fallback path may have returned a pointer inside\n    // the memory region returned by VirtualAlloc; in that case we need to free using\n    // the start of the region.\n    MEMORY_BASIC_INFORMATION info; _mi_memzero_var(info);\n    VirtualQuery(addr, &info, sizeof(info));\n    if (info.AllocationBase < addr && ((uint8_t*)addr - (uint8_t*)info.AllocationBase) < (ptrdiff_t)(4*MI_MiB)) {\n      errcode = 0;\n      err = (VirtualFree(info.AllocationBase, 0, MEM_RELEASE) == 0);\n      if (err) { errcode = GetLastError(); }\n    }\n  }\n  return (int)errcode;\n}\n\n\n//---------------------------------------------\n// VirtualAlloc\n//---------------------------------------------\n\nstatic void* win_virtual_alloc_prim_once(void* addr, size_t size, size_t try_alignment, DWORD flags) {\n  #if (MI_INTPTR_SIZE >= 8)\n  // on 64-bit systems, try to use the virtual address area after 2TiB for 4MiB aligned allocations\n  if (addr == NULL) {\n    void* hint = _mi_os_get_aligned_hint(try_alignment,size);\n    if (hint != NULL) {\n      void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE);\n      if (p != NULL) return p;\n      _mi_verbose_message(\"warning: unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\\n\", size, GetLastError(), hint, try_alignment, flags);\n      // fall through on error\n    }\n  }\n  #endif\n  // on modern Windows try use VirtualAlloc2 for aligned allocation\n  if (addr == NULL && try_alignment > win_allocation_granularity && (try_alignment % _mi_os_page_size()) == 0 && pVirtualAlloc2 != NULL) {\n    MI_MEM_ADDRESS_REQUIREMENTS reqs = { 0, 0, 0 };\n    reqs.Alignment = try_alignment;\n    MI_MEM_EXTENDED_PARAMETER param = { {0, 0}, {0} };\n    param.Type.Type = MiMemExtendedParameterAddressRequirements;\n    param.Arg.Pointer = &reqs;\n    void* p = (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, &param, 1);\n    if (p != NULL) return p;\n    _mi_warning_message(\"unable to allocate aligned OS memory (0x%zx bytes, error code: 0x%x, address: %p, alignment: 0x%zx, flags: 0x%x)\\n\", size, GetLastError(), addr, try_alignment, flags);\n    // fall through on error\n  }\n  // last resort\n  return VirtualAlloc(addr, size, flags, PAGE_READWRITE);\n}\n\nstatic bool win_is_out_of_memory_error(DWORD err) {\n  switch (err) {\n    case ERROR_COMMITMENT_MINIMUM:\n    case ERROR_COMMITMENT_LIMIT:\n    case ERROR_PAGEFILE_QUOTA:\n    case ERROR_NOT_ENOUGH_MEMORY:\n      return true;\n    default:\n      return false;\n  }\n}\n\nstatic void* win_virtual_alloc_prim(void* addr, size_t size, size_t try_alignment, DWORD flags) {\n  long max_retry_msecs = mi_option_get_clamp(mi_option_retry_on_oom, 0, 2000);  // at most 2 seconds\n  if (max_retry_msecs == 1) { max_retry_msecs = 100; }  // if one sets the option to \"true\"\n  for (long tries = 1; tries <= 10; tries++) {          // try at most 10 times (=2200ms)\n    void* p = win_virtual_alloc_prim_once(addr, size, try_alignment, flags);\n    if (p != NULL) {\n      // success, return the address\n      return p;\n    }\n    else if (max_retry_msecs > 0 && (try_alignment <= 8*MI_MiB) &&\n              (flags&MEM_COMMIT) != 0 && (flags&MEM_LARGE_PAGES) == 0 &&\n              win_is_out_of_memory_error(GetLastError())) {\n      // if committing regular memory and being out-of-memory,\n      // keep trying for a bit in case memory frees up after all. See issue #894\n      _mi_warning_message(\"out-of-memory on OS allocation, try again... (attempt %lu, 0x%zx bytes, error code: 0x%x, address: %p, alignment: 0x%zx, flags: 0x%x)\\n\", tries, size, GetLastError(), addr, try_alignment, flags);\n      long sleep_msecs = tries*40;  // increasing waits\n      if (sleep_msecs > max_retry_msecs) { sleep_msecs = max_retry_msecs; }\n      max_retry_msecs -= sleep_msecs;\n      Sleep(sleep_msecs);\n    }\n    else {\n      // otherwise return with an error\n      break;\n    }\n  }\n  return NULL;\n}\n\nstatic void* win_virtual_alloc(void* addr, size_t size, size_t try_alignment, DWORD flags, bool large_only, bool allow_large, bool* is_large) {\n  mi_assert_internal(!(large_only && !allow_large));\n  static _Atomic(size_t) large_page_try_ok; // = 0;\n  void* p = NULL;\n  // Try to allocate large OS pages (2MiB) if allowed or required.\n  if ((large_only || (_mi_os_canuse_large_page(size, try_alignment) && mi_option_is_enabled(mi_option_allow_large_os_pages)))\n      && allow_large && (flags&MEM_COMMIT)!=0 && (flags&MEM_RESERVE)!=0)\n  {\n    size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok);\n    if (!large_only && try_ok > 0) {\n      // if a large page allocation fails, it seems the calls to VirtualAlloc get very expensive.\n      // therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times.\n      mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1);\n    }\n    else {\n      // large OS pages must always reserve and commit.\n      *is_large = true;\n      p = win_virtual_alloc_prim(addr, size, try_alignment, flags | MEM_LARGE_PAGES);\n      if (large_only) return p;\n      // fall back to non-large page allocation on error (`p == NULL`).\n      if (p == NULL) {\n        mi_atomic_store_release(&large_page_try_ok,10UL);  // on error, don't try again for the next N allocations\n      }\n    }\n  }\n  // Fall back to regular page allocation\n  if (p == NULL) {\n    *is_large = ((flags&MEM_LARGE_PAGES) != 0);\n    p = win_virtual_alloc_prim(addr, size, try_alignment, flags);\n  }\n  //if (p == NULL) { _mi_warning_message(\"unable to allocate OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x, large only: %d, allow large: %d)\\n\", size, GetLastError(), addr, try_alignment, flags, large_only, allow_large); }\n  return p;\n}\n\nint _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) {\n  mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);\n  mi_assert_internal(commit || !allow_large);\n  mi_assert_internal(try_alignment > 0);\n  *is_zero = true;\n  int flags = MEM_RESERVE;\n  if (commit) { flags |= MEM_COMMIT; }\n  *addr = win_virtual_alloc(hint_addr, size, try_alignment, flags, false, allow_large, is_large);\n  return (*addr != NULL ? 0 : (int)GetLastError());\n}\n\n\n//---------------------------------------------\n// Commit/Reset/Protect\n//---------------------------------------------\n#ifdef _MSC_VER\n#pragma warning(disable:6250)   // suppress warning calling VirtualFree without MEM_RELEASE (for decommit)\n#endif\n\nint _mi_prim_commit(void* addr, size_t size, bool* is_zero) {\n  *is_zero = false;\n  /*\n  // zero'ing only happens on an initial commit... but checking upfront seems expensive..\n  _MEMORY_BASIC_INFORMATION meminfo; _mi_memzero_var(meminfo);\n  if (VirtualQuery(addr, &meminfo, size) > 0) {\n    if ((meminfo.State & MEM_COMMIT) == 0) {\n      *is_zero = true;\n    }\n  }\n  */\n  // commit\n  void* p = VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE);\n  if (p == NULL) return (int)GetLastError();\n  return 0;\n}\n\nint _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) {\n  BOOL ok = VirtualFree(addr, size, MEM_DECOMMIT);\n  *needs_recommit = true;  // for safety, assume always decommitted even in the case of an error.\n  return (ok ? 0 : (int)GetLastError());\n}\n\nint _mi_prim_reset(void* addr, size_t size) {\n  void* p = VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE);\n  mi_assert_internal(p == addr);\n  #if 0\n  if (p != NULL) {\n    VirtualUnlock(addr,size); // VirtualUnlock after MEM_RESET removes the memory directly from the working set\n  }\n  #endif\n  return (p != NULL ? 0 : (int)GetLastError());\n}\n\nint _mi_prim_reuse(void* addr, size_t size) {\n  MI_UNUSED(addr); MI_UNUSED(size);\n  return 0;\n}\n\nint _mi_prim_protect(void* addr, size_t size, bool protect) {\n  DWORD oldprotect = 0;\n  BOOL ok = VirtualProtect(addr, size, protect ? PAGE_NOACCESS : PAGE_READWRITE, &oldprotect);\n  return (ok ? 0 : (int)GetLastError());\n}\n\n\n//---------------------------------------------\n// Huge page allocation\n//---------------------------------------------\n\nstatic void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int numa_node)\n{\n  const DWORD flags = MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE;\n\n  win_enable_large_os_pages(NULL);\n\n  MI_MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} };\n  // on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages\n  static _Atomic(size_t) mi_huge_pages_available = MI_ATOMIC_VAR_INIT(1);\n  if (pNtAllocateVirtualMemoryEx != NULL && mi_atomic_load_acquire(&mi_huge_pages_available) != 0) {\n    params[0].Type.Type = MiMemExtendedParameterAttributeFlags;\n    params[0].Arg.ULong64 = MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE;\n    ULONG param_count = 1;\n    if (numa_node >= 0) {\n      param_count++;\n      params[1].Type.Type = MiMemExtendedParameterNumaNode;\n      params[1].Arg.ULong = (unsigned)numa_node;\n    }\n    SIZE_T psize = size;\n    void* base = hint_addr;\n    LONG err = (*pNtAllocateVirtualMemoryEx)(GetCurrentProcess(), &base, &psize, flags, PAGE_READWRITE, params, param_count);\n    if (err == 0 && base != NULL) {\n      return base;\n    }\n    else {\n      // fall back to regular large pages\n      mi_atomic_store_release(&mi_huge_pages_available,0); // don't try further huge pages\n      _mi_warning_message(\"unable to allocate using huge (1GiB) pages, trying large (2MiB) pages instead (status 0x%lx)\\n\", err);\n    }\n  }\n  // on modern Windows try use VirtualAlloc2 for numa aware large OS page allocation\n  if (pVirtualAlloc2 != NULL && numa_node >= 0) {\n    params[0].Type.Type = MiMemExtendedParameterNumaNode;\n    params[0].Arg.ULong = (unsigned)numa_node;\n    return (*pVirtualAlloc2)(GetCurrentProcess(), hint_addr, size, flags, PAGE_READWRITE, params, 1);\n  }\n\n  // otherwise use regular virtual alloc on older windows\n  return VirtualAlloc(hint_addr, size, flags, PAGE_READWRITE);\n}\n\nint _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {\n  *is_zero = true;\n  *addr = _mi_prim_alloc_huge_os_pagesx(hint_addr,size,numa_node);\n  return (*addr != NULL ? 0 : (int)GetLastError());\n}\n\n\n//---------------------------------------------\n// Numa nodes\n//---------------------------------------------\n\nsize_t _mi_prim_numa_node(void) {\n  USHORT numa_node = 0;\n  if (pGetCurrentProcessorNumberEx != NULL && pGetNumaProcessorNodeEx != NULL) {\n    // Extended API is supported\n    MI_PROCESSOR_NUMBER pnum;\n    (*pGetCurrentProcessorNumberEx)(&pnum);\n    USHORT nnode = 0;\n    BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode);\n    if (ok) { numa_node = nnode; }\n  }\n  else if (pGetNumaProcessorNode != NULL) {\n    // Vista or earlier, use older API that is limited to 64 processors. Issue #277\n    DWORD pnum = GetCurrentProcessorNumber();\n    UCHAR nnode = 0;\n    BOOL ok = pGetNumaProcessorNode((UCHAR)pnum, &nnode);\n    if (ok) { numa_node = nnode; }\n  }\n  return numa_node;\n}\n\nsize_t _mi_prim_numa_node_count(void) {\n  ULONG numa_max = 0;\n  if (pGetNumaHighestNodeNumber!=NULL) {\n    (*pGetNumaHighestNodeNumber)(&numa_max);\n  }\n  // find the highest node number that has actual processors assigned to it. Issue #282\n  while (numa_max > 0) {\n    if (pGetNumaNodeProcessorMaskEx != NULL) {\n      // Extended API is supported\n      GROUP_AFFINITY affinity;\n      if ((*pGetNumaNodeProcessorMaskEx)((USHORT)numa_max, &affinity)) {\n        if (affinity.Mask != 0) break;  // found the maximum non-empty node\n      }\n    }\n    else {\n      // Vista or earlier, use older API that is limited to 64 processors.\n      ULONGLONG mask;\n      if (pGetNumaNodeProcessorMask != NULL) {\n        if ((*pGetNumaNodeProcessorMask)((UCHAR)numa_max, &mask)) {\n          if (mask != 0) break; // found the maximum non-empty node\n        }\n      };\n    }\n    // max node was invalid or had no processor assigned, try again\n    numa_max--;\n  }\n  return ((size_t)numa_max + 1);\n}\n\n\n//----------------------------------------------------------------\n// Clock\n//----------------------------------------------------------------\n\nstatic mi_msecs_t mi_to_msecs(LARGE_INTEGER t) {\n  static LARGE_INTEGER mfreq; // = 0\n  if (mfreq.QuadPart == 0LL) {\n    LARGE_INTEGER f;\n    QueryPerformanceFrequency(&f);\n    mfreq.QuadPart = f.QuadPart/1000LL;\n    if (mfreq.QuadPart == 0) mfreq.QuadPart = 1;\n  }\n  return (mi_msecs_t)(t.QuadPart / mfreq.QuadPart);\n}\n\nmi_msecs_t _mi_prim_clock_now(void) {\n  LARGE_INTEGER t;\n  QueryPerformanceCounter(&t);\n  return mi_to_msecs(t);\n}\n\n\n//----------------------------------------------------------------\n// Process Info\n//----------------------------------------------------------------\n\n#include <psapi.h>\n\nstatic mi_msecs_t filetime_msecs(const FILETIME* ftime) {\n  ULARGE_INTEGER i;\n  i.LowPart = ftime->dwLowDateTime;\n  i.HighPart = ftime->dwHighDateTime;\n  mi_msecs_t msecs = (i.QuadPart / 10000); // FILETIME is in 100 nano seconds\n  return msecs;\n}\n\ntypedef BOOL (WINAPI *PGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);\nstatic PGetProcessMemoryInfo pGetProcessMemoryInfo = NULL;\n\nvoid _mi_prim_process_info(mi_process_info_t* pinfo)\n{\n  FILETIME ct;\n  FILETIME ut;\n  FILETIME st;\n  FILETIME et;\n  GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut);\n  pinfo->utime = filetime_msecs(&ut);\n  pinfo->stime = filetime_msecs(&st);\n\n  // load psapi on demand\n  mi_atomic_do_once {\n    HINSTANCE hDll = LoadLibrary(TEXT(\"psapi.dll\"));\n    if (hDll != NULL) {\n      pGetProcessMemoryInfo = (PGetProcessMemoryInfo)(void (*)(void))GetProcAddress(hDll, \"GetProcessMemoryInfo\");\n      // FreeLibrary(hDll);  // don't free\n    }\n  }\n\n  // get process info\n  PROCESS_MEMORY_COUNTERS info; _mi_memzero_var(info);\n  if (pGetProcessMemoryInfo != NULL) {\n    pGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));\n  }\n  pinfo->current_rss    = (size_t)info.WorkingSetSize;\n  pinfo->peak_rss       = (size_t)info.PeakWorkingSetSize;\n  pinfo->current_commit = (size_t)info.PagefileUsage;\n  pinfo->peak_commit    = (size_t)info.PeakPagefileUsage;\n  pinfo->page_faults    = (size_t)info.PageFaultCount;\n}\n\n//----------------------------------------------------------------\n// Output\n//----------------------------------------------------------------\n\nvoid _mi_prim_out_stderr( const char* msg )\n{\n  // on windows with redirection, the C runtime cannot handle locale dependent output\n  // after the main thread closes so we use direct console output.\n  if (!_mi_preloading()) {\n    // _cputs(msg);  // _cputs cannot be used as it aborts when failing to lock the console\n    static HANDLE hcon = INVALID_HANDLE_VALUE;\n    static bool hconIsConsole = false;\n    if (hcon == INVALID_HANDLE_VALUE) {\n      hcon = GetStdHandle(STD_ERROR_HANDLE);\n      #ifdef MI_HAS_CONSOLE_IO\n      CONSOLE_SCREEN_BUFFER_INFO sbi;\n      hconIsConsole = ((hcon != INVALID_HANDLE_VALUE) && GetConsoleScreenBufferInfo(hcon, &sbi));\n      #endif\n    }\n    const size_t len = _mi_strlen(msg);\n    if (len > 0 && len < UINT32_MAX) {\n      DWORD written = 0;\n      if (hconIsConsole) {\n        #ifdef MI_HAS_CONSOLE_IO\n        WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL);\n        #endif\n      }\n      else if (hcon != INVALID_HANDLE_VALUE) {\n        // use direct write if stderr was redirected\n        WriteFile(hcon, msg, (DWORD)len, &written, NULL);\n      }\n      else {\n        // finally fall back to fputs after all\n        fputs(msg, stderr);\n      }\n    }\n  }\n}\n\n\n//----------------------------------------------------------------\n// Environment\n//----------------------------------------------------------------\n\n// On Windows use GetEnvironmentVariable instead of getenv to work\n// reliably even when this is invoked before the C runtime is initialized.\n// i.e. when `_mi_preloading() == true`.\n// Note: on windows, environment names are not case sensitive.\nbool _mi_prim_getenv(const char* name, char* result, size_t result_size) {\n  result[0] = 0;\n  const size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size);\n  return (len > 0 && len < result_size);\n}\n\n\n//----------------------------------------------------------------\n// Random\n//----------------------------------------------------------------\n\n#if defined(MI_USE_RTLGENRANDOM) // || defined(__cplusplus)\n// We prefer to use BCryptGenRandom instead of (the unofficial) RtlGenRandom but when using\n// dynamic overriding, we observed it can raise an exception when compiled with C++, and\n// sometimes deadlocks when also running under the VS debugger.\n// In contrast, issue #623 implies that on Windows Server 2019 we need to use BCryptGenRandom.\n// To be continued..\n#pragma comment (lib,\"advapi32.lib\")\n#define RtlGenRandom  SystemFunction036\nmi_decl_externc BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  return (RtlGenRandom(buf, (ULONG)buf_len) != 0);\n}\n\n#else\n\n#ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG\n#define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002\n#endif\n\ntypedef LONG (NTAPI *PBCryptGenRandom)(HANDLE, PUCHAR, ULONG, ULONG);\nstatic  PBCryptGenRandom pBCryptGenRandom = NULL;\n\nbool _mi_prim_random_buf(void* buf, size_t buf_len) {\n  mi_assert(buf_len <= ULONG_MAX);\n  if (buf_len > ULONG_MAX) return false;\n  mi_atomic_do_once {\n    HINSTANCE hDll = LoadLibrary(TEXT(\"bcrypt.dll\"));\n    if (hDll != NULL) {\n      pBCryptGenRandom = (PBCryptGenRandom)(void (*)(void))GetProcAddress(hDll, \"BCryptGenRandom\");\n      // FreeLibrary(hDll);  // don't free\n    }\n  }\n  if (pBCryptGenRandom == NULL) return false;\n  return (pBCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0);\n}\n\n#endif  // MI_USE_RTLGENRANDOM\n\n\n//----------------------------------------------------------------\n// Thread pool?\n//----------------------------------------------------------------\n\nbool _mi_prim_thread_is_in_threadpool(void) {\n#if (MI_ARCH_X64 || MI_ARCH_X86 || MI_ARCH_ARM64)\n  if (win_major_version >= 6) {\n    // check if this thread belongs to a windows threadpool\n    // see: <https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/teb/index.htm>\n    struct _TEB* const teb = NtCurrentTeb();\n    void* const pool_data = *((void**)((uint8_t*)teb + (MI_SIZE_BITS == 32 ? 0x0F90 : 0x1778)));\n    return (pool_data != NULL);\n  }\n#endif\n  return false;\n}\n\nvoid _mi_prim_thread_yield(void) {\n  SwitchToThread();\n}\n\n//----------------------------------------------------------------\n// Process & Thread Init/Done\n//----------------------------------------------------------------\n\n//static void mi_debug_out(const char* s) {\n//  HANDLE h = GetStdHandle(STD_ERROR_HANDLE);\n//  WriteConsole(h, s, (DWORD)_mi_strlen(s), NULL, NULL);\n//}\n\nstatic void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {\n  MI_UNUSED(reserved);\n  MI_UNUSED(module);\n  if (reason==DLL_PROCESS_ATTACH) {\n    _mi_auto_process_init();\n  }\n  else if (reason==DLL_PROCESS_DETACH) {\n    _mi_auto_process_done();\n  }\n  else if (reason==DLL_THREAD_DETACH && !_mi_is_redirected()) {\n    _mi_thread_done(NULL);\n  }\n}\n\n\n/* -----------------------------------------------------------------------\n   Auto initialize and finalize mimalloc on process and thread start/end.\n   By default we use a combination of CRT init and TLS sections for\n   both static and dynamic linkage (`MI_WIN_INIT_USE_CRT_TLS`).\n------------------------------------------------------------------------- */\n#if !defined(MI_WIN_INIT_USE_CRT_TLS) && !defined(MI_WIN_INIT_USE_RAW_DLLMAIN) && !defined(MI_WIN_INIT_USE_TLS_DLLMAIN) && !defined(MI_WIN_INIT_USE_FLS)\n  #if !defined(__INTEL_LLVM_COMPILER) && !defined(__INTEL_COMPILER)\n    #define MI_WIN_INIT_USE_CRT_TLS      1  \n  #else\n    #define MI_WIN_INIT_USE_TLS_DLLMAIN  1  /* default for Intel ICX, see issue #1268 */  \n  #endif\n#endif\n\n#if defined(MI_WIN_INIT_USE_CRT_TLS)\n  #define MI_PRIM_HAS_PROCESS_ATTACH  1\n  // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.\n  void _mi_prim_thread_init_auto_done(void) {}\n  void _mi_prim_thread_done_auto_done(void) {}\n  void _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {\n    MI_UNUSED(theap);\n  }\n\n  static bool mi_module_is_dll(PVOID mod) {\n    if (mod==NULL) return false;\n    PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)mod;\n    PIMAGE_NT_HEADERS imageNtHeaders = (PIMAGE_NT_HEADERS)((unsigned char*)imageDosHeader + imageDosHeader->e_lfanew);\n    return ((imageNtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL);\n  }\n\n  static bool mi_current_module_is_dll(void) {\n    HMODULE mod = NULL;\n    const BOOL ok = GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)mi_current_module_is_dll, &mod);\n    return (ok && mi_module_is_dll(mod));\n  }\n\n  // Hook into CRT initialization and finalization.\n  static void mi_cdecl mi_crt_done(void) {\n    // mi_debug_out(mi_current_module_is_dll() ? \"crt dll done\\n\" : \"crt exe done\\n\");\n    mi_win_main(NULL, DLL_PROCESS_DETACH, 0);\n  }\n\n  static int mi_cdecl mi_crt_init(void) {\n    // mi_debug_out(mi_current_module_is_dll() ? \"crt dll init\\n\" : \"crt exe init\\n\");\n    if (mi_current_module_is_dll()) {\n      // in a dll, atexit (crt_done) is called after tls process detach\n      atexit(&mi_crt_done);\n    }\n    return 0;\n  }\n\n  // We also hook into the Windows loader TLS initialization and finalization.\n  static void NTAPI mi_tls_attach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_THREAD_ATTACH) {\n      //mi_debug_out(\"tls thread attach\\n\");\n      mi_win_main(module, reason, reserved);\n    }\n    else if (reason == DLL_PROCESS_ATTACH) {\n      // mi_debug_out(mi_module_is_dll(module) ? \"tls dll process attach\\n\" : \"tls exe process attach\\n\");\n      // tls process attach is always called before crt init\n      mi_win_main(module, reason, reserved);\n    }\n  }\n\n  static void NTAPI mi_tls_detach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_THREAD_DETACH) {\n      //mi_debug_out(\"tls thread detach\\n\");\n      mi_win_main(module, reason, reserved);\n    }\n    else if (reason == DLL_PROCESS_DETACH) {\n      // mi_debug_out(mi_module_is_dll(module) ? \"tls dll process detach\\n\" : \"tls exe process detach\\n\");\n      if (!mi_module_is_dll(module)) {\n        // in an exe, tls process detach is called after atexit (mi_crt_done)\n        mi_win_main(module, reason, reserved);\n      }\n    }\n  }\n\n  // Set up TLS callbacks in a statically linked library by using special data sections.\n  // See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>\n  // We use 2 entries to ensure we call attach events before constructors\n  // are called, and detach events after destructors are called.\n  // We also set up a CRT initialization callback.\n  #if defined(__cplusplus)\n  extern \"C\" {\n  #endif\n\n  typedef int (mi_cdecl* mi_crt_callback_t)(void);\n  #if defined(_WIN64)\n    #pragma comment(linker, \"/INCLUDE:_tls_used\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_post\")\n    #pragma const_seg(\".CRT$XLB\")\n      extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];\n      const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };\n    #pragma const_seg()\n    #pragma const_seg(\".CRT$XLY\")\n      extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];\n      const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };\n    #pragma const_seg()\n    #pragma const_seg(\".CRT$XIB\")\n      extern const mi_crt_callback_t _mi_crt_callback_init[];\n      const mi_crt_callback_t _mi_crt_callback_init[] = { &mi_crt_init };\n    #pragma const_seg()\n  #else\n    #pragma comment(linker, \"/INCLUDE:__tls_used\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_post\")\n    #pragma data_seg(\".CRT$XLB\")\n      PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };\n    #pragma data_seg()\n    #pragma data_seg(\".CRT$XLY\")\n      PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };\n    #pragma data_seg()\n    #pragma data_seg(\".CRT$XIB\")\n      mi_crt_callback_t _mi_crt_callback_init[] = { &mi_crt_init };\n    #pragma data_seg()\n  #endif\n\n  #if defined(__cplusplus)\n  }\n  #endif\n\n/* ----------------------------------------------------------------\n  Here we use a combination of the raw DLL main and TLS sections for\n  both static and dynamic linkage. This is perhaps the most robust as\n  the raw DLL main ensure we can close mimalloc latest possible.\n  However, it can lead to link errors with on `_pRawDllMain` if other\n  libraries also try to hook into this (like Boost).\n*/\n#elif defined(MI_WIN_INIT_USE_RAW_DLLMAIN)\n  #define MI_PRIM_HAS_PROCESS_ATTACH  1\n  // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.\n  void _mi_prim_thread_init_auto_done(void) {}\n  void _mi_prim_thread_done_auto_done(void) {}\n  void _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {\n    MI_UNUSED(theap);\n  }\n\n  // If linked into a DLL module, this raw entry is called before the CRT attach and\n  // after the CRT detach through the CRT _pRawDllMain pointer.\n  static BOOL NTAPI mi_dll_main_raw(PVOID module, DWORD reason, LPVOID reserved) {\n    mi_win_main(module, reason, reserved);\n    return TRUE;\n  }\n\n  // Set the value of the CRT _pRawDllMain pointer\n  #if defined(__cplusplus)\n  extern \"C\"\n  #endif\n  PVOID _pRawDllMain = (PVOID)&mi_dll_main_raw;\n\n  // We also hook into the Windows loader TLS initialization and finalization.\n  // If we are linked into an EXE module we rely on these as `mi_dll_main_raw`\n  // is not called (and otherwise we ignore the TLS callbacks by checking if we are in a DLL).\n  static bool mi_module_is_dll(PVOID mod) {\n    if (mod==NULL) return false;\n    PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)mod;\n    PIMAGE_NT_HEADERS imageNtHeaders = (PIMAGE_NT_HEADERS)((unsigned char*)imageDosHeader + imageDosHeader->e_lfanew);\n    return ((imageNtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL);\n  }\n\n  static void NTAPI mi_tls_attach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_PROCESS_ATTACH || reason == DLL_THREAD_ATTACH) {\n      if (!mi_module_is_dll(module)) {\n        mi_win_main(module, reason, reserved);\n      }\n    }\n  }\n\n  static void NTAPI mi_tls_detach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_PROCESS_DETACH || reason == DLL_THREAD_DETACH) {\n      if (!mi_module_is_dll(module)) {\n        mi_win_main(module, reason, reserved);\n      }\n    }\n  }\n\n  // Set up TLS callbacks in a statically linked library by using special data sections.\n  // See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>\n  // We use 2 entries to ensure we call attach events before constructors\n  // are called, and detach events after destructors are called.\n  #if defined(__cplusplus)\n  extern \"C\" {\n  #endif\n\n  #if defined(_WIN64)\n    #pragma comment(linker, \"/INCLUDE:_tls_used\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_post\")\n    #pragma const_seg(\".CRT$XLB\")\n      extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];\n      const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };\n    #pragma const_seg()\n    #pragma const_seg(\".CRT$XLY\")\n      extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];\n      const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };\n    #pragma const_seg()\n  #else\n    #pragma comment(linker, \"/INCLUDE:__tls_used\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_post\")\n    #pragma data_seg(\".CRT$XLB\")\n      PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };\n    #pragma data_seg()\n    #pragma data_seg(\".CRT$XLY\")\n      PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };\n    #pragma data_seg()\n  #endif\n\n  #if defined(__cplusplus)\n  }\n  #endif\n\n/* --------------------------------------------------------------------\n   Legacy options: DllMain, TLS, and FLS\n   --------------------------------------------------------------------*/\n#elif defined(MI_WIN_INIT_USE_TLS_DLLMAIN) && defined(MI_SHARED_LIB)\n  #define MI_PRIM_HAS_PROCESS_ATTACH  1\n\n  // Windows DLL: easy to hook into process_init and thread_done\n  BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) {\n    mi_win_main((PVOID)inst,reason,reserved);\n    return TRUE;\n  }\n\n  // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.\n  void _mi_prim_thread_init_auto_done(void) { }\n  void _mi_prim_thread_done_auto_done(void) { }\n  void _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {\n    MI_UNUSED(theap);\n  }\n\n#elif defined(MI_WIN_INIT_USE_TLS_DLLMAIN)\n  #define MI_PRIM_HAS_PROCESS_ATTACH  1\n\n  static void NTAPI mi_win_main_attach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_PROCESS_ATTACH || reason == DLL_THREAD_ATTACH) {\n      mi_win_main(module, reason, reserved);\n    }\n  }\n  static void NTAPI mi_win_main_detach(PVOID module, DWORD reason, LPVOID reserved) {\n    if (reason == DLL_PROCESS_DETACH || reason == DLL_THREAD_DETACH) {\n      mi_win_main(module, reason, reserved);\n    }\n  }\n\n  // Set up TLS callbacks in a statically linked library by using special data sections.\n  // See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>\n  // We use 2 entries to ensure we call attach events before constructors\n  // are called, and detach events after destructors are called.\n  #if defined(__cplusplus)\n  extern \"C\" {\n  #endif\n\n  #if defined(_WIN64)\n    #pragma comment(linker, \"/INCLUDE:_tls_used\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:_mi_tls_callback_post\")\n    #pragma const_seg(\".CRT$XLB\")\n    extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];\n    const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_win_main_attach };\n    #pragma const_seg()\n    #pragma const_seg(\".CRT$XLY\")\n    extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];\n    const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_win_main_detach };\n    #pragma const_seg()\n  #else\n    #pragma comment(linker, \"/INCLUDE:__tls_used\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_pre\")\n    #pragma comment(linker, \"/INCLUDE:__mi_tls_callback_post\")\n    #pragma data_seg(\".CRT$XLB\")\n    PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_win_main_attach };\n    #pragma data_seg()\n    #pragma data_seg(\".CRT$XIY\")\n    PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_win_main_detach };\n    #pragma data_seg()\n  #endif\n\n  #if defined(__cplusplus)\n  }\n  #endif\n\n  // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.\n  void _mi_prim_thread_init_auto_done(void) { }\n  void _mi_prim_thread_done_auto_done(void) { }\n  void _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {\n    MI_UNUSED(theap);\n  }\n\n#elif defined(MI_WIN_INIT_USE_FLS) // deprecated: statically linked, use fiber api\n\n  #if defined(_MSC_VER) // on clang/gcc use the constructor attribute (in `src/prim/prim.c`)\n    // MSVC: use data section magic for static libraries\n    // See <https://www.codeguru.com/cpp/misc/misc/applicationcontrol/article.php/c6945/Running-Code-Before-and-After-Main.htm>\n    #define MI_PRIM_HAS_PROCESS_ATTACH 1\n\n    static int mi_process_attach(void) {\n      mi_win_main(NULL,DLL_PROCESS_ATTACH,NULL);\n      atexit(&_mi_auto_process_done);\n      return 0;\n    }\n    typedef int(*mi_crt_callback_t)(void);\n    #if defined(_WIN64)\n      #pragma comment(linker, \"/INCLUDE:_mi_tls_callback\")\n      #pragma section(\".CRT$XIU\", long, read)\n    #else\n      #pragma comment(linker, \"/INCLUDE:__mi_tls_callback\")\n    #endif\n    #pragma data_seg(\".CRT$XIU\")\n    mi_decl_externc mi_crt_callback_t _mi_tls_callback[] = { &mi_process_attach };\n    #pragma data_seg()\n  #endif\n\n  // use the fiber api for calling `_mi_thread_done`.\n  #include <fibersapi.h>\n  #if (_WIN32_WINNT < 0x600)  // before Windows Vista\n  WINBASEAPI DWORD WINAPI FlsAlloc( _In_opt_ PFLS_CALLBACK_FUNCTION lpCallback );\n  WINBASEAPI PVOID WINAPI FlsGetValue( _In_ DWORD dwFlsIndex );\n  WINBASEAPI BOOL  WINAPI FlsSetValue( _In_ DWORD dwFlsIndex, _In_opt_ PVOID lpFlsData );\n  WINBASEAPI BOOL  WINAPI FlsFree(_In_ DWORD dwFlsIndex);\n  #endif\n\n  static DWORD mi_fls_key = (DWORD)(-1);\n\n  static void NTAPI mi_fls_done(PVOID value) {\n    mi_theap_t* theap = (mi_theap_t*)value;\n    if (theap != NULL) {\n      _mi_thread_done(theap);\n      FlsSetValue(mi_fls_key, NULL);  // prevent recursion as _mi_thread_done may set it back to the main theap, issue #672\n    }\n  }\n\n  void _mi_prim_thread_init_auto_done(void) {\n    mi_fls_key = FlsAlloc(&mi_fls_done);\n  }\n\n  void _mi_prim_thread_done_auto_done(void) {\n    // call thread-done on all threads (except the main thread) to prevent\n    // dangling callback pointer if statically linked with a DLL; Issue #208\n    FlsFree(mi_fls_key);\n  }\n\n  void _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {\n    mi_assert_internal(mi_fls_key != (DWORD)(-1));\n    FlsSetValue(mi_fls_key, theap);\n  }\n#else\n#error \"define windows process and thread auto initialization\"\n#endif\n\n// ----------------------------------------------------\n// Communicate with the redirection module on Windows\n// ----------------------------------------------------\n#if defined(MI_SHARED_LIB) && !defined(MI_WIN_NOREDIRECT)\n  #define MI_PRIM_HAS_ALLOCATOR_INIT 1\n\n  static bool mi_redirected = false;   // true if malloc redirects to mi_malloc\n\n  bool _mi_is_redirected(void) {\n    return mi_redirected;\n  }\n\n  #ifdef __cplusplus\n  extern \"C\" {\n  #endif\n  mi_decl_export void _mi_redirect_entry(DWORD reason) {\n    // called on redirection; careful as this may be called before DllMain\n    if (reason == DLL_PROCESS_ATTACH) {\n      mi_redirected = true;\n    }\n    else if (reason == DLL_PROCESS_DETACH) {\n      mi_redirected = false;\n    }\n    else if (reason == DLL_THREAD_DETACH) {\n      // mi_debug_out(\"redirect thread detach\\n\");\n      _mi_thread_done(NULL);\n    }\n  }\n  __declspec(dllimport) bool mi_cdecl mi_allocator_init(const char** message);\n  __declspec(dllimport) void mi_cdecl mi_allocator_done(void);\n  #ifdef __cplusplus\n  }\n  #endif\n  bool _mi_allocator_init(const char** message) {\n    return mi_allocator_init(message);\n  }\n  void _mi_allocator_done(void) {\n    mi_allocator_done();\n  }\n#endif\n\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/random.c",
      "sha256": "a96a1acc75fd6595811b28420cf0495b87fac98c4dbc73aa0d742b6824f607c8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2021, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"    // _mi_prim_random_buf\n\n/* ----------------------------------------------------------------------------\nWe use our own PRNG to keep predictable performance of random number generation\nand to avoid implementations that use a lock. We only use the OS provided\nrandom source to initialize the initial seeds. Since we do not need ultimate\nperformance but we do rely on the security (for secret cookies in secure mode)\nwe use a cryptographically secure generator (chacha20).\n-----------------------------------------------------------------------------*/\n\n#define MI_CHACHA_ROUNDS (20)   // perhaps use 12 for better performance?\n\n\n/* ----------------------------------------------------------------------------\nChacha20 implementation as the original algorithm with a 64-bit nonce\nand counter: https://en.wikipedia.org/wiki/Salsa20\nThe input matrix has sixteen 32-bit values:\nPosition  0 to  3: constant key\nPosition  4 to 11: the key\nPosition 12 to 13: the counter.\nPosition 14 to 15: the nonce.\n\nThe implementation uses regular C code which compiles very well on modern compilers.\n(gcc x64 has no register spills, and clang 6+ uses SSE instructions)\n-----------------------------------------------------------------------------*/\n\nstatic inline void qround(uint32_t x[16], size_t a, size_t b, size_t c, size_t d) {\n  x[a] += x[b]; x[d] = mi_rotl32(x[d] ^ x[a], 16);\n  x[c] += x[d]; x[b] = mi_rotl32(x[b] ^ x[c], 12);\n  x[a] += x[b]; x[d] = mi_rotl32(x[d] ^ x[a], 8);\n  x[c] += x[d]; x[b] = mi_rotl32(x[b] ^ x[c], 7);\n}\n\nstatic void chacha_block(mi_random_ctx_t* ctx)\n{\n  // scramble into `x`\n  uint32_t x[16];\n  for (size_t i = 0; i < 16; i++) {\n    x[i] = ctx->input[i];\n  }\n  for (size_t i = 0; i < MI_CHACHA_ROUNDS; i += 2) {\n    qround(x, 0, 4,  8, 12);\n    qround(x, 1, 5,  9, 13);\n    qround(x, 2, 6, 10, 14);\n    qround(x, 3, 7, 11, 15);\n    qround(x, 0, 5, 10, 15);\n    qround(x, 1, 6, 11, 12);\n    qround(x, 2, 7,  8, 13);\n    qround(x, 3, 4,  9, 14);\n  }\n\n  // add scrambled data to the initial state\n  for (size_t i = 0; i < 16; i++) {\n    ctx->output[i] = x[i] + ctx->input[i];\n  }\n  ctx->output_available = 16;\n\n  // increment the counter for the next round\n  ctx->input[12] += 1;\n  if (ctx->input[12] == 0) {\n    ctx->input[13] += 1;\n    if (ctx->input[13] == 0) {  // and keep increasing into the nonce\n      ctx->input[14] += 1;\n    }\n  }\n}\n\nstatic uint32_t chacha_next32(mi_random_ctx_t* ctx) {\n  if (ctx->output_available <= 0) {\n    chacha_block(ctx);\n    ctx->output_available = 16; // (assign again to suppress static analysis warning)\n  }\n  const uint32_t x = ctx->output[16 - ctx->output_available];\n  ctx->output[16 - ctx->output_available] = 0; // reset once the data is handed out\n  ctx->output_available--;\n  return x;\n}\n\nstatic inline uint32_t read32(const uint8_t* p, size_t idx32) {\n  const size_t i = 4*idx32;\n  return ((uint32_t)p[i+0] | (uint32_t)p[i+1] << 8 | (uint32_t)p[i+2] << 16 | (uint32_t)p[i+3] << 24);\n}\n\nstatic void chacha_init(mi_random_ctx_t* ctx, const uint8_t key[32], uint64_t nonce)\n{\n  // since we only use chacha for randomness (and not encryption) we\n  // do not _need_ to read 32-bit values as little endian but we do anyways\n  // just for being compatible :-)\n  ctx->output_available = 0;\n  _mi_memzero(ctx->output,sizeof(ctx->output));\n  for (size_t i = 0; i < 4; i++) {\n    const uint8_t* sigma = (uint8_t*)\"expand 32-byte k\";\n    ctx->input[i] = read32(sigma,i);\n  }\n  for (size_t i = 0; i < 8; i++) {\n    ctx->input[i + 4] = read32(key,i);\n  }\n  ctx->input[12] = 0;\n  ctx->input[13] = 0;\n  ctx->input[14] = (uint32_t)nonce;\n  ctx->input[15] = (uint32_t)(nonce >> 32);\n}\n\nstatic void chacha_split(mi_random_ctx_t* ctx, uint64_t nonce, mi_random_ctx_t* ctx_new) {\n  _mi_memzero(ctx_new, sizeof(*ctx_new));\n  ctx_new->weak = ctx->weak;\n  _mi_memcpy(ctx_new->input, ctx->input, sizeof(ctx_new->input));\n  ctx_new->input[12] = 0;\n  ctx_new->input[13] = 0;\n  ctx_new->input[14] = (uint32_t)nonce;\n  ctx_new->input[15] = (uint32_t)(nonce >> 32);\n  mi_assert_internal(ctx->input[14] != ctx_new->input[14] || ctx->input[15] != ctx_new->input[15]); // do not reuse nonces!\n  chacha_block(ctx_new);\n}\n\n\n/* ----------------------------------------------------------------------------\nRandom interface\n-----------------------------------------------------------------------------*/\n\n#if MI_DEBUG>1\nstatic bool mi_random_is_initialized(mi_random_ctx_t* ctx) {\n  return (ctx != NULL && ctx->input[0] != 0);\n}\n#endif\n\nvoid _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* ctx_new) {\n  mi_assert_internal(mi_random_is_initialized(ctx));\n  mi_assert_internal(ctx != ctx_new);\n  chacha_split(ctx, (uintptr_t)ctx_new /*nonce*/, ctx_new);\n}\n\nuintptr_t _mi_random_next(mi_random_ctx_t* ctx) {\n  mi_assert_internal(mi_random_is_initialized(ctx));\n  uintptr_t r;\n  do {\n    #if MI_INTPTR_SIZE <= 4\n    r = chacha_next32(ctx);\n    #elif MI_INTPTR_SIZE == 8\n    r = (((uintptr_t)chacha_next32(ctx) << 32) | chacha_next32(ctx));\n    #else\n    # error \"define mi_random_next for this platform\"\n    #endif\n  } while (r==0);\n  return r;\n}\n\n\n/* ----------------------------------------------------------------------------\nTo initialize a fresh random context.\nIf we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR.\n-----------------------------------------------------------------------------*/\n\nuintptr_t _mi_os_random_weak(uintptr_t extra_seed) {\n  uintptr_t x = (uintptr_t)&_mi_os_random_weak ^ extra_seed; // ASLR makes the address random\n  x ^= _mi_prim_clock_now();\n  // and do a few randomization steps\n  uintptr_t max = ((x ^ (x >> 17)) & 0x0F) + 1;\n  for (uintptr_t i = 0; i < max || x==0; i++, x++) {\n    x = _mi_random_shuffle(x);\n  }\n  mi_assert_internal(x != 0);\n  return x;\n}\n\nstatic void mi_random_init_ex(mi_random_ctx_t* ctx, bool use_weak) {\n  uint8_t key[32];\n  if (use_weak || !_mi_prim_random_buf(key, sizeof(key))) {\n    // if we fail to get random data from the OS, we fall back to a\n    // weak random source based on the current time\n    #if !defined(__wasi__)\n    if (!use_weak) { _mi_warning_message(\"unable to use secure randomness\\n\"); }\n    #endif\n    uintptr_t x = _mi_os_random_weak(0);\n    for (size_t i = 0; i < 32; i+=4, x++) {  \n      x = _mi_random_shuffle(x);\n      key[i]   = (uint8_t)(x);\n      key[i+1] = (uint8_t)(x>>8);\n      key[i+2] = (uint8_t)(x>>16);\n      key[i+3] = (uint8_t)(x>>24);      \n    }\n    ctx->weak = true;\n  }\n  else {\n    ctx->weak = false;\n  }\n  chacha_init(ctx, key, (uintptr_t)ctx /*nonce*/ );\n}\n\nvoid _mi_random_init(mi_random_ctx_t* ctx) {\n  mi_random_init_ex(ctx, false);\n}\n\nvoid _mi_random_init_weak(mi_random_ctx_t * ctx) {\n  mi_random_init_ex(ctx, true);\n}\n\nvoid _mi_random_reinit_if_weak(mi_random_ctx_t * ctx) {\n  if (ctx->weak) {\n    _mi_random_init(ctx);\n  }\n}\n\n/* --------------------------------------------------------\ntest vectors from <https://tools.ietf.org/html/rfc8439>\n----------------------------------------------------------- */\n/*\nstatic bool array_equals(uint32_t* x, uint32_t* y, size_t n) {\n  for (size_t i = 0; i < n; i++) {\n    if (x[i] != y[i]) return false;\n  }\n  return true;\n}\nstatic void chacha_test(void)\n{\n  uint32_t x[4] = { 0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567 };\n  uint32_t x_out[4] = { 0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb };\n  qround(x, 0, 1, 2, 3);\n  mi_assert_internal(array_equals(x, x_out, 4));\n\n  uint32_t y[16] = {\n       0x879531e0,  0xc5ecf37d,  0x516461b1,  0xc9a62f8a,\n       0x44c20ef3,  0x3390af7f,  0xd9fc690b,  0x2a5f714c,\n       0x53372767,  0xb00a5631,  0x974c541a,  0x359e9963,\n       0x5c971061,  0x3d631689,  0x2098d9d6,  0x91dbd320 };\n  uint32_t y_out[16] = {\n       0x879531e0,  0xc5ecf37d,  0xbdb886dc,  0xc9a62f8a,\n       0x44c20ef3,  0x3390af7f,  0xd9fc690b,  0xcfacafd2,\n       0xe46bea80,  0xb00a5631,  0x974c541a,  0x359e9963,\n       0x5c971061,  0xccc07c79,  0x2098d9d6,  0x91dbd320 };\n  qround(y, 2, 7, 8, 13);\n  mi_assert_internal(array_equals(y, y_out, 16));\n\n  mi_random_ctx_t r = {\n    { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,\n      0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,\n      0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,\n      0x00000001, 0x09000000, 0x4a000000, 0x00000000 },\n    {0},\n    0\n  };\n  uint32_t r_out[16] = {\n       0xe4e7f110, 0x15593bd1, 0x1fdd0f50, 0xc47120a3,\n       0xc7f4d1c7, 0x0368c033, 0x9aaa2204, 0x4e6cd4c3,\n       0x466482d2, 0x09aa9f07, 0x05d7c214, 0xa2028bd9,\n       0xd19c12b5, 0xb94e16de, 0xe883d0cb, 0x4e3c50a2 };\n  chacha_block(&r);\n  mi_assert_internal(array_equals(r.output, r_out, 16));\n}\n*/\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/static.c",
      "sha256": "4059be2a6676693be3433f5aedc711f56301772e65f3573654c236d6d1cfd074",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2020, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#ifndef _DEFAULT_SOURCE\n#define _DEFAULT_SOURCE\n#endif\n#if defined(__sun)\n// same remarks as os.c for the static's context.\n#undef _XOPEN_SOURCE\n#undef _POSIX_C_SOURCE\n#endif\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n\n// For a static override we create a single object file\n// containing the whole library. If it is linked first\n// it will override all the standard library allocation\n// functions (on Unix's).\n#include \"alloc.c\"          // includes alloc-override.c and free.c\n#include \"alloc-aligned.c\"\n#include \"alloc-posix.c\"\n#include \"arena.c\"\n#include \"arena-meta.c\"\n#include \"bitmap.c\"\n#include \"heap.c\"\n#include \"init.c\"\n#include \"libc.c\"\n#include \"options.c\"\n#include \"os.c\"\n#include \"page.c\"           // includes page-queue.c\n#include \"page-map.c\"\n#include \"random.c\"\n#include \"stats.c\"\n#include \"theap.c\"\n#include \"threadlocal.c\"\n#include \"prim/prim.c\"\n#if MI_OSX_ZONE\n#include \"prim/osx/alloc-override-zone.c\"\n#endif\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/stats.c",
      "sha256": "16825bbc252de422982b5728df7eda181d952824f5e3ce958c7fc85feae64b8e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n#include \"mimalloc.h\"\n#include \"mimalloc-stats.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/atomic.h\"\n#include \"mimalloc/prim.h\"\n\n#include <string.h> // memset\n\n#if defined(_MSC_VER) && (_MSC_VER < 1920)\n#pragma warning(disable:4204)  // non-constant aggregate initializer\n#endif\n\n/* -----------------------------------------------------------\n  Statistics operations\n----------------------------------------------------------- */\n\nstatic void mi_stat_update_mt(mi_stat_count_t* stat, int64_t amount) {\n  if (amount == 0) return;\n  // add atomically\n  int64_t current = mi_atomic_addi64_relaxed(&stat->current, amount);\n  mi_atomic_maxi64_relaxed(&stat->peak, current + amount);\n  if (amount > 0) {\n    mi_atomic_addi64_relaxed(&stat->total, amount);\n  }\n}\n\nstatic void mi_stat_update(mi_stat_count_t* stat, int64_t amount) {\n  if (amount == 0) return;\n  // add thread local\n  stat->current += amount;\n  if (stat->current > stat->peak) { stat->peak = stat->current; }\n  if (amount > 0) { stat->total += amount; }\n}\n\n\nvoid __mi_stat_counter_increase_mt(mi_stat_counter_t* stat, size_t amount) {\n  mi_atomic_addi64_relaxed(&stat->total, (int64_t)amount);\n}\n\nvoid __mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount) {\n  stat->total += amount;\n}\n\nvoid __mi_stat_increase_mt(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_update_mt(stat, (int64_t)amount);\n}\nvoid __mi_stat_increase(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_update(stat, (int64_t)amount);\n}\n\nvoid __mi_stat_decrease_mt(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_update_mt(stat, -((int64_t)amount));\n}\nvoid __mi_stat_decrease(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_update(stat, -((int64_t)amount));\n}\n\n\n// Adjust stats to compensate; for example before committing a range,\n// first adjust downwards with parts that were already committed so\n// we avoid double counting.\nstatic void mi_stat_adjust_mt(mi_stat_count_t* stat, int64_t amount) {\n  if (amount == 0) return;\n  // adjust atomically\n  mi_atomic_addi64_relaxed(&stat->current, amount);\n  mi_atomic_addi64_relaxed(&stat->total, amount);\n}\n\nstatic void mi_stat_adjust(mi_stat_count_t* stat, int64_t amount) {\n  if (amount == 0) return;\n  stat->current += amount;\n  stat->total += amount;\n}\n\nvoid __mi_stat_adjust_increase_mt(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_adjust_mt(stat, (int64_t)amount);\n}\nvoid __mi_stat_adjust_increase(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_adjust(stat, (int64_t)amount);\n}\nvoid __mi_stat_adjust_decrease_mt(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_adjust_mt(stat, -((int64_t)amount));\n}\nvoid __mi_stat_adjust_decrease(mi_stat_count_t* stat, size_t amount) {\n  mi_stat_adjust(stat, -((int64_t)amount));\n}\n\n\n// must be thread safe as it is called from stats_merge\nstatic void mi_stat_count_add_mt(mi_stat_count_t* stat, const mi_stat_count_t* src) {\n  if (stat==src) return;\n  mi_atomic_void_addi64_relaxed(&stat->total, &src->total);\n  const int64_t prev_current = mi_atomic_addi64_relaxed(&stat->current, src->current);\n\n  // Global current plus thread peak approximates new global peak\n  // note: peak scores do really not work across threads.\n  // we used to just add them together but that often overestimates in practice.\n  // similarly, max does not seem to work well. The current approach\n  // by Artem Kharytoniuk (@artem-lunarg) seems to work better, see PR#1112\n  // for a longer description.\n  mi_atomic_maxi64_relaxed(&stat->peak, prev_current + src->peak);\n}\n\nstatic void mi_stat_counter_add_mt(mi_stat_counter_t* stat, const mi_stat_counter_t* src) {\n  if (stat==src) return;\n  mi_atomic_void_addi64_relaxed(&stat->total, &src->total);\n}\n\n#define MI_STAT_COUNT(stat)    mi_stat_count_add_mt(&stats->stat, &src->stat);\n#define MI_STAT_COUNTER(stat)  mi_stat_counter_add_mt(&stats->stat, &src->stat);\n\n// must be thread safe as it is called from stats_merge\nstatic void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) {\n  if (stats==NULL || src==NULL || stats==src) return;\n\n  // copy all fields\n  MI_STAT_FIELDS()\n\n  #if MI_STAT>1\n  for (size_t i = 0; i <= MI_BIN_HUGE; i++) {\n    mi_stat_count_add_mt(&stats->malloc_bins[i], &src->malloc_bins[i]);\n  }\n  #endif\n  for (size_t i = 0; i <= MI_BIN_HUGE; i++) {\n    mi_stat_count_add_mt(&stats->page_bins[i], &src->page_bins[i]);\n  }\n}\n\n#undef MI_STAT_COUNT\n#undef MI_STAT_COUNTER\n\n/* -----------------------------------------------------------\n  Display statistics\n----------------------------------------------------------- */\n\n// unit > 0 : size in binary bytes\n// unit == 0: count as decimal\n// unit < 0 : count in binary\nstatic void mi_printf_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg, const char* fmt) {\n  char buf[32]; _mi_memzero_var(buf);\n  int  len = 32;\n  const char* suffix = (unit <= 0 ? \" \" : \"B\");\n  const int64_t base = (unit == 0 ? 1000 : 1024);\n  if (unit>0) n *= unit;\n\n  const int64_t pos = (n < 0 ? -n : n);\n  if (pos < base) {\n    if (n!=1 || suffix[0] != 'B') {  // skip printing 1 B for the unit column\n      _mi_snprintf(buf, len, \"%lld   %-3s\", (long long)n, (n==0 ? \"\" : suffix));\n    }\n  }\n  else {\n    int64_t divider = base;\n    const char* magnitude = \"K\";\n    if (pos >= divider*base) { divider *= base; magnitude = \"M\"; }\n    if (pos >= divider*base) { divider *= base; magnitude = \"G\"; }\n    const int64_t tens = (n / (divider/10));\n    const long whole = (long)(tens/10);\n    const long frac1 = (long)(tens%10);\n    char unitdesc[8];\n    _mi_snprintf(unitdesc, 8, \"%s%s%s\", magnitude, (base==1024 ? \"i\" : \"\"), suffix);\n    _mi_snprintf(buf, len, \"%ld.%ld %-3s\", whole, (frac1 < 0 ? -frac1 : frac1), unitdesc);\n  }\n  _mi_fprintf(out, arg, (fmt==NULL ? \"%12s\" : fmt), buf);\n}\n\n\nstatic void mi_print_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg) {\n  mi_printf_amount(n,unit,out,arg,NULL);\n}\n\nstatic void mi_print_count(int64_t n, int64_t unit, mi_output_fun* out, void* arg) {\n  if (unit==1) _mi_fprintf(out, arg, \"%12s\",\" \");\n          else mi_print_amount(n,0,out,arg);\n}\n\nstatic void mi_stat_print_ex(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg, const char* notok ) {\n  _mi_fprintf(out, arg,\"  %-10s:\", msg);\n  if (unit != 0) {\n    if (unit > 0) {\n      mi_print_amount(stat->peak, unit, out, arg);\n      mi_print_amount(stat->total, unit, out, arg);\n      // mi_print_amount(stat->freed, unit, out, arg);\n      mi_print_amount(stat->current, unit, out, arg);\n      mi_print_amount(unit, 1, out, arg);\n      mi_print_count(stat->total, unit, out, arg);\n    }\n    else {\n      mi_print_amount(stat->peak, -1, out, arg);\n      mi_print_amount(stat->total, -1, out, arg);\n      // mi_print_amount(stat->freed, -1, out, arg);\n      mi_print_amount(stat->current, -1, out, arg);\n      if (unit == -1) {\n        _mi_fprintf(out, arg, \"%24s\", \"\");\n      }\n      else {\n        mi_print_amount(-unit, 1, out, arg);\n        mi_print_count((stat->total / -unit), 0, out, arg);\n      }\n    }\n    if (stat->current != 0) {\n      _mi_fprintf(out, arg, \"  \");\n      _mi_fprintf(out, arg, (notok == NULL ? \"not all freed\" : notok));\n      _mi_fprintf(out, arg, \"\\n\");\n    }\n    else {\n      _mi_fprintf(out, arg, \"  ok\\n\");\n    }\n  }\n  else {\n    mi_print_amount(stat->peak, 0, out, arg);\n    mi_print_amount(stat->total, 0, out, arg);\n    mi_print_amount(stat->current, 0, out, arg);\n    _mi_fprintf(out, arg, \"\\n\");\n  }\n}\n\nstatic void mi_stat_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg) {\n  mi_stat_print_ex(stat, msg, unit, out, arg, NULL);\n}\n\n#if MI_STAT>1\nstatic void mi_stat_total_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg) {\n  _mi_fprintf(out, arg, \"  %-10s:\", msg);\n  _mi_fprintf(out, arg, \"%12s\", \" \");  // no peak\n  mi_print_amount(stat->total, unit, out, arg);\n  _mi_fprintf(out, arg, \"\\n\");\n}\n#endif\n\nstatic void mi_stat_counter_print(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg ) {\n  _mi_fprintf(out, arg, \"  %-10s:\", msg);\n  mi_print_amount(stat->total, 0, out, arg);\n  _mi_fprintf(out, arg, \"\\n\");\n}\n\nstatic void mi_stat_counter_print_size(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg ) {\n  _mi_fprintf(out, arg, \"  %-10s:\", msg);\n  mi_print_amount(stat->total, 1, out, arg);\n  _mi_fprintf(out, arg, \"\\n\");\n}\n\nstatic void mi_stat_average_print(int64_t count, int64_t total, const char* msg, mi_output_fun* out, void* arg) {\n  const int64_t avg_tens = (count == 0 ? 0 : (total*10 / count));\n  const int64_t avg_whole = avg_tens/10;\n  const int64_t avg_frac1 = avg_tens%10;\n  _mi_fprintf(out, arg, \"  %-10s: %5lld.%lld avg\\n\", msg, avg_whole, avg_frac1);\n}\n\n\nstatic void mi_print_header(const char* name,mi_output_fun* out, void* arg ) {\n  _mi_fprintf(out, arg, \" %-11s %11s %11s %11s %11s %11s\\n\",\n                        name, \"peak   \", \"total   \", \"current   \", \"block   \", \"total#   \");\n}\n\n#if MI_STAT>1\nstatic bool mi_stats_print_bins(const mi_stat_count_t* bins, size_t max, mi_output_fun* out, void* arg) {\n  bool found = false;\n  char buf[64];\n  for (size_t i = 0; i <= max; i++) {\n    if (bins[i].total > 0) {\n      found = true;\n      const size_t unit = _mi_bin_size((uint8_t)i);\n      const char* pagekind = (unit <= MI_SMALL_MAX_OBJ_SIZE ? \"S\" :\n                               (unit <= MI_MEDIUM_MAX_OBJ_SIZE ? \"M\" :\n                                 (unit <= MI_LARGE_MAX_OBJ_SIZE ? \"L\" : \"H\")));\n      _mi_snprintf(buf, 64, \"bin%2s  %3lu\", pagekind, (long)i);\n      mi_stat_print(&bins[i], buf, (int64_t)unit, out, arg);\n    }\n  }\n  if (found) {\n    _mi_fprintf(out, arg, \"\\n\");\n  }\n  return found;\n}\n#endif\n\n\n\n//------------------------------------------------------------\n// Use an output wrapper for line-buffered output\n// (which is nice when using loggers etc.)\n//------------------------------------------------------------\ntypedef struct buffered_s {\n  mi_output_fun* out;   // original output function\n  void*          arg;   // and state\n  char*          buf;   // local buffer of at least size `count+1`\n  size_t         used;  // currently used chars `used <= count`\n  size_t         count; // total chars available for output\n} buffered_t;\n\nstatic void mi_buffered_flush(buffered_t* buf) {\n  buf->buf[buf->used] = 0;\n  _mi_fputs(buf->out, buf->arg, NULL, buf->buf);\n  buf->used = 0;\n}\n\nstatic void mi_cdecl mi_buffered_out(const char* msg, void* arg) {\n  buffered_t* buf = (buffered_t*)arg;\n  if (msg==NULL || buf==NULL) return;\n  for (const char* src = msg; *src != 0; src++) {\n    char c = *src;\n    if (buf->used >= buf->count) mi_buffered_flush(buf);\n    mi_assert_internal(buf->used < buf->count);\n    buf->buf[buf->used++] = c;\n    if (c == '\\n') mi_buffered_flush(buf);\n  }\n}\n\n//------------------------------------------------------------\n// Print statistics\n//------------------------------------------------------------\n\nmi_decl_export void mi_process_info_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept\n{\n  size_t elapsed;\n  size_t user_time;\n  size_t sys_time;\n  size_t current_rss;\n  size_t peak_rss;\n  size_t current_commit;\n  size_t peak_commit;\n  size_t page_faults;\n  mi_process_info(&elapsed, &user_time, &sys_time, &current_rss, &peak_rss, &current_commit, &peak_commit, &page_faults);\n  _mi_fprintf(out, arg, \"  %-10s: %5zu.%03zu s\\n\", \"elapsed\", elapsed/1000, elapsed%1000);\n  _mi_fprintf(out, arg, \"  %-10s: user: %zu.%03zu s, system: %zu.%03zu s, faults: %zu, peak rss: \", \"process\",\n    user_time/1000, user_time%1000, sys_time/1000, sys_time%1000, page_faults);\n  mi_printf_amount((int64_t)peak_rss, 1, out, arg, \"%s\");\n  if (peak_commit > 0) {\n    _mi_fprintf(out, arg, \", peak commit: \");\n    mi_printf_amount((int64_t)peak_commit, 1, out, arg, \"%s\");\n  }\n  _mi_fprintf(out, arg, \"\\n\");\n}\n\nvoid _mi_stats_print(const char* name, size_t id, const mi_stats_t* stats, mi_output_fun* out0, void* arg0) mi_attr_noexcept {\n  // wrap the output function to be line buffered\n  char buf[256]; _mi_memzero_var(buf);\n  buffered_t buffer = { out0, arg0, NULL, 0, 255 };\n  buffer.buf = buf;\n  mi_output_fun* out = &mi_buffered_out;\n  void* arg = &buffer;\n\n  // and print using that\n  _mi_fprintf(out, arg, \"%s %zu\\n\", name, id);\n\n  if (stats->malloc_normal.total + stats->malloc_huge.total != 0) {\n    #if MI_STAT>1\n    mi_print_header(\"blocks\", out, arg);\n    mi_stats_print_bins(stats->malloc_bins, MI_BIN_HUGE, out, arg);\n    #endif\n    #if MI_STAT\n    mi_stat_print(&stats->malloc_normal, \"binned\", (stats->malloc_normal_count.total == 0 ? -1 : 1), out, arg);\n    mi_stat_print(&stats->malloc_huge, \"huge\", (stats->malloc_huge_count.total == 0 ? -1 : 1), out, arg);\n    mi_stat_count_t total = { 0,0,0 };\n    mi_stat_count_add_mt(&total, &stats->malloc_normal);\n    mi_stat_count_add_mt(&total, &stats->malloc_huge);\n    mi_stat_print_ex(&total, \"total\", 1, out, arg, \"\");\n    #if MI_STAT>1\n    mi_stat_total_print(&stats->malloc_requested, \"malloc req\", 1, out, arg);\n    #endif\n    _mi_fprintf(out, arg, \"\\n\");\n    #endif\n  }\n\n  if (stats->pages.total != 0) {\n    mi_print_header(\"pages\", out, arg);\n    mi_stat_print_ex(&stats->page_committed, \"touched\", 1, out, arg, \"\");\n    // mi_stat_print(&stats->segments, \"segments\", -1, out, arg);\n    // mi_stat_print(&stats->segments_abandoned, \"-abandoned\", -1, out, arg);\n    // mi_stat_print(&stats->segments_cache, \"-cached\", -1, out, arg);\n    mi_stat_print(&stats->pages, \"pages\", 0, out, arg);\n    mi_stat_print(&stats->pages_abandoned, \"abandoned\", 0, out, arg);\n    mi_stat_counter_print(&stats->pages_reclaim_on_alloc, \"reclaima\", out, arg);\n    mi_stat_counter_print(&stats->pages_reclaim_on_free, \"reclaimf\", out, arg);\n    mi_stat_counter_print(&stats->pages_reabandon_full, \"reabandon\", out, arg);\n    mi_stat_counter_print(&stats->pages_unabandon_busy_wait, \"waits\", out, arg);\n    mi_stat_counter_print(&stats->pages_extended, \"extended\", out, arg);\n    mi_stat_counter_print(&stats->pages_retire, \"retire\", out, arg);\n    mi_stat_average_print(stats->page_searches_count.total, stats->page_searches.total, \"searches\", out, arg);\n    _mi_fprintf(out, arg, \"\\n\");\n  }\n\n  if (stats->arena_count.total > 0) {\n    mi_print_header(\"arenas\", out, arg);\n    mi_stat_print_ex(&stats->reserved, \"reserved\", 1, out, arg, \"\");\n    mi_stat_print_ex(&stats->committed, \"committed\", 1, out, arg, \"\");\n    mi_stat_counter_print_size(&stats->reset, \"reset\", out, arg);\n    mi_stat_counter_print_size(&stats->purged, \"purged\", out, arg);\n\n    mi_stat_counter_print(&stats->arena_count, \"arenas\", out, arg);\n    mi_stat_counter_print(&stats->arena_rollback_count, \"rollback\", out, arg);\n    mi_stat_counter_print(&stats->mmap_calls, \"mmaps\", out, arg);\n    mi_stat_counter_print(&stats->commit_calls, \"commits\", out, arg);\n    mi_stat_counter_print(&stats->reset_calls, \"resets\", out, arg);\n    mi_stat_counter_print(&stats->purge_calls, \"purges\", out, arg);\n    mi_stat_counter_print(&stats->malloc_guarded_count, \"guarded\", out, arg);\n    mi_stat_print_ex(&stats->theaps, \"theaps\", 0, out, arg, \"\");\n    mi_stat_print_ex(&stats->heaps, \"heaps\", 0, out, arg, \"\");\n    mi_stat_counter_print(&stats->heaps_delete_wait, \"heap waits\", out, arg);\n    _mi_fprintf(out, arg, \"\\n\");\n\n    mi_print_header(\"process\", out, arg);\n    mi_stat_print_ex(&stats->threads, \"threads\", 0, out, arg, \"\");\n    _mi_fprintf(out, arg, \"  %-10s: %5i\\n\", \"numa nodes\", _mi_os_numa_node_count());\n    mi_process_info_print_out(out, arg);\n  }\n  _mi_fprintf(out, arg, \"\\n\");\n}\n\n\nstatic mi_msecs_t mi_process_start; // = 0\n\n// called on process init\nvoid _mi_stats_init(void) {\n  if (mi_process_start == 0) { mi_process_start = _mi_clock_start(); };\n}\n\nstatic void mi_stats_add_into(mi_stats_t* to, const mi_stats_t* from) {\n  mi_assert_internal(to != NULL && from != NULL);\n  if (to == from) return;\n  mi_stats_add(to, from);\n}\n\nvoid _mi_stats_merge_into(mi_stats_t* to, mi_stats_t* from) {\n  mi_assert_internal(to != NULL && from != NULL);\n  if (to == from) return;\n  mi_stats_add(to, from);\n  _mi_memzero(from, sizeof(mi_stats_t));\n}\n\nstatic const mi_stats_t* mi_stats_merge_theap_to_heap(mi_theap_t* theap) mi_attr_noexcept {\n  mi_stats_t* stats = &theap->stats;\n  mi_stats_t* heap_stats = &_mi_theap_heap(theap)->stats;\n  _mi_stats_merge_into( heap_stats, stats );\n  return heap_stats;\n}\n\nstatic const mi_stats_t* mi_heap_get_stats(mi_heap_t* heap) {\n  if (heap==NULL) { heap = mi_heap_main(); }\n  mi_theap_t* theap = _mi_heap_theap_peek(heap);\n  if (theap==NULL) return &heap->stats;\n              else return mi_stats_merge_theap_to_heap(theap);\n}\n\n// deprecated\nvoid mi_stats_reset(void) mi_attr_noexcept {\n  if (!mi_theap_is_initialized(_mi_theap_default())) return;\n  mi_heap_get_stats(mi_heap_main());\n  mi_heap_stats_merge_to_subproc(mi_heap_main());\n}\n\n\nvoid mi_heap_stats_print_out(mi_heap_t* heap, mi_output_fun* out, void* arg) mi_attr_noexcept {\n  if (heap==NULL) { heap = mi_heap_main(); }\n  _mi_stats_print(\"heap\", heap->heap_seq, mi_heap_get_stats(heap), out, arg);\n}\n\ntypedef struct mi_heap_print_visit_info_s {\n  mi_output_fun* out;\n  void* out_arg;\n} mi_heap_print_visit_info_t;\n\nstatic bool mi_cdecl mi_heap_print_visitor(mi_heap_t* heap, void* arg) {\n  mi_heap_print_visit_info_t* vinfo = (mi_heap_print_visit_info_t*)(arg);\n  mi_heap_stats_print_out(heap, vinfo->out, vinfo->out_arg);\n  return true;\n}\n\n\n// show each heap and then the subproc\nvoid mi_subproc_heap_stats_print_out(mi_subproc_id_t subproc_id, mi_output_fun* out, void* arg) mi_attr_noexcept {\n  mi_subproc_t* subproc = _mi_subproc_from_id(subproc_id);\n  if (subproc==NULL) return;\n  mi_heap_print_visit_info_t vinfo = { out, arg };\n  mi_subproc_visit_heaps(subproc_id, &mi_heap_print_visitor, &vinfo);\n  _mi_stats_print(\"subproc\", subproc->subproc_seq, &subproc->stats, out, arg);\n}\n\n\n// aggregate all stats from the heaps and subproc and print those\nvoid mi_subproc_stats_print_out(mi_subproc_id_t subproc_id, mi_output_fun* out, void* arg) mi_attr_noexcept {\n  mi_subproc_t* subproc = _mi_subproc_from_id(subproc_id);\n  if (subproc==NULL) return;\n  mi_stats_t_decl(stats);\n  if (mi_subproc_stats_get(subproc_id, &stats)) {\n    _mi_stats_print(\"subproc\", subproc->subproc_seq, &stats, out, arg);\n  }\n}\n\nvoid mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept {\n  mi_subproc_stats_print_out(mi_subproc_current(),out, arg);\n}\n\n// deprecated\nvoid mi_stats_print(void* out) mi_attr_noexcept {\n  // for compatibility there is an `out` parameter (which can be `stdout` or `stderr`)\n  mi_stats_print_out((mi_output_fun*)out, NULL);\n}\n\n// deprecated\nvoid mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept {\n  mi_theap_t* theap = _mi_theap_default();\n  if (theap==NULL || !mi_theap_is_initialized(theap)) return;\n  _mi_stats_print(\"heap\", _mi_theap_heap(theap)->heap_seq, &theap->stats, out, arg);\n  mi_stats_merge_theap_to_heap(_mi_theap_default());\n}\n\n\n// ----------------------------------------------------------------\n// Basic timer for convenience; use milli-seconds to avoid doubles\n// ----------------------------------------------------------------\n\nstatic mi_msecs_t mi_clock_diff;\n\nmi_msecs_t _mi_clock_now(void) {\n  return _mi_prim_clock_now();\n}\n\nmi_msecs_t _mi_clock_start(void) {\n  if (mi_clock_diff == 0.0) {\n    mi_msecs_t t0 = _mi_clock_now();\n    mi_clock_diff = _mi_clock_now() - t0;\n  }\n  return _mi_clock_now();\n}\n\nmi_msecs_t _mi_clock_end(mi_msecs_t start) {\n  mi_msecs_t end = _mi_clock_now();\n  return (end - start - mi_clock_diff);\n}\n\n\n// --------------------------------------------------------\n// Basic process statistics\n// --------------------------------------------------------\n\nmi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept\n{\n  mi_process_info_t pinfo;\n  _mi_memzero_var(pinfo);\n  pinfo.elapsed        = _mi_clock_end(mi_process_start);\n  { const mi_subproc_t* subproc = _mi_subproc_main();\n    if (subproc!=NULL) {\n      pinfo.current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)(&subproc->stats.committed.current)));\n      pinfo.peak_commit    = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)(&subproc->stats.committed.peak)));\n    }  \n  }\n  pinfo.current_rss    = pinfo.current_commit;\n  pinfo.peak_rss       = pinfo.peak_commit;\n  pinfo.utime          = 0;\n  pinfo.stime          = 0;\n  pinfo.page_faults    = 0;\n\n  _mi_prim_process_info(&pinfo);\n\n  if (elapsed_msecs!=NULL)  *elapsed_msecs  = (pinfo.elapsed < 0 ? 0 : (pinfo.elapsed < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.elapsed : PTRDIFF_MAX));\n  if (user_msecs!=NULL)     *user_msecs     = (pinfo.utime < 0 ? 0 : (pinfo.utime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.utime : PTRDIFF_MAX));\n  if (system_msecs!=NULL)   *system_msecs   = (pinfo.stime < 0 ? 0 : (pinfo.stime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.stime : PTRDIFF_MAX));\n  if (current_rss!=NULL)    *current_rss    = pinfo.current_rss;\n  if (peak_rss!=NULL)       *peak_rss       = pinfo.peak_rss;\n  if (current_commit!=NULL) *current_commit = pinfo.current_commit;\n  if (peak_commit!=NULL)    *peak_commit    = pinfo.peak_commit;\n  if (page_faults!=NULL)    *page_faults    = pinfo.page_faults;\n}\n\nmi_decl_export void mi_process_info_print(void) mi_attr_noexcept {\n  mi_process_info_print_out(NULL, NULL);\n}\n\n\n// --------------------------------------------------------\n// Return statistics\n// --------------------------------------------------------\n\nsize_t mi_stats_get_bin_size(size_t bin) mi_attr_noexcept {\n  if (bin > MI_BIN_HUGE) return 0;\n  return _mi_bin_size(bin);\n}\n\nstatic bool mi_stats_copy(mi_stats_t* stats_to, const mi_stats_t* stats_from) mi_attr_noexcept {\n  if (stats_to == NULL || stats_to->size != sizeof(mi_stats_t) || stats_to->version != MI_STAT_VERSION) return false;\n  if (stats_from == NULL || stats_from->size != stats_to->size) return false;\n  _mi_memcpy(stats_to, stats_from, stats_to->size);\n  return true;\n}\n\nbool mi_subproc_stats_get_exclusive(mi_subproc_id_t subproc_id, mi_stats_t* stats) mi_attr_noexcept {\n  const mi_subproc_t* subproc = _mi_subproc_from_id(subproc_id);\n  if (subproc==NULL) return false;\n  return mi_stats_copy(stats,&subproc->stats);\n}\n\nbool mi_heap_stats_get(mi_heap_t* heap, mi_stats_t* stats) mi_attr_noexcept {\n  return mi_stats_copy(stats, mi_heap_get_stats(heap));\n}\n\n\nstatic bool mi_cdecl mi_heap_aggregate_visitor(mi_heap_t* heap, void* arg) {\n  mi_stats_t* stats = (mi_stats_t*)arg;\n  mi_stats_add_into(stats, mi_heap_get_stats(heap));\n  return true;\n}\n\nbool mi_subproc_stats_get(mi_subproc_id_t subproc_id, mi_stats_t* stats) mi_attr_noexcept {\n  if (stats==NULL) return false;\n  mi_subproc_t* subproc = _mi_subproc_from_id(subproc_id);\n  if (subproc == NULL) return false;\n  if (!mi_stats_copy(stats, &subproc->stats)) return false;\n  mi_subproc_visit_heaps(subproc_id, &mi_heap_aggregate_visitor, stats);\n  return true;\n}\n\nbool mi_stats_get(mi_stats_t* stats) mi_attr_noexcept {\n  return mi_subproc_stats_get(mi_subproc_current(), stats);\n}\n\n\n// --------------------------------------------------------\n// Statics in json format\n// --------------------------------------------------------\n\ntypedef struct mi_json_buf_s {\n  char*   buf;\n  size_t  size;\n  size_t  used;\n  bool    can_realloc;\n} mi_json_buf_t;\n\nstatic bool mi_json_buf_expand(mi_json_buf_t* hbuf) {\n  if (hbuf==NULL) return false;\n  if (hbuf->buf != NULL && hbuf->size>0) {\n    hbuf->buf[hbuf->size-1] = 0;\n  }\n  if (hbuf->size > SIZE_MAX/2 || !hbuf->can_realloc) return false;\n  const size_t newsize = (hbuf->size == 0 ? mi_good_size(12*MI_KiB) : 2*hbuf->size);\n  char* const  newbuf  = (char*)mi_rezalloc(hbuf->buf, newsize);\n  if (newbuf == NULL) return false;\n  hbuf->buf = newbuf;\n  hbuf->size = newsize;\n  return true;\n}\n\nstatic void mi_json_buf_print(mi_json_buf_t* hbuf, const char* msg) {\n  if (msg==NULL || hbuf==NULL) return;\n  if (hbuf->used + 1 >= hbuf->size && !hbuf->can_realloc) return;\n  for (const char* src = msg; *src != 0; src++) {\n    char c = *src;\n    if (hbuf->used + 1 >= hbuf->size) {\n      if (!mi_json_buf_expand(hbuf)) return;\n    }\n    mi_assert_internal(hbuf->used < hbuf->size);\n    hbuf->buf[hbuf->used++] = c;\n  }\n  mi_assert_internal(hbuf->used < hbuf->size);\n  hbuf->buf[hbuf->used] = 0;\n}\n\nstatic void mi_json_buf_print_count_bin(mi_json_buf_t* hbuf, const char* prefix, const mi_stat_count_t* stat, size_t bin, bool add_comma) {\n  const size_t binsize = mi_stats_get_bin_size(bin);\n  const size_t pagesize = (binsize <= MI_SMALL_MAX_OBJ_SIZE ? MI_SMALL_PAGE_SIZE :\n                            (binsize <= MI_MEDIUM_MAX_OBJ_SIZE ? MI_MEDIUM_PAGE_SIZE :\n                              (binsize <= MI_LARGE_MAX_OBJ_SIZE ? MI_LARGE_PAGE_SIZE : 0)));\n  char buf[128];\n  _mi_snprintf(buf, 128, \"%s{ \\\"total\\\": %lld, \\\"peak\\\": %lld, \\\"current\\\": %lld, \\\"block_size\\\": %zu, \\\"page_size\\\": %zu }%s\\n\", prefix, stat->total, stat->peak, stat->current, binsize, pagesize, (add_comma ? \",\" : \"\"));\n  buf[127] = 0;\n  mi_json_buf_print(hbuf, buf);\n}\n\nstatic void mi_json_buf_print_count_cbin(mi_json_buf_t* hbuf, const char* prefix, const mi_stat_count_t* stat, mi_chunkbin_t bin, bool add_comma) {\n  const char* cbin = \" \";\n  switch(bin) {\n    case MI_CBIN_SMALL:  cbin = \"S\"; break;\n    case MI_CBIN_MEDIUM: cbin = \"M\"; break;\n    case MI_CBIN_LARGE:  cbin = \"L\"; break;\n    case MI_CBIN_HUGE:   cbin = \"H\"; break;\n    case MI_CBIN_OTHER:  cbin = \"X\"; break;\n    default: cbin = \" \"; break;\n  }\n  char buf[128];\n  _mi_snprintf(buf, 128, \"%s{ \\\"total\\\": %lld, \\\"peak\\\": %lld, \\\"current\\\": %lld, \\\"bin\\\": \\\"%s\\\" }%s\\n\", prefix, stat->total, stat->peak, stat->current, cbin, (add_comma ? \",\" : \"\"));\n  buf[127] = 0;\n  mi_json_buf_print(hbuf, buf);\n}\n\nstatic void mi_json_buf_print_count(mi_json_buf_t* hbuf, const char* prefix, const mi_stat_count_t* stat, bool add_comma) {\n  char buf[128];\n  _mi_snprintf(buf, 128, \"%s{ \\\"total\\\": %lld, \\\"peak\\\": %lld, \\\"current\\\": %lld }%s\\n\", prefix, stat->total, stat->peak, stat->current, (add_comma ? \",\" : \"\"));\n  buf[127] = 0;\n  mi_json_buf_print(hbuf, buf);\n}\n\nstatic void mi_json_buf_print_count_value(mi_json_buf_t* hbuf, const char* name, const mi_stat_count_t* stat) {\n  char buf[128];\n  _mi_snprintf(buf, 128, \"  \\\"%s\\\": \", name);\n  buf[127] = 0;\n  mi_json_buf_print(hbuf, buf);\n  mi_json_buf_print_count(hbuf, \"\", stat, true);\n}\n\nstatic void mi_json_buf_print_value(mi_json_buf_t* hbuf, const char* name, int64_t val) {\n  char buf[128];\n  _mi_snprintf(buf, 128, \"  \\\"%s\\\": %lld,\\n\", name, val);\n  buf[127] = 0;\n  mi_json_buf_print(hbuf, buf);\n}\n\nstatic void mi_json_buf_print_size(mi_json_buf_t* hbuf, const char* name, size_t val, bool add_comma) {\n  char buf[128];\n  _mi_snprintf(buf, 128, \"    \\\"%s\\\": %zu%s\\n\", name, val, (add_comma ? \",\" : \"\"));\n  buf[127] = 0;\n  mi_json_buf_print(hbuf, buf);\n}\n\nstatic void mi_json_buf_print_counter_value(mi_json_buf_t* hbuf, const char* name, const mi_stat_counter_t* stat) {\n  mi_json_buf_print_value(hbuf, name, stat->total);\n}\n\n#define MI_STAT_COUNT(stat)    mi_json_buf_print_count_value(&hbuf, #stat, &stats->stat);\n#define MI_STAT_COUNTER(stat)  mi_json_buf_print_counter_value(&hbuf, #stat, &stats->stat);\n\nstatic char* mi_stats_get_json_from(const mi_stats_t* stats, size_t output_size, char* output_buf) mi_attr_noexcept {\n  if (stats==NULL || stats->size!=sizeof(mi_stats_t) || stats->version!=MI_STAT_VERSION) return NULL;\n  mi_json_buf_t hbuf = { NULL, 0, 0, true };\n  if (output_size > 0 && output_buf != NULL) {\n    _mi_memzero(output_buf, output_size);\n    hbuf.buf = output_buf;\n    hbuf.size = output_size;\n    hbuf.can_realloc = false;\n  }\n  else {\n    if (!mi_json_buf_expand(&hbuf)) return NULL;\n  }\n  mi_json_buf_print(&hbuf, \"{\\n\");\n  mi_json_buf_print_value(&hbuf, \"stat_version\", MI_STAT_VERSION);\n  mi_json_buf_print_value(&hbuf, \"mimalloc_version\", MI_MALLOC_VERSION);\n\n  // process info\n  mi_json_buf_print(&hbuf, \"  \\\"process\\\": {\\n\");\n  size_t elapsed;\n  size_t user_time;\n  size_t sys_time;\n  size_t current_rss;\n  size_t peak_rss;\n  size_t current_commit;\n  size_t peak_commit;\n  size_t page_faults;\n  mi_process_info(&elapsed, &user_time, &sys_time, &current_rss, &peak_rss, &current_commit, &peak_commit, &page_faults);\n  mi_json_buf_print_size(&hbuf, \"elapsed_msecs\", elapsed, true);\n  mi_json_buf_print_size(&hbuf, \"user_msecs\", user_time, true);\n  mi_json_buf_print_size(&hbuf, \"system_msecs\", sys_time, true);\n  mi_json_buf_print_size(&hbuf, \"page_faults\", page_faults, true);\n  mi_json_buf_print_size(&hbuf, \"rss_current\", current_rss, true);\n  mi_json_buf_print_size(&hbuf, \"rss_peak\", peak_rss, true);\n  mi_json_buf_print_size(&hbuf, \"commit_current\", current_commit, true);\n  mi_json_buf_print_size(&hbuf, \"commit_peak\", peak_commit, false);\n  mi_json_buf_print(&hbuf, \"  },\\n\");\n\n  // statistics\n  MI_STAT_FIELDS()\n\n  // size bins\n  mi_json_buf_print(&hbuf, \"  \\\"malloc_bins\\\": [\\n\");\n  for (size_t i = 0; i <= MI_BIN_HUGE; i++) {\n    mi_json_buf_print_count_bin(&hbuf, \"    \", &stats->malloc_bins[i], i, i!=MI_BIN_HUGE);\n  }\n  mi_json_buf_print(&hbuf, \"  ],\\n\");\n  mi_json_buf_print(&hbuf, \"  \\\"page_bins\\\": [\\n\");\n  for (size_t i = 0; i <= MI_BIN_HUGE; i++) {\n    mi_json_buf_print_count_bin(&hbuf, \"    \", &stats->page_bins[i], i, i!=MI_BIN_HUGE);\n  }\n  mi_json_buf_print(&hbuf, \"  ],\\n\");\n  mi_json_buf_print(&hbuf, \"  \\\"chunk_bins\\\": [\\n\");\n  for (size_t i = 0; i < MI_CBIN_COUNT; i++) {\n    mi_json_buf_print_count_cbin(&hbuf, \"    \", &stats->chunk_bins[i], (mi_chunkbin_t)i, i!=MI_CBIN_COUNT-1);\n  }\n  mi_json_buf_print(&hbuf, \"  ]\\n\");\n  mi_json_buf_print(&hbuf, \"}\\n\");\n  if (hbuf.used >= hbuf.size) {\n    // failed\n    if (hbuf.can_realloc) { mi_free(hbuf.buf); }\n    return NULL;\n  }\n  else {\n    return hbuf.buf;\n  }\n}\n\nchar* mi_subproc_stats_get_json(mi_subproc_id_t subproc_id, size_t buf_size, char* buf) mi_attr_noexcept {\n  mi_subproc_t* subproc = _mi_subproc_from_id(subproc_id);\n  if (subproc==NULL) return NULL;\n  mi_stats_t_decl(stats);\n  if (!mi_subproc_stats_get(subproc_id,&stats)) return NULL;\n  return mi_stats_get_json_from(&stats, buf_size, buf);\n}\n\nchar* mi_heap_stats_get_json(mi_heap_t* heap, size_t buf_size, char* buf) mi_attr_noexcept {\n  return mi_stats_get_json_from(mi_heap_get_stats(heap), buf_size, buf);\n}\n\nchar* mi_stats_get_json(size_t buf_size, char* buf) mi_attr_noexcept {\n  return mi_subproc_stats_get_json(mi_subproc_current(), buf_size, buf);\n}\n\nchar* mi_stats_as_json(mi_stats_t* stats, size_t buf_size, char* buf) mi_attr_noexcept {\n  return mi_stats_get_json_from(stats, buf_size, buf);\n}\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/theap.c",
      "sha256": "7f76bcace4b0578f2063477752138adabd99f7b10a276998e296a312c47a7cfe",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/*----------------------------------------------------------------------------\nCopyright (c) 2018-2025, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"  // _mi_theap_default\n\n#if defined(_MSC_VER) && (_MSC_VER < 1920)\n#pragma warning(disable:4204)  // non-constant aggregate initializer\n#endif\n\n/* -----------------------------------------------------------\n  Helpers\n----------------------------------------------------------- */\n\n// return `true` if ok, `false` to break\ntypedef bool (theap_page_visitor_fun)(mi_theap_t* theap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2);\n\n// Visit all pages in a theap; returns `false` if break was called.\nstatic bool mi_theap_visit_pages(mi_theap_t* theap, theap_page_visitor_fun* fn, bool include_full, void* arg1, void* arg2)\n{\n  if (theap==NULL || theap->page_count==0) return 0;\n\n  // visit all pages\n  #if MI_DEBUG>1\n  size_t total = theap->page_count;\n  size_t count = 0;\n  #endif\n\n  const size_t max_bin = (include_full ? MI_BIN_FULL : MI_BIN_FULL - 1);\n  for (size_t i = 0; i <= max_bin; i++) {\n    mi_page_queue_t* pq = &theap->pages[i];\n    mi_page_t* page = pq->first;\n    while(page != NULL) {\n      mi_page_t* next = page->next; // save next in case the page gets removed from the queue\n      mi_assert_internal(mi_page_theap(page) == theap);\n      #if MI_DEBUG>1\n      count++;\n      #endif\n      if (!fn(theap, pq, page, arg1, arg2)) return false;\n      page = next; // and continue\n    }\n  }\n  mi_assert_internal(!include_full || count == total);\n  return true;\n}\n\n\n#if MI_DEBUG>=2\nstatic bool mi_theap_page_is_valid(mi_theap_t* theap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) {\n  MI_UNUSED(arg1);\n  MI_UNUSED(arg2);\n  MI_UNUSED(pq);\n  mi_assert_internal(mi_page_theap(page) == theap);\n  mi_assert_expensive(_mi_page_is_valid(page));\n  return true;\n}\n#endif\n#if MI_DEBUG>=3\nstatic bool mi_theap_is_valid(mi_theap_t* theap) {\n  mi_assert_internal(theap!=NULL);\n  mi_theap_visit_pages(theap, &mi_theap_page_is_valid, true, NULL, NULL);\n  for (size_t bin = 0; bin < MI_BIN_COUNT; bin++) {\n    mi_assert_internal(_mi_page_queue_is_valid(theap, &theap->pages[bin]));\n  }\n  return true;\n}\n#endif\n\n\n\n\n/* -----------------------------------------------------------\n  \"Collect\" pages by migrating `local_free` and `thread_free`\n  lists and freeing empty pages. This is done when a thread\n  stops (and in that case abandons pages if there are still\n  blocks alive)\n----------------------------------------------------------- */\n\ntypedef enum mi_collect_e {\n  MI_NORMAL,\n  MI_FORCE,\n  MI_ABANDON\n} mi_collect_t;\n\n\nstatic bool mi_theap_page_collect(mi_theap_t* theap, mi_page_queue_t* pq, mi_page_t* page, void* arg_collect, void* arg2 ) {\n  MI_UNUSED(arg2);\n  MI_UNUSED(theap);\n  mi_assert_internal(mi_theap_page_is_valid(theap, pq, page, NULL, NULL));\n  mi_collect_t collect = *((mi_collect_t*)arg_collect);\n  _mi_page_free_collect(page, collect >= MI_FORCE);\n  if (mi_page_all_free(page)) {\n    // no more used blocks, possibly free the page.\n    if (collect >= MI_FORCE || page->retire_expire == 0) {  // either forced/abandon, or not already retired\n      // note: this will potentially free retired pages as well.\n      _mi_page_free(page, pq);\n    }\n  }\n  else if (collect == MI_ABANDON) {\n    // still used blocks but the thread is done; abandon the page\n    _mi_page_abandon(page, pq);\n  }\n  return true; // don't break\n}\n\nstatic void mi_theap_merge_stats(mi_theap_t* theap) {\n  mi_assert_internal(mi_theap_is_initialized(theap));\n  _mi_stats_merge_into(&_mi_theap_heap(theap)->stats, &theap->stats);\n}\n\nstatic void mi_theap_collect_ex(mi_theap_t* theap, mi_collect_t collect)\n{\n  if (theap==NULL || !mi_theap_is_initialized(theap)) return;\n  mi_assert_expensive(mi_theap_is_valid(theap));\n\n  const bool force = (collect >= MI_FORCE);\n  _mi_deferred_free(theap, force);\n\n  // python/cpython#112532: we may be called from a thread that is not the owner of the theap\n  // const bool is_main_thread = (_mi_is_main_thread() && theap->thread_id == _mi_thread_id());\n\n  // collect retired pages\n  _mi_theap_collect_retired(theap, force);\n\n  // collect all pages owned by this thread\n  mi_theap_visit_pages(theap, &mi_theap_page_collect, (collect!=MI_NORMAL), &collect, NULL);  // dont normally visit full pages, see issue #1220\n\n  // collect arenas (this is program wide so don't force purges on abandonment of threads)\n  //mi_atomic_storei64_release(&theap->tld->subproc->purge_expire, 1);\n  _mi_arenas_collect(collect == MI_FORCE /* force purge? */, collect >= MI_FORCE /* visit all? */, theap->tld);\n\n  // merge statistics\n  mi_theap_merge_stats(theap);\n}\n\nvoid _mi_theap_collect_abandon(mi_theap_t* theap) {\n  mi_theap_collect_ex(theap, MI_ABANDON);\n}\n\nvoid mi_theap_collect(mi_theap_t* theap, bool force) mi_attr_noexcept {\n  mi_theap_collect_ex(theap, (force ? MI_FORCE : MI_NORMAL));\n}\n\nvoid mi_collect(bool force) mi_attr_noexcept {\n  // cannot really collect process wide, just a theap..\n  mi_theap_collect(_mi_theap_default(), force);\n}\n\nvoid mi_heap_collect(mi_heap_t* heap, bool force) {\n  // cannot really collect a heap, just a theap..\n  mi_theap_collect(mi_heap_theap(heap), force);\n}\n\n/* -----------------------------------------------------------\n  Heap new\n----------------------------------------------------------- */\n\nmi_theap_t* mi_theap_get_default(void) {\n  mi_theap_t* theap = _mi_theap_default();\n  if mi_unlikely(!mi_theap_is_initialized(theap)) {\n    mi_thread_init();\n    theap = _mi_theap_default();\n    mi_assert_internal(mi_theap_is_initialized(theap));\n  }\n  return theap;\n}\n\n// todo: make order of parameters consistent (but would that break compat with CPython?)\nvoid _mi_theap_init(mi_theap_t* theap, mi_heap_t* heap, mi_tld_t* tld)\n{\n  mi_assert_internal(theap!=NULL);\n  mi_assert_internal(heap!=NULL);\n  mi_memid_t memid = theap->memid;\n  _mi_memcpy_aligned(theap, &_mi_theap_empty, sizeof(mi_theap_t));\n  theap->memid = memid;\n  theap->refcount = 1;\n  theap->tld   = tld;  // avoid reading the thread-local tld during initialization\n  mi_atomic_store_ptr_relaxed(mi_heap_t,&theap->heap,heap);\n  mi_assert_internal(theap->stats.size == sizeof(mi_stats_t));\n  \n  _mi_theap_options_init(theap);\n  if (theap->tld->is_in_threadpool) {\n    // if we run as part of a thread pool it is better to not arbitrarily reclaim abandoned pages into our theap.\n    // this is checked in `free.c:mi_free_try_collect_mt`\n    // .. but abandoning is good in this case: halve the full page retain (possibly to 0)\n    // (so blocked threads do not hold on to too much memory)\n    if (theap->page_full_retain > 0) {\n      theap->page_full_retain = theap->page_full_retain / 4;\n    }\n  }\n\n  // push on the thread local theaps list\n  mi_theap_t* head = NULL;\n  mi_lock(&theap->tld->theaps_lock) {\n    head = theap->tld->theaps;\n    theap->tprev = NULL;\n    theap->tnext = head;\n    if (head!=NULL) { head->tprev = theap; }\n    theap->tld->theaps = theap;\n  }\n\n  // initialize random\n  if (head == NULL) {  // first theap in this thread?\n    #if defined(_WIN32) && !defined(MI_SHARED_LIB)\n      _mi_random_init_weak(&theap->random);    // prevent allocation failure during bcrypt dll initialization with static linking (issue #1185)\n    #else\n      _mi_random_init(&theap->random);\n    #endif\n  }\n  else {\n    _mi_random_split(&head->random, &theap->random);\n  }\n  theap->cookie  = _mi_theap_random_next(theap) | 1;\n  _mi_theap_guarded_init(theap);\n  mi_subproc_stat_increase(_mi_subproc(),theaps,1);\n\n  // push on the heap's theap list\n  mi_lock(&heap->theaps_lock) {\n    head = heap->theaps;\n    theap->hprev = NULL;\n    theap->hnext = head;\n    if (head!=NULL) { head->hprev = theap; }\n    heap->theaps = theap;\n  }\n}\n\nmi_theap_t* _mi_theap_create(mi_heap_t* heap, mi_tld_t* tld) {\n  mi_assert_internal(tld!=NULL);\n  mi_assert_internal(heap!=NULL);\n  // allocate and initialize a theap\n  mi_memid_t memid;\n  mi_theap_t* theap;\n  //if (!_mi_is_heap_main(heap)) {\n  //  theap = (mi_theap_t*)mi_heap_zalloc(mi_heap_main(),sizeof(mi_theap_t));\n  //  memid = _mi_memid_create(MI_MEM_HEAP_MAIN);\n  //  memid.initially_zero = memid.initially_committed = true;\n  //}\n  //else\n  if (heap->exclusive_arena == NULL) {\n    theap = (mi_theap_t*)_mi_meta_zalloc(sizeof(mi_theap_t), &memid);\n  }\n  else {\n    // theaps associated with a specific arena are allocated in that arena\n    // note: takes up at least one slice which is quite wasteful...\n    const size_t size = _mi_align_up(sizeof(mi_theap_t),MI_ARENA_MIN_OBJ_SIZE);\n    theap = (mi_theap_t*)_mi_arenas_alloc(heap, size, true, true, heap->exclusive_arena, tld->thread_seq, tld->numa_node, &memid);\n    mi_assert_internal(memid.mem.os.size >= size);\n  }\n  if (theap==NULL) {\n    _mi_error_message(ENOMEM, \"unable to allocate theap meta-data\\n\");\n    return NULL;\n  }\n  theap->memid = memid;\n  _mi_theap_init(theap, heap, tld);\n  return theap;\n}\n\nuintptr_t _mi_theap_random_next(mi_theap_t* theap) {\n  return _mi_random_next(&theap->random);\n}\n\nstatic void mi_theap_free_mem(mi_theap_t* theap) {\n  if (theap!=NULL) {\n    mi_subproc_stat_decrease(_mi_subproc(),theaps,1);\n    // free the used memory\n    if (theap->memid.memkind == MI_MEM_HEAP_MAIN) {  // note: for now unused as it would access theap_default stats in mi_free of the current theap\n      mi_assert_internal(_mi_is_heap_main(mi_heap_of(theap)));\n      mi_free(theap);\n    }\n    else if (theap->memid.memkind == MI_MEM_META) {\n      _mi_meta_free(theap, sizeof(*theap), theap->memid);\n    }\n    else {\n      _mi_arenas_free(theap, _mi_align_up(sizeof(*theap),MI_ARENA_MIN_OBJ_SIZE), theap->memid ); // issue #1168, avoid assertion failure\n    }\n  }\n}\n\nvoid _mi_theap_incref(mi_theap_t* theap) {\n  if (theap!=NULL && theap->memid.memkind > MI_MEM_STATIC) {\n    mi_atomic_increment_acq_rel(&theap->refcount);\n  }\n}\n\nvoid _mi_theap_decref(mi_theap_t* theap) {\n  if (theap!=NULL && theap->memid.memkind > MI_MEM_STATIC) {\n    if (mi_atomic_decrement_acq_rel(&theap->refcount) == 1) {\n      mi_theap_free_mem(theap);\n    }\n  }\n}\n\n\n// called from `mi_theap_delete` to free the internal theap resources.\nbool _mi_theap_free(mi_theap_t* theap, bool acquire_heap_theaps_lock, bool acquire_tld_theaps_lock) {\n  mi_assert(theap != NULL);\n  if (theap==NULL) return true;\n\n  mi_heap_t* const heap = mi_atomic_exchange_ptr_acq_rel(mi_heap_t, &theap->heap, NULL);\n  if (heap==NULL) {\n    // concurrent interaction, retry in an outer loop (as the other thread may be blocked on our lock)\n    return false;\n  }\n  else {\n    // merge stats to the owning heap\n    _mi_stats_merge_into(&heap->stats, &theap->stats);\n\n    // remove ourselves from the heap theaps list\n    mi_lock_maybe(&heap->theaps_lock, acquire_heap_theaps_lock) {\n      if (theap->hnext != NULL) { theap->hnext->hprev = theap->hprev; }\n      if (theap->hprev != NULL) { theap->hprev->hnext = theap->hnext; }\n                          else { mi_assert_internal(heap->theaps == theap); heap->theaps = theap->hnext; }\n      theap->hnext = theap->hprev = NULL;\n    }\n\n    // remove ourselves from the thread local theaps list\n    mi_lock_maybe(&theap->tld->theaps_lock, acquire_tld_theaps_lock) {\n      if (theap->tnext != NULL) { theap->tnext->tprev = theap->tprev;  }\n      if (theap->tprev != NULL) { theap->tprev->tnext = theap->tnext;  }\n                          else { mi_assert_internal(theap->tld->theaps == theap); theap->tld->theaps = theap->tnext; }\n      theap->tnext = theap->tprev = NULL;                        \n    }\n    theap->tld = NULL;\n    _mi_theap_decref(theap);\n    return true;\n  }\n}\n\n\n/* -----------------------------------------------------------\n  Heap destroy\n----------------------------------------------------------- */\n/*\n\n// zero out the page queues\nstatic void mi_theap_reset_pages(mi_theap_t* theap) {\n  mi_assert_internal(theap != NULL);\n  mi_assert_internal(mi_theap_is_initialized(theap));\n  // TODO: copy full empty theap instead?\n  _mi_memset(&theap->pages_free_direct, 0, sizeof(theap->pages_free_direct));\n  _mi_memcpy_aligned(&theap->pages, &_mi_theap_empty.pages, sizeof(theap->pages));\n  // theap->thread_delayed_free = NULL;\n  theap->page_count = 0;\n}\n\nstatic bool _mi_theap_page_destroy(mi_theap_t* theap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) {\n  MI_UNUSED(arg1);\n  MI_UNUSED(arg2);\n  MI_UNUSED(pq);\n\n  // ensure no more thread_delayed_free will be added\n  //_mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false);\n\n  // stats\n  const size_t bsize = mi_page_block_size(page);\n  if (bsize > MI_LARGE_MAX_OBJ_SIZE) {\n    mi_theap_stat_decrease(theap, malloc_huge, bsize);\n  }\n  #if (MI_STAT>0)\n  _mi_page_free_collect(page, false);  // update used count\n  const size_t inuse = page->used;\n  if (bsize <= MI_LARGE_MAX_OBJ_SIZE) {\n    mi_theap_stat_decrease(theap, malloc_normal, bsize * inuse);\n    #if (MI_STAT>1)\n    mi_theap_stat_decrease(theap, malloc_bins[_mi_bin(bsize)], inuse);\n    #endif\n  }\n  // mi_theap_stat_decrease(theap, malloc_requested, bsize * inuse);  // todo: off for aligned blocks...\n  #endif\n\n  /// pretend it is all free now\n  mi_assert_internal(mi_page_thread_free(page) == NULL);\n  page->used = 0;\n\n  // and free the page\n  // mi_page_free(page,false);\n  page->next = NULL;\n  page->prev = NULL;\n  mi_page_set_theap(page, NULL);\n  _mi_arenas_page_free(page, theap);\n\n  return true; // keep going\n}\n\nvoid _mi_theap_destroy_pages(mi_theap_t* theap) {\n  mi_theap_visit_pages(theap, &_mi_theap_page_destroy, NULL, NULL);\n  mi_theap_reset_pages(theap);\n}\n\n#if MI_TRACK_HEAP_DESTROY\nstatic bool mi_cdecl mi_theap_track_block_free(const mi_theap_t* theap, const mi_theap_area_t* area, void* block, size_t block_size, void* arg) {\n  MI_UNUSED(theap); MI_UNUSED(area);  MI_UNUSED(arg); MI_UNUSED(block_size);\n  mi_track_free_size(block,mi_usable_size(block));\n  return true;\n}\n#endif\n\nvoid mi_theap_destroy(mi_theap_t* theap) {\n  mi_assert(theap != NULL);\n  mi_assert(mi_theap_is_initialized(theap));\n  mi_assert(!theap->allow_page_reclaim);\n  mi_assert(!theap->allow_page_abandon);\n  mi_assert_expensive(mi_theap_is_valid(theap));\n  if (theap==NULL || !mi_theap_is_initialized(theap)) return;\n  #if MI_GUARDED\n  // _mi_warning_message(\"'mi_theap_destroy' called but MI_GUARDED is enabled -- using `mi_theap_delete` instead (theap at %p)\\n\", theap);\n  mi_theap_delete(theap);\n  return;\n  #else\n  if (theap->allow_page_reclaim) {\n    _mi_warning_message(\"'mi_theap_destroy' called but ignored as the theap was not created with 'allow_destroy' (theap at %p)\\n\", theap);\n    // don't free in case it may contain reclaimed pages,\n    mi_theap_delete(theap);\n  }\n  else {\n    // track all blocks as freed\n    #if MI_TRACK_HEAP_DESTROY\n    mi_theap_visit_blocks(theap, true, mi_theap_track_block_free, NULL);\n    #endif\n    // free all pages\n    _mi_theap_destroy_pages(theap);\n    mi_theap_free(theap,true);\n  }\n  #endif\n}\n\n// forcefully destroy all theaps in the current thread\nvoid _mi_theap_unsafe_destroy_all(mi_theap_t* theap) {\n  mi_assert_internal(theap != NULL);\n  if (theap == NULL) return;\n  mi_theap_t* curr = theap->tld->theaps;\n  while (curr != NULL) {\n    mi_theap_t* next = curr->next;\n    if (!curr->allow_page_reclaim) {\n      mi_theap_destroy(curr);\n    }\n    else {\n      _mi_theap_destroy_pages(curr);\n    }\n    curr = next;\n  }\n}\n*/\n\n/* -----------------------------------------------------------\n  Safe Heap delete\n----------------------------------------------------------- */\n\n// Safe delete a theap without freeing any still allocated blocks in that theap.\nvoid _mi_theap_delete(mi_theap_t* theap, bool acquire_tld_theaps_lock)\n{\n  mi_assert(theap != NULL);\n  mi_assert(mi_theap_is_initialized(theap));\n  mi_assert_expensive(mi_theap_is_valid(theap));\n  if (theap==NULL || !mi_theap_is_initialized(theap)) return;\n\n  // abandon all pages\n  _mi_theap_collect_abandon(theap);\n\n  mi_assert_internal(theap->page_count==0);\n  _mi_theap_free(theap, true /* acquire heap->theaps_lock */, acquire_tld_theaps_lock);\n}\n\n\n\n/* -----------------------------------------------------------\n  Load/unload theaps\n----------------------------------------------------------- */\n/*\nvoid mi_theap_unload(mi_theap_t* theap) {\n  mi_assert(mi_theap_is_initialized(theap));\n  mi_assert_expensive(mi_theap_is_valid(theap));\n  if (theap==NULL || !mi_theap_is_initialized(theap)) return;\n  if (_mi_theap_heap(theap)->exclusive_arena == NULL) {\n    _mi_warning_message(\"cannot unload theaps that are not associated with an exclusive arena\\n\");\n    return;\n  }\n\n  // abandon all pages so all thread'id in the pages are cleared\n  _mi_theap_collect_abandon(theap);\n  mi_assert_internal(theap->page_count==0);\n\n  // remove from theap list\n  mi_theap_free(theap, false); // but don't actually free the memory\n\n  // disassociate from the current thread-local and static state\n  theap->tld = NULL;\n  return;\n}\n\nbool mi_theap_reload(mi_theap_t* theap, mi_arena_id_t arena_id) {\n  mi_assert(mi_theap_is_initialized(theap));\n  if (theap==NULL || !mi_theap_is_initialized(theap)) return false;\n  if (_mi_theap_heap(theap)->exclusive_arena == NULL) {\n    _mi_warning_message(\"cannot reload theaps that were not associated with an exclusive arena\\n\");\n    return false;\n  }\n  if (theap->tld != NULL) {\n    _mi_warning_message(\"cannot reload theaps that were not unloaded first\\n\");\n    return false;\n  }\n  mi_arena_t* arena = _mi_arena_from_id(arena_id);\n  if (_mi_theap_heap(theap)->exclusive_arena != arena) {\n    _mi_warning_message(\"trying to reload a theap at a different arena address: %p vs %p\\n\", _mi_theap_heap(theap)->exclusive_arena, arena);\n    return false;\n  }\n\n  mi_assert_internal(theap->page_count==0);\n\n  // re-associate with the current thread-local and static state\n  theap->tld = mi_theap_get_default()->tld;\n\n  // reinit direct pages (as we may be in a different process)\n  mi_assert_internal(theap->page_count == 0);\n  for (size_t i = 0; i < MI_PAGES_DIRECT; i++) {\n    theap->pages_free_direct[i] = (mi_page_t*)&_mi_page_empty;\n  }\n\n  // push on the thread local theaps list\n  theap->tnext = theap->tld->theaps;\n  theap->tld->theaps = theap;\n  return true;\n}\n*/\n\n\n/* -----------------------------------------------------------\n  Visit all theap blocks and areas\n  Todo: enable visiting abandoned pages, and\n        enable visiting all blocks of all theaps across threads\n----------------------------------------------------------- */\n\nvoid _mi_heap_area_init(mi_heap_area_t* area, mi_page_t* page) {\n  const size_t bsize = mi_page_block_size(page);\n  const size_t ubsize = mi_page_usable_block_size(page);\n  area->reserved = page->reserved * bsize;\n  area->committed = page->capacity * bsize;\n  area->blocks = mi_page_start(page);\n  area->used = page->used;   // number of blocks in use (#553)\n  area->block_size = ubsize;\n  area->full_block_size = bsize;\n  area->reserved1 = page;\n}\n\nstatic void mi_get_fast_divisor(size_t divisor, uint64_t* magic, size_t* shift) {\n  mi_assert_internal(divisor > 0 && divisor <= UINT32_MAX);\n  *shift = MI_SIZE_BITS - mi_clz(divisor - 1);\n  *magic = ((((uint64_t)1 << 32) * (((uint64_t)1 << *shift) - divisor)) / divisor + 1);\n}\n\nstatic size_t mi_fast_divide(size_t n, uint64_t magic, size_t shift) {\n  mi_assert_internal(n <= UINT32_MAX);\n  const uint64_t hi = ((uint64_t)n * magic) >> 32;\n  return (size_t)((hi + n) >> shift);\n}\n\nbool _mi_theap_area_visit_blocks(const mi_heap_area_t* area, mi_page_t* page, mi_block_visit_fun* visitor, void* arg) {\n  mi_assert(area != NULL);\n  if (area==NULL) return true;\n  mi_assert(page != NULL);\n  if (page == NULL) return true;\n\n  _mi_page_free_collect(page,true);              // collect both thread_delayed and local_free\n  mi_assert_internal(page->local_free == NULL);\n  if (page->used == 0) return true;\n\n  size_t psize;\n  uint8_t* const pstart = mi_page_area(page, &psize);\n  mi_heap_t* const heap = mi_page_heap(page);\n  const size_t bsize    = mi_page_block_size(page);\n  const size_t ubsize   = mi_page_usable_block_size(page); // without padding\n\n  // optimize page with one block\n  if (page->capacity == 1) {\n    mi_assert_internal(page->used == 1 && page->free == NULL);\n    return visitor(heap, area, pstart, ubsize, arg);\n  }\n  mi_assert(bsize <= UINT32_MAX);\n\n  // optimize full pages\n  if (page->used == page->capacity) {\n    uint8_t* block = pstart;\n    for (size_t i = 0; i < page->capacity; i++) {\n      if (!visitor(heap, area, block, ubsize, arg)) return false;\n      block += bsize;\n    }\n    return true;\n  }\n\n  // create a bitmap of free blocks.\n  #define MI_MAX_BLOCKS   (MI_SMALL_PAGE_SIZE / sizeof(void*))\n  uintptr_t free_map[MI_MAX_BLOCKS / MI_INTPTR_BITS];\n  const uintptr_t bmapsize = _mi_divide_up(page->capacity, MI_INTPTR_BITS);\n  memset(free_map, 0, bmapsize * sizeof(intptr_t));\n  if (page->capacity % MI_INTPTR_BITS != 0) {\n    // mark left-over bits at the end as free\n    size_t shift   = (page->capacity % MI_INTPTR_BITS);\n    uintptr_t mask = (UINTPTR_MAX << shift);\n    free_map[bmapsize - 1] = mask;\n  }\n\n  // fast repeated division by the block size\n  uint64_t magic;\n  size_t   shift;\n  mi_get_fast_divisor(bsize, &magic, &shift);\n\n  #if MI_DEBUG>1\n  size_t free_count = 0;\n  #endif\n  for (mi_block_t* block = page->free; block != NULL; block = mi_block_next(page, block)) {\n    #if MI_DEBUG>1\n    free_count++;\n    #endif\n    mi_assert_internal((uint8_t*)block >= pstart && (uint8_t*)block < (pstart + psize));\n    size_t offset = (uint8_t*)block - pstart;\n    mi_assert_internal(offset % bsize == 0);\n    mi_assert_internal(offset <= UINT32_MAX);\n    size_t blockidx = mi_fast_divide(offset, magic, shift);\n    mi_assert_internal(blockidx == offset / bsize);\n    mi_assert_internal(blockidx < MI_MAX_BLOCKS);\n    size_t bitidx = (blockidx / MI_INTPTR_BITS);\n    size_t bit = blockidx - (bitidx * MI_INTPTR_BITS);\n    free_map[bitidx] |= ((uintptr_t)1 << bit);\n  }\n  mi_assert_internal(page->capacity == (free_count + page->used));\n\n  // walk through all blocks skipping the free ones\n  #if MI_DEBUG>1\n  size_t used_count = 0;\n  #endif\n  uint8_t* block = pstart;\n  for (size_t i = 0; i < bmapsize; i++) {\n    if (free_map[i] == 0) {\n      // every block is in use\n      for (size_t j = 0; j < MI_INTPTR_BITS; j++) {\n        #if MI_DEBUG>1\n        used_count++;\n        #endif\n        if (!visitor(heap, area, block, ubsize, arg)) return false;\n        block += bsize;\n      }\n    }\n    else {\n      // visit the used blocks in the mask\n      uintptr_t m = ~free_map[i];\n      while (m != 0) {\n        #if MI_DEBUG>1\n        used_count++;\n        #endif\n        size_t bitidx = mi_ctz(m);\n        if (!visitor(heap, area, block + (bitidx * bsize), ubsize, arg)) return false;\n        m &= m - 1;  // clear least significant bit\n      }\n      block += bsize * MI_INTPTR_BITS;\n    }\n  }\n  mi_assert_internal(page->used == used_count);\n  return true;\n}\n\n\n\n// Separate struct to keep `mi_page_t` out of the public interface\ntypedef struct mi_theap_area_ex_s {\n  mi_heap_area_t area;\n  mi_page_t* page;\n} mi_theap_area_ex_t;\n\ntypedef bool (mi_theap_area_visit_fun)(const mi_theap_t* theap, const mi_theap_area_ex_t* area, void* arg);\n\nstatic bool mi_theap_visit_areas_page(mi_theap_t* theap, mi_page_queue_t* pq, mi_page_t* page, void* vfun, void* arg) {\n  MI_UNUSED(theap);\n  MI_UNUSED(pq);\n  mi_theap_area_visit_fun* fun = (mi_theap_area_visit_fun*)vfun;\n  mi_theap_area_ex_t xarea;\n  xarea.page = page;\n  _mi_heap_area_init(&xarea.area, page);\n  return fun(theap, &xarea, arg);\n}\n\n// Visit all theap pages as areas\nstatic bool mi_theap_visit_areas(const mi_theap_t* theap, mi_theap_area_visit_fun* visitor, void* arg) {\n  if (visitor == NULL) return false;\n  return mi_theap_visit_pages((mi_theap_t*)theap, &mi_theap_visit_areas_page, true, (void*)(visitor), arg); // note: function pointer to void* :-{\n}\n\n// Just to pass arguments\ntypedef struct mi_visit_blocks_args_s {\n  bool  visit_blocks;\n  mi_block_visit_fun* visitor;\n  void* arg;\n} mi_visit_blocks_args_t;\n\nstatic bool mi_theap_area_visitor(const mi_theap_t* theap, const mi_theap_area_ex_t* xarea, void* arg) {\n  mi_visit_blocks_args_t* args = (mi_visit_blocks_args_t*)arg;\n  if (!args->visitor(_mi_theap_heap(theap), &xarea->area, NULL, xarea->area.block_size, args->arg)) return false;\n  if (args->visit_blocks) {\n    return _mi_theap_area_visit_blocks(&xarea->area, xarea->page, args->visitor, args->arg);\n  }\n  else {\n    return true;\n  }\n}\n\n// Visit all blocks in a theap\nbool mi_theap_visit_blocks(const mi_theap_t* theap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) {\n  mi_visit_blocks_args_t args = { visit_blocks, visitor, arg };\n  return mi_theap_visit_areas(theap, &mi_theap_area_visitor, &args);\n}\n\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "c_src/mimalloc/v3/src/threadlocal.c",
      "sha256": "49be69a4b674e09690a63870830f3ffb05698ed4210949ef5add11957a08325b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "/* ----------------------------------------------------------------------------\nCopyright (c) 2019-2026, Microsoft Research, Daan Leijen\nThis is free software; you can redistribute it and/or modify it under the\nterms of the MIT license. A copy of the license can be found in the file\n\"LICENSE\" at the root of this distribution.\n-----------------------------------------------------------------------------*/\n\n/* ----------------------------------------------------------------------------\nImplement dynamic thread local variables (for heap's).\nUnlike most OS native implementations there is no limit on the number\nthat can be allocated.\n-----------------------------------------------------------------------------*/\n\n#include \"mimalloc.h\"\n#include \"mimalloc/internal.h\"\n#include \"mimalloc/prim.h\"\n\n/* -----------------------------------------------------------\n  Each thread can have (a dynamically expanding) array of\n  thread-local values. Each slot has a value and a version.\n  The version is used to safely reuse slots.\n----------------------------------------------------------- */\ntypedef struct mi_tls_slot_s {\n  size_t  version;\n  void*   value;\n} mi_tls_slot_t;\n\ntypedef struct mi_thread_locals_s {\n  size_t        count;\n  mi_tls_slot_t slots[1];\n} mi_thread_locals_t;\n\nstatic mi_thread_locals_t mi_thread_locals_empty = { 0, {{0,NULL}} };\n\nmi_decl_thread mi_thread_locals_t* mi_thread_locals = &mi_thread_locals_empty;  // always point to a valid `mi_thread_locals_t`\n\n\n/* -----------------------------------------------------------\n  Each key consists of the slot index in the lower bits,\n  and its version it the top bits. When we get a value\n  the version must match or we return NULL. When we set\n  a value, we also set the version of the key.\n----------------------------------------------------------- */\n\n#if MI_SIZE_BITS < 64\n#define MI_TLS_IDX_BITS     (MI_SIZE_BITS/2)      // half for the index, half for the version\n#else\n#define MI_TLS_IDX_BITS     (MI_SIZE_BITS/4)      // 16 bits for the index, 48 bits for the version\n#endif\n#define MI_TLS_IDX_MASK     ((MI_ZU(1)<<MI_TLS_IDX_BITS)-1)\n#define MI_TLS_IDX_MAX      MI_TLS_IDX_MASK\n#define MI_TLS_VERSION_MAX  ((MI_ZU(1)<<(MI_SIZE_BITS - MI_TLS_IDX_BITS))-1)\n\nstatic size_t mi_key_index( size_t key ) {\n  return (key & MI_TLS_IDX_MASK);\n}\n\nstatic size_t mi_key_version( size_t key ) {\n  return (key >> MI_TLS_IDX_BITS);\n}\n\nstatic mi_thread_local_t mi_key_create( size_t index, size_t version ) {\n  mi_assert_internal(version != 0 && version <= MI_TLS_VERSION_MAX);\n  mi_assert_internal(index <= MI_TLS_IDX_MAX);\n  const mi_thread_local_t key = ((version << MI_TLS_IDX_BITS) | index);\n  mi_assert_internal(key != 0);\n  return key;\n}\n\n\n// dynamically reallocate the thread local slots when needed\nstatic mi_thread_locals_t* mi_thread_locals_expand(size_t least_idx) {\n  mi_thread_locals_t* tls_old = mi_thread_locals;\n  const size_t count_old = tls_old->count;\n  size_t count;\n  if (count_old==0) {\n    tls_old = NULL; // so we allocate fresh from mi_thread_locals_empty\n    count = 16;     // start with 16 slots\n  } \n  else if (count_old >= 1024) {\n    count = count_old + 1024;  // at some point increase linearly\n  }\n  else {\n    count = 2*count_old;       // and double initially\n  }\n  if (count <= least_idx) {   \n    count = least_idx + 1;\n  }\n  if (count > MI_TLS_IDX_MAX) { return NULL; }  // too large\n  mi_thread_locals_t* tls = (mi_thread_locals_t*)mi_rezalloc(tls_old, sizeof(mi_thread_locals_t) + count*sizeof(mi_tls_slot_t));\n  if mi_unlikely(tls==NULL) return NULL;\n  tls->count = count;\n  mi_thread_locals = tls;\n  return tls;\n}\n\nstatic mi_decl_noinline bool mi_thread_local_set_expand( mi_thread_local_t key, void* val ) {\n  if (val==NULL) return true;\n  const size_t idx = mi_key_index(key);  \n  mi_thread_locals_t* tls = mi_thread_locals_expand(idx);\n  if (tls==NULL) return false;\n  mi_assert_internal(tls == mi_thread_locals);\n  mi_assert_internal(idx < tls->count);\n  tls->slots[idx].value = val;\n  tls->slots[idx].version = mi_key_version(key);\n  return true;\n}\n\n// set a tls slot; returns `true` if successful.\n// Can return `false` if we could not reallocate the slots array.\nbool _mi_thread_local_set( mi_thread_local_t key, void* val ) {\n  mi_thread_locals_t* tls = mi_thread_locals;\n  mi_assert_internal(tls!=NULL);\n  mi_assert_internal(key!=0);\n  const size_t idx = mi_key_index(key);\n  if mi_likely(idx < tls->count) {\n    tls->slots[idx].value = val;\n    tls->slots[idx].version = mi_key_version(key);\n    return true;\n  }\n  else {\n    return mi_thread_local_set_expand( key, val );  // tailcall\n  }\n}\n\n// get a tls slot value\nvoid* _mi_thread_local_get( mi_thread_local_t key ) {\n  const mi_thread_locals_t* const tls = mi_thread_locals;\n  mi_assert_internal(tls!=NULL);\n  mi_assert_internal(key!=0);\n  const size_t idx = mi_key_index(key);\n  if mi_likely(idx < tls->count && mi_key_version(key) == tls->slots[idx].version) {\n    return tls->slots[idx].value;\n  }\n  else {\n    return NULL;  \n  }\n}\n\nvoid _mi_thread_locals_thread_done(void) {\n  mi_thread_locals_t* const tls = mi_thread_locals;\n  if (tls!=NULL && tls->count > 0) {\n    mi_free(tls);\n    mi_thread_locals = &mi_thread_locals_empty;\n  }\n}\n\n/* -----------------------------------------------------------\nCreate and free fresh TLS key's\n----------------------------------------------------------- */\n#include \"bitmap.h\"\n\nstatic mi_lock_t    mi_thread_locals_lock;    // we need a lock in order to re-allocate the slot bits\nstatic mi_bitmap_t* mi_thread_locals_free;    // reuse an arena bitmap to track which slots were assigned (1=free, 0=in-use)\nstatic size_t       mi_thread_locals_version; // version to be able to reuse slots safely\n\nvoid _mi_thread_locals_init(void) {\n  mi_lock_init(&mi_thread_locals_lock);\n}\n\nvoid _mi_thread_locals_done(void) {\n  mi_lock(&mi_thread_locals_lock) {\n    mi_bitmap_t* const slots = mi_thread_locals_free;\n    mi_free(slots);\n  }\n  mi_lock_done(&mi_thread_locals_lock);\n}\n\n// strange signature but allows us to reuse the arena code for claiming free pages\nstatic bool mi_thread_local_claim_fun(size_t _slice_index, mi_arena_t* _arena, bool* keep_set) {\n  MI_UNUSED(_slice_index); MI_UNUSED(_arena);\n  *keep_set = false;\n  return true;\n}\n\n// When we claim a free slot, we increase the global version counter \n// (so if we reuse a slot it will be returning NULL initially when a thread tries to get it)\nstatic mi_thread_local_t mi_thread_local_claim(void) {\n  size_t idx = 0;\n  if (mi_thread_locals_free != NULL && mi_bitmap_try_find_and_claim(mi_thread_locals_free,0,&idx,&mi_thread_local_claim_fun,NULL)) {\n    mi_thread_locals_version++;\n    if (mi_thread_locals_version >= MI_TLS_VERSION_MAX) { mi_thread_locals_version = 1; }  /* wrap around the version */\n    return mi_key_create( idx, mi_thread_locals_version);\n  }\n  else {\n    return 0;\n  }\n}\n\nstatic bool mi_thread_local_create_expand(void) {\n  mi_bitmap_t* const slots = mi_thread_locals_free;\n  // 1024 bits at a time\n  const size_t oldcount = (slots==NULL ? 0 : mi_bitmap_max_bits(slots));\n  const size_t newcount = 1024 + oldcount;\n  if (newcount > MI_TLS_IDX_MAX) { return false; }\n  const size_t newsize = mi_bitmap_size( newcount, NULL );\n  mi_bitmap_t* newslots = (mi_bitmap_t*)mi_zalloc_aligned(newsize, MI_BCHUNK_SIZE);\n  if (newslots==NULL) { return false; }\n  if (slots!=NULL) {\n    // copy over the previous bitmap\n    _mi_memcpy_aligned(newslots, slots, mi_bitmap_size(oldcount, NULL)); \n    mi_free(slots);\n  }\n  mi_bitmap_init(newslots, newcount, true /* pretend already zero'd so we do not zero out the copied old entries */);\n  mi_bitmap_unsafe_setN(newslots, oldcount, newcount - oldcount);  /* set the new expanded slots as available */\n  mi_thread_locals_free = newslots;\n  return true;\n}\n\n\n// create a fresh key\nmi_thread_local_t _mi_thread_local_create(void) {\n  mi_thread_local_t key = 0;\n  mi_lock(&mi_thread_locals_lock) {\n    key = mi_thread_local_claim();\n    if (key==0) {\n      if (mi_thread_local_create_expand()) {\n        key = mi_thread_local_claim();\n      }\n    }\n  }\n  return key;\n}\n\n// free a key\nvoid _mi_thread_local_free(mi_thread_local_t key) {\n  if (key==0) return;\n  const size_t idx = mi_key_index(key);\n  mi_lock(&mi_thread_locals_lock) {\n    mi_bitmap_t* const slots = mi_thread_locals_free;\n    if (slots!=NULL && idx < mi_bitmap_max_bits(slots)) {\n      mi_bitmap_set(slots,idx);\n    }\n  }\n}\n\n"
    },
    {
      "package": "libmimalloc-sys@0.1.49",
      "sourcePath": "src/lib.rs",
      "sha256": "3400737f6f802abffa8a7c30c26ee1240d9dd8b8e9afbd4f370da2dc9b3d23bb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "#![no_std]\n// Copyright 2019 Octavian Oncescu\n\nuse core::ffi::c_void;\n\n#[cfg(feature = \"extended\")]\nmod extended;\n#[cfg(feature = \"extended\")]\npub use extended::*;\n\nextern \"C\" {\n    /// Allocate zero-initialized `size` bytes.\n    ///\n    /// Returns a pointer to newly allocated zero-initialized memory, or null if\n    /// out of memory.\n    pub fn mi_zalloc(size: usize) -> *mut c_void;\n\n    /// Allocate `size` bytes.\n    ///\n    /// Returns pointer to the allocated memory or null if out of memory.\n    /// Returns a unique pointer if called with `size` 0.\n    pub fn mi_malloc(size: usize) -> *mut c_void;\n\n    /// Re-allocate memory to `newsize` bytes.\n    ///\n    /// Return pointer to the allocated memory or null if out of memory. If null\n    /// is returned, the pointer `p` is not freed. Otherwise the original\n    /// pointer is either freed or returned as the reallocated result (in case\n    /// it fits in-place with the new size).\n    ///\n    /// If `p` is null, it behaves as [`mi_malloc`]. If `newsize` is larger than\n    /// the original `size` allocated for `p`, the bytes after `size` are\n    /// uninitialized.\n    pub fn mi_realloc(p: *mut c_void, newsize: usize) -> *mut c_void;\n\n    /// Allocate `size` bytes aligned by `alignment`, initialized to zero.\n    ///\n    /// Return pointer to the allocated memory or null if out of memory.\n    ///\n    /// Returns a unique pointer if called with `size` 0.\n    pub fn mi_zalloc_aligned(size: usize, alignment: usize) -> *mut c_void;\n\n    /// Allocate `size` bytes aligned by `alignment`.\n    ///\n    /// Return pointer to the allocated memory or null if out of memory.\n    ///\n    /// Returns a unique pointer if called with `size` 0.\n    pub fn mi_malloc_aligned(size: usize, alignment: usize) -> *mut c_void;\n\n    /// Re-allocate memory to `newsize` bytes, aligned by `alignment`.\n    ///\n    /// Return pointer to the allocated memory or null if out of memory. If null\n    /// is returned, the pointer `p` is not freed. Otherwise the original\n    /// pointer is either freed or returned as the reallocated result (in case\n    /// it fits in-place with the new size).\n    ///\n    /// If `p` is null, it behaves as [`mi_malloc_aligned`]. If `newsize` is\n    /// larger than the original `size` allocated for `p`, the bytes after\n    /// `size` are uninitialized.\n    pub fn mi_realloc_aligned(p: *mut c_void, newsize: usize, alignment: usize) -> *mut c_void;\n\n    /// Free previously allocated memory.\n    ///\n    /// The pointer `p` must have been allocated before (or be null).\n    pub fn mi_free(p: *mut c_void);\n}\n\n/// When using the `\"override\"` feature flag, the user wants us to globally\n/// override the system allocator.\n///\n/// However, since we build and link `mimalloc` as a static library/archive,\n/// the linker may decide to not care about our overrides if it can't directly\n/// see references to the symbols, see the following link for details:\n/// <https://maskray.me/blog/2021-06-20-symbol-processing#archive-processing>\n///\n/// This is problematic if `mimalloc` is used from a library that by itself\n/// doesn't allocate, yet invokes other shared libraries that do, since then\n/// the linker wouldn't see any references to `malloc`/`free`, and the symbols\n/// would not be overridden.\n///\n/// To avoid this problem, we make sure that the allocator functions are\n/// visible to the linker.\n///\n/// To avoid this problem, we reference `mi_malloc` in a `#[used]` static.\n/// This makes it known to `rustc`, which will create a reference to it in a\n/// `symbols.o` stub file that is later passed directly to the linker (instead\n/// of being in an archive). See the following link for details on how this\n/// works: <https://github.com/rust-lang/rust/pull/95604>\n///\n/// NOTE: This works because `mimalloc` is compiled into a single object file\n/// in `static.c`. If it was split across multiple files, we'd need to\n/// reference each symbol. See also the comment at the top of `static.c`.\n///\n/// NOTE: On macOS, mimalloc doesn't just override malloc/free, but also\n/// registers itself with the allocator's zone APIs in a ctor\n/// (`_mi_macos_override_malloc`, marked with `__attribute__((constructor))`).\n/// Similarly to above, for the Mach-O linker to actually consider ctors as\n/// \"used\" when defined in an archive member in a static library, so we need\n/// to explicitly reference something in the object file. The constructor\n/// symbol itself is static, so we can't get a reference to that, so instead\n/// we reference `mi_malloc` here too).\n#[cfg(feature = \"override\")]\nmod set_up_statics {\n    use super::*;\n    #[used] // Could be `#[used(linker)]` once stable\n    static USED: unsafe extern \"C\" fn(usize) -> *mut c_void = mi_malloc;\n}\n\n#[cfg(test)]\nmod tests {\n    extern crate libc;\n    use super::*;\n\n    #[test]\n    fn it_frees_memory_malloc() {\n        let ptr = unsafe { mi_malloc_aligned(8, 8) } as *mut u8;\n        unsafe { mi_free(ptr as *mut c_void) };\n    }\n\n    #[test]\n    fn it_frees_memory_zalloc() {\n        let ptr = unsafe { mi_zalloc_aligned(8, 8) } as *mut u8;\n        unsafe { mi_free(ptr as *mut c_void) };\n    }\n\n    #[test]\n    fn it_frees_memory_realloc() {\n        let ptr = unsafe { mi_malloc_aligned(8, 8) } as *mut u8;\n        let ptr = unsafe { mi_realloc_aligned(ptr as *mut c_void, 8, 8) } as *mut u8;\n        unsafe { mi_free(ptr as *mut c_void) };\n    }\n\n    #[cfg(all(feature = \"override\", target_vendor = \"apple\"))]\n    #[test]\n    fn mimalloc_and_libc_are_interoperable_when_overridden() {\n        let ptr = unsafe { mi_malloc(42) };\n        unsafe { libc::free(ptr) };\n    }\n}\n"
    },
    {
      "package": "log@0.4.34",
      "sourcePath": "src/lib.rs",
      "sha256": "f6633a72e77e5039ef767189116986ba12a57e43304b40eebb466959e03b9a92",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! A lightweight logging facade.\n//!\n//! The `log` crate provides a single logging API that abstracts over the\n//! actual logging implementation. Libraries can use the logging API provided\n//! by this crate, and the consumer of those libraries can choose the logging\n//! implementation that is most suitable for its use case.\n//!\n//! If no logging implementation is selected, the facade falls back to a \"noop\"\n//! implementation that ignores all log messages. The overhead in this case\n//! is very small - just an integer load, comparison and jump.\n//!\n//! A log request consists of a _target_, a _level_, and a _body_. A target is a\n//! string which defaults to the module path of the location of the log request,\n//! though that default may be overridden. Logger implementations typically use\n//! the target to filter requests based on some user configuration.\n//!\n//! # Usage\n//!\n//! The basic use of the log crate is through the five logging macros: [`error!`],\n//! [`warn!`], [`info!`], [`debug!`] and [`trace!`]\n//! where `error!` represents the highest-priority log messages\n//! and `trace!` the lowest. The log messages are filtered by configuring\n//! the log level to exclude messages with a lower priority.\n//! Each of these macros accept format strings similarly to [`println!`].\n//!\n//!\n//! [`error!`]: ./macro.error.html\n//! [`warn!`]: ./macro.warn.html\n//! [`info!`]: ./macro.info.html\n//! [`debug!`]: ./macro.debug.html\n//! [`trace!`]: ./macro.trace.html\n//! [`println!`]: https://doc.rust-lang.org/stable/std/macro.println.html\n//!\n//! Avoid writing expressions with side-effects in log statements. They may not be evaluated.\n//!\n//! ## In libraries\n//!\n//! Libraries should link only to the `log` crate, and use the provided\n//! macros to log whatever information will be useful to downstream consumers.\n//!\n//! ### Examples\n//!\n//! ```\n//! # #[derive(Debug)] pub struct Yak(String);\n//! # impl Yak { fn shave(&mut self, _: u32) {} }\n//! # fn find_a_razor() -> Result<u32, u32> { Ok(1) }\n//! use log::{info, warn};\n//!\n//! pub fn shave_the_yak(yak: &mut Yak) {\n//!     info!(target: \"yak_events\", \"Commencing yak shaving for {yak:?}\");\n//!\n//!     loop {\n//!         match find_a_razor() {\n//!             Ok(razor) => {\n//!                 info!(\"Razor located: {razor}\");\n//!                 yak.shave(razor);\n//!                 break;\n//!             }\n//!             Err(err) => {\n//!                 warn!(\"Unable to locate a razor: {err}, retrying\");\n//!             }\n//!         }\n//!     }\n//! }\n//! # fn main() {}\n//! ```\n//!\n//! ## In executables\n//!\n//! Executables should choose a logging implementation and initialize it early in the\n//! runtime of the program. Logging implementations will typically include a\n//! function to do this. Any log messages generated before\n//! the implementation is initialized will be ignored.\n//!\n//! The executable itself may use the `log` crate to log as well.\n//!\n//! ### Warning\n//!\n//! The logging system may only be initialized once.\n//!\n//! ## Structured logging\n//!\n//! If you enable the `kv` feature you can associate structured values\n//! with your log records. If we take the example from before, we can include\n//! some additional context besides what's in the formatted message:\n//!\n//! ```\n//! # use serde::Serialize;\n//! # #[derive(Debug, Serialize)] pub struct Yak(String);\n//! # impl Yak { fn shave(&mut self, _: u32) {} }\n//! # fn find_a_razor() -> Result<u32, std::io::Error> { Ok(1) }\n//! # #[cfg(feature = \"kv_serde\")]\n//! # fn main() {\n//! use log::{info, warn};\n//!\n//! pub fn shave_the_yak(yak: &mut Yak) {\n//!     info!(target: \"yak_events\", yak:serde; \"Commencing yak shaving\");\n//!\n//!     loop {\n//!         match find_a_razor() {\n//!             Ok(razor) => {\n//!                 info!(razor; \"Razor located\");\n//!                 yak.shave(razor);\n//!                 break;\n//!             }\n//!             Err(e) => {\n//!                 warn!(e:err; \"Unable to locate a razor, retrying\");\n//!             }\n//!         }\n//!     }\n//! }\n//! # }\n//! # #[cfg(not(feature = \"kv_serde\"))]\n//! # fn main() {}\n//! ```\n//!\n//! See the [`kv`] module documentation for more details.\n//!\n//! # Available logging implementations\n//!\n//! In order to produce log output executables have to use\n//! a logger implementation compatible with the facade.\n//! There are many available implementations to choose from,\n//! here are some of the most popular ones:\n//!\n//! * Simple minimal loggers:\n//!     * [env_logger]\n//!     * [colog]\n//!     * [simple_logger]\n//!     * [simplelog]\n//!     * [pretty_env_logger]\n//!     * [stderrlog]\n//!     * [flexi_logger]\n//!     * [call_logger]\n//!     * [std-logger]\n//!     * [structured-logger]\n//!     * [clang_log]\n//!     * [ftail]\n//! * Complex configurable frameworks:\n//!     * [log4rs]\n//!     * [logforth]\n//!     * [fern]\n//!     * [spdlog-rs]\n//! * Adaptors for other facilities:\n//!     * [syslog]\n//!     * [slog-stdlog]\n//!     * [systemd-journal-logger]\n//!     * [android_log]\n//!     * [win_dbg_logger]\n//!     * [db_logger]\n//!     * [log-to-defmt]\n//!     * [logcontrol-log]\n//! * For WebAssembly binaries:\n//!     * [console_log]\n//! * For dynamic libraries:\n//!     * You may need to construct an FFI-safe wrapper over `log` to initialize in your libraries\n//! * Utilities:\n//!     * [log_err]\n//!     * [log-reload]\n//!     * [alterable_logger]\n//!\n//! # Implementing a Logger\n//!\n//! Loggers implement the [`Log`] trait. Here's a very basic example that simply\n//! logs all messages at the [`Error`][level_link], [`Warn`][level_link] or\n//! [`Info`][level_link] levels to stdout:\n//!\n//! ```\n//! use log::{Record, Level, Metadata};\n//!\n//! struct SimpleLogger;\n//!\n//! impl log::Log for SimpleLogger {\n//!     fn enabled(&self, metadata: &Metadata) -> bool {\n//!         metadata.level() <= Level::Info\n//!     }\n//!\n//!     fn log(&self, record: &Record) {\n//!         if self.enabled(record.metadata()) {\n//!             println!(\"{} - {}\", record.level(), record.args());\n//!         }\n//!     }\n//!\n//!     fn flush(&self) {}\n//! }\n//!\n//! # fn main() {}\n//! ```\n//!\n//! Loggers are installed by calling the [`set_logger`] function. The maximum\n//! log level also needs to be adjusted via the [`set_max_level`] function. The\n//! logging facade uses this as an optimization to improve performance of log\n//! messages at levels that are disabled. It's important to set it, as it\n//! defaults to [`Off`][filter_link], so no log messages will ever be captured!\n//! In the case of our example logger, we'll want to set the maximum log level\n//! to [`Info`][filter_link], since we ignore any [`Debug`][level_link] or\n//! [`Trace`][level_link] level log messages. A logging implementation should\n//! provide a function that wraps a call to [`set_logger`] and\n//! [`set_max_level`], handling initialization of the logger:\n//!\n//! ```\n//! # use log::{Level, Metadata};\n//! # struct SimpleLogger;\n//! # impl log::Log for SimpleLogger {\n//! #   fn enabled(&self, _: &Metadata) -> bool { false }\n//! #   fn log(&self, _: &log::Record) {}\n//! #   fn flush(&self) {}\n//! # }\n//! # fn main() {}\n//! use log::{SetLoggerError, LevelFilter};\n//!\n//! static LOGGER: SimpleLogger = SimpleLogger;\n//!\n//! pub fn init() -> Result<(), SetLoggerError> {\n//!     log::set_logger(&LOGGER)\n//!         .map(|()| log::set_max_level(LevelFilter::Info))\n//! }\n//! ```\n//!\n//! Implementations that adjust their configurations at runtime should take care\n//! to adjust the maximum log level as well.\n//!\n//! # Use with `alloc`\n//!\n//! `set_logger` requires you to provide a `&'static Log`, which can be hard to\n//! obtain if your logger depends on some runtime configuration. The\n//! `set_boxed_logger` function is available with the `alloc` Cargo feature. It\n//! is identical to `set_logger` except that it takes a `Box<Log>` rather than a\n//! `&'static Log`:\n//!\n//! ```\n//! # use log::{Level, LevelFilter, Log, SetLoggerError, Metadata};\n//! # struct SimpleLogger;\n//! # impl log::Log for SimpleLogger {\n//! #   fn enabled(&self, _: &Metadata) -> bool { false }\n//! #   fn log(&self, _: &log::Record) {}\n//! #   fn flush(&self) {}\n//! # }\n//! # fn main() {}\n//! # #[cfg(feature = \"alloc\")]\n//! # extern crate alloc;\n//! # #[cfg(feature = \"alloc\")]\n//! # use alloc::boxed::Box;\n//! # #[cfg(feature = \"alloc\")]\n//! pub fn init() -> Result<(), SetLoggerError> {\n//!     log::set_boxed_logger(Box::new(SimpleLogger))\n//!         .map(|()| log::set_max_level(LevelFilter::Info))\n//! }\n//! ```\n//!\n//! # Compile time filters\n//!\n//! Log levels can be statically disabled at compile time by enabling one of these Cargo features:\n//!\n//! * `max_level_off`\n//! * `max_level_error`\n//! * `max_level_warn`\n//! * `max_level_info`\n//! * `max_level_debug`\n//! * `max_level_trace`\n//!\n//! Log invocations at disabled levels will be skipped and will not even be present in the\n//! resulting binary. These features control the value of the `STATIC_MAX_LEVEL` constant. The\n//! logging macros check this value before logging a message. By default, no levels are disabled.\n//!\n//! It is possible to override this level for release builds only with the following features:\n//!\n//! * `release_max_level_off`\n//! * `release_max_level_error`\n//! * `release_max_level_warn`\n//! * `release_max_level_info`\n//! * `release_max_level_debug`\n//! * `release_max_level_trace`\n//!\n//! Libraries should avoid using the max level features because they're global and can't be changed\n//! once they're set.\n//!\n//! For example, a crate can disable trace level logs in debug builds and trace, debug, and info\n//! level logs in release builds with the following configuration:\n//!\n//! ```toml\n//! [dependencies]\n//! log = { version = \"0.4\", features = [\"max_level_debug\", \"release_max_level_warn\"] }\n//! ```\n//! # Crate Feature Flags\n//!\n//! The following crate feature flags are available in addition to the filters. They are\n//! configured in your `Cargo.toml`.\n//!\n//! * `alloc` enables using `alloc::boxed::Box` and `set_boxed_logger`.\n//! * `std` enables `alloc` and allows use of the `std` crate instead of the default `core`.\n//!   It also enables using `std::error`.\n//! * `serde` enables support for serialization and deserialization of `Level` and `LevelFilter`.\n//!\n//! ```toml\n//! [dependencies]\n//! log = { version = \"0.4\", features = [\"std\", \"serde\"] }\n//! ```\n//!\n//! # Version compatibility\n//!\n//! The 0.3 and 0.4 versions of the `log` crate are almost entirely compatible. Log messages\n//! made using `log` 0.3 will forward transparently to a logger implementation using `log` 0.4. Log\n//! messages made using `log` 0.4 will forward to a logger implementation using `log` 0.3, but the\n//! module path and file name information associated with the message will unfortunately be lost.\n//!\n//! [`Log`]: trait.Log.html\n//! [level_link]: enum.Level.html\n//! [filter_link]: enum.LevelFilter.html\n//! [`set_logger`]: fn.set_logger.html\n//! [`set_max_level`]: fn.set_max_level.html\n//! [`try_set_logger_raw`]: fn.try_set_logger_raw.html\n//! [`shutdown_logger_raw`]: fn.shutdown_logger_raw.html\n//! [env_logger]: https://docs.rs/env_logger/*/env_logger/\n//! [colog]: https://docs.rs/colog/*/colog/\n//! [simple_logger]: https://github.com/borntyping/rust-simple_logger\n//! [simplelog]: https://github.com/drakulix/simplelog.rs\n//! [pretty_env_logger]: https://docs.rs/pretty_env_logger/*/pretty_env_logger/\n//! [stderrlog]: https://docs.rs/stderrlog/*/stderrlog/\n//! [flexi_logger]: https://docs.rs/flexi_logger/*/flexi_logger/\n//! [call_logger]: https://docs.rs/call_logger/*/call_logger/\n//! [std-logger]: https://docs.rs/std-logger/*/std_logger/\n//! [syslog]: https://docs.rs/syslog/*/syslog/\n//! [slog-stdlog]: https://docs.rs/slog-stdlog/*/slog_stdlog/\n//! [log4rs]: https://docs.rs/log4rs/*/log4rs/\n//! [logforth]: https://docs.rs/logforth/*/logforth/\n//! [fern]: https://docs.rs/fern/*/fern/\n//! [spdlog-rs]: https://docs.rs/spdlog-rs/*/spdlog/\n//! [systemd-journal-logger]: https://docs.rs/systemd-journal-logger/*/systemd_journal_logger/\n//! [android_log]: https://docs.rs/android_log/*/android_log/\n//! [win_dbg_logger]: https://docs.rs/win_dbg_logger/*/win_dbg_logger/\n//! [db_logger]: https://docs.rs/db_logger/*/db_logger/\n//! [log-to-defmt]: https://docs.rs/log-to-defmt/*/log_to_defmt/\n//! [console_log]: https://docs.rs/console_log/*/console_log/\n//! [structured-logger]: https://docs.rs/structured-logger/latest/structured_logger/\n//! [logcontrol-log]: https://docs.rs/logcontrol-log/*/logcontrol_log/\n//! [log_err]: https://docs.rs/log_err/*/log_err/\n//! [log-reload]: https://docs.rs/log-reload/*/log_reload/\n//! [alterable_logger]: https://docs.rs/alterable_logger/*/alterable_logger\n//! [clang_log]: https://docs.rs/clang_log/latest/clang_log\n//! [ftail]: https://docs.rs/ftail/latest/ftail\n\n#![doc(\n    html_logo_url = \"https://prev.rust-lang.org/logos/rust-logo-128x128-blk-v2.png\",\n    html_favicon_url = \"https://prev.rust-lang.org/favicon.ico\",\n    html_root_url = \"https://docs.rs/log/0.4.34\"\n)]\n#![warn(missing_docs)]\n#![deny(missing_debug_implementations, unconditional_recursion)]\n#![cfg_attr(all(not(feature = \"std\"), not(test)), no_std)]\n\n#[cfg(any(\n    all(feature = \"max_level_off\", feature = \"max_level_error\"),\n    all(feature = \"max_level_off\", feature = \"max_level_warn\"),\n    all(feature = \"max_level_off\", feature = \"max_level_info\"),\n    all(feature = \"max_level_off\", feature = \"max_level_debug\"),\n    all(feature = \"max_level_off\", feature = \"max_level_trace\"),\n    all(feature = \"max_level_error\", feature = \"max_level_warn\"),\n    all(feature = \"max_level_error\", feature = \"max_level_info\"),\n    all(feature = \"max_level_error\", feature = \"max_level_debug\"),\n    all(feature = \"max_level_error\", feature = \"max_level_trace\"),\n    all(feature = \"max_level_warn\", feature = \"max_level_info\"),\n    all(feature = \"max_level_warn\", feature = \"max_level_debug\"),\n    all(feature = \"max_level_warn\", feature = \"max_level_trace\"),\n    all(feature = \"max_level_info\", feature = \"max_level_debug\"),\n    all(feature = \"max_level_info\", feature = \"max_level_trace\"),\n    all(feature = \"max_level_debug\", feature = \"max_level_trace\"),\n))]\ncompile_error!(\"multiple max_level_* features set\");\n\n#[rustfmt::skip]\n#[cfg(any(\n    all(feature = \"release_max_level_off\", feature = \"release_max_level_error\"),\n    all(feature = \"release_max_level_off\", feature = \"release_max_level_warn\"),\n    all(feature = \"release_max_level_off\", feature = \"release_max_level_info\"),\n    all(feature = \"release_max_level_off\", feature = \"release_max_level_debug\"),\n    all(feature = \"release_max_level_off\", feature = \"release_max_level_trace\"),\n    all(feature = \"release_max_level_error\", feature = \"release_max_level_warn\"),\n    all(feature = \"release_max_level_error\", feature = \"release_max_level_info\"),\n    all(feature = \"release_max_level_error\", feature = \"release_max_level_debug\"),\n    all(feature = \"release_max_level_error\", feature = \"release_max_level_trace\"),\n    all(feature = \"release_max_level_warn\", feature = \"release_max_level_info\"),\n    all(feature = \"release_max_level_warn\", feature = \"release_max_level_debug\"),\n    all(feature = \"release_max_level_warn\", feature = \"release_max_level_trace\"),\n    all(feature = \"release_max_level_info\", feature = \"release_max_level_debug\"),\n    all(feature = \"release_max_level_info\", feature = \"release_max_level_trace\"),\n    all(feature = \"release_max_level_debug\", feature = \"release_max_level_trace\"),\n))]\ncompile_error!(\"multiple release_max_level_* features set\");\n\n#[cfg(feature = \"alloc\")]\nextern crate alloc;\n#[cfg(all(not(feature = \"std\"), not(test)))]\nextern crate core as std;\n\n#[cfg(feature = \"alloc\")]\nuse alloc::boxed::Box;\nuse std::cfg;\n#[cfg(feature = \"std\")]\nuse std::error;\nuse std::str::FromStr;\nuse std::{cmp, fmt, mem};\n\n#[macro_use]\nmod macros;\nmod serde;\n\n#[cfg(feature = \"kv\")]\npub mod kv;\n\n#[cfg(target_has_atomic = \"ptr\")]\nuse std::sync::atomic::{AtomicUsize, Ordering};\n\n#[cfg(not(target_has_atomic = \"ptr\"))]\nuse std::cell::Cell;\n#[cfg(not(target_has_atomic = \"ptr\"))]\nuse std::sync::atomic::Ordering;\n\n#[cfg(not(target_has_atomic = \"ptr\"))]\nstruct AtomicUsize {\n    v: Cell<usize>,\n}\n\n#[cfg(not(target_has_atomic = \"ptr\"))]\nimpl AtomicUsize {\n    const fn new(v: usize) -> AtomicUsize {\n        AtomicUsize { v: Cell::new(v) }\n    }\n\n    fn load(&self, _order: Ordering) -> usize {\n        self.v.get()\n    }\n\n    fn store(&self, val: usize, _order: Ordering) {\n        self.v.set(val)\n    }\n}\n\n// Any platform without atomics is unlikely to have multiple cores, so\n// writing via Cell will not be a race condition.\n#[cfg(not(target_has_atomic = \"ptr\"))]\nunsafe impl Sync for AtomicUsize {}\n\n// The LOGGER static holds a pointer to the global logger. It is protected by\n// the STATE static which determines whether LOGGER has been initialized yet.\nstatic mut LOGGER: &dyn Log = &NopLogger;\n\nstatic STATE: AtomicUsize = AtomicUsize::new(0);\n\n// There are three different states that we care about: the logger's\n// uninitialized, the logger's initializing (set_logger's been called but\n// LOGGER hasn't actually been set yet), or the logger's active.\nconst UNINITIALIZED: usize = 0;\nconst INITIALIZING: usize = 1;\nconst INITIALIZED: usize = 2;\n\nstatic MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(0);\n\nstatic LOG_LEVEL_NAMES: [&str; 6] = [\"OFF\", \"ERROR\", \"WARN\", \"INFO\", \"DEBUG\", \"TRACE\"];\n\nstatic SET_LOGGER_ERROR: &str = \"attempted to set a logger after the logging system \\\n                                 was already initialized\";\nstatic LEVEL_PARSE_ERROR: &str =\n    \"attempted to convert a string that doesn't match an existing log level\";\n\n/// An enum representing the available verbosity levels of the logger.\n///\n/// Typical usage includes: checking if a certain `Level` is enabled with\n/// [`log_enabled!`](macro.log_enabled.html), specifying the `Level` of\n/// [`log!`](macro.log.html), and comparing a `Level` directly to a\n/// [`LevelFilter`](enum.LevelFilter.html).\n#[repr(usize)]\n#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]\npub enum Level {\n    /// The \"error\" level.\n    ///\n    /// Designates very serious errors.\n    // This way these line up with the discriminants for LevelFilter below\n    // This works because Rust treats field-less enums the same way as C does:\n    // https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-field-less-enumerations\n    Error = 1,\n    /// The \"warn\" level.\n    ///\n    /// Designates hazardous situations.\n    Warn,\n    /// The \"info\" level.\n    ///\n    /// Designates useful information.\n    Info,\n    /// The \"debug\" level.\n    ///\n    /// Designates lower priority information.\n    Debug,\n    /// The \"trace\" level.\n    ///\n    /// Designates very low priority, often extremely verbose, information.\n    Trace,\n}\n\nimpl PartialEq<LevelFilter> for Level {\n    #[inline]\n    fn eq(&self, other: &LevelFilter) -> bool {\n        *self as usize == *other as usize\n    }\n}\n\nimpl PartialOrd<LevelFilter> for Level {\n    #[inline]\n    fn partial_cmp(&self, other: &LevelFilter) -> Option<cmp::Ordering> {\n        Some((*self as usize).cmp(&(*other as usize)))\n    }\n}\n\nimpl FromStr for Level {\n    type Err = ParseLevelError;\n    fn from_str(level: &str) -> Result<Level, Self::Err> {\n        // iterate from 1, excluding \"OFF\"\n        for idx in 1..LOG_LEVEL_NAMES.len() {\n            if LOG_LEVEL_NAMES[idx].eq_ignore_ascii_case(level) {\n                return Ok(Level::from_usize(idx).unwrap());\n            }\n        }\n        Err(ParseLevelError(()))\n    }\n}\n\nimpl fmt::Display for Level {\n    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {\n        fmt.pad(self.as_str())\n    }\n}\n\nimpl Level {\n    fn from_usize(u: usize) -> Option<Level> {\n        match u {\n            1 => Some(Level::Error),\n            2 => Some(Level::Warn),\n            3 => Some(Level::Info),\n            4 => Some(Level::Debug),\n            5 => Some(Level::Trace),\n            _ => None,\n        }\n    }\n\n    /// Returns the most verbose logging level.\n    #[inline]\n    pub fn max() -> Level {\n        Level::Trace\n    }\n\n    /// Converts the `Level` to the equivalent `LevelFilter`.\n    #[inline]\n    pub fn to_level_filter(&self) -> LevelFilter {\n        LevelFilter::from_usize(*self as usize).unwrap()\n    }\n\n    /// Returns the string representation of the `Level`.\n    ///\n    /// This returns the same string as the `fmt::Display` implementation.\n    pub fn as_str(&self) -> &'static str {\n        LOG_LEVEL_NAMES[*self as usize]\n    }\n\n    /// Iterate through all supported logging levels.\n    ///\n    /// The order of iteration is from more severe to less severe log messages.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use log::Level;\n    ///\n    /// let mut levels = Level::iter();\n    ///\n    /// assert_eq!(Some(Level::Error), levels.next());\n    /// assert_eq!(Some(Level::Trace), levels.last());\n    /// ```\n    pub fn iter() -> impl Iterator<Item = Self> {\n        (1..6).map(|i| Self::from_usize(i).unwrap())\n    }\n\n    /// Get the next-highest `Level` from this one.\n    ///\n    /// If the current `Level` is at the highest level, the returned `Level` will be the same as the\n    /// current one.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use log::Level;\n    ///\n    /// let level = Level::Info;\n    ///\n    /// assert_eq!(Level::Debug, level.increment_severity());\n    /// assert_eq!(Level::Trace, level.increment_severity().increment_severity());\n    /// assert_eq!(Level::Trace, level.increment_severity().increment_severity().increment_severity()); // max level\n    /// ```\n    pub fn increment_severity(&self) -> Self {\n        let current = *self as usize;\n        Self::from_usize(current + 1).unwrap_or(*self)\n    }\n\n    /// Get the next-lowest `Level` from this one.\n    ///\n    /// If the current `Level` is at the lowest level, the returned `Level` will be the same as the\n    /// current one.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use log::Level;\n    ///\n    /// let level = Level::Info;\n    ///\n    /// assert_eq!(Level::Warn, level.decrement_severity());\n    /// assert_eq!(Level::Error, level.decrement_severity().decrement_severity());\n    /// assert_eq!(Level::Error, level.decrement_severity().decrement_severity().decrement_severity()); // min level\n    /// ```\n    pub fn decrement_severity(&self) -> Self {\n        let current = *self as usize;\n        Self::from_usize(current.saturating_sub(1)).unwrap_or(*self)\n    }\n}\n\n/// An enum representing the available verbosity level filters of the logger.\n///\n/// A `LevelFilter` may be compared directly to a [`Level`]. Use this type\n/// to get and set the maximum log level with [`max_level()`] and [`set_max_level`].\n///\n/// [`Level`]: enum.Level.html\n/// [`max_level()`]: fn.max_level.html\n/// [`set_max_level`]: fn.set_max_level.html\n#[repr(usize)]\n#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]\npub enum LevelFilter {\n    /// A level lower than all log levels.\n    Off,\n    /// Corresponds to the `Error` log level.\n    Error,\n    /// Corresponds to the `Warn` log level.\n    Warn,\n    /// Corresponds to the `Info` log level.\n    Info,\n    /// Corresponds to the `Debug` log level.\n    Debug,\n    /// Corresponds to the `Trace` log level.\n    Trace,\n}\n\nimpl PartialEq<Level> for LevelFilter {\n    #[inline]\n    fn eq(&self, other: &Level) -> bool {\n        other.eq(self)\n    }\n}\n\nimpl PartialOrd<Level> for LevelFilter {\n    #[inline]\n    fn partial_cmp(&self, other: &Level) -> Option<cmp::Ordering> {\n        Some((*self as usize).cmp(&(*other as usize)))\n    }\n}\n\nimpl FromStr for LevelFilter {\n    type Err = ParseLevelError;\n    fn from_str(level: &str) -> Result<LevelFilter, Self::Err> {\n        // iterate from 0, including \"OFF\"\n        for idx in 0..LOG_LEVEL_NAMES.len() {\n            if LOG_LEVEL_NAMES[idx].eq_ignore_ascii_case(level) {\n                return Ok(LevelFilter::from_usize(idx).unwrap());\n            }\n        }\n        Err(ParseLevelError(()))\n    }\n}\n\nimpl fmt::Display for LevelFilter {\n    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {\n        fmt.pad(self.as_str())\n    }\n}\n\nimpl LevelFilter {\n    fn from_usize(u: usize) -> Option<LevelFilter> {\n        match u {\n            0 => Some(LevelFilter::Off),\n            1 => Some(LevelFilter::Error),\n            2 => Some(LevelFilter::Warn),\n            3 => Some(LevelFilter::Info),\n            4 => Some(LevelFilter::Debug),\n            5 => Some(LevelFilter::Trace),\n            _ => None,\n        }\n    }\n\n    /// Returns the most verbose logging level filter.\n    #[inline]\n    pub fn max() -> LevelFilter {\n        LevelFilter::Trace\n    }\n\n    /// Converts `self` to the equivalent `Level`.\n    ///\n    /// Returns `None` if `self` is `LevelFilter::Off`.\n    #[inline]\n    pub fn to_level(&self) -> Option<Level> {\n        Level::from_usize(*self as usize)\n    }\n\n    /// Returns the string representation of the `LevelFilter`.\n    ///\n    /// This returns the same string as the `fmt::Display` implementation.\n    pub fn as_str(&self) -> &'static str {\n        LOG_LEVEL_NAMES[*self as usize]\n    }\n\n    /// Iterate through all supported filtering levels.\n    ///\n    /// The order of iteration is from less to more verbose filtering.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use log::LevelFilter;\n    ///\n    /// let mut levels = LevelFilter::iter();\n    ///\n    /// assert_eq!(Some(LevelFilter::Off), levels.next());\n    /// assert_eq!(Some(LevelFilter::Trace), levels.last());\n    /// ```\n    pub fn iter() -> impl Iterator<Item = Self> {\n        (0..6).map(|i| Self::from_usize(i).unwrap())\n    }\n\n    /// Get the next-highest `LevelFilter` from this one.\n    ///\n    /// If the current `LevelFilter` is at the highest level, the returned `LevelFilter` will be the\n    /// same as the current one.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use log::LevelFilter;\n    ///\n    /// let level_filter = LevelFilter::Info;\n    ///\n    /// assert_eq!(LevelFilter::Debug, level_filter.increment_severity());\n    /// assert_eq!(LevelFilter::Trace, level_filter.increment_severity().increment_severity());\n    /// assert_eq!(LevelFilter::Trace, level_filter.increment_severity().increment_severity().increment_severity()); // max level\n    /// ```\n    pub fn increment_severity(&self) -> Self {\n        let current = *self as usize;\n        Self::from_usize(current + 1).unwrap_or(*self)\n    }\n\n    /// Get the next-lowest `LevelFilter` from this one.\n    ///\n    /// If the current `LevelFilter` is at the lowest level, the returned `LevelFilter` will be the\n    /// same as the current one.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use log::LevelFilter;\n    ///\n    /// let level_filter = LevelFilter::Info;\n    ///\n    /// assert_eq!(LevelFilter::Warn, level_filter.decrement_severity());\n    /// assert_eq!(LevelFilter::Error, level_filter.decrement_severity().decrement_severity());\n    /// assert_eq!(LevelFilter::Off, level_filter.decrement_severity().decrement_severity().decrement_severity());\n    /// assert_eq!(LevelFilter::Off, level_filter.decrement_severity().decrement_severity().decrement_severity().decrement_severity()); // min level\n    /// ```\n    pub fn decrement_severity(&self) -> Self {\n        let current = *self as usize;\n        Self::from_usize(current.saturating_sub(1)).unwrap_or(*self)\n    }\n}\n\n#[derive(Copy, Clone, Debug)]\nenum MaybeStaticStr<'a> {\n    Static(&'static str),\n    Borrowed(&'a str),\n}\n\nimpl<'a> MaybeStaticStr<'a> {\n    #[inline]\n    fn get(&self) -> &'a str {\n        match *self {\n            MaybeStaticStr::Static(s) => s,\n            MaybeStaticStr::Borrowed(s) => s,\n        }\n    }\n}\n\nimpl Eq for MaybeStaticStr<'_> {}\n\nimpl PartialEq for MaybeStaticStr<'_> {\n    fn eq(&self, other: &Self) -> bool {\n        self.get() == other.get()\n    }\n}\n\nimpl Ord for MaybeStaticStr<'_> {\n    fn cmp(&self, other: &Self) -> core::cmp::Ordering {\n        self.get().cmp(other.get())\n    }\n}\n\nimpl PartialOrd for MaybeStaticStr<'_> {\n    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {\n        Some(self.cmp(other))\n    }\n}\n\nimpl std::hash::Hash for MaybeStaticStr<'_> {\n    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {\n        self.get().hash(state);\n    }\n}\n\n/// The \"payload\" of a log message.\n///\n/// # Use\n///\n/// `Record` structures are passed as parameters to the [`log`][method.log]\n/// method of the [`Log`] trait. Logger implementors manipulate these\n/// structures in order to display log messages. `Record`s are automatically\n/// created by the [`log!`] macro and so are not seen by log users.\n///\n/// Note that the [`level()`] and [`target()`] accessors are equivalent to\n/// `self.metadata().level()` and `self.metadata().target()` respectively.\n/// These methods are provided as a convenience for users of this structure.\n///\n/// # Example\n///\n/// The following example shows a simple logger that displays the level,\n/// module path, and message of any `Record` that is passed to it.\n///\n/// ```\n/// struct SimpleLogger;\n///\n/// impl log::Log for SimpleLogger {\n///    fn enabled(&self, _metadata: &log::Metadata) -> bool {\n///        true\n///    }\n///\n///    fn log(&self, record: &log::Record) {\n///        if !self.enabled(record.metadata()) {\n///            return;\n///        }\n///\n///        println!(\"{}:{} -- {}\",\n///                 record.level(),\n///                 record.target(),\n///                 record.args());\n///    }\n///    fn flush(&self) {}\n/// }\n/// ```\n///\n/// [method.log]: trait.Log.html#tymethod.log\n/// [`Log`]: trait.Log.html\n/// [`log!`]: macro.log.html\n/// [`level()`]: struct.Record.html#method.level\n/// [`target()`]: struct.Record.html#method.target\n#[derive(Clone, Debug)]\npub struct Record<'a> {\n    metadata: Metadata<'a>,\n    args: fmt::Arguments<'a>,\n    module_path: Option<MaybeStaticStr<'a>>,\n    file: Option<MaybeStaticStr<'a>>,\n    line: Option<u32>,\n    #[cfg(feature = \"kv\")]\n    key_values: KeyValues<'a>,\n}\n\n// This wrapper type is only needed so we can\n// `#[derive(Debug)]` on `Record`. It also\n// provides a useful `Debug` implementation for\n// the underlying `Source`.\n#[cfg(feature = \"kv\")]\n#[derive(Clone)]\nstruct KeyValues<'a>(&'a dyn kv::Source);\n\n#[cfg(feature = \"kv\")]\nimpl<'a> fmt::Debug for KeyValues<'a> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        let mut visitor = f.debug_map();\n        self.0.visit(&mut visitor).map_err(|_| fmt::Error)?;\n        visitor.finish()\n    }\n}\n\nimpl<'a> Record<'a> {\n    /// Returns a new builder.\n    #[inline]\n    pub fn builder() -> RecordBuilder<'a> {\n        RecordBuilder::new()\n    }\n\n    /// The message body.\n    #[inline]\n    pub fn args(&self) -> &fmt::Arguments<'a> {\n        &self.args\n    }\n\n    /// Metadata about the log directive.\n    #[inline]\n    pub fn metadata(&self) -> &Metadata<'a> {\n        &self.metadata\n    }\n\n    /// The verbosity level of the message.\n    #[inline]\n    pub fn level(&self) -> Level {\n        self.metadata.level()\n    }\n\n    /// The name of the target of the directive.\n    #[inline]\n    pub fn target(&self) -> &'a str {\n        self.metadata.target()\n    }\n\n    /// The module path of the message.\n    #[inline]\n    pub fn module_path(&self) -> Option<&'a str> {\n        self.module_path.map(|s| s.get())\n    }\n\n    /// The module path of the message, if it is a `'static` string.\n    #[inline]\n    pub fn module_path_static(&self) -> Option<&'static str> {\n        match self.module_path {\n            Some(MaybeStaticStr::Static(s)) => Some(s),\n            _ => None,\n        }\n    }\n\n    /// The source file containing the message.\n    #[inline]\n    pub fn file(&self) -> Option<&'a str> {\n        self.file.map(|s| s.get())\n    }\n\n    /// The source file containing the message, if it is a `'static` string.\n    #[inline]\n    pub fn file_static(&self) -> Option<&'static str> {\n        match self.file {\n            Some(MaybeStaticStr::Static(s)) => Some(s),\n            _ => None,\n        }\n    }\n\n    /// The line containing the message.\n    #[inline]\n    pub fn line(&self) -> Option<u32> {\n        self.line\n    }\n\n    /// The structured key-value pairs associated with the message.\n    #[cfg(feature = \"kv\")]\n    #[inline]\n    pub fn key_values(&self) -> &dyn kv::Source {\n        self.key_values.0\n    }\n\n    /// Create a new [`RecordBuilder`](struct.RecordBuilder.html) based on this record.\n    #[cfg(feature = \"kv\")]\n    #[inline]\n    pub fn to_builder(&self) -> RecordBuilder<'_> {\n        RecordBuilder {\n            record: Record {\n                metadata: Metadata {\n                    level: self.metadata.level,\n                    target: self.metadata.target,\n                },\n                args: self.args,\n                module_path: self.module_path,\n                file: self.file,\n                line: self.line,\n                key_values: self.key_values.clone(),\n            },\n        }\n    }\n}\n\n/// Builder for [`Record`](struct.Record.html).\n///\n/// Typically should only be used by log library creators or for testing and \"shim loggers\".\n/// The `RecordBuilder` can set the different parameters of `Record` object, and returns\n/// the created object when `build` is called.\n///\n/// # Examples\n///\n/// ```\n/// use log::{Level, Record};\n///\n/// let record = Record::builder()\n///                 .args(format_args!(\"Error!\"))\n///                 .level(Level::Error)\n///                 .target(\"myApp\")\n///                 .file(Some(\"server.rs\"))\n///                 .line(Some(144))\n///                 .module_path(Some(\"server\"))\n///                 .build();\n/// ```\n///\n/// Alternatively, use [`MetadataBuilder`](struct.MetadataBuilder.html):\n///\n/// ```\n/// use log::{Record, Level, MetadataBuilder};\n///\n/// let error_metadata = MetadataBuilder::new()\n///                         .target(\"myApp\")\n///                         .level(Level::Error)\n///                         .build();\n///\n/// let record = Record::builder()\n///                 .metadata(error_metadata)\n///                 .args(format_args!(\"Error!\"))\n///                 .line(Some(433))\n///                 .file(Some(\"app.rs\"))\n///                 .module_path(Some(\"server\"))\n///                 .build();\n/// ```\n#[derive(Debug)]\npub struct RecordBuilder<'a> {\n    record: Record<'a>,\n}\n\nimpl<'a> RecordBuilder<'a> {\n    /// Construct new `RecordBuilder`.\n    ///\n    /// The default options are:\n    ///\n    /// - `args`: [`format_args!(\"\")`]\n    /// - `metadata`: [`Metadata::builder().build()`]\n    /// - `module_path`: `None`\n    /// - `file`: `None`\n    /// - `line`: `None`\n    ///\n    /// [`format_args!(\"\")`]: https://doc.rust-lang.org/std/macro.format_args.html\n    /// [`Metadata::builder().build()`]: struct.MetadataBuilder.html#method.build\n    #[inline]\n    pub fn new() -> RecordBuilder<'a> {\n        RecordBuilder {\n            record: Record {\n                args: format_args!(\"\"),\n                metadata: Metadata::builder().build(),\n                module_path: None,\n                file: None,\n                line: None,\n                #[cfg(feature = \"kv\")]\n                key_values: KeyValues(&None::<(kv::Key, kv::Value)>),\n            },\n        }\n    }\n\n    /// Set [`args`](struct.Record.html#method.args).\n    #[inline]\n    pub fn args(&mut self, args: fmt::Arguments<'a>) -> &mut RecordBuilder<'a> {\n        self.record.args = args;\n        self\n    }\n\n    /// Set [`metadata`](struct.Record.html#method.metadata). Construct a `Metadata` object with [`MetadataBuilder`](struct.MetadataBuilder.html).\n    #[inline]\n    pub fn metadata(&mut self, metadata: Metadata<'a>) -> &mut RecordBuilder<'a> {\n        self.record.metadata = metadata;\n        self\n    }\n\n    /// Set [`Metadata::level`](struct.Metadata.html#method.level).\n    #[inline]\n    pub fn level(&mut self, level: Level) -> &mut RecordBuilder<'a> {\n        self.record.metadata.level = level;\n        self\n    }\n\n    /// Set [`Metadata::target`](struct.Metadata.html#method.target)\n    #[inline]\n    pub fn target(&mut self, target: &'a str) -> &mut RecordBuilder<'a> {\n        self.record.metadata.target = target;\n        self\n    }\n\n    /// Set [`module_path`](struct.Record.html#method.module_path)\n    #[inline]\n    pub fn module_path(&mut self, path: Option<&'a str>) -> &mut RecordBuilder<'a> {\n        self.record.module_path = path.map(MaybeStaticStr::Borrowed);\n        self\n    }\n\n    /// Set [`module_path`](struct.Record.html#method.module_path) to a `'static` string\n    #[inline]\n    pub fn module_path_static(&mut self, path: Option<&'static str>) -> &mut RecordBuilder<'a> {\n        self.record.module_path = path.map(MaybeStaticStr::Static);\n        self\n    }\n\n    /// Set [`file`](struct.Record.html#method.file)\n    #[inline]\n    pub fn file(&mut self, file: Option<&'a str>) -> &mut RecordBuilder<'a> {\n        self.record.file = file.map(MaybeStaticStr::Borrowed);\n        self\n    }\n\n    /// Set [`file`](struct.Record.html#method.file) to a `'static` string.\n    #[inline]\n    pub fn file_static(&mut self, file: Option<&'static str>) -> &mut RecordBuilder<'a> {\n        self.record.file = file.map(MaybeStaticStr::Static);\n        self\n    }\n\n    /// Set [`line`](struct.Record.html#method.line)\n    #[inline]\n    pub fn line(&mut self, line: Option<u32>) -> &mut RecordBuilder<'a> {\n        self.record.line = line;\n        self\n    }\n\n    /// Set [`key_values`](struct.Record.html#method.key_values)\n    #[cfg(feature = \"kv\")]\n    #[inline]\n    pub fn key_values(&mut self, kvs: &'a dyn kv::Source) -> &mut RecordBuilder<'a> {\n        self.record.key_values = KeyValues(kvs);\n        self\n    }\n\n    /// Invoke the builder and return a `Record`\n    #[inline]\n    pub fn build(&self) -> Record<'a> {\n        self.record.clone()\n    }\n}\n\nimpl Default for RecordBuilder<'_> {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\n/// Metadata about a log message.\n///\n/// # Use\n///\n/// `Metadata` structs are created when users of the library use\n/// logging macros.\n///\n/// They are consumed by implementations of the `Log` trait in the\n/// `enabled` method.\n///\n/// `Record`s use `Metadata` to determine the log message's severity\n/// and target.\n///\n/// Users should use the `log_enabled!` macro in their code to avoid\n/// constructing expensive log messages.\n///\n/// # Examples\n///\n/// ```\n/// use log::{Record, Level, Metadata};\n///\n/// struct MyLogger;\n///\n/// impl log::Log for MyLogger {\n///     fn enabled(&self, metadata: &Metadata) -> bool {\n///         metadata.level() <= Level::Info\n///     }\n///\n///     fn log(&self, record: &Record) {\n///         if self.enabled(record.metadata()) {\n///             println!(\"{} - {}\", record.level(), record.args());\n///         }\n///     }\n///     fn flush(&self) {}\n/// }\n///\n/// # fn main(){}\n/// ```\n#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]\npub struct Metadata<'a> {\n    level: Level,\n    target: &'a str,\n}\n\nimpl<'a> Metadata<'a> {\n    /// Returns a new builder.\n    #[inline]\n    pub fn builder() -> MetadataBuilder<'a> {\n        MetadataBuilder::new()\n    }\n\n    /// The verbosity level of the message.\n    #[inline]\n    pub fn level(&self) -> Level {\n        self.level\n    }\n\n    /// The name of the target of the directive.\n    #[inline]\n    pub fn target(&self) -> &'a str {\n        self.target\n    }\n}\n\n/// Builder for [`Metadata`](struct.Metadata.html).\n///\n/// Typically should only be used by log library creators or for testing and \"shim loggers\".\n/// The `MetadataBuilder` can set the different parameters of a `Metadata` object, and returns\n/// the created object when `build` is called.\n///\n/// # Example\n///\n/// ```\n/// let target = \"myApp\";\n/// use log::{Level, MetadataBuilder};\n/// let metadata = MetadataBuilder::new()\n///                     .level(Level::Debug)\n///                     .target(target)\n///                     .build();\n/// ```\n#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]\npub struct MetadataBuilder<'a> {\n    metadata: Metadata<'a>,\n}\n\nimpl<'a> MetadataBuilder<'a> {\n    /// Construct a new `MetadataBuilder`.\n    ///\n    /// The default options are:\n    ///\n    /// - `level`: `Level::Info`\n    /// - `target`: `\"\"`\n    #[inline]\n    pub fn new() -> MetadataBuilder<'a> {\n        MetadataBuilder {\n            metadata: Metadata {\n                level: Level::Info,\n                target: \"\",\n            },\n        }\n    }\n\n    /// Setter for [`level`](struct.Metadata.html#method.level).\n    #[inline]\n    pub fn level(&mut self, arg: Level) -> &mut MetadataBuilder<'a> {\n        self.metadata.level = arg;\n        self\n    }\n\n    /// Setter for [`target`](struct.Metadata.html#method.target).\n    #[inline]\n    pub fn target(&mut self, target: &'a str) -> &mut MetadataBuilder<'a> {\n        self.metadata.target = target;\n        self\n    }\n\n    /// Returns a `Metadata` object.\n    #[inline]\n    pub fn build(&self) -> Metadata<'a> {\n        self.metadata.clone()\n    }\n}\n\nimpl Default for MetadataBuilder<'_> {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\n/// A trait encapsulating the operations required of a logger.\npub trait Log: Sync + Send {\n    /// Determines if a log message with the specified metadata would be\n    /// logged.\n    ///\n    /// This is used by the `log_enabled!` macro to allow callers to avoid\n    /// expensive computation of log message arguments if the message would be\n    /// discarded anyway.\n    ///\n    /// # For implementors\n    ///\n    /// This method isn't called automatically by the `log!` macros.\n    /// It's up to an implementation of the `Log` trait to call `enabled` in its own\n    /// `log` method implementation to guarantee that filtering is applied.\n    fn enabled(&self, metadata: &Metadata) -> bool;\n\n    /// Logs the `Record`.\n    ///\n    /// # For implementors\n    ///\n    /// Note that `enabled` is *not* necessarily called before this method.\n    /// Implementations of `log` should perform all necessary filtering\n    /// internally.\n    fn log(&self, record: &Record);\n\n    /// Flushes any buffered records.\n    ///\n    /// # For implementors\n    ///\n    /// This method isn't called automatically by the `log!` macros.\n    /// It can be called manually on shut-down to ensure any in-flight records are flushed.\n    fn flush(&self);\n}\n\n/// A dummy initial value for LOGGER.\nstruct NopLogger;\n\nimpl Log for NopLogger {\n    fn enabled(&self, _: &Metadata) -> bool {\n        false\n    }\n\n    fn log(&self, _: &Record) {}\n    fn flush(&self) {}\n}\n\nimpl<T> Log for &'_ T\nwhere\n    T: ?Sized + Log,\n{\n    fn enabled(&self, metadata: &Metadata) -> bool {\n        (**self).enabled(metadata)\n    }\n\n    fn log(&self, record: &Record) {\n        (**self).log(record);\n    }\n    fn flush(&self) {\n        (**self).flush();\n    }\n}\n\n#[cfg(feature = \"alloc\")]\nimpl<T> Log for Box<T>\nwhere\n    T: ?Sized + Log,\n{\n    fn enabled(&self, metadata: &Metadata) -> bool {\n        self.as_ref().enabled(metadata)\n    }\n\n    fn log(&self, record: &Record) {\n        self.as_ref().log(record);\n    }\n    fn flush(&self) {\n        self.as_ref().flush();\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl<T> Log for std::sync::Arc<T>\nwhere\n    T: ?Sized + Log,\n{\n    fn enabled(&self, metadata: &Metadata) -> bool {\n        self.as_ref().enabled(metadata)\n    }\n\n    fn log(&self, record: &Record) {\n        self.as_ref().log(record);\n    }\n    fn flush(&self) {\n        self.as_ref().flush();\n    }\n}\n\n/// Sets the global maximum log level.\n///\n/// Generally, this should only be called by the active logging implementation.\n///\n/// Note that `Trace` is the maximum level, because it provides the maximum amount of detail in the emitted logs.\n#[inline]\n#[cfg(target_has_atomic = \"ptr\")]\npub fn set_max_level(level: LevelFilter) {\n    MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::Relaxed);\n}\n\n/// A thread-unsafe version of [`set_max_level`].\n///\n/// This function is available on all platforms, even those that do not have\n/// support for atomics that is needed by [`set_max_level`].\n///\n/// In almost all cases, [`set_max_level`] should be preferred.\n///\n/// # Safety\n///\n/// This function is only safe to call when it cannot race with any other\n/// calls to `set_max_level` or `set_max_level_racy`.\n///\n/// This can be upheld by (for example) making sure that **there are no other\n/// threads**, and (on embedded) that **interrupts are disabled**.\n///\n/// It is safe to use all other logging functions while this function runs\n/// (including all logging macros).\n///\n/// [`set_max_level`]: fn.set_max_level.html\n#[inline]\npub unsafe fn set_max_level_racy(level: LevelFilter) {\n    // `MAX_LOG_LEVEL_FILTER` uses a `Cell` as the underlying primitive when a\n    // platform doesn't support `target_has_atomic = \"ptr\"`, so even though this looks the same\n    // as `set_max_level` it may have different safety properties.\n    MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::Relaxed);\n}\n\n/// Returns the current maximum log level.\n///\n/// The [`log!`], [`error!`], [`warn!`], [`info!`], [`debug!`], and [`trace!`] macros check\n/// this value and discard any message logged at a higher level. The maximum\n/// log level is set by the [`set_max_level`] function.\n///\n/// [`log!`]: macro.log.html\n/// [`error!`]: macro.error.html\n/// [`warn!`]: macro.warn.html\n/// [`info!`]: macro.info.html\n/// [`debug!`]: macro.debug.html\n/// [`trace!`]: macro.trace.html\n/// [`set_max_level`]: fn.set_max_level.html\n#[inline(always)]\npub fn max_level() -> LevelFilter {\n    // Since `LevelFilter` is `repr(usize)`,\n    // this transmute is sound if and only if `MAX_LOG_LEVEL_FILTER`\n    // is set to a usize that is a valid discriminant for `LevelFilter`.\n    // Since `MAX_LOG_LEVEL_FILTER` is private, the only time it's set\n    // is by `set_max_level` above, i.e. by casting a `LevelFilter` to `usize`.\n    // So any usize stored in `MAX_LOG_LEVEL_FILTER` is a valid discriminant.\n    unsafe { mem::transmute(MAX_LOG_LEVEL_FILTER.load(Ordering::Relaxed)) }\n}\n\n/// Sets the global logger to a `Box<Log>`.\n///\n/// This is a simple convenience wrapper over `set_logger`, which takes a\n/// `Box<Log>` rather than a `&'static Log`. See the documentation for\n/// [`set_logger`] for more details.\n///\n/// Requires the `alloc` feature.\n///\n/// # Errors\n///\n/// An error is returned if a logger has already been set.\n///\n/// [`set_logger`]: fn.set_logger.html\n#[cfg(all(feature = \"alloc\", target_has_atomic = \"ptr\"))]\npub fn set_boxed_logger(logger: Box<dyn Log>) -> Result<(), SetLoggerError> {\n    set_logger_inner(|| Box::leak(logger))\n}\n\n/// Sets the global logger to a `&'static Log`.\n///\n/// This function may only be called once in the lifetime of a program. Any log\n/// events that occur before the call to `set_logger` completes will be ignored.\n///\n/// This function does not typically need to be called manually. Logger\n/// implementations should provide an initialization method that installs the\n/// logger internally.\n///\n/// # Availability\n///\n/// This method is available even when the `std` feature is disabled. However,\n/// it is currently unavailable on `thumbv6` targets, which lack support for\n/// some atomic operations which are used by this function. Even on those\n/// targets, [`set_logger_racy`] will be available.\n///\n/// # Errors\n///\n/// An error is returned if a logger has already been set.\n///\n/// # Examples\n///\n/// ```\n/// use log::{error, info, warn, Record, Level, Metadata, LevelFilter};\n///\n/// static MY_LOGGER: MyLogger = MyLogger;\n///\n/// struct MyLogger;\n///\n/// impl log::Log for MyLogger {\n///     fn enabled(&self, metadata: &Metadata) -> bool {\n///         metadata.level() <= Level::Info\n///     }\n///\n///     fn log(&self, record: &Record) {\n///         if self.enabled(record.metadata()) {\n///             println!(\"{} - {}\", record.level(), record.args());\n///         }\n///     }\n///     fn flush(&self) {}\n/// }\n///\n/// # fn main(){\n/// log::set_logger(&MY_LOGGER).unwrap();\n/// log::set_max_level(LevelFilter::Info);\n///\n/// info!(\"hello log\");\n/// warn!(\"warning\");\n/// error!(\"oops\");\n/// # }\n/// ```\n///\n/// [`set_logger_racy`]: fn.set_logger_racy.html\n#[cfg(target_has_atomic = \"ptr\")]\npub fn set_logger(logger: &'static dyn Log) -> Result<(), SetLoggerError> {\n    set_logger_inner(|| logger)\n}\n\n#[cfg(target_has_atomic = \"ptr\")]\nfn set_logger_inner<F>(make_logger: F) -> Result<(), SetLoggerError>\nwhere\n    F: FnOnce() -> &'static dyn Log,\n{\n    match STATE.compare_exchange(\n        UNINITIALIZED,\n        INITIALIZING,\n        Ordering::Acquire,\n        Ordering::Relaxed,\n    ) {\n        Ok(UNINITIALIZED) => {\n            unsafe {\n                LOGGER = make_logger();\n            }\n            STATE.store(INITIALIZED, Ordering::Release);\n            Ok(())\n        }\n        Err(INITIALIZING) => {\n            while STATE.load(Ordering::Relaxed) == INITIALIZING {\n                std::hint::spin_loop();\n            }\n            Err(SetLoggerError(()))\n        }\n        _ => Err(SetLoggerError(())),\n    }\n}\n\n/// A thread-unsafe version of [`set_logger`].\n///\n/// This function is available on all platforms, even those that do not have\n/// support for atomics that is needed by [`set_logger`].\n///\n/// In almost all cases, [`set_logger`] should be preferred.\n///\n/// # Safety\n///\n/// This function is only safe to call when it cannot race with any other\n/// calls to `set_logger` or `set_logger_racy`.\n///\n/// This can be upheld by (for example) making sure that **there are no other\n/// threads**, and (on embedded) that **interrupts are disabled**.\n///\n/// It is safe to use other logging functions while this function runs\n/// (including all logging macros).\n///\n/// [`set_logger`]: fn.set_logger.html\npub unsafe fn set_logger_racy(logger: &'static dyn Log) -> Result<(), SetLoggerError> {\n    match STATE.load(Ordering::Acquire) {\n        UNINITIALIZED => {\n            LOGGER = logger;\n            STATE.store(INITIALIZED, Ordering::Release);\n            Ok(())\n        }\n        INITIALIZING => {\n            // This is just plain UB, since we were racing another initialization function\n            unreachable!(\"set_logger_racy must not be used with other initialization functions\")\n        }\n        _ => Err(SetLoggerError(())),\n    }\n}\n\n/// The type returned by [`set_logger`] if [`set_logger`] has already been called.\n///\n/// [`set_logger`]: fn.set_logger.html\n#[allow(missing_copy_implementations)]\n#[derive(Debug)]\npub struct SetLoggerError(());\n\nimpl fmt::Display for SetLoggerError {\n    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {\n        fmt.write_str(SET_LOGGER_ERROR)\n    }\n}\n\n// The Error trait is not available in libcore\n#[cfg(feature = \"std\")]\nimpl error::Error for SetLoggerError {}\n\n/// The type returned by [`from_str`] when the string doesn't match any of the log levels.\n///\n/// [`from_str`]: https://doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str\n#[allow(missing_copy_implementations)]\n#[derive(Debug, PartialEq, Eq)]\npub struct ParseLevelError(());\n\nimpl fmt::Display for ParseLevelError {\n    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {\n        fmt.write_str(LEVEL_PARSE_ERROR)\n    }\n}\n\n// The Error trait is not available in libcore\n#[cfg(feature = \"std\")]\nimpl error::Error for ParseLevelError {}\n\n/// Returns a reference to the logger.\n///\n/// If a logger has not been set, a no-op implementation is returned.\npub fn logger() -> &'static dyn Log {\n    // Acquire memory ordering guarantees that current thread would see any\n    // memory writes that happened before store of the value\n    // into `STATE` with memory ordering `Release` or stronger.\n    //\n    // Since the value `INITIALIZED` is written only after `LOGGER` was\n    // initialized, observing it after `Acquire` load here makes both\n    // write to the `LOGGER` static and initialization of the logger\n    // internal state synchronized with current thread.\n    if STATE.load(Ordering::Acquire) != INITIALIZED {\n        static NOP: NopLogger = NopLogger;\n        &NOP\n    } else {\n        unsafe { LOGGER }\n    }\n}\n\n// WARNING: this is not part of the crate's public API and is subject to change at any time\n#[doc(hidden)]\npub mod __private_api;\n\n/// The statically resolved maximum log level.\n///\n/// See the crate level documentation for information on how to configure this.\n///\n/// This value is checked by the log macros, but not by the `Log`ger returned by\n/// the [`logger`] function. Code that manually calls functions on that value\n/// should compare the level against this value.\n///\n/// [`logger`]: fn.logger.html\npub const STATIC_MAX_LEVEL: LevelFilter = match cfg!(debug_assertions) {\n    false if cfg!(feature = \"release_max_level_off\") => LevelFilter::Off,\n    false if cfg!(feature = \"release_max_level_error\") => LevelFilter::Error,\n    false if cfg!(feature = \"release_max_level_warn\") => LevelFilter::Warn,\n    false if cfg!(feature = \"release_max_level_info\") => LevelFilter::Info,\n    false if cfg!(feature = \"release_max_level_debug\") => LevelFilter::Debug,\n    false if cfg!(feature = \"release_max_level_trace\") => LevelFilter::Trace,\n    _ if cfg!(feature = \"max_level_off\") => LevelFilter::Off,\n    _ if cfg!(feature = \"max_level_error\") => LevelFilter::Error,\n    _ if cfg!(feature = \"max_level_warn\") => LevelFilter::Warn,\n    _ if cfg!(feature = \"max_level_info\") => LevelFilter::Info,\n    _ if cfg!(feature = \"max_level_debug\") => LevelFilter::Debug,\n    _ => LevelFilter::Trace,\n};\n\n#[cfg(test)]\nmod tests {\n    use super::{Level, LevelFilter, ParseLevelError, STATIC_MAX_LEVEL};\n\n    #[test]\n    fn test_levelfilter_from_str() {\n        let tests = [\n            (\"off\", Ok(LevelFilter::Off)),\n            (\"error\", Ok(LevelFilter::Error)),\n            (\"warn\", Ok(LevelFilter::Warn)),\n            (\"info\", Ok(LevelFilter::Info)),\n            (\"debug\", Ok(LevelFilter::Debug)),\n            (\"trace\", Ok(LevelFilter::Trace)),\n            (\"OFF\", Ok(LevelFilter::Off)),\n            (\"ERROR\", Ok(LevelFilter::Error)),\n            (\"WARN\", Ok(LevelFilter::Warn)),\n            (\"INFO\", Ok(LevelFilter::Info)),\n            (\"DEBUG\", Ok(LevelFilter::Debug)),\n            (\"TRACE\", Ok(LevelFilter::Trace)),\n            (\"asdf\", Err(ParseLevelError(()))),\n        ];\n        for &(s, ref expected) in &tests {\n            assert_eq!(expected, &s.parse());\n        }\n    }\n\n    #[test]\n    fn test_level_from_str() {\n        let tests = [\n            (\"OFF\", Err(ParseLevelError(()))),\n            (\"error\", Ok(Level::Error)),\n            (\"warn\", Ok(Level::Warn)),\n            (\"info\", Ok(Level::Info)),\n            (\"debug\", Ok(Level::Debug)),\n            (\"trace\", Ok(Level::Trace)),\n            (\"ERROR\", Ok(Level::Error)),\n            (\"WARN\", Ok(Level::Warn)),\n            (\"INFO\", Ok(Level::Info)),\n            (\"DEBUG\", Ok(Level::Debug)),\n            (\"TRACE\", Ok(Level::Trace)),\n            (\"asdf\", Err(ParseLevelError(()))),\n        ];\n        for &(s, ref expected) in &tests {\n            assert_eq!(expected, &s.parse());\n        }\n    }\n\n    #[test]\n    fn test_level_as_str() {\n        let tests = &[\n            (Level::Error, \"ERROR\"),\n            (Level::Warn, \"WARN\"),\n            (Level::Info, \"INFO\"),\n            (Level::Debug, \"DEBUG\"),\n            (Level::Trace, \"TRACE\"),\n        ];\n        for (input, expected) in tests {\n            assert_eq!(*expected, input.as_str());\n        }\n    }\n\n    #[test]\n    fn test_level_show() {\n        assert_eq!(\"INFO\", Level::Info.to_string());\n        assert_eq!(\"ERROR\", Level::Error.to_string());\n    }\n\n    #[test]\n    fn test_levelfilter_show() {\n        assert_eq!(\"OFF\", LevelFilter::Off.to_string());\n        assert_eq!(\"ERROR\", LevelFilter::Error.to_string());\n    }\n\n    #[test]\n    fn test_cross_cmp() {\n        assert!(Level::Debug > LevelFilter::Error);\n        assert!(LevelFilter::Warn < Level::Trace);\n        assert!(LevelFilter::Off < Level::Error);\n    }\n\n    #[test]\n    fn test_cross_eq() {\n        assert!(Level::Error == LevelFilter::Error);\n        assert!(LevelFilter::Off != Level::Error);\n        assert!(Level::Trace == LevelFilter::Trace);\n    }\n\n    #[test]\n    fn test_to_level() {\n        assert_eq!(Some(Level::Error), LevelFilter::Error.to_level());\n        assert_eq!(None, LevelFilter::Off.to_level());\n        assert_eq!(Some(Level::Debug), LevelFilter::Debug.to_level());\n    }\n\n    #[test]\n    fn test_to_level_filter() {\n        assert_eq!(LevelFilter::Error, Level::Error.to_level_filter());\n        assert_eq!(LevelFilter::Trace, Level::Trace.to_level_filter());\n    }\n\n    #[test]\n    fn test_level_filter_as_str() {\n        let tests = &[\n            (LevelFilter::Off, \"OFF\"),\n            (LevelFilter::Error, \"ERROR\"),\n            (LevelFilter::Warn, \"WARN\"),\n            (LevelFilter::Info, \"INFO\"),\n            (LevelFilter::Debug, \"DEBUG\"),\n            (LevelFilter::Trace, \"TRACE\"),\n        ];\n        for (input, expected) in tests {\n            assert_eq!(*expected, input.as_str());\n        }\n    }\n\n    #[test]\n    fn test_level_up() {\n        let info = Level::Info;\n        let up = info.increment_severity();\n        assert_eq!(up, Level::Debug);\n\n        let trace = Level::Trace;\n        let up = trace.increment_severity();\n        // trace is already highest level\n        assert_eq!(up, trace);\n    }\n\n    #[test]\n    fn test_level_filter_up() {\n        let info = LevelFilter::Info;\n        let up = info.increment_severity();\n        assert_eq!(up, LevelFilter::Debug);\n\n        let trace = LevelFilter::Trace;\n        let up = trace.increment_severity();\n        // trace is already highest level\n        assert_eq!(up, trace);\n    }\n\n    #[test]\n    fn test_level_down() {\n        let info = Level::Info;\n        let down = info.decrement_severity();\n        assert_eq!(down, Level::Warn);\n\n        let error = Level::Error;\n        let down = error.decrement_severity();\n        // error is already lowest level\n        assert_eq!(down, error);\n    }\n\n    #[test]\n    fn test_level_filter_down() {\n        let info = LevelFilter::Info;\n        let down = info.decrement_severity();\n        assert_eq!(down, LevelFilter::Warn);\n\n        let error = LevelFilter::Error;\n        let down = error.decrement_severity();\n        assert_eq!(down, LevelFilter::Off);\n        // Off is already the lowest\n        assert_eq!(down.decrement_severity(), down);\n    }\n\n    #[test]\n    #[cfg_attr(not(debug_assertions), ignore)]\n    fn test_static_max_level_debug() {\n        if cfg!(feature = \"max_level_off\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Off);\n        } else if cfg!(feature = \"max_level_error\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Error);\n        } else if cfg!(feature = \"max_level_warn\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Warn);\n        } else if cfg!(feature = \"max_level_info\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Info);\n        } else if cfg!(feature = \"max_level_debug\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Debug);\n        } else {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Trace);\n        }\n    }\n\n    #[test]\n    #[cfg_attr(debug_assertions, ignore)]\n    fn test_static_max_level_release() {\n        if cfg!(feature = \"release_max_level_off\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Off);\n        } else if cfg!(feature = \"release_max_level_error\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Error);\n        } else if cfg!(feature = \"release_max_level_warn\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Warn);\n        } else if cfg!(feature = \"release_max_level_info\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Info);\n        } else if cfg!(feature = \"release_max_level_debug\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Debug);\n        } else if cfg!(feature = \"release_max_level_trace\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Trace);\n        } else if cfg!(feature = \"max_level_off\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Off);\n        } else if cfg!(feature = \"max_level_error\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Error);\n        } else if cfg!(feature = \"max_level_warn\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Warn);\n        } else if cfg!(feature = \"max_level_info\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Info);\n        } else if cfg!(feature = \"max_level_debug\") {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Debug);\n        } else {\n            assert_eq!(STATIC_MAX_LEVEL, LevelFilter::Trace);\n        }\n    }\n\n    #[test]\n    #[cfg(feature = \"std\")]\n    fn test_error_trait() {\n        use super::SetLoggerError;\n        let e = SetLoggerError(());\n        assert_eq!(\n            &e.to_string(),\n            \"attempted to set a logger after the logging system \\\n             was already initialized\"\n        );\n    }\n\n    #[test]\n    fn test_metadata_builder() {\n        use super::MetadataBuilder;\n        let target = \"myApp\";\n        let metadata_test = MetadataBuilder::new()\n            .level(Level::Debug)\n            .target(target)\n            .build();\n        assert_eq!(metadata_test.level(), Level::Debug);\n        assert_eq!(metadata_test.target(), \"myApp\");\n    }\n\n    #[test]\n    fn test_metadata_convenience_builder() {\n        use super::Metadata;\n        let target = \"myApp\";\n        let metadata_test = Metadata::builder()\n            .level(Level::Debug)\n            .target(target)\n            .build();\n        assert_eq!(metadata_test.level(), Level::Debug);\n        assert_eq!(metadata_test.target(), \"myApp\");\n    }\n\n    #[test]\n    fn test_record_builder() {\n        use super::{MetadataBuilder, RecordBuilder};\n        let target = \"myApp\";\n        let metadata = MetadataBuilder::new().target(target).build();\n        let fmt_args = format_args!(\"hello\");\n        let record_test = RecordBuilder::new()\n            .args(fmt_args)\n            .metadata(metadata)\n            .module_path(Some(\"foo\"))\n            .file(Some(\"bar\"))\n            .line(Some(30))\n            .build();\n        assert_eq!(record_test.metadata().target(), \"myApp\");\n        assert_eq!(record_test.module_path(), Some(\"foo\"));\n        assert_eq!(record_test.file(), Some(\"bar\"));\n        assert_eq!(record_test.line(), Some(30));\n    }\n\n    #[test]\n    fn test_record_convenience_builder() {\n        use super::{Metadata, Record};\n        let target = \"myApp\";\n        let metadata = Metadata::builder().target(target).build();\n        let fmt_args = format_args!(\"hello\");\n        let record_test = Record::builder()\n            .args(fmt_args)\n            .metadata(metadata)\n            .module_path(Some(\"foo\"))\n            .file(Some(\"bar\"))\n            .line(Some(30))\n            .build();\n        assert_eq!(record_test.target(), \"myApp\");\n        assert_eq!(record_test.module_path(), Some(\"foo\"));\n        assert_eq!(record_test.file(), Some(\"bar\"));\n        assert_eq!(record_test.line(), Some(30));\n    }\n\n    #[test]\n    fn test_record_complete_builder() {\n        use super::{Level, Record};\n        let target = \"myApp\";\n        let record_test = Record::builder()\n            .module_path(Some(\"foo\"))\n            .file(Some(\"bar\"))\n            .line(Some(30))\n            .target(target)\n            .level(Level::Error)\n            .build();\n        assert_eq!(record_test.target(), \"myApp\");\n        assert_eq!(record_test.level(), Level::Error);\n        assert_eq!(record_test.module_path(), Some(\"foo\"));\n        assert_eq!(record_test.file(), Some(\"bar\"));\n        assert_eq!(record_test.line(), Some(30));\n    }\n\n    #[test]\n    #[cfg(feature = \"kv\")]\n    fn test_record_key_values_builder() {\n        use super::Record;\n        use crate::kv::{self, VisitSource};\n\n        struct TestVisitSource {\n            seen_pairs: usize,\n        }\n\n        impl<'kvs> VisitSource<'kvs> for TestVisitSource {\n            fn visit_pair(\n                &mut self,\n                _: kv::Key<'kvs>,\n                _: kv::Value<'kvs>,\n            ) -> Result<(), kv::Error> {\n                self.seen_pairs += 1;\n                Ok(())\n            }\n        }\n\n        let kvs: &[(&str, i32)] = &[(\"a\", 1), (\"b\", 2)];\n        let record_test = Record::builder().key_values(&kvs).build();\n\n        let mut visitor = TestVisitSource { seen_pairs: 0 };\n\n        record_test.key_values().visit(&mut visitor).unwrap();\n\n        assert_eq!(2, visitor.seen_pairs);\n    }\n\n    #[test]\n    #[cfg(feature = \"kv\")]\n    fn test_record_key_values_get_coerce() {\n        use super::Record;\n\n        let kvs: &[(&str, &str)] = &[(\"a\", \"1\"), (\"b\", \"2\")];\n        let record = Record::builder().key_values(&kvs).build();\n\n        assert_eq!(\n            \"2\",\n            record\n                .key_values()\n                .get(\"b\".into())\n                .expect(\"missing key\")\n                .to_borrowed_str()\n                .expect(\"invalid value\")\n        );\n    }\n\n    // Test that the `impl Log for Foo` blocks work\n    // This test mostly operates on a type level, so failures will be compile errors\n    #[test]\n    fn test_foreign_impl() {\n        use super::Log;\n        #[cfg(feature = \"std\")]\n        use std::sync::Arc;\n\n        fn assert_is_log<T: Log + ?Sized>() {}\n\n        assert_is_log::<&dyn Log>();\n\n        #[cfg(feature = \"alloc\")]\n        assert_is_log::<Box<dyn Log>>();\n\n        #[cfg(feature = \"std\")]\n        assert_is_log::<Arc<dyn Log>>();\n\n        // Assert these statements for all T: Log + ?Sized\n        #[allow(unused)]\n        fn forall<T: Log + ?Sized>() {\n            #[cfg(feature = \"alloc\")]\n            assert_is_log::<Box<T>>();\n\n            assert_is_log::<&T>();\n\n            #[cfg(feature = \"std\")]\n            assert_is_log::<Arc<T>>();\n        }\n    }\n}\n"
    },
    {
      "package": "log@0.4.34",
      "sourcePath": "src/macros.rs",
      "sha256": "6917080cd9c4a2ca8128024f562a2bfdbbcd43616e41ef125289a30c6a9a4be2",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n/// The standard logging macro.\n///\n/// This macro will generically log with the specified `Level` and `format!`\n/// based argument list.\n///\n/// ```\n/// use log::{log, Level};\n///\n/// let data = (42, \"Forty-two\");\n/// let private_data = \"private\";\n///\n/// log!(Level::Error, \"Received errors: {}, {}\", data.0, data.1);\n/// ```\n///\n/// Optionally, you can specify a `target` argument to attach a specific target\n/// to the log record. By default, the target is the module path of the caller.\n///\n/// ```\n/// use log::{log, Level};\n///\n/// let data = (42, \"Forty-two\");\n/// let private_data = \"private\";\n///\n/// log!(\n///     target: \"app_events\",\n///     Level::Error,\n///     \"Received errors: {}, {}\",\n///     data.0, data.1\n/// );\n/// ```\n///\n/// And optionally, you can specify a `logger` argument to use a specific logger\n/// instead of the default global logger.\n///\n/// ```\n/// # struct MyLogger {}\n/// # impl Log for MyLogger {\n/// #     fn enabled(&self, _metadata: &log::Metadata) -> bool {\n/// #         false\n/// #     }\n/// #     fn log(&self, _record: &log::Record) {}\n/// #     fn flush(&self) {}\n/// # }\n/// use log::{log, Level, Log};\n///\n/// let data = (42, \"Forty-two\");\n/// let private_data = \"private\";\n///\n/// let my_logger = MyLogger {};\n/// log!(\n///     logger: my_logger,\n///     Level::Error,\n///     \"Received errors: {}, {}\",\n///     data.0, data.1\n/// );\n/// ```\n///\n/// The `logger` argument accepts a value that implements the `Log` trait. The value\n/// will be borrowed within the macro.\n///\n/// Note that the global level set via Cargo features or through `set_max_level` will\n/// still apply, even when a custom logger is supplied with the `logger` argument.\n#[macro_export]\n#[clippy::format_args]\nmacro_rules! log {\n    // log!(logger: my_logger, target: \"my_target\", Level::Info, \"a {} event\", \"log\");\n    (logger: $logger:expr, target: $target:expr, $lvl:expr, $($arg:tt)+) => ({\n        $crate::__log!(\n            logger: $crate::__log_logger!($logger),\n            target: $target,\n            $lvl,\n            $($arg)+\n        )\n    });\n\n    // log!(logger: my_logger, Level::Info, \"a log event\")\n    (logger: $logger:expr, $lvl:expr, $($arg:tt)+) => ({\n        $crate::__log!(\n            logger: $crate::__log_logger!($logger),\n            target: $crate::__private_api::module_path!(),\n            $lvl,\n            $($arg)+\n        )\n    });\n\n    // log!(target: \"my_target\", Level::Info, \"a log event\")\n    (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({\n        $crate::__log!(\n            logger: $crate::__log_logger!(__log_global_logger),\n            target: $target,\n            $lvl,\n            $($arg)+\n        )\n    });\n\n    // log!(Level::Info, \"a log event\")\n    ($lvl:expr, $($arg:tt)+) => ({\n        $crate::__log!(\n            logger: $crate::__log_logger!(__log_global_logger),\n            target: $crate::__private_api::module_path!(),\n            $lvl,\n            $($arg)+\n        )\n    });\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __log {\n    // log!(logger: my_logger, target: \"my_target\", Level::Info, key1:? = 42, key2 = true; \"a {} event\", \"log\");\n    (logger: $logger:expr, target: $target:expr, $lvl:expr, $($key:tt $(:$capture:tt)? $(= $value:expr)?),+; $($arg:tt)+) => ({\n        let lvl = $lvl;\n        if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() {\n            $crate::__private_api::log(\n                $logger,\n                $crate::__private_api::format_args!($($arg)+),\n                lvl,\n                &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),\n                &[$(($crate::__log_key!($key), $crate::__log_value!($key $(:$capture)* = $($value)*))),+] as &[_],\n            );\n        }\n    });\n\n    // log!(logger: my_logger, target: \"my_target\", Level::Info, \"a {} event\", \"log\");\n    (logger: $logger:expr, target: $target:expr, $lvl:expr, $($arg:tt)+) => ({\n        let lvl = $lvl;\n        if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() {\n            $crate::__private_api::log(\n                $logger,\n                $crate::__private_api::format_args!($($arg)+),\n                lvl,\n                &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),\n                (),\n            );\n        }\n    });\n}\n\n/// Logs a message at the error level.\n///\n/// # Examples\n///\n/// ```\n/// use log::error;\n///\n/// # let my_logger = log::__private_api::GlobalLogger;\n/// let (err_info, port) = (\"No connection\", 22);\n///\n/// error!(\"Error: {err_info} on port {port}\");\n/// error!(target: \"app_events\", \"App Error: {err_info}, Port: {port}\");\n/// error!(logger: my_logger, \"App Error: {err_info}, Port: {port}\");\n/// ```\n#[macro_export]\n#[clippy::format_args]\nmacro_rules! error {\n    // error!(logger: my_logger, target: \"my_target\", key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // error!(logger: my_logger, target: \"my_target\", \"a {} event\", \"log\")\n    (logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({\n        $crate::log!(logger: $crate::__log_logger!($logger), target: $target, $crate::Level::Error, $($arg)+)\n    });\n\n    // error!(logger: my_logger, key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // error!(logger: my_logger, \"a {} event\", \"log\")\n    (logger: $logger:expr, $($arg:tt)+) => ({\n        $crate::log!(logger: $crate::__log_logger!($logger), $crate::Level::Error, $($arg)+)\n    });\n\n    // error!(target: \"my_target\", key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // error!(target: \"my_target\", \"a {} event\", \"log\")\n    (target: $target:expr, $($arg:tt)+) => ({\n        $crate::log!(target: $target, $crate::Level::Error, $($arg)+)\n    });\n\n    // error!(\"a {} event\", \"log\")\n    ($($arg:tt)+) => ($crate::log!($crate::Level::Error, $($arg)+))\n}\n\n/// Logs a message at the warn level.\n///\n/// # Examples\n///\n/// ```\n/// use log::warn;\n///\n/// # let my_logger = log::__private_api::GlobalLogger;\n/// let warn_description = \"Invalid Input\";\n///\n/// warn!(\"Warning! {warn_description}!\");\n/// warn!(target: \"input_events\", \"App received warning: {warn_description}\");\n/// warn!(logger: my_logger, \"App received warning: {warn_description}\");\n/// ```\n#[macro_export]\n#[clippy::format_args]\nmacro_rules! warn {\n    // warn!(logger: my_logger, target: \"my_target\", key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // warn!(logger: my_logger, target: \"my_target\", \"a {} event\", \"log\")\n    (logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({\n        $crate::log!(logger: $crate::__log_logger!($logger), target: $target, $crate::Level::Warn, $($arg)+)\n    });\n\n    // warn!(logger: my_logger, key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // warn!(logger: my_logger, \"a {} event\", \"log\")\n    (logger: $logger:expr, $($arg:tt)+) => ({\n        $crate::log!(logger: $crate::__log_logger!($logger), $crate::Level::Warn, $($arg)+)\n    });\n\n    // warn!(target: \"my_target\", key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // warn!(target: \"my_target\", \"a {} event\", \"log\")\n    (target: $target:expr, $($arg:tt)+) => ({\n        $crate::log!(target: $target, $crate::Level::Warn, $($arg)+)\n    });\n\n    // warn!(\"a {} event\", \"log\")\n    ($($arg:tt)+) => ($crate::log!($crate::Level::Warn, $($arg)+))\n}\n\n/// Logs a message at the info level.\n///\n/// # Examples\n///\n/// ```\n/// use log::info;\n///\n/// # let my_logger = log::__private_api::GlobalLogger;\n/// # struct Connection { port: u32, speed: f32 }\n/// let conn_info = Connection { port: 40, speed: 3.20 };\n///\n/// info!(\"Connected to port {} at {} Mb/s\", conn_info.port, conn_info.speed);\n/// info!(\n///     target: \"connection_events\",\n///     \"Successful connection, port: {}, speed: {}\",\n///     conn_info.port, conn_info.speed\n/// );\n/// info!(\n///     logger: my_logger,\n///     \"Successful connection, port: {}, speed: {}\",\n///     conn_info.port, conn_info.speed\n/// );\n/// ```\n#[macro_export]\n#[clippy::format_args]\nmacro_rules! info {\n    // info!(logger: my_logger, target: \"my_target\", key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // info!(logger: my_logger, target: \"my_target\", \"a {} event\", \"log\")\n    (logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({\n        $crate::log!(logger: $crate::__log_logger!($logger), target: $target, $crate::Level::Info, $($arg)+)\n    });\n\n    // info!(logger: my_logger, key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // info!(logger: my_logger, \"a {} event\", \"log\")\n    (logger: $logger:expr, $($arg:tt)+) => ({\n        $crate::log!(logger: $crate::__log_logger!($logger), $crate::Level::Info, $($arg)+)\n    });\n\n    // info!(target: \"my_target\", key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // info!(target: \"my_target\", \"a {} event\", \"log\")\n    (target: $target:expr, $($arg:tt)+) => ({\n        $crate::log!(target: $target, $crate::Level::Info, $($arg)+)\n    });\n\n    // info!(\"a {} event\", \"log\")\n    ($($arg:tt)+) => ($crate::log!($crate::Level::Info, $($arg)+))\n}\n\n/// Logs a message at the debug level.\n///\n/// # Examples\n///\n/// ```\n/// use log::debug;\n///\n/// # let my_logger = log::__private_api::GlobalLogger;\n/// # struct Position { x: f32, y: f32 }\n/// let pos = Position { x: 3.234, y: -1.223 };\n///\n/// debug!(\"New position: x: {}, y: {}\", pos.x, pos.y);\n/// debug!(target: \"app_events\", \"New position: x: {}, y: {}\", pos.x, pos.y);\n/// debug!(logger: my_logger, \"New position: x: {}, y: {}\", pos.x, pos.y);\n/// ```\n#[macro_export]\n#[clippy::format_args]\nmacro_rules! debug {\n    // debug!(logger: my_logger, target: \"my_target\", key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // debug!(logger: my_logger, target: \"my_target\", \"a {} event\", \"log\")\n    (logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({\n        $crate::log!(logger: $crate::__log_logger!($logger), target: $target, $crate::Level::Debug, $($arg)+)\n    });\n\n    // debug!(logger: my_logger, key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // debug!(logger: my_logger, \"a {} event\", \"log\")\n    (logger: $logger:expr, $($arg:tt)+) => ({\n        $crate::log!(logger: $crate::__log_logger!($logger), $crate::Level::Debug, $($arg)+)\n    });\n\n    // debug!(target: \"my_target\", key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // debug!(target: \"my_target\", \"a {} event\", \"log\")\n    (target: $target:expr, $($arg:tt)+) => ({\n        $crate::log!(target: $target, $crate::Level::Debug, $($arg)+)\n    });\n\n    // debug!(\"a {} event\", \"log\")\n    ($($arg:tt)+) => ($crate::log!($crate::Level::Debug, $($arg)+))\n}\n\n/// Logs a message at the trace level.\n///\n/// # Examples\n///\n/// ```\n/// use log::trace;\n///\n/// # let my_logger = log::__private_api::GlobalLogger;\n/// # struct Position { x: f32, y: f32 }\n/// let pos = Position { x: 3.234, y: -1.223 };\n///\n/// trace!(\"Position is: x: {}, y: {}\", pos.x, pos.y);\n/// trace!(target: \"app_events\", \"x is {} and y is {}\",\n///        if pos.x >= 0.0 { \"positive\" } else { \"negative\" },\n///        if pos.y >= 0.0 { \"positive\" } else { \"negative\" });\n/// trace!(logger: my_logger, \"x is {} and y is {}\",\n///        if pos.x >= 0.0 { \"positive\" } else { \"negative\" },\n///        if pos.y >= 0.0 { \"positive\" } else { \"negative\" });\n/// ```\n#[macro_export]\n#[clippy::format_args]\nmacro_rules! trace {\n    // trace!(logger: my_logger, target: \"my_target\", key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // trace!(logger: my_logger, target: \"my_target\", \"a {} event\", \"log\")\n    (logger: $logger:expr, target: $target:expr, $($arg:tt)+) => ({\n        $crate::log!(logger: $crate::__log_logger!($logger), target: $target, $crate::Level::Trace, $($arg)+)\n    });\n\n    // trace!(logger: my_logger, key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // trace!(logger: my_logger, \"a {} event\", \"log\")\n    (logger: $logger:expr, $($arg:tt)+) => ({\n        $crate::log!(logger: $crate::__log_logger!($logger), $crate::Level::Trace, $($arg)+)\n    });\n\n    // trace!(target: \"my_target\", key1 = 42, key2 = true; \"a {} event\", \"log\")\n    // trace!(target: \"my_target\", \"a {} event\", \"log\")\n    (target: $target:expr, $($arg:tt)+) => ({\n        $crate::log!(target: $target, $crate::Level::Trace, $($arg)+)\n    });\n\n    // trace!(\"a {} event\", \"log\")\n    ($($arg:tt)+) => ($crate::log!($crate::Level::Trace, $($arg)+))\n}\n\n/// Determines if a message logged at the specified level in that module will\n/// be logged.\n///\n/// This can be used to avoid expensive computation of log message arguments if\n/// the message would be ignored anyway.\n///\n/// # Examples\n///\n/// ```\n/// use log::{debug, log_enabled, Level};\n///\n/// # struct Data { x: u32, y: u32 }\n/// # fn expensive_call() -> Data { Data { x: 0, y: 0 } }\n/// # let my_logger = log::__private_api::GlobalLogger;\n/// if log_enabled!(Level::Debug) {\n///     let data = expensive_call();\n///     debug!(\"expensive debug data: {} {}\", data.x, data.y);\n/// }\n///\n/// if log_enabled!(target: \"Global\", Level::Debug) {\n///    let data = expensive_call();\n///    debug!(target: \"Global\", \"expensive debug data: {} {}\", data.x, data.y);\n/// }\n///\n/// if log_enabled!(logger: my_logger, Level::Debug) {\n///    let data = expensive_call();\n///    debug!(target: \"Global\", \"expensive debug data: {} {}\", data.x, data.y);\n/// }\n/// ```\n///\n/// This macro accepts the same `target` and `logger` arguments as [`macro@log`].\n#[macro_export]\nmacro_rules! log_enabled {\n    // log_enabled!(logger: my_logger, target: \"my_target\", Level::Info)\n    (logger: $logger:expr, target: $target:expr, $lvl:expr) => ({\n        $crate::__log_enabled!(logger: $crate::__log_logger!($logger), target: $target, $lvl)\n    });\n\n    // log_enabled!(logger: my_logger, Level::Info)\n    (logger: $logger:expr, $lvl:expr) => ({\n        $crate::__log_enabled!(logger: $crate::__log_logger!($logger), target: $crate::__private_api::module_path!(), $lvl)\n    });\n\n    // log_enabled!(target: \"my_target\", Level::Info)\n    (target: $target:expr, $lvl:expr) => ({\n        $crate::__log_enabled!(logger: $crate::__log_logger!(__log_global_logger), target: $target, $lvl)\n    });\n\n    // log_enabled!(Level::Info)\n    ($lvl:expr) => ({\n        $crate::__log_enabled!(logger: $crate::__log_logger!(__log_global_logger), target: $crate::__private_api::module_path!(), $lvl)\n    });\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __log_enabled {\n    // log_enabled!(logger: my_logger, target: \"my_target\", Level::Info)\n    (logger: $logger:expr, target: $target:expr, $lvl:expr) => {{\n        let lvl = $lvl;\n        lvl <= $crate::STATIC_MAX_LEVEL\n            && lvl <= $crate::max_level()\n            && $crate::__private_api::enabled($logger, lvl, $target)\n    }};\n}\n\n// Determine the logger to use, and whether to take it by-value or by reference\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __log_logger {\n    (__log_global_logger) => {{\n        $crate::__private_api::GlobalLogger\n    }};\n\n    ($logger:expr) => {{\n        &($logger)\n    }};\n}\n\n// These macros use a pattern of #[cfg]s to produce nicer error\n// messages when log features aren't available\n\n#[doc(hidden)]\n#[macro_export]\n#[cfg(feature = \"kv\")]\nmacro_rules! __log_key {\n    // key1 = 42\n    ($args:ident) => {\n        $crate::__private_api::Key::from_str_static($crate::__private_api::stringify!($args))\n    };\n    // \"key1\" = 42\n    ($args:literal) => {\n        $crate::__private_api::Key::from_str_static($args)\n    };\n    // key = 42, where key is an expression\n    ($args:expr) => {\n        $crate::__private_api::Key::from_str($args)\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\n#[cfg(not(feature = \"kv\"))]\nmacro_rules! __log_key {\n    ($($args:tt)*) => {\n        compile_error!(\"key value support requires the `kv` feature of `log`\")\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\n#[cfg(feature = \"kv\")]\nmacro_rules! __log_value {\n    // Entrypoint\n    ($key:tt = $args:expr) => {\n        $crate::__log_value!(($args):value)\n    };\n    ($key:tt :$capture:tt = $args:expr) => {\n        $crate::__log_value!(($args):$capture)\n    };\n    ($key:ident =) => {\n        $crate::__log_value!(($key):value)\n    };\n    ($key:ident :$capture:tt =) => {\n        $crate::__log_value!(($key):$capture)\n    };\n    // ToValue\n    (($args:expr):value) => {\n        $crate::__private_api::capture_to_value(&&$args)\n    };\n    // Debug\n    (($args:expr):?) => {\n        $crate::__private_api::capture_debug(&&$args)\n    };\n    (($args:expr):debug) => {\n        $crate::__private_api::capture_debug(&&$args)\n    };\n    // Display\n    (($args:expr):%) => {\n        $crate::__private_api::capture_display(&&$args)\n    };\n    (($args:expr):display) => {\n        $crate::__private_api::capture_display(&&$args)\n    };\n    //Error\n    (($args:expr):err) => {\n        $crate::__log_value_error!($args)\n    };\n    // sval::Value\n    (($args:expr):sval) => {\n        $crate::__log_value_sval!($args)\n    };\n    // serde::Serialize\n    (($args:expr):serde) => {\n        $crate::__log_value_serde!($args)\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\n#[cfg(not(feature = \"kv\"))]\nmacro_rules! __log_value {\n    ($($args:tt)*) => {\n        compile_error!(\"key value support requires the `kv` feature of `log`\")\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\n#[cfg(feature = \"kv_sval\")]\nmacro_rules! __log_value_sval {\n    ($args:expr) => {\n        $crate::__private_api::capture_sval(&&$args)\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\n#[cfg(not(feature = \"kv_sval\"))]\nmacro_rules! __log_value_sval {\n    ($args:expr) => {\n        compile_error!(\"capturing values as `sval::Value` requires the `kv_sval` feature of `log`\")\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\n#[cfg(feature = \"kv_serde\")]\nmacro_rules! __log_value_serde {\n    ($args:expr) => {\n        $crate::__private_api::capture_serde(&&$args)\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\n#[cfg(not(feature = \"kv_serde\"))]\nmacro_rules! __log_value_serde {\n    ($args:expr) => {\n        compile_error!(\n            \"capturing values as `serde::Serialize` requires the `kv_serde` feature of `log`\"\n        )\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\n#[cfg(feature = \"kv_std\")]\nmacro_rules! __log_value_error {\n    ($args:expr) => {\n        $crate::__private_api::capture_error(&$args)\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\n#[cfg(not(feature = \"kv_std\"))]\nmacro_rules! __log_value_error {\n    ($args:expr) => {\n        compile_error!(\n            \"capturing values as `std::error::Error` requires the `kv_std` feature of `log`\"\n        )\n    };\n}\n"
    },
    {
      "package": "memchr@2.8.3",
      "sourcePath": "README.md",
      "sha256": "92a74aaffe011bdaa06fbc34a01686a6eba58ca1322e976759417a547fddf734",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "memchr\n======\nThis library provides heavily optimized routines for string search primitives.\n\n[![Build status](https://github.com/BurntSushi/memchr/workflows/ci/badge.svg)](https://github.com/BurntSushi/memchr/actions)\n[![Crates.io](https://img.shields.io/crates/v/memchr.svg)](https://crates.io/crates/memchr)\n\nDual-licensed under MIT or the [UNLICENSE](https://unlicense.org/).\n\n\n### Documentation\n\n[https://docs.rs/memchr](https://docs.rs/memchr)\n\n\n### Overview\n\n* The top-level module provides routines for searching for 1, 2 or 3 bytes\n  in the forward or reverse direction. When searching for more than one byte,\n  positions are considered a match if the byte at that position matches any\n  of the bytes.\n* The `memmem` sub-module provides forward and reverse substring search\n  routines.\n\nIn all such cases, routines operate on `&[u8]` without regard to encoding. This\nis exactly what you want when searching either UTF-8 or arbitrary bytes.\n\n### Compiling without the standard library\n\nmemchr links to the standard library by default, but you can disable the\n`std` feature if you want to use it in a `#![no_std]` crate:\n\n```toml\n[dependencies]\nmemchr = { version = \"2\", default-features = false }\n```\n\nOn `x86_64` platforms, when the `std` feature is disabled, the SSE2 accelerated\nimplementations will be used. When `std` is enabled, AVX2 accelerated\nimplementations will be used if the CPU is determined to support it at runtime.\n\nSIMD accelerated routines are also available on the `wasm32` and `aarch64`\ntargets. The `std` feature is not required to use them.\n\nWhen a SIMD version is not available, then this crate falls back to\n[SWAR](https://en.wikipedia.org/wiki/SWAR) techniques.\n\n### Minimum Rust version policy\n\nThis crate's minimum supported `rustc` version is `1.61.0`.\n\nThe current policy is that the minimum Rust version required to use this crate\ncan be increased in minor version updates. For example, if `crate 1.0` requires\nRust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust\n1.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum\nversion of Rust.\n\nIn general, this crate will be conservative with respect to the minimum\nsupported version of Rust.\n\n\n### Testing strategy\n\nGiven the complexity of the code in this crate, along with the pervasive use\nof `unsafe`, this crate has an extensive testing strategy. It combines multiple\napproaches:\n\n* Hand-written tests.\n* Exhaustive-style testing meant to exercise all possible branching and offset\n  calculations.\n* Property based testing through [`quickcheck`](https://github.com/BurntSushi/quickcheck).\n* Fuzz testing through [`cargo fuzz`](https://github.com/rust-fuzz/cargo-fuzz).\n* A huge suite of benchmarks that are also run as tests. Benchmarks always\n  confirm that the expected result occurs.\n\nImprovements to the testing infrastructure are very welcome.\n\n\n### Algorithms used\n\nAt time of writing, this crate's implementation of substring search actually\nhas a few different algorithms to choose from depending on the situation.\n\n* For very small haystacks,\n  [Rabin-Karp](https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm)\n  is used to reduce latency. Rabin-Karp has very small overhead and can often\n  complete before other searchers have even been constructed.\n* For small needles, a variant of the\n  [\"Generic SIMD\"](http://0x80.pl/articles/simd-strfind.html#algorithm-1-generic-simd)\n  algorithm is used. Instead of using the first and last bytes, a heuristic is\n  used to select bytes based on a background distribution of byte frequencies.\n* In all other cases,\n  [Two-Way](https://en.wikipedia.org/wiki/Two-way_string-matching_algorithm)\n  is used. If possible, a prefilter based on the \"Generic SIMD\" algorithm\n  linked above is used to find candidates quickly. A dynamic heuristic is used\n  to detect if the prefilter is ineffective, and if so, disables it.\n\n\n### Why is the standard library's substring search so much slower?\n\nWe'll start by establishing what the difference in performance actually\nis. There are two relevant benchmark classes to consider: `prebuilt` and\n`oneshot`. The `prebuilt` benchmarks are designed to measure---to the extent\npossible---search time only. That is, the benchmark first starts by building a\nsearcher and then only tracking the time for _using_ the searcher:\n\n```\n$ rebar rank benchmarks/record/x86_64/2023-08-26.csv --intersection -e memchr/memmem/prebuilt -e std/memmem/prebuilt\nEngine                       Version                   Geometric mean of speed ratios  Benchmark count\n------                       -------                   ------------------------------  ---------------\nrust/memchr/memmem/prebuilt  2.5.0                     1.03                            53\nrust/std/memmem/prebuilt     1.73.0-nightly 180dffba1  6.50                            53\n```\n\nConversely, the `oneshot` benchmark class measures the time it takes to both\nbuild the searcher _and_ use it:\n\n```\n$ rebar rank benchmarks/record/x86_64/2023-08-26.csv --intersection -e memchr/memmem/oneshot -e std/memmem/oneshot\nEngine                      Version                   Geometric mean of speed ratios  Benchmark count\n------                      -------                   ------------------------------  ---------------\nrust/memchr/memmem/oneshot  2.5.0                     1.04                            53\nrust/std/memmem/oneshot     1.73.0-nightly 180dffba1  5.26                            53\n```\n\n**NOTE:** Replace `rebar rank` with `rebar cmp` in the above commands to\nexplore the specific benchmarks and their differences.\n\nSo in both cases, this crate is quite a bit faster over a broad sampling of\nbenchmarks regardless of whether you measure only search time or search time\nplus construction time. The difference is a little smaller when you include\nconstruction time in your measurements.\n\nThese two different types of benchmark classes make for a nice segue into\none reason why the standard library's substring search can be slower: API\ndesign. In the standard library, the only APIs available to you require\none to re-construct the searcher for every search. While you can benefit\nfrom building a searcher once and iterating over all matches in a single\nstring, you cannot reuse that searcher to search other strings. This might\ncome up when, for example, searching a file one line at a time. You'll need\nto re-build the searcher for every line searched, and this can [really\nmatter][burntsushi-bstr-blog].\n\n**NOTE:** The `prebuilt` benchmark for the standard library can't actually\navoid measuring searcher construction at some level, because there is no API\nfor it. Instead, the benchmark consists of building the searcher once and then\nfinding all matches in a single string via an iterator. This tends to\napproximate a benchmark where searcher construction isn't measured, but it\nisn't perfect. While this means the comparison is not strictly\napples-to-apples, it does reflect what is maximally possible with the standard\nlibrary, and thus reflects the best that one could do in a real world scenario.\n\nWhile there is more to the story than just API design here, it's important to\npoint out that even if the standard library's substring search were a precise\nclone of this crate internally, it would still be at a disadvantage in some\nworkloads because of its API. (The same also applies to C's standard library\n`memmem` function. There is no way to amortize construction of the searcher.\nYou need to pay for it on every call.)\n\nThe other reason for the difference in performance is that\nthe standard library has trouble using SIMD. In particular, substring search\nis implemented in the `core` library, where platform specific code generally\ncan't exist. That's an issue because in order to utilize SIMD beyond SSE2\nwhile maintaining portable binaries, one needs to use [dynamic CPU feature\ndetection][dynamic-cpu], and that in turn requires platform specific code.\nWhile there is [an RFC for enabling target feature detection in\n`core`][core-feature], it doesn't yet exist.\n\nThe bottom line here is that `core`'s substring search implementation is\nlimited to making use of SSE2, but not AVX.\n\nStill though, this crate does accelerate substring search even when only SSE2\nis available. The standard library could therefore adopt the techniques in this\ncrate just for SSE2. The reason why that hasn't happened yet isn't totally\nclear to me. It likely needs a champion to push it through. The standard\nlibrary tends to be more conservative in these things. With that said, the\nstandard library does use some [SSE2 acceleration on `x86-64`][std-sse2] added\nin [this PR][std-sse2-pr]. However, at the time of writing, it is only used\nfor short needles and doesn't use the frequency based heuristics found in this\ncrate.\n\n**NOTE:** Another thing worth mentioning is that the standard library's\nsubstring search routine requires that both the needle and haystack have type\n`&str`. Unless you can assume that your data is valid UTF-8, building a `&str`\nwill come with the overhead of UTF-8 validation. This may in turn result in\noverall slower searching depending on your workload. In contrast, the `memchr`\ncrate permits both the needle and the haystack to have type `&[u8]`, where\n`&[u8]` can be created from a `&str` with zero cost. Therefore, the substring\nsearch in this crate is strictly more flexible than what the standard library\nprovides.\n\n[burntsushi-bstr-blog]: https://blog.burntsushi.net/bstr/#motivation-based-on-performance\n[dynamic-cpu]: https://doc.rust-lang.org/std/arch/index.html#dynamic-cpu-feature-detection\n[core-feature]: https://github.com/rust-lang/rfcs/pull/3469\n[std-sse2]: https://github.com/rust-lang/rust/blob/bf9229a2e366b4c311f059014a4aa08af16de5d8/library/core/src/str/pattern.rs#L1719-L1857\n[std-sse2-pr]: https://github.com/rust-lang/rust/pull/103779\n"
    },
    {
      "package": "mimalloc@0.1.52",
      "sourcePath": "LICENSE.txt",
      "sha256": "a08554fab028af3af047e8588d32d019662c1b1bf07959a195a2f75fe340726b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Copyright 2019 Octavian Oncescu\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the\nSoftware without restriction, including without\nlimitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software\nis furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice\nshall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\nSHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\nIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE."
    },
    {
      "package": "mimalloc@0.1.52",
      "sourcePath": "src/lib.rs",
      "sha256": "f2f6e98264507d5cfa836a48e5b0fe220f3bcc3270a8f5fabeb4297898a27201",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 Octavian Oncescu\n\n#![no_std]\n\n//! A drop-in global allocator wrapper around the [mimalloc](https://github.com/microsoft/mimalloc) allocator.\n//! Mimalloc is a general purpose, performance oriented allocator built by Microsoft.\n//!\n//! ## Usage\n//! ```rust,ignore\n//! use mimalloc::MiMalloc;\n//!\n//! #[global_allocator]\n//! static GLOBAL: MiMalloc = MiMalloc;\n//! ```\n//!\n//! ## Usage with secure mode\n//! Using secure mode adds guard pages,\n//! randomized allocation, encrypted free lists, etc. The performance penalty is usually\n//! around 10% according to [mimalloc's](https://github.com/microsoft/mimalloc)\n//! own benchmarks.\n//!\n//! To enable secure mode, put in `Cargo.toml`:\n//! ```toml\n//! [dependencies]\n//! mimalloc = { version = \"*\", features = [\"secure\"] }\n//! ```\n\nextern crate libmimalloc_sys as ffi;\n\n#[cfg(feature = \"extended\")]\nmod extended;\n\nuse core::alloc::{GlobalAlloc, Layout};\nuse core::ffi::c_void;\nuse ffi::*;\n\n/// Drop-in mimalloc global allocator.\n///\n/// ## Usage\n/// ```rust,ignore\n/// use mimalloc::MiMalloc;\n///\n/// #[global_allocator]\n/// static GLOBAL: MiMalloc = MiMalloc;\n/// ```\npub struct MiMalloc;\n\nunsafe impl GlobalAlloc for MiMalloc {\n    #[inline]\n    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {\n        mi_malloc_aligned(layout.size(), layout.align()) as *mut u8\n    }\n\n    #[inline]\n    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {\n        mi_zalloc_aligned(layout.size(), layout.align()) as *mut u8\n    }\n\n    #[inline]\n    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {\n        mi_free(ptr as *mut c_void);\n    }\n\n    #[inline]\n    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {\n        mi_realloc_aligned(ptr as *mut c_void, new_size, layout.align()) as *mut u8\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn it_frees_allocated_memory() {\n        unsafe {\n            let layout = Layout::from_size_align(8, 8).unwrap();\n            let alloc = MiMalloc;\n\n            let ptr = alloc.alloc(layout);\n            alloc.dealloc(ptr, layout);\n        }\n    }\n\n    #[test]\n    fn it_frees_allocated_big_memory() {\n        unsafe {\n            let layout = Layout::from_size_align(1 << 20, 32).unwrap();\n            let alloc = MiMalloc;\n\n            let ptr = alloc.alloc(layout);\n            alloc.dealloc(ptr, layout);\n        }\n    }\n\n    #[test]\n    fn it_frees_zero_allocated_memory() {\n        unsafe {\n            let layout = Layout::from_size_align(8, 8).unwrap();\n            let alloc = MiMalloc;\n\n            let ptr = alloc.alloc_zeroed(layout);\n            alloc.dealloc(ptr, layout);\n        }\n    }\n\n    #[test]\n    fn it_frees_zero_allocated_big_memory() {\n        unsafe {\n            let layout = Layout::from_size_align(1 << 20, 32).unwrap();\n            let alloc = MiMalloc;\n\n            let ptr = alloc.alloc_zeroed(layout);\n            alloc.dealloc(ptr, layout);\n        }\n    }\n\n    #[test]\n    fn it_frees_reallocated_memory() {\n        unsafe {\n            let layout = Layout::from_size_align(8, 8).unwrap();\n            let alloc = MiMalloc;\n\n            let ptr = alloc.alloc(layout);\n            let ptr = alloc.realloc(ptr, layout, 16);\n            alloc.dealloc(ptr, layout);\n        }\n    }\n\n    #[test]\n    fn it_frees_reallocated_big_memory() {\n        unsafe {\n            let layout = Layout::from_size_align(1 << 20, 32).unwrap();\n            let alloc = MiMalloc;\n\n            let ptr = alloc.alloc(layout);\n            let ptr = alloc.realloc(ptr, layout, 2 << 20);\n            alloc.dealloc(ptr, layout);\n        }\n    }\n}\n"
    },
    {
      "package": "miniz_oxide@0.5.4",
      "sourcePath": "LICENSE-APACHE.md",
      "sha256": "0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n"
    },
    {
      "package": "miniz_oxide@0.5.4",
      "sourcePath": "LICENSE-MIT.md",
      "sha256": "e190940e8ad3cdd4fca962a6508ed6865d589d314b1cb055f86000e124b88d8d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "MIT License\n\nCopyright (c) 2017 Frommi\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
    },
    {
      "package": "miniz_oxide@0.5.4",
      "sourcePath": "LICENSE-ZLIB.md",
      "sha256": "c89bcc058da12a0fb24402b8ea4542a21515dd1da2e8c67bba4ed9bd269f1c96",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Copyright (c) 2020 Frommi\n\nThis software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source distribution.\n"
    },
    {
      "package": "miniz_oxide@0.9.1",
      "sourcePath": "LICENSE-APACHE.md",
      "sha256": "0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n"
    },
    {
      "package": "miniz_oxide@0.9.1",
      "sourcePath": "LICENSE-MIT.md",
      "sha256": "799e9ca9d179295ef372f25d3769cdda7d25bb2668add6a6a1e22d1e4c678b8d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "MIT License\n\nCopyright 2013-2014 RAD Game Tools and Valve Software\nCopyright 2010-2014 Rich Geldreich and Tenacious Software LLC\nCopyright (c) 2017 Frommi\nCopyright (c) 2017-2024 oyvindln\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
    },
    {
      "package": "miniz_oxide@0.9.1",
      "sourcePath": "LICENSE-ZLIB.md",
      "sha256": "0a54e647fe54104658b5e563c04c6f9edf251710e47bce692e0bd990a4ddaa39",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Copyright 2013-2014 RAD Game Tools and Valve Software\nCopyright 2010-2014 Rich Geldreich and Tenacious Software LLC\nCopyright (c) 2020 Frommi\nCopyright (c) 2017-2024 oyvindln\n\nThis software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source distribution.\n"
    },
    {
      "package": "once_cell_polyfill@1.70.2",
      "sourcePath": "README.md",
      "sha256": "e37bd89789ba9f0624e3a9c06595d6f45f3c87bfc69c5a1a32af91cdbfd0b456",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# once_cell_polyfill\n\n> Polyfill for `OnceCell` stdlib feature for use with older MSRVs\n\n[![Documentation](https://img.shields.io/badge/docs-master-blue.svg)][Documentation]\n![License](https://img.shields.io/crates/l/once_cell_polyfill.svg)\n[![Crates Status](https://img.shields.io/crates/v/once_cell_polyfill.svg)][Crates.io]\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in the work by you, as defined in the Apache-2.0\nlicense, shall be dual-licensed as above, without any additional terms or\nconditions.\n\n[Crates.io]: https://crates.io/crates/once_cell_polyfill\n[Documentation]: https://docs.rs/once_cell_polyfill\n"
    },
    {
      "package": "paste@1.0.15",
      "sourcePath": "README.md",
      "sha256": "cd8f304fa9cca9566dff0bb3492beae55f47f3972ddfb8f1fa38c3da1068b4a8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Macros for all your token pasting needs\n=======================================\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/paste-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/paste)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/paste.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/paste)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-paste-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/paste)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/paste/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/paste/actions?query=branch%3Amaster)\n\nThe nightly-only [`concat_idents!`] macro in the Rust standard library is\nnotoriously underpowered in that its concatenated identifiers can only refer to\nexisting items, they can never be used to define something new.\n\n[`concat_idents!`]: https://doc.rust-lang.org/std/macro.concat_idents.html\n\nThis crate provides a flexible way to paste together identifiers in a macro,\nincluding using pasted identifiers to define new items.\n\n```toml\n[dependencies]\npaste = \"1.0\"\n```\n\nThis approach works with any Rust compiler 1.31+.\n\n<br>\n\n## Pasting identifiers\n\nWithin the `paste!` macro, identifiers inside `[<`...`>]` are pasted together to\nform a single identifier.\n\n```rust\nuse paste::paste;\n\npaste! {\n    // Defines a const called `QRST`.\n    const [<Q R S T>]: &str = \"success!\";\n}\n\nfn main() {\n    assert_eq!(\n        paste! { [<Q R S T>].len() },\n        8,\n    );\n}\n```\n\n<br>\n\n## More elaborate example\n\nThe next example shows a macro that generates accessor methods for some struct\nfields. It demonstrates how you might find it useful to bundle a paste\ninvocation inside of a macro\\_rules macro.\n\n```rust\nuse paste::paste;\n\nmacro_rules! make_a_struct_and_getters {\n    ($name:ident { $($field:ident),* }) => {\n        // Define a struct. This expands to:\n        //\n        //     pub struct S {\n        //         a: String,\n        //         b: String,\n        //         c: String,\n        //     }\n        pub struct $name {\n            $(\n                $field: String,\n            )*\n        }\n\n        // Build an impl block with getters. This expands to:\n        //\n        //     impl S {\n        //         pub fn get_a(&self) -> &str { &self.a }\n        //         pub fn get_b(&self) -> &str { &self.b }\n        //         pub fn get_c(&self) -> &str { &self.c }\n        //     }\n        paste! {\n            impl $name {\n                $(\n                    pub fn [<get_ $field>](&self) -> &str {\n                        &self.$field\n                    }\n                )*\n            }\n        }\n    }\n}\n\nmake_a_struct_and_getters!(S { a, b, c });\n\nfn call_some_getters(s: &S) -> bool {\n    s.get_a() == s.get_b() && s.get_c().is_empty()\n}\n```\n\n<br>\n\n## Case conversion\n\nUse `$var:lower` or `$var:upper` in the segment list to convert an interpolated\nsegment to lower- or uppercase as part of the paste. For example, `[<ld_\n$reg:lower _expr>]` would paste to `ld_bc_expr` if invoked with $reg=`Bc`.\n\nUse `$var:snake` to convert CamelCase input to snake\\_case.\nUse `$var:camel` to convert snake\\_case to CamelCase.\nThese compose, so for example `$var:snake:upper` would give you SCREAMING\\_CASE.\n\nThe precise Unicode conversions are as defined by [`str::to_lowercase`] and\n[`str::to_uppercase`].\n\n[`str::to_lowercase`]: https://doc.rust-lang.org/std/primitive.str.html#method.to_lowercase\n[`str::to_uppercase`]: https://doc.rust-lang.org/std/primitive.str.html#method.to_uppercase\n\n<br>\n\n## Pasting documentation strings\n\nWithin the `paste!` macro, arguments to a #\\[doc ...\\] attribute are implicitly\nconcatenated together to form a coherent documentation string.\n\n```rust\nuse paste::paste;\n\nmacro_rules! method_new {\n    ($ret:ident) => {\n        paste! {\n            #[doc = \"Create a new `\" $ret \"` object.\"]\n            pub fn new() -> $ret { todo!() }\n        }\n    };\n}\n\npub struct Paste {}\n\nmethod_new!(Paste);  // expands to #[doc = \"Create a new `Paste` object\"]\n```\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "pathfinder_color@0.5.0",
      "sourcePath": "src/lib.rs",
      "sha256": "211af4c221cb572c9b5c2bbaeae5ee63cf9ea840ce43d7dca85c222a1d38cadd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/color/src/lib.rs\n//\n// Copyright © 2020 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse pathfinder_simd::default::F32x4;\nuse std::f32::consts::PI;\nuse std::fmt::{self, Debug, Formatter};\nuse std::slice;\n\n// TODO(pcwalton): Maybe this should be a u32? Need to be aware of endianness issues if we do that.\n#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]\n#[repr(C)]\npub struct ColorU {\n    pub r: u8,\n    pub g: u8,\n    pub b: u8,\n    pub a: u8,\n}\n\nimpl ColorU {\n    #[inline]\n    pub fn new(r: u8, g: u8, b: u8, a: u8) -> ColorU {\n        ColorU { r, g, b, a }\n    }\n\n    #[inline]\n    pub fn transparent_black() -> ColorU {\n        ColorU::from_u32(0)\n    }\n\n    #[inline]\n    pub fn from_u32(rgba: u32) -> ColorU {\n        ColorU {\n            r: (rgba >> 24) as u8,\n            g: ((rgba >> 16) & 0xff) as u8,\n            b: ((rgba >> 8) & 0xff) as u8,\n            a: (rgba & 0xff) as u8,\n        }\n    }\n\n    #[inline]\n    pub fn black() -> ColorU {\n        ColorU {\n            r: 0,\n            g: 0,\n            b: 0,\n            a: 255,\n        }\n    }\n\n    #[inline]\n    pub fn white() -> ColorU {\n        ColorU {\n            r: 255,\n            g: 255,\n            b: 255,\n            a: 255,\n        }\n    }\n\n    #[inline]\n    pub fn to_f32(&self) -> ColorF {\n        let color = F32x4::new(self.r as f32, self.g as f32, self.b as f32, self.a as f32);\n        ColorF(color * F32x4::splat(1.0 / 255.0))\n    }\n\n    #[inline]\n    pub fn is_opaque(&self) -> bool {\n        self.a == !0\n    }\n\n    #[inline]\n    pub fn is_fully_transparent(&self) -> bool {\n        self.a == 0\n    }\n}\n\nimpl Debug for ColorU {\n    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {\n        if self.a == 255 {\n            write!(formatter, \"#{:02x}{:02x}{:02x}\", self.r, self.g, self.b)\n        } else {\n            write!(\n                formatter,\n                \"rgba({}, {}, {}, {})\",\n                self.r,\n                self.g,\n                self.b,\n                self.a as f32 / 255.0\n            )\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Default)]\npub struct ColorF(pub F32x4);\n\nimpl ColorF {\n    // Constructors\n\n    #[inline]\n    pub fn new(r: f32, g: f32, b: f32, a: f32) -> ColorF {\n        ColorF(F32x4::new(r, g, b, a))\n    }\n\n    #[inline]\n    pub fn from_hsla(mut h: f32, s: f32, l: f32, a: f32) -> ColorF {\n        // https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB\n\n        // Make sure hue is always positive.\n        h %= 2.0 * PI;\n        if h < 0.0 {\n            h += 2.0 * PI;\n        }\n\n        h *= 3.0 / PI;\n\n        // Calculate chroma.\n        let c = (1.0 - f32::abs(2.0 * l - 1.0)) * s;\n        let xc = F32x4::new(c * (1.0 - f32::abs(h % 2.0 - 1.0)), c, 0.0, a);\n        let rgba = match f32::ceil(h) as i32 {\n            1     => xc.yxzw(),\n            2     => xc.xyzw(),\n            3     => xc.zyxw(),\n            4     => xc.zxyw(),\n            5     => xc.xzyw(),\n            0 | 6 => xc.yzxw(),\n            _     => xc.zzzw(),\n        };\n        let m = l - 0.5 * c;\n        ColorF(rgba + F32x4::new(m, m, m, 0.0))\n    }\n\n    #[inline]\n    pub fn from_hsl(h: f32, s: f32, l: f32) -> ColorF {\n        ColorF::from_hsla(h, s, l, 1.0)\n    }\n\n    #[inline]\n    pub fn transparent_black() -> ColorF {\n        ColorF::default()\n    }\n\n    #[inline]\n    pub fn black() -> ColorF {\n        ColorF(F32x4::new(0.0, 0.0, 0.0, 1.0))\n    }\n\n    #[inline]\n    pub fn white() -> ColorF {\n        ColorF(F32x4::splat(1.0))\n    }\n\n    #[inline]\n    pub fn to_u8(&self) -> ColorU {\n        let color = (self.0 * F32x4::splat(255.0)).to_i32x4();\n        ColorU { r: color[0] as u8, g: color[1] as u8, b: color[2] as u8, a: color[3] as u8 }\n    }\n\n    #[inline]\n    pub fn lerp(&self, other: ColorF, t: f32) -> ColorF {\n        ColorF(self.0 + (other.0 - self.0) * F32x4::splat(t))\n    }\n\n    #[inline]\n    pub fn r(&self) -> f32 {\n        self.0[0]\n    }\n\n    #[inline]\n    pub fn g(&self) -> f32 {\n        self.0[1]\n    }\n\n    #[inline]\n    pub fn b(&self) -> f32 {\n        self.0[2]\n    }\n\n    #[inline]\n    pub fn a(&self) -> f32 {\n        self.0[3]\n    }\n\n    #[inline]\n    pub fn set_r(&mut self, r: f32) {\n        self.0[0] = r;\n    }\n\n    #[inline]\n    pub fn set_g(&mut self, g: f32) {\n        self.0[1] = g;\n    }\n\n    #[inline]\n    pub fn set_b(&mut self, b: f32) {\n        self.0[2] = b;\n    }\n\n    #[inline]\n    pub fn set_a(&mut self, a: f32) {\n        self.0[3] = a;\n    }\n}\n\nimpl Debug for ColorF {\n    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {\n        write!(\n            formatter,\n            \"rgba({}, {}, {}, {})\",\n            self.r() * 255.0,\n            self.g() * 255.0,\n            self.b() * 255.0,\n            self.a()\n        )\n    }\n}\n\n#[inline]\npub fn color_slice_to_u8_slice(slice: &[ColorU]) -> &[u8] {\n    unsafe {\n        slice::from_raw_parts(slice.as_ptr() as *const u8, slice.len() * 4)\n    }\n}\n\n#[inline]\npub fn u8_slice_to_color_slice(slice: &[u8]) -> &[ColorU] {\n    unsafe {\n        assert_eq!(slice.len() % 4, 0);\n        slice::from_raw_parts(slice.as_ptr() as *const ColorU, slice.len() / 4)\n    }\n}\n\n// TODO(pcwalton): Do this without a copy?\n#[inline]\npub fn u8_vec_to_color_vec(buffer: Vec<u8>) -> Vec<ColorU> {\n    u8_slice_to_color_slice(&buffer).to_vec()\n}\n\n/// A convenience method to construct a `ColorU` from an RGB triple.\n///\n/// Alpha is set to 255.\n#[inline]\npub fn rgbu(r: u8, g: u8, b: u8) -> ColorU {\n    ColorU::new(r, g, b, 255)\n}\n\n/// A convenience method to construct a `ColorU` from an RGBA triple.\n#[inline]\npub fn rgbau(r: u8, g: u8, b: u8, a: u8) -> ColorU {\n    ColorU::new(r, g, b, a)\n}\n\n/// A convenience method to construct a `ColorF` from an RGB triple.\n///\n/// Alpha is set to 1.0.\n#[inline]\npub fn rgbf(r: f32, g: f32, b: f32) -> ColorF {\n    ColorF::new(r, g, b, 1.0)\n}\n\n/// A convenience method to construct a `ColorF` from an RGBA triple.\n#[inline]\npub fn rgbaf(r: f32, g: f32, b: f32, a: f32) -> ColorF {\n    ColorF::new(r, g, b, a)\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/clip.rs",
      "sha256": "35deda1ded3a1f79ffb969742725d6cf61818af142cd0b8068af10a6d8efea87",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/clip.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::outline::{Contour, ContourIterFlags, PointFlags, PushSegmentFlags};\nuse crate::segment::{CubicSegment, Segment};\nuse arrayvec::ArrayVec;\nuse pathfinder_geometry::line_segment::LineSegment2F;\nuse pathfinder_geometry::rect::RectF;\nuse pathfinder_geometry::util::lerp;\nuse pathfinder_geometry::vector::{Vector2F, Vector4F};\nuse smallvec::SmallVec;\nuse std::fmt::Debug;\nuse std::mem;\n\n#[derive(Clone, Copy, Debug)]\nstruct Edge(LineSegment2F);\n\nimpl TEdge for Edge {\n    #[inline]\n    fn point_is_inside(&self, point: Vector2F) -> bool {\n        let area = (self.0.to() - self.0.from()).det(point - self.0.from());\n        debug!(\"point_is_inside({:?}, {:?}), area={}\", self, point, area);\n        area >= 0.0\n    }\n\n    fn intersect_line_segment(&self, segment: LineSegment2F) -> ArrayVec<[f32; 3]> {\n        let mut results = ArrayVec::new();\n        if let Some(t) = segment.intersection_t(self.0) {\n            if t >= 0.0 && t <= 1.0 {\n                results.push(t);\n            }\n        }\n        results\n    }\n}\n\n#[derive(Clone, Copy, Debug)]\nenum AxisAlignedEdge {\n    Left(f32),\n    Top(f32),\n    Right(f32),\n    Bottom(f32),\n}\n\nimpl TEdge for AxisAlignedEdge {\n    #[inline]\n    fn point_is_inside(&self, point: Vector2F) -> bool {\n        match *self {\n            AxisAlignedEdge::Left(x) => point.x() >= x,\n            AxisAlignedEdge::Top(y) => point.y() >= y,\n            AxisAlignedEdge::Right(x) => point.x() <= x,\n            AxisAlignedEdge::Bottom(y) => point.y() <= y,\n        }\n    }\n\n    fn intersect_line_segment(&self, segment: LineSegment2F) -> ArrayVec<[f32; 3]> {\n        let mut results = ArrayVec::new();\n        let t = match *self {\n            AxisAlignedEdge::Left(x) | AxisAlignedEdge::Right(x) => segment.solve_t_for_x(x),\n            AxisAlignedEdge::Top(y) | AxisAlignedEdge::Bottom(y) => segment.solve_t_for_y(y),\n        };\n        if t >= 0.0 && t <= 1.0 {\n            results.push(t);\n        }\n        results\n    }\n}\n\ntrait TEdge: Debug {\n    fn point_is_inside(&self, point: Vector2F) -> bool;\n    fn intersect_line_segment(&self, segment: LineSegment2F) -> ArrayVec<[f32; 3]>;\n\n    fn trivially_test_segment(&self, segment: &Segment) -> EdgeRelativeLocation {\n        let from_inside = self.point_is_inside(segment.baseline.from());\n        debug!(\n            \"point {:?} inside {:?}: {:?}\",\n            segment.baseline.from(),\n            self,\n            from_inside\n        );\n        if from_inside != self.point_is_inside(segment.baseline.to()) {\n            return EdgeRelativeLocation::Intersecting;\n        }\n        if !segment.is_line() {\n            if from_inside != self.point_is_inside(segment.ctrl.from()) {\n                return EdgeRelativeLocation::Intersecting;\n            }\n            if !segment.is_quadratic() {\n                if from_inside != self.point_is_inside(segment.ctrl.to()) {\n                    return EdgeRelativeLocation::Intersecting;\n                }\n            }\n        }\n        if from_inside {\n            EdgeRelativeLocation::Inside\n        } else {\n            EdgeRelativeLocation::Outside\n        }\n    }\n\n    fn intersect_segment(&self, segment: &Segment) -> ArrayVec<[f32; 3]> {\n        if segment.is_line() {\n            return self.intersect_line_segment(segment.baseline);\n        }\n\n        let mut segment = *segment;\n        if segment.is_quadratic() {\n            segment = segment.to_cubic();\n        }\n\n        let mut results = ArrayVec::new();\n        let mut prev_t = 0.0;\n        while !results.is_full() {\n            if prev_t >= 1.0 {\n                break;\n            }\n            let next_t = match self.intersect_cubic_segment(&segment, prev_t, 1.0) {\n                None => break,\n                Some(next_t) => next_t,\n            };\n            results.push(next_t);\n            prev_t = next_t + EPSILON;\n        }\n        return results;\n\n        const EPSILON: f32 = 0.0001;\n    }\n\n    fn intersect_cubic_segment(\n        &self,\n        segment: &Segment,\n        mut t_min: f32,\n        mut t_max: f32,\n    ) -> Option<f32> {\n        debug!(\n            \"... intersect_cubic_segment({:?}, {:?}, t=({}, {}))\",\n            self, segment, t_min, t_max\n        );\n\n        let mut segment = segment.as_cubic_segment().split_after(t_min);\n        segment = segment\n            .as_cubic_segment()\n            .split_before(t_max / (1.0 - t_min));\n\n        if !self.intersects_cubic_segment_hull(segment.as_cubic_segment()) {\n            return None;\n        }\n\n        loop {\n            let t_mid = lerp(t_min, t_max, 0.5);\n            if t_max - t_min < 0.00001 {\n                return Some(t_mid);\n            }\n\n            let (prev_segment, next_segment) = segment.as_cubic_segment().split(0.5);\n            if self.intersects_cubic_segment_hull(prev_segment.as_cubic_segment()) {\n                t_max = t_mid;\n                segment = prev_segment;\n            } else if self.intersects_cubic_segment_hull(next_segment.as_cubic_segment()) {\n                t_min = t_mid;\n                segment = next_segment;\n            } else {\n                return None;\n            }\n        }\n    }\n\n    fn intersects_cubic_segment_hull(&self, cubic_segment: CubicSegment) -> bool {\n        let inside = self.point_is_inside(cubic_segment.0.baseline.from());\n        inside != self.point_is_inside(cubic_segment.0.ctrl.from())\n            || inside != self.point_is_inside(cubic_segment.0.ctrl.to())\n            || inside != self.point_is_inside(cubic_segment.0.baseline.to())\n    }\n}\n\ntrait ContourClipper\nwhere\n    Self::Edge: TEdge + Debug,\n{\n    type Edge;\n\n    fn contour_mut(&mut self) -> &mut Contour;\n\n    fn clip_against(&mut self, edge: Self::Edge) {\n        // Fast path to avoid allocation in the no-clip case.\n        match self.check_for_fast_clip(&edge) {\n            FastClipResult::SlowPath => {}\n            FastClipResult::AllInside => return,\n            FastClipResult::AllOutside => {\n                *self.contour_mut() = Contour::new();\n                return;\n            }\n        }\n\n        let input = self.contour_mut().take();\n        for segment in input.iter(ContourIterFlags::empty()) {\n            self.clip_segment_against(segment, &edge);\n        }\n        if input.is_closed() {\n            self.contour_mut().close();\n        }\n    }\n\n    fn clip_segment_against(&mut self, mut segment: Segment, edge: &Self::Edge) {\n        // Easy cases.\n        match edge.trivially_test_segment(&segment) {\n            EdgeRelativeLocation::Outside => return,\n            EdgeRelativeLocation::Inside => {\n                debug!(\"trivial test inside, pushing segment\");\n                self.push_segment(&segment);\n                return;\n            }\n            EdgeRelativeLocation::Intersecting => {}\n        }\n\n        // We have a potential intersection.\n        debug!(\"potential intersection: {:?} edge: {:?}\", segment, edge);\n        let mut starts_inside = edge.point_is_inside(segment.baseline.from());\n        let intersection_ts = edge.intersect_segment(&segment);\n        let mut last_t = 0.0;\n        debug!(\"... intersections: {:?}\", intersection_ts);\n        for t in intersection_ts {\n            let (before_split, after_split) = segment.split((t - last_t) / (1.0 - last_t));\n\n            // Push the split segment if appropriate.\n            debug!(\n                \"... ... edge={:?} before_split={:?} t={:?} starts_inside={:?}\",\n                edge, before_split, t, starts_inside\n            );\n            if starts_inside {\n                debug!(\"... split segment case, pushing segment\");\n                self.push_segment(&before_split);\n            }\n\n            // We've now transitioned from inside to outside or vice versa.\n            starts_inside = !starts_inside;\n            last_t = t;\n            segment = after_split;\n        }\n\n        // No more intersections. Push the last segment if applicable.\n        if starts_inside {\n            debug!(\"... last segment case, pushing segment\");\n            self.push_segment(&segment);\n        }\n    }\n\n    fn push_segment(&mut self, segment: &Segment) {\n        let contour = self.contour_mut();\n        if let Some(last_position) = contour.last_position() {\n            if last_position != segment.baseline.from() {\n                // Add a line to join up segments.\n                contour.push_point(segment.baseline.from(), PointFlags::empty(), true);\n            }\n        }\n\n        contour.push_segment(segment, PushSegmentFlags::UPDATE_BOUNDS);\n    }\n\n    fn check_for_fast_clip(&mut self, edge: &Self::Edge) -> FastClipResult {\n        let mut result = None;\n        for segment in self.contour_mut().iter(ContourIterFlags::empty()) {\n            let location = edge.trivially_test_segment(&segment);\n            match (result, location) {\n                (None, EdgeRelativeLocation::Outside) => {\n                    result = Some(FastClipResult::AllOutside);\n                }\n                (None, EdgeRelativeLocation::Inside) => {\n                    result = Some(FastClipResult::AllInside);\n                }\n                (Some(FastClipResult::AllInside), EdgeRelativeLocation::Inside)\n                | (Some(FastClipResult::AllOutside), EdgeRelativeLocation::Outside) => {}\n                (_, _) => return FastClipResult::SlowPath,\n            }\n        }\n        result.unwrap_or(FastClipResult::AllOutside)\n    }\n}\n\n#[derive(Clone, Copy)]\nenum FastClipResult {\n    SlowPath,\n    AllInside,\n    AllOutside,\n}\n\n// General convex polygon clipping in 2D\n\npub(crate) struct ContourPolygonClipper {\n    clip_polygon: SmallVec<[Vector2F; 4]>,\n    contour: Contour,\n}\n\nimpl ContourClipper for ContourPolygonClipper {\n    type Edge = Edge;\n\n    #[inline]\n    fn contour_mut(&mut self) -> &mut Contour {\n        &mut self.contour\n    }\n}\n\nimpl ContourPolygonClipper {\n    #[inline]\n    pub(crate) fn new(clip_polygon: &[Vector2F], contour: Contour) -> ContourPolygonClipper {\n        ContourPolygonClipper {\n            clip_polygon: SmallVec::from_slice(clip_polygon),\n            contour,\n        }\n    }\n\n    pub(crate) fn clip(mut self) -> Contour {\n        // TODO(pcwalton): Maybe have a coarse circumscribed rect and use that for clipping?\n\n        let clip_polygon = mem::replace(&mut self.clip_polygon, SmallVec::default());\n        let mut prev = match clip_polygon.last() {\n            None => return Contour::new(),\n            Some(prev) => *prev,\n        };\n        for &next in &clip_polygon {\n            self.clip_against(Edge(LineSegment2F::new(prev, next)));\n            prev = next;\n        }\n\n        self.contour\n    }\n}\n\n#[derive(PartialEq)]\nenum EdgeRelativeLocation {\n    Intersecting,\n    Inside,\n    Outside,\n}\n\n// Fast axis-aligned box 2D clipping\n\npub(crate) struct ContourRectClipper {\n    clip_rect: RectF,\n    contour: Contour,\n}\n\nimpl ContourClipper for ContourRectClipper {\n    type Edge = AxisAlignedEdge;\n\n    #[inline]\n    fn contour_mut(&mut self) -> &mut Contour {\n        &mut self.contour\n    }\n}\n\nimpl ContourRectClipper {\n    #[inline]\n    pub(crate) fn new(clip_rect: RectF, contour: Contour) -> ContourRectClipper {\n        ContourRectClipper { clip_rect, contour }\n    }\n\n    pub(crate) fn clip(mut self) -> Contour {\n        if self.clip_rect.contains_rect(self.contour.bounds()) {\n            return self.contour;\n        }\n\n        self.clip_against(AxisAlignedEdge::Left(self.clip_rect.min_x()));\n        self.clip_against(AxisAlignedEdge::Top(self.clip_rect.min_y()));\n        self.clip_against(AxisAlignedEdge::Right(self.clip_rect.max_x()));\n        self.clip_against(AxisAlignedEdge::Bottom(self.clip_rect.max_y()));\n\n        self.contour\n    }\n}\n\n// 3D quad clipping\n\npub struct PolygonClipper3D {\n    subject: Vec<Vector4F>,\n}\n\nimpl PolygonClipper3D {\n    #[inline]\n    pub fn new(subject: Vec<Vector4F>) -> PolygonClipper3D {\n        PolygonClipper3D { subject }\n    }\n\n    pub fn clip(mut self) -> Vec<Vector4F> {\n        // TODO(pcwalton): Fast path for completely contained polygon?\n\n        debug!(\"before clipping against bottom: {:?}\", self.subject);\n        self.clip_against(Edge3D::Bottom);\n        debug!(\"before clipping against top: {:?}\", self.subject);\n        self.clip_against(Edge3D::Top);\n        debug!(\"before clipping against left: {:?}\", self.subject);\n        self.clip_against(Edge3D::Left);\n        debug!(\"before clipping against right: {:?}\", self.subject);\n        self.clip_against(Edge3D::Right);\n        debug!(\"before clipping against far: {:?}\", self.subject);\n        self.clip_against(Edge3D::Far);\n        debug!(\"before clipping against near: {:?}\", self.subject);\n        self.clip_against(Edge3D::Near);\n        debug!(\"after clipping: {:?}\", self.subject);\n\n        self.subject\n    }\n\n    fn clip_against(&mut self, edge: Edge3D) {\n        let input = mem::replace(&mut self.subject, vec![]);\n        let mut prev = match input.last() {\n            None => return,\n            Some(point) => *point,\n        };\n        for next in input {\n            if edge.point_is_inside(next) {\n                if !edge.point_is_inside(prev) {\n                    self.subject.push(edge.line_intersection(prev, next));\n                }\n                self.subject.push(next);\n            } else if edge.point_is_inside(prev) {\n                self.subject.push(edge.line_intersection(prev, next));\n            }\n            prev = next;\n        }\n    }\n}\n\n#[derive(Clone, Copy, Debug)]\nenum Edge3D {\n    Left,\n    Right,\n    Bottom,\n    Top,\n    Near,\n    Far,\n}\n\nimpl Edge3D {\n    #[inline]\n    fn point_is_inside(self, point: Vector4F) -> bool {\n        let w = point.w();\n        match self {\n            Edge3D::Left => point.x() >= -w,\n            Edge3D::Right => point.x() <= w,\n            Edge3D::Bottom => point.y() >= -w,\n            Edge3D::Top => point.y() <= w,\n            Edge3D::Near => point.z() >= -w,\n            Edge3D::Far => point.z() <= w,\n        }\n    }\n\n    // Blinn & Newell, \"Clipping using homogeneous coordinates\", SIGGRAPH 1978.\n    fn line_intersection(self, prev: Vector4F, next: Vector4F) -> Vector4F {\n        let (x0, x1) = match self {\n            Edge3D::Left | Edge3D::Right => (prev.x(), next.x()),\n            Edge3D::Bottom | Edge3D::Top => (prev.y(), next.y()),\n            Edge3D::Near | Edge3D::Far => (prev.z(), next.z()),\n        };\n        let (w0, w1) = (prev.w(), next.w());\n        let sign = match self {\n            Edge3D::Left | Edge3D::Bottom | Edge3D::Near => -1.0,\n            Edge3D::Right | Edge3D::Top | Edge3D::Far => 1.0,\n        };\n        let alpha = ((x0 - sign * w0) as f64) / ((sign * (w1 - w0) - (x1 - x0)) as f64);\n        prev.lerp(next, alpha as f32)\n    }\n}\n\n/// Coarse collision detection\n\n// Separating axis theorem. Requires that the polygon be convex.\npub(crate) fn rect_is_outside_polygon(rect: RectF, polygon_points: &[Vector2F]) -> bool {\n    let mut outcode = Outcode::all();\n    for point in polygon_points {\n        if point.x() > rect.min_x() {\n            outcode.remove(Outcode::LEFT);\n        }\n        if point.x() < rect.max_x() {\n            outcode.remove(Outcode::RIGHT);\n        }\n        if point.y() > rect.min_y() {\n            outcode.remove(Outcode::TOP);\n        }\n        if point.y() < rect.max_y() {\n            outcode.remove(Outcode::BOTTOM);\n        }\n    }\n    if !outcode.is_empty() {\n        return true;\n    }\n\n    // FIXME(pcwalton): Check winding!\n    let rect_points = [\n        rect.origin(),\n        rect.upper_right(),\n        rect.lower_left(),\n        rect.lower_right(),\n    ];\n    for (next_point_index, &next) in polygon_points.iter().enumerate() {\n        let prev_point_index = if next_point_index == 0 {\n            polygon_points.len() - 1\n        } else {\n            next_point_index - 1\n        };\n        let prev = polygon_points[prev_point_index];\n        let polygon_edge_vector = next - prev;\n        if rect_points\n            .iter()\n            .all(|&rect_point| polygon_edge_vector.det(rect_point - prev) < 0.0)\n        {\n            return true;\n        }\n    }\n\n    false\n}\n\n// Edge equation method. Requires that the polygon be convex.\npub(crate) fn rect_is_inside_polygon(rect: RectF, polygon_points: &[Vector2F]) -> bool {\n    // FIXME(pcwalton): Check winding!\n    let rect_points = [\n        rect.origin(),\n        rect.upper_right(),\n        rect.lower_left(),\n        rect.lower_right(),\n    ];\n    for (next_point_index, &next) in polygon_points.iter().enumerate() {\n        let prev_point_index = if next_point_index == 0 {\n            polygon_points.len() - 1\n        } else {\n            next_point_index - 1\n        };\n        let prev = polygon_points[prev_point_index];\n        let polygon_edge_vector = next - prev;\n        for &rect_point in &rect_points {\n            if polygon_edge_vector.det(rect_point - prev) < 0.0 {\n                return false;\n            }\n        }\n    }\n\n    true\n}\n\nbitflags! {\n    struct Outcode: u8 {\n        const LEFT   = 0x01;\n        const RIGHT  = 0x02;\n        const TOP    = 0x04;\n        const BOTTOM = 0x08;\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/dash.rs",
      "sha256": "1546525d73d08c01e0cf2074920fa0baa081ac89ac310a658dfba7174be5d61d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/dash.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Line dashing support.\n\nuse crate::outline::{Contour, ContourIterFlags, Outline, PushSegmentFlags};\nuse std::mem;\n\nconst EPSILON: f32 = 0.0001;\n\npub struct OutlineDash<'a> {\n    input: &'a Outline,\n    output: Outline,\n    state: DashState<'a>,\n}\n\nimpl<'a> OutlineDash<'a> {\n    #[inline]\n    pub fn new(input: &'a Outline, dashes: &'a [f32], offset: f32) -> OutlineDash<'a> {\n        OutlineDash { input, output: Outline::new(), state: DashState::new(dashes, offset) }\n    }\n\n    pub fn dash(&mut self) {\n        for contour in &self.input.contours {\n            ContourDash::new(contour, &mut self.output, &mut self.state).dash()\n        }\n    }\n\n    pub fn into_outline(mut self) -> Outline {\n        if self.state.is_on() {\n            self.output.push_contour(self.state.output);\n        }\n        self.output\n    }\n}\n\nstruct ContourDash<'a, 'b, 'c> {\n    input: &'a Contour,\n    output: &'b mut Outline,\n    state: &'c mut DashState<'a>,\n}\n\nimpl<'a, 'b, 'c> ContourDash<'a, 'b, 'c> {\n    fn new(input: &'a Contour, output: &'b mut Outline, state: &'c mut DashState<'a>)\n           -> ContourDash<'a, 'b, 'c> {\n        ContourDash { input, output, state }\n    }\n\n    fn dash(&mut self) {\n        let mut iterator = self.input.iter(ContourIterFlags::empty());\n        let mut queued_segment = None;\n        loop {\n            if queued_segment.is_none() {\n                match iterator.next() {\n                    None => break,\n                    Some(segment) => queued_segment = Some(segment),\n                }\n            }\n\n            let mut current_segment = queued_segment.take().unwrap();\n            let mut distance = self.state.distance_left;\n\n            let t = current_segment.time_for_distance(distance);\n            if t < 1.0 {\n                let (prev_segment, next_segment) = current_segment.split(t);\n                current_segment = prev_segment;\n                queued_segment = Some(next_segment);\n            } else {\n                distance = current_segment.arc_length();\n            }\n\n            if self.state.is_on() {\n                self.state.output.push_segment(&current_segment, PushSegmentFlags::empty());\n            }\n\n            self.state.distance_left -= distance;\n            if self.state.distance_left < EPSILON {\n                if self.state.is_on() {\n                    self.output.push_contour(mem::replace(&mut self.state.output, Contour::new()));\n                }\n\n                self.state.current_dash_index += 1;\n                if self.state.current_dash_index == self.state.dashes.len() {\n                    self.state.current_dash_index = 0;\n                }\n\n                self.state.distance_left = self.state.dashes[self.state.current_dash_index];\n            }\n        }\n    }\n}\n\nstruct DashState<'a> {\n    output: Contour,\n    dashes: &'a [f32],\n    current_dash_index: usize,\n    distance_left: f32,\n}\n\nimpl<'a> DashState<'a> {\n    fn new(dashes: &'a [f32], mut offset: f32) -> DashState<'a> {\n        let total: f32 = dashes.iter().cloned().sum();\n        offset %= total;\n\n        let mut current_dash_index = 0;\n        while current_dash_index < dashes.len() {\n            let dash = dashes[current_dash_index];\n            if offset < dash {\n                break;\n            }\n            offset -= dash;\n            current_dash_index += 1;\n        }\n\n        DashState {\n            output: Contour::new(),\n            dashes,\n            current_dash_index,\n            distance_left: offset,\n        }\n    }\n\n    #[inline]\n    fn is_on(&self) -> bool {\n        self.current_dash_index % 2 == 0\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/dilation.rs",
      "sha256": "6da19ab4af3a7c3298d5c97fa9a220e0b13f9a1ef27f9ee1b14f2bc38c5673c0",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/dilation.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::orientation::Orientation;\nuse crate::outline::Contour;\nuse pathfinder_geometry::vector::{Vector2F, vec2f};\n\npub struct ContourDilator<'a> {\n    contour: &'a mut Contour,\n    amount: Vector2F,\n    orientation: Orientation,\n}\n\nimpl<'a> ContourDilator<'a> {\n    pub fn new(\n        contour: &'a mut Contour,\n        amount: Vector2F,\n        orientation: Orientation,\n    ) -> ContourDilator<'a> {\n        ContourDilator {\n            contour,\n            amount,\n            orientation,\n        }\n    }\n\n    pub fn dilate(&mut self) {\n        // Determine orientation.\n        let scale = self.amount * (match self.orientation {\n            Orientation::Ccw => vec2f( 1.0, -1.0),\n            Orientation::Cw  => vec2f(-1.0,  1.0),\n        });\n\n        // Find the starting and previous positions.\n        let first_position = self.contour.position_of(0);\n        let mut prev_point_index = 0;\n        let mut prev_position;\n\n        loop {\n            prev_point_index = self.contour.prev_point_index_of(prev_point_index);\n            prev_position = self.contour.position_of(prev_point_index);\n            if prev_point_index == 0 || prev_position != first_position {\n                break;\n            }\n        }\n\n        // Initialize our loop.\n        let first_point_index = self.contour.next_point_index_of(prev_point_index);\n        let mut current_point_index = first_point_index;\n        let mut position = first_position;\n\n        let mut prev_vector = (position - prev_position).normalize();\n\n        loop {\n            // Find the next non-degenerate position.\n            let mut next_point_index = current_point_index;\n            let mut next_position;\n            loop {\n                next_point_index = self.contour.next_point_index_of(next_point_index);\n                if next_point_index == first_point_index {\n                    next_position = first_position;\n                    break;\n                }\n                next_position = self.contour.position_of(next_point_index);\n                if next_point_index == current_point_index || next_position != position {\n                    break;\n                }\n            }\n            let next_vector = (next_position - position).normalize();\n\n            debug!(\n                \"prev={} cur={} next={}\",\n                prev_point_index, current_point_index, next_point_index\n            );\n\n            // Calculate new position by moving the point by the bisector.\n            let bisector = prev_vector.yx() + next_vector.yx();\n            let bisector_length = bisector.length();\n            let scaled_bisector = if bisector_length == 0.0 {\n                Vector2F::zero()\n            } else {\n                bisector * scale * (1.0 / bisector_length)\n            };\n            let new_position = position - scaled_bisector;\n\n            debug!(\n                \"dilate(): prev={}({:?}) cur={}({:?}) next={}({:?}) bisector={:?}({:?}, {:?})\",\n                prev_point_index,\n                prev_position,\n                current_point_index,\n                position,\n                next_point_index,\n                next_position,\n                bisector,\n                bisector_length,\n                scaled_bisector\n            );\n\n            // Update all points.\n            let mut point_index = current_point_index;\n            while point_index != next_point_index {\n                self.contour.points[point_index as usize] = new_position;\n                debug!(\"... updating {:?}\", point_index);\n                point_index = self.contour.next_point_index_of(point_index);\n            }\n\n            // Check to see if we're done.\n            if next_point_index == first_point_index {\n                break;\n            }\n\n            // Continue.\n            prev_vector = next_vector;\n            position = next_position;\n            current_point_index = next_point_index;\n        }\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/effects.rs",
      "sha256": "3ddbee73eab09b742743081707c47a64e26d4fd28d484ff70a841f495f38d12c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/effects.rs\n//\n// Copyright © 2020 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Special effects that can be applied to layers.\n\nuse pathfinder_color::ColorF;\nuse pathfinder_geometry::line_segment::LineSegment2F;\nuse pathfinder_geometry::vector::Vector2F;\nuse pathfinder_simd::default::F32x2;\n\n/// This intentionally does not precisely match what Core Graphics does (a\n/// Lanczos function), because we don't want any ringing artefacts.\npub static DEFRINGING_KERNEL_CORE_GRAPHICS: DefringingKernel =\n    DefringingKernel([0.033165660, 0.102074051, 0.221434336, 0.286651906]);\npub static DEFRINGING_KERNEL_FREETYPE: DefringingKernel =\n    DefringingKernel([0.0, 0.031372549, 0.301960784, 0.337254902]);\n\n/// Should match macOS 10.13 High Sierra.\npub static STEM_DARKENING_FACTORS: [f32; 2] = [0.0121, 0.0121 * 1.25];\n\n/// Should match macOS 10.13 High Sierra.\npub const MAX_STEM_DARKENING_AMOUNT: [f32; 2] = [0.3, 0.3];\n\n/// This value is a subjective cutoff. Above this ppem value, no stem darkening is performed.\npub const MAX_STEM_DARKENING_PIXELS_PER_EM: f32 = 72.0;\n\n/// The shader that should be used when compositing this layer onto its destination.\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum Filter {\n    /// No special filter.\n    None,\n\n    /// Converts a linear gradient to a radial one.\n    RadialGradient {\n        /// The line that the circles lie along.\n        line: LineSegment2F,\n        /// The radii of the circles at the two endpoints.\n        radii: F32x2,\n        /// The origin of the linearized gradient in the texture.\n        uv_origin: Vector2F,\n    },\n\n    PatternFilter(PatternFilter),\n}\n\n/// Shaders applicable to patterns.\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum PatternFilter {\n    /// Performs postprocessing operations useful for monochrome text.\n    Text {\n        /// The foreground color of the text.\n        fg_color: ColorF,\n        /// The background color of the text.\n        bg_color: ColorF,\n        /// The kernel used for defringing, if subpixel AA is enabled.\n        defringing_kernel: Option<DefringingKernel>,\n        /// Whether gamma correction is used when compositing.\n        ///\n        /// If this is enabled, stem darkening is advised.\n        gamma_correction: bool,\n    },\n\n    /// A blur operation in one direction, either horizontal or vertical.\n    ///\n    /// To produce a full Gaussian blur, perform two successive blur operations, one in each\n    /// direction.\n    Blur {\n        direction: BlurDirection,\n        sigma: f32,\n    },\n}\n\n/// Blend modes that can be applied to individual paths.\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum BlendMode {\n    // Porter-Duff, supported by GPU blender\n    Clear,\n    Copy,\n    SrcIn,\n    SrcOut,\n    SrcOver,\n    SrcAtop,\n    DestIn,\n    DestOut,\n    DestOver,\n    DestAtop,\n    Xor,\n    Lighter,\n\n    // Others, unsupported by GPU blender\n    Darken,\n    Lighten,\n    Multiply,\n    Screen,\n    HardLight,\n    Overlay,\n    ColorDodge,\n    ColorBurn,\n    SoftLight,\n    Difference,\n    Exclusion,\n    Hue,\n    Saturation,\n    Color,\n    Luminosity,\n}\n\n#[derive(Clone, Copy, PartialEq, Debug)]\npub struct DefringingKernel(pub [f32; 4]);\n\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum BlurDirection {\n    X,\n    Y,\n}\n\nimpl Default for BlendMode {\n    #[inline]\n    fn default() -> BlendMode {\n        BlendMode::SrcOver\n    }\n}\n\nimpl Default for Filter {\n    #[inline]\n    fn default() -> Filter {\n        Filter::None\n    }\n}\n\nimpl BlendMode {\n    /// Whether the backdrop is irrelevant when applying this blend mode (i.e. destination blend\n    /// factor is zero when source alpha is one).\n    #[inline]\n    pub fn occludes_backdrop(self) -> bool {\n        match self {\n            BlendMode::SrcOver | BlendMode::Clear => true,\n            BlendMode::DestOver |\n            BlendMode::DestOut |\n            BlendMode::SrcAtop |\n            BlendMode::Xor |\n            BlendMode::Lighter |\n            BlendMode::Lighten |\n            BlendMode::Darken |\n            BlendMode::Copy |\n            BlendMode::SrcIn |\n            BlendMode::DestIn |\n            BlendMode::SrcOut |\n            BlendMode::DestAtop |\n            BlendMode::Multiply |\n            BlendMode::Screen |\n            BlendMode::HardLight |\n            BlendMode::Overlay |\n            BlendMode::ColorDodge |\n            BlendMode::ColorBurn |\n            BlendMode::SoftLight |\n            BlendMode::Difference |\n            BlendMode::Exclusion |\n            BlendMode::Hue |\n            BlendMode::Saturation |\n            BlendMode::Color |\n            BlendMode::Luminosity => false,\n        }\n    }\n\n    /// True if this blend mode does not preserve destination areas outside the source.\n    pub fn is_destructive(self) -> bool {\n        match self {\n            BlendMode::Clear |\n            BlendMode::Copy |\n            BlendMode::SrcIn |\n            BlendMode::DestIn |\n            BlendMode::SrcOut |\n            BlendMode::DestAtop => true,\n            BlendMode::SrcOver |\n            BlendMode::DestOver |\n            BlendMode::DestOut |\n            BlendMode::SrcAtop |\n            BlendMode::Xor |\n            BlendMode::Lighter |\n            BlendMode::Lighten |\n            BlendMode::Darken |\n            BlendMode::Multiply |\n            BlendMode::Screen |\n            BlendMode::HardLight |\n            BlendMode::Overlay |\n            BlendMode::ColorDodge |\n            BlendMode::ColorBurn |\n            BlendMode::SoftLight |\n            BlendMode::Difference |\n            BlendMode::Exclusion |\n            BlendMode::Hue |\n            BlendMode::Saturation |\n            BlendMode::Color |\n            BlendMode::Luminosity => false,\n        }\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/fill.rs",
      "sha256": "9deb3e9a5059b44baae99054c7c4e154287080f640e3e4529154af65fc40e3ee",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/fill.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Fill rules.\n\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum FillRule {\n    Winding,\n    EvenOdd,\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/gradient.rs",
      "sha256": "87c7a30bd20213b7e65f53e5e842bec6a9b58695516d295253aaa5468e1daf48",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/gradient.rs\n//\n// Copyright © 2020 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::sorted_vector::SortedVector;\nuse crate::util;\nuse pathfinder_color::ColorU;\nuse pathfinder_geometry::line_segment::LineSegment2F;\nuse pathfinder_geometry::vector::Vector2F;\nuse pathfinder_geometry::util as geometry_util;\nuse pathfinder_simd::default::F32x2;\nuse std::cmp::{Ordering, PartialOrd};\nuse std::convert;\nuse std::hash::{Hash, Hasher};\nuse std::mem;\n\n#[derive(Clone, PartialEq, Debug)]\npub struct Gradient {\n    /// The line this gradient runs along.\n    /// \n    /// If this is a radial gradient, this is the line that connects the two circles. It may have\n    /// zero-length in the case of simple radial gradients.\n    pub line: LineSegment2F,\n    /// For radial gradients, the radii of the start and endpoints respectively. If this is a\n    /// linear gradient, this is `None`.\n    pub radii: Option<F32x2>,\n    stops: SortedVector<ColorStop>,\n}\n\n#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]\npub struct ColorStop {\n    pub offset: f32,\n    pub color: ColorU,\n}\n\nimpl Eq for Gradient {}\n\nimpl Hash for Gradient {\n    fn hash<H>(&self, state: &mut H) where H: Hasher {\n        util::hash_line_segment(self.line, state);\n        match self.radii {\n            None => (0).hash(state),\n            Some(radii) => {\n                (1).hash(state);\n                util::hash_f32(radii.x(), state);\n                util::hash_f32(radii.y(), state);\n            }\n        }\n        self.stops.hash(state);\n    }\n}\n\nimpl Eq for ColorStop {}\n\nimpl Hash for ColorStop {\n    fn hash<H>(&self, state: &mut H) where H: Hasher {\n        unsafe {\n            self.color.hash(state);\n            let offset = mem::transmute::<f32, u32>(self.offset);\n            offset.hash(state);\n        }\n    }\n}\n\nimpl Gradient {\n    #[inline]\n    pub fn linear(line: LineSegment2F) -> Gradient {\n        Gradient { line, radii: None, stops: SortedVector::new() }\n    }\n\n    #[inline]\n    pub fn linear_from_points(from: Vector2F, to: Vector2F) -> Gradient {\n        Gradient::linear(LineSegment2F::new(from, to))\n    }\n\n    #[inline]\n    pub fn radial<L>(line: L, radii: F32x2) -> Gradient where L: RadialGradientLine {\n        Gradient { line: line.to_line(), radii: Some(radii), stops: SortedVector::new() }\n    }\n\n    #[inline]\n    pub fn add(&mut self, stop: ColorStop) {\n        self.stops.push(stop);\n    }\n\n    /// A convenience method to add a color stop.\n    #[inline]\n    pub fn add_color_stop(&mut self, color: ColorU, offset: f32) {\n        self.add(ColorStop::new(color, offset))\n    }\n\n    #[inline]\n    pub fn line(&self) -> LineSegment2F {\n        self.line\n    }\n\n    #[inline]\n    pub fn set_line(&mut self, line: LineSegment2F) {\n        self.line = line\n    }\n\n    #[inline]\n    pub fn radii(&self) -> Option<F32x2> {\n        self.radii\n    }\n\n    #[inline]\n    pub fn set_radii(&mut self, radii: Option<F32x2>) {\n        self.radii = radii\n    }\n\n    #[inline]\n    pub fn stops(&self) -> &[ColorStop] {\n        &self.stops.array\n    }\n\n    #[inline]\n    pub fn stops_mut(&mut self) -> &mut [ColorStop] {\n        &mut self.stops.array\n    }\n\n    pub fn sample(&self, mut t: f32) -> ColorU {\n        if self.stops.is_empty() {\n            return ColorU::transparent_black();\n        }\n\n        t = geometry_util::clamp(t, 0.0, 1.0);\n        let last_index = self.stops.len() - 1;\n        let upper_index = self.stops.binary_search_by(|stop| {\n            stop.offset.partial_cmp(&t).unwrap_or(Ordering::Less)\n        }).unwrap_or_else(convert::identity).min(last_index);\n        let lower_index = if upper_index > 0 { upper_index - 1 } else { upper_index };\n\n        let lower_stop = &self.stops.array[lower_index];\n        let upper_stop = &self.stops.array[upper_index];\n\n        let denom = upper_stop.offset - lower_stop.offset;\n        if denom == 0.0 {\n            return lower_stop.color;\n        }\n\n        lower_stop.color\n                  .to_f32()\n                  .lerp(upper_stop.color.to_f32(), (t - lower_stop.offset) / denom)\n                  .to_u8()\n    }\n\n    #[inline]\n    pub fn is_opaque(&self) -> bool {\n        self.stops.array.iter().all(|stop| stop.color.is_opaque())\n    }\n\n    #[inline]\n    pub fn is_fully_transparent(&self) -> bool {\n        self.stops.array.iter().all(|stop| stop.color.is_fully_transparent())\n    }\n}\n\nimpl ColorStop {\n    #[inline]\n    pub fn new(color: ColorU, offset: f32) -> ColorStop {\n        ColorStop { color, offset }\n    }\n}\n\npub trait RadialGradientLine {\n    fn to_line(self) -> LineSegment2F;\n}\n\nimpl RadialGradientLine for LineSegment2F {\n    #[inline]\n    fn to_line(self) -> LineSegment2F {\n        self\n    }\n}\n\nimpl RadialGradientLine for Vector2F {\n    #[inline]\n    fn to_line(self) -> LineSegment2F {\n        LineSegment2F::new(self, self)\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/lib.rs",
      "sha256": "a6d51f9a74c053d4fe73b21876363e26a109125dfd77dd4a53101789cf700fee",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/lib.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Pathfinder's representation of a vector scene.\n//!\n//! This module also contains various path utilities.\n\n#[macro_use]\nextern crate bitflags;\n#[macro_use]\nextern crate log;\n\npub mod clip;\npub mod dash;\npub mod effects;\npub mod fill;\npub mod gradient;\npub mod orientation;\npub mod outline;\npub mod pattern;\npub mod render_target;\npub mod segment;\npub mod sorted_vector;\npub mod stroke;\npub mod transform;\n\nmod dilation;\nmod util;\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/orientation.rs",
      "sha256": "cc5b896f47629ace0ff760b4b923fc616e63101528f65030d914297b4c44d044",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/geometry/src/orientation.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::outline::Outline;\n\n#[derive(Clone, Copy, Debug, PartialEq)]\npub enum Orientation {\n    Ccw = -1,\n    Cw = 1,\n}\n\nimpl Orientation {\n    /// This follows the FreeType algorithm.\n    pub fn from_outline(outline: &Outline) -> Orientation {\n        let mut area = 0.0;\n        for contour in &outline.contours {\n            let mut prev_position = match contour.last_position() {\n                None => continue,\n                Some(position) => position,\n            };\n            for &next_position in &contour.points {\n                area += prev_position.det(next_position);\n                prev_position = next_position;\n            }\n        }\n        Orientation::from_area(area)\n    }\n\n    fn from_area(area: f32) -> Orientation {\n        if area <= 0.0 {\n            Orientation::Ccw\n        } else {\n            Orientation::Cw\n        }\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/outline.rs",
      "sha256": "57eab3536a5a3a21fbb819342d3d6a1bf396d7da36de93e0db791aa3ae7665dc",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/outline.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! A compressed in-memory representation of paths.\n\nuse crate::clip::{self, ContourPolygonClipper, ContourRectClipper};\nuse crate::dilation::ContourDilator;\nuse crate::orientation::Orientation;\nuse crate::segment::{Segment, SegmentFlags, SegmentKind};\nuse pathfinder_geometry::line_segment::LineSegment2F;\nuse pathfinder_geometry::rect::RectF;\nuse pathfinder_geometry::transform2d::Transform2F;\nuse pathfinder_geometry::transform3d::Perspective;\nuse pathfinder_geometry::unit_vector::UnitVector;\nuse pathfinder_geometry::vector::{Vector2F, vec2f};\nuse std::f32::consts::PI;\nuse std::fmt::{self, Debug, Formatter};\nuse std::mem;\n\n#[derive(Clone)]\npub struct Outline {\n    pub(crate) contours: Vec<Contour>,\n    pub(crate) bounds: RectF,\n}\n\n#[derive(Clone)]\npub struct Contour {\n    pub(crate) points: Vec<Vector2F>,\n    pub(crate) flags: Vec<PointFlags>,\n    pub(crate) bounds: RectF,\n    pub(crate) closed: bool,\n}\n\nbitflags! {\n    pub struct PointFlags: u8 {\n        const CONTROL_POINT_0 = 0x01;\n        const CONTROL_POINT_1 = 0x02;\n    }\n}\n\nbitflags! {\n    pub struct PushSegmentFlags: u8 {\n        const UPDATE_BOUNDS = 0x01;\n        const INCLUDE_FROM_POINT = 0x02;\n    }\n}\n\nimpl Outline {\n    #[inline]\n    pub fn new() -> Outline {\n        Outline {\n            contours: vec![],\n            bounds: RectF::default(),\n        }\n    }\n\n    #[inline]\n    pub fn from_segments<I>(segments: I) -> Outline\n    where\n        I: Iterator<Item = Segment>,\n    {\n        let mut outline = Outline::new();\n        let mut current_contour = Contour::new();\n\n        for segment in segments {\n            if segment.flags.contains(SegmentFlags::FIRST_IN_SUBPATH) {\n                if !current_contour.is_empty() {\n                    outline\n                        .contours\n                        .push(mem::replace(&mut current_contour, Contour::new()));\n                }\n                current_contour.push_point(segment.baseline.from(), PointFlags::empty(), true);\n            }\n\n            if segment.flags.contains(SegmentFlags::CLOSES_SUBPATH) {\n                if !current_contour.is_empty() {\n                    current_contour.close();\n                    let contour = mem::replace(&mut current_contour, Contour::new());\n                    outline.push_contour(contour);\n                }\n                continue;\n            }\n\n            if segment.is_none() {\n                continue;\n            }\n\n            if !segment.is_line() {\n                current_contour.push_point(segment.ctrl.from(), PointFlags::CONTROL_POINT_0, true);\n                if !segment.is_quadratic() {\n                    current_contour.push_point(\n                        segment.ctrl.to(),\n                        PointFlags::CONTROL_POINT_1,\n                        true,\n                    );\n                }\n            }\n\n            current_contour.push_point(segment.baseline.to(), PointFlags::empty(), true);\n        }\n\n        outline.push_contour(current_contour);\n        outline\n    }\n\n    #[inline]\n    pub fn from_rect(rect: RectF) -> Outline {\n        let mut outline = Outline::new();\n        outline.push_contour(Contour::from_rect(rect));\n        outline\n    }\n\n    #[inline]\n    pub fn bounds(&self) -> RectF {\n        self.bounds\n    }\n\n    #[inline]\n    pub fn contours(&self) -> &[Contour] {\n        &self.contours\n    }\n\n    #[inline]\n    pub fn into_contours(self) -> Vec<Contour> {\n        self.contours\n    }\n\n    /// Removes all contours from this outline.\n    #[inline]\n    pub fn clear(&mut self) {\n        self.contours.clear();\n        self.bounds = RectF::default();\n    }\n\n    pub fn push_contour(&mut self, contour: Contour) {\n        if contour.is_empty() {\n            return;\n        }\n\n        if self.contours.is_empty() {\n            self.bounds = contour.bounds;\n        } else {\n            self.bounds = self.bounds.union_rect(contour.bounds);\n        }\n\n        self.contours.push(contour);\n    }\n\n    pub fn pop_contour(&mut self) -> Option<Contour> {\n        let last_contour = self.contours.pop();\n\n        let mut new_bounds = None;\n        for contour in &mut self.contours {\n            contour.update_bounds(&mut new_bounds);\n        }\n        self.bounds = new_bounds.unwrap_or_else(|| RectF::default());\n\n        last_contour\n    }\n\n    pub fn transform(&mut self, transform: &Transform2F) {\n        if transform.is_identity() {\n            return;\n        }\n\n        let mut new_bounds = None;\n        for contour in &mut self.contours {\n            contour.transform(transform);\n            contour.update_bounds(&mut new_bounds);\n        }\n        self.bounds = new_bounds.unwrap_or_else(|| RectF::default());\n    }\n\n    pub fn apply_perspective(&mut self, perspective: &Perspective) {\n        let mut new_bounds = None;\n        for contour in &mut self.contours {\n            contour.apply_perspective(perspective);\n            contour.update_bounds(&mut new_bounds);\n        }\n        self.bounds = new_bounds.unwrap_or_else(|| RectF::default());\n    }\n\n    pub fn dilate(&mut self, amount: Vector2F) {\n        let orientation = Orientation::from_outline(self);\n        self.contours\n            .iter_mut()\n            .for_each(|contour| contour.dilate(amount, orientation));\n        self.bounds = self.bounds.dilate(amount);\n    }\n\n    pub fn prepare_for_tiling(&mut self, view_box: RectF) {\n        self.contours\n            .iter_mut()\n            .for_each(|contour| contour.prepare_for_tiling(view_box));\n        self.bounds = self\n            .bounds\n            .intersection(view_box)\n            .unwrap_or_else(|| RectF::default());\n    }\n\n    pub fn is_outside_polygon(&self, clip_polygon: &[Vector2F]) -> bool {\n        clip::rect_is_outside_polygon(self.bounds, clip_polygon)\n    }\n\n    fn is_inside_polygon(&self, clip_polygon: &[Vector2F]) -> bool {\n        clip::rect_is_inside_polygon(self.bounds, clip_polygon)\n    }\n\n    pub fn clip_against_polygon(&mut self, clip_polygon: &[Vector2F]) {\n        // Quick check.\n        if self.is_inside_polygon(clip_polygon) {\n            return;\n        }\n\n        for contour in mem::replace(&mut self.contours, vec![]) {\n            self.push_contour(ContourPolygonClipper::new(clip_polygon, contour).clip());\n        }\n    }\n\n    pub fn clip_against_rect(&mut self, clip_rect: RectF) {\n        if clip_rect.contains_rect(self.bounds) {\n            return;\n        }\n\n        for contour in mem::replace(&mut self.contours, vec![]) {\n            self.push_contour(ContourRectClipper::new(clip_rect, contour).clip());\n        }\n    }\n\n    #[inline]\n    pub fn close_all_contours(&mut self) {\n        self.contours.iter_mut().for_each(|contour| contour.close());\n    }\n}\n\nimpl Debug for Outline {\n    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {\n        for (contour_index, contour) in self.contours.iter().enumerate() {\n            if contour_index > 0 {\n                write!(formatter, \" \")?;\n            }\n            contour.fmt(formatter)?;\n        }\n        Ok(())\n    }\n}\n\nimpl Contour {\n    #[inline]\n    pub fn new() -> Contour {\n        Contour {\n            points: vec![],\n            flags: vec![],\n            bounds: RectF::default(),\n            closed: false,\n        }\n    }\n\n    #[inline]\n    pub fn with_capacity(length: usize) -> Contour {\n        Contour {\n            points: Vec::with_capacity(length),\n            flags: Vec::with_capacity(length),\n            bounds: RectF::default(),\n            closed: false,\n        }\n    }\n\n    #[inline]\n    pub fn from_rect(rect: RectF) -> Contour {\n        let mut contour = Contour::new();\n        contour.push_point(rect.origin(), PointFlags::empty(), false);\n        contour.push_point(rect.upper_right(), PointFlags::empty(), false);\n        contour.push_point(rect.lower_right(), PointFlags::empty(), false);\n        contour.push_point(rect.lower_left(), PointFlags::empty(), false);\n        contour.close();\n        contour.bounds = rect;\n        contour\n    }\n\n    // Replaces this contour with a new one, with arrays preallocated to match `self`.\n    #[inline]\n    pub(crate) fn take(&mut self) -> Contour {\n        let length = self.len() as usize;\n        mem::replace(\n            self,\n            Contour {\n                points: Vec::with_capacity(length),\n                flags: Vec::with_capacity(length),\n                bounds: RectF::default(),\n                closed: false,\n            },\n        )\n    }\n\n    /// restore self to the state of Contour::new(), but keep the points buffer allocated\n    #[inline]\n    pub fn clear(&mut self) {\n        self.points.clear();\n        self.flags.clear();\n        self.bounds = RectF::default();\n        self.closed = false;\n    }\n\n    #[inline]\n    pub fn iter(&self, flags: ContourIterFlags) -> ContourIter {\n        ContourIter {\n            contour: self,\n            index: 1,\n            flags,\n        }\n    }\n\n    #[inline]\n    pub fn is_empty(&self) -> bool {\n        self.points.is_empty()\n    }\n\n    #[inline]\n    pub fn len(&self) -> u32 {\n        self.points.len() as u32\n    }\n\n    #[inline]\n    pub fn bounds(&self) -> RectF {\n        self.bounds\n    }\n\n    #[inline]\n    pub fn is_closed(&self) -> bool {\n        self.closed\n    }\n\n    #[inline]\n    pub fn position_of(&self, index: u32) -> Vector2F {\n        self.points[index as usize]\n    }\n\n    #[inline]\n    pub fn last_position(&self) -> Option<Vector2F> {\n        self.points.last().cloned()\n    }\n\n    #[inline]\n    pub(crate) fn position_of_last(&self, index: u32) -> Vector2F {\n        self.points[self.points.len() - index as usize]\n    }\n\n    #[inline]\n    pub fn push_endpoint(&mut self, point: Vector2F) {\n        self.push_point(point, PointFlags::empty(), true);\n    }\n\n    #[inline]\n    pub fn push_quadratic(&mut self, ctrl: Vector2F, point: Vector2F) {\n        self.push_point(ctrl, PointFlags::CONTROL_POINT_0, true);\n        self.push_point(point, PointFlags::empty(), true);\n    }\n\n    #[inline]\n    pub fn push_cubic(&mut self, ctrl0: Vector2F, ctrl1: Vector2F, point: Vector2F) {\n        self.push_point(ctrl0, PointFlags::CONTROL_POINT_0, true);\n        self.push_point(ctrl1, PointFlags::CONTROL_POINT_1, true);\n        self.push_point(point, PointFlags::empty(), true);\n    }\n\n    #[inline]\n    pub fn close(&mut self) {\n        self.closed = true;\n    }\n\n    #[inline]\n    pub(crate) fn push_point(&mut self,\n                             point: Vector2F,\n                             flags: PointFlags,\n                             update_bounds: bool) {\n        debug_assert!(!point.x().is_nan() && !point.y().is_nan());\n\n        if update_bounds {\n            let first = self.is_empty();\n            union_rect(&mut self.bounds, point, first);\n        }\n\n        self.points.push(point);\n        self.flags.push(flags);\n    }\n\n    #[inline]\n    pub(crate) fn push_segment(&mut self, segment: &Segment, flags: PushSegmentFlags) {\n        if segment.is_none() {\n            return;\n        }\n\n        let update_bounds = flags.contains(PushSegmentFlags::UPDATE_BOUNDS);\n        self.push_point(segment.baseline.from(), PointFlags::empty(), update_bounds);\n\n        if !segment.is_line() {\n            self.push_point(\n                segment.ctrl.from(),\n                PointFlags::CONTROL_POINT_0,\n                update_bounds,\n            );\n            if !segment.is_quadratic() {\n                self.push_point(\n                    segment.ctrl.to(),\n                    PointFlags::CONTROL_POINT_1,\n                    update_bounds,\n                );\n            }\n        }\n\n        self.push_point(segment.baseline.to(), PointFlags::empty(), update_bounds);\n    }\n\n    pub fn push_arc(&mut self,\n                    transform: &Transform2F,\n                    start_angle: f32,\n                    end_angle: f32,\n                    direction: ArcDirection) {\n        if end_angle - start_angle >= PI * 2.0 {\n            self.push_ellipse(transform);\n        } else {\n            let start = vec2f(start_angle.cos(), start_angle.sin());\n            let end   = vec2f(end_angle.cos(),   end_angle.sin());\n            self.push_arc_from_unit_chord(transform, LineSegment2F::new(start, end), direction);\n        }\n    }\n\n    pub fn push_arc_from_unit_chord(&mut self,\n                                    transform: &Transform2F,\n                                    mut chord: LineSegment2F,\n                                    direction: ArcDirection) {\n        let mut direction_transform = Transform2F::default();\n        if direction == ArcDirection::CCW {\n            chord *= vec2f(1.0, -1.0);\n            direction_transform = Transform2F::from_scale(vec2f(1.0, -1.0));\n        }\n\n        let (mut vector, end_vector) = (UnitVector(chord.from()), UnitVector(chord.to()));\n        for segment_index in 0..4 {\n            debug!(\"push_arc_from_unit_chord(): loop segment index {}\", segment_index);\n\n            let mut sweep_vector = end_vector.rev_rotate_by(vector);\n            let last = sweep_vector.0.x() >= -EPSILON && sweep_vector.0.y() >= -EPSILON;\n            debug!(\"... end_vector={:?} vector={:?} sweep_vector={:?} last={:?}\",\n                   end_vector,\n                   vector,\n                   sweep_vector,\n                   last);\n\n            let mut segment;\n            if !last {\n                sweep_vector = UnitVector(vec2f(0.0, 1.0));\n                segment = Segment::quarter_circle_arc();\n            } else {\n                segment = Segment::arc_from_cos(sweep_vector.0.x());\n            }\n\n            let half_sweep_vector = sweep_vector.halve_angle();\n            let rotation = Transform2F::from_rotation_vector(half_sweep_vector.rotate_by(vector));\n            segment = segment.transform(&(*transform * direction_transform * rotation));\n\n            let mut push_segment_flags = PushSegmentFlags::UPDATE_BOUNDS;\n            if segment_index == 0 {\n                push_segment_flags.insert(PushSegmentFlags::INCLUDE_FROM_POINT);\n            }\n            self.push_segment(&segment, push_segment_flags);\n\n            if last {\n                break;\n            }\n\n            vector = vector.rotate_by(sweep_vector);\n        }\n\n        const EPSILON: f32 = 0.001;\n    }\n\n    pub fn push_ellipse(&mut self, transform: &Transform2F) {\n        let segment = Segment::quarter_circle_arc();\n        let mut rotation;\n        self.push_segment(&segment.transform(transform),\n                          PushSegmentFlags::UPDATE_BOUNDS | PushSegmentFlags::INCLUDE_FROM_POINT);\n        rotation = Transform2F::from_rotation_vector(UnitVector(vec2f( 0.0,  1.0)));\n        self.push_segment(&segment.transform(&(*transform * rotation)),\n                          PushSegmentFlags::UPDATE_BOUNDS);\n        rotation = Transform2F::from_rotation_vector(UnitVector(vec2f(-1.0,  0.0)));\n        self.push_segment(&segment.transform(&(*transform * rotation)),\n                          PushSegmentFlags::UPDATE_BOUNDS);\n        rotation = Transform2F::from_rotation_vector(UnitVector(vec2f( 0.0, -1.0)));\n        self.push_segment(&segment.transform(&(*transform * rotation)),\n                          PushSegmentFlags::UPDATE_BOUNDS);\n    }\n\n    #[inline]\n    pub fn segment_after(&self, point_index: u32) -> Segment {\n        debug_assert!(self.point_is_endpoint(point_index));\n\n        let mut segment = Segment::none();\n        segment.baseline.set_from(self.position_of(point_index));\n\n        let point1_index = self.add_to_point_index(point_index, 1);\n        if self.point_is_endpoint(point1_index) {\n            segment.baseline.set_to(self.position_of(point1_index));\n            segment.kind = SegmentKind::Line;\n        } else {\n            segment.ctrl.set_from(self.position_of(point1_index));\n\n            let point2_index = self.add_to_point_index(point_index, 2);\n            if self.point_is_endpoint(point2_index) {\n                segment.baseline.set_to(self.position_of(point2_index));\n                segment.kind = SegmentKind::Quadratic;\n            } else {\n                segment.ctrl.set_to(self.position_of(point2_index));\n                segment.kind = SegmentKind::Cubic;\n\n                let point3_index = self.add_to_point_index(point_index, 3);\n                segment.baseline.set_to(self.position_of(point3_index));\n            }\n        }\n\n        segment\n    }\n\n    #[inline]\n    pub fn hull_segment_after(&self, prev_point_index: u32) -> LineSegment2F {\n        let next_point_index = self.next_point_index_of(prev_point_index);\n        LineSegment2F::new(\n            self.points[prev_point_index as usize],\n            self.points[next_point_index as usize],\n        )\n    }\n\n    #[inline]\n    pub fn point_is_endpoint(&self, point_index: u32) -> bool {\n        !self.flags[point_index as usize]\n            .intersects(PointFlags::CONTROL_POINT_0 | PointFlags::CONTROL_POINT_1)\n    }\n\n    #[inline]\n    pub fn add_to_point_index(&self, point_index: u32, addend: u32) -> u32 {\n        let (index, limit) = (point_index + addend, self.len());\n        if index >= limit {\n            index - limit\n        } else {\n            index\n        }\n    }\n\n    #[inline]\n    pub fn point_is_logically_above(&self, a: u32, b: u32) -> bool {\n        let (a_y, b_y) = (self.points[a as usize].y(), self.points[b as usize].y());\n        a_y < b_y || (a_y == b_y && a < b)\n    }\n\n    #[inline]\n    pub fn prev_endpoint_index_of(&self, mut point_index: u32) -> u32 {\n        loop {\n            point_index = self.prev_point_index_of(point_index);\n            if self.point_is_endpoint(point_index) {\n                return point_index;\n            }\n        }\n    }\n\n    #[inline]\n    pub fn next_endpoint_index_of(&self, mut point_index: u32) -> u32 {\n        loop {\n            point_index = self.next_point_index_of(point_index);\n            if self.point_is_endpoint(point_index) {\n                return point_index;\n            }\n        }\n    }\n\n    #[inline]\n    pub fn prev_point_index_of(&self, point_index: u32) -> u32 {\n        if point_index == 0 {\n            self.len() - 1\n        } else {\n            point_index - 1\n        }\n    }\n\n    #[inline]\n    pub fn next_point_index_of(&self, point_index: u32) -> u32 {\n        if point_index == self.len() - 1 {\n            0\n        } else {\n            point_index + 1\n        }\n    }\n\n    pub fn transform(&mut self, transform: &Transform2F) {\n        if transform.is_identity() {\n            return;\n        }\n\n        for (point_index, point) in self.points.iter_mut().enumerate() {\n            *point = *transform * *point;\n            union_rect(&mut self.bounds, *point, point_index == 0);\n        }\n    }\n\n    pub fn apply_perspective(&mut self, perspective: &Perspective) {\n        for (point_index, point) in self.points.iter_mut().enumerate() {\n            *point = *perspective * *point;\n            union_rect(&mut self.bounds, *point, point_index == 0);\n        }\n    }\n\n    pub fn dilate(&mut self, amount: Vector2F, orientation: Orientation) {\n        ContourDilator::new(self, amount, orientation).dilate();\n        self.bounds = self.bounds.dilate(amount);\n    }\n\n    fn prepare_for_tiling(&mut self, view_box: RectF) {\n        // Snap points to the view box bounds. This mops up floating point error from the clipping\n        // process.\n        let (mut last_endpoint_index, mut contour_is_monotonic) = (None, true);\n        for point_index in 0..(self.points.len() as u32) {\n            if contour_is_monotonic {\n                if self.point_is_endpoint(point_index) {\n                    if let Some(last_endpoint_index) = last_endpoint_index {\n                        if !self.curve_with_endpoints_is_monotonic(last_endpoint_index,\n                                                                   point_index) {\n                            contour_is_monotonic = false;\n                        }\n                    }\n                    last_endpoint_index = Some(point_index);\n                }\n            }\n        }\n\n        // Convert to monotonic, if necessary.\n        if !contour_is_monotonic {\n            self.make_monotonic();\n        }\n\n        // Update bounds.\n        self.bounds = self\n            .bounds\n            .intersection(view_box)\n            .unwrap_or_else(|| RectF::default());\n    }\n\n    fn make_monotonic(&mut self) {\n        debug!(\"--- make_monotonic() ---\");\n\n        let contour = self.take();\n        self.bounds = contour.bounds;\n\n        let mut last_endpoint_index = None;\n        let input_point_count = contour.points.len() as u32;\n        for point_index in 0..(input_point_count + 1) {\n            if point_index < input_point_count && !contour.point_is_endpoint(point_index) {\n                continue;\n            }\n\n            if let Some(last_endpoint_index) = last_endpoint_index {\n                let position_index = if point_index == input_point_count {\n                    0\n                } else {\n                    point_index\n                };\n                let baseline = LineSegment2F::new(\n                    contour.points[last_endpoint_index as usize],\n                    contour.points[position_index as usize],\n                );\n                let point_count = point_index - last_endpoint_index + 1;\n                if point_count == 3 {\n                    let ctrl_point_index = last_endpoint_index as usize + 1;\n                    let ctrl_position = &contour.points[ctrl_point_index];\n                    handle_cubic(\n                        self,\n                        &Segment::quadratic(baseline, *ctrl_position).to_cubic(),\n                    );\n                } else if point_count == 4 {\n                    let first_ctrl_point_index = last_endpoint_index as usize + 1;\n                    let ctrl_position_0 = &contour.points[first_ctrl_point_index + 0];\n                    let ctrl_position_1 = &contour.points[first_ctrl_point_index + 1];\n                    let ctrl = LineSegment2F::new(*ctrl_position_0, *ctrl_position_1);\n                    handle_cubic(self, &Segment::cubic(baseline, ctrl));\n                }\n\n                self.push_point(\n                    contour.points[position_index as usize],\n                    PointFlags::empty(),\n                    false,\n                );\n            }\n\n            last_endpoint_index = Some(point_index);\n        }\n\n        fn handle_cubic(contour: &mut Contour, segment: &Segment) {\n            debug!(\"handle_cubic({:?})\", segment);\n\n            match segment.as_cubic_segment().y_extrema() {\n                (Some(t0), Some(t1)) => {\n                    let (segments_01, segment_2) = segment.as_cubic_segment().split(t1);\n                    let (segment_0, segment_1) = segments_01.as_cubic_segment().split(t0 / t1);\n                    contour.push_segment(&segment_0, PushSegmentFlags::empty());\n                    contour.push_segment(&segment_1, PushSegmentFlags::empty());\n                    contour.push_segment(&segment_2, PushSegmentFlags::empty());\n                }\n                (Some(t0), None) | (None, Some(t0)) => {\n                    let (segment_0, segment_1) = segment.as_cubic_segment().split(t0);\n                    contour.push_segment(&segment_0, PushSegmentFlags::empty());\n                    contour.push_segment(&segment_1, PushSegmentFlags::empty());\n                }\n                (None, None) => contour.push_segment(segment, PushSegmentFlags::empty()),\n            }\n        }\n    }\n\n    fn curve_with_endpoints_is_monotonic(\n        &self,\n        start_endpoint_index: u32,\n        end_endpoint_index: u32,\n    ) -> bool {\n        let start_position = self.points[start_endpoint_index as usize];\n        let end_position = self.points[end_endpoint_index as usize];\n\n        if start_position.x() <= end_position.x() {\n            for point_index in start_endpoint_index..end_endpoint_index {\n                if self.points[point_index as usize].x() > self.points[point_index as usize + 1].x()\n                {\n                    return false;\n                }\n            }\n        } else {\n            for point_index in start_endpoint_index..end_endpoint_index {\n                if self.points[point_index as usize].x() < self.points[point_index as usize + 1].x()\n                {\n                    return false;\n                }\n            }\n        }\n\n        if start_position.y() <= end_position.y() {\n            for point_index in start_endpoint_index..end_endpoint_index {\n                if self.points[point_index as usize].y() > self.points[point_index as usize + 1].y()\n                {\n                    return false;\n                }\n            }\n        } else {\n            for point_index in start_endpoint_index..end_endpoint_index {\n                if self.points[point_index as usize].y() < self.points[point_index as usize + 1].y()\n                {\n                    return false;\n                }\n            }\n        }\n\n        true\n    }\n\n    // Use this function to keep bounds up to date when mutating paths. See `Outline::transform()`\n    // for an example of use.\n    pub(crate) fn update_bounds(&self, bounds: &mut Option<RectF>) {\n        *bounds = Some(match *bounds {\n            None => self.bounds,\n            Some(bounds) => bounds.union_rect(self.bounds),\n        })\n    }\n}\n\nimpl Debug for Contour {\n    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {\n        for (segment_index, segment) in self.iter(ContourIterFlags::IGNORE_CLOSE_SEGMENT)\n                                            .enumerate() {\n            if segment_index == 0 {\n                write!(\n                    formatter,\n                    \"M {} {}\",\n                    segment.baseline.from_x(),\n                    segment.baseline.from_y()\n                )?;\n            }\n\n            match segment.kind {\n                SegmentKind::None => {}\n                SegmentKind::Line => {\n                    write!(\n                        formatter,\n                        \" L {} {}\",\n                        segment.baseline.to_x(),\n                        segment.baseline.to_y()\n                    )?;\n                }\n                SegmentKind::Quadratic => {\n                    write!(\n                        formatter,\n                        \" Q {} {} {} {}\",\n                        segment.ctrl.from_x(),\n                        segment.ctrl.from_y(),\n                        segment.baseline.to_x(),\n                        segment.baseline.to_y()\n                    )?;\n                }\n                SegmentKind::Cubic => {\n                    write!(\n                        formatter,\n                        \" C {} {} {} {} {} {}\",\n                        segment.ctrl.from_x(),\n                        segment.ctrl.from_y(),\n                        segment.ctrl.to_x(),\n                        segment.ctrl.to_y(),\n                        segment.baseline.to_x(),\n                        segment.baseline.to_y()\n                    )?;\n                }\n            }\n        }\n\n        if self.closed {\n            write!(formatter, \" z\")?;\n        }\n\n        Ok(())\n    }\n}\n\n#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]\npub struct PointIndex(u32);\n\nimpl PointIndex {\n    #[inline]\n    pub fn new(contour: u32, point: u32) -> PointIndex {\n        debug_assert!(contour <= 0xfff);\n        debug_assert!(point <= 0x000f_ffff);\n        PointIndex((contour << 20) | point)\n    }\n\n    #[inline]\n    pub fn contour(self) -> u32 {\n        self.0 >> 20\n    }\n\n    #[inline]\n    pub fn point(self) -> u32 {\n        self.0 & 0x000f_ffff\n    }\n}\n\npub struct ContourIter<'a> {\n    contour: &'a Contour,\n    index: u32,\n    flags: ContourIterFlags,\n}\n\nimpl<'a> Iterator for ContourIter<'a> {\n    type Item = Segment;\n\n    #[inline]\n    fn next(&mut self) -> Option<Segment> {\n        let contour = self.contour;\n\n        let include_close_segment = self.contour.closed &&\n            !self.flags.contains(ContourIterFlags::IGNORE_CLOSE_SEGMENT);\n        if (self.index == contour.len() && !include_close_segment) ||\n                self.index == contour.len() + 1 {\n            return None;\n        }\n\n        let point0_index = self.index - 1;\n        let point0 = contour.position_of(point0_index);\n        if self.index == contour.len() {\n            let point1 = contour.position_of(0);\n            self.index += 1;\n            return Some(Segment::line(LineSegment2F::new(point0, point1)));\n        }\n\n        let point1_index = self.index;\n        self.index += 1;\n        let point1 = contour.position_of(point1_index);\n        if contour.point_is_endpoint(point1_index) {\n            return Some(Segment::line(LineSegment2F::new(point0, point1)));\n        }\n\n        let point2_index = self.index;\n        let point2 = contour.position_of(point2_index);\n        self.index += 1;\n        if contour.point_is_endpoint(point2_index) {\n            return Some(Segment::quadratic(LineSegment2F::new(point0, point2), point1));\n        }\n\n        let point3_index = self.index;\n        let point3 = contour.position_of(point3_index);\n        self.index += 1;\n        debug_assert!(contour.point_is_endpoint(point3_index));\n        return Some(Segment::cubic(\n            LineSegment2F::new(point0, point3),\n            LineSegment2F::new(point1, point2),\n        ));\n    }\n}\n\n#[derive(Clone, Copy, Debug, PartialEq)]\npub enum ArcDirection {\n    CW,\n    CCW,\n}\n\nbitflags! {\n    pub struct ContourIterFlags: u8 {\n        const IGNORE_CLOSE_SEGMENT = 1;\n    }\n}\n\n#[inline]\npub(crate) fn union_rect(bounds: &mut RectF, new_point: Vector2F, first: bool) {\n    if first {\n        *bounds = RectF::from_points(new_point, new_point);\n    } else {\n        *bounds = bounds.union_point(new_point)\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/pattern.rs",
      "sha256": "2924a04df9d0fcd124feda7b785cf87961e2f8881b74ed47a7d91d3f6d596b0c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/pattern.rs\n//\n// Copyright © 2020 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Raster image patterns.\n\nuse crate::effects::PatternFilter;\nuse crate::render_target::RenderTargetId;\nuse crate::util;\nuse pathfinder_color::{self as color, ColorU};\nuse pathfinder_geometry::transform2d::Transform2F;\nuse pathfinder_geometry::vector::{Vector2I, vec2i};\nuse std::collections::hash_map::DefaultHasher;\nuse std::fmt::{self, Debug, Formatter};\nuse std::hash::{Hash, Hasher};\nuse std::sync::Arc;\n\n#[cfg(feature = \"pf-image\")]\nuse image::RgbaImage;\n\n/// A raster image pattern.\n#[derive(Clone, PartialEq, Debug)]\npub struct Pattern {\n    source: PatternSource,\n    transform: Transform2F,\n    filter: Option<PatternFilter>,\n    flags: PatternFlags,\n}\n\n#[derive(Clone, PartialEq, Eq, Hash, Debug)]\npub enum PatternSource {\n    Image(Image),\n    RenderTarget {\n        id: RenderTargetId,\n        size: Vector2I,\n    }\n}\n\n/// RGBA, non-premultiplied.\n// FIXME(pcwalton): Hash the pixel contents so that we don't have to compare every pixel!\n// TODO(pcwalton): Should the pixels be premultiplied?\n#[derive(Clone, PartialEq, Eq)]\npub struct Image {\n    size: Vector2I,\n    pixels: Arc<Vec<ColorU>>,\n    pixels_hash: u64,\n    is_opaque: bool,\n}\n\nbitflags! {\n    pub struct PatternFlags: u8 {\n        const REPEAT_X      = 0x01;\n        const REPEAT_Y      = 0x02;\n        const NO_SMOOTHING  = 0x04;\n    }\n}\n\nimpl Pattern {\n    #[inline]\n    fn from_source(source: PatternSource) -> Pattern {\n        Pattern {\n            source,\n            transform: Transform2F::default(),\n            filter: None,\n            flags: PatternFlags::empty(),\n        }\n    }\n\n    #[inline]\n    pub fn from_image(image: Image) -> Pattern {\n        Pattern::from_source(PatternSource::Image(image))\n    }\n\n    #[inline]\n    pub fn from_render_target(id: RenderTargetId, size: Vector2I) -> Pattern {\n        Pattern::from_source(PatternSource::RenderTarget { id, size })\n    }\n\n    #[inline]\n    pub fn transform(&self) -> Transform2F {\n        self.transform\n    }\n\n    #[inline]\n    pub fn apply_transform(&mut self, transform: Transform2F) {\n        self.transform = transform * self.transform;\n    }\n\n    #[inline]\n    pub fn size(&self) -> Vector2I {\n        match self.source {\n            PatternSource::Image(ref image) => image.size(),\n            PatternSource::RenderTarget { size, .. } => size,\n        }\n    }\n\n    #[inline]\n    pub fn filter(&self) -> Option<PatternFilter> {\n        self.filter\n    }\n\n    #[inline]\n    pub fn set_filter(&mut self, filter: Option<PatternFilter>) {\n        self.filter = filter;\n    }\n\n    #[inline]\n    pub fn repeat_x(&self) -> bool {\n        self.flags.contains(PatternFlags::REPEAT_X)\n    }\n\n    #[inline]\n    pub fn set_repeat_x(&mut self, repeat_x: bool) {\n        self.flags.set(PatternFlags::REPEAT_X, repeat_x);\n    }\n\n    #[inline]\n    pub fn repeat_y(&self) -> bool {\n        self.flags.contains(PatternFlags::REPEAT_Y)\n    }\n\n    #[inline]\n    pub fn set_repeat_y(&mut self, repeat_y: bool) {\n        self.flags.set(PatternFlags::REPEAT_Y, repeat_y);\n    }\n\n    #[inline]\n    pub fn smoothing_enabled(&self) -> bool {\n        !self.flags.contains(PatternFlags::NO_SMOOTHING)\n    }\n\n    #[inline]\n    pub fn set_smoothing_enabled(&mut self, enable: bool) {\n        self.flags.set(PatternFlags::NO_SMOOTHING, !enable);\n    }\n\n    #[inline]\n    pub fn is_opaque(&self) -> bool {\n        self.source.is_opaque()\n    }\n\n    #[inline]\n    pub fn source(&self) -> &PatternSource {\n        &self.source\n    }\n}\n\nimpl Image {\n    #[inline]\n    pub fn new(size: Vector2I, pixels: Arc<Vec<ColorU>>) -> Image {\n        assert_eq!(size.x() as usize * size.y() as usize, pixels.len());\n        let is_opaque = pixels.iter().all(|pixel| pixel.is_opaque());\n\n        let mut pixels_hasher = DefaultHasher::new();\n        pixels.hash(&mut pixels_hasher);\n        let pixels_hash = pixels_hasher.finish();\n\n        Image { size, pixels, pixels_hash, is_opaque }\n    }\n\n    #[cfg(feature = \"pf-image\")]\n    pub fn from_image_buffer(image_buffer: RgbaImage) -> Image {\n        let (width, height) = image_buffer.dimensions();\n        let pixels = color::u8_vec_to_color_vec(image_buffer.into_raw());\n        Image::new(vec2i(width as i32, height as i32), Arc::new(pixels))\n    }\n\n    #[inline]\n    pub fn size(&self) -> Vector2I {\n        self.size\n    }\n\n    #[inline]\n    pub fn pixels(&self) -> &Arc<Vec<ColorU>> {\n        &self.pixels\n    }\n\n    #[inline]\n    pub fn is_opaque(&self) -> bool {\n        self.is_opaque\n    }\n}\n\nimpl PatternSource {\n    #[inline]\n    pub fn is_opaque(&self) -> bool {\n        match *self {\n            PatternSource::Image(ref image) => image.is_opaque(),\n            PatternSource::RenderTarget { .. } => {\n                // TODO(pcwalton): Maybe do something smarter here?\n                false\n            }\n        }\n    }\n}\n\nimpl Debug for Image {\n    #[inline]\n    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {\n        write!(formatter, \"(image {}×{} px)\", self.size.x(), self.size.y())\n    }\n}\n\nimpl Hash for Image {\n    fn hash<H>(&self, hasher: &mut H) where H: Hasher {\n        self.size.hash(hasher);\n        self.pixels_hash.hash(hasher);\n        self.is_opaque.hash(hasher);\n    }\n}\n\nimpl Eq for Pattern {}\n\nimpl Hash for Pattern {\n    fn hash<H>(&self, state: &mut H) where H: Hasher {\n        self.source.hash(state);\n        util::hash_transform2f(self.transform, state);\n        self.flags.hash(state);\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/render_target.rs",
      "sha256": "4c4351303466b11b11c9e6bf73faec138db7a054e27e3ffcfc6eb108cd95a370",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/render_target.rs\n//\n// Copyright © 2020 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Render targets.\n\n#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]\npub struct RenderTargetId {\n    pub scene: u32,\n    pub render_target: u32,\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/segment.rs",
      "sha256": "8e119e2dc90d839b0577f7de34c20dfd5789d287e55b7ac824e24406e99f0da1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/segment.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Line or curve segments, optimized with SIMD.\n\nuse pathfinder_geometry::line_segment::LineSegment2F;\nuse pathfinder_geometry::transform2d::Transform2F;\nuse pathfinder_geometry::util::{self, EPSILON};\nuse pathfinder_geometry::vector::{Vector2F, vec2f};\nuse pathfinder_simd::default::F32x4;\nuse std::f32::consts::SQRT_2;\n\nconst MAX_NEWTON_ITERATIONS: u32 = 32;\n\n#[derive(Clone, Copy, Debug, PartialEq)]\npub struct Segment {\n    pub baseline: LineSegment2F,\n    pub ctrl: LineSegment2F,\n    pub kind: SegmentKind,\n    pub flags: SegmentFlags,\n}\n\nimpl Segment {\n    #[inline]\n    pub fn none() -> Segment {\n        Segment {\n            baseline: LineSegment2F::default(),\n            ctrl: LineSegment2F::default(),\n            kind: SegmentKind::None,\n            flags: SegmentFlags::empty(),\n        }\n    }\n\n    #[inline]\n    pub fn line(line: LineSegment2F) -> Segment {\n        Segment {\n            baseline: line,\n            ctrl: LineSegment2F::default(),\n            kind: SegmentKind::Line,\n            flags: SegmentFlags::empty(),\n        }\n    }\n\n    #[inline]\n    pub fn quadratic(baseline: LineSegment2F, ctrl: Vector2F) -> Segment {\n        Segment {\n            baseline,\n            ctrl: LineSegment2F::new(ctrl, Vector2F::zero()),\n            kind: SegmentKind::Quadratic,\n            flags: SegmentFlags::empty(),\n        }\n    }\n\n    #[inline]\n    pub fn cubic(baseline: LineSegment2F, ctrl: LineSegment2F) -> Segment {\n        Segment {\n            baseline,\n            ctrl,\n            kind: SegmentKind::Cubic,\n            flags: SegmentFlags::empty(),\n        }\n    }\n\n    /// Approximates an unit-length arc with a cubic Bézier curve.\n    ///\n    /// The maximum supported sweep angle is π/2 (i.e. 90°).\n    pub fn arc(sweep_angle: f32) -> Segment {\n        Segment::arc_from_cos(f32::cos(sweep_angle))\n    }\n\n    /// Approximates an unit-length arc with a cubic Bézier curve, given the cosine of the sweep\n    /// angle.\n    ///\n    /// The maximum supported sweep angle is π/2 (i.e. 90°).\n    pub fn arc_from_cos(cos_sweep_angle: f32) -> Segment {\n        // Richard A. DeVeneza, \"How to determine the control points of a Bézier curve that\n        // approximates a small arc\", 2004.\n        //\n        // https://www.tinaja.com/glib/bezcirc2.pdf\n        if cos_sweep_angle >= 1.0 - EPSILON {\n            return Segment::line(LineSegment2F::new(vec2f(1.0, 0.0), vec2f(1.0, 0.0)));\n        }\n\n        let term = F32x4::new(cos_sweep_angle, -cos_sweep_angle,\n                              cos_sweep_angle, -cos_sweep_angle);\n        let signs = F32x4::new(1.0, -1.0, 1.0, 1.0);\n        let p3p0 = ((F32x4::splat(1.0) + term) * F32x4::splat(0.5)).sqrt() * signs;\n        let (p0x, p0y) = (p3p0.z(), p3p0.w());\n        let (p1x, p1y) = (4.0 - p0x, (1.0 - p0x) * (3.0 - p0x) / p0y);\n        let p2p1 = F32x4::new(p1x, -p1y, p1x, p1y) * F32x4::splat(1.0 / 3.0);\n        return Segment::cubic(LineSegment2F(p3p0), LineSegment2F(p2p1));\n    }\n\n    #[inline]\n    pub fn quarter_circle_arc() -> Segment {\n        let p0 = Vector2F::splat(SQRT_2 * 0.5);\n        let p1 = vec2f(-SQRT_2 / 6.0 + 4.0 / 3.0, 7.0 * SQRT_2 / 6.0 - 4.0 / 3.0);\n        let flip = vec2f(1.0, -1.0);\n        let (p2, p3) = (p1 * flip, p0 * flip);\n        Segment::cubic(LineSegment2F::new(p3, p0), LineSegment2F::new(p2, p1))\n    }\n\n    #[inline]\n    pub fn as_line_segment(&self) -> LineSegment2F {\n        debug_assert!(self.is_line());\n        self.baseline\n    }\n\n    #[inline]\n    pub fn is_none(&self) -> bool {\n        self.kind == SegmentKind::None\n    }\n\n    #[inline]\n    pub fn is_line(&self) -> bool {\n        self.kind == SegmentKind::Line\n    }\n\n    #[inline]\n    pub fn is_quadratic(&self) -> bool {\n        self.kind == SegmentKind::Quadratic\n    }\n\n    #[inline]\n    pub fn is_cubic(&self) -> bool {\n        self.kind == SegmentKind::Cubic\n    }\n\n    #[inline]\n    pub fn as_cubic_segment(&self) -> CubicSegment {\n        debug_assert!(self.is_cubic());\n        CubicSegment(self)\n    }\n\n    // FIXME(pcwalton): We should basically never use this function.\n    // FIXME(pcwalton): Handle lines!\n    #[inline]\n    pub fn to_cubic(&self) -> Segment {\n        if self.is_cubic() {\n            return *self;\n        }\n\n        let mut new_segment = *self;\n        let p1_2 = self.ctrl.from() + self.ctrl.from();\n        new_segment.ctrl = LineSegment2F::new(self.baseline.from() + p1_2,\n                                              p1_2 + self.baseline.to()) * (1.0 / 3.0);\n        new_segment.kind = SegmentKind::Cubic;\n        new_segment\n    }\n\n    #[inline]\n    pub fn is_monotonic(&self) -> bool {\n        // FIXME(pcwalton): Don't degree elevate!\n        match self.kind {\n            SegmentKind::None | SegmentKind::Line => true,\n            SegmentKind::Quadratic => self.to_cubic().as_cubic_segment().is_monotonic(),\n            SegmentKind::Cubic => self.as_cubic_segment().is_monotonic(),\n        }\n    }\n\n    #[inline]\n    pub fn reversed(&self) -> Segment {\n        Segment {\n            baseline: self.baseline.reversed(),\n            ctrl: if self.is_quadratic() {\n                self.ctrl\n            } else {\n                self.ctrl.reversed()\n            },\n            kind: self.kind,\n            flags: self.flags,\n        }\n    }\n\n    // Reverses if necessary so that the from point is above the to point. Calling this method\n    // again will undo the transformation.\n    #[inline]\n    pub fn orient(&self, y_winding: i32) -> Segment {\n        if y_winding >= 0 {\n            *self\n        } else {\n            self.reversed()\n        }\n    }\n\n    #[inline]\n    pub fn is_tiny(&self) -> bool {\n        const EPSILON: f32 = 0.0001;\n        self.baseline.square_length() < EPSILON\n    }\n\n    #[inline]\n    pub fn split(&self, t: f32) -> (Segment, Segment) {\n        // FIXME(pcwalton): Don't degree elevate!\n        if self.is_line() {\n            let (before, after) = self.as_line_segment().split(t);\n            (Segment::line(before), Segment::line(after))\n        } else {\n            self.to_cubic().as_cubic_segment().split(t)\n        }\n    }\n\n    #[inline]\n    pub fn sample(self, t: f32) -> Vector2F {\n        // FIXME(pcwalton): Don't degree elevate!\n        if self.is_line() {\n            self.as_line_segment().sample(t)\n        } else {\n            self.to_cubic().as_cubic_segment().sample(t)\n        }\n    }\n\n    #[inline]\n    pub fn transform(self, transform: &Transform2F) -> Segment {\n        Segment {\n            baseline: *transform * self.baseline,\n            ctrl: *transform * self.ctrl,\n            kind: self.kind,\n            flags: self.flags,\n        }\n    }\n\n    pub fn arc_length(&self) -> f32 {\n        // FIXME(pcwalton)\n        self.baseline.vector().length()\n    }\n\n    pub fn time_for_distance(&self, distance: f32) -> f32 {\n        // FIXME(pcwalton)\n        distance / self.arc_length()\n    }\n}\n\n#[derive(Clone, Copy, Debug, PartialEq)]\n#[repr(u8)]\npub enum SegmentKind {\n    None,\n    Line,\n    Quadratic,\n    Cubic,\n}\n\nbitflags! {\n    pub struct SegmentFlags: u8 {\n        const FIRST_IN_SUBPATH = 0x01;\n        const CLOSES_SUBPATH = 0x02;\n    }\n}\n\n#[derive(Clone, Copy, Debug)]\npub struct CubicSegment<'s>(pub &'s Segment);\n\nimpl<'s> CubicSegment<'s> {\n    // See Kaspar Fischer, \"Piecewise Linear Approximation of Bézier Curves\", 2000.\n    #[inline]\n    pub fn is_flat(self, tolerance: f32) -> bool {\n        let mut uv = F32x4::splat(3.0) * self.0.ctrl.0\n            - self.0.baseline.0\n            - self.0.baseline.0\n            - self.0.baseline.reversed().0;\n        uv = uv * uv;\n        uv = uv.max(uv.zwxy());\n        uv[0] + uv[1] <= 16.0 * tolerance * tolerance\n    }\n\n    #[inline]\n    pub fn split(self, t: f32) -> (Segment, Segment) {\n        let (baseline0, ctrl0, baseline1, ctrl1);\n        if t <= 0.0 {\n            let from = &self.0.baseline.from();\n            baseline0 = LineSegment2F::new(*from, *from);\n            ctrl0 = LineSegment2F::new(*from, *from);\n            baseline1 = self.0.baseline;\n            ctrl1 = self.0.ctrl;\n        } else if t >= 1.0 {\n            let to = &self.0.baseline.to();\n            baseline0 = self.0.baseline;\n            ctrl0 = self.0.ctrl;\n            baseline1 = LineSegment2F::new(*to, *to);\n            ctrl1 = LineSegment2F::new(*to, *to);\n        } else {\n            let tttt = F32x4::splat(t);\n\n            let (p0p3, p1p2) = (self.0.baseline.0, self.0.ctrl.0);\n            let p0p1 = p0p3.concat_xy_xy(p1p2);\n\n            // p01 = lerp(p0, p1, t), p12 = lerp(p1, p2, t), p23 = lerp(p2, p3, t)\n            let p01p12 = p0p1 + tttt * (p1p2 - p0p1);\n            let pxxp23 = p1p2 + tttt * (p0p3 - p1p2);\n            let p12p23 = p01p12.concat_zw_zw(pxxp23);\n\n            // p012 = lerp(p01, p12, t), p123 = lerp(p12, p23, t)\n            let p012p123 = p01p12 + tttt * (p12p23 - p01p12);\n            let p123 = p012p123.zwzw();\n\n            // p0123 = lerp(p012, p123, t)\n            let p0123 = p012p123 + tttt * (p123 - p012p123);\n\n            baseline0 = LineSegment2F(p0p3.concat_xy_xy(p0123));\n            ctrl0 = LineSegment2F(p01p12.concat_xy_xy(p012p123));\n            baseline1 = LineSegment2F(p0123.concat_xy_zw(p0p3));\n            ctrl1 = LineSegment2F(p012p123.concat_zw_zw(p12p23));\n        }\n\n        (\n            Segment {\n                baseline: baseline0,\n                ctrl: ctrl0,\n                kind: SegmentKind::Cubic,\n                flags: self.0.flags & SegmentFlags::FIRST_IN_SUBPATH,\n            },\n            Segment {\n                baseline: baseline1,\n                ctrl: ctrl1,\n                kind: SegmentKind::Cubic,\n                flags: self.0.flags & SegmentFlags::CLOSES_SUBPATH,\n            },\n        )\n    }\n\n    #[inline]\n    pub fn split_before(self, t: f32) -> Segment {\n        self.split(t).0\n    }\n\n    #[inline]\n    pub fn split_after(self, t: f32) -> Segment {\n        self.split(t).1\n    }\n\n    // FIXME(pcwalton): Use Horner's method!\n    #[inline]\n    pub fn sample(self, t: f32) -> Vector2F {\n        self.split(t).0.baseline.to()\n    }\n\n    #[inline]\n    pub fn is_monotonic(self) -> bool {\n        // TODO(pcwalton): Optimize this.\n        let (p0, p3) = (self.0.baseline.from_y(), self.0.baseline.to_y());\n        let (p1, p2) = (self.0.ctrl.from_y(), self.0.ctrl.to_y());\n        (p0 <= p1 && p1 <= p2 && p2 <= p3) || (p0 >= p1 && p1 >= p2 && p2 >= p3)\n    }\n\n    #[inline]\n    pub fn y_extrema(self) -> (Option<f32>, Option<f32>) {\n        if self.is_monotonic() {\n            return (None, None);\n        }\n\n        let p0p1p2p3 = F32x4::new(\n            self.0.baseline.from_y(),\n            self.0.ctrl.from_y(),\n            self.0.ctrl.to_y(),\n            self.0.baseline.to_y(),\n        );\n\n        let pxp0p1p2 = p0p1p2p3.wxyz();\n        let pxv0v1v2 = p0p1p2p3 - pxp0p1p2;\n        let (v0, v1, v2) = (pxv0v1v2[1], pxv0v1v2[2], pxv0v1v2[3]);\n\n        let (t0, t1);\n        let (v0_to_v1, v2_to_v1) = (v0 - v1, v2 - v1);\n        let denom = v0_to_v1 + v2_to_v1;\n\n        if util::approx_eq(denom, 0.0) {\n            // Let's not divide by zero (issue #146). Fall back to Newton's method.\n            // FIXME(pcwalton): Can we have two roots here?\n            let mut t = 0.5;\n            for _ in 0..MAX_NEWTON_ITERATIONS {\n                let dydt = 3.0 * ((denom * t - v0_to_v1 - v0_to_v1) * t + v0);\n                if f32::abs(dydt) <= EPSILON {\n                    break\n                }\n                let d2ydt2 = 6.0 * (denom * t - v0_to_v1);\n                t -= dydt / d2ydt2;\n            }\n            t0 = t;\n            t1 = 0.0;\n            debug!(\"...  t=(newton) {}\", t);\n        } else {\n            // Algebraically compute the values for t.\n            let discrim = f32::sqrt(v1 * v1 - v0 * v2);\n            let denom_recip = 1.0 / denom;\n\n            t0 = (v0_to_v1 + discrim) * denom_recip;\n            t1 = (v0_to_v1 - discrim) * denom_recip;\n\n            debug!(\"... t=({} +/- {})/{} t0={} t1={}\", v0_to_v1, discrim, denom, t0, t1);\n        }\n\n        return match (\n            t0 > EPSILON && t0 < 1.0 - EPSILON,\n            t1 > EPSILON && t1 < 1.0 - EPSILON,\n        ) {\n            (false, false) => (None, None),\n            (true, false) => (Some(t0), None),\n            (false, true) => (Some(t1), None),\n            (true, true) => (Some(f32::min(t0, t1)), Some(f32::max(t0, t1))),\n        };\n    }\n\n    #[inline]\n    pub fn min_x(&self) -> f32 {\n        f32::min(self.0.baseline.min_x(), self.0.ctrl.min_x())\n    }\n    #[inline]\n    pub fn min_y(&self) -> f32 {\n        f32::min(self.0.baseline.min_y(), self.0.ctrl.min_y())\n    }\n    #[inline]\n    pub fn max_x(&self) -> f32 {\n        f32::max(self.0.baseline.max_x(), self.0.ctrl.max_x())\n    }\n    #[inline]\n    pub fn max_y(&self) -> f32 {\n        f32::max(self.0.baseline.max_y(), self.0.ctrl.max_y())\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/sorted_vector.rs",
      "sha256": "a4ce0e1da35c7c1cfc0ccbae16d32fd5b447152bd1a95450ffecb2207d861ba0",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/sorted_vector.rs\n//\n// Copyright © 2020 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! A vector that maintains sorted order with insertion sort.\n\nuse std::cmp::Ordering;\nuse std::convert;\n\n#[derive(Clone, PartialEq, Eq, Hash, Debug)]\npub struct SortedVector<T>\nwhere\n    T: PartialOrd,\n{\n    pub array: Vec<T>,\n}\n\nimpl<T> SortedVector<T>\nwhere\n    T: PartialOrd,\n{\n    #[inline]\n    pub fn new() -> SortedVector<T> {\n        SortedVector { array: vec![] }\n    }\n\n    #[inline]\n    pub fn push(&mut self, value: T) {\n        let index = self.binary_search_by(|other| {\n            other.partial_cmp(&value).unwrap_or(Ordering::Less)\n        }).unwrap_or_else(convert::identity);\n        self.array.insert(index, value);\n    }\n\n    #[inline]\n    pub fn peek(&self) -> Option<&T> {\n        self.array.last()\n    }\n\n    #[inline]\n    pub fn pop(&mut self) -> Option<T> {\n        self.array.pop()\n    }\n\n    #[inline]\n    pub fn clear(&mut self) {\n        self.array.clear()\n    }\n\n    #[allow(dead_code)]\n    #[inline]\n    pub fn is_empty(&self) -> bool {\n        self.array.is_empty()\n    }\n\n    #[inline]\n    pub fn len(&self) -> usize {\n        self.array.len()\n    }\n\n    #[inline]\n    pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>\n                                   where F: FnMut(&'a T) -> Ordering {\n        self.array.binary_search_by(f)\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use crate::sorted_vector::SortedVector;\n    use quickcheck;\n\n    #[test]\n    fn test_sorted_vec() {\n        quickcheck::quickcheck(prop_sorted_vec as fn(Vec<i32>) -> bool);\n\n        fn prop_sorted_vec(mut values: Vec<i32>) -> bool {\n            let mut sorted_vec = SortedVector::new();\n            for &value in &values {\n                sorted_vec.push(value)\n            }\n\n            values.sort();\n            let mut results = Vec::with_capacity(values.len());\n            while !sorted_vec.is_empty() {\n                results.push(sorted_vec.pop().unwrap());\n            }\n            results.reverse();\n            assert_eq!(&values, &results);\n\n            true\n        }\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/stroke.rs",
      "sha256": "25450d1680bee0b0b8848ffb42665cef1f0523ec6c879bcd3df01e4a26d206c9",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/stroke.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Utilities for converting path strokes to fills.\n\nuse crate::outline::{ArcDirection, Contour, ContourIterFlags, Outline, PushSegmentFlags};\nuse crate::segment::Segment;\nuse pathfinder_geometry::line_segment::LineSegment2F;\nuse pathfinder_geometry::rect::RectF;\nuse pathfinder_geometry::transform2d::Transform2F;\nuse pathfinder_geometry::util::EPSILON;\nuse pathfinder_geometry::vector::{Vector2F, vec2f};\nuse std::f32;\n\nconst TOLERANCE: f32 = 0.01;\n\npub struct OutlineStrokeToFill<'a> {\n    input: &'a Outline,\n    output: Outline,\n    style: StrokeStyle,\n}\n\n#[derive(Clone, Copy, Debug, PartialEq)]\npub struct StrokeStyle {\n    pub line_width: f32,\n    pub line_cap: LineCap,\n    pub line_join: LineJoin,\n}\n\n#[derive(Clone, Copy, Debug, PartialEq)]\npub enum LineCap {\n    Butt,\n    Square,\n    Round,\n}\n\n#[derive(Clone, Copy, Debug, PartialEq)]\npub enum LineJoin {\n    Miter(f32),\n    Bevel,\n    Round,\n}\n\nimpl<'a> OutlineStrokeToFill<'a> {\n    #[inline]\n    pub fn new(input: &Outline, style: StrokeStyle) -> OutlineStrokeToFill {\n        OutlineStrokeToFill { input, output: Outline::new(), style }\n    }\n\n    pub fn offset(&mut self) {\n        let mut new_contours = vec![];\n        for input in &self.input.contours {\n            let closed = input.closed;\n            let mut stroker = ContourStrokeToFill::new(input,\n                                                       Contour::new(),\n                                                       self.style.line_width * 0.5,\n                                                       self.style.line_join);\n\n            stroker.offset_forward();\n            if closed {\n                self.push_stroked_contour(&mut new_contours, stroker, true);\n                stroker = ContourStrokeToFill::new(input,\n                                                   Contour::new(),\n                                                   self.style.line_width * 0.5,\n                                                   self.style.line_join);\n            } else {\n                self.add_cap(&mut stroker.output);\n            }\n\n            stroker.offset_backward();\n            if !closed {\n                self.add_cap(&mut stroker.output);\n            }\n\n            self.push_stroked_contour(&mut new_contours, stroker, closed);\n        }\n\n        let mut new_bounds = None;\n        new_contours.iter().for_each(|contour| contour.update_bounds(&mut new_bounds));\n\n        self.output.contours = new_contours;\n        self.output.bounds = new_bounds.unwrap_or_else(|| RectF::default());\n    }\n\n    #[inline]\n    pub fn into_outline(self) -> Outline {\n        self.output\n    }\n\n    fn push_stroked_contour(&mut self,\n                            new_contours: &mut Vec<Contour>,\n                            mut stroker: ContourStrokeToFill,\n                            closed: bool) {\n        // Add join if necessary.\n        if closed && stroker.output.might_need_join(self.style.line_join) {\n            let (p1, p0) = (stroker.output.position_of(1), stroker.output.position_of(0));\n            let final_segment = LineSegment2F::new(p1, p0);\n            stroker.output.add_join(self.style.line_width * 0.5,\n                                    self.style.line_join,\n                                    stroker.input.position_of(0),\n                                    final_segment);\n        }\n\n        stroker.output.closed = true;\n        new_contours.push(stroker.output);\n    }\n\n    fn add_cap(&mut self, contour: &mut Contour) {\n        if self.style.line_cap == LineCap::Butt || contour.len() < 2 {\n            return\n        }\n\n        let width = self.style.line_width;\n        let p1 = contour.position_of_last(1);\n\n        // Determine the ending gradient.\n        let mut p0;\n        let mut p0_index = contour.len() - 2;\n        loop {\n            p0 = contour.position_of(p0_index);\n            if (p1 - p0).square_length() > EPSILON {\n                break;\n            }\n            if p0_index == 0 {\n                return;\n            }\n            p0_index -= 1;\n        }\n        let gradient = (p1 - p0).normalize();\n\n        match self.style.line_cap {\n            LineCap::Butt => unreachable!(),\n\n            LineCap::Square => {\n                let offset = gradient * (width * 0.5);\n\n                let p2 = p1 + offset;\n                let p3 = p2 + gradient.yx() * vec2f(-width, width);\n                let p4 = p3 - offset;\n\n                contour.push_endpoint(p2);\n                contour.push_endpoint(p3);\n                contour.push_endpoint(p4);\n            }\n\n            LineCap::Round => {\n                let scale = width * 0.5;\n                let offset = gradient.yx() * vec2f(-1.0, 1.0);\n                let translation = p1 + offset * (width * 0.5);\n                let transform = Transform2F::from_scale(scale).translate(translation);\n                let chord = LineSegment2F::new(-offset, offset);\n                contour.push_arc_from_unit_chord(&transform, chord, ArcDirection::CW);\n            }\n        }\n    }\n}\n\nstruct ContourStrokeToFill<'a> {\n    input: &'a Contour,\n    output: Contour,\n    radius: f32,\n    join: LineJoin,\n}\n\nimpl<'a> ContourStrokeToFill<'a> {\n    #[inline]\n    fn new(input: &Contour, output: Contour, radius: f32, join: LineJoin) -> ContourStrokeToFill {\n        ContourStrokeToFill { input, output, radius, join }\n    }\n\n    fn offset_forward(&mut self) {\n        for (segment_index, segment) in self.input.iter(ContourIterFlags::empty()).enumerate() {\n            // FIXME(pcwalton): We negate the radius here so that round end caps can be drawn\n            // clockwise. Of course, we should just implement anticlockwise arcs to begin with...\n            let join = if segment_index == 0 { LineJoin::Bevel } else { self.join };\n            segment.offset(-self.radius, join, &mut self.output);\n        }\n    }\n\n    fn offset_backward(&mut self) {\n        let mut segments: Vec<_> = self\n            .input\n            .iter(ContourIterFlags::empty())\n            .map(|segment| segment.reversed())\n            .collect();\n        segments.reverse();\n        for (segment_index, segment) in segments.iter().enumerate() {\n            // FIXME(pcwalton): We negate the radius here so that round end caps can be drawn\n            // clockwise. Of course, we should just implement anticlockwise arcs to begin with...\n            let join = if segment_index == 0 { LineJoin::Bevel } else { self.join };\n            segment.offset(-self.radius, join, &mut self.output);\n        }\n    }\n}\n\ntrait Offset {\n    fn offset(&self, distance: f32, join: LineJoin, contour: &mut Contour);\n    fn add_to_contour(&self,\n                      distance: f32,\n                      join: LineJoin,\n                      join_point: Vector2F,\n                      contour: &mut Contour);\n    fn offset_once(&self, distance: f32) -> Self;\n    fn error_is_within_tolerance(&self, other: &Segment, distance: f32) -> bool;\n}\n\nimpl Offset for Segment {\n    fn offset(&self, distance: f32, join: LineJoin, contour: &mut Contour) {\n        let join_point = self.baseline.from();\n        if self.baseline.square_length() < TOLERANCE * TOLERANCE {\n            self.add_to_contour(distance, join, join_point, contour);\n            return;\n        }\n\n        let candidate = self.offset_once(distance);\n        if self.error_is_within_tolerance(&candidate, distance) {\n            candidate.add_to_contour(distance, join, join_point, contour);\n            return;\n        }\n\n        debug!(\"--- SPLITTING ---\");\n        debug!(\"... PRE-SPLIT: {:?}\", self);\n        let (before, after) = self.split(0.5);\n        debug!(\"... AFTER-SPLIT: {:?} {:?}\", before, after);\n        before.offset(distance, join, contour);\n        after.offset(distance, join, contour);\n    }\n\n    fn add_to_contour(&self,\n                      distance: f32,\n                      join: LineJoin,\n                      join_point: Vector2F,\n                      contour: &mut Contour) {\n        // Add join if necessary.\n        if contour.might_need_join(join) {\n            let p3 = self.baseline.from();\n            let p4 = if self.is_line() {\n                self.baseline.to()\n            } else {\n                // NB: If you change the representation of quadratic curves, you will need to\n                // change this.\n                self.ctrl.from()\n            };\n\n            contour.add_join(distance, join, join_point, LineSegment2F::new(p4, p3));\n        }\n\n        // Push segment.\n        let flags = PushSegmentFlags::UPDATE_BOUNDS | PushSegmentFlags::INCLUDE_FROM_POINT;\n        contour.push_segment(self, flags);\n    }\n\n    fn offset_once(&self, distance: f32) -> Segment {\n        if self.is_line() {\n            return Segment::line(self.baseline.offset(distance));\n        }\n\n        if self.is_quadratic() {\n            let mut segment_0 = LineSegment2F::new(self.baseline.from(), self.ctrl.from());\n            let mut segment_1 = LineSegment2F::new(self.ctrl.from(), self.baseline.to());\n            segment_0 = segment_0.offset(distance);\n            segment_1 = segment_1.offset(distance);\n            let ctrl = match segment_0.intersection_t(segment_1) {\n                Some(t) => segment_0.sample(t),\n                None => segment_0.to().lerp(segment_1.from(), 0.5),\n            };\n            let baseline = LineSegment2F::new(segment_0.from(), segment_1.to());\n            return Segment::quadratic(baseline, ctrl);\n        }\n\n        debug_assert!(self.is_cubic());\n\n        if self.baseline.from() == self.ctrl.from() {\n            let mut segment_0 = LineSegment2F::new(self.baseline.from(), self.ctrl.to());\n            let mut segment_1 = LineSegment2F::new(self.ctrl.to(), self.baseline.to());\n            segment_0 = segment_0.offset(distance);\n            segment_1 = segment_1.offset(distance);\n            let ctrl = match segment_0.intersection_t(segment_1) {\n                Some(t) => segment_0.sample(t),\n                None => segment_0.to().lerp(segment_1.from(), 0.5),\n            };\n            let baseline = LineSegment2F::new(segment_0.from(), segment_1.to());\n            let ctrl = LineSegment2F::new(segment_0.from(), ctrl);\n            return Segment::cubic(baseline, ctrl);\n        }\n\n        if self.ctrl.to() == self.baseline.to() {\n            let mut segment_0 = LineSegment2F::new(self.baseline.from(), self.ctrl.from());\n            let mut segment_1 = LineSegment2F::new(self.ctrl.from(), self.baseline.to());\n            segment_0 = segment_0.offset(distance);\n            segment_1 = segment_1.offset(distance);\n            let ctrl = match segment_0.intersection_t(segment_1) {\n                Some(t) => segment_0.sample(t),\n                None => segment_0.to().lerp(segment_1.from(), 0.5),\n            };\n            let baseline = LineSegment2F::new(segment_0.from(), segment_1.to());\n            let ctrl = LineSegment2F::new(ctrl, segment_1.to());\n            return Segment::cubic(baseline, ctrl);\n        }\n\n        let mut segment_0 = LineSegment2F::new(self.baseline.from(), self.ctrl.from());\n        let mut segment_1 = LineSegment2F::new(self.ctrl.from(), self.ctrl.to());\n        let mut segment_2 = LineSegment2F::new(self.ctrl.to(), self.baseline.to());\n        segment_0 = segment_0.offset(distance);\n        segment_1 = segment_1.offset(distance);\n        segment_2 = segment_2.offset(distance);\n        let (ctrl_0, ctrl_1) = match (\n            segment_0.intersection_t(segment_1),\n            segment_1.intersection_t(segment_2),\n        ) {\n            (Some(t0), Some(t1)) => (segment_0.sample(t0), segment_1.sample(t1)),\n            _ => (\n                segment_0.to().lerp(segment_1.from(), 0.5),\n                segment_1.to().lerp(segment_2.from(), 0.5),\n            ),\n        };\n        let baseline = LineSegment2F::new(segment_0.from(), segment_2.to());\n        let ctrl = LineSegment2F::new(ctrl_0, ctrl_1);\n        Segment::cubic(baseline, ctrl)\n    }\n\n    fn error_is_within_tolerance(&self, other: &Segment, distance: f32) -> bool {\n        let (mut min, mut max) = (\n            f32::abs(distance) - TOLERANCE,\n            f32::abs(distance) + TOLERANCE,\n        );\n        min = if min <= 0.0 { 0.0 } else { min * min };\n        max = if max <= 0.0 { 0.0 } else { max * max };\n\n        for t_num in 0..(SAMPLE_COUNT + 1) {\n            let t = t_num as f32 / SAMPLE_COUNT as f32;\n            // FIXME(pcwalton): Use signed distance!\n            let (this_p, other_p) = (self.sample(t), other.sample(t));\n            let vector = this_p - other_p;\n            let square_distance = vector.square_length();\n            debug!(\n                \"this_p={:?} other_p={:?} vector={:?} sqdist={:?} min={:?} max={:?}\",\n                this_p, other_p, vector, square_distance, min, max\n            );\n            if square_distance < min || square_distance > max {\n                return false;\n            }\n        }\n\n        return true;\n\n        const SAMPLE_COUNT: u32 = 16;\n    }\n}\n\nimpl Contour {\n    fn might_need_join(&self, join: LineJoin) -> bool {\n        if self.len() < 2 {\n            false\n        } else {\n            match join {\n                LineJoin::Miter(_) | LineJoin::Round => true,\n                LineJoin::Bevel => false,\n            }\n        }\n    }\n\n    fn add_join(&mut self,\n                distance: f32,\n                join: LineJoin,\n                join_point: Vector2F,\n                next_tangent: LineSegment2F) {\n        let (p0, p1) = (self.position_of_last(2), self.position_of_last(1));\n        let prev_tangent = LineSegment2F::new(p0, p1);\n\n        if prev_tangent.square_length() < EPSILON || next_tangent.square_length() < EPSILON {\n            return;\n        }\n\n        match join {\n            LineJoin::Bevel => {}\n            LineJoin::Miter(miter_limit) => {\n                if let Some(prev_tangent_t) = prev_tangent.intersection_t(next_tangent) {\n                    if prev_tangent_t < -EPSILON {\n                        return;\n                    }\n                    let miter_endpoint = prev_tangent.sample(prev_tangent_t);\n                    let threshold = miter_limit * distance;\n                    if (miter_endpoint - join_point).square_length() > threshold * threshold {\n                        return;\n                    }\n                    self.push_endpoint(miter_endpoint);\n                }\n            }\n            LineJoin::Round => {\n                let scale = distance.abs();\n                let transform = Transform2F::from_scale(scale).translate(join_point);\n                let chord_from = (prev_tangent.to() - join_point).normalize();\n                let chord_to = (next_tangent.to() - join_point).normalize();\n                let chord = LineSegment2F::new(chord_from, chord_to);\n                self.push_arc_from_unit_chord(&transform, chord, ArcDirection::CW);\n            }\n        }\n    }\n}\n\nimpl Default for StrokeStyle {\n    #[inline]\n    fn default() -> StrokeStyle {\n        StrokeStyle {\n            line_width: 1.0,\n            line_cap: LineCap::default(),\n            line_join: LineJoin::default(),\n        }\n    }\n}\n\nimpl Default for LineCap {\n    #[inline]\n    fn default() -> LineCap { LineCap::Butt }\n}\n\nimpl Default for LineJoin {\n    #[inline]\n    fn default() -> LineJoin { LineJoin::Miter(10.0) }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/transform.rs",
      "sha256": "4eb2c22dbfee166ba857a5173ef4df8428f36cd2ddd2786b9bcd34c8251db414",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/transform.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Utilities for transforming paths.\n\nuse crate::segment::Segment;\nuse pathfinder_geometry::transform2d::Transform2F;\nuse pathfinder_geometry::transform3d::Perspective;\n\n/// Transforms a path with a SIMD 2D transform.\npub struct Transform2FPathIter<I>\nwhere\n    I: Iterator<Item = Segment>,\n{\n    iter: I,\n    transform: Transform2F,\n}\n\nimpl<I> Iterator for Transform2FPathIter<I>\nwhere\n    I: Iterator<Item = Segment>,\n{\n    type Item = Segment;\n\n    #[inline]\n    fn next(&mut self) -> Option<Segment> {\n        // TODO(pcwalton): Can we go faster by transforming an entire line segment with SIMD?\n        let mut segment = self.iter.next()?;\n        if !segment.is_none() {\n            segment.baseline.set_from(self.transform * segment.baseline.from());\n            segment.baseline.set_to(self.transform * segment.baseline.to());\n            if !segment.is_line() {\n                segment.ctrl.set_from(self.transform * segment.ctrl.from());\n                if !segment.is_quadratic() {\n                    segment.ctrl.set_to(self.transform * segment.ctrl.to());\n                }\n            }\n        }\n        Some(segment)\n    }\n}\n\nimpl<I> Transform2FPathIter<I>\nwhere\n    I: Iterator<Item = Segment>,\n{\n    #[inline]\n    pub fn new(iter: I, transform: &Transform2F) -> Transform2FPathIter<I> {\n        Transform2FPathIter {\n            iter,\n            transform: *transform,\n        }\n    }\n}\n\n/// Transforms a path with a perspective projection.\npub struct PerspectivePathIter<I>\nwhere\n    I: Iterator<Item = Segment>,\n{\n    iter: I,\n    perspective: Perspective,\n}\n\nimpl<I> Iterator for PerspectivePathIter<I>\nwhere\n    I: Iterator<Item = Segment>,\n{\n    type Item = Segment;\n\n    #[inline]\n    fn next(&mut self) -> Option<Segment> {\n        let mut segment = self.iter.next()?;\n        if !segment.is_none() {\n            segment.baseline.set_from(self.perspective * segment.baseline.from());\n            segment.baseline.set_to(self.perspective * segment.baseline.to());\n            if !segment.is_line() {\n                segment.ctrl.set_from(self.perspective * segment.ctrl.from());\n                if !segment.is_quadratic() {\n                    segment.ctrl.set_to(self.perspective * segment.ctrl.to());\n                }\n            }\n        }\n        Some(segment)\n    }\n}\n\nimpl<I> PerspectivePathIter<I>\nwhere\n    I: Iterator<Item = Segment>,\n{\n    #[inline]\n    pub fn new(iter: I, perspective: &Perspective) -> PerspectivePathIter<I> {\n        PerspectivePathIter {\n            iter,\n            perspective: *perspective,\n        }\n    }\n}\n"
    },
    {
      "package": "pathfinder_content@0.5.0",
      "sourcePath": "src/util.rs",
      "sha256": "fed2ffe6642fad99f27905840920427d73138fccfd3fad0393326a56aa76ff19",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/content/src/util.rs\n//\n// Copyright © 2020 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Miscellaneous utilities.\n\nuse pathfinder_geometry::line_segment::LineSegment2F;\nuse pathfinder_geometry::transform2d::Transform2F;\nuse pathfinder_simd::default::{F32x2, F32x4};\nuse std::hash::{Hash, Hasher};\nuse std::mem;\n\npub(crate) fn hash_line_segment<H>(line_segment: LineSegment2F, state: &mut H) where H: Hasher {\n    hash_f32x4(line_segment.0, state);\n}\n\npub(crate) fn hash_transform2f<H>(transform: Transform2F, state: &mut H) where H: Hasher {\n    hash_f32x4(transform.matrix.0, state);\n    hash_f32x2(transform.vector.0, state);\n}\n\npub(crate) fn hash_f32<H>(value: f32, state: &mut H) where H: Hasher {\n    unsafe {\n        let data: u32 = mem::transmute::<f32, u32>(value);\n        data.hash(state);\n    }\n}\n\npub(crate) fn hash_f32x2<H>(vector: F32x2, state: &mut H) where H: Hasher {\n    unsafe {\n        let data: [u32; 2] = mem::transmute::<F32x2, [u32; 2]>(vector);\n        data.hash(state);\n    }\n}\n\npub(crate) fn hash_f32x4<H>(vector: F32x4, state: &mut H) where H: Hasher {\n    unsafe {\n        let data: [u32; 4] = mem::transmute::<F32x4, [u32; 4]>(vector);\n        data.hash(state);\n    }\n}\n"
    },
    {
      "package": "pathfinder_geometry@0.5.1",
      "sourcePath": "src/angle.rs",
      "sha256": "dce9c08facbaceccb920035477ac53ffc2798247b42b2ddef9338f2e35ab9c80",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/geometry/src/angle.rs\n//\n// Copyright © 2020 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Angle utilities.\n\nuse std::f32::consts::PI;\n\n#[inline]\npub fn angle_from_degrees(degrees: f32) -> f32 {\n    const SCALE: f32 = 2.0 * PI / 360.0;\n    degrees * SCALE\n}\n"
    },
    {
      "package": "pathfinder_geometry@0.5.1",
      "sourcePath": "src/lib.rs",
      "sha256": "cedfb2d85e682e9b9e327a169347bf0cebecd52668e1ed91a3af05ec91b42090",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/geometry/src/lib.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Basic geometry and linear algebra primitives, optimized with SIMD.\n\npub mod angle;\npub mod line_segment;\npub mod rect;\npub mod transform2d;\npub mod transform3d;\npub mod unit_vector;\npub mod util;\npub mod vector;\n"
    },
    {
      "package": "pathfinder_geometry@0.5.1",
      "sourcePath": "src/line_segment.rs",
      "sha256": "4af21598890aef0ffec10abd5460c0416cb1bb56b003fb499f0cd75fc68177da",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/geometry/src/basic/line_segment.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Line segment types, optimized with SIMD.\n\nuse crate::transform2d::Matrix2x2F;\nuse crate::vector::{Vector2F, vec2f};\nuse crate::util;\nuse pathfinder_simd::default::F32x4;\nuse std::ops::{Add, Mul, MulAssign, Sub};\n\n#[derive(Clone, Copy, Debug, PartialEq, Default)]\npub struct LineSegment2F(pub F32x4);\n\nimpl LineSegment2F {\n    #[inline]\n    pub fn new(from: Vector2F, to: Vector2F) -> LineSegment2F {\n        LineSegment2F(from.0.concat_xy_xy(to.0))\n    }\n\n    #[inline]\n    pub fn from(self) -> Vector2F {\n        Vector2F(self.0.xy())\n    }\n\n    #[inline]\n    pub fn to(self) -> Vector2F {\n        Vector2F(self.0.zw())\n    }\n\n    #[inline]\n    pub fn set_from(&mut self, point: Vector2F) {\n        self.0 = point.0.to_f32x4().concat_xy_zw(self.0)\n    }\n\n    #[inline]\n    pub fn set_to(&mut self, point: Vector2F) {\n        self.0 = self.0.concat_xy_xy(point.0.to_f32x4())\n    }\n\n    #[allow(clippy::wrong_self_convention)]\n    #[inline]\n    pub fn from_x(self) -> f32 {\n        self.0[0]\n    }\n\n    #[allow(clippy::wrong_self_convention)]\n    #[inline]\n    pub fn from_y(self) -> f32 {\n        self.0[1]\n    }\n\n    #[inline]\n    pub fn to_x(self) -> f32 {\n        self.0[2]\n    }\n\n    #[inline]\n    pub fn to_y(self) -> f32 {\n        self.0[3]\n    }\n\n    #[inline]\n    pub fn set_from_x(&mut self, x: f32) {\n        self.0[0] = x\n    }\n\n    #[inline]\n    pub fn set_from_y(&mut self, y: f32) {\n        self.0[1] = y\n    }\n\n    #[inline]\n    pub fn set_to_x(&mut self, x: f32) {\n        self.0[2] = x\n    }\n\n    #[inline]\n    pub fn set_to_y(&mut self, y: f32) {\n        self.0[3] = y\n    }\n\n    #[inline]\n    pub fn split(self, t: f32) -> (LineSegment2F, LineSegment2F) {\n        debug_assert!(t >= 0.0 && t <= 1.0);\n        let (from_from, to_to) = (self.0.xyxy(), self.0.zwzw());\n        let d_d = to_to - from_from;\n        let mid_mid = from_from + d_d * F32x4::splat(t);\n        (\n            LineSegment2F(from_from.concat_xy_xy(mid_mid)),\n            LineSegment2F(mid_mid.concat_xy_xy(to_to)),\n        )\n    }\n\n    // Returns the left segment first, followed by the right segment.\n    #[inline]\n    pub fn split_at_x(self, x: f32) -> (LineSegment2F, LineSegment2F) {\n        let (min_part, max_part) = self.split(self.solve_t_for_x(x));\n        if min_part.from_x() < max_part.from_x() {\n            (min_part, max_part)\n        } else {\n            (max_part, min_part)\n        }\n    }\n\n    // Returns the upper segment first, followed by the lower segment.\n    #[inline]\n    pub fn split_at_y(self, y: f32) -> (LineSegment2F, LineSegment2F) {\n        let (min_part, max_part) = self.split(self.solve_t_for_y(y));\n\n        // Make sure we compare `from_y` and `to_y` to properly handle the case in which one of the\n        // two segments is zero-length.\n        if min_part.from_y() < max_part.to_y() {\n            (min_part, max_part)\n        } else {\n            (max_part, min_part)\n        }\n    }\n\n    #[inline]\n    pub fn solve_t_for_x(self, x: f32) -> f32 {\n        (x - self.from_x()) / (self.to_x() - self.from_x())\n    }\n\n    #[inline]\n    pub fn solve_t_for_y(self, y: f32) -> f32 {\n        (y - self.from_y()) / (self.to_y() - self.from_y())\n    }\n\n    #[inline]\n    pub fn solve_x_for_y(self, y: f32) -> f32 {\n        util::lerp(self.from_x(), self.to_x(), self.solve_t_for_y(y))\n    }\n\n    #[inline]\n    pub fn solve_y_for_x(self, x: f32) -> f32 {\n        util::lerp(self.from_y(), self.to_y(), self.solve_t_for_x(x))\n    }\n\n    #[inline]\n    pub fn reversed(self) -> LineSegment2F {\n        LineSegment2F(self.0.zwxy())\n    }\n\n    #[inline]\n    pub fn upper_point(self) -> Vector2F {\n        if self.from_y() < self.to_y() {\n            self.from()\n        } else {\n            self.to()\n        }\n    }\n\n    #[inline]\n    pub fn min_x(self) -> f32 {\n        f32::min(self.from_x(), self.to_x())\n    }\n\n    #[inline]\n    pub fn max_x(self) -> f32 {\n        f32::max(self.from_x(), self.to_x())\n    }\n\n    #[inline]\n    pub fn min_y(self) -> f32 {\n        f32::min(self.from_y(), self.to_y())\n    }\n\n    #[inline]\n    pub fn max_y(self) -> f32 {\n        f32::max(self.from_y(), self.to_y())\n    }\n\n    #[inline]\n    pub fn y_winding(self) -> i32 {\n        if self.from_y() < self.to_y() {\n            1\n        } else {\n            -1\n        }\n    }\n\n    // Reverses if necessary so that the from point is above the to point. Calling this method\n    // again will undo the transformation.\n    #[inline]\n    pub fn orient(self, y_winding: i32) -> LineSegment2F {\n        if y_winding >= 0 {\n            self\n        } else {\n            self.reversed()\n        }\n    }\n\n    // TODO(pcwalton): Optimize with SIMD.\n    #[inline]\n    pub fn square_length(self) -> f32 {\n        let (dx, dy) = (self.to_x() - self.from_x(), self.to_y() - self.from_y());\n        dx * dx + dy * dy\n    }\n\n    #[inline]\n    pub fn vector(self) -> Vector2F {\n        self.to() - self.from()\n    }\n\n    // http://www.cs.swan.ac.uk/~cssimon/line_intersection.html\n    pub fn intersection_t(self, other: LineSegment2F) -> Option<f32> {\n        let p0p1 = self.vector();\n        let matrix = Matrix2x2F(other.vector().0.concat_xy_xy((-p0p1).0));\n        if f32::abs(matrix.det()) < EPSILON {\n            return None;\n        }\n        return Some((matrix.inverse() * (self.from() - other.from())).y());\n\n        const EPSILON: f32 = 0.0001;\n    }\n\n    #[inline]\n    pub fn sample(self, t: f32) -> Vector2F {\n        self.from() + self.vector() * t\n    }\n\n    #[inline]\n    pub fn midpoint(self) -> Vector2F {\n        self.sample(0.5)\n    }\n\n    #[inline]\n    pub fn offset(self, distance: f32) -> LineSegment2F {\n        if self.is_zero_length() {\n            self\n        } else {\n            self + self.vector().yx().normalize() * vec2f(-distance, distance)\n        }\n    }\n\n    #[inline]\n    pub fn is_zero_length(self) -> bool {\n        self.vector().is_zero()\n    }\n}\n\nimpl Add<Vector2F> for LineSegment2F {\n    type Output = LineSegment2F;\n    #[inline]\n    fn add(self, point: Vector2F) -> LineSegment2F {\n        LineSegment2F(self.0 + point.0.to_f32x4().xyxy())\n    }\n}\n\nimpl Sub<Vector2F> for LineSegment2F {\n    type Output = LineSegment2F;\n    #[inline]\n    fn sub(self, point: Vector2F) -> LineSegment2F {\n        LineSegment2F(self.0 - point.0.to_f32x4().xyxy())\n    }\n}\n\nimpl Mul<Vector2F> for LineSegment2F {\n    type Output = LineSegment2F;\n    #[inline]\n    fn mul(self, factors: Vector2F) -> LineSegment2F {\n        LineSegment2F(self.0 * factors.0.to_f32x4().xyxy())\n    }\n}\n\nimpl Mul<f32> for LineSegment2F {\n    type Output = LineSegment2F;\n    #[inline]\n    fn mul(self, factor: f32) -> LineSegment2F {\n        LineSegment2F(self.0 * F32x4::splat(factor))\n    }\n}\n\nimpl MulAssign<Vector2F> for LineSegment2F {\n    #[inline]\n    fn mul_assign(&mut self, factors: Vector2F) {\n        *self = *self * factors\n    }\n}\n\n#[derive(Clone, Copy, Debug, Default)]\n#[repr(C)]\npub struct LineSegmentU4 {\n    pub from: u8,\n    pub to: u8,\n}\n\n#[derive(Clone, Copy, Debug, Default)]\n#[repr(C)]\npub struct LineSegmentU8 {\n    pub from_x: u8,\n    pub from_y: u8,\n    pub to_x: u8,\n    pub to_y: u8,\n}\n"
    },
    {
      "package": "pathfinder_geometry@0.5.1",
      "sourcePath": "src/rect.rs",
      "sha256": "68d48ddd9934ac11f0ed0e81c2cc6ede9271528dc318c3dd49cc9c9f51cb15ca",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/geometry/src/basic/rect.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! 2D axis-aligned rectangles, optimized with SIMD.\n\nuse crate::vector::{IntoVector2F, Vector2F, Vector2I};\nuse pathfinder_simd::default::{F32x4, I32x4};\nuse std::ops::{Add, Mul, Sub};\n\n#[derive(Clone, Copy, Debug, PartialEq, Default)]\npub struct RectF(pub F32x4);\n\nimpl RectF {\n    #[inline]\n    pub fn new(origin: Vector2F, size: Vector2F) -> RectF {\n        RectF(origin.0.concat_xy_xy(origin.0 + size.0))\n    }\n\n    #[inline]\n    pub fn from_points(origin: Vector2F, lower_right: Vector2F) -> RectF {\n        RectF(origin.0.concat_xy_xy(lower_right.0))\n    }\n\n    // Accessors\n\n    #[inline]\n    pub fn origin(self) -> Vector2F {\n        Vector2F(self.0.xy())\n    }\n\n    #[inline]\n    pub fn size(self) -> Vector2F {\n        Vector2F(self.0.zw() - self.0.xy())\n    }\n\n    #[inline]\n    pub fn origin_x(self) -> f32 {\n        self.0.x()\n    }\n\n    #[inline]\n    pub fn origin_y(self) -> f32 {\n        self.0.y()\n    }\n\n    #[inline]\n    pub fn width(self) -> f32 {\n        self.0.z() - self.0.x()\n    }\n\n    #[inline]\n    pub fn height(self) -> f32 {\n        self.0.w() - self.0.y()\n    }\n\n    #[inline]\n    pub fn upper_right(self) -> Vector2F {\n        Vector2F(self.0.zy())\n    }\n\n    #[inline]\n    pub fn lower_left(self) -> Vector2F {\n        Vector2F(self.0.xw())\n    }\n\n    #[inline]\n    pub fn lower_right(self) -> Vector2F {\n        Vector2F(self.0.zw())\n    }\n\n    // Mutators\n\n    #[inline]\n    pub fn set_origin_x(&mut self, x: f32) {\n        self.0.set_x(x)\n    }\n\n    #[inline]\n    pub fn set_origin_y(&mut self, y: f32) {\n        self.0.set_y(y)\n    }\n\n    #[inline]\n    pub fn contains_point(self, point: Vector2F) -> bool {\n        // self.origin <= point && point <= self.lower_right\n        let point = point.0.to_f32x4();\n        self.0.concat_xy_xy(point).packed_le(point.concat_xy_zw(self.0)).all_true()\n    }\n\n    #[inline]\n    pub fn contains_rect(self, other: RectF) -> bool {\n        // self.origin <= other.origin && other.lower_right <= self.lower_right\n        self.0.concat_xy_zw(other.0).packed_le(other.0.concat_xy_zw(self.0)).all_true()\n    }\n\n    #[inline]\n    pub fn is_empty(self) -> bool {\n        self.origin() == self.lower_right()\n    }\n\n    #[inline]\n    pub fn union_point(self, point: Vector2F) -> RectF {\n        RectF::from_points(self.origin().min(point), self.lower_right().max(point))\n    }\n\n    #[inline]\n    pub fn union_rect(self, other: RectF) -> RectF {\n        RectF::from_points(\n            self.origin().min(other.origin()),\n            self.lower_right().max(other.lower_right()),\n        )\n    }\n\n    #[inline]\n    pub fn intersects(self, other: RectF) -> bool {\n        // self.origin < other.lower_right && other.origin < self.lower_right\n        self.0.concat_xy_xy(other.0).packed_lt(other.0.concat_zw_zw(self.0)).all_true()\n    }\n\n    #[inline]\n    pub fn intersection(self, other: RectF) -> Option<RectF> {\n        if !self.intersects(other) {\n            None\n        } else {\n            Some(RectF::from_points(\n                self.origin().max(other.origin()),\n                self.lower_right().min(other.lower_right()),\n            ))\n        }\n    }\n\n    #[inline]\n    pub fn min_x(self) -> f32 {\n        self.0[0]\n    }\n\n    #[inline]\n    pub fn min_y(self) -> f32 {\n        self.0[1]\n    }\n\n    #[inline]\n    pub fn max_x(self) -> f32 {\n        self.0[2]\n    }\n\n    #[inline]\n    pub fn max_y(self) -> f32 {\n        self.0[3]\n    }\n\n    #[inline]\n    pub fn center(self) -> Vector2F {\n        self.origin() + self.size() * 0.5\n    }\n\n    /// Rounds all points to the nearest integer.\n    #[inline]\n    pub fn round(self) -> RectF {\n        RectF(self.0.to_i32x4().to_f32x4())\n    }\n\n    #[inline]\n    pub fn round_out(self) -> RectF {\n        RectF::from_points(self.origin().floor(), self.lower_right().ceil())\n    }\n\n    #[inline]\n    pub fn dilate<A>(self, amount: A) -> RectF where A: IntoVector2F {\n        let amount = amount.into_vector_2f();\n        RectF::from_points(self.origin() - amount, self.lower_right() + amount)\n    }\n\n    #[inline]\n    pub fn contract<A>(self, amount: A) -> RectF where A: IntoVector2F {\n        let amount = amount.into_vector_2f();\n        RectF::from_points(self.origin() + amount, self.lower_right() - amount)\n    }\n\n    #[inline]\n    pub fn to_i32(&self) -> RectI {\n        RectI(self.0.to_i32x4())\n    }\n}\n\nimpl Add<Vector2F> for RectF {\n    type Output = RectF;\n    #[inline]\n    fn add(self, other: Vector2F) -> RectF {\n        RectF::new(self.origin() + other, self.size())\n    }\n}\n\nimpl Add<f32> for RectF {\n    type Output = RectF;\n    #[inline]\n    fn add(self, other: f32) -> RectF {\n        RectF::new(self.origin() + other, self.size())\n    }\n}\n\nimpl Mul<Vector2F> for RectF {\n    type Output = RectF;\n    #[inline]\n    fn mul(self, factors: Vector2F) -> RectF {\n        RectF(self.0 * factors.0.concat_xy_xy(factors.0))\n    }\n}\n\nimpl Mul<f32> for RectF {\n    type Output = RectF;\n    #[inline]\n    fn mul(self, factor: f32) -> RectF {\n        RectF(self.0 * F32x4::splat(factor))\n    }\n}\n\nimpl Sub<Vector2F> for RectF {\n    type Output = RectF;\n    #[inline]\n    fn sub(self, other: Vector2F) -> RectF {\n        RectF::new(self.origin() - other, self.size())\n    }\n}\n\nimpl Sub<f32> for RectF {\n    type Output = RectF;\n    #[inline]\n    fn sub(self, other: f32) -> RectF {\n        RectF::new(self.origin() - other, self.size())\n    }\n}\n\n/// NB: The origin is inclusive, while the lower right point is exclusive.\n#[derive(Clone, Copy, Debug, PartialEq, Default)]\npub struct RectI(pub I32x4);\n\nimpl RectI {\n    #[inline]\n    pub fn new(origin: Vector2I, size: Vector2I) -> RectI {\n        RectI(origin.0.concat_xy_xy(origin.0 + size.0))\n    }\n\n    #[inline]\n    pub fn from_points(origin: Vector2I, lower_right: Vector2I) -> RectI {\n        RectI(origin.0.concat_xy_xy(lower_right.0))\n    }\n\n    // Accessors\n\n    #[inline]\n    pub fn origin(&self) -> Vector2I {\n        Vector2I(self.0.xy())\n    }\n\n    #[inline]\n    pub fn size(&self) -> Vector2I {\n        Vector2I(self.0.zw() - self.0.xy())\n    }\n\n    #[inline]\n    pub fn origin_x(self) -> i32 {\n        self.0.x()\n    }\n\n    #[inline]\n    pub fn origin_y(self) -> i32 {\n        self.0.y()\n    }\n\n    #[inline]\n    pub fn width(self) -> i32 {\n        self.0.z() - self.0.x()\n    }\n\n    #[inline]\n    pub fn height(self) -> i32 {\n        self.0.w() - self.0.y()\n    }\n\n    #[inline]\n    pub fn upper_right(&self) -> Vector2I {\n        Vector2I(self.0.zy())\n    }\n\n    #[inline]\n    pub fn lower_left(&self) -> Vector2I {\n        Vector2I(self.0.xw())\n    }\n\n    #[inline]\n    pub fn lower_right(&self) -> Vector2I {\n        Vector2I(self.0.zw())\n    }\n\n    #[inline]\n    pub fn scale(self, factor: i32) -> RectI {\n        RectI(self.0 * I32x4::splat(factor))\n    }\n\n    #[inline]\n    pub fn scale_xy(self, factors: Vector2I) -> RectI {\n        RectI(self.0 * factors.0.concat_xy_xy(factors.0))\n    }\n\n    #[inline]\n    pub fn min_x(self) -> i32 {\n        self.0[0]\n    }\n\n    #[inline]\n    pub fn min_y(self) -> i32 {\n        self.0[1]\n    }\n\n    #[inline]\n    pub fn max_x(self) -> i32 {\n        self.0[2]\n    }\n\n    #[inline]\n    pub fn max_y(self) -> i32 {\n        self.0[3]\n    }\n\n    #[inline]\n    pub fn intersects(self, other: RectI) -> bool {\n        // self.origin < other.lower_right && other.origin < self.lower_right\n        self.0.concat_xy_xy(other.0).packed_lt(other.0.concat_zw_zw(self.0)).all_true()\n    }\n\n    #[inline]\n    pub fn intersection(self, other: RectI) -> Option<RectI> {\n        if !self.intersects(other) {\n            None\n        } else {\n            Some(RectI::from_points(\n                self.origin().max(other.origin()),\n                self.lower_right().min(other.lower_right()),\n            ))\n        }\n    }\n\n    #[inline]\n    pub fn contains_point(&self, point: Vector2I) -> bool {\n        // self.origin <= point && point <= self.lower_right - 1\n        let lower_right = self.lower_right() - 1;\n        self.origin()\n            .0\n            .concat_xy_xy(point.0)\n            .packed_le(point.0.concat_xy_xy(lower_right.0))\n            .all_true()\n    }\n\n    #[inline]\n    pub fn contract(self, amount: Vector2I) -> RectI {\n        RectI::from_points(self.origin() + amount, self.lower_right() - amount)\n    }\n\n    #[inline]\n    pub fn to_f32(&self) -> RectF {\n        RectF(self.0.to_f32x4())\n    }\n}\n"
    },
    {
      "package": "pathfinder_geometry@0.5.1",
      "sourcePath": "src/transform2d.rs",
      "sha256": "36514cf158f7bd2118a1e2f2586e439f6484d61f0505919e8005fb733e3c917c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/geometry/src/basic/transform2d.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! 2D affine transforms.\n\nuse crate::line_segment::LineSegment2F;\nuse crate::rect::RectF;\nuse crate::transform3d::Transform4F;\nuse crate::unit_vector::UnitVector;\nuse crate::vector::{IntoVector2F, Vector2F, vec2f};\nuse pathfinder_simd::default::F32x4;\nuse std::ops::{Mul, MulAssign, Sub};\n\n/// A 2x2 matrix, optimized with SIMD, in column-major order.\n#[derive(Clone, Copy, Debug, PartialEq)]\npub struct Matrix2x2F(pub F32x4);\n\nimpl Default for Matrix2x2F {\n    #[inline]\n    fn default() -> Matrix2x2F {\n        Self::from_scale(1.0)\n    }\n}\n\nimpl Matrix2x2F {\n    #[inline]\n    pub fn from_scale<S>(scale: S) -> Matrix2x2F where S: IntoVector2F {\n        let scale = scale.into_vector_2f();\n        Matrix2x2F(F32x4::new(scale.x(), 0.0, 0.0, scale.y()))\n    }\n\n    #[inline]\n    pub fn from_rotation(theta: f32) -> Matrix2x2F {\n        Matrix2x2F::from_rotation_vector(UnitVector::from_angle(theta))\n    }\n\n    #[inline]\n    pub fn from_rotation_vector(vector: UnitVector) -> Matrix2x2F {\n        Matrix2x2F((vector.0).0.to_f32x4().xyyx() * F32x4::new(1.0, 1.0, -1.0, 1.0))\n    }\n\n    #[inline]\n    pub fn row_major(m00: f32, m01: f32, m10: f32, m11: f32) -> Matrix2x2F {\n        Matrix2x2F(F32x4::new(m00, m10, m01, m11))\n    }\n\n    #[inline]\n    pub fn entrywise_mul(&self, other: &Matrix2x2F) -> Matrix2x2F {\n        Matrix2x2F(self.0 * other.0)\n    }\n\n    #[inline]\n    pub fn adjugate(&self) -> Matrix2x2F {\n        Matrix2x2F(self.0.wyzx() * F32x4::new(1.0, -1.0, -1.0, 1.0))\n    }\n\n    #[inline]\n    pub fn det(&self) -> f32 {\n        self.0[0] * self.0[3] - self.0[2] * self.0[1]\n    }\n\n    #[inline]\n    pub fn inverse(&self) -> Matrix2x2F {\n        Matrix2x2F(F32x4::splat(1.0 / self.det()) * self.adjugate().0)\n    }\n\n    #[inline]\n    pub fn scale(&self, factor: f32) -> Matrix2x2F {\n        Matrix2x2F(self.0 * F32x4::splat(factor))\n    }\n\n    /// Extracts the scale from this matrix.\n    #[inline]\n    pub fn extract_scale(&self) -> Vector2F {\n        let squared = self.0 * self.0;\n        Vector2F((squared.xy() + squared.zw()).sqrt())\n    }\n\n    #[inline]\n    pub fn m11(&self) -> f32 {\n        self.0[0]\n    }\n\n    #[inline]\n    pub fn m21(&self) -> f32 {\n        self.0[1]\n    }\n\n    #[inline]\n    pub fn m12(&self) -> f32 {\n        self.0[2]\n    }\n\n    #[inline]\n    pub fn m22(&self) -> f32 {\n        self.0[3]\n    }\n}\n\nimpl Sub<Matrix2x2F> for Matrix2x2F {\n    type Output = Matrix2x2F;\n    #[inline]\n    fn sub(self, other: Matrix2x2F) -> Matrix2x2F {\n        Matrix2x2F(self.0 - other.0)\n    }\n}\n\nimpl Mul<Matrix2x2F> for Matrix2x2F {\n    type Output = Matrix2x2F;\n    #[inline]\n    fn mul(self, other: Matrix2x2F) -> Matrix2x2F {\n        Matrix2x2F(self.0.xyxy() * other.0.xxzz() + self.0.zwzw() * other.0.yyww())\n    }\n}\n\nimpl Mul<Vector2F> for Matrix2x2F {\n    type Output = Vector2F;\n    #[inline]\n    fn mul(self, vector: Vector2F) -> Vector2F {\n        let halves = self.0 * vector.0.to_f32x4().xxyy();\n        Vector2F(halves.xy() + halves.zw())\n    }\n}\n\n/// An affine transform, optimized with SIMD.\n#[derive(Clone, Copy, Debug, PartialEq)]\npub struct Transform2F {\n    pub matrix: Matrix2x2F,\n    pub vector: Vector2F,\n}\n\nimpl Default for Transform2F {\n    #[inline]\n    fn default() -> Transform2F {\n        Self::from_scale(vec2f(1.0, 1.0))\n    }\n}\n\nimpl Transform2F {\n    #[inline]\n    pub fn from_scale<S>(scale: S) -> Transform2F where S: IntoVector2F {\n        let scale = scale.into_vector_2f();\n        Transform2F {\n            matrix: Matrix2x2F::from_scale(scale),\n            vector: Vector2F::zero(),\n        }\n    }\n\n    #[inline]\n    pub fn from_rotation(theta: f32) -> Transform2F {\n        Transform2F {\n            matrix: Matrix2x2F::from_rotation(theta),\n            vector: Vector2F::zero(),\n        }\n    }\n\n    #[inline]\n    pub fn from_rotation_vector(vector: UnitVector) -> Transform2F {\n        Transform2F {\n            matrix: Matrix2x2F::from_rotation_vector(vector),\n            vector: Vector2F::zero(),\n        }\n    }\n\n    #[inline]\n    pub fn from_translation(vector: Vector2F) -> Transform2F {\n        Transform2F { matrix: Matrix2x2F::default(), vector }\n    }\n\n    #[inline]\n    pub fn from_scale_rotation_translation<S>(scale: S, theta: f32, translation: Vector2F)\n                                              -> Transform2F where S: IntoVector2F {\n        let scale = scale.into_vector_2f();\n        let rotation = Transform2F::from_rotation(theta);\n        let translation = Transform2F::from_translation(translation);\n        Transform2F::from_scale(scale) * rotation * translation\n    }\n\n    #[inline]\n    pub fn row_major(m11: f32, m12: f32, m21: f32, m22: f32, m31: f32, m32: f32) -> Transform2F {\n        Transform2F {\n            matrix: Matrix2x2F::row_major(m11, m12, m21, m22),\n            vector: Vector2F::new(m31, m32),\n        }\n    }\n\n    // TODO(pcwalton): Optimize better with SIMD.\n    #[inline]\n    pub fn to_3d(&self) -> Transform4F {\n        Transform4F::row_major(\n            self.matrix.0[0],\n            self.matrix.0[1],\n            0.0,\n            self.vector.x(),\n            self.matrix.0[2],\n            self.matrix.0[3],\n            0.0,\n            self.vector.y(),\n            0.0,\n            0.0,\n            0.0,\n            0.0,\n            0.0,\n            0.0,\n            0.0,\n            1.0,\n        )\n    }\n\n    #[inline]\n    pub fn is_identity(&self) -> bool {\n        *self == Transform2F::default()\n    }\n\n    /// Extracts the scale from this matrix.\n    #[inline]\n    pub fn extract_scale(&self) -> Vector2F {\n        self.matrix.extract_scale()\n    }\n\n    #[inline]\n    pub fn m11(&self) -> f32 {\n        self.matrix.m11()\n    }\n    #[inline]\n    pub fn m21(&self) -> f32 {\n        self.matrix.m21()\n    }\n    #[inline]\n    pub fn m12(&self) -> f32 {\n        self.matrix.m12()\n    }\n    #[inline]\n    pub fn m22(&self) -> f32 {\n        self.matrix.m22()\n    }\n    #[inline]\n    pub fn m31(&self) -> f32 {\n        self.vector.x()\n    }\n    #[inline]\n    pub fn m32(&self) -> f32 {\n        self.vector.y()\n    }\n\n    #[inline]\n    pub fn translate(&self, vector: Vector2F) -> Transform2F {\n        Transform2F::from_translation(vector) * *self\n    }\n\n    #[inline]\n    pub fn rotate(&self, theta: f32) -> Transform2F {\n        Transform2F::from_rotation(theta) * *self\n    }\n\n    #[inline]\n    pub fn scale<S>(&self, scale: S) -> Transform2F where S: IntoVector2F {\n        let scale = scale.into_vector_2f();\n        Transform2F::from_scale(scale) * *self\n    }\n\n    /// Returns the translation part of this matrix.\n    ///\n    /// This decomposition assumes that scale, rotation, and translation are applied in that order.\n    #[inline]\n    pub fn translation(&self) -> Vector2F {\n        self.vector\n    }\n\n    /// Returns the rotation angle of this matrix.\n    ///\n    /// This decomposition assumes that scale, rotation, and translation are applied in that order.\n    #[inline]\n    pub fn rotation(&self) -> f32 {\n        f32::atan2(self.m21(), self.m11())\n    }\n\n    /// Returns the scale factor of this matrix.\n    ///\n    /// This decomposition assumes that scale, rotation, and translation are applied in that order.\n    #[inline]\n    pub fn scale_factor(&self) -> f32 {\n        Vector2F(self.matrix.0.zw()).length()\n    }\n\n    #[inline]\n    pub fn inverse(&self) -> Transform2F {\n        let matrix_inv = self.matrix.inverse();\n        let vector_inv = -(matrix_inv * self.vector);\n        Transform2F { matrix: matrix_inv, vector: vector_inv }\n    }\n}\n\nimpl Mul<Transform2F> for Transform2F {\n    type Output = Transform2F;\n    #[inline]\n    fn mul(self, other: Transform2F) -> Transform2F {\n        Transform2F {\n            matrix: self.matrix * other.matrix,\n            vector: self * other.vector,\n        }\n    }\n}\n\nimpl Mul<Vector2F> for Transform2F {\n    type Output = Vector2F;\n    #[inline]\n    fn mul(self, vector: Vector2F) -> Vector2F {\n        self.matrix * vector + self.vector\n    }\n}\n\nimpl Mul<LineSegment2F> for Transform2F {\n    type Output = LineSegment2F;\n    #[inline]\n    fn mul(self, line_segment: LineSegment2F) -> LineSegment2F {\n        LineSegment2F::new(self * line_segment.from(), self * line_segment.to())\n    }\n}\n\nimpl Mul<RectF> for Transform2F {\n    type Output = RectF;\n    #[inline]\n    fn mul(self, rect: RectF) -> RectF {\n        let (upper_left, upper_right) = (self * rect.origin(),     self * rect.upper_right());\n        let (lower_left, lower_right) = (self * rect.lower_left(), self * rect.lower_right());\n        let min_point = upper_left.min(upper_right).min(lower_left).min(lower_right);\n        let max_point = upper_left.max(upper_right).max(lower_left).max(lower_right);\n        RectF::from_points(min_point, max_point)\n    }\n}\n\nimpl MulAssign for Transform2F {\n    #[inline]\n    fn mul_assign(&mut self, other: Transform2F) {\n        *self = *self * other\n    }\n}\n"
    },
    {
      "package": "pathfinder_geometry@0.5.1",
      "sourcePath": "src/transform3d.rs",
      "sha256": "d42aa24d02570376c429256f24891f489bd71ef257d9691f80b4fb6528e09275",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/geometry/src/basic/transform3d.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! 3D transforms that can be applied to paths.\n\nuse crate::rect::RectF;\nuse crate::transform2d::Matrix2x2F;\nuse crate::vector::{Vector2F, Vector2I, Vector3F, Vector4F};\nuse pathfinder_simd::default::F32x4;\nuse std::ops::{Add, Mul, MulAssign, Neg};\n\n/// An transform, optimized with SIMD.\n///\n/// In column-major order.\n#[derive(Clone, Copy, Debug, PartialEq)]\n#[repr(C)]\npub struct Transform4F {\n    pub c0: F32x4,\n    pub c1: F32x4,\n    pub c2: F32x4,\n    pub c3: F32x4,\n}\n\nimpl Default for Transform4F {\n    #[inline]\n    fn default() -> Transform4F {\n        Transform4F {\n            c0: F32x4::new(1.0, 0.0, 0.0, 0.0),\n            c1: F32x4::new(0.0, 1.0, 0.0, 0.0),\n            c2: F32x4::new(0.0, 0.0, 1.0, 0.0),\n            c3: F32x4::new(0.0, 0.0, 0.0, 1.0),\n        }\n    }\n}\n\nimpl Transform4F {\n    #[inline]\n    pub fn row_major(\n        m00: f32,\n        m01: f32,\n        m02: f32,\n        m03: f32,\n        m10: f32,\n        m11: f32,\n        m12: f32,\n        m13: f32,\n        m20: f32,\n        m21: f32,\n        m22: f32,\n        m23: f32,\n        m30: f32,\n        m31: f32,\n        m32: f32,\n        m33: f32,\n    ) -> Transform4F {\n        Transform4F {\n            c0: F32x4::new(m00, m10, m20, m30),\n            c1: F32x4::new(m01, m11, m21, m31),\n            c2: F32x4::new(m02, m12, m22, m32),\n            c3: F32x4::new(m03, m13, m23, m33),\n        }\n    }\n\n    #[inline]\n    pub fn from_scale(scale: Vector4F) -> Transform4F {\n        Transform4F {\n            c0: F32x4::new(scale.x(), 0.0, 0.0, 0.0),\n            c1: F32x4::new(0.0, scale.y(), 0.0, 0.0),\n            c2: F32x4::new(0.0, 0.0, scale.z(), 0.0),\n            c3: F32x4::new(0.0, 0.0, 0.0,       1.0),\n        }\n    }\n\n    #[inline]\n    pub fn from_uniform_scale(factor: f32) -> Transform4F {\n        Transform4F::from_scale(Vector4F::splat(factor))\n    }\n\n    #[inline]\n    pub fn from_translation(mut translation: Vector4F) -> Transform4F {\n        translation.set_w(1.0);\n        Transform4F { c3: translation.0, ..Transform4F::default() }\n    }\n\n    // TODO(pcwalton): Optimize.\n    pub fn from_rotation(yaw: f32, pitch: f32, roll: f32) -> Transform4F {\n        let (cos_b, sin_b) = (yaw.cos(), yaw.sin());\n        let (cos_c, sin_c) = (pitch.cos(), pitch.sin());\n        let (cos_a, sin_a) = (roll.cos(), roll.sin());\n        let m00 = cos_a * cos_b;\n        let m01 = cos_a * sin_b * sin_c - sin_a * cos_c;\n        let m02 = cos_a * sin_b * cos_c + sin_a * sin_c;\n        let m10 = sin_a * cos_b;\n        let m11 = sin_a * sin_b * sin_c + cos_a * cos_c;\n        let m12 = sin_a * sin_b * cos_c - cos_a * sin_c;\n        let m20 = -sin_b;\n        let m21 = cos_b * sin_c;\n        let m22 = cos_b * cos_c;\n        Transform4F::row_major(\n            m00, m01, m02, 0.0, m10, m11, m12, 0.0, m20, m21, m22, 0.0, 0.0, 0.0, 0.0, 1.0,\n        )\n    }\n\n    /// Creates a rotation matrix from the given quaternion.\n    ///\n    /// The quaternion is expected to be packed into a SIMD type (x, y, z, w) corresponding to\n    /// x + yi + zj + wk.\n    pub fn from_rotation_quaternion(q: F32x4) -> Transform4F {\n        // TODO(pcwalton): Optimize better with more shuffles.\n        let (mut sq, mut w, mut xy_xz_yz) = (q * q, q.wwww() * q, q.xxyy() * q.yzzy());\n        sq += sq;\n        w += w;\n        xy_xz_yz += xy_xz_yz;\n        let diag = F32x4::splat(1.0) - (sq.yxxy() + sq.zzyy());\n        let (wx2, wy2, wz2) = (w.x(), w.y(), w.z());\n        let (xy2, xz2, yz2) = (xy_xz_yz.x(), xy_xz_yz.y(), xy_xz_yz.z());\n        Transform4F::row_major(\n            diag.x(),\n            xy2 - wz2,\n            xz2 + wy2,\n            0.0,\n            xy2 + wz2,\n            diag.y(),\n            yz2 - wx2,\n            0.0,\n            xz2 - wy2,\n            yz2 + wx2,\n            diag.z(),\n            0.0,\n            0.0,\n            0.0,\n            0.0,\n            1.0,\n        )\n    }\n\n    /// Just like `glOrtho()`.\n    #[inline]\n    pub fn from_ortho(\n        left: f32,\n        right: f32,\n        bottom: f32,\n        top: f32,\n        near_val: f32,\n        far_val: f32,\n    ) -> Transform4F {\n        let x_inv = 1.0 / (right - left);\n        let y_inv = 1.0 / (top - bottom);\n        let z_inv = 1.0 / (far_val - near_val);\n        let tx = -(right + left) * x_inv;\n        let ty = -(top + bottom) * y_inv;\n        let tz = -(far_val + near_val) * z_inv;\n        Transform4F::row_major(\n            2.0 * x_inv,\n            0.0,\n            0.0,\n            tx,\n            0.0,\n            2.0 * y_inv,\n            0.0,\n            ty,\n            0.0,\n            0.0,\n            -2.0 * z_inv,\n            tz,\n            0.0,\n            0.0,\n            0.0,\n            1.0,\n        )\n    }\n\n    /// Linearly interpolate between transforms\n    pub fn lerp(&self, weight: f32, other: &Transform4F) -> Transform4F {\n        let c0 = self.c0 * F32x4::splat(weight) + other.c0 * F32x4::splat(1.0 - weight);\n        let c1 = self.c1 * F32x4::splat(weight) + other.c1 * F32x4::splat(1.0 - weight);\n        let c2 = self.c2 * F32x4::splat(weight) + other.c2 * F32x4::splat(1.0 - weight);\n        let c3 = self.c3 * F32x4::splat(weight) + other.c3 * F32x4::splat(1.0 - weight);\n        Transform4F { c0, c1, c2, c3 }\n    }\n\n    /// Just like `gluPerspective()`.\n    #[inline]\n    pub fn from_perspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) -> Transform4F {\n        let f = 1.0 / (fov_y * 0.5).tan();\n        let z_denom = 1.0 / (z_near - z_far);\n        let m00 = f / aspect;\n        let m11 = f;\n        let m22 = (z_far + z_near) * z_denom;\n        let m23 = 2.0 * z_far * z_near * z_denom;\n        let m32 = -1.0;\n        Transform4F::row_major(\n            m00, 0.0, 0.0, 0.0, 0.0, m11, 0.0, 0.0, 0.0, 0.0, m22, m23, 0.0, 0.0, m32, 0.0,\n        )\n    }\n\n    /// Just like `gluLookAt()`.\n    #[inline]\n    pub fn looking_at(eye: Vector3F, center: Vector3F, mut up: Vector3F) -> Transform4F {\n        let f = (center - eye).normalize();\n        up = up.normalize();\n        let s = f.cross(up);\n        let u = s.normalize().cross(f);\n        let minus_f = -f;\n\n        // TODO(pcwalton): Use SIMD. This needs a matrix transpose:\n        // https://fgiesen.wordpress.com/2013/07/09/simd-transposes-1/\n        let transform = Transform4F::row_major(s.x(),       s.y(),       s.z(),       0.0,\n                                               u.x(),       u.y(),       u.z(),       0.0,\n                                               minus_f.x(), minus_f.y(), minus_f.z(), 0.0,\n                                               0.0,         0.0,         0.0,         1.0) *\n                        Transform4F::from_translation((-eye).to_4d());\n        transform\n    }\n\n    //     +-     -+\n    //     |  A B  |\n    //     |  C D  |\n    //     +-     -+\n    #[inline]\n    pub fn from_submatrices(\n        a: Matrix2x2F,\n        b: Matrix2x2F,\n        c: Matrix2x2F,\n        d: Matrix2x2F,\n    ) -> Transform4F {\n        Transform4F {\n            c0: a.0.concat_xy_xy(c.0),\n            c1: a.0.concat_zw_zw(c.0),\n            c2: b.0.concat_xy_xy(d.0),\n            c3: b.0.concat_zw_zw(d.0),\n        }\n    }\n\n    #[inline]\n    pub fn rotate(&self, yaw: f32, pitch: f32, roll: f32) -> Transform4F {\n        Transform4F::from_rotation(yaw, pitch, roll) * *self\n    }\n\n    #[inline]\n    pub fn scale(&self, scale: Vector4F) -> Transform4F {\n        Transform4F::from_scale(scale) * *self\n    }\n\n    #[inline]\n    pub fn uniform_scale(&self, scale: f32) -> Transform4F {\n        Transform4F::from_uniform_scale(scale) * *self\n    }\n\n    #[inline]\n    pub fn translate(&self, translation: Vector4F) -> Transform4F {\n        Transform4F::from_translation(translation) * *self\n    }\n\n    #[inline]\n    pub fn upper_left(&self) -> Matrix2x2F {\n        Matrix2x2F(self.c0.concat_xy_xy(self.c1))\n    }\n\n    #[inline]\n    pub fn upper_right(&self) -> Matrix2x2F {\n        Matrix2x2F(self.c2.concat_xy_xy(self.c3))\n    }\n\n    #[inline]\n    pub fn lower_left(&self) -> Matrix2x2F {\n        Matrix2x2F(self.c0.concat_zw_zw(self.c1))\n    }\n\n    #[inline]\n    pub fn lower_right(&self) -> Matrix2x2F {\n        Matrix2x2F(self.c2.concat_zw_zw(self.c3))\n    }\n\n    // https://en.wikipedia.org/wiki/Invertible_matrix#Blockwise_inversion\n    //\n    // If A is the upper left submatrix of this matrix, this method assumes that A and the Schur\n    // complement of A are invertible.\n    pub fn inverse(&self) -> Transform4F {\n        // Extract submatrices.\n        let (a, b) = (self.upper_left(), self.upper_right());\n        let (c, d) = (self.lower_left(), self.lower_right());\n\n        // Compute temporary matrices.\n        let a_inv = a.inverse();\n        let x = c * a_inv;\n        let y = (d - x * b).inverse();\n        let z = a_inv * b;\n\n        // Compute new submatrices.\n        let (a_new, b_new) = (a_inv + z * y * x, -z * y);\n        let (c_new, d_new) = (-y * x, y);\n\n        // Construct inverse.\n        Transform4F::from_submatrices(a_new, b_new, c_new, d_new)\n    }\n\n    pub fn approx_eq(&self, other: &Transform4F, epsilon: f32) -> bool {\n        self.c0.approx_eq(other.c0, epsilon)\n            && self.c1.approx_eq(other.c1, epsilon)\n            && self.c2.approx_eq(other.c2, epsilon)\n            && self.c3.approx_eq(other.c3, epsilon)\n    }\n\n    #[inline]\n    pub fn as_ptr(&self) -> *const f32 {\n        (&self.c0) as *const F32x4 as *const f32\n    }\n\n    #[inline]\n    pub fn to_columns(&self) -> [F32x4; 4] {\n        [self.c0, self.c1, self.c2, self.c3]\n    }\n}\n\nimpl Mul<Transform4F> for Transform4F {\n    type Output = Transform4F;\n\n    // https://stackoverflow.com/a/18508113\n    #[inline]\n    fn mul(self, other: Transform4F) -> Transform4F {\n        return Transform4F {\n            c0: mul_col(&self, other.c0),\n            c1: mul_col(&self, other.c1),\n            c2: mul_col(&self, other.c2),\n            c3: mul_col(&self, other.c3),\n        };\n\n        #[inline]\n        fn mul_col(a: &Transform4F, b_col: F32x4) -> F32x4 {\n            a.c0 * b_col.xxxx() + a.c1 * b_col.yyyy() + a.c2 * b_col.zzzz() + a.c3 * b_col.wwww()\n        }\n    }\n}\n\nimpl Mul<Vector4F> for Transform4F {\n    type Output = Vector4F;\n\n    #[inline]\n    fn mul(self, vector: Vector4F) -> Vector4F {\n        let term0 = self.c0 * F32x4::splat(vector.x());\n        let term1 = self.c1 * F32x4::splat(vector.y());\n        let term2 = self.c2 * F32x4::splat(vector.z());\n        let term3 = self.c3 * F32x4::splat(vector.w());\n        Vector4F(term0 + term1 + term2 + term3)\n    }\n}\n\nimpl MulAssign<Transform4F> for Transform4F {\n    fn mul_assign(&mut self, other: Transform4F) {\n        *self = *self * other\n    }\n}\n\nimpl Add<Matrix2x2F> for Matrix2x2F {\n    type Output = Matrix2x2F;\n    #[inline]\n    fn add(self, other: Matrix2x2F) -> Matrix2x2F {\n        Matrix2x2F(self.0 + other.0)\n    }\n}\n\nimpl Neg for Matrix2x2F {\n    type Output = Matrix2x2F;\n    #[inline]\n    fn neg(self) -> Matrix2x2F {\n        Matrix2x2F(-self.0)\n    }\n}\n\n#[derive(Clone, Copy, Debug)]\npub struct Perspective {\n    pub transform: Transform4F,\n    pub window_size: Vector2I,\n}\n\nimpl Perspective {\n    #[inline]\n    pub fn new(transform: &Transform4F, window_size: Vector2I) -> Perspective {\n        Perspective {\n            transform: *transform,\n            window_size,\n        }\n    }\n}\n\nimpl Mul<Transform4F> for Perspective {\n    type Output = Perspective;\n    #[inline]\n    fn mul(self, other: Transform4F) -> Perspective {\n        Perspective {\n            transform: self.transform * other,\n            window_size: self.window_size,\n        }\n    }\n}\n\nimpl Mul<Vector2F> for Perspective {\n    type Output = Vector2F;\n    #[inline]\n    fn mul(self, vector: Vector2F) -> Vector2F {\n        let point = (self.transform * vector.to_4d()).to_2d() * Vector2F::new(1.0, -1.0);\n        (point + 1.0) * self.window_size.to_f32() * 0.5\n    }\n}\n\nimpl Mul<RectF> for Perspective {\n    type Output = RectF;\n    #[inline]\n    fn mul(self, rect: RectF) -> RectF {\n        let (upper_left, upper_right) = (self * rect.origin(),     self * rect.upper_right());\n        let (lower_left, lower_right) = (self * rect.lower_left(), self * rect.lower_right());\n        let min_point = upper_left.min(upper_right).min(lower_left).min(lower_right);\n        let max_point = upper_left.max(upper_right).max(lower_left).max(lower_right);\n        RectF::from_points(min_point, max_point)\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use crate::vector::Vector4F;\n    use crate::transform3d::Transform4F;\n\n    #[test]\n    fn test_post_mul() {\n        let a = Transform4F::row_major(\n            3.0, 1.0, 4.0, 5.0, 9.0, 2.0, 6.0, 5.0, 3.0, 5.0, 8.0, 9.0, 7.0, 9.0, 3.0, 2.0,\n        );\n        let b = Transform4F::row_major(\n            3.0, 8.0, 4.0, 6.0, 2.0, 6.0, 4.0, 3.0, 3.0, 8.0, 3.0, 2.0, 7.0, 9.0, 5.0, 0.0,\n        );\n        let c = Transform4F::row_major(\n            58.0, 107.0, 53.0, 29.0, 84.0, 177.0, 87.0, 72.0, 106.0, 199.0, 101.0, 49.0, 62.0,\n            152.0, 83.0, 75.0,\n        );\n        assert_eq!(a * b, c);\n    }\n\n    #[test]\n    fn test_pre_mul() {\n        let a = Transform4F::row_major(\n            3.0, 1.0, 4.0, 5.0, 9.0, 2.0, 6.0, 5.0, 3.0, 5.0, 8.0, 9.0, 7.0, 9.0, 3.0, 2.0,\n        );\n        let b = Transform4F::row_major(\n            3.0, 8.0, 4.0, 6.0, 2.0, 6.0, 4.0, 3.0, 3.0, 8.0, 3.0, 2.0, 7.0, 9.0, 5.0, 0.0,\n        );\n        let c = Transform4F::row_major(\n            135.0, 93.0, 110.0, 103.0, 93.0, 61.0, 85.0, 82.0, 104.0, 52.0, 90.0, 86.0, 117.0,\n            50.0, 122.0, 125.0,\n        );\n        assert_eq!(b * a, c);\n    }\n\n    #[test]\n    fn test_transform_point() {\n        let a = Transform4F::row_major(\n            3.0, 1.0, 4.0, 5.0, 9.0, 2.0, 6.0, 5.0, 3.0, 5.0, 8.0, 9.0, 7.0, 9.0, 3.0, 2.0,\n        );\n        let p = Vector4F::new(3.0, 8.0, 4.0, 6.0);\n        let q = Vector4F::new(63.0, 97.0, 135.0, 117.0);\n        assert_eq!(a * p, q);\n    }\n\n    #[test]\n    fn test_inverse() {\n        // Random matrix.\n        let m = Transform4F::row_major(\n            0.86277982, 0.15986552, 0.90739898, 0.60066808, 0.17386167, 0.016353, 0.8535783,\n            0.12969608, 0.0946466, 0.43248631, 0.63480505, 0.08154603, 0.50305436, 0.48359687,\n            0.51057162, 0.24812012,\n        );\n        let p0 = Vector4F::new(0.95536648, 0.80633691, 0.16357357, 0.5477598);\n        let p1 = m * p0;\n        let m_inv = m.inverse();\n        let m_inv_exp = Transform4F::row_major(\n            -2.47290136,\n            3.48865688,\n            -6.12298336,\n            6.17536696,\n            0.00124033357,\n            -1.72561993,\n            2.16876606,\n            0.186227748,\n            -0.375021729,\n            1.53883017,\n            -0.0558194403,\n            0.121857058,\n            5.78300323,\n            -6.87635769,\n            8.30196620,\n            -9.10374060,\n        );\n        assert!(m_inv.approx_eq(&m_inv_exp, 0.0001));\n        let p2 = m_inv * p1;\n        assert!(p0.approx_eq(p2, 0.0001));\n    }\n}\n"
    },
    {
      "package": "pathfinder_geometry@0.5.1",
      "sourcePath": "src/unit_vector.rs",
      "sha256": "a6c30c98aaf859492746696b9d67999322b18117fbe891b53f38ccfca5b28a5f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/geometry/src/unit_vector.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! A utility module that allows unit vectors to be treated like angles.\n\nuse crate::vector::Vector2F;\nuse pathfinder_simd::default::F32x2;\n\n#[derive(Clone, Copy, Debug)]\npub struct UnitVector(pub Vector2F);\n\nimpl UnitVector {\n    #[inline]\n    pub fn from_angle(theta: f32) -> UnitVector {\n        UnitVector(Vector2F::new(theta.cos(), theta.sin()))\n    }\n\n    /// Angle addition formula.\n    #[inline]\n    pub fn rotate_by(&self, other: UnitVector) -> UnitVector {\n        let products = (self.0).0.to_f32x4().xyyx() * (other.0).0.to_f32x4().xyxy();\n        UnitVector(Vector2F::new(products[0] - products[1], products[2] + products[3]))\n    }\n\n    /// Angle subtraction formula.\n    #[inline]\n    pub fn rev_rotate_by(&self, other: UnitVector) -> UnitVector {\n        let products = (self.0).0.to_f32x4().xyyx() * (other.0).0.to_f32x4().xyxy();\n        UnitVector(Vector2F::new(products[0] + products[1], products[2] - products[3]))\n    }\n\n    /// Half angle formula.\n    #[inline]\n    pub fn halve_angle(&self) -> UnitVector {\n        let x = self.0.x();\n        let term = F32x2::new(x, -x);\n        UnitVector(Vector2F((F32x2::splat(0.5) * (F32x2::splat(1.0) + term)).max(F32x2::default())\n                                                                            .sqrt()))\n    }\n}\n"
    },
    {
      "package": "pathfinder_geometry@0.5.1",
      "sourcePath": "src/util.rs",
      "sha256": "33a05481be71f5cf41128eeeb3e378248249d0f6f30ebc057e4c05f11344a0e5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/geometry/src/util.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Various utilities.\n\nuse std::f32;\n\npub const EPSILON: f32 = 0.001;\n\n/// Approximate equality.\n#[inline]\npub fn approx_eq(a: f32, b: f32) -> bool {\n    f32::abs(a - b) <= EPSILON\n}\n\n/// Linear interpolation.\n#[inline]\npub fn lerp(a: f32, b: f32, t: f32) -> f32 {\n    a + (b - a) * t\n}\n\n/// Clamping.\n#[inline]\npub fn clamp(x: f32, min_val: f32, max_val: f32) -> f32 {\n    f32::min(max_val, f32::max(min_val, x))\n}\n\n/// Divides `a` by `b`, rounding up.\n#[inline]\npub fn alignup_i32(a: i32, b: i32) -> i32 {\n    (a + b - 1) / b\n}\n"
    },
    {
      "package": "pathfinder_geometry@0.5.1",
      "sourcePath": "src/vector.rs",
      "sha256": "cfcaad0394c5489a412bcdbbbe6928e1875d4a422eb5a7da1a3e415fdbc0790c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/geometry/src/basic/point.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! A SIMD-optimized point type.\n\nuse pathfinder_simd::default::{F32x2, F32x4, I32x2};\nuse std::hash::{Hash, Hasher};\nuse std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub, SubAssign};\n\n/// 2D points with 32-bit floating point coordinates.\n#[derive(Clone, Copy, Debug, Default)]\npub struct Vector2F(pub F32x2);\n\nimpl Vector2F {\n    #[inline]\n    pub fn new(x: f32, y: f32) -> Vector2F {\n        Vector2F(F32x2::new(x, y))\n    }\n\n    #[inline]\n    pub fn splat(value: f32) -> Vector2F {\n        Vector2F(F32x2::splat(value))\n    }\n\n    #[inline]\n    pub fn zero() -> Vector2F {\n        Vector2F::default()\n    }\n\n    #[inline]\n    pub fn to_3d(self) -> Vector3F {\n        Vector3F(self.0.to_f32x4().concat_xy_zw(F32x4::new(0.0, 0.0, 0.0, 0.0)))\n    }\n\n    #[inline]\n    pub fn to_4d(self) -> Vector4F {\n        Vector4F(self.0.to_f32x4().concat_xy_zw(F32x4::new(0.0, 0.0, 0.0, 1.0)))\n    }\n\n    #[inline]\n    pub fn x(self) -> f32 {\n        self.0[0]\n    }\n\n    #[inline]\n    pub fn y(self) -> f32 {\n        self.0[1]\n    }\n\n    #[inline]\n    pub fn set_x(&mut self, x: f32) {\n        self.0[0] = x;\n    }\n\n    #[inline]\n    pub fn set_y(&mut self, y: f32) {\n        self.0[1] = y;\n    }\n\n    #[inline]\n    pub fn min(self, other: Vector2F) -> Vector2F {\n        Vector2F(self.0.min(other.0))\n    }\n\n    #[inline]\n    pub fn max(self, other: Vector2F) -> Vector2F {\n        Vector2F(self.0.max(other.0))\n    }\n\n    #[inline]\n    pub fn clamp(self, min_val: Vector2F, max_val: Vector2F) -> Vector2F {\n        self.max(min_val).min(max_val)\n    }\n\n    #[inline]\n    pub fn det(self, other: Vector2F) -> f32 {\n        self.x() * other.y() - self.y() * other.x()\n    }\n\n    #[inline]\n    pub fn dot(self, other: Vector2F) -> f32 {\n        let xy = self.0 * other.0;\n        xy.x() + xy.y()\n    }\n\n    #[inline]\n    pub fn floor(self) -> Vector2F {\n        Vector2F(self.0.floor())\n    }\n\n    #[inline]\n    pub fn ceil(self) -> Vector2F {\n        Vector2F(self.0.ceil())\n    }\n\n    /// Rounds both coordinates to the nearest integer.\n    #[inline]\n    pub fn round(self) -> Vector2F {\n        Vector2F(self.0.to_i32x2().to_f32x2())\n    }\n\n    /// Treats this point as a vector and calculates its squared length.\n    #[inline]\n    pub fn square_length(self) -> f32 {\n        let squared = self.0 * self.0;\n        squared[0] + squared[1]\n    }\n\n    /// Treats this point as a vector and calculates its length.\n    #[inline]\n    pub fn length(self) -> f32 {\n        f32::sqrt(self.square_length())\n    }\n\n    /// Treats this point as a vector and normalizes it.\n    #[inline]\n    pub fn normalize(self) -> Vector2F {\n        self * (1.0 / self.length())\n    }\n\n    /// Swaps y and x.\n    #[inline]\n    pub fn yx(self) -> Vector2F {\n        Vector2F(self.0.yx())\n    }\n\n    /// Returns the coefficient when the given vector `a` is projected onto this one.\n    ///\n    /// That is, if this vector is `v` and this function returns `c`, then `proj_v a = cv`. In\n    /// other words, this function computes `(a⋅v) / (v⋅v)`.\n    #[inline]\n    pub fn projection_coefficient(self, a: Vector2F) -> f32 {\n        a.dot(self) / self.square_length()\n    }\n\n    #[inline]\n    pub fn is_zero(self) -> bool {\n        self == Vector2F::zero()\n    }\n\n    #[inline]\n    pub fn lerp(self, other: Vector2F, t: f32) -> Vector2F {\n        self + (other - self) * t\n    }\n\n    #[inline]\n    pub fn to_i32(self) -> Vector2I {\n        Vector2I(self.0.to_i32x2())\n    }\n}\n\n/// A convenience alias for `Vector2F::new()`.\n#[inline]\npub fn vec2f(x: f32, y: f32) -> Vector2F {\n    Vector2F::new(x, y)\n}\n\nimpl PartialEq for Vector2F {\n    #[inline]\n    fn eq(&self, other: &Vector2F) -> bool {\n        self.0.packed_eq(other.0).all_true()\n    }\n}\n\nimpl Add<Vector2F> for Vector2F {\n    type Output = Vector2F;\n    #[inline]\n    fn add(self, other: Vector2F) -> Vector2F {\n        Vector2F(self.0 + other.0)\n    }\n}\n\nimpl Add<f32> for Vector2F {\n    type Output = Vector2F;\n    #[inline]\n    fn add(self, other: f32) -> Vector2F {\n        self + Vector2F::splat(other)\n    }\n}\n\nimpl AddAssign<Vector2F> for Vector2F {\n    #[inline]\n    fn add_assign(&mut self, other: Vector2F) {\n        *self = *self + other\n    }\n}\n\nimpl Sub<Vector2F> for Vector2F {\n    type Output = Vector2F;\n    #[inline]\n    fn sub(self, other: Vector2F) -> Vector2F {\n        Vector2F(self.0 - other.0)\n    }\n}\n\nimpl Sub<f32> for Vector2F {\n    type Output = Vector2F;\n    #[inline]\n    fn sub(self, other: f32) -> Vector2F {\n        self - Vector2F::splat(other)\n    }\n}\n\nimpl SubAssign<Vector2F> for Vector2F {\n    #[inline]\n    fn sub_assign(&mut self, other: Vector2F) {\n        *self = *self - other\n    }\n}\n\nimpl Mul<Vector2F> for Vector2F {\n    type Output = Vector2F;\n    #[inline]\n    fn mul(self, other: Vector2F) -> Vector2F {\n        Vector2F(self.0 * other.0)\n    }\n}\n\nimpl Mul<f32> for Vector2F {\n    type Output = Vector2F;\n    #[inline]\n    fn mul(self, other: f32) -> Vector2F {\n        self * Vector2F::splat(other)\n    }\n}\n\nimpl MulAssign<Vector2F> for Vector2F {\n    #[inline]\n    fn mul_assign(&mut self, other: Vector2F) {\n        *self = *self * other\n    }\n}\n\nimpl MulAssign<f32> for Vector2F {\n    #[inline]\n    fn mul_assign(&mut self, other: f32) {\n        *self = *self * other\n    }\n}\n\nimpl Div<Vector2F> for Vector2F {\n    type Output = Vector2F;\n    #[inline]\n    fn div(self, other: Vector2F) -> Vector2F {\n        Vector2F(self.0 / other.0)\n    }\n}\n\nimpl Div<f32> for Vector2F {\n    type Output = Vector2F;\n    #[inline]\n    fn div(self, other: f32) -> Vector2F {\n        self / Vector2F::splat(other)\n    }\n}\n\nimpl Neg for Vector2F {\n    type Output = Vector2F;\n    #[inline]\n    fn neg(self) -> Vector2F {\n        Vector2F(-self.0)\n    }\n}\n\n/// Either a scalar or a `Vector2F`.\n/// \n/// Scalars will be automatically splatted (i.e. `x` becomes `vec2f(x, x)`).\n/// \n/// Be judicious with the use of this trait. Only use it if it will aid readability without the\n/// potential to introduce bugs.\npub trait IntoVector2F {\n    fn into_vector_2f(self) -> Vector2F;\n}\n\nimpl IntoVector2F for Vector2F {\n    #[inline]\n    fn into_vector_2f(self) -> Vector2F {\n        self\n    }\n}\n\nimpl IntoVector2F for f32 {\n    #[inline]\n    fn into_vector_2f(self) -> Vector2F {\n        Vector2F::splat(self)\n    }\n}\n\n/// 2D points with 32-bit signed integer coordinates.\n#[derive(Clone, Copy, Debug, Default)]\npub struct Vector2I(pub I32x2);\n\nimpl Vector2I {\n    #[inline]\n    pub fn new(x: i32, y: i32) -> Vector2I {\n        Vector2I(I32x2::new(x, y))\n    }\n\n    #[inline]\n    pub fn splat(value: i32) -> Vector2I {\n        Vector2I(I32x2::splat(value))\n    }\n\n    #[inline]\n    pub fn zero() -> Vector2I {\n        Vector2I::default()\n    }\n\n    #[inline]\n    pub fn x(self) -> i32 {\n        self.0[0]\n    }\n\n    #[inline]\n    pub fn y(self) -> i32 {\n        self.0[1]\n    }\n\n    #[inline]\n    pub fn set_x(&mut self, x: i32) {\n        self.0[0] = x;\n    }\n\n    #[inline]\n    pub fn set_y(&mut self, y: i32) {\n        self.0[1] = y;\n    }\n\n    #[inline]\n    pub fn min(self, other: Vector2I) -> Vector2I {\n        Vector2I(self.0.min(other.0))\n    }\n\n    #[inline]\n    pub fn max(self, other: Vector2I) -> Vector2I {\n        Vector2I(self.0.max(other.0))\n    }\n\n    #[inline]\n    pub fn to_f32(self) -> Vector2F {\n        Vector2F(self.0.to_f32x2())\n    }\n}\n\n/// A convenience alias for `Vector2I::new()`.\n#[inline]\npub fn vec2i(x: i32, y: i32) -> Vector2I {\n    Vector2I::new(x, y)\n}\n\nimpl Add<Vector2I> for Vector2I {\n    type Output = Vector2I;\n    #[inline]\n    fn add(self, other: Vector2I) -> Vector2I {\n        Vector2I(self.0 + other.0)\n    }\n}\n\nimpl Add<i32> for Vector2I {\n    type Output = Vector2I;\n    #[inline]\n    fn add(self, other: i32) -> Vector2I {\n        self + Vector2I::splat(other)\n    }\n}\n\nimpl AddAssign<Vector2I> for Vector2I {\n    #[inline]\n    fn add_assign(&mut self, other: Vector2I) {\n        self.0 += other.0\n    }\n}\n\nimpl Neg for Vector2I {\n    type Output = Vector2I;\n    #[inline]\n    fn neg(self) -> Vector2I {\n        Vector2I(-self.0)\n    }\n}\n\nimpl Sub<Vector2I> for Vector2I {\n    type Output = Vector2I;\n    #[inline]\n    fn sub(self, other: Vector2I) -> Vector2I {\n        Vector2I(self.0 - other.0)\n    }\n}\n\nimpl Sub<i32> for Vector2I {\n    type Output = Vector2I;\n    #[inline]\n    fn sub(self, other: i32) -> Vector2I {\n        self - Vector2I::splat(other)\n    }\n}\n\nimpl Mul<Vector2I> for Vector2I {\n    type Output = Vector2I;\n    #[inline]\n    fn mul(self, other: Vector2I) -> Vector2I {\n        Vector2I(self.0 * other.0)\n    }\n}\n\nimpl Mul<i32> for Vector2I {\n    type Output = Vector2I;\n    #[inline]\n    fn mul(self, other: i32) -> Vector2I {\n        self * Vector2I::splat(other)\n    }\n}\n\nimpl PartialEq for Vector2I {\n    #[inline]\n    fn eq(&self, other: &Vector2I) -> bool {\n        self.0.packed_eq(other.0).all_true()\n    }\n}\n\nimpl Eq for Vector2I {}\n\nimpl Hash for Vector2I {\n    #[inline]\n    fn hash<H>(&self, state: &mut H) where H: Hasher {\n        self.x().hash(state);\n        self.y().hash(state);\n    }\n}\n\n/// 3D points.\n///\n/// The w value in the SIMD vector is always 0.0.\n#[derive(Clone, Copy, Debug, Default, PartialEq)]\npub struct Vector3F(pub F32x4);\n\nimpl Vector3F {\n    #[inline]\n    pub fn new(x: f32, y: f32, z: f32) -> Vector3F {\n        Vector3F(F32x4::new(x, y, z, 0.0))\n    }\n\n    #[inline]\n    pub fn splat(x: f32) -> Vector3F {\n        let mut vector = F32x4::splat(x);\n        vector.set_w(0.0);\n        Vector3F(vector)\n    }\n\n    /// Truncates this vector to 2D.\n    #[inline]\n    pub fn to_2d(self) -> Vector2F {\n        Vector2F(self.0.xy())\n    }\n\n    /// Converts this vector to an equivalent 3D homogeneous one with a w component of 1.0.\n    #[inline]\n    pub fn to_4d(self) -> Vector4F {\n        let mut vector = self.0;\n        vector.set_w(1.0);\n        Vector4F(vector)\n    }\n\n    #[inline]\n    pub fn cross(self, other: Vector3F) -> Vector3F {\n        Vector3F(self.0.yzxw() * other.0.zxyw() - self.0.zxyw() * other.0.yzxw())\n    }\n\n    #[inline]\n    pub fn square_length(self) -> f32 {\n        let squared = self.0 * self.0;\n        squared[0] + squared[1] + squared[2]\n    }\n\n    #[inline]\n    pub fn length(self) -> f32 {\n        f32::sqrt(self.square_length())\n    }\n\n    #[inline]\n    pub fn normalize(self) -> Vector3F {\n        Vector3F(self.0 * F32x4::splat(1.0 / self.length()))\n    }\n\n    #[inline]\n    pub fn x(self) -> f32 {\n        self.0[0]\n    }\n\n    #[inline]\n    pub fn y(self) -> f32 {\n        self.0[1]\n    }\n\n    #[inline]\n    pub fn z(self) -> f32 {\n        self.0[2]\n    }\n\n    #[inline]\n    pub fn scale(self, factor: f32) -> Vector3F {\n        Vector3F(self.0 * F32x4::splat(factor))\n    }\n}\n\nimpl Add<Vector3F> for Vector3F {\n    type Output = Vector3F;\n    #[inline]\n    fn add(self, other: Vector3F) -> Vector3F {\n        Vector3F(self.0 + other.0)\n    }\n}\n\nimpl AddAssign for Vector3F {\n    #[inline]\n    fn add_assign(&mut self, other: Vector3F) {\n        self.0 += other.0\n    }\n}\n\nimpl Neg for Vector3F {\n    type Output = Vector3F;\n    #[inline]\n    fn neg(self) -> Vector3F {\n        Vector3F(self.0 * F32x4::new(-1.0, -1.0, -1.0, 0.0))\n    }\n}\n\nimpl Sub<Vector3F> for Vector3F {\n    type Output = Vector3F;\n    #[inline]\n    fn sub(self, other: Vector3F) -> Vector3F {\n        Vector3F(self.0 - other.0)\n    }\n}\n\n/// 3D homogeneous points.\n#[derive(Clone, Copy, Debug, PartialEq)]\npub struct Vector4F(pub F32x4);\n\nimpl Vector4F {\n    #[inline]\n    pub fn new(x: f32, y: f32, z: f32, w: f32) -> Vector4F {\n        Vector4F(F32x4::new(x, y, z, w))\n    }\n\n    #[inline]\n    pub fn splat(value: f32) -> Vector4F {\n        Vector4F(F32x4::splat(value))\n    }\n\n    #[inline]\n    pub fn to_2d(self) -> Vector2F {\n        self.to_3d().to_2d()\n    }\n\n    /// Performs perspective division to convert this vector to 3D.\n    #[inline]\n    pub fn to_3d(self) -> Vector3F {\n        let mut vector = self.0 * F32x4::splat(1.0 / self.w());\n        vector.set_w(0.0);\n        Vector3F(vector)\n    }\n\n    #[inline]\n    pub fn x(self) -> f32 {\n        self.0[0]\n    }\n\n    #[inline]\n    pub fn y(self) -> f32 {\n        self.0[1]\n    }\n\n    #[inline]\n    pub fn z(self) -> f32 {\n        self.0[2]\n    }\n\n    #[inline]\n    pub fn w(self) -> f32 {\n        self.0[3]\n    }\n\n    #[inline]\n    pub fn scale(self, x: f32) -> Vector4F {\n        let mut factors = F32x4::splat(x);\n        factors[3] = 1.0;\n        Vector4F(self.0 * factors)\n    }\n\n    #[inline]\n    pub fn set_x(&mut self, x: f32) {\n        self.0[0] = x\n    }\n\n    #[inline]\n    pub fn set_y(&mut self, y: f32) {\n        self.0[1] = y\n    }\n\n    #[inline]\n    pub fn set_z(&mut self, z: f32) {\n        self.0[2] = z\n    }\n\n    #[inline]\n    pub fn set_w(&mut self, w: f32) {\n        self.0[3] = w\n    }\n\n    #[inline]\n    pub fn approx_eq(self, other: Vector4F, epsilon: f32) -> bool {\n        self.0.approx_eq(other.0, epsilon)\n    }\n\n    /// Checks to see whether this *homogeneous* coordinate equals zero.\n    ///\n    /// Note that since this treats the coordinate as a homogeneous coordinate, the `w` is ignored.\n    // TODO(pcwalton): Optimize with SIMD.\n    #[inline]\n    pub fn is_zero(self) -> bool {\n        self.x() == 0.0 && self.y() == 0.0 && self.z() == 0.0\n    }\n\n    #[inline]\n    pub fn lerp(self, other: Vector4F, t: f32) -> Vector4F {\n        Vector4F(self.0 + (other.0 - self.0) * F32x4::splat(t))\n    }\n}\n\nimpl Add<Vector4F> for Vector4F {\n    type Output = Vector4F;\n    #[inline]\n    fn add(self, other: Vector4F) -> Vector4F {\n        Vector4F(self.0 + other.0)\n    }\n}\n\nimpl AddAssign for Vector4F {\n    #[inline]\n    fn add_assign(&mut self, other: Vector4F) {\n        self.0 += other.0\n    }\n}\n\nimpl Mul<Vector4F> for Vector4F {\n    type Output = Vector4F;\n    #[inline]\n    fn mul(self, other: Vector4F) -> Vector4F {\n        Vector4F(self.0 * other.0)\n    }\n}\n\nimpl Neg for Vector4F {\n    type Output = Vector4F;\n    /// NB: This does not negate w, because that is rarely what you what for homogeneous\n    /// coordinates.\n    #[inline]\n    fn neg(self) -> Vector4F {\n        Vector4F(self.0 * F32x4::new(-1.0, -1.0, -1.0, 1.0))\n    }\n}\n\nimpl Sub<Vector4F> for Vector4F {\n    type Output = Vector4F;\n    #[inline]\n    fn sub(self, other: Vector4F) -> Vector4F {\n        Vector4F(self.0 - other.0)\n    }\n}\n\nimpl Default for Vector4F {\n    #[inline]\n    fn default() -> Vector4F {\n        let mut point = F32x4::default();\n        point.set_w(1.0);\n        Vector4F(point)\n    }\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "build.rs",
      "sha256": "b515ee342a21c17c65615c6001a90bf1d131e4a46046ae1b0ed92e33d258bb58",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/build.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nextern crate rustc_version;\n\nuse rustc_version::Channel;\n\nfn main() {\n    // Assert we haven't travelled back in time\n    assert!(rustc_version::version().unwrap().major >= 1);\n\n    // Set cfg flags depending on release channel\n    match rustc_version::version_meta().unwrap().channel {\n        Channel::Nightly => {\n            println!(\"cargo:rustc-cfg=pf_rustc_nightly\");\n        }\n        _ => {}\n    }\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/arm/mod.rs",
      "sha256": "cb8566a07af8d8a95f6124bbbd1d94f69b3f084103e6452de3cef364909da849",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/arm.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse std::arch::aarch64::{self, float32x2_t, float32x4_t, int32x2_t, int32x4_t};\nuse std::arch::aarch64::{uint32x2_t, uint32x4_t};\nuse std::f32;\nuse std::fmt::{self, Debug, Formatter};\nuse std::intrinsics::simd::*;\nuse std::mem;\nuse std::ops::{Add, BitAnd, BitOr, Div, Index, IndexMut, Mul, Not, Shr, Sub};\n\nmod swizzle_f32x4;\nmod swizzle_i32x4;\n\n#[repr(simd)]\npub(crate) struct Simd<T, const N: usize>([T; N]);\n\nmacro_rules! simd_shuffle2 {\n    ($x:expr, $y:expr, <$(const $imm:ident : $ty:ty),+> $idx:expr $(,)?) => {{\n        struct ConstParam<$(const $imm: $ty),+>;\n        impl<$(const $imm: $ty),+> ConstParam<$($imm),+> {\n            const IDX: Simd<u32, 2> = Simd($idx);\n        }\n\n        simd_shuffle($x, $y, ConstParam::<$($imm),+>::IDX)\n    }};\n    ($x:expr, $y:expr, $idx:expr $(,)?) => {{\n        const IDX: Simd<u32, 2>  = Simd($idx);\n        simd_shuffle($x, $y, IDX)\n    }};\n}\n\nmacro_rules! simd_shuffle4 {\n    ($x:expr, $y:expr, <$(const $imm:ident : $ty:ty),+> $idx:expr $(,)?) => {{\n        struct ConstParam<$(const $imm: $ty),+>;\n        impl<$(const $imm: $ty),+> ConstParam<$($imm),+> {\n            const IDX: Simd<u32; 4> = Simd($idx);\n        }\n\n        simd_shuffle($x, $y, ConstParam::<$($imm),+>::IDX)\n    }};\n    ($x:expr, $y:expr, $idx:expr $(,)?) => {{\n        const IDX: Simd<u32, 4> = Simd($idx);\n        simd_shuffle($x, $y, IDX)\n    }};\n}\n\n// Two 32-bit floats\n\n#[derive(Clone, Copy)]\npub struct F32x2(pub float32x2_t);\n\nimpl F32x2 {\n    // Constructors\n\n    #[inline]\n    pub fn new(a: f32, b: f32) -> F32x2 {\n        unsafe { F32x2(mem::transmute([a, b])) }\n    }\n\n    #[inline]\n    pub fn splat(x: f32) -> F32x2 {\n        F32x2::new(x, x)\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn approx_recip(self) -> F32x2 {\n        unsafe { F32x2(vrecpe_v2f32(self.0)) }\n    }\n\n    #[inline]\n    pub fn min(self, other: F32x2) -> F32x2 {\n        unsafe { F32x2(simd_minimum_number_nsz(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn max(self, other: F32x2) -> F32x2 {\n        unsafe { F32x2(simd_maximum_number_nsz(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn clamp(self, min: F32x2, max: F32x2) -> F32x2 {\n        self.max(min).min(max)\n    }\n\n    #[inline]\n    pub fn abs(self) -> F32x2 {\n        unsafe { F32x2(fabs_v2f32(self.0)) }\n    }\n\n    #[inline]\n    pub fn floor(self) -> F32x2 {\n        unsafe { F32x2(floor_v2f32(self.0)) }\n    }\n\n    #[inline]\n    pub fn ceil(self) -> F32x2 {\n        unsafe { F32x2(ceil_v2f32(self.0)) }\n    }\n\n    #[inline]\n    pub fn sqrt(self) -> F32x2 {\n        unsafe { F32x2(sqrt_v2f32(self.0)) }\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: F32x2) -> U32x2 {\n        unsafe { U32x2(simd_eq(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn packed_gt(self, other: F32x2) -> U32x2 {\n        unsafe { U32x2(simd_gt(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn packed_lt(self, other: F32x2) -> U32x2 {\n        unsafe { U32x2(simd_lt(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: F32x2) -> U32x2 {\n        unsafe { U32x2(simd_le(self.0, other.0)) }\n    }\n\n    // Conversions\n\n    #[inline]\n    pub fn to_f32x4(self) -> F32x4 {\n        self.concat_xy_xy(F32x2::default())\n    }\n\n    /// Converts these packed floats to integers via rounding.\n    #[inline]\n    pub fn to_i32x2(self) -> I32x2 {\n        unsafe { I32x2(simd_cast(round_v2f32(self.0))) }\n    }\n\n    #[inline]\n    pub fn to_i32x4(self) -> I32x4 {\n        self.to_i32x2().concat_xy_xy(I32x2::default())\n    }\n\n    // Swizzle\n\n    #[inline]\n    pub fn yx(self) -> F32x2 {\n        unsafe { F32x2(simd_shuffle2!(self.0, self.0, [1, 0])) }\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: F32x2) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, other.0, [0, 1, 2, 3])) }\n    }\n}\n\nimpl Default for F32x2 {\n    #[inline]\n    fn default() -> F32x2 {\n        F32x2::new(0.0, 0.0)\n    }\n}\n\nimpl Debug for F32x2 {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {\n        write!(f, \"<{}, {}>\", self[0], self[1])\n    }\n}\n\nimpl Index<usize> for F32x2 {\n    type Output = f32;\n    #[inline]\n    fn index(&self, index: usize) -> &f32 {\n        unsafe {\n            assert!(index < 2);\n            let ptr = &self.0 as *const float32x2_t as *const f32;\n            mem::transmute::<*const f32, &f32>(ptr.offset(index as isize))\n        }\n    }\n}\n\nimpl IndexMut<usize> for F32x2 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut f32 {\n        unsafe {\n            assert!(index < 2);\n            let ptr = &mut self.0 as *mut float32x2_t as *mut f32;\n            mem::transmute::<*mut f32, &mut f32>(ptr.offset(index as isize))\n        }\n    }\n}\n\nimpl Add<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn add(self, other: F32x2) -> F32x2 {\n        unsafe { F32x2(simd_add(self.0, other.0)) }\n    }\n}\n\nimpl Div<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn div(self, other: F32x2) -> F32x2 {\n        unsafe { F32x2(simd_div(self.0, other.0)) }\n    }\n}\n\nimpl Mul<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn mul(self, other: F32x2) -> F32x2 {\n        unsafe { F32x2(simd_mul(self.0, other.0)) }\n    }\n}\n\nimpl Sub<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn sub(self, other: F32x2) -> F32x2 {\n        unsafe { F32x2(simd_sub(self.0, other.0)) }\n    }\n}\n\nimpl PartialEq for F32x2 {\n    #[inline]\n    fn eq(&self, other: &F32x2) -> bool {\n        self.packed_eq(*other).all_true()\n    }\n}\n\n// Four 32-bit floats\n\n#[derive(Clone, Copy)]\npub struct F32x4(pub float32x4_t);\n\nimpl F32x4 {\n    #[inline]\n    pub fn new(a: f32, b: f32, c: f32, d: f32) -> F32x4 {\n        unsafe { F32x4(mem::transmute([a, b, c, d])) }\n    }\n\n    #[inline]\n    pub fn splat(x: f32) -> F32x4 {\n        F32x4::new(x, x, x, x)\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn approx_recip(self) -> F32x4 {\n        unsafe { F32x4(vrecpe_v4f32(self.0)) }\n    }\n\n    #[inline]\n    pub fn min(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(simd_minimum_number_nsz(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn max(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(simd_maximum_number_nsz(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn clamp(self, min: F32x4, max: F32x4) -> F32x4 {\n        self.max(min).min(max)\n    }\n\n    #[inline]\n    pub fn abs(self) -> F32x4 {\n        unsafe { F32x4(fabs_v4f32(self.0)) }\n    }\n\n    #[inline]\n    pub fn floor(self) -> F32x4 {\n        unsafe { F32x4(floor_v4f32(self.0)) }\n    }\n\n    #[inline]\n    pub fn ceil(self) -> F32x4 {\n        unsafe { F32x4(ceil_v4f32(self.0)) }\n    }\n\n    #[inline]\n    pub fn sqrt(self) -> F32x4 {\n        unsafe { F32x4(sqrt_v4f32(self.0)) }\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: F32x4) -> U32x4 {\n        unsafe { U32x4(simd_eq(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn packed_gt(self, other: F32x4) -> U32x4 {\n        unsafe { U32x4(simd_gt(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: F32x4) -> U32x4 {\n        unsafe { U32x4(simd_le(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn packed_lt(self, other: F32x4) -> U32x4 {\n        unsafe { U32x4(simd_lt(self.0, other.0)) }\n    }\n\n    // Swizzle conversions\n\n    #[inline]\n    pub fn xy(self) -> F32x2 {\n        unsafe { F32x2(simd_shuffle2!(self.0, self.0, [0, 1])) }\n    }\n\n    #[inline]\n    pub fn yx(self) -> F32x2 {\n        unsafe { F32x2(simd_shuffle2!(self.0, self.0, [1, 0])) }\n    }\n\n    #[inline]\n    pub fn xw(self) -> F32x2 {\n        unsafe { F32x2(simd_shuffle2!(self.0, self.0, [0, 3])) }\n    }\n\n    #[inline]\n    pub fn zy(self) -> F32x2 {\n        unsafe { F32x2(simd_shuffle2!(self.0, self.0, [2, 1])) }\n    }\n\n    #[inline]\n    pub fn zw(self) -> F32x2 {\n        unsafe { F32x2(simd_shuffle2!(self.0, self.0, [2, 3])) }\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, other.0, [0, 1, 4, 5])) }\n    }\n\n    #[inline]\n    pub fn concat_xy_zw(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, other.0, [0, 1, 6, 7])) }\n    }\n\n    #[inline]\n    pub fn concat_zw_zw(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, other.0, [2, 3, 6, 7])) }\n    }\n\n    #[inline]\n    pub fn concat_wz_yx(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, other.0, [3, 2, 5, 4])) }\n    }\n\n    // Conversions\n\n    /// Converts these packed floats to integers via rounding.\n    #[inline]\n    pub fn to_i32x4(self) -> I32x4 {\n        unsafe { I32x4(simd_cast(round_v4f32(self.0))) }\n    }\n}\n\nimpl Default for F32x4 {\n    #[inline]\n    fn default() -> F32x4 {\n        F32x4::new(0.0, 0.0, 0.0, 0.0)\n    }\n}\n\nimpl Index<usize> for F32x4 {\n    type Output = f32;\n    #[inline]\n    fn index(&self, index: usize) -> &f32 {\n        unsafe {\n            assert!(index < 4);\n            let ptr = &self.0 as *const float32x4_t as *const f32;\n            mem::transmute::<*const f32, &f32>(ptr.offset(index as isize))\n        }\n    }\n}\n\nimpl IndexMut<usize> for F32x4 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut f32 {\n        unsafe {\n            assert!(index < 4);\n            let ptr = &mut self.0 as *mut float32x4_t as *mut f32;\n            mem::transmute::<*mut f32, &mut f32>(ptr.offset(index as isize))\n        }\n    }\n}\n\nimpl Debug for F32x4 {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {\n        write!(f, \"<{}, {}, {}, {}>\", self[0], self[1], self[2], self[3])\n    }\n}\n\nimpl PartialEq for F32x4 {\n    #[inline]\n    fn eq(&self, other: &F32x4) -> bool {\n        self.packed_eq(*other).all_true()\n    }\n}\n\nimpl Add<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn add(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(simd_add(self.0, other.0)) }\n    }\n}\n\nimpl Div<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn div(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(simd_div(self.0, other.0)) }\n    }\n}\n\nimpl Mul<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn mul(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(simd_mul(self.0, other.0)) }\n    }\n}\n\nimpl Sub<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn sub(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(simd_sub(self.0, other.0)) }\n    }\n}\n\n// Two 32-bit signed integers\n\n#[derive(Clone, Copy, Debug)]\npub struct I32x2(pub int32x2_t);\n\nimpl I32x2 {\n    #[inline]\n    pub fn new(x: i32, y: i32) -> I32x2 {\n        unsafe { I32x2(mem::transmute([x, y])) }\n    }\n\n    #[inline]\n    pub fn splat(x: i32) -> I32x2 {\n        I32x2::new(x, x)\n    }\n\n    // Accessors\n\n    #[inline]\n    pub fn x(self) -> i32 {\n        self[0]\n    }\n\n    #[inline]\n    pub fn y(self) -> i32 {\n        self[1]\n    }\n\n    #[inline]\n    pub fn packed_eq(self, other: I32x2) -> U32x2 {\n        unsafe { U32x2(simd_eq(self.0, other.0)) }\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn max(self, other: I32x2) -> I32x2 {\n        self.to_i32x4().max(other.to_i32x4()).xy()\n    }\n\n    #[inline]\n    pub fn min(self, other: I32x2) -> I32x2 {\n        self.to_i32x4().min(other.to_i32x4()).xy()\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: I32x2) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, other.0, [0, 1, 2, 3])) }\n    }\n\n    // Conversions\n\n    /// Converts these packed integers to floats.\n    #[inline]\n    pub fn to_f32x2(self) -> F32x2 {\n        unsafe { F32x2(simd_cast(self.0)) }\n    }\n\n    #[inline]\n    pub fn to_i32x4(self) -> I32x4 {\n        self.concat_xy_xy(I32x2::default())\n    }\n}\n\nimpl Default for I32x2 {\n    #[inline]\n    fn default() -> I32x2 {\n        I32x2::splat(0)\n    }\n}\n\nimpl PartialEq for I32x2 {\n    #[inline]\n    fn eq(&self, other: &I32x2) -> bool {\n        self.packed_eq(*other).all_true()\n    }\n}\n\nimpl Index<usize> for I32x2 {\n    type Output = i32;\n    #[inline]\n    fn index(&self, index: usize) -> &i32 {\n        unsafe {\n            assert!(index < 2);\n            let ptr = &self.0 as *const int32x2_t as *const i32;\n            mem::transmute::<*const i32, &i32>(ptr.offset(index as isize))\n        }\n    }\n}\n\nimpl IndexMut<usize> for I32x2 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut i32 {\n        unsafe {\n            assert!(index < 2);\n            let ptr = &mut self.0 as *mut int32x2_t as *mut i32;\n            mem::transmute::<*mut i32, &mut i32>(ptr.offset(index as isize))\n        }\n    }\n}\n\nimpl Add<I32x2> for I32x2 {\n    type Output = I32x2;\n    #[inline]\n    fn add(self, other: I32x2) -> I32x2 {\n        unsafe { I32x2(simd_add(self.0, other.0)) }\n    }\n}\n\nimpl Sub<I32x2> for I32x2 {\n    type Output = I32x2;\n    #[inline]\n    fn sub(self, other: I32x2) -> I32x2 {\n        unsafe { I32x2(simd_sub(self.0, other.0)) }\n    }\n}\n\nimpl Mul<I32x2> for I32x2 {\n    type Output = I32x2;\n    #[inline]\n    fn mul(self, other: I32x2) -> I32x2 {\n        unsafe { I32x2(simd_mul(self.0, other.0)) }\n    }\n}\n\n// Four 32-bit signed integers\n\n#[derive(Clone, Copy, Debug)]\npub struct I32x4(pub int32x4_t);\n\nimpl I32x4 {\n    #[inline]\n    pub fn new(a: i32, b: i32, c: i32, d: i32) -> I32x4 {\n        unsafe { I32x4(mem::transmute([a, b, c, d])) }\n    }\n\n    #[inline]\n    pub fn splat(x: i32) -> I32x4 {\n        I32x4::new(x, x, x, x)\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn max(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(simd_cast(simd_maximum_number_nsz(self.to_f32x4().0, other.to_f32x4().0))) }\n    }\n\n    #[inline]\n    pub fn min(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(simd_cast(simd_minimum_number_nsz(self.to_f32x4().0, other.to_f32x4().0))) }\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: I32x4) -> U32x4 {\n        unsafe { U32x4(simd_eq(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: I32x4) -> U32x4 {\n        unsafe { U32x4(simd_le(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn packed_lt(self, other: I32x4) -> U32x4 {\n        unsafe { U32x4(simd_lt(self.0, other.0)) }\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, other.0, [0, 1, 4, 5])) }\n    }\n\n    #[inline]\n    pub fn concat_zw_zw(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, other.0, [2, 3, 6, 7])) }\n    }\n\n    // Swizzle conversions\n\n    #[inline]\n    pub fn xy(self) -> I32x2 {\n        unsafe { I32x2(simd_shuffle2!(self.0, self.0, [0, 1])) }\n    }\n\n    #[inline]\n    pub fn yx(self) -> I32x2 {\n        unsafe { I32x2(simd_shuffle2!(self.0, self.0, [1, 0])) }\n    }\n\n    #[inline]\n    pub fn xw(self) -> I32x2 {\n        unsafe { I32x2(simd_shuffle2!(self.0, self.0, [0, 3])) }\n    }\n\n    #[inline]\n    pub fn zy(self) -> I32x2 {\n        unsafe { I32x2(simd_shuffle2!(self.0, self.0, [2, 1])) }\n    }\n\n    #[inline]\n    pub fn zw(self) -> I32x2 {\n        unsafe { I32x2(simd_shuffle2!(self.0, self.0, [2, 3])) }\n    }\n\n    // Conversions\n\n    /// Converts these packed integers to floats.\n    #[inline]\n    pub fn to_f32x4(self) -> F32x4 {\n        unsafe { F32x4(simd_cast(self.0)) }\n    }\n}\n\nimpl Default for I32x4 {\n    #[inline]\n    fn default() -> I32x4 {\n        I32x4::new(0, 0, 0, 0)\n    }\n}\n\nimpl Index<usize> for I32x4 {\n    type Output = i32;\n    #[inline]\n    fn index(&self, index: usize) -> &i32 {\n        unsafe {\n            assert!(index < 4);\n            let ptr = &self.0 as *const int32x4_t as *const i32;\n            mem::transmute::<*const i32, &i32>(ptr.offset(index as isize))\n        }\n    }\n}\n\nimpl IndexMut<usize> for I32x4 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut i32 {\n        unsafe {\n            assert!(index < 4);\n            let ptr = &mut self.0 as *mut int32x4_t as *mut i32;\n            mem::transmute::<*mut i32, &mut i32>(ptr.offset(index as isize))\n        }\n    }\n}\n\nimpl Add<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn add(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(simd_add(self.0, other.0)) }\n    }\n}\n\nimpl Sub<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn sub(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(simd_sub(self.0, other.0)) }\n    }\n}\n\nimpl Mul<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn mul(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(simd_mul(self.0, other.0)) }\n    }\n}\n\nimpl PartialEq for I32x4 {\n    #[inline]\n    fn eq(&self, other: &I32x4) -> bool {\n        self.packed_eq(*other).all_true()\n    }\n}\n\nimpl BitAnd<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn bitand(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(simd_and(self.0, other.0)) }\n    }\n}\n\nimpl BitOr<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn bitor(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(simd_or(self.0, other.0)) }\n    }\n}\n\nimpl Shr<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn shr(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(simd_shr(self.0, other.0)) }\n    }\n}\n\n// Two 32-bit unsigned integers\n\n#[derive(Clone, Copy)]\npub struct U32x2(pub uint32x2_t);\n\nimpl U32x2 {\n    #[inline]\n    pub fn new(x: u32, y: u32) -> U32x2 {\n        unsafe { U32x2(mem::transmute([x, y])) }\n    }\n\n    #[inline]\n    pub fn splat(x: u32) -> U32x2 {\n        U32x2::new(x, x)\n    }\n\n    /// Returns true if both booleans in this vector are true.\n    ///\n    /// The result is *undefined* if both values in this vector are not booleans. A boolean is a\n    /// value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_true(&self) -> bool {\n        unsafe { aarch64::vminv_u32(self.0) == !0 }\n    }\n\n    /// Returns true if both booleans in this vector are false.\n    ///\n    /// The result is *undefined* if both values in this vector are not booleans. A boolean is a\n    /// value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_false(&self) -> bool {\n        unsafe { aarch64::vmaxv_u32(self.0) == 0 }\n    }\n\n    #[inline]\n    pub fn to_i32x2(self) -> I32x2 {\n        unsafe { I32x2(simd_cast(self.0)) }\n    }\n}\n\nimpl Index<usize> for U32x2 {\n    type Output = u32;\n    #[inline]\n    fn index(&self, index: usize) -> &u32 {\n        unsafe {\n            assert!(index < 2);\n            let ptr = &self.0 as *const uint32x2_t as *const u32;\n            mem::transmute::<*const u32, &u32>(ptr.offset(index as isize))\n        }\n    }\n}\n\nimpl Not for U32x2 {\n    type Output = U32x2;\n    #[inline]\n    fn not(self) -> U32x2 {\n        // FIXME(pcwalton): Is there a better way to do this?\n        unsafe { U32x2(simd_xor(self.0, U32x2::splat(!0).0)) }\n    }\n}\n\nimpl BitAnd<U32x2> for U32x2 {\n    type Output = U32x2;\n    #[inline]\n    fn bitand(self, other: U32x2) -> U32x2 {\n        unsafe { U32x2(simd_and(self.0, other.0)) }\n    }\n}\n\nimpl BitOr<U32x2> for U32x2 {\n    type Output = U32x2;\n    #[inline]\n    fn bitor(self, other: U32x2) -> U32x2 {\n        unsafe { U32x2(simd_or(self.0, other.0)) }\n    }\n}\n\n// Four 32-bit unsigned integers\n\n#[derive(Clone, Copy)]\npub struct U32x4(pub uint32x4_t);\n\nimpl U32x4 {\n    #[inline]\n    pub fn new(a: u32, b: u32, c: u32, d: u32) -> U32x4 {\n        unsafe { U32x4(mem::transmute([a, b, c, d])) }\n    }\n\n    #[inline]\n    pub fn splat(x: u32) -> U32x4 {\n        U32x4::new(x, x, x, x)\n    }\n\n    /// Returns true if all four booleans in this vector are true.\n    ///\n    /// The result is *undefined* if all four values in this vector are not booleans. A boolean is\n    /// a value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_true(&self) -> bool {\n        unsafe { aarch64::vminvq_u32(self.0) == !0 }\n    }\n\n    /// Returns true if all four booleans in this vector are false.\n    ///\n    /// The result is *undefined* if all four values in this vector are not booleans. A boolean is\n    /// a value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_false(&self) -> bool {\n        unsafe { aarch64::vmaxvq_u32(self.0) == 0 }\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: U32x4) -> U32x4 {\n        unsafe { U32x4(simd_eq(self.0, other.0)) }\n    }\n}\n\nimpl Debug for U32x4 {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {\n        write!(f, \"<{}, {}, {}, {}>\", self[0], self[1], self[2], self[3])\n    }\n}\n\nimpl Index<usize> for U32x4 {\n    type Output = u32;\n    #[inline]\n    fn index(&self, index: usize) -> &u32 {\n        unsafe {\n            assert!(index < 4);\n            let ptr = &self.0 as *const uint32x4_t as *const u32;\n            mem::transmute::<*const u32, &u32>(ptr.offset(index as isize))\n        }\n    }\n}\n\nimpl PartialEq for U32x4 {\n    #[inline]\n    fn eq(&self, other: &U32x4) -> bool {\n        self.packed_eq(*other).all_true()\n    }\n}\n\nextern \"C\" {\n    #[link_name = \"llvm.fabs.v2f32\"]\n    fn fabs_v2f32(a: float32x2_t) -> float32x2_t;\n    #[link_name = \"llvm.floor.v2f32\"]\n    fn floor_v2f32(a: float32x2_t) -> float32x2_t;\n    #[link_name = \"llvm.ceil.v2f32\"]\n    fn ceil_v2f32(a: float32x2_t) -> float32x2_t;\n    #[link_name = \"llvm.round.v2f32\"]\n    fn round_v2f32(a: float32x2_t) -> float32x2_t;\n    #[link_name = \"llvm.sqrt.v2f32\"]\n    fn sqrt_v2f32(a: float32x2_t) -> float32x2_t;\n\n    #[link_name = \"llvm.fabs.v4f32\"]\n    fn fabs_v4f32(a: float32x4_t) -> float32x4_t;\n    #[link_name = \"llvm.floor.v4f32\"]\n    fn floor_v4f32(a: float32x4_t) -> float32x4_t;\n    #[link_name = \"llvm.ceil.v4f32\"]\n    fn ceil_v4f32(a: float32x4_t) -> float32x4_t;\n    #[link_name = \"llvm.round.v4f32\"]\n    fn round_v4f32(a: float32x4_t) -> float32x4_t;\n    #[link_name = \"llvm.sqrt.v4f32\"]\n    fn sqrt_v4f32(a: float32x4_t) -> float32x4_t;\n\n    #[link_name = \"llvm.aarch64.neon.frecpe.v2f32\"]\n    fn vrecpe_v2f32(a: float32x2_t) -> float32x2_t;\n\n    #[link_name = \"llvm.aarch64.neon.frecpe.v4f32\"]\n    fn vrecpe_v4f32(a: float32x4_t) -> float32x4_t;\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/arm/swizzle_f32x4.rs",
      "sha256": "da7882326e637d636b6a2719285aee6e83fa16b326dbbc0a227564d54c2e2e96",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/arm/swizzle_f32x4.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::arm::{self, F32x4, Simd};\n\nmacro_rules! simd_shuffle4 {\n    ($x:expr, $y:expr, <$(const $imm:ident : $ty:ty),+> $idx:expr $(,)?) => {{\n        struct ConstParam<$(const $imm: $ty),+>;\n        impl<$(const $imm: $ty),+> ConstParam<$($imm),+> {\n            const IDX: Simd<u32, 4> = Simd($idx);\n        }\n\n        arm::simd_shuffle($x, $y, ConstParam::<$($imm),+>::IDX)\n    }};\n    ($x:expr, $y:expr, $idx:expr $(,)?) => {{\n        const IDX: Simd<u32, 4> = Simd($idx);\n        arm::simd_shuffle($x, $y, IDX)\n    }};\n}\n\nimpl F32x4 {\n    /// Constructs a new vector from the first, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the second, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the third, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the first, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the second, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the third, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the first, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the second, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the third, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the first, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the second, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the third, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the first, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the second, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the third, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the first, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the second, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the third, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the first, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the second, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the third, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the first, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the second, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the third, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the first, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the second, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the third, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwx(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the first, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the second, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the third, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the first, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the second, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the third, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the first, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the second, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the third, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the first, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the second, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the third, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the first, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the second, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the third, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the first, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the second, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the third, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the first, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the second, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the third, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the first, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the second, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the third, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the first, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the second, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the third, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwy(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the first, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the second, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the third, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the first, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the second, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the third, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the first, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the second, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the third, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the first, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the second, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the third, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the first, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the second, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the third, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the first, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the second, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the third, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the first, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the second, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the third, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the first, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the second, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the third, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the first, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the second, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the third, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwz(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the first, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the second, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the third, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the first, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the second, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the third, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the first, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the second, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the third, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the first, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the second, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the third, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the first, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the second, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the third, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the first, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the second, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the third, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the first, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the second, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the third, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the first, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the second, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the third, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the first, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the second, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the third, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzw(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 0, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 0, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 0, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 0, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 1, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 1, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 1, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 1, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 2, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 2, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 2, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 2, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [0, 3, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [1, 3, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [2, 3, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwww(self) -> F32x4 {\n        unsafe { F32x4(simd_shuffle4!(self.0, self.0, [3, 3, 3, 3])) }\n    }\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/arm/swizzle_i32x4.rs",
      "sha256": "b51fa2f04b97e3d81c40322e69883c757bdee0d3ef97bce25eb1ac8b181341d7",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/arm/swizzle_i32x4.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::arm::{self, I32x4, Simd};\n\nmacro_rules! simd_shuffle4 {\n    ($x:expr, $y:expr, <$(const $imm:ident : $ty:ty),+> $idx:expr $(,)?) => {{\n        struct ConstParam<$(const $imm: $ty),+>;\n        impl<$(const $imm: $ty),+> ConstParam<$($imm),+> {\n            const IDX: Simd<u32, 4> = Simd($idx);\n        }\n\n        arm::simd_shuffle($x, $y, ConstParam::<$($imm),+>::IDX)\n    }};\n    ($x:expr, $y:expr, $idx:expr $(,)?) => {{\n        const IDX: Simd<u32, 4> = Simd($idx);\n        arm::simd_shuffle($x, $y, IDX)\n    }};\n}\n\nimpl I32x4 {\n    /// Constructs a new vector from the first, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the second, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the third, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the first, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the second, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the third, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the first, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the second, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the third, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 0, 0])) }\n    }\n\n    /// Constructs a new vector from the first, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the second, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the third, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the first, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the second, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the third, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the first, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the second, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the third, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 1, 0])) }\n    }\n\n    /// Constructs a new vector from the first, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the second, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the third, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the first, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the second, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the third, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the first, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the second, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the third, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 2, 0])) }\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwx(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 3, 0])) }\n    }\n\n    /// Constructs a new vector from the first, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the second, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the third, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the first, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the second, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the third, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the first, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the second, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the third, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 0, 1])) }\n    }\n\n    /// Constructs a new vector from the first, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the second, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the third, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the first, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the second, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the third, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the first, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the second, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the third, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 1, 1])) }\n    }\n\n    /// Constructs a new vector from the first, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the second, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the third, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the first, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the second, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the third, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the first, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the second, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the third, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 2, 1])) }\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwy(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 3, 1])) }\n    }\n\n    /// Constructs a new vector from the first, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the second, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the third, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the first, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the second, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the third, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the first, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the second, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the third, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 0, 2])) }\n    }\n\n    /// Constructs a new vector from the first, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the second, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the third, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the first, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the second, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the third, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the first, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the second, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the third, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 1, 2])) }\n    }\n\n    /// Constructs a new vector from the first, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the second, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the third, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the first, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the second, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the third, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the first, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the second, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the third, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 2, 2])) }\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwz(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 3, 2])) }\n    }\n\n    /// Constructs a new vector from the first, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the second, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the third, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the first, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the second, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the third, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the first, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the second, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the third, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 0, 3])) }\n    }\n\n    /// Constructs a new vector from the first, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the second, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the third, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the first, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the second, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the third, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the first, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the second, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the third, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 1, 3])) }\n    }\n\n    /// Constructs a new vector from the first, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the second, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the third, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the first, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the second, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the third, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the first, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the second, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the third, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzw(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 2, 3])) }\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 0, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 0, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 0, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 0, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 1, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 1, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 1, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 1, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 2, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 2, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 2, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 2, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [0, 3, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [1, 3, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [2, 3, 3, 3])) }\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwww(self) -> I32x4 {\n        unsafe { I32x4(simd_shuffle4!(self.0, self.0, [3, 3, 3, 3])) }\n    }\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/extras.rs",
      "sha256": "013cf183ca79dec2b5ac5f993843a8c123a10fdfdf3d9fa8024ef47ee60e57af",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/extras.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::default::{F32x2, F32x4, I32x2, I32x4};\nuse std::ops::{AddAssign, MulAssign, Neg, SubAssign};\n\n// Two 32-bit floats\n\nimpl F32x2 {\n    // Constructors\n\n    #[inline]\n    pub fn from_slice(slice: &[f32]) -> F32x2 {\n        F32x2::new(slice[0], slice[1])\n    }\n\n    // Accessors\n\n    #[inline]\n    pub fn x(self) -> f32 {\n        self[0]\n    }\n\n    #[inline]\n    pub fn y(self) -> f32 {\n        self[1]\n    }\n\n    // Mutators\n\n    #[inline]\n    pub fn set_x(&mut self, x: f32) {\n        self[0] = x\n    }\n\n    #[inline]\n    pub fn set_y(&mut self, y: f32) {\n        self[1] = y\n    }\n\n    // Comparisons\n\n    #[inline]\n    pub fn approx_eq(self, other: F32x2, epsilon: f32) -> bool {\n        (self - other).abs().packed_gt(F32x2::splat(epsilon)).all_false()\n    }\n}\n\nimpl AddAssign for F32x2 {\n    #[inline]\n    fn add_assign(&mut self, other: F32x2) {\n        *self = *self + other\n    }\n}\n\nimpl SubAssign for F32x2 {\n    #[inline]\n    fn sub_assign(&mut self, other: F32x2) {\n        *self = *self - other\n    }\n}\n\nimpl MulAssign for F32x2 {\n    #[inline]\n    fn mul_assign(&mut self, other: F32x2) {\n        *self = *self * other\n    }\n}\n\nimpl Neg for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn neg(self) -> F32x2 {\n        F32x2::default() - self\n    }\n}\n\n// Four 32-bit floats\n\nimpl F32x4 {\n    // Constructors\n\n    #[inline]\n    pub fn from_slice(slice: &[f32]) -> F32x4 {\n        F32x4::new(slice[0], slice[1], slice[2], slice[3])\n    }\n\n    // Accessors\n\n    #[inline]\n    pub fn x(self) -> f32 {\n        self[0]\n    }\n\n    #[inline]\n    pub fn y(self) -> f32 {\n        self[1]\n    }\n\n    #[inline]\n    pub fn z(self) -> f32 {\n        self[2]\n    }\n\n    #[inline]\n    pub fn w(self) -> f32 {\n        self[3]\n    }\n\n    // Mutators\n\n    #[inline]\n    pub fn set_x(&mut self, x: f32) {\n        self[0] = x\n    }\n\n    #[inline]\n    pub fn set_y(&mut self, y: f32) {\n        self[1] = y\n    }\n\n    #[inline]\n    pub fn set_z(&mut self, z: f32) {\n        self[2] = z\n    }\n\n    #[inline]\n    pub fn set_w(&mut self, w: f32) {\n        self[3] = w\n    }\n\n    // Comparisons\n\n    #[inline]\n    pub fn approx_eq(self, other: F32x4, epsilon: f32) -> bool {\n        (self - other).abs().packed_gt(F32x4::splat(epsilon)).all_false()\n    }\n}\n\nimpl AddAssign for F32x4 {\n    #[inline]\n    fn add_assign(&mut self, other: F32x4) {\n        *self = *self + other\n    }\n}\n\nimpl SubAssign for F32x4 {\n    #[inline]\n    fn sub_assign(&mut self, other: F32x4) {\n        *self = *self - other\n    }\n}\n\nimpl MulAssign for F32x4 {\n    #[inline]\n    fn mul_assign(&mut self, other: F32x4) {\n        *self = *self * other\n    }\n}\n\nimpl Neg for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn neg(self) -> F32x4 {\n        F32x4::default() - self\n    }\n}\n\n// Two 32-bit integers\n\nimpl AddAssign for I32x2 {\n    #[inline]\n    fn add_assign(&mut self, other: I32x2) {\n        *self = *self + other\n    }\n}\n\nimpl SubAssign for I32x2 {\n    #[inline]\n    fn sub_assign(&mut self, other: I32x2) {\n        *self = *self - other\n    }\n}\n\nimpl MulAssign for I32x2 {\n    #[inline]\n    fn mul_assign(&mut self, other: I32x2) {\n        *self = *self * other\n    }\n}\n\nimpl Neg for I32x2 {\n    type Output = I32x2;\n    #[inline]\n    fn neg(self) -> I32x2 {\n        I32x2::default() - self\n    }\n}\n\n// Four 32-bit integers\n\nimpl I32x4 {\n    // Accessors\n\n    #[inline]\n    pub fn x(self) -> i32 {\n        self[0]\n    }\n\n    #[inline]\n    pub fn y(self) -> i32 {\n        self[1]\n    }\n\n    #[inline]\n    pub fn z(self) -> i32 {\n        self[2]\n    }\n\n    #[inline]\n    pub fn w(self) -> i32 {\n        self[3]\n    }\n}\n\nimpl AddAssign for I32x4 {\n    #[inline]\n    fn add_assign(&mut self, other: I32x4) {\n        *self = *self + other\n    }\n}\n\nimpl SubAssign for I32x4 {\n    #[inline]\n    fn sub_assign(&mut self, other: I32x4) {\n        *self = *self - other\n    }\n}\n\nimpl MulAssign for I32x4 {\n    #[inline]\n    fn mul_assign(&mut self, other: I32x4) {\n        *self = *self * other\n    }\n}\n\nimpl Neg for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn neg(self) -> I32x4 {\n        I32x4::default() - self\n    }\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/lib.rs",
      "sha256": "7bc08757defaab4b17d7ceabb702cc0b8dfcd30c6ad364dec6e88a8e2c0ae646",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/lib.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n#![cfg_attr(pf_rustc_nightly, allow(internal_features))]\n#![cfg_attr(pf_rustc_nightly, feature(link_llvm_intrinsics, core_intrinsics))]\n#![cfg_attr(pf_rustc_nightly, feature(simd_ffi))]\n#![cfg_attr(pf_rustc_nightly, feature(repr_simd))]\n\n//! A minimal SIMD abstraction, usable outside of Pathfinder.\n\n#[cfg(all(not(feature = \"pf-no-simd\"), pf_rustc_nightly, target_arch = \"aarch64\"))]\npub use crate::arm as default;\n#[cfg(any(\n    feature = \"pf-no-simd\",\n    not(any(\n        target_arch = \"x86\",\n        target_arch = \"x86_64\",\n        all(pf_rustc_nightly, target_arch = \"aarch64\")\n    ))\n))]\npub use crate::scalar as default;\n#[cfg(all(\n    not(feature = \"pf-no-simd\"),\n    any(target_arch = \"x86\", target_arch = \"x86_64\")\n))]\npub use crate::x86 as default;\n\n#[cfg(all(pf_rustc_nightly, target_arch = \"aarch64\"))]\npub mod arm;\nmod extras;\npub mod scalar;\n#[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\npub mod x86;\n\n#[cfg(test)]\nmod test;\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/scalar/mod.rs",
      "sha256": "e636abae729aa7c5f8d7c4be0f0ec0aae02fea4b8a679e0934cfc3b3f70c8109",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/scalar.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse std::f32;\nuse std::fmt::{self, Debug, Formatter};\nuse std::ops::{Add, BitAnd, BitOr, Div, Index, IndexMut, Mul, Shr, Sub, Not};\n\nmod swizzle_f32x4;\nmod swizzle_i32x4;\n\n// Two 32-bit floats\n\n#[derive(Clone, Copy, Debug, Default, PartialEq)]\npub struct F32x2(pub [f32; 2]);\n\nimpl F32x2 {\n    // Constructors\n\n    #[inline]\n    pub fn new(a: f32, b: f32) -> F32x2 {\n        F32x2([a, b])\n    }\n\n    #[inline]\n    pub fn splat(x: f32) -> F32x2 {\n        F32x2([x, x])\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn approx_recip(self) -> F32x2 {\n        F32x2([1.0 / self[0], 1.0 / self[1]])\n    }\n\n    #[inline]\n    pub fn min(self, other: F32x2) -> F32x2 {\n        F32x2([f32::min(self[0], other[0]), f32::min(self[1], other[1])])\n    }\n\n    #[inline]\n    pub fn max(self, other: F32x2) -> F32x2 {\n        F32x2([f32::max(self[0], other[0]), f32::max(self[1], other[1])])\n    }\n\n    #[inline]\n    pub fn clamp(self, min: F32x2, max: F32x2) -> F32x2 {\n        self.max(min).min(max)\n    }\n\n    #[inline]\n    pub fn abs(self) -> F32x2 {\n        F32x2([self[0].abs(), self[1].abs()])\n    }\n\n    #[inline]\n    pub fn floor(self) -> F32x2 {\n        F32x2([self[0].floor(), self[1].floor()])\n    }\n\n    #[inline]\n    pub fn ceil(self) -> F32x2 {\n        F32x2([self[0].ceil(), self[1].ceil()])\n    }\n\n    #[inline]\n    pub fn sqrt(self) -> F32x2 {\n        F32x2([self[0].sqrt(), self[1].sqrt()])\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: F32x2) -> U32x2 {\n        U32x2([\n            if self[0] == other[0] { !0 } else { 0 },\n            if self[1] == other[1] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_gt(self, other: F32x2) -> U32x2 {\n        U32x2([\n            if self[0] > other[0] { !0 } else { 0 },\n            if self[1] > other[1] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_lt(self, other: F32x2) -> U32x2 {\n        U32x2([\n            if self[0] < other[0] { !0 } else { 0 },\n            if self[1] < other[1] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: F32x2) -> U32x2 {\n        U32x2([\n            if self[0] <= other[0] { !0 } else { 0 },\n            if self[1] <= other[1] { !0 } else { 0 },\n        ])\n    }\n\n    // Conversions\n\n    #[inline]\n    pub fn to_f32x4(self) -> F32x4 {\n        F32x4([self[0] as f32, self[1] as f32, 0.0, 0.0])\n    }\n\n    /// Converts these packed floats to integers via rounding.\n    #[inline]\n    pub fn to_i32x2(self) -> I32x2 {\n        I32x2([self[0].round_ties_even() as i32, self[1].round_ties_even() as i32])\n    }\n\n    /// Converts these packed floats to integers via rounding.\n    #[inline]\n    pub fn to_i32x4(self) -> I32x4 {\n        I32x4([self[0].round_ties_even() as i32, self[1].round_ties_even() as i32, 0, 0])\n    }\n\n    // Swizzle\n\n    #[inline]\n    pub fn yx(self) -> F32x2 {\n        F32x2([self[1], self[0]])\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: F32x2) -> F32x4 {\n        F32x4([self[0], self[1], other[0], other[1]])\n    }\n}\n\nimpl Index<usize> for F32x2 {\n    type Output = f32;\n    #[inline]\n    fn index(&self, index: usize) -> &f32 {\n        &self.0[index]\n    }\n}\n\nimpl IndexMut<usize> for F32x2 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut f32 {\n        &mut self.0[index]\n    }\n}\n\nimpl Add<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn add(self, other: F32x2) -> F32x2 {\n        F32x2([self[0] + other[0], self[1] + other[1]])\n    }\n}\n\nimpl Div<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn div(self, other: F32x2) -> F32x2 {\n        F32x2([self[0] / other[0], self[1] / other[1]])\n    }\n}\n\nimpl Mul<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn mul(self, other: F32x2) -> F32x2 {\n        F32x2([self[0] * other[0], self[1] * other[1]])\n    }\n}\n\nimpl Sub<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn sub(self, other: F32x2) -> F32x2 {\n        F32x2([self[0] - other[0], self[1] - other[1]])\n    }\n}\n\n// Four 32-bit floats\n\n#[derive(Clone, Copy, Default, PartialEq)]\npub struct F32x4(pub [f32; 4]);\n\nimpl F32x4 {\n    #[inline]\n    pub fn new(a: f32, b: f32, c: f32, d: f32) -> F32x4 {\n        F32x4([a, b, c, d])\n    }\n\n    #[inline]\n    pub fn splat(x: f32) -> F32x4 {\n        F32x4([x; 4])\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn approx_recip(self) -> F32x4 {\n        F32x4([1.0 / self[0], 1.0 / self[1], 1.0 / self[2], 1.0 / self[3]])\n    }\n\n    #[inline]\n    pub fn min(self, other: F32x4) -> F32x4 {\n        F32x4([\n            self[0].min(other[0]),\n            self[1].min(other[1]),\n            self[2].min(other[2]),\n            self[3].min(other[3]),\n        ])\n    }\n\n    #[inline]\n    pub fn max(self, other: F32x4) -> F32x4 {\n        F32x4([\n            self[0].max(other[0]),\n            self[1].max(other[1]),\n            self[2].max(other[2]),\n            self[3].max(other[3]),\n        ])\n    }\n\n    #[inline]\n    pub fn clamp(self, min: F32x4, max: F32x4) -> F32x4 {\n        self.max(min).min(max)\n    }\n\n    #[inline]\n    pub fn abs(self) -> F32x4 {\n        F32x4([self[0].abs(), self[1].abs(), self[2].abs(), self[3].abs()])\n    }\n\n    #[inline]\n    pub fn floor(self) -> F32x4 {\n        F32x4([\n            self[0].floor(),\n            self[1].floor(),\n            self[2].floor(),\n            self[3].floor(),\n        ])\n    }\n\n    #[inline]\n    pub fn ceil(self) -> F32x4 {\n        F32x4([\n            self[0].ceil(),\n            self[1].ceil(),\n            self[2].ceil(),\n            self[3].ceil(),\n        ])\n    }\n\n    #[inline]\n    pub fn sqrt(self) -> F32x4 {\n        F32x4([\n            self[0].sqrt(),\n            self[1].sqrt(),\n            self[2].sqrt(),\n            self[3].sqrt(),\n        ])\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: F32x4) -> U32x4 {\n        U32x4([\n            if self[0] == other[0] { !0 } else { 0 },\n            if self[1] == other[1] { !0 } else { 0 },\n            if self[2] == other[2] { !0 } else { 0 },\n            if self[3] == other[3] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_gt(self, other: F32x4) -> U32x4 {\n        U32x4([\n            if self[0] > other[0] { !0 } else { 0 },\n            if self[1] > other[1] { !0 } else { 0 },\n            if self[2] > other[2] { !0 } else { 0 },\n            if self[3] > other[3] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: F32x4) -> U32x4 {\n        U32x4([\n            if self[0] <= other[0] { !0 } else { 0 },\n            if self[1] <= other[1] { !0 } else { 0 },\n            if self[2] <= other[2] { !0 } else { 0 },\n            if self[3] <= other[3] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_lt(self, other: F32x4) -> U32x4 {\n        U32x4([\n            if self[0] < other[0] { !0 } else { 0 },\n            if self[1] < other[1] { !0 } else { 0 },\n            if self[2] < other[2] { !0 } else { 0 },\n            if self[3] < other[3] { !0 } else { 0 },\n        ])\n    }\n\n    /// Converts these packed floats to integers via rounding.\n    #[inline]\n    pub fn to_i32x4(self) -> I32x4 {\n        I32x4([\n            self[0].round_ties_even() as i32,\n            self[1].round_ties_even() as i32,\n            self[2].round_ties_even() as i32,\n            self[3].round_ties_even() as i32,\n        ])\n    }\n\n    // Swizzle conversions\n\n    #[inline]\n    pub fn xy(self) -> F32x2 {\n        F32x2([self[0], self[1]])\n    }\n\n    #[inline]\n    pub fn xw(self) -> F32x2 {\n        F32x2([self[0], self[3]])\n    }\n\n    #[inline]\n    pub fn yx(self) -> F32x2 {\n        F32x2([self[1], self[0]])\n    }\n\n    #[inline]\n    pub fn zy(self) -> F32x2 {\n        F32x2([self[2], self[1]])\n    }\n\n    #[inline]\n    pub fn zw(self) -> F32x2 {\n        F32x2([self[2], self[3]])\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: F32x4) -> F32x4 {\n        F32x4([self[0], self[1], other[0], other[1]])\n    }\n\n    #[inline]\n    pub fn concat_xy_zw(self, other: F32x4) -> F32x4 {\n        F32x4([self[0], self[1], other[2], other[3]])\n    }\n\n    #[inline]\n    pub fn concat_zw_zw(self, other: F32x4) -> F32x4 {\n        F32x4([self[2], self[3], other[2], other[3]])\n    }\n\n    #[inline]\n    pub fn concat_wz_yx(self, other: F32x4) -> F32x4 {\n        F32x4([self[3], self[2], other[1], other[0]])\n    }\n}\n\nimpl Index<usize> for F32x4 {\n    type Output = f32;\n    #[inline]\n    fn index(&self, index: usize) -> &f32 {\n        &self.0[index]\n    }\n}\n\nimpl IndexMut<usize> for F32x4 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut f32 {\n        &mut self.0[index]\n    }\n}\n\nimpl Debug for F32x4 {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {\n        write!(f, \"<{}, {}, {}, {}>\", self[0], self[1], self[2], self[3])\n    }\n}\n\nimpl Add<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn add(self, other: F32x4) -> F32x4 {\n        F32x4([\n            self[0] + other[0],\n            self[1] + other[1],\n            self[2] + other[2],\n            self[3] + other[3],\n        ])\n    }\n}\n\nimpl Div<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn div(self, other: F32x4) -> F32x4 {\n        F32x4([\n            self[0] / other[0],\n            self[1] / other[1],\n            self[2] / other[2],\n            self[3] / other[3],\n        ])\n    }\n}\n\nimpl Mul<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn mul(self, other: F32x4) -> F32x4 {\n        F32x4([\n            self[0] * other[0],\n            self[1] * other[1],\n            self[2] * other[2],\n            self[3] * other[3],\n        ])\n    }\n}\n\nimpl Sub<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn sub(self, other: F32x4) -> F32x4 {\n        F32x4([\n            self[0] - other[0],\n            self[1] - other[1],\n            self[2] - other[2],\n            self[3] - other[3],\n        ])\n    }\n}\n\n// Two 32-bit signed integers\n\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\npub struct I32x2([i32; 2]);\n\nimpl I32x2 {\n    #[inline]\n    pub fn new(x: i32, y: i32) -> I32x2 {\n        I32x2([x, y])\n    }\n\n    #[inline]\n    pub fn splat(x: i32) -> I32x2 {\n        I32x2([x, x])\n    }\n\n    // Accessors\n\n    #[inline]\n    pub fn x(self) -> i32 {\n        self[0]\n    }\n\n    #[inline]\n    pub fn y(self) -> i32 {\n        self[1]\n    }\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: I32x2) -> I32x4 {\n        I32x4([self[0], self[1], other[0], other[1]])\n    }\n\n    #[inline]\n    pub fn min(self, other: I32x2) -> I32x2 {\n        I32x2([\n            self[0].min(other[0]),\n            self[1].min(other[1]),\n        ])\n    }\n\n    #[inline]\n    pub fn max(self, other: I32x2) -> I32x2 {\n        I32x2([\n            self[0].max(other[0]),\n            self[1].max(other[1]),\n        ])\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: I32x2) -> U32x2 {\n        U32x2([\n            if self[0] == other[0] { !0 } else { 0 },\n            if self[1] == other[1] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_gt(self, other: I32x2) -> U32x2 {\n        U32x2([\n            if self[0] > other[0] { !0 } else { 0 },\n            if self[1] > other[1] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: I32x2) -> U32x2 {\n        U32x2([\n            if self[0] <= other[0] { !0 } else { 0 },\n            if self[1] <= other[1] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_lt(self, other: I32x2) -> U32x2 {\n        U32x2([\n            if self[0] < other[0] { !0 } else { 0 },\n            if self[1] < other[1] { !0 } else { 0 },\n        ])\n    } \n\n    // Conversions\n\n    /// Converts these packed integers to floats.\n    #[inline]\n    pub fn to_f32x2(self) -> F32x2 {\n        F32x2([self[0] as f32, self[1] as f32])\n    }\n}\n\nimpl Index<usize> for I32x2 {\n    type Output = i32;\n    #[inline]\n    fn index(&self, index: usize) -> &i32 {\n        &self.0[index]\n    }\n}\n\nimpl IndexMut<usize> for I32x2 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut i32 {\n        &mut self.0[index]\n    }\n}\n\nimpl Add<I32x2> for I32x2 {\n    type Output = I32x2;\n    #[inline]\n    fn add(self, other: I32x2) -> I32x2 {\n        I32x2([self[0] + other[0], self[1] + other[1]])\n    }\n}\n\nimpl Sub<I32x2> for I32x2 {\n    type Output = I32x2;\n    #[inline]\n    fn sub(self, other: I32x2) -> I32x2 {\n        I32x2([self[0] - other[0], self[1] - other[1]])\n    }\n}\n\nimpl Mul<I32x2> for I32x2 {\n    type Output = I32x2;\n    #[inline]\n    fn mul(self, other: I32x2) -> I32x2 {\n        I32x2([self[0] * other[0], self[1] * other[1]])\n    }\n}\n\n// Four 32-bit signed integers\n\n#[derive(Clone, Copy, Default, Debug, PartialEq)]\npub struct I32x4([i32; 4]);\n\nimpl I32x4 {\n    #[inline]\n    pub fn new(a: i32, b: i32, c: i32, d: i32) -> I32x4 {\n        I32x4([a, b, c, d])\n    }\n\n    #[inline]\n    pub fn splat(x: i32) -> I32x4 {\n        I32x4([x; 4])\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn min(self, other: I32x4) -> I32x4 {\n        I32x4([\n            self[0].min(other[0]),\n            self[1].min(other[1]),\n            self[2].min(other[2]),\n            self[3].min(other[3]),\n        ])\n    }\n\n    #[inline]\n    pub fn max(self, other: I32x4) -> I32x4 {\n        I32x4([\n            self[0].max(other[0]),\n            self[1].max(other[1]),\n            self[2].max(other[2]),\n            self[3].max(other[3]),\n        ])\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: I32x4) -> U32x4 {\n        U32x4([\n            if self[0] == other[0] { !0 } else { 0 },\n            if self[1] == other[1] { !0 } else { 0 },\n            if self[2] == other[2] { !0 } else { 0 },\n            if self[3] == other[3] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_gt(self, other: I32x4) -> U32x4 {\n        U32x4([\n            if self[0] > other[0] { !0 } else { 0 },\n            if self[1] > other[1] { !0 } else { 0 },\n            if self[2] > other[2] { !0 } else { 0 },\n            if self[3] > other[3] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: I32x4) -> U32x4 {\n        U32x4([\n            if self[0] <= other[0] { !0 } else { 0 },\n            if self[1] <= other[1] { !0 } else { 0 },\n            if self[2] <= other[2] { !0 } else { 0 },\n            if self[3] <= other[3] { !0 } else { 0 },\n        ])\n    }\n\n    #[inline]\n    pub fn packed_lt(self, other: I32x4) -> U32x4 {\n        U32x4([\n            if self[0] < other[0] { !0 } else { 0 },\n            if self[1] < other[1] { !0 } else { 0 },\n            if self[2] < other[2] { !0 } else { 0 },\n            if self[3] < other[3] { !0 } else { 0 },\n        ])\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: I32x4) -> I32x4 {\n        I32x4([self[0], self[1], other[0], other[1]])\n    }\n\n    #[inline]\n    pub fn concat_zw_zw(self, other: I32x4) -> I32x4 {\n        I32x4([self[2], self[3], other[2], other[3]])\n    }\n\n    // Swizzle conversions\n\n    #[inline]\n    pub fn xy(self) -> I32x2 {\n        I32x2([self[0], self[1]])\n    }\n\n    #[inline]\n    pub fn xw(self) -> I32x2 {\n        I32x2([self[0], self[3]])\n    }\n\n    #[inline]\n    pub fn zy(self) -> I32x2 {\n        I32x2([self[2], self[1]])\n    }\n\n    #[inline]\n    pub fn zw(self) -> I32x2 {\n        I32x2([self[2], self[3]])\n    }\n\n    // Conversions\n\n    /// Converts these packed integers to floats.\n    #[inline]\n    pub fn to_f32x4(self) -> F32x4 {\n        F32x4([\n            self[0] as f32,\n            self[1] as f32,\n            self[2] as f32,\n            self[3] as f32,\n        ])\n    }\n\n    /// Converts these packed signed integers to unsigned integers.\n    ///\n    /// Overflowing values will wrap around.\n    ///\n    /// FIXME(pcwalton): Should they? This will assert on overflow in debug.\n    #[inline]\n    pub fn to_u32x4(self) -> U32x4 {\n        U32x4([self[0] as u32, self[1] as u32, self[2] as u32, self[3] as u32])\n    }\n}\n\nimpl Index<usize> for I32x4 {\n    type Output = i32;\n    #[inline]\n    fn index(&self, index: usize) -> &i32 {\n        &self.0[index]\n    }\n}\n\nimpl IndexMut<usize> for I32x4 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut i32 {\n        &mut self.0[index]\n    }\n}\n\nimpl Add<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn add(self, other: I32x4) -> I32x4 {\n        I32x4([\n            self[0] + other[0],\n            self[1] + other[1],\n            self[2] + other[2],\n            self[3] + other[3],\n        ])\n    }\n}\n\nimpl Sub<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn sub(self, other: I32x4) -> I32x4 {\n        I32x4([\n            self[0] - other[0],\n            self[1] - other[1],\n            self[2] - other[2],\n            self[3] - other[3],\n        ])\n    }\n}\n\nimpl Mul<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn mul(self, other: I32x4) -> I32x4 {\n        I32x4([\n            self[0] * other[0],\n            self[1] * other[1],\n            self[2] * other[2],\n            self[3] * other[3],\n        ])\n    }\n}\n\nimpl BitAnd<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn bitand(self, other: I32x4) -> I32x4 {\n        I32x4([self[0] & other[0], self[1] & other[1], self[2] & other[2], self[3] & other[3]])\n    }\n}\n\nimpl BitOr<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn bitor(self, other: I32x4) -> I32x4 {\n        I32x4([self[0] | other[0], self[1] | other[1], self[2] | other[2], self[3] | other[3]])\n    }\n}\n\nimpl Shr<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn shr(self, other: I32x4) -> I32x4 {\n        I32x4([\n            self[0] >> other[0],\n            self[1] >> other[1],\n            self[2] >> other[2],\n            self[3] >> other[3],\n        ])\n    }\n}\n\n// Two 32-bit unsigned integers\n\n#[derive(Clone, Copy)]\npub struct U32x2(pub [u32; 2]);\n\nimpl U32x2 {\n    #[inline]\n    pub fn new(x: u32, y: u32) -> U32x2 {\n        U32x2([x, y])\n    }\n\n    #[inline]\n    pub fn splat(x: u32) -> U32x2 {\n        U32x2::new(x, x)\n    }\n\n    /// Returns true if both booleans in this vector are true.\n    ///\n    /// The result is *undefined* if both values in this vector are not booleans. A boolean is a\n    /// value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_true(&self) -> bool {\n        self[0] == !0 && self[1] == !0\n    }\n\n    /// Returns true if both booleans in this vector are false.\n    ///\n    /// The result is *undefined* if both values in this vector are not booleans. A boolean is a\n    /// value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_false(&self) -> bool {\n        self[0] == 0 && self[1] == 0\n    }\n\n    #[inline]\n    pub fn to_i32x2(self) -> I32x2 {\n        I32x2::new(self[0] as i32, self[1] as i32)\n    }\n\n}\n\nimpl BitAnd<U32x2> for U32x2 {\n    type Output = U32x2;\n    #[inline]\n    fn bitand(self, other: U32x2) -> U32x2 {\n        U32x2([self[0] & other[0], self[1] & other[1]])\n    }\n}\n\nimpl BitOr<U32x2> for U32x2 {\n    type Output = U32x2;\n    #[inline]\n    fn bitor(self, other: U32x2) -> U32x2 {\n        U32x2([self[0] | other[0], self[1] | other[1]])\n    }\n}\n\nimpl Not for U32x2 {\n    type Output = U32x2;\n    #[inline]\n    fn not(self) -> U32x2 {\n        U32x2([!self[0], !self[1]])\n    }\n}\n\nimpl Index<usize> for U32x2 {\n    type Output = u32;\n    #[inline]\n    fn index(&self, index: usize) -> &u32 {\n        &self.0[index]\n    }\n}\n\n// Four 32-bit unsigned integers\n\n#[derive(Clone, Copy, PartialEq, Eq, Debug)]\npub struct U32x4(pub [u32; 4]);\n\nimpl U32x4 {\n    pub fn new(a: u32, b: u32, c: u32, d: u32) -> U32x4 {\n        U32x4([a, b, c, d])\n    }\n\n    // Conversions\n\n    /// Converts these packed unsigned integers to signed integers.\n    ///\n    /// Overflowing values will wrap around.\n    ///\n    /// FIXME(pcwalton): Should they? This will assert on overflow in debug.\n    #[inline]\n    pub fn to_i32x4(self) -> I32x4 {\n        I32x4([self[0] as i32, self[1] as i32, self[2] as i32, self[3] as i32])\n    }\n\n    // Basic operations\n\n    /// Returns true if all four booleans in this vector are true.\n    ///\n    /// The result is *undefined* if all four values in this vector are not booleans. A boolean is\n    /// a value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_true(&self) -> bool {\n        self[0] == !0 && self[1] == !0 && self[2] == !0 && self[3] == !0\n    }\n\n    /// Returns true if all four booleans in this vector are false.\n    ///\n    /// The result is *undefined* if all four values in this vector are not booleans. A boolean is\n    /// a value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_false(&self) -> bool {\n        self[0] == 0 && self[1] == 0 && self[2] == 0 && self[3] == 0\n    }\n}\n\nimpl Index<usize> for U32x4 {\n    type Output = u32;\n    #[inline]\n    fn index(&self, index: usize) -> &u32 {\n        &self.0[index]\n    }\n}\n\nimpl Shr<u32> for U32x4 {\n    type Output = U32x4;\n    #[inline]\n    fn shr(self, amount: u32) -> U32x4 {\n        U32x4([self[0] >> amount, self[1] >> amount, self[2] >> amount, self[3] >> amount])\n    }\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/scalar/swizzle_f32x4.rs",
      "sha256": "0b243334740f3004ca870c2eb57b69bec32fa90a23c35f96b119529eb8e11557",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/scalar/swizzle_f32x4.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::scalar::F32x4;\n\nimpl F32x4 {\n    /// Constructs a new vector from the first, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxx(self) -> F32x4 {\n        F32x4([self[0], self[0], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the second, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxx(self) -> F32x4 {\n        F32x4([self[1], self[0], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the third, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxx(self) -> F32x4 {\n        F32x4([self[2], self[0], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxx(self) -> F32x4 {\n        F32x4([self[3], self[0], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the first, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxx(self) -> F32x4 {\n        F32x4([self[0], self[1], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the second, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxx(self) -> F32x4 {\n        F32x4([self[1], self[1], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the third, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxx(self) -> F32x4 {\n        F32x4([self[2], self[1], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxx(self) -> F32x4 {\n        F32x4([self[3], self[1], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the first, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxx(self) -> F32x4 {\n        F32x4([self[0], self[2], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the second, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxx(self) -> F32x4 {\n        F32x4([self[1], self[2], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the third, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxx(self) -> F32x4 {\n        F32x4([self[2], self[2], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxx(self) -> F32x4 {\n        F32x4([self[3], self[2], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxx(self) -> F32x4 {\n        F32x4([self[0], self[3], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxx(self) -> F32x4 {\n        F32x4([self[1], self[3], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxx(self) -> F32x4 {\n        F32x4([self[2], self[3], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxx(self) -> F32x4 {\n        F32x4([self[3], self[3], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the first, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyx(self) -> F32x4 {\n        F32x4([self[0], self[0], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the second, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyx(self) -> F32x4 {\n        F32x4([self[1], self[0], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the third, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyx(self) -> F32x4 {\n        F32x4([self[2], self[0], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyx(self) -> F32x4 {\n        F32x4([self[3], self[0], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the first, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyx(self) -> F32x4 {\n        F32x4([self[0], self[1], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the second, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyx(self) -> F32x4 {\n        F32x4([self[1], self[1], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the third, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyx(self) -> F32x4 {\n        F32x4([self[2], self[1], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyx(self) -> F32x4 {\n        F32x4([self[3], self[1], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the first, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyx(self) -> F32x4 {\n        F32x4([self[0], self[2], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the second, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyx(self) -> F32x4 {\n        F32x4([self[1], self[2], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the third, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyx(self) -> F32x4 {\n        F32x4([self[2], self[2], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyx(self) -> F32x4 {\n        F32x4([self[3], self[2], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyx(self) -> F32x4 {\n        F32x4([self[0], self[3], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyx(self) -> F32x4 {\n        F32x4([self[1], self[3], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyx(self) -> F32x4 {\n        F32x4([self[2], self[3], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyx(self) -> F32x4 {\n        F32x4([self[3], self[3], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the first, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzx(self) -> F32x4 {\n        F32x4([self[0], self[0], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the second, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzx(self) -> F32x4 {\n        F32x4([self[1], self[0], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the third, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzx(self) -> F32x4 {\n        F32x4([self[2], self[0], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzx(self) -> F32x4 {\n        F32x4([self[3], self[0], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the first, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzx(self) -> F32x4 {\n        F32x4([self[0], self[1], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the second, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzx(self) -> F32x4 {\n        F32x4([self[1], self[1], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the third, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzx(self) -> F32x4 {\n        F32x4([self[2], self[1], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzx(self) -> F32x4 {\n        F32x4([self[3], self[1], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the first, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzx(self) -> F32x4 {\n        F32x4([self[0], self[2], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the second, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzx(self) -> F32x4 {\n        F32x4([self[1], self[2], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the third, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzx(self) -> F32x4 {\n        F32x4([self[2], self[2], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzx(self) -> F32x4 {\n        F32x4([self[3], self[2], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzx(self) -> F32x4 {\n        F32x4([self[0], self[3], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzx(self) -> F32x4 {\n        F32x4([self[1], self[3], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzx(self) -> F32x4 {\n        F32x4([self[2], self[3], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzx(self) -> F32x4 {\n        F32x4([self[3], self[3], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwx(self) -> F32x4 {\n        F32x4([self[0], self[0], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwx(self) -> F32x4 {\n        F32x4([self[1], self[0], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwx(self) -> F32x4 {\n        F32x4([self[2], self[0], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwx(self) -> F32x4 {\n        F32x4([self[3], self[0], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywx(self) -> F32x4 {\n        F32x4([self[0], self[1], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywx(self) -> F32x4 {\n        F32x4([self[1], self[1], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywx(self) -> F32x4 {\n        F32x4([self[2], self[1], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywx(self) -> F32x4 {\n        F32x4([self[3], self[1], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwx(self) -> F32x4 {\n        F32x4([self[0], self[2], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwx(self) -> F32x4 {\n        F32x4([self[1], self[2], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwx(self) -> F32x4 {\n        F32x4([self[2], self[2], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwx(self) -> F32x4 {\n        F32x4([self[3], self[2], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwx(self) -> F32x4 {\n        F32x4([self[0], self[3], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwx(self) -> F32x4 {\n        F32x4([self[1], self[3], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwx(self) -> F32x4 {\n        F32x4([self[2], self[3], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwx(self) -> F32x4 {\n        F32x4([self[3], self[3], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the first, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxy(self) -> F32x4 {\n        F32x4([self[0], self[0], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the second, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxy(self) -> F32x4 {\n        F32x4([self[1], self[0], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the third, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxy(self) -> F32x4 {\n        F32x4([self[2], self[0], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxy(self) -> F32x4 {\n        F32x4([self[3], self[0], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the first, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxy(self) -> F32x4 {\n        F32x4([self[0], self[1], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the second, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxy(self) -> F32x4 {\n        F32x4([self[1], self[1], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the third, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxy(self) -> F32x4 {\n        F32x4([self[2], self[1], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxy(self) -> F32x4 {\n        F32x4([self[3], self[1], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the first, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxy(self) -> F32x4 {\n        F32x4([self[0], self[2], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the second, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxy(self) -> F32x4 {\n        F32x4([self[1], self[2], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the third, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxy(self) -> F32x4 {\n        F32x4([self[2], self[2], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxy(self) -> F32x4 {\n        F32x4([self[3], self[2], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxy(self) -> F32x4 {\n        F32x4([self[0], self[3], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxy(self) -> F32x4 {\n        F32x4([self[1], self[3], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxy(self) -> F32x4 {\n        F32x4([self[2], self[3], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxy(self) -> F32x4 {\n        F32x4([self[3], self[3], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the first, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyy(self) -> F32x4 {\n        F32x4([self[0], self[0], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the second, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyy(self) -> F32x4 {\n        F32x4([self[1], self[0], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the third, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyy(self) -> F32x4 {\n        F32x4([self[2], self[0], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyy(self) -> F32x4 {\n        F32x4([self[3], self[0], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the first, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyy(self) -> F32x4 {\n        F32x4([self[0], self[1], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the second, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyy(self) -> F32x4 {\n        F32x4([self[1], self[1], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the third, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyy(self) -> F32x4 {\n        F32x4([self[2], self[1], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyy(self) -> F32x4 {\n        F32x4([self[3], self[1], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the first, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyy(self) -> F32x4 {\n        F32x4([self[0], self[2], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the second, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyy(self) -> F32x4 {\n        F32x4([self[1], self[2], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the third, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyy(self) -> F32x4 {\n        F32x4([self[2], self[2], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyy(self) -> F32x4 {\n        F32x4([self[3], self[2], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyy(self) -> F32x4 {\n        F32x4([self[0], self[3], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyy(self) -> F32x4 {\n        F32x4([self[1], self[3], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyy(self) -> F32x4 {\n        F32x4([self[2], self[3], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyy(self) -> F32x4 {\n        F32x4([self[3], self[3], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the first, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzy(self) -> F32x4 {\n        F32x4([self[0], self[0], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the second, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzy(self) -> F32x4 {\n        F32x4([self[1], self[0], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the third, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzy(self) -> F32x4 {\n        F32x4([self[2], self[0], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzy(self) -> F32x4 {\n        F32x4([self[3], self[0], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the first, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzy(self) -> F32x4 {\n        F32x4([self[0], self[1], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the second, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzy(self) -> F32x4 {\n        F32x4([self[1], self[1], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the third, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzy(self) -> F32x4 {\n        F32x4([self[2], self[1], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzy(self) -> F32x4 {\n        F32x4([self[3], self[1], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the first, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzy(self) -> F32x4 {\n        F32x4([self[0], self[2], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the second, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzy(self) -> F32x4 {\n        F32x4([self[1], self[2], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the third, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzy(self) -> F32x4 {\n        F32x4([self[2], self[2], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzy(self) -> F32x4 {\n        F32x4([self[3], self[2], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzy(self) -> F32x4 {\n        F32x4([self[0], self[3], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzy(self) -> F32x4 {\n        F32x4([self[1], self[3], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzy(self) -> F32x4 {\n        F32x4([self[2], self[3], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzy(self) -> F32x4 {\n        F32x4([self[3], self[3], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwy(self) -> F32x4 {\n        F32x4([self[0], self[0], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwy(self) -> F32x4 {\n        F32x4([self[1], self[0], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwy(self) -> F32x4 {\n        F32x4([self[2], self[0], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwy(self) -> F32x4 {\n        F32x4([self[3], self[0], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywy(self) -> F32x4 {\n        F32x4([self[0], self[1], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywy(self) -> F32x4 {\n        F32x4([self[1], self[1], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywy(self) -> F32x4 {\n        F32x4([self[2], self[1], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywy(self) -> F32x4 {\n        F32x4([self[3], self[1], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwy(self) -> F32x4 {\n        F32x4([self[0], self[2], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwy(self) -> F32x4 {\n        F32x4([self[1], self[2], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwy(self) -> F32x4 {\n        F32x4([self[2], self[2], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwy(self) -> F32x4 {\n        F32x4([self[3], self[2], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwy(self) -> F32x4 {\n        F32x4([self[0], self[3], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwy(self) -> F32x4 {\n        F32x4([self[1], self[3], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwy(self) -> F32x4 {\n        F32x4([self[2], self[3], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwy(self) -> F32x4 {\n        F32x4([self[3], self[3], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the first, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxz(self) -> F32x4 {\n        F32x4([self[0], self[0], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the second, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxz(self) -> F32x4 {\n        F32x4([self[1], self[0], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the third, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxz(self) -> F32x4 {\n        F32x4([self[2], self[0], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxz(self) -> F32x4 {\n        F32x4([self[3], self[0], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the first, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxz(self) -> F32x4 {\n        F32x4([self[0], self[1], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the second, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxz(self) -> F32x4 {\n        F32x4([self[1], self[1], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the third, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxz(self) -> F32x4 {\n        F32x4([self[2], self[1], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxz(self) -> F32x4 {\n        F32x4([self[3], self[1], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the first, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxz(self) -> F32x4 {\n        F32x4([self[0], self[2], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the second, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxz(self) -> F32x4 {\n        F32x4([self[1], self[2], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the third, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxz(self) -> F32x4 {\n        F32x4([self[2], self[2], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxz(self) -> F32x4 {\n        F32x4([self[3], self[2], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxz(self) -> F32x4 {\n        F32x4([self[0], self[3], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxz(self) -> F32x4 {\n        F32x4([self[1], self[3], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxz(self) -> F32x4 {\n        F32x4([self[2], self[3], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxz(self) -> F32x4 {\n        F32x4([self[3], self[3], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the first, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyz(self) -> F32x4 {\n        F32x4([self[0], self[0], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the second, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyz(self) -> F32x4 {\n        F32x4([self[1], self[0], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the third, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyz(self) -> F32x4 {\n        F32x4([self[2], self[0], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyz(self) -> F32x4 {\n        F32x4([self[3], self[0], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the first, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyz(self) -> F32x4 {\n        F32x4([self[0], self[1], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the second, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyz(self) -> F32x4 {\n        F32x4([self[1], self[1], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the third, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyz(self) -> F32x4 {\n        F32x4([self[2], self[1], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyz(self) -> F32x4 {\n        F32x4([self[3], self[1], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the first, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyz(self) -> F32x4 {\n        F32x4([self[0], self[2], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the second, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyz(self) -> F32x4 {\n        F32x4([self[1], self[2], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the third, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyz(self) -> F32x4 {\n        F32x4([self[2], self[2], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyz(self) -> F32x4 {\n        F32x4([self[3], self[2], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyz(self) -> F32x4 {\n        F32x4([self[0], self[3], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyz(self) -> F32x4 {\n        F32x4([self[1], self[3], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyz(self) -> F32x4 {\n        F32x4([self[2], self[3], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyz(self) -> F32x4 {\n        F32x4([self[3], self[3], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the first, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzz(self) -> F32x4 {\n        F32x4([self[0], self[0], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the second, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzz(self) -> F32x4 {\n        F32x4([self[1], self[0], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the third, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzz(self) -> F32x4 {\n        F32x4([self[2], self[0], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzz(self) -> F32x4 {\n        F32x4([self[3], self[0], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the first, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzz(self) -> F32x4 {\n        F32x4([self[0], self[1], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the second, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzz(self) -> F32x4 {\n        F32x4([self[1], self[1], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the third, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzz(self) -> F32x4 {\n        F32x4([self[2], self[1], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzz(self) -> F32x4 {\n        F32x4([self[3], self[1], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the first, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzz(self) -> F32x4 {\n        F32x4([self[0], self[2], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the second, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzz(self) -> F32x4 {\n        F32x4([self[1], self[2], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the third, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzz(self) -> F32x4 {\n        F32x4([self[2], self[2], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzz(self) -> F32x4 {\n        F32x4([self[3], self[2], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzz(self) -> F32x4 {\n        F32x4([self[0], self[3], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzz(self) -> F32x4 {\n        F32x4([self[1], self[3], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzz(self) -> F32x4 {\n        F32x4([self[2], self[3], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzz(self) -> F32x4 {\n        F32x4([self[3], self[3], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwz(self) -> F32x4 {\n        F32x4([self[0], self[0], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwz(self) -> F32x4 {\n        F32x4([self[1], self[0], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwz(self) -> F32x4 {\n        F32x4([self[2], self[0], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwz(self) -> F32x4 {\n        F32x4([self[3], self[0], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywz(self) -> F32x4 {\n        F32x4([self[0], self[1], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywz(self) -> F32x4 {\n        F32x4([self[1], self[1], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywz(self) -> F32x4 {\n        F32x4([self[2], self[1], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywz(self) -> F32x4 {\n        F32x4([self[3], self[1], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwz(self) -> F32x4 {\n        F32x4([self[0], self[2], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwz(self) -> F32x4 {\n        F32x4([self[1], self[2], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwz(self) -> F32x4 {\n        F32x4([self[2], self[2], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwz(self) -> F32x4 {\n        F32x4([self[3], self[2], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwz(self) -> F32x4 {\n        F32x4([self[0], self[3], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwz(self) -> F32x4 {\n        F32x4([self[1], self[3], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwz(self) -> F32x4 {\n        F32x4([self[2], self[3], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwz(self) -> F32x4 {\n        F32x4([self[3], self[3], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the first, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxw(self) -> F32x4 {\n        F32x4([self[0], self[0], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the second, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxw(self) -> F32x4 {\n        F32x4([self[1], self[0], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the third, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxw(self) -> F32x4 {\n        F32x4([self[2], self[0], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxw(self) -> F32x4 {\n        F32x4([self[3], self[0], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the first, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxw(self) -> F32x4 {\n        F32x4([self[0], self[1], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the second, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxw(self) -> F32x4 {\n        F32x4([self[1], self[1], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the third, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxw(self) -> F32x4 {\n        F32x4([self[2], self[1], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxw(self) -> F32x4 {\n        F32x4([self[3], self[1], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the first, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxw(self) -> F32x4 {\n        F32x4([self[0], self[2], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the second, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxw(self) -> F32x4 {\n        F32x4([self[1], self[2], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the third, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxw(self) -> F32x4 {\n        F32x4([self[2], self[2], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxw(self) -> F32x4 {\n        F32x4([self[3], self[2], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxw(self) -> F32x4 {\n        F32x4([self[0], self[3], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxw(self) -> F32x4 {\n        F32x4([self[1], self[3], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxw(self) -> F32x4 {\n        F32x4([self[2], self[3], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxw(self) -> F32x4 {\n        F32x4([self[3], self[3], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the first, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyw(self) -> F32x4 {\n        F32x4([self[0], self[0], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the second, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyw(self) -> F32x4 {\n        F32x4([self[1], self[0], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the third, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyw(self) -> F32x4 {\n        F32x4([self[2], self[0], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyw(self) -> F32x4 {\n        F32x4([self[3], self[0], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the first, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyw(self) -> F32x4 {\n        F32x4([self[0], self[1], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the second, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyw(self) -> F32x4 {\n        F32x4([self[1], self[1], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the third, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyw(self) -> F32x4 {\n        F32x4([self[2], self[1], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyw(self) -> F32x4 {\n        F32x4([self[3], self[1], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the first, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyw(self) -> F32x4 {\n        F32x4([self[0], self[2], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the second, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyw(self) -> F32x4 {\n        F32x4([self[1], self[2], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the third, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyw(self) -> F32x4 {\n        F32x4([self[2], self[2], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyw(self) -> F32x4 {\n        F32x4([self[3], self[2], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyw(self) -> F32x4 {\n        F32x4([self[0], self[3], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyw(self) -> F32x4 {\n        F32x4([self[1], self[3], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyw(self) -> F32x4 {\n        F32x4([self[2], self[3], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyw(self) -> F32x4 {\n        F32x4([self[3], self[3], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the first, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzw(self) -> F32x4 {\n        F32x4([self[0], self[0], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the second, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzw(self) -> F32x4 {\n        F32x4([self[1], self[0], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the third, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzw(self) -> F32x4 {\n        F32x4([self[2], self[0], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzw(self) -> F32x4 {\n        F32x4([self[3], self[0], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the first, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzw(self) -> F32x4 {\n        F32x4([self[0], self[1], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the second, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzw(self) -> F32x4 {\n        F32x4([self[1], self[1], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the third, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzw(self) -> F32x4 {\n        F32x4([self[2], self[1], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzw(self) -> F32x4 {\n        F32x4([self[3], self[1], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the first, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzw(self) -> F32x4 {\n        F32x4([self[0], self[2], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the second, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzw(self) -> F32x4 {\n        F32x4([self[1], self[2], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the third, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzw(self) -> F32x4 {\n        F32x4([self[2], self[2], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzw(self) -> F32x4 {\n        F32x4([self[3], self[2], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzw(self) -> F32x4 {\n        F32x4([self[0], self[3], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzw(self) -> F32x4 {\n        F32x4([self[1], self[3], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzw(self) -> F32x4 {\n        F32x4([self[2], self[3], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzw(self) -> F32x4 {\n        F32x4([self[3], self[3], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxww(self) -> F32x4 {\n        F32x4([self[0], self[0], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxww(self) -> F32x4 {\n        F32x4([self[1], self[0], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxww(self) -> F32x4 {\n        F32x4([self[2], self[0], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxww(self) -> F32x4 {\n        F32x4([self[3], self[0], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyww(self) -> F32x4 {\n        F32x4([self[0], self[1], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyww(self) -> F32x4 {\n        F32x4([self[1], self[1], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyww(self) -> F32x4 {\n        F32x4([self[2], self[1], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyww(self) -> F32x4 {\n        F32x4([self[3], self[1], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzww(self) -> F32x4 {\n        F32x4([self[0], self[2], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzww(self) -> F32x4 {\n        F32x4([self[1], self[2], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzww(self) -> F32x4 {\n        F32x4([self[2], self[2], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzww(self) -> F32x4 {\n        F32x4([self[3], self[2], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwww(self) -> F32x4 {\n        F32x4([self[0], self[3], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywww(self) -> F32x4 {\n        F32x4([self[1], self[3], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwww(self) -> F32x4 {\n        F32x4([self[2], self[3], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwww(self) -> F32x4 {\n        F32x4([self[3], self[3], self[3], self[3]])\n    }\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/scalar/swizzle_i32x4.rs",
      "sha256": "1612776f2bc21fbbb5b0770a90b9b248abae28ad6e3a5585abad5b8bbfa499bd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/scalar/swizzle_i32x4.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::scalar::I32x4;\n\nimpl I32x4 {\n    /// Constructs a new vector from the first, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxx(self) -> I32x4 {\n        I32x4([self[0], self[0], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the second, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxx(self) -> I32x4 {\n        I32x4([self[1], self[0], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the third, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxx(self) -> I32x4 {\n        I32x4([self[2], self[0], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxx(self) -> I32x4 {\n        I32x4([self[3], self[0], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the first, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxx(self) -> I32x4 {\n        I32x4([self[0], self[1], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the second, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxx(self) -> I32x4 {\n        I32x4([self[1], self[1], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the third, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxx(self) -> I32x4 {\n        I32x4([self[2], self[1], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxx(self) -> I32x4 {\n        I32x4([self[3], self[1], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the first, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxx(self) -> I32x4 {\n        I32x4([self[0], self[2], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the second, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxx(self) -> I32x4 {\n        I32x4([self[1], self[2], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the third, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxx(self) -> I32x4 {\n        I32x4([self[2], self[2], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxx(self) -> I32x4 {\n        I32x4([self[3], self[2], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxx(self) -> I32x4 {\n        I32x4([self[0], self[3], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxx(self) -> I32x4 {\n        I32x4([self[1], self[3], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxx(self) -> I32x4 {\n        I32x4([self[2], self[3], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxx(self) -> I32x4 {\n        I32x4([self[3], self[3], self[0], self[0]])\n    }\n\n    /// Constructs a new vector from the first, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyx(self) -> I32x4 {\n        I32x4([self[0], self[0], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the second, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyx(self) -> I32x4 {\n        I32x4([self[1], self[0], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the third, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyx(self) -> I32x4 {\n        I32x4([self[2], self[0], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyx(self) -> I32x4 {\n        I32x4([self[3], self[0], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the first, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyx(self) -> I32x4 {\n        I32x4([self[0], self[1], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the second, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyx(self) -> I32x4 {\n        I32x4([self[1], self[1], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the third, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyx(self) -> I32x4 {\n        I32x4([self[2], self[1], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyx(self) -> I32x4 {\n        I32x4([self[3], self[1], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the first, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyx(self) -> I32x4 {\n        I32x4([self[0], self[2], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the second, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyx(self) -> I32x4 {\n        I32x4([self[1], self[2], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the third, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyx(self) -> I32x4 {\n        I32x4([self[2], self[2], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyx(self) -> I32x4 {\n        I32x4([self[3], self[2], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyx(self) -> I32x4 {\n        I32x4([self[0], self[3], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyx(self) -> I32x4 {\n        I32x4([self[1], self[3], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyx(self) -> I32x4 {\n        I32x4([self[2], self[3], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyx(self) -> I32x4 {\n        I32x4([self[3], self[3], self[1], self[0]])\n    }\n\n    /// Constructs a new vector from the first, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzx(self) -> I32x4 {\n        I32x4([self[0], self[0], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the second, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzx(self) -> I32x4 {\n        I32x4([self[1], self[0], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the third, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzx(self) -> I32x4 {\n        I32x4([self[2], self[0], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzx(self) -> I32x4 {\n        I32x4([self[3], self[0], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the first, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzx(self) -> I32x4 {\n        I32x4([self[0], self[1], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the second, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzx(self) -> I32x4 {\n        I32x4([self[1], self[1], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the third, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzx(self) -> I32x4 {\n        I32x4([self[2], self[1], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzx(self) -> I32x4 {\n        I32x4([self[3], self[1], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the first, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzx(self) -> I32x4 {\n        I32x4([self[0], self[2], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the second, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzx(self) -> I32x4 {\n        I32x4([self[1], self[2], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the third, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzx(self) -> I32x4 {\n        I32x4([self[2], self[2], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzx(self) -> I32x4 {\n        I32x4([self[3], self[2], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzx(self) -> I32x4 {\n        I32x4([self[0], self[3], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzx(self) -> I32x4 {\n        I32x4([self[1], self[3], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzx(self) -> I32x4 {\n        I32x4([self[2], self[3], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzx(self) -> I32x4 {\n        I32x4([self[3], self[3], self[2], self[0]])\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwx(self) -> I32x4 {\n        I32x4([self[0], self[0], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwx(self) -> I32x4 {\n        I32x4([self[1], self[0], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwx(self) -> I32x4 {\n        I32x4([self[2], self[0], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwx(self) -> I32x4 {\n        I32x4([self[3], self[0], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywx(self) -> I32x4 {\n        I32x4([self[0], self[1], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywx(self) -> I32x4 {\n        I32x4([self[1], self[1], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywx(self) -> I32x4 {\n        I32x4([self[2], self[1], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywx(self) -> I32x4 {\n        I32x4([self[3], self[1], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwx(self) -> I32x4 {\n        I32x4([self[0], self[2], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwx(self) -> I32x4 {\n        I32x4([self[1], self[2], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwx(self) -> I32x4 {\n        I32x4([self[2], self[2], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwx(self) -> I32x4 {\n        I32x4([self[3], self[2], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwx(self) -> I32x4 {\n        I32x4([self[0], self[3], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwx(self) -> I32x4 {\n        I32x4([self[1], self[3], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwx(self) -> I32x4 {\n        I32x4([self[2], self[3], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and first\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwx(self) -> I32x4 {\n        I32x4([self[3], self[3], self[3], self[0]])\n    }\n\n    /// Constructs a new vector from the first, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxy(self) -> I32x4 {\n        I32x4([self[0], self[0], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the second, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxy(self) -> I32x4 {\n        I32x4([self[1], self[0], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the third, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxy(self) -> I32x4 {\n        I32x4([self[2], self[0], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxy(self) -> I32x4 {\n        I32x4([self[3], self[0], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the first, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxy(self) -> I32x4 {\n        I32x4([self[0], self[1], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the second, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxy(self) -> I32x4 {\n        I32x4([self[1], self[1], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the third, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxy(self) -> I32x4 {\n        I32x4([self[2], self[1], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxy(self) -> I32x4 {\n        I32x4([self[3], self[1], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the first, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxy(self) -> I32x4 {\n        I32x4([self[0], self[2], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the second, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxy(self) -> I32x4 {\n        I32x4([self[1], self[2], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the third, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxy(self) -> I32x4 {\n        I32x4([self[2], self[2], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxy(self) -> I32x4 {\n        I32x4([self[3], self[2], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxy(self) -> I32x4 {\n        I32x4([self[0], self[3], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxy(self) -> I32x4 {\n        I32x4([self[1], self[3], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxy(self) -> I32x4 {\n        I32x4([self[2], self[3], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxy(self) -> I32x4 {\n        I32x4([self[3], self[3], self[0], self[1]])\n    }\n\n    /// Constructs a new vector from the first, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyy(self) -> I32x4 {\n        I32x4([self[0], self[0], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the second, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyy(self) -> I32x4 {\n        I32x4([self[1], self[0], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the third, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyy(self) -> I32x4 {\n        I32x4([self[2], self[0], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyy(self) -> I32x4 {\n        I32x4([self[3], self[0], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the first, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyy(self) -> I32x4 {\n        I32x4([self[0], self[1], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the second, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyy(self) -> I32x4 {\n        I32x4([self[1], self[1], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the third, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyy(self) -> I32x4 {\n        I32x4([self[2], self[1], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyy(self) -> I32x4 {\n        I32x4([self[3], self[1], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the first, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyy(self) -> I32x4 {\n        I32x4([self[0], self[2], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the second, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyy(self) -> I32x4 {\n        I32x4([self[1], self[2], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the third, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyy(self) -> I32x4 {\n        I32x4([self[2], self[2], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyy(self) -> I32x4 {\n        I32x4([self[3], self[2], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyy(self) -> I32x4 {\n        I32x4([self[0], self[3], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyy(self) -> I32x4 {\n        I32x4([self[1], self[3], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyy(self) -> I32x4 {\n        I32x4([self[2], self[3], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyy(self) -> I32x4 {\n        I32x4([self[3], self[3], self[1], self[1]])\n    }\n\n    /// Constructs a new vector from the first, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzy(self) -> I32x4 {\n        I32x4([self[0], self[0], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the second, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzy(self) -> I32x4 {\n        I32x4([self[1], self[0], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the third, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzy(self) -> I32x4 {\n        I32x4([self[2], self[0], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzy(self) -> I32x4 {\n        I32x4([self[3], self[0], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the first, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzy(self) -> I32x4 {\n        I32x4([self[0], self[1], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the second, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzy(self) -> I32x4 {\n        I32x4([self[1], self[1], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the third, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzy(self) -> I32x4 {\n        I32x4([self[2], self[1], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzy(self) -> I32x4 {\n        I32x4([self[3], self[1], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the first, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzy(self) -> I32x4 {\n        I32x4([self[0], self[2], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the second, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzy(self) -> I32x4 {\n        I32x4([self[1], self[2], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the third, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzy(self) -> I32x4 {\n        I32x4([self[2], self[2], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzy(self) -> I32x4 {\n        I32x4([self[3], self[2], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzy(self) -> I32x4 {\n        I32x4([self[0], self[3], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzy(self) -> I32x4 {\n        I32x4([self[1], self[3], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzy(self) -> I32x4 {\n        I32x4([self[2], self[3], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzy(self) -> I32x4 {\n        I32x4([self[3], self[3], self[2], self[1]])\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwy(self) -> I32x4 {\n        I32x4([self[0], self[0], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwy(self) -> I32x4 {\n        I32x4([self[1], self[0], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwy(self) -> I32x4 {\n        I32x4([self[2], self[0], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwy(self) -> I32x4 {\n        I32x4([self[3], self[0], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywy(self) -> I32x4 {\n        I32x4([self[0], self[1], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywy(self) -> I32x4 {\n        I32x4([self[1], self[1], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywy(self) -> I32x4 {\n        I32x4([self[2], self[1], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywy(self) -> I32x4 {\n        I32x4([self[3], self[1], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwy(self) -> I32x4 {\n        I32x4([self[0], self[2], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwy(self) -> I32x4 {\n        I32x4([self[1], self[2], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwy(self) -> I32x4 {\n        I32x4([self[2], self[2], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwy(self) -> I32x4 {\n        I32x4([self[3], self[2], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwy(self) -> I32x4 {\n        I32x4([self[0], self[3], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwy(self) -> I32x4 {\n        I32x4([self[1], self[3], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwy(self) -> I32x4 {\n        I32x4([self[2], self[3], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and second\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwy(self) -> I32x4 {\n        I32x4([self[3], self[3], self[3], self[1]])\n    }\n\n    /// Constructs a new vector from the first, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxz(self) -> I32x4 {\n        I32x4([self[0], self[0], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the second, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxz(self) -> I32x4 {\n        I32x4([self[1], self[0], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the third, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxz(self) -> I32x4 {\n        I32x4([self[2], self[0], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxz(self) -> I32x4 {\n        I32x4([self[3], self[0], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the first, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxz(self) -> I32x4 {\n        I32x4([self[0], self[1], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the second, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxz(self) -> I32x4 {\n        I32x4([self[1], self[1], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the third, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxz(self) -> I32x4 {\n        I32x4([self[2], self[1], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxz(self) -> I32x4 {\n        I32x4([self[3], self[1], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the first, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxz(self) -> I32x4 {\n        I32x4([self[0], self[2], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the second, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxz(self) -> I32x4 {\n        I32x4([self[1], self[2], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the third, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxz(self) -> I32x4 {\n        I32x4([self[2], self[2], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxz(self) -> I32x4 {\n        I32x4([self[3], self[2], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxz(self) -> I32x4 {\n        I32x4([self[0], self[3], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxz(self) -> I32x4 {\n        I32x4([self[1], self[3], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxz(self) -> I32x4 {\n        I32x4([self[2], self[3], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxz(self) -> I32x4 {\n        I32x4([self[3], self[3], self[0], self[2]])\n    }\n\n    /// Constructs a new vector from the first, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyz(self) -> I32x4 {\n        I32x4([self[0], self[0], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the second, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyz(self) -> I32x4 {\n        I32x4([self[1], self[0], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the third, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyz(self) -> I32x4 {\n        I32x4([self[2], self[0], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyz(self) -> I32x4 {\n        I32x4([self[3], self[0], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the first, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyz(self) -> I32x4 {\n        I32x4([self[0], self[1], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the second, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyz(self) -> I32x4 {\n        I32x4([self[1], self[1], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the third, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyz(self) -> I32x4 {\n        I32x4([self[2], self[1], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyz(self) -> I32x4 {\n        I32x4([self[3], self[1], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the first, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyz(self) -> I32x4 {\n        I32x4([self[0], self[2], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the second, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyz(self) -> I32x4 {\n        I32x4([self[1], self[2], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the third, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyz(self) -> I32x4 {\n        I32x4([self[2], self[2], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyz(self) -> I32x4 {\n        I32x4([self[3], self[2], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyz(self) -> I32x4 {\n        I32x4([self[0], self[3], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyz(self) -> I32x4 {\n        I32x4([self[1], self[3], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyz(self) -> I32x4 {\n        I32x4([self[2], self[3], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyz(self) -> I32x4 {\n        I32x4([self[3], self[3], self[1], self[2]])\n    }\n\n    /// Constructs a new vector from the first, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzz(self) -> I32x4 {\n        I32x4([self[0], self[0], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the second, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzz(self) -> I32x4 {\n        I32x4([self[1], self[0], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the third, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzz(self) -> I32x4 {\n        I32x4([self[2], self[0], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzz(self) -> I32x4 {\n        I32x4([self[3], self[0], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the first, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzz(self) -> I32x4 {\n        I32x4([self[0], self[1], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the second, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzz(self) -> I32x4 {\n        I32x4([self[1], self[1], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the third, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzz(self) -> I32x4 {\n        I32x4([self[2], self[1], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzz(self) -> I32x4 {\n        I32x4([self[3], self[1], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the first, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzz(self) -> I32x4 {\n        I32x4([self[0], self[2], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the second, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzz(self) -> I32x4 {\n        I32x4([self[1], self[2], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the third, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzz(self) -> I32x4 {\n        I32x4([self[2], self[2], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzz(self) -> I32x4 {\n        I32x4([self[3], self[2], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzz(self) -> I32x4 {\n        I32x4([self[0], self[3], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzz(self) -> I32x4 {\n        I32x4([self[1], self[3], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzz(self) -> I32x4 {\n        I32x4([self[2], self[3], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzz(self) -> I32x4 {\n        I32x4([self[3], self[3], self[2], self[2]])\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxwz(self) -> I32x4 {\n        I32x4([self[0], self[0], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxwz(self) -> I32x4 {\n        I32x4([self[1], self[0], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxwz(self) -> I32x4 {\n        I32x4([self[2], self[0], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxwz(self) -> I32x4 {\n        I32x4([self[3], self[0], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xywz(self) -> I32x4 {\n        I32x4([self[0], self[1], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yywz(self) -> I32x4 {\n        I32x4([self[1], self[1], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zywz(self) -> I32x4 {\n        I32x4([self[2], self[1], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wywz(self) -> I32x4 {\n        I32x4([self[3], self[1], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzwz(self) -> I32x4 {\n        I32x4([self[0], self[2], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzwz(self) -> I32x4 {\n        I32x4([self[1], self[2], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzwz(self) -> I32x4 {\n        I32x4([self[2], self[2], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzwz(self) -> I32x4 {\n        I32x4([self[3], self[2], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwwz(self) -> I32x4 {\n        I32x4([self[0], self[3], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywwz(self) -> I32x4 {\n        I32x4([self[1], self[3], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwwz(self) -> I32x4 {\n        I32x4([self[2], self[3], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and third\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwwz(self) -> I32x4 {\n        I32x4([self[3], self[3], self[3], self[2]])\n    }\n\n    /// Constructs a new vector from the first, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxxw(self) -> I32x4 {\n        I32x4([self[0], self[0], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the second, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxxw(self) -> I32x4 {\n        I32x4([self[1], self[0], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the third, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxxw(self) -> I32x4 {\n        I32x4([self[2], self[0], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, first, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxxw(self) -> I32x4 {\n        I32x4([self[3], self[0], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the first, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyxw(self) -> I32x4 {\n        I32x4([self[0], self[1], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the second, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyxw(self) -> I32x4 {\n        I32x4([self[1], self[1], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the third, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyxw(self) -> I32x4 {\n        I32x4([self[2], self[1], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, second, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyxw(self) -> I32x4 {\n        I32x4([self[3], self[1], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the first, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzxw(self) -> I32x4 {\n        I32x4([self[0], self[2], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the second, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzxw(self) -> I32x4 {\n        I32x4([self[1], self[2], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the third, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzxw(self) -> I32x4 {\n        I32x4([self[2], self[2], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, third, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzxw(self) -> I32x4 {\n        I32x4([self[3], self[2], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the first, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwxw(self) -> I32x4 {\n        I32x4([self[0], self[3], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the second, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywxw(self) -> I32x4 {\n        I32x4([self[1], self[3], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the third, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwxw(self) -> I32x4 {\n        I32x4([self[2], self[3], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, first, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwxw(self) -> I32x4 {\n        I32x4([self[3], self[3], self[0], self[3]])\n    }\n\n    /// Constructs a new vector from the first, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxyw(self) -> I32x4 {\n        I32x4([self[0], self[0], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the second, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxyw(self) -> I32x4 {\n        I32x4([self[1], self[0], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the third, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxyw(self) -> I32x4 {\n        I32x4([self[2], self[0], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, first, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxyw(self) -> I32x4 {\n        I32x4([self[3], self[0], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the first, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyyw(self) -> I32x4 {\n        I32x4([self[0], self[1], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the second, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyyw(self) -> I32x4 {\n        I32x4([self[1], self[1], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the third, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyyw(self) -> I32x4 {\n        I32x4([self[2], self[1], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, second, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyyw(self) -> I32x4 {\n        I32x4([self[3], self[1], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the first, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzyw(self) -> I32x4 {\n        I32x4([self[0], self[2], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the second, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzyw(self) -> I32x4 {\n        I32x4([self[1], self[2], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the third, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzyw(self) -> I32x4 {\n        I32x4([self[2], self[2], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, third, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzyw(self) -> I32x4 {\n        I32x4([self[3], self[2], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the first, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwyw(self) -> I32x4 {\n        I32x4([self[0], self[3], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the second, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywyw(self) -> I32x4 {\n        I32x4([self[1], self[3], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the third, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwyw(self) -> I32x4 {\n        I32x4([self[2], self[3], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, second, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwyw(self) -> I32x4 {\n        I32x4([self[3], self[3], self[1], self[3]])\n    }\n\n    /// Constructs a new vector from the first, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxzw(self) -> I32x4 {\n        I32x4([self[0], self[0], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the second, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxzw(self) -> I32x4 {\n        I32x4([self[1], self[0], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the third, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxzw(self) -> I32x4 {\n        I32x4([self[2], self[0], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, first, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxzw(self) -> I32x4 {\n        I32x4([self[3], self[0], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the first, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyzw(self) -> I32x4 {\n        I32x4([self[0], self[1], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the second, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyzw(self) -> I32x4 {\n        I32x4([self[1], self[1], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the third, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyzw(self) -> I32x4 {\n        I32x4([self[2], self[1], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, second, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyzw(self) -> I32x4 {\n        I32x4([self[3], self[1], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the first, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzzw(self) -> I32x4 {\n        I32x4([self[0], self[2], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the second, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzzw(self) -> I32x4 {\n        I32x4([self[1], self[2], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the third, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzzw(self) -> I32x4 {\n        I32x4([self[2], self[2], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, third, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzzw(self) -> I32x4 {\n        I32x4([self[3], self[2], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the first, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwzw(self) -> I32x4 {\n        I32x4([self[0], self[3], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the second, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywzw(self) -> I32x4 {\n        I32x4([self[1], self[3], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the third, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwzw(self) -> I32x4 {\n        I32x4([self[2], self[3], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, third, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwzw(self) -> I32x4 {\n        I32x4([self[3], self[3], self[2], self[3]])\n    }\n\n    /// Constructs a new vector from the first, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xxww(self) -> I32x4 {\n        I32x4([self[0], self[0], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the second, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yxww(self) -> I32x4 {\n        I32x4([self[1], self[0], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the third, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zxww(self) -> I32x4 {\n        I32x4([self[2], self[0], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, first, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wxww(self) -> I32x4 {\n        I32x4([self[3], self[0], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the first, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xyww(self) -> I32x4 {\n        I32x4([self[0], self[1], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the second, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yyww(self) -> I32x4 {\n        I32x4([self[1], self[1], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the third, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zyww(self) -> I32x4 {\n        I32x4([self[2], self[1], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, second, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wyww(self) -> I32x4 {\n        I32x4([self[3], self[1], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the first, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xzww(self) -> I32x4 {\n        I32x4([self[0], self[2], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the second, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn yzww(self) -> I32x4 {\n        I32x4([self[1], self[2], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the third, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zzww(self) -> I32x4 {\n        I32x4([self[2], self[2], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, third, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wzww(self) -> I32x4 {\n        I32x4([self[3], self[2], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the first, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn xwww(self) -> I32x4 {\n        I32x4([self[0], self[3], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the second, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn ywww(self) -> I32x4 {\n        I32x4([self[1], self[3], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the third, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn zwww(self) -> I32x4 {\n        I32x4([self[2], self[3], self[3], self[3]])\n    }\n\n    /// Constructs a new vector from the fourth, fourth, fourth, and fourth\n    /// lanes in this vector, respectively.\n    #[inline]\n    pub fn wwww(self) -> I32x4 {\n        I32x4([self[3], self[3], self[3], self[3]])\n    }\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/test.rs",
      "sha256": "62e1159ff2977b0e3ddcc302b1c210105a6f1c087a089fd1fffeaef1814e50f6",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/test.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::default::{F32x4, I32x4, U32x4};\nuse crate::scalar::F32x4 as F32x4S;\n\n// F32x4\n\n#[test]\nfn test_f32x4_constructors() {\n    let a = F32x4::new(1.0, 2.0, 3.0, 4.0);\n    assert_eq!((a[0], a[1], a[2], a[3]), (1.0, 2.0, 3.0, 4.0));\n    let b = F32x4::splat(10.0);\n    assert_eq!(b, F32x4::new(10.0, 10.0, 10.0, 10.0));\n}\n\n#[test]\nfn test_f32x4_accessors_and_mutators() {\n    let a = F32x4::new(5.0, 6.0, 7.0, 8.0);\n    assert_eq!((a.x(), a.y(), a.z(), a.w()), (5.0, 6.0, 7.0, 8.0));\n    let mut b = F32x4::new(10.0, 11.0, 12.0, 13.0);\n    b.set_x(20.0);\n    b.set_y(30.0);\n    b.set_z(40.0);\n    b.set_w(50.0);\n    assert_eq!(b, F32x4::new(20.0, 30.0, 40.0, 50.0));\n}\n\n#[test]\nfn test_f32x4_basic_ops() {\n    let a = F32x4::new(1.0, 3.0, 5.0, 7.0);\n    let b = F32x4::new(2.0, 2.0, 6.0, 6.0);\n    let approx_recip = a.approx_recip();\n\n    // The greatest diff we observe between the correct answer to the reciprocal and the answer that\n    // llvm gives us is 1.0 vs 0.9980469, so we need to have the allowable diff be 0.002 so that it\n    // passes. It's approximate, so it's fine to be a bit off.\n    const ALLOWABLE_RECIP_DIFF: f32 = 0.002;\n    assert!((approx_recip[0] - (1. / 1.)).abs() < ALLOWABLE_RECIP_DIFF);\n    assert!((approx_recip[1] - (1. / 3.)).abs() < ALLOWABLE_RECIP_DIFF);\n    assert!((approx_recip[2] - (1. / 5.)).abs() < ALLOWABLE_RECIP_DIFF);\n    assert!((approx_recip[3] - (1. / 7.)).abs() < ALLOWABLE_RECIP_DIFF);\n\n    assert_eq!(a.min(b), F32x4::new(1.0, 2.0, 5.0, 6.0));\n    assert_eq!(a.max(b), F32x4::new(2.0, 3.0, 6.0, 7.0));\n    let c = F32x4::new(-1.0, 1.3, -20.0, 3.6);\n    assert_eq!(c.clamp(a, b), F32x4::new(1.0, 2.0, 5.0, 6.0));\n    assert_eq!(c.abs(), F32x4::new(1.0, 1.3, 20.0, 3.6));\n    assert_eq!(c.floor(), F32x4::new(-1.0, 1.0, -20.0, 3.0));\n    assert_eq!(c.ceil(), F32x4::new(-1.0, 2.0, -20.0, 4.0));\n    assert_eq!(c.to_i32x4().to_f32x4(), F32x4::new(-1.0, 1.0, -20.0, 4.0));\n    let d = F32x4::new(1.0, 2.0, 3.0, 4.0);\n    assert_eq!(d.sqrt(), F32x4::new(1.0, 1.4142135, 1.7320508, 2.0));\n}\n\n#[test]\nfn test_f32x4_packed_comparisons() {\n    let a = F32x4::new(7.0, 3.0, 6.0, -2.0);\n    let b = F32x4::new(10.0, 3.0, 5.0, -2.0);\n    assert_eq!(a.packed_eq(b), U32x4::new(0, !0, 0, !0));\n    assert_eq!(a.packed_gt(b), U32x4::new(0, 0, !0, 0));\n    assert_eq!(a.packed_le(b), U32x4::new(!0, !0, 0, !0));\n}\n\n#[test]\nfn test_f32x4_swizzles() {\n    let a = F32x4::new(1.0, 2.0, 3.0, 4.0);\n    assert_eq!(a.xxxx(), F32x4::splat(1.0));\n    assert_eq!(a.yyyy(), F32x4::splat(2.0));\n    assert_eq!(a.zzzz(), F32x4::splat(3.0));\n    assert_eq!(a.wwww(), F32x4::splat(4.0));\n\n    assert_eq!(a.yxxx(), F32x4::new(2.0, 1.0, 1.0, 1.0));\n    assert_eq!(a.zxxx(), F32x4::new(3.0, 1.0, 1.0, 1.0));\n    assert_eq!(a.wxxx(), F32x4::new(4.0, 1.0, 1.0, 1.0));\n    assert_eq!(a.xyxx(), F32x4::new(1.0, 2.0, 1.0, 1.0));\n    assert_eq!(a.yyxx(), F32x4::new(2.0, 2.0, 1.0, 1.0));\n    assert_eq!(a.zyxx(), F32x4::new(3.0, 2.0, 1.0, 1.0));\n    assert_eq!(a.wyxx(), F32x4::new(4.0, 2.0, 1.0, 1.0));\n    assert_eq!(a.xzxx(), F32x4::new(1.0, 3.0, 1.0, 1.0));\n    assert_eq!(a.yzxx(), F32x4::new(2.0, 3.0, 1.0, 1.0));\n    assert_eq!(a.zzxx(), F32x4::new(3.0, 3.0, 1.0, 1.0));\n    assert_eq!(a.wzxx(), F32x4::new(4.0, 3.0, 1.0, 1.0));\n    assert_eq!(a.xwxx(), F32x4::new(1.0, 4.0, 1.0, 1.0));\n    assert_eq!(a.ywxx(), F32x4::new(2.0, 4.0, 1.0, 1.0));\n    assert_eq!(a.zwxx(), F32x4::new(3.0, 4.0, 1.0, 1.0));\n    assert_eq!(a.wwxx(), F32x4::new(4.0, 4.0, 1.0, 1.0));\n    assert_eq!(a.xxyx(), F32x4::new(1.0, 1.0, 2.0, 1.0));\n    assert_eq!(a.yxyx(), F32x4::new(2.0, 1.0, 2.0, 1.0));\n    assert_eq!(a.zxyx(), F32x4::new(3.0, 1.0, 2.0, 1.0));\n    assert_eq!(a.wxyx(), F32x4::new(4.0, 1.0, 2.0, 1.0));\n    assert_eq!(a.xyyx(), F32x4::new(1.0, 2.0, 2.0, 1.0));\n    assert_eq!(a.yyyx(), F32x4::new(2.0, 2.0, 2.0, 1.0));\n    assert_eq!(a.zyyx(), F32x4::new(3.0, 2.0, 2.0, 1.0));\n    assert_eq!(a.wyyx(), F32x4::new(4.0, 2.0, 2.0, 1.0));\n    assert_eq!(a.xzyx(), F32x4::new(1.0, 3.0, 2.0, 1.0));\n    assert_eq!(a.yzyx(), F32x4::new(2.0, 3.0, 2.0, 1.0));\n    assert_eq!(a.zzyx(), F32x4::new(3.0, 3.0, 2.0, 1.0));\n    assert_eq!(a.wzyx(), F32x4::new(4.0, 3.0, 2.0, 1.0));\n    assert_eq!(a.xwyx(), F32x4::new(1.0, 4.0, 2.0, 1.0));\n    assert_eq!(a.ywyx(), F32x4::new(2.0, 4.0, 2.0, 1.0));\n    assert_eq!(a.zwyx(), F32x4::new(3.0, 4.0, 2.0, 1.0));\n    assert_eq!(a.wwyx(), F32x4::new(4.0, 4.0, 2.0, 1.0));\n    assert_eq!(a.xxzx(), F32x4::new(1.0, 1.0, 3.0, 1.0));\n    assert_eq!(a.yxzx(), F32x4::new(2.0, 1.0, 3.0, 1.0));\n    assert_eq!(a.zxzx(), F32x4::new(3.0, 1.0, 3.0, 1.0));\n    assert_eq!(a.wxzx(), F32x4::new(4.0, 1.0, 3.0, 1.0));\n    assert_eq!(a.xyzx(), F32x4::new(1.0, 2.0, 3.0, 1.0));\n    assert_eq!(a.yyzx(), F32x4::new(2.0, 2.0, 3.0, 1.0));\n    assert_eq!(a.zyzx(), F32x4::new(3.0, 2.0, 3.0, 1.0));\n    assert_eq!(a.wyzx(), F32x4::new(4.0, 2.0, 3.0, 1.0));\n    assert_eq!(a.xzzx(), F32x4::new(1.0, 3.0, 3.0, 1.0));\n    assert_eq!(a.yzzx(), F32x4::new(2.0, 3.0, 3.0, 1.0));\n    assert_eq!(a.zzzx(), F32x4::new(3.0, 3.0, 3.0, 1.0));\n    assert_eq!(a.wzzx(), F32x4::new(4.0, 3.0, 3.0, 1.0));\n    assert_eq!(a.xwzx(), F32x4::new(1.0, 4.0, 3.0, 1.0));\n    assert_eq!(a.ywzx(), F32x4::new(2.0, 4.0, 3.0, 1.0));\n    assert_eq!(a.zwzx(), F32x4::new(3.0, 4.0, 3.0, 1.0));\n    assert_eq!(a.wwzx(), F32x4::new(4.0, 4.0, 3.0, 1.0));\n    assert_eq!(a.xxwx(), F32x4::new(1.0, 1.0, 4.0, 1.0));\n    assert_eq!(a.yxwx(), F32x4::new(2.0, 1.0, 4.0, 1.0));\n    assert_eq!(a.zxwx(), F32x4::new(3.0, 1.0, 4.0, 1.0));\n    assert_eq!(a.wxwx(), F32x4::new(4.0, 1.0, 4.0, 1.0));\n    assert_eq!(a.xywx(), F32x4::new(1.0, 2.0, 4.0, 1.0));\n    assert_eq!(a.yywx(), F32x4::new(2.0, 2.0, 4.0, 1.0));\n    assert_eq!(a.zywx(), F32x4::new(3.0, 2.0, 4.0, 1.0));\n    assert_eq!(a.wywx(), F32x4::new(4.0, 2.0, 4.0, 1.0));\n    assert_eq!(a.xzwx(), F32x4::new(1.0, 3.0, 4.0, 1.0));\n    assert_eq!(a.yzwx(), F32x4::new(2.0, 3.0, 4.0, 1.0));\n    assert_eq!(a.zzwx(), F32x4::new(3.0, 3.0, 4.0, 1.0));\n    assert_eq!(a.wzwx(), F32x4::new(4.0, 3.0, 4.0, 1.0));\n    assert_eq!(a.xwwx(), F32x4::new(1.0, 4.0, 4.0, 1.0));\n    assert_eq!(a.ywwx(), F32x4::new(2.0, 4.0, 4.0, 1.0));\n    assert_eq!(a.zwwx(), F32x4::new(3.0, 4.0, 4.0, 1.0));\n    assert_eq!(a.wwwx(), F32x4::new(4.0, 4.0, 4.0, 1.0));\n\n    assert_eq!(a.xxxy(), F32x4::new(1.0, 1.0, 1.0, 2.0));\n    assert_eq!(a.yxxy(), F32x4::new(2.0, 1.0, 1.0, 2.0));\n    assert_eq!(a.zxxy(), F32x4::new(3.0, 1.0, 1.0, 2.0));\n    assert_eq!(a.wxxy(), F32x4::new(4.0, 1.0, 1.0, 2.0));\n    assert_eq!(a.xyxy(), F32x4::new(1.0, 2.0, 1.0, 2.0));\n    assert_eq!(a.yyxy(), F32x4::new(2.0, 2.0, 1.0, 2.0));\n    assert_eq!(a.zyxy(), F32x4::new(3.0, 2.0, 1.0, 2.0));\n    assert_eq!(a.wyxy(), F32x4::new(4.0, 2.0, 1.0, 2.0));\n    assert_eq!(a.xzxy(), F32x4::new(1.0, 3.0, 1.0, 2.0));\n    assert_eq!(a.yzxy(), F32x4::new(2.0, 3.0, 1.0, 2.0));\n    assert_eq!(a.zzxy(), F32x4::new(3.0, 3.0, 1.0, 2.0));\n    assert_eq!(a.wzxy(), F32x4::new(4.0, 3.0, 1.0, 2.0));\n    assert_eq!(a.xwxy(), F32x4::new(1.0, 4.0, 1.0, 2.0));\n    assert_eq!(a.ywxy(), F32x4::new(2.0, 4.0, 1.0, 2.0));\n    assert_eq!(a.zwxy(), F32x4::new(3.0, 4.0, 1.0, 2.0));\n    assert_eq!(a.wwxy(), F32x4::new(4.0, 4.0, 1.0, 2.0));\n    assert_eq!(a.xxyy(), F32x4::new(1.0, 1.0, 2.0, 2.0));\n    assert_eq!(a.yxyy(), F32x4::new(2.0, 1.0, 2.0, 2.0));\n    assert_eq!(a.zxyy(), F32x4::new(3.0, 1.0, 2.0, 2.0));\n    assert_eq!(a.wxyy(), F32x4::new(4.0, 1.0, 2.0, 2.0));\n    assert_eq!(a.xyyy(), F32x4::new(1.0, 2.0, 2.0, 2.0));\n    assert_eq!(a.zyyy(), F32x4::new(3.0, 2.0, 2.0, 2.0));\n    assert_eq!(a.wyyy(), F32x4::new(4.0, 2.0, 2.0, 2.0));\n    assert_eq!(a.xzyy(), F32x4::new(1.0, 3.0, 2.0, 2.0));\n    assert_eq!(a.yzyy(), F32x4::new(2.0, 3.0, 2.0, 2.0));\n    assert_eq!(a.zzyy(), F32x4::new(3.0, 3.0, 2.0, 2.0));\n    assert_eq!(a.wzyy(), F32x4::new(4.0, 3.0, 2.0, 2.0));\n    assert_eq!(a.xwyy(), F32x4::new(1.0, 4.0, 2.0, 2.0));\n    assert_eq!(a.ywyy(), F32x4::new(2.0, 4.0, 2.0, 2.0));\n    assert_eq!(a.zwyy(), F32x4::new(3.0, 4.0, 2.0, 2.0));\n    assert_eq!(a.wwyy(), F32x4::new(4.0, 4.0, 2.0, 2.0));\n    assert_eq!(a.xxzy(), F32x4::new(1.0, 1.0, 3.0, 2.0));\n    assert_eq!(a.yxzy(), F32x4::new(2.0, 1.0, 3.0, 2.0));\n    assert_eq!(a.zxzy(), F32x4::new(3.0, 1.0, 3.0, 2.0));\n    assert_eq!(a.wxzy(), F32x4::new(4.0, 1.0, 3.0, 2.0));\n    assert_eq!(a.xyzy(), F32x4::new(1.0, 2.0, 3.0, 2.0));\n    assert_eq!(a.yyzy(), F32x4::new(2.0, 2.0, 3.0, 2.0));\n    assert_eq!(a.zyzy(), F32x4::new(3.0, 2.0, 3.0, 2.0));\n    assert_eq!(a.wyzy(), F32x4::new(4.0, 2.0, 3.0, 2.0));\n    assert_eq!(a.xzzy(), F32x4::new(1.0, 3.0, 3.0, 2.0));\n    assert_eq!(a.yzzy(), F32x4::new(2.0, 3.0, 3.0, 2.0));\n    assert_eq!(a.zzzy(), F32x4::new(3.0, 3.0, 3.0, 2.0));\n    assert_eq!(a.wzzy(), F32x4::new(4.0, 3.0, 3.0, 2.0));\n    assert_eq!(a.xwzy(), F32x4::new(1.0, 4.0, 3.0, 2.0));\n    assert_eq!(a.ywzy(), F32x4::new(2.0, 4.0, 3.0, 2.0));\n    assert_eq!(a.zwzy(), F32x4::new(3.0, 4.0, 3.0, 2.0));\n    assert_eq!(a.wwzy(), F32x4::new(4.0, 4.0, 3.0, 2.0));\n    assert_eq!(a.xxwy(), F32x4::new(1.0, 1.0, 4.0, 2.0));\n    assert_eq!(a.yxwy(), F32x4::new(2.0, 1.0, 4.0, 2.0));\n    assert_eq!(a.zxwy(), F32x4::new(3.0, 1.0, 4.0, 2.0));\n    assert_eq!(a.wxwy(), F32x4::new(4.0, 1.0, 4.0, 2.0));\n    assert_eq!(a.xywy(), F32x4::new(1.0, 2.0, 4.0, 2.0));\n    assert_eq!(a.yywy(), F32x4::new(2.0, 2.0, 4.0, 2.0));\n    assert_eq!(a.zywy(), F32x4::new(3.0, 2.0, 4.0, 2.0));\n    assert_eq!(a.wywy(), F32x4::new(4.0, 2.0, 4.0, 2.0));\n    assert_eq!(a.xzwy(), F32x4::new(1.0, 3.0, 4.0, 2.0));\n    assert_eq!(a.yzwy(), F32x4::new(2.0, 3.0, 4.0, 2.0));\n    assert_eq!(a.zzwy(), F32x4::new(3.0, 3.0, 4.0, 2.0));\n    assert_eq!(a.wzwy(), F32x4::new(4.0, 3.0, 4.0, 2.0));\n    assert_eq!(a.xwwy(), F32x4::new(1.0, 4.0, 4.0, 2.0));\n    assert_eq!(a.ywwy(), F32x4::new(2.0, 4.0, 4.0, 2.0));\n    assert_eq!(a.zwwy(), F32x4::new(3.0, 4.0, 4.0, 2.0));\n    assert_eq!(a.wwwy(), F32x4::new(4.0, 4.0, 4.0, 2.0));\n\n    assert_eq!(a.xxxw(), F32x4::new(1.0, 1.0, 1.0, 4.0));\n    assert_eq!(a.yxxw(), F32x4::new(2.0, 1.0, 1.0, 4.0));\n    assert_eq!(a.zxxw(), F32x4::new(3.0, 1.0, 1.0, 4.0));\n    assert_eq!(a.wxxw(), F32x4::new(4.0, 1.0, 1.0, 4.0));\n    assert_eq!(a.xyxw(), F32x4::new(1.0, 2.0, 1.0, 4.0));\n    assert_eq!(a.yyxw(), F32x4::new(2.0, 2.0, 1.0, 4.0));\n    assert_eq!(a.zyxw(), F32x4::new(3.0, 2.0, 1.0, 4.0));\n    assert_eq!(a.wyxw(), F32x4::new(4.0, 2.0, 1.0, 4.0));\n    assert_eq!(a.xzxw(), F32x4::new(1.0, 3.0, 1.0, 4.0));\n    assert_eq!(a.yzxw(), F32x4::new(2.0, 3.0, 1.0, 4.0));\n    assert_eq!(a.zzxw(), F32x4::new(3.0, 3.0, 1.0, 4.0));\n    assert_eq!(a.wzxw(), F32x4::new(4.0, 3.0, 1.0, 4.0));\n    assert_eq!(a.xwxw(), F32x4::new(1.0, 4.0, 1.0, 4.0));\n    assert_eq!(a.ywxw(), F32x4::new(2.0, 4.0, 1.0, 4.0));\n    assert_eq!(a.zwxw(), F32x4::new(3.0, 4.0, 1.0, 4.0));\n    assert_eq!(a.wwxw(), F32x4::new(4.0, 4.0, 1.0, 4.0));\n    assert_eq!(a.xxyw(), F32x4::new(1.0, 1.0, 2.0, 4.0));\n    assert_eq!(a.yxyw(), F32x4::new(2.0, 1.0, 2.0, 4.0));\n    assert_eq!(a.zxyw(), F32x4::new(3.0, 1.0, 2.0, 4.0));\n    assert_eq!(a.wxyw(), F32x4::new(4.0, 1.0, 2.0, 4.0));\n    assert_eq!(a.xyyw(), F32x4::new(1.0, 2.0, 2.0, 4.0));\n    assert_eq!(a.yyyw(), F32x4::new(2.0, 2.0, 2.0, 4.0));\n    assert_eq!(a.zyyw(), F32x4::new(3.0, 2.0, 2.0, 4.0));\n    assert_eq!(a.wyyw(), F32x4::new(4.0, 2.0, 2.0, 4.0));\n    assert_eq!(a.xzyw(), F32x4::new(1.0, 3.0, 2.0, 4.0));\n    assert_eq!(a.yzyw(), F32x4::new(2.0, 3.0, 2.0, 4.0));\n    assert_eq!(a.zzyw(), F32x4::new(3.0, 3.0, 2.0, 4.0));\n    assert_eq!(a.wzyw(), F32x4::new(4.0, 3.0, 2.0, 4.0));\n    assert_eq!(a.xwyw(), F32x4::new(1.0, 4.0, 2.0, 4.0));\n    assert_eq!(a.ywyw(), F32x4::new(2.0, 4.0, 2.0, 4.0));\n    assert_eq!(a.zwyw(), F32x4::new(3.0, 4.0, 2.0, 4.0));\n    assert_eq!(a.wwyw(), F32x4::new(4.0, 4.0, 2.0, 4.0));\n    assert_eq!(a.xxzw(), F32x4::new(1.0, 1.0, 3.0, 4.0));\n    assert_eq!(a.yxzw(), F32x4::new(2.0, 1.0, 3.0, 4.0));\n    assert_eq!(a.zxzw(), F32x4::new(3.0, 1.0, 3.0, 4.0));\n    assert_eq!(a.wxzw(), F32x4::new(4.0, 1.0, 3.0, 4.0));\n    assert_eq!(a.xyzw(), F32x4::new(1.0, 2.0, 3.0, 4.0));\n    assert_eq!(a.yyzw(), F32x4::new(2.0, 2.0, 3.0, 4.0));\n    assert_eq!(a.zyzw(), F32x4::new(3.0, 2.0, 3.0, 4.0));\n    assert_eq!(a.wyzw(), F32x4::new(4.0, 2.0, 3.0, 4.0));\n    assert_eq!(a.xzzw(), F32x4::new(1.0, 3.0, 3.0, 4.0));\n    assert_eq!(a.yzzw(), F32x4::new(2.0, 3.0, 3.0, 4.0));\n    assert_eq!(a.zzzw(), F32x4::new(3.0, 3.0, 3.0, 4.0));\n    assert_eq!(a.wzzw(), F32x4::new(4.0, 3.0, 3.0, 4.0));\n    assert_eq!(a.xwzw(), F32x4::new(1.0, 4.0, 3.0, 4.0));\n    assert_eq!(a.ywzw(), F32x4::new(2.0, 4.0, 3.0, 4.0));\n    assert_eq!(a.zwzw(), F32x4::new(3.0, 4.0, 3.0, 4.0));\n    assert_eq!(a.wwzw(), F32x4::new(4.0, 4.0, 3.0, 4.0));\n    assert_eq!(a.xxww(), F32x4::new(1.0, 1.0, 4.0, 4.0));\n    assert_eq!(a.yxww(), F32x4::new(2.0, 1.0, 4.0, 4.0));\n    assert_eq!(a.zxww(), F32x4::new(3.0, 1.0, 4.0, 4.0));\n    assert_eq!(a.wxww(), F32x4::new(4.0, 1.0, 4.0, 4.0));\n    assert_eq!(a.xyww(), F32x4::new(1.0, 2.0, 4.0, 4.0));\n    assert_eq!(a.yyww(), F32x4::new(2.0, 2.0, 4.0, 4.0));\n    assert_eq!(a.zyww(), F32x4::new(3.0, 2.0, 4.0, 4.0));\n    assert_eq!(a.wzww(), F32x4::new(4.0, 3.0, 4.0, 4.0));\n    assert_eq!(a.xzww(), F32x4::new(1.0, 3.0, 4.0, 4.0));\n    assert_eq!(a.yzww(), F32x4::new(2.0, 3.0, 4.0, 4.0));\n    assert_eq!(a.zzww(), F32x4::new(3.0, 3.0, 4.0, 4.0));\n    assert_eq!(a.wzww(), F32x4::new(4.0, 3.0, 4.0, 4.0));\n    assert_eq!(a.xwww(), F32x4::new(1.0, 4.0, 4.0, 4.0));\n    assert_eq!(a.ywww(), F32x4::new(2.0, 4.0, 4.0, 4.0));\n    assert_eq!(a.zwww(), F32x4::new(3.0, 4.0, 4.0, 4.0));\n\n    assert_eq!(a.xxxz(), F32x4::new(1.0, 1.0, 1.0, 3.0));\n    assert_eq!(a.yxxz(), F32x4::new(2.0, 1.0, 1.0, 3.0));\n    assert_eq!(a.zxxz(), F32x4::new(3.0, 1.0, 1.0, 3.0));\n    assert_eq!(a.wxxz(), F32x4::new(4.0, 1.0, 1.0, 3.0));\n    assert_eq!(a.xyxz(), F32x4::new(1.0, 2.0, 1.0, 3.0));\n    assert_eq!(a.yyxz(), F32x4::new(2.0, 2.0, 1.0, 3.0));\n    assert_eq!(a.zyxz(), F32x4::new(3.0, 2.0, 1.0, 3.0));\n    assert_eq!(a.wyxz(), F32x4::new(4.0, 2.0, 1.0, 3.0));\n    assert_eq!(a.xzxz(), F32x4::new(1.0, 3.0, 1.0, 3.0));\n    assert_eq!(a.yzxz(), F32x4::new(2.0, 3.0, 1.0, 3.0));\n    assert_eq!(a.zzxz(), F32x4::new(3.0, 3.0, 1.0, 3.0));\n    assert_eq!(a.wzxz(), F32x4::new(4.0, 3.0, 1.0, 3.0));\n    assert_eq!(a.xwxz(), F32x4::new(1.0, 4.0, 1.0, 3.0));\n    assert_eq!(a.ywxz(), F32x4::new(2.0, 4.0, 1.0, 3.0));\n    assert_eq!(a.zwxz(), F32x4::new(3.0, 4.0, 1.0, 3.0));\n    assert_eq!(a.wwxz(), F32x4::new(4.0, 4.0, 1.0, 3.0));\n    assert_eq!(a.xxyz(), F32x4::new(1.0, 1.0, 2.0, 3.0));\n    assert_eq!(a.yxyz(), F32x4::new(2.0, 1.0, 2.0, 3.0));\n    assert_eq!(a.zxyz(), F32x4::new(3.0, 1.0, 2.0, 3.0));\n    assert_eq!(a.wxyz(), F32x4::new(4.0, 1.0, 2.0, 3.0));\n    assert_eq!(a.xyyz(), F32x4::new(1.0, 2.0, 2.0, 3.0));\n    assert_eq!(a.yyyz(), F32x4::new(2.0, 2.0, 2.0, 3.0));\n    assert_eq!(a.zyyz(), F32x4::new(3.0, 2.0, 2.0, 3.0));\n    assert_eq!(a.wyyz(), F32x4::new(4.0, 2.0, 2.0, 3.0));\n    assert_eq!(a.xzyz(), F32x4::new(1.0, 3.0, 2.0, 3.0));\n    assert_eq!(a.yzyz(), F32x4::new(2.0, 3.0, 2.0, 3.0));\n    assert_eq!(a.zzyz(), F32x4::new(3.0, 3.0, 2.0, 3.0));\n    assert_eq!(a.wzyz(), F32x4::new(4.0, 3.0, 2.0, 3.0));\n    assert_eq!(a.xwyz(), F32x4::new(1.0, 4.0, 2.0, 3.0));\n    assert_eq!(a.ywyz(), F32x4::new(2.0, 4.0, 2.0, 3.0));\n    assert_eq!(a.zwyz(), F32x4::new(3.0, 4.0, 2.0, 3.0));\n    assert_eq!(a.wwyz(), F32x4::new(4.0, 4.0, 2.0, 3.0));\n    assert_eq!(a.xxzz(), F32x4::new(1.0, 1.0, 3.0, 3.0));\n    assert_eq!(a.yxzz(), F32x4::new(2.0, 1.0, 3.0, 3.0));\n    assert_eq!(a.zxzz(), F32x4::new(3.0, 1.0, 3.0, 3.0));\n    assert_eq!(a.wxzz(), F32x4::new(4.0, 1.0, 3.0, 3.0));\n    assert_eq!(a.xyzz(), F32x4::new(1.0, 2.0, 3.0, 3.0));\n    assert_eq!(a.yyzz(), F32x4::new(2.0, 2.0, 3.0, 3.0));\n    assert_eq!(a.zyzz(), F32x4::new(3.0, 2.0, 3.0, 3.0));\n    assert_eq!(a.wyzz(), F32x4::new(4.0, 2.0, 3.0, 3.0));\n    assert_eq!(a.xzzz(), F32x4::new(1.0, 3.0, 3.0, 3.0));\n    assert_eq!(a.yzzz(), F32x4::new(2.0, 3.0, 3.0, 3.0));\n    assert_eq!(a.wzzz(), F32x4::new(4.0, 3.0, 3.0, 3.0));\n    assert_eq!(a.xwzz(), F32x4::new(1.0, 4.0, 3.0, 3.0));\n    assert_eq!(a.ywzz(), F32x4::new(2.0, 4.0, 3.0, 3.0));\n    assert_eq!(a.zwzz(), F32x4::new(3.0, 4.0, 3.0, 3.0));\n    assert_eq!(a.wwzz(), F32x4::new(4.0, 4.0, 3.0, 3.0));\n    assert_eq!(a.xxwz(), F32x4::new(1.0, 1.0, 4.0, 3.0));\n    assert_eq!(a.yxwz(), F32x4::new(2.0, 1.0, 4.0, 3.0));\n    assert_eq!(a.zxwz(), F32x4::new(3.0, 1.0, 4.0, 3.0));\n    assert_eq!(a.wxwz(), F32x4::new(4.0, 1.0, 4.0, 3.0));\n    assert_eq!(a.xywz(), F32x4::new(1.0, 2.0, 4.0, 3.0));\n    assert_eq!(a.yywz(), F32x4::new(2.0, 2.0, 4.0, 3.0));\n    assert_eq!(a.zywz(), F32x4::new(3.0, 2.0, 4.0, 3.0));\n    assert_eq!(a.wywz(), F32x4::new(4.0, 2.0, 4.0, 3.0));\n    assert_eq!(a.xzwz(), F32x4::new(1.0, 3.0, 4.0, 3.0));\n    assert_eq!(a.yzwz(), F32x4::new(2.0, 3.0, 4.0, 3.0));\n    assert_eq!(a.zzwz(), F32x4::new(3.0, 3.0, 4.0, 3.0));\n    assert_eq!(a.wzwz(), F32x4::new(4.0, 3.0, 4.0, 3.0));\n    assert_eq!(a.xwwz(), F32x4::new(1.0, 4.0, 4.0, 3.0));\n    assert_eq!(a.ywwz(), F32x4::new(2.0, 4.0, 4.0, 3.0));\n    assert_eq!(a.zwwz(), F32x4::new(3.0, 4.0, 4.0, 3.0));\n    assert_eq!(a.wwwz(), F32x4::new(4.0, 4.0, 4.0, 3.0));\n}\n\n#[test]\nfn test_f32x4_concatenations() {\n    let a = F32x4::new(4.0, 2.0, 6.0, -1.0);\n    let b = F32x4::new(10.0, -3.0, 15.0, 41.0);\n    assert_eq!(a.concat_xy_xy(b), F32x4::new(4.0, 2.0, 10.0, -3.0));\n    assert_eq!(a.concat_xy_zw(b), F32x4::new(4.0, 2.0, 15.0, 41.0));\n    assert_eq!(a.concat_zw_zw(b), F32x4::new(6.0, -1.0, 15.0, 41.0));\n    assert_eq!(a.concat_wz_yx(b), F32x4::new(-1.0, 6.0, -3.0, 10.0));\n}\n\n#[test]\nfn test_f32x4_arithmetic_overloads() {\n    let a = F32x4::new(4.0, -1.0, 6.0, -32.0);\n    let b = F32x4::new(0.5, 0.5, 10.0, 3.0);\n    let a_plus_b = F32x4::new(4.5, -0.5, 16.0, -29.0);\n    let a_minus_b = F32x4::new(3.5, -1.5, -4.0, -35.0);\n    let a_times_b = F32x4::new(2.0, -0.5, 60.0, -96.0);\n    assert_eq!(a + b, a_plus_b);\n    assert_eq!(a - b, a_minus_b);\n    assert_eq!(a * b, a_times_b);\n    let mut c = a;\n    c += b;\n    assert_eq!(c, a_plus_b);\n    c = a;\n    c -= b;\n    assert_eq!(c, a_minus_b);\n    c = a;\n    c *= b;\n    assert_eq!(c, a_times_b);\n    assert_eq!(-a, F32x4::new(-4.0, 1.0, -6.0, 32.0));\n}\n\n#[test]\nfn test_f32x4_index_overloads() {\n    let mut a = F32x4::new(4.0, 1.0, -32.5, 75.0);\n    assert_eq!(a[2], -32.5);\n    a[3] = 300.0;\n    assert_eq!(a[3], 300.0);\n    a[0] *= 0.5;\n    assert_eq!(a[0], 2.0);\n}\n\n#[test]\nfn test_f32x4_conversions() {\n    let a = F32x4::new(48.0, -4.0, 200.0, 7.0);\n    assert_eq!(a.to_i32x4(), I32x4::new(48, -4, 200, 7));\n}\n\n#[test]\nfn test_f32x4_debug() {\n    let a = F32x4::new(48.0, -4.0, 200.0, 7.0);\n    assert_eq!(\"<48, -4, 200, 7>\", format!(\"{:?}\", a));\n}\n\n// I32x4\n\n#[test]\nfn test_i32x4_constructors() {\n    let a = I32x4::new(3, 58, 10, 4);\n    assert_eq!((a[0], a[1], a[2], a[3]), (3, 58, 10, 4));\n    let b = I32x4::splat(39);\n    assert_eq!(b, I32x4::new(39, 39, 39, 39));\n}\n\n#[test]\nfn test_i32x4_basic_ops() {\n    let a = I32x4::new(6, 29, -40, 2);\n    let b = I32x4::new(10, -5, 10, 46);\n    assert_eq!(a.min(b), I32x4::new(6, -5, -40, 2));\n}\n\n#[test]\nfn test_i32x4_packed_comparisons() {\n    let a = I32x4::new(59, 1, 5, 63);\n    let b = I32x4::new(-59, 1, 5, 104);\n    assert_eq!(a.packed_eq(b), U32x4::new(0, !0, !0, 0));\n}\n\n#[test]\nfn test_i32x4_swizzles() {\n    let a = I32x4::new(1, 2, 3, 4);\n    assert_eq!(a.xxxx(), I32x4::splat(1));\n    assert_eq!(a.yyyy(), I32x4::splat(2));\n    assert_eq!(a.zzzz(), I32x4::splat(3));\n    assert_eq!(a.wwww(), I32x4::splat(4));\n\n    assert_eq!(a.yxxx(), I32x4::new(2, 1, 1, 1));\n    assert_eq!(a.zxxx(), I32x4::new(3, 1, 1, 1));\n    assert_eq!(a.wxxx(), I32x4::new(4, 1, 1, 1));\n    assert_eq!(a.xyxx(), I32x4::new(1, 2, 1, 1));\n    assert_eq!(a.yyxx(), I32x4::new(2, 2, 1, 1));\n    assert_eq!(a.zyxx(), I32x4::new(3, 2, 1, 1));\n    assert_eq!(a.wyxx(), I32x4::new(4, 2, 1, 1));\n    assert_eq!(a.xzxx(), I32x4::new(1, 3, 1, 1));\n    assert_eq!(a.yzxx(), I32x4::new(2, 3, 1, 1));\n    assert_eq!(a.zzxx(), I32x4::new(3, 3, 1, 1));\n    assert_eq!(a.wzxx(), I32x4::new(4, 3, 1, 1));\n    assert_eq!(a.xwxx(), I32x4::new(1, 4, 1, 1));\n    assert_eq!(a.ywxx(), I32x4::new(2, 4, 1, 1));\n    assert_eq!(a.zwxx(), I32x4::new(3, 4, 1, 1));\n    assert_eq!(a.wwxx(), I32x4::new(4, 4, 1, 1));\n    assert_eq!(a.xxyx(), I32x4::new(1, 1, 2, 1));\n    assert_eq!(a.yxyx(), I32x4::new(2, 1, 2, 1));\n    assert_eq!(a.zxyx(), I32x4::new(3, 1, 2, 1));\n    assert_eq!(a.wxyx(), I32x4::new(4, 1, 2, 1));\n    assert_eq!(a.xyyx(), I32x4::new(1, 2, 2, 1));\n    assert_eq!(a.yyyx(), I32x4::new(2, 2, 2, 1));\n    assert_eq!(a.zyyx(), I32x4::new(3, 2, 2, 1));\n    assert_eq!(a.wyyx(), I32x4::new(4, 2, 2, 1));\n    assert_eq!(a.xzyx(), I32x4::new(1, 3, 2, 1));\n    assert_eq!(a.yzyx(), I32x4::new(2, 3, 2, 1));\n    assert_eq!(a.zzyx(), I32x4::new(3, 3, 2, 1));\n    assert_eq!(a.wzyx(), I32x4::new(4, 3, 2, 1));\n    assert_eq!(a.xwyx(), I32x4::new(1, 4, 2, 1));\n    assert_eq!(a.ywyx(), I32x4::new(2, 4, 2, 1));\n    assert_eq!(a.zwyx(), I32x4::new(3, 4, 2, 1));\n    assert_eq!(a.wwyx(), I32x4::new(4, 4, 2, 1));\n    assert_eq!(a.xxzx(), I32x4::new(1, 1, 3, 1));\n    assert_eq!(a.yxzx(), I32x4::new(2, 1, 3, 1));\n    assert_eq!(a.zxzx(), I32x4::new(3, 1, 3, 1));\n    assert_eq!(a.wxzx(), I32x4::new(4, 1, 3, 1));\n    assert_eq!(a.xyzx(), I32x4::new(1, 2, 3, 1));\n    assert_eq!(a.yyzx(), I32x4::new(2, 2, 3, 1));\n    assert_eq!(a.zyzx(), I32x4::new(3, 2, 3, 1));\n    assert_eq!(a.wyzx(), I32x4::new(4, 2, 3, 1));\n    assert_eq!(a.xzzx(), I32x4::new(1, 3, 3, 1));\n    assert_eq!(a.yzzx(), I32x4::new(2, 3, 3, 1));\n    assert_eq!(a.zzzx(), I32x4::new(3, 3, 3, 1));\n    assert_eq!(a.wzzx(), I32x4::new(4, 3, 3, 1));\n    assert_eq!(a.xwzx(), I32x4::new(1, 4, 3, 1));\n    assert_eq!(a.ywzx(), I32x4::new(2, 4, 3, 1));\n    assert_eq!(a.zwzx(), I32x4::new(3, 4, 3, 1));\n    assert_eq!(a.wwzx(), I32x4::new(4, 4, 3, 1));\n    assert_eq!(a.xxwx(), I32x4::new(1, 1, 4, 1));\n    assert_eq!(a.yxwx(), I32x4::new(2, 1, 4, 1));\n    assert_eq!(a.zxwx(), I32x4::new(3, 1, 4, 1));\n    assert_eq!(a.wxwx(), I32x4::new(4, 1, 4, 1));\n    assert_eq!(a.xywx(), I32x4::new(1, 2, 4, 1));\n    assert_eq!(a.yywx(), I32x4::new(2, 2, 4, 1));\n    assert_eq!(a.zywx(), I32x4::new(3, 2, 4, 1));\n    assert_eq!(a.wywx(), I32x4::new(4, 2, 4, 1));\n    assert_eq!(a.xzwx(), I32x4::new(1, 3, 4, 1));\n    assert_eq!(a.yzwx(), I32x4::new(2, 3, 4, 1));\n    assert_eq!(a.zzwx(), I32x4::new(3, 3, 4, 1));\n    assert_eq!(a.wzwx(), I32x4::new(4, 3, 4, 1));\n    assert_eq!(a.xwwx(), I32x4::new(1, 4, 4, 1));\n    assert_eq!(a.ywwx(), I32x4::new(2, 4, 4, 1));\n    assert_eq!(a.zwwx(), I32x4::new(3, 4, 4, 1));\n    assert_eq!(a.wwwx(), I32x4::new(4, 4, 4, 1));\n\n    assert_eq!(a.xxxy(), I32x4::new(1, 1, 1, 2));\n    assert_eq!(a.yxxy(), I32x4::new(2, 1, 1, 2));\n    assert_eq!(a.zxxy(), I32x4::new(3, 1, 1, 2));\n    assert_eq!(a.wxxy(), I32x4::new(4, 1, 1, 2));\n    assert_eq!(a.xyxy(), I32x4::new(1, 2, 1, 2));\n    assert_eq!(a.yyxy(), I32x4::new(2, 2, 1, 2));\n    assert_eq!(a.zyxy(), I32x4::new(3, 2, 1, 2));\n    assert_eq!(a.wyxy(), I32x4::new(4, 2, 1, 2));\n    assert_eq!(a.xzxy(), I32x4::new(1, 3, 1, 2));\n    assert_eq!(a.yzxy(), I32x4::new(2, 3, 1, 2));\n    assert_eq!(a.zzxy(), I32x4::new(3, 3, 1, 2));\n    assert_eq!(a.wzxy(), I32x4::new(4, 3, 1, 2));\n    assert_eq!(a.xwxy(), I32x4::new(1, 4, 1, 2));\n    assert_eq!(a.ywxy(), I32x4::new(2, 4, 1, 2));\n    assert_eq!(a.zwxy(), I32x4::new(3, 4, 1, 2));\n    assert_eq!(a.wwxy(), I32x4::new(4, 4, 1, 2));\n    assert_eq!(a.xxyy(), I32x4::new(1, 1, 2, 2));\n    assert_eq!(a.yxyy(), I32x4::new(2, 1, 2, 2));\n    assert_eq!(a.zxyy(), I32x4::new(3, 1, 2, 2));\n    assert_eq!(a.wxyy(), I32x4::new(4, 1, 2, 2));\n    assert_eq!(a.xyyy(), I32x4::new(1, 2, 2, 2));\n    assert_eq!(a.zyyy(), I32x4::new(3, 2, 2, 2));\n    assert_eq!(a.wyyy(), I32x4::new(4, 2, 2, 2));\n    assert_eq!(a.xzyy(), I32x4::new(1, 3, 2, 2));\n    assert_eq!(a.yzyy(), I32x4::new(2, 3, 2, 2));\n    assert_eq!(a.zzyy(), I32x4::new(3, 3, 2, 2));\n    assert_eq!(a.wzyy(), I32x4::new(4, 3, 2, 2));\n    assert_eq!(a.xwyy(), I32x4::new(1, 4, 2, 2));\n    assert_eq!(a.ywyy(), I32x4::new(2, 4, 2, 2));\n    assert_eq!(a.zwyy(), I32x4::new(3, 4, 2, 2));\n    assert_eq!(a.wwyy(), I32x4::new(4, 4, 2, 2));\n    assert_eq!(a.xxzy(), I32x4::new(1, 1, 3, 2));\n    assert_eq!(a.yxzy(), I32x4::new(2, 1, 3, 2));\n    assert_eq!(a.zxzy(), I32x4::new(3, 1, 3, 2));\n    assert_eq!(a.wxzy(), I32x4::new(4, 1, 3, 2));\n    assert_eq!(a.xyzy(), I32x4::new(1, 2, 3, 2));\n    assert_eq!(a.yyzy(), I32x4::new(2, 2, 3, 2));\n    assert_eq!(a.zyzy(), I32x4::new(3, 2, 3, 2));\n    assert_eq!(a.wyzy(), I32x4::new(4, 2, 3, 2));\n    assert_eq!(a.xzzy(), I32x4::new(1, 3, 3, 2));\n    assert_eq!(a.yzzy(), I32x4::new(2, 3, 3, 2));\n    assert_eq!(a.zzzy(), I32x4::new(3, 3, 3, 2));\n    assert_eq!(a.wzzy(), I32x4::new(4, 3, 3, 2));\n    assert_eq!(a.xwzy(), I32x4::new(1, 4, 3, 2));\n    assert_eq!(a.ywzy(), I32x4::new(2, 4, 3, 2));\n    assert_eq!(a.zwzy(), I32x4::new(3, 4, 3, 2));\n    assert_eq!(a.wwzy(), I32x4::new(4, 4, 3, 2));\n    assert_eq!(a.xxwy(), I32x4::new(1, 1, 4, 2));\n    assert_eq!(a.yxwy(), I32x4::new(2, 1, 4, 2));\n    assert_eq!(a.zxwy(), I32x4::new(3, 1, 4, 2));\n    assert_eq!(a.wxwy(), I32x4::new(4, 1, 4, 2));\n    assert_eq!(a.xywy(), I32x4::new(1, 2, 4, 2));\n    assert_eq!(a.yywy(), I32x4::new(2, 2, 4, 2));\n    assert_eq!(a.zywy(), I32x4::new(3, 2, 4, 2));\n    assert_eq!(a.wywy(), I32x4::new(4, 2, 4, 2));\n    assert_eq!(a.xzwy(), I32x4::new(1, 3, 4, 2));\n    assert_eq!(a.yzwy(), I32x4::new(2, 3, 4, 2));\n    assert_eq!(a.zzwy(), I32x4::new(3, 3, 4, 2));\n    assert_eq!(a.wzwy(), I32x4::new(4, 3, 4, 2));\n    assert_eq!(a.xwwy(), I32x4::new(1, 4, 4, 2));\n    assert_eq!(a.ywwy(), I32x4::new(2, 4, 4, 2));\n    assert_eq!(a.zwwy(), I32x4::new(3, 4, 4, 2));\n    assert_eq!(a.wwwy(), I32x4::new(4, 4, 4, 2));\n\n    assert_eq!(a.xxxz(), I32x4::new(1, 1, 1, 3));\n    assert_eq!(a.yxxz(), I32x4::new(2, 1, 1, 3));\n    assert_eq!(a.zxxz(), I32x4::new(3, 1, 1, 3));\n    assert_eq!(a.wxxz(), I32x4::new(4, 1, 1, 3));\n    assert_eq!(a.xyxz(), I32x4::new(1, 2, 1, 3));\n    assert_eq!(a.yyxz(), I32x4::new(2, 2, 1, 3));\n    assert_eq!(a.zyxz(), I32x4::new(3, 2, 1, 3));\n    assert_eq!(a.wyxz(), I32x4::new(4, 2, 1, 3));\n    assert_eq!(a.xzxz(), I32x4::new(1, 3, 1, 3));\n    assert_eq!(a.yzxz(), I32x4::new(2, 3, 1, 3));\n    assert_eq!(a.zzxz(), I32x4::new(3, 3, 1, 3));\n    assert_eq!(a.wzxz(), I32x4::new(4, 3, 1, 3));\n    assert_eq!(a.xwxz(), I32x4::new(1, 4, 1, 3));\n    assert_eq!(a.ywxz(), I32x4::new(2, 4, 1, 3));\n    assert_eq!(a.zwxz(), I32x4::new(3, 4, 1, 3));\n    assert_eq!(a.wwxz(), I32x4::new(4, 4, 1, 3));\n    assert_eq!(a.xxyz(), I32x4::new(1, 1, 2, 3));\n    assert_eq!(a.yxyz(), I32x4::new(2, 1, 2, 3));\n    assert_eq!(a.zxyz(), I32x4::new(3, 1, 2, 3));\n    assert_eq!(a.wxyz(), I32x4::new(4, 1, 2, 3));\n    assert_eq!(a.xyyz(), I32x4::new(1, 2, 2, 3));\n    assert_eq!(a.yyyz(), I32x4::new(2, 2, 2, 3));\n    assert_eq!(a.zyyz(), I32x4::new(3, 2, 2, 3));\n    assert_eq!(a.wyyz(), I32x4::new(4, 2, 2, 3));\n    assert_eq!(a.xzyz(), I32x4::new(1, 3, 2, 3));\n    assert_eq!(a.yzyz(), I32x4::new(2, 3, 2, 3));\n    assert_eq!(a.zzyz(), I32x4::new(3, 3, 2, 3));\n    assert_eq!(a.wzyz(), I32x4::new(4, 3, 2, 3));\n    assert_eq!(a.xwyz(), I32x4::new(1, 4, 2, 3));\n    assert_eq!(a.ywyz(), I32x4::new(2, 4, 2, 3));\n    assert_eq!(a.zwyz(), I32x4::new(3, 4, 2, 3));\n    assert_eq!(a.wwyz(), I32x4::new(4, 4, 2, 3));\n    assert_eq!(a.xxzz(), I32x4::new(1, 1, 3, 3));\n    assert_eq!(a.yxzz(), I32x4::new(2, 1, 3, 3));\n    assert_eq!(a.zxzz(), I32x4::new(3, 1, 3, 3));\n    assert_eq!(a.wxzz(), I32x4::new(4, 1, 3, 3));\n    assert_eq!(a.xyzz(), I32x4::new(1, 2, 3, 3));\n    assert_eq!(a.yyzz(), I32x4::new(2, 2, 3, 3));\n    assert_eq!(a.zyzz(), I32x4::new(3, 2, 3, 3));\n    assert_eq!(a.wyzz(), I32x4::new(4, 2, 3, 3));\n    assert_eq!(a.xzzz(), I32x4::new(1, 3, 3, 3));\n    assert_eq!(a.yzzz(), I32x4::new(2, 3, 3, 3));\n    assert_eq!(a.wzzz(), I32x4::new(4, 3, 3, 3));\n    assert_eq!(a.xwzz(), I32x4::new(1, 4, 3, 3));\n    assert_eq!(a.ywzz(), I32x4::new(2, 4, 3, 3));\n    assert_eq!(a.zwzz(), I32x4::new(3, 4, 3, 3));\n    assert_eq!(a.wwzz(), I32x4::new(4, 4, 3, 3));\n    assert_eq!(a.xxwz(), I32x4::new(1, 1, 4, 3));\n    assert_eq!(a.yxwz(), I32x4::new(2, 1, 4, 3));\n    assert_eq!(a.zxwz(), I32x4::new(3, 1, 4, 3));\n    assert_eq!(a.wxwz(), I32x4::new(4, 1, 4, 3));\n    assert_eq!(a.xywz(), I32x4::new(1, 2, 4, 3));\n    assert_eq!(a.yywz(), I32x4::new(2, 2, 4, 3));\n    assert_eq!(a.zywz(), I32x4::new(3, 2, 4, 3));\n    assert_eq!(a.wywz(), I32x4::new(4, 2, 4, 3));\n    assert_eq!(a.xzwz(), I32x4::new(1, 3, 4, 3));\n    assert_eq!(a.yzwz(), I32x4::new(2, 3, 4, 3));\n    assert_eq!(a.zzwz(), I32x4::new(3, 3, 4, 3));\n    assert_eq!(a.wzwz(), I32x4::new(4, 3, 4, 3));\n    assert_eq!(a.xwwz(), I32x4::new(1, 4, 4, 3));\n    assert_eq!(a.ywwz(), I32x4::new(2, 4, 4, 3));\n    assert_eq!(a.zwwz(), I32x4::new(3, 4, 4, 3));\n    assert_eq!(a.wwwz(), I32x4::new(4, 4, 4, 3));\n\n    assert_eq!(a.xxxw(), I32x4::new(1, 1, 1, 4));\n    assert_eq!(a.yxxw(), I32x4::new(2, 1, 1, 4));\n    assert_eq!(a.zxxw(), I32x4::new(3, 1, 1, 4));\n    assert_eq!(a.wxxw(), I32x4::new(4, 1, 1, 4));\n    assert_eq!(a.xyxw(), I32x4::new(1, 2, 1, 4));\n    assert_eq!(a.yyxw(), I32x4::new(2, 2, 1, 4));\n    assert_eq!(a.zyxw(), I32x4::new(3, 2, 1, 4));\n    assert_eq!(a.wyxw(), I32x4::new(4, 2, 1, 4));\n    assert_eq!(a.xzxw(), I32x4::new(1, 3, 1, 4));\n    assert_eq!(a.yzxw(), I32x4::new(2, 3, 1, 4));\n    assert_eq!(a.zzxw(), I32x4::new(3, 3, 1, 4));\n    assert_eq!(a.wzxw(), I32x4::new(4, 3, 1, 4));\n    assert_eq!(a.xwxw(), I32x4::new(1, 4, 1, 4));\n    assert_eq!(a.ywxw(), I32x4::new(2, 4, 1, 4));\n    assert_eq!(a.zwxw(), I32x4::new(3, 4, 1, 4));\n    assert_eq!(a.wwxw(), I32x4::new(4, 4, 1, 4));\n    assert_eq!(a.xxyw(), I32x4::new(1, 1, 2, 4));\n    assert_eq!(a.yxyw(), I32x4::new(2, 1, 2, 4));\n    assert_eq!(a.zxyw(), I32x4::new(3, 1, 2, 4));\n    assert_eq!(a.wxyw(), I32x4::new(4, 1, 2, 4));\n    assert_eq!(a.xyyw(), I32x4::new(1, 2, 2, 4));\n    assert_eq!(a.yyyw(), I32x4::new(2, 2, 2, 4));\n    assert_eq!(a.zyyw(), I32x4::new(3, 2, 2, 4));\n    assert_eq!(a.wyyw(), I32x4::new(4, 2, 2, 4));\n    assert_eq!(a.xzyw(), I32x4::new(1, 3, 2, 4));\n    assert_eq!(a.yzyw(), I32x4::new(2, 3, 2, 4));\n    assert_eq!(a.zzyw(), I32x4::new(3, 3, 2, 4));\n    assert_eq!(a.wzyw(), I32x4::new(4, 3, 2, 4));\n    assert_eq!(a.xwyw(), I32x4::new(1, 4, 2, 4));\n    assert_eq!(a.ywyw(), I32x4::new(2, 4, 2, 4));\n    assert_eq!(a.zwyw(), I32x4::new(3, 4, 2, 4));\n    assert_eq!(a.wwyw(), I32x4::new(4, 4, 2, 4));\n    assert_eq!(a.xxzw(), I32x4::new(1, 1, 3, 4));\n    assert_eq!(a.yxzw(), I32x4::new(2, 1, 3, 4));\n    assert_eq!(a.zxzw(), I32x4::new(3, 1, 3, 4));\n    assert_eq!(a.wxzw(), I32x4::new(4, 1, 3, 4));\n    assert_eq!(a.xyzw(), I32x4::new(1, 2, 3, 4));\n    assert_eq!(a.yyzw(), I32x4::new(2, 2, 3, 4));\n    assert_eq!(a.zyzw(), I32x4::new(3, 2, 3, 4));\n    assert_eq!(a.wyzw(), I32x4::new(4, 2, 3, 4));\n    assert_eq!(a.xzzw(), I32x4::new(1, 3, 3, 4));\n    assert_eq!(a.yzzw(), I32x4::new(2, 3, 3, 4));\n    assert_eq!(a.zzzw(), I32x4::new(3, 3, 3, 4));\n    assert_eq!(a.wzzw(), I32x4::new(4, 3, 3, 4));\n    assert_eq!(a.xwzw(), I32x4::new(1, 4, 3, 4));\n    assert_eq!(a.ywzw(), I32x4::new(2, 4, 3, 4));\n    assert_eq!(a.zwzw(), I32x4::new(3, 4, 3, 4));\n    assert_eq!(a.wwzw(), I32x4::new(4, 4, 3, 4));\n    assert_eq!(a.xxww(), I32x4::new(1, 1, 4, 4));\n    assert_eq!(a.yxww(), I32x4::new(2, 1, 4, 4));\n    assert_eq!(a.zxww(), I32x4::new(3, 1, 4, 4));\n    assert_eq!(a.wxww(), I32x4::new(4, 1, 4, 4));\n    assert_eq!(a.xyww(), I32x4::new(1, 2, 4, 4));\n    assert_eq!(a.yyww(), I32x4::new(2, 2, 4, 4));\n    assert_eq!(a.zyww(), I32x4::new(3, 2, 4, 4));\n    assert_eq!(a.wzww(), I32x4::new(4, 3, 4, 4));\n    assert_eq!(a.xzww(), I32x4::new(1, 3, 4, 4));\n    assert_eq!(a.yzww(), I32x4::new(2, 3, 4, 4));\n    assert_eq!(a.zzww(), I32x4::new(3, 3, 4, 4));\n    assert_eq!(a.wzww(), I32x4::new(4, 3, 4, 4));\n    assert_eq!(a.xwww(), I32x4::new(1, 4, 4, 4));\n    assert_eq!(a.ywww(), I32x4::new(2, 4, 4, 4));\n    assert_eq!(a.zwww(), I32x4::new(3, 4, 4, 4));\n}\n\n// Scalar F32x4\n\n#[test]\nfn test_f32x4s_constructors() {\n    let a = F32x4S::new(1.0, 2.0, 3.0, 4.0);\n    assert_eq!((a[0], a[1], a[2], a[3]), (1.0, 2.0, 3.0, 4.0));\n    let b = F32x4S::splat(10.0);\n    assert_eq!(b, F32x4S::new(10.0, 10.0, 10.0, 10.0));\n}\n\n#[test]\nfn test_f32x4s_basic_ops() {\n    let a = F32x4S::new(1.0, 3.0, 5.0, 7.0);\n    let b = F32x4S::new(2.0, 2.0, 6.0, 6.0);\n    assert_eq!(a.min(b), F32x4S::new(1.0, 2.0, 5.0, 6.0));\n    assert_eq!(a.max(b), F32x4S::new(2.0, 3.0, 6.0, 7.0));\n    let c = F32x4S::new(-1.0, 1.3, -20.0, 3.6);\n    assert_eq!(c.abs(), F32x4S::new(1.0, 1.3, 20.0, 3.6));\n    assert_eq!(c.floor(), F32x4S::new(-1.0, 1.0, -20.0, 3.0));\n    assert_eq!(c.ceil(), F32x4S::new(-1.0, 2.0, -20.0, 4.0));\n    assert_eq!(c.to_i32x4().to_f32x4(), F32x4S::new(-1.0, 1.0, -20.0, 4.0));\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/x86/mod.rs",
      "sha256": "9cdab898e39521790403b85e49c7d92ea8fac1f597cbdd0219bb377421e4f2bd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/x86.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse std::cmp::PartialEq;\nuse std::fmt::{self, Debug, Formatter};\nuse std::mem;\nuse std::ops::{Add, BitAnd, BitOr, BitXor, Div, Index, IndexMut, Mul, Not, Shr, Sub};\n\n#[cfg(target_pointer_width = \"32\")]\nuse std::arch::x86::{__m128, __m128i};\n#[cfg(target_pointer_width = \"32\")]\nuse std::arch::x86;\n#[cfg(target_pointer_width = \"64\")]\nuse std::arch::x86_64::{__m128, __m128i};\n#[cfg(target_pointer_width = \"64\")]\nuse std::arch::x86_64 as x86;\n\nmod swizzle_f32x4;\nmod swizzle_i32x4;\n\n// Two 32-bit floats\n\n#[derive(Clone, Copy)]\npub struct F32x2(pub u64);\n\nimpl F32x2 {\n    // Constructors\n\n    #[inline]\n    pub fn new(a: f32, b: f32) -> F32x2 {\n        unsafe {\n            let a = mem::transmute::<*const f32, *const u32>(&a);\n            let b = mem::transmute::<*const f32, *const u32>(&b);\n            F32x2((*a as u64) | ((*b as u64) << 32))\n        }\n    }\n\n    #[inline]\n    pub fn splat(x: f32) -> F32x2 {\n        F32x2::new(x, x)\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn approx_recip(self) -> F32x2 {\n        self.to_f32x4().approx_recip().xy()\n    }\n\n    #[inline]\n    pub fn min(self, other: F32x2) -> F32x2 {\n        self.to_f32x4().min(other.to_f32x4()).xy()\n    }\n\n    #[inline]\n    pub fn max(self, other: F32x2) -> F32x2 {\n        self.to_f32x4().max(other.to_f32x4()).xy()\n    }\n\n    #[inline]\n    pub fn clamp(self, min: F32x2, max: F32x2) -> F32x2 {\n        self.to_f32x4().clamp(min.to_f32x4(), max.to_f32x4()).xy()\n    }\n\n    #[inline]\n    pub fn abs(self) -> F32x2 {\n        self.to_f32x4().abs().xy()\n    }\n\n    #[inline]\n    pub fn floor(self) -> F32x2 {\n        self.to_f32x4().floor().xy()\n    }\n\n    #[inline]\n    pub fn ceil(self) -> F32x2 {\n        self.to_f32x4().ceil().xy()\n    }\n\n    #[inline]\n    pub fn sqrt(self) -> F32x2 {\n        self.to_f32x4().sqrt().xy()\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: F32x2) -> U32x2 {\n        self.to_f32x4().packed_eq(other.to_f32x4()).xy()\n    }\n\n    #[inline]\n    pub fn packed_gt(self, other: F32x2) -> U32x2 {\n        self.to_f32x4().packed_gt(other.to_f32x4()).xy()\n    }\n\n    #[inline]\n    pub fn packed_lt(self, other: F32x2) -> U32x2 {\n        self.to_f32x4().packed_lt(other.to_f32x4()).xy()\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: F32x2) -> U32x2 {\n        self.to_f32x4().packed_le(other.to_f32x4()).xy()\n    }\n\n    // Conversions\n\n    #[inline]\n    pub fn to_f32x4(self) -> F32x4 {\n        unsafe {\n            let mut result = F32x4::default();\n            *mem::transmute::<&mut __m128, &mut u64>(&mut result.0) = self.0;\n            result\n        }\n    }\n\n    #[inline]\n    pub fn to_i32x2(self) -> I32x2 {\n        self.to_i32x4().xy()\n    }\n\n    #[inline]\n    pub fn to_i32x4(self) -> I32x4 {\n        self.to_f32x4().to_i32x4()\n    }\n\n    // Swizzle\n\n    #[inline]\n    pub fn yx(self) -> F32x2 {\n        self.to_f32x4().yx()\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: F32x2) -> F32x4 {\n        self.to_f32x4().concat_xy_xy(other.to_f32x4())\n    }\n}\n\nimpl Default for F32x2 {\n    #[inline]\n    fn default() -> F32x2 {\n        F32x2(0)\n    }\n}\n\nimpl Index<usize> for F32x2 {\n    type Output = f32;\n    #[inline]\n    fn index(&self, index: usize) -> &f32 {\n        unsafe { &mem::transmute::<&u64, &[f32; 2]>(&self.0)[index] }\n    }\n}\n\nimpl IndexMut<usize> for F32x2 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut f32 {\n        unsafe { &mut mem::transmute::<&mut u64, &mut [f32; 2]>(&mut self.0)[index] }\n    }\n}\n\nimpl Debug for F32x2 {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {\n        write!(f, \"<{}, {}>\", self[0], self[1])\n    }\n}\n\nimpl PartialEq for F32x2 {\n    #[inline]\n    fn eq(&self, other: &F32x2) -> bool {\n        self.packed_eq(*other).all_true()\n    }\n}\n\nimpl Add<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn add(self, other: F32x2) -> F32x2 {\n        (self.to_f32x4() + other.to_f32x4()).xy()\n    }\n}\n\nimpl Div<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn div(self, other: F32x2) -> F32x2 {\n        (self.to_f32x4() / other.to_f32x4()).xy()\n    }\n}\n\nimpl Mul<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn mul(self, other: F32x2) -> F32x2 {\n        (self.to_f32x4() * other.to_f32x4()).xy()\n    }\n}\n\nimpl Sub<F32x2> for F32x2 {\n    type Output = F32x2;\n    #[inline]\n    fn sub(self, other: F32x2) -> F32x2 {\n        (self.to_f32x4() - other.to_f32x4()).xy()\n    }\n}\n\n// Four 32-bit floats\n\n#[derive(Clone, Copy)]\npub struct F32x4(pub __m128);\n\nimpl F32x4 {\n    // Constructors\n\n    #[inline]\n    pub fn new(a: f32, b: f32, c: f32, d: f32) -> F32x4 {\n        unsafe {\n            let vector = [a, b, c, d];\n            F32x4(x86::_mm_loadu_ps(vector.as_ptr()))\n        }\n    }\n\n    #[inline]\n    pub fn splat(x: f32) -> F32x4 {\n        unsafe { F32x4(x86::_mm_set1_ps(x)) }\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn approx_recip(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_rcp_ps(self.0)) }\n    }\n\n    #[inline]\n    pub fn min(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(x86::_mm_min_ps(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn max(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(x86::_mm_max_ps(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn clamp(self, min: F32x4, max: F32x4) -> F32x4 {\n        self.max(min).min(max)\n    }\n\n    #[inline]\n    pub fn abs(self) -> F32x4 {\n        unsafe {\n            let tmp = x86::_mm_srli_epi32(I32x4::splat(-1).0, 1);\n            F32x4(x86::_mm_and_ps(x86::_mm_castsi128_ps(tmp), self.0))\n        }\n    }\n\n    #[inline]\n    pub fn floor(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_floor_ps(self.0)) }\n    }\n\n    #[inline]\n    pub fn ceil(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_ceil_ps(self.0)) }\n    }\n\n    #[inline]\n    pub fn sqrt(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_sqrt_ps(self.0)) }\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: F32x4) -> U32x4 {\n        unsafe {\n            U32x4(x86::_mm_castps_si128(x86::_mm_cmpeq_ps(\n                self.0, other.0,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn packed_gt(self, other: F32x4) -> U32x4 {\n        unsafe {\n            U32x4(x86::_mm_castps_si128(x86::_mm_cmpgt_ps(\n                self.0, other.0,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn packed_lt(self, other: F32x4) -> U32x4 {\n        other.packed_gt(self)\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: F32x4) -> U32x4 {\n        !self.packed_gt(other)\n    }\n\n    // Conversions\n\n    /// Converts these packed floats to integers via rounding.\n    #[inline]\n    pub fn to_i32x4(self) -> I32x4 {\n        unsafe { I32x4(x86::_mm_cvtps_epi32(self.0)) }\n    }\n\n    // Extraction\n\n    #[inline]\n    pub fn xy(self) -> F32x2 {\n        unsafe {\n            let swizzled = self.0;\n            F32x2(*mem::transmute::<&__m128, &u64>(&swizzled))\n        }\n    }\n\n    #[inline]\n    pub fn xw(self) -> F32x2 {\n        self.xwyz().xy()\n    }\n\n    #[inline]\n    pub fn yx(self) -> F32x2 {\n        self.yxwz().xy()\n    }\n\n    #[inline]\n    pub fn zy(self) -> F32x2 {\n        self.zyxw().xy()\n    }\n\n    #[inline]\n    pub fn zw(self) -> F32x2 {\n        self.zwxy().xy()\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: F32x4) -> F32x4 {\n        unsafe {\n            let this = x86::_mm_castps_pd(self.0);\n            let other = x86::_mm_castps_pd(other.0);\n            let result = x86::_mm_unpacklo_pd(this, other);\n            F32x4(x86::_mm_castpd_ps(result))\n        }\n    }\n\n    #[inline]\n    pub fn concat_xy_zw(self, other: F32x4) -> F32x4 {\n        unsafe {\n            let this = x86::_mm_castps_pd(self.0);\n            let other = x86::_mm_castps_pd(other.0);\n            let result = x86::_mm_shuffle_pd(this, other, 0b10);\n            F32x4(x86::_mm_castpd_ps(result))\n        }\n    }\n\n    #[inline]\n    pub fn concat_zw_zw(self, other: F32x4) -> F32x4 {\n        unsafe {\n            let this = x86::_mm_castps_pd(self.0);\n            let other = x86::_mm_castps_pd(other.0);\n            let result = x86::_mm_unpackhi_pd(this, other);\n            F32x4(x86::_mm_castpd_ps(result))\n        }\n    }\n\n    #[inline]\n    pub fn concat_wz_yx(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, other.0, 0b0001_1011)) }\n    }\n}\n\nimpl Default for F32x4 {\n    #[inline]\n    fn default() -> F32x4 {\n        unsafe { F32x4(x86::_mm_setzero_ps()) }\n    }\n}\n\nimpl Index<usize> for F32x4 {\n    type Output = f32;\n    #[inline]\n    fn index(&self, index: usize) -> &f32 {\n        unsafe { &mem::transmute::<&__m128, &[f32; 4]>(&self.0)[index] }\n    }\n}\n\nimpl IndexMut<usize> for F32x4 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut f32 {\n        unsafe { &mut mem::transmute::<&mut __m128, &mut [f32; 4]>(&mut self.0)[index] }\n    }\n}\n\nimpl Debug for F32x4 {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {\n        write!(f, \"<{}, {}, {}, {}>\", self[0], self[1], self[2], self[3])\n    }\n}\n\nimpl PartialEq for F32x4 {\n    #[inline]\n    fn eq(&self, other: &F32x4) -> bool {\n        self.packed_eq(*other).all_true()\n    }\n}\n\nimpl Add<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn add(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(x86::_mm_add_ps(self.0, other.0)) }\n    }\n}\n\nimpl Div<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn div(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(x86::_mm_div_ps(self.0, other.0)) }\n    }\n}\n\nimpl Mul<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn mul(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(x86::_mm_mul_ps(self.0, other.0)) }\n    }\n}\n\nimpl Sub<F32x4> for F32x4 {\n    type Output = F32x4;\n    #[inline]\n    fn sub(self, other: F32x4) -> F32x4 {\n        unsafe { F32x4(x86::_mm_sub_ps(self.0, other.0)) }\n    }\n}\n\n// Two 32-bit signed integers\n\n#[derive(Clone, Copy)]\npub struct I32x2(pub u64);\n\nimpl I32x2 {\n    // Constructors\n\n    #[inline]\n    pub fn new(a: i32, b: i32) -> I32x2 {\n        unsafe {\n            let a = mem::transmute::<*const i32, *const u32>(&a);\n            let b = mem::transmute::<*const i32, *const u32>(&b);\n            I32x2((*a as u64) | ((*b as u64) << 32))\n        }\n    }\n\n    #[inline]\n    pub fn splat(x: i32) -> I32x2 {\n        I32x2::new(x, x)\n    }\n\n    // Accessors\n\n    #[inline]\n    pub fn x(self) -> i32 {\n        self[0]\n    }\n\n    #[inline]\n    pub fn y(self) -> i32 {\n        self[1]\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: I32x2) -> I32x4 {\n        self.to_i32x4().concat_xy_xy(other.to_i32x4())\n    }\n\n    // Conversions\n\n    #[inline]\n    pub fn to_i32x4(self) -> I32x4 {\n        unsafe {\n            let mut result = I32x4::default();\n            *mem::transmute::<&mut __m128i, &mut u64>(&mut result.0) = self.0;\n            result\n        }\n    }\n\n    #[inline]\n    pub fn to_f32x4(self) -> F32x4 {\n        self.to_i32x4().to_f32x4()\n    }\n\n    /// Converts these packed integers to floats.\n    #[inline]\n    pub fn to_f32x2(self) -> F32x2 {\n        self.to_f32x4().xy()\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn max(self, other: I32x2) -> I32x2 {\n        self.to_i32x4().max(other.to_i32x4()).xy()\n    }\n\n    #[inline]\n    pub fn min(self, other: I32x2) -> I32x2 {\n        self.to_i32x4().min(other.to_i32x4()).xy()\n    }\n\n    // Comparisons\n\n    // TODO(pcwalton): Use the `U32x2` type!\n    #[inline]\n    pub fn packed_eq(self, other: I32x2) -> U32x4 {\n        self.to_i32x4().packed_eq(other.to_i32x4())\n    }\n\n    #[inline]\n    pub fn packed_gt(self, other: I32x2) -> U32x4 {\n        self.to_i32x4().packed_gt(other.to_i32x4())\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: I32x2) -> U32x4 {\n        self.to_i32x4().packed_le(other.to_i32x4())\n    }\n}\n\nimpl Default for I32x2 {\n    #[inline]\n    fn default() -> I32x2 {\n        I32x2(0)\n    }\n}\n\nimpl Index<usize> for I32x2 {\n    type Output = i32;\n    #[inline]\n    fn index(&self, index: usize) -> &i32 {\n        unsafe { &mem::transmute::<&u64, &[i32; 2]>(&self.0)[index] }\n    }\n}\n\nimpl IndexMut<usize> for I32x2 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut i32 {\n        unsafe { &mut mem::transmute::<&mut u64, &mut [i32; 2]>(&mut self.0)[index] }\n    }\n}\n\nimpl Add<I32x2> for I32x2 {\n    type Output = I32x2;\n    #[inline]\n    fn add(self, other: I32x2) -> I32x2 {\n        (self.to_i32x4() + other.to_i32x4()).xy()\n    }\n}\n\nimpl Sub<I32x2> for I32x2 {\n    type Output = I32x2;\n    #[inline]\n    fn sub(self, other: I32x2) -> I32x2 {\n        (self.to_i32x4() - other.to_i32x4()).xy()\n    }\n}\n\nimpl Mul<I32x2> for I32x2 {\n    type Output = I32x2;\n    #[inline]\n    fn mul(self, other: I32x2) -> I32x2 {\n        (self.to_i32x4() * other.to_i32x4()).xy()\n    }\n}\n\nimpl Debug for I32x2 {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {\n        write!(f, \"<{}, {}>\", self[0], self[1])\n    }\n}\n\nimpl PartialEq for I32x2 {\n    #[inline]\n    fn eq(&self, other: &I32x2) -> bool {\n        self.packed_eq(*other).all_true()\n    }\n}\n\n// Four 32-bit signed integers\n\n#[derive(Clone, Copy)]\npub struct I32x4(pub __m128i);\n\nimpl I32x4 {\n    // Constructors\n\n    #[inline]\n    pub fn new(a: i32, b: i32, c: i32, d: i32) -> I32x4 {\n        unsafe {\n            let vector = [a, b, c, d];\n            I32x4(x86::_mm_loadu_si128(vector.as_ptr() as *const __m128i))\n        }\n    }\n\n    #[inline]\n    pub fn splat(x: i32) -> I32x4 {\n        unsafe { I32x4(x86::_mm_set1_epi32(x)) }\n    }\n\n    // Extraction\n\n    #[inline]\n    pub fn xy(self) -> I32x2 {\n        unsafe {\n            let swizzled = self.0;\n            I32x2(*mem::transmute::<&__m128i, &u64>(&swizzled))\n        }\n    }\n\n    #[inline]\n    pub fn xw(self) -> I32x2 {\n        self.xwyz().xy()\n    }\n\n    #[inline]\n    pub fn yx(self) -> I32x2 {\n        self.yxwz().xy()\n    }\n\n    #[inline]\n    pub fn zy(self) -> I32x2 {\n        self.zyxw().xy()\n    }\n\n    #[inline]\n    pub fn zw(self) -> I32x2 {\n        self.zwxy().xy()\n    }\n\n    // Concatenations\n\n    #[inline]\n    pub fn concat_xy_xy(self, other: I32x4) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_pd(self.0);\n            let other = x86::_mm_castsi128_pd(other.0);\n            let result = x86::_mm_unpacklo_pd(this, other);\n            I32x4(x86::_mm_castpd_si128(result))\n        }\n    }\n\n    #[inline]\n    pub fn concat_zw_zw(self, other: I32x4) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_pd(self.0);\n            let other = x86::_mm_castsi128_pd(other.0);\n            let result = x86::_mm_unpackhi_pd(this, other);\n            I32x4(x86::_mm_castpd_si128(result))\n        }\n    }\n\n    // Conversions\n\n    /// Converts these packed integers to floats.\n    #[inline]\n    pub fn to_f32x4(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_cvtepi32_ps(self.0)) }\n    }\n\n    /// Converts these packed signed integers to unsigned integers.\n    ///\n    /// Overflowing values will wrap around.\n    #[inline]\n    pub fn to_u32x4(self) -> U32x4 {\n        U32x4(self.0)\n    }\n\n    // Basic operations\n\n    #[inline]\n    pub fn max(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(x86::_mm_max_epi32(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn min(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(x86::_mm_min_epi32(self.0, other.0)) }\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: I32x4) -> U32x4 {\n        unsafe { U32x4(x86::_mm_cmpeq_epi32(self.0, other.0)) }\n    }\n\n    // Comparisons\n\n    #[inline]\n    pub fn packed_gt(self, other: I32x4) -> U32x4 {\n        unsafe { U32x4(x86::_mm_cmpgt_epi32(self.0, other.0)) }\n    }\n\n    #[inline]\n    pub fn packed_lt(self, other: I32x4) -> U32x4 {\n        other.packed_gt(self)\n    }\n\n    #[inline]\n    pub fn packed_le(self, other: I32x4) -> U32x4 {\n        !self.packed_gt(other)\n    }\n}\n\nimpl Default for I32x4 {\n    #[inline]\n    fn default() -> I32x4 {\n        unsafe { I32x4(x86::_mm_setzero_si128()) }\n    }\n}\n\nimpl Index<usize> for I32x4 {\n    type Output = i32;\n    #[inline]\n    fn index(&self, index: usize) -> &i32 {\n        unsafe { &mem::transmute::<&__m128i, &[i32; 4]>(&self.0)[index] }\n    }\n}\n\nimpl IndexMut<usize> for I32x4 {\n    #[inline]\n    fn index_mut(&mut self, index: usize) -> &mut i32 {\n        unsafe { &mut mem::transmute::<&mut __m128i, &mut [i32; 4]>(&mut self.0)[index] }\n    }\n}\n\nimpl Add<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn add(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(x86::_mm_add_epi32(self.0, other.0)) }\n    }\n}\n\nimpl Sub<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn sub(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(x86::_mm_sub_epi32(self.0, other.0)) }\n    }\n}\n\nimpl Mul<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn mul(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(x86::_mm_mullo_epi32(self.0, other.0)) }\n    }\n}\n\nimpl BitAnd<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn bitand(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(x86::_mm_and_si128(self.0, other.0)) }\n    }\n}\n\nimpl BitOr<I32x4> for I32x4 {\n    type Output = I32x4;\n    #[inline]\n    fn bitor(self, other: I32x4) -> I32x4 {\n        unsafe { I32x4(x86::_mm_or_si128(self.0, other.0)) }\n    }\n}\n\nimpl Debug for I32x4 {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {\n        write!(f, \"<{}, {}, {}, {}>\", self[0], self[1], self[2], self[3])\n    }\n}\n\nimpl PartialEq for I32x4 {\n    #[inline]\n    fn eq(&self, other: &I32x4) -> bool {\n        self.packed_eq(*other).all_true()\n    }\n}\n\n// Two 32-bit unsigned integers\n\n#[derive(Clone, Copy)]\npub struct U32x2(pub u64);\n\nimpl U32x2 {\n    #[inline]\n    pub fn new(x: u32, y: u32) -> U32x2 {\n        U32x2(x as u64 | ((y as u64) << 32))\n    }\n\n    #[inline]\n    pub fn splat(x: u32) -> U32x2 {\n        U32x2::new(x, x)\n    }\n\n    /// Returns true if both booleans in this vector are true.\n    ///\n    /// The result is *undefined* if both values in this vector are not booleans. A boolean is a\n    /// value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_true(self) -> bool {\n        self.0 == !0\n    }\n\n    /// Returns true if both booleans in this vector are false.\n    ///\n    /// The result is *undefined* if both values in this vector are not booleans. A boolean is a\n    /// value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_false(self) -> bool {\n        self.0 == 0\n    }\n\n    #[inline]\n    pub fn to_i32x2(self) -> I32x2 {\n        I32x2(self.0)\n    }\n}\n\nimpl Not for U32x2 {\n    type Output = U32x2;\n    #[inline]\n    fn not(self) -> U32x2 {\n        U32x2(!self.0)\n    }\n}\n\nimpl BitAnd<U32x2> for U32x2 {\n    type Output = U32x2;\n    #[inline]\n    fn bitand(self, other: U32x2) -> U32x2 {\n        U32x2(self.0 & other.0)\n    }\n}\n\nimpl BitOr<U32x2> for U32x2 {\n    type Output = U32x2;\n    #[inline]\n    fn bitor(self, other: U32x2) -> U32x2 {\n        U32x2(self.0 | other.0)\n    }\n}\n\n// Four 32-bit unsigned integers\n\n#[derive(Clone, Copy)]\npub struct U32x4(pub __m128i);\n\nimpl U32x4 {\n    // Constructors\n\n    #[inline]\n    pub fn new(a: u32, b: u32, c: u32, d: u32) -> U32x4 {\n        unsafe {\n            let vector = [a, b, c, d];\n            U32x4(x86::_mm_loadu_si128(vector.as_ptr() as *const __m128i))\n        }\n    }\n\n    #[inline]\n    pub fn splat(x: u32) -> U32x4 {\n        unsafe { U32x4(x86::_mm_set1_epi32(x as i32)) }\n    }\n\n    // Conversions\n\n    /// Converts these packed unsigned integers to signed integers.\n    ///\n    /// Overflowing values will wrap around.\n    #[inline]\n    pub fn to_i32x4(self) -> I32x4 {\n        I32x4(self.0)\n    }\n\n    // Basic operations\n\n    /// Returns true if all four booleans in this vector are true.\n    ///\n    /// The result is *undefined* if all four values in this vector are not booleans. A boolean is\n    /// a value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_true(self) -> bool {\n        unsafe { x86::_mm_movemask_ps(x86::_mm_castsi128_ps(self.0)) == 0x0f }\n    }\n\n    /// Returns true if all four booleans in this vector are false.\n    ///\n    /// The result is *undefined* if all four values in this vector are not booleans. A boolean is\n    /// a value with all bits set or all bits clear (i.e. !0 or 0).\n    #[inline]\n    pub fn all_false(self) -> bool {\n        unsafe { x86::_mm_movemask_ps(x86::_mm_castsi128_ps(self.0)) == 0x00 }\n    }\n\n    // Extraction\n\n    #[inline]\n    pub fn xy(self) -> U32x2 {\n        unsafe {\n            let swizzled = self.0;\n            U32x2(*mem::transmute::<&__m128i, &u64>(&swizzled))\n        }\n    }\n\n    // Packed comparisons\n\n    #[inline]\n    pub fn packed_eq(self, other: U32x4) -> U32x4 {\n        unsafe { U32x4(x86::_mm_cmpeq_epi32(self.0, other.0)) }\n    }\n}\n\nimpl Debug for U32x4 {\n    #[inline]\n    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {\n        write!(f, \"<{}, {}, {}, {}>\", self[0], self[1], self[2], self[3])\n    }\n}\n\nimpl Index<usize> for U32x4 {\n    type Output = u32;\n    #[inline]\n    fn index(&self, index: usize) -> &u32 {\n        unsafe { &mem::transmute::<&__m128i, &[u32; 4]>(&self.0)[index] }\n    }\n}\n\nimpl PartialEq for U32x4 {\n    #[inline]\n    fn eq(&self, other: &U32x4) -> bool {\n        self.packed_eq(*other).all_true()\n    }\n}\n\nimpl Not for U32x4 {\n    type Output = U32x4;\n    #[inline]\n    fn not(self) -> U32x4 {\n        self ^ U32x4::splat(!0)\n    }\n}\n\nimpl BitXor<U32x4> for U32x4 {\n    type Output = U32x4;\n    #[inline]\n    fn bitxor(self, other: U32x4) -> U32x4 {\n        unsafe { U32x4(x86::_mm_xor_si128(self.0, other.0)) }\n    }\n}\n\nimpl Shr<u32> for U32x4 {\n    type Output = U32x4;\n    #[inline]\n    fn shr(self, amount: u32) -> U32x4 {\n        unsafe { U32x4(x86::_mm_srl_epi32(self.0, U32x4::new(amount, 0, 0, 0).0)) }\n    }\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/x86/swizzle_f32x4.rs",
      "sha256": "59868ea641f48fbf09de20bf145dd101e50254bc7890c860a42ecadb61d0c1e1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/x86/swizzle_f32x4.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::x86::F32x4;\n\n#[cfg(target_pointer_width = \"32\")]\nuse std::arch::x86;\n#[cfg(target_pointer_width = \"64\")]\nuse std::arch::x86_64 as x86;\n\nimpl F32x4 {\n    #[inline]\n    pub fn xxxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 0)) }\n    }\n\n    #[inline]\n    pub fn yxxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 1)) }\n    }\n\n    #[inline]\n    pub fn zxxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 2)) }\n    }\n\n    #[inline]\n    pub fn wxxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 3)) }\n    }\n\n    #[inline]\n    pub fn xyxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 4)) }\n    }\n\n    #[inline]\n    pub fn yyxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 5)) }\n    }\n\n    #[inline]\n    pub fn zyxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 6)) }\n    }\n\n    #[inline]\n    pub fn wyxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 7)) }\n    }\n\n    #[inline]\n    pub fn xzxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 8)) }\n    }\n\n    #[inline]\n    pub fn yzxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 9)) }\n    }\n\n    #[inline]\n    pub fn zzxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 10)) }\n    }\n\n    #[inline]\n    pub fn wzxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 11)) }\n    }\n\n    #[inline]\n    pub fn xwxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 12)) }\n    }\n\n    #[inline]\n    pub fn ywxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 13)) }\n    }\n\n    #[inline]\n    pub fn zwxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 14)) }\n    }\n\n    #[inline]\n    pub fn wwxx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 15)) }\n    }\n\n    #[inline]\n    pub fn xxyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 16)) }\n    }\n\n    #[inline]\n    pub fn yxyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 17)) }\n    }\n\n    #[inline]\n    pub fn zxyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 18)) }\n    }\n\n    #[inline]\n    pub fn wxyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 19)) }\n    }\n\n    #[inline]\n    pub fn xyyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 20)) }\n    }\n\n    #[inline]\n    pub fn yyyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 21)) }\n    }\n\n    #[inline]\n    pub fn zyyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 22)) }\n    }\n\n    #[inline]\n    pub fn wyyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 23)) }\n    }\n\n    #[inline]\n    pub fn xzyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 24)) }\n    }\n\n    #[inline]\n    pub fn yzyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 25)) }\n    }\n\n    #[inline]\n    pub fn zzyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 26)) }\n    }\n\n    #[inline]\n    pub fn wzyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 27)) }\n    }\n\n    #[inline]\n    pub fn xwyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 28)) }\n    }\n\n    #[inline]\n    pub fn ywyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 29)) }\n    }\n\n    #[inline]\n    pub fn zwyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 30)) }\n    }\n\n    #[inline]\n    pub fn wwyx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 31)) }\n    }\n\n    #[inline]\n    pub fn xxzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 32)) }\n    }\n\n    #[inline]\n    pub fn yxzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 33)) }\n    }\n\n    #[inline]\n    pub fn zxzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 34)) }\n    }\n\n    #[inline]\n    pub fn wxzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 35)) }\n    }\n\n    #[inline]\n    pub fn xyzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 36)) }\n    }\n\n    #[inline]\n    pub fn yyzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 37)) }\n    }\n\n    #[inline]\n    pub fn zyzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 38)) }\n    }\n\n    #[inline]\n    pub fn wyzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 39)) }\n    }\n\n    #[inline]\n    pub fn xzzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 40)) }\n    }\n\n    #[inline]\n    pub fn yzzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 41)) }\n    }\n\n    #[inline]\n    pub fn zzzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 42)) }\n    }\n\n    #[inline]\n    pub fn wzzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 43)) }\n    }\n\n    #[inline]\n    pub fn xwzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 44)) }\n    }\n\n    #[inline]\n    pub fn ywzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 45)) }\n    }\n\n    #[inline]\n    pub fn zwzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 46)) }\n    }\n\n    #[inline]\n    pub fn wwzx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 47)) }\n    }\n\n    #[inline]\n    pub fn xxwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 48)) }\n    }\n\n    #[inline]\n    pub fn yxwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 49)) }\n    }\n\n    #[inline]\n    pub fn zxwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 50)) }\n    }\n\n    #[inline]\n    pub fn wxwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 51)) }\n    }\n\n    #[inline]\n    pub fn xywx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 52)) }\n    }\n\n    #[inline]\n    pub fn yywx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 53)) }\n    }\n\n    #[inline]\n    pub fn zywx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 54)) }\n    }\n\n    #[inline]\n    pub fn wywx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 55)) }\n    }\n\n    #[inline]\n    pub fn xzwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 56)) }\n    }\n\n    #[inline]\n    pub fn yzwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 57)) }\n    }\n\n    #[inline]\n    pub fn zzwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 58)) }\n    }\n\n    #[inline]\n    pub fn wzwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 59)) }\n    }\n\n    #[inline]\n    pub fn xwwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 60)) }\n    }\n\n    #[inline]\n    pub fn ywwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 61)) }\n    }\n\n    #[inline]\n    pub fn zwwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 62)) }\n    }\n\n    #[inline]\n    pub fn wwwx(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 63)) }\n    }\n\n    #[inline]\n    pub fn xxxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 64)) }\n    }\n\n    #[inline]\n    pub fn yxxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 65)) }\n    }\n\n    #[inline]\n    pub fn zxxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 66)) }\n    }\n\n    #[inline]\n    pub fn wxxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 67)) }\n    }\n\n    #[inline]\n    pub fn xyxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 68)) }\n    }\n\n    #[inline]\n    pub fn yyxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 69)) }\n    }\n\n    #[inline]\n    pub fn zyxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 70)) }\n    }\n\n    #[inline]\n    pub fn wyxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 71)) }\n    }\n\n    #[inline]\n    pub fn xzxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 72)) }\n    }\n\n    #[inline]\n    pub fn yzxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 73)) }\n    }\n\n    #[inline]\n    pub fn zzxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 74)) }\n    }\n\n    #[inline]\n    pub fn wzxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 75)) }\n    }\n\n    #[inline]\n    pub fn xwxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 76)) }\n    }\n\n    #[inline]\n    pub fn ywxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 77)) }\n    }\n\n    #[inline]\n    pub fn zwxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 78)) }\n    }\n\n    #[inline]\n    pub fn wwxy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 79)) }\n    }\n\n    #[inline]\n    pub fn xxyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 80)) }\n    }\n\n    #[inline]\n    pub fn yxyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 81)) }\n    }\n\n    #[inline]\n    pub fn zxyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 82)) }\n    }\n\n    #[inline]\n    pub fn wxyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 83)) }\n    }\n\n    #[inline]\n    pub fn xyyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 84)) }\n    }\n\n    #[inline]\n    pub fn yyyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 85)) }\n    }\n\n    #[inline]\n    pub fn zyyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 86)) }\n    }\n\n    #[inline]\n    pub fn wyyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 87)) }\n    }\n\n    #[inline]\n    pub fn xzyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 88)) }\n    }\n\n    #[inline]\n    pub fn yzyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 89)) }\n    }\n\n    #[inline]\n    pub fn zzyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 90)) }\n    }\n\n    #[inline]\n    pub fn wzyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 91)) }\n    }\n\n    #[inline]\n    pub fn xwyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 92)) }\n    }\n\n    #[inline]\n    pub fn ywyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 93)) }\n    }\n\n    #[inline]\n    pub fn zwyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 94)) }\n    }\n\n    #[inline]\n    pub fn wwyy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 95)) }\n    }\n\n    #[inline]\n    pub fn xxzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 96)) }\n    }\n\n    #[inline]\n    pub fn yxzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 97)) }\n    }\n\n    #[inline]\n    pub fn zxzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 98)) }\n    }\n\n    #[inline]\n    pub fn wxzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 99)) }\n    }\n\n    #[inline]\n    pub fn xyzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 100)) }\n    }\n\n    #[inline]\n    pub fn yyzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 101)) }\n    }\n\n    #[inline]\n    pub fn zyzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 102)) }\n    }\n\n    #[inline]\n    pub fn wyzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 103)) }\n    }\n\n    #[inline]\n    pub fn xzzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 104)) }\n    }\n\n    #[inline]\n    pub fn yzzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 105)) }\n    }\n\n    #[inline]\n    pub fn zzzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 106)) }\n    }\n\n    #[inline]\n    pub fn wzzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 107)) }\n    }\n\n    #[inline]\n    pub fn xwzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 108)) }\n    }\n\n    #[inline]\n    pub fn ywzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 109)) }\n    }\n\n    #[inline]\n    pub fn zwzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 110)) }\n    }\n\n    #[inline]\n    pub fn wwzy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 111)) }\n    }\n\n    #[inline]\n    pub fn xxwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 112)) }\n    }\n\n    #[inline]\n    pub fn yxwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 113)) }\n    }\n\n    #[inline]\n    pub fn zxwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 114)) }\n    }\n\n    #[inline]\n    pub fn wxwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 115)) }\n    }\n\n    #[inline]\n    pub fn xywy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 116)) }\n    }\n\n    #[inline]\n    pub fn yywy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 117)) }\n    }\n\n    #[inline]\n    pub fn zywy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 118)) }\n    }\n\n    #[inline]\n    pub fn wywy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 119)) }\n    }\n\n    #[inline]\n    pub fn xzwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 120)) }\n    }\n\n    #[inline]\n    pub fn yzwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 121)) }\n    }\n\n    #[inline]\n    pub fn zzwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 122)) }\n    }\n\n    #[inline]\n    pub fn wzwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 123)) }\n    }\n\n    #[inline]\n    pub fn xwwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 124)) }\n    }\n\n    #[inline]\n    pub fn ywwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 125)) }\n    }\n\n    #[inline]\n    pub fn zwwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 126)) }\n    }\n\n    #[inline]\n    pub fn wwwy(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 127)) }\n    }\n\n    #[inline]\n    pub fn xxxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 128)) }\n    }\n\n    #[inline]\n    pub fn yxxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 129)) }\n    }\n\n    #[inline]\n    pub fn zxxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 130)) }\n    }\n\n    #[inline]\n    pub fn wxxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 131)) }\n    }\n\n    #[inline]\n    pub fn xyxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 132)) }\n    }\n\n    #[inline]\n    pub fn yyxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 133)) }\n    }\n\n    #[inline]\n    pub fn zyxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 134)) }\n    }\n\n    #[inline]\n    pub fn wyxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 135)) }\n    }\n\n    #[inline]\n    pub fn xzxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 136)) }\n    }\n\n    #[inline]\n    pub fn yzxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 137)) }\n    }\n\n    #[inline]\n    pub fn zzxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 138)) }\n    }\n\n    #[inline]\n    pub fn wzxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 139)) }\n    }\n\n    #[inline]\n    pub fn xwxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 140)) }\n    }\n\n    #[inline]\n    pub fn ywxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 141)) }\n    }\n\n    #[inline]\n    pub fn zwxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 142)) }\n    }\n\n    #[inline]\n    pub fn wwxz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 143)) }\n    }\n\n    #[inline]\n    pub fn xxyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 144)) }\n    }\n\n    #[inline]\n    pub fn yxyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 145)) }\n    }\n\n    #[inline]\n    pub fn zxyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 146)) }\n    }\n\n    #[inline]\n    pub fn wxyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 147)) }\n    }\n\n    #[inline]\n    pub fn xyyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 148)) }\n    }\n\n    #[inline]\n    pub fn yyyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 149)) }\n    }\n\n    #[inline]\n    pub fn zyyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 150)) }\n    }\n\n    #[inline]\n    pub fn wyyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 151)) }\n    }\n\n    #[inline]\n    pub fn xzyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 152)) }\n    }\n\n    #[inline]\n    pub fn yzyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 153)) }\n    }\n\n    #[inline]\n    pub fn zzyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 154)) }\n    }\n\n    #[inline]\n    pub fn wzyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 155)) }\n    }\n\n    #[inline]\n    pub fn xwyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 156)) }\n    }\n\n    #[inline]\n    pub fn ywyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 157)) }\n    }\n\n    #[inline]\n    pub fn zwyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 158)) }\n    }\n\n    #[inline]\n    pub fn wwyz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 159)) }\n    }\n\n    #[inline]\n    pub fn xxzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 160)) }\n    }\n\n    #[inline]\n    pub fn yxzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 161)) }\n    }\n\n    #[inline]\n    pub fn zxzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 162)) }\n    }\n\n    #[inline]\n    pub fn wxzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 163)) }\n    }\n\n    #[inline]\n    pub fn xyzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 164)) }\n    }\n\n    #[inline]\n    pub fn yyzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 165)) }\n    }\n\n    #[inline]\n    pub fn zyzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 166)) }\n    }\n\n    #[inline]\n    pub fn wyzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 167)) }\n    }\n\n    #[inline]\n    pub fn xzzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 168)) }\n    }\n\n    #[inline]\n    pub fn yzzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 169)) }\n    }\n\n    #[inline]\n    pub fn zzzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 170)) }\n    }\n\n    #[inline]\n    pub fn wzzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 171)) }\n    }\n\n    #[inline]\n    pub fn xwzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 172)) }\n    }\n\n    #[inline]\n    pub fn ywzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 173)) }\n    }\n\n    #[inline]\n    pub fn zwzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 174)) }\n    }\n\n    #[inline]\n    pub fn wwzz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 175)) }\n    }\n\n    #[inline]\n    pub fn xxwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 176)) }\n    }\n\n    #[inline]\n    pub fn yxwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 177)) }\n    }\n\n    #[inline]\n    pub fn zxwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 178)) }\n    }\n\n    #[inline]\n    pub fn wxwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 179)) }\n    }\n\n    #[inline]\n    pub fn xywz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 180)) }\n    }\n\n    #[inline]\n    pub fn yywz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 181)) }\n    }\n\n    #[inline]\n    pub fn zywz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 182)) }\n    }\n\n    #[inline]\n    pub fn wywz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 183)) }\n    }\n\n    #[inline]\n    pub fn xzwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 184)) }\n    }\n\n    #[inline]\n    pub fn yzwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 185)) }\n    }\n\n    #[inline]\n    pub fn zzwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 186)) }\n    }\n\n    #[inline]\n    pub fn wzwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 187)) }\n    }\n\n    #[inline]\n    pub fn xwwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 188)) }\n    }\n\n    #[inline]\n    pub fn ywwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 189)) }\n    }\n\n    #[inline]\n    pub fn zwwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 190)) }\n    }\n\n    #[inline]\n    pub fn wwwz(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 191)) }\n    }\n\n    #[inline]\n    pub fn xxxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 192)) }\n    }\n\n    #[inline]\n    pub fn yxxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 193)) }\n    }\n\n    #[inline]\n    pub fn zxxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 194)) }\n    }\n\n    #[inline]\n    pub fn wxxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 195)) }\n    }\n\n    #[inline]\n    pub fn xyxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 196)) }\n    }\n\n    #[inline]\n    pub fn yyxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 197)) }\n    }\n\n    #[inline]\n    pub fn zyxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 198)) }\n    }\n\n    #[inline]\n    pub fn wyxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 199)) }\n    }\n\n    #[inline]\n    pub fn xzxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 200)) }\n    }\n\n    #[inline]\n    pub fn yzxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 201)) }\n    }\n\n    #[inline]\n    pub fn zzxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 202)) }\n    }\n\n    #[inline]\n    pub fn wzxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 203)) }\n    }\n\n    #[inline]\n    pub fn xwxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 204)) }\n    }\n\n    #[inline]\n    pub fn ywxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 205)) }\n    }\n\n    #[inline]\n    pub fn zwxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 206)) }\n    }\n\n    #[inline]\n    pub fn wwxw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 207)) }\n    }\n\n    #[inline]\n    pub fn xxyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 208)) }\n    }\n\n    #[inline]\n    pub fn yxyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 209)) }\n    }\n\n    #[inline]\n    pub fn zxyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 210)) }\n    }\n\n    #[inline]\n    pub fn wxyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 211)) }\n    }\n\n    #[inline]\n    pub fn xyyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 212)) }\n    }\n\n    #[inline]\n    pub fn yyyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 213)) }\n    }\n\n    #[inline]\n    pub fn zyyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 214)) }\n    }\n\n    #[inline]\n    pub fn wyyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 215)) }\n    }\n\n    #[inline]\n    pub fn xzyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 216)) }\n    }\n\n    #[inline]\n    pub fn yzyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 217)) }\n    }\n\n    #[inline]\n    pub fn zzyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 218)) }\n    }\n\n    #[inline]\n    pub fn wzyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 219)) }\n    }\n\n    #[inline]\n    pub fn xwyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 220)) }\n    }\n\n    #[inline]\n    pub fn ywyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 221)) }\n    }\n\n    #[inline]\n    pub fn zwyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 222)) }\n    }\n\n    #[inline]\n    pub fn wwyw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 223)) }\n    }\n\n    #[inline]\n    pub fn xxzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 224)) }\n    }\n\n    #[inline]\n    pub fn yxzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 225)) }\n    }\n\n    #[inline]\n    pub fn zxzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 226)) }\n    }\n\n    #[inline]\n    pub fn wxzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 227)) }\n    }\n\n    #[inline]\n    pub fn xyzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 228)) }\n    }\n\n    #[inline]\n    pub fn yyzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 229)) }\n    }\n\n    #[inline]\n    pub fn zyzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 230)) }\n    }\n\n    #[inline]\n    pub fn wyzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 231)) }\n    }\n\n    #[inline]\n    pub fn xzzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 232)) }\n    }\n\n    #[inline]\n    pub fn yzzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 233)) }\n    }\n\n    #[inline]\n    pub fn zzzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 234)) }\n    }\n\n    #[inline]\n    pub fn wzzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 235)) }\n    }\n\n    #[inline]\n    pub fn xwzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 236)) }\n    }\n\n    #[inline]\n    pub fn ywzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 237)) }\n    }\n\n    #[inline]\n    pub fn zwzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 238)) }\n    }\n\n    #[inline]\n    pub fn wwzw(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 239)) }\n    }\n\n    #[inline]\n    pub fn xxww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 240)) }\n    }\n\n    #[inline]\n    pub fn yxww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 241)) }\n    }\n\n    #[inline]\n    pub fn zxww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 242)) }\n    }\n\n    #[inline]\n    pub fn wxww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 243)) }\n    }\n\n    #[inline]\n    pub fn xyww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 244)) }\n    }\n\n    #[inline]\n    pub fn yyww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 245)) }\n    }\n\n    #[inline]\n    pub fn zyww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 246)) }\n    }\n\n    #[inline]\n    pub fn wyww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 247)) }\n    }\n\n    #[inline]\n    pub fn xzww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 248)) }\n    }\n\n    #[inline]\n    pub fn yzww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 249)) }\n    }\n\n    #[inline]\n    pub fn zzww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 250)) }\n    }\n\n    #[inline]\n    pub fn wzww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 251)) }\n    }\n\n    #[inline]\n    pub fn xwww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 252)) }\n    }\n\n    #[inline]\n    pub fn ywww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 253)) }\n    }\n\n    #[inline]\n    pub fn zwww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 254)) }\n    }\n\n    #[inline]\n    pub fn wwww(self) -> F32x4 {\n        unsafe { F32x4(x86::_mm_shuffle_ps(self.0, self.0, 255)) }\n    }\n}\n"
    },
    {
      "package": "pathfinder_simd@0.5.6",
      "sourcePath": "src/x86/swizzle_i32x4.rs",
      "sha256": "000ff6f0fb425f439b2d5ee0afd128b97873b4bb207b3bf6b30ec5e4466111ea",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// pathfinder/simd/src/x86/swizzle_i32x4.rs\n//\n// Copyright © 2019 The Pathfinder Project Developers.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::x86::I32x4;\n\n#[cfg(target_pointer_width = \"32\")]\nuse std::arch::x86;\n#[cfg(target_pointer_width = \"64\")]\nuse std::arch::x86_64 as x86;\n\nimpl I32x4 {\n    #[inline]\n    pub fn xxxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 0,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 1,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 2,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 3,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 4,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 5,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 6,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 7,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 8,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 9,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 10,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 11,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 12,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 13,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 14,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwxx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 15,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 16,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 17,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 18,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 19,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 20,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 21,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 22,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 23,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 24,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 25,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 26,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 27,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 28,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 29,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 30,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwyx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 31,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 32,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 33,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 34,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 35,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 36,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 37,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 38,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 39,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 40,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 41,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 42,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 43,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 44,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 45,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 46,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwzx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 47,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 48,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 49,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 50,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 51,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xywx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 52,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yywx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 53,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zywx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 54,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wywx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 55,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 56,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 57,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 58,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 59,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 60,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 61,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 62,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwwx(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 63,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 64,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 65,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 66,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 67,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 68,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 69,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 70,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 71,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 72,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 73,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 74,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 75,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 76,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 77,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 78,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwxy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 79,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 80,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 81,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 82,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 83,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 84,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 85,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 86,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 87,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 88,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 89,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 90,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 91,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 92,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 93,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 94,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwyy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 95,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 96,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 97,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 98,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 99,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 100,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 101,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 102,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 103,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 104,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 105,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 106,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 107,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 108,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 109,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 110,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwzy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 111,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 112,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 113,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 114,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 115,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xywy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 116,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yywy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 117,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zywy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 118,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wywy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 119,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 120,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 121,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 122,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 123,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 124,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 125,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 126,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwwy(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 127,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 128,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 129,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 130,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 131,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 132,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 133,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 134,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 135,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 136,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 137,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 138,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 139,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 140,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 141,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 142,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwxz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 143,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 144,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 145,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 146,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 147,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 148,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 149,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 150,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 151,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 152,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 153,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 154,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 155,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 156,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 157,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 158,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwyz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 159,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 160,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 161,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 162,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 163,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 164,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 165,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 166,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 167,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 168,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 169,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 170,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 171,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 172,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 173,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 174,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwzz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 175,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 176,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 177,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 178,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 179,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xywz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 180,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yywz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 181,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zywz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 182,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wywz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 183,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 184,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 185,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 186,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 187,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 188,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 189,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 190,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwwz(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 191,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 192,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 193,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 194,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 195,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 196,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 197,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 198,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 199,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 200,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 201,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 202,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 203,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 204,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 205,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 206,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwxw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 207,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 208,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 209,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 210,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 211,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 212,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 213,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 214,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 215,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 216,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 217,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 218,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 219,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 220,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 221,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 222,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwyw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 223,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 224,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 225,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 226,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 227,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 228,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 229,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 230,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 231,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 232,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 233,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 234,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 235,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 236,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 237,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 238,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwzw(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 239,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xxww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 240,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yxww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 241,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zxww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 242,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wxww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 243,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xyww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 244,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yyww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 245,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zyww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 246,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wyww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 247,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xzww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 248,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn yzww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 249,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zzww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 250,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wzww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 251,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn xwww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 252,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn ywww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 253,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn zwww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 254,\n            )))\n        }\n    }\n\n    #[inline]\n    pub fn wwww(self) -> I32x4 {\n        unsafe {\n            let this = x86::_mm_castsi128_ps(self.0);\n            I32x4(x86::_mm_castps_si128(x86::_mm_shuffle_ps(\n                this, this, 255,\n            )))\n        }\n    }\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "README.md",
      "sha256": "a6221fce50cc09c13b03a7973fb1d4dbf59ce7f46ca06830bbd46d201ed3b2d8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# pin-project-lite\n\n[![crates.io](https://img.shields.io/crates/v/pin-project-lite?style=flat-square&logo=rust)](https://crates.io/crates/pin-project-lite)\n[![docs.rs](https://img.shields.io/badge/docs.rs-pin--project--lite-blue?style=flat-square&logo=docs.rs)](https://docs.rs/pin-project-lite)\n[![license](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue?style=flat-square)](#license)\n[![msrv](https://img.shields.io/badge/msrv-1.37-blue?style=flat-square&logo=rust)](https://www.rust-lang.org)\n[![github actions](https://img.shields.io/github/actions/workflow/status/taiki-e/pin-project-lite/ci.yml?branch=main&style=flat-square&logo=github)](https://github.com/taiki-e/pin-project-lite/actions)\n\n<!-- tidy:sync-markdown-to-rustdoc:start:src/lib.rs -->\n\nA lightweight version of [pin-project] written with declarative macros.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\npin-project-lite = \"0.2\"\n```\n\n## Examples\n\n[`pin_project!`] macro creates a projection type covering all the fields of\nstruct.\n\n```rust\nuse std::pin::Pin;\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    struct Struct<T, U> {\n        #[pin]\n        pinned: T,\n        unpinned: U,\n    }\n}\n\nimpl<T, U> Struct<T, U> {\n    fn method(self: Pin<&mut Self>) {\n        let this = self.project();\n        let _: Pin<&mut T> = this.pinned; // Pinned reference to the field\n        let _: &mut U = this.unpinned; // Normal reference to the field\n    }\n}\n```\n\nTo use [`pin_project!`] on enums, you need to name the projection type\nreturned from the method.\n\n```rust\nuse std::pin::Pin;\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project = EnumProj]\n    enum Enum<T, U> {\n        Variant { #[pin] pinned: T, unpinned: U },\n    }\n}\n\nimpl<T, U> Enum<T, U> {\n    fn method(self: Pin<&mut Self>) {\n        match self.project() {\n            EnumProj::Variant { pinned, unpinned } => {\n                let _: Pin<&mut T> = pinned;\n                let _: &mut U = unpinned;\n            }\n        }\n    }\n}\n```\n\n## [pin-project] vs pin-project-lite\n\nHere are some similarities and differences compared to [pin-project].\n\n### Similar: Safety\n\npin-project-lite guarantees safety in much the same way as [pin-project].\nBoth are completely safe unless you write other unsafe code.\n\n### Different: Minimal design\n\nThis library does not tackle as expansive of a range of use cases as\n[pin-project] does. If your use case is not already covered, please use\n[pin-project].\n\n### Different: No proc-macro related dependencies\n\nThis is the **only** reason to use this crate. However, **if you already\nhave proc-macro related dependencies in your crate's dependency graph, there\nis no benefit from using this crate.** (Note: There is almost no difference\nin the amount of code generated between [pin-project] and pin-project-lite.)\n\n### Different: No useful error messages\n\nThis macro does not handle any invalid input. So error messages are not to\nbe useful in most cases. If you do need useful error messages, then upon\nerror you can pass the same input to [pin-project] to receive a helpful\ndescription of the compile error.\n\n### Different: No support for custom Unpin implementation\n\npin-project supports this by [`UnsafeUnpin`][unsafe-unpin]. (`!Unpin` is supported by both [pin-project][not-unpin] and [pin-project-lite][not-unpin-lite].)\n\n### Different: No support for tuple structs and tuple variants\n\npin-project supports this.\n\n[not-unpin]: https://docs.rs/pin-project/latest/pin_project/attr.pin_project.html#unpin\n[pin-project]: https://github.com/taiki-e/pin-project\n[unsafe-unpin]: https://docs.rs/pin-project/latest/pin_project/attr.pin_project.html#unsafeunpin\n\n<!-- tidy:sync-markdown-to-rustdoc:end -->\n\n[not-unpin-lite]: https://docs.rs/pin-project-lite/latest/pin_project_lite/macro.pin_project.html#unpin\n[`pin_project!`]: https://docs.rs/pin-project-lite/latest/pin_project_lite/macro.pin_project.html\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "src/lib.rs",
      "sha256": "09a84ff233021dabb75200ef71ebcb1c5a47c94484ce294ef5dcf43797873ba4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*!\n<!-- Note: Document from sync-markdown-to-rustdoc:start through sync-markdown-to-rustdoc:end\n     is synchronized from README.md. Any changes to that range are not preserved. -->\n<!-- tidy:sync-markdown-to-rustdoc:start -->\n\nA lightweight version of [pin-project] written with declarative macros.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\npin-project-lite = \"0.2\"\n```\n\n## Examples\n\n[`pin_project!`] macro creates a projection type covering all the fields of\nstruct.\n\n```\nuse std::pin::Pin;\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    struct Struct<T, U> {\n        #[pin]\n        pinned: T,\n        unpinned: U,\n    }\n}\n\nimpl<T, U> Struct<T, U> {\n    fn method(self: Pin<&mut Self>) {\n        let this = self.project();\n        let _: Pin<&mut T> = this.pinned; // Pinned reference to the field\n        let _: &mut U = this.unpinned; // Normal reference to the field\n    }\n}\n```\n\nTo use [`pin_project!`] on enums, you need to name the projection type\nreturned from the method.\n\n```\nuse std::pin::Pin;\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project = EnumProj]\n    enum Enum<T, U> {\n        Variant { #[pin] pinned: T, unpinned: U },\n    }\n}\n\nimpl<T, U> Enum<T, U> {\n    fn method(self: Pin<&mut Self>) {\n        match self.project() {\n            EnumProj::Variant { pinned, unpinned } => {\n                let _: Pin<&mut T> = pinned;\n                let _: &mut U = unpinned;\n            }\n        }\n    }\n}\n```\n\n## [pin-project] vs pin-project-lite\n\nHere are some similarities and differences compared to [pin-project].\n\n### Similar: Safety\n\npin-project-lite guarantees safety in much the same way as [pin-project].\nBoth are completely safe unless you write other unsafe code.\n\n### Different: Minimal design\n\nThis library does not tackle as expansive of a range of use cases as\n[pin-project] does. If your use case is not already covered, please use\n[pin-project].\n\n### Different: No proc-macro related dependencies\n\nThis is the **only** reason to use this crate. However, **if you already\nhave proc-macro related dependencies in your crate's dependency graph, there\nis no benefit from using this crate.** (Note: There is almost no difference\nin the amount of code generated between [pin-project] and pin-project-lite.)\n\n### Different: No useful error messages\n\nThis macro does not handle any invalid input. So error messages are not to\nbe useful in most cases. If you do need useful error messages, then upon\nerror you can pass the same input to [pin-project] to receive a helpful\ndescription of the compile error.\n\n### Different: No support for custom Unpin implementation\n\npin-project supports this by [`UnsafeUnpin`][unsafe-unpin]. (`!Unpin` is supported by both [pin-project][not-unpin] and [pin-project-lite][not-unpin-lite].)\n\n### Different: No support for tuple structs and tuple variants\n\npin-project supports this.\n\n[not-unpin]: https://docs.rs/pin-project/latest/pin_project/attr.pin_project.html#unpin\n[pin-project]: https://github.com/taiki-e/pin-project\n[unsafe-unpin]: https://docs.rs/pin-project/latest/pin_project/attr.pin_project.html#unsafeunpin\n\n<!-- tidy:sync-markdown-to-rustdoc:end -->\n\n[not-unpin-lite]: pin_project#unpin\n*/\n\n#![no_std]\n#![doc(test(\n    no_crate_inject,\n    attr(allow(\n        dead_code,\n        unused_variables,\n        clippy::undocumented_unsafe_blocks,\n        clippy::unused_trait_names,\n    ))\n))]\n// #![warn(unsafe_op_in_unsafe_fn)] // requires Rust 1.52\n#![warn(\n    // Lints that may help when writing public library.\n    missing_debug_implementations,\n    missing_docs,\n    clippy::alloc_instead_of_core,\n    clippy::exhaustive_enums,\n    clippy::exhaustive_structs,\n    clippy::impl_trait_in_params,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    // clippy::missing_inline_in_public_items,\n)]\n\n/// A macro that creates a projection type covering all the fields of struct.\n///\n/// This macro creates a projection type according to the following rules:\n///\n/// - For the field that uses `#[pin]` attribute, makes the pinned reference to the field.\n/// - For the other fields, makes the unpinned reference to the field.\n///\n/// And the following methods are implemented on the original type:\n///\n/// ```\n/// # use std::pin::Pin;\n/// # type Projection<'a> = &'a ();\n/// # type ProjectionRef<'a> = &'a ();\n/// # trait Dox {\n/// fn project(self: Pin<&mut Self>) -> Projection<'_>;\n/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>;\n/// # }\n/// ```\n///\n/// By passing an attribute with the same name as the method to the macro,\n/// you can name the projection type returned from the method. This allows you\n/// to use pattern matching on the projected types.\n///\n/// ```\n/// # use pin_project_lite::pin_project;\n/// # use std::pin::Pin;\n/// pin_project! {\n///     #[project = EnumProj]\n///     enum Enum<T> {\n///         Variant { #[pin] field: T },\n///     }\n/// }\n///\n/// impl<T> Enum<T> {\n///     fn method(self: Pin<&mut Self>) {\n///         let this: EnumProj<'_, T> = self.project();\n///         match this {\n///             EnumProj::Variant { field } => {\n///                 let _: Pin<&mut T> = field;\n///             }\n///         }\n///     }\n/// }\n/// ```\n///\n/// By passing the `#[project_replace = MyProjReplace]` attribute you may create an additional\n/// method which allows the contents of `Pin<&mut Self>` to be replaced while simultaneously moving\n/// out all unpinned fields in `Self`.\n///\n/// ```\n/// # use std::pin::Pin;\n/// # type MyProjReplace = ();\n/// # trait Dox {\n/// fn project_replace(self: Pin<&mut Self>, replacement: Self) -> MyProjReplace;\n/// # }\n/// ```\n///\n/// Also, note that the projection types returned by `project` and `project_ref` have\n/// an additional lifetime at the beginning of generics.\n///\n/// ```text\n/// let this: EnumProj<'_, T> = self.project();\n///                    ^^\n/// ```\n///\n/// The visibility of the projected types and projection methods is based on the\n/// original type. However, if the visibility of the original type is `pub`, the\n/// visibility of the projected types and the projection methods is downgraded\n/// to `pub(crate)`.\n///\n/// # Safety\n///\n/// `pin_project!` macro guarantees safety in much the same way as [pin-project] crate.\n/// Both are completely safe unless you write other unsafe code.\n///\n/// See [pin-project] crate for more details.\n///\n/// # Examples\n///\n/// ```\n/// use std::pin::Pin;\n///\n/// use pin_project_lite::pin_project;\n///\n/// pin_project! {\n///     struct Struct<T, U> {\n///         #[pin]\n///         pinned: T,\n///         unpinned: U,\n///     }\n/// }\n///\n/// impl<T, U> Struct<T, U> {\n///     fn method(self: Pin<&mut Self>) {\n///         let this = self.project();\n///         let _: Pin<&mut T> = this.pinned; // Pinned reference to the field\n///         let _: &mut U = this.unpinned; // Normal reference to the field\n///     }\n/// }\n/// ```\n///\n/// To use `pin_project!` on enums, you need to name the projection type\n/// returned from the method.\n///\n/// ```\n/// use std::pin::Pin;\n///\n/// use pin_project_lite::pin_project;\n///\n/// pin_project! {\n///     #[project = EnumProj]\n///     enum Enum<T> {\n///         Struct {\n///             #[pin]\n///             field: T,\n///         },\n///         Unit,\n///     }\n/// }\n///\n/// impl<T> Enum<T> {\n///     fn method(self: Pin<&mut Self>) {\n///         match self.project() {\n///             EnumProj::Struct { field } => {\n///                 let _: Pin<&mut T> = field;\n///             }\n///             EnumProj::Unit => {}\n///         }\n///     }\n/// }\n/// ```\n///\n/// If you want to call the `project()` method multiple times or later use the\n/// original [`Pin`] type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid\n/// consuming the [`Pin`].\n///\n/// ```\n/// use std::pin::Pin;\n///\n/// use pin_project_lite::pin_project;\n///\n/// pin_project! {\n///     struct Struct<T> {\n///         #[pin]\n///         field: T,\n///     }\n/// }\n///\n/// impl<T> Struct<T> {\n///     fn call_project_twice(mut self: Pin<&mut Self>) {\n///         // `project` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`.\n///         self.as_mut().project();\n///         self.as_mut().project();\n///     }\n/// }\n/// ```\n///\n/// # `!Unpin`\n///\n/// If you want to make sure `Unpin` is not implemented, use the `#[project(!Unpin)]`\n/// attribute.\n///\n/// ```\n/// use pin_project_lite::pin_project;\n///\n/// pin_project! {\n///      #[project(!Unpin)]\n///      struct Struct<T> {\n///          #[pin]\n///          field: T,\n///      }\n/// }\n/// ```\n///\n/// This is equivalent to using `#[pin]` attribute for a [`PhantomPinned`] field.\n///\n/// ```\n/// use std::marker::PhantomPinned;\n///\n/// use pin_project_lite::pin_project;\n///\n/// pin_project! {\n///     struct Struct<T> {\n///         field: T,\n///         #[pin]\n///         _pin: PhantomPinned,\n///     }\n/// }\n/// ```\n///\n/// Note that using [`PhantomPinned`] without `#[pin]` or `#[project(!Unpin)]`\n/// attribute has no effect.\n///\n/// # Pinned Drop\n///\n/// In order to correctly implement pin projections, a type's [`Drop`] impl must not move out of any\n/// structurally pinned fields. Unfortunately, [`Drop::drop`] takes `&mut Self`, not `Pin<&mut Self>`.\n///\n/// To implement [`Drop`] for type that has pin, add an `impl PinnedDrop` block at the end of the\n/// [`pin_project`] macro block. PinnedDrop has the following interface:\n///\n/// ```\n/// # use std::pin::Pin;\n/// trait PinnedDrop {\n///     fn drop(this: Pin<&mut Self>);\n/// }\n/// ```\n///\n/// Note that the argument to `PinnedDrop::drop` cannot be named `self`.\n///\n/// `pin_project!` implements the actual [`Drop`] trait via PinnedDrop you implemented. To\n/// explicitly drop a type that implements PinnedDrop, use the [drop] function just like dropping a\n/// type that directly implements [`Drop`].\n///\n/// `PinnedDrop::drop` will never be called more than once, just like [`Drop::drop`].\n///\n/// ```\n/// use pin_project_lite::pin_project;\n///\n/// pin_project! {\n///     pub struct Struct<'a> {\n///         was_dropped: &'a mut bool,\n///         #[pin]\n///         field: u8,\n///     }\n///\n///     impl PinnedDrop for Struct<'_> {\n///         fn drop(this: Pin<&mut Self>) { // <----- NOTE: this is not `self`\n///             **this.project().was_dropped = true;\n///         }\n///     }\n/// }\n///\n/// let mut was_dropped = false;\n/// drop(Struct { was_dropped: &mut was_dropped, field: 42 });\n/// assert!(was_dropped);\n/// ```\n///\n/// [`PhantomPinned`]: core::marker::PhantomPinned\n/// [`Pin::as_mut`]: core::pin::Pin::as_mut\n/// [`Pin`]: core::pin::Pin\n/// [pin-project]: https://github.com/taiki-e/pin-project\n#[macro_export]\nmacro_rules! pin_project {\n    ($($tt:tt)*) => {\n        $crate::__pin_project_internal! {\n            [][][][][]\n            $($tt)*\n        }\n    };\n}\n\n// limitations:\n// - no support for tuple structs and tuple variant (wontfix).\n// - no support for multiple trait/lifetime bounds.\n// - no support for `Self` in where clauses. (wontfix)\n// - no support for overlapping lifetime names. (wontfix)\n// - no interoperability with other field attributes.\n// - no useful error messages. (wontfix)\n// etc...\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_expand {\n    (\n        [$($proj_mut_ident:ident)?]\n        [$($proj_ref_ident:ident)?]\n        [$($proj_replace_ident:ident)?]\n        [$($proj_not_unpin_mark:ident)?]\n        [$proj_vis:vis]\n        [$(#[$attrs:meta])* $vis:vis $struct_ty_ident:ident $ident:ident]\n        [$($def_generics:tt)*]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        {\n            $($body_data:tt)*\n        }\n        $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)?\n    ) => {\n        $crate::__pin_project_reconstruct! {\n            [$(#[$attrs])* $vis $struct_ty_ident $ident]\n            [$($def_generics)*] [$($impl_generics)*]\n            [$($ty_generics)*] [$(where $($where_clause)*)?]\n            {\n                $($body_data)*\n            }\n        }\n\n        $crate::__pin_project_make_proj_ty! {\n            [$($proj_mut_ident)?]\n            [$proj_vis $struct_ty_ident $ident]\n            [__pin_project_make_proj_field_mut]\n            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n            {\n                $($body_data)*\n            }\n        }\n        $crate::__pin_project_make_proj_ty! {\n            [$($proj_ref_ident)?]\n            [$proj_vis $struct_ty_ident $ident]\n            [__pin_project_make_proj_field_ref]\n            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n            {\n                $($body_data)*\n            }\n        }\n        $crate::__pin_project_make_proj_replace_ty! {\n            [$($proj_replace_ident)?]\n            [$proj_vis $struct_ty_ident]\n            [__pin_project_make_proj_field_replace]\n            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n            {\n                $($body_data)*\n            }\n        }\n\n        $crate::__pin_project_constant! {\n            [$(#[$attrs])* $vis $struct_ty_ident $ident]\n            [$($proj_mut_ident)?] [$($proj_ref_ident)?] [$($proj_replace_ident)?]\n            [$($proj_not_unpin_mark)?]\n            [$proj_vis]\n            [$($def_generics)*] [$($impl_generics)*]\n            [$($ty_generics)*] [$(where $($where_clause)*)?]\n            {\n                $($body_data)*\n            }\n            $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_constant {\n    (\n        [$(#[$attrs:meta])* $vis:vis struct $ident:ident]\n        [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?]\n        [$($proj_not_unpin_mark:ident)?]\n        [$proj_vis:vis]\n        [$($def_generics:tt)*]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        {\n            $(\n                $(#[$pin:ident])?\n                $field_vis:vis $field:ident: $field_ty:ty\n            ),+ $(,)?\n        }\n        $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)?\n    ) => {\n        #[allow(\n            explicit_outlives_requirements, // https://github.com/rust-lang/rust/issues/60993\n            single_use_lifetimes, // https://github.com/rust-lang/rust/issues/55058\n            // This lint warns of `clippy::*` generated by external macros.\n            // We allow this lint for compatibility with older compilers.\n            clippy::unknown_clippy_lints,\n            clippy::absolute_paths,\n            clippy::min_ident_chars,\n            clippy::redundant_pub_crate, // This lint warns `pub(crate)` field in private struct.\n            clippy::single_char_lifetime_names,\n            clippy::used_underscore_binding\n        )]\n        const _: () = {\n            $crate::__pin_project_make_proj_ty! {\n                [$($proj_mut_ident)? Projection]\n                [$proj_vis struct $ident]\n                [__pin_project_make_proj_field_mut]\n                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n                {\n                    $(\n                        $(#[$pin])?\n                        $field_vis $field: $field_ty\n                    ),+\n                }\n            }\n            $crate::__pin_project_make_proj_ty! {\n                [$($proj_ref_ident)? ProjectionRef]\n                [$proj_vis struct $ident]\n                [__pin_project_make_proj_field_ref]\n                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n                {\n                    $(\n                        $(#[$pin])?\n                        $field_vis $field: $field_ty\n                    ),+\n                }\n            }\n\n            impl<$($impl_generics)*> $ident <$($ty_generics)*>\n            $(where\n                $($where_clause)*)?\n            {\n                $crate::__pin_project_struct_make_proj_method! {\n                    [$($proj_mut_ident)? Projection]\n                    [$proj_vis]\n                    [project get_unchecked_mut mut]\n                    [$($ty_generics)*]\n                    {\n                        $(\n                            $(#[$pin])?\n                            $field_vis $field\n                        ),+\n                    }\n                }\n                $crate::__pin_project_struct_make_proj_method! {\n                    [$($proj_ref_ident)? ProjectionRef]\n                    [$proj_vis]\n                    [project_ref get_ref]\n                    [$($ty_generics)*]\n                    {\n                        $(\n                            $(#[$pin])?\n                            $field_vis $field\n                        ),+\n                    }\n                }\n                $crate::__pin_project_struct_make_proj_replace_method! {\n                    [$($proj_replace_ident)?]\n                    [$proj_vis]\n                    [ProjectionReplace]\n                    [$($ty_generics)*]\n                    {\n                        $(\n                            $(#[$pin])?\n                            $field_vis $field\n                        ),+\n                    }\n                }\n            }\n\n            $crate::__pin_project_make_unpin_impl! {\n                [$($proj_not_unpin_mark)?]\n                [$vis $ident]\n                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n                $(\n                    $field: $crate::__pin_project_make_unpin_bound!(\n                        $(#[$pin])? $field_ty\n                    )\n                ),+\n            }\n\n            $crate::__pin_project_make_drop_impl! {\n                [$ident]\n                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n                $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?\n            }\n\n            // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.\n            //\n            // Taking a reference to a packed field is UB, and applying\n            // `#[forbid(unaligned_references)]` makes sure that doing this is a hard error.\n            //\n            // If the struct ends up having #[repr(packed)] applied somehow,\n            // this will generate an (unfriendly) error message. Under all reasonable\n            // circumstances, we'll detect the #[repr(packed)] attribute, and generate\n            // a much nicer error above.\n            //\n            // See https://github.com/taiki-e/pin-project/pull/34 for more details.\n            //\n            // Note:\n            // - Lint-based tricks aren't perfect, but they're much better than nothing:\n            //   https://github.com/taiki-e/pin-project-lite/issues/26\n            //\n            // - Enable both unaligned_references and safe_packed_borrows lints\n            //   because unaligned_references lint does not exist in older compilers:\n            //   https://github.com/taiki-e/pin-project-lite/pull/55\n            //   https://github.com/rust-lang/rust/pull/82525\n            #[forbid(unaligned_references, safe_packed_borrows)]\n            fn __assert_not_repr_packed <$($impl_generics)*> (this: &$ident <$($ty_generics)*>)\n            $(where\n                $($where_clause)*)?\n            {\n                $(\n                    let _ = &this.$field;\n                )+\n            }\n        };\n    };\n    (\n        [$(#[$attrs:meta])* $vis:vis enum $ident:ident]\n        [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?]\n        [$($proj_not_unpin_mark:ident)?]\n        [$proj_vis:vis]\n        [$($def_generics:tt)*]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        {\n            $(\n                $(#[$variant_attrs:meta])*\n                $variant:ident $({\n                    $(\n                        $(#[$pin:ident])?\n                        $field:ident: $field_ty:ty\n                    ),+ $(,)?\n                })?\n            ),+ $(,)?\n        }\n        $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)?\n    ) => {\n        #[allow(\n            single_use_lifetimes, // https://github.com/rust-lang/rust/issues/55058\n            // This lint warns of `clippy::*` generated by external macros.\n            // We allow this lint for compatibility with older compilers.\n            clippy::unknown_clippy_lints,\n            clippy::absolute_paths,\n            clippy::min_ident_chars,\n            clippy::single_char_lifetime_names,\n            clippy::used_underscore_binding\n        )]\n        const _: () = {\n            impl<$($impl_generics)*> $ident <$($ty_generics)*>\n            $(where\n                $($where_clause)*)?\n            {\n                $crate::__pin_project_enum_make_proj_method! {\n                    [$($proj_mut_ident)?]\n                    [$proj_vis]\n                    [project get_unchecked_mut mut]\n                    [$($ty_generics)*]\n                    {\n                        $(\n                            $variant $({\n                                $(\n                                    $(#[$pin])?\n                                    $field\n                                ),+\n                            })?\n                        ),+\n                    }\n                }\n                $crate::__pin_project_enum_make_proj_method! {\n                    [$($proj_ref_ident)?]\n                    [$proj_vis]\n                    [project_ref get_ref]\n                    [$($ty_generics)*]\n                    {\n                        $(\n                            $variant $({\n                                $(\n                                    $(#[$pin])?\n                                    $field\n                                ),+\n                            })?\n                        ),+\n                    }\n                }\n                $crate::__pin_project_enum_make_proj_replace_method! {\n                    [$($proj_replace_ident)?]\n                    [$proj_vis]\n                    [$($ty_generics)*]\n                    {\n                        $(\n                            $variant $({\n                                $(\n                                    $(#[$pin])?\n                                    $field\n                                ),+\n                            })?\n                        ),+\n                    }\n                }\n            }\n\n            $crate::__pin_project_make_unpin_impl! {\n                [$($proj_not_unpin_mark)?]\n                [$vis $ident]\n                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n                $(\n                    $variant: ($(\n                        $(\n                            $crate::__pin_project_make_unpin_bound!(\n                                $(#[$pin])? $field_ty\n                            )\n                        ),+\n                    )?)\n                ),+\n            }\n\n            $crate::__pin_project_make_drop_impl! {\n                [$ident]\n                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n                $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?\n            }\n\n            // We don't need to check for '#[repr(packed)]',\n            // since it does not apply to enums.\n        };\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_reconstruct {\n    (\n        [$(#[$attrs:meta])* $vis:vis struct $ident:ident]\n        [$($def_generics:tt)*] [$($impl_generics:tt)*]\n        [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        {\n            $(\n                $(#[$pin:ident])?\n                $field_vis:vis $field:ident: $field_ty:ty\n            ),+ $(,)?\n        }\n    ) => {\n        $(#[$attrs])*\n        $vis struct $ident $($def_generics)*\n        $(where\n            $($where_clause)*)?\n        {\n            $(\n                $field_vis $field: $field_ty\n            ),+\n        }\n    };\n    (\n        [$(#[$attrs:meta])* $vis:vis enum $ident:ident]\n        [$($def_generics:tt)*] [$($impl_generics:tt)*]\n        [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        {\n            $(\n                $(#[$variant_attrs:meta])*\n                $variant:ident $({\n                    $(\n                        $(#[$pin:ident])?\n                        $field:ident: $field_ty:ty\n                    ),+ $(,)?\n                })?\n            ),+ $(,)?\n        }\n    ) => {\n        $(#[$attrs])*\n        $vis enum $ident $($def_generics)*\n        $(where\n            $($where_clause)*)?\n        {\n            $(\n                $(#[$variant_attrs])*\n                $variant $({\n                    $(\n                        $field: $field_ty\n                    ),+\n                })?\n            ),+\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_proj_ty {\n    ([] $($field:tt)*) => {};\n    (\n        [$proj_ty_ident:ident $default_ident:ident]\n        [$proj_vis:vis struct $ident:ident]\n        $($field:tt)*\n    ) => {};\n    (\n        [$proj_ty_ident:ident]\n        [$proj_vis:vis struct $ident:ident]\n        [$__pin_project_make_proj_field:ident]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        {\n            $(\n                $(#[$pin:ident])?\n                $field_vis:vis $field:ident: $field_ty:ty\n            ),+ $(,)?\n        }\n    ) => {\n        $crate::__pin_project_make_proj_ty_body! {\n            [$proj_ty_ident]\n            [$proj_vis struct $ident]\n            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n            [\n                $(\n                    $field_vis $field: $crate::$__pin_project_make_proj_field!(\n                        $(#[$pin])? $field_ty\n                    )\n                ),+\n            ]\n        }\n    };\n    (\n        [$proj_ty_ident:ident]\n        [$proj_vis:vis enum $ident:ident]\n        [$__pin_project_make_proj_field:ident]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        {\n            $(\n                $(#[$variant_attrs:meta])*\n                $variant:ident $({\n                    $(\n                        $(#[$pin:ident])?\n                        $field:ident: $field_ty:ty\n                    ),+ $(,)?\n                })?\n            ),+ $(,)?\n        }\n    ) => {\n        $crate::__pin_project_make_proj_ty_body! {\n            [$proj_ty_ident]\n            [$proj_vis enum $ident]\n            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n            [\n                $(\n                    $variant $({\n                        $(\n                            $field: $crate::$__pin_project_make_proj_field!(\n                                $(#[$pin])? $field_ty\n                            )\n                        ),+\n                    })?\n                ),+\n            ]\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_proj_ty_body {\n    (\n        [$proj_ty_ident:ident]\n        [$proj_vis:vis $struct_ty_ident:ident $ident:ident]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        [$($body_data:tt)+]\n    ) => {\n        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.\n        #[allow(\n            dead_code, // This lint warns unused fields/variants.\n            single_use_lifetimes, // https://github.com/rust-lang/rust/issues/55058\n            // This lint warns of `clippy::*` generated by external macros.\n            // We allow this lint for compatibility with older compilers.\n            clippy::unknown_clippy_lints,\n            clippy::absolute_paths,\n            clippy::min_ident_chars,\n            clippy::mut_mut, // This lint warns `&mut &mut <ty>`. (only needed for project)\n            clippy::redundant_pub_crate, // This lint warns `pub(crate)` field in private struct.\n            clippy::ref_option_ref, // This lint warns `&Option<&<ty>>`. (only needed for project_ref)\n            clippy::single_char_lifetime_names,\n            clippy::type_repetition_in_bounds // https://github.com/rust-lang/rust-clippy/issues/4326\n        )]\n        $proj_vis $struct_ty_ident $proj_ty_ident <'__pin, $($impl_generics)*>\n        where\n            $ident <$($ty_generics)*>: '__pin\n            $(, $($where_clause)*)?\n        {\n            $($body_data)+\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_proj_replace_ty {\n    ([] $($field:tt)*) => {};\n    (\n        [$proj_ty_ident:ident]\n        [$proj_vis:vis struct]\n        [$__pin_project_make_proj_field:ident]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        {\n            $(\n                $(#[$pin:ident])?\n                $field_vis:vis $field:ident: $field_ty:ty\n            ),+ $(,)?\n        }\n    ) => {\n        $crate::__pin_project_make_proj_replace_ty_body! {\n            [$proj_ty_ident]\n            [$proj_vis struct]\n            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n            [\n                $(\n                    $field_vis $field: $crate::$__pin_project_make_proj_field!(\n                        $(#[$pin])? $field_ty\n                    )\n                ),+\n            ]\n        }\n    };\n    (\n        [$proj_ty_ident:ident]\n        [$proj_vis:vis enum]\n        [$__pin_project_make_proj_field:ident]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        {\n            $(\n                $(#[$variant_attrs:meta])*\n                $variant:ident $({\n                    $(\n                        $(#[$pin:ident])?\n                        $field:ident: $field_ty:ty\n                    ),+ $(,)?\n                })?\n            ),+ $(,)?\n        }\n    ) => {\n        $crate::__pin_project_make_proj_replace_ty_body! {\n            [$proj_ty_ident]\n            [$proj_vis enum]\n            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]\n            [\n                $(\n                    $variant $({\n                        $(\n                            $field: $crate::$__pin_project_make_proj_field!(\n                                $(#[$pin])? $field_ty\n                            )\n                        ),+\n                    })?\n                ),+\n            ]\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_proj_replace_ty_body {\n    (\n        [$proj_ty_ident:ident]\n        [$proj_vis:vis $struct_ty_ident:ident]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        [$($body_data:tt)+]\n    ) => {\n        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.\n        #[allow(\n            dead_code, // This lint warns unused fields/variants.\n            single_use_lifetimes, // https://github.com/rust-lang/rust/issues/55058\n            // This lint warns of `clippy::*` generated by external macros.\n            // We allow this lint for compatibility with older compilers.\n            clippy::unknown_clippy_lints,\n            clippy::absolute_paths,\n            clippy::min_ident_chars,\n            clippy::mut_mut, // This lint warns `&mut &mut <ty>`. (only needed for project)\n            clippy::redundant_pub_crate, // This lint warns `pub(crate)` field in private struct.\n            clippy::single_char_lifetime_names,\n            clippy::type_repetition_in_bounds // https://github.com/rust-lang/rust-clippy/issues/4326\n        )]\n        $proj_vis $struct_ty_ident $proj_ty_ident <$($impl_generics)*>\n        where\n            $($($where_clause)*)?\n        {\n            $($body_data)+\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_proj_replace_block {\n    (\n        [$($proj_path:tt)+]\n        {\n            $(\n                $(#[$pin:ident])?\n                $field_vis:vis $field:ident\n            ),+\n        }\n    ) => {\n        let result = $($proj_path)* {\n            $(\n                $field: $crate::__pin_project_make_replace_field_proj!(\n                    $(#[$pin])? $field\n                )\n            ),+\n        };\n\n        {\n            ( $(\n                $crate::__pin_project_make_unsafe_drop_in_place_guard!(\n                    $(#[$pin])? $field\n                ),\n            )* );\n        }\n\n        result\n    };\n    ([$($proj_path:tt)+]) => { $($proj_path)* };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_struct_make_proj_method {\n    ([] $($variant:tt)*) => {};\n    (\n        [$proj_ty_ident:ident $_ignored_default_arg:ident]\n        [$proj_vis:vis]\n        [$method_ident:ident $get_method:ident $($mut:ident)?]\n        [$($ty_generics:tt)*]\n        $($variant:tt)*\n    ) => {\n        $crate::__pin_project_struct_make_proj_method! {\n            [$proj_ty_ident]\n            [$proj_vis]\n            [$method_ident $get_method $($mut)?]\n            [$($ty_generics)*]\n            $($variant)*\n        }\n    };\n    (\n        [$proj_ty_ident:ident]\n        [$proj_vis:vis]\n        [$method_ident:ident $get_method:ident $($mut:ident)?]\n        [$($ty_generics:tt)*]\n        {\n            $(\n                $(#[$pin:ident])?\n                $field_vis:vis $field:ident\n            ),+\n        }\n    ) => {\n        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.\n        #[inline]\n        $proj_vis fn $method_ident<'__pin>(\n            self: $crate::__private::Pin<&'__pin $($mut)? Self>,\n        ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {\n            unsafe {\n                let Self { $($field),* } = self.$get_method();\n                $proj_ty_ident {\n                    $(\n                        $field: $crate::__pin_project_make_unsafe_field_proj!(\n                            $(#[$pin])? $field\n                        )\n                    ),+\n                }\n            }\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_struct_make_proj_replace_method {\n    ([] $($field:tt)*) => {};\n    (\n        [$proj_ty_ident:ident]\n        [$proj_vis:vis]\n        [$_proj_ty_ident:ident]\n        [$($ty_generics:tt)*]\n        {\n            $(\n                $(#[$pin:ident])?\n                $field_vis:vis $field:ident\n            ),+\n        }\n    ) => {\n        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.\n        #[inline]\n        $proj_vis fn project_replace(\n            self: $crate::__private::Pin<&mut Self>,\n            replacement: Self,\n        ) -> $proj_ty_ident <$($ty_generics)*> {\n            unsafe {\n                let __self_ptr: *mut Self = self.get_unchecked_mut();\n\n                // Destructors will run in reverse order, so next create a guard to overwrite\n                // `self` with the replacement value without calling destructors.\n                let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);\n\n                let Self { $($field),* } = &mut *__self_ptr;\n\n                $crate::__pin_project_make_proj_replace_block! {\n                    [$proj_ty_ident]\n                    {\n                        $(\n                            $(#[$pin])?\n                            $field\n                        ),+\n                    }\n                }\n            }\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_enum_make_proj_method {\n    ([] $($variant:tt)*) => {};\n    (\n        [$proj_ty_ident:ident]\n        [$proj_vis:vis]\n        [$method_ident:ident $get_method:ident $($mut:ident)?]\n        [$($ty_generics:tt)*]\n        {\n            $(\n                $variant:ident $({\n                    $(\n                        $(#[$pin:ident])?\n                        $field:ident\n                    ),+\n                })?\n            ),+\n        }\n    ) => {\n        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.\n        #[inline]\n        $proj_vis fn $method_ident<'__pin>(\n            self: $crate::__private::Pin<&'__pin $($mut)? Self>,\n        ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {\n            unsafe {\n                match self.$get_method() {\n                    $(\n                        Self::$variant $({\n                            $($field),+\n                        })? => {\n                            $proj_ty_ident::$variant $({\n                                $(\n                                    $field: $crate::__pin_project_make_unsafe_field_proj!(\n                                        $(#[$pin])? $field\n                                    )\n                                ),+\n                            })?\n                        }\n                    ),+\n                }\n            }\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_enum_make_proj_replace_method {\n    ([] $($field:tt)*) => {};\n    (\n        [$proj_ty_ident:ident]\n        [$proj_vis:vis]\n        [$($ty_generics:tt)*]\n        {\n            $(\n                $variant:ident $({\n                    $(\n                        $(#[$pin:ident])?\n                        $field:ident\n                    ),+\n                })?\n            ),+\n        }\n    ) => {\n        #[doc(hidden)] // Workaround for rustc bug: see https://github.com/taiki-e/pin-project-lite/issues/77#issuecomment-1671540180 for more.\n        #[inline]\n        $proj_vis fn project_replace(\n            self: $crate::__private::Pin<&mut Self>,\n            replacement: Self,\n        ) -> $proj_ty_ident <$($ty_generics)*> {\n            unsafe {\n                let __self_ptr: *mut Self = self.get_unchecked_mut();\n\n                // Destructors will run in reverse order, so next create a guard to overwrite\n                // `self` with the replacement value without calling destructors.\n                let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);\n\n                match &mut *__self_ptr {\n                    $(\n                        Self::$variant $({\n                            $($field),+\n                        })? => {\n                            $crate::__pin_project_make_proj_replace_block! {\n                                [$proj_ty_ident :: $variant]\n                                $({\n                                    $(\n                                        $(#[$pin])?\n                                        $field\n                                    ),+\n                                })?\n                            }\n                        }\n                    ),+\n                }\n            }\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_unpin_impl {\n    (\n        []\n        [$vis:vis $ident:ident]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        $($field:tt)*\n    ) => {\n        // Automatically create the appropriate conditional `Unpin` implementation.\n        //\n        // Basically this is equivalent to the following code:\n        // ```\n        // impl<T, U> Unpin for Struct<T, U> where T: Unpin {}\n        // ```\n        //\n        // However, if struct is public and there is a private type field,\n        // this would cause an E0446 (private type in public interface).\n        //\n        // When RFC 2145 is implemented (rust-lang/rust#48054),\n        // this will become a lint, rather than a hard error.\n        //\n        // As a workaround for this, we generate a new struct, containing all of the pinned\n        // fields from our #[pin_project] type. This struct is declared within\n        // a function, which makes it impossible to be named by user code.\n        // This guarantees that it will use the default auto-trait impl for Unpin -\n        // that is, it will implement Unpin iff all of its fields implement Unpin.\n        // This type can be safely declared as 'public', satisfying the privacy\n        // checker without actually allowing user code to access it.\n        //\n        // This allows users to apply the #[pin_project] attribute to types\n        // regardless of the privacy of the types of their fields.\n        //\n        // See also https://github.com/taiki-e/pin-project/pull/53.\n        #[allow(non_snake_case)]\n        $vis struct __Origin<'__pin, $($impl_generics)*>\n        $(where\n            $($where_clause)*)?\n        {\n            __dummy_lifetime: $crate::__private::PhantomData<&'__pin ()>,\n            $($field)*\n        }\n        impl<'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*>\n        where\n            $crate::__private::PinnedFieldsOf<__Origin<'__pin, $($ty_generics)*>>:\n                $crate::__private::Unpin\n            $(, $($where_clause)*)?\n        {\n        }\n    };\n    (\n        [$proj_not_unpin_mark:ident]\n        [$vis:vis $ident:ident]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n        $($field:tt)*\n    ) => {\n        // TODO: Using `<unsized type>: Sized` here allow emulating real negative_impls...\n        // https://github.com/taiki-e/pin-project/issues/340#issuecomment-2428002670\n        #[doc(hidden)]\n        impl<'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*>\n        where\n            (\n                $crate::__private::PhantomData<&'__pin ()>,\n                $crate::__private::PhantomPinned,\n            ): $crate::__private::Unpin\n            $(, $($where_clause)*)?\n        {\n        }\n    }\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_drop_impl {\n    (\n        [$_ident:ident]\n        [$($_impl_generics:tt)*] [$($_ty_generics:tt)*] [$(where $($_where_clause:tt)*)?]\n        $(#[$drop_impl_attrs:meta])*\n        impl $(<\n            $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?\n            $( $generics:ident\n                $(: $generics_bound:path)?\n                $(: ?$generics_unsized_bound:path)?\n                $(: $generics_lifetime_bound:lifetime)?\n            ),*\n        >)? PinnedDrop for $self_ty:ty\n        $(where\n            $( $where_clause_ty:ty\n                $(: $where_clause_bound:path)?\n                $(: ?$where_clause_unsized_bound:path)?\n                $(: $where_clause_lifetime_bound:lifetime)?\n            ),* $(,)?\n        )?\n        {\n            $(#[$drop_fn_attrs:meta])*\n            fn drop($($arg:ident)+: Pin<&mut Self>) {\n                $($tt:tt)*\n            }\n        }\n    ) => {\n        $(#[$drop_impl_attrs])*\n        impl $(<\n            $( $lifetime $(: $lifetime_bound)? ,)*\n            $( $generics\n                $(: $generics_bound)?\n                $(: ?$generics_unsized_bound)?\n                $(: $generics_lifetime_bound)?\n            ),*\n        >)? $crate::__private::Drop for $self_ty\n        $(where\n            $( $where_clause_ty\n                $(: $where_clause_bound)?\n                $(: ?$where_clause_unsized_bound)?\n                $(: $where_clause_lifetime_bound)?\n            ),*\n        )?\n        {\n            $(#[$drop_fn_attrs])*\n            fn drop(&mut self) {\n                // Implementing `__DropInner::__drop_inner` is safe, but calling it is not safe.\n                // This is because destructors can be called multiple times in safe code and\n                // [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360).\n                //\n                // `__drop_inner` is defined as a safe method, but this is fine since\n                // `__drop_inner` is not accessible by the users and we call `__drop_inner` only\n                // once.\n                //\n                // Users can implement [`Drop`] safely using `pin_project!` and can drop a\n                // type that implements `PinnedDrop` using the [`drop`] function safely.\n                fn __drop_inner $(<\n                    $( $lifetime $(: $lifetime_bound)? ,)*\n                    $( $generics\n                        $(: $generics_bound)?\n                        $(: ?$generics_unsized_bound)?\n                        $(: $generics_lifetime_bound)?\n                    ),*\n                >)? (\n                    $($arg)+: $crate::__private::Pin<&mut $self_ty>,\n                )\n                $(where\n                    $( $where_clause_ty\n                        $(: $where_clause_bound)?\n                        $(: ?$where_clause_unsized_bound)?\n                        $(: $where_clause_lifetime_bound)?\n                    ),*\n                )?\n                {\n                    // A dummy `__drop_inner` function to prevent users call outer `__drop_inner`.\n                    fn __drop_inner() {}\n                    $($tt)*\n                }\n\n                // Safety - we're in 'drop', so we know that 'self' will\n                // never move again.\n                let pinned_self: $crate::__private::Pin<&mut Self>\n                    = unsafe { $crate::__private::Pin::new_unchecked(self) };\n                // We call `__drop_inner` only once. Since `__DropInner::__drop_inner`\n                // is not accessible by the users, it is never called again.\n                __drop_inner(pinned_self);\n            }\n        }\n    };\n    (\n        [$ident:ident]\n        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]\n    ) => {\n        // Ensure that struct does not implement `Drop`.\n        //\n        // There are two possible cases:\n        // 1. The user type does not implement Drop. In this case,\n        // the first blanket impl will not apply to it. This code\n        // will compile, as there is only one impl of MustNotImplDrop for the user type\n        // 2. The user type does impl Drop. This will make the blanket impl applicable,\n        // which will then conflict with the explicit MustNotImplDrop impl below.\n        // This will result in a compilation error, which is exactly what we want.\n        trait MustNotImplDrop {}\n        #[allow(clippy::drop_bounds, drop_bounds)]\n        impl<T: $crate::__private::Drop> MustNotImplDrop for T {}\n        impl<$($impl_generics)*> MustNotImplDrop for $ident <$($ty_generics)*>\n        $(where\n            $($where_clause)*)?\n        {\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_unpin_bound {\n    (#[pin] $field_ty:ty) => {\n        $field_ty\n    };\n    ($field_ty:ty) => {\n        $crate::__private::AlwaysUnpin<$field_ty>\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_unsafe_field_proj {\n    (#[pin] $field:ident) => {\n        $crate::__private::Pin::new_unchecked($field)\n    };\n    ($field:ident) => {\n        $field\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_replace_field_proj {\n    (#[pin] $field:ident) => {\n        $crate::__private::PhantomData\n    };\n    ($field:ident) => {\n        $crate::__private::ptr::read($field)\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_unsafe_drop_in_place_guard {\n    (#[pin] $field:ident) => {\n        $crate::__private::UnsafeDropInPlaceGuard::new($field)\n    };\n    ($field:ident) => {\n        ()\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_proj_field_mut {\n    (#[pin] $field_ty:ty) => {\n        $crate::__private::Pin<&'__pin mut ($field_ty)>\n    };\n    ($field_ty:ty) => {\n        &'__pin mut ($field_ty)\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_proj_field_ref {\n    (#[pin] $field_ty:ty) => {\n        $crate::__private::Pin<&'__pin ($field_ty)>\n    };\n    ($field_ty:ty) => {\n        &'__pin ($field_ty)\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_make_proj_field_replace {\n    (#[pin] $field_ty:ty) => {\n        $crate::__private::PhantomData<$field_ty>\n    };\n    ($field_ty:ty) => {\n        $field_ty\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_internal {\n    // parsing proj_mut_ident\n    (\n        []\n        [$($proj_ref_ident:ident)?]\n        [$($proj_replace_ident:ident)?]\n        [$( ! $proj_not_unpin_mark:ident)?]\n        [$($attrs:tt)*]\n\n        #[project = $proj_mut_ident:ident]\n        $($tt:tt)*\n    ) => {\n        $crate::__pin_project_internal! {\n            [$proj_mut_ident]\n            [$($proj_ref_ident)?]\n            [$($proj_replace_ident)?]\n            [$( ! $proj_not_unpin_mark)?]\n            [$($attrs)*]\n            $($tt)*\n        }\n    };\n    // parsing proj_ref_ident\n    (\n        [$($proj_mut_ident:ident)?]\n        []\n        [$($proj_replace_ident:ident)?]\n        [$( ! $proj_not_unpin_mark:ident)?]\n        [$($attrs:tt)*]\n\n        #[project_ref = $proj_ref_ident:ident]\n        $($tt:tt)*\n    ) => {\n        $crate::__pin_project_internal! {\n            [$($proj_mut_ident)?]\n            [$proj_ref_ident]\n            [$($proj_replace_ident)?]\n            [$( ! $proj_not_unpin_mark)?]\n            [$($attrs)*]\n            $($tt)*\n        }\n    };\n    // parsing proj_replace_ident\n    (\n        [$($proj_mut_ident:ident)?]\n        [$($proj_ref_ident:ident)?]\n        []\n        [$( ! $proj_not_unpin_mark:ident)?]\n        [$($attrs:tt)*]\n\n        #[project_replace = $proj_replace_ident:ident]\n        $($tt:tt)*\n    ) => {\n        $crate::__pin_project_internal! {\n            [$($proj_mut_ident)?]\n            [$($proj_ref_ident)?]\n            [$proj_replace_ident]\n            [$( ! $proj_not_unpin_mark)?]\n            [$($attrs)*]\n            $($tt)*\n        }\n    };\n    // parsing !Unpin\n    (\n        [$($proj_mut_ident:ident)?]\n        [$($proj_ref_ident:ident)?]\n        [$($proj_replace_ident:ident)?]\n        []\n        [$($attrs:tt)*]\n\n        #[project( ! $proj_not_unpin_mark:ident)]\n        $($tt:tt)*\n    ) => {\n        $crate::__pin_project_internal! {\n            [$($proj_mut_ident)?]\n            [$($proj_ref_ident)?]\n            [$($proj_replace_ident)?]\n            [ ! $proj_not_unpin_mark]\n            [$($attrs)*]\n            $($tt)*\n        }\n    };\n    // this is actually part of a recursive step that picks off a single non-`pin_project_lite` attribute\n    // there could be more to parse\n    (\n        [$($proj_mut_ident:ident)?]\n        [$($proj_ref_ident:ident)?]\n        [$($proj_replace_ident:ident)?]\n        [$( ! $proj_not_unpin_mark:ident)?]\n        [$($attrs:tt)*]\n\n        #[$($attr:tt)*]\n        $($tt:tt)*\n    ) => {\n        $crate::__pin_project_internal! {\n            [$($proj_mut_ident)?]\n            [$($proj_ref_ident)?]\n            [$($proj_replace_ident)?]\n            [$( ! $proj_not_unpin_mark)?]\n            [$($attrs)* #[$($attr)*]]\n            $($tt)*\n        }\n    };\n    // now determine visibility\n    // if public, downgrade\n    (\n        [$($proj_mut_ident:ident)?]\n        [$($proj_ref_ident:ident)?]\n        [$($proj_replace_ident:ident)?]\n        [$( ! $proj_not_unpin_mark:ident)?]\n        [$($attrs:tt)*]\n        pub $struct_ty_ident:ident $ident:ident\n        $($tt:tt)*\n    ) => {\n        $crate::__pin_project_parse_generics! {\n            [$($proj_mut_ident)?]\n            [$($proj_ref_ident)?]\n            [$($proj_replace_ident)?]\n            [$($proj_not_unpin_mark)?]\n            [$($attrs)*]\n            [pub $struct_ty_ident $ident pub(crate)]\n            $($tt)*\n        }\n    };\n    (\n        [$($proj_mut_ident:ident)?]\n        [$($proj_ref_ident:ident)?]\n        [$($proj_replace_ident:ident)?]\n        [$( ! $proj_not_unpin_mark:ident)?]\n        [$($attrs:tt)*]\n        $vis:vis $struct_ty_ident:ident $ident:ident\n        $($tt:tt)*\n    ) => {\n        $crate::__pin_project_parse_generics! {\n            [$($proj_mut_ident)?]\n            [$($proj_ref_ident)?]\n            [$($proj_replace_ident)?]\n            [$($proj_not_unpin_mark)?]\n            [$($attrs)*]\n            [$vis $struct_ty_ident $ident $vis]\n            $($tt)*\n        }\n    };\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __pin_project_parse_generics {\n    (\n        [$($proj_mut_ident:ident)?]\n        [$($proj_ref_ident:ident)?]\n        [$($proj_replace_ident:ident)?]\n        [$($proj_not_unpin_mark:ident)?]\n        [$($attrs:tt)*]\n        [$vis:vis $struct_ty_ident:ident $ident:ident $proj_vis:vis]\n        $(<\n            $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?\n            $( $generics:ident\n                $(: $generics_bound:path)?\n                $(: ?$generics_unsized_bound:path)?\n                $(: $generics_lifetime_bound:lifetime)?\n                $(= $generics_default:ty)?\n            ),* $(,)?\n        >)?\n        $(where\n            $( $where_clause_ty:ty\n                $(: $where_clause_bound:path)?\n                $(: ?$where_clause_unsized_bound:path)?\n                $(: $where_clause_lifetime_bound:lifetime)?\n            ),* $(,)?\n        )?\n        {\n            $($body_data:tt)*\n        }\n        $($(#[$drop_impl_attrs:meta])* impl $($pinned_drop:tt)*)?\n    ) => {\n        $crate::__pin_project_expand! {\n            [$($proj_mut_ident)?]\n            [$($proj_ref_ident)?]\n            [$($proj_replace_ident)?]\n            [$($proj_not_unpin_mark)?]\n            [$proj_vis]\n            [$($attrs)* $vis $struct_ty_ident $ident]\n            [$(<\n                $( $lifetime $(: $lifetime_bound)? ,)*\n                $( $generics\n                    $(: $generics_bound)?\n                    $(: ?$generics_unsized_bound)?\n                    $(: $generics_lifetime_bound)?\n                    $(= $generics_default)?\n                ),*\n            >)?]\n            [$(\n                $( $lifetime $(: $lifetime_bound)? ,)*\n                $( $generics\n                    $(: $generics_bound)?\n                    $(: ?$generics_unsized_bound)?\n                    $(: $generics_lifetime_bound)?\n                ),*\n            )?]\n            [$( $( $lifetime ,)* $( $generics ),* )?]\n            [$(where $( $where_clause_ty\n                $(: $where_clause_bound)?\n                $(: ?$where_clause_unsized_bound)?\n                $(: $where_clause_lifetime_bound)?\n            ),* )?]\n            {\n                $($body_data)*\n            }\n            $($(#[$drop_impl_attrs])* impl $($pinned_drop)*)?\n        }\n    };\n}\n\n// Not public API.\n#[doc(hidden)]\n#[allow(missing_debug_implementations)]\npub mod __private {\n    use core::mem::ManuallyDrop;\n    #[doc(hidden)]\n    pub use core::{\n        marker::{PhantomData, PhantomPinned, Unpin},\n        ops::Drop,\n        pin::Pin,\n        ptr,\n    };\n\n    // Workaround for issue on unstable negative_impls feature that allows unsound overlapping Unpin\n    // implementations and rustc bug that leaks unstable negative_impls into stable.\n    // See https://github.com/taiki-e/pin-project/issues/340#issuecomment-2432146009 for details.\n    #[doc(hidden)]\n    pub type PinnedFieldsOf<T> =\n        <PinnedFieldsOfHelperStruct<T> as PinnedFieldsOfHelperTrait>::Actual;\n    // We cannot use <Option<T> as IntoIterator>::Item or similar since we should allow ?Sized in T.\n    #[doc(hidden)]\n    pub trait PinnedFieldsOfHelperTrait {\n        type Actual: ?Sized;\n    }\n    #[doc(hidden)]\n    pub struct PinnedFieldsOfHelperStruct<T: ?Sized>(T);\n    impl<T: ?Sized> PinnedFieldsOfHelperTrait for PinnedFieldsOfHelperStruct<T> {\n        type Actual = T;\n    }\n\n    // This is an internal helper struct used by `pin_project!`.\n    #[doc(hidden)]\n    pub struct AlwaysUnpin<T: ?Sized>(PhantomData<T>);\n    impl<T: ?Sized> Unpin for AlwaysUnpin<T> {}\n\n    // This is an internal helper used to ensure a value is dropped.\n    #[doc(hidden)]\n    pub struct UnsafeDropInPlaceGuard<T: ?Sized>(*mut T);\n    impl<T: ?Sized> UnsafeDropInPlaceGuard<T> {\n        #[doc(hidden)]\n        pub unsafe fn new(ptr: *mut T) -> Self {\n            Self(ptr)\n        }\n    }\n    impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {\n        fn drop(&mut self) {\n            // SAFETY: the caller of `UnsafeDropInPlaceGuard::new` must guarantee\n            // that `ptr` is valid for drop when this guard is destructed.\n            unsafe {\n                ptr::drop_in_place(self.0);\n            }\n        }\n    }\n\n    // This is an internal helper used to ensure a value is overwritten without\n    // its destructor being called.\n    #[doc(hidden)]\n    pub struct UnsafeOverwriteGuard<T> {\n        target: *mut T,\n        value: ManuallyDrop<T>,\n    }\n    impl<T> UnsafeOverwriteGuard<T> {\n        #[doc(hidden)]\n        pub unsafe fn new(target: *mut T, value: T) -> Self {\n            Self { target, value: ManuallyDrop::new(value) }\n        }\n    }\n    impl<T> Drop for UnsafeOverwriteGuard<T> {\n        fn drop(&mut self) {\n            // SAFETY: the caller of `UnsafeOverwriteGuard::new` must guarantee\n            // that `target` is valid for writes when this guard is destructed.\n            unsafe {\n                ptr::write(self.target, ptr::read(&*self.value));\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/auxiliary/mod.rs",
      "sha256": "52a78b77be05c67737c56865fbce4477eaacc6482d6377af2a5822f05a2ce061",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![allow(dead_code, unused_macros)]\n\nmacro_rules! assert_unpin {\n    ($ty:ty) => {\n        static_assertions::assert_impl_all!($ty: Unpin);\n    };\n}\nmacro_rules! assert_not_unpin {\n    ($ty:ty) => {\n        static_assertions::assert_not_impl_all!($ty: Unpin);\n    };\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/compiletest.rs",
      "sha256": "48cfd92c7271345d57a6c222a7a61e00449f38e6ba379130813c45b31a5589c9",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![cfg(not(miri))]\n\n#[rustversion::attr(not(nightly), ignore)]\n#[test]\nfn ui() {\n    let t = trybuild::TestCases::new();\n    t.compile_fail(\"tests/ui/**/*.rs\");\n    t.pass(\"tests/run-pass/**/*.rs\");\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/drop_order.rs",
      "sha256": "9b13b6461e44be1c1beca6ec47387de83efcb988326e4ff832183b8fad17a3f4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// Refs: https://doc.rust-lang.org/reference/destructors.html\n\nuse std::{cell::Cell, panic, pin::Pin, thread};\n\nuse pin_project_lite::pin_project;\n\nstruct D<'a>(&'a Cell<usize>, usize);\n\nimpl Drop for D<'_> {\n    fn drop(&mut self) {\n        if !thread::panicking() {\n            let old = self.0.replace(self.1);\n            assert_eq!(old, self.1 - 1);\n        }\n    }\n}\n\npin_project! {\n#[project = StructPinnedProj]\n#[project_ref = StructPinnedProjRef]\n#[project_replace = StructPinnedProjReplace]\nstruct StructPinned<'a> {\n    #[pin]\n    f1: D<'a>,\n    #[pin]\n    f2: D<'a>,\n}\n}\n\npin_project! {\n#[project = StructUnpinnedProj]\n#[project_ref = StructUnpinnedProjRef]\n#[project_replace = StructUnpinnedProjReplace]\nstruct StructUnpinned<'a> {\n    f1: D<'a>,\n    f2: D<'a>,\n}\n}\n\npin_project! {\n#[project_replace = EnumProjReplace]\nenum Enum<'a> {\n    #[allow(dead_code)] // false positive that fixed in Rust 1.38\n    StructPinned {\n        #[pin]\n        f1: D<'a>,\n        #[pin]\n        f2: D<'a>,\n    },\n    #[allow(dead_code)] // false positive that fixed in Rust 1.38\n    StructUnpinned {\n        f1: D<'a>,\n        f2: D<'a>,\n    },\n}\n}\n\n#[test]\nfn struct_pinned() {\n    {\n        let c = Cell::new(0);\n        let _x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };\n    }\n    {\n        let c = Cell::new(0);\n        let mut x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };\n        let y = Pin::new(&mut x);\n        let _z = y.project_replace(StructPinned { f1: D(&c, 3), f2: D(&c, 4) });\n    }\n}\n\n#[test]\nfn struct_unpinned() {\n    {\n        let c = Cell::new(0);\n        let _x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };\n    }\n    {\n        let c = Cell::new(0);\n        let mut x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };\n        let y = Pin::new(&mut x);\n        let _z = y.project_replace(StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });\n    }\n}\n\n#[test]\nfn enum_struct() {\n    {\n        let c = Cell::new(0);\n        let _x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };\n    }\n    {\n        let c = Cell::new(0);\n        let mut x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };\n        let y = Pin::new(&mut x);\n        let _z = y.project_replace(Enum::StructPinned { f1: D(&c, 3), f2: D(&c, 4) });\n    }\n\n    {\n        let c = Cell::new(0);\n        let _x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };\n    }\n    {\n        let c = Cell::new(0);\n        let mut x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };\n        let y = Pin::new(&mut x);\n        let _z = y.project_replace(Enum::StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });\n    }\n}\n\n// https://github.com/rust-lang/rust/issues/47949\n// https://github.com/taiki-e/pin-project/pull/194#discussion_r419098111\n#[allow(clippy::many_single_char_names)]\n#[test]\nfn project_replace_panic() {\n    pin_project! {\n    #[project_replace = SProjReplace]\n    struct S<T, U> {\n        #[pin]\n        pinned: T,\n        unpinned: U,\n    }\n    }\n\n    struct D<'a>(&'a mut bool, bool);\n    impl Drop for D<'_> {\n        fn drop(&mut self) {\n            *self.0 = true;\n            if self.1 {\n                panic!();\n            }\n        }\n    }\n\n    let (mut a, mut b, mut c, mut d) = (false, false, false, false);\n    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {\n        let mut x = S { pinned: D(&mut a, true), unpinned: D(&mut b, false) };\n        let _y = Pin::new(&mut x)\n            .project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });\n        // Previous `x.pinned` was dropped and panicked when `project_replace` is\n        // called, so this is unreachable.\n        unreachable!();\n    }));\n    assert!(res.is_err());\n    assert!(a);\n    assert!(b);\n    assert!(c);\n    assert!(d);\n\n    let (mut a, mut b, mut c, mut d) = (false, false, false, false);\n    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {\n        let mut x = S { pinned: D(&mut a, false), unpinned: D(&mut b, true) };\n        {\n            let _y = Pin::new(&mut x)\n                .project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });\n            // `_y` (previous `x.unpinned`) live to the end of this scope, so\n            // this is not unreachable.\n            // unreachable!();\n        }\n        unreachable!();\n    }));\n    assert!(res.is_err());\n    assert!(a);\n    assert!(b);\n    assert!(c);\n    assert!(d);\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/default/enum.rs",
      "sha256": "ebe6b6403e35459420f6fe979243c382972d2d582376d69f6c630ab5ba2599b5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project = EnumProj]\n    #[project_ref = EnumProjRef]\n    #[project_replace = EnumProjReplace]\n    enum Enum<T, U> {\n        Struct {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        },\n        Unit,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/default/struct.rs",
      "sha256": "05767cd68ec5cddc481cff5ad677b5146f7d6fd1effcf1ff131d24c334d85032",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    struct Struct<T, U> {\n        #[pin]\n        pinned: T,\n        unpinned: U,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/multifields/enum.rs",
      "sha256": "d38eb301c86307edbf5cb07ed434b64a10a68aaef32dfb8b15029b5cc5586b0b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n#[project_replace = EnumProjReplace]\nenum Enum<T, U> {\n    Struct {\n        #[pin]\n        pinned1: T,\n        #[pin]\n        pinned2: T,\n        unpinned1: U,\n        unpinned2: U,\n    },\n    Unit,\n}\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/multifields/struct.rs",
      "sha256": "1fe2b911e8782eaac5952d9e0914473d46d82db45b1da859bdc6b8dc3978e549",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n#[project_replace = StructProjReplace]\nstruct Struct<T, U> {\n    #[pin]\n    pinned1: T,\n    #[pin]\n    pinned2: T,\n    unpinned1: U,\n    unpinned2: U,\n}\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/naming/enum-all.rs",
      "sha256": "ebe6b6403e35459420f6fe979243c382972d2d582376d69f6c630ab5ba2599b5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project = EnumProj]\n    #[project_ref = EnumProjRef]\n    #[project_replace = EnumProjReplace]\n    enum Enum<T, U> {\n        Struct {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        },\n        Unit,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/naming/enum-mut.rs",
      "sha256": "bf215d055b29a7f9fdb84cabf34576d9dec8e87c33cebe2b553d1fe5e5cb0882",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project = EnumProj]\n    enum Enum<T, U> {\n        Struct {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        },\n        Unit,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/naming/enum-none.rs",
      "sha256": "115968816e1a1a6b3634b8594dde4815d4641d817d69ebdd90879b96a8a2808e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    enum Enum<T, U> {\n        Struct {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        },\n        Unit,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/naming/enum-ref.rs",
      "sha256": "e09ce2ca812b9fcf7dc59b486e5b50b84db08860a2ceda63ba094d7351bb391f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project_ref = EnumProjRef]\n    enum Enum<T, U> {\n        Struct {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        },\n        Unit,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/naming/struct-all.rs",
      "sha256": "0d6b64bc687fbc19329a5558461329e3d2cfa367ff8adb7be76efe2d3160d33e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project = StructProj]\n    #[project_ref = StructProjRef]\n    #[project_replace = StructProjReplace]\n    struct Struct<T, U> {\n        #[pin]\n        pinned: T,\n        unpinned: U,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/naming/struct-mut.rs",
      "sha256": "36edd8db816c122c80ccb139b4305cad8edfdf9b7ee4aebacafa1180613a5075",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project = StructProj]\n    struct Struct<T, U> {\n        #[pin]\n        pinned: T,\n        unpinned: U,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/naming/struct-none.rs",
      "sha256": "05767cd68ec5cddc481cff5ad677b5146f7d6fd1effcf1ff131d24c334d85032",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    struct Struct<T, U> {\n        #[pin]\n        pinned: T,\n        unpinned: U,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/naming/struct-ref.rs",
      "sha256": "dd249875f962d16dd9ec821acf0c2b5c1ed0ed05569f6e874ccd5caca2759acf",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project_ref = StructProjRef]\n    struct Struct<T, U> {\n        #[pin]\n        pinned: T,\n        unpinned: U,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/not_unpin/enum.rs",
      "sha256": "c65aac4d2083e83d2dfc3bec8ce243e3e9169ef5f986f077f0a8b4226d39f7c3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project(!Unpin)]\n    #[project = EnumProj]\n    #[project_ref = EnumProjRef]\n    enum Enum<T, U> {\n        Struct {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        },\n        Unit,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/not_unpin/struct.rs",
      "sha256": "99d77727393e4a050d2ceb99710172dfdd13dfcb6e6416f63de39e5df3a9f03f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project = StructProj]\n    #[project(!Unpin)]\n    #[project_ref = StructProjRef]\n    struct Struct<T, U> {\n        #[pin]\n        pinned: T,\n        unpinned: U,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/pinned_drop/enum.rs",
      "sha256": "8f590791cb4693bb077c562f0d93128f9452e6a5f60c631b5fd624a221883ebd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project = EnumProj]\n    #[project_ref = EnumProjRef]\n    enum Enum<T, U> {\n        Struct {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        },\n        Unit,\n    }\n    impl<T, U> PinnedDrop for Enum<T, U> {\n        fn drop(this: Pin<&mut Self>) {\n            let _ = this;\n        }\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/pinned_drop/struct.rs",
      "sha256": "8da271d7d3182b33be297d985a1e3b57d6067406db21eca8ac2c448ef1a0869a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    struct Struct<T, U> {\n        #[pin]\n        pinned: T,\n        unpinned: U,\n    }\n    impl<T, U> PinnedDrop for Struct<T, U> {\n        fn drop(this: Pin<&mut Self>) {\n            let _ = this;\n        }\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/pub/enum.rs",
      "sha256": "fdbd806e92cfad4e67737d1f782544aa4e3116bae702161c43b5c22bfbf3a208",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project = EnumProj]\n    #[project_ref = EnumProjRef]\n    pub enum Enum<T, U> {\n        Struct {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        },\n        Unit,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expand/pub/struct.rs",
      "sha256": "05cb3f03ef9801fecf0a7c86bbd236c97218b34ac01ee507cb7de9a78efaeffa",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    pub struct Struct<T, U> {\n        #[pin]\n        pub pinned: T,\n        pub unpinned: U,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/expandtest.rs",
      "sha256": "a4336ab879d79824ab3144ea385a7a00ba77604c3b6639ae53b6283850b421df",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![cfg(not(miri))]\n\n#[rustversion::attr(not(nightly), ignore)]\n#[test]\nfn expandtest() {\n    let args = &[\"--all-features\"];\n    macrotest::expand_args(\"tests/expand/**/*.rs\", args);\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/include/basic.rs",
      "sha256": "8c06c765c92d696284dde5b4762488100ce0ee1661ead307023a85d5c82d8ddc",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// default pin_project! is completely safe.\n\n::pin_project_lite::pin_project! {\n    /// Testing default struct.\n    #[derive(Debug)]\n    #[allow(clippy::exhaustive_structs)] // for the type itself\n    pub struct DefaultStruct<T, U> {\n        #[pin]\n        pub pinned: T,\n        pub unpinned: U,\n    }\n}\n\n::pin_project_lite::pin_project! {\n    /// Testing named struct.\n    #[allow(clippy::exhaustive_structs)] // for the type itself\n    #[project = DefaultStructProj]\n    #[project_ref = DefaultStructProjRef]\n    #[derive(Debug)]\n    pub struct DefaultStructNamed<T, U> {\n        #[pin]\n        pub pinned: T,\n        pub unpinned: U,\n    }\n}\n\n::pin_project_lite::pin_project! {\n    /// Testing enum.\n    #[allow(clippy::exhaustive_enums)] // for the type itself\n    #[project = DefaultEnumProj]\n    #[project_ref = DefaultEnumProjRef]\n    #[derive(Debug)]\n    pub enum DefaultEnum<T, U> {\n        /// Struct variant.\n        Struct {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        },\n        /// Unit variant.\n        Unit,\n    }\n}\n\n::pin_project_lite::pin_project! {\n    /// Testing pinned drop struct.\n    #[allow(clippy::exhaustive_structs)] // for the type itself\n    #[derive(Debug)]\n    pub struct PinnedDropStruct<T, U> {\n        #[pin]\n        pub pinned: T,\n        pub unpinned: U,\n    }\n    impl<T, U> PinnedDrop for PinnedDropStruct<T, U> {\n        fn drop(_this: Pin<&mut Self>) {}\n    }\n}\n\n::pin_project_lite::pin_project! {\n    /// Testing pinned drop enum.\n    #[allow(clippy::absolute_paths, clippy::exhaustive_enums)] // for the type itself\n    #[project = PinnedDropEnumProj]\n    #[project_ref = PinnedDropEnumProjRef]\n    #[derive(Debug)]\n    pub enum PinnedDropEnum<T: ::pin_project_lite::__private::Unpin, U> {\n        /// Struct variant.\n        Struct {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        },\n        /// Unit variant.\n        Unit,\n    }\n    #[allow(clippy::absolute_paths)]\n    impl<T: ::pin_project_lite::__private::Unpin, U> PinnedDrop for PinnedDropEnum<T, U> {\n        fn drop(_this: Pin<&mut Self>) {}\n    }\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/proper_unpin.rs",
      "sha256": "83790eb38ae2fd5aed97fc67da79d91c1071f08d1e5aaef0c71e65d8b5767403",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![allow(dead_code)]\n\n#[macro_use]\nmod auxiliary;\n\npub mod default {\n    use std::marker::PhantomPinned;\n\n    use pin_project_lite::pin_project;\n\n    struct Inner<T> {\n        f: T,\n    }\n\n    assert_unpin!(Inner<()>);\n    assert_not_unpin!(Inner<PhantomPinned>);\n\n    pin_project! {\n        struct Struct<T, U> {\n            #[pin]\n            f1: Inner<T>,\n            f2: U,\n        }\n    }\n\n    assert_unpin!(Struct<(), ()>);\n    assert_unpin!(Struct<(), PhantomPinned>);\n    assert_not_unpin!(Struct<PhantomPinned, ()>);\n    assert_not_unpin!(Struct<PhantomPinned, PhantomPinned>);\n\n    pin_project! {\n        #[project = EnumProj]\n        #[project_ref = EnumProjRef]\n        enum Enum<T, U> {\n            V1 {\n                #[pin]\n                f1: Inner<T>,\n                f2: U,\n            },\n        }\n    }\n\n    assert_unpin!(Enum<(), ()>);\n    assert_unpin!(Enum<(), PhantomPinned>);\n    assert_not_unpin!(Enum<PhantomPinned, ()>);\n    assert_not_unpin!(Enum<PhantomPinned, PhantomPinned>);\n\n    pin_project! {\n        #[project(!Unpin)]\n        enum NotUnpinEnum<T, U> {\n            V1 {\n                #[pin] f1: Inner<T>,\n                f2: U,\n            }\n        }\n    }\n\n    assert_not_unpin!(NotUnpinEnum<(), ()>);\n\n    pin_project! {\n        struct TrivialBounds {\n            #[pin]\n            f: PhantomPinned,\n        }\n    }\n\n    assert_not_unpin!(TrivialBounds);\n\n    pin_project! {\n        struct PinRef<'a, T, U> {\n            #[pin]\n            f1: &'a mut Inner<T>,\n            f2: U,\n        }\n    }\n\n    assert_unpin!(PinRef<'_, PhantomPinned, PhantomPinned>);\n\n    pin_project! {\n        #[project(!Unpin)]\n        struct NotUnpin<U> {\n            #[pin]\n            u: U\n        }\n    }\n\n    assert_not_unpin!(NotUnpin<()>);\n\n    pin_project! {\n        #[project(!Unpin)]\n        struct NotUnpinRef<'a, T, U> {\n            #[pin]\n            f1: &'a mut Inner<T>,\n            f2: U\n        }\n    }\n\n    assert_not_unpin!(NotUnpinRef<'_, (), ()>);\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/test.rs",
      "sha256": "3bfff987a820770bd0126656a77871d5609f21c9c3b6825bd1606561aa37b572",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![allow(dead_code, unreachable_pub, clippy::no_effect_underscore_binding)]\n\n#[macro_use]\nmod auxiliary;\n\nuse std::{\n    marker::{PhantomData, PhantomPinned},\n    pin::Pin,\n};\n\nuse pin_project_lite::pin_project;\n\n#[test]\nfn projection() {\n    pin_project! {\n        #[project = StructProj]\n        #[project_ref = StructProjRef]\n        #[project_replace = StructProjReplace]\n        #[derive(Default)]\n        struct Struct<T, U> {\n            #[pin]\n            f1: T,\n            f2: U,\n        }\n    }\n\n    let mut s = Struct { f1: 1, f2: 2 };\n    let mut s_orig = Pin::new(&mut s);\n    let s = s_orig.as_mut().project();\n\n    let _: Pin<&mut i32> = s.f1;\n    assert_eq!(*s.f1, 1);\n    let _: &mut i32 = s.f2;\n    assert_eq!(*s.f2, 2);\n\n    assert_eq!(s_orig.as_ref().f1, 1);\n    assert_eq!(s_orig.as_ref().f2, 2);\n\n    let mut s = Struct { f1: 1, f2: 2 };\n    let mut s = Pin::new(&mut s);\n    {\n        let StructProj { f1, f2 } = s.as_mut().project();\n        let _: Pin<&mut i32> = f1;\n        let _: &mut i32 = f2;\n    }\n    {\n        let StructProjRef { f1, f2 } = s.as_ref().project_ref();\n        let _: Pin<&i32> = f1;\n        let _: &i32 = f2;\n    }\n\n    {\n        let StructProjReplace { f1: PhantomData, f2 } =\n            s.as_mut().project_replace(Struct::default());\n        assert_eq!(f2, 2);\n        let StructProj { f1, f2 } = s.project();\n        assert_eq!(*f1, 0);\n        assert_eq!(*f2, 0);\n    }\n\n    pin_project! {\n        #[project = EnumProj]\n        #[project_ref = EnumProjRef]\n        #[project_replace = EnumProjReplace]\n        #[derive(Eq, PartialEq, Debug)]\n        enum Enum<C, D> {\n            Struct {\n                #[pin]\n                f1: C,\n                f2: D,\n            },\n            Unit,\n        }\n    }\n\n    let mut e = Enum::Struct { f1: 1, f2: 2 };\n    let mut e = Pin::new(&mut e);\n\n    match e.as_mut().project() {\n        EnumProj::Struct { f1, f2 } => {\n            let _: Pin<&mut i32> = f1;\n            assert_eq!(*f1, 1);\n            let _: &mut i32 = f2;\n            assert_eq!(*f2, 2);\n        }\n        EnumProj::Unit => unreachable!(),\n    }\n\n    assert_eq!(&*e, &Enum::Struct { f1: 1, f2: 2 });\n\n    if let EnumProj::Struct { f1, f2 } = e.as_mut().project() {\n        let _: Pin<&mut i32> = f1;\n        assert_eq!(*f1, 1);\n        let _: &mut i32 = f2;\n        assert_eq!(*f2, 2);\n    }\n\n    if let EnumProjReplace::Struct { f1: PhantomData, f2 } = e.as_mut().project_replace(Enum::Unit)\n    {\n        assert_eq!(f2, 2);\n    }\n}\n\n#[test]\nfn enum_project_set() {\n    pin_project! {\n        #[project = EnumProj]\n        #[project_ref = EnumProjRef]\n        #[derive(Eq, PartialEq, Debug)]\n        enum Enum {\n            V1 { #[pin] f: u8 },\n            V2 { f: bool },\n        }\n    }\n\n    let mut e = Enum::V1 { f: 25 };\n    let mut e_orig = Pin::new(&mut e);\n    let e_proj = e_orig.as_mut().project();\n\n    match e_proj {\n        EnumProj::V1 { f } => {\n            let new_e = Enum::V2 { f: f.as_ref().get_ref() == &25 };\n            e_orig.set(new_e);\n        }\n        EnumProj::V2 { .. } => unreachable!(),\n    }\n\n    assert_eq!(e, Enum::V2 { f: true });\n}\n\n#[test]\nfn where_clause() {\n    pin_project! {\n        struct Struct<T>\n        where\n            T: Copy,\n        {\n            f: T,\n        }\n    }\n\n    pin_project! {\n        #[project = EnumProj]\n        #[project_ref = EnumProjRef]\n        enum Enum<T>\n        where\n            T: Copy,\n        {\n            V { f: T },\n        }\n    }\n}\n\n#[test]\nfn where_clause_and_associated_type_field() {\n    pin_project! {\n        struct Struct1<I>\n        where\n            I: Iterator,\n        {\n            #[pin]\n            f1: I,\n            f2: I::Item,\n        }\n    }\n\n    pin_project! {\n        struct Struct2<I, J>\n        where\n            I: Iterator<Item = J>,\n        {\n            #[pin]\n            f1: I,\n            f2: J,\n        }\n    }\n\n    pin_project! {\n        pub struct Struct3<T>\n        where\n            T: 'static,\n        {\n            f: T,\n        }\n    }\n\n    trait Static: 'static {}\n\n    impl<T> Static for Struct3<T> {}\n\n    pin_project! {\n        #[project = EnumProj]\n        #[project_ref = EnumProjRef]\n        enum Enum<I>\n        where\n            I: Iterator,\n        {\n            V1 { #[pin] f: I },\n            V2 { f: I::Item },\n        }\n    }\n}\n\n#[test]\nfn derive_copy() {\n    pin_project! {\n        #[derive(Clone, Copy)]\n        struct Struct<T> {\n            f: T,\n        }\n    }\n\n    fn is_copy<T: Copy>() {}\n\n    is_copy::<Struct<u8>>();\n}\n\n#[test]\nfn move_out() {\n    struct NotCopy;\n\n    pin_project! {\n        struct Struct {\n            f: NotCopy,\n        }\n    }\n\n    let x = Struct { f: NotCopy };\n    let _val: NotCopy = x.f;\n\n    pin_project! {\n        #[project = EnumProj]\n        #[project_ref = EnumProjRef]\n        enum Enum {\n            V { f: NotCopy },\n        }\n    }\n\n    let x = Enum::V { f: NotCopy };\n    #[allow(clippy::infallible_destructuring_match)]\n    let _val: NotCopy = match x {\n        Enum::V { f } => f,\n    };\n}\n\n#[test]\nfn trait_bounds_on_type_generics() {\n    pin_project! {\n        pub struct Struct1<'a, T: ?Sized> {\n            f: &'a mut T,\n        }\n    }\n\n    pin_project! {\n        pub struct Struct2<'a, T: ::core::fmt::Debug> {\n            f: &'a mut T,\n        }\n    }\n\n    pin_project! {\n        pub struct Struct3<'a, T: core::fmt::Debug> {\n            f: &'a mut T,\n        }\n    }\n\n    // pin_project! {\n    //     pub struct Struct4<'a, T: core::fmt::Debug + core::fmt::Display> {\n    //         f: &'a mut T,\n    //     }\n    // }\n\n    // pin_project! {\n    //     pub struct Struct5<'a, T: core::fmt::Debug + ?Sized> {\n    //         f: &'a mut T,\n    //     }\n    // }\n\n    pin_project! {\n        pub struct Struct6<'a, T: core::fmt::Debug = [u8; 16]> {\n            f: &'a mut T,\n        }\n    }\n\n    let _: Struct6<'_> = Struct6 { f: &mut [0_u8; 16] };\n\n    pin_project! {\n        pub struct Struct7<T: 'static> {\n            f: T,\n        }\n    }\n\n    trait Static: 'static {}\n\n    impl<T> Static for Struct7<T> {}\n\n    pin_project! {\n        pub struct Struct8<'a, 'b: 'a> {\n            f1: &'a u8,\n            f2: &'b u8,\n        }\n    }\n\n    pin_project! {\n        #[project = EnumProj]\n        #[project_ref = EnumProjRef]\n        enum Enum<'a, T: ?Sized> {\n            V { f: &'a mut T },\n        }\n    }\n}\n\n#[test]\nfn private_type_in_public_type() {\n    pin_project! {\n        pub struct PublicStruct<T> {\n            #[pin]\n            inner: PrivateStruct<T>,\n        }\n    }\n\n    struct PrivateStruct<T>(T);\n}\n\n#[allow(clippy::needless_lifetimes)]\n#[test]\nfn lifetime_project() {\n    pin_project! {\n        struct Struct1<T, U> {\n            #[pin]\n            pinned: T,\n            unpinned: U,\n        }\n    }\n\n    pin_project! {\n        struct Struct2<'a, T, U> {\n            #[pin]\n            pinned: &'a T,\n            unpinned: U,\n        }\n    }\n\n    pin_project! {\n        #[project = EnumProj]\n        #[project_ref = EnumProjRef]\n        enum Enum<T, U> {\n            V {\n                #[pin]\n                pinned: T,\n                unpinned: U,\n            },\n        }\n    }\n\n    impl<T, U> Struct1<T, U> {\n        fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a T> {\n            self.project_ref().pinned\n        }\n        fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut T> {\n            self.project().pinned\n        }\n        fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&T> {\n            self.project_ref().pinned\n        }\n        fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut T> {\n            self.project().pinned\n        }\n    }\n\n    impl<'b, T, U> Struct2<'b, T, U> {\n        fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a &'b T> {\n            self.project_ref().pinned\n        }\n        fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut &'b T> {\n            self.project().pinned\n        }\n        fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&&'b T> {\n            self.project_ref().pinned\n        }\n        fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut &'b T> {\n            self.project().pinned\n        }\n    }\n\n    impl<T, U> Enum<T, U> {\n        fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a T> {\n            match self.project_ref() {\n                EnumProjRef::V { pinned, .. } => pinned,\n            }\n        }\n        fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut T> {\n            match self.project() {\n                EnumProj::V { pinned, .. } => pinned,\n            }\n        }\n        fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&T> {\n            match self.project_ref() {\n                EnumProjRef::V { pinned, .. } => pinned,\n            }\n        }\n        fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut T> {\n            match self.project() {\n                EnumProj::V { pinned, .. } => pinned,\n            }\n        }\n    }\n}\n\nmod visibility {\n    use pin_project_lite::pin_project;\n\n    pin_project! {\n        pub(crate) struct S {\n            pub f: u8,\n        }\n    }\n}\n\n#[test]\nfn visibility() {\n    let mut x = visibility::S { f: 0 };\n    let x = Pin::new(&mut x);\n    let y = x.as_ref().project_ref();\n    let _: &u8 = y.f;\n    let y = x.project();\n    let _: &mut u8 = y.f;\n}\n\n#[test]\nfn trivial_bounds() {\n    pin_project! {\n        pub struct NoGenerics {\n            #[pin]\n            f: PhantomPinned,\n        }\n    }\n\n    assert_not_unpin!(NoGenerics);\n}\n\n#[test]\nfn dst() {\n    pin_project! {\n        pub struct Struct1<T: ?Sized> {\n            f: T,\n        }\n    }\n\n    let mut x = Struct1 { f: 0_u8 };\n    let x: Pin<&mut Struct1<dyn core::fmt::Debug>> = Pin::new(&mut x);\n    let _: &mut dyn core::fmt::Debug = x.project().f;\n\n    pin_project! {\n        pub struct Struct2<T: ?Sized> {\n            #[pin]\n            f: T,\n        }\n    }\n\n    let mut x = Struct2 { f: 0_u8 };\n    let x: Pin<&mut Struct2<dyn core::fmt::Debug + Unpin>> = Pin::new(&mut x);\n    let _: Pin<&mut (dyn core::fmt::Debug + Unpin)> = x.project().f;\n\n    pin_project! {\n        struct Struct3<T>\n        where\n            T: ?Sized,\n        {\n            f: T,\n        }\n    }\n\n    pin_project! {\n        struct Struct4<T>\n        where\n            T: ?Sized,\n        {\n            #[pin]\n            f: T,\n        }\n    }\n\n    pin_project! {\n        struct Struct11<'a, T: ?Sized, U: ?Sized> {\n            f1: &'a mut T,\n            f2: U,\n        }\n    }\n}\n\n#[test]\nfn dyn_type() {\n    pin_project! {\n        struct Struct1 {\n            f: dyn core::fmt::Debug,\n        }\n    }\n\n    pin_project! {\n        struct Struct2 {\n            #[pin]\n            f: dyn core::fmt::Debug,\n        }\n    }\n\n    pin_project! {\n        struct Struct3 {\n            f: dyn core::fmt::Debug + Send,\n        }\n    }\n\n    pin_project! {\n        struct Struct4 {\n            #[pin]\n            f: dyn core::fmt::Debug + Send,\n        }\n    }\n}\n\n#[test]\nfn no_infer_outlives() {\n    trait Trait<X> {\n        type Y;\n    }\n\n    struct Struct1<A>(A);\n\n    impl<X, T> Trait<X> for Struct1<T> {\n        type Y = Option<T>;\n    }\n\n    pin_project! {\n        struct Struct2<A, B> {\n            _f: <Struct1<A> as Trait<B>>::Y,\n        }\n    }\n}\n\n// https://github.com/taiki-e/pin-project-lite/issues/31\n#[test]\nfn trailing_comma() {\n    pub trait T {}\n\n    pin_project! {\n        pub struct S1<\n            A: T,\n            B: T,\n        > {\n            f: (A, B),\n        }\n    }\n\n    pin_project! {\n        pub struct S2<\n            A,\n            B,\n        >\n        where\n            A: T,\n            B: T,\n        {\n            f: (A, B),\n        }\n    }\n\n    pin_project! {\n        #[allow(explicit_outlives_requirements)]\n        pub struct S3<\n            'a,\n            A: 'a,\n            B: 'a,\n        > {\n            f: &'a (A, B),\n        }\n    }\n\n    // pin_project! {\n    //     pub struct S4<\n    //         'a,\n    //         'b: 'a, // <-----\n    //     > {\n    //         f: &'a &'b (),\n    //     }\n    // }\n}\n\n#[test]\nfn attrs() {\n    pin_project! {\n        /// dox1\n        #[derive(Clone)]\n        #[project = StructProj]\n        #[project_ref = StructProjRef]\n        /// dox2\n        #[derive(Debug)]\n        /// dox3\n        struct Struct {\n            // TODO\n            // /// dox4\n            f: ()\n        }\n    }\n\n    pin_project! {\n        #[project = Enum1Proj]\n        #[project_ref = Enum1ProjRef]\n        enum Enum1 {\n            #[cfg(not(any()))]\n            V {\n                f: ()\n            },\n        }\n    }\n\n    pin_project! {\n        /// dox1\n        #[derive(Clone)]\n        #[project(!Unpin)]\n        #[project = Enum2Proj]\n        #[project_ref = Enum2ProjRef]\n        /// dox2\n        #[derive(Debug)]\n        /// dox3\n        enum Enum2 {\n            /// dox4\n            V1 {\n                // TODO\n                // /// dox5\n                f: ()\n            },\n            /// dox6\n            V2,\n        }\n    }\n}\n\n#[test]\nfn pinned_drop() {\n    pin_project! {\n        pub struct Struct1<'a> {\n            was_dropped: &'a mut bool,\n            #[pin]\n            field: u8,\n        }\n        impl PinnedDrop for Struct1<'_> {\n            fn drop(this: Pin<&mut Self>) {\n                **this.project().was_dropped = true;\n            }\n        }\n    }\n\n    let mut was_dropped = false;\n    drop(Struct1 { was_dropped: &mut was_dropped, field: 42 });\n    assert!(was_dropped);\n\n    pin_project! {\n        pub struct Struct2<'a> {\n            was_dropped: &'a mut bool,\n            #[pin]\n            field: u8,\n        }\n        impl PinnedDrop for Struct2<'_> {\n            fn drop(mut this: Pin<&mut Self>) {\n                **this.as_mut().project().was_dropped = true;\n            }\n        }\n    }\n\n    trait Service<Request> {\n        type Error;\n    }\n\n    pin_project! {\n        struct Struct3<'a, T, Request>\n        where\n            T: Service<Request>,\n            T::Error: std::error::Error,\n        {\n            was_dropped: &'a mut bool,\n            #[pin]\n            field: T,\n            req: Request,\n        }\n\n        /// dox1\n        impl<T, Request> PinnedDrop for Struct3<'_, T, Request>\n        where\n            T: Service<Request>,\n            T::Error: std::error::Error,\n        {\n            /// dox2\n            fn drop(mut this: Pin<&mut Self>) {\n                **this.as_mut().project().was_dropped = true;\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/not_unpin/conflict-unpin.rs",
      "sha256": "23c7e081d86f2000838c32844dce1eee98d1b118eb1a29daf65c705aad5c68fb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    #[project(!Unpin)]\n    struct Foo<T, U> {\n        #[pin]\n        f1: T,\n        f2: U,\n    }\n}\n\nimpl<T, U> Unpin for Foo<T, U> where T: Unpin {}\n\npin_project! {\n    #[project(!Unpin)]\n    struct Bar<T, U> {\n        #[pin]\n        f1: T,\n        f2: U,\n    }\n}\n\nimpl<T, U> Unpin for Bar<T, U> {}\n\npin_project! {\n    #[project(!Unpin)]\n    struct Baz<T, U> {\n        #[pin]\n        f1: T,\n        f2: U,\n    }\n}\n\nimpl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/not_unpin/negative_impls_stable.rs",
      "sha256": "f014d5398d505ca5f482905cb9597a2d5fced563b9350229468c3751dd7f92ae",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// https://github.com/taiki-e/pin-project/issues/340#issuecomment-2428002670\n\npin_project_lite::pin_project! {\n    #[project(!Unpin)]\n    struct Foo<Pinned, Unpinned> {\n        #[pin]\n        pinned: Pinned,\n        unpinned: Unpinned,\n    }\n}\n\nstruct MyPhantomPinned(::core::marker::PhantomPinned);\nimpl Unpin for MyPhantomPinned where for<'cursed> str: Sized {}\nimpl Unpin for Foo<MyPhantomPinned, ()> {}\n\nfn is_unpin<T: Unpin>() {}\n\nfn main() {\n    is_unpin::<Foo<MyPhantomPinned, ()>>()\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pin_project/conflict-drop.rs",
      "sha256": "a1964fa136080cc354479ff55b8428e5fa79305681fb2475cc37d6071cd64112",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! { //~ ERROR E0119\n    struct Foo<T, U> {\n        #[pin]\n        future: T,\n        field: U,\n    }\n}\n\nimpl<T, U> Drop for Foo<T, U> {\n    fn drop(&mut self) {}\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pin_project/conflict-unpin.rs",
      "sha256": "37e7b2f9ab1be70d0521c9dbbc954067f22a2321511e008f0f72e13d0edb4afe",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\n// The same implementation.\n\npin_project! { //~ ERROR E0119\n    struct Foo<T, U> {\n        #[pin]\n        future: T,\n        field: U,\n    }\n}\n\n// conflicting implementations\nimpl<T, U> Unpin for Foo<T, U> where T: Unpin {} // Conditional Unpin impl\n\n// The implementation that under different conditions.\n\npin_project! { //~ ERROR E0119\n    struct Bar<T, U> {\n        #[pin]\n        future: T,\n        field: U,\n    }\n}\n\n// conflicting implementations\nimpl<T, U> Unpin for Bar<T, U> {} // Non-conditional Unpin impl\n\npin_project! { //~ ERROR E0119\n    struct Baz<T, U> {\n        #[pin]\n        future: T,\n        field: U,\n    }\n}\n\n// conflicting implementations\nimpl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {} // Conditional Unpin impl\n\npin_project! { //~ ERROR E0119\n    #[project(!Unpin)]\n    struct Qux<T, U> {\n        #[pin]\n        future: T,\n        field: U,\n    }\n}\n\n// conflicting implementations\nimpl<T, U> Unpin for Qux<T, U> {} // Non-conditional Unpin impl\n\npin_project! { //~ ERROR E0119\n    #[project(!Unpin)]\n    struct Fred<T, U> {\n        #[pin]\n        future: T,\n        field: U,\n    }\n}\n\n// conflicting implementations\nimpl<T: Unpin, U: Unpin> Unpin for Fred<T, U> {} // Conditional Unpin impl\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pin_project/invalid-bounds.rs",
      "sha256": "4068e272a4f5d44851e0901dd6cfa806ead000c2e1a507a2b42be51d26d17056",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    struct Generics1<T: 'static : Sized> { //~ ERROR no rules expected the token `:`\n        field: T,\n    }\n}\n\npin_project! {\n    struct Generics2<T: 'static : ?Sized> { //~ ERROR no rules expected the token `:`\n        field: T,\n    }\n}\n\npin_project! {\n    struct Generics3<T: Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`\n        field: T,\n    }\n}\n\npin_project! {\n    struct Generics4<T: ?Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`\n        field: T,\n    }\n}\n\npin_project! {\n    struct Generics5<T: Sized : ?Sized> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`\n        field: T,\n    }\n}\n\npin_project! {\n    struct Generics6<T: ?Sized : Sized> { //~ ERROR no rules expected the token `Sized`\n        field: T,\n    }\n}\n\npin_project! {\n    struct WhereClause1<T>\n    where\n        T: 'static : Sized //~ ERROR no rules expected the token `:`\n    {\n        field: T,\n    }\n}\n\npin_project! {\n    struct WhereClause2<T>\n    where\n        T: 'static : ?Sized //~ ERROR no rules expected the token `:`\n    {\n        field: T,\n    }\n}\n\npin_project! {\n    struct WhereClause3<T>\n    where\n        T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`\n    {\n        field: T,\n    }\n}\n\npin_project! {\n    struct WhereClause4<T>\n    where\n        T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`\n    {\n        field: T,\n    }\n}\n\npin_project! {\n    struct WhereClause5<T>\n    where\n        T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:`\n    {\n        field: T,\n    }\n}\n\npin_project! {\n    struct WhereClause6<T>\n    where\n        T: ?Sized : Sized //~ ERROR no rules expected the token `Sized`\n    {\n        field: T,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pin_project/invalid.rs",
      "sha256": "1c84cc089623dd31f483011ed6543f169af341b028a212fcf00146bc96dd792f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    struct A<T> {\n        #[pin()] //~ ERROR no rules expected the token `(`\n        pinned: T,\n    }\n}\n\npin_project! {\n    #[pin] //~ ERROR cannot find attribute `pin` in this scope\n    struct B<T> {\n        pinned: T,\n    }\n}\n\npin_project! {\n    struct C<T> {\n        #[pin]\n        #[pin] //~ ERROR no rules expected the token `#`\n        pinned: T,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pin_project/negative_impls_stable.rs",
      "sha256": "1e70055fbec4bc0a53454fd93a0663f8785440d37dcf359ab29958d97fd51e9d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// https://github.com/taiki-e/pin-project/issues/340#issuecomment-2428002670\n\npin_project_lite::pin_project! {\n    struct Foo<Pinned, Unpinned> {\n        #[pin]\n        pinned: Pinned,\n        unpinned: Unpinned,\n    }\n}\n\nstruct MyPhantomPinned(::core::marker::PhantomPinned);\nimpl Unpin for MyPhantomPinned where for<'cursed> str: Sized {}\nimpl Unpin for Foo<MyPhantomPinned, ()> {}\n\nfn is_unpin<T: Unpin>() {}\n\nfn main() {\n    is_unpin::<Foo<MyPhantomPinned, ()>>()\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pin_project/overlapping_lifetime_names.rs",
      "sha256": "ac9c29b389e8e067e9e384cf04be69c0e5bb862cf373de0e3b4296fe2007809b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! { //~ ERROR E0263,E0496\n    pub struct Foo<'__pin, T> {\n        #[pin]\n        field: &'__pin mut T,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pin_project/overlapping_unpin_struct.rs",
      "sha256": "cb3d6d4087b8b4c917bc71e55764775f6bb018a77cda5c6b726afacd66789859",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::marker::PhantomPinned;\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    struct Foo<T> {\n        #[pin]\n        inner: T,\n    }\n}\n\nstruct __Origin {}\n\nimpl Unpin for __Origin {}\n\nfn is_unpin<T: Unpin>() {}\n\nfn main() {\n    is_unpin::<Foo<PhantomPinned>>(); //~ ERROR E0277\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pin_project/packed.rs",
      "sha256": "6a24ac14e61e5d3e3b495f49d226318ec500e5aa46f34acf8e4f3e0827bd9604",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! { //~ ERROR reference to packed field is unaligned\n    #[repr(packed, C)]\n    struct Packed {\n        #[pin]\n        field: u16,\n    }\n}\n\npin_project! { //~ ERROR reference to packed field is unaligned\n    #[repr(packed(2))]\n    struct PackedN {\n        #[pin]\n        field: u32,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pin_project/unpin_sneaky.rs",
      "sha256": "6e6385e067679c3bf5233163b3fa99ff2fc28bcb93fe594a5c987c0db7c0eaa6",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    struct Foo {\n        #[pin]\n        inner: u8,\n    }\n}\n\nimpl Unpin for __Origin {} //~ ERROR E0412,E0321\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pin_project/unsupported.rs",
      "sha256": "3ad5f584f9e56be3573133fba026a7bb378595d0a4b7b1bcbb6b78e37cef20a7",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    struct Struct1 {} //~ ERROR no rules expected the token `}`\n}\n\npin_project! {\n    struct Struct2(); //~ ERROR no rules expected the token `(`\n}\n\npin_project! {\n    struct Struct3; //~ ERROR no rules expected the token `;`\n}\n\npin_project! {\n    enum Enum { //~ ERROR no rules expected the token `enum`\n        A(u8)\n    }\n}\n\npin_project! {\n    union Union { //~ ERROR no rules expected the token `union`\n        x: u8,\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pinned_drop/call-drop-inner.rs",
      "sha256": "0618b60a450c99b5953b302e26c68df1abe7632af3d9baf3639eb60091e4ff4e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\npin_project! {\n    pub struct S {\n        #[pin]\n        field: u8,\n    }\n    impl PinnedDrop for S {\n        fn drop(this: Pin<&mut Self>) {\n            __drop_inner(this);\n        }\n    }\n}\n\nfn main() {\n    let _x = S { field: 0 };\n}\n"
    },
    {
      "package": "pin-project-lite@0.2.17",
      "sourcePath": "tests/ui/pinned_drop/conditional-drop-impl.rs",
      "sha256": "df03f38b2a331f339af2734fdd4ad2f637b2e2189d9928599adebe04ebee517f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse pin_project_lite::pin_project;\n\n// In `Drop` impl, the implementor must specify the same requirement as type definition.\n\nstruct DropImpl<T> {\n    f: T,\n}\n\nimpl<T: Unpin> Drop for DropImpl<T> {\n    //~^ ERROR E0367\n    fn drop(&mut self) {}\n}\n\npin_project! {\n    //~^ ERROR E0367\n    struct PinnedDropImpl<T> {\n        #[pin]\n        f: T,\n    }\n\n    impl<T: Unpin> PinnedDrop for PinnedDropImpl<T> {\n        fn drop(_this: Pin<&mut Self>) {}\n    }\n}\n\nfn main() {}\n"
    },
    {
      "package": "png@0.17.5",
      "sourcePath": "README.md",
      "sha256": "a87e2bc972068409cff0665241349c4eb72291b33d12ed97a09f97e9a2560655",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# PNG Decoder/Encoder\n[![Build Status](https://github.com/image-rs/image-png/workflows/Rust%20CI/badge.svg)](https://github.com/image-rs/image-png/actions)\n[![Documentation](https://docs.rs/png/badge.svg)](https://docs.rs/png)\n[![Crates.io](https://img.shields.io/crates/v/png.svg)](https://crates.io/crates/png)\n![Lines of Code](https://tokei.rs/b1/github/image-rs/image-png)\n[![License](https://img.shields.io/crates/l/png.svg)](https://github.com/image-rs/image-png)\n[![fuzzit](https://app.fuzzit.dev/badge?org_id=image-rs)](https://app.fuzzit.dev/orgs/image-rs/dashboard)\n\nPNG decoder/encoder in pure Rust.\n\nIt contains all features required to handle the entirety of [the PngSuite by\nWillem van Schack][PngSuite].\n\n[PngSuite]: http://www.schaik.com/pngsuite2011/pngsuite.html\n\n## pngcheck\n\nThe `pngcheck` utility is a small demonstration binary that checks and prints\nmetadata on every `.png` image provided via parameter. You can run it (for\nexample on the test directories) with\n\n```bash\ncargo run --release --example pngcheck ./tests/pngsuite/*\n```\n\n## License\n\nLicensed under either of\n\n * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any\nadditional terms or conditions.\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "README.md",
      "sha256": "a66e02c23633b74d19013225a52fe26742b59b9575a5cb0451f53e8e7468b622",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# portable-atomic\n\n[![crates.io](https://img.shields.io/crates/v/portable-atomic?style=flat-square&logo=rust)](https://crates.io/crates/portable-atomic)\n[![docs.rs](https://img.shields.io/badge/docs.rs-portable--atomic-blue?style=flat-square&logo=docs.rs)](https://docs.rs/portable-atomic)\n[![license](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue?style=flat-square)](#license)\n[![msrv](https://img.shields.io/badge/msrv-1.34-blue?style=flat-square&logo=rust)](https://www.rust-lang.org)\n[![github actions](https://img.shields.io/github/actions/workflow/status/taiki-e/portable-atomic/ci.yml?branch=main&style=flat-square&logo=github)](https://github.com/taiki-e/portable-atomic/actions)\n\n<!-- tidy:sync-markdown-to-rustdoc:start:src/lib.rs -->\n\nPortable atomic types including support for 128-bit atomics, atomic float, etc.\n\n- Provide all atomic integer types (`Atomic{I,U}{8,16,32,64}`) for all targets that can use atomic CAS. (i.e., all targets that can use `std`, and most no-std targets)\n- Provide `AtomicI128` and `AtomicU128`.\n- Provide `AtomicF32` and `AtomicF64`. ([optional, requires the `float` feature](#optional-features-float))\n- Provide `AtomicF16` and `AtomicF128` for [unstable `f16` and `f128`](https://github.com/rust-lang/rust/issues/116909). ([optional, requires the `float` feature and unstable cfgs](#optional-features-float))\n- Provide atomic load/store for targets where atomic is not available at all in the standard library. (RISC-V without A-extension, MSP430, AVR)\n- Provide atomic CAS for targets where atomic CAS is not available in the standard library. (thumbv6m, pre-v6 Arm, RISC-V without A-extension, MSP430, AVR, Xtensa, etc.) (always enabled for MSP430 and AVR, [optional](#optional-features-critical-section) otherwise)\n- Make features that require newer compilers, such as [`fetch_{max,min}`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_max), [`fetch_update`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_update), [`as_ptr`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.as_ptr), [`from_ptr`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.from_ptr), [`AtomicBool::fetch_not`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicBool.html#method.fetch_not), [`AtomicPtr::fetch_*`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.fetch_and), and [stronger CAS failure ordering](https://github.com/rust-lang/rust/pull/98383) available on Rust 1.34+.\n- Provide workaround for bugs in the standard library's atomic-related APIs, such as [rust-lang/compiler-builtins#1234], [rust-lang/rust#100650], `fence`/`compiler_fence` on MSP430 that cause LLVM error, etc.\n\n<!-- TODO:\n- mention Atomic{I,U}*::fetch_neg, Atomic{I*,U*,Ptr}::bit_*, etc.\n- mention optimizations not available in the standard library's equivalents\n-->\n\nportable-atomic version of `std::sync::Arc` and `std::task::Wake` is provided by the [portable-atomic-util] crate.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nportable-atomic = \"1\"\n```\n\nThe default features are mainly for users who use atomics larger than the pointer width.\nIf you don't need them, disabling the default features may reduce code size and compile time slightly.\n\n```toml\n[dependencies]\nportable-atomic = { version = \"1\", default-features = false }\n```\n\nIf your crate supports no-std environment and requires atomic CAS, enabling the `require-cas` feature will allow the portable-atomic to display a [helpful error message](https://github.com/taiki-e/portable-atomic/pull/100) to users on targets requiring additional action on the user side to provide atomic CAS.\n\n```toml\n[dependencies]\nportable-atomic = { version = \"1.3\", default-features = false, features = [\"require-cas\"] }\n```\n\n(Since 1.8, portable-atomic can display a [helpful error message](https://github.com/taiki-e/portable-atomic/pull/181) even without the `require-cas` feature when the rustc version is 1.78+. However, the `require-cas` feature also allows rejecting builds at an earlier stage, we recommend enabling it unless enabling it causes [problems](https://github.com/matklad/once_cell/pull/267).)\n\n## 128-bit atomics support\n\nNative 128-bit atomic operations are available on x86_64 (Rust 1.59+), AArch64 (Rust 1.59+), riscv64 (Rust 1.59+), Arm64EC (Rust 1.84+), s390x (Rust 1.84+), and powerpc64 (Rust 1.95+), otherwise the fallback implementation is used.\n\nOn x86_64, even if `cmpxchg16b` is not available at compile-time (Note: `cmpxchg16b` target feature is enabled by default only on Apple, Windows (except Windows 7), and Fuchsia targets), run-time detection checks whether `cmpxchg16b` is available. If `cmpxchg16b` is not available at either compile-time or run-time detection, the fallback implementation is used. See also [`portable_atomic_no_outline_atomics`](#optional-cfg-no-outline-atomics) cfg.\n\nThey are usually implemented using inline assembly, and when using Miri or ThreadSanitizer that do not support inline assembly, core intrinsics are used instead of inline assembly if possible.\n\nSee the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md) for details.\n\n## <a name=\"optional-features\"></a><a name=\"optional-cfg\"></a>Optional features/cfgs\n\nportable-atomic provides features and cfgs to allow enabling specific APIs and customizing its behavior.\n\nSome options have both a feature and a cfg. When both exist, it indicates that the feature does not follow Cargo's recommendation that [features should be additive](https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-unification). Therefore, the maintainer's recommendation is to use cfg instead of feature. However, in the embedded ecosystem, it is very common to use features in such places, so these options provide both so you can choose based on your preference.\n\n<details>\n<summary>How to enable cfg (click to show)</summary>\n\nOne of the ways to enable cfg is to set [rustflags in the cargo config](https://doc.rust-lang.org/cargo/reference/config.html#targettriplerustflags):\n\n```toml\n# .cargo/config.toml\n[target.<target>]\nrustflags = [\"--cfg\", \"portable_atomic_unsafe_assume_single_core\"]\n```\n\nOr set environment variable:\n\n```sh\nRUSTFLAGS=\"--cfg portable_atomic_unsafe_assume_single_core\" cargo ...\n```\n\n</details>\n\n- <a name=\"optional-features-fallback\"></a>**`fallback` feature** *(enabled by default)*<br>\n  Enable fallback implementations.\n\n  This enables atomic types with larger than the width supported by atomic instructions available on the current target. If the current target [supports 128-bit atomics](#128-bit-atomics-support), this is no-op.\n\n  This uses fallback implementation that using global locks by default. The following features/cfgs change this behavior:\n  - [`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg](#optional-features-unsafe-assume-single-core): Use fallback implementations that disabling interrupts instead of using global locks.\n    - If your target is single-core and calling interrupt disable instructions is safe, this is a safer and more efficient option.\n  - [`unsafe-assume-privileged` feature / `portable_atomic_unsafe_assume_privileged` cfg](#optional-features-unsafe-assume-privileged): Use fallback implementations that using global locks with disabling interrupts.\n    - If your target is multi-core and calling interrupt disable instructions is safe, this is a safer option.\n\n- <a name=\"optional-features-float\"></a>**`float` feature**<br>\n  Provide `AtomicF{32,64}`.\n\n  If you want atomic types for unstable float types ([`f16` and `f128`](https://github.com/rust-lang/rust/issues/116909)), enable unstable cfg (`portable_atomic_unstable_f16` cfg for `AtomicF16`, `portable_atomic_unstable_f128` cfg for `AtomicF128`, [there is no possibility that both feature and cfg will be provided for unstable options.](https://github.com/taiki-e/portable-atomic/pull/200#issuecomment-2682252991)).\n\n> [!NOTE]\n> - Atomic float's `fetch_{add,sub,min,max}` are usually implemented using CAS loops, which can be slower than equivalent operations of atomic integers. As an exception, AArch64 with FEAT_LSFE and GPU targets have atomic float instructions and we use them on AArch64 when `lsfe` target feature is available at compile-time. We [plan to use atomic float instructions for GPU targets as well in the future.](https://github.com/taiki-e/portable-atomic/issues/34)\n> - Unstable cfgs are outside of the normal semver guarantees and minor or patch versions of portable-atomic may make breaking changes to them at any time.\n\n- <a name=\"optional-features-std\"></a>**`std` feature**<br>\n  Use `std`.\n\n- <a name=\"optional-features-require-cas\"></a>**`require-cas` feature**<br>\n  Emit compile error if atomic CAS is not available. See [Usage](#usage) section for usage of this feature.\n\n- <a name=\"optional-features-serde\"></a>**`serde` feature**<br>\n  Implement `serde::{Serialize,Deserialize}` for atomic types.\n\n  Note:\n  - The MSRV when this feature is enabled depends on the MSRV of [serde].\n\n- <a name=\"optional-features-critical-section\"></a>**`critical-section` feature**<br>\n  Use [critical-section] to provide atomic CAS for targets where atomic CAS is not available in the standard library.\n\n  `critical-section` support is useful to get atomic CAS when the [`unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)](#optional-features-unsafe-assume-single-core) can't be used,\n  such as multi-core targets, unprivileged code running under some RTOS, or environments where disabling interrupts\n  needs extra care due to e.g. real-time requirements.\n\n> [!NOTE]\n> - When enabling this feature, you should provide a suitable critical section implementation for the current target, see the [critical-section] documentation for details on how to do so.\n> - With this feature, critical sections are taken for all atomic operations, while with `unsafe-assume-single-core` feature [some operations](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/interrupt/README.md#no-disable-interrupts) don't require disabling interrupts. Therefore, for better performance, if all the `critical-section` implementation for your target does is disable interrupts, prefer using `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) instead.\n> - It is usually **discouraged** to always enable this feature in libraries that depend on `portable-atomic`.\n>\n>   Enabling this feature will prevent the end user from having the chance to take advantage of other (potentially) efficient implementations (implementations provided by `unsafe-assume-single-core` feature mentioned above, implementation proposed in [#60], etc.). Also, targets that are currently unsupported may be supported in the future.\n>\n>   The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature. (However, it may make sense to enable this feature by default for libraries specific to a platform where other implementations are known not to work.)\n>\n>   See also [this comment](https://github.com/matklad/once_cell/issues/264#issuecomment-2352654806).\n>\n>   As an example, the end-user's `Cargo.toml` that uses a crate that provides a critical-section implementation and a crate that depends on portable-atomic as an option would be expected to look like this:\n>\n>   ```toml\n>   [dependencies]\n>   portable-atomic = { version = \"1\", default-features = false, features = [\"critical-section\"] }\n>   crate-provides-critical-section-impl = \"...\"\n>   crate-uses-portable-atomic-as-feature = { version = \"...\", features = [\"portable-atomic\"] }\n>   ```\n>\n> - Enabling both this feature and `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) will result in a compile error.\n> - Enabling both this feature and `unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg) will result in a compile error.\n> - The MSRV when this feature is enabled depends on the MSRV of [critical-section].\n\n- <a name=\"optional-features-unsafe-assume-single-core\"></a><a name=\"optional-cfg-unsafe-assume-single-core\"></a>**`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg**<br>\n  Assume that the target is single-core and privileged instructions required to disable interrupts are available.\n\n  - When this feature/cfg is enabled, this crate provides atomic CAS for targets where atomic CAS is not available in the standard library by disabling interrupts.\n  - When both this feature/cfg and enabled-by-default `fallback` feature is enabled, this crate provides atomic types with larger than the width supported by native instructions by disabling interrupts.\n\n> [!WARNING]\n> This feature/cfg is `unsafe`, and note the following safety requirements:\n> - Enabling this feature/cfg for multi-core systems is always **unsound**.\n>\n> - This uses privileged instructions to disable interrupts, so it usually doesn't work on unprivileged mode.\n>\n>   Enabling this feature/cfg in an environment where privileged instructions are not available, or if the instructions used are not sufficient to disable interrupts in the system, it is also usually considered **unsound**, although the details are system-dependent.\n>\n>   The following are known cases:\n>   - On Arm (except for M-Profile architectures), this disables only IRQs by default. For many systems (e.g., GBA) this is enough. If the system need to disable both IRQs and FIQs, you need to enable the `disable-fiq` feature (or `portable_atomic_disable_fiq` cfg) together.\n>   - On RISC-V, this generates code for machine-mode (M-mode) by default. If you enable the `s-mode` feature (or `portable_atomic_s_mode` cfg) together, this generates code for supervisor-mode (S-mode). In particular, `qemu-system-riscv*` uses [OpenSBI](https://github.com/riscv-software-src/opensbi) as the default firmware.\n\nConsider using the [`unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg)](#optional-features-unsafe-assume-privileged) for multi-core systems with atomic CAS.\n\nConsider using the [`critical-section` feature](#optional-features-critical-section) for systems that cannot use this feature/cfg.\n\nSee also the [`interrupt` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/interrupt/README.md).\n\n> [!NOTE]\n> - It is **very strongly discouraged** to enable this feature/cfg in libraries that depend on `portable-atomic`.\n>\n>   The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature/cfg. (However, it may make sense to enable this feature/cfg by default for libraries specific to a platform where it is guaranteed to always be sound, for example in a hardware abstraction layer targeting a single-core chip.)\n> - Enabling this feature/cfg for unsupported architectures will result in a compile error.\n>   - Arm, RISC-V, and Xtensa are currently supported. (Since all MSP430 and AVR are single-core, we always provide atomic CAS for them without this feature/cfg.)\n>   - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target is not supported yet.\n> - Enabling this feature/cfg for targets where privileged instructions are obviously unavailable (e.g., Linux) will result in a compile error.\n>   - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target supports privileged instructions but the build rejected.\n> - Enabling both this feature/cfg and `critical-section` feature will result in a compile error.\n> - When both this feature/cfg and `unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg) are enabled, this feature/cfg is preferred.\n\n- <a name=\"optional-features-unsafe-assume-privileged\"></a><a name=\"optional-cfg-unsafe-assume-privileged\"></a>**`unsafe-assume-privileged` feature / `portable_atomic_unsafe_assume_privileged` cfg**<br>\n  Similar to `unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg, but only assumes about availability of privileged instructions required to disable interrupts.\n\n  - When both this feature/cfg and enabled-by-default `fallback` feature is enabled, this crate provides atomic types with larger than the width supported by native instructions by using global locks with disabling interrupts.\n\n> [!WARNING]\n> This feature/cfg is `unsafe`, and except for being sound in multi-core systems, this has the same safety requirements as [`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg](#optional-features-unsafe-assume-single-core).\n\n> [!NOTE]\n> - It is **very strongly discouraged** to enable this feature/cfg in libraries that depend on `portable-atomic`.\n>\n>   The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature/cfg. (However, it may make sense to enable this feature/cfg by default for libraries specific to a platform where it is guaranteed to always be sound, for example in a hardware abstraction layer.)\n> - Enabling this feature/cfg for unsupported targets will result in a compile error.\n>   - This requires atomic CAS (`cfg(target_has_atomic = \"ptr\")` or `cfg_no_atomic_cas!`).\n>   - Arm, RISC-V, and Xtensa are currently supported.\n>   - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target is not supported yet.\n> - Enabling this feature/cfg for targets where privileged instructions are obviously unavailable (e.g., Linux) will result in a compile error.\n>   - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target supports privileged instructions but the build rejected.\n> - Enabling both this feature/cfg and `critical-section` feature will result in a compile error.\n> - When both this feature/cfg and `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) are enabled, `unsafe-assume-single-core` is preferred.\n\n- <a name=\"optional-cfg-no-outline-atomics\"></a>**`portable_atomic_no_outline_atomics` cfg**<br>\n  Disable dynamic dispatching by run-time CPU feature detection.\n\n  Dynamic dispatching by run-time CPU feature detection allows maintaining support for older CPUs while using features that are not supported on older CPUs, such as CMPXCHG16B (x86_64) and FEAT_LSE/FEAT_LSE2 (AArch64).\n\n  See also the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md).\n\n> [!NOTE]\n> - If the required target features are enabled at compile-time, dynamic dispatching is automatically disabled and the atomic operations are inlined.\n> - This is compatible with no-std (as with all features except `std`).\n> - On some targets, run-time detection is disabled by default mainly for compatibility with incomplete build environments or support for it is experimental, and can be enabled by `portable_atomic_outline_atomics` cfg. (When both cfg are enabled, `*_no_*` cfg is preferred.)\n> - Some AArch64 targets enable LLVM's `outline-atomics` target feature by default, so if you set this cfg, you may want to disable that as well. (However, portable-atomic's outline-atomics does not depend on the compiler-rt symbols, so even if you need to disable LLVM's outline-atomics, you may not need to disable portable-atomic's outline-atomics.)\n> - Dynamic detection is currently only supported in x86_64, AArch64, Arm, RISC-V, Arm64EC, and powerpc64. Enabling this cfg for unsupported architectures will be ignored.\n\n## Related Projects\n\n- [portable-atomic-util]: Synchronization primitives built with portable-atomic. This provides portable-atomic version of `std::sync::Arc` and `std::task::Wake`.\n- [atomic-maybe-uninit]: Atomic operations on potentially uninitialized integers.\n- [atomic-memcpy]: Byte-wise atomic memcpy.\n- [asmtest]: A library for tracking generated assemblies.\n\n[#60]: https://github.com/taiki-e/portable-atomic/issues/60\n[asmtest]: https://github.com/taiki-e/asmtest\n[atomic-maybe-uninit]: https://github.com/taiki-e/atomic-maybe-uninit\n[atomic-memcpy]: https://github.com/taiki-e/atomic-memcpy\n[critical-section]: https://github.com/rust-embedded/critical-section\n[portable-atomic-util]: https://github.com/taiki-e/portable-atomic-util\n[rust-lang/compiler-builtins#1234]: https://github.com/rust-lang/compiler-builtins/pull/1234\n[rust-lang/rust#100650]: https://github.com/rust-lang/rust/issues/100650\n[serde]: https://github.com/serde-rs/serde\n\n<!-- tidy:sync-markdown-to-rustdoc:end -->\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "build.rs",
      "sha256": "9d0b1e071715580497aadb918d4b3b124ee366ba66f15ac05a3d8045f0bc2cf0",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// The rustc-cfg emitted by the build script are *not* public API.\n\n#![allow(clippy::match_same_arms)] // https://github.com/rust-lang/rust-clippy/issues/12044\n\n#[path = \"src/gen/build.rs\"]\nmod generated;\n#[path = \"version.rs\"]\nmod version;\n\nuse std::{env, str};\n\nuse self::version::{Version, rustc_version};\n\nfn main() {\n    println!(\"cargo:rerun-if-changed=build.rs\");\n    println!(\"cargo:rerun-if-changed=src/gen/build.rs\");\n    println!(\"cargo:rerun-if-changed=version.rs\");\n\n    #[cfg(feature = \"unsafe-assume-single-core\")]\n    println!(\"cargo:rustc-cfg=portable_atomic_unsafe_assume_single_core\");\n    #[cfg(feature = \"unsafe-assume-privileged\")]\n    println!(\"cargo:rustc-cfg=portable_atomic_unsafe_assume_privileged\");\n    #[cfg(feature = \"s-mode\")]\n    println!(\"cargo:rustc-cfg=portable_atomic_s_mode\");\n    #[cfg(feature = \"force-amo\")]\n    println!(\"cargo:rustc-cfg=portable_atomic_force_amo\");\n    #[cfg(feature = \"disable-fiq\")]\n    println!(\"cargo:rustc-cfg=portable_atomic_disable_fiq\");\n\n    let target = &*env::var(\"TARGET\").expect(\"TARGET not set\");\n    let target_arch = &*env::var(\"CARGO_CFG_TARGET_ARCH\").expect(\"CARGO_CFG_TARGET_ARCH not set\");\n    let target_os = &*env::var(\"CARGO_CFG_TARGET_OS\").expect(\"CARGO_CFG_TARGET_OS not set\");\n\n    let version = match rustc_version() {\n        Some(version) => version,\n        None => {\n            if env::var_os(\"PORTABLE_ATOMIC_DENY_WARNINGS\").is_some() {\n                panic!(\"unable to determine rustc version\")\n            }\n            println!(\n                \"cargo:warning={}: unable to determine rustc version; assuming latest stable rustc (1.{})\",\n                env!(\"CARGO_PKG_NAME\"),\n                Version::LATEST.minor\n            );\n            Version::LATEST\n        }\n    };\n\n    if version.minor >= 80 {\n        println!(\n            r#\"cargo:rustc-check-cfg=cfg(target_feature,values(\"lsfe\",\"fast-serialization\",\"load-store-on-cond\",\"distinct-ops\",\"rmw\"))\"#\n        );\n\n        // Custom cfgs set by build script. Not public API.\n        // grep -F 'cargo:rustc-cfg=' build.rs | grep -Ev '^ *//' | sed -E 's/^.*cargo:rustc-cfg=//; s/(=\\\\)?\".*$//' | LC_ALL=C sort -u | tr '\\n' ',' | sed -E 's/,$/\\n/'\n        println!(\n            \"cargo:rustc-check-cfg=cfg(portable_atomic_atomic_intrinsics,portable_atomic_disable_fiq,portable_atomic_force_amo,portable_atomic_ll_sc_rmw,portable_atomic_no_asm,portable_atomic_no_asm_maybe_uninit,portable_atomic_no_asm_syscall,portable_atomic_no_atomic_64,portable_atomic_no_atomic_cas,portable_atomic_no_atomic_load_store,portable_atomic_no_atomic_min_max,portable_atomic_no_cfg_target_has_atomic,portable_atomic_no_cmpxchg16b_intrinsic,portable_atomic_no_cmpxchg16b_target_feature,portable_atomic_no_const_mut_refs,portable_atomic_no_const_raw_ptr_deref,portable_atomic_no_const_transmute,portable_atomic_no_core_unwind_safe,portable_atomic_no_diagnostic_namespace,portable_atomic_no_strict_provenance,portable_atomic_no_strict_provenance_atomic_ptr,portable_atomic_no_stronger_failure_ordering,portable_atomic_no_track_caller,portable_atomic_no_unsafe_op_in_unsafe_fn,portable_atomic_pre_llvm_16,portable_atomic_pre_llvm_18,portable_atomic_pre_llvm_20,portable_atomic_s_mode,portable_atomic_sanitize_thread,portable_atomic_target_feature,portable_atomic_unsafe_assume_privileged,portable_atomic_unsafe_assume_single_core,portable_atomic_unstable_asm,portable_atomic_unstable_asm_experimental_arch,portable_atomic_unstable_cfg_target_has_atomic,portable_atomic_unstable_isa_attribute)\"\n        );\n        // TODO: handle multi-line target_feature_fallback\n        // grep -F 'target_feature_fallback(\"' build.rs | grep -Ev '^ *//' | sed -E 's/^.*target_feature_fallback\\(//; s/\",.*$/\"/' | LC_ALL=C sort -u | tr '\\n' ',' | sed -E 's/,$/\\n/'\n        println!(\n            r#\"cargo:rustc-check-cfg=cfg(portable_atomic_target_feature,values(\"cmpxchg16b\",\"distinct-ops\",\"fast-serialization\",\"load-store-on-cond\",\"lse\",\"lse128\",\"lse2\",\"lsfe\",\"mclass\",\"miscellaneous-extensions-3\",\"quadword-atomics\",\"rcpc3\",\"rmw\",\"v6\",\"v7\",\"zaamo\",\"zabha\",\"zacas\"))\"#\n        );\n    }\n\n    // https://github.com/rust-lang/rust/pull/123745 (includes https://github.com/rust-lang/cargo/pull/13560) merged in Rust 1.79 (nightly-2024-04-11).\n    if !version.probe(79, 2024, 4, 10) {\n        // HACK: If --target is specified, rustflags is not applied to the build\n        // script itself, so the build script will not be recompiled when rustflags\n        // is changed. That in itself is not a problem, but the old Cargo does\n        // not rerun the build script as well, which can be problematic.\n        // https://github.com/rust-lang/cargo/issues/13003\n        // This problem has been fixed in 1.79 so only older versions need a workaround.\n        println!(\"cargo:rerun-if-env-changed=CARGO_ENCODED_RUSTFLAGS\");\n        println!(\"cargo:rerun-if-env-changed=RUSTFLAGS\");\n        println!(\"cargo:rerun-if-env-changed=CARGO_BUILD_RUSTFLAGS\");\n        let mut target_upper = target.replace(|c: char| c == '-' || c == '.', \"_\");\n        target_upper.make_ascii_uppercase();\n        println!(\"cargo:rerun-if-env-changed=CARGO_TARGET_{}_RUSTFLAGS\", target_upper);\n    }\n\n    // Note that cfgs are `no_`*, not `has_*`. This allows treating as the latest\n    // stable rustc is used when the build script doesn't run. This is useful\n    // for non-cargo build systems that don't run the build script.\n\n    // atomic_min_max stabilized in Rust 1.45 (nightly-2020-05-30): https://github.com/rust-lang/rust/pull/72324\n    if !version.probe(45, 2020, 5, 29) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_atomic_min_max\");\n    }\n    // track_caller stabilized in Rust 1.46 (nightly-2020-07-02): https://github.com/rust-lang/rust/pull/72445\n    if !version.probe(46, 2020, 7, 1) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_track_caller\");\n    }\n    // unsafe_op_in_unsafe_fn stabilized in Rust 1.52 (nightly-2021-03-11): https://github.com/rust-lang/rust/pull/79208\n    if !version.probe(52, 2021, 3, 10) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_unsafe_op_in_unsafe_fn\");\n    }\n    // const_transmute stabilized in Rust 1.56 (nightly-2021-07-29): https://github.com/rust-lang/rust/pull/85769\n    if !version.probe(56, 2021, 7, 28) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_const_transmute\");\n    }\n    // https://github.com/rust-lang/rust/pull/84662 merged in Rust 1.56 (nightly-2021-08-02).\n    if !version.probe(56, 2021, 8, 1) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_core_unwind_safe\");\n    }\n    // const_raw_ptr_deref stabilized in Rust 1.58 (nightly-2021-11-15): https://github.com/rust-lang/rust/pull/89551\n    if !version.probe(58, 2021, 11, 14) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_const_raw_ptr_deref\");\n    }\n    // https://github.com/rust-lang/rust/pull/98383 merged in Rust 1.64 (nightly-2022-07-19).\n    if !version.probe(64, 2022, 7, 18) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_stronger_failure_ordering\");\n    }\n    // https://github.com/rust-lang/rust/pull/114790 merged in nightly-2023-08-24\n    if !version.probe(74, 2023, 8, 23) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_asm_maybe_uninit\");\n    }\n    // #[diagnostic] stabilized in Rust 1.78 (nightly-2024-03-09): https://github.com/rust-lang/rust/pull/119888\n    if !version.probe(78, 2024, 3, 8) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_diagnostic_namespace\");\n    }\n    // const_mut_refs/const_refs_to_cell stabilized in Rust 1.83 (nightly-2024-09-16): https://github.com/rust-lang/rust/pull/129195\n    if !version.probe(83, 2024, 9, 15) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_const_mut_refs\");\n    }\n    // strict_provenance/exposed_provenance APIs stabilized in Rust 1.84 (nightly-2024-10-22): https://github.com/rust-lang/rust/pull/130350\n    if !version.probe(84, 2024, 10, 21) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_strict_provenance\");\n    }\n    // strict_provenance_atomic_ptr stabilized in Rust 1.91 (nightly-2024-10-22): https://github.com/rust-lang/rust/pull/145467\n    if !version.probe(91, 2025, 8, 30) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_strict_provenance_atomic_ptr\");\n    }\n\n    // For Miri and ThreadSanitizer. (aarch64, arm64ec, s390x, powerpc64)\n    // https://github.com/rust-lang/rust/pull/97423 merged in Rust 1.64 (nightly-2022-06-30).\n    // https://github.com/rust-lang/rust/pull/141507 merged in Rust 1.89 (nightly-2025-05-31).\n    if version.nightly\n        && version.probe(64, 2022, 6, 29)\n        && !version.probe(89, 2025, 5, 30)\n        && (target_arch != \"powerpc64\" || version.llvm >= 15)\n    {\n        println!(\"cargo:rustc-cfg=portable_atomic_atomic_intrinsics\");\n    }\n\n    // asm! on AArch64, Arm, RISC-V, x86, and x86_64 stabilized in Rust 1.59 (nightly-2021-12-16): https://github.com/rust-lang/rust/pull/91728\n    let no_asm = !version.probe(59, 2021, 12, 15);\n    if no_asm {\n        if version.nightly\n            && version.probe(46, 2020, 6, 20)\n            && ((target_arch != \"x86\" && target_arch != \"x86_64\") || version.llvm >= 10)\n            && is_allowed_feature(\"asm\")\n        {\n            // This feature was added in Rust 1.45 (nightly-2020-05-20), but\n            // concat! in asm! requires Rust 1.46 (nightly-2020-06-21).\n            // x86 intel syntax requires LLVM 10 (since Rust 1.53, the minimum\n            // external LLVM version is 10+: https://github.com/rust-lang/rust/pull/83387).\n            // The part of this feature we use has not been changed since nightly-2020-06-21\n            // until it was stabilized, so it can safely be enabled in nightly for that period.\n            println!(\"cargo:rustc-cfg=portable_atomic_unstable_asm\");\n            if (target_arch == \"riscv32\" || target_arch == \"riscv64\")\n                && !version.probe(56, 2021, 8, 15)\n            {\n                // Clobbering vector status needed for asm syscall require Rust 1.56 (nightly-2021-08-16): https://github.com/rust-lang/rust/pull/87581\n                println!(\"cargo:rustc-cfg=portable_atomic_no_asm_syscall\");\n            }\n        }\n        println!(\"cargo:rustc-cfg=portable_atomic_no_asm\");\n    } else {\n        match target_arch {\n            \"arm64ec\" | \"s390x\" => {\n                // asm! on Arm64EC and s390x stabilized in Rust 1.84 (nightly-2024-11-11): https://github.com/rust-lang/rust/pull/131781, https://github.com/rust-lang/rust/pull/131258\n                if !version.probe(84, 2024, 11, 10) {\n                    if version.nightly\n                        && (target_arch != \"s390x\" || version.probe(71, 2023, 5, 8))\n                        && is_allowed_feature(\"asm_experimental_arch\")\n                    {\n                        // https://github.com/rust-lang/rust/pull/111331 merged in Rust 1.71 (nightly-2023-05-09).\n                        // The part of this feature we use has not been changed since nightly-2023-05-09\n                        // until it was stabilized, so it can safely be enabled in nightly for that period.\n                        println!(\"cargo:rustc-cfg=portable_atomic_unstable_asm_experimental_arch\");\n                    } else {\n                        println!(\"cargo:rustc-cfg=portable_atomic_no_asm\");\n                    }\n                }\n            }\n            \"powerpc64\" => {\n                // asm! on PowerPC stabilized in Rust 1.95 (nightly-2026-01-28): https://github.com/rust-lang/rust/pull/147996\n                if !version.probe(95, 2026, 1, 27) {\n                    if version.nightly\n                        && version.probe(60, 2022, 2, 12)\n                        && is_allowed_feature(\"asm_experimental_arch\")\n                    {\n                        // https://github.com/rust-lang/rust/pull/93868 merged in Rust 1.60 (nightly-2022-02-13).\n                        // The part of this feature we use has not been changed since nightly-2022-02-13\n                        // until it was stabilized, so it can safely be enabled in nightly for that period.\n                        println!(\"cargo:rustc-cfg=portable_atomic_unstable_asm_experimental_arch\");\n                    } else {\n                        println!(\"cargo:rustc-cfg=portable_atomic_no_asm\");\n                    }\n                    if !version.probe(92, 2025, 9, 22)\n                        || env::var(\"CARGO_CFG_TARGET_ABI\")\n                            .unwrap_or_default()\n                            .split(',')\n                            .any(|abi| abi == \"spu\")\n                    {\n                        // Clobbering ctr register needed for asm syscall require Rust 1.92 (nightly-2025-09-23): https://github.com/rust-lang/rust/pull/146831\n                        // Cell/B.E. Linux's SPU syscalls support a subset of powerpc64 syscalls with the exact semantics: https://github.com/torvalds/linux/blob/v7.1/arch/powerpc/platforms/cell/spu_callbacks.c#L17\n                        // but have a different syscall sequence: https://github.com/mirror/newlib-cygwin/blob/newlib-4.4.0/libgloss/spu/linux_syscalls.c#L37\n                        // This is currently used only for testing.\n                        println!(\"cargo:rustc-cfg=portable_atomic_no_asm_syscall\");\n                    }\n                }\n            }\n            _ => {}\n        }\n    }\n\n    // feature(cfg_target_has_atomic) stabilized in Rust 1.60 (nightly-2022-02-11): https://github.com/rust-lang/rust/pull/93824\n    if !version.probe(60, 2022, 2, 10) {\n        if version.nightly\n            && version.probe(40, 2019, 10, 13)\n            && is_allowed_feature(\"cfg_target_has_atomic\")\n        {\n            // The part of this feature we use has not been changed since nightly-2019-10-14\n            // until it was stabilized, so it can safely be enabled in nightly for that period.\n            println!(\"cargo:rustc-cfg=portable_atomic_unstable_cfg_target_has_atomic\");\n        } else {\n            println!(\"cargo:rustc-cfg=portable_atomic_no_cfg_target_has_atomic\");\n            let target = &*convert_custom_linux_target(target);\n            if generated::NO_ATOMIC_CAS.contains(&target) {\n                println!(\"cargo:rustc-cfg=portable_atomic_no_atomic_cas\");\n            }\n            if generated::NO_ATOMIC_64.contains(&target) {\n                println!(\"cargo:rustc-cfg=portable_atomic_no_atomic_64\");\n            } else {\n                // Otherwise, assuming `\"max-atomic-width\" == 64` or `\"max-atomic-width\" == 128`.\n            }\n        }\n    }\n    // We don't need to use convert_custom_linux_target here because all linux targets have atomics.\n    if generated::NO_ATOMIC.contains(&target) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_atomic_load_store\");\n    }\n\n    if version.llvm < 20 {\n        println!(\"cargo:rustc-cfg=portable_atomic_pre_llvm_20\");\n        if version.llvm < 18 {\n            println!(\"cargo:rustc-cfg=portable_atomic_pre_llvm_18\");\n            if version.llvm < 16 {\n                println!(\"cargo:rustc-cfg=portable_atomic_pre_llvm_16\");\n            }\n        }\n    }\n\n    if version.nightly {\n        // `cfg(sanitize = \"..\")` is not stabilized.\n        let sanitize = env::var(\"CARGO_CFG_SANITIZE\").unwrap_or_default();\n        if sanitize.contains(\"thread\") {\n            // Most kinds of sanitizers are not compatible with asm\n            // (https://github.com/google/sanitizers/issues/192),\n            // but it seems that ThreadSanitizer is the only one that can cause\n            // false positives in our code.\n            println!(\"cargo:rustc-cfg=portable_atomic_sanitize_thread\");\n        }\n    }\n\n    match target_arch {\n        \"x86_64\" => {\n            // cmpxchg16b_target_feature stabilized in Rust 1.69 (nightly-2023-03-01): https://github.com/rust-lang/rust/pull/106774\n            if !version.probe(69, 2023, 2, 28) {\n                println!(\"cargo:rustc-cfg=portable_atomic_no_cmpxchg16b_target_feature\");\n            }\n            // For Miri and ThreadSanitizer.\n            // https://github.com/rust-lang/rust/pull/109359 (includes https://github.com/rust-lang/stdarch/pull/1358) merged in Rust 1.70 (nightly-2023-03-24).\n            if version.nightly && !version.probe(70, 2023, 3, 23) {\n                println!(\"cargo:rustc-cfg=portable_atomic_no_cmpxchg16b_intrinsic\");\n            }\n\n            // cmpxchg16b_target_feature stabilized in Rust 1.69.\n            if needs_target_feature_fallback(&version, Some(69)) {\n                // x86_64 Apple targets always support CMPXCHG16B:\n                // https://github.com/rust-lang/rust/blob/1.68.0/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs#L8\n                // https://github.com/rust-lang/rust/blob/1.68.0/compiler/rustc_target/src/spec/apple_base.rs#L69-L70\n                // (Windows (except Windows 7, since Rust 1.78) and Fuchsia (since Rust 1.87) targets\n                // also enable CMPXCHG16B, but this branch is only used on pre-1.69 that\n                // cmpxchg16b_target_feature is unstable.)\n                // Script to get builtin targets that support CMPXCHG16B by default:\n                // $ (for target in $(rustc -Z unstable-options --print all-target-specs-json | jq -r '. | to_entries[] | if .value.arch == \"x86_64\" then .key else empty end'); do rustc --print cfg --target \"${target}\" | grep -Fq '\"cmpxchg16b\"' && printf '%s\\n' \"${target}\"; done)\n                let is_apple = env::var(\"CARGO_CFG_TARGET_VENDOR\").unwrap_or_default() == \"apple\";\n                let cmpxchg16b = is_apple;\n                // LLVM recognizes this also as cx16 target feature: https://godbolt.org/z/KM3jz616j\n                // However, it is unlikely that rustc will support that name, so we ignore it.\n                target_feature_fallback(\"cmpxchg16b\", cmpxchg16b);\n            }\n        }\n        \"aarch64\" | \"arm64ec\" => {\n            // target_feature \"lse2\"/\"lse128\"/\"rcpc3\" is unstable and available on rustc side since nightly-2024-08-30: https://github.com/rust-lang/rust/pull/128192\n            if !version.probe(82, 2024, 8, 29) || needs_target_feature_fallback(&version, None) {\n                // FEAT_LSE2 doesn't imply FEAT_LSE. FEAT_LSE128 implies FEAT_LSE but not FEAT_LSE2.\n                // AArch64 macOS always supports FEAT_LSE and FEAT_LSE2 because M1 is Armv8.4 with all features of Armv8.5 except FEAT_BTI:\n                // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/AArch64/AArch64Processors.td#L1558\n                // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/AArch64/AArch64Processors.td#L1180\n                // Script to get builtin targets that support FEAT_LSE/FEAT_LSE2 by default:\n                // $ (for target in $(rustc -Z unstable-options --print all-target-specs-json | jq -r '. | to_entries[] | if .value.arch == \"aarch64\" or .value.arch == \"arm64ec\" then .key else empty end'); do rustc --print cfg --target \"${target}\" | grep -Fq '\"lse\"' && printf '%s\\n' \"${target}\"; done)\n                // $ (for target in $(rustc -Z unstable-options --print all-target-specs-json | jq -r '. | to_entries[] | if .value.arch == \"aarch64\" or .value.arch == \"arm64ec\" then .key else empty end'); do rustc --print cfg --target \"${target}\" | grep -Fq '\"lse2\"' && printf '%s\\n' \"${target}\"; done)\n                let is_macos = target_os == \"macos\";\n                let mut lse = is_macos;\n                target_feature_fallback(\"lse2\", is_macos);\n                lse |= target_feature_fallback(\"lse128\", false);\n                target_feature_fallback(\"rcpc3\", false);\n                // aarch64_target_feature stabilized in Rust 1.61.\n                if needs_target_feature_fallback(&version, Some(61)) {\n                    target_feature_fallback(\"lse\", lse);\n                }\n            }\n            // As of Rust 1.85, target_feature \"lsfe\" is not available on rustc side:\n            // https://github.com/rust-lang/rust/blob/1.85.0/compiler/rustc_target/src/target_features.rs\n            target_feature_fallback(\"lsfe\", false);\n\n            // As of Apple M1/M1 Pro, on Apple hardware, CAS-loop-based RMW is much slower than\n            // LL/SC-loop-based RMW: https://github.com/taiki-e/portable-atomic/pull/89\n            let is_apple = env::var(\"CARGO_CFG_TARGET_VENDOR\").unwrap_or_default() == \"apple\";\n            if is_apple || target_cpu().map_or(false, |cpu| cpu.starts_with(\"apple-\")) {\n                println!(\"cargo:rustc-cfg=portable_atomic_ll_sc_rmw\");\n            }\n        }\n        \"arm\" => {\n            // For non-Linux/Android pre-v6 Arm (tier 3) with unsafe_assume_single_core enabled.\n            // feature(isa_attribute) stabilized in Rust 1.67 (nightly-2022-11-06): https://github.com/rust-lang/rust/pull/102458\n            if version.nightly && !version.probe(67, 2022, 11, 5) {\n                println!(\"cargo:rustc-cfg=portable_atomic_unstable_isa_attribute\");\n            }\n\n            if needs_target_feature_fallback(&version, None) {\n                // #[cfg(target_feature = \"v7\")] and others don't work on stable.\n                // armv7-unknown-linux-gnueabihf\n                //    ^^\n                let mut mclass = false;\n                let mut v6 = false;\n                let mut v7 = false;\n                if let Some(mut subarch) =\n                    strip_prefix(target, \"arm\").or_else(|| strip_prefix(target, \"thumb\"))\n                {\n                    subarch = strip_prefix(subarch, \"eb\").unwrap_or(subarch); // ignore endianness\n                    subarch = subarch.split('-').next().unwrap(); // ignore vender/os/env\n                    let mut i = subarch.splitn(2, '.');\n                    subarch = i.next().unwrap();\n                    let suffix = i.next().unwrap_or_default(); // .base/.main suffix\n                    let mut known = true;\n                    // See https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/build.rs for details\n                    match subarch {\n                        \"v7\" | \"v7a\" | \"v7neon\" | \"v7s\" | \"v7k\" | \"v8\" | \"v8a\" | \"v9\" | \"v9a\" => {} // aclass\n                        \"v7r\" | \"v8r\" | \"v9r\" => {} // rclass\n                        \"v6m\" | \"v7em\" | \"v7m\" | \"v8m\" => mclass = true,\n                        // arm-linux-androideabi is v5te\n                        // https://github.com/rust-lang/rust/blob/1.84.0/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs#L18\n                        _ if target == \"arm-linux-androideabi\" => subarch = \"v5te\",\n                        // armeb-unknown-linux-gnueabi is v8 & aclass\n                        // https://github.com/rust-lang/rust/blob/1.84.0/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs#L18\n                        _ if target == \"armeb-unknown-linux-gnueabi\" => subarch = \"v8\",\n                        // Legacy Arm architectures (pre-v7 except v6m) don't have *class target feature.\n                        \"\" => subarch = \"v6\",\n                        \"v4t\" | \"v5te\" | \"v6\" | \"v6k\" => {}\n                        _ => {\n                            known = false;\n                            if env::var_os(\"PORTABLE_ATOMIC_DENY_WARNINGS\").is_some() {\n                                panic!(\"unrecognized Arm subarch: {}\", target)\n                            }\n                            println!(\n                                \"cargo:warning={}: unrecognized Arm subarch: {}\",\n                                env!(\"CARGO_PKG_NAME\"),\n                                target\n                            );\n                        }\n                    }\n                    v6 = known && subarch.starts_with(\"v6\");\n                    v7 = known && subarch.starts_with(\"v7\");\n                    if known && (subarch.starts_with(\"v8\") || subarch.starts_with(\"v9\")) {\n                        // Armv8-M is not considered as v8 by LLVM.\n                        // https://github.com/rust-lang/stdarch/blob/a0c30f3e3c75adcd6ee7efc94014ebcead61c507/crates/core_arch/src/arm_shared/mod.rs\n                        if mclass {\n                            // Armv8-M Mainline is a superset of Armv7-M.\n                            // Armv8-M Baseline is a superset of Armv6-M.\n                            // That said, LLVM handles thumbv8m.main without v8m like v6m, not v7m: https://godbolt.org/z/Ph96v9zae\n                            // TODO: Armv9-M has not yet been released,\n                            // so it is not clear how it will be handled here.\n                            v6 = true;\n                            v7 = suffix == \"main\";\n                        } else {\n                            v7 = true;\n                        }\n                    }\n                }\n                v6 |= target_feature_fallback(\"v7\", v7);\n                target_feature_fallback(\"v6\", v6);\n                target_feature_fallback(\"mclass\", mclass);\n            }\n        }\n        \"riscv32\" | \"riscv64\" => {\n            // zabha and zacas imply zaamo in GCC, LLVM 20+, and Rust, but do not in LLVM 19.\n            // However, enabling them without zaamo or a is not allowed in LLVM 19, so we can assume\n            // zaamo is available when zabha is enabled).\n            // https://github.com/llvm/llvm-project/commit/956361ca080a689a96b6552d28681aaf0ad2f494\n            // https://github.com/gcc-mirror/gcc/commit/7b2b2e3d660edc8ef3a8cfbdfc2b0fd499459601\n            // https://github.com/gcc-mirror/gcc/commit/11c2453a16b725b7fb67778e1ab4636a51a1217d\n            // https://github.com/rust-lang/rust/pull/130877\n            let mut zaamo = false;\n            // target_feature \"zacas\" is available as unstable on rustc side\n            // since nightly-2025-02-26 (https://github.com/rust-lang/rust/pull/137417),\n            // and stabilized in Rust 1.94 (https://github.com/rust-lang/rust/pull/145948).\n            if !version.probe(87, 2025, 2, 25) || needs_target_feature_fallback(&version, Some(94))\n            {\n                // amocas.{w,d,q} (and amocas.{b,h} if zabha is also available)\n                // available as experimental since LLVM 17 https://github.com/llvm/llvm-project/commit/29f630a1ddcbb03caa31b5002f0cbc105ff3a869\n                // available non-experimental since LLVM 20 https://github.com/llvm/llvm-project/commit/614aeda93b2225c6eb42b00ba189ba7ca2585c60\n                zaamo |= target_feature_fallback(\"zacas\", false);\n            }\n            // target_feature \"zaamo\"/\"zabha\" is available as unstable on rustc side\n            // since nightly-2024-10-02 (https://github.com/rust-lang/rust/pull/130877),\n            // and stabilized in Rust 1.94 (https://github.com/rust-lang/rust/pull/145948).\n            if !version.probe(83, 2024, 10, 1) || needs_target_feature_fallback(&version, Some(94))\n            {\n                if version.llvm >= 19 {\n                    // amo*.{b,h}\n                    // available since LLVM 19 https://github.com/llvm/llvm-project/commit/89f87c387627150d342722b79c78cea2311cddf7 / https://github.com/llvm/llvm-project/commit/6b7444964a8d028989beee554a1f5c61d16a1cac\n                    zaamo |= target_feature_fallback(\"zabha\", false);\n                }\n                // amo*.{w,d}\n                target_feature_fallback(\"zaamo\", zaamo);\n            }\n        }\n        \"powerpc64\" => {\n            // target_feature \"quadword-atomics\" is unstable and available on rustc side since nightly-2024-09-28: https://github.com/rust-lang/rust/pull/130873\n            if !version.probe(83, 2024, 9, 27) || needs_target_feature_fallback(&version, None) {\n                let mut pwr8_features = false;\n                if let Some(cpu) = target_cpu() {\n                    if let Some(mut cpu_version) = strip_prefix(&cpu, \"pwr\") {\n                        cpu_version = strip_suffix(cpu_version, \"x\").unwrap_or(cpu_version); // for pwr5x and pwr6x\n                        if let Ok(cpu_version) = cpu_version.parse::<u32>() {\n                            pwr8_features = cpu_version >= 8;\n                        }\n                    } else {\n                        // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/PowerPC/PPC.td#L789\n                        // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/PowerPC/PPC.td#L557\n                        // On the minimum external LLVM version of the oldest rustc version which we can use asm_experimental_arch\n                        // on this target (see CI config for more), \"future\" is based on pwr10 features.\n                        // https://github.com/llvm/llvm-project/blob/llvmorg-12.0.0/llvm/lib/Target/PowerPC/PPC.td#L370\n                        pwr8_features = cpu == \"future\" || cpu == \"ppc64le\";\n                    }\n                } else {\n                    // powerpc64le is pwr8 by default https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/PowerPC/PPC.td#L789\n                    // See also https://github.com/rust-lang/rust/issues/59932\n                    pwr8_features = env::var(\"CARGO_CFG_TARGET_ENDIAN\")\n                        .expect(\"CARGO_CFG_TARGET_ENDIAN not set\")\n                        == \"little\";\n                }\n                // power8 features: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/PowerPC/PPC.td#L484\n                // lqarx and stqcx.\n                target_feature_fallback(\"quadword-atomics\", pwr8_features);\n            }\n        }\n        \"s390x\" => {\n            let mut arch9_features = false; // z196+\n            let mut arch13_features = false; // z15+\n            if let Some(cpu) = target_cpu() {\n                // LLVM and GCC recognize the same names:\n                // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/SystemZ/SystemZProcessors.td\n                // https://github.com/gcc-mirror/gcc/blob/releases/gcc-15.2.0/gcc/config/s390/s390.opt#L58-L128\n                if let Some(arch_version) = strip_prefix(&cpu, \"arch\") {\n                    if let Ok(arch_version) = arch_version.parse::<u32>() {\n                        arch9_features = arch_version >= 9;\n                        arch13_features = arch_version >= 13;\n                    }\n                } else {\n                    match &*cpu {\n                        \"z196\" | \"zEC12\" | \"z13\" | \"z14\" => arch9_features = true,\n                        \"z15\" | \"z16\" | \"z17\" => {\n                            arch9_features = true;\n                            arch13_features = true;\n                        }\n                        _ => {}\n                    }\n                }\n            }\n            // target_feature \"miscellaneous-extensions-3\" is available as unstable on rustc side\n            // since nightly-2025-06-05 (https://github.com/rust-lang/rust/pull/141250),\n            // and stabilized in Rust 1.93 (https://github.com/rust-lang/rust/pull/145656).\n            if !version.probe(89, 2025, 6, 4) || needs_target_feature_fallback(&version, Some(93)) {\n                // arch13 features: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/SystemZ/SystemZFeatures.td#L303\n                // nand (nnr{,g}k), select (sel{,g}r), etc.\n                target_feature_fallback(\"miscellaneous-extensions-3\", arch13_features);\n            }\n            // As of Rust 1.84, target_feature \"fast-serialization\"/\"load-store-on-cond\"/\"distinct-ops\"/\"miscellaneous-extensions-3\" is not available on rustc side:\n            // https://github.com/rust-lang/rust/blob/1.84.0/compiler/rustc_target/src/target_features.rs#L547\n            // arch9 features: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/SystemZ/SystemZFeatures.td#L103\n            // bcr 14,0\n            target_feature_fallback(\"fast-serialization\", arch9_features);\n            // {l,st}oc{,g}{,r}\n            target_feature_fallback(\"load-store-on-cond\", arch9_features);\n            // {al,sl,n,o,x}{,g}rk\n            target_feature_fallback(\"distinct-ops\", arch9_features);\n        }\n        \"avr\" => {\n            // target_feature \"rmw\" is unstable and available on rustc side since nightly-2026-02-08: https://github.com/rust-lang/rust/pull/146900\n            if !version.probe(95, 2026, 2, 7) || needs_target_feature_fallback(&version, None) {\n                // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/AVR/AVRDevices.td\n                let mut xmegau = false; // FamilyXMEGAU\n                if let Some(cpu) = target_cpu() {\n                    match &*cpu {\n                        \"atxmega16a4u\" | \"atxmega16c4\" | \"atxmega32a4u\" | \"atxmega32c3\"\n                        | \"atxmega32c4\" | \"atxmega32e5\" | \"atxmega16e5\" | \"atxmega8e5\"\n                        | \"atxmega64a3u\" | \"atxmega64a4u\" | \"atxmega64b1\" | \"atxmega64b3\"\n                        | \"atxmega64c3\" | \"atxmega64a1u\" | \"atxmega128a3u\" | \"atxmega128b1\"\n                        | \"atxmega128b3\" | \"atxmega128c3\" | \"atxmega192a3u\" | \"atxmega192c3\"\n                        | \"atxmega256a3u\" | \"atxmega256a3bu\" | \"atxmega256c3\" | \"atxmega384c3\"\n                        | \"atxmega128a1u\" | \"atxmega128a4u\" => xmegau = true,\n                        _ => {}\n                    }\n                }\n                target_feature_fallback(\"rmw\", xmegau);\n            }\n        }\n        _ => {}\n    }\n}\n\n// HACK: Currently, it seems that the only way to handle unstable target\n// features on the stable is to parse the `-C target-feature` in RUSTFLAGS.\n//\n// - #[cfg(target_feature = \"unstable_target_feature\")] doesn't work on stable.\n// - CARGO_CFG_TARGET_FEATURE excludes unstable target features on stable.\n//\n// As mentioned in the [RFC2045], unstable target features are also passed to LLVM\n// (e.g., https://godbolt.org/z/4rr7rMcfG), so this hack works properly on stable.\n//\n// [RFC2045]: https://rust-lang.github.io/rfcs/2045-target-feature.html#backend-compilation-options\nfn needs_target_feature_fallback(version: &Version, stable: Option<u32>) -> bool {\n    match stable {\n        // In these cases, cfg(target_feature = \"...\") would work, so skip emitting our own fallback target_feature cfg.\n        _ if version.nightly => false,\n        Some(stabilized) if version.minor >= stabilized => false,\n        _ => true,\n    }\n}\nfn target_feature_fallback(name: &str, mut has_target_feature: bool) -> bool {\n    if let Some(rustflags) = env::var_os(\"CARGO_ENCODED_RUSTFLAGS\") {\n        for mut flag in rustflags.to_string_lossy().split('\\x1f') {\n            flag = strip_prefix(flag, \"-C\").unwrap_or(flag);\n            if let Some(flag) = strip_prefix(flag, \"target-feature=\") {\n                for s in flag.split(',') {\n                    // TODO: Handles cases where a specific target feature\n                    // implicitly enables another target feature.\n                    match (s.as_bytes().first(), s.as_bytes().get(1..)) {\n                        (Some(b'+'), Some(f)) if f == name.as_bytes() => has_target_feature = true,\n                        (Some(b'-'), Some(f)) if f == name.as_bytes() => has_target_feature = false,\n                        _ => {}\n                    }\n                }\n            }\n        }\n    }\n    if has_target_feature {\n        println!(\"cargo:rustc-cfg=portable_atomic_target_feature=\\\"{}\\\"\", name);\n    }\n    has_target_feature\n}\n\nfn target_cpu() -> Option<String> {\n    let rustflags = env::var_os(\"CARGO_ENCODED_RUSTFLAGS\")?;\n    let rustflags = rustflags.to_string_lossy();\n    let mut cpu = None;\n    for mut flag in rustflags.split('\\x1f') {\n        flag = strip_prefix(flag, \"-C\").unwrap_or(flag);\n        if let Some(flag) = strip_prefix(flag, \"target-cpu=\") {\n            cpu = Some(flag);\n        }\n    }\n    cpu.map(str::to_owned)\n}\n\nfn is_allowed_feature(name: &str) -> bool {\n    // https://github.com/dtolnay/thiserror/pull/248\n    if env::var_os(\"RUSTC_STAGE\").is_some() {\n        return false;\n    }\n\n    // allowed by default\n    let mut allowed = true;\n    if let Some(rustflags) = env::var_os(\"CARGO_ENCODED_RUSTFLAGS\") {\n        for mut flag in rustflags.to_string_lossy().split('\\x1f') {\n            flag = strip_prefix(flag, \"-Z\").unwrap_or(flag);\n            if let Some(flag) = strip_prefix(flag, \"allow-features=\") {\n                // If it is specified multiple times, the last value will be preferred.\n                allowed = flag.split(',').any(|allowed| allowed == name);\n            }\n        }\n    }\n    allowed\n}\n\n// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/build-common.rs.\n//\n// The target triplets have the form of 'arch-vendor-system'.\n//\n// When building for Linux (e.g. the 'system' part is\n// 'linux-something'), replace the vendor with 'unknown'\n// so that mapping to rust standard targets happens correctly.\nfn convert_custom_linux_target(target: &str) -> String {\n    let mut parts: Vec<&str> = target.split('-').collect();\n    let system = parts.get(2);\n    if system == Some(&\"linux\") {\n        parts[1] = \"unknown\";\n    }\n    parts.join(\"-\")\n}\n\n// str::strip_prefix requires Rust 1.45\n#[must_use]\nfn strip_prefix<'a>(s: &'a str, pat: &str) -> Option<&'a str> {\n    if s.starts_with(pat) { Some(&s[pat.len()..]) } else { None }\n}\n// str::strip_suffix requires Rust 1.45\n#[must_use]\nfn strip_suffix<'a>(s: &'a str, pat: &str) -> Option<&'a str> {\n    if s.ends_with(pat) { Some(&s[..s.len() - pat.len()]) } else { None }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/cfgs.rs",
      "sha256": "7a438600e742bca248c16c980c20c2b65be01bb786e6cde738cbd94f612344e0",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![allow(missing_docs)]\n\n#[cfg(not(all(\n    portable_atomic_no_atomic_load_store,\n    not(any(\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        target_arch = \"riscv32\",\n        target_arch = \"riscv64\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    )),\n)))]\n#[macro_use]\nmod atomic_8_16_macros {\n    #[macro_export]\n    macro_rules! cfg_has_atomic_8 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_8 {\n        ($($tt:tt)*) => {};\n    }\n    #[macro_export]\n    macro_rules! cfg_has_atomic_16 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_16 {\n        ($($tt:tt)*) => {};\n    }\n}\n#[cfg(all(\n    portable_atomic_no_atomic_load_store,\n    not(any(\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        target_arch = \"riscv32\",\n        target_arch = \"riscv64\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    )),\n))]\n#[macro_use]\nmod atomic_8_16_macros {\n    #[macro_export]\n    macro_rules! cfg_has_atomic_8 {\n        ($($tt:tt)*) => {};\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_8 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[macro_export]\n    macro_rules! cfg_has_atomic_16 {\n        ($($tt:tt)*) => {};\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_16 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n}\n\n#[cfg(all(\n    any(not(target_pointer_width = \"16\"), feature = \"fallback\"),\n    not(all(\n        portable_atomic_no_atomic_load_store,\n        not(any(\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            target_arch = \"riscv32\",\n            target_arch = \"riscv64\",\n            feature = \"critical-section\",\n            portable_atomic_unsafe_assume_single_core,\n        )),\n    )),\n))]\n#[macro_use]\nmod atomic_32_macros {\n    #[macro_export]\n    macro_rules! cfg_has_atomic_32 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_32 {\n        ($($tt:tt)*) => {};\n    }\n}\n#[cfg(not(all(\n    any(not(target_pointer_width = \"16\"), feature = \"fallback\"),\n    not(all(\n        portable_atomic_no_atomic_load_store,\n        not(any(\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            target_arch = \"riscv32\",\n            target_arch = \"riscv64\",\n            feature = \"critical-section\",\n            portable_atomic_unsafe_assume_single_core,\n        )),\n    )),\n)))]\n#[macro_use]\nmod atomic_32_macros {\n    #[macro_export]\n    macro_rules! cfg_has_atomic_32 {\n        ($($tt:tt)*) => {};\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_32 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n}\n\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(any(\n        all(\n            feature = \"fallback\",\n            any(\n                not(portable_atomic_no_atomic_cas),\n                target_arch = \"avr\",\n                target_arch = \"msp430\",\n                feature = \"critical-section\",\n                portable_atomic_unsafe_assume_single_core,\n            ),\n        ),\n        not(portable_atomic_no_atomic_64),\n        not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")),\n        all(\n            target_arch = \"riscv32\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n        ),\n    ))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(\n        all(\n            feature = \"fallback\",\n            any(\n                target_has_atomic = \"ptr\",\n                target_arch = \"avr\",\n                target_arch = \"msp430\",\n                feature = \"critical-section\",\n                portable_atomic_unsafe_assume_single_core,\n            ),\n        ),\n        target_has_atomic = \"64\",\n        not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")),\n        all(\n            target_arch = \"riscv32\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n        ),\n    ))\n)]\n#[macro_use]\nmod atomic_64_macros {\n    #[macro_export]\n    macro_rules! cfg_has_atomic_64 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_64 {\n        ($($tt:tt)*) => {};\n    }\n}\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(not(any(\n        all(\n            feature = \"fallback\",\n            any(\n                not(portable_atomic_no_atomic_cas),\n                target_arch = \"avr\",\n                target_arch = \"msp430\",\n                feature = \"critical-section\",\n                portable_atomic_unsafe_assume_single_core,\n            ),\n        ),\n        not(portable_atomic_no_atomic_64),\n        not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")),\n        all(\n            target_arch = \"riscv32\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n        ),\n    )))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(not(any(\n        all(\n            feature = \"fallback\",\n            any(\n                target_has_atomic = \"ptr\",\n                target_arch = \"avr\",\n                target_arch = \"msp430\",\n                feature = \"critical-section\",\n                portable_atomic_unsafe_assume_single_core,\n            ),\n        ),\n        target_has_atomic = \"64\",\n        not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")),\n        all(\n            target_arch = \"riscv32\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n        ),\n    )))\n)]\n#[macro_use]\nmod atomic_64_macros {\n    #[macro_export]\n    macro_rules! cfg_has_atomic_64 {\n        ($($tt:tt)*) => {};\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_64 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n}\n\n#[cfg_attr(\n    not(feature = \"fallback\"),\n    cfg(any(\n        all(\n            target_arch = \"aarch64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n        ),\n        all(\n            target_arch = \"arm64ec\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n        ),\n        all(\n            target_arch = \"x86_64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                portable_atomic_no_cmpxchg16b_intrinsic,\n            )),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n        ),\n        all(\n            target_arch = \"riscv64\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n        ),\n        all(\n            target_arch = \"powerpc64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n            any(\n                target_feature = \"quadword-atomics\",\n                portable_atomic_target_feature = \"quadword-atomics\",\n            ),\n        ),\n        all(\n            target_arch = \"s390x\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n        ),\n    ))\n)]\n#[cfg_attr(\n    all(feature = \"fallback\", portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(\n        not(portable_atomic_no_atomic_cas),\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    ))\n)]\n#[cfg_attr(\n    all(feature = \"fallback\", not(portable_atomic_no_cfg_target_has_atomic)),\n    cfg(any(\n        target_has_atomic = \"ptr\",\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    ))\n)]\n#[macro_use]\nmod atomic_128_macros {\n    #[macro_export]\n    macro_rules! cfg_has_atomic_128 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_128 {\n        ($($tt:tt)*) => {};\n    }\n}\n#[cfg_attr(\n    not(feature = \"fallback\"),\n    cfg(not(any(\n        all(\n            target_arch = \"aarch64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n        ),\n        all(\n            target_arch = \"arm64ec\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n        ),\n        all(\n            target_arch = \"x86_64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                portable_atomic_no_cmpxchg16b_intrinsic,\n            )),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n        ),\n        all(\n            target_arch = \"riscv64\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n        ),\n        all(\n            target_arch = \"powerpc64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n            any(\n                target_feature = \"quadword-atomics\",\n                portable_atomic_target_feature = \"quadword-atomics\",\n            ),\n        ),\n        all(\n            target_arch = \"s390x\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n        ),\n    )))\n)]\n#[cfg_attr(\n    all(feature = \"fallback\", portable_atomic_no_cfg_target_has_atomic),\n    cfg(not(any(\n        not(portable_atomic_no_atomic_cas),\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    )))\n)]\n#[cfg_attr(\n    all(feature = \"fallback\", not(portable_atomic_no_cfg_target_has_atomic)),\n    cfg(not(any(\n        target_has_atomic = \"ptr\",\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    )))\n)]\n#[macro_use]\nmod atomic_128_macros {\n    #[macro_export]\n    macro_rules! cfg_has_atomic_128 {\n        ($($tt:tt)*) => {};\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_128 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n}\n\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(any(\n        not(portable_atomic_no_atomic_cas),\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    ))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(\n        target_has_atomic = \"ptr\",\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    ))\n)]\n#[macro_use]\nmod atomic_cas_macros {\n    #[macro_export]\n    macro_rules! cfg_has_atomic_cas {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_cas {\n        ($($tt:tt)*) => {};\n    }\n    // private\n    macro_rules! cfg_has_atomic_cas_or_amo32 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    macro_rules! cfg_has_atomic_cas_or_amo8 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n}\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(not(any(\n        not(portable_atomic_no_atomic_cas),\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    )))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(not(any(\n        target_has_atomic = \"ptr\",\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    )))\n)]\n#[macro_use]\nmod atomic_cas_macros {\n    #[macro_export]\n    macro_rules! cfg_has_atomic_cas {\n        ($($tt:tt)*) => {};\n    }\n    #[macro_export]\n    macro_rules! cfg_no_atomic_cas {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    // private\n    #[cfg_attr(\n        any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n        cfg(not(any(target_feature = \"zaamo\", portable_atomic_target_feature = \"zaamo\")))\n    )]\n    macro_rules! cfg_has_atomic_cas_or_amo32 {\n        ($($tt:tt)*) => {};\n    }\n    #[cfg_attr(\n        any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n        cfg(not(any(target_feature = \"zaamo\", portable_atomic_target_feature = \"zaamo\")))\n    )]\n    macro_rules! cfg_no_atomic_cas_or_amo32 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[cfg(all(\n        any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n        any(target_feature = \"zaamo\", portable_atomic_target_feature = \"zaamo\"),\n    ))]\n    macro_rules! cfg_has_atomic_cas_or_amo32 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[cfg(all(\n        any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n        any(target_feature = \"zaamo\", portable_atomic_target_feature = \"zaamo\"),\n    ))]\n    macro_rules! cfg_no_atomic_cas_or_amo32 {\n        ($($tt:tt)*) => {};\n    }\n    #[cfg_attr(\n        any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n        cfg(not(any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\")))\n    )]\n    #[allow(unused_macros)]\n    macro_rules! cfg_has_atomic_cas_or_amo8 {\n        ($($tt:tt)*) => {};\n    }\n    #[cfg_attr(\n        any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n        cfg(not(any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\")))\n    )]\n    #[cfg_attr(target_arch = \"bpf\", allow(unused_macros))]\n    macro_rules! cfg_no_atomic_cas_or_amo8 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[cfg(all(\n        any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n        any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\"),\n    ))]\n    macro_rules! cfg_has_atomic_cas_or_amo8 {\n        ($($tt:tt)*) => {\n            $($tt)*\n        };\n    }\n    #[cfg(all(\n        any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n        any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\"),\n    ))]\n    macro_rules! cfg_no_atomic_cas_or_amo8 {\n        ($($tt:tt)*) => {};\n    }\n}\n\nmacro_rules! cfg_core_atomic {\n    ($($tt:tt)*) => {\n        #[cfg(not(any(\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            all(\n                portable_atomic_no_atomic_load_store,\n                not(all(target_arch = \"bpf\", not(feature = \"critical-section\"))),\n            ),\n        )))]\n        #[cfg_attr(\n            portable_atomic_no_cfg_target_has_atomic,\n            cfg(not(all(\n                any(\n                    target_arch = \"riscv32\",\n                    target_arch = \"riscv64\",\n                    feature = \"critical-section\",\n                    portable_atomic_unsafe_assume_single_core,\n                ),\n                portable_atomic_no_atomic_cas,\n            )))\n        )]\n        #[cfg_attr(\n            not(portable_atomic_no_cfg_target_has_atomic),\n            cfg(not(all(\n                any(\n                    target_arch = \"riscv32\",\n                    target_arch = \"riscv64\",\n                    feature = \"critical-section\",\n                    portable_atomic_unsafe_assume_single_core,\n                ),\n                not(target_has_atomic = \"ptr\"),\n            )))\n        )]\n        items!($($tt)*);\n    };\n}\n\n// Check that all cfg_ macros work.\nmod check {\n    crate::cfg_has_atomic_8! { type _Atomic8 = (); }\n    crate::cfg_no_atomic_8! { type _Atomic8 = (); }\n    crate::cfg_has_atomic_16! { type _Atomic16 = (); }\n    crate::cfg_no_atomic_16! { type _Atomic16 = (); }\n    crate::cfg_has_atomic_32! { type _Atomic32 = (); }\n    crate::cfg_no_atomic_32! { type _Atomic32 = (); }\n    crate::cfg_has_atomic_64! { type _Atomic64 = (); }\n    crate::cfg_no_atomic_64! { type _Atomic64 = (); }\n    crate::cfg_has_atomic_128! { type _Atomic128 = (); }\n    crate::cfg_no_atomic_128! { type _Atomic128 = (); }\n    crate::cfg_has_atomic_ptr! { type _AtomicPtr = (); }\n    crate::cfg_no_atomic_ptr! { type _AtomicPtr = (); }\n    crate::cfg_has_atomic_cas! { type __AtomicPtr = (); }\n    crate::cfg_no_atomic_cas! { type __AtomicPtr = (); }\n    #[allow(unused_imports)]\n    use self::{\n        __AtomicPtr as _, _Atomic8 as _, _Atomic16 as _, _Atomic32 as _, _Atomic64 as _,\n        _Atomic128 as _, _AtomicPtr as _,\n    };\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/gen/build.rs",
      "sha256": "4ad2fa43f8f725631e9754338f39b80f64a2e61facdb3bd735efc215b95a6597",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n// This file is @generated by target_spec.sh.\n// It is not intended for manual editing.\n\n// Note: This is the list as of nightly-2022-02-10. We don't refer to this in\n// nightly-2022-02-11+ because feature(cfg_target_has_atomic) stabilized.\n#[rustfmt::skip]\npub(crate) static NO_ATOMIC_CAS: &[&str] = &[\n    \"avr-unknown-gnu-atmega328\",\n    \"bpfeb-unknown-none\",\n    \"bpfel-unknown-none\",\n    \"msp430-none-elf\",\n    \"riscv32i-unknown-none-elf\",\n    \"riscv32imc-unknown-none-elf\",\n    \"thumbv4t-none-eabi\",\n    \"thumbv6m-none-eabi\",\n];\n\n// Note: This is the list as of nightly-2022-02-10. We don't refer to this in\n// nightly-2022-02-11+ because feature(cfg_target_has_atomic) stabilized.\n#[rustfmt::skip]\npub(crate) static NO_ATOMIC_64: &[&str] = &[\n    \"arm-linux-androideabi\",\n    \"armebv7r-none-eabi\",\n    \"armebv7r-none-eabihf\",\n    \"armv4t-unknown-linux-gnueabi\",\n    \"armv5te-unknown-linux-gnueabi\",\n    \"armv5te-unknown-linux-musleabi\",\n    \"armv5te-unknown-linux-uclibceabi\",\n    \"armv6k-nintendo-3ds\",\n    \"armv7r-none-eabi\",\n    \"armv7r-none-eabihf\",\n    \"avr-unknown-gnu-atmega328\",\n    \"hexagon-unknown-linux-musl\",\n    \"m68k-unknown-linux-gnu\",\n    \"mips-unknown-linux-gnu\",\n    \"mips-unknown-linux-musl\",\n    \"mips-unknown-linux-uclibc\",\n    \"mipsel-sony-psp\",\n    \"mipsel-unknown-linux-gnu\",\n    \"mipsel-unknown-linux-musl\",\n    \"mipsel-unknown-linux-uclibc\",\n    \"mipsel-unknown-none\",\n    \"mipsisa32r6-unknown-linux-gnu\",\n    \"mipsisa32r6el-unknown-linux-gnu\",\n    \"msp430-none-elf\",\n    \"powerpc-unknown-freebsd\",\n    \"powerpc-unknown-linux-gnu\",\n    \"powerpc-unknown-linux-gnuspe\",\n    \"powerpc-unknown-linux-musl\",\n    \"powerpc-unknown-netbsd\",\n    \"powerpc-unknown-openbsd\",\n    \"powerpc-wrs-vxworks\",\n    \"powerpc-wrs-vxworks-spe\",\n    \"riscv32gc-unknown-linux-gnu\",\n    \"riscv32gc-unknown-linux-musl\",\n    \"riscv32i-unknown-none-elf\",\n    \"riscv32imac-unknown-none-elf\",\n    \"riscv32imc-esp-espidf\",\n    \"riscv32imc-unknown-none-elf\",\n    \"thumbv4t-none-eabi\",\n    \"thumbv6m-none-eabi\",\n    \"thumbv7em-none-eabi\",\n    \"thumbv7em-none-eabihf\",\n    \"thumbv7m-none-eabi\",\n    \"thumbv8m.base-none-eabi\",\n    \"thumbv8m.main-none-eabi\",\n    \"thumbv8m.main-none-eabihf\",\n];\n\n#[rustfmt::skip]\npub(crate) static NO_ATOMIC: &[&str] = &[\n    \"armv4t-none-eabi\",\n    \"armv5te-none-eabi\",\n    \"bpfeb-unknown-none\",\n    \"bpfel-unknown-none\",\n    \"mipsel-sony-psx\",\n    \"thumbv4t-none-eabi\",\n    \"thumbv5te-none-eabi\",\n];\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/gen/utils.rs",
      "sha256": "c44ee71296aaa90c8104339e470688f631a2380d7f10349c7766205c415050aa",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n// This file is @generated by target_spec.sh.\n// It is not intended for manual editing.\n\n#![allow(dead_code, unused_macros)]\n\n// On AArch64, the base register of memory-related instructions must be 64-bit.\n// Passing a 32-bit value to `in(reg)` on AArch64 results in the upper bits\n// having an undefined value, but to work correctly with ILP32 ABI, the upper\n// bits must be zero, which is handled here by casting to u64. Another way to\n// handle this is to pass it as a pointer and clear the upper bits inside asm,\n// but it is easier to overlook than cast, which can catch overlooks by\n// asm_sub_register lint.\n// See also https://github.com/ARM-software/abi-aa/blob/2025Q4/aapcs64/aapcs64.rst#pointers\n//\n// Except for x86_64, which can use 32-bit registers in the destination operand\n// (on x86_64, we use the ptr_modifier macro to handle this), we need to do the\n// same for ILP32 ABI on other 64-bit architectures. (At least, as far as I can\n// see from the assembly generated by LLVM, this is also required for MIPS64 N32\n// ABI. I don't know about other similar ABIs, but in any case, this should be\n// a safe default for such ABIs).\n//\n// Known architectures that have such ABI are x86_64 (X32), AArch64 (ILP32),\n// mips64/mips64r6 (N32), riscv64 (RV64ILP32*), PowerPC64 (Lv2). (As of\n// 2026-03-22, only the former two are supported by rustc.) However, we list\n// all known 64-bit architectures because similar ABIs may exist or future added\n// for other architectures.\n#[cfg(all(\n    target_pointer_width = \"32\",\n    any(\n        target_arch = \"aarch64\",\n        target_arch = \"amdgpu\",\n        target_arch = \"arm64ec\",\n        target_arch = \"bpf\",\n        target_arch = \"loongarch64\",\n        target_arch = \"mips64\",\n        target_arch = \"mips64r6\",\n        target_arch = \"nvptx64\",\n        target_arch = \"powerpc64\",\n        target_arch = \"riscv64\",\n        target_arch = \"s390x\",\n        target_arch = \"sparc64\",\n        target_arch = \"wasm64\",\n        target_arch = \"x86_64\",\n    ),\n))]\n#[macro_use]\nmod imp {\n    #[cfg(not(any(target_arch = \"x86\", target_arch = \"x86_64\")))]\n    macro_rules! ptr_reg {\n        ($ptr:ident) => {{\n            let _: *const _ = $ptr; // ensure $ptr is a pointer (*mut _ or *const _)\n            #[cfg(not(portable_atomic_no_asm_maybe_uninit))]\n            #[allow(clippy::ptr_as_ptr)]\n            {\n                // If we cast to u64 here, the provenance will be lost,\n                // so we convert to MaybeUninit<u64> via zero extend helper.\n                crate::utils::zero_extend64_ptr($ptr as *mut ())\n            }\n            #[cfg(portable_atomic_no_asm_maybe_uninit)]\n            {\n                // Use cast on old rustc because it does not support MaybeUninit\n                // registers. This is still permissive-provenance compatible and\n                // is sound.\n                $ptr as u64\n            }\n        }};\n    }\n    pub(crate) type RegISize = i64;\n    pub(crate) type RegSize = u64;\n}\n#[cfg(not(all(\n    target_pointer_width = \"32\",\n    any(\n        target_arch = \"aarch64\",\n        target_arch = \"amdgpu\",\n        target_arch = \"arm64ec\",\n        target_arch = \"bpf\",\n        target_arch = \"loongarch64\",\n        target_arch = \"mips64\",\n        target_arch = \"mips64r6\",\n        target_arch = \"nvptx64\",\n        target_arch = \"powerpc64\",\n        target_arch = \"riscv64\",\n        target_arch = \"s390x\",\n        target_arch = \"sparc64\",\n        target_arch = \"wasm64\",\n        target_arch = \"x86_64\",\n    ),\n)))]\n#[macro_use]\nmod imp {\n    #[cfg(not(any(target_arch = \"x86\", target_arch = \"x86_64\")))]\n    macro_rules! ptr_reg {\n        ($ptr:ident) => {{\n            let _: *const _ = $ptr; // ensure $ptr is a pointer (*mut _ or *const _)\n            $ptr // cast is unnecessary here.\n        }};\n    }\n    pub(crate) type RegISize = isize;\n    pub(crate) type RegSize = usize;\n}\npub(crate) use self::imp::{RegISize, RegSize};\n\n// Some 64-bit architectures have ABI with 32-bit pointer width (e.g., x86_64 X32 ABI,\n// AArch64 ILP32 ABI, MIPS64 N32 ABI). On those targets, AtomicU64 is available\n// and fast, so use it to implement normal sequence lock.\n//\n// See ptr_reg macro for the reason why all known 64-bit architectures are listed.\n//\n// Note: These macros are cfg_*!({ }), not cfg_*! { }.\n// An extra brace is used in input to make contents rustfmt-able.\n#[cfg(any(\n    not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")), // i.e., 64-bit or greater\n    target_arch = \"aarch64\",\n    target_arch = \"amdgpu\",\n    target_arch = \"arm64ec\",\n    target_arch = \"bpf\",\n    target_arch = \"loongarch64\",\n    target_arch = \"mips64\",\n    target_arch = \"mips64r6\",\n    target_arch = \"nvptx64\",\n    target_arch = \"powerpc64\",\n    target_arch = \"riscv64\",\n    target_arch = \"s390x\",\n    target_arch = \"sparc64\",\n    target_arch = \"wasm64\",\n    target_arch = \"x86_64\",\n))]\n#[macro_use]\nmod fast_atomic_64_macros {\n    macro_rules! cfg_has_fast_atomic_64 {\n        ({$($tt:tt)*}) => {\n            $($tt)*\n        };\n    }\n    macro_rules! cfg_no_fast_atomic_64 {\n        ({$($tt:tt)*}) => {};\n    }\n}\n#[cfg(not(any(\n    not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")), // i.e., 64-bit or greater\n    target_arch = \"aarch64\",\n    target_arch = \"amdgpu\",\n    target_arch = \"arm64ec\",\n    target_arch = \"bpf\",\n    target_arch = \"loongarch64\",\n    target_arch = \"mips64\",\n    target_arch = \"mips64r6\",\n    target_arch = \"nvptx64\",\n    target_arch = \"powerpc64\",\n    target_arch = \"riscv64\",\n    target_arch = \"s390x\",\n    target_arch = \"sparc64\",\n    target_arch = \"wasm64\",\n    target_arch = \"x86_64\",\n)))]\n#[macro_use]\nmod fast_atomic_64_macros {\n    macro_rules! cfg_has_fast_atomic_64 {\n        ({$($tt:tt)*}) => {};\n    }\n    macro_rules! cfg_no_fast_atomic_64 {\n        ({$($tt:tt)*}) => {\n            $($tt)*\n        };\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/arm_linux.rs",
      "sha256": "6f5ba9542ec89340444094ee4c96503dec7476c38d308abd1b09168785d672c5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nAtomic operations implementation on pre-v6 ARM Linux/Android.\n\nThis module optimizes cases where LLVM code generation is not optimal,\nand provides workaround for core::sync::atomic bug (https://github.com/rust-lang/compiler-builtins/pull/1234).\n\nSee \"Atomic operation overview by architecture\" in atomic-maybe-uninit for a more comprehensive and\ndetailed description of the atomic and synchronize instructions in this architecture:\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#arm\n\nRefs:\n- https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm/kernel_user_helpers.rst\n- https://github.com/rust-lang/compiler-builtins/blob/compiler_builtins-v0.1.124/src/arm_linux.rs\n- https://github.com/taiki-e/atomic-maybe-uninit\n\nNote: __kuser_memory_barrier is always SeqCst.\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/v0.3.21/src/arch/arm.rs#L215\n\nNote: On Miri and ThreadSanitizer which do not go through compiler-builtins, we don't use\nthis module and use normal core::sync::atomic instead.\n*/\n\nuse core::{mem, sync::atomic::Ordering};\n\n// https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm/kernel_user_helpers.rst\n// __kuser_helper_version >= 3 (kernel version 2.6.15+)\nconst KUSER_MEMORY_BARRIER: usize = 0xFFFF0FA0;\n#[inline]\nfn __kuser_memory_barrier() {\n    // SAFETY: kernel docs specify a known address with the given signature.\n    // core assumes __kuser_helper_version >= 3.\n    unsafe {\n        let f: extern \"C\" fn() =\n            mem::transmute(crate::utils::ptr::with_exposed_provenance::<()>(KUSER_MEMORY_BARRIER));\n        f();\n    }\n}\n\n/// An atomic fence.\n///\n/// # Panics\n///\n/// Panics if `order` is [`Relaxed`](Ordering::Relaxed).\n#[cfg_attr(doc, allow(dead_code))]\n#[inline]\n#[cfg_attr(any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri), track_caller)]\npub fn fence(order: Ordering) {\n    // Call __kuser_memory_barrier without going through __sync_synchronize.\n    match order {\n        Ordering::Relaxed => panic!(\"there is no such thing as a relaxed fence\"),\n        _ => __kuser_memory_barrier(),\n    }\n}\n\ncfg_core_atomic!({\n    use super::core_atomic::{\n        AtomicI8, AtomicI16, AtomicI32, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16, AtomicU32,\n        AtomicUsize,\n    };\n    macro_rules! atomic {\n        ($([$($generics:tt)*])? $atomic_type:ident, $value_type:ty) => {\n            impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub(crate) fn load(&self, order: Ordering) -> $value_type {\n                    crate::utils::assert_load_ordering(order);\n                    match order {\n                        Ordering::Relaxed => self.inner.load(Ordering::Relaxed),\n                        // Acquire and SeqCst loads are equivalent.\n                        // This matches with LLVM, but GCC emits `dmb; ldr*; dmb` for SeqCst load.\n                        Ordering::Acquire | Ordering::SeqCst => {\n                            let out = self.inner.load(Ordering::Relaxed);\n                            __kuser_memory_barrier();\n                            out\n                        }\n                        _ => unreachable!(),\n                    }\n                }\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub(crate) fn store(&self, val: $value_type, order: Ordering) {\n                    crate::utils::assert_store_ordering(order);\n                    match order {\n                        Ordering::Relaxed => self.inner.store(val, Ordering::Relaxed),\n                        Ordering::Release => {\n                            __kuser_memory_barrier();\n                            self.inner.store(val, Ordering::Relaxed);\n                        }\n                        Ordering::SeqCst => {\n                            __kuser_memory_barrier();\n                            self.inner.store(val, Ordering::Relaxed);\n                            __kuser_memory_barrier();\n                        }\n                        _ => unreachable!(),\n                    }\n                }\n            }\n            #[cfg_attr(\n                portable_atomic_no_cfg_target_has_atomic,\n                cfg(not(portable_atomic_no_atomic_cas))\n            )]\n            #[cfg_attr(\n                not(portable_atomic_no_cfg_target_has_atomic),\n                cfg(target_has_atomic = \"ptr\")\n            )]\n            impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub(crate) fn compare_exchange(\n                    &self,\n                    current: $value_type,\n                    new: $value_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$value_type, $value_type> {\n                    crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check)\n                    #[cfg(portable_atomic_no_stronger_failure_ordering)]\n                    let success = crate::utils::upgrade_success_ordering(success, failure);\n                    let res = self.inner.compare_exchange(current, new, success, failure);\n                    if failure != Ordering::Relaxed && res.is_err() {\n                        __kuser_memory_barrier();\n                    }\n                    res\n                }\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub(crate) fn compare_exchange_weak(\n                    &self,\n                    current: $value_type,\n                    new: $value_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$value_type, $value_type> {\n                    crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check)\n                    #[cfg(portable_atomic_no_stronger_failure_ordering)]\n                    let success = crate::utils::upgrade_success_ordering(success, failure);\n                    let res = self.inner.compare_exchange_weak(current, new, success, failure);\n                    if failure != Ordering::Relaxed && res.is_err() {\n                        __kuser_memory_barrier();\n                    }\n                    res\n                }\n            }\n        };\n    }\n\n    atomic!(AtomicI8, i8);\n    atomic!(AtomicU8, u8);\n    atomic!(AtomicI16, i16);\n    atomic!(AtomicU16, u16);\n    atomic!(AtomicI32, i32);\n    atomic!(AtomicU32, u32);\n    atomic!(AtomicIsize, isize);\n    atomic!(AtomicUsize, usize);\n    atomic!([T] AtomicPtr, *mut T);\n});\n\n#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not(portable_atomic_no_atomic_64)))]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(\n        target_has_atomic = \"64\",\n        not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")),\n    ))\n)]\nitems!({\n    // This is not normally reached on this platform.\n    // It is only reached if something strange occurs, such as using target-feature=-v6 on armv6 target.\n    // Since 64-bit atomic operations differ from 32-bit or smaller ones on Arm, similar optimizations\n    // or workarounds are useless here, so do the same as atomic_int! macro in core_atomic.rs.\n    // NB: Sync with atomic_int! macro in core_atomic.rs\n    use super::core_atomic::{AtomicI64, AtomicU64};\n    macro_rules! atomic_int {\n        ($atomic_type:ident, $int_type:ident) => {\n            impl $atomic_type {\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub(crate) fn load(&self, order: Ordering) -> $int_type {\n                    crate::utils::assert_load_ordering(order); // for track_caller (compiler can omit double check)\n                    self.inner.load(order)\n                }\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub(crate) fn store(&self, val: $int_type, order: Ordering) {\n                    crate::utils::assert_store_ordering(order); // for track_caller (compiler can omit double check)\n                    self.inner.store(val, order);\n                }\n            }\n            #[cfg_attr(\n                portable_atomic_no_cfg_target_has_atomic,\n                cfg(not(portable_atomic_no_atomic_cas))\n            )]\n            #[cfg_attr(\n                not(portable_atomic_no_cfg_target_has_atomic),\n                cfg(target_has_atomic = \"ptr\")\n            )]\n            impl $atomic_type {\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub(crate) fn compare_exchange(\n                    &self,\n                    current: $int_type,\n                    new: $int_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$int_type, $int_type> {\n                    crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check)\n                    #[cfg(portable_atomic_no_stronger_failure_ordering)]\n                    let success = crate::utils::upgrade_success_ordering(success, failure);\n                    self.inner.compare_exchange(current, new, success, failure)\n                }\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub(crate) fn compare_exchange_weak(\n                    &self,\n                    current: $int_type,\n                    new: $int_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$int_type, $int_type> {\n                    crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check)\n                    #[cfg(portable_atomic_no_stronger_failure_ordering)]\n                    let success = crate::utils::upgrade_success_ordering(success, failure);\n                    self.inner.compare_exchange_weak(current, new, success, failure)\n                }\n            }\n        };\n    }\n    atomic_int!(AtomicI64, i64);\n    atomic_int!(AtomicU64, u64);\n});\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic128/aarch64.rs",
      "sha256": "8fe3bebbf1a7991b35e6ffeb796ff872bc15edcdbbdcf7a5835cb2b1ce149542",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\n128-bit atomic implementation on AArch64.\n\nThis architecture provides the following 128-bit atomic instructions:\n\n- LDXP/STXP: LL/SC (Armv8.0 baseline)\n- CASP: CAS (added as Armv8.1 FEAT_LSE (optional from Armv8.0, mandatory from Armv8.1))\n- LDP/STP: load/store (if Armv8.4 FEAT_LSE2 (optional from Armv8.2, mandatory from Armv8.4) is available)\n- LDIAPP/STILP: acquire-load/release-store (added as Armv8.9 FEAT_LRCPC3 (optional from Armv8.2) (if FEAT_LSE2 is also available))\n- LDCLRP/LDSETP/SWPP: fetch-and-{clear,or},swap (added as Armv9.4 FEAT_LSE128 (optional from Armv9.3))\n\nSee \"Atomic operation overview by architecture\" in atomic-maybe-uninit for a more comprehensive and\ndetailed description of the atomic and synchronize instructions in this architecture:\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#aarch64\n\nThis module supports all of these instructions and attempts to select the best\none based on compile-time and run-time information about available CPU features\nand platforms. For example:\n\n- If outline-atomics is not enabled and FEAT_LSE is not available at\n  compile-time, we use LDXP/STXP loop.\n- If outline-atomics is enabled and FEAT_LSE is not available at\n  compile-time, we use CASP for CAS if FEAT_LSE is available\n  at run-time, otherwise, use LDXP/STXP loop.\n- If FEAT_LSE is available at compile-time, we use CASP for load/store/CAS/RMW.\n  However, when portable_atomic_ll_sc_rmw cfg is set, use LDXP/STXP loop instead of CASP\n  loop for RMW (by default, it is set on Apple hardware where CASP is slow;\n  see build script for details).\n- If outline-atomics is enabled and FEAT_LSE2 is not available at compile-time,\n  we use LDP/STP (and also LDIAPP/STILP/SWPP if FEAT_LRCPC3/FEAT_LSE128 is\n  available) for load/store if FEAT_LSE2 is available at run-time, otherwise,\n  use LDXP/STXP or CASP depending on whether FEAT_LSE is available.\n- If FEAT_LSE2 is available at compile-time, we use LDP/STP for load/store.\n- If FEAT_LSE128 is available at compile-time, we use LDCLRP/LDSETP/SWPP for fetch_and/fetch_or/swap/{release,seqcst}-store.\n- If FEAT_LSE2 and FEAT_LRCPC3 are available at compile-time, we use LDIAPP/STILP for acquire-load/release-store.\n\nSee each \"Instruction selection flow for ...\" comment in this file for the exact\ninstruction selection per operation.\n\nNote: FEAT_LSE2 doesn't imply FEAT_LSE. FEAT_LSE128 implies FEAT_LSE but not FEAT_LSE2.\n\nNote that we do not separate LL and SC into separate functions, but handle\nthem within a single asm block. This is because it is theoretically possible\nfor the compiler to insert operations that might clear the reservation between\nLL and SC. Considering the type of operations we are providing and the fact\nthat [progress64](https://github.com/ARM-software/progress64) uses such code,\nthis is probably not a problem for AArch64, but it seems that AArch64 doesn't\nguarantee it and hexagon is the only architecture with hardware guarantees\nthat such code works. See also:\n\n- https://yarchive.net/comp/linux/cmpxchg_ll_sc_portability.html\n- https://lists.llvm.org/pipermail/llvm-dev/2016-May/099490.html\n- https://lists.llvm.org/pipermail/llvm-dev/2018-June/123993.html\n\nAlso, even when using a CAS loop to implement atomic RMW, include the loop itself\nin the asm block because it is more efficient for some codegen backends.\nhttps://github.com/rust-lang/compiler-builtins/issues/339#issuecomment-1191260474\n\nNote: On Miri and ThreadSanitizer which do not support inline assembly, we don't use\nthis module and use intrinsics.rs instead.\n\nRefs:\n- Arm A-profile A64 Instruction Set Architecture\n  https://developer.arm.com/documentation/ddi0602/2025-06\n- C/C++ Atomics Application Binary Interface Standard for the Arm® 64-bit Architecture\n  https://github.com/ARM-software/abi-aa/blob/2025Q4/atomicsabi64/atomicsabi64.rst\n- Arm Compiler armasm User Guide\n  https://developer.arm.com/documentation/dui0801/latest\n- Arm Architecture Reference Manual for A-profile architecture\n  https://developer.arm.com/documentation/ddi0487/latest (PDF)\n- Arm Architecture Reference Manual Supplement - Armv8, for Armv8-R AArch64 architecture profile\n  https://developer.arm.com/documentation/ddi0600/latest (PDF)\n- atomic-maybe-uninit https://github.com/taiki-e/atomic-maybe-uninit\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\ninclude!(\"macros.rs\");\n\n// On musl with static linking, it seems that getauxval is not always available.\n// See detect/auxv.rs for more.\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(\n    test,\n    not(all(\n        any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n        any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\"),\n    )),\n))]\n#[cfg(any(\n    all(\n        target_os = \"linux\",\n        any(\n            target_env = \"gnu\",\n            all(target_env = \"musl\", any(not(target_feature = \"crt-static\"), feature = \"std\")),\n            target_env = \"ohos\",\n            all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n            portable_atomic_outline_atomics,\n        ),\n    ),\n    target_os = \"android\",\n    target_os = \"freebsd\",\n))]\n#[path = \"../detect/auxv.rs\"]\nmod detect;\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(\n    test,\n    not(all(\n        any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n        any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\"),\n    )),\n))]\n#[cfg(any(target_os = \"netbsd\", target_os = \"openbsd\"))]\n#[path = \"../detect/aarch64_aa64reg.rs\"]\nmod detect;\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(\n    test,\n    not(all(\n        any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\"),\n        any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n    )),\n))]\n#[cfg(target_os = \"illumos\")]\n#[path = \"../detect/aarch64_illumos.rs\"]\nmod detect;\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(test, not(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"))))]\n#[cfg(target_os = \"fuchsia\")]\n#[path = \"../detect/aarch64_fuchsia.rs\"]\nmod detect;\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(\n    test,\n    not(all(\n        any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\"),\n        any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n    )),\n))]\n#[cfg(target_vendor = \"apple\")]\n#[path = \"../detect/aarch64_apple.rs\"]\nmod detect;\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(\n    test,\n    not(all(\n        any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\"),\n        any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n    )),\n))]\n#[cfg(windows)]\n#[path = \"../detect/aarch64_windows.rs\"]\nmod detect;\n\n#[cfg(test)] // test-only (we use auxv.rs instead)\n#[cfg(not(valgrind))]\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(target_os = \"linux\", target_os = \"android\", target_os = \"freebsd\"))]\n#[path = \"../detect/aarch64_aa64reg.rs\"]\nmod test_detect_aa64reg;\n#[cfg(test)] // test-only (we use aarch64_aa64reg.rs instead)\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(target_os = \"openbsd\")]\n#[path = \"../detect/auxv.rs\"]\nmod test_detect_auxv;\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\nuse core::sync::atomic::Ordering;\n\n#[cfg(portable_atomic_no_strict_provenance)]\nuse crate::utils::ptr::PtrExt as _;\nuse crate::utils::{Pair, U128};\n\n#[cfg(any(\n    target_feature = \"lse\",\n    portable_atomic_target_feature = \"lse\",\n    not(portable_atomic_no_outline_atomics),\n))]\n#[rustfmt::skip]\nmacro_rules! debug_assert_lse {\n    () => {\n        #[cfg(all(\n            not(portable_atomic_no_outline_atomics),\n            any(\n                all(\n                    target_os = \"linux\",\n                    any(\n                        target_env = \"gnu\",\n                        all(\n                            target_env = \"musl\",\n                            any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                        ),\n                        target_env = \"ohos\",\n                        all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                        portable_atomic_outline_atomics,\n                    ),\n                ),\n                target_os = \"android\",\n                target_os = \"freebsd\",\n                target_os = \"netbsd\",\n                target_os = \"openbsd\",\n                target_os = \"illumos\",\n                target_os = \"fuchsia\",\n                target_vendor = \"apple\",\n                windows,\n            ),\n        ))]\n        #[cfg(not(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\")))]\n        {\n            debug_assert!(detect::detect().lse());\n        }\n    };\n}\n#[cfg(any(\n    target_feature = \"lse2\",\n    portable_atomic_target_feature = \"lse2\",\n    not(portable_atomic_no_outline_atomics),\n))]\n#[rustfmt::skip]\nmacro_rules! debug_assert_lse2 {\n    () => {\n        #[cfg(all(\n            not(portable_atomic_no_outline_atomics),\n            any(\n                all(\n                    target_os = \"linux\",\n                    any(\n                        target_env = \"gnu\",\n                        all(\n                            target_env = \"musl\",\n                            any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                        ),\n                        target_env = \"ohos\",\n                        all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                        portable_atomic_outline_atomics,\n                    ),\n                ),\n                target_os = \"android\",\n                target_os = \"freebsd\",\n                target_os = \"netbsd\",\n                target_os = \"openbsd\",\n                target_os = \"illumos\",\n                // These don't support detection of FEAT_LSE2.\n                // target_os = \"fuchsia\",\n                target_vendor = \"apple\",\n                windows,\n            ),\n        ))]\n        #[cfg(not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")))]\n        {\n            debug_assert!(detect::detect().lse2());\n        }\n    };\n}\n#[cfg(any(\n    target_feature = \"lse128\",\n    portable_atomic_target_feature = \"lse128\",\n    all(\n        not(portable_atomic_no_outline_atomics),\n        not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")),\n    ),\n))]\n#[rustfmt::skip]\nmacro_rules! debug_assert_lse128 {\n    () => {\n        #[cfg(all(\n            not(portable_atomic_no_outline_atomics),\n            any(\n                all(\n                    target_os = \"linux\",\n                    any(\n                        target_env = \"gnu\",\n                        all(\n                            target_env = \"musl\",\n                            any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                        ),\n                        target_env = \"ohos\",\n                        all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                        portable_atomic_outline_atomics,\n                    ),\n                ),\n                target_os = \"android\",\n                target_os = \"freebsd\",\n                target_os = \"netbsd\",\n                target_os = \"openbsd\",\n                target_os = \"illumos\",\n                // These don't support detection of FEAT_LSE128.\n                // target_os = \"fuchsia\",\n                target_vendor = \"apple\",\n                windows,\n            ),\n        ))]\n        #[cfg(not(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\")))]\n        {\n            debug_assert!(detect::detect().lse128());\n        }\n    };\n}\n#[cfg(any(\n    target_feature = \"rcpc3\",\n    portable_atomic_target_feature = \"rcpc3\",\n    all(\n        not(portable_atomic_no_outline_atomics),\n        not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")),\n    ),\n))]\n#[rustfmt::skip]\nmacro_rules! debug_assert_rcpc3 {\n    () => {\n        #[cfg(all(\n            not(portable_atomic_no_outline_atomics),\n            any(\n                all(\n                    target_os = \"linux\",\n                    any(\n                        target_env = \"gnu\",\n                        all(\n                            target_env = \"musl\",\n                            any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                        ),\n                        target_env = \"ohos\",\n                        all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                        portable_atomic_outline_atomics,\n                    ),\n                ),\n                target_os = \"android\",\n                target_os = \"freebsd\",\n                target_os = \"netbsd\",\n                target_os = \"openbsd\",\n                target_os = \"illumos\",\n                // These don't support detection of FEAT_LRCPC3.\n                // target_os = \"fuchsia\",\n                target_vendor = \"apple\",\n                windows,\n            ),\n        ))]\n        #[cfg(not(any(target_feature = \"rcpc3\", portable_atomic_target_feature = \"rcpc3\")))]\n        {\n            debug_assert!(detect::detect().rcpc3());\n        }\n    };\n}\n\n// Refs: https://developer.arm.com/documentation/100067/0611/armclang-Integrated-Assembler/AArch32-Target-selection-directives\n//\n// This is similar to #[target_feature(enable = \"lse\")], except that there are\n// no compiler guarantees regarding (un)inlining, and the scope is within an asm\n// block rather than a function. We use this directive because #[target_feature(enable = \"lse\")]\n// is unstable on pre-1.61 rustc and incompatible with rustc_codegen_cranelift:\n// https://github.com/rust-lang/rustc_codegen_cranelift/issues/1400#issuecomment-1774599775\n//\n// The .arch_extension directive in asm! is effective until the end of the assembly block and\n// is not propagated to subsequent code, so the end_lse macro is unneeded.\n// https://godbolt.org/z/o6EPndP94\n// https://github.com/torvalds/linux/commit/e0d5896bd356cd577f9710a02d7a474cdf58426b\n// https://github.com/torvalds/linux/commit/dd1f6308b28edf0452dd5dc7877992903ec61e69\n// (It seems GCC effectively ignores this directive and always allow FEAT_LSE instructions: https://godbolt.org/z/W9W6rensG)\n// Note that the .arch_extension directive in global_asm!/naked_asm! which are\n// not used in this crate has different behavior: https://github.com/rust-lang/rust/pull/137720#discussion_r1973608259\n// Note that this directive currently cannot be used correctly with global_asm!/naked_asm!\n// due to LLVM bug: https://github.com/rust-lang/rust/pull/137720#discussion_r2014505753\n//\n// The .arch directive has a similar effect, but we don't use it due to the following issue:\n// https://github.com/torvalds/linux/commit/dd1f6308b28edf0452dd5dc7877992903ec61e69\n//\n// Note: If FEAT_LSE is not available at compile-time, we must guarantee that\n// the function that uses it is not inlined into a function where it is not\n// clear whether FEAT_LSE is available. Otherwise, (even if we checked whether\n// FEAT_LSE is available at run-time) optimizations that reorder its\n// instructions across the if condition might introduce undefined behavior.\n// (see also https://rust-lang.github.io/rfcs/2045-target-feature.html#safely-inlining-target_feature-functions-on-more-contexts)\n// However, our code uses the ifunc helper macro that works with function pointers,\n// so we don't have to worry about this unless calling without helper macro.\n#[cfg(any(\n    target_feature = \"lse\",\n    portable_atomic_target_feature = \"lse\",\n    not(portable_atomic_no_outline_atomics),\n))]\nmacro_rules! start_lse {\n    () => {\n        \".arch_extension lse\"\n    };\n}\n#[cfg(not(portable_atomic_pre_llvm_16))]\n#[cfg(any(\n    target_feature = \"lse128\",\n    portable_atomic_target_feature = \"lse128\",\n    all(\n        not(portable_atomic_no_outline_atomics),\n        not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")),\n    ),\n))]\nmacro_rules! start_lse128 {\n    () => {\n        \".arch_extension lse128\"\n    };\n}\n#[cfg(not(portable_atomic_pre_llvm_16))]\n#[cfg(any(\n    target_feature = \"rcpc3\",\n    portable_atomic_target_feature = \"rcpc3\",\n    all(\n        not(portable_atomic_no_outline_atomics),\n        not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")),\n    ),\n))]\nmacro_rules! start_rcpc3 {\n    () => {\n        \".arch_extension rcpc3\"\n    };\n}\n\n#[cfg(target_endian = \"little\")]\nmacro_rules! select_le_or_be {\n    ($le:expr, $be:expr) => {\n        $le\n    };\n}\n#[cfg(target_endian = \"big\")]\nmacro_rules! select_le_or_be {\n    ($le:expr, $be:expr) => {\n        $be\n    };\n}\n\nmacro_rules! atomic_rmw {\n    ($op:ident, $order:ident) => {\n        atomic_rmw!($op, $order, write = $order)\n    };\n    ($op:ident, $order:ident, write = $write:ident) => {\n        match $order {\n            Ordering::Relaxed => $op!(\"\", \"\", \"\"),\n            Ordering::Acquire => $op!(\"a\", \"\", \"\"),\n            Ordering::Release => $op!(\"\", \"l\", \"\"),\n            Ordering::AcqRel => $op!(\"a\", \"l\", \"\"),\n            // In MSVC environments, SeqCst stores/writes by non-LSE* instructions needs fences after writes.\n            // https://reviews.llvm.org/D141748\n            // https://github.com/llvm/llvm-project/commit/1ea201d73be2fdf03347e9c6be09ebed5f8e0e00\n            #[cfg(target_env = \"msvc\")]\n            Ordering::SeqCst if $write == Ordering::SeqCst => $op!(\"a\", \"l\", \"dmb ish\"),\n            // AcqRel and SeqCst RMWs are equivalent in non-MSVC environments.\n            Ordering::SeqCst => $op!(\"a\", \"l\", \"\"),\n            _ => unreachable!(),\n        }\n    };\n}\n#[cfg(portable_atomic_pre_llvm_16)]\n#[cfg(any(\n    target_feature = \"lse128\",\n    portable_atomic_target_feature = \"lse128\",\n    all(\n        not(portable_atomic_no_outline_atomics),\n        not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")),\n    ),\n))]\nmacro_rules! atomic_rmw_inst {\n    ($op:ident, $order:ident) => {\n        atomic_rmw_inst!($op, $order, write = $order)\n    };\n    ($op:ident, $order:ident, write = $write:ident) => {\n        match $order {\n            Ordering::Relaxed => $op!(\"2\", \"\"), // \"\"\n            Ordering::Acquire => $op!(\"a\", \"\"), // \"a\"\n            Ordering::Release => $op!(\"6\", \"\"), // \"l\"\n            Ordering::AcqRel => $op!(\"e\", \"\"),  // \"al\"\n            // In MSVC environments, SeqCst stores/writes by non-LSE* instructions needs fences after writes.\n            // https://reviews.llvm.org/D141748\n            // https://github.com/llvm/llvm-project/commit/1ea201d73be2fdf03347e9c6be09ebed5f8e0e00\n            #[cfg(target_env = \"msvc\")]\n            Ordering::SeqCst if $write == Ordering::SeqCst => $op!(\"e\", \"dmb ish\"),\n            // AcqRel and SeqCst RMWs are equivalent in non-MSVC environments.\n            Ordering::SeqCst => $op!(\"e\", \"\"),\n            _ => unreachable!(),\n        }\n    };\n}\n\n// -----------------------------------------------------------------------------\n// load\n\n/*\n\nInstruction selection flow for load:\n- if compile_time(FEAT_LSE2) => ldp:\n  - if compile_time(FEAT_LRCPC3) && order != relaxed => ldiapp\n  - else => ldp\n- if platform_supports_detection_of(FEAT_LSE2):\n  - if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (ldiapp)\n  - if detect(FEAT_LSE2) => lse2 (ldp)\n- else => no_lse2:\n  - if compile_time(FEAT_LSE) => casp\n  - else => ldxp_stxp\n\nNote:\n- If FEAT_LSE2 is available at compile-time, we don't do run-time detection of\n  FEAT_LRCPC3 at this time, since FEAT_LRCPC3 is not yet available for most CPUs.\n  (macOS that doesn't have any FEAT_LRCPC3-enabled CPUs as of M4 is only a platform\n  that currently enables FEAT_LSE2 at compile-time by default.)\n- If FEAT_LSE2 is not available at compile-time, we want to do run-time detection\n  of FEAT_LSE2, so we do run-time detection of FEAT_LRCPC3 at the same time.\n- We don't do run-time detection of FEAT_LSE for load at this time, but since\n  load by CAS is wait-free, it would probably make sense to do run-time detection. (TODO)\n\n*/\n\ncfg_sel!({\n    // if compile_time(FEAT_LSE2) => ldp:\n    // cfg guarantee that the CPU supports FEAT_LSE2.\n    #[cfg(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\"))]\n    {\n        use self::_atomic_load_ldp as atomic_load;\n    }\n    // if platform_supports_detection_of(FEAT_LSE2):\n    #[cfg(all(\n        not(portable_atomic_no_outline_atomics),\n        any(\n            all(\n                target_os = \"linux\",\n                any(\n                    target_env = \"gnu\",\n                    all(\n                        target_env = \"musl\",\n                        any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                    ),\n                    target_env = \"ohos\",\n                    all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                    portable_atomic_outline_atomics,\n                ),\n            ),\n            target_os = \"android\",\n            target_os = \"freebsd\",\n            target_os = \"netbsd\",\n            target_os = \"openbsd\",\n            target_os = \"illumos\",\n            // These don't support detection of FEAT_LSE2.\n            // target_os = \"fuchsia\",\n            target_vendor = \"apple\",\n            windows,\n        ),\n    ))]\n    {\n        #[inline]\n        unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {\n            fn_alias! {\n                // inline(never) is just a hint and also not strictly necessary\n                // because we use ifunc helper macro, but used for clarity.\n                #[inline(never)]\n                unsafe fn(src: *mut u128) -> u128;\n                atomic_load_lse2_relaxed = _atomic_load_ldp(Ordering::Relaxed);\n                atomic_load_lse2_acquire = _atomic_load_ldp(Ordering::Acquire);\n                atomic_load_lse2_seqcst = _atomic_load_ldp(Ordering::SeqCst);\n                atomic_load_lse2_rcpc3_acquire = _atomic_load_ldiapp(Ordering::Acquire);\n                atomic_load_lse2_rcpc3_seqcst = _atomic_load_ldiapp(Ordering::SeqCst);\n            }\n            fn_alias! {\n                unsafe fn(src: *mut u128) -> u128;\n                atomic_load_no_lse2_relaxed = atomic_load_no_lse2(Ordering::Relaxed);\n                atomic_load_no_lse2_acquire = atomic_load_no_lse2(Ordering::Acquire);\n                atomic_load_no_lse2_seqcst = atomic_load_no_lse2(Ordering::SeqCst);\n            }\n            // SAFETY: the caller must uphold the safety contract.\n            // and we've checked if FEAT_LSE2/FEAT_LRCPC3 is available.\n            unsafe {\n                match order {\n                    Ordering::Relaxed => {\n                        ifunc!(unsafe fn(src: *mut u128) -> u128 {\n                            let cpuinfo = detect::detect();\n                            if cpuinfo.lse2() {\n                                // if detect(FEAT_LSE2) => lse2 (ldp)\n                                atomic_load_lse2_relaxed\n                            } else {\n                                // else => no_lse2:\n                                atomic_load_no_lse2_relaxed\n                            }\n                        })\n                    }\n                    Ordering::Acquire => {\n                        ifunc!(unsafe fn(src: *mut u128) -> u128 {\n                            let cpuinfo = detect::detect();\n                            if cpuinfo.lse2() {\n                                if cpuinfo.rcpc3() {\n                                    // if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (ldiapp)\n                                    atomic_load_lse2_rcpc3_acquire\n                                } else {\n                                    // if detect(FEAT_LSE2) => lse2 (ldp)\n                                    atomic_load_lse2_acquire\n                                }\n                            } else {\n                                // else => no_lse2:\n                                atomic_load_no_lse2_acquire\n                            }\n                        })\n                    }\n                    Ordering::SeqCst => {\n                        ifunc!(unsafe fn(src: *mut u128) -> u128 {\n                            let cpuinfo = detect::detect();\n                            if cpuinfo.lse2() {\n                                if cpuinfo.rcpc3() {\n                                    // if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (ldiapp)\n                                    atomic_load_lse2_rcpc3_seqcst\n                                } else {\n                                    // if detect(FEAT_LSE2) => lse2 (ldp)\n                                    atomic_load_lse2_seqcst\n                                }\n                            } else {\n                                // else => no_lse2:\n                                atomic_load_no_lse2_seqcst\n                            }\n                        })\n                    }\n                    _ => unreachable!(),\n                }\n            }\n        }\n    }\n    // else => no_lse2:\n    #[cfg(else)]\n    {\n        use self::atomic_load_no_lse2 as atomic_load;\n    }\n});\n#[cfg(not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")))]\ncfg_sel!({\n    // if compile_time(FEAT_LSE) => casp\n    // cfg guarantee that the CPU supports FEAT_LSE.\n    #[cfg(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"))]\n    {\n        use self::_atomic_load_casp as atomic_load_no_lse2;\n    }\n    // else => ldxp_stxp\n    #[cfg(else)]\n    {\n        use self::_atomic_load_ldxp_stxp as atomic_load_no_lse2;\n    }\n});\n// If CPU supports FEAT_LSE2, LDP/LDIAPP is single-copy atomic reads,\n// otherwise it is two single-copy atomic reads.\n// Refs: B2.2.1 of the Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile\n#[cfg(any(\n    target_feature = \"lse2\",\n    portable_atomic_target_feature = \"lse2\",\n    not(portable_atomic_no_outline_atomics),\n))]\n#[inline]\nunsafe fn _atomic_load_ldp(src: *mut u128, order: Ordering) -> u128 {\n    debug_assert!(src.addr() % 16 == 0);\n    debug_assert_lse2!();\n\n    // SAFETY: the caller must guarantee that `dst` is valid for reads,\n    // 16-byte aligned, that there are no concurrent non-atomic operations.\n    //\n    // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDP--Load-pair-of-registers-\n    unsafe {\n        let (out_lo, out_hi);\n        macro_rules! atomic_load_relaxed {\n            ($acquire:tt) => {{\n                asm!(\n                    \"ldp {out_lo}, {out_hi}, [{src}]\", // atomic { out_lo:out_hi = *src }\n                    $acquire,                          // fence\n                    src = in(reg) ptr_reg!(src),\n                    out_hi = lateout(reg) out_hi,\n                    out_lo = lateout(reg) out_lo,\n                    options(nostack, preserves_flags),\n                );\n                U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n            }};\n        }\n        match order {\n            // if compile_time(FEAT_LRCPC3) && order != relaxed => ldiapp\n            // SAFETY: cfg guarantee that the CPU supports FEAT_LRCPC3.\n            #[cfg(any(target_feature = \"rcpc3\", portable_atomic_target_feature = \"rcpc3\"))]\n            Ordering::Acquire | Ordering::SeqCst => _atomic_load_ldiapp(src, order),\n\n            // else => ldp\n            Ordering::Relaxed => atomic_load_relaxed!(\"\"),\n            #[cfg(not(any(target_feature = \"rcpc3\", portable_atomic_target_feature = \"rcpc3\")))]\n            Ordering::Acquire => atomic_load_relaxed!(\"dmb ishld\"),\n            #[cfg(not(any(target_feature = \"rcpc3\", portable_atomic_target_feature = \"rcpc3\")))]\n            Ordering::SeqCst => {\n                asm!(\n                    // ldar (or dmb ishld) is required to prevent reordering with preceding stlxp.\n                    // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108891 for details.\n                    \"ldar {tmp}, [{src}]\",             // atomic { tmp = *src }\n                    \"ldp {out_lo}, {out_hi}, [{src}]\", // atomic { out_lo:out_hi = *src }\n                    \"dmb ishld\",                       // fence\n                    src = in(reg) ptr_reg!(src),\n                    out_hi = lateout(reg) out_hi,\n                    out_lo = lateout(reg) out_lo,\n                    tmp = out(reg) _,\n                    options(nostack, preserves_flags),\n                );\n                U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n            }\n            _ => unreachable!(),\n        }\n    }\n}\n#[cfg(any(\n    target_feature = \"lse2\",\n    portable_atomic_target_feature = \"lse2\",\n    not(portable_atomic_no_outline_atomics),\n))]\n#[cfg(any(\n    target_feature = \"rcpc3\",\n    portable_atomic_target_feature = \"rcpc3\",\n    all(\n        not(portable_atomic_no_outline_atomics),\n        not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")),\n    ),\n))]\n#[inline]\nunsafe fn _atomic_load_ldiapp(src: *mut u128, order: Ordering) -> u128 {\n    debug_assert!(src.addr() % 16 == 0);\n    debug_assert_lse2!();\n    debug_assert_rcpc3!();\n\n    // SAFETY: the caller must guarantee that `dst` is valid for reads,\n    // 16-byte aligned, that there are no concurrent non-atomic operations.\n    //\n    // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDIAPP--Load-Acquire-RCpc-ordered-pair-of-registers-\n    unsafe {\n        let (out_lo, out_hi);\n        match order {\n            Ordering::Acquire => {\n                #[cfg(not(portable_atomic_pre_llvm_16))]\n                asm!(\n                    start_rcpc3!(),\n                    \"ldiapp {out_lo}, {out_hi}, [{src}]\", // atomic { out_lo:out_hi = *src }\n                    src = in(reg) ptr_reg!(src),\n                    out_hi = lateout(reg) out_hi,\n                    out_lo = lateout(reg) out_lo,\n                    options(nostack, preserves_flags),\n                );\n                // LLVM supports FEAT_LRCPC3 instructions on LLVM 16+, so use .inst directive on old LLVM.\n                // https://github.com/llvm/llvm-project/commit/a6aaa969f7caec58a994142f8d855861cf3a1463\n                #[cfg(portable_atomic_pre_llvm_16)]\n                asm!(\n                    // ldiapp x0, x1, [x0] // atomic { out_lo:out_hi = *src }\n                    \".inst 0xd9411800\",\n                    in(\"x0\") ptr_reg!(src),\n                    lateout(\"x1\") out_hi,\n                    lateout(\"x0\") out_lo,\n                    options(nostack, preserves_flags),\n                );\n            }\n            Ordering::SeqCst => {\n                #[cfg(not(portable_atomic_pre_llvm_16))]\n                asm!(\n                    start_rcpc3!(),\n                    // ldar (or dmb ishld) is required to prevent reordering with preceding stlxp.\n                    // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108891 for details.\n                    \"ldar {tmp}, [{src}]\",                // atomic { tmp = *src }\n                    \"ldiapp {out_lo}, {out_hi}, [{src}]\", // atomic { out_lo:out_hi = *src }\n                    src = in(reg) ptr_reg!(src),\n                    out_hi = lateout(reg) out_hi,\n                    out_lo = lateout(reg) out_lo,\n                    tmp = out(reg) _,\n                    options(nostack, preserves_flags),\n                );\n                // LLVM supports FEAT_LRCPC3 instructions on LLVM 16+, so use .inst directive on old LLVM.\n                // https://github.com/llvm/llvm-project/commit/a6aaa969f7caec58a994142f8d855861cf3a1463\n                #[cfg(portable_atomic_pre_llvm_16)]\n                asm!(\n                    // ldar (or dmb ishld) is required to prevent reordering with preceding stlxp.\n                    // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108891 for details.\n                    \"ldar {tmp}, [x0]\",    // atomic { out_lo:out_hi = *src }\n                    // ldiapp x0, x1, [x0] // atomic { tmp = *src }\n                    \".inst 0xd9411800\",\n                    tmp = out(reg) _,\n                    in(\"x0\") ptr_reg!(src),\n                    lateout(\"x1\") out_hi,\n                    lateout(\"x0\") out_lo,\n                    options(nostack, preserves_flags),\n                );\n            }\n            _ => unreachable!(),\n        }\n        U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n    }\n}\n// Do not use _atomic_compare_exchange_casp because it needs extra MOV to implement load.\n#[cfg(any(test, not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\"))))]\n#[cfg(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"))]\n#[inline]\nunsafe fn _atomic_load_casp(src: *mut u128, order: Ordering) -> u128 {\n    debug_assert!(src.addr() % 16 == 0);\n    debug_assert_lse!();\n\n    // SAFETY: the caller must uphold the safety contract.\n    // cfg guarantee that the CPU supports FEAT_LSE.\n    unsafe {\n        let (out_lo, out_hi);\n        macro_rules! atomic_load {\n            ($acquire:tt, $release:tt) => {\n                asm!(\n                    start_lse!(),\n                    concat!(\"casp\", $acquire, $release, \" x2, x3, x2, x3, [{src}]\"), // atomic { if *src == x2:x3 { *dst = x2:x3 } else { x2:x3 = *dst } }\n                    src = in(reg) ptr_reg!(src),\n                    // must be allocated to even/odd register pair\n                    inout(\"x2\") 0_u64 => out_lo,\n                    inout(\"x3\") 0_u64 => out_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        match order {\n            Ordering::Relaxed => atomic_load!(\"\", \"\"),\n            Ordering::Acquire => atomic_load!(\"a\", \"\"),\n            // TODO: in atomicsabi64, seqcst load is the same as acquire load\n            Ordering::SeqCst => atomic_load!(\"a\", \"l\"),\n            _ => unreachable!(),\n        }\n        U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n    }\n}\n#[cfg(any(\n    test,\n    all(\n        not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")),\n        not(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\")),\n    ),\n))]\n#[inline]\nunsafe fn _atomic_load_ldxp_stxp(src: *mut u128, order: Ordering) -> u128 {\n    debug_assert!(src.addr() % 16 == 0);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        let (mut out_lo, mut out_hi);\n        macro_rules! atomic_load {\n            ($acquire:tt, $release:tt) => {\n                asm!(\n                    \"2:\", // 'retry:\n                        concat!(\"ld\", $acquire, \"xp {out_lo}, {out_hi}, [{src}]\"),        // atomic { out_lo:out_hi = *src; EXCLUSIVE = src }\n                        // write back to ensure atomicity\n                        concat!(\"st\", $release, \"xp {r:w}, {out_lo}, {out_hi}, [{src}]\"), // atomic { if EXCLUSIVE == src { *src = out_lo:out_hi; r = 0 } else { r = 1 }; EXCLUSIVE = None }\n                        \"cbnz {r:w}, 2b\",                                                 // if r != 0 { jump 'retry }\n                    src = in(reg) ptr_reg!(src),\n                    out_lo = out(reg) out_lo,\n                    out_hi = out(reg) out_hi,\n                    r = out(reg) _,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        match order {\n            Ordering::Relaxed => atomic_load!(\"\", \"\"),\n            Ordering::Acquire => atomic_load!(\"a\", \"\"),\n            // TODO: in atomicsabi64, seqcst load is the same as acquire load\n            Ordering::SeqCst => atomic_load!(\"a\", \"l\"),\n            _ => unreachable!(),\n        }\n        U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n    }\n}\n\n// -----------------------------------------------------------------------------\n// store\n\n/*\n\nInstruction selection flow for store:\n- if compile_time(FEAT_LSE2) => stp:\n  - if compile_time(FEAT_LSE128) && order == seqcst => swpp\n  - if compile_time(FEAT_LRCPC3) && order != relaxed => stilp\n  - if compile_time(FEAT_LSE128) && order != relaxed => swpp\n  - else => stp\n- if platform_supports_detection_of(FEAT_LSE2):\n  - if detect(FEAT_LSE2) && detect(FEAT_LSE128) && order == seqcst => lse128 (swpp)\n  - if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (stilp)\n  - if detect(FEAT_LSE2) && detect(FEAT_LSE128) && order != relaxed => lse128 (swpp)\n  - if detect(FEAT_LSE2) => lse2 (stp)\n- else => no_lse2:\n  - if compile_time(FEAT_LSE) && not(ll_sc_rmw) => casp\n  - else => ldxp_stxp\n\nNote:\n- If FEAT_LSE2 is available at compile-time, we don't do run-time detection of\n  FEAT_LRCPC3/FEAT_LSE128 at this time, since FEAT_LRCPC3/FEAT_LSE128 is not yet available for most CPUs.\n  (macOS that doesn't have any FEAT_LRCPC3/FEAT_LSE128-enabled CPUs as of M4 is only a platform\n  that currently enables FEAT_LSE2 at compile-time by default.)\n- If FEAT_LSE2 is not available at compile-time, we want to do run-time detection\n  of FEAT_LSE2, so we do run-time detection of FEAT_LRCPC3/FEAT_LSE128 at the same time.\n- We don't do run-time detection of FEAT_LSE for store at this time.\n\n*/\n\ncfg_sel!({\n    // if compile_time(FEAT_LSE2) => stp:\n    // cfg guarantee that the CPU supports FEAT_LSE2.\n    #[cfg(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\"))]\n    {\n        use self::_atomic_store_stp as atomic_store;\n    }\n    // if platform_supports_detection_of(FEAT_LSE2):\n    #[cfg(all(\n        not(portable_atomic_no_outline_atomics),\n        any(\n            all(\n                target_os = \"linux\",\n                any(\n                    target_env = \"gnu\",\n                    all(\n                        target_env = \"musl\",\n                        any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                    ),\n                    target_env = \"ohos\",\n                    all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                    portable_atomic_outline_atomics,\n                ),\n            ),\n            target_os = \"android\",\n            target_os = \"freebsd\",\n            target_os = \"netbsd\",\n            target_os = \"openbsd\",\n            target_os = \"illumos\",\n            // These don't support detection of FEAT_LSE2.\n            // target_os = \"fuchsia\",\n            target_vendor = \"apple\",\n            windows,\n        ),\n    ))]\n    {\n        #[inline]\n        unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {\n            #[cfg(any(\n                target_feature = \"lse128\",\n                portable_atomic_target_feature = \"lse128\",\n                all(\n                    not(portable_atomic_no_outline_atomics),\n                    not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")),\n                ),\n            ))]\n            #[inline]\n            unsafe fn _atomic_store_swpp(dst: *mut u128, val: u128, order: Ordering) {\n                // SAFETY: the caller must uphold the safety contract.\n                unsafe {\n                    _atomic_swap_swpp(dst, val, order);\n                }\n            }\n            fn_alias! {\n                // inline(never) is just a hint and also not strictly necessary\n                // because we use ifunc helper macro, but used for clarity.\n                #[inline(never)]\n                unsafe fn(dst: *mut u128, val: u128);\n                atomic_store_lse2_relaxed = _atomic_store_stp(Ordering::Relaxed);\n                atomic_store_lse2_release = _atomic_store_stp(Ordering::Release);\n                atomic_store_lse2_seqcst = _atomic_store_stp(Ordering::SeqCst);\n                atomic_store_lse2_rcpc3_release = _atomic_store_stilp(Ordering::Release);\n                atomic_store_lse2_rcpc3_seqcst = _atomic_store_stilp(Ordering::SeqCst);\n                atomic_store_lse128_release = _atomic_store_swpp(Ordering::Release);\n                atomic_store_lse128_seqcst = _atomic_store_swpp(Ordering::SeqCst);\n            }\n            fn_alias! {\n                unsafe fn(dst: *mut u128, val: u128);\n                atomic_store_no_lse2_relaxed = atomic_store_no_lse2(Ordering::Relaxed);\n                atomic_store_no_lse2_release = atomic_store_no_lse2(Ordering::Release);\n                atomic_store_no_lse2_seqcst = atomic_store_no_lse2(Ordering::SeqCst);\n            }\n            // SAFETY: the caller must uphold the safety contract.\n            // and we've checked if FEAT_LSE2/FEAT_LRCPC3/FEAT_LSE128 is available.\n            unsafe {\n                match order {\n                    Ordering::Relaxed => {\n                        ifunc!(unsafe fn(dst: *mut u128, val: u128) {\n                            let cpuinfo = detect::detect();\n                            if cpuinfo.lse2() {\n                                // if detect(FEAT_LSE2) => lse2 (stp)\n                                atomic_store_lse2_relaxed\n                            } else {\n                                // else => no_lse2:\n                                atomic_store_no_lse2_relaxed\n                            }\n                        });\n                    }\n                    Ordering::Release => {\n                        ifunc!(unsafe fn(dst: *mut u128, val: u128) {\n                            let cpuinfo = detect::detect();\n                            if cpuinfo.lse2() {\n                                if cpuinfo.rcpc3() {\n                                    // if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (stilp)\n                                    atomic_store_lse2_rcpc3_release\n                                } else if cpuinfo.lse128() {\n                                    // if detect(FEAT_LSE2) && detect(FEAT_LSE128) && order != relaxed => lse128 (swpp)\n                                    atomic_store_lse128_release\n                                } else {\n                                    // if detect(FEAT_LSE2) => lse2 (stp)\n                                    atomic_store_lse2_release\n                                }\n                            } else {\n                                // else => no_lse2:\n                                atomic_store_no_lse2_release\n                            }\n                        });\n                    }\n                    Ordering::SeqCst => {\n                        ifunc!(unsafe fn(dst: *mut u128, val: u128) {\n                            let cpuinfo = detect::detect();\n                            if cpuinfo.lse2() {\n                                if cpuinfo.lse128() {\n                                    // if detect(FEAT_LSE2) && detect(FEAT_LSE128) && order == seqcst => lse128 (swpp)\n                                    atomic_store_lse128_seqcst\n                                } else if cpuinfo.rcpc3() {\n                                    // if detect(FEAT_LSE2) && detect(FEAT_LRCPC3) && order != relaxed => lse2_rcpc3 (stilp)\n                                    atomic_store_lse2_rcpc3_seqcst\n                                } else {\n                                    // if detect(FEAT_LSE2) => lse2 (stp)\n                                    atomic_store_lse2_seqcst\n                                }\n                            } else {\n                                // else => no_lse2:\n                                atomic_store_no_lse2_seqcst\n                            }\n                        });\n                    }\n                    _ => unreachable!(),\n                }\n            }\n        }\n    }\n    // else => no_lse2:\n    #[cfg(else)]\n    {\n        use self::atomic_store_no_lse2 as atomic_store;\n    }\n});\n#[cfg(not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")))]\ncfg_sel!({\n    // if compile_time(FEAT_LSE) && not(ll_sc_rmw) => casp\n    // If FEAT_LSE is available at compile-time and portable_atomic_ll_sc_rmw cfg is not set,\n    // we use CAS-based atomic RMW.\n    #[cfg(all(\n        any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n        not(portable_atomic_ll_sc_rmw),\n    ))]\n    {\n        #[inline]\n        unsafe fn atomic_store_no_lse2(dst: *mut u128, val: u128, order: Ordering) {\n            // SAFETY: the caller must uphold the safety contract.\n            // cfg guarantee that the CPU supports FEAT_LSE.\n            unsafe {\n                _atomic_swap_casp(dst, val, order);\n            }\n        }\n    }\n    // else => ldxp_stxp\n    #[cfg(else)]\n    {\n        use self::_atomic_store_ldxp_stxp as atomic_store_no_lse2;\n    }\n});\n// If CPU supports FEAT_LSE2, STP/STILP is single-copy atomic writes,\n// otherwise it is two single-copy atomic writes.\n// Refs: B2.2.1 of the Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile\n#[cfg(any(\n    target_feature = \"lse2\",\n    portable_atomic_target_feature = \"lse2\",\n    not(portable_atomic_no_outline_atomics),\n))]\n#[inline]\nunsafe fn _atomic_store_stp(dst: *mut u128, val: u128, order: Ordering) {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_lse2!();\n\n    // SAFETY: the caller must guarantee that `dst` is valid for writes,\n    // 16-byte aligned, that there are no concurrent non-atomic operations.\n    //\n    // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/STP--Store-pair-of-registers-\n    unsafe {\n        macro_rules! atomic_store {\n            ($acquire:tt, $release:tt) => {{\n                let val = U128 { whole: val };\n                asm!(\n                    $release,                          // fence\n                    \"stp {val_lo}, {val_hi}, [{dst}]\", // atomic { *dst = val_lo:val_hi }\n                    $acquire,                          // fence\n                    dst = in(reg) ptr_reg!(dst),\n                    val_lo = in(reg) val.pair.lo,\n                    val_hi = in(reg) val.pair.hi,\n                    options(nostack, preserves_flags),\n                );\n            }};\n        }\n        match order {\n            // if compile_time(FEAT_LSE128) && order == seqcst => swpp\n            // Prefer swpp if stp requires fences. https://reviews.llvm.org/D143506\n            // SAFETY: cfg guarantee that the CPU supports FEAT_LSE128.\n            #[cfg(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\"))]\n            Ordering::SeqCst => {\n                _atomic_swap_swpp(dst, val, order);\n            }\n\n            // if compile_time(FEAT_LRCPC3) && order != relaxed => stilp\n            // SAFETY: cfg guarantee that the CPU supports FEAT_LRCPC3.\n            #[cfg(any(target_feature = \"rcpc3\", portable_atomic_target_feature = \"rcpc3\"))]\n            Ordering::Release => _atomic_store_stilp(dst, val, order),\n            #[cfg(any(target_feature = \"rcpc3\", portable_atomic_target_feature = \"rcpc3\"))]\n            #[cfg(not(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\")))]\n            Ordering::SeqCst => _atomic_store_stilp(dst, val, order),\n\n            // if compile_time(FEAT_LSE128) && order != relaxed => swpp\n            // Prefer swpp if stp requires fences. https://reviews.llvm.org/D143506\n            // SAFETY: cfg guarantee that the CPU supports FEAT_LSE128.\n            #[cfg(not(any(target_feature = \"rcpc3\", portable_atomic_target_feature = \"rcpc3\")))]\n            #[cfg(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\"))]\n            Ordering::Release => {\n                _atomic_swap_swpp(dst, val, order);\n            }\n\n            // else => stp\n            Ordering::Relaxed => atomic_store!(\"\", \"\"),\n            #[cfg(not(any(target_feature = \"rcpc3\", portable_atomic_target_feature = \"rcpc3\")))]\n            #[cfg(not(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\")))]\n            Ordering::Release => atomic_store!(\"\", \"dmb ish\"),\n            #[cfg(not(any(target_feature = \"rcpc3\", portable_atomic_target_feature = \"rcpc3\")))]\n            #[cfg(not(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\")))]\n            Ordering::SeqCst => atomic_store!(\"dmb ish\", \"dmb ish\"),\n            _ => unreachable!(),\n        }\n    }\n}\n#[cfg(any(\n    target_feature = \"lse2\",\n    portable_atomic_target_feature = \"lse2\",\n    not(portable_atomic_no_outline_atomics),\n))]\n#[cfg(any(\n    target_feature = \"rcpc3\",\n    portable_atomic_target_feature = \"rcpc3\",\n    all(\n        not(portable_atomic_no_outline_atomics),\n        not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")),\n    ),\n))]\n#[inline]\nunsafe fn _atomic_store_stilp(dst: *mut u128, val: u128, order: Ordering) {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_lse2!();\n    debug_assert_rcpc3!();\n\n    // SAFETY: the caller must guarantee that `dst` is valid for writes,\n    // 16-byte aligned, that there are no concurrent non-atomic operations.\n    //\n    // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/STILP--Store-release-ordered-pair-of-registers-\n    unsafe {\n        macro_rules! atomic_store {\n            ($acquire:tt) => {{\n                let val = U128 { whole: val };\n                #[cfg(not(portable_atomic_pre_llvm_16))]\n                asm!(\n                    start_rcpc3!(),\n                    \"stilp {val_lo}, {val_hi}, [{dst}]\", // atomic { *dst = val_lo:val_hi }\n                    $acquire,                            // fence\n                    dst = in(reg) ptr_reg!(dst),\n                    val_lo = in(reg) val.pair.lo,\n                    val_hi = in(reg) val.pair.hi,\n                    options(nostack, preserves_flags),\n                );\n                // LLVM supports FEAT_LRCPC3 instructions on LLVM 16+, so use .inst directive on old LLVM.\n                // https://github.com/llvm/llvm-project/commit/a6aaa969f7caec58a994142f8d855861cf3a1463\n                #[cfg(portable_atomic_pre_llvm_16)]\n                asm!(\n                    // stilp x2, x3, [x0] // atomic { *dst = x2:x3 }\n                    \".inst 0xd9031802\",\n                    $acquire,             // fence\n                    in(\"x0\") ptr_reg!(dst),\n                    in(\"x2\") val.pair.lo,\n                    in(\"x3\") val.pair.hi,\n                    options(nostack, preserves_flags),\n                );\n            }};\n        }\n        match order {\n            Ordering::Release => atomic_store!(\"\"),\n            // TODO: in atomicsabi64, seqcst store is the same as release store\n            // LLVM uses store-release (dmb ish; stp); dmb ish, GCC (libatomic) and Atomics ABI Standard\n            // uses store-release (stilp) without fence for SeqCst store\n            // (https://github.com/gcc-mirror/gcc/commit/7107574958e2bed11d916a1480ef1319f15e5ffe).\n            // Considering https://reviews.llvm.org/D141748, LLVM's lowering seems\n            // to be the safer option here (I'm not convinced that the libatomic's implementation is wrong).\n            Ordering::SeqCst => atomic_store!(\"dmb ish\"),\n            _ => unreachable!(),\n        }\n    }\n}\n// Do not use _atomic_swap_ldxp_stxp because it needs extra registers to implement store.\n#[cfg(any(\n    test,\n    not(all(\n        any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n        not(portable_atomic_ll_sc_rmw),\n    ))\n))]\n#[inline]\nunsafe fn _atomic_store_ldxp_stxp(dst: *mut u128, val: u128, order: Ordering) {\n    debug_assert!(dst.addr() % 16 == 0);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        let val = U128 { whole: val };\n        macro_rules! store {\n            ($acquire:tt, $release:tt, $msvc_fence:tt) => {\n                asm!(\n                    \"2:\", // 'retry:\n                        concat!(\"ld\", $acquire, \"xp xzr, {tmp}, [{dst}]\"),                  // atomic { xzr:tmp = *dst; EXCLUSIVE = dst }\n                        concat!(\"st\", $release, \"xp {tmp:w}, {val_lo}, {val_hi}, [{dst}]\"), // atomic { if EXCLUSIVE == dst { *dst = val_lo:val_hi; tmp = 0 } else { tmp = 1 }; EXCLUSIVE = None }\n                        \"cbnz {tmp:w}, 2b\",                                                 // if tmp != 0 { jump 'retry }\n                    $msvc_fence,                                                            // fence\n                    dst = in(reg) ptr_reg!(dst),\n                    val_lo = in(reg) val.pair.lo,\n                    val_hi = in(reg) val.pair.hi,\n                    tmp = out(reg) _,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        atomic_rmw!(store, order);\n    }\n}\n\n// -----------------------------------------------------------------------------\n// compare_exchange\n\n/*\n\nInstruction selection flow for compare_exchange:\n- if compile_time(FEAT_LSE) => casp\n- if platform_supports_detection_of(FEAT_LSE):\n  - if detect(FEAT_LSE) => casp\n- else => ldxp_stxp\n\n*/\n\n#[inline]\nunsafe fn atomic_compare_exchange(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> Result<u128, u128> {\n    // if compile_time(FEAT_LSE) => casp\n    #[cfg(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"))]\n    // SAFETY: the caller must uphold the safety contract.\n    // cfg guarantee that the CPU supports FEAT_LSE.\n    let prev = unsafe { _atomic_compare_exchange_casp(dst, old, new, success, failure) };\n    // if platform_supports_detection_of(FEAT_LSE):\n    #[cfg(all(\n        not(portable_atomic_no_outline_atomics),\n        any(\n            all(\n                target_os = \"linux\",\n                any(\n                    target_env = \"gnu\",\n                    all(\n                        target_env = \"musl\",\n                        any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                    ),\n                    target_env = \"ohos\",\n                    all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                    portable_atomic_outline_atomics,\n                ),\n            ),\n            target_os = \"android\",\n            target_os = \"freebsd\",\n            target_os = \"netbsd\",\n            target_os = \"openbsd\",\n            target_os = \"illumos\",\n            target_os = \"fuchsia\",\n            target_vendor = \"apple\",\n            windows,\n        ),\n    ))]\n    #[cfg(not(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\")))]\n    let prev = {\n        fn_alias! {\n            // inline(never) is just a hint and also not strictly necessary\n            // because we use ifunc helper macro, but used for clarity.\n            #[inline(never)]\n            unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128;\n            atomic_compare_exchange_casp_relaxed\n                = _atomic_compare_exchange_casp(Ordering::Relaxed, Ordering::Relaxed);\n            atomic_compare_exchange_casp_acquire\n                = _atomic_compare_exchange_casp(Ordering::Acquire, Ordering::Acquire);\n            atomic_compare_exchange_casp_release\n                = _atomic_compare_exchange_casp(Ordering::Release, Ordering::Relaxed);\n            atomic_compare_exchange_casp_acqrel\n                = _atomic_compare_exchange_casp(Ordering::AcqRel, Ordering::Acquire);\n        }\n        fn_alias! {\n            unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128;\n            atomic_compare_exchange_ldxp_stxp_relaxed\n                = _atomic_compare_exchange_ldxp_stxp(Ordering::Relaxed, Ordering::Relaxed);\n            atomic_compare_exchange_ldxp_stxp_acquire\n                = _atomic_compare_exchange_ldxp_stxp(Ordering::Acquire, Ordering::Acquire);\n            atomic_compare_exchange_ldxp_stxp_release\n                = _atomic_compare_exchange_ldxp_stxp(Ordering::Release, Ordering::Relaxed);\n            atomic_compare_exchange_ldxp_stxp_acqrel\n                = _atomic_compare_exchange_ldxp_stxp(Ordering::AcqRel, Ordering::Acquire);\n            // AcqRel and SeqCst RMWs are equivalent in non-MSVC environments.\n            #[cfg(target_env = \"msvc\")]\n            atomic_compare_exchange_ldxp_stxp_seqcst\n                = _atomic_compare_exchange_ldxp_stxp(Ordering::SeqCst, Ordering::SeqCst);\n        }\n        // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n        // reads, 16-byte aligned, that there are no concurrent non-atomic operations,\n        // and we've checked if FEAT_LSE is available.\n        unsafe {\n            let success = crate::utils::upgrade_success_ordering(success, failure);\n            match success {\n                Ordering::Relaxed => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 {\n                        if detect::detect().lse() {\n                            // if detect(FEAT_LSE) => casp\n                            atomic_compare_exchange_casp_relaxed\n                        } else {\n                            // else => ldxp_stxp\n                            atomic_compare_exchange_ldxp_stxp_relaxed\n                        }\n                    })\n                }\n                Ordering::Acquire => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 {\n                        if detect::detect().lse() {\n                            // if detect(FEAT_LSE) => casp\n                            atomic_compare_exchange_casp_acquire\n                        } else {\n                            // else => ldxp_stxp\n                            atomic_compare_exchange_ldxp_stxp_acquire\n                        }\n                    })\n                }\n                Ordering::Release => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 {\n                        if detect::detect().lse() {\n                            // if detect(FEAT_LSE) => casp\n                            atomic_compare_exchange_casp_release\n                        } else {\n                            // else => ldxp_stxp\n                            atomic_compare_exchange_ldxp_stxp_release\n                        }\n                    })\n                }\n                // AcqRel and SeqCst RMWs are equivalent in both implementations in non-MSVC environments\n                // or LSE* instructions is used.\n                #[cfg(not(target_env = \"msvc\"))]\n                Ordering::AcqRel | Ordering::SeqCst => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 {\n                        if detect::detect().lse() {\n                            // if detect(FEAT_LSE) => casp\n                            atomic_compare_exchange_casp_acqrel\n                        } else {\n                            // else => ldxp_stxp\n                            atomic_compare_exchange_ldxp_stxp_acqrel\n                        }\n                    })\n                }\n                #[cfg(target_env = \"msvc\")]\n                Ordering::AcqRel => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 {\n                        if detect::detect().lse() {\n                            // if detect(FEAT_LSE) => casp\n                            atomic_compare_exchange_casp_acqrel\n                        } else {\n                            // else => ldxp_stxp\n                            atomic_compare_exchange_ldxp_stxp_acqrel\n                        }\n                    })\n                }\n                #[cfg(target_env = \"msvc\")]\n                Ordering::SeqCst => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> u128 {\n                        if detect::detect().lse() {\n                            // if detect(FEAT_LSE) => casp\n                            atomic_compare_exchange_casp_acqrel\n                        } else {\n                            // else => ldxp_stxp\n                            atomic_compare_exchange_ldxp_stxp_seqcst\n                        }\n                    })\n                }\n                _ => unreachable!(),\n            }\n        }\n    };\n    // else => ldxp_stxp\n    #[cfg(not(all(\n        not(portable_atomic_no_outline_atomics),\n        any(\n            all(\n                target_os = \"linux\",\n                any(\n                    target_env = \"gnu\",\n                    all(\n                        target_env = \"musl\",\n                        any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                    ),\n                    target_env = \"ohos\",\n                    all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                    portable_atomic_outline_atomics,\n                ),\n            ),\n            target_os = \"android\",\n            target_os = \"freebsd\",\n            target_os = \"netbsd\",\n            target_os = \"openbsd\",\n            target_os = \"illumos\",\n            target_os = \"fuchsia\",\n            target_vendor = \"apple\",\n            windows,\n        ),\n    )))]\n    #[cfg(not(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\")))]\n    // SAFETY: the caller must uphold the safety contract.\n    let prev = unsafe { _atomic_compare_exchange_ldxp_stxp(dst, old, new, success, failure) };\n    if prev == old { Ok(prev) } else { Err(prev) }\n}\n#[cfg(any(\n    target_feature = \"lse\",\n    portable_atomic_target_feature = \"lse\",\n    not(portable_atomic_no_outline_atomics),\n))]\n#[inline]\nunsafe fn _atomic_compare_exchange_casp(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> u128 {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_lse!();\n    let order = crate::utils::upgrade_success_ordering(success, failure);\n\n    // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n    // reads, 16-byte aligned, that there are no concurrent non-atomic operations,\n    // and the CPU supports FEAT_LSE.\n    //\n    // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/CASP--CASPA--CASPAL--CASPL--Compare-and-swap-pair-of-words-or-doublewords-in-memory-\n    unsafe {\n        let old = U128 { whole: old };\n        let new = U128 { whole: new };\n        let (prev_lo, prev_hi);\n        macro_rules! cmpxchg {\n            ($acquire:tt, $release:tt, $_msvc_fence:tt) => {\n                asm!(\n                    start_lse!(),\n                    concat!(\"casp\", $acquire, $release, \" x6, x7, x4, x5, [{dst}]\"), // atomic { if *dst == x6:x7 { *dst = x4:x5 } else { x6:x7 = *dst } }\n                    dst = in(reg) ptr_reg!(dst),\n                    // must be allocated to even/odd register pair\n                    inout(\"x6\") old.pair.lo => prev_lo,\n                    inout(\"x7\") old.pair.hi => prev_hi,\n                    // must be allocated to even/odd register pair\n                    in(\"x4\") new.pair.lo,\n                    in(\"x5\") new.pair.hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        atomic_rmw!(cmpxchg, order, write = success);\n        U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n    }\n}\n#[cfg(any(test, not(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"))))]\n#[inline]\nunsafe fn _atomic_compare_exchange_ldxp_stxp(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> u128 {\n    debug_assert!(dst.addr() % 16 == 0);\n    let order = crate::utils::upgrade_success_ordering(success, failure);\n\n    // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n    // reads, 16-byte aligned, and that there are no concurrent non-atomic operations.\n    //\n    // Refs:\n    // - LDXP: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDXP--Load-exclusive-pair-of-registers-\n    // - LDAXP: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDAXP--Load-acquire-exclusive-pair-of-registers-\n    // - STXP: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/STXP--Store-exclusive-pair-of-registers-\n    // - STLXP: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/STLXP--Store-release-exclusive-pair-of-registers-\n    //\n    // Note: Load-Exclusive pair (by itself) does not guarantee atomicity; to complete an atomic\n    // operation (even load/store), a corresponding Store-Exclusive pair must succeed.\n    // See Arm Architecture Reference Manual for A-profile architecture\n    // Section B2.2.1 \"Requirements for single-copy atomicity\", and\n    // Section B2.9 \"Synchronization and semaphores\" for more.\n    unsafe {\n        let old = U128 { whole: old };\n        let new = U128 { whole: new };\n        let (mut prev_lo, mut prev_hi);\n        macro_rules! cmpxchg {\n            ($acquire:tt, $release:tt, $msvc_fence:tt) => {\n                asm!(\n                    \"2:\", // 'retry:\n                        concat!(\"ld\", $acquire, \"xp {prev_lo}, {prev_hi}, [{dst}]\"),      // atomic { prev_lo:prev_hi = *dst; EXCLUSIVE = dst }\n                        \"cmp {prev_lo}, {old_lo}\",                                        // if prev_lo == old_lo { Z = 1 } else { Z = 0 }\n                        \"ccmp {prev_hi}, {old_hi}, #0, eq\",                               // if Z == 1 { if prev_hi == old_hi { Z = 1 } else { Z = 0 } } else { Z = 0 }\n                        // write back to ensure atomicity\n                        \"csel {tmp_lo}, {new_lo}, {prev_lo}, eq\",                         // if Z == 1 { tmp_lo = new_lo } else { tmp_lo = prev_lo }\n                        \"csel {tmp_hi}, {new_hi}, {prev_hi}, eq\",                         // if Z == 1 { tmp_hi = new_hi } else { tmp_hi = prev_hi }\n                        concat!(\"st\", $release, \"xp {r:w}, {tmp_lo}, {tmp_hi}, [{dst}]\"), // atomic { if EXCLUSIVE == dst { *dst = tmp_lo:tmp_hi; r = 0 } else { r = 1 }; EXCLUSIVE = None }\n                        \"cbnz {r:w}, 2b\",                                                 // if r != 0 { jump 'retry }\n                    $msvc_fence,                                                          // fence\n                    dst = in(reg) ptr_reg!(dst),\n                    old_lo = in(reg) old.pair.lo,\n                    old_hi = in(reg) old.pair.hi,\n                    new_lo = in(reg) new.pair.lo,\n                    new_hi = in(reg) new.pair.hi,\n                    prev_lo = out(reg) prev_lo,\n                    prev_hi = out(reg) prev_hi,\n                    r = out(reg) _,\n                    tmp_lo = out(reg) _,\n                    tmp_hi = out(reg) _,\n                    // Do not use `preserves_flags` because CMP and CCMP modify the condition flags.\n                    options(nostack),\n                )\n            };\n        }\n        atomic_rmw!(cmpxchg, order, write = success);\n        U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n    }\n}\n\n// casp is always strong, and ldxp requires a corresponding (succeed) stxp for\n// its atomicity (see code comment in _atomic_compare_exchange_ldxp_stxp).\n// (i.e., AArch64 doesn't have 128-bit weak CAS)\nuse self::atomic_compare_exchange as atomic_compare_exchange_weak;\n\n// -----------------------------------------------------------------------------\n// RMW\n\n/*\n\nInstruction selection flow for swap/fetch_and/fetch_or:\n- if compile_time(FEAT_LSE128) => swpp/ldclrp/ldsetp\n- if compile_time(FEAT_LSE) && not(ll_sc_rmw) => casp\n- else => ldxp_stxp\n\nInstruction selection flow for other RMWs:\n- if compile_time(FEAT_LSE) && not(ll_sc_rmw) => casp\n- else => ldxp_stxp\n\nNote:\n- We don't do run-time detection of FEAT_LSE128 at this time, because\n  FEAT_LSE128 is not yet available for most CPUs, but since\n  swpp/ldclrp/ldsetp is wait-free, it would make sense to do run-time\n  detection in the future. (TODO)\n- We don't do run-time detection of FEAT_LSE for store at this time.\n\n*/\n\ncfg_sel!({\n    #[cfg(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\"))]\n    {\n        use self::_atomic_swap_swpp as atomic_swap;\n    }\n    #[cfg(all(\n        any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n        not(portable_atomic_ll_sc_rmw),\n    ))]\n    {\n        use self::_atomic_swap_casp as atomic_swap;\n    }\n    #[cfg(else)]\n    {\n        use self::_atomic_swap_ldxp_stxp as atomic_swap;\n    }\n});\n#[cfg(any(\n    target_feature = \"lse128\",\n    portable_atomic_target_feature = \"lse128\",\n    all(\n        not(portable_atomic_no_outline_atomics),\n        not(any(target_feature = \"lse2\", portable_atomic_target_feature = \"lse2\")),\n    ),\n))]\n#[inline]\nunsafe fn _atomic_swap_swpp(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_lse128!();\n\n    // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n    // reads, 16-byte aligned, that there are no concurrent non-atomic operations,\n    // and the CPU supports FEAT_LSE128.\n    //\n    // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/SWPP--SWPPA--SWPPAL--SWPPL--Swap-quadword-in-memory-\n    unsafe {\n        let val = U128 { whole: val };\n        let (prev_lo, prev_hi);\n        #[cfg(not(portable_atomic_pre_llvm_16))]\n        macro_rules! swap {\n            ($acquire:tt, $release:tt, $_msvc_fence:tt) => {\n                asm!(\n                    start_lse128!(),\n                    concat!(\"swpp\", $acquire, $release, \" {val_lo}, {val_hi}, [{dst}]\"), // atomic { _x = *dst; *dst = val_lo:val_hi; val_lo:val_hi = _x }\n                    dst = in(reg) ptr_reg!(dst),\n                    val_lo = inout(reg) val.pair.lo => prev_lo,\n                    val_hi = inout(reg) val.pair.hi => prev_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(not(portable_atomic_pre_llvm_16))]\n        atomic_rmw!(swap, order);\n        // LLVM supports FEAT_LSE128 instructions on LLVM 16+, so use .inst directive on old LLVM.\n        // https://github.com/llvm/llvm-project/commit/7fea6f2e0e606e5339c3359568f680eaf64aa306\n        #[cfg(portable_atomic_pre_llvm_16)]\n        macro_rules! swap {\n            ($order:tt, $_msvc_fence:tt) => {\n                asm!(\n                    // swpp{,a,l,al} x2, x1, [x0] // atomic { _x = *x0; *x0 = x2:x1; x2:x1 = _x }\n                    concat!(\".inst 0x19\", $order, \"18002\"),\n                    in(\"x0\") ptr_reg!(dst),\n                    inout(\"x2\") val.pair.lo => prev_lo,\n                    inout(\"x1\") val.pair.hi => prev_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(portable_atomic_pre_llvm_16)]\n        atomic_rmw_inst!(swap, order);\n        U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n    }\n}\n// Do not use atomic_rmw_cas_3 because it needs extra MOV to implement swap.\n#[cfg(any(test, not(portable_atomic_ll_sc_rmw)))]\n#[cfg(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"))]\n#[inline]\nunsafe fn _atomic_swap_casp(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_lse!();\n\n    // SAFETY: the caller must uphold the safety contract.\n    // cfg guarantee that the CPU supports FEAT_LSE.\n    unsafe {\n        let val = U128 { whole: val };\n        let (mut prev_lo, mut prev_hi);\n        macro_rules! swap {\n            ($acquire:tt, $release:tt, $_msvc_fence:tt) => {\n                asm!(\n                    start_lse!(),\n                    // If FEAT_LSE2 is not supported, this works like byte-wise atomic.\n                    // This is not single-copy atomic reads, but this is ok because subsequent\n                    // CAS will check for consistency.\n                    \"ldp x4, x5, [{dst}]\",                                               // atomic { x4:x5 = *dst }\n                    \"2:\", // 'retry:\n                        // casp writes the current value to the first register pair,\n                        // so copy the `out`'s value for later comparison.\n                        \"mov {tmp_lo}, x4\",                                              // tmp_lo = x4\n                        \"mov {tmp_hi}, x5\",                                              // tmp_hi = x5\n                        concat!(\"casp\", $acquire, $release, \" x4, x5, x2, x3, [{dst}]\"), // atomic { if *dst == x4:x5 { *dst = x2:x3 } else { x4:x5 = *dst } }\n                        \"cmp {tmp_hi}, x5\",                                              // if tmp_hi == x5 { Z = 1 } else { Z = 0 }\n                        \"ccmp {tmp_lo}, x4, #0, eq\",                                     // if Z == 1 { if tmp_lo == x4 { Z = 1 } else { Z = 0 } } else { Z = 0 }\n                        \"b.ne 2b\",                                                       // if Z == 0 { jump 'retry }\n                    dst = in(reg) ptr_reg!(dst),\n                    tmp_lo = out(reg) _,\n                    tmp_hi = out(reg) _,\n                    // must be allocated to even/odd register pair\n                    out(\"x4\") prev_lo,\n                    out(\"x5\") prev_hi,\n                    // must be allocated to even/odd register pair\n                    in(\"x2\") val.pair.lo,\n                    in(\"x3\") val.pair.hi,\n                    // Do not use `preserves_flags` because CMP and CCMP modify the condition flags.\n                    options(nostack),\n                )\n            };\n        }\n        atomic_rmw!(swap, order);\n        U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n    }\n}\n// Do not use atomic_rmw_ll_sc_3 because it needs extra MOV to implement swap.\n#[cfg(any(\n    test,\n    not(all(\n        any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n        not(portable_atomic_ll_sc_rmw),\n    ))\n))]\n#[inline]\nunsafe fn _atomic_swap_ldxp_stxp(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    debug_assert!(dst.addr() % 16 == 0);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        let val = U128 { whole: val };\n        let (mut prev_lo, mut prev_hi);\n        macro_rules! swap {\n            ($acquire:tt, $release:tt, $msvc_fence:tt) => {\n                asm!(\n                    \"2:\", // 'retry:\n                        concat!(\"ld\", $acquire, \"xp {prev_lo}, {prev_hi}, [{dst}]\"),      // atomic { prev_lo:prev_hi = *dst; EXCLUSIVE = dst }\n                        concat!(\"st\", $release, \"xp {r:w}, {val_lo}, {val_hi}, [{dst}]\"), // atomic { if EXCLUSIVE == dst { *dst = val_lo:val_hi; r = 0 } else { r = 1 }; EXCLUSIVE = None }\n                        \"cbnz {r:w}, 2b\",                                                 // if r != 0 { jump 'retry }\n                    $msvc_fence,                                                          // fence\n                    dst = in(reg) ptr_reg!(dst),\n                    val_lo = in(reg) val.pair.lo,\n                    val_hi = in(reg) val.pair.hi,\n                    prev_lo = out(reg) prev_lo,\n                    prev_hi = out(reg) prev_hi,\n                    r = out(reg) _,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        atomic_rmw!(swap, order);\n        U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n    }\n}\n\n/// Atomic RMW by LL/SC loop (3 arguments)\n/// `unsafe fn(dst: *mut u128, val: u128, order: Ordering) -> u128;`\n///\n/// `$op` can use the following registers:\n/// - val_lo/val_hi pair: val argument (read-only for `$op`)\n/// - prev_lo/prev_hi pair: previous value loaded by ll (read-only for `$op`)\n/// - new_lo/new_hi pair: new value that will be stored by sc\nmacro_rules! atomic_rmw_ll_sc_3 {\n    ($name:ident as $reexport_name:ident $(($preserves_flags:tt))?, $($op:tt)*) => {\n        // If FEAT_LSE is available at compile-time and portable_atomic_ll_sc_rmw cfg is not set,\n        // we use CAS-based atomic RMW generated by atomic_rmw_cas_3! macro instead.\n        #[cfg(not(all(\n            any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n            not(portable_atomic_ll_sc_rmw),\n        )))]\n        use self::$name as $reexport_name;\n        #[cfg(any(\n            test,\n            not(all(\n                any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n                not(portable_atomic_ll_sc_rmw),\n            ))\n        ))]\n        #[inline]\n        unsafe fn $name(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            debug_assert!(dst.addr() % 16 == 0);\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                let val = U128 { whole: val };\n                let (mut prev_lo, mut prev_hi);\n                macro_rules! op {\n                    ($acquire:tt, $release:tt, $msvc_fence:tt) => {\n                        asm!(\n                            \"2:\", // 'retry:\n                                concat!(\"ld\", $acquire, \"xp {prev_lo}, {prev_hi}, [{dst}]\"),      // atomic { prev_lo:prev_hi = *dst; EXCLUSIVE = dst }\n                                $($op)*\n                                concat!(\"st\", $release, \"xp {r:w}, {new_lo}, {new_hi}, [{dst}]\"), // atomic { if EXCLUSIVE == dst { *dst = new_lo:new_hi; r = 0 } else { r = 1 }; EXCLUSIVE = None }\n                                \"cbnz {r:w}, 2b\",                                                 // if r != 0 { jump 'retry }\n                            $msvc_fence,                                                          // fence\n                            dst = in(reg) ptr_reg!(dst),\n                            val_lo = in(reg) val.pair.lo,\n                            val_hi = in(reg) val.pair.hi,\n                            prev_lo = out(reg) prev_lo,\n                            prev_hi = out(reg) prev_hi,\n                            new_lo = out(reg) _,\n                            new_hi = out(reg) _,\n                            r = out(reg) _,\n                            options(nostack $(, $preserves_flags)?),\n                        )\n                    };\n                }\n                atomic_rmw!(op, order);\n                U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n            }\n        }\n    };\n}\n/// Atomic RMW by CAS loop (3 arguments)\n/// `unsafe fn(dst: *mut u128, val: u128, order: Ordering) -> u128;`\n///\n/// `$op` can use the following registers:\n/// - val_lo/val_hi pair: val argument (read-only for `$op`)\n/// - x6/x7 pair: previous value loaded (read-only for `$op`)\n/// - x4/x5 pair: new value that will be stored\nmacro_rules! atomic_rmw_cas_3 {\n    ($name:ident as $reexport_name:ident, $($op:tt)*) => {\n        // If FEAT_LSE is not available at compile-time or portable_atomic_ll_sc_rmw cfg is set,\n        // we use LL/SC-based atomic RMW generated by atomic_rmw_ll_sc_3! macro instead.\n        #[cfg(all(\n            any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n            not(portable_atomic_ll_sc_rmw),\n        ))]\n        use self::$name as $reexport_name;\n        #[cfg(any(test, not(portable_atomic_ll_sc_rmw)))]\n        #[cfg(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"))]\n        #[inline]\n        unsafe fn $name(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            debug_assert!(dst.addr() % 16 == 0);\n            debug_assert_lse!();\n            // SAFETY: the caller must uphold the safety contract.\n            // cfg guarantee that the CPU supports FEAT_LSE.\n            unsafe {\n                let val = U128 { whole: val };\n                let (mut prev_lo, mut prev_hi);\n                macro_rules! op {\n                    ($acquire:tt, $release:tt, $_msvc_fence:tt) => {\n                        asm!(\n                            start_lse!(),\n                            // If FEAT_LSE2 is not supported, this works like byte-wise atomic.\n                            // This is not single-copy atomic reads, but this is ok because subsequent\n                            // CAS will check for consistency.\n                            \"ldp x6, x7, [{dst}]\",                                               // atomic { x6:x7 = *dst }\n                            \"2:\", // 'retry:\n                                // casp writes the current value to the first register pair,\n                                // so copy the `out`'s value for later comparison.\n                                \"mov {tmp_lo}, x6\",                                              // tmp_lo = x6\n                                \"mov {tmp_hi}, x7\",                                              // tmp_hi = x7\n                                $($op)*\n                                concat!(\"casp\", $acquire, $release, \" x6, x7, x4, x5, [{dst}]\"), // atomic { if *dst == x6:x7 { *dst = x4:x5 } else { x6:x7 = *dst } }\n                                \"cmp {tmp_hi}, x7\",                                              // if tmp_hi == x7 { Z = 1 } else { Z = 0 }\n                                \"ccmp {tmp_lo}, x6, #0, eq\",                                     // if Z == 1 { if tmp_lo == x6 { Z = 1 } else { Z = 0 } } else { Z = 0 }\n                                \"b.ne 2b\",                                                       // if Z == 0 { jump 'retry }\n                            dst = in(reg) ptr_reg!(dst),\n                            val_lo = in(reg) val.pair.lo,\n                            val_hi = in(reg) val.pair.hi,\n                            tmp_lo = out(reg) _,\n                            tmp_hi = out(reg) _,\n                            // must be allocated to even/odd register pair\n                            out(\"x6\") prev_lo,\n                            out(\"x7\") prev_hi,\n                            // must be allocated to even/odd register pair\n                            out(\"x4\") _,\n                            out(\"x5\") _,\n                            // Do not use `preserves_flags` because CMP and CCMP modify the condition flags.\n                            options(nostack),\n                        )\n                    };\n                }\n                atomic_rmw!(op, order);\n                U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n            }\n        }\n    };\n}\n\n/// Atomic RMW by LL/SC loop (2 arguments)\n/// `unsafe fn(dst: *mut u128, order: Ordering) -> u128;`\n///\n/// `$op` can use the following registers:\n/// - prev_lo/prev_hi pair: previous value loaded by ll (read-only for `$op`)\n/// - new_lo/new_hi pair: new value that will be stored by sc\nmacro_rules! atomic_rmw_ll_sc_2 {\n    ($name:ident as $reexport_name:ident $(($preserves_flags:tt))?, $($op:tt)*) => {\n        // If FEAT_LSE is available at compile-time and portable_atomic_ll_sc_rmw cfg is not set,\n        // we use CAS-based atomic RMW generated by atomic_rmw_cas_2! macro instead.\n        #[cfg(not(all(\n            any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n            not(portable_atomic_ll_sc_rmw),\n        )))]\n        use self::$name as $reexport_name;\n        #[cfg(any(\n            test,\n            not(all(\n                any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n                not(portable_atomic_ll_sc_rmw),\n            ))\n        ))]\n        #[inline]\n        unsafe fn $name(dst: *mut u128, order: Ordering) -> u128 {\n            debug_assert!(dst.addr() % 16 == 0);\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                let (mut prev_lo, mut prev_hi);\n                macro_rules! op {\n                    ($acquire:tt, $release:tt, $msvc_fence:tt) => {\n                        asm!(\n                            \"2:\", // 'retry:\n                                concat!(\"ld\", $acquire, \"xp {prev_lo}, {prev_hi}, [{dst}]\"),      // atomic { prev_lo:prev_hi = *dst; EXCLUSIVE = dst }\n                                $($op)*\n                                concat!(\"st\", $release, \"xp {r:w}, {new_lo}, {new_hi}, [{dst}]\"), // atomic { if EXCLUSIVE == dst { *dst = new_lo:new_hi; r = 0 } else { r = 1 }; EXCLUSIVE = None }\n                                \"cbnz {r:w}, 2b\",                                                 // if r != 0 { jump 'retry }\n                            $msvc_fence,                                                          // fence\n                            dst = in(reg) ptr_reg!(dst),\n                            prev_lo = out(reg) prev_lo,\n                            prev_hi = out(reg) prev_hi,\n                            new_lo = out(reg) _,\n                            new_hi = out(reg) _,\n                            r = out(reg) _,\n                            options(nostack $(, $preserves_flags)?),\n                        )\n                    };\n                }\n                atomic_rmw!(op, order);\n                U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n            }\n        }\n    };\n}\n/// Atomic RMW by CAS loop (2 arguments)\n/// `unsafe fn(dst: *mut u128, order: Ordering) -> u128;`\n///\n/// `$op` can use the following registers:\n/// - x6/x7 pair: previous value loaded (read-only for `$op`)\n/// - x4/x5 pair: new value that will be stored\nmacro_rules! atomic_rmw_cas_2 {\n    ($name:ident as $reexport_name:ident, $($op:tt)*) => {\n        // If FEAT_LSE is not available at compile-time or portable_atomic_ll_sc_rmw cfg is set,\n        // we use LL/SC-based atomic RMW generated by atomic_rmw_ll_sc_3! macro instead.\n        #[cfg(all(\n            any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"),\n            not(portable_atomic_ll_sc_rmw),\n        ))]\n        use self::$name as $reexport_name;\n        #[cfg(any(test, not(portable_atomic_ll_sc_rmw)))]\n        #[cfg(any(target_feature = \"lse\", portable_atomic_target_feature = \"lse\"))]\n        #[inline]\n        unsafe fn $name(dst: *mut u128, order: Ordering) -> u128 {\n            debug_assert!(dst.addr() % 16 == 0);\n            debug_assert_lse!();\n            // SAFETY: the caller must uphold the safety contract.\n            // cfg guarantee that the CPU supports FEAT_LSE.\n            unsafe {\n                let (mut prev_lo, mut prev_hi);\n                macro_rules! op {\n                    ($acquire:tt, $release:tt, $_msvc_fence:tt) => {\n                        asm!(\n                            start_lse!(),\n                            // If FEAT_LSE2 is not supported, this works like byte-wise atomic.\n                            // This is not single-copy atomic reads, but this is ok because subsequent\n                            // CAS will check for consistency.\n                            \"ldp x6, x7, [{dst}]\",                                               // atomic { x6:x7 = *dst }\n                            \"2:\", // 'retry:\n                                // casp writes the current value to the first register pair,\n                                // so copy the `out`'s value for later comparison.\n                                \"mov {tmp_lo}, x6\",                                              // tmp_lo = x6\n                                \"mov {tmp_hi}, x7\",                                              // tmp_hi = x7\n                                $($op)*\n                                concat!(\"casp\", $acquire, $release, \" x6, x7, x4, x5, [{dst}]\"), // atomic { if *dst == x6:x7 { *dst = x4:x5 } else { x6:x7 = *dst } }\n                                \"cmp {tmp_hi}, x7\",                                              // if tmp_hi == x7 { Z = 1 } else { Z = 0 }\n                                \"ccmp {tmp_lo}, x6, #0, eq\",                                     // if Z == 1 { if tmp_lo == x6 { Z = 1 } else { Z = 0 } } else { Z = 0 }\n                                \"b.ne 2b\",                                                       // if Z == 0 { jump 'retry }\n                            dst = in(reg) ptr_reg!(dst),\n                            tmp_lo = out(reg) _,\n                            tmp_hi = out(reg) _,\n                            // must be allocated to even/odd register pair\n                            out(\"x6\") prev_lo,\n                            out(\"x7\") prev_hi,\n                            // must be allocated to even/odd register pair\n                            out(\"x4\") _,\n                            out(\"x5\") _,\n                            // Do not use `preserves_flags` because CMP and CCMP modify the condition flags.\n                            options(nostack),\n                        )\n                    };\n                }\n                atomic_rmw!(op, order);\n                U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n            }\n        }\n    };\n}\n\n// Do not use `preserves_flags` because ADDS modifies the condition flags.\natomic_rmw_ll_sc_3! {\n    _atomic_add_ldxp_stxp as atomic_add,\n    select_le_or_be!(\"adds {new_lo}, {prev_lo}, {val_lo}\", \"adds {new_hi}, {prev_hi}, {val_hi}\"), // if endian == little { new_lo = prev_lo + val_lo } else { new_hi = prev_hi + val_hi }; C = carry\n    select_le_or_be!(\"adc {new_hi}, {prev_hi}, {val_hi}\", \"adc {new_lo}, {prev_lo}, {val_lo}\"),   // if endian == little { new_hi = prev_hi + val_hi + C } else { new_lo = prev_lo + val_lo + C }\n}\natomic_rmw_cas_3! {\n    _atomic_add_casp as atomic_add,\n    select_le_or_be!(\"adds x4, x6, {val_lo}\", \"adds x5, x7, {val_hi}\"), // if endian == little { x4 = x6 + val_lo } else { x5 = x7 + val_hi }; C = carry\n    select_le_or_be!(\"adc x5, x7, {val_hi}\", \"adc x4, x6, {val_lo}\"),   // if endian == little { x5 = x7 + val_hi + C } else { x4 = x6 + val_lo + C }\n}\n\n// Do not use `preserves_flags` because SUBS modifies the condition flags.\natomic_rmw_ll_sc_3! {\n    _atomic_sub_ldxp_stxp as atomic_sub,\n    select_le_or_be!(\"subs {new_lo}, {prev_lo}, {val_lo}\", \"subs {new_hi}, {prev_hi}, {val_hi}\"), // if endian == little { new_lo = prev_lo - val_lo } else { new_hi = prev_hi - val_hi }; C = !borrow\n    select_le_or_be!(\"sbc {new_hi}, {prev_hi}, {val_hi}\", \"sbc {new_lo}, {prev_lo}, {val_lo}\"),   // if endian == little { new_hi = prev_hi - val_hi - !C } else { new_lo = prev_lo - val_lo - !C }\n}\natomic_rmw_cas_3! {\n    _atomic_sub_casp as atomic_sub,\n    select_le_or_be!(\"subs x4, x6, {val_lo}\", \"subs x5, x7, {val_hi}\"), // if endian == little { x4 = x6 - val_lo } else { x5 = x7 - val_hi }; C = !borrow\n    select_le_or_be!(\"sbc x5, x7, {val_hi}\", \"sbc x4, x6, {val_lo}\"),   // if endian == little { x5 = x7 - val_hi - !C } else { x4 = x6 - val_lo - !C }\n}\n\n#[cfg(not(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\")))]\natomic_rmw_ll_sc_3! {\n    _atomic_and_ldxp_stxp as atomic_and (preserves_flags),\n    \"and {new_lo}, {prev_lo}, {val_lo}\", // new_lo = prev_lo & val_lo\n    \"and {new_hi}, {prev_hi}, {val_hi}\", // new_hi = prev_hi & val_hi\n}\n#[cfg(not(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\")))]\natomic_rmw_cas_3! {\n    _atomic_and_casp as atomic_and,\n    \"and x4, x6, {val_lo}\", // x4 = x6 & val_lo\n    \"and x5, x7, {val_hi}\", // x5 = x7 & val_hi\n}\n#[cfg(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\"))]\n#[inline]\nunsafe fn atomic_and(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    debug_assert!(dst.addr() % 16 == 0);\n\n    // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n    // reads, 16-byte aligned, that there are no concurrent non-atomic operations,\n    // and the CPU supports FEAT_LSE128.\n    //\n    // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDCLRP--LDCLRPA--LDCLRPAL--LDCLRPL--Atomic-bit-clear-on-quadword-in-memory-\n    unsafe {\n        let val = U128 { whole: !val };\n        let (prev_lo, prev_hi);\n        #[cfg(not(portable_atomic_pre_llvm_16))]\n        macro_rules! clear {\n            ($acquire:tt, $release:tt, $_msvc_fence:tt) => {\n                asm!(\n                    start_lse128!(),\n                    concat!(\"ldclrp\", $acquire, $release, \" {val_lo}, {val_hi}, [{dst}]\"), // atomic { _x = *dst; *dst = _x & !val; val = _x }\n                    dst = in(reg) ptr_reg!(dst),\n                    val_lo = inout(reg) val.pair.lo => prev_lo,\n                    val_hi = inout(reg) val.pair.hi => prev_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(not(portable_atomic_pre_llvm_16))]\n        atomic_rmw!(clear, order);\n        // LLVM supports FEAT_LSE128 instructions on LLVM 16+, so use .inst directive on old LLVM.\n        // https://github.com/llvm/llvm-project/commit/7fea6f2e0e606e5339c3359568f680eaf64aa306\n        #[cfg(portable_atomic_pre_llvm_16)]\n        macro_rules! clear {\n            ($order:tt, $_msvc_fence:tt) => {\n                asm!(\n                    // ldclrp{,a,l,al} x8, x1, [x0] // atomic { _x = *x0; *x0 = _x & !x8:x1; x8:x1 = _x }\n                    concat!(\".inst 0x19\", $order, \"11008\"),\n                    in(\"x0\") ptr_reg!(dst),\n                    inout(\"x8\") val.pair.lo => prev_lo,\n                    inout(\"x1\") val.pair.hi => prev_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(portable_atomic_pre_llvm_16)]\n        atomic_rmw_inst!(clear, order);\n        U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n    }\n}\n\natomic_rmw_ll_sc_3! {\n    _atomic_nand_ldxp_stxp as atomic_nand (preserves_flags),\n    \"and {new_lo}, {prev_lo}, {val_lo}\", // new_lo = prev_lo & val_lo\n    \"and {new_hi}, {prev_hi}, {val_hi}\", // new_hi = prev_hi & val_hi\n    \"mvn {new_lo}, {new_lo}\",            // new_lo = !new_lo\n    \"mvn {new_hi}, {new_hi}\",            // new_hi = !new_hi\n}\natomic_rmw_cas_3! {\n    _atomic_nand_casp as atomic_nand,\n    \"and x4, x6, {val_lo}\", // x4 = x6 & val_lo\n    \"and x5, x7, {val_hi}\", // x5 = x7 & val_hi\n    \"mvn x4, x4\",           // x4 = !x4\n    \"mvn x5, x5\",           // x5 = !x5\n}\n\n#[cfg(not(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\")))]\natomic_rmw_ll_sc_3! {\n    _atomic_or_ldxp_stxp as atomic_or (preserves_flags),\n    \"orr {new_lo}, {prev_lo}, {val_lo}\", // new_lo = prev_lo | val_lo\n    \"orr {new_hi}, {prev_hi}, {val_hi}\", // new_hi = prev_hi | val_hi\n}\n#[cfg(not(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\")))]\natomic_rmw_cas_3! {\n    _atomic_or_casp as atomic_or,\n    \"orr x4, x6, {val_lo}\", // x4 = x6 | val_lo\n    \"orr x5, x7, {val_hi}\", // x5 = x7 | val_hi\n}\n#[cfg(any(target_feature = \"lse128\", portable_atomic_target_feature = \"lse128\"))]\n#[inline]\nunsafe fn atomic_or(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    debug_assert!(dst.addr() % 16 == 0);\n\n    // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n    // reads, 16-byte aligned, that there are no concurrent non-atomic operations,\n    // and the CPU supports FEAT_LSE128.\n    //\n    // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/Base-Instructions/LDSETP--LDSETPA--LDSETPAL--LDSETPL--Atomic-bit-set-on-quadword-in-memory-\n    unsafe {\n        let val = U128 { whole: val };\n        let (prev_lo, prev_hi);\n        #[cfg(not(portable_atomic_pre_llvm_16))]\n        macro_rules! or {\n            ($acquire:tt, $release:tt, $_msvc_fence:tt) => {\n                asm!(\n                    start_lse128!(),\n                    concat!(\"ldsetp\", $acquire, $release, \" {val_lo}, {val_hi}, [{dst}]\"), // atomic { _x = *dst; *dst = _x | val; val = _x }\n                    dst = in(reg) ptr_reg!(dst),\n                    val_lo = inout(reg) val.pair.lo => prev_lo,\n                    val_hi = inout(reg) val.pair.hi => prev_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(not(portable_atomic_pre_llvm_16))]\n        atomic_rmw!(or, order);\n        // LLVM supports FEAT_LSE128 instructions on LLVM 16+, so use .inst directive on old LLVM.\n        // https://github.com/llvm/llvm-project/commit/7fea6f2e0e606e5339c3359568f680eaf64aa306\n        #[cfg(portable_atomic_pre_llvm_16)]\n        macro_rules! or {\n            ($order:tt, $_msvc_fence:tt) => {\n                asm!(\n                    // ldsetp{,a,l,al} x2, x1, [x0] // atomic { _x = *x0; *x0 = _x | x2:x1; x2:x1 = _x }\n                    concat!(\".inst 0x19\", $order, \"13002\"),\n                    in(\"x0\") ptr_reg!(dst),\n                    inout(\"x2\") val.pair.lo => prev_lo,\n                    inout(\"x1\") val.pair.hi => prev_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(portable_atomic_pre_llvm_16)]\n        atomic_rmw_inst!(or, order);\n        U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n    }\n}\n\natomic_rmw_ll_sc_3! {\n    _atomic_xor_ldxp_stxp as atomic_xor (preserves_flags),\n    \"eor {new_lo}, {prev_lo}, {val_lo}\", // new_lo = prev_lo ^ val_lo\n    \"eor {new_hi}, {prev_hi}, {val_hi}\", // new_hi = prev_hi ^ val_hi\n}\natomic_rmw_cas_3! {\n    _atomic_xor_casp as atomic_xor,\n    \"eor x4, x6, {val_lo}\", // x4 = x6 ^ val_lo\n    \"eor x5, x7, {val_hi}\", // x5 = x7 ^ val_hi\n}\n\natomic_rmw_ll_sc_2! {\n    _atomic_not_ldxp_stxp as atomic_not (preserves_flags),\n    \"mvn {new_lo}, {prev_lo}\", // new_lo = !prev_lo\n    \"mvn {new_hi}, {prev_hi}\", // new_hi = !prev_hi\n}\natomic_rmw_cas_2! {\n    _atomic_not_casp as atomic_not,\n    \"mvn x4, x6\", // x4 = !x6\n    \"mvn x5, x7\", // x5 = !x7\n}\n\n// Do not use `preserves_flags` because NEGS modifies the condition flags.\natomic_rmw_ll_sc_2! {\n    _atomic_neg_ldxp_stxp as atomic_neg,\n    select_le_or_be!(\"negs {new_lo}, {prev_lo}\", \"negs {new_hi}, {prev_hi}\"), // if endian == little { new_lo = 0 - prev_lo } else { new_hi = 0 - prev_hi }; C = !borrow\n    select_le_or_be!(\"ngc {new_hi}, {prev_hi}\", \"ngc {new_lo}, {prev_lo}\"),   // if endian == little { new_hi = 0 - prev_hi - !C } else { new_lo = 0 - prev_lo - !C }\n}\natomic_rmw_cas_2! {\n    _atomic_neg_casp as atomic_neg,\n    select_le_or_be!(\"negs x4, x6\", \"negs x5, x7\"), // if endian == little { x4 = 0 - x6 } else { x5 = 0 - x7 }; C = !borrow\n    select_le_or_be!(\"ngc x5, x7\", \"ngc x4, x6\"),   // if endian == little { x5 = 0 - x7 - !C } else { x4 = 0 - x6 - !C }\n}\n\n// Do not use `preserves_flags` because CMP and SBCS modify the condition flags.\natomic_rmw_ll_sc_3! {\n    _atomic_max_ldxp_stxp as atomic_max,\n    select_le_or_be!(\"cmp {val_lo}, {prev_lo}\", \"cmp {val_hi}, {prev_hi}\"),             // if endian == little { C = !(val_lo < prev_lo) } else { C = !(val_hi < prev_hi) }\n    select_le_or_be!(\"sbcs xzr, {val_hi}, {prev_hi}\", \"sbcs xzr, {val_lo}, {prev_lo}\"), // if endian == little { (_, NZCV) = val_hi - prev_hi - !C } else { (_, NZCV) = val_lo - prev_lo - !C }\n    \"csel {new_hi}, {prev_hi}, {val_hi}, lt\",                                           // if N != V { new_hi = prev_hi } else { new_hi = val_hi }\n    \"csel {new_lo}, {prev_lo}, {val_lo}, lt\",                                           // if N != V { new_lo = prev_lo } else { new_lo = val_lo }\n}\natomic_rmw_cas_3! {\n    _atomic_max_casp as atomic_max,\n    select_le_or_be!(\"cmp {val_lo}, x6\", \"cmp {val_hi}, x7\"),             // if endian == little { C = !(val_lo < x6) } else { C = !(val_hi < x7) }\n    select_le_or_be!(\"sbcs xzr, {val_hi}, x7\", \"sbcs xzr, {val_lo}, x6\"), // if endian == little { (_, NZCV) = val_hi - x7 - !C } else { (_, NZCV) = val_lo - x6 - !C }\n    \"csel x5, x7, {val_hi}, lt\",                                          // if N != V { x5 = x7 } else { x5 = val_hi }\n    \"csel x4, x6, {val_lo}, lt\",                                          // if N != V { x4 = x6 } else { x4 = val_lo }\n}\n\n// Do not use `preserves_flags` because CMP and SBCS modify the condition flags.\natomic_rmw_ll_sc_3! {\n    _atomic_umax_ldxp_stxp as atomic_umax,\n    select_le_or_be!(\"cmp {val_lo}, {prev_lo}\", \"cmp {val_hi}, {prev_hi}\"),             // if endian == little { C = !(val_lo < prev_lo) } else { C = !(val_hi < prev_hi) }\n    select_le_or_be!(\"sbcs xzr, {val_hi}, {prev_hi}\", \"sbcs xzr, {val_lo}, {prev_lo}\"), // if endian == little { (_, NZCV) = val_hi - prev_hi - !C } else { (_, NZCV) = val_lo - prev_lo - !C }\n    \"csel {new_hi}, {prev_hi}, {val_hi}, lo\",                                           // if C == 0 { new_hi = prev_hi } else { new_hi = val_hi }\n    \"csel {new_lo}, {prev_lo}, {val_lo}, lo\",                                           // if C == 0 { new_hi = prev_hi } else { new_hi = val_hi }\n}\natomic_rmw_cas_3! {\n    _atomic_umax_casp as atomic_umax,\n    select_le_or_be!(\"cmp {val_lo}, x6\", \"cmp {val_hi}, x7\"),             // if endian == little { C = !(val_lo < x6) } else { C = !(val_hi < x7) }\n    select_le_or_be!(\"sbcs xzr, {val_hi}, x7\", \"sbcs xzr, {val_lo}, x6\"), // if endian == little { (_, NZCV) = val_hi - x7 - !C } else { (_, NZCV) = val_lo - x6 - !C }\n    \"csel x5, x7, {val_hi}, lo\",                                          // if C == 0 { x5 = x7 } else { x5 = val_hi }\n    \"csel x4, x6, {val_lo}, lo\",                                          // if C == 0 { x4 = x6 } else { x4 = val_lo }\n}\n\n// Do not use `preserves_flags` because CMP and SBCS modify the condition flags.\natomic_rmw_ll_sc_3! {\n    _atomic_min_ldxp_stxp as atomic_min,\n    select_le_or_be!(\"cmp {val_lo}, {prev_lo}\", \"cmp {val_hi}, {prev_hi}\"),             // if endian == little { C = !(val_lo < prev_lo) } else { C = !(val_hi < prev_hi) }\n    select_le_or_be!(\"sbcs xzr, {val_hi}, {prev_hi}\", \"sbcs xzr, {val_lo}, {prev_lo}\"), // if endian == little { (_, NZCV) = val_hi - prev_hi - !C } else { (_, NZCV) = val_lo - prev_lo - !C }\n    \"csel {new_hi}, {prev_hi}, {val_hi}, ge\",                                           // if N == V { new_hi = prev_hi } else { new_hi = val_hi }\n    \"csel {new_lo}, {prev_lo}, {val_lo}, ge\",                                           // if N == V { new_lo = prev_lo } else { new_lo = val_lo }\n}\natomic_rmw_cas_3! {\n    _atomic_min_casp as atomic_min,\n    select_le_or_be!(\"cmp {val_lo}, x6\", \"cmp {val_hi}, x7\"),             // if endian == little { C = !(val_lo < x6) } else { C = !(val_hi < x7) }\n    select_le_or_be!(\"sbcs xzr, {val_hi}, x7\", \"sbcs xzr, {val_lo}, x6\"), // if endian == little { (_, NZCV) = val_hi - x7 - !C } else { (_, NZCV) = val_lo - x6 - !C }\n    \"csel x5, x7, {val_hi}, ge\",                                          // if N == V { x5 = x7 } else { x5 = val_hi }\n    \"csel x4, x6, {val_lo}, ge\",                                          // if N == V { x4 = x6 } else { x4 = val_lo }\n}\n\n// Do not use `preserves_flags` because CMP and SBCS modify the condition flags.\natomic_rmw_ll_sc_3! {\n    _atomic_umin_ldxp_stxp as atomic_umin,\n    select_le_or_be!(\"cmp {val_lo}, {prev_lo}\", \"cmp {val_hi}, {prev_hi}\"),             // if endian == little { C = !(val_lo < prev_lo) } else { C = !(val_hi < prev_hi) }\n    select_le_or_be!(\"sbcs xzr, {val_hi}, {prev_hi}\", \"sbcs xzr, {val_lo}, {prev_lo}\"), // if endian == little { (_, NZCV) = val_hi - prev_hi - !C } else { (_, NZCV) = val_lo - prev_lo - !C }\n    \"csel {new_hi}, {prev_hi}, {val_hi}, hs\",                                           // if C == 1 { new_hi = prev_hi } else { new_hi = val_hi }\n    \"csel {new_lo}, {prev_lo}, {val_lo}, hs\",                                           // if C == 1 { new_lo = prev_lo } else { new_lo = val_lo }\n}\natomic_rmw_cas_3! {\n    _atomic_umin_casp as atomic_umin,\n    select_le_or_be!(\"cmp {val_lo}, x6\", \"cmp {val_hi}, x7\"),             // if endian == little { C = !(val_lo < x6) } else { C = !(val_hi < x7) }\n    select_le_or_be!(\"sbcs xzr, {val_hi}, x7\", \"sbcs xzr, {val_lo}, x6\"), // if endian == little { (_, NZCV) = val_hi - x7 - !C } else { (_, NZCV) = val_lo - x6 - !C }\n    \"csel x5, x7, {val_hi}, hs\",                                          // if C == 1 { x5 = x7 } else { x5 = val_hi }\n    \"csel x4, x6, {val_lo}, hs\",                                          // if C == 1 { x4 = x6 } else { x4 = val_lo }\n}\n\n#[inline]\nconst fn is_lock_free() -> bool {\n    IS_ALWAYS_LOCK_FREE\n}\nconst IS_ALWAYS_LOCK_FREE: bool = true;\n\natomic128!(AtomicI128, i128, atomic_max, atomic_min);\natomic128!(AtomicU128, u128, atomic_umax, atomic_umin);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    test_atomic_int!(i128);\n    test_atomic_int!(u128);\n\n    // load/store/swap implementation is not affected by signedness, so it is\n    // enough to test only unsigned types.\n    stress_test!(u128);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic128/intrinsics.rs",
      "sha256": "882b817a77ba6b90ad96585bdd5545c8526a9590473a93ca8dda96d91d1fcbcb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\n128-bit atomic implementation without inline assembly.\n\nAdapted from https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs.\n\nNote: This module is currently only enabled on Miri and ThreadSanitizer which\ndo not support inline assembly.\n\nThis uses `core::arch::x86_64::cmpxchg16b` on x86_64 and\n`core::intrinsics::atomic_*` on aarch64, powerpc64, and s390x.\n\nSee README.md of this directory for performance comparison with the\nimplementation with inline assembly.\n\nNote:\n- This currently needs Rust 1.70 on x86_64, otherwise nightly compilers.\n- On powerpc64, this requires LLVM 15+ and quadword-atomics target feature:\n  https://github.com/llvm/llvm-project/commit/549e118e93c666914a1045fde38a2cac33e1e445\n- On s390x, old LLVM (pre-18) generates libcalls for operations other than load/store/cmpxchg:\n  https://github.com/llvm/llvm-project/commit/c568927f3e2e7d9804ea74ecbf11c16c014ddcbc\n- On aarch64 big-endian, LLVM (as of 17) generates broken code. (wrong result in stress test)\n  (on cfg(miri)/cfg(sanitize) it may be fine though)\n- On powerpc64, LLVM (as of 17) doesn't support 128-bit atomic min/max:\n  https://github.com/llvm/llvm-project/issues/68390\n- On powerpc64le, LLVM (as of 17) generates broken code. (wrong result from fetch_add)\n- On riscv64, LLVM does not automatically use 128-bit atomic instructions even if zacas feature is\n  enabled, because doing it changes the ABI. (If the ability to do that is provided by LLVM in the\n  future, it should probably be controlled by another ABI feature similar to forced-atomics.)\n*/\n\ninclude!(\"macros.rs\");\n\n#[allow(dead_code)] // we only use compare_exchange.\n#[cfg(target_arch = \"x86_64\")]\n#[cfg(not(target_feature = \"cmpxchg16b\"))]\n#[path = \"../fallback/outline_atomics.rs\"]\nmod fallback;\n\n#[cfg(target_arch = \"x86_64\")]\n#[cfg(not(target_feature = \"cmpxchg16b\"))]\n#[path = \"../detect/x86_64.rs\"]\nmod detect;\n\n#[cfg(not(target_arch = \"x86_64\"))]\nuse core::intrinsics;\nuse core::sync::atomic::Ordering::{self, AcqRel, Acquire, Relaxed, Release, SeqCst};\n\n#[cfg(target_arch = \"x86_64\")]\n#[inline]\nfn strongest_failure_ordering(order: Ordering) -> Ordering {\n    match order {\n        Release | Relaxed => Relaxed,\n        SeqCst => SeqCst,\n        Acquire | AcqRel => Acquire,\n        _ => unreachable!(),\n    }\n}\n\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {\n    #[cfg(target_arch = \"x86_64\")]\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        let fail_order = strongest_failure_ordering(order);\n        match atomic_compare_exchange(src, 0, 0, order, fail_order) {\n            Ok(v) | Err(v) => v,\n        }\n    }\n    #[cfg(not(target_arch = \"x86_64\"))]\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_load_acquire(src),\n            Relaxed => intrinsics::atomic_load_relaxed(src),\n            SeqCst => intrinsics::atomic_load_seqcst(src),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {\n    #[cfg(target_arch = \"x86_64\")]\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        atomic_swap(dst, val, order);\n    }\n    #[cfg(not(target_arch = \"x86_64\"))]\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Release => intrinsics::atomic_store_release(dst, val),\n            Relaxed => intrinsics::atomic_store_relaxed(dst, val),\n            SeqCst => intrinsics::atomic_store_seqcst(dst, val),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_compare_exchange(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> Result<u128, u128> {\n    #[cfg(target_arch = \"x86_64\")]\n    let (val, ok) = {\n        #[target_feature(enable = \"cmpxchg16b\")]\n        #[cfg_attr(target_feature = \"cmpxchg16b\", inline)]\n        #[cfg_attr(not(target_feature = \"cmpxchg16b\"), inline(never))]\n        unsafe fn cmpxchg16b(\n            dst: *mut u128,\n            old: u128,\n            new: u128,\n            success: Ordering,\n            failure: Ordering,\n        ) -> (u128, bool) {\n            #[cfg(portable_atomic_no_strict_provenance)]\n            use crate::utils::ptr::PtrExt as _;\n            debug_assert!(dst.addr() % 16 == 0);\n            #[cfg(not(target_feature = \"cmpxchg16b\"))]\n            {\n                debug_assert!(detect::detect().cmpxchg16b());\n            }\n            // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n            // reads, 16-byte aligned (required by CMPXCHG16B), that there are no\n            // concurrent non-atomic operations, and that the CPU supports CMPXCHG16B.\n            let prev = unsafe { core::arch::x86_64::cmpxchg16b(dst, old, new, success, failure) };\n            (prev, prev == old)\n        }\n        #[cfg(target_feature = \"cmpxchg16b\")]\n        // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n        // reads, 16-byte aligned, that there are no concurrent non-atomic operations,\n        // and cfg guarantees that CMPXCHG16B is available at compile-time.\n        unsafe {\n            cmpxchg16b(dst, old, new, success, failure)\n        }\n        #[cfg(not(target_feature = \"cmpxchg16b\"))]\n        // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n        // reads, 16-byte aligned, and that there are no different kinds of concurrent accesses.\n        unsafe {\n            ifunc!(unsafe fn(\n                dst: *mut u128, old: u128, new: u128, success: Ordering, failure: Ordering\n            ) -> (u128, bool) {\n                if detect::detect().cmpxchg16b() {\n                    cmpxchg16b\n                } else {\n                    fallback::atomic_compare_exchange\n                }\n            })\n        }\n    };\n    #[cfg(not(target_arch = \"x86_64\"))]\n    // SAFETY: the caller must uphold the safety contract.\n    let (val, ok) = unsafe {\n        match (success, failure) {\n            (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),\n            (Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),\n            (Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),\n            (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new),\n            (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new),\n            (Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),\n            (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new),\n            (Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),\n            (Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),\n            (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new),\n            (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new),\n            (AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),\n            (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new),\n            (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new),\n            (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new),\n            _ => unreachable!(),\n        }\n    };\n    if ok { Ok(val) } else { Err(val) }\n}\n\n#[cfg(target_arch = \"x86_64\")]\nuse self::atomic_compare_exchange as atomic_compare_exchange_weak;\n#[cfg(not(target_arch = \"x86_64\"))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_compare_exchange_weak(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> Result<u128, u128> {\n    // SAFETY: the caller must uphold the safety contract.\n    let (val, ok) = unsafe {\n        match (success, failure) {\n            (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new),\n            (Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new),\n            (Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new),\n            (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new),\n            (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new),\n            (Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new),\n            (Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new),\n            (Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new),\n            (Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new),\n            (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new),\n            (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new),\n            (AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new),\n            (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new),\n            (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new),\n            (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new),\n            _ => unreachable!(),\n        }\n    };\n    if ok { Ok(val) } else { Err(val) }\n}\n\n#[inline(always)]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_update<F>(dst: *mut u128, order: Ordering, mut f: F) -> u128\nwhere\n    F: FnMut(u128) -> u128,\n{\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        // This is a private function and all instances of `f` only operate on the value\n        // loaded, so there is no need to synchronize the first load/failed CAS.\n        let mut prev = atomic_load(dst, Ordering::Relaxed);\n        loop {\n            let next = f(prev);\n            match atomic_compare_exchange_weak(dst, prev, next, order, Ordering::Relaxed) {\n                Ok(x) => return x,\n                Err(x) => prev = x,\n            }\n        }\n    }\n}\n\n// On x86_64, we use core::arch::x86_64::cmpxchg16b instead of core::intrinsics.\n// - On s390x, old LLVM (pre-18) generates libcalls for operations other than load/store/cmpxchg (see also module-level comment).\n#[cfg(any(target_arch = \"x86_64\", all(target_arch = \"s390x\", portable_atomic_pre_llvm_18)))]\natomic_rmw_by_atomic_update!();\n// On powerpc64, LLVM doesn't support 128-bit atomic min/max (see also module-level comment).\n#[cfg(target_arch = \"powerpc64\")]\natomic_rmw_by_atomic_update!(cmp);\n\n#[cfg(not(any(target_arch = \"x86_64\", all(target_arch = \"s390x\", portable_atomic_pre_llvm_18))))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_swap(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_xchg_acquire(dst, val),\n            Release => intrinsics::atomic_xchg_release(dst, val),\n            AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),\n            Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),\n            SeqCst => intrinsics::atomic_xchg_seqcst(dst, val),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(target_arch = \"x86_64\", all(target_arch = \"s390x\", portable_atomic_pre_llvm_18))))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_add(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_xadd_acquire(dst, val),\n            Release => intrinsics::atomic_xadd_release(dst, val),\n            AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),\n            Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),\n            SeqCst => intrinsics::atomic_xadd_seqcst(dst, val),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(target_arch = \"x86_64\", all(target_arch = \"s390x\", portable_atomic_pre_llvm_18))))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_sub(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_xsub_acquire(dst, val),\n            Release => intrinsics::atomic_xsub_release(dst, val),\n            AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),\n            Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),\n            SeqCst => intrinsics::atomic_xsub_seqcst(dst, val),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(target_arch = \"x86_64\", all(target_arch = \"s390x\", portable_atomic_pre_llvm_18))))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_and(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_and_acquire(dst, val),\n            Release => intrinsics::atomic_and_release(dst, val),\n            AcqRel => intrinsics::atomic_and_acqrel(dst, val),\n            Relaxed => intrinsics::atomic_and_relaxed(dst, val),\n            SeqCst => intrinsics::atomic_and_seqcst(dst, val),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(target_arch = \"x86_64\", all(target_arch = \"s390x\", portable_atomic_pre_llvm_18))))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_nand(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_nand_acquire(dst, val),\n            Release => intrinsics::atomic_nand_release(dst, val),\n            AcqRel => intrinsics::atomic_nand_acqrel(dst, val),\n            Relaxed => intrinsics::atomic_nand_relaxed(dst, val),\n            SeqCst => intrinsics::atomic_nand_seqcst(dst, val),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(target_arch = \"x86_64\", all(target_arch = \"s390x\", portable_atomic_pre_llvm_18))))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_or(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_or_acquire(dst, val),\n            Release => intrinsics::atomic_or_release(dst, val),\n            AcqRel => intrinsics::atomic_or_acqrel(dst, val),\n            Relaxed => intrinsics::atomic_or_relaxed(dst, val),\n            SeqCst => intrinsics::atomic_or_seqcst(dst, val),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(target_arch = \"x86_64\", all(target_arch = \"s390x\", portable_atomic_pre_llvm_18))))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_xor(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_xor_acquire(dst, val),\n            Release => intrinsics::atomic_xor_release(dst, val),\n            AcqRel => intrinsics::atomic_xor_acqrel(dst, val),\n            Relaxed => intrinsics::atomic_xor_relaxed(dst, val),\n            SeqCst => intrinsics::atomic_xor_seqcst(dst, val),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(\n    target_arch = \"x86_64\",\n    target_arch = \"powerpc64\",\n    all(target_arch = \"s390x\", portable_atomic_pre_llvm_18),\n)))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_max(dst: *mut u128, val: u128, order: Ordering) -> i128 {\n    #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_max_acquire(dst.cast::<i128>(), val as i128),\n            Release => intrinsics::atomic_max_release(dst.cast::<i128>(), val as i128),\n            AcqRel => intrinsics::atomic_max_acqrel(dst.cast::<i128>(), val as i128),\n            Relaxed => intrinsics::atomic_max_relaxed(dst.cast::<i128>(), val as i128),\n            SeqCst => intrinsics::atomic_max_seqcst(dst.cast::<i128>(), val as i128),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(\n    target_arch = \"x86_64\",\n    target_arch = \"powerpc64\",\n    all(target_arch = \"s390x\", portable_atomic_pre_llvm_18),\n)))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_min(dst: *mut u128, val: u128, order: Ordering) -> i128 {\n    #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_min_acquire(dst.cast::<i128>(), val as i128),\n            Release => intrinsics::atomic_min_release(dst.cast::<i128>(), val as i128),\n            AcqRel => intrinsics::atomic_min_acqrel(dst.cast::<i128>(), val as i128),\n            Relaxed => intrinsics::atomic_min_relaxed(dst.cast::<i128>(), val as i128),\n            SeqCst => intrinsics::atomic_min_seqcst(dst.cast::<i128>(), val as i128),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(\n    target_arch = \"x86_64\",\n    target_arch = \"powerpc64\",\n    all(target_arch = \"s390x\", portable_atomic_pre_llvm_18),\n)))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_umax(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_umax_acquire(dst, val),\n            Release => intrinsics::atomic_umax_release(dst, val),\n            AcqRel => intrinsics::atomic_umax_acqrel(dst, val),\n            Relaxed => intrinsics::atomic_umax_relaxed(dst, val),\n            SeqCst => intrinsics::atomic_umax_seqcst(dst, val),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(\n    target_arch = \"x86_64\",\n    target_arch = \"powerpc64\",\n    all(target_arch = \"s390x\", portable_atomic_pre_llvm_18),\n)))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_umin(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match order {\n            Acquire => intrinsics::atomic_umin_acquire(dst, val),\n            Release => intrinsics::atomic_umin_release(dst, val),\n            AcqRel => intrinsics::atomic_umin_acqrel(dst, val),\n            Relaxed => intrinsics::atomic_umin_relaxed(dst, val),\n            SeqCst => intrinsics::atomic_umin_seqcst(dst, val),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(any(target_arch = \"x86_64\", all(target_arch = \"s390x\", portable_atomic_pre_llvm_18))))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_not(dst: *mut u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe { atomic_xor(dst, !0, order) }\n}\n\n#[cfg(not(any(target_arch = \"x86_64\", all(target_arch = \"s390x\", portable_atomic_pre_llvm_18))))]\n#[inline]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\nunsafe fn atomic_neg(dst: *mut u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe { atomic_update(dst, order, u128::wrapping_neg) }\n}\n\n#[cfg(not(target_arch = \"x86_64\"))]\n#[inline]\nconst fn is_lock_free() -> bool {\n    IS_ALWAYS_LOCK_FREE\n}\n#[cfg(not(target_arch = \"x86_64\"))]\nconst IS_ALWAYS_LOCK_FREE: bool = true;\n\n#[cfg(target_arch = \"x86_64\")]\n#[inline]\nfn is_lock_free() -> bool {\n    #[cfg(target_feature = \"cmpxchg16b\")]\n    {\n        // CMPXCHG16B is available at compile-time.\n        true\n    }\n    #[cfg(not(target_feature = \"cmpxchg16b\"))]\n    {\n        detect::detect().cmpxchg16b()\n    }\n}\n#[cfg(target_arch = \"x86_64\")]\nconst IS_ALWAYS_LOCK_FREE: bool = cfg!(target_feature = \"cmpxchg16b\");\n\natomic128!(AtomicI128, i128, atomic_max, atomic_min);\natomic128!(AtomicU128, u128, atomic_umax, atomic_umin);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    test_atomic_int!(i128);\n    test_atomic_int!(u128);\n\n    // load/store/swap implementation is not affected by signedness, so it is\n    // enough to test only unsigned types.\n    stress_test!(u128);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic128/macros.rs",
      "sha256": "31f63dd5f6523fdc80d752afdd7b13e90394e7210b8f14bfa38a4feab0822cd5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nmacro_rules! atomic128 {\n    ($atomic_type:ident, $int_type:ident, $atomic_max:ident, $atomic_min:ident) => {\n        #[repr(C, align(16))]\n        pub(crate) struct $atomic_type {\n            v: core::cell::UnsafeCell<$int_type>,\n        }\n\n        // Send is implicitly implemented.\n        // SAFETY: any data races are prevented by atomic intrinsics.\n        unsafe impl Sync for $atomic_type {}\n\n        impl_default_no_fetch_ops!($atomic_type, $int_type);\n        impl_default_bit_opts!($atomic_type, $int_type);\n        impl $atomic_type {\n            #[inline]\n            pub(crate) const fn new(v: $int_type) -> Self {\n                Self { v: core::cell::UnsafeCell::new(v) }\n            }\n\n            #[inline]\n            pub(crate) fn is_lock_free() -> bool {\n                is_lock_free()\n            }\n            pub(crate) const IS_ALWAYS_LOCK_FREE: bool = IS_ALWAYS_LOCK_FREE;\n\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub(crate) fn load(&self, order: Ordering) -> $int_type {\n                crate::utils::assert_load_ordering(order);\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_load(self.v.get().cast::<u128>(), order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub(crate) fn store(&self, val: $int_type, order: Ordering) {\n                crate::utils::assert_store_ordering(order);\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_store(self.v.get().cast::<u128>(), val as u128, order)\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn swap(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_swap(self.v.get().cast::<u128>(), val as u128, order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub(crate) fn compare_exchange(\n                &self,\n                current: $int_type,\n                new: $int_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$int_type, $int_type> {\n                crate::utils::assert_compare_exchange_ordering(success, failure);\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    match atomic_compare_exchange(\n                        self.v.get().cast::<u128>(),\n                        current as u128,\n                        new as u128,\n                        success,\n                        failure,\n                    ) {\n                        Ok(v) => Ok(v as $int_type),\n                        Err(v) => Err(v as $int_type),\n                    }\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub(crate) fn compare_exchange_weak(\n                &self,\n                current: $int_type,\n                new: $int_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$int_type, $int_type> {\n                crate::utils::assert_compare_exchange_ordering(success, failure);\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    match atomic_compare_exchange_weak(\n                        self.v.get().cast::<u128>(),\n                        current as u128,\n                        new as u128,\n                        success,\n                        failure,\n                    ) {\n                        Ok(v) => Ok(v as $int_type),\n                        Err(v) => Err(v as $int_type),\n                    }\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_add(self.v.get().cast::<u128>(), val as u128, order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_sub(self.v.get().cast::<u128>(), val as u128, order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_and(self.v.get().cast::<u128>(), val as u128, order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_nand(self.v.get().cast::<u128>(), val as u128, order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_or(self.v.get().cast::<u128>(), val as u128, order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_xor(self.v.get().cast::<u128>(), val as u128, order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    $atomic_max(self.v.get().cast::<u128>(), val as u128, order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    $atomic_min(self.v.get().cast::<u128>(), val as u128, order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_not(&self, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_not(self.v.get().cast::<u128>(), order) as $int_type\n                }\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn not(&self, order: Ordering) {\n                self.fetch_not(order);\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_neg(&self, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_neg(self.v.get().cast::<u128>(), order) as $int_type\n                }\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn neg(&self, order: Ordering) {\n                self.fetch_neg(order);\n            }\n\n            #[inline]\n            pub(crate) const fn as_ptr(&self) -> *mut $int_type {\n                self.v.get()\n            }\n        }\n    };\n}\n\n#[cfg(any(target_arch = \"powerpc64\", target_arch = \"s390x\", target_arch = \"x86_64\"))]\n#[allow(unused_macros)] // also used by intrinsics.rs\nmacro_rules! atomic_rmw_by_atomic_update {\n    () => {\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_swap(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, |_| val) }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_add(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, |x| x.wrapping_add(val)) }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_sub(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, |x| x.wrapping_sub(val)) }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_and(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, |x| x & val) }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_nand(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, |x| !(x & val)) }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_or(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, |x| x | val) }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_xor(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, |x| x ^ val) }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_not(dst: *mut u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, |x| !x) }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_neg(dst: *mut u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, u128::wrapping_neg) }\n        }\n        atomic_rmw_by_atomic_update!(cmp);\n    };\n    (cmp) => {\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_max(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                atomic_update(dst, order, |x| core::cmp::max(x as i128, val as i128) as u128)\n            }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_umax(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, |x| core::cmp::max(x, val)) }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_min(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                atomic_update(dst, order, |x| core::cmp::min(x as i128, val as i128) as u128)\n            }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        unsafe fn atomic_umin(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { atomic_update(dst, order, |x| core::cmp::min(x, val)) }\n        }\n    };\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic128/mod.rs",
      "sha256": "4d12d39ed3c0e5ab46724ac9536598ccc0028147d258b739ed27212c4e4d5e7e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\n128-bit atomic implementations on 64-bit architectures\n\nSee README.md for details.\n*/\n\n// AArch64\n#[cfg(any(\n    all(\n        target_arch = \"aarch64\",\n        not(all(\n            any(miri, portable_atomic_sanitize_thread),\n            not(portable_atomic_atomic_intrinsics),\n        )),\n        any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n    ),\n    all(\n        target_arch = \"arm64ec\",\n        not(all(\n            any(miri, portable_atomic_sanitize_thread),\n            not(portable_atomic_atomic_intrinsics),\n        )),\n        not(portable_atomic_no_asm),\n    ),\n))]\n// Use intrinsics.rs on Miri and Sanitizer that do not support inline assembly.\n#[cfg_attr(any(miri, portable_atomic_sanitize_thread), path = \"intrinsics.rs\")]\npub(super) mod aarch64;\n\n// powerpc64\n#[cfg(all(\n    target_arch = \"powerpc64\",\n    not(all(\n        any(miri, portable_atomic_sanitize_thread),\n        not(portable_atomic_atomic_intrinsics),\n    )),\n    not(portable_atomic_no_asm),\n    any(\n        target_feature = \"quadword-atomics\",\n        portable_atomic_target_feature = \"quadword-atomics\",\n        all(\n            feature = \"fallback\",\n            not(portable_atomic_no_outline_atomics),\n            any(\n                all(\n                    target_os = \"linux\",\n                    any(\n                        all(\n                            target_env = \"gnu\",\n                            any(target_endian = \"little\", not(target_feature = \"crt-static\")),\n                        ),\n                        all(\n                            target_env = \"musl\",\n                            any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                        ),\n                        target_env = \"ohos\",\n                        all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                        portable_atomic_outline_atomics,\n                    ),\n                ),\n                target_os = \"android\",\n                all(\n                    target_os = \"freebsd\",\n                    any(\n                        target_endian = \"little\",\n                        not(target_feature = \"crt-static\"),\n                        portable_atomic_outline_atomics,\n                    ),\n                ),\n                target_os = \"openbsd\",\n                all(\n                    target_os = \"aix\",\n                    not(portable_atomic_pre_llvm_20),\n                    any(test, portable_atomic_outline_atomics), // TODO(aix): currently disabled by default\n                ),\n            ),\n            not(any(miri, portable_atomic_sanitize_thread)),\n        ),\n    ),\n))]\n// Use intrinsics.rs on Miri and Sanitizer that do not support inline assembly.\n#[cfg_attr(any(miri, portable_atomic_sanitize_thread), path = \"intrinsics.rs\")]\npub(super) mod powerpc64;\n\n// riscv64\n#[cfg(all(\n    target_arch = \"riscv64\",\n    not(any(miri, portable_atomic_sanitize_thread)),\n    any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n    any(\n        target_feature = \"zacas\",\n        portable_atomic_target_feature = \"zacas\",\n        all(\n            feature = \"fallback\",\n            not(portable_atomic_no_outline_atomics),\n            any(target_os = \"linux\", target_os = \"android\"),\n        ),\n    ),\n))]\npub(super) mod riscv64;\n\n// s390x\n#[cfg(all(\n    target_arch = \"s390x\",\n    not(all(any(miri, portable_atomic_sanitize_thread), not(portable_atomic_atomic_intrinsics))),\n    not(portable_atomic_no_asm),\n))]\n// Use intrinsics.rs on Miri and Sanitizer that do not support inline assembly.\n#[cfg_attr(any(miri, portable_atomic_sanitize_thread), path = \"intrinsics.rs\")]\npub(super) mod s390x;\n\n// x86_64\n#[cfg(all(\n    target_arch = \"x86_64\",\n    not(all(any(miri, portable_atomic_sanitize_thread), portable_atomic_no_cmpxchg16b_intrinsic)),\n    any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n    any(\n        target_feature = \"cmpxchg16b\",\n        portable_atomic_target_feature = \"cmpxchg16b\",\n        all(\n            feature = \"fallback\",\n            not(portable_atomic_no_outline_atomics),\n            not(any(target_env = \"sgx\", miri)),\n        ),\n    ),\n))]\n// Use intrinsics.rs on Miri and Sanitizer that do not support inline assembly.\n#[cfg_attr(any(miri, portable_atomic_sanitize_thread), path = \"intrinsics.rs\")]\npub(super) mod x86_64;\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic128/powerpc64.rs",
      "sha256": "f1831b186b89049aba31be4c4cd37b5572554f2655944d5cfc04ab5654691715",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\n128-bit atomic implementation on PowerPC64.\n\nThis architecture provides the following 128-bit atomic instructions:\n\n- lq/stq: load/store (ISA 2.07 or later, included in the Linux Compliancy subset and AIX Compliancy subset)\n- lqarx/stqcx.: LL/SC (ISA 2.07 or later, included in the Linux Compliancy subset and AIX Compliancy subset)\n- plq/pstq: load/store (ISA 3.1 or later, included in the Linux Compliancy subset and AIX Compliancy subset)\n\nSee \"Atomic operation overview by architecture\" in atomic-maybe-uninit for a more comprehensive and\ndetailed description of the atomic and synchronize instructions in this architecture:\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#powerpc\n\nNote that we do not separate LL and SC into separate functions, but handle\nthem within a single asm block. This is because it is theoretically possible\nfor the compiler to insert operations that might clear the reservation between\nLL and SC. See aarch64.rs for details.\n\nNote: On Miri and ThreadSanitizer which do not support inline assembly, we don't use\nthis module and use intrinsics.rs instead.\n\nRefs:\n- Power ISA\n  https://openpowerfoundation.org/specifications/isa\n- AIX Assembler language reference\n  https://www.ibm.com/docs/en/aix/7.3?topic=aix-assembler-language-reference\n- atomic-maybe-uninit\n  https://github.com/taiki-e/atomic-maybe-uninit\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\ninclude!(\"macros.rs\");\n\n#[cfg(not(any(\n    target_feature = \"quadword-atomics\",\n    portable_atomic_target_feature = \"quadword-atomics\",\n)))]\n#[path = \"../fallback/outline_atomics.rs\"]\nmod fallback;\n\n// On musl with static linking, it seems that getauxval is not always available.\n// See detect/auxv.rs for more.\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(\n    test,\n    not(any(\n        target_feature = \"quadword-atomics\",\n        portable_atomic_target_feature = \"quadword-atomics\",\n    )),\n))]\n#[cfg(any(\n    all(\n        target_os = \"linux\",\n        any(\n            all(\n                target_env = \"gnu\",\n                any(target_endian = \"little\", not(target_feature = \"crt-static\")),\n            ),\n            all(target_env = \"musl\", any(not(target_feature = \"crt-static\"), feature = \"std\")),\n            target_env = \"ohos\",\n            all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n            portable_atomic_outline_atomics,\n        ),\n    ),\n    target_os = \"android\",\n    all(\n        target_os = \"freebsd\",\n        any(\n            target_endian = \"little\",\n            not(target_feature = \"crt-static\"),\n            portable_atomic_outline_atomics,\n        ),\n    ),\n    target_os = \"openbsd\",\n))]\n#[path = \"../detect/auxv.rs\"]\nmod detect;\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(\n    test,\n    not(any(\n        target_feature = \"quadword-atomics\",\n        portable_atomic_target_feature = \"quadword-atomics\",\n    )),\n))]\n#[cfg(target_os = \"aix\")]\n#[cfg(not(portable_atomic_pre_llvm_20))] // SIGTRAP on LLVM 19\n#[cfg(any(test, portable_atomic_outline_atomics))] // TODO(aix): currently disabled by default\n#[path = \"../detect/powerpc64_aix.rs\"]\nmod detect;\n\nuse core::{arch::asm, sync::atomic::Ordering};\n\n#[cfg(portable_atomic_no_strict_provenance)]\nuse crate::utils::ptr::PtrExt as _;\nuse crate::utils::{Pair, U128};\n\nmacro_rules! debug_assert_pwr8 {\n    () => {\n        #[cfg(not(any(\n            target_feature = \"quadword-atomics\",\n            portable_atomic_target_feature = \"quadword-atomics\",\n        )))]\n        {\n            debug_assert!(detect::detect().quadword_atomics());\n        }\n    };\n}\n\n// Refs: https://www.ibm.com/docs/en/aix/7.3?topic=ops-machine-pseudo-op\n//\n// This is similar to #[target_feature(enable = \"quadword-atomics\")], except that there are\n// no compiler guarantees regarding (un)inlining, and the scope is within an asm\n// block rather than a function. We use this directive because #[target_feature(enable = \"quadword-atomics\")]\n// is unstable and unavailable on old nightly and incompatible with rustc_codegen_cranelift:\n// https://github.com/rust-lang/rustc_codegen_cranelift/issues/1400#issuecomment-1774599775\n//\n// Note: start_pwr8 and end_pwr8 must be used in pairs.\n//\n// Note: If power8 instructions are not available at compile-time, we must guarantee that\n// the function that uses it is not inlined into a function where it is not\n// clear whether power8 instructions are available. Otherwise, (even if we checked whether\n// power8 instructions are available at run-time) optimizations that reorder its\n// instructions across the if condition might introduce undefined behavior.\n// (see also https://rust-lang.github.io/rfcs/2045-target-feature.html#safely-inlining-target_feature-functions-on-more-contexts)\n// However, our code uses the ifunc helper macro that works with function pointers,\n// so we don't have to worry about this unless calling without helper macro.\nmacro_rules! start_pwr8 {\n    () => {\n        \".machine push\\n.machine power8\"\n    };\n}\nmacro_rules! end_pwr8 {\n    () => {\n        \".machine pop\"\n    };\n}\n\nmacro_rules! atomic_rmw {\n    ($op:ident, $order:ident) => {\n        match $order {\n            Ordering::Relaxed => $op!(\"\", \"\"),\n            Ordering::Acquire => $op!(\"isync\", \"\"),\n            Ordering::Release => $op!(\"\", \"lwsync\"),\n            Ordering::AcqRel => $op!(\"isync\", \"lwsync\"),\n            Ordering::SeqCst => $op!(\"isync\", \"sync\"),\n            _ => unreachable!(),\n        }\n    };\n}\nmacro_rules! atomic_cas {\n    ($op:ident, $success:ident, $failure:ident) => {\n        if $failure == Ordering::Relaxed {\n            match $success {\n                Ordering::Relaxed => $op!(\"\", \"\", \"\"),\n                Ordering::Acquire => $op!(\"\", \"isync\", \"\"),\n                Ordering::Release => $op!(\"\", \"\", \"lwsync\"),\n                Ordering::AcqRel => $op!(\"\", \"isync\", \"lwsync\"),\n                Ordering::SeqCst => $op!(\"\", \"isync\", \"sync\"),\n                _ => unreachable!(),\n            }\n        } else {\n            let order = crate::utils::upgrade_success_ordering($success, $failure);\n            match order {\n                // Relaxed and Release are covered in $failure == Relaxed branch.\n                Ordering::Acquire => $op!(\"isync\", \"\", \"\"),\n                Ordering::AcqRel => $op!(\"isync\", \"\", \"lwsync\"),\n                Ordering::SeqCst => $op!(\"isync\", \"\", \"sync\"),\n                _ => unreachable!(),\n            }\n        }\n    };\n}\n\n// Extracts and checks the EQ bit of cr0.\n#[inline]\nfn test_cr0_eq(cr: u64) -> bool {\n    cr & 0x20000000 != 0\n}\n\n// If quadword-atomics is available at compile-time, we can always use pwr8_fn.\n#[cfg(any(\n    target_feature = \"quadword-atomics\",\n    portable_atomic_target_feature = \"quadword-atomics\",\n))]\nuse self::atomic_load_pwr8 as atomic_load;\n// Otherwise, we need to do run-time detection and can use pwr8_fn only if quadword-atomics is available.\n#[cfg(not(any(\n    target_feature = \"quadword-atomics\",\n    portable_atomic_target_feature = \"quadword-atomics\",\n)))]\n#[inline]\nunsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {\n    fn_alias! {\n        // inline(never) is just a hint and also not strictly necessary\n        // because we use ifunc helper macro, but used for clarity.\n        #[inline(never)]\n        unsafe fn(src: *mut u128) -> u128;\n        atomic_load_pwr8_relaxed = atomic_load_pwr8(Ordering::Relaxed);\n        atomic_load_pwr8_acquire = atomic_load_pwr8(Ordering::Acquire);\n        atomic_load_pwr8_seqcst = atomic_load_pwr8(Ordering::SeqCst);\n    }\n    // SAFETY: the caller must uphold the safety contract.\n    // we only calls atomic_load_pwr8 if quadword-atomics is available.\n    unsafe {\n        match order {\n            Ordering::Relaxed => {\n                ifunc!(unsafe fn(src: *mut u128) -> u128 {\n                    if detect::detect().quadword_atomics() {\n                        atomic_load_pwr8_relaxed\n                    } else {\n                        fallback::atomic_load_non_seqcst\n                    }\n                })\n            }\n            Ordering::Acquire => {\n                ifunc!(unsafe fn(src: *mut u128) -> u128 {\n                    if detect::detect().quadword_atomics() {\n                        atomic_load_pwr8_acquire\n                    } else {\n                        fallback::atomic_load_non_seqcst\n                    }\n                })\n            }\n            Ordering::SeqCst => {\n                ifunc!(unsafe fn(src: *mut u128) -> u128 {\n                    if detect::detect().quadword_atomics() {\n                        atomic_load_pwr8_seqcst\n                    } else {\n                        fallback::atomic_load_seqcst\n                    }\n                })\n            }\n            _ => unreachable!(),\n        }\n    }\n}\n#[inline]\nunsafe fn atomic_load_pwr8(src: *mut u128, order: Ordering) -> u128 {\n    debug_assert!(src.addr() % 16 == 0);\n    debug_assert_pwr8!();\n    let (out_hi, out_lo);\n\n    // SAFETY: the caller must uphold the safety contract.\n    //\n    // Refs: Section 3.3.4 \"Fixed Point Load and Store Quadword Instructions\" of Power ISA 3.1C Book I\n    unsafe {\n        macro_rules! atomic_load_acquire {\n            ($release:tt) => {\n                asm!(\n                    start_pwr8!(),\n                    $release,\n                    \"lq %r4, 0({src})\", // atomic { r4:r5 = *src }\n                    \"cmpw %r4, %r4\",    // if r4 == r4 { cr0.EQ = 1 } else { cr0.EQ = 0 }\n                    \"bne- %cr0, 2f\",    // if unlikely(cr0.EQ == 0) { jump 'never }\n                    \"2:\", // 'never:\n                    \"isync\",            // fence (works in combination with a branch that depends on the loaded value)\n                    end_pwr8!(),\n                    src = in(reg_nonzero) ptr_reg!(src),\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater.\n                    out(\"r4\") out_hi,\n                    out(\"r5\") out_lo,\n                    out(\"cr0\") _,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        match order {\n            Ordering::Relaxed => {\n                asm!(\n                    start_pwr8!(),\n                    \"lq %r4, 0({src})\", // atomic { r4:r5 = *src }\n                    end_pwr8!(),\n                    src = in(reg_nonzero) ptr_reg!(src),\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater.\n                    out(\"r4\") out_hi,\n                    out(\"r5\") out_lo,\n                    options(nostack, preserves_flags),\n                );\n            }\n            Ordering::Acquire => atomic_load_acquire!(\"\"),\n            Ordering::SeqCst => atomic_load_acquire!(\"sync\"),\n            _ => unreachable!(),\n        }\n        U128 { pair: Pair { hi: out_hi, lo: out_lo } }.whole\n    }\n}\n\n// If quadword-atomics is available at compile-time, we can always use pwr8_fn.\n#[cfg(any(\n    target_feature = \"quadword-atomics\",\n    portable_atomic_target_feature = \"quadword-atomics\",\n))]\nuse self::atomic_store_pwr8 as atomic_store;\n// Otherwise, we need to do run-time detection and can use pwr8_fn only if quadword-atomics is available.\n#[cfg(not(any(\n    target_feature = \"quadword-atomics\",\n    portable_atomic_target_feature = \"quadword-atomics\",\n)))]\n#[inline]\nunsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {\n    fn_alias! {\n        // inline(never) is just a hint and also not strictly necessary\n        // because we use ifunc helper macro, but used for clarity.\n        #[inline(never)]\n        unsafe fn(dst: *mut u128, val: u128);\n        atomic_store_pwr8_relaxed = atomic_store_pwr8(Ordering::Relaxed);\n        atomic_store_pwr8_release = atomic_store_pwr8(Ordering::Release);\n        atomic_store_pwr8_seqcst = atomic_store_pwr8(Ordering::SeqCst);\n    }\n    // SAFETY: the caller must uphold the safety contract.\n    // we only calls atomic_store_pwr8 if quadword-atomics is available.\n    unsafe {\n        match order {\n            Ordering::Relaxed => {\n                ifunc!(unsafe fn(dst: *mut u128, val: u128) {\n                    if detect::detect().quadword_atomics() {\n                        atomic_store_pwr8_relaxed\n                    } else {\n                        fallback::atomic_store_non_seqcst\n                    }\n                });\n            }\n            Ordering::Release => {\n                ifunc!(unsafe fn(dst: *mut u128, val: u128) {\n                    if detect::detect().quadword_atomics() {\n                        atomic_store_pwr8_release\n                    } else {\n                        fallback::atomic_store_non_seqcst\n                    }\n                });\n            }\n            Ordering::SeqCst => {\n                ifunc!(unsafe fn(dst: *mut u128, val: u128) {\n                    if detect::detect().quadword_atomics() {\n                        atomic_store_pwr8_seqcst\n                    } else {\n                        fallback::atomic_store_seqcst\n                    }\n                });\n            }\n            _ => unreachable!(),\n        }\n    }\n}\n#[inline]\nunsafe fn atomic_store_pwr8(dst: *mut u128, val: u128, order: Ordering) {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_pwr8!();\n    let val = U128 { whole: val };\n\n    // SAFETY: the caller must uphold the safety contract.\n    //\n    // Refs: Section 3.3.4 \"Fixed Point Load and Store Quadword Instructions\" of Power ISA 3.1C Book I\n    unsafe {\n        macro_rules! atomic_store {\n            ($release:tt) => {\n                asm!(\n                    start_pwr8!(),\n                    $release,            // fence\n                    \"stq %r4, 0({dst})\", // atomic { *dst = r4:r5 }\n                    end_pwr8!(),\n                    dst = in(reg_nonzero) ptr_reg!(dst),\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater.\n                    in(\"r4\") val.pair.hi,\n                    in(\"r5\") val.pair.lo,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        match order {\n            Ordering::Relaxed => atomic_store!(\"\"),\n            Ordering::Release => atomic_store!(\"lwsync\"),\n            Ordering::SeqCst => atomic_store!(\"sync\"),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[inline]\nunsafe fn atomic_compare_exchange(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> Result<u128, u128> {\n    #[cfg(any(\n        target_feature = \"quadword-atomics\",\n        portable_atomic_target_feature = \"quadword-atomics\",\n    ))]\n    // SAFETY: the caller must uphold the safety contract.\n    // cfg guarantees that quadword atomics instructions are available at compile-time.\n    let (prev, ok) = unsafe { atomic_compare_exchange_pwr8(dst, old, new, success, failure) };\n    #[cfg(not(any(\n        target_feature = \"quadword-atomics\",\n        portable_atomic_target_feature = \"quadword-atomics\",\n    )))]\n    // SAFETY: the caller must uphold the safety contract.\n    let (prev, ok) = {\n        fn_alias! {\n            // inline(never) is just a hint and also not strictly necessary\n            // because we use ifunc helper macro, but used for clarity.\n            #[inline(never)]\n            unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool);\n            pwr8_relaxed_fn = atomic_compare_exchange_pwr8(Ordering::Relaxed, Ordering::Relaxed);\n            pwr8_acquire_fn = atomic_compare_exchange_pwr8(Ordering::Acquire, Ordering::Acquire);\n            pwr8_release_fn = atomic_compare_exchange_pwr8(Ordering::Release, Ordering::Relaxed);\n            pwr8_acqrel_fn = atomic_compare_exchange_pwr8(Ordering::AcqRel, Ordering::Acquire);\n            pwr8_seqcst_fn = atomic_compare_exchange_pwr8(Ordering::SeqCst, Ordering::SeqCst);\n        }\n        // SAFETY: the caller must uphold the safety contract.\n        // we only calls pwr8_fn if quadword-atomics is available.\n        unsafe {\n            let success = crate::utils::upgrade_success_ordering(success, failure);\n            match success {\n                Ordering::Relaxed => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n                        if detect::detect().quadword_atomics() {\n                            pwr8_relaxed_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::Acquire => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n                        if detect::detect().quadword_atomics() {\n                            pwr8_acquire_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::Release => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n                        if detect::detect().quadword_atomics() {\n                            pwr8_release_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::AcqRel => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n                        if detect::detect().quadword_atomics() {\n                            pwr8_acqrel_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::SeqCst => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n                        if detect::detect().quadword_atomics() {\n                            pwr8_seqcst_fn\n                        } else {\n                            fallback::atomic_compare_exchange_seqcst\n                        }\n                    })\n                }\n                _ => unreachable!(),\n            }\n        }\n    };\n    if ok { Ok(prev) } else { Err(prev) }\n}\n#[inline]\nunsafe fn atomic_compare_exchange_pwr8(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> (u128, bool) {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_pwr8!();\n    let old = U128 { whole: old };\n    let new = U128 { whole: new };\n    let (mut prev_hi, mut prev_lo);\n    let mut r;\n\n    // SAFETY: the caller must uphold the safety contract.\n    //\n    // Refs: Section 4.6.2.2 \"128-bit Load And Reserve and Store Conditional Instructions\" of Power ISA 3.1C Book II\n    unsafe {\n        macro_rules! cmpxchg {\n            ($acquire_always:tt, $acquire_success:tt, $release:tt) => {\n                asm!(\n                    start_pwr8!(),\n                    $release,                               // fence\n                    \"2:\", // 'retry:\n                        \"lqarx %r8, 0, {dst}\",              // atomic { RESERVE = (dst, 16); r8:r9 = *dst }\n                        \"xor {tmp_lo}, %r9, {old_lo}\",      // tmp_lo = r9 ^ old_lo\n                        \"xor {tmp_hi}, %r8, {old_hi}\",      // tmp_hi = r8 ^ old_hi\n                        \"or. {tmp_lo}, {tmp_lo}, {tmp_hi}\", // tmp_lo |= tmp_hi; if tmp_lo == 0 { cr0.EQ = 1 } else { cr0.EQ = 0 }\n                        \"bne %cr0, 3f\",                     // if cr0.EQ == 0 { jump 'cmp-fail }\n                        \"stqcx. %r6, 0, {dst}\",             // atomic { if RESERVE == (dst, 16) { *dst = r6:r7; cr0.EQ = 1 } else { cr0.EQ = 0 }; RESERVE = None }\n                        \"bne %cr0, 2b\",                     // if cr0.EQ == 0 { jump 'retry }\n                        $acquire_success,                   // fence\n                    \"3:\", // 'cmp-fail:\n                    $acquire_always,                        // fence\n                    \"mfcr {tmp_lo}\",                        // tmp_lo = zero_extend(cr)\n                    end_pwr8!(),\n                    dst = in(reg_nonzero) ptr_reg!(dst),\n                    old_hi = in(reg) old.pair.hi,\n                    old_lo = in(reg) old.pair.lo,\n                    tmp_hi = out(reg) _,\n                    tmp_lo = out(reg) r,\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater.\n                    in(\"r6\") new.pair.hi,\n                    in(\"r7\") new.pair.lo,\n                    out(\"r8\") prev_hi,\n                    out(\"r9\") prev_lo,\n                    out(\"cr0\") _,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        atomic_cas!(cmpxchg, success, failure);\n        // if compare failed EQ bit is cleared, if store succeeds EQ bit is set.\n        (U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole, test_cr0_eq(r))\n    }\n}\n\n// Always use strong CAS for outline-atomics.\n#[cfg(not(any(\n    target_feature = \"quadword-atomics\",\n    portable_atomic_target_feature = \"quadword-atomics\",\n)))]\nuse self::atomic_compare_exchange as atomic_compare_exchange_weak;\n#[cfg(any(\n    target_feature = \"quadword-atomics\",\n    portable_atomic_target_feature = \"quadword-atomics\",\n))]\n#[inline]\nunsafe fn atomic_compare_exchange_weak(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> Result<u128, u128> {\n    // SAFETY: the caller must uphold the safety contract.\n    // cfg guarantees that quadword atomics instructions are available at compile-time.\n    let (prev, ok) = unsafe { atomic_compare_exchange_weak_pwr8(dst, old, new, success, failure) };\n    if ok { Ok(prev) } else { Err(prev) }\n}\n#[cfg(any(\n    target_feature = \"quadword-atomics\",\n    portable_atomic_target_feature = \"quadword-atomics\",\n))]\n#[inline]\nunsafe fn atomic_compare_exchange_weak_pwr8(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> (u128, bool) {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_pwr8!();\n    let old = U128 { whole: old };\n    let new = U128 { whole: new };\n    let (mut prev_hi, mut prev_lo);\n    let mut r;\n\n    // SAFETY: the caller must uphold the safety contract.\n    //\n    // Refs: Section 4.6.2.2 \"128-bit Load And Reserve and Store Conditional Instructions\" of Power ISA 3.1C Book II\n    unsafe {\n        macro_rules! cmpxchg_weak {\n            ($acquire_always:tt, $acquire_success:tt, $release:tt) => {\n                asm!(\n                    start_pwr8!(),\n                    $release,                           // fence\n                    \"lqarx %r8, 0, {dst}\",              // atomic { RESERVE = (dst, 16); r8:r9 = *dst }\n                    \"xor {tmp_lo}, %r9, {old_lo}\",      // tmp_lo = r9 ^ old_lo\n                    \"xor {tmp_hi}, %r8, {old_hi}\",      // tmp_hi = r8 ^ old_hi\n                    \"or. {tmp_lo}, {tmp_lo}, {tmp_hi}\", // tmp_lo |= tmp_hi; if tmp_lo == 0 { cr0.EQ = 1 } else { cr0.EQ = 0 }\n                    \"bne %cr0, 3f\",                     // if cr0.EQ == 0 { jump 'cmp-fail }\n                    \"stqcx. %r6, 0, {dst}\",             // atomic { if RESERVE == (dst, 16) { *dst = r6:r7; cr0.EQ = 1 } else { cr0.EQ = 0 }; RESERVE = None }\n                    $acquire_success,                   // fence\n                    \"3:\", // 'cmp-fail:\n                    $acquire_always,                    // fence\n                    \"mfcr {tmp_lo}\",                    // tmp_lo = zero_extend(cr)\n                    end_pwr8!(),\n                    dst = in(reg_nonzero) ptr_reg!(dst),\n                    old_hi = in(reg) old.pair.hi,\n                    old_lo = in(reg) old.pair.lo,\n                    tmp_hi = out(reg) _,\n                    tmp_lo = out(reg) r,\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater.\n                    in(\"r6\") new.pair.hi,\n                    in(\"r7\") new.pair.lo,\n                    out(\"r8\") prev_hi,\n                    out(\"r9\") prev_lo,\n                    out(\"cr0\") _,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        atomic_cas!(cmpxchg_weak, success, failure);\n        // if compare or store failed EQ bit is cleared, if store succeeds EQ bit is set.\n        (U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole, test_cr0_eq(r))\n    }\n}\n\n// Do not use atomic_rmw_ll_sc_3 because it needs extra MR to implement swap.\n#[inline]\nunsafe fn atomic_swap_pwr8(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_pwr8!();\n    let val = U128 { whole: val };\n    let (mut prev_hi, mut prev_lo);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        macro_rules! swap {\n            ($acquire:tt, $release:tt) => {\n                asm!(\n                    start_pwr8!(),\n                    $release,                   // fence\n                    \"2:\", // 'retry:\n                        \"lqarx %r6, 0, {dst}\",  // atomic { RESERVE = (dst, 16); r6:r7 = *dst }\n                        \"stqcx. %r8, 0, {dst}\", // atomic { if RESERVE == (dst, 16) { *dst = r8:r9; cr0.EQ = 1 } else { cr0.EQ = 0 }; RESERVE = None }\n                        \"bne %cr0, 2b\",         // if cr0.EQ == 0 { jump 'retry }\n                    $acquire,                   // fence\n                    end_pwr8!(),\n                    dst = in(reg_nonzero) ptr_reg!(dst),\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater.\n                    out(\"r6\") prev_hi,\n                    out(\"r7\") prev_lo,\n                    in(\"r8\") val.pair.hi,\n                    in(\"r9\") val.pair.lo,\n                    out(\"cr0\") _,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        atomic_rmw!(swap, order);\n        U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole\n    }\n}\n\n/// Atomic RMW by LL/SC loop (3 arguments)\n/// `unsafe fn(dst: *mut u128, val: u128, order: Ordering) -> u128;`\n///\n/// $op can use the following registers:\n/// - val_hi/val_lo pair: val argument (read-only for `$op`)\n/// - r6/r7 pair: previous value loaded by ll (read-only for `$op`)\n/// - r8/r9 pair: new value that will be stored by sc\nmacro_rules! atomic_rmw_ll_sc_3 {\n    ($name:ident, [$($reg:tt)*], $($op:tt)*) => {\n        #[inline]\n        unsafe fn $name(dst: *mut u128, val: u128, order: Ordering) -> u128 {\n            debug_assert!(dst.addr() % 16 == 0);\n            debug_assert_pwr8!();\n            let val = U128 { whole: val };\n            let (mut prev_hi, mut prev_lo);\n\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                macro_rules! op {\n                    ($acquire:tt, $release:tt) => {\n                        asm!(\n                            start_pwr8!(),\n                            $release,                   // fence\n                            \"2:\", // 'retry:\n                                \"lqarx %r6, 0, {dst}\",  // atomic { RESERVE = (dst, 16); r6:r7 = *dst }\n                                $($op)*\n                                \"stqcx. %r8, 0, {dst}\", // atomic { if RESERVE == (dst, 16) { *dst = r8:r9; cr0.EQ = 1 } else { cr0.EQ = 0 }; RESERVE = None }\n                                \"bne %cr0, 2b\",         // if cr0.EQ == 0 { jump 'retry }\n                            $acquire,                   // fence\n                            end_pwr8!(),\n                            dst = in(reg_nonzero) ptr_reg!(dst),\n                            val_hi = in(reg) val.pair.hi,\n                            val_lo = in(reg) val.pair.lo,\n                            $($reg)*\n                            // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                            // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater.\n                            out(\"r6\") prev_hi,\n                            out(\"r7\") prev_lo,\n                            out(\"r8\") _, // new (hi)\n                            out(\"r9\") _, // new (lo)\n                            out(\"cr0\") _,\n                            options(nostack, preserves_flags),\n                        )\n                    };\n                }\n                atomic_rmw!(op, order);\n                U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole\n            }\n        }\n    };\n}\n/// Atomic RMW by LL/SC loop (2 arguments)\n/// `unsafe fn(dst: *mut u128, order: Ordering) -> u128;`\n///\n/// $op can use the following registers:\n/// - r6/r7 pair: previous value loaded by ll (read-only for `$op`)\n/// - r8/r9 pair: new value that will be stored by sc\nmacro_rules! atomic_rmw_ll_sc_2 {\n    ($name:ident, [$($reg:tt)*], $($op:tt)*) => {\n        #[inline]\n        unsafe fn $name(dst: *mut u128, order: Ordering) -> u128 {\n            debug_assert!(dst.addr() % 16 == 0);\n            debug_assert_pwr8!();\n            let (mut prev_hi, mut prev_lo);\n\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                macro_rules! op {\n                    ($acquire:tt, $release:tt) => {\n                        asm!(\n                            start_pwr8!(),\n                            $release,                   // fence\n                            \"2:\", // 'retry:\n                                \"lqarx %r6, 0, {dst}\",  // atomic { RESERVE = (dst, 16); r6:r7 = *dst }\n                                $($op)*\n                                \"stqcx. %r8, 0, {dst}\", // atomic { if RESERVE == (dst, 16) { *dst = r8:r9; cr0.EQ = 1 } else { cr0.EQ = 0 }; RESERVE = None }\n                                \"bne %cr0, 2b\",         // if cr0.EQ == 0 { jump 'retry }\n                            $acquire,                   // fence\n                            end_pwr8!(),\n                            dst = in(reg_nonzero) ptr_reg!(dst),\n                            $($reg)*\n                            // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                            // We cannot use r1 (sp) and r2 (system reserved), so start with r4 or grater.\n                            out(\"r6\") prev_hi,\n                            out(\"r7\") prev_lo,\n                            out(\"r8\") _, // new (hi)\n                            out(\"r9\") _, // new (lo)\n                            out(\"cr0\") _,\n                            options(nostack, preserves_flags),\n                        )\n                    };\n                }\n                atomic_rmw!(op, order);\n                U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole\n            }\n        }\n    };\n}\n\natomic_rmw_ll_sc_3! {\n    atomic_add_pwr8, [out(\"xer\") _,],\n    \"addc %r9, {val_lo}, %r7\", // r9 = val_lo + r7; xer.CA = carry\n    \"adde %r8, {val_hi}, %r6\", // r8 = val_hi + r6 + xer.CA\n}\natomic_rmw_ll_sc_3! {\n    atomic_sub_pwr8, [out(\"xer\") _,],\n    \"subc %r9, %r7, {val_lo}\",  // r9 = val_lo - r7; xer.CA = borrow\n    \"subfe %r8, {val_hi}, %r6\", // r8 = val_hi - r6 - xer.CA\n}\natomic_rmw_ll_sc_3! {\n    atomic_and_pwr8, [],\n    \"and %r9, {val_lo}, %r7\", // r9 = val_lo & r7\n    \"and %r8, {val_hi}, %r6\", // r8 = val_hi & r6\n}\natomic_rmw_ll_sc_3! {\n    atomic_nand_pwr8, [],\n    \"nand %r9, {val_lo}, %r7\", // r9 = !(val_lo & r7)\n    \"nand %r8, {val_hi}, %r6\", // r8 = !(val_hi & r6)\n}\natomic_rmw_ll_sc_3! {\n    atomic_or_pwr8, [],\n    \"or %r9, {val_lo}, %r7\", // r9 = val_lo | r7\n    \"or %r8, {val_hi}, %r6\", // r8 = val_hi | r6\n}\natomic_rmw_ll_sc_3! {\n    atomic_xor_pwr8, [],\n    \"xor %r9, {val_lo}, %r7\", // r9 = val_lo ^ r7\n    \"xor %r8, {val_hi}, %r6\", // r8 = val_hi ^ r6\n}\natomic_rmw_ll_sc_3! {\n    atomic_max_pwr8, [out(\"cr1\") _,],\n    \"cmpld %r7, {val_lo}\",        // if r7(u) < val_lo(u) { cr0 = { LT: 1, ..0 } } else if r7(u) > val_lo(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } }\n    \"iselgt %r9, %r7, {val_lo}\",  // if cr0.GT == 1 { r9 = r7 } else { r9 = val_lo }\n    \"cmpd %cr1, %r6, {val_hi}\",   // if r6(i) < val_hi(i) { cr1 = { LT: 1, ..0 } } else if r6(i) > val_hi(i) { cr1 = { GT: 1, ..0 } } else { cr1 = { EQ: 1, ..0 } }\n    \"isel %r8, %r7, {val_lo}, 5\", // if cr1.GT == 1 { r8 = r7 } else { r8 = val_lo }\n    \"cmpld %r6, {val_hi}\",        // if r6(u) < val_hi(u) { cr0 = { LT: 1, ..0 } } else if r6(u) > val_hi(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } }\n    \"iseleq %r9, %r9, %r8\",       // if cr0.EQ == 1 { r9 = r9 } else { r9 = r8 }\n    \"isel %r8, %r6, {val_hi}, 5\", // if cr1.GT == 1 { r8 = r6 } else { r8 = val_hi }\n}\natomic_rmw_ll_sc_3! {\n    atomic_umax_pwr8, [],\n    \"cmpld %r7, {val_lo}\",       // if r7(u) < val_lo(u) { cr0 = { LT: 1, ..0 } } else if r7(u) > val_lo(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } }\n    \"iselgt %r9, %r7, {val_lo}\", // if cr0.GT == 1 { r9 = r7 } else { r9 = val_lo }\n    \"cmpld %r6, {val_hi}\",       // if r6(u) < val_hi(u) { cr0 = { LT: 1, ..0 } } else if r6(u) > val_hi(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } }\n    \"iselgt %r8, %r7, {val_lo}\", // if cr0.GT == 1 { r8 = r7 } else { r8 = val_lo }\n    \"iseleq %r9, %r9, %r8\",      // if cr0.EQ == 1 { r9 = r9 } else { r9 = r8 }\n    \"iselgt %r8, %r6, {val_hi}\", // if cr0.GT == 1 { r8 = r6 } else { r8 = val_hi }\n}\natomic_rmw_ll_sc_3! {\n    atomic_min_pwr8, [out(\"cr1\") _,],\n    \"cmpld %r7, {val_lo}\",        // if r7(u) < val_lo(u) { cr0 = { LT: 1, ..0 } } else if r7(u) > val_lo(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } }\n    \"isellt %r9, %r7, {val_lo}\",  // if cr0.LT == 1 { r9 = r7 } else { r9 = val_lo }\n    \"cmpd %cr1, %r6, {val_hi}\",   // if r6(i) < val_hi(i) { cr1 = { LT: 1, ..0 } } else if r6(i) > val_hi(i) { cr1 = { GT: 1, ..0 } } else { cr1 = { EQ: 1, ..0 } }\n    \"isel %r8, %r7, {val_lo}, 4\", // if cr1.LT == 1 { r8 = r7 } else { r8 = val_lo }\n    \"cmpld %r6, {val_hi}\",        // if r6(u) < val_hi(u) { cr0 = { LT: 1, ..0 } } else if r6(u) > val_hi(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } }\n    \"iseleq %r9, %r9, %r8\",       // if cr0.EQ == 1 { r9 = r9 } else { r9 = r8 }\n    \"isel %r8, %r6, {val_hi}, 4\", // if cr1.LT == 1 { r8 = r6 } else { r8 = val_hi }\n}\natomic_rmw_ll_sc_3! {\n    atomic_umin_pwr8, [],\n    \"cmpld %r7, {val_lo}\",       // if r7(u) < val_lo(u) { cr0 = { LT: 1, ..0 } } else if r7(u) > val_lo(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } }\n    \"isellt %r9, %r7, {val_lo}\", // if cr0.LT == 1 { r9 = r7 } else { r9 = val_lo }\n    \"cmpld %r6, {val_hi}\",       // if r6(u) < val_hi(u) { cr0 = { LT: 1, ..0 } } else if r6(u) > val_hi(u) { cr0 = { GT: 1, ..0 } } else { cr0 = { EQ: 1, ..0 } }\n    \"isellt %r8, %r7, {val_lo}\", // if cr0.LT == 1 { r8 = r7 } else { r8 = val_lo }\n    \"iseleq %r9, %r9, %r8\",      // if cr0.EQ == 1 { r9 = r9 } else { r9 = r8 }\n    \"isellt %r8, %r6, {val_hi}\", // if cr0.LT == 1 { r8 = r6 } else { r8 = val_hi }\n}\n\n#[inline]\nunsafe fn atomic_not_pwr8(dst: *mut u128, order: Ordering) -> u128 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe { atomic_xor_pwr8(dst, !0, order) }\n}\n\n#[cfg(not(portable_atomic_pre_llvm_16))]\natomic_rmw_ll_sc_2! {\n    atomic_neg_pwr8, [out(\"xer\") _,],\n    \"subfic %r9, %r7, 0\", // r9 = 0 - r7; xer.CA = borrow\n    \"subfze %r8, %r6\",    // r8 = 0 - r6 - xer.CA\n}\n// LLVM 15 miscompiles subfic.\n#[cfg(portable_atomic_pre_llvm_16)]\natomic_rmw_ll_sc_2! {\n    atomic_neg_pwr8, [zero = in(reg) 0_u64, out(\"xer\") _,],\n    \"subc %r9, {zero}, %r7\", // r9 = 0 - r7; xer.CA = borrow\n    \"subfze %r8, %r6\",       // r8 = 0 - r6 - xer.CA\n}\n\nmacro_rules! select_atomic_rmw {\n    (\n        unsafe fn $name:ident($($arg:tt)*) $(-> $ret_ty:ty)?;\n        pwr8 = $pwr8_fn:ident;\n        non_seqcst_fallback = $non_seqcst_fallback_fn:ident;\n        seqcst_fallback = $seqcst_fallback_fn:ident;\n    ) => {\n        // If quadword-atomics is available at compile-time, we can always use pwr8_fn.\n        #[cfg(any(\n            target_feature = \"quadword-atomics\",\n            portable_atomic_target_feature = \"quadword-atomics\",\n        ))]\n        use self::$pwr8_fn as $name;\n        // Otherwise, we need to do run-time detection and can use pwr8_fn only if quadword-atomics is available.\n        #[cfg(not(any(\n            target_feature = \"quadword-atomics\",\n            portable_atomic_target_feature = \"quadword-atomics\",\n        )))]\n        #[inline]\n        unsafe fn $name($($arg)*, order: Ordering) $(-> $ret_ty)? {\n            fn_alias! {\n                // inline(never) is just a hint and also not strictly necessary\n                // because we use ifunc helper macro, but used for clarity.\n                #[inline(never)]\n                unsafe fn($($arg)*) $(-> $ret_ty)?;\n                pwr8_relaxed_fn = $pwr8_fn(Ordering::Relaxed);\n                pwr8_acquire_fn = $pwr8_fn(Ordering::Acquire);\n                pwr8_release_fn = $pwr8_fn(Ordering::Release);\n                pwr8_acqrel_fn = $pwr8_fn(Ordering::AcqRel);\n                pwr8_seqcst_fn = $pwr8_fn(Ordering::SeqCst);\n            }\n            // SAFETY: the caller must uphold the safety contract.\n            // we only calls pwr8_fn if quadword-atomics is available.\n            unsafe {\n                match order {\n                    Ordering::Relaxed => {\n                        ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? {\n                            if detect::detect().quadword_atomics() {\n                                pwr8_relaxed_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::Acquire => {\n                        ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? {\n                            if detect::detect().quadword_atomics() {\n                                pwr8_acquire_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::Release => {\n                        ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? {\n                            if detect::detect().quadword_atomics() {\n                                pwr8_release_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::AcqRel => {\n                        ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? {\n                            if detect::detect().quadword_atomics() {\n                                pwr8_acqrel_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::SeqCst => {\n                        ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? {\n                            if detect::detect().quadword_atomics() {\n                                pwr8_seqcst_fn\n                            } else {\n                                fallback::$seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\nselect_atomic_rmw! {\n    unsafe fn atomic_swap(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_swap_pwr8;\n    non_seqcst_fallback = atomic_swap_non_seqcst;\n    seqcst_fallback = atomic_swap_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_add(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_add_pwr8;\n    non_seqcst_fallback = atomic_add_non_seqcst;\n    seqcst_fallback = atomic_add_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_sub(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_sub_pwr8;\n    non_seqcst_fallback = atomic_sub_non_seqcst;\n    seqcst_fallback = atomic_sub_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_and(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_and_pwr8;\n    non_seqcst_fallback = atomic_and_non_seqcst;\n    seqcst_fallback = atomic_and_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_nand(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_nand_pwr8;\n    non_seqcst_fallback = atomic_nand_non_seqcst;\n    seqcst_fallback = atomic_nand_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_or(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_or_pwr8;\n    non_seqcst_fallback = atomic_or_non_seqcst;\n    seqcst_fallback = atomic_or_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_xor(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_xor_pwr8;\n    non_seqcst_fallback = atomic_xor_non_seqcst;\n    seqcst_fallback = atomic_xor_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_max(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_max_pwr8;\n    non_seqcst_fallback = atomic_max_non_seqcst;\n    seqcst_fallback = atomic_max_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_umax(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_umax_pwr8;\n    non_seqcst_fallback = atomic_umax_non_seqcst;\n    seqcst_fallback = atomic_umax_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_min(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_min_pwr8;\n    non_seqcst_fallback = atomic_min_non_seqcst;\n    seqcst_fallback = atomic_min_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_umin(dst: *mut u128, val: u128) -> u128;\n    pwr8 = atomic_umin_pwr8;\n    non_seqcst_fallback = atomic_umin_non_seqcst;\n    seqcst_fallback = atomic_umin_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_not(dst: *mut u128) -> u128;\n    pwr8 = atomic_not_pwr8;\n    non_seqcst_fallback = atomic_not_non_seqcst;\n    seqcst_fallback = atomic_not_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_neg(dst: *mut u128) -> u128;\n    pwr8 = atomic_neg_pwr8;\n    non_seqcst_fallback = atomic_neg_non_seqcst;\n    seqcst_fallback = atomic_neg_seqcst;\n}\n\n#[inline]\nfn is_lock_free() -> bool {\n    #[cfg(any(\n        target_feature = \"quadword-atomics\",\n        portable_atomic_target_feature = \"quadword-atomics\",\n    ))]\n    {\n        // lqarx and stqcx. instructions are statically available.\n        true\n    }\n    #[cfg(not(any(\n        target_feature = \"quadword-atomics\",\n        portable_atomic_target_feature = \"quadword-atomics\",\n    )))]\n    {\n        detect::detect().quadword_atomics()\n    }\n}\nconst IS_ALWAYS_LOCK_FREE: bool = cfg!(any(\n    target_feature = \"quadword-atomics\",\n    portable_atomic_target_feature = \"quadword-atomics\",\n));\n\natomic128!(AtomicI128, i128, atomic_max, atomic_min);\natomic128!(AtomicU128, u128, atomic_umax, atomic_umin);\n\n#[cfg(not(valgrind))] // TODO(powerpc64): Hang (as of Valgrind 3.26)\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    test_atomic_int!(i128);\n    test_atomic_int!(u128);\n\n    // load/store/swap implementation is not affected by signedness, so it is\n    // enough to test only unsigned types.\n    stress_test!(u128);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic128/riscv64.rs",
      "sha256": "115c4d8bc0fed79973bc12462f506121c7e612f3cf14cc627a0d024c3a131387",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\n128-bit atomic implementation on riscv64.\n\nThis architecture provides the following 128-bit atomic instructions:\n\n- amocas.q: CAS (Zacas extension)\n\nSee \"Atomic operation overview by architecture\" in atomic-maybe-uninit for a more comprehensive and\ndetailed description of the atomic and synchronize instructions in this architecture:\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#risc-v\n\nNote: On Miri and ThreadSanitizer which do not support inline assembly, we don't use\nthis module and use fallback implementation instead.\n\nRefs:\n- RISC-V Instruction Set Manual\n  \"Zacas\" Extension for Atomic Compare-and-Swap (CAS) Instructions\n  https://docs.riscv.org/reference/isa/v20260120/unpriv/zacas.html\n- RISC-V Atomics ABI Specification\n  https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20250812-301374e92976e298e676e7129a6212926b2299ce/riscv-atomic.adoc\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\ninclude!(\"macros.rs\");\n\n#[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n#[path = \"../fallback/outline_atomics.rs\"]\nmod fallback;\n\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(test, not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"))))]\n#[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n#[path = \"../detect/riscv_linux.rs\"]\nmod detect;\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\nuse core::sync::atomic::Ordering;\n\n#[cfg(portable_atomic_no_strict_provenance)]\nuse crate::utils::ptr::PtrExt as _;\nuse crate::utils::{Pair, U128};\n\nmacro_rules! debug_assert_zacas {\n    () => {\n        #[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n        {\n            debug_assert!(detect::detect().zacas());\n        }\n    };\n}\n\n// `.option arch, +zacas` directive requires LLVM 20, so we use .4byte directive for old LLVM.\n// Note that `.insn <value>` directive requires LLVM 19.\n// https://github.com/llvm/llvm-project/commit/2a086dce691e3cc34a2fc27f4fb255bb2cbbfac9\n// https://github.com/riscv-non-isa/riscv-asm-manual/blob/v0.0.1/src/asm-manual.adoc#arch\n#[cfg(not(portable_atomic_pre_llvm_20))]\nmacro_rules! start_zacas {\n    () => {\n        \".option push\\n.option arch, +zacas\"\n    };\n}\n#[cfg(not(portable_atomic_pre_llvm_20))]\nmacro_rules! end_zacas {\n    () => {\n        \".option pop\"\n    };\n}\n\n#[cfg(not(portable_atomic_pre_llvm_20))]\nmacro_rules! atomic_rmw_amocas_order {\n    ($op:ident, $order:ident) => {\n        atomic_rmw_amocas_order!($op, $order, failure = $order)\n    };\n    ($op:ident, $order:ident, failure = $failure:ident) => {\n        match $order {\n            Ordering::Relaxed => $op!(\"\", \"\"),\n            Ordering::Acquire => $op!(\"\", \".aq\"),\n            Ordering::Release => $op!(\"\", \".rl\"),\n            Ordering::AcqRel => $op!(\"\", \".aqrl\"),\n            Ordering::SeqCst if $failure == Ordering::SeqCst => $op!(\"fence rw,rw\", \".aqrl\"),\n            Ordering::SeqCst => $op!(\"\", \".aqrl\"),\n            _ => unreachable!(),\n        }\n    };\n}\n#[cfg(portable_atomic_pre_llvm_20)]\nmacro_rules! atomic_rmw_amocas_order_insn {\n    ($op:ident, $order:ident) => {\n        atomic_rmw_amocas_order_insn!($op, $order, failure = $order)\n    };\n    ($op:ident, $order:ident, failure = $failure:ident) => {\n        match $order {\n            Ordering::Relaxed => $op!(\"\", \"8\"),\n            Ordering::Acquire => $op!(\"\", \"c\"),\n            Ordering::Release => $op!(\"\", \"a\"),\n            Ordering::AcqRel => $op!(\"\", \"e\"),\n            Ordering::SeqCst if $failure == Ordering::SeqCst => $op!(\"fence rw,rw\", \"e\"),\n            Ordering::SeqCst => $op!(\"\", \"e\"),\n            _ => unreachable!(),\n        }\n    };\n}\n\n// If zacas is available at compile-time, we can always use zacas_fn.\n#[cfg(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"))]\nuse self::atomic_load_zacas as atomic_load;\n// Otherwise, we need to do run-time detection and can use zacas_fn only if zacas is available.\n#[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n#[inline]\nunsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {\n    fn_alias! {\n        // inline(never) is just a hint and also not strictly necessary\n        // because we use ifunc helper macro, but used for clarity.\n        #[inline(never)]\n        unsafe fn(src: *mut u128) -> u128;\n        atomic_load_zacas_relaxed = atomic_load_zacas(Ordering::Relaxed);\n        atomic_load_zacas_acquire = atomic_load_zacas(Ordering::Acquire);\n        atomic_load_zacas_seqcst = atomic_load_zacas(Ordering::SeqCst);\n    }\n    // SAFETY: the caller must uphold the safety contract.\n    // we only calls atomic_load_zacas if zacas is available.\n    unsafe {\n        match order {\n            Ordering::Relaxed => {\n                ifunc!(unsafe fn(src: *mut u128) -> u128 {\n                    if detect::detect().zacas() {\n                        atomic_load_zacas_relaxed\n                    } else {\n                        fallback::atomic_load_non_seqcst\n                    }\n                })\n            }\n            Ordering::Acquire => {\n                ifunc!(unsafe fn(src: *mut u128) -> u128 {\n                    if detect::detect().zacas() {\n                        atomic_load_zacas_acquire\n                    } else {\n                        fallback::atomic_load_non_seqcst\n                    }\n                })\n            }\n            Ordering::SeqCst => {\n                ifunc!(unsafe fn(src: *mut u128) -> u128 {\n                    if detect::detect().zacas() {\n                        atomic_load_zacas_seqcst\n                    } else {\n                        fallback::atomic_load_seqcst\n                    }\n                })\n            }\n            _ => unreachable!(),\n        }\n    }\n}\n#[inline]\nunsafe fn atomic_load_zacas(src: *mut u128, order: Ordering) -> u128 {\n    debug_assert!(src.addr() % 16 == 0);\n    debug_assert_zacas!();\n    let (out_lo, out_hi);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        #[cfg(not(portable_atomic_pre_llvm_20))]\n        macro_rules! load {\n            ($fence:tt, $asm_order:tt) => {\n                asm!(\n                    start_zacas!(),\n                    $fence,                                               // fence\n                    concat!(\"amocas.q\", $asm_order, \" a2, a2, 0({src})\"), // atomic { if *dst == a2:a3 { *dst = a2:a3 } else { a2:a3 = *dst } }\n                    end_zacas!(),\n                    src = in(reg) ptr_reg!(src),\n                    inout(\"a2\") 0_u64 => out_lo,\n                    inout(\"a3\") 0_u64 => out_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(not(portable_atomic_pre_llvm_20))]\n        atomic_rmw_amocas_order!(load, order);\n        #[cfg(portable_atomic_pre_llvm_20)]\n        macro_rules! load {\n            ($fence:tt, $insn_order:tt) => {\n                asm!(\n                    $fence,                                  // fence\n                    // amocas.q{,.aq,.rl,.aqrl} a2, a2, (a0) // atomic { if *a0 == a2:a3 { *a0 = a2:a3 } else { a2:a3 = *a0 } }\n                    concat!(\".4byte 0x2\", $insn_order, \"c5462f\"),\n                    in(\"a0\") ptr_reg!(src),\n                    inout(\"a2\") 0_u64 => out_lo,\n                    inout(\"a3\") 0_u64 => out_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(portable_atomic_pre_llvm_20)]\n        atomic_rmw_amocas_order_insn!(load, order);\n        U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n    }\n}\n\n#[inline]\nunsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        atomic_swap(dst, val, order);\n    }\n}\n\n#[inline]\nunsafe fn atomic_compare_exchange(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> Result<u128, u128> {\n    #[cfg(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"))]\n    // SAFETY: the caller must uphold the safety contract.\n    // cfg guarantees that zacas instructions are available at compile-time.\n    let (prev, ok) = unsafe { atomic_compare_exchange_zacas(dst, old, new, success, failure) };\n    #[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n    let (prev, ok) = {\n        fn_alias! {\n            // inline(never) is just a hint and also not strictly necessary\n            // because we use ifunc helper macro, but used for clarity.\n            #[inline(never)]\n            unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool);\n            zacas_relaxed_fn = atomic_compare_exchange_zacas(Ordering::Relaxed, Ordering::Relaxed);\n            zacas_acquire_fn = atomic_compare_exchange_zacas(Ordering::Acquire, Ordering::Acquire);\n            zacas_release_fn = atomic_compare_exchange_zacas(Ordering::Release, Ordering::Relaxed);\n            zacas_acqrel_fn = atomic_compare_exchange_zacas(Ordering::AcqRel, Ordering::Acquire);\n            zacas_seqcst_fn = atomic_compare_exchange_zacas(Ordering::SeqCst, Ordering::SeqCst);\n        }\n        let order = crate::utils::upgrade_success_ordering(success, failure);\n        // SAFETY: the caller must uphold the safety contract.\n        // we only calls atomic_compare_exchange_zacas if zacas is available.\n        unsafe {\n            match order {\n                Ordering::Relaxed => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n                        if detect::detect().zacas() {\n                            zacas_relaxed_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::Acquire => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n                        if detect::detect().zacas() {\n                            zacas_acquire_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::Release => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n                        if detect::detect().zacas() {\n                            zacas_release_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::AcqRel => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n                        if detect::detect().zacas() {\n                            zacas_acqrel_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::SeqCst => {\n                    ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n                        if detect::detect().zacas() {\n                            zacas_seqcst_fn\n                        } else {\n                            fallback::atomic_compare_exchange_seqcst\n                        }\n                    })\n                }\n                _ => unreachable!(),\n            }\n        }\n    };\n    if ok { Ok(prev) } else { Err(prev) }\n}\n#[inline]\nunsafe fn atomic_compare_exchange_zacas(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    success: Ordering,\n    failure: Ordering,\n) -> (u128, bool) {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_zacas!();\n    let order = crate::utils::upgrade_success_ordering(success, failure);\n    let old = U128 { whole: old };\n    let new = U128 { whole: new };\n    let (prev_lo, prev_hi);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        #[cfg(not(portable_atomic_pre_llvm_20))]\n        macro_rules! cmpxchg {\n            ($fence:tt, $asm_order:tt) => {\n                asm!(\n                    start_zacas!(),\n                    $fence,                                               // fence\n                    concat!(\"amocas.q\", $asm_order, \" a4, a2, 0({dst})\"), // atomic { if *dst == a4:a5 { *dst = a2:a3 } else { a4:a5 = *dst } }\n                    end_zacas!(),\n                    dst = in(reg) ptr_reg!(dst),\n                    // must be allocated to even/odd register pair\n                    inout(\"a4\") old.pair.lo => prev_lo,\n                    inout(\"a5\") old.pair.hi => prev_hi,\n                    // must be allocated to even/odd register pair\n                    in(\"a2\") new.pair.lo,\n                    in(\"a3\") new.pair.hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(not(portable_atomic_pre_llvm_20))]\n        atomic_rmw_amocas_order!(cmpxchg, order, failure = failure);\n        #[cfg(portable_atomic_pre_llvm_20)]\n        macro_rules! cmpxchg {\n            ($fence:tt, $insn_order:tt) => {\n                asm!(\n                    $fence,                                  // fence\n                    // amocas.q{,.aq,.rl,.aqrl} a4, a2, (a0) // atomic { if *a0 == a4:a5 { *a0 = a2:a3 } else { a4:a5 = *a0 } }\n                    concat!(\".4byte 0x2\", $insn_order, \"c5472f\"),\n                    in(\"a0\") ptr_reg!(dst),\n                    // must be allocated to even/odd register pair\n                    inout(\"a4\") old.pair.lo => prev_lo,\n                    inout(\"a5\") old.pair.hi => prev_hi,\n                    // must be allocated to even/odd register pair\n                    in(\"a2\") new.pair.lo,\n                    in(\"a3\") new.pair.hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(portable_atomic_pre_llvm_20)]\n        atomic_rmw_amocas_order_insn!(cmpxchg, order, failure = failure);\n        let prev = U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole;\n        (prev, prev == old.whole)\n    }\n}\n\n// amocas is always strong.\nuse self::atomic_compare_exchange as atomic_compare_exchange_weak;\n\n// 128-bit atomic load by two 64-bit atomic loads.\n#[inline]\nunsafe fn byte_wise_atomic_load(src: *const u128) -> u128 {\n    let (out_lo, out_hi);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        asm!(\n            \"ld {out_lo}, ({src})\",  // atomic { out_lo = *src }\n            \"ld {out_hi}, 8({src})\", // atomic { out_hi = *src.byte_add(8) }\n            src = in(reg) ptr_reg!(src),\n            out_lo = out(reg) out_lo,\n            out_hi = out(reg) out_hi,\n            options(pure, nostack, preserves_flags, readonly),\n        );\n        U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n    }\n}\n\nmacro_rules! select_atomic_rmw {\n    (\n        unsafe fn $name:ident(dst: *mut u128 $(, $($arg:tt)*)?) $(-> $ret_ty:ty)? {\n            |$zacas_fn_binding:ident| $($zacas_fn_body:tt)*\n        }\n        zacas = $zacas_fn:ident;\n        non_seqcst_fallback = $non_seqcst_fallback_fn:ident;\n        seqcst_fallback = $seqcst_fallback_fn:ident;\n    ) => {\n        #[inline]\n        unsafe fn $zacas_fn(dst: *mut u128 $(, $($arg)*)?, order: Ordering) $(-> $ret_ty)? {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                // This is not single-copy atomic reads, but this is ok because subsequent\n                // CAS will check for consistency.\n                //\n                // Note that the C++20 memory model does not allow mixed-sized atomic access,\n                // so we must use inline assembly to implement byte_wise_atomic_load.\n                // (i.e., byte-wise atomic based on the standard library's atomic types\n                // cannot be used here).\n                let mut prev = byte_wise_atomic_load(dst);\n                loop {\n                    let next = {\n                        let $zacas_fn_binding = prev;\n                        $($zacas_fn_body)*\n                    };\n                    match atomic_compare_exchange_weak(dst, prev, next, order, Ordering::Relaxed) {\n                        Ok(x) => return x,\n                        Err(x) => prev = x,\n                    }\n                }\n            }\n        }\n        // If zacas is available at compile-time, we can always use zacas_fn.\n        #[cfg(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"))]\n        use self::$zacas_fn as $name;\n        // Otherwise, we need to do run-time detection and can use zacas_fn only if zacas is available.\n        #[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n        #[inline]\n        unsafe fn $name(dst: *mut u128 $(, $($arg)*)?, order: Ordering) $(-> $ret_ty)? {\n            fn_alias! {\n                // inline(never) is just a hint and also not strictly necessary\n                // because we use ifunc helper macro, but used for clarity.\n                #[inline(never)]\n                unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)?;\n                zacas_relaxed_fn = $zacas_fn(Ordering::Relaxed);\n                zacas_acquire_fn = $zacas_fn(Ordering::Acquire);\n                zacas_release_fn = $zacas_fn(Ordering::Release);\n                zacas_acqrel_fn = $zacas_fn(Ordering::AcqRel);\n                zacas_seqcst_fn = $zacas_fn(Ordering::SeqCst);\n            }\n            // SAFETY: the caller must uphold the safety contract.\n            // we only calls zacas_fn if zacas is available.\n            unsafe {\n                match order {\n                    Ordering::Relaxed => {\n                        ifunc!(unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)? {\n                            if detect::detect().zacas() {\n                                zacas_relaxed_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::Acquire => {\n                        ifunc!(unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)? {\n                            if detect::detect().zacas() {\n                                zacas_acquire_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::Release => {\n                        ifunc!(unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)? {\n                            if detect::detect().zacas() {\n                                zacas_release_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::AcqRel => {\n                        ifunc!(unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)? {\n                            if detect::detect().zacas() {\n                                zacas_acqrel_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::SeqCst => {\n                        ifunc!(unsafe fn(dst: *mut u128 $(, $($arg)*)?) $(-> $ret_ty)? {\n                            if detect::detect().zacas() {\n                                zacas_seqcst_fn\n                            } else {\n                                fallback::$seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\nselect_atomic_rmw! {\n    unsafe fn atomic_swap(dst: *mut u128, val: u128) -> u128 {\n        |_x| val\n    }\n    zacas = atomic_swap_zacas;\n    non_seqcst_fallback = atomic_swap_non_seqcst;\n    seqcst_fallback = atomic_swap_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_add(dst: *mut u128, val: u128) -> u128 {\n        |x| x.wrapping_add(val)\n    }\n    zacas = atomic_add_zacas;\n    non_seqcst_fallback = atomic_add_non_seqcst;\n    seqcst_fallback = atomic_add_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_sub(dst: *mut u128, val: u128) -> u128 {\n        |x| x.wrapping_sub(val)\n    }\n    zacas = atomic_sub_zacas;\n    non_seqcst_fallback = atomic_sub_non_seqcst;\n    seqcst_fallback = atomic_sub_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_and(dst: *mut u128, val: u128) -> u128 {\n        |x| x & val\n    }\n    zacas = atomic_and_zacas;\n    non_seqcst_fallback = atomic_and_non_seqcst;\n    seqcst_fallback = atomic_and_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_nand(dst: *mut u128, val: u128) -> u128 {\n        |x| !(x & val)\n    }\n    zacas = atomic_nand_zacas;\n    non_seqcst_fallback = atomic_nand_non_seqcst;\n    seqcst_fallback = atomic_nand_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_or(dst: *mut u128, val: u128) -> u128 {\n        |x| x | val\n    }\n    zacas = atomic_or_zacas;\n    non_seqcst_fallback = atomic_or_non_seqcst;\n    seqcst_fallback = atomic_or_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_xor(dst: *mut u128, val: u128) -> u128 {\n        |x| x ^ val\n    }\n    zacas = atomic_xor_zacas;\n    non_seqcst_fallback = atomic_xor_non_seqcst;\n    seqcst_fallback = atomic_xor_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_max(dst: *mut u128, val: u128) -> u128 {\n        |x| {\n            #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n            { core::cmp::max(x as i128, val as i128) as u128 }\n        }\n    }\n    zacas = atomic_max_zacas;\n    non_seqcst_fallback = atomic_max_non_seqcst;\n    seqcst_fallback = atomic_max_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_umax(dst: *mut u128, val: u128) -> u128 {\n        |x| core::cmp::max(x, val)\n    }\n    zacas = atomic_umax_zacas;\n    non_seqcst_fallback = atomic_umax_non_seqcst;\n    seqcst_fallback = atomic_umax_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_min(dst: *mut u128, val: u128) -> u128 {\n        |x| {\n            #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n            { core::cmp::min(x as i128, val as i128) as u128 }\n        }\n    }\n    zacas = atomic_min_zacas;\n    non_seqcst_fallback = atomic_min_non_seqcst;\n    seqcst_fallback = atomic_min_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_umin(dst: *mut u128, val: u128) -> u128 {\n        |x| core::cmp::min(x, val)\n    }\n    zacas = atomic_umin_zacas;\n    non_seqcst_fallback = atomic_umin_non_seqcst;\n    seqcst_fallback = atomic_umin_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_not(dst: *mut u128) -> u128 {\n        |x| !x\n    }\n    zacas = atomic_not_zacas;\n    non_seqcst_fallback = atomic_not_non_seqcst;\n    seqcst_fallback = atomic_not_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_neg(dst: *mut u128) -> u128 {\n        |x| x.wrapping_neg()\n    }\n    zacas = atomic_neg_zacas;\n    non_seqcst_fallback = atomic_neg_non_seqcst;\n    seqcst_fallback = atomic_neg_seqcst;\n}\n\n#[inline]\nfn is_lock_free() -> bool {\n    #[cfg(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"))]\n    {\n        // zacas is available at compile-time.\n        true\n    }\n    #[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n    {\n        detect::detect().zacas()\n    }\n}\nconst IS_ALWAYS_LOCK_FREE: bool =\n    cfg!(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"));\n\natomic128!(AtomicI128, i128, atomic_max, atomic_min);\natomic128!(AtomicU128, u128, atomic_umax, atomic_umin);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    test_atomic_int!(i128);\n    test_atomic_int!(u128);\n\n    // load/store/swap implementation is not affected by signedness, so it is\n    // enough to test only unsigned types.\n    stress_test!(u128);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic128/s390x.rs",
      "sha256": "b657e6f3e48d12b79dfaf7dec5268d2558967c14288e097bb37e40d49b9b6eba",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\n128-bit atomic implementation on s390x.\n\nThis architecture provides the following 128-bit atomic instructions:\n\n- LPQ/STPQ: load/store (arch1 or later, i.e., baseline)\n- CDSG: CAS (arch1 or later, i.e., baseline)\n\nSee \"Atomic operation overview by architecture\" in atomic-maybe-uninit for a more comprehensive and\ndetailed description of the atomic and synchronize instructions in this architecture:\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#s390x\n\nLLVM's minimal supported architecture level is arch8 (z10):\nhttps://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/SystemZ/SystemZProcessors.td#L16-L17\nThis does not appear to have changed since the current s390x backend was added in LLVM 3.3:\nhttps://github.com/llvm/llvm-project/commit/5f613dfd1f7edb0ae95d521b7107b582d9df5103#diff-cbaef692b3958312e80fd5507a7e2aff071f1acb086f10e8a96bc06a7bb289db\n\nWe could use asm byte_wise_atomic_load + asm atomic_compare_exchange pattern for RMW here, but using an\ninline assembly allows omitting the comparison of results and the storing/comparing of condition flags.\n\nNote: On Miri and ThreadSanitizer which do not support inline assembly, we don't use\nthis module and use intrinsics.rs instead.\n\nRefs:\n- z/Architecture Principles of Operation, Fifteenth Edition (SA22-7832-14)\n  https://www.ibm.com/docs/en/module_1678991624569/pdf/SA22-7832-14.pdf\n- atomic-maybe-uninit\n  https://github.com/taiki-e/atomic-maybe-uninit\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\ninclude!(\"macros.rs\");\n\nuse core::{arch::asm, sync::atomic::Ordering};\n\n#[cfg(portable_atomic_no_strict_provenance)]\nuse crate::utils::ptr::PtrExt as _;\nuse crate::utils::{Pair, U128};\n\n// bcr 14,0 requires fast-BCR-serialization facility added in arch9 (z196).\n#[cfg(any(\n    target_feature = \"fast-serialization\",\n    portable_atomic_target_feature = \"fast-serialization\",\n))]\nmacro_rules! serialization {\n    () => {\n        \"bcr 14, 0\"\n    };\n}\n#[cfg(not(any(\n    target_feature = \"fast-serialization\",\n    portable_atomic_target_feature = \"fast-serialization\",\n)))]\nmacro_rules! serialization {\n    () => {\n        \"bcr 15, 0\"\n    };\n}\n\n// Use distinct operands on z196 or later, otherwise split to lgr and $op.\n#[cfg(any(target_feature = \"distinct-ops\", portable_atomic_target_feature = \"distinct-ops\"))]\nmacro_rules! distinct_op {\n    ($op:tt, $a0:tt, $a1:tt, $a2:tt) => {\n        concat!($op, \"k \", $a0, \", \", $a1, \", \", $a2)\n    };\n}\n#[cfg(not(any(target_feature = \"distinct-ops\", portable_atomic_target_feature = \"distinct-ops\")))]\nmacro_rules! distinct_op {\n    ($op:tt, $a0:tt, $a1:tt, $a2:tt) => {\n        concat!(\"lgr \", $a0, \", \", $a1, \"\\n\", $op, \" \", $a0, \", \", $a2)\n    };\n}\n\n// Use selgr$cond on z15 or later, otherwise split to locgr$cond and $op.\n#[cfg(any(\n    target_feature = \"miscellaneous-extensions-3\",\n    portable_atomic_target_feature = \"miscellaneous-extensions-3\",\n))]\n#[cfg(any(\n    target_feature = \"load-store-on-cond\",\n    portable_atomic_target_feature = \"load-store-on-cond\",\n))]\nmacro_rules! select_op {\n    ($cond:tt, $a0:tt, $a1:tt, $a2:tt) => {\n        concat!(\"selgr\", $cond, \" \", $a0, \", \", $a1, \", \", $a2)\n    };\n}\n#[cfg(not(any(\n    target_feature = \"miscellaneous-extensions-3\",\n    portable_atomic_target_feature = \"miscellaneous-extensions-3\",\n)))]\n#[cfg(any(\n    target_feature = \"load-store-on-cond\",\n    portable_atomic_target_feature = \"load-store-on-cond\",\n))]\nmacro_rules! select_op {\n    ($cond:tt, $a0:tt, $a1:tt, $a2:tt) => {\n        concat!(\"lgr \", $a0, \", \", $a2, \"\\n\", \"locgr\", $cond, \" \", $a0, \", \", $a1)\n    };\n}\n\n// Extracts and checks condition code.\n#[inline]\nfn extract_cc(r: i64) -> bool {\n    r.wrapping_add(-268435456) & (1 << 31) != 0\n}\n\n#[inline]\nunsafe fn atomic_load(src: *mut u128, _order: Ordering) -> u128 {\n    debug_assert!(src.addr() % 16 == 0);\n    let (out_hi, out_lo);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        // atomic load is always SeqCst.\n        asm!(\n            \"lpq %r0, 0({src})\", // atomic { r0:r1 = *src }\n            src = in(reg) ptr_reg!(src),\n            // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n            out(\"r0\") out_hi,\n            out(\"r1\") out_lo,\n            options(nostack, preserves_flags),\n        );\n        U128 { pair: Pair { hi: out_hi, lo: out_lo } }.whole\n    }\n}\n\n#[inline]\nunsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {\n    debug_assert!(dst.addr() % 16 == 0);\n    let val = U128 { whole: val };\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        macro_rules! atomic_store {\n            ($acquire:expr) => {\n                asm!(\n                    \"stpq %r0, 0({dst})\", // atomic { *dst = r0:r1 }\n                    $acquire,             // fence\n                    dst = in(reg) ptr_reg!(dst),\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    in(\"r0\") val.pair.hi,\n                    in(\"r1\") val.pair.lo,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        match order {\n            // Relaxed and Release stores are equivalent.\n            Ordering::Relaxed | Ordering::Release => atomic_store!(\"\"),\n            Ordering::SeqCst => atomic_store!(serialization!()),\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[inline]\nunsafe fn atomic_compare_exchange(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    _success: Ordering,\n    _failure: Ordering,\n) -> Result<u128, u128> {\n    debug_assert!(dst.addr() % 16 == 0);\n    let old = U128 { whole: old };\n    let new = U128 { whole: new };\n    let (prev_hi, prev_lo);\n    let r;\n\n    // SAFETY: the caller must uphold the safety contract.\n    // CDSG has SeqCst semantics.\n    let prev = unsafe {\n        macro_rules! cmpxchg {\n            ($new_hi:tt, $new_lo:tt) => {\n                asm!(\n                    concat!(\"cdsg %r0, %\", $new_hi, \", 0({dst})\"), // atomic { if *dst == r0:r1 { cc = 0; *dst = new_hi:new_lo } else { cc = 1; r0:r1 = *dst } }\n                    \"ipm {r}\",                                     // r[:] = cc\n                    dst = in(reg) ptr_reg!(dst),\n                    r = lateout(reg) r,\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    inout(\"r0\") old.pair.hi => prev_hi,\n                    inout(\"r1\") old.pair.lo => prev_lo,\n                    in($new_hi) new.pair.hi,\n                    in($new_lo) new.pair.lo,\n                    // Do not use `preserves_flags` because CDSG modifies the condition code.\n                    options(nostack),\n                )\n            };\n        }\n        // r4 is stack pointer on z/OS.\n        #[cfg(not(target_os = \"zos\"))]\n        cmpxchg!(\"r4\", \"r5\");\n        #[cfg(target_os = \"zos\")]\n        cmpxchg!(\"r12\", \"r13\");\n        U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole\n    };\n    if extract_cc(r) { Ok(prev) } else { Err(prev) }\n}\n\n// cdsg is always strong.\nuse self::atomic_compare_exchange as atomic_compare_exchange_weak;\n\n#[inline]\nunsafe fn atomic_swap(dst: *mut u128, val: u128, _order: Ordering) -> u128 {\n    debug_assert!(dst.addr() % 16 == 0);\n    let val = U128 { whole: val };\n    let (mut prev_hi, mut prev_lo);\n\n    // SAFETY: the caller must uphold the safety contract.\n    // CDSG has SeqCst semantics.\n    //\n    // Do not use atomic_rmw_cas_3 because it needs extra LGR to implement swap.\n    unsafe {\n        macro_rules! swap {\n            ($val_hi:tt, $val_lo:tt) => {\n                asm!(\n                    \"lg %r1, 8({dst})\",                                // atomic { r1 = *dst.byte_add(8) }\n                    \"lg %r0, 0({dst})\",                                // atomic { r0 = *dst }\n                    \"2:\", // 'retry:\n                        concat!(\"cdsg %r0, %\", $val_hi, \", 0({dst})\"), // atomic { if *dst == r0:r1 { cc = 0; *dst = val_hi:val_lo } else { cc = 1; r0:r1 = *dst } }\n                        \"jl 2b\",                                       // if cc == 1 { jump 'retry }\n                    dst = in(reg) ptr_reg!(dst),\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    out(\"r0\") prev_hi,\n                    out(\"r1\") prev_lo,\n                    in($val_hi) val.pair.hi,\n                    in($val_lo) val.pair.lo,\n                    // Do not use `preserves_flags` because CDSG modifies the condition code.\n                    options(nostack),\n                )\n            };\n        }\n        // r4 is stack pointer on z/OS.\n        #[cfg(not(target_os = \"zos\"))]\n        swap!(\"r4\", \"r5\");\n        #[cfg(target_os = \"zos\")]\n        swap!(\"r12\", \"r13\");\n        U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole\n    }\n}\n\n/// Atomic RMW by CAS loop (3 arguments)\n/// `unsafe fn(dst: *mut u128, val: u128, order: Ordering) -> u128;`\n///\n/// `$op` can use the following registers:\n/// - val_hi/val_lo pair: val argument (read-only for `$op`)\n/// - r0/r1 pair: previous value loaded (read-only for `$op`)\n/// - r12/r13 pair: new value that will be stored\nmacro_rules! atomic_rmw_cas_3 {\n    ($name:ident, [$($reg:tt)*], $($op:tt)*) => {\n        #[inline]\n        unsafe fn $name(dst: *mut u128, val: u128, _order: Ordering) -> u128 {\n            debug_assert!(dst.addr() % 16 == 0);\n            let val = U128 { whole: val };\n            let (mut prev_hi, mut prev_lo);\n\n            // SAFETY: the caller must uphold the safety contract.\n            // CDSG has SeqCst semantics.\n            unsafe {\n                asm!(\n                    \"lg %r1, 8({dst})\",             // atomic { r1 = *dst.byte_add(8) }\n                    \"lg %r0, 0({dst})\",             // atomic { r0 = *dst }\n                    \"2:\", // 'retry:\n                        $($op)*\n                        \"cdsg %r0, %r12, 0({dst})\", // atomic { if *dst == r0:r1 { cc = 0; *dst = r12:r13 } else { cc = 1; r0:r1 = *dst } }\n                        \"jl 2b\",                    // if cc == 1 { jump 'retry }\n                    dst = in(reg) ptr_reg!(dst),\n                    val_hi = in(reg) val.pair.hi,\n                    val_lo = in(reg) val.pair.lo,\n                    $($reg)*\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    out(\"r0\") prev_hi,\n                    out(\"r1\") prev_lo,\n                    out(\"r12\") _,\n                    out(\"r13\") _,\n                    // Do not use `preserves_flags` because CDSG modifies the condition code.\n                    options(nostack),\n                );\n                U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole\n            }\n        }\n    };\n}\n/// Atomic RMW by CAS loop (2 arguments)\n/// `unsafe fn(dst: *mut u128, order: Ordering) -> u128;`\n///\n/// `$op` can use the following registers:\n/// - r0/r1 pair: previous value loaded (read-only for `$op`)\n/// - r12/r13 pair: new value that will be stored\nmacro_rules! atomic_rmw_cas_2 {\n    ($name:ident, [$($reg:tt)*], $($op:tt)*) => {\n        #[inline]\n        unsafe fn $name(dst: *mut u128, _order: Ordering) -> u128 {\n            debug_assert!(dst.addr() % 16 == 0);\n            let (mut prev_hi, mut prev_lo);\n\n            // SAFETY: the caller must uphold the safety contract.\n            // CDSG has SeqCst semantics.\n            unsafe {\n                asm!(\n                    \"lg %r1, 8({dst})\",             // atomic { r1 = *dst.byte_add(8) }\n                    \"lg %r0, 0({dst})\",             // atomic { r0 = *dst }\n                    \"2:\", // 'retry:\n                        $($op)*\n                        \"cdsg %r0, %r12, 0({dst})\", // atomic { if *dst == r0:r1 { cc = 0; *dst = r12:r13 } else { cc = 1; r0:r1 = *dst } }\n                        \"jl 2b\",                    // if cc == 1 { jump 'retry }\n                    dst = in(reg) ptr_reg!(dst),\n                    $($reg)*\n                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                    out(\"r0\") prev_hi,\n                    out(\"r1\") prev_lo,\n                    out(\"r12\") _,\n                    out(\"r13\") _,\n                    // Do not use `preserves_flags` because CDSG modifies the condition code.\n                    options(nostack),\n                );\n                U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole\n            }\n        }\n    };\n}\n\natomic_rmw_cas_3! {\n    atomic_add, [],\n    distinct_op!(\"algr\", \"%r13\", \"%r1\", \"{val_lo}\"), // r13 = r1 + val_lo; cc = zero | carry\n    \"lgr %r12, %r0\",                                 // r12 = r0\n    \"alcgr %r12, {val_hi}\",                          // r12 += val_hi + carry\n}\natomic_rmw_cas_3! {\n    atomic_sub, [],\n    distinct_op!(\"slgr\", \"%r13\", \"%r1\", \"{val_lo}\"), // r13 = r1 - val_lo; cc = zero | borrow\n    \"lgr %r12, %r0\",                                 // r12 = r0\n    \"slbgr %r12, {val_hi}\",                          // r12 -= val_hi + borrow\n}\natomic_rmw_cas_3! {\n    atomic_and, [],\n    distinct_op!(\"ngr\", \"%r13\", \"%r1\", \"{val_lo}\"), // r13 = r1 & val_lo\n    distinct_op!(\"ngr\", \"%r12\", \"%r0\", \"{val_hi}\"), // r12 = r0 & val_hi\n}\n\n// Use nngrk on z15 or later.\n#[cfg(any(\n    target_feature = \"miscellaneous-extensions-3\",\n    portable_atomic_target_feature = \"miscellaneous-extensions-3\",\n))]\natomic_rmw_cas_3! {\n    atomic_nand, [],\n    \"nngrk %r13, %r1, {val_lo}\", // r13 = !(r1 & val_lo)\n    \"nngrk %r12, %r0, {val_hi}\", // r12 = !(r0 & val_hi)\n}\n#[cfg(not(any(\n    target_feature = \"miscellaneous-extensions-3\",\n    portable_atomic_target_feature = \"miscellaneous-extensions-3\",\n)))]\natomic_rmw_cas_3! {\n    atomic_nand, [],\n    distinct_op!(\"ngr\", \"%r13\", \"%r1\", \"{val_lo}\"), // r13 = r1 & val_lo\n    distinct_op!(\"ngr\", \"%r12\", \"%r0\", \"{val_hi}\"), // r12 = r0 & val_hi\n    \"lcgr %r13, %r13\",                              // r13 = !r13 + 1\n    \"aghi %r13, -1\",                                // r13 -= 1\n    \"lcgr %r12, %r12\",                              // r12 = !r12 + 1\n    \"aghi %r12, -1\",                                // r12 -= 1\n}\n\natomic_rmw_cas_3! {\n    atomic_or, [],\n    distinct_op!(\"ogr\", \"%r13\", \"%r1\", \"{val_lo}\"), // r13 = r1 | val_lo\n    distinct_op!(\"ogr\", \"%r12\", \"%r0\", \"{val_hi}\"), // r12 = r0 | val_hi\n}\natomic_rmw_cas_3! {\n    atomic_xor, [],\n    distinct_op!(\"xgr\", \"%r13\", \"%r1\", \"{val_lo}\"), // r13 = r1 ^ val_lo\n    distinct_op!(\"xgr\", \"%r12\", \"%r0\", \"{val_hi}\"), // r12 = r0 ^ val_hi\n}\n\ncfg_sel!({\n    #[cfg(any(\n        target_feature = \"load-store-on-cond\",\n        portable_atomic_target_feature = \"load-store-on-cond\",\n    ))]\n    {\n        atomic_rmw_cas_3! {\n            atomic_max, [],\n            \"clgr %r1, {val_lo}\",                       // if r1(u) < val_lo(u) { cc = 1 } else if r1(u) > val_lo(u) { cc = 2 } else { cc = 0 }\n            select_op!(\"h\", \"%r12\", \"%r1\", \"{val_lo}\"), // if cc == 2 { r12 = r1 } else { r12 = val_lo }\n            \"cgr %r0, {val_hi}\",                        // if r0(i) < val_hi(i) { cc = 1 } else if r0(i) > val_hi(i) { cc = 2 } else { cc = 0 }\n            select_op!(\"h\", \"%r13\", \"%r1\", \"{val_lo}\"), // if cc == 2 { r13 = r1 } else { r13 = val_lo }\n            \"locgre %r13, %r12\",                        // if cc == 0 { r13 = r12 }\n            select_op!(\"h\", \"%r12\", \"%r0\", \"{val_hi}\"), // if cc == 2 { r12 = r0 } else { r12 = val_hi }\n        }\n        atomic_rmw_cas_3! {\n            atomic_umax, [tmp = out(reg) _,],\n            \"clgr %r1, {val_lo}\",                        // if r1(u) < val_lo(u) { cc = 1 } else if r1(u) > val_lo(u) { cc = 2 } else { cc = 0 }\n            select_op!(\"h\", \"{tmp}\", \"%r1\", \"{val_lo}\"), // if cc == 2 { tmp = r1 } else { tmp = val_lo }\n            \"clgr %r0, {val_hi}\",                        // if r0(u) < val_hi(u) { cc = 1 } else if r0(u) > val_hi(u) { cc = 2 } else { cc = 0 }\n            select_op!(\"h\", \"%r12\", \"%r0\", \"{val_hi}\"),  // if cc == 2 { r12 = r0 } else { r12 = val_hi }\n            select_op!(\"h\", \"%r13\", \"%r1\", \"{val_lo}\"),  // if cc == 2 { r13 = r1 } else { r13 = val_lo }\n            \"cgr %r0, {val_hi}\",                         // if r0(i) < val_hi(i) { cc = 1 } else if r0(i) > val_hi(i) { cc = 2 } else { cc = 0 }\n            \"locgre %r13, {tmp}\",                        // if cc == 0 { r13 = tmp }\n        }\n        atomic_rmw_cas_3! {\n            atomic_min, [],\n            \"clgr %r1, {val_lo}\",                       // if r1(u) < val_lo(u) { cc = 1 } else if r1(u) > val_lo(u) { cc = 2 } else { cc = 0 }\n            select_op!(\"l\", \"%r12\", \"%r1\", \"{val_lo}\"), // if cc == 1 { r12 = r1 } else { r12 = val_lo }\n            \"cgr %r0, {val_hi}\",                        // if r0(i) < val_hi(i) { cc = 1 } else if r0(i) > val_hi(i) { cc = 2 } else { cc = 0 }\n            select_op!(\"l\", \"%r13\", \"%r1\", \"{val_lo}\"), // if cc == 1 { r13 = r1 } else { r13 = val_lo }\n            \"locgre %r13, %r12\",                        // if cc == 0 { r13 = r12 }\n            select_op!(\"l\", \"%r12\", \"%r0\", \"{val_hi}\"), // if cc == 1 { r12 = r0 } else { r12 = val_hi }\n        }\n        atomic_rmw_cas_3! {\n            atomic_umin, [tmp = out(reg) _,],\n            \"clgr %r1, {val_lo}\",                        // if r1(u) < val_lo(u) { cc = 1 } else if r1(u) > val_lo(u) { cc = 2 } else { cc = 0 }\n            select_op!(\"l\", \"{tmp}\", \"%r1\", \"{val_lo}\"), // if cc == 1 { tmp = r1 } else { tmp = val_lo }\n            \"clgr %r0, {val_hi}\",                        // if r0(u) < val_hi(u) { cc = 1 } else if r0(u) > val_hi(u) { cc = 2 } else { cc = 0 }\n            select_op!(\"l\", \"%r12\", \"%r0\", \"{val_hi}\"),  // if cc == 1 { r12 = r0 } else { r12 = val_hi }\n            select_op!(\"l\", \"%r13\", \"%r1\", \"{val_lo}\"),  // if cc == 1 { r13 = r1 } else { r13 = val_lo }\n            \"cgr %r0, {val_hi}\",                         // if r0(i) < val_hi(i) { cc = 1 } else if r0(i) > val_hi(i) { cc = 2 } else { cc = 0 }\n            \"locgre %r13, {tmp}\",                        // if cc == 0 { r13 = tmp }\n        }\n    }\n    #[cfg(else)]\n    {\n        #[rustfmt::skip]\n        macro_rules! atomic_cmp {\n            ($name:ident, $cmp_hi1:tt, $cmp_hi2:tt, $cmp_lo:tt,) => {\n                #[inline]\n                unsafe fn $name(dst: *mut u128, val: u128, _order: Ordering) -> u128 {\n                    debug_assert!(dst.addr() % 16 == 0);\n                    let val = U128 { whole: val };\n                    let (mut prev_hi, mut prev_lo);\n\n                    // SAFETY: the caller must uphold the safety contract.\n                    // CDSG has SeqCst semantics.\n                    unsafe {\n                        macro_rules! cmp {\n                            ($val_hi:tt, $val_lo:tt) => {\n                                asm!(\n                                    \"lg %r1, 8({dst})\",                                // atomic { r1 = *dst.byte_add(8) }\n                                    \"lg %r0, 0({dst})\",                                // atomic { r0 = *dst }\n                                    \"2:\", // 'retry:\n                                        concat!($cmp_hi1, \" %\", $val_hi, \", %r0, 4f\"), // if $cmp_hi1(val_hi, r0) { jump 'val }\n                                        concat!($cmp_hi2, \" %\", $val_hi, \", %r0, 3f\"), // if $cmp_hi2(val_hi, r0) { jump 'prev }\n                                        concat!($cmp_lo, \" %\", $val_lo, \", %r1, 4f\"),  // if $cmp_lo(val_lo, r1) { jump 'val }\n                                    \"3:\", // 'prev:\n                                        \"cdsg %r0, %r0, 0({dst})\",                     // atomic { if *dst == r0:r1 { cc = 0; *dst = r0:r1 } else { cc = 1; r0:r1 = *dst } }\n                                        \"jl 2b\",                                       // if cc == 1 { jump 'retry }\n                                        \"j 5f\",\n                                    \"4:\", // 'val:\n                                        concat!(\"cdsg %r0, %\", $val_hi, \", 0({dst})\"), // atomic { if *dst == r0:r1 { cc = 0; *dst = val_hi:val_lo } else { cc = 1; r0:r1 = *dst } }\n                                        \"jl 2b\",                                       // if cc == 1 { jump 'retry }\n                                    \"5:\",\n                                    dst = in(reg) ptr_reg!(dst),\n                                    // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.\n                                    out(\"r0\") prev_hi,\n                                    out(\"r1\") prev_lo,\n                                    in($val_hi) val.pair.hi,\n                                    in($val_lo) val.pair.lo,\n                                    // Do not use `preserves_flags` because CDSG modifies the condition code.\n                                    options(nostack),\n                                )\n                            };\n                        }\n                        // r4 is stack pointer on z/OS.\n                        #[cfg(not(target_os = \"zos\"))]\n                        cmp!(\"r4\", \"r5\");\n                        #[cfg(target_os = \"zos\")]\n                        cmp!(\"r12\", \"r13\");\n                        U128 { pair: Pair { hi: prev_hi, lo: prev_lo } }.whole\n                    }\n                }\n            };\n        }\n        // loc{,g}r requires z196 or later.\n        atomic_cmp! {\n            atomic_max,\n            \"cgrjh\",   // signed >\n            \"cgrjl\",   // signed <\n            \"clgrjhe\", // unsigned >=\n        }\n        atomic_cmp! {\n            atomic_umax,\n            \"clgrjh\",  // unsigned >\n            \"clgrjl\",  // unsigned <\n            \"clgrjhe\", // unsigned >=\n        }\n        atomic_cmp! {\n            atomic_min,\n            \"cgrjl\",   // signed <\n            \"cgrjh\",   // signed >\n            \"clgrjle\", // unsigned <=\n        }\n        atomic_cmp! {\n            atomic_umin,\n            \"clgrjl\",   // unsigned <\n            \"clgrjh\",   // unsigned >\n            \"clgrjle\",  // unsigned <=\n        }\n    }\n});\n\natomic_rmw_cas_2! {\n    atomic_not, [],\n    \"lcgr %r13, %r1\", // r13 = !r1 + 1\n    \"aghi %r13, -1\",  // r13 -= 1\n    \"lcgr %r12, %r0\", // r12 = !r0 + 1\n    \"aghi %r12, -1\",  // r12 -= 1\n}\n\n#[cfg(any(target_feature = \"distinct-ops\", portable_atomic_target_feature = \"distinct-ops\"))]\natomic_rmw_cas_2! {\n    atomic_neg, [zero = in(reg) 0_u64,],\n    \"slgrk %r13, {zero}, %r1\", // r13 = 0 - r1; cc = zero | borrow\n    \"lghi %r12, 0\",            // r12 = 0\n    \"slbgr %r12, %r0\",         // r12 -= r0 + borrow\n}\n#[cfg(not(any(target_feature = \"distinct-ops\", portable_atomic_target_feature = \"distinct-ops\")))]\natomic_rmw_cas_2! {\n    atomic_neg, [],\n    \"lghi %r13, 0\",    // r13 = 0\n    \"slgr %r13, %r1\",  // r13 -= r1; cc = zero | borrow\n    \"lghi %r12, 0\",    // r12 = 0\n    \"slbgr %r12, %r0\", // r12 -= r0 + borrow\n}\n\n#[inline]\nconst fn is_lock_free() -> bool {\n    IS_ALWAYS_LOCK_FREE\n}\nconst IS_ALWAYS_LOCK_FREE: bool = true;\n\natomic128!(AtomicI128, i128, atomic_max, atomic_min);\natomic128!(AtomicU128, u128, atomic_umax, atomic_umin);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    test_atomic_int!(i128);\n    test_atomic_int!(u128);\n\n    // load/store/swap implementation is not affected by signedness, so it is\n    // enough to test only unsigned types.\n    stress_test!(u128);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic128/x86_64.rs",
      "sha256": "19c67a75d8ee1392aae67f49b88a3b69e78acce5004280c7a7be33051774c8ed",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\n128-bit atomic implementation on x86_64.\n\nThis architecture provides the following 128-bit atomic instructions:\n\n- CMPXCHG16B: CAS (CMPXCHG16B)\n- VMOVDQA: load/store (AVX)\n\nWe could use asm byte_wise_atomic_load + asm atomic_compare_exchange pattern for RMW here, but using an\ninline assembly allows omitting the comparison of results and the storing/comparing of flags.\n\nNote: On Miri and ThreadSanitizer which do not support inline assembly, we don't use\nthis module and use intrinsics.rs instead.\n\nRefs:\n- x86 and amd64 instruction reference https://www.felixcloutier.com/x86\n- atomic-maybe-uninit https://github.com/taiki-e/atomic-maybe-uninit\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\n// TODO: use core::arch::x86_64::cmpxchg16b where available and efficient than asm\n\ninclude!(\"macros.rs\");\n\n#[cfg(not(any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\")))]\n#[path = \"../fallback/outline_atomics.rs\"]\nmod fallback;\n\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(not(target_env = \"sgx\"))]\n#[cfg_attr(\n    not(target_feature = \"sse\"),\n    cfg(not(any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\")))\n)]\n#[cfg(any(\n    test,\n    not(all(\n        any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n        target_feature = \"avx\",\n    )),\n))]\n#[path = \"../detect/x86_64.rs\"]\nmod detect;\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\n#[cfg(not(all(\n    not(target_feature = \"avx\"),\n    any(portable_atomic_no_outline_atomics, target_env = \"sgx\", not(target_feature = \"sse\")),\n)))]\nuse core::arch::x86_64::__m128i;\nuse core::sync::atomic::Ordering;\n\n#[cfg(portable_atomic_no_strict_provenance)]\nuse crate::utils::ptr::PtrExt as _;\nuse crate::utils::{Pair, U128};\n\n// Asserts that the function is called in the correct context.\nmacro_rules! debug_assert_cmpxchg16b {\n    () => {\n        #[cfg(not(any(\n            target_feature = \"cmpxchg16b\",\n            portable_atomic_target_feature = \"cmpxchg16b\",\n        )))]\n        {\n            debug_assert!(detect::detect().cmpxchg16b());\n        }\n    };\n}\n#[cfg(not(all(\n    not(target_feature = \"avx\"),\n    any(portable_atomic_no_outline_atomics, target_env = \"sgx\", not(target_feature = \"sse\")),\n)))]\nmacro_rules! debug_assert_cmpxchg16b_avx {\n    () => {{\n        debug_assert_cmpxchg16b!();\n        #[cfg(not(target_feature = \"avx\"))]\n        {\n            debug_assert!(detect::detect().avx());\n        }\n    }};\n}\n\n#[cfg(not(all(\n    not(target_feature = \"avx\"),\n    any(portable_atomic_no_outline_atomics, target_env = \"sgx\", not(target_feature = \"sse\")),\n)))]\n#[cfg(target_pointer_width = \"32\")]\nmacro_rules! ptr_modifier {\n    () => {\n        \":e\"\n    };\n}\n#[cfg(not(all(\n    not(target_feature = \"avx\"),\n    any(portable_atomic_no_outline_atomics, target_env = \"sgx\", not(target_feature = \"sse\")),\n)))]\n#[cfg(target_pointer_width = \"64\")]\nmacro_rules! ptr_modifier {\n    () => {\n        \"\"\n    };\n}\n\n// Unlike AArch64 and RISC-V, x86's assembler doesn't check instruction\n// requirements for the currently enabled target features. In the first place,\n// there is no option in the x86 assembly for such case, like Arm .arch_extension,\n// RISC-V .option arch, PowerPC .machine, etc.\n// However, we set target_feature(enable) when available (Rust 1.69+) in case a\n// new codegen backend is added that checks for it in the future, or an option\n// is added to the assembler to check for it.\n#[cfg_attr(\n    not(portable_atomic_no_cmpxchg16b_target_feature),\n    target_feature(enable = \"cmpxchg16b\")\n)]\n#[inline]\nunsafe fn cmpxchg16b(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_cmpxchg16b!();\n\n    // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n    // reads, 16-byte aligned (required by CMPXCHG16B), that there are no\n    // concurrent non-atomic operations, and that the CPU supports CMPXCHG16B.\n    //\n    // If the value at `dst` (destination operand) and rdx:rax are equal, the\n    // 128-bit value in rcx:rbx is stored in the `dst`, otherwise the value at\n    // `dst` is loaded to rdx:rax.\n    //\n    // The ZF flag is set if the value at `dst` and rdx:rax are equal,\n    // otherwise it is cleared. Other flags are unaffected.\n    //\n    // Refs: https://www.felixcloutier.com/x86/cmpxchg8b:cmpxchg16b\n    unsafe {\n        // cmpxchg16b is always SeqCst.\n        let r: u8;\n        let old = U128 { whole: old };\n        let new = U128 { whole: new };\n        let (prev_lo, prev_hi);\n        macro_rules! cmpxchg16b {\n            ($dst:tt) => {\n                asm!(\n                    \"xchg r8, rbx\", // save rbx which is reserved by LLVM\n                    concat!(\"lock cmpxchg16b xmmword ptr [\", $dst, \"]\"),\n                    \"setne cl\",\n                    \"mov rbx, r8\", // restore rbx\n                    inout(\"r8\") new.pair.lo => _,\n                    in(\"rcx\") new.pair.hi,\n                    inout(\"rax\") old.pair.lo => prev_lo,\n                    inout(\"rdx\") old.pair.hi => prev_hi,\n                    in($dst) dst,\n                    lateout(\"cl\") r,\n                    // Do not use `preserves_flags` because CMPXCHG16B modifies the ZF flag.\n                    options(nostack),\n                )\n            };\n        }\n        // rdi and rsi are call-preserved on Windows.\n        #[cfg(not(windows))]\n        #[cfg(target_pointer_width = \"32\")]\n        cmpxchg16b!(\"esi\");\n        #[cfg(not(windows))]\n        #[cfg(target_pointer_width = \"64\")]\n        cmpxchg16b!(\"rsi\");\n        #[cfg(windows)]\n        #[cfg(target_pointer_width = \"32\")]\n        cmpxchg16b!(\"r11d\");\n        #[cfg(windows)]\n        #[cfg(target_pointer_width = \"64\")]\n        cmpxchg16b!(\"r11\");\n        crate::utils::assert_unchecked(r == 0 || r == 1); // needed to remove extra test\n        (U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole, r == 0)\n    }\n}\n\n// VMOVDQA is atomic when AVX available.\n// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104688 for details.\n// Intel, AMD, and Zhaoxin officially guarantee this behavior (VIA has not responded),\n// but both LLVM and Boost always treat VMOVDQA as atomic when AVX available.\n// https://github.com/llvm/llvm-project/pull/74275\n// https://github.com/boostorg/atomic/commit/24a41db3e61627d99895f7e324b3d725d1be27c1\n//\n// Refs: https://www.felixcloutier.com/x86/movdqa:vmovdqa32:vmovdqa64\n//\n// Use cfg(target_feature = \"sse\") here -- SSE is included in the x86_64\n// baseline and is always available, but the SSE target feature is disabled for\n// use cases such as kernels and firmware that should not use vector registers.\n// So, do not use vector registers unless SSE target feature is enabled.\n// Note that we cannot use cfg(target_abi = \"softfloat\") because cfg(target_abi)\n// is unavailable on old rustc and target_abi = \"softfloat\" is not set for\n// softfloat x86_64 targets as of Rust 1.95.\n// See also https://github.com/rust-lang/rust/blob/1.84.0/src/doc/rustc/src/platform-support/x86_64-unknown-none.md.\n#[cfg(not(all(\n    not(target_feature = \"avx\"),\n    any(portable_atomic_no_outline_atomics, target_env = \"sgx\", not(target_feature = \"sse\")),\n)))]\n#[target_feature(enable = \"avx\")]\n#[inline]\nunsafe fn _atomic_load_vmovdqa(src: *mut u128) -> u128 {\n    debug_assert!(src.addr() % 16 == 0);\n    debug_assert_cmpxchg16b_avx!();\n\n    // SAFETY: the caller must uphold the safety contract.\n    //\n    // atomic load by vmovdqa is always SeqCst.\n    unsafe {\n        let out: __m128i;\n        asm!(\n            concat!(\"vmovdqa {out}, xmmword ptr [{src\", ptr_modifier!(), \"}]\"),\n            src = in(reg) src,\n            out = out(xmm_reg) out,\n            options(nostack, preserves_flags),\n        );\n        core::mem::transmute(out)\n    }\n}\n#[cfg(not(all(\n    not(target_feature = \"avx\"),\n    any(portable_atomic_no_outline_atomics, target_env = \"sgx\", not(target_feature = \"sse\")),\n)))]\n#[target_feature(enable = \"avx\")]\n#[inline]\nunsafe fn _atomic_store_vmovdqa(dst: *mut u128, val: u128, order: Ordering) {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_cmpxchg16b_avx!();\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        let val: __m128i = core::mem::transmute(val);\n        match order {\n            // Relaxed and Release stores are equivalent.\n            Ordering::Relaxed | Ordering::Release => {\n                asm!(\n                    concat!(\"vmovdqa xmmword ptr [{dst\", ptr_modifier!(), \"}], {val}\"),\n                    dst = in(reg) dst,\n                    val = in(xmm_reg) val,\n                    options(nostack, preserves_flags),\n                );\n            }\n            Ordering::SeqCst => {\n                let p = core::cell::UnsafeCell::new(core::mem::MaybeUninit::<u64>::uninit());\n                asm!(\n                    concat!(\"vmovdqa xmmword ptr [{dst\", ptr_modifier!(), \"}], {val}\"),\n                    // Equivalent to `mfence`, but is up to 3.1x faster on Coffee Lake and up to 2.4x faster on Raptor Lake-H at least in simple cases.\n                    // - https://github.com/taiki-e/portable-atomic/pull/156\n                    // - LLVM uses `lock or` https://godbolt.org/z/vv6rjzfYd\n                    // - Windows uses `xchg` for x86_32 for MemoryBarrier https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-memorybarrier\n                    // - MSVC STL uses `lock inc` https://github.com/microsoft/STL/pull/740\n                    // - boost uses `lock or` https://github.com/boostorg/atomic/commit/559eba81af71386cedd99f170dc6101c6ad7bf22\n                    concat!(\"xchg qword ptr [{p\", ptr_modifier!(), \"}], {tmp}\"),\n                    dst = in(reg) dst,\n                    val = in(xmm_reg) val,\n                    p = in(reg) p.get(),\n                    tmp = out(reg) _,\n                    options(nostack, preserves_flags),\n                );\n            }\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(not(all(\n    any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n    target_feature = \"avx\",\n)))]\n#[cfg(not(all(\n    any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n    any(portable_atomic_no_outline_atomics, target_env = \"sgx\", not(target_feature = \"sse\")),\n)))]\nmacro_rules! load_store_detect {\n    (\n        vmovdqa = $vmovdqa:ident\n        cmpxchg16b = $cmpxchg16b:ident\n        fallback = $fallback:ident\n    ) => {{\n        let cpuid = detect::detect();\n        #[cfg(not(any(\n            target_feature = \"cmpxchg16b\",\n            portable_atomic_target_feature = \"cmpxchg16b\",\n        )))]\n        {\n            // Check CMPXCHG16B first to prevent mixing atomic and non-atomic access.\n            if cpuid.cmpxchg16b() {\n                #[cfg(target_feature = \"avx\")]\n                {\n                    $vmovdqa\n                }\n                // We only use VMOVDQA when SSE is enabled. See _atomic_load_vmovdqa() for more.\n                #[cfg(not(target_feature = \"avx\"))]\n                {\n                    #[cfg(target_feature = \"sse\")]\n                    {\n                        if cpuid.avx() { $vmovdqa } else { $cmpxchg16b }\n                    }\n                    #[cfg(not(target_feature = \"sse\"))]\n                    {\n                        $cmpxchg16b\n                    }\n                }\n            } else {\n                fallback::$fallback\n            }\n        }\n        #[cfg(any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"))]\n        {\n            if cpuid.avx() { $vmovdqa } else { $cmpxchg16b }\n        }\n    }};\n}\n\n#[inline]\nunsafe fn atomic_load(src: *mut u128, _order: Ordering) -> u128 {\n    #[cfg(all(\n        any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n        target_feature = \"avx\",\n    ))]\n    // SAFETY: the caller must uphold the safety contract.\n    // cfg guarantees that CMPXCHG16B and AVX are available at compile-time.\n    unsafe {\n        _atomic_load_vmovdqa(src)\n    }\n    #[cfg(not(all(\n        any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n        target_feature = \"avx\",\n    )))]\n    {\n        // We only use VMOVDQA when SSE is enabled. See _atomic_load_vmovdqa() for more.\n        // SGX doesn't support CPUID.\n        #[cfg(all(\n            any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n            any(\n                portable_atomic_no_outline_atomics,\n                target_env = \"sgx\",\n                not(target_feature = \"sse\")\n            ),\n        ))]\n        // SAFETY: the caller must uphold the safety contract.\n        // cfg guarantees that CMPXCHG16B is available at compile-time.\n        unsafe {\n            // cmpxchg16b is always SeqCst.\n            _atomic_load_cmpxchg16b(src)\n        }\n        #[cfg(not(all(\n            any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n            any(\n                portable_atomic_no_outline_atomics,\n                target_env = \"sgx\",\n                not(target_feature = \"sse\")\n            ),\n        )))]\n        // SAFETY: the caller must uphold the safety contract.\n        unsafe {\n            ifunc!(unsafe fn(src: *mut u128) -> u128 {\n                load_store_detect! {\n                    vmovdqa = _atomic_load_vmovdqa\n                    cmpxchg16b = _atomic_load_cmpxchg16b\n                    // Use SeqCst because cmpxchg16b and atomic load by vmovdqa is always SeqCst.\n                    fallback = atomic_load_seqcst\n                }\n            })\n        }\n    }\n}\n// See cmpxchg16b() for target_feature(enable).\n#[cfg_attr(\n    not(portable_atomic_no_cmpxchg16b_target_feature),\n    target_feature(enable = \"cmpxchg16b\")\n)]\n#[inline]\nunsafe fn _atomic_load_cmpxchg16b(src: *mut u128) -> u128 {\n    debug_assert!(src.addr() % 16 == 0);\n    debug_assert_cmpxchg16b!();\n\n    // SAFETY: the caller must guarantee that `src` is valid for both writes and\n    // reads, 16-byte aligned, and that there are no concurrent non-atomic operations.\n    // cfg guarantees that the CPU supports CMPXCHG16B.\n    //\n    // See cmpxchg16b function for more.\n    //\n    // We could use CAS loop by atomic_compare_exchange here, but using an inline assembly allows\n    // omitting the storing of condition flags and avoid use of xchg to handle rbx.\n    unsafe {\n        // cmpxchg16b is always SeqCst.\n        let (out_lo, out_hi);\n        macro_rules! cmpxchg16b {\n            ($dst:tt, $save:tt) => {\n                asm!(\n                    concat!(\"mov \", $save, \", rbx\"), // save rbx which is reserved by LLVM\n                    \"xor rbx, rbx\", // zeroed rbx\n                    concat!(\"lock cmpxchg16b xmmword ptr [\", $dst, \"]\"),\n                    concat!(\"mov rbx, \", $save), // restore rbx\n                    // set old/new args of cmpxchg16b to 0 (rbx is zeroed after saved to rbx_tmp, to avoid xchg)\n                    out($save) _,\n                    in(\"rcx\") 0_u64,\n                    inout(\"rax\") 0_u64 => out_lo,\n                    inout(\"rdx\") 0_u64 => out_hi,\n                    in($dst) src,\n                    // Do not use `preserves_flags` because CMPXCHG16B modifies the ZF flag.\n                    options(nostack),\n                )\n            };\n        }\n        // rdi and rsi are call-preserved on Windows.\n        #[cfg(not(windows))]\n        #[cfg(target_pointer_width = \"32\")]\n        cmpxchg16b!(\"edi\", \"rsi\");\n        #[cfg(not(windows))]\n        #[cfg(target_pointer_width = \"64\")]\n        cmpxchg16b!(\"rdi\", \"rsi\");\n        #[cfg(windows)]\n        #[cfg(target_pointer_width = \"32\")]\n        cmpxchg16b!(\"r9d\", \"r8\");\n        #[cfg(windows)]\n        #[cfg(target_pointer_width = \"64\")]\n        cmpxchg16b!(\"r9\", \"r8\");\n        U128 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n    }\n}\n\n#[inline]\nunsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {\n    #[cfg(all(\n        any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n        target_feature = \"avx\",\n    ))]\n    // SAFETY: the caller must uphold the safety contract.\n    // cfg guarantees that CMPXCHG16B and AVX are available at compile-time.\n    unsafe {\n        _atomic_store_vmovdqa(dst, val, order);\n    }\n    #[cfg(not(all(\n        any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n        target_feature = \"avx\",\n    )))]\n    {\n        // We only use VMOVDQA when SSE is enabled. See _atomic_load_vmovdqa() for more.\n        // SGX doesn't support CPUID.\n        #[cfg(all(\n            any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n            any(\n                portable_atomic_no_outline_atomics,\n                target_env = \"sgx\",\n                not(target_feature = \"sse\")\n            ),\n        ))]\n        // SAFETY: the caller must uphold the safety contract.\n        // cfg guarantees that CMPXCHG16B is available at compile-time.\n        unsafe {\n            // cmpxchg16b is always SeqCst.\n            let _ = order;\n            _atomic_store_cmpxchg16b(dst, val);\n        }\n        #[cfg(not(all(\n            any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n            any(\n                portable_atomic_no_outline_atomics,\n                target_env = \"sgx\",\n                not(target_feature = \"sse\")\n            ),\n        )))]\n        // SAFETY: the caller must uphold the safety contract.\n        unsafe {\n            #[cfg(target_feature = \"sse\")]\n            fn_alias! {\n                #[target_feature(enable = \"avx\")]\n                unsafe fn(dst: *mut u128, val: u128);\n                // atomic store by vmovdqa has at least release semantics.\n                _atomic_store_vmovdqa_non_seqcst = _atomic_store_vmovdqa(Ordering::Release);\n                _atomic_store_vmovdqa_seqcst = _atomic_store_vmovdqa(Ordering::SeqCst);\n            }\n            match order {\n                // Relaxed and Release stores are equivalent in all implementations\n                // that may be called here (vmovdqa, asm-based cmpxchg16b, and fallback).\n                // core::arch's cmpxchg16b will never called here.\n                Ordering::Relaxed | Ordering::Release => {\n                    ifunc!(unsafe fn(dst: *mut u128, val: u128) {\n                        load_store_detect! {\n                            vmovdqa = _atomic_store_vmovdqa_non_seqcst\n                            cmpxchg16b = _atomic_store_cmpxchg16b\n                            fallback = atomic_store_non_seqcst\n                        }\n                    });\n                }\n                Ordering::SeqCst => {\n                    ifunc!(unsafe fn(dst: *mut u128, val: u128) {\n                        load_store_detect! {\n                            vmovdqa = _atomic_store_vmovdqa_seqcst\n                            cmpxchg16b = _atomic_store_cmpxchg16b\n                            fallback = atomic_store_seqcst\n                        }\n                    });\n                }\n                _ => unreachable!(),\n            }\n        }\n    }\n}\n// See cmpxchg16b() for target_feature(enable).\n#[cfg_attr(\n    not(portable_atomic_no_cmpxchg16b_target_feature),\n    target_feature(enable = \"cmpxchg16b\")\n)]\n#[inline]\nunsafe fn _atomic_store_cmpxchg16b(dst: *mut u128, val: u128) {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        // cmpxchg16b is always SeqCst.\n        atomic_swap_cmpxchg16b(dst, val, Ordering::SeqCst);\n    }\n}\n\n#[inline]\nunsafe fn atomic_compare_exchange(\n    dst: *mut u128,\n    old: u128,\n    new: u128,\n    _success: Ordering,\n    _failure: Ordering,\n) -> Result<u128, u128> {\n    #[cfg(any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"))]\n    // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n    // reads, 16-byte aligned, that there are no concurrent non-atomic operations,\n    // and cfg guarantees that CMPXCHG16B is available at compile-time.\n    let (prev, ok) = unsafe { cmpxchg16b(dst, old, new) };\n    #[cfg(not(any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\")))]\n    // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n    // reads, 16-byte aligned, and that there are no different kinds of concurrent accesses.\n    let (prev, ok) = unsafe {\n        ifunc!(unsafe fn(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {\n            if detect::detect().cmpxchg16b() {\n                cmpxchg16b\n            } else {\n                // Use SeqCst because cmpxchg16b is always SeqCst.\n                fallback::atomic_compare_exchange_seqcst\n            }\n        })\n    };\n    if ok { Ok(prev) } else { Err(prev) }\n}\n\n// cmpxchg16b is always strong.\nuse self::atomic_compare_exchange as atomic_compare_exchange_weak;\n\n// See cmpxchg16b() for target_feature(enable).\n#[cfg_attr(\n    not(portable_atomic_no_cmpxchg16b_target_feature),\n    target_feature(enable = \"cmpxchg16b\")\n)]\n#[inline]\nunsafe fn atomic_swap_cmpxchg16b(dst: *mut u128, val: u128, _order: Ordering) -> u128 {\n    debug_assert!(dst.addr() % 16 == 0);\n    debug_assert_cmpxchg16b!();\n\n    // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n    // reads, 16-byte aligned, and that there are no concurrent non-atomic operations.\n    // cfg guarantees that the CPU supports CMPXCHG16B.\n    //\n    // See cmpxchg16b function for more.\n    //\n    // We could use CAS loop by atomic_compare_exchange here, but using an inline assembly allows\n    // omitting the storing/comparing of condition flags and reducing uses of xchg/mov to handle rbx.\n    //\n    // Do not use atomic_rmw_cas_3 because it needs extra MOV to implement swap.\n    unsafe {\n        // cmpxchg16b is always SeqCst.\n        let val = U128 { whole: val };\n        let (mut prev_lo, mut prev_hi);\n        macro_rules! cmpxchg16b {\n            ($dst:tt, $save:tt) => {\n                asm!(\n                    concat!(\"xchg \", $save, \", rbx\"), // save rbx which is reserved by LLVM\n                    // This is not single-copy atomic reads, but this is ok because subsequent\n                    // CAS will check for consistency.\n                    //\n                    // This is based on the code generated for the first load in DW RMWs by LLVM.\n                    //\n                    // Note that the C++20 memory model does not allow mixed-sized atomic access,\n                    // so we must use inline assembly to implement this.\n                    // (i.e., byte-wise atomic based on the standard library's atomic types\n                    // cannot be used here).\n                    concat!(\"mov rax, qword ptr [\", $dst, \"]\"),\n                    concat!(\"mov rdx, qword ptr [\", $dst, \" + 8]\"),\n                    \"2:\",\n                        concat!(\"lock cmpxchg16b xmmword ptr [\", $dst, \"]\"),\n                        \"jne 2b\",\n                    concat!(\"mov rbx, \", $save), // restore rbx\n                    inout($save) val.pair.lo => _,\n                    in(\"rcx\") val.pair.hi,\n                    out(\"rax\") prev_lo,\n                    out(\"rdx\") prev_hi,\n                    in($dst) dst,\n                    // Do not use `preserves_flags` because CMPXCHG16B modifies the ZF flag.\n                    options(nostack),\n                )\n            };\n        }\n        // rdi and rsi are call-preserved on Windows.\n        #[cfg(not(windows))]\n        #[cfg(target_pointer_width = \"32\")]\n        cmpxchg16b!(\"edi\", \"rsi\");\n        #[cfg(not(windows))]\n        #[cfg(target_pointer_width = \"64\")]\n        cmpxchg16b!(\"rdi\", \"rsi\");\n        #[cfg(windows)]\n        #[cfg(target_pointer_width = \"32\")]\n        cmpxchg16b!(\"r9d\", \"r8\");\n        #[cfg(windows)]\n        #[cfg(target_pointer_width = \"64\")]\n        cmpxchg16b!(\"r9\", \"r8\");\n        U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n    }\n}\n\n/// Atomic RMW by CAS loop (3 arguments)\n/// `unsafe fn(dst: *mut u128, val: u128, order: Ordering) -> u128;`\n///\n/// `$op` can use the following registers:\n/// - r8/r9 pair: val argument (read-only for `$op`)\n/// - rax/rdx pair: previous value loaded (read-only for `$op`)\n/// - rbx/rcx pair: new value that will be stored\n// We could use CAS loop by atomic_compare_exchange here, but using an inline assembly allows\n// omitting the storing/comparing of condition flags and reducing uses of xchg/mov to handle rbx.\nmacro_rules! atomic_rmw_cas_3 {\n    ($name:ident, $($op:tt)*) => {\n        // See cmpxchg16b() for target_feature(enable).\n        #[cfg_attr(\n            not(portable_atomic_no_cmpxchg16b_target_feature),\n            target_feature(enable = \"cmpxchg16b\")\n        )]\n        #[inline]\n        unsafe fn $name(dst: *mut u128, val: u128, _order: Ordering) -> u128 {\n            debug_assert!(dst.addr() % 16 == 0);\n            debug_assert_cmpxchg16b!();\n            // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n            // reads, 16-byte aligned, and that there are no concurrent non-atomic operations.\n            // cfg guarantees that the CPU supports CMPXCHG16B.\n            //\n            // See cmpxchg16b function for more.\n            unsafe {\n                // cmpxchg16b is always SeqCst.\n                let val = U128 { whole: val };\n                let (mut prev_lo, mut prev_hi);\n                macro_rules! cmpxchg16b {\n                    ($dst:tt, $save:tt) => {\n                        asm!(\n                            concat!(\"mov \", $save, \", rbx\"), // save rbx which is reserved by LLVM\n                            // This is not single-copy atomic reads, but this is ok because subsequent\n                            // CAS will check for consistency.\n                            //\n                            // This is based on the code generated for the first load in DW RMWs by LLVM.\n                            //\n                            // Note that the C++20 memory model does not allow mixed-sized atomic access,\n                            // so we must use inline assembly to implement this.\n                            // (i.e., byte-wise atomic based on the standard library's atomic types\n                            // cannot be used here).\n                            concat!(\"mov rax, qword ptr [\", $dst, \"]\"),\n                            concat!(\"mov rdx, qword ptr [\", $dst, \" + 8]\"),\n                            \"2:\",\n                                $($op)*\n                                concat!(\"lock cmpxchg16b xmmword ptr [\", $dst, \"]\"),\n                                \"jne 2b\",\n                            concat!(\"mov rbx, \", $save), // restore rbx\n                            out($save) _,\n                            out(\"rcx\") _,\n                            out(\"rax\") prev_lo,\n                            out(\"rdx\") prev_hi,\n                            in($dst) dst,\n                            in(\"r8\") val.pair.lo,\n                            in(\"r9\") val.pair.hi,\n                            // Do not use `preserves_flags` because CMPXCHG16B modifies the ZF flag.\n                            options(nostack),\n                        )\n                    };\n                }\n                // rdi and rsi are call-preserved on Windows.\n                #[cfg(not(windows))]\n                #[cfg(target_pointer_width = \"32\")]\n                cmpxchg16b!(\"edi\", \"r10\");\n                #[cfg(not(windows))]\n                #[cfg(target_pointer_width = \"64\")]\n                cmpxchg16b!(\"rdi\", \"r10\");\n                #[cfg(windows)]\n                #[cfg(target_pointer_width = \"32\")]\n                cmpxchg16b!(\"r10d\", \"r11\");\n                #[cfg(windows)]\n                #[cfg(target_pointer_width = \"64\")]\n                cmpxchg16b!(\"r10\", \"r11\");\n                U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n            }\n        }\n    };\n}\n/// Atomic RMW by CAS loop (2 arguments)\n/// `unsafe fn(dst: *mut u128, order: Ordering) -> u128;`\n///\n/// `$op` can use the following registers:\n/// - rax/rdx pair: previous value loaded (read-only for `$op`)\n/// - rbx/rcx pair: new value that will be stored\n// We could use CAS loop by atomic_compare_exchange here, but using an inline assembly allows\n// omitting the storing of condition flags and avoid use of xchg to handle rbx.\nmacro_rules! atomic_rmw_cas_2 {\n    ($name:ident, $($op:tt)*) => {\n        // See cmpxchg16b() for target_feature(enable).\n        #[cfg_attr(\n            not(portable_atomic_no_cmpxchg16b_target_feature),\n            target_feature(enable = \"cmpxchg16b\")\n        )]\n        #[inline]\n        unsafe fn $name(dst: *mut u128, _order: Ordering) -> u128 {\n            debug_assert!(dst.addr() % 16 == 0);\n            debug_assert_cmpxchg16b!();\n            // SAFETY: the caller must guarantee that `dst` is valid for both writes and\n            // reads, 16-byte aligned, and that there are no concurrent non-atomic operations.\n            // cfg guarantees that the CPU supports CMPXCHG16B.\n            //\n            // See cmpxchg16b function for more.\n            unsafe {\n                // cmpxchg16b is always SeqCst.\n                let (mut prev_lo, mut prev_hi);\n                macro_rules! cmpxchg16b {\n                    ($dst:tt, $save:tt) => {\n                        asm!(\n                            concat!(\"mov \", $save, \", rbx\"), // save rbx which is reserved by LLVM\n                            // This is not single-copy atomic reads, but this is ok because subsequent\n                            // CAS will check for consistency.\n                            //\n                            // This is based on the code generated for the first load in DW RMWs by LLVM.\n                            //\n                            // Note that the C++20 memory model does not allow mixed-sized atomic access,\n                            // so we must use inline assembly to implement this.\n                            // (i.e., byte-wise atomic based on the standard library's atomic types\n                            // cannot be used here).\n                            concat!(\"mov rax, qword ptr [\", $dst, \"]\"),\n                            concat!(\"mov rdx, qword ptr [\", $dst, \" + 8]\"),\n                            \"2:\",\n                                $($op)*\n                                concat!(\"lock cmpxchg16b xmmword ptr [\", $dst, \"]\"),\n                                \"jne 2b\",\n                            concat!(\"mov rbx, \", $save), // restore rbx\n                            out($save) _,\n                            out(\"rcx\") _,\n                            out(\"rax\") prev_lo,\n                            out(\"rdx\") prev_hi,\n                            in($dst) dst,\n                            // Do not use `preserves_flags` because CMPXCHG16B modifies the ZF flag.\n                            options(nostack),\n                        )\n                    };\n                }\n                // rdi and rsi are call-preserved on Windows.\n                #[cfg(not(windows))]\n                #[cfg(target_pointer_width = \"32\")]\n                cmpxchg16b!(\"edi\", \"rsi\");\n                #[cfg(not(windows))]\n                #[cfg(target_pointer_width = \"64\")]\n                cmpxchg16b!(\"rdi\", \"rsi\");\n                #[cfg(windows)]\n                #[cfg(target_pointer_width = \"32\")]\n                cmpxchg16b!(\"r9d\", \"r8\");\n                #[cfg(windows)]\n                #[cfg(target_pointer_width = \"64\")]\n                cmpxchg16b!(\"r9\", \"r8\");\n                U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole\n            }\n        }\n    };\n}\n\natomic_rmw_cas_3! {\n    atomic_add_cmpxchg16b,\n    \"mov rbx, rax\",\n    \"add rbx, r8\",\n    \"mov rcx, rdx\",\n    \"adc rcx, r9\",\n}\natomic_rmw_cas_3! {\n    atomic_sub_cmpxchg16b,\n    \"mov rbx, rax\",\n    \"sub rbx, r8\",\n    \"mov rcx, rdx\",\n    \"sbb rcx, r9\",\n}\natomic_rmw_cas_3! {\n    atomic_and_cmpxchg16b,\n    \"mov rbx, rax\",\n    \"and rbx, r8\",\n    \"mov rcx, rdx\",\n    \"and rcx, r9\",\n}\natomic_rmw_cas_3! {\n    atomic_nand_cmpxchg16b,\n    \"mov rbx, rax\",\n    \"and rbx, r8\",\n    \"not rbx\",\n    \"mov rcx, rdx\",\n    \"and rcx, r9\",\n    \"not rcx\",\n}\natomic_rmw_cas_3! {\n    atomic_or_cmpxchg16b,\n    \"mov rbx, rax\",\n    \"or rbx, r8\",\n    \"mov rcx, rdx\",\n    \"or rcx, r9\",\n}\natomic_rmw_cas_3! {\n    atomic_xor_cmpxchg16b,\n    \"mov rbx, rax\",\n    \"xor rbx, r8\",\n    \"mov rcx, rdx\",\n    \"xor rcx, r9\",\n}\n\natomic_rmw_cas_2! {\n    atomic_not_cmpxchg16b,\n    \"mov rbx, rax\",\n    \"not rbx\",\n    \"mov rcx, rdx\",\n    \"not rcx\",\n}\natomic_rmw_cas_2! {\n    atomic_neg_cmpxchg16b,\n    \"mov rbx, rax\",\n    \"neg rbx\",\n    \"mov rcx, 0\",\n    \"sbb rcx, rdx\",\n}\n\natomic_rmw_cas_3! {\n    atomic_max_cmpxchg16b,\n    \"cmp r8, rax\",\n    \"mov rcx, r9\",\n    \"sbb rcx, rdx\",\n    \"mov rcx, r9\",\n    \"cmovl rcx, rdx\",\n    \"mov rbx, r8\",\n    \"cmovl rbx, rax\",\n}\natomic_rmw_cas_3! {\n    atomic_umax_cmpxchg16b,\n    \"cmp r8, rax\",\n    \"mov rcx, r9\",\n    \"sbb rcx, rdx\",\n    \"mov rcx, r9\",\n    \"cmovb rcx, rdx\",\n    \"mov rbx, r8\",\n    \"cmovb rbx, rax\",\n}\natomic_rmw_cas_3! {\n    atomic_min_cmpxchg16b,\n    \"cmp r8, rax\",\n    \"mov rcx, r9\",\n    \"sbb rcx, rdx\",\n    \"mov rcx, r9\",\n    \"cmovge rcx, rdx\",\n    \"mov rbx, r8\",\n    \"cmovge rbx, rax\",\n}\natomic_rmw_cas_3! {\n    atomic_umin_cmpxchg16b,\n    \"cmp r8, rax\",\n    \"mov rcx, r9\",\n    \"sbb rcx, rdx\",\n    \"mov rcx, r9\",\n    \"cmovae rcx, rdx\",\n    \"mov rbx, r8\",\n    \"cmovae rbx, rax\",\n}\n\nmacro_rules! select_atomic_rmw {\n    (\n        unsafe fn $name:ident($($arg:tt)*) $(-> $ret_ty:ty)?;\n        cmpxchg16b = $cmpxchg16b_fn:ident;\n        fallback = $seqcst_fallback_fn:ident;\n    ) => {\n        // If cmpxchg16b is available at compile-time, we can always use cmpxchg16b_fn.\n        #[cfg(any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"))]\n        use self::$cmpxchg16b_fn as $name;\n        // Otherwise, we need to do run-time detection and can use cmpxchg16b_fn only if cmpxchg16b is available.\n        #[cfg(not(any(\n            target_feature = \"cmpxchg16b\",\n            portable_atomic_target_feature = \"cmpxchg16b\",\n        )))]\n        #[inline]\n        unsafe fn $name($($arg)*, _order: Ordering) $(-> $ret_ty)? {\n            fn_alias! {\n                // See cmpxchg16b() for target_feature(enable).\n                #[cfg_attr(\n                    not(portable_atomic_no_cmpxchg16b_target_feature),\n                    target_feature(enable = \"cmpxchg16b\")\n                )]\n                unsafe fn($($arg)*) $(-> $ret_ty)?;\n                // cmpxchg16b is always SeqCst.\n                cmpxchg16b_seqcst_fn = $cmpxchg16b_fn(Ordering::SeqCst);\n            }\n            // SAFETY: the caller must uphold the safety contract.\n            // we only calls cmpxchg16b_fn if cmpxchg16b is available.\n            unsafe {\n                ifunc!(unsafe fn($($arg)*) $(-> $ret_ty)? {\n                    if detect::detect().cmpxchg16b() {\n                        cmpxchg16b_seqcst_fn\n                    } else {\n                        // Use SeqCst because cmpxchg16b is always SeqCst.\n                        fallback::$seqcst_fallback_fn\n                    }\n                })\n            }\n        }\n    };\n}\n\nselect_atomic_rmw! {\n    unsafe fn atomic_swap(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_swap_cmpxchg16b;\n    fallback = atomic_swap_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_add(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_add_cmpxchg16b;\n    fallback = atomic_add_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_sub(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_sub_cmpxchg16b;\n    fallback = atomic_sub_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_and(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_and_cmpxchg16b;\n    fallback = atomic_and_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_nand(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_nand_cmpxchg16b;\n    fallback = atomic_nand_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_or(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_or_cmpxchg16b;\n    fallback = atomic_or_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_xor(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_xor_cmpxchg16b;\n    fallback = atomic_xor_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_max(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_max_cmpxchg16b;\n    fallback = atomic_max_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_umax(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_umax_cmpxchg16b;\n    fallback = atomic_umax_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_min(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_min_cmpxchg16b;\n    fallback = atomic_min_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_umin(dst: *mut u128, val: u128) -> u128;\n    cmpxchg16b = atomic_umin_cmpxchg16b;\n    fallback = atomic_umin_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_not(dst: *mut u128) -> u128;\n    cmpxchg16b = atomic_not_cmpxchg16b;\n    fallback = atomic_not_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_neg(dst: *mut u128) -> u128;\n    cmpxchg16b = atomic_neg_cmpxchg16b;\n    fallback = atomic_neg_seqcst;\n}\n\n#[inline]\nfn is_lock_free() -> bool {\n    #[cfg(any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"))]\n    {\n        // CMPXCHG16B is available at compile-time.\n        true\n    }\n    #[cfg(not(any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\")))]\n    {\n        detect::detect().cmpxchg16b()\n    }\n}\nconst IS_ALWAYS_LOCK_FREE: bool =\n    cfg!(any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"));\n\natomic128!(AtomicI128, i128, atomic_max, atomic_min);\natomic128!(AtomicU128, u128, atomic_umax, atomic_umin);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    test_atomic_int!(i128);\n    test_atomic_int!(u128);\n\n    // load/store/swap implementation is not affected by signedness, so it is\n    // enough to test only unsigned types.\n    stress_test!(u128);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic64/arm_linux.rs",
      "sha256": "e4857c2c7240b73a3e3c9bb092b1251d9b71a44617cc43345ffd14bf11ee5f65",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\n64-bit atomic implementation using kuser_cmpxchg64 on pre-v6 Arm Linux/Android.\n\nSee \"Atomic operation overview by architecture\" in atomic-maybe-uninit for a more comprehensive and\ndetailed description of the atomic and synchronize instructions in this architecture:\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#arm\n\nRefs:\n- https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm/kernel_user_helpers.rst\n- https://github.com/rust-lang/compiler-builtins/blob/compiler_builtins-v0.1.124/src/arm_linux.rs\n- https://github.com/taiki-e/atomic-maybe-uninit\n\nNote: __kuser_cmpxchg64 is always SeqCst.\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/v0.3.21/src/arch/arm.rs#L230\n\nNote: On Miri and ThreadSanitizer which do not support inline assembly, we don't use\nthis module and use fallback implementation instead.\n*/\n\n// TODO: Since Rust 1.64, the Linux kernel requirement for Rust when using std is 3.2+, so it should\n// be possible to omit the dynamic kernel version check if the std feature is enabled on Rust 1.64+.\n// https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements\n\ninclude!(\"macros.rs\");\n\n#[path = \"../fallback/outline_atomics.rs\"]\nmod fallback;\n\n#[cfg(test)] // test-only (unused)\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(\n    all(\n        target_os = \"linux\",\n        any(\n            target_env = \"gnu\",\n            target_env = \"musl\",\n            target_env = \"ohos\",\n            all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n        ),\n    ),\n    target_os = \"android\",\n    target_os = \"freebsd\",\n    target_os = \"openbsd\",\n))]\n#[path = \"../detect/auxv.rs\"]\nmod test_detect_auxv;\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\nuse core::{mem, sync::atomic::Ordering};\n\n#[cfg(portable_atomic_no_strict_provenance)]\nuse crate::utils::ptr::PtrExt as _;\nuse crate::utils::{Pair, U64};\n\n// https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm/kernel_user_helpers.rst\nconst KUSER_HELPER_VERSION: usize = 0xFFFF0FFC;\n// __kuser_helper_version >= 5 (kernel version 3.1+)\nconst KUSER_CMPXCHG64: usize = 0xFFFF0F60;\n#[inline]\nfn __kuser_helper_version() -> i32 {\n    // SAFETY: core assumes that at least __kuser_memory_barrier (__kuser_helper_version >= 3) is\n    // available on this platform. __kuser_helper_version is always available on such a platform.\n    unsafe { crate::utils::ptr::with_exposed_provenance::<i32>(KUSER_HELPER_VERSION).read() }\n}\n#[inline]\nfn has_kuser_cmpxchg64() -> bool {\n    // Note: detect_false cfg is intended to make it easy for developers to test\n    // cases where features usually available is not available, and is not a public API.\n    if cfg!(portable_atomic_test_detect_false) {\n        return false;\n    }\n    __kuser_helper_version() >= 5\n}\n#[inline]\nunsafe fn __kuser_cmpxchg64(old_val: *const u64, new_val: *const u64, ptr: *mut u64) -> bool {\n    // SAFETY: kernel docs specify a known address with the given signature.\n    // And the caller must guarantee that the pointer is valid for read and write,\n    // aligned to the element size, and __kuser_helper_version >= 5.\n    unsafe {\n        let f: extern \"C\" fn(*const u64, *const u64, *mut u64) -> u32 =\n            mem::transmute(crate::utils::ptr::with_exposed_provenance::<()>(KUSER_CMPXCHG64));\n        f(old_val, new_val, ptr) == 0\n    }\n}\n\n// 64-bit atomic load by two 32-bit atomic loads.\n#[inline]\nunsafe fn byte_wise_atomic_load(src: *const u64) -> u64 {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        let (out_lo, out_hi);\n        asm!(\n            \"ldr {out_lo}, [{src}]\",     // atomic { out_lo = *src }\n            \"ldr {out_hi}, [{src}, #4]\", // atomic { out_hi = *src.byte_add(4) }\n            src = in(reg) src,\n            out_lo = out(reg) out_lo,\n            out_hi = out(reg) out_hi,\n            options(pure, nostack, preserves_flags, readonly),\n        );\n        U64 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n    }\n}\n\nmacro_rules! select_atomic {\n    (\n        unsafe fn $name:ident($dst:ident: *mut u64 $(, $($arg:tt)*)?) $(-> $ret_ty:ty)? {\n            |$kuser_cmpxchg64_fn_binding:ident| $($kuser_cmpxchg64_fn_body:tt)*\n        }\n        fallback = $seqcst_fallback_fn:ident\n    ) => {\n        #[inline]\n        unsafe fn $name($dst: *mut u64 $(, $($arg)*)?, _: Ordering) $(-> $ret_ty)? {\n            unsafe fn kuser_cmpxchg64_fn($dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? {\n                debug_assert!($dst.addr() % 8 == 0);\n                debug_assert!(has_kuser_cmpxchg64());\n                // SAFETY: the caller must uphold the safety contract.\n                unsafe {\n                    loop {\n                        // This is not single-copy atomic reads, but this is ok because subsequent\n                        // CAS will check for consistency.\n                        //\n                        // Arm's memory model allow mixed-sized atomic access.\n                        // https://github.com/rust-lang/unsafe-code-guidelines/issues/345#issuecomment-1172891466\n                        //\n                        // Note that the C++20 memory model does not allow mixed-sized atomic access,\n                        // so we must use inline assembly to implement byte_wise_atomic_load.\n                        // (i.e., byte-wise atomic based on the standard library's atomic types\n                        // cannot be used here).\n                        let prev = byte_wise_atomic_load($dst);\n                        let next = {\n                            let $kuser_cmpxchg64_fn_binding = prev;\n                            $($kuser_cmpxchg64_fn_body)*\n                        };\n                        if __kuser_cmpxchg64(&prev, &next, $dst) {\n                            return prev;\n                        }\n                    }\n                }\n            }\n            // SAFETY: the caller must uphold the safety contract.\n            // we only calls __kuser_cmpxchg64 if it is available.\n            unsafe {\n                ifunc!(unsafe fn($dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? {\n                    if has_kuser_cmpxchg64() {\n                        kuser_cmpxchg64_fn\n                    } else {\n                        // Use SeqCst because __kuser_cmpxchg64 is always SeqCst.\n                        fallback::$seqcst_fallback_fn\n                    }\n                })\n            }\n        }\n    };\n}\n\nselect_atomic! {\n    unsafe fn atomic_load(src: *mut u64) -> u64 {\n        |old| old\n    }\n    fallback = atomic_load_seqcst\n}\n#[inline]\nunsafe fn atomic_store(dst: *mut u64, val: u64, order: Ordering) {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        atomic_swap(dst, val, order);\n    }\n}\nselect_atomic! {\n    unsafe fn atomic_swap(dst: *mut u64, val: u64) -> u64 {\n        |_x| val\n    }\n    fallback = atomic_swap_seqcst\n}\n#[inline]\nunsafe fn atomic_compare_exchange(\n    dst: *mut u64,\n    old: u64,\n    new: u64,\n    _: Ordering,\n    _: Ordering,\n) -> Result<u64, u64> {\n    unsafe fn kuser_cmpxchg64_fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) {\n        debug_assert!(dst.addr() % 8 == 0);\n        debug_assert!(has_kuser_cmpxchg64());\n        // SAFETY: the caller must uphold the safety contract.\n        unsafe {\n            loop {\n                // See select_atomic! for more.\n                let prev = byte_wise_atomic_load(dst);\n                let next = if prev == old { new } else { prev };\n                if __kuser_cmpxchg64(&prev, &next, dst) {\n                    return (prev, prev == old);\n                }\n            }\n        }\n    }\n    // SAFETY: the caller must uphold the safety contract.\n    // we only calls __kuser_cmpxchg64 if it is available.\n    let (prev, ok) = unsafe {\n        ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) {\n            if has_kuser_cmpxchg64() {\n                kuser_cmpxchg64_fn\n            } else {\n                // Use SeqCst because __kuser_cmpxchg64 is always SeqCst.\n                fallback::atomic_compare_exchange_seqcst\n            }\n        })\n    };\n    if ok { Ok(prev) } else { Err(prev) }\n}\nuse self::atomic_compare_exchange as atomic_compare_exchange_weak;\nselect_atomic! {\n    unsafe fn atomic_add(dst: *mut u64, val: u64) -> u64 {\n        |x| x.wrapping_add(val)\n    }\n    fallback = atomic_add_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_sub(dst: *mut u64, val: u64) -> u64 {\n        |x| x.wrapping_sub(val)\n    }\n    fallback = atomic_sub_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_and(dst: *mut u64, val: u64) -> u64 {\n        |x| x & val\n    }\n    fallback = atomic_and_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_nand(dst: *mut u64, val: u64) -> u64 {\n        |x| !(x & val)\n    }\n    fallback = atomic_nand_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_or(dst: *mut u64, val: u64) -> u64 {\n        |x| x | val\n    }\n    fallback = atomic_or_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_xor(dst: *mut u64, val: u64) -> u64 {\n        |x| x ^ val\n    }\n    fallback = atomic_xor_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_max(dst: *mut u64, val: u64) -> u64 {\n        |x| {\n            #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n            { core::cmp::max(x as i64, val as i64) as u64 }\n        }\n    }\n    fallback = atomic_max_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_umax(dst: *mut u64, val: u64) -> u64 {\n        |x| core::cmp::max(x, val)\n    }\n    fallback = atomic_umax_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_min(dst: *mut u64, val: u64) -> u64 {\n        |x| {\n            #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n            { core::cmp::min(x as i64, val as i64) as u64 }\n        }\n    }\n    fallback = atomic_min_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_umin(dst: *mut u64, val: u64) -> u64 {\n        |x| core::cmp::min(x, val)\n    }\n    fallback = atomic_umin_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_not(dst: *mut u64) -> u64 {\n        |x| !x\n    }\n    fallback = atomic_not_seqcst\n}\nselect_atomic! {\n    unsafe fn atomic_neg(dst: *mut u64) -> u64 {\n        |x| x.wrapping_neg()\n    }\n    fallback = atomic_neg_seqcst\n}\n\n#[inline]\nfn is_lock_free() -> bool {\n    has_kuser_cmpxchg64()\n}\nconst IS_ALWAYS_LOCK_FREE: bool = false;\n\natomic64!(AtomicI64, i64, atomic_max, atomic_min);\natomic64!(AtomicU64, u64, atomic_umax, atomic_umin);\n\n#[allow(\n    clippy::alloc_instead_of_core,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    clippy::undocumented_unsafe_blocks,\n    clippy::wildcard_imports\n)]\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn kuser_helper_version() {\n        let version = __kuser_helper_version();\n        assert!(version >= 5, \"{:?}\", version);\n        assert_eq!(version, unsafe {\n            crate::utils::ptr::with_exposed_provenance::<i32>(KUSER_HELPER_VERSION).read()\n        });\n    }\n\n    test_atomic_int!(i64);\n    test_atomic_int!(u64);\n\n    // load/store/swap implementation is not affected by signedness, so it is\n    // enough to test only unsigned types.\n    stress_test!(u64);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic64/macros.rs",
      "sha256": "5b6f0bfe40064885926cfd57a336f15da92f6964864c50d339d1bb9903802a9d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nmacro_rules! atomic64 {\n    ($atomic_type:ident, $int_type:ident, $atomic_max:ident, $atomic_min:ident) => {\n        #[repr(C, align(8))]\n        pub(crate) struct $atomic_type {\n            v: core::cell::UnsafeCell<$int_type>,\n        }\n\n        // Send is implicitly implemented.\n        // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock.\n        unsafe impl Sync for $atomic_type {}\n\n        impl_default_no_fetch_ops!($atomic_type, $int_type);\n        impl_default_bit_opts!($atomic_type, $int_type);\n        impl $atomic_type {\n            #[inline]\n            pub(crate) const fn new(v: $int_type) -> Self {\n                Self { v: core::cell::UnsafeCell::new(v) }\n            }\n\n            #[inline]\n            pub(crate) fn is_lock_free() -> bool {\n                is_lock_free()\n            }\n            pub(crate) const IS_ALWAYS_LOCK_FREE: bool = IS_ALWAYS_LOCK_FREE;\n\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn load(&self, order: Ordering) -> $int_type {\n                crate::utils::assert_load_ordering(order);\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_load(self.v.get().cast::<u64>(), order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn store(&self, val: $int_type, order: Ordering) {\n                crate::utils::assert_store_ordering(order);\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_store(self.v.get().cast::<u64>(), val as u64, order)\n                }\n            }\n\n            #[inline]\n            pub(crate) fn swap(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_swap(self.v.get().cast::<u64>(), val as u64, order) as $int_type\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn compare_exchange(\n                &self,\n                current: $int_type,\n                new: $int_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$int_type, $int_type> {\n                crate::utils::assert_compare_exchange_ordering(success, failure);\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    match atomic_compare_exchange(\n                        self.v.get().cast::<u64>(),\n                        current as u64,\n                        new as u64,\n                        success,\n                        failure,\n                    ) {\n                        Ok(v) => Ok(v as $int_type),\n                        Err(v) => Err(v as $int_type),\n                    }\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn compare_exchange_weak(\n                &self,\n                current: $int_type,\n                new: $int_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$int_type, $int_type> {\n                crate::utils::assert_compare_exchange_ordering(success, failure);\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    match atomic_compare_exchange_weak(\n                        self.v.get().cast::<u64>(),\n                        current as u64,\n                        new as u64,\n                        success,\n                        failure,\n                    ) {\n                        Ok(v) => Ok(v as $int_type),\n                        Err(v) => Err(v as $int_type),\n                    }\n                }\n            }\n\n            #[inline]\n            pub(crate) fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_add(self.v.get().cast::<u64>(), val as u64, order) as $int_type\n                }\n            }\n\n            #[inline]\n            pub(crate) fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_sub(self.v.get().cast::<u64>(), val as u64, order) as $int_type\n                }\n            }\n\n            #[inline]\n            pub(crate) fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_and(self.v.get().cast::<u64>(), val as u64, order) as $int_type\n                }\n            }\n\n            #[inline]\n            pub(crate) fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_nand(self.v.get().cast::<u64>(), val as u64, order) as $int_type\n                }\n            }\n\n            #[inline]\n            pub(crate) fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_or(self.v.get().cast::<u64>(), val as u64, order) as $int_type\n                }\n            }\n\n            #[inline]\n            pub(crate) fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_xor(self.v.get().cast::<u64>(), val as u64, order) as $int_type\n                }\n            }\n\n            #[inline]\n            pub(crate) fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    $atomic_max(self.v.get().cast::<u64>(), val as u64, order) as $int_type\n                }\n            }\n\n            #[inline]\n            pub(crate) fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    $atomic_min(self.v.get().cast::<u64>(), val as u64, order) as $int_type\n                }\n            }\n\n            #[inline]\n            pub(crate) fn fetch_not(&self, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_not(self.v.get().cast::<u64>(), order) as $int_type\n                }\n            }\n            #[inline]\n            pub(crate) fn not(&self, order: Ordering) {\n                self.fetch_not(order);\n            }\n\n            #[inline]\n            pub(crate) fn fetch_neg(&self, order: Ordering) -> $int_type {\n                #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n                // SAFETY: any data races are prevented by atomic intrinsics, the kernel user helper, or the lock\n                // and the raw pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    atomic_neg(self.v.get().cast::<u64>(), order) as $int_type\n                }\n            }\n            #[inline]\n            pub(crate) fn neg(&self, order: Ordering) {\n                self.fetch_neg(order);\n            }\n\n            #[inline]\n            pub(crate) const fn as_ptr(&self) -> *mut $int_type {\n                self.v.get()\n            }\n        }\n    };\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic64/mod.rs",
      "sha256": "2977468d184134a068179eb8361d73500865b8d1476b87590099d6b503db30e5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\n64-bit atomic implementations on 32-bit architectures\n\nSee README.md for details.\n*/\n\n// pre-v6 Arm Linux\n// Miri and Sanitizer do not support inline assembly.\n#[cfg(all(\n    feature = \"fallback\",\n    target_arch = \"arm\",\n    not(any(miri, portable_atomic_sanitize_thread)),\n    any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n    any(target_os = \"linux\", target_os = \"android\"),\n    any(test, not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\"))),\n    not(portable_atomic_no_outline_atomics),\n))]\n#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(any(test, portable_atomic_no_atomic_64)))]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(test, not(target_has_atomic = \"64\")))\n)]\npub(super) mod arm_linux;\n\n// riscv32\n// Miri and Sanitizer do not support inline assembly.\n#[cfg(all(\n    target_arch = \"riscv32\",\n    not(any(miri, portable_atomic_sanitize_thread)),\n    any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n    any(\n        target_feature = \"zacas\",\n        portable_atomic_target_feature = \"zacas\",\n        all(\n            feature = \"fallback\",\n            not(portable_atomic_no_outline_atomics),\n            any(target_os = \"linux\", target_os = \"android\"),\n        ),\n    ),\n))]\npub(super) mod riscv32;\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/atomic64/riscv32.rs",
      "sha256": "c8e00a15c0524fc94b0df7946fcd84b6779eb01bfe48f06bf6f4f84039c00337",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\n64-bit atomic implementation on riscv32.\n\nThis architecture provides the following 64-bit atomic instructions:\n\n- amocas.d: CAS (Zacas extension)\n\nSee \"Atomic operation overview by architecture\" in atomic-maybe-uninit for a more comprehensive and\ndetailed description of the atomic and synchronize instructions in this architecture:\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#risc-v\n\nNote: On Miri and ThreadSanitizer which do not support inline assembly, we don't use\nthis module and use fallback implementation instead.\n\nRefs:\n- RISC-V Instruction Set Manual\n  \"Zacas\" Extension for Atomic Compare-and-Swap (CAS) Instructions\n  https://docs.riscv.org/reference/isa/v20260120/unpriv/zacas.html\n- RISC-V Atomics ABI Specification\n  https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20250812-301374e92976e298e676e7129a6212926b2299ce/riscv-atomic.adoc\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\n// TODO: merge duplicated code with atomic128/riscv64.rs\n\ninclude!(\"macros.rs\");\n\n#[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n#[path = \"../fallback/outline_atomics.rs\"]\nmod fallback;\n\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(test, not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"))))]\n#[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n#[path = \"../detect/riscv_linux.rs\"]\nmod detect;\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\nuse core::sync::atomic::Ordering;\n\n#[cfg(portable_atomic_no_strict_provenance)]\nuse crate::utils::ptr::PtrExt as _;\nuse crate::utils::{Pair, U64};\n\nmacro_rules! debug_assert_zacas {\n    () => {\n        #[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n        {\n            debug_assert!(detect::detect().zacas());\n        }\n    };\n}\n\n// `.option arch, +zacas` directive requires LLVM 20, so we use .4byte directive for old LLVM.\n// Note that `.insn <value>` directive requires LLVM 19.\n// https://github.com/llvm/llvm-project/commit/2a086dce691e3cc34a2fc27f4fb255bb2cbbfac9\n// https://github.com/riscv-non-isa/riscv-asm-manual/blob/v0.0.1/src/asm-manual.adoc#arch\n#[cfg(not(portable_atomic_pre_llvm_20))]\nmacro_rules! start_zacas {\n    () => {\n        \".option push\\n.option arch, +zacas\"\n    };\n}\n#[cfg(not(portable_atomic_pre_llvm_20))]\nmacro_rules! end_zacas {\n    () => {\n        \".option pop\"\n    };\n}\n\n#[cfg(not(portable_atomic_pre_llvm_20))]\nmacro_rules! atomic_rmw_amocas_order {\n    ($op:ident, $order:ident) => {\n        atomic_rmw_amocas_order!($op, $order, failure = $order)\n    };\n    ($op:ident, $order:ident, failure = $failure:ident) => {\n        match $order {\n            Ordering::Relaxed => $op!(\"\", \"\"),\n            Ordering::Acquire => $op!(\"\", \".aq\"),\n            Ordering::Release => $op!(\"\", \".rl\"),\n            Ordering::AcqRel => $op!(\"\", \".aqrl\"),\n            Ordering::SeqCst if $failure == Ordering::SeqCst => $op!(\"fence rw,rw\", \".aqrl\"),\n            Ordering::SeqCst => $op!(\"\", \".aqrl\"),\n            _ => unreachable!(),\n        }\n    };\n}\n#[cfg(portable_atomic_pre_llvm_20)]\nmacro_rules! atomic_rmw_amocas_order_insn {\n    ($op:ident, $order:ident) => {\n        atomic_rmw_amocas_order_insn!($op, $order, failure = $order)\n    };\n    ($op:ident, $order:ident, failure = $failure:ident) => {\n        match $order {\n            Ordering::Relaxed => $op!(\"\", \"8\"),\n            Ordering::Acquire => $op!(\"\", \"c\"),\n            Ordering::Release => $op!(\"\", \"a\"),\n            Ordering::AcqRel => $op!(\"\", \"e\"),\n            Ordering::SeqCst if $failure == Ordering::SeqCst => $op!(\"fence rw,rw\", \"e\"),\n            Ordering::SeqCst => $op!(\"\", \"e\"),\n            _ => unreachable!(),\n        }\n    };\n}\n\n// If zacas is available at compile-time, we can always use zacas_fn.\n#[cfg(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"))]\nuse self::atomic_load_zacas as atomic_load;\n// Otherwise, we need to do run-time detection and can use zacas_fn only if zacas is available.\n#[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n#[inline]\nunsafe fn atomic_load(src: *mut u64, order: Ordering) -> u64 {\n    fn_alias! {\n        // inline(never) is just a hint and also not strictly necessary\n        // because we use ifunc helper macro, but used for clarity.\n        #[inline(never)]\n        unsafe fn(src: *mut u64) -> u64;\n        atomic_load_zacas_relaxed = atomic_load_zacas(Ordering::Relaxed);\n        atomic_load_zacas_acquire = atomic_load_zacas(Ordering::Acquire);\n        atomic_load_zacas_seqcst = atomic_load_zacas(Ordering::SeqCst);\n    }\n    // SAFETY: the caller must uphold the safety contract.\n    // we only calls atomic_load_zacas if zacas is available.\n    unsafe {\n        match order {\n            Ordering::Relaxed => {\n                ifunc!(unsafe fn(src: *mut u64) -> u64 {\n                    if detect::detect().zacas() {\n                        atomic_load_zacas_relaxed\n                    } else {\n                        fallback::atomic_load_non_seqcst\n                    }\n                })\n            }\n            Ordering::Acquire => {\n                ifunc!(unsafe fn(src: *mut u64) -> u64 {\n                    if detect::detect().zacas() {\n                        atomic_load_zacas_acquire\n                    } else {\n                        fallback::atomic_load_non_seqcst\n                    }\n                })\n            }\n            Ordering::SeqCst => {\n                ifunc!(unsafe fn(src: *mut u64) -> u64 {\n                    if detect::detect().zacas() {\n                        atomic_load_zacas_seqcst\n                    } else {\n                        fallback::atomic_load_seqcst\n                    }\n                })\n            }\n            _ => unreachable!(),\n        }\n    }\n}\n#[inline]\nunsafe fn atomic_load_zacas(src: *mut u64, order: Ordering) -> u64 {\n    debug_assert!(src.addr() % 8 == 0);\n    debug_assert_zacas!();\n    let (out_lo, out_hi);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        #[cfg(not(portable_atomic_pre_llvm_20))]\n        macro_rules! load {\n            ($fence:tt, $asm_order:tt) => {\n                asm!(\n                    start_zacas!(),\n                    $fence,                                               // fence\n                    concat!(\"amocas.d\", $asm_order, \" a2, a2, 0({src})\"), // atomic { if *dst == a2:a3 { *dst = a2:a3 } else { a2:a3 = *dst } }\n                    end_zacas!(),\n                    src = in(reg) ptr_reg!(src),\n                    inout(\"a2\") 0_u32 => out_lo,\n                    inout(\"a3\") 0_u32 => out_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(not(portable_atomic_pre_llvm_20))]\n        atomic_rmw_amocas_order!(load, order);\n        #[cfg(portable_atomic_pre_llvm_20)]\n        macro_rules! load {\n            ($fence:tt, $insn_order:tt) => {\n                asm!(\n                    $fence,                                  // fence\n                    // amocas.d{,.aq,.rl,.aqrl} a2, a2, (a0) // atomic { if *a0 == a2:a3 { *a0 = a2:a3 } else { a2:a3 = *a0 } }\n                    concat!(\".4byte 0x2\", $insn_order, \"c5362f\"),\n                    in(\"a0\") ptr_reg!(src),\n                    inout(\"a2\") 0_u32 => out_lo,\n                    inout(\"a3\") 0_u32 => out_hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(portable_atomic_pre_llvm_20)]\n        atomic_rmw_amocas_order_insn!(load, order);\n        U64 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n    }\n}\n\n#[inline]\nunsafe fn atomic_store(dst: *mut u64, val: u64, order: Ordering) {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        atomic_swap(dst, val, order);\n    }\n}\n\n#[inline]\nunsafe fn atomic_compare_exchange(\n    dst: *mut u64,\n    old: u64,\n    new: u64,\n    success: Ordering,\n    failure: Ordering,\n) -> Result<u64, u64> {\n    #[cfg(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"))]\n    // SAFETY: the caller must uphold the safety contract.\n    // cfg guarantees that zacas instructions are available at compile-time.\n    let (prev, ok) = unsafe { atomic_compare_exchange_zacas(dst, old, new, success, failure) };\n    #[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n    let (prev, ok) = {\n        fn_alias! {\n            // inline(never) is just a hint and also not strictly necessary\n            // because we use ifunc helper macro, but used for clarity.\n            #[inline(never)]\n            unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool);\n            zacas_relaxed_fn = atomic_compare_exchange_zacas(Ordering::Relaxed, Ordering::Relaxed);\n            zacas_acquire_fn = atomic_compare_exchange_zacas(Ordering::Acquire, Ordering::Acquire);\n            zacas_release_fn = atomic_compare_exchange_zacas(Ordering::Release, Ordering::Relaxed);\n            zacas_acqrel_fn = atomic_compare_exchange_zacas(Ordering::AcqRel, Ordering::Acquire);\n            zacas_seqcst_fn = atomic_compare_exchange_zacas(Ordering::SeqCst, Ordering::SeqCst);\n        }\n        let order = crate::utils::upgrade_success_ordering(success, failure);\n        // SAFETY: the caller must uphold the safety contract.\n        // we only calls atomic_compare_exchange_zacas if zacas is available.\n        unsafe {\n            match order {\n                Ordering::Relaxed => {\n                    ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) {\n                        if detect::detect().zacas() {\n                            zacas_relaxed_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::Acquire => {\n                    ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) {\n                        if detect::detect().zacas() {\n                            zacas_acquire_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::Release => {\n                    ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) {\n                        if detect::detect().zacas() {\n                            zacas_release_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::AcqRel => {\n                    ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) {\n                        if detect::detect().zacas() {\n                            zacas_acqrel_fn\n                        } else {\n                            fallback::atomic_compare_exchange_non_seqcst\n                        }\n                    })\n                }\n                Ordering::SeqCst => {\n                    ifunc!(unsafe fn(dst: *mut u64, old: u64, new: u64) -> (u64, bool) {\n                        if detect::detect().zacas() {\n                            zacas_seqcst_fn\n                        } else {\n                            fallback::atomic_compare_exchange_seqcst\n                        }\n                    })\n                }\n                _ => unreachable!(),\n            }\n        }\n    };\n    if ok { Ok(prev) } else { Err(prev) }\n}\n#[inline]\nunsafe fn atomic_compare_exchange_zacas(\n    dst: *mut u64,\n    old: u64,\n    new: u64,\n    success: Ordering,\n    failure: Ordering,\n) -> (u64, bool) {\n    debug_assert!(dst.addr() % 8 == 0);\n    debug_assert_zacas!();\n    let order = crate::utils::upgrade_success_ordering(success, failure);\n    let old = U64 { whole: old };\n    let new = U64 { whole: new };\n    let (prev_lo, prev_hi);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        #[cfg(not(portable_atomic_pre_llvm_20))]\n        macro_rules! cmpxchg {\n            ($fence:tt, $asm_order:tt) => {\n                asm!(\n                    start_zacas!(),\n                    $fence,                                               // fence\n                    concat!(\"amocas.d\", $asm_order, \" a4, a2, 0({dst})\"), // atomic { if *dst == a4:a5 { *dst = a2:a3 } else { a4:a5 = *dst } }\n                    end_zacas!(),\n                    dst = in(reg) ptr_reg!(dst),\n                    // must be allocated to even/odd register pair\n                    inout(\"a4\") old.pair.lo => prev_lo,\n                    inout(\"a5\") old.pair.hi => prev_hi,\n                    // must be allocated to even/odd register pair\n                    in(\"a2\") new.pair.lo,\n                    in(\"a3\") new.pair.hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(not(portable_atomic_pre_llvm_20))]\n        atomic_rmw_amocas_order!(cmpxchg, order, failure = failure);\n        #[cfg(portable_atomic_pre_llvm_20)]\n        macro_rules! cmpxchg {\n            ($fence:tt, $insn_order:tt) => {\n                asm!(\n                    $fence,                                  // fence\n                    // amocas.d{,.aq,.rl,.aqrl} a4, a2, (a0) // atomic { if *a0 == a4:a5 { *a0 = a2:a3 } else { a4:a5 = *a0 } }\n                    concat!(\".4byte 0x2\", $insn_order, \"c5372f\"),\n                    in(\"a0\") ptr_reg!(dst),\n                    // must be allocated to even/odd register pair\n                    inout(\"a4\") old.pair.lo => prev_lo,\n                    inout(\"a5\") old.pair.hi => prev_hi,\n                    // must be allocated to even/odd register pair\n                    in(\"a2\") new.pair.lo,\n                    in(\"a3\") new.pair.hi,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(portable_atomic_pre_llvm_20)]\n        atomic_rmw_amocas_order_insn!(cmpxchg, order, failure = failure);\n        let prev = U64 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole;\n        (prev, prev == old.whole)\n    }\n}\n\n// amocas is always strong.\nuse self::atomic_compare_exchange as atomic_compare_exchange_weak;\n\n// 64-bit atomic load by two 32-bit atomic loads.\n#[inline]\nunsafe fn byte_wise_atomic_load(src: *const u64) -> u64 {\n    let (out_lo, out_hi);\n\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        asm!(\n            \"lw {out_lo}, ({src})\",  // atomic { out_lo = *src }\n            \"lw {out_hi}, 4({src})\", // atomic { out_hi = *src.byte_add(4) }\n            src = in(reg) ptr_reg!(src),\n            out_lo = out(reg) out_lo,\n            out_hi = out(reg) out_hi,\n            options(pure, nostack, preserves_flags, readonly),\n        );\n        U64 { pair: Pair { lo: out_lo, hi: out_hi } }.whole\n    }\n}\n\nmacro_rules! select_atomic_rmw {\n    (\n        unsafe fn $name:ident(dst: *mut u64 $(, $($arg:tt)*)?) $(-> $ret_ty:ty)? {\n            |$zacas_fn_binding:ident| $($zacas_fn_body:tt)*\n        }\n        zacas = $zacas_fn:ident;\n        non_seqcst_fallback = $non_seqcst_fallback_fn:ident;\n        seqcst_fallback = $seqcst_fallback_fn:ident;\n    ) => {\n        #[inline]\n        unsafe fn $zacas_fn(dst: *mut u64 $(, $($arg)*)?, order: Ordering) $(-> $ret_ty)? {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                // This is not single-copy atomic reads, but this is ok because subsequent\n                // CAS will check for consistency.\n                //\n                // Note that the C++20 memory model does not allow mixed-sized atomic access,\n                // so we must use inline assembly to implement byte_wise_atomic_load.\n                // (i.e., byte-wise atomic based on the standard library's atomic types\n                // cannot be used here).\n                let mut prev = byte_wise_atomic_load(dst);\n                loop {\n                    let next = {\n                        let $zacas_fn_binding = prev;\n                        $($zacas_fn_body)*\n                    };\n                    match atomic_compare_exchange_weak(dst, prev, next, order, Ordering::Relaxed) {\n                        Ok(x) => return x,\n                        Err(x) => prev = x,\n                    }\n                }\n            }\n        }\n        // If zacas is available at compile-time, we can always use zacas_fn.\n        #[cfg(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"))]\n        use self::$zacas_fn as $name;\n        // Otherwise, we need to do run-time detection and can use zacas_fn only if zacas is available.\n        #[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n        #[inline]\n        unsafe fn $name(dst: *mut u64 $(, $($arg)*)?, order: Ordering) $(-> $ret_ty)? {\n            fn_alias! {\n                // inline(never) is just a hint and also not strictly necessary\n                // because we use ifunc helper macro, but used for clarity.\n                #[inline(never)]\n                unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)?;\n                zacas_relaxed_fn = $zacas_fn(Ordering::Relaxed);\n                zacas_acquire_fn = $zacas_fn(Ordering::Acquire);\n                zacas_release_fn = $zacas_fn(Ordering::Release);\n                zacas_acqrel_fn = $zacas_fn(Ordering::AcqRel);\n                zacas_seqcst_fn = $zacas_fn(Ordering::SeqCst);\n            }\n            // SAFETY: the caller must uphold the safety contract.\n            // we only calls zacas_fn if zacas is available.\n            unsafe {\n                match order {\n                    Ordering::Relaxed => {\n                        ifunc!(unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? {\n                            if detect::detect().zacas() {\n                                zacas_relaxed_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::Acquire => {\n                        ifunc!(unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? {\n                            if detect::detect().zacas() {\n                                zacas_acquire_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::Release => {\n                        ifunc!(unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? {\n                            if detect::detect().zacas() {\n                                zacas_release_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::AcqRel => {\n                        ifunc!(unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? {\n                            if detect::detect().zacas() {\n                                zacas_acqrel_fn\n                            } else {\n                                fallback::$non_seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    Ordering::SeqCst => {\n                        ifunc!(unsafe fn(dst: *mut u64 $(, $($arg)*)?) $(-> $ret_ty)? {\n                            if detect::detect().zacas() {\n                                zacas_seqcst_fn\n                            } else {\n                                fallback::$seqcst_fallback_fn\n                            }\n                        })\n                    }\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\nselect_atomic_rmw! {\n    unsafe fn atomic_swap(dst: *mut u64, val: u64) -> u64 {\n        |_x| val\n    }\n    zacas = atomic_swap_zacas;\n    non_seqcst_fallback = atomic_swap_non_seqcst;\n    seqcst_fallback = atomic_swap_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_add(dst: *mut u64, val: u64) -> u64 {\n        |x| x.wrapping_add(val)\n    }\n    zacas = atomic_add_zacas;\n    non_seqcst_fallback = atomic_add_non_seqcst;\n    seqcst_fallback = atomic_add_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_sub(dst: *mut u64, val: u64) -> u64 {\n        |x| x.wrapping_sub(val)\n    }\n    zacas = atomic_sub_zacas;\n    non_seqcst_fallback = atomic_sub_non_seqcst;\n    seqcst_fallback = atomic_sub_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_and(dst: *mut u64, val: u64) -> u64 {\n        |x| x & val\n    }\n    zacas = atomic_and_zacas;\n    non_seqcst_fallback = atomic_and_non_seqcst;\n    seqcst_fallback = atomic_and_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_nand(dst: *mut u64, val: u64) -> u64 {\n        |x| !(x & val)\n    }\n    zacas = atomic_nand_zacas;\n    non_seqcst_fallback = atomic_nand_non_seqcst;\n    seqcst_fallback = atomic_nand_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_or(dst: *mut u64, val: u64) -> u64 {\n        |x| x | val\n    }\n    zacas = atomic_or_zacas;\n    non_seqcst_fallback = atomic_or_non_seqcst;\n    seqcst_fallback = atomic_or_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_xor(dst: *mut u64, val: u64) -> u64 {\n        |x| x ^ val\n    }\n    zacas = atomic_xor_zacas;\n    non_seqcst_fallback = atomic_xor_non_seqcst;\n    seqcst_fallback = atomic_xor_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_max(dst: *mut u64, val: u64) -> u64 {\n        |x| {\n            #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n            { core::cmp::max(x as i64, val as i64) as u64 }\n        }\n    }\n    zacas = atomic_max_zacas;\n    non_seqcst_fallback = atomic_max_non_seqcst;\n    seqcst_fallback = atomic_max_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_umax(dst: *mut u64, val: u64) -> u64 {\n        |x| core::cmp::max(x, val)\n    }\n    zacas = atomic_umax_zacas;\n    non_seqcst_fallback = atomic_umax_non_seqcst;\n    seqcst_fallback = atomic_umax_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_min(dst: *mut u64, val: u64) -> u64 {\n        |x| {\n            #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]\n            { core::cmp::min(x as i64, val as i64) as u64 }\n        }\n    }\n    zacas = atomic_min_zacas;\n    non_seqcst_fallback = atomic_min_non_seqcst;\n    seqcst_fallback = atomic_min_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_umin(dst: *mut u64, val: u64) -> u64 {\n        |x| core::cmp::min(x, val)\n    }\n    zacas = atomic_umin_zacas;\n    non_seqcst_fallback = atomic_umin_non_seqcst;\n    seqcst_fallback = atomic_umin_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_not(dst: *mut u64) -> u64 {\n        |x| !x\n    }\n    zacas = atomic_not_zacas;\n    non_seqcst_fallback = atomic_not_non_seqcst;\n    seqcst_fallback = atomic_not_seqcst;\n}\nselect_atomic_rmw! {\n    unsafe fn atomic_neg(dst: *mut u64) -> u64 {\n        |x| x.wrapping_neg()\n    }\n    zacas = atomic_neg_zacas;\n    non_seqcst_fallback = atomic_neg_non_seqcst;\n    seqcst_fallback = atomic_neg_seqcst;\n}\n\n#[inline]\nfn is_lock_free() -> bool {\n    #[cfg(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"))]\n    {\n        // zacas is available at compile-time.\n        true\n    }\n    #[cfg(not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")))]\n    {\n        detect::detect().zacas()\n    }\n}\nconst IS_ALWAYS_LOCK_FREE: bool =\n    cfg!(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"));\n\natomic64!(AtomicI64, i64, atomic_max, atomic_min);\natomic64!(AtomicU64, u64, atomic_umax, atomic_umin);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    test_atomic_int!(i64);\n    test_atomic_int!(u64);\n\n    // load/store/swap implementation is not affected by signedness, so it is\n    // enough to test only unsigned types.\n    stress_test!(u64);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/avr.rs",
      "sha256": "085cdcc03d7ffb85c491f3939e0bcc3ae1e78738acadf09472f547a0b9d7c8fc",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nAtomic load/store implementation on AVR.\n\nOperations not supported here are provided by disabling interrupts.\nSee also src/imp/interrupt/avr.rs.\n\nSee \"Atomic operation overview by architecture\" in atomic-maybe-uninit for a more comprehensive and\ndetailed description of the atomic and synchronize instructions in this architecture:\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#avr\n\nNote: Ordering is always SeqCst.\n\nRefs:\n- AVR® Instruction Set Manual, Rev. DS40002198B\n  https://ww1.microchip.com/downloads/en/DeviceDoc/AVR-InstructionSet-Manual-DS40002198.pdf\n- atomic-maybe-uninit\n  https://github.com/taiki-e/atomic-maybe-uninit\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\nuse core::{arch::asm, cell::UnsafeCell, sync::atomic::Ordering};\n\nmacro_rules! atomic8 {\n    ($atomic_type:ident, $value_type:ty) => {\n        #[repr(transparent)]\n        pub(crate) struct $atomic_type {\n            v: UnsafeCell<$value_type>,\n        }\n\n        // Send is implicitly implemented for atomic integers, but not for atomic pointers.\n        // SAFETY: any data races are prevented by atomic operations.\n        unsafe impl Send for $atomic_type {}\n        // SAFETY: any data races are prevented by atomic operations.\n        unsafe impl Sync for $atomic_type {}\n\n        impl $atomic_type {\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn load(&self, order: Ordering) -> $value_type {\n                crate::utils::assert_load_ordering(order);\n                let src = self.v.get();\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    let out;\n                    asm!(\n                        \"ld {out}, Z\", // atomic { out = *Z }\n                        out = out(reg) out,\n                        in(\"Z\") src,\n                        options(nostack, preserves_flags),\n                    );\n                    out\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn store(&self, val: $value_type, order: Ordering) {\n                crate::utils::assert_store_ordering(order);\n                let dst = self.v.get();\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    asm!(\n                        \"st Z, {val}\", // atomic { *Z = val }\n                        val = in(reg) val,\n                        in(\"Z\") dst,\n                        options(nostack, preserves_flags),\n                    );\n                }\n            }\n        }\n\n        #[cfg(any(target_feature = \"rmw\", portable_atomic_target_feature = \"rmw\"))]\n        impl $atomic_type {\n            #[inline]\n            pub(crate) fn swap(&self, val: $value_type, _order: Ordering) -> $value_type {\n                let dst = self.v.get();\n                let out;\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                // cfg guarantee that the CPU supports RMW instructions.\n                unsafe {\n                    asm!(\n                        \"xch Z, {val}\", // atomic { _x = *Z; *Z = val; val = _x }\n                        val = inout(reg) val => out,\n                        in(\"Z\") dst,\n                        options(nostack, preserves_flags),\n                    );\n                }\n                out\n            }\n\n            #[inline]\n            pub(crate) fn fetch_and(&self, val: $value_type, _order: Ordering) -> $value_type {\n                let dst = self.v.get();\n                let out;\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                // cfg guarantee that the CPU supports RMW instructions.\n                unsafe {\n                    asm!(\n                        \"lac Z, {val}\", // atomic { _x = *Z; *Z &= !val; val = _x }\n                        val = inout(reg) !val => out,\n                        in(\"Z\") dst,\n                        options(nostack, preserves_flags),\n                    );\n                }\n                out\n            }\n\n            #[inline]\n            pub(crate) fn fetch_or(&self, val: $value_type, _order: Ordering) -> $value_type {\n                let dst = self.v.get();\n                let out;\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                // cfg guarantee that the CPU supports RMW instructions.\n                unsafe {\n                    asm!(\n                        \"las Z, {val}\", // atomic { _x = *Z; *Z |= val; val = _x }\n                        val = inout(reg) val => out,\n                        in(\"Z\") dst,\n                        options(nostack, preserves_flags),\n                    );\n                }\n                out\n            }\n\n            #[inline]\n            pub(crate) fn fetch_xor(&self, val: $value_type, _order: Ordering) -> $value_type {\n                let dst = self.v.get();\n                let out;\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                // cfg guarantee that the CPU supports RMW instructions.\n                unsafe {\n                    asm!(\n                        \"lat Z, {val}\", // atomic { _x = *Z; *Z ^= val; val = _x }\n                        val = inout(reg) val => out,\n                        in(\"Z\") dst,\n                        options(nostack, preserves_flags),\n                    );\n                }\n                out\n            }\n\n            #[inline]\n            pub(crate) fn fetch_not(&self, order: Ordering) -> $value_type {\n                self.fetch_xor(!0, order)\n            }\n        }\n    };\n}\n\natomic8!(AtomicI8, i8);\natomic8!(AtomicU8, u8);\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/core_atomic.rs",
      "sha256": "0ce4a6ca4fb50fd8e3c6fb2adf96535ab9b8593b951d25f16b5762ddf867b7bd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nWrap the standard library's atomic types in newtype.\n\nThis is not a reexport, because we want to backport changes like\nhttps://github.com/rust-lang/rust/pull/98383 to old compilers.\n*/\n\nuse core::{cell::UnsafeCell, marker::PhantomData, sync::atomic::Ordering};\n\n// core::panic::RefUnwindSafe is only available on Rust 1.56+, so on pre-1.56\n// Rust, we implement RefUnwindSafe when \"std\" feature is enabled.\n// However, on pre-1.56 Rust, the standard library's atomic types implement\n// RefUnwindSafe when \"linked to std\", and that's behavior that our other atomic\n// implementations can't emulate, so use PhantomData<NotRefUnwindSafe> to match\n// conditions where our other atomic implementations implement RefUnwindSafe.\n//\n// If we do not do this, for example, downstream that is only tested on x86_64\n// may incorrectly assume that AtomicU64 always implements RefUnwindSafe even on\n// older rustc, and may be broken on platforms where std AtomicU64 is not available.\nstruct NotRefUnwindSafe(UnsafeCell<()>);\n// SAFETY: this is a marker type and we'll never access the value.\nunsafe impl Sync for NotRefUnwindSafe {}\n\n#[repr(transparent)]\npub(crate) struct AtomicPtr<T> {\n    pub(super) inner: core::sync::atomic::AtomicPtr<T>,\n    // Prevent RefUnwindSafe from being propagated from the std atomic type. See NotRefUnwindSafe for more.\n    _not_ref_unwind_safe: PhantomData<NotRefUnwindSafe>,\n}\nimpl<T> AtomicPtr<T> {\n    #[inline]\n    pub(crate) const fn new(v: *mut T) -> Self {\n        Self { inner: core::sync::atomic::AtomicPtr::new(v), _not_ref_unwind_safe: PhantomData }\n    }\n    #[inline]\n    pub(crate) fn is_lock_free() -> bool {\n        Self::IS_ALWAYS_LOCK_FREE\n    }\n    pub(crate) const IS_ALWAYS_LOCK_FREE: bool = true;\n    const_fn! {\n        const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))];\n        #[inline]\n        pub(crate) const fn as_ptr(&self) -> *mut *mut T {\n            // SAFETY: Self is #[repr(C)] and internally UnsafeCell<*mut T>.\n            // See also https://github.com/rust-lang/rust/pull/66705 and\n            // https://github.com/rust-lang/rust/issues/66136#issuecomment-557867116.\n            unsafe { (*(self as *const Self as *const UnsafeCell<*mut T>)).get() }\n        }\n    }\n}\n#[cfg(not(all(\n    target_arch = \"arm\",\n    not(any(miri, portable_atomic_sanitize_thread)),\n    any(target_os = \"linux\", target_os = \"android\"),\n    not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n)))]\nimpl<T> AtomicPtr<T> {\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub(crate) fn load(&self, order: Ordering) -> *mut T {\n        crate::utils::assert_load_ordering(order); // for track_caller (compiler can omit double check)\n        self.inner.load(order)\n    }\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub(crate) fn store(&self, ptr: *mut T, order: Ordering) {\n        crate::utils::assert_store_ordering(order); // for track_caller (compiler can omit double check)\n        self.inner.store(ptr, order);\n    }\n}\n#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not(portable_atomic_no_atomic_cas)))]\n#[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(target_has_atomic = \"ptr\"))]\nitems!({\n    #[cfg(not(all(\n        target_arch = \"arm\",\n        not(any(miri, portable_atomic_sanitize_thread)),\n        any(target_os = \"linux\", target_os = \"android\"),\n        not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n    )))]\n    impl<T> AtomicPtr<T> {\n        #[inline]\n        #[cfg_attr(\n            any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n            track_caller\n        )]\n        pub(crate) fn compare_exchange(\n            &self,\n            current: *mut T,\n            new: *mut T,\n            success: Ordering,\n            failure: Ordering,\n        ) -> Result<*mut T, *mut T> {\n            crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check)\n            #[cfg(portable_atomic_no_stronger_failure_ordering)]\n            let success = crate::utils::upgrade_success_ordering(success, failure);\n            self.inner.compare_exchange(current, new, success, failure)\n        }\n        #[inline]\n        #[cfg_attr(\n            any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n            track_caller\n        )]\n        pub(crate) fn compare_exchange_weak(\n            &self,\n            current: *mut T,\n            new: *mut T,\n            success: Ordering,\n            failure: Ordering,\n        ) -> Result<*mut T, *mut T> {\n            crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check)\n            #[cfg(portable_atomic_no_stronger_failure_ordering)]\n            let success = crate::utils::upgrade_success_ordering(success, failure);\n            self.inner.compare_exchange_weak(current, new, success, failure)\n        }\n    }\n    // Ideally, we would always use AtomicPtr::fetch_* since it is strict-provenance\n    // compatible, but it requires 1.91+. So, for now emulate it only on cfg(miri).\n    // Code using AtomicUsize::fetch_* via casts is still permissive-provenance\n    // compatible and is sound.\n    #[cfg(portable_atomic_no_strict_provenance_atomic_ptr)]\n    impl<T> AtomicPtr<T> {\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        pub(crate) fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {\n            #[cfg(miri)]\n            {\n                #[cfg(portable_atomic_no_strict_provenance)]\n                use crate::utils::ptr::PtrExt as _;\n                self.fetch_update_(order, |x| x.with_addr(x.addr().wrapping_add(val)))\n            }\n            #[cfg(not(miri))]\n            {\n                crate::utils::ptr::with_exposed_provenance_mut(\n                    self.as_atomic_usize().fetch_add(val, order),\n                )\n            }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        pub(crate) fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {\n            #[cfg(miri)]\n            {\n                #[cfg(portable_atomic_no_strict_provenance)]\n                use crate::utils::ptr::PtrExt as _;\n                self.fetch_update_(order, |x| x.with_addr(x.addr().wrapping_sub(val)))\n            }\n            #[cfg(not(miri))]\n            {\n                crate::utils::ptr::with_exposed_provenance_mut(\n                    self.as_atomic_usize().fetch_sub(val, order),\n                )\n            }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        pub(crate) fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {\n            #[cfg(miri)]\n            {\n                #[cfg(portable_atomic_no_strict_provenance)]\n                use crate::utils::ptr::PtrExt as _;\n                self.fetch_update_(order, |x| x.with_addr(x.addr() | val))\n            }\n            #[cfg(not(miri))]\n            {\n                crate::utils::ptr::with_exposed_provenance_mut(\n                    self.as_atomic_usize().fetch_or(val, order),\n                )\n            }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        pub(crate) fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {\n            #[cfg(miri)]\n            {\n                #[cfg(portable_atomic_no_strict_provenance)]\n                use crate::utils::ptr::PtrExt as _;\n                self.fetch_update_(order, |x| x.with_addr(x.addr() & val))\n            }\n            #[cfg(not(miri))]\n            {\n                crate::utils::ptr::with_exposed_provenance_mut(\n                    self.as_atomic_usize().fetch_and(val, order),\n                )\n            }\n        }\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        pub(crate) fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {\n            #[cfg(miri)]\n            {\n                #[cfg(portable_atomic_no_strict_provenance)]\n                use crate::utils::ptr::PtrExt as _;\n                self.fetch_update_(order, |x| x.with_addr(x.addr() ^ val))\n            }\n            #[cfg(not(miri))]\n            {\n                crate::utils::ptr::with_exposed_provenance_mut(\n                    self.as_atomic_usize().fetch_xor(val, order),\n                )\n            }\n        }\n        #[cfg(miri)]\n        #[inline]\n        #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n        fn fetch_update_<F>(&self, order: Ordering, mut f: F) -> *mut T\n        where\n            F: FnMut(*mut T) -> *mut T,\n        {\n            // This is a private function and all instances of `f` only operate on the value\n            // loaded, so there is no need to synchronize the first load/failed CAS.\n            let mut prev = self.load(Ordering::Relaxed);\n            loop {\n                let next = f(prev);\n                match self.compare_exchange_weak(prev, next, order, Ordering::Relaxed) {\n                    Ok(x) => return x,\n                    Err(next_prev) => prev = next_prev,\n                }\n            }\n        }\n        #[cfg(not(miri))]\n        #[inline(always)]\n        fn as_atomic_usize(&self) -> &AtomicUsize {\n            static_assert!(\n                core::mem::size_of::<AtomicPtr<()>>() == core::mem::size_of::<AtomicUsize>()\n            );\n            static_assert!(\n                core::mem::align_of::<AtomicPtr<()>>() == core::mem::align_of::<AtomicUsize>()\n            );\n            // SAFETY: AtomicPtr and AtomicUsize have the same layout,\n            // and both access data in the same way.\n            unsafe { &*(self as *const Self as *const AtomicUsize) }\n        }\n    }\n    #[cfg(not(all(\n        any(target_arch = \"x86\", target_arch = \"x86_64\"),\n        not(any(miri, portable_atomic_sanitize_thread)),\n        any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n    )))]\n    impl_default_bit_opts!(AtomicPtr, usize);\n});\nimpl<T> core::ops::Deref for AtomicPtr<T> {\n    type Target = core::sync::atomic::AtomicPtr<T>;\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    fn deref(&self) -> &Self::Target {\n        &self.inner\n    }\n}\n\n// NB: Sync with atomic_int! macro in arm_linux.rs\nmacro_rules! atomic_int {\n    ($atomic_type:ident, $int_type:ident) => {\n        #[repr(transparent)]\n        pub(crate) struct $atomic_type {\n            pub(super) inner: core::sync::atomic::$atomic_type,\n            // Prevent RefUnwindSafe from being propagated from the std atomic type. See NotRefUnwindSafe for more.\n            _not_ref_unwind_safe: PhantomData<NotRefUnwindSafe>,\n        }\n        impl $atomic_type {\n            #[inline]\n            pub(crate) const fn new(v: $int_type) -> Self {\n                Self {\n                    inner: core::sync::atomic::$atomic_type::new(v),\n                    _not_ref_unwind_safe: PhantomData,\n                }\n            }\n            #[inline]\n            pub(crate) fn is_lock_free() -> bool {\n                Self::IS_ALWAYS_LOCK_FREE\n            }\n            // ESP-IDF targets' 64-bit atomics are not lock-free.\n            // https://github.com/rust-lang/rust/pull/115577#issuecomment-1732259297\n            pub(crate) const IS_ALWAYS_LOCK_FREE: bool = cfg!(not(all(\n                any(target_arch = \"riscv32\", target_arch = \"xtensa\"),\n                target_os = \"espidf\",\n            ))) | (core::mem::size_of::<$int_type>()\n                < 8);\n            const_fn! {\n                const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))];\n                #[inline]\n                pub(crate) const fn as_ptr(&self) -> *mut $int_type {\n                    // SAFETY: Self is #[repr(C)] and internally UnsafeCell<$int_type>.\n                    // See also https://github.com/rust-lang/rust/pull/66705 and\n                    // https://github.com/rust-lang/rust/issues/66136#issuecomment-557867116.\n                    unsafe {\n                        (*(self as *const Self as *const UnsafeCell<$int_type>)).get()\n                    }\n                }\n            }\n        }\n        #[cfg(not(all(\n            target_arch = \"arm\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(target_os = \"linux\", target_os = \"android\"),\n            not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n        )))]\n        impl $atomic_type {\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub(crate) fn load(&self, order: Ordering) -> $int_type {\n                crate::utils::assert_load_ordering(order); // for track_caller (compiler can omit double check)\n                self.inner.load(order)\n            }\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub(crate) fn store(&self, val: $int_type, order: Ordering) {\n                crate::utils::assert_store_ordering(order); // for track_caller (compiler can omit double check)\n                self.inner.store(val, order);\n            }\n        }\n        #[cfg_attr(\n            portable_atomic_no_cfg_target_has_atomic,\n            cfg(not(portable_atomic_no_atomic_cas))\n        )]\n        #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(target_has_atomic = \"ptr\"))]\n        items!({\n            impl_default_no_fetch_ops!($atomic_type, $int_type);\n            #[cfg(not(all(\n                target_arch = \"arm\",\n                not(any(miri, portable_atomic_sanitize_thread)),\n                any(target_os = \"linux\", target_os = \"android\"),\n                not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n            )))]\n            impl $atomic_type {\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub(crate) fn compare_exchange(\n                    &self,\n                    current: $int_type,\n                    new: $int_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$int_type, $int_type> {\n                    crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check)\n                    #[cfg(portable_atomic_no_stronger_failure_ordering)]\n                    let success = crate::utils::upgrade_success_ordering(success, failure);\n                    self.inner.compare_exchange(current, new, success, failure)\n                }\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub(crate) fn compare_exchange_weak(\n                    &self,\n                    current: $int_type,\n                    new: $int_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$int_type, $int_type> {\n                    crate::utils::assert_compare_exchange_ordering(success, failure); // for track_caller (compiler can omit double check)\n                    #[cfg(portable_atomic_no_stronger_failure_ordering)]\n                    let success = crate::utils::upgrade_success_ordering(success, failure);\n                    self.inner.compare_exchange_weak(current, new, success, failure)\n                }\n            }\n            impl $atomic_type {\n                #[allow(dead_code)]\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                fn fetch_update_<F>(&self, order: Ordering, mut f: F) -> $int_type\n                where\n                    F: FnMut($int_type) -> $int_type,\n                {\n                    // This is a private function and all instances of `f` only operate on the value\n                    // loaded, so there is no need to synchronize the first load/failed CAS.\n                    let mut prev = self.load(Ordering::Relaxed);\n                    loop {\n                        let next = f(prev);\n                        match self.compare_exchange_weak(prev, next, order, Ordering::Relaxed) {\n                            Ok(x) => return x,\n                            Err(next_prev) => prev = next_prev,\n                        }\n                    }\n                }\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub(crate) fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {\n                    #[cfg(not(portable_atomic_no_atomic_min_max))]\n                    {\n                        #[cfg(any(\n                            all(\n                                any(target_arch = \"aarch64\", target_arch = \"arm64ec\"),\n                                any(\n                                    target_feature = \"lse\",\n                                    portable_atomic_target_feature = \"lse\",\n                                ),\n                            ),\n                            all(\n                                target_arch = \"arm\",\n                                not(any(\n                                    target_feature = \"v6\",\n                                    portable_atomic_target_feature = \"v6\",\n                                )),\n                            ),\n                            target_arch = \"mips\",\n                            target_arch = \"mips32r6\",\n                            target_arch = \"mips64\",\n                            target_arch = \"mips64r6\",\n                            target_arch = \"powerpc\",\n                            target_arch = \"powerpc64\",\n                        ))]\n                        {\n                            // HACK: the following operations are currently broken (at least on qemu-user):\n                            // - aarch64's `AtomicI{8,16}::fetch_{max,min}` (release mode + lse)\n                            // - armv5te's `Atomic{I,U}{8,16}::fetch_{max,min}`\n                            // - mips's `AtomicI8::fetch_{max,min}` (release mode)\n                            // - mipsel's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least)\n                            // - mips64's `AtomicI8::fetch_{max,min}` (release mode)\n                            // - mips64el's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least)\n                            // - powerpc's `AtomicI{8,16}::fetch_{max,min}`\n                            // - powerpc64's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least)\n                            // - powerpc64le's `AtomicU{8,16}::fetch_{max,min}` (release mode + fat LTO)\n                            // See also:\n                            // https://github.com/llvm/llvm-project/issues/61880\n                            // https://github.com/llvm/llvm-project/issues/61881\n                            // https://github.com/llvm/llvm-project/issues/61882\n                            // https://github.com/taiki-e/portable-atomic/issues/2\n                            // https://github.com/rust-lang/rust/issues/100650\n                            if core::mem::size_of::<$int_type>() <= 2 {\n                                return self.fetch_update_(order, |x| core::cmp::max(x, val));\n                            }\n                        }\n                        self.inner.fetch_max(val, order)\n                    }\n                    #[cfg(portable_atomic_no_atomic_min_max)]\n                    {\n                        self.fetch_update_(order, |x| core::cmp::max(x, val))\n                    }\n                }\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub(crate) fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {\n                    #[cfg(not(portable_atomic_no_atomic_min_max))]\n                    {\n                        #[cfg(any(\n                            all(\n                                any(target_arch = \"aarch64\", target_arch = \"arm64ec\"),\n                                any(\n                                    target_feature = \"lse\",\n                                    portable_atomic_target_feature = \"lse\",\n                                ),\n                            ),\n                            all(\n                                target_arch = \"arm\",\n                                not(any(\n                                    target_feature = \"v6\",\n                                    portable_atomic_target_feature = \"v6\",\n                                )),\n                            ),\n                            target_arch = \"mips\",\n                            target_arch = \"mips32r6\",\n                            target_arch = \"mips64\",\n                            target_arch = \"mips64r6\",\n                            target_arch = \"powerpc\",\n                            target_arch = \"powerpc64\",\n                        ))]\n                        {\n                            // HACK: the following operations are currently broken (at least on qemu-user):\n                            // - aarch64's `AtomicI{8,16}::fetch_{max,min}` (release mode + lse)\n                            // - armv5te's `Atomic{I,U}{8,16}::fetch_{max,min}`\n                            // - mips's `AtomicI8::fetch_{max,min}` (release mode)\n                            // - mipsel's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least)\n                            // - mips64's `AtomicI8::fetch_{max,min}` (release mode)\n                            // - mips64el's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least)\n                            // - powerpc's `AtomicI{8,16}::fetch_{max,min}`\n                            // - powerpc64's `AtomicI{8,16}::fetch_{max,min}` (debug mode, at least)\n                            // - powerpc64le's `AtomicU{8,16}::fetch_{max,min}` (release mode + fat LTO)\n                            // See also:\n                            // https://github.com/llvm/llvm-project/issues/61880\n                            // https://github.com/llvm/llvm-project/issues/61881\n                            // https://github.com/llvm/llvm-project/issues/61882\n                            // https://github.com/taiki-e/portable-atomic/issues/2\n                            // https://github.com/rust-lang/rust/issues/100650\n                            if core::mem::size_of::<$int_type>() <= 2 {\n                                return self.fetch_update_(order, |x| core::cmp::min(x, val));\n                            }\n                        }\n                        self.inner.fetch_min(val, order)\n                    }\n                    #[cfg(portable_atomic_no_atomic_min_max)]\n                    {\n                        self.fetch_update_(order, |x| core::cmp::min(x, val))\n                    }\n                }\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub(crate) fn fetch_not(&self, order: Ordering) -> $int_type {\n                    self.fetch_xor(!0, order)\n                }\n                // TODO: provide asm-based implementation on AArch64 without FEAT_LSE, Armv7, RISC-V, etc.\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub(crate) fn fetch_neg(&self, order: Ordering) -> $int_type {\n                    self.fetch_update_(order, $int_type::wrapping_neg)\n                }\n            }\n            #[cfg(not(all(\n                any(target_arch = \"x86\", target_arch = \"x86_64\"),\n                not(any(miri, portable_atomic_sanitize_thread)),\n                any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            )))]\n            items!({\n                impl_default_bit_opts!($atomic_type, $int_type);\n                impl $atomic_type {\n                    #[inline]\n                    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                    pub(crate) fn not(&self, order: Ordering) {\n                        self.fetch_not(order);\n                    }\n                    #[inline]\n                    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                    pub(crate) fn neg(&self, order: Ordering) {\n                        self.fetch_neg(order);\n                    }\n                }\n            });\n        });\n        impl core::ops::Deref for $atomic_type {\n            type Target = core::sync::atomic::$atomic_type;\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            fn deref(&self) -> &Self::Target {\n                &self.inner\n            }\n        }\n    };\n}\n\natomic_int!(AtomicIsize, isize);\natomic_int!(AtomicUsize, usize);\n#[cfg(not(portable_atomic_no_atomic_load_store))]\natomic_int!(AtomicI8, i8);\n#[cfg(not(portable_atomic_no_atomic_load_store))]\natomic_int!(AtomicU8, u8);\n#[cfg(not(portable_atomic_no_atomic_load_store))]\natomic_int!(AtomicI16, i16);\n#[cfg(not(portable_atomic_no_atomic_load_store))]\natomic_int!(AtomicU16, u16);\n#[cfg(not(portable_atomic_no_atomic_load_store))]\n#[cfg(not(target_pointer_width = \"16\"))]\natomic_int!(AtomicI32, i32);\n#[cfg(not(portable_atomic_no_atomic_load_store))]\n#[cfg(not(target_pointer_width = \"16\"))]\natomic_int!(AtomicU32, u32);\n#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not(portable_atomic_no_atomic_64)))]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(\n        target_has_atomic = \"64\",\n        not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")),\n    ))\n)]\nitems!({\n    atomic_int!(AtomicI64, i64);\n    atomic_int!(AtomicU64, u64);\n});\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/detect/aarch64_aa64reg.rs",
      "sha256": "77d6b3a2fafbdeb881c671379d0be0a330b46d78c8252d074c97ed44b1138123",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRun-time CPU feature detection on AArch64 Linux/Android/FreeBSD/NetBSD/OpenBSD by parsing system registers.\n\nAs of Rust 1.94, is_aarch64_feature_detected doesn't support run-time detection on NetBSD.\nhttps://github.com/rust-lang/rust/blob/1.94.0/library/std_detect/src/detect/mod.rs\nRun-time detection on OpenBSD by is_aarch64_feature_detected is supported on Rust 1.70+.\nhttps://github.com/rust-lang/stdarch/pull/1374\n\nRefs:\n- https://developer.arm.com/documentation/ddi0601/2025-06/AArch64-Registers\n- https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm64/cpu-feature-registers.rst\n- https://github.com/rust-lang/stdarch/blob/a0c30f3e3c75adcd6ee7efc94014ebcead61c507/crates/std_detect/src/detect/os/aarch64.rs\n\nSupported platforms:\n- Linux 4.11+ (emulate mrs instruction)\n  https://github.com/torvalds/linux/commit/77c97b4ee21290f5f083173d957843b615abbff2\n- FreeBSD 12.0+ (emulate mrs instruction)\n  https://github.com/freebsd/freebsd-src/commit/398810619cb32abf349f8de23f29510b2ee0839b\n- NetBSD 9.0+ (through sysctl/sysctlbyname)\n  https://github.com/NetBSD/src/commit/0e9d25528729f7fea53e78275d1bc5039dfe8ffb\n  sysctl/sysctlbyname returns an unsupported error if operation is not supported,\n  so we can safely use this on older versions.\n- OpenBSD 7.1+ (through sysctl)\n  https://github.com/openbsd/src/commit/d335af936b9d7dd9cf655cae1ce19560c45de6c8\n  sysctl returns an unsupported error if operation is not supported,\n  so we can safely use this on older versions.\n\nFor now, this module is only used on NetBSD/OpenBSD.\n\nOn Linux/Android/FreeBSD, we use auxv.rs and this module is test-only because:\n- On Linux/Android, this approach requires a higher kernel version than Rust supports,\n  and also does not work with qemu-user (as of QEMU 7.2) and Valgrind (as of Valgrind 3.24).\n  (Looking into HWCAP_CPUID in auxvec, it appears that Valgrind is setting it\n  to false correctly, but qemu-user is setting it to true.)\n  - qemu-user issue seem to be fixed as of QEMU 9.2.\n- On FreeBSD, this approach does not work on FreeBSD 12 on QEMU (confirmed on\n  FreeBSD 12.{2,3,4}), and we got SIGILL (worked on FreeBSD 13 and 14).\n*/\n\ninclude!(\"common.rs\");\n\n#[cfg_attr(test, derive(Debug, PartialEq))]\nstruct AA64Reg {\n    aa64isar0: u64,\n    aa64isar1: u64,\n    #[cfg(test)]\n    aa64isar3: u64,\n    aa64mmfr2: u64,\n}\n\n#[cold]\n#[must_use]\nfn _detect(mut info: CpuInfo) -> CpuInfo {\n    let AA64Reg {\n        aa64isar0,\n        aa64isar1,\n        #[cfg(test)]\n        aa64isar3,\n        aa64mmfr2,\n    } = imp::aa64reg();\n\n    // ID_AA64ISAR0_EL1, AArch64 Instruction Set Attribute Register 0\n    // https://developer.arm.com/documentation/ddi0601/2025-06/AArch64-Registers/ID-AA64ISAR0-EL1--AArch64-Instruction-Set-Attribute-Register-0\n    // Atomic, bits [23:20]\n    // > FEAT_LSE implements the functionality identified by the value 0b0010.\n    // > FEAT_LSE128 implements the functionality identified by the value 0b0011.\n    // > From Armv8.1, the value 0b0000 is not permitted.\n    let atomic = extract(aa64isar0, 23, 20);\n    if atomic >= 0b0010 {\n        info.set(CpuInfoFlag::lse);\n        if atomic >= 0b0011 {\n            info.set(CpuInfoFlag::lse128);\n        }\n    }\n    // ID_AA64ISAR1_EL1, AArch64 Instruction Set Attribute Register 1\n    // https://developer.arm.com/documentation/ddi0601/2025-06/AArch64-Registers/ID-AA64ISAR1-EL1--AArch64-Instruction-Set-Attribute-Register-1\n    // LRCPC, bits [23:20]\n    // > FEAT_LRCPC implements the functionality identified by the value 0b0001.\n    // > FEAT_LRCPC2 implements the functionality identified by the value 0b0010.\n    // > FEAT_LRCPC3 implements the functionality identified by the value 0b0011.\n    // > From Armv8.3, the value 0b0000 is not permitted.\n    // > From Armv8.4, the value 0b0001 is not permitted.\n    let lrcpc = extract(aa64isar1, 23, 20);\n    if lrcpc >= 0b0011 {\n        info.set(CpuInfoFlag::rcpc3);\n    }\n    #[cfg(test)]\n    if lrcpc >= 0b0001 {\n        info.set(CpuInfoFlag::rcpc);\n        if lrcpc >= 0b0010 {\n            info.set(CpuInfoFlag::rcpc2);\n        }\n    }\n    // LS64, bits [63:60]\n    // > FEAT_LS64 implements the functionality identified by 0b0001.\n    // > FEAT_LS64_V implements the functionality identified by 0b0010.\n    // > FEAT_LS64_ACCDATA implements the functionality identified by 0b0011.\n    // > FEAT_LS64WB implements the functionality identified by 0b0100.\n    #[cfg(test)]\n    if extract(aa64isar1, 63, 60) >= 0b0100 {\n        info.set(CpuInfoFlag::ls64wb);\n    }\n    // ID_AA64ISAR3_EL1, AArch64 Instruction Set Attribute Register 3\n    // https://developer.arm.com/documentation/ddi0601/2025-06/AArch64-Registers/ID-AA64ISAR3-EL1--AArch64-Instruction-Set-Attribute-Register-3\n    // LSFE, bits [19:16]\n    // > FEAT_LSFE implements the functionality identified by the value 0b0001\n    #[cfg(test)]\n    if extract(aa64isar3, 19, 16) >= 0b0001 {\n        info.set(CpuInfoFlag::lsfe);\n    }\n    // ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2\n    // https://developer.arm.com/documentation/ddi0601/2025-06/AArch64-Registers/ID-AA64MMFR2-EL1--AArch64-Memory-Model-Feature-Register-2\n    // AT, bits [35:32]\n    // > FEAT_LSE2 implements the functionality identified by the value 0b0001.\n    // > From Armv8.4, the value 0b0000 is not permitted.\n    if extract(aa64mmfr2, 35, 32) >= 0b0001 {\n        info.set(CpuInfoFlag::lse2);\n    }\n    info\n}\n\nfn extract(x: u64, high: usize, low: usize) -> u64 {\n    (x >> low) & ((1 << (high - low + 1)) - 1)\n}\n\n#[cfg(not(any(target_os = \"netbsd\", target_os = \"openbsd\")))]\nmod imp {\n    // This module is test-only. See parent module docs for details.\n\n    #[cfg(not(portable_atomic_no_asm))]\n    use core::arch::asm;\n\n    use super::AA64Reg;\n\n    pub(super) fn aa64reg() -> AA64Reg {\n        // SAFETY: This is safe on FreeBSD 12.0+. FreeBSD 11 was EoL on 2021-09-30.\n        // Note that stdarch has been doing the same thing since before FreeBSD 11 was EoL.\n        // https://github.com/rust-lang/stdarch/pull/611\n        unsafe {\n            let aa64isar0: u64;\n            asm!(\n                \"mrs {}, ID_AA64ISAR0_EL1\",\n                out(reg) aa64isar0,\n                options(pure, nomem, nostack, preserves_flags),\n            );\n            let aa64isar1: u64;\n            asm!(\n                \"mrs {}, ID_AA64ISAR1_EL1\",\n                out(reg) aa64isar1,\n                options(pure, nomem, nostack, preserves_flags),\n            );\n            #[cfg(test)]\n            #[cfg(not(portable_atomic_pre_llvm_18))]\n            let aa64isar3: u64;\n            // ID_AA64ISAR3_EL1 is only recognized on LLVM 18+.\n            // https://github.com/llvm/llvm-project/commit/17baba9fa2728b1b1134f9dccb9318debd5a9a1b\n            #[cfg(test)]\n            #[cfg(not(portable_atomic_pre_llvm_18))]\n            asm!(\n                \"mrs {}, ID_AA64ISAR3_EL1\",\n                out(reg) aa64isar3,\n                options(pure, nomem, nostack, preserves_flags),\n            );\n            let aa64mmfr2: u64;\n            asm!(\n                \"mrs {}, ID_AA64MMFR2_EL1\",\n                out(reg) aa64mmfr2,\n                options(pure, nomem, nostack, preserves_flags),\n            );\n            AA64Reg {\n                aa64isar0,\n                aa64isar1,\n                #[cfg(test)]\n                #[cfg(not(portable_atomic_pre_llvm_18))]\n                aa64isar3,\n                #[cfg(test)]\n                #[cfg(portable_atomic_pre_llvm_18)]\n                aa64isar3: 0,\n                aa64mmfr2,\n            }\n        }\n    }\n}\n#[cfg(target_os = \"netbsd\")]\nmod imp {\n    // NetBSD doesn't trap the mrs instruction, but exposes the system registers through sysctl.\n    // https://github.com/NetBSD/src/commit/0e9d25528729f7fea53e78275d1bc5039dfe8ffb\n    // https://github.com/golang/sys/commit/ef9fd89ba245e184bdd308f7f2b4f3c551fa5b0f\n\n    use core::{mem, ptr};\n\n    use super::AA64Reg;\n\n    // libc requires Rust 1.63\n    #[allow(non_camel_case_types)]\n    pub(super) mod ffi {\n        pub(crate) use crate::utils::ffi::{CStr, c_char, c_int, c_size_t, c_void};\n\n        sys_struct!({\n            // Defined in machine/armreg.h.\n            // https://github.com/NetBSD/src/blob/121914f187d0f46c2ce43f00531d2c500d8e81e5/sys/arch/aarch64/include/armreg.h#L1863\n            pub(crate) struct aarch64_sysctl_cpu_id {\n                // NetBSD 9.0+\n                // https://github.com/NetBSD/src/commit/0e9d25528729f7fea53e78275d1bc5039dfe8ffb\n                pub(crate) ac_midr: u64,\n                pub(crate) ac_revidr: u64,\n                pub(crate) ac_mpidr: u64,\n                pub(crate) ac_aa64dfr0: u64,\n                pub(crate) ac_aa64dfr1: u64,\n                pub(crate) ac_aa64isar0: u64,\n                pub(crate) ac_aa64isar1: u64,\n                pub(crate) ac_aa64mmfr0: u64,\n                pub(crate) ac_aa64mmfr1: u64,\n                pub(crate) ac_aa64mmfr2: u64,\n                pub(crate) ac_aa64pfr0: u64,\n                pub(crate) ac_aa64pfr1: u64,\n                pub(crate) ac_aa64zfr0: u64,\n                pub(crate) ac_mvfr0: u32,\n                pub(crate) ac_mvfr1: u32,\n                pub(crate) ac_mvfr2: u32,\n                // NetBSD 10.0+\n                // https://github.com/NetBSD/src/commit/0c7bdc13f0e332cccec56e307f023b4888638973\n                pub(crate) ac_pad: u32,\n                pub(crate) ac_clidr: u64,\n                pub(crate) ac_ctr: u64,\n            }\n        });\n\n        sys_fn!({\n            extern \"C\" {\n                // Defined in sys/sysctl.h.\n                // https://man.netbsd.org/sysctl.3\n                // https://github.com/NetBSD/src/blob/121914f187d0f46c2ce43f00531d2c500d8e81e5/sys/sys/sysctl.h\n                pub(crate) fn sysctlbyname(\n                    name: *const c_char,\n                    old_p: *mut c_void,\n                    old_len_p: *mut c_size_t,\n                    new_p: *const c_void,\n                    new_len: c_size_t,\n                ) -> c_int;\n            }\n        });\n    }\n\n    pub(super) fn sysctl_cpu_id(name: &ffi::CStr) -> Option<AA64Reg> {\n        const OUT_LEN: ffi::c_size_t =\n            mem::size_of::<ffi::aarch64_sysctl_cpu_id>() as ffi::c_size_t;\n\n        // SAFETY: all fields of aarch64_sysctl_cpu_id are zero-able and we use\n        // the result when machdep.cpuN.cpu_id sysctl was successful.\n        let mut buf: ffi::aarch64_sysctl_cpu_id = unsafe { mem::zeroed() };\n        let mut out_len = OUT_LEN;\n        // SAFETY:\n        // - `name` a valid C string.\n        // - `out_len` does not exceed the size of the value at `buf`.\n        // - `sysctlbyname` is thread-safe.\n        let res = unsafe {\n            ffi::sysctlbyname(\n                name.as_ptr(),\n                (&mut buf as *mut ffi::aarch64_sysctl_cpu_id).cast::<ffi::c_void>(),\n                &mut out_len,\n                ptr::null_mut(),\n                0,\n            )\n        };\n        if res != 0 {\n            return None;\n        }\n        Some(AA64Reg {\n            aa64isar0: buf.ac_aa64isar0,\n            aa64isar1: buf.ac_aa64isar1,\n            #[cfg(test)]\n            aa64isar3: 0,\n            aa64mmfr2: buf.ac_aa64mmfr2,\n        })\n    }\n\n    pub(super) fn aa64reg() -> AA64Reg {\n        // Get system registers for cpu0.\n        // If failed, returns default because machdep.cpuN.cpu_id sysctl is not available.\n        // machdep.cpuN.cpu_id sysctl was added in NetBSD 9.0 so it is not available on older versions.\n        // It is ok to check only cpu0, even if there are more CPUs.\n        // https://github.com/NetBSD/src/commit/bd9707e06ea7d21b5c24df6dfc14cb37c2819416\n        // https://github.com/golang/sys/commit/ef9fd89ba245e184bdd308f7f2b4f3c551fa5b0f\n        match sysctl_cpu_id(c!(\"machdep.cpu0.cpu_id\")) {\n            Some(cpu_id) => cpu_id,\n            None => AA64Reg {\n                aa64isar0: 0,\n                aa64isar1: 0,\n                #[cfg(test)]\n                aa64isar3: 0,\n                aa64mmfr2: 0,\n            },\n        }\n    }\n}\n#[cfg(target_os = \"openbsd\")]\nmod imp {\n    // OpenBSD doesn't trap the mrs instruction, but exposes the system registers through sysctl.\n    // https://github.com/openbsd/src/commit/d335af936b9d7dd9cf655cae1ce19560c45de6c8\n    // https://github.com/golang/go/commit/cd54ef1f61945459486e9eea2f016d99ef1da925\n\n    use core::{mem, ptr};\n\n    use super::AA64Reg;\n\n    // libc requires Rust 1.63\n    pub(super) mod ffi {\n        pub(crate) use crate::utils::ffi::{c_int, c_size_t, c_uint, c_void};\n\n        sys_const!({\n            // Defined in sys/sysctl.h.\n            // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/sys/sysctl.h\n            pub(crate) const CTL_MACHDEP: c_int = 7;\n\n            // Defined in machine/cpu.h.\n            // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/arch/arm64/include/cpu.h\n            // OpenBSD 7.1+\n            // https://github.com/openbsd/src/commit/d335af936b9d7dd9cf655cae1ce19560c45de6c8\n            pub(crate) const CPU_ID_AA64ISAR0: c_int = 2;\n            pub(crate) const CPU_ID_AA64ISAR1: c_int = 3;\n            // OpenBSD 7.3+\n            // https://github.com/openbsd/src/commit/c7654cd65262d532212f65123ee3905ba200365c\n            // However, on OpenBSD 7.3-7.5, querying CPU_ID_AA64MMFR2 always returns 0.\n            // https://github.com/openbsd/src/commit/e8331b74e5c20302d4bd948c9db722af688ccfc1\n            pub(crate) const CPU_ID_AA64MMFR2: c_int = 7;\n        });\n\n        sys_fn!({\n            extern \"C\" {\n                // Defined in sys/sysctl.h.\n                // https://man.openbsd.org/sysctl.2\n                // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/sys/sysctl.h\n                pub(crate) fn sysctl(\n                    name: *const c_int,\n                    name_len: c_uint,\n                    old_p: *mut c_void,\n                    old_len_p: *mut c_size_t,\n                    new_p: *mut c_void,\n                    new_len: c_size_t,\n                ) -> c_int;\n            }\n        });\n    }\n\n    // sysctl returns an unsupported error if operation is not supported,\n    // so we can safely use this function on older versions of OpenBSD.\n    pub(super) fn aa64reg() -> AA64Reg {\n        let aa64isar0 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64ISAR0]).unwrap_or(0);\n        let aa64isar1 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64ISAR1]).unwrap_or(0);\n        let aa64mmfr2 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64MMFR2]).unwrap_or(0);\n        AA64Reg {\n            aa64isar0,\n            aa64isar1,\n            #[cfg(test)]\n            aa64isar3: 0,\n            aa64mmfr2,\n        }\n    }\n\n    fn sysctl64(mib: &[ffi::c_int]) -> Option<u64> {\n        const OUT_LEN: ffi::c_size_t = mem::size_of::<u64>() as ffi::c_size_t;\n        let mut out = 0_u64;\n        let mut out_len = OUT_LEN;\n        #[allow(clippy::cast_possible_truncation)]\n        let mib_len = mib.len() as ffi::c_uint;\n        // SAFETY:\n        // - `mib_len` does not exceed the size of `mib`.\n        // - `out_len` does not exceed the size of `out`.\n        // - `sysctl` is thread-safe.\n        let res = unsafe {\n            ffi::sysctl(\n                mib.as_ptr(),\n                mib_len,\n                (&mut out as *mut u64).cast::<ffi::c_void>(),\n                &mut out_len,\n                ptr::null_mut(),\n                0,\n            )\n        };\n        // OpenBSD sysctl returns -1 on failure.\n        if res == -1 {\n            return None;\n        }\n        debug_assert_eq!(out_len, OUT_LEN);\n        Some(out)\n    }\n}\n\n#[allow(\n    clippy::alloc_instead_of_core,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    clippy::undocumented_unsafe_blocks,\n    clippy::wildcard_imports\n)]\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    #[cfg_attr(portable_atomic_test_detect_false, ignore = \"detection disabled\")]\n    fn test_aa64reg() {\n        let AA64Reg { aa64isar0, aa64isar1, aa64isar3, aa64mmfr2 } = imp::aa64reg();\n        test_helper::eprintln_nocapture!(\n            \"aa64isar0={},aa64isar1={},aa64isar3={},aa64mmfr2={}\",\n            aa64isar0,\n            aa64isar1,\n            aa64isar3,\n            aa64mmfr2,\n        );\n        let atomic = extract(aa64isar0, 23, 20);\n        if detect().lse() {\n            if detect().lse128() {\n                assert_eq!(atomic, 0b0011);\n            } else {\n                assert_eq!(atomic, 0b0010);\n            }\n        } else {\n            assert_eq!(atomic, 0b0000);\n        }\n        let lrcpc = extract(aa64isar1, 23, 20);\n        if detect().rcpc() {\n            if detect().rcpc2() {\n                if detect().rcpc3() {\n                    assert_eq!(lrcpc, 0b0011);\n                } else {\n                    assert_eq!(lrcpc, 0b0010);\n                }\n            } else {\n                assert_eq!(lrcpc, 0b0001);\n            }\n        } else {\n            assert_eq!(lrcpc, 0b0000);\n        }\n        let ls64 = extract(aa64isar1, 63, 60);\n        if detect().ls64wb() {\n            assert_eq!(ls64, 0b0100);\n        } else {\n            assert!(ls64 < 0b0100, \"{}\", ls64);\n        }\n        let lsfe = extract(aa64isar3, 19, 16);\n        if detect().lsfe() {\n            assert_eq!(lsfe, 0b0001);\n        } else {\n            assert_eq!(lsfe, 0b0000);\n        }\n        let at = extract(aa64mmfr2, 35, 32);\n        if detect().lse2() {\n            assert_eq!(at, 0b0001);\n        } else {\n            assert_eq!(at, 0b0000);\n        }\n    }\n\n    #[cfg(target_os = \"openbsd\")]\n    #[test]\n    fn test_alternative() {\n        use std::{format, process::Command, string::String};\n\n        // Call sysctl command instead of libc API.\n        //\n        // This is used only for testing.\n        struct SysctlMachdepOutput(String);\n        impl SysctlMachdepOutput {\n            fn new() -> Self {\n                let output = Command::new(\"sysctl\").arg(\"machdep\").output().unwrap();\n                assert!(output.status.success());\n                let stdout = String::from_utf8(output.stdout).unwrap();\n                Self(stdout)\n            }\n            fn field(&self, name: &str) -> Option<u64> {\n                Some(\n                    self.0\n                        .lines()\n                        .find_map(|s| s.strip_prefix(&format!(\"{}=\", name)))?\n                        .parse()\n                        .unwrap(),\n                )\n            }\n        }\n\n        let AA64Reg { aa64isar0, aa64isar1, aa64isar3, aa64mmfr2 } = imp::aa64reg();\n        let sysctl_output = SysctlMachdepOutput::new();\n        assert_eq!(aa64isar0, sysctl_output.field(\"machdep.id_aa64isar0\").unwrap_or(0));\n        assert_eq!(aa64isar1, sysctl_output.field(\"machdep.id_aa64isar1\").unwrap_or(0));\n        assert_eq!(aa64isar3, sysctl_output.field(\"machdep.id_aa64isar3\").unwrap_or(0));\n        assert_eq!(aa64mmfr2, sysctl_output.field(\"machdep.id_aa64mmfr2\").unwrap_or(0));\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/detect/aarch64_apple.rs",
      "sha256": "149a79530b9bdb11b1521918a4d61ece2be2cb99ab4c86cb6765c3acde1c727a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRun-time CPU feature detection on AArch64 Apple targets by using sysctlbyname.\n\nOn macOS, this module is currently only enabled on tests because there are no\ninstructions that were not available on the M1 but are now available on the\nlatest Apple hardware and this library currently wants to use:\n\n```console\n$ LC_ALL=C comm -23 <(rustc --print cfg --target aarch64-apple-darwin -C target-cpu=apple-m5 | grep -F target_feature) <(rustc --print cfg --target aarch64-apple-darwin | grep -F target_feature)\ntarget_feature=\"bf16\"\ntarget_feature=\"bti\"\ntarget_feature=\"cssc\"\ntarget_feature=\"ecv\"\ntarget_feature=\"hbc\"\ntarget_feature=\"i8mm\"\ntarget_feature=\"mte\"\ntarget_feature=\"sme\"\ntarget_feature=\"sme-b16b16\"\ntarget_feature=\"sme-f16f16\"\ntarget_feature=\"sme-f64f64\"\ntarget_feature=\"sme-i16i64\"\ntarget_feature=\"sme2\"\ntarget_feature=\"sme2p1\"\ntarget_feature=\"sve-b16b16\"\ntarget_feature=\"v8.5a\"\ntarget_feature=\"v8.6a\"\ntarget_feature=\"v8.7a\"\ntarget_feature=\"wfxt\"\n```\n\nNon-macOS targets doesn't always supports FEAT_LSE2, so we use this module on them.\nAs used in the example in https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Enable-DIT-for-constant-time-cryptographic-operations,\nsysctlbyname is supported on all Apple platforms.\n\nRefs: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics\n*/\n\ninclude!(\"common.rs\");\n\nuse core::{mem, ptr};\n\n// libc requires Rust 1.63\nmod ffi {\n    pub(crate) use crate::utils::ffi::{CStr, c_char, c_int, c_size_t, c_void};\n\n    #[cfg(test)] // test-only\n    sys_const!({\n        // https://github.com/apple-oss-distributions/xnu/blob/xnu-12377.121.6/osfmk/arm/cpu_capabilities_public.h\n        pub(crate) const CAP_BIT_FEAT_LSE: usize = 6;\n        pub(crate) const CAP_BIT_FEAT_LRCPC: usize = 15;\n        pub(crate) const CAP_BIT_FEAT_LRCPC2: usize = 16;\n        pub(crate) const CAP_BIT_FEAT_LSE2: usize = 30;\n        pub(crate) const CAP_BIT_NB: usize = 92;\n    });\n\n    sys_fn!({\n        extern \"C\" {\n            // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname\n            // https://github.com/apple-oss-distributions/xnu/blob/xnu-12377.121.6/bsd/sys/sysctl.h\n            pub(crate) fn sysctlbyname(\n                name: *const c_char,\n                old_p: *mut c_void,\n                old_len_p: *mut c_size_t,\n                new_p: *mut c_void,\n                new_len: c_size_t,\n            ) -> c_int;\n        }\n    });\n}\n\nfn sysctlbyname32(name: &ffi::CStr) -> Option<u32> {\n    const OUT_LEN: ffi::c_size_t = mem::size_of::<u32>() as ffi::c_size_t;\n\n    let mut out = 0_u32;\n    let mut out_len = OUT_LEN;\n    // SAFETY:\n    // - `name` a valid C string.\n    // - `out_len` does not exceed the size of `out`.\n    // - `sysctlbyname` is thread-safe.\n    let res = unsafe {\n        ffi::sysctlbyname(\n            name.as_ptr(),\n            (&mut out as *mut u32).cast::<ffi::c_void>(),\n            &mut out_len,\n            ptr::null_mut(),\n            0,\n        )\n    };\n    if res != 0 {\n        return None;\n    }\n    debug_assert_eq!(out_len, OUT_LEN);\n    Some(out)\n}\n\n#[cold]\n#[must_use]\nfn _detect(mut info: CpuInfo) -> CpuInfo {\n    macro_rules! check {\n        ($flag:ident, $($name:tt) ||+) => {\n            if $(sysctlbyname32(c!($name)).unwrap_or(0) != 0) ||+ {\n                info.set(CpuInfoFlag::$flag);\n            }\n        };\n    }\n\n    // On macOS, AArch64 support was added in macOS 11,\n    // hw.optional.armv8_1_atomics is available on macOS 11+,\n    // hw.optional.arm.FEAT_* are only available on macOS 12+.\n    // Query both names in case future versions of macOS remove the old name.\n    // https://github.com/golang/go/commit/c15593197453b8bf90fc3a9080ba2afeaf7934ea\n    // https://github.com/google/boringssl/commit/91e0b11eba517d83b910b20fe3740eeb39ecb37e\n    // hw.optional.arm.caps is available on macOS 15+.\n    // https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/apple.inc#L56\n    check!(lse, \"hw.optional.arm.FEAT_LSE\" || \"hw.optional.armv8_1_atomics\");\n    check!(lse2, \"hw.optional.arm.FEAT_LSE2\");\n    #[cfg(test)]\n    check!(rcpc, \"hw.optional.arm.FEAT_LRCPC\");\n    #[cfg(test)]\n    check!(rcpc2, \"hw.optional.arm.FEAT_LRCPC2\");\n    info\n}\n\n#[allow(\n    clippy::alloc_instead_of_core,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    clippy::undocumented_unsafe_blocks,\n    clippy::wildcard_imports\n)]\n#[cfg(test)]\nmod tests {\n    use std::{format, process::Command, str, string::String};\n\n    use super::*;\n\n    #[test]\n    fn test_alternative() {\n        use crate::utils::ffi::*;\n\n        const CAPS_LEN: usize = (ffi::CAP_BIT_NB + 63) / 64;\n        fn arm_caps(caps: &mut [u64; CAPS_LEN]) -> bool {\n            let mut caps_len = CAPS_LEN * 8;\n            // SAFETY:\n            // - name a valid C string.\n            // - `caps_len` does not exceed the size of `caps`.\n            // - `sysctlbyname` is thread-safe.\n            let res = unsafe {\n                ffi::sysctlbyname(\n                    c!(\"hw.optional.arm.caps\").as_ptr(),\n                    caps.as_mut_ptr().cast::<ffi::c_void>(),\n                    &mut caps_len,\n                    ptr::null_mut(),\n                    0,\n                )\n            };\n            res == 0\n        }\n\n        // Call sysctl command instead of libc API.\n        //\n        // This is used only for testing.\n        struct SysctlHwOptionalOutput(String);\n        impl SysctlHwOptionalOutput {\n            fn new() -> Self {\n                let output = Command::new(\"sysctl\").arg(\"hw.optional\").output().unwrap();\n                assert!(output.status.success());\n                let stdout = String::from_utf8(output.stdout).unwrap();\n                test_helper::eprintln_nocapture!(\"sysctl hw.optional:\\n{}\", stdout);\n                Self(stdout)\n            }\n            fn field(&self, name: &CStr) -> Option<u32> {\n                let name = name.to_bytes_with_nul();\n                let name = str::from_utf8(&name[..name.len() - 1]).unwrap();\n                let prefix = format!(\"{}: \", name);\n                Some(self.0.lines().find_map(|s| s.strip_prefix(&prefix))?.parse().unwrap())\n            }\n        }\n\n        let mut caps = [0_u64; CAPS_LEN];\n        let has_caps = arm_caps(&mut caps);\n        let sysctl_output = SysctlHwOptionalOutput::new();\n        for (name, expected_on_macos, cap_bit) in [\n            (c!(\"hw.optional.arm.FEAT_LSE\"), Some(1), ffi::CAP_BIT_FEAT_LSE),\n            (c!(\"hw.optional.armv8_1_atomics\"), Some(1), ffi::CAP_BIT_FEAT_LSE),\n            (c!(\"hw.optional.arm.FEAT_LSE2\"), Some(1), ffi::CAP_BIT_FEAT_LSE2),\n            (c!(\"hw.optional.arm.FEAT_LSE128\"), None, 0),\n            (c!(\"hw.optional.arm.FEAT_LSFE\"), None, 0),\n            (c!(\"hw.optional.arm.FEAT_LRCPC\"), Some(1), ffi::CAP_BIT_FEAT_LRCPC),\n            (c!(\"hw.optional.arm.FEAT_LRCPC2\"), Some(1), ffi::CAP_BIT_FEAT_LRCPC2),\n            (c!(\"hw.optional.arm.FEAT_LRCPC3\"), None, 0),\n        ] {\n            let res = sysctlbyname32(name);\n            if res.is_none() {\n                assert_eq!(std::io::Error::last_os_error().kind(), std::io::ErrorKind::NotFound);\n            }\n            if cfg!(any(target_os = \"macos\", target_abi = \"macabi\")) {\n                assert_eq!(\n                    res,\n                    expected_on_macos,\n                    \"{}\",\n                    str::from_utf8(name.to_bytes_with_nul()).unwrap()\n                );\n            }\n            if let Some(res) = res {\n                assert_eq!(res, sysctl_output.field(name).unwrap());\n                if has_caps {\n                    assert_eq!(caps[cap_bit / 64] & (1 << (cap_bit & 63)) != 0, res != 0);\n                }\n            } else {\n                assert!(sysctl_output.field(name).is_none());\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/detect/aarch64_fuchsia.rs",
      "sha256": "edb86bdc2630329b96396d3da23d3ee2ca55d3d45737df2de76ac2bfbce4964f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRun-time CPU feature detection on AArch64 Fuchsia by using zx_system_get_features.\n\nAs of Rust 1.94, is_aarch64_feature_detected doesn't support run-time detection on Fuchsia.\nhttps://github.com/rust-lang/rust/blob/1.94.0/library/std_detect/src/detect/mod.rs\n\nRefs:\n- https://fuchsia.dev/reference/syscalls/system_get_features\n- https://github.com/llvm/llvm-project/commit/4e731abc55681751b5d736b613f7720e50eb1ad4\n*/\n\ninclude!(\"common.rs\");\n\n#[allow(non_camel_case_types)]\nmod ffi {\n    sys_type!({\n        // https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/zircon/system/public/zircon/types.h\n        pub(crate) type zx_status_t = i32;\n    });\n\n    sys_const!({\n        // https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/zircon/system/public/zircon/errors.h\n        pub(crate) const ZX_OK: zx_status_t = 0;\n\n        // https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/zircon/system/public/zircon/features.h\n        pub(crate) const ZX_FEATURE_KIND_CPU: u32 = 0;\n        pub(crate) const ZX_ARM64_FEATURE_ISA_ATOMICS: u32 = 1 << 8;\n    });\n\n    // TODO: use sys_fn!\n    #[link(name = \"zircon\")]\n    extern \"C\" {\n        // https://fuchsia.dev/reference/syscalls/system_get_features\n        pub(crate) fn zx_system_get_features(kind: u32, features: *mut u32) -> zx_status_t;\n    }\n}\n\nfn zx_system_get_features(kind: u32) -> u32 {\n    let mut out = 0_u32;\n    // SAFETY: the pointer is valid because we got it from a reference.\n    let res = unsafe { ffi::zx_system_get_features(kind, &mut out) };\n    if res != ffi::ZX_OK {\n        return 0;\n    }\n    out\n}\n\n#[cold]\n#[must_use]\nfn _detect(mut info: CpuInfo) -> CpuInfo {\n    let features = zx_system_get_features(ffi::ZX_FEATURE_KIND_CPU);\n    macro_rules! check {\n        ($flag:ident, $bit:ident) => {\n            if features & ffi::$bit != 0 {\n                info.set(CpuInfoFlag::$flag);\n            }\n        };\n    }\n    check!(lse, ZX_ARM64_FEATURE_ISA_ATOMICS);\n    info\n}\n\n#[allow(\n    clippy::alloc_instead_of_core,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    clippy::undocumented_unsafe_blocks,\n    clippy::wildcard_imports\n)]\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_fuchsia() {\n        let features = zx_system_get_features(ffi::ZX_FEATURE_KIND_CPU);\n        test_helper::eprintln_nocapture!(\n            \"zx_system_get_features(ZX_FEATURE_KIND_CPU): {:b}\",\n            features\n        );\n        assert_ne!(features, 0);\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/detect/aarch64_illumos.rs",
      "sha256": "50b95302831a5fe2837fc13b882d6d4e92f79e05b004c4c6cd2a6402d86eefc3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRun-time CPU feature detection on AArch64 illumos by using getisax.\n\nAs of Rust 1.94, is_aarch64_feature_detected doesn't support run-time detection on illumos.\nhttps://github.com/rust-lang/rust/blob/1.94.0/library/std_detect/src/detect/mod.rs\n*/\n\ninclude!(\"common.rs\");\n\n// libc requires Rust 1.63\nmod ffi {\n    pub(crate) use crate::utils::ffi::c_uint;\n\n    sys_const!({\n        // Defined in sys/auxv_aarch64.h.\n        // https://github.com/richlowe/illumos-gate/blob/arm64-gate/usr/src/uts/common/sys/auxv_aarch64.h\n        pub(crate) const AV_AARCH64_LSE: u32 = 1 << 15;\n        #[cfg(test)]\n        pub(crate) const AV_AARCH64_LRCPC: u32 = 1 << 28;\n        #[cfg(test)]\n        pub(crate) const AV_AARCH64_2_ILRCPC: u32 = 1 << 1;\n        pub(crate) const AV_AARCH64_2_LSE2: u32 = 1 << 2;\n    });\n\n    sys_fn!({\n        extern \"C\" {\n            // Defined in sys/auxv.h.\n            // https://illumos.org/man/2/getisax\n            // https://github.com/richlowe/illumos-gate/blob/arm64-gate/usr/src/uts/common/sys/auxv.h\n            pub(crate) fn getisax(array: *mut u32, n: c_uint) -> c_uint;\n        }\n    });\n}\n\n#[cold]\n#[must_use]\nfn _detect(mut info: CpuInfo) -> CpuInfo {\n    const OUT_LEN: ffi::c_uint = 2;\n    let mut out = [0_u32; OUT_LEN as usize];\n    // SAFETY: the pointer is valid because we got it from a reference.\n    unsafe {\n        ffi::getisax(out.as_mut_ptr(), OUT_LEN);\n    }\n    macro_rules! check {\n        ($x:ident, $flag:ident, $bit:ident) => {\n            if $x & ffi::$bit != 0 {\n                info.set(CpuInfoFlag::$flag);\n            }\n        };\n    }\n    let v1 = out[0];\n    check!(v1, lse, AV_AARCH64_LSE);\n    #[cfg(test)]\n    check!(v1, rcpc, AV_AARCH64_LRCPC);\n    let v2 = out[1];\n    #[cfg(test)]\n    check!(v2, rcpc2, AV_AARCH64_2_ILRCPC);\n    check!(v2, lse2, AV_AARCH64_2_LSE2);\n    info\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/detect/aarch64_windows.rs",
      "sha256": "2cfc29df37c09aa8685b47e4973ab11fdb18f66ca9bbc2346e2713ef6898e1e1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRun-time CPU feature detection on AArch64 Windows by using IsProcessorFeaturePresent.\n\nRun-time detection of FEAT_LSE on Windows by is_aarch64_feature_detected is supported on Rust 1.70+.\nhttps://github.com/rust-lang/stdarch/pull/1373\n\nRefs: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent\n*/\n\ninclude!(\"common.rs\");\n\n// windows-sys requires Rust 1.71\n#[allow(non_camel_case_types, clippy::upper_case_acronyms)]\nmod ffi {\n    sys_type!({\n        pub(crate) type [Win32::System::Threading] PROCESSOR_FEATURE_ID = u32;\n        pub(crate) type [core] BOOL = i32;\n    });\n\n    sys_const!({\n        pub(crate) const [Win32::Foundation] FALSE: BOOL = 0;\n\n        // Defined in winnt.h of Windows SDK.\n        pub(crate) const [Win32::System::Threading]\n            PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE: PROCESSOR_FEATURE_ID = 34;\n        #[cfg(test)]\n        pub(crate) const [Win32::System::Threading]\n            PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE: PROCESSOR_FEATURE_ID = 45;\n    });\n    // TODO: put in sys_const! once windows-sys updated.\n    pub(crate) const PF_ARM_LSE2_AVAILABLE: PROCESSOR_FEATURE_ID = 62;\n\n    sys_fn!({\n        extern \"system\" {\n            // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent\n            pub(crate) fn [Win32::System::Threading] IsProcessorFeaturePresent(\n                ProcessorFeature: PROCESSOR_FEATURE_ID,\n            ) -> BOOL;\n        }\n    });\n}\n\n#[cold]\n#[must_use]\nfn _detect(mut info: CpuInfo) -> CpuInfo {\n    macro_rules! check {\n        ($flag:ident, $bit:ident) => {\n            // SAFETY: calling IsProcessorFeaturePresent is safe, and FALSE is also\n            // returned if the HAL does not support detection of the specified feature.\n            if unsafe { ffi::IsProcessorFeaturePresent(ffi::$bit) != ffi::FALSE } {\n                info.set(CpuInfoFlag::$flag);\n            }\n        };\n    }\n    check!(lse, PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE);\n    check!(lse2, PF_ARM_LSE2_AVAILABLE);\n    #[cfg(test)]\n    check!(rcpc, PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE);\n    info\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/detect/auxv.rs",
      "sha256": "4897e7d126b69bc7d8121bdc7516aca794c361ed767d6031e61b1e4456f9cae6",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRun-time CPU feature detection on AArch64/Arm/PowerPC64 Linux/Android/FreeBSD/OpenBSD by parsing ELF auxiliary vectors.\n\nSupported platforms:\n- Linux 6.4+ (through prctl)\n  https://github.com/torvalds/linux/commit/ddc65971bb677aa9f6a4c21f76d3133e106f88eb\n  prctl returns an unsupported error if operation is not supported,\n  so we can safely use this on older versions.\n- glibc 2.16+ (through getauxval)\n  https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;hb=glibc-2.16#l83\n  Always available on:\n  - aarch64 (glibc 2.17+ https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;hb=glibc-2.17#l36)\n  - powerpc64 (le) (glibc 2.19+ or RHEL/CentOS's patched glibc 2.17+ https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;hb=glibc-2.19#l108)\n  Not always available on:\n  - arm (glibc 2.1+ https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;hb=glibc-2.1#l97)\n  - powerpc64 (be) (glibc 2.3+ https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;hb=glibc-2.3#l56)\n  Since Rust 1.64, std requires glibc 2.17+ https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements\n- musl 1.1.0+ (through getauxval)\n  https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.0#n1197\n  Always available on:\n  - aarch64 (musl 1.1.7+ https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.7#n1422)\n  - powerpc64 (musl 1.1.15+ https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.15#n1702)\n  Not always available on:\n  - arm (musl 0.8.3+ https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v0.8.3#n354)\n  At least since Rust 1.15, std requires musl 1.1.14+ https://github.com/rust-lang/rust/blob/1.15.0/src/ci/docker/x86_64-musl/build-musl.sh#L15\n  Since Rust 1.18, std requires musl 1.1.16+ https://github.com/rust-lang/rust/pull/41089\n  Since Rust 1.23, std requires musl 1.1.17+ https://github.com/rust-lang/rust/pull/45393\n  Since Rust 1.25, std requires musl 1.1.18+ https://github.com/rust-lang/rust/pull/47283\n  Since Rust 1.29, std requires musl 1.1.19+ https://github.com/rust-lang/rust/pull/52087\n  Since Rust 1.31, std requires musl 1.1.20+ https://github.com/rust-lang/rust/pull/54430\n  Since Rust 1.37, std requires musl 1.1.22+ https://github.com/rust-lang/rust/pull/61252\n  Since Rust 1.46, std requires musl 1.1.24+ https://github.com/rust-lang/rust/pull/73089\n  Since Rust 1.71, std requires musl 1.2.3+ https://blog.rust-lang.org/2023/05/09/Updating-musl-targets\n  Since Rust 1.93, std requires musl 1.2.5+ https://blog.rust-lang.org/2025/12/05/Updating-musl-1.2.5/\n  OpenHarmony uses a fork of musl 1.2 https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/native-lib/musl.md\n- uClibc-ng 1.0.43+ (through getauxval)\n  https://github.com/wbx-github/uclibc-ng/commit/d869bb1600942c01a77539128f9ba5b5b55ad647\n  Not always available on:\n  - aarch64 (uClibc-ng 1.0.22+ https://github.com/wbx-github/uclibc-ng/commit/dba942c80dc2cfa5768a856fff98e22a755fdd27)\n  - arm (uClibc-ng 1.0.0+ https://github.com/wbx-github/uclibc-ng/tree/v1.0.0/libc/sysdeps/linux)\n  (powerpc64 is not supported https://github.com/wbx-github/uclibc-ng/commit/d4d4f37fda7fa57e57132ff2f0d735ce7cc2178e)\n- Picolibc 1.4.6+ (through getauxval)\n  https://github.com/picolibc/picolibc/commit/19bfe51d62ad7e32533c7f664b5bca8e26286e31\n  The implementation always return 0 (as of 1.8.12): https://github.com/picolibc/picolibc/blob/1.8.12/libc/misc/getauxval.c\n- Android 4.3+ (API level 18+) (through getauxval)\n  https://android.googlesource.com/platform/bionic.git/+/2c5153b043b44e9935a334ae9b2d5a4bc5258b40\n  https://android.googlesource.com/platform/bionic.git/+/655e430b28d7404f763e7ebefe84fba5a387666d\n  Always available on:\n  - 64-bit architectures (Android 5.0+ (API level 21+) https://android-developers.googleblog.com/2014/10/whats-new-in-android-50-lollipop.html)\n  Not always available on:\n  - arm\n  Since Rust 1.68, std requires API level 19+ https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25\n  Since Rust 1.82, std requires API level 21+ https://github.com/rust-lang/rust/pull/120593\n- FreeBSD 12.0+ and 11.4+ (through elf_aux_info)\n  https://github.com/freebsd/freebsd-src/commit/0b08ae2120cdd08c20a2b806e2fcef4d0a36c470\n  https://github.com/freebsd/freebsd-src/blob/release/11.4.0/sys/sys/auxv.h\n  Always available on:\n  - arm (v7) (FreeBSD 12.0+ https://www.freebsd.org/releases/12.0R/announce, https://man.freebsd.org/cgi/man.cgi?arch)\n  - powerpc64 (le) (FreeBSD 12.4+ https://www.freebsd.org/releases/12.4R/announce, https://man.freebsd.org/cgi/man.cgi?arch)\n  Not always available on:\n  - aarch64 (FreeBSD 11.0+ https://www.freebsd.org/releases/11.0R/announce, https://man.freebsd.org/cgi/man.cgi?arch)\n  - arm (v6) (FreeBSD 10.1+ https://www.freebsd.org/releases/10.1R/announce, https://man.freebsd.org/cgi/man.cgi?arch)\n  - powerpc64 (be) (FreeBSD 9.0+ https://www.freebsd.org/releases/9.0R/announce, https://man.freebsd.org/cgi/man.cgi?arch)\n  Since Rust 1.75, std requires FreeBSD 12+ https://github.com/rust-lang/rust/pull/114521\n  Since Rust 1.97, std requires FreeBSD 14+ https://github.com/rust-lang/rust/pull/156607\n- OpenBSD 7.6+ (through elf_aux_info)\n  https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d\n  Not always available on:\n  - aarch64 (OpenBSD 6.1+ https://www.openbsd.org/61.html)\n  - arm (OpenBSD 6.0+ https://www.openbsd.org/60.html)\n  - powerpc64 (OpenBSD 6.8+ https://www.openbsd.org/68.html)\n\nOn L4Re which uses uClibc-ng, a dummy getauxval was added first in 2020 that always returns 0 (https://github.com/kernkonzept/l4re-core/commit/e88fa67198074d3e6b4983c5c8af1538e2089ff3),\nthen implemented in 2024 (https://github.com/kernkonzept/l4re-core/commit/3ee2a50dd1b3bc22955e593004990887a0a5b4a3).\nHowever, getauxval(AT_HWCAP*) always returns 0 (as of 2025-12-25). (see tests/l4re test)\nOn Redox, getauxval is available since 0.5.0 (https://github.com/redox-os/relibc/commit/f9f752d74c4f1f56a89c0fcdd5cab63d2380fe09),\nbut the implementation always return 0 (as of 2026-08-08): https://github.com/redox-os/relibc/blob/49aeb9470a885030ed43a70d0b708f3caec19478/src/header/sys_auxv/mod.rs\n\nOn platforms that we can assume that getauxval/elf_aux_info is always available, we directly call\nthem on except for musl with static linking. (At this time, we also retain compatibility with\nversions that reached EoL or no longer supported by `std`, with the exception of AArch64 FreeBSD described below.)\n\nOn musl with static linking, it seems that getauxval is not always available, independent of version\nrequirements: https://github.com/rust-lang/rust/issues/89626\n(That problem may have been fixed in https://github.com/rust-lang/rust/commit/9a04ae4997493e9260352064163285cddc43de3c,\nbut even in the version containing that patch, [there is report](https://github.com/rust-lang/rust/issues/89626#issuecomment-1242636038)\nof the same error.)\nThis seems to be due to the fact that compiler-builtins is built before libc (which is a dependency\nof std) links musl. And the std and its dependent can use getauxval without this problem at least\nsince the rust-lang/rust patch mentioned above:\nhttps://github.com/rust-lang/rust/blob/1.85.0/library/std/src/sys/pal/unix/stack_overflow.rs#L268\n(According to https://github.com/rust-lang/rust/issues/89626#issuecomment-2420469392, this problem\nmay have been fixed in https://github.com/rust-lang/rust/commit/9ed0d11efbec18a1fa4155576a3bcb685676d23c.)\nSee also https://github.com/rust-lang/stdarch/pull/1746.\nSo as for musl with static linking, we assume that getauxval is always available also when `std` feature enabled.\n\nOn platforms that we cannot assume that getauxval/elf_aux_info is always available, so we use dlsym\ninstead of directly calling getauxval/elf_aux_info. (You can force getauxval/elf_aux_info to be\ncalled directly instead of using dlsym by `--cfg portable_atomic_outline_atomics`).\n\nAlso, note that dlsym usually not working with static linking.\n\n# Linux/Android\n\nAs of Rust 1.69, is_aarch64_feature_detected always uses dlsym by default\non AArch64 Linux/Android, but on some platforms, we can safely assume\ngetauxval is linked to the binary (see the above).\n\nSee also https://github.com/rust-lang/stdarch/pull/1375\n\nSee tests::test_alternative and aarch64_aa64reg.rs for (test-only) alternative implementations.\n\n# FreeBSD\n\nAs of Rust 1.94, is_aarch64_feature_detected always uses mrs on\nAArch64 FreeBSD. However, they do not work on FreeBSD 12 on QEMU (confirmed\non FreeBSD 12.{2,3,4}), and we got SIGILL (worked on FreeBSD 13 and 14).\n\nSo use elf_aux_info instead of mrs like compiler-rt does.\nhttps://reviews.llvm.org/D109330\n\nelf_aux_info is available on FreeBSD 12.0+ and 11.4+:\nhttps://github.com/freebsd/freebsd-src/commit/0b08ae2120cdd08c20a2b806e2fcef4d0a36c470\nhttps://github.com/freebsd/freebsd-src/blob/release/11.4.0/sys/sys/auxv.h\nOn FreeBSD, [AArch64 support is available on FreeBSD 11.0+](https://www.freebsd.org/releases/11.0R/announce),\nbut FreeBSD 11 (11.4) was EoL on 2021-09-30, and FreeBSD 11.3 was EoL on 2020-09-30:\nhttps://www.freebsd.org/security/unsupported\nSee also https://github.com/rust-lang/stdarch/pull/611#issuecomment-445464613\n\nSee tests::test_alternative and aarch64_aa64reg.rs for (test-only) alternative implementations.\n\n# OpenBSD\n\nelf_aux_info is available on OpenBSD 7.6+:\nhttps://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d\n\nOn AArch64, there is an alternative that available on older version,\nso we use it (see aarch64_aa64reg.rs).\n\n*/\n\ninclude!(\"common.rs\");\n\nuse self::os::ffi;\n#[cfg(any(target_os = \"linux\", target_os = \"android\"))]\nmod os {\n    // libc requires Rust 1.63\n    #[cfg_attr(test, allow(dead_code))]\n    pub(super) mod ffi {\n        pub(crate) use crate::utils::ffi::c_ulong;\n        #[allow(unused_imports)]\n        pub(crate) use crate::utils::ffi::{c_char, c_int, c_void};\n\n        sys_const!({\n            // https://github.com/torvalds/linux/blob/v6.19/include/uapi/linux/auxvec.h\n            pub(crate) const AT_HWCAP: c_ulong = 16;\n            #[cfg(any(\n                test,\n                all(target_arch = \"aarch64\", target_pointer_width = \"64\"),\n                target_arch = \"powerpc64\",\n            ))]\n            pub(crate) const AT_HWCAP2: c_ulong = 26;\n            // Linux 6.9+\n            // https://github.com/torvalds/linux/commit/3281366a8e79a512956382885091565db1036b64\n            #[cfg(test)]\n            #[cfg(not(all(target_arch = \"aarch64\", target_pointer_width = \"32\")))]\n            pub(crate) const AT_HWCAP3: c_ulong = 29;\n            #[cfg(test)]\n            #[cfg(not(all(target_arch = \"aarch64\", target_pointer_width = \"32\")))]\n            pub(crate) const AT_HWCAP4: c_ulong = 30;\n\n            // Defined in dlfcn.h.\n            // https://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlfcn.h;hb=glibc-2.43\n            // https://git.musl-libc.org/cgit/musl/tree/include/dlfcn.h?h=v1.2.5\n            // https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/dlfcn.h\n            // https://github.com/kernkonzept/l4re-core/blob/r-2026-W07/libc/uclibc-ng/contrib/uclibc/include/dlfcn.h\n            // https://android.googlesource.com/platform/bionic.git/+/refs/tags/android-16.0.0_r1/libc/include/dlfcn.h\n            #[cfg(any(\n                test,\n                not(any(\n                    all(\n                        target_os = \"linux\",\n                        any(\n                            all(\n                                target_env = \"gnu\",\n                                any(\n                                    target_arch = \"aarch64\",\n                                    all(target_arch = \"powerpc64\", target_endian = \"little\"),\n                                ),\n                            ),\n                            target_env = \"musl\",\n                            target_env = \"ohos\",\n                        ),\n                    ),\n                    all(target_os = \"android\", target_pointer_width = \"64\"),\n                    portable_atomic_outline_atomics,\n                )),\n            ))]\n            #[cfg(not(all(target_os = \"android\", target_pointer_width = \"32\")))]\n            pub(crate) const RTLD_DEFAULT: *mut c_void = core::ptr::null_mut();\n            #[cfg(all(target_os = \"android\", target_pointer_width = \"32\"))]\n            #[allow(clippy::cast_sign_loss)]\n            pub(crate) const RTLD_DEFAULT: *mut c_void =\n                crate::utils::ptr::without_provenance_mut(-1_isize as usize);\n\n            // Defined in sys/system_properties.h.\n            // https://android.googlesource.com/platform/bionic.git/+/refs/tags/android-16.0.0_r1/libc/include/sys/system_properties.h\n            #[cfg(all(target_arch = \"aarch64\", target_os = \"android\"))]\n            pub(crate) const PROP_VALUE_MAX: c_int = 92;\n        });\n\n        sys_fn!({\n            extern \"C\" {\n                // Defined in sys/auxv.h.\n                // https://man7.org/linux/man-pages/man3/getauxval.3.html\n                // https://sourceware.org/git/?p=glibc.git;a=blob;f=misc/sys/auxv.h;hb=glibc-2.43\n                // https://git.musl-libc.org/cgit/musl/tree/include/sys/auxv.h?h=v1.2.5\n                // https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/sys/auxv.h\n                // https://github.com/kernkonzept/l4re-core/blob/r-2026-W07/libc/uclibc-ng/contrib/uclibc/include/sys/auxv.h\n                // https://android.googlesource.com/platform/bionic.git/+/refs/tags/android-16.0.0_r1/libc/include/sys/auxv.h\n                // https://github.com/picolibc/picolibc/blob/1.8.12/libc/include/sys/auxv.h\n                #[cfg(any(\n                    test,\n                    all(\n                        target_os = \"linux\",\n                        any(\n                            all(\n                                target_env = \"gnu\",\n                                any(\n                                    target_arch = \"aarch64\",\n                                    all(target_arch = \"powerpc64\", target_endian = \"little\"),\n                                ),\n                            ),\n                            target_env = \"musl\",\n                            target_env = \"ohos\",\n                        ),\n                    ),\n                    all(target_os = \"android\", target_pointer_width = \"64\"),\n                    portable_atomic_outline_atomics,\n                ))]\n                pub(crate) fn getauxval(type_: c_ulong) -> c_ulong;\n\n                // Defined in dlfcn.h.\n                // https://man7.org/linux/man-pages/man3/dlsym.3.html\n                // https://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlfcn.h;hb=glibc-2.43\n                // https://git.musl-libc.org/cgit/musl/tree/include/dlfcn.h?h=v1.2.5\n                // https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/dlfcn.h\n                // https://github.com/kernkonzept/l4re-core/blob/r-2026-W07/libc/uclibc-ng/contrib/uclibc/include/dlfcn.h\n                // https://android.googlesource.com/platform/bionic.git/+/refs/tags/android-16.0.0_r1/libc/include/dlfcn.h\n                #[cfg(any(\n                    test,\n                    not(any(\n                        all(\n                            target_os = \"linux\",\n                            any(\n                                all(\n                                    target_env = \"gnu\",\n                                    any(\n                                        target_arch = \"aarch64\",\n                                        all(target_arch = \"powerpc64\", target_endian = \"little\"),\n                                    ),\n                                ),\n                                target_env = \"musl\",\n                                target_env = \"ohos\",\n                            ),\n                        ),\n                        all(target_os = \"android\", target_pointer_width = \"64\"),\n                        portable_atomic_outline_atomics,\n                    )),\n                ))]\n                pub(crate) fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void;\n\n                // Defined in sys/system_properties.h.\n                // https://android.googlesource.com/platform/bionic.git/+/refs/tags/android-16.0.0_r1/libc/include/sys/system_properties.h\n                #[cfg(all(target_arch = \"aarch64\", target_os = \"android\"))]\n                pub(crate) fn __system_property_get(\n                    name: *const c_char,\n                    value: *mut c_char,\n                ) -> c_int;\n            }\n        });\n    }\n\n    pub(super) type GetauxvalTy = unsafe extern \"C\" fn(ffi::c_ulong) -> ffi::c_ulong;\n    pub(super) fn getauxval(type_: ffi::c_ulong) -> ffi::c_ulong {\n        cfg_sel!({\n            #[cfg(any(\n                all(\n                    target_os = \"linux\",\n                    any(\n                        all(\n                            target_env = \"gnu\",\n                            any(\n                                target_arch = \"aarch64\",\n                                all(target_arch = \"powerpc64\", target_endian = \"little\"),\n                            ),\n                        ),\n                        target_env = \"musl\",\n                        target_env = \"ohos\",\n                    ),\n                ),\n                all(target_os = \"android\", target_pointer_width = \"64\"),\n                portable_atomic_outline_atomics,\n            ))]\n            {\n                let getauxval: GetauxvalTy = ffi::getauxval;\n            }\n            #[cfg(else)]\n            {\n                // SAFETY: we passed a valid C string to dlsym, and a pointer returned by dlsym\n                // is a valid pointer to the function if it is non-null.\n                let getauxval: GetauxvalTy = unsafe {\n                    let ptr = ffi::dlsym(ffi::RTLD_DEFAULT, c!(\"getauxval\").as_ptr());\n                    if ptr.is_null() {\n                        return 0;\n                    }\n                    core::mem::transmute::<*mut ffi::c_void, GetauxvalTy>(ptr)\n                };\n            }\n        });\n\n        // SAFETY: `getauxval` is thread-safe.\n        unsafe { getauxval(type_) }\n    }\n}\n#[cfg(any(target_os = \"freebsd\", target_os = \"openbsd\"))]\nmod os {\n    use core::mem;\n\n    // libc requires Rust 1.63\n    #[cfg_attr(test, allow(dead_code))]\n    pub(super) mod ffi {\n        #[allow(unused_imports)]\n        pub(crate) use crate::utils::ffi::c_char;\n        pub(crate) use crate::utils::ffi::{c_int, c_ulong, c_void};\n\n        sys_const!({\n            // FreeBSD\n            // Defined in sys/elf_common.h.\n            // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/sys/sys/elf_common.h\n            // OpenBSD\n            // Defined in sys/auxv.h.\n            // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/sys/auxv.h\n            pub(crate) const AT_HWCAP: c_int = 25;\n            #[cfg(any(\n                test,\n                all(target_os = \"freebsd\", target_arch = \"aarch64\", target_pointer_width = \"64\"),\n                target_arch = \"powerpc64\",\n            ))]\n            pub(crate) const AT_HWCAP2: c_int = 26;\n            // FreeBSD 15.0+\n            // https://github.com/freebsd/freebsd-src/commit/85007872d1227006adf2ce119fe30de856cbe12d\n            #[cfg(test)]\n            #[cfg(not(target_os = \"openbsd\"))]\n            pub(crate) const AT_HWCAP3: c_int = 38;\n            #[cfg(test)]\n            #[cfg(not(target_os = \"openbsd\"))]\n            pub(crate) const AT_HWCAP4: c_int = 39;\n\n            // FreeBSD\n            // Defined in dlfcn.h.\n            // https://man.freebsd.org/dlsym(3)\n            // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/include/dlfcn.h\n            // OpenBSD\n            // Defined in dlfcn.h.\n            // https://man.openbsd.org/dlsym.3\n            // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/include/dlfcn.h\n            #[cfg(any(\n                test,\n                not(any(\n                    all(\n                        target_os = \"freebsd\",\n                        any(\n                            target_arch = \"aarch64\",\n                            all(target_arch = \"powerpc64\", target_endian = \"little\"),\n                        ),\n                    ),\n                    portable_atomic_outline_atomics,\n                )),\n            ))]\n            #[allow(clippy::cast_sign_loss)]\n            pub(crate) const RTLD_DEFAULT: *mut c_void =\n                crate::utils::ptr::without_provenance_mut(-2_isize as usize);\n        });\n\n        sys_fn!({\n            extern \"C\" {\n                // FreeBSD\n                // Defined in sys/auxv.h.\n                // https://man.freebsd.org/elf_aux_info(3)\n                // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/sys/sys/auxv.h\n                // OpenBSD\n                // Defined in sys/auxv.h.\n                // https://man.openbsd.org/elf_aux_info.3\n                // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/sys/auxv.h\n                #[cfg(any(\n                    test,\n                    any(\n                        all(\n                            target_os = \"freebsd\",\n                            any(\n                                target_arch = \"aarch64\",\n                                all(target_arch = \"powerpc64\", target_endian = \"little\"),\n                            ),\n                        ),\n                        portable_atomic_outline_atomics,\n                    ),\n                ))]\n                pub(crate) fn elf_aux_info(aux: c_int, buf: *mut c_void, buf_len: c_int) -> c_int;\n\n                // FreeBSD\n                // Defined in dlfcn.h.\n                // https://man.freebsd.org/dlsym(3)\n                // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/include/dlfcn.h\n                // OpenBSD\n                // Defined in dlfcn.h.\n                // https://man.openbsd.org/dlsym.3\n                // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/include/dlfcn.h\n                #[cfg(any(\n                    test,\n                    not(any(\n                        all(\n                            target_os = \"freebsd\",\n                            any(\n                                target_arch = \"aarch64\",\n                                all(target_arch = \"powerpc64\", target_endian = \"little\"),\n                            ),\n                        ),\n                        portable_atomic_outline_atomics,\n                    )),\n                ))]\n                pub(crate) fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void;\n            }\n        });\n    }\n\n    pub(super) type ElfAuxInfoTy =\n        unsafe extern \"C\" fn(ffi::c_int, *mut ffi::c_void, ffi::c_int) -> ffi::c_int;\n    pub(super) fn getauxval(aux: ffi::c_int) -> ffi::c_ulong {\n        #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)]\n        const OUT_LEN: ffi::c_int = mem::size_of::<ffi::c_ulong>() as ffi::c_int;\n\n        cfg_sel!({\n            #[cfg(any(\n                all(\n                    target_os = \"freebsd\",\n                    any(\n                        target_arch = \"aarch64\",\n                        all(target_arch = \"powerpc64\", target_endian = \"little\"),\n                    ),\n                ),\n                portable_atomic_outline_atomics,\n            ))]\n            {\n                let elf_aux_info: ElfAuxInfoTy = ffi::elf_aux_info;\n            }\n            #[cfg(else)]\n            {\n                // SAFETY: we passed a valid C string to dlsym, and a pointer returned by dlsym\n                // is a valid pointer to the function if it is non-null.\n                let elf_aux_info: ElfAuxInfoTy = unsafe {\n                    let ptr = ffi::dlsym(ffi::RTLD_DEFAULT, c!(\"elf_aux_info\").as_ptr());\n                    if ptr.is_null() {\n                        return 0;\n                    }\n                    mem::transmute::<*mut ffi::c_void, ElfAuxInfoTy>(ptr)\n                };\n            }\n        });\n\n        let mut out: ffi::c_ulong = 0;\n        // SAFETY:\n        // - the pointer is valid because we got it from a reference.\n        // - `OUT_LEN` is the same as the size of `out`.\n        // - `elf_aux_info` is thread-safe.\n        let res = unsafe {\n            elf_aux_info(aux, (&mut out as *mut ffi::c_ulong).cast::<ffi::c_void>(), OUT_LEN)\n        };\n        // If elf_aux_info fails, `out` will be left at zero (which is the proper default value).\n        debug_assert!(res == 0 || out == 0);\n        out\n    }\n}\n\n// Basically, Linux/FreeBSD/OpenBSD use the same hwcap values.\n// FreeBSD and OpenBSD usually support a subset of the hwcap values supported by Linux.\nuse self::arch::_detect;\n#[cfg(target_arch = \"aarch64\")]\nmod arch {\n    use super::{CpuInfo, CpuInfoFlag, ffi, os};\n\n    sys_const!({\n        // Linux\n        // https://github.com/torvalds/linux/blob/v6.19/arch/arm64/include/uapi/asm/hwcap.h\n        // https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/arm64/elf_hwcaps.rst\n        // FreeBSD\n        // Defined in machine/elf.h.\n        // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/sys/arm64/include/elf.h\n        // OpenBSD\n        // Defined in machine/elf.h.\n        // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/arch/arm64/include/elf.h\n        // Linux 4.3+\n        // https://github.com/torvalds/linux/commit/40a1db2434a1b62332b1af25cfa14d7b8c0301fe\n        // FreeBSD 13.0+/12.2+\n        // https://github.com/freebsd/freebsd-src/blob/release/13.0.0/sys/arm64/include/elf.h\n        // https://github.com/freebsd/freebsd-src/blob/release/12.2.0/sys/arm64/include/elf.h\n        // OpenBSD 7.6+\n        // https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d\n        pub(crate) const HWCAP_ATOMICS: ffi::c_ulong = 1 << 8;\n        // Linux 4.11+\n        // https://github.com/torvalds/linux/commit/77c97b4ee21290f5f083173d957843b615abbff2\n        // FreeBSD 13.0+/12.2+\n        // https://github.com/freebsd/freebsd-src/blob/release/13.0.0/sys/arm64/include/elf.h\n        // https://github.com/freebsd/freebsd-src/blob/release/12.2.0/sys/arm64/include/elf.h\n        // OpenBSD 7.6+\n        // https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d\n        #[cfg(test)]\n        pub(crate) const HWCAP_CPUID: ffi::c_ulong = 1 << 11;\n        // Linux 4.12+\n        // https://github.com/torvalds/linux/commit/c651aae5a7732287c1c9bc974ece4ed798780544\n        // FreeBSD 13.0+/12.2+\n        // https://github.com/freebsd/freebsd-src/blob/release/13.0.0/sys/arm64/include/elf.h\n        // https://github.com/freebsd/freebsd-src/blob/release/12.2.0/sys/arm64/include/elf.h\n        // OpenBSD 7.6+\n        // https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d\n        #[cfg(test)]\n        pub(crate) const HWCAP_LRCPC: ffi::c_ulong = 1 << 15;\n        // Linux 4.17+\n        // https://github.com/torvalds/linux/commit/7206dc93a58fb76421c4411eefa3c003337bcb2d\n        // FreeBSD 13.0+/12.2+\n        // https://github.com/freebsd/freebsd-src/blob/release/13.0.0/sys/arm64/include/elf.h\n        // https://github.com/freebsd/freebsd-src/blob/release/12.2.0/sys/arm64/include/elf.h\n        // OpenBSD 7.6+\n        // https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d\n        pub(crate) const HWCAP_USCAT: ffi::c_ulong = 1 << 25;\n        #[cfg(test)]\n        pub(crate) const HWCAP_ILRCPC: ffi::c_ulong = 1 << 26;\n        // Linux 6.7+\n        // https://github.com/torvalds/linux/commit/338a835f40a849cd89b993e342bd9fbd5684825c\n        // FreeBSD 15.0+\n        // https://github.com/freebsd/freebsd-src/commit/94686b081fdb0c1bb0fc1dfeda14bd53f26ce7c5\n        #[cfg(not(target_os = \"openbsd\"))]\n        #[cfg(target_pointer_width = \"64\")]\n        pub(crate) const HWCAP2_LRCPC3: ffi::c_ulong = 1 << 46;\n        // Linux 6.7+\n        // https://github.com/torvalds/linux/commit/94d0657f9f0d311489606589133ebf49e28104d8\n        // FreeBSD 15.0+\n        // https://github.com/freebsd/freebsd-src/commit/94686b081fdb0c1bb0fc1dfeda14bd53f26ce7c5\n        #[cfg(not(target_os = \"openbsd\"))]\n        #[cfg(target_pointer_width = \"64\")]\n        pub(crate) const HWCAP2_LSE128: ffi::c_ulong = 1 << 47;\n        // Linux 6.18+\n        // https://github.com/torvalds/linux/commit/220928e52cb03d223b3acad3888baf0687486d21\n        // FreeBSD 16.0+\n        // https://github.com/freebsd/freebsd-src/commit/3a960425df759a7bb8f946d23f035c63f3a5de7a\n        #[cfg(test)]\n        #[cfg(not(target_os = \"openbsd\"))]\n        #[cfg(target_pointer_width = \"64\")]\n        pub(crate) const HWCAP3_LSFE: ffi::c_ulong = 1 << 2;\n    });\n\n    #[cold]\n    #[must_use]\n    pub(crate) fn _detect(mut info: CpuInfo) -> CpuInfo {\n        #[cfg(target_os = \"android\")]\n        {\n            // Samsung Exynos 9810 has a bug that big and little cores have different\n            // ISAs. And on older Android (pre-9), the kernel incorrectly reports\n            // that features available only on some cores are available on all cores.\n            // https://reviews.llvm.org/D114523\n            let mut arch = [0_u8; ffi::PROP_VALUE_MAX as usize];\n            // SAFETY: we've passed a valid C string and a buffer with max length.\n            let len = unsafe {\n                ffi::__system_property_get(\n                    c!(\"ro.arch\").as_ptr(),\n                    arch.as_mut_ptr().cast::<ffi::c_char>(),\n                )\n            };\n            // On Exynos, ro.arch is not available on Android 12+, but it is fine\n            // because Android 9+ includes the fix.\n            if len > 0 && arch.starts_with(b\"exynos9810\") {\n                return info;\n            }\n        }\n\n        macro_rules! check {\n            ($x:ident, $flag:ident, $bit:ident) => {\n                if $x & $bit != 0 {\n                    info.set(CpuInfoFlag::$flag);\n                }\n            };\n        }\n        let hwcap = os::getauxval(ffi::AT_HWCAP);\n        check!(hwcap, lse, HWCAP_ATOMICS);\n        check!(hwcap, lse2, HWCAP_USCAT);\n        #[cfg(test)]\n        check!(hwcap, rcpc, HWCAP_LRCPC);\n        #[cfg(test)]\n        check!(hwcap, rcpc2, HWCAP_ILRCPC);\n        #[cfg(test)]\n        check!(hwcap, cpuid, HWCAP_CPUID);\n        #[cfg(not(target_os = \"openbsd\"))]\n        // HWCAP2 is not yet available on ILP32: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/tree/arch/arm64/include/uapi/asm/hwcap.h?h=staging/ilp32-5.1\n        #[cfg(target_pointer_width = \"64\")]\n        {\n            let hwcap2 = os::getauxval(ffi::AT_HWCAP2);\n            check!(hwcap2, rcpc3, HWCAP2_LRCPC3);\n            check!(hwcap2, lse128, HWCAP2_LSE128);\n            #[cfg(test)]\n            {\n                let hwcap3 = os::getauxval(ffi::AT_HWCAP3);\n                check!(hwcap3, lsfe, HWCAP3_LSFE);\n            }\n        }\n        info\n    }\n}\n#[cfg(target_arch = \"arm\")]\nmod arch {\n    use super::{CpuInfo, CpuInfoFlag, ffi, os};\n\n    sys_const!({\n        // Linux\n        // https://github.com/torvalds/linux/blob/v6.19/arch/arm/include/uapi/asm/hwcap.h\n        // FreeBSD\n        // Defined in machine/elf.h.\n        // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/sys/arm/include/elf.h\n        // OpenBSD\n        // Defined in machine/elf.h.\n        // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/arch/arm/include/elf.h\n        // Linux 3.11+\n        // https://github.com/torvalds/linux/commit/a469abd0f868c902b75532579bf87553dcf1b360\n        // FreeBSD 12.0+/11.2+\n        // https://github.com/freebsd/freebsd-src/commit/0cbf724ed03571bc90ed22c3b4bf8c6c7b2da564\n        // https://github.com/freebsd/freebsd-src/blob/release/11.2.0/sys/arm/include/elf.h\n        // OpenBSD 7.6+\n        // https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d\n        #[cfg(test)]\n        pub(crate) const HWCAP_LPAE: ffi::c_ulong = 1 << 20;\n    });\n\n    #[cold]\n    #[must_use]\n    pub(crate) fn _detect(mut info: CpuInfo) -> CpuInfo {\n        macro_rules! check {\n            ($x:ident, $flag:ident, $($bit:ident) ||+) => {\n                if $x & ($($bit) |+) != 0 {\n                    info.set(CpuInfoFlag::$flag);\n                }\n            };\n            ($x:ident, $flag:ident, $($bit:ident) &&+) => {\n                if $x & ($($bit) |+) == ($($bit) |+) {\n                    info.set(CpuInfoFlag::$flag);\n                }\n            };\n        }\n        let hwcap = os::getauxval(ffi::AT_HWCAP);\n        #[cfg(test)]\n        check!(hwcap, lpae, HWCAP_LPAE);\n        info\n    }\n}\n#[cfg(target_arch = \"powerpc64\")]\nmod arch {\n    use super::{CpuInfo, CpuInfoFlag, ffi, os};\n\n    sys_const!({\n        // Linux\n        // https://github.com/torvalds/linux/blob/v6.19/arch/powerpc/include/uapi/asm/cputable.h\n        // https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/powerpc/elf_hwcaps.rst\n        // FreeBSD\n        // Defined in machine/cpu.h.\n        // https://github.com/freebsd/freebsd-src/blob/release/15.1.0/sys/powerpc/include/cpu.h\n        // OpenBSD\n        // Defined in machine/elf.h.\n        // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/arch/powerpc64/include/elf.h\n        // Linux 2.6.16+\n        // https://github.com/torvalds/linux/commit/80f15dc703b3677d0b025bafd215f1f3664c8978\n        // FreeBSD 11.0+\n        // https://github.com/freebsd/freebsd-src/commit/b0bf7fcd298133457991b27625bbed766e612730\n        // OpenBSD 7.6+\n        // https://github.com/openbsd/src/commit/0b0568a19fc4c197871ceafbabc91fabf17ca152\n        pub(crate) const PPC_FEATURE_BOOKE: ffi::c_ulong = 0x00008000;\n        // Linux 3.10+\n        // https://github.com/torvalds/linux/commit/cbbc6f1b1433ef553d57826eee87a84ca49645ce\n        // FreeBSD 11.0+\n        // https://github.com/freebsd/freebsd-src/commit/b0bf7fcd298133457991b27625bbed766e612730\n        // OpenBSD 7.6+\n        // https://github.com/openbsd/src/commit/0b0568a19fc4c197871ceafbabc91fabf17ca152\n        pub(crate) const PPC_FEATURE2_ARCH_2_07: ffi::c_ulong = 0x80000000;\n        // Linux 4.5+\n        // https://github.com/torvalds/linux/commit/e708c24cd01ce80b1609d8baccee40ccc3608a01\n        // FreeBSD 12.0+\n        // https://github.com/freebsd/freebsd-src/commit/18f48e0c72f91bc2d4373078a3f1ab1bcab4d8b3\n        // OpenBSD 7.6+\n        // https://github.com/openbsd/src/commit/0b0568a19fc4c197871ceafbabc91fabf17ca152\n        pub(crate) const PPC_FEATURE2_ARCH_3_00: ffi::c_ulong = 0x00800000;\n        // Linux 5.8+\n        // https://github.com/torvalds/linux/commit/ee988c11acf6f9464b7b44e9a091bf6afb3b3a49\n        // FreeBSD 15.0+/14.2+\n        // https://github.com/freebsd/freebsd-src/commit/1e434da3b065ef96b389e5e0b604ae05a51e794e\n        // https://github.com/freebsd/freebsd-src/blob/release/14.2.0/sys/powerpc/include/cpu.h\n        // OpenBSD 7.7+\n        // https://github.com/openbsd/src/commit/483a78e15aaa23c010911940770c1c97db5c1287\n        pub(crate) const PPC_FEATURE2_ARCH_3_1: ffi::c_ulong = 0x00040000;\n    });\n\n    #[cold]\n    #[must_use]\n    pub(crate) fn _detect(mut info: CpuInfo) -> CpuInfo {\n        let hwcap = os::getauxval(ffi::AT_HWCAP);\n        if hwcap & PPC_FEATURE_BOOKE != 0 {\n            // quadword-atomics (Load/Store Quadword category in ISA 2.07) is requirement of ISA 2.07\n            // server processors. It is always optional in ISA 2.07 BookE (embedded category)\n            // processors and there is no corresponding HWCAP bit. (Although there are no ISA 2.07\n            // BookE processors that appear to be supported on these platforms.)\n            // Refs: Appendix B \"Platform Support Requirements\" of Power ISA 2.07B\n            // https://ibm.ent.box.com/s/jd5w15gz301s5b5dt375mshpq9c3lh4u\n            return info;\n        }\n        let hwcap2 = os::getauxval(ffi::AT_HWCAP2);\n        // Check both 2_07 and later ISAs (which are superset of 2_07) because\n        // OpenBSD (as of 8.0-beta) doesn't set 2_07 even when 3_00 is set.\n        // https://github.com/openbsd/src/blob/d2e81eb18e50973c87ae2c9c2ba348ff3ff89cf9/sys/arch/powerpc64/powerpc64/cpu.c#L222-L238\n        // Other OSes should be fine, but check all OSs in the same way just in case.\n        let isa_2_07_or_later =\n            PPC_FEATURE2_ARCH_2_07 | PPC_FEATURE2_ARCH_3_00 | PPC_FEATURE2_ARCH_3_1;\n        if hwcap2 & isa_2_07_or_later != 0 {\n            info.set(CpuInfoFlag::quadword_atomics);\n        }\n        info\n    }\n}\n\n#[allow(\n    clippy::alloc_instead_of_core,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    clippy::undocumented_unsafe_blocks,\n    clippy::wildcard_imports\n)]\n#[cfg(test)]\nmod tests {\n    use std::mem;\n\n    use super::*;\n\n    #[allow(clippy::cast_sign_loss)]\n    #[cfg(all(target_arch = \"aarch64\", target_os = \"android\"))]\n    #[test]\n    fn test_android() {\n        use std::{slice, str};\n        unsafe {\n            let mut arch = [1; ffi::PROP_VALUE_MAX as usize];\n            let len = ffi::__system_property_get(\n                c!(\"ro.arch\").as_ptr(),\n                arch.as_mut_ptr().cast::<ffi::c_char>(),\n            );\n            assert!(len >= 0);\n            test_helper::eprintln_nocapture!(\"ro.arch=raw={:?},len={}\", arch, len);\n            test_helper::eprintln_nocapture!(\n                \"ro.arch={:?}\",\n                str::from_utf8(slice::from_raw_parts(arch.as_ptr(), len as usize)).unwrap()\n            );\n        }\n    }\n\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    #[test]\n    fn test_dlsym_getauxval() {\n        unsafe {\n            let ptr = ffi::dlsym(ffi::RTLD_DEFAULT, c!(\"getauxval\").as_ptr());\n            if cfg!(target_feature = \"crt-static\") {\n                assert!(ptr.is_null());\n            } else if cfg!(any(\n                all(\n                    target_os = \"linux\",\n                    any(target_env = \"gnu\", target_env = \"musl\", target_env = \"ohos\"),\n                ),\n                target_os = \"android\",\n            )) {\n                assert!(!ptr.is_null());\n            } else if option_env!(\"CI\").is_some() {\n                assert!(ptr.is_null());\n            }\n            if ptr.is_null() {\n                return;\n            }\n            let dlsym_getauxval = mem::transmute::<*mut ffi::c_void, os::GetauxvalTy>(ptr);\n            for &at in &[ffi::AT_HWCAP, ffi::AT_HWCAP2] {\n                assert_eq!(dlsym_getauxval(at), ffi::getauxval(at));\n            }\n            #[cfg(not(all(target_arch = \"aarch64\", target_pointer_width = \"32\")))]\n            for &at in &[ffi::AT_HWCAP3, ffi::AT_HWCAP4] {\n                assert_eq!(dlsym_getauxval(at), ffi::getauxval(at));\n            }\n        }\n    }\n    #[cfg(any(target_os = \"freebsd\", target_os = \"openbsd\"))]\n    #[test]\n    fn test_dlsym_elf_aux_info() {\n        unsafe {\n            let ptr = ffi::dlsym(ffi::RTLD_DEFAULT, c!(\"elf_aux_info\").as_ptr());\n            if cfg!(target_feature = \"crt-static\") {\n                assert!(ptr.is_null());\n            } else if cfg!(target_os = \"freebsd\") || option_env!(\"CI\").is_some() {\n                assert!(!ptr.is_null());\n            }\n            if ptr.is_null() {\n                return;\n            }\n            let dlsym_elf_aux_info = mem::transmute::<*mut ffi::c_void, os::ElfAuxInfoTy>(ptr);\n            #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)]\n            let out_len = mem::size_of::<ffi::c_ulong>() as ffi::c_int;\n            for &at in &[ffi::AT_HWCAP, ffi::AT_HWCAP2] {\n                let mut out: ffi::c_ulong = 0;\n                let mut dlsym_out: ffi::c_ulong = 0;\n                assert_eq!(\n                    ffi::elf_aux_info(\n                        at,\n                        (&mut out as *mut ffi::c_ulong).cast::<ffi::c_void>(),\n                        out_len,\n                    ),\n                    dlsym_elf_aux_info(\n                        at,\n                        (&mut dlsym_out as *mut ffi::c_ulong).cast::<ffi::c_void>(),\n                        out_len,\n                    ),\n                );\n                assert_eq!(out, dlsym_out);\n            }\n            #[cfg(not(target_os = \"openbsd\"))]\n            for &at in &[ffi::AT_HWCAP3, ffi::AT_HWCAP4] {\n                let mut out: ffi::c_ulong = 0;\n                let mut dlsym_out: ffi::c_ulong = 0;\n                assert_eq!(\n                    ffi::elf_aux_info(\n                        at,\n                        (&mut out as *mut ffi::c_ulong).cast::<ffi::c_void>(),\n                        out_len,\n                    ),\n                    dlsym_elf_aux_info(\n                        at,\n                        (&mut dlsym_out as *mut ffi::c_ulong).cast::<ffi::c_void>(),\n                        out_len,\n                    ),\n                );\n                assert_eq!(out, dlsym_out);\n            }\n        }\n    }\n\n    #[cfg(any(target_os = \"linux\", target_os = \"android\"))]\n    #[cfg(not(all(target_arch = \"aarch64\", target_pointer_width = \"32\")))] // no PR_GET_AUXV\n    #[test]\n    fn test_alternative() {\n        use std::{eprintln, str, vec};\n\n        #[cfg(target_pointer_width = \"32\")]\n        use sys::Elf32_auxv_t as Elf_auxv_t;\n        #[cfg(target_pointer_width = \"64\")]\n        use sys::Elf64_auxv_t as Elf_auxv_t;\n        use test_helper::sys;\n\n        use crate::utils::ffi::*;\n\n        // Linux kernel 6.4 has added a way to read auxv without depending on either libc or mrs trap.\n        // https://github.com/torvalds/linux/commit/ddc65971bb677aa9f6a4c21f76d3133e106f88eb\n        // (Actually 6.5? https://github.com/torvalds/linux/commit/636e348353a7cc52609fdba5ff3270065da140d5)\n        //\n        // This is currently used only for testing.\n        #[cfg(not(target_os = \"android\"))]\n        #[cfg(not(portable_atomic_no_asm_syscall))]\n        fn getauxval_pr_get_auxv_no_libc(type_: c_ulong) -> Result<c_ulong, c_int> {\n            use crate::utils::{RegISize, RegSize};\n\n            unsafe fn prctl_get_auxv(out: *mut c_void, len: usize) -> Result<usize, c_int> {\n                #[cfg_attr(target_arch = \"arm\", allow(unused_variables))]\n                let number = sys::__NR_prctl as RegSize;\n                let arg1 = sys::PR_GET_AUXV as RegSize;\n                let arg2 = ptr_reg!(out);\n                let arg3 = len as RegSize;\n                let arg4: RegSize = 0;\n                let arg5: RegSize = 0;\n                let r: RegISize;\n                // SAFETY: the caller must uphold the safety contract.\n                // we've extended the syscall number and arguments to the register size.\n                unsafe {\n                    #[cfg(target_arch = \"arm\")]\n                    asm_syscall!(sys::__NR_prctl, 172, r, arg1, arg2, arg3, arg4, arg5);\n                    // POWER9+ has fast syscall using SCV, but since detection is cold path,\n                    // there’s no need to consider it here.\n                    #[cfg(not(target_arch = \"arm\"))]\n                    asm_syscall!(number, r, arg1, arg2, arg3, arg4, arg5);\n                }\n                #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]\n                if (r as c_int) < 0 { Err(r as c_int) } else { Ok(r as usize) }\n            }\n\n            let mut auxv = vec![unsafe { mem::zeroed::<Elf_auxv_t>() }; 38];\n\n            let old_len = auxv.len() * mem::size_of::<Elf_auxv_t>();\n\n            // SAFETY:\n            // - `out_len` does not exceed the size of `auxv`.\n            let _len = unsafe { prctl_get_auxv(auxv.as_mut_ptr().cast::<c_void>(), old_len)? };\n\n            for aux in &auxv {\n                if aux.a_type == type_ {\n                    // SAFETY: aux.a_un is #[repr(C)] union and all fields have\n                    // the same size and can be safely transmuted to integers.\n                    return Ok(unsafe { aux.a_un.a_val });\n                }\n            }\n            Err(0)\n        }\n        // Similar to the above, but call libc prctl instead of syscall using asm.\n        //\n        // This is used only for testing.\n        fn getauxval_pr_get_auxv_libc(type_: c_ulong) -> Result<c_ulong, c_int> {\n            unsafe fn prctl_get_auxv(out: *mut c_void, len: usize) -> Result<usize, c_int> {\n                // arg4 and arg5 must be zero.\n                #[allow(clippy::cast_possible_wrap)]\n                let r = unsafe { libc::prctl(sys::PR_GET_AUXV as c_int, out, len, 0, 0) };\n                #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]\n                if (r as c_int) < 0 { Err(r as c_int) } else { Ok(r as usize) }\n            }\n\n            let mut auxv = vec![unsafe { mem::zeroed::<Elf_auxv_t>() }; 38];\n\n            let old_len = auxv.len() * mem::size_of::<Elf_auxv_t>();\n\n            // SAFETY:\n            // - `out_len` does not exceed the size of `auxv`.\n            let _len = unsafe { prctl_get_auxv(auxv.as_mut_ptr().cast::<c_void>(), old_len)? };\n\n            for aux in &auxv {\n                if aux.a_type == type_ {\n                    // SAFETY: aux.a_un is #[repr(C)] union and all fields have\n                    // the same size and can be safely transmuted to integers.\n                    return Ok(unsafe { aux.a_un.a_val });\n                }\n            }\n            Err(0)\n        }\n\n        unsafe {\n            let mut u = mem::zeroed();\n            assert_eq!(libc::uname(&mut u), 0);\n            let release = std::ffi::CStr::from_ptr(u.release.as_ptr());\n            let release = str::from_utf8(release.to_bytes()).unwrap();\n            let mut digits = release.split('.');\n            let major = digits.next().unwrap().parse::<u32>().unwrap();\n            let minor = digits.next().unwrap().parse::<u32>().unwrap();\n            // TODO: qemu-user bug (fails even on kernel >= 6.4) (as of 9.2)\n            if (major, minor) < (6, 4) || cfg!(qemu) {\n                eprintln!(\"kernel version: {}.{} (no pr_get_auxv)\", major, minor);\n                for &at in &[ffi::AT_HWCAP, ffi::AT_HWCAP2, ffi::AT_HWCAP3, ffi::AT_HWCAP4] {\n                    assert_eq!(getauxval_pr_get_auxv_libc(at).unwrap_err(), -1);\n                    #[cfg(not(target_os = \"android\"))]\n                    #[cfg(not(portable_atomic_no_asm_syscall))]\n                    assert_eq!(getauxval_pr_get_auxv_no_libc(at).unwrap_err(), -libc::EINVAL);\n                }\n            } else {\n                eprintln!(\"kernel version: {}.{} (has pr_get_auxv)\", major, minor);\n                for &at in &[ffi::AT_HWCAP, ffi::AT_HWCAP2] {\n                    if cfg!(all(valgrind, target_arch = \"powerpc64\")) {\n                        // TODO: valgrind bug (as of Valgrind 3.26)\n                        assert_eq!(getauxval_pr_get_auxv_libc(at).unwrap_err(), -1);\n                        #[cfg(not(target_os = \"android\"))]\n                        #[cfg(not(portable_atomic_no_asm_syscall))]\n                        assert_eq!(getauxval_pr_get_auxv_no_libc(at).unwrap_err(), -libc::EINVAL);\n                    } else if cfg!(all(valgrind, target_arch = \"aarch64\"))\n                        || cfg!(all(valgrind, target_arch = \"arm\")) && at == ffi::AT_HWCAP2\n                    {\n                        // TODO: valgrind bug (result value mismatch) (as of Valgrind 3.26)\n                        assert_ne!(os::getauxval(at), getauxval_pr_get_auxv_libc(at).unwrap());\n                        #[cfg(not(target_os = \"android\"))]\n                        #[cfg(not(portable_atomic_no_asm_syscall))]\n                        assert_ne!(os::getauxval(at), getauxval_pr_get_auxv_no_libc(at).unwrap());\n                    } else {\n                        assert_eq!(os::getauxval(at), getauxval_pr_get_auxv_libc(at).unwrap());\n                        #[cfg(not(target_os = \"android\"))]\n                        #[cfg(not(portable_atomic_no_asm_syscall))]\n                        assert_eq!(os::getauxval(at), getauxval_pr_get_auxv_no_libc(at).unwrap());\n                    }\n                }\n                for &at in &[ffi::AT_HWCAP3, ffi::AT_HWCAP4] {\n                    assert_eq!(\n                        os::getauxval(at),\n                        getauxval_pr_get_auxv_libc(at).unwrap_or_default()\n                    );\n                    #[cfg(not(target_os = \"android\"))]\n                    #[cfg(not(portable_atomic_no_asm_syscall))]\n                    assert_eq!(\n                        os::getauxval(at),\n                        getauxval_pr_get_auxv_no_libc(at).unwrap_or_default()\n                    );\n                }\n            }\n        }\n    }\n    #[allow(clippy::cast_possible_wrap)]\n    #[cfg(target_os = \"freebsd\")]\n    #[test]\n    fn test_alternative() {\n        use std::ptr;\n\n        use test_helper::sys;\n\n        use crate::utils::ffi::*;\n\n        // This is almost equivalent to what elf_aux_info does.\n        // https://man.freebsd.org/elf_aux_info(3)\n        // On FreeBSD, [AArch64 support is available on FreeBSD 11.0+](https://www.freebsd.org/releases/11.0R/announce),\n        // but elf_aux_info is available on FreeBSD 12.0+ and 11.4+:\n        // https://github.com/freebsd/freebsd-src/commit/0b08ae2120cdd08c20a2b806e2fcef4d0a36c470\n        // https://github.com/freebsd/freebsd-src/blob/release/11.4.0/sys/sys/auxv.h\n        // so use sysctl instead of elf_aux_info.\n        // Note that FreeBSD 11 (11.4) was EoL on 2021-09-30, and FreeBSD 11.3 was EoL on 2020-09-30:\n        // https://www.freebsd.org/security/unsupported\n        //\n        // This is currently used only for testing.\n        // If you want us to use this implementation for compatibility with the older FreeBSD\n        // version that came to EoL a few years ago, please open an issue.\n        fn getauxval_sysctl_libc(type_: ffi::c_int) -> Result<ffi::c_ulong, c_int> {\n            let mut auxv: [sys::Elf_Auxinfo; sys::AT_COUNT as usize] = unsafe { mem::zeroed() };\n\n            let mut len = mem::size_of_val(&auxv) as c_size_t;\n\n            // SAFETY: calling getpid is safe.\n            let pid = unsafe { libc::getpid() };\n            let mib = [\n                sys::CTL_KERN as c_int,\n                sys::KERN_PROC as c_int,\n                sys::KERN_PROC_AUXV as c_int,\n                pid,\n            ];\n            #[allow(clippy::cast_possible_truncation)]\n            let mib_len = mib.len() as c_uint;\n            // SAFETY:\n            // - `mib_len` does not exceed the size of `mib`.\n            // - `len` does not exceed the size of `auxv`.\n            // - `sysctl` is thread-safe.\n            let res = unsafe {\n                libc::sysctl(\n                    mib.as_ptr(),\n                    mib_len,\n                    auxv.as_mut_ptr().cast::<c_void>(),\n                    &mut len,\n                    ptr::null_mut(),\n                    0,\n                )\n            };\n            // FreeBSD sysctl returns 0 on success, -1 on failure.\n            if res != 0 {\n                return Err(res);\n            }\n\n            for aux in &auxv {\n                #[allow(clippy::cast_sign_loss)]\n                if aux.a_type == type_ as c_long {\n                    // SAFETY: aux.a_un is #[repr(C)] union and all fields have\n                    // the same size and can be safely transmuted to integers.\n                    return Ok(unsafe { aux.a_un.a_val as c_ulong });\n                }\n            }\n            Err(0)\n        }\n\n        // AT_HWCAP2 is only available on FreeBSD 13+ on AArch64.\n        let hwcap2_else = |e| if cfg!(target_arch = \"aarch64\") { 0 } else { panic!(\"{:?}\", e) };\n        let at = ffi::AT_HWCAP;\n        assert_eq!(os::getauxval(at), getauxval_sysctl_libc(at).unwrap());\n        let at = ffi::AT_HWCAP2;\n        assert_eq!(os::getauxval(at), getauxval_sysctl_libc(at).unwrap_or_else(hwcap2_else));\n        for &at in &[ffi::AT_HWCAP3, ffi::AT_HWCAP4] {\n            assert_eq!(os::getauxval(at), getauxval_sysctl_libc(at).unwrap_or_default());\n        }\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/detect/common.rs",
      "sha256": "735925ba2717d649f49a7550d78fd523b002fb8c030cb7d52e542d982ada43a9",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#[derive(Clone, Copy)]\n#[repr(transparent)]\npub(crate) struct CpuInfo(u32);\n\nimpl CpuInfo {\n    #[inline]\n    fn set(&mut self, bit: CpuInfoFlag) {\n        self.0 = set(self.0, bit as u32);\n    }\n    #[inline]\n    #[must_use]\n    fn test(self, bit: CpuInfoFlag) -> bool {\n        test(self.0, bit as u32)\n    }\n}\n\n#[inline]\n#[must_use]\nfn set(x: u32, bit: u32) -> u32 {\n    x | (1 << bit)\n}\n#[inline]\n#[must_use]\nfn test(x: u32, bit: u32) -> bool {\n    x & (1 << bit) != 0\n}\n\n#[inline]\npub(crate) fn detect() -> CpuInfo {\n    use core::sync::atomic::{AtomicU32, Ordering};\n\n    static CACHE: AtomicU32 = AtomicU32::new(0);\n    let mut info = CpuInfo(CACHE.load(Ordering::Relaxed));\n    if info.0 != 0 {\n        return info;\n    }\n    info.set(CpuInfoFlag::Init);\n    // Note: detect_false cfg is intended to make it easy for developers to test\n    // cases where features usually available is not available, and is not a public API.\n    if !cfg!(portable_atomic_test_detect_false) {\n        info = _detect(info);\n    }\n    if cfg!(any(\n        all(\n            target_arch = \"x86_64\",\n            not(any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\")),\n        ),\n        all(\n            target_arch = \"powerpc64\",\n            not(any(\n                target_feature = \"quadword-atomics\",\n                portable_atomic_target_feature = \"quadword-atomics\",\n            )),\n        ),\n        all(\n            any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n            not(any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\")),\n        ),\n    )) {\n        // Use CAS if the detection result affects lock-freeness.\n        match CACHE.compare_exchange(0, info.0, Ordering::Relaxed, Ordering::Relaxed) {\n            Ok(_) => info,\n            Err(info) => {\n                debug_assert_ne!(info, 0);\n                CpuInfo(info)\n            }\n        }\n    } else {\n        CACHE.store(info.0, Ordering::Relaxed);\n        info\n    }\n}\n\nmacro_rules! flags {\n    ($(\n        $(#[$attr:meta])*\n        $func:ident($name:literal, any($($cfg:ident),*)),\n    )*) => {\n        #[allow(dead_code, non_camel_case_types)]\n        #[derive(Clone, Copy)]\n        #[cfg_attr(test, derive(PartialEq, Eq, PartialOrd, Ord))]\n        #[repr(u32)]\n        enum CpuInfoFlag {\n            Init = 0,\n            $($func,)*\n        }\n        impl CpuInfo {\n            $(\n                $(#[$attr])*\n                #[cfg(any(test, not(any($($cfg = $name),*))))]\n                #[inline]\n                #[must_use]\n                pub(crate) fn $func(self) -> bool {\n                    self.test(CpuInfoFlag::$func)\n                }\n            )*\n            #[cfg(test)] // for test\n            const ALL_FLAGS: &'static [(&'static str, CpuInfoFlag, bool)] = &[$(\n                ($name, CpuInfoFlag::$func, cfg!(any($($cfg = $name),*))),\n            )*];\n        }\n        #[test]\n        #[cfg_attr(portable_atomic_test_detect_false, ignore = \"detection disabled\")]\n        fn test_detect() {$(\n            $(#[$attr])*\n            {\n                const _: u32 = 1_u32 << CpuInfoFlag::$func as u32;\n                assert_eq!($name.replace(|c: char| c == '-' || c == '.', \"_\"), stringify!($func));\n                if detect().$func() {\n                    assert!(detect().test(CpuInfoFlag::$func));\n                } else {\n                    assert!(!detect().test(CpuInfoFlag::$func));\n                }\n            }\n        )*}\n    };\n}\n\n// rustc definitions: https://github.com/rust-lang/rust/blob/ddaf12390d3ffb7d5ba74491a48f3cd528e5d777/compiler/rustc_target/src/target_features.rs\n\n// LLVM definitions: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/AArch64/AArch64Features.td\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\"))]\nflags! {\n    // The Armv8.1 architecture extension\n    // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv8-1-architecture-extension\n    // FEAT_LSE, Large System Extensions\n    // > This feature is supported in AArch64 state only.\n    // > FEAT_LSE is OPTIONAL from Armv8.0.\n    // > FEAT_LSE is mandatory from Armv8.1.\n    lse(\"lse\", any(target_feature /* 1.61+ */, portable_atomic_target_feature)),\n\n    // The Armv8.3 architecture extension\n    // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv8-3-architecture-extension\n    // FEAT_LRCPC, Load-Acquire RCpc instructions\n    // > These instructions are added to the A64 instruction set only.\n    // > FEAT_LRCPC is OPTIONAL from Armv8.2.\n    // > FEAT_LRCPC is mandatory from Armv8.3.\n    #[cfg(test)] // test-only\n    rcpc(\"rcpc\", any(target_feature /* 1.61+ */)),\n\n    // The Armv8.4 architecture extension\n    // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv8-4-architecture-extension\n    // FEAT_LSE2, Large System Extensions version 2\n    // > This feature is supported in AArch64 state only.\n    // > FEAT_LSE2 is OPTIONAL from Armv8.2.\n    // > FEAT_LSE2 is mandatory from Armv8.4.\n    #[cfg_attr(not(test), allow(dead_code))]\n    lse2(\"lse2\", any(target_feature /* nightly */, portable_atomic_target_feature)),\n    // FEAT_LRCPC2, Load-Acquire RCpc instructions version 2\n    // > These instructions are added to the A64 instruction set only.\n    // > FEAT_LRCPC2 is OPTIONAL from Armv8.2.\n    // > FEAT_LRCPC2 is mandatory from Armv8.4.\n    // > If FEAT_LRCPC2 is implemented, then FEAT_LRCPC is implemented.\n    #[cfg(test)] // test-only\n    rcpc2(\"rcpc2\", any(target_feature /* 1.61+ */)),\n\n    // The Armv8.9 architecture extension\n    // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv8-9-architecture-extension\n    // FEAT_LRCPC3, Load-Acquire RCpc instructions version 3\n    // > This feature is supported in AArch64 state only.\n    // > FEAT_LRCPC3 is OPTIONAL from Armv8.2.\n    // > If FEAT_LRCPC3 is implemented, then FEAT_LRCPC2 is implemented.\n    #[cfg_attr(not(test), allow(dead_code))]\n    rcpc3(\"rcpc3\", any(target_feature /* nightly */, portable_atomic_target_feature)),\n\n    // The Armv9.4 architecture extension\n    // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv9-4-architecture-extension\n    // FEAT_LSE128, 128-bit Atomics\n    // > This feature is supported in AArch64 state only.\n    // > FEAT_LSE128 is OPTIONAL from Armv9.3.\n    // > If FEAT_LSE128 is implemented, then FEAT_LSE is implemented.\n    #[cfg_attr(not(test), allow(dead_code))]\n    lse128(\"lse128\", any(target_feature /* nightly */, portable_atomic_target_feature)),\n\n    // The Armv9.6 architecture extension\n    // https://developer.arm.com/documentation/109697/2025_06/Feature-descriptions/The-Armv9-6-architecture-extension\n    // FEAT_LS64WB, LS64 for Write-back cacheable memory\n    // > This feature is supported in AArch64 state only.\n    // > FEAT_LS64WB is OPTIONAL from Armv9.2.\n    // > If FEAT_LS64WB is implemented, then FEAT_LS64_ACCDATA is implemented.\n    #[cfg(test)] // test-only\n    ls64wb(\"ls64wb\", any(/* no corresponding target feature */)),\n    // FEAT_LSFE, Large System Float Extension\n    // > This feature is supported in AArch64 state only.\n    // > FEAT_LSFE is OPTIONAL from Armv9.3.\n    // > If FEAT_LSFE is implemented, then FEAT_FP is implemented.\n    #[cfg(test)] // test-only\n    lsfe(\"lsfe\", any(target_feature /* N/A */, portable_atomic_target_feature)),\n\n    #[cfg(test)] // test-only\n    cpuid(\"cpuid\", any(/* no corresponding target feature */)),\n}\n\n// LLVM definitions: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/ARM/ARMFeatures.td\n#[cfg(target_arch = \"arm\")]\nflags! {\n    #[cfg(test)] // test-only\n    lpae(\"lpae\", any(/* no corresponding target feature */)),\n}\n\n// LLVM definitions: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/PowerPC/PPC.td\n#[cfg(target_arch = \"powerpc64\")]\nflags! {\n    // lqarx and stqcx.\n    quadword_atomics(\"quadword-atomics\", any(target_feature /* nightly */, portable_atomic_target_feature)),\n}\n\n// LLVM definitions: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/RISCV/RISCVFeatures.td\n#[cfg(any(target_arch = \"riscv32\", target_arch = \"riscv64\"))]\nflags! {\n    // amocas.{w,d,q}\n    zacas(\"zacas\", any(target_feature /* 1.94+ */, portable_atomic_target_feature)),\n    #[cfg(test)] // test-only\n    zabha(\"zabha\", any(target_feature /* 1.94+ */, portable_atomic_target_feature)),\n    #[cfg(test)] // test-only\n    zalasr(\"zalasr\", any(/* no corresponding target feature */)),\n}\n\n// LLVM definitions: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/X86/X86.td\n#[cfg(target_arch = \"x86_64\")]\nflags! {\n    // avx\n    #[cfg(target_feature = \"sse\")]\n    avx(\"avx\", any(target_feature)),\n    // cmpxchg16b\n    cmpxchg16b(\"cmpxchg16b\", any(target_feature /* 1.69+ */, portable_atomic_target_feature)),\n}\n\n#[allow(\n    clippy::alloc_instead_of_core,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    clippy::undocumented_unsafe_blocks,\n    clippy::wildcard_imports\n)]\n#[cfg(test)]\nmod tests_common {\n    use std::{collections::BTreeSet, vec};\n\n    use super::*;\n\n    #[test]\n    fn test_bit_flags() {\n        let mut flags = vec![(\"init\", CpuInfoFlag::Init)];\n        flags.extend(CpuInfo::ALL_FLAGS.iter().map(|&(name, flag, _)| (name, flag)));\n        let flag_set = flags.iter().map(|(_, flag)| flag).collect::<BTreeSet<_>>();\n        let name_set = flags.iter().map(|(name, _)| name).collect::<BTreeSet<_>>();\n        if flag_set.len() != flags.len() {\n            panic!(\"CpuInfo flag values must be unique\")\n        }\n        if name_set.len() != flags.len() {\n            panic!(\"CpuInfo flag names must be unique\")\n        }\n\n        let mut x = CpuInfo(0);\n        for &(_, f) in &flags {\n            assert!(!x.test(f));\n        }\n        for i in 0..flags.len() {\n            x.set(flags[i].1);\n            for &(_, f) in &flags[..i + 1] {\n                assert!(x.test(f));\n            }\n            for &(_, f) in &flags[i + 1..] {\n                assert!(!x.test(f));\n            }\n        }\n        for &(_, f) in &flags {\n            assert!(x.test(f));\n        }\n    }\n\n    #[test]\n    fn print_features() {\n        use std::{fmt::Write as _, string::String};\n\n        let mut features = String::new();\n        features.push_str(\"\\nfeatures:\\n\");\n        for &(name, flag, compile_time) in CpuInfo::ALL_FLAGS {\n            let run_time = detect().test(flag);\n            if run_time == compile_time {\n                let _ = writeln!(features, \"  {}: {}\", name, run_time);\n            } else {\n                let _ = writeln!(\n                    features,\n                    \"  {}: {} (compile-time), {} (run-time)\",\n                    name, compile_time, run_time\n                );\n            }\n        }\n        test_helper::eprintln_nocapture!(\"{}\", features);\n    }\n\n    // Static assertions for C type definitions.\n    // Assertions with core::ffi types are in crate::utils::ffi module.\n    #[cfg(not(any(windows, target_arch = \"x86\", target_arch = \"x86_64\")))]\n    const _: fn() = || {\n        use test_helper::sys;\n        let _: crate::utils::ffi::c_char = 0 as sys::c_char;\n    };\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/detect/powerpc64_aix.rs",
      "sha256": "b635538662e9add807cebd26c5742eae6dd764e11fd2c30fc6661baa03b69d01",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRun-time CPU feature detection on PowerPC64 AIX by using getsystemcfg.\n\nRefs:\n- https://github.com/golang/go/blob/go1.26.0/src/internal/cpu/cpu_ppc64x_aix.go\n\nAs of Rust 1.94, is_powerpc_feature_detected doesn't support run-time detection on AIX.\nhttps://github.com/rust-lang/rust/blob/1.94.0/library/std_detect/src/detect/mod.rs\n\nRun-time detection on PowerPC64 AIX is currently disabled by default as experimental\nbecause we cannot run tests on the VM or real machine.\n*/\n\ninclude!(\"common.rs\");\n\n// libc requires Rust 1.63\nmod ffi {\n    pub(crate) use crate::utils::ffi::{c_int, c_ulong};\n\n    sys_const!({\n        // https://github.com/rust-lang/libc/blob/0.2.158/src/unix/aix/mod.rs#L2058\n        // https://github.com/golang/go/blob/go1.26.0/src/internal/cpu/cpu_ppc64x_aix.go\n        pub(crate) const SC_IMPL: c_int = 2;\n        pub(crate) const POWER_8: c_ulong = 0x10000;\n        pub(crate) const POWER_9: c_ulong = 0x20000;\n    });\n    // TODO: use sys_const! once libc crate defined it.\n    pub(crate) const POWER_10: c_ulong = 0x40000;\n\n    sys_fn!({\n        extern \"C\" {\n            // https://www.ibm.com/docs/en/aix/7.3?topic=g-getsystemcfg-subroutine\n            // https://github.com/rust-lang/libc/blob/0.2.158/src/unix/aix/powerpc64.rs#L643\n            pub(crate) fn getsystemcfg(name: c_int) -> c_ulong;\n        }\n    });\n}\n\n#[cold]\n#[must_use]\nfn _detect(mut info: CpuInfo) -> CpuInfo {\n    // SAFETY: calling getsystemcfg is safe.\n    let impl_ = unsafe { ffi::getsystemcfg(ffi::SC_IMPL) };\n    if impl_ == ffi::c_ulong::MAX {\n        return info;\n    }\n    // Check both POWER_8 and later ISAs (which are superset of POWER_8) because\n    // AIX currently doesn't set POWER_8 when POWER_9 is set.\n    // https://github.com/golang/go/commit/51859ec2292d9c1d82a7054ec672ff551a0d7497\n    if impl_ & (ffi::POWER_8 | ffi::POWER_9 | ffi::POWER_10) != 0 {\n        info.set(CpuInfoFlag::quadword_atomics);\n    }\n    info\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/detect/riscv_linux.rs",
      "sha256": "9e8b214013992dcf7ff5e0beb9228db4f2125aa134afdc573781788349f3a159",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRun-time CPU feature detection on RISC-V Linux/Android by using riscv_hwprobe.\n\nOn RISC-V, detection using auxv only supports single-letter extensions.\nSo, we use riscv_hwprobe that supports multi-letter extensions.\n\nRefs: https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/riscv/hwprobe.rst\n*/\n\ninclude!(\"common.rs\");\n\nuse core::ptr;\n\n// libc requires Rust 1.63\n#[allow(non_camel_case_types, non_upper_case_globals)]\nmod ffi {\n    pub(crate) use crate::utils::ffi::{c_long, c_size_t, c_uint, c_ulong};\n\n    sys_struct!({\n        // https://github.com/torvalds/linux/blob/v6.19/arch/riscv/include/uapi/asm/hwprobe.h\n        pub(crate) struct riscv_hwprobe {\n            pub(crate) key: i64,\n            pub(crate) value: u64,\n        }\n    });\n\n    sys_const!({\n        pub(crate) const __NR_riscv_hwprobe: c_long = 258;\n\n        // https://github.com/torvalds/linux/blob/v6.19/arch/riscv/include/uapi/asm/hwprobe.h\n        // Linux 6.4+\n        // https://github.com/torvalds/linux/commit/00e76e2c6a2bd3976d44d4a1fdd0b7a3c2566607\n        pub(crate) const RISCV_HWPROBE_KEY_BASE_BEHAVIOR: i64 = 3;\n        pub(crate) const RISCV_HWPROBE_BASE_BEHAVIOR_IMA: u64 = 1 << 0;\n        pub(crate) const RISCV_HWPROBE_KEY_IMA_EXT_0: i64 = 4;\n        // Linux 6.8+\n        // https://github.com/torvalds/linux/commit/154a3706122978eeb34d8223d49285ed4f3c61fa\n        pub(crate) const RISCV_HWPROBE_EXT_ZACAS: u64 = 1 << 34;\n        // Linux 6.16+\n        // https://github.com/torvalds/linux/commit/415a8c81da3dab0a585bd4f8d505a11ad5a171a7\n        #[cfg(test)]\n        pub(crate) const RISCV_HWPROBE_EXT_ZABHA: u64 = 1 << 58;\n        // Linux 6.19+\n        // https://github.com/torvalds/linux/commit/f4922b69165735e81752ee47d174f873e989a449\n        #[cfg(test)]\n        pub(crate) const RISCV_HWPROBE_EXT_ZALASR: u64 = 1 << 59;\n    });\n\n    cfg_sel!({\n        // Use asm-based syscall on Linux for compatibility with non-libc targets if possible.\n        // Do not use this on Android. See comments on syscall_helper module in src/utils.rs for details.\n        #[cfg(all(\n            target_os = \"linux\",\n            any(\n                target_arch = \"riscv32\",\n                all(target_arch = \"riscv64\", target_pointer_width = \"64\"),\n            ),\n            not(portable_atomic_no_asm_syscall),\n        ))]\n        {\n            use crate::utils::{RegISize, RegSize};\n\n            #[inline]\n            pub(crate) unsafe fn syscall5(\n                number: c_long,\n                arg1: *mut riscv_hwprobe,\n                arg2: c_size_t,\n                arg3: c_size_t,\n                arg4: *mut c_ulong,\n                arg5: c_uint,\n            ) -> c_long {\n                #[allow(clippy::cast_possible_truncation)]\n                let number = number as RegISize;\n                let arg1 = ptr_reg!(arg1);\n                let arg2 = arg2 as RegSize;\n                let arg3 = arg3 as RegSize;\n                let arg4 = ptr_reg!(arg4);\n                let arg5 = arg5 as RegSize;\n                let r: RegISize;\n                // SAFETY: the caller must uphold the safety contract.\n                // we've extended the syscall number and arguments to the register size.\n                unsafe {\n                    asm_syscall!(number, r, arg1, arg2, arg3, arg4, arg5);\n                }\n                #[allow(clippy::cast_possible_truncation)]\n                {\n                    r as c_long\n                }\n            }\n        }\n        #[cfg(else)]\n        {\n            sys_fn!({\n                extern \"C\" {\n                    // https://man7.org/linux/man-pages/man2/syscall.2.html\n                    pub(crate) fn syscall(number: c_long, ...) -> c_long;\n                }\n            });\n            pub(crate) use self::syscall as syscall5;\n        }\n    });\n\n    // https://github.com/torvalds/linux/blob/v6.19/Documentation/arch/riscv/hwprobe.rst\n    pub(crate) unsafe fn __riscv_hwprobe(\n        pairs: *mut riscv_hwprobe,\n        pair_count: c_size_t,\n        cpu_set_size: c_size_t,\n        cpus: *mut c_ulong,\n        flags: c_uint,\n    ) -> c_long {\n        // SAFETY: the caller must uphold the safety contract.\n        unsafe { syscall5(__NR_riscv_hwprobe, pairs, pair_count, cpu_set_size, cpus, flags) }\n    }\n}\n\n// syscall returns an unsupported error if riscv_hwprobe is not supported,\n// so we can safely use this function on older versions of Linux.\nfn riscv_hwprobe(out: &mut [ffi::riscv_hwprobe]) -> bool {\n    let len = out.len();\n    // SAFETY: We've passed the valid pointer and length,\n    // passing null ptr for cpus is safe because cpu_set_size is zero.\n    unsafe { ffi::__riscv_hwprobe(out.as_mut_ptr(), len, 0, ptr::null_mut(), 0) == 0 }\n}\n\n#[cold]\n#[must_use]\nfn _detect(mut info: CpuInfo) -> CpuInfo {\n    let mut out = [\n        ffi::riscv_hwprobe { key: ffi::RISCV_HWPROBE_KEY_BASE_BEHAVIOR, value: 0 },\n        ffi::riscv_hwprobe { key: ffi::RISCV_HWPROBE_KEY_IMA_EXT_0, value: 0 },\n    ];\n    if riscv_hwprobe(&mut out)\n        && out[0].key != -1\n        && out[0].value & ffi::RISCV_HWPROBE_BASE_BEHAVIOR_IMA != 0\n        && out[1].key != -1\n    {\n        let value = out[1].value;\n        macro_rules! check {\n            ($flag:ident, $bit:ident) => {\n                if value & ffi::$bit != 0 {\n                    info.set(CpuInfoFlag::$flag);\n                }\n            };\n        }\n        check!(zacas, RISCV_HWPROBE_EXT_ZACAS);\n        #[cfg(test)]\n        check!(zabha, RISCV_HWPROBE_EXT_ZABHA);\n        #[cfg(test)]\n        check!(zalasr, RISCV_HWPROBE_EXT_ZALASR);\n    }\n    info\n}\n\n#[allow(\n    clippy::alloc_instead_of_core,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    clippy::undocumented_unsafe_blocks,\n    clippy::wildcard_imports\n)]\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    // We use asm-based syscall for compatibility with non-libc targets.\n    // This test tests that our ones and libc::syscall returns the same result.\n    #[test]\n    fn test_alternative() {\n        unsafe fn __riscv_hwprobe_libc(\n            pairs: *mut ffi::riscv_hwprobe,\n            pair_count: ffi::c_size_t,\n            cpu_set_size: ffi::c_size_t,\n            cpus: *mut ffi::c_ulong,\n            flags: ffi::c_uint,\n        ) -> ffi::c_long {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                libc::syscall(ffi::__NR_riscv_hwprobe, pairs, pair_count, cpu_set_size, cpus, flags)\n            }\n        }\n        fn riscv_hwprobe_libc(out: &mut [ffi::riscv_hwprobe]) -> bool {\n            let len = out.len();\n            unsafe { __riscv_hwprobe_libc(out.as_mut_ptr(), len, 0, ptr::null_mut(), 0) == 0 }\n        }\n        let mut out = [\n            ffi::riscv_hwprobe { key: ffi::RISCV_HWPROBE_KEY_BASE_BEHAVIOR, value: 0 },\n            ffi::riscv_hwprobe { key: ffi::RISCV_HWPROBE_KEY_IMA_EXT_0, value: 0 },\n        ];\n        let mut libc_out = out;\n        assert_eq!(riscv_hwprobe(&mut out), riscv_hwprobe_libc(&mut libc_out));\n        assert_eq!(out, libc_out);\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/detect/x86_64.rs",
      "sha256": "8b315b61a409d3350b19c02e98a741f4c1c1e3861e6792594137267f4595eeb1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRun-time CPU feature detection on x86_64 by using CPUID.\n\nAdapted from https://github.com/rust-lang/rust/blob/1.92.0/library/std_detect/src/detect/os/x86.rs.\n*/\n\n#![cfg_attr(portable_atomic_sanitize_thread, allow(dead_code))]\n\n// Miri doesn't support inline assembly used in __cpuid: https://github.com/rust-lang/miri/issues/932\n// SGX doesn't support CPUID: https://github.com/rust-lang/rust/blob/1.92.0/library/std_detect/src/detect/os/x86.rs#L30-L33\n#[cfg(any(target_env = \"sgx\", miri))]\ncompile_error!(\"internal error: this module is not supported on this environment\");\n\ninclude!(\"common.rs\");\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\nuse core::arch::x86_64::CpuidResult;\n\n// Workaround for https://github.com/rust-lang/rust/issues/101346\n// It is not clear if our use cases are affected, but we implement this just in case.\n//\n// Refs:\n// - https://www.felixcloutier.com/x86/cpuid\n// - https://en.wikipedia.org/wiki/CPUID\n// - https://github.com/rust-lang/stdarch/blob/a0c30f3e3c75adcd6ee7efc94014ebcead61c507/crates/core_arch/src/x86/cpuid.rs\n#[cfg(not(target_env = \"sgx\"))]\nfn __cpuid(leaf: u32) -> CpuidResult {\n    let eax;\n    let mut ebx;\n    let ecx;\n    let edx;\n    // SAFETY: Calling `__cpuid` is safe on all x86_64 CPUs except for SGX,\n    // which doesn't support `cpuid`.\n    // https://github.com/rust-lang/stdarch/blob/a0c30f3e3c75adcd6ee7efc94014ebcead61c507/crates/core_arch/src/x86/cpuid.rs#L102-L109\n    unsafe {\n        asm!(\n            \"mov r8, rbx\", // save rbx which is reserved by LLVM\n            \"cpuid\",\n            \"xchg r8, rbx\", // restore rbx\n            out(\"r8\") ebx,\n            inout(\"eax\") leaf => eax,\n            inout(\"ecx\") 0 => ecx,\n            out(\"edx\") edx,\n            options(nostack, preserves_flags),\n        );\n    }\n    CpuidResult { eax, ebx, ecx, edx }\n}\n\n#[cold]\n#[must_use]\nfn _detect(mut info: CpuInfo) -> CpuInfo {\n    let CpuidResult { ecx: proc_info_ecx, .. } = __cpuid(1);\n\n    // https://github.com/rust-lang/rust/blob/1.92.0/library/std_detect/src/detect/os/x86.rs#L104\n    if test(proc_info_ecx, 13) {\n        info.set(CpuInfoFlag::cmpxchg16b);\n    }\n\n    // We only use VMOVDQA when SSE is enabled. See _atomic_load_vmovdqa() in atomic128/x86_64.rs for more.\n    #[cfg(target_feature = \"sse\")]\n    {\n        use core::arch::x86_64::_xgetbv;\n\n        // https://github.com/rust-lang/rust/blob/1.92.0/library/std_detect/src/detect/os/x86.rs#L166-L236\n        let cpu_xsave = test(proc_info_ecx, 26);\n        if cpu_xsave {\n            let cpu_osxsave = test(proc_info_ecx, 27);\n            if cpu_osxsave {\n                // SAFETY: Calling `_xgetbv` is safe because the CPU has `xsave` support\n                // and OS has set `osxsave`.\n                let xcr0 = unsafe { _xgetbv(0) };\n                let os_avx_support = xcr0 & 6 == 6;\n                if os_avx_support && test(proc_info_ecx, 28) {\n                    info.set(CpuInfoFlag::avx);\n                }\n            }\n        }\n    }\n    info\n}\n\n#[allow(\n    clippy::alloc_instead_of_core,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    clippy::undocumented_unsafe_blocks,\n    clippy::wildcard_imports\n)]\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    #[cfg_attr(portable_atomic_test_detect_false, ignore = \"detection disabled\")]\n    fn test_cpuid() {\n        // The recent Rosetta 2 unofficially implements AVX support.\n        // (The OS reports it as unsupported, likely due to poor performance.)\n        #[cfg(target_vendor = \"apple\")]\n        assert_eq!(\n            std::is_x86_feature_detected!(\"avx\"),\n            detect().avx() || cfg!(target_feature = \"avx\")\n        );\n        #[cfg(not(target_vendor = \"apple\"))]\n        assert_eq!(std::is_x86_feature_detected!(\"avx\"), detect().avx());\n        assert_eq!(std::is_x86_feature_detected!(\"cmpxchg16b\"), detect().cmpxchg16b());\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/fallback/mod.rs",
      "sha256": "970934078d4cf02e424f2bc80ad7724e188bc8fe4c883898311ef32b4601d826",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nFallback implementation using global locks.\n\nThis implementation uses seqlock for global locks.\n\nThis is basically based on global locks in crossbeam-utils's `AtomicCell`,\nbut seqlock is implemented in a way that does not depend on UB\n(see comments in optimistic_read method in atomic! macro for details).\n\nNote that we cannot use a lock per atomic type, since the in-memory representation of the atomic\ntype and the value type must be the same.\n*/\n\n#![cfg_attr(\n    any(\n        all(\n            target_arch = \"riscv32\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            not(portable_atomic_no_outline_atomics),\n            any(target_os = \"linux\", target_os = \"android\"),\n        ),\n        all(\n            target_arch = \"arm\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_os = \"linux\", target_os = \"android\"),\n            any(test, not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\"))),\n            not(portable_atomic_no_outline_atomics),\n        ),\n    ),\n    allow(dead_code)\n)]\n\n// This module requires CAS and this crate only provides atomics up to 128-bit.\n// I don't believe there are any 16-bit multi-core systems with CAS, and\n// at least no such architecture is currently supported in Rust.\n// 128-bit targets that lack atomic usize CAS also do not reach this module.\n#[cfg(target_pointer_width = \"16\")]\ncompile_error!(\n    \"internal error: unreachable since atomics for 16-bit targets can always be provided by disable interrupts\"\n);\n#[cfg(target_pointer_width = \"128\")]\ncompile_error!(\n    \"internal error: unreachable since 128-bit target either has atomic CAS for the pointer width or does not have CAS\"\n);\n\nmod utils;\n\n// Use \"wide\" sequence lock if the pointer width <= 32 for preventing its counter against wrap\n// around.\n//\n// Some 64-bit architectures have ABI with 32-bit pointer width (e.g., x86_64 X32 ABI,\n// AArch64 ILP32 ABI, mips64 N32 ABI). On those targets, AtomicU64 is available and fast,\n// so use it to implement normal sequence lock and reduce chunks of byte-wise atomic memcpy.\ncfg_has_fast_atomic_64!({\n    mod seq_lock;\n    type AtomicChunk = core::sync::atomic::AtomicU64;\n    type Chunk = u64;\n});\ncfg_no_fast_atomic_64!({\n    #[path = \"seq_lock_wide.rs\"]\n    mod seq_lock;\n    type AtomicChunk = core::sync::atomic::AtomicU32;\n    type Chunk = u32;\n});\n\nuse core::{cell::UnsafeCell, mem, sync::atomic::Ordering};\n\nuse self::{\n    seq_lock::{SeqLock, SeqLockWriteGuard},\n    utils::CachePadded,\n};\n#[cfg(portable_atomic_no_strict_provenance)]\nuse crate::utils::ptr::PtrExt as _;\nuse crate::utils::unlikely;\n\n// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/atomic_cell.rs#L970-L1010.\n#[inline]\n#[must_use]\nfn lock(addr: usize) -> &'static SeqLock {\n    // The number of locks is a prime number because we want to make sure `addr % LEN` gets\n    // dispersed across all locks.\n    const LEN: usize = 67;\n    const L: CachePadded<SeqLock> = CachePadded::new(SeqLock::new());\n    static LOCKS: [CachePadded<SeqLock>; LEN] = [\n        L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,\n        L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,\n        L, L, L, L, L, L, L,\n    ];\n\n    // If the modulus is a constant number, the compiler will use crazy math to transform this into\n    // a sequence of cheap arithmetic operations rather than using the slow modulo instruction.\n    &LOCKS[addr % LEN]\n}\n\n// Emit SeqCst fence to ensure SeqCst semantics when ordering is SeqCst.\n#[must_use]\nstruct ScFenceGuard;\nimpl ScFenceGuard {\n    #[inline]\n    fn new(emit_sc_fence: bool) -> Option<Self> {\n        if unlikely(emit_sc_fence) {\n            crate::fence(Ordering::SeqCst);\n            Some(ScFenceGuard)\n        } else {\n            None\n        }\n    }\n}\nimpl Drop for ScFenceGuard {\n    #[inline]\n    fn drop(&mut self) {\n        crate::fence(Ordering::SeqCst);\n    }\n}\n\nmacro_rules! atomic {\n    ($atomic_type:ident, $int_type:ident, $align:literal) => {\n        #[repr(C, align($align))]\n        pub(crate) struct $atomic_type {\n            v: UnsafeCell<$int_type>,\n        }\n\n        impl $atomic_type {\n            const LEN: usize = mem::size_of::<$int_type>() / mem::size_of::<Chunk>();\n\n            #[inline]\n            unsafe fn chunks(&self) -> &[AtomicChunk; Self::LEN] {\n                static_assert!($atomic_type::LEN > 1);\n                static_assert!(mem::size_of::<$int_type>() % mem::size_of::<Chunk>() == 0);\n\n                // SAFETY: the caller must uphold the safety contract for `chunks`.\n                unsafe { &*(self.v.get() as *const $int_type as *const [AtomicChunk; Self::LEN]) }\n            }\n\n            #[inline]\n            fn optimistic_read(&self) -> $int_type {\n                // Using `MaybeUninit<[usize; Self::LEN]>` here doesn't change codegen: https://godbolt.org/z/86f8s733M\n                let mut dst: [Chunk; Self::LEN] = [0; Self::LEN];\n                // SAFETY:\n                // - There are no threads that perform non-atomic concurrent write operations.\n                // - There is no writer that updates the value using atomic operations of different granularity.\n                //\n                // If the atomic operation is not used here, it will cause a data race\n                // when `write` performs concurrent write operation.\n                // Such a data race is sometimes considered virtually unproblematic\n                // in SeqLock implementations:\n                //\n                // - https://github.com/Amanieu/seqlock/issues/2\n                // - https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/atomic_cell.rs#L1063-L1069\n                // - https://rust-lang.zulipchat.com/#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/avoiding.20UB.20due.20to.20races.20by.20discarding.20result.3F\n                //\n                // However, in our use case, the implementation that loads/stores value as\n                // chunks of usize is enough fast and sound, so we use that implementation.\n                //\n                // See also atomic-memcpy crate, a generic implementation of this pattern:\n                // https://github.com/taiki-e/atomic-memcpy\n                let chunks = unsafe { self.chunks() };\n                for i in 0..Self::LEN {\n                    dst[i] = chunks[i].load(Ordering::Relaxed);\n                }\n                // SAFETY: integers are plain old data types so we can always transmute to them.\n                unsafe { mem::transmute::<[Chunk; Self::LEN], $int_type>(dst) }\n            }\n\n            #[inline]\n            fn read(&self, _guard: &SeqLockWriteGuard<'static>) -> $int_type {\n                // This calls optimistic_read that can return teared value, but the resulting value\n                // is guaranteed not to be teared because we hold the lock to write.\n                self.optimistic_read()\n            }\n\n            #[inline]\n            fn write(&self, val: $int_type, _guard: &SeqLockWriteGuard<'static>) {\n                // SAFETY: integers are plain old data types so we can always transmute them to arrays of integers.\n                let val = unsafe { mem::transmute::<$int_type, [Chunk; Self::LEN]>(val) };\n                // SAFETY:\n                // - The guard guarantees that we hold the lock to write.\n                // - There are no threads that perform non-atomic concurrent read or write operations.\n                //\n                // See optimistic_read for the reason that atomic operations are used here.\n                let chunks = unsafe { self.chunks() };\n                for i in 0..Self::LEN {\n                    chunks[i].store(val[i], Ordering::Relaxed);\n                }\n            }\n        }\n\n        // Send is implicitly implemented.\n        // SAFETY: any data races are prevented by the lock and atomic operation.\n        unsafe impl Sync for $atomic_type {}\n\n        #[cfg(any(\n            test,\n            not(any(\n                all(\n                    target_arch = \"x86_64\",\n                    not(all(\n                        any(miri, portable_atomic_sanitize_thread),\n                        portable_atomic_no_cmpxchg16b_intrinsic,\n                    )),\n                    any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n                    not(portable_atomic_no_outline_atomics),\n                    not(any(target_env = \"sgx\", miri)),\n                ),\n                all(\n                    target_arch = \"powerpc64\",\n                    not(portable_atomic_no_asm),\n                    not(portable_atomic_no_outline_atomics),\n                    any(\n                        all(\n                            target_os = \"linux\",\n                            any(\n                                all(\n                                    target_env = \"gnu\",\n                                    any(target_endian = \"little\", not(target_feature = \"crt-static\")),\n                                ),\n                                all(\n                                    target_env = \"musl\",\n                                    any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                                ),\n                                target_env = \"ohos\",\n                                all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                                portable_atomic_outline_atomics,\n                            ),\n                        ),\n                        target_os = \"android\",\n                        all(\n                            target_os = \"freebsd\",\n                            any(\n                                target_endian = \"little\",\n                                not(target_feature = \"crt-static\"),\n                                portable_atomic_outline_atomics,\n                            ),\n                        ),\n                        target_os = \"openbsd\",\n                        all(\n                            target_os = \"aix\",\n                            not(portable_atomic_pre_llvm_20),\n                            portable_atomic_outline_atomics, // TODO(aix): currently disabled by default\n                        ),\n                    ),\n                    not(any(miri, portable_atomic_sanitize_thread)),\n                ),\n                all(\n                    target_arch = \"riscv64\",\n                    not(any(miri, portable_atomic_sanitize_thread)),\n                    any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n                    not(portable_atomic_no_outline_atomics),\n                    any(target_os = \"linux\", target_os = \"android\"),\n                ),\n            )),\n        ))]\n        items!({\n            impl_default_no_fetch_ops!($atomic_type, $int_type);\n            impl_default_bit_opts!($atomic_type, $int_type);\n            impl $atomic_type {\n                #[inline]\n                pub(crate) const fn new(v: $int_type) -> Self {\n                    Self { v: UnsafeCell::new(v) }\n                }\n\n                #[inline]\n                pub(crate) fn is_lock_free() -> bool {\n                    Self::IS_ALWAYS_LOCK_FREE\n                }\n                pub(crate) const IS_ALWAYS_LOCK_FREE: bool = false;\n\n                #[inline]\n                #[cfg_attr(\n                    all(debug_assertions, not(portable_atomic_no_track_caller)),\n                    track_caller\n                )]\n                pub(crate) fn compare_exchange_weak(\n                    &self,\n                    current: $int_type,\n                    new: $int_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$int_type, $int_type> {\n                    self.compare_exchange(current, new, success, failure)\n                }\n\n                #[inline]\n                pub(crate) fn not(&self, order: Ordering) {\n                    self.fetch_not(order);\n                }\n                #[inline]\n                pub(crate) fn neg(&self, order: Ordering) {\n                    self.fetch_neg(order);\n                }\n\n                #[inline]\n                pub(crate) const fn as_ptr(&self) -> *mut $int_type {\n                    self.v.get()\n                }\n            }\n        });\n        #[cfg_attr(\n            any(\n                all(\n                    target_arch = \"x86_64\",\n                    not(all(\n                        any(miri, portable_atomic_sanitize_thread),\n                        portable_atomic_no_cmpxchg16b_intrinsic,\n                    )),\n                    any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n                    not(portable_atomic_no_outline_atomics),\n                    not(any(target_env = \"sgx\", miri)),\n                ),\n                all(\n                    target_arch = \"powerpc64\",\n                    not(portable_atomic_no_asm),\n                    not(portable_atomic_no_outline_atomics),\n                    any(\n                        all(\n                            target_os = \"linux\",\n                            any(\n                                all(\n                                    target_env = \"gnu\",\n                                    any(target_endian = \"little\", not(target_feature = \"crt-static\")),\n                                ),\n                                all(\n                                    target_env = \"musl\",\n                                    any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                                ),\n                                target_env = \"ohos\",\n                                all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                                portable_atomic_outline_atomics,\n                            ),\n                        ),\n                        target_os = \"android\",\n                        all(\n                            target_os = \"freebsd\",\n                            any(\n                                target_endian = \"little\",\n                                not(target_feature = \"crt-static\"),\n                                portable_atomic_outline_atomics,\n                            ),\n                        ),\n                        target_os = \"openbsd\",\n                        all(\n                            target_os = \"aix\",\n                            not(portable_atomic_pre_llvm_20),\n                            portable_atomic_outline_atomics, // TODO(aix): currently disabled by default\n                        ),\n                    ),\n                    not(any(miri, portable_atomic_sanitize_thread)),\n                ),\n                all(\n                    target_arch = \"riscv64\",\n                    not(any(miri, portable_atomic_sanitize_thread)),\n                    any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n                    not(portable_atomic_no_outline_atomics),\n                    any(target_os = \"linux\", target_os = \"android\"),\n                ),\n            ),\n            allow(dead_code)\n        )]\n        impl $atomic_type {\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn load(&self, order: Ordering) -> $int_type {\n                crate::utils::assert_load_ordering(order);\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let lock = lock(self.v.get().addr());\n\n                // Try doing an optimistic read first.\n                if let Some(stamp) = lock.optimistic_read() {\n                    let val = self.optimistic_read();\n\n                    if lock.validate_read(stamp) {\n                        return val;\n                    }\n                }\n\n                // Grab a regular write lock so that writers don't starve this load.\n                let guard = lock.write();\n                let val = self.read(&guard);\n                // The value hasn't been changed. Drop the guard without incrementing the stamp.\n                guard.abort();\n                val\n            }\n\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn store(&self, val: $int_type, order: Ordering) {\n                crate::utils::assert_store_ordering(order);\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                self.write(val, &guard)\n            }\n\n            #[inline]\n            pub(crate) fn swap(&self, val: $int_type, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(val, &guard);\n                prev\n            }\n\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn compare_exchange(\n                &self,\n                current: $int_type,\n                new: $int_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$int_type, $int_type> {\n                crate::utils::assert_compare_exchange_ordering(success, failure);\n                let _sc_fence = ScFenceGuard::new(\n                    success == Ordering::SeqCst || failure == Ordering::SeqCst\n                );\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                if prev == current {\n                    self.write(new, &guard);\n                    Ok(prev)\n                } else {\n                    // The value hasn't been changed. Drop the guard without incrementing the stamp.\n                    guard.abort();\n                    Err(prev)\n                }\n            }\n\n            #[inline]\n            pub(crate) fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(prev.wrapping_add(val), &guard);\n                prev\n            }\n\n            #[inline]\n            pub(crate) fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(prev.wrapping_sub(val), &guard);\n                prev\n            }\n\n            #[inline]\n            pub(crate) fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(prev & val, &guard);\n                prev\n            }\n\n            #[inline]\n            pub(crate) fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(!(prev & val), &guard);\n                prev\n            }\n\n            #[inline]\n            pub(crate) fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(prev | val, &guard);\n                prev\n            }\n\n            #[inline]\n            pub(crate) fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(prev ^ val, &guard);\n                prev\n            }\n\n            #[inline]\n            pub(crate) fn fetch_not(&self, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(!prev, &guard);\n                prev\n            }\n\n            #[inline]\n            pub(crate) fn fetch_neg(&self, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(prev.wrapping_neg(), &guard);\n                prev\n            }\n        }\n        impl $atomic_type {\n            #[inline]\n            pub(crate) fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(core::cmp::max(prev, val), &guard);\n                prev\n            }\n\n            #[inline]\n            pub(crate) fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {\n                let _sc_fence = ScFenceGuard::new(order == Ordering::SeqCst);\n                let guard = lock(self.v.get().addr()).write();\n                let prev = self.read(&guard);\n                self.write(core::cmp::min(prev, val), &guard);\n                prev\n            }\n        }\n    };\n}\n\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(any(\n        test,\n        not(any(\n            not(portable_atomic_no_atomic_64),\n            all(\n                target_arch = \"riscv32\",\n                not(any(miri, portable_atomic_sanitize_thread)),\n                any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n                any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n            ),\n        ))\n    ))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(\n        test,\n        not(any(\n            target_has_atomic = \"64\",\n            all(\n                target_arch = \"riscv32\",\n                not(any(miri, portable_atomic_sanitize_thread)),\n                any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n                any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n            ),\n        ))\n    ))\n)]\ncfg_no_fast_atomic_64!({\n    atomic!(AtomicI64, i64, 8);\n    atomic!(AtomicU64, u64, 8);\n});\n\natomic!(AtomicI128, i128, 16);\natomic!(AtomicU128, u128, 16);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    cfg_no_fast_atomic_64!({\n        test_atomic_int!(i64);\n        test_atomic_int!(u64);\n    });\n    test_atomic_int!(i128);\n    test_atomic_int!(u128);\n\n    // load/store/swap implementation is not affected by signedness, so it is\n    // enough to test only unsigned types.\n    cfg_no_fast_atomic_64!({\n        stress_test!(u64);\n    });\n    stress_test!(u128);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/fallback/outline_atomics.rs",
      "sha256": "041d872affc4ad0b6b452f695a1373a1f76fe75d1b2377c24c3c0d199d89e383",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nHelper for outline-atomics.\n\nOn architectures where DW atomics are not supported on older CPUs, we use\nfallback implementation when DW atomic instructions are not supported and\noutline-atomics is enabled.\n\nThis module provides helpers to implement them.\n*/\n\nuse core::sync::atomic::Ordering;\n\n#[cfg(any(target_arch = \"x86_64\", target_arch = \"powerpc64\", target_arch = \"riscv64\"))]\npub(crate) type Udw = u128;\n#[cfg(any(target_arch = \"x86_64\", target_arch = \"powerpc64\", target_arch = \"riscv64\"))]\npub(crate) type AtomicUdw = super::super::super::fallback::AtomicU128;\n#[cfg(any(target_arch = \"x86_64\", target_arch = \"powerpc64\", target_arch = \"riscv64\"))]\npub(crate) type AtomicIdw = super::super::super::fallback::AtomicI128;\n\n#[cfg(any(target_arch = \"arm\", target_arch = \"riscv32\"))]\npub(crate) type Udw = u64;\n#[cfg(any(target_arch = \"arm\", target_arch = \"riscv32\"))]\npub(crate) type AtomicUdw = super::super::super::fallback::AtomicU64;\n#[cfg(any(target_arch = \"arm\", target_arch = \"riscv32\"))]\npub(crate) type AtomicIdw = super::super::super::fallback::AtomicI64;\n\n// Asserts that the function is called in the correct context.\nmacro_rules! debug_assert_outline_atomics {\n    () => {\n        #[cfg(target_arch = \"x86_64\")]\n        {\n            debug_assert!(!super::detect::detect().cmpxchg16b());\n        }\n        #[cfg(target_arch = \"powerpc64\")]\n        {\n            debug_assert!(!super::detect::detect().quadword_atomics());\n        }\n        #[cfg(any(target_arch = \"riscv32\", target_arch = \"riscv64\"))]\n        {\n            debug_assert!(!super::detect::detect().zacas());\n        }\n        #[cfg(target_arch = \"arm\")]\n        {\n            debug_assert!(!super::has_kuser_cmpxchg64());\n        }\n    };\n}\n\n#[cold]\npub(crate) unsafe fn atomic_load(src: *mut Udw, order: Ordering) -> Udw {\n    debug_assert_outline_atomics!();\n    #[allow(clippy::cast_ptr_alignment)]\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        (*(src as *const AtomicUdw)).load(order)\n    }\n}\nfn_alias! {\n    #[cold]\n    pub(crate) unsafe fn(src: *mut Udw) -> Udw;\n    // fallback's atomic load has at least acquire semantics.\n    #[cfg(not(any(target_arch = \"arm\", target_arch = \"x86_64\")))]\n    atomic_load_non_seqcst = atomic_load(Ordering::Acquire);\n    atomic_load_seqcst = atomic_load(Ordering::SeqCst);\n}\n\n#[cfg(not(any(target_arch = \"arm\", target_arch = \"riscv32\", target_arch = \"riscv64\")))]\n#[cold]\npub(crate) unsafe fn atomic_store(dst: *mut Udw, val: Udw, order: Ordering) {\n    debug_assert_outline_atomics!();\n    #[allow(clippy::cast_ptr_alignment)]\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        (*(dst as *const AtomicUdw)).store(val, order);\n    }\n}\n#[cfg(not(any(target_arch = \"arm\", target_arch = \"riscv32\", target_arch = \"riscv64\")))]\nfn_alias! {\n    #[cold]\n    pub(crate) unsafe fn(dst: *mut Udw, val: Udw);\n    // fallback's atomic store has at least release semantics.\n    atomic_store_non_seqcst = atomic_store(Ordering::Release);\n    atomic_store_seqcst = atomic_store(Ordering::SeqCst);\n}\n\n#[cold]\npub(crate) unsafe fn atomic_compare_exchange(\n    dst: *mut Udw,\n    old: Udw,\n    new: Udw,\n    success: Ordering,\n    failure: Ordering,\n) -> (Udw, bool) {\n    debug_assert_outline_atomics!();\n    #[allow(clippy::cast_ptr_alignment)]\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        match (*(dst as *const AtomicUdw)).compare_exchange(old, new, success, failure) {\n            Ok(v) => (v, true),\n            Err(v) => (v, false),\n        }\n    }\n}\nfn_alias! {\n    #[cold]\n    pub(crate) unsafe fn(dst: *mut Udw, old: Udw, new: Udw) -> (Udw, bool);\n    // fallback's atomic CAS has at least AcqRel semantics.\n    #[cfg(not(any(target_arch = \"arm\", target_arch = \"x86_64\")))]\n    atomic_compare_exchange_non_seqcst\n        = atomic_compare_exchange(Ordering::AcqRel, Ordering::Acquire);\n    atomic_compare_exchange_seqcst\n        = atomic_compare_exchange(Ordering::SeqCst, Ordering::SeqCst);\n}\n\nmacro_rules! atomic_rmw_3 {\n    (\n        $name:ident($atomic_type:ident::$method_name:ident),\n        $non_seqcst_alias:ident, $seqcst_alias:ident\n    ) => {\n        #[cold]\n        pub(crate) unsafe fn $name(dst: *mut Udw, val: Udw, order: Ordering) -> Udw {\n            debug_assert_outline_atomics!();\n            #[allow(\n                clippy::as_underscore,\n                clippy::cast_possible_wrap,\n                clippy::cast_ptr_alignment,\n                clippy::cast_sign_loss\n            )]\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                (*(dst as *const $atomic_type)).$method_name(val as _, order) as Udw\n            }\n        }\n        fn_alias! {\n            #[cold]\n            pub(crate) unsafe fn(dst: *mut Udw, val: Udw) -> Udw;\n            // fallback's atomic RMW has at least AcqRel semantics.\n            #[cfg(not(any(target_arch = \"arm\", target_arch = \"x86_64\")))]\n            $non_seqcst_alias = $name(Ordering::AcqRel);\n            $seqcst_alias = $name(Ordering::SeqCst);\n        }\n    };\n}\nmacro_rules! atomic_rmw_2 {\n    (\n        $name:ident($atomic_type:ident::$method_name:ident),\n        $non_seqcst_alias:ident, $seqcst_alias:ident\n    ) => {\n        #[cold]\n        pub(crate) unsafe fn $name(dst: *mut Udw, order: Ordering) -> Udw {\n            debug_assert_outline_atomics!();\n            #[allow(clippy::cast_ptr_alignment)]\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe {\n                (*(dst as *const $atomic_type)).$method_name(order) as Udw\n            }\n        }\n        fn_alias! {\n            #[cold]\n            pub(crate) unsafe fn(dst: *mut Udw) -> Udw;\n            // fallback's atomic RMW has at least AcqRel semantics.\n            #[cfg(not(any(target_arch = \"arm\", target_arch = \"x86_64\")))]\n            $non_seqcst_alias = $name(Ordering::AcqRel);\n            $seqcst_alias = $name(Ordering::SeqCst);\n        }\n    };\n}\n\natomic_rmw_3!(atomic_swap(AtomicUdw::swap), atomic_swap_non_seqcst, atomic_swap_seqcst);\natomic_rmw_3!(atomic_add(AtomicUdw::fetch_add), atomic_add_non_seqcst, atomic_add_seqcst);\natomic_rmw_3!(atomic_sub(AtomicUdw::fetch_sub), atomic_sub_non_seqcst, atomic_sub_seqcst);\natomic_rmw_3!(atomic_and(AtomicUdw::fetch_and), atomic_and_non_seqcst, atomic_and_seqcst);\natomic_rmw_3!(atomic_nand(AtomicUdw::fetch_nand), atomic_nand_non_seqcst, atomic_nand_seqcst);\natomic_rmw_3!(atomic_or(AtomicUdw::fetch_or), atomic_or_non_seqcst, atomic_or_seqcst);\natomic_rmw_3!(atomic_xor(AtomicUdw::fetch_xor), atomic_xor_non_seqcst, atomic_xor_seqcst);\natomic_rmw_3!(atomic_max(AtomicIdw::fetch_max), atomic_max_non_seqcst, atomic_max_seqcst);\natomic_rmw_3!(atomic_umax(AtomicUdw::fetch_max), atomic_umax_non_seqcst, atomic_umax_seqcst);\natomic_rmw_3!(atomic_min(AtomicIdw::fetch_min), atomic_min_non_seqcst, atomic_min_seqcst);\natomic_rmw_3!(atomic_umin(AtomicUdw::fetch_min), atomic_umin_non_seqcst, atomic_umin_seqcst);\n\natomic_rmw_2!(atomic_not(AtomicUdw::fetch_not), atomic_not_non_seqcst, atomic_not_seqcst);\natomic_rmw_2!(atomic_neg(AtomicUdw::fetch_neg), atomic_neg_non_seqcst, atomic_neg_seqcst);\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/fallback/seq_lock.rs",
      "sha256": "f099568551ecd866b8deff71655421f7eff21d045af598debe44d7a355c7bb39",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/seq_lock.rs.\n\ninclude!(\"seq_lock_common.rs\");\n\nuse crate::imp::core_atomic::AtomicU64;\n\npub(super) type State = u64;\n\n/// A simple stamped lock.\npub(super) struct SeqLock {\n    /// The current state of the lock.\n    ///\n    /// All bits except the least significant one hold the current stamp. When locked, the state\n    /// equals 1 and doesn't contain a valid stamp.\n    state: AtomicU64,\n}\n\nimpl SeqLock {\n    #[inline]\n    pub(super) const fn new() -> Self {\n        Self { state: AtomicU64::new(0) }\n    }\n\n    /// If not locked, returns the current stamp.\n    ///\n    /// This method should be called before optimistic reads.\n    #[inline]\n    pub(super) fn optimistic_read(&self) -> Option<State> {\n        // The acquire load from `state` synchronizes with the release stores in\n        // `SeqLockWriteGuard::drop` and `SeqLockWriteGuard::abort`.\n        let state = self.state.load(Ordering::Acquire);\n        if state == LOCKED { None } else { Some(state) }\n    }\n\n    /// Returns `true` if the current stamp is equal to `stamp`.\n    ///\n    /// This method should be called after optimistic reads to check whether they are valid. The\n    /// argument `stamp` should correspond to the one returned by method `optimistic_read`.\n    #[inline]\n    pub(super) fn validate_read(&self, stamp: State) -> bool {\n        // Thanks to the fence, if we're noticing any modification to the data at the critical\n        // section of `stamp`, then the critical section's write of 1 to state\n        // should be visible.\n        crate::fence(Ordering::Acquire);\n        self.state.load(Ordering::Relaxed) == stamp\n    }\n}\n\nimpl SeqLockWriteGuard<'_> {\n    #[inline]\n    fn next_stamp(&self) -> State {\n        self.state.wrapping_add(2)\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/fallback/seq_lock_common.rs",
      "sha256": "2c519835f7a9b20b64b9cc3428dcf9ed18ad7e56fd73791404d4f7f87975dd3e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/seq_lock.rs\n// and https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/seq_lock_wide.rs.\n\nuse core::{mem::ManuallyDrop, sync::atomic::Ordering};\n\nuse super::utils::Backoff;\n#[cfg(portable_atomic_unsafe_assume_privileged)]\nuse crate::imp::interrupt::arch as interrupt;\n\nconst LOCKED: State = 1;\n\nimpl SeqLock {\n    /// Grabs the lock for writing.\n    #[inline]\n    pub(super) fn write(&self) -> SeqLockWriteGuard<'_> {\n        // Get current interrupt state and disable interrupts when the user\n        // explicitly declares that privileged instructions are available.\n        #[cfg(portable_atomic_unsafe_assume_privileged)]\n        let interrupt_state = interrupt::disable();\n\n        let mut backoff = Backoff::new();\n        loop {\n            let previous = self.state.swap(LOCKED, Ordering::Acquire);\n\n            if previous != LOCKED {\n                // To synchronize with the acquire fence in `validate_read` via any modification to\n                // the data at the critical section of `previous` (seq_lock.rs) or `(state_hi, previous)`\n                // (seq_lock_wide.rs).\n                crate::fence(Ordering::Release);\n\n                return SeqLockWriteGuard {\n                    lock: self,\n                    state: previous,\n                    #[cfg(portable_atomic_unsafe_assume_privileged)]\n                    interrupt_state,\n                };\n            }\n\n            while self.state.load(Ordering::Relaxed) == LOCKED {\n                backoff.snooze();\n            }\n        }\n    }\n}\n\n/// An RAII guard that releases the lock and increments the stamp when dropped.\n#[must_use]\npub(crate) struct SeqLockWriteGuard<'a> {\n    /// The parent lock.\n    lock: &'a SeqLock,\n\n    /// The stamp before locking.\n    state: State,\n\n    /// The interrupt state before disabling.\n    #[cfg(portable_atomic_unsafe_assume_privileged)]\n    interrupt_state: interrupt::State,\n}\n\nimpl SeqLockWriteGuard<'_> {\n    /// Releases the lock without incrementing the stamp.\n    #[inline]\n    pub(crate) fn abort(self) {\n        // We specifically don't want to call drop(), since that's\n        // what increments the stamp.\n        let this = ManuallyDrop::new(self);\n\n        // Restore the stamp.\n        //\n        // Release ordering for synchronizing with `optimistic_read`.\n        this.lock.state.store(this.state, Ordering::Release);\n\n        // Restore interrupt state.\n        // SAFETY: the state was retrieved by the previous `disable`.\n        #[cfg(portable_atomic_unsafe_assume_privileged)]\n        unsafe {\n            interrupt::restore(this.interrupt_state);\n        }\n    }\n}\n\nimpl Drop for SeqLockWriteGuard<'_> {\n    #[inline]\n    fn drop(&mut self) {\n        let state = self.next_stamp();\n\n        // Release the lock and increment the stamp.\n        //\n        // Release ordering for synchronizing with `optimistic_read`.\n        self.lock.state.store(state, Ordering::Release);\n\n        // Restore interrupt state.\n        // SAFETY: the state was retrieved by the previous `disable`.\n        #[cfg(portable_atomic_unsafe_assume_privileged)]\n        unsafe {\n            interrupt::restore(self.interrupt_state);\n        }\n    }\n}\n\n#[cfg(test)]\n#[allow(clippy::items_after_test_module)]\nmod tests {\n    use core::sync::atomic::Ordering;\n\n    use super::SeqLock;\n\n    #[test]\n    fn smoke() {\n        let lock = SeqLock::new();\n        let before = lock.optimistic_read().unwrap();\n        assert!(lock.validate_read(before));\n        {\n            let _guard = lock.write();\n            assert!(lock.optimistic_read().is_none());\n        }\n        assert!(!lock.validate_read(before));\n        let after = lock.optimistic_read().unwrap();\n        assert_ne!(before, after);\n    }\n\n    #[test]\n    fn test_wrap() {\n        let lock = SeqLock::new();\n        let zero = lock.optimistic_read().unwrap();\n        lock.state.store(0xFFFF_FFFE, Ordering::Relaxed); // u32::MAX & !1\n        let before = lock.optimistic_read().unwrap();\n        assert!(lock.validate_read(before));\n        {\n            let _guard = lock.write();\n            assert!(lock.optimistic_read().is_none());\n        }\n        assert!(!lock.validate_read(before));\n        let after = lock.optimistic_read().unwrap();\n        assert_ne!(before, after);\n        assert_ne!(after, zero);\n        #[allow(clippy::identity_op)]\n        {\n            assert_eq!(lock.state.load(Ordering::Relaxed) & 0xFFFF_FFFF, 0);\n        }\n    }\n\n    #[test]\n    fn test_abort() {\n        let lock = SeqLock::new();\n        let before = lock.optimistic_read().unwrap();\n        {\n            let guard = lock.write();\n            assert!(lock.optimistic_read().is_none());\n            guard.abort();\n        }\n        let after = lock.optimistic_read().unwrap();\n        assert_eq!(before, after, \"aborted write does not update the stamp\");\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/fallback/seq_lock_wide.rs",
      "sha256": "b2870e179e7d903327ef4ca52e13471e771622ebefd8b06940a5584d8e83416c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/atomic/seq_lock_wide.rs.\n\ninclude!(\"seq_lock_common.rs\");\n\nuse crate::imp::core_atomic::AtomicU32;\n\npub(super) type State = u32;\n\n/// A simple stamped lock.\n///\n/// The state is represented as two `AtomicU32`: `state_hi` for high bits and `state_lo` for low\n/// bits.\npub(super) struct SeqLock {\n    /// The high bits of the current state of the lock.\n    state_hi: AtomicU32,\n\n    /// The low bits of the current state of the lock.\n    ///\n    /// All bits except the least significant one hold the current stamp. When locked, the state_lo\n    /// equals 1 and doesn't contain a valid stamp.\n    state: AtomicU32,\n}\n\nimpl SeqLock {\n    #[inline]\n    pub(super) const fn new() -> Self {\n        Self { state_hi: AtomicU32::new(0), state: AtomicU32::new(0) }\n    }\n\n    /// If not locked, returns the current stamp.\n    ///\n    /// This method should be called before optimistic reads.\n    #[inline]\n    pub(super) fn optimistic_read(&self) -> Option<(State, State)> {\n        // The acquire loads from `state_hi` and `state_lo` synchronize with the release stores in\n        // `SeqLockWriteGuard::drop` and `SeqLockWriteGuard::abort`.\n        //\n        // As a consequence, we can make sure that (1) all writes within the era of `state_hi - 1`\n        // happens before now; and therefore, (2) if `state_lo` is even, all writes within the\n        // critical section of (`state_hi`, `state_lo`) happens before now.\n        let state_hi = self.state_hi.load(Ordering::Acquire);\n        let state_lo = self.state.load(Ordering::Acquire);\n        if state_lo == LOCKED { None } else { Some((state_hi, state_lo)) }\n    }\n\n    /// Returns `true` if the current stamp is equal to `stamp`.\n    ///\n    /// This method should be called after optimistic reads to check whether they are valid. The\n    /// argument `stamp` should correspond to the one returned by method `optimistic_read`.\n    #[inline]\n    pub(super) fn validate_read(&self, stamp: (State, State)) -> bool {\n        // Thanks to the fence, if we're noticing any modification to the data at the critical\n        // section of `(stamp.0, stamp.1)`, then the critical section's write of 1 to state_lo\n        // should be visible.\n        crate::fence(Ordering::Acquire);\n\n        // So if `state_lo` coincides with `stamp.1`, then either (1) we're noticing no modification\n        // to the data after the critical section of `(stamp.0, stamp.1)`, or (2) `state_lo` wrapped\n        // around.\n        //\n        // If (2) is the case, the acquire ordering ensures we see the new value of `state_hi`.\n        let state_lo = self.state.load(Ordering::Acquire);\n\n        // If (2) is the case and `state_hi` coincides with `stamp.0`, then `state_hi` also wrapped\n        // around, which we give up to correctly validate the read.\n        let state_hi = self.state_hi.load(Ordering::Relaxed);\n\n        // Except for the case that both `state_hi` and `state_lo` wrapped around, the following\n        // condition implies that we're noticing no modification to the data after the critical\n        // section of `(stamp.0, stamp.1)`.\n        (state_hi, state_lo) == stamp\n    }\n}\n\nimpl SeqLockWriteGuard<'_> {\n    #[inline]\n    fn next_stamp(&self) -> State {\n        let state_lo = self.state.wrapping_add(2);\n\n        // Increase the high bits if the low bits wrap around.\n        //\n        // Release ordering for synchronizing with `optimistic_read`.\n        if state_lo == 0 {\n            let state_hi = self.lock.state_hi.load(Ordering::Relaxed);\n            self.lock.state_hi.store(state_hi.wrapping_add(1), Ordering::Release);\n        }\n\n        state_lo\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/fallback/utils.rs",
      "sha256": "4b04423031fa66eaf7619e4ddbb30689eb834f74e9dd876b8f4d163cf9c75f73",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse core::ops;\n\n// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/cache_padded.rs.\n/// Pads and aligns a value to the length of a cache line.\n// Starting from Intel's Sandy Bridge, spatial prefetcher is now pulling pairs of 64-byte cache\n// lines at a time, so we have to align to 128 bytes rather than 64.\n//\n// Sources:\n// - https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf\n// - https://github.com/facebook/folly/blob/1b5288e6eea6df074758f877c849b6e73bbb9fbb/folly/lang/Align.h#L107\n//\n// aarch64/arm64ec's big.LITTLE architecture has asymmetric cores and \"big\" cores have 128-byte cache line size.\n//\n// Sources:\n// - https://www.mono-project.com/news/2016/09/12/arm64-icache/\n//\n// powerpc64 has 128-byte cache line size.\n//\n// Sources:\n// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_ppc64x.go#L9\n// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/powerpc/include/asm/cache.h#L26\n#[cfg_attr(\n    any(\n        target_arch = \"x86_64\",\n        target_arch = \"aarch64\",\n        target_arch = \"arm64ec\",\n        target_arch = \"powerpc64\",\n    ),\n    repr(align(128))\n)]\n// arm, mips, mips64, sparc, and hexagon have 32-byte cache line size.\n//\n// Sources:\n// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_arm.go#L7\n// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips.go#L7\n// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7\n// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9\n// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/sparc/include/asm/cache.h#L17\n// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/hexagon/include/asm/cache.h#L12\n#[cfg_attr(\n    any(\n        target_arch = \"arm\",\n        target_arch = \"mips\",\n        target_arch = \"mips32r6\",\n        target_arch = \"mips64\",\n        target_arch = \"mips64r6\",\n        target_arch = \"sparc\",\n        target_arch = \"hexagon\",\n    ),\n    repr(align(32))\n)]\n// m68k has 16-byte cache line size.\n//\n// Sources:\n// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/m68k/include/asm/cache.h#L9\n#[cfg_attr(target_arch = \"m68k\", repr(align(16)))]\n// s390x has 256-byte cache line size.\n//\n// Sources:\n// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_s390x.go#L7\n// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/s390/include/asm/cache.h#L13\n#[cfg_attr(target_arch = \"s390x\", repr(align(256)))]\n// x86, wasm, riscv, and sparc64 have 64-byte cache line size.\n//\n// Sources:\n// - https://github.com/golang/go/blob/dda2991c2ea0c5914714469c4defc2562a907230/src/internal/cpu/cpu_x86.go#L9\n// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_wasm.go#L7\n// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/riscv/include/asm/cache.h#L10\n// - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/sparc/include/asm/cache.h#L19\n//\n// All others are assumed to have 64-byte cache line size.\n#[cfg_attr(\n    not(any(\n        target_arch = \"x86_64\",\n        target_arch = \"aarch64\",\n        target_arch = \"arm64ec\",\n        target_arch = \"powerpc64\",\n        target_arch = \"arm\",\n        target_arch = \"mips\",\n        target_arch = \"mips32r6\",\n        target_arch = \"mips64\",\n        target_arch = \"mips64r6\",\n        target_arch = \"sparc\",\n        target_arch = \"hexagon\",\n        target_arch = \"m68k\",\n        target_arch = \"s390x\",\n    )),\n    repr(align(64))\n)]\n#[repr(C)]\npub(crate) struct CachePadded<T> {\n    value: T,\n}\n\nimpl<T> CachePadded<T> {\n    #[inline]\n    pub(crate) const fn new(value: T) -> Self {\n        Self { value }\n    }\n}\n\nimpl<T> ops::Deref for CachePadded<T> {\n    type Target = T;\n\n    #[inline]\n    fn deref(&self) -> &Self::Target {\n        &self.value\n    }\n}\n\n// Adapted from https://github.com/crossbeam-rs/crossbeam/blob/crossbeam-utils-0.8.21/crossbeam-utils/src/backoff.rs.\n// Adjusted to reduce spinning.\n/// Performs exponential backoff in spin loops.\npub(crate) struct Backoff {\n    step: u32,\n}\n\n// https://github.com/oneapi-src/oneTBB/blob/v2021.5.0/include/oneapi/tbb/detail/_utils.h#L46-L48\nconst SPIN_LIMIT: u32 = 4;\n\nimpl Backoff {\n    #[inline]\n    pub(crate) const fn new() -> Self {\n        Self { step: 0 }\n    }\n\n    #[inline]\n    pub(crate) fn snooze(&mut self) {\n        if self.step <= SPIN_LIMIT {\n            for _ in 0..1 << self.step {\n                #[allow(deprecated)]\n                core::sync::atomic::spin_loop_hint();\n            }\n            self.step += 1;\n        } else {\n            #[cfg(not(feature = \"std\"))]\n            for _ in 0..1 << self.step {\n                #[allow(deprecated)]\n                core::sync::atomic::spin_loop_hint();\n            }\n\n            #[cfg(feature = \"std\")]\n            std::thread::yield_now();\n        }\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/float/aarch64.rs",
      "sha256": "b3d69ef526252b8ee99662f2059898cfa6cb99e1c969828225a2be99de2d45df",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nAtomic float implementation based on AArch64 with FEAT_LSFE.\n\nThis module provides atomic float implementations using FEAT_LSFE instructions.\n\nGenerated asm:\n- aarch64 (+lsfe) https://godbolt.org/z/7vaxeofv1\n*/\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\nuse core::sync::atomic::Ordering;\n\n#[cfg(portable_atomic_unstable_f16)]\nuse super::int::AtomicF16;\n#[cfg(portable_atomic_unstable_f128)]\nuse super::int::AtomicF128;\nuse super::int::{AtomicF32, AtomicF64};\n\n// TODO: optimize no return cases:\n// https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/STFADD--STFADDL--Floating-point-atomic-add-in-memory--without-return-\n// https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/STFMAXNM--STFMAXNML--Floating-point-atomic-maximum-number-in-memory--without-return-\n// https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/STFMINNM--STFMINNML--Floating-point-atomic-minimum-number-in-memory--without-return-\n\n#[cfg(not(portable_atomic_pre_llvm_20))]\nmacro_rules! start_lsfe {\n    () => {\n        \".arch_extension lsfe\"\n    };\n}\n\n#[cfg(not(portable_atomic_pre_llvm_20))]\nmacro_rules! atomic_rmw {\n    ($op:ident, $order:ident) => {\n        atomic_rmw!($op, $order, write = $order)\n    };\n    ($op:ident, $order:ident, write = $write:ident) => {\n        match $order {\n            Ordering::Relaxed => $op!(\"\", \"\", \"\"),\n            Ordering::Acquire => $op!(\"a\", \"\", \"\"),\n            Ordering::Release => $op!(\"\", \"l\", \"\"),\n            Ordering::AcqRel => $op!(\"a\", \"l\", \"\"),\n            // In MSVC environments, SeqCst stores/writes by non-LSE* instructions needs fences after writes.\n            // https://reviews.llvm.org/D141748\n            // https://github.com/llvm/llvm-project/commit/1ea201d73be2fdf03347e9c6be09ebed5f8e0e00\n            #[cfg(target_env = \"msvc\")]\n            Ordering::SeqCst if $write == Ordering::SeqCst => $op!(\"a\", \"l\", \"dmb ish\"),\n            // AcqRel and SeqCst RMWs are equivalent in non-MSVC environments.\n            Ordering::SeqCst => $op!(\"a\", \"l\", \"\"),\n            _ => unreachable!(),\n        }\n    };\n}\n#[cfg(portable_atomic_pre_llvm_20)]\nmacro_rules! atomic_rmw_inst {\n    ($op:ident, $order:ident) => {\n        atomic_rmw_inst!($op, $order, write = $order)\n    };\n    ($op:ident, $order:ident, write = $write:ident) => {\n        match $order {\n            Ordering::Relaxed => $op!(\"2\", \"\"), // \"\"\n            Ordering::Acquire => $op!(\"a\", \"\"), // \"a\"\n            Ordering::Release => $op!(\"6\", \"\"), // \"l\"\n            Ordering::AcqRel => $op!(\"e\", \"\"),  // \"al\"\n            // In MSVC environments, SeqCst stores/writes by non-LSE* instructions needs fences after writes.\n            // https://reviews.llvm.org/D141748\n            // https://github.com/llvm/llvm-project/commit/1ea201d73be2fdf03347e9c6be09ebed5f8e0e00\n            #[cfg(target_env = \"msvc\")]\n            Ordering::SeqCst if $write == Ordering::SeqCst => $op!(\"e\", \"dmb ish\"),\n            // AcqRel and SeqCst RMWs are equivalent in non-MSVC environments.\n            Ordering::SeqCst => $op!(\"e\", \"\"),\n            _ => unreachable!(),\n        }\n    };\n}\n\n#[rustfmt::skip]\nmacro_rules! atomic_float {\n    ($atomic_type:ident, $float_type:ident, $modifier:tt, $inst_modifier:tt) => {\n        impl $atomic_type {\n            #[inline]\n            pub(crate) fn fetch_add(&self, val: $float_type, order: Ordering) -> $float_type {\n                let dst = self.as_ptr();\n                let out;\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                //\n                // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/LDFADD--LDFADDA--LDFADDAL--LDFADDL--Floating-point-atomic-add-in-memory-\n                unsafe {\n                    #[cfg(not(portable_atomic_pre_llvm_20))]\n                    macro_rules! add {\n                        ($acquire:tt, $release:tt, $_msvc_fence:tt) => {\n                            asm!(\n                                start_lsfe!(),\n                                concat!(\"ldfadd\", $acquire, $release, \" {val:\", $modifier, \"}, {out:\", $modifier, \"}, [{dst}]\"), // atomic { _x = *dst; *dst = _x + val; out = _x }\n                                dst = in(reg) ptr_reg!(dst),\n                                val = in(vreg) val,\n                                out = lateout(vreg) out,\n                                options(nostack),\n                            )\n                        };\n                    }\n                    #[cfg(not(portable_atomic_pre_llvm_20))]\n                    atomic_rmw!(add, order);\n                    // LLVM supports FEAT_LSFE instructions on LLVM 20+, so use .inst directive on old LLVM.\n                    // https://github.com/llvm/llvm-project/commit/67ff5ba9af9754261abe11d762af11532a816126\n                    #[cfg(portable_atomic_pre_llvm_20)]\n                    macro_rules! add {\n                        ($order:tt, $_msvc_fence:tt) => {\n                            asm!(\n                                // ldfadd{,a,l,al} {h,s,d}0, {h,s,d}1, [x2] // atomic { _x = *x2; *x2 = _x + {h,s,d}0; {h,s,d}1 = _x }\n                                concat!(\".inst 0x\", $inst_modifier, \"c\", $order, \"00041\"),\n                                in(\"x2\") ptr_reg!(dst),\n                                in(\"v0\") val,\n                                out(\"v1\") out,\n                                options(nostack),\n                            )\n                        };\n                    }\n                    #[cfg(portable_atomic_pre_llvm_20)]\n                    atomic_rmw_inst!(add, order);\n                }\n                out\n            }\n            #[inline]\n            pub(crate) fn fetch_sub(&self, val: $float_type, order: Ordering) -> $float_type {\n                // There is no atomic sub instruction, so add `-val`.\n                self.fetch_add(-val, order)\n            }\n            #[inline]\n            pub(crate) fn fetch_max(&self, val: $float_type, order: Ordering) -> $float_type {\n                let dst = self.as_ptr();\n                let out;\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                //\n                // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/LDFMAXNM--LDFMAXNMA--LDFMAXNMAL--LDFMAXNML--Floating-point-atomic-maximum-number-in-memory-\n                unsafe {\n                    #[cfg(not(portable_atomic_pre_llvm_20))]\n                    macro_rules! max {\n                        ($acquire:tt, $release:tt, $_msvc_fence:tt) => {\n                            asm!(\n                                start_lsfe!(),\n                                concat!(\"ldfmaxnm\", $acquire, $release, \" {val:\", $modifier, \"}, {out:\", $modifier, \"}, [{dst}]\"), // atomic { _x = *dst; *dst = _x.max(val); out = _x }\n                                dst = in(reg) ptr_reg!(dst),\n                                val = in(vreg) val,\n                                out = lateout(vreg) out,\n                                options(nostack),\n                            )\n                        };\n                    }\n                    #[cfg(not(portable_atomic_pre_llvm_20))]\n                    atomic_rmw!(max, order);\n                    // LLVM supports FEAT_LSFE instructions on LLVM 20+, so use .inst directive on old LLVM.\n                    // https://github.com/llvm/llvm-project/commit/67ff5ba9af9754261abe11d762af11532a816126\n                    #[cfg(portable_atomic_pre_llvm_20)]\n                    macro_rules! max {\n                        ($order:tt, $_msvc_fence:tt) => {\n                            asm!(\n                                // ldfmaxnm{,a,l,al} {h,s,d}0, {h,s,d}1, [x2] // atomic { _x = *x2; *x2 = _x.max({h,s,d}0); {h,s,d}1 = _x }\n                                concat!(\".inst 0x\", $inst_modifier, \"c\", $order, \"06041\"),\n                                in(\"x2\") ptr_reg!(dst),\n                                in(\"v0\") val,\n                                out(\"v1\") out,\n                                options(nostack),\n                            )\n                        };\n                    }\n                    #[cfg(portable_atomic_pre_llvm_20)]\n                    atomic_rmw_inst!(max, order);\n                }\n                out\n            }\n            #[inline]\n            pub(crate) fn fetch_min(&self, val: $float_type, order: Ordering) -> $float_type {\n                let dst = self.as_ptr();\n                let out;\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                //\n                // Refs: https://developer.arm.com/documentation/ddi0602/2025-06/SIMD-FP-Instructions/LDFMINNM--LDFMINNMA--LDFMINNMAL--LDFMINNML--Floating-point-atomic-minimum-number-in-memory-\n                unsafe {\n                    #[cfg(not(portable_atomic_pre_llvm_20))]\n                    macro_rules! min {\n                        ($acquire:tt, $release:tt, $_msvc_fence:tt) => {\n                            asm!(\n                                start_lsfe!(),\n                                concat!(\"ldfminnm\", $acquire, $release, \" {val:\", $modifier, \"}, {out:\", $modifier, \"}, [{dst}]\"), // atomic { _x = *dst; *dst = _x.min(val); out = _x }\n                                dst = in(reg) ptr_reg!(dst),\n                                val = in(vreg) val,\n                                out = lateout(vreg) out,\n                                options(nostack),\n                            )\n                        };\n                    }\n                    #[cfg(not(portable_atomic_pre_llvm_20))]\n                    atomic_rmw!(min, order);\n                    // LLVM supports FEAT_LSFE instructions on LLVM 20+, so use .inst directive on old LLVM.\n                    // https://github.com/llvm/llvm-project/commit/67ff5ba9af9754261abe11d762af11532a816126\n                    #[cfg(portable_atomic_pre_llvm_20)]\n                    macro_rules! min {\n                        ($order:tt, $_msvc_fence:tt) => {\n                            asm!(\n                                // ldfminnm{,a,l,al} {h,s,d}0, {h,s,d}1, [x2] // atomic { _x = *x2; *x2 = _x.min({h,s,d}0); {h,s,d}1 = _x }\n                                concat!(\".inst 0x\", $inst_modifier, \"c\", $order, \"07041\"),\n                                in(\"x2\") ptr_reg!(dst),\n                                in(\"v0\") val,\n                                out(\"v1\") out,\n                                options(nostack),\n                            )\n                        };\n                    }\n                    #[cfg(portable_atomic_pre_llvm_20)]\n                    atomic_rmw_inst!(min, order);\n                }\n                out\n            }\n        }\n    };\n}\n\n#[cfg(portable_atomic_unstable_f16)]\natomic_float!(AtomicF16, f16, \"h\", \"7\");\natomic_float!(AtomicF32, f32, \"s\", \"b\");\natomic_float!(AtomicF64, f64, \"d\", \"f\");\n\n#[cfg(portable_atomic_unstable_f128)]\nimpl AtomicF128 {\n    #[inline]\n    pub(crate) fn fetch_add(&self, val: f128, order: Ordering) -> f128 {\n        self.fetch_update_(order, |x| x + val)\n    }\n    #[inline]\n    pub(crate) fn fetch_sub(&self, val: f128, order: Ordering) -> f128 {\n        self.fetch_update_(order, |x| x - val)\n    }\n    #[inline]\n    pub(super) fn fetch_update_<F>(&self, order: Ordering, mut f: F) -> f128\n    where\n        F: FnMut(f128) -> f128,\n    {\n        // This is a private function and all instances of `f` only operate on the value\n        // loaded, so there is no need to synchronize the first load/failed CAS.\n        let mut prev = self.load(Ordering::Relaxed);\n        loop {\n            let next = f(prev);\n            match self.compare_exchange_weak(prev, next, order, Ordering::Relaxed) {\n                Ok(x) => return x,\n                Err(next_prev) => prev = next_prev,\n            }\n        }\n    }\n    #[inline]\n    pub(crate) fn fetch_max(&self, val: f128, order: Ordering) -> f128 {\n        self.fetch_update_(order, |x| x.max(val))\n    }\n    #[inline]\n    pub(crate) fn fetch_min(&self, val: f128, order: Ordering) -> f128 {\n        self.fetch_update_(order, |x| x.min(val))\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/float/int.rs",
      "sha256": "8801b336650a039bc6e056857c0f65c2f148a0774c83baa9bd9bf415618107e5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nAtomic float implementation based on atomic integer.\n\nThis module provides atomic float implementations using atomic integer.\n\nNote that most of `fetch_*` operations of atomic floats are implemented using\nCAS loops, which can be slower than equivalent operations of atomic integers.\n\nAArch64 with FEAT_LSFE and GPU targets have atomic instructions for float.\nSee aarch64.rs for AArch64 with FEAT_LSFE.\nGPU targets will also use architecture-specific implementations instead of this implementation in the\nfuture: https://github.com/taiki-e/portable-atomic/issues/34 / https://github.com/taiki-e/portable-atomic/pull/45\n*/\n\n// TODO: fetch_{minimum,maximum}* https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3008r2.html / https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0493r5.pdf\n\n#![cfg_attr(\n    all(target_pointer_width = \"16\", not(feature = \"fallback\")),\n    allow(unused_imports, unused_macros)\n)]\n\nuse core::{cell::UnsafeCell, sync::atomic::Ordering};\n\nmacro_rules! atomic_float {\n    (\n        $atomic_type:ident, $float_type:ident, $atomic_int_type:ident, $int_type:ident,\n        $align:literal\n    ) => {\n        #[repr(C, align($align))]\n        pub(crate) struct $atomic_type {\n            v: UnsafeCell<$float_type>,\n        }\n\n        // Send is implicitly implemented.\n        // SAFETY: any data races are prevented by atomic operations.\n        unsafe impl Sync for $atomic_type {}\n\n        impl $atomic_type {\n            #[inline]\n            pub(crate) const fn new(v: $float_type) -> Self {\n                Self { v: UnsafeCell::new(v) }\n            }\n\n            #[inline]\n            pub(crate) fn is_lock_free() -> bool {\n                crate::$atomic_int_type::is_lock_free()\n            }\n            pub(crate) const IS_ALWAYS_LOCK_FREE: bool =\n                crate::$atomic_int_type::is_always_lock_free();\n\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub(crate) fn load(&self, order: Ordering) -> $float_type {\n                $float_type::from_bits(self.as_bits().load(order))\n            }\n\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub(crate) fn store(&self, val: $float_type, order: Ordering) {\n                self.as_bits().store(val.to_bits(), order)\n            }\n\n            const_fn! {\n                const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))];\n                #[inline(always)]\n                pub(crate) const fn as_bits(&self) -> &crate::$atomic_int_type {\n                    // SAFETY: $atomic_type and $atomic_int_type have the same layout,\n                    // and there is no concurrent access to the value that does not go through this method.\n                    unsafe { &*(self as *const Self as *const crate::$atomic_int_type) }\n                }\n            }\n\n            #[inline]\n            pub(crate) const fn as_ptr(&self) -> *mut $float_type {\n                self.v.get()\n            }\n        }\n\n        cfg_has_atomic_cas_or_amo32! {\n        impl $atomic_type {\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn swap(&self, val: $float_type, order: Ordering) -> $float_type {\n                $float_type::from_bits(self.as_bits().swap(val.to_bits(), order))\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_neg(&self, order: Ordering) -> $float_type {\n                const NEG_MASK: $int_type = !0 / 2 + 1;\n                $float_type::from_bits(self.as_bits().fetch_xor(NEG_MASK, order))\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_abs(&self, order: Ordering) -> $float_type {\n                const ABS_MASK: $int_type = !0 / 2;\n                $float_type::from_bits(self.as_bits().fetch_and(ABS_MASK, order))\n            }\n        }\n        cfg_has_atomic_cas! {\n        impl $atomic_type {\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub(crate) fn compare_exchange(\n                &self,\n                current: $float_type,\n                new: $float_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$float_type, $float_type> {\n                match self.as_bits().compare_exchange(\n                    current.to_bits(),\n                    new.to_bits(),\n                    success,\n                    failure,\n                ) {\n                    Ok(v) => Ok($float_type::from_bits(v)),\n                    Err(v) => Err($float_type::from_bits(v)),\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub(crate) fn compare_exchange_weak(\n                &self,\n                current: $float_type,\n                new: $float_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$float_type, $float_type> {\n                match self.as_bits().compare_exchange_weak(\n                    current.to_bits(),\n                    new.to_bits(),\n                    success,\n                    failure,\n                ) {\n                    Ok(v) => Ok($float_type::from_bits(v)),\n                    Err(v) => Err($float_type::from_bits(v)),\n                }\n            }\n        }\n        #[cfg(not(all(\n            any(target_arch = \"aarch64\", target_arch = \"arm64ec\"),\n            any(target_feature = \"lsfe\", portable_atomic_target_feature = \"lsfe\"),\n            target_feature = \"neon\", // for vreg\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n        )))]\n        impl $atomic_type {\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_add(&self, val: $float_type, order: Ordering) -> $float_type {\n                self.fetch_update_(order, |x| x + val)\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_sub(&self, val: $float_type, order: Ordering) -> $float_type {\n                self.fetch_update_(order, |x| x - val)\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            fn fetch_update_<F>(&self, order: Ordering, mut f: F) -> $float_type\n            where\n                F: FnMut($float_type) -> $float_type,\n            {\n                // This is a private function and all instances of `f` only operate on the value\n                // loaded, so there is no need to synchronize the first load/failed CAS.\n                let mut prev = self.load(Ordering::Relaxed);\n                loop {\n                    let next = f(prev);\n                    match self.compare_exchange_weak(prev, next, order, Ordering::Relaxed) {\n                        Ok(x) => return x,\n                        Err(next_prev) => prev = next_prev,\n                    }\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_max(&self, val: $float_type, order: Ordering) -> $float_type {\n                self.fetch_update_(order, |x| x.max(val))\n            }\n\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn fetch_min(&self, val: $float_type, order: Ordering) -> $float_type {\n                self.fetch_update_(order, |x| x.min(val))\n            }\n        }\n        } // cfg_has_atomic_cas!\n        } // cfg_has_atomic_cas_or_amo32!\n    };\n}\n\n#[cfg(portable_atomic_unstable_f16)]\ncfg_has_atomic_16! {\n    atomic_float!(AtomicF16, f16, AtomicU16, u16, 2);\n}\ncfg_has_atomic_32! {\n    atomic_float!(AtomicF32, f32, AtomicU32, u32, 4);\n}\ncfg_has_atomic_64! {\n    atomic_float!(AtomicF64, f64, AtomicU64, u64, 8);\n}\n#[cfg(portable_atomic_unstable_f128)]\ncfg_has_atomic_128! {\n    atomic_float!(AtomicF128, f128, AtomicU128, u128, 16);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/float/mod.rs",
      "sha256": "2c722182baee05df65f9f6e2b4de5d5474a3b2bf0c24803a65a771de78b76f95",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nAtomic float implementations\n*/\n\n#![allow(clippy::float_arithmetic)]\n\nmod int;\n\n#[cfg(all(\n    any(target_arch = \"aarch64\", target_arch = \"arm64ec\"),\n    any(target_feature = \"lsfe\", portable_atomic_target_feature = \"lsfe\"),\n    target_feature = \"neon\", // for vreg\n    not(any(miri, portable_atomic_sanitize_thread)),\n    any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n))]\nmod aarch64;\n\n#[cfg(portable_atomic_unstable_f16)]\ncfg_has_atomic_16! {\n    pub(crate) use self::int::AtomicF16;\n}\ncfg_has_atomic_32! {\n    pub(crate) use self::int::AtomicF32;\n}\ncfg_has_atomic_64! {\n    pub(crate) use self::int::AtomicF64;\n}\n#[cfg(portable_atomic_unstable_f128)]\ncfg_has_atomic_128! {\n    pub(crate) use self::int::AtomicF128;\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/interrupt/armv4t.rs",
      "sha256": "6fb9e7d01f7fb483bc6bec07916fdcba8563b605b53bd87c5310662da04e55a4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nArm A-Profile Architectures, Arm R-Profile Architectures, Legacy Arm Architectures\n\nRefs: https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/Program-Status-Registers--PSRs-\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\n\n// - 0x80 - I (IRQ mask) bit (1 << 7)\n// - 0x40 - F (FIQ mask) bit (1 << 6)\n// We disable only IRQs by default. See also https://github.com/taiki-e/portable-atomic/pull/28#issuecomment-1214146912.\n#[cfg(not(portable_atomic_disable_fiq))]\nmacro_rules! mask {\n    () => {\n        \"0x80\"\n    };\n}\n#[cfg(portable_atomic_disable_fiq)]\nmacro_rules! mask {\n    () => {\n        \"0xC0\" // 0x80 | 0x40\n    };\n}\n\npub(crate) type State = u32;\n\n/// Disables interrupts and returns the previous interrupt state.\n#[inline]\n#[cfg_attr(\n    not(any(target_feature = \"v7\", portable_atomic_target_feature = \"v7\")),\n    instruction_set(arm::a32)\n)]\npub(crate) fn disable() -> State {\n    let cpsr: State;\n    // SAFETY: reading CPSR and disabling interrupts are safe.\n    // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions)\n    unsafe {\n        asm!(\n            \"mrs {prev}, cpsr\",                      // prev = CPSR\n            concat!(\"orr {new}, {prev}, \", mask!()), // new = prev | mask\n            \"msr cpsr_c, {new}\",                     // CPSR.{I,F,T,M} = new.{I,F,T,M}\n            prev = out(reg) cpsr,\n            new = out(reg) _,\n            // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled.\n            options(nostack, preserves_flags),\n        );\n    }\n    cpsr\n}\n\n/// Restores the previous interrupt state.\n///\n/// # Safety\n///\n/// The state must be the one retrieved by the previous `disable`.\n#[inline]\n#[cfg_attr(\n    not(any(target_feature = \"v7\", portable_atomic_target_feature = \"v7\")),\n    instruction_set(arm::a32)\n)]\npub(crate) unsafe fn restore(prev_cpsr: State) {\n    // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`,\n    //\n    // This clobbers the control field mask byte of CPSR. See msp430.rs for safety on this.\n    // (preserves_flags is fine because we can clobber only the I, F, T, and M bits of CPSR.)\n    //\n    // Refs: https://developer.arm.com/documentation/dui0473/m/arm-and-thumb-instructions/msr--general-purpose-register-to-psr-\n    unsafe {\n        asm!(\n            \"msr cpsr_c, {prev_cpsr}\", // CPSR.{I,F,T,M} = prev_cpsr.{I,F,T,M}\n            prev_cpsr = in(reg) prev_cpsr,\n            // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled.\n            options(nostack, preserves_flags),\n        );\n    }\n}\n\n// On pre-v6 Arm, we cannot use core::sync::atomic here because they call the\n// `__sync_*` builtins for non-relaxed load/store (because pre-v6 Arm doesn't\n// have Data Memory Barrier).\n#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(any(test, portable_atomic_no_atomic_cas)))]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(test, not(target_has_atomic = \"ptr\")))\n)]\npub(super) mod atomic {\n    #[cfg(not(portable_atomic_no_asm))]\n    use core::arch::asm;\n    use core::{cell::UnsafeCell, sync::atomic::Ordering};\n\n    macro_rules! atomic {\n        ($([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $suffix:tt) => {\n            #[repr(transparent)]\n            pub(crate) struct $atomic_type $(<$($generics)*>)? {\n                v: UnsafeCell<$value_type>,\n            }\n\n            // Send is implicitly implemented for atomic integers, but not for atomic pointers.\n            // SAFETY: any data races are prevented by atomic operations.\n            unsafe impl $(<$($generics)*>)? Send for $atomic_type $(<$($generics)*>)? {}\n            // SAFETY: any data races are prevented by atomic operations.\n            unsafe impl $(<$($generics)*>)? Sync for $atomic_type $(<$($generics)*>)? {}\n\n            impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n                #[inline]\n                pub(crate) fn load(&self, _order: Ordering) -> $value_type {\n                    let src = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe {\n                        let out;\n                        // inline asm without nomem/readonly implies compiler fence.\n                        // And compiler fence is fine because the user explicitly declares that\n                        // the system is single-core by using an unsafe cfg.\n                        asm!(\n                            concat!(\"ldr\", $suffix, \" {out}, [{src}]\"), // atomic { out = *src }\n                            src = in(reg) src,\n                            out = lateout(reg) out,\n                            options(nostack, preserves_flags),\n                        );\n                        out\n                    }\n                }\n\n                #[inline]\n                pub(crate) fn store(&self, val: $value_type, _order: Ordering) {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe {\n                        // inline asm without nomem/readonly implies compiler fence.\n                        // And compiler fence is fine because the user explicitly declares that\n                        // the system is single-core by using an unsafe cfg.\n                        asm!(\n                            concat!(\"str\", $suffix, \" {val}, [{dst}]\"), // atomic { *dst = val }\n                            dst = in(reg) dst,\n                            val = in(reg) val,\n                            options(nostack, preserves_flags),\n                        );\n                    }\n                }\n            }\n        };\n    }\n\n    atomic!(AtomicI8, i8, \"b\");\n    atomic!(AtomicU8, u8, \"b\");\n    atomic!(AtomicI16, i16, \"h\");\n    atomic!(AtomicU16, u16, \"h\");\n    atomic!(AtomicI32, i32, \"\");\n    atomic!(AtomicU32, u32, \"\");\n    atomic!(AtomicIsize, isize, \"\");\n    atomic!(AtomicUsize, usize, \"\");\n    atomic!([T] AtomicPtr, *mut T, \"\");\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/interrupt/armv6m.rs",
      "sha256": "364a38f18ffb2b3cd836700dff6a390d9542f0f2a3eda07bc63bc8868dafaad1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nArm M-Profile Architectures\n\nAdapted from https://github.com/rust-embedded/cortex-m.\n\nRefs: https://developer.arm.com/documentation/ddi0419/c/System-Level-Architecture/System-Level-Programmers--Model/Registers/The-special-purpose-mask-register--PRIMASK\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(any(test, portable_atomic_no_atomic_cas))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(test, not(target_has_atomic = \"ptr\")))\n)]\npub(super) use core::sync::atomic;\n\npub(crate) type State = u32;\n\n/// Disables interrupts and returns the previous interrupt state.\n#[inline(always)]\npub(crate) fn disable() -> State {\n    let primask: State;\n    // SAFETY: reading the priority mask register and disabling interrupts are safe.\n    // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions)\n    unsafe {\n        asm!(\n            \"mrs {primask}, PRIMASK\", // primask = PRIMASK\n            \"cpsid i\",                // PRIMASK.PM = 1\n            primask = out(reg) primask,\n            // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled.\n            options(nostack, preserves_flags),\n        );\n    }\n    primask\n}\n\n/// Restores the previous interrupt state.\n///\n/// # Safety\n///\n/// The state must be the one retrieved by the previous `disable`.\n#[inline(always)]\npub(crate) unsafe fn restore(prev_primask: State) {\n    // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`,\n    // and we've checked that interrupts were enabled before disabling interrupts.\n    //\n    // This clobbers the entire PRIMASK register. See msp430.rs for safety on this.\n    unsafe {\n        asm!(\n            \"msr PRIMASK, {prev_primask}\", // PRIMASK = prev_primask\n            prev_primask = in(reg) prev_primask,\n            // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled.\n            options(nostack, preserves_flags),\n        );\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/interrupt/avr.rs",
      "sha256": "252569da4b194f91d7f52c6480a869e26679dc74c30a3a8fcd6568a39b90440d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nAdapted from https://github.com/Rahix/avr-device.\n\nSee also src/imp/avr.rs.\n\nRefs:\n- AVR® Instruction Set Manual, Rev. DS40002198B\n  https://ww1.microchip.com/downloads/en/DeviceDoc/AVR-InstructionSet-Manual-DS40002198.pdf\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\n\n#[cfg(not(portable_atomic_no_asm))]\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(any(test, portable_atomic_no_atomic_cas))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(test, not(target_has_atomic = \"ptr\")))\n)]\npub(super) use super::super::avr as atomic;\n\npub(crate) type State = u8;\n\n/// Disables interrupts and returns the previous interrupt state.\n#[inline(always)]\npub(crate) fn disable() -> State {\n    let sreg: State;\n    // SAFETY: reading the status register (SREG) and disabling interrupts are safe.\n    // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions)\n    unsafe {\n        // Refs: https://ww1.microchip.com/downloads/en/DeviceDoc/AVR-InstructionSet-Manual-DS40002198.pdf#page=58\n        #[cfg(not(portable_atomic_no_asm))]\n        asm!(\n            \"in {sreg}, 0x3F\", // sreg = SREG\n            \"cli\",             // SREG.I = 0\n            sreg = out(reg) sreg,\n            // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled.\n            // Do not use `preserves_flags` because CLI modifies the I bit of the status register (SREG).\n            options(nostack),\n        );\n        #[cfg(portable_atomic_no_asm)]\n        {\n            llvm_asm!(\"in $0, 0x3F\" : \"=r\"(sreg) ::: \"volatile\");\n            llvm_asm!(\"cli\" ::: \"memory\" : \"volatile\");\n        }\n    }\n    sreg\n}\n\n/// Restores the previous interrupt state.\n///\n/// # Safety\n///\n/// The state must be the one retrieved by the previous `disable`.\n#[inline(always)]\npub(crate) unsafe fn restore(prev_sreg: State) {\n    // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`.\n    //\n    // This clobbers the entire status register, but all other flags are the arithmetic flags that\n    // are changed as a side effect of arithmetic operations, etc., which LLVM recognizes unless\n    // preserves_flags is set, so it is safe to clobber them here.\n    // See also the discussion at https://github.com/taiki-e/portable-atomic/pull/40.\n    unsafe {\n        #[cfg(not(portable_atomic_no_asm))]\n        asm!(\n            \"out 0x3F, {prev_sreg}\", // SREG = prev_sreg\n            prev_sreg = in(reg) prev_sreg,\n            // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled.\n            // Do not use `preserves_flags` because OUT modifies the status register (SREG).\n            options(nostack),\n        );\n        #[cfg(portable_atomic_no_asm)]\n        llvm_asm!(\"out 0x3F, $0\" :: \"r\"(prev_sreg) : \"memory\" : \"volatile\");\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/interrupt/mod.rs",
      "sha256": "256ed2675f921dc2c2fb0ea06b610990e391ec2714dc460383e21d688a0f751f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nFallback implementation based on disabling interrupts or critical-section\n\n- mod.rs contains critical section based fallback implementations.\n- Each architecture modules contain implementations of disabling interrupts.\n\nSee README.md of this directory for details.\n*/\n\n#[cfg(not(feature = \"critical-section\"))]\n#[cfg_attr(\n    all(\n        target_arch = \"arm\",\n        any(target_feature = \"mclass\", portable_atomic_target_feature = \"mclass\"),\n    ),\n    path = \"armv6m.rs\"\n)]\n#[cfg_attr(\n    all(\n        target_arch = \"arm\",\n        not(any(target_feature = \"mclass\", portable_atomic_target_feature = \"mclass\")),\n    ),\n    path = \"armv4t.rs\"\n)]\n#[cfg_attr(target_arch = \"avr\", path = \"avr.rs\")]\n#[cfg_attr(target_arch = \"msp430\", path = \"msp430.rs\")]\n#[cfg_attr(any(target_arch = \"riscv32\", target_arch = \"riscv64\"), path = \"riscv.rs\")]\n#[cfg_attr(target_arch = \"xtensa\", path = \"xtensa.rs\")]\npub(super) mod arch;\n\n#[cfg(not(all(\n    portable_atomic_unsafe_assume_privileged,\n    not(portable_atomic_unsafe_assume_single_core),\n)))]\nitems!({\n    use core::{cell::UnsafeCell, sync::atomic::Ordering};\n\n    // critical-section implementations might use locks internally.\n    #[cfg(feature = \"critical-section\")]\n    const IS_ALWAYS_LOCK_FREE: bool = false;\n    // Consider atomic operations based on disabling interrupts on single-core\n    // systems are lock-free. (We consider the pre-v6 Arm Linux's atomic operations\n    // provided in a similar way by the Linux kernel to be lock-free.)\n    #[cfg(not(feature = \"critical-section\"))]\n    const IS_ALWAYS_LOCK_FREE: bool = true;\n\n    // Put this in its own module to prevent guard creation.\n    use self::guard::disable;\n    mod guard {\n        // Note: The caller must NOT explicitly modify registers containing fields modified by disable/restore.\n        //       (Fields modified as side effects of other operations are covered by the absence of preserves_flags,\n        //        so they are fine -- see msp430.rs for more.)\n        #[inline(always)]\n        pub(super) fn disable() -> Guard {\n            Guard {\n                #[cfg(feature = \"critical-section\")]\n                // SAFETY: the state will be restored in the subsequent `release`.\n                state: unsafe { critical_section::acquire() },\n                #[cfg(not(feature = \"critical-section\"))]\n                // Get current interrupt state and disable interrupts.\n                state: super::arch::disable(),\n            }\n        }\n        pub(super) struct Guard {\n            #[cfg(feature = \"critical-section\")]\n            state: critical_section::RestoreState,\n            #[cfg(not(feature = \"critical-section\"))]\n            state: super::arch::State,\n        }\n        impl Drop for Guard {\n            #[inline(always)]\n            fn drop(&mut self) {\n                #[cfg(feature = \"critical-section\")]\n                // SAFETY: the state was retrieved by the previous `acquire`.\n                unsafe {\n                    critical_section::release(self.state);\n                }\n                #[cfg(not(feature = \"critical-section\"))]\n                // Restore interrupt state.\n                // SAFETY: the state was retrieved by the previous `disable`.\n                unsafe {\n                    super::arch::restore(self.state);\n                }\n            }\n        }\n    }\n\n    macro_rules! atomic_base {\n        (base, $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $align:literal) => {\n            #[repr(C, align($align))]\n            pub(crate) struct $atomic_type $(<$($generics)*>)? {\n                v: UnsafeCell<$value_type>,\n            }\n\n            // Send is implicitly implemented for atomic integers, but not for atomic pointers.\n            // SAFETY: any data races are prevented by disabling interrupts (or\n            // atomic intrinsics) or critical-section (see module-level comments).\n            unsafe impl $(<$($generics)*>)? Send for $atomic_type $(<$($generics)*>)? {}\n            // SAFETY: any data races are prevented by disabling interrupts (or\n            // atomic intrinsics) or critical-section (see module-level comments).\n            unsafe impl $(<$($generics)*>)? Sync for $atomic_type $(<$($generics)*>)? {}\n\n            impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n                #[inline]\n                pub(crate) const fn new(v: $value_type) -> Self {\n                    Self { v: UnsafeCell::new(v) }\n                }\n\n                #[inline]\n                pub(crate) fn is_lock_free() -> bool {\n                    Self::IS_ALWAYS_LOCK_FREE\n                }\n                pub(crate) const IS_ALWAYS_LOCK_FREE: bool = IS_ALWAYS_LOCK_FREE;\n\n                #[inline]\n                fn read(&self, _guard: &guard::Guard) -> $value_type {\n                    // SAFETY: any data races are prevented by disabling interrupts or critical-section (see\n                    // module-level comments) and the raw pointer is valid because we got it\n                    // from a reference.\n                    unsafe { self.v.get().read() }\n                }\n                #[inline]\n                fn write(&self, val: $value_type, _guard: &guard::Guard) {\n                    // SAFETY: any data races are prevented by disabling interrupts or critical-section (see\n                    // module-level comments) and the raw pointer is valid because we got it\n                    // from a reference.\n                    unsafe { self.v.get().write(val) }\n                }\n\n                // As for CAS, there is no corresponding atomic operation on all architectures that use this code.\n                // (If the CAS instruction exists, all atomic operations can be implemented by it, so this code will not be used.)\n                #[inline]\n                #[cfg_attr(\n                    all(debug_assertions, not(portable_atomic_no_track_caller)),\n                    track_caller\n                )]\n                pub(crate) fn compare_exchange(\n                    &self,\n                    current: $value_type,\n                    new: $value_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$value_type, $value_type> {\n                    crate::utils::assert_compare_exchange_ordering(success, failure);\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    if prev == current {\n                        self.write(new, &guard);\n                        Ok(prev)\n                    } else {\n                        Err(prev)\n                    }\n                }\n                #[inline]\n                #[cfg_attr(\n                    all(debug_assertions, not(portable_atomic_no_track_caller)),\n                    track_caller\n                )]\n                pub(crate) fn compare_exchange_weak(\n                    &self,\n                    current: $value_type,\n                    new: $value_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$value_type, $value_type> {\n                    self.compare_exchange(current, new, success, failure)\n                }\n\n                #[inline]\n                pub(crate) const fn as_ptr(&self) -> *mut $value_type {\n                    self.v.get()\n                }\n            }\n        };\n        (native_load_store, $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty) => {\n            impl $(<$($generics)*>)? core::ops::Deref for $atomic_type $(<$($generics)*>)? {\n                type Target = atomic::$atomic_type $(<$($generics)*>)?;\n                #[inline(always)]\n                fn deref(&self) -> &Self::Target {\n                    // SAFETY: $atomic_type and atomic::$atomic_type have the same layout and\n                    // guarantee atomicity in a compatible way. (see module-level comments)\n                    unsafe {\n                        &*(self as *const Self as *const atomic::$atomic_type $(<$($generics)*>)?)\n                    }\n                }\n            }\n        };\n        (emulate_load_store, $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty) => {\n            impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n                #[inline]\n                #[cfg_attr(\n                    all(debug_assertions, not(portable_atomic_no_track_caller)),\n                    track_caller\n                )]\n                pub(crate) fn load(&self, order: Ordering) -> $value_type {\n                    crate::utils::assert_load_ordering(order);\n                    let guard = disable();\n                    self.read(&guard)\n                }\n                #[inline]\n                #[cfg_attr(\n                    all(debug_assertions, not(portable_atomic_no_track_caller)),\n                    track_caller\n                )]\n                pub(crate) fn store(&self, val: $value_type, order: Ordering) {\n                    crate::utils::assert_store_ordering(order);\n                    let guard = disable();\n                    self.write(val, &guard);\n                }\n            }\n        };\n        (emulate_swap, $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty) => {\n            impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n                #[inline]\n                pub(crate) fn swap(&self, val: $value_type, _order: Ordering) -> $value_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(val, &guard);\n                    prev\n                }\n            }\n        };\n    }\n\n    #[cfg_attr(\n        portable_atomic_no_cfg_target_has_atomic,\n        cfg(any(\n            test,\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            portable_atomic_no_atomic_cas\n        ))\n    )]\n    #[cfg_attr(\n        not(portable_atomic_no_cfg_target_has_atomic),\n        cfg(any(\n            test,\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            not(target_has_atomic = \"ptr\")\n        ))\n    )]\n    items!({\n        #[cfg(target_pointer_width = \"16\")]\n        atomic_base!(base, [T] AtomicPtr, *mut T, 2);\n        #[cfg(target_pointer_width = \"32\")]\n        atomic_base!(base, [T] AtomicPtr, *mut T, 4);\n        #[cfg(target_pointer_width = \"64\")]\n        atomic_base!(base, [T] AtomicPtr, *mut T, 8);\n        #[cfg(target_pointer_width = \"128\")]\n        atomic_base!(base, [T] AtomicPtr, *mut T, 16);\n\n        impl_default_bit_opts!(AtomicPtr, usize);\n\n        cfg_sel!({\n            #[cfg(any(target_arch = \"avr\", feature = \"critical-section\"))]\n            {\n                atomic_base!(emulate_load_store, [T] AtomicPtr, *mut T);\n            }\n            #[cfg(else)]\n            {\n                atomic_base!(native_load_store, [T] AtomicPtr, *mut T);\n            }\n        });\n\n        #[cfg(not(all(\n            any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n            not(feature = \"critical-section\"),\n            any(\n                portable_atomic_force_amo,\n                target_feature = \"zaamo\",\n                portable_atomic_target_feature = \"zaamo\",\n            ),\n        )))]\n        items!({\n            atomic_base!(emulate_swap, [T] AtomicPtr, *mut T);\n            impl<T> AtomicPtr<T> {\n                #[inline]\n                pub(crate) fn fetch_byte_add(&self, val: usize, _order: Ordering) -> *mut T {\n                    #[cfg(portable_atomic_no_strict_provenance)]\n                    use crate::utils::ptr::PtrExt as _;\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev.with_addr(prev.addr().wrapping_add(val)), &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_byte_sub(&self, val: usize, _order: Ordering) -> *mut T {\n                    #[cfg(portable_atomic_no_strict_provenance)]\n                    use crate::utils::ptr::PtrExt as _;\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev.with_addr(prev.addr().wrapping_sub(val)), &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_and(&self, val: usize, _order: Ordering) -> *mut T {\n                    #[cfg(portable_atomic_no_strict_provenance)]\n                    use crate::utils::ptr::PtrExt as _;\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev.with_addr(prev.addr() & val), &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_or(&self, val: usize, _order: Ordering) -> *mut T {\n                    #[cfg(portable_atomic_no_strict_provenance)]\n                    use crate::utils::ptr::PtrExt as _;\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev.with_addr(prev.addr() | val), &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_xor(&self, val: usize, _order: Ordering) -> *mut T {\n                    #[cfg(portable_atomic_no_strict_provenance)]\n                    use crate::utils::ptr::PtrExt as _;\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev.with_addr(prev.addr() ^ val), &guard);\n                    prev\n                }\n            }\n        });\n\n        impl<T> AtomicPtr<T> {\n            #[cfg(test)]\n            #[inline]\n            fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T {\n                self.fetch_byte_add(val.wrapping_mul(core::mem::size_of::<T>()), order)\n            }\n            #[cfg(test)]\n            #[inline]\n            fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {\n                self.fetch_byte_sub(val.wrapping_mul(core::mem::size_of::<T>()), order)\n            }\n        }\n    });\n\n    macro_rules! atomic_int {\n        (base, $atomic_type:ident, $int_type:ty, $align:literal) => {\n            atomic_base!(base, $atomic_type, $int_type, $align);\n            // As for nand and neg, there is no corresponding atomic operation on all architectures that use this code.\n            impl $atomic_type {\n                #[inline]\n                pub(crate) fn fetch_nand(&self, val: $int_type, _order: Ordering) -> $int_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(!(prev & val), &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_neg(&self, _order: Ordering) -> $int_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev.wrapping_neg(), &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn neg(&self, order: Ordering) {\n                    self.fetch_neg(order);\n                }\n            }\n        };\n        (load_store_atomic $([$kind:ident])?, $atomic_type:ident, $int_type:ty, $align:literal) => {\n            cfg_sel!({\n                #[cfg(feature = \"critical-section\")]\n                {\n                    atomic_int!(all_critical_session, $atomic_type, $int_type, $align);\n                }\n                #[cfg(else)]\n                {\n                    atomic_int!(base, $atomic_type, $int_type, $align);\n                    impl_default_bit_opts!($atomic_type, $int_type);\n                    // load/store\n                    cfg_sel!({\n                        // AVR with very old rustc\n                        #[cfg(all(target_arch = \"avr\", portable_atomic_no_asm))]\n                        {\n                            atomic_base!(emulate_load_store, $atomic_type, $int_type);\n                        }\n                        #[cfg(else)]\n                        {\n                            atomic_base!(native_load_store, $atomic_type, $int_type);\n                        }\n                    });\n                    // RMW\n                    cfg_sel!({\n                        // AVR 8-bit RMW with RMW instructions\n                        #[cfg(all(\n                            target_arch = \"avr\",\n                            not(portable_atomic_no_asm),\n                            any(target_feature = \"rmw\", portable_atomic_target_feature = \"rmw\"),\n                        ))]\n                        {\n                            atomic_int!(emulate_arithmetic, $atomic_type, $int_type);\n                        }\n                        // RISC-V RMW with Zaamo extension\n                        #[cfg(all(\n                            any(target_arch = \"riscv32\", target_arch = \"riscv64\"),\n                            any(\n                                portable_atomic_force_amo,\n                                target_feature = \"zaamo\",\n                                portable_atomic_target_feature = \"zaamo\",\n                            ),\n                        ))]\n                        {\n                            atomic_int!(cas $([$kind])?, $atomic_type, $int_type);\n                        }\n                        #[cfg(else)]\n                        {\n                            atomic_int!(cas[emulate], $atomic_type, $int_type);\n                        }\n                    });\n                    // RMW (no-fetch)\n                    #[cfg(not(target_arch = \"msp430\"))]\n                    items!({\n                        impl_default_no_fetch_ops!($atomic_type, $int_type);\n                        impl $atomic_type {\n                            #[inline]\n                            pub(crate) fn not(&self, order: Ordering) {\n                                self.fetch_not(order);\n                            }\n                        }\n                    });\n                }\n            });\n        };\n        (all_critical_session, $atomic_type:ident, $int_type:ty, $align:literal) => {\n            atomic_int!(base, $atomic_type, $int_type, $align);\n            atomic_base!(emulate_load_store, $atomic_type, $int_type);\n            atomic_int!(cas[emulate], $atomic_type, $int_type);\n            impl_default_no_fetch_ops!($atomic_type, $int_type);\n            impl_default_bit_opts!($atomic_type, $int_type);\n            impl $atomic_type {\n                #[inline]\n                pub(crate) fn not(&self, order: Ordering) {\n                    self.fetch_not(order);\n                }\n            }\n        };\n        (emulate_arithmetic, $atomic_type:ident, $int_type:ty) => {\n            impl $atomic_type {\n                #[inline]\n                pub(crate) fn fetch_add(&self, val: $int_type, _order: Ordering) -> $int_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev.wrapping_add(val), &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_sub(&self, val: $int_type, _order: Ordering) -> $int_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev.wrapping_sub(val), &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_max(&self, val: $int_type, _order: Ordering) -> $int_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(core::cmp::max(prev, val), &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_min(&self, val: $int_type, _order: Ordering) -> $int_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(core::cmp::min(prev, val), &guard);\n                    prev\n                }\n            }\n        };\n        (emulate_bit, $atomic_type:ident, $int_type:ty) => {\n            impl $atomic_type {\n                #[inline]\n                pub(crate) fn fetch_and(&self, val: $int_type, _order: Ordering) -> $int_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev & val, &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_or(&self, val: $int_type, _order: Ordering) -> $int_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev | val, &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_xor(&self, val: $int_type, _order: Ordering) -> $int_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(prev ^ val, &guard);\n                    prev\n                }\n                #[inline]\n                pub(crate) fn fetch_not(&self, _order: Ordering) -> $int_type {\n                    let guard = disable();\n                    let prev = self.read(&guard);\n                    self.write(!prev, &guard);\n                    prev\n                }\n            }\n        };\n        (cas[emulate], $atomic_type:ident, $int_type:ty) => {\n            atomic_base!(emulate_swap, $atomic_type, $int_type);\n            atomic_int!(emulate_arithmetic, $atomic_type, $int_type);\n            atomic_int!(emulate_bit, $atomic_type, $int_type);\n        };\n        // RISC-V 32-bit(RV32)/{32,64}-bit(RV64) RMW with Zaamo extension\n        // RISC-V 8-bit/16-bit RMW with Zabha extension\n        (cas, $atomic_type:ident, $int_type:ty) => {};\n        // RISC-V 8-bit/16-bit RMW with Zaamo extension\n        (cas[sub_word], $atomic_type:ident, $int_type:ty) => {\n            // RISC-V 8-bit/16-bit RMW with Zaamo+Zabha extension\n            #[cfg(any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\"))]\n            atomic_int!(cas, $atomic_type, $int_type);\n\n            // RISC-V 8-bit/16-bit RMW with Zaamo extension\n            #[cfg(not(any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\")))]\n            atomic_base!(emulate_swap, $atomic_type, $int_type);\n            #[cfg(not(any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\")))]\n            atomic_int!(emulate_arithmetic, $atomic_type, $int_type);\n        };\n    }\n\n    #[cfg_attr(\n        portable_atomic_no_cfg_target_has_atomic,\n        cfg(any(\n            test,\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            portable_atomic_no_atomic_cas,\n        ))\n    )]\n    #[cfg_attr(\n        not(portable_atomic_no_cfg_target_has_atomic),\n        cfg(any(\n            test,\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            not(target_has_atomic = \"ptr\"),\n        ))\n    )]\n    items!({\n        // On some platforms, atomic load/store can be implemented in a more efficient\n        // way than disabling interrupts. On MSP430, some RMWs that do not return the\n        // previous value can also be optimized.\n        //\n        // Note: On single-core systems, it is okay to use critical session-based\n        // CAS together with atomic load/store. The load/store will not be\n        // called while interrupts are disabled, and since the load/store is\n        // atomic, it is not affected by interrupts even if interrupts are enabled.\n        #[cfg(not(any(\n            all(target_arch = \"avr\", portable_atomic_no_asm),\n            feature = \"critical-section\",\n        )))]\n        use self::arch::atomic;\n\n        #[cfg(target_pointer_width = \"16\")]\n        #[cfg(not(target_arch = \"avr\"))]\n        atomic_int!(load_store_atomic, AtomicIsize, isize, 2);\n        #[cfg(target_pointer_width = \"16\")]\n        #[cfg(not(target_arch = \"avr\"))]\n        atomic_int!(load_store_atomic, AtomicUsize, usize, 2);\n        #[cfg(target_arch = \"avr\")]\n        atomic_int!(all_critical_session, AtomicIsize, isize, 2);\n        #[cfg(target_arch = \"avr\")]\n        atomic_int!(all_critical_session, AtomicUsize, usize, 2);\n        #[cfg(target_pointer_width = \"32\")]\n        atomic_int!(load_store_atomic, AtomicIsize, isize, 4);\n        #[cfg(target_pointer_width = \"32\")]\n        atomic_int!(load_store_atomic, AtomicUsize, usize, 4);\n        #[cfg(target_pointer_width = \"64\")]\n        atomic_int!(load_store_atomic, AtomicIsize, isize, 8);\n        #[cfg(target_pointer_width = \"64\")]\n        atomic_int!(load_store_atomic, AtomicUsize, usize, 8);\n        #[cfg(target_pointer_width = \"128\")]\n        atomic_int!(load_store_atomic, AtomicIsize, isize, 16);\n        #[cfg(target_pointer_width = \"128\")]\n        atomic_int!(load_store_atomic, AtomicUsize, usize, 16);\n\n        #[cfg(not(all(target_arch = \"avr\", portable_atomic_no_asm)))]\n        atomic_int!(load_store_atomic[sub_word], AtomicI8, i8, 1);\n        #[cfg(not(all(target_arch = \"avr\", portable_atomic_no_asm)))]\n        atomic_int!(load_store_atomic[sub_word], AtomicU8, u8, 1);\n        #[cfg(all(target_arch = \"avr\", portable_atomic_no_asm))]\n        atomic_int!(all_critical_session, AtomicI8, i8, 1);\n        #[cfg(all(target_arch = \"avr\", portable_atomic_no_asm))]\n        atomic_int!(all_critical_session, AtomicU8, u8, 1);\n        #[cfg(not(target_arch = \"avr\"))]\n        atomic_int!(load_store_atomic[sub_word], AtomicI16, i16, 2);\n        #[cfg(not(target_arch = \"avr\"))]\n        atomic_int!(load_store_atomic[sub_word], AtomicU16, u16, 2);\n        #[cfg(target_arch = \"avr\")]\n        atomic_int!(all_critical_session, AtomicI16, i16, 2);\n        #[cfg(target_arch = \"avr\")]\n        atomic_int!(all_critical_session, AtomicU16, u16, 2);\n\n        #[cfg(not(target_pointer_width = \"16\"))]\n        atomic_int!(load_store_atomic, AtomicI32, i32, 4);\n        #[cfg(not(target_pointer_width = \"16\"))]\n        atomic_int!(load_store_atomic, AtomicU32, u32, 4);\n\n        cfg_has_fast_atomic_64!({\n            atomic_int!(load_store_atomic, AtomicI64, i64, 8);\n            atomic_int!(load_store_atomic, AtomicU64, u64, 8);\n        });\n    });\n\n    // Double or more width atomics (require fallback feature for consistency with other situations).\n    #[cfg(target_pointer_width = \"16\")]\n    #[cfg(any(test, feature = \"fallback\"))]\n    items!({\n        atomic_int!(all_critical_session, AtomicI32, i32, 4);\n        atomic_int!(all_critical_session, AtomicU32, u32, 4);\n    });\n    #[cfg(any(\n        test,\n        all(\n            feature = \"fallback\",\n            not(all(\n                target_arch = \"riscv32\",\n                not(any(miri, portable_atomic_sanitize_thread)),\n                any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n                any(\n                    target_feature = \"zacas\",\n                    portable_atomic_target_feature = \"zacas\",\n                    all(\n                        feature = \"fallback\",\n                        not(portable_atomic_no_outline_atomics),\n                        any(target_os = \"linux\", target_os = \"android\"),\n                    ),\n                ),\n            )),\n        ),\n    ))]\n    #[cfg_attr(\n        portable_atomic_no_cfg_target_has_atomic,\n        cfg(any(test, portable_atomic_no_atomic_64))\n    )]\n    #[cfg_attr(\n        not(portable_atomic_no_cfg_target_has_atomic),\n        cfg(any(test, not(target_has_atomic = \"64\")))\n    )]\n    cfg_no_fast_atomic_64!({\n        atomic_int!(all_critical_session, AtomicI64, i64, 8);\n        atomic_int!(all_critical_session, AtomicU64, u64, 8);\n    });\n    #[cfg(any(\n        test,\n        all(\n            feature = \"fallback\",\n            not(all(\n                target_arch = \"riscv64\",\n                not(any(miri, portable_atomic_sanitize_thread)),\n                any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n                any(\n                    target_feature = \"zacas\",\n                    portable_atomic_target_feature = \"zacas\",\n                    all(\n                        feature = \"fallback\",\n                        not(portable_atomic_no_outline_atomics),\n                        any(target_os = \"linux\", target_os = \"android\"),\n                    ),\n                ),\n            )),\n        ),\n    ))]\n    items!({\n        atomic_int!(all_critical_session, AtomicI128, i128, 16);\n        atomic_int!(all_critical_session, AtomicU128, u128, 16);\n    });\n});\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    test_atomic_ptr_single_thread!();\n    test_atomic_int_single_thread!(i8);\n    test_atomic_int_single_thread!(u8);\n    test_atomic_int_single_thread!(i16);\n    test_atomic_int_single_thread!(u16);\n    test_atomic_int_single_thread!(i32);\n    test_atomic_int_single_thread!(u32);\n    test_atomic_int_single_thread!(i64);\n    test_atomic_int_single_thread!(u64);\n    test_atomic_int_single_thread!(i128);\n    test_atomic_int_single_thread!(u128);\n    test_atomic_int_single_thread!(isize);\n    test_atomic_int_single_thread!(usize);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/interrupt/msp430.rs",
      "sha256": "a7131a478fca956de4ca569f340641da2eb6a5cbd86a05a854f1231dd24e62d1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nAdapted from https://github.com/rust-embedded/msp430.\n\nSee also src/imp/msp430.rs.\n\nRefs:\n- MSP430x5xx and MSP430x6xx Family User's Guide, Rev. Q\n  https://www.ti.com/lit/ug/slau208q/slau208q.pdf\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\n\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(any(test, portable_atomic_no_atomic_cas))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(test, not(target_has_atomic = \"ptr\")))\n)]\npub(super) use super::super::msp430 as atomic;\n\npub(crate) type State = u16;\n\n/// Disables interrupts and returns the previous interrupt state.\n#[inline(always)]\npub(crate) fn disable() -> State {\n    let sr: State;\n    // SAFETY: reading the status register and disabling interrupts are safe.\n    // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions)\n    //\n    // See \"NOTE: Enable and Disable Interrupt\" of User's Guide for NOP: https://www.ti.com/lit/ug/slau208q/slau208q.pdf#page=60\n    unsafe {\n        #[cfg(not(portable_atomic_no_asm))]\n        asm!(\n            \"mov r2, {sr}\", // sr = SR\n            \"dint {{ nop\",  // SR.GIE = 0\n            sr = out(reg) sr,\n            // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled.\n            // Do not use `preserves_flags` because DINT modifies the GIE (global interrupt enable) bit of the status register.\n            options(nostack),\n        );\n        #[cfg(portable_atomic_no_asm)]\n        {\n            llvm_asm!(\"mov r2, $0\" : \"=r\"(sr) ::: \"volatile\");\n            llvm_asm!(\"dint { nop\" ::: \"memory\" : \"volatile\");\n        }\n    }\n    sr\n}\n\n/// Restores the previous interrupt state.\n///\n/// # Safety\n///\n/// The state must be the one retrieved by the previous `disable`.\n#[inline(always)]\npub(crate) unsafe fn restore(prev_sr: State) {\n    // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`,\n    //\n    // This clobbers the entire status register, but we never explicitly modify\n    // flags within a critical session, and the only flags that may be changed\n    // within a critical session are the arithmetic flags that are changed as\n    // a side effect of arithmetic operations, etc., which LLVM recognizes unless\n    // preserves_flags is set, so it is safe to clobber them here.\n    // See also the discussion at https://github.com/taiki-e/portable-atomic/pull/40.\n    //\n    // See \"NOTE: Enable and Disable Interrupt\" of User's Guide for NOP: https://www.ti.com/lit/ug/slau208q/slau208q.pdf#page=60\n    unsafe {\n        #[cfg(not(portable_atomic_no_asm))]\n        asm!(\n            \"nop {{ mov {prev_sr}, r2 {{ nop\", // SR = prev_sr\n            prev_sr = in(reg) prev_sr,\n            // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled.\n            // Do not use `preserves_flags` because MOV modifies the status register.\n            options(nostack),\n        );\n        #[cfg(portable_atomic_no_asm)]\n        llvm_asm!(\"nop { mov $0, r2 { nop\" :: \"r\"(prev_sr) : \"memory\" : \"volatile\");\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/interrupt/riscv.rs",
      "sha256": "32a0291b174310385f850c19283d583852b128cb9c037633c8a5e872245842bc",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRefs:\n- RISC-V Instruction Set Manual\n  Machine Status (mstatus and mstatush) Registers\n  https://docs.riscv.org/reference/isa/v20260120/priv/machine.html#3-1-1-6-machine-status-mstatus-and-mstatush-registers\n  Supervisor Status (sstatus) Register\n  https://docs.riscv.org/reference/isa/v20260120/priv/supervisor.html#sstatus\n\nSee also src/imp/riscv.rs.\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\n\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(any(test, portable_atomic_no_atomic_cas))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(test, not(target_has_atomic = \"ptr\")))\n)]\npub(super) use super::super::riscv as atomic;\n\ncfg_sel!({\n    // Supervisor-mode (S-mode)\n    #[cfg(portable_atomic_s_mode)]\n    {\n        // Status register\n        macro_rules! status {\n            () => {\n                \"sstatus\"\n            };\n        }\n        // SIE (Supervisor Interrupt Enable) bit (1 << 1)\n        #[cfg(portable_atomic_s_mode)]\n        macro_rules! mask {\n            () => {\n                \"0x2\"\n            };\n        }\n        const MASK: State = 0x2;\n    }\n    // Machine-mode (M-mode)\n    #[cfg(else)]\n    {\n        // Status register\n        macro_rules! status {\n            () => {\n                \"mstatus\"\n            };\n        }\n        // MIE (Machine Interrupt Enable) bit (1 << 3)\n        macro_rules! mask {\n            () => {\n                \"0x8\"\n            };\n        }\n        const MASK: State = 0x8;\n    }\n});\n\npub(crate) type State = crate::utils::RegSize;\n\n/// Disables interrupts and returns the previous interrupt state.\n#[inline(always)]\npub(crate) fn disable() -> State {\n    let status: State;\n    // SAFETY: reading mstatus/sstatus and disabling interrupts is safe.\n    // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions)\n    unsafe {\n        asm!(\n            concat!(\"csrrci {status}, \", status!(), \", \", mask!()), // atomic { status = status!(); status!() &= !mask!() }\n            status = out(reg) status,\n            // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled.\n            options(nostack, preserves_flags),\n        );\n    }\n    status\n}\n\n/// Restores the previous interrupt state.\n///\n/// # Safety\n///\n/// The state must be the one retrieved by the previous `disable`.\n#[inline(always)]\npub(crate) unsafe fn restore(prev_status: State) {\n    // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`,\n    //\n    // This avoids clobbering other fields in the mstatus/sstatus register.\n    unsafe {\n        asm!(\n            concat!(\"csrs \", status!(), \", {mask}\"), // atomic { status!() |= mask }\n            mask = in(reg) prev_status & MASK,\n            // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled.\n            options(nostack, preserves_flags),\n        );\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/interrupt/xtensa.rs",
      "sha256": "7c877f42c237d7ff6564776ee9c4afa5b8143d4fb6b39b4ac869e5e357189b4f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nRefs:\n- Xtensa Instruction Set Architecture (ISA) Summary for all Xtensa LX Processors\n  https://www.cadence.com/content/dam/cadence-www/global/en_US/documents/tools/silicon-solutions/compute-ip/isa-summary.pdf\n- Linux kernel's Xtensa atomic implementation\n  https://github.com/torvalds/linux/blob/v6.19/arch/xtensa/include/asm/atomic.h\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\nuse core::arch::asm;\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(any(test, portable_atomic_no_atomic_cas))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(test, not(target_has_atomic = \"ptr\")))\n)]\npub(super) use core::sync::atomic;\n\npub(crate) type State = u32;\n\n/// Disables interrupts and returns the previous interrupt state.\n#[inline(always)]\npub(crate) fn disable() -> State {\n    let ps: State;\n    // SAFETY: reading the PS special register and disabling all interrupts is safe.\n    // (see module-level comments of interrupt/mod.rs on the safety of using privileged instructions)\n    //\n    // Interrupt level 15 to disable all interrupts.\n    // SYNC after RSIL is not required.\n    // Use a14 per https://github.com/torvalds/linux/blob/v6.16/arch/xtensa/include/asm/atomic.h#L33-L37.\n    unsafe {\n        asm!(\n            \"rsil a14, 15\", // a14 = PS; PS.INTLEVEL = 15\n            out(\"a14\") ps,\n            // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled.\n            options(nostack),\n        );\n    }\n    ps\n}\n\n/// Restores the previous interrupt state.\n///\n/// # Safety\n///\n/// The state must be the one retrieved by the previous `disable`.\n#[inline(always)]\npub(crate) unsafe fn restore(prev_ps: State) {\n    // SAFETY: the caller must guarantee that the state was retrieved by the previous `disable`,\n    // and we've checked that interrupts were enabled before disabling interrupts.\n    //\n    // SYNC after WSR is required to guarantee that subsequent RSIL read the written value.\n    // See also 3.8.10 Processor Control Instructions of Xtensa Instruction Set Architecture (ISA) Summary for all Xtensa LX Processors.\n    unsafe {\n        asm!(\n            \"wsr.ps a14\", // PS = a14\n            \"rsync\",      // wait\n            in(\"a14\") prev_ps,\n            // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled.\n            options(nostack),\n        );\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/mod.rs",
      "sha256": "d9505be50a63ea4b00590a3637266ccb88dc85078572aa8fd8bf4236bb9ae18c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// -----------------------------------------------------------------------------\n// Lock-free implementations\n\ncfg_core_atomic!({\n    mod core_atomic;\n});\n\n// AVR\n#[cfg(target_arch = \"avr\")]\n#[cfg(not(portable_atomic_no_asm))]\n#[cfg(not(feature = \"critical-section\"))]\nmod avr;\n\n// pre-v6 Arm Linux\n#[cfg(all(\n    target_arch = \"arm\",\n    not(any(miri, portable_atomic_sanitize_thread)),\n    any(target_os = \"linux\", target_os = \"android\"),\n    not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n))]\npub(crate) mod arm_linux;\n\n// MSP430\n#[cfg(target_arch = \"msp430\")]\npub(crate) mod msp430;\n\n// RISC-V without A-extension\n#[cfg(any(test, not(feature = \"critical-section\")))]\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(any(\n        all(test, not(any(miri, portable_atomic_sanitize_thread))),\n        portable_atomic_no_atomic_cas,\n    ))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(\n        all(test, not(any(miri, portable_atomic_sanitize_thread))),\n        not(target_has_atomic = \"ptr\"),\n    ))\n)]\n#[cfg(any(target_arch = \"riscv32\", target_arch = \"riscv64\"))]\nmod riscv;\n\n// x86-specific optimizations\n// Miri and Sanitizer do not support inline assembly.\n#[cfg(all(\n    any(target_arch = \"x86\", target_arch = \"x86_64\"),\n    not(any(miri, portable_atomic_sanitize_thread)),\n    any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n))]\npub(crate) mod x86;\n\n// 64-bit atomic implementations on 32-bit architectures\n#[cfg(any(target_arch = \"arm\", target_arch = \"riscv32\"))]\nmod atomic64;\n\n// 128-bit atomic implementations on 64-bit architectures\n#[cfg(any(\n    target_arch = \"aarch64\",\n    target_arch = \"arm64ec\",\n    target_arch = \"powerpc64\",\n    target_arch = \"riscv64\",\n    target_arch = \"s390x\",\n    target_arch = \"x86_64\",\n))]\nmod atomic128;\n\n// -----------------------------------------------------------------------------\n// Lock-based fallback implementations\n\n#[cfg(feature = \"fallback\")]\n#[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not(portable_atomic_no_atomic_cas)))]\n#[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(target_has_atomic = \"ptr\"))]\n#[cfg_attr(\n    not(test),\n    cfg(not(any(\n        // ---------------\n        // Use other ways.\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        portable_atomic_unsafe_assume_single_core,\n        // --------------------\n        // Has 128-bit atomics.\n        all(\n            target_arch = \"aarch64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n        ),\n        all(\n            target_arch = \"arm64ec\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n        ),\n        all(\n            target_arch = \"x86_64\",\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n        ),\n        all(\n            target_arch = \"riscv64\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n        ),\n        all(\n            target_arch = \"powerpc64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n            any(\n                target_feature = \"quadword-atomics\",\n                portable_atomic_target_feature = \"quadword-atomics\",\n            ),\n        ),\n        all(\n            target_arch = \"s390x\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n        ),\n    ))\n))]\nmod fallback;\n\n// -----------------------------------------------------------------------------\n// Fallback implementation based on disabling interrupts or critical-section\n\n// On AVR, we always use critical section based fallback implementation.\n// AVR can be safely assumed to be single-core, so this is sound.\n// MSP430 as well.\n// See the module-level comments of interrupt module for more.\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(any(\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        all(feature = \"critical-section\", any(test, portable_atomic_no_atomic_cas)),\n        portable_atomic_unsafe_assume_single_core,\n        portable_atomic_unsafe_assume_privileged,\n    ))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(any(\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        all(feature = \"critical-section\", any(test, not(target_has_atomic = \"ptr\"))),\n        portable_atomic_unsafe_assume_single_core,\n        portable_atomic_unsafe_assume_privileged,\n    ))\n)]\n#[cfg(any(\n    target_arch = \"arm\",\n    target_arch = \"avr\",\n    target_arch = \"msp430\",\n    target_arch = \"riscv32\",\n    target_arch = \"riscv64\",\n    target_arch = \"xtensa\",\n    feature = \"critical-section\",\n))]\nmod interrupt;\n\n// -----------------------------------------------------------------------------\n// Atomic float implementations\n\n#[cfg(feature = \"float\")]\npub(crate) mod float;\n\n// -----------------------------------------------------------------------------\n\n// {8,16,32}-bit & ptr-sized atomics\ncfg_sel!({\n    // has CAS | (has core atomic & !(avr | msp430 | critical section)) => core atomic\n    #[cfg_attr(\n        portable_atomic_no_cfg_target_has_atomic,\n        cfg(not(any(\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            portable_atomic_no_atomic_load_store,\n            all(\n                any(\n                    target_arch = \"riscv32\",\n                    target_arch = \"riscv64\",\n                    feature = \"critical-section\",\n                    portable_atomic_unsafe_assume_single_core,\n                ),\n                portable_atomic_no_atomic_cas,\n            ),\n        )))\n    )]\n    #[cfg_attr(\n        not(portable_atomic_no_cfg_target_has_atomic),\n        cfg(not(any(\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            portable_atomic_no_atomic_load_store,\n            all(\n                any(\n                    target_arch = \"riscv32\",\n                    target_arch = \"riscv64\",\n                    feature = \"critical-section\",\n                    portable_atomic_unsafe_assume_single_core,\n                ),\n                not(target_has_atomic = \"ptr\"),\n            ),\n        )))\n    )]\n    {\n        pub(crate) use self::core_atomic::{\n            AtomicI8, AtomicI16, AtomicI32, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16, AtomicU32,\n            AtomicUsize,\n        };\n    }\n    // no native atomic CAS & (assume single core | critical section) => critical section based fallback\n    #[cfg(any(\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    ))]\n    {\n        pub(crate) use self::interrupt::{\n            AtomicI8, AtomicI16, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16, AtomicUsize,\n        };\n        #[cfg(any(not(target_pointer_width = \"16\"), feature = \"fallback\"))]\n        pub(crate) use self::interrupt::{AtomicI32, AtomicU32};\n    }\n    // RISC-V without A-extension & !(assume single core | critical section)\n    #[cfg(any(target_arch = \"riscv32\", target_arch = \"riscv64\"))]\n    {\n        pub(crate) use self::riscv::{\n            AtomicI8, AtomicI16, AtomicI32, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16, AtomicU32,\n            AtomicUsize,\n        };\n    }\n    // bpf & !(critical section) => core atomic\n    #[cfg(target_arch = \"bpf\")]\n    {\n        pub(crate) use self::core_atomic::{AtomicIsize, AtomicPtr, AtomicUsize};\n    }\n    #[cfg(else)]\n    {\n        // no atomic\n    }\n});\n\n// 64-bit atomics\ncfg_sel!({\n    // has CAS | (has core atomic & !(avr | msp430 | critical section)) => core atomic\n    #[cfg_attr(\n        portable_atomic_no_cfg_target_has_atomic,\n        cfg(all(\n            not(any(\n                target_arch = \"avr\",\n                target_arch = \"msp430\",\n                portable_atomic_no_atomic_load_store,\n                all(\n                    any(\n                        target_arch = \"riscv32\",\n                        target_arch = \"riscv64\",\n                        feature = \"critical-section\",\n                        portable_atomic_unsafe_assume_single_core,\n                    ),\n                    portable_atomic_no_atomic_cas,\n                )\n            )),\n            any(\n                not(portable_atomic_no_atomic_64),\n                not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")),\n            ),\n        ))\n    )]\n    #[cfg_attr(\n        not(portable_atomic_no_cfg_target_has_atomic),\n        cfg(all(\n            not(any(\n                target_arch = \"avr\",\n                target_arch = \"msp430\",\n                portable_atomic_no_atomic_load_store,\n                all(\n                    any(\n                        target_arch = \"riscv32\",\n                        target_arch = \"riscv64\",\n                        feature = \"critical-section\",\n                        portable_atomic_unsafe_assume_single_core,\n                    ),\n                    not(target_has_atomic = \"ptr\"),\n                )\n            )),\n            any(\n                target_has_atomic = \"64\",\n                not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")),\n            ),\n        ))\n    )]\n    {\n        pub(crate) use self::core_atomic::{AtomicI64, AtomicU64};\n    }\n    // pre-v6 Arm Linux\n    #[cfg(all(\n        feature = \"fallback\",\n        target_arch = \"arm\",\n        not(any(miri, portable_atomic_sanitize_thread)),\n        any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n        any(target_os = \"linux\", target_os = \"android\"),\n        not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n        not(portable_atomic_no_outline_atomics),\n    ))]\n    {\n        pub(crate) use self::atomic64::arm_linux::{AtomicI64, AtomicU64};\n    }\n    // riscv32 & (zacas | outline-atomics)\n    #[cfg(all(\n        target_arch = \"riscv32\",\n        not(any(miri, portable_atomic_sanitize_thread)),\n        any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n        any(\n            target_feature = \"zacas\",\n            portable_atomic_target_feature = \"zacas\",\n            all(\n                feature = \"fallback\",\n                not(portable_atomic_no_outline_atomics),\n                any(target_os = \"linux\", target_os = \"android\"),\n            ),\n        ),\n    ))]\n    {\n        pub(crate) use self::atomic64::riscv32::{AtomicI64, AtomicU64};\n    }\n    // no native atomic CAS & (assume single core | critical section) => critical section based fallback\n    #[cfg_attr(\n        portable_atomic_no_cfg_target_has_atomic,\n        cfg(any(\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            all(feature = \"critical-section\", portable_atomic_no_atomic_cas),\n            portable_atomic_unsafe_assume_single_core,\n        ))\n    )]\n    #[cfg_attr(\n        not(portable_atomic_no_cfg_target_has_atomic),\n        cfg(any(\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            all(feature = \"critical-section\", not(target_has_atomic = \"ptr\")),\n            portable_atomic_unsafe_assume_single_core,\n        ))\n    )]\n    {\n        #[cfg(any(\n            not(any(target_pointer_width = \"16\", target_pointer_width = \"32\")),\n            feature = \"fallback\",\n        ))]\n        pub(crate) use self::interrupt::{AtomicI64, AtomicU64};\n    }\n    // no core 64-bit atomic & has CAS => use lock-base fallback\n    #[cfg_attr(\n        portable_atomic_no_cfg_target_has_atomic,\n        cfg(all(feature = \"fallback\", not(portable_atomic_no_atomic_cas)))\n    )]\n    #[cfg_attr(\n        not(portable_atomic_no_cfg_target_has_atomic),\n        cfg(all(feature = \"fallback\", target_has_atomic = \"ptr\"))\n    )]\n    {\n        pub(crate) use self::fallback::{AtomicI64, AtomicU64};\n    }\n    // RISC-V without A-extension & !(assume single core | critical section)\n    #[cfg(target_arch = \"riscv64\")]\n    {\n        pub(crate) use self::riscv::{AtomicI64, AtomicU64};\n    }\n    // bpf & !(critical section) => core atomic\n    #[cfg(target_arch = \"bpf\")]\n    {\n        pub(crate) use self::core_atomic::{AtomicI64, AtomicU64};\n    }\n    #[cfg(else)]\n    {\n        // no atomic\n    }\n});\n\n// 128-bit atomics\ncfg_sel!({\n    // AArch64\n    #[cfg(any(\n        all(\n            target_arch = \"aarch64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n        ),\n        all(\n            target_arch = \"arm64ec\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n        ),\n    ))]\n    {\n        pub(crate) use self::atomic128::aarch64::{AtomicI128, AtomicU128};\n    }\n    // x86_64 & (cmpxchg16b | outline-atomics)\n    #[cfg(all(\n        target_arch = \"x86_64\",\n        not(all(\n            any(miri, portable_atomic_sanitize_thread),\n            portable_atomic_no_cmpxchg16b_intrinsic,\n        )),\n        any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n        any(\n            target_feature = \"cmpxchg16b\",\n            portable_atomic_target_feature = \"cmpxchg16b\",\n            all(\n                feature = \"fallback\",\n                not(portable_atomic_no_outline_atomics),\n                not(any(target_env = \"sgx\", miri)),\n            ),\n        ),\n    ))]\n    {\n        pub(crate) use self::atomic128::x86_64::{AtomicI128, AtomicU128};\n    }\n    // riscv64 & (zacas | outline-atomics)\n    #[cfg(all(\n        target_arch = \"riscv64\",\n        not(any(miri, portable_atomic_sanitize_thread)),\n        any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n        any(\n            target_feature = \"zacas\",\n            portable_atomic_target_feature = \"zacas\",\n            all(\n                feature = \"fallback\",\n                not(portable_atomic_no_outline_atomics),\n                any(target_os = \"linux\", target_os = \"android\"),\n            ),\n        ),\n    ))]\n    {\n        pub(crate) use self::atomic128::riscv64::{AtomicI128, AtomicU128};\n    }\n    // powerpc64 & (pwr8 | outline-atomics)\n    #[cfg(all(\n        target_arch = \"powerpc64\",\n        not(all(\n            any(miri, portable_atomic_sanitize_thread),\n            not(portable_atomic_atomic_intrinsics),\n        )),\n        not(portable_atomic_no_asm),\n        any(\n            target_feature = \"quadword-atomics\",\n            portable_atomic_target_feature = \"quadword-atomics\",\n            all(\n                feature = \"fallback\",\n                not(portable_atomic_no_outline_atomics),\n                any(\n                    all(\n                        target_os = \"linux\",\n                        any(\n                            all(\n                                target_env = \"gnu\",\n                                any(target_endian = \"little\", not(target_feature = \"crt-static\")),\n                            ),\n                            all(\n                                target_env = \"musl\",\n                                any(not(target_feature = \"crt-static\"), feature = \"std\"),\n                            ),\n                            target_env = \"ohos\",\n                            all(target_env = \"uclibc\", not(target_feature = \"crt-static\")),\n                            portable_atomic_outline_atomics,\n                        ),\n                    ),\n                    target_os = \"android\",\n                    all(\n                        target_os = \"freebsd\",\n                        any(\n                            target_endian = \"little\",\n                            not(target_feature = \"crt-static\"),\n                            portable_atomic_outline_atomics,\n                        ),\n                    ),\n                    target_os = \"openbsd\",\n                    all(\n                        target_os = \"aix\",\n                        not(portable_atomic_pre_llvm_20),\n                        portable_atomic_outline_atomics,\n                    ), // TODO(aix): currently disabled by default\n                ),\n                not(any(miri, portable_atomic_sanitize_thread)),\n            ),\n        ),\n    ))]\n    {\n        pub(crate) use self::atomic128::powerpc64::{AtomicI128, AtomicU128};\n    }\n    // s390x\n    #[cfg(all(\n        target_arch = \"s390x\",\n        not(all(\n            any(miri, portable_atomic_sanitize_thread),\n            not(portable_atomic_atomic_intrinsics),\n        )),\n        not(portable_atomic_no_asm),\n    ))]\n    {\n        pub(crate) use self::atomic128::s390x::{AtomicI128, AtomicU128};\n    }\n    // no native atomic CAS & (assume single core | critical section) => critical section based fallback\n    #[cfg_attr(\n        portable_atomic_no_cfg_target_has_atomic,\n        cfg(any(\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            all(feature = \"critical-section\", portable_atomic_no_atomic_cas),\n            portable_atomic_unsafe_assume_single_core,\n        ))\n    )]\n    #[cfg_attr(\n        not(portable_atomic_no_cfg_target_has_atomic),\n        cfg(any(\n            target_arch = \"avr\",\n            target_arch = \"msp430\",\n            all(feature = \"critical-section\", not(target_has_atomic = \"ptr\")),\n            portable_atomic_unsafe_assume_single_core,\n        ))\n    )]\n    {\n        #[cfg(feature = \"fallback\")]\n        pub(crate) use self::interrupt::{AtomicI128, AtomicU128};\n    }\n    // no core 128-bit atomic & has CAS => use lock-base fallback\n    #[cfg_attr(\n        portable_atomic_no_cfg_target_has_atomic,\n        cfg(all(feature = \"fallback\", not(portable_atomic_no_atomic_cas)))\n    )]\n    #[cfg_attr(\n        not(portable_atomic_no_cfg_target_has_atomic),\n        cfg(all(feature = \"fallback\", target_has_atomic = \"ptr\"))\n    )]\n    {\n        pub(crate) use self::fallback::{AtomicI128, AtomicU128};\n    }\n    #[cfg(else)]\n    {\n        // no atomic\n    }\n});\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/msp430.rs",
      "sha256": "16635485eeca1c1c4b866253eefc1f39fa6121c84c16ec389b904c03fa9cdb55",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nAtomic implementation on MSP430.\n\nAdapted from https://github.com/pftbest/msp430-atomic.\n\nOperations not supported here are provided by disabling interrupts.\nSee also src/imp/interrupt/msp430.rs.\n\nSee \"Atomic operation overview by architecture\" in atomic-maybe-uninit for a more comprehensive and\ndetailed description of the atomic and synchronize instructions in this architecture:\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#msp430\n\nNote: Ordering is always SeqCst.\n\nRefs:\n- MSP430x5xx and MSP430x6xx Family User's Guide, Rev. Q\n  https://www.ti.com/lit/ug/slau208q/slau208q.pdf\n- atomic-maybe-uninit\n  https://github.com/taiki-e/atomic-maybe-uninit\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\n#[cfg(not(feature = \"critical-section\"))]\nuse core::cell::UnsafeCell;\nuse core::sync::atomic::Ordering;\n\n/// An atomic fence.\n///\n/// # Panics\n///\n/// Panics if `order` is [`Relaxed`](Ordering::Relaxed).\n#[inline]\n#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\npub fn fence(order: Ordering) {\n    match order {\n        Ordering::Relaxed => panic!(\"there is no such thing as a relaxed fence\"),\n        // MSP430 is single-core and a compiler fence works as an atomic fence.\n        _ => compiler_fence(order),\n    }\n}\n\n/// A compiler memory fence.\n///\n/// # Panics\n///\n/// Panics if `order` is [`Relaxed`](Ordering::Relaxed).\n#[inline]\n#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\npub fn compiler_fence(order: Ordering) {\n    match order {\n        Ordering::Relaxed => panic!(\"there is no such thing as a relaxed compiler fence\"),\n        _ => {}\n    }\n    // SAFETY: using an empty asm is safe.\n    unsafe {\n        // Do not use `nomem` and `readonly` because prevent preceding and subsequent memory accesses from being reordered.\n        #[cfg(not(portable_atomic_no_asm))]\n        asm!(\"\", options(nostack, preserves_flags));\n        #[cfg(portable_atomic_no_asm)]\n        llvm_asm!(\"\" ::: \"memory\" : \"volatile\");\n    }\n}\n\n#[cfg(not(feature = \"critical-section\"))]\nitems!({\n    macro_rules! atomic {\n        (load_store, $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $size:tt) => {\n            #[repr(transparent)]\n            pub(crate) struct $atomic_type $(<$($generics)*>)? {\n                v: UnsafeCell<$value_type>,\n            }\n\n            // Send is implicitly implemented for atomic integers, but not for atomic pointers.\n            // SAFETY: any data races are prevented by atomic operations.\n            unsafe impl $(<$($generics)*>)? Send for $atomic_type $(<$($generics)*>)? {}\n            // SAFETY: any data races are prevented by atomic operations.\n            unsafe impl $(<$($generics)*>)? Sync for $atomic_type $(<$($generics)*>)? {}\n\n            impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n                #[inline]\n                #[cfg_attr(\n                    all(debug_assertions, not(portable_atomic_no_track_caller)),\n                    track_caller\n                )]\n                pub(crate) fn load(&self, order: Ordering) -> $value_type {\n                    crate::utils::assert_load_ordering(order);\n                    let src = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe {\n                        let out;\n                        #[cfg(not(portable_atomic_no_asm))]\n                        asm!(\n                            concat!(\"mov.\", $size, \" @{src}, {out}\"), // atomic { out = *src }\n                            src = in(reg) src,\n                            out = lateout(reg) out,\n                            options(nostack, preserves_flags),\n                        );\n                        #[cfg(portable_atomic_no_asm)]\n                        llvm_asm!(\n                            concat!(\"mov.\", $size, \" $1, $0\")\n                            : \"=r\"(out) : \"*m\"(src) : \"memory\" : \"volatile\"\n                        );\n                        out\n                    }\n                }\n\n                #[inline]\n                #[cfg_attr(\n                    all(debug_assertions, not(portable_atomic_no_track_caller)),\n                    track_caller\n                )]\n                pub(crate) fn store(&self, val: $value_type, order: Ordering) {\n                    crate::utils::assert_store_ordering(order);\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe {\n                        #[cfg(not(portable_atomic_no_asm))]\n                        asm!(\n                            concat!(\"mov.\", $size, \" {val}, 0({dst})\"), // atomic { *dst = val }\n                            dst = in(reg) dst,\n                            val = in(reg) val,\n                            options(nostack, preserves_flags),\n                        );\n                        #[cfg(portable_atomic_no_asm)]\n                        llvm_asm!(\n                            concat!(\"mov.\", $size, \" $1, $0\")\n                            :: \"*m\"(dst), \"ir\"(val) : \"memory\" : \"volatile\"\n                        );\n                    }\n                }\n            }\n        };\n        ($([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $size:tt) => {\n            atomic!(load_store, $([$($generics)*])? $atomic_type, $value_type, $size);\n            impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n                #[inline]\n                pub(crate) fn add(&self, val: $value_type, _order: Ordering) {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe {\n                        #[cfg(not(portable_atomic_no_asm))]\n                        asm!(\n                            concat!(\"add.\", $size, \" {val}, 0({dst})\"), // atomic { *dst += val }\n                            dst = in(reg) dst,\n                            val = in(reg) val,\n                            // Do not use `preserves_flags` because ADD modifies the V, N, Z, and C bits of the status register.\n                            options(nostack),\n                        );\n                        #[cfg(portable_atomic_no_asm)]\n                        llvm_asm!(\n                            concat!(\"add.\", $size, \" $1, $0\")\n                            :: \"*m\"(dst), \"ir\"(val) : \"memory\" : \"volatile\"\n                        );\n                    }\n                }\n\n                #[inline]\n                pub(crate) fn sub(&self, val: $value_type, _order: Ordering) {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe {\n                        #[cfg(not(portable_atomic_no_asm))]\n                        asm!(\n                            concat!(\"sub.\", $size, \" {val}, 0({dst})\"), // atomic { *dst -= val }\n                            dst = in(reg) dst,\n                            val = in(reg) val,\n                            // Do not use `preserves_flags` because SUB modifies the V, N, Z, and C bits of the status register.\n                            options(nostack),\n                        );\n                        #[cfg(portable_atomic_no_asm)]\n                        llvm_asm!(\n                            concat!(\"sub.\", $size, \" $1, $0\")\n                            :: \"*m\"(dst), \"ir\"(val) : \"memory\" : \"volatile\"\n                        );\n                    }\n                }\n\n                #[inline]\n                pub(crate) fn and(&self, val: $value_type, _order: Ordering) {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe {\n                        #[cfg(not(portable_atomic_no_asm))]\n                        asm!(\n                            concat!(\"and.\", $size, \" {val}, 0({dst})\"), // atomic { *dst &= val }\n                            dst = in(reg) dst,\n                            val = in(reg) val,\n                            // Do not use `preserves_flags` because AND modifies the V, N, Z, and C bits of the status register.\n                            options(nostack),\n                        );\n                        #[cfg(portable_atomic_no_asm)]\n                        llvm_asm!(\n                            concat!(\"and.\", $size, \" $1, $0\")\n                            :: \"*m\"(dst), \"ir\"(val) : \"memory\" : \"volatile\"\n                        );\n                    }\n                }\n\n                #[inline]\n                pub(crate) fn or(&self, val: $value_type, _order: Ordering) {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe {\n                        #[cfg(not(portable_atomic_no_asm))]\n                        asm!(\n                            concat!(\"bis.\", $size, \" {val}, 0({dst})\"), // atomic { *dst |= val }\n                            dst = in(reg) dst,\n                            val = in(reg) val,\n                            options(nostack, preserves_flags),\n                        );\n                        #[cfg(portable_atomic_no_asm)]\n                        llvm_asm!(\n                            concat!(\"bis.\", $size, \" $1, $0\")\n                            :: \"*m\"(dst), \"ir\"(val) : \"memory\" : \"volatile\"\n                        );\n                    }\n                }\n\n                #[inline]\n                pub(crate) fn xor(&self, val: $value_type, _order: Ordering) {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe {\n                        #[cfg(not(portable_atomic_no_asm))]\n                        asm!(\n                            concat!(\"xor.\", $size, \" {val}, 0({dst})\"), // atomic { *dst ^= val }\n                            dst = in(reg) dst,\n                            val = in(reg) val,\n                            // Do not use `preserves_flags` because XOR modifies the V, N, Z, and C bits of the status register.\n                            options(nostack),\n                        );\n                        #[cfg(portable_atomic_no_asm)]\n                        llvm_asm!(\n                            concat!(\"xor.\", $size, \" $1, $0\")\n                            :: \"*m\"(dst), \"ir\"(val) : \"memory\" : \"volatile\"\n                        );\n                    }\n                }\n\n                #[inline]\n                pub(crate) fn not(&self, _order: Ordering) {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe {\n                        #[cfg(not(portable_atomic_no_asm))]\n                        asm!(\n                            concat!(\"inv.\", $size, \" 0({dst})\"), // atomic { *dst = !*dst }\n                            dst = in(reg) dst,\n                            // Do not use `preserves_flags` because INV modifies the V, N, Z, and C bits of the status register.\n                            options(nostack),\n                        );\n                        #[cfg(portable_atomic_no_asm)]\n                        llvm_asm!(\n                            concat!(\"inv.\", $size, \" $0\")\n                            :: \"*m\"(dst) : \"memory\" : \"volatile\"\n                        );\n                    }\n                }\n            }\n        };\n    }\n\n    atomic!(AtomicI8, i8, \"b\");\n    atomic!(AtomicU8, u8, \"b\");\n    atomic!(AtomicI16, i16, \"w\");\n    atomic!(AtomicU16, u16, \"w\");\n    atomic!(AtomicIsize, isize, \"w\");\n    atomic!(AtomicUsize, usize, \"w\");\n    atomic!(load_store, [T] AtomicPtr, *mut T, \"w\");\n});\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/riscv.rs",
      "sha256": "72c05a835e13b007ff587ec2fd35f619c32b74f18f0aa544fc304456ad5d255a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nAtomic load/store implementation on RISC-V.\n\nThis is for RISC-V targets without A extension. (pre-1.76 rustc doesn't provide atomics\nat all on such targets. https://github.com/rust-lang/rust/pull/114499)\n\nAlso, optionally provides RMW implementation when Zaamo extension or force-amo feature is enabled.\n\nIf A extension is not available but Zalrsc or Zacas extension is available, LLVM can implement all\natomic operations using it (https://github.com/llvm/llvm-project/commit/70f70390bb83a383fcb88ea843adbc4edf6ee34b),\nso this module contains no code for these extensions.\n\nSee \"Atomic operation overview by architecture\" in atomic-maybe-uninit for a more comprehensive and\ndetailed description of the atomic and synchronize instructions in this architecture:\nhttps://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md#risc-v\n\nRefs:\n- RISC-V Instruction Set Manual\n  \"Zaamo\" Extension for Atomic Memory Operations\n  https://docs.riscv.org/reference/isa/v20260120/unpriv/a-st-ext.html#sec:amo\n  \"Zabha\" Extension for Byte and Halfword Atomic Memory Operations\n  https://docs.riscv.org/reference/isa/v20260120/unpriv/zabha.html\n- RISC-V Atomics ABI Specification\n  https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20250812-301374e92976e298e676e7129a6212926b2299ce/riscv-atomic.adoc\n- atomic-maybe-uninit\n  https://github.com/taiki-e/atomic-maybe-uninit\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\nuse core::{cell::UnsafeCell, sync::atomic::Ordering};\n\n#[cfg(any(\n    test,\n    portable_atomic_force_amo,\n    target_feature = \"zaamo\",\n    portable_atomic_target_feature = \"zaamo\",\n))]\nitems!({\n    macro_rules! atomic_rmw_amo_ext {\n        // Use +a also for zaamo because `option arch +zaamo` requires LLVM 19.\n        // https://github.com/llvm/llvm-project/commit/8be079cdddfd628d356d9ddb5ab397ea95fb1030\n        (\"w\") => {\n            \"+a\"\n        };\n        (\"d\") => {\n            \"+a\"\n        };\n        (\"b\") => {\n            \"+a,+zabha\"\n        };\n        (\"h\") => {\n            \"+a,+zabha\"\n        };\n    }\n    macro_rules! atomic_rmw_amo {\n        ($op:ident, $dst:ident, $val:ident, $order:ident, $size:tt) => {{\n            let out;\n            macro_rules! op {\n                ($asm_order:tt) => {\n                    // SAFETY: The user guaranteed that the AMO instruction is available in this\n                    // system by setting the portable_atomic_force_amo/target_feature and\n                    // portable_atomic_unsafe_assume_single_core.\n                    // The caller of this macro must guarantee the validity of the pointer.\n                    asm!(\n                        \".option push\",\n                        // https://github.com/riscv-non-isa/riscv-asm-manual/blob/v0.0.1/src/asm-manual.adoc#arch\n                        // LLVM supports `.option arch` directive on LLVM 17+.\n                        // https://github.com/llvm/llvm-project/commit/9e8ed3403c191ab9c4903e8eeb8f732ff8a43cb4\n                        // Note that `.insn <value>` directive requires LLVM 19.\n                        // https://github.com/llvm/llvm-project/commit/2a086dce691e3cc34a2fc27f4fb255bb2cbbfac9\n                        concat!(\".option arch, \", atomic_rmw_amo_ext!($size)),\n                        concat!(\"amo\", stringify!($op), \".\", $size, $asm_order, \" {out}, {val}, 0({dst})\"), // atomic { _x = *dst; *dst = op(_x, val); out = _x }\n                        \".option pop\",\n                        dst = in(reg) ptr_reg!($dst),\n                        val = in(reg) $val,\n                        out = lateout(reg) out,\n                        options(nostack, preserves_flags),\n                    )\n                };\n            }\n            match $order {\n                Ordering::Relaxed => op!(\"\"),\n                Ordering::Acquire => op!(\".aq\"),\n                Ordering::Release => op!(\".rl\"),\n                // AcqRel and SeqCst RMWs are equivalent.\n                Ordering::AcqRel | Ordering::SeqCst => op!(\".aqrl\"),\n                _ => unreachable!(),\n            }\n            out\n        }};\n    }\n\n    #[cfg(not(any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\")))]\n    items!({\n        #[cfg(target_arch = \"riscv32\")]\n        macro_rules! w {\n            () => {\n                \"\"\n            };\n        }\n        #[cfg(target_arch = \"riscv64\")]\n        macro_rules! w {\n            () => {\n                \"w\"\n            };\n        }\n\n        // 32-bit val.wrapping_shl(shift) but no extra `& (u32::BITS - 1)`\n        #[inline(always)]\n        fn sllw(val: u32, shift: u32) -> u32 {\n            // SAFETY: Calling sll{,w} is safe.\n            unsafe {\n                let out;\n                asm!(\n                    concat!(\"sll\", w!(), \" {out}, {val}, {shift}\"), // out = val << shift & 31\n                    out = lateout(reg) out,\n                    val = in(reg) val,\n                    shift = in(reg) shift,\n                    options(pure, nomem, nostack, preserves_flags),\n                );\n                out\n            }\n        }\n        // 32-bit val.wrapping_shr(shift) but no extra `& (u32::BITS - 1)`\n        macro_rules! srlw {\n            ($val:expr, $shift:expr) => {\n                // SAFETY: Calling srl{,w} is safe.\n                unsafe {\n                    let val: u32 = $val;\n                    let shift: u32 = $shift;\n                    let out;\n                    asm!(\n                        concat!(\"srl\", w!(), \" {out}, {val}, {shift}\"), // out = val >> shift & 31\n                        out = lateout(reg) out,\n                        val = in(reg) val,\n                        shift = in(reg) shift,\n                        options(pure, nomem, nostack, preserves_flags),\n                    );\n                    out\n                }\n            };\n        }\n\n        trait ZeroExtend: Copy {\n            /// Zero-extends `self` to `u32` if it is smaller than 32-bit.\n            fn zero_extend(self) -> u32;\n        }\n        macro_rules! zero_extend {\n            ($int:ident, $uint:ident) => {\n                impl ZeroExtend for $uint {\n                    #[inline(always)]\n                    fn zero_extend(self) -> u32 {\n                        self as u32\n                    }\n                }\n                impl ZeroExtend for $int {\n                    #[allow(clippy::cast_sign_loss)]\n                    #[inline(always)]\n                    fn zero_extend(self) -> u32 {\n                        self as $uint as u32\n                    }\n                }\n            };\n        }\n        zero_extend!(i8, u8);\n        zero_extend!(i16, u16);\n    });\n});\n\nmacro_rules! atomic_load_store {\n    ($([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $size:tt) => {\n        #[repr(transparent)]\n        pub(crate) struct $atomic_type $(<$($generics)*>)? {\n            v: UnsafeCell<$value_type>,\n        }\n\n        // Send is implicitly implemented for atomic integers, but not for atomic pointers.\n        // SAFETY: any data races are prevented by atomic operations.\n        unsafe impl $(<$($generics)*>)? Send for $atomic_type $(<$($generics)*>)? {}\n        // SAFETY: any data races are prevented by atomic operations.\n        unsafe impl $(<$($generics)*>)? Sync for $atomic_type $(<$($generics)*>)? {}\n\n        #[cfg(any(test, not(portable_atomic_unsafe_assume_single_core)))]\n        impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n            #[inline]\n            pub(crate) const fn new(v: $value_type) -> Self {\n                Self { v: UnsafeCell::new(v) }\n            }\n\n            #[inline]\n            pub(crate) fn is_lock_free() -> bool {\n                Self::IS_ALWAYS_LOCK_FREE\n            }\n            pub(crate) const IS_ALWAYS_LOCK_FREE: bool = true;\n\n            #[inline]\n            pub(crate) const fn as_ptr(&self) -> *mut $value_type {\n                self.v.get()\n            }\n        }\n        impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn load(&self, order: Ordering) -> $value_type {\n                crate::utils::assert_load_ordering(order);\n                let src = self.v.get();\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    let out;\n                    macro_rules! atomic_load {\n                        ($acquire:tt, $release:tt) => {\n                            asm!(\n                                $release,                                // fence\n                                concat!(\"l\", $size, \" {out}, 0({src})\"), // atomic { out = *src }\n                                $acquire,                                // fence\n                                src = in(reg) ptr_reg!(src),\n                                out = lateout(reg) out,\n                                options(nostack, preserves_flags),\n                            )\n                        };\n                    }\n                    match order {\n                        Ordering::Relaxed => atomic_load!(\"\", \"\"),\n                        Ordering::Acquire => atomic_load!(\"fence r, rw\", \"\"),\n                        Ordering::SeqCst => atomic_load!(\"fence r, rw\", \"fence rw, rw\"),\n                        _ => unreachable!(),\n                    }\n                    out\n                }\n            }\n\n            #[inline]\n            #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n            pub(crate) fn store(&self, val: $value_type, order: Ordering) {\n                crate::utils::assert_store_ordering(order);\n                let dst = self.v.get();\n                // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                // pointer passed in is valid because we got it from a reference.\n                unsafe {\n                    macro_rules! atomic_store {\n                        ($acquire:tt, $release:tt) => {\n                            asm!(\n                                $release,                                // fence\n                                concat!(\"s\", $size, \" {val}, 0({dst})\"), // atomic { *dst = val }\n                                $acquire,                                // fence\n                                dst = in(reg) ptr_reg!(dst),\n                                val = in(reg) val,\n                                options(nostack, preserves_flags),\n                            )\n                        };\n                    }\n                    match order {\n                        Ordering::Relaxed => atomic_store!(\"\", \"\"),\n                        Ordering::Release => atomic_store!(\"\", \"fence rw, w\"),\n                        // https://github.com/llvm/llvm-project/commit/3ea8f2526541884e03d5bd4f4e46f4eb190990b6\n                        Ordering::SeqCst => atomic_store!(\"fence rw, rw\", \"fence rw, w\"),\n                        _ => unreachable!(),\n                    }\n                }\n            }\n        }\n    };\n}\n\nmacro_rules! atomic_base {\n    (\n        $([$($generics:tt)*])? $atomic_type:ident, $value_type:ty, $int_type:ty, $size:tt,\n        $fetch_add:ident, $fetch_sub:ident\n    ) => {\n        atomic_load_store!($([$($generics)*])? $atomic_type, $value_type, $size);\n        #[cfg(any(\n            test,\n            portable_atomic_force_amo,\n            target_feature = \"zaamo\",\n            portable_atomic_target_feature = \"zaamo\",\n        ))]\n        items!({\n            // There is no amo{sub,nand,neg}.\n            impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n                #[inline]\n                pub(crate) fn swap(&self, val: $value_type, order: Ordering) -> $value_type {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe { atomic_rmw_amo!(swap, dst, val, order, $size) }\n                }\n                #[inline]\n                pub(crate) fn $fetch_add(&self, val: $int_type, order: Ordering) -> $value_type {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe { atomic_rmw_amo!(add, dst, val, order, $size) }\n                }\n                #[inline]\n                pub(crate) fn $fetch_sub(&self, val: $int_type, order: Ordering) -> $value_type {\n                    self.$fetch_add(val.wrapping_neg(), order)\n                }\n                #[inline]\n                pub(crate) fn fetch_and(&self, val: $int_type, order: Ordering) -> $value_type {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe { atomic_rmw_amo!(and, dst, val, order, $size) }\n                }\n                #[inline]\n                pub(crate) fn fetch_or(&self, val: $int_type, order: Ordering) -> $value_type {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe { atomic_rmw_amo!(or, dst, val, order, $size) }\n                }\n                #[inline]\n                pub(crate) fn fetch_xor(&self, val: $int_type, order: Ordering) -> $value_type {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe { atomic_rmw_amo!(xor, dst, val, order, $size) }\n                }\n            }\n            #[cfg(not(any(portable_atomic_unsafe_assume_single_core, feature = \"critical-section\")))]\n            impl_default_bit_opts!($atomic_type, $int_type);\n        });\n    };\n}\n\nmacro_rules! atomic_ptr {\n    ($size:tt) => {\n        atomic_base!([T] AtomicPtr, *mut T, usize, $size, fetch_byte_add, fetch_byte_sub);\n    };\n}\n\nmacro_rules! atomic {\n    ($atomic_type:ident, $value_type:ty, $size:tt, $max:tt, $min:tt) => {\n        atomic_base!($atomic_type, $value_type, $value_type, $size, fetch_add, fetch_sub);\n        #[cfg(any(\n            test,\n            portable_atomic_force_amo,\n            target_feature = \"zaamo\",\n            portable_atomic_target_feature = \"zaamo\",\n        ))]\n        items!({\n            // There is no amo{sub,nand,neg}.\n            impl $atomic_type {\n                #[inline]\n                pub(crate) fn fetch_not(&self, order: Ordering) -> $value_type {\n                    let dst = self.v.get();\n                    let val: crate::utils::RegSize = !0;\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe { atomic_rmw_amo!(xor, dst, val, order, $size) }\n                }\n                #[inline]\n                pub(crate) fn fetch_max(&self, val: $value_type, order: Ordering) -> $value_type {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe { atomic_rmw_amo!($max, dst, val, order, $size) }\n                }\n                #[inline]\n                pub(crate) fn fetch_min(&self, val: $value_type, order: Ordering) -> $value_type {\n                    let dst = self.v.get();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    unsafe { atomic_rmw_amo!($min, dst, val, order, $size) }\n                }\n            }\n            #[cfg(not(any(\n                portable_atomic_unsafe_assume_single_core,\n                feature = \"critical-section\",\n            )))]\n            items!({\n                impl_default_no_fetch_ops!($atomic_type, $value_type);\n                impl $atomic_type {\n                    #[inline]\n                    pub(crate) fn not(&self, order: Ordering) {\n                        self.fetch_not(order);\n                    }\n                }\n            });\n        });\n    };\n}\n\nmacro_rules! atomic_sub_word {\n    ($atomic_type:ident, $value_type:ty, $size:tt, $max:tt, $min:tt) => {\n        cfg_sel!({\n            #[cfg(any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\"))]\n            {\n                atomic!($atomic_type, $value_type, $size, $max, $min);\n            }\n            #[cfg(else)]\n            {\n                atomic_load_store!($atomic_type, $value_type, $size);\n                #[cfg(any(\n                    test,\n                    portable_atomic_force_amo,\n                    target_feature = \"zaamo\",\n                    portable_atomic_target_feature = \"zaamo\",\n                ))]\n                items!({\n                    impl $atomic_type {\n                        #[inline]\n                        pub(crate) fn fetch_and(\n                            &self,\n                            val: $value_type,\n                            order: Ordering,\n                        ) -> $value_type {\n                            let dst = self.v.get();\n                            let (dst, shift, mut mask) =\n                                crate::utils::create_sub_word_mask_values(dst);\n                            mask = !sllw(mask, shift);\n                            let mut val = sllw(ZeroExtend::zero_extend(val), shift);\n                            val |= mask;\n                            // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                            // pointer passed in is valid because we got it from a reference.\n                            let out: u32 = unsafe { atomic_rmw_amo!(and, dst, val, order, \"w\") };\n                            srlw!(out, shift)\n                        }\n                        #[inline]\n                        pub(crate) fn fetch_or(\n                            &self,\n                            val: $value_type,\n                            order: Ordering,\n                        ) -> $value_type {\n                            let dst = self.v.get();\n                            let (dst, shift, _mask) =\n                                crate::utils::create_sub_word_mask_values(dst);\n                            let val = sllw(ZeroExtend::zero_extend(val), shift);\n                            // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                            // pointer passed in is valid because we got it from a reference.\n                            let out: u32 = unsafe { atomic_rmw_amo!(or, dst, val, order, \"w\") };\n                            srlw!(out, shift)\n                        }\n                        #[inline]\n                        pub(crate) fn fetch_xor(\n                            &self,\n                            val: $value_type,\n                            order: Ordering,\n                        ) -> $value_type {\n                            let dst = self.v.get();\n                            let (dst, shift, _mask) =\n                                crate::utils::create_sub_word_mask_values(dst);\n                            let val = sllw(ZeroExtend::zero_extend(val), shift);\n                            // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                            // pointer passed in is valid because we got it from a reference.\n                            let out: u32 = unsafe { atomic_rmw_amo!(xor, dst, val, order, \"w\") };\n                            srlw!(out, shift)\n                        }\n                        #[inline]\n                        pub(crate) fn fetch_not(&self, order: Ordering) -> $value_type {\n                            self.fetch_xor(!0, order)\n                        }\n                    }\n                    #[cfg(not(any(\n                        portable_atomic_unsafe_assume_single_core,\n                        feature = \"critical-section\",\n                    )))]\n                    items!({\n                        impl_default_bit_opts!($atomic_type, $value_type);\n                        impl $atomic_type {\n                            #[inline]\n                            pub(crate) fn and(&self, val: $value_type, order: Ordering) {\n                                self.fetch_and(val, order);\n                            }\n                            #[inline]\n                            pub(crate) fn or(&self, val: $value_type, order: Ordering) {\n                                self.fetch_or(val, order);\n                            }\n                            #[inline]\n                            pub(crate) fn xor(&self, val: $value_type, order: Ordering) {\n                                self.fetch_xor(val, order);\n                            }\n                            #[inline]\n                            pub(crate) fn not(&self, order: Ordering) {\n                                self.fetch_not(order);\n                            }\n                        }\n                    });\n                });\n            }\n        });\n    };\n}\n\natomic_sub_word!(AtomicI8, i8, \"b\", max, min);\natomic_sub_word!(AtomicU8, u8, \"b\", maxu, minu);\natomic_sub_word!(AtomicI16, i16, \"h\", max, min);\natomic_sub_word!(AtomicU16, u16, \"h\", maxu, minu);\natomic!(AtomicI32, i32, \"w\", max, min);\natomic!(AtomicU32, u32, \"w\", maxu, minu);\n#[cfg(target_arch = \"riscv64\")]\natomic!(AtomicI64, i64, \"d\", max, min);\n#[cfg(target_arch = \"riscv64\")]\natomic!(AtomicU64, u64, \"d\", maxu, minu);\n#[cfg(target_pointer_width = \"32\")]\natomic!(AtomicIsize, isize, \"w\", max, min);\n#[cfg(target_pointer_width = \"32\")]\natomic!(AtomicUsize, usize, \"w\", maxu, minu);\n#[cfg(target_pointer_width = \"32\")]\natomic_ptr!(\"w\");\n#[cfg(target_pointer_width = \"64\")]\natomic!(AtomicIsize, isize, \"d\", max, min);\n#[cfg(target_pointer_width = \"64\")]\natomic!(AtomicUsize, usize, \"d\", maxu, minu);\n#[cfg(target_pointer_width = \"64\")]\natomic_ptr!(\"d\");\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    test_atomic_ptr_load_store!();\n    test_atomic_int_load_store!(i8);\n    test_atomic_int_load_store!(u8);\n    test_atomic_int_load_store!(i16);\n    test_atomic_int_load_store!(u16);\n    test_atomic_int_load_store!(i32);\n    test_atomic_int_load_store!(u32);\n    #[cfg(target_arch = \"riscv64\")]\n    test_atomic_int_load_store!(i64);\n    #[cfg(target_arch = \"riscv64\")]\n    test_atomic_int_load_store!(u64);\n    test_atomic_int_load_store!(isize);\n    test_atomic_int_load_store!(usize);\n\n    macro_rules! test_atomic_ptr_amo {\n        () => {\n            #[allow(\n                clippy::alloc_instead_of_core,\n                clippy::std_instead_of_alloc,\n                clippy::std_instead_of_core,\n                clippy::undocumented_unsafe_blocks\n            )]\n            mod test_atomic_ptr_amo {\n                use super::*;\n                test_atomic_ptr_amo!(AtomicPtr<u8>);\n            }\n        };\n        ($atomic_type:ty) => {\n            #[allow(unused_imports)]\n            use sptr::Strict as _;\n\n            use crate::tests::helper; // for old rustc\n\n            ::quickcheck::quickcheck! {\n                fn quickcheck_swap(x: usize, y: usize) -> bool {\n                    let x = sptr::invalid_mut(x);\n                    let y = sptr::invalid_mut(y);\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.swap(y, order), x);\n                        assert_eq!(a.swap(x, order), y);\n                    }\n                    true\n                }\n                fn quickcheck_fetch_byte_add(x: usize, y: usize) -> bool {\n                    let x = sptr::invalid_mut(x);\n                    let y = sptr::invalid_mut::<u8>(y);\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_byte_add(y.addr(), order), x);\n                        assert_eq!(\n                            a.load(Ordering::Relaxed).addr(), x.addr().wrapping_add(y.addr())\n                        );\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_byte_add(x.addr(), order), y);\n                        assert_eq!(\n                            a.load(Ordering::Relaxed).addr(), y.addr().wrapping_add(x.addr())\n                        );\n                    }\n                    true\n                }\n                fn quickcheck_fetch_byte_sub(x: usize, y: usize) -> bool {\n                    let x = sptr::invalid_mut(x);\n                    let y = sptr::invalid_mut::<u8>(y);\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_byte_sub(y.addr(), order), x);\n                        assert_eq!(\n                            a.load(Ordering::Relaxed).addr(), x.addr().wrapping_sub(y.addr())\n                        );\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_byte_sub(x.addr(), order), y);\n                        assert_eq!(\n                            a.load(Ordering::Relaxed).addr(), y.addr().wrapping_sub(x.addr())\n                        );\n                    }\n                    true\n                }\n                fn quickcheck_fetch_and(x: usize, y: usize) -> bool {\n                    let x = sptr::invalid_mut(x);\n                    let y = sptr::invalid_mut::<u8>(y);\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_and(y.addr(), order), x);\n                        assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() & y.addr());\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_and(x.addr(), order), y);\n                        assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() & x.addr());\n                    }\n                    true\n                }\n                fn quickcheck_fetch_or(x: usize, y: usize) -> bool {\n                    let x = sptr::invalid_mut(x);\n                    let y = sptr::invalid_mut::<u8>(y);\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_or(y.addr(), order), x);\n                        assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() | y.addr());\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_or(x.addr(), order), y);\n                        assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() | x.addr());\n                    }\n                    true\n                }\n                fn quickcheck_fetch_xor(x: usize, y: usize) -> bool {\n                    let x = sptr::invalid_mut(x);\n                    let y = sptr::invalid_mut::<u8>(y);\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_xor(y.addr(), order), x);\n                        assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() ^ y.addr());\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_xor(x.addr(), order), y);\n                        assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() ^ x.addr());\n                    }\n                    true\n                }\n            }\n        };\n    }\n    macro_rules! test_atomic_int_amo {\n        ($int_type:ident) => {\n            paste::paste! {\n                #[allow(\n                    clippy::alloc_instead_of_core,\n                    clippy::std_instead_of_alloc,\n                    clippy::std_instead_of_core,\n                    clippy::undocumented_unsafe_blocks\n                )]\n                mod [<test_atomic_ $int_type _amo>] {\n                    use super::*;\n                    test_atomic_int_amo!([<Atomic $int_type:camel>], $int_type);\n                }\n            }\n        };\n        ($atomic_type:ty, $int_type:ident) => {\n            use crate::tests::helper;\n            ::quickcheck::quickcheck! {\n                fn quickcheck_swap(x: $int_type, y: $int_type) -> bool {\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.swap(y, order), x);\n                        assert_eq!(a.swap(x, order), y);\n                    }\n                    true\n                }\n                fn quickcheck_fetch_add(x: $int_type, y: $int_type) -> bool {\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_add(y, order), x);\n                        assert_eq!(a.load(Ordering::Relaxed), x.wrapping_add(y));\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_add(x, order), y);\n                        assert_eq!(a.load(Ordering::Relaxed), y.wrapping_add(x));\n                    }\n                    true\n                }\n                fn quickcheck_fetch_sub(x: $int_type, y: $int_type) -> bool {\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_sub(y, order), x);\n                        assert_eq!(a.load(Ordering::Relaxed), x.wrapping_sub(y));\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_sub(x, order), y);\n                        assert_eq!(a.load(Ordering::Relaxed), y.wrapping_sub(x));\n                    }\n                    true\n                }\n                fn quickcheck_fetch_and(x: $int_type, y: $int_type) -> bool {\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_and(y, order), x);\n                        assert_eq!(a.load(Ordering::Relaxed), x & y);\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_and(x, order), y);\n                        assert_eq!(a.load(Ordering::Relaxed), y & x);\n                    }\n                    true\n                }\n                fn quickcheck_fetch_or(x: $int_type, y: $int_type) -> bool {\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_or(y, order), x);\n                        assert_eq!(a.load(Ordering::Relaxed), x | y);\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_or(x, order), y);\n                        assert_eq!(a.load(Ordering::Relaxed), y | x);\n                    }\n                    true\n                }\n                fn quickcheck_fetch_xor(x: $int_type, y: $int_type) -> bool {\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_xor(y, order), x);\n                        assert_eq!(a.load(Ordering::Relaxed), x ^ y);\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_xor(x, order), y);\n                        assert_eq!(a.load(Ordering::Relaxed), y ^ x);\n                    }\n                    true\n                }\n                fn quickcheck_fetch_max(x: $int_type, y: $int_type) -> bool {\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_max(y, order), x);\n                        assert_eq!(a.load(Ordering::Relaxed), core::cmp::max(x, y));\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_max(x, order), y);\n                        assert_eq!(a.load(Ordering::Relaxed), core::cmp::max(y, x));\n                    }\n                    true\n                }\n                fn quickcheck_fetch_min(x: $int_type, y: $int_type) -> bool {\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_min(y, order), x);\n                        assert_eq!(a.load(Ordering::Relaxed), core::cmp::min(x, y));\n                        let a = <$atomic_type>::new(y);\n                        assert_eq!(a.fetch_min(x, order), y);\n                        assert_eq!(a.load(Ordering::Relaxed), core::cmp::min(y, x));\n                    }\n                    true\n                }\n                fn quickcheck_fetch_not(x: $int_type) -> bool {\n                    for &order in &helper::SWAP_ORDERINGS {\n                        let a = <$atomic_type>::new(x);\n                        assert_eq!(a.fetch_not(order), x);\n                        assert_eq!(a.load(Ordering::Relaxed), !x);\n                        assert_eq!(a.fetch_not(order), !x);\n                        assert_eq!(a.load(Ordering::Relaxed), x);\n                    }\n                    true\n                }\n            }\n        };\n    }\n    macro_rules! test_atomic_int_amo_sub_word {\n        ($int_type:ident) => {\n            paste::paste! {\n                #[allow(\n                    clippy::alloc_instead_of_core,\n                    clippy::std_instead_of_alloc,\n                    clippy::std_instead_of_core,\n                    clippy::undocumented_unsafe_blocks\n                )]\n                mod [<test_atomic_ $int_type _amo>] {\n                    use super::*;\n                    #[cfg(any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\"))]\n                    test_atomic_int_amo!([<Atomic $int_type:camel>], $int_type);\n                    #[cfg(not(any(target_feature = \"zabha\", portable_atomic_target_feature = \"zabha\")))]\n                    test_atomic_int_amo_sub_word!([<Atomic $int_type:camel>], $int_type);\n                }\n            }\n        };\n        ($atomic_type:ty, $int_type:ident) => {\n            use crate::tests::helper::{self, *};\n            ::quickcheck::quickcheck! {\n                fn quickcheck_fetch_and(x: $int_type, y: $int_type) -> bool {\n                    let mut rng = fastrand::Rng::new();\n                    for &order in &helper::SWAP_ORDERINGS {\n                        for base in [0, !0] {\n                            let mut arr = Align16([\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                            ]);\n                            let a_idx = rng.usize(3..=6);\n                            arr.0[a_idx] = <$atomic_type>::new(x);\n                            let a = &arr.0[a_idx];\n                            assert_eq!(a.fetch_and(y, order), x);\n                            assert_eq!(a.load(Ordering::Relaxed), x & y);\n                            for i in 0..a_idx {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                            for i in a_idx + 1..arr.0.len() {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                            arr.0[a_idx] = <$atomic_type>::new(y);\n                            let a = &arr.0[a_idx];\n                            assert_eq!(a.fetch_and(x, order), y);\n                            assert_eq!(a.load(Ordering::Relaxed), y & x);\n                            for i in 0..a_idx {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                            for i in a_idx + 1..arr.0.len() {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                        }\n                    }\n                    true\n                }\n                fn quickcheck_fetch_or(x: $int_type, y: $int_type) -> bool {\n                    let mut rng = fastrand::Rng::new();\n                    for &order in &helper::SWAP_ORDERINGS {\n                        for base in [0, !0] {\n                            let mut arr = Align16([\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                            ]);\n                            let a_idx = rng.usize(3..=6);\n                            arr.0[a_idx] = <$atomic_type>::new(x);\n                            let a = &arr.0[a_idx];\n                            assert_eq!(a.fetch_or(y, order), x);\n                            assert_eq!(a.load(Ordering::Relaxed), x | y);\n                            for i in 0..a_idx {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                            for i in a_idx + 1..arr.0.len() {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                            arr.0[a_idx] = <$atomic_type>::new(y);\n                            let a = &arr.0[a_idx];\n                            assert_eq!(a.fetch_or(x, order), y);\n                            assert_eq!(a.load(Ordering::Relaxed), y | x);\n                            for i in 0..a_idx {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                            for i in a_idx + 1..arr.0.len() {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                        }\n                    }\n                    true\n                }\n                fn quickcheck_fetch_xor(x: $int_type, y: $int_type) -> bool {\n                    let mut rng = fastrand::Rng::new();\n                    for &order in &helper::SWAP_ORDERINGS {\n                        for base in [0, !0] {\n                            let mut arr = Align16([\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                            ]);\n                            let a_idx = rng.usize(3..=6);\n                            arr.0[a_idx] = <$atomic_type>::new(x);\n                            let a = &arr.0[a_idx];\n                            assert_eq!(a.fetch_xor(y, order), x);\n                            assert_eq!(a.load(Ordering::Relaxed), x ^ y);\n                            for i in 0..a_idx {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                            for i in a_idx + 1..arr.0.len() {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                            arr.0[a_idx] = <$atomic_type>::new(y);\n                            let a = &arr.0[a_idx];\n                            assert_eq!(a.fetch_xor(x, order), y);\n                            assert_eq!(a.load(Ordering::Relaxed), y ^ x);\n                            for i in 0..a_idx {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                            for i in a_idx + 1..arr.0.len() {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                        }\n                    }\n                    true\n                }\n                fn quickcheck_fetch_not(x: $int_type) -> bool {\n                    let mut rng = fastrand::Rng::new();\n                    for &order in &helper::SWAP_ORDERINGS {\n                        for base in [0, !0] {\n                            let mut arr = Align16([\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                                <$atomic_type>::new(base),\n                            ]);\n                            let a_idx = rng.usize(3..=6);\n                            arr.0[a_idx] = <$atomic_type>::new(x);\n                            let a = &arr.0[a_idx];\n                            assert_eq!(a.fetch_not(order), x);\n                            assert_eq!(a.load(Ordering::Relaxed), !x);\n                            assert_eq!(a.fetch_not(order), !x);\n                            assert_eq!(a.load(Ordering::Relaxed), x);\n                            for i in 0..a_idx {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                            for i in a_idx + 1..arr.0.len() {\n                                assert_eq!(arr.0[i].load(Ordering::Relaxed), base, \"invalid value written\");\n                            }\n                        }\n                    }\n                    true\n                }\n            }\n        };\n    }\n    test_atomic_ptr_amo!();\n    test_atomic_int_amo_sub_word!(i8);\n    test_atomic_int_amo_sub_word!(u8);\n    test_atomic_int_amo_sub_word!(i16);\n    test_atomic_int_amo_sub_word!(u16);\n    test_atomic_int_amo!(i32);\n    test_atomic_int_amo!(u32);\n    #[cfg(target_arch = \"riscv64\")]\n    test_atomic_int_amo!(i64);\n    #[cfg(target_arch = \"riscv64\")]\n    test_atomic_int_amo!(u64);\n    test_atomic_int_amo!(isize);\n    test_atomic_int_amo!(usize);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/imp/x86.rs",
      "sha256": "4c11976fccadc618d68d6aba4caf744d2859f60f63c6fb08f626f2a2561e6b52",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*\nAtomic operations implementation on x86/x86_64.\n\nThis module provides atomic operations not supported by LLVM or optimizes\ncases where LLVM code generation is not optimal.\n\nNote: On Miri and ThreadSanitizer which do not support inline assembly, we don't use\nthis module and use CAS loop instead.\n\nRefs:\n- x86 and amd64 instruction reference https://www.felixcloutier.com/x86\n\nSee tests/asm-test/asm/portable-atomic for generated assembly.\n*/\n\n#[cfg(not(portable_atomic_no_asm))]\nuse core::arch::asm;\nuse core::sync::atomic::Ordering;\n\n#[cfg(target_pointer_width = \"32\")]\nmacro_rules! ptr_modifier {\n    () => {\n        \":e\"\n    };\n}\n#[cfg(target_pointer_width = \"64\")]\nmacro_rules! ptr_modifier {\n    () => {\n        \"\"\n    };\n}\n\n/// An atomic fence.\n///\n/// # Panics\n///\n/// Panics if `order` is [`Relaxed`](Ordering::Relaxed).\n#[cfg_attr(doc, allow(dead_code))]\n#[inline]\n#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\npub fn fence(order: Ordering) {\n    if order == Ordering::SeqCst {\n        let p = core::cell::UnsafeCell::new(core::mem::MaybeUninit::<usize>::uninit());\n        // SAFETY: raw pointer passed in is valid because we got it from a reference.\n        unsafe {\n            // Equivalent to `mfence`, but is up to 3.1x faster on Coffee Lake and up to 2.4x faster on Raptor Lake-H at least in simple cases.\n            // - https://github.com/taiki-e/portable-atomic/pull/156\n            // - LLVM uses `lock or` https://godbolt.org/z/vv6rjzfYd\n            // - Windows uses `xchg` for x86_32 for MemoryBarrier https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-memorybarrier\n            // - MSVC STL uses `lock inc` https://github.com/microsoft/STL/pull/740\n            // - boost uses `lock or` https://github.com/boostorg/atomic/commit/559eba81af71386cedd99f170dc6101c6ad7bf22\n            #[cfg(target_pointer_width = \"64\")]\n            asm!(\n                concat!(\"xchg qword ptr [{p\", ptr_modifier!(), \"}], {tmp}\"),\n                p = in(reg) p.get(),\n                tmp = out(reg) _,\n                options(nostack, preserves_flags),\n            );\n            #[cfg(target_pointer_width = \"32\")]\n            asm!(\n                concat!(\"xchg dword ptr [{p\", ptr_modifier!(), \"}], {tmp:e}\"),\n                p = in(reg) p.get(),\n                tmp = out(reg) _,\n                options(nostack, preserves_flags),\n            );\n        }\n    } else {\n        core::sync::atomic::fence(order);\n    }\n}\n\ncfg_core_atomic!({\n    use super::core_atomic::{\n        AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize, AtomicPtr, AtomicU8, AtomicU16,\n        AtomicU32, AtomicU64, AtomicUsize,\n    };\n\n    macro_rules! atomic_int {\n        ($atomic_type:ident, $ptr_size:tt) => {\n            impl $atomic_type {\n                #[inline]\n                pub(crate) fn not(&self, _order: Ordering) {\n                    let dst = self.as_ptr();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    //\n                    // https://www.felixcloutier.com/x86/not\n                    unsafe {\n                        // atomic RMW is always SeqCst.\n                        asm!(\n                            concat!(\"lock not \", $ptr_size, \" ptr [{dst\", ptr_modifier!(), \"}]\"),\n                            dst = in(reg) dst,\n                            options(nostack, preserves_flags),\n                        );\n                    }\n                }\n                #[inline]\n                pub(crate) fn neg(&self, _order: Ordering) {\n                    let dst = self.as_ptr();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    //\n                    // https://www.felixcloutier.com/x86/neg\n                    unsafe {\n                        // atomic RMW is always SeqCst.\n                        asm!(\n                            concat!(\"lock neg \", $ptr_size, \" ptr [{dst\", ptr_modifier!(), \"}]\"),\n                            dst = in(reg) dst,\n                            // Do not use `preserves_flags` because NEG modifies the CF, OF, SF, ZF, AF, and PF flag.\n                            options(nostack),\n                        );\n                    }\n                }\n            }\n        };\n    }\n\n    atomic_int!(AtomicI8, \"byte\");\n    atomic_int!(AtomicU8, \"byte\");\n    atomic_int!(AtomicI16, \"word\");\n    atomic_int!(AtomicU16, \"word\");\n    atomic_int!(AtomicI32, \"dword\");\n    atomic_int!(AtomicU32, \"dword\");\n    #[cfg(target_arch = \"x86_64\")]\n    atomic_int!(AtomicI64, \"qword\");\n    #[cfg(target_arch = \"x86_64\")]\n    atomic_int!(AtomicU64, \"qword\");\n    #[cfg(target_pointer_width = \"32\")]\n    atomic_int!(AtomicIsize, \"dword\");\n    #[cfg(target_pointer_width = \"32\")]\n    atomic_int!(AtomicUsize, \"dword\");\n    #[cfg(target_pointer_width = \"64\")]\n    atomic_int!(AtomicIsize, \"qword\");\n    #[cfg(target_pointer_width = \"64\")]\n    atomic_int!(AtomicUsize, \"qword\");\n\n    #[cfg(target_arch = \"x86\")]\n    impl AtomicI64 {\n        #[inline]\n        pub(crate) fn not(&self, order: Ordering) {\n            self.fetch_not(order);\n        }\n        #[inline]\n        pub(crate) fn neg(&self, order: Ordering) {\n            self.fetch_neg(order);\n        }\n    }\n    #[cfg(target_arch = \"x86\")]\n    impl AtomicU64 {\n        #[inline]\n        pub(crate) fn not(&self, order: Ordering) {\n            self.fetch_not(order);\n        }\n        #[inline]\n        pub(crate) fn neg(&self, order: Ordering) {\n            self.fetch_neg(order);\n        }\n    }\n\n    macro_rules! atomic_bit_opts {\n        (\n            $([$($generics:tt)*])? $atomic_type:ident, $int_type:ident, $val_modifier:tt,\n            $ptr_size:tt\n        ) => {\n            // LLVM 14 and older don't support generating `lock bt{s,r,c}`.\n            // LLVM 15 only supports generating `lock bt{s,r,c}` for immediate bit offsets.\n            // LLVM 16+ can generate `lock bt{s,r,c}` for both immediate and register bit offsets.\n            // https://godbolt.org/z/TGhr5z4ds\n            // So, use fetch_* based implementations on LLVM 16+, otherwise use asm based implementations.\n            #[cfg(not(portable_atomic_pre_llvm_16))]\n            impl_default_bit_opts!($atomic_type, $int_type);\n            #[cfg(portable_atomic_pre_llvm_16)]\n            impl $(<$($generics)*>)? $atomic_type $(<$($generics)*>)? {\n                // `<integer>::BITS` requires Rust 1.53\n                const BITS: u32 = (core::mem::size_of::<$int_type>() * 8) as u32;\n                #[inline]\n                pub(crate) fn bit_set(&self, bit: u32, _order: Ordering) -> bool {\n                    let dst = self.as_ptr();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    // the masking by the bit size of the type ensures that we do not shift\n                    // out of bounds.\n                    //\n                    // https://www.felixcloutier.com/x86/bts\n                    unsafe {\n                        let r: u8;\n                        // atomic RMW is always SeqCst.\n                        asm!(\n                            concat!(\"lock bts \", $ptr_size, \" ptr [{dst\", ptr_modifier!(), \"}], {bit\", $val_modifier, \"}\"),\n                            \"setb {r}\",\n                            dst = in(reg) dst,\n                            bit = in(reg) (bit & (Self::BITS - 1)) as $int_type,\n                            r = out(reg_byte) r,\n                            // Do not use `preserves_flags` because BTS modifies the CF flag.\n                            options(nostack),\n                        );\n                        crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test\n                        r != 0\n                    }\n                }\n                #[inline]\n                pub(crate) fn bit_clear(&self, bit: u32, _order: Ordering) -> bool {\n                    let dst = self.as_ptr();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    // the masking by the bit size of the type ensures that we do not shift\n                    // out of bounds.\n                    //\n                    // https://www.felixcloutier.com/x86/btr\n                    unsafe {\n                        let r: u8;\n                        // atomic RMW is always SeqCst.\n                        asm!(\n                            concat!(\"lock btr \", $ptr_size, \" ptr [{dst\", ptr_modifier!(), \"}], {bit\", $val_modifier, \"}\"),\n                            \"setb {r}\",\n                            dst = in(reg) dst,\n                            bit = in(reg) (bit & (Self::BITS - 1)) as $int_type,\n                            r = out(reg_byte) r,\n                            // Do not use `preserves_flags` because BTR modifies the CF flag.\n                            options(nostack),\n                        );\n                        crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test\n                        r != 0\n                    }\n                }\n                #[inline]\n                pub(crate) fn bit_toggle(&self, bit: u32, _order: Ordering) -> bool {\n                    let dst = self.as_ptr();\n                    // SAFETY: any data races are prevented by atomic intrinsics and the raw\n                    // pointer passed in is valid because we got it from a reference.\n                    // the masking by the bit size of the type ensures that we do not shift\n                    // out of bounds.\n                    //\n                    // https://www.felixcloutier.com/x86/btc\n                    unsafe {\n                        let r: u8;\n                        // atomic RMW is always SeqCst.\n                        asm!(\n                            concat!(\"lock btc \", $ptr_size, \" ptr [{dst\", ptr_modifier!(), \"}], {bit\", $val_modifier, \"}\"),\n                            \"setb {r}\",\n                            dst = in(reg) dst,\n                            bit = in(reg) (bit & (Self::BITS - 1)) as $int_type,\n                            r = out(reg_byte) r,\n                            // Do not use `preserves_flags` because BTC modifies the CF flag.\n                            options(nostack),\n                        );\n                        crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test\n                        r != 0\n                    }\n                }\n            }\n        };\n    }\n\n    impl_default_bit_opts!(AtomicI8, i8);\n    impl_default_bit_opts!(AtomicU8, u8);\n    atomic_bit_opts!(AtomicI16, i16, \":x\", \"word\");\n    atomic_bit_opts!(AtomicU16, u16, \":x\", \"word\");\n    atomic_bit_opts!(AtomicI32, i32, \":e\", \"dword\");\n    atomic_bit_opts!(AtomicU32, u32, \":e\", \"dword\");\n    #[cfg(target_arch = \"x86_64\")]\n    atomic_bit_opts!(AtomicI64, i64, \"\", \"qword\");\n    #[cfg(target_arch = \"x86_64\")]\n    atomic_bit_opts!(AtomicU64, u64, \"\", \"qword\");\n    #[cfg(target_arch = \"x86\")]\n    impl_default_bit_opts!(AtomicI64, i64);\n    #[cfg(target_arch = \"x86\")]\n    impl_default_bit_opts!(AtomicU64, u64);\n    #[cfg(target_pointer_width = \"32\")]\n    atomic_bit_opts!(AtomicIsize, isize, \":e\", \"dword\");\n    #[cfg(target_pointer_width = \"32\")]\n    atomic_bit_opts!(AtomicUsize, usize, \":e\", \"dword\");\n    #[cfg(target_pointer_width = \"32\")]\n    atomic_bit_opts!([T] AtomicPtr, usize, \":e\", \"dword\");\n    #[cfg(target_pointer_width = \"64\")]\n    atomic_bit_opts!(AtomicIsize, isize, \"\", \"qword\");\n    #[cfg(target_pointer_width = \"64\")]\n    atomic_bit_opts!(AtomicUsize, usize, \"\", \"qword\");\n    #[cfg(target_pointer_width = \"64\")]\n    atomic_bit_opts!([T] AtomicPtr, usize, \"\", \"qword\");\n});\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/lib.rs",
      "sha256": "8fac4257f626a2669a44dd74a966677b368647fd883e32d8db79c57a06af6895",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*!\n<!-- Note: Document from sync-markdown-to-rustdoc:start through sync-markdown-to-rustdoc:end\n     is synchronized from README.md. Any changes to that range are not preserved. -->\n<!-- tidy:sync-markdown-to-rustdoc:start -->\n\nPortable atomic types including support for 128-bit atomics, atomic float, etc.\n\n- Provide all atomic integer types (`Atomic{I,U}{8,16,32,64}`) for all targets that can use atomic CAS. (i.e., all targets that can use `std`, and most no-std targets)\n- Provide `AtomicI128` and `AtomicU128`.\n- Provide `AtomicF32` and `AtomicF64`. ([optional, requires the `float` feature](#optional-features-float))\n- Provide `AtomicF16` and `AtomicF128` for [unstable `f16` and `f128`](https://github.com/rust-lang/rust/issues/116909). ([optional, requires the `float` feature and unstable cfgs](#optional-features-float))\n- Provide atomic load/store for targets where atomic is not available at all in the standard library. (RISC-V without A-extension, MSP430, AVR)\n- Provide atomic CAS for targets where atomic CAS is not available in the standard library. (thumbv6m, pre-v6 Arm, RISC-V without A-extension, MSP430, AVR, Xtensa, etc.) (always enabled for MSP430 and AVR, [optional](#optional-features-critical-section) otherwise)\n- Make features that require newer compilers, such as [`fetch_{max,min}`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_max), [`fetch_update`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_update), [`as_ptr`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.as_ptr), [`from_ptr`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.from_ptr), [`AtomicBool::fetch_not`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicBool.html#method.fetch_not), [`AtomicPtr::fetch_*`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.fetch_and), and [stronger CAS failure ordering](https://github.com/rust-lang/rust/pull/98383) available on Rust 1.34+.\n- Provide workaround for bugs in the standard library's atomic-related APIs, such as [rust-lang/compiler-builtins#1234], [rust-lang/rust#100650], `fence`/`compiler_fence` on MSP430 that cause LLVM error, etc.\n\n<!-- TODO:\n- mention Atomic{I,U}*::fetch_neg, Atomic{I*,U*,Ptr}::bit_*, etc.\n- mention optimizations not available in the standard library's equivalents\n-->\n\nportable-atomic version of `std::sync::Arc` and `std::task::Wake` is provided by the [portable-atomic-util] crate.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nportable-atomic = \"1\"\n```\n\nThe default features are mainly for users who use atomics larger than the pointer width.\nIf you don't need them, disabling the default features may reduce code size and compile time slightly.\n\n```toml\n[dependencies]\nportable-atomic = { version = \"1\", default-features = false }\n```\n\nIf your crate supports no-std environment and requires atomic CAS, enabling the `require-cas` feature will allow the portable-atomic to display a [helpful error message](https://github.com/taiki-e/portable-atomic/pull/100) to users on targets requiring additional action on the user side to provide atomic CAS.\n\n```toml\n[dependencies]\nportable-atomic = { version = \"1.3\", default-features = false, features = [\"require-cas\"] }\n```\n\n(Since 1.8, portable-atomic can display a [helpful error message](https://github.com/taiki-e/portable-atomic/pull/181) even without the `require-cas` feature when the rustc version is 1.78+. However, the `require-cas` feature also allows rejecting builds at an earlier stage, we recommend enabling it unless enabling it causes [problems](https://github.com/matklad/once_cell/pull/267).)\n\n## 128-bit atomics support\n\nNative 128-bit atomic operations are available on x86_64 (Rust 1.59+), AArch64 (Rust 1.59+), riscv64 (Rust 1.59+), Arm64EC (Rust 1.84+), s390x (Rust 1.84+), and powerpc64 (Rust 1.95+), otherwise the fallback implementation is used.\n\nOn x86_64, even if `cmpxchg16b` is not available at compile-time (Note: `cmpxchg16b` target feature is enabled by default only on Apple, Windows (except Windows 7), and Fuchsia targets), run-time detection checks whether `cmpxchg16b` is available. If `cmpxchg16b` is not available at either compile-time or run-time detection, the fallback implementation is used. See also [`portable_atomic_no_outline_atomics`](#optional-cfg-no-outline-atomics) cfg.\n\nThey are usually implemented using inline assembly, and when using Miri or ThreadSanitizer that do not support inline assembly, core intrinsics are used instead of inline assembly if possible.\n\nSee the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md) for details.\n\n## <a name=\"optional-features\"></a><a name=\"optional-cfg\"></a>Optional features/cfgs\n\nportable-atomic provides features and cfgs to allow enabling specific APIs and customizing its behavior.\n\nSome options have both a feature and a cfg. When both exist, it indicates that the feature does not follow Cargo's recommendation that [features should be additive](https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-unification). Therefore, the maintainer's recommendation is to use cfg instead of feature. However, in the embedded ecosystem, it is very common to use features in such places, so these options provide both so you can choose based on your preference.\n\n<details>\n<summary>How to enable cfg (click to show)</summary>\n\nOne of the ways to enable cfg is to set [rustflags in the cargo config](https://doc.rust-lang.org/cargo/reference/config.html#targettriplerustflags):\n\n```toml\n# .cargo/config.toml\n[target.<target>]\nrustflags = [\"--cfg\", \"portable_atomic_unsafe_assume_single_core\"]\n```\n\nOr set environment variable:\n\n```sh\nRUSTFLAGS=\"--cfg portable_atomic_unsafe_assume_single_core\" cargo ...\n```\n\n</details>\n\n- <a name=\"optional-features-fallback\"></a>**`fallback` feature** *(enabled by default)*<br>\n  Enable fallback implementations.\n\n  This enables atomic types with larger than the width supported by atomic instructions available on the current target. If the current target [supports 128-bit atomics](#128-bit-atomics-support), this is no-op.\n\n  This uses fallback implementation that using global locks by default. The following features/cfgs change this behavior:\n  - [`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg](#optional-features-unsafe-assume-single-core): Use fallback implementations that disabling interrupts instead of using global locks.\n    - If your target is single-core and calling interrupt disable instructions is safe, this is a safer and more efficient option.\n  - [`unsafe-assume-privileged` feature / `portable_atomic_unsafe_assume_privileged` cfg](#optional-features-unsafe-assume-privileged): Use fallback implementations that using global locks with disabling interrupts.\n    - If your target is multi-core and calling interrupt disable instructions is safe, this is a safer option.\n\n- <a name=\"optional-features-float\"></a>**`float` feature**<br>\n  Provide `AtomicF{32,64}`.\n\n  If you want atomic types for unstable float types ([`f16` and `f128`](https://github.com/rust-lang/rust/issues/116909)), enable unstable cfg (`portable_atomic_unstable_f16` cfg for `AtomicF16`, `portable_atomic_unstable_f128` cfg for `AtomicF128`, [there is no possibility that both feature and cfg will be provided for unstable options.](https://github.com/taiki-e/portable-atomic/pull/200#issuecomment-2682252991)).\n\n<div class=\"rustdoc-alert rustdoc-alert-note\">\n\n> **ⓘ Note**\n>\n> - Atomic float's `fetch_{add,sub,min,max}` are usually implemented using CAS loops, which can be slower than equivalent operations of atomic integers. As an exception, AArch64 with FEAT_LSFE and GPU targets have atomic float instructions and we use them on AArch64 when `lsfe` target feature is available at compile-time. We [plan to use atomic float instructions for GPU targets as well in the future.](https://github.com/taiki-e/portable-atomic/issues/34)\n> - Unstable cfgs are outside of the normal semver guarantees and minor or patch versions of portable-atomic may make breaking changes to them at any time.\n\n</div>\n\n- <a name=\"optional-features-std\"></a>**`std` feature**<br>\n  Use `std`.\n\n- <a name=\"optional-features-require-cas\"></a>**`require-cas` feature**<br>\n  Emit compile error if atomic CAS is not available. See [Usage](#usage) section for usage of this feature.\n\n- <a name=\"optional-features-serde\"></a>**`serde` feature**<br>\n  Implement `serde::{Serialize,Deserialize}` for atomic types.\n\n  Note:\n  - The MSRV when this feature is enabled depends on the MSRV of [serde].\n\n- <a name=\"optional-features-critical-section\"></a>**`critical-section` feature**<br>\n  Use [critical-section] to provide atomic CAS for targets where atomic CAS is not available in the standard library.\n\n  `critical-section` support is useful to get atomic CAS when the [`unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)](#optional-features-unsafe-assume-single-core) can't be used,\n  such as multi-core targets, unprivileged code running under some RTOS, or environments where disabling interrupts\n  needs extra care due to e.g. real-time requirements.\n\n<div class=\"rustdoc-alert rustdoc-alert-note\">\n\n> **ⓘ Note**\n>\n> - When enabling this feature, you should provide a suitable critical section implementation for the current target, see the [critical-section] documentation for details on how to do so.\n> - With this feature, critical sections are taken for all atomic operations, while with `unsafe-assume-single-core` feature [some operations](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/interrupt/README.md#no-disable-interrupts) don't require disabling interrupts. Therefore, for better performance, if all the `critical-section` implementation for your target does is disable interrupts, prefer using `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) instead.\n> - It is usually **discouraged** to always enable this feature in libraries that depend on `portable-atomic`.\n>\n>   Enabling this feature will prevent the end user from having the chance to take advantage of other (potentially) efficient implementations (implementations provided by `unsafe-assume-single-core` feature mentioned above, implementation proposed in [#60], etc.). Also, targets that are currently unsupported may be supported in the future.\n>\n>   The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature. (However, it may make sense to enable this feature by default for libraries specific to a platform where other implementations are known not to work.)\n>\n>   See also [this comment](https://github.com/matklad/once_cell/issues/264#issuecomment-2352654806).\n>\n>   As an example, the end-user's `Cargo.toml` that uses a crate that provides a critical-section implementation and a crate that depends on portable-atomic as an option would be expected to look like this:\n>\n>   ```toml\n>   [dependencies]\n>   portable-atomic = { version = \"1\", default-features = false, features = [\"critical-section\"] }\n>   crate-provides-critical-section-impl = \"...\"\n>   crate-uses-portable-atomic-as-feature = { version = \"...\", features = [\"portable-atomic\"] }\n>   ```\n>\n> - Enabling both this feature and `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) will result in a compile error.\n> - Enabling both this feature and `unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg) will result in a compile error.\n> - The MSRV when this feature is enabled depends on the MSRV of [critical-section].\n\n</div>\n\n- <a name=\"optional-features-unsafe-assume-single-core\"></a><a name=\"optional-cfg-unsafe-assume-single-core\"></a>**`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg**<br>\n  Assume that the target is single-core and privileged instructions required to disable interrupts are available.\n\n  - When this feature/cfg is enabled, this crate provides atomic CAS for targets where atomic CAS is not available in the standard library by disabling interrupts.\n  - When both this feature/cfg and enabled-by-default `fallback` feature is enabled, this crate provides atomic types with larger than the width supported by native instructions by disabling interrupts.\n\n<div class=\"rustdoc-alert rustdoc-alert-warning\">\n\n> **⚠ Warning**\n>\n> This feature/cfg is `unsafe`, and note the following safety requirements:\n> - Enabling this feature/cfg for multi-core systems is always **unsound**.\n>\n> - This uses privileged instructions to disable interrupts, so it usually doesn't work on unprivileged mode.\n>\n>   Enabling this feature/cfg in an environment where privileged instructions are not available, or if the instructions used are not sufficient to disable interrupts in the system, it is also usually considered **unsound**, although the details are system-dependent.\n>\n>   The following are known cases:\n>   - On Arm (except for M-Profile architectures), this disables only IRQs by default. For many systems (e.g., GBA) this is enough. If the system need to disable both IRQs and FIQs, you need to enable the `disable-fiq` feature (or `portable_atomic_disable_fiq` cfg) together.\n>   - On RISC-V, this generates code for machine-mode (M-mode) by default. If you enable the `s-mode` feature (or `portable_atomic_s_mode` cfg) together, this generates code for supervisor-mode (S-mode). In particular, `qemu-system-riscv*` uses [OpenSBI](https://github.com/riscv-software-src/opensbi) as the default firmware.\n\n</div>\n\nConsider using the [`unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg)](#optional-features-unsafe-assume-privileged) for multi-core systems with atomic CAS.\n\nConsider using the [`critical-section` feature](#optional-features-critical-section) for systems that cannot use this feature/cfg.\n\nSee also the [`interrupt` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/interrupt/README.md).\n\n<div class=\"rustdoc-alert rustdoc-alert-note\">\n\n> **ⓘ Note**\n>\n> - It is **very strongly discouraged** to enable this feature/cfg in libraries that depend on `portable-atomic`.\n>\n>   The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature/cfg. (However, it may make sense to enable this feature/cfg by default for libraries specific to a platform where it is guaranteed to always be sound, for example in a hardware abstraction layer targeting a single-core chip.)\n> - Enabling this feature/cfg for unsupported architectures will result in a compile error.\n>   - Arm, RISC-V, and Xtensa are currently supported. (Since all MSP430 and AVR are single-core, we always provide atomic CAS for them without this feature/cfg.)\n>   - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target is not supported yet.\n> - Enabling this feature/cfg for targets where privileged instructions are obviously unavailable (e.g., Linux) will result in a compile error.\n>   - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target supports privileged instructions but the build rejected.\n> - Enabling both this feature/cfg and `critical-section` feature will result in a compile error.\n> - When both this feature/cfg and `unsafe-assume-privileged` feature (or `portable_atomic_unsafe_assume_privileged` cfg) are enabled, this feature/cfg is preferred.\n\n</div>\n\n- <a name=\"optional-features-unsafe-assume-privileged\"></a><a name=\"optional-cfg-unsafe-assume-privileged\"></a>**`unsafe-assume-privileged` feature / `portable_atomic_unsafe_assume_privileged` cfg**<br>\n  Similar to `unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg, but only assumes about availability of privileged instructions required to disable interrupts.\n\n  - When both this feature/cfg and enabled-by-default `fallback` feature is enabled, this crate provides atomic types with larger than the width supported by native instructions by using global locks with disabling interrupts.\n\n<div class=\"rustdoc-alert rustdoc-alert-warning\">\n\n> **⚠ Warning**\n>\n> This feature/cfg is `unsafe`, and except for being sound in multi-core systems, this has the same safety requirements as [`unsafe-assume-single-core` feature / `portable_atomic_unsafe_assume_single_core` cfg](#optional-features-unsafe-assume-single-core).\n\n</div>\n\n<div class=\"rustdoc-alert rustdoc-alert-note\">\n\n> **ⓘ Note**\n>\n> - It is **very strongly discouraged** to enable this feature/cfg in libraries that depend on `portable-atomic`.\n>\n>   The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature/cfg. (However, it may make sense to enable this feature/cfg by default for libraries specific to a platform where it is guaranteed to always be sound, for example in a hardware abstraction layer.)\n> - Enabling this feature/cfg for unsupported targets will result in a compile error.\n>   - This requires atomic CAS (`cfg(target_has_atomic = \"ptr\")` or `cfg_no_atomic_cas!`).\n>   - Arm, RISC-V, and Xtensa are currently supported.\n>   - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target is not supported yet.\n> - Enabling this feature/cfg for targets where privileged instructions are obviously unavailable (e.g., Linux) will result in a compile error.\n>   - Feel free to [submit an issue](https://github.com/taiki-e/portable-atomic/issues/new) if your target supports privileged instructions but the build rejected.\n> - Enabling both this feature/cfg and `critical-section` feature will result in a compile error.\n> - When both this feature/cfg and `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg) are enabled, `unsafe-assume-single-core` is preferred.\n\n</div>\n\n- <a name=\"optional-cfg-no-outline-atomics\"></a>**`portable_atomic_no_outline_atomics` cfg**<br>\n  Disable dynamic dispatching by run-time CPU feature detection.\n\n  Dynamic dispatching by run-time CPU feature detection allows maintaining support for older CPUs while using features that are not supported on older CPUs, such as CMPXCHG16B (x86_64) and FEAT_LSE/FEAT_LSE2 (AArch64).\n\n  See also the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md).\n\n<div class=\"rustdoc-alert rustdoc-alert-note\">\n\n> **ⓘ Note**\n>\n> - If the required target features are enabled at compile-time, dynamic dispatching is automatically disabled and the atomic operations are inlined.\n> - This is compatible with no-std (as with all features except `std`).\n> - On some targets, run-time detection is disabled by default mainly for compatibility with incomplete build environments or support for it is experimental, and can be enabled by `portable_atomic_outline_atomics` cfg. (When both cfg are enabled, `*_no_*` cfg is preferred.)\n> - Some AArch64 targets enable LLVM's `outline-atomics` target feature by default, so if you set this cfg, you may want to disable that as well. (However, portable-atomic's outline-atomics does not depend on the compiler-rt symbols, so even if you need to disable LLVM's outline-atomics, you may not need to disable portable-atomic's outline-atomics.)\n> - Dynamic detection is currently only supported in x86_64, AArch64, Arm, RISC-V, Arm64EC, and powerpc64. Enabling this cfg for unsupported architectures will be ignored.\n\n</div>\n\n## Related Projects\n\n- [portable-atomic-util]: Synchronization primitives built with portable-atomic. This provides portable-atomic version of `std::sync::Arc` and `std::task::Wake`.\n- [atomic-maybe-uninit]: Atomic operations on potentially uninitialized integers.\n- [atomic-memcpy]: Byte-wise atomic memcpy.\n- [asmtest]: A library for tracking generated assemblies.\n\n[#60]: https://github.com/taiki-e/portable-atomic/issues/60\n[asmtest]: https://github.com/taiki-e/asmtest\n[atomic-maybe-uninit]: https://github.com/taiki-e/atomic-maybe-uninit\n[atomic-memcpy]: https://github.com/taiki-e/atomic-memcpy\n[critical-section]: https://github.com/rust-embedded/critical-section\n[portable-atomic-util]: https://github.com/taiki-e/portable-atomic-util\n[rust-lang/compiler-builtins#1234]: https://github.com/rust-lang/compiler-builtins/pull/1234\n[rust-lang/rust#100650]: https://github.com/rust-lang/rust/issues/100650\n[serde]: https://github.com/serde-rs/serde\n\n<!-- tidy:sync-markdown-to-rustdoc:end -->\n*/\n\n#![no_std]\n#![doc(test(\n    no_crate_inject,\n    attr(\n        deny(warnings, rust_2018_idioms, single_use_lifetimes),\n        allow(dead_code, unused_variables)\n    )\n))]\n#![cfg_attr(not(portable_atomic_no_unsafe_op_in_unsafe_fn), warn(unsafe_op_in_unsafe_fn))] // unsafe_op_in_unsafe_fn requires Rust 1.52\n#![cfg_attr(portable_atomic_no_unsafe_op_in_unsafe_fn, allow(unused_unsafe))]\n#![warn(\n    // Lints that may help when writing public library.\n    missing_debug_implementations,\n    // missing_docs,\n    clippy::alloc_instead_of_core,\n    clippy::exhaustive_enums,\n    clippy::exhaustive_structs,\n    clippy::impl_trait_in_params,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    clippy::missing_inline_in_public_items,\n    // Code outside of cfg(feature = \"float\") shouldn't use float.\n    clippy::float_arithmetic,\n)]\n#![cfg_attr(not(portable_atomic_no_asm), warn(missing_docs))] // module-level #![allow(missing_docs)] doesn't work for macros on old rustc\n#![cfg_attr(portable_atomic_no_strict_provenance, allow(unstable_name_collisions))]\n#![allow(\n    clippy::inline_always,\n    clippy::manual_assert_eq,\n    clippy::unreadable_literal,\n    clippy::used_underscore_items\n)]\n// asm_experimental_arch\n// AVR, MSP430, and Xtensa are tier 3 platforms and require nightly anyway.\n// On tier 2 platforms (currently N/A), we use cfg set by build script to\n// determine whether this feature is available or not.\n#![cfg_attr(\n    all(\n        not(portable_atomic_no_asm),\n        any(\n            all(target_arch = \"avr\", not(feature = \"critical-section\")),\n            target_arch = \"msp430\",\n            all(\n                target_arch = \"xtensa\",\n                any(\n                    portable_atomic_unsafe_assume_single_core,\n                    portable_atomic_unsafe_assume_privileged,\n                ),\n            ),\n        ),\n    ),\n    feature(asm_experimental_arch)\n)]\n// f16/f128\n// cfg is unstable and explicitly enabled by the user\n#![cfg_attr(\n    any(portable_atomic_unstable_f16, portable_atomic_unstable_f128),\n    allow(unused_features)\n)]\n#![cfg_attr(all(portable_atomic_unstable_f16, feature = \"float\"), feature(f16))]\n#![cfg_attr(all(portable_atomic_unstable_f128, feature = \"float\"), feature(f128))]\n// Old nightly only\n// These features are already stabilized or have already been removed from compilers,\n// and can safely be enabled for old nightly as long as version detection works.\n// - cfg(target_has_atomic)\n// - asm! on AArch64, Arm, RISC-V, x86, x86_64, Arm64EC, s390x, PowerPC64\n// - llvm_asm! on AVR (tier 3) and MSP430 (tier 3)\n// - #[instruction_set] on non-Linux/Android pre-v6 Arm (tier 3)\n// This also helps us test that our assembly code works with the minimum external\n// LLVM version of the first rustc version that inline assembly stabilized.\n#![cfg_attr(portable_atomic_unstable_cfg_target_has_atomic, feature(cfg_target_has_atomic))]\n#![cfg_attr(\n    all(\n        portable_atomic_unstable_asm,\n        any(\n            target_arch = \"aarch64\",\n            target_arch = \"arm\",\n            target_arch = \"riscv32\",\n            target_arch = \"riscv64\",\n            target_arch = \"x86\",\n            target_arch = \"x86_64\",\n        ),\n    ),\n    feature(asm)\n)]\n#![cfg_attr(\n    all(\n        portable_atomic_unstable_asm_experimental_arch,\n        any(target_arch = \"arm64ec\", target_arch = \"s390x\", target_arch = \"powerpc64\"),\n    ),\n    feature(asm_experimental_arch)\n)]\n#![cfg_attr(\n    all(any(target_arch = \"avr\", target_arch = \"msp430\"), portable_atomic_no_asm),\n    feature(llvm_asm)\n)]\n#![cfg_attr(\n    all(\n        target_arch = \"arm\",\n        portable_atomic_unstable_isa_attribute,\n        any(portable_atomic_unsafe_assume_single_core, portable_atomic_unsafe_assume_privileged),\n        not(any(target_feature = \"v7\", portable_atomic_target_feature = \"v7\")),\n        not(any(target_feature = \"mclass\", portable_atomic_target_feature = \"mclass\")),\n    ),\n    feature(isa_attribute)\n)]\n// Miri and/or ThreadSanitizer only\n// They do not support inline assembly, so we need to use unstable features instead.\n// Since they require nightly compilers anyway, we can use the unstable features.\n// This is not an ideal situation, but it is still better than always using lock-based\n// fallback and causing memory ordering problems to be missed by these checkers.\n#![cfg_attr(\n    all(\n        any(\n            target_arch = \"aarch64\",\n            target_arch = \"arm64ec\",\n            target_arch = \"powerpc64\",\n            target_arch = \"s390x\",\n        ),\n        any(miri, portable_atomic_sanitize_thread),\n    ),\n    allow(internal_features)\n)]\n#![cfg_attr(\n    all(\n        any(\n            target_arch = \"aarch64\",\n            target_arch = \"arm64ec\",\n            target_arch = \"powerpc64\",\n            target_arch = \"s390x\",\n        ),\n        portable_atomic_atomic_intrinsics,\n        any(miri, portable_atomic_sanitize_thread),\n    ),\n    feature(core_intrinsics)\n)]\n// docs.rs only (cfg is enabled by docs.rs, not build script)\n#![cfg_attr(docsrs, feature(doc_cfg))]\n#![cfg_attr(docsrs, doc(auto_cfg = false))]\n#![cfg_attr(\n    all(\n        portable_atomic_no_atomic_load_store,\n        not(any(\n            target_arch = \"avr\",\n            target_arch = \"bpf\",\n            target_arch = \"msp430\",\n            target_arch = \"riscv32\",\n            target_arch = \"riscv64\",\n            feature = \"critical-section\",\n            portable_atomic_unsafe_assume_single_core,\n        )),\n    ),\n    allow(unused_imports, unused_macros, clippy::unused_trait_names)\n)]\n\n#[cfg(any(test, feature = \"std\"))]\nextern crate std;\n\n#[macro_use]\nmod cfgs;\n#[cfg(target_pointer_width = \"16\")]\npub use self::{cfg_has_atomic_16 as cfg_has_atomic_ptr, cfg_no_atomic_16 as cfg_no_atomic_ptr};\n#[cfg(target_pointer_width = \"32\")]\npub use self::{cfg_has_atomic_32 as cfg_has_atomic_ptr, cfg_no_atomic_32 as cfg_no_atomic_ptr};\n#[cfg(target_pointer_width = \"64\")]\npub use self::{cfg_has_atomic_64 as cfg_has_atomic_ptr, cfg_no_atomic_64 as cfg_no_atomic_ptr};\n#[cfg(target_pointer_width = \"128\")]\npub use self::{cfg_has_atomic_128 as cfg_has_atomic_ptr, cfg_no_atomic_128 as cfg_no_atomic_ptr};\n\n// There are currently no 128-bit or higher builtin targets.\n// (Although some of our generic code is written with the future\n// addition of 128-bit targets in mind.)\n// Note that Rust (and C99) pointers must be at least 16-bit (i.e., 8-bit targets are impossible): https://github.com/rust-lang/rust/pull/49305\n#[cfg(not(any(\n    target_pointer_width = \"16\",\n    target_pointer_width = \"32\",\n    target_pointer_width = \"64\",\n)))]\ncompile_error!(\n    \"portable-atomic currently only supports targets with {16,32,64}-bit pointer width; \\\n     if you need support for others, \\\n     please submit an issue at <https://github.com/taiki-e/portable-atomic>\"\n);\n\n// Reject unsupported architectures.\n#[cfg(portable_atomic_unsafe_assume_single_core)]\n#[cfg(not(any(\n    target_arch = \"arm\",\n    target_arch = \"avr\",\n    target_arch = \"msp430\",\n    target_arch = \"riscv32\",\n    target_arch = \"riscv64\",\n    target_arch = \"xtensa\",\n)))]\ncompile_error!(\n    \"`portable_atomic_unsafe_assume_single_core` cfg (`unsafe-assume-single-core` feature) \\\n     is not supported yet on this architecture;\\n\\\n     if you need unsafe-assume-{single-core,privileged} support for this target,\\n\\\n     please submit an issue at <https://github.com/taiki-e/portable-atomic/issues/new>\"\n);\n// unsafe-assume-single-core is accepted on AVR/MSP430, but\n// unsafe-assume-privileged on them is really useless on them since they are\n// always single-core, so rejected here.\n#[cfg(portable_atomic_unsafe_assume_privileged)]\n#[cfg(not(any(\n    target_arch = \"arm\",\n    target_arch = \"riscv32\",\n    target_arch = \"riscv64\",\n    target_arch = \"xtensa\",\n)))]\ncompile_error!(\n    \"`portable_atomic_unsafe_assume_privileged` cfg (`unsafe-assume-privileged` feature) \\\n     is not supported yet on this architecture;\\n\\\n     if you need unsafe-assume-{single-core,privileged} support for this target,\\n\\\n     please submit an issue at <https://github.com/taiki-e/portable-atomic/issues/new>\"\n);\n// unsafe-assume-privileged requires CAS.\n#[cfg(portable_atomic_unsafe_assume_privileged)]\ncfg_no_atomic_cas! {\n    compile_error!(\n        \"`portable_atomic_unsafe_assume_privileged` cfg (`unsafe-assume-privileged` feature) \\\n        requires atomic CAS\"\n    );\n}\n// Reject targets where privileged instructions are obviously unavailable.\n// TODO: Some embedded OSes should probably be accepted here.\n#[cfg(any(portable_atomic_unsafe_assume_single_core, portable_atomic_unsafe_assume_privileged))]\n#[cfg(any(\n    target_arch = \"arm\",\n    target_arch = \"avr\",\n    target_arch = \"msp430\",\n    target_arch = \"riscv32\",\n    target_arch = \"riscv64\",\n    target_arch = \"xtensa\",\n))]\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(all(not(portable_atomic_no_atomic_cas), not(target_os = \"none\")))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(all(target_has_atomic = \"ptr\", not(target_os = \"none\")))\n)]\ncompile_error!(\n    \"`portable_atomic_unsafe_assume_{single_core,privileged}` cfg (`unsafe-assume-{single-core,privileged}` feature) \\\n     is not compatible with target where privileged instructions are obviously unavailable;\\n\\\n     if you need unsafe-assume-{single-core,privileged} support for this target,\\n\\\n     please submit an issue at <https://github.com/taiki-e/portable-atomic/issues/new>\\n\\\n     see also <https://github.com/taiki-e/portable-atomic/issues/148> for troubleshooting\"\n);\n\n#[cfg(portable_atomic_outline_atomics)]\n#[cfg(not(any(\n    target_arch = \"aarch64\",\n    target_arch = \"powerpc64\",\n    target_arch = \"riscv32\",\n    target_arch = \"riscv64\",\n)))]\ncompile_error!(\"`portable_atomic_outline_atomics` cfg does not compatible with this target\");\n\n#[cfg(portable_atomic_disable_fiq)]\n#[cfg(not(all(\n    target_arch = \"arm\",\n    not(any(target_feature = \"mclass\", portable_atomic_target_feature = \"mclass\")),\n)))]\ncompile_error!(\n    \"`portable_atomic_disable_fiq` cfg (`disable-fiq` feature) is only available on Arm (except for M-Profile architectures)\"\n);\n#[cfg(portable_atomic_s_mode)]\n#[cfg(not(any(target_arch = \"riscv32\", target_arch = \"riscv64\")))]\ncompile_error!(\"`portable_atomic_s_mode` cfg (`s-mode` feature) is only available on RISC-V\");\n#[cfg(portable_atomic_force_amo)]\n#[cfg(not(any(target_arch = \"riscv32\", target_arch = \"riscv64\")))]\ncompile_error!(\"`portable_atomic_force_amo` cfg (`force-amo` feature) is only available on RISC-V\");\n\n#[cfg(portable_atomic_disable_fiq)]\n#[cfg(not(any(\n    portable_atomic_unsafe_assume_single_core,\n    portable_atomic_unsafe_assume_privileged,\n)))]\ncompile_error!(\n    \"`portable_atomic_disable_fiq` cfg (`disable-fiq` feature) may only be used together with `portable_atomic_unsafe_assume_{single_core,privileged}` cfg (`unsafe-assume-{single-core,privileged}` feature)\"\n);\n#[cfg(portable_atomic_s_mode)]\n#[cfg(not(any(\n    portable_atomic_unsafe_assume_single_core,\n    portable_atomic_unsafe_assume_privileged,\n)))]\ncompile_error!(\n    \"`portable_atomic_s_mode` cfg (`s-mode` feature) may only be used together with `portable_atomic_unsafe_assume_{single_core,privileged}` cfg (`unsafe-assume-{single-core,privileged}` feature)\"\n);\n#[cfg(portable_atomic_force_amo)]\n#[cfg(not(portable_atomic_unsafe_assume_single_core))]\ncompile_error!(\n    \"`portable_atomic_force_amo` cfg (`force-amo` feature) may only be used together with `portable_atomic_unsafe_assume_single_core` cfg (`unsafe-assume-single-core` feature)\"\n);\n#[cfg(portable_atomic_unsafe_assume_privileged)]\n#[cfg(not(feature = \"fallback\"))]\ncompile_error!(\n    \"`portable_atomic_unsafe_assume_privileged` cfg (`unsafe-assume-privileged` feature) may only be used together with `fallback` feature\"\n);\n\n#[cfg(all(\n    any(portable_atomic_unsafe_assume_single_core, portable_atomic_unsafe_assume_privileged),\n    feature = \"critical-section\"\n))]\ncompile_error!(\n    \"you may not enable `critical-section` feature and `portable_atomic_unsafe_assume_{single_core,privileged}` cfg (`unsafe-assume-{single-core,privileged}` feature) at the same time\"\n);\n\n#[cfg(feature = \"require-cas\")]\n#[cfg_attr(\n    portable_atomic_no_cfg_target_has_atomic,\n    cfg(not(any(\n        not(portable_atomic_no_atomic_cas),\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    )))\n)]\n#[cfg_attr(\n    not(portable_atomic_no_cfg_target_has_atomic),\n    cfg(not(any(\n        target_has_atomic = \"ptr\",\n        target_arch = \"avr\",\n        target_arch = \"msp430\",\n        feature = \"critical-section\",\n        portable_atomic_unsafe_assume_single_core,\n    )))\n)]\ncompile_error!(\n    \"dependents require atomic CAS but not available on this target by default;\\n\\\n    consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg).\\n\\\n    see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n);\n\n#[macro_use]\nmod utils;\n\n#[cfg(test)]\n#[macro_use]\nmod tests;\n\n#[doc(no_inline)]\npub use core::sync::atomic::Ordering;\n\ncfg_sel!({\n    // LLVM doesn't support fence/compiler_fence for MSP430.\n    #[cfg(target_arch = \"msp430\")]\n    {\n        pub use self::imp::msp430::compiler_fence;\n    }\n    #[cfg(else)]\n    {\n        pub use core::sync::atomic::compiler_fence;\n    }\n});\ncfg_sel!({\n    // LLVM doesn't support fence/compiler_fence for MSP430.\n    #[cfg(target_arch = \"msp430\")]\n    {\n        pub use self::imp::msp430::fence;\n    }\n    // We have optimized fence for x86.\n    // Miri and Sanitizer do not support inline assembly.\n    #[cfg(all(\n        not(doc),\n        any(target_arch = \"x86\", target_arch = \"x86_64\"),\n        not(any(miri, portable_atomic_sanitize_thread)),\n        any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n    ))]\n    {\n        pub use self::imp::x86::fence;\n    }\n    // We have optimized fence for pre-v6 ARM Linux/Android.\n    // Miri and Sanitizer do not go through __sync_synchronize.\n    #[cfg(all(\n        not(doc),\n        target_arch = \"arm\",\n        not(any(miri, portable_atomic_sanitize_thread)),\n        any(target_os = \"linux\", target_os = \"android\"),\n        not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n    ))]\n    {\n        pub use self::imp::arm_linux::fence;\n    }\n    #[cfg(else)]\n    {\n        pub use core::sync::atomic::fence;\n    }\n});\n\nmod imp;\n\npub mod hint {\n    //! Re-export of the [`core::hint`] module.\n    //!\n    //! The only difference from the [`core::hint`] module is that [`spin_loop`]\n    //! is available in all rust versions that this crate supports.\n    //!\n    //! ```\n    //! use portable_atomic::hint;\n    //!\n    //! hint::spin_loop();\n    //! ```\n\n    #[doc(no_inline)]\n    pub use core::hint::*;\n\n    /// Emits a machine instruction to signal the processor that it is running in\n    /// a busy-wait spin-loop (\"spin lock\").\n    ///\n    /// Upon receiving the spin-loop signal the processor can optimize its behavior by,\n    /// for example, saving power or switching hyper-threads.\n    ///\n    /// This function is different from [`thread::yield_now`] which directly\n    /// yields to the system's scheduler, whereas `spin_loop` does not interact\n    /// with the operating system.\n    ///\n    /// A common use case for `spin_loop` is implementing bounded optimistic\n    /// spinning in a CAS loop in synchronization primitives. To avoid problems\n    /// like priority inversion, it is strongly recommended that the spin loop is\n    /// terminated after a finite amount of iterations and an appropriate blocking\n    /// syscall is made.\n    ///\n    /// **Note:** On platforms that do not support receiving spin-loop hints this\n    /// function does not do anything at all.\n    ///\n    /// [`thread::yield_now`]: https://doc.rust-lang.org/std/thread/fn.yield_now.html\n    #[inline]\n    pub fn spin_loop() {\n        #[allow(deprecated)]\n        core::sync::atomic::spin_loop_hint();\n    }\n}\n\n#[cfg(doc)]\nuse core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release, SeqCst};\nuse core::{fmt, ptr};\n\ncfg_has_atomic_8! {\n/// A boolean type which can be safely shared between threads.\n///\n/// This type has the same in-memory representation as a [`bool`].\n///\n/// If the compiler and the platform support atomic loads and stores of `u8`,\n/// this type is a wrapper for the standard library's\n/// [`AtomicBool`](core::sync::atomic::AtomicBool). If the platform supports it\n/// but the compiler does not, atomic operations are implemented using inline\n/// assembly.\n#[repr(C, align(1))]\npub struct AtomicBool {\n    v: core::cell::UnsafeCell<u8>,\n}\n\nimpl Default for AtomicBool {\n    /// Creates an `AtomicBool` initialized to `false`.\n    #[inline]\n    fn default() -> Self {\n        Self::new(false)\n    }\n}\n\nimpl From<bool> for AtomicBool {\n    /// Converts a `bool` into an `AtomicBool`.\n    #[inline]\n    fn from(b: bool) -> Self {\n        Self::new(b)\n    }\n}\n\n// Send is implicitly implemented.\n// SAFETY: any data races are prevented by disabling interrupts or\n// atomic intrinsics (see module-level comments).\nunsafe impl Sync for AtomicBool {}\n\n// UnwindSafe is implicitly implemented.\n#[cfg(not(portable_atomic_no_core_unwind_safe))]\nimpl core::panic::RefUnwindSafe for AtomicBool {}\n#[cfg(all(portable_atomic_no_core_unwind_safe, feature = \"std\"))]\nimpl std::panic::RefUnwindSafe for AtomicBool {}\n\nimpl_debug_and_serde!(AtomicBool);\n\nimpl AtomicBool {\n    /// Creates a new `AtomicBool`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::AtomicBool;\n    ///\n    /// let atomic_true = AtomicBool::new(true);\n    /// let atomic_false = AtomicBool::new(false);\n    /// ```\n    #[inline]\n    #[must_use]\n    pub const fn new(v: bool) -> Self {\n        static_assert_layout!(AtomicBool, bool);\n        Self { v: core::cell::UnsafeCell::new(v as u8) }\n    }\n\n    // TODO: update docs based on https://github.com/rust-lang/rust/pull/116762\n    const_fn! {\n        const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))];\n        /// Creates a new `AtomicBool` from a pointer.\n        ///\n        /// This is `const fn` on Rust 1.58+.\n        ///\n        /// # Safety\n        ///\n        /// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that on some platforms this can\n        ///   be bigger than `align_of::<bool>()`).\n        /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.\n        /// * If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value\n        ///   behind `ptr` must have a happens-before relationship with atomic accesses via the returned\n        ///   value (or vice-versa).\n        ///   * In other words, time periods where the value is accessed atomically may not overlap\n        ///     with periods where the value is accessed non-atomically.\n        ///   * This requirement is trivially satisfied if `ptr` is never used non-atomically for the\n        ///     duration of lifetime `'a`. Most use cases should be able to follow this guideline.\n        ///   * This requirement is also trivially satisfied if all accesses (atomic or not) are done\n        ///     from the same thread.\n        /// * If this atomic type is *not* lock-free:\n        ///   * Any accesses to the value behind `ptr` must have a happens-before relationship\n        ///     with accesses via the returned value (or vice-versa).\n        ///   * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must\n        ///     be compatible with operations performed by this atomic type.\n        /// * This method must not be used to create overlapping or mixed-size atomic accesses, as\n        ///   these are not supported by the memory model.\n        ///\n        /// [valid]: core::ptr#safety\n        #[inline]\n        #[must_use]\n        pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a Self {\n            #[allow(clippy::cast_ptr_alignment)]\n            // SAFETY: guaranteed by the caller\n            unsafe { &*(ptr as *mut Self as *const Self) }\n        }\n    }\n\n    /// Returns `true` if operations on values of this type are lock-free.\n    ///\n    /// If the compiler or the platform doesn't support the necessary\n    /// atomic instructions, global locks for every potentially\n    /// concurrent atomic operation will be used.\n    ///\n    /// This function is guaranteed to always return the same result.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::AtomicBool;\n    ///\n    /// let is_lock_free = AtomicBool::is_lock_free();\n    /// ```\n    #[inline]\n    #[must_use]\n    pub fn is_lock_free() -> bool {\n        imp::AtomicU8::is_lock_free()\n    }\n\n    /// Returns `true` if operations on values of this type are lock-free.\n    ///\n    /// If the compiler or the platform doesn't support the necessary\n    /// atomic instructions, global locks for every potentially\n    /// concurrent atomic operation will be used.\n    ///\n    /// **Note:** If the atomic operation relies on dynamic CPU feature detection,\n    /// this type may be lock-free even if the function returns false.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::AtomicBool;\n    ///\n    /// const IS_ALWAYS_LOCK_FREE: bool = AtomicBool::is_always_lock_free();\n    /// ```\n    #[inline]\n    #[must_use]\n    pub const fn is_always_lock_free() -> bool {\n        imp::AtomicU8::IS_ALWAYS_LOCK_FREE\n    }\n    #[cfg(test)]\n    const IS_ALWAYS_LOCK_FREE: bool = Self::is_always_lock_free();\n\n    const_fn! {\n        const_if: #[cfg(not(portable_atomic_no_const_mut_refs))];\n        /// Returns a mutable reference to the underlying [`bool`].\n        ///\n        /// This is safe because the mutable reference guarantees that no other threads are\n        /// concurrently accessing the atomic data.\n        ///\n        /// This is `const fn` on Rust 1.83+.\n        ///\n        /// # Examples\n        ///\n        /// ```\n        /// use portable_atomic::{AtomicBool, Ordering};\n        ///\n        /// let mut some_bool = AtomicBool::new(true);\n        /// assert_eq!(*some_bool.get_mut(), true);\n        /// *some_bool.get_mut() = false;\n        /// assert_eq!(some_bool.load(Ordering::SeqCst), false);\n        /// ```\n        #[inline]\n        pub const fn get_mut(&mut self) -> &mut bool {\n            // SAFETY: the mutable reference guarantees unique ownership.\n            unsafe { &mut *self.as_ptr() }\n        }\n    }\n\n    // TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types.\n    // https://github.com/rust-lang/rust/issues/76314\n\n    const_fn! {\n        const_if: #[cfg(not(portable_atomic_no_const_transmute))];\n        /// Consumes the atomic and returns the contained value.\n        ///\n        /// This is safe because passing `self` by value guarantees that no other threads are\n        /// concurrently accessing the atomic data.\n        ///\n        /// This is `const fn` on Rust 1.56+.\n        ///\n        /// # Examples\n        ///\n        /// ```\n        /// use portable_atomic::AtomicBool;\n        ///\n        /// let some_bool = AtomicBool::new(true);\n        /// assert_eq!(some_bool.into_inner(), true);\n        /// ```\n        #[inline]\n        pub const fn into_inner(self) -> bool {\n            // SAFETY: AtomicBool and u8 have the same size and in-memory representations,\n            // so they can be safely transmuted.\n            // (const UnsafeCell::into_inner is unstable)\n            unsafe { core::mem::transmute::<AtomicBool, u8>(self) != 0 }\n        }\n    }\n\n    /// Loads a value from the bool.\n    ///\n    /// `load` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].\n    ///\n    /// # Panics\n    ///\n    /// Panics if `order` is [`Release`] or [`AcqRel`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let some_bool = AtomicBool::new(true);\n    ///\n    /// assert_eq!(some_bool.load(Ordering::Relaxed), true);\n    /// ```\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub fn load(&self, order: Ordering) -> bool {\n        self.as_atomic_u8().load(order) != 0\n    }\n\n    /// Stores a value into the bool.\n    ///\n    /// `store` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].\n    ///\n    /// # Panics\n    ///\n    /// Panics if `order` is [`Acquire`] or [`AcqRel`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let some_bool = AtomicBool::new(true);\n    ///\n    /// some_bool.store(false, Ordering::Relaxed);\n    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);\n    /// ```\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub fn store(&self, val: bool, order: Ordering) {\n        self.as_atomic_u8().store(val as u8, order);\n    }\n\n    cfg_has_atomic_cas_or_amo32! {\n    /// Stores a value into the bool, returning the previous value.\n    ///\n    /// `swap` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let some_bool = AtomicBool::new(true);\n    ///\n    /// assert_eq!(some_bool.swap(false, Ordering::Relaxed), true);\n    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn swap(&self, val: bool, order: Ordering) -> bool {\n        #[cfg(any(\n            target_arch = \"riscv32\",\n            target_arch = \"riscv64\",\n            target_arch = \"loongarch32\",\n            target_arch = \"loongarch64\",\n        ))]\n        {\n            // See https://github.com/rust-lang/rust/pull/114034 for details.\n            // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L249\n            // https://godbolt.org/z/ofbGGdx44\n            if val { self.fetch_or(true, order) } else { self.fetch_and(false, order) }\n        }\n        #[cfg(not(any(\n            target_arch = \"riscv32\",\n            target_arch = \"riscv64\",\n            target_arch = \"loongarch32\",\n            target_arch = \"loongarch64\",\n        )))]\n        {\n            self.as_atomic_u8().swap(val as u8, order) != 0\n        }\n    }\n\n    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.\n    ///\n    /// The return value is a result indicating whether the new value was written and containing\n    /// the previous value. On success this value is guaranteed to be equal to `current`.\n    ///\n    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory\n    /// ordering of this operation. `success` describes the required ordering for the\n    /// read-modify-write operation that takes place if the comparison with `current` succeeds.\n    /// `failure` describes the required ordering for the load operation that takes place when\n    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part\n    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load\n    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].\n    ///\n    /// # Panics\n    ///\n    /// Panics if `failure` is [`Release`], [`AcqRel`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let some_bool = AtomicBool::new(true);\n    ///\n    /// assert_eq!(\n    ///     some_bool.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed),\n    ///     Ok(true)\n    /// );\n    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);\n    ///\n    /// assert_eq!(\n    ///     some_bool.compare_exchange(true, true, Ordering::SeqCst, Ordering::Acquire),\n    ///     Err(false)\n    /// );\n    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);\n    /// ```\n    #[cfg_attr(docsrs, doc(alias = \"compare_and_swap\"))]\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub fn compare_exchange(\n        &self,\n        current: bool,\n        new: bool,\n        success: Ordering,\n        failure: Ordering,\n    ) -> Result<bool, bool> {\n        #[cfg(any(\n            target_arch = \"riscv32\",\n            target_arch = \"riscv64\",\n            target_arch = \"loongarch32\",\n            target_arch = \"loongarch64\",\n        ))]\n        {\n            // See https://github.com/rust-lang/rust/pull/114034 for details.\n            // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L249\n            // https://godbolt.org/z/ofbGGdx44\n            crate::utils::assert_compare_exchange_ordering(success, failure);\n            let order = crate::utils::upgrade_success_ordering(success, failure);\n            let old = if current == new {\n                // This is a no-op, but we still need to perform the operation\n                // for memory ordering reasons.\n                self.fetch_or(false, order)\n            } else {\n                // This sets the value to the new one and returns the old one.\n                self.swap(new, order)\n            };\n            if old == current { Ok(old) } else { Err(old) }\n        }\n        #[cfg(not(any(\n            target_arch = \"riscv32\",\n            target_arch = \"riscv64\",\n            target_arch = \"loongarch32\",\n            target_arch = \"loongarch64\",\n        )))]\n        {\n            match self.as_atomic_u8().compare_exchange(current as u8, new as u8, success, failure) {\n                Ok(x) => Ok(x != 0),\n                Err(x) => Err(x != 0),\n            }\n        }\n    }\n\n    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.\n    ///\n    /// Unlike [`AtomicBool::compare_exchange`], this function is allowed to spuriously fail even when the\n    /// comparison succeeds, which can result in more efficient code on some platforms. The\n    /// return value is a result indicating whether the new value was written and containing the\n    /// previous value.\n    ///\n    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory\n    /// ordering of this operation. `success` describes the required ordering for the\n    /// read-modify-write operation that takes place if the comparison with `current` succeeds.\n    /// `failure` describes the required ordering for the load operation that takes place when\n    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part\n    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load\n    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].\n    ///\n    /// # Panics\n    ///\n    /// Panics if `failure` is [`Release`], [`AcqRel`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let val = AtomicBool::new(false);\n    ///\n    /// let new = true;\n    /// let mut old = val.load(Ordering::Relaxed);\n    /// loop {\n    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {\n    ///         Ok(_) => break,\n    ///         Err(x) => old = x,\n    ///     }\n    /// }\n    /// ```\n    #[cfg_attr(docsrs, doc(alias = \"compare_and_swap\"))]\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub fn compare_exchange_weak(\n        &self,\n        current: bool,\n        new: bool,\n        success: Ordering,\n        failure: Ordering,\n    ) -> Result<bool, bool> {\n        #[cfg(any(\n            target_arch = \"riscv32\",\n            target_arch = \"riscv64\",\n            target_arch = \"loongarch32\",\n            target_arch = \"loongarch64\",\n        ))]\n        {\n            // See https://github.com/rust-lang/rust/pull/114034 for details.\n            // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L249\n            // https://godbolt.org/z/ofbGGdx44\n            self.compare_exchange(current, new, success, failure)\n        }\n        #[cfg(not(any(\n            target_arch = \"riscv32\",\n            target_arch = \"riscv64\",\n            target_arch = \"loongarch32\",\n            target_arch = \"loongarch64\",\n        )))]\n        {\n            match self\n                .as_atomic_u8()\n                .compare_exchange_weak(current as u8, new as u8, success, failure)\n            {\n                Ok(x) => Ok(x != 0),\n                Err(x) => Err(x != 0),\n            }\n        }\n    }\n\n    /// Logical \"and\" with a boolean value.\n    ///\n    /// Performs a logical \"and\" operation on the current value and the argument `val`, and sets\n    /// the new value to the result.\n    ///\n    /// Returns the previous value.\n    ///\n    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), true);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// assert_eq!(foo.fetch_and(true, Ordering::SeqCst), true);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    ///\n    /// let foo = AtomicBool::new(false);\n    /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), false);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {\n        self.as_atomic_u8().fetch_and(val as u8, order) != 0\n    }\n\n    /// Logical \"and\" with a boolean value.\n    ///\n    /// Performs a logical \"and\" operation on the current value and the argument `val`, and sets\n    /// the new value to the result.\n    ///\n    /// Unlike `fetch_and`, this does not return the previous value.\n    ///\n    /// `and` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// This function may generate more efficient code than `fetch_and` on some platforms.\n    ///\n    /// - x86/x86_64: `lock and` instead of `cmpxchg` loop\n    /// - MSP430: `and` instead of disabling interrupts\n    ///\n    /// Note: On x86/x86_64, the use of either function should not usually\n    /// affect the generated code, because LLVM can properly optimize the case\n    /// where the result is unused.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// foo.and(false, Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// foo.and(true, Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    ///\n    /// let foo = AtomicBool::new(false);\n    /// foo.and(false, Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn and(&self, val: bool, order: Ordering) {\n        self.as_atomic_u8().and(val as u8, order);\n    }\n\n    /// Logical \"nand\" with a boolean value.\n    ///\n    /// Performs a logical \"nand\" operation on the current value and the argument `val`, and sets\n    /// the new value to the result.\n    ///\n    /// Returns the previous value.\n    ///\n    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), true);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// assert_eq!(foo.fetch_nand(true, Ordering::SeqCst), true);\n    /// assert_eq!(foo.load(Ordering::SeqCst) as usize, 0);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    ///\n    /// let foo = AtomicBool::new(false);\n    /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), false);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {\n        // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L973-L985\n        if val {\n            // !(x & true) == !x\n            // We must invert the bool.\n            self.fetch_xor(true, order)\n        } else {\n            // !(x & false) == true\n            // We must set the bool to true.\n            self.swap(true, order)\n        }\n    }\n\n    /// Logical \"or\" with a boolean value.\n    ///\n    /// Performs a logical \"or\" operation on the current value and the argument `val`, and sets the\n    /// new value to the result.\n    ///\n    /// Returns the previous value.\n    ///\n    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), true);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    ///\n    /// let foo = AtomicBool::new(false);\n    /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), false);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {\n        self.as_atomic_u8().fetch_or(val as u8, order) != 0\n    }\n\n    /// Logical \"or\" with a boolean value.\n    ///\n    /// Performs a logical \"or\" operation on the current value and the argument `val`, and sets the\n    /// new value to the result.\n    ///\n    /// Unlike `fetch_or`, this does not return the previous value.\n    ///\n    /// `or` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// This function may generate more efficient code than `fetch_or` on some platforms.\n    ///\n    /// - x86/x86_64: `lock or` instead of `cmpxchg` loop\n    /// - MSP430: `bis` instead of disabling interrupts\n    ///\n    /// Note: On x86/x86_64, the use of either function should not usually\n    /// affect the generated code, because LLVM can properly optimize the case\n    /// where the result is unused.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// foo.or(false, Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// foo.or(true, Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    ///\n    /// let foo = AtomicBool::new(false);\n    /// foo.or(false, Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn or(&self, val: bool, order: Ordering) {\n        self.as_atomic_u8().or(val as u8, order);\n    }\n\n    /// Logical \"xor\" with a boolean value.\n    ///\n    /// Performs a logical \"xor\" operation on the current value and the argument `val`, and sets\n    /// the new value to the result.\n    ///\n    /// Returns the previous value.\n    ///\n    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), true);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// assert_eq!(foo.fetch_xor(true, Ordering::SeqCst), true);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    ///\n    /// let foo = AtomicBool::new(false);\n    /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), false);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {\n        self.as_atomic_u8().fetch_xor(val as u8, order) != 0\n    }\n\n    /// Logical \"xor\" with a boolean value.\n    ///\n    /// Performs a logical \"xor\" operation on the current value and the argument `val`, and sets\n    /// the new value to the result.\n    ///\n    /// Unlike `fetch_xor`, this does not return the previous value.\n    ///\n    /// `xor` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// This function may generate more efficient code than `fetch_xor` on some platforms.\n    ///\n    /// - x86/x86_64: `lock xor` instead of `cmpxchg` loop\n    /// - MSP430: `xor` instead of disabling interrupts\n    ///\n    /// Note: On x86/x86_64, the use of either function should not usually\n    /// affect the generated code, because LLVM can properly optimize the case\n    /// where the result is unused.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// foo.xor(false, Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// foo.xor(true, Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    ///\n    /// let foo = AtomicBool::new(false);\n    /// foo.xor(false, Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn xor(&self, val: bool, order: Ordering) {\n        self.as_atomic_u8().xor(val as u8, order);\n    }\n\n    /// Logical \"not\" with a boolean value.\n    ///\n    /// Performs a logical \"not\" operation on the current value, and sets\n    /// the new value to the result.\n    ///\n    /// Returns the previous value.\n    ///\n    /// `fetch_not` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// assert_eq!(foo.fetch_not(Ordering::SeqCst), true);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    ///\n    /// let foo = AtomicBool::new(false);\n    /// assert_eq!(foo.fetch_not(Ordering::SeqCst), false);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_not(&self, order: Ordering) -> bool {\n        self.fetch_xor(true, order)\n    }\n\n    /// Logical \"not\" with a boolean value.\n    ///\n    /// Performs a logical \"not\" operation on the current value, and sets\n    /// the new value to the result.\n    ///\n    /// Unlike `fetch_not`, this does not return the previous value.\n    ///\n    /// `not` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// This function may generate more efficient code than `fetch_not` on some platforms.\n    ///\n    /// - x86/x86_64: `lock xor` instead of `cmpxchg` loop\n    /// - MSP430: `xor` instead of disabling interrupts\n    ///\n    /// Note: On x86/x86_64, the use of either function should not usually\n    /// affect the generated code, because LLVM can properly optimize the case\n    /// where the result is unused.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let foo = AtomicBool::new(true);\n    /// foo.not(Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), false);\n    ///\n    /// let foo = AtomicBool::new(false);\n    /// foo.not(Ordering::SeqCst);\n    /// assert_eq!(foo.load(Ordering::SeqCst), true);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn not(&self, order: Ordering) {\n        self.xor(true, order);\n    }\n\n    /// Fetches the value, and applies a function to it that returns an optional\n    /// new value. Returns a `Result` of `Ok(previous_value)` if the function\n    /// returned `Some(_)`, else `Err(previous_value)`.\n    ///\n    /// Note: This may call the function multiple times if the value has been\n    /// changed from other threads in the meantime, as long as the function\n    /// returns `Some(_)`, but the function will have been applied only once to\n    /// the stored value.\n    ///\n    /// `fetch_update` takes two [`Ordering`] arguments to describe the memory\n    /// ordering of this operation. The first describes the required ordering for\n    /// when the operation finally succeeds while the second describes the\n    /// required ordering for loads. These correspond to the success and failure\n    /// orderings of [`compare_exchange`](Self::compare_exchange) respectively.\n    ///\n    /// Using [`Acquire`] as success ordering makes the store part of this\n    /// operation [`Relaxed`], and using [`Release`] makes the final successful\n    /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],\n    /// [`Acquire`] or [`Relaxed`].\n    ///\n    /// # Considerations\n    ///\n    /// This method is not magic; it is not provided by the hardware.\n    /// It is implemented in terms of [`compare_exchange_weak`](Self::compare_exchange_weak),\n    /// and suffers from the same drawbacks.\n    /// In particular, this method will not circumvent the [ABA Problem].\n    ///\n    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem\n    ///\n    /// # Panics\n    ///\n    /// Panics if `fetch_order` is [`Release`], [`AcqRel`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicBool, Ordering};\n    ///\n    /// let x = AtomicBool::new(false);\n    /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(false));\n    /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(false));\n    /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(true));\n    /// assert_eq!(x.load(Ordering::SeqCst), false);\n    /// ```\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub fn fetch_update<F>(\n        &self,\n        set_order: Ordering,\n        fetch_order: Ordering,\n        mut f: F,\n    ) -> Result<bool, bool>\n    where\n        F: FnMut(bool) -> Option<bool>,\n    {\n        let mut prev = self.load(fetch_order);\n        while let Some(next) = f(prev) {\n            match self.compare_exchange_weak(prev, next, set_order, fetch_order) {\n                x @ Ok(_) => return x,\n                Err(next_prev) => prev = next_prev,\n            }\n        }\n        Err(prev)\n    }\n    } // cfg_has_atomic_cas_or_amo32!\n\n    const_fn! {\n        // This function is actually `const fn`-compatible on Rust 1.32+,\n        // but makes `const fn` only on Rust 1.58+ to match other atomic types.\n        const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))];\n        /// Returns a mutable pointer to the underlying [`bool`].\n        ///\n        /// Returning an `*mut` pointer from a shared reference to this atomic is\n        /// safe because the atomic types work with interior mutability. Any use of\n        /// the returned raw pointer requires an `unsafe` block and has to uphold\n        /// the safety requirements. If there is concurrent access, note the following\n        /// additional safety requirements:\n        ///\n        /// - If this atomic type is [lock-free](Self::is_lock_free), any concurrent\n        ///   operations on it must be atomic.\n        /// - Otherwise, any concurrent operations on it must be compatible with\n        ///   operations performed by this atomic type.\n        ///\n        /// This is `const fn` on Rust 1.58+.\n        #[inline]\n        pub const fn as_ptr(&self) -> *mut bool {\n            self.v.get() as *mut bool\n        }\n    }\n\n    #[inline(always)]\n    fn as_atomic_u8(&self) -> &imp::AtomicU8 {\n        // SAFETY: AtomicBool and imp::AtomicU8 have the same layout,\n        // and both access data in the same way.\n        unsafe { &*(self as *const Self as *const imp::AtomicU8) }\n    }\n}\n// See https://github.com/taiki-e/portable-atomic/issues/180\n#[cfg(not(feature = \"require-cas\"))]\ncfg_no_atomic_cas! {\n#[doc(hidden)]\n#[allow(unused_variables, clippy::unused_self, clippy::extra_unused_lifetimes)]\nimpl<'a> AtomicBool {\n    cfg_no_atomic_cas_or_amo32! {\n    #[inline]\n    pub fn swap(&self, val: bool, order: Ordering) -> bool\n    where\n        &'a Self: HasSwap,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn compare_exchange(\n        &self,\n        current: bool,\n        new: bool,\n        success: Ordering,\n        failure: Ordering,\n    ) -> Result<bool, bool>\n    where\n        &'a Self: HasCompareExchange,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn compare_exchange_weak(\n        &self,\n        current: bool,\n        new: bool,\n        success: Ordering,\n        failure: Ordering,\n    ) -> Result<bool, bool>\n    where\n        &'a Self: HasCompareExchangeWeak,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_and(&self, val: bool, order: Ordering) -> bool\n    where\n        &'a Self: HasFetchAnd,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn and(&self, val: bool, order: Ordering)\n    where\n        &'a Self: HasAnd,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool\n    where\n        &'a Self: HasFetchNand,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_or(&self, val: bool, order: Ordering) -> bool\n    where\n        &'a Self: HasFetchOr,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn or(&self, val: bool, order: Ordering)\n    where\n        &'a Self: HasOr,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool\n    where\n        &'a Self: HasFetchXor,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn xor(&self, val: bool, order: Ordering)\n    where\n        &'a Self: HasXor,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_not(&self, order: Ordering) -> bool\n    where\n        &'a Self: HasFetchNot,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn not(&self, order: Ordering)\n    where\n        &'a Self: HasNot,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_update<F>(\n        &self,\n        set_order: Ordering,\n        fetch_order: Ordering,\n        f: F,\n    ) -> Result<bool, bool>\n    where\n        F: FnMut(bool) -> Option<bool>,\n        &'a Self: HasFetchUpdate,\n    {\n        unimplemented!()\n    }\n    } // cfg_no_atomic_cas_or_amo32!\n}\n} // cfg_no_atomic_cas!\n} // cfg_has_atomic_8!\n\ncfg_has_atomic_ptr! {\n/// A raw pointer type which can be safely shared between threads.\n///\n/// This type has the same in-memory representation as a `*mut T`.\n///\n/// If the compiler and the platform support atomic loads and stores of pointers,\n/// this type is a wrapper for the standard library's\n/// [`AtomicPtr`](core::sync::atomic::AtomicPtr). If the platform supports it\n/// but the compiler does not, atomic operations are implemented using inline\n/// assembly.\n// We can use #[repr(transparent)] here, but #[repr(C, align(N))]\n// will show clearer docs.\n#[cfg_attr(target_pointer_width = \"16\", repr(C, align(2)))]\n#[cfg_attr(target_pointer_width = \"32\", repr(C, align(4)))]\n#[cfg_attr(target_pointer_width = \"64\", repr(C, align(8)))]\n#[cfg_attr(target_pointer_width = \"128\", repr(C, align(16)))]\npub struct AtomicPtr<T> {\n    inner: imp::AtomicPtr<T>,\n}\n\nimpl<T> Default for AtomicPtr<T> {\n    /// Creates a null `AtomicPtr<T>`.\n    #[inline]\n    fn default() -> Self {\n        Self::new(ptr::null_mut())\n    }\n}\n\nimpl<T> From<*mut T> for AtomicPtr<T> {\n    #[inline]\n    fn from(p: *mut T) -> Self {\n        Self::new(p)\n    }\n}\n\nimpl<T> fmt::Debug for AtomicPtr<T> {\n    #[inline] // fmt is not hot path, but #[inline] on fmt seems to still be useful: https://github.com/rust-lang/rust/pull/117727\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        // std atomic types use Relaxed in Debug::fmt: https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L2188\n        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)\n    }\n}\n\nimpl<T> fmt::Pointer for AtomicPtr<T> {\n    #[inline] // fmt is not hot path, but #[inline] on fmt seems to still be useful: https://github.com/rust-lang/rust/pull/117727\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        // std atomic types use Relaxed in Debug::fmt: https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L2188\n        fmt::Pointer::fmt(&self.load(Ordering::Relaxed), f)\n    }\n}\n\n// UnwindSafe is implicitly implemented.\n#[cfg(not(portable_atomic_no_core_unwind_safe))]\nimpl<T> core::panic::RefUnwindSafe for AtomicPtr<T> {}\n#[cfg(all(portable_atomic_no_core_unwind_safe, feature = \"std\"))]\nimpl<T> std::panic::RefUnwindSafe for AtomicPtr<T> {}\n\nimpl<T> AtomicPtr<T> {\n    /// Creates a new `AtomicPtr`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::AtomicPtr;\n    ///\n    /// let ptr = &mut 5;\n    /// let atomic_ptr = AtomicPtr::new(ptr);\n    /// ```\n    #[inline]\n    #[must_use]\n    pub const fn new(p: *mut T) -> Self {\n        static_assert_layout!(AtomicPtr<()>, *mut ());\n        Self { inner: imp::AtomicPtr::new(p) }\n    }\n\n    // TODO: update docs based on https://github.com/rust-lang/rust/pull/116762\n    const_fn! {\n        const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))];\n        /// Creates a new `AtomicPtr` from a pointer.\n        ///\n        /// This is `const fn` on Rust 1.58+.\n        ///\n        /// # Safety\n        ///\n        /// * `ptr` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this\n        ///   can be bigger than `align_of::<*mut T>()`).\n        /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.\n        /// * If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value\n        ///   behind `ptr` must have a happens-before relationship with atomic accesses via the returned\n        ///   value (or vice-versa).\n        ///   * In other words, time periods where the value is accessed atomically may not overlap\n        ///     with periods where the value is accessed non-atomically.\n        ///   * This requirement is trivially satisfied if `ptr` is never used non-atomically for the\n        ///     duration of lifetime `'a`. Most use cases should be able to follow this guideline.\n        ///   * This requirement is also trivially satisfied if all accesses (atomic or not) are done\n        ///     from the same thread.\n        /// * If this atomic type is *not* lock-free:\n        ///   * Any accesses to the value behind `ptr` must have a happens-before relationship\n        ///     with accesses via the returned value (or vice-versa).\n        ///   * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must\n        ///     be compatible with operations performed by this atomic type.\n        /// * This method must not be used to create overlapping or mixed-size atomic accesses, as\n        ///   these are not supported by the memory model.\n        ///\n        /// [valid]: core::ptr#safety\n        #[inline]\n        #[must_use]\n        pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a Self {\n            #[allow(clippy::cast_ptr_alignment)]\n            // SAFETY: guaranteed by the caller\n            unsafe { &*(ptr as *mut Self as *const Self) }\n        }\n    }\n\n    /// Returns `true` if operations on values of this type are lock-free.\n    ///\n    /// If the compiler or the platform doesn't support the necessary\n    /// atomic instructions, global locks for every potentially\n    /// concurrent atomic operation will be used.\n    ///\n    /// This function is guaranteed to always return the same result.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::AtomicPtr;\n    ///\n    /// let is_lock_free = AtomicPtr::<()>::is_lock_free();\n    /// ```\n    #[inline]\n    #[must_use]\n    pub fn is_lock_free() -> bool {\n        <imp::AtomicPtr<T>>::is_lock_free()\n    }\n\n    /// Returns `true` if operations on values of this type are lock-free.\n    ///\n    /// If the compiler or the platform doesn't support the necessary\n    /// atomic instructions, global locks for every potentially\n    /// concurrent atomic operation will be used.\n    ///\n    /// **Note:** If the atomic operation relies on dynamic CPU feature detection,\n    /// this type may be lock-free even if the function returns false.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::AtomicPtr;\n    ///\n    /// const IS_ALWAYS_LOCK_FREE: bool = AtomicPtr::<()>::is_always_lock_free();\n    /// ```\n    #[inline]\n    #[must_use]\n    pub const fn is_always_lock_free() -> bool {\n        <imp::AtomicPtr<T>>::IS_ALWAYS_LOCK_FREE\n    }\n    #[cfg(test)]\n    const IS_ALWAYS_LOCK_FREE: bool = Self::is_always_lock_free();\n\n    const_fn! {\n        const_if: #[cfg(not(portable_atomic_no_const_mut_refs))];\n        /// Returns a mutable reference to the underlying pointer.\n        ///\n        /// This is safe because the mutable reference guarantees that no other threads are\n        /// concurrently accessing the atomic data.\n        ///\n        /// This is `const fn` on Rust 1.83+.\n        ///\n        /// # Examples\n        ///\n        /// ```\n        /// use portable_atomic::{AtomicPtr, Ordering};\n        ///\n        /// let mut data = 10;\n        /// let mut atomic_ptr = AtomicPtr::new(&mut data);\n        /// let mut other_data = 5;\n        /// *atomic_ptr.get_mut() = &mut other_data;\n        /// assert_eq!(unsafe { *atomic_ptr.load(Ordering::SeqCst) }, 5);\n        /// ```\n        #[inline]\n        pub const fn get_mut(&mut self) -> &mut *mut T {\n            // SAFETY: the mutable reference guarantees unique ownership.\n            // (core::sync::atomic::Atomic*::get_mut is not const yet)\n            unsafe { &mut *self.as_ptr() }\n        }\n    }\n\n    // TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types.\n    // https://github.com/rust-lang/rust/issues/76314\n\n    const_fn! {\n        const_if: #[cfg(not(portable_atomic_no_const_transmute))];\n        /// Consumes the atomic and returns the contained value.\n        ///\n        /// This is safe because passing `self` by value guarantees that no other threads are\n        /// concurrently accessing the atomic data.\n        ///\n        /// This is `const fn` on Rust 1.56+.\n        ///\n        /// # Examples\n        ///\n        /// ```\n        /// use portable_atomic::AtomicPtr;\n        ///\n        /// let mut data = 5;\n        /// let atomic_ptr = AtomicPtr::new(&mut data);\n        /// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);\n        /// ```\n        #[inline]\n        pub const fn into_inner(self) -> *mut T {\n            // SAFETY: AtomicPtr<T> and *mut T have the same size and in-memory representations,\n            // so they can be safely transmuted.\n            // (const UnsafeCell::into_inner is unstable)\n            unsafe { core::mem::transmute(self) }\n        }\n    }\n\n    /// Loads a value from the pointer.\n    ///\n    /// `load` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].\n    ///\n    /// # Panics\n    ///\n    /// Panics if `order` is [`Release`] or [`AcqRel`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let ptr = &mut 5;\n    /// let some_ptr = AtomicPtr::new(ptr);\n    ///\n    /// let value = some_ptr.load(Ordering::Relaxed);\n    /// ```\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub fn load(&self, order: Ordering) -> *mut T {\n        self.inner.load(order)\n    }\n\n    /// Stores a value into the pointer.\n    ///\n    /// `store` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].\n    ///\n    /// # Panics\n    ///\n    /// Panics if `order` is [`Acquire`] or [`AcqRel`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let ptr = &mut 5;\n    /// let some_ptr = AtomicPtr::new(ptr);\n    ///\n    /// let other_ptr = &mut 10;\n    ///\n    /// some_ptr.store(other_ptr, Ordering::Relaxed);\n    /// ```\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub fn store(&self, ptr: *mut T, order: Ordering) {\n        self.inner.store(ptr, order);\n    }\n\n    cfg_has_atomic_cas_or_amo32! {\n    /// Stores a value into the pointer, returning the previous value.\n    ///\n    /// `swap` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let ptr = &mut 5;\n    /// let some_ptr = AtomicPtr::new(ptr);\n    ///\n    /// let other_ptr = &mut 10;\n    ///\n    /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {\n        self.inner.swap(ptr, order)\n    }\n\n    cfg_has_atomic_cas! {\n    /// Stores a value into the pointer if the current value is the same as the `current` value.\n    ///\n    /// The return value is a result indicating whether the new value was written and containing\n    /// the previous value. On success this value is guaranteed to be equal to `current`.\n    ///\n    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory\n    /// ordering of this operation. `success` describes the required ordering for the\n    /// read-modify-write operation that takes place if the comparison with `current` succeeds.\n    /// `failure` describes the required ordering for the load operation that takes place when\n    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part\n    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load\n    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].\n    ///\n    /// # Panics\n    ///\n    /// Panics if `failure` is [`Release`], [`AcqRel`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let ptr = &mut 5;\n    /// let some_ptr = AtomicPtr::new(ptr);\n    ///\n    /// let other_ptr = &mut 10;\n    ///\n    /// let value = some_ptr.compare_exchange(ptr, other_ptr, Ordering::SeqCst, Ordering::Relaxed);\n    /// ```\n    #[cfg_attr(docsrs, doc(alias = \"compare_and_swap\"))]\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub fn compare_exchange(\n        &self,\n        current: *mut T,\n        new: *mut T,\n        success: Ordering,\n        failure: Ordering,\n    ) -> Result<*mut T, *mut T> {\n        self.inner.compare_exchange(current, new, success, failure)\n    }\n\n    /// Stores a value into the pointer if the current value is the same as the `current` value.\n    ///\n    /// Unlike [`AtomicPtr::compare_exchange`], this function is allowed to spuriously fail even when the\n    /// comparison succeeds, which can result in more efficient code on some platforms. The\n    /// return value is a result indicating whether the new value was written and containing the\n    /// previous value.\n    ///\n    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory\n    /// ordering of this operation. `success` describes the required ordering for the\n    /// read-modify-write operation that takes place if the comparison with `current` succeeds.\n    /// `failure` describes the required ordering for the load operation that takes place when\n    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part\n    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load\n    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].\n    ///\n    /// # Panics\n    ///\n    /// Panics if `failure` is [`Release`], [`AcqRel`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let some_ptr = AtomicPtr::new(&mut 5);\n    ///\n    /// let new = &mut 10;\n    /// let mut old = some_ptr.load(Ordering::Relaxed);\n    /// loop {\n    ///     match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {\n    ///         Ok(_) => break,\n    ///         Err(x) => old = x,\n    ///     }\n    /// }\n    /// ```\n    #[cfg_attr(docsrs, doc(alias = \"compare_and_swap\"))]\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub fn compare_exchange_weak(\n        &self,\n        current: *mut T,\n        new: *mut T,\n        success: Ordering,\n        failure: Ordering,\n    ) -> Result<*mut T, *mut T> {\n        self.inner.compare_exchange_weak(current, new, success, failure)\n    }\n\n    /// Fetches the value, and applies a function to it that returns an optional\n    /// new value. Returns a `Result` of `Ok(previous_value)` if the function\n    /// returned `Some(_)`, else `Err(previous_value)`.\n    ///\n    /// Note: This may call the function multiple times if the value has been\n    /// changed from other threads in the meantime, as long as the function\n    /// returns `Some(_)`, but the function will have been applied only once to\n    /// the stored value.\n    ///\n    /// `fetch_update` takes two [`Ordering`] arguments to describe the memory\n    /// ordering of this operation. The first describes the required ordering for\n    /// when the operation finally succeeds while the second describes the\n    /// required ordering for loads. These correspond to the success and failure\n    /// orderings of [`compare_exchange`](Self::compare_exchange) respectively.\n    ///\n    /// Using [`Acquire`] as success ordering makes the store part of this\n    /// operation [`Relaxed`], and using [`Release`] makes the final successful\n    /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],\n    /// [`Acquire`] or [`Relaxed`].\n    ///\n    /// # Panics\n    ///\n    /// Panics if `fetch_order` is [`Release`], [`AcqRel`].\n    ///\n    /// # Considerations\n    ///\n    /// This method is not magic; it is not provided by the hardware.\n    /// It is implemented in terms of [`compare_exchange_weak`](Self::compare_exchange_weak),\n    /// and suffers from the same drawbacks.\n    /// In particular, this method will not circumvent the [ABA Problem].\n    ///\n    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let ptr: *mut _ = &mut 5;\n    /// let some_ptr = AtomicPtr::new(ptr);\n    ///\n    /// let new: *mut _ = &mut 10;\n    /// assert_eq!(some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(ptr));\n    /// let result = some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {\n    ///     if x == ptr {\n    ///         Some(new)\n    ///     } else {\n    ///         None\n    ///     }\n    /// });\n    /// assert_eq!(result, Ok(ptr));\n    /// assert_eq!(some_ptr.load(Ordering::SeqCst), new);\n    /// ```\n    #[inline]\n    #[cfg_attr(\n        any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n        track_caller\n    )]\n    pub fn fetch_update<F>(\n        &self,\n        set_order: Ordering,\n        fetch_order: Ordering,\n        mut f: F,\n    ) -> Result<*mut T, *mut T>\n    where\n        F: FnMut(*mut T) -> Option<*mut T>,\n    {\n        let mut prev = self.load(fetch_order);\n        while let Some(next) = f(prev) {\n            match self.compare_exchange_weak(prev, next, set_order, fetch_order) {\n                x @ Ok(_) => return x,\n                Err(next_prev) => prev = next_prev,\n            }\n        }\n        Err(prev)\n    }\n    } // cfg_has_atomic_cas!\n\n    /// Offsets the pointer's address by adding `val` (in units of `T`),\n    /// returning the previous pointer.\n    ///\n    /// This is equivalent to using [`wrapping_add`] to atomically perform the\n    /// equivalent of `ptr = ptr.wrapping_add(val);`.\n    ///\n    /// This method operates in units of `T`, which means that it cannot be used\n    /// to offset the pointer by an amount which is not a multiple of\n    /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to\n    /// work with a deliberately misaligned pointer. In such cases, you may use\n    /// the [`fetch_byte_add`](Self::fetch_byte_add) method instead.\n    ///\n    /// `fetch_ptr_add` takes an [`Ordering`] argument which describes the\n    /// memory ordering of this operation. All ordering modes are possible. Note\n    /// that using [`Acquire`] makes the store part of this operation\n    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// [`wrapping_add`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_add\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unstable_name_collisions)]\n    /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());\n    /// assert_eq!(atom.fetch_ptr_add(1, Ordering::Relaxed).addr(), 0);\n    /// // Note: units of `size_of::<i64>()`.\n    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 8);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T {\n        self.fetch_byte_add(val.wrapping_mul(core::mem::size_of::<T>()), order)\n    }\n\n    /// Offsets the pointer's address by subtracting `val` (in units of `T`),\n    /// returning the previous pointer.\n    ///\n    /// This is equivalent to using [`wrapping_sub`] to atomically perform the\n    /// equivalent of `ptr = ptr.wrapping_sub(val);`.\n    ///\n    /// This method operates in units of `T`, which means that it cannot be used\n    /// to offset the pointer by an amount which is not a multiple of\n    /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to\n    /// work with a deliberately misaligned pointer. In such cases, you may use\n    /// the [`fetch_byte_sub`](Self::fetch_byte_sub) method instead.\n    ///\n    /// `fetch_ptr_sub` takes an [`Ordering`] argument which describes the memory\n    /// ordering of this operation. All ordering modes are possible. Note that\n    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],\n    /// and using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// [`wrapping_sub`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_sub\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let array = [1i32, 2i32];\n    /// let atom = AtomicPtr::new(array.as_ptr().wrapping_add(1) as *mut _);\n    ///\n    /// assert!(core::ptr::eq(atom.fetch_ptr_sub(1, Ordering::Relaxed), &array[1]));\n    /// assert!(core::ptr::eq(atom.load(Ordering::Relaxed), &array[0]));\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {\n        self.fetch_byte_sub(val.wrapping_mul(core::mem::size_of::<T>()), order)\n    }\n\n    /// Offsets the pointer's address by adding `val` *bytes*, returning the\n    /// previous pointer.\n    ///\n    /// This is equivalent to using [`wrapping_add`] and [`cast`] to atomically\n    /// perform `ptr = ptr.cast::<u8>().wrapping_add(val).cast::<T>()`.\n    ///\n    /// `fetch_byte_add` takes an [`Ordering`] argument which describes the\n    /// memory ordering of this operation. All ordering modes are possible. Note\n    /// that using [`Acquire`] makes the store part of this operation\n    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// [`wrapping_add`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_add\n    /// [`cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unstable_name_collisions)]\n    /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());\n    /// assert_eq!(atom.fetch_byte_add(1, Ordering::Relaxed).addr(), 0);\n    /// // Note: in units of bytes, not `size_of::<i64>()`.\n    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 1);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {\n        self.inner.fetch_byte_add(val, order)\n    }\n\n    /// Offsets the pointer's address by subtracting `val` *bytes*, returning the\n    /// previous pointer.\n    ///\n    /// This is equivalent to using [`wrapping_sub`] and [`cast`] to atomically\n    /// perform `ptr = ptr.cast::<u8>().wrapping_sub(val).cast::<T>()`.\n    ///\n    /// `fetch_byte_sub` takes an [`Ordering`] argument which describes the\n    /// memory ordering of this operation. All ordering modes are possible. Note\n    /// that using [`Acquire`] makes the store part of this operation\n    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// [`wrapping_sub`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_sub\n    /// [`cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unstable_name_collisions)]\n    /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let atom = AtomicPtr::<i64>::new(sptr::invalid_mut(1));\n    /// assert_eq!(atom.fetch_byte_sub(1, Ordering::Relaxed).addr(), 1);\n    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 0);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {\n        self.inner.fetch_byte_sub(val, order)\n    }\n\n    /// Performs a bitwise \"or\" operation on the address of the current pointer,\n    /// and the argument `val`, and stores a pointer with provenance of the\n    /// current pointer and the resulting address.\n    ///\n    /// This is equivalent to using [`map_addr`] to atomically perform\n    /// `ptr = ptr.map_addr(|a| a | val)`. This can be used in tagged\n    /// pointer schemes to atomically set tag bits.\n    ///\n    /// **Caveat**: This operation returns the previous value. To compute the\n    /// stored value without losing provenance, you may use [`map_addr`]. For\n    /// example: `a.fetch_or(val).map_addr(|a| a | val)`.\n    ///\n    /// `fetch_or` takes an [`Ordering`] argument which describes the memory\n    /// ordering of this operation. All ordering modes are possible. Note that\n    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],\n    /// and using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// This API and its claimed semantics are part of the Strict Provenance\n    /// experiment, see the [module documentation for `ptr`][core::ptr] for\n    /// details.\n    ///\n    /// [`map_addr`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.map_addr\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unstable_name_collisions)]\n    /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let pointer = &mut 3i64 as *mut i64;\n    ///\n    /// let atom = AtomicPtr::<i64>::new(pointer);\n    /// // Tag the bottom bit of the pointer.\n    /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 0);\n    /// // Extract and untag.\n    /// let tagged = atom.load(Ordering::Relaxed);\n    /// assert_eq!(tagged.addr() & 1, 1);\n    /// assert_eq!(tagged.map_addr(|p| p & !1), pointer);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {\n        self.inner.fetch_or(val, order)\n    }\n\n    /// Performs a bitwise \"and\" operation on the address of the current\n    /// pointer, and the argument `val`, and stores a pointer with provenance of\n    /// the current pointer and the resulting address.\n    ///\n    /// This is equivalent to using [`map_addr`] to atomically perform\n    /// `ptr = ptr.map_addr(|a| a & val)`. This can be used in tagged\n    /// pointer schemes to atomically unset tag bits.\n    ///\n    /// **Caveat**: This operation returns the previous value. To compute the\n    /// stored value without losing provenance, you may use [`map_addr`]. For\n    /// example: `a.fetch_and(val).map_addr(|a| a & val)`.\n    ///\n    /// `fetch_and` takes an [`Ordering`] argument which describes the memory\n    /// ordering of this operation. All ordering modes are possible. Note that\n    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],\n    /// and using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// This API and its claimed semantics are part of the Strict Provenance\n    /// experiment, see the [module documentation for `ptr`][core::ptr] for\n    /// details.\n    ///\n    /// [`map_addr`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.map_addr\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unstable_name_collisions)]\n    /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let pointer = &mut 3i64 as *mut i64;\n    /// // A tagged pointer\n    /// let atom = AtomicPtr::<i64>::new(pointer.map_addr(|a| a | 1));\n    /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 1);\n    /// // Untag, and extract the previously tagged pointer.\n    /// let untagged = atom.fetch_and(!1, Ordering::Relaxed).map_addr(|a| a & !1);\n    /// assert_eq!(untagged, pointer);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {\n        self.inner.fetch_and(val, order)\n    }\n\n    /// Performs a bitwise \"xor\" operation on the address of the current\n    /// pointer, and the argument `val`, and stores a pointer with provenance of\n    /// the current pointer and the resulting address.\n    ///\n    /// This is equivalent to using [`map_addr`] to atomically perform\n    /// `ptr = ptr.map_addr(|a| a ^ val)`. This can be used in tagged\n    /// pointer schemes to atomically toggle tag bits.\n    ///\n    /// **Caveat**: This operation returns the previous value. To compute the\n    /// stored value without losing provenance, you may use [`map_addr`]. For\n    /// example: `a.fetch_xor(val).map_addr(|a| a ^ val)`.\n    ///\n    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory\n    /// ordering of this operation. All ordering modes are possible. Note that\n    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],\n    /// and using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// This API and its claimed semantics are part of the Strict Provenance\n    /// experiment, see the [module documentation for `ptr`][core::ptr] for\n    /// details.\n    ///\n    /// [`map_addr`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.map_addr\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unstable_name_collisions)]\n    /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let pointer = &mut 3i64 as *mut i64;\n    /// let atom = AtomicPtr::<i64>::new(pointer);\n    ///\n    /// // Toggle a tag bit on the pointer.\n    /// atom.fetch_xor(1, Ordering::Relaxed);\n    /// assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {\n        self.inner.fetch_xor(val, order)\n    }\n\n    /// Sets the bit at the specified bit-position to 1.\n    ///\n    /// Returns `true` if the specified bit was previously set to 1.\n    ///\n    /// `bit_set` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// This corresponds to x86's `lock bts`, and the implementation calls them on x86/x86_64.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unstable_name_collisions)]\n    /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let pointer = &mut 3i64 as *mut i64;\n    ///\n    /// let atom = AtomicPtr::<i64>::new(pointer);\n    /// // Tag the bottom bit of the pointer.\n    /// assert!(!atom.bit_set(0, Ordering::Relaxed));\n    /// // Extract and untag.\n    /// let tagged = atom.load(Ordering::Relaxed);\n    /// assert_eq!(tagged.addr() & 1, 1);\n    /// assert_eq!(tagged.map_addr(|p| p & !1), pointer);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn bit_set(&self, bit: u32, order: Ordering) -> bool {\n        self.inner.bit_set(bit, order)\n    }\n\n    /// Clears the bit at the specified bit-position to 0.\n    ///\n    /// Returns `true` if the specified bit was previously set to 1.\n    ///\n    /// `bit_clear` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// This corresponds to x86's `lock btr`, and the implementation calls them on x86/x86_64.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unstable_name_collisions)]\n    /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let pointer = &mut 3i64 as *mut i64;\n    /// // A tagged pointer\n    /// let atom = AtomicPtr::<i64>::new(pointer.map_addr(|a| a | 1));\n    /// assert!(atom.bit_set(0, Ordering::Relaxed));\n    /// // Untag\n    /// assert!(atom.bit_clear(0, Ordering::Relaxed));\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn bit_clear(&self, bit: u32, order: Ordering) -> bool {\n        self.inner.bit_clear(bit, order)\n    }\n\n    /// Toggles the bit at the specified bit-position.\n    ///\n    /// Returns `true` if the specified bit was previously set to 1.\n    ///\n    /// `bit_toggle` takes an [`Ordering`] argument which describes the memory ordering\n    /// of this operation. All ordering modes are possible. Note that using\n    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n    /// using [`Release`] makes the load part [`Relaxed`].\n    ///\n    /// This corresponds to x86's `lock btc`, and the implementation calls them on x86/x86_64.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unstable_name_collisions)]\n    /// # #[allow(unused_imports)] use sptr::Strict as _; // strict provenance polyfill for old rustc\n    /// use portable_atomic::{AtomicPtr, Ordering};\n    ///\n    /// let pointer = &mut 3i64 as *mut i64;\n    /// let atom = AtomicPtr::<i64>::new(pointer);\n    ///\n    /// // Toggle a tag bit on the pointer.\n    /// atom.bit_toggle(0, Ordering::Relaxed);\n    /// assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1);\n    /// ```\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    pub fn bit_toggle(&self, bit: u32, order: Ordering) -> bool {\n        self.inner.bit_toggle(bit, order)\n    }\n    } // cfg_has_atomic_cas_or_amo32!\n\n    const_fn! {\n        const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))];\n        /// Returns a mutable pointer to the underlying pointer.\n        ///\n        /// Returning an `*mut` pointer from a shared reference to this atomic is\n        /// safe because the atomic types work with interior mutability. Any use of\n        /// the returned raw pointer requires an `unsafe` block and has to uphold\n        /// the safety requirements. If there is concurrent access, note the following\n        /// additional safety requirements:\n        ///\n        /// - If this atomic type is [lock-free](Self::is_lock_free), any concurrent\n        ///   operations on it must be atomic.\n        /// - Otherwise, any concurrent operations on it must be compatible with\n        ///   operations performed by this atomic type.\n        ///\n        /// This is `const fn` on Rust 1.58+.\n        #[inline]\n        pub const fn as_ptr(&self) -> *mut *mut T {\n            self.inner.as_ptr()\n        }\n    }\n}\n// See https://github.com/taiki-e/portable-atomic/issues/180\n#[cfg(not(feature = \"require-cas\"))]\ncfg_no_atomic_cas! {\n#[doc(hidden)]\n#[allow(unused_variables, clippy::unused_self, clippy::extra_unused_lifetimes)]\nimpl<'a, T: 'a> AtomicPtr<T> {\n    cfg_no_atomic_cas_or_amo32! {\n    #[inline]\n    pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T\n    where\n        &'a Self: HasSwap,\n    {\n        unimplemented!()\n    }\n    } // cfg_no_atomic_cas_or_amo32!\n    #[inline]\n    pub fn compare_exchange(\n        &self,\n        current: *mut T,\n        new: *mut T,\n        success: Ordering,\n        failure: Ordering,\n    ) -> Result<*mut T, *mut T>\n    where\n        &'a Self: HasCompareExchange,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn compare_exchange_weak(\n        &self,\n        current: *mut T,\n        new: *mut T,\n        success: Ordering,\n        failure: Ordering,\n    ) -> Result<*mut T, *mut T>\n    where\n        &'a Self: HasCompareExchangeWeak,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_update<F>(\n        &self,\n        set_order: Ordering,\n        fetch_order: Ordering,\n        f: F,\n    ) -> Result<*mut T, *mut T>\n    where\n        F: FnMut(*mut T) -> Option<*mut T>,\n        &'a Self: HasFetchUpdate,\n    {\n        unimplemented!()\n    }\n    cfg_no_atomic_cas_or_amo32! {\n    #[inline]\n    pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T\n    where\n        &'a Self: HasFetchPtrAdd,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T\n    where\n        &'a Self: HasFetchPtrSub,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T\n    where\n        &'a Self: HasFetchByteAdd,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T\n    where\n        &'a Self: HasFetchByteSub,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T\n    where\n        &'a Self: HasFetchOr,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T\n    where\n        &'a Self: HasFetchAnd,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T\n    where\n        &'a Self: HasFetchXor,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn bit_set(&self, bit: u32, order: Ordering) -> bool\n    where\n        &'a Self: HasBitSet,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn bit_clear(&self, bit: u32, order: Ordering) -> bool\n    where\n        &'a Self: HasBitClear,\n    {\n        unimplemented!()\n    }\n    #[inline]\n    pub fn bit_toggle(&self, bit: u32, order: Ordering) -> bool\n    where\n        &'a Self: HasBitToggle,\n    {\n        unimplemented!()\n    }\n    } // cfg_no_atomic_cas_or_amo32!\n}\n} // cfg_no_atomic_cas!\n} // cfg_has_atomic_ptr!\n\nmacro_rules! atomic_int {\n    // Atomic{I,U}* impls\n    ($atomic_type:ident, $int_type:ident, $align:literal,\n        $cfg_has_atomic_cas_or_amo32_or_8:ident, $cfg_no_atomic_cas_or_amo32_or_8:ident\n        $(, #[$cfg_float:meta] $atomic_float_type:ident, $float_type:ident)?\n    ) => {\n        doc_comment! {\n            concat!(\"An integer type which can be safely shared between threads.\n\nThis type has the same in-memory representation as the underlying integer type,\n[`\", stringify!($int_type), \"`].\n\nIf the compiler and the platform support atomic loads and stores of [`\", stringify!($int_type),\n\"`], this type is a wrapper for the standard library's `\", stringify!($atomic_type),\n\"`. If the platform supports it but the compiler does not, atomic operations are implemented using\ninline assembly. Otherwise synchronizes using global locks.\nYou can call [`\", stringify!($atomic_type), \"::is_lock_free()`] to check whether\natomic instructions or locks will be used.\n\"\n            ),\n            // We can use #[repr(transparent)] here, but #[repr(C, align(N))]\n            // will show clearer docs.\n            #[repr(C, align($align))]\n            pub struct $atomic_type {\n                inner: imp::$atomic_type,\n            }\n        }\n\n        impl Default for $atomic_type {\n            #[inline]\n            fn default() -> Self {\n                Self::new($int_type::default())\n            }\n        }\n\n        impl From<$int_type> for $atomic_type {\n            #[inline]\n            fn from(v: $int_type) -> Self {\n                Self::new(v)\n            }\n        }\n\n        // UnwindSafe is implicitly implemented.\n        #[cfg(not(portable_atomic_no_core_unwind_safe))]\n        impl core::panic::RefUnwindSafe for $atomic_type {}\n        #[cfg(all(portable_atomic_no_core_unwind_safe, feature = \"std\"))]\n        impl std::panic::RefUnwindSafe for $atomic_type {}\n\n        impl_debug_and_serde!($atomic_type);\n\n        impl $atomic_type {\n            doc_comment! {\n                concat!(\n                    \"Creates a new atomic integer.\n\n# Examples\n\n```\nuse portable_atomic::\", stringify!($atomic_type), \";\n\nlet atomic_forty_two = \", stringify!($atomic_type), \"::new(42);\n```\"\n                ),\n                #[inline]\n                #[must_use]\n                pub const fn new(v: $int_type) -> Self {\n                    static_assert_layout!($atomic_type, $int_type);\n                    Self { inner: imp::$atomic_type::new(v) }\n                }\n            }\n\n            // TODO: update docs based on https://github.com/rust-lang/rust/pull/116762\n            #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]\n            doc_comment! {\n                concat!(\"Creates a new reference to an atomic integer from a pointer.\n\nThis is `const fn` on Rust 1.58+.\n\n# Safety\n\n* `ptr` must be aligned to `align_of::<\", stringify!($atomic_type), \">()` (note that on some platforms this\n  can be bigger than `align_of::<\", stringify!($int_type), \">()`).\n* `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.\n* If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value\n  behind `ptr` must have a happens-before relationship with atomic accesses via\n  the returned value (or vice-versa).\n  * In other words, time periods where the value is accessed atomically may not\n    overlap with periods where the value is accessed non-atomically.\n  * This requirement is trivially satisfied if `ptr` is never used non-atomically\n    for the duration of lifetime `'a`. Most use cases should be able to follow\n    this guideline.\n  * This requirement is also trivially satisfied if all accesses (atomic or not) are\n    done from the same thread.\n* If this atomic type is *not* lock-free:\n  * Any accesses to the value behind `ptr` must have a happens-before relationship\n    with accesses via the returned value (or vice-versa).\n  * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must\n    be compatible with operations performed by this atomic type.\n* This method must not be used to create overlapping or mixed-size atomic\n  accesses, as these are not supported by the memory model.\n\n[valid]: core::ptr#safety\"),\n                #[inline]\n                #[must_use]\n                pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a Self {\n                    #[allow(clippy::cast_ptr_alignment)]\n                    // SAFETY: guaranteed by the caller\n                    unsafe { &*(ptr as *mut Self as *const Self) }\n                }\n            }\n            #[cfg(portable_atomic_no_const_raw_ptr_deref)]\n            doc_comment! {\n                concat!(\"Creates a new reference to an atomic integer from a pointer.\n\nThis is `const fn` on Rust 1.58+.\n\n# Safety\n\n* `ptr` must be aligned to `align_of::<\", stringify!($atomic_type), \">()` (note that on some platforms this\n  can be bigger than `align_of::<\", stringify!($int_type), \">()`).\n* `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.\n* If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value\n  behind `ptr` must have a happens-before relationship with atomic accesses via\n  the returned value (or vice-versa).\n  * In other words, time periods where the value is accessed atomically may not\n    overlap with periods where the value is accessed non-atomically.\n  * This requirement is trivially satisfied if `ptr` is never used non-atomically\n    for the duration of lifetime `'a`. Most use cases should be able to follow\n    this guideline.\n  * This requirement is also trivially satisfied if all accesses (atomic or not) are\n    done from the same thread.\n* If this atomic type is *not* lock-free:\n  * Any accesses to the value behind `ptr` must have a happens-before relationship\n    with accesses via the returned value (or vice-versa).\n  * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must\n    be compatible with operations performed by this atomic type.\n* This method must not be used to create overlapping or mixed-size atomic\n  accesses, as these are not supported by the memory model.\n\n[valid]: core::ptr#safety\"),\n                #[inline]\n                #[must_use]\n                pub unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a Self {\n                    #[allow(clippy::cast_ptr_alignment)]\n                    // SAFETY: guaranteed by the caller\n                    unsafe { &*(ptr as *mut Self as *const Self) }\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Returns `true` if operations on values of this type are lock-free.\n\nIf the compiler or the platform doesn't support the necessary\natomic instructions, global locks for every potentially\nconcurrent atomic operation will be used.\n\nThis function is guaranteed to always return the same result.\n\n# Examples\n\n```\nuse portable_atomic::\", stringify!($atomic_type), \";\n\nlet is_lock_free = \", stringify!($atomic_type), \"::is_lock_free();\n```\"),\n                #[inline]\n                #[must_use]\n                pub fn is_lock_free() -> bool {\n                    <imp::$atomic_type>::is_lock_free()\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Returns `true` if operations on values of this type are lock-free.\n\nIf the compiler or the platform doesn't support the necessary\natomic instructions, global locks for every potentially\nconcurrent atomic operation will be used.\n\n**Note:** If the atomic operation relies on dynamic CPU feature detection,\nthis type may be lock-free even if the function returns false.\n\n# Examples\n\n```\nuse portable_atomic::\", stringify!($atomic_type), \";\n\nconst IS_ALWAYS_LOCK_FREE: bool = \", stringify!($atomic_type), \"::is_always_lock_free();\n```\"),\n                #[inline]\n                #[must_use]\n                pub const fn is_always_lock_free() -> bool {\n                    <imp::$atomic_type>::IS_ALWAYS_LOCK_FREE\n                }\n            }\n            #[cfg(test)]\n            #[cfg_attr(all(valgrind, target_arch = \"powerpc64\"), allow(dead_code))] // TODO(powerpc64): Hang (as of Valgrind 3.26)\n            const IS_ALWAYS_LOCK_FREE: bool = Self::is_always_lock_free();\n\n            #[cfg(not(portable_atomic_no_const_mut_refs))]\n            doc_comment! {\n                concat!(\"Returns a mutable reference to the underlying integer.\\n\nThis is safe because the mutable reference guarantees that no other threads are\nconcurrently accessing the atomic data.\n\nThis is `const fn` on Rust 1.83+.\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet mut some_var = \", stringify!($atomic_type), \"::new(10);\nassert_eq!(*some_var.get_mut(), 10);\n*some_var.get_mut() = 5;\nassert_eq!(some_var.load(Ordering::SeqCst), 5);\n```\"),\n                #[inline]\n                pub const fn get_mut(&mut self) -> &mut $int_type {\n                    // SAFETY: the mutable reference guarantees unique ownership.\n                    // (core::sync::atomic::Atomic*::get_mut is not const yet)\n                    unsafe { &mut *self.as_ptr() }\n                }\n            }\n            #[cfg(portable_atomic_no_const_mut_refs)]\n            doc_comment! {\n                concat!(\"Returns a mutable reference to the underlying integer.\\n\nThis is safe because the mutable reference guarantees that no other threads are\nconcurrently accessing the atomic data.\n\nThis is `const fn` on Rust 1.83+.\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet mut some_var = \", stringify!($atomic_type), \"::new(10);\nassert_eq!(*some_var.get_mut(), 10);\n*some_var.get_mut() = 5;\nassert_eq!(some_var.load(Ordering::SeqCst), 5);\n```\"),\n                #[inline]\n                pub fn get_mut(&mut self) -> &mut $int_type {\n                    // SAFETY: the mutable reference guarantees unique ownership.\n                    unsafe { &mut *self.as_ptr() }\n                }\n            }\n\n            // TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types.\n            // https://github.com/rust-lang/rust/issues/76314\n\n            #[cfg(not(portable_atomic_no_const_transmute))]\n            doc_comment! {\n                concat!(\"Consumes the atomic and returns the contained value.\n\nThis is safe because passing `self` by value guarantees that no other threads are\nconcurrently accessing the atomic data.\n\nThis is `const fn` on Rust 1.56+.\n\n# Examples\n\n```\nuse portable_atomic::\", stringify!($atomic_type), \";\n\nlet some_var = \", stringify!($atomic_type), \"::new(5);\nassert_eq!(some_var.into_inner(), 5);\n```\"),\n                #[inline]\n                pub const fn into_inner(self) -> $int_type {\n                    // SAFETY: $atomic_type and $int_type have the same size and in-memory representations,\n                    // so they can be safely transmuted.\n                    // (const UnsafeCell::into_inner is unstable)\n                    unsafe { core::mem::transmute(self) }\n                }\n            }\n            #[cfg(portable_atomic_no_const_transmute)]\n            doc_comment! {\n                concat!(\"Consumes the atomic and returns the contained value.\n\nThis is safe because passing `self` by value guarantees that no other threads are\nconcurrently accessing the atomic data.\n\nThis is `const fn` on Rust 1.56+.\n\n# Examples\n\n```\nuse portable_atomic::\", stringify!($atomic_type), \";\n\nlet some_var = \", stringify!($atomic_type), \"::new(5);\nassert_eq!(some_var.into_inner(), 5);\n```\"),\n                #[inline]\n                pub fn into_inner(self) -> $int_type {\n                    // SAFETY: $atomic_type and $int_type have the same size and in-memory representations,\n                    // so they can be safely transmuted.\n                    // (const UnsafeCell::into_inner is unstable)\n                    unsafe { core::mem::transmute(self) }\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Loads a value from the atomic integer.\n\n`load` takes an [`Ordering`] argument which describes the memory ordering of this operation.\nPossible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].\n\n# Panics\n\nPanics if `order` is [`Release`] or [`AcqRel`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet some_var = \", stringify!($atomic_type), \"::new(5);\n\nassert_eq!(some_var.load(Ordering::Relaxed), 5);\n```\"),\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub fn load(&self, order: Ordering) -> $int_type {\n                    self.inner.load(order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Stores a value into the atomic integer.\n\n`store` takes an [`Ordering`] argument which describes the memory ordering of this operation.\nPossible values are [`SeqCst`], [`Release`] and [`Relaxed`].\n\n# Panics\n\nPanics if `order` is [`Acquire`] or [`AcqRel`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet some_var = \", stringify!($atomic_type), \"::new(5);\n\nsome_var.store(10, Ordering::Relaxed);\nassert_eq!(some_var.load(Ordering::Relaxed), 10);\n```\"),\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub fn store(&self, val: $int_type, order: Ordering) {\n                    self.inner.store(val, order)\n                }\n            }\n\n            cfg_has_atomic_cas_or_amo32! {\n            $cfg_has_atomic_cas_or_amo32_or_8! {\n            doc_comment! {\n                concat!(\"Stores a value into the atomic integer, returning the previous value.\n\n`swap` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet some_var = \", stringify!($atomic_type), \"::new(5);\n\nassert_eq!(some_var.swap(10, Ordering::Relaxed), 5);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {\n                    self.inner.swap(val, order)\n                }\n            }\n            } // $cfg_has_atomic_cas_or_amo32_or_8!\n\n            cfg_has_atomic_cas! {\n            doc_comment! {\n                concat!(\"Stores a value into the atomic integer if the current value is the same as\nthe `current` value.\n\nThe return value is a result indicating whether the new value was written and\ncontaining the previous value. On success this value is guaranteed to be equal to\n`current`.\n\n`compare_exchange` takes two [`Ordering`] arguments to describe the memory\nordering of this operation. `success` describes the required ordering for the\nread-modify-write operation that takes place if the comparison with `current` succeeds.\n`failure` describes the required ordering for the load operation that takes place when\nthe comparison fails. Using [`Acquire`] as success ordering makes the store part\nof this operation [`Relaxed`], and using [`Release`] makes the successful load\n[`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].\n\n# Panics\n\nPanics if `failure` is [`Release`], [`AcqRel`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet some_var = \", stringify!($atomic_type), \"::new(5);\n\nassert_eq!(\n    some_var.compare_exchange(5, 10, Ordering::Acquire, Ordering::Relaxed),\n    Ok(5),\n);\nassert_eq!(some_var.load(Ordering::Relaxed), 10);\n\nassert_eq!(\n    some_var.compare_exchange(6, 12, Ordering::SeqCst, Ordering::Acquire),\n    Err(10),\n);\nassert_eq!(some_var.load(Ordering::Relaxed), 10);\n```\"),\n                #[cfg_attr(docsrs, doc(alias = \"compare_and_swap\"))]\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub fn compare_exchange(\n                    &self,\n                    current: $int_type,\n                    new: $int_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$int_type, $int_type> {\n                    self.inner.compare_exchange(current, new, success, failure)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Stores a value into the atomic integer if the current value is the same as\nthe `current` value.\nUnlike [`compare_exchange`](Self::compare_exchange)\nthis function is allowed to spuriously fail even\nwhen the comparison succeeds, which can result in more efficient code on some\nplatforms. The return value is a result indicating whether the new value was\nwritten and containing the previous value.\n\n`compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory\nordering of this operation. `success` describes the required ordering for the\nread-modify-write operation that takes place if the comparison with `current` succeeds.\n`failure` describes the required ordering for the load operation that takes place when\nthe comparison fails. Using [`Acquire`] as success ordering makes the store part\nof this operation [`Relaxed`], and using [`Release`] makes the successful load\n[`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].\n\n# Panics\n\nPanics if `failure` is [`Release`], [`AcqRel`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet val = \", stringify!($atomic_type), \"::new(4);\n\nlet mut old = val.load(Ordering::Relaxed);\nloop {\n    let new = old * 2;\n    match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {\n        Ok(_) => break,\n        Err(x) => old = x,\n    }\n}\n```\"),\n                #[cfg_attr(docsrs, doc(alias = \"compare_and_swap\"))]\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub fn compare_exchange_weak(\n                    &self,\n                    current: $int_type,\n                    new: $int_type,\n                    success: Ordering,\n                    failure: Ordering,\n                ) -> Result<$int_type, $int_type> {\n                    self.inner.compare_exchange_weak(current, new, success, failure)\n                }\n            }\n            } // cfg_has_atomic_cas!\n\n            $cfg_has_atomic_cas_or_amo32_or_8! {\n            doc_comment! {\n                concat!(\"Adds to the current value, returning the previous value.\n\nThis operation wraps around on overflow.\n\n`fetch_add` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0);\nassert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);\nassert_eq!(foo.load(Ordering::SeqCst), 10);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {\n                    self.inner.fetch_add(val, order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Adds to the current value.\n\nThis operation wraps around on overflow.\n\nUnlike `fetch_add`, this does not return the previous value.\n\n`add` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\nThis function may generate more efficient code than `fetch_add` on some platforms.\n\n- MSP430: `add` instead of disabling interrupts ({8,16}-bit atomics)\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0);\nfoo.add(10, Ordering::SeqCst);\nassert_eq!(foo.load(Ordering::SeqCst), 10);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn add(&self, val: $int_type, order: Ordering) {\n                    self.inner.add(val, order);\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Subtracts from the current value, returning the previous value.\n\nThis operation wraps around on overflow.\n\n`fetch_sub` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(20);\nassert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);\nassert_eq!(foo.load(Ordering::SeqCst), 10);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {\n                    self.inner.fetch_sub(val, order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Subtracts from the current value.\n\nThis operation wraps around on overflow.\n\nUnlike `fetch_sub`, this does not return the previous value.\n\n`sub` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\nThis function may generate more efficient code than `fetch_sub` on some platforms.\n\n- MSP430: `sub` instead of disabling interrupts ({8,16}-bit atomics)\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(20);\nfoo.sub(10, Ordering::SeqCst);\nassert_eq!(foo.load(Ordering::SeqCst), 10);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn sub(&self, val: $int_type, order: Ordering) {\n                    self.inner.sub(val, order);\n                }\n            }\n            } // $cfg_has_atomic_cas_or_amo32_or_8!\n\n            doc_comment! {\n                concat!(\"Bitwise \\\"and\\\" with the current value.\n\nPerforms a bitwise \\\"and\\\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_and` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0b101101);\nassert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);\nassert_eq!(foo.load(Ordering::SeqCst), 0b100001);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {\n                    self.inner.fetch_and(val, order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Bitwise \\\"and\\\" with the current value.\n\nPerforms a bitwise \\\"and\\\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nUnlike `fetch_and`, this does not return the previous value.\n\n`and` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\nThis function may generate more efficient code than `fetch_and` on some platforms.\n\n- x86/x86_64: `lock and` instead of `cmpxchg` loop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64)\n- MSP430: `and` instead of disabling interrupts ({8,16}-bit atomics)\n\nNote: On x86/x86_64, the use of either function should not usually\naffect the generated code, because LLVM can properly optimize the case\nwhere the result is unused.\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0b101101);\nassert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);\nassert_eq!(foo.load(Ordering::SeqCst), 0b100001);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn and(&self, val: $int_type, order: Ordering) {\n                    self.inner.and(val, order);\n                }\n            }\n\n            cfg_has_atomic_cas! {\n            doc_comment! {\n                concat!(\"Bitwise \\\"nand\\\" with the current value.\n\nPerforms a bitwise \\\"nand\\\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_nand` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0x13);\nassert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);\nassert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {\n                    self.inner.fetch_nand(val, order)\n                }\n            }\n            } // cfg_has_atomic_cas!\n\n            doc_comment! {\n                concat!(\"Bitwise \\\"or\\\" with the current value.\n\nPerforms a bitwise \\\"or\\\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_or` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0b101101);\nassert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);\nassert_eq!(foo.load(Ordering::SeqCst), 0b111111);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {\n                    self.inner.fetch_or(val, order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Bitwise \\\"or\\\" with the current value.\n\nPerforms a bitwise \\\"or\\\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nUnlike `fetch_or`, this does not return the previous value.\n\n`or` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\nThis function may generate more efficient code than `fetch_or` on some platforms.\n\n- x86/x86_64: `lock or` instead of `cmpxchg` loop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64)\n- MSP430: `or` instead of disabling interrupts ({8,16}-bit atomics)\n\nNote: On x86/x86_64, the use of either function should not usually\naffect the generated code, because LLVM can properly optimize the case\nwhere the result is unused.\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0b101101);\nassert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);\nassert_eq!(foo.load(Ordering::SeqCst), 0b111111);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn or(&self, val: $int_type, order: Ordering) {\n                    self.inner.or(val, order);\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Bitwise \\\"xor\\\" with the current value.\n\nPerforms a bitwise \\\"xor\\\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_xor` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0b101101);\nassert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);\nassert_eq!(foo.load(Ordering::SeqCst), 0b011110);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {\n                    self.inner.fetch_xor(val, order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Bitwise \\\"xor\\\" with the current value.\n\nPerforms a bitwise \\\"xor\\\" operation on the current value and the argument `val`, and\nsets the new value to the result.\n\nUnlike `fetch_xor`, this does not return the previous value.\n\n`xor` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\nThis function may generate more efficient code than `fetch_xor` on some platforms.\n\n- x86/x86_64: `lock xor` instead of `cmpxchg` loop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64)\n- MSP430: `xor` instead of disabling interrupts ({8,16}-bit atomics)\n\nNote: On x86/x86_64, the use of either function should not usually\naffect the generated code, because LLVM can properly optimize the case\nwhere the result is unused.\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0b101101);\nfoo.xor(0b110011, Ordering::SeqCst);\nassert_eq!(foo.load(Ordering::SeqCst), 0b011110);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn xor(&self, val: $int_type, order: Ordering) {\n                    self.inner.xor(val, order);\n                }\n            }\n\n            cfg_has_atomic_cas! {\n            doc_comment! {\n                concat!(\"Fetches the value, and applies a function to it that returns an optional\nnew value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else\n`Err(previous_value)`.\n\nNote: This may call the function multiple times if the value has been changed from other threads in\nthe meantime, as long as the function returns `Some(_)`, but the function will have been applied\nonly once to the stored value.\n\n`fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.\nThe first describes the required ordering for when the operation finally succeeds while the second\ndescribes the required ordering for loads. These correspond to the success and failure orderings of\n[`compare_exchange`](Self::compare_exchange) respectively.\n\nUsing [`Acquire`] as success ordering makes the store part\nof this operation [`Relaxed`], and using [`Release`] makes the final successful load\n[`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].\n\n# Panics\n\nPanics if `fetch_order` is [`Release`], [`AcqRel`].\n\n# Considerations\n\nThis method is not magic; it is not provided by the hardware.\nIt is implemented in terms of [`compare_exchange_weak`](Self::compare_exchange_weak),\nand suffers from the same drawbacks.\nIn particular, this method will not circumvent the [ABA Problem].\n\n[ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet x = \", stringify!($atomic_type), \"::new(7);\nassert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));\nassert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));\nassert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));\nassert_eq!(x.load(Ordering::SeqCst), 9);\n```\"),\n                #[inline]\n                #[cfg_attr(\n                    any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                    track_caller\n                )]\n                pub fn fetch_update<F>(\n                    &self,\n                    set_order: Ordering,\n                    fetch_order: Ordering,\n                    mut f: F,\n                ) -> Result<$int_type, $int_type>\n                where\n                    F: FnMut($int_type) -> Option<$int_type>,\n                {\n                    let mut prev = self.load(fetch_order);\n                    while let Some(next) = f(prev) {\n                        match self.compare_exchange_weak(prev, next, set_order, fetch_order) {\n                            x @ Ok(_) => return x,\n                            Err(next_prev) => prev = next_prev,\n                        }\n                    }\n                    Err(prev)\n                }\n            }\n            } // cfg_has_atomic_cas!\n\n            $cfg_has_atomic_cas_or_amo32_or_8! {\n            doc_comment! {\n                concat!(\"Maximum with the current value.\n\nFinds the maximum of the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_max` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(23);\nassert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);\nassert_eq!(foo.load(Ordering::SeqCst), 42);\n```\n\nIf you want to obtain the maximum value in one step, you can use the following:\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(23);\nlet bar = 42;\nlet max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);\nassert!(max_foo == 42);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {\n                    self.inner.fetch_max(val, order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Minimum with the current value.\n\nFinds the minimum of the current value and the argument `val`, and\nsets the new value to the result.\n\nReturns the previous value.\n\n`fetch_min` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(23);\nassert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);\nassert_eq!(foo.load(Ordering::Relaxed), 23);\nassert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);\nassert_eq!(foo.load(Ordering::Relaxed), 22);\n```\n\nIf you want to obtain the minimum value in one step, you can use the following:\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(23);\nlet bar = 12;\nlet min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);\nassert_eq!(min_foo, 12);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {\n                    self.inner.fetch_min(val, order)\n                }\n            }\n            } // $cfg_has_atomic_cas_or_amo32_or_8!\n\n            doc_comment! {\n                concat!(\"Sets the bit at the specified bit-position to 1.\n\nReturns `true` if the specified bit was previously set to 1.\n\n`bit_set` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\nThis corresponds to x86's `lock bts`, and the implementation calls them on x86/x86_64.\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0b0000);\nassert!(!foo.bit_set(0, Ordering::Relaxed));\nassert_eq!(foo.load(Ordering::Relaxed), 0b0001);\nassert!(foo.bit_set(0, Ordering::Relaxed));\nassert_eq!(foo.load(Ordering::Relaxed), 0b0001);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn bit_set(&self, bit: u32, order: Ordering) -> bool {\n                    self.inner.bit_set(bit, order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Clears the bit at the specified bit-position to 0.\n\nReturns `true` if the specified bit was previously set to 1.\n\n`bit_clear` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\nThis corresponds to x86's `lock btr`, and the implementation calls them on x86/x86_64.\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0b0001);\nassert!(foo.bit_clear(0, Ordering::Relaxed));\nassert_eq!(foo.load(Ordering::Relaxed), 0b0000);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn bit_clear(&self, bit: u32, order: Ordering) -> bool {\n                    self.inner.bit_clear(bit, order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Toggles the bit at the specified bit-position.\n\nReturns `true` if the specified bit was previously set to 1.\n\n`bit_toggle` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\nThis corresponds to x86's `lock btc`, and the implementation calls them on x86/x86_64.\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0b0000);\nassert!(!foo.bit_toggle(0, Ordering::Relaxed));\nassert_eq!(foo.load(Ordering::Relaxed), 0b0001);\nassert!(foo.bit_toggle(0, Ordering::Relaxed));\nassert_eq!(foo.load(Ordering::Relaxed), 0b0000);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn bit_toggle(&self, bit: u32, order: Ordering) -> bool {\n                    self.inner.bit_toggle(bit, order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Logical negates the current value, and sets the new value to the result.\n\nReturns the previous value.\n\n`fetch_not` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0);\nassert_eq!(foo.fetch_not(Ordering::Relaxed), 0);\nassert_eq!(foo.load(Ordering::Relaxed), !0);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn fetch_not(&self, order: Ordering) -> $int_type {\n                    self.inner.fetch_not(order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Logical negates the current value, and sets the new value to the result.\n\nUnlike `fetch_not`, this does not return the previous value.\n\n`not` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\nThis function may generate more efficient code than `fetch_not` on some platforms.\n\n- x86/x86_64: `lock not` instead of `cmpxchg` loop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64)\n- MSP430: `inv` instead of disabling interrupts ({8,16}-bit atomics)\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(0);\nfoo.not(Ordering::Relaxed);\nassert_eq!(foo.load(Ordering::Relaxed), !0);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn not(&self, order: Ordering) {\n                    self.inner.not(order);\n                }\n            }\n\n            cfg_has_atomic_cas! {\n            doc_comment! {\n                concat!(\"Negates the current value, and sets the new value to the result.\n\nReturns the previous value.\n\n`fetch_neg` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(5);\nassert_eq!(foo.fetch_neg(Ordering::Relaxed), 5);\nassert_eq!(foo.load(Ordering::Relaxed), 5_\", stringify!($int_type), \".wrapping_neg());\nassert_eq!(foo.fetch_neg(Ordering::Relaxed), 5_\", stringify!($int_type), \".wrapping_neg());\nassert_eq!(foo.load(Ordering::Relaxed), 5);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn fetch_neg(&self, order: Ordering) -> $int_type {\n                    self.inner.fetch_neg(order)\n                }\n            }\n\n            doc_comment! {\n                concat!(\"Negates the current value, and sets the new value to the result.\n\nUnlike `fetch_neg`, this does not return the previous value.\n\n`neg` takes an [`Ordering`] argument which describes the memory ordering\nof this operation. All ordering modes are possible. Note that using\n[`Acquire`] makes the store part of this operation [`Relaxed`], and\nusing [`Release`] makes the load part [`Relaxed`].\n\nThis function may generate more efficient code than `fetch_neg` on some platforms.\n\n- x86/x86_64: `lock neg` instead of `cmpxchg` loop ({8,16,32}-bit atomics on x86, but additionally 64-bit atomics on x86_64)\n\n# Examples\n\n```\nuse portable_atomic::{\", stringify!($atomic_type), \", Ordering};\n\nlet foo = \", stringify!($atomic_type), \"::new(5);\nfoo.neg(Ordering::Relaxed);\nassert_eq!(foo.load(Ordering::Relaxed), 5_\", stringify!($int_type), \".wrapping_neg());\nfoo.neg(Ordering::Relaxed);\nassert_eq!(foo.load(Ordering::Relaxed), 5);\n```\"),\n                #[inline]\n                #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n                pub fn neg(&self, order: Ordering) {\n                    self.inner.neg(order);\n                }\n            }\n            } // cfg_has_atomic_cas!\n            } // cfg_has_atomic_cas_or_amo32!\n\n            const_fn! {\n                const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))];\n                /// Returns a mutable pointer to the underlying integer.\n                ///\n                /// Returning an `*mut` pointer from a shared reference to this atomic is\n                /// safe because the atomic types work with interior mutability. Any use of\n                /// the returned raw pointer requires an `unsafe` block and has to uphold\n                /// the safety requirements. If there is concurrent access, note the following\n                /// additional safety requirements:\n                ///\n                /// - If this atomic type is [lock-free](Self::is_lock_free), any concurrent\n                ///   operations on it must be atomic.\n                /// - Otherwise, any concurrent operations on it must be compatible with\n                ///   operations performed by this atomic type.\n                ///\n                /// This is `const fn` on Rust 1.58+.\n                #[inline]\n                pub const fn as_ptr(&self) -> *mut $int_type {\n                    self.inner.as_ptr()\n                }\n            }\n        }\n        // See https://github.com/taiki-e/portable-atomic/issues/180\n        #[cfg(not(feature = \"require-cas\"))]\n        cfg_no_atomic_cas! {\n        #[doc(hidden)]\n        #[allow(unused_variables, clippy::unused_self, clippy::extra_unused_lifetimes)]\n        impl<'a> $atomic_type {\n            $cfg_no_atomic_cas_or_amo32_or_8! {\n            #[inline]\n            pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type\n            where\n                &'a Self: HasSwap,\n            {\n                unimplemented!()\n            }\n            } // $cfg_no_atomic_cas_or_amo32_or_8!\n            #[inline]\n            pub fn compare_exchange(\n                &self,\n                current: $int_type,\n                new: $int_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$int_type, $int_type>\n            where\n                &'a Self: HasCompareExchange,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn compare_exchange_weak(\n                &self,\n                current: $int_type,\n                new: $int_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$int_type, $int_type>\n            where\n                &'a Self: HasCompareExchangeWeak,\n            {\n                unimplemented!()\n            }\n            $cfg_no_atomic_cas_or_amo32_or_8! {\n            #[inline]\n            pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type\n            where\n                &'a Self: HasFetchAdd,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn add(&self, val: $int_type, order: Ordering)\n            where\n                &'a Self: HasAdd,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type\n            where\n                &'a Self: HasFetchSub,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn sub(&self, val: $int_type, order: Ordering)\n            where\n                &'a Self: HasSub,\n            {\n                unimplemented!()\n            }\n            } // $cfg_no_atomic_cas_or_amo32_or_8!\n            cfg_no_atomic_cas_or_amo32! {\n            #[inline]\n            pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type\n            where\n                &'a Self: HasFetchAnd,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn and(&self, val: $int_type, order: Ordering)\n            where\n                &'a Self: HasAnd,\n            {\n                unimplemented!()\n            }\n            } // cfg_no_atomic_cas_or_amo32!\n            #[inline]\n            pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type\n            where\n                &'a Self: HasFetchNand,\n            {\n                unimplemented!()\n            }\n            cfg_no_atomic_cas_or_amo32! {\n            #[inline]\n            pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type\n            where\n                &'a Self: HasFetchOr,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn or(&self, val: $int_type, order: Ordering)\n            where\n                &'a Self: HasOr,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type\n            where\n                &'a Self: HasFetchXor,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn xor(&self, val: $int_type, order: Ordering)\n            where\n                &'a Self: HasXor,\n            {\n                unimplemented!()\n            }\n            } // cfg_no_atomic_cas_or_amo32!\n            #[inline]\n            pub fn fetch_update<F>(\n                &self,\n                set_order: Ordering,\n                fetch_order: Ordering,\n                f: F,\n            ) -> Result<$int_type, $int_type>\n            where\n                F: FnMut($int_type) -> Option<$int_type>,\n                &'a Self: HasFetchUpdate,\n            {\n                unimplemented!()\n            }\n            $cfg_no_atomic_cas_or_amo32_or_8! {\n            #[inline]\n            pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type\n            where\n                &'a Self: HasFetchMax,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type\n            where\n                &'a Self: HasFetchMin,\n            {\n                unimplemented!()\n            }\n            } // $cfg_no_atomic_cas_or_amo32_or_8!\n            cfg_no_atomic_cas_or_amo32! {\n            #[inline]\n            pub fn bit_set(&self, bit: u32, order: Ordering) -> bool\n            where\n                &'a Self: HasBitSet,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn bit_clear(&self, bit: u32, order: Ordering) -> bool\n            where\n                &'a Self: HasBitClear,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn bit_toggle(&self, bit: u32, order: Ordering) -> bool\n            where\n                &'a Self: HasBitToggle,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn fetch_not(&self, order: Ordering) -> $int_type\n            where\n                &'a Self: HasFetchNot,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn not(&self, order: Ordering)\n            where\n                &'a Self: HasNot,\n            {\n                unimplemented!()\n            }\n            } // cfg_no_atomic_cas_or_amo32!\n            #[inline]\n            pub fn fetch_neg(&self, order: Ordering) -> $int_type\n            where\n                &'a Self: HasFetchNeg,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn neg(&self, order: Ordering)\n            where\n                &'a Self: HasNeg,\n            {\n                unimplemented!()\n            }\n        }\n        } // cfg_no_atomic_cas!\n        $(\n            #[$cfg_float]\n            atomic_int!(float,\n                #[$cfg_float] $atomic_float_type, $float_type, $atomic_type, $int_type, $align\n            );\n        )?\n    };\n\n    // AtomicF* impls\n    (float,\n        #[$cfg_float:meta]\n        $atomic_type:ident,\n        $float_type:ident,\n        $atomic_int_type:ident,\n        $int_type:ident,\n        $align:literal\n    ) => {\n        doc_comment! {\n            concat!(\"A floating point type which can be safely shared between threads.\n\nThis type has the same in-memory representation as the underlying floating point type,\n[`\", stringify!($float_type), \"`].\n\"\n            ),\n            #[cfg_attr(docsrs, doc($cfg_float))]\n            // We can use #[repr(transparent)] here, but #[repr(C, align(N))]\n            // will show clearer docs.\n            #[repr(C, align($align))]\n            pub struct $atomic_type {\n                inner: imp::float::$atomic_type,\n            }\n        }\n\n        impl Default for $atomic_type {\n            #[inline]\n            fn default() -> Self {\n                Self::new($float_type::default())\n            }\n        }\n\n        impl From<$float_type> for $atomic_type {\n            #[inline]\n            fn from(v: $float_type) -> Self {\n                Self::new(v)\n            }\n        }\n\n        // UnwindSafe is implicitly implemented.\n        #[cfg(not(portable_atomic_no_core_unwind_safe))]\n        impl core::panic::RefUnwindSafe for $atomic_type {}\n        #[cfg(all(portable_atomic_no_core_unwind_safe, feature = \"std\"))]\n        impl std::panic::RefUnwindSafe for $atomic_type {}\n\n        impl_debug_and_serde!($atomic_type);\n\n        impl $atomic_type {\n            /// Creates a new atomic float.\n            #[inline]\n            #[must_use]\n            pub const fn new(v: $float_type) -> Self {\n                static_assert_layout!($atomic_type, $float_type);\n                Self { inner: imp::float::$atomic_type::new(v) }\n            }\n\n            // TODO: update docs based on https://github.com/rust-lang/rust/pull/116762\n            #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]\n            doc_comment! {\n                concat!(\"Creates a new reference to an atomic float from a pointer.\n\nThis is `const fn` on Rust 1.58+.\n\n# Safety\n\n* `ptr` must be aligned to `align_of::<\", stringify!($atomic_type), \">()` (note that on some platforms this\n  can be bigger than `align_of::<\", stringify!($float_type), \">()`).\n* `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.\n* If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value\n  behind `ptr` must have a happens-before relationship with atomic accesses via\n  the returned value (or vice-versa).\n  * In other words, time periods where the value is accessed atomically may not\n    overlap with periods where the value is accessed non-atomically.\n  * This requirement is trivially satisfied if `ptr` is never used non-atomically\n    for the duration of lifetime `'a`. Most use cases should be able to follow\n    this guideline.\n  * This requirement is also trivially satisfied if all accesses (atomic or not) are\n    done from the same thread.\n* If this atomic type is *not* lock-free:\n  * Any accesses to the value behind `ptr` must have a happens-before relationship\n    with accesses via the returned value (or vice-versa).\n  * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must\n    be compatible with operations performed by this atomic type.\n* This method must not be used to create overlapping or mixed-size atomic\n  accesses, as these are not supported by the memory model.\n\n[valid]: core::ptr#safety\"),\n                #[inline]\n                #[must_use]\n                pub const unsafe fn from_ptr<'a>(ptr: *mut $float_type) -> &'a Self {\n                    #[allow(clippy::cast_ptr_alignment)]\n                    // SAFETY: guaranteed by the caller\n                    unsafe { &*(ptr as *mut Self as *const Self) }\n                }\n            }\n            #[cfg(portable_atomic_no_const_raw_ptr_deref)]\n            doc_comment! {\n                concat!(\"Creates a new reference to an atomic float from a pointer.\n\nThis is `const fn` on Rust 1.58+.\n\n# Safety\n\n* `ptr` must be aligned to `align_of::<\", stringify!($atomic_type), \">()` (note that on some platforms this\n  can be bigger than `align_of::<\", stringify!($float_type), \">()`).\n* `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.\n* If this atomic type is [lock-free](Self::is_lock_free), non-atomic accesses to the value\n  behind `ptr` must have a happens-before relationship with atomic accesses via\n  the returned value (or vice-versa).\n  * In other words, time periods where the value is accessed atomically may not\n    overlap with periods where the value is accessed non-atomically.\n  * This requirement is trivially satisfied if `ptr` is never used non-atomically\n    for the duration of lifetime `'a`. Most use cases should be able to follow\n    this guideline.\n  * This requirement is also trivially satisfied if all accesses (atomic or not) are\n    done from the same thread.\n* If this atomic type is *not* lock-free:\n  * Any accesses to the value behind `ptr` must have a happens-before relationship\n    with accesses via the returned value (or vice-versa).\n  * Any concurrent accesses to the value behind `ptr` for the duration of lifetime `'a` must\n    be compatible with operations performed by this atomic type.\n* This method must not be used to create overlapping or mixed-size atomic\n  accesses, as these are not supported by the memory model.\n\n[valid]: core::ptr#safety\"),\n                #[inline]\n                #[must_use]\n                pub unsafe fn from_ptr<'a>(ptr: *mut $float_type) -> &'a Self {\n                    #[allow(clippy::cast_ptr_alignment)]\n                    // SAFETY: guaranteed by the caller\n                    unsafe { &*(ptr as *mut Self as *const Self) }\n                }\n            }\n\n            /// Returns `true` if operations on values of this type are lock-free.\n            ///\n            /// If the compiler or the platform doesn't support the necessary\n            /// atomic instructions, global locks for every potentially\n            /// concurrent atomic operation will be used.\n            ///\n            /// This function is guaranteed to always return the same result.\n            #[inline]\n            #[must_use]\n            pub fn is_lock_free() -> bool {\n                <imp::float::$atomic_type>::is_lock_free()\n            }\n\n            /// Returns `true` if operations on values of this type are lock-free.\n            ///\n            /// If the compiler or the platform doesn't support the necessary\n            /// atomic instructions, global locks for every potentially\n            /// concurrent atomic operation will be used.\n            ///\n            /// **Note:** If the atomic operation relies on dynamic CPU feature detection,\n            /// this type may be lock-free even if the function returns false.\n            #[inline]\n            #[must_use]\n            pub const fn is_always_lock_free() -> bool {\n                <imp::float::$atomic_type>::IS_ALWAYS_LOCK_FREE\n            }\n            #[cfg(test)]\n            #[cfg_attr(all(not(debug_assertions), target_arch = \"x86\", not(target_feature = \"sse2\")), allow(dead_code))]\n            const IS_ALWAYS_LOCK_FREE: bool = Self::is_always_lock_free();\n\n            const_fn! {\n                const_if: #[cfg(not(portable_atomic_no_const_mut_refs))];\n                /// Returns a mutable reference to the underlying float.\n                ///\n                /// This is safe because the mutable reference guarantees that no other threads are\n                /// concurrently accessing the atomic data.\n                ///\n                /// This is `const fn` on Rust 1.83+.\n                #[inline]\n                pub const fn get_mut(&mut self) -> &mut $float_type {\n                    // SAFETY: the mutable reference guarantees unique ownership.\n                    unsafe { &mut *self.as_ptr() }\n                }\n            }\n\n            // TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types.\n            // https://github.com/rust-lang/rust/issues/76314\n\n            const_fn! {\n                const_if: #[cfg(not(portable_atomic_no_const_transmute))];\n                /// Consumes the atomic and returns the contained value.\n                ///\n                /// This is safe because passing `self` by value guarantees that no other threads are\n                /// concurrently accessing the atomic data.\n                ///\n                /// This is `const fn` on Rust 1.56+.\n                #[inline]\n                pub const fn into_inner(self) -> $float_type {\n                    // SAFETY: $atomic_type and $float_type have the same size and in-memory representations,\n                    // so they can be safely transmuted.\n                    // (const UnsafeCell::into_inner is unstable)\n                    unsafe { core::mem::transmute(self) }\n                }\n            }\n\n            /// Loads a value from the atomic float.\n            ///\n            /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.\n            /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].\n            ///\n            /// # Panics\n            ///\n            /// Panics if `order` is [`Release`] or [`AcqRel`].\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub fn load(&self, order: Ordering) -> $float_type {\n                self.inner.load(order)\n            }\n\n            /// Stores a value into the atomic float.\n            ///\n            /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.\n            ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].\n            ///\n            /// # Panics\n            ///\n            /// Panics if `order` is [`Acquire`] or [`AcqRel`].\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub fn store(&self, val: $float_type, order: Ordering) {\n                self.inner.store(val, order)\n            }\n\n            cfg_has_atomic_cas_or_amo32! {\n            /// Stores a value into the atomic float, returning the previous value.\n            ///\n            /// `swap` takes an [`Ordering`] argument which describes the memory ordering\n            /// of this operation. All ordering modes are possible. Note that using\n            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n            /// using [`Release`] makes the load part [`Relaxed`].\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub fn swap(&self, val: $float_type, order: Ordering) -> $float_type {\n                self.inner.swap(val, order)\n            }\n\n            cfg_has_atomic_cas! {\n            /// Stores a value into the atomic float if the current value is the same as\n            /// the `current` value.\n            ///\n            /// The return value is a result indicating whether the new value was written and\n            /// containing the previous value. On success this value is guaranteed to be equal to\n            /// `current`.\n            ///\n            /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory\n            /// ordering of this operation. `success` describes the required ordering for the\n            /// read-modify-write operation that takes place if the comparison with `current` succeeds.\n            /// `failure` describes the required ordering for the load operation that takes place when\n            /// the comparison fails. Using [`Acquire`] as success ordering makes the store part\n            /// of this operation [`Relaxed`], and using [`Release`] makes the successful load\n            /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].\n            ///\n            /// # Panics\n            ///\n            /// Panics if `failure` is [`Release`], [`AcqRel`].\n            #[cfg_attr(docsrs, doc(alias = \"compare_and_swap\"))]\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub fn compare_exchange(\n                &self,\n                current: $float_type,\n                new: $float_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$float_type, $float_type> {\n                self.inner.compare_exchange(current, new, success, failure)\n            }\n\n            /// Stores a value into the atomic float if the current value is the same as\n            /// the `current` value.\n            /// Unlike [`compare_exchange`](Self::compare_exchange)\n            /// this function is allowed to spuriously fail even\n            /// when the comparison succeeds, which can result in more efficient code on some\n            /// platforms. The return value is a result indicating whether the new value was\n            /// written and containing the previous value.\n            ///\n            /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory\n            /// ordering of this operation. `success` describes the required ordering for the\n            /// read-modify-write operation that takes place if the comparison with `current` succeeds.\n            /// `failure` describes the required ordering for the load operation that takes place when\n            /// the comparison fails. Using [`Acquire`] as success ordering makes the store part\n            /// of this operation [`Relaxed`], and using [`Release`] makes the successful load\n            /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].\n            ///\n            /// # Panics\n            ///\n            /// Panics if `failure` is [`Release`], [`AcqRel`].\n            #[cfg_attr(docsrs, doc(alias = \"compare_and_swap\"))]\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub fn compare_exchange_weak(\n                &self,\n                current: $float_type,\n                new: $float_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$float_type, $float_type> {\n                self.inner.compare_exchange_weak(current, new, success, failure)\n            }\n\n            /// Adds to the current value, returning the previous value.\n            ///\n            /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering\n            /// of this operation. All ordering modes are possible. Note that using\n            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n            /// using [`Release`] makes the load part [`Relaxed`].\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub fn fetch_add(&self, val: $float_type, order: Ordering) -> $float_type {\n                self.inner.fetch_add(val, order)\n            }\n\n            /// Subtracts from the current value, returning the previous value.\n            ///\n            /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering\n            /// of this operation. All ordering modes are possible. Note that using\n            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n            /// using [`Release`] makes the load part [`Relaxed`].\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub fn fetch_sub(&self, val: $float_type, order: Ordering) -> $float_type {\n                self.inner.fetch_sub(val, order)\n            }\n\n            /// Fetches the value, and applies a function to it that returns an optional\n            /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else\n            /// `Err(previous_value)`.\n            ///\n            /// Note: This may call the function multiple times if the value has been changed from other threads in\n            /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied\n            /// only once to the stored value.\n            ///\n            /// `fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.\n            /// The first describes the required ordering for when the operation finally succeeds while the second\n            /// describes the required ordering for loads. These correspond to the success and failure orderings of\n            /// [`compare_exchange`](Self::compare_exchange) respectively.\n            ///\n            /// Using [`Acquire`] as success ordering makes the store part\n            /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load\n            /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].\n            ///\n            /// # Panics\n            ///\n            /// Panics if `fetch_order` is [`Release`], [`AcqRel`].\n            ///\n            /// # Considerations\n            ///\n            /// This method is not magic; it is not provided by the hardware.\n            /// It is implemented in terms of [`compare_exchange_weak`](Self::compare_exchange_weak),\n            /// and suffers from the same drawbacks.\n            /// In particular, this method will not circumvent the [ABA Problem].\n            ///\n            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem\n            #[inline]\n            #[cfg_attr(\n                any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),\n                track_caller\n            )]\n            pub fn fetch_update<F>(\n                &self,\n                set_order: Ordering,\n                fetch_order: Ordering,\n                mut f: F,\n            ) -> Result<$float_type, $float_type>\n            where\n                F: FnMut($float_type) -> Option<$float_type>,\n            {\n                let mut prev = self.load(fetch_order);\n                while let Some(next) = f(prev) {\n                    match self.compare_exchange_weak(prev, next, set_order, fetch_order) {\n                        x @ Ok(_) => return x,\n                        Err(next_prev) => prev = next_prev,\n                    }\n                }\n                Err(prev)\n            }\n\n            /// Maximum with the current value.\n            ///\n            /// Finds the maximum of the current value and the argument `val`, and\n            /// sets the new value to the result.\n            ///\n            /// Returns the previous value.\n            ///\n            /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering\n            /// of this operation. All ordering modes are possible. Note that using\n            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n            /// using [`Release`] makes the load part [`Relaxed`].\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub fn fetch_max(&self, val: $float_type, order: Ordering) -> $float_type {\n                self.inner.fetch_max(val, order)\n            }\n\n            /// Minimum with the current value.\n            ///\n            /// Finds the minimum of the current value and the argument `val`, and\n            /// sets the new value to the result.\n            ///\n            /// Returns the previous value.\n            ///\n            /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering\n            /// of this operation. All ordering modes are possible. Note that using\n            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n            /// using [`Release`] makes the load part [`Relaxed`].\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub fn fetch_min(&self, val: $float_type, order: Ordering) -> $float_type {\n                self.inner.fetch_min(val, order)\n            }\n            } // cfg_has_atomic_cas!\n\n            /// Negates the current value, and sets the new value to the result.\n            ///\n            /// Returns the previous value.\n            ///\n            /// `fetch_neg` takes an [`Ordering`] argument which describes the memory ordering\n            /// of this operation. All ordering modes are possible. Note that using\n            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n            /// using [`Release`] makes the load part [`Relaxed`].\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub fn fetch_neg(&self, order: Ordering) -> $float_type {\n                self.inner.fetch_neg(order)\n            }\n\n            /// Computes the absolute value of the current value, and sets the\n            /// new value to the result.\n            ///\n            /// Returns the previous value.\n            ///\n            /// `fetch_abs` takes an [`Ordering`] argument which describes the memory ordering\n            /// of this operation. All ordering modes are possible. Note that using\n            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and\n            /// using [`Release`] makes the load part [`Relaxed`].\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub fn fetch_abs(&self, order: Ordering) -> $float_type {\n                self.inner.fetch_abs(order)\n            }\n            } // cfg_has_atomic_cas_or_amo32!\n\n            #[cfg(not(portable_atomic_no_const_raw_ptr_deref))]\n            doc_comment! {\n                concat!(\"Raw transmutation to `&\", stringify!($atomic_int_type), \"`.\n\nSee [`\", stringify!($float_type) ,\"::from_bits`] for some discussion of the\nportability of this operation (there are almost no issues).\n\nThis is `const fn` on Rust 1.58+.\"),\n                #[inline]\n                pub const fn as_bits(&self) -> &$atomic_int_type {\n                    self.inner.as_bits()\n                }\n            }\n            #[cfg(portable_atomic_no_const_raw_ptr_deref)]\n            doc_comment! {\n                concat!(\"Raw transmutation to `&\", stringify!($atomic_int_type), \"`.\n\nSee [`\", stringify!($float_type) ,\"::from_bits`] for some discussion of the\nportability of this operation (there are almost no issues).\n\nThis is `const fn` on Rust 1.58+.\"),\n                #[inline]\n                pub fn as_bits(&self) -> &$atomic_int_type {\n                    self.inner.as_bits()\n                }\n            }\n\n            const_fn! {\n                const_if: #[cfg(not(portable_atomic_no_const_raw_ptr_deref))];\n                /// Returns a mutable pointer to the underlying float.\n                ///\n                /// Returning an `*mut` pointer from a shared reference to this atomic is\n                /// safe because the atomic types work with interior mutability. Any use of\n                /// the returned raw pointer requires an `unsafe` block and has to uphold\n                /// the safety requirements. If there is concurrent access, note the following\n                /// additional safety requirements:\n                ///\n                /// - If this atomic type is [lock-free](Self::is_lock_free), any concurrent\n                ///   operations on it must be atomic.\n                /// - Otherwise, any concurrent operations on it must be compatible with\n                ///   operations performed by this atomic type.\n                ///\n                /// This is `const fn` on Rust 1.58+.\n                #[inline]\n                pub const fn as_ptr(&self) -> *mut $float_type {\n                    self.inner.as_ptr()\n                }\n            }\n        }\n        // See https://github.com/taiki-e/portable-atomic/issues/180\n        #[cfg(not(feature = \"require-cas\"))]\n        cfg_no_atomic_cas! {\n        #[doc(hidden)]\n        #[allow(unused_variables, clippy::unused_self, clippy::extra_unused_lifetimes)]\n        impl<'a> $atomic_type {\n            cfg_no_atomic_cas_or_amo32! {\n            #[inline]\n            pub fn swap(&self, val: $float_type, order: Ordering) -> $float_type\n            where\n                &'a Self: HasSwap,\n            {\n                unimplemented!()\n            }\n            } // cfg_no_atomic_cas_or_amo32!\n            #[inline]\n            pub fn compare_exchange(\n                &self,\n                current: $float_type,\n                new: $float_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$float_type, $float_type>\n            where\n                &'a Self: HasCompareExchange,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn compare_exchange_weak(\n                &self,\n                current: $float_type,\n                new: $float_type,\n                success: Ordering,\n                failure: Ordering,\n            ) -> Result<$float_type, $float_type>\n            where\n                &'a Self: HasCompareExchangeWeak,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn fetch_add(&self, val: $float_type, order: Ordering) -> $float_type\n            where\n                &'a Self: HasFetchAdd,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn fetch_sub(&self, val: $float_type, order: Ordering) -> $float_type\n            where\n                &'a Self: HasFetchSub,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn fetch_update<F>(\n                &self,\n                set_order: Ordering,\n                fetch_order: Ordering,\n                f: F,\n            ) -> Result<$float_type, $float_type>\n            where\n                F: FnMut($float_type) -> Option<$float_type>,\n                &'a Self: HasFetchUpdate,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn fetch_max(&self, val: $float_type, order: Ordering) -> $float_type\n            where\n                &'a Self: HasFetchMax,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn fetch_min(&self, val: $float_type, order: Ordering) -> $float_type\n            where\n                &'a Self: HasFetchMin,\n            {\n                unimplemented!()\n            }\n            cfg_no_atomic_cas_or_amo32! {\n            #[inline]\n            pub fn fetch_neg(&self, order: Ordering) -> $float_type\n            where\n                &'a Self: HasFetchNeg,\n            {\n                unimplemented!()\n            }\n            #[inline]\n            pub fn fetch_abs(&self, order: Ordering) -> $float_type\n            where\n                &'a Self: HasFetchAbs,\n            {\n                unimplemented!()\n            }\n            } // cfg_no_atomic_cas_or_amo32!\n        }\n        } // cfg_no_atomic_cas!\n    };\n}\n\ncfg_has_atomic_ptr! {\n    #[cfg(target_pointer_width = \"16\")]\n    atomic_int!(AtomicIsize, isize, 2, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8);\n    #[cfg(target_pointer_width = \"16\")]\n    atomic_int!(AtomicUsize, usize, 2, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8);\n    #[cfg(target_pointer_width = \"32\")]\n    atomic_int!(AtomicIsize, isize, 4, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32);\n    #[cfg(target_pointer_width = \"32\")]\n    atomic_int!(AtomicUsize, usize, 4, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32);\n    #[cfg(target_pointer_width = \"64\")]\n    atomic_int!(AtomicIsize, isize, 8, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32);\n    #[cfg(target_pointer_width = \"64\")]\n    atomic_int!(AtomicUsize, usize, 8, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32);\n    #[cfg(target_pointer_width = \"128\")]\n    atomic_int!(AtomicIsize, isize, 16, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32);\n    #[cfg(target_pointer_width = \"128\")]\n    atomic_int!(AtomicUsize, usize, 16, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32);\n}\n\ncfg_has_atomic_8! {\n    atomic_int!(AtomicI8, i8, 1, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8);\n    atomic_int!(AtomicU8, u8, 1, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8);\n}\ncfg_has_atomic_16! {\n    atomic_int!(AtomicI16, i16, 2, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8);\n    atomic_int!(AtomicU16, u16, 2, cfg_has_atomic_cas_or_amo8, cfg_no_atomic_cas_or_amo8,\n        #[cfg(all(feature = \"float\", portable_atomic_unstable_f16))] AtomicF16, f16);\n}\ncfg_has_atomic_32! {\n    atomic_int!(AtomicI32, i32, 4, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32);\n    atomic_int!(AtomicU32, u32, 4, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32,\n        #[cfg(feature = \"float\")] AtomicF32, f32);\n}\ncfg_has_atomic_64! {\n    atomic_int!(AtomicI64, i64, 8, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32);\n    atomic_int!(AtomicU64, u64, 8, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32,\n        #[cfg(feature = \"float\")] AtomicF64, f64);\n}\ncfg_has_atomic_128! {\n    atomic_int!(AtomicI128, i128, 16, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32);\n    atomic_int!(AtomicU128, u128, 16, cfg_has_atomic_cas_or_amo32, cfg_no_atomic_cas_or_amo32,\n        #[cfg(all(feature = \"float\", portable_atomic_unstable_f128))] AtomicF128, f128);\n}\n\n// See https://github.com/taiki-e/portable-atomic/issues/180\n#[cfg(not(feature = \"require-cas\"))]\ncfg_no_atomic_cas! {\ncfg_no_atomic_cas_or_amo32! {\n#[cfg(feature = \"float\")]\nuse self::diagnostic_helper::HasFetchAbs;\nuse self::diagnostic_helper::{\n    HasAnd, HasBitClear, HasBitSet, HasBitToggle, HasFetchAnd, HasFetchByteAdd, HasFetchByteSub,\n    HasFetchNot, HasFetchOr, HasFetchPtrAdd, HasFetchPtrSub, HasFetchXor, HasNot, HasOr, HasXor,\n};\n} // cfg_no_atomic_cas_or_amo32!\ncfg_no_atomic_cas_or_amo8! {\nuse self::diagnostic_helper::{HasAdd, HasSub, HasSwap};\n} // cfg_no_atomic_cas_or_amo8!\n#[cfg_attr(not(feature = \"float\"), allow(unused_imports))]\nuse self::diagnostic_helper::{\n    HasCompareExchange, HasCompareExchangeWeak, HasFetchAdd, HasFetchMax, HasFetchMin,\n    HasFetchNand, HasFetchNeg, HasFetchSub, HasFetchUpdate, HasNeg,\n};\n#[cfg_attr(\n    any(\n        all(\n            portable_atomic_no_atomic_load_store,\n            not(any(\n                target_arch = \"avr\",\n                target_arch = \"bpf\",\n                target_arch = \"msp430\",\n                target_arch = \"riscv32\",\n                target_arch = \"riscv64\",\n                feature = \"critical-section\",\n                portable_atomic_unsafe_assume_single_core,\n            )),\n        ),\n        not(feature = \"float\"),\n    ),\n    allow(dead_code, unreachable_pub)\n)]\n#[allow(unknown_lints, unnameable_types)] // Not public API. unnameable_types is available on Rust 1.79+\nmod diagnostic_helper {\n    cfg_no_atomic_cas_or_amo8! {\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`swap` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasSwap {}\n    } // cfg_no_atomic_cas_or_amo8!\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`compare_exchange` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasCompareExchange {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`compare_exchange_weak` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasCompareExchangeWeak {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_add` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchAdd {}\n    cfg_no_atomic_cas_or_amo8! {\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`add` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasAdd {}\n    } // cfg_no_atomic_cas_or_amo8!\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_sub` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchSub {}\n    cfg_no_atomic_cas_or_amo8! {\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`sub` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasSub {}\n    } // cfg_no_atomic_cas_or_amo8!\n    cfg_no_atomic_cas_or_amo32! {\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_ptr_add` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchPtrAdd {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_ptr_sub` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchPtrSub {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_byte_add` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchByteAdd {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_byte_sub` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchByteSub {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_and` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchAnd {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`and` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasAnd {}\n    } // cfg_no_atomic_cas_or_amo32!\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_nand` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchNand {}\n    cfg_no_atomic_cas_or_amo32! {\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_or` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchOr {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`or` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasOr {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_xor` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchXor {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`xor` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasXor {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_not` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchNot {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`not` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasNot {}\n    } // cfg_no_atomic_cas_or_amo32!\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_neg` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchNeg {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`neg` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasNeg {}\n    cfg_no_atomic_cas_or_amo32! {\n    #[cfg(feature = \"float\")]\n    #[cfg_attr(target_pointer_width = \"16\", allow(dead_code, unreachable_pub))]\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_abs` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchAbs {}\n    } // cfg_no_atomic_cas_or_amo32!\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_min` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchMin {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_max` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchMax {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`fetch_update` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasFetchUpdate {}\n    cfg_no_atomic_cas_or_amo32! {\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`bit_set` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasBitSet {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`bit_clear` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasBitClear {}\n    #[doc(hidden)]\n    #[cfg_attr(\n        not(portable_atomic_no_diagnostic_namespace),\n        diagnostic::on_unimplemented(\n            message = \"`bit_toggle` requires atomic CAS but not available on this target by default\",\n            label = \"this associated function is not available on this target by default\",\n            note = \"consider enabling one of the `critical-section` feature or `unsafe-assume-single-core` feature (or `portable_atomic_unsafe_assume_single_core` cfg)\",\n            note = \"see <https://docs.rs/portable-atomic/latest/portable_atomic/#optional-features> for more.\"\n        )\n    )]\n    pub trait HasBitToggle {}\n    } // cfg_no_atomic_cas_or_amo32!\n}\n} // cfg_no_atomic_cas!\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/tests/helper.rs",
      "sha256": "dc3d529032bd0a0ec4c9f25246504758042531109b3fd1a65a6be5bc1c4b7265",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![allow(unused_macros, clippy::undocumented_unsafe_blocks)]\n\nuse std::{\n    eprintln,\n    sync::atomic::{AtomicIsize, AtomicUsize, Ordering},\n};\n\nuse crossbeam_utils::thread;\n\nmacro_rules! __test_atomic_common {\n    ($atomic_type:ty, $value_type:ty) => {\n        use std::mem;\n        #[test]\n        fn assert_auto_traits() {\n            fn _assert<T: Send + Sync + Unpin + std::panic::UnwindSafe>() {}\n            _assert::<$atomic_type>();\n        }\n        #[test]\n        fn alignment() {\n            // https://github.com/rust-lang/rust/blob/1.84.0/library/core/tests/atomic.rs#L252\n            assert_eq!(mem::align_of::<$atomic_type>(), mem::size_of::<$atomic_type>());\n            assert_eq!(mem::size_of::<$atomic_type>(), mem::size_of::<$value_type>());\n        }\n        #[test]\n        fn is_lock_free() {\n            const IS_ALWAYS_LOCK_FREE: bool = <$atomic_type>::IS_ALWAYS_LOCK_FREE;\n            assert_eq!(IS_ALWAYS_LOCK_FREE, <$atomic_type>::IS_ALWAYS_LOCK_FREE);\n            let is_lock_free = <$atomic_type>::is_lock_free();\n            if IS_ALWAYS_LOCK_FREE {\n                // If is_always_lock_free is true, then is_lock_free must always be true.\n                assert!(is_lock_free);\n            }\n        }\n    };\n}\nmacro_rules! __test_atomic_pub_common {\n    ($atomic_type:ty, $value_type:ty) => {\n        #[test]\n        fn is_always_lock_free() {\n            assert_eq!(<$atomic_type>::IS_ALWAYS_LOCK_FREE, <$atomic_type>::is_always_lock_free());\n        }\n        #[test]\n        fn assert_ref_unwind_safe() {\n            #[cfg(not(all(portable_atomic_no_core_unwind_safe, not(feature = \"std\"))))]\n            static_assertions::assert_impl_all!($atomic_type: std::panic::RefUnwindSafe);\n            #[cfg(all(portable_atomic_no_core_unwind_safe, not(feature = \"std\")))]\n            static_assertions::assert_not_impl_all!($atomic_type: std::panic::RefUnwindSafe);\n        }\n    };\n}\n\nmacro_rules! __test_atomic_int_load_store {\n    ($atomic_type:ty, $int_type:ident, single_thread) => {\n        __test_atomic_common!($atomic_type, $int_type);\n        use crate::tests::helper::{self, *};\n        #[test]\n        fn accessor() {\n            let a = <$atomic_type>::new(10);\n            unsafe {\n                assert_eq!(*a.as_ptr(), 10);\n                *a.as_ptr() = 5;\n                assert_eq!(a.as_ptr() as *const (), &a as *const _ as *const ());\n                assert_eq!(*a.as_ptr(), 5);\n            }\n        }\n        // https://bugs.llvm.org/show_bug.cgi?id=37061\n        #[test]\n        fn static_load_only() {\n            static VAR: $atomic_type = <$atomic_type>::new(10);\n            for &order in &helper::LOAD_ORDERINGS {\n                assert_eq!(VAR.load(order), 10);\n            }\n        }\n        #[test]\n        fn load_store() {\n            static VAR: $atomic_type = <$atomic_type>::new(10);\n            test_load_ordering(&|order| {\n                VAR.load(order);\n            });\n            test_store_ordering(&|order| VAR.store(10, order));\n            for (&load_order, &store_order) in\n                helper::LOAD_ORDERINGS.iter().zip(&helper::STORE_ORDERINGS)\n            {\n                assert_eq!(VAR.load(load_order), 10);\n                VAR.store(5, store_order);\n                assert_eq!(VAR.load(load_order), 5);\n                VAR.store(10, store_order);\n                let a = <$atomic_type>::new(1);\n                assert_eq!(a.load(load_order), 1);\n                a.store($int_type::MIN, store_order);\n                assert_eq!(a.load(load_order), $int_type::MIN);\n                a.store($int_type::MAX, store_order);\n                assert_eq!(a.load(load_order), $int_type::MAX);\n            }\n        }\n    };\n    ($atomic_type:ty, $int_type:ident) => {\n        __test_atomic_int_load_store!($atomic_type, $int_type, single_thread);\n\n        use std::{collections::BTreeSet, eprintln, time::Instant, vec, vec::Vec};\n\n        use crossbeam_utils::thread;\n\n        #[test]\n        fn stress_load_store() {\n            let mut rng = fastrand::Rng::new();\n            let (iterations, threads) = stress_test_config(&mut rng);\n            let data1 = (0..iterations).map(|_| rng.$int_type(..)).collect::<Vec<_>>();\n            let set = data1.iter().copied().collect::<BTreeSet<_>>();\n            let a = <$atomic_type>::new(data1[rng.usize(0..iterations)]);\n            let now = &Instant::now();\n            thread::scope(|s| {\n                for _ in 0..threads {\n                    s.spawn(|_| {\n                        let mut rng = fastrand::Rng::new();\n                        let now = *now;\n                        for i in 0..iterations {\n                            a.store(data1[i], rand_store_ordering(&mut rng));\n                        }\n                        eprintln!(\"store end={:?}\", now.elapsed());\n                    });\n                    s.spawn(|_| {\n                        let mut rng = fastrand::Rng::new();\n                        let now = *now;\n                        let mut v = vec![0; iterations];\n                        for i in 0..iterations {\n                            v[i] = a.load(rand_load_ordering(&mut rng));\n                        }\n                        eprintln!(\"load end={:?}\", now.elapsed());\n                        for v in v {\n                            assert!(set.contains(&v), \"load unexpected={}\", v);\n                        }\n                    });\n                }\n            })\n            .unwrap();\n        }\n    };\n}\nmacro_rules! __test_atomic_float_load_store {\n    ($atomic_type:ty, $float_type:ident, single_thread) => {\n        __test_atomic_common!($atomic_type, $float_type);\n        use crate::tests::helper::{self, *};\n        #[test]\n        fn accessor() {\n            let a = <$atomic_type>::new(10.);\n            unsafe {\n                assert_eq!(*a.as_ptr(), 10.);\n                *a.as_ptr() = 5.;\n                assert_eq!(a.as_ptr() as *const (), &a as *const _ as *const ());\n                assert_eq!(*a.as_ptr(), 5.);\n            }\n        }\n        // https://bugs.llvm.org/show_bug.cgi?id=37061\n        #[test]\n        fn static_load_only() {\n            static VAR: $atomic_type = <$atomic_type>::new(10.);\n            for &order in &helper::LOAD_ORDERINGS {\n                assert_eq!(VAR.load(order), 10.);\n            }\n        }\n        #[test]\n        fn load_store() {\n            static VAR: $atomic_type = <$atomic_type>::new(10.);\n            test_load_ordering(&|order| {\n                VAR.load(order);\n            });\n            test_store_ordering(&|order| VAR.store(10., order));\n            for (&load_order, &store_order) in\n                helper::LOAD_ORDERINGS.iter().zip(&helper::STORE_ORDERINGS)\n            {\n                assert_eq!(VAR.load(load_order), 10.);\n                VAR.store(5., store_order);\n                assert_eq!(VAR.load(load_order), 5.);\n                VAR.store(10., store_order);\n                let a = <$atomic_type>::new(1.);\n                assert_eq!(a.load(load_order), 1.);\n                a.store(2., store_order);\n                assert_eq!(a.load(load_order), 2.);\n            }\n        }\n    };\n    ($atomic_type:ty, $float_type:ident) => {\n        __test_atomic_float_load_store!($atomic_type, $float_type, single_thread);\n        // TODO: multi thread\n    };\n}\nmacro_rules! __test_atomic_bool_load_store {\n    ($atomic_type:ty, single_thread) => {\n        __test_atomic_common!($atomic_type, bool);\n        use crate::tests::helper::{self, *};\n        #[test]\n        fn accessor() {\n            let a = <$atomic_type>::new(false);\n            unsafe {\n                assert_eq!(*a.as_ptr(), false);\n                *a.as_ptr() = true;\n                assert_eq!(a.as_ptr() as *const (), &a as *const _ as *const ());\n                assert_eq!(*a.as_ptr(), true);\n            }\n        }\n        // https://bugs.llvm.org/show_bug.cgi?id=37061\n        #[test]\n        fn static_load_only() {\n            static VAR: $atomic_type = <$atomic_type>::new(false);\n            for &order in &helper::LOAD_ORDERINGS {\n                assert_eq!(VAR.load(order), false);\n            }\n        }\n        #[test]\n        fn load_store() {\n            static VAR: $atomic_type = <$atomic_type>::new(false);\n            test_load_ordering(&|order| {\n                VAR.load(order);\n            });\n            test_store_ordering(&|order| VAR.store(false, order));\n            for (&load_order, &store_order) in\n                helper::LOAD_ORDERINGS.iter().zip(&helper::STORE_ORDERINGS)\n            {\n                assert_eq!(VAR.load(load_order), false);\n                VAR.store(true, store_order);\n                assert_eq!(VAR.load(load_order), true);\n                VAR.store(false, store_order);\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.load(load_order), true);\n                a.store(false, store_order);\n                assert_eq!(a.load(load_order), false);\n            }\n        }\n    };\n    ($atomic_type:ty) => {\n        __test_atomic_bool_load_store!($atomic_type, single_thread);\n        // TODO: multi thread\n    };\n}\nmacro_rules! __test_atomic_ptr_load_store {\n    ($atomic_type:ty, single_thread) => {\n        __test_atomic_common!($atomic_type, *mut u8);\n\n        use std::ptr;\n\n        use crate::tests::helper::{self, *};\n\n        #[test]\n        fn accessor() {\n            let mut v = 1;\n            let a = <$atomic_type>::new(ptr::null_mut());\n            unsafe {\n                assert!((*a.as_ptr()).is_null());\n                *a.as_ptr() = &mut v;\n                assert_eq!(a.as_ptr() as *const (), &a as *const _ as *const ());\n                assert!(!(*a.as_ptr()).is_null());\n            }\n        }\n        // https://bugs.llvm.org/show_bug.cgi?id=37061\n        #[test]\n        fn static_load_only() {\n            static VAR: $atomic_type = <$atomic_type>::new(ptr::null_mut());\n            for &order in &helper::LOAD_ORDERINGS {\n                assert_eq!(VAR.load(order), ptr::null_mut());\n            }\n        }\n        #[test]\n        fn load_store() {\n            static VAR: $atomic_type = <$atomic_type>::new(ptr::null_mut());\n            test_load_ordering(&|order| {\n                VAR.load(order);\n            });\n            test_store_ordering(&|order| VAR.store(ptr::null_mut(), order));\n            let mut v = 1_u8;\n            let p = &mut v as *mut u8;\n            for (&load_order, &store_order) in\n                helper::LOAD_ORDERINGS.iter().zip(&helper::STORE_ORDERINGS)\n            {\n                assert_eq!(VAR.load(load_order), ptr::null_mut());\n                VAR.store(p, store_order);\n                assert_eq!(VAR.load(load_order), p);\n                VAR.store(ptr::null_mut(), store_order);\n                let a = <$atomic_type>::new(p);\n                assert_eq!(a.load(load_order), p);\n                a.store(ptr::null_mut(), store_order);\n                assert_eq!(a.load(load_order), ptr::null_mut());\n            }\n        }\n    };\n    ($atomic_type:ty) => {\n        __test_atomic_ptr_load_store!($atomic_type, single_thread);\n        // TODO: multi thread\n    };\n}\n\nmacro_rules! __test_atomic_int {\n    ($atomic_type:ty, $int_type:ident, single_thread) => {\n        #[test]\n        fn swap() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(5);\n            test_swap_ordering(&|order| {\n                a.swap(5, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                assert_eq!(a.swap(10, order), 5);\n                assert_eq!(a.swap($int_type::MIN, order), 10);\n                assert_eq!(a.swap($int_type::MAX, order), $int_type::MIN);\n                assert_eq!(a.swap(5, order), $int_type::MAX);\n            }\n        }\n        #[test]\n        fn compare_exchange() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(5);\n            test_compare_exchange_ordering(&|success, failure| {\n                let _ = a.compare_exchange(5, 5, success, failure);\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(5);\n                assert_eq!(a.compare_exchange(5, 10, success, failure), Ok(5));\n                assert_eq!(a.load(Ordering::Relaxed), 10);\n                assert_eq!(a.compare_exchange(6, 12, success, failure), Err(10));\n                assert_eq!(a.load(Ordering::Relaxed), 10);\n            }\n        }\n        #[test]\n        fn compare_exchange_weak() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(4);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                mark_aligned_defined(&a);\n            }\n            test_compare_exchange_ordering(&|success, failure| {\n                let _ = a.compare_exchange_weak(4, 4, success, failure);\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(4);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.compare_exchange_weak(6, 8, success, failure), Err(4));\n                let mut old = a.load(Ordering::Relaxed);\n                loop {\n                    let new = old * 2;\n                    match a.compare_exchange_weak(old, new, success, failure) {\n                        Ok(_) => break,\n                        Err(x) => old = x,\n                    }\n                }\n                assert_eq!(a.load(Ordering::Relaxed), 8);\n            }\n        }\n        #[test]\n        fn fetch_add() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(0);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                mark_aligned_defined(&a);\n            }\n            test_swap_ordering(&|order| {\n                a.fetch_add(0, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_add(10, order), 0);\n                assert_eq!(a.load(Ordering::Relaxed), 10);\n                let a = <$atomic_type>::new($int_type::MAX);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_add(1, order), $int_type::MAX);\n                assert_eq!(a.load(Ordering::Relaxed), $int_type::MAX.wrapping_add(1));\n            }\n        }\n        #[test]\n        fn add() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(0);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                mark_aligned_defined(&a);\n            }\n            test_swap_ordering(&|order| a.add(0, order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                a.add(10, order);\n                assert_eq!(a.load(Ordering::Relaxed), 10);\n                let a = <$atomic_type>::new($int_type::MAX);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                a.add(1, order);\n                assert_eq!(a.load(Ordering::Relaxed), $int_type::MAX.wrapping_add(1));\n            }\n        }\n        #[test]\n        fn fetch_sub() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(20);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                mark_aligned_defined(&a);\n            }\n            test_swap_ordering(&|order| {\n                a.fetch_sub(0, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(20);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_sub(10, order), 20);\n                assert_eq!(a.load(Ordering::Relaxed), 10);\n                let a = <$atomic_type>::new($int_type::MIN);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_sub(1, order), $int_type::MIN);\n                assert_eq!(a.load(Ordering::Relaxed), $int_type::MIN.wrapping_sub(1));\n            }\n        }\n        #[test]\n        fn sub() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(20);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                mark_aligned_defined(&a);\n            }\n            test_swap_ordering(&|order| a.sub(0, order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(20);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                a.sub(10, order);\n                assert_eq!(a.load(Ordering::Relaxed), 10);\n                let a = <$atomic_type>::new($int_type::MIN);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                a.sub(1, order);\n                assert_eq!(a.load(Ordering::Relaxed), $int_type::MIN.wrapping_sub(1));\n            }\n        }\n        #[test]\n        fn fetch_and() {\n            let a = <$atomic_type>::new(0b101101);\n            test_swap_ordering(&|order| {\n                a.fetch_and(0b101101, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0b101101);\n                assert_eq!(a.fetch_and(0b110011, order), 0b101101);\n                assert_eq!(a.load(Ordering::Relaxed), 0b100001);\n            }\n        }\n        #[test]\n        fn and() {\n            let a = <$atomic_type>::new(0b101101);\n            test_swap_ordering(&|order| a.and(0b101101, order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0b101101);\n                a.and(0b110011, order);\n                assert_eq!(a.load(Ordering::Relaxed), 0b100001);\n            }\n        }\n        #[test]\n        fn fetch_nand() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") {\n                return;\n            }\n            let a = <$atomic_type>::new(0x13);\n            test_swap_ordering(&|order| {\n                a.fetch_nand(0x31, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0x13);\n                assert_eq!(a.fetch_nand(0x31, order), 0x13);\n                assert_eq!(a.load(Ordering::Relaxed), !(0x13 & 0x31));\n            }\n        }\n        #[test]\n        fn fetch_or() {\n            let a = <$atomic_type>::new(0b101101);\n            test_swap_ordering(&|order| {\n                a.fetch_or(0, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0b101101);\n                assert_eq!(a.fetch_or(0b110011, order), 0b101101);\n                assert_eq!(a.load(Ordering::Relaxed), 0b111111);\n            }\n        }\n        #[test]\n        fn or() {\n            let a = <$atomic_type>::new(0b101101);\n            test_swap_ordering(&|order| a.or(0, order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0b101101);\n                a.or(0b110011, order);\n                assert_eq!(a.load(Ordering::Relaxed), 0b111111);\n            }\n        }\n        #[test]\n        fn fetch_xor() {\n            let a = <$atomic_type>::new(0b101101);\n            test_swap_ordering(&|order| {\n                a.fetch_xor(0, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0b101101);\n                assert_eq!(a.fetch_xor(0b110011, order), 0b101101);\n                assert_eq!(a.load(Ordering::Relaxed), 0b011110);\n            }\n        }\n        #[test]\n        fn xor() {\n            let a = <$atomic_type>::new(0b101101);\n            test_swap_ordering(&|order| a.xor(0, order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0b101101);\n                a.xor(0b110011, order);\n                assert_eq!(a.load(Ordering::Relaxed), 0b011110);\n            }\n        }\n        #[test]\n        fn fetch_max() {\n            // TODO(gcc): failure: https://github.com/rust-lang/rustc_codegen_gcc/issues/821#issuecomment-3793567607\n            if option_env!(\"RUSTC_CODEGEN_GCC\").unwrap_or_default() == \"1\"\n                && $int_type::MIN == 0\n                && mem::size_of::<$int_type>() <= 8\n            {\n                return;\n            }\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(23);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                mark_aligned_defined(&a);\n            }\n            test_swap_ordering(&|order| {\n                a.fetch_max(23, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(23);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_max(22, order), 23);\n                assert_eq!(a.load(Ordering::Relaxed), 23);\n                assert_eq!(a.fetch_max(24, order), 23);\n                assert_eq!(a.load(Ordering::Relaxed), 24);\n                let a = <$atomic_type>::new(0);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_max(1, order), 0);\n                assert_eq!(a.load(Ordering::Relaxed), 1);\n                assert_eq!(a.fetch_max(0, order), 1);\n                assert_eq!(a.load(Ordering::Relaxed), 1);\n                let a = <$atomic_type>::new(!0);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_max(0, order), !0);\n                assert_eq!(a.load(Ordering::Relaxed), core::cmp::max(!0, 0));\n            }\n        }\n        #[test]\n        fn fetch_min() {\n            // TODO(gcc): failure: https://github.com/rust-lang/rustc_codegen_gcc/issues/821#issuecomment-3793567607\n            if option_env!(\"RUSTC_CODEGEN_GCC\").unwrap_or_default() == \"1\"\n                && $int_type::MIN == 0\n                && mem::size_of::<$int_type>() <= 8\n            {\n                return;\n            }\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(23);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                mark_aligned_defined(&a);\n            }\n            test_swap_ordering(&|order| {\n                a.fetch_min(23, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(23);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_min(24, order), 23);\n                assert_eq!(a.load(Ordering::Relaxed), 23);\n                assert_eq!(a.fetch_min(22, order), 23);\n                assert_eq!(a.load(Ordering::Relaxed), 22);\n                let a = <$atomic_type>::new(1);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_min(0, order), 1);\n                assert_eq!(a.load(Ordering::Relaxed), 0);\n                assert_eq!(a.fetch_min(1, order), 0);\n                assert_eq!(a.load(Ordering::Relaxed), 0);\n                let a = <$atomic_type>::new(!0);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_min(0, order), !0);\n                assert_eq!(a.load(Ordering::Relaxed), core::cmp::min(!0, 0));\n            }\n        }\n        #[test]\n        fn fetch_not() {\n            let a = <$atomic_type>::new(1);\n            test_swap_ordering(&|order| {\n                a.fetch_not(order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(1);\n                assert_eq!(a.fetch_not(order), 1);\n                assert_eq!(a.load(Ordering::Relaxed), !1);\n            }\n        }\n        #[test]\n        fn not() {\n            let a = <$atomic_type>::new(1);\n            test_swap_ordering(&|order| a.not(order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(1);\n                a.not(order);\n                assert_eq!(a.load(Ordering::Relaxed), !1);\n            }\n        }\n        #[test]\n        fn fetch_neg() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(5);\n            test_swap_ordering(&|order| {\n                a.fetch_neg(order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(5);\n                assert_eq!(a.fetch_neg(order), 5);\n                assert_eq!(a.load(Ordering::Relaxed), <$int_type>::wrapping_neg(5));\n                assert_eq!(a.fetch_neg(order), <$int_type>::wrapping_neg(5));\n                assert_eq!(a.load(Ordering::Relaxed), 5);\n                let a = <$atomic_type>::new(<$int_type>::MIN);\n                assert_eq!(a.fetch_neg(order), <$int_type>::MIN);\n                assert_eq!(a.load(Ordering::Relaxed), <$int_type>::MIN.wrapping_neg());\n                assert_eq!(a.fetch_neg(order), <$int_type>::MIN.wrapping_neg());\n                assert_eq!(a.load(Ordering::Relaxed), <$int_type>::MIN);\n            }\n        }\n        #[test]\n        fn neg() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(5);\n            test_swap_ordering(&|order| a.neg(order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(5);\n                a.neg(order);\n                assert_eq!(a.load(Ordering::Relaxed), <$int_type>::wrapping_neg(5));\n                a.neg(order);\n                assert_eq!(a.load(Ordering::Relaxed), 5);\n                let a = <$atomic_type>::new(<$int_type>::MIN);\n                a.neg(order);\n                assert_eq!(a.load(Ordering::Relaxed), <$int_type>::MIN.wrapping_neg());\n                a.neg(order);\n                assert_eq!(a.load(Ordering::Relaxed), <$int_type>::MIN);\n            }\n        }\n        #[test]\n        fn bit_set() {\n            let a = <$atomic_type>::new(0b0001);\n            test_swap_ordering(&|order| assert!(a.bit_set(0, order)));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0b0000);\n                assert!(!a.bit_set(0, order));\n                assert_eq!(a.load(Ordering::Relaxed), 0b0001);\n                assert!(a.bit_set(0, order));\n                assert_eq!(a.load(Ordering::Relaxed), 0b0001);\n            }\n        }\n        #[test]\n        fn bit_clear() {\n            let a = <$atomic_type>::new(0b0000);\n            test_swap_ordering(&|order| assert!(!a.bit_clear(0, order)));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0b0001);\n                assert!(a.bit_clear(0, order));\n                assert_eq!(a.load(Ordering::Relaxed), 0b0000);\n                assert!(!a.bit_clear(0, order));\n                assert_eq!(a.load(Ordering::Relaxed), 0b0000);\n            }\n        }\n        #[test]\n        fn bit_toggle() {\n            let a = <$atomic_type>::new(0b0000);\n            test_swap_ordering(&|order| {\n                a.bit_toggle(0, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0b0000);\n                assert!(!a.bit_toggle(0, order));\n                assert_eq!(a.load(Ordering::Relaxed), 0b0001);\n                assert!(a.bit_toggle(0, order));\n                assert_eq!(a.load(Ordering::Relaxed), 0b0000);\n            }\n        }\n        ::quickcheck::quickcheck! {\n            fn quickcheck_swap(x: $int_type, y: $int_type) -> bool {\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.swap(y, order), x);\n                    assert_eq!(a.swap(x, order), y);\n                }\n                true\n            }\n            fn quickcheck_compare_exchange(x: $int_type, y: $int_type) -> bool {\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                #[cfg(all(\n                    target_arch = \"arm\",\n                    not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n                ))]\n                {\n                    // TODO: LLVM bug:\n                    // https://github.com/llvm/llvm-project/issues/61880\n                    // https://github.com/taiki-e/portable-atomic/issues/2\n                    if mem::size_of::<$int_type>() <= 2 {\n                        return true;\n                    }\n                }\n                let mut rng = fastrand::Rng::new();\n                let z = loop {\n                    let z = rng.$int_type(..);\n                    if z != y {\n                        break z;\n                    }\n                };\n                for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.compare_exchange(x, y, success, failure).unwrap(), x);\n                    assert_eq!(a.load(Ordering::Relaxed), y);\n                    assert_eq!(a.compare_exchange(z, x, success, failure).unwrap_err(), y);\n                    assert_eq!(a.load(Ordering::Relaxed), y);\n                }\n                true\n            }\n            fn quickcheck_fetch_add(x: $int_type, y: $int_type) -> bool {\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    assert_eq!(a.fetch_add(y, order), x);\n                    assert_eq!(a.load(Ordering::Relaxed), x.wrapping_add(y));\n                    let a = <$atomic_type>::new(y);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    assert_eq!(a.fetch_add(x, order), y);\n                    assert_eq!(a.load(Ordering::Relaxed), y.wrapping_add(x));\n                }\n                true\n            }\n            fn quickcheck_add(x: $int_type, y: $int_type) -> bool {\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    a.add(y, order);\n                    assert_eq!(a.load(Ordering::Relaxed), x.wrapping_add(y));\n                    let a = <$atomic_type>::new(y);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    a.add(x, order);\n                    assert_eq!(a.load(Ordering::Relaxed), y.wrapping_add(x));\n                }\n                true\n            }\n            fn quickcheck_fetch_sub(x: $int_type, y: $int_type) -> bool {\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    assert_eq!(a.fetch_sub(y, order), x);\n                    assert_eq!(a.load(Ordering::Relaxed), x.wrapping_sub(y));\n                    let a = <$atomic_type>::new(y);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    assert_eq!(a.fetch_sub(x, order), y);\n                    assert_eq!(a.load(Ordering::Relaxed), y.wrapping_sub(x));\n                }\n                true\n            }\n            fn quickcheck_sub(x: $int_type, y: $int_type) -> bool {\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    a.sub(y, order);\n                    assert_eq!(a.load(Ordering::Relaxed), x.wrapping_sub(y));\n                    let a = <$atomic_type>::new(y);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    a.sub(x, order);\n                    assert_eq!(a.load(Ordering::Relaxed), y.wrapping_sub(x));\n                }\n                true\n            }\n            fn quickcheck_fetch_and(x: $int_type, y: $int_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_and(y, order), x);\n                    assert_eq!(a.load(Ordering::Relaxed), x & y);\n                    let a = <$atomic_type>::new(y);\n                    assert_eq!(a.fetch_and(x, order), y);\n                    assert_eq!(a.load(Ordering::Relaxed), y & x);\n                }\n                true\n            }\n            fn quickcheck_and(x: $int_type, y: $int_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    a.and(y, order);\n                    assert_eq!(a.load(Ordering::Relaxed), x & y);\n                    let a = <$atomic_type>::new(y);\n                    a.and(x, order);\n                    assert_eq!(a.load(Ordering::Relaxed), y & x);\n                }\n                true\n            }\n            fn quickcheck_fetch_nand(x: $int_type, y: $int_type) -> bool {\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") {\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_nand(y, order), x);\n                    assert_eq!(a.load(Ordering::Relaxed), !(x & y));\n                    let a = <$atomic_type>::new(y);\n                    assert_eq!(a.fetch_nand(x, order), y);\n                    assert_eq!(a.load(Ordering::Relaxed), !(y & x));\n                }\n                true\n            }\n            fn quickcheck_fetch_or(x: $int_type, y: $int_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_or(y, order), x);\n                    assert_eq!(a.load(Ordering::Relaxed), x | y);\n                    let a = <$atomic_type>::new(y);\n                    assert_eq!(a.fetch_or(x, order), y);\n                    assert_eq!(a.load(Ordering::Relaxed), y | x);\n                }\n                true\n            }\n            fn quickcheck_or(x: $int_type, y: $int_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    a.or(y, order);\n                    assert_eq!(a.load(Ordering::Relaxed), x | y);\n                    let a = <$atomic_type>::new(y);\n                    a.or(x, order);\n                    assert_eq!(a.load(Ordering::Relaxed), y | x);\n                }\n                true\n            }\n            fn quickcheck_fetch_xor(x: $int_type, y: $int_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_xor(y, order), x);\n                    assert_eq!(a.load(Ordering::Relaxed), x ^ y);\n                    let a = <$atomic_type>::new(y);\n                    assert_eq!(a.fetch_xor(x, order), y);\n                    assert_eq!(a.load(Ordering::Relaxed), y ^ x);\n                }\n                true\n            }\n            fn quickcheck_xor(x: $int_type, y: $int_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    a.xor(y, order);\n                    assert_eq!(a.load(Ordering::Relaxed), x ^ y);\n                    let a = <$atomic_type>::new(y);\n                    a.xor(x, order);\n                    assert_eq!(a.load(Ordering::Relaxed), y ^ x);\n                }\n                true\n            }\n            fn quickcheck_fetch_max(x: $int_type, y: $int_type) -> bool {\n                // TODO(gcc): failure: https://github.com/rust-lang/rustc_codegen_gcc/issues/821#issuecomment-3793567607\n                if option_env!(\"RUSTC_CODEGEN_GCC\").unwrap_or_default() == \"1\"\n                    && $int_type::MIN == 0\n                    && mem::size_of::<$int_type>() <= 8\n                {\n                    return true;\n                }\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    assert_eq!(a.fetch_max(y, order), x);\n                    assert_eq!(a.load(Ordering::Relaxed), core::cmp::max(x, y));\n                    let a = <$atomic_type>::new(y);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    assert_eq!(a.fetch_max(x, order), y);\n                    assert_eq!(a.load(Ordering::Relaxed), core::cmp::max(y, x));\n                }\n                true\n            }\n            fn quickcheck_fetch_min(x: $int_type, y: $int_type) -> bool {\n                // TODO(gcc): failure: https://github.com/rust-lang/rustc_codegen_gcc/issues/821#issuecomment-3793567607\n                if option_env!(\"RUSTC_CODEGEN_GCC\").unwrap_or_default() == \"1\"\n                    && $int_type::MIN == 0\n                    && mem::size_of::<$int_type>() <= 8\n                {\n                    return true;\n                }\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    assert_eq!(a.fetch_min(y, order), x);\n                    assert_eq!(a.load(Ordering::Relaxed), core::cmp::min(x, y));\n                    let a = <$atomic_type>::new(y);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                        mark_aligned_defined(&a);\n                    }\n                    assert_eq!(a.fetch_min(x, order), y);\n                    assert_eq!(a.load(Ordering::Relaxed), core::cmp::min(y, x));\n                }\n                true\n            }\n            fn quickcheck_fetch_not(x: $int_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_not(order), x);\n                    assert_eq!(a.load(Ordering::Relaxed), !x);\n                    assert_eq!(a.fetch_not(order), !x);\n                    assert_eq!(a.load(Ordering::Relaxed), x);\n                }\n                true\n            }\n            fn quickcheck_not(x: $int_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    a.not(order);\n                    assert_eq!(a.load(Ordering::Relaxed), !x);\n                    a.not(order);\n                    assert_eq!(a.load(Ordering::Relaxed), x);\n                }\n                true\n            }\n            fn quickcheck_fetch_neg(x: $int_type) -> bool {\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                #[cfg(all(\n                    target_arch = \"arm\",\n                    not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n                ))]\n                {\n                    // TODO: LLVM bug:\n                    // https://github.com/llvm/llvm-project/issues/61880\n                    // https://github.com/taiki-e/portable-atomic/issues/2\n                    if mem::size_of::<$int_type>() <= 2 {\n                        return true;\n                    }\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_neg(order), x);\n                    assert_eq!(a.load(Ordering::Relaxed), x.wrapping_neg());\n                    assert_eq!(a.fetch_neg(order), x.wrapping_neg());\n                    assert_eq!(a.load(Ordering::Relaxed), x);\n                }\n                true\n            }\n            fn quickcheck_neg(x: $int_type) -> bool {\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    a.neg(order);\n                    assert_eq!(a.load(Ordering::Relaxed), x.wrapping_neg());\n                    a.neg(order);\n                    assert_eq!(a.load(Ordering::Relaxed), x);\n                }\n                true\n            }\n            fn quickcheck_bit_set(x: $int_type, bit: u32) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    let b = a.bit_set(bit, order);\n                    let mask = <$int_type>::wrapping_shl(1, bit);\n                    assert_eq!(a.load(Ordering::Relaxed), x | mask);\n                    assert_eq!(b, x & mask != 0);\n                }\n                true\n            }\n            fn quickcheck_bit_clear(x: $int_type, bit: u32) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    let b = a.bit_clear(bit, order);\n                    let mask = <$int_type>::wrapping_shl(1, bit);\n                    assert_eq!(a.load(Ordering::Relaxed), x & !mask);\n                    assert_eq!(b, x & mask != 0);\n                }\n                true\n            }\n            fn quickcheck_bit_toggle(x: $int_type, bit: u32) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    let b = a.bit_toggle(bit, order);\n                    let mask = <$int_type>::wrapping_shl(1, bit);\n                    assert_eq!(a.load(Ordering::Relaxed), x ^ mask);\n                    assert_eq!(b, x & mask != 0);\n                }\n                true\n            }\n        }\n    };\n    ($atomic_type:ty, $int_type:ident) => {\n        __test_atomic_int!($atomic_type, $int_type, single_thread);\n\n        #[test]\n        fn stress_swap() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let mut rng = fastrand::Rng::new();\n            let (iterations, threads) = stress_test_config(&mut rng);\n            let data1 = &(0..threads)\n                .map(|_| (0..iterations).map(|_| rng.$int_type(..)).collect::<Vec<_>>())\n                .collect::<Vec<_>>();\n            let data2 = &(0..threads)\n                .map(|_| (0..iterations).map(|_| rng.$int_type(..)).collect::<Vec<_>>())\n                .collect::<Vec<_>>();\n            let set = &data1\n                .iter()\n                .flat_map(|v| v.iter().copied())\n                .chain(data2.iter().flat_map(|v| v.iter().copied()))\n                .collect::<BTreeSet<_>>();\n            let a = &<$atomic_type>::new(data2[0][rng.usize(0..iterations)]);\n            let now = &Instant::now();\n            thread::scope(|s| {\n                for thread in 0..threads {\n                    if thread % 2 == 0 {\n                        s.spawn(move |_| {\n                            let mut rng = fastrand::Rng::new();\n                            let now = *now;\n                            for i in 0..iterations {\n                                a.store(data1[thread][i], rand_store_ordering(&mut rng));\n                            }\n                            eprintln!(\"store end={:?}\", now.elapsed());\n                        });\n                    } else {\n                        s.spawn(|_| {\n                            let mut rng = fastrand::Rng::new();\n                            let now = *now;\n                            let mut v = vec![0; iterations];\n                            for i in 0..iterations {\n                                v[i] = a.load(rand_load_ordering(&mut rng));\n                            }\n                            eprintln!(\"load end={:?}\", now.elapsed());\n                            for v in v {\n                                assert!(set.contains(&v), \"load unexpected={}\", v);\n                            }\n                        });\n                    }\n                    s.spawn(move |_| {\n                        let mut rng = fastrand::Rng::new();\n                        let now = *now;\n                        let mut v = vec![0; iterations];\n                        for i in 0..iterations {\n                            v[i] = a.swap(data2[thread][i], rand_swap_ordering(&mut rng));\n                        }\n                        eprintln!(\"swap end={:?}\", now.elapsed());\n                        for v in v {\n                            assert!(set.contains(&v), \"swap unexpected={}\", v);\n                        }\n                    });\n                }\n            })\n            .unwrap();\n        }\n        #[test]\n        fn stress_compare_exchange() {\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let mut rng = fastrand::Rng::new();\n            let (iterations, threads) = stress_test_config(&mut rng);\n            let data1 = &(0..threads)\n                .map(|_| (0..iterations).map(|_| rng.$int_type(..)).collect::<Vec<_>>())\n                .collect::<Vec<_>>();\n            let data2 = &(0..threads)\n                .map(|_| (0..iterations).map(|_| rng.$int_type(..)).collect::<Vec<_>>())\n                .collect::<Vec<_>>();\n            let set = &data1\n                .iter()\n                .flat_map(|v| v.iter().copied())\n                .chain(data2.iter().flat_map(|v| v.iter().copied()))\n                .collect::<BTreeSet<_>>();\n            let a = &<$atomic_type>::new(data2[0][rng.usize(0..iterations)]);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                mark_aligned_defined(a);\n            }\n            let now = &Instant::now();\n            thread::scope(|s| {\n                for thread in 0..threads {\n                    s.spawn(move |_| {\n                        let mut rng = fastrand::Rng::new();\n                        let now = *now;\n                        for i in 0..iterations {\n                            a.store(data1[thread][i], rand_store_ordering(&mut rng));\n                        }\n                        eprintln!(\"store end={:?}\", now.elapsed());\n                    });\n                    s.spawn(|_| {\n                        let mut rng = fastrand::Rng::new();\n                        let now = *now;\n                        let mut v = vec![data2[0][0]; iterations];\n                        for i in 0..iterations {\n                            v[i] = a.load(rand_load_ordering(&mut rng));\n                        }\n                        eprintln!(\"load end={:?}\", now.elapsed());\n                        for v in v {\n                            assert!(set.contains(&v), \"load unexpected={}\", v);\n                        }\n                    });\n                    s.spawn(move |_| {\n                        let mut rng = fastrand::Rng::new();\n                        let now = *now;\n                        let mut v = vec![data2[0][0]; iterations];\n                        for i in 0..iterations {\n                            let old = if i % 2 == 0 {\n                                rng.$int_type(..)\n                            } else {\n                                a.load(Ordering::Relaxed)\n                            };\n                            let new = data2[thread][i];\n                            let o = rand_compare_exchange_ordering(&mut rng);\n                            match a.compare_exchange(old, new, o.0, o.1) {\n                                Ok(r) => assert_eq!(old, r),\n                                Err(r) => v[i] = r,\n                            }\n                        }\n                        eprintln!(\"compare_exchange end={:?}\", now.elapsed());\n                        for v in v {\n                            assert!(set.contains(&v), \"cas unexpected={}\", v);\n                        }\n                    });\n                }\n            })\n            .unwrap();\n        }\n    };\n}\nmacro_rules! __test_atomic_float {\n    ($atomic_type:ty, $float_type:ident, single_thread) => {\n        #[test]\n        fn swap() {\n            let a = <$atomic_type>::new(5.);\n            test_swap_ordering(&|order| { a.swap(5., order); });\n            for &order in &helper::SWAP_ORDERINGS {\n                assert_eq!(a.swap(10., order), 5.);\n                assert_eq!(a.swap(5., order), 10.);\n            }\n        }\n        #[test]\n        fn compare_exchange() {\n            let a = <$atomic_type>::new(5.);\n            test_compare_exchange_ordering(&|success, failure| {\n                let _ = a.compare_exchange(5., 5., success, failure);\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(5.);\n                assert_eq!(a.compare_exchange(5., 10., success, failure), Ok(5.));\n                assert_eq!(a.load(Ordering::Relaxed), 10.);\n                assert_eq!(a.compare_exchange(6., 12., success, failure), Err(10.));\n                assert_eq!(a.load(Ordering::Relaxed), 10.);\n            }\n        }\n        #[test]\n        fn compare_exchange_weak() {\n            let a = <$atomic_type>::new(4.);\n            test_compare_exchange_ordering(&|success, failure| {\n                let _ = a.compare_exchange_weak(4., 4., success, failure);\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(4.);\n                assert_eq!(a.compare_exchange_weak(6., 8., success, failure), Err(4.));\n                let mut old = a.load(Ordering::Relaxed);\n                loop {\n                    let new = old * 2.;\n                    match a.compare_exchange_weak(old, new, success, failure) {\n                        Ok(_) => break,\n                        Err(x) => old = x,\n                    }\n                }\n                assert_eq!(a.load(Ordering::Relaxed), 8.);\n            }\n        }\n        #[test]\n        fn fetch_add() {\n            let a = <$atomic_type>::new(0.);\n            test_swap_ordering(&|order| { a.fetch_add(0., order); });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(0.);\n                assert_eq!(a.fetch_add(10., order), 0.);\n                assert_eq!(a.load(Ordering::Relaxed), 10.);\n                let a = <$atomic_type>::new($float_type::MAX);\n                assert_eq!(a.fetch_add(1., order), $float_type::MAX);\n                assert_eq!(a.load(Ordering::Relaxed), $float_type::MAX + 1.);\n            }\n        }\n        #[test]\n        fn fetch_sub() {\n            let a = <$atomic_type>::new(20.);\n            test_swap_ordering(&|order| { a.fetch_sub(0., order); });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(20.);\n                assert_eq!(a.fetch_sub(10., order), 20.);\n                assert_eq!(a.load(Ordering::Relaxed), 10.);\n                let a = <$atomic_type>::new($float_type::MIN);\n                assert_eq!(a.fetch_sub(1., order), $float_type::MIN);\n                assert_eq!(a.load(Ordering::Relaxed), $float_type::MIN - 1.);\n            }\n        }\n        #[test]\n        fn fetch_max() {\n            if mem::size_of::<$float_type>() == 16\n                && cfg!(any(\n                    target_arch = \"arm\",\n                    target_arch = \"mips\",\n                    target_arch = \"mips32r6\",\n                    target_arch = \"mips64\",\n                    target_arch = \"mips64r6\",\n                    target_vendor = \"apple\",\n                    windows,\n                ))\n            {\n                // TODO(f128):\n                return;\n            }\n            let a = <$atomic_type>::new(23.);\n            test_swap_ordering(&|order| { a.fetch_max(23., order); });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(23.);\n                assert_eq!(a.fetch_max(22., order), 23.);\n                assert_eq!(a.load(Ordering::Relaxed), 23.);\n                assert_eq!(a.fetch_max(24., order), 23.);\n                assert_eq!(a.load(Ordering::Relaxed), 24.);\n            }\n        }\n        #[test]\n        fn fetch_min() {\n            if mem::size_of::<$float_type>() == 16\n                && cfg!(any(\n                    target_arch = \"arm\",\n                    target_arch = \"mips\",\n                    target_arch = \"mips32r6\",\n                    target_arch = \"mips64\",\n                    target_arch = \"mips64r6\",\n                    target_vendor = \"apple\",\n                    windows,\n                ))\n            {\n                // TODO(f128):\n                return;\n            }\n            let a = <$atomic_type>::new(23.);\n            test_swap_ordering(&|order| { a.fetch_min(23., order); });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(23.);\n                assert_eq!(a.fetch_min(24., order), 23.);\n                assert_eq!(a.load(Ordering::Relaxed), 23.);\n                assert_eq!(a.fetch_min(22., order), 23.);\n                assert_eq!(a.load(Ordering::Relaxed), 22.);\n            }\n        }\n        #[test]\n        fn fetch_neg() {\n            let a = <$atomic_type>::new(5.);\n            test_swap_ordering(&|order| { a.fetch_neg(order); });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(5.);\n                assert_eq!(a.fetch_neg(order), 5.);\n                assert_eq!(a.load(Ordering::Relaxed), -5.);\n                assert_eq!(a.fetch_neg(order), -5.);\n                assert_eq!(a.load(Ordering::Relaxed), 5.);\n            }\n        }\n        #[test]\n        fn fetch_abs() {\n            let a = <$atomic_type>::new(23.);\n            test_swap_ordering(&|order| { a.fetch_abs(order); });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(-23.);\n                assert_eq!(a.fetch_abs(order), -23.);\n                assert_eq!(a.load(Ordering::Relaxed), 23.);\n                assert_eq!(a.fetch_abs(order), 23.);\n                assert_eq!(a.load(Ordering::Relaxed), 23.);\n            }\n        }\n        ::quickcheck::quickcheck! {\n            fn quickcheck_swap(x: $float_type, y: $float_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_float_op_eq!(a.swap(y, order), x);\n                    assert_float_op_eq!(a.swap(x, order), y);\n                }\n                true\n            }\n            fn quickcheck_compare_exchange(x: $float_type, y: $float_type) -> bool {\n                #[cfg(all(\n                    target_arch = \"arm\",\n                    not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n                ))]\n                {\n                    // TODO: LLVM bug:\n                    // https://github.com/llvm/llvm-project/issues/61880\n                    // https://github.com/taiki-e/portable-atomic/issues/2\n                    if mem::size_of::<$float_type>() <= 2 {\n                        return true;\n                    }\n                }\n                let mut rng = fastrand::Rng::new();\n                let z = loop {\n                    let z = float_rand::$float_type(&mut rng);\n                    if z != y {\n                        break z;\n                    }\n                };\n                for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_float_op_eq!(a.compare_exchange(x, y, success, failure).unwrap(), x);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), y);\n                    assert_float_op_eq!(\n                        a.compare_exchange(z, x, success, failure).unwrap_err(),\n                        y,\n                    );\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), y);\n                }\n                true\n            }\n            fn quickcheck_fetch_add(x: $float_type, y: $float_type) -> bool {\n                if cfg!(all(not(debug_assertions), target_arch = \"x86\", not(target_feature = \"sse2\"))) {\n                    // TODO: rustc bug: https://github.com/rust-lang/rust/issues/114479\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_float_op_eq!(a.fetch_add(y, order), x);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), x + y);\n                    let a = <$atomic_type>::new(y);\n                    assert_float_op_eq!(a.fetch_add(x, order), y);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), y + x);\n                }\n                true\n            }\n            fn quickcheck_fetch_sub(x: $float_type, y: $float_type) -> bool {\n                if cfg!(all(not(debug_assertions), target_arch = \"x86\", not(target_feature = \"sse2\"))) {\n                    // TODO: rustc bug: https://github.com/rust-lang/rust/issues/114479\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_float_op_eq!(a.fetch_sub(y, order), x);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), x - y);\n                    let a = <$atomic_type>::new(y);\n                    assert_float_op_eq!(a.fetch_sub(x, order), y);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), y - x);\n                }\n                true\n            }\n            fn quickcheck_fetch_max(x: $float_type, y: $float_type) -> bool {\n                if mem::size_of::<$float_type>() == 16\n                    && cfg!(any(\n                        target_arch = \"arm\",\n                        target_arch = \"mips\",\n                        target_arch = \"mips32r6\",\n                        target_arch = \"mips64\",\n                        target_arch = \"mips64r6\",\n                        target_vendor = \"apple\",\n                        windows,\n                    ))\n                {\n                    // TODO(f128):\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_float_op_eq!(a.fetch_max(y, order), x);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), x.max(y));\n                    let a = <$atomic_type>::new(y);\n                    assert_float_op_eq!(a.fetch_max(x, order), y);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), y.max(x));\n                }\n                true\n            }\n            fn quickcheck_fetch_min(x: $float_type, y: $float_type) -> bool {\n                if mem::size_of::<$float_type>() == 16\n                    && cfg!(any(\n                        target_arch = \"arm\",\n                        target_arch = \"mips\",\n                        target_arch = \"mips32r6\",\n                        target_arch = \"mips64\",\n                        target_arch = \"mips64r6\",\n                        target_vendor = \"apple\",\n                        windows,\n                    ))\n                {\n                    // TODO(f128):\n                    return true;\n                }\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_float_op_eq!(a.fetch_min(y, order), x);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), x.min(y));\n                    let a = <$atomic_type>::new(y);\n                    assert_float_op_eq!(a.fetch_min(x, order), y);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), y.min(x));\n                }\n                true\n            }\n            fn quickcheck_fetch_neg(x: $float_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_float_op_eq!(a.fetch_neg(order), x);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), -x);\n                    assert_float_op_eq!(a.fetch_neg(order), -x);\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), x);\n                }\n                true\n            }\n            fn quickcheck_fetch_abs(x: $float_type) -> bool {\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_float_op_eq!(a.fetch_abs(order), x);\n                    assert_float_op_eq!(a.fetch_abs(order), x.abs());\n                    assert_float_op_eq!(a.load(Ordering::Relaxed), x.abs());\n                }\n                true\n            }\n        }\n    };\n    ($atomic_type:ty, $float_type:ident) => {\n        __test_atomic_float!($atomic_type, $float_type, single_thread);\n        // TODO: multi thread\n    };\n}\nmacro_rules! __test_atomic_bool {\n    ($atomic_type:ty, single_thread) => {\n        #[test]\n        fn swap() {\n            let a = <$atomic_type>::new(true);\n            test_swap_ordering(&|order| {\n                a.swap(true, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                assert_eq!(a.swap(true, order), true);\n                assert_eq!(a.swap(false, order), true);\n                assert_eq!(a.swap(false, order), false);\n                assert_eq!(a.swap(true, order), false);\n            }\n        }\n        #[test]\n        fn compare_exchange() {\n            let a = <$atomic_type>::new(true);\n            test_compare_exchange_ordering(&|success, failure| {\n                let _ = a.compare_exchange(true, true, success, failure);\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.compare_exchange(true, false, success, failure), Ok(true));\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                assert_eq!(a.compare_exchange(true, true, success, failure), Err(false));\n                assert_eq!(a.load(Ordering::Relaxed), false);\n            }\n        }\n        #[test]\n        fn compare_exchange_weak() {\n            let a = <$atomic_type>::new(false);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS {\n                mark_aligned_defined(&a);\n            }\n            test_compare_exchange_ordering(&|success, failure| {\n                let _ = a.compare_exchange_weak(false, false, success, failure);\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(false);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.compare_exchange_weak(true, true, success, failure), Err(false));\n                let mut old = a.load(Ordering::Relaxed);\n                let new = true;\n                loop {\n                    match a.compare_exchange_weak(old, new, success, failure) {\n                        Ok(_) => break,\n                        Err(x) => old = x,\n                    }\n                }\n                assert_eq!(a.load(Ordering::Relaxed), true);\n            }\n        }\n        #[test]\n        fn fetch_and() {\n            let a = <$atomic_type>::new(true);\n            test_swap_ordering(&|order| assert_eq!(a.fetch_and(true, order), true));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.fetch_and(false, order), true);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.fetch_and(true, order), true);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n                let a = <$atomic_type>::new(false);\n                assert_eq!(a.fetch_and(false, order), false);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                assert_eq!(a.fetch_and(true, order), false);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n            }\n        }\n        #[test]\n        fn and() {\n            let a = <$atomic_type>::new(true);\n            test_swap_ordering(&|order| a.and(true, order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(true);\n                a.and(false, order);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(true);\n                a.and(true, order);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n                let a = <$atomic_type>::new(false);\n                a.and(false, order);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                a.and(true, order);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n            }\n        }\n        #[test]\n        fn fetch_or() {\n            let a = <$atomic_type>::new(true);\n            test_swap_ordering(&|order| assert_eq!(a.fetch_or(false, order), true));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.fetch_or(false, order), true);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.fetch_or(true, order), true);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n                let a = <$atomic_type>::new(false);\n                assert_eq!(a.fetch_or(false, order), false);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                assert_eq!(a.fetch_or(true, order), false);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n            }\n        }\n        #[test]\n        fn or() {\n            let a = <$atomic_type>::new(true);\n            test_swap_ordering(&|order| a.or(false, order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(true);\n                a.or(false, order);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n                let a = <$atomic_type>::new(true);\n                a.or(true, order);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n                let a = <$atomic_type>::new(false);\n                a.or(false, order);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                a.or(true, order);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n            }\n        }\n        #[test]\n        fn fetch_xor() {\n            let a = <$atomic_type>::new(true);\n            test_swap_ordering(&|order| assert_eq!(a.fetch_xor(false, order), true));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.fetch_xor(false, order), true);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.fetch_xor(true, order), true);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                assert_eq!(a.fetch_xor(false, order), false);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                assert_eq!(a.fetch_xor(true, order), false);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n            }\n        }\n        #[test]\n        fn xor() {\n            let a = <$atomic_type>::new(true);\n            test_swap_ordering(&|order| a.xor(false, order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(true);\n                a.xor(false, order);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n                let a = <$atomic_type>::new(true);\n                a.xor(true, order);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                a.xor(false, order);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                a.xor(true, order);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n            }\n        }\n        ::quickcheck::quickcheck! {\n            fn quickcheck_compare_exchange(x: bool, y: bool) -> bool {\n                let z = !y;\n                for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    #[cfg(valgrind)]\n                    if IMP_EMU_SUB_WORD_CAS {\n                        mark_aligned_defined(&a);\n                    }\n                    assert_eq!(a.compare_exchange(x, y, success, failure).unwrap(), x);\n                    assert_eq!(a.load(Ordering::Relaxed), y);\n                    assert_eq!(a.compare_exchange(z, x, success, failure).unwrap_err(), y);\n                    assert_eq!(a.load(Ordering::Relaxed), y);\n                }\n                true\n            }\n        }\n    };\n    ($atomic_type:ty) => {\n        __test_atomic_bool!($atomic_type, single_thread);\n        // TODO: multi thread\n    };\n}\nmacro_rules! __test_atomic_ptr {\n    ($atomic_type:ty, single_thread) => {\n        #[allow(unused_imports)]\n        use sptr::Strict as _; // for old rustc\n        #[test]\n        fn swap() {\n            let a = <$atomic_type>::new(ptr::null_mut());\n            test_swap_ordering(&|order| {\n                a.swap(ptr::null_mut(), order);\n            });\n            let x = &mut 1;\n            for &order in &helper::SWAP_ORDERINGS {\n                assert_eq!(a.swap(x, order), ptr::null_mut());\n                assert_eq!(a.swap(ptr::null_mut(), order), x as *mut _);\n            }\n        }\n        #[test]\n        fn compare_exchange() {\n            let a = <$atomic_type>::new(ptr::null_mut());\n            test_compare_exchange_ordering(&|success, failure| {\n                let _ = a.compare_exchange(ptr::null_mut(), ptr::null_mut(), success, failure);\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(ptr::null_mut());\n                let x = &mut 1;\n                assert_eq!(\n                    a.compare_exchange(ptr::null_mut(), x, success, failure),\n                    Ok(ptr::null_mut()),\n                );\n                assert_eq!(a.load(Ordering::Relaxed), x as *mut _);\n                assert_eq!(\n                    a.compare_exchange(ptr::null_mut(), ptr::null_mut(), success, failure),\n                    Err(x as *mut _),\n                );\n                assert_eq!(a.load(Ordering::Relaxed), x as *mut _);\n            }\n        }\n        #[test]\n        fn compare_exchange_weak() {\n            let a = <$atomic_type>::new(ptr::null_mut());\n            test_compare_exchange_ordering(&|success, failure| {\n                let _ = a.compare_exchange_weak(ptr::null_mut(), ptr::null_mut(), success, failure);\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(ptr::null_mut());\n                let x = &mut 1;\n                assert_eq!(a.compare_exchange_weak(x, x, success, failure), Err(ptr::null_mut()));\n                let mut old = a.load(Ordering::Relaxed);\n                loop {\n                    match a.compare_exchange_weak(old, x, success, failure) {\n                        Ok(_) => break,\n                        Err(x) => old = x,\n                    }\n                }\n                assert_eq!(a.load(Ordering::Relaxed), x as *mut _);\n            }\n        }\n        // https://github.com/rust-lang/rust/blob/1.84.0/library/core/tests/atomic.rs#L130-L213\n        #[test]\n        fn ptr_add_null() {\n            let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());\n            assert_eq!(atom.fetch_ptr_add(1, Ordering::SeqCst).addr(), 0);\n            assert_eq!(atom.load(Ordering::SeqCst).addr(), 8);\n\n            assert_eq!(atom.fetch_byte_add(1, Ordering::SeqCst).addr(), 8);\n            assert_eq!(atom.load(Ordering::SeqCst).addr(), 9);\n\n            assert_eq!(atom.fetch_ptr_sub(1, Ordering::SeqCst).addr(), 9);\n            assert_eq!(atom.load(Ordering::SeqCst).addr(), 1);\n\n            assert_eq!(atom.fetch_byte_sub(1, Ordering::SeqCst).addr(), 1);\n            assert_eq!(atom.load(Ordering::SeqCst).addr(), 0);\n        }\n        #[test]\n        fn ptr_add_data() {\n            let num = 0i64;\n            let n = &num as *const i64 as *mut _;\n            let atom = AtomicPtr::<i64>::new(n);\n            assert_eq!(atom.fetch_ptr_add(1, Ordering::SeqCst), n);\n            assert_eq!(atom.load(Ordering::SeqCst), n.wrapping_add(1));\n\n            assert_eq!(atom.fetch_ptr_sub(1, Ordering::SeqCst), n.wrapping_add(1));\n            assert_eq!(atom.load(Ordering::SeqCst), n);\n            #[allow(clippy::cast_ptr_alignment)]\n            let bytes_from_n = |b| n.cast::<u8>().wrapping_add(b).cast::<i64>();\n\n            assert_eq!(atom.fetch_byte_add(1, Ordering::SeqCst), n);\n            assert_eq!(atom.load(Ordering::SeqCst), bytes_from_n(1));\n\n            assert_eq!(atom.fetch_byte_add(5, Ordering::SeqCst), bytes_from_n(1));\n            assert_eq!(atom.load(Ordering::SeqCst), bytes_from_n(6));\n\n            assert_eq!(atom.fetch_byte_sub(1, Ordering::SeqCst), bytes_from_n(6));\n            assert_eq!(atom.load(Ordering::SeqCst), bytes_from_n(5));\n\n            assert_eq!(atom.fetch_byte_sub(5, Ordering::SeqCst), bytes_from_n(5));\n            assert_eq!(atom.load(Ordering::SeqCst), n);\n        }\n        #[test]\n        fn ptr_bitops() {\n            let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());\n            assert_eq!(atom.fetch_or(0b0111, Ordering::SeqCst).addr(), 0);\n            assert_eq!(atom.load(Ordering::SeqCst).addr(), 0b0111);\n\n            assert_eq!(atom.fetch_and(0b1101, Ordering::SeqCst).addr(), 0b0111);\n            assert_eq!(atom.load(Ordering::SeqCst).addr(), 0b0101);\n\n            assert_eq!(atom.fetch_xor(0b1111, Ordering::SeqCst).addr(), 0b0101);\n            assert_eq!(atom.load(Ordering::SeqCst).addr(), 0b1010);\n        }\n        #[test]\n        fn ptr_bitops_tagging() {\n            const MASK_TAG: usize = 0b1111;\n            const MASK_PTR: usize = !MASK_TAG;\n\n            #[repr(align(16))]\n            struct Tagme(#[allow(dead_code)] u128);\n\n            let tagme = Tagme(1000);\n            let ptr = &tagme as *const Tagme as *mut Tagme;\n            let atom: AtomicPtr<Tagme> = AtomicPtr::new(ptr);\n\n            assert_eq!(ptr.addr() & MASK_TAG, 0);\n\n            assert_eq!(atom.fetch_or(0b0111, Ordering::SeqCst), ptr);\n            assert_eq!(atom.load(Ordering::SeqCst), ptr.map_addr(|a| a | 0b111));\n\n            assert_eq!(\n                atom.fetch_and(MASK_PTR | 0b0010, Ordering::SeqCst),\n                ptr.map_addr(|a| a | 0b111)\n            );\n            assert_eq!(atom.load(Ordering::SeqCst), ptr.map_addr(|a| a | 0b0010));\n\n            assert_eq!(atom.fetch_xor(0b1011, Ordering::SeqCst), ptr.map_addr(|a| a | 0b0010));\n            assert_eq!(atom.load(Ordering::SeqCst), ptr.map_addr(|a| a | 0b1001));\n\n            assert_eq!(atom.fetch_and(MASK_PTR, Ordering::SeqCst), ptr.map_addr(|a| a | 0b1001));\n            assert_eq!(atom.load(Ordering::SeqCst), ptr);\n        }\n        #[test]\n        fn bit_set() {\n            let a = <$atomic_type>::new(ptr::null_mut::<u64>().cast::<u8>().map_addr(|a| a | 1));\n            test_swap_ordering(&|order| assert!(a.bit_set(0, order)));\n            for &order in &helper::SWAP_ORDERINGS {\n                let pointer = &mut 1u64 as *mut u64 as *mut u8;\n                let atom = <$atomic_type>::new(pointer);\n                // Tag the bottom bit of the pointer.\n                assert!(!atom.bit_set(0, order));\n                // Extract and untag.\n                let tagged = atom.load(Ordering::Relaxed);\n                assert_eq!(tagged.addr() & 1, 1);\n                assert_eq!(tagged.map_addr(|p| p & !1), pointer);\n            }\n        }\n        #[test]\n        fn bit_clear() {\n            let a = <$atomic_type>::new(ptr::null_mut::<u64>().cast::<u8>());\n            test_swap_ordering(&|order| assert!(!a.bit_clear(0, order)));\n            for &order in &helper::SWAP_ORDERINGS {\n                let pointer = &mut 1u64 as *mut u64 as *mut u8;\n                // A tagged pointer\n                let atom = <$atomic_type>::new(pointer.map_addr(|a| a | 1));\n                assert!(atom.bit_set(0, order));\n                // Untag\n                assert!(atom.bit_clear(0, order));\n            }\n        }\n        #[test]\n        fn bit_toggle() {\n            let a = <$atomic_type>::new(ptr::null_mut::<u64>().cast::<u8>());\n            test_swap_ordering(&|order| {\n                a.bit_toggle(0, order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let pointer = &mut 1u64 as *mut u64 as *mut u8;\n                let atom = <$atomic_type>::new(pointer);\n                // Toggle a tag bit on the pointer.\n                atom.bit_toggle(0, order);\n                assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1);\n            }\n        }\n        ::quickcheck::quickcheck! {\n            fn quickcheck_swap(x: usize, y: usize) -> bool {\n                let x = sptr::invalid_mut(x);\n                let y = sptr::invalid_mut(y);\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.swap(y, order), x);\n                    assert_eq!(a.swap(x, order), y);\n                }\n                true\n            }\n            fn quickcheck_compare_exchange(x: usize, y: usize) -> bool {\n                let mut rng = fastrand::Rng::new();\n                let z = loop {\n                    let z = rng.usize(..);\n                    if z != y {\n                        break z;\n                    }\n                };\n                let x = sptr::invalid_mut(x);\n                let y = sptr::invalid_mut(y);\n                let z = sptr::invalid_mut(z);\n                for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.compare_exchange(x, y, success, failure).unwrap(), x);\n                    assert_eq!(a.load(Ordering::Relaxed), y);\n                    assert_eq!(a.compare_exchange(z, x, success, failure).unwrap_err(), y);\n                    assert_eq!(a.load(Ordering::Relaxed), y);\n                }\n                true\n            }\n            fn quickcheck_fetch_byte_add(x: usize, y: usize) -> bool {\n                let x = sptr::invalid_mut(x);\n                let y = sptr::invalid_mut::<u8>(y);\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_byte_add(y.addr(), order), x);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr().wrapping_add(y.addr()));\n                    let a = <$atomic_type>::new(y);\n                    assert_eq!(a.fetch_byte_add(x.addr(), order), y);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr().wrapping_add(x.addr()));\n                }\n                true\n            }\n            fn quickcheck_fetch_byte_sub(x: usize, y: usize) -> bool {\n                let x = sptr::invalid_mut(x);\n                let y = sptr::invalid_mut::<u8>(y);\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_byte_sub(y.addr(), order), x);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr().wrapping_sub(y.addr()));\n                    let a = <$atomic_type>::new(y);\n                    assert_eq!(a.fetch_byte_sub(x.addr(), order), y);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr().wrapping_sub(x.addr()));\n                }\n                true\n            }\n            fn quickcheck_fetch_and(x: usize, y: usize) -> bool {\n                let x = sptr::invalid_mut(x);\n                let y = sptr::invalid_mut::<u8>(y);\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_and(y.addr(), order), x);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() & y.addr());\n                    let a = <$atomic_type>::new(y);\n                    assert_eq!(a.fetch_and(x.addr(), order), y);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() & x.addr());\n                }\n                true\n            }\n            fn quickcheck_fetch_or(x: usize, y: usize) -> bool {\n                let x = sptr::invalid_mut(x);\n                let y = sptr::invalid_mut::<u8>(y);\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_or(y.addr(), order), x);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() | y.addr());\n                    let a = <$atomic_type>::new(y);\n                    assert_eq!(a.fetch_or(x.addr(), order), y);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() | x.addr());\n                }\n                true\n            }\n            fn quickcheck_fetch_xor(x: usize, y: usize) -> bool {\n                let x = sptr::invalid_mut(x);\n                let y = sptr::invalid_mut::<u8>(y);\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(a.fetch_xor(y.addr(), order), x);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() ^ y.addr());\n                    let a = <$atomic_type>::new(y);\n                    assert_eq!(a.fetch_xor(x.addr(), order), y);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), y.addr() ^ x.addr());\n                }\n                true\n            }\n            fn quickcheck_bit_set(x: usize, bit: u32) -> bool {\n                let x = sptr::invalid_mut(x);\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    let b = a.bit_set(bit, order);\n                    let mask = <usize>::wrapping_shl(1, bit);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() | mask);\n                    assert_eq!(b, x.addr() & mask != 0);\n                }\n                true\n            }\n            fn quickcheck_bit_clear(x: usize, bit: u32) -> bool {\n                let x = sptr::invalid_mut(x);\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    let b = a.bit_clear(bit, order);\n                    let mask = <usize>::wrapping_shl(1, bit);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() & !mask);\n                    assert_eq!(b, x.addr() & mask != 0);\n                }\n                true\n            }\n            fn quickcheck_bit_toggle(x: usize, bit: u32) -> bool {\n                let x = sptr::invalid_mut(x);\n                for &order in &helper::SWAP_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    let b = a.bit_toggle(bit, order);\n                    let mask = <usize>::wrapping_shl(1, bit);\n                    assert_eq!(a.load(Ordering::Relaxed).addr(), x.addr() ^ mask);\n                    assert_eq!(b, x.addr() & mask != 0);\n                }\n                true\n            }\n        }\n    };\n    ($atomic_type:ty) => {\n        __test_atomic_ptr!($atomic_type, single_thread);\n        // TODO: multi thread\n    };\n}\n\nmacro_rules! __test_atomic_int_pub {\n    ($atomic_type:ty, $int_type:ident) => {\n        __test_atomic_pub_common!($atomic_type, $int_type);\n        use std::boxed::Box;\n\n        #[allow(unused_imports)]\n        use sptr::Strict as _; // for old rustc\n        #[test]\n        fn fetch_update() {\n            // TODO(gcc): failure\n            if option_env!(\"RUSTC_CODEGEN_GCC\").unwrap_or_default() == \"1\"\n                && !cfg!(debug_assertions)\n            {\n                return;\n            }\n            // TODO(riscv): wrong result (as of Valgrind 3.26)\n            #[cfg(valgrind)]\n            if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                return;\n            }\n            let a = <$atomic_type>::new(7);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                mark_aligned_defined(&a);\n            }\n            test_compare_exchange_ordering(&|set, fetch| {\n                let _ = a.fetch_update(set, fetch, |x| Some(x));\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(7);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS && mem::size_of::<$int_type>() <= 2 {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_update(success, failure, |_| None), Err(7));\n                assert_eq!(a.fetch_update(success, failure, |x| Some(x + 1)), Ok(7));\n                assert_eq!(a.fetch_update(success, failure, |x| Some(x + 1)), Ok(8));\n                assert_eq!(a.load(Ordering::SeqCst), 9);\n            }\n        }\n        #[test]\n        fn impls() {\n            #[cfg(not(portable_atomic_no_const_transmute))]\n            const INTO_INNER: $int_type = {\n                let a = <$atomic_type>::new(10);\n                a.into_inner()\n            };\n            #[cfg(not(portable_atomic_no_const_mut_refs))]\n            const GET_MUT: $atomic_type = {\n                let mut a = <$atomic_type>::new(10);\n                let _ = unsafe { <$atomic_type>::from_ptr(a.as_ptr()) };\n                *a.get_mut() = 5;\n                a\n            };\n            #[cfg(not(portable_atomic_no_const_transmute))]\n            {\n                assert_eq!(INTO_INNER, 10);\n            }\n            #[cfg(not(portable_atomic_no_const_mut_refs))]\n            {\n                assert_eq!(GET_MUT.into_inner(), 5);\n            }\n            let a = <$atomic_type>::default();\n            let b = <$atomic_type>::from(0);\n            assert_eq!(a.load(Ordering::SeqCst), b.load(Ordering::SeqCst));\n            assert_eq!(std::format!(\"{:?}\", a), std::format!(\"{:?}\", a.load(Ordering::SeqCst)));\n            assert_eq!(a.into_inner(), 0);\n            assert_eq!(b.into_inner(), 0);\n\n            unsafe {\n                let ptr: *mut Align16<$int_type> = Box::into_raw(Box::new(Align16(0)));\n                assert!(ptr.addr() % mem::align_of::<$atomic_type>() == 0);\n                {\n                    let a = <$atomic_type>::from_ptr(ptr.cast::<$int_type>());\n                    *a.as_ptr() = 1;\n                }\n                assert_eq!((*ptr).0, 1);\n                drop(Box::from_raw(ptr));\n            }\n        }\n        ::quickcheck::quickcheck! {\n            fn quickcheck_fetch_update(x: $int_type, y: $int_type) -> bool {\n                // TODO(riscv): wrong result (as of Valgrind 3.26)\n                #[cfg(valgrind)]\n                if cfg!(target_arch = \"riscv64\") && mem::size_of::<$int_type>() <= 2 {\n                    return true;\n                }\n                let mut rng = fastrand::Rng::new();\n                let z = loop {\n                    let z = rng.$int_type(..);\n                    if z != y {\n                        break z;\n                    }\n                };\n                for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                    let a = <$atomic_type>::new(x);\n                    assert_eq!(\n                        a.fetch_update(success, failure, |_| Some(y))\n                        .unwrap(),\n                        x\n                    );\n                    assert_eq!(\n                        a.fetch_update(success, failure, |_| Some(z))\n                        .unwrap(),\n                        y\n                    );\n                    assert_eq!(a.load(Ordering::Relaxed), z);\n                    assert_eq!(\n                        a.fetch_update(success, failure, |z| if z == y { Some(z) } else { None })\n                        .unwrap_err(),\n                        z\n                    );\n                    assert_eq!(a.load(Ordering::Relaxed), z);\n                }\n                true\n            }\n        }\n    };\n}\nmacro_rules! __test_atomic_float_pub {\n    ($atomic_type:ty, $float_type:ident) => {\n        __test_atomic_pub_common!($atomic_type, $float_type);\n        use std::boxed::Box;\n\n        #[allow(unused_imports)]\n        use sptr::Strict as _; // for old rustc\n        #[test]\n        fn fetch_update() {\n            let a = <$atomic_type>::new(7.);\n            test_compare_exchange_ordering(&|set, fetch| {\n                let _ = a.fetch_update(set, fetch, |x| Some(x));\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(7.);\n                assert_eq!(a.fetch_update(success, failure, |_| None), Err(7.));\n                assert_eq!(a.fetch_update(success, failure, |x| Some(x + 1.)), Ok(7.));\n                assert_eq!(a.fetch_update(success, failure, |x| Some(x + 1.)), Ok(8.));\n                assert_eq!(a.load(Ordering::SeqCst), 9.);\n            }\n        }\n        #[test]\n        fn impls() {\n            #[cfg(not(portable_atomic_no_const_transmute))]\n            const INTO_INNER: $float_type = {\n                let a = <$atomic_type>::new(10.);\n                a.into_inner()\n            };\n            #[cfg(not(portable_atomic_no_const_mut_refs))]\n            const GET_MUT: $atomic_type = {\n                let mut a = <$atomic_type>::new(10.);\n                let _ = unsafe { <$atomic_type>::from_ptr(a.as_ptr()) };\n                *a.get_mut() = 5.;\n                a\n            };\n            #[cfg(not(portable_atomic_no_const_transmute))]\n            {\n                assert_eq!(INTO_INNER, 10.);\n            }\n            #[cfg(not(portable_atomic_no_const_mut_refs))]\n            {\n                assert_eq!(GET_MUT.into_inner(), 5.);\n            }\n            let a = <$atomic_type>::default();\n            let b = <$atomic_type>::from(0.);\n            assert_eq!(a.load(Ordering::SeqCst), b.load(Ordering::SeqCst));\n            assert_eq!(std::format!(\"{:?}\", a), std::format!(\"{:?}\", a.load(Ordering::SeqCst)));\n            assert_eq!(a.into_inner(), 0.);\n            assert_eq!(b.into_inner(), 0.);\n\n            unsafe {\n                let ptr: *mut Align16<$float_type> = Box::into_raw(Box::new(Align16(0.)));\n                assert!(ptr.addr() % mem::align_of::<$atomic_type>() == 0);\n                {\n                    let a = <$atomic_type>::from_ptr(ptr.cast::<$float_type>());\n                    *a.as_ptr() = 1.;\n                }\n                assert_eq!((*ptr).0, 1.);\n                drop(Box::from_raw(ptr));\n            }\n        }\n    };\n}\nmacro_rules! __test_atomic_bool_pub {\n    ($atomic_type:ty) => {\n        __test_atomic_pub_common!($atomic_type, bool);\n        use std::boxed::Box;\n\n        #[allow(unused_imports)]\n        use sptr::Strict as _; // for old rustc\n        #[test]\n        fn fetch_nand() {\n            let a = <$atomic_type>::new(true);\n            test_swap_ordering(&|order| assert_eq!(a.fetch_nand(false, order), true));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.fetch_nand(false, order), true);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.fetch_nand(true, order), true);\n                assert_eq!(a.load(Ordering::Relaxed) as usize, 0);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                assert_eq!(a.fetch_nand(false, order), false);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n                let a = <$atomic_type>::new(false);\n                assert_eq!(a.fetch_nand(true, order), false);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n            }\n        }\n        #[test]\n        fn fetch_not() {\n            let a = <$atomic_type>::new(true);\n            test_swap_ordering(&|order| {\n                a.fetch_not(order);\n            });\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(true);\n                assert_eq!(a.fetch_not(order), true);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                assert_eq!(a.fetch_not(order), false);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n            }\n        }\n        #[test]\n        fn not() {\n            let a = <$atomic_type>::new(true);\n            test_swap_ordering(&|order| a.not(order));\n            for &order in &helper::SWAP_ORDERINGS {\n                let a = <$atomic_type>::new(true);\n                a.not(order);\n                assert_eq!(a.load(Ordering::Relaxed), false);\n                let a = <$atomic_type>::new(false);\n                a.not(order);\n                assert_eq!(a.load(Ordering::Relaxed), true);\n            }\n        }\n        #[test]\n        fn fetch_update() {\n            // TODO(gcc): failure\n            if option_env!(\"RUSTC_CODEGEN_GCC\").unwrap_or_default() == \"1\"\n                && !cfg!(debug_assertions)\n            {\n                return;\n            }\n            let a = <$atomic_type>::new(false);\n            #[cfg(valgrind)]\n            if IMP_EMU_SUB_WORD_CAS {\n                mark_aligned_defined(&a);\n            }\n            test_compare_exchange_ordering(&|set, fetch| {\n                let _ = a.fetch_update(set, fetch, |x| Some(x));\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(false);\n                #[cfg(valgrind)]\n                if IMP_EMU_SUB_WORD_CAS {\n                    mark_aligned_defined(&a);\n                }\n                assert_eq!(a.fetch_update(success, failure, |_| None), Err(false));\n                assert_eq!(a.fetch_update(success, failure, |x| Some(!x)), Ok(false));\n                assert_eq!(a.fetch_update(success, failure, |x| Some(!x)), Ok(true));\n                assert_eq!(a.load(Ordering::SeqCst), false);\n            }\n        }\n        #[test]\n        fn impls() {\n            #[cfg(not(portable_atomic_no_const_transmute))]\n            const INTO_INNER: bool = {\n                let a = <$atomic_type>::new(true);\n                a.into_inner()\n            };\n            #[cfg(not(portable_atomic_no_const_mut_refs))]\n            const GET_MUT: $atomic_type = {\n                let mut a = <$atomic_type>::new(true);\n                let _ = unsafe { <$atomic_type>::from_ptr(a.as_ptr()) };\n                *a.get_mut() = false;\n                a\n            };\n            #[cfg(not(portable_atomic_no_const_transmute))]\n            {\n                assert_eq!(INTO_INNER, true);\n            }\n            #[cfg(not(portable_atomic_no_const_mut_refs))]\n            {\n                assert_eq!(GET_MUT.into_inner(), false);\n            }\n            let a = <$atomic_type>::default();\n            let b = <$atomic_type>::from(false);\n            assert_eq!(a.load(Ordering::SeqCst), b.load(Ordering::SeqCst));\n            assert_eq!(std::format!(\"{:?}\", a), std::format!(\"{:?}\", a.load(Ordering::SeqCst)));\n            assert_eq!(a.into_inner(), false);\n            assert_eq!(b.into_inner(), false);\n\n            unsafe {\n                let ptr: *mut bool = Box::into_raw(Box::new(false));\n                assert!(ptr.addr() % mem::align_of::<$atomic_type>() == 0);\n                {\n                    let a = <$atomic_type>::from_ptr(ptr);\n                    *a.as_ptr() = true;\n                }\n                assert_eq!((*ptr), true);\n                drop(Box::from_raw(ptr));\n            }\n        }\n    };\n}\nmacro_rules! __test_atomic_ptr_pub {\n    ($atomic_type:ty) => {\n        __test_atomic_pub_common!($atomic_type, *mut u8);\n        use std::boxed::Box;\n        #[test]\n        fn fetch_update() {\n            // TODO(gcc): failure\n            if option_env!(\"RUSTC_CODEGEN_GCC\").unwrap_or_default() == \"1\"\n                && !cfg!(debug_assertions)\n            {\n                return;\n            }\n            let a = <$atomic_type>::new(ptr::null_mut());\n            test_compare_exchange_ordering(&|set, fetch| {\n                let _ = a.fetch_update(set, fetch, |x| Some(x));\n            });\n            for &(success, failure) in &helper::COMPARE_EXCHANGE_ORDERINGS {\n                let a = <$atomic_type>::new(ptr::null_mut());\n                assert_eq!(a.fetch_update(success, failure, |_| None), Err(ptr::null_mut()));\n                assert_eq!(\n                    a.fetch_update(success, failure, |_| Some(&a as *const _ as *mut _)),\n                    Ok(ptr::null_mut())\n                );\n                assert_eq!(a.load(Ordering::SeqCst), &a as *const _ as *mut _);\n            }\n        }\n        #[test]\n        fn impls() {\n            #[cfg(not(portable_atomic_no_const_transmute))]\n            const INTO_INNER: *mut u8 = {\n                let a = <$atomic_type>::new(ptr::null_mut());\n                a.into_inner()\n            };\n            #[cfg(not(portable_atomic_no_const_mut_refs))]\n            const GET_MUT: $atomic_type = {\n                let mut a = <$atomic_type>::new(ptr::null_mut());\n                let _ = unsafe { <$atomic_type>::from_ptr(a.as_ptr()) };\n                *a.get_mut() = ptr::null_mut::<u8>().wrapping_add(1);\n                a\n            };\n            #[cfg(not(portable_atomic_no_const_transmute))]\n            {\n                assert!(INTO_INNER.is_null());\n            }\n            #[cfg(not(portable_atomic_no_const_mut_refs))]\n            {\n                assert_eq!(GET_MUT.into_inner(), ptr::null_mut::<u8>().wrapping_add(1));\n            }\n            let a = <$atomic_type>::default();\n            let b = <$atomic_type>::from(ptr::null_mut());\n            assert_eq!(a.load(Ordering::SeqCst), b.load(Ordering::SeqCst));\n            assert_eq!(std::format!(\"{:?}\", a), std::format!(\"{:?}\", a.load(Ordering::SeqCst)));\n            assert_eq!(std::format!(\"{:p}\", a), std::format!(\"{:p}\", a.load(Ordering::SeqCst)));\n            assert_eq!(a.into_inner(), ptr::null_mut());\n            assert_eq!(b.into_inner(), ptr::null_mut());\n\n            unsafe {\n                let ptr: *mut Align16<*mut u8> = Box::into_raw(Box::new(Align16(ptr::null_mut())));\n                assert!(ptr.addr() % mem::align_of::<$atomic_type>() == 0);\n                {\n                    let a = <$atomic_type>::from_ptr(ptr.cast::<*mut u8>());\n                    *a.as_ptr() = ptr::null_mut::<u8>().wrapping_add(1);\n                }\n                assert_eq!((*ptr).0, ptr::null_mut::<u8>().wrapping_add(1));\n                drop(Box::from_raw(ptr));\n            }\n        }\n    };\n}\n\nmacro_rules! test_atomic_int_load_store {\n    ($int_type:ident) => {\n        paste::paste! {\n            #[allow(\n                clippy::alloc_instead_of_core,\n                clippy::std_instead_of_alloc,\n                clippy::std_instead_of_core,\n                clippy::undocumented_unsafe_blocks\n            )]\n            mod [<test_atomic_ $int_type>] {\n                use super::*;\n                __test_atomic_int_load_store!([<Atomic $int_type:camel>], $int_type);\n            }\n        }\n    };\n}\nmacro_rules! test_atomic_ptr_load_store {\n    () => {\n        #[allow(\n            clippy::alloc_instead_of_core,\n            clippy::std_instead_of_alloc,\n            clippy::std_instead_of_core,\n            clippy::undocumented_unsafe_blocks\n        )]\n        mod test_atomic_ptr {\n            use super::*;\n            __test_atomic_ptr_load_store!(AtomicPtr<u8>);\n        }\n    };\n}\n\nmacro_rules! test_atomic_int_single_thread {\n    ($int_type:ident) => {\n        paste::paste! {\n            #[allow(\n                clippy::alloc_instead_of_core,\n                clippy::std_instead_of_alloc,\n                clippy::std_instead_of_core,\n                clippy::undocumented_unsafe_blocks\n            )]\n            mod [<test_atomic_ $int_type>] {\n                use super::*;\n                __test_atomic_int_load_store!([<Atomic $int_type:camel>], $int_type, single_thread);\n                __test_atomic_int!([<Atomic $int_type:camel>], $int_type, single_thread);\n            }\n        }\n    };\n}\nmacro_rules! test_atomic_ptr_single_thread {\n    () => {\n        #[allow(\n            clippy::alloc_instead_of_core,\n            clippy::std_instead_of_alloc,\n            clippy::std_instead_of_core,\n            clippy::undocumented_unsafe_blocks\n        )]\n        mod test_atomic_ptr {\n            use super::*;\n            __test_atomic_ptr_load_store!(AtomicPtr<u8>, single_thread);\n            __test_atomic_ptr!(AtomicPtr<u8>, single_thread);\n        }\n    };\n}\n\nmacro_rules! test_atomic_int {\n    ($int_type:ident) => {\n        paste::paste! {\n            #[allow(\n                clippy::alloc_instead_of_core,\n                clippy::std_instead_of_alloc,\n                clippy::std_instead_of_core,\n                clippy::undocumented_unsafe_blocks\n            )]\n            mod [<test_atomic_ $int_type>] {\n                use super::*;\n                __test_atomic_int_load_store!([<Atomic $int_type:camel>], $int_type);\n                __test_atomic_int!([<Atomic $int_type:camel>], $int_type);\n            }\n        }\n    };\n}\nmacro_rules! test_atomic_ptr {\n    () => {\n        #[allow(\n            clippy::alloc_instead_of_core,\n            clippy::std_instead_of_alloc,\n            clippy::std_instead_of_core,\n            clippy::undocumented_unsafe_blocks\n        )]\n        #[allow(unstable_name_collisions)] // for sptr crate\n        mod test_atomic_ptr {\n            use super::*;\n            __test_atomic_ptr_load_store!(AtomicPtr<u8>);\n            __test_atomic_ptr!(AtomicPtr<u8>);\n        }\n    };\n}\n\nmacro_rules! test_atomic_int_pub {\n    ($int_type:ident) => {\n        paste::paste! {\n            #[allow(\n                clippy::alloc_instead_of_core,\n                clippy::std_instead_of_alloc,\n                clippy::std_instead_of_core,\n                clippy::undocumented_unsafe_blocks\n            )]\n            mod [<test_atomic_ $int_type>] {\n                use super::*;\n                __test_atomic_int_load_store!([<Atomic $int_type:camel>], $int_type);\n                __test_atomic_int!([<Atomic $int_type:camel>], $int_type);\n                __test_atomic_int_pub!([<Atomic $int_type:camel>], $int_type);\n            }\n        }\n    };\n}\n#[cfg(feature = \"float\")]\nmacro_rules! test_atomic_float_pub {\n    ($float_type:ident) => {\n        paste::paste! {\n            #[allow(\n                clippy::alloc_instead_of_core,\n                clippy::float_arithmetic,\n                clippy::std_instead_of_alloc,\n                clippy::std_instead_of_core,\n                clippy::undocumented_unsafe_blocks\n            )]\n            mod [<test_atomic_ $float_type>] {\n                use super::*;\n                __test_atomic_float_load_store!([<Atomic $float_type:camel>], $float_type);\n                __test_atomic_float!([<Atomic $float_type:camel>], $float_type);\n                __test_atomic_float_pub!([<Atomic $float_type:camel>], $float_type);\n            }\n        }\n    };\n}\nmacro_rules! test_atomic_bool_pub {\n    () => {\n        #[allow(\n            clippy::alloc_instead_of_core,\n            clippy::std_instead_of_alloc,\n            clippy::std_instead_of_core,\n            clippy::undocumented_unsafe_blocks\n        )]\n        mod test_atomic_bool {\n            use super::*;\n            __test_atomic_bool_load_store!(AtomicBool);\n            __test_atomic_bool!(AtomicBool);\n            __test_atomic_bool_pub!(AtomicBool);\n        }\n    };\n}\nmacro_rules! test_atomic_ptr_pub {\n    () => {\n        #[allow(\n            clippy::alloc_instead_of_core,\n            clippy::std_instead_of_alloc,\n            clippy::std_instead_of_core,\n            clippy::undocumented_unsafe_blocks\n        )]\n        #[allow(unstable_name_collisions)] // for sptr crate\n        mod test_atomic_ptr {\n            use super::*;\n            __test_atomic_ptr_load_store!(AtomicPtr<u8>);\n            __test_atomic_ptr!(AtomicPtr<u8>);\n            __test_atomic_ptr_pub!(AtomicPtr<u8>);\n        }\n    };\n}\n\n// Asserts that `$a` and `$b` have performed equivalent operations.\n#[cfg(feature = \"float\")]\nmacro_rules! assert_float_op_eq {\n    ($a:expr, $b:expr $(,)?) => {{\n        // See also:\n        // - https://github.com/rust-lang/unsafe-code-guidelines/issues/237.\n        // - https://github.com/rust-lang/portable-simd/issues/39.\n        let a = $a;\n        let b = $b;\n        if a.is_nan() && b.is_nan() // don't check sign of NaN: https://github.com/rust-lang/rust/issues/55131\n            || a.is_infinite()\n                && b.is_infinite()\n                && a.is_sign_positive() == b.is_sign_positive()\n                && a.is_sign_negative() == b.is_sign_negative()\n        {\n            // ok\n        } else {\n            assert_eq!(a, b);\n        }\n    }};\n}\n\n#[allow(unused_unsafe)] // for old rustc\nfn assert_panic(f: &dyn Fn()) -> std::string::String {\n    let backtrace = std::env::var_os(\"RUST_BACKTRACE\");\n    let hook = std::panic::take_hook();\n    // set_var/remove_var is fine as we run tests with RUST_TEST_THREADS=1\n    // std::panic::set_backtrace_style is better way here, but is unstable.\n    unsafe { std::env::set_var(\"RUST_BACKTRACE\", \"0\") } // Suppress backtrace\n    std::panic::set_hook(std::boxed::Box::new(|_| {})); // Suppress panic msg\n    let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(f));\n    std::panic::set_hook(hook);\n    match backtrace {\n        Some(v) => unsafe { std::env::set_var(\"RUST_BACKTRACE\", v) },\n        None => unsafe { std::env::remove_var(\"RUST_BACKTRACE\") },\n    }\n    let msg = res.unwrap_err();\n    msg.downcast_ref::<std::string::String>()\n        .cloned()\n        .unwrap_or_else(|| msg.downcast_ref::<&'static str>().copied().unwrap().into())\n}\npub(crate) const LOAD_ORDERINGS: [Ordering; 3] =\n    [Ordering::Relaxed, Ordering::Acquire, Ordering::SeqCst];\npub(crate) fn rand_load_ordering(rng: &mut fastrand::Rng) -> Ordering {\n    LOAD_ORDERINGS[rng.usize(0..LOAD_ORDERINGS.len())]\n}\npub(crate) fn test_load_ordering(f: &dyn Fn(Ordering)) {\n    for &order in &LOAD_ORDERINGS {\n        f(order);\n    }\n    if !skip_should_panic_test() {\n        assert_eq!(\n            assert_panic(&|| f(Ordering::Release)),\n            \"there is no such thing as a release load\"\n        );\n        assert_eq!(\n            assert_panic(&|| f(Ordering::AcqRel)),\n            \"there is no such thing as an acquire-release load\"\n        );\n    }\n}\npub(crate) const STORE_ORDERINGS: [Ordering; 3] =\n    [Ordering::Relaxed, Ordering::Release, Ordering::SeqCst];\npub(crate) fn rand_store_ordering(rng: &mut fastrand::Rng) -> Ordering {\n    STORE_ORDERINGS[rng.usize(0..STORE_ORDERINGS.len())]\n}\npub(crate) fn test_store_ordering(f: &dyn Fn(Ordering)) {\n    for &order in &STORE_ORDERINGS {\n        f(order);\n    }\n    if !skip_should_panic_test() {\n        assert_eq!(\n            assert_panic(&|| f(Ordering::Acquire)),\n            \"there is no such thing as an acquire store\"\n        );\n        assert_eq!(\n            assert_panic(&|| f(Ordering::AcqRel)),\n            \"there is no such thing as an acquire-release store\"\n        );\n    }\n}\npub(crate) const SWAP_ORDERINGS: [Ordering; 5] =\n    [Ordering::Relaxed, Ordering::Release, Ordering::Acquire, Ordering::AcqRel, Ordering::SeqCst];\npub(crate) fn rand_swap_ordering(rng: &mut fastrand::Rng) -> Ordering {\n    SWAP_ORDERINGS[rng.usize(0..SWAP_ORDERINGS.len())]\n}\npub(crate) fn test_swap_ordering(f: &dyn Fn(Ordering)) {\n    for &order in &SWAP_ORDERINGS {\n        f(order);\n    }\n}\npub(crate) const COMPARE_EXCHANGE_ORDERINGS: [(Ordering, Ordering); 15] = [\n    (Ordering::Relaxed, Ordering::Relaxed),\n    (Ordering::Relaxed, Ordering::Acquire),\n    (Ordering::Relaxed, Ordering::SeqCst),\n    (Ordering::Acquire, Ordering::Relaxed),\n    (Ordering::Acquire, Ordering::Acquire),\n    (Ordering::Acquire, Ordering::SeqCst),\n    (Ordering::Release, Ordering::Relaxed),\n    (Ordering::Release, Ordering::Acquire),\n    (Ordering::Release, Ordering::SeqCst),\n    (Ordering::AcqRel, Ordering::Relaxed),\n    (Ordering::AcqRel, Ordering::Acquire),\n    (Ordering::AcqRel, Ordering::SeqCst),\n    (Ordering::SeqCst, Ordering::Relaxed),\n    (Ordering::SeqCst, Ordering::Acquire),\n    (Ordering::SeqCst, Ordering::SeqCst),\n];\npub(crate) fn rand_compare_exchange_ordering(rng: &mut fastrand::Rng) -> (Ordering, Ordering) {\n    COMPARE_EXCHANGE_ORDERINGS[rng.usize(0..COMPARE_EXCHANGE_ORDERINGS.len())]\n}\npub(crate) fn test_compare_exchange_ordering(f: &dyn Fn(Ordering, Ordering)) {\n    for &(success, failure) in &COMPARE_EXCHANGE_ORDERINGS {\n        f(success, failure);\n    }\n    if !skip_should_panic_test() {\n        for &order in &SWAP_ORDERINGS {\n            let msg = assert_panic(&|| f(order, Ordering::AcqRel));\n            assert!(\n                msg == \"there is no such thing as an acquire-release failure ordering\"\n                    || msg == \"there is no such thing as an acquire-release load\",\n                \"{}\",\n                msg\n            );\n            let msg = assert_panic(&|| f(order, Ordering::Release));\n            assert!(\n                msg == \"there is no such thing as a release failure ordering\"\n                    || msg == \"there is no such thing as a release load\",\n                \"{}\",\n                msg\n            );\n        }\n    }\n}\n\n// Used in stress tests to find atomicity bug generated by __test_atomic_* macro.\npub(crate) fn stress_test_config(rng: &mut fastrand::Rng) -> (usize, usize) {\n    let iterations = if cfg!(miri) {\n        50\n    } else if cfg!(any(debug_assertions, qemu, valgrind)) {\n        5_000\n    } else {\n        25_000\n    };\n    let threads = if cfg!(any(debug_assertions, valgrind)) { 2 } else { rng.usize(2..=8) };\n    eprintln!(\"threads={}\", threads);\n    (iterations, threads)\n}\n\n// true if the current implementation implements sub-word atomics using word-size CAS.\n#[cfg(valgrind)]\npub(crate) const IMP_EMU_SUB_WORD_CAS: bool = cfg!(target_arch = \"s390x\");\n\n#[cfg(valgrind)]\n#[inline(always)]\npub(crate) fn mark_aligned_defined<T: ?Sized>(a: &T) {\n    test_helper::valgrind::make_aligned_mem_defined::<T, 4>(a);\n}\n\nfn skip_should_panic_test() -> bool {\n    // Miri's panic handling is slow\n    // MSAN false positive: https://gist.github.com/taiki-e/dd6269a8ffec46284fdc764a4849f884\n    // Valgrind false positive on s390x\n    is_panic_abort()\n        || cfg!(miri)\n        || option_env!(\"CARGO_PROFILE_RELEASE_LTO\").map_or(false, |v| v == \"fat\")\n            && build_context::SANITIZE.contains(\"memory\")\n        || cfg!(all(valgrind, target_arch = \"s390x\"))\n}\n\n// For -C panic=abort -Z panic_abort_tests: https://github.com/rust-lang/rust/issues/67650\nfn is_panic_abort() -> bool {\n    !matches!(build_context::PANIC, \"unwind\" | \"\") // cfg(panic) requires Rust 1.60\n}\n\n#[repr(C, align(16))]\npub(crate) struct Align16<T>(pub(crate) T);\n\n// Stress tests to find memory ordering bug.\n// Note that this is not exhaustive and only tests a few cases.\nmacro_rules! __stress_acquire_release {\n    (should_pass,\n        $int_type:ident, $read:ident, $write:ident, $load_order:ident, $store_order:ident\n    ) => {\n        paste::paste! {\n            #[test]\n            #[cfg_attr(all(any(debug_assertions, valgrind_cross), not(miri)), ignore = \"slow in some environments\")] // debug mode is slow.\n            #[allow(\n                clippy::cast_possible_wrap,\n                clippy::cast_sign_loss,\n                clippy::cast_possible_truncation,\n            )]\n            fn [<acquire_release1 _ $read _ $load_order:lower _ $write _ $store_order:lower>]() {\n                __call_stress_test_fn!(acquire_release1, [<Atomic $int_type:camel>],\n                    $int_type, $read, $write, $load_order, $store_order);\n            }\n        }\n    };\n    (can_panic,\n        $int_type:ident, $read:ident, $write:ident, $load_order:ident, $store_order:ident\n    ) => {\n        paste::paste! {\n            // Currently, to make this test work well enough outside of Miri, tens of thousands\n            // of iterations are needed, but this test is slow in some environments.\n            // So, ignore on non-Miri environments by default. See also catch_unwind_on_weak_memory_arch.\n            #[test]\n            #[cfg_attr(not(miri), ignore = \"slow in some environments\")]\n            #[allow(\n                clippy::cast_possible_wrap,\n                clippy::cast_sign_loss,\n                clippy::cast_possible_truncation,\n            )]\n            fn [<acquire_release1 _ $read _ $load_order:lower _ $write _ $store_order:lower>]() {\n                use crate::tests::helper::catch_unwind_on_weak_memory_arch as can_panic;\n                can_panic(\"a=\", test_helper::function_name!(), || {\n                    __call_stress_test_fn!(acquire_release1, [<Atomic $int_type:camel>],\n                        $int_type, $read, $write, $load_order, $store_order);\n                });\n            }\n        }\n    };\n}\nmacro_rules! __stress_seqcst {\n    (should_pass,\n        $int_type:ident, $read:ident, $write:ident, $load_order:ident, $store_order:ident\n    ) => {\n        paste::paste! {\n            // Currently, to make this test work well enough outside of Miri, tens of thousands\n            // of iterations are needed, but this test is slow in some environments.\n            // So, ignore on QEMU by default.\n            #[test]\n            #[cfg_attr(any(all(any(debug_assertions, valgrind_cross), not(miri)), qemu), ignore = \"slow in some environments\")] // debug mode is slow.\n            #[allow(\n                clippy::cast_possible_wrap,\n                clippy::cast_sign_loss,\n                clippy::cast_possible_truncation,\n            )]\n            fn [<seqcst1 _ $read _ $load_order:lower _ $write _ $store_order:lower>]() {\n                __call_stress_test_fn!(seqcst1, [<Atomic $int_type:camel>],\n                    $int_type, $read, $write, $load_order, $store_order);\n            }\n        }\n    };\n    (can_panic,\n        $int_type:ident, $read:ident, $write:ident, $load_order:ident, $store_order:ident\n    ) => {\n        paste::paste! {\n            // Currently, to make this test work well enough outside of Miri, tens of thousands\n            // of iterations are needed, but this test is slow in some environments.\n            // So, ignore on non-Miri environments by default. See also catch_unwind_on_non_seqcst_arch.\n            #[test]\n            #[cfg_attr(not(miri), ignore = \"slow in some environments\")]\n            #[allow(\n                clippy::cast_possible_wrap,\n                clippy::cast_sign_loss,\n                clippy::cast_possible_truncation,\n            )]\n            fn [<seqcst1 _ $read _ $load_order:lower _ $write _ $store_order:lower>]() {\n                use crate::tests::helper::catch_unwind_on_non_seqcst_arch as can_panic;\n                can_panic(\"c=2\", test_helper::function_name!(), || {\n                    __call_stress_test_fn!(seqcst1, [<Atomic $int_type:camel>],\n                        $int_type, $read, $write, $load_order, $store_order);\n                });\n            }\n        }\n    };\n}\n// To test this working correctly:\n// - Uncomment can_panic case in __stress_seqcst,\n//   and run test with `--release -- acquire_release1 --ignored`.\n//   At least on AArch64 machine, some \"panicked as expected\" will be shown.\npub(crate) fn acquire_release1<T: Send + Sync>(\n    min: isize,\n    max: isize,\n    new: impl Fn(isize) -> T,\n    load: impl Fn(&T) -> isize + Send + Sync,\n    store: impl Fn(&T, isize) + Send + Sync,\n) {\n    let n: usize = if cfg!(miri) {\n        10\n    } else if cfg!(any(qemu, valgrind)) {\n        5_000\n    } else {\n        50_000\n    };\n\n    let mut start: isize = 0;\n    #[allow(clippy::cast_possible_wrap)]\n    let mut end: isize = n as isize;\n    // This test is relatively fast because it spawns only one thread, but\n    // the iterations are limited to a maximum value of integers.\n    if max < end {\n        start = min;\n        end = max;\n    }\n    assert!((start..end).len() <= n, \"{}\", (start..end).len());\n    let a = &new(start);\n    let b = &AtomicIsize::new(start);\n    let a_ready = &AtomicUsize::new(0);\n    let b_ready = &AtomicUsize::new(0);\n    thread::scope(|s| {\n        s.spawn(|_| {\n            while a_ready.load(Ordering::Relaxed) == 0 {}\n            b_ready.store(1, Ordering::Relaxed);\n            for i in start..end {\n                b.store(i, Ordering::Relaxed);\n                store(a, i);\n            }\n        });\n        let end = end - 1;\n        a_ready.store(1, Ordering::Relaxed);\n        while b_ready.load(Ordering::Relaxed) == 0 {}\n        loop {\n            let a = load(a);\n            let b = b.load(Ordering::Relaxed);\n            assert!(a <= b, \"a={},b={}\", a, b);\n            if a == end && b == end {\n                break;\n            }\n        }\n    })\n    .unwrap();\n}\n// To test this working correctly:\n// - Uncomment can_panic case in __stress_seqcst,\n//   and run test with `--release -- seqcst1 --ignored`.\n//   At least on AArch64 machine, some \"panicked as expected\" will be shown.\n// - Change aarch64.rs's 128-bit seqcst load from `ldar; ldp; dmb ishld` to `ldp; dmb ish`\n//   and run test with `--release -- seqcst1` on AArch64 macOS or other AArch64 which supports FEAT_LSE2\n//   with `RUSTFLAGS=-C target-feature=+lse2`.\n//   tests::stress_swap_u128::seqcst1_load_seqcst_swap_seqcst should fail within a few repetitions.\npub(crate) fn seqcst1<T: Send + Sync>(\n    _min: isize,\n    #[allow(unused_variables)] max: isize,\n    new: impl Fn(isize) -> T,\n    load: impl Fn(&T) -> isize + Send + Sync,\n    store: impl Fn(&T, isize) + Send + Sync,\n) {\n    let n: usize = if cfg!(miri) {\n        8\n    } else if cfg!(valgrind)\n        || build_context::SANITIZE.contains(\"address\")\n        || build_context::SANITIZE.contains(\"memory\")\n    {\n        50\n    } else if cfg!(qemu)\n        || option_env!(\"GITHUB_ACTIONS\").is_some() && cfg!(not(target_os = \"linux\"))\n    {\n        // GitHub Actions' macOS and Windows runners are slow.\n        5_000\n    } else {\n        50_000\n    };\n\n    let a = &new(0);\n    let b = &new(0);\n    let c = &AtomicUsize::new(0);\n    let a_done = &AtomicUsize::new(0);\n    let a_ready = &AtomicUsize::new(0);\n    let b_ready = &AtomicUsize::new(0);\n    let panicked = &AtomicUsize::new(0);\n    thread::scope(|s| {\n        s.spawn(|_| {\n            for n in 1..n {\n                // Acquire to make initialization of a/b/c visible.\n                while a_ready.load(Ordering::Acquire) != n {\n                    if panicked.load(Ordering::Relaxed) != 0 {\n                        return;\n                    }\n                }\n                b_ready.store(n, Ordering::Relaxed);\n                store(a, 1);\n                if load(b) == 0 {\n                    c.fetch_add(1, Ordering::Relaxed);\n                }\n                // Release to make update of c visible.\n                a_done.store(n, Ordering::Release);\n            }\n        });\n        for n in 1..n {\n            store(a, 0);\n            store(b, 0);\n            c.store(0, Ordering::Relaxed);\n            // Release to make initialization of a/b/c visible.\n            a_ready.store(n, Ordering::Release);\n            while b_ready.load(Ordering::Relaxed) != n {}\n            store(b, 1);\n            if load(a) == 0 {\n                c.fetch_add(1, Ordering::Relaxed);\n            }\n            // Acquire to make update of c visible.\n            while a_done.load(Ordering::Acquire) != n {}\n            let c = c.load(Ordering::Relaxed);\n            let ok = matches!(c, 0 | 1);\n            if !ok {\n                panicked.store(1, Ordering::Relaxed);\n                panic!(\"c={},n={}\", c, n);\n            }\n        }\n    })\n    .unwrap();\n}\n// Catches unwinding panic on architectures with weak memory models.\n#[allow(dead_code)]\npub(crate) fn catch_unwind_on_weak_memory_arch(pat: &str, function_name: &str, f: impl Fn()) {\n    // With x86 TSO, RISC-V TSO (optional), SPARC TSO (optional, default?),\n    // and IBM-370 memory models should never be a panic here.\n    // Miri emulates weak memory models regardless of target architectures.\n    if cfg!(all(\n        any(\n            target_arch = \"x86\",\n            target_arch = \"x86_64\",\n            target_arch = \"s390x\",\n            target_arch = \"sparc\",\n            target_arch = \"sparc64\",\n            all(any(target_arch = \"riscv32\", target_arch = \"riscv64\"), target_feature = \"ztso\"),\n        ),\n        not(any(miri)),\n    )) {\n        f();\n    } else if !is_panic_abort() {\n        // This could be Err on architectures with weak memory models.\n        // However, this does not necessarily mean that it will always be panic,\n        // and implementing it with stronger orderings is also okay.\n        match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {\n            Ok(()) => {\n                // panic!();\n            }\n            Err(msg) => {\n                let msg = msg\n                    .downcast_ref::<std::string::String>()\n                    .cloned()\n                    .unwrap_or_else(|| msg.downcast_ref::<&'static str>().copied().unwrap().into());\n                assert!(msg.contains(pat), \"{}\", msg);\n                test_helper::eprintln_nocapture!(\"  {} panicked as expected\", function_name);\n            }\n        }\n    }\n}\n// Catches unwinding panic on architectures with non-sequentially consistent memory models.\n#[allow(dead_code)]\npub(crate) fn catch_unwind_on_non_seqcst_arch(pat: &str, function_name: &str, f: impl Fn()) {\n    if !is_panic_abort() {\n        // This could be Err on architectures with non-sequentially consistent memory models.\n        // However, this does not necessarily mean that it will always be panic,\n        // and implementing it with stronger orderings is also okay.\n        match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {\n            Ok(()) => {\n                // panic!();\n            }\n            Err(msg) => {\n                let msg = msg\n                    .downcast_ref::<std::string::String>()\n                    .cloned()\n                    .unwrap_or_else(|| msg.downcast_ref::<&'static str>().copied().unwrap().into());\n                assert!(msg.contains(pat), \"{}\", msg);\n                test_helper::eprintln_nocapture!(\"  {} panicked as expected\", function_name);\n            }\n        }\n    }\n}\nmacro_rules! __call_stress_test_fn {\n    ($name:ident, $atomic_type:ident,\n        $int_type:ident, load, cas, $load_order:ident, $store_order:ident\n    ) => {\n        $name(\n            $int_type::MIN.try_into().unwrap_or(isize::MIN),\n            $int_type::MAX.try_into().unwrap_or(isize::MAX),\n            |v| <$atomic_type>::new(v as $int_type),\n            |a| a.load(Ordering::$load_order) as isize,\n            |a, v| {\n                a.fetch_update(Ordering::$store_order, Ordering::Relaxed, |_| Some(v as $int_type))\n                    .unwrap();\n            },\n        )\n    };\n    ($name:ident, $atomic_type:ident,\n        $int_type:ident, load, $write:ident, $load_order:ident, $store_order:ident\n    ) => {\n        $name(\n            $int_type::MIN.try_into().unwrap_or(isize::MIN),\n            $int_type::MAX.try_into().unwrap_or(isize::MAX),\n            |v| <$atomic_type>::new(v as $int_type),\n            |a| a.load(Ordering::$load_order) as isize,\n            |a, v| {\n                a.$write(v as $int_type, Ordering::$store_order);\n            },\n        )\n    };\n    ($name:ident, $atomic_type:ident,\n        $int_type:ident, cas, $write:ident, $load_order:ident, $store_order:ident\n    ) => {\n        $name(\n            $int_type::MIN.try_into().unwrap_or(isize::MIN),\n            $int_type::MAX.try_into().unwrap_or(isize::MAX),\n            |v| <$atomic_type>::new(v as $int_type),\n            |a| {\n                a.compare_exchange(0, 0, Ordering::$load_order, match Ordering::$load_order {\n                    Ordering::Release => Ordering::Relaxed,\n                    Ordering::AcqRel => Ordering::Acquire,\n                    _ => Ordering::$load_order,\n                })\n                .unwrap_or_else(|x| x) as isize\n            },\n            |a, v| {\n                a.$write(v as $int_type, Ordering::$store_order);\n            },\n        )\n    };\n    ($name:ident, $atomic_type:ident,\n        $int_type:ident, cas_weak, $write:ident, $load_order:ident, $store_order:ident\n    ) => {\n        $name(\n            $int_type::MIN.try_into().unwrap_or(isize::MIN),\n            $int_type::MAX.try_into().unwrap_or(isize::MAX),\n            |v| <$atomic_type>::new(v as $int_type),\n            |a| {\n                a.compare_exchange_weak(0, 0, Ordering::$load_order, match Ordering::$load_order {\n                    Ordering::Release => Ordering::Relaxed,\n                    Ordering::AcqRel => Ordering::Acquire,\n                    _ => Ordering::$load_order,\n                })\n                .unwrap_or_else(|x| x) as isize\n            },\n            |a, v| {\n                a.$write(v as $int_type, Ordering::$store_order);\n            },\n        )\n    };\n}\nmacro_rules! stress_test_load_store {\n    ($int_type:ident) => {\n        paste::paste! {\n            #[allow(\n                clippy::alloc_instead_of_core,\n                clippy::std_instead_of_alloc,\n                clippy::std_instead_of_core,\n                clippy::undocumented_unsafe_blocks\n            )]\n            mod [<stress_load_store_ $int_type>] {\n                use std::{convert::TryInto as _, sync::atomic::Ordering};\n\n                use crate::tests::helper::*;\n                use super::*;\n\n                __stress_acquire_release!(can_panic, $int_type, load, store, Relaxed, Relaxed);\n                __stress_acquire_release!(can_panic, $int_type, load, store, Relaxed, Release);\n                __stress_acquire_release!(can_panic, $int_type, load, store, Relaxed, SeqCst);\n                __stress_acquire_release!(can_panic, $int_type, load, store, Acquire, Relaxed);\n                __stress_acquire_release!(should_pass, $int_type, load, store, Acquire, Release);\n                __stress_acquire_release!(should_pass, $int_type, load, store, Acquire, SeqCst);\n                __stress_acquire_release!(can_panic, $int_type, load, store, SeqCst, Relaxed);\n                __stress_acquire_release!(should_pass, $int_type, load, store, SeqCst, Release);\n                __stress_acquire_release!(should_pass, $int_type, load, store, SeqCst, SeqCst);\n\n                __stress_seqcst!(can_panic, $int_type, load, store, Relaxed, Relaxed);\n                __stress_seqcst!(can_panic, $int_type, load, store, Relaxed, Release);\n                __stress_seqcst!(can_panic, $int_type, load, store, Relaxed, SeqCst);\n                __stress_seqcst!(can_panic, $int_type, load, store, Acquire, Relaxed);\n                __stress_seqcst!(can_panic, $int_type, load, store, Acquire, Release);\n                __stress_seqcst!(can_panic, $int_type, load, store, Acquire, SeqCst);\n                __stress_seqcst!(can_panic, $int_type, load, store, SeqCst, Relaxed);\n                __stress_seqcst!(can_panic, $int_type, load, store, SeqCst, Release);\n                __stress_seqcst!(should_pass, $int_type, load, store, SeqCst, SeqCst);\n            }\n        }\n    };\n}\nmacro_rules! stress_test {\n    ($int_type:ident) => {\n        stress_test_load_store!($int_type);\n        paste::paste! {\n            #[allow(\n                clippy::alloc_instead_of_core,\n                clippy::std_instead_of_alloc,\n                clippy::std_instead_of_core,\n                clippy::undocumented_unsafe_blocks\n            )]\n            mod [<stress_swap_ $int_type>] {\n                use std::{convert::TryInto as _, sync::atomic::Ordering};\n\n                use crate::tests::helper::*;\n                use super::*;\n\n                __stress_acquire_release!(can_panic, $int_type, load, swap, Relaxed, Relaxed);\n                __stress_acquire_release!(can_panic, $int_type, load, swap, Relaxed, Acquire);\n                __stress_acquire_release!(can_panic, $int_type, load, swap, Relaxed, Release);\n                __stress_acquire_release!(can_panic, $int_type, load, swap, Relaxed, AcqRel);\n                __stress_acquire_release!(can_panic, $int_type, load, swap, Relaxed, SeqCst);\n                __stress_acquire_release!(can_panic, $int_type, load, swap, Acquire, Relaxed);\n                __stress_acquire_release!(can_panic, $int_type, load, swap, Acquire, Acquire);\n                __stress_acquire_release!(should_pass, $int_type, load, swap, Acquire, Release);\n                __stress_acquire_release!(should_pass, $int_type, load, swap, Acquire, AcqRel);\n                __stress_acquire_release!(should_pass, $int_type, load, swap, Acquire, SeqCst);\n                __stress_acquire_release!(can_panic, $int_type, load, swap, SeqCst, Relaxed);\n                __stress_acquire_release!(can_panic, $int_type, load, swap, SeqCst, Acquire);\n                __stress_acquire_release!(should_pass, $int_type, load, swap, SeqCst, Release);\n                __stress_acquire_release!(should_pass, $int_type, load, swap, SeqCst, AcqRel);\n                __stress_acquire_release!(should_pass, $int_type, load, swap, SeqCst, SeqCst);\n\n                __stress_seqcst!(can_panic, $int_type, load, swap, Relaxed, Relaxed);\n                __stress_seqcst!(can_panic, $int_type, load, swap, Relaxed, Acquire);\n                __stress_seqcst!(can_panic, $int_type, load, swap, Relaxed, Release);\n                __stress_seqcst!(can_panic, $int_type, load, swap, Relaxed, AcqRel);\n                __stress_seqcst!(can_panic, $int_type, load, swap, Relaxed, SeqCst);\n                __stress_seqcst!(can_panic, $int_type, load, swap, Acquire, Relaxed);\n                __stress_seqcst!(can_panic, $int_type, load, swap, Acquire, Acquire);\n                __stress_seqcst!(can_panic, $int_type, load, swap, Acquire, Release);\n                __stress_seqcst!(can_panic, $int_type, load, swap, Acquire, AcqRel);\n                __stress_seqcst!(can_panic, $int_type, load, swap, Acquire, SeqCst);\n                __stress_seqcst!(can_panic, $int_type, load, swap, SeqCst, Relaxed);\n                __stress_seqcst!(can_panic, $int_type, load, swap, SeqCst, Acquire);\n                __stress_seqcst!(can_panic, $int_type, load, swap, SeqCst, Release);\n                __stress_seqcst!(can_panic, $int_type, load, swap, SeqCst, AcqRel);\n                __stress_seqcst!(should_pass, $int_type, load, swap, SeqCst, SeqCst);\n            }\n        }\n        // TODO: cas\n    };\n}\n\n#[cfg(feature = \"float\")]\npub(crate) mod float_rand {\n    #[cfg(portable_atomic_unstable_f16)]\n    pub(crate) fn f16(rng: &mut fastrand::Rng) -> f16 {\n        f16::from_bits(rng.u16(..))\n    }\n    pub(crate) fn f32(rng: &mut fastrand::Rng) -> f32 {\n        f32::from_bits(rng.u32(..))\n    }\n    #[cfg(not(all(not(debug_assertions), target_arch = \"x86\", not(target_feature = \"sse2\"))))]\n    pub(crate) fn f64(rng: &mut fastrand::Rng) -> f64 {\n        f64::from_bits(rng.u64(..))\n    }\n    #[cfg(portable_atomic_unstable_f128)]\n    pub(crate) fn f128(rng: &mut fastrand::Rng) -> f128 {\n        f128::from_bits(rng.u128(..))\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/tests/mod.rs",
      "sha256": "74aff58531edbba0c833d6a3ec7a45b987896945074763ab3a88f6d99feff05e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![allow(\n    clippy::alloc_instead_of_core,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    clippy::undocumented_unsafe_blocks,\n    clippy::wildcard_imports\n)]\n\n#[macro_use]\npub(crate) mod helper;\n\n#[allow(dead_code)]\n#[path = \"../../version.rs\"]\nmod version;\n\nuse test_helper as _; // For critical-section test\n\nuse super::*;\n\ntest_atomic_bool_pub!();\ntest_atomic_ptr_pub!();\n\ntest_atomic_int_pub!(isize);\ntest_atomic_int_pub!(usize);\ntest_atomic_int_pub!(i8);\ntest_atomic_int_pub!(u8);\ntest_atomic_int_pub!(i16);\ntest_atomic_int_pub!(u16);\ntest_atomic_int_pub!(i32);\ntest_atomic_int_pub!(u32);\ntest_atomic_int_pub!(i64);\ntest_atomic_int_pub!(u64);\n#[cfg(not(all(valgrind, target_arch = \"powerpc64\")))] // TODO(powerpc64): Hang (as of Valgrind 3.26)\ntest_atomic_int_pub!(i128);\n#[cfg(not(all(valgrind, target_arch = \"powerpc64\")))] // TODO(powerpc64): Hang (as of Valgrind 3.26)\ntest_atomic_int_pub!(u128);\n\n#[cfg(all(feature = \"float\", portable_atomic_unstable_f16))]\ntest_atomic_float_pub!(f16);\n#[cfg(feature = \"float\")]\ntest_atomic_float_pub!(f32);\n#[cfg(feature = \"float\")]\n// TODO: rustc bug: https://github.com/rust-lang/rust/issues/114479\n#[cfg(not(all(not(debug_assertions), target_arch = \"x86\", not(target_feature = \"sse2\"))))]\ntest_atomic_float_pub!(f64);\n#[cfg(all(feature = \"float\", portable_atomic_unstable_f128))]\ntest_atomic_float_pub!(f128);\n\n#[deny(improper_ctypes)]\nextern \"C\" {\n    fn _atomic_bool_ffi_safety(_: AtomicBool);\n    fn _atomic_ptr_ffi_safety(_: AtomicPtr<u8>);\n    fn _atomic_isize_ffi_safety(_: AtomicIsize);\n    fn _atomic_usize_ffi_safety(_: AtomicUsize);\n    fn _atomic_i8_ffi_safety(_: AtomicI8);\n    fn _atomic_u8_ffi_safety(_: AtomicU8);\n    fn _atomic_i16_ffi_safety(_: AtomicI16);\n    fn _atomic_u16_ffi_safety(_: AtomicU16);\n    fn _atomic_i32_ffi_safety(_: AtomicI32);\n    fn _atomic_u32_ffi_safety(_: AtomicU32);\n    fn _atomic_i64_ffi_safety(_: AtomicI64);\n    fn _atomic_u64_ffi_safety(_: AtomicU64);\n    #[rustversion::since(1.89)] // https://github.com/rust-lang/rust/pull/137306\n    fn _atomic_i128_ffi_safety(_: AtomicI128);\n    #[rustversion::since(1.89)] // https://github.com/rust-lang/rust/pull/137306\n    fn _atomic_u128_ffi_safety(_: AtomicU128);\n    #[cfg(all(feature = \"float\", portable_atomic_unstable_f16))]\n    fn _atomic_f16_ffi_safety(_: AtomicF16);\n    #[cfg(feature = \"float\")]\n    fn _atomic_f32_ffi_safety(_: AtomicF32);\n    #[cfg(feature = \"float\")]\n    fn _atomic_f64_ffi_safety(_: AtomicF64);\n    #[cfg(all(feature = \"float\", portable_atomic_unstable_f128))]\n    fn _atomic_f128_ffi_safety(_: AtomicF128);\n}\n\n#[test]\nfn test_is_lock_free() {\n    assert!(AtomicI8::is_always_lock_free());\n    assert!(AtomicI8::is_lock_free());\n    assert!(AtomicU8::is_always_lock_free());\n    assert!(AtomicU8::is_lock_free());\n    assert!(AtomicI16::is_always_lock_free());\n    assert!(AtomicI16::is_lock_free());\n    assert!(AtomicU16::is_always_lock_free());\n    assert!(AtomicU16::is_lock_free());\n    #[cfg(all(feature = \"float\", portable_atomic_unstable_f16))]\n    assert!(AtomicF16::is_always_lock_free());\n    #[cfg(all(feature = \"float\", portable_atomic_unstable_f16))]\n    assert!(AtomicF16::is_lock_free());\n    assert!(AtomicI32::is_always_lock_free());\n    assert!(AtomicI32::is_lock_free());\n    assert!(AtomicU32::is_always_lock_free());\n    assert!(AtomicU32::is_lock_free());\n    #[cfg(feature = \"float\")]\n    assert!(AtomicF32::is_always_lock_free());\n    #[cfg(feature = \"float\")]\n    assert!(AtomicF32::is_lock_free());\n    #[cfg(not(portable_atomic_no_cfg_target_has_atomic))]\n    {\n        if cfg!(any(\n            target_has_atomic = \"64\",\n            all(\n                target_arch = \"riscv32\",\n                not(any(miri, portable_atomic_sanitize_thread)),\n                any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n                any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n            ),\n        )) {\n            assert!(AtomicI64::is_always_lock_free());\n            assert!(AtomicI64::is_lock_free());\n            assert!(AtomicU64::is_always_lock_free());\n            assert!(AtomicU64::is_lock_free());\n            #[cfg(feature = \"float\")]\n            assert!(AtomicF64::is_always_lock_free());\n            #[cfg(feature = \"float\")]\n            assert!(AtomicF64::is_lock_free());\n        } else if cfg!(all(\n            feature = \"fallback\",\n            target_arch = \"arm\",\n            not(any(miri, portable_atomic_sanitize_thread)),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n            any(target_os = \"linux\", target_os = \"android\"),\n            not(any(target_feature = \"v6\", portable_atomic_target_feature = \"v6\")),\n            not(portable_atomic_no_outline_atomics),\n            not(target_has_atomic = \"64\"),\n            not(portable_atomic_test_detect_false),\n        )) {\n            assert!(!AtomicI64::is_always_lock_free());\n            assert!(!AtomicU64::is_always_lock_free());\n            #[cfg(feature = \"float\")]\n            assert!(!AtomicF64::is_always_lock_free());\n            assert!(AtomicI64::is_lock_free());\n            assert!(AtomicU64::is_lock_free());\n            #[cfg(feature = \"float\")]\n            assert!(AtomicF64::is_lock_free());\n        } else {\n            assert!(!AtomicI64::is_always_lock_free());\n            assert!(!AtomicU64::is_always_lock_free());\n            #[cfg(feature = \"float\")]\n            assert!(!AtomicF64::is_always_lock_free());\n            #[cfg(not(target_arch = \"riscv32\"))]\n            {\n                assert!(!AtomicI64::is_lock_free());\n                assert!(!AtomicU64::is_lock_free());\n                #[cfg(feature = \"float\")]\n                assert!(!AtomicF64::is_lock_free());\n            }\n            #[cfg(target_arch = \"riscv32\")]\n            {\n                // TODO(riscv): check detect.has_zacas\n            }\n        }\n    }\n    if cfg!(portable_atomic_no_asm) && cfg!(not(portable_atomic_unstable_asm)) {\n        assert!(!AtomicI128::is_always_lock_free());\n        assert!(!AtomicI128::is_lock_free());\n        assert!(!AtomicU128::is_always_lock_free());\n        assert!(!AtomicU128::is_lock_free());\n        #[cfg(all(feature = \"float\", portable_atomic_unstable_f128))]\n        assert!(!AtomicF128::is_always_lock_free());\n        #[cfg(all(feature = \"float\", portable_atomic_unstable_f128))]\n        assert!(!AtomicF128::is_lock_free());\n    } else if cfg!(any(\n        all(\n            target_arch = \"aarch64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            any(not(portable_atomic_no_asm), portable_atomic_unstable_asm),\n        ),\n        all(\n            target_arch = \"arm64ec\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n        ),\n        all(\n            target_arch = \"x86_64\",\n            any(target_feature = \"cmpxchg16b\", portable_atomic_target_feature = \"cmpxchg16b\"),\n        ),\n        all(\n            target_arch = \"riscv64\",\n            any(target_feature = \"zacas\", portable_atomic_target_feature = \"zacas\"),\n        ),\n        all(\n            target_arch = \"powerpc64\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n            any(\n                target_feature = \"quadword-atomics\",\n                portable_atomic_target_feature = \"quadword-atomics\",\n            ),\n        ),\n        all(\n            target_arch = \"s390x\",\n            not(all(\n                any(miri, portable_atomic_sanitize_thread),\n                not(portable_atomic_atomic_intrinsics),\n            )),\n            not(portable_atomic_no_asm),\n        ),\n    )) {\n        assert!(AtomicI128::is_always_lock_free());\n        assert!(AtomicI128::is_lock_free());\n        assert!(AtomicU128::is_always_lock_free());\n        assert!(AtomicU128::is_lock_free());\n        #[cfg(all(feature = \"float\", portable_atomic_unstable_f128))]\n        assert!(AtomicF128::is_always_lock_free());\n        #[cfg(all(feature = \"float\", portable_atomic_unstable_f128))]\n        assert!(AtomicF128::is_lock_free());\n    } else {\n        assert!(!AtomicI128::is_always_lock_free());\n        assert!(!AtomicU128::is_always_lock_free());\n        #[cfg(all(feature = \"float\", portable_atomic_unstable_f128))]\n        assert!(!AtomicF128::is_always_lock_free());\n        #[cfg(not(any(\n            target_arch = \"x86_64\",\n            target_arch = \"powerpc64\",\n            target_arch = \"riscv64\",\n        )))]\n        {\n            assert!(!AtomicI128::is_lock_free());\n            assert!(!AtomicU128::is_lock_free());\n            #[cfg(all(feature = \"float\", portable_atomic_unstable_f128))]\n            assert!(!AtomicF128::is_lock_free());\n        }\n        #[cfg(target_arch = \"x86_64\")]\n        {\n            let has_cmpxchg16b = cfg!(all(\n                feature = \"fallback\",\n                not(portable_atomic_no_outline_atomics),\n                not(any(target_env = \"sgx\", miri)),\n                not(portable_atomic_test_detect_false),\n            )) && std::is_x86_feature_detected!(\"cmpxchg16b\");\n            assert_eq!(AtomicI128::is_lock_free(), has_cmpxchg16b);\n            assert_eq!(AtomicU128::is_lock_free(), has_cmpxchg16b);\n            #[cfg(all(feature = \"float\", portable_atomic_unstable_f128))]\n            assert_eq!(AtomicF128::is_lock_free(), has_cmpxchg16b);\n        }\n        #[cfg(target_arch = \"powerpc64\")]\n        {\n            // TODO(powerpc64): is_powerpc_feature_detected is unstable\n        }\n        #[cfg(target_arch = \"riscv64\")]\n        {\n            // TODO(riscv): check detect.has_zacas\n        }\n    }\n}\n\n// test version parsing code used in the build script.\n#[test]\nfn test_rustc_version() {\n    use self::version::Version;\n\n    // rustc 1.34 (rustup)\n    let v = Version::parse(\n        \"rustc 1.34.2 (6c2484dc3 2019-05-13)\nbinary: rustc\ncommit-hash: 6c2484dc3c532c052f159264e970278d8b77cdc9\ncommit-date: 2019-05-13\nhost: x86_64-apple-darwin\nrelease: 1.34.2\nLLVM version: 8.0\",\n    )\n    .unwrap();\n    assert_eq!(v, Version::stable(34, 8));\n\n    // rustc 1.50 (rustup)\n    let v = Version::parse(\n        \"rustc 1.50.0 (cb75ad5db 2021-02-10)\nbinary: rustc\ncommit-hash: cb75ad5db02783e8b0222fee363c5f63f7e2cf5b\ncommit-date: 2021-02-10\nhost: aarch64-unknown-linux-gnu\nrelease: 1.50.0\",\n    )\n    .unwrap();\n    assert_eq!(v, Version::stable(50, 0));\n\n    // rustc 1.67 (rustup)\n    let v = Version::parse(\n        \"rustc 1.67.0 (fc594f156 2023-01-24)\nbinary: rustc\ncommit-hash: fc594f15669680fa70d255faec3ca3fb507c3405\ncommit-date: 2023-01-24\nhost: aarch64-apple-darwin\nrelease: 1.67.0\nLLVM version: 15.0.6\",\n    )\n    .unwrap();\n    assert_eq!(v, Version::stable(67, 15));\n\n    // rustc 1.68-beta (rustup)\n    let v = Version::parse(\n        \"rustc 1.68.0-beta.2 (10b73bf73 2023-02-01)\nbinary: rustc\ncommit-hash: 10b73bf73a6b770cd92ad8ff538173bc3298411c\ncommit-date: 2023-02-01\nhost: aarch64-apple-darwin\nrelease: 1.68.0-beta.2\nLLVM version: 15.0.6\",\n    )\n    .unwrap();\n    // We do not distinguish between stable and beta because we are only\n    // interested in whether unstable features are potentially available.\n    assert_eq!(v, Version::stable(68, 15));\n\n    // rustc nightly-2019-01-27 (rustup)\n    let v = Version::parse(\n        \"rustc 1.33.0-nightly (20c2cba61 2019-01-26)\nbinary: rustc\ncommit-hash: 20c2cba61dc83e612d25ed496025171caa3db30f\ncommit-date: 2019-01-26\nhost: x86_64-apple-darwin\nrelease: 1.33.0-nightly\nLLVM version: 8.0\",\n    )\n    .unwrap();\n    assert_eq!(v.minor, 33);\n    assert!(v.nightly);\n    assert_eq!(v.llvm, 8);\n    assert_eq!(v.commit_date().year, 2019);\n    assert_eq!(v.commit_date().month, 1);\n    assert_eq!(v.commit_date().day, 26);\n\n    // rustc 1.69-nightly (rustup)\n    let v = Version::parse(\n        \"rustc 1.69.0-nightly (bd39bbb4b 2023-02-07)\nbinary: rustc\ncommit-hash: bd39bbb4bb92df439bf6d85470e296cc6a47ffbd\ncommit-date: 2023-02-07\nhost: aarch64-apple-darwin\nrelease: 1.69.0-nightly\nLLVM version: 15.0.7\",\n    )\n    .unwrap();\n    assert_eq!(v.minor, 69);\n    assert!(v.nightly);\n    assert_eq!(v.llvm, 15);\n    assert_eq!(v.commit_date().year, 2023);\n    assert_eq!(v.commit_date().month, 2);\n    assert_eq!(v.commit_date().day, 7);\n\n    // clippy-driver 1.69-nightly (rustup)\n    let v = Version::parse(\n        \"rustc 1.69.0-nightly (bd39bbb4b 2023-02-07)\nbinary: rustc\ncommit-hash: bd39bbb4bb92df439bf6d85470e296cc6a47ffbd\ncommit-date: 2023-02-07\nhost: aarch64-apple-darwin\nrelease: 1.69.0-nightly\nLLVM version: 15.0.7\",\n    )\n    .unwrap();\n    assert_eq!(v.minor, 69);\n    assert!(v.nightly);\n    assert_eq!(v.llvm, 15);\n    assert_eq!(v.commit_date().year, 2023);\n    assert_eq!(v.commit_date().month, 2);\n    assert_eq!(v.commit_date().day, 7);\n\n    // rustc 1.69-dev (from source: ./x.py build)\n    let v = Version::parse(\n        \"rustc 1.69.0-dev\nbinary: rustc\ncommit-hash: unknown\ncommit-date: unknown\nhost: aarch64-unknown-linux-gnu\nrelease: 1.69.0-dev\nLLVM version: 16.0.0\",\n    )\n    .unwrap();\n    assert_eq!(v.minor, 69);\n    assert!(v.nightly);\n    assert_eq!(v.llvm, 16);\n    assert_eq!(v.commit_date().year, 0);\n    assert_eq!(v.commit_date().month, 0);\n    assert_eq!(v.commit_date().day, 0);\n\n    // rustc 1.48 (debian 11: apt-get install cargo)\n    let v = Version::parse(\n        \"rustc 1.48.0\nbinary: rustc\ncommit-hash: unknown\ncommit-date: unknown\nhost: aarch64-unknown-linux-gnu\nrelease: 1.48.0\nLLVM version: 11.0\",\n    )\n    .unwrap();\n    assert_eq!(v, Version::stable(48, 11));\n\n    // rustc 1.67 (fedora: dnf install cargo)\n    let v = Version::parse(\n        \"rustc 1.67.0 (fc594f156 2023-01-24) (Fedora 1.67.0-2.fc37)\nbinary: rustc\ncommit-hash: fc594f15669680fa70d255faec3ca3fb507c3405\ncommit-date: 2023-01-24\nhost: aarch64-unknown-linux-gnu\nrelease: 1.67.0\nLLVM version: 15.0.7\",\n    )\n    .unwrap();\n    assert_eq!(v, Version::stable(67, 15));\n\n    // rustc 1.64 (alpine: apk add cargo)\n    let v = Version::parse(\n        \"rustc 1.64.0\nbinary: rustc\ncommit-hash: unknown\ncommit-date: unknown\nhost: aarch64-alpine-linux-musl\nrelease: 1.64.0\nLLVM version: 15.0.3\",\n    )\n    .unwrap();\n    assert_eq!(v, Version::stable(64, 15));\n}\n\n#[cfg(feature = \"serde\")]\n#[test]\nfn test_serde() {\n    use std::{eprint, eprintln, fmt};\n\n    use serde::{\n        de::{Deserialize, Deserializer},\n        ser::{Serialize, Serializer},\n    };\n    use serde_test::{Token, assert_tokens};\n\n    #[derive(Debug)]\n    struct DebugPartialEq<T>(T);\n    impl<T: fmt::Debug> PartialEq for DebugPartialEq<T> {\n        fn eq(&self, other: &Self) -> bool {\n            std::format!(\"{:?}\", self) == std::format!(\"{:?}\", other)\n        }\n    }\n    impl<T: Serialize> Serialize for DebugPartialEq<T> {\n        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n        where\n            S: Serializer,\n        {\n            self.0.serialize(serializer)\n        }\n    }\n    impl<'de, T: Deserialize<'de>> Deserialize<'de> for DebugPartialEq<T> {\n        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n        where\n            D: Deserializer<'de>,\n        {\n            T::deserialize(deserializer).map(Self)\n        }\n    }\n\n    macro_rules! t {\n        ($atomic_type:ty, $value_type:ident $(as $token_value_type:ident)?, $token_type:ident) => {\n            eprint!(\"test_serde {} ... \", stringify!($value_type));\n            assert_tokens(&DebugPartialEq(<$atomic_type>::new($value_type::MAX)), &[\n                Token::$token_type($value_type::MAX $(as $token_value_type)?),\n            ]);\n            assert_tokens(&DebugPartialEq(<$atomic_type>::new($value_type::MIN)), &[\n                Token::$token_type($value_type::MIN $(as $token_value_type)?),\n            ]);\n            eprintln!(\"ok\");\n        };\n    }\n\n    assert_tokens(&DebugPartialEq(AtomicBool::new(true)), &[Token::Bool(true)]);\n    assert_tokens(&DebugPartialEq(AtomicBool::new(false)), &[Token::Bool(false)]);\n    t!(AtomicIsize, isize as i64, I64);\n    t!(AtomicUsize, usize as u64, U64);\n    t!(AtomicI8, i8, I8);\n    t!(AtomicU8, u8, U8);\n    t!(AtomicI16, i16, I16);\n    t!(AtomicU16, u16, U16);\n    t!(AtomicI32, i32, I32);\n    t!(AtomicU32, u32, U32);\n    t!(AtomicI64, i64, I64);\n    t!(AtomicU64, u64, U64);\n    #[cfg(not(all(valgrind, target_arch = \"powerpc64\")))] // TODO(powerpc64): Hang (as of Valgrind 3.26)\n    t!(AtomicI128, i128, I128);\n    #[cfg(not(all(valgrind, target_arch = \"powerpc64\")))] // TODO(powerpc64): Hang (as of Valgrind 3.26)\n    t!(AtomicU128, u128, U128);\n    // TODO(f16_and_f128): Test f16 & f128 once stabilized.\n    #[cfg(feature = \"float\")]\n    t!(AtomicF32, f32, F32);\n    #[cfg(feature = \"float\")]\n    t!(AtomicF64, f64, F64);\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "src/utils.rs",
      "sha256": "9211b8295c0ec7dc02592731264a0d5516622541126ddd768006d79ef6749dfe",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![cfg_attr(not(all(test, feature = \"float\")), allow(dead_code, unused_macros))]\n\n#[allow(unused_imports)]\npub(crate) use self::generated::{RegISize, RegSize};\n#[macro_use]\n#[path = \"gen/utils.rs\"]\nmod generated;\n\nuse core::sync::atomic::Ordering;\n\nmacro_rules! static_assert {\n    ($cond:expr $(,)?) => {{\n        let [()] = [(); (true /* type check */ & $cond) as usize];\n    }};\n}\n\nmacro_rules! static_assert_layout {\n    ($atomic_type:ty, $value_type:ty) => {\n        static_assert!(\n            core::mem::align_of::<$atomic_type>() == core::mem::size_of::<$atomic_type>()\n        );\n        static_assert!(core::mem::size_of::<$atomic_type>() == core::mem::size_of::<$value_type>());\n    };\n}\n\n// #[doc = concat!(...)] requires Rust 1.54\nmacro_rules! doc_comment {\n    ($doc:expr, $($tt:tt)*) => {\n        #[doc = $doc]\n        $($tt)*\n    };\n}\n\n// Adapted from https://github.com/BurntSushi/memchr/blob/2.4.1/src/memchr/x86/mod.rs#L9-L71.\n/// # Safety\n///\n/// - the caller must uphold the safety contract for the function returned by $detect_body.\n/// - the memory pointed by the function pointer returned by $detect_body must be visible from any threads.\n///\n/// The second requirement is always met if the function pointer is to the function definition.\n/// (Currently, all uses of this macro in our code are in this case.)\n#[allow(unused_macros)]\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(\n    target_arch = \"aarch64\",\n    target_arch = \"arm\",\n    target_arch = \"arm64ec\",\n    target_arch = \"powerpc64\",\n    target_arch = \"riscv32\",\n    target_arch = \"riscv64\",\n    all(target_arch = \"x86_64\", not(any(target_env = \"sgx\", miri))),\n))]\nmacro_rules! ifunc {\n    (unsafe fn($($arg_pat:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)? { $($init_body:tt)* }) => {{\n        type FnTy = unsafe fn($($arg_ty),*) $(-> $ret_ty)?;\n        static FUNC: core::sync::atomic::AtomicPtr<()>\n            = core::sync::atomic::AtomicPtr::new(init as *mut ());\n        #[cold]\n        unsafe fn init($($arg_pat: $arg_ty),*) $(-> $ret_ty)? {\n            let func: FnTy = { $($init_body)* };\n            FUNC.store(func as *mut (), core::sync::atomic::Ordering::Relaxed);\n            // SAFETY: the caller must uphold the safety contract for the function returned by $init_body.\n            unsafe { func($($arg_pat),*) }\n        }\n        // SAFETY: `FnTy` is a function pointer, which is always safe to transmute with a `*mut ()`.\n        // (To force the caller to use unsafe block for this macro, do not use\n        // unsafe block here.)\n        let func = {\n            core::mem::transmute::<*mut (), FnTy>(FUNC.load(core::sync::atomic::Ordering::Relaxed))\n        };\n        // SAFETY: the caller must uphold the safety contract for the function returned by $init_body.\n        // (To force the caller to use unsafe block for this macro, do not use\n        // unsafe block here.)\n        func($($arg_pat),*)\n    }};\n}\n\n#[cfg(not(portable_atomic_no_asm))]\n#[allow(unused_macros)]\nmacro_rules! __asm {\n    ($($tt:tt)*) => {\n        core::arch::asm!($($tt)*)\n    };\n}\n#[cfg(portable_atomic_no_asm)]\n#[allow(unused_macros)]\nmacro_rules! __asm {\n    ($($tt:tt)*) => {\n        asm!($($tt)*)\n    };\n}\n\n#[allow(unused_macros)]\n#[cfg(not(portable_atomic_no_outline_atomics))]\n#[cfg(any(\n    target_arch = \"aarch64\",\n    target_arch = \"arm\",\n    target_arch = \"arm64ec\",\n    target_arch = \"powerpc64\",\n    target_arch = \"riscv32\",\n    target_arch = \"riscv64\",\n    all(target_arch = \"x86_64\", not(any(target_env = \"sgx\", miri))),\n))]\nmacro_rules! fn_alias {\n    (\n        $(#[$($fn_attr:tt)*])*\n        $vis:vis unsafe fn($($arg_pat:ident: $arg_ty:ty),*) $(-> $ret_ty:ty)?;\n        $(#[$($alias_attr:tt)*])*\n        $new:ident = $from:ident($($last_args:tt)*);\n        $($rest:tt)*\n    ) => {\n        $(#[$($fn_attr)*])*\n        $(#[$($alias_attr)*])*\n        $vis unsafe fn $new($($arg_pat: $arg_ty),*) $(-> $ret_ty)? {\n            // SAFETY: the caller must uphold the safety contract.\n            unsafe { $from($($arg_pat,)* $($last_args)*) }\n        }\n        fn_alias! {\n            $(#[$($fn_attr)*])*\n            $vis unsafe fn($($arg_pat: $arg_ty),*) $(-> $ret_ty)?;\n            $($rest)*\n        }\n    };\n    (\n        $(#[$($attr:tt)*])*\n        $vis:vis unsafe fn($($arg_pat:ident: $arg_ty:ty),*) $(-> $ret_ty:ty)?;\n    ) => {}\n}\n\n/// Make the given function const if the given condition is true.\nmacro_rules! const_fn {\n    (\n        const_if: #[cfg($($cfg:tt)+)];\n        $(#[$($attr:tt)*])*\n        $vis:vis const $($rest:tt)*\n    ) => {\n        #[cfg($($cfg)+)]\n        $(#[$($attr)*])*\n        $vis const $($rest)*\n        #[cfg(not($($cfg)+))]\n        $(#[$($attr)*])*\n        $vis $($rest)*\n    };\n}\n\n/// Implements `core::fmt::Debug` and `serde::{Serialize, Deserialize}` (when serde\n/// feature is enabled) for atomic bool, integer, or float.\nmacro_rules! impl_debug_and_serde {\n    // TODO(f16_and_f128): Implement serde traits for f16 & f128 once stabilized.\n    (AtomicF16) => {\n        impl_debug!(AtomicF16);\n    };\n    (AtomicF128) => {\n        impl_debug!(AtomicF128);\n    };\n    ($atomic_type:ident) => {\n        impl_debug!($atomic_type);\n        #[cfg(feature = \"serde\")]\n        #[cfg_attr(docsrs, doc(cfg(feature = \"serde\")))]\n        impl serde::ser::Serialize for $atomic_type {\n            #[allow(clippy::missing_inline_in_public_items)] // serde doesn't use inline on std atomic's Serialize/Deserialize impl\n            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n            where\n                S: serde::ser::Serializer,\n            {\n                // https://github.com/serde-rs/serde/blob/v1.0.152/serde/src/ser/impls.rs#L958-L959\n                self.load(Ordering::Relaxed).serialize(serializer)\n            }\n        }\n        #[cfg(feature = \"serde\")]\n        #[cfg_attr(docsrs, doc(cfg(feature = \"serde\")))]\n        impl<'de> serde::de::Deserialize<'de> for $atomic_type {\n            #[allow(clippy::missing_inline_in_public_items)] // serde doesn't use inline on std atomic's Serialize/Deserialize impl\n            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n            where\n                D: serde::de::Deserializer<'de>,\n            {\n                serde::de::Deserialize::deserialize(deserializer).map(Self::new)\n            }\n        }\n    };\n}\nmacro_rules! impl_debug {\n    ($atomic_type:ident) => {\n        impl fmt::Debug for $atomic_type {\n            #[inline] // fmt is not hot path, but #[inline] on fmt seems to still be useful: https://github.com/rust-lang/rust/pull/117727\n            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n                // std atomic types use Relaxed in Debug::fmt: https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L2188\n                fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)\n            }\n        }\n    };\n}\n\n// We do not provide `nand` because it cannot be optimized on neither x86 nor MSP430.\n// https://godbolt.org/z/ahWejchbT\nmacro_rules! impl_default_no_fetch_ops {\n    ($atomic_type:ident, bool) => {\n        impl $atomic_type {\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn and(&self, val: bool, order: Ordering) {\n                self.fetch_and(val, order);\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn or(&self, val: bool, order: Ordering) {\n                self.fetch_or(val, order);\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn xor(&self, val: bool, order: Ordering) {\n                self.fetch_xor(val, order);\n            }\n        }\n    };\n    ($atomic_type:ident, $int_type:ty) => {\n        impl $atomic_type {\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn add(&self, val: $int_type, order: Ordering) {\n                self.fetch_add(val, order);\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn sub(&self, val: $int_type, order: Ordering) {\n                self.fetch_sub(val, order);\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn and(&self, val: $int_type, order: Ordering) {\n                self.fetch_and(val, order);\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn or(&self, val: $int_type, order: Ordering) {\n                self.fetch_or(val, order);\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn xor(&self, val: $int_type, order: Ordering) {\n                self.fetch_xor(val, order);\n            }\n        }\n    };\n}\nmacro_rules! impl_default_bit_opts {\n    (AtomicPtr, $int_type:ty) => {\n        impl<T> AtomicPtr<T> {\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn bit_set(&self, bit: u32, order: Ordering) -> bool {\n                #[cfg(portable_atomic_no_strict_provenance)]\n                use crate::utils::ptr::PtrExt as _;\n                let mask = <$int_type>::wrapping_shl(1, bit);\n                self.fetch_or(mask, order).addr() & mask != 0\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn bit_clear(&self, bit: u32, order: Ordering) -> bool {\n                #[cfg(portable_atomic_no_strict_provenance)]\n                use crate::utils::ptr::PtrExt as _;\n                let mask = <$int_type>::wrapping_shl(1, bit);\n                self.fetch_and(!mask, order).addr() & mask != 0\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn bit_toggle(&self, bit: u32, order: Ordering) -> bool {\n                #[cfg(portable_atomic_no_strict_provenance)]\n                use crate::utils::ptr::PtrExt as _;\n                let mask = <$int_type>::wrapping_shl(1, bit);\n                self.fetch_xor(mask, order).addr() & mask != 0\n            }\n        }\n    };\n    ($atomic_type:ident, $int_type:ty) => {\n        impl $atomic_type {\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn bit_set(&self, bit: u32, order: Ordering) -> bool {\n                let mask = <$int_type>::wrapping_shl(1, bit);\n                self.fetch_or(mask, order) & mask != 0\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn bit_clear(&self, bit: u32, order: Ordering) -> bool {\n                let mask = <$int_type>::wrapping_shl(1, bit);\n                self.fetch_and(!mask, order) & mask != 0\n            }\n            #[inline]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn bit_toggle(&self, bit: u32, order: Ordering) -> bool {\n                let mask = <$int_type>::wrapping_shl(1, bit);\n                self.fetch_xor(mask, order) & mask != 0\n            }\n        }\n    };\n}\n\n// This just outputs the input as is, but can be used like an item-level block by using it with cfg.\n// Note: This macro is items!({ }), not items! { }.\n// An extra brace is used in input to make contents rustfmt-able.\nmacro_rules! items {\n    ({$($tt:tt)*}) => {\n        $($tt)*\n    };\n}\n\n// rustfmt-compatible cfg_select/cfg_if alternative\n// Note: This macro is cfg_sel!({ }), not cfg_sel! { }.\n// An extra brace is used in input to make contents rustfmt-able.\nmacro_rules! cfg_sel {\n    ({#[cfg(else)] { $($output:tt)* }}) => {\n        $($output)*\n    };\n    ({\n        #[cfg($cfg:meta)]\n        { $($output:tt)* }\n        $($( $rest:tt )+)?\n    }) => {\n        #[cfg($cfg)]\n        cfg_sel! {{#[cfg(else)] { $($output)* }}}\n        $(\n            #[cfg(not($cfg))]\n            cfg_sel! {{ $($rest)+ }}\n        )?\n    };\n    ({\n        #[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg($cfg1:meta))]\n        #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg($cfg2:meta))]\n        { $($output:tt)* }\n        $($( $rest:tt )+)?\n    }) => {\n        #[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg($cfg1))]\n        #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg($cfg2))]\n        cfg_sel! {{#[cfg(else)] { $($output)* }}}\n        $(\n            #[cfg_attr(portable_atomic_no_cfg_target_has_atomic, cfg(not($cfg1)))]\n            #[cfg_attr(not(portable_atomic_no_cfg_target_has_atomic), cfg(not($cfg2)))]\n            cfg_sel! {{ $($rest)+ }}\n        )?\n    };\n}\n\n// Equivalent to core::hint::cold_path, but compatible with pre-1.95 rustc.\n#[allow(dead_code)]\n#[inline(always)]\n#[cold]\nfn cold_path() {}\n// Stable equivalent of core::hint::{likely, unlikely}.\n#[allow(dead_code)]\n#[inline(always)]\npub(crate) fn likely(b: bool) -> bool {\n    if b {\n        true\n    } else {\n        cold_path();\n        false\n    }\n}\n#[allow(dead_code)]\n#[inline(always)]\npub(crate) fn unlikely(b: bool) -> bool {\n    if b {\n        cold_path();\n        true\n    } else {\n        false\n    }\n}\n\n// Equivalent to core::hint::assert_unchecked, but compatible with pre-1.81 rustc.\n#[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\n#[allow(dead_code)]\n#[inline(always)]\n#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\npub(crate) unsafe fn assert_unchecked(cond: bool) {\n    if !cond {\n        #[cfg(debug_assertions)]\n        unreachable!();\n        #[cfg(not(debug_assertions))]\n        // SAFETY: the caller promised `cond` is true.\n        unsafe {\n            core::hint::unreachable_unchecked()\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L3338\n#[inline]\n#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\npub(crate) fn assert_load_ordering(order: Ordering) {\n    match order {\n        Ordering::Acquire | Ordering::Relaxed | Ordering::SeqCst => {}\n        Ordering::Release => panic!(\"there is no such thing as a release load\"),\n        Ordering::AcqRel => panic!(\"there is no such thing as an acquire-release load\"),\n        _ => unreachable!(),\n    }\n}\n// https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L3323\n#[inline]\n#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\npub(crate) fn assert_store_ordering(order: Ordering) {\n    match order {\n        Ordering::Release | Ordering::Relaxed | Ordering::SeqCst => {}\n        Ordering::Acquire => panic!(\"there is no such thing as an acquire store\"),\n        Ordering::AcqRel => panic!(\"there is no such thing as an acquire-release store\"),\n        _ => unreachable!(),\n    }\n}\n// https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/sync/atomic.rs#L3404\n#[inline]\n#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\npub(crate) fn assert_compare_exchange_ordering(success: Ordering, failure: Ordering) {\n    match success {\n        Ordering::AcqRel\n        | Ordering::Acquire\n        | Ordering::Relaxed\n        | Ordering::Release\n        | Ordering::SeqCst => {}\n        _ => unreachable!(),\n    }\n    match failure {\n        Ordering::Acquire | Ordering::Relaxed | Ordering::SeqCst => {}\n        Ordering::Release => panic!(\"there is no such thing as a release failure ordering\"),\n        Ordering::AcqRel => panic!(\"there is no such thing as an acquire-release failure ordering\"),\n        _ => unreachable!(),\n    }\n}\n\n// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0418r2.html\n// https://github.com/rust-lang/rust/pull/98383\n#[allow(dead_code)]\n#[inline]\npub(crate) fn upgrade_success_ordering(success: Ordering, failure: Ordering) -> Ordering {\n    match (success, failure) {\n        (Ordering::Relaxed, Ordering::Acquire) => Ordering::Acquire,\n        (Ordering::Release, Ordering::Acquire) => Ordering::AcqRel,\n        (_, Ordering::SeqCst) => Ordering::SeqCst,\n        _ => success,\n    }\n}\n\n#[cfg(not(portable_atomic_no_asm_maybe_uninit))]\n#[cfg(target_pointer_width = \"32\")]\n// SAFETY: MaybeUninit returned by zero_extend64_ptr is always initialized.\nconst _: () = assert!(unsafe {\n    zero_extend64_ptr(ptr::without_provenance_mut(!0)).assume_init() == !0_u32 as u64\n});\n/// Zero-extends the given 32-bit pointer to `MaybeUninit<u64>`.\n/// This is used for 64-bit architecture's 32-bit ABI (e.g., AArch64 ILP32 ABI).\n/// See ptr_reg! macro in src/gen/utils.rs for details.\n#[cfg(not(portable_atomic_no_asm_maybe_uninit))]\n#[cfg(target_pointer_width = \"32\")]\n#[allow(dead_code)]\n#[inline]\npub(crate) const fn zero_extend64_ptr(v: *mut ()) -> core::mem::MaybeUninit<u64> {\n    #[repr(C)]\n    struct ZeroExtended {\n        #[cfg(target_endian = \"big\")]\n        pad: *mut (),\n        v: *mut (),\n        #[cfg(target_endian = \"little\")]\n        pad: *mut (),\n    }\n    // SAFETY: we can safely transmute any 64-bit value to MaybeUninit<u64>.\n    unsafe { core::mem::transmute(ZeroExtended { v, pad: core::ptr::null_mut() }) }\n}\n\n#[allow(dead_code)]\n#[cfg(any(\n    target_arch = \"aarch64\",\n    target_arch = \"arm64ec\",\n    target_arch = \"powerpc64\",\n    target_arch = \"riscv64\",\n    target_arch = \"s390x\",\n    target_arch = \"x86_64\",\n))]\n/// A 128-bit value represented as a pair of 64-bit values.\n///\n/// This type is `#[repr(C)]`, both fields have the same in-memory representation\n/// and are plain old data types, so access to the fields is always safe.\n#[derive(Clone, Copy)]\n#[repr(C)]\npub(crate) union U128 {\n    pub(crate) whole: u128,\n    pub(crate) pair: Pair<u64>,\n}\n#[allow(dead_code)]\n#[cfg(any(target_arch = \"arm\", target_arch = \"riscv32\"))]\n/// A 64-bit value represented as a pair of 32-bit values.\n///\n/// This type is `#[repr(C)]`, both fields have the same in-memory representation\n/// and are plain old data types, so access to the fields is always safe.\n#[derive(Clone, Copy)]\n#[repr(C)]\npub(crate) union U64 {\n    pub(crate) whole: u64,\n    pub(crate) pair: Pair<u32>,\n}\n#[allow(dead_code)]\n#[derive(Clone, Copy)]\n#[repr(C)]\npub(crate) struct Pair<T: Copy> {\n    // little endian order\n    #[cfg(any(\n        target_endian = \"little\",\n        target_arch = \"aarch64\",\n        target_arch = \"arm\",\n        target_arch = \"arm64ec\",\n    ))]\n    pub(crate) lo: T,\n    pub(crate) hi: T,\n    // big endian order\n    #[cfg(not(any(\n        target_endian = \"little\",\n        target_arch = \"aarch64\",\n        target_arch = \"arm\",\n        target_arch = \"arm64ec\",\n    )))]\n    pub(crate) lo: T,\n}\n\n#[cfg(any(target_arch = \"riscv32\", target_arch = \"riscv64\"))]\ntype MinWord = u32;\n#[cfg(any(target_arch = \"riscv32\", target_arch = \"riscv64\"))]\ntype RetInt = u32;\n// Adapted from https://github.com/taiki-e/atomic-maybe-uninit/blob/v0.3.6/src/utils.rs#L255.\n// Helper for implementing sub-word atomic operations using word-sized LL/SC loop or CAS loop.\n//\n// Refs: https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/CodeGen/AtomicExpandPass.cpp#L811\n// (aligned_ptr, shift, mask)\n#[cfg(any(target_arch = \"riscv32\", target_arch = \"riscv64\"))]\n#[allow(dead_code)]\n#[inline]\npub(crate) fn create_sub_word_mask_values<T>(ptr: *mut T) -> (*mut MinWord, RetInt, RetInt) {\n    use core::mem;\n\n    #[cfg(portable_atomic_no_strict_provenance)]\n    use self::ptr::PtrExt as _;\n\n    // RISC-V, MIPS, SPARC, LoongArch, Xtensa, BPF: shift amount of 32-bit shift instructions is 5 bits unsigned (0-31).\n    // PowerPC, C-SKY: shift amount of 32-bit shift instructions is 6 bits unsigned (0-63) and shift amount 32-63 means \"clear\".\n    // Arm: shift amount of 32-bit shift instructions is 8 bits unsigned (0-255).\n    // Hexagon: shift amount of 32-bit shift instructions is 7 bits signed (-64-63) and negative shift amount means \"reverse the direction of the shift\".\n    // (On s390x, we don't use the mask returned from this function.)\n    // (See also https://devblogs.microsoft.com/oldnewthing/20230904-00/?p=108704 for others)\n    const SHIFT_MASK: bool = !cfg!(any(\n        target_arch = \"bpf\",\n        target_arch = \"loongarch32\",\n        target_arch = \"loongarch64\",\n        target_arch = \"mips\",\n        target_arch = \"mips32r6\",\n        target_arch = \"mips64\",\n        target_arch = \"mips64r6\",\n        target_arch = \"riscv32\",\n        target_arch = \"riscv64\",\n        target_arch = \"s390x\",\n        target_arch = \"sparc\",\n        target_arch = \"sparc64\",\n        target_arch = \"xtensa\",\n    ));\n    let ptr_mask = mem::size_of::<MinWord>() - 1;\n    let aligned_ptr = ptr.with_addr(ptr.addr() & !ptr_mask) as *mut MinWord;\n    let ptr_lsb = if SHIFT_MASK {\n        ptr.addr() & ptr_mask\n    } else {\n        // We use 32-bit wrapping shift instructions in asm on these platforms.\n        ptr.addr()\n    };\n    let shift = if cfg!(any(target_endian = \"little\", target_arch = \"s390x\")) {\n        ptr_lsb.wrapping_mul(8)\n    } else {\n        (ptr_lsb ^ (mem::size_of::<MinWord>() - mem::size_of::<T>())).wrapping_mul(8)\n    };\n    let mut mask: RetInt = (1 << (mem::size_of::<T>() * 8)) - 1; // !(0 as T) as RetInt\n    if SHIFT_MASK {\n        mask <<= shift;\n    }\n    #[allow(clippy::cast_possible_truncation)]\n    {\n        (aligned_ptr, shift as RetInt, mask)\n    }\n}\n\n// This module provides core::ptr strict_provenance/exposed_provenance polyfill for pre-1.84 rustc.\n#[allow(dead_code)]\npub(crate) mod ptr {\n    cfg_sel!({\n        #[cfg(not(portable_atomic_no_strict_provenance))]\n        {\n            #[allow(unused_imports)]\n            pub(crate) use core::ptr::{\n                with_exposed_provenance, with_exposed_provenance_mut, without_provenance_mut,\n            };\n        }\n        #[cfg(else)]\n        {\n            #[inline(always)]\n            #[must_use]\n            pub(crate) const fn without_provenance_mut<T>(addr: usize) -> *mut T {\n                // An int-to-pointer transmute currently has exactly the intended semantics: it creates a\n                // pointer without provenance. Note that this is *not* a stable guarantee about transmute\n                // semantics, it relies on sysroot crates having special status.\n                // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that\n                // pointer).\n                #[cfg(miri)]\n                unsafe {\n                    core::mem::transmute(addr)\n                }\n                // const transmute requires Rust 1.56.\n                // Using transmute doesn't work with CHERI: https://github.com/kent-weak-memory/rust/blob/0c0ca909de877f889629057e1ddf139527446d75/library/core/src/ptr/mod.rs#L607\n                #[cfg(not(miri))]\n                {\n                    addr as *mut T\n                }\n            }\n            #[inline(always)]\n            #[must_use]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn with_exposed_provenance<T>(addr: usize) -> *const T {\n                addr as *const T\n            }\n            #[inline(always)]\n            #[must_use]\n            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n            pub(crate) fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T {\n                addr as *mut T\n            }\n\n            pub(crate) trait PtrExt<T: ?Sized>: Copy {\n                #[must_use]\n                fn addr(self) -> usize;\n                #[must_use]\n                fn with_addr(self, addr: usize) -> Self\n                where\n                    T: Sized;\n            }\n            impl<T: ?Sized> PtrExt<T> for *mut T {\n                #[inline(always)]\n                #[must_use]\n                fn addr(self) -> usize {\n                    // A pointer-to-integer transmute currently has exactly the right semantics: it returns the\n                    // address without exposing the provenance. Note that this is *not* a stable guarantee about\n                    // transmute semantics, it relies on sysroot crates having special status.\n                    // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the\n                    // provenance).\n                    #[cfg(miri)]\n                    unsafe {\n                        core::mem::transmute(self as *mut ())\n                    }\n                    // Using transmute doesn't work with CHERI: https://github.com/kent-weak-memory/rust/blob/0c0ca909de877f889629057e1ddf139527446d75/library/core/src/ptr/mut_ptr.rs#L210\n                    #[cfg(not(miri))]\n                    {\n                        self as *mut () as usize\n                    }\n                }\n                #[inline]\n                #[must_use]\n                fn with_addr(self, addr: usize) -> Self\n                where\n                    T: Sized,\n                {\n                    // This should probably be an intrinsic to avoid doing any sort of arithmetic, but\n                    // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's\n                    // provenance.\n                    let self_addr = self.addr() as isize;\n                    let dest_addr = addr as isize;\n                    let offset = dest_addr.wrapping_sub(self_addr);\n                    (self as *mut u8).wrapping_offset(offset) as *mut T\n                }\n            }\n        }\n    });\n}\n\n// This module provides:\n// - core::ffi polyfill (c_* type aliases and CStr) for pre-1.64 rustc compatibility.\n//   (core::ffi::* (except c_void) requires Rust 1.64)\n// - Safe abstraction (c! macro) for creating static C strings without runtime checks.\n//   (c\"...\" requires Rust 1.77)\n// - Helper macros for defining FFI bindings with static signature/type/value assertions.\n// - Helper macros for defining asm-based syscalls on Linux.\n#[cfg(any(\n    test,\n    portable_atomic_test_no_std_static_assert_ffi,\n    not(any(target_arch = \"x86\", target_arch = \"x86_64\"))\n))]\n#[cfg(any(not(portable_atomic_no_asm), portable_atomic_unstable_asm))]\n#[allow(dead_code, non_camel_case_types, unused_macros)]\n#[macro_use]\npub(crate) mod ffi {\n    // -------------------------------------------------------------------------\n    // core::ffi polyfill and c\"...\" equivalent\n\n    pub(crate) type c_void = core::ffi::c_void;\n    // c_{,u}int is {i,u}16 on 16-bit targets, otherwise {i,u}32.\n    // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/ffi/mod.rs#L156\n    cfg_sel!({\n        #[cfg(target_pointer_width = \"16\")]\n        {\n            pub(crate) type c_int = i16;\n            pub(crate) type c_uint = u16;\n        }\n        #[cfg(else)]\n        {\n            pub(crate) type c_int = i32;\n            pub(crate) type c_uint = u32;\n        }\n    });\n    // c_{,u}long is {i,u}64 on non-Windows 64-bit targets, otherwise {i,u}32.\n    // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/ffi/mod.rs#L168\n    cfg_sel!({\n        #[cfg(all(target_pointer_width = \"64\", not(windows)))]\n        {\n            pub(crate) type c_long = i64;\n            pub(crate) type c_ulong = u64;\n        }\n        #[cfg(else)]\n        {\n            pub(crate) type c_long = i32;\n            pub(crate) type c_ulong = u32;\n        }\n    });\n    // c_size_t is currently always usize.\n    // https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/ffi/mod.rs#L76\n    pub(crate) type c_size_t = usize;\n    // c_char is u8 by default on non-Apple/non-Windows/non-Vita Arm/C-SKY/Hexagon/MSP430/PowerPC/RISC-V/s390x/Xtensa targets, otherwise i8 by default.\n    // See references in https://github.com/rust-lang/rust/issues/129945 for details.\n    cfg_sel!({\n        #[cfg(all(\n            not(any(target_vendor = \"apple\", windows, target_os = \"vita\")),\n            any(\n                target_arch = \"aarch64\",\n                target_arch = \"arm\",\n                target_arch = \"csky\",\n                target_arch = \"hexagon\",\n                target_arch = \"msp430\",\n                target_arch = \"powerpc\",\n                target_arch = \"powerpc64\",\n                target_arch = \"riscv32\",\n                target_arch = \"riscv64\",\n                target_arch = \"s390x\",\n                target_arch = \"xtensa\",\n            ),\n        ))]\n        {\n            pub(crate) type c_char = u8;\n        }\n        #[cfg(else)]\n        {\n            pub(crate) type c_char = i8;\n        }\n    });\n\n    // Static assertions for C type definitions.\n    #[cfg(test)]\n    const _: fn() = || {\n        let _: c_int = 0 as std::os::raw::c_int;\n        let _: c_uint = 0 as std::os::raw::c_uint;\n        let _: c_long = 0 as std::os::raw::c_long;\n        let _: c_ulong = 0 as std::os::raw::c_ulong;\n        #[cfg(unix)]\n        let _: c_size_t = 0 as libc::size_t; // std::os::raw::c_size_t is unstable\n        let _: c_char = 0 as std::os::raw::c_char;\n    };\n\n    #[repr(transparent)]\n    pub(crate) struct CStr([c_char]);\n    impl CStr {\n        #[inline]\n        #[must_use]\n        pub(crate) const fn as_ptr(&self) -> *const c_char {\n            self.0.as_ptr()\n        }\n        /// # Safety\n        ///\n        /// The provided slice **must** be nul-terminated and not contain any interior\n        /// nul bytes.\n        #[inline]\n        #[must_use]\n        pub(crate) unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {\n            // SAFETY: Casting to CStr is safe because *our* CStr is #[repr(transparent)]\n            // and its internal representation is a [u8] too. (Note that std's CStr\n            // is not #[repr(transparent)].)\n            // Dereferencing the obtained pointer is safe because it comes from a\n            // reference. Making a reference is then safe because its lifetime\n            // is bound by the lifetime of the given `bytes`.\n            unsafe { &*(bytes as *const [u8] as *const CStr) }\n        }\n        #[cfg(test)]\n        #[inline]\n        #[must_use]\n        pub(crate) fn to_bytes_with_nul(&self) -> &[u8] {\n            #[allow(clippy::unnecessary_cast)] // triggered for targets that c_char is u8\n            // SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s\n            // is safe on all supported targets.\n            unsafe {\n                &*(&self.0 as *const [c_char] as *const [u8])\n            }\n        }\n    }\n\n    macro_rules! c {\n        ($s:expr) => {{\n            const BYTES: &[u8] = concat!($s, \"\\0\").as_bytes();\n            const _: () = static_assert!(crate::utils::ffi::_const_is_c_str(BYTES));\n            #[allow(unused_unsafe)]\n            // SAFETY: we've checked `BYTES` is a valid C string\n            unsafe {\n                crate::utils::ffi::CStr::from_bytes_with_nul_unchecked(BYTES)\n            }\n        }};\n    }\n\n    #[must_use]\n    pub(crate) const fn _const_is_c_str(bytes: &[u8]) -> bool {\n        #[cfg(portable_atomic_no_track_caller)]\n        {\n            // const_if_match/const_loop was stabilized (nightly-2020-06-30) 2 days before\n            // track_caller was stabilized (nightly-2020-07-02), so we reuse the cfg for\n            // track_caller here instead of emitting a cfg for const_if_match/const_loop.\n            // https://github.com/rust-lang/rust/pull/72437\n            // track_caller was stabilized 11 days after the oldest nightly version\n            // that uses this module, and is included in the same 1.46 stable release.\n            // The check here is insufficient in this case, but this is fine because this function\n            // is internal code that is not used to process input from the user and our CI checks\n            // all builtin targets and some custom targets with some versions of newer compilers.\n            !bytes.is_empty()\n        }\n        #[cfg(not(portable_atomic_no_track_caller))]\n        {\n            // Based on https://github.com/rust-lang/rust/blob/1.84.0/library/core/src/ffi/c_str.rs#L417\n            // - bytes must be nul-terminated.\n            // - bytes must not contain any interior nul bytes.\n            if bytes.is_empty() {\n                return false;\n            }\n            let mut i = bytes.len() - 1;\n            if bytes[i] != 0 {\n                return false;\n            }\n            // Ending null byte exists, skip to the rest.\n            while i != 0 {\n                i -= 1;\n                if bytes[i] == 0 {\n                    return false;\n                }\n            }\n            true\n        }\n    }\n\n    // -------------------------------------------------------------------------\n    // Helper macros for defining FFI bindings with static signature/type/value assertions.\n\n    /// Defines types with #[cfg(test)] static assertions which checks\n    /// types are the same as the platform's latest header files' ones.\n    // Note: This macro is sys_ty!({ }), not sys_ty! { }.\n    // An extra brace is used in input to make contents rustfmt-able.\n    macro_rules! sys_type {\n        ({$(\n            $(#[$attr:meta])*\n            $vis:vis type $([$($windows_path:ident)::+])? $name:ident = $ty:ty;\n        )*}) => {\n            $(\n                $(#[$attr])*\n                $vis type $name = $ty;\n            )*\n            #[cfg(any(test, portable_atomic_test_no_std_static_assert_ffi))]\n            test_helper::static_assert_sys_type!($(\n                $(#[$attr])*\n                type $([$($windows_path)::+])? $name;\n            )*);\n        };\n    }\n    /// Defines #[repr(C)] structs with #[cfg(test)] static assertions which checks\n    /// fields are the same as the platform's latest header files' ones.\n    // Note: This macro is sys_struct!({ }), not sys_struct! { }.\n    // An extra brace is used in input to make contents rustfmt-able.\n    macro_rules! sys_struct {\n        ({$(\n            $(#[$attr:meta])*\n            $vis:vis struct $([$($windows_path:ident)::+])? $name:ident {$(\n                $(#[$field_attr:meta])*\n                $field_vis:vis $field_name:ident: $field_ty:ty,\n            )*}\n        )*}) => {\n            $(\n                $(#[$attr])*\n                #[derive(Clone, Copy)]\n                #[cfg_attr(\n                    any(test, portable_atomic_test_no_std_static_assert_ffi),\n                    derive(Debug, PartialEq)\n                )]\n                #[repr(C)]\n                $vis struct $name {$(\n                    $(#[$field_attr])*\n                    $field_vis $field_name: $field_ty,\n                )*}\n            )*\n            #[cfg(any(test, portable_atomic_test_no_std_static_assert_ffi))]\n            test_helper::static_assert_sys_struct!($(\n                $(#[$attr])*\n                struct $([$($windows_path)::+])? $name {$(\n                    $(#[$field_attr])*\n                    $field_name: $field_ty,\n                )*}\n            )*);\n        };\n    }\n    /// Defines constants with #[cfg(test)] static assertions which checks\n    /// values are the same as the platform's latest header files' ones.\n    // Note: This macro is sys_const!({ }), not sys_const! { }.\n    // An extra brace is used in input to make contents rustfmt-able.\n    macro_rules! sys_const {\n        ({$(\n            $(#[$attr:meta])*\n            $vis:vis const $([$($windows_path:ident)::+])? $name:ident: $ty:ty = $val:expr;\n        )*}) => {\n            $(\n                $(#[$attr])*\n                $vis const $name: $ty = $val;\n            )*\n            #[cfg(any(test, portable_atomic_test_no_std_static_assert_ffi))]\n            test_helper::static_assert_sys_const!($(\n                $(#[$attr])*\n                const $([$($windows_path)::+])? $name: $ty;\n            )*);\n        };\n    }\n    /// Defines functions with #[cfg(test)] static assertions which checks\n    /// signatures are the same as the platform's latest header files' ones.\n    // Note: This macro is sys_fn!({ }), not sys_fn! { }.\n    // An extra brace is used in input to make contents rustfmt-able.\n    macro_rules! sys_fn {\n        ({\n            $(#[$extern_attr:meta])*\n            extern $abi:tt {$(\n                $(#[$fn_attr:meta])*\n                $vis:vis fn $([$($windows_path:ident)::+])? $name:ident(\n                    $($args:tt)*\n                ) $(-> $ret_ty:ty)?;\n            )*}\n        }) => {\n            $(#[$extern_attr])*\n            extern $abi {$(\n                $(#[$fn_attr])*\n                $vis fn $name($($args)*) $(-> $ret_ty)?;\n            )*}\n            #[cfg(any(test, portable_atomic_test_no_std_static_assert_ffi))]\n            test_helper::static_assert_sys_fn!(\n                $(#[$extern_attr])*\n                extern $abi {$(\n                    $(#[$fn_attr])*\n                    fn $([$($windows_path)::+])? $name($($args)*) $(-> $ret_ty)?;\n                )*}\n            );\n        };\n    }\n\n    // -----------------------------------------------------------------------------\n    // Helper macros for defining asm-based syscalls on Linux.\n    //\n    // Use asm-based syscall on Linux for compatibility with non-libc targets if possible.\n    //\n    // In non-Linux environments (including Android), syscalls should be called via libc,\n    // mainly for the following reasons.\n    // - asm-based syscalls are not permitted in the first place. e.g.,\n    //   - OpenBSD https://github.com/golang/go/issues/36435\n    //   - CheriBSD https://www.cheribsd.org/release-notes/25.03/index.html\n    // - Stability of asm-based syscalls is not guaranteed. e.g.,\n    //   - macOS https://go-review.googlesource.com/c/go/+/25495\n    // - Syscalls via libc (or also libsys on FreeBSD) provide additional protections. e.g.,\n    //   - OpenBSD https://lwn.net/Articles/806863/\n    //   - CheriBSD https://www.cheribsd.org/release-notes/25.03/index.html\n    //   - FreeBSD https://www.freebsd.org/status/report-2024-01-2024-03/libsys/\n    //   - Android https://android.googlesource.com/platform/bionic/+/HEAD/docs/fdtrack.md\n    //\n    // Miri and Sanitizer do not support inline assembly.\n    #[cfg(all(\n        target_os = \"linux\",\n        not(any(miri, portable_atomic_sanitize_thread)),\n        not(portable_atomic_no_asm_syscall),\n    ))]\n    #[macro_use]\n    mod syscall_helper {\n        // Note:\n        // - The syscall number and arguments must be extended to the register size by the caller of macros.\n        //   The kernel extends the low bits on some architectures, but it does not on many architectures. e.g.,\n        //   x86_64 (pre-5.14): https://github.com/torvalds/linux/commit/0595494891723a1dcca5eaa8eeca8ab54ad953b9\n        //   powerpc64: https://github.com/torvalds/linux/blob/v7.1/arch/powerpc/kernel/syscall.c#L16\n        //   riscv64: https://github.com/torvalds/linux/blob/v7.1/arch/riscv/kernel/traps.c#L328\n        //   loongarch64: https://github.com/torvalds/linux/blob/v7.1/arch/loongarch/kernel/syscall.c#L61\n        //\n        // Refs:\n        // - https://man7.org/linux/man-pages/man2/syscall.2.html\n        // - aarch64 (test-only)\n        //   https://git.musl-libc.org/cgit/musl/tree/arch/aarch64/syscall_arch.h?h=v1.2.6\n        // - arm (test-only)\n        //   https://git.musl-libc.org/cgit/musl/tree/arch/arm/syscall_arch.h?h=v1.2.6\n        // - powerpc64 (test-only)\n        //   https://github.com/torvalds/linux/blob/v7.1/Documentation/arch/powerpc/syscall64-abi.rst\n        //   https://git.musl-libc.org/cgit/musl/tree/arch/powerpc64/syscall_arch.h?h=v1.2.6\n        // - riscv32/riscv64\n        //   https://git.musl-libc.org/cgit/musl/tree/arch/riscv32/syscall_arch.h?h=v1.2.6\n        //   https://git.musl-libc.org/cgit/musl/tree/arch/riscv64/syscall_arch.h?h=v1.2.6\n\n        #[cfg(test)] // test-only\n        #[cfg(all(target_arch = \"aarch64\", target_pointer_width = \"64\"))]\n        macro_rules! asm_syscall {\n            (\n                $number:ident, $r:ident,\n                $($arg1:ident $(, $arg2:ident $(, $arg3:ident\n                    $(, $arg4:ident $(, $arg5:ident $(, $arg6:ident )?)?)?\n                )?)?)?\n            ) => {\n                __asm!(\n                    \"svc 0\",\n                    in(\"x8\") $number,\n                    lateout(\"x0\") $r,\n                    $(in(\"x0\") $arg1,\n                        $(in(\"x1\") $arg2,\n                            $(in(\"x2\") $arg3,\n                                $(in(\"x3\") $arg4,\n                                    $(in(\"x4\") $arg5,\n                                        $(in(\"x5\") $arg6, )?\n                                    )?\n                                )?\n                            )?\n                        )?\n                    )?\n                    // Clobber SVE registers and do not use `preserves_flags` because\n                    // AArch64 Linux syscalls clears non-v[0-31] bits of z[0-31], and all of p[0-15] and ffr,\n                    // and calls SMSTOP SM which clears z[0-31], p[0-15], ffr, and modifies FPSR\n                    // when CPU is in streaming SVE mode.\n                    // https://github.com/torvalds/linux/blob/v7.1/Documentation/arch/arm64/sve.rst#3--system-call-behaviour\n                    // https://github.com/torvalds/linux/blob/v7.1/Documentation/arch/arm64/sme.rst#3--system-call-behaviour\n                    // https://developer.arm.com/documentation/109246/0101/SME-Overview/Streaming-SVE-mode\n                    out(\"z0\") _,\n                    out(\"z1\") _,\n                    out(\"z2\") _,\n                    out(\"z3\") _,\n                    out(\"z4\") _,\n                    out(\"z5\") _,\n                    out(\"z6\") _,\n                    out(\"z7\") _,\n                    out(\"z8\") _,\n                    out(\"z9\") _,\n                    out(\"z10\") _,\n                    out(\"z11\") _,\n                    out(\"z12\") _,\n                    out(\"z13\") _,\n                    out(\"z14\") _,\n                    out(\"z15\") _,\n                    out(\"z16\") _,\n                    out(\"z17\") _,\n                    out(\"z18\") _,\n                    out(\"z19\") _,\n                    out(\"z20\") _,\n                    out(\"z21\") _,\n                    out(\"z22\") _,\n                    out(\"z23\") _,\n                    out(\"z24\") _,\n                    out(\"z25\") _,\n                    out(\"z26\") _,\n                    out(\"z27\") _,\n                    out(\"z28\") _,\n                    out(\"z29\") _,\n                    out(\"z30\") _,\n                    out(\"z31\") _,\n                    out(\"p0\") _,\n                    out(\"p1\") _,\n                    out(\"p2\") _,\n                    out(\"p3\") _,\n                    out(\"p4\") _,\n                    out(\"p5\") _,\n                    out(\"p6\") _,\n                    out(\"p7\") _,\n                    out(\"p8\") _,\n                    out(\"p9\") _,\n                    out(\"p10\") _,\n                    out(\"p11\") _,\n                    out(\"p12\") _,\n                    out(\"p13\") _,\n                    out(\"p14\") _,\n                    out(\"p15\") _,\n                    out(\"ffr\") _,\n                    options(nostack),\n                )\n            };\n        }\n        #[cfg(test)] // test-only\n        #[cfg(target_arch = \"arm\")]\n        macro_rules! asm_syscall {\n            (\n                $number_const:path, $number:literal, $r:ident,\n                $($arg1:ident $(, $arg2:ident $(, $arg3:ident\n                    $(, $arg4:ident $(, $arg5:ident $(, $arg6:ident )?)?)?\n                )?)?)?\n            ) => {{\n                static_assert!($number_const == $number && 0 <= $number && $number <= 255);\n                __asm!(\n                    // r7 is reserved on thumb and MOV requires Thumb-2 or Arm mode.\n                    // cfg(target_feature = \"thumb-mode\")/cfg(target_feature = \"thumb2\")\n                    // doesn't work on stable and register swapping is much cheaper than syscall,\n                    // so we always swap register and use MOVS instead of MOV.\n                    // Note: r6 is reserved by LLVM, so this assembly may not work for syscall6\n                    //       with Thumb-1 (pre-v7 Arm in Thumb mode) because the allocation of\n                    //       `tmp` may fail.\n                    //       (syscall6 is needless in the current our use cases.)\n                    \"movs {tmp}, r7\",\n                    concat!(\"movs r7, \", $number),\n                    \"svc 0\",\n                    \"movs r7, {tmp}\",\n                    tmp = out(reg) _,\n                    lateout(\"r0\") $r,\n                    $(in(\"r0\") $arg1,\n                        $(in(\"r1\") $arg2,\n                            $(in(\"r2\") $arg3,\n                                $(in(\"r3\") $arg4,\n                                    $(in(\"r4\") $arg5,\n                                        $(in(\"r5\") $arg6, )?\n                                    )?\n                                )?\n                            )?\n                        )?\n                    )?\n                    // Do not use `preserves_flags` because MOVS modifies the flags.\n                    // Do not use `nostack` because SVC pushes to stack on M-profile architectures.\n                    // https://github.com/torvalds/linux/blob/v7.1/arch/arm/kernel/entry-header.S#L61\n                )\n            }};\n        }\n        // POWER9+ has fast syscall using SCV, but it is needless in the current our use cases.\n        #[cfg(test)] // test-only\n        #[cfg(all(target_arch = \"powerpc64\", target_pointer_width = \"64\"))]\n        macro_rules! asm_syscall {\n            (\n                $number:ident, $r:ident,\n                $($arg1:ident $(, $arg2:ident $(, $arg3:ident\n                    $(, $arg4:ident $(, $arg5:ident $(, $arg6:ident )?)?)?\n                )?)?)?\n            ) => {\n                __asm!(\n                    \"sc\",\n                    \"bns+ 2f\",\n                    \"neg %r3, %r3\",\n                    \"2:\",\n                    inout(\"r0\") $number => _,\n                    lateout(\"r3\") $r,\n                    $(in(\"r3\") $arg1,\n                        $(in(\"r4\") $arg2,\n                            $(in(\"r5\") $arg3,\n                                $(in(\"r6\") $arg4,\n                                    $(in(\"r7\") $arg5,\n                                        $(in(\"r8\") $arg6, )?\n                                    )?\n                                )?\n                            )?\n                        )?\n                    )?\n                    lateout(\"r4\") _,\n                    lateout(\"r5\") _,\n                    lateout(\"r6\") _,\n                    lateout(\"r7\") _,\n                    lateout(\"r8\") _,\n                    out(\"r9\") _,\n                    out(\"r10\") _,\n                    out(\"r11\") _,\n                    out(\"r12\") _,\n                    out(\"cr0\") _,\n                    out(\"ctr\") _,\n                    out(\"xer\") _,\n                    options(nostack, preserves_flags),\n                )\n            };\n        }\n        #[cfg(any(\n            target_arch = \"riscv32\",\n            all(target_arch = \"riscv64\", target_pointer_width = \"64\"),\n        ))]\n        macro_rules! asm_syscall {\n            (\n                $number:ident, $r:ident,\n                $($arg1:ident $(, $arg2:ident $(, $arg3:ident\n                    $(, $arg4:ident $(, $arg5:ident $(, $arg6:ident )?)?)?\n                )?)?)?\n            ) => {\n                __asm!(\n                    \"ecall\",\n                    in(\"a7\") $number,\n                    lateout(\"a0\") $r,\n                    $(in(\"a0\") $arg1,\n                        $(in(\"a1\") $arg2,\n                            $(in(\"a2\") $arg3,\n                                $(in(\"a3\") $arg4,\n                                    $(in(\"a4\") $arg5,\n                                        $(in(\"a5\") $arg6, )?\n                                    )?\n                                )?\n                            )?\n                        )?\n                    )?\n                    // Clobber vector registers and do not use `preserves_flags` because RISC-V Linux syscalls don't preserve them.\n                    // https://github.com/torvalds/linux/blob/v7.1/Documentation/arch/riscv/vector.rst#3--vector-register-state-across-system-calls\n                    out(\"v0\") _,\n                    out(\"v1\") _,\n                    out(\"v2\") _,\n                    out(\"v3\") _,\n                    out(\"v4\") _,\n                    out(\"v5\") _,\n                    out(\"v6\") _,\n                    out(\"v7\") _,\n                    out(\"v8\") _,\n                    out(\"v9\") _,\n                    out(\"v10\") _,\n                    out(\"v11\") _,\n                    out(\"v12\") _,\n                    out(\"v13\") _,\n                    out(\"v14\") _,\n                    out(\"v15\") _,\n                    out(\"v16\") _,\n                    out(\"v17\") _,\n                    out(\"v18\") _,\n                    out(\"v19\") _,\n                    out(\"v20\") _,\n                    out(\"v21\") _,\n                    out(\"v22\") _,\n                    out(\"v23\") _,\n                    out(\"v24\") _,\n                    out(\"v25\") _,\n                    out(\"v26\") _,\n                    out(\"v27\") _,\n                    out(\"v28\") _,\n                    out(\"v29\") _,\n                    out(\"v30\") _,\n                    out(\"v31\") _,\n                    options(nostack),\n                )\n            };\n        }\n    }\n\n    #[allow(\n        clippy::alloc_instead_of_core,\n        clippy::std_instead_of_alloc,\n        clippy::std_instead_of_core,\n        clippy::undocumented_unsafe_blocks,\n        clippy::wildcard_imports\n    )]\n    #[cfg(test)]\n    mod tests {\n        #[test]\n        fn test_c_macro() {\n            #[track_caller]\n            fn t(s: &crate::utils::ffi::CStr, raw: &[u8]) {\n                assert_eq!(s.to_bytes_with_nul(), raw);\n            }\n            t(c!(\"\"), b\"\\0\");\n            t(c!(\"a\"), b\"a\\0\");\n            t(c!(\"abc\"), b\"abc\\0\");\n            t(c!(concat!(\"abc\", \"d\")), b\"abcd\\0\");\n        }\n\n        #[test]\n        fn test_is_c_str() {\n            #[track_caller]\n            fn t(bytes: &[u8]) {\n                assert_eq!(\n                    super::_const_is_c_str(bytes),\n                    std::ffi::CStr::from_bytes_with_nul(bytes).is_ok()\n                );\n            }\n            t(b\"\\0\");\n            t(b\"a\\0\");\n            t(b\"abc\\0\");\n            t(b\"\");\n            t(b\"a\");\n            t(b\"abc\");\n            t(b\"\\0a\");\n            t(b\"\\0a\\0\");\n            t(b\"ab\\0c\\0\");\n            t(b\"\\0\\0\");\n        }\n    }\n}\n"
    },
    {
      "package": "portable-atomic@1.15.0",
      "sourcePath": "version.rs",
      "sha256": "25c4e742d5a9e49ee16793b607157e181fd79eeafcbcbf0aa389f31b8d5514d1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::{env, iter, process::Command, str};\n\npub(crate) fn rustc_version() -> Option<Version> {\n    let rustc = env::var_os(\"RUSTC\")?;\n    let rustc_wrapper = if env::var_os(\"CARGO_ENCODED_RUSTFLAGS\").is_some() {\n        env::var_os(\"RUSTC_WRAPPER\").filter(|v| !v.is_empty())\n    } else {\n        // Cargo sets environment variables for wrappers correctly only since https://github.com/rust-lang/cargo/pull/9601.\n        None\n    };\n    // Do not apply RUSTC_WORKSPACE_WRAPPER: https://github.com/cuviper/autocfg/issues/58#issuecomment-2067625980\n    let mut rustc = rustc_wrapper.into_iter().chain(iter::once(rustc));\n    let mut cmd = Command::new(rustc.next().unwrap());\n    cmd.args(rustc);\n    // Use verbose version output because the packagers add extra strings to the normal version output.\n    // Do not use long flags (--version --verbose) because clippy-deriver doesn't handle them properly.\n    // -vV is also matched with that cargo internally uses: https://github.com/rust-lang/cargo/blob/0.80.0/src/cargo/util/rustc.rs#L65\n    let output = cmd.arg(\"-vV\").output().ok()?;\n    let verbose_version = str::from_utf8(&output.stdout).ok()?;\n    Version::parse(verbose_version)\n}\n\n#[cfg_attr(test, derive(Debug, PartialEq))]\npub(crate) struct Version {\n    pub(crate) minor: u32,\n    pub(crate) nightly: bool,\n    commit_date: Date,\n    pub(crate) llvm: u32,\n}\n\nimpl Version {\n    // The known latest stable version. If we unable to determine\n    // the rustc version, we assume this is the current version.\n    // It is no problem if this is older than the actual latest stable.\n    // LLVM version is assumed to be the minimum external LLVM version:\n    // https://github.com/rust-lang/rust/blob/1.97.0/src/bootstrap/src/core/build_steps/llvm.rs#L638\n    pub(crate) const LATEST: Self = Self::stable(97, 21);\n\n    pub(crate) const fn stable(rustc_minor: u32, llvm_major: u32) -> Self {\n        Self { minor: rustc_minor, nightly: false, commit_date: Date::UNKNOWN, llvm: llvm_major }\n    }\n\n    pub(crate) fn probe(&self, minor: u32, year: u16, month: u8, day: u8) -> bool {\n        if self.nightly {\n            self.minor > minor\n                || self.minor == minor && self.commit_date >= Date::new(year, month, day)\n        } else {\n            self.minor >= minor\n        }\n    }\n\n    #[cfg(test)]\n    pub(crate) fn commit_date(&self) -> &Date {\n        &self.commit_date\n    }\n\n    pub(crate) fn parse(verbose_version: &str) -> Option<Self> {\n        let mut release = verbose_version\n            .lines()\n            .find(|line| line.starts_with(\"release: \"))\n            .map(|line| &line[\"release: \".len()..])?\n            .splitn(2, '-');\n        let version = release.next().unwrap();\n        let channel = release.next().unwrap_or_default();\n        let mut digits = version.splitn(3, '.');\n        let major = digits.next()?;\n        if major != \"1\" {\n            return None;\n        }\n        let minor = digits.next()?.parse::<u32>().ok()?;\n        let _patch = digits.next().unwrap_or(\"0\").parse::<u32>().ok()?;\n        let nightly = match env::var_os(\"RUSTC_BOOTSTRAP\") {\n            // When -1 is passed rustc works like stable, e.g., cfg(target_feature = \"unstable_target_feature\") will never be set. https://github.com/rust-lang/rust/pull/132993\n            Some(ref v) if v == \"-1\" => false,\n            // When 1 is passed stable rustc works like nightly, but we ignore it for now.\n            _ => channel == \"nightly\" || channel == \"dev\",\n        };\n\n        // Note that rustc 1.49-1.50 (and 1.13 or older) don't print LLVM version.\n        let llvm_major = (|| {\n            let version = verbose_version\n                .lines()\n                .find(|line| line.starts_with(\"LLVM version: \"))\n                .map(|line| &line[\"LLVM version: \".len()..])?;\n            let mut digits = version.splitn(3, '.');\n            let major = digits.next()?.parse::<u32>().ok()?;\n            let _minor = digits.next()?.parse::<u32>().ok()?;\n            let _patch = digits.next().unwrap_or(\"0\").parse::<u32>().ok()?;\n            Some(major)\n        })()\n        .unwrap_or(0);\n\n        // we don't refer commit date on stable/beta.\n        if nightly {\n            let commit_date = (|| {\n                let mut commit_date = verbose_version\n                    .lines()\n                    .find(|line| line.starts_with(\"commit-date: \"))\n                    .map(|line| &line[\"commit-date: \".len()..])?\n                    .splitn(3, '-');\n                let year = commit_date.next()?.parse::<u16>().ok()?;\n                let month = commit_date.next()?.parse::<u8>().ok()?;\n                let day = commit_date.next()?.parse::<u8>().ok()?;\n                if month > 12 || day > 31 {\n                    return None;\n                }\n                Some(Date::new(year, month, day))\n            })();\n            Some(Self {\n                minor,\n                nightly,\n                commit_date: commit_date.unwrap_or(Date::UNKNOWN),\n                llvm: llvm_major,\n            })\n        } else {\n            Some(Self::stable(minor, llvm_major))\n        }\n    }\n}\n\n#[derive(PartialEq, PartialOrd)]\n#[cfg_attr(test, derive(Debug))]\npub(crate) struct Date {\n    pub(crate) year: u16,\n    pub(crate) month: u8,\n    pub(crate) day: u8,\n}\n\nimpl Date {\n    const UNKNOWN: Self = Self::new(0, 0, 0);\n\n    const fn new(year: u16, month: u8, day: u8) -> Self {\n        Self { year, month, day }\n    }\n}\n"
    },
    {
      "package": "portable-atomic-util@0.2.8",
      "sourcePath": "README.md",
      "sha256": "340557050bd651407ee059bc56c3296461d3be4fb9caf22b22784bd11931959b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# portable-atomic-util\n\n[![crates.io](https://img.shields.io/crates/v/portable-atomic-util?style=flat-square&logo=rust)](https://crates.io/crates/portable-atomic-util)\n[![docs.rs](https://img.shields.io/badge/docs.rs-portable--atomic--util-blue?style=flat-square&logo=docs.rs)](https://docs.rs/portable-atomic-util)\n[![license](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue?style=flat-square)](#license)\n[![msrv](https://img.shields.io/badge/msrv-1.36-blue?style=flat-square&logo=rust)](https://www.rust-lang.org)\n[![github actions](https://img.shields.io/github/actions/workflow/status/taiki-e/portable-atomic-util/ci.yml?branch=main&style=flat-square&logo=github)](https://github.com/taiki-e/portable-atomic-util/actions)\n\n<!-- tidy:sync-markdown-to-rustdoc:start:src/lib.rs -->\n\nSynchronization primitives built with [portable-atomic].\n\n- Provide `Arc`. (optional, requires the `std` or `alloc` feature)\n- Provide `task::Wake`. (optional, requires the `std` or `alloc` feature)\n<!-- - Provide generic `Atomic<T>` type. (optional, requires the `generic` feature) -->\n\nSee [portable-atomic#1] for other primitives being considered for addition to this crate.\n\nThis crate was originally [part of the portable-atomic repository](https://github.com/taiki-e/portable-atomic/tree/cbbee0c0d202a5944f7d66aaafaac6ed76e6f599/portable-atomic-util) and was extracted into its own repository.\n\n## Optional features\n\n- **`std`**<br>\n  Use `std`.\n\n  Note:\n  - This implicitly enables the `alloc` feature.\n\n- **`alloc`**<br>\n  Use `alloc`.\n\n- **`serde`**<br>\n  Implement `serde::{Serialize, Deserialize}` for `Arc`.\n\n  Note:\n  - The MSRV when this feature is enabled is the one coming from serde, as of now it's Rust 1.56\n\n<!-- TODO: https://github.com/taiki-e/portable-atomic/issues/1\n- **`generic`**<br>\n  Provides generic `Atomic<T>` type.\n-->\n\n[portable-atomic]: https://github.com/taiki-e/portable-atomic\n[portable-atomic#1]: https://github.com/taiki-e/portable-atomic/issues/1\n\n## Optional cfg\n\nOne of the ways to enable cfg is to set [rustflags in the cargo config](https://doc.rust-lang.org/cargo/reference/config.html#targettriplerustflags):\n\n```toml\n# .cargo/config.toml\n[target.<target>]\nrustflags = [\"--cfg\", \"portable_atomic_unstable_coerce_unsized\"]\n```\n\nOr set environment variable:\n\n```sh\nRUSTFLAGS=\"--cfg portable_atomic_unstable_coerce_unsized\" cargo ...\n```\n\n- <a name=\"optional-cfg-unstable-coerce-unsized\"></a>**`--cfg portable_atomic_unstable_coerce_unsized`**<br>\n  Support coercing of `Arc<T>` to `Arc<U>` as in `std::sync::Arc`.\n\n  <!-- TODO: add coercing of `Weak<T>` to `Weak<U>` as well, with testing & documentation updates -->\n\n  This cfg requires Rust nightly because this coercing requires [unstable `CoerceUnsized` trait](https://doc.rust-lang.org/nightly/core/ops/trait.CoerceUnsized.html).\n\n  See [this issue comment](https://github.com/taiki-e/portable-atomic/issues/143#issuecomment-1866488569) for another known workaround.\n\n  **Note:** This cfg is unstable and outside of the normal semver guarantees and minor or patch versions of portable-atomic-util may make breaking changes to them at any time.\n\n## Related Projects\n\n- [portable-atomic]: Portable atomic types including support for 128-bit atomics, atomic float, etc.\n- [atomic-maybe-uninit]: Atomic operations on potentially uninitialized integers.\n- [atomic-memcpy]: Byte-wise atomic memcpy.\n\n[atomic-maybe-uninit]: https://github.com/taiki-e/atomic-maybe-uninit\n[atomic-memcpy]: https://github.com/taiki-e/atomic-memcpy\n\n<!-- tidy:sync-markdown-to-rustdoc:end -->\n\n## License\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT) at your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "portable-atomic-util@0.2.8",
      "sourcePath": "build.rs",
      "sha256": "f17a8f6b7c93fa6bcefc325a7b75e9e03fc9c97f23ded051f31d6dc8b8e0d478",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// The rustc-cfg emitted by the build script are *not* public API.\n\nuse std::env;\n\nuse self::version::{Version, rustc_version};\n\nfn main() {\n    println!(\"cargo:rerun-if-changed=build.rs\");\n\n    let target = &*env::var(\"TARGET\").expect(\"TARGET not set\");\n\n    let version = match rustc_version() {\n        Some(version) => version,\n        None => {\n            if env::var_os(\"PORTABLE_ATOMIC_DENY_WARNINGS\").is_some() {\n                panic!(\"unable to determine rustc version\")\n            }\n            println!(\n                \"cargo:warning={}: unable to determine rustc version; assuming latest stable rustc (1.{})\",\n                env!(\"CARGO_PKG_NAME\"),\n                Version::LATEST.minor\n            );\n            Version::LATEST\n        }\n    };\n\n    if version.minor >= 80 {\n        // Custom cfgs set by build script. Not public API.\n        // grep -F 'cargo:rustc-cfg=' portable-atomic-util/build.rs | grep -Ev '^ *//' | sed -E 's/^.*cargo:rustc-cfg=//; s/(=\\\\)?\".*$//' | LC_ALL=C sort -u | tr '\\n' ',' | sed -E 's/,$/\\n/'\n        println!(\n            \"cargo:rustc-check-cfg=cfg(portable_atomic_no_core_unwind_safe,portable_atomic_no_error_in_core,portable_atomic_no_io_safety,portable_atomic_no_min_const_generics,portable_atomic_no_strict_provenance,portable_atomic_no_track_caller,portable_atomic_no_unsafe_op_in_unsafe_fn,portable_atomic_sanitize_thread)\"\n        );\n    }\n\n    // Note that cfgs are `no_`*, not `has_*`. This allows treating as the latest\n    // stable rustc is used when the build script doesn't run. This is useful\n    // for non-cargo build systems that don't run the build script.\n\n    // track_caller stabilized in Rust 1.46 (nightly-2020-07-02): https://github.com/rust-lang/rust/pull/72445\n    if !version.probe(46, 2020, 7, 1) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_track_caller\");\n    }\n    // min_const_generics stabilized in Rust 1.51 (nightly-2020-12-28): https://github.com/rust-lang/rust/pull/79135\n    if !version.probe(51, 2020, 12, 27) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_min_const_generics\");\n    }\n    // unsafe_op_in_unsafe_fn stabilized in Rust 1.52 (nightly-2021-03-11): https://github.com/rust-lang/rust/pull/79208\n    if !version.probe(52, 2021, 3, 10) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_unsafe_op_in_unsafe_fn\");\n    }\n    // https://github.com/rust-lang/rust/pull/84662 merged in Rust 1.56 (nightly-2021-08-02).\n    if !version.probe(56, 2021, 8, 1) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_core_unwind_safe\");\n    }\n    // io_safety stabilized in Rust 1.63 (nightly-2022-06-16): https://github.com/rust-lang/rust/pull/95118\n    // std::os::hermit::io::AsFd requires Rust 1.69 (https://github.com/rust-lang/rust/commit/b5fb4f3d9b1b308d59cab24ef2f9bf23dad948aa)\n    if !version.probe(63, 2022, 6, 15)\n        || version.minor < 69\n            && env::var(\"CARGO_CFG_TARGET_OS\").expect(\"CARGO_CFG_TARGET_OS not set\") == \"hermit\"\n    {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_io_safety\");\n    }\n    // error_in_core stabilized in Rust 1.81 (nightly-2024-06-09): https://github.com/rust-lang/rust/pull/125951\n    if !version.probe(81, 2024, 6, 8) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_error_in_core\");\n    }\n    // strict_provenance/exposed_provenance APIs stabilized in Rust 1.84 (nightly-2024-10-22): https://github.com/rust-lang/rust/pull/130350\n    if !version.probe(84, 2024, 10, 21) {\n        println!(\"cargo:rustc-cfg=portable_atomic_no_strict_provenance\");\n    }\n\n    // `cfg(sanitize = \"..\")` is not stabilized.\n    // x86_64-unknown-linux-gnutsan is available on stable since Rust 1.96: https://github.com/rust-lang/rust/pull/152757\n    let sanitize = env::var(\"CARGO_CFG_SANITIZE\").unwrap_or_default();\n    if sanitize.contains(\"thread\") || target == \"x86_64-unknown-linux-gnutsan\" {\n        println!(\"cargo:rustc-cfg=portable_atomic_sanitize_thread\");\n    }\n}\n\nmod version {\n    use std::{env, iter, process::Command, str};\n\n    pub(crate) fn rustc_version() -> Option<Version> {\n        let rustc = env::var_os(\"RUSTC\")?;\n        let rustc_wrapper = if env::var_os(\"CARGO_ENCODED_RUSTFLAGS\").is_some() {\n            env::var_os(\"RUSTC_WRAPPER\").filter(|v| !v.is_empty())\n        } else {\n            // Cargo sets environment variables for wrappers correctly only since https://github.com/rust-lang/cargo/pull/9601.\n            None\n        };\n        // Do not apply RUSTC_WORKSPACE_WRAPPER: https://github.com/cuviper/autocfg/issues/58#issuecomment-2067625980\n        let mut rustc = rustc_wrapper.into_iter().chain(iter::once(rustc));\n        let mut cmd = Command::new(rustc.next().unwrap());\n        cmd.args(rustc);\n        // Use verbose version output because the packagers add extra strings to the normal version output.\n        // Do not use long flags (--version --verbose) because clippy-deriver doesn't handle them properly.\n        // -vV is also matched with that cargo internally uses: https://github.com/rust-lang/cargo/blob/0.80.0/src/cargo/util/rustc.rs#L65\n        let output = cmd.arg(\"-vV\").output().ok()?;\n        let verbose_version = str::from_utf8(&output.stdout).ok()?;\n        Version::parse(verbose_version)\n    }\n\n    pub(crate) struct Version {\n        pub(crate) minor: u32,\n        pub(crate) nightly: bool,\n        commit_date: Date,\n    }\n\n    impl Version {\n        // The known latest stable version. If we unable to determine\n        // the rustc version, we assume this is the current version.\n        // It is no problem if this is older than the actual latest stable.\n        pub(crate) const LATEST: Self = Self::stable(98);\n\n        pub(crate) const fn stable(rustc_minor: u32) -> Self {\n            Self { minor: rustc_minor, nightly: false, commit_date: Date::UNKNOWN }\n        }\n\n        pub(crate) fn probe(&self, minor: u32, year: u16, month: u8, day: u8) -> bool {\n            if self.nightly {\n                self.minor > minor\n                    || self.minor == minor && self.commit_date >= Date::new(year, month, day)\n            } else {\n                self.minor >= minor\n            }\n        }\n\n        pub(crate) fn parse(verbose_version: &str) -> Option<Self> {\n            let mut release = verbose_version\n                .lines()\n                .find(|line| line.starts_with(\"release: \"))\n                .map(|line| &line[\"release: \".len()..])?\n                .splitn(2, '-');\n            let version = release.next().unwrap();\n            let channel = release.next().unwrap_or_default();\n            let mut digits = version.splitn(3, '.');\n            let major = digits.next()?;\n            if major != \"1\" {\n                return None;\n            }\n            let minor = digits.next()?.parse::<u32>().ok()?;\n            let _patch = digits.next().unwrap_or(\"0\").parse::<u32>().ok()?;\n            let nightly = match env::var_os(\"RUSTC_BOOTSTRAP\") {\n                // When -1 is passed rustc works like stable, e.g., cfg(target_feature = \"unstable_target_feature\") will never be set. https://github.com/rust-lang/rust/pull/132993\n                Some(ref v) if v == \"-1\" => false,\n                // When 1 is passed stable rustc works like nightly, but we ignore it for now.\n                _ => channel == \"nightly\" || channel == \"dev\",\n            };\n\n            // we don't refer commit date on stable/beta.\n            if nightly {\n                let commit_date = (|| {\n                    let mut commit_date = verbose_version\n                        .lines()\n                        .find(|line| line.starts_with(\"commit-date: \"))\n                        .map(|line| &line[\"commit-date: \".len()..])?\n                        .splitn(3, '-');\n                    let year = commit_date.next()?.parse::<u16>().ok()?;\n                    let month = commit_date.next()?.parse::<u8>().ok()?;\n                    let day = commit_date.next()?.parse::<u8>().ok()?;\n                    if month > 12 || day > 31 {\n                        return None;\n                    }\n                    Some(Date::new(year, month, day))\n                })();\n                Some(Self { minor, nightly, commit_date: commit_date.unwrap_or(Date::UNKNOWN) })\n            } else {\n                Some(Self::stable(minor))\n            }\n        }\n    }\n\n    #[derive(PartialEq, PartialOrd)]\n    pub(crate) struct Date {\n        pub(crate) year: u16,\n        pub(crate) month: u8,\n        pub(crate) day: u8,\n    }\n\n    impl Date {\n        const UNKNOWN: Self = Self::new(0, 0, 0);\n\n        const fn new(year: u16, month: u8, day: u8) -> Self {\n            Self { year, month, day }\n        }\n    }\n}\n"
    },
    {
      "package": "portable-atomic-util@0.2.8",
      "sourcePath": "src/arc.rs",
      "sha256": "e23f18ca0592f694ac2da85e9b83ea3add4fad978cd37ac05c742af254fa82a9",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// This module is based on alloc::sync::Arc.\n//\n// The code has been adjusted to work with stable Rust (and optionally support some unstable features).\n//\n// Source: https://github.com/rust-lang/rust/blob/1.93.0/library/alloc/src/sync.rs\n//\n// Copyright & License of the original code:\n// - https://github.com/rust-lang/rust/blob/1.93.0/COPYRIGHT\n// - https://github.com/rust-lang/rust/blob/1.93.0/LICENSE-APACHE\n// - https://github.com/rust-lang/rust/blob/1.93.0/LICENSE-MIT\n\n#![allow(clippy::must_use_candidate)] // align to alloc::sync::Arc\n#![allow(clippy::undocumented_unsafe_blocks)] // TODO: most of the unsafe codes were inherited from alloc::sync::Arc\n\nuse alloc::{\n    alloc::handle_alloc_error,\n    borrow::{Cow, ToOwned},\n    boxed::Box,\n    string::String,\n    vec::Vec,\n};\n#[cfg(not(portable_atomic_no_min_const_generics))]\nuse core::convert::TryFrom;\nuse core::{\n    alloc::Layout,\n    any::Any,\n    borrow,\n    cmp::Ordering,\n    fmt,\n    hash::{Hash, Hasher},\n    iter::FromIterator,\n    marker::PhantomData,\n    mem::{self, ManuallyDrop},\n    ops::Deref,\n    pin::Pin,\n    ptr::{self, NonNull},\n    slice,\n};\n#[allow(deprecated)]\nuse core::{isize, usize};\n#[cfg(portable_atomic_unstable_coerce_unsized)]\nuse core::{marker::Unsize, ops::CoerceUnsized};\n\nuse portable_atomic::{\n    self as atomic,\n    Ordering::{Acquire, Relaxed, Release},\n    hint,\n};\n\nuse crate::utils::ptr as strict;\n#[cfg(portable_atomic_no_strict_provenance)]\nuse crate::utils::ptr::PtrExt as _;\n\n#[allow(deprecated)] // associated constant MAX requires Rust 1.43\nconst ISIZE_MAX: isize = isize::MAX;\n#[allow(deprecated)] // associated constant MAX requires Rust 1.43\nconst USIZE_MAX: usize = usize::MAX;\n\n/// A soft limit on the amount of references that may be made to an `Arc`.\n///\n/// Going above this limit will abort your program (although not\n/// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references.\n/// Trying to go above it might call a `panic` (if not actually going above it).\n///\n/// This is a global invariant, and also applies when using a compare-exchange loop.\n///\n/// See comment in `Arc::clone`.\nconst MAX_REFCOUNT: usize = ISIZE_MAX as usize;\n\n/// The error in case either counter reaches above `MAX_REFCOUNT`, and we can `panic` safely.\nconst INTERNAL_OVERFLOW_ERROR: &str = \"Arc counter overflow\";\n\n#[cfg(not(portable_atomic_sanitize_thread))]\nmacro_rules! acquire {\n    ($x:expr) => {\n        atomic::fence(Acquire)\n    };\n}\n\n// ThreadSanitizer does not support memory fences. To avoid false positive\n// reports in Arc / Weak implementation use atomic loads for synchronization\n// instead.\n#[cfg(portable_atomic_sanitize_thread)]\nmacro_rules! acquire {\n    ($x:expr) => {\n        $x.load(Acquire)\n    };\n}\n\n/// A thread-safe reference-counting pointer. 'Arc' stands for 'Atomically\n/// Reference Counted'.\n///\n/// This is an equivalent to [`std::sync::Arc`], but using [portable-atomic] for synchronization.\n/// See the documentation for [`std::sync::Arc`] for more details.\n///\n/// **Note:** Unlike `std::sync::Arc`, coercing `Arc<T>` to `Arc<U>` is only possible if\n/// the optional cfg `portable_atomic_unstable_coerce_unsized` is enabled, as documented at the crate-level documentation,\n/// and this optional cfg item is only supported with Rust nightly version.\n/// This is because coercing the pointee requires the\n/// [unstable `CoerceUnsized` trait](https://doc.rust-lang.org/nightly/core/ops/trait.CoerceUnsized.html).\n/// See [this issue comment](https://github.com/taiki-e/portable-atomic/issues/143#issuecomment-1866488569)\n/// for a workaround that works without depending on unstable features.\n///\n/// [portable-atomic]: https://crates.io/crates/portable-atomic\n///\n/// # Examples\n///\n/// ```\n/// use portable_atomic_util::Arc;\n/// use std::thread;\n///\n/// let five = Arc::new(5);\n///\n/// for _ in 0..10 {\n///     let five = Arc::clone(&five);\n///\n///     thread::spawn(move || {\n///         assert_eq!(*five, 5);\n///     });\n/// }\n/// # if cfg!(miri) { std::thread::sleep(std::time::Duration::from_millis(500)); } // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371\n/// ```\npub struct Arc<T: ?Sized> {\n    ptr: NonNull<ArcInner<T>>,\n    phantom: PhantomData<ArcInner<T>>,\n}\n\nunsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}\nunsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}\n\n#[cfg(not(portable_atomic_no_core_unwind_safe))]\nimpl<T: ?Sized + core::panic::RefUnwindSafe> core::panic::UnwindSafe for Arc<T> {}\n#[cfg(all(portable_atomic_no_core_unwind_safe, feature = \"std\"))]\nimpl<T: ?Sized + std::panic::RefUnwindSafe> std::panic::UnwindSafe for Arc<T> {}\n\n#[cfg(portable_atomic_unstable_coerce_unsized)]\nimpl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}\n\nimpl<T: ?Sized> Arc<T> {\n    #[inline]\n    fn into_inner_non_null(this: Self) -> NonNull<ArcInner<T>> {\n        let this = mem::ManuallyDrop::new(this);\n        this.ptr\n    }\n\n    #[inline]\n    unsafe fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {\n        Self { ptr, phantom: PhantomData }\n    }\n\n    #[inline]\n    unsafe fn from_ptr(ptr: *mut ArcInner<T>) -> Self {\n        // SAFETY: the caller must uphold the safety contract.\n        unsafe { Self::from_inner(NonNull::new_unchecked(ptr)) }\n    }\n}\n\n/// `Weak` is a version of [`Arc`] that holds a non-owning reference to the\n/// managed allocation.\n///\n/// The allocation is accessed by calling [`upgrade`] on the `Weak`\n/// pointer, which returns an <code>[Option]<[Arc]\\<T>></code>.\n///\n/// This is an equivalent to [`std::sync::Weak`], but using [portable-atomic] for synchronization.\n/// See the documentation for [`std::sync::Weak`] for more details.\n///\n/// <!-- TODO: support coercing `Weak<T>` to `Weak<U>` with testing, if optional cfg `portable_atomic_unstable_coerce_unsized` is enabled -->\n/// **Note:** Unlike `std::sync::Weak`, coercing `Weak<T>` to `Weak<U>` is not possible, not even if\n/// the optional cfg `portable_atomic_unstable_coerce_unsized` is enabled.\n///\n/// [`upgrade`]: Weak::upgrade\n/// [portable-atomic]: https://crates.io/crates/portable-atomic\n///\n/// # Examples\n///\n/// ```\n/// use portable_atomic_util::Arc;\n/// use std::thread;\n///\n/// let five = Arc::new(5);\n/// let weak_five = Arc::downgrade(&five);\n///\n/// # let t =\n/// thread::spawn(move || {\n///     let five = weak_five.upgrade().unwrap();\n///     assert_eq!(*five, 5);\n/// });\n/// # t.join().unwrap(); // join thread to avoid https://github.com/rust-lang/miri/issues/1371\n/// ```\npub struct Weak<T: ?Sized> {\n    // This is a `NonNull` to allow optimizing the size of this type in enums,\n    // but it is not necessarily a valid pointer.\n    // `Weak::new` sets this to `usize::MAX` so that it doesn't need\n    // to allocate space on the heap. That's not a value a real pointer\n    // will ever have because ArcInner has alignment at least 2.\n    ptr: NonNull<ArcInner<T>>,\n}\n\nunsafe impl<T: ?Sized + Sync + Send> Send for Weak<T> {}\nunsafe impl<T: ?Sized + Sync + Send> Sync for Weak<T> {}\n\nimpl<T: ?Sized> fmt::Debug for Weak<T> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(\"(Weak)\")\n    }\n}\n\n// This is repr(C) to future-proof against possible field-reordering, which\n// would interfere with otherwise safe [into|from]_raw() of transmutable\n// inner types.\n// Unlike RcInner, repr(align(2)) is not strictly required because atomic types\n// have the alignment same as its size, but we use it for consistency and clarity.\n#[repr(C, align(2))]\nstruct ArcInner<T: ?Sized> {\n    strong: atomic::AtomicUsize,\n\n    // the value usize::MAX acts as a sentinel for temporarily \"locking\" the\n    // ability to upgrade weak pointers or downgrade strong ones; this is used\n    // to avoid races in `make_mut` and `get_mut`.\n    weak: atomic::AtomicUsize,\n\n    data: T,\n}\n\n/// Calculate layout for `ArcInner<T>` using the inner value's layout\nfn arc_inner_layout_for_value_layout(layout: Layout) -> Layout {\n    // Calculate layout using the given value layout.\n    // Previously, layout was calculated on the expression\n    // `&*(ptr as *const ArcInner<T>)`, but this created a misaligned\n    // reference (see #54908).\n    layout::pad_to_align(layout::extend(Layout::new::<ArcInner<()>>(), layout).unwrap().0)\n}\n\nunsafe impl<T: ?Sized + Sync + Send> Send for ArcInner<T> {}\nunsafe impl<T: ?Sized + Sync + Send> Sync for ArcInner<T> {}\n\nimpl<T> Arc<T> {\n    /// Constructs a new `Arc<T>`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    /// ```\n    #[inline]\n    pub fn new(data: T) -> Self {\n        // Start the weak pointer count as 1 which is the weak pointer that's\n        // held by all the strong pointers (kinda), see std/rc.rs for more info\n        let x: Box<_> = Box::new(ArcInner {\n            strong: atomic::AtomicUsize::new(1),\n            weak: atomic::AtomicUsize::new(1),\n            data,\n        });\n        unsafe { Self::from_inner(Box::leak(x).into()) }\n    }\n\n    /// Constructs a new `Arc<T>` while giving you a `Weak<T>` to the allocation,\n    /// to allow you to construct a `T` which holds a weak pointer to itself.\n    ///\n    /// Generally, a structure circularly referencing itself, either directly or\n    /// indirectly, should not hold a strong reference to itself to prevent a memory leak.\n    /// Using this function, you get access to the weak pointer during the\n    /// initialization of `T`, before the `Arc<T>` is created, such that you can\n    /// clone and store it inside the `T`.\n    ///\n    /// `new_cyclic` first allocates the managed allocation for the `Arc<T>`,\n    /// then calls your closure, giving it a `Weak<T>` to this allocation,\n    /// and only afterwards completes the construction of the `Arc<T>` by placing\n    /// the `T` returned from your closure into the allocation.\n    ///\n    /// Since the new `Arc<T>` is not fully-constructed until `Arc<T>::new_cyclic`\n    /// returns, calling [`upgrade`] on the weak reference inside your closure will\n    /// fail and result in a `None` value.\n    ///\n    /// # Panics\n    ///\n    /// If `data_fn` panics, the panic is propagated to the caller, and the\n    /// temporary [`Weak<T>`] is dropped normally.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use portable_atomic_util::{Arc, Weak};\n    ///\n    /// struct Gadget {\n    ///     me: Weak<Gadget>,\n    /// }\n    ///\n    /// impl Gadget {\n    ///     /// Constructs a reference counted Gadget.\n    ///     fn new() -> Arc<Self> {\n    ///         // `me` is a `Weak<Gadget>` pointing at the new allocation of the\n    ///         // `Arc` we're constructing.\n    ///         Arc::new_cyclic(|me| {\n    ///             // Create the actual struct here.\n    ///             Gadget { me: me.clone() }\n    ///         })\n    ///     }\n    ///\n    ///     /// Returns a reference counted pointer to Self.\n    ///     fn me(&self) -> Arc<Self> {\n    ///         self.me.upgrade().unwrap()\n    ///     }\n    /// }\n    /// ```\n    /// [`upgrade`]: Weak::upgrade\n    #[inline]\n    pub fn new_cyclic<F>(data_fn: F) -> Self\n    where\n        F: FnOnce(&Weak<T>) -> T,\n    {\n        // Construct the inner in the \"uninitialized\" state with a single\n        // weak reference.\n        let init_ptr = Weak::new_uninit_ptr();\n\n        let weak = Weak { ptr: init_ptr };\n\n        // It's important we don't give up ownership of the weak pointer, or\n        // else the memory might be freed by the time `data_fn` returns. If\n        // we really wanted to pass ownership, we could create an additional\n        // weak pointer for ourselves, but this would result in additional\n        // updates to the weak reference count which might not be necessary\n        // otherwise.\n        let data = data_fn(&weak);\n\n        // Now we can properly initialize the inner value and turn our weak\n        // reference into a strong reference.\n        unsafe {\n            let inner = init_ptr.as_ptr();\n            ptr::write(data_ptr::<T>(inner, &data), data);\n\n            // The above write to the data field must be visible to any threads which\n            // observe a non-zero strong count. Therefore we need at least \"Release\" ordering\n            // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`.\n            //\n            // \"Acquire\" ordering is not required. When considering the possible behaviors\n            // of `data_fn` we only need to look at what it could do with a reference to a\n            // non-upgradeable `Weak`:\n            // - It can *clone* the `Weak`, increasing the weak reference count.\n            // - It can drop those clones, decreasing the weak reference count (but never to zero).\n            //\n            // These side effects do not impact us in any way, and no other side effects are\n            // possible with safe code alone.\n            let prev_value = (*inner).strong.fetch_add(1, Release);\n            debug_assert_eq!(prev_value, 0, \"No prior strong references should exist\");\n\n            // Strong references should collectively own a shared weak reference,\n            // so don't run the destructor for our old weak reference.\n            mem::forget(weak);\n\n            Self::from_inner(init_ptr)\n        }\n    }\n\n    /// Constructs a new `Arc` with uninitialized contents.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let mut five = Arc::<u32>::new_uninit();\n    ///\n    /// // Deferred initialization:\n    /// Arc::get_mut(&mut five).unwrap().write(5);\n    ///\n    /// let five = unsafe { five.assume_init() };\n    ///\n    /// assert_eq!(*five, 5)\n    /// ```\n    #[inline]\n    #[must_use]\n    pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {\n        unsafe {\n            Arc::from_ptr(Arc::allocate_for_layout(\n                Layout::new::<T>(),\n                |layout| Global.allocate(layout),\n                |ptr| ptr as *mut _,\n            ))\n        }\n    }\n\n    /// Constructs a new `Arc` with uninitialized contents, with the memory\n    /// being filled with `0` bytes.\n    ///\n    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage\n    /// of this method.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let zero = Arc::<u32>::new_zeroed();\n    /// let zero = unsafe { zero.assume_init() };\n    ///\n    /// assert_eq!(*zero, 0)\n    /// ```\n    ///\n    /// [zeroed]: mem::MaybeUninit::zeroed\n    #[inline]\n    #[must_use]\n    pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {\n        unsafe {\n            Arc::from_ptr(Arc::allocate_for_layout(\n                Layout::new::<T>(),\n                |layout| Global.allocate_zeroed(layout),\n                |ptr| ptr as *mut _,\n            ))\n        }\n    }\n\n    /// Constructs a new `Pin<Arc<T>>`. If `T` does not implement `Unpin`, then\n    /// `data` will be pinned in memory and unable to be moved.\n    #[must_use]\n    pub fn pin(data: T) -> Pin<Self> {\n        unsafe { Pin::new_unchecked(Self::new(data)) }\n    }\n\n    /// Returns the inner value, if the `Arc` has exactly one strong reference.\n    ///\n    /// Otherwise, an [`Err`] is returned with the same `Arc` that was\n    /// passed in.\n    ///\n    /// This will succeed even if there are outstanding weak references.\n    ///\n    /// It is strongly recommended to use [`Arc::into_inner`] instead if you don't\n    /// keep the `Arc` in the [`Err`] case.\n    /// Immediately dropping the [`Err`]-value, as the expression\n    /// `Arc::try_unwrap(this).ok()` does, can cause the strong count to\n    /// drop to zero and the inner value of the `Arc` to be dropped.\n    /// For instance, if two threads execute such an expression in parallel,\n    /// there is a race condition without the possibility of unsafety:\n    /// The threads could first both check whether they own the last instance\n    /// in `Arc::try_unwrap`, determine that they both do not, and then both\n    /// discard and drop their instance in the call to [`ok`][`Result::ok`].\n    /// In this scenario, the value inside the `Arc` is safely destroyed\n    /// by exactly one of the threads, but neither thread will ever be able\n    /// to use the value.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let x = Arc::new(3);\n    /// assert_eq!(Arc::try_unwrap(x), Ok(3));\n    ///\n    /// let x = Arc::new(4);\n    /// let _y = Arc::clone(&x);\n    /// assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4);\n    /// ```\n    #[inline]\n    pub fn try_unwrap(this: Self) -> Result<T, Self> {\n        if this.inner().strong.compare_exchange(1, 0, Relaxed, Relaxed).is_err() {\n            return Err(this);\n        }\n\n        acquire!(this.inner().strong);\n\n        let this = ManuallyDrop::new(this);\n        let elem: T = unsafe { ptr::read(&this.ptr.as_ref().data) };\n\n        // Make a weak pointer to clean up the implicit strong-weak reference\n        let _weak = Weak { ptr: this.ptr };\n\n        Ok(elem)\n    }\n\n    /// Returns the inner value, if the `Arc` has exactly one strong reference.\n    ///\n    /// Otherwise, [`None`] is returned and the `Arc` is dropped.\n    ///\n    /// This will succeed even if there are outstanding weak references.\n    ///\n    /// If `Arc::into_inner` is called on every clone of this `Arc`,\n    /// it is guaranteed that exactly one of the calls returns the inner value.\n    /// This means in particular that the inner value is not dropped.\n    ///\n    /// [`Arc::try_unwrap`] is conceptually similar to `Arc::into_inner`, but it\n    /// is meant for different use-cases. If used as a direct replacement\n    /// for `Arc::into_inner` anyway, such as with the expression\n    /// <code>[Arc::try_unwrap]\\(this).[ok][Result::ok]()</code>, then it does\n    /// **not** give the same guarantee as described in the previous paragraph.\n    /// For more information, see the examples below and read the documentation\n    /// of [`Arc::try_unwrap`].\n    ///\n    /// # Examples\n    ///\n    /// Minimal example demonstrating the guarantee that `Arc::into_inner` gives.\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let x = Arc::new(3);\n    /// let y = Arc::clone(&x);\n    ///\n    /// // Two threads calling `Arc::into_inner` on both clones of an `Arc`:\n    /// let x_thread = std::thread::spawn(|| Arc::into_inner(x));\n    /// let y_thread = std::thread::spawn(|| Arc::into_inner(y));\n    ///\n    /// let x_inner_value = x_thread.join().unwrap();\n    /// let y_inner_value = y_thread.join().unwrap();\n    ///\n    /// // One of the threads is guaranteed to receive the inner value:\n    /// assert!(matches!((x_inner_value, y_inner_value), (None, Some(3)) | (Some(3), None)));\n    /// // The result could also be `(None, None)` if the threads called\n    /// // `Arc::try_unwrap(x).ok()` and `Arc::try_unwrap(y).ok()` instead.\n    /// ```\n    ///\n    /// A more practical example demonstrating the need for `Arc::into_inner`:\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// // Definition of a simple singly linked list using `Arc`:\n    /// #[derive(Clone)]\n    /// struct LinkedList<T>(Option<Arc<Node<T>>>);\n    /// struct Node<T>(T, Option<Arc<Node<T>>>);\n    ///\n    /// // Dropping a long `LinkedList<T>` relying on the destructor of `Arc`\n    /// // can cause a stack overflow. To prevent this, we can provide a\n    /// // manual `Drop` implementation that does the destruction in a loop:\n    /// impl<T> Drop for LinkedList<T> {\n    ///     fn drop(&mut self) {\n    ///         let mut link = self.0.take();\n    ///         while let Some(arc_node) = link.take() {\n    ///             if let Some(Node(_value, next)) = Arc::into_inner(arc_node) {\n    ///                 link = next;\n    ///             }\n    ///         }\n    ///     }\n    /// }\n    ///\n    /// // Implementation of `new` and `push` omitted\n    /// impl<T> LinkedList<T> {\n    ///     /* ... */\n    /// #   fn new() -> Self {\n    /// #       LinkedList(None)\n    /// #   }\n    /// #   fn push(&mut self, x: T) {\n    /// #       self.0 = Some(Arc::new(Node(x, self.0.take())));\n    /// #   }\n    /// }\n    ///\n    /// // The following code could have still caused a stack overflow\n    /// // despite the manual `Drop` impl if that `Drop` impl had used\n    /// // `Arc::try_unwrap(arc).ok()` instead of `Arc::into_inner(arc)`.\n    ///\n    /// // Create a long list and clone it\n    /// let mut x = LinkedList::new();\n    /// let size = 100_000;\n    /// # let size = if cfg!(miri) { 100 } else { size };\n    /// for i in 0..size {\n    ///     x.push(i); // Adds i to the front of x\n    /// }\n    /// let y = x.clone();\n    ///\n    /// // Drop the clones in parallel\n    /// let x_thread = std::thread::spawn(|| drop(x));\n    /// let y_thread = std::thread::spawn(|| drop(y));\n    /// x_thread.join().unwrap();\n    /// y_thread.join().unwrap();\n    /// ```\n    #[inline]\n    pub fn into_inner(this: Self) -> Option<T> {\n        // Make sure that the ordinary `Drop` implementation isn't called as well\n        let mut this = mem::ManuallyDrop::new(this);\n\n        // Following the implementation of `drop` and `drop_slow`\n        if this.inner().strong.fetch_sub(1, Release) != 1 {\n            return None;\n        }\n\n        acquire!(this.inner().strong);\n\n        // SAFETY: This mirrors the line\n        //\n        //     unsafe { ptr::drop_in_place(Self::get_mut_unchecked(self)) };\n        //\n        // in `drop_slow`. Instead of dropping the value behind the pointer,\n        // it is read and eventually returned; `ptr::read` has the same\n        // safety conditions as `ptr::drop_in_place`.\n        let inner = unsafe { ptr::read(Self::get_mut_unchecked(&mut this)) };\n\n        drop(Weak { ptr: this.ptr });\n\n        Some(inner)\n    }\n\n    /// Maps the value in an `Arc`, reusing the allocation if possible.\n    ///\n    /// `f` is called on a reference to the value in the `Arc`, and the result is returned, also in\n    /// an `Arc`.\n    ///\n    /// Note: this is an associated function, which means that you have\n    /// to call it as `Arc::map(a, f)` instead of `r.map(a)`. This\n    /// is so that there is no conflict with a method on the inner type.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let r = Arc::new(7);\n    /// let new = Arc::map(r, |i| i + 7);\n    /// assert_eq!(*new, 14);\n    /// ```\n    #[inline]\n    pub fn map<F, U>(this: Self, f: F) -> Arc<U>\n    where\n        F: FnOnce(&T) -> U,\n    {\n        if mem::size_of::<T>() == mem::size_of::<U>()\n            && mem::align_of::<T>() == mem::align_of::<U>()\n            && Arc::is_unique(&this)\n        {\n            unsafe {\n                let ptr = Arc::into_raw(this);\n                let value = ptr.read();\n                let mut allocation = Arc::from_raw(ptr as *const mem::MaybeUninit<U>);\n\n                *Arc::get_mut_unchecked(&mut allocation) = mem::MaybeUninit::new(f(&value));\n                allocation.assume_init()\n            }\n        } else {\n            Arc::new(f(&*this))\n        }\n    }\n}\n\nimpl<T> Arc<[T]> {\n    /// Constructs a new atomically reference-counted slice with uninitialized contents.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let mut values = Arc::<[u32]>::new_uninit_slice(3);\n    ///\n    /// // Deferred initialization:\n    /// let data = Arc::get_mut(&mut values).unwrap();\n    /// data[0].write(1);\n    /// data[1].write(2);\n    /// data[2].write(3);\n    ///\n    /// let values = unsafe { values.assume_init() };\n    ///\n    /// assert_eq!(*values, [1, 2, 3])\n    /// ```\n    #[inline]\n    #[must_use]\n    pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {\n        unsafe { Arc::from_ptr(Arc::allocate_for_slice(len)) }\n    }\n\n    /// Constructs a new atomically reference-counted slice with uninitialized contents, with the memory being\n    /// filled with `0` bytes.\n    ///\n    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and\n    /// incorrect usage of this method.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let values = Arc::<[u32]>::new_zeroed_slice(3);\n    /// let values = unsafe { values.assume_init() };\n    ///\n    /// assert_eq!(*values, [0, 0, 0])\n    /// ```\n    ///\n    /// [zeroed]: mem::MaybeUninit::zeroed\n    #[inline]\n    #[must_use]\n    #[allow(clippy::missing_panics_doc)]\n    pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {\n        unsafe {\n            Arc::from_ptr(Arc::allocate_for_layout(\n                layout::array::<T>(len).unwrap(),\n                |layout| Global.allocate_zeroed(layout),\n                |mem| {\n                    // We create a slice just for metadata (we must use `[mem::MaybeUninit<T>]`\n                    // instead of `[T]` because values behind `mem` is not valid initialized `T`s.\n                    // there is no size/alignment issue thanks to layout::array), and create a\n                    // pointer from `mem` and slice's metadata.\n                    //\n                    // We cannot use other ways here:\n                    // - ptr::slice_from_raw_parts_mut is best way here, but requires Rust 1.42.\n                    // - We cannot use slice::from_raw_parts_mut then casting to its pointer to\n                    //   ArcInner due to provenance because the actual size of valid allocation\n                    //   behind `mem` is `layout.size()` bytes (counters + values + padding) but the\n                    //   allocation from the pointer from slice::from_raw_parts_mut only valid for\n                    //   `size_of::<T> * len` bytes (only values).\n                    let meta: *const _ =\n                        slice::from_raw_parts(mem as *const mem::MaybeUninit<T>, len);\n                    strict::with_metadata_of(mem, meta) as *mut ArcInner<[mem::MaybeUninit<T>]>\n                },\n            ))\n        }\n    }\n}\n\nimpl<T> Arc<mem::MaybeUninit<T>> {\n    /// Converts to `Arc<T>`.\n    ///\n    /// # Safety\n    ///\n    /// As with [`MaybeUninit::assume_init`],\n    /// it is up to the caller to guarantee that the inner value\n    /// really is in an initialized state.\n    /// Calling this when the content is not yet fully initialized\n    /// causes immediate undefined behavior.\n    ///\n    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let mut five = Arc::<u32>::new_uninit();\n    ///\n    /// // Deferred initialization:\n    /// Arc::get_mut(&mut five).unwrap().write(5);\n    ///\n    /// let five = unsafe { five.assume_init() };\n    ///\n    /// assert_eq!(*five, 5)\n    /// ```\n    #[inline]\n    #[must_use = \"`self` will be dropped if the result is not used\"]\n    pub unsafe fn assume_init(self) -> Arc<T> {\n        let ptr = Arc::into_inner_non_null(self);\n        // SAFETY: MaybeUninit<T> has the same layout as T, and\n        // the caller must guarantee that the data is initialized.\n        unsafe { Arc::from_inner(ptr.cast::<ArcInner<T>>()) }\n    }\n}\n\nimpl<T: ?Sized + CloneToUninit> Arc<T> {\n    fn clone_from_ref(value: &T) -> Self {\n        // `in_progress` drops the allocation if we panic before finishing initializing it.\n        let mut in_progress: UniqueArcUninit<T> = UniqueArcUninit::new(value);\n\n        // Initialize with clone of value.\n        unsafe {\n            // Clone. If the clone panics, `in_progress` will be dropped and clean up.\n            value.clone_to_uninit(in_progress.data_ptr() as *mut u8);\n            // Cast type of pointer, now that it is initialized.\n            in_progress.into_arc()\n        }\n    }\n}\n\nimpl<T> Arc<[mem::MaybeUninit<T>]> {\n    /// Converts to `Arc<[T]>`.\n    ///\n    /// # Safety\n    ///\n    /// As with [`MaybeUninit::assume_init`],\n    /// it is up to the caller to guarantee that the inner value\n    /// really is in an initialized state.\n    /// Calling this when the content is not yet fully initialized\n    /// causes immediate undefined behavior.\n    ///\n    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let mut values = Arc::<[u32]>::new_uninit_slice(3);\n    ///\n    /// // Deferred initialization:\n    /// let data = Arc::get_mut(&mut values).unwrap();\n    /// data[0].write(1);\n    /// data[1].write(2);\n    /// data[2].write(3);\n    ///\n    /// let values = unsafe { values.assume_init() };\n    ///\n    /// assert_eq!(*values, [1, 2, 3])\n    /// ```\n    #[inline]\n    #[must_use = \"`self` will be dropped if the result is not used\"]\n    pub unsafe fn assume_init(self) -> Arc<[T]> {\n        let ptr = Arc::into_inner_non_null(self);\n        // SAFETY: [MaybeUninit<T>] has the same layout as [T], and\n        // the caller must guarantee that the data is initialized.\n        unsafe { Arc::from_ptr(ptr.as_ptr() as *mut ArcInner<[T]>) }\n    }\n}\n\nimpl<T: ?Sized> Arc<T> {\n    /// Constructs an `Arc<T>` from a raw pointer.\n    ///\n    /// # Safety\n    ///\n    /// The raw pointer must have been previously returned by a call to\n    /// [`Arc<U>::into_raw`][into_raw] with the following requirements:\n    ///\n    /// * If `U` is sized, it must have the same size and alignment as `T`. This\n    ///   is trivially true if `U` is `T`.\n    /// * If `U` is unsized, its data pointer must have the same size and\n    ///   alignment as `T`. This is trivially true if `Arc<U>` was constructed\n    ///   through `Arc<T>` and then converted to `Arc<U>` through an [unsized\n    ///   coercion].\n    ///\n    /// Note that if `U` or `U`'s data pointer is not `T` but has the same size\n    /// and alignment, this is basically like transmuting references of\n    /// different types. See [`mem::transmute`] for more information\n    /// on what restrictions apply in this case.\n    ///\n    /// The raw pointer must point to a block of memory allocated by the global allocator.\n    ///\n    /// The user of `from_raw` has to make sure a specific value of `T` is only\n    /// dropped once.\n    ///\n    /// This function is unsafe because improper use may lead to memory unsafety,\n    /// even if the returned `Arc<T>` is never accessed.\n    ///\n    /// [into_raw]: Arc::into_raw\n    /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let x = Arc::new(\"hello\".to_owned());\n    /// let x_ptr = Arc::into_raw(x);\n    ///\n    /// unsafe {\n    ///     // Convert back to an `Arc` to prevent leak.\n    ///     let x = Arc::from_raw(x_ptr);\n    ///     assert_eq!(&*x, \"hello\");\n    ///\n    ///     // Further calls to `Arc::from_raw(x_ptr)` would be memory-unsafe.\n    /// }\n    ///\n    /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!\n    /// ```\n    ///\n    /// Convert a slice back into its original array:\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let x: Arc<[u32]> = Arc::from([1, 2, 3]);\n    /// let x_ptr: *const [u32] = Arc::into_raw(x);\n    ///\n    /// unsafe {\n    ///     let x: Arc<[u32; 3]> = Arc::from_raw(x_ptr.cast::<[u32; 3]>());\n    ///     assert_eq!(&*x, &[1, 2, 3]);\n    /// }\n    /// ```\n    #[inline]\n    pub unsafe fn from_raw(ptr: *const T) -> Self {\n        unsafe {\n            let offset = data_offset::<T>(&*ptr);\n\n            // Reverse the offset to find the original ArcInner.\n            let arc_ptr = strict::byte_sub(ptr as *mut T, offset) as *mut ArcInner<T>;\n\n            Self::from_ptr(arc_ptr)\n        }\n    }\n\n    /// Consumes the `Arc`, returning the wrapped pointer.\n    ///\n    /// To avoid a memory leak the pointer must be converted back to an `Arc` using\n    /// [`Arc::from_raw`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let x = Arc::new(\"hello\".to_owned());\n    /// let x_ptr = Arc::into_raw(x);\n    /// assert_eq!(unsafe { &*x_ptr }, \"hello\");\n    /// # // Prevent leaks for Miri.\n    /// # drop(unsafe { Arc::from_raw(x_ptr) });\n    /// ```\n    #[must_use = \"losing the pointer will leak memory\"]\n    pub fn into_raw(this: Self) -> *const T {\n        let this = ManuallyDrop::new(this);\n        Self::as_ptr(&*this)\n    }\n\n    /// Increments the strong reference count on the `Arc<T>` associated with the\n    /// provided pointer by one.\n    ///\n    /// # Safety\n    ///\n    /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the\n    /// same layout requirements specified in [`Arc::from_raw`].\n    /// The associated `Arc` instance must be valid (i.e. the strong count must be at\n    /// least 1) for the duration of this method, and `ptr` must point to a block of memory\n    /// allocated by the global allocator.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// unsafe {\n    ///     let ptr = Arc::into_raw(five);\n    ///     Arc::increment_strong_count(ptr);\n    ///\n    ///     // This assertion is deterministic because we haven't shared\n    ///     // the `Arc` between threads.\n    ///     let five = Arc::from_raw(ptr);\n    ///     assert_eq!(2, Arc::strong_count(&five));\n    /// #   // Prevent leaks for Miri.\n    /// #   Arc::decrement_strong_count(ptr);\n    /// }\n    /// ```\n    #[inline]\n    pub unsafe fn increment_strong_count(ptr: *const T) {\n        // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop\n        let arc = unsafe { mem::ManuallyDrop::new(Self::from_raw(ptr)) };\n        // Now increase refcount, but don't drop new refcount either\n        let _arc_clone: mem::ManuallyDrop<_> = arc.clone();\n    }\n\n    /// Decrements the strong reference count on the `Arc<T>` associated with the\n    /// provided pointer by one.\n    ///\n    /// # Safety\n    ///\n    /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the\n    /// same layout requirements specified in [`Arc::from_raw`].\n    /// The associated `Arc` instance must be valid (i.e. the strong count must be at\n    /// least 1) when invoking this method, and `ptr` must point to a block of memory\n    /// allocated by the global allocator. This method can be used to release the final\n    /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been\n    /// released.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// unsafe {\n    ///     let ptr = Arc::into_raw(five);\n    ///     Arc::increment_strong_count(ptr);\n    ///\n    ///     // Those assertions are deterministic because we haven't shared\n    ///     // the `Arc` between threads.\n    ///     let five = Arc::from_raw(ptr);\n    ///     assert_eq!(2, Arc::strong_count(&five));\n    ///     Arc::decrement_strong_count(ptr);\n    ///     assert_eq!(1, Arc::strong_count(&five));\n    /// }\n    /// ```\n    #[inline]\n    pub unsafe fn decrement_strong_count(ptr: *const T) {\n        // SAFETY: the caller must uphold the safety contract.\n        unsafe { drop(Self::from_raw(ptr)) }\n    }\n\n    /// Provides a raw pointer to the data.\n    ///\n    /// The counts are not affected in any way and the `Arc` is not consumed. The pointer is valid for\n    /// as long as there are strong counts in the `Arc`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let x = Arc::new(\"hello\".to_owned());\n    /// let y = Arc::clone(&x);\n    /// let x_ptr = Arc::as_ptr(&x);\n    /// assert_eq!(x_ptr, Arc::as_ptr(&y));\n    /// assert_eq!(unsafe { &*x_ptr }, \"hello\");\n    /// ```\n    #[must_use]\n    pub fn as_ptr(this: &Self) -> *const T {\n        let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);\n\n        // SAFETY: This cannot go through Deref::deref or ArcInnerPtr::inner because\n        // this is required to retain raw/mut provenance such that e.g. `get_mut` can\n        // write through the pointer after the Arc is recovered through `from_raw`.\n        unsafe { data_ptr::<T>(ptr, &**this) }\n    }\n\n    /// Creates a new [`Weak`] pointer to this allocation.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// let weak_five = Arc::downgrade(&five);\n    /// ```\n    #[must_use = \"this returns a new `Weak` pointer, \\\n                  without modifying the original `Arc`\"]\n    #[allow(clippy::missing_panics_doc)]\n    pub fn downgrade(this: &Self) -> Weak<T> {\n        // This Relaxed is OK because we're checking the value in the CAS\n        // below.\n        let mut cur = this.inner().weak.load(Relaxed);\n\n        loop {\n            // check if the weak counter is currently \"locked\"; if so, spin.\n            if cur == USIZE_MAX {\n                hint::spin_loop();\n                cur = this.inner().weak.load(Relaxed);\n                continue;\n            }\n\n            // We can't allow the refcount to increase much past `MAX_REFCOUNT`.\n            assert!(cur <= MAX_REFCOUNT, \"{}\", INTERNAL_OVERFLOW_ERROR);\n\n            // NOTE: this code currently ignores the possibility of overflow\n            // into usize::MAX; in general both Rc and Arc need to be adjusted\n            // to deal with overflow.\n\n            // Unlike with Clone(), we need this to be an Acquire read to\n            // synchronize with the write coming from `is_unique`, so that the\n            // events prior to that write happen before this read.\n            match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acquire, Relaxed) {\n                Ok(_) => {\n                    // Make sure we do not create a dangling Weak\n                    debug_assert!(!is_dangling(this.ptr.as_ptr()));\n                    return Weak { ptr: this.ptr };\n                }\n                Err(old) => cur = old,\n            }\n        }\n    }\n\n    /// Gets the number of [`Weak`] pointers to this allocation.\n    ///\n    /// # Safety\n    ///\n    /// This method by itself is safe, but using it correctly requires extra care.\n    /// Another thread can change the weak count at any time,\n    /// including potentially between calling this method and acting on the result.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    /// let _weak_five = Arc::downgrade(&five);\n    ///\n    /// // This assertion is deterministic because we haven't shared\n    /// // the `Arc` or `Weak` between threads.\n    /// assert_eq!(1, Arc::weak_count(&five));\n    /// ```\n    #[inline]\n    #[must_use]\n    pub fn weak_count(this: &Self) -> usize {\n        let cnt = this.inner().weak.load(Relaxed);\n        // If the weak count is currently locked, the value of the\n        // count was 0 just before taking the lock.\n        if cnt == USIZE_MAX { 0 } else { cnt - 1 }\n    }\n\n    /// Gets the number of strong (`Arc`) pointers to this allocation.\n    ///\n    /// # Safety\n    ///\n    /// This method by itself is safe, but using it correctly requires extra care.\n    /// Another thread can change the strong count at any time,\n    /// including potentially between calling this method and acting on the result.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    /// let _also_five = Arc::clone(&five);\n    ///\n    /// // This assertion is deterministic because we haven't shared\n    /// // the `Arc` between threads.\n    /// assert_eq!(2, Arc::strong_count(&five));\n    /// ```\n    #[inline]\n    #[must_use]\n    pub fn strong_count(this: &Self) -> usize {\n        this.inner().strong.load(Relaxed)\n    }\n\n    #[inline]\n    fn inner(&self) -> &ArcInner<T> {\n        // This unsafety is ok because while this arc is alive we're guaranteed\n        // that the inner pointer is valid. Furthermore, we know that the\n        // `ArcInner` structure itself is `Sync` because the inner data is\n        // `Sync` as well, so we're ok loaning out an immutable pointer to these\n        // contents.\n        unsafe { self.ptr.as_ref() }\n    }\n\n    // Non-inlined part of `drop`.\n    #[inline(never)]\n    unsafe fn drop_slow(&mut self) {\n        // Drop the weak ref collectively held by all strong references when this\n        // variable goes out of scope. This ensures that the memory is deallocated\n        // even if the destructor of `T` panics.\n        // Take a reference to `self.alloc` instead of cloning because 1. it'll last long\n        // enough, and 2. you should be able to drop `Arc`s with unclonable allocators\n        let _weak = Weak { ptr: self.ptr };\n\n        // Destroy the data at this time, even though we must not free the box\n        // allocation itself (there might still be weak pointers lying around).\n        // We cannot use `get_mut_unchecked` here, because `self.alloc` is borrowed.\n        unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).data) }\n    }\n\n    /// Returns `true` if the two `Arc`s point to the same allocation in a vein similar to\n    /// [`ptr::eq`]. This function ignores the metadata of  `dyn Trait` pointers.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    /// let same_five = Arc::clone(&five);\n    /// let other_five = Arc::new(5);\n    ///\n    /// assert!(Arc::ptr_eq(&five, &same_five));\n    /// assert!(!Arc::ptr_eq(&five, &other_five));\n    /// ```\n    ///\n    /// [`ptr::eq`]: core::ptr::eq \"ptr::eq\"\n    #[inline]\n    #[must_use]\n    pub fn ptr_eq(this: &Self, other: &Self) -> bool {\n        ptr::eq(this.ptr.as_ptr() as *const (), other.ptr.as_ptr() as *const ())\n    }\n}\n\nimpl<T: ?Sized> Arc<T> {\n    /// Allocates an `ArcInner<T>` with sufficient space for\n    /// a possibly-unsized inner value where the value has the layout provided.\n    ///\n    /// The function `mem_to_arc_inner` is called with the data pointer\n    /// and must return back a (potentially fat)-pointer for the `ArcInner<T>`.\n    unsafe fn allocate_for_layout(\n        value_layout: Layout,\n        allocate: impl FnOnce(Layout) -> Option<NonNull<u8>>,\n        mem_to_arc_inner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,\n    ) -> *mut ArcInner<T> {\n        let layout = arc_inner_layout_for_value_layout(value_layout);\n\n        let ptr = allocate(layout).unwrap_or_else(|| handle_alloc_error(layout));\n\n        unsafe { Self::initialize_arc_inner(ptr, layout, mem_to_arc_inner) }\n    }\n\n    unsafe fn initialize_arc_inner(\n        ptr: NonNull<u8>,\n        _layout: Layout,\n        mem_to_arc_inner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,\n    ) -> *mut ArcInner<T> {\n        let inner: *mut ArcInner<T> = mem_to_arc_inner(ptr.as_ptr());\n        // debug_assert_eq!(unsafe { Layout::for_value_raw(inner) }, layout); // for_value_raw is unstable\n\n        // SAFETY: mem_to_arc_inner return a valid pointer to uninitialized ArcInner<T>.\n        // ArcInner<T> is repr(C), and strong and weak are the first and second fields and\n        // are the same type, so `inner as *mut atomic::AtomicUsize` is strong and\n        // `(inner as *mut atomic::AtomicUsize).add(1)` is weak.\n        unsafe {\n            let strong = inner as *mut atomic::AtomicUsize;\n            strong.write(atomic::AtomicUsize::new(1));\n            let weak = strong.add(1);\n            weak.write(atomic::AtomicUsize::new(1));\n        }\n\n        inner\n    }\n}\n\nimpl<T: ?Sized> Arc<T> {\n    /// Allocates an `ArcInner<T>` with sufficient space for an unsized inner value.\n    #[inline]\n    unsafe fn allocate_for_value(value: &T) -> *mut ArcInner<T> {\n        let ptr: *const T = value;\n        // Allocate for the `ArcInner<T>` using the given value.\n        unsafe {\n            Self::allocate_for_layout(\n                Layout::for_value(value),\n                |layout| Global.allocate(layout),\n                |mem| strict::with_metadata_of(mem, ptr as *const ArcInner<T>),\n            )\n        }\n    }\n\n    fn from_box(src: Box<T>) -> Arc<T> {\n        unsafe {\n            let value_size = mem::size_of_val(&*src);\n            let ptr = Self::allocate_for_value(&*src);\n\n            // Copy value as bytes\n            ptr::copy_nonoverlapping(\n                &*src as *const T as *const u8,\n                data_ptr::<T>(ptr, &*src) as *mut u8,\n                value_size,\n            );\n\n            // Free the allocation without dropping its contents\n            let box_ptr = Box::into_raw(src);\n            let src = Box::from_raw(box_ptr as *mut mem::ManuallyDrop<T>);\n            drop(src);\n\n            Self::from_ptr(ptr)\n        }\n    }\n}\n\nimpl<T> Arc<[T]> {\n    /// Allocates an `ArcInner<[mem::MaybeUninit<T>]>` with the given length.\n    unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[mem::MaybeUninit<T>]> {\n        unsafe {\n            Arc::allocate_for_layout(\n                layout::array::<T>(len).unwrap(),\n                |layout| Global.allocate(layout),\n                |mem| {\n                    // We create a slice just for metadata (we must use `[mem::MaybeUninit<T>]`\n                    // instead of `[T]` because values behind `mem` is not valid initialized `T`s.\n                    // there is no size/alignment issue thanks to layout::array), and create a\n                    // pointer from `mem` and slice's metadata.\n                    //\n                    // We cannot use other ways here:\n                    // - ptr::slice_from_raw_parts_mut is best way here, but requires Rust 1.42.\n                    // - We cannot use slice::from_raw_parts_mut then casting to its pointer to\n                    //   ArcInner due to provenance because the actual size of valid allocation\n                    //   behind `mem` is `layout.size()` bytes (counters + values + padding) but the\n                    //   allocation from the pointer from slice::from_raw_parts_mut only valid for\n                    //   `size_of::<T> * len` bytes (only values).\n                    let meta: *const _ =\n                        slice::from_raw_parts(mem as *const mem::MaybeUninit<T>, len);\n                    strict::with_metadata_of(mem, meta) as *mut ArcInner<[mem::MaybeUninit<T>]>\n                },\n            )\n        }\n    }\n\n    /// Constructs an `Arc<[T]>` from an iterator known to be of a certain size.\n    ///\n    /// Behavior is undefined should the size be wrong.\n    unsafe fn from_iter_exact(iter: impl Iterator<Item = T>, len: usize) -> Self {\n        // Panic guard while cloning T elements.\n        // In the event of a panic, elements that have been written\n        // into the new ArcInner will be dropped, then the memory freed.\n        struct Guard<T> {\n            mem: NonNull<u8>,\n            elems: *mut T,\n            layout: Layout,\n            n_elems: usize,\n        }\n\n        impl<T> Drop for Guard<T> {\n            fn drop(&mut self) {\n                unsafe {\n                    let slice = slice::from_raw_parts_mut(self.elems, self.n_elems);\n                    ptr::drop_in_place(slice);\n\n                    Global.deallocate(self.mem, self.layout);\n                }\n            }\n        }\n\n        unsafe {\n            let ptr: *mut ArcInner<[mem::MaybeUninit<T>]> = Arc::allocate_for_slice(len);\n\n            let mem = ptr as *mut _ as *mut u8;\n            let layout = Layout::for_value(&*ptr);\n\n            // Pointer to first element\n            let elems = (*ptr).data.as_mut_ptr() as *mut T;\n\n            let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 };\n\n            for (i, item) in iter.enumerate() {\n                ptr::write(elems.add(i), item);\n                guard.n_elems += 1;\n            }\n\n            // All clear. Forget the guard so it doesn't free the new ArcInner.\n            mem::forget(guard);\n\n            Arc::from_ptr(ptr).assume_init()\n        }\n    }\n}\n\nimpl<T: ?Sized> Clone for Arc<T> {\n    /// Makes a clone of the `Arc` pointer.\n    ///\n    /// This creates another pointer to the same allocation, increasing the\n    /// strong reference count.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// let _ = Arc::clone(&five);\n    /// ```\n    #[inline]\n    fn clone(&self) -> Self {\n        // Using a relaxed ordering is alright here, as knowledge of the\n        // original reference prevents other threads from erroneously deleting\n        // the object.\n        //\n        // As explained in the [Boost documentation][1], Increasing the\n        // reference counter can always be done with memory_order_relaxed: New\n        // references to an object can only be formed from an existing\n        // reference, and passing an existing reference from one thread to\n        // another must already provide any required synchronization.\n        //\n        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)\n        let old_size = self.inner().strong.fetch_add(1, Relaxed);\n\n        // However we need to guard against massive refcounts in case someone is `mem::forget`ing\n        // Arcs. If we don't do this the count can overflow and users will use-after free. This\n        // branch will never be taken in any realistic program. We abort because such a program is\n        // incredibly degenerate, and we don't care to support it.\n        //\n        // This check is not 100% water-proof: we error when the refcount grows beyond `isize::MAX`.\n        // But we do that check *after* having done the increment, so there is a chance here that\n        // the worst already happened and we actually do overflow the `usize` counter. However, that\n        // requires the counter to grow from `isize::MAX` to `usize::MAX` between the increment\n        // above and the `abort` below, which seems exceedingly unlikely.\n        //\n        // This is a global invariant, and also applies when using a compare-exchange loop to increment\n        // counters in other methods.\n        // Otherwise, the counter could be brought to an almost-overflow using a compare-exchange loop,\n        // and then overflow using a few `fetch_add`s.\n        if old_size > MAX_REFCOUNT {\n            abort();\n        }\n\n        unsafe { Self::from_inner(self.ptr) }\n    }\n}\n\nimpl<T: ?Sized> Deref for Arc<T> {\n    type Target = T;\n\n    #[inline]\n    fn deref(&self) -> &Self::Target {\n        &self.inner().data\n    }\n}\n\nimpl<T: ?Sized + CloneToUninit> Arc<T> {\n    /// Makes a mutable reference into the given `Arc`.\n    ///\n    /// If there are other `Arc` pointers to the same allocation, then `make_mut` will\n    /// [`clone`] the inner value to a new allocation to ensure unique ownership.  This is also\n    /// referred to as clone-on-write.\n    ///\n    /// However, if there are no other `Arc` pointers to this allocation, but some [`Weak`]\n    /// pointers, then the [`Weak`] pointers will be dissociated and the inner value will not\n    /// be cloned.\n    ///\n    /// See also [`get_mut`], which will fail rather than cloning the inner value\n    /// or dissociating [`Weak`] pointers.\n    ///\n    /// [`clone`]: Clone::clone\n    /// [`get_mut`]: Arc::get_mut\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let mut data = Arc::new(5);\n    ///\n    /// *Arc::make_mut(&mut data) += 1; // Won't clone anything\n    /// let mut other_data = Arc::clone(&data); // Won't clone inner data\n    /// *Arc::make_mut(&mut data) += 1; // Clones inner data\n    /// *Arc::make_mut(&mut data) += 1; // Won't clone anything\n    /// *Arc::make_mut(&mut other_data) *= 2; // Won't clone anything\n    ///\n    /// // Now `data` and `other_data` point to different allocations.\n    /// assert_eq!(*data, 8);\n    /// assert_eq!(*other_data, 12);\n    /// ```\n    ///\n    /// [`Weak`] pointers will be dissociated:\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let mut data = Arc::new(75);\n    /// let weak = Arc::downgrade(&data);\n    ///\n    /// assert_eq!(75, *data);\n    /// assert_eq!(75, *weak.upgrade().unwrap());\n    ///\n    /// *Arc::make_mut(&mut data) += 1;\n    ///\n    /// assert_eq!(76, *data);\n    /// assert!(weak.upgrade().is_none());\n    /// ```\n    #[inline]\n    pub fn make_mut(this: &mut Self) -> &mut T {\n        let size_of_val = mem::size_of_val::<T>(&**this);\n\n        // Note that we hold both a strong reference and a weak reference.\n        // Thus, releasing our strong reference only will not, by itself, cause\n        // the memory to be deallocated.\n        //\n        // Use Acquire to ensure that we see any writes to `weak` that happen\n        // before release writes (i.e., decrements) to `strong`. Since we hold a\n        // weak count, there's no chance the ArcInner itself could be\n        // deallocated.\n        if this.inner().strong.compare_exchange(1, 0, Acquire, Relaxed).is_err() {\n            // Another strong pointer exists, so we must clone.\n            *this = Arc::clone_from_ref(&**this);\n        } else if this.inner().weak.load(Relaxed) != 1 {\n            // Relaxed suffices in the above because this is fundamentally an\n            // optimization: we are always racing with weak pointers being\n            // dropped. Worst case, we end up allocated a new Arc unnecessarily.\n\n            // We removed the last strong ref, but there are additional weak\n            // refs remaining. We'll move the contents to a new Arc, and\n            // invalidate the other weak refs.\n\n            // Note that it is not possible for the read of `weak` to yield\n            // usize::MAX (i.e., locked), since the weak count can only be\n            // locked by a thread with a strong reference.\n\n            // Materialize our own implicit weak pointer, so that it can clean\n            // up the ArcInner as needed.\n            let _weak = Weak { ptr: this.ptr };\n\n            // Can just steal the data, all that's left is `Weak`s\n            //\n            // We don't need panic-protection like the above branch does, but we might as well\n            // use the same mechanism.\n            let mut in_progress: UniqueArcUninit<T> = UniqueArcUninit::new(&**this);\n            unsafe {\n                // Initialize `in_progress` with move of **this.\n                // We have to express this in terms of bytes because `T: ?Sized`; there is no\n                // operation that just copies a value based on its `size_of_val()`.\n                ptr::copy_nonoverlapping(\n                    &**this as *const T as *const u8,\n                    in_progress.data_ptr() as *mut u8,\n                    size_of_val,\n                );\n\n                ptr::write(this, in_progress.into_arc());\n            }\n        } else {\n            // We were the sole reference of either kind; bump back up the\n            // strong ref count.\n            this.inner().strong.store(1, Release);\n        }\n\n        // As with `get_mut()`, the unsafety is ok because our reference was\n        // either unique to begin with, or became one upon cloning the contents.\n        unsafe { Self::get_mut_unchecked(this) }\n    }\n}\n\nimpl<T: Clone> Arc<T> {\n    /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the\n    /// clone.\n    ///\n    /// Assuming `arc_t` is of type `Arc<T>`, this function is functionally equivalent to\n    /// `(*arc_t).clone()`, but will avoid cloning the inner value where possible.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use std::ptr;\n    ///\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let inner = String::from(\"test\");\n    /// let ptr = inner.as_ptr();\n    ///\n    /// let arc = Arc::new(inner);\n    /// let inner = Arc::unwrap_or_clone(arc);\n    /// // The inner value was not cloned\n    /// assert!(ptr::eq(ptr, inner.as_ptr()));\n    ///\n    /// let arc = Arc::new(inner);\n    /// let arc2 = arc.clone();\n    /// let inner = Arc::unwrap_or_clone(arc);\n    /// // Because there were 2 references, we had to clone the inner value.\n    /// assert!(!ptr::eq(ptr, inner.as_ptr()));\n    /// // `arc2` is the last reference, so when we unwrap it we get back\n    /// // the original `String`.\n    /// let inner = Arc::unwrap_or_clone(arc2);\n    /// assert!(ptr::eq(ptr, inner.as_ptr()));\n    /// ```\n    #[inline]\n    pub fn unwrap_or_clone(this: Self) -> T {\n        Self::try_unwrap(this).unwrap_or_else(|arc| (*arc).clone())\n    }\n}\n\nimpl<T: ?Sized> Arc<T> {\n    /// Returns a mutable reference into the given `Arc`, if there are\n    /// no other `Arc` or [`Weak`] pointers to the same allocation.\n    ///\n    /// Returns [`None`] otherwise, because it is not safe to\n    /// mutate a shared value.\n    ///\n    /// See also [`make_mut`][make_mut], which will [`clone`][clone]\n    /// the inner value when there are other `Arc` pointers.\n    ///\n    /// [make_mut]: Arc::make_mut\n    /// [clone]: Clone::clone\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let mut x = Arc::new(3);\n    /// *Arc::get_mut(&mut x).unwrap() = 4;\n    /// assert_eq!(*x, 4);\n    ///\n    /// let _y = Arc::clone(&x);\n    /// assert!(Arc::get_mut(&mut x).is_none());\n    /// ```\n    #[inline]\n    pub fn get_mut(this: &mut Self) -> Option<&mut T> {\n        if Self::is_unique(this) {\n            // This unsafety is ok because we're guaranteed that the pointer\n            // returned is the *only* pointer that will ever be returned to T. Our\n            // reference count is guaranteed to be 1 at this point, and we required\n            // the Arc itself to be `mut`, so we're returning the only possible\n            // reference to the inner data.\n            unsafe { Some(Self::get_mut_unchecked(this)) }\n        } else {\n            None\n        }\n    }\n\n    #[inline]\n    unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {\n        // We are careful to *not* create a reference covering the \"count\" fields, as\n        // this would alias with concurrent access to the reference counts (e.g. by `Weak`).\n        unsafe { &mut (*this.ptr.as_ptr()).data }\n    }\n\n    #[inline]\n    fn is_unique(this: &Self) -> bool {\n        // lock the weak pointer count if we appear to be the sole weak pointer\n        // holder.\n        //\n        // The acquire label here ensures a happens-before relationship with any\n        // writes to `strong` (in particular in `Weak::upgrade`) prior to decrements\n        // of the `weak` count (via `Weak::drop`, which uses release). If the upgraded\n        // weak ref was never dropped, the CAS here will fail so we do not care to synchronize.\n        if this.inner().weak.compare_exchange(1, USIZE_MAX, Acquire, Relaxed).is_ok() {\n            // This needs to be an `Acquire` to synchronize with the decrement of the `strong`\n            // counter in `drop` -- the only access that happens when any but the last reference\n            // is being dropped.\n            let unique = this.inner().strong.load(Acquire) == 1;\n\n            // The release write here synchronizes with a read in `downgrade`,\n            // effectively preventing the above read of `strong` from happening\n            // after the write.\n            this.inner().weak.store(1, Release); // release the lock\n            unique\n        } else {\n            false\n        }\n    }\n}\n\nimpl<T: ?Sized> Drop for Arc<T> {\n    /// Drops the `Arc`.\n    ///\n    /// This will decrement the strong reference count. If the strong reference\n    /// count reaches zero then the only other references (if any) are\n    /// [`Weak`], so we `drop` the inner value.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// struct Foo;\n    ///\n    /// impl Drop for Foo {\n    ///     fn drop(&mut self) {\n    ///         println!(\"dropped!\");\n    ///     }\n    /// }\n    ///\n    /// let foo = Arc::new(Foo);\n    /// let foo2 = Arc::clone(&foo);\n    ///\n    /// drop(foo); // Doesn't print anything\n    /// drop(foo2); // Prints \"dropped!\"\n    /// ```\n    #[inline]\n    fn drop(&mut self) {\n        // Because `fetch_sub` is already atomic, we do not need to synchronize\n        // with other threads unless we are going to delete the object. This\n        // same logic applies to the below `fetch_sub` to the `weak` count.\n        if self.inner().strong.fetch_sub(1, Release) != 1 {\n            return;\n        }\n\n        // This fence is needed to prevent reordering of use of the data and\n        // deletion of the data. Because it is marked `Release`, the decreasing\n        // of the reference count synchronizes with this `Acquire` fence. This\n        // means that use of the data happens before decreasing the reference\n        // count, which happens before this fence, which happens before the\n        // deletion of the data.\n        //\n        // As explained in the [Boost documentation][1],\n        //\n        // > It is important to enforce any possible access to the object in one\n        // > thread (through an existing reference) to *happen before* deleting\n        // > the object in a different thread. This is achieved by a \"release\"\n        // > operation after dropping a reference (any access to the object\n        // > through this reference must obviously happened before), and an\n        // > \"acquire\" operation before deleting the object.\n        //\n        // In particular, while the contents of an Arc are usually immutable, it's\n        // possible to have interior writes to something like a Mutex<T>. Since a\n        // Mutex is not acquired when it is deleted, we can't rely on its\n        // synchronization logic to make writes in thread A visible to a destructor\n        // running in thread B.\n        //\n        // Also note that the Acquire fence here could probably be replaced with an\n        // Acquire load, which could improve performance in highly-contended\n        // situations. See [2].\n        //\n        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)\n        // [2]: (https://github.com/rust-lang/rust/pull/41714)\n        acquire!(self.inner().strong);\n\n        unsafe {\n            self.drop_slow();\n        }\n    }\n}\n\nimpl Arc<dyn Any + Send + Sync> {\n    /// Attempts to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use std::any::Any;\n    ///\n    /// use portable_atomic_util::Arc;\n    ///\n    /// fn print_if_string(value: Arc<dyn Any + Send + Sync>) {\n    ///     if let Ok(string) = value.downcast::<String>() {\n    ///         println!(\"String ({}): {}\", string.len(), string);\n    ///     }\n    /// }\n    ///\n    /// let my_string = \"Hello World\".to_string();\n    /// print_if_string(Arc::from(Box::new(my_string) as Box<dyn Any + Send + Sync>));\n    /// print_if_string(Arc::from(Box::new(0i8) as Box<dyn Any + Send + Sync>));\n    /// // or with \"--cfg portable_atomic_unstable_coerce_unsized\" in RUSTFLAGS (requires Rust nightly):\n    /// // print_if_string(Arc::new(my_string));\n    /// // print_if_string(Arc::new(0i8));\n    /// ```\n    #[inline]\n    pub fn downcast<T>(self) -> Result<Arc<T>, Self>\n    where\n        T: Any + Send + Sync,\n    {\n        if (*self).is::<T>() {\n            unsafe {\n                let ptr = Arc::into_inner_non_null(self);\n                Ok(Arc::from_inner(ptr.cast::<ArcInner<T>>()))\n            }\n        } else {\n            Err(self)\n        }\n    }\n}\n\nimpl<T> Weak<T> {\n    /// Constructs a new `Weak<T>`, without allocating any memory.\n    /// Calling [`upgrade`] on the return value always gives [`None`].\n    ///\n    /// [`upgrade`]: Weak::upgrade\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Weak;\n    ///\n    /// let empty: Weak<i64> = Weak::new();\n    /// assert!(empty.upgrade().is_none());\n    /// ```\n    #[inline]\n    #[must_use]\n    pub const fn new() -> Self {\n        Self {\n            ptr: unsafe {\n                NonNull::new_unchecked(strict::without_provenance_mut::<ArcInner<T>>(USIZE_MAX))\n            },\n        }\n    }\n\n    #[inline]\n    #[must_use]\n    fn new_uninit_ptr() -> NonNull<ArcInner<T>> {\n        unsafe {\n            NonNull::new_unchecked(Self::allocate_for_layout(\n                Layout::new::<T>(),\n                |layout| Global.allocate(layout),\n                |ptr| ptr as *mut _,\n            ))\n        }\n    }\n}\n\n/// Helper type to allow accessing the reference counts without\n/// making any assertions about the data field.\nstruct WeakInner<'a> {\n    weak: &'a atomic::AtomicUsize,\n    strong: &'a atomic::AtomicUsize,\n}\n\n// TODO: See todo comment in Weak::from_raw\nimpl<T /*: ?Sized */> Weak<T> {\n    /// Converts a raw pointer previously created by [`into_raw`] back into `Weak<T>`.\n    ///\n    /// This can be used to safely get a strong reference (by calling [`upgrade`]\n    /// later) or to deallocate the weak count by dropping the `Weak<T>`.\n    ///\n    /// It takes ownership of one weak reference (with the exception of pointers created by [`new`],\n    /// as these don't own anything; the method still works on them).\n    ///\n    /// # Safety\n    ///\n    /// The pointer must have originated from the [`into_raw`] and must still own its potential\n    /// weak reference, and must point to a block of memory allocated by global allocator.\n    ///\n    /// It is allowed for the strong count to be 0 at the time of calling this. Nevertheless, this\n    /// takes ownership of one weak reference currently represented as a raw pointer (the weak\n    /// count is not modified by this operation) and therefore it must be paired with a previous\n    /// call to [`into_raw`].\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::{Arc, Weak};\n    ///\n    /// let strong = Arc::new(\"hello\".to_owned());\n    ///\n    /// let raw_1 = Arc::downgrade(&strong).into_raw();\n    /// let raw_2 = Arc::downgrade(&strong).into_raw();\n    ///\n    /// assert_eq!(2, Arc::weak_count(&strong));\n    ///\n    /// assert_eq!(\"hello\", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap());\n    /// assert_eq!(1, Arc::weak_count(&strong));\n    ///\n    /// drop(strong);\n    ///\n    /// // Decrement the last weak count.\n    /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());\n    /// ```\n    ///\n    /// [`new`]: Weak::new\n    /// [`into_raw`]: Weak::into_raw\n    /// [`upgrade`]: Weak::upgrade\n    #[inline]\n    pub unsafe fn from_raw(ptr: *const T) -> Self {\n        // See Weak::as_ptr for context on how the input pointer is derived.\n\n        let ptr = if is_dangling(ptr) {\n            // This is a dangling Weak.\n            ptr as *mut ArcInner<T>\n        } else {\n            // Otherwise, we're guaranteed the pointer came from a non-dangling Weak.\n            // TODO: data_offset calls align_of_val which needs to create a reference\n            // to data but we cannot create a reference to data here since data in Weak\n            // can be dropped concurrently from another thread. Therefore, we can\n            // only support sized types that can avoid references to data\n            // unless align_of_val_raw is stabilized.\n            // // SAFETY: data_offset is safe to call, as ptr references a real (potentially dropped) T.\n            // let offset = unsafe { data_offset(ptr) };\n            let offset = data_offset_align(mem::align_of::<T>());\n            // Thus, we reverse the offset to get the whole ArcInner.\n            // SAFETY: the pointer originated from a Weak, so this offset is safe.\n            unsafe { strict::byte_sub(ptr as *mut T, offset) as *mut ArcInner<T> }\n        };\n\n        // SAFETY: we now have recovered the original Weak pointer, so can create the Weak.\n        Self { ptr: unsafe { NonNull::new_unchecked(ptr) } }\n    }\n\n    /// Consumes the `Weak<T>` and turns it into a raw pointer.\n    ///\n    /// This converts the weak pointer into a raw pointer, while still preserving the ownership of\n    /// one weak reference (the weak count is not modified by this operation). It can be turned\n    /// back into the `Weak<T>` with [`from_raw`].\n    ///\n    /// The same restrictions of accessing the target of the pointer as with\n    /// [`as_ptr`] apply.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::{Arc, Weak};\n    ///\n    /// let strong = Arc::new(\"hello\".to_owned());\n    /// let weak = Arc::downgrade(&strong);\n    /// let raw = weak.into_raw();\n    ///\n    /// assert_eq!(1, Arc::weak_count(&strong));\n    /// assert_eq!(\"hello\", unsafe { &*raw });\n    ///\n    /// drop(unsafe { Weak::from_raw(raw) });\n    /// assert_eq!(0, Arc::weak_count(&strong));\n    /// ```\n    ///\n    /// [`from_raw`]: Weak::from_raw\n    /// [`as_ptr`]: Weak::as_ptr\n    #[must_use = \"losing the pointer will leak memory\"]\n    pub fn into_raw(self) -> *const T {\n        ManuallyDrop::new(self).as_ptr()\n    }\n}\n\n// TODO: See todo comment in Weak::from_raw\nimpl<T /*: ?Sized */> Weak<T> {\n    /// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.\n    ///\n    /// The pointer is valid only if there are some strong references. The pointer may be dangling,\n    /// unaligned or even [`null`] otherwise.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use std::ptr;\n    ///\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let strong = Arc::new(\"hello\".to_owned());\n    /// let weak = Arc::downgrade(&strong);\n    /// // Both point to the same object\n    /// assert!(ptr::eq(&*strong, weak.as_ptr()));\n    /// // The strong here keeps it alive, so we can still access the object.\n    /// assert_eq!(\"hello\", unsafe { &*weak.as_ptr() });\n    ///\n    /// drop(strong);\n    /// // But not any more. We can do weak.as_ptr(), but accessing the pointer would lead to\n    /// // undefined behavior.\n    /// // assert_eq!(\"hello\", unsafe { &*weak.as_ptr() });\n    /// ```\n    ///\n    /// [`null`]: core::ptr::null \"ptr::null\"\n    #[must_use]\n    pub fn as_ptr(&self) -> *const T {\n        let ptr: *mut ArcInner<T> = NonNull::as_ptr(self.ptr);\n\n        if is_dangling(ptr) {\n            // If the pointer is dangling, we return the sentinel directly. This cannot be\n            // a valid payload address, as the payload is at least as aligned as ArcInner (usize).\n            ptr as *const T\n        } else {\n            // TODO: See todo comment in Weak::from_raw\n            // // SAFETY: if is_dangling returns false, then the pointer is dereferenceable.\n            // // The payload may be dropped at this point, and we have to maintain provenance,\n            // // so use raw pointer manipulation.\n            // unsafe { data_ptr::<T>(ptr, &(*ptr).data) }\n            unsafe {\n                let offset = data_offset_align(mem::align_of::<T>());\n                strict::byte_add(ptr, offset) as *const T\n            }\n        }\n    }\n}\n\nimpl<T: ?Sized> Weak<T> {\n    /// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying\n    /// dropping of the inner value if successful.\n    ///\n    /// Returns [`None`] if the inner value has since been dropped.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// let weak_five = Arc::downgrade(&five);\n    ///\n    /// let strong_five: Option<Arc<_>> = weak_five.upgrade();\n    /// assert!(strong_five.is_some());\n    ///\n    /// // Destroy all strong pointers.\n    /// drop(strong_five);\n    /// drop(five);\n    ///\n    /// assert!(weak_five.upgrade().is_none());\n    /// ```\n    #[must_use = \"this returns a new `Arc`, \\\n                  without modifying the original weak pointer\"]\n    pub fn upgrade(&self) -> Option<Arc<T>> {\n        #[inline]\n        fn checked_increment(n: usize) -> Option<usize> {\n            // Any write of 0 we can observe leaves the field in permanently zero state.\n            if n == 0 {\n                return None;\n            }\n            // See comments in `Arc::clone` for why we do this (for `mem::forget`).\n            assert!(n <= MAX_REFCOUNT, \"{}\", INTERNAL_OVERFLOW_ERROR);\n            Some(n + 1)\n        }\n\n        // We use a CAS loop to increment the strong count instead of a\n        // fetch_add as this function should never take the reference count\n        // from zero to one.\n        //\n        // Relaxed is fine for the failure case because we don't have any expectations about the new state.\n        // Acquire is necessary for the success case to synchronize with `Arc::new_cyclic`, when the inner\n        // value can be initialized after `Weak` references have already been created. In that case, we\n        // expect to observe the fully initialized value.\n        if self.inner()?.strong.fetch_update(Acquire, Relaxed, checked_increment).is_ok() {\n            // SAFETY: pointer is not null, verified in checked_increment\n            unsafe { Some(Arc::from_inner(self.ptr)) }\n        } else {\n            None\n        }\n    }\n\n    /// Gets the number of strong (`Arc`) pointers pointing to this allocation.\n    ///\n    /// If `self` was created using [`Weak::new`], this will return 0.\n    #[must_use]\n    pub fn strong_count(&self) -> usize {\n        if let Some(inner) = self.inner() { inner.strong.load(Relaxed) } else { 0 }\n    }\n\n    /// Gets an approximation of the number of `Weak` pointers pointing to this\n    /// allocation.\n    ///\n    /// If `self` was created using [`Weak::new`], or if there are no remaining\n    /// strong pointers, this will return 0.\n    ///\n    /// # Accuracy\n    ///\n    /// Due to implementation details, the returned value can be off by 1 in\n    /// either direction when other threads are manipulating any `Arc`s or\n    /// `Weak`s pointing to the same allocation.\n    #[must_use]\n    pub fn weak_count(&self) -> usize {\n        if let Some(inner) = self.inner() {\n            let weak = inner.weak.load(Acquire);\n            let strong = inner.strong.load(Relaxed);\n            if strong == 0 {\n                0\n            } else {\n                // Since we observed that there was at least one strong pointer\n                // after reading the weak count, we know that the implicit weak\n                // reference (present whenever any strong references are alive)\n                // was still around when we observed the weak count, and can\n                // therefore safely subtract it.\n                weak - 1\n            }\n        } else {\n            0\n        }\n    }\n\n    /// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,\n    /// (i.e., when this `Weak` was created by `Weak::new`).\n    #[inline]\n    fn inner(&self) -> Option<WeakInner<'_>> {\n        let ptr = self.ptr.as_ptr();\n        if is_dangling(ptr) {\n            None\n        } else {\n            // SAFETY: non-dangling Weak has a valid pointer.\n            // We are careful to *not* create a reference covering the \"data\" field, as\n            // the field may be mutated concurrently (for example, if the last `Arc`\n            // is dropped, the data field will be dropped in-place).\n            Some(unsafe { WeakInner { strong: &(*ptr).strong, weak: &(*ptr).weak } })\n        }\n    }\n\n    /// Returns `true` if the two `Weak`s point to the same allocation similar to [`ptr::eq`], or if\n    /// both don't point to any allocation (because they were created with `Weak::new()`). However,\n    /// this function ignores the metadata of  `dyn Trait` pointers.\n    ///\n    /// # Notes\n    ///\n    /// Since this compares pointers it means that `Weak::new()` will equal each\n    /// other, even though they don't point to any allocation.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let first_rc = Arc::new(5);\n    /// let first = Arc::downgrade(&first_rc);\n    /// let second = Arc::downgrade(&first_rc);\n    ///\n    /// assert!(first.ptr_eq(&second));\n    ///\n    /// let third_rc = Arc::new(5);\n    /// let third = Arc::downgrade(&third_rc);\n    ///\n    /// assert!(!first.ptr_eq(&third));\n    /// ```\n    ///\n    /// Comparing `Weak::new`.\n    ///\n    /// ```\n    /// use portable_atomic_util::{Arc, Weak};\n    ///\n    /// let first = Weak::new();\n    /// let second = Weak::new();\n    /// assert!(first.ptr_eq(&second));\n    ///\n    /// let third_rc = Arc::new(());\n    /// let third = Arc::downgrade(&third_rc);\n    /// assert!(!first.ptr_eq(&third));\n    /// ```\n    ///\n    /// [`ptr::eq`]: core::ptr::eq \"ptr::eq\"\n    #[inline]\n    #[must_use]\n    pub fn ptr_eq(&self, other: &Self) -> bool {\n        ptr::eq(self.ptr.as_ptr() as *const (), other.ptr.as_ptr() as *const ())\n    }\n}\n\nimpl<T: ?Sized> Weak<T> {\n    /// Allocates an `ArcInner<T>` with sufficient space for\n    /// a possibly-unsized inner value where the value has the layout provided.\n    ///\n    /// The function `mem_to_arc_inner` is called with the data pointer\n    /// and must return back a (potentially fat)-pointer for the `ArcInner<T>`.\n    unsafe fn allocate_for_layout(\n        value_layout: Layout,\n        allocate: impl FnOnce(Layout) -> Option<NonNull<u8>>,\n        mem_to_arc_inner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,\n    ) -> *mut ArcInner<T> {\n        let layout = arc_inner_layout_for_value_layout(value_layout);\n\n        let ptr = allocate(layout).unwrap_or_else(|| handle_alloc_error(layout));\n\n        unsafe { Self::initialize_arc_inner(ptr, layout, mem_to_arc_inner) }\n    }\n\n    unsafe fn initialize_arc_inner(\n        ptr: NonNull<u8>,\n        _layout: Layout,\n        mem_to_arc_inner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,\n    ) -> *mut ArcInner<T> {\n        let inner: *mut ArcInner<T> = mem_to_arc_inner(ptr.as_ptr());\n        // debug_assert_eq!(unsafe { Layout::for_value_raw(inner) }, layout); // for_value_raw is unstable\n\n        // SAFETY: mem_to_arc_inner return a valid pointer to uninitialized ArcInner<T>.\n        // ArcInner<T> is repr(C), and strong and weak are the first and second fields and\n        // are the same type, so `inner as *mut atomic::AtomicUsize` is strong and\n        // `(inner as *mut atomic::AtomicUsize).add(1)` is weak.\n        unsafe {\n            let strong = inner as *mut atomic::AtomicUsize;\n            strong.write(atomic::AtomicUsize::new(0));\n            let weak = strong.add(1);\n            weak.write(atomic::AtomicUsize::new(1));\n        }\n\n        inner\n    }\n}\n\nimpl<T: ?Sized> Clone for Weak<T> {\n    /// Makes a clone of the `Weak` pointer that points to the same allocation.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::{Arc, Weak};\n    ///\n    /// let weak_five = Arc::downgrade(&Arc::new(5));\n    ///\n    /// let _ = Weak::clone(&weak_five);\n    /// ```\n    #[inline]\n    fn clone(&self) -> Self {\n        if let Some(inner) = self.inner() {\n            // See comments in Arc::clone() for why this is relaxed. This can use a\n            // fetch_add (ignoring the lock) because the weak count is only locked\n            // where are *no other* weak pointers in existence. (So we can't be\n            // running this code in that case).\n            let old_size = inner.weak.fetch_add(1, Relaxed);\n\n            // See comments in Arc::clone() for why we do this (for mem::forget).\n            if old_size > MAX_REFCOUNT {\n                abort();\n            }\n        }\n\n        Self { ptr: self.ptr }\n    }\n}\n\nimpl<T> Default for Weak<T> {\n    /// Constructs a new `Weak<T>`, without allocating memory.\n    /// Calling [`upgrade`] on the return value always\n    /// gives [`None`].\n    ///\n    /// [`upgrade`]: Weak::upgrade\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Weak;\n    ///\n    /// let empty: Weak<i64> = Weak::default();\n    /// assert!(empty.upgrade().is_none());\n    /// ```\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl<T: ?Sized> Drop for Weak<T> {\n    /// Drops the `Weak` pointer.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::{Arc, Weak};\n    ///\n    /// struct Foo;\n    ///\n    /// impl Drop for Foo {\n    ///     fn drop(&mut self) {\n    ///         println!(\"dropped!\");\n    ///     }\n    /// }\n    ///\n    /// let foo = Arc::new(Foo);\n    /// let weak_foo = Arc::downgrade(&foo);\n    /// let other_weak_foo = Weak::clone(&weak_foo);\n    ///\n    /// drop(weak_foo); // Doesn't print anything\n    /// drop(foo); // Prints \"dropped!\"\n    ///\n    /// assert!(other_weak_foo.upgrade().is_none());\n    /// ```\n    fn drop(&mut self) {\n        // If we find out that we were the last weak pointer, then its time to\n        // deallocate the data entirely. See the discussion in Arc::drop() about\n        // the memory orderings\n        //\n        // It's not necessary to check for the locked state here, because the\n        // weak count can only be locked if there was precisely one weak ref,\n        // meaning that drop could only subsequently run ON that remaining weak\n        // ref, which can only happen after the lock is released.\n        let inner = if let Some(inner) = self.inner() { inner } else { return };\n\n        if inner.weak.fetch_sub(1, Release) == 1 {\n            acquire!(inner.weak);\n            // Free the allocation without dropping T\n            let ptr = self.ptr.as_ptr() as *mut ArcInner<mem::ManuallyDrop<T>>;\n            drop(unsafe { Box::from_raw(ptr) });\n        }\n    }\n}\n\nimpl<T: ?Sized + PartialEq> PartialEq for Arc<T> {\n    /// Equality for two `Arc`s.\n    ///\n    /// Two `Arc`s are equal if their inner values are equal, even if they are\n    /// stored in different allocation.\n    ///\n    /// If `T` also implements `Eq` (implying reflexivity of equality),\n    /// two `Arc`s that point to the same allocation are always equal.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// assert_eq!(five, Arc::new(5));\n    /// ```\n    #[inline]\n    fn eq(&self, other: &Self) -> bool {\n        **self == **other\n    }\n\n    /// Inequality for two `Arc`s.\n    ///\n    /// Two `Arc`s are not equal if their inner values are not equal.\n    ///\n    /// If `T` also implements `Eq` (implying reflexivity of equality),\n    /// two `Arc`s that point to the same value are always equal.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// assert_ne!(five, Arc::new(6));\n    /// ```\n    #[allow(clippy::partialeq_ne_impl)]\n    #[inline]\n    fn ne(&self, other: &Self) -> bool {\n        **self != **other\n    }\n}\n\nimpl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {\n    /// Partial comparison for two `Arc`s.\n    ///\n    /// The two are compared by calling `partial_cmp()` on their inner values.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use std::cmp::Ordering;\n    ///\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Arc::new(6)));\n    /// ```\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        (**self).partial_cmp(&**other)\n    }\n\n    /// Less-than comparison for two `Arc`s.\n    ///\n    /// The two are compared by calling `<` on their inner values.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// assert!(five < Arc::new(6));\n    /// ```\n    fn lt(&self, other: &Self) -> bool {\n        *(*self) < *(*other)\n    }\n\n    /// 'Less than or equal to' comparison for two `Arc`s.\n    ///\n    /// The two are compared by calling `<=` on their inner values.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// assert!(five <= Arc::new(5));\n    /// ```\n    fn le(&self, other: &Self) -> bool {\n        *(*self) <= *(*other)\n    }\n\n    /// Greater-than comparison for two `Arc`s.\n    ///\n    /// The two are compared by calling `>` on their inner values.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// assert!(five > Arc::new(4));\n    /// ```\n    fn gt(&self, other: &Self) -> bool {\n        *(*self) > *(*other)\n    }\n\n    /// 'Greater than or equal to' comparison for two `Arc`s.\n    ///\n    /// The two are compared by calling `>=` on their inner values.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// assert!(five >= Arc::new(5));\n    /// ```\n    fn ge(&self, other: &Self) -> bool {\n        *(*self) >= *(*other)\n    }\n}\nimpl<T: ?Sized + Ord> Ord for Arc<T> {\n    /// Comparison for two `Arc`s.\n    ///\n    /// The two are compared by calling `cmp()` on their inner values.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use std::cmp::Ordering;\n    ///\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let five = Arc::new(5);\n    ///\n    /// assert_eq!(Ordering::Less, five.cmp(&Arc::new(6)));\n    /// ```\n    fn cmp(&self, other: &Self) -> Ordering {\n        (**self).cmp(&**other)\n    }\n}\nimpl<T: ?Sized + Eq> Eq for Arc<T> {}\n\nimpl<T: ?Sized + fmt::Display> fmt::Display for Arc<T> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        fmt::Display::fmt(&**self, f)\n    }\n}\n\nimpl<T: ?Sized + fmt::Debug> fmt::Debug for Arc<T> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        fmt::Debug::fmt(&**self, f)\n    }\n}\n\nimpl<T: ?Sized> fmt::Pointer for Arc<T> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        fmt::Pointer::fmt(&(&**self as *const T), f)\n    }\n}\n\nimpl<T: Default> Default for Arc<T> {\n    /// Creates a new `Arc<T>`, with the `Default` value for `T`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let x: Arc<i32> = Arc::default();\n    /// assert_eq!(*x, 0);\n    /// ```\n    fn default() -> Self {\n        // TODO: https://github.com/rust-lang/rust/pull/131460 / https://github.com/rust-lang/rust/pull/132031\n        Self::new(T::default())\n    }\n}\n\n#[cfg(not(portable_atomic_no_min_const_generics))]\nimpl Default for Arc<str> {\n    /// Creates an empty str inside an Arc.\n    ///\n    /// This may or may not share an allocation with other Arcs.\n    #[inline]\n    fn default() -> Self {\n        let arc: Arc<[u8]> = Arc::default();\n        debug_assert!(core::str::from_utf8(&arc).is_ok());\n        let ptr = Arc::into_inner_non_null(arc);\n        unsafe { Arc::from_ptr(ptr.as_ptr() as *mut ArcInner<str>) }\n    }\n}\n\n#[cfg(not(portable_atomic_no_min_const_generics))]\nimpl<T> Default for Arc<[T]> {\n    /// Creates an empty `[T]` inside an Arc.\n    ///\n    /// This may or may not share an allocation with other Arcs.\n    #[inline]\n    fn default() -> Self {\n        // TODO: we cannot use non-allocation optimization (https://github.com/rust-lang/rust/blob/1.93.0/library/alloc/src/sync.rs#L3807)\n        // for now since casting Arc<[T; N]> -> Arc<[T]> requires unstable CoerceUnsized.\n        let arr: [T; 0] = [];\n        Arc::from(arr)\n    }\n}\n\nimpl<T> Default for Pin<Arc<T>>\nwhere\n    T: ?Sized,\n    Arc<T>: Default,\n{\n    #[inline]\n    fn default() -> Self {\n        unsafe { Pin::new_unchecked(Arc::<T>::default()) }\n    }\n}\n\nimpl<T: ?Sized + Hash> Hash for Arc<T> {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        (**self).hash(state);\n    }\n}\n\nimpl<T> From<T> for Arc<T> {\n    /// Converts a `T` into an `Arc<T>`\n    ///\n    /// The conversion moves the value into a\n    /// newly allocated `Arc`. It is equivalent to\n    /// calling `Arc::new(t)`.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let x = 5;\n    /// let arc = Arc::new(5);\n    ///\n    /// assert_eq!(Arc::from(x), arc);\n    /// ```\n    fn from(t: T) -> Self {\n        Self::new(t)\n    }\n}\n\n// This just outputs the input as is, but can be used like an item-level block by using it with cfg.\n// Note: This macro is items!({ }), not items! { }.\n// An extra brace is used in input to make contents rustfmt-able.\n#[cfg(not(portable_atomic_no_min_const_generics))]\nmacro_rules! items {\n    ({$($tt:tt)*}) => {\n        $($tt)*\n    };\n}\n\n#[cfg(not(portable_atomic_no_min_const_generics))]\nitems!({\n    impl<T, const N: usize> From<[T; N]> for Arc<[T]> {\n        /// Converts a [`[T; N]`](prim@array) into an `Arc<[T]>`.\n        ///\n        /// The conversion moves the array into a newly allocated `Arc`.\n        ///\n        /// # Example\n        ///\n        /// ```\n        /// use portable_atomic_util::Arc;\n        /// let original: [i32; 3] = [1, 2, 3];\n        /// let shared: Arc<[i32]> = Arc::from(original);\n        /// assert_eq!(&[1, 2, 3], &shared[..]);\n        /// ```\n        #[inline]\n        fn from(v: [T; N]) -> Self {\n            // Casting Arc<[T; N]> -> Arc<[T]> requires unstable CoerceUnsized, so we convert via Box.\n            // Since the compiler knows the actual size and metadata, the intermediate allocation is\n            // optimized and generates the same code as when using CoerceUnsized and convert Arc<[T; N]> to Arc<[T]>.\n            // https://github.com/taiki-e/portable-atomic/issues/143#issuecomment-1866488569\n            let v: Box<[T]> = Box::<[T; N]>::from(v);\n            v.into()\n        }\n    }\n});\n\nimpl<T: Clone> From<&[T]> for Arc<[T]> {\n    /// Allocates a reference-counted slice and fills it by cloning `v`'s items.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let original: &[i32] = &[1, 2, 3];\n    /// let shared: Arc<[i32]> = Arc::from(original);\n    /// assert_eq!(&[1, 2, 3], &shared[..]);\n    /// ```\n    #[inline]\n    fn from(v: &[T]) -> Self {\n        unsafe { Self::from_iter_exact(v.iter().cloned(), v.len()) }\n    }\n}\n\nimpl<T: Clone> From<&mut [T]> for Arc<[T]> {\n    /// Allocates a reference-counted slice and fills it by cloning `v`'s items.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let mut original = [1, 2, 3];\n    /// let original: &mut [i32] = &mut original;\n    /// let shared: Arc<[i32]> = Arc::from(original);\n    /// assert_eq!(&[1, 2, 3], &shared[..]);\n    /// ```\n    #[inline]\n    fn from(v: &mut [T]) -> Self {\n        Self::from(&*v)\n    }\n}\n\nimpl From<&str> for Arc<str> {\n    /// Allocates a reference-counted `str` and copies `v` into it.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let shared: Arc<str> = Arc::from(\"eggplant\");\n    /// assert_eq!(\"eggplant\", &shared[..]);\n    /// ```\n    #[inline]\n    fn from(v: &str) -> Self {\n        let arc = Arc::<[u8]>::from(v.as_bytes());\n        // SAFETY: `str` has the same layout as `[u8]`.\n        // https://doc.rust-lang.org/nightly/reference/type-layout.html#str-layout\n        unsafe { Self::from_raw(Arc::into_raw(arc) as *const str) }\n    }\n}\n\nimpl From<&mut str> for Arc<str> {\n    /// Allocates a reference-counted `str` and copies `v` into it.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let mut original = String::from(\"eggplant\");\n    /// let original: &mut str = &mut original;\n    /// let shared: Arc<str> = Arc::from(original);\n    /// assert_eq!(\"eggplant\", &shared[..]);\n    /// ```\n    #[inline]\n    fn from(v: &mut str) -> Self {\n        Self::from(&*v)\n    }\n}\n\nimpl From<String> for Arc<str> {\n    /// Allocates a reference-counted `str` and copies `v` into it.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let unique: String = \"eggplant\".to_owned();\n    /// let shared: Arc<str> = Arc::from(unique);\n    /// assert_eq!(\"eggplant\", &shared[..]);\n    /// ```\n    #[inline]\n    fn from(v: String) -> Self {\n        Self::from(&v[..])\n    }\n}\n\nimpl<T: ?Sized> From<Box<T>> for Arc<T> {\n    /// Move a boxed object to a new, reference-counted allocation.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let unique: Box<str> = Box::from(\"eggplant\");\n    /// let shared: Arc<str> = Arc::from(unique);\n    /// assert_eq!(\"eggplant\", &shared[..]);\n    /// ```\n    #[inline]\n    fn from(v: Box<T>) -> Self {\n        Self::from_box(v)\n    }\n}\n\nimpl<T> From<Vec<T>> for Arc<[T]> {\n    /// Allocates a reference-counted slice and moves `v`'s items into it.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let unique: Vec<i32> = vec![1, 2, 3];\n    /// let shared: Arc<[i32]> = Arc::from(unique);\n    /// assert_eq!(&[1, 2, 3], &shared[..]);\n    /// ```\n    #[inline]\n    fn from(v: Vec<T>) -> Self {\n        unsafe {\n            let len = v.len();\n            let cap = v.capacity();\n            let vec_ptr = mem::ManuallyDrop::new(v).as_mut_ptr();\n\n            let mut arc = Self::new_uninit_slice(len);\n            let data = Arc::get_mut_unchecked(&mut arc);\n            ptr::copy_nonoverlapping(vec_ptr, data.as_mut_ptr() as *mut T, len);\n\n            // Create a `Vec<T>` with length 0, to deallocate the buffer\n            // without dropping its contents or the allocator\n            let _ = Vec::from_raw_parts(vec_ptr, 0, cap);\n\n            arc.assume_init()\n        }\n    }\n}\n\nimpl<'a, B> From<Cow<'a, B>> for Arc<B>\nwhere\n    B: ?Sized + ToOwned,\n    Arc<B>: From<&'a B> + From<B::Owned>,\n{\n    /// Creates an atomically reference-counted pointer from a clone-on-write\n    /// pointer by copying its content.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use std::borrow::Cow;\n    ///\n    /// use portable_atomic_util::Arc;\n    ///\n    /// let cow: Cow<'_, str> = Cow::Borrowed(\"eggplant\");\n    /// let shared: Arc<str> = Arc::from(cow);\n    /// assert_eq!(\"eggplant\", &shared[..]);\n    /// ```\n    #[inline]\n    fn from(cow: Cow<'a, B>) -> Self {\n        match cow {\n            Cow::Borrowed(s) => Self::from(s),\n            Cow::Owned(s) => Self::from(s),\n        }\n    }\n}\n\nimpl From<Arc<str>> for Arc<[u8]> {\n    /// Converts an atomically reference-counted string slice into a byte slice.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let string: Arc<str> = Arc::from(\"eggplant\");\n    /// let bytes: Arc<[u8]> = Arc::from(string);\n    /// assert_eq!(\"eggplant\".as_bytes(), bytes.as_ref());\n    /// ```\n    #[inline]\n    fn from(rc: Arc<str>) -> Self {\n        // SAFETY: `str` has the same layout as `[u8]`.\n        // https://doc.rust-lang.org/nightly/reference/type-layout.html#str-layout\n        unsafe { Self::from_raw(Arc::into_raw(rc) as *const [u8]) }\n    }\n}\n\n#[cfg(not(portable_atomic_no_min_const_generics))]\nitems!({\n    impl<T, const N: usize> TryFrom<Arc<[T]>> for Arc<[T; N]> {\n        type Error = Arc<[T]>;\n\n        fn try_from(boxed_slice: Arc<[T]>) -> Result<Self, Self::Error> {\n            if boxed_slice.len() == N {\n                let ptr = Arc::into_inner_non_null(boxed_slice);\n                Ok(unsafe { Self::from_inner(ptr.cast::<ArcInner<[T; N]>>()) })\n            } else {\n                Err(boxed_slice)\n            }\n        }\n    }\n});\n\nimpl<T> FromIterator<T> for Arc<[T]> {\n    /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`.\n    ///\n    /// # Performance characteristics\n    ///\n    /// ## The general case\n    ///\n    /// In the general case, collecting into `Arc<[T]>` is done by first\n    /// collecting into a `Vec<T>`. That is, when writing the following:\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect();\n    /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);\n    /// ```\n    ///\n    /// this behaves as if we wrote:\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0)\n    ///     .collect::<Vec<_>>() // The first set of allocations happens here.\n    ///     .into(); // A second allocation for `Arc<[T]>` happens here.\n    ///\n    /// assert_eq!(&*evens, &[0, 2, 4, 6, 8]);\n    /// ```\n    ///\n    /// This will allocate as many times as needed for constructing the `Vec<T>`\n    /// and then it will allocate once for turning the `Vec<T>` into the `Arc<[T]>`.\n    ///\n    /// ## Iterators of known length\n    ///\n    /// When your `Iterator` implements `TrustedLen` and is of an exact size,\n    /// a single allocation will be made for the `Arc<[T]>`. For example:\n    ///\n    /// ```\n    /// use portable_atomic_util::Arc;\n    /// let evens: Arc<[u8]> = (0..10).collect(); // Just a single allocation happens here.\n    ///\n    /// assert_eq!(&*evens, &*(0..10).collect::<Vec<_>>());\n    /// ```\n    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {\n        iter.into_iter().collect::<Vec<T>>().into()\n    }\n}\n\nimpl<T: ?Sized> borrow::Borrow<T> for Arc<T> {\n    fn borrow(&self) -> &T {\n        self\n    }\n}\n\nimpl<T: ?Sized> AsRef<T> for Arc<T> {\n    fn as_ref(&self) -> &T {\n        self\n    }\n}\n\nimpl<T: ?Sized> Unpin for Arc<T> {}\n\n/// Gets the pointer to data within the given an `ArcInner`.\n///\n/// # Safety\n///\n/// `arc` must uphold the safety requirements for `.byte_add(data_offset)`.\n/// This is automatically satisfied if it is a pointer to a valid `ArcInner`.\nunsafe fn data_ptr<T: ?Sized>(arc: *mut ArcInner<T>, data: &T) -> *mut T {\n    // SAFETY: the caller must uphold the safety contract.\n    unsafe {\n        let offset = data_offset::<T>(data);\n        strict::byte_add(arc, offset) as *mut T\n    }\n}\n\n/// Gets the offset within an `ArcInner` for the payload behind a pointer.\nfn data_offset<T: ?Sized>(ptr: &T) -> usize {\n    // Align the unsized value to the end of the ArcInner.\n    // Because ArcInner is repr(C), it will always be the last field in memory.\n    data_offset_align(mem::align_of_val::<T>(ptr))\n}\n\n#[inline]\nfn data_offset_align(align: usize) -> usize {\n    let layout = Layout::new::<ArcInner<()>>();\n    layout.size() + layout::padding_needed_for(layout, align)\n}\n\n/// A unique owning pointer to an [`ArcInner`] **that does not imply the contents are initialized,**\n/// but will deallocate it (without dropping the value) when dropped.\n///\n/// This is a helper for [`Arc::make_mut()`] to ensure correct cleanup on panic.\nstruct UniqueArcUninit<T: ?Sized> {\n    ptr: NonNull<ArcInner<T>>,\n    layout_for_value: Layout,\n}\n\nimpl<T: ?Sized> UniqueArcUninit<T> {\n    /// Allocates an ArcInner with layout suitable to contain `for_value` or a clone of it.\n    fn new(for_value: &T) -> Self {\n        let layout = Layout::for_value(for_value);\n        let ptr = unsafe { Arc::allocate_for_value(for_value) };\n        Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout }\n    }\n\n    /// Returns the pointer to be written into to initialize the [`Arc`].\n    fn data_ptr(&mut self) -> *mut T {\n        let offset = data_offset_align(self.layout_for_value.align());\n        unsafe { strict::byte_add(self.ptr.as_ptr(), offset) as *mut T }\n    }\n\n    /// Upgrade this into a normal [`Arc`].\n    ///\n    /// # Safety\n    ///\n    /// The data must have been initialized (by writing to [`Self::data_ptr()`]).\n    unsafe fn into_arc(self) -> Arc<T> {\n        let this = ManuallyDrop::new(self);\n        let ptr = this.ptr.as_ptr();\n\n        // SAFETY: The pointer is valid as per `UniqueArcUninit::new`, and the caller is responsible\n        // for having initialized the data.\n        unsafe { Arc::from_ptr(ptr) }\n    }\n}\n\nimpl<T: ?Sized> Drop for UniqueArcUninit<T> {\n    fn drop(&mut self) {\n        // SAFETY:\n        // * new() produced a pointer safe to deallocate.\n        // * We own the pointer unless into_arc() was called, which forgets us.\n        unsafe {\n            Global.deallocate(\n                self.ptr.cast::<u8>(),\n                arc_inner_layout_for_value_layout(self.layout_for_value),\n            );\n        }\n    }\n}\n\n#[cfg(not(portable_atomic_no_error_in_core))]\nuse core::error;\n#[cfg(all(portable_atomic_no_error_in_core, feature = \"std\"))]\nuse std::error;\n#[cfg(any(not(portable_atomic_no_error_in_core), feature = \"std\"))]\nimpl<T: ?Sized + error::Error> error::Error for Arc<T> {\n    #[allow(deprecated)]\n    fn cause(&self) -> Option<&dyn error::Error> {\n        error::Error::cause(&**self)\n    }\n    fn source(&self) -> Option<&(dyn error::Error + 'static)> {\n        error::Error::source(&**self)\n    }\n}\n\n#[cfg(feature = \"serde\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"serde\")))]\nmod serde_impls {\n    use serde::{\n        de::{Deserialize, Deserializer},\n        ser::{Serialize, Serializer},\n    };\n\n    use super::{Arc, Box, Weak};\n\n    // Refs: https://github.com/serde-rs/serde/blob/v1.0.228/serde_core/src/ser/impls.rs#L472\n    impl<T: ?Sized + Serialize> Serialize for Arc<T> {\n        #[inline]\n        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n        where\n            S: Serializer,\n        {\n            (**self).serialize(serializer)\n        }\n    }\n\n    // Refs: https://github.com/serde-rs/serde/blob/v1.0.228/serde_core/src/ser/impls.rs#L564\n    impl<T: ?Sized + Serialize> Serialize for Weak<T> {\n        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n        where\n            S: Serializer,\n        {\n            self.upgrade().serialize(serializer)\n        }\n    }\n\n    // Refs: https://github.com/serde-rs/serde/blob/v1.0.228/serde_core/src/de/impls.rs#L2057\n    impl<'de, T> Deserialize<'de> for Arc<T>\n    where\n        T: ?Sized,\n        Box<T>: Deserialize<'de>,\n    {\n        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n        where\n            D: serde::Deserializer<'de>,\n        {\n            Box::deserialize(deserializer).map(Into::into)\n        }\n    }\n\n    // Refs: https://github.com/serde-rs/serde/blob/v1.0.228/serde_core/src/de/impls.rs#L2035\n    impl<'de, T> Deserialize<'de> for Weak<T>\n    where\n        T: Deserialize<'de>,\n    {\n        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n        where\n            D: Deserializer<'de>,\n        {\n            Option::<T>::deserialize(deserializer)?;\n            Ok(Weak::new())\n        }\n    }\n}\n\n#[cfg(feature = \"std\")]\nmod std_impls {\n    // TODO: Other trait implementations that are stable but we currently don't provide:\n    // - alloc::ffi\n    //   - https://doc.rust-lang.org/nightly/alloc/sync/struct.Arc.html#impl-From%3C%26CStr%3E-for-Arc%3CCStr%3E\n    //   - https://doc.rust-lang.org/nightly/alloc/sync/struct.Arc.html#impl-From%3C%26mut+CStr%3E-for-Arc%3CCStr%3E\n    //   - https://doc.rust-lang.org/nightly/alloc/sync/struct.Arc.html#impl-From%3CCString%3E-for-Arc%3CCStr%3E\n    //   - https://doc.rust-lang.org/nightly/alloc/sync/struct.Arc.html#impl-Default-for-Arc%3CCStr%3E\n    //   - Currently, we cannot implement these since CStr layout is not stable.\n    // - std::ffi\n    //   - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3C%26OsStr%3E-for-Arc%3COsStr%3E\n    //   - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3C%26mut+OsStr%3E-for-Arc%3COsStr%3E\n    //   - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3COsString%3E-for-Arc%3COsStr%3E\n    //   - Currently, we cannot implement these since OsStr layout is not stable.\n    // - std::path\n    //   - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3C%26Path%3E-for-Arc%3CPath%3E\n    //   - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3C%26mut+Path%3E-for-Arc%3CPath%3E\n    //   - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3CPathBuf%3E-for-Arc%3CPath%3E\n    //   - Currently, we cannot implement these since Path layout is not stable.\n\n    use std::io;\n    // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-AsFd-for-Arc%3CT%3E\n    // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-AsHandle-for-Arc%3CT%3E\n    // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-AsRawFd-for-Arc%3CT%3E\n    // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-AsSocket-for-Arc%3CT%3E\n    // Note:\n    // - T: ?Sized is currently only allowed on AsFd/AsHandle: https://github.com/rust-lang/rust/pull/114655#issuecomment-1977994288\n    // - std doesn't implement AsRawHandle/AsRawSocket for Arc as of Rust 1.90.\n    // - std::os::unix::io::AsRawFd and std::os::windows::io::{AsRawHandle, AsRawSocket} are available in all versions\n    // - std::os::wasi::prelude::AsRawFd requires 1.56 (https://github.com/rust-lang/rust/commit/e555003e6d6b6d71ce5509a6b6c7a15861208d6c)\n    // - std::os::unix::io::AsFd, std::os::wasi::prelude::AsFd, and std::os::windows::io::{AsHandle, AsSocket} require Rust 1.63\n    // - std::os::wasi::io::AsFd requires Rust 1.65 (https://github.com/rust-lang/rust/pull/103308)\n    // - std::os::fd requires Rust 1.66 (https://github.com/rust-lang/rust/pull/98368)\n    // - std::os::hermit::io::AsFd requires Rust 1.69 (https://github.com/rust-lang/rust/commit/b5fb4f3d9b1b308d59cab24ef2f9bf23dad948aa)\n    // - std::os::fd for HermitOS requires Rust 1.81 (https://github.com/rust-lang/rust/pull/126346)\n    // - std::os::fd for Trusty requires Rust 1.87 (no std support before it, https://github.com/rust-lang/rust/commit/7f6ee12526700e037ef34912b2b0c628028d382c)\n    // - std::os::solid::io::AsFd is unstable (solid_ext, https://github.com/rust-lang/rust/pull/115159)\n    // Note: we don't implement unstable ones.\n    #[cfg(not(portable_atomic_no_io_safety))]\n    #[cfg(target_os = \"trusty\")]\n    use std::os::fd;\n    #[cfg(not(portable_atomic_no_io_safety))]\n    #[cfg(target_os = \"hermit\")]\n    use std::os::hermit::io as fd;\n    #[cfg(unix)]\n    use std::os::unix::io as fd;\n    #[cfg(not(portable_atomic_no_io_safety))]\n    #[cfg(target_os = \"wasi\")]\n    use std::os::wasi::prelude as fd;\n\n    use super::Arc;\n\n    /// This impl allows implementing traits that require `AsRawFd` on Arc.\n    /// ```\n    /// # #[cfg(target_os = \"hermit\")]\n    /// # use std::os::hermit::io::AsRawFd;\n    /// # #[cfg(target_os = \"wasi\")]\n    /// # use std::os::wasi::prelude::AsRawFd;\n    /// # #[cfg(unix)]\n    /// # use std::os::unix::io::AsRawFd;\n    /// use std::net::UdpSocket;\n    ///\n    /// use portable_atomic_util::Arc;\n    ///\n    /// trait MyTrait: AsRawFd {}\n    /// impl MyTrait for Arc<UdpSocket> {}\n    /// ```\n    #[cfg(any(\n        unix,\n        all(\n            not(portable_atomic_no_io_safety),\n            any(target_os = \"hermit\", target_os = \"trusty\", target_os = \"wasi\"),\n        ),\n    ))]\n    impl<T: fd::AsRawFd> fd::AsRawFd for Arc<T> {\n        #[inline]\n        fn as_raw_fd(&self) -> fd::RawFd {\n            (**self).as_raw_fd()\n        }\n    }\n    /// This impl allows implementing traits that require `AsFd` on Arc.\n    /// ```\n    /// # #[cfg(target_os = \"hermit\")]\n    /// # use std::os::hermit::io::AsFd;\n    /// # #[cfg(target_os = \"wasi\")]\n    /// # use std::os::wasi::prelude::AsFd;\n    /// # #[cfg(unix)]\n    /// # use std::os::unix::io::AsFd;\n    /// use std::net::UdpSocket;\n    ///\n    /// use portable_atomic_util::Arc;\n    ///\n    /// trait MyTrait: AsFd {}\n    /// impl MyTrait for Arc<UdpSocket> {}\n    /// ```\n    #[cfg(not(portable_atomic_no_io_safety))]\n    #[cfg(any(unix, target_os = \"hermit\", target_os = \"trusty\", target_os = \"wasi\"))]\n    impl<T: ?Sized + fd::AsFd> fd::AsFd for Arc<T> {\n        #[inline]\n        fn as_fd(&self) -> fd::BorrowedFd<'_> {\n            (**self).as_fd()\n        }\n    }\n    /// This impl allows implementing traits that require `AsHandle` on Arc.\n    /// ```\n    /// # use std::os::windows::io::AsHandle;\n    /// use std::fs::File;\n    ///\n    /// use portable_atomic_util::Arc;\n    ///\n    /// trait MyTrait: AsHandle {}\n    /// impl MyTrait for Arc<File> {}\n    /// ```\n    #[cfg(not(portable_atomic_no_io_safety))]\n    #[cfg(windows)]\n    impl<T: ?Sized + std::os::windows::io::AsHandle> std::os::windows::io::AsHandle for Arc<T> {\n        #[inline]\n        fn as_handle(&self) -> std::os::windows::io::BorrowedHandle<'_> {\n            (**self).as_handle()\n        }\n    }\n    /// This impl allows implementing traits that require `AsSocket` on Arc.\n    /// ```\n    /// # use std::os::windows::io::AsSocket;\n    /// use std::net::UdpSocket;\n    ///\n    /// use portable_atomic_util::Arc;\n    ///\n    /// trait MyTrait: AsSocket {}\n    /// impl MyTrait for Arc<UdpSocket> {}\n    /// ```\n    #[cfg(not(portable_atomic_no_io_safety))]\n    #[cfg(windows)]\n    impl<T: std::os::windows::io::AsSocket> std::os::windows::io::AsSocket for Arc<T> {\n        #[inline]\n        fn as_socket(&self) -> std::os::windows::io::BorrowedSocket<'_> {\n            (**self).as_socket()\n        }\n    }\n\n    // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-Read-for-Arc%3CFile%3E\n    // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-Seek-for-Arc%3CFile%3E\n    // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-Write-for-Arc%3CFile%3E\n    impl io::Read for Arc<std::fs::File> {\n        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n            (&**self).read(buf)\n        }\n        fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {\n            (&**self).read_vectored(bufs)\n        }\n        // fn read_buf(&mut self, cursor: io::BorrowedCursor<'_>) -> io::Result<()> {\n        //     (&**self).read_buf(cursor)\n        // }\n        // #[inline]\n        // fn is_read_vectored(&self) -> bool {\n        //     (&**self).is_read_vectored()\n        // }\n        fn read_to_end(&mut self, buf: &mut alloc::vec::Vec<u8>) -> io::Result<usize> {\n            (&**self).read_to_end(buf)\n        }\n        fn read_to_string(&mut self, buf: &mut alloc::string::String) -> io::Result<usize> {\n            (&**self).read_to_string(buf)\n        }\n    }\n    impl io::Write for Arc<std::fs::File> {\n        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n            (&**self).write(buf)\n        }\n        fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {\n            (&**self).write_vectored(bufs)\n        }\n        // #[inline]\n        // fn is_write_vectored(&self) -> bool {\n        //     (&**self).is_write_vectored()\n        // }\n        #[inline]\n        fn flush(&mut self) -> io::Result<()> {\n            (&**self).flush()\n        }\n    }\n    impl io::Seek for Arc<std::fs::File> {\n        fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {\n            (&**self).seek(pos)\n        }\n    }\n    // TODO: TcpStream and UnixStream: https://github.com/rust-lang/rust/pull/134190\n    // impl io::Read for Arc<std::net::TcpStream> {\n    //     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n    //         (&**self).read(buf)\n    //     }\n    //     // fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {\n    //     //     (&**self).read_buf(buf)\n    //     // }\n    //     fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {\n    //         (&**self).read_vectored(bufs)\n    //     }\n    //     // #[inline]\n    //     // fn is_read_vectored(&self) -> bool {\n    //     //     (&**self).is_read_vectored()\n    //     // }\n    // }\n    // impl io::Write for Arc<std::net::TcpStream> {\n    //     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n    //         (&**self).write(buf)\n    //     }\n    //     fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {\n    //         (&**self).write_vectored(bufs)\n    //     }\n    //     // #[inline]\n    //     // fn is_write_vectored(&self) -> bool {\n    //     //     (&**self).is_write_vectored()\n    //     // }\n    //     #[inline]\n    //     fn flush(&mut self) -> io::Result<()> {\n    //         (&**self).flush()\n    //     }\n    // }\n    // #[cfg(unix)]\n    // impl io::Read for Arc<std::os::unix::net::UnixStream> {\n    //     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n    //         (&**self).read(buf)\n    //     }\n    //     // fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {\n    //     //     (&**self).read_buf(buf)\n    //     // }\n    //     fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {\n    //         (&**self).read_vectored(bufs)\n    //     }\n    //     // #[inline]\n    //     // fn is_read_vectored(&self) -> bool {\n    //     //     (&**self).is_read_vectored()\n    //     // }\n    // }\n    // #[cfg(unix)]\n    // impl io::Write for Arc<std::os::unix::net::UnixStream> {\n    //     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n    //         (&**self).write(buf)\n    //     }\n    //     fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {\n    //         (&**self).write_vectored(bufs)\n    //     }\n    //     // #[inline]\n    //     // fn is_write_vectored(&self) -> bool {\n    //     //     (&**self).is_write_vectored()\n    //     // }\n    //     #[inline]\n    //     fn flush(&mut self) -> io::Result<()> {\n    //         (&**self).flush()\n    //     }\n    // }\n}\n\nuse self::clone::CloneToUninit;\nmod clone {\n    use core::{\n        mem::{self, MaybeUninit},\n        ptr, slice,\n    };\n\n    use super::strict;\n\n    // Based on unstable core::clone::CloneToUninit.\n    // This trait is private and cannot be implemented for types outside of `portable-atomic-util`.\n    #[doc(hidden)] // private API\n    #[allow(unknown_lints, unnameable_types)] // Not public API. unnameable_types is available on Rust 1.79+\n    pub unsafe trait CloneToUninit {\n        unsafe fn clone_to_uninit(&self, dest: *mut u8);\n    }\n    unsafe impl<T: Clone> CloneToUninit for T {\n        #[inline]\n        unsafe fn clone_to_uninit(&self, dest: *mut u8) {\n            // SAFETY: we're calling a specialization with the same contract\n            unsafe { clone_one(self, dest as *mut T) }\n        }\n    }\n    unsafe impl<T: Clone> CloneToUninit for [T] {\n        #[inline]\n        #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n        unsafe fn clone_to_uninit(&self, dest: *mut u8) {\n            let dest: *mut [T] = strict::with_metadata_of(dest, self);\n            // SAFETY: we're calling a specialization with the same contract\n            unsafe { clone_slice(self, dest) }\n        }\n    }\n    unsafe impl CloneToUninit for str {\n        #[inline]\n        #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n        unsafe fn clone_to_uninit(&self, dest: *mut u8) {\n            // SAFETY: str is just a [u8] with UTF-8 invariant\n            unsafe { self.as_bytes().clone_to_uninit(dest) }\n        }\n    }\n    // Note: Currently, we cannot implement this for CStr/OsStr/Path since theirs layout is not stable.\n\n    #[inline]\n    unsafe fn clone_one<T: Clone>(src: &T, dst: *mut T) {\n        // SAFETY: The safety conditions of clone_to_uninit() are a superset of those of\n        // ptr::write().\n        unsafe {\n            // We hope the optimizer will figure out to create the cloned value in-place,\n            // skipping ever storing it on the stack and the copy to the destination.\n            ptr::write(dst, src.clone());\n        }\n    }\n    #[inline]\n    #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]\n    unsafe fn clone_slice<T: Clone>(src: &[T], dst: *mut [T]) {\n        let len = src.len();\n\n        // SAFETY: The produced `&mut` is valid because:\n        // * The caller is obligated to provide a pointer which is valid for writes.\n        // * All bytes pointed to are in MaybeUninit, so we don't care about the memory's\n        //   initialization status.\n        let uninit_ref = unsafe { &mut *(dst as *mut [MaybeUninit<T>]) };\n\n        // This is the most likely mistake to make, so check it as a debug assertion.\n        debug_assert_eq!(\n            len,\n            uninit_ref.len(), // <*const [T]>::len is unstable\n            \"clone_to_uninit() source and destination must have equal lengths\",\n        );\n\n        // Copy the elements\n        let mut initializing = InitializingSlice::from_fully_uninit(uninit_ref);\n        for element_ref in src {\n            // If the clone() panics, `initializing` will take care of the cleanup.\n            initializing.push(element_ref.clone());\n        }\n        // If we reach here, then the entire slice is initialized, and we've satisfied our\n        // responsibilities to the caller. Disarm the cleanup guard by forgetting it.\n        mem::forget(initializing);\n    }\n\n    /// Ownership of a collection of values stored in a non-owned `[MaybeUninit<T>]`, some of which\n    /// are not yet initialized. This is sort of like a `Vec` that doesn't own its allocation.\n    /// Its responsibility is to provide cleanup on unwind by dropping the values that *are*\n    /// initialized, unless disarmed by forgetting.\n    ///\n    /// This is a helper for `impl<T: Clone> CloneToUninit for [T]`.\n    struct InitializingSlice<'a, T> {\n        data: &'a mut [MaybeUninit<T>],\n        /// Number of elements of `*self.data` that are initialized.\n        initialized_len: usize,\n    }\n    impl<'a, T> InitializingSlice<'a, T> {\n        #[inline]\n        fn from_fully_uninit(data: &'a mut [MaybeUninit<T>]) -> Self {\n            Self { data, initialized_len: 0 }\n        }\n        /// Push a value onto the end of the initialized part of the slice.\n        ///\n        /// # Panics\n        ///\n        /// Panics if the slice is already fully initialized.\n        #[inline]\n        fn push(&mut self, value: T) {\n            self.data[self.initialized_len] = MaybeUninit::new(value);\n            self.initialized_len += 1;\n        }\n    }\n    impl<T> Drop for InitializingSlice<'_, T> {\n        #[cold] // will only be invoked on unwind\n        fn drop(&mut self) {\n            let initialized_slice = unsafe {\n                slice::from_raw_parts_mut(self.data.as_mut_ptr() as *mut T, self.initialized_len)\n            };\n            // SAFETY:\n            // * the pointer is valid because it was made from a mutable reference\n            // * `initialized_len` counts the initialized elements as an invariant of this type,\n            //   so each of the pointed-to elements is initialized and may be dropped.\n            unsafe {\n                ptr::drop_in_place::<[T]>(initialized_slice);\n            }\n        }\n    }\n}\n\nmod layout {\n    use core::{alloc::Layout, cmp};\n\n    use super::{ISIZE_MAX, USIZE_MAX};\n\n    // Based on unstable Layout::padding_needed_for.\n    #[inline]\n    #[must_use]\n    pub(super) fn padding_needed_for(layout: Layout, align: usize) -> usize {\n        // FIXME: Can we just change the type on this to `Alignment`?\n        if !align.is_power_of_two() {\n            return USIZE_MAX;\n        }\n        let len_rounded_up = size_rounded_up_to_custom_align(layout, align);\n        // SAFETY: Cannot overflow because the rounded-up value is never less\n        len_rounded_up.wrapping_sub(layout.size()) // can use unchecked_sub\n    }\n\n    /// Returns the smallest multiple of `align` greater than or equal to `self.size()`.\n    ///\n    /// This can return at most `Alignment::MAX` (aka `isize::MAX + 1`)\n    /// because the original size is at most `isize::MAX`.\n    #[inline]\n    fn size_rounded_up_to_custom_align(layout: Layout, align: usize) -> usize {\n        // Rounded up value is:\n        //   size_rounded_up = (size + align - 1) & !(align - 1);\n        //\n        // The arithmetic we do here can never overflow:\n        //\n        // 1. align is guaranteed to be > 0, so align - 1 is always\n        //    valid.\n        //\n        // 2. size is at most `isize::MAX`, so adding `align - 1` (which is at\n        //    most `isize::MAX`) can never overflow a `usize`.\n        //\n        // 3. masking by the alignment can remove at most `align - 1`,\n        //    which is what we just added, thus the value we return is never\n        //    less than the original `size`.\n        //\n        // (Size 0 Align MAX is already aligned, so stays the same, but things like\n        // Size 1 Align MAX or Size isize::MAX Align 2 round up to `isize::MAX + 1`.)\n        let align_m1 = align.wrapping_sub(1);\n        layout.size().wrapping_add(align_m1) & !align_m1\n    }\n\n    // Based on Layout::pad_to_align stabilized in Rust 1.44.\n    #[inline]\n    #[must_use]\n    pub(super) fn pad_to_align(layout: Layout) -> Layout {\n        // This cannot overflow. Quoting from the invariant of Layout:\n        // > `size`, when rounded up to the nearest multiple of `align`,\n        // > must not overflow isize (i.e., the rounded value must be\n        // > less than or equal to `isize::MAX`)\n        let new_size = size_rounded_up_to_custom_align(layout, layout.align());\n\n        // SAFETY: padded size is guaranteed to not exceed `isize::MAX`.\n        unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }\n    }\n\n    // Based on Layout::extend stabilized in Rust 1.44.\n    #[inline]\n    pub(super) fn extend(layout: Layout, next: Layout) -> Option<(Layout, usize)> {\n        let new_align = cmp::max(layout.align(), next.align());\n        let offset = size_rounded_up_to_custom_align(layout, next.align());\n\n        // SAFETY: `offset` is at most `isize::MAX + 1` (such as from aligning\n        // to `Alignment::MAX`) and `next.size` is at most `isize::MAX` (from the\n        // `Layout` type invariant).  Thus the largest possible `new_size` is\n        // `isize::MAX + 1 + isize::MAX`, which is `usize::MAX`, and cannot overflow.\n        let new_size = offset.wrapping_add(next.size()); // can use unchecked_add\n\n        let layout = Layout::from_size_align(new_size, new_align).ok()?;\n        Some((layout, offset))\n    }\n\n    // Based on Layout::array stabilized in Rust 1.44.\n    #[inline]\n    pub(super) fn array<T>(n: usize) -> Option<Layout> {\n        #[inline(always)]\n        const fn max_size_for_align(align: usize) -> usize {\n            // (power-of-two implies align != 0.)\n\n            // Rounded up size is:\n            //   size_rounded_up = (size + align - 1) & !(align - 1);\n            //\n            // We know from above that align != 0. If adding (align - 1)\n            // does not overflow, then rounding up will be fine.\n            //\n            // Conversely, &-masking with !(align - 1) will subtract off\n            // only low-order-bits. Thus if overflow occurs with the sum,\n            // the &-mask cannot subtract enough to undo that overflow.\n            //\n            // Above implies that checking for summation overflow is both\n            // necessary and sufficient.\n\n            // SAFETY: the maximum possible alignment is `isize::MAX + 1`,\n            // so the subtraction cannot overflow.\n            (ISIZE_MAX as usize + 1).wrapping_sub(align)\n        }\n\n        #[inline]\n        fn inner(element_layout: Layout, n: usize) -> Option<Layout> {\n            let element_size = element_layout.size();\n            let align = element_layout.align();\n\n            // We need to check two things about the size:\n            //  - That the total size won't overflow a `usize`, and\n            //  - That the total size still fits in an `isize`.\n            // By using division we can check them both with a single threshold.\n            // That'd usually be a bad idea, but thankfully here the element size\n            // and alignment are constants, so the compiler will fold all of it.\n            if element_size != 0 && n > max_size_for_align(align) / element_size {\n                return None;\n            }\n\n            // SAFETY: We just checked that we won't overflow `usize` when we multiply.\n            // This is a useless hint inside this function, but after inlining this helps\n            // deduplicate checks for whether the overall capacity is zero (e.g., in `RawVec`'s\n            // allocation path) before/after this multiplication.\n            let array_size = element_size.wrapping_mul(n); // can use unchecked_mul\n\n            // SAFETY: We just checked above that the `array_size` will not\n            // exceed `isize::MAX` even when rounded up to the alignment.\n            // And `Alignment` guarantees it's a power of two.\n            unsafe { Some(Layout::from_size_align_unchecked(array_size, align)) }\n        }\n\n        // Reduce the amount of code we need to monomorphize per `T`.\n        inner(Layout::new::<T>(), n)\n    }\n}\n\n#[cfg(feature = \"std\")]\nuse std::process::abort;\n#[cfg(not(feature = \"std\"))]\n#[cold]\nfn abort() -> ! {\n    struct Abort;\n    impl Drop for Abort {\n        fn drop(&mut self) {\n            panic!();\n        }\n    }\n\n    let _abort = Abort;\n    panic!(\"abort\")\n}\n\nfn is_dangling<T: ?Sized>(ptr: *const T) -> bool {\n    (ptr as *const ()).addr() == USIZE_MAX\n}\n\n// Based on unstable alloc::alloc::Global.\n//\n// Note: unlike alloc::alloc::Global that returns NonNull<[u8]>,\n// this returns NonNull<u8>.\nstruct Global;\n#[allow(clippy::unused_self)]\nimpl Global {\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Option<NonNull<u8>> {\n        // Layout::dangling is unstable\n        #[inline]\n        #[must_use]\n        fn dangling(layout: Layout) -> NonNull<u8> {\n            // SAFETY: align is guaranteed to be non-zero\n            unsafe { NonNull::new_unchecked(strict::without_provenance_mut::<u8>(layout.align())) }\n        }\n\n        match layout.size() {\n            0 => Some(dangling(layout)),\n            // SAFETY: `layout` is non-zero in size,\n            _size => unsafe {\n                let raw_ptr = if zeroed {\n                    alloc::alloc::alloc_zeroed(layout)\n                } else {\n                    alloc::alloc::alloc(layout)\n                };\n                NonNull::new(raw_ptr)\n            },\n        }\n    }\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    fn allocate(self, layout: Layout) -> Option<NonNull<u8>> {\n        self.alloc_impl(layout, false)\n    }\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    fn allocate_zeroed(self, layout: Layout) -> Option<NonNull<u8>> {\n        self.alloc_impl(layout, true)\n    }\n    #[inline]\n    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\n    unsafe fn deallocate(self, ptr: NonNull<u8>, layout: Layout) {\n        if layout.size() != 0 {\n            // SAFETY:\n            // * We have checked that `layout` is non-zero in size.\n            // * The caller is obligated to provide a layout that \"fits\", and in this case,\n            //   \"fit\" always means a layout that is equal to the original, because our\n            //   `allocate()`, `grow()`, and `shrink()` implementations never returns a larger\n            //   allocation than requested.\n            // * Other conditions must be upheld by the caller, as per `Allocator::deallocate()`'s\n            //   safety documentation.\n            unsafe { alloc::alloc::dealloc(ptr.as_ptr(), layout) }\n        }\n    }\n}\n"
    },
    {
      "package": "portable-atomic-util@0.2.8",
      "sourcePath": "src/lib.rs",
      "sha256": "4cedeff1ec801c7365d9c033354f5632f7f25c46bf3d48f8330ede559dc579a6",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*!\n<!-- Note: Document from sync-markdown-to-rustdoc:start through sync-markdown-to-rustdoc:end\n     is synchronized from README.md. Any changes to that range are not preserved. -->\n<!-- tidy:sync-markdown-to-rustdoc:start -->\n\nSynchronization primitives built with [portable-atomic].\n\n- Provide `Arc`. (optional, requires the `std` or `alloc` feature)\n- Provide `task::Wake`. (optional, requires the `std` or `alloc` feature)\n<!-- - Provide generic `Atomic<T>` type. (optional, requires the `generic` feature) -->\n\nSee [portable-atomic#1] for other primitives being considered for addition to this crate.\n\nThis crate was originally [part of the portable-atomic repository](https://github.com/taiki-e/portable-atomic/tree/cbbee0c0d202a5944f7d66aaafaac6ed76e6f599/portable-atomic-util) and was extracted into its own repository.\n\n## Optional features\n\n- **`std`**<br>\n  Use `std`.\n\n  Note:\n  - This implicitly enables the `alloc` feature.\n\n- **`alloc`**<br>\n  Use `alloc`.\n\n- **`serde`**<br>\n  Implement `serde::{Serialize, Deserialize}` for `Arc`.\n\n  Note:\n  - The MSRV when this feature is enabled is the one coming from serde, as of now it's Rust 1.56\n\n<!-- TODO: https://github.com/taiki-e/portable-atomic/issues/1\n- **`generic`**<br>\n  Provides generic `Atomic<T>` type.\n-->\n\n[portable-atomic]: https://github.com/taiki-e/portable-atomic\n[portable-atomic#1]: https://github.com/taiki-e/portable-atomic/issues/1\n\n## Optional cfg\n\nOne of the ways to enable cfg is to set [rustflags in the cargo config](https://doc.rust-lang.org/cargo/reference/config.html#targettriplerustflags):\n\n```toml\n# .cargo/config.toml\n[target.<target>]\nrustflags = [\"--cfg\", \"portable_atomic_unstable_coerce_unsized\"]\n```\n\nOr set environment variable:\n\n```sh\nRUSTFLAGS=\"--cfg portable_atomic_unstable_coerce_unsized\" cargo ...\n```\n\n- <a name=\"optional-cfg-unstable-coerce-unsized\"></a>**`--cfg portable_atomic_unstable_coerce_unsized`**<br>\n  Support coercing of `Arc<T>` to `Arc<U>` as in `std::sync::Arc`.\n\n  <!-- TODO: add coercing of `Weak<T>` to `Weak<U>` as well, with testing & documentation updates -->\n\n  This cfg requires Rust nightly because this coercing requires [unstable `CoerceUnsized` trait](https://doc.rust-lang.org/nightly/core/ops/trait.CoerceUnsized.html).\n\n  See [this issue comment](https://github.com/taiki-e/portable-atomic/issues/143#issuecomment-1866488569) for another known workaround.\n\n  **Note:** This cfg is unstable and outside of the normal semver guarantees and minor or patch versions of portable-atomic-util may make breaking changes to them at any time.\n\n## Related Projects\n\n- [portable-atomic]: Portable atomic types including support for 128-bit atomics, atomic float, etc.\n- [atomic-maybe-uninit]: Atomic operations on potentially uninitialized integers.\n- [atomic-memcpy]: Byte-wise atomic memcpy.\n\n[atomic-maybe-uninit]: https://github.com/taiki-e/atomic-maybe-uninit\n[atomic-memcpy]: https://github.com/taiki-e/atomic-memcpy\n\n<!-- tidy:sync-markdown-to-rustdoc:end -->\n*/\n\n#![no_std]\n#![doc(test(\n    no_crate_inject,\n    attr(allow(\n        dead_code,\n        unused_variables,\n        clippy::undocumented_unsafe_blocks,\n        clippy::unused_trait_names,\n    ))\n))]\n#![cfg_attr(not(portable_atomic_no_unsafe_op_in_unsafe_fn), warn(unsafe_op_in_unsafe_fn))] // unsafe_op_in_unsafe_fn requires Rust 1.52\n#![cfg_attr(portable_atomic_no_unsafe_op_in_unsafe_fn, allow(unused_unsafe))]\n#![warn(\n    // Lints that may help when writing public library.\n    missing_debug_implementations,\n    missing_docs,\n    clippy::alloc_instead_of_core,\n    clippy::exhaustive_enums,\n    clippy::exhaustive_structs,\n    clippy::impl_trait_in_params,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core,\n    // clippy::missing_inline_in_public_items,\n)]\n#![cfg_attr(portable_atomic_no_strict_provenance, allow(unstable_name_collisions))]\n#![allow(clippy::inline_always)]\n// docs.rs only (cfg is enabled by docs.rs, not build script)\n#![cfg_attr(docsrs, feature(doc_cfg))]\n#![cfg_attr(docsrs, doc(auto_cfg = false))]\n// Enable custom unsized coercions if the user explicitly opts-in to unstable cfg\n#![cfg_attr(portable_atomic_unstable_coerce_unsized, feature(coerce_unsized, unsize))]\n\n#[cfg(feature = \"alloc\")]\nextern crate alloc;\n#[cfg(feature = \"std\")]\nextern crate std;\n\n#[macro_use]\nmod utils;\n\n#[cfg(feature = \"alloc\")]\nmod arc;\n#[cfg(feature = \"alloc\")]\n#[cfg_attr(docsrs, doc(cfg(any(feature = \"alloc\", feature = \"std\"))))]\npub use self::arc::{Arc, Weak};\n\n#[cfg(feature = \"alloc\")]\n#[cfg_attr(docsrs, doc(cfg(any(feature = \"alloc\", feature = \"std\"))))]\npub mod task;\n"
    },
    {
      "package": "portable-atomic-util@0.2.8",
      "sourcePath": "src/task.rs",
      "sha256": "fc6f5a52f300d428f07b915aea711b638d49b00e4b5b804dcff00937e7fda2c5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Types and Traits for working with asynchronous tasks.\n\n// This module is based on alloc::task::Wake.\n//\n// The code has been adjusted to work with stable Rust.\n//\n// Source: https://github.com/rust-lang/rust/blob/1.84.0/library/alloc/src/task.rs.\n//\n// Copyright & License of the original code:\n// - https://github.com/rust-lang/rust/blob/1.84.0/COPYRIGHT\n// - https://github.com/rust-lang/rust/blob/1.84.0/LICENSE-APACHE\n// - https://github.com/rust-lang/rust/blob/1.84.0/LICENSE-MIT\n\nuse core::{\n    mem::ManuallyDrop,\n    task::{RawWaker, RawWakerVTable, Waker},\n};\n\nuse crate::Arc;\n\n/// The implementation of waking a task on an executor.\n///\n/// This is an equivalent to [`std::task::Wake`], but using [`portable_atomic_util::Arc`](crate::Arc)\n/// as a reference-counted pointer. See the documentation for [`std::task::Wake`] for more details.\n///\n/// **Note:** Unlike `std::task::Wake`, all methods take `this:` instead of `self:`.\n/// This is because using `portable_atomic_util::Arc` as a receiver requires the\n/// [unstable `arbitrary_self_types` feature](https://github.com/rust-lang/rust/issues/44874).\n///\n/// # Examples\n///\n/// A basic `block_on` function that takes a future and runs it to completion on\n/// the current thread.\n///\n/// **Note:** This example trades correctness for simplicity. In order to prevent\n/// deadlocks, production-grade implementations will also need to handle\n/// intermediate calls to `thread::unpark` as well as nested invocations.\n///\n/// ```\n/// use std::{\n///     future::Future,\n///     task::{Context, Poll},\n///     thread::{self, Thread},\n/// };\n///\n/// use portable_atomic_util::{Arc, task::Wake};\n///\n/// /// A waker that wakes up the current thread when called.\n/// struct ThreadWaker(Thread);\n///\n/// impl Wake for ThreadWaker {\n///     fn wake(this: Arc<Self>) {\n///         this.0.unpark();\n///     }\n/// }\n///\n/// /// Run a future to completion on the current thread.\n/// fn block_on<T>(fut: impl Future<Output = T>) -> T {\n///     // Pin the future so it can be polled.\n///     let mut fut = Box::pin(fut);\n///\n///     // Create a new context to be passed to the future.\n///     let t = thread::current();\n///     let waker = Arc::new(ThreadWaker(t)).into();\n///     let mut cx = Context::from_waker(&waker);\n///\n///     // Run the future to completion.\n///     loop {\n///         match fut.as_mut().poll(&mut cx) {\n///             Poll::Ready(res) => return res,\n///             Poll::Pending => thread::park(),\n///         }\n///     }\n/// }\n///\n/// block_on(async {\n///     println!(\"Hi from inside a future!\");\n/// });\n/// ```\npub trait Wake {\n    /// Wake this task.\n    fn wake(this: Arc<Self>);\n\n    /// Wake this task without consuming the waker.\n    ///\n    /// If an executor supports a cheaper way to wake without consuming the\n    /// waker, it should override this method. By default, it clones the\n    /// [`Arc`] and calls [`wake`] on the clone.\n    ///\n    /// [`wake`]: Wake::wake\n    fn wake_by_ref(this: &Arc<Self>) {\n        Self::wake(this.clone());\n    }\n}\nimpl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {\n    /// Use a [`Wake`]-able type as a `Waker`.\n    ///\n    /// No heap allocations or atomic operations are used for this conversion.\n    fn from(waker: Arc<W>) -> Self {\n        // SAFETY: This is safe because raw_waker safely constructs\n        // a RawWaker from Arc<W>.\n        unsafe { Self::from_raw(raw_waker(waker)) }\n    }\n}\nimpl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {\n    /// Use a `Wake`-able type as a `RawWaker`.\n    ///\n    /// No heap allocations or atomic operations are used for this conversion.\n    fn from(waker: Arc<W>) -> Self {\n        raw_waker(waker)\n    }\n}\n\n// NB: This private function for constructing a RawWaker is used, rather than\n// inlining this into the `From<Arc<W>> for RawWaker` impl, to ensure that\n// the safety of `From<Arc<W>> for Waker` does not depend on the correct\n// trait dispatch - instead both impls call this function directly and\n// explicitly.\n#[inline(always)]\nfn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {\n    // Increment the reference count of the arc to clone it.\n    //\n    // The #[inline(always)] is to ensure that raw_waker and clone_waker are\n    // always generated in the same code generation unit as one another, and\n    // therefore that the structurally identical const-promoted RawWakerVTable\n    // within both functions is deduplicated at LLVM IR code generation time.\n    // This allows optimizing Waker::will_wake to a single pointer comparison of\n    // the vtable pointers, rather than comparing all four function pointers\n    // within the vtables.\n    #[inline(always)]\n    unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker {\n        // SAFETY: the caller must uphold the safety contract.\n        unsafe { Arc::increment_strong_count(waker as *const W) }\n        RawWaker::new(\n            waker,\n            &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),\n        )\n    }\n\n    // Wake by value, moving the Arc into the Wake::wake function\n    unsafe fn wake<W: Wake + Send + Sync + 'static>(waker: *const ()) {\n        // SAFETY: the caller must uphold the safety contract.\n        let waker = unsafe { Arc::from_raw(waker as *const W) };\n        <W as Wake>::wake(waker);\n    }\n\n    // Wake by reference, wrap the waker in ManuallyDrop to avoid dropping it\n    unsafe fn wake_by_ref<W: Wake + Send + Sync + 'static>(waker: *const ()) {\n        // SAFETY: the caller must uphold the safety contract.\n        let waker = unsafe { ManuallyDrop::new(Arc::from_raw(waker as *const W)) };\n        <W as Wake>::wake_by_ref(&waker);\n    }\n\n    // Decrement the reference count of the Arc on drop\n    unsafe fn drop_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) {\n        // SAFETY: the caller must uphold the safety contract.\n        unsafe { Arc::decrement_strong_count(waker as *const W) }\n    }\n\n    RawWaker::new(\n        Arc::into_raw(waker) as *const (),\n        &RawWakerVTable::new(clone_waker::<W>, wake::<W>, wake_by_ref::<W>, drop_waker::<W>),\n    )\n}\n"
    },
    {
      "package": "portable-atomic-util@0.2.8",
      "sourcePath": "src/utils.rs",
      "sha256": "afe133c869f3a833a8a3d35afeb96e4caffc39da5c5bc063501b0293ae0344db",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![cfg_attr(not(feature = \"alloc\"), allow(dead_code, unused_macros, unused_imports))]\n\n// rustfmt-compatible cfg_select/cfg_if alternative\n// Note: This macro is cfg_sel!({ }), not cfg_sel! { }.\n// An extra brace is used in input to make contents rustfmt-able.\nmacro_rules! cfg_sel {\n    ({#[cfg(else)] { $($output:tt)* }}) => {\n        $($output)*\n    };\n    ({\n        #[cfg($cfg:meta)]\n        { $($output:tt)* }\n        $($( $rest:tt )+)?\n    }) => {\n        #[cfg($cfg)]\n        cfg_sel! {{#[cfg(else)] { $($output)* }}}\n        $(\n            #[cfg(not($cfg))]\n            cfg_sel! {{ $($rest)+ }}\n        )?\n    };\n}\n\n// This module provides core::ptr strict_provenance/exposed_provenance polyfill for pre-1.84 rustc.\npub(crate) mod ptr {\n    cfg_sel!({\n        #[cfg(not(portable_atomic_no_strict_provenance))]\n        {\n            pub(crate) use core::ptr::without_provenance_mut;\n        }\n        #[cfg(else)]\n        {\n            #[inline(always)]\n            #[must_use]\n            pub(crate) const fn without_provenance_mut<T>(addr: usize) -> *mut T {\n                // An int-to-pointer transmute currently has exactly the intended semantics: it creates a\n                // pointer without provenance. Note that this is *not* a stable guarantee about transmute\n                // semantics, it relies on sysroot crates having special status.\n                // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that\n                // pointer).\n                #[cfg(miri)]\n                unsafe {\n                    core::mem::transmute(addr)\n                }\n                // const transmute requires Rust 1.56.\n                // Using transmute doesn't work with CHERI: https://github.com/kent-weak-memory/rust/blob/0c0ca909de877f889629057e1ddf139527446d75/library/core/src/ptr/mod.rs#L607\n                #[cfg(not(miri))]\n                {\n                    addr as *mut T\n                }\n            }\n\n            pub(crate) trait PtrExt<T: ?Sized>: Copy {\n                #[must_use]\n                fn addr(self) -> usize;\n            }\n            impl<T: ?Sized> PtrExt<T> for *const T {\n                #[inline(always)]\n                #[must_use]\n                fn addr(self) -> usize {\n                    // A pointer-to-integer transmute currently has exactly the right semantics: it returns the\n                    // address without exposing the provenance. Note that this is *not* a stable guarantee about\n                    // transmute semantics, it relies on sysroot crates having special status.\n                    // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the\n                    // provenance).\n                    #[cfg(miri)]\n                    unsafe {\n                        core::mem::transmute(self as *const ())\n                    }\n                    // Using transmute doesn't work with CHERI: https://github.com/kent-weak-memory/rust/blob/0c0ca909de877f889629057e1ddf139527446d75/library/core/src/ptr/mut_ptr.rs#L210\n                    #[cfg(not(miri))]\n                    {\n                        self as *const () as usize\n                    }\n                }\n            }\n        }\n    });\n\n    /// Creates a new pointer with the metadata of `other`.\n    #[inline]\n    #[must_use]\n    pub(crate) fn with_metadata_of<T, U: ?Sized>(this: *mut T, mut other: *const U) -> *mut U {\n        let target = &mut other as *mut *const U as *mut *const u8;\n\n        // SAFETY: In case of a thin pointer, this operations is identical\n        // to a simple assignment. In case of a fat pointer, with the current\n        // fat pointer layout implementation, the first field of such a\n        // pointer is always the data pointer, which is likewise assigned.\n        unsafe { *target = this as *const u8 }\n        other as *mut U\n    }\n\n    // Based on <pointer>::byte_add stabilized in Rust 1.75.\n    #[inline]\n    #[must_use]\n    pub(crate) unsafe fn byte_add<T: ?Sized>(ptr: *mut T, count: usize) -> *mut T {\n        // SAFETY: the caller must uphold the safety contract for `add`.\n        unsafe { with_metadata_of((ptr as *mut u8).add(count), ptr) }\n    }\n\n    // Based on <pointer>::byte_sub stabilized in Rust 1.75.\n    #[inline]\n    #[must_use]\n    pub(crate) unsafe fn byte_sub<T: ?Sized>(ptr: *mut T, count: usize) -> *mut T {\n        // SAFETY: the caller must uphold the safety contract for `sub`.\n        unsafe { with_metadata_of((ptr as *mut u8).sub(count), ptr) }\n    }\n}\n"
    },
    {
      "package": "portable-atomic-util@0.2.8",
      "sourcePath": "tests/arc.rs",
      "sha256": "19963c36b6781078a5882809f4bc7a6c5866931ade681bd983177f05c9c44105",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![cfg(any(feature = \"std\", feature = \"alloc\"))]\n#![allow(clippy::undocumented_unsafe_blocks)]\n\nuse std::{borrow::Cow, panic};\n\nuse portable_atomic_util::{Arc, Weak};\n\n#[derive(Debug, PartialEq)]\n#[repr(align(128))]\nstruct Aligned(u32);\n\n// https://github.com/taiki-e/portable-atomic/issues/37\n#[test]\nfn over_aligned() {\n    let value = Arc::new(Aligned(128));\n    let ptr = Arc::into_raw(value);\n    // SAFETY: `ptr` should always be a valid `Aligned`.\n    assert_eq!(unsafe { (*ptr).0 }, 128);\n    // SAFETY: `ptr` is a valid reference to an `Arc<Aligned>`.\n    let value = unsafe { Arc::from_raw(ptr) };\n    assert_eq!(value.0, 128);\n}\n\n#[test]\nfn default() {\n    let v = Arc::<[Aligned]>::default();\n    assert_eq!(v[..], []);\n    let v = Arc::<[()]>::default();\n    assert_eq!(v[..], []);\n    let v = Arc::<str>::default();\n    assert_eq!(&v[..], \"\");\n}\n\n#[test]\nfn cow_from() {\n    let o = Cow::Owned(\"abc\".to_owned());\n    let b = Cow::Borrowed(\"def\");\n    let o: Arc<str> = Arc::from(o);\n    let b: Arc<str> = Arc::from(b);\n    assert_eq!(&*o, \"abc\");\n    assert_eq!(&*b, \"def\");\n}\n\n#[test]\nfn make_mut_unsized() {\n    let mut v: Arc<[i32]> = Arc::from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n    Arc::make_mut(&mut v)[0] += 10;\n    assert_eq!(&*v, [11, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n    let v1 = Arc::clone(&v);\n    let v2 = Arc::make_mut(&mut v);\n    v2[1] += 10;\n    assert_eq!(&*v1, [11, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n    assert_eq!(&*v2, [11, 12, 3, 4, 5, 6, 7, 8, 9, 10]);\n    assert_eq!(&*v, [11, 12, 3, 4, 5, 6, 7, 8, 9, 10]);\n    drop(v1);\n    let w = Arc::downgrade(&v);\n    Arc::make_mut(&mut v)[2] += 10;\n    assert_eq!(&*v, [11, 12, 13, 4, 5, 6, 7, 8, 9, 10]);\n    assert!(w.upgrade().is_none());\n}\n\n#[test]\nfn make_mut_clone_panic() {\n    struct C(#[allow(dead_code)] Box<u8>);\n    impl Clone for C {\n        fn clone(&self) -> Self {\n            panic!()\n        }\n    }\n    let mut v: Arc<[C]> = Arc::from([C(Box::new(1)), C(Box::new(2))]);\n    let _v = Arc::make_mut(&mut v);\n    let v1 = Arc::clone(&v);\n    if !is_panic_abort() {\n        panic::catch_unwind(panic::AssertUnwindSafe(|| {\n            let _v = Arc::make_mut(&mut v);\n        }))\n        .unwrap_err();\n    }\n    drop(v1);\n}\n\n/// Test that a panic from a destructor does not leak the allocation.\n#[test]\nfn panic_no_leak() {\n    // use std::alloc::{AllocError, Allocator, Global, Layout};\n    use std::panic::{AssertUnwindSafe, catch_unwind};\n    // use std::ptr::NonNull;\n\n    // TODO: no custom allocator support\n    // struct AllocCount(Cell<i32>);\n    // unsafe impl Allocator for AllocCount {\n    //     fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {\n    //         self.0.set(self.0.get() + 1);\n    //         Global.allocate(layout)\n    //     }\n    //     unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {\n    //         self.0.set(self.0.get() - 1);\n    //         unsafe { Global.deallocate(ptr, layout) }\n    //     }\n    // }\n\n    struct PanicOnDrop;\n    impl Drop for PanicOnDrop {\n        fn drop(&mut self) {\n            panic!(\"PanicOnDrop\");\n        }\n    }\n\n    if !is_panic_abort() {\n        // let alloc = AllocCount(Cell::new(0));\n        // let rc = Arc::new_in(PanicOnDrop, &alloc);\n        let rc = Arc::new(PanicOnDrop);\n        // assert_eq!(alloc.0.get(), 1);\n\n        let panic_message = catch_unwind(AssertUnwindSafe(|| drop(rc))).unwrap_err();\n        assert_eq!(*panic_message.downcast_ref::<&'static str>().unwrap(), \"PanicOnDrop\");\n        // assert_eq!(alloc.0.get(), 0);\n    }\n}\n\n#[test]\nfn weak_dangling() {\n    let w = Weak::<Aligned>::new();\n    let p = Weak::into_raw(w);\n    let w = unsafe { Weak::from_raw(p) };\n    let w2 = Weak::clone(&w);\n    assert!(w.upgrade().is_none());\n    assert!(w2.upgrade().is_none());\n}\n\n// For -C panic=abort -Z panic_abort_tests: https://github.com/rust-lang/rust/issues/67650\nfn is_panic_abort() -> bool {\n    !matches!(build_context::PANIC, \"unwind\" | \"\") // cfg(panic) requires Rust 1.60\n}\n\n// https://github.com/rust-lang/rust/blob/1.84.0/library/alloc/src/sync/tests.rs\n#[allow(clippy::many_single_char_names)]\nmod alloc_tests {\n    use std::{\n        convert::TryInto as _,\n        sync::{Mutex, mpsc::channel},\n        thread,\n    };\n\n    use portable_atomic::{\n        AtomicBool, AtomicUsize,\n        Ordering::{Acquire, SeqCst},\n    };\n    use portable_atomic_util::{Arc, Weak};\n\n    struct Canary(*mut AtomicUsize);\n\n    impl Drop for Canary {\n        fn drop(&mut self) {\n            unsafe {\n                match *self {\n                    Canary(c) => {\n                        (*c).fetch_add(1, SeqCst);\n                    }\n                }\n            }\n        }\n    }\n\n    #[test]\n    #[cfg_attr(target_os = \"emscripten\", ignore = \"thread::spawn doesn't work on emscripten\")]\n    fn manually_share_arc() {\n        let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n        let arc_v = Arc::new(v);\n\n        let (tx, rx) = channel();\n\n        let _t = thread::spawn(move || {\n            let arc_v: Arc<Vec<i32>> = rx.recv().unwrap();\n            assert_eq!((*arc_v)[3], 4);\n        });\n\n        tx.send(arc_v.clone()).unwrap();\n\n        assert_eq!((*arc_v)[2], 3);\n        assert_eq!((*arc_v)[4], 5);\n    }\n\n    #[test]\n    fn test_arc_get_mut() {\n        let mut x = Arc::new(3);\n        *Arc::get_mut(&mut x).unwrap() = 4;\n        assert_eq!(*x, 4);\n        let y = x.clone();\n        assert!(Arc::get_mut(&mut x).is_none());\n        drop(y);\n        assert!(Arc::get_mut(&mut x).is_some());\n        let _w = Arc::downgrade(&x);\n        assert!(Arc::get_mut(&mut x).is_none());\n    }\n\n    #[test]\n    fn weak_counts() {\n        assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);\n        assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);\n\n        let a = Arc::new(0);\n        let w = Arc::downgrade(&a);\n        assert_eq!(Weak::strong_count(&w), 1);\n        assert_eq!(Weak::weak_count(&w), 1);\n        let w2 = w.clone();\n        assert_eq!(Weak::strong_count(&w), 1);\n        assert_eq!(Weak::weak_count(&w), 2);\n        assert_eq!(Weak::strong_count(&w2), 1);\n        assert_eq!(Weak::weak_count(&w2), 2);\n        drop(w);\n        assert_eq!(Weak::strong_count(&w2), 1);\n        assert_eq!(Weak::weak_count(&w2), 1);\n        let a2 = a.clone();\n        assert_eq!(Weak::strong_count(&w2), 2);\n        assert_eq!(Weak::weak_count(&w2), 1);\n        drop(a2);\n        drop(a);\n        assert_eq!(Weak::strong_count(&w2), 0);\n        assert_eq!(Weak::weak_count(&w2), 0);\n        drop(w2);\n    }\n\n    #[test]\n    fn try_unwrap() {\n        let x = Arc::new(3);\n        assert_eq!(Arc::try_unwrap(x), Ok(3));\n        let x = Arc::new(4);\n        let _y = x.clone();\n        assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4)));\n        let x = Arc::new(5);\n        let _w = Arc::downgrade(&x);\n        assert_eq!(Arc::try_unwrap(x), Ok(5));\n    }\n\n    #[test]\n    fn into_inner() {\n        for _ in 0..100\n        // ^ Increase chances of hitting potential race conditions\n        {\n            let x = Arc::new(3);\n            let y = Arc::clone(&x);\n            let r_thread = std::thread::spawn(|| Arc::into_inner(x));\n            let s_thread = std::thread::spawn(|| Arc::into_inner(y));\n            let r = r_thread.join().expect(\"r_thread panicked\");\n            let s = s_thread.join().expect(\"s_thread panicked\");\n            assert!(\n                matches!((r, s), (None, Some(3)) | (Some(3), None)),\n                \"assertion failed: unexpected result `{:?}`\\\n            \\n  expected `(None, Some(3))` or `(Some(3), None)`\",\n                (r, s),\n            );\n        }\n\n        let x = Arc::new(3);\n        assert_eq!(Arc::into_inner(x), Some(3));\n\n        let x = Arc::new(4);\n        let y = Arc::clone(&x);\n        assert_eq!(Arc::into_inner(x), None);\n        assert_eq!(Arc::into_inner(y), Some(4));\n\n        let x = Arc::new(5);\n        let _w = Arc::downgrade(&x);\n        assert_eq!(Arc::into_inner(x), Some(5));\n    }\n\n    #[test]\n    fn into_from_raw() {\n        let x = Arc::new(Box::new(\"hello\"));\n        let y = x.clone();\n\n        let x_ptr = Arc::into_raw(x);\n        drop(y);\n        unsafe {\n            assert_eq!(**x_ptr, \"hello\");\n\n            let x = Arc::from_raw(x_ptr);\n            assert_eq!(**x, \"hello\");\n\n            assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok(\"hello\"));\n        }\n    }\n\n    #[test]\n    fn test_into_from_raw_unsized() {\n        use std::fmt::Display;\n\n        let arc: Arc<str> = Arc::from(\"foo\");\n\n        let ptr = Arc::into_raw(arc.clone());\n        let arc2 = unsafe { Arc::from_raw(ptr) };\n\n        assert_eq!(unsafe { &*ptr }, \"foo\");\n        assert_eq!(arc, arc2);\n\n        #[cfg(portable_atomic_unstable_coerce_unsized)]\n        let arc: Arc<dyn Display> = Arc::new(123);\n        // TODO: This is a workaround in case CoerceUnsized is not available - remove this once it is no longer needed\n        #[cfg(not(portable_atomic_unstable_coerce_unsized))]\n        let arc: Arc<dyn Display> = Arc::from(Box::new(123) as Box<dyn Display>);\n\n        let ptr = Arc::into_raw(arc.clone());\n        let arc2 = unsafe { Arc::from_raw(ptr) };\n\n        assert_eq!(unsafe { &*ptr }.to_string(), \"123\");\n        assert_eq!(arc2.to_string(), \"123\");\n    }\n\n    #[test]\n    fn into_from_weak_raw() {\n        let x = Arc::new(Box::new(\"hello\"));\n        let y = Arc::downgrade(&x);\n\n        let y_ptr = Weak::into_raw(y);\n        unsafe {\n            assert_eq!(**y_ptr, \"hello\");\n\n            let y = Weak::from_raw(y_ptr);\n            let y_up = Weak::upgrade(&y).unwrap();\n            assert_eq!(**y_up, \"hello\");\n            drop(y_up);\n\n            assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok(\"hello\"));\n        }\n    }\n\n    // TODO: See Weak::from_raw\n    // #[test]\n    // fn test_into_from_weak_raw_unsized() {\n    //     use std::fmt::Display;\n\n    //     let arc: Arc<str> = Arc::from(\"foo\");\n    //     let weak: Weak<str> = Arc::downgrade(&arc);\n\n    //     let ptr = Weak::into_raw(weak.clone());\n    //     let weak2 = unsafe { Weak::from_raw(ptr) };\n\n    //     assert_eq!(unsafe { &*ptr }, \"foo\");\n    //     assert!(weak.ptr_eq(&weak2));\n\n    //     // TODO: CoerceUnsized is needed to cast to Arc<dyn ..>\n    //     // (may be possible to support this with portable_atomic_unstable_coerce_unsized cfg option)\n    //     // let arc: Arc<dyn Display> = Arc::new(123);\n    //     let arc: Arc<dyn Display> = Arc::from(Box::new(123) as Box<dyn Display>);\n    //     let weak: Weak<dyn Display> = Arc::downgrade(&arc);\n\n    //     let ptr = Weak::into_raw(weak.clone());\n    //     let weak2 = unsafe { Weak::from_raw(ptr) };\n\n    //     assert_eq!(unsafe { &*ptr }.to_string(), \"123\");\n    //     assert!(weak.ptr_eq(&weak2));\n    // }\n\n    #[test]\n    fn test_cow_arc_clone_make_mut() {\n        let mut cow0 = Arc::new(75);\n        let mut cow1 = cow0.clone();\n        let mut cow2 = cow1.clone();\n\n        assert_eq!(75, *Arc::make_mut(&mut cow0));\n        assert_eq!(75, *Arc::make_mut(&mut cow1));\n        assert_eq!(75, *Arc::make_mut(&mut cow2));\n\n        *Arc::make_mut(&mut cow0) += 1;\n        *Arc::make_mut(&mut cow1) += 2;\n        *Arc::make_mut(&mut cow2) += 3;\n\n        assert_eq!(76, *cow0);\n        assert_eq!(77, *cow1);\n        assert_eq!(78, *cow2);\n\n        // none should point to the same backing memory\n        assert_ne!(*cow0, *cow1);\n        assert_ne!(*cow0, *cow2);\n        assert_ne!(*cow1, *cow2);\n    }\n\n    #[test]\n    fn test_cow_arc_clone_unique2() {\n        let mut cow0 = Arc::new(75);\n        let cow1 = cow0.clone();\n        let cow2 = cow1.clone();\n\n        assert_eq!(75, *cow0);\n        assert_eq!(75, *cow1);\n        assert_eq!(75, *cow2);\n\n        *Arc::make_mut(&mut cow0) += 1;\n        assert_eq!(76, *cow0);\n        assert_eq!(75, *cow1);\n        assert_eq!(75, *cow2);\n\n        // cow1 and cow2 should share the same contents\n        // cow0 should have a unique reference\n        assert_ne!(*cow0, *cow1);\n        assert_ne!(*cow0, *cow2);\n        assert_eq!(*cow1, *cow2);\n    }\n\n    #[test]\n    fn test_cow_arc_clone_weak() {\n        let mut cow0 = Arc::new(75);\n        let cow1_weak = Arc::downgrade(&cow0);\n\n        assert_eq!(75, *cow0);\n        assert_eq!(75, *cow1_weak.upgrade().unwrap());\n\n        *Arc::make_mut(&mut cow0) += 1;\n\n        assert_eq!(76, *cow0);\n        assert!(cow1_weak.upgrade().is_none());\n    }\n\n    #[test]\n    fn test_live() {\n        let x = Arc::new(5);\n        let y = Arc::downgrade(&x);\n        assert!(y.upgrade().is_some());\n    }\n\n    #[test]\n    fn test_dead() {\n        let x = Arc::new(5);\n        let y = Arc::downgrade(&x);\n        drop(x);\n        assert!(y.upgrade().is_none());\n    }\n\n    #[test]\n    fn weak_self_cyclic() {\n        struct Cycle {\n            x: Mutex<Option<Weak<Cycle>>>,\n        }\n\n        let a = Arc::new(Cycle { x: Mutex::new(None) });\n        let b = Arc::downgrade(&a.clone());\n        *a.x.lock().unwrap() = Some(b);\n\n        // hopefully we don't double-free (or leak)...\n    }\n\n    #[test]\n    fn drop_arc() {\n        let mut canary = AtomicUsize::new(0);\n        let x = Arc::new(Canary(&mut canary as *mut AtomicUsize));\n        drop(x);\n        assert_eq!(canary.load(Acquire), 1);\n    }\n\n    #[test]\n    fn drop_arc_weak() {\n        let mut canary = AtomicUsize::new(0);\n        let arc = Arc::new(Canary(&mut canary as *mut AtomicUsize));\n        let arc_weak = Arc::downgrade(&arc);\n        assert_eq!(canary.load(Acquire), 0);\n        drop(arc);\n        assert_eq!(canary.load(Acquire), 1);\n        drop(arc_weak);\n    }\n\n    #[test]\n    fn test_strong_count() {\n        let a = Arc::new(0);\n        assert_eq!(Arc::strong_count(&a), 1);\n        let w = Arc::downgrade(&a);\n        assert_eq!(Arc::strong_count(&a), 1);\n        let b = w.upgrade().expect(\"\");\n        assert_eq!(Arc::strong_count(&b), 2);\n        assert_eq!(Arc::strong_count(&a), 2);\n        drop(w);\n        drop(a);\n        assert_eq!(Arc::strong_count(&b), 1);\n        let c = b.clone();\n        assert_eq!(Arc::strong_count(&b), 2);\n        assert_eq!(Arc::strong_count(&c), 2);\n    }\n\n    #[test]\n    fn test_weak_count() {\n        let a = Arc::new(0);\n        assert_eq!(Arc::strong_count(&a), 1);\n        assert_eq!(Arc::weak_count(&a), 0);\n        let w = Arc::downgrade(&a);\n        assert_eq!(Arc::strong_count(&a), 1);\n        assert_eq!(Arc::weak_count(&a), 1);\n        let x = w.clone();\n        assert_eq!(Arc::weak_count(&a), 2);\n        drop(w);\n        drop(x);\n        assert_eq!(Arc::strong_count(&a), 1);\n        assert_eq!(Arc::weak_count(&a), 0);\n        let c = a.clone();\n        assert_eq!(Arc::strong_count(&a), 2);\n        assert_eq!(Arc::weak_count(&a), 0);\n        let d = Arc::downgrade(&c);\n        assert_eq!(Arc::weak_count(&c), 1);\n        assert_eq!(Arc::strong_count(&c), 2);\n\n        drop(a);\n        drop(c);\n        drop(d);\n    }\n\n    #[test]\n    fn show_arc() {\n        let a = Arc::new(5);\n        assert_eq!(format!(\"{:?}\", a), \"5\");\n    }\n\n    // Make sure deriving works with Arc<T>\n    #[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]\n    struct _Foo {\n        inner: Arc<i32>,\n    }\n\n    #[test]\n    fn test_unsized() {\n        #[cfg(portable_atomic_unstable_coerce_unsized)]\n        let x: Arc<[i32]> = Arc::new([1, 2, 3]);\n        // TODO: This is a workaround in case CoerceUnsized is not available - remove this once it is no longer needed\n        #[cfg(not(portable_atomic_unstable_coerce_unsized))]\n        let x: Arc<[i32]> = Arc::from(Box::new([1, 2, 3]) as Box<[i32]>);\n        assert_eq!(format!(\"{:?}\", x), \"[1, 2, 3]\");\n        let y = Arc::downgrade(&x.clone());\n        drop(x);\n        assert!(y.upgrade().is_none());\n    }\n\n    #[test]\n    fn test_maybe_thin_unsized() {\n        // If/when custom thin DSTs exist, this test should be updated to use one\n        use std::ffi::{CStr, CString};\n\n        let x: Arc<CStr> = Arc::from(CString::new(\"swordfish\").unwrap().into_boxed_c_str());\n        assert_eq!(format!(\"{:?}\", x), \"\\\"swordfish\\\"\");\n        let y: Weak<CStr> = Arc::downgrade(&x);\n        drop(x);\n\n        // At this point, the weak points to a dropped DST\n        assert!(y.upgrade().is_none());\n        // But we still need to be able to get the alloc layout to drop.\n        // CStr has no drop glue, but custom DSTs might, and need to work.\n        drop(y);\n    }\n\n    #[test]\n    fn test_from_owned() {\n        let foo = 123;\n        let foo_arc = Arc::from(foo);\n        assert_eq!(123, *foo_arc);\n    }\n\n    #[test]\n    fn test_new_weak() {\n        let foo: Weak<usize> = Weak::new();\n        assert!(foo.upgrade().is_none());\n    }\n\n    #[test]\n    fn test_ptr_eq() {\n        let five = Arc::new(5);\n        let same_five = five.clone();\n        let other_five = Arc::new(5);\n\n        assert!(Arc::ptr_eq(&five, &same_five));\n        assert!(!Arc::ptr_eq(&five, &other_five));\n    }\n\n    #[test]\n    #[cfg_attr(target_os = \"emscripten\", ignore = \"thread::spawn doesn't work on emscripten\")]\n    fn test_weak_count_locked() {\n        let mut a = Arc::new(AtomicBool::new(false));\n        let a2 = a.clone();\n        let t = thread::spawn(move || {\n            // Miri is too slow\n            let count = if cfg!(miri) { 1_000 } else { 1_000_000 };\n            for _i in 0..count {\n                Arc::get_mut(&mut a);\n            }\n            a.store(true, SeqCst);\n        });\n\n        while !a2.load(SeqCst) {\n            let n = Arc::weak_count(&a2);\n            assert!(n < 2, \"bad weak count: {}\", n);\n            #[cfg(miri)] // Miri's scheduler does not guarantee liveness, and thus needs this hint.\n            std::hint::spin_loop();\n        }\n        t.join().unwrap();\n    }\n\n    #[test]\n    fn test_from_str() {\n        let r: Arc<str> = Arc::from(\"foo\");\n\n        assert_eq!(&r[..], \"foo\");\n    }\n\n    #[test]\n    fn test_copy_from_slice() {\n        let s: &[u32] = &[1, 2, 3];\n        let r: Arc<[u32]> = Arc::from(s);\n\n        assert_eq!(&r[..], [1, 2, 3]);\n    }\n\n    #[test]\n    fn test_clone_from_slice() {\n        #[derive(Clone, Debug, Eq, PartialEq)]\n        struct X(u32);\n\n        let s: &[X] = &[X(1), X(2), X(3)];\n        let r: Arc<[X]> = Arc::from(s);\n\n        assert_eq!(&r[..], s);\n    }\n\n    #[test]\n    #[should_panic = \"test_clone_from_slice_panic\"]\n    fn test_clone_from_slice_panic() {\n        struct Fail(u32, String);\n\n        impl Clone for Fail {\n            fn clone(&self) -> Fail {\n                if self.0 == 2 {\n                    panic!(\"test_clone_from_slice_panic\");\n                }\n                Fail(self.0, self.1.clone())\n            }\n        }\n\n        let s: &[Fail] =\n            &[Fail(0, \"foo\".to_owned()), Fail(1, \"bar\".to_owned()), Fail(2, \"baz\".to_owned())];\n\n        // Should panic, but not cause memory corruption\n        let _r: Arc<[Fail]> = Arc::from(s);\n    }\n\n    #[test]\n    fn test_from_box() {\n        let b: Box<u32> = Box::new(123);\n        let r: Arc<u32> = Arc::from(b);\n\n        assert_eq!(*r, 123);\n    }\n\n    #[test]\n    fn test_from_box_str() {\n        let s = String::from(\"foo\").into_boxed_str();\n        let r: Arc<str> = Arc::from(s);\n\n        assert_eq!(&r[..], \"foo\");\n    }\n\n    #[test]\n    fn test_from_box_slice() {\n        let s = vec![1, 2, 3].into_boxed_slice();\n        let r: Arc<[u32]> = Arc::from(s);\n\n        assert_eq!(&r[..], [1, 2, 3]);\n    }\n\n    #[test]\n    fn test_from_box_trait() {\n        use std::fmt::Display;\n\n        let b: Box<dyn Display> = Box::new(123);\n        let r: Arc<dyn Display> = Arc::from(b);\n\n        assert_eq!(r.to_string(), \"123\");\n    }\n\n    #[test]\n    fn test_from_box_trait_zero_sized() {\n        use std::fmt::Debug;\n\n        let b: Box<dyn Debug> = Box::new(());\n        let r: Arc<dyn Debug> = Arc::from(b);\n\n        assert_eq!(format!(\"{:?}\", r), \"()\");\n    }\n\n    #[test]\n    fn test_from_vec() {\n        let v = vec![1, 2, 3];\n        let r: Arc<[u32]> = Arc::from(v);\n\n        assert_eq!(&r[..], [1, 2, 3]);\n    }\n\n    #[test]\n    fn test_downcast() {\n        use std::any::Any;\n\n        #[cfg(portable_atomic_unstable_coerce_unsized)]\n        let r1: Arc<dyn Any + Send + Sync> = Arc::new(i32::MAX);\n        // TODO: This is a workaround in case CoerceUnsized is not available - remove this once it is no longer needed\n        #[cfg(not(portable_atomic_unstable_coerce_unsized))]\n        let r1: Arc<dyn Any + Send + Sync> =\n            Arc::from(Box::new(i32::MAX) as Box<dyn Any + Send + Sync>);\n\n        #[cfg(portable_atomic_unstable_coerce_unsized)]\n        let r2: Arc<dyn Any + Send + Sync> = Arc::new(\"abc\");\n        // TODO: This is a workaround in case CoerceUnsized is not available - remove this once it is no longer needed\n        #[cfg(not(portable_atomic_unstable_coerce_unsized))]\n        let r2: Arc<dyn Any + Send + Sync> =\n            Arc::from(Box::new(\"abc\") as Box<dyn Any + Send + Sync>);\n\n        assert!(r1.clone().downcast::<u32>().is_err());\n\n        let r1i32 = r1.downcast::<i32>();\n        assert!(r1i32.is_ok());\n        assert_eq!(r1i32.unwrap(), Arc::new(i32::MAX));\n\n        assert!(r2.clone().downcast::<i32>().is_err());\n\n        let r2str = r2.downcast::<&'static str>();\n        assert!(r2str.is_ok());\n        assert_eq!(r2str.unwrap(), Arc::new(\"abc\"));\n    }\n\n    #[test]\n    fn test_array_from_slice() {\n        let v = vec![1, 2, 3];\n        let r: Arc<[u32]> = Arc::from(v);\n\n        let a: Result<Arc<[u32; 3]>, _> = r.clone().try_into();\n        assert!(a.is_ok());\n\n        let a: Result<Arc<[u32; 2]>, _> = r.clone().try_into();\n        assert!(a.is_err());\n    }\n\n    #[test]\n    fn test_arc_cyclic_with_zero_refs() {\n        struct ZeroRefs {\n            inner: Weak<ZeroRefs>,\n        }\n        let zero_refs = Arc::new_cyclic(|inner| {\n            assert_eq!(inner.strong_count(), 0);\n            assert!(inner.upgrade().is_none());\n            ZeroRefs { inner: Weak::new() }\n        });\n\n        assert_eq!(Arc::strong_count(&zero_refs), 1);\n        assert_eq!(Arc::weak_count(&zero_refs), 0);\n        assert_eq!(zero_refs.inner.strong_count(), 0);\n        assert_eq!(zero_refs.inner.weak_count(), 0);\n    }\n\n    #[test]\n    fn test_arc_new_cyclic_one_ref() {\n        struct OneRef {\n            inner: Weak<OneRef>,\n        }\n        let one_ref = Arc::new_cyclic(|inner| {\n            assert_eq!(inner.strong_count(), 0);\n            assert!(inner.upgrade().is_none());\n            OneRef { inner: inner.clone() }\n        });\n\n        assert_eq!(Arc::strong_count(&one_ref), 1);\n        assert_eq!(Arc::weak_count(&one_ref), 1);\n\n        let one_ref2 = Weak::upgrade(&one_ref.inner).unwrap();\n        assert!(Arc::ptr_eq(&one_ref, &one_ref2));\n\n        assert_eq!(Arc::strong_count(&one_ref), 2);\n        assert_eq!(Arc::weak_count(&one_ref), 1);\n    }\n\n    #[test]\n    fn test_arc_cyclic_two_refs() {\n        struct TwoRefs {\n            inner1: Weak<TwoRefs>,\n            inner2: Weak<TwoRefs>,\n        }\n        let two_refs = Arc::new_cyclic(|inner| {\n            assert_eq!(inner.strong_count(), 0);\n            assert!(inner.upgrade().is_none());\n\n            let inner1 = inner.clone();\n            let inner2 = inner1.clone();\n\n            TwoRefs { inner1, inner2 }\n        });\n\n        assert_eq!(Arc::strong_count(&two_refs), 1);\n        assert_eq!(Arc::weak_count(&two_refs), 2);\n\n        let two_refs1 = Weak::upgrade(&two_refs.inner1).unwrap();\n        assert!(Arc::ptr_eq(&two_refs, &two_refs1));\n\n        let two_refs2 = Weak::upgrade(&two_refs.inner2).unwrap();\n        assert!(Arc::ptr_eq(&two_refs, &two_refs2));\n\n        assert_eq!(Arc::strong_count(&two_refs), 3);\n        assert_eq!(Arc::weak_count(&two_refs), 2);\n    }\n\n    /// Test for Arc::drop bug (https://github.com/rust-lang/rust/issues/55005)\n    #[test]\n    #[cfg(miri)] // relies on Stacked Borrows in Miri\n    fn arc_drop_dereferenceable_race() {\n        // The bug seems to take up to 700 iterations to reproduce with most seeds (tested 0-9).\n        for _ in 0..750 {\n            let arc_1 = Arc::new(());\n            let arc_2 = arc_1.clone();\n            let thread = thread::spawn(|| drop(arc_2));\n            // Spin a bit; makes the race more likely to appear\n            let mut i = 0;\n            while i < 256 {\n                i += 1;\n            }\n            drop(arc_1);\n            thread.join().unwrap();\n        }\n    }\n}\n"
    },
    {
      "package": "proc-macro2@1.0.107",
      "sourcePath": "README.md",
      "sha256": "8eebdcf2f9a5034693589a9982adf06c2aac5c9f078c07a44400d293ed5b4a8e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# proc-macro2\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/proc--macro2-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/proc-macro2)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/proc-macro2.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/proc-macro2)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-proc--macro2-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/proc-macro2)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/proc-macro2/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/proc-macro2/actions?query=branch%3Amaster)\n\nA wrapper around the procedural macro API of the compiler's `proc_macro` crate.\nThis library serves two purposes:\n\n- **Bring proc-macro-like functionality to other contexts like build.rs and\n  main.rs.** Types from `proc_macro` are entirely specific to procedural macros\n  and cannot ever exist in code outside of a procedural macro. Meanwhile\n  `proc_macro2` types may exist anywhere including non-macro code. By developing\n  foundational libraries like [syn] and [quote] against `proc_macro2` rather\n  than `proc_macro`, the procedural macro ecosystem becomes easily applicable to\n  many other use cases and we avoid reimplementing non-macro equivalents of\n  those libraries.\n\n- **Make procedural macros unit testable.** As a consequence of being specific\n  to procedural macros, nothing that uses `proc_macro` can be executed from a\n  unit test. In order for helper libraries or components of a macro to be\n  testable in isolation, they must be implemented using `proc_macro2`.\n\n[syn]: https://github.com/dtolnay/syn\n[quote]: https://github.com/dtolnay/quote\n\n## Usage\n\n```toml\n[dependencies]\nproc-macro2 = \"1.0\"\n```\n\nThe skeleton of a typical procedural macro typically looks like this:\n\n```rust\nextern crate proc_macro;\n\n#[proc_macro_derive(MyDerive)]\npub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {\n    let input = proc_macro2::TokenStream::from(input);\n\n    let output: proc_macro2::TokenStream = {\n        /* transform input */\n    };\n\n    proc_macro::TokenStream::from(output)\n}\n```\n\nIf parsing with [Syn], you'll use [`parse_macro_input!`] instead to propagate\nparse errors correctly back to the compiler when parsing fails.\n\n[`parse_macro_input!`]: https://docs.rs/syn/3/syn/macro.parse_macro_input.html\n\n## Unstable features\n\nThe default feature set of proc-macro2 tracks the most recent stable compiler\nAPI. Functionality in `proc_macro` that is not yet stable is not exposed by\nproc-macro2 by default.\n\nTo opt into the additional APIs available in the most recent nightly compiler,\nthe `procmacro2_semver_exempt` config flag must be passed to rustc. We will\npolyfill those nightly-only APIs back to Rust 1.71.0. As these are unstable APIs\nthat track the nightly compiler, minor versions of proc-macro2 may make breaking\nchanges to them at any time.\n\n```\nRUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build\n```\n\nNote that this must not only be done for your crate, but for any crate that\ndepends on your crate. This infectious nature is intentional, as it serves as a\nreminder that you are outside of the normal semver guarantees.\n\nSemver exempt methods are marked as such in the proc-macro2 documentation.\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "quote@1.0.47",
      "sourcePath": "README.md",
      "sha256": "9d6af721967088b8263c0544c0c3c459206998252dd5632a3bdf87cb27ec92be",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Rust Quasi-Quoting\n==================\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/quote-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/quote)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/quote.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/quote)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-quote-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/quote)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/quote/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/quote/actions?query=branch%3Amaster)\n\nThis crate provides the [`quote!`] macro for turning Rust syntax tree data\nstructures into tokens of source code.\n\n[`quote!`]: https://docs.rs/quote/1.0/quote/macro.quote.html\n\nProcedural macros in Rust receive a stream of tokens as input, execute arbitrary\nRust code to determine how to manipulate those tokens, and produce a stream of\ntokens to hand back to the compiler to compile into the caller's crate.\nQuasi-quoting is a solution to one piece of that &mdash; producing tokens to\nreturn to the compiler.\n\nThe idea of quasi-quoting is that we write *code* that we treat as *data*.\nWithin the `quote!` macro, we can write what looks like code to our text editor\nor IDE. We get all the benefits of the editor's brace matching, syntax\nhighlighting, indentation, and maybe autocompletion. But rather than compiling\nthat as code into the current crate, we can treat it as data, pass it around,\nmutate it, and eventually hand it back to the compiler as tokens to compile into\nthe macro caller's crate.\n\nThis crate is motivated by the procedural macro use case, but is a\ngeneral-purpose Rust quasi-quoting library and is not specific to procedural\nmacros.\n\n```toml\n[dependencies]\nquote = \"1.0\"\n```\n\n[*Release notes*](https://github.com/dtolnay/quote/releases)\n\n<br>\n\n## Syntax\n\nThe quote crate provides a [`quote!`] macro within which you can write Rust code\nthat gets packaged into a [`TokenStream`] and can be treated as data. You should\nthink of `TokenStream` as representing a fragment of Rust source code.\n\n[`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html\n\nWithin the `quote!` macro, interpolation is done with `#var`. Any type\nimplementing the [`quote::ToTokens`] trait can be interpolated. This includes\nmost Rust primitive types as well as most of the syntax tree types from [`syn`].\n\n[`quote::ToTokens`]: https://docs.rs/quote/1.0/quote/trait.ToTokens.html\n[`syn`]: https://github.com/dtolnay/syn\n\n```rust\nlet tokens = quote! {\n    struct SerializeWith #generics #where_clause {\n        value: &'a #field_ty,\n        phantom: core::marker::PhantomData<#item_ty>,\n    }\n\n    impl #generics serde::Serialize for SerializeWith #generics #where_clause {\n        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n        where\n            S: serde::Serializer,\n        {\n            #path(self.value, serializer)\n        }\n    }\n\n    SerializeWith {\n        value: #value,\n        phantom: core::marker::PhantomData::<#item_ty>,\n    }\n};\n```\n\n<br>\n\n## Repetition\n\nRepetition is done using `#(...)*` or `#(...),*` similar to `macro_rules!`. This\niterates through the elements of any variable interpolated within the repetition\nand inserts a copy of the repetition body for each one. The variables in an\ninterpolation may be a `Vec`, slice, `BTreeSet`, or any `Iterator`.\n\n- `#(#var)*` — no separators\n- `#(#var),*` — the character before the asterisk is used as a separator\n- `#( struct #var; )*` — the repetition can contain other things\n- `#( #k => println!(\"{}\", #v), )*` — even multiple interpolations\n\nNote that there is a difference between `#(#var ,)*` and `#(#var),*`—the latter\ndoes not produce a trailing comma. This matches the behavior of delimiters in\n`macro_rules!`.\n\n<br>\n\n## Returning tokens to the compiler\n\nThe `quote!` macro evaluates to an expression of type\n`proc_macro2::TokenStream`. Meanwhile Rust procedural macros are expected to\nreturn the type `proc_macro::TokenStream`.\n\nThe difference between the two types is that `proc_macro` types are entirely\nspecific to procedural macros and cannot ever exist in code outside of a\nprocedural macro, while `proc_macro2` types may exist anywhere including tests\nand non-macro code like main.rs and build.rs. This is why even the procedural\nmacro ecosystem is largely built around `proc_macro2`, because that ensures the\nlibraries are unit testable and accessible in non-macro contexts.\n\nThere is a [`From`]-conversion in both directions so returning the output of\n`quote!` from a procedural macro usually looks like `tokens.into()` or\n`proc_macro::TokenStream::from(tokens)`.\n\n[`From`]: https://doc.rust-lang.org/std/convert/trait.From.html\n\n<br>\n\n## Examples\n\n### Combining quoted fragments\n\nUsually you don't end up constructing an entire final `TokenStream` in one\npiece. Different parts may come from different helper functions. The tokens\nproduced by `quote!` themselves implement `ToTokens` and so can be interpolated\ninto later `quote!` invocations to build up a final result.\n\n```rust\nlet type_definition = quote! {...};\nlet methods = quote! {...};\n\nlet tokens = quote! {\n    #type_definition\n    #methods\n};\n```\n\n### Constructing identifiers\n\nSuppose we have an identifier `ident` which came from somewhere in a macro\ninput and we need to modify it in some way for the macro output. Let's consider\nprepending the identifier with an underscore.\n\nSimply interpolating the identifier next to an underscore will not have the\nbehavior of concatenating them. The underscore and the identifier will continue\nto be two separate tokens as if you had written `_ x`.\n\n```rust\n// incorrect\nquote! {\n    let mut _#ident = 0;\n}\n```\n\nThe solution is to build a new identifier token with the correct value. As this\nis such a common case, the `format_ident!` macro provides a convenient utility\nfor doing so correctly.\n\n```rust\nlet varname = format_ident!(\"_{}\", ident);\nquote! {\n    let mut #varname = 0;\n}\n```\n\nAlternatively, the APIs provided by Syn and proc-macro2 can be used to directly\nbuild the identifier. This is roughly equivalent to the above, but will not\nhandle `ident` being a raw identifier.\n\n```rust\nlet concatenated = format!(\"_{}\", ident);\nlet varname = syn::Ident::new(&concatenated, ident.span());\nquote! {\n    let mut #varname = 0;\n}\n```\n\n### Making method calls\n\nLet's say our macro requires some type specified in the macro input to have a\nconstructor called `new`. We have the type in a variable called `field_type` of\ntype `syn::Type` and want to invoke the constructor.\n\n```rust\n// incorrect\nquote! {\n    let value = #field_type::new();\n}\n```\n\nThis works only sometimes. If `field_type` is `String`, the expanded code\ncontains `String::new()` which is fine. But if `field_type` is something like\n`Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid syntax.\nOrdinarily in handwritten Rust we would write `Vec::<i32>::new()` but for macros\noften the following is more convenient.\n\n```rust\nquote! {\n    let value = <#field_type>::new();\n}\n```\n\nThis expands to `<Vec<i32>>::new()` which behaves correctly.\n\nA similar pattern is appropriate for trait methods.\n\n```rust\nquote! {\n    let value = <#field_type as core::default::Default>::default();\n}\n```\n\n<br>\n\n## Hygiene\n\nAny interpolated tokens preserve the `Span` information provided by their\n`ToTokens` implementation. Tokens that originate within a `quote!` invocation\nare spanned with [`Span::call_site()`].\n\n[`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site\n\nA different span can be provided explicitly through the [`quote_spanned!`]\nmacro.\n\n[`quote_spanned!`]: https://docs.rs/quote/1.0/quote/macro.quote_spanned.html\n\n<br>\n\n## Non-macro code generators\n\nWhen using `quote` in a build.rs or main.rs and writing the output out to a\nfile, consider having the code generator pass the tokens through [prettyplease]\nbefore writing. This way if an error occurs in the generated code it is\nconvenient for a human to read and debug.\n\nBe aware that no kind of hygiene or span information is retained when tokens are\nwritten to a file; the conversion from tokens to source code is lossy.\n\nExample usage in build.rs:\n\n```rust\nlet output = quote! { ... };\nlet syntax_tree = syn::parse2(output).unwrap();\nlet formatted = prettyplease::unparse(&syntax_tree);\n\nlet out_dir = env::var_os(\"OUT_DIR\").unwrap();\nlet dest_path = Path::new(&out_dir).join(\"out.rs\");\nfs::write(dest_path, formatted).unwrap();\n```\n\n[prettyplease]: https://github.com/dtolnay/prettyplease\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "radium@0.7.0",
      "sourcePath": "LICENSE.txt",
      "sha256": "13f4cc9fbc8d4a447b28aa84019c10ad4abf4b5f6919db061bf6690ccc23bc02",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "MIT License\n\nCopyright (c) 2019 kneecaw (Nika Layzell)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
    },
    {
      "package": "rctree@0.5.0",
      "sourcePath": "README.md",
      "sha256": "8b89a6f85cd86ba8525d96a9fe29d9907e3c8f8e000eda366987bd590dbfa4a3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# rctree\n![Build Status](https://github.com/RazrFalcon/rctree/workflows/rctree/badge.svg)\n[![Crates.io](https://img.shields.io/crates/v/rctree.svg)](https://crates.io/crates/rctree)\n[![Documentation](https://docs.rs/rctree/badge.svg)](https://docs.rs/rctree)\n[![Rust 1.22+](https://img.shields.io/badge/rust-1.22+-orange.svg)](https://www.rust-lang.org)\n![](https://img.shields.io/badge/unsafe-forbidden-brightgreen.svg)\n\n*rctree* is a \"DOM-like\" tree implemented using reference counting.\n\n### Origin\n\nThis is a fork of the [rust-forest](https://github.com/SimonSapin/rust-forest) rctree.\n\n### Details\n\n\"DOM-like\" here means that data structures can be used to represent\nthe parsed content of an HTML or XML document,\nlike [*the* DOM](https://dom.spec.whatwg.org/) does,\nbut don't necessarily have the exact same API as the DOM.\nThat is:\n\n* A tree is made up of nodes.\n* Each node has zero or more *child* nodes, which are ordered.\n* Each node has a no more than one *parent*, the node that it is a *child* of.\n* A node without a *parent* is called a *root*.\n* As a consequence, each node may also have *siblings*: its *parent*'s other *children*, if any.\n* From any given node, access to its\n  parent, previous sibling, next sibling, first child, and last child (if any)\n  can take no more than *O(1)* time.\n* Each node also has data associated to it,\n  which for the purpose of this project is purely generic.\n  For an HTML document, the data would be either the text of a text node,\n  or the name and attributes of an element node.\n* The tree is mutable:\n  nodes (with their sub-trees) can be inserted or removed anywhere in the tree.\n\nThe lifetime of nodes is managed through *reference counting*.\nTo avoid reference cycles which would cause memory leaks, the tree is *asymmetric*:\neach node holds optional *strong references* to its next sibling and first child,\nbut only optional *weak references* to its parent, previous sibling, and last child.\n\nNodes are destroyed as soon as there is no strong reference left to them.\nThe structure is such that holding a reference to the root\nis sufficient to keep the entire tree alive.\nHowever, if for example the only reference that exists from outside the tree\nis one that you use to traverse it,\nyou will not be able to go back \"up\" the tree to ancestors and previous siblings after going \"down\",\nas those nodes will have been destroyed.\n\nWeak references to destroyed nodes are treated as if they were not set at all.\n(E.g. a node can become a root when its parent is destroyed.)\n\nSince nodes are *aliased* (have multiple references to them),\n[`RefCell`](http://doc.rust-lang.org/std/cell/index.html) is used for interior mutability.\n\nAdvantages:\n\n* A single `Node` user-visible type to manipulate the tree, with methods.\n* Memory is freed as soon as it becomes unused (if parts of the tree are removed).\n\nDisadvantages:\n\n* The tree can only be accessed from the thread is was created in.\n* Any tree manipulation, including read-only traversals,\n  requires incrementing and decrementing reference counts,\n  which causes run-time overhead.\n* Nodes are allocated individually, which may cause memory fragmentation and hurt performance.\n\n### License\n\n*rctree* is licensed under the **MIT**.\n"
    },
    {
      "package": "regex@1.13.1",
      "sourcePath": "README.md",
      "sha256": "ce1a8faf72cf8f0e28a28658c59033b02726e3caecd9a3d358b4c6f6cd3e6c24",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "regex\n=====\nThis crate provides routines for searching strings for matches of a [regular\nexpression] (aka \"regex\"). The regex syntax supported by this crate is similar\nto other regex engines, but it lacks several features that are not known how to\nimplement efficiently. This includes, but is not limited to, look-around and\nbackreferences. In exchange, all regex searches in this crate have worst case\n`O(m * n)` time complexity, where `m` is proportional to the size of the regex\nand `n` is proportional to the size of the string being searched.\n\n[regular expression]: https://en.wikipedia.org/wiki/Regular_expression\n\n[![Build status](https://github.com/rust-lang/regex/workflows/ci/badge.svg)](https://github.com/rust-lang/regex/actions)\n[![Crates.io](https://img.shields.io/crates/v/regex.svg)](https://crates.io/crates/regex)\n\n### Documentation\n\n[Module documentation with examples](https://docs.rs/regex).\nThe module documentation also includes a comprehensive description of the\nsyntax supported.\n\nDocumentation with examples for the various matching functions and iterators\ncan be found on the\n[`Regex` type](https://docs.rs/regex/*/regex/struct.Regex.html).\n\n### Usage\n\nTo bring this crate into your repository, either add `regex` to your\n`Cargo.toml`, or run `cargo add regex`.\n\nHere's a simple example that matches a date in YYYY-MM-DD format and prints the\nyear, month and day:\n\n```rust\nuse regex::Regex;\n\nfn main() {\n    let re = Regex::new(r\"(?x)\n(?P<year>\\d{4})  # the year\n-\n(?P<month>\\d{2}) # the month\n-\n(?P<day>\\d{2})   # the day\n\").unwrap();\n\n    let caps = re.captures(\"2010-03-14\").unwrap();\n    assert_eq!(\"2010\", &caps[\"year\"]);\n    assert_eq!(\"03\", &caps[\"month\"]);\n    assert_eq!(\"14\", &caps[\"day\"]);\n}\n```\n\nIf you have lots of dates in text that you'd like to iterate over, then it's\neasy to adapt the above example with an iterator:\n\n```rust\nuse regex::Regex;\n\nfn main() {\n    let re = Regex::new(r\"(\\d{4})-(\\d{2})-(\\d{2})\").unwrap();\n    let hay = \"On 2010-03-14, foo happened. On 2014-10-14, bar happened.\";\n\n    let mut dates = vec![];\n    for (_, [year, month, day]) in re.captures_iter(hay).map(|c| c.extract()) {\n        dates.push((year, month, day));\n    }\n    assert_eq!(dates, vec![\n      (\"2010\", \"03\", \"14\"),\n      (\"2014\", \"10\", \"14\"),\n    ]);\n}\n```\n\n### Usage: Avoid compiling the same regex in a loop\n\nIt is an anti-pattern to compile the same regular expression in a loop since\ncompilation is typically expensive. (It takes anywhere from a few microseconds\nto a few **milliseconds** depending on the size of the regex.) Not only is\ncompilation itself expensive, but this also prevents optimizations that reuse\nallocations internally to the matching engines.\n\nIn Rust, it can sometimes be a pain to pass regular expressions around if\nthey're used from inside a helper function. Instead, we recommend using\n[`std::sync::LazyLock`], or the [`once_cell`] crate,\nif you can't use the standard library.\n\nThis example shows how to use `std::sync::LazyLock`:\n\n```rust\nuse std::sync::LazyLock;\n\nuse regex::Regex;\n\nfn some_helper_function(haystack: &str) -> bool {\n    static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r\"...\").unwrap());\n    RE.is_match(haystack)\n}\n\nfn main() {\n    assert!(some_helper_function(\"abc\"));\n    assert!(!some_helper_function(\"ac\"));\n}\n```\n\nSpecifically, in this example, the regex will be compiled when it is used for\nthe first time. On subsequent uses, it will reuse the previous compilation.\n\nThe [`regex!`] macro can also be used, which handles lazy compilation.\n\n[`std::sync::LazyLock`]: https://doc.rust-lang.org/std/sync/struct.LazyLock.html\n[`once_cell`]: https://crates.io/crates/once_cell\n[`regex!`]: https://docs.rs/regex/*/regex/macro.regex.html\n\n### Usage: match regular expressions on `&[u8]`\n\nThe main API of this crate (`regex::Regex`) requires the caller to pass a\n`&str` for searching. In Rust, an `&str` is required to be valid UTF-8, which\nmeans the main API can't be used for searching arbitrary bytes.\n\nTo match on arbitrary bytes, use the `regex::bytes::Regex` API. The API is\nidentical to the main API, except that it takes an `&[u8]` to search on instead\nof an `&str`. The `&[u8]` APIs also permit disabling Unicode mode in the regex\neven when the pattern would match invalid UTF-8. For example, `(?-u:.)` is\nnot allowed in `regex::Regex` but is allowed in `regex::bytes::Regex` since\n`(?-u:.)` matches any byte except for `\\n`. Conversely, `.` will match the\nUTF-8 encoding of any Unicode scalar value except for `\\n`.\n\nThis example shows how to find all null-terminated strings in a slice of bytes:\n\n```rust\nuse regex::bytes::Regex;\n\nlet re = Regex::new(r\"(?-u)(?<cstr>[^\\x00]+)\\x00\").unwrap();\nlet text = b\"foo\\xFFbar\\x00baz\\x00\";\n\n// Extract all of the strings without the null terminator from each match.\n// The unwrap is OK here since a match requires the `cstr` capture to match.\nlet cstrs: Vec<&[u8]> =\n    re.captures_iter(text)\n      .map(|c| c.name(\"cstr\").unwrap().as_bytes())\n      .collect();\nassert_eq!(vec![&b\"foo\\xFFbar\"[..], &b\"baz\"[..]], cstrs);\n```\n\nNotice here that the `[^\\x00]+` will match any *byte* except for `NUL`,\nincluding bytes like `\\xFF` which are not valid UTF-8. When using the main API,\n`[^\\x00]+` would instead match any valid UTF-8 sequence except for `NUL`.\n\n### Usage: match multiple regular expressions simultaneously\n\nThis demonstrates how to use a `RegexSet` to match multiple (possibly\noverlapping) regular expressions in a single scan of the search text:\n\n```rust\nuse regex::RegexSet;\n\nlet set = RegexSet::new(&[\n    r\"\\w+\",\n    r\"\\d+\",\n    r\"\\pL+\",\n    r\"foo\",\n    r\"bar\",\n    r\"barfoo\",\n    r\"foobar\",\n]).unwrap();\n\n// Iterate over and collect all of the matches.\nlet matches: Vec<_> = set.matches(\"foobar\").into_iter().collect();\nassert_eq!(matches, vec![0, 2, 3, 4, 6]);\n\n// You can also test whether a particular regex matched:\nlet matches = set.matches(\"foobar\");\nassert!(!matches.matched(5));\nassert!(matches.matched(6));\n```\n\n\n### Usage: regex internals as a library\n\nThe [`regex-automata` directory](./regex-automata/) contains a crate that\nexposes all the internal matching engines used by the `regex` crate. The\nidea is that the `regex` crate exposes a simple API for 99% of use cases, but\n`regex-automata` exposes oodles of customizable behaviors.\n\n[Documentation for `regex-automata`.](https://docs.rs/regex-automata)\n\n\n### Usage: a regular expression parser\n\nThis repository contains a crate that provides a well tested regular expression\nparser, abstract syntax and a high-level intermediate representation for\nconvenient analysis. It provides no facilities for compilation or execution.\nThis may be useful if you're implementing your own regex engine or otherwise\nneed to do analysis on the syntax of a regular expression. It is otherwise not\nrecommended for general use.\n\n[Documentation for `regex-syntax`.](https://docs.rs/regex-syntax)\n\n\n### Crate features\n\nThis crate comes with several features that permit tweaking the trade-off\nbetween binary size, compilation time and runtime performance. Users of this\ncrate can selectively disable Unicode tables, or choose from a variety of\noptimizations performed by this crate to disable.\n\nWhen all of these features are disabled, runtime match performance may be much\nworse, but if you're matching on short strings, or if high performance isn't\nnecessary, then such a configuration is perfectly serviceable. To disable\nall such features, use the following `Cargo.toml` dependency configuration:\n\n```toml\n[dependencies.regex]\nversion = \"1.3\"\ndefault-features = false\n# Unless you have a specific reason not to, it's good sense to enable standard\n# library support. It enables several optimizations and avoids spin locks. It\n# also shouldn't meaningfully impact compile times or binary size.\nfeatures = [\"std\"]\n```\n\nThis will reduce the dependency tree of `regex` down to two crates:\n`regex-syntax` and `regex-automata`.\n\nThe full set of features one can disable are\n[in the \"Crate features\" section of the documentation](https://docs.rs/regex/1.*/#crate-features).\n\n\n### Performance\n\nOne of the goals of this crate is for the regex engine to be \"fast.\" What that\nis a somewhat nebulous goal, it is usually interpreted in one of two ways.\nFirst, it means that all searches take worst case `O(m * n)` time, where\n`m` is proportional to `len(regex)` and `n` is proportional to `len(haystack)`.\nSecond, it means that even aside from the time complexity constraint, regex\nsearches are \"fast\" in practice.\n\nWhile the first interpretation is pretty unambiguous, the second one remains\nnebulous. While nebulous, it guides this crate's architecture and the sorts of\nthe trade-offs it makes. For example, here are some general architectural\nstatements that follow as a result of the goal to be \"fast\":\n\n* When given the choice between faster regex searches and faster _Rust compile\ntimes_, this crate will generally choose faster regex searches.\n* When given the choice between faster regex searches and faster _regex compile\ntimes_, this crate will generally choose faster regex searches. That is, it is\ngenerally acceptable for `Regex::new` to get a little slower if it means that\nsearches get faster. (This is a somewhat delicate balance to strike, because\nthe speed of `Regex::new` needs to remain somewhat reasonable. But this is why\none should avoid re-compiling the same regex over and over again.)\n* When given the choice between faster regex searches and simpler API\ndesign, this crate will generally choose faster regex searches. For example,\nif one didn't care about performance, we could like get rid of both of\nthe `Regex::is_match` and `Regex::find` APIs and instead just rely on\n`Regex::captures`.\n\nThere are perhaps more ways that being \"fast\" influences things.\n\nWhile this repository used to provide its own benchmark suite, it has since\nbeen moved to [rebar](https://github.com/BurntSushi/rebar). The benchmarks are\nquite extensive, and there are many more than what is shown in rebar's README\n(which is just limited to a \"curated\" set meant to compare performance between\nregex engines). To run all of this crate's benchmarks, first start by cloning\nand installing `rebar`:\n\n```text\n$ git clone https://github.com/BurntSushi/rebar\n$ cd rebar\n$ cargo install --path ./\n```\n\nThen build the benchmark harness for just this crate:\n\n```text\n$ rebar build -e '^rust/regex$'\n```\n\nRun all benchmarks for this crate as tests (each benchmark is executed once to\nensure it works):\n\n```text\n$ rebar measure -e '^rust/regex$' -t\n```\n\nRecord measurements for all benchmarks and save them to a CSV file:\n\n```text\n$ rebar measure -e '^rust/regex$' | tee results.csv\n```\n\nExplore benchmark timings:\n\n```text\n$ rebar cmp results.csv\n```\n\nSee the `rebar` documentation for more details on how it works and how to\ncompare results with other regex engines.\n\n\n### Hacking\n\nThe `regex` crate is, for the most part, a pretty thin wrapper around the\n[`meta::Regex`](https://docs.rs/regex-automata/latest/regex_automata/meta/struct.Regex.html)\nfrom the\n[`regex-automata` crate](https://docs.rs/regex-automata/latest/regex_automata/).\nTherefore, if you're looking to work on the internals of this crate, you'll\nlikely either want to look in `regex-syntax` (for parsing) or `regex-automata`\n(for construction of finite automata and the search routines).\n\nMy [blog on regex internals](https://burntsushi.net/regex-internals/)\ngoes into more depth.\n\n\n### Minimum Rust version policy\n\nThis crate's minimum supported `rustc` version is `1.65.0`.\n\nThe policy is that the minimum Rust version required to use this crate can be\nincreased in minor version updates. For example, if regex 1.0 requires Rust\n1.20.0, then regex 1.0.z for all values of `z` will also require Rust 1.20.0 or\nnewer. However, regex 1.y for `y > 0` may require a newer minimum version of\nRust.\n\n\n### License\n\nThis project is licensed under either of\n\n * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\n   https://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or\n   https://opensource.org/licenses/MIT)\n\nat your option.\n\nThe data in `regex-syntax/src/unicode_tables/` is licensed under the Unicode\nLicense Agreement\n([LICENSE-UNICODE](https://www.unicode.org/copyright.html#License)).\n"
    },
    {
      "package": "resvg@0.34.1",
      "sourcePath": "LICENSE.txt",
      "sha256": "fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n    means each individual or legal entity that creates, contributes to\n    the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n    means the combination of the Contributions of others (if any) used\n    by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n    means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n    means Source Code Form to which the initial Contributor has attached\n    the notice in Exhibit A, the Executable Form of such Source Code\n    Form, and Modifications of such Source Code Form, in each case\n    including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n    means\n\n    (a) that the initial Contributor has attached the notice described\n        in Exhibit B to the Covered Software; or\n\n    (b) that the Covered Software was made available under the terms of\n        version 1.1 or earlier of the License, but not also under the\n        terms of a Secondary License.\n\n1.6. \"Executable Form\"\n    means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n    means a work that combines Covered Software with other material, in \n    a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n    means this document.\n\n1.9. \"Licensable\"\n    means having the right to grant, to the maximum extent possible,\n    whether at the time of the initial grant or subsequently, any and\n    all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n    means any of the following:\n\n    (a) any file in Source Code Form that results from an addition to,\n        deletion from, or modification of the contents of Covered\n        Software; or\n\n    (b) any new file in Source Code Form that contains any Covered\n        Software.\n\n1.11. \"Patent Claims\" of a Contributor\n    means any patent claim(s), including without limitation, method,\n    process, and apparatus claims, in any patent Licensable by such\n    Contributor that would be infringed, but for the grant of the\n    License, by the making, using, selling, offering for sale, having\n    made, import, or transfer of either its Contributions or its\n    Contributor Version.\n\n1.12. \"Secondary License\"\n    means either the GNU General Public License, Version 2.0, the GNU\n    Lesser General Public License, Version 2.1, the GNU Affero General\n    Public License, Version 3.0, or any later versions of those\n    licenses.\n\n1.13. \"Source Code Form\"\n    means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n    means an individual or a legal entity exercising rights under this\n    License. For legal entities, \"You\" includes any entity that\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n    Licensable by such Contributor to use, reproduce, make available,\n    modify, display, perform, distribute, and otherwise exploit its\n    Contributions, either on an unmodified basis, with Modifications, or\n    as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n    for sale, have made, import, and otherwise transfer either its\n    Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n    or\n\n(b) for infringements caused by: (i) Your and any other third party's\n    modifications of Covered Software, or (ii) the combination of its\n    Contributions with other software (except as part of its Contributor\n    Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n    its Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\n    Form, as described in Section 3.1, and You must inform recipients of\n    the Executable Form how they can obtain a copy of such Source Code\n    Form by reasonable means in a timely manner, at a charge no more\n    than the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\n    License, or sublicense it under different terms, provided that the\n    license for the Executable Form does not attempt to limit or alter\n    the recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n*                                                                      *\n*  6. Disclaimer of Warranty                                           *\n*  -------------------------                                           *\n*                                                                      *\n*  Covered Software is provided under this License on an \"as is\"       *\n*  basis, without warranty of any kind, either expressed, implied, or  *\n*  statutory, including, without limitation, warranties that the       *\n*  Covered Software is free of defects, merchantable, fit for a        *\n*  particular purpose or non-infringing. The entire risk as to the     *\n*  quality and performance of the Covered Software is with You.        *\n*  Should any Covered Software prove defective in any respect, You     *\n*  (not any Contributor) assume the cost of any necessary servicing,   *\n*  repair, or correction. This disclaimer of warranty constitutes an   *\n*  essential part of this License. No use of any Covered Software is   *\n*  authorized under this License except under this disclaimer.         *\n*                                                                      *\n************************************************************************\n\n************************************************************************\n*                                                                      *\n*  7. Limitation of Liability                                          *\n*  --------------------------                                          *\n*                                                                      *\n*  Under no circumstances and under no legal theory, whether tort      *\n*  (including negligence), contract, or otherwise, shall any           *\n*  Contributor, or anyone who distributes Covered Software as          *\n*  permitted above, be liable to You for any direct, indirect,         *\n*  special, incidental, or consequential damages of any character      *\n*  including, without limitation, damages for lost profits, loss of    *\n*  goodwill, work stoppage, computer failure or malfunction, or any    *\n*  and all other commercial damages or losses, even if such party      *\n*  shall have been informed of the possibility of such damages. This   *\n*  limitation of liability shall not apply to liability for death or   *\n*  personal injury resulting from such party's negligence to the       *\n*  extent applicable law prohibits such limitation. Some               *\n*  jurisdictions do not allow the exclusion or limitation of           *\n*  incidental or consequential damages, so this exclusion and          *\n*  limitation may not apply to You.                                    *\n*                                                                      *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\n  This Source Code Form is subject to the terms of the Mozilla Public\n  License, v. 2.0. If a copy of the MPL was not distributed with this\n  file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\n  This Source Code Form is \"Incompatible With Secondary Licenses\", as\n  defined by the Mozilla Public License, v. 2.0.\n"
    },
    {
      "package": "resvg@0.34.1",
      "sourcePath": "src/filter/iir_blur.rs",
      "sha256": "b4f295e31b547ec9b3f83a6b875d0440ba7311f94e8e9f0ac6ad1eeb9ee804ac",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n// An IIR blur.\n//\n// Based on http://www.getreuer.info/home/gaussianiir\n//\n// Licensed under 'Simplified BSD License'.\n//\n//\n// Implements the fast Gaussian convolution algorithm of Alvarez and Mazorra,\n// where the Gaussian is approximated by a cascade of first-order infinite\n// impulsive response (IIR) filters.  Boundaries are handled with half-sample\n// symmetric extension.\n//\n// Gaussian convolution is approached as approximating the heat equation and\n// each timestep is performed with an efficient recursive computation.  Using\n// more steps yields a more accurate approximation of the Gaussian.  A\n// reasonable default value for `numsteps` is 4.\n//\n// Reference:\n// Alvarez, Mazorra, \"Signal and Image Restoration using Shock Filters and\n// Anisotropic Diffusion,\" SIAM J. on Numerical Analysis, vol. 31, no. 2,\n// pp. 590-605, 1994.\n\n// TODO: Blurs right and bottom sides twice for some reason.\n\nuse super::ImageRefMut;\nuse rgb::ComponentSlice;\n\nstruct BlurData {\n    width: usize,\n    height: usize,\n    sigma_x: f64,\n    sigma_y: f64,\n    steps: usize,\n}\n\n/// Applies an IIR blur.\n///\n/// Input image pixels should have a **premultiplied alpha**.\n///\n/// A negative or zero `sigma_x`/`sigma_y` will disable the blur along that axis.\n///\n/// # Allocations\n///\n/// This method will allocate a 2x `src` buffer.\npub fn apply(sigma_x: f64, sigma_y: f64, src: ImageRefMut) {\n    let buf_size = (src.width * src.height) as usize;\n    let mut buf = vec![0.0; buf_size];\n    let buf = &mut buf;\n\n    let d = BlurData {\n        width: src.width as usize,\n        height: src.height as usize,\n        sigma_x,\n        sigma_y,\n        steps: 4,\n    };\n\n    let data = src.data.as_mut_slice();\n    gaussian_channel(data, &d, 0, buf);\n    gaussian_channel(data, &d, 1, buf);\n    gaussian_channel(data, &d, 2, buf);\n    gaussian_channel(data, &d, 3, buf);\n}\n\nfn gaussian_channel(data: &mut [u8], d: &BlurData, channel: usize, buf: &mut Vec<f64>) {\n    for i in 0..data.len() / 4 {\n        buf[i] = data[i * 4 + channel] as f64 / 255.0;\n    }\n\n    gaussianiir2d(d, buf);\n\n    for i in 0..data.len() / 4 {\n        data[i * 4 + channel] = (buf[i] * 255.0) as u8;\n    }\n}\n\nfn gaussianiir2d(d: &BlurData, buf: &mut Vec<f64>) {\n    // Filter horizontally along each row.\n    let (lambda_x, dnu_x) = if d.sigma_x > 0.0 {\n        let (lambda, dnu) = gen_coefficients(d.sigma_x, d.steps);\n\n        for y in 0..d.height {\n            for _ in 0..d.steps {\n                let idx = d.width * y;\n\n                // Filter rightwards.\n                for x in 1..d.width {\n                    buf[idx + x] += dnu * buf[idx + x - 1];\n                }\n\n                let mut x = d.width - 1;\n\n                // Filter leftwards.\n                while x > 0 {\n                    buf[idx + x - 1] += dnu * buf[idx + x];\n                    x -= 1;\n                }\n            }\n        }\n\n        (lambda, dnu)\n    } else {\n        (1.0, 1.0)\n    };\n\n    // Filter vertically along each column.\n    let (lambda_y, dnu_y) = if d.sigma_y > 0.0 {\n        let (lambda, dnu) = gen_coefficients(d.sigma_y, d.steps);\n        for x in 0..d.width {\n            for _ in 0..d.steps {\n                let idx = x;\n\n                // Filter downwards.\n                let mut y = d.width;\n                while y < buf.len() {\n                    buf[idx + y] += dnu * buf[idx + y - d.width];\n                    y += d.width;\n                }\n\n                y = buf.len() - d.width;\n\n                // Filter upwards.\n                while y > 0 {\n                    buf[idx + y - d.width] += dnu * buf[idx + y];\n                    y -= d.width;\n                }\n            }\n        }\n\n        (lambda, dnu)\n    } else {\n        (1.0, 1.0)\n    };\n\n    let post_scale =\n        ((dnu_x * dnu_y).sqrt() / (lambda_x * lambda_y).sqrt()).powi(2 * d.steps as i32);\n    buf.iter_mut().for_each(|v| *v *= post_scale);\n}\n\nfn gen_coefficients(sigma: f64, steps: usize) -> (f64, f64) {\n    let lambda = (sigma * sigma) / (2.0 * steps as f64);\n    let dnu = (1.0 + 2.0 * lambda - (1.0 + 4.0 * lambda).sqrt()) / (2.0 * lambda);\n    (lambda, dnu)\n}\n"
    },
    {
      "package": "resvg@0.34.1",
      "sourcePath": "tests/fonts/Amiri-LICENSE-OFL.txt",
      "sha256": "1f91c5ef4a18a747526f9c527d8e39337d31d3f37a8472c89fbdfe874c2d0d69",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Copyright (c) 2010-2016, Khaled Hosny (<khaledhosny@eglug.org>)\r\n\r\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\r\nThis license is copied below, and is also available with a FAQ at:\r\nhttp://scripts.sil.org/OFL\r\n\r\n\r\n-----------------------------------------------------------\r\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\r\n-----------------------------------------------------------\r\n\r\nPREAMBLE\r\nThe goals of the Open Font License (OFL) are to stimulate worldwide\r\ndevelopment of collaborative font projects, to support the font creation\r\nefforts of academic and linguistic communities, and to provide a free and\r\nopen framework in which fonts may be shared and improved in partnership\r\nwith others.\r\n\r\nThe OFL allows the licensed fonts to be used, studied, modified and\r\nredistributed freely as long as they are not sold by themselves. The\r\nfonts, including any derivative works, can be bundled, embedded, \r\nredistributed and/or sold with any software provided that any reserved\r\nnames are not used by derivative works. The fonts and derivatives,\r\nhowever, cannot be released under any other type of license. The\r\nrequirement for fonts to remain under this license does not apply\r\nto any document created using the fonts or their derivatives.\r\n\r\nDEFINITIONS\r\n\"Font Software\" refers to the set of files released by the Copyright\r\nHolder(s) under this license and clearly marked as such. This may\r\ninclude source files, build scripts and documentation.\r\n\r\n\"Reserved Font Name\" refers to any names specified as such after the\r\ncopyright statement(s).\r\n\r\n\"Original Version\" refers to the collection of Font Software components as\r\ndistributed by the Copyright Holder(s).\r\n\r\n\"Modified Version\" refers to any derivative made by adding to, deleting,\r\nor substituting -- in part or in whole -- any of the components of the\r\nOriginal Version, by changing formats or by porting the Font Software to a\r\nnew environment.\r\n\r\n\"Author\" refers to any designer, engineer, programmer, technical\r\nwriter or other person who contributed to the Font Software.\r\n\r\nPERMISSION & CONDITIONS\r\nPermission is hereby granted, free of charge, to any person obtaining\r\na copy of the Font Software, to use, study, copy, merge, embed, modify,\r\nredistribute, and sell modified and unmodified copies of the Font\r\nSoftware, subject to the following conditions:\r\n\r\n1) Neither the Font Software nor any of its individual components,\r\nin Original or Modified Versions, may be sold by itself.\r\n\r\n2) Original or Modified Versions of the Font Software may be bundled,\r\nredistributed and/or sold with any software, provided that each copy\r\ncontains the above copyright notice and this license. These can be\r\nincluded either as stand-alone text files, human-readable headers or\r\nin the appropriate machine-readable metadata fields within text or\r\nbinary files as long as those fields can be easily viewed by the user.\r\n\r\n3) No Modified Version of the Font Software may use the Reserved Font\r\nName(s) unless explicit written permission is granted by the corresponding\r\nCopyright Holder. This restriction only applies to the primary font name as\r\npresented to the users.\r\n\r\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\r\nSoftware shall not be used to promote, endorse or advertise any\r\nModified Version, except to acknowledge the contribution(s) of the\r\nCopyright Holder(s) and the Author(s) or with their explicit written\r\npermission.\r\n\r\n5) The Font Software, modified or unmodified, in part or in whole,\r\nmust be distributed entirely under this license, and must not be\r\ndistributed under any other license. The requirement for fonts to\r\nremain under this license does not apply to any document created\r\nusing the Font Software.\r\n\r\nTERMINATION\r\nThis license becomes null and void if any of the above conditions are\r\nnot met.\r\n\r\nDISCLAIMER\r\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\r\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\r\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\r\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\r\nOTHER DEALINGS IN THE FONT SOFTWARE.\r\n"
    },
    {
      "package": "resvg@0.34.1",
      "sourcePath": "tests/fonts/MPLUS1p-LICENSE-OFL.txt",
      "sha256": "7f18ec1ebb6b50e3ed0f74b2c61f25b8d7cd69e43f4de66e991bcfd3c419a8bb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "This Font Software is licensed under the SIL Open Font License, Version 1.1.\r\nThis license is copied below, and is also available with a FAQ at:\r\nhttp://scripts.sil.org/OFL\r\n\r\n\r\n-----------------------------------------------------------\r\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\r\n-----------------------------------------------------------\r\n\r\nPREAMBLE\r\nThe goals of the Open Font License (OFL) are to stimulate worldwide\r\ndevelopment of collaborative font projects, to support the font creation\r\nefforts of academic and linguistic communities, and to provide a free and\r\nopen framework in which fonts may be shared and improved in partnership\r\nwith others.\r\n\r\nThe OFL allows the licensed fonts to be used, studied, modified and\r\nredistributed freely as long as they are not sold by themselves. The\r\nfonts, including any derivative works, can be bundled, embedded, \r\nredistributed and/or sold with any software provided that any reserved\r\nnames are not used by derivative works. The fonts and derivatives,\r\nhowever, cannot be released under any other type of license. The\r\nrequirement for fonts to remain under this license does not apply\r\nto any document created using the fonts or their derivatives.\r\n\r\nDEFINITIONS\r\n\"Font Software\" refers to the set of files released by the Copyright\r\nHolder(s) under this license and clearly marked as such. This may\r\ninclude source files, build scripts and documentation.\r\n\r\n\"Reserved Font Name\" refers to any names specified as such after the\r\ncopyright statement(s).\r\n\r\n\"Original Version\" refers to the collection of Font Software components as\r\ndistributed by the Copyright Holder(s).\r\n\r\n\"Modified Version\" refers to any derivative made by adding to, deleting,\r\nor substituting -- in part or in whole -- any of the components of the\r\nOriginal Version, by changing formats or by porting the Font Software to a\r\nnew environment.\r\n\r\n\"Author\" refers to any designer, engineer, programmer, technical\r\nwriter or other person who contributed to the Font Software.\r\n\r\nPERMISSION & CONDITIONS\r\nPermission is hereby granted, free of charge, to any person obtaining\r\na copy of the Font Software, to use, study, copy, merge, embed, modify,\r\nredistribute, and sell modified and unmodified copies of the Font\r\nSoftware, subject to the following conditions:\r\n\r\n1) Neither the Font Software nor any of its individual components,\r\nin Original or Modified Versions, may be sold by itself.\r\n\r\n2) Original or Modified Versions of the Font Software may be bundled,\r\nredistributed and/or sold with any software, provided that each copy\r\ncontains the above copyright notice and this license. These can be\r\nincluded either as stand-alone text files, human-readable headers or\r\nin the appropriate machine-readable metadata fields within text or\r\nbinary files as long as those fields can be easily viewed by the user.\r\n\r\n3) No Modified Version of the Font Software may use the Reserved Font\r\nName(s) unless explicit written permission is granted by the corresponding\r\nCopyright Holder. This restriction only applies to the primary font name as\r\npresented to the users.\r\n\r\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\r\nSoftware shall not be used to promote, endorse or advertise any\r\nModified Version, except to acknowledge the contribution(s) of the\r\nCopyright Holder(s) and the Author(s) or with their explicit written\r\npermission.\r\n\r\n5) The Font Software, modified or unmodified, in part or in whole,\r\nmust be distributed entirely under this license, and must not be\r\ndistributed under any other license. The requirement for fonts to\r\nremain under this license does not apply to any document created\r\nusing the Font Software.\r\n\r\nTERMINATION\r\nThis license becomes null and void if any of the above conditions are\r\nnot met.\r\n\r\nDISCLAIMER\r\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\r\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\r\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\r\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\r\nOTHER DEALINGS IN THE FONT SOFTWARE.\r\n"
    },
    {
      "package": "resvg@0.34.1",
      "sourcePath": "tests/fonts/Noto-LICENSE-OFL.txt",
      "sha256": "6a73f9541c2de74158c0e7cf6b0a58ef774f5a780bf191f2d7ec9cc53efe2bf2",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "This Font Software is licensed under the SIL Open Font License,\nVersion 1.1.\n\nThis license is copied below, and is also available with a FAQ at:\nhttp://scripts.sil.org/OFL\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font\ncreation efforts of academic and linguistic communities, and to\nprovide a free and open framework in which fonts may be shared and\nimproved in partnership with others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded,\nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply to\nany document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software\ncomponents as distributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to,\ndeleting, or substituting -- in part or in whole -- any of the\ncomponents of the Original Version, by changing formats or by porting\nthe Font Software to a new environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed,\nmodify, redistribute, and sell modified and unmodified copies of the\nFont Software, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components, in\nOriginal or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the\ncorresponding Copyright Holder. This restriction only applies to the\nprimary font name as presented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created using\nthe Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
    },
    {
      "package": "resvg@0.34.1",
      "sourcePath": "tests/fonts/SedgwickAveDisplay-LICENSE-OFL.txt",
      "sha256": "7727a792e40376a1a6ef139e2b94a8199692de5a2ea48a3d72e7161bf672753d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Copyright 2017 The Sedgwick Ave Project Authors (https://github.com/googlefonts/sedgwickave)\r\n\r\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\r\nThis license is copied below, and is also available with a FAQ at:\r\nhttp://scripts.sil.org/OFL\r\n\r\n\r\n-----------------------------------------------------------\r\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\r\n-----------------------------------------------------------\r\n\r\nPREAMBLE\r\nThe goals of the Open Font License (OFL) are to stimulate worldwide\r\ndevelopment of collaborative font projects, to support the font creation\r\nefforts of academic and linguistic communities, and to provide a free and\r\nopen framework in which fonts may be shared and improved in partnership\r\nwith others.\r\n\r\nThe OFL allows the licensed fonts to be used, studied, modified and\r\nredistributed freely as long as they are not sold by themselves. The\r\nfonts, including any derivative works, can be bundled, embedded, \r\nredistributed and/or sold with any software provided that any reserved\r\nnames are not used by derivative works. The fonts and derivatives,\r\nhowever, cannot be released under any other type of license. The\r\nrequirement for fonts to remain under this license does not apply\r\nto any document created using the fonts or their derivatives.\r\n\r\nDEFINITIONS\r\n\"Font Software\" refers to the set of files released by the Copyright\r\nHolder(s) under this license and clearly marked as such. This may\r\ninclude source files, build scripts and documentation.\r\n\r\n\"Reserved Font Name\" refers to any names specified as such after the\r\ncopyright statement(s).\r\n\r\n\"Original Version\" refers to the collection of Font Software components as\r\ndistributed by the Copyright Holder(s).\r\n\r\n\"Modified Version\" refers to any derivative made by adding to, deleting,\r\nor substituting -- in part or in whole -- any of the components of the\r\nOriginal Version, by changing formats or by porting the Font Software to a\r\nnew environment.\r\n\r\n\"Author\" refers to any designer, engineer, programmer, technical\r\nwriter or other person who contributed to the Font Software.\r\n\r\nPERMISSION & CONDITIONS\r\nPermission is hereby granted, free of charge, to any person obtaining\r\na copy of the Font Software, to use, study, copy, merge, embed, modify,\r\nredistribute, and sell modified and unmodified copies of the Font\r\nSoftware, subject to the following conditions:\r\n\r\n1) Neither the Font Software nor any of its individual components,\r\nin Original or Modified Versions, may be sold by itself.\r\n\r\n2) Original or Modified Versions of the Font Software may be bundled,\r\nredistributed and/or sold with any software, provided that each copy\r\ncontains the above copyright notice and this license. These can be\r\nincluded either as stand-alone text files, human-readable headers or\r\nin the appropriate machine-readable metadata fields within text or\r\nbinary files as long as those fields can be easily viewed by the user.\r\n\r\n3) No Modified Version of the Font Software may use the Reserved Font\r\nName(s) unless explicit written permission is granted by the corresponding\r\nCopyright Holder. This restriction only applies to the primary font name as\r\npresented to the users.\r\n\r\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\r\nSoftware shall not be used to promote, endorse or advertise any\r\nModified Version, except to acknowledge the contribution(s) of the\r\nCopyright Holder(s) and the Author(s) or with their explicit written\r\npermission.\r\n\r\n5) The Font Software, modified or unmodified, in part or in whole,\r\nmust be distributed entirely under this license, and must not be\r\ndistributed under any other license. The requirement for fonts to\r\nremain under this license does not apply to any document created\r\nusing the Font Software.\r\n\r\nTERMINATION\r\nThis license becomes null and void if any of the above conditions are\r\nnot met.\r\n\r\nDISCLAIMER\r\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\r\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\r\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\r\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\r\nOTHER DEALINGS IN THE FONT SOFTWARE.\r\n"
    },
    {
      "package": "resvg@0.34.1",
      "sourcePath": "tests/fonts/SourceSansPro-LICENSE-OFL.md",
      "sha256": "e1d1fdcefb57985226c06fa9500d29caacfa2b1f8b8c74db911f13c6cad186a1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Copyright 2010-2018 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.\r\n\r\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\r\n\r\nThis license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL\r\n\r\n\r\n-----------------------------------------------------------\r\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\r\n-----------------------------------------------------------\r\n\r\nPREAMBLE\r\nThe goals of the Open Font License (OFL) are to stimulate worldwide\r\ndevelopment of collaborative font projects, to support the font creation\r\nefforts of academic and linguistic communities, and to provide a free and\r\nopen framework in which fonts may be shared and improved in partnership\r\nwith others.\r\n\r\nThe OFL allows the licensed fonts to be used, studied, modified and\r\nredistributed freely as long as they are not sold by themselves. The\r\nfonts, including any derivative works, can be bundled, embedded, \r\nredistributed and/or sold with any software provided that any reserved\r\nnames are not used by derivative works. The fonts and derivatives,\r\nhowever, cannot be released under any other type of license. The\r\nrequirement for fonts to remain under this license does not apply\r\nto any document created using the fonts or their derivatives.\r\n\r\nDEFINITIONS\r\n\"Font Software\" refers to the set of files released by the Copyright\r\nHolder(s) under this license and clearly marked as such. This may\r\ninclude source files, build scripts and documentation.\r\n\r\n\"Reserved Font Name\" refers to any names specified as such after the\r\ncopyright statement(s).\r\n\r\n\"Original Version\" refers to the collection of Font Software components as\r\ndistributed by the Copyright Holder(s).\r\n\r\n\"Modified Version\" refers to any derivative made by adding to, deleting,\r\nor substituting -- in part or in whole -- any of the components of the\r\nOriginal Version, by changing formats or by porting the Font Software to a\r\nnew environment.\r\n\r\n\"Author\" refers to any designer, engineer, programmer, technical\r\nwriter or other person who contributed to the Font Software.\r\n\r\nPERMISSION & CONDITIONS\r\nPermission is hereby granted, free of charge, to any person obtaining\r\na copy of the Font Software, to use, study, copy, merge, embed, modify,\r\nredistribute, and sell modified and unmodified copies of the Font\r\nSoftware, subject to the following conditions:\r\n\r\n1) Neither the Font Software nor any of its individual components,\r\nin Original or Modified Versions, may be sold by itself.\r\n\r\n2) Original or Modified Versions of the Font Software may be bundled,\r\nredistributed and/or sold with any software, provided that each copy\r\ncontains the above copyright notice and this license. These can be\r\nincluded either as stand-alone text files, human-readable headers or\r\nin the appropriate machine-readable metadata fields within text or\r\nbinary files as long as those fields can be easily viewed by the user.\r\n\r\n3) No Modified Version of the Font Software may use the Reserved Font\r\nName(s) unless explicit written permission is granted by the corresponding\r\nCopyright Holder. This restriction only applies to the primary font name as\r\npresented to the users.\r\n\r\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\r\nSoftware shall not be used to promote, endorse or advertise any\r\nModified Version, except to acknowledge the contribution(s) of the\r\nCopyright Holder(s) and the Author(s) or with their explicit written\r\npermission.\r\n\r\n5) The Font Software, modified or unmodified, in part or in whole,\r\nmust be distributed entirely under this license, and must not be\r\ndistributed under any other license. The requirement for fonts to\r\nremain under this license does not apply to any document created\r\nusing the Font Software.\r\n\r\nTERMINATION\r\nThis license becomes null and void if any of the above conditions are\r\nnot met.\r\n\r\nDISCLAIMER\r\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\r\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\r\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\r\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\r\nOTHER DEALINGS IN THE FONT SOFTWARE.\r\n"
    },
    {
      "package": "resvg@0.34.1",
      "sourcePath": "tests/fonts/Yellowtail-LICENSE-Apache2.txt",
      "sha256": "3ddf9be5c28fe27dad143a5dc76eea25222ad1dd68934a047064e56ed2fa40c5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "\r\n                                 Apache License\r\n                           Version 2.0, January 2004\r\n                        http://www.apache.org/licenses/\r\n\r\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n\r\n   1. Definitions.\r\n\r\n      \"License\" shall mean the terms and conditions for use, reproduction,\r\n      and distribution as defined by Sections 1 through 9 of this document.\r\n\r\n      \"Licensor\" shall mean the copyright owner or entity authorized by\r\n      the copyright owner that is granting the License.\r\n\r\n      \"Legal Entity\" shall mean the union of the acting entity and all\r\n      other entities that control, are controlled by, or are under common\r\n      control with that entity. For the purposes of this definition,\r\n      \"control\" means (i) the power, direct or indirect, to cause the\r\n      direction or management of such entity, whether by contract or\r\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n      outstanding shares, or (iii) beneficial ownership of such entity.\r\n\r\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n      exercising permissions granted by this License.\r\n\r\n      \"Source\" form shall mean the preferred form for making modifications,\r\n      including but not limited to software source code, documentation\r\n      source, and configuration files.\r\n\r\n      \"Object\" form shall mean any form resulting from mechanical\r\n      transformation or translation of a Source form, including but\r\n      not limited to compiled object code, generated documentation,\r\n      and conversions to other media types.\r\n\r\n      \"Work\" shall mean the work of authorship, whether in Source or\r\n      Object form, made available under the License, as indicated by a\r\n      copyright notice that is included in or attached to the work\r\n      (an example is provided in the Appendix below).\r\n\r\n      \"Derivative Works\" shall mean any work, whether in Source or Object\r\n      form, that is based on (or derived from) the Work and for which the\r\n      editorial revisions, annotations, elaborations, or other modifications\r\n      represent, as a whole, an original work of authorship. For the purposes\r\n      of this License, Derivative Works shall not include works that remain\r\n      separable from, or merely link (or bind by name) to the interfaces of,\r\n      the Work and Derivative Works thereof.\r\n\r\n      \"Contribution\" shall mean any work of authorship, including\r\n      the original version of the Work and any modifications or additions\r\n      to that Work or Derivative Works thereof, that is intentionally\r\n      submitted to Licensor for inclusion in the Work by the copyright owner\r\n      or by an individual or Legal Entity authorized to submit on behalf of\r\n      the copyright owner. For the purposes of this definition, \"submitted\"\r\n      means any form of electronic, verbal, or written communication sent\r\n      to the Licensor or its representatives, including but not limited to\r\n      communication on electronic mailing lists, source code control systems,\r\n      and issue tracking systems that are managed by, or on behalf of, the\r\n      Licensor for the purpose of discussing and improving the Work, but\r\n      excluding communication that is conspicuously marked or otherwise\r\n      designated in writing by the copyright owner as \"Not a Contribution.\"\r\n\r\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n      on behalf of whom a Contribution has been received by Licensor and\r\n      subsequently incorporated within the Work.\r\n\r\n   2. Grant of Copyright License. Subject to the terms and conditions of\r\n      this License, each Contributor hereby grants to You a perpetual,\r\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n      copyright license to reproduce, prepare Derivative Works of,\r\n      publicly display, publicly perform, sublicense, and distribute the\r\n      Work and such Derivative Works in Source or Object form.\r\n\r\n   3. Grant of Patent License. Subject to the terms and conditions of\r\n      this License, each Contributor hereby grants to You a perpetual,\r\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n      (except as stated in this section) patent license to make, have made,\r\n      use, offer to sell, sell, import, and otherwise transfer the Work,\r\n      where such license applies only to those patent claims licensable\r\n      by such Contributor that are necessarily infringed by their\r\n      Contribution(s) alone or by combination of their Contribution(s)\r\n      with the Work to which such Contribution(s) was submitted. If You\r\n      institute patent litigation against any entity (including a\r\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n      or a Contribution incorporated within the Work constitutes direct\r\n      or contributory patent infringement, then any patent licenses\r\n      granted to You under this License for that Work shall terminate\r\n      as of the date such litigation is filed.\r\n\r\n   4. Redistribution. You may reproduce and distribute copies of the\r\n      Work or Derivative Works thereof in any medium, with or without\r\n      modifications, and in Source or Object form, provided that You\r\n      meet the following conditions:\r\n\r\n      (a) You must give any other recipients of the Work or\r\n          Derivative Works a copy of this License; and\r\n\r\n      (b) You must cause any modified files to carry prominent notices\r\n          stating that You changed the files; and\r\n\r\n      (c) You must retain, in the Source form of any Derivative Works\r\n          that You distribute, all copyright, patent, trademark, and\r\n          attribution notices from the Source form of the Work,\r\n          excluding those notices that do not pertain to any part of\r\n          the Derivative Works; and\r\n\r\n      (d) If the Work includes a \"NOTICE\" text file as part of its\r\n          distribution, then any Derivative Works that You distribute must\r\n          include a readable copy of the attribution notices contained\r\n          within such NOTICE file, excluding those notices that do not\r\n          pertain to any part of the Derivative Works, in at least one\r\n          of the following places: within a NOTICE text file distributed\r\n          as part of the Derivative Works; within the Source form or\r\n          documentation, if provided along with the Derivative Works; or,\r\n          within a display generated by the Derivative Works, if and\r\n          wherever such third-party notices normally appear. The contents\r\n          of the NOTICE file are for informational purposes only and\r\n          do not modify the License. You may add Your own attribution\r\n          notices within Derivative Works that You distribute, alongside\r\n          or as an addendum to the NOTICE text from the Work, provided\r\n          that such additional attribution notices cannot be construed\r\n          as modifying the License.\r\n\r\n      You may add Your own copyright statement to Your modifications and\r\n      may provide additional or different license terms and conditions\r\n      for use, reproduction, or distribution of Your modifications, or\r\n      for any such Derivative Works as a whole, provided Your use,\r\n      reproduction, and distribution of the Work otherwise complies with\r\n      the conditions stated in this License.\r\n\r\n   5. Submission of Contributions. Unless You explicitly state otherwise,\r\n      any Contribution intentionally submitted for inclusion in the Work\r\n      by You to the Licensor shall be under the terms and conditions of\r\n      this License, without any additional terms or conditions.\r\n      Notwithstanding the above, nothing herein shall supersede or modify\r\n      the terms of any separate license agreement you may have executed\r\n      with Licensor regarding such Contributions.\r\n\r\n   6. Trademarks. This License does not grant permission to use the trade\r\n      names, trademarks, service marks, or product names of the Licensor,\r\n      except as required for reasonable and customary use in describing the\r\n      origin of the Work and reproducing the content of the NOTICE file.\r\n\r\n   7. Disclaimer of Warranty. Unless required by applicable law or\r\n      agreed to in writing, Licensor provides the Work (and each\r\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\r\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r\n      implied, including, without limitation, any warranties or conditions\r\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r\n      PARTICULAR PURPOSE. You are solely responsible for determining the\r\n      appropriateness of using or redistributing the Work and assume any\r\n      risks associated with Your exercise of permissions under this License.\r\n\r\n   8. Limitation of Liability. In no event and under no legal theory,\r\n      whether in tort (including negligence), contract, or otherwise,\r\n      unless required by applicable law (such as deliberate and grossly\r\n      negligent acts) or agreed to in writing, shall any Contributor be\r\n      liable to You for damages, including any direct, indirect, special,\r\n      incidental, or consequential damages of any character arising as a\r\n      result of this License or out of the use or inability to use the\r\n      Work (including but not limited to damages for loss of goodwill,\r\n      work stoppage, computer failure or malfunction, or any and all\r\n      other commercial damages or losses), even if such Contributor\r\n      has been advised of the possibility of such damages.\r\n\r\n   9. Accepting Warranty or Additional Liability. While redistributing\r\n      the Work or Derivative Works thereof, You may choose to offer,\r\n      and charge a fee for, acceptance of support, warranty, indemnity,\r\n      or other liability obligations and/or rights consistent with this\r\n      License. However, in accepting such obligations, You may act only\r\n      on Your own behalf and on Your sole responsibility, not on behalf\r\n      of any other Contributor, and only if You agree to indemnify,\r\n      defend, and hold each Contributor harmless for any liability\r\n      incurred by, or claims asserted against, such Contributor by reason\r\n      of your accepting any such warranty or additional liability.\r\n\r\n   END OF TERMS AND CONDITIONS\r\n\r\n   APPENDIX: How to apply the Apache License to your work.\r\n\r\n      To apply the Apache License to your work, attach the following\r\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\r\n      replaced with your own identifying information. (Don't include\r\n      the brackets!)  The text should be enclosed in the appropriate\r\n      comment syntax for the file format. We also recommend that a\r\n      file or class name and description of purpose be included on the\r\n      same \"printed page\" as the copyright notice for easier\r\n      identification within third-party archives.\r\n\r\n   Copyright [yyyy] [name of copyright owner]\r\n\r\n   Licensed under the Apache License, Version 2.0 (the \"License\");\r\n   you may not use this file except in compliance with the License.\r\n   You may obtain a copy of the License at\r\n\r\n       http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n   Unless required by applicable law or agreed to in writing, software\r\n   distributed under the License is distributed on an \"AS IS\" BASIS,\r\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n   See the License for the specific language governing permissions and\r\n   limitations under the License.\r\n"
    },
    {
      "package": "resvg-js@1.0.0",
      "sourcePath": "README.md",
      "sha256": "e3e35220f5dd57ef197086ea5de17cb46e5df78a50501d3e5fa2bc0526942f90",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# resvg-js\r\n\r\n<a href=\"https://github.com/yisibl/resvg-js/actions\"><img alt=\"GitHub CI Status\" src=\"https://github.com/yisibl/resvg-js/workflows/CI/badge.svg?branch=main\"></a>\r\n<a href=\"https://www.npmjs.com/package/@resvg/resvg-js\"><img src=\"https://img.shields.io/npm/v/@resvg/resvg-js.svg?sanitize=true\" alt=\"@resvg/resvg-js npm version\"></a>\r\n<a href=\"https://npmcharts.com/compare/@resvg/resvg-js?minimal=true\"><img src=\"https://img.shields.io/npm/dm/@resvg/resvg-js.svg?sanitize=true\" alt=\"@resvg/resvg-js downloads\"></a>\r\n[![Rust 1.65+](https://img.shields.io/badge/rust-1.65+-orange.svg)](https://www.rust-lang.org)\r\n\r\n> resvg-js is a high-performance SVG renderer and toolkit, powered by Rust based [resvg](https://github.com/RazrFalcon/resvg/), with Node.js backend using [napi-rs](https://github.com/napi-rs/napi-rs), also a pure WebAssembly backend.\r\n\r\nPlease use all lowercase `resvg-js` when referencing project names.\r\n\r\n**💖 🙏[Sponsoring me](#sponsor)**\r\n\r\n> Your sponsorship means a lot to me. It will help me sustain my projects actively and make more of my ideas come true. Much appreciated!\r\n\r\n## Features\r\n\r\n- Fast, safe and zero dependencies, with correct output.\r\n- Convert SVG to PNG, includes cropping, scaling and setting the background color.\r\n- Support system fonts and custom fonts in SVG text.\r\n- `v2`: Gets the width and height of the SVG and the generated PNG.\r\n- `v2`: Support for outputting simplified SVG strings, such as converting shapes(rect, circle, etc) to `<path>`.\r\n- `v2`: Support WebAssembly.\r\n- `v2`: Support to get SVG bounding box and crop according to bounding box.\r\n- `v2`: Support for loading images of external links in `<image>`.\r\n- No need for node-gyp and postinstall, the `.node` file has been compiled for you.\r\n- Cross-platform support, including [Apple M Chips](https://www.apple.com/newsroom/2020/11/apple-unleashes-m1/).\r\n- Support for running as native addons in Deno.\r\n\r\n## Sponsor\r\n\r\nAlipay(支付宝)\r\n\r\n<img width=\"260\" src=\"https://user-images.githubusercontent.com/2784308/275749798-dcecb901-6a44-46f6-aab3-98635664719e.jpeg\">\r\n\r\n## Installation\r\n\r\n### Node.js\r\n\r\n```shell\r\nnpm i @resvg/resvg-js\r\n```\r\n\r\n### Browser(Wasm)\r\n\r\n```html\r\n<script src=\"https://unpkg.com/@resvg/resvg-wasm\"></script>\r\n```\r\n\r\n## Docs\r\n\r\n- Node.js see [index.d.ts](./index.d.ts)\r\n- Wasm see [wasm/index.d.ts](./wasm/index.d.ts)\r\n\r\n## Example\r\n\r\n### [Node.js Example](example/index.js)\r\n\r\nThis example will load Source Han Serif, and then render the SVG to PNG.\r\n\r\n```shell\r\nnode example/index.js\r\n\r\nLoaded 1 font faces in 0ms.\r\nFont './example/SourceHanSerifCN-Light-subset.ttf':0 found in 0.006ms.\r\n✨ Done in 55.65491008758545 ms\r\n```\r\n\r\n### [Deno Example](example/index-deno.js)\r\n\r\n```shell\r\ndeno run --unstable --allow-read --allow-write --allow-ffi example/index-deno.js\r\n\r\n[2022-11-16T15:03:29Z DEBUG resvg_js::fonts] Loaded 1 font faces in 0.067ms.\r\n[2022-11-16T15:03:29Z DEBUG resvg_js::fonts] Font './example/SourceHanSerifCN-Light-subset.ttf':0 found in 0.001ms.\r\nOriginal SVG Size: 1324 x 687\r\nOutput PNG Size  : 1200 x 623\r\n✨ Done in 66 ms\r\n```\r\n\r\n| SVG                                      | PNG                                          |\r\n| ---------------------------------------- | -------------------------------------------- |\r\n| <img width=\"500\" src=\"example/text.svg\"> | <img width=\"500\" src=\"example/text-out.png\"> |\r\n\r\n## Usage\r\n\r\n### Node.js\r\n\r\n```js\r\nconst { promises } = require('fs')\r\nconst { join } = require('path')\r\nconst { Resvg } = require('@resvg/resvg-js')\r\n\r\nasync function main() {\r\n  const svg = await promises.readFile(join(__dirname, './text.svg'))\r\n  const opts = {\r\n    background: 'rgba(238, 235, 230, .9)',\r\n    fitTo: {\r\n      mode: 'width',\r\n      value: 1200,\r\n    },\r\n    font: {\r\n      fontFiles: ['./example/SourceHanSerifCN-Light-subset.ttf'], // Load custom fonts.\r\n      loadSystemFonts: false, // It will be faster to disable loading system fonts.\r\n      // defaultFontFamily: 'Source Han Serif CN Light', // You can omit this.\r\n    },\r\n  }\r\n  const resvg = new Resvg(svg, opts)\r\n  const pngData = resvg.render()\r\n  const pngBuffer = pngData.asPng()\r\n\r\n  console.info('Original SVG Size:', `${resvg.width} x ${resvg.height}`)\r\n  console.info('Output PNG Size  :', `${pngData.width} x ${pngData.height}`)\r\n\r\n  await promises.writeFile(join(__dirname, './text-out.png'), pngBuffer)\r\n}\r\n\r\nmain()\r\n```\r\n\r\n### Bun\r\n\r\nStarting with [Bun 0.8.1](https://github.com/oven-sh/bun/issues/172#issuecomment-1692930718), resvg-js can be run directly in Bun without any modification to the JS files, and is fully compatible with the syntax in Node.js.\r\n\r\n```shell\r\nbun example/index.js\r\n```\r\n\r\n### Deno\r\n\r\nStarting with [Deno 1.26.1](https://github.com/denoland/deno/releases/tag/v1.26.1), there is support for running Native Addons directly from Node.js.\r\nThis allows for performance that is close to that found in Node.js.\r\n\r\n```shell\r\ndeno run --unstable --allow-read --allow-write --allow-ffi example/index-deno.js\r\n```\r\n\r\n```js\r\nimport * as path from 'https://deno.land/std@0.159.0/path/mod.ts'\r\nimport { Resvg } from 'npm:@resvg/resvg-js'\r\nconst __dirname = path.dirname(path.fromFileUrl(import.meta.url))\r\n\r\nconst svg = await Deno.readFile(path.join(__dirname, './text.svg'))\r\nconst opts = {\r\n  fitTo: {\r\n    mode: 'width',\r\n    value: 1200,\r\n  },\r\n}\r\n\r\nconst t = performance.now()\r\nconst resvg = new Resvg(svg, opts)\r\nconst pngData = resvg.render()\r\nconst pngBuffer = pngData.asPng()\r\nconsole.info('Original SVG Size:', `${resvg.width} x ${resvg.height}`)\r\nconsole.info('Output PNG Size  :', `${pngData.width} x ${pngData.height}`)\r\nconsole.info('✨ Done in', performance.now() - t, 'ms')\r\n\r\nawait Deno.writeFile(path.join(__dirname, './text-out-deno.png'), pngBuffer)\r\n```\r\n\r\n### WebAssembly\r\n\r\nThis package also ships a pure WebAssembly artifact built with `wasm-bindgen` to run in browsers.\r\n\r\n#### Browser\r\n\r\n```html\r\n<script src=\"https://unpkg.com/@resvg/resvg-wasm\"></script>\r\n<script>\r\n  ;(async function () {\r\n    // The Wasm must be initialized first\r\n    await resvg.initWasm(fetch('https://unpkg.com/@resvg/resvg-wasm/index_bg.wasm'))\r\n\r\n    const font = await fetch('./fonts/Pacifico-Regular.woff2')\r\n    if (!font.ok) return\r\n\r\n    const fontData = await font.arrayBuffer()\r\n    const buffer = new Uint8Array(fontData)\r\n\r\n    const opts = {\r\n      fitTo: {\r\n        mode: 'width', // If you need to change the size\r\n        value: 800,\r\n      },\r\n      font: {\r\n        fontBuffers: [buffer], // New in 2.5.0, loading custom fonts\r\n      },\r\n    }\r\n\r\n    const svg = '<svg> ... </svg>' // Input SVG, String or Uint8Array\r\n    const resvgJS = new resvg.Resvg(svg, opts)\r\n    const pngData = resvgJS.render(svg, opts) // Output PNG data, Uint8Array\r\n    const pngBuffer = pngData.asPng()\r\n    const svgURL = URL.createObjectURL(new Blob([pngData], { type: 'image/png' }))\r\n    document.getElementById('output').src = svgURL\r\n  })()\r\n</script>\r\n```\r\n\r\nSee [playground](wasm/index.html), it is also possible to [call Wasm in Node.js](example/wasm-node.js), but it is slower.\r\n\r\n## Sample Benchmark\r\n\r\n```shell\r\nnpm i benny@3.x sharp@0.x @types/sharp svg2img@0.x\r\nnpm run bench\r\n```\r\n\r\n```shell\r\nRunning \"resize width\" suite...\r\n  resvg-js(Rust):\r\n    12 ops/s\r\n\r\n  sharp:\r\n    9 ops/s\r\n\r\n  skr-canvas(Rust):\r\n    7 ops/s\r\n\r\n  svg2img(canvg and node-canvas):\r\n    6 ops/s\r\n```\r\n\r\n## Support matrix\r\n\r\n|                  | Node.js 12 | Node.js 14 | Node.js 16 | Node.js 18 | Node.js 20 | npm                                                                                                                                                                     |\r\n| ---------------- | ---------- | ---------- | ---------- | ---------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\r\n| Windows x64      | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-win32-x64-msvc.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-win32-x64-msvc)           |\r\n| Windows x32      | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-win32-ia32-msvc.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-win32-ia32-msvc)         |\r\n| Windows arm64    | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-win32-arm64-msvc.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-win32-arm64-msvc)       |\r\n| macOS x64        | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-darwin-x64.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-darwin-x64)                   |\r\n| macOS arm64(M1)  | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-darwin-arm64.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-darwin-arm64)               |\r\n| Linux x64 gnu    | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-linux-x64-gnu.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-linux-x64-gnu)             |\r\n| Linux x64 musl   | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-linux-x64-musl.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-linux-x64-musl)           |\r\n| Linux arm gnu    | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-linux-arm-gnueabihf.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-linux-arm-gnueabihf) |\r\n| Linux arm64 gnu  | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-linux-arm64-gnu.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-linux-arm64-gnu)         |\r\n| Linux arm64 musl | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-linux-arm64-musl.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-linux-arm64-musl)       |\r\n| Android arm64    | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-android-arm64.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-android-arm64)             |\r\n| Android armv7    | ✓          | ✓          | ✓          | ✓          | ✓          | [![npm version](https://img.shields.io/npm/v/@resvg/resvg-js-android-arm-eabi.svg?sanitize=true)](https://www.npmjs.com/package/@resvg/resvg-js-android-arm-eabi)       |\r\n\r\n## Test or Contributing\r\n\r\n- Install latest `Rust`\r\n- Install `Node.js@10+` which fully supported `Node-API`\r\n- Install `wasm-pack`\r\n\r\n  ```bash\r\n  curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh\r\n  ```\r\n\r\n  Normally `wasm-pack` will install `wasm-bindgen` automatically, but if the installation [fails due to network reasons](https://github.com/rustwasm/wasm-pack-template/issues/44#issuecomment-521657516), please try to install it manually.\r\n\r\n  ```bash\r\n  cargo install wasm-bindgen-cli\r\n  ```\r\n\r\n  On computers with Apple M chips, the following error message may appear:\r\n\r\n  > Error: failed to download from https://github.com/WebAssembly/binaryen/releases/download/version_90/binaryen-version_90-x86_64-apple-darwin.tar.gz\r\n\r\n  Please install binaryen manually:\r\n\r\n  ```bash\r\n  brew install binaryen\r\n  ```\r\n\r\n### Build Node.js bindings\r\n\r\n```bash\r\nnpm i\r\nnpm run build\r\nnpm test\r\n```\r\n\r\n### Build WebAssembly bindings\r\n\r\n```bash\r\nnpm i\r\nnpm run build:wasm\r\nnpm run test:wasm\r\n```\r\n\r\n## Roadmap\r\n\r\nI will consider implementing the following features, if you happen to be interested,\r\nplease feel free to discuss with me or submit a PR.\r\n\r\n- [x] Support async API\r\n- [x] Upgrade to napi-rs v2\r\n- [x] Support WebAssembly\r\n- [x] Output usvg-simplified SVG string\r\n- [x] Support for getting SVG Bounding box\r\n- [ ] Support for generating more lossless bitmap formats, e.g. avif, webp, JPEG XL\r\n\r\n## Release package\r\n\r\nWe use GitHub actions to automatically publish npm packages.\r\n\r\n```bash\r\n# 1.0.0 => 1.0.1\r\nnpm version patch\r\n\r\n# or 1.0.0 => 1.1.0\r\nnpm version minor\r\n```\r\n\r\n## License\r\n\r\nPlease use all lowercase `resvg-js` when referencing project names.\r\n\r\n[MPLv2.0](https://www.mozilla.org/en-US/MPL/)\r\n\r\nCopyright (c) 2021-present, yisibl(一丝)\r\n"
    },
    {
      "package": "resvg-js@1.0.0",
      "sourcePath": "wasm/README.md",
      "sha256": "f976bda8ccb79e0f7e1e64bde1403f3b130af6ca105ac273e6dac1290f12c268",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# resvg-js\r\n\r\n## @resvg/resvg-wasm\r\n\r\n<a href=\"https://github.com/yisibl/resvg-js/actions\"><img alt=\"GitHub CI Status\" src=\"https://github.com/yisibl/resvg-js/workflows/CI/badge.svg?branch=main\"></a>\r\n<a href=\"https://www.npmjs.com/package/@resvg/resvg-wasm\"><img src=\"https://img.shields.io/npm/v/@resvg/resvg-wasm.svg?sanitize=true\" alt=\"npm version\"></a>\r\n<a href=\"https://npmcharts.com/compare/@resvg/resvg-wasm?minimal=true\"><img src=\"https://img.shields.io/npm/dm/@resvg/resvg-wasm.svg?sanitize=true\" alt=\"downloads\"></a>\r\n\r\n\r\n> resvg-js is a high-performance SVG renderer and toolkit, powered by Rust based [resvg](https://github.com/RazrFalcon/resvg/) and [napi-rs](https://github.com/napi-rs/napi-rs).\r\n\r\nThis is the **WebAssembly** binary for [`resvg-js`](https://github.com/yisibl/resvg-js)\r\n## Playground\r\n\r\nhttps://resvg-js.vercel.app\r\n\r\n## License\r\n\r\n[MPLv2.0](https://www.mozilla.org/en-US/MPL/)\r\n\r\nCopyright (c) 2021-present, yisibl(一丝)"
    },
    {
      "package": "roxmltree@0.18.1",
      "sourcePath": "README.md",
      "sha256": "4ed952fe6175615766f1a6559d7f2868c2ac190b5cb79567e25fe6dce2f41352",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# roxmltree\n![Build Status](https://github.com/RazrFalcon/roxmltree/workflows/Rust/badge.svg)\n[![Crates.io](https://img.shields.io/crates/v/roxmltree.svg)](https://crates.io/crates/roxmltree)\n[![Documentation](https://docs.rs/roxmltree/badge.svg)](https://docs.rs/roxmltree)\n[![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-orange.svg)](https://www.rust-lang.org)\n\nRepresents an [XML 1.0](https://www.w3.org/TR/xml/) document as a read-only tree.\n\n```rust\n// Find element by id.\nlet doc = roxmltree::Document::parse(\"<rect id='rect1'/>\")?;\nlet elem = doc.descendants().find(|n| n.attribute(\"id\") == Some(\"rect1\"))?;\nassert!(elem.has_tag_name(\"rect\"));\n```\n\n## Why read-only?\n\nBecause in some cases all you need is to retrieve some data from an XML document.\nAnd for such cases, we can make a lot of optimizations.\n\nAs for *roxmltree*, it's fast not only because it's read-only, but also because\nit uses [xmlparser], which is many times faster than [xml-rs].\nSee the [Performance](#performance) section for details.\n\n## Parsing behavior\n\nSadly, XML can be parsed in many different ways. *roxmltree* tries to mimic the\nbehavior of Python's [lxml](https://lxml.de/).\nBut unlike *lxml*, *roxmltree* does support comments outside the root element.\n\nFor more details see [docs/parsing.md](https://github.com/RazrFalcon/roxmltree/blob/master/docs/parsing.md).\n\n## Alternatives\n\n| Feature/Crate                   | roxmltree        | [libxml2]           | [xmltree]        | [sxd-document]   |\n| ------------------------------- | :--------------: | :-----------------: | :--------------: | :--------------: |\n| Element namespace resolving     | ✓                | ✓                   | ✓                | ~<sup>1</sup>    |\n| Attribute namespace resolving   | ✓                | ✓                   |                  | ✓                |\n| [Entity references]             | ✓                | ✓                   | ×                | ×                |\n| [Character references]          | ✓                | ✓                   | ✓                | ✓                |\n| [Attribute-Value normalization] | ✓                | ✓                   |                  |                  |\n| Comments                        | ✓                | ✓                   |                  | ✓                |\n| Processing instructions         | ✓                | ✓                   | ✓                | ✓                |\n| UTF-8 BOM                       | ✓                | ✓                   | ×                | ×                |\n| Non UTF-8 input                 |                  | ✓                   |                  |                  |\n| Complete DTD support            |                  | ✓                   |                  |                  |\n| Position preserving<sup>2</sup> | ✓                | ✓                   |                  |                  |\n| HTML support                    |                  | ✓                   |                  |                  |\n| Tree modification               |                  | ✓                   | ✓                | ✓                |\n| Writing                         |                  | ✓                   | ✓                | ✓                |\n| No **unsafe**                   | ✓                |                     | ✓                |                  |\n| Language                        | Rust             | C                   | Rust             | Rust             |\n| Size overhead<sup>4</sup>       | **~55KiB**       | ~1.4MiB<sup>5</sup> | ~78KiB           | ~102KiB          |\n| Dependencies                    | **1**            | ?<sup>5</sup>       | 2                | 2                |\n| Tested version                  | 0.18.0           | Apple-provided      | 0.10.3           | 0.3.2            |\n| License                         | MIT / Apache-2.0 | MIT                 | MIT              | MIT              |\n\nLegend:\n\n- ✓ - supported\n- × - parsing error\n- ~ - partial\n- *nothing* - not supported\n\nNotes:\n\n1. No default namespace propagation.\n2. *roxmltree* keeps all node and attribute positions in the original document,\n   so you can easily retrieve it if you need it.\n   See [examples/print_pos.rs](examples/print_pos.rs) for details.\n3. In the `memchr` crate.\n4. Binary size overhead according to [cargo-bloat](https://github.com/RazrFalcon/cargo-bloat).\n5. Depends on build flags.\n\nThere is also `elementtree` and `treexml` crates, but they are abandoned for a long time.\n\n[Entity references]: https://www.w3.org/TR/REC-xml/#dt-entref\n[Character references]: https://www.w3.org/TR/REC-xml/#NT-CharRef\n[Attribute-Value Normalization]: https://www.w3.org/TR/REC-xml/#AVNormalize\n\n[libxml2]: http://xmlsoft.org/\n[xmltree]: https://crates.io/crates/xmltree\n[sxd-document]: https://crates.io/crates/sxd-document\n\n## Performance\n\n### Parsing\n\n```text\ntest huge_roxmltree      ... bench:   3,147,424 ns/iter (+/- 49,153)\ntest huge_libxml         ... bench:   6,850,666 ns/iter (+/- 306,180)\ntest huge_sdx_document   ... bench:   9,440,412 ns/iter (+/- 117,106)\ntest huge_xmltree        ... bench:  41,662,316 ns/iter (+/- 850,360)\n\ntest large_roxmltree     ... bench:   1,594,201 ns/iter (+/- 27,425)\ntest large_libxml        ... bench:   3,250,606 ns/iter (+/- 140,201)\ntest large_sdx_document  ... bench:   4,242,162 ns/iter (+/- 99,740)\ntest large_xmltree       ... bench:  13,980,228 ns/iter (+/- 229,363)\n\ntest medium_roxmltree    ... bench:     418,929 ns/iter (+/- 4,843)\ntest medium_libxml       ... bench:     950,984 ns/iter (+/- 34,099)\ntest medium_sdx_document ... bench:   1,618,270 ns/iter (+/- 23,466)\ntest medium_xmltree      ... bench:   4,315,974 ns/iter (+/- 31,849)\n\ntest tiny_roxmltree      ... bench:       2,654 ns/iter (+/- 103)\ntest tiny_libxml         ... bench:       8,931 ns/iter (+/- 235)\ntest tiny_sdx_document   ... bench:      11,658 ns/iter (+/- 82)\ntest tiny_xmltree        ... bench:      20,215 ns/iter (+/- 303)\n```\n\n*roxmltree* uses [xmlparser] internally,\nwhile *sdx-document* uses its own implementation,\n*xmltree* uses the [xml-rs].\nHere is a comparison between *xmlparser*, *xml-rs* and *quick-xml*:\n\n```text\ntest huge_xmlparser      ... bench:   1,672,879 ns/iter (+/- 20,140)\ntest huge_quick_xml      ... bench:   2,396,037 ns/iter (+/- 39,752)\ntest huge_xmlrs          ... bench:  36,258,312 ns/iter (+/- 180,438)\n\ntest large_xmlparser     ... bench:     730,787 ns/iter (+/- 22,924)\ntest large_quick_xml     ... bench:   1,250,053 ns/iter (+/- 21,943)\ntest large_xmlrs         ... bench:  11,239,516 ns/iter (+/- 76,937)\n\ntest medium_quick_xml    ... bench:     206,232 ns/iter (+/- 2,157)\ntest medium_xmlparser    ... bench:     240,737 ns/iter (+/- 4,531)\ntest medium_xmlrs        ... bench:   3,975,916 ns/iter (+/- 44,967)\n\ntest tiny_xmlparser      ... bench:       1,078 ns/iter (+/- 17)\ntest tiny_quick_xml      ... bench:       2,233 ns/iter (+/- 70)\ntest tiny_xmlrs          ... bench:      17,155 ns/iter (+/- 429)\n```\n\n### Iteration\n\n```text\ntest roxmltree_iter_descendants_expensive   ... bench:     255,882 ns/iter (+/- 1,427)\ntest xmltree_iter_descendants_expensive     ... bench:     372,464 ns/iter (+/- 52,938)\n\ntest roxmltree_iter_descendants_inexpensive ... bench:      20,800 ns/iter (+/- 642)\ntest xmltree_iter_descendants_inexpensive   ... bench:     133,030 ns/iter (+/- 10,546)\n\ntest roxmltree_iter_children                ... bench:       2,168 ns/iter (+/- 12)\n```\n\nWhere expensive refers to the matching done on each element. In these\nbenchmarks, *expensive* means searching for any node in the document which\ncontains a string. And *inexpensive* means searching for any element with a\nparticular name.\n\n### Notes\n\nThe benchmarks were taken on a Apple M1 Pro.\nYou can try running the benchmarks yourself by running `cargo bench` in the `benches` dir.\n\n- Since all libraries have a different XML support, benchmarking is a bit pointless.\n- Tree crates may use different *xml-rs* crate versions.\n- We bench *libxml2* using the *[rust-libxml]* wrapper crate\n- *quick-xml* is faster than *xmlparser* because it's more forgiving for the input,\n  while *xmlparser* is very strict and does a lot of checks, which are expensive.\n  So performance difference is mainly due to validation.\n\n[xml-rs]: https://crates.io/crates/xml-rs\n[quick-xml]: https://crates.io/crates/quick-xml\n[xmlparser]: https://crates.io/crates/xmlparser\n[rust-libxml]: https://github.com/KWARC/rust-libxml\n\n## Memory Overhead\n\n`roxmltree` tries to use as little memory as possible to allow parsing\nvery large (multi-GB) XML files.\n\nThe peak memory usage doesn't directly correlates with the file size\nbut rather with the amount of nodes and attributes a file has.\nHow many attributes had to be normalized (i.e. allocated).\nAnd how many text nodes had to be preprocessed (i.e. allocated).\n\n`roxmltree` never allocates element and attribute names, processing instructions\nand comments.\n\nBy disabling the `positions` feature, you can shave by 8 bytes from each node and attribute.\n\nOn average, the overhead is around 6-8x the file size.\nFor example, our 1.1GB sample XML will peak at 7.6GB RAM with default features enabled\nand at 6.8GB RAM when `positions` is disabled.\n\n## Safety\n\n- This library must not panic. Any panic should be considered a critical bug and reported.\n- This library forbids `unsafe` code.\n\n## Non-goals\n\n- Complete XML support.\n- Tree modification and writing.\n- XPath/XQuery.\n\n## API\n\nThis library uses Rust's idiomatic API based on iterators.\nIn case you are more familiar with browser/JS DOM APIs - you can check out\n[tests/dom-api.rs](tests/dom-api.rs) to see how it can be converted into a Rust one.\n\n## License\n\nLicensed under either of\n\n- [Apache License v2.0](LICENSE-APACHE)\n- [MIT license](LICENSE-MIT)\n\nat your option.\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "roxmltree@0.20.0",
      "sourcePath": "README.md",
      "sha256": "4fe693e39a50b30070b276e1f8bf6a5e9017b62423d766d986ae3f269f89b19d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# roxmltree\n![Build Status](https://github.com/RazrFalcon/roxmltree/workflows/Rust/badge.svg)\n[![Crates.io](https://img.shields.io/crates/v/roxmltree.svg)](https://crates.io/crates/roxmltree)\n[![Documentation](https://docs.rs/roxmltree/badge.svg)](https://docs.rs/roxmltree)\n[![Rust 1.60+](https://img.shields.io/badge/rust-1.60+-orange.svg)](https://www.rust-lang.org)\n\nRepresents an [XML](https://www.w3.org/TR/xml/) document as a read-only tree.\n\n```rust\n// Find element by id.\nlet doc = roxmltree::Document::parse(\"<rect id='rect1'/>\")?;\nlet elem = doc.descendants().find(|n| n.attribute(\"id\") == Some(\"rect1\"))?;\nassert!(elem.has_tag_name(\"rect\"));\n```\n\n## Why read-only?\n\nBecause in some cases all you need is to retrieve some data from an XML document.\nAnd for such cases, we can make a lot of optimizations.\n\n## Parsing behavior\n\nSadly, XML can be parsed in many different ways. *roxmltree* tries to mimic the\nbehavior of Python's [lxml](https://lxml.de/).\nFor more details see [docs/parsing.md](https://github.com/RazrFalcon/roxmltree/blob/master/docs/parsing.md).\n\n## Alternatives\n\n| Feature/Crate                   | roxmltree        | [libxml2]           | [xmltree]        | [sxd-document]   |\n| ------------------------------- | :--------------: | :-----------------: | :--------------: | :--------------: |\n| Element namespace resolving     | ✓                | ✓                   | ✓                | ~<sup>1</sup>    |\n| Attribute namespace resolving   | ✓                | ✓                   |                  | ✓                |\n| [Entity references]             | ✓                | ✓                   | ×                | ×                |\n| [Character references]          | ✓                | ✓                   | ✓                | ✓                |\n| [Attribute-Value normalization] | ✓                | ✓                   |                  |                  |\n| Comments                        | ✓                | ✓                   |                  | ✓                |\n| Processing instructions         | ✓                | ✓                   | ✓                | ✓                |\n| UTF-8 BOM                       | ✓                | ✓                   | ×                | ×                |\n| Non UTF-8 input                 |                  | ✓                   |                  |                  |\n| Complete DTD support            |                  | ✓                   |                  |                  |\n| Position preserving<sup>2</sup> | ✓                | ✓                   |                  |                  |\n| HTML support                    |                  | ✓                   |                  |                  |\n| Tree modification               |                  | ✓                   | ✓                | ✓                |\n| Writing                         |                  | ✓                   | ✓                | ✓                |\n| No **unsafe**                   | ✓                |                     | ✓                |                  |\n| Language                        | Rust             | C                   | Rust             | Rust             |\n| Dependencies                    | **0**            | -                   | 2                | 2                |\n| Tested version                  | 0.20.0           | Apple-provided      | 0.10.3           | 0.3.2            |\n| License                         | MIT / Apache-2.0 | MIT                 | MIT              | MIT              |\n\nLegend:\n\n- ✓ - supported\n- × - parsing error\n- ~ - partial\n- *nothing* - not supported\n\nNotes:\n\n1. No default namespace propagation.\n2. *roxmltree* keeps all node and attribute positions in the original document,\n   so you can easily retrieve it if you need it.\n   See [examples/print_pos.rs](examples/print_pos.rs) for details.\n\nThere is also `elementtree` and `treexml` crates, but they are abandoned for a long time.\n\n[Entity references]: https://www.w3.org/TR/REC-xml/#dt-entref\n[Character references]: https://www.w3.org/TR/REC-xml/#NT-CharRef\n[Attribute-Value Normalization]: https://www.w3.org/TR/REC-xml/#AVNormalize\n\n[libxml2]: http://xmlsoft.org/\n[xmltree]: https://crates.io/crates/xmltree\n[sxd-document]: https://crates.io/crates/sxd-document\n\n## Performance\n\nHere are some benchmarks comparing `roxmltree` to other XML tree libraries.\n\n```text\ntest huge_roxmltree      ... bench:   2,997,887 ns/iter (+/- 48,976)\ntest huge_libxml2        ... bench:   6,850,666 ns/iter (+/- 306,180)\ntest huge_sdx_document   ... bench:   9,440,412 ns/iter (+/- 117,106)\ntest huge_xmltree        ... bench:  41,662,316 ns/iter (+/- 850,360)\n\ntest large_roxmltree     ... bench:   1,494,886 ns/iter (+/- 30,384)\ntest large_libxml2       ... bench:   3,250,606 ns/iter (+/- 140,201)\ntest large_sdx_document  ... bench:   4,242,162 ns/iter (+/- 99,740)\ntest large_xmltree       ... bench:  13,980,228 ns/iter (+/- 229,363)\n\ntest medium_roxmltree    ... bench:     421,137 ns/iter (+/- 13,855)\ntest medium_libxml2      ... bench:     950,984 ns/iter (+/- 34,099)\ntest medium_sdx_document ... bench:   1,618,270 ns/iter (+/- 23,466)\ntest medium_xmltree      ... bench:   4,315,974 ns/iter (+/- 31,849)\n\ntest tiny_roxmltree      ... bench:       2,522 ns/iter (+/- 31)\ntest tiny_libxml2        ... bench:       8,931 ns/iter (+/- 235)\ntest tiny_sdx_document   ... bench:      11,658 ns/iter (+/- 82)\ntest tiny_xmltree        ... bench:      20,215 ns/iter (+/- 303)\n```\n\nWhen comparing to streaming XML parsers `roxmltree` is slightly slower than `quick-xml`,\nbut still way faster than `xmlrs`.\nNote that streaming parsers usually do not provide a proper string unescaping,\nDTD resolving and namespaces support.\n\n```text\ntest huge_quick_xml      ... bench:   2,997,887 ns/iter (+/- 48,976)\ntest huge_roxmltree      ... bench:   3,147,424 ns/iter (+/- 49,153)\ntest huge_xmlrs          ... bench:  36,258,312 ns/iter (+/- 180,438)\n\ntest large_quick_xml     ... bench:   1,250,053 ns/iter (+/- 21,943)\ntest large_roxmltree     ... bench:   1,494,886 ns/iter (+/- 30,384)\ntest large_xmlrs         ... bench:  11,239,516 ns/iter (+/- 76,937)\n\ntest medium_quick_xml    ... bench:     206,232 ns/iter (+/- 2,157)\ntest medium_roxmltree    ... bench:     421,137 ns/iter (+/- 13,855)\ntest medium_xmlrs        ... bench:   3,975,916 ns/iter (+/- 44,967)\n\ntest tiny_quick_xml      ... bench:       2,233 ns/iter (+/- 70)\ntest tiny_roxmltree      ... bench:       2,522 ns/iter (+/- 31)\ntest tiny_xmlrs          ... bench:      17,155 ns/iter (+/- 429)\n```\n\n### Notes\n\nThe benchmarks were taken on a Apple M1 Pro.\nYou can try running the benchmarks yourself by running `cargo bench` in the `benches` dir.\n\n- Since all libraries have a different XML support, benchmarking is a bit pointless.\n- We bench *libxml2* using the *[rust-libxml]* wrapper crate\n\n[xml-rs]: https://crates.io/crates/xml-rs\n[quick-xml]: https://crates.io/crates/quick-xml\n[rust-libxml]: https://github.com/KWARC/rust-libxml\n\n## Memory overhead\n\n`roxmltree` tries to use as little memory as possible to allow parsing\nvery large (multi-GB) XML files.\n\nThe peak memory usage doesn't directly correlate with the file size\nbut rather with the amount of nodes and attributes a file has.\nHow many attributes had to be normalized (i.e. allocated).\nAnd how many text nodes had to be preprocessed (i.e. allocated).\n\n`roxmltree` never allocates element and attribute names, processing instructions\nand comments.\n\nBy disabling the `positions` feature, you can shave 8 bytes from each node and attribute.\n\nOn average, the overhead is around 6-8x the file size.\nFor example, our 1.1GB sample XML will peak at 7.6GB RAM with default features enabled\nand at 6.8GB RAM when `positions` is disabled.\n\n## Safety\n\n- This library must not panic. Any panic should be considered a critical bug and reported.\n- This library forbids `unsafe` code.\n\n## API\n\nThis library uses Rust's idiomatic API based on iterators.\nIn case you are more familiar with browser/JS DOM APIs - you can check out\n[tests/dom-api.rs](tests/dom-api.rs) to see how it can be mapped onto the Rust one.\n\n## License\n\nLicensed under either of\n\n- [Apache License v2.0](LICENSE-APACHE)\n- [MIT license](LICENSE-MIT)\n\nat your option.\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "rustc_version@0.4.1",
      "sourcePath": "README.md",
      "sha256": "36d55c32ba7174f7e705faf42eab21fd6e76e9b69093715f403ba9c48e4f9f2e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "rustc-version-rs\n================\n\n[![Documentation](https://docs.rs/rustc_version/badge.svg)](https://docs.rs/rustc_version/)\n[![Crates.io](https://img.shields.io/crates/v/rustc_version.svg)](https://crates.io/crates/rustc_version)\n[![Build status](https://github.com/djc/rustc-version-rs/workflows/CI/badge.svg)](https://github.com/djc/rustc-version-rs/actions?query=workflow%3ACI)\n\nA library for querying the version of a `rustc` compiler.\n\nThis can be used by build scripts or other tools dealing with Rust sources\nto make decisions based on the version of the compiler. Current MSRV is 1.32.0.\n\nIf this is of interest, also consider looking at these other crates:\n\n* [autocfg](https://crates.io/crates/autocfg/), which helps with feature detection instead of depending on compiler versions\n* [rustversion](https://github.com/dtolnay/rustversion) provides a procedural macro with no other dependencies\n\n# Getting Started\n\n[rustc-version-rs is available on crates.io](https://crates.io/crates/rustc_version).\nIt is recommended to look there for the newest released version, as well as links to the newest builds of the docs.\n\nAt the point of the last update of this README, the latest published version could be used like this:\n\nAdd the following dependency to your Cargo manifest...\n\n```toml\n[build-dependencies]\nrustc_version = \"0.2\"\n```\n\n... and see the [docs](https://docs.rs/rustc_version) for how to use it.\n\n# Example\n\n```rust\n// This could be a cargo build script\n\nuse rustc_version::{version, version_meta, Channel, Version};\n\nfn main() {\n    // Assert we haven't travelled back in time\n    assert!(version().unwrap().major >= 1);\n\n    // Set cfg flags depending on release channel\n    match version_meta().unwrap().channel {\n        Channel::Stable => {\n            println!(\"cargo:rustc-cfg=RUSTC_IS_STABLE\");\n        }\n        Channel::Beta => {\n            println!(\"cargo:rustc-cfg=RUSTC_IS_BETA\");\n        }\n        Channel::Nightly => {\n            println!(\"cargo:rustc-cfg=RUSTC_IS_NIGHTLY\");\n        }\n        Channel::Dev => {\n            println!(\"cargo:rustc-cfg=RUSTC_IS_DEV\");\n        }\n    }\n\n    // Check for a minimum version\n    if version().unwrap() >= Version::parse(\"1.4.0\").unwrap() {\n        println!(\"cargo:rustc-cfg=compiler_has_important_bugfix\");\n    }\n}\n```\n\n## License\n\nLicensed under either of\n\n * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any\nadditional terms or conditions.\n"
    },
    {
      "package": "rustc_version@0.4.1",
      "sourcePath": "src/lib.rs",
      "sha256": "6d0dbf7bd12ba7121e6767841a0cee23b8282cc4d7c4b778a1e33129abdd7d72",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2016 rustc-version-rs developers\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n#![warn(missing_docs)]\n\n//! Simple library for getting the version information of a `rustc`\n//! compiler.\n//!\n//! This can be used by build scripts or other tools dealing with Rust sources\n//! to make decisions based on the version of the compiler.\n//!\n//! It calls `$RUSTC --version -v` and parses the output, falling\n//! back to `rustc` if `$RUSTC` is not set.\n//!\n//! # Example\n//!\n//! ```rust\n//! // This could be a cargo build script\n//!\n//! use rustc_version::{version, version_meta, Channel, Version};\n//!\n//! // Assert we haven't travelled back in time\n//! assert!(version().unwrap().major >= 1);\n//!\n//! // Set cfg flags depending on release channel\n//! match version_meta().unwrap().channel {\n//!     Channel::Stable => {\n//!         println!(\"cargo:rustc-cfg=RUSTC_IS_STABLE\");\n//!     }\n//!     Channel::Beta => {\n//!         println!(\"cargo:rustc-cfg=RUSTC_IS_BETA\");\n//!     }\n//!     Channel::Nightly => {\n//!         println!(\"cargo:rustc-cfg=RUSTC_IS_NIGHTLY\");\n//!     }\n//!     Channel::Dev => {\n//!         println!(\"cargo:rustc-cfg=RUSTC_IS_DEV\");\n//!     }\n//! }\n//!\n//! // Check for a minimum version\n//! if version().unwrap() >= Version::parse(\"1.4.0\").unwrap() {\n//!     println!(\"cargo:rustc-cfg=compiler_has_important_bugfix\");\n//! }\n//! ```\n\n#[cfg(test)]\n#[macro_use]\nextern crate doc_comment;\n\n#[cfg(test)]\ndoctest!(\"../README.md\");\n\nuse std::collections::HashMap;\nuse std::process::Command;\nuse std::{env, error, fmt, io, num, str};\nuse std::{ffi::OsString, str::FromStr};\n\n// Convenience re-export to allow version comparison without needing to add\n// semver crate.\npub use semver::Version;\n\nuse Error::*;\n\n/// Release channel of the compiler.\n#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]\npub enum Channel {\n    /// Development release channel\n    Dev,\n    /// Nightly release channel\n    Nightly,\n    /// Beta release channel\n    Beta,\n    /// Stable release channel\n    Stable,\n}\n\n/// LLVM version\n///\n/// LLVM's version numbering scheme is not semver compatible until version 4.0\n///\n/// rustc [just prints the major and minor versions], so other parts of the version are not included.\n///\n/// [just prints the major and minor versions]: https://github.com/rust-lang/rust/blob/b5c9e2448c9ace53ad5c11585803894651b18b0a/compiler/rustc_codegen_llvm/src/llvm_util.rs#L173-L178\n#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]\npub struct LlvmVersion {\n    // fields must be ordered major, minor for comparison to be correct\n    /// Major version\n    pub major: u64,\n    /// Minor version\n    pub minor: u64,\n    // TODO: expose micro version here\n}\n\nimpl fmt::Display for LlvmVersion {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"{}.{}\", self.major, self.minor)\n    }\n}\n\nimpl FromStr for LlvmVersion {\n    type Err = LlvmVersionParseError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let mut parts = s\n            .split('.')\n            .map(|part| -> Result<u64, LlvmVersionParseError> {\n                if part == \"0\" {\n                    Ok(0)\n                } else if part.starts_with('0') {\n                    Err(LlvmVersionParseError::ComponentMustNotHaveLeadingZeros)\n                } else if part.starts_with('-') || part.starts_with('+') {\n                    Err(LlvmVersionParseError::ComponentMustNotHaveSign)\n                } else {\n                    Ok(part.parse()?)\n                }\n            });\n\n        let major = parts.next().unwrap()?;\n        let mut minor = 0;\n\n        if let Some(part) = parts.next() {\n            minor = part?;\n        } else if major < 4 {\n            // LLVM versions earlier than 4.0 have significant minor versions, so require the minor version in this case.\n            return Err(LlvmVersionParseError::MinorVersionRequiredBefore4);\n        }\n\n        if let Some(Err(e)) = parts.next() {\n            return Err(e);\n        }\n\n        if parts.next().is_some() {\n            return Err(LlvmVersionParseError::TooManyComponents);\n        }\n\n        Ok(Self { major, minor })\n    }\n}\n\n/// Rustc version plus metadata like git short hash and build date.\n#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]\npub struct VersionMeta {\n    /// Version of the compiler\n    pub semver: Version,\n\n    /// Git short hash of the build of the compiler\n    pub commit_hash: Option<String>,\n\n    /// Commit date of the compiler\n    pub commit_date: Option<String>,\n\n    /// Build date of the compiler; this was removed between Rust 1.0.0 and 1.1.0.\n    pub build_date: Option<String>,\n\n    /// Release channel of the compiler\n    pub channel: Channel,\n\n    /// Host target triple of the compiler\n    pub host: String,\n\n    /// Short version string of the compiler\n    pub short_version_string: String,\n\n    /// Version of LLVM used by the compiler\n    pub llvm_version: Option<LlvmVersion>,\n}\n\nimpl VersionMeta {\n    /// Returns the version metadata for `cmd`, which should be a `rustc` command.\n    pub fn for_command(mut cmd: Command) -> Result<VersionMeta> {\n        let out = cmd\n            .arg(\"-vV\")\n            .output()\n            .map_err(Error::CouldNotExecuteCommand)?;\n\n        if !out.status.success() {\n            return Err(Error::CommandError {\n                stdout: String::from_utf8_lossy(&out.stdout).into(),\n                stderr: String::from_utf8_lossy(&out.stderr).into(),\n            });\n        }\n\n        version_meta_for(str::from_utf8(&out.stdout)?)\n    }\n}\n\n/// Returns the `rustc` SemVer version.\npub fn version() -> Result<Version> {\n    Ok(version_meta()?.semver)\n}\n\n/// Returns the `rustc` SemVer version and additional metadata\n/// like the git short hash and build date.\npub fn version_meta() -> Result<VersionMeta> {\n    let rustc = env::var_os(\"RUSTC\").unwrap_or_else(|| OsString::from(\"rustc\"));\n    let cmd = if let Some(wrapper) = env::var_os(\"RUSTC_WRAPPER\").filter(|w| !w.is_empty()) {\n        let mut cmd = Command::new(wrapper);\n        cmd.arg(rustc);\n        cmd\n    } else {\n        Command::new(rustc)\n    };\n\n    VersionMeta::for_command(cmd)\n}\n\n/// Parses a \"rustc -vV\" output string and returns\n/// the SemVer version and additional metadata\n/// like the git short hash and build date.\npub fn version_meta_for(verbose_version_string: &str) -> Result<VersionMeta> {\n    let mut map = HashMap::new();\n    for (i, line) in verbose_version_string.lines().enumerate() {\n        if i == 0 {\n            map.insert(\"short\", line);\n            continue;\n        }\n\n        let mut parts = line.splitn(2, \": \");\n        let key = match parts.next() {\n            Some(key) => key,\n            None => continue,\n        };\n\n        if let Some(value) = parts.next() {\n            map.insert(key, value);\n        }\n    }\n\n    let short_version_string = expect_key(\"short\", &map)?;\n    let host = expect_key(\"host\", &map)?;\n    let release = expect_key(\"release\", &map)?;\n    let semver: Version = release.parse()?;\n\n    let channel = match semver.pre.split('.').next().unwrap() {\n        \"\" => Channel::Stable,\n        \"dev\" => Channel::Dev,\n        \"beta\" => Channel::Beta,\n        \"nightly\" => Channel::Nightly,\n        x => return Err(Error::UnknownPreReleaseTag(x.to_owned())),\n    };\n\n    let commit_hash = expect_key_or_unknown(\"commit-hash\", &map)?;\n    let commit_date = expect_key_or_unknown(\"commit-date\", &map)?;\n    let build_date = map\n        .get(\"build-date\")\n        .filter(|&v| *v != \"unknown\")\n        .map(|&v| String::from(v));\n    let llvm_version = match map.get(\"LLVM version\") {\n        Some(&v) => Some(v.parse()?),\n        None => None,\n    };\n\n    Ok(VersionMeta {\n        semver,\n        commit_hash,\n        commit_date,\n        build_date,\n        channel,\n        host,\n        short_version_string,\n        llvm_version,\n    })\n}\n\nfn expect_key_or_unknown(key: &str, map: &HashMap<&str, &str>) -> Result<Option<String>, Error> {\n    match map.get(key) {\n        Some(&\"unknown\") => Ok(None),\n        Some(&v) => Ok(Some(String::from(v))),\n        None => Err(Error::UnexpectedVersionFormat),\n    }\n}\n\nfn expect_key(key: &str, map: &HashMap<&str, &str>) -> Result<String, Error> {\n    map.get(key)\n        .map(|&v| String::from(v))\n        .ok_or(Error::UnexpectedVersionFormat)\n}\n\n/// LLVM Version Parse Error\n#[derive(Debug)]\npub enum LlvmVersionParseError {\n    /// An error occurred in parsing a version component as an integer\n    ParseIntError(num::ParseIntError),\n    /// A version component must not have leading zeros\n    ComponentMustNotHaveLeadingZeros,\n    /// A version component has a sign\n    ComponentMustNotHaveSign,\n    /// Minor version component must be zero on LLVM versions later than 4.0\n    MinorVersionMustBeZeroAfter4,\n    /// Minor version component is required on LLVM versions earlier than 4.0\n    MinorVersionRequiredBefore4,\n    /// Too many components\n    TooManyComponents,\n}\n\nimpl From<num::ParseIntError> for LlvmVersionParseError {\n    fn from(e: num::ParseIntError) -> Self {\n        LlvmVersionParseError::ParseIntError(e)\n    }\n}\n\nimpl fmt::Display for LlvmVersionParseError {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            LlvmVersionParseError::ParseIntError(e) => {\n                write!(f, \"error parsing LLVM version component: {}\", e)\n            }\n            LlvmVersionParseError::ComponentMustNotHaveLeadingZeros => {\n                write!(f, \"a version component must not have leading zeros\")\n            }\n            LlvmVersionParseError::ComponentMustNotHaveSign => {\n                write!(f, \"a version component must not have a sign\")\n            }\n            LlvmVersionParseError::MinorVersionMustBeZeroAfter4 => write!(\n                f,\n                \"LLVM's minor version component must be 0 for versions greater than 4.0\"\n            ),\n            LlvmVersionParseError::MinorVersionRequiredBefore4 => write!(\n                f,\n                \"LLVM's minor version component is required for versions less than 4.0\"\n            ),\n            LlvmVersionParseError::TooManyComponents => write!(f, \"too many version components\"),\n        }\n    }\n}\n\nimpl error::Error for LlvmVersionParseError {\n    fn source(&self) -> Option<&(dyn error::Error + 'static)> {\n        match self {\n            LlvmVersionParseError::ParseIntError(e) => Some(e),\n            LlvmVersionParseError::ComponentMustNotHaveLeadingZeros\n            | LlvmVersionParseError::ComponentMustNotHaveSign\n            | LlvmVersionParseError::MinorVersionMustBeZeroAfter4\n            | LlvmVersionParseError::MinorVersionRequiredBefore4\n            | LlvmVersionParseError::TooManyComponents => None,\n        }\n    }\n}\n\n/// The error type for this crate.\n#[derive(Debug)]\npub enum Error {\n    /// An error occurred while trying to find the `rustc` to run.\n    CouldNotExecuteCommand(io::Error),\n    /// Error output from the command that was run.\n    CommandError {\n        /// stdout output from the command\n        stdout: String,\n        /// stderr output from the command\n        stderr: String,\n    },\n    /// The output of `rustc -vV` was not valid utf-8.\n    Utf8Error(str::Utf8Error),\n    /// The output of `rustc -vV` was not in the expected format.\n    UnexpectedVersionFormat,\n    /// An error occurred in parsing the semver.\n    SemVerError(semver::Error),\n    /// The pre-release tag is unknown.\n    UnknownPreReleaseTag(String),\n    /// An error occurred in parsing a `LlvmVersion`.\n    LlvmVersionError(LlvmVersionParseError),\n}\n\nimpl fmt::Display for Error {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match *self {\n            CouldNotExecuteCommand(ref e) => write!(f, \"could not execute command: {}\", e),\n            CommandError {\n                ref stdout,\n                ref stderr,\n            } => write!(\n                f,\n                \"error from command -- stderr:\\n\\n{}\\n\\nstderr:\\n\\n{}\",\n                stderr, stdout,\n            ),\n            Utf8Error(_) => write!(f, \"invalid UTF-8 output from `rustc -vV`\"),\n            UnexpectedVersionFormat => write!(f, \"unexpected `rustc -vV` format\"),\n            SemVerError(ref e) => write!(f, \"error parsing version: {}\", e),\n            UnknownPreReleaseTag(ref i) => write!(f, \"unknown pre-release tag: {}\", i),\n            LlvmVersionError(ref e) => write!(f, \"error parsing LLVM's version: {}\", e),\n        }\n    }\n}\n\nimpl error::Error for Error {\n    fn source(&self) -> Option<&(dyn error::Error + 'static)> {\n        match *self {\n            CouldNotExecuteCommand(ref e) => Some(e),\n            CommandError { .. } => None,\n            Utf8Error(ref e) => Some(e),\n            UnexpectedVersionFormat => None,\n            SemVerError(ref e) => Some(e),\n            UnknownPreReleaseTag(_) => None,\n            LlvmVersionError(ref e) => Some(e),\n        }\n    }\n}\n\nmacro_rules! impl_from {\n    ($($err_ty:ty => $variant:ident),* $(,)*) => {\n        $(\n            impl From<$err_ty> for Error {\n                fn from(e: $err_ty) -> Error {\n                    Error::$variant(e)\n                }\n            }\n        )*\n    }\n}\n\nimpl_from! {\n    str::Utf8Error => Utf8Error,\n    semver::Error => SemVerError,\n    LlvmVersionParseError => LlvmVersionError,\n}\n\n/// The result type for this crate.\npub type Result<T, E = Error> = std::result::Result<T, E>;\n"
    },
    {
      "package": "rustybuzz@0.7.0",
      "sourcePath": "README.md",
      "sha256": "906a15703d1dd77945b73c1d9b4ebc2ecd6707a2ed591a1fbe86205b8d34631b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# rustybuzz\n![Build Status](https://github.com/RazrFalcon/rustybuzz/workflows/Rust/badge.svg)\n[![Crates.io](https://img.shields.io/crates/v/rustybuzz.svg)](https://crates.io/crates/rustybuzz)\n[![Documentation](https://docs.rs/rustybuzz/badge.svg)](https://docs.rs/rustybuzz)\n\n`rustybuzz` is a complete [harfbuzz](https://github.com/harfbuzz/harfbuzz)'s\nshaping algorithm port to Rust.\n\nMatches `harfbuzz` v2.7.1\n\n## Why?\n\nBecause you can add `rustybuzz = \"*\"` to your project and it just works.\nNo need for a C++ compiler. No need to configure anything. No need to link to system libraries.\n\n## Conformance\n\nrustybuzz passes 98% of harfbuzz tests (1764 to be more precise).\nSo it's mostly identical, but there are still some tiny edge-cases which\nare not implemented yet or cannot be implemented at all.\n\nAlso, Apple layout is largely untested, because we cannot include Apple fonts for legal reasons.\nharfbuzz uses macOS CI instances to test it, which is extremely painful\nand we do not do this for now.\n\n## Major changes\n\n- Subsetting removed.\n- TrueType parsing is completely handled by the\n  [ttf-parser](https://github.com/RazrFalcon/ttf-parser).\n  And while the parsing algorithm is very different, it's not better or worse, just different.\n- Malformed fonts will cause an error. HarfBuzz uses fallback/dummy shaper in this case.\n- No font size property. Shaping is always using UnitsPerEm. You should scale the result manually.\n- Most of the TrueType and Unicode handling code was moved into separate crates.\n- rustybuzz doesn't interact with any system libraries and must produce exactly the same\n  results on all OS'es and targets.\n- `mort` table is not supported, since it's deprecated by Apple.\n- No Arabic fallback shaper, since it requires subsetting.\n- No `graphite` library support.\n- No automated Apple layout testing for legal reasons. We just cannot include Apple fonts.\n  harfbuzz avoids this by running such tests only on CI, which is far from ideal.\n\n## Performance\n\nAt the moment, performance isn't that great. We're 1.5-2x slower than harfbuzz.\nAlso, rustybuzz doesn't support shaping plan caching at the moment.\n\nSee [benches/README.md](./benches/README.md) for details.\n\n## Notes about the port\n\nrustybuzz is not a faithful port.\n\nharfbuzz can roughly be split into 6 parts: shaping, subsetting, TrueType parsing,\nUnicode routines, custom containers and utilities (harfbuzz doesn't use C++ std)\nand glue for system/3rd party libraries. In the mean time, rustybuzz contains only shaping.\nAll of the TrueType parsing was moved to the [ttf-parser](https://github.com/RazrFalcon/ttf-parser).\nSubsetting was removed. Unicode code was mostly moved to external crates.\nWe don't need custom containers because Rust's std is good enough.\nAnd we do not use any non Rust libraries, so no glue code either.\n\nIn the end, we still have around 20 KLOC. While harfbuzz is around 80 KLOC.\n\n## Lines of code\n\nAs mentioned above, rustybuzz has around 20 KLOC. But this is not strictly true,\nbecause there are a lot of auto-generated data tables.\n\nYou can find the \"real\" code size using:\n\n```sh\ntokei --exclude unicode_norm.rs --exclude complex/vowel_constraints.rs \\\n      --exclude '*_machine.rs' --exclude '*_table.rs' src\n```\n\nWhich gives us around 13 KLOC, which is still a lot.\n\n## Future work\n\nSince the port is finished, there is not much to do other than syncing it with\na new harfbuzz releases.\nBut there are still a lot of room for performance optimizations and refactoring.\n\nAlso, despite the fact that harfbuzz has a vast test suite, there are still a lot of\nthings left to test.\n\n## Safety\n\nThe library is completely safe.\n\nWe do have one `unsafe` to cast between two POD structures, which is perfectly safe.\nBut except that, there are no `unsafe` in this library and in most of its dependencies\n(excluding `bytemuck`).\n\n## Alternatives\n\n- [harfbuzz_rs](https://crates.io/crates/harfbuzz_rs) - bindings to the actual harfbuzz library.\n  As of v2 doesn't expose subsetting and glyph outlining, which harfbuzz supports.\n- [allsorts](https://github.com/yeslogic/allsorts) - shaper and subsetter.\n  As of v0.6 doesn't support variable fonts and\n  [Apple Advanced Typography](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html).\n  Relies on some unsafe code.\n- [swash](https://github.com/dfrg/swash) - Supports variable fonts, text layout and rendering.\n  No subsetting. Relies on some unsafe code. As of v0.1.4 has zero tests.\n\n## License\n\n`rustybuzz` is licensed under the **MIT**.\n\n`harfbuzz` is [licensed](https://github.com/harfbuzz/harfbuzz/blob/master/COPYING) under the **Old MIT**\n"
    },
    {
      "package": "semver@1.0.28",
      "sourcePath": "README.md",
      "sha256": "f1f736262db1f11353bca2fbdde906bfbb1d54e5eb7497dd110984f5eebb801e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "semver\n======\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/semver-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/semver)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/semver.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/semver)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-semver-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/semver)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/semver/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/semver/actions?query=branch%3Amaster)\n\nA parser and evaluator for Cargo's flavor of Semantic Versioning.\n\nSemantic Versioning (see <https://semver.org>) is a guideline for how version\nnumbers are assigned and incremented. It is widely followed within the\nCargo/crates.io ecosystem for Rust.\n\n```toml\n[dependencies]\nsemver = \"1.0\"\n```\n\n<br>\n\n## Example\n\n```rust\nuse semver::{BuildMetadata, Prerelease, Version, VersionReq};\n\nfn main() {\n    let req = VersionReq::parse(\">=1.2.3, <1.8.0\").unwrap();\n\n    // Check whether this requirement matches version 1.2.3-alpha.1 (no)\n    let version = Version {\n        major: 1,\n        minor: 2,\n        patch: 3,\n        pre: Prerelease::new(\"alpha.1\").unwrap(),\n        build: BuildMetadata::EMPTY,\n    };\n    assert!(!req.matches(&version));\n\n    // Check whether it matches 1.3.0 (yes it does)\n    let version = Version::parse(\"1.3.0\").unwrap();\n    assert!(req.matches(&version));\n}\n```\n\n<br>\n\n## Scope of this crate\n\nBesides Cargo, several other package ecosystems and package managers for other\nlanguages also use SemVer:&ensp;RubyGems/Bundler for Ruby, npm for JavaScript,\nComposer for PHP, CocoaPods for Objective-C...\n\nThe `semver` crate is specifically intended to implement Cargo's interpretation\nof Semantic Versioning.\n\nWhere the various tools differ in their interpretation or implementation of the\nspec, this crate follows the implementation choices made by Cargo. If you are\noperating on version numbers from some other package ecosystem, you will want to\nuse a different semver library which is appropriate to that ecosystem.\n\nThe extent of Cargo's SemVer support is documented in the *[Specifying\nDependencies]* chapter of the Cargo reference.\n\n[Specifying Dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "serde@1.0.229",
      "sourcePath": "README.md",
      "sha256": "0a33359b87747c0ae2437374c1dd4fc4d151ae3122b3931e2757b45d0ed519b8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# Serde &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![serde msrv]][Rust 1.56] [![serde_derive msrv]][Rust 1.71]\n\n[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master\n[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster\n[Latest Version]: https://img.shields.io/crates/v/serde.svg\n[crates.io]: https://crates.io/crates/serde\n[serde msrv]: https://img.shields.io/crates/msrv/serde.svg?label=serde%20msrv&color=lightgray\n[serde_derive msrv]: https://img.shields.io/crates/msrv/serde_derive.svg?label=serde_derive%20msrv&color=lightgray\n[Rust 1.56]: https://blog.rust-lang.org/2021/10/21/Rust-1.56.0/\n[Rust 1.71]: https://blog.rust-lang.org/2023/07/13/Rust-1.71.0/\n\n**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**\n\n---\n\nYou may be looking for:\n\n- [An overview of Serde](https://serde.rs)\n- [Data formats supported by Serde](https://serde.rs/#data-formats)\n- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)\n- [Examples](https://serde.rs/examples.html)\n- [API documentation](https://docs.rs/serde)\n- [Release notes](https://github.com/serde-rs/serde/releases)\n\n## Serde in action\n\n<details>\n<summary>\nClick to show Cargo.toml.\n<a href=\"https://play.rust-lang.org/?edition=2021&gist=72755f28f99afc95e01d63174b28c1f5\" target=\"_blank\">Run this code in the playground.</a>\n</summary>\n\n```toml\n[dependencies]\n\n# The core APIs, including the Serialize and Deserialize traits. Always\n# required when using Serde. The \"derive\" feature is only required when\n# using #[derive(Serialize, Deserialize)] to make Serde work with structs\n# and enums defined in your crate.\nserde = { version = \"1.0\", features = [\"derive\"] }\n\n# Each data format lives in its own crate; the sample code below uses JSON\n# but you may be using a different one.\nserde_json = \"1.0\"\n```\n\n</details>\n<p></p>\n\n```rust\nuse serde::{Deserialize, Serialize};\n\n#[derive(Serialize, Deserialize, Debug)]\nstruct Point {\n    x: i32,\n    y: i32,\n}\n\nfn main() {\n    let point = Point { x: 1, y: 2 };\n\n    // Convert the Point to a JSON string.\n    let serialized = serde_json::to_string(&point).unwrap();\n\n    // Prints serialized = {\"x\":1,\"y\":2}\n    println!(\"serialized = {}\", serialized);\n\n    // Convert the JSON string back to a Point.\n    let deserialized: Point = serde_json::from_str(&serialized).unwrap();\n\n    // Prints deserialized = Point { x: 1, y: 2 }\n    println!(\"deserialized = {:?}\", deserialized);\n}\n```\n\n## Getting help\n\nSerde is one of the most widely used Rust libraries so any place that Rustaceans\ncongregate will be able to help you out. For chat, consider trying the\n[#rust-questions] or [#rust-beginners] channels of the unofficial community\nDiscord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or\n[#beginners] channels of the official Rust Project Discord (invite:\n<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For\nasynchronous, consider the [\\[rust\\] tag on StackOverflow][stackoverflow], the\n[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust\n[Discourse forum][discourse]. It's acceptable to file a support issue in this\nrepo but they tend not to get as many eyes as any of the above and may get\nclosed without a response after some time.\n\n[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513\n[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281\n[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848\n[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612\n[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general\n[stackoverflow]: https://stackoverflow.com/questions/tagged/rust\n[/r/rust]: https://www.reddit.com/r/rust\n[discourse]: https://users.rust-lang.org\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in Serde by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "serde_derive@1.0.229",
      "sourcePath": "README.md",
      "sha256": "0a33359b87747c0ae2437374c1dd4fc4d151ae3122b3931e2757b45d0ed519b8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# Serde &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![serde msrv]][Rust 1.56] [![serde_derive msrv]][Rust 1.71]\n\n[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master\n[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster\n[Latest Version]: https://img.shields.io/crates/v/serde.svg\n[crates.io]: https://crates.io/crates/serde\n[serde msrv]: https://img.shields.io/crates/msrv/serde.svg?label=serde%20msrv&color=lightgray\n[serde_derive msrv]: https://img.shields.io/crates/msrv/serde_derive.svg?label=serde_derive%20msrv&color=lightgray\n[Rust 1.56]: https://blog.rust-lang.org/2021/10/21/Rust-1.56.0/\n[Rust 1.71]: https://blog.rust-lang.org/2023/07/13/Rust-1.71.0/\n\n**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**\n\n---\n\nYou may be looking for:\n\n- [An overview of Serde](https://serde.rs)\n- [Data formats supported by Serde](https://serde.rs/#data-formats)\n- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)\n- [Examples](https://serde.rs/examples.html)\n- [API documentation](https://docs.rs/serde)\n- [Release notes](https://github.com/serde-rs/serde/releases)\n\n## Serde in action\n\n<details>\n<summary>\nClick to show Cargo.toml.\n<a href=\"https://play.rust-lang.org/?edition=2021&gist=72755f28f99afc95e01d63174b28c1f5\" target=\"_blank\">Run this code in the playground.</a>\n</summary>\n\n```toml\n[dependencies]\n\n# The core APIs, including the Serialize and Deserialize traits. Always\n# required when using Serde. The \"derive\" feature is only required when\n# using #[derive(Serialize, Deserialize)] to make Serde work with structs\n# and enums defined in your crate.\nserde = { version = \"1.0\", features = [\"derive\"] }\n\n# Each data format lives in its own crate; the sample code below uses JSON\n# but you may be using a different one.\nserde_json = \"1.0\"\n```\n\n</details>\n<p></p>\n\n```rust\nuse serde::{Deserialize, Serialize};\n\n#[derive(Serialize, Deserialize, Debug)]\nstruct Point {\n    x: i32,\n    y: i32,\n}\n\nfn main() {\n    let point = Point { x: 1, y: 2 };\n\n    // Convert the Point to a JSON string.\n    let serialized = serde_json::to_string(&point).unwrap();\n\n    // Prints serialized = {\"x\":1,\"y\":2}\n    println!(\"serialized = {}\", serialized);\n\n    // Convert the JSON string back to a Point.\n    let deserialized: Point = serde_json::from_str(&serialized).unwrap();\n\n    // Prints deserialized = Point { x: 1, y: 2 }\n    println!(\"deserialized = {:?}\", deserialized);\n}\n```\n\n## Getting help\n\nSerde is one of the most widely used Rust libraries so any place that Rustaceans\ncongregate will be able to help you out. For chat, consider trying the\n[#rust-questions] or [#rust-beginners] channels of the unofficial community\nDiscord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or\n[#beginners] channels of the official Rust Project Discord (invite:\n<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For\nasynchronous, consider the [\\[rust\\] tag on StackOverflow][stackoverflow], the\n[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust\n[Discourse forum][discourse]. It's acceptable to file a support issue in this\nrepo but they tend not to get as many eyes as any of the above and may get\nclosed without a response after some time.\n\n[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513\n[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281\n[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848\n[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612\n[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general\n[stackoverflow]: https://stackoverflow.com/questions/tagged/rust\n[/r/rust]: https://www.reddit.com/r/rust\n[discourse]: https://users.rust-lang.org\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in Serde by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "serde_json@1.0.151",
      "sourcePath": "README.md",
      "sha256": "10cb8c14d9d29f29a031329747b352fc149a689b449ee5a8abb43712695aed72",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# Serde JSON &emsp; [![Build Status]][actions] [![Latest Version]][crates.io]\n\n[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/json/ci.yml?branch=master\n[actions]: https://github.com/serde-rs/json/actions?query=branch%3Amaster\n[Latest Version]: https://img.shields.io/crates/v/serde_json.svg\n[crates.io]: https://crates.io/crates/serde\\_json\n\n**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**\n\n---\n\n```toml\n[dependencies]\nserde_json = \"1.0\"\n```\n\nYou may be looking for:\n\n- [JSON API documentation](https://docs.rs/serde_json)\n- [Serde API documentation](https://docs.rs/serde)\n- [Detailed documentation about Serde](https://serde.rs/)\n- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)\n- [Release notes](https://github.com/serde-rs/json/releases)\n\nJSON is a ubiquitous open-standard format that uses human-readable text to\ntransmit data objects consisting of key-value pairs.\n\n```json\n{\n    \"name\": \"John Doe\",\n    \"age\": 43,\n    \"address\": {\n        \"street\": \"10 Downing Street\",\n        \"city\": \"London\"\n    },\n    \"phones\": [\n        \"+44 1234567\",\n        \"+44 2345678\"\n    ]\n}\n```\n\nThere are three common ways that you might find yourself needing to work with\nJSON data in Rust.\n\n - **As text data.** An unprocessed string of JSON data that you receive on an\n   HTTP endpoint, read from a file, or prepare to send to a remote server.\n - **As an untyped or loosely typed representation.** Maybe you want to check\n   that some JSON data is valid before passing it on, but without knowing the\n   structure of what it contains. Or you want to do very basic manipulations\n   like insert a key in a particular spot.\n - **As a strongly typed Rust data structure.** When you expect all or most of\n   your data to conform to a particular structure and want to get real work done\n   without JSON's loosey-goosey nature tripping you up.\n\nSerde JSON provides efficient, flexible, safe ways of converting data between\neach of these representations.\n\n## Operating on untyped JSON values\n\nAny valid JSON data can be manipulated in the following recursive enum\nrepresentation. This data structure is [`serde_json::Value`][value].\n\n```rust\nenum Value {\n    Null,\n    Bool(bool),\n    Number(Number),\n    String(String),\n    Array(Vec<Value>),\n    Object(Map<String, Value>),\n}\n```\n\nA string of JSON data can be parsed into a `serde_json::Value` by the\n[`serde_json::from_str`][from_str] function. There is also\n[`from_slice`][from_slice] for parsing from a byte slice `&[u8]` and\n[`from_reader`][from_reader] for parsing from any `io::Read` like a File or a\nTCP stream.\n\n<div align=\"right\">\n<a href=\"https://play.rust-lang.org/?edition=2018&gist=d69d8e3156d4bb81c4461b60b772ab72\" target=\"_blank\">\n<img align=\"center\" width=\"85\" src=\"https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png\">\n</a>\n</div>\n\n```rust\nuse serde_json::{Result, Value};\n\nfn untyped_example() -> Result<()> {\n    // Some JSON input data as a &str. Maybe this comes from the user.\n    let data = r#\"\n        {\n            \"name\": \"John Doe\",\n            \"age\": 43,\n            \"phones\": [\n                \"+44 1234567\",\n                \"+44 2345678\"\n            ]\n        }\"#;\n\n    // Parse the string of data into serde_json::Value.\n    let v: Value = serde_json::from_str(data)?;\n\n    // Access parts of the data by indexing with square brackets.\n    println!(\"Please call {} at the number {}\", v[\"name\"], v[\"phones\"][0]);\n\n    Ok(())\n}\n```\n\nThe result of square bracket indexing like `v[\"name\"]` is a borrow of the data\nat that index, so the type is `&Value`. A JSON map can be indexed with string\nkeys, while a JSON array can be indexed with integer keys. If the type of the\ndata is not right for the type with which it is being indexed, or if a map does\nnot contain the key being indexed, or if the index into a vector is out of\nbounds, the returned element is `Value::Null`.\n\nWhen a `Value` is printed, it is printed as a JSON string. So in the code above,\nthe output looks like `Please call \"John Doe\" at the number \"+44 1234567\"`. The\nquotation marks appear because `v[\"name\"]` is a `&Value` containing a JSON\nstring and its JSON representation is `\"John Doe\"`. Printing as a plain string\nwithout quotation marks involves converting from a JSON string to a Rust string\nwith [`as_str()`] or avoiding the use of `Value` as described in the following\nsection.\n\n[`as_str()`]: https://docs.rs/serde_json/1/serde_json/enum.Value.html#method.as_str\n\nThe `Value` representation is sufficient for very basic tasks but can be tedious\nto work with for anything more significant. Error handling is verbose to\nimplement correctly, for example imagine trying to detect the presence of\nunrecognized fields in the input data. The compiler is powerless to help you\nwhen you make a mistake, for example imagine typoing `v[\"name\"]` as `v[\"nmae\"]`\nin one of the dozens of places it is used in your code.\n\n## Parsing JSON as strongly typed data structures\n\nSerde provides a powerful way of mapping JSON data into Rust data structures\nlargely automatically.\n\n<div align=\"right\">\n<a href=\"https://play.rust-lang.org/?edition=2018&gist=15cfab66d38ff8a15a9cf1d8d897ac68\" target=\"_blank\">\n<img align=\"center\" width=\"85\" src=\"https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png\">\n</a>\n</div>\n\n```rust\nuse serde::{Deserialize, Serialize};\nuse serde_json::Result;\n\n#[derive(Serialize, Deserialize)]\nstruct Person {\n    name: String,\n    age: u8,\n    phones: Vec<String>,\n}\n\nfn typed_example() -> Result<()> {\n    // Some JSON input data as a &str. Maybe this comes from the user.\n    let data = r#\"\n        {\n            \"name\": \"John Doe\",\n            \"age\": 43,\n            \"phones\": [\n                \"+44 1234567\",\n                \"+44 2345678\"\n            ]\n        }\"#;\n\n    // Parse the string of data into a Person object. This is exactly the\n    // same function as the one that produced serde_json::Value above, but\n    // now we are asking it for a Person as output.\n    let p: Person = serde_json::from_str(data)?;\n\n    // Do things just like with any other Rust data structure.\n    println!(\"Please call {} at the number {}\", p.name, p.phones[0]);\n\n    Ok(())\n}\n```\n\nThis is the same `serde_json::from_str` function as before, but this time we\nassign the return value to a variable of type `Person` so Serde will\nautomatically interpret the input data as a `Person` and produce informative\nerror messages if the layout does not conform to what a `Person` is expected to\nlook like.\n\nAny type that implements Serde's `Deserialize` trait can be deserialized this\nway. This includes built-in Rust standard library types like `Vec<T>` and\n`HashMap<K, V>`, as well as any structs or enums annotated with\n`#[derive(Deserialize)]`.\n\nOnce we have `p` of type `Person`, our IDE and the Rust compiler can help us use\nit correctly like they do for any other Rust code. The IDE can autocomplete\nfield names to prevent typos, which was impossible in the `serde_json::Value`\nrepresentation. And the Rust compiler can check that when we write\n`p.phones[0]`, then `p.phones` is guaranteed to be a `Vec<String>` so indexing\ninto it makes sense and produces a `String`.\n\nThe necessary setup for using Serde's derive macros is explained on the *[Using\nderive]* page of the Serde site.\n\n[Using derive]: https://serde.rs/derive.html\n\n## Constructing JSON values\n\nSerde JSON provides a [`json!` macro][macro] to build `serde_json::Value`\nobjects with very natural JSON syntax.\n\n<div align=\"right\">\n<a href=\"https://play.rust-lang.org/?edition=2018&gist=6ccafad431d72b62e77cc34c8e879b24\" target=\"_blank\">\n<img align=\"center\" width=\"85\" src=\"https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png\">\n</a>\n</div>\n\n```rust\nuse serde_json::json;\n\nfn main() {\n    // The type of `john` is `serde_json::Value`\n    let john = json!({\n        \"name\": \"John Doe\",\n        \"age\": 43,\n        \"phones\": [\n            \"+44 1234567\",\n            \"+44 2345678\"\n        ]\n    });\n\n    println!(\"first phone number: {}\", john[\"phones\"][0]);\n\n    // Convert to a string of JSON and print it out\n    println!(\"{}\", john.to_string());\n}\n```\n\nThe `Value::to_string()` function converts a `serde_json::Value` into a `String`\nof JSON text.\n\nOne neat thing about the `json!` macro is that variables and expressions can be\ninterpolated directly into the JSON value as you are building it. Serde will\ncheck at compile time that the value you are interpolating is able to be\nrepresented as JSON.\n\n<div align=\"right\">\n<a href=\"https://play.rust-lang.org/?edition=2018&gist=f9101a6e61dfc9e02c6a67f315ed24f2\" target=\"_blank\">\n<img align=\"center\" width=\"85\" src=\"https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png\">\n</a>\n</div>\n\n```rust\nlet full_name = \"John Doe\";\nlet age_last_year = 42;\n\n// The type of `john` is `serde_json::Value`\nlet john = json!({\n    \"name\": full_name,\n    \"age\": age_last_year + 1,\n    \"phones\": [\n        format!(\"+44 {}\", random_phone())\n    ]\n});\n```\n\nThis is amazingly convenient, but we have the problem we had before with\n`Value`: the IDE and Rust compiler cannot help us if we get it wrong. Serde JSON\nprovides a better way of serializing strongly-typed data structures into JSON\ntext.\n\n## Creating JSON by serializing data structures\n\nA data structure can be converted to a JSON string by\n[`serde_json::to_string`][to_string]. There is also\n[`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and\n[`serde_json::to_writer`][to_writer] which serializes to any `io::Write`\nsuch as a File or a TCP stream.\n\n<div align=\"right\">\n<a href=\"https://play.rust-lang.org/?edition=2018&gist=3472242a08ed2ff88a944f2a2283b0ee\" target=\"_blank\">\n<img align=\"center\" width=\"85\" src=\"https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png\">\n</a>\n</div>\n\n```rust\nuse serde::{Deserialize, Serialize};\nuse serde_json::Result;\n\n#[derive(Serialize, Deserialize)]\nstruct Address {\n    street: String,\n    city: String,\n}\n\nfn print_an_address() -> Result<()> {\n    // Some data structure.\n    let address = Address {\n        street: \"10 Downing Street\".to_owned(),\n        city: \"London\".to_owned(),\n    };\n\n    // Serialize it to a JSON string.\n    let j = serde_json::to_string(&address)?;\n\n    // Print, write to a file, or send to an HTTP server.\n    println!(\"{}\", j);\n\n    Ok(())\n}\n```\n\nAny type that implements Serde's `Serialize` trait can be serialized this way.\nThis includes built-in Rust standard library types like `Vec<T>` and `HashMap<K,\nV>`, as well as any structs or enums annotated with `#[derive(Serialize)]`.\n\n## Performance\n\nIt is fast. You should expect in the ballpark of 500 to 1000 megabytes per\nsecond deserialization and 600 to 900 megabytes per second serialization,\ndepending on the characteristics of your data. This is competitive with the\nfastest C and C++ JSON libraries or even 30% faster for many use cases.\nBenchmarks live in the [serde-rs/json-benchmark] repo.\n\n[serde-rs/json-benchmark]: https://github.com/serde-rs/json-benchmark\n\n## Getting help\n\nSerde is one of the most widely used Rust libraries, so any place that\nRustaceans congregate will be able to help you out. For chat, consider trying\nthe [#rust-questions] or [#rust-beginners] channels of the unofficial community\nDiscord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or\n[#beginners] channels of the official Rust Project Discord (invite:\n<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For\nasynchronous, consider the [\\[rust\\] tag on StackOverflow][stackoverflow], the\n[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust\n[Discourse forum][discourse]. It's acceptable to file a support issue in this\nrepo, but they tend not to get as many eyes as any of the above and may get\nclosed without a response after some time.\n\n[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513\n[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281\n[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848\n[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612\n[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general\n[stackoverflow]: https://stackoverflow.com/questions/tagged/rust\n[/r/rust]: https://www.reddit.com/r/rust\n[discourse]: https://users.rust-lang.org\n\n## No-std support\n\nAs long as there is a memory allocator, it is possible to use serde_json without\nthe rest of the Rust standard library. Disable the default \"std\" feature and\nenable the \"alloc\" feature:\n\n```toml\n[dependencies]\nserde_json = { version = \"1.0\", default-features = false, features = [\"alloc\"] }\n```\n\nFor JSON support in Serde without a memory allocator, please see the\n[`serde-json-core`] crate.\n\n[`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core\n\n[value]: https://docs.rs/serde_json/1/serde_json/value/enum.Value.html\n[from_str]: https://docs.rs/serde_json/1/serde_json/de/fn.from_str.html\n[from_slice]: https://docs.rs/serde_json/1/serde_json/de/fn.from_slice.html\n[from_reader]: https://docs.rs/serde_json/1/serde_json/de/fn.from_reader.html\n[to_string]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_string.html\n[to_vec]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_vec.html\n[to_writer]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_writer.html\n[macro]: https://docs.rs/serde_json/1/serde_json/macro.json.html\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "serde_json@1.0.151",
      "sourcePath": "src/lexical/mod.rs",
      "sha256": "ace2ccea2cd541f019a84b9eeb3b9ecd88daf6bccbe9edf0eac00b62704f47c4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// The code in this module is derived from the `lexical` crate by @Alexhuszagh\n// which the author condensed into this minimal subset for use in serde_json.\n// For the serde_json use case we care more about reliably round tripping all\n// possible floating point values than about parsing any arbitrarily long string\n// of digits with perfect accuracy, as the latter would take a high cost in\n// compile time and performance.\n//\n// Dual licensed as MIT and Apache 2.0 just like the rest of serde_json, but\n// copyright Alexander Huszagh.\n\n//! Fast, minimal float-parsing algorithm.\n\n// MODULES\npub(crate) mod algorithm;\nmod bhcomp;\nmod bignum;\nmod cached;\nmod cached_float80;\nmod digit;\nmod errors;\npub(crate) mod exponent;\npub(crate) mod float;\nmod large_powers;\npub(crate) mod math;\npub(crate) mod num;\npub(crate) mod parse;\npub(crate) mod rounding;\nmod shift;\nmod small_powers;\n\n#[cfg(fast_arithmetic = \"32\")]\nmod large_powers32;\n\n#[cfg(fast_arithmetic = \"64\")]\nmod large_powers64;\n\n// API\npub use self::parse::{parse_concise_float, parse_truncated_float};\n"
    },
    {
      "package": "shlex@2.0.1",
      "sourcePath": "README.md",
      "sha256": "082e505bba5dffc5904af5602b45d01129173e617db62c81e6c11d71c964ea71",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "[![ci badge]][ci link] [![crates.io badge]][crates.io link] [![docs.rs badge]][docs.rs link]\n\n[crates.io badge]: https://img.shields.io/crates/v/shlex.svg?style=flat-square\n[crates.io link]: https://crates.io/crates/shlex\n[docs.rs badge]: https://img.shields.io/badge/docs-online-dddddd.svg?style=flat-square\n[docs.rs link]: https://docs.rs/shlex\n[ci badge]: https://img.shields.io/github/actions/workflow/status/comex/rust-shlex/test.yml?branch=master&style=flat-square\n[ci link]: https://github.com/comex/rust-shlex/actions\n\nSame idea as (but implementation not directly based on) the Python shlex\nmodule. However, this implementation does not support any of the Python\nmodule's customization because it makes parsing slower and is fairly useless.\nYou only get the default settings of shlex.split, which mimic the POSIX shell:\n<https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html>\n\nThis implementation also deviates from the Python version in not treating \\r\nspecially, which I believe is more compliant.\n\nThis crate can be used on either normal Rust strings, or on byte strings with\nthe `bytes` module. The algorithms used are oblivious to UTF-8 high bytes, so\ninternally they all work on bytes directly as a micro-optimization.\n\nDisabling the `std` feature (which is enabled by default) will allow the crate\nto work in `no_std` environments, where the `alloc` crate, and a global\nallocator, are available.\n\n# LICENSE\n\nThe source code in this repository is Licensed under either of\n- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\n  https://www.apache.org/licenses/LICENSE-2.0)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or\n  https://opensource.org/licenses/MIT)\n\nat your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "shlex@2.0.1",
      "sourcePath": "src/bytes.rs",
      "sha256": "14ac6d79be6cd93543de6cbba8a4c07181aacf7d02d01a1e5f51b63a89bf11c0",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 Nicholas Allegra (comex).\n// Licensed under the Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> or\n// the MIT license <https://opensource.org/licenses/MIT>, at your option. This file may not be\n// copied, modified, or distributed except according to those terms.\n\n//! [`Shlex`] and friends for byte strings.\n//!\n//! This is used internally by the [outer module](crate), and may be more\n//! convenient if you are working with byte slices (`[u8]`) or types that are\n//! wrappers around bytes, such as [`OsStr`](std::ffi::OsStr):\n//!\n//! ```rust\n//! #[cfg(unix)] {\n//!     use shlex::bytes::try_quote;\n//!     use std::ffi::OsStr;\n//!     use std::os::unix::ffi::OsStrExt;\n//!\n//!     // `\\x80` is invalid in UTF-8.\n//!     let os_str = OsStr::from_bytes(b\"a\\x80b c\");\n//!     assert_eq!(try_quote(os_str.as_bytes()).unwrap(), &b\"'a\\x80b c'\"[..]);\n//! }\n//! ```\n//!\n//! (On Windows, `OsStr` uses 16 bit wide characters so this will not work.)\n\nextern crate alloc;\nuse alloc::vec::Vec;\nuse alloc::borrow::Cow;\n#[cfg(test)]\nuse alloc::borrow::ToOwned;\n#[cfg(all(doc, not(doctest)))]\nuse crate::{self as shlex, quoting_warning};\n\nuse super::QuoteError;\n\n/// An iterator that takes an input byte string and splits it into the words using the same syntax as\n/// the POSIX shell.\npub struct Shlex<'a> {\n    in_iter: core::slice::Iter<'a, u8>,\n    /// The number of newlines read so far, plus one.\n    pub line_no: usize,\n    /// An input string is erroneous if it ends while inside a quotation or right after an\n    /// unescaped backslash.  Since Iterator does not have a mechanism to return an error, if that\n    /// happens, Shlex just throws out the last token, ends the iteration, and sets 'had_error' to\n    /// true; best to check it after you're done iterating.\n    pub had_error: bool,\n}\n\nimpl<'a> Shlex<'a> {\n    pub fn new(in_bytes: &'a [u8]) -> Self {\n        Shlex {\n            in_iter: in_bytes.iter(),\n            line_no: 1,\n            had_error: false,\n        }\n    }\n\n    fn parse_word(&mut self, mut ch: u8) -> Option<Vec<u8>> {\n        let mut result: Vec<u8> = Vec::new();\n        loop {\n            match ch as char {\n                '\"' => if let Err(()) = self.parse_double(&mut result) {\n                    self.had_error = true;\n                    return None;\n                },\n                '\\'' => if let Err(()) = self.parse_single(&mut result) {\n                    self.had_error = true;\n                    return None;\n                },\n                '\\\\' => if let Some(ch2) = self.next_char() {\n                    if ch2 != b'\\n' { result.push(ch2); }\n                } else {\n                    self.had_error = true;\n                    return None;\n                },\n                ' ' | '\\t' | '\\n' => { break; },\n                _ => { result.push(ch); },\n            }\n            if let Some(ch2) = self.next_char() { ch = ch2; } else { break; }\n        }\n        Some(result)\n    }\n\n    fn parse_double(&mut self, result: &mut Vec<u8>) -> Result<(), ()> {\n        loop {\n            if let Some(ch2) = self.next_char() {\n                match ch2 as char {\n                    '\\\\' => {\n                        if let Some(ch3) = self.next_char() {\n                            match ch3 as char {\n                                // \\$ => $\n                                '$' | '`' | '\"' | '\\\\' => { result.push(ch3); },\n                                // \\<newline> => nothing\n                                '\\n' => {},\n                                // \\x => =x\n                                _ => { result.push(b'\\\\'); result.push(ch3); }\n                            }\n                        } else {\n                            return Err(());\n                        }\n                    },\n                    '\"' => { return Ok(()); },\n                    _ => { result.push(ch2); },\n                }\n            } else {\n                return Err(());\n            }\n        }\n    }\n\n    fn parse_single(&mut self, result: &mut Vec<u8>) -> Result<(), ()> {\n        loop {\n            if let Some(ch2) = self.next_char() {\n                match ch2 as char {\n                    '\\'' => { return Ok(()); },\n                    _ => { result.push(ch2); },\n                }\n            } else {\n                return Err(());\n            }\n        }\n    }\n\n    fn next_char(&mut self) -> Option<u8> {\n        let res = self.in_iter.next().copied();\n        if res == Some(b'\\n') { self.line_no += 1; }\n        res\n    }\n}\n\nimpl Iterator for Shlex<'_> {\n    type Item = Vec<u8>;\n    fn next(&mut self) -> Option<Self::Item> {\n        if let Some(mut ch) = self.next_char() {\n            // skip initial whitespace\n            loop {\n                match ch as char {\n                    ' ' | '\\t' | '\\n' => {},\n                    '#' => {\n                        while let Some(ch2) = self.next_char() {\n                            if ch2 as char == '\\n' { break; }\n                        }\n                    },\n                    _ => { break; }\n                }\n                if let Some(ch2) = self.next_char() { ch = ch2; } else { return None; }\n            }\n            self.parse_word(ch)\n        } else { // no initial character\n            None\n        }\n    }\n\n}\n\n/// Convenience function that consumes the whole byte string at once.  Returns None if the input was\n/// erroneous.\npub fn split(in_bytes: &[u8]) -> Option<Vec<Vec<u8>>> {\n    let mut shl = Shlex::new(in_bytes);\n    let res = shl.by_ref().collect();\n    if shl.had_error { None } else { Some(res) }\n}\n\n/// A more configurable interface to quote strings.  If you only want the default settings you can\n/// use the convenience functions [`try_quote`] and [`try_join`].\n///\n/// The string equivalent is [`shlex::Quoter`].\n#[derive(Default, Debug, Clone)]\npub struct Quoter {\n    allow_nul: bool,\n    // TODO: more options\n}\n\nimpl Quoter {\n    /// Create a new [`Quoter`] with default settings.\n    #[inline]\n    pub fn new() -> Self {\n        Self::default()\n    }\n\n    /// Set whether to allow [nul bytes](quoting_warning#nul-bytes).  By default they are not\n    /// allowed and will result in an error of [`QuoteError::Nul`].\n    #[inline]\n    pub fn allow_nul(mut self, allow: bool) -> Self {\n        self.allow_nul = allow;\n        self\n    }\n\n    /// Convenience function that consumes an iterable of words and turns it into a single byte string,\n    /// quoting words when necessary. Consecutive words will be separated by a single space.\n    pub fn join<'a, I: IntoIterator<Item = &'a [u8]>>(&self, words: I) -> Result<Vec<u8>, QuoteError> {\n        Ok(words.into_iter()\n            .map(|word| self.quote(word))\n            .collect::<Result<Vec<Cow<[u8]>>, QuoteError>>()?\n            .join(&b' '))\n    }\n\n    /// Given a single word, return a byte string suitable to encode it as a shell argument.\n    ///\n    /// If given valid UTF-8, this will never produce invalid UTF-8. This is because it only\n    /// ever inserts valid ASCII characters before or after existing ASCII characters (or\n    /// returns two single quotes if the input was an empty string). It will never modify a\n    /// multibyte UTF-8 character.\n    pub fn quote<'a>(&self, mut in_bytes: &'a [u8]) -> Result<Cow<'a, [u8]>, QuoteError> {\n        if in_bytes.is_empty() {\n            // Empty string.  Special case that isn't meaningful as only part of a word.\n            return Ok(b\"''\"[..].into());\n        }\n        if !self.allow_nul && in_bytes.contains(&b'\\0') {\n            return Err(QuoteError::Nul);\n        }\n        let mut out: Vec<u8> = Vec::new();\n        while !in_bytes.is_empty() {\n            // Pick a quoting strategy for some prefix of the input.  Normally this will cover the\n            // entire input, but in some case we might need to divide the input into multiple chunks\n            // that are quoted differently.\n            let (cur_len, strategy) = quoting_strategy(in_bytes);\n            if cur_len == in_bytes.len() && strategy == QuotingStrategy::Unquoted && out.is_empty() {\n                // Entire string can be represented unquoted.  Reuse the allocation.\n                return Ok(in_bytes.into());\n            }\n            let (cur_chunk, rest) = in_bytes.split_at(cur_len);\n            assert!(rest.len() < in_bytes.len()); // no infinite loop\n            in_bytes = rest;\n            append_quoted_chunk(&mut out, cur_chunk, strategy);\n        }\n        Ok(out.into())\n    }\n\n}\n\n#[derive(PartialEq)]\nenum QuotingStrategy {\n    /// No quotes and no backslash escapes.  (If backslash escapes would be necessary, we use a\n    /// different strategy instead.)\n    Unquoted,\n    /// Single quoted.\n    SingleQuoted,\n    /// Double quotes, potentially with backslash escapes.\n    DoubleQuoted,\n    // TODO: add $'xxx' and \"$(printf 'xxx')\" styles\n}\n\n/// Is this ASCII byte okay to emit unquoted?\nconst fn unquoted_ok(c: u8) -> bool {\n    match c as char {\n        // Allowed characters:\n        '+' | '-' | '.' | '/' | ':' | '@' | ']' | '_' |\n        '0'..='9' | 'A'..='Z' | 'a'..='z'\n        => true,\n\n        // Non-allowed characters:\n        // From POSIX https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html\n        // \"The application shall quote the following characters if they are to represent themselves:\"\n        '|' | '&' | ';' | '<' | '>' | '(' | ')' | '$' | '`' | '\\\\' | '\"' | '\\'' | ' ' | '\\t' | '\\n' |\n        // \"and the following may need to be quoted under certain circumstances[..]:\"\n        '*' | '?' | '[' | '#' | '~' | '=' | '%' |\n        // Brace expansion.  These ought to be in the POSIX list but aren't yet;\n        // see: https://www.austingroupbugs.net/view.php?id=1193\n        '{' | '}' |\n        // Also quote comma, just to be safe in the extremely odd case that the user of this crate\n        // is intentionally placing a quoted string inside a brace expansion, e.g.:\n        //     format!(\"echo foo{{a,b,{}}}\" | shlex::quote(some_str))\n        ',' |\n        // '\\r' is allowed in a word by all real shells I tested, but is treated as a word\n        // separator by Python `shlex` | and might be translated to '\\n' in interactive mode.\n        '\\r' |\n        // '!' and '^' are treated specially in interactive mode; see quoting_warning.\n        '!' | '^' |\n        // Nul bytes and control characters.\n        '\\x00' ..= '\\x1f' | '\\x7f'\n        => false,\n        '\\u{80}' ..= '\\u{10ffff}' => {\n            // This is unreachable since `unquoted_ok` is only called for 0..128.\n            // Non-ASCII bytes are handled separately in `quoting_strategy`.\n            // Can't call unreachable!() from `const fn` on old Rust, so...\n            unquoted_ok(c)\n        },\n    }\n    // Note: The logic cited above for quoting comma might suggest that `..` should also be quoted,\n    // it as a special case of brace expansion).  But it's not necessary.  There are three cases:\n    //\n    // 1. The user wants comma-based brace expansion, but the untrusted string being `quote`d\n    //    contains `..`, so they get something like `{foo,bar,3..5}`.\n    //  => That's safe; both Bash and Zsh expand this to `foo bar 3..5` rather than\n    //     `foo bar 3 4 5`.  The presence of commas disables sequence expression expansion.\n    //\n    // 2. The user wants comma-based brace expansion where the contents of the braces are a\n    //    variable number of `quote`d strings and nothing else.  There happens to be exactly\n    //    one string and it contains `..`, so they get something like `{3..5}`.\n    //  => Then this will expand as a sequence expression, which is unintended.  But I don't mind,\n    //     because any such code is already buggy.  Suppose the untrusted string *didn't* contain\n    //     `,` or `..`, resulting in shell input like `{foo}`.  Then the shell would interpret it\n    //     as the literal string `{foo}` rather than brace-expanding it into `foo`.\n    //\n    // 3. The user wants a sequence expression and wants to supply an untrusted string as one of\n    //    the endpoints or the increment.\n    //  => Well, that's just silly, since the endpoints can only be numbers or single letters.\n}\n\n/// Optimized version of `unquoted_ok`.\nfn unquoted_ok_fast(c: u8) -> bool {\n    const UNQUOTED_OK_MASK: u128 = {\n        // Make a mask of all bytes in 0..<0x80 that pass.\n        let mut c = 0u8;\n        let mut mask = 0u128;\n        while c < 0x80 {\n            if unquoted_ok(c) {\n                mask |= 1u128 << c;\n            }\n            c += 1;\n        }\n        mask\n    };\n    ((UNQUOTED_OK_MASK >> c) & 1) != 0\n}\n\n/// Is this ASCII byte okay to emit in single quotes?\nfn single_quoted_ok(c: u8) -> bool {\n    match c {\n        // No single quotes in single quotes.\n        b'\\'' => false,\n        // To work around a Bash bug, ^ is only allowed right after an opening single quote; see\n        // quoting_warning.\n        b'^' => false,\n        // Backslashes in single quotes are literal according to POSIX, but Fish treats them as an\n        // escape character.  Ban them.  Fish doesn't aim to be POSIX-compatible, but we *can*\n        // achieve Fish compatibility using double quotes, so we might as well.\n        b'\\\\' => false,\n        _ => true\n    }\n}\n\n/// Is this ASCII byte okay to emit in double quotes?\nfn double_quoted_ok(c: u8) -> bool {\n    match c {\n        // Work around Python `shlex` bug where parsing \"\\`\" and \"\\$\" doesn't strip the\n        // backslash, even though POSIX requires it.\n        b'`' | b'$' => false,\n        // '!' and '^' are treated specially in interactive mode; see quoting_warning.\n        b'!' | b'^' => false,\n        _ => true\n    }\n}\n\n/// Given an input, return a quoting strategy that can cover some prefix of the string, along with\n/// the size of that prefix.\n///\n/// Precondition: input size is nonzero.  (Empty strings are handled by the caller.)\n/// Postcondition: returned size is nonzero.\n#[cfg_attr(manual_codegen_check, inline(never))]\nfn quoting_strategy(in_bytes: &[u8]) -> (usize, QuotingStrategy) {\n    const UNQUOTED_OK: u8 = 1;\n    const SINGLE_QUOTED_OK: u8 = 2;\n    const DOUBLE_QUOTED_OK: u8 = 4;\n\n    let mut prev_ok = SINGLE_QUOTED_OK | DOUBLE_QUOTED_OK | UNQUOTED_OK;\n    let mut i = 0;\n\n    if in_bytes[0] == b'^' {\n        // To work around a Bash bug, ^ is only allowed right after an opening single quote; see\n        // quoting_warning.\n        prev_ok = SINGLE_QUOTED_OK;\n        i = 1;\n    }\n\n    while i < in_bytes.len() {\n        let c = in_bytes[i];\n        let mut cur_ok = prev_ok;\n\n        if c >= 0x80 {\n            // Normally, non-ASCII characters shouldn't require quoting, but see quoting_warning.md\n            // about \\xa0.  For now, just treat all non-ASCII characters as requiring quotes.  This\n            // also ensures things are safe in the off-chance that you're in a legacy 8-bit locale that\n            // has additional characters satisfying `isblank`.\n            cur_ok &= !UNQUOTED_OK;\n        } else {\n            if !unquoted_ok_fast(c) {\n                cur_ok &= !UNQUOTED_OK;\n            }\n            if !single_quoted_ok(c){\n                cur_ok &= !SINGLE_QUOTED_OK;\n            }\n            if !double_quoted_ok(c) {\n                cur_ok &= !DOUBLE_QUOTED_OK;\n            }\n        }\n\n        if cur_ok == 0 {\n            // There are no quoting strategies that would work for both the previous characters and\n            // this one.  So we have to end the chunk before this character.  The caller will call\n            // `quoting_strategy` again to handle the rest of the string.\n            break;\n        }\n\n        prev_ok = cur_ok;\n        i += 1;\n    }\n\n    // Pick the best allowed strategy.\n    let strategy = if prev_ok & UNQUOTED_OK != 0 {\n        QuotingStrategy::Unquoted\n    } else if prev_ok & SINGLE_QUOTED_OK != 0 {\n        QuotingStrategy::SingleQuoted\n    } else if prev_ok & DOUBLE_QUOTED_OK != 0 {\n        QuotingStrategy::DoubleQuoted\n    } else {\n        unreachable!()\n    };\n    debug_assert!(i > 0);\n    (i, strategy)\n}\n\nfn append_quoted_chunk(out: &mut Vec<u8>, cur_chunk: &[u8], strategy: QuotingStrategy) {\n    match strategy {\n        QuotingStrategy::Unquoted => {\n            out.extend_from_slice(cur_chunk);\n        },\n        QuotingStrategy::SingleQuoted => {\n            out.reserve(cur_chunk.len() + 2);\n            out.push(b'\\'');\n            out.extend_from_slice(cur_chunk);\n            out.push(b'\\'');\n        },\n        QuotingStrategy::DoubleQuoted => {\n            out.reserve(cur_chunk.len() + 2);\n            out.push(b'\"');\n            for &c in cur_chunk.iter() {\n                if let b'$' | b'`' | b'\"' | b'\\\\' = c {\n                    // Add a preceding backslash.\n                    // Note: We shouldn't actually get here for $ and ` because they don't pass\n                    // `double_quoted_ok`.\n                    out.push(b'\\\\');\n                }\n                // Add the character itself.\n                out.push(c);\n            }\n            out.push(b'\"');\n        },\n    }\n}\n\n/// Convenience function that consumes an iterable of words and turns it into a single byte string,\n/// quoting words when necessary. Consecutive words will be separated by a single space.\n///\n/// Uses default settings. The only error that can be returned is [`QuoteError::Nul`].\n///\n/// Equivalent to [`Quoter::new().join(words)`](Quoter).\n///\n/// The string equivalent is [shlex::try_join].\npub fn try_join<'a, I: IntoIterator<Item = &'a [u8]>>(words: I) -> Result<Vec<u8>, QuoteError> {\n    Quoter::new().join(words)\n}\n\n/// Given a single word, return a string suitable to encode it as a shell argument.\n///\n/// Uses default settings. The only error that can be returned is [`QuoteError::Nul`].\n///\n/// Equivalent to [`Quoter::new().quote(in_bytes)`](Quoter).\n///\n/// The string equivalent is [shlex::try_quote].\npub fn try_quote(in_bytes: &[u8]) -> Result<Cow<'_, [u8]>, QuoteError> {\n    Quoter::new().quote(in_bytes)\n}\n\n#[cfg(test)]\nconst INVALID_UTF8: &[u8] = b\"\\xa1\";\n\n#[test]\n#[allow(invalid_from_utf8)]\nfn test_invalid_utf8() {\n    // Check that our test string is actually invalid UTF-8.\n    assert!(core::str::from_utf8(INVALID_UTF8).is_err());\n}\n\n#[cfg(test)]\nstatic SPLIT_TEST_ITEMS: &[(&[u8], Option<&[&[u8]]>)] = &[\n    (b\"foo$baz\", Some(&[b\"foo$baz\"])),\n    (b\"foo baz\", Some(&[b\"foo\", b\"baz\"])),\n    (b\"foo\\\"bar\\\"baz\", Some(&[b\"foobarbaz\"])),\n    (b\"foo \\\"bar\\\"baz\", Some(&[b\"foo\", b\"barbaz\"])),\n    (b\"   foo \\nbar\", Some(&[b\"foo\", b\"bar\"])),\n    (b\"foo\\\\\\nbar\", Some(&[b\"foobar\"])),\n    (b\"\\\"foo\\\\\\nbar\\\"\", Some(&[b\"foobar\"])),\n    (b\"'baz\\\\$b'\", Some(&[b\"baz\\\\$b\"])),\n    (b\"'baz\\\\\\''\", None),\n    (b\"\\\\\", None),\n    (b\"\\\"\\\\\", None),\n    (b\"'\\\\\", None),\n    (b\"\\\"\", None),\n    (b\"'\", None),\n    (b\"foo #bar\\nbaz\", Some(&[b\"foo\", b\"baz\"])),\n    (b\"foo #bar\", Some(&[b\"foo\"])),\n    (b\"foo#bar\", Some(&[b\"foo#bar\"])),\n    (b\"foo\\\"#bar\", None),\n    (b\"'\\\\n'\", Some(&[b\"\\\\n\"])),\n    (b\"'\\\\\\\\n'\", Some(&[b\"\\\\\\\\n\"])),\n    (INVALID_UTF8, Some(&[INVALID_UTF8])),\n];\n\n#[test]\nfn test_split() {\n    for &(input, output) in SPLIT_TEST_ITEMS {\n        assert_eq!(split(input), output.map(|o| o.iter().map(|&x| x.to_owned()).collect()));\n    }\n}\n\n#[test]\nfn test_lineno() {\n    let mut sh = Shlex::new(b\"\\nfoo\\nbar\");\n    while let Some(word) = sh.next() {\n        if word == b\"bar\" {\n            assert_eq!(sh.line_no, 3);\n        }\n    }\n}\n"
    },
    {
      "package": "shlex@2.0.1",
      "sourcePath": "src/lib.rs",
      "sha256": "d707a605a9dbe52b48c53f5d0209ab457d1db535f10acad060883b6c3d8d7a91",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 Nicholas Allegra (comex).\n// Licensed under the Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> or\n// the MIT license <https://opensource.org/licenses/MIT>, at your option. This file may not be\n// copied, modified, or distributed except according to those terms.\n\n//! Parse strings like, and escape strings for, POSIX shells.\n//!\n//! Same idea as (but implementation not directly based on) the Python shlex module.\n//!\n//! Disabling the `std` feature (which is enabled by default) will allow the crate to work in\n//! `no_std` environments, where the `alloc` crate, and a global allocator, are available.\n//!\n//! ## <span style=\"color:red\">Warning</span>\n//!\n//! The [`try_quote`]/[`try_join`] family of APIs does not quote control characters (because they\n//! cannot be quoted portably).\n//!\n//! This is fully safe in noninteractive contexts, like shell scripts and `sh -c` arguments (or\n//! even scripts `source`d from interactive shells).\n//!\n//! But if you are quoting for human consumption, you should keep in mind that ugly inputs produce\n//! ugly outputs (which may not be copy-pastable).\n//!\n//! And if by chance you are piping the output of [`try_quote`]/[`try_join`] directly to the stdin\n//! of an interactive shell, you should stop, because control characters can lead to arbitrary\n//! command injection.\n//!\n//! For more information, and for information about more minor issues, please see [quoting_warning].\n//!\n//! ## Compatibility\n//!\n//! This crate's quoting functionality tries to be compatible with **any POSIX-compatible shell**;\n//! it's tested against `bash`, `zsh`, `dash`, Busybox `ash`, and `mksh`, plus `fish` (which is not\n//! POSIX-compatible but close enough).\n//!\n//! It also aims to be compatible with Python `shlex` and C `wordexp`.\n\n#![cfg_attr(not(feature = \"std\"), no_std)]\n\nextern crate alloc;\nuse alloc::vec::Vec;\nuse alloc::borrow::Cow;\nuse alloc::string::String;\n#[cfg(test)]\nuse alloc::vec;\n#[cfg(test)]\nuse alloc::borrow::ToOwned;\n\npub mod bytes;\n#[cfg(all(doc, not(doctest)))]\n#[path = \"quoting_warning.md\"]\npub mod quoting_warning;\n\n/// An iterator that takes an input string and splits it into the words using the same syntax as\n/// the POSIX shell.\n///\n/// See [`bytes::Shlex`].\npub struct Shlex<'a>(bytes::Shlex<'a>);\n\nimpl<'a> Shlex<'a> {\n    pub fn new(in_str: &'a str) -> Self {\n        Self(bytes::Shlex::new(in_str.as_bytes()))\n    }\n\n    /// # Safety\n    ///\n    /// The parameter must have been constructed from valid UTF-8.\n    pub unsafe fn from_bytes(bytes: bytes::Shlex<'a>) -> Self {\n        Self(bytes)\n    }\n\n    /// # Safety\n    ///\n    /// If the returned reference is reassigned, the new [`bytes::Shlex`] must have been constructed from valid UTF-8.\n    pub unsafe fn as_bytes_mut(&mut self) -> &mut bytes::Shlex<'a> {\n        &mut self.0\n    }\n}\n\nimpl Iterator for Shlex<'_> {\n    type Item = String;\n    fn next(&mut self) -> Option<String> {\n        self.0.next().map(|byte_word| {\n            // Safety: given valid UTF-8, bytes::Shlex will always return valid UTF-8.\n            unsafe { String::from_utf8_unchecked(byte_word) }\n        })\n    }\n}\n\nimpl<'a> core::ops::Deref for Shlex<'a> {\n    type Target = bytes::Shlex<'a>;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\n/// Convenience function that consumes the whole string at once.  Returns None if the input was\n/// erroneous.\npub fn split(in_str: &str) -> Option<Vec<String>> {\n    let mut shl = Shlex::new(in_str);\n    let res = shl.by_ref().collect();\n    if shl.had_error { None } else { Some(res) }\n}\n\n/// Errors from [`Quoter::quote`], [`Quoter::join`], etc. (and their [`bytes`] counterparts).\n///\n/// By default, the only error that can be returned is [`QuoteError::Nul`].  If you call\n/// `allow_nul(true)`, then no errors can be returned at all.  Any error variants added in the\n/// future will not be enabled by default; they will be enabled through corresponding non-default\n/// [`Quoter`] options.\n///\n/// ...In theory.  In the unlikely event that additional classes of inputs are discovered that,\n/// like nul bytes, are fundamentally unsafe to quote even for non-interactive shells, the risk\n/// will be mitigated by adding corresponding [`QuoteError`] variants that *are* enabled by\n/// default.\n#[non_exhaustive]\n#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub enum QuoteError {\n    /// The input contained a nul byte.  In most cases, shells fundamentally [cannot handle strings\n    /// containing nul bytes](quoting_warning#nul-bytes), no matter how they are quoted.  But if\n    /// you're sure you can handle nul bytes, you can call `allow_nul(true)` on the `Quoter` to let\n    /// them pass through.\n    Nul,\n}\n\nimpl core::fmt::Display for QuoteError {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        match self {\n            QuoteError::Nul => f.write_str(\"cannot shell-quote string containing nul byte\"),\n        }\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl std::error::Error for QuoteError {}\n\n/// A more configurable interface to quote strings.  If you only want the default settings you can\n/// use the convenience functions [`try_quote`] and [`try_join`].\n///\n/// The bytes equivalent is [`bytes::Quoter`].\n#[derive(Default, Debug, Clone)]\npub struct Quoter {\n    inner: bytes::Quoter,\n}\n\nimpl Quoter {\n    /// Create a new [`Quoter`] with default settings.\n    #[inline]\n    pub fn new() -> Self {\n        Self::default()\n    }\n\n    /// Set whether to allow [nul bytes](quoting_warning#nul-bytes).  By default they are not\n    /// allowed and will result in an error of [`QuoteError::Nul`].\n    #[inline]\n    pub fn allow_nul(mut self, allow: bool) -> Self {\n        self.inner = self.inner.allow_nul(allow);\n        self\n    }\n\n    /// Convenience function that consumes an iterable of words and turns it into a single string,\n    /// quoting words when necessary. Consecutive words will be separated by a single space.\n    pub fn join<'a, I: IntoIterator<Item = &'a str>>(&self, words: I) -> Result<String, QuoteError> {\n        // Safety: given valid UTF-8, bytes::join() will always return valid UTF-8.\n        self.inner.join(words.into_iter().map(|s| s.as_bytes()))\n            .map(|bytes| unsafe { String::from_utf8_unchecked(bytes) })\n    }\n\n    /// Given a single word, return a string suitable to encode it as a shell argument.\n    pub fn quote<'a>(&self, in_str: &'a str) -> Result<Cow<'a, str>, QuoteError> {\n        Ok(match self.inner.quote(in_str.as_bytes())? {\n            Cow::Borrowed(out) => {\n                // Safety: given valid UTF-8, bytes::quote() will always return valid UTF-8.\n                unsafe { core::str::from_utf8_unchecked(out) }.into()\n            }\n            Cow::Owned(out) => {\n                // Safety: given valid UTF-8, bytes::quote() will always return valid UTF-8.\n                unsafe { String::from_utf8_unchecked(out) }.into()\n            }\n        })\n    }\n}\n\nimpl From<bytes::Quoter> for Quoter {\n    fn from(inner: bytes::Quoter) -> Quoter {\n        Quoter { inner }\n    }\n}\n\nimpl From<Quoter> for bytes::Quoter {\n    fn from(quoter: Quoter) -> bytes::Quoter {\n        quoter.inner\n    }\n}\n\n/// Convenience function that consumes an iterable of words and turns it into a single string,\n/// quoting words when necessary. Consecutive words will be separated by a single space.\n///\n/// Uses default settings. The only error that can be returned is [`QuoteError::Nul`].\n///\n/// Equivalent to [`Quoter::new().join(words)`](Quoter).\n///\n/// The bytes equivalent is [bytes::try_join].\npub fn try_join<'a, I: IntoIterator<Item = &'a str>>(words: I) -> Result<String, QuoteError> {\n    Quoter::new().join(words)\n}\n\n/// Given a single word, return a string suitable to encode it as a shell argument.\n///\n/// Uses default settings. The only error that can be returned is [`QuoteError::Nul`].\n///\n/// Equivalent to [`Quoter::new().quote(in_str)`](Quoter).\n///\n/// The bytes equivalent is [bytes::try_quote].\npub fn try_quote(in_str: &str) -> Result<Cow<'_, str>, QuoteError> {\n    Quoter::new().quote(in_str)\n}\n\n#[cfg(test)]\nstatic SPLIT_TEST_ITEMS: &[(&str, Option<&[&str]>)] = &[\n    (\"foo$baz\", Some(&[\"foo$baz\"])),\n    (\"foo baz\", Some(&[\"foo\", \"baz\"])),\n    (\"foo\\\"bar\\\"baz\", Some(&[\"foobarbaz\"])),\n    (\"foo \\\"bar\\\"baz\", Some(&[\"foo\", \"barbaz\"])),\n    (\"   foo \\nbar\", Some(&[\"foo\", \"bar\"])),\n    (\"foo\\\\\\nbar\", Some(&[\"foobar\"])),\n    (\"\\\"foo\\\\\\nbar\\\"\", Some(&[\"foobar\"])),\n    (\"'baz\\\\$b'\", Some(&[\"baz\\\\$b\"])),\n    (\"'baz\\\\\\''\", None),\n    (\"\\\\\", None),\n    (\"\\\"\\\\\", None),\n    (\"'\\\\\", None),\n    (\"\\\"\", None),\n    (\"'\", None),\n    (\"foo #bar\\nbaz\", Some(&[\"foo\", \"baz\"])),\n    (\"foo #bar\", Some(&[\"foo\"])),\n    (\"foo#bar\", Some(&[\"foo#bar\"])),\n    (\"foo\\\"#bar\", None),\n    (\"'\\\\n'\", Some(&[\"\\\\n\"])),\n    (\"'\\\\\\\\n'\", Some(&[\"\\\\\\\\n\"])),\n];\n\n#[test]\nfn test_split() {\n    for &(input, output) in SPLIT_TEST_ITEMS {\n        assert_eq!(split(input), output.map(|o| o.iter().map(|&x| x.to_owned()).collect()));\n    }\n}\n\n#[test]\nfn test_lineno() {\n    let mut sh = Shlex::new(\"\\nfoo\\nbar\");\n    while let Some(word) = sh.next() {\n        if word == \"bar\" {\n            assert_eq!(sh.line_no, 3);\n        }\n    }\n}\n\n#[test]\n#[cfg_attr(not(feature = \"std\"), allow(unreachable_code, unused_mut))]\nfn test_quote() {\n    // This is a list of (unquoted, quoted) pairs.\n    // But it's using a single long (raw) string literal with an ad-hoc format, just because it's\n    // hard to read if we have to put the test strings through Rust escaping on top of the escaping\n    // being tested.  (Even raw string literals are noisy for short strings).\n    // Ad-hoc: \"NL\" is replaced with a literal newline; no other escape sequences.\n    let tests = r#\"\n        <>                => <''>\n        <foobar>          => <foobar>\n        <foo bar>         => <'foo bar'>\n        <\"foo bar'\">      => <\"\\\"foo bar'\\\"\">\n        <'foo bar'>       => <\"'foo bar'\">\n        <\">               => <'\"'>\n        <\"'>              => <\"\\\"'\">\n        <hello!world>     => <'hello!world'>\n        <'hello!world>    => <\"'hello\"'!world'>\n        <'hello!>         => <\"'hello\"'!'>\n        <hello ^ world>   => <'hello ''^ world'>\n        <hello^>          => <hello'^'>\n        <!world'>         => <'!world'\"'\">\n        <{a, b}>          => <'{a, b}'>\n        <NL>              => <'NL'>\n        <^>               => <'^'>\n        <foo^bar>         => <foo'^bar'>\n        <NLx^>            => <'NLx''^'>\n        <NL^x>            => <'NL''^x'>\n        <NL ^x>           => <'NL ''^x'>\n        <{a,b}>           => <'{a,b}'>\n        <a,b>             => <'a,b'>\n        <a..b             => <a..b>\n        <'$>              => <\"'\"'$'>\n        <\"^>              => <'\"''^'>\n    \"#;\n    let mut ok = true;\n    for test in tests.trim().split('\\n') {\n        let parts: Vec<String> = test\n            .replace(\"NL\", \"\\n\")\n            .split(\"=>\")\n            .map(|part| part.trim().trim_start_matches('<').trim_end_matches('>').to_owned())\n            .collect();\n        assert!(parts.len() == 2);\n        let unquoted = &*parts[0];\n        let quoted_expected = &*parts[1];\n        let quoted_actual = try_quote(&parts[0]).unwrap();\n        if quoted_expected != quoted_actual {\n            #[cfg(not(feature = \"std\"))]\n            panic!(\"FAIL: for input <{}>, expected <{}>, got <{}>\",\n                     unquoted, quoted_expected, quoted_actual);\n            #[cfg(feature = \"std\")]\n            println!(\"FAIL: for input <{}>, expected <{}>, got <{}>\",\n                     unquoted, quoted_expected, quoted_actual);\n            ok = false;\n        }\n    }\n    assert!(ok);\n}\n\n#[test]\nfn test_fallible() {\n    assert_eq!(try_join(vec![\"\\0\"]), Err(QuoteError::Nul));\n    assert_eq!(try_quote(\"\\0\"), Err(QuoteError::Nul));\n}\n"
    },
    {
      "package": "simd-adler32@0.3.10",
      "sourcePath": "LICENSE.md",
      "sha256": "42a35170233e83e18856792e748de4c1ce4a63b2afce9a370c89ef3fe23f9f2d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "MIT License\n\nCopyright (c) [2021] [Marvin Countryman]\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "README.md",
      "sha256": "a6e895d2e8e499be9240a1fdcd9b9addf712dfe0026e320aa51529643088abd4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "<div align=\"center\">\n\n# SimpleCSS\n\n**A simple [CSS 2.1](https://www.w3.org/TR/CSS21/) parser and selector.**\n\n[![Linebender Zulip, #resvg channel](https://img.shields.io/badge/Linebender-%23resvg-blue?logo=Zulip)](https://xi.zulipchat.com/#narrow/channel/465085-resvg)\n[![dependency status](https://deps.rs/repo/github/linebender/simplecss/status.svg)](https://deps.rs/repo/github/linebender/simplecss)\n[![Apache 2.0 or MIT license.](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue.svg)](#license)\n[![Build status](https://github.com/linebender/simplecss/workflows/CI/badge.svg)](https://github.com/linebender/simplecss/actions)\n[![Crates.io](https://img.shields.io/crates/v/simplecss.svg)](https://crates.io/crates/simplecss)\n[![Docs](https://docs.rs/simplecss/badge.svg)](https://docs.rs/simplecss)\n![](https://img.shields.io/badge/unsafe-forbidden-brightgreen.svg)\n\n</div>\n\nThis is not a browser-grade CSS parser.\nIf you need one, use [cssparser](https://crates.io/crates/cssparser) + [selectors](https://crates.io/crates/selectors).\n\nSince it's very simple we will start with limitations:\n\n## Limitations\n\n- [At-rules](https://www.w3.org/TR/CSS21/syndata.html#at-rules) are not supported.\n  They will be skipped during parsing.\n- Property values are not parsed.\n  In CSS like `* { width: 5px }` you will get a `width` property with a `5px` value as a string.\n- CDO/CDC comments are not supported.\n- Parser is case sensitive.\n  All keywords must be lowercase.\n- Unicode escape, like `\\26`, is not supported.\n\n## Features\n\n- Selector matching support.\n- The rules are sorted by specificity.\n- `!important` parsing support.\n- Has a high-level parsers and low-level, zero-allocation tokenizers.\n- No unsafe.\n\n## Minimum supported Rust Version (MSRV)\n\nThis version of SimpleCSS has been verified to compile with **Rust 1.65** and later.\n\nFuture versions of SimpleCSS might increase the Rust version requirement.\nIt will not be treated as a breaking change and as such can even happen with small patch releases.\n\n<details>\n<summary>Click here if compiling fails.</summary>\n\nAs time has passed, some of SimpleCSS's dependencies could have released versions with a higher Rust requirement.\nIf you encounter a compilation issue due to a dependency and don't want to upgrade your Rust toolchain, then you could downgrade the dependency.\n\n```sh\n# Use the problematic dependency's name and version\ncargo update -p package_name --precise 0.1.1\n```\n</details>\n\n## Community\n\n[![Linebender Zulip, #resvg channel](https://img.shields.io/badge/Linebender-%23resvg-blue?logo=Zulip)](https://xi.zulipchat.com/#narrow/channel/465085-resvg)\n\nDiscussion of SimpleCSS development happens in the Linebender Zulip at <https://xi.zulipchat.com/>, specifically the [#resvg channel](https://xi.zulipchat.com/#narrow/channel/465085-resvg).\nAll public content can be read without logging in.\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)\n\nat your option.\n\n## Contribution\n\nContributions are welcome by pull request. The [Rust code of conduct] applies.\nPlease feel free to add your name to the [AUTHORS] file in any substantive pull request.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.\n\n[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct\n[AUTHORS]: ./AUTHORS\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "examples/parse.rs",
      "sha256": "6439b8d0257865d1351645856c54586a6e44ba119eb28ab37e6be3c2c23f0de5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Parse\n\nuse std::io::{Read, Write};\n\nfn main() {\n    let args: Vec<_> = std::env::args().collect();\n    if args.len() != 2 {\n        println!(\"Usage:\\n\\tparse style.css\\n\\tparse - 'p {{ color:red }}'\");\n        std::process::exit(1);\n    }\n\n    std::env::set_var(\"RUST_LOG\", \"simplecss=warn\");\n    env_logger::builder()\n        .format(|buf, record| writeln!(buf, \"{}: {}\", record.level(), record.args()))\n        .init();\n\n    let text = if args[1] == \"-\" {\n        let mut buffer = String::new();\n        let stdin = std::io::stdin();\n        let mut handle = stdin.lock();\n        handle.read_to_string(&mut buffer).unwrap();\n        buffer\n    } else {\n        std::fs::read_to_string(&args[1]).unwrap()\n    };\n\n    let style = simplecss::StyleSheet::parse(&text);\n    println!(\"{:#?}\", style);\n}\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "examples/select.rs",
      "sha256": "4a18448eeac79fd59540f1f86af514524a0fb474f87c755508efa7319f0f05e5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Select\n\nstruct XmlNode<'a, 'input: 'a>(roxmltree::Node<'a, 'input>);\n\nimpl<'a, 'input: 'a> XmlNode<'a, 'input> {\n    fn select(&self, text: &str) -> Option<roxmltree::Node<'a, 'input>> {\n        let selectors = simplecss::Selector::parse(text)?;\n        self.0\n            .descendants()\n            .filter(|n| n.is_element())\n            .find(|&node| selectors.matches(&XmlNode(node)))\n    }\n}\n\nimpl simplecss::Element for XmlNode<'_, '_> {\n    fn parent_element(&self) -> Option<Self> {\n        self.0.parent_element().map(XmlNode)\n    }\n\n    fn prev_sibling_element(&self) -> Option<Self> {\n        self.0\n            .prev_siblings()\n            .filter(|n| n.is_element())\n            .nth(0)\n            .map(XmlNode)\n    }\n\n    fn has_local_name(&self, local_name: &str) -> bool {\n        self.0.tag_name().name() == local_name\n    }\n\n    fn attribute_matches(\n        &self,\n        local_name: &str,\n        operator: simplecss::AttributeOperator<'_>,\n    ) -> bool {\n        match self.0.attribute(local_name) {\n            Some(value) => operator.matches(value),\n            None => false,\n        }\n    }\n\n    fn pseudo_class_matches(&self, class: simplecss::PseudoClass<'_>) -> bool {\n        match class {\n            simplecss::PseudoClass::FirstChild => self.prev_sibling_element().is_none(),\n            _ => false, // Since we are querying a static XML we can ignore other pseudo-classes.\n        }\n    }\n}\n\nfn main() {\n    let doc = roxmltree::Document::parse(\n        \"<svg>\n            <g>\n                <rect id='rect1' class='round blue'/>\n                <rect id='rect2' color='red'/>\n            </g>\n        </svg>\",\n    )\n    .unwrap();\n    let root = XmlNode(doc.root_element());\n\n    assert_eq!(\n        root.select(\"rect:first-child\")\n            .unwrap()\n            .attribute(\"id\")\n            .unwrap(),\n        \"rect1\",\n        \"selected wrong element\"\n    );\n\n    assert_eq!(\n        root.select(\"[color=red]\").unwrap().attribute(\"id\").unwrap(),\n        \"rect2\",\n        \"selected wrong element\"\n    );\n\n    assert_eq!(\n        root.select(\"svg rect\").unwrap().attribute(\"id\").unwrap(),\n        \"rect1\",\n        \"selected wrong element\"\n    );\n\n    assert_eq!(\n        root.select(\"svg > g > rect\")\n            .unwrap()\n            .attribute(\"id\")\n            .unwrap(),\n        \"rect1\",\n        \"selected wrong element\"\n    );\n\n    assert_eq!(\n        root.select(\".blue\").unwrap().attribute(\"id\").unwrap(),\n        \"rect1\",\n        \"selected wrong element\"\n    );\n}\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "src/lib.rs",
      "sha256": "36389e726cf7c266026a22202ce79d1b3131f22a65443b1a070999694bdb0852",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2016 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n/*!\nA simple [CSS 2.1](https://www.w3.org/TR/CSS21/) parser and selector.\n\nThis is not a browser-grade CSS parser. If you need one,\nuse [cssparser](https://crates.io/crates/cssparser) +\n[selectors](https://crates.io/crates/selectors).\n\nSince it's very simple we will start with limitations:\n\n## Limitations\n\n- [At-rules](https://www.w3.org/TR/CSS21/syndata.html#at-rules) are not supported.\n  They will be skipped during parsing.\n- Property values are not parsed.\n  In CSS like `* { width: 5px }` you will get a `width` property with a `5px` value as a string.\n- CDO/CDC comments are not supported.\n- Parser is case sensitive. All keywords must be lowercase.\n- Unicode escape, like `\\26`, is not supported.\n\n## Features\n\n- Selector matching support.\n- The rules are sorted by specificity.\n- `!important` parsing support.\n- Has a high-level parsers and low-level, zero-allocation tokenizers.\n- No unsafe.\n*/\n\n// LINEBENDER LINT SET - lib.rs - v2\n// See https://linebender.org/wiki/canonical-lints/\n// These lints aren't included in Cargo.toml because they\n// shouldn't apply to examples and tests\n#![warn(unused_crate_dependencies)]\n#![warn(clippy::print_stdout, clippy::print_stderr)]\n// Targeting e.g. 32-bit means structs containing usize can give false positives for 64-bit.\n#![cfg_attr(target_pointer_width = \"64\", warn(clippy::trivially_copy_pass_by_ref))]\n// END LINEBENDER LINT SET\n#![cfg_attr(docsrs, feature(doc_auto_cfg))]\n#![cfg_attr(all(not(feature = \"std\"), not(test)), no_std)]\n// The following lints are part of the Linebender standard set,\n// but resolving them has been deferred for now.\n// Feel free to send a PR that solves one or more of these.\n#![allow(\n    missing_debug_implementations,\n    unreachable_pub,\n    clippy::use_self,\n    clippy::missing_assert_message,\n    clippy::missing_panics_doc,\n    clippy::exhaustive_enums,\n    clippy::unseparated_literal_suffix\n)]\n#![cfg_attr(test, allow(unused_crate_dependencies))] // Some dev dependencies are only used in tests\n\nextern crate alloc;\n\nuse alloc::vec::Vec;\nuse core::fmt;\n\nuse log::warn;\n\nmod selector;\nmod stream;\n\npub use selector::*;\nuse stream::Stream;\n\n/// A list of possible errors.\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum Error {\n    /// The steam ended earlier than we expected.\n    ///\n    /// Should only appear on invalid input data.\n    UnexpectedEndOfStream,\n\n    /// An invalid ident.\n    InvalidIdent(TextPos),\n\n    /// An unclosed comment.\n    InvalidComment(TextPos),\n\n    /// An invalid declaration value.\n    InvalidValue(TextPos),\n\n    /// An invalid byte.\n    #[allow(missing_docs)]\n    InvalidByte {\n        expected: u8,\n        actual: u8,\n        pos: TextPos,\n    },\n\n    /// A missing selector.\n    SelectorMissing,\n\n    /// An unexpected selector.\n    UnexpectedSelector,\n\n    /// An unexpected combinator.\n    UnexpectedCombinator,\n\n    /// An invalid or unsupported attribute selector.\n    InvalidAttributeSelector,\n\n    /// An invalid language pseudo-class.\n    InvalidLanguagePseudoClass,\n}\n\nimpl fmt::Display for Error {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match *self {\n            Error::UnexpectedEndOfStream => {\n                write!(f, \"unexpected end of stream\")\n            }\n            Error::InvalidIdent(pos) => {\n                write!(f, \"invalid ident at {}\", pos)\n            }\n            Error::InvalidComment(pos) => {\n                write!(f, \"invalid comment at {}\", pos)\n            }\n            Error::InvalidValue(pos) => {\n                write!(f, \"invalid value at {}\", pos)\n            }\n            Error::InvalidByte {\n                expected,\n                actual,\n                pos,\n            } => {\n                write!(\n                    f,\n                    \"expected '{}' not '{}' at {}\",\n                    expected as char, actual as char, pos\n                )\n            }\n            Error::SelectorMissing => {\n                write!(f, \"selector missing\")\n            }\n            Error::UnexpectedSelector => {\n                write!(f, \"unexpected selector\")\n            }\n            Error::UnexpectedCombinator => {\n                write!(f, \"unexpected combinator\")\n            }\n            Error::InvalidAttributeSelector => {\n                write!(f, \"invalid or unsupported attribute selector\")\n            }\n            Error::InvalidLanguagePseudoClass => {\n                write!(f, \"invalid language pseudo-class\")\n            }\n        }\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl std::error::Error for Error {}\n\n/// A position in text.\n///\n/// Position indicates a row/line and a column in the original text. Starting from 1:1.\n#[derive(Clone, Copy, PartialEq, Debug)]\n#[allow(missing_docs)]\npub struct TextPos {\n    pub row: u32,\n    pub col: u32,\n}\n\nimpl TextPos {\n    /// Constructs a new `TextPos`.\n    ///\n    /// Should not be invoked manually, but rather via `Stream::gen_text_pos`.\n    pub fn new(row: u32, col: u32) -> TextPos {\n        TextPos { row, col }\n    }\n}\n\nimpl fmt::Display for TextPos {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"{}:{}\", self.row, self.col)\n    }\n}\n\n/// A declaration.\n#[derive(Clone, Copy, PartialEq, Debug)]\n#[allow(missing_docs)]\npub struct Declaration<'a> {\n    pub name: &'a str,\n    pub value: &'a str,\n    pub important: bool,\n}\n\n/// A rule.\n#[derive(Clone, Debug)]\npub struct Rule<'a> {\n    /// A rule selector.\n    pub selector: Selector<'a>,\n    /// A rule declarations.\n    pub declarations: Vec<Declaration<'a>>,\n}\n\n/// A style sheet.\n#[derive(Clone, Debug)]\npub struct StyleSheet<'a> {\n    /// A list of rules.\n    pub rules: Vec<Rule<'a>>,\n}\n\nimpl<'a> StyleSheet<'a> {\n    /// Creates an empty style sheet.\n    pub fn new() -> Self {\n        StyleSheet { rules: Vec::new() }\n    }\n\n    /// Parses a style sheet from text.\n    ///\n    /// At-rules are not supported and will be skipped.\n    ///\n    /// # Errors\n    ///\n    /// Doesn't produce any errors. In worst case scenario will return an empty stylesheet.\n    ///\n    /// All warnings will be logged.\n    pub fn parse(text: &'a str) -> Self {\n        let mut sheet = StyleSheet::new();\n        sheet.parse_more(text);\n        sheet\n    }\n\n    /// Parses a style sheet from a text to the current style sheet.\n    pub fn parse_more(&mut self, text: &'a str) {\n        let mut s = Stream::from(text);\n\n        if s.skip_spaces_and_comments().is_err() {\n            return;\n        }\n\n        while !s.at_end() {\n            if s.skip_spaces_and_comments().is_err() {\n                break;\n            }\n\n            let _ = consume_statement(&mut s, &mut self.rules);\n        }\n\n        if !s.at_end() {\n            warn!(\"{} bytes were left.\", s.slice_tail().len());\n        }\n\n        // Remove empty rules.\n        self.rules.retain(|rule| !rule.declarations.is_empty());\n\n        // Sort the rules by specificity.\n        self.rules\n            .sort_by_cached_key(|rule| rule.selector.specificity());\n    }\n}\n\nimpl fmt::Display for StyleSheet<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        for (i, rule) in self.rules.iter().enumerate() {\n            write!(f, \"{} {{ \", rule.selector)?;\n            for dec in &rule.declarations {\n                write!(f, \"{}:{}\", dec.name, dec.value)?;\n                if dec.important {\n                    write!(f, \" !important\")?;\n                }\n                write!(f, \";\")?;\n            }\n            write!(f, \" }}\")?;\n\n            if i != self.rules.len() - 1 {\n                writeln!(f)?;\n            }\n        }\n\n        Ok(())\n    }\n}\n\nimpl Default for StyleSheet<'_> {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nfn consume_statement<'a>(s: &mut Stream<'a>, rules: &mut Vec<Rule<'a>>) -> Result<(), Error> {\n    if s.curr_byte() == Ok(b'@') {\n        s.advance(1);\n        consume_at_rule(s)\n    } else {\n        consume_rule_set(s, rules)\n    }\n}\n\nfn consume_at_rule(s: &mut Stream<'_>) -> Result<(), Error> {\n    let ident = s.consume_ident()?;\n    warn!(\"The @{} rule is not supported. Skipped.\", ident);\n\n    s.skip_bytes(|c| c != b';' && c != b'{');\n\n    match s.curr_byte()? {\n        b';' => s.advance(1),\n        b'{' => consume_block(s),\n        _ => {}\n    }\n\n    Ok(())\n}\n\nfn consume_rule_set<'a>(s: &mut Stream<'a>, rules: &mut Vec<Rule<'a>>) -> Result<(), Error> {\n    let start_rule_idx = rules.len();\n\n    while s.curr_byte()? == b',' || start_rule_idx == rules.len() {\n        if s.curr_byte()? == b',' {\n            s.advance(1);\n        }\n\n        let (selector, offset) = parse(s.slice_tail());\n        s.advance(offset);\n        s.skip_spaces();\n\n        if let Some(selector) = selector {\n            rules.push(Rule {\n                selector,\n                declarations: Vec::new(),\n            });\n        }\n\n        match s.curr_byte()? {\n            b'{' => break,\n            b',' => {}\n            _ => {\n                s.skip_bytes(|c| c != b'{');\n                break;\n            }\n        }\n    }\n\n    s.try_consume_byte(b'{');\n\n    let declarations = consume_declarations(s)?;\n    for rule in rules.iter_mut().skip(start_rule_idx) {\n        rule.declarations = declarations.clone();\n    }\n\n    s.try_consume_byte(b'}');\n\n    Ok(())\n}\n\nfn consume_block(s: &mut Stream<'_>) {\n    s.try_consume_byte(b'{');\n    consume_until_block_end(s);\n}\n\nfn consume_until_block_end(s: &mut Stream<'_>) {\n    // Block can have nested blocks, so we have to check for matching braces.\n    // We simply counting the number of opening braces, which is incorrect,\n    // since `{` can be inside a string, but it's fine for majority of the cases.\n\n    let mut braces = 0;\n    while !s.at_end() {\n        match s.curr_byte_unchecked() {\n            b'{' => {\n                braces += 1;\n            }\n            b'}' => {\n                if braces == 0 {\n                    break;\n                } else {\n                    braces -= 1;\n                }\n            }\n            _ => {}\n        }\n\n        s.advance(1);\n    }\n\n    s.try_consume_byte(b'}');\n}\n\nfn consume_declarations<'a>(s: &mut Stream<'a>) -> Result<Vec<Declaration<'a>>, Error> {\n    let mut declarations = Vec::new();\n\n    while !s.at_end() && s.curr_byte() != Ok(b'}') {\n        match consume_declaration(s) {\n            Ok(declaration) => declarations.push(declaration),\n            Err(_) => {\n                consume_until_block_end(s);\n                break;\n            }\n        }\n    }\n\n    Ok(declarations)\n}\n\n/// A declaration tokenizer.\n///\n/// Tokenizer will stop at the first invalid token.\n///\n/// # Example\n///\n/// ```\n/// use simplecss::{DeclarationTokenizer, Declaration};\n///\n/// let mut t = DeclarationTokenizer::from(\"background: url(\\\"img.png\\\"); color:red !important\");\n/// assert_eq!(t.next().unwrap(), Declaration { name: \"background\", value: \"url(\\\"img.png\\\")\", important: false });\n/// assert_eq!(t.next().unwrap(), Declaration { name: \"color\", value: \"red\", important: true });\n/// ```\npub struct DeclarationTokenizer<'a> {\n    stream: Stream<'a>,\n}\n\nimpl<'a> From<&'a str> for DeclarationTokenizer<'a> {\n    fn from(text: &'a str) -> Self {\n        DeclarationTokenizer {\n            stream: Stream::from(text),\n        }\n    }\n}\n\nimpl<'a> Iterator for DeclarationTokenizer<'a> {\n    type Item = Declaration<'a>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let _ = self.stream.skip_spaces_and_comments();\n\n        if self.stream.at_end() {\n            return None;\n        }\n\n        match consume_declaration(&mut self.stream) {\n            Ok(v) => Some(v),\n            Err(_) => {\n                self.stream.jump_to_end();\n                None\n            }\n        }\n    }\n}\n\nfn consume_declaration<'a>(s: &mut Stream<'a>) -> Result<Declaration<'a>, Error> {\n    s.skip_spaces_and_comments()?;\n\n    // Parse name.\n\n    // https://snook.ca/archives/html_and_css/targetting_ie7\n    if s.curr_byte() == Ok(b'*') {\n        s.advance(1);\n    }\n\n    let name = s.consume_ident()?;\n\n    s.skip_spaces_and_comments()?;\n    s.consume_byte(b':')?;\n    s.skip_spaces_and_comments()?;\n\n    // Parse value.\n    let start = s.pos();\n    let mut end = s.pos();\n    while consume_term(s).is_ok() {\n        end = s.pos();\n        s.skip_spaces_and_comments()?;\n    }\n    let value = s.slice_range(start, end).trim();\n\n    s.skip_spaces_and_comments()?;\n\n    // Check for `important`.\n    let mut important = false;\n    if s.curr_byte() == Ok(b'!') {\n        s.advance(1);\n        s.skip_spaces_and_comments()?;\n        if s.slice_tail().starts_with(\"important\") {\n            s.advance(9);\n            important = true;\n        }\n    }\n\n    s.skip_spaces_and_comments()?;\n\n    while s.curr_byte() == Ok(b';') {\n        s.advance(1);\n        s.skip_spaces_and_comments()?;\n    }\n\n    s.skip_spaces_and_comments()?;\n\n    if value.is_empty() {\n        return Err(Error::InvalidValue(s.gen_text_pos_from(start)));\n    }\n\n    Ok(Declaration {\n        name,\n        value,\n        important,\n    })\n}\n\nfn consume_term(s: &mut Stream<'_>) -> Result<(), Error> {\n    fn consume_digits(s: &mut Stream<'_>) {\n        while let Ok(b'0'..=b'9') = s.curr_byte() {\n            s.advance(1);\n        }\n    }\n\n    match s.curr_byte()? {\n        b'#' => {\n            s.advance(1);\n            match s.consume_ident() {\n                Ok(_) => {}\n                Err(_) => {\n                    // Try consume as a hex color.\n                    while let Ok(c) = s.curr_byte() {\n                        match c {\n                            b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F' => s.advance(1),\n                            _ => break,\n                        }\n                    }\n                }\n            }\n        }\n        b'+' | b'-' | b'0'..=b'9' | b'.' => {\n            // Consume number.\n\n            s.advance(1);\n            consume_digits(s);\n            if s.curr_byte() == Ok(b'.') {\n                s.advance(1);\n                consume_digits(s);\n            }\n\n            if s.curr_byte() == Ok(b'%') {\n                s.advance(1);\n            } else {\n                // Consume suffix if any.\n                let _ = s.consume_ident();\n            }\n        }\n        b'\\'' | b'\"' => {\n            s.consume_string()?;\n        }\n        b',' => {\n            s.advance(1);\n        }\n        _ => {\n            let _ = s.consume_ident()?;\n\n            // Consume function.\n            if s.curr_byte() == Ok(b'(') {\n                s.skip_bytes(|c| c != b')');\n                s.consume_byte(b')')?;\n            }\n        }\n    }\n\n    Ok(())\n}\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "src/selector.rs",
      "sha256": "f1283a29b37232ee9fb8f9715da9d564d96c309e59e770e5fdddff6f9cae006e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse alloc::{vec, vec::Vec};\nuse core::fmt;\n\nuse log::warn;\n\nuse crate::stream::Stream;\nuse crate::Error;\n\n/// An attribute selector operator.\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum AttributeOperator<'a> {\n    /// `[attr]`\n    Exists,\n    /// `[attr=value]`\n    Matches(&'a str),\n    /// `[attr~=value]`\n    Contains(&'a str),\n    /// `[attr|=value]`\n    StartsWith(&'a str),\n}\n\nimpl AttributeOperator<'_> {\n    /// Checks that value is matching the operator.\n    pub fn matches(&self, value: &str) -> bool {\n        match *self {\n            AttributeOperator::Exists => true,\n            AttributeOperator::Matches(v) => value == v,\n            AttributeOperator::Contains(v) => value.split(' ').any(|s| s == v),\n            AttributeOperator::StartsWith(v) => {\n                // exactly `v` or beginning with `v` immediately followed by `-`\n                if value == v {\n                    true\n                } else if value.starts_with(v) {\n                    value.get(v.len()..v.len() + 1) == Some(\"-\")\n                } else {\n                    false\n                }\n            }\n        }\n    }\n}\n\n/// A pseudo-class.\n#[derive(Clone, Copy, PartialEq, Debug)]\n#[allow(missing_docs)]\npub enum PseudoClass<'a> {\n    FirstChild,\n    Link,\n    Visited,\n    Hover,\n    Active,\n    Focus,\n    Lang(&'a str),\n}\n\nimpl fmt::Display for PseudoClass<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            PseudoClass::FirstChild => write!(f, \"first-child\"),\n            PseudoClass::Link => write!(f, \"link\"),\n            PseudoClass::Visited => write!(f, \"visited\"),\n            PseudoClass::Hover => write!(f, \"hover\"),\n            PseudoClass::Active => write!(f, \"active\"),\n            PseudoClass::Focus => write!(f, \"focus\"),\n            PseudoClass::Lang(lang) => write!(f, \"lang({})\", lang),\n        }\n    }\n}\n\n/// A trait to query an element node metadata.\npub trait Element: Sized {\n    /// Returns a parent element.\n    fn parent_element(&self) -> Option<Self>;\n\n    /// Returns a previous sibling element.\n    fn prev_sibling_element(&self) -> Option<Self>;\n\n    /// Checks that the element has a specified local name.\n    fn has_local_name(&self, name: &str) -> bool;\n\n    /// Checks that the element has a specified attribute.\n    fn attribute_matches(&self, local_name: &str, operator: AttributeOperator<'_>) -> bool;\n\n    /// Checks that the element matches a specified pseudo-class.\n    fn pseudo_class_matches(&self, class: PseudoClass<'_>) -> bool;\n}\n\n#[derive(Clone, Copy, PartialEq, Debug)]\nenum SimpleSelectorType<'a> {\n    Type(&'a str),\n    Universal,\n}\n\n#[derive(Clone, Copy, PartialEq, Debug)]\nenum SubSelector<'a> {\n    Attribute(&'a str, AttributeOperator<'a>),\n    PseudoClass(PseudoClass<'a>),\n}\n\n#[derive(Clone, Debug)]\nstruct SimpleSelector<'a> {\n    kind: SimpleSelectorType<'a>,\n    subselectors: Vec<SubSelector<'a>>,\n}\n\n#[derive(Clone, Copy, PartialEq, Debug)]\nenum Combinator {\n    None,\n    Descendant,\n    Child,\n    AdjacentSibling,\n}\n\n#[derive(Clone, Debug)]\nstruct Component<'a> {\n    /// A combinator that precede the selector.\n    combinator: Combinator,\n    selector: SimpleSelector<'a>,\n}\n\n/// A selector.\n#[derive(Clone, Debug)]\npub struct Selector<'a> {\n    components: Vec<Component<'a>>,\n}\n\nimpl<'a> Selector<'a> {\n    /// Parses a selector from a string.\n    ///\n    /// Will log any errors as a warnings.\n    ///\n    /// Parsing will be stopped at EOF, `,` or `{`.\n    pub fn parse(text: &'a str) -> Option<Self> {\n        parse(text).0\n    }\n\n    /// Compute the selector's specificity.\n    ///\n    /// Cf. <https://www.w3.org/TR/selectors/#specificity>.\n    pub fn specificity(&self) -> [u8; 3] {\n        let mut spec = [0u8; 3];\n\n        for selector in self.components.iter().map(|c| &c.selector) {\n            if matches!(selector.kind, SimpleSelectorType::Type(_)) {\n                spec[2] = spec[2].saturating_add(1);\n            }\n\n            for sub in &selector.subselectors {\n                match sub {\n                    SubSelector::Attribute(\"id\", _) => spec[0] = spec[0].saturating_add(1),\n                    _ => spec[1] = spec[1].saturating_add(1),\n                }\n            }\n        }\n\n        spec\n    }\n\n    /// Checks that the provided element matches the current selector.\n    pub fn matches<E: Element>(&self, element: &E) -> bool {\n        assert!(!self.components.is_empty(), \"selector must not be empty\");\n        assert_eq!(\n            self.components[0].combinator,\n            Combinator::None,\n            \"the first component must not have a combinator\"\n        );\n\n        self.matches_impl(self.components.len() - 1, element)\n    }\n\n    fn matches_impl<E: Element>(&self, idx: usize, element: &E) -> bool {\n        let component = &self.components[idx];\n\n        if !match_selector(&component.selector, element) {\n            return false;\n        }\n\n        match component.combinator {\n            Combinator::Descendant => {\n                let mut parent = element.parent_element();\n                while let Some(e) = parent {\n                    if self.matches_impl(idx - 1, &e) {\n                        return true;\n                    }\n\n                    parent = e.parent_element();\n                }\n\n                false\n            }\n            Combinator::Child => {\n                if let Some(parent) = element.parent_element() {\n                    if self.matches_impl(idx - 1, &parent) {\n                        return true;\n                    }\n                }\n\n                false\n            }\n            Combinator::AdjacentSibling => {\n                if let Some(prev) = element.prev_sibling_element() {\n                    if self.matches_impl(idx - 1, &prev) {\n                        return true;\n                    }\n                }\n\n                false\n            }\n            Combinator::None => true,\n        }\n    }\n}\n\nfn match_selector<E: Element>(selector: &SimpleSelector<'_>, element: &E) -> bool {\n    if let SimpleSelectorType::Type(ident) = selector.kind {\n        if !element.has_local_name(ident) {\n            return false;\n        }\n    }\n\n    for sub in &selector.subselectors {\n        match sub {\n            SubSelector::Attribute(name, operator) => {\n                if !element.attribute_matches(name, *operator) {\n                    return false;\n                }\n            }\n            SubSelector::PseudoClass(class) => {\n                if !element.pseudo_class_matches(*class) {\n                    return false;\n                }\n            }\n        }\n    }\n\n    true\n}\n\npub(crate) fn parse(text: &str) -> (Option<Selector<'_>>, usize) {\n    let mut components: Vec<Component<'_>> = Vec::new();\n    let mut combinator = Combinator::None;\n\n    let mut tokenizer = SelectorTokenizer::from(text);\n    for token in &mut tokenizer {\n        let mut add_sub = |sub| {\n            if combinator == Combinator::None && !components.is_empty() {\n                if let Some(ref mut component) = components.last_mut() {\n                    component.selector.subselectors.push(sub);\n                }\n            } else {\n                components.push(Component {\n                    selector: SimpleSelector {\n                        kind: SimpleSelectorType::Universal,\n                        subselectors: vec![sub],\n                    },\n                    combinator,\n                });\n\n                combinator = Combinator::None;\n            }\n        };\n\n        let token = match token {\n            Ok(t) => t,\n            Err(e) => {\n                warn!(\"Selector parsing failed cause {}.\", e);\n                return (None, tokenizer.stream.pos());\n            }\n        };\n\n        match token {\n            SelectorToken::UniversalSelector => {\n                components.push(Component {\n                    selector: SimpleSelector {\n                        kind: SimpleSelectorType::Universal,\n                        subselectors: Vec::new(),\n                    },\n                    combinator,\n                });\n\n                combinator = Combinator::None;\n            }\n            SelectorToken::TypeSelector(ident) => {\n                components.push(Component {\n                    selector: SimpleSelector {\n                        kind: SimpleSelectorType::Type(ident),\n                        subselectors: Vec::new(),\n                    },\n                    combinator,\n                });\n\n                combinator = Combinator::None;\n            }\n            SelectorToken::ClassSelector(ident) => {\n                add_sub(SubSelector::Attribute(\n                    \"class\",\n                    AttributeOperator::Contains(ident),\n                ));\n            }\n            SelectorToken::IdSelector(id) => {\n                add_sub(SubSelector::Attribute(\"id\", AttributeOperator::Matches(id)));\n            }\n            SelectorToken::AttributeSelector(name, op) => {\n                add_sub(SubSelector::Attribute(name, op));\n            }\n            SelectorToken::PseudoClass(ident) => {\n                let class = match ident {\n                    \"first-child\" => PseudoClass::FirstChild,\n                    \"link\" => PseudoClass::Link,\n                    \"visited\" => PseudoClass::Visited,\n                    \"hover\" => PseudoClass::Hover,\n                    \"active\" => PseudoClass::Active,\n                    \"focus\" => PseudoClass::Focus,\n                    _ => {\n                        warn!(\"':{}' is not supported. Selector skipped.\", ident);\n                        return (None, tokenizer.stream.pos());\n                    }\n                };\n\n                // TODO: duplicates\n                // TODO: order\n\n                add_sub(SubSelector::PseudoClass(class));\n            }\n            SelectorToken::LangPseudoClass(lang) => {\n                add_sub(SubSelector::PseudoClass(PseudoClass::Lang(lang)));\n            }\n            SelectorToken::DescendantCombinator => {\n                combinator = Combinator::Descendant;\n            }\n            SelectorToken::ChildCombinator => {\n                combinator = Combinator::Child;\n            }\n            SelectorToken::AdjacentCombinator => {\n                combinator = Combinator::AdjacentSibling;\n            }\n        }\n    }\n\n    if components.is_empty() {\n        (None, tokenizer.stream.pos())\n    } else if components[0].combinator != Combinator::None {\n        debug_assert_eq!(\n            components[0].combinator,\n            Combinator::None,\n            \"the first component must not have a combinator\"\n        );\n\n        (None, tokenizer.stream.pos())\n    } else {\n        (Some(Selector { components }), tokenizer.stream.pos())\n    }\n}\n\nimpl fmt::Display for Selector<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        for component in &self.components {\n            match component.combinator {\n                Combinator::Descendant => write!(f, \" \")?,\n                Combinator::Child => write!(f, \" > \")?,\n                Combinator::AdjacentSibling => write!(f, \" + \")?,\n                Combinator::None => {}\n            }\n\n            match component.selector.kind {\n                SimpleSelectorType::Universal => write!(f, \"*\")?,\n                SimpleSelectorType::Type(ident) => write!(f, \"{}\", ident)?,\n            };\n\n            for sel in &component.selector.subselectors {\n                match sel {\n                    SubSelector::Attribute(name, operator) => {\n                        match operator {\n                            AttributeOperator::Exists => {\n                                write!(f, \"[{}]\", name)?;\n                            }\n                            AttributeOperator::Matches(value) => {\n                                write!(f, \"[{}='{}']\", name, value)?;\n                            }\n                            AttributeOperator::Contains(value) => {\n                                write!(f, \"[{}~='{}']\", name, value)?;\n                            }\n                            AttributeOperator::StartsWith(value) => {\n                                write!(f, \"[{}|='{}']\", name, value)?;\n                            }\n                        };\n                    }\n                    SubSelector::PseudoClass(class) => write!(f, \":{}\", class)?,\n                }\n            }\n        }\n\n        Ok(())\n    }\n}\n\n/// A selector token.\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum SelectorToken<'a> {\n    /// `*`\n    UniversalSelector,\n\n    /// `div`\n    TypeSelector(&'a str),\n\n    /// `.class`\n    ClassSelector(&'a str),\n\n    /// `#id`\n    IdSelector(&'a str),\n\n    /// `[color=red]`\n    AttributeSelector(&'a str, AttributeOperator<'a>),\n\n    /// `:first-child`\n    PseudoClass(&'a str),\n\n    /// `:lang(en)`\n    LangPseudoClass(&'a str),\n\n    /// `a b`\n    DescendantCombinator,\n\n    /// `a > b`\n    ChildCombinator,\n\n    /// `a + b`\n    AdjacentCombinator,\n}\n\n/// A selector tokenizer.\n///\n/// # Example\n///\n/// ```\n/// use simplecss::{SelectorTokenizer, SelectorToken};\n///\n/// let mut t = SelectorTokenizer::from(\"div > p:first-child\");\n/// assert_eq!(t.next().unwrap().unwrap(), SelectorToken::TypeSelector(\"div\"));\n/// assert_eq!(t.next().unwrap().unwrap(), SelectorToken::ChildCombinator);\n/// assert_eq!(t.next().unwrap().unwrap(), SelectorToken::TypeSelector(\"p\"));\n/// assert_eq!(t.next().unwrap().unwrap(), SelectorToken::PseudoClass(\"first-child\"));\n/// assert!(t.next().is_none());\n/// ```\npub struct SelectorTokenizer<'a> {\n    stream: Stream<'a>,\n    after_combinator: bool,\n    finished: bool,\n}\n\nimpl<'a> From<&'a str> for SelectorTokenizer<'a> {\n    fn from(text: &'a str) -> Self {\n        SelectorTokenizer {\n            stream: Stream::from(text),\n            after_combinator: true,\n            finished: false,\n        }\n    }\n}\n\nimpl<'a> Iterator for SelectorTokenizer<'a> {\n    type Item = Result<SelectorToken<'a>, Error>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.finished || self.stream.at_end() {\n            if self.after_combinator {\n                self.after_combinator = false;\n                return Some(Err(Error::SelectorMissing));\n            }\n\n            return None;\n        }\n\n        macro_rules! try2 {\n            ($e:expr) => {\n                match $e {\n                    Ok(v) => v,\n                    Err(e) => {\n                        self.finished = true;\n                        return Some(Err(e));\n                    }\n                }\n            };\n        }\n\n        match self.stream.curr_byte_unchecked() {\n            b'*' => {\n                if !self.after_combinator {\n                    self.finished = true;\n                    return Some(Err(Error::UnexpectedSelector));\n                }\n\n                self.after_combinator = false;\n                self.stream.advance(1);\n                Some(Ok(SelectorToken::UniversalSelector))\n            }\n            b'#' => {\n                self.after_combinator = false;\n                self.stream.advance(1);\n                let ident = try2!(self.stream.consume_ident());\n                Some(Ok(SelectorToken::IdSelector(ident)))\n            }\n            b'.' => {\n                self.after_combinator = false;\n                self.stream.advance(1);\n                let ident = try2!(self.stream.consume_ident());\n                Some(Ok(SelectorToken::ClassSelector(ident)))\n            }\n            b'[' => {\n                self.after_combinator = false;\n                self.stream.advance(1);\n                let ident = try2!(self.stream.consume_ident());\n\n                let op = match try2!(self.stream.curr_byte()) {\n                    b']' => AttributeOperator::Exists,\n                    b'=' => {\n                        self.stream.advance(1);\n                        let value = try2!(self.stream.consume_string());\n                        AttributeOperator::Matches(value)\n                    }\n                    b'~' => {\n                        self.stream.advance(1);\n                        try2!(self.stream.consume_byte(b'='));\n                        let value = try2!(self.stream.consume_string());\n                        AttributeOperator::Contains(value)\n                    }\n                    b'|' => {\n                        self.stream.advance(1);\n                        try2!(self.stream.consume_byte(b'='));\n                        let value = try2!(self.stream.consume_string());\n                        AttributeOperator::StartsWith(value)\n                    }\n                    _ => {\n                        self.finished = true;\n                        return Some(Err(Error::InvalidAttributeSelector));\n                    }\n                };\n\n                try2!(self.stream.consume_byte(b']'));\n\n                Some(Ok(SelectorToken::AttributeSelector(ident, op)))\n            }\n            b':' => {\n                self.after_combinator = false;\n                self.stream.advance(1);\n                let ident = try2!(self.stream.consume_ident());\n\n                if ident == \"lang\" {\n                    try2!(self.stream.consume_byte(b'('));\n                    let lang = self.stream.consume_bytes(|c| c != b')').trim();\n                    try2!(self.stream.consume_byte(b')'));\n\n                    if lang.is_empty() {\n                        self.finished = true;\n                        return Some(Err(Error::InvalidLanguagePseudoClass));\n                    }\n\n                    Some(Ok(SelectorToken::LangPseudoClass(lang)))\n                } else {\n                    Some(Ok(SelectorToken::PseudoClass(ident)))\n                }\n            }\n            b'>' => {\n                if self.after_combinator {\n                    self.after_combinator = false;\n                    self.finished = true;\n                    return Some(Err(Error::UnexpectedCombinator));\n                }\n\n                self.stream.advance(1);\n                self.after_combinator = true;\n                Some(Ok(SelectorToken::ChildCombinator))\n            }\n            b'+' => {\n                if self.after_combinator {\n                    self.after_combinator = false;\n                    self.finished = true;\n                    return Some(Err(Error::UnexpectedCombinator));\n                }\n\n                self.stream.advance(1);\n                self.after_combinator = true;\n                Some(Ok(SelectorToken::AdjacentCombinator))\n            }\n            b' ' | b'\\t' | b'\\n' | b'\\r' | b'\\x0C' => {\n                self.stream.skip_spaces();\n\n                if self.after_combinator {\n                    return self.next();\n                }\n\n                while self.stream.curr_byte() == Ok(b'/') {\n                    try2!(self.stream.skip_comment());\n                    self.stream.skip_spaces();\n                }\n\n                match self.stream.curr_byte() {\n                    Ok(b'>') | Ok(b'+') | Ok(b',') | Ok(b'{') | Err(_) => self.next(),\n                    _ => {\n                        if self.after_combinator {\n                            self.after_combinator = false;\n                            self.finished = true;\n                            return Some(Err(Error::UnexpectedSelector));\n                        }\n\n                        self.after_combinator = true;\n                        Some(Ok(SelectorToken::DescendantCombinator))\n                    }\n                }\n            }\n            b'/' => {\n                if self.stream.next_byte() == Ok(b'*') {\n                    try2!(self.stream.skip_comment());\n                } else {\n                    self.finished = true;\n                }\n\n                self.next()\n            }\n            b',' | b'{' => {\n                self.finished = true;\n                self.next()\n            }\n            _ => {\n                let ident = try2!(self.stream.consume_ident());\n\n                if !self.after_combinator {\n                    self.finished = true;\n                    return Some(Err(Error::UnexpectedSelector));\n                }\n\n                self.after_combinator = false;\n                Some(Ok(SelectorToken::TypeSelector(ident)))\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "src/stream.rs",
      "sha256": "b9750b32e474dd7d69430c9ed7e848df6ceb5fe52a0da20159d6d1274dfeee8e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2016 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse core::str;\n\nuse crate::{Error, TextPos};\n\ntrait CssCharExt {\n    fn is_name_start(&self) -> bool;\n    fn is_name_char(&self) -> bool;\n    fn is_non_ascii(&self) -> bool;\n    fn is_escape(&self) -> bool;\n}\n\nimpl CssCharExt for char {\n    #[inline]\n    fn is_name_start(&self) -> bool {\n        match *self {\n            '_' | 'a'..='z' | 'A'..='Z' => true,\n            _ => self.is_non_ascii() || self.is_escape(),\n        }\n    }\n\n    #[inline]\n    fn is_name_char(&self) -> bool {\n        match *self {\n            '_' | 'a'..='z' | 'A'..='Z' | '0'..='9' | '-' => true,\n            _ => self.is_non_ascii() || self.is_escape(),\n        }\n    }\n\n    #[inline]\n    fn is_non_ascii(&self) -> bool {\n        *self as u32 > 237\n    }\n\n    #[inline]\n    fn is_escape(&self) -> bool {\n        // TODO: this\n        false\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Debug)]\npub(crate) struct Stream<'a> {\n    text: &'a str,\n    pos: usize,\n    end: usize,\n}\n\nimpl<'a> From<&'a str> for Stream<'a> {\n    fn from(text: &'a str) -> Self {\n        Stream::new(text)\n    }\n}\n\nimpl<'a> Stream<'a> {\n    pub fn new(text: &'a str) -> Self {\n        Stream {\n            text,\n            pos: 0,\n            end: text.len(),\n        }\n    }\n\n    #[inline]\n    pub fn pos(&self) -> usize {\n        self.pos\n    }\n\n    #[inline]\n    pub fn jump_to_end(&mut self) {\n        self.pos = self.end;\n    }\n\n    #[inline]\n    pub fn at_end(&self) -> bool {\n        self.pos >= self.end\n    }\n\n    #[inline]\n    pub fn curr_byte(&self) -> Result<u8, Error> {\n        if self.at_end() {\n            return Err(Error::UnexpectedEndOfStream);\n        }\n\n        Ok(self.curr_byte_unchecked())\n    }\n\n    #[inline]\n    pub fn curr_byte_unchecked(&self) -> u8 {\n        self.text.as_bytes()[self.pos]\n    }\n\n    #[inline]\n    pub fn next_byte(&self) -> Result<u8, Error> {\n        if self.pos + 1 >= self.end {\n            return Err(Error::UnexpectedEndOfStream);\n        }\n\n        Ok(self.text.as_bytes()[self.pos + 1])\n    }\n\n    #[inline]\n    pub fn advance(&mut self, n: usize) {\n        debug_assert!(self.pos + n <= self.end);\n        self.pos += n;\n    }\n\n    pub fn consume_byte(&mut self, c: u8) -> Result<(), Error> {\n        if self.curr_byte()? != c {\n            return Err(Error::InvalidByte {\n                expected: c,\n                actual: self.curr_byte()?,\n                pos: self.gen_text_pos(),\n            });\n        }\n\n        self.advance(1);\n        Ok(())\n    }\n\n    pub fn try_consume_byte(&mut self, c: u8) {\n        if self.curr_byte() == Ok(c) {\n            self.advance(1);\n        }\n    }\n\n    pub fn consume_bytes<F>(&mut self, f: F) -> &'a str\n    where\n        F: Fn(u8) -> bool,\n    {\n        let start = self.pos;\n        self.skip_bytes(f);\n        self.slice_back(start)\n    }\n\n    pub fn skip_bytes<F>(&mut self, f: F)\n    where\n        F: Fn(u8) -> bool,\n    {\n        while !self.at_end() && f(self.curr_byte_unchecked()) {\n            self.advance(1);\n        }\n    }\n\n    #[inline]\n    fn chars(&self) -> str::Chars<'a> {\n        self.text[self.pos..self.end].chars()\n    }\n\n    #[inline]\n    pub fn slice_range(&self, start: usize, end: usize) -> &'a str {\n        &self.text[start..end]\n    }\n\n    #[inline]\n    pub fn slice_back(&self, pos: usize) -> &'a str {\n        &self.text[pos..self.pos]\n    }\n\n    #[inline]\n    pub fn slice_tail(&self) -> &'a str {\n        &self.text[self.pos..]\n    }\n\n    #[inline]\n    pub fn skip_spaces(&mut self) {\n        while !self.at_end() {\n            match self.curr_byte_unchecked() {\n                b' ' | b'\\t' | b'\\n' | b'\\r' | b'\\x0C' => self.advance(1),\n                _ => break,\n            }\n        }\n    }\n\n    #[inline]\n    pub fn skip_spaces_and_comments(&mut self) -> Result<(), Error> {\n        self.skip_spaces();\n        while self.curr_byte() == Ok(b'/') && self.next_byte() == Ok(b'*') {\n            self.skip_comment()?;\n            self.skip_spaces();\n        }\n\n        Ok(())\n    }\n\n    pub fn consume_ident(&mut self) -> Result<&'a str, Error> {\n        let start = self.pos();\n\n        if self.curr_byte() == Ok(b'-') {\n            self.advance(1);\n        }\n\n        let mut iter = self.chars();\n        if let Some(c) = iter.next() {\n            if c.is_name_start() {\n                self.advance(c.len_utf8());\n            } else {\n                return Err(Error::InvalidIdent(self.gen_text_pos_from(start)));\n            }\n        }\n\n        for c in iter {\n            if c.is_name_char() {\n                self.advance(c.len_utf8());\n            } else {\n                break;\n            }\n        }\n\n        if start == self.pos() {\n            return Err(Error::InvalidIdent(self.gen_text_pos_from(start)));\n        }\n\n        let name = self.slice_back(start);\n        Ok(name)\n    }\n\n    pub fn consume_string(&mut self) -> Result<&'a str, Error> {\n        // Check for opening quote.\n        let quote = self.curr_byte()?;\n        if quote == b'\\'' || quote == b'\"' {\n            let mut prev = quote;\n            self.advance(1);\n\n            let start = self.pos();\n\n            while !self.at_end() {\n                let curr = self.curr_byte_unchecked();\n\n                // Advance until the closing quote.\n                if curr == quote {\n                    // Check for escaped quote.\n                    if prev != b'\\\\' {\n                        break;\n                    }\n                }\n\n                prev = curr;\n                self.advance(1);\n            }\n\n            let value = self.slice_back(start);\n\n            // Check for closing quote.\n            self.consume_byte(quote)?;\n\n            Ok(value)\n        } else {\n            self.consume_ident()\n        }\n    }\n\n    pub fn skip_comment(&mut self) -> Result<(), Error> {\n        let start = self.pos();\n        self.skip_comment_impl()\n            .map_err(|_| Error::InvalidComment(self.gen_text_pos_from(start)))?;\n        Ok(())\n    }\n\n    fn skip_comment_impl(&mut self) -> Result<(), Error> {\n        self.consume_byte(b'/')?;\n        self.consume_byte(b'*')?;\n\n        while !self.at_end() {\n            let curr = self.curr_byte_unchecked();\n            if curr == b'*' && self.next_byte() == Ok(b'/') {\n                break;\n            }\n\n            self.advance(1);\n        }\n\n        self.consume_byte(b'*')?;\n        self.consume_byte(b'/')?;\n        Ok(())\n    }\n\n    #[inline(never)]\n    pub fn gen_text_pos(&self) -> TextPos {\n        let row = Self::calc_curr_row(self.text, self.pos);\n        let col = Self::calc_curr_col(self.text, self.pos);\n        TextPos::new(row, col)\n    }\n\n    #[inline(never)]\n    pub fn gen_text_pos_from(&self, pos: usize) -> TextPos {\n        let mut s = *self;\n        s.pos = core::cmp::min(pos, self.text.len());\n        s.gen_text_pos()\n    }\n\n    fn calc_curr_row(text: &str, end: usize) -> u32 {\n        let mut row = 1;\n        for c in &text.as_bytes()[..end] {\n            if *c == b'\\n' {\n                row += 1;\n            }\n        }\n\n        row\n    }\n\n    fn calc_curr_col(text: &str, end: usize) -> u32 {\n        let mut col = 1;\n        for c in text[..end].chars().rev() {\n            if c == '\\n' {\n                break;\n            } else {\n                col += 1;\n            }\n        }\n\n        col\n    }\n}\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "tests/declaration_tokenizer.rs",
      "sha256": "b2ffc1d4a84ae740dfd6fba873b3b32604a7d445d9ab8ddb3927e7103ae0b04b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Declaration Tokenizer\n\nuse simplecss::*;\n\nmacro_rules! tokenize {\n    ($name:ident, $text:expr, $( $token:expr ),*) => (\n        #[test]\n        fn $name() {\n            let mut t = DeclarationTokenizer::from($text);\n            $(\n                assert_eq!(t.next().unwrap(), $token);\n            )*\n\n            assert!(t.next().is_none());\n        }\n    )\n}\n\nfn declare<'a>(name: &'a str, value: &'a str) -> Declaration<'a> {\n    Declaration {\n        name,\n        value,\n        important: false,\n    }\n}\n\nfn declare_important<'a>(name: &'a str, value: &'a str) -> Declaration<'a> {\n    Declaration {\n        name,\n        value,\n        important: true,\n    }\n}\n\ntokenize!(tokenize_01, \"\",);\n\ntokenize!(tokenize_02, \" \",);\n\ntokenize!(tokenize_03, \"/**/\",);\n\ntokenize!(tokenize_04, \"color:red\", declare(\"color\", \"red\"));\n\ntokenize!(tokenize_05, \"color:red;\", declare(\"color\", \"red\"));\n\ntokenize!(tokenize_06, \"color:red \", declare(\"color\", \"red\"));\n\ntokenize!(tokenize_07, \" color: red; \", declare(\"color\", \"red\"));\n\ntokenize!(tokenize_08, \"  color  :  red  ; \", declare(\"color\", \"red\"));\n\ntokenize!(\n    tokenize_09,\n    \"  color:red;;;;color:red; \",\n    declare(\"color\", \"red\"),\n    declare(\"color\", \"red\")\n);\n\ntokenize!(\n    tokenize_10,\n    \"background: url(\\\"img.png\\\");\",\n    declare(\"background\", \"url(\\\"img.png\\\")\")\n);\n\ntokenize!(\n    tokenize_11,\n    \"background: url(\\\"{}\\\");\",\n    declare(\"background\", \"url(\\\"{}\\\")\")\n);\n\ntokenize!(\n    tokenize_12,\n    \"color: red ! important\",\n    declare_important(\"color\", \"red\")\n);\n\ntokenize!(\n    tokenize_13,\n    \"color: red !important\",\n    declare_important(\"color\", \"red\")\n);\n\ntokenize!(\n    tokenize_14,\n    \"color: red!important\",\n    declare_important(\"color\", \"red\")\n);\n\ntokenize!(\n    tokenize_15,\n    \"color: red !/**/important\",\n    declare_important(\"color\", \"red\")\n);\n\ntokenize!(\n    tokenize_16,\n    \"border: 1em solid blue\",\n    declare(\"border\", \"1em solid blue\")\n);\n\ntokenize!(\n    tokenize_17,\n    \"background: navy url(support/diamond.png) -2em -2em no-repeat\",\n    declare(\n        \"background\",\n        \"navy url(support/diamond.png) -2em -2em no-repeat\"\n    )\n);\n\ntokenize!(tokenize_18, \"/**/color:red\", declare(\"color\", \"red\"));\n\ntokenize!(tokenize_19, \"/* *\\\\/*/color: red;\", declare(\"color\", \"red\"));\n\ntokenize!(\n    tokenize_20,\n    \"/**/color/**/:/**/red/**/;/**/\",\n    declare(\"color\", \"red\")\n);\n\ntokenize!(tokenize_21, \"\\ncolor\\n:\\nred\\n;\\n\", declare(\"color\", \"red\"));\n\ntokenize!(tokenize_22, \"{color:red}\",);\n\ntokenize!(tokenize_23, \"(color:red)\",);\n\ntokenize!(tokenize_24, \"[color:red]\",);\n\ntokenize!(tokenize_25, \"color:\",);\n\ntokenize!(tokenize_26, \"value:\\\"text\\\"\", declare(\"value\", \"\\\"text\\\"\"));\n\ntokenize!(tokenize_27, \"value:'text'\", declare(\"value\", \"'text'\"));\n\ntokenize!(tokenize_28, \"color:#fff\", declare(\"color\", \"#fff\"));\ntokenize!(tokenize_29, \"color:0.5\", declare(\"color\", \"0.5\"));\n\ntokenize!(tokenize_30, \"color:.5\", declare(\"color\", \".5\"));\n\ntokenize!(tokenize_31, \"color:#FFF\", declare(\"color\", \"#FFF\"));\n\ntokenize!(\n    tokenize_32,\n    \"content: counter(chapno, upper-roman) \\\". \\\"\",\n    declare(\"content\", \"counter(chapno, upper-roman) \\\". \\\"\")\n);\n\ntokenize!(\n    tokenize_33,\n    \"font-family:'Noto Serif','DejaVu Serif',serif\",\n    declare(\"font-family\", \"'Noto Serif','DejaVu Serif',serif\")\n);\n\ntokenize!(tokenize_34, \"*zoom:1;\", declare(\"zoom\", \"1\"));\n\n//tokenize!(tokenize_, \"@unsupported { splines: reticulating } color: green\",\n//    declare(\"color\", \"green\")\n//);\n\n//tokenize!(tokenize_, \"/*\\\\*/*/color: red;\", declare(\"color\", \"red\"));\n\n//tokenize!(tokenize_, \"\\\"this is a string]}\\\"\\\"[{\\\\\\\"'\\\";  /*should be parsed as a string but be ignored*/\n//    {{}}[]'';                     /*should be parsed as nested blocks and a string but be ignored*/\n//    color: red;\", declare(\"color\", \"red\"));\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "tests/select.rs",
      "sha256": "180301f547fe7dc44efdc26e27cee4df7ffb0a19372f79ef22b6d75c5e85b6cf",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Select\n\nuse simplecss::*;\n\nstruct XmlNode<'a, 'input: 'a>(roxmltree::Node<'a, 'input>);\n\nimpl<'a, 'input: 'a> XmlNode<'a, 'input> {\n    fn select(&self, text: &str) -> Vec<roxmltree::Node<'a, 'input>> {\n        let selectors = Selector::parse(text).unwrap();\n        let mut nodes = Vec::new();\n        for node in self.0.descendants().filter(|n| n.is_element()) {\n            if selectors.matches(&XmlNode(node)) {\n                nodes.push(node);\n            }\n        }\n\n        nodes\n    }\n}\n\nimpl Element for XmlNode<'_, '_> {\n    fn parent_element(&self) -> Option<Self> {\n        self.0.parent_element().map(XmlNode)\n    }\n\n    fn prev_sibling_element(&self) -> Option<Self> {\n        self.0.prev_sibling_element().map(XmlNode)\n    }\n\n    fn has_local_name(&self, local_name: &str) -> bool {\n        self.0.tag_name().name() == local_name\n    }\n\n    fn attribute_matches(&self, local_name: &str, operator: AttributeOperator<'_>) -> bool {\n        match self.0.attribute(local_name) {\n            Some(value) => operator.matches(value),\n            None => false,\n        }\n    }\n\n    fn pseudo_class_matches(&self, class: PseudoClass<'_>) -> bool {\n        match class {\n            PseudoClass::FirstChild => self.prev_sibling_element().is_none(),\n            _ => false,\n        }\n    }\n}\n\nmacro_rules! match_single {\n    ($doc:expr, $selector:expr) => {{\n        let nodes = XmlNode($doc.root_element()).select($selector);\n        assert_eq!(nodes.len(), 1);\n        nodes[0].attribute(\"id\").unwrap()\n    }};\n}\n\nmacro_rules! match_none {\n    ($doc:expr, $selector:expr) => {{\n        assert_eq!(XmlNode($doc.root_element()).select($selector).len(), 0);\n    }};\n}\n\n#[test]\nfn select_01() {\n    let doc = roxmltree::Document::parse(\"<div id='div1'/>\").unwrap();\n    assert_eq!(match_single!(doc, \"*\"), \"div1\");\n}\n\n#[test]\nfn select_02() {\n    let doc = roxmltree::Document::parse(\"<div id='div1'/>\").unwrap();\n    assert_eq!(match_single!(doc, \"div\"), \"div1\");\n    match_none!(doc, \"p\");\n}\n\n#[test]\nfn select_03() {\n    let doc = roxmltree::Document::parse(\"<div id='div1'/>\").unwrap();\n    assert_eq!(match_single!(doc, \"#div1\"), \"div1\");\n    match_none!(doc, \"#d1\");\n}\n\n#[test]\nfn select_04() {\n    let doc = roxmltree::Document::parse(\"<div id='div1'/>\").unwrap();\n    match_none!(doc, \"p#div1\");\n}\n\n#[test]\nfn select_05() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"div p\"), \"p1\");\n}\n\n#[test]\nfn select_06() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <g id='g1'>\n        <p id='p1'/>\n    </g>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"div p\"), \"p1\");\n}\n\n#[test]\nfn select_07() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <div id='div2'>\n        <g id='g1'>\n            <p id='p1'/>\n        </g>\n    </div>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"div p\"), \"p1\");\n}\n\n#[test]\nfn select_08() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <g id='g1'>\n        <p id='p1'>\n            <div/>\n        </p>\n    </g>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"div p\"), \"p1\");\n}\n\n#[test]\nfn select_09() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <g id='g1'>\n        <p id='p1'/>\n    </g>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"div g p\"), \"p1\");\n}\n\n#[test]\nfn select_10() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <q id='g1'>\n        <p id='p1'/>\n    </q>\n</div>\n\",\n    )\n    .unwrap();\n\n    match_none!(doc, \"div g p\");\n}\n\n#[test]\nfn select_11() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <g id='g1'>\n        <p id='p1'/>\n    </g>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"div * p\"), \"p1\");\n}\n\n#[test]\nfn select_12() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1'>\n        <rect id='rect1'/>\n        <rect id='rect2' color='green'/>\n    </p>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"div p *[color]\"), \"rect2\");\n    assert_eq!(match_single!(doc, \"div p [color]\"), \"rect2\");\n}\n\n#[test]\nfn select_13() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"div > p\"), \"p1\");\n}\n\n#[test]\nfn select_14() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<p id='p1'/>\n\",\n    )\n    .unwrap();\n\n    match_none!(doc, \"div > p\");\n}\n\n#[test]\nfn select_15() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <g id='g1'>\n        <p id='p1'/>\n    </g>\n</div>\n\",\n    )\n    .unwrap();\n\n    match_none!(doc, \"div > p\");\n}\n\n#[test]\nfn select_16() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p>\n        <ol>\n            <li>\n                <g>\n                    <p id='p1'/>\n                </g>\n            </li>\n        </ol>\n    </p>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"div ol>li p\"), \"p1\");\n}\n\n#[test]\nfn select_17() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p>\n        <ol>\n            <g>\n                <li>\n                    <g>\n                        <p id='p1'/>\n                    </g>\n                </li>\n            </g>\n        </ol>\n    </p>\n</div>\n\",\n    )\n    .unwrap();\n\n    match_none!(doc, \"div ol>li p\");\n}\n\n#[test]\nfn select_18() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <g/>\n    <p id='p1'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"g + p\"), \"p1\");\n}\n\n#[test]\nfn select_19() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <test/>\n    <g/>\n    <p id='p1'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"g + p\"), \"p1\");\n}\n\n#[test]\nfn select_20() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1'/>\n    <g/>\n</div>\n\",\n    )\n    .unwrap();\n\n    match_none!(doc, \"g + p\");\n}\n\n#[test]\nfn select_21() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    match_none!(doc, \"div + p\");\n}\n\n#[test]\nfn select_22() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"[id=p1]\"), \"p1\");\n}\n\n#[test]\nfn select_23() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1' class='test warn'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"[class~=warn]\"), \"p1\");\n}\n\n#[test]\nfn select_24() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1' class='test warn'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    match_none!(doc, \"[class~='test warn']\");\n}\n\n#[test]\nfn select_25() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1' lang='en'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"[lang=en]\"), \"p1\");\n    assert_eq!(match_single!(doc, \"[lang|=en]\"), \"p1\");\n}\n\n#[test]\nfn select_26() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1' lang='en-US'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"[lang='en-US']\"), \"p1\");\n    assert_eq!(match_single!(doc, \"[lang|=en]\"), \"p1\");\n}\n\n#[test]\nfn select_27() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1' class='pastoral blue aqua marine'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \".marine.pastoral\"), \"p1\");\n}\n\n#[test]\nfn select_28() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    assert_eq!(match_single!(doc, \"p:first-child\"), \"p1\");\n}\n\n#[test]\nfn select_29() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <rect/>\n    <p id='p1'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    match_none!(doc, \"p:first-child\");\n}\n\n#[test]\nfn select_30() {\n    let doc = roxmltree::Document::parse(\n        \"\\\n<div id='div1'>\n    <p id='p1'/>\n    <p id='p2'/>\n</div>\n\",\n    )\n    .unwrap();\n\n    let nodes = XmlNode(doc.root_element()).select(\":first-child\");\n    assert_eq!(nodes.len(), 2);\n    assert_eq!(nodes[0].attribute(\"id\").unwrap(), \"div1\");\n    assert_eq!(nodes[1].attribute(\"id\").unwrap(), \"p1\");\n}\n\n#[test]\nfn to_string() {\n    let selectors = Selector::parse(\"a > b\").unwrap();\n    assert_eq!(selectors.to_string(), \"a > b\");\n}\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "tests/selector_tokenizer.rs",
      "sha256": "45c32806e8857bd6cf560d4c787aa6fb872f40505159a2643a254c664ec85ec9",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Selector Tokenizer\n\nuse simplecss::*;\n\nmacro_rules! tokenize {\n    ($name:ident, $text:expr, $( $token:expr ),*) => (\n        #[test]\n        fn $name() {\n            let mut t = SelectorTokenizer::from($text);\n            $(\n                assert_eq!(t.next().unwrap().unwrap(), $token);\n            )*\n\n            assert!(t.next().is_none());\n        }\n    )\n}\n\ntokenize!(tokenize_01, \"*\", SelectorToken::UniversalSelector);\n\ntokenize!(tokenize_02, \"div\", SelectorToken::TypeSelector(\"div\"));\n\ntokenize!(tokenize_03, \"#div\", SelectorToken::IdSelector(\"div\"));\n\ntokenize!(tokenize_04, \".div\", SelectorToken::ClassSelector(\"div\"));\n\ntokenize!(\n    tokenize_05,\n    \"[id]\",\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::Exists)\n);\n\ntokenize!(\n    tokenize_06,\n    \"[id=test]\",\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::Matches(\"test\"))\n);\n\ntokenize!(\n    tokenize_07,\n    \"[id~=test]\",\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::Contains(\"test\"))\n);\n\ntokenize!(\n    tokenize_08,\n    \"[id|=test]\",\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::StartsWith(\"test\"))\n);\n\ntokenize!(\n    tokenize_09,\n    \"[id='test']\",\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::Matches(\"test\"))\n);\n\ntokenize!(\n    tokenize_10,\n    \"[id=\\\"test\\\"]\",\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::Matches(\"test\"))\n);\n\ntokenize!(\n    tokenize_11,\n    \"[id='te\\\\'st']\",\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::Matches(\"te\\\\'st\"))\n);\n\ntokenize!(\n    tokenize_12,\n    \"[id=\\\"te\\\\\\\"st\\\"]\",\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::Matches(\"te\\\\\\\"st\"))\n);\n\ntokenize!(\n    tokenize_13,\n    \"div:first-child\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::PseudoClass(\"first-child\")\n);\n\ntokenize!(\n    tokenize_14,\n    \":first-child\",\n    SelectorToken::PseudoClass(\"first-child\")\n);\n\ntokenize!(\n    tokenize_15,\n    \"div p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_16,\n    \"div p a\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"p\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"a\")\n);\n\ntokenize!(\n    tokenize_17,\n    \"div>p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::ChildCombinator,\n    SelectorToken::TypeSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_18,\n    \"div >p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::ChildCombinator,\n    SelectorToken::TypeSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_19,\n    \"div> p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::ChildCombinator,\n    SelectorToken::TypeSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_20,\n    \"div > p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::ChildCombinator,\n    SelectorToken::TypeSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_21,\n    \"div .p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::ClassSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_22,\n    \"div *\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::UniversalSelector\n);\n\ntokenize!(\n    tokenize_23,\n    \"div #p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::IdSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_24,\n    \"div [id]\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::Exists)\n);\n\ntokenize!(\n    tokenize_25,\n    \"div :link\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::PseudoClass(\"link\")\n);\n\ntokenize!(\n    tokenize_26,\n    \"div+p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::AdjacentCombinator,\n    SelectorToken::TypeSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_27,\n    \"div +p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::AdjacentCombinator,\n    SelectorToken::TypeSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_28,\n    \"div+ p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::AdjacentCombinator,\n    SelectorToken::TypeSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_29,\n    \"div + p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::AdjacentCombinator,\n    SelectorToken::TypeSelector(\"p\")\n);\n\ntokenize!(tokenize_30, \"div {\", SelectorToken::TypeSelector(\"div\"));\n\ntokenize!(tokenize_31, \"div,\", SelectorToken::TypeSelector(\"div\"));\n\ntokenize!(tokenize_32, \"div{\", SelectorToken::TypeSelector(\"div\"));\n\ntokenize!(tokenize_33, \"div ,\", SelectorToken::TypeSelector(\"div\"));\n\ntokenize!(\n    tokenize_34,\n    \"div.test\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::ClassSelector(\"test\")\n);\n\ntokenize!(\n    tokenize_35,\n    \"div.test.warn\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::ClassSelector(\"test\"),\n    SelectorToken::ClassSelector(\"warn\")\n);\n\ntokenize!(\n    tokenize_36,\n    \"div#id\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::IdSelector(\"id\")\n);\n\ntokenize!(\n    tokenize_37,\n    \"*[id]\",\n    SelectorToken::UniversalSelector,\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::Exists)\n);\n\ntokenize!(\n    tokenize_38,\n    \"*.test\",\n    SelectorToken::UniversalSelector,\n    SelectorToken::ClassSelector(\"test\")\n);\n\ntokenize!(\n    tokenize_39,\n    \"*#id\",\n    SelectorToken::UniversalSelector,\n    SelectorToken::IdSelector(\"id\")\n);\n\ntokenize!(\n    tokenize_40,\n    \"div * p\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::UniversalSelector,\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"p\")\n);\n\ntokenize!(\n    tokenize_41,\n    \"div[id=test][color=red]\",\n    SelectorToken::TypeSelector(\"div\"),\n    SelectorToken::AttributeSelector(\"id\", AttributeOperator::Matches(\"test\")),\n    SelectorToken::AttributeSelector(\"color\", AttributeOperator::Matches(\"red\"))\n);\n\ntokenize!(\n    tokenize_42,\n    \"a.external:visited\",\n    SelectorToken::TypeSelector(\"a\"),\n    SelectorToken::ClassSelector(\"external\"),\n    SelectorToken::PseudoClass(\"visited\")\n);\n\ntokenize!(\n    tokenize_43,\n    \":lang(en)\",\n    SelectorToken::LangPseudoClass(\"en\")\n);\n\ntokenize!(\n    tokenize_44,\n    \"a\\nb\",\n    SelectorToken::TypeSelector(\"a\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"b\")\n);\n\ntokenize!(\n    tokenize_45,\n    \".warn :first-child\",\n    SelectorToken::ClassSelector(\"warn\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::PseudoClass(\"first-child\")\n);\n\nmacro_rules! malformed {\n    ($name:ident, $text:expr, $err_str:expr) => {\n        #[test]\n        fn $name() {\n            for token in SelectorTokenizer::from($text) {\n                match token {\n                    Ok(_) => {}\n                    Err(e) => {\n                        assert_eq!(e.to_string(), $err_str);\n                        return;\n                    }\n                }\n            }\n\n            unreachable!()\n        }\n    };\n}\n\nmalformed!(malformed_01, \">\", \"unexpected combinator\");\n\nmalformed!(malformed_02, \"+\", \"unexpected combinator\");\n\nmalformed!(malformed_03, \"> a\", \"unexpected combinator\");\n\nmalformed!(malformed_04, \"a >\", \"selector missing\");\n\nmalformed!(malformed_05, \"*a\", \"unexpected selector\");\n\nmalformed!(malformed_06, \"a*\", \"unexpected selector\");\n\nmalformed!(malformed_07, \"a > ,\", \"selector missing\");\n\nmalformed!(malformed_08, \"a > >\", \"unexpected combinator\");\n\nmalformed!(malformed_09, \"a > {\", \"selector missing\");\n\nmalformed!(malformed_10, \"a/**/b\", \"unexpected selector\");\n\nmalformed!(malformed_11, \"a < b\", \"invalid ident at 1:3\");\n\nmalformed!(malformed_12, \":lang()\", \"invalid language pseudo-class\");\n\nmalformed!(malformed_13, \":lang( )\", \"invalid language pseudo-class\");\n\nmalformed!(malformed_14, \"::first-child\", \"invalid ident at 1:2\");\n\nmalformed!(\n    malformed_15,\n    \"[olor:red\",\n    \"invalid or unsupported attribute selector\"\n);\n\nmalformed!(malformed_16, \"\", \"selector missing\");\n\nmalformed!(malformed_17, \" \", \"selector missing\");\n\nmalformed!(malformed_18, \"/**/\", \"selector missing\");\n\ntokenize!(comment_01, \"/**/a\", SelectorToken::TypeSelector(\"a\"));\n\ntokenize!(comment_02, \"/* */a\", SelectorToken::TypeSelector(\"a\"));\n\ntokenize!(\n    comment_03,\n    \"/* comment */a\",\n    SelectorToken::TypeSelector(\"a\")\n);\n\ntokenize!(comment_04, \"/**/ /**/a\", SelectorToken::TypeSelector(\"a\"));\n\ntokenize!(comment_05, \"/**/ a /**/\", SelectorToken::TypeSelector(\"a\"));\n\ntokenize!(\n    comment_06,\n    \"a /**/ b\",\n    SelectorToken::TypeSelector(\"a\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"b\")\n);\n\ntokenize!(\n    comment_08,\n    \"a /**/b\",\n    SelectorToken::TypeSelector(\"a\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"b\")\n);\n\ntokenize!(\n    comment_09,\n    \"a/**/ b\",\n    SelectorToken::TypeSelector(\"a\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"b\")\n);\n\ntokenize!(\n    comment_10,\n    \"a/**/ /**/b\",\n    SelectorToken::TypeSelector(\"a\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"b\")\n);\n\ntokenize!(\n    comment_11,\n    \"a /**/ /**/ b\",\n    SelectorToken::TypeSelector(\"a\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"b\")\n);\n\ntokenize!(\n    comment_12,\n    \"a /**//**/ b\",\n    SelectorToken::TypeSelector(\"a\"),\n    SelectorToken::DescendantCombinator,\n    SelectorToken::TypeSelector(\"b\")\n);\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "tests/specificity.rs",
      "sha256": "f3d2c6532238602d616073c321313013fc1965af8df79b8cf6d49a7ad1073378",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Specificity\n\nuse simplecss::*;\n\n#[test]\nfn spec_01() {\n    let selectors = Selector::parse(\"*\").unwrap();\n    assert_eq!(selectors.specificity(), [0, 0, 0]);\n}\n\n#[test]\nfn spec_02() {\n    let selectors = Selector::parse(\"li\").unwrap();\n    assert_eq!(selectors.specificity(), [0, 0, 1]);\n}\n\n#[test]\nfn spec_03() {\n    let selectors = Selector::parse(\"ul li\").unwrap();\n    assert_eq!(selectors.specificity(), [0, 0, 2]);\n}\n\n#[test]\nfn spec_04() {\n    let selectors = Selector::parse(\"ul ol + li\").unwrap();\n    assert_eq!(selectors.specificity(), [0, 0, 3]);\n}\n\n#[test]\nfn spec_05() {\n    let selectors = Selector::parse(\"h1 + *[rel=up]\").unwrap();\n    assert_eq!(selectors.specificity(), [0, 1, 1]);\n}\n\n#[test]\nfn spec_06() {\n    let selectors = Selector::parse(\"ul ol li.red\").unwrap();\n    assert_eq!(selectors.specificity(), [0, 1, 3]);\n}\n\n#[test]\nfn spec_07() {\n    let selectors = Selector::parse(\"li.red.level\").unwrap();\n    assert_eq!(selectors.specificity(), [0, 2, 1]);\n}\n\n#[test]\nfn spec_08() {\n    let selectors = Selector::parse(\"#x34y\").unwrap();\n    assert_eq!(selectors.specificity(), [1, 0, 0]);\n}\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "tests/stylesheet.rs",
      "sha256": "ebef9d5edef430fa44032e86a276b9f4d06a5eb3b25a47b7acb1e03a68218429",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Stylesheet\n\nuse simplecss::*;\n\n#[test]\nfn style_01() {\n    let style = StyleSheet::parse(\"\");\n    assert_eq!(style.to_string(), \"\");\n}\n\n#[test]\nfn style_02() {\n    let style = StyleSheet::parse(\"a {}\");\n    assert_eq!(style.to_string(), \"\");\n}\n\n#[test]\nfn style_03() {\n    let style = StyleSheet::parse(\"a { color:red }\");\n    assert_eq!(style.to_string(), \"a { color:red; }\");\n}\n\n#[test]\nfn style_04() {\n    let style = StyleSheet::parse(\"/**/\");\n    assert_eq!(style.to_string(), \"\");\n}\n\n#[test]\nfn style_05() {\n    let style = StyleSheet::parse(\"a { color:red } /**/\");\n    assert_eq!(style.to_string(), \"a { color:red; }\");\n}\n\n#[test]\nfn style_06() {\n    let style = StyleSheet::parse(\"a, b { color:red }\");\n    assert_eq!(style.to_string(), \"a { color:red; }\\nb { color:red; }\");\n}\n\n#[test]\nfn style_07() {\n    let style = StyleSheet::parse(\"a, { color:red }\");\n    assert_eq!(style.to_string(), \"a { color:red; }\");\n}\n\n#[test]\nfn style_08() {\n    let style = StyleSheet::parse(\"a,, { color:red }\");\n    assert_eq!(style.to_string(), \"a { color:red; }\");\n}\n\n#[test]\nfn style_09() {\n    let style = StyleSheet::parse(\"a,,b { color:red }\");\n    assert_eq!(style.to_string(), \"a { color:red; }\\nb { color:red; }\");\n}\n\n#[test]\nfn style_10() {\n    let style = StyleSheet::parse(\",a { color:red }\");\n    assert_eq!(style.to_string(), \"a { color:red; }\");\n}\n\n#[test]\nfn style_11() {\n    let style = StyleSheet::parse(\"@import \\\"subs.css\\\";\\na { color:red }\");\n    assert_eq!(style.to_string(), \"a { color:red; }\");\n}\n\n#[test]\nfn style_12() {\n    let style = StyleSheet::parse(\n        \"\\\n@media screen {\n    p:before { content: 'Hello'; }\n}\na { color:red }\",\n    );\n    assert_eq!(style.to_string(), \"a { color:red; }\");\n}\n\n#[test]\nfn style_13() {\n    let style = StyleSheet::parse(\"a > { color:red }\");\n    assert_eq!(style.to_string(), \"\");\n}\n\n#[test]\nfn style_14() {\n    let style = StyleSheet::parse(\"p { color:green; color }\");\n    assert_eq!(style.to_string(), \"p { color:green; }\");\n}\n\n#[test]\nfn style_15() {\n    let style = StyleSheet::parse(\"p { color; color:green }\");\n    assert_eq!(style.to_string(), \"\"); // TODO: should be 'p { color:green; }'\n}\n\n#[test]\nfn style_16() {\n    let style = StyleSheet::parse(\"p { color:green; color: }\");\n    assert_eq!(style.to_string(), \"p { color:green; }\");\n}\n\n#[test]\nfn style_17() {\n    let style = StyleSheet::parse(\"p { color:green; color:; color:red; }\");\n    assert_eq!(style.to_string(), \"p { color:green; }\");\n}\n\n#[test]\nfn style_18() {\n    let style = StyleSheet::parse(\"p { color:green; color{;color:maroon} }\");\n    assert_eq!(style.to_string(), \"p { color:green; }\");\n}\n\n#[test]\nfn style_19() {\n    let style = StyleSheet::parse(\"p { color{;color:maroon} color:green; }\");\n    assert_eq!(style.to_string(), \"\"); // TODO: should be 'p { color:green; }'\n}\n\n#[test]\nfn style_20() {\n    let style = StyleSheet::parse(\n        \"\\\n        h1 { color: green }\n        h2 & h3 { color: red }\n        h4 { color: black }\n    \",\n    );\n    assert_eq!(\n        style.to_string(),\n        \"h1 { color:green; }\\nh4 { color:black; }\"\n    );\n}\n\n#[test]\nfn style_21() {\n    let style = StyleSheet::parse(\":le>*\");\n    assert_eq!(style.to_string(), \"\");\n}\n"
    },
    {
      "package": "simplecss@0.2.2",
      "sourcePath": "tests/warnings.rs",
      "sha256": "b93bb7e1ac75575aeb19302de8570738576e7c4aae8b4ef9a8b6d0c5b9330a6f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2019 the SimpleCSS Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! Warnings\n\nfn run_process(input: &str) -> String {\n    use std::io::Write;\n    use std::process::Stdio;\n\n    let mut child = std::process::Command::new(\"target/debug/examples/parse\")\n        .arg(\"-\")\n        .stdin(Stdio::piped())\n        .stdout(Stdio::null())\n        .stderr(Stdio::piped())\n        .spawn()\n        .unwrap();\n\n    child\n        .stdin\n        .as_mut()\n        .unwrap()\n        .write_all(input.as_bytes())\n        .unwrap();\n\n    let output = child.wait_with_output().expect(\"Failed to read stdout\");\n    String::from_utf8(output.stderr).unwrap()\n}\n\n#[test]\nfn style_01() {\n    assert_eq!(\n        run_process(\"> {}\"),\n        \"WARN: Selector parsing failed cause unexpected combinator.\\n\"\n    );\n}\n\n#[test]\nfn style_02() {\n    assert_eq!(\n        run_process(\"@import 'subs.css';\"),\n        \"WARN: The @import rule is not supported. Skipped.\\n\"\n    );\n}\n"
    },
    {
      "package": "siphasher@0.3.11",
      "sourcePath": "src/sip.rs",
      "sha256": "b2f0067642100232f78f046167299972ec4e64bf8b9a48d5283ab9e0101e12da",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! An implementation of SipHash.\n\nuse core::cmp;\nuse core::hash;\nuse core::hash::Hasher as _;\nuse core::marker::PhantomData;\nuse core::mem;\nuse core::ptr;\nuse core::u64;\n\n/// An implementation of SipHash 1-3.\n///\n/// See: <https://www.aumasson.jp/siphash/siphash.pdf>\n#[derive(Debug, Clone, Copy, Default)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct SipHasher13 {\n    hasher: Hasher<Sip13Rounds>,\n}\n\n/// An implementation of SipHash 2-4.\n///\n/// See: <https://www.aumasson.jp/siphash/siphash.pdf>\n#[derive(Debug, Clone, Copy, Default)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct SipHasher24 {\n    hasher: Hasher<Sip24Rounds>,\n}\n\n/// An implementation of SipHash 2-4.\n///\n/// See: <https://www.aumasson.jp/siphash/siphash.pdf>\n///\n/// SipHash is a general-purpose hashing function: it runs at a good\n/// speed (competitive with Spooky and City) and permits strong _keyed_\n/// hashing. This lets you key your hashtables from a strong RNG, such as\n/// [`rand::os::OsRng`](https://doc.rust-lang.org/rand/rand/os/struct.OsRng.html).\n///\n/// Although the SipHash algorithm is considered to be generally strong,\n/// it is not intended for cryptographic purposes. As such, all\n/// cryptographic uses of this implementation are _strongly discouraged_.\n#[derive(Debug, Clone, Copy, Default)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct SipHasher(SipHasher24);\n\n#[derive(Debug, Clone, Copy)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\nstruct Hasher<S: Sip> {\n    k0: u64,\n    k1: u64,\n    length: usize, // how many bytes we've processed\n    state: State,  // hash State\n    tail: u64,     // unprocessed bytes le\n    ntail: usize,  // how many bytes in tail are valid\n    _marker: PhantomData<S>,\n}\n\n#[derive(Debug, Clone, Copy)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\nstruct State {\n    // v0, v2 and v1, v3 show up in pairs in the algorithm,\n    // and simd implementations of SipHash will use vectors\n    // of v02 and v13. By placing them in this order in the struct,\n    // the compiler can pick up on just a few simd optimizations by itself.\n    v0: u64,\n    v2: u64,\n    v1: u64,\n    v3: u64,\n}\n\nmacro_rules! compress {\n    ($state:expr) => {{\n        compress!($state.v0, $state.v1, $state.v2, $state.v3)\n    }};\n    ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{\n        $v0 = $v0.wrapping_add($v1);\n        $v1 = $v1.rotate_left(13);\n        $v1 ^= $v0;\n        $v0 = $v0.rotate_left(32);\n        $v2 = $v2.wrapping_add($v3);\n        $v3 = $v3.rotate_left(16);\n        $v3 ^= $v2;\n        $v0 = $v0.wrapping_add($v3);\n        $v3 = $v3.rotate_left(21);\n        $v3 ^= $v0;\n        $v2 = $v2.wrapping_add($v1);\n        $v1 = $v1.rotate_left(17);\n        $v1 ^= $v2;\n        $v2 = $v2.rotate_left(32);\n    }};\n}\n\n/// Loads an integer of the desired type from a byte stream, in LE order. Uses\n/// `copy_nonoverlapping` to let the compiler generate the most efficient way\n/// to load it from a possibly unaligned address.\n///\n/// Unsafe because: unchecked indexing at `i..i+size_of(int_ty)`\nmacro_rules! load_int_le {\n    ($buf:expr, $i:expr, $int_ty:ident) => {{\n        debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());\n        let mut data = 0 as $int_ty;\n        ptr::copy_nonoverlapping(\n            $buf.as_ptr().add($i),\n            &mut data as *mut _ as *mut u8,\n            mem::size_of::<$int_ty>(),\n        );\n        data.to_le()\n    }};\n}\n\n/// Loads a u64 using up to 7 bytes of a byte slice. It looks clumsy but the\n/// `copy_nonoverlapping` calls that occur (via `load_int_le!`) all have fixed\n/// sizes and avoid calling `memcpy`, which is good for speed.\n///\n/// Unsafe because: unchecked indexing at start..start+len\n#[inline]\nunsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {\n    debug_assert!(len < 8);\n    let mut i = 0; // current byte index (from LSB) in the output u64\n    let mut out = 0;\n    if i + 3 < len {\n        out = load_int_le!(buf, start + i, u32) as u64;\n        i += 4;\n    }\n    if i + 1 < len {\n        out |= (load_int_le!(buf, start + i, u16) as u64) << (i * 8);\n        i += 2\n    }\n    if i < len {\n        out |= (*buf.get_unchecked(start + i) as u64) << (i * 8);\n        i += 1;\n    }\n    debug_assert_eq!(i, len);\n    out\n}\n\nimpl SipHasher {\n    /// Creates a new `SipHasher` with the two initial keys set to 0.\n    #[inline]\n    pub fn new() -> SipHasher {\n        SipHasher::new_with_keys(0, 0)\n    }\n\n    /// Creates a `SipHasher` that is keyed off the provided keys.\n    #[inline]\n    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {\n        SipHasher(SipHasher24::new_with_keys(key0, key1))\n    }\n\n    /// Creates a `SipHasher` from a 16 byte key.\n    pub fn new_with_key(key: &[u8; 16]) -> SipHasher {\n        let mut b0 = [0u8; 8];\n        let mut b1 = [0u8; 8];\n        b0.copy_from_slice(&key[0..8]);\n        b1.copy_from_slice(&key[8..16]);\n        let key0 = u64::from_le_bytes(b0);\n        let key1 = u64::from_le_bytes(b1);\n        Self::new_with_keys(key0, key1)\n    }\n\n    /// Get the keys used by this hasher\n    pub fn keys(&self) -> (u64, u64) {\n        (self.0.hasher.k0, self.0.hasher.k1)\n    }\n\n    /// Get the key used by this hasher as a 16 byte vector\n    pub fn key(&self) -> [u8; 16] {\n        let mut bytes = [0u8; 16];\n        bytes[0..8].copy_from_slice(&self.0.hasher.k0.to_le_bytes());\n        bytes[8..16].copy_from_slice(&self.0.hasher.k1.to_le_bytes());\n        bytes\n    }\n\n    /// Hash a byte array - This is the easiest and safest way to use SipHash.\n    #[inline]\n    pub fn hash(&self, bytes: &[u8]) -> u64 {\n        let mut hasher = self.0.hasher;\n        hasher.write(bytes);\n        hasher.finish()\n    }\n}\n\nimpl SipHasher13 {\n    /// Creates a new `SipHasher13` with the two initial keys set to 0.\n    #[inline]\n    pub fn new() -> SipHasher13 {\n        SipHasher13::new_with_keys(0, 0)\n    }\n\n    /// Creates a `SipHasher13` that is keyed off the provided keys.\n    #[inline]\n    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {\n        SipHasher13 {\n            hasher: Hasher::new_with_keys(key0, key1),\n        }\n    }\n\n    /// Creates a `SipHasher13` from a 16 byte key.\n    pub fn new_with_key(key: &[u8; 16]) -> SipHasher13 {\n        let mut b0 = [0u8; 8];\n        let mut b1 = [0u8; 8];\n        b0.copy_from_slice(&key[0..8]);\n        b1.copy_from_slice(&key[8..16]);\n        let key0 = u64::from_le_bytes(b0);\n        let key1 = u64::from_le_bytes(b1);\n        Self::new_with_keys(key0, key1)\n    }\n\n    /// Get the keys used by this hasher\n    pub fn keys(&self) -> (u64, u64) {\n        (self.hasher.k0, self.hasher.k1)\n    }\n\n    /// Get the key used by this hasher as a 16 byte vector\n    pub fn key(&self) -> [u8; 16] {\n        let mut bytes = [0u8; 16];\n        bytes[0..8].copy_from_slice(&self.hasher.k0.to_le_bytes());\n        bytes[8..16].copy_from_slice(&self.hasher.k1.to_le_bytes());\n        bytes\n    }\n\n    /// Hash a byte array - This is the easiest and safest way to use SipHash.\n    #[inline]\n    pub fn hash(&self, bytes: &[u8]) -> u64 {\n        let mut hasher = self.hasher;\n        hasher.write(bytes);\n        hasher.finish()\n    }\n}\n\nimpl SipHasher24 {\n    /// Creates a new `SipHasher24` with the two initial keys set to 0.\n    #[inline]\n    pub fn new() -> SipHasher24 {\n        SipHasher24::new_with_keys(0, 0)\n    }\n\n    /// Creates a `SipHasher24` that is keyed off the provided keys.\n    #[inline]\n    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher24 {\n        SipHasher24 {\n            hasher: Hasher::new_with_keys(key0, key1),\n        }\n    }\n\n    /// Creates a `SipHasher24` from a 16 byte key.\n    pub fn new_with_key(key: &[u8; 16]) -> SipHasher24 {\n        let mut b0 = [0u8; 8];\n        let mut b1 = [0u8; 8];\n        b0.copy_from_slice(&key[0..8]);\n        b1.copy_from_slice(&key[8..16]);\n        let key0 = u64::from_le_bytes(b0);\n        let key1 = u64::from_le_bytes(b1);\n        Self::new_with_keys(key0, key1)\n    }\n\n    /// Get the keys used by this hasher\n    pub fn keys(&self) -> (u64, u64) {\n        (self.hasher.k0, self.hasher.k1)\n    }\n\n    /// Get the key used by this hasher as a 16 byte vector\n    pub fn key(&self) -> [u8; 16] {\n        let mut bytes = [0u8; 16];\n        bytes[0..8].copy_from_slice(&self.hasher.k0.to_le_bytes());\n        bytes[8..16].copy_from_slice(&self.hasher.k1.to_le_bytes());\n        bytes\n    }\n\n    /// Hash a byte array - This is the easiest and safest way to use SipHash.\n    #[inline]\n    pub fn hash(&self, bytes: &[u8]) -> u64 {\n        let mut hasher = self.hasher;\n        hasher.write(bytes);\n        hasher.finish()\n    }\n}\n\nimpl<S: Sip> Hasher<S> {\n    #[inline]\n    fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {\n        let mut state = Hasher {\n            k0: key0,\n            k1: key1,\n            length: 0,\n            state: State {\n                v0: 0,\n                v1: 0,\n                v2: 0,\n                v3: 0,\n            },\n            tail: 0,\n            ntail: 0,\n            _marker: PhantomData,\n        };\n        state.reset();\n        state\n    }\n\n    #[inline]\n    fn reset(&mut self) {\n        self.length = 0;\n        self.state.v0 = self.k0 ^ 0x736f6d6570736575;\n        self.state.v1 = self.k1 ^ 0x646f72616e646f6d;\n        self.state.v2 = self.k0 ^ 0x6c7967656e657261;\n        self.state.v3 = self.k1 ^ 0x7465646279746573;\n        self.ntail = 0;\n    }\n\n    // A specialized write function for values with size <= 8.\n    //\n    // The hashing of multi-byte integers depends on endianness. E.g.:\n    // - little-endian: `write_u32(0xDDCCBBAA)` == `write([0xAA, 0xBB, 0xCC, 0xDD])`\n    // - big-endian:    `write_u32(0xDDCCBBAA)` == `write([0xDD, 0xCC, 0xBB, 0xAA])`\n    //\n    // This function does the right thing for little-endian hardware. On\n    // big-endian hardware `x` must be byte-swapped first to give the right\n    // behaviour. After any byte-swapping, the input must be zero-extended to\n    // 64-bits. The caller is responsible for the byte-swapping and\n    // zero-extension.\n    #[inline]\n    fn short_write<T>(&mut self, _x: T, x: u64) {\n        let size = mem::size_of::<T>();\n        self.length += size;\n\n        // The original number must be zero-extended, not sign-extended.\n        debug_assert!(if size < 8 { x >> (8 * size) == 0 } else { true });\n\n        // The number of bytes needed to fill `self.tail`.\n        let needed = 8 - self.ntail;\n\n        self.tail |= x << (8 * self.ntail);\n        if size < needed {\n            self.ntail += size;\n            return;\n        }\n\n        // `self.tail` is full, process it.\n        self.state.v3 ^= self.tail;\n        S::c_rounds(&mut self.state);\n        self.state.v0 ^= self.tail;\n\n        self.ntail = size - needed;\n        self.tail = if needed < 8 { x >> (8 * needed) } else { 0 };\n    }\n}\n\nimpl hash::Hasher for SipHasher {\n    #[inline]\n    fn write(&mut self, msg: &[u8]) {\n        self.0.write(msg)\n    }\n\n    #[inline]\n    fn finish(&self) -> u64 {\n        self.0.finish()\n    }\n\n    #[inline]\n    fn write_usize(&mut self, i: usize) {\n        self.0.write_usize(i);\n    }\n\n    #[inline]\n    fn write_u8(&mut self, i: u8) {\n        self.0.write_u8(i);\n    }\n\n    #[inline]\n    fn write_u16(&mut self, i: u16) {\n        self.0.write_u16(i);\n    }\n\n    #[inline]\n    fn write_u32(&mut self, i: u32) {\n        self.0.write_u32(i);\n    }\n\n    #[inline]\n    fn write_u64(&mut self, i: u64) {\n        self.0.write_u64(i);\n    }\n}\n\nimpl hash::Hasher for SipHasher13 {\n    #[inline]\n    fn write(&mut self, msg: &[u8]) {\n        self.hasher.write(msg)\n    }\n\n    #[inline]\n    fn finish(&self) -> u64 {\n        self.hasher.finish()\n    }\n\n    #[inline]\n    fn write_usize(&mut self, i: usize) {\n        self.hasher.write_usize(i);\n    }\n\n    #[inline]\n    fn write_u8(&mut self, i: u8) {\n        self.hasher.write_u8(i);\n    }\n\n    #[inline]\n    fn write_u16(&mut self, i: u16) {\n        self.hasher.write_u16(i);\n    }\n\n    #[inline]\n    fn write_u32(&mut self, i: u32) {\n        self.hasher.write_u32(i);\n    }\n\n    #[inline]\n    fn write_u64(&mut self, i: u64) {\n        self.hasher.write_u64(i);\n    }\n}\n\nimpl hash::Hasher for SipHasher24 {\n    #[inline]\n    fn write(&mut self, msg: &[u8]) {\n        self.hasher.write(msg)\n    }\n\n    #[inline]\n    fn finish(&self) -> u64 {\n        self.hasher.finish()\n    }\n\n    #[inline]\n    fn write_usize(&mut self, i: usize) {\n        self.hasher.write_usize(i);\n    }\n\n    #[inline]\n    fn write_u8(&mut self, i: u8) {\n        self.hasher.write_u8(i);\n    }\n\n    #[inline]\n    fn write_u16(&mut self, i: u16) {\n        self.hasher.write_u16(i);\n    }\n\n    #[inline]\n    fn write_u32(&mut self, i: u32) {\n        self.hasher.write_u32(i);\n    }\n\n    #[inline]\n    fn write_u64(&mut self, i: u64) {\n        self.hasher.write_u64(i);\n    }\n}\n\nimpl<S: Sip> hash::Hasher for Hasher<S> {\n    #[inline]\n    fn write_usize(&mut self, i: usize) {\n        self.short_write(i, i.to_le() as u64);\n    }\n\n    #[inline]\n    fn write_u8(&mut self, i: u8) {\n        self.short_write(i, i as u64);\n    }\n\n    #[inline]\n    fn write_u32(&mut self, i: u32) {\n        self.short_write(i, i.to_le() as u64);\n    }\n\n    #[inline]\n    fn write_u64(&mut self, i: u64) {\n        self.short_write(i, i.to_le());\n    }\n\n    #[inline]\n    fn write(&mut self, msg: &[u8]) {\n        let length = msg.len();\n        self.length += length;\n\n        let mut needed = 0;\n\n        if self.ntail != 0 {\n            needed = 8 - self.ntail;\n            self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail);\n            if length < needed {\n                self.ntail += length;\n                return;\n            } else {\n                self.state.v3 ^= self.tail;\n                S::c_rounds(&mut self.state);\n                self.state.v0 ^= self.tail;\n                self.ntail = 0;\n            }\n        }\n\n        // Buffered tail is now flushed, process new input.\n        let len = length - needed;\n        let left = len & 0x7;\n\n        let mut i = needed;\n        while i < len - left {\n            let mi = unsafe { load_int_le!(msg, i, u64) };\n\n            self.state.v3 ^= mi;\n            S::c_rounds(&mut self.state);\n            self.state.v0 ^= mi;\n\n            i += 8;\n        }\n\n        self.tail = unsafe { u8to64_le(msg, i, left) };\n        self.ntail = left;\n    }\n\n    #[inline]\n    fn finish(&self) -> u64 {\n        let mut state = self.state;\n\n        let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;\n\n        state.v3 ^= b;\n        S::c_rounds(&mut state);\n        state.v0 ^= b;\n\n        state.v2 ^= 0xff;\n        S::d_rounds(&mut state);\n\n        state.v0 ^ state.v1 ^ state.v2 ^ state.v3\n    }\n}\n\nimpl<S: Sip> Default for Hasher<S> {\n    /// Creates a `Hasher<S>` with the two initial keys set to 0.\n    #[inline]\n    fn default() -> Hasher<S> {\n        Hasher::new_with_keys(0, 0)\n    }\n}\n\n#[doc(hidden)]\ntrait Sip {\n    fn c_rounds(_: &mut State);\n    fn d_rounds(_: &mut State);\n}\n\n#[derive(Debug, Clone, Copy, Default)]\nstruct Sip13Rounds;\n\nimpl Sip for Sip13Rounds {\n    #[inline]\n    fn c_rounds(state: &mut State) {\n        compress!(state);\n    }\n\n    #[inline]\n    fn d_rounds(state: &mut State) {\n        compress!(state);\n        compress!(state);\n        compress!(state);\n    }\n}\n\n#[derive(Debug, Clone, Copy, Default)]\nstruct Sip24Rounds;\n\nimpl Sip for Sip24Rounds {\n    #[inline]\n    fn c_rounds(state: &mut State) {\n        compress!(state);\n        compress!(state);\n    }\n\n    #[inline]\n    fn d_rounds(state: &mut State) {\n        compress!(state);\n        compress!(state);\n        compress!(state);\n        compress!(state);\n    }\n}\n"
    },
    {
      "package": "siphasher@0.3.11",
      "sourcePath": "src/sip128.rs",
      "sha256": "eccfff86293b02af3e22a087592afcea08995f54c551e9fe0ec087e13d9e6eea",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! An implementation of SipHash with a 128-bit output.\n\nuse core::cmp;\nuse core::hash;\nuse core::hash::Hasher as _;\nuse core::marker::PhantomData;\nuse core::mem;\nuse core::ptr;\nuse core::u64;\n\n/// A 128-bit (2x64) hash output\n#[derive(Debug, Clone, Copy, Default)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct Hash128 {\n    pub h1: u64,\n    pub h2: u64,\n}\n\nimpl From<u128> for Hash128 {\n    fn from(v: u128) -> Self {\n        Hash128 {\n            h1: v as u64,\n            h2: (v >> 64) as u64,\n        }\n    }\n}\n\nimpl From<Hash128> for u128 {\n    fn from(h: Hash128) -> u128 {\n        (h.h1 as u128) | ((h.h2 as u128) << 64)\n    }\n}\n\n/// An implementation of SipHash128 1-3.\n#[derive(Debug, Clone, Copy, Default)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct SipHasher13 {\n    hasher: Hasher<Sip13Rounds>,\n}\n\n/// An implementation of SipHash128 2-4.\n#[derive(Debug, Clone, Copy, Default)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\npub struct SipHasher24 {\n    hasher: Hasher<Sip24Rounds>,\n}\n\n/// An implementation of SipHash128 2-4.\n///\n/// SipHash is a general-purpose hashing function: it runs at a good\n/// speed (competitive with Spooky and City) and permits strong _keyed_\n/// hashing. This lets you key your hashtables from a strong RNG, such as\n/// [`rand::os::OsRng`](https://doc.rust-lang.org/rand/rand/os/struct.OsRng.html).\n///\n/// Although the SipHash algorithm is considered to be generally strong,\n/// it is not intended for cryptographic purposes. As such, all\n/// cryptographic uses of this implementation are _strongly discouraged_.\n#[derive(Debug, Clone, Copy, Default)]\npub struct SipHasher(SipHasher24);\n\n#[derive(Debug, Copy)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\nstruct Hasher<S: Sip> {\n    k0: u64,\n    k1: u64,\n    length: usize, // how many bytes we've processed\n    state: State,  // hash State\n    tail: u64,     // unprocessed bytes le\n    ntail: usize,  // how many bytes in tail are valid\n    _marker: PhantomData<S>,\n}\n\n#[derive(Debug, Clone, Copy)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\nstruct State {\n    // v0, v2 and v1, v3 show up in pairs in the algorithm,\n    // and simd implementations of SipHash will use vectors\n    // of v02 and v13. By placing them in this order in the struct,\n    // the compiler can pick up on just a few simd optimizations by itself.\n    v0: u64,\n    v2: u64,\n    v1: u64,\n    v3: u64,\n}\n\nmacro_rules! compress {\n    ($state:expr) => {{\n        compress!($state.v0, $state.v1, $state.v2, $state.v3)\n    }};\n    ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{\n        $v0 = $v0.wrapping_add($v1);\n        $v1 = $v1.rotate_left(13);\n        $v1 ^= $v0;\n        $v0 = $v0.rotate_left(32);\n        $v2 = $v2.wrapping_add($v3);\n        $v3 = $v3.rotate_left(16);\n        $v3 ^= $v2;\n        $v0 = $v0.wrapping_add($v3);\n        $v3 = $v3.rotate_left(21);\n        $v3 ^= $v0;\n        $v2 = $v2.wrapping_add($v1);\n        $v1 = $v1.rotate_left(17);\n        $v1 ^= $v2;\n        $v2 = $v2.rotate_left(32);\n    }};\n}\n\n/// Loads an integer of the desired type from a byte stream, in LE order. Uses\n/// `copy_nonoverlapping` to let the compiler generate the most efficient way\n/// to load it from a possibly unaligned address.\n///\n/// Unsafe because: unchecked indexing at `i..i+size_of(int_ty)`\nmacro_rules! load_int_le {\n    ($buf:expr, $i:expr, $int_ty:ident) => {{\n        debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());\n        let mut data = 0 as $int_ty;\n        ptr::copy_nonoverlapping(\n            $buf.as_ptr().add($i),\n            &mut data as *mut _ as *mut u8,\n            mem::size_of::<$int_ty>(),\n        );\n        data.to_le()\n    }};\n}\n\n/// Loads a u64 using up to 7 bytes of a byte slice. It looks clumsy but the\n/// `copy_nonoverlapping` calls that occur (via `load_int_le!`) all have fixed\n/// sizes and avoid calling `memcpy`, which is good for speed.\n///\n/// Unsafe because: unchecked indexing at start..start+len\n#[inline]\nunsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {\n    debug_assert!(len < 8);\n    let mut i = 0; // current byte index (from LSB) in the output u64\n    let mut out = 0;\n    if i + 3 < len {\n        out = load_int_le!(buf, start + i, u32) as u64;\n        i += 4;\n    }\n    if i + 1 < len {\n        out |= (load_int_le!(buf, start + i, u16) as u64) << (i * 8);\n        i += 2\n    }\n    if i < len {\n        out |= (*buf.get_unchecked(start + i) as u64) << (i * 8);\n        i += 1;\n    }\n    debug_assert_eq!(i, len);\n    out\n}\n\npub trait Hasher128 {\n    /// Return a 128-bit hash\n    fn finish128(&self) -> Hash128;\n}\n\nimpl SipHasher {\n    /// Creates a new `SipHasher` with the two initial keys set to 0.\n    #[inline]\n    pub fn new() -> SipHasher {\n        SipHasher::new_with_keys(0, 0)\n    }\n\n    /// Creates a `SipHasher` that is keyed off the provided keys.\n    #[inline]\n    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {\n        SipHasher(SipHasher24::new_with_keys(key0, key1))\n    }\n\n    /// Creates a `SipHasher` from a 16 byte key.\n    pub fn new_with_key(key: &[u8; 16]) -> SipHasher {\n        let mut b0 = [0u8; 8];\n        let mut b1 = [0u8; 8];\n        b0.copy_from_slice(&key[0..8]);\n        b1.copy_from_slice(&key[8..16]);\n        let key0 = u64::from_le_bytes(b0);\n        let key1 = u64::from_le_bytes(b1);\n        Self::new_with_keys(key0, key1)\n    }\n\n    /// Get the keys used by this hasher\n    pub fn keys(&self) -> (u64, u64) {\n        (self.0.hasher.k0, self.0.hasher.k1)\n    }\n\n    /// Get the key used by this hasher as a 16 byte vector\n    pub fn key(&self) -> [u8; 16] {\n        let mut bytes = [0u8; 16];\n        bytes[0..8].copy_from_slice(&self.0.hasher.k0.to_le_bytes());\n        bytes[8..16].copy_from_slice(&self.0.hasher.k1.to_le_bytes());\n        bytes\n    }\n\n    /// Hash a byte array - This is the easiest and safest way to use SipHash.\n    #[inline]\n    pub fn hash(&self, bytes: &[u8]) -> Hash128 {\n        let mut hasher = self.0.hasher;\n        hasher.write(bytes);\n        hasher.finish128()\n    }\n}\n\nimpl Hasher128 for SipHasher {\n    /// Return a 128-bit hash\n    #[inline]\n    fn finish128(&self) -> Hash128 {\n        self.0.finish128()\n    }\n}\n\nimpl SipHasher13 {\n    /// Creates a new `SipHasher13` with the two initial keys set to 0.\n    #[inline]\n    pub fn new() -> SipHasher13 {\n        SipHasher13::new_with_keys(0, 0)\n    }\n\n    /// Creates a `SipHasher13` that is keyed off the provided keys.\n    #[inline]\n    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {\n        SipHasher13 {\n            hasher: Hasher::new_with_keys(key0, key1),\n        }\n    }\n\n    /// Creates a `SipHasher13` from a 16 byte key.\n    pub fn new_with_key(key: &[u8; 16]) -> SipHasher13 {\n        let mut b0 = [0u8; 8];\n        let mut b1 = [0u8; 8];\n        b0.copy_from_slice(&key[0..8]);\n        b1.copy_from_slice(&key[8..16]);\n        let key0 = u64::from_le_bytes(b0);\n        let key1 = u64::from_le_bytes(b1);\n        Self::new_with_keys(key0, key1)\n    }\n\n    /// Get the keys used by this hasher\n    pub fn keys(&self) -> (u64, u64) {\n        (self.hasher.k0, self.hasher.k1)\n    }\n\n    /// Get the key used by this hasher as a 16 byte vector\n    pub fn key(&self) -> [u8; 16] {\n        let mut bytes = [0u8; 16];\n        bytes[0..8].copy_from_slice(&self.hasher.k0.to_le_bytes());\n        bytes[8..16].copy_from_slice(&self.hasher.k1.to_le_bytes());\n        bytes\n    }\n\n    /// Hash a byte array - This is the easiest and safest way to use SipHash.\n    #[inline]\n    pub fn hash(&self, bytes: &[u8]) -> Hash128 {\n        let mut hasher = self.hasher;\n        hasher.write(bytes);\n        hasher.finish128()\n    }\n}\n\nimpl Hasher128 for SipHasher13 {\n    /// Return a 128-bit hash\n    #[inline]\n    fn finish128(&self) -> Hash128 {\n        self.hasher.finish128()\n    }\n}\n\nimpl SipHasher24 {\n    /// Creates a new `SipHasher24` with the two initial keys set to 0.\n    #[inline]\n    pub fn new() -> SipHasher24 {\n        SipHasher24::new_with_keys(0, 0)\n    }\n\n    /// Creates a `SipHasher24` that is keyed off the provided keys.\n    #[inline]\n    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher24 {\n        SipHasher24 {\n            hasher: Hasher::new_with_keys(key0, key1),\n        }\n    }\n\n    /// Creates a `SipHasher24` from a 16 byte key.\n    pub fn new_with_key(key: &[u8; 16]) -> SipHasher24 {\n        let mut b0 = [0u8; 8];\n        let mut b1 = [0u8; 8];\n        b0.copy_from_slice(&key[0..8]);\n        b1.copy_from_slice(&key[8..16]);\n        let key0 = u64::from_le_bytes(b0);\n        let key1 = u64::from_le_bytes(b1);\n        Self::new_with_keys(key0, key1)\n    }\n\n    /// Get the keys used by this hasher\n    pub fn keys(&self) -> (u64, u64) {\n        (self.hasher.k0, self.hasher.k1)\n    }\n\n    /// Get the key used by this hasher as a 16 byte vector\n    pub fn key(&self) -> [u8; 16] {\n        let mut bytes = [0u8; 16];\n        bytes[0..8].copy_from_slice(&self.hasher.k0.to_le_bytes());\n        bytes[8..16].copy_from_slice(&self.hasher.k1.to_le_bytes());\n        bytes\n    }\n\n    /// Hash a byte array - This is the easiest and safest way to use SipHash.\n    #[inline]\n    pub fn hash(&self, bytes: &[u8]) -> Hash128 {\n        let mut hasher = self.hasher;\n        hasher.write(bytes);\n        hasher.finish128()\n    }\n}\n\nimpl Hasher128 for SipHasher24 {\n    /// Return a 128-bit hash\n    #[inline]\n    fn finish128(&self) -> Hash128 {\n        self.hasher.finish128()\n    }\n}\n\nimpl<S: Sip> Hasher<S> {\n    #[inline]\n    fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {\n        let mut state = Hasher {\n            k0: key0,\n            k1: key1,\n            length: 0,\n            state: State {\n                v0: 0,\n                v1: 0xee,\n                v2: 0,\n                v3: 0,\n            },\n            tail: 0,\n            ntail: 0,\n            _marker: PhantomData,\n        };\n        state.reset();\n        state\n    }\n\n    #[inline]\n    fn reset(&mut self) {\n        self.length = 0;\n        self.state.v0 = self.k0 ^ 0x736f6d6570736575;\n        self.state.v1 = self.k1 ^ 0x646f72616e646f83;\n        self.state.v2 = self.k0 ^ 0x6c7967656e657261;\n        self.state.v3 = self.k1 ^ 0x7465646279746573;\n        self.ntail = 0;\n    }\n\n    // A specialized write function for values with size <= 8.\n    //\n    // The hashing of multi-byte integers depends on endianness. E.g.:\n    // - little-endian: `write_u32(0xDDCCBBAA)` == `write([0xAA, 0xBB, 0xCC, 0xDD])`\n    // - big-endian:    `write_u32(0xDDCCBBAA)` == `write([0xDD, 0xCC, 0xBB, 0xAA])`\n    //\n    // This function does the right thing for little-endian hardware. On\n    // big-endian hardware `x` must be byte-swapped first to give the right\n    // behaviour. After any byte-swapping, the input must be zero-extended to\n    // 64-bits. The caller is responsible for the byte-swapping and\n    // zero-extension.\n    #[inline]\n    fn short_write<T>(&mut self, _x: T, x: u64) {\n        let size = mem::size_of::<T>();\n        self.length += size;\n\n        // The original number must be zero-extended, not sign-extended.\n        debug_assert!(if size < 8 { x >> (8 * size) == 0 } else { true });\n\n        // The number of bytes needed to fill `self.tail`.\n        let needed = 8 - self.ntail;\n\n        self.tail |= x << (8 * self.ntail);\n        if size < needed {\n            self.ntail += size;\n            return;\n        }\n\n        // `self.tail` is full, process it.\n        self.state.v3 ^= self.tail;\n        S::c_rounds(&mut self.state);\n        self.state.v0 ^= self.tail;\n\n        self.ntail = size - needed;\n        self.tail = if needed < 8 { x >> (8 * needed) } else { 0 };\n    }\n}\n\nimpl<S: Sip> Hasher<S> {\n    #[inline]\n    pub fn finish128(&self) -> Hash128 {\n        let mut state = self.state;\n\n        let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;\n\n        state.v3 ^= b;\n        S::c_rounds(&mut state);\n        state.v0 ^= b;\n\n        state.v2 ^= 0xee;\n        S::d_rounds(&mut state);\n        let h1 = state.v0 ^ state.v1 ^ state.v2 ^ state.v3;\n\n        state.v1 ^= 0xdd;\n        S::d_rounds(&mut state);\n        let h2 = state.v0 ^ state.v1 ^ state.v2 ^ state.v3;\n\n        Hash128 { h1, h2 }\n    }\n}\n\nimpl hash::Hasher for SipHasher {\n    #[inline]\n    fn write(&mut self, msg: &[u8]) {\n        self.0.write(msg)\n    }\n\n    #[inline]\n    fn finish(&self) -> u64 {\n        self.0.finish()\n    }\n\n    #[inline]\n    fn write_usize(&mut self, i: usize) {\n        self.0.write_usize(i);\n    }\n\n    #[inline]\n    fn write_u8(&mut self, i: u8) {\n        self.0.write_u8(i);\n    }\n\n    #[inline]\n    fn write_u16(&mut self, i: u16) {\n        self.0.write_u16(i);\n    }\n\n    #[inline]\n    fn write_u32(&mut self, i: u32) {\n        self.0.write_u32(i);\n    }\n\n    #[inline]\n    fn write_u64(&mut self, i: u64) {\n        self.0.write_u64(i);\n    }\n}\n\nimpl hash::Hasher for SipHasher13 {\n    #[inline]\n    fn write(&mut self, msg: &[u8]) {\n        self.hasher.write(msg)\n    }\n\n    #[inline]\n    fn finish(&self) -> u64 {\n        self.hasher.finish()\n    }\n\n    #[inline]\n    fn write_usize(&mut self, i: usize) {\n        self.hasher.write_usize(i);\n    }\n\n    #[inline]\n    fn write_u8(&mut self, i: u8) {\n        self.hasher.write_u8(i);\n    }\n\n    #[inline]\n    fn write_u16(&mut self, i: u16) {\n        self.hasher.write_u16(i);\n    }\n\n    #[inline]\n    fn write_u32(&mut self, i: u32) {\n        self.hasher.write_u32(i);\n    }\n\n    #[inline]\n    fn write_u64(&mut self, i: u64) {\n        self.hasher.write_u64(i);\n    }\n}\n\nimpl hash::Hasher for SipHasher24 {\n    #[inline]\n    fn write(&mut self, msg: &[u8]) {\n        self.hasher.write(msg)\n    }\n\n    #[inline]\n    fn finish(&self) -> u64 {\n        self.hasher.finish()\n    }\n\n    #[inline]\n    fn write_usize(&mut self, i: usize) {\n        self.hasher.write_usize(i);\n    }\n\n    #[inline]\n    fn write_u8(&mut self, i: u8) {\n        self.hasher.write_u8(i);\n    }\n\n    #[inline]\n    fn write_u16(&mut self, i: u16) {\n        self.hasher.write_u16(i);\n    }\n\n    #[inline]\n    fn write_u32(&mut self, i: u32) {\n        self.hasher.write_u32(i);\n    }\n\n    #[inline]\n    fn write_u64(&mut self, i: u64) {\n        self.hasher.write_u64(i);\n    }\n}\n\nimpl<S: Sip> hash::Hasher for Hasher<S> {\n    #[inline]\n    fn write_usize(&mut self, i: usize) {\n        self.short_write(i, i.to_le() as u64);\n    }\n\n    #[inline]\n    fn write_u8(&mut self, i: u8) {\n        self.short_write(i, i as u64);\n    }\n\n    #[inline]\n    fn write_u32(&mut self, i: u32) {\n        self.short_write(i, i.to_le() as u64);\n    }\n\n    #[inline]\n    fn write_u64(&mut self, i: u64) {\n        self.short_write(i, i.to_le());\n    }\n\n    #[inline]\n    fn write(&mut self, msg: &[u8]) {\n        let length = msg.len();\n        self.length += length;\n\n        let mut needed = 0;\n\n        if self.ntail != 0 {\n            needed = 8 - self.ntail;\n            self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail);\n            if length < needed {\n                self.ntail += length;\n                return;\n            } else {\n                self.state.v3 ^= self.tail;\n                S::c_rounds(&mut self.state);\n                self.state.v0 ^= self.tail;\n                self.ntail = 0;\n            }\n        }\n\n        // Buffered tail is now flushed, process new input.\n        let len = length - needed;\n        let left = len & 0x7;\n\n        let mut i = needed;\n        while i < len - left {\n            let mi = unsafe { load_int_le!(msg, i, u64) };\n\n            self.state.v3 ^= mi;\n            S::c_rounds(&mut self.state);\n            self.state.v0 ^= mi;\n\n            i += 8;\n        }\n\n        self.tail = unsafe { u8to64_le(msg, i, left) };\n        self.ntail = left;\n    }\n\n    #[inline]\n    fn finish(&self) -> u64 {\n        self.finish128().h2\n    }\n}\n\nimpl<S: Sip> Clone for Hasher<S> {\n    #[inline]\n    fn clone(&self) -> Hasher<S> {\n        Hasher {\n            k0: self.k0,\n            k1: self.k1,\n            length: self.length,\n            state: self.state,\n            tail: self.tail,\n            ntail: self.ntail,\n            _marker: self._marker,\n        }\n    }\n}\n\nimpl<S: Sip> Default for Hasher<S> {\n    /// Creates a `Hasher<S>` with the two initial keys set to 0.\n    #[inline]\n    fn default() -> Hasher<S> {\n        Hasher::new_with_keys(0, 0)\n    }\n}\n\n#[doc(hidden)]\ntrait Sip {\n    fn c_rounds(_: &mut State);\n    fn d_rounds(_: &mut State);\n}\n\n#[derive(Debug, Clone, Copy, Default)]\nstruct Sip13Rounds;\n\nimpl Sip for Sip13Rounds {\n    #[inline]\n    fn c_rounds(state: &mut State) {\n        compress!(state);\n    }\n\n    #[inline]\n    fn d_rounds(state: &mut State) {\n        compress!(state);\n        compress!(state);\n        compress!(state);\n    }\n}\n\n#[derive(Debug, Clone, Copy, Default)]\nstruct Sip24Rounds;\n\nimpl Sip for Sip24Rounds {\n    #[inline]\n    fn c_rounds(state: &mut State) {\n        compress!(state);\n        compress!(state);\n    }\n\n    #[inline]\n    fn d_rounds(state: &mut State) {\n        compress!(state);\n        compress!(state);\n        compress!(state);\n        compress!(state);\n    }\n}\n\nimpl Hash128 {\n    /// Convert into a 16-bytes vector\n    pub fn as_bytes(&self) -> [u8; 16] {\n        let mut bytes = [0u8; 16];\n        let h1 = self.h1.to_le();\n        let h2 = self.h2.to_le();\n        unsafe {\n            ptr::copy_nonoverlapping(&h1 as *const _ as *const u8, bytes.as_mut_ptr(), 8);\n            ptr::copy_nonoverlapping(&h2 as *const _ as *const u8, bytes.as_mut_ptr().add(8), 8);\n        }\n        bytes\n    }\n\n    /// Convert into a `u128`\n    #[inline]\n    pub fn as_u128(&self) -> u128 {\n        let h1 = self.h1.to_le();\n        let h2 = self.h2.to_le();\n        h1 as u128 | ((h2 as u128) << 64)\n    }\n\n    /// Convert into `(u64, u64)`\n    #[inline]\n    pub fn as_u64(&self) -> (u64, u64) {\n        let h1 = self.h1.to_le();\n        let h2 = self.h2.to_le();\n        (h1, h2)\n    }\n}\n"
    },
    {
      "package": "siphasher@0.3.11",
      "sourcePath": "src/tests.rs",
      "sha256": "99c299d1951aee4c70cd01bea8baabc151a7b316904e5d31de847807a671eaf5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse std::hash::{Hash, Hasher};\n\nuse super::sip::{SipHasher, SipHasher13, SipHasher24};\n\n// Hash just the bytes of the slice, without length prefix\nstruct Bytes<'a>(&'a [u8]);\n\nimpl<'a> Hash for Bytes<'a> {\n    #[allow(unused_must_use)]\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let Bytes(v) = *self;\n        state.write(v);\n    }\n}\n\nmacro_rules! u8to64_le {\n    ($buf:expr, $i:expr) => {\n        $buf[0 + $i] as u64\n            | ($buf[1 + $i] as u64) << 8\n            | ($buf[2 + $i] as u64) << 16\n            | ($buf[3 + $i] as u64) << 24\n            | ($buf[4 + $i] as u64) << 32\n            | ($buf[5 + $i] as u64) << 40\n            | ($buf[6 + $i] as u64) << 48\n            | ($buf[7 + $i] as u64) << 56\n    };\n    ($buf:expr, $i:expr, $len:expr) => {{\n        let mut t = 0;\n        let mut out = 0;\n        while t < $len {\n            out |= ($buf[t + $i] as u64) << t * 8;\n            t += 1;\n        }\n        out\n    }};\n}\n\nfn hash_with<H: Hasher, T: Hash>(mut st: H, x: &T) -> u64 {\n    x.hash(&mut st);\n    st.finish()\n}\n\nfn hash<T: Hash>(x: &T) -> u64 {\n    hash_with(SipHasher::new(), x)\n}\n\n#[test]\n#[allow(unused_must_use)]\nfn test_siphash_1_3() {\n    let vecs: [[u8; 8]; 64] = [\n        [0xdc, 0xc4, 0x0f, 0x05, 0x58, 0x01, 0xac, 0xab],\n        [0x93, 0xca, 0x57, 0x7d, 0xf3, 0x9b, 0xf4, 0xc9],\n        [0x4d, 0xd4, 0xc7, 0x4d, 0x02, 0x9b, 0xcb, 0x82],\n        [0xfb, 0xf7, 0xdd, 0xe7, 0xb8, 0x0a, 0xf8, 0x8b],\n        [0x28, 0x83, 0xd3, 0x88, 0x60, 0x57, 0x75, 0xcf],\n        [0x67, 0x3b, 0x53, 0x49, 0x2f, 0xd5, 0xf9, 0xde],\n        [0xa7, 0x22, 0x9f, 0xc5, 0x50, 0x2b, 0x0d, 0xc5],\n        [0x40, 0x11, 0xb1, 0x9b, 0x98, 0x7d, 0x92, 0xd3],\n        [0x8e, 0x9a, 0x29, 0x8d, 0x11, 0x95, 0x90, 0x36],\n        [0xe4, 0x3d, 0x06, 0x6c, 0xb3, 0x8e, 0xa4, 0x25],\n        [0x7f, 0x09, 0xff, 0x92, 0xee, 0x85, 0xde, 0x79],\n        [0x52, 0xc3, 0x4d, 0xf9, 0xc1, 0x18, 0xc1, 0x70],\n        [0xa2, 0xd9, 0xb4, 0x57, 0xb1, 0x84, 0xa3, 0x78],\n        [0xa7, 0xff, 0x29, 0x12, 0x0c, 0x76, 0x6f, 0x30],\n        [0x34, 0x5d, 0xf9, 0xc0, 0x11, 0xa1, 0x5a, 0x60],\n        [0x56, 0x99, 0x51, 0x2a, 0x6d, 0xd8, 0x20, 0xd3],\n        [0x66, 0x8b, 0x90, 0x7d, 0x1a, 0xdd, 0x4f, 0xcc],\n        [0x0c, 0xd8, 0xdb, 0x63, 0x90, 0x68, 0xf2, 0x9c],\n        [0x3e, 0xe6, 0x73, 0xb4, 0x9c, 0x38, 0xfc, 0x8f],\n        [0x1c, 0x7d, 0x29, 0x8d, 0xe5, 0x9d, 0x1f, 0xf2],\n        [0x40, 0xe0, 0xcc, 0xa6, 0x46, 0x2f, 0xdc, 0xc0],\n        [0x44, 0xf8, 0x45, 0x2b, 0xfe, 0xab, 0x92, 0xb9],\n        [0x2e, 0x87, 0x20, 0xa3, 0x9b, 0x7b, 0xfe, 0x7f],\n        [0x23, 0xc1, 0xe6, 0xda, 0x7f, 0x0e, 0x5a, 0x52],\n        [0x8c, 0x9c, 0x34, 0x67, 0xb2, 0xae, 0x64, 0xf4],\n        [0x79, 0x09, 0x5b, 0x70, 0x28, 0x59, 0xcd, 0x45],\n        [0xa5, 0x13, 0x99, 0xca, 0xe3, 0x35, 0x3e, 0x3a],\n        [0x35, 0x3b, 0xde, 0x4a, 0x4e, 0xc7, 0x1d, 0xa9],\n        [0x0d, 0xd0, 0x6c, 0xef, 0x02, 0xed, 0x0b, 0xfb],\n        [0xf4, 0xe1, 0xb1, 0x4a, 0xb4, 0x3c, 0xd9, 0x88],\n        [0x63, 0xe6, 0xc5, 0x43, 0xd6, 0x11, 0x0f, 0x54],\n        [0xbc, 0xd1, 0x21, 0x8c, 0x1f, 0xdd, 0x70, 0x23],\n        [0x0d, 0xb6, 0xa7, 0x16, 0x6c, 0x7b, 0x15, 0x81],\n        [0xbf, 0xf9, 0x8f, 0x7a, 0xe5, 0xb9, 0x54, 0x4d],\n        [0x3e, 0x75, 0x2a, 0x1f, 0x78, 0x12, 0x9f, 0x75],\n        [0x91, 0x6b, 0x18, 0xbf, 0xbe, 0xa3, 0xa1, 0xce],\n        [0x06, 0x62, 0xa2, 0xad, 0xd3, 0x08, 0xf5, 0x2c],\n        [0x57, 0x30, 0xc3, 0xa3, 0x2d, 0x1c, 0x10, 0xb6],\n        [0xa1, 0x36, 0x3a, 0xae, 0x96, 0x74, 0xf4, 0xb3],\n        [0x92, 0x83, 0x10, 0x7b, 0x54, 0x57, 0x6b, 0x62],\n        [0x31, 0x15, 0xe4, 0x99, 0x32, 0x36, 0xd2, 0xc1],\n        [0x44, 0xd9, 0x1a, 0x3f, 0x92, 0xc1, 0x7c, 0x66],\n        [0x25, 0x88, 0x13, 0xc8, 0xfe, 0x4f, 0x70, 0x65],\n        [0xa6, 0x49, 0x89, 0xc2, 0xd1, 0x80, 0xf2, 0x24],\n        [0x6b, 0x87, 0xf8, 0xfa, 0xed, 0x1c, 0xca, 0xc2],\n        [0x96, 0x21, 0x04, 0x9f, 0xfc, 0x4b, 0x16, 0xc2],\n        [0x23, 0xd6, 0xb1, 0x68, 0x93, 0x9c, 0x6e, 0xa1],\n        [0xfd, 0x14, 0x51, 0x8b, 0x9c, 0x16, 0xfb, 0x49],\n        [0x46, 0x4c, 0x07, 0xdf, 0xf8, 0x43, 0x31, 0x9f],\n        [0xb3, 0x86, 0xcc, 0x12, 0x24, 0xaf, 0xfd, 0xc6],\n        [0x8f, 0x09, 0x52, 0x0a, 0xd1, 0x49, 0xaf, 0x7e],\n        [0x9a, 0x2f, 0x29, 0x9d, 0x55, 0x13, 0xf3, 0x1c],\n        [0x12, 0x1f, 0xf4, 0xa2, 0xdd, 0x30, 0x4a, 0xc4],\n        [0xd0, 0x1e, 0xa7, 0x43, 0x89, 0xe9, 0xfa, 0x36],\n        [0xe6, 0xbc, 0xf0, 0x73, 0x4c, 0xb3, 0x8f, 0x31],\n        [0x80, 0xe9, 0xa7, 0x70, 0x36, 0xbf, 0x7a, 0xa2],\n        [0x75, 0x6d, 0x3c, 0x24, 0xdb, 0xc0, 0xbc, 0xb4],\n        [0x13, 0x15, 0xb7, 0xfd, 0x52, 0xd8, 0xf8, 0x23],\n        [0x08, 0x8a, 0x7d, 0xa6, 0x4d, 0x5f, 0x03, 0x8f],\n        [0x48, 0xf1, 0xe8, 0xb7, 0xe5, 0xd0, 0x9c, 0xd8],\n        [0xee, 0x44, 0xa6, 0xf7, 0xbc, 0xe6, 0xf4, 0xf6],\n        [0xf2, 0x37, 0x18, 0x0f, 0xd8, 0x9a, 0xc5, 0xae],\n        [0xe0, 0x94, 0x66, 0x4b, 0x15, 0xf6, 0xb2, 0xc3],\n        [0xa8, 0xb3, 0xbb, 0xb7, 0x62, 0x90, 0x19, 0x9d],\n    ];\n\n    let k0 = 0x_07_06_05_04_03_02_01_00;\n    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;\n    let mut buf = Vec::new();\n    let mut t = 0;\n    let mut state_inc = SipHasher13::new_with_keys(k0, k1);\n\n    while t < 64 {\n        let vec = u8to64_le!(vecs[t], 0);\n        let out = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));\n        assert_eq!(vec, out);\n\n        let full = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));\n        let i = state_inc.finish();\n\n        assert_eq!(full, i);\n        assert_eq!(full, vec);\n\n        buf.push(t as u8);\n        Hasher::write(&mut state_inc, &[t as u8]);\n\n        t += 1;\n    }\n}\n\n#[test]\n#[allow(unused_must_use)]\nfn test_siphash_2_4() {\n    let vecs: [[u8; 8]; 64] = [\n        [0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72],\n        [0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74],\n        [0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d],\n        [0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85],\n        [0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf],\n        [0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18],\n        [0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb],\n        [0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab],\n        [0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93],\n        [0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e],\n        [0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a],\n        [0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4],\n        [0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75],\n        [0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14],\n        [0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7],\n        [0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1],\n        [0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f],\n        [0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69],\n        [0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b],\n        [0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb],\n        [0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe],\n        [0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0],\n        [0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93],\n        [0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8],\n        [0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8],\n        [0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc],\n        [0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17],\n        [0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f],\n        [0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde],\n        [0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6],\n        [0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad],\n        [0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32],\n        [0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71],\n        [0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7],\n        [0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12],\n        [0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15],\n        [0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31],\n        [0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02],\n        [0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca],\n        [0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a],\n        [0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e],\n        [0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad],\n        [0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18],\n        [0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4],\n        [0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9],\n        [0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9],\n        [0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb],\n        [0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0],\n        [0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6],\n        [0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7],\n        [0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee],\n        [0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1],\n        [0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a],\n        [0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81],\n        [0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f],\n        [0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24],\n        [0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7],\n        [0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea],\n        [0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60],\n        [0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66],\n        [0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c],\n        [0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f],\n        [0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5],\n        [0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95],\n    ];\n\n    let k0 = 0x_07_06_05_04_03_02_01_00;\n    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;\n    let mut buf = Vec::new();\n    let mut t = 0;\n    let mut state_inc = SipHasher24::new_with_keys(k0, k1);\n\n    while t < 64 {\n        let vec = u8to64_le!(vecs[t], 0);\n        let out = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));\n        assert_eq!(vec, out);\n\n        let full = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));\n        let i = state_inc.finish();\n\n        assert_eq!(full, i);\n        assert_eq!(full, vec);\n\n        buf.push(t as u8);\n        Hasher::write(&mut state_inc, &[t as u8]);\n\n        t += 1;\n    }\n}\n#[test]\nfn test_hash_idempotent() {\n    let val64 = 0xdead_beef_dead_beef_u64;\n    assert_eq!(hash(&val64), hash(&val64));\n    let val32 = 0xdeadbeef_u32;\n    assert_eq!(hash(&val32), hash(&val32));\n}\n\n#[test]\nfn test_hash_no_bytes_dropped_64() {\n    let val = 0xdead_beef_dead_beef_u64;\n\n    assert_ne!(hash(&val), hash(&zero_byte(val, 0)));\n    assert_ne!(hash(&val), hash(&zero_byte(val, 1)));\n    assert_ne!(hash(&val), hash(&zero_byte(val, 2)));\n    assert_ne!(hash(&val), hash(&zero_byte(val, 3)));\n    assert_ne!(hash(&val), hash(&zero_byte(val, 4)));\n    assert_ne!(hash(&val), hash(&zero_byte(val, 5)));\n    assert_ne!(hash(&val), hash(&zero_byte(val, 6)));\n    assert_ne!(hash(&val), hash(&zero_byte(val, 7)));\n\n    fn zero_byte(val: u64, byte: usize) -> u64 {\n        assert!(byte < 8);\n        val & !(0xff << (byte * 8))\n    }\n}\n\n#[test]\nfn test_hash_no_bytes_dropped_32() {\n    let val = 0xdeadbeef_u32;\n\n    assert_ne!(hash(&val), hash(&zero_byte(val, 0)));\n    assert_ne!(hash(&val), hash(&zero_byte(val, 1)));\n    assert_ne!(hash(&val), hash(&zero_byte(val, 2)));\n    assert_ne!(hash(&val), hash(&zero_byte(val, 3)));\n\n    fn zero_byte(val: u32, byte: usize) -> u32 {\n        assert!(byte < 4);\n        val & !(0xff << (byte * 8))\n    }\n}\n\n#[test]\nfn test_hash_no_concat_alias() {\n    let s = (\"aa\", \"bb\");\n    let t = (\"aabb\", \"\");\n    let u = (\"a\", \"abb\");\n\n    assert!(s != t && t != u);\n    assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));\n\n    let u = [1, 0, 0, 0];\n    let v = (&u[..1], &u[1..3], &u[3..]);\n    let w = (&u[..], &u[4..4], &u[4..4]);\n\n    assert_ne!(v, w);\n    assert_ne!(hash(&v), hash(&w));\n}\n\n#[test]\nfn test_hash_simple() {\n    let array: &[u8] = &[1, 2, 3];\n    let key: &[u8; 16] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n    let hasher = SipHasher13::new_with_key(key);\n    let h = hasher.hash(array);\n    _ = h;\n}\n\n#[test]\nfn test_hash_incremental() {\n    let array1: &[u8] = &[1, 2, 3];\n    let array2: &[u8] = &[4, 5, 6];\n    let key: &[u8; 16] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n    let mut hasher = SipHasher13::new_with_key(key);\n    hasher.write(array1);\n    hasher.write(array2);\n    let h = hasher.finish();\n    _ = h;\n}\n\n#[test]\n#[cfg(all(feature = \"serde\", feature = \"serde_json\"))]\nfn test_hash_serde() {\n    let val64 = 0xdead_beef_dead_beef_u64;\n    let hash = hash(&val64);\n    let serialized = serde_json::to_string(&hash).unwrap();\n    let deserialized: u64 = serde_json::from_str(&serialized).unwrap();\n    assert_eq!(hash, deserialized);\n}\n"
    },
    {
      "package": "siphasher@0.3.11",
      "sourcePath": "src/tests128.rs",
      "sha256": "227986a432d65be2c947a500209adb7767a376b49d82e448487db6a2215476cc",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse std::hash::{Hash, Hasher};\n\nuse super::sip128::{Hasher128, SipHasher, SipHasher13, SipHasher24};\n\n// Hash just the bytes of the slice, without length prefix\nstruct Bytes<'a>(&'a [u8]);\n\nimpl<'a> Hash for Bytes<'a> {\n    #[allow(unused_must_use)]\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let Bytes(v) = *self;\n        state.write(v);\n    }\n}\n\nfn hash_with<H: Hasher + Hasher128, T: Hash>(mut st: H, x: &T) -> [u8; 16] {\n    x.hash(&mut st);\n    st.finish128().as_bytes()\n}\n\nfn hash<T: Hash>(x: &T) -> [u8; 16] {\n    hash_with(SipHasher::new(), x)\n}\n\n#[test]\nfn test_siphash128_idempotent() {\n    let val64 = 0xdead_beef_dead_beef_u64;\n    assert_eq!(hash(&val64), hash(&val64));\n    let val32 = 0xdeadbeef_u32;\n    assert_eq!(hash(&val32), hash(&val32));\n}\n\n#[test]\n#[allow(unused_must_use)]\nfn test_siphash128_1_3() {\n    let vecs: [[u8; 16]; 1] = [[\n        231, 126, 188, 178, 39, 136, 165, 190, 253, 98, 219, 106, 221, 48, 48, 1,\n    ]];\n\n    let k0 = 0x_07_06_05_04_03_02_01_00;\n    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;\n    let mut buf = Vec::new();\n    let mut t = 0;\n    let mut state_inc = SipHasher13::new_with_keys(k0, k1);\n\n    while t < 1 {\n        let vec = vecs[t];\n        let out = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));\n        assert_eq!(vec, out[..]);\n\n        let full = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));\n        let i = state_inc.finish128().as_bytes();\n\n        assert_eq!(full, i);\n        assert_eq!(full, vec);\n\n        buf.push(t as u8);\n        Hasher::write(&mut state_inc, &[t as u8]);\n\n        t += 1;\n    }\n}\n\n#[test]\n#[allow(unused_must_use)]\nfn test_siphash128_2_4() {\n    let vecs: [[u8; 16]; 1] = [[\n        163, 129, 127, 4, 186, 37, 168, 230, 109, 246, 114, 20, 199, 85, 2, 147,\n    ]];\n\n    let k0 = 0x_07_06_05_04_03_02_01_00;\n    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;\n    let mut buf = Vec::new();\n    let mut t = 0;\n    let mut state_inc = SipHasher24::new_with_keys(k0, k1);\n\n    while t < 1 {\n        let vec = vecs[t];\n        let out = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));\n        assert_eq!(vec, out[..]);\n\n        let full = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));\n        let i = state_inc.finish128().as_bytes();\n\n        assert_eq!(full, i);\n        assert_eq!(full, vec);\n\n        buf.push(t as u8);\n        Hasher::write(&mut state_inc, &[t as u8]);\n\n        t += 1;\n    }\n}\n\n#[test]\nfn test_siphash128_simple() {\n    let array: &[u8] = &[1, 2, 3];\n    let key: &[u8; 16] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n    let hasher = SipHasher13::new_with_key(key);\n    let h = hasher.hash(array).as_bytes();\n    _ = h;\n}\n\n#[test]\nfn test_siphash128_incremental() {\n    let array1: &[u8] = &[1, 2, 3];\n    let array2: &[u8] = &[4, 5, 6];\n    let key: &[u8; 16] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n    let mut hasher = SipHasher13::new_with_key(key);\n    hasher.write(array1);\n    hasher.write(array2);\n    let h = hasher.finish128().as_bytes();\n    _ = h;\n}\n\n#[test]\n#[cfg(all(feature = \"serde\", feature = \"serde_json\"))]\nfn test_siphash128_serde() {\n    let val64 = 0xdead_beef_dead_beef_u64;\n    let hash = hash(&val64);\n    let serialized = serde_json::to_string(&hash).unwrap();\n    let deserialized: [u8; 16] = serde_json::from_str(&serialized).unwrap();\n    assert_eq!(hash, deserialized);\n}\n"
    },
    {
      "package": "slab@0.4.12",
      "sourcePath": "README.md",
      "sha256": "6e8d6d493aec6526593ae9b05e3b21d3f878c5816a94af9d372598e03406b35f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# Slab\n\nPre-allocated storage for a uniform data type.\n\n[![Crates.io][crates-badge]][crates-url]\n[![Build Status][ci-badge]][ci-url]\n\n[crates-badge]: https://img.shields.io/crates/v/slab\n[crates-url]: https://crates.io/crates/slab\n[ci-badge]: https://img.shields.io/github/actions/workflow/status/tokio-rs/slab/ci.yml?branch=master\n[ci-url]: https://github.com/tokio-rs/slab/actions\n\n[Documentation](https://docs.rs/slab)\n\n## Usage\n\nTo use `slab`, first add this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nslab = \"0.4\"\n```\n\nNext, add this to your crate:\n\n```rust\nuse slab::Slab;\n\nlet mut slab = Slab::new();\n\nlet hello = slab.insert(\"hello\");\nlet world = slab.insert(\"world\");\n\nassert_eq!(slab[hello], \"hello\");\nassert_eq!(slab[world], \"world\");\n\nslab[world] = \"earth\";\nassert_eq!(slab[world], \"earth\");\n```\n\nSee [documentation](https://docs.rs/slab) for more details.\n\n## License\n\nThis project is licensed under the [MIT license](LICENSE).\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in `slab` by you, shall be licensed as MIT, without any additional\nterms or conditions.\n"
    },
    {
      "package": "smallvec@1.16.1",
      "sourcePath": "src/lib.rs",
      "sha256": "5b134e57ce9dfa4ef8bfaac59bd0f73250123fed74f315030cd052a2ae64a41d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Small vectors in various sizes. These store a certain number of elements\n//! inline, and fall back to the heap for larger allocations.  This can be a\n//! useful optimization for improving cache locality and reducing allocator\n//! traffic for workloads that fit within the inline buffer.\n//!\n//! ## `no_std` support\n//!\n//! By default, `smallvec` does not depend on `std`.  However, the optional\n//! `write` feature implements the `std::io::Write` trait for vectors of `u8`.\n//! When this feature is enabled, `smallvec` depends on `std`.\n//!\n//! ## Optional features\n//!\n//! ### `serde`\n//!\n//! When this optional dependency is enabled, `SmallVec` implements the\n//! `serde::Serialize` and `serde::Deserialize` traits.\n//!\n//! ### `write`\n//!\n//! When this feature is enabled, `SmallVec<[u8; _]>` implements the\n//! `std::io::Write` trait. This feature is not compatible with `#![no_std]`\n//! programs.\n//!\n//! ### `union`\n//!\n//! **This feature requires Rust 1.49.**\n//!\n//! When the `union` feature is enabled `smallvec` will track its state (inline\n//! or spilled) without the use of an enum tag, reducing the size of the\n//! `smallvec` by one machine word. This means that there is potentially no\n//! space overhead compared to `Vec`. Note that `smallvec` can still be larger\n//! than `Vec` if the inline buffer is larger than two machine words.\n//!\n//! To use this feature add `features = [\"union\"]` in the `smallvec` section of\n//! Cargo.toml. Note that this feature requires Rust 1.49.\n//!\n//! Tracking issue: [rust-lang/rust#55149](https://github.com/rust-lang/rust/issues/55149)\n//!\n//! ### `const_generics`\n//!\n//! **This feature requires Rust 1.51.**\n//!\n//! When this feature is enabled, `SmallVec` works with any arrays of any size,\n//! not just a fixed list of sizes.\n//!\n//! ### `const_new`\n//!\n//! **This feature requires Rust 1.51.**\n//!\n//! This feature exposes the functions [`SmallVec::new_const`],\n//! [`SmallVec::from_const`], and [`smallvec_inline`] which enables the\n//! `SmallVec` to be initialized from a const context. For details, see the\n//! [Rust Reference](https://doc.rust-lang.org/reference/const_eval.html#const-functions).\n//!\n//! ### `drain_filter`\n//!\n//! **This feature is unstable.** It may change to match the unstable\n//! `drain_filter` method in libstd.\n//!\n//! Enables the `drain_filter` method, which produces an iterator that calls a\n//! user-provided closure to determine which elements of the vector to remove\n//! and yield from the iterator.\n//!\n//! ### `drain_keep_rest`\n//!\n//! **This feature is unstable.** It may change to match the unstable\n//! `drain_keep_rest` method in libstd.\n//!\n//! Enables the `DrainFilter::keep_rest` method.\n//!\n//! ### `specialization`\n//!\n//! **This feature is unstable and requires a nightly build of the Rust\n//! toolchain.**\n//!\n//! When this feature is enabled, `SmallVec::from(slice)` has improved\n//! performance for slices of `Copy` types.  (Without this feature, you can use\n//! `SmallVec::from_slice` to get optimal performance for `Copy` types.)\n//!\n//! Tracking issue: [rust-lang/rust#31844](https://github.com/rust-lang/rust/issues/31844)\n//!\n//! ### `may_dangle`\n//!\n//! **This feature is unstable and requires a nightly build of the Rust\n//! toolchain.**\n//!\n//! This feature makes the Rust compiler less strict about use of vectors that\n//! contain borrowed references. For details, see the\n//! [Rustonomicon](https://doc.rust-lang.org/1.42.0/nomicon/dropck.html#an-escape-hatch).\n//!\n//! Tracking issue: [rust-lang/rust#34761](https://github.com/rust-lang/rust/issues/34761)\n\n#![no_std]\n#![cfg_attr(docsrs, feature(doc_cfg))]\n#![cfg_attr(feature = \"specialization\", allow(incomplete_features))]\n#![cfg_attr(feature = \"specialization\", feature(specialization))]\n#![cfg_attr(feature = \"may_dangle\", feature(dropck_eyepatch))]\n#![deny(missing_docs)]\n\n#[doc(hidden)]\npub extern crate alloc;\n\n#[cfg(any(test, feature = \"write\"))]\nextern crate std;\n\n#[cfg(test)]\nmod tests;\n\n#[cfg(feature = \"serde\")]\nuse core::marker::PhantomData;\n#[cfg(feature = \"drain_keep_rest\")]\nuse core::mem::ManuallyDrop;\n#[cfg(feature = \"malloc_size_of\")]\nuse malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};\n#[cfg(feature = \"serde\")]\nuse serde::{\n    de::{Deserialize, Deserializer, SeqAccess, Visitor},\n    ser::{Serialize, SerializeSeq, Serializer},\n};\n#[cfg(feature = \"write\")]\nuse std::io;\n#[allow(deprecated)]\nuse {\n    alloc::{\n        alloc::{Layout, LayoutErr},\n        boxed::Box,\n        vec,\n        vec::Vec,\n    },\n    core::{\n        borrow::{Borrow, BorrowMut},\n        cmp, fmt,\n        hash::{Hash, Hasher},\n        hint::unreachable_unchecked,\n        iter::{repeat, FromIterator, FusedIterator, IntoIterator},\n        mem::{self, MaybeUninit},\n        ops::{self, Range, RangeBounds},\n        ptr::{self, NonNull},\n        slice::{self, SliceIndex},\n    },\n};\n\n/// Creates a [`SmallVec`] containing the arguments.\n///\n/// `smallvec!` allows `SmallVec`s to be defined with the same syntax as array\n/// expressions. There are two forms of this macro:\n///\n/// - Create a [`SmallVec`] containing a given list of elements:\n///\n/// ```\n/// # use smallvec::{smallvec, SmallVec};\n/// # fn main() {\n/// let v: SmallVec<[_; 128]> = smallvec![1, 2, 3];\n/// assert_eq!(v[0], 1);\n/// assert_eq!(v[1], 2);\n/// assert_eq!(v[2], 3);\n/// # }\n/// ```\n///\n/// - Create a [`SmallVec`] from a given element and size:\n///\n/// ```\n/// # use smallvec::{smallvec, SmallVec};\n/// # fn main() {\n/// let v: SmallVec<[_; 10]> = smallvec![1; 3];\n/// assert_eq!(v, SmallVec::from_buf([1, 1, 1]));\n/// # }\n/// ```\n///\n/// Note that unlike array expressions this syntax supports all elements\n/// which implement [`Clone`] and the number of elements doesn't have to be\n/// a constant.\n///\n/// This will use `clone` to duplicate an expression, so one should be careful\n/// using this with types having a nonstandard `Clone` implementation. For\n/// example, `smallvec![Rc::new(1); 5]` will create a vector of five references\n/// to the same boxed integer value, not five references pointing to\n/// independently boxed integers.\n#[macro_export]\nmacro_rules! smallvec {\n    // count helper: transform any expression into 1\n    (@one $x:expr) => (1usize);\n    () => (\n        $crate::SmallVec::new()\n    );\n    ($elem:expr; $n:expr) => ({\n        $crate::SmallVec::from_elem($elem, $n)\n    });\n    ($($x:expr),+$(,)?) => ({\n        let count = 0usize $(+ $crate::smallvec!(@one $x))+;\n        let mut vec = $crate::SmallVec::new();\n        if count <= vec.inline_size() {\n            $(vec.push($x);)*\n            vec\n        } else {\n            $crate::SmallVec::from_vec($crate::alloc::vec![$($x,)+])\n        }\n    });\n}\n\n/// Creates an inline [`SmallVec`] containing the arguments. This macro is\n/// enabled by the feature `const_new`.\n///\n/// `smallvec_inline!` allows `SmallVec`s to be defined with the same syntax as\n/// array expressions in `const` contexts. The inline storage `A` will always be\n/// an array of the size specified by the arguments. There are two forms of this\n/// macro:\n///\n/// - Create a [`SmallVec`] containing a given list of elements:\n///\n/// ```\n/// # use smallvec::{smallvec_inline, SmallVec};\n/// # fn main() {\n/// const V: SmallVec<[i32; 3]> = smallvec_inline![1, 2, 3];\n/// assert_eq!(V[0], 1);\n/// assert_eq!(V[1], 2);\n/// assert_eq!(V[2], 3);\n/// # }\n/// ```\n///\n/// - Create a [`SmallVec`] from a given element and size:\n///\n/// ```\n/// # use smallvec::{smallvec_inline, SmallVec};\n/// # fn main() {\n/// const V: SmallVec<[i32; 3]> = smallvec_inline![1; 3];\n/// assert_eq!(V, SmallVec::from_buf([1, 1, 1]));\n/// # }\n/// ```\n///\n/// Note that the behavior mimics that of array expressions, in contrast to\n/// [`smallvec`].\n#[cfg(feature = \"const_new\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"const_new\")))]\n#[macro_export]\nmacro_rules! smallvec_inline {\n    // count helper: transform any expression into 1\n    (@one $x:expr) => (1usize);\n    ($elem:expr; $n:expr) => ({\n        $crate::SmallVec::<[_; $n]>::from_const([$elem; $n])\n    });\n    ($($x:expr),+ $(,)?) => ({\n        const N: usize = 0usize $(+ $crate::smallvec_inline!(@one $x))*;\n        $crate::SmallVec::<[_; N]>::from_const([$($x,)*])\n    });\n}\n\n/// `panic!()` in debug builds, optimization hint in release.\n#[cfg(not(feature = \"union\"))]\nmacro_rules! debug_unreachable {\n    () => {\n        debug_unreachable!(\"entered unreachable code\")\n    };\n    ($e:expr) => {\n        if cfg!(debug_assertions) {\n            panic!($e);\n        } else {\n            unreachable_unchecked();\n        }\n    };\n}\n\n/// Trait to be implemented by a collection that can be extended from a slice\n///\n/// ## Example\n///\n/// ```rust\n/// use smallvec::{ExtendFromSlice, SmallVec};\n///\n/// fn initialize<V: ExtendFromSlice<u8>>(v: &mut V) {\n///     v.extend_from_slice(b\"Test!\");\n/// }\n///\n/// let mut vec = Vec::new();\n/// initialize(&mut vec);\n/// assert_eq!(&vec, b\"Test!\");\n///\n/// let mut small_vec = SmallVec::<[u8; 8]>::new();\n/// initialize(&mut small_vec);\n/// assert_eq!(&small_vec as &[_], b\"Test!\");\n/// ```\n#[doc(hidden)]\n#[deprecated]\npub trait ExtendFromSlice<T> {\n    /// Extends a collection from a slice of its element type\n    fn extend_from_slice(&mut self, other: &[T]);\n}\n\n#[allow(deprecated)]\nimpl<T: Clone> ExtendFromSlice<T> for Vec<T> {\n    fn extend_from_slice(&mut self, other: &[T]) {\n        Vec::extend_from_slice(self, other)\n    }\n}\n\n/// Error type for APIs with fallible heap allocation\n#[derive(Debug)]\npub enum CollectionAllocErr {\n    /// Overflow `usize::MAX` or other error during size computation\n    CapacityOverflow,\n    /// The allocator return an error\n    AllocErr {\n        /// The layout that was passed to the allocator\n        layout: Layout,\n    },\n}\n\nimpl fmt::Display for CollectionAllocErr {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"Allocation error: {:?}\", self)\n    }\n}\n\n#[allow(deprecated)]\nimpl From<LayoutErr> for CollectionAllocErr {\n    fn from(_: LayoutErr) -> Self {\n        CollectionAllocErr::CapacityOverflow\n    }\n}\n\nfn infallible<T>(result: Result<T, CollectionAllocErr>) -> T {\n    match result {\n        Ok(x) => x,\n        Err(CollectionAllocErr::CapacityOverflow) => panic!(\"capacity overflow\"),\n        Err(CollectionAllocErr::AllocErr { layout }) => alloc::alloc::handle_alloc_error(layout),\n    }\n}\n\n/// FIXME: use `Layout::array` when we require a Rust version where it’s stable\n/// <https://github.com/rust-lang/rust/issues/55724>\nfn layout_array<T>(n: usize) -> Result<Layout, CollectionAllocErr> {\n    let size = mem::size_of::<T>()\n        .checked_mul(n)\n        .ok_or(CollectionAllocErr::CapacityOverflow)?;\n    let align = mem::align_of::<T>();\n    Layout::from_size_align(size, align).map_err(|_| CollectionAllocErr::CapacityOverflow)\n}\n\nunsafe fn deallocate<T>(ptr: NonNull<T>, capacity: usize) {\n    // This unwrap should succeed since the same did when allocating.\n    let layout = layout_array::<T>(capacity).unwrap();\n    alloc::alloc::dealloc(ptr.as_ptr() as *mut u8, layout)\n}\n\n/// An iterator that removes the items from a `SmallVec` and yields them by\n/// value.\n///\n/// Returned from [`SmallVec::drain`][1].\n///\n/// [1]: struct.SmallVec.html#method.drain\npub struct Drain<'a, T: 'a + Array> {\n    tail_start: usize,\n    tail_len: usize,\n    iter: slice::Iter<'a, T::Item>,\n    vec: NonNull<SmallVec<T>>,\n}\n\nimpl<'a, T: 'a + Array> fmt::Debug for Drain<'a, T>\nwhere\n    T::Item: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_tuple(\"Drain\").field(&self.iter.as_slice()).finish()\n    }\n}\n\nunsafe impl<'a, T: Sync + Array> Sync for Drain<'a, T> {}\nunsafe impl<'a, T: Send + Array> Send for Drain<'a, T> {}\n\nimpl<'a, T: 'a + Array> Iterator for Drain<'a, T> {\n    type Item = T::Item;\n\n    #[inline]\n    fn next(&mut self) -> Option<T::Item> {\n        self.iter\n            .next()\n            .map(|reference| unsafe { ptr::read(reference) })\n    }\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.iter.size_hint()\n    }\n}\n\nimpl<'a, T: 'a + Array> DoubleEndedIterator for Drain<'a, T> {\n    #[inline]\n    fn next_back(&mut self) -> Option<T::Item> {\n        self.iter\n            .next_back()\n            .map(|reference| unsafe { ptr::read(reference) })\n    }\n}\n\nimpl<'a, T: Array> ExactSizeIterator for Drain<'a, T> {\n    #[inline]\n    fn len(&self) -> usize {\n        self.iter.len()\n    }\n}\n\nimpl<'a, T: Array> FusedIterator for Drain<'a, T> {}\n\nimpl<'a, T: 'a + Array> Drop for Drain<'a, T> {\n    fn drop(&mut self) {\n        self.for_each(drop);\n\n        if self.tail_len > 0 {\n            unsafe {\n                let source_vec = self.vec.as_mut();\n\n                // memmove back untouched tail, update to new length\n                let start = source_vec.len();\n                let tail = self.tail_start;\n                if tail != start {\n                    // as_mut_ptr creates a &mut, invalidating other pointers.\n                    // This pattern avoids calling it with a pointer already\n                    // present.\n                    let ptr = source_vec.as_mut_ptr();\n                    let src = ptr.add(tail);\n                    let dst = ptr.add(start);\n                    ptr::copy(src, dst, self.tail_len);\n                }\n                source_vec.set_len(start + self.tail_len);\n            }\n        }\n    }\n}\n\n#[cfg(feature = \"drain_filter\")]\n/// An iterator which uses a closure to determine if an element should be\n/// removed.\n///\n/// Returned from [`SmallVec::drain_filter`][1].\n///\n/// [1]: struct.SmallVec.html#method.drain_filter\npub struct DrainFilter<'a, T, F>\nwhere\n    F: FnMut(&mut T::Item) -> bool,\n    T: Array,\n{\n    vec: &'a mut SmallVec<T>,\n    /// The index of the item that will be inspected by the next call to `next`.\n    idx: usize,\n    /// The number of items that have been drained (removed) thus far.\n    del: usize,\n    /// The original length of `vec` prior to draining.\n    old_len: usize,\n    /// The filter test predicate.\n    pred: F,\n    /// A flag that indicates a panic has occurred in the filter test predicate.\n    /// This is used as a hint in the drop implementation to prevent consumption\n    /// of the remainder of the `DrainFilter`. Any unprocessed items will be\n    /// backshifted in the `vec`, but no further items will be dropped or\n    /// tested by the filter predicate.\n    panic_flag: bool,\n}\n\n#[cfg(feature = \"drain_filter\")]\nimpl<T, F> fmt::Debug for DrainFilter<'_, T, F>\nwhere\n    F: FnMut(&mut T::Item) -> bool,\n    T: Array,\n    T::Item: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_tuple(\"DrainFilter\")\n            .field(&self.vec.as_slice())\n            .finish()\n    }\n}\n\n#[cfg(feature = \"drain_filter\")]\nimpl<T, F> Iterator for DrainFilter<'_, T, F>\nwhere\n    F: FnMut(&mut T::Item) -> bool,\n    T: Array,\n{\n    type Item = T::Item;\n\n    fn next(&mut self) -> Option<T::Item> {\n        unsafe {\n            while self.idx < self.old_len {\n                let i = self.idx;\n                let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len);\n                self.panic_flag = true;\n                let drained = (self.pred)(&mut v[i]);\n                self.panic_flag = false;\n                // Update the index *after* the predicate is called. If the\n                // index is updated prior and the predicate\n                // panics, the element at this index would be\n                // leaked.\n                self.idx += 1;\n                if drained {\n                    self.del += 1;\n                    return Some(ptr::read(&v[i]));\n                } else if self.del > 0 {\n                    let del = self.del;\n                    let src: *const Self::Item = &v[i];\n                    let dst: *mut Self::Item = &mut v[i - del];\n                    ptr::copy_nonoverlapping(src, dst, 1);\n                }\n            }\n            None\n        }\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        (0, Some(self.old_len - self.idx))\n    }\n}\n\n#[cfg(feature = \"drain_filter\")]\nimpl<T, F> Drop for DrainFilter<'_, T, F>\nwhere\n    F: FnMut(&mut T::Item) -> bool,\n    T: Array,\n{\n    fn drop(&mut self) {\n        struct BackshiftOnDrop<'a, 'b, T, F>\n        where\n            F: FnMut(&mut T::Item) -> bool,\n            T: Array,\n        {\n            drain: &'b mut DrainFilter<'a, T, F>,\n        }\n\n        impl<'a, 'b, T, F> Drop for BackshiftOnDrop<'a, 'b, T, F>\n        where\n            F: FnMut(&mut T::Item) -> bool,\n            T: Array,\n        {\n            fn drop(&mut self) {\n                unsafe {\n                    if self.drain.idx < self.drain.old_len && self.drain.del > 0 {\n                        // This is a pretty messed up state, and there isn't\n                        // really an obviously right\n                        // thing to do. We don't want to keep trying\n                        // to execute `pred`, so we just backshift all the\n                        // unprocessed elements and tell\n                        // the vec that they still exist. The backshift\n                        // is required to prevent a double-drop of the last\n                        // successfully drained item\n                        // prior to a panic in the predicate.\n                        let ptr = self.drain.vec.as_mut_ptr();\n                        let src = ptr.add(self.drain.idx);\n                        let dst = src.sub(self.drain.del);\n                        let tail_len = self.drain.old_len - self.drain.idx;\n                        src.copy_to(dst, tail_len);\n                    }\n                    self.drain.vec.set_len(self.drain.old_len - self.drain.del);\n                }\n            }\n        }\n\n        let backshift = BackshiftOnDrop { drain: self };\n\n        // Attempt to consume any remaining elements if the filter predicate\n        // has not yet panicked. We'll backshift any remaining elements\n        // whether we've already panicked or if the consumption here panics.\n        if !backshift.drain.panic_flag {\n            backshift.drain.for_each(drop);\n        }\n    }\n}\n\n#[cfg(feature = \"drain_keep_rest\")]\nimpl<T, F> DrainFilter<'_, T, F>\nwhere\n    F: FnMut(&mut T::Item) -> bool,\n    T: Array,\n{\n    /// Keep unyielded elements in the source `Vec`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use smallvec::{smallvec, SmallVec};\n    ///\n    /// let mut vec: SmallVec<[char; 2]> = smallvec!['a', 'b', 'c'];\n    /// let mut drain = vec.drain_filter(|_| true);\n    ///\n    /// assert_eq!(drain.next().unwrap(), 'a');\n    ///\n    /// // This call keeps 'b' and 'c' in the vec.\n    /// drain.keep_rest();\n    ///\n    /// // If we wouldn't call `keep_rest()`,\n    /// // `vec` would be empty.\n    /// assert_eq!(vec, SmallVec::<[char; 2]>::from_slice(&['b', 'c']));\n    /// ```\n    pub fn keep_rest(self) {\n        // At this moment layout looks like this:\n        //\n        //  _____________________/-- old_len\n        // /                     \\\n        // [kept] [yielded] [tail]\n        //        \\_______/ ^-- idx\n        //                \\-- del\n        //\n        // Normally `Drop` impl would drop [tail] (via .for_each(drop), ie still\n        // calling `pred`)\n        //\n        // 1. Move [tail] after [kept]\n        // 2. Update length of the original vec to `old_len - del` a. In case of\n        //    ZST, this is the only thing we want to do\n        // 3. Do *not* drop self, as everything is put in a consistent state\n        //    already, there is nothing to do\n        let mut this = ManuallyDrop::new(self);\n\n        unsafe {\n            // ZSTs have no identity, so we don't need to move them around.\n            let needs_move = mem::size_of::<T::Item>() != 0;\n\n            if needs_move && this.idx < this.old_len && this.del > 0 {\n                let ptr = this.vec.as_mut_ptr();\n                let src = ptr.add(this.idx);\n                let dst = src.sub(this.del);\n                let tail_len = this.old_len - this.idx;\n                src.copy_to(dst, tail_len);\n            }\n\n            let new_len = this.old_len - this.del;\n            this.vec.set_len(new_len);\n        }\n    }\n}\n\n#[cfg(feature = \"union\")]\nunion SmallVecData<A: Array> {\n    inline: core::mem::ManuallyDrop<MaybeUninit<A>>,\n    heap: (NonNull<A::Item>, usize),\n}\n\n#[cfg(all(feature = \"union\", feature = \"const_new\"))]\nimpl<T, const N: usize> SmallVecData<[T; N]> {\n    #[cfg_attr(docsrs, doc(cfg(feature = \"const_new\")))]\n    #[inline]\n    const fn from_const(inline: MaybeUninit<[T; N]>) -> Self {\n        SmallVecData {\n            inline: core::mem::ManuallyDrop::new(inline),\n        }\n    }\n}\n\n#[cfg(feature = \"union\")]\nimpl<A: Array> SmallVecData<A> {\n    #[inline]\n    unsafe fn inline(&self) -> ConstNonNull<A::Item> {\n        ConstNonNull::new(self.inline.as_ptr() as *const A::Item).unwrap()\n    }\n    #[inline]\n    unsafe fn inline_mut(&mut self) -> NonNull<A::Item> {\n        NonNull::new(self.inline.as_mut_ptr() as *mut A::Item).unwrap()\n    }\n    #[inline]\n    fn from_inline(inline: MaybeUninit<A>) -> SmallVecData<A> {\n        SmallVecData {\n            inline: core::mem::ManuallyDrop::new(inline),\n        }\n    }\n    // Workaround for https://github.com/rust-lang/rust/issues/157743: when from_inline is\n    // called with MaybeUninit::uninit(), rustc 1.93+ GVN propagates const\n    // <uninit> into the ManuallyDrop::new() aggregate, causing LLVM to\n    // materialize a global constant that MemCpyOpt then collapses into a\n    // memset over the whole struct. Using assume_init() of a doubly-wrapped\n    // MaybeUninit produces Immediate::Uninit instead of const <uninit>,\n    // which codegen handles as undef without emitting any global. This\n    // function also avoids introducing an intermediate local that would\n    // inflate stack frames in debug builds.\n    #[inline]\n    fn empty() -> SmallVecData<A> {\n        // SAFETY: ManuallyDrop<MaybeUninit<A>> is valid for any bit pattern\n        // including uninitialized bytes, so assume_init() on a\n        // MaybeUninit of that type is sound.\n        SmallVecData {\n            inline: unsafe { MaybeUninit::uninit().assume_init() },\n        }\n    }\n    #[inline]\n    unsafe fn into_inline(self) -> MaybeUninit<A> {\n        core::mem::ManuallyDrop::into_inner(self.inline)\n    }\n    #[inline]\n    unsafe fn heap(&self) -> (ConstNonNull<A::Item>, usize) {\n        (ConstNonNull(self.heap.0), self.heap.1)\n    }\n    #[inline]\n    unsafe fn heap_mut(&mut self) -> (NonNull<A::Item>, &mut usize) {\n        let h = &mut self.heap;\n        (h.0, &mut h.1)\n    }\n    #[inline]\n    fn from_heap(ptr: NonNull<A::Item>, len: usize) -> SmallVecData<A> {\n        SmallVecData { heap: (ptr, len) }\n    }\n}\n\n#[cfg(not(feature = \"union\"))]\nenum SmallVecData<A: Array> {\n    Inline(MaybeUninit<A>),\n    // Using NonNull and NonZero here allows to reduce size of `SmallVec`.\n    Heap {\n        // Since we never allocate on heap\n        // unless our capacity is bigger than inline capacity\n        // heap capacity cannot be less than 1.\n        // Therefore, pointer cannot be null too.\n        ptr: NonNull<A::Item>,\n        len: usize,\n    },\n}\n\n#[cfg(all(not(feature = \"union\"), feature = \"const_new\"))]\nimpl<T, const N: usize> SmallVecData<[T; N]> {\n    #[cfg_attr(docsrs, doc(cfg(feature = \"const_new\")))]\n    #[inline]\n    const fn from_const(inline: MaybeUninit<[T; N]>) -> Self {\n        SmallVecData::Inline(inline)\n    }\n}\n\n#[cfg(not(feature = \"union\"))]\nimpl<A: Array> SmallVecData<A> {\n    #[inline]\n    unsafe fn inline(&self) -> ConstNonNull<A::Item> {\n        match self {\n            SmallVecData::Inline(a) => ConstNonNull::new(a.as_ptr() as *const A::Item).unwrap(),\n            _ => debug_unreachable!(),\n        }\n    }\n    #[inline]\n    unsafe fn inline_mut(&mut self) -> NonNull<A::Item> {\n        match self {\n            SmallVecData::Inline(a) => NonNull::new(a.as_mut_ptr() as *mut A::Item).unwrap(),\n            _ => debug_unreachable!(),\n        }\n    }\n    #[inline]\n    fn from_inline(inline: MaybeUninit<A>) -> SmallVecData<A> {\n        SmallVecData::Inline(inline)\n    }\n    // See the comment on the union variant's empty() for why this exists.\n    #[inline]\n    fn empty() -> SmallVecData<A> {\n        // SAFETY: MaybeUninit<A> is valid for any bit pattern including\n        // uninitialized bytes, so assume_init() on a MaybeUninit of\n        // that type is sound.\n        SmallVecData::Inline(unsafe { MaybeUninit::uninit().assume_init() })\n    }\n    #[inline]\n    unsafe fn into_inline(self) -> MaybeUninit<A> {\n        match self {\n            SmallVecData::Inline(a) => a,\n            _ => debug_unreachable!(),\n        }\n    }\n    #[inline]\n    unsafe fn heap(&self) -> (ConstNonNull<A::Item>, usize) {\n        match self {\n            SmallVecData::Heap { ptr, len } => (ConstNonNull(*ptr), *len),\n            _ => debug_unreachable!(),\n        }\n    }\n    #[inline]\n    unsafe fn heap_mut(&mut self) -> (NonNull<A::Item>, &mut usize) {\n        match self {\n            SmallVecData::Heap { ptr, len } => (*ptr, len),\n            _ => debug_unreachable!(),\n        }\n    }\n    #[inline]\n    fn from_heap(ptr: NonNull<A::Item>, len: usize) -> SmallVecData<A> {\n        SmallVecData::Heap { ptr, len }\n    }\n}\n\nunsafe impl<A: Array + Send> Send for SmallVecData<A> {}\nunsafe impl<A: Array + Sync> Sync for SmallVecData<A> {}\n\n/// A `Vec`-like container that can store a small number of elements inline.\n///\n/// `SmallVec` acts like a vector, but can store a limited amount of data inline\n/// within the `SmallVec` struct rather than in a separate allocation.  If the\n/// data exceeds this limit, the `SmallVec` will \"spill\" its data onto the heap,\n/// allocating a new buffer to hold it.\n///\n/// The amount of data that a `SmallVec` can store inline depends on its backing\n/// store. The backing store can be any type that implements the `Array` trait;\n/// usually it is a small fixed-sized array.  For example a `SmallVec<[u64; 8]>`\n/// can hold up to eight 64-bit integers inline.\n///\n/// ## Example\n///\n/// ```rust\n/// use smallvec::SmallVec;\n/// let mut v = SmallVec::<[u8; 4]>::new(); // initialize an empty vector\n///\n/// // The vector can hold up to 4 items without spilling onto the heap.\n/// v.extend(0..4);\n/// assert_eq!(v.len(), 4);\n/// assert!(!v.spilled());\n///\n/// // Pushing another element will force the buffer to spill:\n/// v.push(4);\n/// assert_eq!(v.len(), 5);\n/// assert!(v.spilled());\n/// ```\npub struct SmallVec<A: Array> {\n    // The capacity field is used to determine which of the storage variants is active:\n    // If capacity <= Self::inline_capacity() then the inline variant is used and capacity holds\n    // the current length of the vector (number of elements actually in use). If capacity >\n    // Self::inline_capacity() then the heap variant is used and capacity holds the size of the\n    // memory allocation.\n    capacity: usize,\n    data: SmallVecData<A>,\n}\n\nimpl<A: Array> SmallVec<A> {\n    /// Construct an empty vector\n    #[inline]\n    pub fn new() -> SmallVec<A> {\n        // Try to detect invalid custom implementations of `Array`. Hopefully,\n        // this check should be optimized away entirely for valid ones.\n        assert!(\n            mem::size_of::<A>() == A::size() * mem::size_of::<A::Item>()\n                && mem::align_of::<A>() >= mem::align_of::<A::Item>()\n        );\n        SmallVec {\n            capacity: 0,\n            data: SmallVecData::empty(),\n        }\n    }\n\n    /// Construct an empty vector with enough capacity pre-allocated to store at\n    /// least `n` elements.\n    ///\n    /// Will create a heap allocation only if `n` is larger than the inline\n    /// capacity.\n    ///\n    /// ```\n    /// # use smallvec::SmallVec;\n    ///\n    /// let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(100);\n    ///\n    /// assert!(v.is_empty());\n    /// assert!(v.capacity() >= 100);\n    /// ```\n    #[inline]\n    pub fn with_capacity(n: usize) -> Self {\n        let mut v = SmallVec::new();\n        v.reserve_exact(n);\n        v\n    }\n\n    /// Construct a new `SmallVec` from a `Vec<A::Item>`.\n    ///\n    /// Elements will be copied to the inline buffer if `vec.capacity() <=\n    /// Self::inline_capacity()`.\n    ///\n    /// ```rust\n    /// use smallvec::SmallVec;\n    ///\n    /// let vec = vec![1, 2, 3, 4, 5];\n    /// let small_vec: SmallVec<[_; 3]> = SmallVec::from_vec(vec);\n    ///\n    /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);\n    /// ```\n    #[inline]\n    pub fn from_vec(mut vec: Vec<A::Item>) -> SmallVec<A> {\n        if vec.capacity() <= Self::inline_capacity() {\n            // Cannot use Vec with smaller capacity\n            // because we use value of `Self::capacity` field as indicator.\n            unsafe {\n                let mut data = SmallVecData::<A>::empty();\n                let len = vec.len();\n                vec.set_len(0);\n                ptr::copy_nonoverlapping(vec.as_ptr(), data.inline_mut().as_ptr(), len);\n\n                SmallVec {\n                    capacity: len,\n                    data,\n                }\n            }\n        } else {\n            let (ptr, cap, len) = (vec.as_mut_ptr(), vec.capacity(), vec.len());\n            mem::forget(vec);\n            let ptr = NonNull::new(ptr)\n                // See docs: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.as_mut_ptr\n                .expect(\"Cannot be null by `Vec` invariant\");\n\n            SmallVec {\n                capacity: cap,\n                data: SmallVecData::from_heap(ptr, len),\n            }\n        }\n    }\n\n    /// Constructs a new `SmallVec` on the stack from an `A` without\n    /// copying elements.\n    ///\n    /// ```rust\n    /// use smallvec::SmallVec;\n    ///\n    /// let buf = [1, 2, 3, 4, 5];\n    /// let small_vec: SmallVec<_> = SmallVec::from_buf(buf);\n    ///\n    /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);\n    /// ```\n    #[inline]\n    pub fn from_buf(buf: A) -> SmallVec<A> {\n        SmallVec {\n            capacity: A::size(),\n            data: SmallVecData::from_inline(MaybeUninit::new(buf)),\n        }\n    }\n\n    /// Constructs a new `SmallVec` on the stack from an `A` without\n    /// copying elements. Also sets the length, which must be less or\n    /// equal to the size of `buf`.\n    ///\n    /// ```rust\n    /// use smallvec::SmallVec;\n    ///\n    /// let buf = [1, 2, 3, 4, 5, 0, 0, 0];\n    /// let small_vec: SmallVec<_> = SmallVec::from_buf_and_len(buf, 5);\n    ///\n    /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);\n    /// ```\n    #[inline]\n    pub fn from_buf_and_len(buf: A, len: usize) -> SmallVec<A> {\n        assert!(len <= A::size());\n        unsafe { SmallVec::from_buf_and_len_unchecked(MaybeUninit::new(buf), len) }\n    }\n\n    /// Constructs a new `SmallVec` on the stack from an `A` without\n    /// copying elements. Also sets the length. The user is responsible\n    /// for ensuring that `len <= A::size()`.\n    ///\n    /// ```rust\n    /// use {smallvec::SmallVec, std::mem::MaybeUninit};\n    ///\n    /// let buf = [1, 2, 3, 4, 5, 0, 0, 0];\n    /// let small_vec: SmallVec<_> =\n    ///     unsafe { SmallVec::from_buf_and_len_unchecked(MaybeUninit::new(buf), 5) };\n    ///\n    /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);\n    /// ```\n    #[inline]\n    pub unsafe fn from_buf_and_len_unchecked(buf: MaybeUninit<A>, len: usize) -> SmallVec<A> {\n        SmallVec {\n            capacity: len,\n            data: SmallVecData::from_inline(buf),\n        }\n    }\n\n    /// Sets the length of a vector.\n    ///\n    /// This will explicitly set the size of the vector, without actually\n    /// modifying its buffers, so it is up to the caller to ensure that the\n    /// vector is actually the specified size.\n    pub unsafe fn set_len(&mut self, new_len: usize) {\n        let (_, len_ptr, _) = self.triple_mut();\n        *len_ptr = new_len;\n    }\n\n    /// The maximum number of elements this vector can hold inline\n    #[inline]\n    fn inline_capacity() -> usize {\n        if mem::size_of::<A::Item>() > 0 {\n            A::size()\n        } else {\n            // For zero-size items code like `ptr.add(offset)` always returns\n            // the same pointer. Therefore all items are at the same\n            // address, and any array size has capacity for\n            // infinitely many items. The capacity is limited by the\n            // bit width of the length field.\n            //\n            // `Vec` also does this:\n            // https://github.com/rust-lang/rust/blob/1.44.0/src/liballoc/raw_vec.rs#L186\n            //\n            // In our case, this also ensures that a smallvec of zero-size items\n            // never spills, and we never try to allocate zero bytes\n            // which `std::alloc::alloc` disallows.\n            #[allow(deprecated)]\n            core::usize::MAX\n        }\n    }\n\n    /// The maximum number of elements this vector can hold inline\n    #[inline]\n    pub fn inline_size(&self) -> usize {\n        Self::inline_capacity()\n    }\n\n    /// The number of elements stored in the vector\n    #[inline]\n    pub fn len(&self) -> usize {\n        self.triple().1\n    }\n\n    /// Returns `true` if the vector is empty\n    #[inline]\n    pub fn is_empty(&self) -> bool {\n        self.len() == 0\n    }\n\n    /// The number of items the vector can hold without reallocating\n    #[inline]\n    pub fn capacity(&self) -> usize {\n        self.triple().2\n    }\n\n    /// Returns a tuple with (data ptr, len, capacity)\n    /// Useful to get all `SmallVec` properties with a single check of the\n    /// current storage variant.\n    #[inline]\n    fn triple(&self) -> (ConstNonNull<A::Item>, usize, usize) {\n        unsafe {\n            if self.spilled() {\n                let (ptr, len) = self.data.heap();\n                (ptr, len, self.capacity)\n            } else {\n                (self.data.inline(), self.capacity, Self::inline_capacity())\n            }\n        }\n    }\n\n    /// Returns a tuple with (data ptr, len ptr, capacity)\n    #[inline]\n    fn triple_mut(&mut self) -> (NonNull<A::Item>, &mut usize, usize) {\n        unsafe {\n            if self.spilled() {\n                let (ptr, len_ptr) = self.data.heap_mut();\n                (ptr, len_ptr, self.capacity)\n            } else {\n                (\n                    self.data.inline_mut(),\n                    &mut self.capacity,\n                    Self::inline_capacity(),\n                )\n            }\n        }\n    }\n\n    /// Returns `true` if the data has spilled into a separate heap-allocated\n    /// buffer.\n    #[inline]\n    pub fn spilled(&self) -> bool {\n        self.capacity > Self::inline_capacity()\n    }\n\n    /// Creates a draining iterator that removes the specified range in the\n    /// vector and yields the removed items.\n    ///\n    /// Note 1: The element range is removed even if the iterator is only\n    /// partially consumed or not consumed at all.\n    ///\n    /// Note 2: It is unspecified how many elements are removed from the vector\n    /// if the `Drain` value is leaked.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the starting point is greater than the end point or if\n    /// the end point is greater than the length of the vector.\n    pub fn drain<R>(&mut self, range: R) -> Drain<'_, A>\n    where\n        R: RangeBounds<usize>,\n    {\n        use core::ops::Bound::*;\n\n        let len = self.len();\n        let start = match range.start_bound() {\n            Included(&n) => n,\n            Excluded(&n) => n.checked_add(1).expect(\"Range start out of bounds\"),\n            Unbounded => 0,\n        };\n        let end = match range.end_bound() {\n            Included(&n) => n.checked_add(1).expect(\"Range end out of bounds\"),\n            Excluded(&n) => n,\n            Unbounded => len,\n        };\n\n        assert!(start <= end);\n        assert!(end <= len);\n\n        unsafe {\n            self.set_len(start);\n\n            let range_slice = slice::from_raw_parts(self.as_ptr().add(start), end - start);\n\n            Drain {\n                tail_start: end,\n                tail_len: len - end,\n                iter: range_slice.iter(),\n                // Since self is a &mut, passing it to a function would invalidate the slice\n                // iterator.\n                vec: NonNull::new_unchecked(self as *mut _),\n            }\n        }\n    }\n\n    #[cfg(feature = \"drain_filter\")]\n    /// Creates an iterator which uses a closure to determine if an element\n    /// should be removed.\n    ///\n    /// If the closure returns true, the element is removed and yielded. If the\n    /// closure returns false, the element will remain in the vector and\n    /// will not be yielded by the iterator.\n    ///\n    /// Using this method is equivalent to the following code:\n    /// ```\n    /// # use smallvec::SmallVec;\n    /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };\n    /// # let mut vec: SmallVec<[i32; 8]> = SmallVec::from_slice(&[1i32, 2, 3, 4, 5, 6]);\n    /// let mut i = 0;\n    /// while i < vec.len() {\n    ///     if some_predicate(&mut vec[i]) {\n    ///         let val = vec.remove(i);\n    ///         // your code here\n    ///     } else {\n    ///         i += 1;\n    ///     }\n    /// }\n    ///\n    /// # assert_eq!(vec, SmallVec::<[i32; 8]>::from_slice(&[1i32, 4, 5]));\n    /// ```\n    /// ///\n    /// But `drain_filter` is easier to use. `drain_filter` is also more\n    /// efficient, because it can backshift the elements of the array in\n    /// bulk.\n    ///\n    /// Note that `drain_filter` also lets you mutate every element in the\n    /// filter closure, regardless of whether you choose to keep or remove\n    /// it.\n    ///\n    /// # Examples\n    ///\n    /// Splitting an array into evens and odds, reusing the original allocation:\n    ///\n    /// ```\n    /// # use smallvec::SmallVec;\n    /// let mut numbers: SmallVec<[i32; 16]> =\n    ///     SmallVec::from_slice(&[1i32, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]);\n    ///\n    /// let evens = numbers\n    ///     .drain_filter(|x| *x % 2 == 0)\n    ///     .collect::<SmallVec<[i32; 16]>>();\n    /// let odds = numbers;\n    ///\n    /// assert_eq!(\n    ///     evens,\n    ///     SmallVec::<[i32; 16]>::from_slice(&[2i32, 4, 6, 8, 14])\n    /// );\n    /// assert_eq!(\n    ///     odds,\n    ///     SmallVec::<[i32; 16]>::from_slice(&[1i32, 3, 5, 9, 11, 13, 15])\n    /// );\n    /// ```\n    pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, A, F>\n    where\n        F: FnMut(&mut A::Item) -> bool,\n    {\n        let old_len = self.len();\n\n        // Guard against us getting leaked (leak amplification)\n        unsafe {\n            self.set_len(0);\n        }\n\n        DrainFilter {\n            vec: self,\n            idx: 0,\n            del: 0,\n            old_len,\n            pred: filter,\n            panic_flag: false,\n        }\n    }\n\n    /// Append an item to the vector.\n    #[inline]\n    pub fn push(&mut self, value: A::Item) {\n        unsafe {\n            if self.spilled() {\n                let (mut ptr, mut len_ptr) = self.data.heap_mut();\n                if *len_ptr == self.capacity {\n                    self.reserve_one_unchecked();\n                    let (heap_ptr, heap_len) = self.data.heap_mut();\n                    ptr = heap_ptr;\n                    len_ptr = heap_len;\n                }\n                ptr::write(ptr.as_ptr().add(*len_ptr), value);\n                *len_ptr += 1;\n            } else {\n                let mut ptr = self.data.inline_mut();\n                let mut len_ptr = &mut self.capacity;\n                if *len_ptr == Self::inline_capacity() {\n                    self.reserve_one_unchecked();\n                    let (heap_ptr, heap_len) = self.data.heap_mut();\n                    ptr = heap_ptr;\n                    len_ptr = heap_len;\n                }\n                ptr::write(ptr.as_ptr().add(*len_ptr), value);\n                *len_ptr += 1;\n            };\n        }\n    }\n\n    /// Remove an item from the end of the vector and return it, or None if\n    /// empty.\n    #[inline]\n    pub fn pop(&mut self) -> Option<A::Item> {\n        unsafe {\n            let (ptr, len_ptr, _) = self.triple_mut();\n            let ptr: *const _ = ptr.as_ptr();\n            if *len_ptr == 0 {\n                return None;\n            }\n            let last_index = *len_ptr - 1;\n            *len_ptr = last_index;\n            Some(ptr::read(ptr.add(last_index)))\n        }\n    }\n\n    /// Moves all the elements of `other` into `self`, leaving `other` empty.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use smallvec::{SmallVec, smallvec};\n    /// let mut v0: SmallVec<[u8; 16]> = smallvec![1, 2, 3];\n    /// let mut v1: SmallVec<[u8; 32]> = smallvec![4, 5, 6];\n    /// v0.append(&mut v1);\n    /// assert_eq!(*v0, [1, 2, 3, 4, 5, 6]);\n    /// assert_eq!(*v1, []);\n    /// ```\n    pub fn append<B>(&mut self, other: &mut SmallVec<B>)\n    where\n        B: Array<Item = A::Item>,\n    {\n        self.extend(other.drain(..))\n    }\n\n    /// Re-allocate to set the capacity to `max(new_cap, inline_size())`.\n    ///\n    /// Panics if `new_cap` is less than the vector's length\n    /// or if the capacity computation overflows `usize`.\n    pub fn grow(&mut self, new_cap: usize) {\n        infallible(self.try_grow(new_cap))\n    }\n\n    /// Re-allocate to set the capacity to `max(new_cap, inline_size())`.\n    ///\n    /// Panics if `new_cap` is less than the vector's length\n    pub fn try_grow(&mut self, new_cap: usize) -> Result<(), CollectionAllocErr> {\n        unsafe {\n            let unspilled = !self.spilled();\n            let (ptr, &mut len, cap) = self.triple_mut();\n            assert!(new_cap >= len);\n            if new_cap <= Self::inline_capacity() {\n                if unspilled {\n                    return Ok(());\n                }\n                self.data = SmallVecData::empty();\n                ptr::copy_nonoverlapping(ptr.as_ptr(), self.data.inline_mut().as_ptr(), len);\n                self.capacity = len;\n                deallocate(ptr, cap);\n            } else if new_cap != cap {\n                let layout = layout_array::<A::Item>(new_cap)?;\n                debug_assert!(layout.size() > 0);\n                let new_alloc;\n                if unspilled {\n                    new_alloc = NonNull::new(alloc::alloc::alloc(layout))\n                        .ok_or(CollectionAllocErr::AllocErr { layout })?\n                        .cast();\n                    ptr::copy_nonoverlapping(ptr.as_ptr(), new_alloc.as_ptr(), len);\n                } else {\n                    // This should never fail since the same succeeded\n                    // when previously allocating `ptr`.\n                    let old_layout = layout_array::<A::Item>(cap)?;\n\n                    let new_ptr =\n                        alloc::alloc::realloc(ptr.as_ptr() as *mut u8, old_layout, layout.size());\n                    new_alloc = NonNull::new(new_ptr)\n                        .ok_or(CollectionAllocErr::AllocErr { layout })?\n                        .cast();\n                }\n                self.data = SmallVecData::from_heap(new_alloc, len);\n                self.capacity = new_cap;\n            }\n            Ok(())\n        }\n    }\n\n    /// Reserve capacity for `additional` more elements to be inserted.\n    ///\n    /// May reserve more space to avoid frequent reallocations.\n    ///\n    /// Panics if the capacity computation overflows `usize`.\n    #[inline]\n    pub fn reserve(&mut self, additional: usize) {\n        infallible(self.try_reserve(additional))\n    }\n\n    /// Internal method used to grow in push() and insert(), where we know\n    /// already we have to grow.\n    #[cold]\n    fn reserve_one_unchecked(&mut self) {\n        debug_assert_eq!(self.len(), self.capacity());\n        let new_cap = self\n            .len()\n            .checked_add(1)\n            .and_then(usize::checked_next_power_of_two)\n            .expect(\"capacity overflow\");\n        infallible(self.try_grow(new_cap))\n    }\n\n    /// Reserve capacity for `additional` more elements to be inserted.\n    ///\n    /// May reserve more space to avoid frequent reallocations.\n    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {\n        // prefer triple_mut() even if triple() would work so that the optimizer\n        // removes duplicated calls to it from callers.\n        let (_, &mut len, cap) = self.triple_mut();\n        if cap - len >= additional {\n            return Ok(());\n        }\n        let new_cap = len\n            .checked_add(additional)\n            .and_then(usize::checked_next_power_of_two)\n            .ok_or(CollectionAllocErr::CapacityOverflow)?;\n        self.try_grow(new_cap)\n    }\n\n    /// Reserve the minimum capacity for `additional` more elements to be\n    /// inserted.\n    ///\n    /// Panics if the new capacity overflows `usize`.\n    pub fn reserve_exact(&mut self, additional: usize) {\n        infallible(self.try_reserve_exact(additional))\n    }\n\n    /// Reserve the minimum capacity for `additional` more elements to be\n    /// inserted.\n    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {\n        let (_, &mut len, cap) = self.triple_mut();\n        if cap - len >= additional {\n            return Ok(());\n        }\n        let new_cap = len\n            .checked_add(additional)\n            .ok_or(CollectionAllocErr::CapacityOverflow)?;\n        self.try_grow(new_cap)\n    }\n\n    /// Shrink the capacity of the vector as much as possible.\n    ///\n    /// When possible, this will move data from an external heap buffer to the\n    /// vector's inline storage.\n    pub fn shrink_to_fit(&mut self) {\n        if !self.spilled() {\n            return;\n        }\n        let len = self.len();\n        if self.inline_size() >= len {\n            unsafe {\n                let (ptr, len) = self.data.heap();\n                self.data = SmallVecData::empty();\n                ptr::copy_nonoverlapping(ptr.as_ptr(), self.data.inline_mut().as_ptr(), len);\n                deallocate(ptr.0, self.capacity);\n                self.capacity = len;\n            }\n        } else if self.capacity() > len {\n            self.grow(len);\n        }\n    }\n\n    /// Shorten the vector, keeping the first `len` elements and dropping the\n    /// rest.\n    ///\n    /// If `len` is greater than or equal to the vector's current length, this\n    /// has no effect.\n    ///\n    /// This does not re-allocate.  If you want the vector's capacity to shrink,\n    /// call `shrink_to_fit` after truncating.\n    pub fn truncate(&mut self, len: usize) {\n        unsafe {\n            let (ptr, len_ptr, _) = self.triple_mut();\n            let ptr = ptr.as_ptr();\n            while len < *len_ptr {\n                let last_index = *len_ptr - 1;\n                *len_ptr = last_index;\n                ptr::drop_in_place(ptr.add(last_index));\n            }\n        }\n    }\n\n    /// Extracts a slice containing the entire vector.\n    ///\n    /// Equivalent to `&s[..]`.\n    pub fn as_slice(&self) -> &[A::Item] {\n        self\n    }\n\n    /// Extracts a mutable slice of the entire vector.\n    ///\n    /// Equivalent to `&mut s[..]`.\n    pub fn as_mut_slice(&mut self) -> &mut [A::Item] {\n        self\n    }\n\n    /// Remove the element at position `index`, replacing it with the last\n    /// element.\n    ///\n    /// This does not preserve ordering, but is O(1).\n    ///\n    /// Panics if `index` is out of bounds.\n    #[inline]\n    pub fn swap_remove(&mut self, index: usize) -> A::Item {\n        let len = self.len();\n        self.swap(len - 1, index);\n        self.pop()\n            .unwrap_or_else(|| unsafe { unreachable_unchecked() })\n    }\n\n    /// Remove all elements from the vector.\n    #[inline]\n    pub fn clear(&mut self) {\n        self.truncate(0);\n    }\n\n    /// Remove and return the element at position `index`, shifting all elements\n    /// after it to the left.\n    ///\n    /// Panics if `index` is out of bounds.\n    pub fn remove(&mut self, index: usize) -> A::Item {\n        unsafe {\n            let (ptr, len_ptr, _) = self.triple_mut();\n            let len = *len_ptr;\n            assert!(index < len);\n            *len_ptr = len - 1;\n            let ptr = ptr.as_ptr().add(index);\n            let item = ptr::read(ptr);\n            ptr::copy(ptr.add(1), ptr, len - index - 1);\n            item\n        }\n    }\n\n    /// Insert an element at position `index`, shifting all elements after it to\n    /// the right.\n    ///\n    /// Panics if `index > len`.\n    pub fn insert(&mut self, index: usize, element: A::Item) {\n        unsafe {\n            let (mut ptr, mut len_ptr, cap) = self.triple_mut();\n            if *len_ptr == cap {\n                self.reserve_one_unchecked();\n                let (heap_ptr, heap_len_ptr) = self.data.heap_mut();\n                ptr = heap_ptr;\n                len_ptr = heap_len_ptr;\n            }\n            let mut ptr = ptr.as_ptr();\n            let len = *len_ptr;\n            if index > len {\n                panic!(\"index exceeds length\");\n            }\n            // SAFETY: add is UB if index > len, but we panicked first\n            ptr = ptr.add(index);\n            if index < len {\n                // Shift element to the right of `index`.\n                ptr::copy(ptr, ptr.add(1), len - index);\n            }\n            *len_ptr = len + 1;\n            ptr::write(ptr, element);\n        }\n    }\n\n    /// Insert multiple elements at position `index`, shifting all following\n    /// elements toward the back.\n    pub fn insert_many<I: IntoIterator<Item = A::Item>>(&mut self, index: usize, iterable: I) {\n        let mut iter = iterable.into_iter();\n        if index == self.len() {\n            return self.extend(iter);\n        }\n\n        let (lower_size_bound, _) = iter.size_hint();\n        #[allow(deprecated)]\n        {\n            assert!(lower_size_bound <= core::isize::MAX as usize)\n        } // Ensure offset is indexable\n        assert!(index + lower_size_bound >= index); // Protect against overflow\n\n        let mut num_added = 0;\n        let old_len = self.len();\n        assert!(index <= old_len);\n\n        unsafe {\n            // Reserve space for `lower_size_bound` elements.\n            self.reserve(lower_size_bound);\n            let start = self.as_mut_ptr();\n            let ptr = start.add(index);\n\n            // Move the trailing elements.\n            ptr::copy(ptr, ptr.add(lower_size_bound), old_len - index);\n\n            // In case the iterator panics, don't double-drop the items we just\n            // copied above.\n            self.set_len(0);\n            let mut guard = DropOnPanic {\n                start,\n                skip: index..(index + lower_size_bound),\n                len: old_len + lower_size_bound,\n            };\n\n            // The set_len above invalidates the previous pointers, so we must\n            // re-create them.\n            let start = self.as_mut_ptr();\n            let ptr = start.add(index);\n\n            while num_added < lower_size_bound {\n                let element = match iter.next() {\n                    Some(x) => x,\n                    None => break,\n                };\n                let cur = ptr.add(num_added);\n                ptr::write(cur, element);\n                guard.skip.start += 1;\n                num_added += 1;\n            }\n\n            if num_added < lower_size_bound {\n                // Iterator provided fewer elements than the hint. Move the tail\n                // backward.\n                ptr::copy(\n                    ptr.add(lower_size_bound),\n                    ptr.add(num_added),\n                    old_len - index,\n                );\n            }\n            // There are no more duplicate or uninitialized slots, so the guard\n            // is not needed.\n            self.set_len(old_len + num_added);\n            mem::forget(guard);\n        }\n\n        // Insert any remaining elements one-by-one.\n        for element in iter {\n            self.insert(index + num_added, element);\n            num_added += 1;\n        }\n\n        struct DropOnPanic<T> {\n            start: *mut T,\n            skip: Range<usize>, // Space we copied-out-of, but haven't written-to yet.\n            len: usize,\n        }\n\n        impl<T> Drop for DropOnPanic<T> {\n            fn drop(&mut self) {\n                for i in 0..self.len {\n                    if !self.skip.contains(&i) {\n                        unsafe {\n                            ptr::drop_in_place(self.start.add(i));\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    /// Convert a `SmallVec` to a `Vec`, without reallocating if the `SmallVec`\n    /// has already spilled onto the heap.\n    pub fn into_vec(mut self) -> Vec<A::Item> {\n        if self.spilled() {\n            unsafe {\n                let (ptr, &mut len) = self.data.heap_mut();\n                let v = Vec::from_raw_parts(ptr.as_ptr(), len, self.capacity);\n                mem::forget(self);\n                v\n            }\n        } else {\n            self.into_iter().collect()\n        }\n    }\n\n    /// Converts a `SmallVec` into a `Box<[T]>` without reallocating if the\n    /// `SmallVec` has already spilled onto the heap.\n    ///\n    /// Note that this will drop any excess capacity.\n    pub fn into_boxed_slice(self) -> Box<[A::Item]> {\n        self.into_vec().into_boxed_slice()\n    }\n\n    /// Convert the `SmallVec` into an `A` if possible. Otherwise return\n    /// `Err(Self)`.\n    ///\n    /// This method returns `Err(Self)` if the `SmallVec` is too short (and the\n    /// `A` contains uninitialized elements), or if the `SmallVec` is too\n    /// long (and all the elements were spilled to the heap).\n    pub fn into_inner(self) -> Result<A, Self> {\n        if self.spilled() || self.len() != A::size() {\n            // Note: A::size, not Self::inline_capacity\n            Err(self)\n        } else {\n            unsafe {\n                let data = ptr::read(&self.data);\n                mem::forget(self);\n                Ok(data.into_inline().assume_init())\n            }\n        }\n    }\n\n    /// Retains only the elements specified by the predicate.\n    ///\n    /// In other words, remove all elements `e` such that `f(&e)` returns\n    /// `false`. This method operates in place and preserves the order of\n    /// the retained elements.\n    pub fn retain<F: FnMut(&mut A::Item) -> bool>(&mut self, mut f: F) {\n        let mut del = 0;\n        let len = self.len();\n        for i in 0..len {\n            if !f(&mut self[i]) {\n                del += 1;\n            } else if del > 0 {\n                self.swap(i - del, i);\n            }\n        }\n        self.truncate(len - del);\n    }\n\n    /// Retains only the elements specified by the predicate.\n    ///\n    /// This method is identical in behaviour to [`SmallVec::retain`]; it is\n    /// included only to maintain api-compatibility with `std::Vec`, where\n    /// the methods are separate for historical reasons.\n    pub fn retain_mut<F: FnMut(&mut A::Item) -> bool>(&mut self, f: F) {\n        self.retain(f)\n    }\n\n    /// Removes consecutive duplicate elements.\n    pub fn dedup(&mut self)\n    where\n        A::Item: PartialEq<A::Item>,\n    {\n        self.dedup_by(|a, b| a == b);\n    }\n\n    /// Removes consecutive duplicate elements using the given equality\n    /// relation.\n    pub fn dedup_by<F>(&mut self, mut same_bucket: F)\n    where\n        F: FnMut(&mut A::Item, &mut A::Item) -> bool,\n    {\n        // See the implementation of Vec::dedup_by in the\n        // standard library for an explanation of this algorithm.\n        let len = self.len();\n        if len <= 1 {\n            return;\n        }\n\n        let ptr = self.as_mut_ptr();\n        let mut w: usize = 1;\n\n        unsafe {\n            for r in 1..len {\n                let p_r = ptr.add(r);\n                let p_wm1 = ptr.add(w - 1);\n                if !same_bucket(&mut *p_r, &mut *p_wm1) {\n                    if r != w {\n                        let p_w = p_wm1.add(1);\n                        mem::swap(&mut *p_r, &mut *p_w);\n                    }\n                    w += 1;\n                }\n            }\n        }\n\n        self.truncate(w);\n    }\n\n    /// Removes consecutive elements that map to the same key.\n    pub fn dedup_by_key<F, K>(&mut self, mut key: F)\n    where\n        F: FnMut(&mut A::Item) -> K,\n        K: PartialEq<K>,\n    {\n        self.dedup_by(|a, b| key(a) == key(b));\n    }\n\n    /// Resizes the `SmallVec` in-place so that `len` is equal to `new_len`.\n    ///\n    /// If `new_len` is greater than `len`, the `SmallVec` is extended by the\n    /// difference, with each additional slot filled with the result of\n    /// calling the closure `f`. The return values from `f` will end up in\n    /// the `SmallVec` in the order they have been generated.\n    ///\n    /// If `new_len` is less than `len`, the `SmallVec` is simply truncated.\n    ///\n    /// This method uses a closure to create new values on every push. If you'd\n    /// rather `Clone` a given value, use `resize`. If you want to use the\n    /// `Default` trait to generate values, you can pass\n    /// `Default::default()` as the second argument.\n    ///\n    /// Added for `std::vec::Vec` compatibility (added in Rust 1.33.0)\n    ///\n    /// ```\n    /// # use smallvec::{smallvec, SmallVec};\n    /// let mut vec: SmallVec<[_; 4]> = smallvec![1, 2, 3];\n    /// vec.resize_with(5, Default::default);\n    /// assert_eq!(&*vec, &[1, 2, 3, 0, 0]);\n    ///\n    /// let mut vec: SmallVec<[_; 4]> = smallvec![];\n    /// let mut p = 1;\n    /// vec.resize_with(4, || {\n    ///     p *= 2;\n    ///     p\n    /// });\n    /// assert_eq!(&*vec, &[2, 4, 8, 16]);\n    /// ```\n    pub fn resize_with<F>(&mut self, new_len: usize, f: F)\n    where\n        F: FnMut() -> A::Item,\n    {\n        let old_len = self.len();\n        if old_len < new_len {\n            let mut f = f;\n            let additional = new_len - old_len;\n            self.reserve(additional);\n            for _ in 0..additional {\n                self.push(f());\n            }\n        } else if old_len > new_len {\n            self.truncate(new_len);\n        }\n    }\n\n    /// Creates a `SmallVec` directly from the raw components of another\n    /// `SmallVec`.\n    ///\n    /// # Safety\n    ///\n    /// This is highly unsafe, due to the number of invariants that aren't\n    /// checked:\n    ///\n    /// * `ptr` needs to have been previously allocated via `SmallVec` for its\n    ///   spilled storage (at least, it's highly likely to be incorrect if it\n    ///   wasn't).\n    /// * `ptr`'s `A::Item` type needs to be the same size and alignment that it\n    ///   was allocated with\n    /// * `length` needs to be less than or equal to `capacity`.\n    /// * `capacity` needs to be the capacity that the pointer was allocated\n    ///   with.\n    ///\n    /// Violating these may cause problems like corrupting the allocator's\n    /// internal data structures.\n    ///\n    /// Additionally, `capacity` must be greater than the amount of inline\n    /// storage `A` has; that is, the new `SmallVec` must need to spill over\n    /// into heap allocated storage. This condition is asserted against.\n    ///\n    /// The ownership of `ptr` is effectively transferred to the\n    /// `SmallVec` which may then deallocate, reallocate or change the\n    /// contents of memory pointed to by the pointer at will. Ensure\n    /// that nothing else uses the pointer after calling this\n    /// function.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use smallvec::{smallvec, SmallVec};\n    /// use std::mem;\n    /// use std::ptr;\n    ///\n    /// fn main() {\n    ///     let mut v: SmallVec<[_; 1]> = smallvec![1, 2, 3];\n    ///\n    ///     // Pull out the important parts of `v`.\n    ///     let p = v.as_mut_ptr();\n    ///     let len = v.len();\n    ///     let cap = v.capacity();\n    ///     let spilled = v.spilled();\n    ///\n    ///     unsafe {\n    ///         // Forget all about `v`. The heap allocation that stored the\n    ///         // three values won't be deallocated.\n    ///         mem::forget(v);\n    ///\n    ///         // Overwrite memory with [4, 5, 6].\n    ///         //\n    ///         // This is only safe if `spilled` is true! Otherwise, we are\n    ///         // writing into the old `SmallVec`'s inline storage on the\n    ///         // stack.\n    ///         assert!(spilled);\n    ///         for i in 0..len {\n    ///             ptr::write(p.add(i), 4 + i);\n    ///         }\n    ///\n    ///         // Put everything back together into a SmallVec with a different\n    ///         // amount of inline storage, but which is still less than `cap`.\n    ///         let rebuilt = SmallVec::<[_; 2]>::from_raw_parts(p, len, cap);\n    ///         assert_eq!(&*rebuilt, &[4, 5, 6]);\n    ///     }\n    /// }\n    #[inline]\n    pub unsafe fn from_raw_parts(ptr: *mut A::Item, length: usize, capacity: usize) -> SmallVec<A> {\n        // SAFETY: We require caller to provide same ptr as we alloc\n        // and we never alloc null pointer.\n        let ptr = unsafe {\n            debug_assert!(!ptr.is_null(), \"Called `from_raw_parts` with null pointer.\");\n            NonNull::new_unchecked(ptr)\n        };\n        assert!(capacity > Self::inline_capacity());\n        SmallVec {\n            capacity,\n            data: SmallVecData::from_heap(ptr, length),\n        }\n    }\n\n    /// Returns a raw pointer to the vector's buffer.\n    pub fn as_ptr(&self) -> *const A::Item {\n        // We shadow the slice method of the same name to avoid going through\n        // `deref`, which creates an intermediate reference that may place\n        // additional safety constraints on the contents of the slice.\n        self.triple().0.as_ptr()\n    }\n\n    /// Returns a raw mutable pointer to the vector's buffer.\n    pub fn as_mut_ptr(&mut self) -> *mut A::Item {\n        // We shadow the slice method of the same name to avoid going through\n        // `deref_mut`, which creates an intermediate reference that may place\n        // additional safety constraints on the contents of the slice.\n        self.triple_mut().0.as_ptr()\n    }\n}\n\nimpl<A: Array> SmallVec<A>\nwhere\n    A::Item: Copy,\n{\n    /// Copy the elements from a slice into a new `SmallVec`.\n    ///\n    /// For slices of `Copy` types, this is more efficient than\n    /// `SmallVec::from(slice)`.\n    pub fn from_slice(slice: &[A::Item]) -> Self {\n        let len = slice.len();\n        if len <= Self::inline_capacity() {\n            SmallVec {\n                capacity: len,\n                data: SmallVecData::from_inline(unsafe {\n                    let mut data: MaybeUninit<A> = MaybeUninit::uninit();\n                    ptr::copy_nonoverlapping(\n                        slice.as_ptr(),\n                        data.as_mut_ptr() as *mut A::Item,\n                        len,\n                    );\n                    data\n                }),\n            }\n        } else {\n            let mut b = slice.to_vec();\n            let cap = b.capacity();\n            let ptr = NonNull::new(b.as_mut_ptr()).expect(\"Vec always contain non null pointers.\");\n            mem::forget(b);\n            SmallVec {\n                capacity: cap,\n                data: SmallVecData::from_heap(ptr, len),\n            }\n        }\n    }\n\n    /// Copy elements from a slice into the vector at position `index`, shifting\n    /// any following elements toward the back.\n    ///\n    /// For slices of `Copy` types, this is more efficient than `insert`.\n    #[inline]\n    pub fn insert_from_slice(&mut self, index: usize, slice: &[A::Item]) {\n        self.reserve(slice.len());\n\n        let len = self.len();\n        assert!(index <= len);\n\n        unsafe {\n            let slice_ptr = slice.as_ptr();\n            let ptr = self.as_mut_ptr().add(index);\n            ptr::copy(ptr, ptr.add(slice.len()), len - index);\n            ptr::copy_nonoverlapping(slice_ptr, ptr, slice.len());\n            self.set_len(len + slice.len());\n        }\n    }\n\n    /// Copy elements from a slice and append them to the vector.\n    ///\n    /// For slices of `Copy` types, this is more efficient than `extend`.\n    #[inline]\n    pub fn extend_from_slice(&mut self, slice: &[A::Item]) {\n        let len = self.len();\n        self.insert_from_slice(len, slice);\n    }\n}\n\nimpl<A: Array> SmallVec<A>\nwhere\n    A::Item: Clone,\n{\n    /// Resizes the vector so that its length is equal to `len`.\n    ///\n    /// If `len` is less than the current length, the vector simply truncated.\n    ///\n    /// If `len` is greater than the current length, `value` is appended to the\n    /// vector until its length equals `len`.\n    pub fn resize(&mut self, len: usize, value: A::Item) {\n        let old_len = self.len();\n\n        if len > old_len {\n            self.extend(repeat(value).take(len - old_len));\n        } else {\n            self.truncate(len);\n        }\n    }\n\n    /// Creates a `SmallVec` with `n` copies of `elem`.\n    /// ```\n    /// use smallvec::SmallVec;\n    ///\n    /// let v = SmallVec::<[char; 128]>::from_elem('d', 2);\n    /// assert_eq!(v, SmallVec::from_buf(['d', 'd']));\n    /// ```\n    pub fn from_elem(elem: A::Item, n: usize) -> Self {\n        if n > Self::inline_capacity() {\n            vec![elem; n].into()\n        } else {\n            let mut v = SmallVec::<A>::new();\n            unsafe {\n                let (ptr, len_ptr, _) = v.triple_mut();\n                let ptr = ptr.as_ptr();\n                let mut local_len = SetLenOnDrop::new(len_ptr);\n\n                for i in 0..n {\n                    ::core::ptr::write(ptr.add(i), elem.clone());\n                    local_len.increment_len(1);\n                }\n            }\n            v\n        }\n    }\n}\n\nimpl<A: Array> ops::Deref for SmallVec<A> {\n    type Target = [A::Item];\n    #[inline]\n    fn deref(&self) -> &[A::Item] {\n        unsafe {\n            let (ptr, len, _) = self.triple();\n            slice::from_raw_parts(ptr.as_ptr(), len)\n        }\n    }\n}\n\nimpl<A: Array> ops::DerefMut for SmallVec<A> {\n    #[inline]\n    fn deref_mut(&mut self) -> &mut [A::Item] {\n        unsafe {\n            let (ptr, &mut len, _) = self.triple_mut();\n            slice::from_raw_parts_mut(ptr.as_ptr(), len)\n        }\n    }\n}\n\nimpl<A: Array> AsRef<[A::Item]> for SmallVec<A> {\n    #[inline]\n    fn as_ref(&self) -> &[A::Item] {\n        self\n    }\n}\n\nimpl<A: Array> AsMut<[A::Item]> for SmallVec<A> {\n    #[inline]\n    fn as_mut(&mut self) -> &mut [A::Item] {\n        self\n    }\n}\n\nimpl<A: Array> Borrow<[A::Item]> for SmallVec<A> {\n    #[inline]\n    fn borrow(&self) -> &[A::Item] {\n        self\n    }\n}\n\nimpl<A: Array> BorrowMut<[A::Item]> for SmallVec<A> {\n    #[inline]\n    fn borrow_mut(&mut self) -> &mut [A::Item] {\n        self\n    }\n}\n\n#[cfg(feature = \"write\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"write\")))]\nimpl<A: Array<Item = u8>> io::Write for SmallVec<A> {\n    #[inline]\n    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n        self.extend_from_slice(buf);\n        Ok(buf.len())\n    }\n\n    #[inline]\n    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {\n        self.extend_from_slice(buf);\n        Ok(())\n    }\n\n    #[inline]\n    fn flush(&mut self) -> io::Result<()> {\n        Ok(())\n    }\n}\n\n#[cfg(feature = \"serde\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"serde\")))]\nimpl<A: Array> Serialize for SmallVec<A>\nwhere\n    A::Item: Serialize,\n{\n    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {\n        let mut state = serializer.serialize_seq(Some(self.len()))?;\n        for item in self {\n            state.serialize_element(&item)?;\n        }\n        state.end()\n    }\n}\n\n#[cfg(feature = \"serde\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"serde\")))]\nimpl<'de, A: Array> Deserialize<'de> for SmallVec<A>\nwhere\n    A::Item: Deserialize<'de>,\n{\n    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {\n        deserializer.deserialize_seq(SmallVecVisitor {\n            phantom: PhantomData,\n        })\n    }\n}\n\n#[cfg(feature = \"serde\")]\nstruct SmallVecVisitor<A> {\n    phantom: PhantomData<A>,\n}\n\n#[cfg(feature = \"serde\")]\nimpl<'de, A: Array> Visitor<'de> for SmallVecVisitor<A>\nwhere\n    A::Item: Deserialize<'de>,\n{\n    type Value = SmallVec<A>;\n\n    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n        formatter.write_str(\"a sequence\")\n    }\n\n    fn visit_seq<B>(self, mut seq: B) -> Result<Self::Value, B::Error>\n    where\n        B: SeqAccess<'de>,\n    {\n        use serde::de::Error;\n        let len = seq.size_hint().unwrap_or(0);\n        let mut values = SmallVec::new();\n        values.try_reserve(len).map_err(B::Error::custom)?;\n\n        while let Some(value) = seq.next_element()? {\n            values.push(value);\n        }\n\n        Ok(values)\n    }\n}\n\n#[cfg(feature = \"malloc_size_of\")]\nimpl<A: Array> MallocShallowSizeOf for SmallVec<A> {\n    fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {\n        if self.spilled() {\n            unsafe { ops.malloc_size_of(self.as_ptr()) }\n        } else {\n            0\n        }\n    }\n}\n\n#[cfg(feature = \"malloc_size_of\")]\nimpl<A> MallocSizeOf for SmallVec<A>\nwhere\n    A: Array,\n    A::Item: MallocSizeOf,\n{\n    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {\n        let mut n = self.shallow_size_of(ops);\n        for elem in self.iter() {\n            n += elem.size_of(ops);\n        }\n        n\n    }\n}\n\n#[cfg(feature = \"specialization\")]\ntrait SpecFrom<A: Array, S> {\n    fn spec_from(slice: S) -> SmallVec<A>;\n}\n\n#[cfg(feature = \"specialization\")]\nmod specialization;\n\n#[cfg(feature = \"arbitrary\")]\nmod arbitrary;\n\n#[cfg(feature = \"specialization\")]\nimpl<'a, A: Array> SpecFrom<A, &'a [A::Item]> for SmallVec<A>\nwhere\n    A::Item: Copy,\n{\n    #[inline]\n    fn spec_from(slice: &'a [A::Item]) -> SmallVec<A> {\n        SmallVec::from_slice(slice)\n    }\n}\n\nimpl<'a, A: Array> From<&'a [A::Item]> for SmallVec<A>\nwhere\n    A::Item: Clone,\n{\n    #[cfg(not(feature = \"specialization\"))]\n    #[inline]\n    fn from(slice: &'a [A::Item]) -> SmallVec<A> {\n        slice.iter().cloned().collect()\n    }\n\n    #[cfg(feature = \"specialization\")]\n    #[inline]\n    fn from(slice: &'a [A::Item]) -> SmallVec<A> {\n        SmallVec::spec_from(slice)\n    }\n}\n\nimpl<A: Array> From<Vec<A::Item>> for SmallVec<A> {\n    #[inline]\n    fn from(vec: Vec<A::Item>) -> SmallVec<A> {\n        SmallVec::from_vec(vec)\n    }\n}\n\nimpl<A: Array> From<A> for SmallVec<A> {\n    #[inline]\n    fn from(array: A) -> SmallVec<A> {\n        SmallVec::from_buf(array)\n    }\n}\n\nimpl<A: Array, I: SliceIndex<[A::Item]>> ops::Index<I> for SmallVec<A> {\n    type Output = I::Output;\n\n    fn index(&self, index: I) -> &I::Output {\n        &(**self)[index]\n    }\n}\n\nimpl<A: Array, I: SliceIndex<[A::Item]>> ops::IndexMut<I> for SmallVec<A> {\n    fn index_mut(&mut self, index: I) -> &mut I::Output {\n        &mut (&mut **self)[index]\n    }\n}\n\n#[allow(deprecated)]\nimpl<A: Array> ExtendFromSlice<A::Item> for SmallVec<A>\nwhere\n    A::Item: Copy,\n{\n    fn extend_from_slice(&mut self, other: &[A::Item]) {\n        SmallVec::extend_from_slice(self, other)\n    }\n}\n\nimpl<A: Array> FromIterator<A::Item> for SmallVec<A> {\n    #[inline]\n    fn from_iter<I: IntoIterator<Item = A::Item>>(iterable: I) -> SmallVec<A> {\n        let mut v = SmallVec::new();\n        v.extend(iterable);\n        v\n    }\n}\n\nimpl<A: Array> Extend<A::Item> for SmallVec<A> {\n    fn extend<I: IntoIterator<Item = A::Item>>(&mut self, iterable: I) {\n        let mut iter = iterable.into_iter();\n        let (lower_size_bound, _) = iter.size_hint();\n        self.reserve(lower_size_bound);\n\n        unsafe {\n            let (ptr, len_ptr, cap) = self.triple_mut();\n            let ptr = ptr.as_ptr();\n            let mut len = SetLenOnDrop::new(len_ptr);\n            while len.get() < cap {\n                if let Some(out) = iter.next() {\n                    ptr::write(ptr.add(len.get()), out);\n                    len.increment_len(1);\n                } else {\n                    return;\n                }\n            }\n        }\n\n        for elem in iter {\n            self.push(elem);\n        }\n    }\n}\n\nimpl<A: Array> fmt::Debug for SmallVec<A>\nwhere\n    A::Item: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_list().entries(self.iter()).finish()\n    }\n}\n\nimpl<A: Array> Default for SmallVec<A> {\n    #[inline]\n    fn default() -> SmallVec<A> {\n        SmallVec::new()\n    }\n}\n\n#[cfg(feature = \"may_dangle\")]\nunsafe impl<#[may_dangle] A: Array> Drop for SmallVec<A> {\n    fn drop(&mut self) {\n        unsafe {\n            if self.spilled() {\n                let (ptr, &mut len) = self.data.heap_mut();\n                Vec::from_raw_parts(ptr.as_ptr(), len, self.capacity);\n            } else {\n                ptr::drop_in_place(&mut self[..]);\n            }\n        }\n    }\n}\n\n#[cfg(not(feature = \"may_dangle\"))]\nimpl<A: Array> Drop for SmallVec<A> {\n    fn drop(&mut self) {\n        unsafe {\n            if self.spilled() {\n                let (ptr, &mut len) = self.data.heap_mut();\n                drop(Vec::from_raw_parts(ptr.as_ptr(), len, self.capacity));\n            } else {\n                ptr::drop_in_place(&mut self[..]);\n            }\n        }\n    }\n}\n\nimpl<A: Array> Clone for SmallVec<A>\nwhere\n    A::Item: Clone,\n{\n    #[inline]\n    fn clone(&self) -> SmallVec<A> {\n        SmallVec::from(self.as_slice())\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        // Inspired from `impl Clone for Vec`.\n\n        // drop anything that will not be overwritten\n        self.truncate(source.len());\n\n        // self.len <= other.len due to the truncate above, so the\n        // slices here are always in-bounds.\n        let (init, tail) = source.split_at(self.len());\n\n        // reuse the contained values' allocations/resources.\n        self.clone_from_slice(init);\n        self.extend(tail.iter().cloned());\n    }\n}\n\nimpl<A: Array, B: Array> PartialEq<SmallVec<B>> for SmallVec<A>\nwhere\n    A::Item: PartialEq<B::Item>,\n{\n    #[inline]\n    fn eq(&self, other: &SmallVec<B>) -> bool {\n        self[..] == other[..]\n    }\n}\n\nimpl<A: Array> Eq for SmallVec<A> where A::Item: Eq {}\n\nimpl<A: Array> PartialOrd for SmallVec<A>\nwhere\n    A::Item: PartialOrd,\n{\n    #[inline]\n    fn partial_cmp(&self, other: &SmallVec<A>) -> Option<cmp::Ordering> {\n        PartialOrd::partial_cmp(&**self, &**other)\n    }\n}\n\nimpl<A: Array> Ord for SmallVec<A>\nwhere\n    A::Item: Ord,\n{\n    #[inline]\n    fn cmp(&self, other: &SmallVec<A>) -> cmp::Ordering {\n        Ord::cmp(&**self, &**other)\n    }\n}\n\nimpl<A: Array> Hash for SmallVec<A>\nwhere\n    A::Item: Hash,\n{\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        (**self).hash(state)\n    }\n}\n\nunsafe impl<A: Array> Send for SmallVec<A> where A::Item: Send {}\n\n/// An iterator that consumes a `SmallVec` and yields its items by value.\n///\n/// Returned from [`SmallVec::into_iter`][1].\n///\n/// [1]: struct.SmallVec.html#method.into_iter\npub struct IntoIter<A: Array> {\n    data: SmallVec<A>,\n    current: usize,\n    end: usize,\n}\n\nimpl<A: Array> fmt::Debug for IntoIter<A>\nwhere\n    A::Item: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_tuple(\"IntoIter\").field(&self.as_slice()).finish()\n    }\n}\n\nimpl<A: Array + Clone> Clone for IntoIter<A>\nwhere\n    A::Item: Clone,\n{\n    fn clone(&self) -> IntoIter<A> {\n        SmallVec::from(self.as_slice()).into_iter()\n    }\n}\n\nimpl<A: Array> Drop for IntoIter<A> {\n    fn drop(&mut self) {\n        for _ in self {}\n    }\n}\n\nimpl<A: Array> Iterator for IntoIter<A> {\n    type Item = A::Item;\n\n    #[inline]\n    fn next(&mut self) -> Option<A::Item> {\n        if self.current == self.end {\n            None\n        } else {\n            unsafe {\n                let current = self.current;\n                self.current += 1;\n                Some(ptr::read(self.data.as_ptr().add(current)))\n            }\n        }\n    }\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let size = self.end - self.current;\n        (size, Some(size))\n    }\n}\n\nimpl<A: Array> DoubleEndedIterator for IntoIter<A> {\n    #[inline]\n    fn next_back(&mut self) -> Option<A::Item> {\n        if self.current == self.end {\n            None\n        } else {\n            unsafe {\n                self.end -= 1;\n                Some(ptr::read(self.data.as_ptr().add(self.end)))\n            }\n        }\n    }\n}\n\nimpl<A: Array> ExactSizeIterator for IntoIter<A> {}\nimpl<A: Array> FusedIterator for IntoIter<A> {}\n\nimpl<A: Array> IntoIter<A> {\n    /// Returns the remaining items of this iterator as a slice.\n    pub fn as_slice(&self) -> &[A::Item] {\n        let len = self.end - self.current;\n        unsafe { core::slice::from_raw_parts(self.data.as_ptr().add(self.current), len) }\n    }\n\n    /// Returns the remaining items of this iterator as a mutable slice.\n    pub fn as_mut_slice(&mut self) -> &mut [A::Item] {\n        let len = self.end - self.current;\n        unsafe { core::slice::from_raw_parts_mut(self.data.as_mut_ptr().add(self.current), len) }\n    }\n}\n\nimpl<A: Array> IntoIterator for SmallVec<A> {\n    type IntoIter = IntoIter<A>;\n    type Item = A::Item;\n    fn into_iter(mut self) -> Self::IntoIter {\n        unsafe {\n            // Set SmallVec len to zero as `IntoIter` drop handles dropping of\n            // the elements\n            let len = self.len();\n            self.set_len(0);\n            IntoIter {\n                data: self,\n                current: 0,\n                end: len,\n            }\n        }\n    }\n}\n\nimpl<'a, A: Array> IntoIterator for &'a SmallVec<A> {\n    type IntoIter = slice::Iter<'a, A::Item>;\n    type Item = &'a A::Item;\n    fn into_iter(self) -> Self::IntoIter {\n        self.iter()\n    }\n}\n\nimpl<'a, A: Array> IntoIterator for &'a mut SmallVec<A> {\n    type IntoIter = slice::IterMut<'a, A::Item>;\n    type Item = &'a mut A::Item;\n    fn into_iter(self) -> Self::IntoIter {\n        self.iter_mut()\n    }\n}\n\n/// Types that can be used as the backing store for a [`SmallVec`].\npub unsafe trait Array {\n    /// The type of the array's elements.\n    type Item;\n    /// Returns the number of items the array can hold.\n    fn size() -> usize;\n}\n\n/// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.\n///\n/// Copied from <https://github.com/rust-lang/rust/pull/36355>\nstruct SetLenOnDrop<'a> {\n    len: &'a mut usize,\n    local_len: usize,\n}\n\nimpl<'a> SetLenOnDrop<'a> {\n    #[inline]\n    fn new(len: &'a mut usize) -> Self {\n        SetLenOnDrop {\n            local_len: *len,\n            len,\n        }\n    }\n\n    #[inline]\n    fn get(&self) -> usize {\n        self.local_len\n    }\n\n    #[inline]\n    fn increment_len(&mut self, increment: usize) {\n        self.local_len += increment;\n    }\n}\n\nimpl<'a> Drop for SetLenOnDrop<'a> {\n    #[inline]\n    fn drop(&mut self) {\n        *self.len = self.local_len;\n    }\n}\n\n#[cfg(feature = \"const_new\")]\nimpl<T, const N: usize> SmallVec<[T; N]> {\n    /// Construct an empty vector.\n    ///\n    /// This is a `const` version of [`SmallVec::new`] that is enabled by the\n    /// feature `const_new`, with the limitation that it only works for arrays.\n    #[cfg_attr(docsrs, doc(cfg(feature = \"const_new\")))]\n    #[inline]\n    pub const fn new_const() -> Self {\n        SmallVec {\n            capacity: 0,\n            data: SmallVecData::from_const(MaybeUninit::uninit()),\n        }\n    }\n\n    /// The array passed as an argument is moved to be an inline version of\n    /// `SmallVec`.\n    ///\n    /// This is a `const` version of [`SmallVec::from_buf`] that is enabled by\n    /// the feature `const_new`, with the limitation that it only works for\n    /// arrays.\n    #[cfg_attr(docsrs, doc(cfg(feature = \"const_new\")))]\n    #[inline]\n    pub const fn from_const(items: [T; N]) -> Self {\n        SmallVec {\n            capacity: N,\n            data: SmallVecData::from_const(MaybeUninit::new(items)),\n        }\n    }\n\n    /// Constructs a new `SmallVec` on the stack from an array without\n    /// copying elements. Also sets the length. The user is responsible\n    /// for ensuring that `len <= N`.\n    ///\n    /// This is a `const` version of [`SmallVec::from_buf_and_len_unchecked`]\n    /// that is enabled by the feature `const_new`, with the limitation that it\n    /// only works for arrays.\n    #[cfg_attr(docsrs, doc(cfg(feature = \"const_new\")))]\n    #[inline]\n    pub const unsafe fn from_const_with_len_unchecked(items: [T; N], len: usize) -> Self {\n        SmallVec {\n            capacity: len,\n            data: SmallVecData::from_const(MaybeUninit::new(items)),\n        }\n    }\n}\n\n#[cfg(feature = \"const_generics\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"const_generics\")))]\nunsafe impl<T, const N: usize> Array for [T; N] {\n    type Item = T;\n    #[inline]\n    fn size() -> usize {\n        N\n    }\n}\n\n#[cfg(not(feature = \"const_generics\"))]\nmacro_rules! impl_array(\n    ($($size:expr),+) => {\n        $(\n            unsafe impl<T> Array for [T; $size] {\n                type Item = T;\n                #[inline]\n                fn size() -> usize { $size }\n            }\n        )+\n    }\n);\n\n#[cfg(not(feature = \"const_generics\"))]\nimpl_array!(\n    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,\n    26, 27, 28, 29, 30, 31, 32, 36, 0x40, 0x60, 0x80, 0x100, 0x200, 0x400, 0x600, 0x800, 0x1000,\n    0x2000, 0x4000, 0x6000, 0x8000, 0x10000, 0x20000, 0x40000, 0x60000, 0x80000, 0x10_0000\n);\n\n/// Convenience trait for constructing a `SmallVec`\npub trait ToSmallVec<A: Array> {\n    /// Construct a new `SmallVec` from a slice.\n    fn to_smallvec(&self) -> SmallVec<A>;\n}\n\nimpl<A: Array> ToSmallVec<A> for [A::Item]\nwhere\n    A::Item: Copy,\n{\n    #[inline]\n    fn to_smallvec(&self) -> SmallVec<A> {\n        SmallVec::from_slice(self)\n    }\n}\n\n// Immutable counterpart for `NonNull<T>`.\n#[repr(transparent)]\nstruct ConstNonNull<T>(NonNull<T>);\n\nimpl<T> ConstNonNull<T> {\n    #[inline]\n    fn new(ptr: *const T) -> Option<Self> {\n        NonNull::new(ptr as *mut T).map(Self)\n    }\n    #[inline]\n    fn as_ptr(self) -> *const T {\n        self.0.as_ptr()\n    }\n}\n\nimpl<T> Clone for ConstNonNull<T> {\n    #[inline]\n    fn clone(&self) -> Self {\n        *self\n    }\n}\n\nimpl<T> Copy for ConstNonNull<T> {}\n\n#[cfg(feature = \"impl_bincode\")]\nuse bincode::{\n    de::{read::Reader, BorrowDecoder, Decode, Decoder},\n    enc::{write::Writer, Encode, Encoder},\n    error::{DecodeError, EncodeError},\n    BorrowDecode,\n};\n\n#[cfg(feature = \"impl_bincode\")]\nimpl<A, Context> Decode<Context> for SmallVec<A>\nwhere\n    A: Array,\n    A::Item: Decode<Context>,\n{\n    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {\n        use core::convert::TryInto;\n        let len = u64::decode(decoder)?;\n        let len = len\n            .try_into()\n            .map_err(|_| DecodeError::OutsideUsizeRange(len))?;\n        decoder.claim_container_read::<A::Item>(len)?;\n\n        let mut vec = SmallVec::with_capacity(len);\n        if unty::type_equal::<A::Item, u8>() {\n            // Initialize the smallvec's buffer.  Note that we need to do this\n            // through the raw pointer as we cannot name the type\n            // [u8; N] even though A::Item is u8.\n            let ptr = vec.as_mut_ptr();\n            // SAFETY: A::Item is u8 and the smallvec has been allocated with\n            // enough capacity\n            unsafe {\n                core::ptr::write_bytes(ptr, 0, len);\n                vec.set_len(len);\n            }\n            // Read the data into the smallvec's buffer.\n            let slice = vec.as_mut_slice();\n            // SAFETY: A::Item is u8\n            let slice = unsafe { core::mem::transmute::<&mut [A::Item], &mut [u8]>(slice) };\n            decoder.reader().read(slice)?;\n        } else {\n            for _ in 0..len {\n                decoder.unclaim_bytes_read(core::mem::size_of::<A::Item>());\n                vec.push(A::Item::decode(decoder)?);\n            }\n        }\n        Ok(vec)\n    }\n}\n\n#[cfg(feature = \"impl_bincode\")]\nimpl<'de, A, Context> BorrowDecode<'de, Context> for SmallVec<A>\nwhere\n    A: Array,\n    A::Item: BorrowDecode<'de, Context>,\n{\n    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(\n        decoder: &mut D,\n    ) -> Result<Self, DecodeError> {\n        use core::convert::TryInto;\n        let len = u64::decode(decoder)?;\n        let len = len\n            .try_into()\n            .map_err(|_| DecodeError::OutsideUsizeRange(len))?;\n        decoder.claim_container_read::<A::Item>(len)?;\n\n        let mut vec = SmallVec::with_capacity(len);\n        if unty::type_equal::<A::Item, u8>() {\n            // Initialize the smallvec's buffer.  Note that we need to do this\n            // through the raw pointer as we cannot name the type\n            // [u8; N] even though A::Item is u8.\n            let ptr = vec.as_mut_ptr();\n            // SAFETY: A::Item is u8 and the smallvec has been allocated with\n            // enough capacity\n            unsafe {\n                core::ptr::write_bytes(ptr, 0, len);\n                vec.set_len(len);\n            }\n            // Read the data into the smallvec's buffer.\n            let slice = vec.as_mut_slice();\n            // SAFETY: A::Item is u8\n            let slice = unsafe { core::mem::transmute::<&mut [A::Item], &mut [u8]>(slice) };\n            decoder.reader().read(slice)?;\n        } else {\n            for _ in 0..len {\n                decoder.unclaim_bytes_read(core::mem::size_of::<A::Item>());\n                vec.push(A::Item::borrow_decode(decoder)?);\n            }\n        }\n        Ok(vec)\n    }\n}\n\n#[cfg(feature = \"impl_bincode\")]\nimpl<A> Encode for SmallVec<A>\nwhere\n    A: Array,\n    A::Item: Encode,\n{\n    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {\n        (self.len() as u64).encode(encoder)?;\n        if unty::type_equal::<A::Item, u8>() {\n            // Safety: A::Item is u8\n            let slice: &[u8] = unsafe { core::mem::transmute(self.as_slice()) };\n            encoder.writer().write(slice)?;\n        } else {\n            for item in self.iter() {\n                item.encode(encoder)?;\n            }\n        }\n        Ok(())\n    }\n}\n"
    },
    {
      "package": "smallvec@1.16.1",
      "sourcePath": "src/specialization.rs",
      "sha256": "46433586203399251cba496d67b88d34e1be3c2b591986b77463513da1c66471",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Implementations that require `default fn`.\n\nuse super::{Array, SmallVec, SpecFrom};\n\nimpl<'a, A: Array> SpecFrom<A, &'a [A::Item]> for SmallVec<A>\nwhere\n    A::Item: Clone,\n{\n    #[inline]\n    default fn spec_from(slice: &'a [A::Item]) -> SmallVec<A> {\n        slice.into_iter().cloned().collect()\n    }\n}\n"
    },
    {
      "package": "svgtypes@0.11.0",
      "sourcePath": "README.md",
      "sha256": "4c84903e4a242563e6f703ae6ee1fd06c0318fc1ee0edcff0a85a14641facd8c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "## svgtypes\n![Build Status](https://github.com/RazrFalcon/svgtypes/workflows/svgtypes/badge.svg)\n[![Crates.io](https://img.shields.io/crates/v/svgtypes.svg)](https://crates.io/crates/svgtypes)\n[![Documentation](https://docs.rs/svgtypes/badge.svg)](https://docs.rs/svgtypes)\n[![Rust 1.65+](https://img.shields.io/badge/rust-1.65+-orange.svg)](https://www.rust-lang.org)\n![](https://img.shields.io/badge/unsafe-forbidden-brightgreen.svg)\n\n*svgtypes* is a collection of parsers for [SVG](https://www.w3.org/TR/SVG2/) types.\n\n### Supported SVG types\n\n- [`<color>`](https://www.w3.org/TR/css-color-3/)\n- [`<number>`](https://www.w3.org/TR/SVG2/types.html#InterfaceSVGNumber)\n- [`<length>`](https://www.w3.org/TR/SVG2/types.html#InterfaceSVGLength)\n- [`<angle>`](https://www.w3.org/TR/SVG2/types.html#InterfaceSVGAngle)\n- [`<viewBox>`](https://www.w3.org/TR/SVG2/coords.html#ViewBoxAttribute)\n- [`<path>`](https://www.w3.org/TR/SVG2/paths.html#PathData)\n- [`<transform>`](https://www.w3.org/TR/SVG11/types.html#DataTypeTransformList)\n- [`<list-of-numbers>`](https://www.w3.org/TR/SVG2/types.html#InterfaceSVGNumberList)\n- [`<list-of-lengths>`](https://www.w3.org/TR/SVG2/types.html#InterfaceSVGLengthList)\n- [`<list-of-points>`](https://www.w3.org/TR/SVG11/shapes.html#PointsBNF)\n- [`<filter-value-list>`](https://www.w3.org/TR/filter-effects-1/#typedef-filter-value-list)\n- [`<paint>`](https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint)\n- [`<preserveAspectRatio>`](https://www.w3.org/TR/SVG11/coords.html#PreserveAspectRatioAttribute)\n- [`<enable-background>`](https://www.w3.org/TR/SVG11/filters.html#EnableBackgroundProperty)\n- [`<IRI>`](https://www.w3.org/TR/SVG11/types.html#DataTypeIRI)\n- [`<FuncIRI>`](https://www.w3.org/TR/SVG11/types.html#DataTypeFuncIRI)\n- [`paint-order`](https://www.w3.org/TR/SVG2/painting.html#PaintOrder)\n\n### Features\n\n- Complete support of paths, so data like `M10-20A5.5.3-4 110-.1` will be parsed correctly.\n- Implicit path commands will be automatically converted into explicit one.\n- Some SVG2 data types support.\n- Pretty fast.\n\n### Limitations\n\n- Accepts only [normalized](https://www.w3.org/TR/REC-xml/#AVNormalize) values,\n  e.g. an input text should not contain `&#x20;` or `&data;`.\n- All keywords must be lowercase.\n  Case-insensitive parsing is supported only for colors (requires allocation for named colors).\n- The `<color>` followed by the `<icccolor>` is not supported. As the `<icccolor>` itself.\n- [System colors](https://www.w3.org/TR/css3-color/#css2-system), like `fill=\"AppWorkspace\"`,\n  are not supported. They were deprecated anyway.\n\n### Safety\n\n- The library should not panic. Any panic considered as a critical bug and should be reported.\n- The library forbids unsafe code.\n\n### Alternatives\n\nNone.\n\n### License\n\nLicensed under either of\n\n- Apache License, Version 2.0\n  ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license\n  ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "svgtypes@0.14.0",
      "sourcePath": "README.md",
      "sha256": "6370a2a7fc140bbe84261103248bcf94a1daf4ddf71b475501c9c28016399a9d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "## svgtypes\n![Build Status](https://github.com/RazrFalcon/svgtypes/workflows/svgtypes/badge.svg)\n[![Crates.io](https://img.shields.io/crates/v/svgtypes.svg)](https://crates.io/crates/svgtypes)\n[![Documentation](https://docs.rs/svgtypes/badge.svg)](https://docs.rs/svgtypes)\n[![Rust 1.65+](https://img.shields.io/badge/rust-1.65+-orange.svg)](https://www.rust-lang.org)\n![](https://img.shields.io/badge/unsafe-forbidden-brightgreen.svg)\n\n*svgtypes* is a collection of parsers for [SVG](https://www.w3.org/TR/SVG2/) types.\n\n### Supported SVG types\n\n- [`<color>`](https://www.w3.org/TR/css-color-3/)\n- [`<number>`](https://www.w3.org/TR/SVG2/types.html#InterfaceSVGNumber)\n- [`<length>`](https://www.w3.org/TR/SVG2/types.html#InterfaceSVGLength)\n- [`<angle>`](https://www.w3.org/TR/SVG2/types.html#InterfaceSVGAngle)\n- [`<viewBox>`](https://www.w3.org/TR/SVG2/coords.html#ViewBoxAttribute)\n- [`<path>`](https://www.w3.org/TR/SVG2/paths.html#PathData)\n- [`<transform>`](https://www.w3.org/TR/SVG11/types.html#DataTypeTransformList)\n- [`transform-origin`](https://drafts.csswg.org/css-transforms/#transform-origin-property)\n- [`<list-of-numbers>`](https://www.w3.org/TR/SVG2/types.html#InterfaceSVGNumberList)\n- [`<list-of-lengths>`](https://www.w3.org/TR/SVG2/types.html#InterfaceSVGLengthList)\n- [`<list-of-points>`](https://www.w3.org/TR/SVG11/shapes.html#PointsBNF)\n- [`<filter-value-list>`](https://www.w3.org/TR/filter-effects-1/#typedef-filter-value-list)\n- [`<paint>`](https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint)\n- [`<preserveAspectRatio>`](https://www.w3.org/TR/SVG11/coords.html#PreserveAspectRatioAttribute)\n- [`<enable-background>`](https://www.w3.org/TR/SVG11/filters.html#EnableBackgroundProperty)\n- [`<IRI>`](https://www.w3.org/TR/SVG11/types.html#DataTypeIRI)\n- [`<FuncIRI>`](https://www.w3.org/TR/SVG11/types.html#DataTypeFuncIRI)\n- [`paint-order`](https://www.w3.org/TR/SVG2/painting.html#PaintOrder)\n- [`<font-family>`](https://www.w3.org/TR/2018/REC-css-fonts-3-20180920/#font-family-prop)\n- [`font`](https://www.w3.org/TR/css-fonts-3/#font-prop)\n\n### Features\n\n- Complete support of paths, so data like `M10-20A5.5.3-4 110-.1` will be parsed correctly.\n- Implicit path commands will be automatically converted into explicit one.\n- Some SVG2 data types support.\n- Pretty fast.\n\n### Limitations\n\n- Accepts only [normalized](https://www.w3.org/TR/REC-xml/#AVNormalize) values,\n  e.g. an input text should not contain `&#x20;` or `&data;`.\n- All keywords must be lowercase.\n  Case-insensitive parsing is supported only for colors (requires allocation for named colors).\n- The `<color>` followed by the `<icccolor>` is not supported. As the `<icccolor>` itself.\n- [System colors](https://www.w3.org/TR/css3-color/#css2-system), like `fill=\"AppWorkspace\"`,\n  are not supported. They were deprecated anyway.\n\n### Safety\n\n- The library should not panic. Any panic considered as a critical bug and should be reported.\n- The library forbids unsafe code.\n\n### Alternatives\n\nNone.\n\n### License\n\nLicensed under either of\n\n- Apache License, Version 2.0\n  ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license\n  ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "syn@2.0.119",
      "sourcePath": "README.md",
      "sha256": "4a050aa3ee831ad3d27ab15d9b612bb32712f86517fa2e6be0b1cac37137ebe5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Parser for Rust source code\n===========================\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/syn-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/syn)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/syn.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/syn)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-syn-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/syn)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/syn/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/syn/actions?query=branch%3Amaster)\n\nSyn is a parsing library for parsing a stream of Rust tokens into a syntax tree\nof Rust source code.\n\nCurrently this library is geared toward use in Rust procedural macros, but\ncontains some APIs that may be useful more generally.\n\n- **Data structures** — Syn provides a complete syntax tree that can represent\n  any valid Rust source code. The syntax tree is rooted at [`syn::File`] which\n  represents a full source file, but there are other entry points that may be\n  useful to procedural macros including [`syn::Item`], [`syn::Expr`] and\n  [`syn::Type`].\n\n- **Derives** — Of particular interest to derive macros is [`syn::DeriveInput`]\n  which is any of the three legal input items to a derive macro. An example\n  below shows using this type in a library that can derive implementations of a\n  user-defined trait.\n\n- **Parsing** — Parsing in Syn is built around [parser functions] with the\n  signature `fn(ParseStream) -> Result<T>`. Every syntax tree node defined by\n  Syn is individually parsable and may be used as a building block for custom\n  syntaxes, or you may dream up your own brand new syntax without involving any\n  of our syntax tree types.\n\n- **Location information** — Every token parsed by Syn is associated with a\n  `Span` that tracks line and column information back to the source of that\n  token. These spans allow a procedural macro to display detailed error messages\n  pointing to all the right places in the user's code. There is an example of\n  this below.\n\n- **Feature flags** — Functionality is aggressively feature gated so your\n  procedural macros enable only what they need, and do not pay in compile time\n  for all the rest.\n\n[`syn::File`]: https://docs.rs/syn/2.0/syn/struct.File.html\n[`syn::Item`]: https://docs.rs/syn/2.0/syn/enum.Item.html\n[`syn::Expr`]: https://docs.rs/syn/2.0/syn/enum.Expr.html\n[`syn::Type`]: https://docs.rs/syn/2.0/syn/enum.Type.html\n[`syn::DeriveInput`]: https://docs.rs/syn/2.0/syn/struct.DeriveInput.html\n[parser functions]: https://docs.rs/syn/2.0/syn/parse/index.html\n\n[*Release notes*](https://github.com/dtolnay/syn/releases)\n\n<br>\n\n## Resources\n\nThe best way to learn about procedural macros is by writing some. Consider\nworking through [this procedural macro workshop][workshop] to get familiar with\nthe different types of procedural macros. The workshop contains relevant links\ninto the Syn documentation as you work through each project.\n\n[workshop]: https://github.com/dtolnay/proc-macro-workshop\n\n<br>\n\n## Example of a derive macro\n\nThe canonical derive macro using Syn looks like this. We write an ordinary Rust\nfunction tagged with a `proc_macro_derive` attribute and the name of the trait\nwe are deriving. Any time that derive appears in the user's code, the Rust\ncompiler passes their data structure as tokens into our macro. We get to execute\narbitrary Rust code to figure out what to do with those tokens, then hand some\ntokens back to the compiler to compile into the user's crate.\n\n[`TokenStream`]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html\n\n```toml\n[dependencies]\nsyn = \"2.0\"\nquote = \"1.0\"\n\n[lib]\nproc-macro = true\n```\n\n```rust\nuse proc_macro::TokenStream;\nuse quote::quote;\nuse syn::{parse_macro_input, DeriveInput};\n\n#[proc_macro_derive(MyMacro)]\npub fn my_macro(input: TokenStream) -> TokenStream {\n    // Parse the input tokens into a syntax tree\n    let input = parse_macro_input!(input as DeriveInput);\n\n    // Build the output, possibly using quasi-quotation\n    let expanded = quote! {\n        // ...\n    };\n\n    // Hand the output tokens back to the compiler\n    TokenStream::from(expanded)\n}\n```\n\nThe [`heapsize`] example directory shows a complete working implementation of a\nderive macro. The example derives a `HeapSize` trait which computes an estimate\nof the amount of heap memory owned by a value.\n\n[`heapsize`]: examples/heapsize\n\n```rust\npub trait HeapSize {\n    /// Total number of bytes of heap memory owned by `self`.\n    fn heap_size_of_children(&self) -> usize;\n}\n```\n\nThe derive macro allows users to write `#[derive(HeapSize)]` on data structures\nin their program.\n\n```rust\n#[derive(HeapSize)]\nstruct Demo<'a, T: ?Sized> {\n    a: Box<T>,\n    b: u8,\n    c: &'a str,\n    d: String,\n}\n```\n\n<br>\n\n## Spans and error reporting\n\nThe token-based procedural macro API provides great control over where the\ncompiler's error messages are displayed in user code. Consider the error the\nuser sees if one of their field types does not implement `HeapSize`.\n\n```rust\n#[derive(HeapSize)]\nstruct Broken {\n    ok: String,\n    bad: std::thread::Thread,\n}\n```\n\nBy tracking span information all the way through the expansion of a procedural\nmacro as shown in the `heapsize` example, token-based macros in Syn are able to\ntrigger errors that directly pinpoint the source of the problem.\n\n```console\nerror[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied\n --> src/main.rs:7:5\n  |\n7 |     bad: std::thread::Thread,\n  |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `std::thread::Thread`\n```\n\n<br>\n\n## Parsing a custom syntax\n\nThe [`lazy-static`] example directory shows the implementation of a\n`functionlike!(...)` procedural macro in which the input tokens are parsed using\nSyn's parsing API.\n\n[`lazy-static`]: examples/lazy-static\n\nThe example reimplements the popular `lazy_static` crate from crates.io as a\nprocedural macro.\n\n```rust\nlazy_static! {\n    static ref USERNAME: Regex = Regex::new(\"^[a-z0-9_-]{3,16}$\").unwrap();\n}\n```\n\nThe implementation shows how to trigger custom warnings and error messages on\nthe macro input.\n\n```console\nwarning: come on, pick a more creative name\n  --> src/main.rs:10:16\n   |\n10 |     static ref FOO: String = \"lazy_static\".to_owned();\n   |                ^^^\n```\n\n<br>\n\n## Testing\n\nWhen testing macros, we often care not just that the macro can be used\nsuccessfully but also that when the macro is provided with invalid input it\nproduces maximally helpful error messages. Consider using the [`trybuild`] crate\nto write tests for errors that are emitted by your macro or errors detected by\nthe Rust compiler in the expanded code following misuse of the macro. Such tests\nhelp avoid regressions from later refactors that mistakenly make an error no\nlonger trigger or be less helpful than it used to be.\n\n[`trybuild`]: https://github.com/dtolnay/trybuild\n\n<br>\n\n## Debugging\n\nWhen developing a procedural macro it can be helpful to look at what the\ngenerated code looks like. Use `cargo rustc -- -Zunstable-options\n-Zunpretty=expanded` or the [`cargo expand`] subcommand.\n\n[`cargo expand`]: https://github.com/dtolnay/cargo-expand\n\nTo show the expanded code for some crate that uses your procedural macro, run\n`cargo expand` from that crate. To show the expanded code for one of your own\ntest cases, run `cargo expand --test the_test_case` where the last argument is\nthe name of the test file without the `.rs` extension.\n\nThis write-up by Brandon W Maister discusses debugging in more detail:\n[Debugging Rust's new Custom Derive system][debugging].\n\n[debugging]: https://quodlibetor.github.io/posts/debugging-rusts-new-custom-derive-system/\n\n<br>\n\n## Optional features\n\nSyn puts a lot of functionality behind optional features in order to optimize\ncompile time for the most common use cases. The following features are\navailable.\n\n- **`derive`** *(enabled by default)* — Data structures for representing the\n  possible input to a derive macro, including structs and enums and types.\n- **`full`** — Data structures for representing the syntax tree of all valid\n  Rust source code, including items and expressions.\n- **`parsing`** *(enabled by default)* — Ability to parse input tokens into a\n  syntax tree node of a chosen type.\n- **`printing`** *(enabled by default)* — Ability to print a syntax tree node as\n  tokens of Rust source code.\n- **`visit`** — Trait for traversing a syntax tree.\n- **`visit-mut`** — Trait for traversing and mutating in place a syntax tree.\n- **`fold`** — Trait for transforming an owned syntax tree.\n- **`clone-impls`** *(enabled by default)* — Clone impls for all syntax tree\n  types.\n- **`extra-traits`** — Debug, Eq, PartialEq, Hash impls for all syntax tree\n  types.\n- **`proc-macro`** *(enabled by default)* — Runtime dependency on the dynamic\n  library libproc_macro from rustc toolchain.\n\n<br>\n\n## Proc macro shim\n\nSyn operates on the token representation provided by the [proc-macro2] crate\nfrom crates.io rather than using the compiler's built in proc-macro crate\ndirectly. This enables code using Syn to execute outside of the context of a\nprocedural macro, such as in unit tests or build.rs, and we avoid needing\nincompatible ecosystems for proc macros vs non-macro use cases.\n\nIn general all of your code should be written against proc-macro2 rather than\nproc-macro. The one exception is in the signatures of procedural macro entry\npoints, which are required by the language to use `proc_macro::TokenStream`.\n\nThe proc-macro2 crate will automatically detect and use the compiler's data\nstructures when a procedural macro is active.\n\n[proc-macro2]: https://docs.rs/proc-macro2/1.0/proc_macro2/\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "syn@3.0.6",
      "sourcePath": "README.md",
      "sha256": "a00f270c7f468863f28b9984547872efb57c7db1b9beb6e685852dc24de6846e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Parser for Rust source code\n===========================\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/syn-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/syn)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/syn.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/syn)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-syn-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/syn)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/syn/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/syn/actions?query=branch%3Amaster)\n\nSyn is a parsing library for parsing a stream of Rust tokens into a syntax tree\nof Rust source code.\n\nCurrently this library is geared toward use in Rust procedural macros, but\ncontains some APIs that may be useful more generally.\n\n- **Data structures** — Syn provides a syntax tree that can represent most\n  stable Rust source code and some unstable syntax. The syntax tree is rooted at\n  [`syn::File`] which represents a full source file, but there are other entry\n  points that may be useful to procedural macros including [`syn::Item`],\n  [`syn::Expr`] and [`syn::Type`].\n\n- **Derives** — Of particular interest to derive macros is [`syn::DeriveInput`]\n  which is any of the three legal input items to a derive macro. An example\n  below shows using this type in a library that can derive implementations of a\n  user-defined trait.\n\n- **Parsing** — Parsing in Syn is built around [parser functions] with the\n  signature `fn(ParseStream) -> Result<T>`. Every syntax tree node defined by\n  Syn is individually parsable and may be used as a building block for custom\n  syntaxes, or you may dream up your own brand new syntax without involving any\n  of our syntax tree types.\n\n- **Location information** — Every token parsed by Syn is associated with a\n  `Span` that tracks line and column information back to the source of that\n  token. These spans allow a procedural macro to display detailed error messages\n  pointing to all the right places in the user's code. There is an example of\n  this below.\n\n- **Feature flags** — Functionality is aggressively feature gated so your\n  procedural macros enable only what they need, and do not pay in compile time\n  for all the rest.\n\n[`syn::File`]: https://docs.rs/syn/3/syn/struct.File.html\n[`syn::Item`]: https://docs.rs/syn/3/syn/enum.Item.html\n[`syn::Expr`]: https://docs.rs/syn/3/syn/enum.Expr.html\n[`syn::Type`]: https://docs.rs/syn/3/syn/enum.Type.html\n[`syn::DeriveInput`]: https://docs.rs/syn/3/syn/struct.DeriveInput.html\n[parser functions]: https://docs.rs/syn/3/syn/parse/index.html\n\n[*Release notes*](https://github.com/dtolnay/syn/releases)\n\n<br>\n\n## Resources\n\nThe best way to learn about procedural macros is by writing some. Consider\nworking through [this procedural macro workshop][workshop] to get familiar with\nthe different types of procedural macros. The workshop contains relevant links\ninto the Syn documentation as you work through each project.\n\n[workshop]: https://github.com/dtolnay/proc-macro-workshop\n\n<br>\n\n## Example of a derive macro\n\nThe canonical derive macro using Syn looks like this. We write an ordinary Rust\nfunction tagged with a `proc_macro_derive` attribute and the name of the trait\nwe are deriving. Any time that derive appears in the user's code, the Rust\ncompiler passes their data structure as tokens into our macro. We get to execute\narbitrary Rust code to figure out what to do with those tokens, then hand some\ntokens back to the compiler to compile into the user's crate.\n\n[`TokenStream`]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html\n\n```toml\n# Cargo.toml\n[package]\n...\n\n[lib]\nproc-macro = true\n\n[dependencies]\nsyn = \"3\"\nquote = \"1\"\n```\n\n```rust\nuse proc_macro::TokenStream;\nuse quote::quote;\nuse syn::{parse_macro_input, DeriveInput};\n\n#[proc_macro_derive(MyMacro)]\npub fn my_macro(input: TokenStream) -> TokenStream {\n    // Parse the input tokens into a syntax tree\n    let input = parse_macro_input!(input as DeriveInput);\n\n    // Build the output, possibly using quasi-quotation\n    let expanded = quote! {\n        // ...\n    };\n\n    // Hand the output tokens back to the compiler\n    TokenStream::from(expanded)\n}\n```\n\nThe [`heapsize`] example directory shows a complete working implementation of a\nderive macro. The example derives a `HeapSize` trait which computes an estimate\nof the amount of heap memory owned by a value.\n\n[`heapsize`]: examples/heapsize\n\n```rust\npub trait HeapSize {\n    /// Total number of bytes of heap memory owned by `self`.\n    fn heap_size_of_children(&self) -> usize;\n}\n```\n\nThe derive macro allows users to write `#[derive(HeapSize)]` on data structures\nin their program.\n\n```rust\n#[derive(HeapSize)]\nstruct Demo<'a, T: ?Sized> {\n    a: Box<T>,\n    b: u8,\n    c: &'a str,\n    d: String,\n}\n```\n\n<br>\n\n## Spans and error reporting\n\nThe token-based procedural macro API provides great control over where the\ncompiler's error messages are displayed in user code. Consider the error the\nuser sees if one of their field types does not implement `HeapSize`.\n\n```rust\n#[derive(HeapSize)]\nstruct Broken {\n    ok: String,\n    bad: std::thread::Thread,\n}\n```\n\nBy tracking span information all the way through the expansion of a procedural\nmacro as shown in the `heapsize` example, token-based macros in Syn are able to\ntrigger errors that directly pinpoint the source of the problem.\n\n```console\nerror[E0277]: the trait bound `Thread: HeapSize` is not satisfied\n --> src/main.rs:9:5\n  |\n3 | #[derive(HeapSize)]\n  |          -------- required by a bound introduced by this call\n...\n9 |     bad: std::thread::Thread,\n  |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `Thread`\n  |\n  = help: the following other types implement trait `HeapSize`:\n            &'a T\n            Box<T>\n            Demo<'a, T>\n            String\n            [T]\n            u8\n```\n\n<br>\n\n## Parsing a custom syntax\n\nThe [`lazy-static`] example directory shows the implementation of a\n`functionlike!(...)` procedural macro in which the input tokens are parsed using\nSyn's parsing API.\n\n[`lazy-static`]: examples/lazy-static\n\nThe example reimplements the popular `lazy_static` crate from crates.io as a\nprocedural macro.\n\n```rust\nlazy_static! {\n    static ref USERNAME: Regex = Regex::new(\"^[a-z0-9_-]{3,16}$\").unwrap();\n}\n```\n\nThe implementation shows how to trigger custom warnings and error messages on\nthe macro input.\n\n```console\nwarning: come on, pick a more creative name\n  --> src/main.rs:10:16\n   |\n10 |     static ref FOO: String = \"lazy_static\".to_owned();\n   |                ^^^\n```\n\n<br>\n\n## Testing\n\nWhen testing macros, we often care not just that the macro can be used\nsuccessfully but also that when the macro is provided with invalid input it\nproduces maximally helpful error messages. Consider using the [`trybuild`] crate\nto write tests for errors that are emitted by your macro or errors detected by\nthe Rust compiler in the expanded code following misuse of the macro. Such tests\nhelp avoid regressions from later refactors that mistakenly make an error no\nlonger trigger or be less helpful than it used to be.\n\n[`trybuild`]: https://github.com/dtolnay/trybuild\n\n<br>\n\n## Debugging\n\nWhen developing a procedural macro it can be helpful to look at what the\ngenerated code looks like. Use `cargo rustc -- -Zunstable-options\n-Zunpretty=expanded` or the [`cargo expand`] subcommand.\n\n[`cargo expand`]: https://github.com/dtolnay/cargo-expand\n\nTo show the expanded code for some crate that uses your procedural macro, run\n`cargo expand` from that crate. To show the expanded code for one of your own\ntest cases, run `cargo expand --test the_test_case` where the last argument is\nthe name of the test file without the `.rs` extension.\n\nThis write-up by Brandon W Maister discusses debugging in more detail:\n[Debugging Rust's new Custom Derive system][debugging].\n\n[debugging]: https://quodlibetor.github.io/posts/debugging-rusts-new-custom-derive-system/\n\n<br>\n\n## Optional features\n\nSyn puts a lot of functionality behind optional features in order to optimize\ncompile time for the most common use cases. The following features are\navailable.\n\n- **`derive`** *(enabled by default)* — Data structures for representing the\n  possible input to a derive macro, including structs and enums and types.\n- **`full`** — Data structures for representing the syntax tree of all valid\n  Rust source code, including items and expressions.\n- **`parsing`** *(enabled by default)* — Ability to parse input tokens into a\n  syntax tree node of a chosen type.\n- **`printing`** *(enabled by default)* — Ability to print a syntax tree node as\n  tokens of Rust source code.\n- **`visit`** — Trait for traversing a syntax tree.\n- **`visit-mut`** — Trait for traversing and mutating in place a syntax tree.\n- **`fold`** — Trait for transforming an owned syntax tree.\n- **`clone-impls`** *(enabled by default)* — Clone impls for all syntax tree\n  types.\n- **`extra-traits`** — Debug, Eq, PartialEq, Hash impls for all syntax tree\n  types.\n- **`proc-macro`** *(enabled by default)* — Runtime dependency on the dynamic\n  library libproc_macro from rustc toolchain.\n\n<br>\n\n## Proc macro shim\n\nSyn operates on the token representation provided by the [proc-macro2] crate\nfrom crates.io rather than using the compiler's built in proc-macro crate\ndirectly. This enables code using Syn to execute outside of the context of a\nprocedural macro, such as in unit tests or build.rs, and we avoid needing\nincompatible ecosystems for proc macros vs non-macro use cases.\n\nIn general all of your code should be written against proc-macro2 rather than\nproc-macro. The one exception is in the signatures of procedural macro entry\npoints, which are required by the language to use `proc_macro::TokenStream`.\n\nThe proc-macro2 crate will automatically detect and use the compiler's data\nstructures when a procedural macro is active.\n\n[proc-macro2]: https://docs.rs/proc-macro2/1.0/proc_macro2/\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "tap@1.0.1",
      "sourcePath": "LICENSE.txt",
      "sha256": "8b4e95f5cf0dc40269c99f7b787203ffe04ded245ca2427422c196efa2b2f42a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "MIT License\n\nCopyright (c) 2017 Elliot Linder <darfink@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
    },
    {
      "package": "thiserror@1.0.69",
      "sourcePath": "README.md",
      "sha256": "868031e233823e023fd80a53a590da851b7aea469fda30c51dc097925e309cd1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "derive(Error)\n=============\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/thiserror-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/thiserror)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/thiserror.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/thiserror)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-thiserror-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/thiserror)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/thiserror/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/thiserror/actions?query=branch%3Amaster)\n\nThis library provides a convenient derive macro for the standard library's\n[`std::error::Error`] trait.\n\n[`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html\n\n```toml\n[dependencies]\nthiserror = \"1.0\"\n```\n\n*Compiler support: requires rustc 1.61+*\n\n<br>\n\n## Example\n\n```rust\nuse thiserror::Error;\n\n#[derive(Error, Debug)]\npub enum DataStoreError {\n    #[error(\"data store disconnected\")]\n    Disconnect(#[from] io::Error),\n    #[error(\"the data for key `{0}` is not available\")]\n    Redaction(String),\n    #[error(\"invalid header (expected {expected:?}, found {found:?})\")]\n    InvalidHeader {\n        expected: String,\n        found: String,\n    },\n    #[error(\"unknown data store error\")]\n    Unknown,\n}\n```\n\n<br>\n\n## Details\n\n- Thiserror deliberately does not appear in your public API. You get the same\n  thing as if you had written an implementation of `std::error::Error` by hand,\n  and switching from handwritten impls to thiserror or vice versa is not a\n  breaking change.\n\n- Errors may be enums, structs with named fields, tuple structs, or unit\n  structs.\n\n- A `Display` impl is generated for your error if you provide `#[error(\"...\")]`\n  messages on the struct or each variant of your enum, as shown above in the\n  example.\n\n  The messages support a shorthand for interpolating fields from the error.\n\n    - `#[error(\"{var}\")]`&ensp;⟶&ensp;`write!(\"{}\", self.var)`\n    - `#[error(\"{0}\")]`&ensp;⟶&ensp;`write!(\"{}\", self.0)`\n    - `#[error(\"{var:?}\")]`&ensp;⟶&ensp;`write!(\"{:?}\", self.var)`\n    - `#[error(\"{0:?}\")]`&ensp;⟶&ensp;`write!(\"{:?}\", self.0)`\n\n  These shorthands can be used together with any additional format args, which\n  may be arbitrary expressions. For example:\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum Error {\n      #[error(\"invalid rdo_lookahead_frames {0} (expected < {})\", i32::MAX)]\n      InvalidLookahead(u32),\n  }\n  ```\n\n  If one of the additional expression arguments needs to refer to a field of the\n  struct or enum, then refer to named fields as `.var` and tuple fields as `.0`.\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum Error {\n      #[error(\"first letter must be lowercase but was {:?}\", first_char(.0))]\n      WrongCase(String),\n      #[error(\"invalid index {idx}, expected at least {} and at most {}\", .limits.lo, .limits.hi)]\n      OutOfBounds { idx: usize, limits: Limits },\n  }\n  ```\n\n- A `From` impl is generated for each variant that contains a `#[from]`\n  attribute.\n\n  The variant using `#[from]` must not contain any other fields beyond the\n  source error (and possibly a backtrace &mdash; see below). Usually `#[from]`\n  fields are unnamed, but `#[from]` is allowed on a named field too.\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum MyError {\n      Io(#[from] io::Error),\n      Glob(#[from] globset::Error),\n  }\n  ```\n\n- The Error trait's `source()` method is implemented to return whichever field\n  has a `#[source]` attribute or is named `source`, if any. This is for\n  identifying the underlying lower level error that caused your error.\n\n  The `#[from]` attribute always implies that the same field is `#[source]`, so\n  you don't ever need to specify both attributes.\n\n  Any error type that implements `std::error::Error` or dereferences to `dyn\n  std::error::Error` will work as a source.\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub struct MyError {\n      msg: String,\n      #[source]  // optional if field name is `source`\n      source: anyhow::Error,\n  }\n  ```\n\n- The Error trait's `provide()` method is implemented to provide whichever field\n  has a type named `Backtrace`, if any, as a `std::backtrace::Backtrace`. Using\n  `Backtrace` in errors requires a nightly compiler with Rust version 1.73 or\n  newer.\n\n  ```rust\n  use std::backtrace::Backtrace;\n\n  #[derive(Error, Debug)]\n  pub struct MyError {\n      msg: String,\n      backtrace: Backtrace,  // automatically detected\n  }\n  ```\n\n- If a field is both a source (named `source`, or has `#[source]` or `#[from]`\n  attribute) *and* is marked `#[backtrace]`, then the Error trait's `provide()`\n  method is forwarded to the source's `provide` so that both layers of the error\n  share the same backtrace. The `#[backtrace]` attribute requires a nightly\n  compiler with Rust version 1.73 or newer.\n\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum MyError {\n      Io {\n          #[backtrace]\n          source: io::Error,\n      },\n  }\n  ```\n\n- For variants that use `#[from]` and also contain a `Backtrace` field, a\n  backtrace is captured from within the `From` impl.\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum MyError {\n      Io {\n          #[from]\n          source: io::Error,\n          backtrace: Backtrace,\n      },\n  }\n  ```\n\n- Errors may use `error(transparent)` to forward the source and Display methods\n  straight through to an underlying error without adding an additional message.\n  This would be appropriate for enums that need an \"anything else\" variant.\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum MyError {\n      ...\n\n      #[error(transparent)]\n      Other(#[from] anyhow::Error),  // source and Display delegate to anyhow::Error\n  }\n  ```\n\n  Another use case is hiding implementation details of an error representation\n  behind an opaque error type, so that the representation is able to evolve\n  without breaking the crate's public API.\n\n  ```rust\n  // PublicError is public, but opaque and easy to keep compatible.\n  #[derive(Error, Debug)]\n  #[error(transparent)]\n  pub struct PublicError(#[from] ErrorRepr);\n\n  impl PublicError {\n      // Accessors for anything we do want to expose publicly.\n  }\n\n  // Private and free to change across minor version of the crate.\n  #[derive(Error, Debug)]\n  enum ErrorRepr {\n      ...\n  }\n  ```\n\n- See also the [`anyhow`] library for a convenient single error type to use in\n  application code.\n\n  [`anyhow`]: https://github.com/dtolnay/anyhow\n\n<br>\n\n## Comparison to anyhow\n\nUse thiserror if you care about designing your own dedicated error type(s) so\nthat the caller receives exactly the information that you choose in the event of\nfailure. This most often applies to library-like code. Use [Anyhow] if you don't\ncare what error type your functions return, you just want it to be easy. This is\ncommon in application-like code.\n\n[Anyhow]: https://github.com/dtolnay/anyhow\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "thiserror@2.0.20",
      "sourcePath": "README.md",
      "sha256": "96da8e4001dbd51bdc135de6deb4c954889624beb9f0c177ed0fdcd7e9ff41a2",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "derive(Error)\n=============\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/thiserror-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/thiserror)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/thiserror.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/thiserror)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-thiserror-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/thiserror)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/thiserror/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/thiserror/actions?query=branch%3Amaster)\n\nThis library provides a convenient derive macro for the standard library's\n[`std::error::Error`] trait.\n\n[`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html\n\n```toml\n[dependencies]\nthiserror = \"2\"\n```\n\n<br>\n\n## Example\n\n```rust\nuse thiserror::Error;\n\n#[derive(Error, Debug)]\npub enum DataStoreError {\n    #[error(\"data store disconnected\")]\n    Disconnect(#[from] io::Error),\n    #[error(\"the data for key `{0}` is not available\")]\n    Redaction(String),\n    #[error(\"invalid header (expected {expected:?}, found {found:?})\")]\n    InvalidHeader {\n        expected: String,\n        found: String,\n    },\n    #[error(\"unknown data store error\")]\n    Unknown,\n}\n```\n\n<br>\n\n## Details\n\n- Thiserror deliberately does not appear in your public API. You get the same\n  thing as if you had written an implementation of `std::error::Error` by hand,\n  and switching from handwritten impls to thiserror or vice versa is not a\n  breaking change.\n\n- Errors may be enums, structs with named fields, tuple structs, or unit\n  structs.\n\n- A `Display` impl is generated for your error if you provide `#[error(\"...\")]`\n  messages on the struct or each variant of your enum, as shown above in the\n  example.\n\n  The messages support a shorthand for interpolating fields from the error.\n\n    - `#[error(\"{var}\")]`&ensp;⟶&ensp;`write!(\"{}\", self.var)`\n    - `#[error(\"{0}\")]`&ensp;⟶&ensp;`write!(\"{}\", self.0)`\n    - `#[error(\"{var:?}\")]`&ensp;⟶&ensp;`write!(\"{:?}\", self.var)`\n    - `#[error(\"{0:?}\")]`&ensp;⟶&ensp;`write!(\"{:?}\", self.0)`\n\n  These shorthands can be used together with any additional format args, which\n  may be arbitrary expressions. For example:\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum Error {\n      #[error(\"invalid rdo_lookahead_frames {0} (expected < {max})\", max = i32::MAX)]\n      InvalidLookahead(u32),\n  }\n  ```\n\n  If one of the additional expression arguments needs to refer to a field of the\n  struct or enum, then refer to named fields as `.var` and tuple fields as `.0`.\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum Error {\n      #[error(\"first letter must be lowercase but was {:?}\", first_char(.0))]\n      WrongCase(String),\n      #[error(\"invalid index {idx}, expected at least {} and at most {}\", .limits.lo, .limits.hi)]\n      OutOfBounds { idx: usize, limits: Limits },\n  }\n  ```\n\n- A `From` impl is generated for each variant that contains a `#[from]`\n  attribute.\n\n  The variant using `#[from]` must not contain any other fields beyond the\n  source error (and possibly a backtrace &mdash; see below). Usually `#[from]`\n  fields are unnamed, but `#[from]` is allowed on a named field too.\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum MyError {\n      Io(#[from] io::Error),\n      Glob(#[from] globset::Error),\n  }\n  ```\n\n- The Error trait's `source()` method is implemented to return whichever field\n  has a `#[source]` attribute or is named `source`, if any. This is for\n  identifying the underlying lower level error that caused your error.\n\n  The `#[from]` attribute always implies that the same field is `#[source]`, so\n  you don't ever need to specify both attributes.\n\n  Any error type that implements `std::error::Error` or dereferences to `dyn\n  std::error::Error` will work as a source.\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub struct MyError {\n      msg: String,\n      #[source]  // optional if field name is `source`\n      source: anyhow::Error,\n  }\n  ```\n\n- The Error trait's `provide()` method is implemented to provide whichever field\n  has a type named `Backtrace`, if any, as a `std::backtrace::Backtrace`. Using\n  `Backtrace` in errors requires a nightly compiler with Rust version 1.73 or\n  newer.\n\n  ```rust\n  use std::backtrace::Backtrace;\n\n  #[derive(Error, Debug)]\n  pub struct MyError {\n      msg: String,\n      backtrace: Backtrace,  // automatically detected\n  }\n  ```\n\n- If a field is both a source (named `source`, or has `#[source]` or `#[from]`\n  attribute) *and* is marked `#[backtrace]`, then the Error trait's `provide()`\n  method is forwarded to the source's `provide` so that both layers of the error\n  share the same backtrace. The `#[backtrace]` attribute requires a nightly\n  compiler with Rust version 1.73 or newer.\n\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum MyError {\n      Io {\n          #[backtrace]\n          source: io::Error,\n      },\n  }\n  ```\n\n- For variants that use `#[from]` and also contain a `Backtrace` field, a\n  backtrace is captured from within the `From` impl.\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum MyError {\n      Io {\n          #[from]\n          source: io::Error,\n          backtrace: Backtrace,\n      },\n  }\n  ```\n\n- Errors may use `error(transparent)` to forward the source and Display methods\n  straight through to an underlying error without adding an additional message.\n  This would be appropriate for enums that need an \"anything else\" variant.\n\n  ```rust\n  #[derive(Error, Debug)]\n  pub enum MyError {\n      ...\n\n      #[error(transparent)]\n      Other(#[from] anyhow::Error),  // source and Display delegate to anyhow::Error\n  }\n  ```\n\n  Another use case is hiding implementation details of an error representation\n  behind an opaque error type, so that the representation is able to evolve\n  without breaking the crate's public API.\n\n  ```rust\n  // PublicError is public, but opaque and easy to keep compatible.\n  #[derive(Error, Debug)]\n  #[error(transparent)]\n  pub struct PublicError(#[from] ErrorRepr);\n\n  impl PublicError {\n      // Accessors for anything we do want to expose publicly.\n  }\n\n  // Private and free to change across minor version of the crate.\n  #[derive(Error, Debug)]\n  enum ErrorRepr {\n      ...\n  }\n  ```\n\n- See also the [`anyhow`] library for a convenient single error type to use in\n  application code.\n\n  [`anyhow`]: https://github.com/dtolnay/anyhow\n\n<br>\n\n## Comparison to anyhow\n\nUse thiserror if you care about designing your own dedicated error type(s) so\nthat the caller receives exactly the information that you choose in the event of\nfailure. This most often applies to library-like code. Use [Anyhow] if you don't\ncare what error type your functions return, you just want it to be easy. This is\ncommon in application-like code.\n\n[Anyhow]: https://github.com/dtolnay/anyhow\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n</sub>\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/alpha_runs.rs",
      "sha256": "bf5a2505be77c70d82768f46c69775fc362c3c47d93f2dd9b3a65434647fb303",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse core::convert::TryFrom;\nuse core::num::NonZeroU16;\n\nuse crate::color::AlphaU8;\nuse crate::LengthU32;\n\npub type AlphaRun = Option<NonZeroU16>;\n\n/// Sparse array of run-length-encoded alpha (supersampling coverage) values.\n///\n/// Sparseness allows us to independently compose several paths into the\n/// same AlphaRuns buffer.\npub struct AlphaRuns {\n    pub runs: Vec<AlphaRun>,\n    pub alpha: Vec<u8>,\n}\n\nimpl AlphaRuns {\n    pub fn new(width: LengthU32) -> Self {\n        let mut runs = AlphaRuns {\n            runs: vec![None; (width.get() + 1) as usize],\n            alpha: vec![0; (width.get() + 1) as usize],\n        };\n        runs.reset(width);\n        runs\n    }\n\n    /// Returns 0-255 given 0-256.\n    pub fn catch_overflow(alpha: u16) -> AlphaU8 {\n        debug_assert!(alpha <= 256);\n        (alpha - (alpha >> 8)) as u8\n    }\n\n    /// Returns true if the scanline contains only a single run, of alpha value 0.\n    pub fn is_empty(&self) -> bool {\n        debug_assert!(self.runs[0].is_some());\n        match self.runs[0] {\n            Some(run) => self.alpha[0] == 0 && self.runs[usize::from(run.get())].is_none(),\n            None => true,\n        }\n    }\n\n    /// Reinitialize for a new scanline.\n    pub fn reset(&mut self, width: LengthU32) {\n        let run = u16::try_from(width.get()).unwrap();\n        self.runs[0] = NonZeroU16::new(run);\n        self.runs[width.get() as usize] = None;\n        self.alpha[0] = 0;\n    }\n\n    /// Insert into the buffer a run starting at (x-offset_x).\n    ///\n    /// if start_alpha > 0\n    ///     one pixel with value += start_alpha,\n    ///         max 255\n    /// if middle_count > 0\n    ///     middle_count pixels with value += max_value\n    /// if stop_alpha > 0\n    ///     one pixel with value += stop_alpha\n    ///\n    /// Returns the offset_x value that should be passed on the next call,\n    /// assuming we're on the same scanline. If the caller is switching\n    /// scanlines, then offset_x should be 0 when this is called.\n    pub fn add(\n        &mut self,\n        x: u32,\n        start_alpha: AlphaU8,\n        mut middle_count: usize,\n        stop_alpha: AlphaU8,\n        max_value: u8,\n        offset_x: usize,\n    ) -> usize {\n        let mut x = x as usize;\n\n        let mut runs_offset = offset_x;\n        let mut alpha_offset = offset_x;\n        let mut last_alpha_offset = offset_x;\n        x -= offset_x;\n\n        if start_alpha != 0 {\n            Self::break_run(\n                &mut self.runs[runs_offset..],\n                &mut self.alpha[alpha_offset..],\n                x,\n                1,\n            );\n            // I should be able to just add alpha[x] + start_alpha.\n            // However, if the trailing edge of the previous span and the leading\n            // edge of the current span round to the same super-sampled x value,\n            // I might overflow to 256 with this add, hence the funny subtract (crud).\n            let tmp = u16::from(self.alpha[alpha_offset + x]) + u16::from(start_alpha);\n            debug_assert!(tmp <= 256);\n            // was (tmp >> 7), but that seems wrong if we're trying to catch 256\n            self.alpha[alpha_offset + x] = (tmp - (tmp >> 8)) as u8;\n\n            runs_offset += x + 1;\n            alpha_offset += x + 1;\n            x = 0;\n        }\n\n        if middle_count != 0 {\n            Self::break_run(\n                &mut self.runs[runs_offset..],\n                &mut self.alpha[alpha_offset..],\n                x,\n                middle_count,\n            );\n            alpha_offset += x;\n            runs_offset += x;\n            x = 0;\n            loop {\n                let a = Self::catch_overflow(\n                    u16::from(self.alpha[alpha_offset]) + u16::from(max_value),\n                );\n                self.alpha[alpha_offset] = a;\n\n                let n = usize::from(self.runs[runs_offset].unwrap().get());\n                debug_assert!(n <= middle_count);\n                alpha_offset += n;\n                runs_offset += n;\n                middle_count -= n;\n\n                if middle_count == 0 {\n                    break;\n                }\n            }\n\n            last_alpha_offset = alpha_offset;\n        }\n\n        if stop_alpha != 0 {\n            Self::break_run(\n                &mut self.runs[runs_offset..],\n                &mut self.alpha[alpha_offset..],\n                x,\n                1,\n            );\n            alpha_offset += x;\n            self.alpha[alpha_offset] = (self.alpha[alpha_offset] + stop_alpha) as u8;\n            last_alpha_offset = alpha_offset;\n        }\n\n        // new offset_x\n        last_alpha_offset\n    }\n\n    /// Break the runs in the buffer at offsets x and x+count, properly\n    /// updating the runs to the right and left.\n    ///\n    /// i.e. from the state AAAABBBB, run-length encoded as A4B4,\n    /// break_run(..., 2, 5) would produce AAAABBBB rle as A2A2B3B1.\n    /// Allows add() to sum another run to some of the new sub-runs.\n    /// i.e. adding ..CCCCC. would produce AADDEEEB, rle as A2D2E3B1.\n    fn break_run(runs: &mut [AlphaRun], alpha: &mut [u8], mut x: usize, count: usize) {\n        debug_assert!(count > 0);\n\n        let orig_x = x;\n        let mut runs_offset = 0;\n        let mut alpha_offset = 0;\n\n        while x > 0 {\n            let n = usize::from(runs[runs_offset].unwrap().get());\n            debug_assert!(n > 0);\n\n            if x < n {\n                alpha[alpha_offset + x] = alpha[alpha_offset];\n                runs[runs_offset + 0] = NonZeroU16::new(x as u16);\n                runs[runs_offset + x] = NonZeroU16::new((n - x) as u16);\n                break;\n            }\n            runs_offset += n;\n            alpha_offset += n;\n            x -= n;\n        }\n\n        runs_offset = orig_x;\n        alpha_offset = orig_x;\n        x = count;\n\n        loop {\n            let n = usize::from(runs[runs_offset].unwrap().get());\n            debug_assert!(n > 0);\n\n            if x < n {\n                alpha[alpha_offset + x] = alpha[alpha_offset];\n                runs[runs_offset + 0] = NonZeroU16::new(x as u16);\n                runs[runs_offset + x] = NonZeroU16::new((n - x) as u16);\n                break;\n            }\n\n            x -= n;\n            if x == 0 {\n                break;\n            }\n\n            runs_offset += n;\n            alpha_offset += n;\n        }\n    }\n\n    /// Cut (at offset x in the buffer) a run into two shorter runs with\n    /// matching alpha values.\n    ///\n    /// Used by the RectClipBlitter to trim a RLE encoding to match the\n    /// clipping rectangle.\n    pub fn break_at(alpha: &mut [AlphaU8], runs: &mut [AlphaRun], mut x: i32) {\n        let mut alpha_i = 0;\n        let mut run_i = 0;\n        while x > 0 {\n            let n = runs[run_i].unwrap().get();\n            let n_usize = usize::from(n);\n            let n_i32 = i32::from(n);\n            if x < n_i32 {\n                alpha[alpha_i + x as usize] = alpha[alpha_i];\n                runs[0] = NonZeroU16::new(x as u16);\n                runs[x as usize] = NonZeroU16::new((n_i32 - x) as u16);\n                break;\n            }\n\n            run_i += n_usize;\n            alpha_i += n_usize;\n            x -= n_i32;\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/blitter.rs",
      "sha256": "3262acaac9f2a78736295e937eee9542667b1de07b5a23db554830b192eb929e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse crate::geom::ScreenIntRect;\n\nuse crate::alpha_runs::AlphaRun;\nuse crate::color::AlphaU8;\nuse crate::LengthU32;\n\n/// Mask is used to describe alpha bitmaps.\npub struct Mask {\n    pub image: [u8; 2],\n    pub bounds: ScreenIntRect,\n    pub row_bytes: u32,\n}\n\n/// Blitter is responsible for actually writing pixels into memory.\n///\n/// Besides efficiency, they handle clipping and antialiasing.\n/// An object that implements Blitter contains all the context needed to generate pixels\n/// for the destination and how src/generated pixels map to the destination.\n/// The coordinates passed to the `blit_*` calls are in destination pixel space.\npub trait Blitter {\n    /// Blits a horizontal run of one or more pixels.\n    fn blit_h(&mut self, _x: u32, _y: u32, _width: LengthU32) {\n        unreachable!()\n    }\n\n    /// Blits a horizontal run of antialiased pixels.\n    ///\n    /// runs[] is a *sparse* zero-terminated run-length encoding of spans of constant alpha values.\n    ///\n    /// The runs[] and antialias[] work together to represent long runs of pixels with the same\n    /// alphas. The runs[] contains the number of pixels with the same alpha, and antialias[]\n    /// contain the coverage value for that number of pixels. The runs[] (and antialias[]) are\n    /// encoded in a clever way. The runs array is zero terminated, and has enough entries for\n    /// each pixel plus one, in most cases some of the entries will not contain valid data. An entry\n    /// in the runs array contains the number of pixels (np) that have the same alpha value. The\n    /// next np value is found np entries away. For example, if runs[0] = 7, then the next valid\n    /// entry will by at runs[7]. The runs array and antialias[] are coupled by index. So, if the\n    /// np entry is at runs[45] = 12 then the alpha value can be found at antialias[45] = 0x88.\n    /// This would mean to use an alpha value of 0x88 for the next 12 pixels starting at pixel 45.\n    fn blit_anti_h(\n        &mut self,\n        _x: u32,\n        _y: u32,\n        _antialias: &mut [AlphaU8],\n        _runs: &mut [AlphaRun],\n    ) {\n        unreachable!()\n    }\n\n    /// Blits a vertical run of pixels with a constant alpha value.\n    fn blit_v(&mut self, _x: u32, _y: u32, _height: LengthU32, _alpha: AlphaU8) {\n        unreachable!()\n    }\n\n    fn blit_anti_h2(&mut self, _x: u32, _y: u32, _alpha0: AlphaU8, _alpha1: AlphaU8) {\n        unreachable!()\n    }\n\n    fn blit_anti_v2(&mut self, _x: u32, _y: u32, _alpha0: AlphaU8, _alpha1: AlphaU8) {\n        unreachable!()\n    }\n\n    /// Blits a solid rectangle one or more pixels wide.\n    fn blit_rect(&mut self, _rect: &ScreenIntRect) {\n        unreachable!()\n    }\n\n    /// Blits a pattern of pixels defined by a rectangle-clipped mask.\n    fn blit_mask(&mut self, _mask: &Mask, _clip: &ScreenIntRect) {\n        unreachable!()\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/color.rs",
      "sha256": "41a25664ba67f30823dc48781fa35fd344d7f3cfd0c02a83e736c3fe6c18bc7d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse tiny_skia_path::{NormalizedF32, Scalar};\n\n/// 8-bit type for an alpha value. 255 is 100% opaque, zero is 100% transparent.\npub type AlphaU8 = u8;\n\n/// Represents fully transparent AlphaU8 value.\npub const ALPHA_U8_TRANSPARENT: AlphaU8 = 0x00;\n\n/// Represents fully opaque AlphaU8 value.\npub const ALPHA_U8_OPAQUE: AlphaU8 = 0xFF;\n\n/// Represents fully transparent Alpha value.\npub const ALPHA_TRANSPARENT: NormalizedF32 = NormalizedF32::ZERO;\n\n/// Represents fully opaque Alpha value.\npub const ALPHA_OPAQUE: NormalizedF32 = NormalizedF32::ONE;\n\n/// A 32-bit RGBA color value.\n///\n/// Byteorder: RGBA (relevant for bytemuck casts)\n#[repr(transparent)]\n#[derive(Copy, Clone, PartialEq)]\npub struct ColorU8([u8; 4]);\n\nimpl ColorU8 {\n    /// Creates a new color.\n    pub const fn from_rgba(r: u8, g: u8, b: u8, a: u8) -> Self {\n        ColorU8([r, g, b, a])\n    }\n\n    /// Returns color's red component.\n    pub const fn red(self) -> u8 {\n        self.0[0]\n    }\n\n    /// Returns color's green component.\n    pub const fn green(self) -> u8 {\n        self.0[1]\n    }\n\n    /// Returns color's blue component.\n    pub const fn blue(self) -> u8 {\n        self.0[2]\n    }\n\n    /// Returns color's alpha component.\n    pub const fn alpha(self) -> u8 {\n        self.0[3]\n    }\n\n    /// Check that color is opaque.\n    ///\n    /// Alpha == 255\n    pub fn is_opaque(&self) -> bool {\n        self.alpha() == ALPHA_U8_OPAQUE\n    }\n\n    /// Converts into a premultiplied color.\n    pub fn premultiply(&self) -> PremultipliedColorU8 {\n        let a = self.alpha();\n        if a != ALPHA_U8_OPAQUE {\n            PremultipliedColorU8::from_rgba_unchecked(\n                premultiply_u8(self.red(), a),\n                premultiply_u8(self.green(), a),\n                premultiply_u8(self.blue(), a),\n                a,\n            )\n        } else {\n            PremultipliedColorU8::from_rgba_unchecked(self.red(), self.green(), self.blue(), a)\n        }\n    }\n}\n\nimpl core::fmt::Debug for ColorU8 {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        f.debug_struct(\"ColorU8\")\n            .field(\"r\", &self.red())\n            .field(\"g\", &self.green())\n            .field(\"b\", &self.blue())\n            .field(\"a\", &self.alpha())\n            .finish()\n    }\n}\n\n/// A 32-bit premultiplied RGBA color value.\n///\n/// Byteorder: RGBA (relevant for bytemuck casts)\n#[repr(transparent)]\n#[derive(Copy, Clone, PartialEq)]\npub struct PremultipliedColorU8([u8; 4]);\n\n// Perfectly safe, since [u8; 4] is already Pod.\nunsafe impl bytemuck::Zeroable for PremultipliedColorU8 {}\nunsafe impl bytemuck::Pod for PremultipliedColorU8 {}\n\nimpl PremultipliedColorU8 {\n    /// A transparent color.\n    pub const TRANSPARENT: Self = PremultipliedColorU8::from_rgba_unchecked(0, 0, 0, 0);\n\n    /// Creates a new premultiplied color.\n    ///\n    /// RGB components must be <= alpha.\n    pub fn from_rgba(r: u8, g: u8, b: u8, a: u8) -> Option<Self> {\n        if r <= a && g <= a && b <= a {\n            Some(PremultipliedColorU8([r, g, b, a]))\n        } else {\n            None\n        }\n    }\n\n    /// Creates a new color.\n    pub(crate) const fn from_rgba_unchecked(r: u8, g: u8, b: u8, a: u8) -> Self {\n        PremultipliedColorU8([r, g, b, a])\n    }\n\n    /// Returns color's red component.\n    ///\n    /// The value is <= alpha.\n    pub const fn red(self) -> u8 {\n        self.0[0]\n    }\n\n    /// Returns color's green component.\n    ///\n    /// The value is <= alpha.\n    pub const fn green(self) -> u8 {\n        self.0[1]\n    }\n\n    /// Returns color's blue component.\n    ///\n    /// The value is <= alpha.\n    pub const fn blue(self) -> u8 {\n        self.0[2]\n    }\n\n    /// Returns color's alpha component.\n    pub const fn alpha(self) -> u8 {\n        self.0[3]\n    }\n\n    /// Check that color is opaque.\n    ///\n    /// Alpha == 255\n    pub fn is_opaque(&self) -> bool {\n        self.alpha() == ALPHA_U8_OPAQUE\n    }\n\n    /// Returns a demultiplied color.\n    pub fn demultiply(&self) -> ColorU8 {\n        let alpha = self.alpha();\n        if alpha == ALPHA_U8_OPAQUE {\n            ColorU8(self.0)\n        } else {\n            let a = alpha as f64 / 255.0;\n            ColorU8::from_rgba(\n                (self.red() as f64 / a + 0.5) as u8,\n                (self.green() as f64 / a + 0.5) as u8,\n                (self.blue() as f64 / a + 0.5) as u8,\n                alpha,\n            )\n        }\n    }\n}\n\nimpl core::fmt::Debug for PremultipliedColorU8 {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        f.debug_struct(\"PremultipliedColorU8\")\n            .field(\"r\", &self.red())\n            .field(\"g\", &self.green())\n            .field(\"b\", &self.blue())\n            .field(\"a\", &self.alpha())\n            .finish()\n    }\n}\n\n/// An RGBA color value, holding four floating point components.\n///\n/// # Guarantees\n///\n/// - All values are in 0..=1 range.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub struct Color {\n    r: NormalizedF32,\n    g: NormalizedF32,\n    b: NormalizedF32,\n    a: NormalizedF32,\n}\n\nconst NV_ZERO: NormalizedF32 = NormalizedF32::ZERO;\nconst NV_ONE: NormalizedF32 = NormalizedF32::ONE;\n\nimpl Color {\n    /// A transparent color.\n    pub const TRANSPARENT: Color = Color {\n        r: NV_ZERO,\n        g: NV_ZERO,\n        b: NV_ZERO,\n        a: NV_ZERO,\n    };\n    /// A black color.\n    pub const BLACK: Color = Color {\n        r: NV_ZERO,\n        g: NV_ZERO,\n        b: NV_ZERO,\n        a: NV_ONE,\n    };\n    /// A white color.\n    pub const WHITE: Color = Color {\n        r: NV_ONE,\n        g: NV_ONE,\n        b: NV_ONE,\n        a: NV_ONE,\n    };\n\n    /// Creates a new color from 4 components.\n    ///\n    /// All values must be in 0..=1 range.\n    pub fn from_rgba(r: f32, g: f32, b: f32, a: f32) -> Option<Self> {\n        Some(Color {\n            r: NormalizedF32::new(r)?,\n            g: NormalizedF32::new(g)?,\n            b: NormalizedF32::new(b)?,\n            a: NormalizedF32::new(a)?,\n        })\n    }\n\n    /// Creates a new color from 4 components.\n    ///\n    /// u8 will be divided by 255 to get the float component.\n    pub fn from_rgba8(r: u8, g: u8, b: u8, a: u8) -> Self {\n        Color {\n            r: NormalizedF32::new_u8(r),\n            g: NormalizedF32::new_u8(g),\n            b: NormalizedF32::new_u8(b),\n            a: NormalizedF32::new_u8(a),\n        }\n    }\n\n    /// Returns color's red component.\n    ///\n    /// The value is guarantee to be in a 0..=1 range.\n    pub fn red(&self) -> f32 {\n        self.r.get()\n    }\n\n    /// Returns color's green component.\n    ///\n    /// The value is guarantee to be in a 0..=1 range.\n    pub fn green(&self) -> f32 {\n        self.g.get()\n    }\n\n    /// Returns color's blue component.\n    ///\n    /// The value is guarantee to be in a 0..=1 range.\n    pub fn blue(&self) -> f32 {\n        self.b.get()\n    }\n\n    /// Returns color's alpha component.\n    ///\n    /// The value is guarantee to be in a 0..=1 range.\n    pub fn alpha(&self) -> f32 {\n        self.a.get()\n    }\n\n    /// Sets the red component value.\n    ///\n    /// The new value will be clipped to the 0..=1 range.\n    pub fn set_red(&mut self, c: f32) {\n        self.r = NormalizedF32::new_clamped(c);\n    }\n\n    /// Sets the green component value.\n    ///\n    /// The new value will be clipped to the 0..=1 range.\n    pub fn set_green(&mut self, c: f32) {\n        self.g = NormalizedF32::new_clamped(c);\n    }\n\n    /// Sets the blue component value.\n    ///\n    /// The new value will be clipped to the 0..=1 range.\n    pub fn set_blue(&mut self, c: f32) {\n        self.b = NormalizedF32::new_clamped(c);\n    }\n\n    /// Sets the alpha component value.\n    ///\n    /// The new value will be clipped to the 0..=1 range.\n    pub fn set_alpha(&mut self, c: f32) {\n        self.a = NormalizedF32::new_clamped(c);\n    }\n\n    /// Shifts color's opacity.\n    ///\n    /// Essentially, multiplies color's alpha by opacity.\n    ///\n    /// `opacity` will be clamped to the 0..=1 range first.\n    /// The final alpha will also be clamped.\n    pub fn apply_opacity(&mut self, opacity: f32) {\n        self.a = NormalizedF32::new_clamped(self.a.get() * opacity.bound(0.0, 1.0));\n    }\n\n    /// Check that color is opaque.\n    ///\n    /// Alpha == 1.0\n    pub fn is_opaque(&self) -> bool {\n        self.a == ALPHA_OPAQUE\n    }\n\n    /// Converts into a premultiplied color.\n    pub fn premultiply(&self) -> PremultipliedColor {\n        if self.is_opaque() {\n            PremultipliedColor {\n                r: self.r,\n                g: self.g,\n                b: self.b,\n                a: self.a,\n            }\n        } else {\n            PremultipliedColor {\n                r: NormalizedF32::new_clamped(self.r.get() * self.a.get()),\n                g: NormalizedF32::new_clamped(self.g.get() * self.a.get()),\n                b: NormalizedF32::new_clamped(self.b.get() * self.a.get()),\n                a: self.a,\n            }\n        }\n    }\n\n    /// Converts into `ColorU8`.\n    pub fn to_color_u8(&self) -> ColorU8 {\n        let c = color_f32_to_u8(self.r, self.g, self.b, self.a);\n        ColorU8::from_rgba(c[0], c[1], c[2], c[3])\n    }\n}\n\n/// A premultiplied RGBA color value, holding four floating point components.\n///\n/// # Guarantees\n///\n/// - All values are in 0..=1 range.\n/// - RGB components are <= A.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub struct PremultipliedColor {\n    r: NormalizedF32,\n    g: NormalizedF32,\n    b: NormalizedF32,\n    a: NormalizedF32,\n}\n\nimpl PremultipliedColor {\n    /// Returns color's red component.\n    ///\n    /// - The value is guarantee to be in a 0..=1 range.\n    /// - The value is <= alpha.\n    pub fn red(&self) -> f32 {\n        self.r.get()\n    }\n\n    /// Returns color's green component.\n    ///\n    /// - The value is guarantee to be in a 0..=1 range.\n    /// - The value is <= alpha.\n    pub fn green(&self) -> f32 {\n        self.g.get()\n    }\n\n    /// Returns color's blue component.\n    ///\n    /// - The value is guarantee to be in a 0..=1 range.\n    /// - The value is <= alpha.\n    pub fn blue(&self) -> f32 {\n        self.b.get()\n    }\n\n    /// Returns color's alpha component.\n    ///\n    /// - The value is guarantee to be in a 0..=1 range.\n    pub fn alpha(&self) -> f32 {\n        self.a.get()\n    }\n\n    /// Returns a demultiplied color.\n    pub fn demultiply(&self) -> Color {\n        let a = self.a.get();\n        if a == 0.0 {\n            Color::TRANSPARENT\n        } else {\n            Color {\n                r: NormalizedF32::new_clamped(self.r.get() / a),\n                g: NormalizedF32::new_clamped(self.g.get() / a),\n                b: NormalizedF32::new_clamped(self.b.get() / a),\n                a: self.a,\n            }\n        }\n    }\n\n    /// Converts into `PremultipliedColorU8`.\n    pub fn to_color_u8(&self) -> PremultipliedColorU8 {\n        let c = color_f32_to_u8(self.r, self.g, self.b, self.a);\n        PremultipliedColorU8::from_rgba_unchecked(c[0], c[1], c[2], c[3])\n    }\n}\n\n/// Return a*b/255, rounding any fractional bits.\npub fn premultiply_u8(c: u8, a: u8) -> u8 {\n    let prod = u32::from(c) * u32::from(a) + 128;\n    ((prod + (prod >> 8)) >> 8) as u8\n}\n\nfn color_f32_to_u8(\n    r: NormalizedF32,\n    g: NormalizedF32,\n    b: NormalizedF32,\n    a: NormalizedF32,\n) -> [u8; 4] {\n    [\n        (r.get() * 255.0 + 0.5) as u8,\n        (g.get() * 255.0 + 0.5) as u8,\n        (b.get() * 255.0 + 0.5) as u8,\n        (a.get() * 255.0 + 0.5) as u8,\n    ]\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn premultiply_u8() {\n        assert_eq!(\n            ColorU8::from_rgba(10, 20, 30, 40).premultiply(),\n            PremultipliedColorU8::from_rgba_unchecked(2, 3, 5, 40)\n        );\n    }\n\n    #[test]\n    fn premultiply_u8_opaque() {\n        assert_eq!(\n            ColorU8::from_rgba(10, 20, 30, 255).premultiply(),\n            PremultipliedColorU8::from_rgba_unchecked(10, 20, 30, 255)\n        );\n    }\n\n    #[test]\n    fn demultiply_u8_1() {\n        assert_eq!(\n            PremultipliedColorU8::from_rgba_unchecked(2, 3, 5, 40).demultiply(),\n            ColorU8::from_rgba(13, 19, 32, 40)\n        );\n    }\n\n    #[test]\n    fn demultiply_u8_2() {\n        assert_eq!(\n            PremultipliedColorU8::from_rgba_unchecked(10, 20, 30, 255).demultiply(),\n            ColorU8::from_rgba(10, 20, 30, 255)\n        );\n    }\n\n    #[test]\n    fn demultiply_u8_3() {\n        assert_eq!(\n            PremultipliedColorU8::from_rgba_unchecked(153, 99, 54, 180).demultiply(),\n            ColorU8::from_rgba(217, 140, 77, 180)\n        );\n    }\n\n    #[test]\n    fn bytemuck_casts_rgba() {\n        let slice = &[\n            PremultipliedColorU8::from_rgba_unchecked(0, 1, 2, 3),\n            PremultipliedColorU8::from_rgba_unchecked(10, 11, 12, 13),\n        ];\n        let bytes: &[u8] = bytemuck::cast_slice(slice);\n        assert_eq!(bytes, &[0, 1, 2, 3, 10, 11, 12, 13]);\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/edge.rs",
      "sha256": "6c0c824169937e9720ad824aa2ab68efc8c71c32e553b828fd809dd064e607e1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse crate::Point;\n\nuse crate::fixed_point::{fdot16, fdot6, FDot16, FDot6};\nuse crate::math::left_shift;\n\n/// We store 1<<shift in a (signed) byte, so its maximum value is 1<<6 == 64.\n///\n/// Note that this limits the number of lines we use to approximate a curve.\n/// If we need to increase this, we need to store curve_count in something\n/// larger than i8.\nconst MAX_COEFF_SHIFT: i32 = 6;\n\n#[derive(Clone, Debug)]\npub enum Edge {\n    Line(LineEdge),\n    Quadratic(QuadraticEdge),\n    Cubic(CubicEdge),\n}\n\nimpl Edge {\n    pub fn as_line(&self) -> &LineEdge {\n        match self {\n            Edge::Line(line) => line,\n            Edge::Quadratic(quad) => &quad.line,\n            Edge::Cubic(cubic) => &cubic.line,\n        }\n    }\n\n    pub fn as_line_mut(&mut self) -> &mut LineEdge {\n        match self {\n            Edge::Line(line) => line,\n            Edge::Quadratic(quad) => &mut quad.line,\n            Edge::Cubic(cubic) => &mut cubic.line,\n        }\n    }\n}\n\nimpl core::ops::Deref for Edge {\n    type Target = LineEdge;\n\n    fn deref(&self) -> &Self::Target {\n        self.as_line()\n    }\n}\n\nimpl core::ops::DerefMut for Edge {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        self.as_line_mut()\n    }\n}\n\n#[derive(Clone, Default, Debug)]\npub struct LineEdge {\n    // Imitate a linked list.\n    pub prev: Option<u32>,\n    pub next: Option<u32>,\n\n    pub x: FDot16,\n    pub dx: FDot16,\n    pub first_y: i32,\n    pub last_y: i32,\n    pub winding: i8, // 1 or -1\n}\n\nimpl LineEdge {\n    pub fn new(p0: Point, p1: Point, shift: i32) -> Option<Self> {\n        let scale = (1 << (shift + 6)) as f32;\n        let mut x0 = (p0.x * scale) as i32;\n        let mut y0 = (p0.y * scale) as i32;\n        let mut x1 = (p1.x * scale) as i32;\n        let mut y1 = (p1.y * scale) as i32;\n\n        let mut winding = 1;\n\n        if y0 > y1 {\n            core::mem::swap(&mut x0, &mut x1);\n            core::mem::swap(&mut y0, &mut y1);\n            winding = -1;\n        }\n\n        let top = fdot6::round(y0);\n        let bottom = fdot6::round(y1);\n\n        // are we a zero-height line?\n        if top == bottom {\n            return None;\n        }\n\n        let slope = fdot6::div(x1 - x0, y1 - y0);\n        let dy = compute_dy(top, y0);\n\n        Some(LineEdge {\n            next: None,\n            prev: None,\n            x: fdot6::to_fdot16(x0 + fdot16::mul(slope, dy)),\n            dx: slope,\n            first_y: top,\n            last_y: bottom - 1,\n            winding,\n        })\n    }\n\n    pub fn is_vertical(&self) -> bool {\n        self.dx == 0\n    }\n\n    fn update(&mut self, mut x0: FDot16, mut y0: FDot16, mut x1: FDot16, mut y1: FDot16) -> bool {\n        debug_assert!(self.winding == 1 || self.winding == -1);\n\n        y0 >>= 10;\n        y1 >>= 10;\n\n        debug_assert!(y0 <= y1);\n\n        let top = fdot6::round(y0);\n        let bottom = fdot6::round(y1);\n\n        // are we a zero-height line?\n        if top == bottom {\n            return false;\n        }\n\n        x0 >>= 10;\n        x1 >>= 10;\n\n        let slope = fdot6::div(x1 - x0, y1 - y0);\n        let dy = compute_dy(top, y0);\n\n        self.x = fdot6::to_fdot16(x0 + fdot16::mul(slope, dy));\n        self.dx = slope;\n        self.first_y = top;\n        self.last_y = bottom - 1;\n\n        true\n    }\n}\n\n#[derive(Clone, Debug)]\npub struct QuadraticEdge {\n    pub line: LineEdge,\n    pub curve_count: i8,\n    curve_shift: u8, // applied to all dx/ddx/dddx\n    qx: FDot16,\n    qy: FDot16,\n    qdx: FDot16,\n    qdy: FDot16,\n    qddx: FDot16,\n    qddy: FDot16,\n    q_last_x: FDot16,\n    q_last_y: FDot16,\n}\n\nimpl QuadraticEdge {\n    pub fn new(points: &[Point], shift: i32) -> Option<Self> {\n        let mut quad = Self::new2(points, shift)?;\n        if quad.update() {\n            Some(quad)\n        } else {\n            None\n        }\n    }\n\n    fn new2(points: &[Point], mut shift: i32) -> Option<Self> {\n        let scale = (1 << (shift + 6)) as f32;\n        let mut x0 = (points[0].x * scale) as i32;\n        let mut y0 = (points[0].y * scale) as i32;\n        let x1 = (points[1].x * scale) as i32;\n        let y1 = (points[1].y * scale) as i32;\n        let mut x2 = (points[2].x * scale) as i32;\n        let mut y2 = (points[2].y * scale) as i32;\n\n        let mut winding = 1;\n        if y0 > y2 {\n            core::mem::swap(&mut x0, &mut x2);\n            core::mem::swap(&mut y0, &mut y2);\n            winding = -1;\n        }\n        debug_assert!(y0 <= y1 && y1 <= y2);\n\n        let top = fdot6::round(y0);\n        let bottom = fdot6::round(y2);\n\n        // are we a zero-height quad (line)?\n        if top == bottom {\n            return None;\n        }\n\n        // compute number of steps needed (1 << shift)\n        {\n            let dx = (left_shift(x1, 1) - x0 - x2) >> 2;\n            let dy = (left_shift(y1, 1) - y0 - y2) >> 2;\n            // This is a little confusing:\n            // before this line, shift is the scale up factor for AA;\n            // after this line, shift is the fCurveShift.\n            shift = diff_to_shift(dx, dy, shift);\n            debug_assert!(shift >= 0);\n        }\n\n        // need at least 1 subdivision for our bias trick\n        if shift == 0 {\n            shift = 1;\n        } else if shift > MAX_COEFF_SHIFT {\n            shift = MAX_COEFF_SHIFT;\n        }\n\n        let curve_count = (1 << shift) as i8;\n\n        // We want to reformulate into polynomial form, to make it clear how we\n        // should forward-difference.\n        //\n        // p0 (1 - t)^2 + p1 t(1 - t) + p2 t^2 ==> At^2 + Bt + C\n        //\n        // A = p0 - 2p1 + p2\n        // B = 2(p1 - p0)\n        // C = p0\n        //\n        // Our caller must have constrained our inputs (p0..p2) to all fit into\n        // 16.16. However, as seen above, we sometimes compute values that can be\n        // larger (e.g. B = 2*(p1 - p0)). To guard against overflow, we will store\n        // A and B at 1/2 of their actual value, and just apply a 2x scale during\n        // application in updateQuadratic(). Hence we store (shift - 1) in\n        // curve_shift.\n\n        let curve_shift = (shift - 1) as u8;\n\n        let mut a = fdot6_to_fixed_div2(x0 - x1 - x1 + x2); // 1/2 the real value\n        let mut b = fdot6::to_fdot16(x1 - x0); // 1/2 the real value\n\n        let qx = fdot6::to_fdot16(x0);\n        let qdx = b + (a >> shift); // biased by shift\n        let qddx = a >> (shift - 1); // biased by shift\n\n        a = fdot6_to_fixed_div2(y0 - y1 - y1 + y2); // 1/2 the real value\n        b = fdot6::to_fdot16(y1 - y0); // 1/2 the real value\n\n        let qy = fdot6::to_fdot16(y0);\n        let qdy = b + (a >> shift); // biased by shift\n        let qddy = a >> (shift - 1); // biased by shift\n\n        let q_last_x = fdot6::to_fdot16(x2);\n        let q_last_y = fdot6::to_fdot16(y2);\n\n        Some(QuadraticEdge {\n            line: LineEdge {\n                next: None,\n                prev: None,\n                x: 0,\n                dx: 0,\n                first_y: 0,\n                last_y: 0,\n                winding,\n            },\n            curve_count,\n            curve_shift,\n            qx,\n            qy,\n            qdx,\n            qdy,\n            qddx,\n            qddy,\n            q_last_x,\n            q_last_y,\n        })\n    }\n\n    pub fn update(&mut self) -> bool {\n        let mut success;\n        let mut count = self.curve_count;\n        let mut oldx = self.qx;\n        let mut oldy = self.qy;\n        let mut dx = self.qdx;\n        let mut dy = self.qdy;\n        let mut newx;\n        let mut newy;\n        let shift = self.curve_shift;\n\n        debug_assert!(count > 0);\n\n        loop {\n            count -= 1;\n            if count > 0 {\n                newx = oldx + (dx >> shift);\n                dx += self.qddx;\n                newy = oldy + (dy >> shift);\n                dy += self.qddy;\n            } else {\n                // last segment\n                newx = self.q_last_x;\n                newy = self.q_last_y;\n            }\n            success = self.line.update(oldx, oldy, newx, newy);\n            oldx = newx;\n            oldy = newy;\n\n            if count == 0 || success {\n                break;\n            }\n        }\n\n        self.qx = newx;\n        self.qy = newy;\n        self.qdx = dx;\n        self.qdy = dy;\n        self.curve_count = count as i8;\n\n        success\n    }\n}\n\n#[derive(Clone, Debug)]\npub struct CubicEdge {\n    pub line: LineEdge,\n    pub curve_count: i8,\n    curve_shift: u8, // applied to all dx/ddx/dddx except for dshift exception\n    dshift: u8,      // applied to cdx and cdy\n    cx: FDot16,\n    cy: FDot16,\n    cdx: FDot16,\n    cdy: FDot16,\n    cddx: FDot16,\n    cddy: FDot16,\n    cdddx: FDot16,\n    cdddy: FDot16,\n    c_last_x: FDot16,\n    c_last_y: FDot16,\n}\n\nimpl CubicEdge {\n    pub fn new(points: &[Point], shift: i32) -> Option<Self> {\n        let mut cubic = Self::new2(points, shift, true)?;\n        if cubic.update() {\n            Some(cubic)\n        } else {\n            None\n        }\n    }\n\n    fn new2(points: &[Point], mut shift: i32, sort_y: bool) -> Option<Self> {\n        let scale = (1 << (shift + 6)) as f32;\n        let mut x0 = (points[0].x * scale) as i32;\n        let mut y0 = (points[0].y * scale) as i32;\n        let mut x1 = (points[1].x * scale) as i32;\n        let mut y1 = (points[1].y * scale) as i32;\n        let mut x2 = (points[2].x * scale) as i32;\n        let mut y2 = (points[2].y * scale) as i32;\n        let mut x3 = (points[3].x * scale) as i32;\n        let mut y3 = (points[3].y * scale) as i32;\n\n        let mut winding = 1;\n        if sort_y && y0 > y3 {\n            core::mem::swap(&mut x0, &mut x3);\n            core::mem::swap(&mut x1, &mut x2);\n            core::mem::swap(&mut y0, &mut y3);\n            core::mem::swap(&mut y1, &mut y2);\n            winding = -1;\n        }\n\n        let top = fdot6::round(y0);\n        let bot = fdot6::round(y3);\n\n        // are we a zero-height cubic (line)?\n        if sort_y && top == bot {\n            return None;\n        }\n\n        // compute number of steps needed (1 << shift)\n        {\n            // Can't use (center of curve - center of baseline), since center-of-curve\n            // need not be the max delta from the baseline (it could even be coincident)\n            // so we try just looking at the two off-curve points\n            let dx = cubic_delta_from_line(x0, x1, x2, x3);\n            let dy = cubic_delta_from_line(y0, y1, y2, y3);\n            // add 1 (by observation)\n            shift = diff_to_shift(dx, dy, 2) + 1;\n        }\n        // need at least 1 subdivision for our bias trick\n        debug_assert!(shift > 0);\n        if shift > MAX_COEFF_SHIFT {\n            shift = MAX_COEFF_SHIFT;\n        }\n\n        // Since our in coming data is initially shifted down by 10 (or 8 in\n        // antialias). That means the most we can shift up is 8. However, we\n        // compute coefficients with a 3*, so the safest upshift is really 6\n        let mut up_shift = 6; // largest safe value\n        let mut down_shift = shift + up_shift - 10;\n        if down_shift < 0 {\n            down_shift = 0;\n            up_shift = 10 - shift;\n        }\n\n        let curve_count = left_shift(-1, shift) as i8;\n        let curve_shift = shift as u8;\n        let dshift = down_shift as u8;\n\n        let mut b = fdot6_up_shift(3 * (x1 - x0), up_shift);\n        let mut c = fdot6_up_shift(3 * (x0 - x1 - x1 + x2), up_shift);\n        let mut d = fdot6_up_shift(x3 + 3 * (x1 - x2) - x0, up_shift);\n\n        let cx = fdot6::to_fdot16(x0);\n        let cdx = b + (c >> shift) + (d >> (2 * shift)); // biased by shift\n        let cddx = 2 * c + ((3 * d) >> (shift - 1)); // biased by 2*shift\n        let cdddx = (3 * d) >> (shift - 1); // biased by 2*shift\n\n        b = fdot6_up_shift(3 * (y1 - y0), up_shift);\n        c = fdot6_up_shift(3 * (y0 - y1 - y1 + y2), up_shift);\n        d = fdot6_up_shift(y3 + 3 * (y1 - y2) - y0, up_shift);\n\n        let cy = fdot6::to_fdot16(y0);\n        let cdy = b + (c >> shift) + (d >> (2 * shift)); // biased by shift\n        let cddy = 2 * c + ((3 * d) >> (shift - 1)); // biased by 2*shift\n        let cdddy = (3 * d) >> (shift - 1); // biased by 2*shift\n\n        let c_last_x = fdot6::to_fdot16(x3);\n        let c_last_y = fdot6::to_fdot16(y3);\n\n        Some(CubicEdge {\n            line: LineEdge {\n                next: None,\n                prev: None,\n                x: 0,\n                dx: 0,\n                first_y: 0,\n                last_y: 0,\n                winding,\n            },\n            curve_count,\n            curve_shift,\n            dshift,\n            cx,\n            cy,\n            cdx,\n            cdy,\n            cddx,\n            cddy,\n            cdddx,\n            cdddy,\n            c_last_x,\n            c_last_y,\n        })\n    }\n\n    pub fn update(&mut self) -> bool {\n        let mut success;\n        let mut count = self.curve_count;\n        let mut oldx = self.cx;\n        let mut oldy = self.cy;\n        let mut newx;\n        let mut newy;\n        let ddshift = self.curve_shift;\n        let dshift = self.dshift;\n\n        debug_assert!(count < 0);\n\n        loop {\n            count += 1;\n            if count < 0 {\n                newx = oldx + (self.cdx >> dshift);\n                self.cdx += self.cddx >> ddshift;\n                self.cddx += self.cdddx;\n\n                newy = oldy + (self.cdy >> dshift);\n                self.cdy += self.cddy >> ddshift;\n                self.cddy += self.cdddy;\n            } else {\n                // last segment\n                newx = self.c_last_x;\n                newy = self.c_last_y;\n            }\n\n            // we want to say debug_assert(oldy <= newy), but our finite fixedpoint\n            // doesn't always achieve that, so we have to explicitly pin it here.\n            if newy < oldy {\n                newy = oldy;\n            }\n\n            success = self.line.update(oldx, oldy, newx, newy);\n            oldx = newx;\n            oldy = newy;\n\n            if count == 0 || success {\n                break;\n            }\n        }\n\n        self.cx = newx;\n        self.cy = newy;\n        self.curve_count = count;\n\n        success\n    }\n}\n\n// This correctly favors the lower-pixel when y0 is on a 1/2 pixel boundary\nfn compute_dy(top: FDot6, y0: FDot6) -> FDot6 {\n    left_shift(top, 6) + 32 - y0\n}\n\nfn diff_to_shift(dx: FDot6, dy: FDot6, shift_aa: i32) -> i32 {\n    // cheap calc of distance from center of p0-p2 to the center of the curve\n    let mut dist = cheap_distance(dx, dy);\n\n    // shift down dist (it is currently in dot6)\n    // down by 3 should give us 1/8 pixel accuracy (assuming our dist is accurate...)\n    // this is chosen by heuristic: make it as big as possible (to minimize segments)\n    // ... but small enough so that our curves still look smooth\n    // When shift > 0, we're using AA and everything is scaled up so we can\n    // lower the accuracy.\n    dist = (dist + (1 << 4)) >> (3 + shift_aa);\n\n    // each subdivision (shift value) cuts this dist (error) by 1/4\n    (32 - dist.leading_zeros() as i32) >> 1\n}\n\nfn cheap_distance(mut dx: FDot6, mut dy: FDot6) -> FDot6 {\n    dx = dx.abs();\n    dy = dy.abs();\n    // return max + min/2\n    if dx > dy {\n        dx + (dy >> 1)\n    } else {\n        dy + (dx >> 1)\n    }\n}\n\n// In LineEdge::new, QuadraticEdge::new, CubicEdge::new, the first thing we do is to convert\n// the points into FDot6. This is modulated by the shift parameter, which\n// will either be 0, or something like 2 for antialiasing.\n//\n// In the float case, we want to turn the float into .6 by saying pt * 64,\n// or pt * 256 for antialiasing. This is implemented as 1 << (shift + 6).\n//\n// In the fixed case, we want to turn the fixed into .6 by saying pt >> 10,\n// or pt >> 8 for antialiasing. This is implemented as pt >> (10 - shift).\nfn fdot6_to_fixed_div2(value: FDot6) -> FDot16 {\n    // we want to return SkFDot6ToFixed(value >> 1), but we don't want to throw\n    // away data in value, so just perform a modify up-shift\n    left_shift(value, 16 - 6 - 1)\n}\n\nfn fdot6_up_shift(x: FDot6, up_shift: i32) -> i32 {\n    debug_assert!((left_shift(x, up_shift) >> up_shift) == x);\n    left_shift(x, up_shift)\n}\n\n// f(1/3) = (8a + 12b + 6c + d) / 27\n// f(2/3) = (a + 6b + 12c + 8d) / 27\n//\n// f(1/3)-b = (8a - 15b + 6c + d) / 27\n// f(2/3)-c = (a + 6b - 15c + 8d) / 27\n//\n// use 16/512 to approximate 1/27\nfn cubic_delta_from_line(a: FDot6, b: FDot6, c: FDot6, d: FDot6) -> FDot6 {\n    // since our parameters may be negative, we don't use <<\n    let one_third = ((a * 8 - b * 15 + 6 * c + d) * 19) >> 9;\n    let two_third = ((a + 6 * b - c * 15 + d * 8) * 19) >> 9;\n\n    one_third.abs().max(two_third.abs())\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/edge_builder.rs",
      "sha256": "82f050de9a216141ca6c1a4d190bc001ecaed90eb65998d05a69b2016bf3310d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2011 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse alloc::vec::Vec;\n\nuse tiny_skia_path::PathVerb;\n\nuse crate::{Path, Point};\n\nuse crate::edge::{CubicEdge, Edge, LineEdge, QuadraticEdge};\nuse crate::edge_clipper::EdgeClipperIter;\nuse crate::geom::ScreenIntRect;\nuse crate::path_geometry;\n\n#[derive(Copy, Clone, PartialEq, Debug)]\nenum Combine {\n    No,\n    Partial,\n    Total,\n}\n\n#[derive(Copy, Clone, Debug)]\npub struct ShiftedIntRect {\n    shifted: ScreenIntRect,\n    shift: i32,\n}\n\nimpl ShiftedIntRect {\n    pub fn new(rect: &ScreenIntRect, shift: i32) -> Option<Self> {\n        let shifted = ScreenIntRect::from_xywh(\n            rect.x() << shift,\n            rect.y() << shift,\n            rect.width() << shift,\n            rect.height() << shift,\n        )?;\n        Some(ShiftedIntRect { shifted, shift })\n    }\n\n    pub fn shifted(&self) -> &ScreenIntRect {\n        &self.shifted\n    }\n\n    pub fn recover(&self) -> ScreenIntRect {\n        ScreenIntRect::from_xywh(\n            self.shifted.x() >> self.shift,\n            self.shifted.y() >> self.shift,\n            self.shifted.width() >> self.shift,\n            self.shifted.height() >> self.shift,\n        )\n        .unwrap() // cannot fail, because the original rect was valid\n    }\n}\n\npub struct BasicEdgeBuilder {\n    edges: Vec<Edge>,\n    clip_shift: i32,\n}\n\nimpl BasicEdgeBuilder {\n    pub fn new(clip_shift: i32) -> Self {\n        BasicEdgeBuilder {\n            edges: Vec::with_capacity(64), // TODO: stack array + fallback\n            clip_shift,\n        }\n    }\n\n    // Skia returns a linked list here, but it's a nightmare to use in Rust,\n    // so we're mimicking it with Vec.\n    pub fn build_edges(\n        path: &Path,\n        clip: Option<&ShiftedIntRect>,\n        clip_shift: i32,\n    ) -> Option<Vec<Edge>> {\n        // If we're convex, then we need both edges, even if the right edge is past the clip.\n        // let can_cull_to_the_right = !path.isConvex();\n        let can_cull_to_the_right = false; // TODO: this\n\n        let mut builder = BasicEdgeBuilder::new(clip_shift);\n        if !builder.build(path, clip, can_cull_to_the_right) {\n            log::warn!(\"infinite or NaN segments detected during edges building\");\n            return None;\n        }\n\n        if builder.edges.len() < 2 {\n            return None;\n        }\n\n        Some(builder.edges)\n    }\n\n    // TODO: build_poly\n    pub fn build(\n        &mut self,\n        path: &Path,\n        clip: Option<&ShiftedIntRect>,\n        can_cull_to_the_right: bool,\n    ) -> bool {\n        if let Some(clip) = clip {\n            let clip = clip.recover().to_rect();\n            for edges in EdgeClipperIter::new(path, clip, can_cull_to_the_right) {\n                for edge in edges {\n                    match edge {\n                        PathEdge::LineTo(p0, p1) => {\n                            if !p0.is_finite() || !p1.is_finite() {\n                                return false;\n                            }\n\n                            self.push_line(&[p0, p1])\n                        }\n                        PathEdge::QuadTo(p0, p1, p2) => {\n                            if !p0.is_finite() || !p1.is_finite() || !p2.is_finite() {\n                                return false;\n                            }\n\n                            self.push_quad(&[p0, p1, p2])\n                        }\n                        PathEdge::CubicTo(p0, p1, p2, p3) => {\n                            if !p0.is_finite()\n                                || !p1.is_finite()\n                                || !p2.is_finite()\n                                || !p3.is_finite()\n                            {\n                                return false;\n                            }\n\n                            self.push_cubic(&[p0, p1, p2, p3])\n                        }\n                    }\n                }\n            }\n        } else {\n            for edge in edge_iter(path) {\n                match edge {\n                    PathEdge::LineTo(p0, p1) => {\n                        self.push_line(&[p0, p1]);\n                    }\n                    PathEdge::QuadTo(p0, p1, p2) => {\n                        let points = [p0, p1, p2];\n                        let mut mono_x = [Point::zero(); 5];\n                        let n = path_geometry::chop_quad_at_y_extrema(&points, &mut mono_x);\n                        for i in 0..=n {\n                            self.push_quad(&mono_x[i * 2..]);\n                        }\n                    }\n                    PathEdge::CubicTo(p0, p1, p2, p3) => {\n                        let points = [p0, p1, p2, p3];\n                        let mut mono_y = [Point::zero(); 10];\n                        let n = path_geometry::chop_cubic_at_y_extrema(&points, &mut mono_y);\n                        for i in 0..=n {\n                            self.push_cubic(&mono_y[i * 3..]);\n                        }\n                    }\n                }\n            }\n        }\n\n        true\n    }\n\n    fn push_line(&mut self, points: &[Point; 2]) {\n        if let Some(edge) = LineEdge::new(points[0], points[1], self.clip_shift) {\n            let combine = if edge.is_vertical() && !self.edges.is_empty() {\n                if let Some(Edge::Line(last)) = self.edges.last_mut() {\n                    combine_vertical(&edge, last)\n                } else {\n                    Combine::No\n                }\n            } else {\n                Combine::No\n            };\n\n            match combine {\n                Combine::Total => {\n                    self.edges.pop();\n                }\n                Combine::Partial => {}\n                Combine::No => self.edges.push(Edge::Line(edge)),\n            }\n        }\n    }\n\n    fn push_quad(&mut self, points: &[Point]) {\n        if let Some(edge) = QuadraticEdge::new(points, self.clip_shift) {\n            self.edges.push(Edge::Quadratic(edge));\n        }\n    }\n\n    fn push_cubic(&mut self, points: &[Point]) {\n        if let Some(edge) = CubicEdge::new(points, self.clip_shift) {\n            self.edges.push(Edge::Cubic(edge));\n        }\n    }\n}\n\nfn combine_vertical(edge: &LineEdge, last: &mut LineEdge) -> Combine {\n    if last.dx != 0 || edge.x != last.x {\n        return Combine::No;\n    }\n\n    if edge.winding == last.winding {\n        return if edge.last_y + 1 == last.first_y {\n            last.first_y = edge.first_y;\n            Combine::Partial\n        } else if edge.first_y == last.last_y + 1 {\n            last.last_y = edge.last_y;\n            Combine::Partial\n        } else {\n            Combine::No\n        };\n    }\n\n    if edge.first_y == last.first_y {\n        return if edge.last_y == last.last_y {\n            Combine::Total\n        } else if edge.last_y < last.last_y {\n            last.first_y = edge.last_y + 1;\n            Combine::Partial\n        } else {\n            last.first_y = last.last_y + 1;\n            last.last_y = edge.last_y;\n            last.winding = edge.winding;\n            Combine::Partial\n        };\n    }\n\n    if edge.last_y == last.last_y {\n        if edge.first_y > last.first_y {\n            last.last_y = edge.first_y - 1;\n        } else {\n            last.last_y = last.first_y - 1;\n            last.first_y = edge.first_y;\n            last.winding = edge.winding;\n        }\n\n        return Combine::Partial;\n    }\n\n    Combine::No\n}\n\npub fn edge_iter(path: &Path) -> PathEdgeIter {\n    PathEdgeIter {\n        path,\n        verb_index: 0,\n        points_index: 0,\n        move_to: Point::zero(),\n        needs_close_line: false,\n    }\n}\n\n#[derive(Copy, Clone, PartialEq, Debug)]\npub enum PathEdge {\n    LineTo(Point, Point),\n    QuadTo(Point, Point, Point),\n    CubicTo(Point, Point, Point, Point),\n}\n\n/// Lightweight variant of PathIter that only returns segments (e.g. lines/quads).\n///\n/// Does not return Move or Close. Always \"auto-closes\" each contour.\npub struct PathEdgeIter<'a> {\n    path: &'a Path,\n    verb_index: usize,\n    points_index: usize,\n    move_to: Point,\n    needs_close_line: bool,\n}\n\nimpl<'a> PathEdgeIter<'a> {\n    fn close_line(&mut self) -> Option<PathEdge> {\n        self.needs_close_line = false;\n\n        let edge = PathEdge::LineTo(self.path.points()[self.points_index - 1], self.move_to);\n        Some(edge)\n    }\n}\n\nimpl<'a> Iterator for PathEdgeIter<'a> {\n    type Item = PathEdge;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.verb_index < self.path.verbs().len() {\n            let verb = self.path.verbs()[self.verb_index];\n            self.verb_index += 1;\n\n            match verb {\n                PathVerb::Move => {\n                    if self.needs_close_line {\n                        let res = self.close_line();\n                        self.move_to = self.path.points()[self.points_index];\n                        self.points_index += 1;\n                        return res;\n                    }\n\n                    self.move_to = self.path.points()[self.points_index];\n                    self.points_index += 1;\n                    self.next()\n                }\n                PathVerb::Close => {\n                    if self.needs_close_line {\n                        return self.close_line();\n                    }\n\n                    self.next()\n                }\n                _ => {\n                    // Actual edge.\n                    self.needs_close_line = true;\n\n                    let edge;\n                    match verb {\n                        PathVerb::Line => {\n                            edge = PathEdge::LineTo(\n                                self.path.points()[self.points_index - 1],\n                                self.path.points()[self.points_index + 0],\n                            );\n                            self.points_index += 1;\n                        }\n                        PathVerb::Quad => {\n                            edge = PathEdge::QuadTo(\n                                self.path.points()[self.points_index - 1],\n                                self.path.points()[self.points_index + 0],\n                                self.path.points()[self.points_index + 1],\n                            );\n                            self.points_index += 2;\n                        }\n                        PathVerb::Cubic => {\n                            edge = PathEdge::CubicTo(\n                                self.path.points()[self.points_index - 1],\n                                self.path.points()[self.points_index + 0],\n                                self.path.points()[self.points_index + 1],\n                                self.path.points()[self.points_index + 2],\n                            );\n                            self.points_index += 3;\n                        }\n                        _ => unreachable!(),\n                    };\n\n                    Some(edge)\n                }\n            }\n        } else if self.needs_close_line {\n            self.close_line()\n        } else {\n            None\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/edge_clipper.rs",
      "sha256": "ecc3c4ea2da87cc4dce22a8e61b828528bee875ec096ce53f2c580aa2d493dc2",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2009 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse arrayvec::ArrayVec;\n\nuse tiny_skia_path::{NormalizedF32Exclusive, SCALAR_MAX};\n\nuse crate::{Path, Point, Rect};\n\nuse crate::edge_builder::{edge_iter, PathEdge, PathEdgeIter};\nuse crate::line_clipper;\nuse crate::path_geometry;\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\n// This is a fail-safe `arr[n..n+3].try_into().unwrap()` alternative.\n// Everything is checked at compile-time so there is no bound checking and panics.\nmacro_rules! copy_3_points {\n    ($arr:expr, $i:expr) => {\n        [$arr[$i], $arr[$i + 1], $arr[$i + 2]]\n    };\n}\n\nmacro_rules! copy_4_points {\n    ($arr:expr, $i:expr) => {\n        [$arr[$i], $arr[$i + 1], $arr[$i + 2], $arr[$i + 3]]\n    };\n}\n\n/// Max curvature in X and Y split cubic into 9 pieces, * (line + cubic).\nconst MAX_VERBS: usize = 18;\n\npub type ClippedEdges = ArrayVec<PathEdge, MAX_VERBS>;\n\npub struct EdgeClipper {\n    clip: Rect,\n    can_cull_to_the_right: bool,\n    edges: ClippedEdges,\n}\n\nimpl EdgeClipper {\n    fn new(clip: Rect, can_cull_to_the_right: bool) -> Self {\n        EdgeClipper {\n            clip,\n            can_cull_to_the_right,\n            edges: ArrayVec::new(),\n        }\n    }\n\n    fn clip_line(mut self, p0: Point, p1: Point) -> Option<ClippedEdges> {\n        let mut points = [Point::zero(); line_clipper::MAX_POINTS];\n        let points = line_clipper::clip(\n            &[p0, p1],\n            &self.clip,\n            self.can_cull_to_the_right,\n            &mut points,\n        );\n        if !points.is_empty() {\n            for i in 0..points.len() - 1 {\n                self.push_line(points[i], points[i + 1]);\n            }\n        }\n\n        if self.edges.is_empty() {\n            None\n        } else {\n            Some(self.edges)\n        }\n    }\n\n    fn push_line(&mut self, p0: Point, p1: Point) {\n        self.edges.push(PathEdge::LineTo(p0, p1));\n    }\n\n    fn push_vline(&mut self, x: f32, mut y0: f32, mut y1: f32, reverse: bool) {\n        if reverse {\n            core::mem::swap(&mut y0, &mut y1);\n        }\n\n        self.edges.push(PathEdge::LineTo(\n            Point::from_xy(x, y0),\n            Point::from_xy(x, y1),\n        ));\n    }\n\n    fn clip_quad(mut self, p0: Point, p1: Point, p2: Point) -> Option<ClippedEdges> {\n        let pts = [p0, p1, p2];\n        let bounds = Rect::from_points(&pts)?;\n\n        if !quick_reject(&bounds, &self.clip) {\n            let mut mono_y = [Point::zero(); 5];\n            let count_y = path_geometry::chop_quad_at_y_extrema(&pts, &mut mono_y);\n            for y in 0..=count_y {\n                let mut mono_x = [Point::zero(); 5];\n                let y_points: [Point; 3] = copy_3_points!(mono_y, y * 2);\n                let count_x = path_geometry::chop_quad_at_x_extrema(&y_points, &mut mono_x);\n                for x in 0..=count_x {\n                    let x_points: [Point; 3] = copy_3_points!(mono_x, x * 2);\n                    self.clip_mono_quad(&x_points);\n                }\n            }\n        }\n\n        if self.edges.is_empty() {\n            None\n        } else {\n            Some(self.edges)\n        }\n    }\n\n    // src[] must be monotonic in X and Y\n    fn clip_mono_quad(&mut self, src: &[Point; 3]) {\n        let mut pts = [Point::zero(); 3];\n        let mut reverse = sort_increasing_y(src, &mut pts);\n\n        // are we completely above or below\n        if pts[2].y <= self.clip.top() || pts[0].y >= self.clip.bottom() {\n            return;\n        }\n\n        // Now chop so that pts is contained within clip in Y\n        chop_quad_in_y(&self.clip, &mut pts);\n\n        if pts[0].x > pts[2].x {\n            pts.swap(0, 2);\n            reverse = !reverse;\n        }\n        debug_assert!(pts[0].x <= pts[1].x);\n        debug_assert!(pts[1].x <= pts[2].x);\n\n        // Now chop in X has needed, and record the segments\n\n        if pts[2].x <= self.clip.left() {\n            // wholly to the left\n            self.push_vline(self.clip.left(), pts[0].y, pts[2].y, reverse);\n            return;\n        }\n\n        if pts[0].x >= self.clip.right() {\n            // wholly to the right\n            if !self.can_cull_to_the_right {\n                self.push_vline(self.clip.right(), pts[0].y, pts[2].y, reverse);\n            }\n\n            return;\n        }\n\n        let mut t = NormalizedF32Exclusive::ANY;\n        let mut tmp = [Point::zero(); 5];\n\n        // are we partially to the left\n        if pts[0].x < self.clip.left() {\n            if chop_mono_quad_at_x(&pts, self.clip.left(), &mut t) {\n                path_geometry::chop_quad_at(&pts, t, &mut tmp);\n                self.push_vline(self.clip.left(), tmp[0].y, tmp[2].y, reverse);\n                // clamp to clean up imprecise numerics in the chop\n                tmp[2].x = self.clip.left();\n                tmp[3].x = tmp[3].x.max(self.clip.left());\n\n                pts[0] = tmp[2];\n                pts[1] = tmp[3];\n            } else {\n                // if chopMonoQuadAtY failed, then we may have hit inexact numerics\n                // so we just clamp against the left\n                self.push_vline(self.clip.left(), pts[0].y, pts[2].y, reverse);\n                return;\n            }\n        }\n\n        // are we partially to the right\n        if pts[2].x > self.clip.right() {\n            if chop_mono_quad_at_x(&pts, self.clip.right(), &mut t) {\n                path_geometry::chop_quad_at(&pts, t, &mut tmp);\n                // clamp to clean up imprecise numerics in the chop\n                tmp[1].x = tmp[1].x.min(self.clip.right());\n                tmp[2].x = self.clip.right();\n\n                self.push_quad(&copy_3_points!(tmp, 0), reverse);\n                self.push_vline(self.clip.right(), tmp[2].y, tmp[4].y, reverse);\n            } else {\n                // if chopMonoQuadAtY failed, then we may have hit inexact numerics\n                // so we just clamp against the right\n                pts[1].x = pts[1].x.min(self.clip.right());\n                pts[2].x = pts[2].x.min(self.clip.right());\n                self.push_quad(&pts, reverse);\n            }\n        } else {\n            // wholly inside the clip\n            self.push_quad(&pts, reverse);\n        }\n    }\n\n    fn push_quad(&mut self, pts: &[Point; 3], reverse: bool) {\n        if reverse {\n            self.edges.push(PathEdge::QuadTo(pts[2], pts[1], pts[0]));\n        } else {\n            self.edges.push(PathEdge::QuadTo(pts[0], pts[1], pts[2]));\n        }\n    }\n\n    fn clip_cubic(mut self, p0: Point, p1: Point, p2: Point, p3: Point) -> Option<ClippedEdges> {\n        let pts = [p0, p1, p2, p3];\n        let bounds = Rect::from_points(&pts)?;\n\n        // check if we're clipped out vertically\n        if bounds.bottom() > self.clip.top() && bounds.top() < self.clip.bottom() {\n            if too_big_for_reliable_float_math(&bounds) {\n                // can't safely clip the cubic, so we give up and draw a line (which we can safely clip)\n                //\n                // If we rewrote chopcubicat*extrema and chopmonocubic using doubles, we could very\n                // likely always handle the cubic safely, but (it seems) at a big loss in speed, so\n                // we'd only want to take that alternate impl if needed.\n                return self.clip_line(p0, p3);\n            } else {\n                let mut mono_y = [Point::zero(); 10];\n                let count_y = path_geometry::chop_cubic_at_y_extrema(&pts, &mut mono_y);\n                for y in 0..=count_y {\n                    let mut mono_x = [Point::zero(); 10];\n                    let y_points: [Point; 4] = copy_4_points!(mono_y, y * 3);\n                    let count_x = path_geometry::chop_cubic_at_x_extrema(&y_points, &mut mono_x);\n                    for x in 0..=count_x {\n                        let x_points: [Point; 4] = copy_4_points!(mono_x, x * 3);\n                        self.clip_mono_cubic(&x_points);\n                    }\n                }\n            }\n        }\n\n        if self.edges.is_empty() {\n            None\n        } else {\n            Some(self.edges)\n        }\n    }\n\n    // src[] must be monotonic in X and Y\n    fn clip_mono_cubic(&mut self, src: &[Point; 4]) {\n        let mut pts = [Point::zero(); 4];\n        let mut reverse = sort_increasing_y(src, &mut pts);\n\n        // are we completely above or below\n        if pts[3].y <= self.clip.top() || pts[0].y >= self.clip.bottom() {\n            return;\n        }\n\n        // Now chop so that pts is contained within clip in Y\n        chop_cubic_in_y(&self.clip, &mut pts);\n\n        if pts[0].x > pts[3].x {\n            pts.swap(0, 3);\n            pts.swap(1, 2);\n            reverse = !reverse;\n        }\n\n        // Now chop in X has needed, and record the segments\n\n        if pts[3].x <= self.clip.left() {\n            // wholly to the left\n            self.push_vline(self.clip.left(), pts[0].y, pts[3].y, reverse);\n            return;\n        }\n\n        if pts[0].x >= self.clip.right() {\n            // wholly to the right\n            if !self.can_cull_to_the_right {\n                self.push_vline(self.clip.right(), pts[0].y, pts[3].y, reverse);\n            }\n\n            return;\n        }\n\n        // are we partially to the left\n        if pts[0].x < self.clip.left() {\n            let mut tmp = [Point::zero(); 7];\n            chop_mono_cubic_at_x(&pts, self.clip.left(), &mut tmp);\n            self.push_vline(self.clip.left(), tmp[0].y, tmp[3].y, reverse);\n\n            // tmp[3, 4].fX should all be to the right of clip.left().\n            // Since we can't trust the numerics of\n            // the chopper, we force those conditions now\n            tmp[3].x = self.clip.left();\n            tmp[4].x = tmp[4].x.max(self.clip.left());\n\n            pts[0] = tmp[3];\n            pts[1] = tmp[4];\n            pts[2] = tmp[5];\n        }\n\n        // are we partially to the right\n        if pts[3].x > self.clip.right() {\n            let mut tmp = [Point::zero(); 7];\n            chop_mono_cubic_at_x(&pts, self.clip.right(), &mut tmp);\n            tmp[3].x = self.clip.right();\n            tmp[2].x = tmp[2].x.min(self.clip.right());\n\n            self.push_cubic(&copy_4_points!(tmp, 0), reverse);\n            self.push_vline(self.clip.right(), tmp[3].y, tmp[6].y, reverse);\n        } else {\n            // wholly inside the clip\n            self.push_cubic(&pts, reverse);\n        }\n    }\n\n    fn push_cubic(&mut self, pts: &[Point; 4], reverse: bool) {\n        if reverse {\n            self.edges\n                .push(PathEdge::CubicTo(pts[3], pts[2], pts[1], pts[0]));\n        } else {\n            self.edges\n                .push(PathEdge::CubicTo(pts[0], pts[1], pts[2], pts[3]));\n        }\n    }\n}\n\npub struct EdgeClipperIter<'a> {\n    edge_iter: PathEdgeIter<'a>,\n    clip: Rect,\n    can_cull_to_the_right: bool,\n}\n\nimpl<'a> EdgeClipperIter<'a> {\n    pub fn new(path: &'a Path, clip: Rect, can_cull_to_the_right: bool) -> Self {\n        EdgeClipperIter {\n            edge_iter: edge_iter(path),\n            clip,\n            can_cull_to_the_right,\n        }\n    }\n}\n\nimpl Iterator for EdgeClipperIter<'_> {\n    type Item = ClippedEdges;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        for edge in &mut self.edge_iter {\n            let clipper = EdgeClipper::new(self.clip, self.can_cull_to_the_right);\n\n            match edge {\n                PathEdge::LineTo(p0, p1) => {\n                    if let Some(edges) = clipper.clip_line(p0, p1) {\n                        return Some(edges);\n                    }\n                }\n                PathEdge::QuadTo(p0, p1, p2) => {\n                    if let Some(edges) = clipper.clip_quad(p0, p1, p2) {\n                        return Some(edges);\n                    }\n                }\n                PathEdge::CubicTo(p0, p1, p2, p3) => {\n                    if let Some(edges) = clipper.clip_cubic(p0, p1, p2, p3) {\n                        return Some(edges);\n                    }\n                }\n            }\n        }\n\n        None\n    }\n}\n\nfn quick_reject(bounds: &Rect, clip: &Rect) -> bool {\n    bounds.top() >= clip.bottom() || bounds.bottom() <= clip.top()\n}\n\n// src[] must be monotonic in Y. This routine copies src into dst, and sorts\n// it to be increasing in Y. If it had to reverse the order of the points,\n// it returns true, otherwise it returns false\nfn sort_increasing_y(src: &[Point], dst: &mut [Point]) -> bool {\n    // We need the data to be monotonically increasing in Y.\n    // Never fails, because src is always non-empty.\n    if src[0].y > src.last().unwrap().y {\n        for (i, p) in src.iter().rev().enumerate() {\n            dst[i] = *p;\n        }\n\n        true\n    } else {\n        dst[0..src.len()].copy_from_slice(src);\n        false\n    }\n}\n\n/// Modifies pts[] in place so that it is clipped in Y to the clip rect.\nfn chop_quad_in_y(clip: &Rect, pts: &mut [Point; 3]) {\n    let mut t = NormalizedF32Exclusive::ANY;\n    let mut tmp = [Point::zero(); 5];\n\n    // are we partially above\n    if pts[0].y < clip.top() {\n        if chop_mono_quad_at_y(pts, clip.top(), &mut t) {\n            // take the 2nd chopped quad\n            path_geometry::chop_quad_at(pts, t, &mut tmp);\n            // clamp to clean up imprecise numerics in the chop\n            tmp[2].y = clip.top();\n            tmp[3].y = tmp[3].y.max(clip.top());\n\n            pts[0] = tmp[2];\n            pts[1] = tmp[3];\n        } else {\n            // if chop_mono_quad_at_y failed, then we may have hit inexact numerics\n            // so we just clamp against the top\n            for p in pts.iter_mut() {\n                if p.y < clip.top() {\n                    p.y = clip.top();\n                }\n            }\n        }\n    }\n\n    // are we partially below\n    if pts[2].y > clip.bottom() {\n        if chop_mono_quad_at_y(pts, clip.bottom(), &mut t) {\n            path_geometry::chop_quad_at(pts, t, &mut tmp);\n            // clamp to clean up imprecise numerics in the chop\n            tmp[1].y = tmp[1].y.min(clip.bottom());\n            tmp[2].y = clip.bottom();\n\n            pts[1] = tmp[1];\n            pts[2] = tmp[2];\n        } else {\n            // if chop_mono_quad_at_y failed, then we may have hit inexact numerics\n            // so we just clamp against the bottom\n            for p in pts.iter_mut() {\n                if p.y > clip.bottom() {\n                    p.y = clip.bottom();\n                }\n            }\n        }\n    }\n}\n\nfn chop_mono_quad_at_x(pts: &[Point; 3], x: f32, t: &mut NormalizedF32Exclusive) -> bool {\n    chop_mono_quad_at(pts[0].x, pts[1].x, pts[2].x, x, t)\n}\n\nfn chop_mono_quad_at_y(pts: &[Point; 3], y: f32, t: &mut NormalizedF32Exclusive) -> bool {\n    chop_mono_quad_at(pts[0].y, pts[1].y, pts[2].y, y, t)\n}\n\nfn chop_mono_quad_at(\n    c0: f32,\n    c1: f32,\n    c2: f32,\n    target: f32,\n    t: &mut NormalizedF32Exclusive,\n) -> bool {\n    // Solve F(t) = y where F(t) := [0](1-t)^2 + 2[1]t(1-t) + [2]t^2\n    // We solve for t, using quadratic equation, hence we have to rearrange\n    // our coefficients to look like At^2 + Bt + C\n    let a = c0 - c1 - c1 + c2;\n    let b = 2.0 * (c1 - c0);\n    let c = c0 - target;\n\n    let mut roots = path_geometry::new_t_values();\n    let count = path_geometry::find_unit_quad_roots(a, b, c, &mut roots);\n    if count != 0 {\n        *t = roots[0];\n        true\n    } else {\n        false\n    }\n}\n\nfn too_big_for_reliable_float_math(r: &Rect) -> bool {\n    // limit set as the largest float value for which we can still reliably compute things like\n    // - chopping at XY extrema\n    // - chopping at Y or X values for clipping\n    //\n    // Current value chosen just by experiment. Larger (and still succeeds) is always better.\n\n    let limit = (1 << 22) as f32;\n    r.left() < -limit || r.top() < -limit || r.right() > limit || r.bottom() > limit\n}\n\n/// Modifies pts[] in place so that it is clipped in Y to the clip rect.\nfn chop_cubic_in_y(clip: &Rect, pts: &mut [Point; 4]) {\n    // are we partially above\n    if pts[0].y < clip.top() {\n        let mut tmp = [Point::zero(); 7];\n        chop_mono_cubic_at_y(pts, clip.top(), &mut tmp);\n\n        // For a large range in the points, we can do a poor job of chopping, such that the t\n        // we computed resulted in the lower cubic still being partly above the clip.\n        //\n        // If just the first or first 2 Y values are above the fTop, we can just smash them\n        // down. If the first 3 Ys are above fTop, we can't smash all 3, as that can really\n        // distort the cubic. In this case, we take the first output (tmp[3..6] and treat it as\n        // a guess, and re-chop against fTop. Then we fall through to checking if we need to\n        // smash the first 1 or 2 Y values.\n        if tmp[3].y < clip.top() && tmp[4].y < clip.top() && tmp[5].y < clip.top() {\n            let tmp2: [Point; 4] = copy_4_points!(tmp, 3);\n            chop_mono_cubic_at_y(&tmp2, clip.top(), &mut tmp);\n        }\n\n        // tmp[3, 4].y should all be to the below clip.fTop.\n        // Since we can't trust the numerics of the chopper, we force those conditions now\n        tmp[3].y = clip.top();\n        tmp[4].y = tmp[4].y.max(clip.top());\n\n        pts[0] = tmp[3];\n        pts[1] = tmp[4];\n        pts[2] = tmp[5];\n    }\n\n    // are we partially below\n    if pts[3].y > clip.bottom() {\n        let mut tmp = [Point::zero(); 7];\n        chop_mono_cubic_at_y(pts, clip.bottom(), &mut tmp);\n        tmp[3].y = clip.bottom();\n        tmp[2].y = tmp[2].y.min(clip.bottom());\n\n        pts[1] = tmp[1];\n        pts[2] = tmp[2];\n        pts[3] = tmp[3];\n    }\n}\n\nfn chop_mono_cubic_at_x(src: &[Point; 4], x: f32, dst: &mut [Point; 7]) {\n    if path_geometry::chop_mono_cubic_at_x(src, x, dst) {\n        return;\n    }\n\n    let src_values = [src[0].x, src[1].x, src[2].x, src[3].x];\n    path_geometry::chop_cubic_at2(src, mono_cubic_closest_t(&src_values, x), dst);\n}\n\nfn chop_mono_cubic_at_y(src: &[Point; 4], y: f32, dst: &mut [Point; 7]) {\n    if path_geometry::chop_mono_cubic_at_y(src, y, dst) {\n        return;\n    }\n\n    let src_values = [src[0].y, src[1].y, src[2].y, src[3].y];\n    path_geometry::chop_cubic_at2(src, mono_cubic_closest_t(&src_values, y), dst);\n}\n\nfn mono_cubic_closest_t(src: &[f32; 4], mut x: f32) -> NormalizedF32Exclusive {\n    let mut t = 0.5;\n    let mut last_t;\n    let mut best_t = t;\n    let mut step = 0.25;\n    let d = src[0];\n    let a = src[3] + 3.0 * (src[1] - src[2]) - d;\n    let b = 3.0 * (src[2] - src[1] - src[1] + d);\n    let c = 3.0 * (src[1] - d);\n    x -= d;\n    let mut closest = SCALAR_MAX;\n    loop {\n        let loc = ((a * t + b) * t + c) * t;\n        let dist = (loc - x).abs();\n        if closest > dist {\n            closest = dist;\n            best_t = t;\n        }\n\n        last_t = t;\n        t += if loc < x { step } else { -step };\n        step *= 0.5;\n\n        if !(closest > 0.25 && last_t != t) {\n            break;\n        }\n    }\n\n    NormalizedF32Exclusive::new(best_t).unwrap()\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/fixed_point.rs",
      "sha256": "9bf2c97418e0640fbcadcdb34ca3bf2c4c6ca9aee746d1b4acbf4d4d8c9d712d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Skia uses fixed points pretty chaotically, therefore we cannot use\n// strongly typed wrappers. Which is unfortunate.\n\nuse tiny_skia_path::SaturateCast;\n\nuse crate::math::{bound, left_shift, left_shift64};\n\n/// A 26.6 fixed point.\npub type FDot6 = i32;\n\n/// A 24.8 fixed point.\npub type FDot8 = i32;\n\n/// A 16.16 fixed point.\npub type FDot16 = i32;\n\npub mod fdot6 {\n    use super::*;\n    use core::convert::TryFrom;\n\n    pub const ONE: FDot6 = 64;\n\n    pub fn from_i32(n: i32) -> FDot6 {\n        debug_assert!(n as i16 as i32 == n);\n        n << 6\n    }\n\n    pub fn from_f32(n: f32) -> FDot6 {\n        (n * 64.0) as i32\n    }\n\n    pub fn floor(n: FDot6) -> FDot6 {\n        n >> 6\n    }\n\n    pub fn ceil(n: FDot6) -> FDot6 {\n        (n + 63) >> 6\n    }\n\n    pub fn round(n: FDot6) -> FDot6 {\n        (n + 32) >> 6\n    }\n\n    pub fn to_fdot16(n: FDot6) -> FDot16 {\n        debug_assert!((left_shift(n, 10) >> 10) == n);\n        left_shift(n, 10)\n    }\n\n    pub fn div(a: FDot6, b: FDot6) -> FDot16 {\n        debug_assert_ne!(b, 0);\n\n        if i16::try_from(a).is_ok() {\n            left_shift(a, 16) / b\n        } else {\n            fdot16::div(a, b)\n        }\n    }\n\n    pub fn can_convert_to_fdot16(n: FDot6) -> bool {\n        let max_dot6 = core::i32::MAX >> (16 - 6);\n        n.abs() <= max_dot6\n    }\n\n    pub fn small_scale(value: u8, dot6: FDot6) -> u8 {\n        debug_assert!(dot6 as u32 <= 64);\n        ((value as i32 * dot6) >> 6) as u8\n    }\n}\n\npub mod fdot8 {\n    use super::*;\n\n    // Extracted from SkScan_Antihair.cpp\n\n    pub fn from_fdot16(x: FDot16) -> FDot8 {\n        (x + 0x80) >> 8\n    }\n}\n\npub mod fdot16 {\n    use super::*;\n\n    pub const HALF: FDot16 = (1 << 16) / 2;\n    pub const ONE: FDot16 = 1 << 16;\n\n    // `from_f32` seems to lack a rounding step. For all fixed-point\n    // values, this version is as accurate as possible for (fixed -> float -> fixed). Rounding reduces\n    // accuracy if the intermediate floats are in the range that only holds integers (adding 0.5 to an\n    // odd integer then snaps to nearest even). Using double for the rounding math gives maximum\n    // accuracy for (float -> fixed -> float), but that's usually overkill.\n    pub fn from_f32(x: f32) -> FDot16 {\n        i32::saturate_from(x * ONE as f32)\n    }\n\n    pub fn floor_to_i32(x: FDot16) -> i32 {\n        x >> 16\n    }\n\n    pub fn ceil_to_i32(x: FDot16) -> i32 {\n        (x + ONE - 1) >> 16\n    }\n\n    pub fn round_to_i32(x: FDot16) -> i32 {\n        (x + HALF) >> 16\n    }\n\n    // The divide may exceed 32 bits. Clamp to a signed 32 bit result.\n    pub fn mul(a: FDot16, b: FDot16) -> FDot16 {\n        ((i64::from(a) * i64::from(b)) >> 16) as FDot16\n    }\n\n    // The divide may exceed 32 bits. Clamp to a signed 32 bit result.\n    pub fn div(numer: FDot6, denom: FDot6) -> FDot16 {\n        let v = left_shift64(numer as i64, 16) / denom as i64;\n        let n = bound(i32::MIN as i64, v, i32::MAX as i64);\n        n as i32\n    }\n\n    pub fn fast_div(a: FDot6, b: FDot6) -> FDot16 {\n        debug_assert!((left_shift(a, 16) >> 16) == a);\n        debug_assert!(b != 0);\n        left_shift(a, 16) / b\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/geom.rs",
      "sha256": "5bdfe8f1633e392f98c78a503f12bad13bb01afdfc4dcd116c13fecedc916f37",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse core::convert::TryFrom;\n\nuse tiny_skia_path::{IntRect, IntSize, Rect};\n\nuse crate::LengthU32;\n\n/// A screen `IntRect`.\n///\n/// # Guarantees\n///\n/// - X and Y are in 0..=i32::MAX range.\n/// - Width and height are in 1..=i32::MAX range.\n/// - x+width and y+height does not overflow.\n#[allow(missing_docs)]\n#[derive(Copy, Clone, PartialEq, Debug)]\npub struct ScreenIntRect {\n    x: u32,\n    y: u32,\n    width: LengthU32,\n    height: LengthU32,\n}\n\nimpl ScreenIntRect {\n    /// Creates a new `ScreenIntRect`.\n    pub fn from_xywh(x: u32, y: u32, width: u32, height: u32) -> Option<Self> {\n        i32::try_from(x).ok()?;\n        i32::try_from(y).ok()?;\n        i32::try_from(width).ok()?;\n        i32::try_from(height).ok()?;\n\n        x.checked_add(width)?;\n        y.checked_add(height)?;\n\n        let width = LengthU32::new(width)?;\n        let height = LengthU32::new(height)?;\n\n        Some(ScreenIntRect {\n            x,\n            y,\n            width,\n            height,\n        })\n    }\n\n    /// Creates a new `ScreenIntRect`.\n    pub const fn from_xywh_safe(x: u32, y: u32, width: LengthU32, height: LengthU32) -> Self {\n        ScreenIntRect {\n            x,\n            y,\n            width,\n            height,\n        }\n    }\n\n    /// Returns rect's X position.\n    pub fn x(&self) -> u32 {\n        self.x\n    }\n\n    /// Returns rect's Y position.\n    pub fn y(&self) -> u32 {\n        self.y\n    }\n\n    /// Returns rect's width.\n    pub fn width(&self) -> u32 {\n        self.width.get()\n    }\n\n    /// Returns rect's height.\n    pub fn height(&self) -> u32 {\n        self.height.get()\n    }\n\n    /// Returns rect's width.\n    pub fn width_safe(&self) -> LengthU32 {\n        self.width\n    }\n\n    /// Returns rect's left edge.\n    pub fn left(&self) -> u32 {\n        self.x\n    }\n\n    /// Returns rect's top edge.\n    pub fn top(&self) -> u32 {\n        self.y\n    }\n\n    /// Returns rect's right edge.\n    ///\n    /// The right edge is at least 1.\n    pub fn right(&self) -> u32 {\n        // No overflow is guaranteed by constructors.\n        self.x + self.width.get()\n    }\n\n    /// Returns rect's bottom edge.\n    ///\n    /// The bottom edge is at least 1.\n    pub fn bottom(&self) -> u32 {\n        // No overflow is guaranteed by constructors.\n        self.y + self.height.get()\n    }\n\n    /// Returns rect's size.\n    pub fn size(&self) -> IntSize {\n        IntSize::from_wh(self.width(), self.height()).unwrap()\n    }\n\n    /// Checks that the rect is completely includes `other` Rect.\n    pub fn contains(&self, other: &Self) -> bool {\n        self.x <= other.x\n            && self.y <= other.y\n            && self.right() >= other.right()\n            && self.bottom() >= other.bottom()\n    }\n\n    /// Converts into a `IntRect`.\n    pub fn to_int_rect(&self) -> IntRect {\n        // Everything is already checked by constructors.\n        IntRect::from_xywh(\n            self.x as i32,\n            self.y as i32,\n            self.width.get(),\n            self.height.get(),\n        )\n        .unwrap()\n    }\n\n    /// Converts into a `Rect`.\n    pub fn to_rect(&self) -> Rect {\n        // Can't fail, because `ScreenIntRect` is always valid.\n        // And u32 always fits into f32.\n        Rect::from_ltrb(\n            self.x as f32,\n            self.y as f32,\n            self.x as f32 + self.width.get() as f32,\n            self.y as f32 + self.height.get() as f32,\n        )\n        .unwrap()\n    }\n}\n\n#[cfg(test)]\nmod screen_int_rect_tests {\n    use super::*;\n\n    #[test]\n    fn tests() {\n        assert_eq!(ScreenIntRect::from_xywh(0, 0, 0, 0), None);\n        assert_eq!(ScreenIntRect::from_xywh(0, 0, 1, 0), None);\n        assert_eq!(ScreenIntRect::from_xywh(0, 0, 0, 1), None);\n\n        assert_eq!(\n            ScreenIntRect::from_xywh(0, 0, core::u32::MAX, core::u32::MAX),\n            None\n        );\n        assert_eq!(ScreenIntRect::from_xywh(0, 0, 1, core::u32::MAX), None);\n        assert_eq!(ScreenIntRect::from_xywh(0, 0, core::u32::MAX, 1), None);\n\n        assert_eq!(ScreenIntRect::from_xywh(core::u32::MAX, 0, 1, 1), None);\n        assert_eq!(ScreenIntRect::from_xywh(0, core::u32::MAX, 1, 1), None);\n\n        assert_eq!(\n            ScreenIntRect::from_xywh(\n                core::u32::MAX,\n                core::u32::MAX,\n                core::u32::MAX,\n                core::u32::MAX\n            ),\n            None\n        );\n\n        let r = ScreenIntRect::from_xywh(1, 2, 3, 4).unwrap();\n        assert_eq!(r.x(), 1);\n        assert_eq!(r.y(), 2);\n        assert_eq!(r.width(), 3);\n        assert_eq!(r.height(), 4);\n        assert_eq!(r.right(), 4);\n        assert_eq!(r.bottom(), 6);\n    }\n}\n\npub trait IntSizeExt {\n    /// Converts the current size into a `IntRect` at a provided position.\n    fn to_screen_int_rect(&self, x: u32, y: u32) -> ScreenIntRect;\n}\n\nimpl IntSizeExt for IntSize {\n    fn to_screen_int_rect(&self, x: u32, y: u32) -> ScreenIntRect {\n        ScreenIntRect::from_xywh(x, y, self.width(), self.height()).unwrap()\n    }\n}\n\npub trait IntRectExt {\n    /// Converts into `ScreenIntRect`.\n    ///\n    /// # Checks\n    ///\n    /// - x >= 0\n    /// - y >= 0\n    fn to_screen_int_rect(&self) -> Option<ScreenIntRect>;\n}\n\nimpl IntRectExt for IntRect {\n    fn to_screen_int_rect(&self) -> Option<ScreenIntRect> {\n        let x = u32::try_from(self.x()).ok()?;\n        let y = u32::try_from(self.y()).ok()?;\n        ScreenIntRect::from_xywh(x, y, self.width(), self.height())\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/line_clipper.rs",
      "sha256": "b17d6ce38666a08f24d365551d10632c17edee5838943a31506c77417762e798",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2011 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse crate::{Point, Rect};\n\nuse tiny_skia_path::Scalar;\n\npub const MAX_POINTS: usize = 4;\n\n/// Clip the line pts[0]...pts[1] against clip, ignoring segments that\n/// lie completely above or below the clip. For portions to the left or\n/// right, turn those into vertical line segments that are aligned to the\n/// edge of the clip.\n///\n/// Return the number of line segments that result, and store the end-points\n/// of those segments sequentially in lines as follows:\n///\n/// 1st segment: lines[0]..lines[1]\n/// 2nd segment: lines[1]..lines[2]\n/// 3rd segment: lines[2]..lines[3]\npub fn clip<'a>(\n    src: &[Point; 2],\n    clip: &Rect,\n    can_cull_to_the_right: bool,\n    points: &'a mut [Point; MAX_POINTS],\n) -> &'a [Point] {\n    let (mut index0, mut index1) = if src[0].y < src[1].y { (0, 1) } else { (1, 0) };\n\n    // Check if we're completely clipped out in Y (above or below)\n\n    if src[index1].y <= clip.top() {\n        // we're above the clip\n        return &[];\n    }\n\n    if src[index0].y >= clip.bottom() {\n        // we're below the clip\n        return &[];\n    }\n\n    // Chop in Y to produce a single segment, stored in tmp[0..1]\n\n    let mut tmp = *src;\n\n    // now compute intersections\n    if src[index0].y < clip.top() {\n        tmp[index0] = Point::from_xy(sect_with_horizontal(src, clip.top()), clip.top());\n        debug_assert!(is_between_unsorted(tmp[index0].x, src[0].x, src[1].x));\n    }\n\n    if tmp[index1].y > clip.bottom() {\n        tmp[index1] = Point::from_xy(sect_with_horizontal(src, clip.bottom()), clip.bottom());\n        debug_assert!(is_between_unsorted(tmp[index1].x, src[0].x, src[1].x));\n    }\n\n    // Chop it into 1..3 segments that are wholly within the clip in X.\n\n    // temp storage for up to 3 segments\n    let mut result_storage = [Point::zero(); MAX_POINTS];\n    let mut line_count = 1;\n    let mut reverse;\n\n    if src[0].x < src[1].x {\n        index0 = 0;\n        index1 = 1;\n        reverse = false;\n    } else {\n        index0 = 1;\n        index1 = 0;\n        reverse = true;\n    }\n\n    let result: &[Point] = if tmp[index1].x <= clip.left() {\n        // wholly to the left\n        tmp[0].x = clip.left();\n        tmp[1].x = clip.left();\n        reverse = false;\n        &tmp\n    } else if tmp[index0].x >= clip.right() {\n        // wholly to the right\n        if can_cull_to_the_right {\n            return &[];\n        }\n\n        tmp[0].x = clip.right();\n        tmp[1].x = clip.right();\n        reverse = false;\n        &tmp\n    } else {\n        let mut offset = 0;\n\n        if tmp[index0].x < clip.left() {\n            result_storage[offset] = Point::from_xy(clip.left(), tmp[index0].y);\n            offset += 1;\n            result_storage[offset] =\n                Point::from_xy(clip.left(), sect_clamp_with_vertical(&tmp, clip.left()));\n            debug_assert!(is_between_unsorted(\n                result_storage[offset].y,\n                tmp[0].y,\n                tmp[1].y\n            ));\n        } else {\n            result_storage[offset] = tmp[index0];\n        }\n        offset += 1;\n\n        if tmp[index1].x > clip.right() {\n            result_storage[offset] =\n                Point::from_xy(clip.right(), sect_clamp_with_vertical(&tmp, clip.right()));\n            debug_assert!(is_between_unsorted(\n                result_storage[offset].y,\n                tmp[0].y,\n                tmp[1].y\n            ));\n            offset += 1;\n            result_storage[offset] = Point::from_xy(clip.right(), tmp[index1].y);\n        } else {\n            result_storage[offset] = tmp[index1];\n        }\n\n        line_count = offset;\n        &result_storage\n    };\n\n    // Now copy the results into the caller's lines[] parameter\n    if reverse {\n        // copy the pts in reverse order to maintain winding order\n        for i in 0..=line_count {\n            points[line_count - i] = result[i];\n        }\n    } else {\n        let len = line_count + 1;\n        points[0..len].copy_from_slice(&result[0..len]);\n    }\n\n    &points[0..line_count + 1]\n}\n\n/// Returns X coordinate of intersection with horizontal line at Y.\nfn sect_with_horizontal(src: &[Point; 2], y: f32) -> f32 {\n    let dy = src[1].y - src[0].y;\n    if dy.is_nearly_zero() {\n        src[0].x.ave(src[1].x)\n    } else {\n        // need the extra precision so we don't compute a value that exceeds\n        // our original limits\n        let x0 = f64::from(src[0].x);\n        let y0 = f64::from(src[0].y);\n        let x1 = f64::from(src[1].x);\n        let y1 = f64::from(src[1].y);\n        let result = x0 + (f64::from(y) - y0) * (x1 - x0) / (y1 - y0);\n\n        // The computed X value might still exceed [X0..X1] due to quantum flux\n        // when the doubles were added and subtracted, so we have to pin the\n        // answer :(\n        pin_unsorted_f64(result, x0, x1) as f32\n    }\n}\n\n/// Returns value between the two limits, where the limits are either ascending or descending.\nfn is_between_unsorted(value: f32, limit0: f32, limit1: f32) -> bool {\n    if limit0 < limit1 {\n        limit0 <= value && value <= limit1\n    } else {\n        limit1 <= value && value <= limit0\n    }\n}\n\nfn sect_clamp_with_vertical(src: &[Point; 2], x: f32) -> f32 {\n    let y = sect_with_vertical(src, x);\n    // Our caller expects y to be between src[0].y and src[1].y (unsorted), but due to the\n    // numerics of floats/doubles, we might have computed a value slightly outside of that,\n    // so we have to manually clamp afterwards.\n    // See skbug.com/7491\n    pin_unsorted_f32(y, src[0].y, src[1].y)\n}\n\n/// Returns Y coordinate of intersection with vertical line at X.\nfn sect_with_vertical(src: &[Point; 2], x: f32) -> f32 {\n    let dx = src[1].x - src[0].x;\n    if dx.is_nearly_zero() {\n        src[0].y.ave(src[1].y)\n    } else {\n        // need the extra precision so we don't compute a value that exceeds\n        // our original limits\n        let x0 = f64::from(src[0].x);\n        let y0 = f64::from(src[0].y);\n        let x1 = f64::from(src[1].x);\n        let y1 = f64::from(src[1].y);\n        let result = y0 + (f64::from(x) - x0) * (y1 - y0) / (x1 - x0);\n        result as f32\n    }\n}\n\nfn pin_unsorted_f32(value: f32, mut limit0: f32, mut limit1: f32) -> f32 {\n    if limit1 < limit0 {\n        core::mem::swap(&mut limit0, &mut limit1);\n    }\n    // now the limits are sorted\n    debug_assert!(limit0 <= limit1);\n\n    if value < limit0 {\n        limit0\n    } else if value > limit1 {\n        limit1\n    } else {\n        value\n    }\n}\n\nfn pin_unsorted_f64(value: f64, mut limit0: f64, mut limit1: f64) -> f64 {\n    if limit1 < limit0 {\n        core::mem::swap(&mut limit0, &mut limit1);\n    }\n    // now the limits are sorted\n    debug_assert!(limit0 <= limit1);\n\n    if value < limit0 {\n        limit0\n    } else if value > limit1 {\n        limit1\n    } else {\n        value\n    }\n}\n\n/// Intersect the line segment against the rect. If there is a non-empty\n/// resulting segment, return true and set dst[] to that segment. If not,\n/// return false and ignore dst[].\n///\n/// `clip` is specialized for scan-conversion, as it adds vertical\n/// segments on the sides to show where the line extended beyond the\n/// left or right sides. `intersect` does not.\npub fn intersect(src: &[Point; 2], clip: &Rect, dst: &mut [Point; 2]) -> bool {\n    let bounds = Rect::from_ltrb(\n        src[0].x.min(src[1].x),\n        src[0].y.min(src[1].y),\n        src[0].x.max(src[1].x),\n        src[0].y.max(src[1].y),\n    );\n\n    if let Some(bounds) = bounds {\n        if contains_no_empty_check(clip, &bounds) {\n            dst.copy_from_slice(src);\n            return true;\n        }\n\n        // check for no overlap, and only permit coincident edges if the line\n        // and the edge are colinear\n        if nested_lt(bounds.right(), clip.left(), bounds.width())\n            || nested_lt(clip.right(), bounds.left(), bounds.width())\n            || nested_lt(bounds.bottom(), clip.top(), bounds.height())\n            || nested_lt(clip.bottom(), bounds.top(), bounds.height())\n        {\n            return false;\n        }\n    }\n\n    let (index0, index1) = if src[0].y < src[1].y { (0, 1) } else { (1, 0) };\n\n    let mut tmp = src.clone();\n\n    // now compute Y intersections\n    if tmp[index0].y < clip.top() {\n        tmp[index0] = Point::from_xy(sect_with_horizontal(src, clip.top()), clip.top());\n    }\n\n    if tmp[index1].y > clip.bottom() {\n        tmp[index1] = Point::from_xy(sect_with_horizontal(src, clip.bottom()), clip.bottom());\n    }\n\n    let (index0, index1) = if tmp[0].x < tmp[1].x { (0, 1) } else { (1, 0) };\n\n    // check for quick-reject in X again, now that we may have been chopped\n    if tmp[index1].x <= clip.left() || tmp[index0].x >= clip.right() {\n        // usually we will return false, but we don't if the line is vertical and coincident\n        // with the clip.\n        if tmp[0].x != tmp[1].x || tmp[0].x < clip.left() || tmp[0].x > clip.right() {\n            return false;\n        }\n    }\n\n    if tmp[index0].x < clip.left() {\n        tmp[index0] = Point::from_xy(clip.left(), sect_with_vertical(src, clip.left()));\n    }\n\n    if tmp[index1].x > clip.right() {\n        tmp[index1] = Point::from_xy(clip.right(), sect_with_vertical(src, clip.right()));\n    }\n\n    dst.copy_from_slice(&tmp);\n    true\n}\n\nfn nested_lt(a: f32, b: f32, dim: f32) -> bool {\n    a <= b && (a < b || dim > 0.0)\n}\n\n// returns true if outer contains inner, even if inner is empty.\nfn contains_no_empty_check(outer: &Rect, inner: &Rect) -> bool {\n    outer.left() <= inner.left()\n        && outer.top() <= inner.top()\n        && outer.right() >= inner.right()\n        && outer.bottom() >= inner.bottom()\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/mask.rs",
      "sha256": "c0acccd67eb17082128647d81871aece69d80a1533835ac36a0e3d05cd5a56ce",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\nuse alloc::vec;\nuse alloc::vec::Vec;\n\nuse tiny_skia_path::{IntRect, IntSize, Path, Scalar, Transform};\n\nuse crate::geom::IntSizeExt;\nuse crate::painter::DrawTiler;\nuse crate::pipeline::RasterPipelineBlitter;\nuse crate::pixmap::SubPixmapMut;\nuse crate::scan;\nuse crate::{FillRule, PixmapRef};\n\n/// A mask type.\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum MaskType {\n    /// Transfers only the Alpha channel from `Pixmap` to `Mask`.\n    Alpha,\n    /// Transfers RGB channels as luminance from `Pixmap` to `Mask`.\n    ///\n    /// Formula: `Y = 0.2126 * R + 0.7152 * G + 0.0722 * B`\n    Luminance,\n}\n\n/// A mask.\n///\n/// During drawing over `Pixmap`, mask's black (0) \"pixels\" would block rendering\n/// and white (255) will allow it.\n/// Anything in between is used for gradual masking and anti-aliasing.\n///\n/// Unlike Skia, we're using just a simple 8bit alpha mask.\n/// It's way slower, but easier to implement.\n#[derive(Clone, PartialEq)]\npub struct Mask {\n    data: Vec<u8>,\n    size: IntSize,\n}\n\nimpl Mask {\n    /// Creates a new mask by taking ownership over a mask buffer.\n    ///\n    /// The size needs to match the data provided.\n    pub fn new(width: u32, height: u32) -> Option<Self> {\n        let size = IntSize::from_wh(width, height)?;\n        Some(Mask {\n            data: vec![0; width as usize * height as usize],\n            size,\n        })\n    }\n\n    /// Creates a new mask from a `PixmapRef`.\n    pub fn from_pixmap(pixmap: PixmapRef, mask_type: MaskType) -> Self {\n        let data_len = pixmap.width() as usize * pixmap.height() as usize;\n        let mut mask = Mask {\n            data: vec![0; data_len],\n            size: pixmap.size(),\n        };\n\n        // TODO: optimize\n        match mask_type {\n            MaskType::Alpha => {\n                for (p, a) in pixmap.pixels().iter().zip(mask.data.as_mut_slice()) {\n                    *a = p.alpha();\n                }\n            }\n            MaskType::Luminance => {\n                for (p, ma) in pixmap.pixels().iter().zip(mask.data.as_mut_slice()) {\n                    // Normalize.\n                    let mut r = f32::from(p.red()) / 255.0;\n                    let mut g = f32::from(p.green()) / 255.0;\n                    let mut b = f32::from(p.blue()) / 255.0;\n                    let a = f32::from(p.alpha()) / 255.0;\n\n                    // Demultiply.\n                    if p.alpha() != 0 {\n                        r /= a;\n                        g /= a;\n                        b /= a;\n                    }\n\n                    let luma = r * 0.2126 + g * 0.7152 + b * 0.0722;\n                    *ma = ((luma * a) * 255.0).clamp(0.0, 255.0).ceil() as u8;\n                }\n            }\n        }\n\n        mask\n    }\n\n    /// Creates a new mask by taking ownership over a mask buffer.\n    ///\n    /// The size needs to match the data provided.\n    pub fn from_vec(data: Vec<u8>, size: IntSize) -> Option<Self> {\n        let data_len = size.width() as usize * size.height() as usize;\n        if data.len() != data_len {\n            return None;\n        }\n\n        Some(Mask { data, size })\n    }\n\n    /// Returns mask's width.\n    #[inline]\n    pub fn width(&self) -> u32 {\n        self.size.width()\n    }\n\n    /// Returns mask's height.\n    #[inline]\n    pub fn height(&self) -> u32 {\n        self.size.height()\n    }\n\n    /// Returns mask's size.\n    #[allow(dead_code)]\n    pub(crate) fn size(&self) -> IntSize {\n        self.size\n    }\n\n    /// Returns the internal data.\n    pub fn data(&self) -> &[u8] {\n        self.data.as_slice()\n    }\n\n    /// Returns the mutable internal data.\n    pub fn data_mut(&mut self) -> &mut [u8] {\n        self.data.as_mut_slice()\n    }\n\n    pub(crate) fn as_submask<'a>(&'a self) -> SubMaskRef<'a> {\n        SubMaskRef {\n            size: self.size,\n            real_width: self.size.width(),\n            data: &self.data,\n        }\n    }\n\n    pub(crate) fn submask<'a>(&'a self, rect: IntRect) -> Option<SubMaskRef<'a>> {\n        let rect = self.size.to_int_rect(0, 0).intersect(&rect)?;\n        let row_bytes = self.width() as usize;\n        let offset = rect.top() as usize * row_bytes + rect.left() as usize;\n\n        Some(SubMaskRef {\n            size: rect.size(),\n            real_width: self.size.width(),\n            data: &self.data[offset..],\n        })\n    }\n\n    pub(crate) fn as_subpixmap<'a>(&'a mut self) -> SubPixmapMut<'a> {\n        SubPixmapMut {\n            size: self.size,\n            real_width: self.size.width() as usize,\n            data: &mut self.data,\n        }\n    }\n\n    pub(crate) fn subpixmap<'a>(&'a mut self, rect: IntRect) -> Option<SubPixmapMut<'a>> {\n        let rect = self.size.to_int_rect(0, 0).intersect(&rect)?;\n        let row_bytes = self.width() as usize;\n        let offset = rect.top() as usize * row_bytes + rect.left() as usize;\n\n        Some(SubPixmapMut {\n            size: rect.size(),\n            real_width: self.size.width() as usize,\n            data: &mut self.data[offset..],\n        })\n    }\n\n    /// Loads a PNG file into a `Mask`.\n    ///\n    /// Only grayscale images are supported.\n    #[cfg(feature = \"png-format\")]\n    pub fn decode_png(data: &[u8]) -> Result<Self, png::DecodingError> {\n        fn make_custom_png_error(msg: &str) -> png::DecodingError {\n            std::io::Error::new(std::io::ErrorKind::Other, msg).into()\n        }\n\n        let mut decoder = png::Decoder::new(data);\n        decoder.set_transformations(png::Transformations::normalize_to_color8());\n        let mut reader = decoder.read_info()?;\n        let mut img_data = vec![0; reader.output_buffer_size()];\n        let info = reader.next_frame(&mut img_data)?;\n\n        if info.bit_depth != png::BitDepth::Eight {\n            return Err(make_custom_png_error(\"unsupported bit depth\"));\n        }\n\n        if info.color_type != png::ColorType::Grayscale {\n            return Err(make_custom_png_error(\"only grayscale masks are supported\"));\n        }\n\n        let size = IntSize::from_wh(info.width, info.height)\n            .ok_or_else(|| make_custom_png_error(\"invalid image size\"))?;\n\n        Mask::from_vec(img_data, size)\n            .ok_or_else(|| make_custom_png_error(\"failed to create a mask\"))\n    }\n\n    /// Loads a PNG file into a `Mask`.\n    ///\n    /// Only grayscale images are supported.\n    #[cfg(feature = \"png-format\")]\n    pub fn load_png<P: AsRef<std::path::Path>>(path: P) -> Result<Self, png::DecodingError> {\n        // `png::Decoder` is generic over input, which means that it will instance\n        // two copies: one for `&[]` and one for `File`. Which will simply bloat the code.\n        // Therefore we're using only one type for input.\n        let data = std::fs::read(path)?;\n        Self::decode_png(&data)\n    }\n\n    /// Encodes mask into a PNG data.\n    #[cfg(feature = \"png-format\")]\n    pub fn encode_png(&self) -> Result<Vec<u8>, png::EncodingError> {\n        let mut data = Vec::new();\n        {\n            let mut encoder = png::Encoder::new(&mut data, self.width(), self.height());\n            encoder.set_color(png::ColorType::Grayscale);\n            encoder.set_depth(png::BitDepth::Eight);\n            let mut writer = encoder.write_header()?;\n            writer.write_image_data(&self.data)?;\n        }\n\n        Ok(data)\n    }\n\n    /// Saves mask as a PNG file.\n    #[cfg(feature = \"png-format\")]\n    pub fn save_png<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), png::EncodingError> {\n        let data = self.encode_png()?;\n        std::fs::write(path, data)?;\n        Ok(())\n    }\n\n    // Almost a direct copy of PixmapMut::fill_path\n    /// Draws a filled path onto the mask.\n    ///\n    /// In terms of RGB (no alpha) image, draws a white path on top of black mask.\n    ///\n    /// Doesn't reset the existing mask content and draws the path on top of existing data.\n    ///\n    /// If the above behavior is undesired, [`clear()`] should be called first.\n    ///\n    /// This method is intended to be used for simple cases. For more complex masks\n    /// prefer [`from_pixmap()`].\n    pub fn fill_path(\n        &mut self,\n        path: &Path,\n        fill_rule: FillRule,\n        anti_alias: bool,\n        transform: Transform,\n    ) {\n        if transform.is_identity() {\n            // This is sort of similar to SkDraw::drawPath\n\n            // Skip empty paths and horizontal/vertical lines.\n            let path_bounds = path.bounds();\n            if path_bounds.width().is_nearly_zero() || path_bounds.height().is_nearly_zero() {\n                log::warn!(\"empty paths and horizontal/vertical lines cannot be filled\");\n                return;\n            }\n\n            if crate::painter::is_too_big_for_math(path) {\n                log::warn!(\"path coordinates are too big\");\n                return;\n            }\n\n            // TODO: ignore paths outside the pixmap\n\n            if let Some(tiler) = DrawTiler::new(self.width(), self.height()) {\n                let mut path = path.clone(); // TODO: avoid cloning\n\n                for tile in tiler {\n                    let ts = Transform::from_translate(-(tile.x() as f32), -(tile.y() as f32));\n                    path = match path.transform(ts) {\n                        Some(v) => v,\n                        None => {\n                            log::warn!(\"path transformation failed\");\n                            return;\n                        }\n                    };\n\n                    let clip_rect = tile.size().to_screen_int_rect(0, 0);\n                    let mut subpix = match self.subpixmap(tile.to_int_rect()) {\n                        Some(v) => v,\n                        None => continue, // technically unreachable\n                    };\n\n                    let mut blitter = match RasterPipelineBlitter::new_mask(&mut subpix) {\n                        Some(v) => v,\n                        None => continue, // nothing to do, all good\n                    };\n\n                    // We're ignoring \"errors\" here, because `fill_path` will return `None`\n                    // when rendering a tile that doesn't have a path on it.\n                    // Which is not an error in this case.\n                    if anti_alias {\n                        scan::path_aa::fill_path(&path, fill_rule, &clip_rect, &mut blitter);\n                    } else {\n                        scan::path::fill_path(&path, fill_rule, &clip_rect, &mut blitter);\n                    }\n\n                    let ts = Transform::from_translate(tile.x() as f32, tile.y() as f32);\n                    path = match path.transform(ts) {\n                        Some(v) => v,\n                        None => return, // technically unreachable\n                    };\n                }\n            } else {\n                let clip_rect = self.size().to_screen_int_rect(0, 0);\n                let mut subpix = self.as_subpixmap();\n                let mut blitter = match RasterPipelineBlitter::new_mask(&mut subpix) {\n                    Some(v) => v,\n                    None => return, // nothing to do, all good\n                };\n\n                if anti_alias {\n                    scan::path_aa::fill_path(path, fill_rule, &clip_rect, &mut blitter);\n                } else {\n                    scan::path::fill_path(path, fill_rule, &clip_rect, &mut blitter);\n                }\n            }\n        } else {\n            let path = match path.clone().transform(transform) {\n                Some(v) => v,\n                None => {\n                    log::warn!(\"path transformation failed\");\n                    return;\n                }\n            };\n\n            self.fill_path(&path, fill_rule, anti_alias, Transform::identity());\n        }\n    }\n\n    /// Intersects the provided path with the current clipping path.\n    ///\n    /// A temporary mask with the same size as the current one will be created.\n    pub fn intersect_path(\n        &mut self,\n        path: &Path,\n        fill_rule: FillRule,\n        anti_alias: bool,\n        transform: Transform,\n    ) {\n        let mut submask = Mask::new(self.width(), self.height()).unwrap();\n        submask.fill_path(path, fill_rule, anti_alias, transform);\n\n        for (a, b) in self.data.iter_mut().zip(submask.data.iter()) {\n            *a = crate::color::premultiply_u8(*a, *b);\n        }\n    }\n\n    /// Inverts the mask.\n    pub fn invert(&mut self) {\n        self.data.iter_mut().for_each(|a| *a = 255 - *a);\n    }\n\n    /// Clears the mask.\n    ///\n    /// Zero-fills the internal data buffer.\n    pub fn clear(&mut self) {\n        self.data.fill(0);\n    }\n}\n\nimpl core::fmt::Debug for Mask {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        f.debug_struct(\"Mask\")\n            .field(\"data\", &\"...\")\n            .field(\"width\", &self.size.width())\n            .field(\"height\", &self.size.height())\n            .finish()\n    }\n}\n\n#[derive(Clone, Copy)]\npub struct SubMaskRef<'a> {\n    pub data: &'a [u8],\n    pub size: IntSize,\n    pub real_width: u32,\n}\n\nimpl<'a> SubMaskRef<'a> {\n    pub(crate) fn mask_ctx(&self) -> crate::pipeline::MaskCtx<'a> {\n        crate::pipeline::MaskCtx {\n            data: &self.data,\n            real_width: self.real_width,\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/math.rs",
      "sha256": "59ff8f3201e0ff5c26b8057dc7105e59be7bff7a5120bb4d7b3aa20f000f5342",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse crate::LengthU32;\n\n// Perfectly safe.\npub const LENGTH_U32_ONE: LengthU32 = unsafe { LengthU32::new_unchecked(1) };\n\npub fn left_shift(value: i32, shift: i32) -> i32 {\n    ((value as u32) << shift) as i32\n}\n\npub fn left_shift64(value: i64, shift: i32) -> i64 {\n    ((value as u64) << shift) as i64\n}\n\npub fn bound<T: Ord + Copy>(min: T, value: T, max: T) -> T {\n    max.min(value).max(min)\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/painter.rs",
      "sha256": "76d57ca174e7619a4ac8b7170b3d640a4c85d92eafe3fe12879dffcbe34599eb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse crate::*;\n\nuse tiny_skia_path::{PathStroker, Scalar, SCALAR_MAX};\n\nuse crate::geom::ScreenIntRect;\nuse crate::mask::SubMaskRef;\nuse crate::pipeline::{RasterPipelineBlitter, RasterPipelineBuilder};\nuse crate::pixmap::SubPixmapMut;\nuse crate::scan;\n\nuse crate::geom::IntSizeExt;\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\n/// A path filling rule.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub enum FillRule {\n    /// Specifies that \"inside\" is computed by a non-zero sum of signed edge crossings.\n    Winding,\n    /// Specifies that \"inside\" is computed by an odd number of edge crossings.\n    EvenOdd,\n}\n\nimpl Default for FillRule {\n    fn default() -> Self {\n        FillRule::Winding\n    }\n}\n\n/// Controls how a shape should be painted.\n#[derive(Clone, PartialEq, Debug)]\npub struct Paint<'a> {\n    /// A paint shader.\n    ///\n    /// Default: black color\n    pub shader: Shader<'a>,\n\n    /// Paint blending mode.\n    ///\n    /// Default: SourceOver\n    pub blend_mode: BlendMode,\n\n    /// Enables anti-aliased painting.\n    ///\n    /// Default: true\n    pub anti_alias: bool,\n\n    /// Forces the high quality/precision rendering pipeline.\n    ///\n    /// `tiny-skia`, just like Skia, has two rendering pipelines:\n    /// one uses `f32` and another one uses `u16`. `u16` one is usually way faster,\n    /// but less precise. Which can lead to slight differences.\n    ///\n    /// By default, `tiny-skia` will choose the pipeline automatically,\n    /// depending on a blending mode and other parameters.\n    /// But you can force the high quality one using this flag.\n    ///\n    /// This feature is especially useful during testing.\n    ///\n    /// Unlike high quality pipeline, the low quality one doesn't support all\n    /// rendering stages, therefore we cannot force it like hq one.\n    ///\n    /// Default: false\n    pub force_hq_pipeline: bool,\n}\n\nimpl Default for Paint<'_> {\n    fn default() -> Self {\n        Paint {\n            shader: Shader::SolidColor(Color::BLACK),\n            blend_mode: BlendMode::default(),\n            anti_alias: true,\n            force_hq_pipeline: false,\n        }\n    }\n}\n\nimpl<'a> Paint<'a> {\n    /// Sets a paint source to a solid color.\n    pub fn set_color(&mut self, color: Color) {\n        self.shader = Shader::SolidColor(color);\n    }\n\n    /// Sets a paint source to a solid color.\n    ///\n    /// `self.shader = Shader::SolidColor(Color::from_rgba8(50, 127, 150, 200));` shorthand.\n    pub fn set_color_rgba8(&mut self, r: u8, g: u8, b: u8, a: u8) {\n        self.set_color(Color::from_rgba8(r, g, b, a))\n    }\n\n    /// Checks that the paint source is a solid color.\n    pub fn is_solid_color(&self) -> bool {\n        matches!(self.shader, Shader::SolidColor(_))\n    }\n}\n\nimpl Pixmap {\n    /// Draws a filled rectangle onto the pixmap.\n    ///\n    /// See [`PixmapMut::fill_rect`](struct.PixmapMut.html#method.fill_rect) for details.\n    pub fn fill_rect(\n        &mut self,\n        rect: Rect,\n        paint: &Paint,\n        transform: Transform,\n        mask: Option<&Mask>,\n    ) {\n        self.as_mut().fill_rect(rect, paint, transform, mask);\n    }\n\n    /// Draws a filled path onto the pixmap.\n    ///\n    /// See [`PixmapMut::fill_path`](struct.PixmapMut.html#method.fill_path) for details.\n    pub fn fill_path(\n        &mut self,\n        path: &Path,\n        paint: &Paint,\n        fill_rule: FillRule,\n        transform: Transform,\n        mask: Option<&Mask>,\n    ) {\n        self.as_mut()\n            .fill_path(path, paint, fill_rule, transform, mask);\n    }\n\n    /// Strokes a path.\n    ///\n    /// See [`PixmapMut::stroke_path`](struct.PixmapMut.html#method.stroke_path) for details.\n    pub fn stroke_path(\n        &mut self,\n        path: &Path,\n        paint: &Paint,\n        stroke: &Stroke,\n        transform: Transform,\n        mask: Option<&Mask>,\n    ) {\n        self.as_mut()\n            .stroke_path(path, paint, stroke, transform, mask);\n    }\n\n    /// Draws a `Pixmap` on top of the current `Pixmap`.\n    ///\n    /// See [`PixmapMut::draw_pixmap`](struct.PixmapMut.html#method.draw_pixmap) for details.\n    pub fn draw_pixmap(\n        &mut self,\n        x: i32,\n        y: i32,\n        pixmap: PixmapRef,\n        paint: &PixmapPaint,\n        transform: Transform,\n        mask: Option<&Mask>,\n    ) {\n        self.as_mut()\n            .draw_pixmap(x, y, pixmap, paint, transform, mask);\n    }\n\n    /// Applies a masks.\n    ///\n    /// See [`PixmapMut::apply_mask`](struct.PixmapMut.html#method.apply_mask) for details.\n    pub fn apply_mask(&mut self, mask: &Mask) {\n        self.as_mut().apply_mask(mask);\n    }\n}\n\nimpl PixmapMut<'_> {\n    // TODO: accept NonZeroRect?\n    /// Draws a filled rectangle onto the pixmap.\n    ///\n    /// This function is usually slower than filling a rectangular path,\n    /// but it produces better results. Mainly it doesn't suffer from weird\n    /// clipping of horizontal/vertical edges.\n    ///\n    /// Used mainly to render a pixmap onto a pixmap.\n    ///\n    /// Returns `None` when there is nothing to fill or in case of a numeric overflow.\n    pub fn fill_rect(\n        &mut self,\n        rect: Rect,\n        paint: &Paint,\n        transform: Transform,\n        mask: Option<&Mask>,\n    ) {\n        // TODO: we probably can use tiler for rect too\n        if transform.is_identity() && !DrawTiler::required(self.width(), self.height()) {\n            // TODO: ignore rects outside the pixmap\n\n            let clip = self.size().to_screen_int_rect(0, 0);\n\n            let mask = mask.map(|mask| mask.as_submask());\n            let mut subpix = self.as_subpixmap();\n            let mut blitter = match RasterPipelineBlitter::new(paint, mask, &mut subpix) {\n                Some(v) => v,\n                None => return, // nothing to do, all good\n            };\n\n            if paint.anti_alias {\n                scan::fill_rect_aa(&rect, &clip, &mut blitter);\n            } else {\n                scan::fill_rect(&rect, &clip, &mut blitter);\n            }\n        } else {\n            let path = PathBuilder::from_rect(rect);\n            self.fill_path(&path, paint, FillRule::Winding, transform, mask);\n        }\n    }\n\n    /// Draws a filled path onto the pixmap.\n    pub fn fill_path(\n        &mut self,\n        path: &Path,\n        paint: &Paint,\n        fill_rule: FillRule,\n        transform: Transform,\n        mask: Option<&Mask>,\n    ) {\n        if transform.is_identity() {\n            // This is sort of similar to SkDraw::drawPath\n\n            // Skip empty paths and horizontal/vertical lines.\n            let path_bounds = path.bounds();\n            if path_bounds.width().is_nearly_zero() || path_bounds.height().is_nearly_zero() {\n                log::warn!(\"empty paths and horizontal/vertical lines cannot be filled\");\n                return;\n            }\n\n            if is_too_big_for_math(path) {\n                log::warn!(\"path coordinates are too big\");\n                return;\n            }\n\n            // TODO: ignore paths outside the pixmap\n\n            if let Some(tiler) = DrawTiler::new(self.width(), self.height()) {\n                let mut path = path.clone(); // TODO: avoid cloning\n                let mut paint = paint.clone();\n\n                for tile in tiler {\n                    let ts = Transform::from_translate(-(tile.x() as f32), -(tile.y() as f32));\n                    path = match path.transform(ts) {\n                        Some(v) => v,\n                        None => {\n                            log::warn!(\"path transformation failed\");\n                            return;\n                        }\n                    };\n                    paint.shader.transform(ts);\n\n                    let clip_rect = tile.size().to_screen_int_rect(0, 0);\n                    let mut subpix = match self.subpixmap(tile.to_int_rect()) {\n                        Some(v) => v,\n                        None => continue, // technically unreachable\n                    };\n\n                    let submask = mask.and_then(|mask| mask.submask(tile.to_int_rect()));\n                    let mut blitter = match RasterPipelineBlitter::new(&paint, submask, &mut subpix)\n                    {\n                        Some(v) => v,\n                        None => continue, // nothing to do, all good\n                    };\n\n                    // We're ignoring \"errors\" here, because `fill_path` will return `None`\n                    // when rendering a tile that doesn't have a path on it.\n                    // Which is not an error in this case.\n                    if paint.anti_alias {\n                        scan::path_aa::fill_path(&path, fill_rule, &clip_rect, &mut blitter);\n                    } else {\n                        scan::path::fill_path(&path, fill_rule, &clip_rect, &mut blitter);\n                    }\n\n                    let ts = Transform::from_translate(tile.x() as f32, tile.y() as f32);\n                    path = match path.transform(ts) {\n                        Some(v) => v,\n                        None => return, // technically unreachable\n                    };\n                    paint.shader.transform(ts);\n                }\n            } else {\n                let clip_rect = self.size().to_screen_int_rect(0, 0);\n                let submask = mask.map(|mask| mask.as_submask());\n                let mut subpix = self.as_subpixmap();\n                let mut blitter = match RasterPipelineBlitter::new(paint, submask, &mut subpix) {\n                    Some(v) => v,\n                    None => return, // nothing to do, all good\n                };\n\n                if paint.anti_alias {\n                    scan::path_aa::fill_path(path, fill_rule, &clip_rect, &mut blitter);\n                } else {\n                    scan::path::fill_path(path, fill_rule, &clip_rect, &mut blitter);\n                }\n            }\n        } else {\n            let path = match path.clone().transform(transform) {\n                Some(v) => v,\n                None => {\n                    log::warn!(\"path transformation failed\");\n                    return;\n                }\n            };\n\n            let mut paint = paint.clone();\n            paint.shader.transform(transform);\n\n            self.fill_path(&path, &paint, fill_rule, Transform::identity(), mask)\n        }\n    }\n\n    /// Strokes a path.\n    ///\n    /// Stroking is implemented using two separate algorithms:\n    ///\n    /// 1. If a stroke width is wider than 1px (after applying the transformation),\n    ///    a path will be converted into a stroked path and then filled using `fill_path`.\n    ///    Which means that we have to allocate a separate `Path`, that can be 2-3x larger\n    ///    then the original path.\n    /// 2. If a stroke width is thinner than 1px (after applying the transformation),\n    ///    we will use hairline stroking, which doesn't involve a separate path allocation.\n    ///\n    /// Also, if a `stroke` has a dash array, then path will be converted into\n    /// a dashed path first and then stroked. Which means a yet another allocation.\n    pub fn stroke_path(\n        &mut self,\n        path: &Path,\n        paint: &Paint,\n        stroke: &Stroke,\n        transform: Transform,\n        mask: Option<&Mask>,\n    ) {\n        if stroke.width < 0.0 {\n            log::warn!(\"negative stroke width isn't allowed\");\n            return;\n        }\n\n        let res_scale = PathStroker::compute_resolution_scale(&transform);\n\n        let dash_path;\n        let path = if let Some(ref dash) = stroke.dash {\n            dash_path = match path.dash(dash, res_scale) {\n                Some(v) => v,\n                None => {\n                    log::warn!(\"path dashing failed\");\n                    return;\n                }\n            };\n            &dash_path\n        } else {\n            path\n        };\n\n        if let Some(coverage) = treat_as_hairline(paint, stroke, transform) {\n            let mut paint = paint.clone();\n            if coverage == 1.0 {\n                // No changes to the `paint`.\n            } else if paint.blend_mode.should_pre_scale_coverage() {\n                // This is the old technique, which we preserve for now so\n                // we don't change previous results (testing)\n                // the new way seems fine, its just (a tiny bit) different.\n                let scale = (coverage * 256.0) as i32;\n                let new_alpha = (255 * scale) >> 8;\n                paint.shader.apply_opacity(new_alpha as f32 / 255.0);\n            }\n\n            if let Some(tiler) = DrawTiler::new(self.width(), self.height()) {\n                let mut path = path.clone(); // TODO: avoid cloning\n                let mut paint = paint.clone();\n\n                if !transform.is_identity() {\n                    paint.shader.transform(transform);\n                    path = match path.transform(transform) {\n                        Some(v) => v,\n                        None => {\n                            log::warn!(\"path transformation failed\");\n                            return;\n                        }\n                    };\n                }\n\n                for tile in tiler {\n                    let ts = Transform::from_translate(-(tile.x() as f32), -(tile.y() as f32));\n                    path = match path.transform(ts) {\n                        Some(v) => v,\n                        None => {\n                            log::warn!(\"path transformation failed\");\n                            return;\n                        }\n                    };\n                    paint.shader.transform(ts);\n\n                    let mut subpix = match self.subpixmap(tile.to_int_rect()) {\n                        Some(v) => v,\n                        None => continue, // technically unreachable\n                    };\n                    let submask = mask.and_then(|mask| mask.submask(tile.to_int_rect()));\n\n                    // We're ignoring \"errors\" here, because `stroke_hairline` will return `None`\n                    // when rendering a tile that doesn't have a path on it.\n                    // Which is not an error in this case.\n                    Self::stroke_hairline(&path, &paint, stroke.line_cap, submask, &mut subpix);\n\n                    let ts = Transform::from_translate(tile.x() as f32, tile.y() as f32);\n                    path = match path.transform(ts) {\n                        Some(v) => v,\n                        None => return,\n                    };\n                    paint.shader.transform(ts);\n                }\n            } else {\n                let subpix = &mut self.as_subpixmap();\n                let submask = mask.map(|mask| mask.as_submask());\n                if !transform.is_identity() {\n                    paint.shader.transform(transform);\n\n                    // TODO: avoid clone\n                    let path = match path.clone().transform(transform) {\n                        Some(v) => v,\n                        None => {\n                            log::warn!(\"path transformation failed\");\n                            return;\n                        }\n                    };\n\n                    Self::stroke_hairline(&path, &paint, stroke.line_cap, submask, subpix);\n                } else {\n                    Self::stroke_hairline(path, &paint, stroke.line_cap, submask, subpix);\n                }\n            }\n        } else {\n            let path = match path.stroke(stroke, res_scale) {\n                Some(v) => v,\n                None => {\n                    log::warn!(\"path stroking failed\");\n                    return;\n                }\n            };\n\n            self.fill_path(&path, paint, FillRule::Winding, transform, mask);\n        }\n    }\n\n    /// A stroking for paths with subpixel/hairline width.\n    fn stroke_hairline(\n        path: &Path,\n        paint: &Paint,\n        line_cap: LineCap,\n        mask: Option<SubMaskRef>,\n        pixmap: &mut SubPixmapMut,\n    ) {\n        let clip = pixmap.size.to_screen_int_rect(0, 0);\n        let mut blitter = match RasterPipelineBlitter::new(paint, mask, pixmap) {\n            Some(v) => v,\n            None => return, // nothing to do, all good\n        };\n        if paint.anti_alias {\n            scan::hairline_aa::stroke_path(path, line_cap, &clip, &mut blitter);\n        } else {\n            scan::hairline::stroke_path(path, line_cap, &clip, &mut blitter);\n        }\n    }\n\n    /// Draws a `Pixmap` on top of the current `Pixmap`.\n    ///\n    /// The same as filling a rectangle with a `pixmap` pattern.\n    pub fn draw_pixmap(\n        &mut self,\n        x: i32,\n        y: i32,\n        pixmap: PixmapRef,\n        paint: &PixmapPaint,\n        transform: Transform,\n        mask: Option<&Mask>,\n    ) {\n        let rect = pixmap.size().to_int_rect(x, y).to_rect();\n\n        // TODO: SkSpriteBlitter\n        // TODO: partially clipped\n        // TODO: clipped out\n\n        // Translate pattern as well as bounds.\n        let patt_transform = Transform::from_translate(x as f32, y as f32);\n\n        let paint = Paint {\n            shader: Pattern::new(\n                pixmap,\n                SpreadMode::Pad, // Pad, otherwise we will get weird borders overlap.\n                paint.quality,\n                paint.opacity,\n                patt_transform,\n            ),\n            blend_mode: paint.blend_mode,\n            anti_alias: false,        // Skia doesn't use it too.\n            force_hq_pipeline: false, // Pattern will use hq anyway.\n        };\n\n        self.fill_rect(rect, &paint, transform, mask);\n    }\n\n    /// Applies a masks.\n    ///\n    /// When a `Mask` is passed to drawing methods, it will be used to mask-out\n    /// content we're about to draw.\n    /// This method masks-out an already drawn content.\n    /// It's not as fast, but can be useful when a mask is not available during drawing.\n    ///\n    /// This method is similar to filling the whole pixmap with an another,\n    /// mask-like pixmap using the `DestinationOut` blend mode.\n    ///\n    /// `Mask` must have the same size as `Pixmap`. No transform or offset are allowed.\n    pub fn apply_mask(&mut self, mask: &Mask) {\n        if self.size() != mask.size() {\n            log::warn!(\"Pixmap and Mask are expected to have the same size\");\n            return;\n        }\n\n        // Just a dummy.\n        let pixmap_src = PixmapRef::from_bytes(&[0, 0, 0, 0], 1, 1).unwrap();\n\n        let mut p = RasterPipelineBuilder::new();\n        p.push(pipeline::Stage::LoadMaskU8);\n        p.push(pipeline::Stage::LoadDestination);\n        p.push(pipeline::Stage::DestinationIn);\n        p.push(pipeline::Stage::Store);\n        let mut p = p.compile();\n        let rect = self.size().to_screen_int_rect(0, 0);\n        p.run(\n            &rect,\n            pipeline::AAMaskCtx::default(),\n            mask.as_submask().mask_ctx(),\n            pixmap_src,\n            &mut self.as_subpixmap(),\n        );\n    }\n}\n\nfn treat_as_hairline(paint: &Paint, stroke: &Stroke, mut ts: Transform) -> Option<f32> {\n    fn fast_len(p: Point) -> f32 {\n        let mut x = p.x.abs();\n        let mut y = p.y.abs();\n        if x < y {\n            core::mem::swap(&mut x, &mut y);\n        }\n\n        x + y.half()\n    }\n\n    debug_assert!(stroke.width >= 0.0);\n\n    if stroke.width == 0.0 {\n        return Some(1.0);\n    }\n\n    if !paint.anti_alias {\n        return None;\n    }\n\n    // We don't care about translate.\n    ts.tx = 0.0;\n    ts.ty = 0.0;\n\n    // We need to try to fake a thick-stroke with a modulated hairline.\n    let mut points = [\n        Point::from_xy(stroke.width, 0.0),\n        Point::from_xy(0.0, stroke.width),\n    ];\n    ts.map_points(&mut points);\n\n    let len0 = fast_len(points[0]);\n    let len1 = fast_len(points[1]);\n\n    if len0 <= 1.0 && len1 <= 1.0 {\n        return Some(len0.ave(len1));\n    }\n\n    None\n}\n\n/// Sometimes in the drawing pipeline, we have to perform math on path coordinates, even after\n/// the path is in device-coordinates. Tessellation and clipping are two examples. Usually this\n/// is pretty modest, but it can involve subtracting/adding coordinates, or multiplying by\n/// small constants (e.g. 2,3,4). To try to preflight issues where these optionations could turn\n/// finite path values into infinities (or NaNs), we allow the upper drawing code to reject\n/// the path if its bounds (in device coordinates) is too close to max float.\npub(crate) fn is_too_big_for_math(path: &Path) -> bool {\n    // This value is just a guess. smaller is safer, but we don't want to reject largish paths\n    // that we don't have to.\n    const SCALE_DOWN_TO_ALLOW_FOR_SMALL_MULTIPLIES: f32 = 0.25;\n    const MAX: f32 = SCALAR_MAX * SCALE_DOWN_TO_ALLOW_FOR_SMALL_MULTIPLIES;\n\n    let b = path.bounds();\n\n    // use ! expression so we return true if bounds contains NaN\n    !(b.left() >= -MAX && b.top() >= -MAX && b.right() <= MAX && b.bottom() <= MAX)\n}\n\n/// Splits the target pixmap into a list of tiles.\n///\n/// Skia/tiny-skia uses a lot of fixed-point math during path rendering.\n/// Probably more for precision than performance.\n/// And our fixed-point types are limited by 8192 and 32768.\n/// Which means that we cannot render a path larger than 8192 onto a pixmap.\n/// When pixmap is smaller than 8192, the path will be automatically clipped anyway,\n/// but for large pixmaps we have to render in tiles.\npub(crate) struct DrawTiler {\n    image_width: u32,\n    image_height: u32,\n    x_offset: u32,\n    y_offset: u32,\n    finished: bool,\n}\n\nimpl DrawTiler {\n    // 8K is 1 too big, since 8K << supersample == 32768 which is too big for Fixed.\n    const MAX_DIMENSIONS: u32 = 8192 - 1;\n\n    fn required(image_width: u32, image_height: u32) -> bool {\n        image_width > Self::MAX_DIMENSIONS || image_height > Self::MAX_DIMENSIONS\n    }\n\n    pub(crate) fn new(image_width: u32, image_height: u32) -> Option<Self> {\n        if Self::required(image_width, image_height) {\n            Some(DrawTiler {\n                image_width,\n                image_height,\n                x_offset: 0,\n                y_offset: 0,\n                finished: false,\n            })\n        } else {\n            None\n        }\n    }\n}\n\nimpl Iterator for DrawTiler {\n    type Item = ScreenIntRect;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.finished {\n            return None;\n        }\n\n        // TODO: iterate only over tiles that actually affected by the shape\n\n        if self.x_offset < self.image_width && self.y_offset < self.image_height {\n            let h = if self.y_offset < self.image_height {\n                (self.image_height - self.y_offset).min(Self::MAX_DIMENSIONS)\n            } else {\n                self.image_height\n            };\n\n            let r = ScreenIntRect::from_xywh(\n                self.x_offset,\n                self.y_offset,\n                (self.image_width - self.x_offset).min(Self::MAX_DIMENSIONS),\n                h,\n            );\n\n            self.x_offset += Self::MAX_DIMENSIONS;\n            if self.x_offset >= self.image_width {\n                self.x_offset = 0;\n                self.y_offset += Self::MAX_DIMENSIONS;\n            }\n\n            return r;\n        }\n\n        None\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    const MAX_DIM: u32 = DrawTiler::MAX_DIMENSIONS;\n\n    #[test]\n    fn skip() {\n        assert!(DrawTiler::new(100, 500).is_none());\n    }\n\n    #[test]\n    fn horizontal() {\n        let mut iter = DrawTiler::new(10000, 500).unwrap();\n        assert_eq!(iter.next(), ScreenIntRect::from_xywh(0, 0, MAX_DIM, 500));\n        assert_eq!(\n            iter.next(),\n            ScreenIntRect::from_xywh(MAX_DIM, 0, 10000 - MAX_DIM, 500)\n        );\n        assert_eq!(iter.next(), None);\n    }\n\n    #[test]\n    fn vertical() {\n        let mut iter = DrawTiler::new(500, 10000).unwrap();\n        assert_eq!(iter.next(), ScreenIntRect::from_xywh(0, 0, 500, MAX_DIM));\n        assert_eq!(\n            iter.next(),\n            ScreenIntRect::from_xywh(0, MAX_DIM, 500, 10000 - MAX_DIM)\n        );\n        assert_eq!(iter.next(), None);\n    }\n\n    #[test]\n    fn rect() {\n        let mut iter = DrawTiler::new(10000, 10000).unwrap();\n        // Row 1\n        assert_eq!(\n            iter.next(),\n            ScreenIntRect::from_xywh(0, 0, MAX_DIM, MAX_DIM)\n        );\n        assert_eq!(\n            iter.next(),\n            ScreenIntRect::from_xywh(MAX_DIM, 0, 10000 - MAX_DIM, MAX_DIM)\n        );\n        // Row 2\n        assert_eq!(\n            iter.next(),\n            ScreenIntRect::from_xywh(0, MAX_DIM, MAX_DIM, 10000 - MAX_DIM)\n        );\n        assert_eq!(\n            iter.next(),\n            ScreenIntRect::from_xywh(MAX_DIM, MAX_DIM, 10000 - MAX_DIM, 10000 - MAX_DIM)\n        );\n        assert_eq!(iter.next(), None);\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/path64/cubic64.rs",
      "sha256": "1f03bfd3a26c465a8a861aac7ce7d9b6d77ad73c9db07f27fe13500b02e83d60",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse super::point64::{Point64, SearchAxis};\nuse super::quad64;\nuse super::Scalar64;\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\npub const POINT_COUNT: usize = 4;\nconst PI: f64 = 3.141592653589793;\n\npub struct Cubic64Pair {\n    pub points: [Point64; 7],\n}\n\npub struct Cubic64 {\n    pub points: [Point64; POINT_COUNT],\n}\n\nimpl Cubic64 {\n    pub fn new(points: [Point64; POINT_COUNT]) -> Self {\n        Cubic64 { points }\n    }\n\n    pub fn as_f64_slice(&self) -> [f64; POINT_COUNT * 2] {\n        [\n            self.points[0].x,\n            self.points[0].y,\n            self.points[1].x,\n            self.points[1].y,\n            self.points[2].x,\n            self.points[2].y,\n            self.points[3].x,\n            self.points[3].y,\n        ]\n    }\n\n    pub fn point_at_t(&self, t: f64) -> Point64 {\n        if t == 0.0 {\n            return self.points[0];\n        }\n\n        if t == 1.0 {\n            return self.points[3];\n        }\n\n        let one_t = 1.0 - t;\n        let one_t2 = one_t * one_t;\n        let a = one_t2 * one_t;\n        let b = 3.0 * one_t2 * t;\n        let t2 = t * t;\n        let c = 3.0 * one_t * t2;\n        let d = t2 * t;\n        Point64::from_xy(\n            a * self.points[0].x\n                + b * self.points[1].x\n                + c * self.points[2].x\n                + d * self.points[3].x,\n            a * self.points[0].y\n                + b * self.points[1].y\n                + c * self.points[2].y\n                + d * self.points[3].y,\n        )\n    }\n\n    pub fn search_roots(\n        &self,\n        mut extrema: usize,\n        axis_intercept: f64,\n        x_axis: SearchAxis,\n        extreme_ts: &mut [f64; 6],\n        valid_roots: &mut [f64],\n    ) -> usize {\n        extrema += self.find_inflections(&mut extreme_ts[extrema..]);\n        extreme_ts[extrema] = 0.0;\n        extrema += 1;\n        extreme_ts[extrema] = 1.0;\n        debug_assert!(extrema < 6);\n        extreme_ts[0..extrema].sort_by(cmp_f64);\n        let mut valid_count = 0;\n        let mut index = 0;\n        while index < extrema {\n            let min = extreme_ts[index];\n            index += 1;\n            let max = extreme_ts[index];\n            if min == max {\n                continue;\n            }\n\n            let new_t = self.binary_search(min, max, axis_intercept, x_axis);\n            if new_t >= 0.0 {\n                if valid_count >= 3 {\n                    return 0;\n                }\n\n                valid_roots[valid_count] = new_t;\n                valid_count += 1;\n            }\n        }\n\n        valid_count\n    }\n\n    fn find_inflections(&self, t_values: &mut [f64]) -> usize {\n        let ax = self.points[1].x - self.points[0].x;\n        let ay = self.points[1].y - self.points[0].y;\n        let bx = self.points[2].x - 2.0 * self.points[1].x + self.points[0].x;\n        let by = self.points[2].y - 2.0 * self.points[1].y + self.points[0].y;\n        let cx = self.points[3].x + 3.0 * (self.points[1].x - self.points[2].x) - self.points[0].x;\n        let cy = self.points[3].y + 3.0 * (self.points[1].y - self.points[2].y) - self.points[0].y;\n        quad64::roots_valid_t(\n            bx * cy - by * cx,\n            ax * cy - ay * cx,\n            ax * by - ay * bx,\n            t_values,\n        )\n    }\n\n    // give up when changing t no longer moves point\n    // also, copy point rather than recompute it when it does change\n    fn binary_search(&self, min: f64, max: f64, axis_intercept: f64, x_axis: SearchAxis) -> f64 {\n        let mut t = (min + max) / 2.0;\n        let mut step = (t - min) / 2.0;\n        let mut cubic_at_t = self.point_at_t(t);\n        let mut calc_pos = cubic_at_t.axis_coord(x_axis);\n        let mut calc_dist = calc_pos - axis_intercept;\n        loop {\n            let prior_t = min.max(t - step);\n            let less_pt = self.point_at_t(prior_t);\n            if less_pt.x.approximately_equal_half(cubic_at_t.x)\n                && less_pt.y.approximately_equal_half(cubic_at_t.y)\n            {\n                return -1.0; // binary search found no point at this axis intercept\n            }\n\n            let less_dist = less_pt.axis_coord(x_axis) - axis_intercept;\n            let last_step = step;\n            step /= 2.0;\n            let ok = if calc_dist > 0.0 {\n                calc_dist > less_dist\n            } else {\n                calc_dist < less_dist\n            };\n            if ok {\n                t = prior_t;\n            } else {\n                let next_t = t + last_step;\n                if next_t > max {\n                    return -1.0;\n                }\n\n                let more_pt = self.point_at_t(next_t);\n                if more_pt.x.approximately_equal_half(cubic_at_t.x)\n                    && more_pt.y.approximately_equal_half(cubic_at_t.y)\n                {\n                    return -1.0; // binary search found no point at this axis intercept\n                }\n\n                let more_dist = more_pt.axis_coord(x_axis) - axis_intercept;\n                let ok = if calc_dist > 0.0 {\n                    calc_dist <= more_dist\n                } else {\n                    calc_dist >= more_dist\n                };\n                if ok {\n                    continue;\n                }\n\n                t = next_t;\n            }\n\n            let test_at_t = self.point_at_t(t);\n            cubic_at_t = test_at_t;\n            calc_pos = cubic_at_t.axis_coord(x_axis);\n            calc_dist = calc_pos - axis_intercept;\n\n            if calc_pos.approximately_equal(axis_intercept) {\n                break;\n            }\n        }\n\n        t\n    }\n\n    pub fn chop_at(&self, t: f64) -> Cubic64Pair {\n        let mut dst = [Point64::zero(); 7];\n        if t == 0.5 {\n            dst[0] = self.points[0];\n            dst[1].x = (self.points[0].x + self.points[1].x) / 2.0;\n            dst[1].y = (self.points[0].y + self.points[1].y) / 2.0;\n            dst[2].x = (self.points[0].x + 2.0 * self.points[1].x + self.points[2].x) / 4.0;\n            dst[2].y = (self.points[0].y + 2.0 * self.points[1].y + self.points[2].y) / 4.0;\n            dst[3].x =\n                (self.points[0].x + 3.0 * (self.points[1].x + self.points[2].x) + self.points[3].x)\n                    / 8.0;\n            dst[3].y =\n                (self.points[0].y + 3.0 * (self.points[1].y + self.points[2].y) + self.points[3].y)\n                    / 8.0;\n            dst[4].x = (self.points[1].x + 2.0 * self.points[2].x + self.points[3].x) / 4.0;\n            dst[4].y = (self.points[1].y + 2.0 * self.points[2].y + self.points[3].y) / 4.0;\n            dst[5].x = (self.points[2].x + self.points[3].x) / 2.0;\n            dst[5].y = (self.points[2].y + self.points[3].y) / 2.0;\n            dst[6] = self.points[3];\n\n            Cubic64Pair { points: dst }\n        } else {\n            interp_cubic_coords_x(&self.points, t, &mut dst);\n            interp_cubic_coords_y(&self.points, t, &mut dst);\n            Cubic64Pair { points: dst }\n        }\n    }\n}\n\npub fn coefficients(src: &[f64]) -> (f64, f64, f64, f64) {\n    let mut a = src[6]; // d\n    let mut b = src[4] * 3.0; // 3*c\n    let mut c = src[2] * 3.0; // 3*b\n    let d = src[0]; // a\n    a -= d - c + b; // A =   -a + 3*b - 3*c + d\n    b += 3.0 * d - 2.0 * c; // B =  3*a - 6*b + 3*c\n    c -= 3.0 * d; // C = -3*a + 3*b\n\n    (a, b, c, d)\n}\n\n// from SkGeometry.cpp (and Numeric Solutions, 5.6)\npub fn roots_valid_t(a: f64, b: f64, c: f64, d: f64, t: &mut [f64; 3]) -> usize {\n    let mut s = [0.0; 3];\n    let real_roots = roots_real(a, b, c, d, &mut s);\n    let mut found_roots = quad64::push_valid_ts(&s, real_roots, t);\n    'outer: for index in 0..real_roots {\n        let t_value = s[index];\n        if !t_value.approximately_one_or_less() && t_value.between(1.0, 1.00005) {\n            for idx2 in 0..found_roots {\n                if t[idx2].approximately_equal(1.0) {\n                    continue 'outer;\n                }\n            }\n\n            debug_assert!(found_roots < 3);\n            t[found_roots] = 1.0;\n            found_roots += 1;\n        } else if !t_value.approximately_zero_or_more() && t_value.between(-0.00005, 0.0) {\n            for idx2 in 0..found_roots {\n                if t[idx2].approximately_equal(0.0) {\n                    continue 'outer;\n                }\n            }\n\n            debug_assert!(found_roots < 3);\n            t[found_roots] = 0.0;\n            found_roots += 1;\n        }\n    }\n\n    found_roots\n}\n\nfn roots_real(a: f64, b: f64, c: f64, d: f64, s: &mut [f64; 3]) -> usize {\n    if a.approximately_zero()\n        && a.approximately_zero_when_compared_to(b)\n        && a.approximately_zero_when_compared_to(c)\n        && a.approximately_zero_when_compared_to(d)\n    {\n        // we're just a quadratic\n        return quad64::roots_real(b, c, d, s);\n    }\n\n    if d.approximately_zero_when_compared_to(a)\n        && d.approximately_zero_when_compared_to(b)\n        && d.approximately_zero_when_compared_to(c)\n    {\n        // 0 is one root\n        let mut num = quad64::roots_real(a, b, c, s);\n        for i in 0..num {\n            if s[i].approximately_zero() {\n                return num;\n            }\n        }\n\n        s[num] = 0.0;\n        num += 1;\n\n        return num;\n    }\n\n    if (a + b + c + d).approximately_zero() {\n        // 1 is one root\n        let mut num = quad64::roots_real(a, a + b, -d, s);\n        for i in 0..num {\n            if s[i].almost_dequal_ulps(1.0) {\n                return num;\n            }\n        }\n        s[num] = 1.0;\n        num += 1;\n        return num;\n    }\n\n    let (a, b, c) = {\n        let inv_a = 1.0 / a;\n        let a = b * inv_a;\n        let b = c * inv_a;\n        let c = d * inv_a;\n        (a, b, c)\n    };\n\n    let a2 = a * a;\n    let q = (a2 - b * 3.0) / 9.0;\n    let r = (2.0 * a2 * a - 9.0 * a * b + 27.0 * c) / 54.0;\n    let r2 = r * r;\n    let q3 = q * q * q;\n    let r2_minus_q3 = r2 - q3;\n    let adiv3 = a / 3.0;\n    let mut offset = 0;\n    if r2_minus_q3 < 0.0 {\n        // we have 3 real roots\n\n        // the divide/root can, due to finite precisions, be slightly outside of -1...1\n        let theta = (r / q3.sqrt()).bound(-1.0, 1.0).acos();\n        let neg2_root_q = -2.0 * q.sqrt();\n\n        let mut rr = neg2_root_q * (theta / 3.0).cos() - adiv3;\n        s[offset] = rr;\n        offset += 1;\n\n        rr = neg2_root_q * ((theta + 2.0 * PI) / 3.0).cos() - adiv3;\n        if !s[0].almost_dequal_ulps(rr) {\n            s[offset] = rr;\n            offset += 1;\n        }\n\n        rr = neg2_root_q * ((theta - 2.0 * PI) / 3.0).cos() - adiv3;\n        if !s[0].almost_dequal_ulps(rr) && (offset == 1 || !s[1].almost_dequal_ulps(rr)) {\n            s[offset] = rr;\n            offset += 1;\n        }\n    } else {\n        // we have 1 real root\n        let sqrt_r2_minus_q3 = r2_minus_q3.sqrt();\n        let mut a = r.abs() + sqrt_r2_minus_q3;\n        a = super::cube_root(a);\n        if r > 0.0 {\n            a = -a;\n        }\n\n        if a != 0.0 {\n            a += q / a;\n        }\n\n        let mut r2 = a - adiv3;\n        s[offset] = r2;\n        offset += 1;\n        if r2.almost_dequal_ulps(q3) {\n            r2 = -a / 2.0 - adiv3;\n            if !s[0].almost_dequal_ulps(r2) {\n                s[offset] = r2;\n                offset += 1;\n            }\n        }\n    }\n\n    offset\n}\n\n// Cubic64'(t) = At^2 + Bt + C, where\n// A = 3(-a + 3(b - c) + d)\n// B = 6(a - 2b + c)\n// C = 3(b - a)\n// Solve for t, keeping only those that fit between 0 < t < 1\npub fn find_extrema(src: &[f64], t_values: &mut [f64]) -> usize {\n    // we divide A,B,C by 3 to simplify\n    let a = src[0];\n    let b = src[2];\n    let c = src[4];\n    let d = src[6];\n    let a2 = d - a + 3.0 * (b - c);\n    let b2 = 2.0 * (a - b - b + c);\n    let c2 = b - a;\n\n    quad64::roots_valid_t(a2, b2, c2, t_values)\n}\n\n// Skia doesn't seems to care about NaN/inf during sorting, so we don't too.\nfn cmp_f64(a: &f64, b: &f64) -> core::cmp::Ordering {\n    if a < b {\n        core::cmp::Ordering::Less\n    } else if a > b {\n        core::cmp::Ordering::Greater\n    } else {\n        core::cmp::Ordering::Equal\n    }\n}\n\n// classic one t subdivision\nfn interp_cubic_coords_x(src: &[Point64; 4], t: f64, dst: &mut [Point64; 7]) {\n    use super::interp;\n\n    let ab = interp(src[0].x, src[1].x, t);\n    let bc = interp(src[1].x, src[2].x, t);\n    let cd = interp(src[2].x, src[3].x, t);\n    let abc = interp(ab, bc, t);\n    let bcd = interp(bc, cd, t);\n    let abcd = interp(abc, bcd, t);\n\n    dst[0].x = src[0].x;\n    dst[1].x = ab;\n    dst[2].x = abc;\n    dst[3].x = abcd;\n    dst[4].x = bcd;\n    dst[5].x = cd;\n    dst[6].x = src[3].x;\n}\n\nfn interp_cubic_coords_y(src: &[Point64; 4], t: f64, dst: &mut [Point64; 7]) {\n    use super::interp;\n\n    let ab = interp(src[0].y, src[1].y, t);\n    let bc = interp(src[1].y, src[2].y, t);\n    let cd = interp(src[2].y, src[3].y, t);\n    let abc = interp(ab, bc, t);\n    let bcd = interp(bc, cd, t);\n    let abcd = interp(abc, bcd, t);\n\n    dst[0].y = src[0].y;\n    dst[1].y = ab;\n    dst[2].y = abc;\n    dst[3].y = abcd;\n    dst[4].y = bcd;\n    dst[5].y = cd;\n    dst[6].y = src[3].y;\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/path64/line_cubic_intersections.rs",
      "sha256": "67164e6971ae50b553b7553b3a37e389966d25590b637a3b5b1b3aecf77fd5df",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/*\nFind the intersection of a line and cubic by solving for valid t values.\n\nAnalogous to line-quadratic intersection, solve line-cubic intersection by\nrepresenting the cubic as:\n  x = a(1-t)^3 + 2b(1-t)^2t + c(1-t)t^2 + dt^3\n  y = e(1-t)^3 + 2f(1-t)^2t + g(1-t)t^2 + ht^3\nand the line as:\n  y = i*x + j  (if the line is more horizontal)\nor:\n  x = i*y + j  (if the line is more vertical)\n\nThen using Mathematica, solve for the values of t where the cubic intersects the\nline:\n\n  (in) Resultant[\n        a*(1 - t)^3 + 3*b*(1 - t)^2*t + 3*c*(1 - t)*t^2 + d*t^3 - x,\n        e*(1 - t)^3 + 3*f*(1 - t)^2*t + 3*g*(1 - t)*t^2 + h*t^3 - i*x - j, x]\n  (out) -e     +   j     +\n       3 e t   - 3 f t   -\n       3 e t^2 + 6 f t^2 - 3 g t^2 +\n         e t^3 - 3 f t^3 + 3 g t^3 - h t^3 +\n     i ( a     -\n       3 a t + 3 b t +\n       3 a t^2 - 6 b t^2 + 3 c t^2 -\n         a t^3 + 3 b t^3 - 3 c t^3 + d t^3 )\n\nif i goes to infinity, we can rewrite the line in terms of x. Mathematica:\n\n  (in) Resultant[\n        a*(1 - t)^3 + 3*b*(1 - t)^2*t + 3*c*(1 - t)*t^2 + d*t^3 - i*y - j,\n        e*(1 - t)^3 + 3*f*(1 - t)^2*t + 3*g*(1 - t)*t^2 + h*t^3 - y,       y]\n  (out)  a     -   j     -\n       3 a t   + 3 b t   +\n       3 a t^2 - 6 b t^2 + 3 c t^2 -\n         a t^3 + 3 b t^3 - 3 c t^3 + d t^3 -\n     i ( e     -\n       3 e t   + 3 f t   +\n       3 e t^2 - 6 f t^2 + 3 g t^2 -\n         e t^3 + 3 f t^3 - 3 g t^3 + h t^3 )\n\nSolving this with Mathematica produces an expression with hundreds of terms;\ninstead, use Numeric Solutions recipe to solve the cubic.\n\nThe near-horizontal case, in terms of:  Ax^3 + Bx^2 + Cx + D == 0\n    A =   (-(-e + 3*f - 3*g + h) + i*(-a + 3*b - 3*c + d)     )\n    B = 3*(-( e - 2*f +   g    ) + i*( a - 2*b +   c    )     )\n    C = 3*(-(-e +   f          ) + i*(-a +   b          )     )\n    D =   (-( e                ) + i*( a                ) + j )\n\nThe near-vertical case, in terms of:  Ax^3 + Bx^2 + Cx + D == 0\n    A =   ( (-a + 3*b - 3*c + d) - i*(-e + 3*f - 3*g + h)     )\n    B = 3*( ( a - 2*b +   c    ) - i*( e - 2*f +   g    )     )\n    C = 3*( (-a +   b          ) - i*(-e +   f          )     )\n    D =   ( ( a                ) - i*( e                ) - j )\n\nFor horizontal lines:\n(in) Resultant[\n      a*(1 - t)^3 + 3*b*(1 - t)^2*t + 3*c*(1 - t)*t^2 + d*t^3 - j,\n      e*(1 - t)^3 + 3*f*(1 - t)^2*t + 3*g*(1 - t)*t^2 + h*t^3 - y, y]\n(out)  e     -   j     -\n     3 e t   + 3 f t   +\n     3 e t^2 - 6 f t^2 + 3 g t^2 -\n       e t^3 + 3 f t^3 - 3 g t^3 + h t^3\n*/\n\nuse super::cubic64::{self, Cubic64};\nuse super::point64::SearchAxis;\nuse super::Scalar64;\n\npub fn horizontal_intersect(cubic: &Cubic64, axis_intercept: f64, roots: &mut [f64; 3]) -> usize {\n    let (a, b, c, mut d) = cubic64::coefficients(&cubic.as_f64_slice()[1..]);\n    d -= axis_intercept;\n    let mut count = cubic64::roots_valid_t(a, b, c, d, roots);\n    let mut index = 0;\n    while index < count {\n        let calc_pt = cubic.point_at_t(roots[index]);\n        if !calc_pt.y.approximately_equal(axis_intercept) {\n            let mut extreme_ts = [0.0; 6];\n            let extrema = cubic64::find_extrema(&cubic.as_f64_slice()[1..], &mut extreme_ts);\n            count = cubic.search_roots(\n                extrema,\n                axis_intercept,\n                SearchAxis::Y,\n                &mut extreme_ts,\n                roots,\n            );\n            break;\n        }\n\n        index += 1;\n    }\n\n    count\n}\n\npub fn vertical_intersect(cubic: &Cubic64, axis_intercept: f64, roots: &mut [f64; 3]) -> usize {\n    let (a, b, c, mut d) = cubic64::coefficients(&cubic.as_f64_slice());\n    d -= axis_intercept;\n    let mut count = cubic64::roots_valid_t(a, b, c, d, roots);\n    let mut index = 0;\n    while index < count {\n        let calc_pt = cubic.point_at_t(roots[index]);\n        if !calc_pt.x.approximately_equal(axis_intercept) {\n            let mut extreme_ts = [0.0; 6];\n            let extrema = cubic64::find_extrema(&cubic.as_f64_slice(), &mut extreme_ts);\n            count = cubic.search_roots(\n                extrema,\n                axis_intercept,\n                SearchAxis::X,\n                &mut extreme_ts,\n                roots,\n            );\n            break;\n        }\n\n        index += 1;\n    }\n\n    count\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/path64/mod.rs",
      "sha256": "b1a931a1e0cfcb2d42e50ae535f4e6991a9db4ff41eb28cdb1f45f14cf0b2e95",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse tiny_skia_path::{Scalar, SCALAR_MAX};\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\n// Must be first, because of macro scope rules.\n#[macro_use]\npub mod point64;\n\npub mod cubic64;\npub mod line_cubic_intersections;\nmod quad64;\n\n// The code below is from SkPathOpsTypes.\n\nconst DBL_EPSILON_ERR: f64 = f64::EPSILON * 4.0;\nconst FLT_EPSILON_HALF: f64 = (f32::EPSILON / 2.0) as f64;\nconst FLT_EPSILON_CUBED: f64 = (f32::EPSILON * f32::EPSILON * f32::EPSILON) as f64;\nconst FLT_EPSILON_INVERSE: f64 = 1.0 / f32::EPSILON as f64;\n\npub trait Scalar64 {\n    fn bound(self, min: Self, max: Self) -> Self;\n    fn between(self, a: f64, b: f64) -> bool;\n    fn precisely_zero(self) -> bool;\n    fn approximately_zero_or_more(self) -> bool;\n    fn approximately_one_or_less(self) -> bool;\n    fn approximately_zero(self) -> bool;\n    fn approximately_zero_inverse(self) -> bool;\n    fn approximately_zero_cubed(self) -> bool;\n    fn approximately_zero_half(self) -> bool;\n    fn approximately_zero_when_compared_to(self, other: Self) -> bool;\n    fn approximately_equal(self, other: Self) -> bool;\n    fn approximately_equal_half(self, other: Self) -> bool;\n    fn almost_dequal_ulps(self, other: Self) -> bool;\n}\n\nimpl Scalar64 for f64 {\n    // Works just like SkTPin, returning `max` for NaN/inf\n    fn bound(self, min: Self, max: Self) -> Self {\n        max.min(self).max(min)\n    }\n\n    /// Returns true if (a <= self <= b) || (a >= self >= b).\n    fn between(self, a: f64, b: f64) -> bool {\n        debug_assert!(\n            ((a <= self && self <= b) || (a >= self && self >= b))\n                == ((a - self) * (b - self) <= 0.0)\n                || (a.precisely_zero() && self.precisely_zero() && b.precisely_zero())\n        );\n\n        (a - self) * (b - self) <= 0.0\n    }\n\n    fn precisely_zero(self) -> bool {\n        self.abs() < DBL_EPSILON_ERR\n    }\n\n    fn approximately_zero_or_more(self) -> bool {\n        self > -f64::EPSILON\n    }\n\n    fn approximately_one_or_less(self) -> bool {\n        self < 1.0 + f64::EPSILON\n    }\n\n    fn approximately_zero(self) -> bool {\n        self.abs() < f64::EPSILON\n    }\n\n    fn approximately_zero_inverse(self) -> bool {\n        self.abs() > FLT_EPSILON_INVERSE\n    }\n\n    fn approximately_zero_cubed(self) -> bool {\n        self.abs() < FLT_EPSILON_CUBED\n    }\n\n    fn approximately_zero_half(self) -> bool {\n        self < FLT_EPSILON_HALF\n    }\n\n    fn approximately_zero_when_compared_to(self, other: Self) -> bool {\n        self == 0.0 || self.abs() < (other * (f32::EPSILON as f64)).abs()\n    }\n\n    // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use\n    // AlmostEqualUlps instead.\n    fn approximately_equal(self, other: Self) -> bool {\n        (self - other).approximately_zero()\n    }\n\n    fn approximately_equal_half(self, other: Self) -> bool {\n        (self - other).approximately_zero_half()\n    }\n\n    fn almost_dequal_ulps(self, other: Self) -> bool {\n        if self.abs() < SCALAR_MAX as f64 && other.abs() < SCALAR_MAX as f64 {\n            (self as f32).almost_dequal_ulps(other as f32)\n        } else {\n            (self - other).abs() / self.abs().max(other.abs()) < (f32::EPSILON * 16.0) as f64\n        }\n    }\n}\n\npub fn cube_root(x: f64) -> f64 {\n    if x.approximately_zero_cubed() {\n        return 0.0;\n    }\n\n    let result = halley_cbrt3d(x.abs());\n    if x < 0.0 {\n        -result\n    } else {\n        result\n    }\n}\n\n// cube root approximation using 3 iterations of Halley's method (double)\nfn halley_cbrt3d(d: f64) -> f64 {\n    let mut a = cbrt_5d(d);\n    a = cbrta_halleyd(a, d);\n    a = cbrta_halleyd(a, d);\n    cbrta_halleyd(a, d)\n}\n\n// cube root approximation using bit hack for 64-bit float\n// adapted from Kahan's cbrt\nfn cbrt_5d(d: f64) -> f64 {\n    let b1 = 715094163;\n    let mut t: f64 = 0.0;\n    let pt: &mut [u32; 2] = bytemuck::cast_mut(&mut t);\n    let px: [u32; 2] = bytemuck::cast(d);\n    pt[1] = px[1] / 3 + b1;\n    t\n}\n\n// iterative cube root approximation using Halley's method (double)\nfn cbrta_halleyd(a: f64, r: f64) -> f64 {\n    let a3 = a * a * a;\n    a * (a3 + r + r) / (a3 + a3 + r)\n}\n\nfn interp(a: f64, b: f64, t: f64) -> f64 {\n    a + (b - a) * t\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/path64/point64.rs",
      "sha256": "1f2c35539aad92ed3a3335d5bf03fedff2ac125ee104f732588694412835fd63",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse crate::Point;\n\n#[derive(Copy, Clone, PartialEq, Debug)]\npub enum SearchAxis {\n    X,\n    Y,\n}\n\n#[repr(C)]\n#[derive(Copy, Clone, PartialEq, Default, Debug)]\npub struct Point64 {\n    pub x: f64,\n    pub y: f64,\n}\n\nimpl Point64 {\n    pub fn from_xy(x: f64, y: f64) -> Self {\n        Point64 { x, y }\n    }\n\n    pub fn from_point(p: Point) -> Self {\n        Point64 {\n            x: f64::from(p.x),\n            y: f64::from(p.y),\n        }\n    }\n\n    pub fn zero() -> Self {\n        Point64 { x: 0.0, y: 0.0 }\n    }\n\n    pub fn to_point(&self) -> Point {\n        Point::from_xy(self.x as f32, self.y as f32)\n    }\n\n    pub fn axis_coord(&self, axis: SearchAxis) -> f64 {\n        match axis {\n            SearchAxis::X => self.x,\n            SearchAxis::Y => self.y,\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/path64/quad64.rs",
      "sha256": "05b3263b9287c5c506442f3e1d4dfb17bb3f729d8c5074ce4c6387ee489ffc96",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse super::Scalar64;\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\npub fn push_valid_ts(s: &[f64], real_roots: usize, t: &mut [f64]) -> usize {\n    let mut found_roots = 0;\n    'outer: for index in 0..real_roots {\n        let mut t_value = s[index];\n        if t_value.approximately_zero_or_more() && t_value.approximately_one_or_less() {\n            t_value = t_value.bound(0.0, 1.0);\n\n            for idx2 in 0..found_roots {\n                if t[idx2].approximately_equal(t_value) {\n                    continue 'outer;\n                }\n            }\n\n            t[found_roots] = t_value;\n            found_roots += 1;\n        }\n    }\n\n    found_roots\n}\n\n// note: caller expects multiple results to be sorted smaller first\n// note: http://en.wikipedia.org/wiki/Loss_of_significance has an interesting\n//  analysis of the quadratic equation, suggesting why the following looks at\n//  the sign of B -- and further suggesting that the greatest loss of precision\n//  is in b squared less two a c\npub fn roots_valid_t(a: f64, b: f64, c: f64, t: &mut [f64]) -> usize {\n    let mut s = [0.0; 3];\n    let real_roots = roots_real(a, b, c, &mut s);\n    push_valid_ts(&s, real_roots, t)\n}\n\n// Numeric Solutions (5.6) suggests to solve the quadratic by computing\n//     Q = -1/2(B + sgn(B)Sqrt(B^2 - 4 A C))\n// and using the roots\n//     t1 = Q / A\n//     t2 = C / Q\n//\n// this does not discard real roots <= 0 or >= 1\npub fn roots_real(a: f64, b: f64, c: f64, s: &mut [f64; 3]) -> usize {\n    if a == 0.0 {\n        return handle_zero(b, c, s);\n    }\n\n    let p = b / (2.0 * a);\n    let q = c / a;\n    if a.approximately_zero() && (p.approximately_zero_inverse() || q.approximately_zero_inverse())\n    {\n        return handle_zero(b, c, s);\n    }\n\n    // normal form: x^2 + px + q = 0\n    let p2 = p * p;\n    if !p2.almost_dequal_ulps(q) && p2 < q {\n        return 0;\n    }\n\n    let mut sqrt_d = 0.0;\n    if p2 > q {\n        sqrt_d = (p2 - q).sqrt();\n    }\n\n    s[0] = sqrt_d - p;\n    s[1] = -sqrt_d - p;\n    1 + usize::from(!s[0].almost_dequal_ulps(s[1]))\n}\n\nfn handle_zero(b: f64, c: f64, s: &mut [f64; 3]) -> usize {\n    if b.approximately_zero() {\n        s[0] = 0.0;\n        (c == 0.0) as usize\n    } else {\n        s[0] = -c / b;\n        1\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/path_geometry.rs",
      "sha256": "7b3a7070bafb899cea0195b72dba9a88556633e17b208769342214d97daa9bd4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse tiny_skia_path::{NormalizedF32, NormalizedF32Exclusive, Point};\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\npub use tiny_skia_path::path_geometry::{\n    chop_cubic_at2, chop_quad_at, find_cubic_max_curvature, find_unit_quad_roots, new_t_values,\n    CubicCoeff, QuadCoeff,\n};\n\nuse tiny_skia_path::path_geometry::valid_unit_divide;\n\n// TODO: return custom type\n/// Returns 0 for 1 quad, and 1 for two quads, either way the answer is stored in dst[].\n///\n/// Guarantees that the 1/2 quads will be monotonic.\npub fn chop_quad_at_x_extrema(src: &[Point; 3], dst: &mut [Point; 5]) -> usize {\n    let a = src[0].x;\n    let mut b = src[1].x;\n    let c = src[2].x;\n\n    if is_not_monotonic(a, b, c) {\n        if let Some(t_value) = valid_unit_divide(a - b, a - b - b + c) {\n            chop_quad_at(src, t_value, dst);\n\n            // flatten double quad extrema\n            dst[1].x = dst[2].x;\n            dst[3].x = dst[2].x;\n\n            return 1;\n        }\n\n        // if we get here, we need to force dst to be monotonic, even though\n        // we couldn't compute a unit_divide value (probably underflow).\n        b = if (a - b).abs() < (b - c).abs() { a } else { c };\n    }\n\n    dst[0] = Point::from_xy(a, src[0].y);\n    dst[1] = Point::from_xy(b, src[1].y);\n    dst[2] = Point::from_xy(c, src[2].y);\n    0\n}\n\n/// Returns 0 for 1 quad, and 1 for two quads, either way the answer is stored in dst[].\n///\n/// Guarantees that the 1/2 quads will be monotonic.\npub fn chop_quad_at_y_extrema(src: &[Point; 3], dst: &mut [Point; 5]) -> usize {\n    let a = src[0].y;\n    let mut b = src[1].y;\n    let c = src[2].y;\n\n    if is_not_monotonic(a, b, c) {\n        if let Some(t_value) = valid_unit_divide(a - b, a - b - b + c) {\n            chop_quad_at(src, t_value, dst);\n\n            // flatten double quad extrema\n            dst[1].y = dst[2].y;\n            dst[3].y = dst[2].y;\n\n            return 1;\n        }\n\n        // if we get here, we need to force dst to be monotonic, even though\n        // we couldn't compute a unit_divide value (probably underflow).\n        b = if (a - b).abs() < (b - c).abs() { a } else { c };\n    }\n\n    dst[0] = Point::from_xy(src[0].x, a);\n    dst[1] = Point::from_xy(src[1].x, b);\n    dst[2] = Point::from_xy(src[2].x, c);\n    0\n}\n\nfn is_not_monotonic(a: f32, b: f32, c: f32) -> bool {\n    let ab = a - b;\n    let mut bc = b - c;\n    if ab < 0.0 {\n        bc = -bc;\n    }\n\n    ab == 0.0 || bc < 0.0\n}\n\npub fn chop_cubic_at_x_extrema(src: &[Point; 4], dst: &mut [Point; 10]) -> usize {\n    let mut t_values = new_t_values();\n    let t_values = find_cubic_extrema(src[0].x, src[1].x, src[2].x, src[3].x, &mut t_values);\n\n    chop_cubic_at(src, t_values, dst);\n    if !t_values.is_empty() {\n        // we do some cleanup to ensure our X extrema are flat\n        dst[2].x = dst[3].x;\n        dst[4].x = dst[3].x;\n        if t_values.len() == 2 {\n            dst[5].x = dst[6].x;\n            dst[7].x = dst[6].x;\n        }\n    }\n\n    t_values.len()\n}\n\n/// Given 4 points on a cubic bezier, chop it into 1, 2, 3 beziers such that\n/// the resulting beziers are monotonic in Y.\n///\n/// This is called by the scan converter.\n///\n/// Depending on what is returned, dst[] is treated as follows:\n///\n/// - 0: dst[0..3] is the original cubic\n/// - 1: dst[0..3] and dst[3..6] are the two new cubics\n/// - 2: dst[0..3], dst[3..6], dst[6..9] are the three new cubics\npub fn chop_cubic_at_y_extrema(src: &[Point; 4], dst: &mut [Point; 10]) -> usize {\n    let mut t_values = new_t_values();\n    let t_values = find_cubic_extrema(src[0].y, src[1].y, src[2].y, src[3].y, &mut t_values);\n\n    chop_cubic_at(src, t_values, dst);\n    if !t_values.is_empty() {\n        // we do some cleanup to ensure our Y extrema are flat\n        dst[2].y = dst[3].y;\n        dst[4].y = dst[3].y;\n        if t_values.len() == 2 {\n            dst[5].y = dst[6].y;\n            dst[7].y = dst[6].y;\n        }\n    }\n\n    t_values.len()\n}\n\n// Cubic'(t) = At^2 + Bt + C, where\n// A = 3(-a + 3(b - c) + d)\n// B = 6(a - 2b + c)\n// C = 3(b - a)\n// Solve for t, keeping only those that fit between 0 < t < 1\nfn find_cubic_extrema(\n    a: f32,\n    b: f32,\n    c: f32,\n    d: f32,\n    t_values: &mut [NormalizedF32Exclusive; 3],\n) -> &[NormalizedF32Exclusive] {\n    // we divide A,B,C by 3 to simplify\n    let na = d - a + 3.0 * (b - c);\n    let nb = 2.0 * (a - b - b + c);\n    let nc = b - a;\n\n    let roots = find_unit_quad_roots(na, nb, nc, t_values);\n    &t_values[0..roots]\n}\n\n// http://code.google.com/p/skia/issues/detail?id=32\n//\n// This test code would fail when we didn't check the return result of\n// valid_unit_divide in SkChopCubicAt(... NormalizedF32Exclusives[], int roots). The reason is\n// that after the first chop, the parameters to valid_unit_divide are equal\n// (thanks to finite float precision and rounding in the subtracts). Thus\n// even though the 2nd NormalizedF32Exclusive looks < 1.0, after we renormalize it, we end\n// up with 1.0, hence the need to check and just return the last cubic as\n// a degenerate clump of 4 points in the same place.\npub fn chop_cubic_at(src: &[Point; 4], t_values: &[NormalizedF32Exclusive], dst: &mut [Point]) {\n    if t_values.is_empty() {\n        // nothing to chop\n        dst[0] = src[0];\n        dst[1] = src[1];\n        dst[2] = src[2];\n        dst[3] = src[3];\n    } else {\n        let mut t = t_values[0];\n        let mut tmp = [Point::zero(); 4];\n\n        // Reduce the `src` lifetime, so we can use `src = &tmp` later.\n        let mut src = src;\n\n        let mut dst_offset = 0;\n        for i in 0..t_values.len() {\n            chop_cubic_at2(src, t, &mut dst[dst_offset..]);\n            if i == t_values.len() - 1 {\n                break;\n            }\n\n            dst_offset += 3;\n            // have src point to the remaining cubic (after the chop)\n            tmp[0] = dst[dst_offset + 0];\n            tmp[1] = dst[dst_offset + 1];\n            tmp[2] = dst[dst_offset + 2];\n            tmp[3] = dst[dst_offset + 3];\n            src = &tmp;\n\n            // watch out in case the renormalized t isn't in range\n            let n = valid_unit_divide(\n                t_values[i + 1].get() - t_values[i].get(),\n                1.0 - t_values[i].get(),\n            );\n\n            match n {\n                Some(n) => t = n,\n                None => {\n                    // if we can't, just create a degenerate cubic\n                    dst[dst_offset + 4] = src[3];\n                    dst[dst_offset + 5] = src[3];\n                    dst[dst_offset + 6] = src[3];\n                    break;\n                }\n            }\n        }\n    }\n}\n\npub fn chop_cubic_at_max_curvature(\n    src: &[Point; 4],\n    t_values: &mut [NormalizedF32Exclusive; 3],\n    dst: &mut [Point],\n) -> usize {\n    let mut roots = [NormalizedF32::ZERO; 3];\n    let roots = find_cubic_max_curvature(src, &mut roots);\n\n    // Throw out values not inside 0..1.\n    let mut count = 0;\n    for root in roots {\n        if 0.0 < root.get() && root.get() < 1.0 {\n            t_values[count] = NormalizedF32Exclusive::new_bounded(root.get());\n            count += 1;\n        }\n    }\n\n    if count == 0 {\n        dst[0..4].copy_from_slice(src);\n    } else {\n        chop_cubic_at(src, &t_values[0..count], dst);\n    }\n\n    count + 1\n}\n\npub fn chop_mono_cubic_at_x(src: &[Point; 4], x: f32, dst: &mut [Point; 7]) -> bool {\n    cubic_dchop_at_intercept(src, x, true, dst)\n}\n\npub fn chop_mono_cubic_at_y(src: &[Point; 4], y: f32, dst: &mut [Point; 7]) -> bool {\n    cubic_dchop_at_intercept(src, y, false, dst)\n}\n\nfn cubic_dchop_at_intercept(\n    src: &[Point; 4],\n    intercept: f32,\n    is_vertical: bool,\n    dst: &mut [Point; 7],\n) -> bool {\n    use crate::path64::{cubic64::Cubic64, line_cubic_intersections, point64::Point64};\n\n    let src = [\n        Point64::from_point(src[0]),\n        Point64::from_point(src[1]),\n        Point64::from_point(src[2]),\n        Point64::from_point(src[3]),\n    ];\n\n    let cubic = Cubic64::new(src);\n    let mut roots = [0.0; 3];\n    let count = if is_vertical {\n        line_cubic_intersections::vertical_intersect(&cubic, f64::from(intercept), &mut roots)\n    } else {\n        line_cubic_intersections::horizontal_intersect(&cubic, f64::from(intercept), &mut roots)\n    };\n\n    if count > 0 {\n        let pair = cubic.chop_at(roots[0]);\n        for i in 0..7 {\n            dst[i] = pair.points[i].to_point();\n        }\n\n        true\n    } else {\n        false\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn chop_cubic_at_y_extrema_1() {\n        let src = [\n            Point::from_xy(10.0, 20.0),\n            Point::from_xy(67.0, 437.0),\n            Point::from_xy(298.0, 213.0),\n            Point::from_xy(401.0, 214.0),\n        ];\n\n        let mut dst = [Point::zero(); 10];\n        let n = chop_cubic_at_y_extrema(&src, &mut dst);\n        assert_eq!(n, 2);\n        assert_eq!(dst[0], Point::from_xy(10.0, 20.0));\n        assert_eq!(dst[1], Point::from_xy(37.508274, 221.24475));\n        assert_eq!(dst[2], Point::from_xy(105.541855, 273.19803));\n        assert_eq!(dst[3], Point::from_xy(180.15599, 273.19803));\n        assert_eq!(dst[4], Point::from_xy(259.80502, 273.19803));\n        assert_eq!(dst[5], Point::from_xy(346.9527, 213.99666));\n        assert_eq!(dst[6], Point::from_xy(400.30844, 213.99666));\n        assert_eq!(dst[7], Point::from_xy(400.53958, 213.99666));\n        assert_eq!(dst[8], Point::from_xy(400.7701, 213.99777));\n        assert_eq!(dst[9], Point::from_xy(401.0, 214.0));\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/pipeline/blitter.rs",
      "sha256": "959da6b806093b45ba3e8a368d4d81e6f3921a309b5ea8c39e7c989f2008e6b8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2016 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse crate::{BlendMode, Color, LengthU32, Paint, PixmapRef, PremultipliedColorU8, Shader};\nuse crate::{ALPHA_U8_OPAQUE, ALPHA_U8_TRANSPARENT};\n\nuse crate::alpha_runs::AlphaRun;\nuse crate::blitter::{Blitter, Mask};\nuse crate::color::AlphaU8;\nuse crate::geom::ScreenIntRect;\nuse crate::mask::SubMaskRef;\nuse crate::math::LENGTH_U32_ONE;\nuse crate::pipeline::{self, RasterPipeline, RasterPipelineBuilder};\nuse crate::pixmap::SubPixmapMut;\n\npub struct RasterPipelineBlitter<'a, 'b: 'a> {\n    mask: Option<SubMaskRef<'a>>,\n    pixmap_src: PixmapRef<'a>,\n    pixmap: &'a mut SubPixmapMut<'b>,\n    memset2d_color: Option<PremultipliedColorU8>,\n    blit_anti_h_rp: RasterPipeline,\n    blit_rect_rp: RasterPipeline,\n    blit_mask_rp: RasterPipeline,\n    is_mask: bool,\n}\n\nimpl<'a, 'b: 'a> RasterPipelineBlitter<'a, 'b> {\n    pub fn new(\n        paint: &Paint<'a>,\n        mask: Option<SubMaskRef<'a>>,\n        pixmap: &'a mut SubPixmapMut<'b>,\n    ) -> Option<Self> {\n        // Make sure that `mask` has the same size as `pixmap`.\n        if let Some(mask) = mask {\n            if mask.size.width() != pixmap.size.width()\n                || mask.size.height() != pixmap.size.height()\n            {\n                log::warn!(\"Pixmap and Mask are expected to have the same size\");\n                return None;\n            }\n        }\n\n        // Fast-reject.\n        // This is basically SkInterpretXfermode().\n        match paint.blend_mode {\n            // `Destination` keep the pixmap unchanged. Nothing to do here.\n            BlendMode::Destination => return None,\n            BlendMode::DestinationIn if paint.shader.is_opaque() && paint.is_solid_color() => {\n                return None\n            }\n            _ => {}\n        }\n\n        // We can strength-reduce SourceOver into Source when opaque.\n        let mut blend_mode = paint.blend_mode;\n        if paint.shader.is_opaque() && blend_mode == BlendMode::SourceOver && mask.is_none() {\n            blend_mode = BlendMode::Source;\n        }\n\n        // When we're drawing a constant color in Source mode, we can sometimes just memset.\n        let mut memset2d_color = None;\n        if paint.is_solid_color() && blend_mode == BlendMode::Source && mask.is_none() {\n            // Unlike Skia, our shader cannot be constant.\n            // Therefore there is no need to run a raster pipeline to get shader's color.\n            if let Shader::SolidColor(ref color) = paint.shader {\n                memset2d_color = Some(color.premultiply().to_color_u8());\n            }\n        };\n\n        // Clear is just a transparent color memset.\n        if blend_mode == BlendMode::Clear && !paint.anti_alias && mask.is_none() {\n            blend_mode = BlendMode::Source;\n            memset2d_color = Some(PremultipliedColorU8::TRANSPARENT);\n        }\n\n        let blit_anti_h_rp = {\n            let mut p = RasterPipelineBuilder::new();\n            p.set_force_hq_pipeline(paint.force_hq_pipeline);\n            if !paint.shader.push_stages(&mut p) {\n                return None;\n            }\n\n            if mask.is_some() {\n                p.push(pipeline::Stage::MaskU8);\n            }\n\n            if blend_mode.should_pre_scale_coverage() {\n                p.push(pipeline::Stage::Scale1Float);\n                p.push(pipeline::Stage::LoadDestination);\n                if let Some(blend_stage) = blend_mode.to_stage() {\n                    p.push(blend_stage);\n                }\n            } else {\n                p.push(pipeline::Stage::LoadDestination);\n                if let Some(blend_stage) = blend_mode.to_stage() {\n                    p.push(blend_stage);\n                }\n\n                p.push(pipeline::Stage::Lerp1Float);\n            }\n\n            p.push(pipeline::Stage::Store);\n\n            p.compile()\n        };\n\n        let blit_rect_rp = {\n            let mut p = RasterPipelineBuilder::new();\n            p.set_force_hq_pipeline(paint.force_hq_pipeline);\n            if !paint.shader.push_stages(&mut p) {\n                return None;\n            }\n\n            if mask.is_some() {\n                p.push(pipeline::Stage::MaskU8);\n            }\n\n            if blend_mode == BlendMode::SourceOver && mask.is_none() {\n                // TODO: ignore when dither_rate is non-zero\n                p.push(pipeline::Stage::SourceOverRgba);\n            } else {\n                if blend_mode != BlendMode::Source {\n                    p.push(pipeline::Stage::LoadDestination);\n                    if let Some(blend_stage) = blend_mode.to_stage() {\n                        p.push(blend_stage);\n                    }\n                }\n\n                p.push(pipeline::Stage::Store);\n            }\n\n            p.compile()\n        };\n\n        let blit_mask_rp = {\n            let mut p = RasterPipelineBuilder::new();\n            p.set_force_hq_pipeline(paint.force_hq_pipeline);\n            if !paint.shader.push_stages(&mut p) {\n                return None;\n            }\n\n            if mask.is_some() {\n                p.push(pipeline::Stage::MaskU8);\n            }\n\n            if blend_mode.should_pre_scale_coverage() {\n                p.push(pipeline::Stage::ScaleU8);\n                p.push(pipeline::Stage::LoadDestination);\n                if let Some(blend_stage) = blend_mode.to_stage() {\n                    p.push(blend_stage);\n                }\n            } else {\n                p.push(pipeline::Stage::LoadDestination);\n                if let Some(blend_stage) = blend_mode.to_stage() {\n                    p.push(blend_stage);\n                }\n\n                p.push(pipeline::Stage::LerpU8);\n            }\n\n            p.push(pipeline::Stage::Store);\n\n            p.compile()\n        };\n\n        let pixmap_src = match paint.shader {\n            Shader::Pattern(ref patt) => patt.pixmap,\n            // Just a dummy one.\n            _ => PixmapRef::from_bytes(&[0, 0, 0, 0], 1, 1).unwrap(),\n        };\n\n        Some(RasterPipelineBlitter {\n            mask,\n            pixmap_src,\n            pixmap,\n            memset2d_color,\n            blit_anti_h_rp,\n            blit_rect_rp,\n            blit_mask_rp,\n            is_mask: false,\n        })\n    }\n\n    pub fn new_mask(pixmap: &'a mut SubPixmapMut<'b>) -> Option<Self> {\n        let color = Color::WHITE.premultiply();\n\n        let memset2d_color = Some(color.to_color_u8());\n\n        let blit_anti_h_rp = {\n            let mut p = RasterPipelineBuilder::new();\n            p.push_uniform_color(color);\n            p.push(pipeline::Stage::LoadDestinationU8);\n            p.push(pipeline::Stage::Lerp1Float);\n            p.push(pipeline::Stage::StoreU8);\n            p.compile()\n        };\n\n        let blit_rect_rp = {\n            let mut p = RasterPipelineBuilder::new();\n            p.push_uniform_color(color);\n            p.push(pipeline::Stage::StoreU8);\n            p.compile()\n        };\n\n        let blit_mask_rp = {\n            let mut p = RasterPipelineBuilder::new();\n            p.push_uniform_color(color);\n            p.push(pipeline::Stage::LoadDestinationU8);\n            p.push(pipeline::Stage::LerpU8);\n            p.push(pipeline::Stage::StoreU8);\n            p.compile()\n        };\n\n        Some(RasterPipelineBlitter {\n            mask: None,\n            pixmap_src: PixmapRef::from_bytes(&[0, 0, 0, 0], 1, 1).unwrap(),\n            pixmap,\n            memset2d_color,\n            blit_anti_h_rp,\n            blit_rect_rp,\n            blit_mask_rp,\n            is_mask: true,\n        })\n    }\n}\n\nimpl Blitter for RasterPipelineBlitter<'_, '_> {\n    fn blit_h(&mut self, x: u32, y: u32, width: LengthU32) {\n        let r = ScreenIntRect::from_xywh_safe(x, y, width, LENGTH_U32_ONE);\n        self.blit_rect(&r);\n    }\n\n    fn blit_anti_h(&mut self, mut x: u32, y: u32, aa: &mut [AlphaU8], runs: &mut [AlphaRun]) {\n        let mask_ctx = self.mask.map(|c| c.mask_ctx()).unwrap_or_default();\n\n        let mut aa_offset = 0;\n        let mut run_offset = 0;\n        let mut run_opt = runs[0];\n        while let Some(run) = run_opt {\n            let width = LengthU32::from(run);\n\n            match aa[aa_offset] {\n                ALPHA_U8_TRANSPARENT => {}\n                ALPHA_U8_OPAQUE => {\n                    self.blit_h(x, y, width);\n                }\n                alpha => {\n                    self.blit_anti_h_rp.ctx.current_coverage = alpha as f32 * (1.0 / 255.0);\n\n                    let rect = ScreenIntRect::from_xywh_safe(x, y, width, LENGTH_U32_ONE);\n                    self.blit_anti_h_rp.run(\n                        &rect,\n                        pipeline::AAMaskCtx::default(),\n                        mask_ctx,\n                        self.pixmap_src,\n                        self.pixmap,\n                    );\n                }\n            }\n\n            x += width.get();\n            run_offset += usize::from(run.get());\n            aa_offset += usize::from(run.get());\n            run_opt = runs[run_offset];\n        }\n    }\n\n    fn blit_v(&mut self, x: u32, y: u32, height: LengthU32, alpha: AlphaU8) {\n        let bounds = ScreenIntRect::from_xywh_safe(x, y, LENGTH_U32_ONE, height);\n\n        let mask = Mask {\n            image: [alpha, alpha],\n            bounds,\n            row_bytes: 0, // so we reuse the 1 \"row\" for all of height\n        };\n\n        self.blit_mask(&mask, &bounds);\n    }\n\n    fn blit_anti_h2(&mut self, x: u32, y: u32, alpha0: AlphaU8, alpha1: AlphaU8) {\n        let bounds = ScreenIntRect::from_xywh(x, y, 2, 1).unwrap();\n\n        let mask = Mask {\n            image: [alpha0, alpha1],\n            bounds,\n            row_bytes: 2,\n        };\n\n        self.blit_mask(&mask, &bounds);\n    }\n\n    fn blit_anti_v2(&mut self, x: u32, y: u32, alpha0: AlphaU8, alpha1: AlphaU8) {\n        let bounds = ScreenIntRect::from_xywh(x, y, 1, 2).unwrap();\n\n        let mask = Mask {\n            image: [alpha0, alpha1],\n            bounds,\n            row_bytes: 1,\n        };\n\n        self.blit_mask(&mask, &bounds);\n    }\n\n    fn blit_rect(&mut self, rect: &ScreenIntRect) {\n        if let Some(c) = self.memset2d_color {\n            if self.is_mask {\n                for y in 0..rect.height() {\n                    let start = self\n                        .pixmap\n                        .offset(rect.x() as usize, (rect.y() + y) as usize);\n                    let end = start + rect.width() as usize;\n                    self.pixmap.data[start..end]\n                        .iter_mut()\n                        .for_each(|p| *p = c.alpha());\n                }\n            } else {\n                for y in 0..rect.height() {\n                    let start = self\n                        .pixmap\n                        .offset(rect.x() as usize, (rect.y() + y) as usize);\n                    let end = start + rect.width() as usize;\n                    self.pixmap.pixels_mut()[start..end]\n                        .iter_mut()\n                        .for_each(|p| *p = c);\n                }\n            }\n\n            return;\n        }\n\n        let mask_ctx = self.mask.map(|c| c.mask_ctx()).unwrap_or_default();\n\n        self.blit_rect_rp.run(\n            rect,\n            pipeline::AAMaskCtx::default(),\n            mask_ctx,\n            self.pixmap_src,\n            self.pixmap,\n        );\n    }\n\n    fn blit_mask(&mut self, mask: &Mask, clip: &ScreenIntRect) {\n        let aa_mask_ctx = pipeline::AAMaskCtx {\n            pixels: mask.image,\n            stride: mask.row_bytes,\n            shift: (mask.bounds.left() + mask.bounds.top() * mask.row_bytes) as usize,\n        };\n\n        let mask_ctx = self.mask.map(|c| c.mask_ctx()).unwrap_or_default();\n\n        self.blit_mask_rp\n            .run(clip, aa_mask_ctx, mask_ctx, self.pixmap_src, self.pixmap);\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/pipeline/highp.rs",
      "sha256": "96f9d086b0ff783adce4e4121f00bf31983213a8edaa94fcce4f5d89ed2ea393",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/*!\nA high precision raster pipeline implementation.\n\nUnlike lowp, this one implements all stages.\n\nJust like Skia, this pipeline is implemented using f32x8.\n\nFor some reason, we are almost 2x slower. Maybe because Skia uses clang's vector extensions\nand we're using a manual implementation.\n*/\n\nuse crate::{PremultipliedColorU8, SpreadMode, PixmapRef};\n\nuse crate::geom::ScreenIntRect;\nuse crate::pixmap::SubPixmapMut;\nuse crate::wide::{f32x8, i32x8, u32x8};\n\npub const STAGE_WIDTH: usize = 8;\n\npub type StageFn = fn(p: &mut Pipeline);\n\npub struct Pipeline<'a, 'b: 'a> {\n    index: usize,\n    functions: &'a [StageFn],\n    pixmap_src: PixmapRef<'a>,\n    pixmap_dst: &'a mut SubPixmapMut<'b>,\n    ctx: &'a mut super::Context, // TODO: remove mut\n    mask_ctx: super::MaskCtx<'a>,\n    aa_mask_ctx: super::AAMaskCtx,\n    r: f32x8,\n    g: f32x8,\n    b: f32x8,\n    a: f32x8,\n    dr: f32x8,\n    dg: f32x8,\n    db: f32x8,\n    da: f32x8,\n    tail: usize,\n    dx: usize,\n    dy: usize,\n}\n\nimpl Pipeline<'_, '_> {\n    #[inline(always)]\n    fn next_stage(&mut self) {\n        let next: fn(&mut Self) = self.functions[self.index];\n        self.index += 1;\n        next(self);\n    }\n}\n\n// Must be in the same order as raster_pipeline::Stage\npub const STAGES: &[StageFn; super::STAGES_COUNT] = &[\n    move_source_to_destination,\n    move_destination_to_source,\n    clamp_0,\n    clamp_a,\n    premultiply,\n    uniform_color,\n    seed_shader,\n    load_dst,\n    store,\n    load_dst_u8,\n    store_u8,\n    gather,\n    load_mask_u8,\n    mask_u8,\n    scale_u8,\n    lerp_u8,\n    scale_1_float,\n    lerp_1_float,\n    destination_atop,\n    destination_in,\n    destination_out,\n    destination_over,\n    source_atop,\n    source_in,\n    source_out,\n    source_over,\n    clear,\n    modulate,\n    multiply,\n    plus,\n    screen,\n    xor,\n    color_burn,\n    color_dodge,\n    darken,\n    difference,\n    exclusion,\n    hard_light,\n    lighten,\n    overlay,\n    soft_light,\n    hue,\n    saturation,\n    color,\n    luminosity,\n    source_over_rgba,\n    transform,\n    reflect,\n    repeat,\n    bilinear,\n    bicubic,\n    pad_x1,\n    reflect_x1,\n    repeat_x1,\n    gradient,\n    evenly_spaced_2_stop_gradient,\n    xy_to_radius,\n    xy_to_2pt_conical_focal_on_circle,\n    xy_to_2pt_conical_well_behaved,\n    xy_to_2pt_conical_greater,\n    mask_2pt_conical_degenerates,\n    apply_vector_mask,\n];\n\npub fn fn_ptr(f: StageFn) -> *const () {\n    f as *const ()\n}\n\n#[inline(never)]\npub fn start(\n    functions: &[StageFn],\n    functions_tail: &[StageFn],\n    rect: &ScreenIntRect,\n    aa_mask_ctx: super::AAMaskCtx,\n    mask_ctx: super::MaskCtx,\n    ctx: &mut super::Context,\n    pixmap_src: PixmapRef,\n    pixmap_dst: &mut SubPixmapMut,\n) {\n    let mut p = Pipeline {\n        index: 0,\n        functions: &[],\n        pixmap_src,\n        pixmap_dst,\n        mask_ctx,\n        aa_mask_ctx,\n        ctx,\n        r: f32x8::default(),\n        g: f32x8::default(),\n        b: f32x8::default(),\n        a: f32x8::default(),\n        dr: f32x8::default(),\n        dg: f32x8::default(),\n        db: f32x8::default(),\n        da: f32x8::default(),\n        tail: 0,\n        dx: 0,\n        dy: 0,\n    };\n\n    for y in rect.y()..rect.bottom() {\n        let mut x = rect.x() as usize;\n        let end = rect.right() as usize;\n\n        p.functions = functions;\n        while x + STAGE_WIDTH <= end {\n            p.index = 0;\n            p.dx = x;\n            p.dy = y as usize;\n            p.tail = STAGE_WIDTH;\n            p.next_stage();\n            x += STAGE_WIDTH;\n        }\n\n        if x != end {\n            p.index = 0;\n            p.functions = functions_tail;\n            p.dx = x;\n            p.dy = y as usize;\n            p.tail = end - x;\n            p.next_stage();\n        }\n    }\n}\n\nfn move_source_to_destination(p: &mut Pipeline) {\n    p.dr = p.r;\n    p.dg = p.g;\n    p.db = p.b;\n    p.da = p.a;\n\n    p.next_stage();\n}\n\nfn premultiply(p: &mut Pipeline) {\n    p.r *= p.a;\n    p.g *= p.a;\n    p.b *= p.a;\n\n    p.next_stage();\n}\n\nfn move_destination_to_source(p: &mut Pipeline) {\n    p.r = p.dr;\n    p.g = p.dg;\n    p.b = p.db;\n    p.a = p.da;\n\n    p.next_stage();\n}\n\nfn clamp_0(p: &mut Pipeline) {\n    p.r = p.r.max(f32x8::default());\n    p.g = p.g.max(f32x8::default());\n    p.b = p.b.max(f32x8::default());\n    p.a = p.a.max(f32x8::default());\n\n    p.next_stage();\n}\n\nfn clamp_a(p: &mut Pipeline) {\n    p.r = p.r.min(f32x8::splat(1.0));\n    p.g = p.g.min(f32x8::splat(1.0));\n    p.b = p.b.min(f32x8::splat(1.0));\n    p.a = p.a.min(f32x8::splat(1.0));\n\n    p.next_stage();\n}\n\nfn uniform_color(p: &mut Pipeline) {\n    let ctx = &p.ctx.uniform_color;\n    p.r = f32x8::splat(ctx.r);\n    p.g = f32x8::splat(ctx.g);\n    p.b = f32x8::splat(ctx.b);\n    p.a = f32x8::splat(ctx.a);\n\n    p.next_stage();\n}\n\nfn seed_shader(p: &mut Pipeline) {\n    let iota = f32x8::from([0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5]);\n\n    p.r = f32x8::splat(p.dx as f32) + iota;\n    p.g = f32x8::splat(p.dy as f32 + 0.5);\n    p.b = f32x8::splat(1.0);\n    p.a = f32x8::default();\n\n    p.dr = f32x8::default();\n    p.dg = f32x8::default();\n    p.db = f32x8::default();\n    p.da = f32x8::default();\n\n    p.next_stage();\n}\n\npub fn load_dst(p: &mut Pipeline) {\n    load_8888(p.pixmap_dst.slice4_at_xy(p.dx, p.dy), &mut p.dr, &mut p.dg, &mut p.db, &mut p.da);\n    p.next_stage();\n}\n\npub fn load_dst_tail(p: &mut Pipeline) {\n    load_8888_tail(p.tail, p.pixmap_dst.slice_at_xy(p.dx, p.dy), &mut p.dr, &mut p.dg, &mut p.db, &mut p.da);\n    p.next_stage();\n}\n\npub fn store(p: &mut Pipeline) {\n    store_8888(&p.r, &p.g, &p.b, &p.a, p.pixmap_dst.slice4_at_xy(p.dx, p.dy));\n    p.next_stage();\n}\n\npub fn store_tail(p: &mut Pipeline) {\n    store_8888_tail(&p.r, &p.g, &p.b, &p.a, p.tail, p.pixmap_dst.slice_at_xy(p.dx, p.dy));\n    p.next_stage();\n}\n\n// Currently, all mask/A8 pixmaps are handled by lowp.\npub fn load_dst_u8(_: &mut Pipeline) {\n    // unreachable\n}\n\npub fn load_dst_u8_tail(_: &mut Pipeline) {\n    // unreachable\n}\n\npub fn store_u8(_: &mut Pipeline) {\n    // unreachable\n}\n\npub fn store_u8_tail(_: &mut Pipeline) {\n    // unreachable\n}\n\npub fn gather(p: &mut Pipeline) {\n    let ix = gather_ix(p.pixmap_src, p.r, p.g);\n    load_8888(&p.pixmap_src.gather(ix), &mut p.r, &mut p.g, &mut p.b, &mut p.a);\n\n    p.next_stage();\n}\n\n#[inline(always)]\nfn gather_ix(pixmap: PixmapRef, mut x: f32x8, mut y: f32x8) -> u32x8 {\n    // Exclusive -> inclusive.\n    let w = ulp_sub(pixmap.width() as f32);\n    let h = ulp_sub(pixmap.height() as f32);\n    x = x.max(f32x8::default()).min(f32x8::splat(w));\n    y = y.max(f32x8::default()).min(f32x8::splat(h));\n\n    (y.trunc_int() * i32x8::splat(pixmap.width() as i32) + x.trunc_int()).to_u32x8_bitcast()\n}\n\n#[inline(always)]\nfn ulp_sub(v: f32) -> f32 {\n    // Somewhat similar to v - f32::EPSILON\n    bytemuck::cast::<u32, f32>(bytemuck::cast::<f32, u32>(v) - 1)\n}\n\nfn load_mask_u8(_: &mut Pipeline) {\n    // unreachable\n}\n\nfn mask_u8(p: &mut Pipeline) {\n    let offset = p.mask_ctx.offset(p.dx, p.dy);\n    let mut c = [0.0; 8];\n    for i in 0..p.tail {\n        c[i] = p.mask_ctx.data[offset + i] as f32;\n    }\n    let c = f32x8::from(c) / f32x8::splat(255.0);\n\n    if c == f32x8::default() {\n        return;\n    }\n\n    p.r *= c;\n    p.g *= c;\n    p.b *= c;\n    p.a *= c;\n\n    p.next_stage();\n}\n\nfn scale_u8(p: &mut Pipeline) {\n    // Load u8xTail and cast it to f32x8.\n    let data = p.aa_mask_ctx.copy_at_xy(p.dx, p.dy, p.tail);\n    let c = f32x8::from([data[0] as f32, data[1] as f32, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);\n    let c = c / f32x8::splat(255.0);\n\n    p.r *= c;\n    p.g *= c;\n    p.b *= c;\n    p.a *= c;\n\n    p.next_stage();\n}\n\nfn lerp_u8(p: &mut Pipeline) {\n    // Load u8xTail and cast it to f32x8.\n    let data = p.aa_mask_ctx.copy_at_xy(p.dx, p.dy, p.tail);\n    let c = f32x8::from([data[0] as f32, data[1] as f32, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);\n    let c = c / f32x8::splat(255.0);\n\n    p.r = lerp(p.dr, p.r, c);\n    p.g = lerp(p.dg, p.g, c);\n    p.b = lerp(p.db, p.b, c);\n    p.a = lerp(p.da, p.a, c);\n\n    p.next_stage();\n}\n\nfn scale_1_float(p: &mut Pipeline) {\n    let c = f32x8::splat(p.ctx.current_coverage);\n    p.r *= c;\n    p.g *= c;\n    p.b *= c;\n    p.a *= c;\n\n    p.next_stage();\n}\n\nfn lerp_1_float(p: &mut Pipeline) {\n    let c = f32x8::splat(p.ctx.current_coverage);\n    p.r = lerp(p.dr, p.r, c);\n    p.g = lerp(p.dg, p.g, c);\n    p.b = lerp(p.db, p.b, c);\n    p.a = lerp(p.da, p.a, c);\n\n    p.next_stage();\n}\n\nmacro_rules! blend_fn {\n    ($name:ident, $f:expr) => {\n        fn $name(p: &mut Pipeline) {\n            p.r = $f(p.r, p.dr, p.a, p.da);\n            p.g = $f(p.g, p.dg, p.a, p.da);\n            p.b = $f(p.b, p.db, p.a, p.da);\n            p.a = $f(p.a, p.da, p.a, p.da);\n\n            p.next_stage();\n        }\n    };\n}\n\nblend_fn!(clear,            |_, _,  _,  _| f32x8::default());\nblend_fn!(source_atop,      |s, d, sa, da| s * da + d * inv(sa));\nblend_fn!(destination_atop, |s, d, sa, da| d * sa + s * inv(da));\nblend_fn!(source_in,        |s, _,  _, da| s * da);\nblend_fn!(destination_in,   |_, d, sa,  _| d * sa);\nblend_fn!(source_out,       |s, _,  _, da| s * inv(da));\nblend_fn!(destination_out,  |_, d, sa,  _| d * inv(sa));\nblend_fn!(source_over,      |s, d, sa,  _| mad(d, inv(sa), s));\nblend_fn!(destination_over, |s, d,  _, da| mad(s, inv(da), d));\nblend_fn!(modulate,         |s, d,  _,  _| s * d);\nblend_fn!(multiply,         |s, d, sa, da| s * inv(da) + d * inv(sa) + s * d);\nblend_fn!(screen,           |s, d,  _,  _| s + d - s * d);\nblend_fn!(xor,              |s, d, sa, da| s * inv(da) + d * inv(sa));\n\n// Wants a type for some reason.\nblend_fn!(plus, |s: f32x8, d: f32x8, _, _| (s + d).min(f32x8::splat(1.0)));\n\nmacro_rules! blend_fn2 {\n    ($name:ident, $f:expr) => {\n        fn $name(p: &mut Pipeline) {\n            // The same logic applied to color, and source_over for alpha.\n            p.r = $f(p.r, p.dr, p.a, p.da);\n            p.g = $f(p.g, p.dg, p.a, p.da);\n            p.b = $f(p.b, p.db, p.a, p.da);\n            p.a = mad(p.da, inv(p.a), p.a);\n\n            p.next_stage();\n        }\n    };\n}\n\nblend_fn2!(darken,      |s: f32x8, d, sa, da: f32x8| s + d - (s * da).max(d * sa));\nblend_fn2!(lighten,     |s: f32x8, d, sa, da: f32x8| s + d - (s * da).min(d * sa));\nblend_fn2!(difference,  |s: f32x8, d, sa, da: f32x8| s + d - two((s * da).min(d * sa)));\nblend_fn2!(exclusion,   |s: f32x8, d,  _,  _| s + d - two(s * d));\n\nblend_fn2!(color_burn, |s: f32x8, d: f32x8, sa: f32x8, da: f32x8|\n    d.cmp_eq(da).blend(\n        d + s * inv(da),\n        s.cmp_eq(f32x8::default()).blend(\n            d * inv(sa),\n            sa * (da - da.min((da - d) * sa * s.recip_fast())) + s * inv(da) + d * inv(sa)\n        )\n    )\n);\n\nblend_fn2!(color_dodge, |s: f32x8, d: f32x8, sa: f32x8, da: f32x8|\n    d.cmp_eq(f32x8::default()).blend(\n        s * inv(da),\n        s.cmp_eq(sa).blend(\n            s + d * inv(sa),\n            sa * da.min((d * sa) * (sa - s).recip_fast()) + s * inv(da) + d * inv(sa)\n        )\n    )\n);\n\nblend_fn2!(hard_light, |s: f32x8, d: f32x8, sa, da|\n    s * inv(da) + d * inv(sa) + two(s).cmp_le(sa).blend(\n        two(s * d),\n        sa * da - two((da - d) * (sa - s))\n    )\n);\n\nblend_fn2!(overlay, |s: f32x8, d: f32x8, sa, da|\n    s * inv(da) + d * inv(sa) + two(d).cmp_le(da).blend(\n        two(s * d),\n        sa * da - two((da - d) * (sa - s))\n    )\n);\n\nblend_fn2!(soft_light, |s: f32x8, d: f32x8, sa: f32x8, da: f32x8| {\n    let m  = da.cmp_gt(f32x8::default()).blend(d / da, f32x8::default());\n    let s2 = two(s);\n    let m4 = two(two(m));\n\n    // The logic forks three ways:\n    //    1. dark src?\n    //    2. light src, dark dst?\n    //    3. light src, light dst?\n    let dark_src = d * (sa + (s2 - sa) * (f32x8::splat(1.0) - m));\n    let dark_dst = (m4 * m4 + m4) * (m - f32x8::splat(1.0)) + f32x8::splat(7.0) * m;\n    let lite_dst = m.sqrt() - m;\n    let lite_src = d * sa + da * (s2 - sa)\n        * two(two(d)).cmp_le(da).blend(dark_dst, lite_dst); // 2 or 3?\n\n    s * inv(da) + d * inv(sa) + s2.cmp_le(sa).blend(dark_src, lite_src) // 1 or (2 or 3)?\n});\n\n// We're basing our implementation of non-separable blend modes on\n//   https://www.w3.org/TR/compositing-1/#blendingnonseparable.\n// and\n//   https://www.khronos.org/registry/OpenGL/specs/es/3.2/es_spec_3.2.pdf\n// They're equivalent, but ES' math has been better simplified.\n//\n// Anything extra we add beyond that is to make the math work with premul inputs.\n\nmacro_rules! blend_fn3 {\n    ($name:ident, $f:expr) => {\n        fn $name(p: &mut Pipeline) {\n            let (tr, tg, tb, ta) = $f(p.r, p.g, p.b, p.a, p.dr, p.dg, p.db, p.da);\n            p.r = tr;\n            p.g = tg;\n            p.b = tb;\n            p.a = ta;\n\n            p.next_stage();\n        }\n    };\n}\n\nblend_fn3!(hue, hue_k);\n\n#[inline(always)]\nfn hue_k(\n    r: f32x8, g: f32x8, b: f32x8, a: f32x8,\n    dr: f32x8, dg: f32x8, db: f32x8, da: f32x8,\n) -> (f32x8, f32x8, f32x8, f32x8) {\n    let rr = &mut (r * a);\n    let gg = &mut (g * a);\n    let bb = &mut (b * a);\n\n    set_sat(rr, gg, bb, sat(dr, dg, db) * a);\n    set_lum(rr, gg, bb, lum(dr, dg, db) * a);\n    clip_color(rr, gg, bb, a * da);\n\n    let r = r * inv(da) + dr * inv(a) + *rr;\n    let g = g * inv(da) + dg * inv(a) + *gg;\n    let b = b * inv(da) + db * inv(a) + *bb;\n    let a = a + da - a * da;\n\n    (r, g, b, a)\n}\n\nblend_fn3!(saturation, saturation_k);\n\n#[inline(always)]\nfn saturation_k(\n    r: f32x8, g: f32x8, b: f32x8, a: f32x8,\n    dr: f32x8, dg: f32x8, db: f32x8, da: f32x8,\n) -> (f32x8, f32x8, f32x8, f32x8) {\n    let rr = &mut (dr * a);\n    let gg = &mut (dg * a);\n    let bb = &mut (db * a);\n\n    set_sat(rr, gg, bb, sat(r, g, b) * da);\n    set_lum(rr, gg, bb, lum(dr, dg, db) * a); // (This is not redundant.)\n    clip_color(rr, gg, bb, a * da);\n\n    let r = r * inv(da) + dr * inv(a) + *rr;\n    let g = g * inv(da) + dg * inv(a) + *gg;\n    let b = b * inv(da) + db * inv(a) + *bb;\n    let a = a + da - a * da;\n\n    (r, g, b, a)\n}\n\nblend_fn3!(color, color_k);\n\n#[inline(always)]\nfn color_k(\n    r: f32x8, g: f32x8, b: f32x8, a: f32x8,\n    dr: f32x8, dg: f32x8, db: f32x8, da: f32x8,\n) -> (f32x8, f32x8, f32x8, f32x8) {\n    let rr = &mut (r * da);\n    let gg = &mut (g * da);\n    let bb = &mut (b * da);\n\n    set_lum(rr, gg, bb, lum(dr, dg, db) * a);\n    clip_color(rr, gg, bb, a * da);\n\n    let r = r * inv(da) + dr * inv(a) + *rr;\n    let g = g * inv(da) + dg * inv(a) + *gg;\n    let b = b * inv(da) + db * inv(a) + *bb;\n    let a = a + da - a * da;\n\n    (r, g, b, a)\n}\n\nblend_fn3!(luminosity, luminosity_k);\n\n#[inline(always)]\nfn luminosity_k(\n    r: f32x8, g: f32x8, b: f32x8, a: f32x8,\n    dr: f32x8, dg: f32x8, db: f32x8, da: f32x8,\n) -> (f32x8, f32x8, f32x8, f32x8) {\n    let rr = &mut (dr * a);\n    let gg = &mut (dg * a);\n    let bb = &mut (db * a);\n\n    set_lum(rr, gg, bb, lum(r, g, b) * da);\n    clip_color(rr, gg, bb, a * da);\n\n    let r = r * inv(da) + dr * inv(a) + *rr;\n    let g = g * inv(da) + dg * inv(a) + *gg;\n    let b = b * inv(da) + db * inv(a) + *bb;\n    let a = a + da - a * da;\n\n    (r, g, b, a)\n}\n\n#[inline(always)]\nfn sat(r: f32x8, g: f32x8, b: f32x8) -> f32x8 {\n    r.max(g.max(b)) - r.min(g.min(b))\n}\n\n#[inline(always)]\nfn lum(r: f32x8, g: f32x8, b: f32x8) -> f32x8 {\n    r * f32x8::splat(0.30) + g * f32x8::splat(0.59) + b * f32x8::splat(0.11)\n}\n\n#[inline(always)]\nfn set_sat(r: &mut f32x8, g: &mut f32x8, b: &mut f32x8, s: f32x8) {\n    let mn  = r.min(g.min(*b));\n    let mx  = r.max(g.max(*b));\n    let sat = mx - mn;\n\n    // Map min channel to 0, max channel to s, and scale the middle proportionally.\n    let scale = |c| sat.cmp_eq(f32x8::default())\n                       .blend(f32x8::default(), (c - mn) * s / sat);\n\n    *r = scale(*r);\n    *g = scale(*g);\n    *b = scale(*b);\n}\n\n#[inline(always)]\nfn set_lum(r: &mut f32x8, g: &mut f32x8, b: &mut f32x8, l: f32x8) {\n    let diff = l - lum(*r, *g, *b);\n    *r += diff;\n    *g += diff;\n    *b += diff;\n}\n\n#[inline(always)]\nfn clip_color(r: &mut f32x8, g: &mut f32x8, b: &mut f32x8, a: f32x8) {\n    let mn = r.min(g.min(*b));\n    let mx = r.max(g.max(*b));\n    let l  = lum(*r, *g, *b);\n\n    let clip = |mut c| {\n        c = mx.cmp_ge(f32x8::default()).blend(c, l + (c - l) * l / (l - mn));\n        c = mx.cmp_gt(a).blend(l + (c - l) * (a - l) / (mx - l), c);\n        c = c.max(f32x8::default()); // Sometimes without this we may dip just a little negative.\n        c\n    };\n\n    *r = clip(*r);\n    *g = clip(*g);\n    *b = clip(*b);\n}\n\npub fn source_over_rgba(p: &mut Pipeline) {\n    let pixels = p.pixmap_dst.slice4_at_xy(p.dx, p.dy);\n    load_8888(pixels, &mut p.dr, &mut p.dg, &mut p.db, &mut p.da);\n    p.r = mad(p.dr, inv(p.a), p.r);\n    p.g = mad(p.dg, inv(p.a), p.g);\n    p.b = mad(p.db, inv(p.a), p.b);\n    p.a = mad(p.da, inv(p.a), p.a);\n    store_8888(&p.r, &p.g, &p.b, &p.a, pixels);\n\n    p.next_stage();\n}\n\npub fn source_over_rgba_tail(p: &mut Pipeline) {\n    let pixels = p.pixmap_dst.slice_at_xy(p.dx, p.dy);\n    load_8888_tail(p.tail, pixels, &mut p.dr, &mut p.dg, &mut p.db, &mut p.da);\n    p.r = mad(p.dr, inv(p.a), p.r);\n    p.g = mad(p.dg, inv(p.a), p.g);\n    p.b = mad(p.db, inv(p.a), p.b);\n    p.a = mad(p.da, inv(p.a), p.a);\n    store_8888_tail(&p.r, &p.g, &p.b, &p.a, p.tail, pixels);\n\n    p.next_stage();\n}\n\nfn transform(p: &mut Pipeline) {\n    let ts = &p.ctx.transform;\n\n    let tr = mad(p.r, f32x8::splat(ts.sx), mad(p.g, f32x8::splat(ts.kx), f32x8::splat(ts.tx)));\n    let tg = mad(p.r, f32x8::splat(ts.ky), mad(p.g, f32x8::splat(ts.sy), f32x8::splat(ts.ty)));\n    p.r = tr;\n    p.g = tg;\n\n    p.next_stage();\n}\n\n// Tile x or y to [0,limit) == [0,limit - 1 ulp] (think, sampling from images).\n// The gather stages will hard clamp the output of these stages to [0,limit)...\n// we just need to do the basic repeat or mirroring.\n\nfn reflect(p: &mut Pipeline) {\n    let ctx = &p.ctx.limit_x;\n    p.r = exclusive_reflect(p.r, ctx.scale, ctx.inv_scale);\n\n    let ctx = &p.ctx.limit_y;\n    p.g = exclusive_reflect(p.g, ctx.scale, ctx.inv_scale);\n\n    p.next_stage();\n}\n\n#[inline(always)]\nfn exclusive_reflect(v: f32x8, limit: f32, inv_limit: f32) -> f32x8 {\n    let limit = f32x8::splat(limit);\n    let inv_limit = f32x8::splat(inv_limit);\n    ((v - limit) - (limit + limit)\n        * ((v - limit) * (inv_limit * f32x8::splat(0.5))).floor() - limit).abs()\n}\n\nfn repeat(p: &mut Pipeline) {\n    let ctx = &p.ctx.limit_x;\n    p.r = exclusive_repeat(p.r, ctx.scale, ctx.inv_scale);\n\n    let ctx = &p.ctx.limit_y;\n    p.g = exclusive_repeat(p.g, ctx.scale, ctx.inv_scale);\n\n    p.next_stage();\n}\n\n#[inline(always)]\nfn exclusive_repeat(v: f32x8, limit: f32, inv_limit: f32) -> f32x8 {\n    v - (v * f32x8::splat(inv_limit)).floor() * f32x8::splat(limit)\n}\n\nfn bilinear(p: &mut Pipeline) {\n    let x = p.r;\n    let fx = (x + f32x8::splat(0.5)).fract();\n    let y = p.g;\n    let fy = (y + f32x8::splat(0.5)).fract();\n    let one = f32x8::splat(1.0);\n    let wx = [one - fx, fx];\n    let wy = [one - fy, fy];\n\n    sampler_2x2(p.pixmap_src, &p.ctx.sampler, x, y, &wx, &wy, &mut p.r, &mut p.g, &mut p.b, &mut p.a);\n\n    p.next_stage();\n}\n\nfn bicubic(p: &mut Pipeline) {\n    let x = p.r;\n    let fx = (x + f32x8::splat(0.5)).fract();\n    let y = p.g;\n    let fy = (y + f32x8::splat(0.5)).fract();\n    let one = f32x8::splat(1.0);\n    let wx = [bicubic_far(one - fx), bicubic_near(one - fx), bicubic_near(fx), bicubic_far(fx)];\n    let wy = [bicubic_far(one - fy), bicubic_near(one - fy), bicubic_near(fy), bicubic_far(fy)];\n\n    sampler_4x4(p.pixmap_src, &p.ctx.sampler, x, y, &wx, &wy, &mut p.r, &mut p.g, &mut p.b, &mut p.a);\n\n    p.next_stage();\n}\n\n// In bicubic interpolation, the 16 pixels and +/- 0.5 and +/- 1.5 offsets from the sample\n// pixel center are combined with a non-uniform cubic filter, with higher values near the center.\n//\n// We break this function into two parts, one for near 0.5 offsets and one for far 1.5 offsets.\n\n#[inline(always)]\nfn bicubic_near(t: f32x8) -> f32x8 {\n    // 1/18 + 9/18t + 27/18t^2 - 21/18t^3 == t ( t ( -21/18t + 27/18) + 9/18) + 1/18\n    mad(\n        t,\n        mad(t,\n            mad(\n                f32x8::splat(-21.0/18.0),\n                t,\n                f32x8::splat(27.0/18.0),\n            ),\n            f32x8::splat(9.0/18.0),\n        ),\n        f32x8::splat(1.0/18.0),\n    )\n}\n\n#[inline(always)]\nfn bicubic_far(t: f32x8) -> f32x8 {\n    // 0/18 + 0/18*t - 6/18t^2 + 7/18t^3 == t^2 (7/18t - 6/18)\n    (t * t) * mad(f32x8::splat(7.0/18.0), t, f32x8::splat(-6.0/18.0))\n}\n\n#[inline(always)]\nfn sampler_2x2(\n    pixmap: PixmapRef,\n    ctx: &super::SamplerCtx,\n    cx: f32x8, cy: f32x8,\n    wx: &[f32x8; 2], wy: &[f32x8; 2],\n    r: &mut f32x8, g: &mut f32x8, b: &mut f32x8, a: &mut f32x8,\n) {\n    *r = f32x8::default();\n    *g = f32x8::default();\n    *b = f32x8::default();\n    *a = f32x8::default();\n\n    let one = f32x8::splat(1.0);\n    let start = -0.5;\n    let mut y = cy + f32x8::splat(start);\n    for j in 0..2 {\n        let mut x = cx + f32x8::splat(start);\n        for i in 0..2 {\n            let mut rr = f32x8::default();\n            let mut gg = f32x8::default();\n            let mut bb = f32x8::default();\n            let mut aa = f32x8::default();\n            sample(pixmap, ctx, x,y, &mut rr, &mut gg, &mut bb, &mut aa);\n\n            let w = wx[i] * wy[j];\n            *r = mad(w, rr, *r);\n            *g = mad(w, gg, *g);\n            *b = mad(w, bb, *b);\n            *a = mad(w, aa, *a);\n\n            x += one;\n        }\n\n        y += one;\n    }\n}\n\n#[inline(always)]\nfn sampler_4x4(\n    pixmap: PixmapRef,\n    ctx: &super::SamplerCtx,\n    cx: f32x8, cy: f32x8,\n    wx: &[f32x8; 4], wy: &[f32x8; 4],\n    r: &mut f32x8, g: &mut f32x8, b: &mut f32x8, a: &mut f32x8,\n) {\n    *r = f32x8::default();\n    *g = f32x8::default();\n    *b = f32x8::default();\n    *a = f32x8::default();\n\n    let one = f32x8::splat(1.0);\n    let start = -1.5;\n    let mut y = cy + f32x8::splat(start);\n    for j in 0..4 {\n        let mut x = cx + f32x8::splat(start);\n        for i in 0..4 {\n            let mut rr = f32x8::default();\n            let mut gg = f32x8::default();\n            let mut bb = f32x8::default();\n            let mut aa = f32x8::default();\n            sample(pixmap, ctx, x,y, &mut rr, &mut gg, &mut bb, &mut aa);\n\n            let w = wx[i] * wy[j];\n            *r = mad(w, rr, *r);\n            *g = mad(w, gg, *g);\n            *b = mad(w, bb, *b);\n            *a = mad(w, aa, *a);\n\n            x += one;\n        }\n\n        y += one;\n    }\n}\n\n#[inline(always)]\nfn sample(\n    pixmap: PixmapRef, ctx: &super::SamplerCtx, mut x: f32x8, mut y: f32x8,\n    r: &mut f32x8, g: &mut f32x8, b: &mut f32x8, a: &mut f32x8,\n) {\n    x = tile(x, ctx.spread_mode, pixmap.width() as f32, ctx.inv_width);\n    y = tile(y, ctx.spread_mode, pixmap.height() as f32, ctx.inv_height);\n\n    let ix = gather_ix(pixmap, x, y);\n    load_8888(&pixmap.gather(ix), r, g, b, a);\n}\n\n#[inline(always)]\nfn tile(v: f32x8, mode: SpreadMode, limit: f32, inv_limit: f32) -> f32x8 {\n    match mode {\n        SpreadMode::Pad => v,\n        SpreadMode::Repeat => exclusive_repeat(v, limit, inv_limit),\n        SpreadMode::Reflect => exclusive_reflect(v, limit, inv_limit),\n    }\n}\n\nfn pad_x1(p: &mut Pipeline) {\n    p.r = p.r.normalize();\n\n    p.next_stage();\n}\n\nfn reflect_x1(p: &mut Pipeline) {\n    p.r = (\n        (p.r - f32x8::splat(1.0))\n            - two(((p.r - f32x8::splat(1.0)) * f32x8::splat(0.5)).floor())\n            - f32x8::splat(1.0)\n    ).abs().normalize();\n\n    p.next_stage();\n}\n\nfn repeat_x1(p: &mut Pipeline) {\n    p.r = (p.r - p.r.floor()).normalize();\n\n    p.next_stage();\n}\n\nfn gradient(p: &mut Pipeline) {\n    let ctx = &p.ctx.gradient;\n\n    // N.B. The loop starts at 1 because idx 0 is the color to use before the first stop.\n    let t: [f32; 8] = p.r.into();\n    let mut idx = u32x8::default();\n    for i in 1..ctx.len {\n        let tt = ctx.t_values[i].get();\n        let n: u32x8 = bytemuck::cast([\n            (t[0] >= tt) as u32,\n            (t[1] >= tt) as u32,\n            (t[2] >= tt) as u32,\n            (t[3] >= tt) as u32,\n            (t[4] >= tt) as u32,\n            (t[5] >= tt) as u32,\n            (t[6] >= tt) as u32,\n            (t[7] >= tt) as u32,\n        ]);\n        idx = idx + n;\n    }\n    gradient_lookup(ctx, &idx, p.r, &mut p.r, &mut p.g, &mut p.b, &mut p.a);\n\n    p.next_stage();\n}\n\nfn gradient_lookup(\n    ctx: &super::GradientCtx, idx: &u32x8, t: f32x8,\n    r: &mut f32x8, g: &mut f32x8, b: &mut f32x8, a: &mut f32x8,\n) {\n    let idx: [u32; 8] = bytemuck::cast(*idx);\n\n    macro_rules! gather {\n        ($d:expr, $c:ident) => {\n            // Surprisingly, but bound checking doesn't affect the performance.\n            // And since `idx` can contain any number, we should leave it in place.\n            f32x8::from([\n                $d[idx[0] as usize].$c,\n                $d[idx[1] as usize].$c,\n                $d[idx[2] as usize].$c,\n                $d[idx[3] as usize].$c,\n                $d[idx[4] as usize].$c,\n                $d[idx[5] as usize].$c,\n                $d[idx[6] as usize].$c,\n                $d[idx[7] as usize].$c,\n            ])\n        };\n    }\n\n    let fr = gather!(&ctx.factors, r);\n    let fg = gather!(&ctx.factors, g);\n    let fb = gather!(&ctx.factors, b);\n    let fa = gather!(&ctx.factors, a);\n\n    let br = gather!(&ctx.biases, r);\n    let bg = gather!(&ctx.biases, g);\n    let bb = gather!(&ctx.biases, b);\n    let ba = gather!(&ctx.biases, a);\n\n    *r = mad(t, fr, br);\n    *g = mad(t, fg, bg);\n    *b = mad(t, fb, bb);\n    *a = mad(t, fa, ba);\n}\n\nfn evenly_spaced_2_stop_gradient(p: &mut Pipeline) {\n    let ctx = &p.ctx.evenly_spaced_2_stop_gradient;\n\n    let t = p.r;\n    p.r = mad(t, f32x8::splat(ctx.factor.r), f32x8::splat(ctx.bias.r));\n    p.g = mad(t, f32x8::splat(ctx.factor.g), f32x8::splat(ctx.bias.g));\n    p.b = mad(t, f32x8::splat(ctx.factor.b), f32x8::splat(ctx.bias.b));\n    p.a = mad(t, f32x8::splat(ctx.factor.a), f32x8::splat(ctx.bias.a));\n\n    p.next_stage();\n}\n\nfn xy_to_radius(p: &mut Pipeline) {\n    let x2 = p.r * p.r;\n    let y2 = p.g * p.g;\n    p.r = (x2 + y2).sqrt();\n\n    p.next_stage();\n}\n\nfn xy_to_2pt_conical_focal_on_circle(p: &mut Pipeline) {\n    let x = p.r;\n    let y = p.g;\n    p.r = x + y * y / x;\n\n    p.next_stage();\n}\n\nfn xy_to_2pt_conical_well_behaved(p: &mut Pipeline) {\n    let ctx = &p.ctx.two_point_conical_gradient;\n\n    let x = p.r;\n    let y = p.g;\n    p.r = (x * x + y * y).sqrt() - x * f32x8::splat(ctx.p0);\n\n    p.next_stage();\n}\n\nfn xy_to_2pt_conical_greater(p: &mut Pipeline) {\n    let ctx = &p.ctx.two_point_conical_gradient;\n\n    let x = p.r;\n    let y = p.g;\n    p.r = (x * x - y * y).sqrt() - x * f32x8::splat(ctx.p0);\n\n    p.next_stage();\n}\n\nfn mask_2pt_conical_degenerates(p: &mut Pipeline) {\n    let ctx = &mut p.ctx.two_point_conical_gradient;\n\n    let t = p.r;\n    let is_degenerate = t.cmp_le(f32x8::default()) | t.cmp_ne(t);\n    p.r = is_degenerate.blend(f32x8::default(), t);\n\n    let is_not_degenerate = !is_degenerate.to_u32x8_bitcast();\n    let is_not_degenerate: [u32; 8] = bytemuck::cast(is_not_degenerate);\n    ctx.mask = bytemuck::cast([\n        if is_not_degenerate[0] != 0 { !0 } else { 0 },\n        if is_not_degenerate[1] != 0 { !0 } else { 0 },\n        if is_not_degenerate[2] != 0 { !0 } else { 0 },\n        if is_not_degenerate[3] != 0 { !0 } else { 0 },\n        if is_not_degenerate[4] != 0 { !0 } else { 0 },\n        if is_not_degenerate[5] != 0 { !0 } else { 0 },\n        if is_not_degenerate[6] != 0 { !0 } else { 0 },\n        if is_not_degenerate[7] != 0 { !0 } else { 0 },\n    ]);\n\n    p.next_stage();\n}\n\nfn apply_vector_mask(p: &mut Pipeline) {\n    let ctx = &p.ctx.two_point_conical_gradient;\n\n    p.r = (p.r.to_u32x8_bitcast() & ctx.mask).to_f32x8_bitcast();\n    p.g = (p.g.to_u32x8_bitcast() & ctx.mask).to_f32x8_bitcast();\n    p.b = (p.b.to_u32x8_bitcast() & ctx.mask).to_f32x8_bitcast();\n    p.a = (p.a.to_u32x8_bitcast() & ctx.mask).to_f32x8_bitcast();\n\n    p.next_stage();\n}\n\npub fn just_return(_: &mut Pipeline) {\n    // Ends the loop.\n}\n\n#[inline(always)]\nfn load_8888(\n    data: &[PremultipliedColorU8; STAGE_WIDTH],\n    r: &mut f32x8, g: &mut f32x8, b: &mut f32x8, a: &mut f32x8,\n) {\n    // Surprisingly, `f32 * FACTOR` is way faster than `f32x8 * f32x8::splat(FACTOR)`.\n\n    const FACTOR: f32 = 1.0 / 255.0;\n\n    *r = f32x8::from([\n        data[0].red() as f32 * FACTOR, data[1].red() as f32 * FACTOR,\n        data[2].red() as f32 * FACTOR, data[3].red() as f32 * FACTOR,\n        data[4].red() as f32 * FACTOR, data[5].red() as f32 * FACTOR,\n        data[6].red() as f32 * FACTOR, data[7].red() as f32 * FACTOR,\n    ]);\n\n    *g = f32x8::from([\n        data[0].green() as f32 * FACTOR, data[1].green() as f32 * FACTOR,\n        data[2].green() as f32 * FACTOR, data[3].green() as f32 * FACTOR,\n        data[4].green() as f32 * FACTOR, data[5].green() as f32 * FACTOR,\n        data[6].green() as f32 * FACTOR, data[7].green() as f32 * FACTOR,\n    ]);\n\n    *b = f32x8::from([\n        data[0].blue() as f32 * FACTOR, data[1].blue() as f32 * FACTOR,\n        data[2].blue() as f32 * FACTOR, data[3].blue() as f32 * FACTOR,\n        data[4].blue() as f32 * FACTOR, data[5].blue() as f32 * FACTOR,\n        data[6].blue() as f32 * FACTOR, data[7].blue() as f32 * FACTOR,\n    ]);\n\n    *a = f32x8::from([\n        data[0].alpha() as f32 * FACTOR, data[1].alpha() as f32 * FACTOR,\n        data[2].alpha() as f32 * FACTOR, data[3].alpha() as f32 * FACTOR,\n        data[4].alpha() as f32 * FACTOR, data[5].alpha() as f32 * FACTOR,\n        data[6].alpha() as f32 * FACTOR, data[7].alpha() as f32 * FACTOR,\n    ]);\n}\n\n#[inline(always)]\nfn load_8888_tail(\n    tail: usize, data: &[PremultipliedColorU8],\n    r: &mut f32x8, g: &mut f32x8, b: &mut f32x8, a: &mut f32x8,\n) {\n    // Fill a dummy array with `tail` values. `tail` is always in a 1..STAGE_WIDTH-1 range.\n    // This way we can reuse the `load_8888_` method and remove any branches.\n    let mut tmp = [PremultipliedColorU8::TRANSPARENT; STAGE_WIDTH];\n    tmp[0..tail].copy_from_slice(&data[0..tail]);\n    load_8888(&tmp, r, g, b, a);\n}\n\n#[inline(always)]\nfn store_8888(\n    r: &f32x8, g: &f32x8, b: &f32x8, a: &f32x8,\n    data: &mut [PremultipliedColorU8; STAGE_WIDTH],\n) {\n    let r: [i32; 8] = unnorm(r).into();\n    let g: [i32; 8] = unnorm(g).into();\n    let b: [i32; 8] = unnorm(b).into();\n    let a: [i32; 8] = unnorm(a).into();\n\n    let conv = |rr, gg, bb, aa|\n        PremultipliedColorU8::from_rgba_unchecked(rr as u8, gg as u8, bb as u8, aa as u8);\n\n    data[0] = conv(r[0], g[0], b[0], a[0]);\n    data[1] = conv(r[1], g[1], b[1], a[1]);\n    data[2] = conv(r[2], g[2], b[2], a[2]);\n    data[3] = conv(r[3], g[3], b[3], a[3]);\n    data[4] = conv(r[4], g[4], b[4], a[4]);\n    data[5] = conv(r[5], g[5], b[5], a[5]);\n    data[6] = conv(r[6], g[6], b[6], a[6]);\n    data[7] = conv(r[7], g[7], b[7], a[7]);\n}\n\n#[inline(always)]\nfn store_8888_tail(\n    r: &f32x8, g: &f32x8, b: &f32x8, a: &f32x8,\n    tail: usize, data: &mut [PremultipliedColorU8],\n) {\n    let r: [i32; 8] = unnorm(r).into();\n    let g: [i32; 8] = unnorm(g).into();\n    let b: [i32; 8] = unnorm(b).into();\n    let a: [i32; 8] = unnorm(a).into();\n\n    // This is better than `for i in 0..tail`, because this way the compiler\n    // knows that we have only 4 steps and slices access is guarantee to be valid.\n    // This removes bounds checking and a possible panic call.\n    for i in 0..STAGE_WIDTH {\n        data[i] = PremultipliedColorU8::from_rgba_unchecked(\n            r[i] as u8, g[i] as u8, b[i] as u8, a[i] as u8,\n        );\n\n        if i + 1 == tail {\n            break;\n        }\n    }\n}\n\n#[inline(always)]\nfn unnorm(v: &f32x8) -> i32x8 {\n    (v.max(f32x8::default()).min(f32x8::splat(1.0)) * f32x8::splat(255.0)).round_int()\n}\n\n#[inline(always)]\nfn inv(v: f32x8) -> f32x8 {\n    f32x8::splat(1.0) - v\n}\n\n#[inline(always)]\nfn two(v: f32x8) -> f32x8 {\n    v + v\n}\n\n#[inline(always)]\nfn mad(f: f32x8, m: f32x8, a: f32x8) -> f32x8 {\n    f * m + a\n}\n\n#[inline(always)]\nfn lerp(from: f32x8, to: f32x8, t: f32x8) -> f32x8 {\n    mad(to - from, t, from)\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/pipeline/lowp.rs",
      "sha256": "878f4d05da7a5b101ff5bb2af87b5ccc208b94fc85c108644b95654198d66ab8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2018 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/*!\nA low precision raster pipeline implementation.\n\nA lowp pipeline uses u16 instead of f32 for math.\nBecause of that, it doesn't implement stages that require high precision.\nThe pipeline compiler will automatically decide which one to use.\n\nSkia uses u16x8 (128bit) types for a generic CPU and u16x16 (256bit) for modern x86 CPUs.\nBut instead of explicit SIMD instructions, it mainly relies on clang's vector extensions.\nAnd since they are unavailable in Rust, we have to do everything manually.\n\nAccording to our benchmarks, a SIMD-accelerated u16x8 in Rust is almost 2x slower than in Skia.\nNot sure why. For example, there are no div instruction for u16x8, so we have to use\na basic scalar version. Which means unnecessary load/store. No idea what clang does in this case.\nSurprisingly, a SIMD-accelerated u16x8 is even slower than a scalar one. Again, not sure why.\n\nTherefore we are using scalar u16x16 by default and relying on rustc/llvm auto vectorization instead.\nWhen targeting a generic CPU, we're just 5-10% slower than Skia. While u16x8 is 30-40% slower.\nAnd while `-C target-cpu=haswell` boosts our performance by around 25%,\nwe are still 40-60% behind Skia built for Haswell.\n\nOn ARM AArch64 the story is different and explicit SIMD make our code up to 2-3x faster.\n*/\n\nuse crate::PremultipliedColorU8;\n\nuse crate::pixmap::SubPixmapMut;\nuse crate::wide::{f32x8, u16x16, f32x16};\nuse crate::geom::ScreenIntRect;\n\npub const STAGE_WIDTH: usize = 16;\n\npub type StageFn = fn(p: &mut Pipeline);\n\npub struct Pipeline<'a, 'b: 'a> {\n    index: usize,\n    functions: &'a [StageFn],\n    pixmap: &'a mut SubPixmapMut<'b>,\n    mask_ctx: super::MaskCtx<'a>,\n    aa_mask_ctx: super::AAMaskCtx,\n    ctx: &'a mut super::Context,\n    r: u16x16,\n    g: u16x16,\n    b: u16x16,\n    a: u16x16,\n    dr: u16x16,\n    dg: u16x16,\n    db: u16x16,\n    da: u16x16,\n    tail: usize,\n    dx: usize,\n    dy: usize,\n}\n\nimpl Pipeline<'_, '_> {\n    #[inline(always)]\n    fn next_stage(&mut self) {\n        let next: fn(&mut Self) = self.functions[self.index];\n        self.index += 1;\n        next(self);\n    }\n}\n\n\n// Must be in the same order as raster_pipeline::Stage\npub const STAGES: &[StageFn; super::STAGES_COUNT] = &[\n    move_source_to_destination,\n    move_destination_to_source,\n    null_fn, // Clamp0\n    null_fn, // ClampA\n    premultiply,\n    uniform_color,\n    seed_shader,\n    load_dst,\n    store,\n    load_dst_u8,\n    store_u8,\n    null_fn, // Gather\n    load_mask_u8,\n    mask_u8,\n    scale_u8,\n    lerp_u8,\n    scale_1_float,\n    lerp_1_float,\n    destination_atop,\n    destination_in,\n    destination_out,\n    destination_over,\n    source_atop,\n    source_in,\n    source_out,\n    source_over,\n    clear,\n    modulate,\n    multiply,\n    plus,\n    screen,\n    xor,\n    null_fn, // ColorBurn\n    null_fn, // ColorDodge\n    darken,\n    difference,\n    exclusion,\n    hard_light,\n    lighten,\n    overlay,\n    null_fn, // SoftLight\n    null_fn, // Hue\n    null_fn, // Saturation\n    null_fn, // Color\n    null_fn, // Luminosity\n    source_over_rgba,\n    transform,\n    null_fn, // Reflect\n    null_fn, // Repeat\n    null_fn, // Bilinear\n    null_fn, // Bicubic\n    pad_x1,\n    reflect_x1,\n    repeat_x1,\n    gradient,\n    evenly_spaced_2_stop_gradient,\n    xy_to_radius,\n    null_fn, // XYTo2PtConicalFocalOnCircle\n    null_fn, // XYTo2PtConicalWellBehaved\n    null_fn, // XYTo2PtConicalGreater\n    null_fn, // Mask2PtConicalDegenerates\n    null_fn, // ApplyVectorMask\n];\n\npub fn fn_ptr(f: StageFn) -> *const () {\n    f as *const ()\n}\n\npub fn fn_ptr_eq(f1: StageFn, f2: StageFn) -> bool {\n    core::ptr::eq(f1 as *const (), f2 as *const ())\n}\n\n#[inline(never)]\npub fn start(\n    functions: &[StageFn],\n    functions_tail: &[StageFn],\n    rect: &ScreenIntRect,\n    aa_mask_ctx: super::AAMaskCtx,\n    mask_ctx: super::MaskCtx,\n    ctx: &mut super::Context,\n    pixmap: &mut SubPixmapMut,\n) {\n    let mut p = Pipeline {\n        index: 0,\n        functions: &[],\n        pixmap,\n        mask_ctx,\n        aa_mask_ctx,\n        ctx,\n        r: u16x16::default(),\n        g: u16x16::default(),\n        b: u16x16::default(),\n        a: u16x16::default(),\n        dr: u16x16::default(),\n        dg: u16x16::default(),\n        db: u16x16::default(),\n        da: u16x16::default(),\n        tail: 0,\n        dx: 0,\n        dy: 0,\n    };\n\n    for y in rect.y()..rect.bottom() {\n        let mut x = rect.x() as usize;\n        let end = rect.right() as usize;\n\n        p.functions = functions;\n        while x + STAGE_WIDTH <= end {\n            p.index = 0;\n            p.dx = x;\n            p.dy = y as usize;\n            p.tail = STAGE_WIDTH;\n            p.next_stage();\n            x += STAGE_WIDTH;\n        }\n\n        if x != end {\n            p.index = 0;\n            p.functions = functions_tail;\n            p.dx = x;\n            p.dy = y as usize;\n            p.tail = end - x;\n            p.next_stage();\n        }\n    }\n}\n\nfn move_source_to_destination(p: &mut Pipeline) {\n    p.dr = p.r;\n    p.dg = p.g;\n    p.db = p.b;\n    p.da = p.a;\n\n    p.next_stage();\n}\n\nfn move_destination_to_source(p: &mut Pipeline) {\n    p.r = p.dr;\n    p.g = p.dg;\n    p.b = p.db;\n    p.a = p.da;\n\n    p.next_stage();\n}\n\nfn premultiply(p: &mut Pipeline) {\n    p.r = div255(p.r * p.a);\n    p.g = div255(p.g * p.a);\n    p.b = div255(p.b * p.a);\n\n    p.next_stage();\n}\n\nfn uniform_color(p: &mut Pipeline) {\n    let ctx = p.ctx.uniform_color;\n    p.r = u16x16::splat(ctx.rgba[0]);\n    p.g = u16x16::splat(ctx.rgba[1]);\n    p.b = u16x16::splat(ctx.rgba[2]);\n    p.a = u16x16::splat(ctx.rgba[3]);\n\n    p.next_stage();\n}\n\nfn seed_shader(p: &mut Pipeline) {\n    let iota = f32x16(\n        f32x8::from([0.5,  1.5,  2.5,  3.5,  4.5,  5.5,  6.5,  7.5]),\n        f32x8::from([8.5,  9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5]),\n    );\n\n    let x = f32x16::splat(p.dx as f32) + iota;\n    let y = f32x16::splat(p.dy as f32 + 0.5);\n    split(&x, &mut p.r, &mut p.g);\n    split(&y, &mut p.b, &mut p.a);\n\n    p.next_stage();\n}\n\npub fn load_dst(p: &mut Pipeline) {\n    load_8888(p.pixmap.slice16_at_xy(p.dx, p.dy), &mut p.dr, &mut p.dg, &mut p.db, &mut p.da);\n    p.next_stage();\n}\n\npub fn load_dst_tail(p: &mut Pipeline) {\n    load_8888_tail(p.tail, p.pixmap.slice_at_xy(p.dx, p.dy), &mut p.dr, &mut p.dg, &mut p.db, &mut p.da);\n    p.next_stage();\n}\n\npub fn store(p: &mut Pipeline) {\n    store_8888(&p.r, &p.g, &p.b, &p.a, p.pixmap.slice16_at_xy(p.dx, p.dy));\n    p.next_stage();\n}\n\npub fn store_tail(p: &mut Pipeline) {\n    store_8888_tail(&p.r, &p.g, &p.b, &p.a, p.tail, p.pixmap.slice_at_xy(p.dx, p.dy));\n    p.next_stage();\n}\n\npub fn load_dst_u8(p: &mut Pipeline) {\n    load_8(p.pixmap.slice16_mask_at_xy(p.dx, p.dy), &mut p.da);\n    p.next_stage();\n}\n\npub fn load_dst_u8_tail(p: &mut Pipeline) {\n    // Fill a dummy array with `tail` values. `tail` is always in a 1..STAGE_WIDTH-1 range.\n    // This way we can reuse the `load_8888__` method and remove any branches.\n    let data = p.pixmap.slice_mask_at_xy(p.dx, p.dy);\n    let mut tmp = [0u8; STAGE_WIDTH];\n    tmp[0..p.tail].copy_from_slice(&data[0..p.tail]);\n    load_8(&tmp, &mut p.da);\n\n    p.next_stage();\n}\n\npub fn store_u8(p: &mut Pipeline) {\n    let data = p.pixmap.slice16_mask_at_xy(p.dx, p.dy);\n    let a = p.a.as_slice();\n\n    data[ 0] = a[ 0] as u8;\n    data[ 1] = a[ 1] as u8;\n    data[ 2] = a[ 2] as u8;\n    data[ 3] = a[ 3] as u8;\n    data[ 4] = a[ 4] as u8;\n    data[ 5] = a[ 5] as u8;\n    data[ 6] = a[ 6] as u8;\n    data[ 7] = a[ 7] as u8;\n    data[ 8] = a[ 8] as u8;\n    data[ 9] = a[ 9] as u8;\n    data[10] = a[10] as u8;\n    data[11] = a[11] as u8;\n    data[12] = a[12] as u8;\n    data[13] = a[13] as u8;\n    data[14] = a[14] as u8;\n    data[15] = a[15] as u8;\n\n    p.next_stage();\n}\n\npub fn store_u8_tail(p: &mut Pipeline) {\n    let data = p.pixmap.slice_mask_at_xy(p.dx, p.dy);\n    let a = p.a.as_slice();\n\n    // This is better than `for i in 0..tail`, because this way the compiler\n    // knows that we have only 16 steps and slices access is guarantee to be valid.\n    // This removes bounds checking and a possible panic call.\n    for i in 0..STAGE_WIDTH {\n        data[i] = a[i] as u8;\n\n        if i + 1 == p.tail {\n            break;\n        }\n    }\n\n    p.next_stage();\n}\n\n// Similar to mask_u8, but only loads the mask values without actually masking the pipeline.\nfn load_mask_u8(p: &mut Pipeline) {\n    let offset = p.mask_ctx.offset(p.dx, p.dy);\n\n    let mut c = u16x16::default();\n    for i in 0..p.tail {\n        c.0[i] = u16::from(p.mask_ctx.data[offset + i]);\n    }\n\n    p.r = u16x16::splat(0);\n    p.g = u16x16::splat(0);\n    p.b = u16x16::splat(0);\n    p.a = c;\n\n    p.next_stage();\n}\n\nfn mask_u8(p: &mut Pipeline) {\n    let offset = p.mask_ctx.offset(p.dx, p.dy);\n\n    let mut c = u16x16::default();\n    for i in 0..p.tail {\n        c.0[i] = u16::from(p.mask_ctx.data[offset + i]);\n    }\n\n    if c == u16x16::default() {\n        return;\n    }\n\n    p.r = div255(p.r * c);\n    p.g = div255(p.g * c);\n    p.b = div255(p.b * c);\n    p.a = div255(p.a * c);\n\n    p.next_stage();\n}\n\nfn scale_u8(p: &mut Pipeline) {\n    // Load u8xTail and cast it to u16x16.\n    let data = p.aa_mask_ctx.copy_at_xy(p.dx, p.dy, p.tail);\n    let c = u16x16([\n        u16::from(data[0]),\n        u16::from(data[1]),\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n    ]);\n\n    p.r = div255(p.r * c);\n    p.g = div255(p.g * c);\n    p.b = div255(p.b * c);\n    p.a = div255(p.a * c);\n\n    p.next_stage();\n}\n\nfn lerp_u8(p: &mut Pipeline) {\n    // Load u8xTail and cast it to u16x16.\n    let data = p.aa_mask_ctx.copy_at_xy(p.dx, p.dy, p.tail);\n    let c = u16x16([\n        u16::from(data[0]),\n        u16::from(data[1]),\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n        0,\n    ]);\n\n    p.r = lerp(p.dr, p.r, c);\n    p.g = lerp(p.dg, p.g, c);\n    p.b = lerp(p.db, p.b, c);\n    p.a = lerp(p.da, p.a, c);\n\n    p.next_stage();\n}\n\nfn scale_1_float(p: &mut Pipeline) {\n    let c = from_float(p.ctx.current_coverage);\n    p.r = div255(p.r * c);\n    p.g = div255(p.g * c);\n    p.b = div255(p.b * c);\n    p.a = div255(p.a * c);\n\n    p.next_stage();\n}\n\nfn lerp_1_float(p: &mut Pipeline) {\n    let c = from_float(p.ctx.current_coverage);\n    p.r = lerp(p.dr, p.r, c);\n    p.g = lerp(p.dg, p.g, c);\n    p.b = lerp(p.db, p.b, c);\n    p.a = lerp(p.da, p.a, c);\n\n    p.next_stage();\n}\n\nmacro_rules! blend_fn {\n    ($name:ident, $f:expr) => {\n        fn $name(p: &mut Pipeline) {\n            p.r = $f(p.r, p.dr, p.a, p.da);\n            p.g = $f(p.g, p.dg, p.a, p.da);\n            p.b = $f(p.b, p.db, p.a, p.da);\n            p.a = $f(p.a, p.da, p.a, p.da);\n\n            p.next_stage();\n        }\n    };\n}\n\nblend_fn!(clear,            |_, _,  _,  _| u16x16::splat(0));\nblend_fn!(source_atop,      |s, d, sa, da| div255(s * da + d * inv(sa)));\nblend_fn!(destination_atop, |s, d, sa, da| div255(d * sa + s * inv(da)));\nblend_fn!(source_in,        |s, _,  _, da| div255(s * da));\nblend_fn!(destination_in,   |_, d, sa,  _| div255(d * sa));\nblend_fn!(source_out,       |s, _,  _, da| div255(s * inv(da)));\nblend_fn!(destination_out,  |_, d, sa,  _| div255(d * inv(sa)));\nblend_fn!(source_over,      |s, d, sa,  _| s + div255(d * inv(sa)));\nblend_fn!(destination_over, |s, d,  _, da| d + div255(s * inv(da)));\nblend_fn!(modulate,         |s, d,  _,  _| div255(s * d));\nblend_fn!(multiply,         |s, d, sa, da| div255(s * inv(da) + d * inv(sa) + s * d));\nblend_fn!(screen,           |s, d,  _,  _| s + d - div255(s * d));\nblend_fn!(xor,              |s, d, sa, da| div255(s * inv(da) + d * inv(sa)));\n\n// Wants a type for some reason.\nblend_fn!(plus, |s: u16x16, d, _, _| (s + d).min(&u16x16::splat(255)));\n\n\nmacro_rules! blend_fn2 {\n    ($name:ident, $f:expr) => {\n        fn $name(p: &mut Pipeline) {\n            // The same logic applied to color, and source_over for alpha.\n            p.r = $f(p.r, p.dr, p.a, p.da);\n            p.g = $f(p.g, p.dg, p.a, p.da);\n            p.b = $f(p.b, p.db, p.a, p.da);\n            p.a = p.a + div255(p.da * inv(p.a));\n\n            p.next_stage();\n        }\n    };\n}\n\nblend_fn2!(darken,      |s: u16x16, d, sa, da| s + d - div255((s * da).max(&(d * sa))));\nblend_fn2!(lighten,     |s: u16x16, d, sa, da| s + d - div255((s * da).min(&(d * sa))));\nblend_fn2!(exclusion,   |s: u16x16, d,  _,  _| s + d - u16x16::splat(2) * div255(s * d));\n\nblend_fn2!(difference,  |s: u16x16, d, sa, da|\n    s + d - u16x16::splat(2) * div255((s * da).min(&(d * sa))));\n\nblend_fn2!(hard_light, |s: u16x16, d: u16x16, sa, da| {\n    div255(s * inv(da) + d * inv(sa)\n        + (s+s).cmp_le(&sa).blend(\n            u16x16::splat(2) * s * d,\n            sa * da - u16x16::splat(2) * (sa-s)*(da-d)\n        )\n    )\n});\n\nblend_fn2!(overlay, |s: u16x16, d: u16x16, sa, da| {\n    div255(s * inv(da) + d * inv(sa)\n        + (d+d).cmp_le(&da).blend(\n            u16x16::splat(2) * s * d,\n            sa * da - u16x16::splat(2) * (sa-s)*(da-d)\n        )\n    )\n});\n\npub fn source_over_rgba(p: &mut Pipeline) {\n    let pixels = p.pixmap.slice16_at_xy(p.dx, p.dy);\n    load_8888(pixels, &mut p.dr, &mut p.dg, &mut p.db, &mut p.da);\n    p.r = p.r + div255(p.dr * inv(p.a));\n    p.g = p.g + div255(p.dg * inv(p.a));\n    p.b = p.b + div255(p.db * inv(p.a));\n    p.a = p.a + div255(p.da * inv(p.a));\n    store_8888(&p.r, &p.g, &p.b, &p.a, pixels);\n\n    p.next_stage();\n}\n\npub fn source_over_rgba_tail(p: &mut Pipeline) {\n    let pixels = p.pixmap.slice_at_xy(p.dx, p.dy);\n    load_8888_tail(p.tail, pixels, &mut p.dr, &mut p.dg, &mut p.db, &mut p.da);\n    p.r = p.r + div255(p.dr * inv(p.a));\n    p.g = p.g + div255(p.dg * inv(p.a));\n    p.b = p.b + div255(p.db * inv(p.a));\n    p.a = p.a + div255(p.da * inv(p.a));\n    store_8888_tail(&p.r, &p.g, &p.b, &p.a, p.tail, pixels);\n\n    p.next_stage();\n}\n\nfn transform(p: &mut Pipeline) {\n    let ts = &p.ctx.transform;\n\n    let x = join(&p.r, &p.g);\n    let y = join(&p.b, &p.a);\n\n    let nx = mad(x, f32x16::splat(ts.sx), mad(y, f32x16::splat(ts.kx), f32x16::splat(ts.tx)));\n    let ny = mad(x, f32x16::splat(ts.ky), mad(y, f32x16::splat(ts.sy), f32x16::splat(ts.ty)));\n\n    split(&nx, &mut p.r, &mut p.g);\n    split(&ny, &mut p.b, &mut p.a);\n\n    p.next_stage();\n}\n\nfn pad_x1(p: &mut Pipeline) {\n    let x = join(&p.r, &p.g);\n    let x = x.normalize();\n    split(&x, &mut p.r, &mut p.g);\n\n    p.next_stage();\n}\n\nfn reflect_x1(p: &mut Pipeline) {\n    let x = join(&p.r, &p.g);\n    let two = |x| x + x;\n    let x = (\n        (x - f32x16::splat(1.0))\n        - two(((x - f32x16::splat(1.0)) * f32x16::splat(0.5)).floor())\n        - f32x16::splat(1.0)\n    ).abs().normalize();\n    split(&x, &mut p.r, &mut p.g);\n\n    p.next_stage();\n}\n\nfn repeat_x1(p: &mut Pipeline) {\n    let x = join(&p.r, &p.g);\n    let x = (x - x.floor()).normalize();\n    split(&x, &mut p.r, &mut p.g);\n\n    p.next_stage();\n}\n\nfn gradient(p: &mut Pipeline) {\n    let ctx = &p.ctx.gradient;\n\n    // N.B. The loop starts at 1 because idx 0 is the color to use before the first stop.\n    let t = join(&p.r, &p.g);\n    let mut idx = u16x16::splat(0);\n    for i in 1..ctx.len {\n        let tt = ctx.t_values[i].get();\n        let t0: [f32; 8] = t.0.into();\n        let t1: [f32; 8] = t.1.into();\n        idx.0[ 0] += (t0[0] >= tt) as u16;\n        idx.0[ 1] += (t0[1] >= tt) as u16;\n        idx.0[ 2] += (t0[2] >= tt) as u16;\n        idx.0[ 3] += (t0[3] >= tt) as u16;\n        idx.0[ 4] += (t0[4] >= tt) as u16;\n        idx.0[ 5] += (t0[5] >= tt) as u16;\n        idx.0[ 6] += (t0[6] >= tt) as u16;\n        idx.0[ 7] += (t0[7] >= tt) as u16;\n        idx.0[ 8] += (t1[0] >= tt) as u16;\n        idx.0[ 9] += (t1[1] >= tt) as u16;\n        idx.0[10] += (t1[2] >= tt) as u16;\n        idx.0[11] += (t1[3] >= tt) as u16;\n        idx.0[12] += (t1[4] >= tt) as u16;\n        idx.0[13] += (t1[5] >= tt) as u16;\n        idx.0[14] += (t1[6] >= tt) as u16;\n        idx.0[15] += (t1[7] >= tt) as u16;\n    }\n    gradient_lookup(ctx, &idx, t, &mut p.r, &mut p.g, &mut p.b, &mut p.a);\n\n    p.next_stage();\n}\n\nfn evenly_spaced_2_stop_gradient(p: &mut Pipeline) {\n    let ctx = &p.ctx.evenly_spaced_2_stop_gradient;\n\n    let t = join(&p.r, &p.g);\n    round_f32_to_u16(\n        mad(t, f32x16::splat(ctx.factor.r), f32x16::splat(ctx.bias.r)),\n        mad(t, f32x16::splat(ctx.factor.g), f32x16::splat(ctx.bias.g)),\n        mad(t, f32x16::splat(ctx.factor.b), f32x16::splat(ctx.bias.b)),\n        mad(t, f32x16::splat(ctx.factor.a), f32x16::splat(ctx.bias.a)),\n        &mut p.r, &mut p.g, &mut p.b, &mut p.a,\n    );\n\n    p.next_stage();\n}\n\nfn xy_to_radius(p: &mut Pipeline) {\n    let x = join(&p.r, &p.g);\n    let y = join(&p.b, &p.a);\n    let x = (x*x + y*y).sqrt();\n    split(&x, &mut p.r, &mut p.g);\n    split(&y, &mut p.b, &mut p.a);\n\n    p.next_stage();\n}\n\n// We are using u16 for index, not u32 as Skia, to simplify the code a bit.\n// The gradient creation code will not allow that many stops anyway.\nfn gradient_lookup(\n    ctx: &super::GradientCtx, idx: &u16x16, t: f32x16,\n    r: &mut u16x16, g: &mut u16x16, b: &mut u16x16, a: &mut u16x16,\n) {\n    macro_rules! gather {\n        ($d:expr, $c:ident) => {\n            // Surprisingly, but bound checking doesn't affect the performance.\n            // And since `idx` can contain any number, we should leave it in place.\n            f32x16(\n                f32x8::from([\n                    $d[idx.0[ 0] as usize].$c,\n                    $d[idx.0[ 1] as usize].$c,\n                    $d[idx.0[ 2] as usize].$c,\n                    $d[idx.0[ 3] as usize].$c,\n                    $d[idx.0[ 4] as usize].$c,\n                    $d[idx.0[ 5] as usize].$c,\n                    $d[idx.0[ 6] as usize].$c,\n                    $d[idx.0[ 7] as usize].$c,\n                ]),\n                f32x8::from([\n                    $d[idx.0[ 8] as usize].$c,\n                    $d[idx.0[ 9] as usize].$c,\n                    $d[idx.0[10] as usize].$c,\n                    $d[idx.0[11] as usize].$c,\n                    $d[idx.0[12] as usize].$c,\n                    $d[idx.0[13] as usize].$c,\n                    $d[idx.0[14] as usize].$c,\n                    $d[idx.0[15] as usize].$c,\n                ]),\n            )\n        };\n    }\n\n    let fr = gather!(&ctx.factors, r);\n    let fg = gather!(&ctx.factors, g);\n    let fb = gather!(&ctx.factors, b);\n    let fa = gather!(&ctx.factors, a);\n\n    let br = gather!(&ctx.biases, r);\n    let bg = gather!(&ctx.biases, g);\n    let bb = gather!(&ctx.biases, b);\n    let ba = gather!(&ctx.biases, a);\n\n    round_f32_to_u16(\n        mad(t, fr, br),\n        mad(t, fg, bg),\n        mad(t, fb, bb),\n        mad(t, fa, ba),\n        r, g, b, a,\n    );\n}\n\n#[inline(always)]\nfn round_f32_to_u16(\n    rf: f32x16, gf: f32x16, bf: f32x16, af: f32x16,\n    r: &mut u16x16, g: &mut u16x16, b: &mut u16x16, a: &mut u16x16,\n) {\n    // TODO: may produce a slightly different result to Skia\n    //       affects the two_stops_linear_mirror test\n\n    let rf = rf.normalize() * f32x16::splat(255.0) + f32x16::splat(0.5);\n    let gf = gf.normalize() * f32x16::splat(255.0) + f32x16::splat(0.5);\n    let bf = bf.normalize() * f32x16::splat(255.0) + f32x16::splat(0.5);\n    let af = af * f32x16::splat(255.0) + f32x16::splat(0.5);\n\n    rf.save_to_u16x16(r);\n    gf.save_to_u16x16(g);\n    bf.save_to_u16x16(b);\n    af.save_to_u16x16(a);\n}\n\npub fn just_return(_: &mut Pipeline) {\n    // Ends the loop.\n}\n\npub fn null_fn(_: &mut Pipeline) {\n    // Just for unsupported functions in STAGES.\n}\n\n#[inline(always)]\nfn load_8888(\n    data: &[PremultipliedColorU8; STAGE_WIDTH],\n    r: &mut u16x16, g: &mut u16x16, b: &mut u16x16, a: &mut u16x16,\n) {\n    *r = u16x16([\n        data[ 0].red() as u16, data[ 1].red() as u16, data[ 2].red() as u16, data[ 3].red() as u16,\n        data[ 4].red() as u16, data[ 5].red() as u16, data[ 6].red() as u16, data[ 7].red() as u16,\n        data[ 8].red() as u16, data[ 9].red() as u16, data[10].red() as u16, data[11].red() as u16,\n        data[12].red() as u16, data[13].red() as u16, data[14].red() as u16, data[15].red() as u16,\n    ]);\n\n    *g = u16x16([\n        data[ 0].green() as u16, data[ 1].green() as u16, data[ 2].green() as u16, data[ 3].green() as u16,\n        data[ 4].green() as u16, data[ 5].green() as u16, data[ 6].green() as u16, data[ 7].green() as u16,\n        data[ 8].green() as u16, data[ 9].green() as u16, data[10].green() as u16, data[11].green() as u16,\n        data[12].green() as u16, data[13].green() as u16, data[14].green() as u16, data[15].green() as u16,\n    ]);\n\n    *b = u16x16([\n        data[ 0].blue() as u16, data[ 1].blue() as u16, data[ 2].blue() as u16, data[ 3].blue() as u16,\n        data[ 4].blue() as u16, data[ 5].blue() as u16, data[ 6].blue() as u16, data[ 7].blue() as u16,\n        data[ 8].blue() as u16, data[ 9].blue() as u16, data[10].blue() as u16, data[11].blue() as u16,\n        data[12].blue() as u16, data[13].blue() as u16, data[14].blue() as u16, data[15].blue() as u16,\n    ]);\n\n    *a = u16x16([\n        data[ 0].alpha() as u16, data[ 1].alpha() as u16, data[ 2].alpha() as u16, data[ 3].alpha() as u16,\n        data[ 4].alpha() as u16, data[ 5].alpha() as u16, data[ 6].alpha() as u16, data[ 7].alpha() as u16,\n        data[ 8].alpha() as u16, data[ 9].alpha() as u16, data[10].alpha() as u16, data[11].alpha() as u16,\n        data[12].alpha() as u16, data[13].alpha() as u16, data[14].alpha() as u16, data[15].alpha() as u16,\n    ]);\n}\n\n#[inline(always)]\nfn load_8888_tail(\n    tail: usize, data: &[PremultipliedColorU8],\n    r: &mut u16x16, g: &mut u16x16, b: &mut u16x16, a: &mut u16x16,\n) {\n    // Fill a dummy array with `tail` values. `tail` is always in a 1..STAGE_WIDTH-1 range.\n    // This way we can reuse the `load_8888__` method and remove any branches.\n    let mut tmp = [PremultipliedColorU8::TRANSPARENT; STAGE_WIDTH];\n    tmp[0..tail].copy_from_slice(&data[0..tail]);\n    load_8888(&tmp, r, g, b, a);\n}\n\n#[inline(always)]\nfn store_8888(\n    r: &u16x16, g: &u16x16, b: &u16x16, a: &u16x16,\n    data: &mut [PremultipliedColorU8; STAGE_WIDTH],\n) {\n    let r = r.as_slice();\n    let g = g.as_slice();\n    let b = b.as_slice();\n    let a = a.as_slice();\n\n    data[ 0] = PremultipliedColorU8::from_rgba_unchecked(r[ 0] as u8, g[ 0] as u8, b[ 0] as u8, a[ 0] as u8);\n    data[ 1] = PremultipliedColorU8::from_rgba_unchecked(r[ 1] as u8, g[ 1] as u8, b[ 1] as u8, a[ 1] as u8);\n    data[ 2] = PremultipliedColorU8::from_rgba_unchecked(r[ 2] as u8, g[ 2] as u8, b[ 2] as u8, a[ 2] as u8);\n    data[ 3] = PremultipliedColorU8::from_rgba_unchecked(r[ 3] as u8, g[ 3] as u8, b[ 3] as u8, a[ 3] as u8);\n    data[ 4] = PremultipliedColorU8::from_rgba_unchecked(r[ 4] as u8, g[ 4] as u8, b[ 4] as u8, a[ 4] as u8);\n    data[ 5] = PremultipliedColorU8::from_rgba_unchecked(r[ 5] as u8, g[ 5] as u8, b[ 5] as u8, a[ 5] as u8);\n    data[ 6] = PremultipliedColorU8::from_rgba_unchecked(r[ 6] as u8, g[ 6] as u8, b[ 6] as u8, a[ 6] as u8);\n    data[ 7] = PremultipliedColorU8::from_rgba_unchecked(r[ 7] as u8, g[ 7] as u8, b[ 7] as u8, a[ 7] as u8);\n    data[ 8] = PremultipliedColorU8::from_rgba_unchecked(r[ 8] as u8, g[ 8] as u8, b[ 8] as u8, a[ 8] as u8);\n    data[ 9] = PremultipliedColorU8::from_rgba_unchecked(r[ 9] as u8, g[ 9] as u8, b[ 9] as u8, a[ 9] as u8);\n    data[10] = PremultipliedColorU8::from_rgba_unchecked(r[10] as u8, g[10] as u8, b[10] as u8, a[10] as u8);\n    data[11] = PremultipliedColorU8::from_rgba_unchecked(r[11] as u8, g[11] as u8, b[11] as u8, a[11] as u8);\n    data[12] = PremultipliedColorU8::from_rgba_unchecked(r[12] as u8, g[12] as u8, b[12] as u8, a[12] as u8);\n    data[13] = PremultipliedColorU8::from_rgba_unchecked(r[13] as u8, g[13] as u8, b[13] as u8, a[13] as u8);\n    data[14] = PremultipliedColorU8::from_rgba_unchecked(r[14] as u8, g[14] as u8, b[14] as u8, a[14] as u8);\n    data[15] = PremultipliedColorU8::from_rgba_unchecked(r[15] as u8, g[15] as u8, b[15] as u8, a[15] as u8);\n}\n\n#[inline(always)]\nfn store_8888_tail(\n    r: &u16x16, g: &u16x16, b: &u16x16, a: &u16x16,\n    tail: usize, data: &mut [PremultipliedColorU8],\n) {\n    let r = r.as_slice();\n    let g = g.as_slice();\n    let b = b.as_slice();\n    let a = a.as_slice();\n\n    // This is better than `for i in 0..tail`, because this way the compiler\n    // knows that we have only 16 steps and slices access is guarantee to be valid.\n    // This removes bounds checking and a possible panic call.\n    for i in 0..STAGE_WIDTH {\n        data[i] = PremultipliedColorU8::from_rgba_unchecked(\n            r[i] as u8, g[i] as u8, b[i] as u8, a[i] as u8,\n        );\n\n        if i + 1 == tail {\n            break;\n        }\n    }\n}\n\n#[inline(always)]\nfn load_8(data: &[u8; STAGE_WIDTH], a: &mut u16x16) {\n    *a = u16x16([\n        data[ 0] as u16, data[ 1] as u16, data[ 2] as u16, data[ 3] as u16,\n        data[ 4] as u16, data[ 5] as u16, data[ 6] as u16, data[ 7] as u16,\n        data[ 8] as u16, data[ 9] as u16, data[10] as u16, data[11] as u16,\n        data[12] as u16, data[13] as u16, data[14] as u16, data[15] as u16,\n    ]);\n}\n\n#[inline(always)]\nfn div255(v: u16x16) -> u16x16 {\n    // Skia uses `vrshrq_n_u16(vrsraq_n_u16(v, v, 8), 8)` here when NEON is available,\n    // but it doesn't affect performance much and breaks reproducible result. Ignore it.\n    // NOTE: the compiler does not replace the devision with a shift.\n    (v + u16x16::splat(255)) >> u16x16::splat(8) // / u16x16::splat(256)\n}\n\n#[inline(always)]\nfn inv(v: u16x16) -> u16x16 {\n    u16x16::splat(255) - v\n}\n\n#[inline(always)]\nfn from_float(f: f32) -> u16x16 {\n    u16x16::splat((f * 255.0 + 0.5) as u16)\n}\n\n#[inline(always)]\nfn lerp(from: u16x16, to: u16x16, t: u16x16) -> u16x16 {\n    div255(from * inv(t) + to * t)\n}\n\n#[inline(always)]\nfn split(v: &f32x16, lo: &mut u16x16, hi: &mut u16x16) {\n    // We're splitting f32x16 (512bit) into two u16x16 (256 bit).\n    let data: [u8; 64] = bytemuck::cast(*v);\n    let d0: &mut [u8; 32] = bytemuck::cast_mut(&mut lo.0);\n    let d1: &mut [u8; 32] = bytemuck::cast_mut(&mut hi.0);\n\n    d0.copy_from_slice(&data[0..32]);\n    d1.copy_from_slice(&data[32..64]);\n}\n\n#[inline(always)]\nfn join(lo: &u16x16, hi: &u16x16) -> f32x16 {\n    // We're joining two u16x16 (256 bit) into f32x16 (512bit).\n\n    let d0: [u8; 32] = bytemuck::cast(lo.0);\n    let d1: [u8; 32] = bytemuck::cast(hi.0);\n\n    let mut v = f32x16::default();\n    let data: &mut [u8; 64] = bytemuck::cast_mut(&mut v);\n\n    data[0..32].copy_from_slice(&d0);\n    data[32..64].copy_from_slice(&d1);\n\n    v\n}\n\n#[inline(always)]\nfn mad(f: f32x16, m: f32x16, a: f32x16) -> f32x16 {\n    // NEON vmlaq_f32 doesn't seem to affect performance in any way. Ignore it.\n    f * m + a\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/pipeline/mod.rs",
      "sha256": "300bfe14f5223aed89c9d2f31b087b942eba6ed28b0aa0100d7a0e21a25c7fa7",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2016 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n/*!\nA raster pipeline implementation.\n\nDespite having a lot of changes compared to `SkRasterPipeline`,\nthe core principles are the same:\n\n1. A pipeline consists of stages.\n1. A pipeline has a global context shared by all stages.\n   Unlike Skia, were each stage has it's own, possibly shared, context.\n1. Each stage has a high precision implementation. See `highp.rs`.\n1. Some stages have a low precision implementation. See `lowp.rs`.\n1. Each stage calls the \"next\" stage after its done.\n1. During pipeline \"compilation\", if **all** stages have a lowp implementation,\n   the lowp pipeline will be used. Otherwise, the highp variant will be used.\n1. The pipeline \"compilation\" produces a list of function pointer.\n   The last pointer is a pointer to the \"return\" function,\n   which simply stops the execution of the pipeline.\n\nThis implementation is a bit tricky, but it gives the maximum performance.\nA simple and straightforward implementation using traits and loops, like:\n\n```ignore\ntrait StageTrait {\n    fn apply(&mut self, pixels: &mut [Pixel]);\n}\n\nlet stages: Vec<&mut dyn StageTrait>;\nfor stage in stages {\n    stage.apply(pixels);\n}\n```\n\nwill be at least 20-30% slower. Not really sure why.\n\nAlso, since this module is all about performance, any kind of branching is\nstrictly forbidden. All stage functions must not use `if`, `match` or loops.\nThere are still some exceptions, which are basically an imperfect implementations\nand should be optimized out in the future.\n*/\n\nuse alloc::vec::Vec;\n\nuse arrayvec::ArrayVec;\n\nuse tiny_skia_path::NormalizedF32;\n\nuse crate::{Color, PremultipliedColor, PremultipliedColorU8, SpreadMode};\nuse crate::{PixmapRef, Transform};\n\npub use blitter::RasterPipelineBlitter;\n\nuse crate::geom::ScreenIntRect;\nuse crate::pixmap::SubPixmapMut;\nuse crate::wide::u32x8;\n\nmod blitter;\n#[rustfmt::skip] mod highp;\n#[rustfmt::skip] mod lowp;\n\nconst MAX_STAGES: usize = 32; // More than enough.\n\n#[allow(dead_code)]\n#[derive(Copy, Clone, Debug)]\npub enum Stage {\n    MoveSourceToDestination = 0,\n    MoveDestinationToSource,\n    Clamp0,\n    ClampA,\n    Premultiply,\n    UniformColor,\n    SeedShader,\n    LoadDestination,\n    Store,\n    LoadDestinationU8,\n    StoreU8,\n    Gather,\n    LoadMaskU8,\n    MaskU8,\n    ScaleU8,\n    LerpU8,\n    Scale1Float,\n    Lerp1Float,\n    DestinationAtop,\n    DestinationIn,\n    DestinationOut,\n    DestinationOver,\n    SourceAtop,\n    SourceIn,\n    SourceOut,\n    SourceOver,\n    Clear,\n    Modulate,\n    Multiply,\n    Plus,\n    Screen,\n    Xor,\n    ColorBurn,\n    ColorDodge,\n    Darken,\n    Difference,\n    Exclusion,\n    HardLight,\n    Lighten,\n    Overlay,\n    SoftLight,\n    Hue,\n    Saturation,\n    Color,\n    Luminosity,\n    SourceOverRgba,\n    Transform,\n    Reflect,\n    Repeat,\n    Bilinear,\n    Bicubic,\n    PadX1,\n    ReflectX1,\n    RepeatX1,\n    Gradient,\n    EvenlySpaced2StopGradient,\n    XYToRadius,\n    XYTo2PtConicalFocalOnCircle,\n    XYTo2PtConicalWellBehaved,\n    XYTo2PtConicalGreater,\n    Mask2PtConicalDegenerates,\n    ApplyVectorMask,\n}\n\npub const STAGES_COUNT: usize = Stage::ApplyVectorMask as usize + 1;\n\nimpl<'a> PixmapRef<'a> {\n    #[inline(always)]\n    pub(crate) fn gather(&self, index: u32x8) -> [PremultipliedColorU8; highp::STAGE_WIDTH] {\n        let index: [u32; 8] = bytemuck::cast(index);\n        let pixels = self.pixels();\n        [\n            pixels[index[0] as usize],\n            pixels[index[1] as usize],\n            pixels[index[2] as usize],\n            pixels[index[3] as usize],\n            pixels[index[4] as usize],\n            pixels[index[5] as usize],\n            pixels[index[6] as usize],\n            pixels[index[7] as usize],\n        ]\n    }\n}\n\nimpl<'a> SubPixmapMut<'a> {\n    #[inline(always)]\n    pub(crate) fn offset(&self, dx: usize, dy: usize) -> usize {\n        self.real_width * dy + dx\n    }\n\n    #[inline(always)]\n    pub(crate) fn slice_at_xy(&mut self, dx: usize, dy: usize) -> &mut [PremultipliedColorU8] {\n        let offset = self.offset(dx, dy);\n        &mut self.pixels_mut()[offset..]\n    }\n\n    #[inline(always)]\n    pub(crate) fn slice_mask_at_xy(&mut self, dx: usize, dy: usize) -> &mut [u8] {\n        let offset = self.offset(dx, dy);\n        &mut self.data[offset..]\n    }\n\n    #[inline(always)]\n    pub(crate) fn slice4_at_xy(\n        &mut self,\n        dx: usize,\n        dy: usize,\n    ) -> &mut [PremultipliedColorU8; highp::STAGE_WIDTH] {\n        arrayref::array_mut_ref!(self.pixels_mut(), self.offset(dx, dy), highp::STAGE_WIDTH)\n    }\n\n    #[inline(always)]\n    pub(crate) fn slice16_at_xy(\n        &mut self,\n        dx: usize,\n        dy: usize,\n    ) -> &mut [PremultipliedColorU8; lowp::STAGE_WIDTH] {\n        arrayref::array_mut_ref!(self.pixels_mut(), self.offset(dx, dy), lowp::STAGE_WIDTH)\n    }\n\n    #[inline(always)]\n    pub(crate) fn slice16_mask_at_xy(\n        &mut self,\n        dx: usize,\n        dy: usize,\n    ) -> &mut [u8; lowp::STAGE_WIDTH] {\n        arrayref::array_mut_ref!(self.data, self.offset(dx, dy), lowp::STAGE_WIDTH)\n    }\n}\n\n#[derive(Default, Debug)]\npub struct AAMaskCtx {\n    pub pixels: [u8; 2],\n    pub stride: u32,  // can be zero\n    pub shift: usize, // mask offset/position in pixmap coordinates\n}\n\nimpl AAMaskCtx {\n    #[inline(always)]\n    pub fn copy_at_xy(&self, dx: usize, dy: usize, tail: usize) -> [u8; 2] {\n        let offset = (self.stride as usize * dy + dx) - self.shift;\n        // We have only 3 variants, so unroll them.\n        match (offset, tail) {\n            (0, 1) => [self.pixels[0], 0],\n            (0, 2) => [self.pixels[0], self.pixels[1]],\n            (1, 1) => [self.pixels[1], 0],\n            _ => [0, 0], // unreachable\n        }\n    }\n}\n\n#[derive(Copy, Clone, Debug)]\npub struct MaskCtx<'a> {\n    pub data: &'a [u8],\n    pub real_width: u32,\n}\n\nimpl Default for MaskCtx<'_> {\n    fn default() -> Self {\n        MaskCtx {\n            data: &[],\n            real_width: 0,\n        }\n    }\n}\n\nimpl MaskCtx<'_> {\n    #[inline(always)]\n    fn offset(&self, dx: usize, dy: usize) -> usize {\n        self.real_width as usize * dy + dx\n    }\n}\n\n#[derive(Default)]\npub struct Context {\n    pub current_coverage: f32,\n    pub sampler: SamplerCtx,\n    pub uniform_color: UniformColorCtx,\n    pub evenly_spaced_2_stop_gradient: EvenlySpaced2StopGradientCtx,\n    pub gradient: GradientCtx,\n    pub two_point_conical_gradient: TwoPointConicalGradientCtx,\n    pub limit_x: TileCtx,\n    pub limit_y: TileCtx,\n    pub transform: Transform,\n}\n\n#[derive(Copy, Clone, Default, Debug)]\npub struct SamplerCtx {\n    pub spread_mode: SpreadMode,\n    pub inv_width: f32,\n    pub inv_height: f32,\n}\n\n#[derive(Copy, Clone, Default, Debug)]\npub struct UniformColorCtx {\n    pub r: f32,\n    pub g: f32,\n    pub b: f32,\n    pub a: f32,\n    pub rgba: [u16; 4], // [0,255] in a 16-bit lane.\n}\n\n// A gradient color is an unpremultiplied RGBA not in a 0..1 range.\n// It basically can have any float value.\n#[derive(Copy, Clone, Default, Debug)]\npub struct GradientColor {\n    pub r: f32,\n    pub g: f32,\n    pub b: f32,\n    pub a: f32,\n}\n\nimpl GradientColor {\n    pub fn new(r: f32, g: f32, b: f32, a: f32) -> Self {\n        GradientColor { r, g, b, a }\n    }\n}\n\nimpl From<Color> for GradientColor {\n    fn from(c: Color) -> Self {\n        GradientColor {\n            r: c.red(),\n            g: c.green(),\n            b: c.blue(),\n            a: c.alpha(),\n        }\n    }\n}\n\n#[derive(Copy, Clone, Default, Debug)]\npub struct EvenlySpaced2StopGradientCtx {\n    pub factor: GradientColor,\n    pub bias: GradientColor,\n}\n\n#[derive(Clone, Default, Debug)]\npub struct GradientCtx {\n    /// This value stores the actual colors count.\n    /// `factors` and `biases` must store at least 16 values,\n    /// since this is the length of a lowp pipeline stage.\n    /// So any any value past `len` is just zeros.\n    pub len: usize,\n    pub factors: Vec<GradientColor>,\n    pub biases: Vec<GradientColor>,\n    pub t_values: Vec<NormalizedF32>,\n}\n\nimpl GradientCtx {\n    pub fn push_const_color(&mut self, color: GradientColor) {\n        self.factors.push(GradientColor::new(0.0, 0.0, 0.0, 0.0));\n        self.biases.push(color);\n    }\n}\n\n#[derive(Copy, Clone, Default, Debug)]\npub struct TwoPointConicalGradientCtx {\n    // This context is used only in highp, where we use Tx4.\n    pub mask: u32x8,\n    pub p0: f32,\n}\n\n#[derive(Copy, Clone, Default, Debug)]\npub struct TileCtx {\n    pub scale: f32,\n    pub inv_scale: f32, // cache of 1/scale\n}\n\npub struct RasterPipelineBuilder {\n    stages: ArrayVec<Stage, MAX_STAGES>,\n    force_hq_pipeline: bool,\n    pub ctx: Context,\n}\n\nimpl RasterPipelineBuilder {\n    pub fn new() -> Self {\n        RasterPipelineBuilder {\n            stages: ArrayVec::new(),\n            force_hq_pipeline: false,\n            ctx: Context::default(),\n        }\n    }\n\n    pub fn set_force_hq_pipeline(&mut self, hq: bool) {\n        self.force_hq_pipeline = hq;\n    }\n\n    pub fn push(&mut self, stage: Stage) {\n        self.stages.push(stage);\n    }\n\n    pub fn push_transform(&mut self, ts: Transform) {\n        if ts.is_finite() && !ts.is_identity() {\n            self.stages.push(Stage::Transform);\n            self.ctx.transform = ts;\n        }\n    }\n\n    pub fn push_uniform_color(&mut self, c: PremultipliedColor) {\n        let r = c.red();\n        let g = c.green();\n        let b = c.blue();\n        let a = c.alpha();\n        let rgba = [\n            (r * 255.0 + 0.5) as u16,\n            (g * 255.0 + 0.5) as u16,\n            (b * 255.0 + 0.5) as u16,\n            (a * 255.0 + 0.5) as u16,\n        ];\n\n        let ctx = UniformColorCtx { r, g, b, a, rgba };\n\n        self.stages.push(Stage::UniformColor);\n        self.ctx.uniform_color = ctx;\n    }\n\n    pub fn compile(self) -> RasterPipeline {\n        if self.stages.is_empty() {\n            return RasterPipeline {\n                kind: RasterPipelineKind::High {\n                    functions: ArrayVec::new(),\n                    tail_functions: ArrayVec::new(),\n                },\n                ctx: Context::default(),\n            };\n        }\n\n        let is_lowp_compatible = self\n            .stages\n            .iter()\n            .all(|stage| !lowp::fn_ptr_eq(lowp::STAGES[*stage as usize], lowp::null_fn));\n\n        if self.force_hq_pipeline || !is_lowp_compatible {\n            let mut functions: ArrayVec<_, MAX_STAGES> = self\n                .stages\n                .iter()\n                .map(|stage| highp::STAGES[*stage as usize] as highp::StageFn)\n                .collect();\n            functions.push(highp::just_return as highp::StageFn);\n\n            // I wasn't able to reproduce Skia's load_8888_/store_8888_ performance.\n            // Skia uses fallthrough switch, which is probably the reason.\n            // In Rust, any branching in load/store code drastically affects the performance.\n            // So instead, we're using two \"programs\": one for \"full stages\" and one for \"tail stages\".\n            // While the only difference is the load/store methods.\n            let mut tail_functions = functions.clone();\n            for fun in &mut tail_functions {\n                if highp::fn_ptr(*fun) == highp::fn_ptr(highp::load_dst) {\n                    *fun = highp::load_dst_tail as highp::StageFn;\n                } else if highp::fn_ptr(*fun) == highp::fn_ptr(highp::store) {\n                    *fun = highp::store_tail as highp::StageFn;\n                } else if highp::fn_ptr(*fun) == highp::fn_ptr(highp::load_dst_u8) {\n                    *fun = highp::load_dst_u8_tail as highp::StageFn;\n                } else if highp::fn_ptr(*fun) == highp::fn_ptr(highp::store_u8) {\n                    *fun = highp::store_u8_tail as highp::StageFn;\n                } else if highp::fn_ptr(*fun) == highp::fn_ptr(highp::source_over_rgba) {\n                    // SourceOverRgba calls load/store manually, without the pipeline,\n                    // therefore we have to switch it too.\n                    *fun = highp::source_over_rgba_tail as highp::StageFn;\n                }\n            }\n\n            RasterPipeline {\n                kind: RasterPipelineKind::High {\n                    functions,\n                    tail_functions,\n                },\n                ctx: self.ctx,\n            }\n        } else {\n            let mut functions: ArrayVec<_, MAX_STAGES> = self\n                .stages\n                .iter()\n                .map(|stage| lowp::STAGES[*stage as usize] as lowp::StageFn)\n                .collect();\n            functions.push(lowp::just_return as lowp::StageFn);\n\n            // See above.\n            let mut tail_functions = functions.clone();\n            for fun in &mut tail_functions {\n                if lowp::fn_ptr(*fun) == lowp::fn_ptr(lowp::load_dst) {\n                    *fun = lowp::load_dst_tail as lowp::StageFn;\n                } else if lowp::fn_ptr(*fun) == lowp::fn_ptr(lowp::store) {\n                    *fun = lowp::store_tail as lowp::StageFn;\n                } else if lowp::fn_ptr(*fun) == lowp::fn_ptr(lowp::load_dst_u8) {\n                    *fun = lowp::load_dst_u8_tail as lowp::StageFn;\n                } else if lowp::fn_ptr(*fun) == lowp::fn_ptr(lowp::store_u8) {\n                    *fun = lowp::store_u8_tail as lowp::StageFn;\n                } else if lowp::fn_ptr(*fun) == lowp::fn_ptr(lowp::source_over_rgba) {\n                    // SourceOverRgba calls load/store manually, without the pipeline,\n                    // therefore we have to switch it too.\n                    *fun = lowp::source_over_rgba_tail as lowp::StageFn;\n                }\n            }\n\n            RasterPipeline {\n                kind: RasterPipelineKind::Low {\n                    functions,\n                    tail_functions,\n                },\n                ctx: self.ctx,\n            }\n        }\n    }\n}\n\npub enum RasterPipelineKind {\n    High {\n        functions: ArrayVec<highp::StageFn, MAX_STAGES>,\n        tail_functions: ArrayVec<highp::StageFn, MAX_STAGES>,\n    },\n    Low {\n        functions: ArrayVec<lowp::StageFn, MAX_STAGES>,\n        tail_functions: ArrayVec<lowp::StageFn, MAX_STAGES>,\n    },\n}\n\npub struct RasterPipeline {\n    kind: RasterPipelineKind,\n    pub ctx: Context,\n}\n\nimpl RasterPipeline {\n    pub fn run(\n        &mut self,\n        rect: &ScreenIntRect,\n        aa_mask_ctx: AAMaskCtx,\n        mask_ctx: MaskCtx,\n        pixmap_src: PixmapRef,\n        pixmap_dst: &mut SubPixmapMut,\n    ) {\n        match self.kind {\n            RasterPipelineKind::High {\n                ref functions,\n                ref tail_functions,\n            } => {\n                highp::start(\n                    functions.as_slice(),\n                    tail_functions.as_slice(),\n                    rect,\n                    aa_mask_ctx,\n                    mask_ctx,\n                    &mut self.ctx,\n                    pixmap_src,\n                    pixmap_dst,\n                );\n            }\n            RasterPipelineKind::Low {\n                ref functions,\n                ref tail_functions,\n            } => {\n                lowp::start(\n                    functions.as_slice(),\n                    tail_functions.as_slice(),\n                    rect,\n                    aa_mask_ctx,\n                    mask_ctx,\n                    &mut self.ctx,\n                    // lowp doesn't support pattern, so no `pixmap_src` for it.\n                    pixmap_dst,\n                );\n            }\n        }\n    }\n}\n\n#[rustfmt::skip]\n#[cfg(test)]\nmod blend_tests {\n    // Test blending modes.\n    //\n    // Skia has two kinds of a raster pipeline: high and low precision.\n    // \"High\" uses f32 and \"low\" uses u16.\n    // And for basic operations we don't need f32 and u16 simply faster.\n    // But those modes are not identical. They can produce slightly different results\n    // due rounding.\n\n    use super::*;\n    use crate::{BlendMode, Color, Pixmap, PremultipliedColorU8};\n    use crate::geom::IntSizeExt;\n\n    macro_rules! test_blend {\n        ($name:ident, $mode:expr, $is_highp:expr, $r:expr, $g:expr, $b:expr, $a:expr) => {\n            #[test]\n            fn $name() {\n                let mut pixmap = Pixmap::new(1, 1).unwrap();\n                pixmap.fill(Color::from_rgba8(50, 127, 150, 200));\n\n                let pixmap_src = PixmapRef::from_bytes(&[0, 0, 0, 0], 1, 1).unwrap();\n\n                let mut p = RasterPipelineBuilder::new();\n                p.set_force_hq_pipeline($is_highp);\n                p.push_uniform_color(Color::from_rgba8(220, 140, 75, 180).premultiply());\n                p.push(Stage::LoadDestination);\n                p.push($mode.to_stage().unwrap());\n                p.push(Stage::Store);\n                let mut p = p.compile();\n                let rect = pixmap.size().to_screen_int_rect(0, 0);\n                p.run(&rect, AAMaskCtx::default(), MaskCtx::default(), pixmap_src,\n                      &mut pixmap.as_mut().as_subpixmap());\n\n                assert_eq!(\n                    pixmap.as_ref().pixel(0, 0).unwrap(),\n                    PremultipliedColorU8::from_rgba($r, $g, $b, $a).unwrap()\n                );\n            }\n        };\n    }\n\n    macro_rules! test_blend_lowp {\n        ($name:ident, $mode:expr, $r:expr, $g:expr, $b:expr, $a:expr) => (\n            test_blend!{$name, $mode, false, $r, $g, $b, $a}\n        )\n    }\n\n    macro_rules! test_blend_highp {\n        ($name:ident, $mode:expr, $r:expr, $g:expr, $b:expr, $a:expr) => (\n            test_blend!{$name, $mode, true, $r, $g, $b, $a}\n        )\n    }\n\n    test_blend_lowp!(clear_lowp,              BlendMode::Clear,                 0,   0,   0,   0);\n    // Source is a no-op\n    test_blend_lowp!(destination_lowp,        BlendMode::Destination,          39, 100, 118, 200);\n    test_blend_lowp!(source_over_lowp,        BlendMode::SourceOver,          167, 129,  88, 239);\n    test_blend_lowp!(destination_over_lowp,   BlendMode::DestinationOver,      73, 122, 130, 239);\n    test_blend_lowp!(source_in_lowp,          BlendMode::SourceIn,            122,  78,  42, 141);\n    test_blend_lowp!(destination_in_lowp,     BlendMode::DestinationIn,        28,  71,  83, 141);\n    test_blend_lowp!(source_out_lowp,         BlendMode::SourceOut,            34,  22,  12,  39);\n    test_blend_lowp!(destination_out_lowp,    BlendMode::DestinationOut,       12,  30,  35,  59);\n    test_blend_lowp!(source_atop_lowp,        BlendMode::SourceAtop,          133, 107,  76, 200);\n    test_blend_lowp!(destination_atop_lowp,   BlendMode::DestinationAtop,      61,  92,  95, 180);\n    test_blend_lowp!(xor_lowp,                BlendMode::Xor,                  45,  51,  46,  98);\n    test_blend_lowp!(plus_lowp,               BlendMode::Plus,                194, 199, 171, 255);\n    test_blend_lowp!(modulate_lowp,           BlendMode::Modulate,             24,  39,  25, 141);\n    test_blend_lowp!(screen_lowp,             BlendMode::Screen,              170, 160, 146, 239);\n    test_blend_lowp!(overlay_lowp,            BlendMode::Overlay,              92, 128, 106, 239);\n    test_blend_lowp!(darken_lowp,             BlendMode::Darken,               72, 121,  88, 239);\n    test_blend_lowp!(lighten_lowp,            BlendMode::Lighten,             166, 128, 129, 239);\n    // ColorDodge in not available for lowp.\n    // ColorBurn in not available for lowp.\n    test_blend_lowp!(hard_light_lowp,         BlendMode::HardLight,           154, 128,  95, 239);\n    // SoftLight in not available for lowp.\n    test_blend_lowp!(difference_lowp,         BlendMode::Difference,          138,  57,  87, 239);\n    test_blend_lowp!(exclusion_lowp,          BlendMode::Exclusion,           146, 121, 121, 239);\n    test_blend_lowp!(multiply_lowp,           BlendMode::Multiply,             69,  90,  71, 238);\n    // Hue in not available for lowp.\n    // Saturation in not available for lowp.\n    // Color in not available for lowp.\n    // Luminosity in not available for lowp.\n\n    test_blend_highp!(clear_highp,            BlendMode::Clear,                 0,   0,   0,   0);\n    // Source is a no-op\n    test_blend_highp!(destination_highp,      BlendMode::Destination,          39, 100, 118, 200);\n    test_blend_highp!(source_over_highp,      BlendMode::SourceOver,          167, 128,  88, 239);\n    test_blend_highp!(destination_over_highp, BlendMode::DestinationOver,      72, 121, 129, 239);\n    test_blend_highp!(source_in_highp,        BlendMode::SourceIn,            122,  78,  42, 141);\n    test_blend_highp!(destination_in_highp,   BlendMode::DestinationIn,        28,  71,  83, 141);\n    test_blend_highp!(source_out_highp,       BlendMode::SourceOut,            33,  21,  11,  39);\n    test_blend_highp!(destination_out_highp,  BlendMode::DestinationOut,       11,  29,  35,  59);\n    test_blend_highp!(source_atop_highp,      BlendMode::SourceAtop,          133, 107,  76, 200);\n    test_blend_highp!(destination_atop_highp, BlendMode::DestinationAtop,      61,  92,  95, 180);\n    test_blend_highp!(xor_highp,              BlendMode::Xor,                  45,  51,  46,  98);\n    test_blend_highp!(plus_highp,             BlendMode::Plus,                194, 199, 171, 255);\n    test_blend_highp!(modulate_highp,         BlendMode::Modulate,             24,  39,  24, 141);\n    test_blend_highp!(screen_highp,           BlendMode::Screen,              171, 160, 146, 239);\n    test_blend_highp!(overlay_highp,          BlendMode::Overlay,              92, 128, 106, 239);\n    test_blend_highp!(darken_highp,           BlendMode::Darken,               72, 121,  88, 239);\n    test_blend_highp!(lighten_highp,          BlendMode::Lighten,             167, 128, 129, 239);\n    test_blend_highp!(color_dodge_highp,      BlendMode::ColorDodge,          186, 192, 164, 239);\n    test_blend_highp!(color_burn_highp,       BlendMode::ColorBurn,            54,  63,  46, 239);\n    test_blend_highp!(hard_light_highp,       BlendMode::HardLight,           155, 128,  95, 239);\n    test_blend_highp!(soft_light_highp,       BlendMode::SoftLight,            98, 124, 115, 239);\n    test_blend_highp!(difference_highp,       BlendMode::Difference,          139,  58,  88, 239);\n    test_blend_highp!(exclusion_highp,        BlendMode::Exclusion,           147, 121, 122, 239);\n    test_blend_highp!(multiply_highp,         BlendMode::Multiply,             69,  89,  71, 239);\n    test_blend_highp!(hue_highp,              BlendMode::Hue,                 128, 103,  74, 239);\n    test_blend_highp!(saturation_highp,       BlendMode::Saturation,           59, 126, 140, 239);\n    test_blend_highp!(color_highp,            BlendMode::Color,               139, 100,  60, 239);\n    test_blend_highp!(luminosity_highp,       BlendMode::Luminosity,          100, 149, 157, 239);\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/pixmap.rs",
      "sha256": "4918eda1ac2844e277252f2b3b4113cddb74f471c5e940bec863b9aac6975175",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse alloc::vec;\nuse alloc::vec::Vec;\n\nuse core::convert::TryFrom;\nuse core::num::NonZeroUsize;\n\nuse tiny_skia_path::IntSize;\n\nuse crate::{Color, IntRect};\n\nuse crate::color::PremultipliedColorU8;\nuse crate::geom::{IntSizeExt, ScreenIntRect};\n\n#[cfg(feature = \"png-format\")]\nuse crate::color::{premultiply_u8, ALPHA_U8_OPAQUE};\n\n/// Number of bytes per pixel.\npub const BYTES_PER_PIXEL: usize = 4;\n\n/// A container that owns premultiplied RGBA pixels.\n///\n/// The data is not aligned, therefore width == stride.\n#[derive(Clone, PartialEq)]\npub struct Pixmap {\n    data: Vec<u8>,\n    size: IntSize,\n}\n\nimpl Pixmap {\n    /// Allocates a new pixmap.\n    ///\n    /// A pixmap is filled with transparent black by default, aka (0, 0, 0, 0).\n    ///\n    /// Zero size in an error.\n    ///\n    /// Pixmap's width is limited by i32::MAX/4.\n    pub fn new(width: u32, height: u32) -> Option<Self> {\n        let size = IntSize::from_wh(width, height)?;\n        let data_len = data_len_for_size(size)?;\n\n        // We cannot check that allocation was successful yet.\n        // We have to wait for https://github.com/rust-lang/rust/issues/48043\n\n        Some(Pixmap {\n            data: vec![0; data_len],\n            size,\n        })\n    }\n\n    /// Creates a new pixmap by taking ownership over an image buffer\n    /// (premultiplied RGBA pixels).\n    ///\n    /// The size needs to match the data provided.\n    ///\n    /// Pixmap's width is limited by i32::MAX/4.\n    pub fn from_vec(data: Vec<u8>, size: IntSize) -> Option<Self> {\n        let data_len = data_len_for_size(size)?;\n        if data.len() != data_len {\n            return None;\n        }\n\n        Some(Pixmap { data, size })\n    }\n\n    /// Decodes a PNG data into a `Pixmap`.\n    ///\n    /// Only 8-bit images are supported.\n    /// Index PNGs are not supported.\n    #[cfg(feature = \"png-format\")]\n    pub fn decode_png(data: &[u8]) -> Result<Self, png::DecodingError> {\n        fn make_custom_png_error(msg: &str) -> png::DecodingError {\n            std::io::Error::new(std::io::ErrorKind::Other, msg).into()\n        }\n\n        let mut decoder = png::Decoder::new(data);\n        decoder.set_transformations(png::Transformations::normalize_to_color8());\n        let mut reader = decoder.read_info()?;\n        let mut img_data = vec![0; reader.output_buffer_size()];\n        let info = reader.next_frame(&mut img_data)?;\n\n        if info.bit_depth != png::BitDepth::Eight {\n            return Err(make_custom_png_error(\"unsupported bit depth\"));\n        }\n\n        let size = IntSize::from_wh(info.width, info.height)\n            .ok_or_else(|| make_custom_png_error(\"invalid image size\"))?;\n        let data_len =\n            data_len_for_size(size).ok_or_else(|| make_custom_png_error(\"image is too big\"))?;\n\n        img_data = match info.color_type {\n            png::ColorType::Rgb => {\n                let mut rgba_data = Vec::with_capacity(data_len);\n                for rgb in img_data.chunks(3) {\n                    rgba_data.push(rgb[0]);\n                    rgba_data.push(rgb[1]);\n                    rgba_data.push(rgb[2]);\n                    rgba_data.push(ALPHA_U8_OPAQUE);\n                }\n\n                rgba_data\n            }\n            png::ColorType::Rgba => img_data,\n            png::ColorType::Grayscale => {\n                let mut rgba_data = Vec::with_capacity(data_len);\n                for gray in img_data {\n                    rgba_data.push(gray);\n                    rgba_data.push(gray);\n                    rgba_data.push(gray);\n                    rgba_data.push(ALPHA_U8_OPAQUE);\n                }\n\n                rgba_data\n            }\n            png::ColorType::GrayscaleAlpha => {\n                let mut rgba_data = Vec::with_capacity(data_len);\n                for slice in img_data.chunks(2) {\n                    let gray = slice[0];\n                    let alpha = slice[1];\n                    rgba_data.push(gray);\n                    rgba_data.push(gray);\n                    rgba_data.push(gray);\n                    rgba_data.push(alpha);\n                }\n\n                rgba_data\n            }\n            png::ColorType::Indexed => {\n                return Err(make_custom_png_error(\"indexed PNG is not supported\"));\n            }\n        };\n\n        // Premultiply alpha.\n        //\n        // We cannon use RasterPipeline here, which is faster,\n        // because it produces slightly different results.\n        // Seems like Skia does the same.\n        //\n        // Also, in our tests unsafe version (no bound checking)\n        // had roughly the same performance. So we keep the safe one.\n        for pixel in img_data.as_mut_slice().chunks_mut(BYTES_PER_PIXEL) {\n            let a = pixel[3];\n            pixel[0] = premultiply_u8(pixel[0], a);\n            pixel[1] = premultiply_u8(pixel[1], a);\n            pixel[2] = premultiply_u8(pixel[2], a);\n        }\n\n        Pixmap::from_vec(img_data, size)\n            .ok_or_else(|| make_custom_png_error(\"failed to create a pixmap\"))\n    }\n\n    /// Loads a PNG file into a `Pixmap`.\n    ///\n    /// Only 8-bit images are supported.\n    /// Index PNGs are not supported.\n    #[cfg(feature = \"png-format\")]\n    pub fn load_png<P: AsRef<std::path::Path>>(path: P) -> Result<Self, png::DecodingError> {\n        // `png::Decoder` is generic over input, which means that it will instance\n        // two copies: one for `&[]` and one for `File`. Which will simply bloat the code.\n        // Therefore we're using only one type for input.\n        let data = std::fs::read(path)?;\n        Self::decode_png(&data)\n    }\n\n    /// Encodes pixmap into a PNG data.\n    #[cfg(feature = \"png-format\")]\n    pub fn encode_png(&self) -> Result<Vec<u8>, png::EncodingError> {\n        self.as_ref().encode_png()\n    }\n\n    /// Saves pixmap as a PNG file.\n    #[cfg(feature = \"png-format\")]\n    pub fn save_png<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), png::EncodingError> {\n        self.as_ref().save_png(path)\n    }\n\n    /// Returns a container that references Pixmap's data.\n    pub fn as_ref(&self) -> PixmapRef {\n        PixmapRef {\n            data: &self.data,\n            size: self.size,\n        }\n    }\n\n    /// Returns a container that references Pixmap's data.\n    pub fn as_mut(&mut self) -> PixmapMut {\n        PixmapMut {\n            data: &mut self.data,\n            size: self.size,\n        }\n    }\n\n    /// Returns pixmap's width.\n    #[inline]\n    pub fn width(&self) -> u32 {\n        self.size.width()\n    }\n\n    /// Returns pixmap's height.\n    #[inline]\n    pub fn height(&self) -> u32 {\n        self.size.height()\n    }\n\n    /// Returns pixmap's size.\n    #[allow(dead_code)]\n    pub(crate) fn size(&self) -> IntSize {\n        self.size\n    }\n\n    /// Fills the entire pixmap with a specified color.\n    pub fn fill(&mut self, color: Color) {\n        let c = color.premultiply().to_color_u8();\n        for p in self.as_mut().pixels_mut() {\n            *p = c;\n        }\n    }\n\n    /// Returns the internal data.\n    ///\n    /// Byteorder: RGBA\n    pub fn data(&self) -> &[u8] {\n        self.data.as_slice()\n    }\n\n    /// Returns the mutable internal data.\n    ///\n    /// Byteorder: RGBA\n    pub fn data_mut(&mut self) -> &mut [u8] {\n        self.data.as_mut_slice()\n    }\n\n    /// Returns a pixel color.\n    ///\n    /// Returns `None` when position is out of bounds.\n    pub fn pixel(&self, x: u32, y: u32) -> Option<PremultipliedColorU8> {\n        let idx = self.width().checked_mul(y)?.checked_add(x)?;\n        self.pixels().get(idx as usize).cloned()\n    }\n\n    /// Returns a mutable slice of pixels.\n    pub fn pixels_mut(&mut self) -> &mut [PremultipliedColorU8] {\n        bytemuck::cast_slice_mut(self.data_mut())\n    }\n\n    /// Returns a slice of pixels.\n    pub fn pixels(&self) -> &[PremultipliedColorU8] {\n        bytemuck::cast_slice(self.data())\n    }\n\n    /// Consumes the internal data.\n    ///\n    /// Byteorder: RGBA\n    pub fn take(self) -> Vec<u8> {\n        self.data\n    }\n\n    /// Returns a copy of the pixmap that intersects the `rect`.\n    ///\n    /// Returns `None` when `Pixmap`'s rect doesn't contain `rect`.\n    pub fn clone_rect(&self, rect: IntRect) -> Option<Pixmap> {\n        self.as_ref().clone_rect(rect)\n    }\n}\n\nimpl core::fmt::Debug for Pixmap {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        f.debug_struct(\"Pixmap\")\n            .field(\"data\", &\"...\")\n            .field(\"width\", &self.size.width())\n            .field(\"height\", &self.size.height())\n            .finish()\n    }\n}\n\n/// A container that references premultiplied RGBA pixels.\n///\n/// Can be created from `Pixmap` or from a user provided data.\n///\n/// The data is not aligned, therefore width == stride.\n#[derive(Clone, Copy, PartialEq)]\npub struct PixmapRef<'a> {\n    data: &'a [u8],\n    size: IntSize,\n}\n\nimpl<'a> PixmapRef<'a> {\n    /// Creates a new `PixmapRef` from bytes.\n    ///\n    /// The size must be at least `size.width() * size.height() * BYTES_PER_PIXEL`.\n    /// Zero size in an error. Width is limited by i32::MAX/4.\n    ///\n    /// The `data` is assumed to have premultiplied RGBA pixels (byteorder: RGBA).\n    pub fn from_bytes(data: &'a [u8], width: u32, height: u32) -> Option<Self> {\n        let size = IntSize::from_wh(width, height)?;\n        let data_len = data_len_for_size(size)?;\n        if data.len() < data_len {\n            return None;\n        }\n\n        Some(PixmapRef { data, size })\n    }\n\n    /// Creates a new `Pixmap` from the current data.\n    ///\n    /// Clones the underlying data.\n    pub fn to_owned(&self) -> Pixmap {\n        Pixmap {\n            data: self.data.to_vec(),\n            size: self.size,\n        }\n    }\n\n    /// Returns pixmap's width.\n    #[inline]\n    pub fn width(&self) -> u32 {\n        self.size.width()\n    }\n\n    /// Returns pixmap's height.\n    #[inline]\n    pub fn height(&self) -> u32 {\n        self.size.height()\n    }\n\n    /// Returns pixmap's size.\n    pub(crate) fn size(&self) -> IntSize {\n        self.size\n    }\n\n    /// Returns pixmap's rect.\n    pub(crate) fn rect(&self) -> ScreenIntRect {\n        self.size.to_screen_int_rect(0, 0)\n    }\n\n    /// Returns the internal data.\n    ///\n    /// Byteorder: RGBA\n    pub fn data(&self) -> &'a [u8] {\n        self.data\n    }\n\n    /// Returns a pixel color.\n    ///\n    /// Returns `None` when position is out of bounds.\n    pub fn pixel(&self, x: u32, y: u32) -> Option<PremultipliedColorU8> {\n        let idx = self.width().checked_mul(y)?.checked_add(x)?;\n        self.pixels().get(idx as usize).cloned()\n    }\n\n    /// Returns a slice of pixels.\n    pub fn pixels(&self) -> &'a [PremultipliedColorU8] {\n        bytemuck::cast_slice(self.data())\n    }\n\n    // TODO: add rows() iterator\n\n    /// Returns a copy of the pixmap that intersects the `rect`.\n    ///\n    /// Returns `None` when `Pixmap`'s rect doesn't contain `rect`.\n    pub fn clone_rect(&self, rect: IntRect) -> Option<Pixmap> {\n        // TODO: to ScreenIntRect?\n\n        let rect = self.rect().to_int_rect().intersect(&rect)?;\n        let mut new = Pixmap::new(rect.width(), rect.height())?;\n        {\n            let old_pixels = self.pixels();\n            let mut new_mut = new.as_mut();\n            let new_pixels = new_mut.pixels_mut();\n\n            // TODO: optimize\n            for y in 0..rect.height() {\n                for x in 0..rect.width() {\n                    let old_idx = (y + rect.y() as u32) * self.width() + (x + rect.x() as u32);\n                    let new_idx = y * rect.width() + x;\n                    new_pixels[new_idx as usize] = old_pixels[old_idx as usize];\n                }\n            }\n        }\n\n        Some(new)\n    }\n\n    /// Encodes pixmap into a PNG data.\n    #[cfg(feature = \"png-format\")]\n    pub fn encode_png(&self) -> Result<Vec<u8>, png::EncodingError> {\n        // Skia uses skcms here, which is somewhat similar to RasterPipeline.\n\n        // Sadly, we have to copy the pixmap here, because of demultiplication.\n        // Not sure how to avoid this.\n        // TODO: remove allocation\n        let mut tmp_pixmap = self.to_owned();\n\n        // Demultiply alpha.\n        //\n        // RasterPipeline is 15% faster here, but produces slightly different results\n        // due to rounding. So we stick with this method for now.\n        for pixel in tmp_pixmap.pixels_mut() {\n            let c = pixel.demultiply();\n            *pixel =\n                PremultipliedColorU8::from_rgba_unchecked(c.red(), c.green(), c.blue(), c.alpha());\n        }\n\n        let mut data = Vec::new();\n        {\n            let mut encoder = png::Encoder::new(&mut data, self.width(), self.height());\n            encoder.set_color(png::ColorType::Rgba);\n            encoder.set_depth(png::BitDepth::Eight);\n            let mut writer = encoder.write_header()?;\n            writer.write_image_data(&tmp_pixmap.data)?;\n        }\n\n        Ok(data)\n    }\n\n    /// Saves pixmap as a PNG file.\n    #[cfg(feature = \"png-format\")]\n    pub fn save_png<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), png::EncodingError> {\n        let data = self.encode_png()?;\n        std::fs::write(path, data)?;\n        Ok(())\n    }\n}\n\nimpl core::fmt::Debug for PixmapRef<'_> {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        f.debug_struct(\"PixmapRef\")\n            .field(\"data\", &\"...\")\n            .field(\"width\", &self.size.width())\n            .field(\"height\", &self.size.height())\n            .finish()\n    }\n}\n\n/// A container that references mutable premultiplied RGBA pixels.\n///\n/// Can be created from `Pixmap` or from a user provided data.\n///\n/// The data is not aligned, therefore width == stride.\n#[derive(PartialEq)]\npub struct PixmapMut<'a> {\n    data: &'a mut [u8],\n    size: IntSize,\n}\n\nimpl<'a> PixmapMut<'a> {\n    /// Creates a new `PixmapMut` from bytes.\n    ///\n    /// The size must be at least `size.width() * size.height() * BYTES_PER_PIXEL`.\n    /// Zero size in an error. Width is limited by i32::MAX/4.\n    ///\n    /// The `data` is assumed to have premultiplied RGBA pixels (byteorder: RGBA).\n    pub fn from_bytes(data: &'a mut [u8], width: u32, height: u32) -> Option<Self> {\n        let size = IntSize::from_wh(width, height)?;\n        let data_len = data_len_for_size(size)?;\n        if data.len() < data_len {\n            return None;\n        }\n\n        Some(PixmapMut { data, size })\n    }\n\n    /// Creates a new `Pixmap` from the current data.\n    ///\n    /// Clones the underlying data.\n    pub fn to_owned(&self) -> Pixmap {\n        Pixmap {\n            data: self.data.to_vec(),\n            size: self.size,\n        }\n    }\n\n    /// Returns a container that references Pixmap's data.\n    pub fn as_ref(&self) -> PixmapRef {\n        PixmapRef {\n            data: self.data,\n            size: self.size,\n        }\n    }\n\n    /// Returns pixmap's width.\n    #[inline]\n    pub fn width(&self) -> u32 {\n        self.size.width()\n    }\n\n    /// Returns pixmap's height.\n    #[inline]\n    pub fn height(&self) -> u32 {\n        self.size.height()\n    }\n\n    /// Returns pixmap's size.\n    pub(crate) fn size(&self) -> IntSize {\n        self.size\n    }\n\n    /// Fills the entire pixmap with a specified color.\n    pub fn fill(&mut self, color: Color) {\n        let c = color.premultiply().to_color_u8();\n        for p in self.pixels_mut() {\n            *p = c;\n        }\n    }\n\n    /// Returns the mutable internal data.\n    ///\n    /// Byteorder: RGBA\n    pub fn data_mut(&mut self) -> &mut [u8] {\n        self.data\n    }\n\n    /// Returns a mutable slice of pixels.\n    pub fn pixels_mut(&mut self) -> &mut [PremultipliedColorU8] {\n        bytemuck::cast_slice_mut(self.data_mut())\n    }\n\n    /// Creates `SubPixmapMut` that contains the whole `PixmapMut`.\n    pub(crate) fn as_subpixmap(&mut self) -> SubPixmapMut {\n        SubPixmapMut {\n            size: self.size(),\n            real_width: self.width() as usize,\n            data: &mut self.data,\n        }\n    }\n\n    /// Returns a mutable reference to the pixmap region that intersects the `rect`.\n    ///\n    /// Returns `None` when `Pixmap`'s rect doesn't contain `rect`.\n    pub(crate) fn subpixmap(&mut self, rect: IntRect) -> Option<SubPixmapMut> {\n        let rect = self.size.to_int_rect(0, 0).intersect(&rect)?;\n        let row_bytes = self.width() as usize * BYTES_PER_PIXEL;\n        let offset = rect.top() as usize * row_bytes + rect.left() as usize * BYTES_PER_PIXEL;\n\n        Some(SubPixmapMut {\n            size: rect.size(),\n            real_width: self.width() as usize,\n            data: &mut self.data[offset..],\n        })\n    }\n}\n\nimpl core::fmt::Debug for PixmapMut<'_> {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        f.debug_struct(\"PixmapMut\")\n            .field(\"data\", &\"...\")\n            .field(\"width\", &self.size.width())\n            .field(\"height\", &self.size.height())\n            .finish()\n    }\n}\n\n/// A `PixmapMut` subregion.\n///\n/// Unlike `PixmapMut`, contains `real_width` which references the parent `PixmapMut` width.\n/// This way we can operate on a `PixmapMut` subregion without reallocations.\n/// Primarily required because of `DrawTiler`.\n///\n/// We cannot implement it in `PixmapMut` directly, because it will brake `fill`, `data_mut`\n/// `pixels_mut` and other similar methods.\n/// This is because `SubPixmapMut.data` references more \"data\" than it actually allowed to access.\n/// On the other hand, `PixmapMut.data` can access all it's data and it's stored linearly.\npub struct SubPixmapMut<'a> {\n    pub data: &'a mut [u8],\n    pub size: IntSize,\n    pub real_width: usize,\n}\n\nimpl<'a> SubPixmapMut<'a> {\n    /// Returns a mutable slice of pixels.\n    pub fn pixels_mut(&mut self) -> &mut [PremultipliedColorU8] {\n        bytemuck::cast_slice_mut(self.data)\n    }\n}\n\n/// Returns minimum bytes per row as usize.\n///\n/// Pixmap's maximum value for row bytes must fit in 31 bits.\nfn min_row_bytes(size: IntSize) -> Option<NonZeroUsize> {\n    let w = i32::try_from(size.width()).ok()?;\n    let w = w.checked_mul(BYTES_PER_PIXEL as i32)?;\n    NonZeroUsize::new(w as usize)\n}\n\n/// Returns storage size required by pixel array.\nfn compute_data_len(size: IntSize, row_bytes: usize) -> Option<usize> {\n    let h = size.height().checked_sub(1)?;\n    let h = (h as usize).checked_mul(row_bytes)?;\n\n    let w = (size.width() as usize).checked_mul(BYTES_PER_PIXEL)?;\n\n    h.checked_add(w)\n}\n\nfn data_len_for_size(size: IntSize) -> Option<usize> {\n    let row_bytes = min_row_bytes(size)?;\n    compute_data_len(size, row_bytes.get())\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/scan/hairline.rs",
      "sha256": "aa50d030fc207e198d0b106b9792dd9fc606bd6ccc11384327ce768d879ab5b1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse core::convert::TryInto;\n\nuse tiny_skia_path::{f32x2, PathVerb, SaturateCast, Scalar};\n\nuse crate::{IntRect, LineCap, Path, PathSegment, Point, Rect};\n\nuse crate::blitter::Blitter;\nuse crate::fixed_point::{fdot16, fdot6};\nuse crate::geom::ScreenIntRect;\nuse crate::line_clipper;\nuse crate::math::LENGTH_U32_ONE;\nuse crate::path_geometry;\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\nconst FLOAT_PI: f32 = 3.14159265;\n\npub type LineProc = fn(&[Point], Option<&ScreenIntRect>, &mut dyn Blitter);\n\nconst MAX_CUBIC_SUBDIVIDE_LEVEL: u8 = 9;\nconst MAX_QUAD_SUBDIVIDE_LEVEL: u8 = 5;\n\npub fn stroke_path(\n    path: &Path,\n    line_cap: LineCap,\n    clip: &ScreenIntRect,\n    blitter: &mut dyn Blitter,\n) {\n    super::hairline::stroke_path_impl(path, line_cap, clip, hair_line_rgn, blitter)\n}\n\nfn hair_line_rgn(points: &[Point], clip: Option<&ScreenIntRect>, blitter: &mut dyn Blitter) {\n    let max = 32767.0;\n    let fixed_bounds = Rect::from_ltrb(-max, -max, max, max).unwrap();\n\n    let clip_bounds = clip.map(|c| c.to_rect());\n\n    for i in 0..points.len() - 1 {\n        let mut pts = [Point::zero(); 2];\n\n        // We have to pre-clip the line to fit in a Fixed, so we just chop the line.\n        if !line_clipper::intersect(&[points[i], points[i + 1]], &fixed_bounds, &mut pts) {\n            continue;\n        }\n\n        if let Some(clip_bounds) = clip_bounds {\n            let tmp = pts.clone();\n            // Perform a clip in scalar space, so we catch huge values which might\n            // be missed after we convert to FDot6 (overflow).\n            if !line_clipper::intersect(&tmp, &clip_bounds, &mut pts) {\n                continue;\n            }\n        }\n\n        let mut x0 = fdot6::from_f32(pts[0].x);\n        let mut y0 = fdot6::from_f32(pts[0].y);\n        let mut x1 = fdot6::from_f32(pts[1].x);\n        let mut y1 = fdot6::from_f32(pts[1].y);\n\n        debug_assert!(fdot6::can_convert_to_fdot16(x0));\n        debug_assert!(fdot6::can_convert_to_fdot16(y0));\n        debug_assert!(fdot6::can_convert_to_fdot16(x1));\n        debug_assert!(fdot6::can_convert_to_fdot16(y1));\n\n        let dx = x1 - x0;\n        let dy = y1 - y0;\n\n        if dx.abs() > dy.abs() {\n            // mostly horizontal\n\n            if x0 > x1 {\n                // we want to go left-to-right\n                core::mem::swap(&mut x0, &mut x1);\n                core::mem::swap(&mut y0, &mut y1);\n            }\n\n            let mut ix0 = fdot6::round(x0);\n            let ix1 = fdot6::round(x1);\n            if ix0 == ix1 {\n                // too short to draw\n                continue;\n            }\n\n            let slope = fdot16::div(dy, dx);\n            #[allow(clippy::precedence)]\n            let mut start_y = fdot6::to_fdot16(y0) + (slope * ((32 - x0) & 63) >> 6);\n\n            // In some cases, probably due to precision/rounding issues,\n            // `start_y` can become equal to the image height,\n            // which will lead to panic, because we would be accessing pixels outside\n            // the current memory buffer.\n            // This is tiny-skia specific issue. Skia handles this part differently.\n            let max_y = if let Some(clip_bounds) = clip_bounds {\n                fdot16::from_f32(clip_bounds.bottom())\n            } else {\n                i32::MAX\n            };\n\n            debug_assert!(ix0 < ix1);\n            loop {\n                if ix0 >= 0 && start_y >= 0 && start_y < max_y {\n                    blitter.blit_h(ix0 as u32, (start_y >> 16) as u32, LENGTH_U32_ONE);\n                }\n\n                start_y += slope;\n                ix0 += 1;\n                if ix0 >= ix1 {\n                    break;\n                }\n            }\n        } else {\n            // mostly vertical\n\n            if y0 > y1 {\n                // we want to go top-to-bottom\n                core::mem::swap(&mut x0, &mut x1);\n                core::mem::swap(&mut y0, &mut y1);\n            }\n\n            let mut iy0 = fdot6::round(y0);\n            let iy1 = fdot6::round(y1);\n            if iy0 == iy1 {\n                // too short to draw\n                continue;\n            }\n\n            let slope = fdot16::div(dx, dy);\n            #[allow(clippy::precedence)]\n            let mut start_x = fdot6::to_fdot16(x0) + (slope * ((32 - y0) & 63) >> 6);\n\n            debug_assert!(iy0 < iy1);\n            loop {\n                if start_x >= 0 && iy0 >= 0 {\n                    blitter.blit_h((start_x >> 16) as u32, iy0 as u32, LENGTH_U32_ONE);\n                }\n\n                start_x += slope;\n                iy0 += 1;\n                if iy0 >= iy1 {\n                    break;\n                }\n            }\n        }\n    }\n}\n\npub fn stroke_path_impl(\n    path: &Path,\n    line_cap: LineCap,\n    clip: &ScreenIntRect,\n    line_proc: LineProc,\n    blitter: &mut dyn Blitter,\n) {\n    let mut inset_clip = None;\n    let mut outset_clip = None;\n\n    {\n        let cap_out = if line_cap == LineCap::Butt { 1.0 } else { 2.0 };\n        let ibounds = match path\n            .bounds()\n            .outset(cap_out, cap_out)\n            .and_then(|r| r.round_out())\n        {\n            Some(v) => v,\n            None => return,\n        };\n        if clip.to_int_rect().intersect(&ibounds).is_none() {\n            return;\n        }\n\n        if !clip.to_int_rect().contains(&ibounds) {\n            // We now cache two scalar rects, to use for culling per-segment (e.g. cubic).\n            // Since we're hairlining, the \"bounds\" of the control points isn't necessairly the\n            // limit of where a segment can draw (it might draw up to 1 pixel beyond in aa-hairs).\n            //\n            // Compute the pt-bounds per segment is easy, so we do that, and then inversely adjust\n            // the culling bounds so we can just do a straight compare per segment.\n            //\n            // insetClip is use for quick-accept (i.e. the segment is not clipped), so we inset\n            // it from the clip-bounds (since segment bounds can be off by 1).\n            //\n            // outsetClip is used for quick-reject (i.e. the segment is entirely outside), so we\n            // outset it from the clip-bounds.\n            match clip.to_int_rect().make_outset(1, 1) {\n                Some(v) => outset_clip = Some(v),\n                None => return,\n            }\n            match clip.to_int_rect().inset(1, 1) {\n                Some(v) => inset_clip = Some(v),\n                None => return,\n            }\n        }\n    }\n\n    let clip = Some(clip);\n    let mut prev_verb = PathVerb::Move;\n    let mut first_pt = Point::zero();\n    let mut last_pt = Point::zero();\n\n    let mut iter = path.segments();\n    while let Some(segment) = iter.next() {\n        let verb = iter.curr_verb();\n        let next_verb = iter.next_verb();\n        let last_pt2;\n        match segment {\n            PathSegment::MoveTo(p) => {\n                first_pt = p;\n                last_pt = p;\n                last_pt2 = p;\n            }\n            PathSegment::LineTo(p) => {\n                let mut points = [last_pt, p];\n                if line_cap != LineCap::Butt {\n                    extend_pts(line_cap, prev_verb, next_verb, &mut points);\n                }\n\n                line_proc(&points, clip, blitter);\n                last_pt = p;\n                last_pt2 = points[0];\n            }\n            PathSegment::QuadTo(p0, p1) => {\n                let mut points = [last_pt, p0, p1];\n                if line_cap != LineCap::Butt {\n                    extend_pts(line_cap, prev_verb, next_verb, &mut points);\n                }\n\n                hair_quad(\n                    &points,\n                    clip,\n                    inset_clip.as_ref(),\n                    outset_clip.as_ref(),\n                    compute_quad_level(&points),\n                    line_proc,\n                    blitter,\n                );\n\n                last_pt = p1;\n                last_pt2 = points[0];\n            }\n            PathSegment::CubicTo(p0, p1, p2) => {\n                let mut points = [last_pt, p0, p1, p2];\n                if line_cap != LineCap::Butt {\n                    extend_pts(line_cap, prev_verb, next_verb, &mut points);\n                }\n\n                hair_cubic(\n                    &points,\n                    clip,\n                    inset_clip.as_ref(),\n                    outset_clip.as_ref(),\n                    line_proc,\n                    blitter,\n                );\n\n                last_pt = p2;\n                last_pt2 = points[0];\n            }\n            PathSegment::Close => {\n                let mut points = [last_pt, first_pt];\n                if line_cap != LineCap::Butt && prev_verb == PathVerb::Move {\n                    // cap moveTo/close to match svg expectations for degenerate segments\n                    extend_pts(line_cap, prev_verb, next_verb, &mut points);\n                }\n                line_proc(&points, clip, blitter);\n                last_pt2 = points[0];\n            }\n        }\n\n        if line_cap != LineCap::Butt {\n            if prev_verb == PathVerb::Move\n                && matches!(verb, PathVerb::Line | PathVerb::Quad | PathVerb::Cubic)\n            {\n                first_pt = last_pt2; // the curve moved the initial point, so close to it instead\n            }\n\n            prev_verb = verb;\n        }\n    }\n}\n\n/// Extend the points in the direction of the starting or ending tangent by 1/2 unit to\n/// account for a round or square cap.\n///\n/// If there's no distance between the end point and\n/// the control point, use the next control point to create a tangent. If the curve\n/// is degenerate, move the cap out 1/2 unit horizontally.\nfn extend_pts(\n    line_cap: LineCap,\n    prev_verb: PathVerb,\n    next_verb: Option<PathVerb>,\n    points: &mut [Point],\n) {\n    debug_assert!(!points.is_empty()); // TODO: use non-zero slice\n    debug_assert!(line_cap != LineCap::Butt);\n\n    // The area of a circle is PI*R*R. For a unit circle, R=1/2, and the cap covers half of that.\n    let cap_outset = if line_cap == LineCap::Square {\n        0.5\n    } else {\n        FLOAT_PI / 8.0\n    };\n    if prev_verb == PathVerb::Move {\n        let first = points[0];\n        let mut offset = 0;\n        let mut controls = points.len() - 1;\n        let mut tangent;\n        loop {\n            offset += 1;\n            tangent = first - points[offset];\n\n            if !tangent.is_zero() {\n                break;\n            }\n\n            controls -= 1;\n            if controls == 0 {\n                break;\n            }\n        }\n\n        if tangent.is_zero() {\n            tangent = Point::from_xy(1.0, 0.0);\n            controls = points.len() - 1; // If all points are equal, move all but one.\n        } else {\n            tangent.normalize();\n        }\n\n        offset = 0;\n        loop {\n            // If the end point and control points are equal, loop to move them in tandem.\n            points[offset].x += tangent.x * cap_outset;\n            points[offset].y += tangent.y * cap_outset;\n\n            offset += 1;\n            controls += 1;\n            if controls >= points.len() {\n                break;\n            }\n        }\n    }\n\n    if matches!(\n        next_verb,\n        Some(PathVerb::Move) | Some(PathVerb::Close) | None\n    ) {\n        let last = points.last().unwrap().clone();\n        let mut offset = points.len() - 1;\n        let mut controls = points.len() - 1;\n        let mut tangent;\n        loop {\n            offset -= 1;\n            tangent = last - points[offset];\n\n            if !tangent.is_zero() {\n                break;\n            }\n\n            controls -= 1;\n            if controls == 0 {\n                break;\n            }\n        }\n\n        if tangent.is_zero() {\n            tangent = Point::from_xy(-1.0, 0.0);\n            controls = points.len() - 1;\n        } else {\n            tangent.normalize();\n        }\n\n        offset = points.len() - 1;\n        loop {\n            points[offset].x += tangent.x * cap_outset;\n            points[offset].y += tangent.y * cap_outset;\n\n            offset -= 1;\n            controls += 1;\n            if controls >= points.len() {\n                break;\n            }\n        }\n    }\n}\n\nfn hair_quad(\n    points: &[Point; 3],\n    mut clip: Option<&ScreenIntRect>,\n    inset_clip: Option<&IntRect>,\n    outset_clip: Option<&IntRect>,\n    level: u8,\n    line_proc: LineProc,\n    blitter: &mut dyn Blitter,\n) {\n    if let Some(inset_clip) = inset_clip {\n        debug_assert!(outset_clip.is_some());\n        let inset_clip = inset_clip.to_rect();\n        let outset_clip = match outset_clip {\n            Some(v) => v.to_rect(),\n            None => return,\n        };\n\n        let bounds = match compute_nocheck_quad_bounds(points) {\n            Some(v) => v,\n            None => return,\n        };\n        if !geometric_overlap(&outset_clip, &bounds) {\n            return; // nothing to do\n        } else if geometric_contains(&inset_clip, &bounds) {\n            clip = None;\n        }\n    }\n\n    hair_quad2(points, clip, level, line_proc, blitter);\n}\n\nfn compute_nocheck_quad_bounds(points: &[Point; 3]) -> Option<Rect> {\n    debug_assert!(points[0].is_finite());\n    debug_assert!(points[1].is_finite());\n    debug_assert!(points[2].is_finite());\n\n    let mut min = points[0].to_f32x2();\n    let mut max = min;\n    for i in 1..3 {\n        let pair = points[i].to_f32x2();\n        min = min.min(pair);\n        max = max.max(pair);\n    }\n\n    Rect::from_ltrb(min.x(), min.y(), max.x(), max.y())\n}\n\nfn geometric_overlap(a: &Rect, b: &Rect) -> bool {\n    a.left() < b.right() && b.left() < a.right() && a.top() < b.bottom() && b.top() < a.bottom()\n}\n\nfn geometric_contains(outer: &Rect, inner: &Rect) -> bool {\n    inner.right() <= outer.right()\n        && inner.left() >= outer.left()\n        && inner.bottom() <= outer.bottom()\n        && inner.top() >= outer.top()\n}\n\nfn hair_quad2(\n    points: &[Point; 3],\n    clip: Option<&ScreenIntRect>,\n    level: u8,\n    line_proc: LineProc,\n    blitter: &mut dyn Blitter,\n) {\n    debug_assert!(level <= MAX_QUAD_SUBDIVIDE_LEVEL); // TODO: to type\n\n    let coeff = path_geometry::QuadCoeff::from_points(points);\n\n    const MAX_POINTS: usize = (1 << MAX_QUAD_SUBDIVIDE_LEVEL) + 1;\n    let lines = 1 << level;\n    debug_assert!(lines < MAX_POINTS);\n\n    let mut tmp = [Point::zero(); MAX_POINTS];\n    tmp[0] = points[0];\n\n    let mut t = f32x2::default();\n    let dt = f32x2::splat(1.0 / lines as f32);\n    for i in 1..lines {\n        t = t + dt;\n        let v = (coeff.a * t + coeff.b) * t + coeff.c;\n        tmp[i] = Point::from_xy(v.x(), v.y());\n    }\n\n    tmp[lines] = points[2];\n    line_proc(&tmp[0..lines + 1], clip, blitter);\n}\n\nfn compute_quad_level(points: &[Point; 3]) -> u8 {\n    let d = compute_int_quad_dist(points);\n    // Quadratics approach the line connecting their start and end points\n    // 4x closer with each subdivision, so we compute the number of\n    // subdivisions to be the minimum need to get that distance to be less\n    // than a pixel.\n    let mut level = (33 - d.leading_zeros()) >> 1;\n    // sanity check on level (from the previous version)\n    if level > MAX_QUAD_SUBDIVIDE_LEVEL as u32 {\n        level = MAX_QUAD_SUBDIVIDE_LEVEL as u32;\n    }\n\n    level as u8\n}\n\nfn compute_int_quad_dist(points: &[Point; 3]) -> u32 {\n    // compute the vector between the control point ([1]) and the middle of the\n    // line connecting the start and end ([0] and [2])\n    let dx = ((points[0].x + points[2].x).half() - points[1].x).abs();\n    let dy = ((points[0].y + points[2].y).half() - points[1].y).abs();\n\n    // convert to whole pixel values (use ceiling to be conservative).\n    // assign to unsigned so we can safely add 1/2 of the smaller and still fit in\n    // u32, since T::saturate_from() returns 31 bits at most.\n    let idx = i32::saturate_from(dx.ceil()) as u32;\n    let idy = i32::saturate_from(dy.ceil()) as u32;\n\n    // use the cheap approx for distance\n    if idx > idy {\n        idx + (idy >> 1)\n    } else {\n        idy + (idx >> 1)\n    }\n}\n\nfn hair_cubic(\n    points: &[Point; 4],\n    mut clip: Option<&ScreenIntRect>,\n    inset_clip: Option<&IntRect>,\n    outset_clip: Option<&IntRect>,\n    line_proc: LineProc,\n    blitter: &mut dyn Blitter,\n) {\n    if let Some(inset_clip) = inset_clip {\n        debug_assert!(outset_clip.is_some());\n        let inset_clip = inset_clip.to_rect();\n        let outset_clip = match outset_clip {\n            Some(v) => v.to_rect(),\n            None => return,\n        };\n\n        let bounds = match compute_nocheck_cubic_bounds(points) {\n            Some(v) => v,\n            None => return,\n        };\n        if !geometric_overlap(&outset_clip, &bounds) {\n            return; // noting to do\n        } else if geometric_contains(&inset_clip, &bounds) {\n            clip = None;\n        }\n    }\n\n    if quick_cubic_niceness_check(points) {\n        hair_cubic2(points, clip, line_proc, blitter);\n    } else {\n        let mut tmp = [Point::zero(); 13];\n        let mut t_values = path_geometry::new_t_values();\n\n        let count = path_geometry::chop_cubic_at_max_curvature(points, &mut t_values, &mut tmp);\n        for i in 0..count {\n            let offset = i * 3;\n            let new_points: [Point; 4] = tmp[offset..offset + 4].try_into().unwrap();\n            hair_cubic2(&new_points, clip, line_proc, blitter);\n        }\n    }\n}\n\nfn compute_nocheck_cubic_bounds(points: &[Point; 4]) -> Option<Rect> {\n    debug_assert!(points[0].is_finite());\n    debug_assert!(points[1].is_finite());\n    debug_assert!(points[2].is_finite());\n    debug_assert!(points[3].is_finite());\n\n    let mut min = points[0].to_f32x2();\n    let mut max = min;\n    for i in 1..4 {\n        let pair = points[i].to_f32x2();\n        min = min.min(pair);\n        max = max.max(pair);\n    }\n\n    Rect::from_ltrb(min.x(), min.y(), max.x(), max.y())\n}\n\n// The off-curve points are \"inside\" the limits of the on-curve points.\nfn quick_cubic_niceness_check(points: &[Point; 4]) -> bool {\n    lt_90(points[1], points[0], points[3])\n        && lt_90(points[2], points[0], points[3])\n        && lt_90(points[1], points[3], points[0])\n        && lt_90(points[2], points[3], points[0])\n}\n\nfn lt_90(p0: Point, pivot: Point, p2: Point) -> bool {\n    (p0 - pivot).dot(p2 - pivot) >= 0.0\n}\n\nfn hair_cubic2(\n    points: &[Point; 4],\n    clip: Option<&ScreenIntRect>,\n    line_proc: LineProc,\n    blitter: &mut dyn Blitter,\n) {\n    let lines = compute_cubic_segments(points);\n    debug_assert!(lines > 0);\n    if lines == 1 {\n        line_proc(&[points[0], points[3]], clip, blitter);\n        return;\n    }\n\n    let coeff = path_geometry::CubicCoeff::from_points(points);\n\n    const MAX_POINTS: usize = (1 << MAX_CUBIC_SUBDIVIDE_LEVEL) + 1;\n    debug_assert!(lines < MAX_POINTS);\n    let mut tmp = [Point::zero(); MAX_POINTS];\n\n    let dt = f32x2::splat(1.0 / lines as f32);\n    let mut t = f32x2::default();\n\n    tmp[0] = points[0];\n    for i in 1..lines {\n        t = t + dt;\n        tmp[i] = Point::from_f32x2(((coeff.a * t + coeff.b) * t + coeff.c) * t + coeff.d);\n    }\n\n    if tmp.iter().all(|p| p.is_finite()) {\n        tmp[lines] = points[3];\n        line_proc(&tmp[0..lines + 1], clip, blitter);\n    } else {\n        // else some point(s) are non-finite, so don't draw\n    }\n}\n\nfn compute_cubic_segments(points: &[Point; 4]) -> usize {\n    let p0 = points[0].to_f32x2();\n    let p1 = points[1].to_f32x2();\n    let p2 = points[2].to_f32x2();\n    let p3 = points[3].to_f32x2();\n\n    let one_third = f32x2::splat(1.0 / 3.0);\n    let two_third = f32x2::splat(2.0 / 3.0);\n\n    let p13 = one_third * p3 + two_third * p0;\n    let p23 = one_third * p0 + two_third * p3;\n\n    let diff = (p1 - p13).abs().max((p2 - p23).abs()).max_component();\n    let mut tol = 1.0 / 8.0;\n\n    for i in 0..MAX_CUBIC_SUBDIVIDE_LEVEL {\n        if diff < tol {\n            return 1 << i;\n        }\n\n        tol *= 4.0;\n    }\n\n    1 << MAX_CUBIC_SUBDIVIDE_LEVEL\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/scan/hairline_aa.rs",
      "sha256": "50f1948aa413647e5ad8a3d2020cf758c29bd5b54f8c829190d453fad8e39549",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2011 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse core::convert::TryFrom;\nuse core::num::NonZeroU16;\n\nuse crate::{IntRect, LengthU32, LineCap, Path, Point, Rect};\n\nuse crate::alpha_runs::{AlphaRun, AlphaRuns};\nuse crate::blitter::Blitter;\nuse crate::color::AlphaU8;\nuse crate::fixed_point::{fdot16, fdot6, fdot8, FDot16, FDot6, FDot8};\nuse crate::geom::{IntRectExt, ScreenIntRect};\nuse crate::line_clipper;\nuse crate::math::LENGTH_U32_ONE;\n\n#[derive(Copy, Clone, Debug)]\nstruct FixedRect {\n    left: FDot16,\n    top: FDot16,\n    right: FDot16,\n    bottom: FDot16,\n}\n\nimpl FixedRect {\n    fn from_rect(src: &Rect) -> Self {\n        FixedRect {\n            left: fdot16::from_f32(src.left()),\n            top: fdot16::from_f32(src.top()),\n            right: fdot16::from_f32(src.right()),\n            bottom: fdot16::from_f32(src.bottom()),\n        }\n    }\n}\n\n/// Multiplies value by 0..256, and shift the result down 8\n/// (i.e. return (value * alpha256) >> 8)\nfn alpha_mul(value: AlphaU8, alpha256: i32) -> u8 {\n    let a = (i32::from(value) * alpha256) >> 8;\n    debug_assert!(a >= 0 && a <= 255);\n    a as u8\n}\n\npub fn fill_rect(rect: &Rect, clip: &ScreenIntRect, blitter: &mut dyn Blitter) {\n    let rect = match rect.intersect(&clip.to_rect()) {\n        Some(v) => v,\n        None => return, // everything was clipped out\n    };\n\n    let fr = FixedRect::from_rect(&rect);\n    fill_fixed_rect(&fr, blitter);\n}\n\nfn fill_fixed_rect(rect: &FixedRect, blitter: &mut dyn Blitter) {\n    fill_dot8(\n        fdot8::from_fdot16(rect.left),\n        fdot8::from_fdot16(rect.top),\n        fdot8::from_fdot16(rect.right),\n        fdot8::from_fdot16(rect.bottom),\n        true,\n        blitter,\n    )\n}\n\nfn fill_dot8(l: FDot8, t: FDot8, r: FDot8, b: FDot8, fill_inner: bool, blitter: &mut dyn Blitter) {\n    fn to_alpha(a: i32) -> u8 {\n        debug_assert!(a >= 0 && a <= 255);\n        a as u8\n    }\n\n    // check for empty now that we're in our reduced precision space\n    if l >= r || t >= b {\n        return;\n    }\n\n    let mut top = t >> 8;\n    if top == ((b - 1) >> 8) {\n        // just one scanline high\n        do_scanline(l, top, r, to_alpha(b - t - 1), blitter);\n        return;\n    }\n\n    if t & 0xFF != 0 {\n        do_scanline(l, top, r, to_alpha(256 - (t & 0xFF)), blitter);\n        top += 1;\n    }\n\n    let bottom = b >> 8;\n    let height = bottom - top;\n    if let Some(height) = u32::try_from(height).ok().and_then(LengthU32::new) {\n        let mut left = l >> 8;\n        if left == ((r - 1) >> 8) {\n            // just 1-pixel wide\n            if let (Ok(left), Ok(top)) = (u32::try_from(left), u32::try_from(top)) {\n                blitter.blit_v(left, top, height, to_alpha(r - l - 1));\n            } else {\n                debug_assert!(false);\n            }\n        } else {\n            if l & 0xFF != 0 {\n                if let (Ok(left), Ok(top)) = (u32::try_from(left), u32::try_from(top)) {\n                    blitter.blit_v(left, top, height, to_alpha(256 - (l & 0xFF)));\n                } else {\n                    debug_assert!(false);\n                }\n\n                left += 1;\n            }\n\n            let right = r >> 8;\n            let width = right - left;\n            if fill_inner {\n                if let Some(width) = u32::try_from(width).ok().and_then(LengthU32::new) {\n                    if let (Ok(left), Ok(top)) = (u32::try_from(left), u32::try_from(top)) {\n                        let rect = ScreenIntRect::from_xywh_safe(left, top, width, height);\n                        blitter.blit_rect(&rect);\n                    } else {\n                        debug_assert!(false);\n                    }\n                } else {\n                    debug_assert!(false);\n                }\n            }\n\n            if r & 0xFF != 0 {\n                if let (Ok(right), Ok(top)) = (u32::try_from(right), u32::try_from(top)) {\n                    blitter.blit_v(right, top, height, to_alpha(r & 0xFF));\n                } else {\n                    debug_assert!(false);\n                }\n            }\n        }\n    }\n\n    if b & 0xFF != 0 {\n        do_scanline(l, bottom, r, to_alpha(b & 0xFF), blitter);\n    }\n}\n\nfn do_scanline(l: FDot8, top: i32, r: FDot8, alpha: AlphaU8, blitter: &mut dyn Blitter) {\n    debug_assert!(l < r);\n\n    let one_len = LENGTH_U32_ONE;\n    let top = match u32::try_from(top) {\n        Ok(n) => n,\n        _ => return,\n    };\n\n    if (l >> 8) == ((r - 1) >> 8) {\n        // 1x1 pixel\n        if let Ok(left) = u32::try_from(l >> 8) {\n            blitter.blit_v(left, top, one_len, alpha_mul(alpha, r - l));\n        }\n\n        return;\n    }\n\n    let mut left = l >> 8;\n\n    if l & 0xFF != 0 {\n        if let Ok(left) = u32::try_from(l >> 8) {\n            blitter.blit_v(left, top, one_len, alpha_mul(alpha, 256 - (l & 0xFF)));\n        }\n\n        left += 1;\n    }\n\n    let right = r >> 8;\n    let width = right - left;\n    if let Some(width) = u32::try_from(width).ok().and_then(LengthU32::new) {\n        if let Ok(left) = u32::try_from(left) {\n            call_hline_blitter(left, Some(top), width, alpha, blitter);\n        }\n    }\n\n    if r & 0xFF != 0 {\n        if let Ok(right) = u32::try_from(right) {\n            blitter.blit_v(right, top, one_len, alpha_mul(alpha, r & 0xFF));\n        }\n    }\n}\n\nfn call_hline_blitter(\n    mut x: u32,\n    y: Option<u32>,\n    count: LengthU32,\n    alpha: AlphaU8,\n    blitter: &mut dyn Blitter,\n) {\n    const HLINE_STACK_BUFFER: usize = 100;\n\n    let mut runs = [None; HLINE_STACK_BUFFER + 1];\n    let mut aa = [0u8; HLINE_STACK_BUFFER];\n\n    let mut count = count.get();\n    loop {\n        // In theory, we should be able to just do this once (outside of the loop),\n        // since aa[] and runs[] are supposed\" to be const when we call the blitter.\n        // In reality, some wrapper-blitters (e.g. RgnClipBlitter) cast away that\n        // constness, and modify the buffers in-place. Hence the need to be defensive\n        // here and reseed the aa value.\n        aa[0] = alpha;\n\n        let mut n = count;\n        if n > HLINE_STACK_BUFFER as u32 {\n            n = HLINE_STACK_BUFFER as u32;\n        }\n\n        debug_assert!(n <= core::u16::MAX as u32);\n        runs[0] = NonZeroU16::new(n as u16);\n        runs[n as usize] = None;\n        if let Some(y) = y {\n            blitter.blit_anti_h(x, y, &mut aa, &mut runs);\n        }\n        x += n;\n\n        if n >= count || count == 0 {\n            break;\n        }\n\n        count -= n;\n    }\n}\n\npub fn stroke_path(\n    path: &Path,\n    line_cap: LineCap,\n    clip: &ScreenIntRect,\n    blitter: &mut dyn Blitter,\n) {\n    super::hairline::stroke_path_impl(path, line_cap, clip, anti_hair_line_rgn, blitter);\n}\n\nfn anti_hair_line_rgn(points: &[Point], clip: Option<&ScreenIntRect>, blitter: &mut dyn Blitter) {\n    let max = 32767.0;\n    let fixed_bounds = Rect::from_ltrb(-max, -max, max, max).unwrap();\n\n    let clip_bounds = if let Some(clip) = clip {\n        // We perform integral clipping later on, but we do a scalar clip first\n        // to ensure that our coordinates are expressible in fixed/integers.\n        //\n        // antialiased hairlines can draw up to 1/2 of a pixel outside of\n        // their bounds, so we need to outset the clip before calling the\n        // clipper. To make the numerics safer, we outset by a whole pixel,\n        // since the 1/2 pixel boundary is important to the antihair blitter,\n        // we don't want to risk numerical fate by chopping on that edge.\n        clip.to_rect().outset(1.0, 1.0)\n    } else {\n        None\n    };\n\n    for i in 0..points.len() - 1 {\n        let mut pts = [Point::zero(); 2];\n\n        // We have to pre-clip the line to fit in a Fixed, so we just chop the line.\n        if !line_clipper::intersect(&[points[i], points[i + 1]], &fixed_bounds, &mut pts) {\n            continue;\n        }\n\n        if let Some(clip_bounds) = clip_bounds {\n            let tmp = pts;\n            if !line_clipper::intersect(&tmp, &clip_bounds, &mut pts) {\n                continue;\n            }\n        }\n\n        let x0 = fdot6::from_f32(pts[0].x);\n        let y0 = fdot6::from_f32(pts[0].y);\n        let x1 = fdot6::from_f32(pts[1].x);\n        let y1 = fdot6::from_f32(pts[1].y);\n\n        if let Some(clip) = clip {\n            let left = x0.min(x1);\n            let top = y0.min(y1);\n            let right = x0.max(x1);\n            let bottom = y0.max(y1);\n\n            let ir = IntRect::from_ltrb(\n                fdot6::floor(left) - 1,\n                fdot6::floor(top) - 1,\n                fdot6::ceil(right) + 1,\n                fdot6::ceil(bottom) + 1,\n            );\n            let ir = match ir {\n                Some(v) => v,\n                None => return,\n            };\n\n            if clip.to_int_rect().intersect(&ir).is_none() {\n                continue;\n            }\n\n            if !clip.to_int_rect().contains(&ir) {\n                let subclip = ir\n                    .intersect(&clip.to_int_rect())\n                    .and_then(|r| r.to_screen_int_rect());\n\n                if let Some(subclip) = subclip {\n                    do_anti_hairline(x0, y0, x1, y1, Some(subclip), blitter);\n                }\n\n                continue;\n            }\n\n            // fall through to no-clip case\n        }\n\n        do_anti_hairline(x0, y0, x1, y1, None, blitter);\n    }\n}\n\n#[derive(Copy, Clone, Debug)]\nenum BlitterKind {\n    HLine,\n    Horish,\n    VLine,\n    Vertish,\n}\n\nfn do_anti_hairline(\n    mut x0: FDot6,\n    mut y0: FDot6,\n    mut x1: FDot6,\n    mut y1: FDot6,\n    mut clip_opt: Option<ScreenIntRect>,\n    blitter: &mut dyn Blitter,\n) {\n    // check for integer NaN (0x80000000) which we can't handle (can't negate it)\n    // It appears typically from a huge float (inf or nan) being converted to int.\n    // If we see it, just don't draw.\n    if any_bad_ints(x0, y0, x1, y1) != 0 {\n        return;\n    }\n\n    // The caller must clip the line to [-32767.0 ... 32767.0] ahead of time  (in dot6 format)\n    debug_assert!(fdot6::can_convert_to_fdot16(x0));\n    debug_assert!(fdot6::can_convert_to_fdot16(y0));\n    debug_assert!(fdot6::can_convert_to_fdot16(x1));\n    debug_assert!(fdot6::can_convert_to_fdot16(y1));\n\n    if (x1 - x0).abs() > fdot6::from_i32(511) || (y1 - y0).abs() > fdot6::from_i32(511) {\n        // instead of (x0 + x1) >> 1, we shift each separately. This is less\n        // precise, but avoids overflowing the intermediate result if the\n        // values are huge. A better fix might be to clip the original pts\n        // directly (i.e. do the divide), so we don't spend time subdividing\n        // huge lines at all.\n        let hx = (x0 >> 1) + (x1 >> 1);\n        let hy = (y0 >> 1) + (y1 >> 1);\n        do_anti_hairline(x0, y0, hx, hy, clip_opt, blitter);\n        do_anti_hairline(hx, hy, x1, y1, clip_opt, blitter);\n        return; // we're done\n    }\n\n    let mut scale_start;\n    let mut scale_stop;\n    let mut istart;\n    let mut istop;\n    let mut fstart;\n    let slope;\n    let blitter_kind;\n\n    if (x1 - x0).abs() > (y1 - y0).abs() {\n        // mostly horizontal\n\n        if x0 > x1 {\n            // we want to go left-to-right\n            core::mem::swap(&mut x0, &mut x1);\n            core::mem::swap(&mut y0, &mut y1);\n        }\n\n        istart = fdot6::floor(x0);\n        istop = fdot6::ceil(x1);\n        fstart = fdot6::to_fdot16(y0);\n        if y0 == y1 {\n            // completely horizontal, take fast case\n            slope = 0;\n            blitter_kind = Some(BlitterKind::HLine);\n        } else {\n            slope = fdot16::fast_div(y1 - y0, x1 - x0);\n            debug_assert!(slope >= -fdot16::ONE && slope <= fdot16::ONE);\n            fstart += (slope * (32 - (x0 & 63)) + 32) >> 6;\n            blitter_kind = Some(BlitterKind::Horish);\n        }\n\n        debug_assert!(istop > istart);\n        if istop - istart == 1 {\n            // we are within a single pixel\n            scale_start = x1 - x0;\n            debug_assert!(scale_start >= 0 && scale_start <= 64);\n            scale_stop = 0;\n        } else {\n            scale_start = 64 - (x0 & 63);\n            scale_stop = x1 & 63;\n        }\n\n        if let Some(clip) = clip_opt {\n            let clip = clip.to_int_rect();\n\n            if istart >= clip.right() || istop <= clip.left() {\n                return; // we're done\n            }\n\n            if istart < clip.left() {\n                fstart += slope * (clip.left() - istart);\n                istart = clip.left();\n                scale_start = 64;\n                if istop - istart == 1 {\n                    // we are within a single pixel\n                    scale_start = contribution_64(x1);\n                    scale_stop = 0;\n                }\n            }\n\n            if istop > clip.right() {\n                istop = clip.right();\n                scale_stop = 0; // so we don't draw this last column\n            }\n\n            debug_assert!(istart <= istop);\n            if istart == istop {\n                return; // we're done\n            }\n\n            // now test if our Y values are completely inside the clip\n            let (mut top, mut bottom) = if slope >= 0 {\n                // T2B\n                let top = fdot16::floor_to_i32(fstart - fdot16::HALF);\n                let bottom =\n                    fdot16::ceil_to_i32(fstart + (istop - istart - 1) * slope + fdot16::HALF);\n                (top, bottom)\n            } else {\n                // B2T\n                let bottom = fdot16::ceil_to_i32(fstart + fdot16::HALF);\n                let top =\n                    fdot16::floor_to_i32(fstart + (istop - istart - 1) * slope - fdot16::HALF);\n                (top, bottom)\n            };\n\n            top -= 1;\n            bottom += 1;\n\n            if top >= clip.bottom() || bottom <= clip.top() {\n                return; // we're done\n            }\n\n            if clip.top() <= top && clip.bottom() >= bottom {\n                clip_opt = None;\n            }\n        }\n    } else {\n        // mostly vertical\n\n        if y0 > y1 {\n            // we want to go top-to-bottom\n            core::mem::swap(&mut x0, &mut x1);\n            core::mem::swap(&mut y0, &mut y1);\n        }\n\n        istart = fdot6::floor(y0);\n        istop = fdot6::ceil(y1);\n        fstart = fdot6::to_fdot16(x0);\n        if x0 == x1 {\n            if y0 == y1 {\n                // are we zero length? nothing to do\n                return; // we're done\n            }\n\n            slope = 0;\n            blitter_kind = Some(BlitterKind::VLine);\n        } else {\n            slope = fdot16::fast_div(x1 - x0, y1 - y0);\n            debug_assert!(slope <= fdot16::ONE && slope >= -fdot16::ONE);\n            fstart += (slope * (32 - (y0 & 63)) + 32) >> 6;\n            blitter_kind = Some(BlitterKind::Vertish);\n        }\n\n        debug_assert!(istop > istart);\n        if istop - istart == 1 {\n            // we are within a single pixel\n            scale_start = y1 - y0;\n            debug_assert!(scale_start >= 0 && scale_start <= 64);\n            scale_stop = 0;\n        } else {\n            scale_start = 64 - (y0 & 63);\n            scale_stop = y1 & 63;\n        }\n\n        if let Some(clip) = clip_opt {\n            let clip = clip.to_int_rect();\n\n            if istart >= clip.bottom() || istop <= clip.top() {\n                return; // we're done\n            }\n\n            if istart < clip.top() {\n                fstart += slope * (clip.top() - istart);\n                istart = clip.top();\n                scale_start = 64;\n                if istop - istart == 1 {\n                    // we are within a single pixel\n                    scale_start = contribution_64(y1);\n                    scale_stop = 0;\n                }\n            }\n            if istop > clip.bottom() {\n                istop = clip.bottom();\n                scale_stop = 0; // so we don't draw this last row\n            }\n\n            debug_assert!(istart <= istop);\n            if istart == istop {\n                return; // we're done\n            }\n\n            // now test if our X values are completely inside the clip\n            let (mut left, mut right) = if slope >= 0 {\n                // L2R\n                let left = fdot16::floor_to_i32(fstart - fdot16::HALF);\n                let right =\n                    fdot16::ceil_to_i32(fstart + (istop - istart - 1) * slope + fdot16::HALF);\n                (left, right)\n            } else {\n                // R2L\n                let right = fdot16::ceil_to_i32(fstart + fdot16::HALF);\n                let left =\n                    fdot16::floor_to_i32(fstart + (istop - istart - 1) * slope - fdot16::HALF);\n                (left, right)\n            };\n\n            left -= 1;\n            right += 1;\n\n            if left >= clip.right() || right <= clip.left() {\n                return; // we're done\n            }\n\n            if clip.left() <= left && clip.right() >= right {\n                clip_opt = None;\n            }\n        }\n    }\n\n    let mut clip_blitter;\n    let blitter = if let Some(clip) = clip_opt {\n        clip_blitter = RectClipBlitter { blitter, clip };\n        &mut clip_blitter\n    } else {\n        blitter\n    };\n\n    let blitter_kind = match blitter_kind {\n        Some(v) => v,\n        None => return,\n    };\n\n    // A bit ugly, but looks like this is the only way to have stack allocated object trait.\n    let mut hline_blitter;\n    let mut horish_blitter;\n    let mut vline_blitter;\n    let mut vertish_blitter;\n    let hair_blitter: &mut dyn AntiHairBlitter = match blitter_kind {\n        BlitterKind::HLine => {\n            hline_blitter = HLineAntiHairBlitter(blitter);\n            &mut hline_blitter\n        }\n        BlitterKind::Horish => {\n            horish_blitter = HorishAntiHairBlitter(blitter);\n            &mut horish_blitter\n        }\n        BlitterKind::VLine => {\n            vline_blitter = VLineAntiHairBlitter(blitter);\n            &mut vline_blitter\n        }\n        BlitterKind::Vertish => {\n            vertish_blitter = VertishAntiHairBlitter(blitter);\n            &mut vertish_blitter\n        }\n    };\n\n    debug_assert!(istart >= 0);\n    let mut istart = istart as u32;\n\n    debug_assert!(istop >= 0);\n    let istop = istop as u32;\n\n    fstart = hair_blitter.draw_cap(istart, fstart, slope, scale_start);\n    istart += 1;\n    let full_spans = istop - istart - (scale_stop > 0) as u32;\n    if full_spans > 0 {\n        fstart = hair_blitter.draw_line(istart, istart + full_spans, fstart, slope);\n    }\n\n    if scale_stop > 0 {\n        hair_blitter.draw_cap(istop - 1, fstart, slope, scale_stop);\n    }\n}\n\n// returns high-bit set if x == 0x8000\nfn bad_int(x: i32) -> i32 {\n    x & -x\n}\n\nfn any_bad_ints(a: i32, b: i32, c: i32, d: i32) -> i32 {\n    (bad_int(a) | bad_int(b) | bad_int(c) | bad_int(d)) >> ((core::mem::size_of::<i32>() << 3) - 1)\n}\n\n// We want the fractional part of ordinate, but we want multiples of 64 to\n// return 64, not 0, so we can't just say (ordinate & 63).\n// We basically want to compute those bits, and if they're 0, return 64.\n// We can do that w/o a branch with an extra sub and add.\nfn contribution_64(ordinate: FDot6) -> i32 {\n    let result = ((ordinate - 1) & 63) + 1;\n    debug_assert!(result > 0 && result <= 64);\n    result\n}\n\ntrait AntiHairBlitter {\n    fn draw_cap(&mut self, x: u32, fy: FDot16, slope: FDot16, mod64: i32) -> FDot16;\n    fn draw_line(&mut self, x: u32, stopx: u32, fy: FDot16, slope: FDot16) -> FDot16;\n}\n\nstruct HLineAntiHairBlitter<'a>(&'a mut dyn Blitter);\n\nimpl AntiHairBlitter for HLineAntiHairBlitter<'_> {\n    fn draw_cap(&mut self, x: u32, mut fy: FDot16, _: FDot16, mod64: i32) -> FDot16 {\n        fy += fdot16::ONE / 2;\n        fy = fy.max(0);\n\n        let y = (fy >> 16) as u32;\n        let a = i32_to_alpha(fy >> 8);\n\n        // lower line\n        let mut ma = fdot6::small_scale(a, mod64);\n        if ma != 0 {\n            call_hline_blitter(x, Some(y), LENGTH_U32_ONE, ma, self.0);\n        }\n\n        // upper line\n        ma = fdot6::small_scale(255 - a, mod64);\n        if ma != 0 {\n            call_hline_blitter(x, y.checked_sub(1), LENGTH_U32_ONE, ma, self.0);\n        }\n\n        fy - fdot16::ONE / 2\n    }\n\n    fn draw_line(&mut self, x: u32, stop_x: u32, mut fy: FDot16, _: FDot16) -> FDot16 {\n        let count = match LengthU32::new(stop_x - x) {\n            Some(n) => n,\n            None => return fy,\n        };\n\n        fy += fdot16::ONE / 2;\n        fy = fy.max(0);\n\n        let y = (fy >> 16) as u32;\n        let mut a = i32_to_alpha(fy >> 8);\n\n        // lower line\n        if a != 0 {\n            call_hline_blitter(x, Some(y), count, a, self.0);\n        }\n\n        // upper line\n        a = 255 - a;\n        if a != 0 {\n            call_hline_blitter(x, y.checked_sub(1), count, a, self.0);\n        }\n\n        fy - fdot16::ONE / 2\n    }\n}\n\nstruct HorishAntiHairBlitter<'a>(&'a mut dyn Blitter);\n\nimpl AntiHairBlitter for HorishAntiHairBlitter<'_> {\n    fn draw_cap(&mut self, x: u32, mut fy: FDot16, dy: FDot16, mod64: i32) -> FDot16 {\n        fy += fdot16::ONE / 2;\n        fy = fy.max(0);\n\n        let lower_y = (fy >> 16) as u32;\n        let a = i32_to_alpha(fy >> 8);\n        let a0 = fdot6::small_scale(255 - a, mod64);\n        let a1 = fdot6::small_scale(a, mod64);\n        self.0.blit_anti_v2(x, lower_y.max(1) - 1, a0, a1);\n\n        fy + dy - fdot16::ONE / 2\n    }\n\n    fn draw_line(&mut self, mut x: u32, stop_x: u32, mut fy: FDot16, dy: FDot16) -> FDot16 {\n        debug_assert!(x < stop_x);\n\n        fy += fdot16::ONE / 2;\n        loop {\n            fy = fy.max(0);\n            let lower_y = (fy >> 16) as u32;\n            let a = i32_to_alpha(fy >> 8);\n            self.0.blit_anti_v2(x, lower_y.max(1) - 1, 255 - a, a);\n            fy += dy;\n\n            x += 1;\n            if x >= stop_x {\n                break;\n            }\n        }\n\n        fy - fdot16::ONE / 2\n    }\n}\n\nstruct VLineAntiHairBlitter<'a>(&'a mut dyn Blitter);\n\nimpl AntiHairBlitter for VLineAntiHairBlitter<'_> {\n    fn draw_cap(&mut self, y: u32, mut fx: FDot16, dx: FDot16, mod64: i32) -> FDot16 {\n        debug_assert!(dx == 0);\n        fx += fdot16::ONE / 2;\n        fx = fx.max(0);\n\n        let x = (fx >> 16) as u32;\n        let a = i32_to_alpha(fx >> 8);\n\n        let mut ma = fdot6::small_scale(a, mod64);\n        if ma != 0 {\n            self.0.blit_v(x, y, LENGTH_U32_ONE, ma);\n        }\n\n        ma = fdot6::small_scale(255 - a, mod64);\n        if ma != 0 {\n            self.0.blit_v(x.max(1) - 1, y, LENGTH_U32_ONE, ma);\n        }\n\n        fx - fdot16::ONE / 2\n    }\n\n    fn draw_line(&mut self, y: u32, stop_y: u32, mut fx: FDot16, dx: FDot16) -> FDot16 {\n        debug_assert!(dx == 0);\n        let height = match LengthU32::new(stop_y - y) {\n            Some(n) => n,\n            None => return fx,\n        };\n\n        fx += fdot16::ONE / 2;\n        fx = fx.max(0);\n\n        let x = (fx >> 16) as u32;\n        let mut a = i32_to_alpha(fx >> 8);\n\n        if a != 0 {\n            self.0.blit_v(x, y, height, a);\n        }\n\n        a = 255 - a;\n        if a != 0 {\n            self.0.blit_v(x.max(1) - 1, y, height, a);\n        }\n\n        fx - fdot16::ONE / 2\n    }\n}\n\nstruct VertishAntiHairBlitter<'a>(&'a mut dyn Blitter);\n\nimpl AntiHairBlitter for VertishAntiHairBlitter<'_> {\n    fn draw_cap(&mut self, y: u32, mut fx: FDot16, dx: FDot16, mod64: i32) -> FDot16 {\n        fx += fdot16::ONE / 2;\n        fx = fx.max(0);\n\n        let x = (fx >> 16) as u32;\n        let a = i32_to_alpha(fx >> 8);\n        self.0.blit_anti_h2(\n            x.max(1) - 1,\n            y,\n            fdot6::small_scale(255 - a, mod64),\n            fdot6::small_scale(a, mod64),\n        );\n\n        fx + dx - fdot16::ONE / 2\n    }\n\n    fn draw_line(&mut self, mut y: u32, stop_y: u32, mut fx: FDot16, dx: FDot16) -> FDot16 {\n        debug_assert!(y < stop_y);\n\n        fx += fdot16::ONE / 2;\n        loop {\n            fx = fx.max(0);\n            let x = (fx >> 16) as u32;\n            let a = i32_to_alpha(fx >> 8);\n            self.0.blit_anti_h2(x.max(1) - 1, y, 255 - a, a);\n            fx += dx;\n\n            y += 1;\n            if y >= stop_y {\n                break;\n            }\n        }\n\n        fx - fdot16::ONE / 2\n    }\n}\n\nfn i32_to_alpha(a: i32) -> u8 {\n    (a & 0xFF) as u8\n}\n\nstruct RectClipBlitter<'a> {\n    blitter: &'a mut dyn Blitter,\n    clip: ScreenIntRect,\n}\n\nimpl Blitter for RectClipBlitter<'_> {\n    fn blit_anti_h(\n        &mut self,\n        x: u32,\n        y: u32,\n        mut antialias: &mut [AlphaU8],\n        mut runs: &mut [AlphaRun],\n    ) {\n        fn y_in_rect(y: u32, rect: ScreenIntRect) -> bool {\n            (y - rect.top()) < rect.height()\n        }\n\n        if !y_in_rect(y, self.clip) || x >= self.clip.right() {\n            return;\n        }\n\n        let mut x0 = x;\n        let mut x1 = x + compute_anti_width(runs);\n\n        if x1 <= self.clip.left() {\n            return;\n        }\n\n        debug_assert!(x0 < x1);\n        if x0 < self.clip.left() {\n            let dx = self.clip.left() - x0;\n            AlphaRuns::break_at(antialias, runs, dx as i32);\n            antialias = &mut antialias[dx as usize..];\n            runs = &mut runs[dx as usize..];\n            x0 = self.clip.left();\n        }\n\n        debug_assert!(x0 < x1 && runs[(x1 - x0) as usize].is_none());\n        if x1 > self.clip.right() {\n            x1 = self.clip.right();\n            AlphaRuns::break_at(antialias, runs, (x1 - x0) as i32);\n            runs[(x1 - x0) as usize] = None;\n        }\n\n        debug_assert!(x0 < x1 && runs[(x1 - x0) as usize].is_none());\n        debug_assert!(compute_anti_width(runs) == x1 - x0);\n\n        self.blitter.blit_anti_h(x0, y, antialias, runs);\n    }\n\n    fn blit_v(&mut self, x: u32, y: u32, height: LengthU32, alpha: AlphaU8) {\n        fn x_in_rect(x: u32, rect: ScreenIntRect) -> bool {\n            (x - rect.left()) < rect.width()\n        }\n\n        if !x_in_rect(x, self.clip) {\n            return;\n        }\n\n        let mut y0 = y;\n        let mut y1 = y + height.get();\n\n        if y0 < self.clip.top() {\n            y0 = self.clip.top();\n        }\n\n        if y1 > self.clip.bottom() {\n            y1 = self.clip.bottom();\n        }\n\n        if y0 < y1 {\n            if let Some(h) = LengthU32::new(y1 - y0) {\n                self.blitter.blit_v(x, y0, h, alpha);\n            }\n        }\n    }\n\n    fn blit_anti_h2(&mut self, x: u32, y: u32, alpha0: AlphaU8, alpha1: AlphaU8) {\n        self.blit_anti_h(\n            x,\n            y,\n            &mut [alpha0, alpha1],\n            &mut [NonZeroU16::new(1), NonZeroU16::new(1), None],\n        );\n    }\n\n    fn blit_anti_v2(&mut self, x: u32, y: u32, alpha0: AlphaU8, alpha1: AlphaU8) {\n        self.blit_anti_h(x, y, &mut [alpha0], &mut [NonZeroU16::new(1), None]);\n\n        self.blit_anti_h(x, y + 1, &mut [alpha1], &mut [NonZeroU16::new(1), None]);\n    }\n}\n\nfn compute_anti_width(runs: &[AlphaRun]) -> u32 {\n    let mut i = 0;\n    let mut width = 0;\n    while let Some(count) = runs[i] {\n        width += u32::from(count.get());\n        i += usize::from(count.get());\n    }\n\n    width\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/scan/mod.rs",
      "sha256": "db9ca53fad681f35b4c13dc228e1bab54cb08a0c3efb4d1e4b13d937c5ec1a65",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2011 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\npub mod hairline;\npub mod hairline_aa;\npub mod path;\npub mod path_aa;\n\nuse crate::{IntRect, Rect};\n\nuse crate::blitter::Blitter;\nuse crate::geom::{IntRectExt, ScreenIntRect};\n\npub fn fill_rect(rect: &Rect, clip: &ScreenIntRect, blitter: &mut dyn Blitter) {\n    if let Some(rect) = rect.round() {\n        fill_int_rect(&rect, clip, blitter);\n    }\n}\n\nfn fill_int_rect(rect: &IntRect, clip: &ScreenIntRect, blitter: &mut dyn Blitter) {\n    let rect = match rect.intersect(&clip.to_int_rect()) {\n        Some(v) => v,\n        None => return, // everything was clipped out\n    };\n\n    let rect = match rect.to_screen_int_rect() {\n        Some(v) => v,\n        None => return,\n    };\n\n    blitter.blit_rect(&rect);\n}\n\npub fn fill_rect_aa(rect: &Rect, clip: &ScreenIntRect, blitter: &mut dyn Blitter) {\n    hairline_aa::fill_rect(rect, clip, blitter);\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/scan/path.rs",
      "sha256": "1d8a89c974b120f1a82d8318d1ceedc740be44a3e4fc73bdfe20184ae5c26619",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse core::convert::TryFrom;\n\nuse tiny_skia_path::SaturateCast;\n\nuse crate::{FillRule, IntRect, LengthU32, Path, Rect};\n\nuse crate::blitter::Blitter;\nuse crate::edge::{Edge, LineEdge};\nuse crate::edge_builder::{BasicEdgeBuilder, ShiftedIntRect};\nuse crate::fixed_point::{fdot16, fdot6, FDot16};\nuse crate::geom::{IntRectExt, ScreenIntRect};\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\npub fn fill_path(\n    path: &Path,\n    fill_rule: FillRule,\n    clip: &ScreenIntRect,\n    blitter: &mut dyn Blitter,\n) {\n    let ir = match conservative_round_to_int(&path.bounds()) {\n        Some(v) => v,\n        None => return,\n    };\n\n    let path_contained_in_clip = if let Some(bounds) = ir.to_screen_int_rect() {\n        clip.contains(&bounds)\n    } else {\n        // If bounds cannot be converted into ScreenIntRect,\n        // the path is out of clip.\n        false\n    };\n\n    // TODO: SkScanClipper\n\n    fill_path_impl(\n        path,\n        fill_rule,\n        clip,\n        ir.y(),\n        ir.bottom(),\n        0,\n        path_contained_in_clip,\n        blitter,\n    );\n}\n\n// Conservative rounding function, which effectively nudges the int-rect to be slightly larger\n// than Rect::round() might have produced. This is a safety-net for the scan-converter, which\n// inspects the returned int-rect, and may disable clipping (for speed) if it thinks all of the\n// edges will fit inside the clip's bounds. The scan-converter introduces slight numeric errors\n// due to accumulated += of the slope, so this function is used to return a conservatively large\n// int-bounds, and thus we will only disable clipping if we're sure the edges will stay in-bounds.\nfn conservative_round_to_int(src: &Rect) -> Option<IntRect> {\n    // We must use `from_ltrb`, otherwise rounding will be incorrect.\n    IntRect::from_ltrb(\n        round_down_to_int(src.left()),\n        round_down_to_int(src.top()),\n        round_up_to_int(src.right()),\n        round_up_to_int(src.bottom()),\n    )\n}\n\n// Bias used for conservative rounding of float rects to int rects, to nudge the irects a little\n// larger, so we don't \"think\" a path's bounds are inside a clip, when (due to numeric drift in\n// the scan-converter) we might walk beyond the predicted limits.\n//\n// This value has been determined trial and error: pick the smallest value (after the 0.5) that\n// fixes any problematic cases (e.g. crbug.com/844457)\n// NOTE: cubics appear to be the main reason for needing this slop. If we could (perhaps) have a\n// more accurate walker for cubics, we may be able to reduce this fudge factor.\nconst CONSERVATIVE_ROUND_BIAS: f64 = 0.5 + 1.5 / fdot6::ONE as f64;\n\n// Round the value down. This is used to round the top and left of a rectangle,\n// and corresponds to the way the scan converter treats the top and left edges.\n// It has a slight bias to make the \"rounded\" int smaller than a normal round, to create a more\n// conservative int-bounds (larger) from a float rect.\nfn round_down_to_int(x: f32) -> i32 {\n    let mut xx = x as f64;\n    xx -= CONSERVATIVE_ROUND_BIAS;\n    i32::saturate_from(xx.ceil())\n}\n\n// Round the value up. This is used to round the right and bottom of a rectangle.\n// It has a slight bias to make the \"rounded\" int smaller than a normal round, to create a more\n// conservative int-bounds (larger) from a float rect.\nfn round_up_to_int(x: f32) -> i32 {\n    let mut xx = x as f64;\n    xx += CONSERVATIVE_ROUND_BIAS;\n    i32::saturate_from(xx.floor())\n}\n\npub fn fill_path_impl(\n    path: &Path,\n    fill_rule: FillRule,\n    clip_rect: &ScreenIntRect,\n    mut start_y: i32,\n    mut stop_y: i32,\n    shift_edges_up: i32,\n    path_contained_in_clip: bool,\n    blitter: &mut dyn Blitter,\n) {\n    let shifted_clip = match ShiftedIntRect::new(clip_rect, shift_edges_up) {\n        Some(v) => v,\n        None => return,\n    };\n\n    let clip = if path_contained_in_clip {\n        None\n    } else {\n        Some(&shifted_clip)\n    };\n    let mut edges = match BasicEdgeBuilder::build_edges(path, clip, shift_edges_up) {\n        Some(v) => v,\n        None => return, // no edges to render, just return\n    };\n\n    edges.sort_by(|a, b| {\n        let mut value_a = a.as_line().first_y;\n        let mut value_b = b.as_line().first_y;\n\n        if value_a == value_b {\n            value_a = a.as_line().x;\n            value_b = b.as_line().x;\n        }\n\n        value_a.cmp(&value_b)\n    });\n\n    for i in 0..edges.len() {\n        // 0 will be set later, so start with 1.\n        edges[i].prev = Some(i as u32 + 0);\n        edges[i].next = Some(i as u32 + 2);\n    }\n\n    const EDGE_HEAD_Y: i32 = i32::MIN;\n    const EDGE_TAIL_Y: i32 = i32::MAX;\n\n    edges.insert(\n        0,\n        Edge::Line(LineEdge {\n            prev: None,\n            next: Some(1),\n            x: i32::MIN,\n            first_y: EDGE_HEAD_Y,\n            ..LineEdge::default()\n        }),\n    );\n\n    edges.push(Edge::Line(LineEdge {\n        prev: Some(edges.len() as u32 - 1),\n        next: None,\n        first_y: EDGE_TAIL_Y,\n        ..LineEdge::default()\n    }));\n\n    start_y <<= shift_edges_up;\n    stop_y <<= shift_edges_up;\n\n    let top = shifted_clip.shifted().y() as i32;\n    if !path_contained_in_clip && start_y < top {\n        start_y = top;\n    }\n\n    let bottom = shifted_clip.shifted().bottom() as i32;\n    if !path_contained_in_clip && stop_y > bottom as i32 {\n        stop_y = bottom as i32;\n    }\n\n    let start_y = match u32::try_from(start_y) {\n        Ok(v) => v,\n        Err(_) => return,\n    };\n    let stop_y = match u32::try_from(stop_y) {\n        Ok(v) => v,\n        Err(_) => return,\n    };\n\n    // TODO: walk_simple_edges\n\n    walk_edges(\n        fill_rule,\n        start_y,\n        stop_y,\n        shifted_clip.shifted().right(),\n        &mut edges,\n        blitter,\n    );\n}\n\n// TODO: simplify!\nfn walk_edges(\n    fill_rule: FillRule,\n    start_y: u32,\n    stop_y: u32,\n    right_clip: u32,\n    edges: &mut [Edge],\n    blitter: &mut dyn Blitter,\n) {\n    let mut curr_y = start_y;\n    let winding_mask = if fill_rule == FillRule::EvenOdd {\n        1\n    } else {\n        -1\n    };\n\n    loop {\n        let mut w = 0i32;\n        let mut left = 0u32;\n        let mut prev_x = edges[0].x;\n\n        let mut curr_idx = edges[0].next.unwrap() as usize;\n        while edges[curr_idx].first_y <= curr_y as i32 {\n            debug_assert!(edges[curr_idx].last_y >= curr_y as i32);\n\n            let x = fdot16::round_to_i32(edges[curr_idx].x) as u32; // TODO: check\n\n            if (w & winding_mask) == 0 {\n                // we're starting interval\n                left = x;\n            }\n\n            w += i32::from(edges[curr_idx].winding);\n\n            if (w & winding_mask) == 0 {\n                // we finished an interval\n                if let Some(width) = LengthU32::new(x - left) {\n                    blitter.blit_h(left, curr_y, width);\n                }\n            }\n\n            let next_idx = edges[curr_idx].next.unwrap();\n            let new_x;\n\n            if edges[curr_idx].last_y == curr_y as i32 {\n                // are we done with this edge?\n                match &mut edges[curr_idx] {\n                    Edge::Line(_) => {\n                        remove_edge(curr_idx, edges);\n                    }\n                    Edge::Quadratic(ref mut quad) => {\n                        if quad.curve_count > 0 && quad.update() {\n                            new_x = quad.line.x;\n\n                            if new_x < prev_x {\n                                // ripple current edge backwards until it is x-sorted\n                                backward_insert_edge_based_on_x(curr_idx, edges);\n                            } else {\n                                prev_x = new_x;\n                            }\n                        } else {\n                            remove_edge(curr_idx, edges);\n                        }\n                    }\n                    Edge::Cubic(ref mut cubic) => {\n                        if cubic.curve_count < 0 && cubic.update() {\n                            debug_assert!(cubic.line.first_y == curr_y as i32 + 1);\n\n                            new_x = cubic.line.x;\n\n                            if new_x < prev_x {\n                                // ripple current edge backwards until it is x-sorted\n                                backward_insert_edge_based_on_x(curr_idx, edges);\n                            } else {\n                                prev_x = new_x;\n                            }\n                        } else {\n                            remove_edge(curr_idx, edges);\n                        }\n                    }\n                }\n            } else {\n                debug_assert!(edges[curr_idx].last_y > curr_y as i32);\n                new_x = edges[curr_idx].x + edges[curr_idx].dx;\n                edges[curr_idx].x = new_x;\n\n                if new_x < prev_x {\n                    // ripple current edge backwards until it is x-sorted\n                    backward_insert_edge_based_on_x(curr_idx, edges);\n                } else {\n                    prev_x = new_x;\n                }\n            }\n\n            curr_idx = next_idx as usize;\n        }\n\n        if (w & winding_mask) != 0 {\n            // was our right-edge culled away?\n            if let Some(width) = LengthU32::new(right_clip - left) {\n                blitter.blit_h(left, curr_y, width);\n            }\n        }\n\n        curr_y += 1;\n        if curr_y >= stop_y {\n            break;\n        }\n\n        // now current edge points to the first edge with a Yint larger than curr_y\n        insert_new_edges(curr_idx, curr_y as i32, edges);\n    }\n}\n\nfn remove_edge(curr_idx: usize, edges: &mut [Edge]) {\n    let prev = edges[curr_idx].prev.unwrap();\n    let next = edges[curr_idx].next.unwrap();\n\n    edges[prev as usize].next = Some(next);\n    edges[next as usize].prev = Some(prev);\n}\n\nfn backward_insert_edge_based_on_x(curr_idx: usize, edges: &mut [Edge]) {\n    let x = edges[curr_idx].x;\n    let mut prev_idx = edges[curr_idx].prev.unwrap() as usize;\n    while prev_idx != 0 {\n        if edges[prev_idx].x > x {\n            prev_idx = edges[prev_idx].prev.unwrap() as usize;\n        } else {\n            break;\n        }\n    }\n\n    let next_idx = edges[prev_idx].next.unwrap() as usize;\n    if next_idx != curr_idx {\n        remove_edge(curr_idx, edges);\n        insert_edge_after(curr_idx, prev_idx, edges);\n    }\n}\n\nfn insert_edge_after(curr_idx: usize, after_idx: usize, edges: &mut [Edge]) {\n    edges[curr_idx].prev = Some(after_idx as u32);\n    edges[curr_idx].next = edges[after_idx].next;\n\n    let after_next_idx = edges[after_idx].next.unwrap() as usize;\n    edges[after_next_idx].prev = Some(curr_idx as u32);\n    edges[after_idx].next = Some(curr_idx as u32);\n}\n\n// Start from the right side, searching backwards for the point to begin the new edge list\n// insertion, marching forwards from here. The implementation could have started from the left\n// of the prior insertion, and search to the right, or with some additional caching, binary\n// search the starting point. More work could be done to determine optimal new edge insertion.\nfn backward_insert_start(mut prev_idx: usize, x: FDot16, edges: &mut [Edge]) -> usize {\n    while let Some(prev) = edges[prev_idx].prev {\n        prev_idx = prev as usize;\n        if edges[prev_idx].x <= x {\n            break;\n        }\n    }\n\n    prev_idx\n}\n\nfn insert_new_edges(mut new_idx: usize, curr_y: i32, edges: &mut [Edge]) {\n    if edges[new_idx].first_y != curr_y {\n        return;\n    }\n\n    let prev_idx = edges[new_idx].prev.unwrap() as usize;\n    if edges[prev_idx].x <= edges[new_idx].x {\n        return;\n    }\n\n    // find first x pos to insert\n    let mut start_idx = backward_insert_start(prev_idx, edges[new_idx].x, edges);\n    // insert the lot, fixing up the links as we go\n    loop {\n        let next_idx = edges[new_idx].next.unwrap() as usize;\n        let mut keep_edge = false;\n        loop {\n            let after_idx = edges[start_idx].next.unwrap() as usize;\n            if after_idx == new_idx {\n                keep_edge = true;\n                break;\n            }\n\n            if edges[after_idx].x >= edges[new_idx].x {\n                break;\n            }\n\n            start_idx = after_idx;\n        }\n\n        if !keep_edge {\n            remove_edge(new_idx, edges);\n            insert_edge_after(new_idx, start_idx, edges);\n        }\n\n        start_idx = new_idx;\n        new_idx = next_idx;\n\n        if edges[new_idx].first_y != curr_y {\n            break;\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/scan/path_aa.rs",
      "sha256": "d6fee0876986a9225be67d47c9f3e60dc6cf863d1b0ef2949ec499e72f7e893c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse core::convert::TryFrom;\n\nuse crate::{FillRule, IntRect, LengthU32, Path, Rect};\n\nuse crate::alpha_runs::AlphaRuns;\nuse crate::blitter::Blitter;\nuse crate::color::AlphaU8;\nuse crate::geom::{IntRectExt, ScreenIntRect};\nuse crate::math::left_shift;\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\n/// controls how much we super-sample (when we use that scan conversion)\nconst SUPERSAMPLE_SHIFT: u32 = 2;\n\nconst SHIFT: u32 = SUPERSAMPLE_SHIFT;\nconst SCALE: u32 = 1 << SHIFT;\nconst MASK: u32 = SCALE - 1;\n\npub fn fill_path(\n    path: &Path,\n    fill_rule: FillRule,\n    clip: &ScreenIntRect,\n    blitter: &mut dyn Blitter,\n) {\n    // Unlike `path.bounds.to_rect()?.round_out()`,\n    // this method rounds out first and then converts into a Rect.\n    let ir = Rect::from_ltrb(\n        path.bounds().left().floor(),\n        path.bounds().top().floor(),\n        path.bounds().right().ceil(),\n        path.bounds().bottom().ceil(),\n    )\n    .and_then(|r| r.round_out());\n    let ir = match ir {\n        Some(v) => v,\n        None => return,\n    };\n\n    // TODO: remove\n    // If the intersection of the path bounds and the clip bounds\n    // will overflow 32767 when << by SHIFT, we can't supersample,\n    // so draw without antialiasing.\n    let clipped_ir = match ir.intersect(&clip.to_int_rect()) {\n        Some(v) => v,\n        None => return,\n    };\n    if rect_overflows_short_shift(&clipped_ir, SHIFT as i32) != 0 {\n        super::path::fill_path(path, fill_rule, clip, blitter);\n        return;\n    }\n\n    // TODO: remove\n    // Our antialiasing can't handle a clip larger than 32767.\n    // TODO: skia actually limits the clip to 32767\n    {\n        const MAX_CLIP_COORD: u32 = 32767;\n        if clip.right() > MAX_CLIP_COORD || clip.bottom() > MAX_CLIP_COORD {\n            return;\n        }\n    }\n\n    // TODO: SkScanClipper\n    // TODO: AAA\n\n    fill_path_impl(path, fill_rule, &ir, clip, blitter)\n}\n\n// Would any of the coordinates of this rectangle not fit in a short,\n// when left-shifted by shift?\nfn rect_overflows_short_shift(rect: &IntRect, shift: i32) -> i32 {\n    debug_assert!(overflows_short_shift(8191, shift) == 0);\n    debug_assert!(overflows_short_shift(8192, shift) != 0);\n    debug_assert!(overflows_short_shift(32767, 0) == 0);\n    debug_assert!(overflows_short_shift(32768, 0) != 0);\n\n    // Since we expect these to succeed, we bit-or together\n    // for a tiny extra bit of speed.\n    overflows_short_shift(rect.left(), shift)\n        | overflows_short_shift(rect.top(), shift)\n        | overflows_short_shift(rect.right(), shift)\n        | overflows_short_shift(rect.bottom(), shift)\n}\n\nfn overflows_short_shift(value: i32, shift: i32) -> i32 {\n    let s = 16 + shift;\n    (left_shift(value, s) >> s) - value\n}\n\nfn fill_path_impl(\n    path: &Path,\n    fill_rule: FillRule,\n    bounds: &IntRect,\n    clip: &ScreenIntRect,\n    blitter: &mut dyn Blitter,\n) {\n    // TODO: MaskSuperBlitter\n\n    // TODO: 15% slower than skia, find out why\n    let mut blitter = match SuperBlitter::new(bounds, clip, blitter) {\n        Some(v) => v,\n        None => return, // clipped out, nothing else to do\n    };\n\n    let path_contained_in_clip = if let Some(bounds) = bounds.to_screen_int_rect() {\n        clip.contains(&bounds)\n    } else {\n        // If bounds cannot be converted into ScreenIntRect,\n        // the path is out of clip.\n        false\n    };\n\n    super::path::fill_path_impl(\n        path,\n        fill_rule,\n        clip,\n        bounds.top(),\n        bounds.bottom(),\n        SHIFT as i32,\n        path_contained_in_clip,\n        &mut blitter,\n    );\n}\n\nstruct BaseSuperBlitter<'a> {\n    real_blitter: &'a mut dyn Blitter,\n\n    /// Current y coordinate, in destination coordinates.\n    curr_iy: i32,\n    /// Widest row of region to be blitted, in destination coordinates.\n    width: LengthU32,\n    /// Leftmost x coordinate in any row, in destination coordinates.\n    left: u32,\n    /// Leftmost x coordinate in any row, in supersampled coordinates.\n    super_left: u32,\n\n    /// Current y coordinate in supersampled coordinates.\n    curr_y: i32,\n    /// Initial y coordinate (top of bounds).\n    top: i32,\n}\n\nimpl<'a> BaseSuperBlitter<'a> {\n    fn new(\n        bounds: &IntRect,\n        clip_rect: &ScreenIntRect,\n        blitter: &'a mut dyn Blitter,\n    ) -> Option<Self> {\n        let sect = bounds\n            .intersect(&clip_rect.to_int_rect())?\n            .to_screen_int_rect()?;\n        Some(BaseSuperBlitter {\n            real_blitter: blitter,\n            curr_iy: sect.top() as i32 - 1,\n            width: sect.width_safe(),\n            left: sect.left(),\n            super_left: sect.left() << SHIFT,\n            curr_y: (sect.top() << SHIFT) as i32 - 1,\n            top: sect.top() as i32,\n        })\n    }\n}\n\nstruct SuperBlitter<'a> {\n    base: BaseSuperBlitter<'a>,\n    runs: AlphaRuns,\n    offset_x: usize,\n}\n\nimpl<'a> SuperBlitter<'a> {\n    fn new(\n        bounds: &IntRect,\n        clip_rect: &ScreenIntRect,\n        blitter: &'a mut dyn Blitter,\n    ) -> Option<Self> {\n        let base = BaseSuperBlitter::new(bounds, clip_rect, blitter)?;\n        let runs_width = base.width;\n        Some(SuperBlitter {\n            base,\n            runs: AlphaRuns::new(runs_width),\n            offset_x: 0,\n        })\n    }\n\n    /// Once `runs` contains a complete supersampled row, flush() blits\n    /// it out through the wrapped blitter.\n    fn flush(&mut self) {\n        if self.base.curr_iy >= self.base.top {\n            if !self.runs.is_empty() {\n                self.base.real_blitter.blit_anti_h(\n                    self.base.left,\n                    u32::try_from(self.base.curr_iy).unwrap(),\n                    &mut self.runs.alpha,\n                    &mut self.runs.runs,\n                );\n                self.runs.reset(self.base.width);\n                self.offset_x = 0;\n            }\n\n            self.base.curr_iy = self.base.top - 1;\n        }\n    }\n}\n\nimpl Drop for SuperBlitter<'_> {\n    fn drop(&mut self) {\n        self.flush();\n    }\n}\n\nimpl Blitter for SuperBlitter<'_> {\n    /// Blits a row of pixels, with location and width specified\n    /// in supersampled coordinates.\n    fn blit_h(&mut self, mut x: u32, y: u32, mut width: LengthU32) {\n        let iy = (y >> SHIFT) as i32;\n        debug_assert!(iy >= self.base.curr_iy);\n\n        // hack, until I figure out why my cubics (I think) go beyond the bounds\n        match x.checked_sub(self.base.super_left) {\n            Some(n) => x = n,\n            None => {\n                width = LengthU32::new(x + width.get()).unwrap();\n                x = 0;\n            }\n        }\n\n        debug_assert!(y as i32 >= self.base.curr_y);\n        if self.base.curr_y != y as i32 {\n            self.offset_x = 0;\n            self.base.curr_y = y as i32;\n        }\n\n        if iy != self.base.curr_iy {\n            // new scanline\n            self.flush();\n            self.base.curr_iy = iy;\n        }\n\n        let start = x;\n        let stop = x + width.get();\n\n        debug_assert!(stop > start);\n        // integer-pixel-aligned ends of blit, rounded out\n        let mut fb = start & MASK;\n        let mut fe = stop & MASK;\n        let mut n: i32 = (stop as i32 >> SHIFT) - (start as i32 >> SHIFT) - 1;\n\n        if n < 0 {\n            fb = fe - fb;\n            n = 0;\n            fe = 0;\n        } else {\n            if fb == 0 {\n                n += 1;\n            } else {\n                fb = SCALE - fb;\n            }\n        }\n\n        let max_value = u8::try_from((1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT)).unwrap();\n        self.offset_x = self.runs.add(\n            x >> SHIFT,\n            coverage_to_partial_alpha(fb),\n            n as usize,\n            coverage_to_partial_alpha(fe),\n            max_value,\n            self.offset_x,\n        );\n    }\n}\n\n// coverage_to_partial_alpha() is being used by AlphaRuns, which\n// *accumulates* SCALE pixels worth of \"alpha\" in [0,(256/SCALE)]\n// to produce a final value in [0, 255] and handles clamping 256->255\n// itself, with the same (alpha - (alpha >> 8)) correction as\n// coverage_to_exact_alpha().\nfn coverage_to_partial_alpha(mut aa: u32) -> AlphaU8 {\n    aa <<= 8 - 2 * SHIFT;\n    aa as AlphaU8\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/shaders/gradient.rs",
      "sha256": "df396a8df82213ea576f031110ce7e786912bc68b1fed6bbea0a79a1e3547d3c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse alloc::vec::Vec;\n\nuse tiny_skia_path::{NormalizedF32, Scalar};\n\nuse crate::{Color, SpreadMode, Transform};\n\nuse crate::pipeline::RasterPipelineBuilder;\nuse crate::pipeline::{self, EvenlySpaced2StopGradientCtx, GradientColor, GradientCtx};\n\n// The default SCALAR_NEARLY_ZERO threshold of .0024 is too big and causes regressions for svg\n// gradients defined in the wild.\npub const DEGENERATE_THRESHOLD: f32 = 1.0 / (1 << 15) as f32;\n\n/// A gradient point.\n#[allow(missing_docs)]\n#[derive(Clone, Copy, PartialEq, Debug)]\npub struct GradientStop {\n    pub(crate) position: NormalizedF32,\n    pub(crate) color: Color,\n}\n\nimpl GradientStop {\n    /// Creates a new gradient point.\n    ///\n    /// `position` will be clamped to a 0..=1 range.\n    pub fn new(position: f32, color: Color) -> Self {\n        GradientStop {\n            position: NormalizedF32::new_clamped(position),\n            color,\n        }\n    }\n}\n\n#[derive(Clone, PartialEq, Debug)]\npub struct Gradient {\n    stops: Vec<GradientStop>,\n    tile_mode: SpreadMode,\n    pub(crate) transform: Transform,\n    points_to_unit: Transform,\n    pub(crate) colors_are_opaque: bool,\n    has_uniform_stops: bool,\n}\n\nimpl Gradient {\n    pub fn new(\n        mut stops: Vec<GradientStop>,\n        tile_mode: SpreadMode,\n        transform: Transform,\n        points_to_unit: Transform,\n    ) -> Self {\n        debug_assert!(stops.len() > 1);\n\n        // Note: we let the caller skip the first and/or last position.\n        // i.e. pos[0] = 0.3, pos[1] = 0.7\n        // In these cases, we insert dummy entries to ensure that the final data\n        // will be bracketed by [0, 1].\n        // i.e. our_pos[0] = 0, our_pos[1] = 0.3, our_pos[2] = 0.7, our_pos[3] = 1\n        let dummy_first = stops[0].position.get() != 0.0;\n        let dummy_last = stops[stops.len() - 1].position.get() != 1.0;\n\n        // Now copy over the colors, adding the dummies as needed.\n        if dummy_first {\n            stops.insert(0, GradientStop::new(0.0, stops[0].color));\n        }\n\n        if dummy_last {\n            stops.push(GradientStop::new(1.0, stops[stops.len() - 1].color));\n        }\n\n        let colors_are_opaque = stops.iter().all(|p| p.color.is_opaque());\n\n        // Pin the last value to 1.0, and make sure positions are monotonic.\n        let start_index = if dummy_first { 0 } else { 1 };\n        let mut prev = 0.0;\n        let mut has_uniform_stops = true;\n        let uniform_step = stops[start_index].position.get() - prev;\n        for i in start_index..stops.len() {\n            let curr = if i + 1 == stops.len() {\n                // The last one must be zero.\n                1.0\n            } else {\n                stops[i].position.get().bound(prev, 1.0)\n            };\n\n            has_uniform_stops &= uniform_step.is_nearly_equal(curr - prev);\n            stops[i].position = NormalizedF32::new_clamped(curr);\n            prev = curr;\n        }\n\n        Gradient {\n            stops,\n            tile_mode,\n            transform,\n            points_to_unit,\n            colors_are_opaque,\n            has_uniform_stops,\n        }\n    }\n\n    pub fn push_stages(\n        &self,\n        p: &mut RasterPipelineBuilder,\n        push_stages_pre: &dyn Fn(&mut RasterPipelineBuilder),\n        push_stages_post: &dyn Fn(&mut RasterPipelineBuilder),\n    ) -> bool {\n        p.push(pipeline::Stage::SeedShader);\n\n        let ts = match self.transform.invert() {\n            Some(v) => v,\n            None => {\n                log::warn!(\"failed to invert a gradient transform. Nothing will be rendered\");\n                return false;\n            }\n        };\n        let ts = ts.post_concat(self.points_to_unit);\n        p.push_transform(ts);\n\n        push_stages_pre(p);\n\n        match self.tile_mode {\n            SpreadMode::Reflect => {\n                p.push(pipeline::Stage::ReflectX1);\n            }\n            SpreadMode::Repeat => {\n                p.push(pipeline::Stage::RepeatX1);\n            }\n            SpreadMode::Pad => {\n                if self.has_uniform_stops {\n                    // We clamp only when the stops are evenly spaced.\n                    // If not, there may be hard stops, and clamping ruins hard stops at 0 and/or 1.\n                    // In that case, we must make sure we're using the general \"gradient\" stage,\n                    // which is the only stage that will correctly handle unclamped t.\n                    p.push(pipeline::Stage::PadX1);\n                }\n            }\n        }\n\n        // The two-stop case with stops at 0 and 1.\n        if self.stops.len() == 2 {\n            debug_assert!(self.has_uniform_stops);\n\n            let c0 = self.stops[0].color;\n            let c1 = self.stops[1].color;\n\n            p.ctx.evenly_spaced_2_stop_gradient = EvenlySpaced2StopGradientCtx {\n                factor: GradientColor::new(\n                    c1.red() - c0.red(),\n                    c1.green() - c0.green(),\n                    c1.blue() - c0.blue(),\n                    c1.alpha() - c0.alpha(),\n                ),\n                bias: GradientColor::from(c0),\n            };\n\n            p.push(pipeline::Stage::EvenlySpaced2StopGradient);\n        } else {\n            // Unlike Skia, we do not support the `evenly_spaced_gradient` stage.\n            // In our case, there is no performance difference.\n\n            let mut ctx = GradientCtx::default();\n\n            // Note: In order to handle clamps in search, the search assumes\n            // a stop conceptually placed at -inf.\n            // Therefore, the max number of stops is `self.points.len()+1`.\n            //\n            // We also need at least 16 values for lowp pipeline.\n            ctx.factors.reserve((self.stops.len() + 1).max(16));\n            ctx.biases.reserve((self.stops.len() + 1).max(16));\n\n            ctx.t_values.reserve(self.stops.len() + 1);\n\n            // Remove the dummy stops inserted by Gradient::new\n            // because they are naturally handled by the search method.\n            let (first_stop, last_stop) = if self.stops.len() > 2 {\n                let first = if self.stops[0].color != self.stops[1].color {\n                    0\n                } else {\n                    1\n                };\n\n                let len = self.stops.len();\n                let last = if self.stops[len - 2].color != self.stops[len - 1].color {\n                    len - 1\n                } else {\n                    len - 2\n                };\n                (first, last)\n            } else {\n                (0, 1)\n            };\n\n            let mut t_l = self.stops[first_stop].position.get();\n            let mut c_l = GradientColor::from(self.stops[first_stop].color);\n            ctx.push_const_color(c_l);\n            ctx.t_values.push(NormalizedF32::ZERO);\n            // N.B. lastStop is the index of the last stop, not one after.\n            for i in first_stop..last_stop {\n                let t_r = self.stops[i + 1].position.get();\n                let c_r = GradientColor::from(self.stops[i + 1].color);\n                debug_assert!(t_l <= t_r);\n                if t_l < t_r {\n                    // For each stop we calculate a bias B and a scale factor F, such that\n                    // for any t between stops n and n+1, the color we want is B[n] + F[n]*t.\n                    let f = GradientColor::new(\n                        (c_r.r - c_l.r) / (t_r - t_l),\n                        (c_r.g - c_l.g) / (t_r - t_l),\n                        (c_r.b - c_l.b) / (t_r - t_l),\n                        (c_r.a - c_l.a) / (t_r - t_l),\n                    );\n                    ctx.factors.push(f);\n\n                    ctx.biases.push(GradientColor::new(\n                        c_l.r - f.r * t_l,\n                        c_l.g - f.g * t_l,\n                        c_l.b - f.b * t_l,\n                        c_l.a - f.a * t_l,\n                    ));\n\n                    ctx.t_values.push(NormalizedF32::new_clamped(t_l));\n                }\n\n                t_l = t_r;\n                c_l = c_r;\n            }\n\n            ctx.push_const_color(c_l);\n            ctx.t_values.push(NormalizedF32::new_clamped(t_l));\n\n            ctx.len = ctx.factors.len();\n\n            // All lists must have the same length.\n            debug_assert_eq!(ctx.factors.len(), ctx.t_values.len());\n            debug_assert_eq!(ctx.biases.len(), ctx.t_values.len());\n\n            // Will with zeros until we have enough data to fit into F32x16.\n            while ctx.factors.len() < 16 {\n                ctx.factors.push(GradientColor::default());\n                ctx.biases.push(GradientColor::default());\n            }\n\n            p.push(pipeline::Stage::Gradient);\n            p.ctx.gradient = ctx;\n        }\n\n        if !self.colors_are_opaque {\n            p.push(pipeline::Stage::Premultiply);\n        }\n\n        push_stages_post(p);\n\n        true\n    }\n\n    pub fn apply_opacity(&mut self, opacity: f32) {\n        for stop in &mut self.stops {\n            stop.color.apply_opacity(opacity);\n        }\n\n        self.colors_are_opaque = self.stops.iter().all(|p| p.color.is_opaque());\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/shaders/linear_gradient.rs",
      "sha256": "2d101e497d51e431f8d31fbf343d0e6eedfad0a1d42d0dcd1b75e742f456bb53",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse alloc::vec::Vec;\n\nuse tiny_skia_path::Scalar;\n\nuse crate::{Color, GradientStop, Point, Shader, SpreadMode, Transform};\n\nuse super::gradient::{Gradient, DEGENERATE_THRESHOLD};\nuse crate::pipeline::RasterPipelineBuilder;\n\n/// A linear gradient shader.\n#[derive(Clone, PartialEq, Debug)]\npub struct LinearGradient {\n    pub(crate) base: Gradient,\n}\n\nimpl LinearGradient {\n    /// Creates a new linear gradient shader.\n    ///\n    /// Returns `Shader::SolidColor` when:\n    /// - `stops.len()` == 1\n    /// - `start` and `end` are very close\n    ///\n    /// Returns `None` when:\n    ///\n    /// - `stops` is empty\n    /// - `start` == `end`\n    /// - `transform` is not invertible\n    #[allow(clippy::new_ret_no_self)]\n    pub fn new(\n        start: Point,\n        end: Point,\n        stops: Vec<GradientStop>,\n        mode: SpreadMode,\n        transform: Transform,\n    ) -> Option<Shader<'static>> {\n        if stops.is_empty() {\n            return None;\n        }\n\n        if stops.len() == 1 {\n            return Some(Shader::SolidColor(stops[0].color));\n        }\n\n        let length = (end - start).length();\n        if !length.is_finite() {\n            return None;\n        }\n\n        if length.is_nearly_zero_within_tolerance(DEGENERATE_THRESHOLD) {\n            // Degenerate gradient, the only tricky complication is when in clamp mode,\n            // the limit of the gradient approaches two half planes of solid color\n            // (first and last). However, they are divided by the line perpendicular\n            // to the start and end point, which becomes undefined once start and end\n            // are exactly the same, so just use the end color for a stable solution.\n\n            // Except for special circumstances of clamped gradients,\n            // every gradient shape (when degenerate) can be mapped to the same fallbacks.\n            // The specific shape factories must account for special clamped conditions separately,\n            // this will always return the last color for clamped gradients.\n            match mode {\n                SpreadMode::Pad => {\n                    // Depending on how the gradient shape degenerates,\n                    // there may be a more specialized fallback representation\n                    // for the factories to use, but this is a reasonable default.\n                    return Some(Shader::SolidColor(stops.last().unwrap().color));\n                }\n                SpreadMode::Reflect | SpreadMode::Repeat => {\n                    // repeat and mirror are treated the same: the border colors are never visible,\n                    // but approximate the final color as infinite repetitions of the colors, so\n                    // it can be represented as the average color of the gradient.\n                    return Some(Shader::SolidColor(average_gradient_color(&stops)));\n                }\n            }\n        }\n\n        transform.invert()?;\n\n        let unit_ts = points_to_unit_ts(start, end)?;\n        Some(Shader::LinearGradient(LinearGradient {\n            base: Gradient::new(stops, mode, transform, unit_ts),\n        }))\n    }\n\n    pub(crate) fn is_opaque(&self) -> bool {\n        self.base.colors_are_opaque\n    }\n\n    pub(crate) fn push_stages(&self, p: &mut RasterPipelineBuilder) -> bool {\n        self.base.push_stages(p, &|_| {}, &|_| {})\n    }\n}\n\nfn points_to_unit_ts(start: Point, end: Point) -> Option<Transform> {\n    let mut vec = end - start;\n    let mag = vec.length();\n    let inv = if mag != 0.0 { mag.invert() } else { 0.0 };\n\n    vec.scale(inv);\n\n    let mut ts = ts_from_sin_cos_at(-vec.y, vec.x, start.x, start.y);\n    ts = ts.post_translate(-start.x, -start.y);\n    ts = ts.post_scale(inv, inv);\n    Some(ts)\n}\n\nfn average_gradient_color(points: &[GradientStop]) -> Color {\n    use crate::wide::f32x4;\n\n    fn load_color(c: Color) -> f32x4 {\n        f32x4::from([c.red(), c.green(), c.blue(), c.alpha()])\n    }\n\n    fn store_color(c: f32x4) -> Color {\n        let c: [f32; 4] = c.into();\n        Color::from_rgba(c[0], c[1], c[2], c[3]).unwrap()\n    }\n\n    assert!(!points.is_empty());\n\n    // The gradient is a piecewise linear interpolation between colors. For a given interval,\n    // the integral between the two endpoints is 0.5 * (ci + cj) * (pj - pi), which provides that\n    // intervals average color. The overall average color is thus the sum of each piece. The thing\n    // to keep in mind is that the provided gradient definition may implicitly use p=0 and p=1.\n    let mut blend = f32x4::splat(0.0);\n\n    // Bake 1/(colorCount - 1) uniform stop difference into this scale factor\n    let w_scale = f32x4::splat(0.5);\n\n    for i in 0..points.len() - 1 {\n        // Calculate the average color for the interval between pos(i) and pos(i+1)\n        let c0 = load_color(points[i].color);\n        let c1 = load_color(points[i + 1].color);\n        // when pos == null, there are colorCount uniformly distributed stops, going from 0 to 1,\n        // so pos[i + 1] - pos[i] = 1/(colorCount-1)\n        let w = points[i + 1].position.get() - points[i].position.get();\n        blend += w_scale * f32x4::splat(w) * (c1 + c0);\n    }\n\n    // Now account for any implicit intervals at the start or end of the stop definitions\n    if points[0].position.get() > 0.0 {\n        // The first color is fixed between p = 0 to pos[0], so 0.5 * (ci + cj) * (pj - pi)\n        // becomes 0.5 * (c + c) * (pj - 0) = c * pj\n        let c = load_color(points[0].color);\n        blend += f32x4::splat(points[0].position.get()) * c;\n    }\n\n    let last_idx = points.len() - 1;\n    if points[last_idx].position.get() < 1.0 {\n        // The last color is fixed between pos[n-1] to p = 1, so 0.5 * (ci + cj) * (pj - pi)\n        // becomes 0.5 * (c + c) * (1 - pi) = c * (1 - pi)\n        let c = load_color(points[last_idx].color);\n        blend += (f32x4::splat(1.0) - f32x4::splat(points[last_idx].position.get())) * c;\n    }\n\n    store_color(blend)\n}\n\nfn ts_from_sin_cos_at(sin: f32, cos: f32, px: f32, py: f32) -> Transform {\n    let cos_inv = 1.0 - cos;\n    Transform::from_row(\n        cos,\n        sin,\n        -sin,\n        cos,\n        sdot(sin, py, cos_inv, px),\n        sdot(-sin, px, cos_inv, py),\n    )\n}\n\nfn sdot(a: f32, b: f32, c: f32, d: f32) -> f32 {\n    a * b + c * d\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/shaders/mod.rs",
      "sha256": "05b9d88de14df33ad56122bd03ceb717abf2d4223609c58d6b28b49bba214d62",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nmod gradient;\nmod linear_gradient;\nmod pattern;\nmod radial_gradient;\n\nuse tiny_skia_path::{NormalizedF32, Scalar};\n\npub use gradient::GradientStop;\npub use linear_gradient::LinearGradient;\npub use pattern::{FilterQuality, Pattern, PixmapPaint};\npub use radial_gradient::RadialGradient;\n\nuse crate::{Color, Transform};\n\nuse crate::pipeline::RasterPipelineBuilder;\n\n/// A shader spreading mode.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub enum SpreadMode {\n    /// Replicate the edge color if the shader draws outside of its\n    /// original bounds.\n    Pad,\n\n    /// Repeat the shader's image horizontally and vertically, alternating\n    /// mirror images so that adjacent images always seam.\n    Reflect,\n\n    /// Repeat the shader's image horizontally and vertically.\n    Repeat,\n}\n\nimpl Default for SpreadMode {\n    fn default() -> Self {\n        SpreadMode::Pad\n    }\n}\n\n/// A shader specifies the source color(s) for what is being drawn.\n///\n/// If a paint has no shader, then the paint's color is used. If the paint has a\n/// shader, then the shader's color(s) are use instead, but they are\n/// modulated by the paint's alpha. This makes it easy to create a shader\n/// once (e.g. bitmap tiling or gradient) and then change its transparency\n/// without having to modify the original shader. Only the paint's alpha needs\n/// to be modified.\n#[derive(Clone, PartialEq, Debug)]\npub enum Shader<'a> {\n    /// A solid color shader.\n    SolidColor(Color),\n    /// A linear gradient shader.\n    LinearGradient(LinearGradient),\n    /// A radial gradient shader.\n    RadialGradient(RadialGradient),\n    /// A pattern shader.\n    Pattern(Pattern<'a>),\n}\n\nimpl<'a> Shader<'a> {\n    /// Checks if the shader is guaranteed to produce only opaque colors.\n    pub fn is_opaque(&self) -> bool {\n        match self {\n            Shader::SolidColor(ref c) => c.is_opaque(),\n            Shader::LinearGradient(ref g) => g.is_opaque(),\n            Shader::RadialGradient(_) => false,\n            Shader::Pattern(_) => false,\n        }\n    }\n\n    // Unlike Skia, we do not have is_constant, because we don't have Color shaders.\n\n    /// If this returns false, then we draw nothing (do not fall back to shader context)\n    #[must_use]\n    pub(crate) fn push_stages(&self, p: &mut RasterPipelineBuilder) -> bool {\n        match self {\n            Shader::SolidColor(color) => {\n                p.push_uniform_color(color.premultiply());\n                true\n            }\n            Shader::LinearGradient(ref g) => g.push_stages(p),\n            Shader::RadialGradient(ref g) => g.push_stages(p),\n            Shader::Pattern(ref patt) => patt.push_stages(p),\n        }\n    }\n\n    /// Transforms the shader.\n    pub fn transform(&mut self, ts: Transform) {\n        match self {\n            Shader::SolidColor(_) => {}\n            Shader::LinearGradient(g) => {\n                g.base.transform = g.base.transform.post_concat(ts);\n            }\n            Shader::RadialGradient(g) => {\n                g.base.transform = g.base.transform.post_concat(ts);\n            }\n            Shader::Pattern(p) => {\n                p.transform = p.transform.post_concat(ts);\n            }\n        }\n    }\n\n    /// Shifts shader's opacity.\n    ///\n    /// `opacity` will be clamped to the 0..=1 range.\n    ///\n    /// This is roughly the same as Skia's `SkPaint::setAlpha`.\n    ///\n    /// Unlike Skia, we do not support global alpha/opacity, which is in Skia\n    /// is set via the alpha channel of the `SkPaint::fColor4f`.\n    /// Instead, you can shift the opacity of the shader to whatever value you need.\n    ///\n    /// - For `SolidColor` this function will multiply `color.alpha` by `opacity`.\n    /// - For gradients this function will multiply all colors by `opacity`.\n    /// - For `Pattern` this function will multiply `Patter::opacity` by `opacity`.\n    pub fn apply_opacity(&mut self, opacity: f32) {\n        match self {\n            Shader::SolidColor(ref mut c) => {\n                c.apply_opacity(opacity);\n            }\n            Shader::LinearGradient(g) => {\n                g.base.apply_opacity(opacity);\n            }\n            Shader::RadialGradient(g) => {\n                g.base.apply_opacity(opacity);\n            }\n            Shader::Pattern(ref mut p) => {\n                p.opacity = NormalizedF32::new(p.opacity.get() * opacity.bound(0.0, 1.0)).unwrap();\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/shaders/pattern.rs",
      "sha256": "96865d92752b85b20024f5aa81d36239efdb606224aa6e23c180125b0d2be1ab",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse tiny_skia_path::NormalizedF32;\n\nuse crate::{BlendMode, PixmapRef, Shader, SpreadMode, Transform};\n\nuse crate::pipeline;\nuse crate::pipeline::RasterPipelineBuilder;\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\n/// Controls how much filtering to be done when transforming images.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub enum FilterQuality {\n    /// Nearest-neighbor. Low quality, but fastest.\n    Nearest,\n    /// Bilinear.\n    Bilinear,\n    /// Bicubic. High quality, but slow.\n    Bicubic,\n}\n\n/// Controls how a pixmap should be blended.\n///\n/// Like `Paint`, but for `Pixmap`.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub struct PixmapPaint {\n    /// Pixmap opacity.\n    ///\n    /// Must be in 0..=1 range.\n    ///\n    /// Default: 1.0\n    pub opacity: f32,\n\n    /// Pixmap blending mode.\n    ///\n    /// Default: SourceOver\n    pub blend_mode: BlendMode,\n\n    /// Specifies how much filtering to be done when transforming images.\n    ///\n    /// Default: Nearest\n    pub quality: FilterQuality,\n}\n\nimpl Default for PixmapPaint {\n    fn default() -> Self {\n        PixmapPaint {\n            opacity: 1.0,\n            blend_mode: BlendMode::default(),\n            quality: FilterQuality::Nearest,\n        }\n    }\n}\n\n/// A pattern shader.\n///\n/// Essentially a `SkImageShader`.\n///\n/// Unlike Skia, we do not support FilterQuality::Medium, because it involves\n/// mipmap generation, which adds too much complexity.\n#[derive(Clone, PartialEq, Debug)]\npub struct Pattern<'a> {\n    pub(crate) pixmap: PixmapRef<'a>,\n    quality: FilterQuality,\n    spread_mode: SpreadMode,\n    pub(crate) opacity: NormalizedF32,\n    pub(crate) transform: Transform,\n}\n\nimpl<'a> Pattern<'a> {\n    /// Creates a new pattern shader.\n    ///\n    /// `opacity` will be clamped to the 0..=1 range.\n    #[allow(clippy::new_ret_no_self)]\n    pub fn new(\n        pixmap: PixmapRef<'a>,\n        spread_mode: SpreadMode,\n        quality: FilterQuality,\n        opacity: f32,\n        transform: Transform,\n    ) -> Shader {\n        Shader::Pattern(Pattern {\n            pixmap,\n            spread_mode,\n            quality,\n            opacity: NormalizedF32::new_clamped(opacity),\n            transform,\n        })\n    }\n\n    pub(crate) fn push_stages(&self, p: &mut RasterPipelineBuilder) -> bool {\n        let ts = match self.transform.invert() {\n            Some(v) => v,\n            None => {\n                log::warn!(\"failed to invert a pattern transform. Nothing will be rendered\");\n                return false;\n            }\n        };\n\n        p.push(pipeline::Stage::SeedShader);\n\n        p.push_transform(ts);\n\n        let mut quality = self.quality;\n\n        if ts.is_identity() || ts.is_translate() {\n            quality = FilterQuality::Nearest;\n        }\n\n        if quality == FilterQuality::Bilinear {\n            if ts.is_translate() {\n                if ts.tx == ts.tx.trunc() && ts.ty == ts.ty.trunc() {\n                    // When the matrix is just an integer translate, bilerp == nearest neighbor.\n                    quality = FilterQuality::Nearest;\n                }\n            }\n        }\n\n        // TODO: minimizing scale via mipmap\n\n        match quality {\n            FilterQuality::Nearest => {\n                p.ctx.limit_x = pipeline::TileCtx {\n                    scale: self.pixmap.width() as f32,\n                    inv_scale: 1.0 / self.pixmap.width() as f32,\n                };\n\n                p.ctx.limit_y = pipeline::TileCtx {\n                    scale: self.pixmap.height() as f32,\n                    inv_scale: 1.0 / self.pixmap.height() as f32,\n                };\n\n                match self.spread_mode {\n                    SpreadMode::Pad => { /* The gather() stage will clamp for us. */ }\n                    SpreadMode::Repeat => p.push(pipeline::Stage::Repeat),\n                    SpreadMode::Reflect => p.push(pipeline::Stage::Reflect),\n                }\n\n                p.push(pipeline::Stage::Gather);\n            }\n            FilterQuality::Bilinear => {\n                p.ctx.sampler = pipeline::SamplerCtx {\n                    spread_mode: self.spread_mode,\n                    inv_width: 1.0 / self.pixmap.width() as f32,\n                    inv_height: 1.0 / self.pixmap.height() as f32,\n                };\n                p.push(pipeline::Stage::Bilinear);\n            }\n            FilterQuality::Bicubic => {\n                p.ctx.sampler = pipeline::SamplerCtx {\n                    spread_mode: self.spread_mode,\n                    inv_width: 1.0 / self.pixmap.width() as f32,\n                    inv_height: 1.0 / self.pixmap.height() as f32,\n                };\n                p.push(pipeline::Stage::Bicubic);\n\n                // Bicubic filtering naturally produces out of range values on both sides of [0,1].\n                p.push(pipeline::Stage::Clamp0);\n                p.push(pipeline::Stage::ClampA);\n            }\n        }\n\n        // Unlike Skia, we do not support global opacity and only Pattern allows it.\n        if self.opacity != NormalizedF32::ONE {\n            debug_assert_eq!(\n                core::mem::size_of_val(&self.opacity),\n                4,\n                \"alpha must be f32\"\n            );\n            p.ctx.current_coverage = self.opacity.get();\n            p.push(pipeline::Stage::Scale1Float);\n        }\n\n        true\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/shaders/radial_gradient.rs",
      "sha256": "ddcd5026ccfa12dc5277e65180511698b2a2db54351032cb7a8cd2e85c84f648",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse alloc::vec::Vec;\n\nuse tiny_skia_path::Scalar;\n\nuse crate::{GradientStop, Point, Shader, SpreadMode, Transform};\n\nuse super::gradient::{Gradient, DEGENERATE_THRESHOLD};\nuse crate::pipeline;\nuse crate::pipeline::RasterPipelineBuilder;\nuse crate::wide::u32x8;\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\n#[derive(Copy, Clone, PartialEq, Debug)]\nstruct FocalData {\n    r1: f32, // r1 after mapping focal point to (0, 0)\n}\n\nimpl FocalData {\n    // Whether the focal point (0, 0) is on the end circle with center (1, 0) and radius r1. If\n    // this is true, it's as if an aircraft is flying at Mach 1 and all circles (soundwaves)\n    // will go through the focal point (aircraft). In our previous implementations, this was\n    // known as the edge case where the inside circle touches the outside circle (on the focal\n    // point). If we were to solve for t bruteforcely using a quadratic equation, this case\n    // implies that the quadratic equation degenerates to a linear equation.\n    fn is_focal_on_circle(&self) -> bool {\n        (1.0 - self.r1).is_nearly_zero()\n    }\n\n    fn is_well_behaved(&self) -> bool {\n        !self.is_focal_on_circle() && self.r1 > 1.0\n    }\n}\n\n/// A radial gradient shader.\n///\n/// This is not `SkRadialGradient` like in Skia, but rather `SkTwoPointConicalGradient`\n/// without the start radius.\n#[derive(Clone, PartialEq, Debug)]\npub struct RadialGradient {\n    pub(crate) base: Gradient,\n    focal_data: Option<FocalData>,\n}\n\nimpl RadialGradient {\n    /// Creates a new radial gradient shader.\n    ///\n    /// Returns `Shader::SolidColor` when:\n    /// - `stops.len()` == 1\n    ///\n    /// Returns `None` when:\n    ///\n    /// - `stops` is empty\n    /// - `radius` <= 0\n    /// - `transform` is not invertible\n    #[allow(clippy::new_ret_no_self)]\n    pub fn new(\n        start: Point,\n        end: Point,\n        radius: f32,\n        stops: Vec<GradientStop>,\n        mode: SpreadMode,\n        transform: Transform,\n    ) -> Option<Shader<'static>> {\n        // From SkGradientShader::MakeTwoPointConical\n\n        if radius < 0.0 || radius.is_nearly_zero() {\n            return None;\n        }\n\n        if stops.is_empty() {\n            return None;\n        }\n\n        if stops.len() == 1 {\n            return Some(Shader::SolidColor(stops[0].color));\n        }\n\n        transform.invert()?;\n\n        let length = (end - start).length();\n        if !length.is_finite() {\n            return None;\n        }\n\n        if length.is_nearly_zero_within_tolerance(DEGENERATE_THRESHOLD) {\n            // If the center positions are the same, then the gradient\n            // is the radial variant of a 2 pt conical gradient,\n            // an actual radial gradient (startRadius == 0),\n            // or it is fully degenerate (startRadius == endRadius).\n\n            let inv = radius.invert();\n            let mut ts = Transform::from_translate(-start.x, -start.y);\n            ts = ts.post_scale(inv, inv);\n\n            // We can treat this gradient as radial, which is faster. If we got here, we know\n            // that endRadius is not equal to 0, so this produces a meaningful gradient\n            Some(Shader::RadialGradient(RadialGradient {\n                base: Gradient::new(stops, mode, transform, ts),\n                focal_data: None,\n            }))\n        } else {\n            // From SkTwoPointConicalGradient::Create\n            let mut ts = ts_from_poly_to_poly(\n                start,\n                end,\n                Point::from_xy(0.0, 0.0),\n                Point::from_xy(1.0, 0.0),\n            )?;\n\n            let d_center = (start - end).length();\n            let r1 = radius / d_center;\n            let focal_data = FocalData { r1 };\n\n            // The following transformations are just to accelerate the shader computation by saving\n            // some arithmetic operations.\n            if focal_data.is_focal_on_circle() {\n                ts = ts.post_scale(0.5, 0.5);\n            } else {\n                ts = ts.post_scale(r1 / (r1 * r1 - 1.0), 1.0 / ((r1 * r1 - 1.0).abs()).sqrt());\n            }\n\n            Some(Shader::RadialGradient(RadialGradient {\n                base: Gradient::new(stops, mode, transform, ts),\n                focal_data: Some(focal_data),\n            }))\n        }\n    }\n\n    pub(crate) fn push_stages(&self, p: &mut RasterPipelineBuilder) -> bool {\n        let p0 = if let Some(focal_data) = self.focal_data {\n            1.0 / focal_data.r1\n        } else {\n            1.0\n        };\n\n        p.ctx.two_point_conical_gradient = pipeline::TwoPointConicalGradientCtx {\n            mask: u32x8::default(),\n            p0,\n        };\n\n        self.base.push_stages(\n            p,\n            &|p| {\n                if let Some(focal_data) = self.focal_data {\n                    // Unlike Skia, we have only the Focal radial gradient type.\n\n                    if focal_data.is_focal_on_circle() {\n                        p.push(pipeline::Stage::XYTo2PtConicalFocalOnCircle);\n                    } else if focal_data.is_well_behaved() {\n                        p.push(pipeline::Stage::XYTo2PtConicalWellBehaved);\n                    } else {\n                        p.push(pipeline::Stage::XYTo2PtConicalGreater);\n                    }\n\n                    if !focal_data.is_well_behaved() {\n                        p.push(pipeline::Stage::Mask2PtConicalDegenerates);\n                    }\n                } else {\n                    p.push(pipeline::Stage::XYToRadius);\n                }\n            },\n            &|p| {\n                if let Some(focal_data) = self.focal_data {\n                    if !focal_data.is_well_behaved() {\n                        p.push(pipeline::Stage::ApplyVectorMask);\n                    }\n                }\n            },\n        )\n    }\n}\n\nfn ts_from_poly_to_poly(src1: Point, src2: Point, dst1: Point, dst2: Point) -> Option<Transform> {\n    let tmp = from_poly2(src1, src2);\n    let res = tmp.invert()?;\n    let tmp = from_poly2(dst1, dst2);\n    Some(tmp.pre_concat(res))\n}\n\nfn from_poly2(p0: Point, p1: Point) -> Transform {\n    Transform::from_row(\n        p1.y - p0.y,\n        p0.x - p1.x,\n        p1.x - p0.x,\n        p1.y - p0.y,\n        p0.x,\n        p0.y,\n    )\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/wide/f32x16_t.rs",
      "sha256": "a4907134acfaa60fbc06c324c8595259795fae7aecd740ad268ba439155c38a9",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse super::{f32x8, u16x16};\n\n#[derive(Copy, Clone, Debug)]\n#[repr(C, align(32))]\npub struct f32x16(pub f32x8, pub f32x8);\n\nunsafe impl bytemuck::Zeroable for f32x16 {}\nunsafe impl bytemuck::Pod for f32x16 {}\n\nimpl Default for f32x16 {\n    fn default() -> Self {\n        Self::splat(0.0)\n    }\n}\n\nimpl f32x16 {\n    pub fn splat(n: f32) -> Self {\n        Self(f32x8::splat(n), f32x8::splat(n))\n    }\n\n    #[inline]\n    pub fn abs(&self) -> Self {\n        // Yes, Skia does it in the same way.\n        let abs = |x| bytemuck::cast::<i32, f32>(bytemuck::cast::<f32, i32>(x) & 0x7fffffff);\n\n        let n0: [f32; 8] = self.0.into();\n        let n1: [f32; 8] = self.1.into();\n        Self(\n            f32x8::from([\n                abs(n0[0]),\n                abs(n0[1]),\n                abs(n0[2]),\n                abs(n0[3]),\n                abs(n0[4]),\n                abs(n0[5]),\n                abs(n0[6]),\n                abs(n0[7]),\n            ]),\n            f32x8::from([\n                abs(n1[0]),\n                abs(n1[1]),\n                abs(n1[2]),\n                abs(n1[3]),\n                abs(n1[4]),\n                abs(n1[5]),\n                abs(n1[6]),\n                abs(n1[7]),\n            ]),\n        )\n    }\n\n    pub fn cmp_gt(self, rhs: &Self) -> Self {\n        Self(self.0.cmp_gt(rhs.0), self.1.cmp_gt(rhs.1))\n    }\n\n    pub fn blend(self, t: Self, f: Self) -> Self {\n        Self(self.0.blend(t.0, f.0), self.1.blend(t.1, f.1))\n    }\n\n    pub fn normalize(&self) -> Self {\n        Self(self.0.normalize(), self.1.normalize())\n    }\n\n    pub fn floor(&self) -> Self {\n        // Yes, Skia does it in the same way.\n        let roundtrip = self.round();\n        roundtrip\n            - roundtrip\n                .cmp_gt(self)\n                .blend(f32x16::splat(1.0), f32x16::splat(0.0))\n    }\n\n    pub fn sqrt(&self) -> Self {\n        Self(self.0.sqrt(), self.1.sqrt())\n    }\n\n    pub fn round(&self) -> Self {\n        Self(self.0.round(), self.1.round())\n    }\n\n    // This method is too heavy and shouldn't be inlined.\n    pub fn save_to_u16x16(&self, dst: &mut u16x16) {\n        // Do not use to_i32x8, because it involves rounding,\n        // and Skia cast's without it.\n\n        let n0: [f32; 8] = self.0.into();\n        let n1: [f32; 8] = self.1.into();\n\n        dst.0[0] = n0[0] as u16;\n        dst.0[1] = n0[1] as u16;\n        dst.0[2] = n0[2] as u16;\n        dst.0[3] = n0[3] as u16;\n\n        dst.0[4] = n0[4] as u16;\n        dst.0[5] = n0[5] as u16;\n        dst.0[6] = n0[6] as u16;\n        dst.0[7] = n0[7] as u16;\n\n        dst.0[8] = n1[0] as u16;\n        dst.0[9] = n1[1] as u16;\n        dst.0[10] = n1[2] as u16;\n        dst.0[11] = n1[3] as u16;\n\n        dst.0[12] = n1[4] as u16;\n        dst.0[13] = n1[5] as u16;\n        dst.0[14] = n1[6] as u16;\n        dst.0[15] = n1[7] as u16;\n    }\n}\n\nimpl core::ops::Add<f32x16> for f32x16 {\n    type Output = Self;\n\n    fn add(self, rhs: Self) -> Self::Output {\n        Self(self.0 + rhs.0, self.1 + rhs.1)\n    }\n}\n\nimpl core::ops::Sub<f32x16> for f32x16 {\n    type Output = Self;\n\n    fn sub(self, rhs: Self) -> Self::Output {\n        Self(self.0 - rhs.0, self.1 - rhs.1)\n    }\n}\n\nimpl core::ops::Mul<f32x16> for f32x16 {\n    type Output = Self;\n\n    fn mul(self, rhs: Self) -> Self::Output {\n        Self(self.0 * rhs.0, self.1 * rhs.1)\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/wide/f32x4_t.rs",
      "sha256": "7dc219c8dc68965994de82632d00f34480502096f9a8bafffd63f21f0cd76443",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Based on https://github.com/Lokathor/wide (Zlib)\n\nuse bytemuck::cast;\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse tiny_skia_path::NoStdFloat;\n\nuse super::i32x4;\n\ncfg_if::cfg_if! {\n    if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n        #[cfg(target_arch = \"x86\")]\n        use core::arch::x86::*;\n        #[cfg(target_arch = \"x86_64\")]\n        use core::arch::x86_64::*;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct f32x4(__m128);\n    } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n        use core::arch::wasm32::*;\n\n        // repr(transparent) allows for directly passing the v128 on the WASM stack.\n        #[derive(Clone, Copy, Debug)]\n        #[repr(transparent)]\n        pub struct f32x4(v128);\n    } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n        use core::arch::aarch64::*;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct f32x4(float32x4_t);\n    } else {\n        use super::FasterMinMax;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct f32x4([f32; 4]);\n    }\n}\n\nunsafe impl bytemuck::Zeroable for f32x4 {}\nunsafe impl bytemuck::Pod for f32x4 {}\n\nimpl Default for f32x4 {\n    fn default() -> Self {\n        Self::splat(0.0)\n    }\n}\n\nimpl f32x4 {\n    pub fn splat(n: f32) -> Self {\n        Self::from([n, n, n, n])\n    }\n\n    pub fn floor(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_floor(self.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vrndmq_f32(self.0) })\n            } else {\n                let roundtrip: f32x4 = cast(self.trunc_int().to_f32x4());\n                roundtrip - roundtrip.cmp_gt(self).blend(f32x4::splat(1.0), f32x4::default())\n            }\n        }\n    }\n\n    pub fn abs(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_abs(self.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vabsq_f32(self.0) })\n            } else {\n                let non_sign_bits = f32x4::splat(f32::from_bits(i32::MAX as u32));\n                self & non_sign_bits\n            }\n        }\n    }\n\n    pub fn max(self, rhs: Self) -> Self {\n        // These technically don't have the same semantics for NaN and 0, but it\n        // doesn't seem to matter as Skia does it the same way.\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_max_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_pmax(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vmaxq_f32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0].faster_max(rhs.0[0]),\n                    self.0[1].faster_max(rhs.0[1]),\n                    self.0[2].faster_max(rhs.0[2]),\n                    self.0[3].faster_max(rhs.0[3]),\n                ])\n            }\n        }\n    }\n\n    pub fn min(self, rhs: Self) -> Self {\n        // These technically don't have the same semantics for NaN and 0, but it\n        // doesn't seem to matter as Skia does it the same way.\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_min_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_pmin(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vminq_f32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0].faster_min(rhs.0[0]),\n                    self.0[1].faster_min(rhs.0[1]),\n                    self.0[2].faster_min(rhs.0[2]),\n                    self.0[3].faster_min(rhs.0[3]),\n                ])\n            }\n        }\n    }\n\n    pub fn cmp_eq(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_cmpeq_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_eq(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(cast(unsafe { vceqq_f32(self.0, rhs.0) }))\n            } else {\n                Self([\n                    if self.0[0] == rhs.0[0] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[1] == rhs.0[1] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[2] == rhs.0[2] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[3] == rhs.0[3] { f32::from_bits(u32::MAX) } else { 0.0 },\n                ])\n            }\n        }\n    }\n\n    pub fn cmp_ne(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_cmpneq_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_ne(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(cast(unsafe { vmvnq_u32(vceqq_f32(self.0, rhs.0)) }))\n            } else {\n                Self([\n                    if self.0[0] != rhs.0[0] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[1] != rhs.0[1] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[2] != rhs.0[2] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[3] != rhs.0[3] { f32::from_bits(u32::MAX) } else { 0.0 },\n                ])\n            }\n        }\n    }\n\n    pub fn cmp_ge(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_cmpge_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_ge(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(cast(unsafe { vcgeq_f32(self.0, rhs.0) }))\n            } else {\n                Self([\n                    if self.0[0] >= rhs.0[0] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[1] >= rhs.0[1] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[2] >= rhs.0[2] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[3] >= rhs.0[3] { f32::from_bits(u32::MAX) } else { 0.0 },\n                ])\n            }\n        }\n    }\n\n    pub fn cmp_gt(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_cmpgt_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_gt(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(cast(unsafe { vcgtq_f32(self.0, rhs.0) }))\n            } else {\n                Self([\n                    if self.0[0] > rhs.0[0] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[1] > rhs.0[1] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[2] > rhs.0[2] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[3] > rhs.0[3] { f32::from_bits(u32::MAX) } else { 0.0 },\n                ])\n            }\n        }\n    }\n\n    pub fn cmp_le(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_cmple_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_le(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(cast(unsafe { vcleq_f32(self.0, rhs.0) }))\n            } else {\n                Self([\n                    if self.0[0] <= rhs.0[0] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[1] <= rhs.0[1] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[2] <= rhs.0[2] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[3] <= rhs.0[3] { f32::from_bits(u32::MAX) } else { 0.0 },\n                ])\n            }\n        }\n    }\n\n    pub fn cmp_lt(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_cmplt_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_lt(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(cast(unsafe { vcltq_f32(self.0, rhs.0) }))\n            } else {\n                Self([\n                    if self.0[0] < rhs.0[0] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[1] < rhs.0[1] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[2] < rhs.0[2] { f32::from_bits(u32::MAX) } else { 0.0 },\n                    if self.0[3] < rhs.0[3] { f32::from_bits(u32::MAX) } else { 0.0 },\n                ])\n            }\n        }\n    }\n\n    #[inline]\n    pub fn blend(self, t: Self, f: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse4.1\"))] {\n                Self(unsafe { _mm_blendv_ps(f.0, t.0, self.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_bitselect(t.0, f.0, self.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { cast(vbslq_u32( cast(self.0), cast(t.0), cast(f.0))) })\n            } else {\n                super::generic_bit_blend(self, t, f)\n            }\n        }\n    }\n\n    pub fn round(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse4.1\"))] {\n                Self(\n                    unsafe { _mm_round_ps(self.0, _MM_FROUND_NO_EXC | _MM_FROUND_TO_NEAREST_INT) },\n                )\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_nearest(self.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vrndnq_f32(self.0) })\n            } else {\n                use super::u32x4;\n\n                let to_int = f32x4::splat(1.0 / f32::EPSILON);\n                let u: u32x4 = cast(self);\n                let e: i32x4 = cast(u.shr::<23>() & u32x4::splat(0xff));\n                let mut y: f32x4;\n\n                let no_op_magic = i32x4::splat(0x7f + 23);\n                let no_op_mask: f32x4 = cast(e.cmp_gt(no_op_magic) | e.cmp_eq(no_op_magic));\n                let no_op_val: f32x4 = self;\n\n                let zero_magic = i32x4::splat(0x7f - 1);\n                let zero_mask: f32x4 = cast(e.cmp_lt(zero_magic));\n                let zero_val: f32x4 = self * f32x4::splat(0.0);\n\n                let neg_bit: f32x4 = cast(cast::<u32x4, i32x4>(u).cmp_lt(i32x4::default()));\n                let x: f32x4 = neg_bit.blend(-self, self);\n                y = x + to_int - to_int - x;\n                y = y.cmp_gt(f32x4::splat(0.5)).blend(\n                    y + x - f32x4::splat(-1.0),\n                    y.cmp_lt(f32x4::splat(-0.5)).blend(y + x + f32x4::splat(1.0), y + x),\n                );\n                y = neg_bit.blend(-y, y);\n\n                no_op_mask.blend(no_op_val, zero_mask.blend(zero_val, y))\n            }\n        }\n    }\n\n    pub fn round_int(self) -> i32x4 {\n        // These technically don't have the same semantics for NaN and out of\n        // range values, but it doesn't seem to matter as Skia does it the same\n        // way.\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                i32x4(unsafe { _mm_cvtps_epi32(self.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                i32x4(i32x4_trunc_sat_f32x4(self.round().0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                i32x4(unsafe { vcvtnq_s32_f32(self.0) } )\n            } else {\n                let rounded: [f32; 4] = cast(self.round());\n                cast([\n                    rounded[0] as i32,\n                    rounded[1] as i32,\n                    rounded[2] as i32,\n                    rounded[3] as i32,\n                ])\n            }\n        }\n    }\n\n    pub fn trunc_int(self) -> i32x4 {\n        // These technically don't have the same semantics for NaN and out of\n        // range values, but it doesn't seem to matter as Skia does it the same\n        // way.\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                i32x4(unsafe { _mm_cvttps_epi32(self.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                i32x4(i32x4_trunc_sat_f32x4(self.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                i32x4(unsafe { vcvtq_s32_f32(self.0) })\n            } else {\n                cast([\n                    self.0[0] as i32,\n                    self.0[1] as i32,\n                    self.0[2] as i32,\n                    self.0[3] as i32,\n                ])\n            }\n        }\n    }\n\n    pub fn recip_fast(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_rcp_ps(self.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_div(f32x4_splat(1.0), self.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                unsafe {\n                    let a = vrecpeq_f32(self.0);\n                    let a = vmulq_f32(vrecpsq_f32(self.0, a), a);\n                    Self(a)\n                }\n            } else {\n                Self::from([\n                    1.0 / self.0[0],\n                    1.0 / self.0[1],\n                    1.0 / self.0[2],\n                    1.0 / self.0[3],\n                ])\n            }\n        }\n    }\n\n    pub fn recip_sqrt(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_rsqrt_ps(self.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_div(f32x4_splat(1.0), f32x4_sqrt(self.0)))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                unsafe {\n                    let a = vrsqrteq_f32(self.0);\n                    let a = vmulq_f32(vrsqrtsq_f32(self.0, vmulq_f32(a, a)), a);\n                    Self(a)\n                }\n            } else {\n                Self::from([\n                    1.0 / self.0[0].sqrt(),\n                    1.0 / self.0[1].sqrt(),\n                    1.0 / self.0[2].sqrt(),\n                    1.0 / self.0[3].sqrt(),\n                ])\n            }\n        }\n    }\n\n    pub fn sqrt(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_sqrt_ps(self.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_sqrt(self.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vsqrtq_f32(self.0) })\n            } else {\n                Self::from([\n                    self.0[0].sqrt(),\n                    self.0[1].sqrt(),\n                    self.0[2].sqrt(),\n                    self.0[3].sqrt(),\n                ])\n            }\n        }\n    }\n}\n\nimpl From<[f32; 4]> for f32x4 {\n    fn from(v: [f32; 4]) -> Self {\n        cast(v)\n    }\n}\n\nimpl From<f32x4> for [f32; 4] {\n    fn from(v: f32x4) -> Self {\n        cast(v)\n    }\n}\n\nimpl core::ops::Add for f32x4 {\n    type Output = Self;\n\n    fn add(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_add_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_add(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vaddq_f32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0] + rhs.0[0],\n                    self.0[1] + rhs.0[1],\n                    self.0[2] + rhs.0[2],\n                    self.0[3] + rhs.0[3],\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::AddAssign for f32x4 {\n    fn add_assign(&mut self, rhs: f32x4) {\n        *self = *self + rhs;\n    }\n}\n\nimpl core::ops::Sub for f32x4 {\n    type Output = Self;\n\n    fn sub(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_sub_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_sub(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vsubq_f32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0] - rhs.0[0],\n                    self.0[1] - rhs.0[1],\n                    self.0[2] - rhs.0[2],\n                    self.0[3] - rhs.0[3],\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::Mul for f32x4 {\n    type Output = Self;\n\n    fn mul(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_mul_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_mul(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vmulq_f32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0] * rhs.0[0],\n                    self.0[1] * rhs.0[1],\n                    self.0[2] * rhs.0[2],\n                    self.0[3] * rhs.0[3],\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::MulAssign for f32x4 {\n    fn mul_assign(&mut self, rhs: f32x4) {\n        *self = *self * rhs;\n    }\n}\n\nimpl core::ops::Div for f32x4 {\n    type Output = Self;\n\n    fn div(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_div_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(f32x4_div(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vdivq_f32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0] / rhs.0[0],\n                    self.0[1] / rhs.0[1],\n                    self.0[2] / rhs.0[2],\n                    self.0[3] / rhs.0[3],\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::BitAnd for f32x4 {\n    type Output = Self;\n\n    #[inline(always)]\n    fn bitand(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_and_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_and(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(cast(unsafe { vandq_u32(cast(self.0), cast(rhs.0)) }))\n            } else {\n                Self([\n                    f32::from_bits(self.0[0].to_bits() & rhs.0[0].to_bits()),\n                    f32::from_bits(self.0[1].to_bits() & rhs.0[1].to_bits()),\n                    f32::from_bits(self.0[2].to_bits() & rhs.0[2].to_bits()),\n                    f32::from_bits(self.0[3].to_bits() & rhs.0[3].to_bits()),\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::BitOr for f32x4 {\n    type Output = Self;\n\n    #[inline(always)]\n    fn bitor(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_or_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_or(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(cast(unsafe { vorrq_u32(cast(self.0), cast(rhs.0)) }))\n            } else {\n                Self([\n                    f32::from_bits(self.0[0].to_bits() | rhs.0[0].to_bits()),\n                    f32::from_bits(self.0[1].to_bits() | rhs.0[1].to_bits()),\n                    f32::from_bits(self.0[2].to_bits() | rhs.0[2].to_bits()),\n                    f32::from_bits(self.0[3].to_bits() | rhs.0[3].to_bits()),\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::BitXor for f32x4 {\n    type Output = Self;\n\n    #[inline(always)]\n    fn bitxor(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_xor_ps(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_xor(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(cast(unsafe { veorq_u32(cast(self.0), cast(rhs.0)) }))\n            } else {\n                Self([\n                    f32::from_bits(self.0[0].to_bits() ^ rhs.0[0].to_bits()),\n                    f32::from_bits(self.0[1].to_bits() ^ rhs.0[1].to_bits()),\n                    f32::from_bits(self.0[2].to_bits() ^ rhs.0[2].to_bits()),\n                    f32::from_bits(self.0[3].to_bits() ^ rhs.0[3].to_bits()),\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::Neg for f32x4 {\n    type Output = Self;\n\n    fn neg(self) -> Self {\n        Self::default() - self\n    }\n}\n\nimpl core::ops::Not for f32x4 {\n    type Output = Self;\n\n    fn not(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                unsafe {\n                    let all_bits = _mm_set1_ps(f32::from_bits(u32::MAX));\n                    Self(_mm_xor_ps(self.0, all_bits))\n                }\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_not(self.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(cast(unsafe { vmvnq_u32(cast(self.0)) }))\n            } else {\n                self ^ Self::splat(cast(u32::MAX))\n            }\n        }\n    }\n}\n\nimpl core::cmp::PartialEq for f32x4 {\n    fn eq(&self, rhs: &Self) -> bool {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                unsafe { _mm_movemask_ps(_mm_cmpeq_ps(self.0, rhs.0)) == 0b1111 }\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                unsafe { vminvq_u32(vceqq_f32(self.0, rhs.0)) != 0 }\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                u32x4_all_true(f32x4_eq(self.0, rhs.0))\n            } else {\n                self.0 == rhs.0\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/wide/f32x8_t.rs",
      "sha256": "661777a07ae3bc2aad17228b067d75bb8674eebefae966bb37fff08819896104",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Based on https://github.com/Lokathor/wide (Zlib)\n\nuse bytemuck::cast;\n\nuse super::{i32x8, u32x8};\n\ncfg_if::cfg_if! {\n    if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n        #[cfg(target_arch = \"x86\")]\n        use core::arch::x86::*;\n        #[cfg(target_arch = \"x86_64\")]\n        use core::arch::x86_64::*;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(32))]\n        pub struct f32x8(__m256);\n    } else {\n        use super::f32x4;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(32))]\n        pub struct f32x8(pub f32x4, pub f32x4);\n    }\n}\n\nunsafe impl bytemuck::Zeroable for f32x8 {}\nunsafe impl bytemuck::Pod for f32x8 {}\n\nimpl Default for f32x8 {\n    fn default() -> Self {\n        Self::splat(0.0)\n    }\n}\n\nimpl f32x8 {\n    pub fn splat(n: f32) -> Self {\n        cast([n, n, n, n, n, n, n, n])\n    }\n\n    pub fn floor(self) -> Self {\n        let roundtrip: f32x8 = cast(self.trunc_int().to_f32x8());\n        roundtrip\n            - roundtrip\n                .cmp_gt(self)\n                .blend(f32x8::splat(1.0), f32x8::default())\n    }\n\n    pub fn fract(self) -> Self {\n        self - self.floor()\n    }\n\n    pub fn normalize(self) -> Self {\n        self.max(f32x8::default()).min(f32x8::splat(1.0))\n    }\n\n    pub fn to_i32x8_bitcast(self) -> i32x8 {\n        bytemuck::cast(self)\n    }\n\n    pub fn to_u32x8_bitcast(self) -> u32x8 {\n        bytemuck::cast(self)\n    }\n\n    pub fn cmp_eq(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_cmp_ps(self.0, rhs.0, _CMP_EQ_OQ) })\n            } else {\n                Self(self.0.cmp_eq(rhs.0), self.1.cmp_eq(rhs.1))\n            }\n        }\n    }\n\n    pub fn cmp_ne(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_cmp_ps(self.0, rhs.0, _CMP_NEQ_OQ) })\n            } else {\n                Self(self.0.cmp_ne(rhs.0), self.1.cmp_ne(rhs.1))\n            }\n        }\n    }\n\n    pub fn cmp_ge(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_cmp_ps(self.0, rhs.0, _CMP_GE_OQ) })\n            } else {\n                Self(self.0.cmp_ge(rhs.0), self.1.cmp_ge(rhs.1))\n            }\n        }\n    }\n\n    pub fn cmp_gt(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_cmp_ps(self.0, rhs.0, _CMP_GT_OQ) })\n            } else {\n                Self(self.0.cmp_gt(rhs.0), self.1.cmp_gt(rhs.1))\n            }\n        }\n    }\n\n    pub fn cmp_le(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_cmp_ps(self.0, rhs.0, _CMP_LE_OQ) })\n            } else {\n                Self(self.0.cmp_le(rhs.0), self.1.cmp_le(rhs.1))\n            }\n        }\n    }\n\n    pub fn cmp_lt(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_cmp_ps(self.0, rhs.0, _CMP_LT_OQ) })\n            } else {\n                Self(self.0.cmp_lt(rhs.0), self.1.cmp_lt(rhs.1))\n            }\n        }\n    }\n\n    #[inline]\n    pub fn blend(self, t: Self, f: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_blendv_ps(f.0, t.0, self.0) })\n            } else {\n                Self(self.0.blend(t.0, f.0), self.1.blend(t.1, f.1))\n            }\n        }\n    }\n\n    pub fn abs(self) -> Self {\n        let non_sign_bits = f32x8::splat(f32::from_bits(i32::MAX as u32));\n        self & non_sign_bits\n    }\n\n    pub fn max(self, rhs: Self) -> Self {\n        // These technically don't have the same semantics for NaN and 0, but it\n        // doesn't seem to matter as Skia does it the same way.\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_max_ps(self.0, rhs.0) })\n            } else {\n                Self(self.0.max(rhs.0), self.1.max(rhs.1))\n            }\n        }\n    }\n\n    pub fn min(self, rhs: Self) -> Self {\n        // These technically don't have the same semantics for NaN and 0, but it\n        // doesn't seem to matter as Skia does it the same way.\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_min_ps(self.0, rhs.0) })\n            } else {\n                Self(self.0.min(rhs.0), self.1.min(rhs.1))\n            }\n        }\n    }\n\n    pub fn is_finite(self) -> Self {\n        let shifted_exp_mask = u32x8::splat(0xFF000000);\n        let u: u32x8 = cast(self);\n        let shift_u = u.shl::<1>();\n        let out = !(shift_u & shifted_exp_mask).cmp_eq(shifted_exp_mask);\n        cast(out)\n    }\n\n    pub fn round(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_round_ps(self.0, _MM_FROUND_NO_EXC | _MM_FROUND_TO_NEAREST_INT) })\n            } else {\n                Self(self.0.round(), self.1.round())\n            }\n        }\n    }\n\n    pub fn round_int(self) -> i32x8 {\n        // These technically don't have the same semantics for NaN and out of\n        // range values, but it doesn't seem to matter as Skia does it the same\n        // way.\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                cast(unsafe { _mm256_cvtps_epi32(self.0) })\n            } else {\n                i32x8(self.0.round_int(), self.1.round_int())\n            }\n        }\n    }\n\n    pub fn trunc_int(self) -> i32x8 {\n        // These technically don't have the same semantics for NaN and out of\n        // range values, but it doesn't seem to matter as Skia does it the same\n        // way.\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                cast(unsafe { _mm256_cvttps_epi32(self.0) })\n            } else {\n                i32x8(self.0.trunc_int(), self.1.trunc_int())\n            }\n        }\n    }\n\n    pub fn recip_fast(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_rcp_ps(self.0) })\n            } else {\n                Self(self.0.recip_fast(), self.1.recip_fast())\n            }\n        }\n    }\n\n    pub fn recip_sqrt(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_rsqrt_ps(self.0) })\n            } else {\n                Self(self.0.recip_sqrt(), self.1.recip_sqrt())\n            }\n        }\n    }\n\n    pub fn sqrt(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_sqrt_ps(self.0) })\n            } else {\n                Self(self.0.sqrt(), self.1.sqrt())\n            }\n        }\n    }\n}\n\nimpl From<[f32; 8]> for f32x8 {\n    fn from(v: [f32; 8]) -> Self {\n        cast(v)\n    }\n}\n\nimpl From<f32x8> for [f32; 8] {\n    fn from(v: f32x8) -> Self {\n        cast(v)\n    }\n}\n\nimpl core::ops::Add for f32x8 {\n    type Output = Self;\n\n    fn add(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_add_ps(self.0, rhs.0) })\n            } else {\n                Self(self.0 + rhs.0, self.1 + rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::AddAssign for f32x8 {\n    fn add_assign(&mut self, rhs: f32x8) {\n        *self = *self + rhs;\n    }\n}\n\nimpl core::ops::Sub for f32x8 {\n    type Output = Self;\n\n    fn sub(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_sub_ps(self.0, rhs.0) })\n            } else {\n                Self(self.0 - rhs.0, self.1 - rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::Mul for f32x8 {\n    type Output = Self;\n\n    fn mul(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_mul_ps(self.0, rhs.0) })\n            } else {\n                Self(self.0 * rhs.0, self.1 * rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::MulAssign for f32x8 {\n    fn mul_assign(&mut self, rhs: f32x8) {\n        *self = *self * rhs;\n    }\n}\n\nimpl core::ops::Div for f32x8 {\n    type Output = Self;\n\n    fn div(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_div_ps(self.0, rhs.0) })\n            } else {\n                Self(self.0 / rhs.0, self.1 / rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::BitAnd for f32x8 {\n    type Output = Self;\n\n    #[inline(always)]\n    fn bitand(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_and_ps(self.0, rhs.0) })\n            } else {\n                Self(self.0 & rhs.0, self.1 & rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::BitOr for f32x8 {\n    type Output = Self;\n\n    #[inline(always)]\n    fn bitor(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_or_ps(self.0, rhs.0) })\n            } else {\n                Self(self.0 | rhs.0, self.1 | rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::BitXor for f32x8 {\n    type Output = Self;\n\n    #[inline(always)]\n    fn bitxor(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                Self(unsafe { _mm256_xor_ps(self.0, rhs.0) })\n            } else {\n                Self(self.0 ^ rhs.0, self.1 ^ rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::Neg for f32x8 {\n    type Output = Self;\n\n    fn neg(self) -> Self {\n        Self::default() - self\n    }\n}\n\nimpl core::ops::Not for f32x8 {\n    type Output = Self;\n\n    fn not(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                let all_bits = unsafe { _mm256_set1_ps(f32::from_bits(u32::MAX)) };\n                Self(unsafe { _mm256_xor_ps(self.0, all_bits) })\n            } else {\n                Self(!self.0, !self.1)\n            }\n        }\n    }\n}\n\nimpl core::cmp::PartialEq for f32x8 {\n    fn eq(&self, rhs: &Self) -> bool {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                let mask = unsafe { _mm256_cmp_ps(self.0, rhs.0, _CMP_EQ_OQ) };\n                unsafe { _mm256_movemask_ps(mask) == 0b1111_1111 }\n            } else {\n                self.0 == rhs.0 && self.1 == rhs.1\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/wide/i32x4_t.rs",
      "sha256": "2f4de262ed53ad6d429c140a6401b8267c8df8ebf7fefa5362865ef1ce007c05",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Based on https://github.com/Lokathor/wide (Zlib)\n\nuse bytemuck::cast;\n\nuse super::f32x4;\n\ncfg_if::cfg_if! {\n    if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n        #[cfg(target_arch = \"x86\")]\n        use core::arch::x86::*;\n        #[cfg(target_arch = \"x86_64\")]\n        use core::arch::x86_64::*;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct i32x4(pub __m128i);\n    } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n        use core::arch::wasm32::*;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct i32x4(pub v128);\n    } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n        use core::arch::aarch64::*;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct i32x4(pub int32x4_t);\n    } else {\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct i32x4([i32; 4]);\n    }\n}\n\nunsafe impl bytemuck::Zeroable for i32x4 {}\nunsafe impl bytemuck::Pod for i32x4 {}\n\nimpl Default for i32x4 {\n    fn default() -> Self {\n        Self::splat(0)\n    }\n}\n\nimpl i32x4 {\n    pub fn splat(n: i32) -> Self {\n        cast([n, n, n, n])\n    }\n\n    pub fn blend(self, t: Self, f: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse4.1\"))] {\n                Self(unsafe { _mm_blendv_epi8(f.0, t.0, self.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_bitselect(t.0, f.0, self.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vbslq_s32(cast(self.0), t.0, f.0) })\n            } else {\n                super::generic_bit_blend(self, t, f)\n            }\n        }\n    }\n\n    pub fn cmp_eq(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                cast(Self(cast(unsafe { _mm_cmpeq_epi32(self.0, rhs.0) })))\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(i32x4_eq(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { cast(vceqq_s32(self.0, rhs.0)) })\n            } else {\n                Self([\n                    if self.0[0] == rhs.0[0] { -1 } else { 0 },\n                    if self.0[1] == rhs.0[1] { -1 } else { 0 },\n                    if self.0[2] == rhs.0[2] { -1 } else { 0 },\n                    if self.0[3] == rhs.0[3] { -1 } else { 0 },\n                ])\n            }\n        }\n    }\n\n    pub fn cmp_gt(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                cast(Self(cast(unsafe { _mm_cmpgt_epi32(self.0, rhs.0) })))\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(i32x4_gt(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { cast(vcgtq_s32(self.0, rhs.0)) })\n            } else {\n                Self([\n                    if self.0[0] > rhs.0[0] { -1 } else { 0 },\n                    if self.0[1] > rhs.0[1] { -1 } else { 0 },\n                    if self.0[2] > rhs.0[2] { -1 } else { 0 },\n                    if self.0[3] > rhs.0[3] { -1 } else { 0 },\n                ])\n            }\n        }\n    }\n\n    pub fn cmp_lt(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                cast(Self(cast(unsafe { _mm_cmplt_epi32(self.0, rhs.0) })))\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(i32x4_lt(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { cast(vcltq_s32(self.0, rhs.0)) })\n            } else {\n                Self([\n                    if self.0[0] < rhs.0[0] { -1 } else { 0 },\n                    if self.0[1] < rhs.0[1] { -1 } else { 0 },\n                    if self.0[2] < rhs.0[2] { -1 } else { 0 },\n                    if self.0[3] < rhs.0[3] { -1 } else { 0 },\n                ])\n            }\n        }\n    }\n\n    pub fn to_f32x4(self) -> f32x4 {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                cast(Self(cast(unsafe { _mm_cvtepi32_ps(self.0) })))\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                cast(Self(f32x4_convert_i32x4(self.0)))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                cast(Self(unsafe { cast(vcvtq_f32_s32(self.0)) }))\n            } else {\n                let arr: [i32; 4] = cast(self);\n                cast([\n                    arr[0] as f32,\n                    arr[1] as f32,\n                    arr[2] as f32,\n                    arr[3] as f32,\n                ])\n            }\n        }\n    }\n\n    pub fn to_f32x4_bitcast(self) -> f32x4 {\n        bytemuck::cast(self)\n    }\n}\n\nimpl From<[i32; 4]> for i32x4 {\n    fn from(v: [i32; 4]) -> Self {\n        cast(v)\n    }\n}\n\nimpl From<i32x4> for [i32; 4] {\n    fn from(v: i32x4) -> Self {\n        cast(v)\n    }\n}\n\nimpl core::ops::Add for i32x4 {\n    type Output = Self;\n\n    fn add(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_add_epi32(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(i32x4_add(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vaddq_s32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0].wrapping_add(rhs.0[0]),\n                    self.0[1].wrapping_add(rhs.0[1]),\n                    self.0[2].wrapping_add(rhs.0[2]),\n                    self.0[3].wrapping_add(rhs.0[3]),\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::BitAnd for i32x4 {\n    type Output = Self;\n\n    fn bitand(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_and_si128(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_and(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vandq_s32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0] & rhs.0[0],\n                    self.0[1] & rhs.0[1],\n                    self.0[2] & rhs.0[2],\n                    self.0[3] & rhs.0[3],\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::Mul for i32x4 {\n    type Output = Self;\n\n    fn mul(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse4.1\"))] {\n                Self(unsafe { _mm_mullo_epi32(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(i32x4_mul(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vmulq_s32(self.0, rhs.0) })\n            } else {\n                // Cast is required, since we have to use scalar multiplication on SSE2.\n                let a: [i32; 4] = cast(self);\n                let b: [i32; 4] = cast(rhs);\n                Self(cast([\n                    a[0].wrapping_mul(b[0]),\n                    a[1].wrapping_mul(b[1]),\n                    a[2].wrapping_mul(b[2]),\n                    a[3].wrapping_mul(b[3]),\n                ]))\n            }\n        }\n    }\n}\n\nimpl core::ops::BitOr for i32x4 {\n    type Output = Self;\n\n    #[inline]\n    fn bitor(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_or_si128(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_or(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vorrq_s32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0] | rhs.0[0],\n                    self.0[1] | rhs.0[1],\n                    self.0[2] | rhs.0[2],\n                    self.0[3] | rhs.0[3],\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::BitXor for i32x4 {\n    type Output = Self;\n\n    #[inline]\n    fn bitxor(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_xor_si128(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_xor(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { veorq_s32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0] ^ rhs.0[0],\n                    self.0[1] ^ rhs.0[1],\n                    self.0[2] ^ rhs.0[2],\n                    self.0[3] ^ rhs.0[3],\n                ])\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/wide/i32x8_t.rs",
      "sha256": "7bfc17eacd1442e2008a3e213f04118d7c33150f5902091a59b50340e30cfe06",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Based on https://github.com/Lokathor/wide (Zlib)\n\nuse bytemuck::cast;\n\nuse super::{f32x8, u32x8};\n\ncfg_if::cfg_if! {\n    if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n        #[cfg(target_arch = \"x86\")]\n        use core::arch::x86::*;\n        #[cfg(target_arch = \"x86_64\")]\n        use core::arch::x86_64::*;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(32))]\n        pub struct i32x8(__m256i);\n    } else {\n        use super::i32x4;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(32))]\n        pub struct i32x8(pub i32x4, pub i32x4);\n    }\n}\n\nunsafe impl bytemuck::Zeroable for i32x8 {}\nunsafe impl bytemuck::Pod for i32x8 {}\n\nimpl Default for i32x8 {\n    fn default() -> Self {\n        Self::splat(0)\n    }\n}\n\nimpl i32x8 {\n    pub fn splat(n: i32) -> Self {\n        cast([n, n, n, n, n, n, n, n])\n    }\n\n    pub fn blend(self, t: Self, f: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_blendv_epi8(f.0, t.0, self.0) })\n            } else {\n                Self(self.0.blend(t.0, f.0), self.1.blend(t.1, f.1))\n            }\n        }\n    }\n\n    pub fn cmp_eq(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_cmpeq_epi32(self.0, rhs.0) })\n            } else {\n                Self(self.0.cmp_eq(rhs.0), self.1.cmp_eq(rhs.1))\n            }\n        }\n    }\n\n    pub fn cmp_gt(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_cmpgt_epi32(self.0, rhs.0) })\n            } else {\n                Self(self.0.cmp_gt(rhs.0), self.1.cmp_gt(rhs.1))\n            }\n        }\n    }\n\n    pub fn cmp_lt(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                // There is no `_mm256_cmpLT_epi32`, therefore we have to use\n                // `_mm256_cmpGT_epi32` and then invert the result.\n                let v = unsafe { _mm256_cmpgt_epi32(self.0, rhs.0) };\n                let all_bits = unsafe { _mm256_set1_epi16(-1) };\n                Self(unsafe { _mm256_xor_si256(v, all_bits) })\n            } else {\n                Self(self.0.cmp_lt(rhs.0), self.1.cmp_lt(rhs.1))\n            }\n        }\n    }\n\n    pub fn to_f32x8(self) -> f32x8 {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                cast(unsafe { _mm256_cvtepi32_ps(self.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"avx\"))] {\n                cast([self.0.to_f32x4(), self.1.to_f32x4()])\n            } else {\n                f32x8(self.0.to_f32x4(), self.1.to_f32x4())\n            }\n        }\n    }\n\n    pub fn to_u32x8_bitcast(self) -> u32x8 {\n        bytemuck::cast(self)\n    }\n\n    pub fn to_f32x8_bitcast(self) -> f32x8 {\n        bytemuck::cast(self)\n    }\n}\n\nimpl From<[i32; 8]> for i32x8 {\n    fn from(v: [i32; 8]) -> Self {\n        cast(v)\n    }\n}\n\nimpl From<i32x8> for [i32; 8] {\n    fn from(v: i32x8) -> Self {\n        cast(v)\n    }\n}\n\nimpl core::ops::Add for i32x8 {\n    type Output = Self;\n\n    fn add(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_add_epi32(self.0, rhs.0) })\n            } else {\n                Self(self.0 + rhs.0, self.1 + rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::BitAnd for i32x8 {\n    type Output = Self;\n\n    fn bitand(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_and_si256(self.0, rhs.0) })\n            } else {\n                Self(self.0 & rhs.0, self.1 & rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::Mul for i32x8 {\n    type Output = Self;\n\n    fn mul(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_mullo_epi32(self.0, rhs.0) })\n            } else {\n                Self(self.0 * rhs.0, self.1 * rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::BitOr for i32x8 {\n    type Output = Self;\n\n    #[inline]\n    fn bitor(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_or_si256(self.0, rhs.0) })\n            } else {\n                Self(self.0 | rhs.0, self.1 | rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::BitXor for i32x8 {\n    type Output = Self;\n\n    #[inline]\n    fn bitxor(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_xor_si256(self.0, rhs.0) })\n            } else {\n                Self(self.0 ^ rhs.0, self.1 ^ rhs.1)\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/wide/mod.rs",
      "sha256": "653956086a14cbae739357bcddac8baacf56f88360100c07e3171ecccc313ee8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// This module was written from scratch, therefore there is no Google copyright.\n\n// f32x16, i32x16 and u32x16 are implemented as [Tx8; 2] and not as [T; 16].\n// This way we still can use some SIMD.\n//\n// We doesn't use #[inline] that much in this module.\n// The compiler will inline most of the methods automatically.\n// The only exception is U16x16, were we have to force inlining,\n// otherwise the performance will be horrible.\n\n#![allow(non_camel_case_types)]\n\nmod f32x16_t;\nmod f32x4_t;\nmod f32x8_t;\nmod i32x4_t;\nmod i32x8_t;\nmod u16x16_t;\nmod u32x4_t;\nmod u32x8_t;\n\npub use f32x16_t::f32x16;\npub use f32x4_t::f32x4;\npub use f32x8_t::f32x8;\npub use i32x4_t::i32x4;\npub use i32x8_t::i32x8;\npub use tiny_skia_path::f32x2;\npub use u16x16_t::u16x16;\npub use u32x4_t::u32x4;\npub use u32x8_t::u32x8;\n\n#[allow(dead_code)]\n#[inline]\npub fn generic_bit_blend<T>(mask: T, y: T, n: T) -> T\nwhere\n    T: Copy + core::ops::BitXor<Output = T> + core::ops::BitAnd<Output = T>,\n{\n    n ^ ((n ^ y) & mask)\n}\n\n/// A faster and more forgiving f32 min/max implementation.\n///\n/// Unlike std one, we do not care about NaN.\n#[allow(dead_code)]\npub trait FasterMinMax {\n    fn faster_min(self, rhs: f32) -> f32;\n    fn faster_max(self, rhs: f32) -> f32;\n}\n\n#[allow(dead_code)]\nimpl FasterMinMax for f32 {\n    fn faster_min(self, rhs: f32) -> f32 {\n        if rhs < self {\n            rhs\n        } else {\n            self\n        }\n    }\n\n    fn faster_max(self, rhs: f32) -> f32 {\n        if self < rhs {\n            rhs\n        } else {\n            self\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/wide/u16x16_t.rs",
      "sha256": "fbbf313213582c8663471cb3739612840e9544d4a08ae78c1123fbbd2a6e8f54",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// No need to use explicit 256bit AVX2 SIMD.\n// `-C target-cpu=native` will autovectorize it better than us.\n// Not even sure why explicit instructions are so slow...\n//\n// On ARM AArch64 we can actually get up to 2x performance boost by using SIMD.\n//\n// We also have to inline all the methods. They are pretty large,\n// but without the inlining the performance is plummeting.\n\n#[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))]\nuse bytemuck::cast;\n#[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))]\nuse core::arch::aarch64::uint16x8_t;\n\n#[allow(non_camel_case_types)]\n#[derive(Copy, Clone, PartialEq, Default, Debug)]\npub struct u16x16(pub [u16; 16]);\n\nmacro_rules! impl_u16x16_op {\n    ($a:expr, $op:ident, $b:expr) => {\n        u16x16([\n            $a.0[0].$op($b.0[0]),\n            $a.0[1].$op($b.0[1]),\n            $a.0[2].$op($b.0[2]),\n            $a.0[3].$op($b.0[3]),\n            $a.0[4].$op($b.0[4]),\n            $a.0[5].$op($b.0[5]),\n            $a.0[6].$op($b.0[6]),\n            $a.0[7].$op($b.0[7]),\n            $a.0[8].$op($b.0[8]),\n            $a.0[9].$op($b.0[9]),\n            $a.0[10].$op($b.0[10]),\n            $a.0[11].$op($b.0[11]),\n            $a.0[12].$op($b.0[12]),\n            $a.0[13].$op($b.0[13]),\n            $a.0[14].$op($b.0[14]),\n            $a.0[15].$op($b.0[15]),\n        ])\n    };\n}\n\n#[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))]\nmacro_rules! impl_aarch64_call {\n    ($f:ident, $a:expr, $b:expr) => {\n        let a = $a.split();\n        let b = $b.split();\n        Self(bytemuck::cast([\n            unsafe { core::arch::aarch64::$f(a.0, b.0) },\n            unsafe { core::arch::aarch64::$f(a.1, b.1) },\n        ]))\n    };\n}\n\nimpl u16x16 {\n    #[inline]\n    pub fn splat(n: u16) -> Self {\n        Self([n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n])\n    }\n\n    #[inline]\n    pub fn as_slice(&self) -> &[u16; 16] {\n        &self.0\n    }\n\n    #[inline]\n    pub fn min(&self, rhs: &Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                impl_aarch64_call!(vminq_u16, self, rhs)\n            } else {\n                impl_u16x16_op!(self, min, rhs)\n            }\n        }\n    }\n\n    #[inline]\n    pub fn max(&self, rhs: &Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                impl_aarch64_call!(vmaxq_u16, self, rhs)\n            } else {\n                impl_u16x16_op!(self, max, rhs)\n            }\n        }\n    }\n\n    #[inline]\n    pub fn cmp_le(&self, rhs: &Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                impl_aarch64_call!(vcleq_u16, self, rhs)\n            } else {\n                Self([\n                    if self.0[ 0] <= rhs.0[ 0] { !0 } else { 0 },\n                    if self.0[ 1] <= rhs.0[ 1] { !0 } else { 0 },\n                    if self.0[ 2] <= rhs.0[ 2] { !0 } else { 0 },\n                    if self.0[ 3] <= rhs.0[ 3] { !0 } else { 0 },\n                    if self.0[ 4] <= rhs.0[ 4] { !0 } else { 0 },\n                    if self.0[ 5] <= rhs.0[ 5] { !0 } else { 0 },\n                    if self.0[ 6] <= rhs.0[ 6] { !0 } else { 0 },\n                    if self.0[ 7] <= rhs.0[ 7] { !0 } else { 0 },\n                    if self.0[ 8] <= rhs.0[ 8] { !0 } else { 0 },\n                    if self.0[ 9] <= rhs.0[ 9] { !0 } else { 0 },\n                    if self.0[10] <= rhs.0[10] { !0 } else { 0 },\n                    if self.0[11] <= rhs.0[11] { !0 } else { 0 },\n                    if self.0[12] <= rhs.0[12] { !0 } else { 0 },\n                    if self.0[13] <= rhs.0[13] { !0 } else { 0 },\n                    if self.0[14] <= rhs.0[14] { !0 } else { 0 },\n                    if self.0[15] <= rhs.0[15] { !0 } else { 0 },\n                ])\n            }\n        }\n    }\n\n    #[inline]\n    pub fn blend(self, t: Self, e: Self) -> Self {\n        (t & self) | (e & !self)\n    }\n\n    #[inline]\n    #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))]\n    pub fn split(self) -> (uint16x8_t, uint16x8_t) {\n        let pair: [uint16x8_t; 2] = cast(self.0);\n        (pair[0], pair[1])\n    }\n}\n\nimpl core::ops::Add<u16x16> for u16x16 {\n    type Output = Self;\n\n    #[inline]\n    fn add(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                impl_aarch64_call!(vaddq_u16, self, rhs)\n            } else {\n                impl_u16x16_op!(self, add, rhs)\n            }\n        }\n    }\n}\n\nimpl core::ops::Sub<u16x16> for u16x16 {\n    type Output = Self;\n\n    #[inline]\n    fn sub(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                impl_aarch64_call!(vsubq_u16, self, rhs)\n            } else {\n                impl_u16x16_op!(self, sub, rhs)\n            }\n        }\n    }\n}\n\nimpl core::ops::Mul<u16x16> for u16x16 {\n    type Output = Self;\n\n    #[inline]\n    fn mul(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                impl_aarch64_call!(vmulq_u16, self, rhs)\n            } else {\n                impl_u16x16_op!(self, mul, rhs)\n            }\n        }\n    }\n}\n\nimpl core::ops::Div<u16x16> for u16x16 {\n    type Output = Self;\n\n    #[inline]\n    fn div(self, rhs: Self) -> Self::Output {\n        impl_u16x16_op!(self, div, rhs)\n    }\n}\n\nimpl core::ops::BitAnd<u16x16> for u16x16 {\n    type Output = Self;\n\n    #[inline]\n    fn bitand(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                impl_aarch64_call!(vandq_u16, self, rhs)\n            } else {\n                impl_u16x16_op!(self, bitand, rhs)\n            }\n        }\n    }\n}\n\nimpl core::ops::BitOr<u16x16> for u16x16 {\n    type Output = Self;\n\n    #[inline]\n    fn bitor(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                impl_aarch64_call!(vorrq_u16, self, rhs)\n            } else {\n                impl_u16x16_op!(self, bitor, rhs)\n            }\n        }\n    }\n}\n\nimpl core::ops::Not for u16x16 {\n    type Output = Self;\n\n    #[inline]\n    fn not(self) -> Self::Output {\n        u16x16([\n            !self.0[0],\n            !self.0[1],\n            !self.0[2],\n            !self.0[3],\n            !self.0[4],\n            !self.0[5],\n            !self.0[6],\n            !self.0[7],\n            !self.0[8],\n            !self.0[9],\n            !self.0[10],\n            !self.0[11],\n            !self.0[12],\n            !self.0[13],\n            !self.0[14],\n            !self.0[15],\n        ])\n    }\n}\n\nimpl core::ops::Shr for u16x16 {\n    type Output = Self;\n\n    #[inline]\n    fn shr(self, rhs: Self) -> Self::Output {\n        impl_u16x16_op!(self, shr, rhs)\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/wide/u32x4_t.rs",
      "sha256": "bdcdbbccec0171e5f743546ca89b6552182d2e9fd31c26863e9c7a1da68debae",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Based on https://github.com/Lokathor/wide (Zlib)\n\ncfg_if::cfg_if! {\n    if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n        #[cfg(target_arch = \"x86\")]\n        use core::arch::x86::*;\n        #[cfg(target_arch = \"x86_64\")]\n        use core::arch::x86_64::*;\n\n        // unused when AVX is available\n        #[cfg(not(target_feature = \"avx2\"))]\n        use bytemuck::cast;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct u32x4(__m128i);\n    } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n        use core::arch::wasm32::*;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct u32x4(v128);\n    } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n        use core::arch::aarch64::*;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct u32x4(uint32x4_t);\n    } else {\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(16))]\n        pub struct u32x4([u32; 4]);\n    }\n}\n\nunsafe impl bytemuck::Zeroable for u32x4 {}\nunsafe impl bytemuck::Pod for u32x4 {}\n\nimpl Default for u32x4 {\n    fn default() -> Self {\n        Self::splat(0)\n    }\n}\n\nimpl u32x4 {\n    pub fn splat(n: u32) -> Self {\n        bytemuck::cast([n, n, n, n])\n    }\n\n    // unused when AVX is available\n    #[cfg(not(target_feature = \"avx2\"))]\n    pub fn cmp_eq(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_cmpeq_epi32(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(u32x4_eq(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vceqq_u32(self.0, rhs.0) })\n            } else {\n                Self([\n                    if self.0[0] == rhs.0[0] { u32::MAX } else { 0 },\n                    if self.0[1] == rhs.0[1] { u32::MAX } else { 0 },\n                    if self.0[2] == rhs.0[2] { u32::MAX } else { 0 },\n                    if self.0[3] == rhs.0[3] { u32::MAX } else { 0 },\n                ])\n            }\n        }\n    }\n\n    // unused when AVX is available\n    #[cfg(not(target_feature = \"avx2\"))]\n    pub fn shl<const RHS: i32>(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                let shift = cast([RHS as u64, 0]);\n                Self(unsafe { _mm_sll_epi32(self.0, shift) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(u32x4_shl(self.0, RHS as _))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vshlq_n_u32::<RHS>(self.0) })\n            } else {\n                let u = RHS as u64;\n                Self([\n                    self.0[0] << u,\n                    self.0[1] << u,\n                    self.0[2] << u,\n                    self.0[3] << u,\n                ])\n            }\n        }\n    }\n\n    // unused when AVX is available\n    #[cfg(not(target_feature = \"avx2\"))]\n    pub fn shr<const RHS: i32>(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                let shift: __m128i = cast([RHS as u64, 0]);\n                Self(unsafe { _mm_srl_epi32(self.0, shift) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(u32x4_shr(self.0, RHS as _))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vshrq_n_u32::<RHS>(self.0) })\n            } else {\n                let u = RHS as u64;\n                Self([\n                    self.0[0] >> u,\n                    self.0[1] >> u,\n                    self.0[2] >> u,\n                    self.0[3] >> u,\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::Not for u32x4 {\n    type Output = Self;\n\n    fn not(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                let all_bits = unsafe { _mm_set1_epi32(-1) };\n                Self(unsafe { _mm_xor_si128(self.0, all_bits) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_not(self.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vmvnq_u32(self.0) })\n            } else {\n                Self([\n                    !self.0[0],\n                    !self.0[1],\n                    !self.0[2],\n                    !self.0[3],\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::Add for u32x4 {\n    type Output = Self;\n\n    fn add(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_add_epi32(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(u32x4_add(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vaddq_u32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0].wrapping_add(rhs.0[0]),\n                    self.0[1].wrapping_add(rhs.0[1]),\n                    self.0[2].wrapping_add(rhs.0[2]),\n                    self.0[3].wrapping_add(rhs.0[3]),\n                ])\n            }\n        }\n    }\n}\n\nimpl core::ops::BitAnd for u32x4 {\n    type Output = Self;\n\n    fn bitand(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"sse2\"))] {\n                Self(unsafe { _mm_and_si128(self.0, rhs.0) })\n            } else if #[cfg(all(feature = \"simd\", target_feature = \"simd128\"))] {\n                Self(v128_and(self.0, rhs.0))\n            } else if #[cfg(all(feature = \"simd\", target_arch = \"aarch64\", target_feature = \"neon\"))] {\n                Self(unsafe { vandq_u32(self.0, rhs.0) })\n            } else {\n                Self([\n                    self.0[0] & rhs.0[0],\n                    self.0[1] & rhs.0[1],\n                    self.0[2] & rhs.0[2],\n                    self.0[3] & rhs.0[3],\n                ])\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia@0.10.0",
      "sourcePath": "src/wide/u32x8_t.rs",
      "sha256": "061feb0a51f6ca4dc715a53a9ac92f7bc163ca39366a73d9b6f2190ae30c8f6a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Based on https://github.com/Lokathor/wide (Zlib)\n\nuse super::{f32x8, i32x8};\n\ncfg_if::cfg_if! {\n    if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n        #[cfg(target_arch = \"x86\")]\n        use core::arch::x86::*;\n        #[cfg(target_arch = \"x86_64\")]\n        use core::arch::x86_64::*;\n\n        use bytemuck::cast;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(32))]\n        pub struct u32x8(__m256i);\n    } else {\n        use super::u32x4;\n\n        #[derive(Clone, Copy, Debug)]\n        #[repr(C, align(32))]\n        pub struct u32x8(u32x4, u32x4);\n    }\n}\n\nunsafe impl bytemuck::Zeroable for u32x8 {}\nunsafe impl bytemuck::Pod for u32x8 {}\n\nimpl Default for u32x8 {\n    fn default() -> Self {\n        Self::splat(0)\n    }\n}\n\nimpl u32x8 {\n    pub fn splat(n: u32) -> Self {\n        bytemuck::cast([n, n, n, n, n, n, n, n])\n    }\n\n    pub fn to_i32x8_bitcast(self) -> i32x8 {\n        bytemuck::cast(self)\n    }\n\n    pub fn to_f32x8_bitcast(self) -> f32x8 {\n        bytemuck::cast(self)\n    }\n\n    pub fn cmp_eq(self, rhs: Self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_cmpeq_epi32(self.0, rhs.0) })\n            } else {\n                Self(self.0.cmp_eq(rhs.0), self.1.cmp_eq(rhs.1))\n            }\n        }\n    }\n\n    pub fn shl<const RHS: i32>(self) -> Self {\n        cfg_if::cfg_if! {\n           if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                let shift: __m128i = cast([RHS as u64, 0]);\n                Self(unsafe { _mm256_sll_epi32(self.0, shift) })\n            } else {\n                Self(self.0.shl::<RHS>(), self.1.shl::<RHS>())\n            }\n        }\n    }\n\n    pub fn shr<const RHS: i32>(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                let shift: __m128i = cast([RHS as u64, 0]);\n                Self(unsafe { _mm256_srl_epi32(self.0, shift) })\n            } else {\n                Self(self.0.shr::<RHS>(), self.1.shr::<RHS>())\n            }\n        }\n    }\n}\n\nimpl core::ops::Not for u32x8 {\n    type Output = Self;\n\n    fn not(self) -> Self {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                let all_bits = unsafe { _mm256_set1_epi16(-1) };\n                Self(unsafe { _mm256_xor_si256(self.0, all_bits) })\n            } else {\n                Self(!self.0, !self.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::Add for u32x8 {\n    type Output = Self;\n\n    fn add(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_add_epi32(self.0, rhs.0) })\n            } else {\n                Self(self.0 + rhs.0, self.1 + rhs.1)\n            }\n        }\n    }\n}\n\nimpl core::ops::BitAnd for u32x8 {\n    type Output = Self;\n\n    fn bitand(self, rhs: Self) -> Self::Output {\n        cfg_if::cfg_if! {\n            if #[cfg(all(feature = \"simd\", target_feature = \"avx2\"))] {\n                Self(unsafe { _mm256_and_si256(self.0, rhs.0) })\n            } else {\n                Self(self.0 & rhs.0, self.1 & rhs.1)\n            }\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/dash.rs",
      "sha256": "3b7a2614cf3b72a6b48fdc348312c2562f268bc022f32f6437756aa08feae1a8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2014 Google Inc.\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// This module is a mix of SkDashPath, SkDashPathEffect, SkContourMeasure and SkPathMeasure.\n\nuse alloc::vec::Vec;\n\nuse arrayref::array_ref;\n\nuse crate::{Path, Point};\n\nuse crate::floating_point::{FiniteF32, NonZeroPositiveF32, NormalizedF32, NormalizedF32Exclusive};\nuse crate::path::{PathSegment, PathSegmentsIter, PathVerb};\nuse crate::path_builder::PathBuilder;\nuse crate::path_geometry;\nuse crate::scalar::Scalar;\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse crate::NoStdFloat;\n\n/// A stroke dashing properties.\n///\n/// Contains an array of pairs, where the first number indicates an \"on\" interval\n/// and the second one indicates an \"off\" interval;\n/// a dash offset value and internal properties.\n///\n/// # Guarantees\n///\n/// - The dash array always have an even number of values.\n/// - All dash array values are finite and >= 0.\n/// - There is at least two dash array values.\n/// - The sum of all dash array values is positive and finite.\n/// - Dash offset is finite.\n#[derive(Clone, PartialEq, Debug)]\npub struct StrokeDash {\n    array: Vec<f32>,\n    offset: f32,\n    interval_len: NonZeroPositiveF32,\n    first_len: f32, // TODO: PositiveF32\n    first_index: usize,\n}\n\nimpl StrokeDash {\n    /// Creates a new stroke dashing object.\n    pub fn new(dash_array: Vec<f32>, dash_offset: f32) -> Option<Self> {\n        let dash_offset = FiniteF32::new(dash_offset)?;\n\n        if dash_array.len() < 2 || dash_array.len() % 2 != 0 {\n            return None;\n        }\n\n        if dash_array.iter().any(|n| *n < 0.0) {\n            return None;\n        }\n\n        let interval_len: f32 = dash_array.iter().sum();\n        let interval_len = NonZeroPositiveF32::new(interval_len)?;\n\n        let dash_offset = adjust_dash_offset(dash_offset.get(), interval_len.get());\n        debug_assert!(dash_offset >= 0.0);\n        debug_assert!(dash_offset < interval_len.get());\n\n        let (first_len, first_index) = find_first_interval(&dash_array, dash_offset);\n        debug_assert!(first_len >= 0.0);\n        debug_assert!(first_index < dash_array.len());\n\n        Some(StrokeDash {\n            array: dash_array,\n            offset: dash_offset,\n            interval_len,\n            first_len,\n            first_index,\n        })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use alloc::vec;\n\n    #[test]\n    fn test() {\n        assert_eq!(StrokeDash::new(vec![], 0.0), None);\n        assert_eq!(StrokeDash::new(vec![1.0], 0.0), None);\n        assert_eq!(StrokeDash::new(vec![1.0, 2.0, 3.0], 0.0), None);\n        assert_eq!(StrokeDash::new(vec![1.0, -2.0], 0.0), None);\n        assert_eq!(StrokeDash::new(vec![0.0, 0.0], 0.0), None);\n        assert_eq!(StrokeDash::new(vec![1.0, -1.0], 0.0), None);\n        assert_eq!(StrokeDash::new(vec![1.0, 1.0], f32::INFINITY), None);\n        assert_eq!(StrokeDash::new(vec![1.0, f32::INFINITY], 0.0), None);\n    }\n\n    #[test]\n    fn bug_26() {\n        let mut pb = PathBuilder::new();\n        pb.move_to(665.54, 287.3);\n        pb.line_to(675.67, 273.04);\n        pb.line_to(675.52, 271.32);\n        pb.line_to(674.79, 269.61);\n        pb.line_to(674.05, 268.04);\n        pb.line_to(672.88, 266.47);\n        pb.line_to(671.27, 264.9);\n        let path = pb.finish().unwrap();\n\n        let stroke_dash = StrokeDash::new(vec![6.0, 4.5], 0.0).unwrap();\n\n        assert!(path.dash(&stroke_dash, 1.0).is_some());\n    }\n}\n\n// Adjust phase to be between 0 and len, \"flipping\" phase if negative.\n// e.g., if len is 100, then phase of -20 (or -120) is equivalent to 80.\nfn adjust_dash_offset(mut offset: f32, len: f32) -> f32 {\n    if offset < 0.0 {\n        offset = -offset;\n        if offset > len {\n            offset %= len;\n        }\n\n        offset = len - offset;\n\n        // Due to finite precision, it's possible that phase == len,\n        // even after the subtract (if len >>> phase), so fix that here.\n        debug_assert!(offset <= len);\n        if offset == len {\n            offset = 0.0;\n        }\n\n        offset\n    } else if offset >= len {\n        offset % len\n    } else {\n        offset\n    }\n}\n\nfn find_first_interval(dash_array: &[f32], mut dash_offset: f32) -> (f32, usize) {\n    for (i, gap) in dash_array.iter().copied().enumerate() {\n        if dash_offset > gap || (dash_offset == gap && gap != 0.0) {\n            dash_offset -= gap;\n        } else {\n            return (gap - dash_offset, i);\n        }\n    }\n\n    // If we get here, phase \"appears\" to be larger than our length. This\n    // shouldn't happen with perfect precision, but we can accumulate errors\n    // during the initial length computation (rounding can make our sum be too\n    // big or too small. In that event, we just have to eat the error here.\n    (dash_array[0], 0)\n}\n\nimpl Path {\n    /// Converts the current path into a dashed one.\n    ///\n    /// `resolution_scale` can be obtained via\n    /// [`compute_resolution_scale`](crate::PathStroker::compute_resolution_scale).\n    ///\n    /// Returns `None` when more than 1_000_000 dashes had to be produced\n    /// or when the final path has an invalid bounding box.\n    pub fn dash(&self, dash: &StrokeDash, resolution_scale: f32) -> Option<Path> {\n        dash_impl(self, dash, resolution_scale)\n    }\n}\n\nfn dash_impl(src: &Path, dash: &StrokeDash, res_scale: f32) -> Option<Path> {\n    // We do not support the `cull_path` branch here.\n    // Skia has a lot of code for cases when a path contains only a single zero-length line\n    // or when a path is a rect. Not sure why.\n    // We simply ignoring it for the sake of simplicity.\n\n    // We also doesn't support the `SpecialLineRec` case.\n    // I have no idea what the point in it.\n\n    fn is_even(x: usize) -> bool {\n        x % 2 == 0\n    }\n\n    let mut pb = PathBuilder::new();\n    let mut dash_count = 0.0;\n    for contour in ContourMeasureIter::new(src, res_scale) {\n        let mut skip_first_segment = contour.is_closed;\n        let mut added_segment = false;\n        let length = contour.length;\n        let mut index = dash.first_index;\n\n        // Since the path length / dash length ratio may be arbitrarily large, we can exert\n        // significant memory pressure while attempting to build the filtered path. To avoid this,\n        // we simply give up dashing beyond a certain threshold.\n        //\n        // The original bug report (http://crbug.com/165432) is based on a path yielding more than\n        // 90 million dash segments and crashing the memory allocator. A limit of 1 million\n        // segments seems reasonable: at 2 verbs per segment * 9 bytes per verb, this caps the\n        // maximum dash memory overhead at roughly 17MB per path.\n        const MAX_DASH_COUNT: usize = 1000000;\n        dash_count += length * (dash.array.len() >> 1) as f32 / dash.interval_len.get();\n        if dash_count > MAX_DASH_COUNT as f32 {\n            return None;\n        }\n\n        // Using double precision to avoid looping indefinitely due to single precision rounding\n        // (for extreme path_length/dash_length ratios). See test_infinite_dash() unittest.\n        let mut distance = 0.0;\n        let mut d_len = dash.first_len;\n\n        while distance < length {\n            debug_assert!(d_len >= 0.0);\n            added_segment = false;\n            if is_even(index) && !skip_first_segment {\n                added_segment = true;\n                contour.push_segment(distance as f32, (distance + d_len) as f32, true, &mut pb);\n            }\n\n            distance += d_len;\n\n            // clear this so we only respect it the first time around\n            skip_first_segment = false;\n\n            // wrap around our intervals array if necessary\n            index += 1;\n            debug_assert!(index <= dash.array.len());\n            if index == dash.array.len() {\n                index = 0;\n            }\n\n            // fetch our next d_len\n            d_len = dash.array[index];\n        }\n\n        // extend if we ended on a segment and we need to join up with the (skipped) initial segment\n        if contour.is_closed && is_even(dash.first_index) && dash.first_len >= 0.0 {\n            contour.push_segment(0.0, dash.first_len, !added_segment, &mut pb);\n        }\n    }\n\n    pb.finish()\n}\n\nconst MAX_T_VALUE: u32 = 0x3FFFFFFF;\n\nstruct ContourMeasureIter<'a> {\n    iter: PathSegmentsIter<'a>,\n    tolerance: f32,\n}\n\nimpl<'a> ContourMeasureIter<'a> {\n    fn new(path: &'a Path, res_scale: f32) -> Self {\n        // can't use tangents, since we need [0..1..................2] to be seen\n        // as definitely not a line (it is when drawn, but not parametrically)\n        // so we compare midpoints\n        const CHEAP_DIST_LIMIT: f32 = 0.5; // just made this value up\n\n        ContourMeasureIter {\n            iter: path.segments(),\n            tolerance: CHEAP_DIST_LIMIT * res_scale.invert(),\n        }\n    }\n}\n\nimpl Iterator for ContourMeasureIter<'_> {\n    type Item = ContourMeasure;\n\n    // If it encounters a zero-length contour, it is skipped.\n    fn next(&mut self) -> Option<Self::Item> {\n        // Note:\n        // as we accumulate distance, we have to check that the result of +=\n        // actually made it larger, since a very small delta might be > 0, but\n        // still have no effect on distance (if distance >>> delta).\n        //\n        // We do this check below, and in compute_quad_segs and compute_cubic_segs\n\n        let mut contour = ContourMeasure::default();\n\n        let mut point_index = 0;\n        let mut distance = 0.0;\n        let mut have_seen_close = false;\n        let mut prev_p = Point::zero();\n        while let Some(seg) = self.iter.next() {\n            match seg {\n                PathSegment::MoveTo(p0) => {\n                    contour.points.push(p0);\n                    prev_p = p0;\n                }\n                PathSegment::LineTo(p0) => {\n                    let prev_d = distance;\n                    distance = contour.compute_line_seg(prev_p, p0, distance, point_index);\n\n                    if distance > prev_d {\n                        contour.points.push(p0);\n                        point_index += 1;\n                    }\n\n                    prev_p = p0;\n                }\n                PathSegment::QuadTo(p0, p1) => {\n                    let prev_d = distance;\n                    distance = contour.compute_quad_segs(\n                        prev_p,\n                        p0,\n                        p1,\n                        distance,\n                        0,\n                        MAX_T_VALUE,\n                        point_index,\n                        self.tolerance,\n                    );\n\n                    if distance > prev_d {\n                        contour.points.push(p0);\n                        contour.points.push(p1);\n                        point_index += 2;\n                    }\n\n                    prev_p = p1;\n                }\n                PathSegment::CubicTo(p0, p1, p2) => {\n                    let prev_d = distance;\n                    distance = contour.compute_cubic_segs(\n                        prev_p,\n                        p0,\n                        p1,\n                        p2,\n                        distance,\n                        0,\n                        MAX_T_VALUE,\n                        point_index,\n                        self.tolerance,\n                    );\n\n                    if distance > prev_d {\n                        contour.points.push(p0);\n                        contour.points.push(p1);\n                        contour.points.push(p2);\n                        point_index += 3;\n                    }\n\n                    prev_p = p2;\n                }\n                PathSegment::Close => {\n                    have_seen_close = true;\n                }\n            }\n\n            // TODO: to contour iter?\n            if self.iter.next_verb() == Some(PathVerb::Move) {\n                break;\n            }\n        }\n\n        if !distance.is_finite() {\n            return None;\n        }\n\n        if have_seen_close {\n            let prev_d = distance;\n            let first_pt = contour.points[0];\n            distance = contour.compute_line_seg(\n                contour.points[point_index],\n                first_pt,\n                distance,\n                point_index,\n            );\n\n            if distance > prev_d {\n                contour.points.push(first_pt);\n            }\n        }\n\n        contour.length = distance;\n        contour.is_closed = have_seen_close;\n\n        if contour.points.is_empty() {\n            None\n        } else {\n            Some(contour)\n        }\n    }\n}\n\n#[derive(Copy, Clone, PartialEq, Debug)]\nenum SegmentType {\n    Line,\n    Quad,\n    Cubic,\n}\n\n#[derive(Copy, Clone, Debug)]\nstruct Segment {\n    distance: f32,      // total distance up to this point\n    point_index: usize, // index into the ContourMeasure::points array\n    t_value: u32,\n    kind: SegmentType,\n}\n\nimpl Segment {\n    fn scalar_t(&self) -> f32 {\n        debug_assert!(self.t_value <= MAX_T_VALUE);\n        // 1/kMaxTValue can't be represented as a float, but it's close and the limits work fine.\n        const MAX_T_RECIPROCAL: f32 = 1.0 / MAX_T_VALUE as f32;\n        self.t_value as f32 * MAX_T_RECIPROCAL\n    }\n}\n\n#[derive(Default, Debug)]\nstruct ContourMeasure {\n    segments: Vec<Segment>,\n    points: Vec<Point>,\n    length: f32,\n    is_closed: bool,\n}\n\nimpl ContourMeasure {\n    fn push_segment(\n        &self,\n        mut start_d: f32,\n        mut stop_d: f32,\n        start_with_move_to: bool,\n        pb: &mut PathBuilder,\n    ) {\n        if start_d < 0.0 {\n            start_d = 0.0;\n        }\n\n        if stop_d > self.length {\n            stop_d = self.length;\n        }\n\n        if !(start_d <= stop_d) {\n            // catch NaN values as well\n            return;\n        }\n\n        if self.segments.is_empty() {\n            return;\n        }\n\n        let (seg_index, mut start_t) = match self.distance_to_segment(start_d) {\n            Some(v) => v,\n            None => return,\n        };\n        let mut seg = self.segments[seg_index];\n\n        let (stop_seg_index, stop_t) = match self.distance_to_segment(stop_d) {\n            Some(v) => v,\n            None => return,\n        };\n        let stop_seg = self.segments[stop_seg_index];\n\n        debug_assert!(stop_seg_index <= stop_seg_index);\n        let mut p = Point::zero();\n        if start_with_move_to {\n            compute_pos_tan(\n                &self.points[seg.point_index..],\n                seg.kind,\n                start_t,\n                Some(&mut p),\n                None,\n            );\n            pb.move_to(p.x, p.y);\n        }\n\n        if seg.point_index == stop_seg.point_index {\n            segment_to(\n                &self.points[seg.point_index..],\n                seg.kind,\n                start_t,\n                stop_t,\n                pb,\n            );\n        } else {\n            let mut new_seg_index = seg_index;\n            loop {\n                segment_to(\n                    &self.points[seg.point_index..],\n                    seg.kind,\n                    start_t,\n                    NormalizedF32::ONE,\n                    pb,\n                );\n\n                let old_point_index = seg.point_index;\n                loop {\n                    new_seg_index += 1;\n                    if self.segments[new_seg_index].point_index != old_point_index {\n                        break;\n                    }\n                }\n                seg = self.segments[new_seg_index];\n\n                start_t = NormalizedF32::ZERO;\n\n                if seg.point_index >= stop_seg.point_index {\n                    break;\n                }\n            }\n\n            segment_to(\n                &self.points[seg.point_index..],\n                seg.kind,\n                NormalizedF32::ZERO,\n                stop_t,\n                pb,\n            );\n        }\n    }\n\n    fn distance_to_segment(&self, distance: f32) -> Option<(usize, NormalizedF32)> {\n        debug_assert!(distance >= 0.0 && distance <= self.length);\n\n        let mut index = find_segment(&self.segments, distance);\n        // don't care if we hit an exact match or not, so we xor index if it is negative\n        index ^= index >> 31;\n        let index = index as usize;\n        let seg = self.segments[index];\n\n        // now interpolate t-values with the prev segment (if possible)\n        let mut start_t = 0.0;\n        let mut start_d = 0.0;\n        // check if the prev segment is legal, and references the same set of points\n        if index > 0 {\n            start_d = self.segments[index - 1].distance;\n            if self.segments[index - 1].point_index == seg.point_index {\n                debug_assert!(self.segments[index - 1].kind == seg.kind);\n                start_t = self.segments[index - 1].scalar_t();\n            }\n        }\n\n        debug_assert!(seg.scalar_t() > start_t);\n        debug_assert!(distance >= start_d);\n        debug_assert!(seg.distance > start_d);\n\n        let t =\n            start_t + (seg.scalar_t() - start_t) * (distance - start_d) / (seg.distance - start_d);\n        let t = NormalizedF32::new(t)?;\n        Some((index, t))\n    }\n\n    fn compute_line_seg(\n        &mut self,\n        p0: Point,\n        p1: Point,\n        mut distance: f32,\n        point_index: usize,\n    ) -> f32 {\n        let d = p0.distance(p1);\n        debug_assert!(d >= 0.0);\n        let prev_d = distance;\n        distance += d;\n        if distance > prev_d {\n            debug_assert!(point_index < self.points.len());\n            self.segments.push(Segment {\n                distance,\n                point_index,\n                t_value: MAX_T_VALUE,\n                kind: SegmentType::Line,\n            });\n        }\n\n        distance\n    }\n\n    fn compute_quad_segs(\n        &mut self,\n        p0: Point,\n        p1: Point,\n        p2: Point,\n        mut distance: f32,\n        min_t: u32,\n        max_t: u32,\n        point_index: usize,\n        tolerance: f32,\n    ) -> f32 {\n        if t_span_big_enough(max_t - min_t) != 0 && quad_too_curvy(p0, p1, p2, tolerance) {\n            let mut tmp = [Point::zero(); 5];\n            let half_t = (min_t + max_t) >> 1;\n\n            path_geometry::chop_quad_at(&[p0, p1, p2], NormalizedF32Exclusive::HALF, &mut tmp);\n            distance = self.compute_quad_segs(\n                tmp[0],\n                tmp[1],\n                tmp[2],\n                distance,\n                min_t,\n                half_t,\n                point_index,\n                tolerance,\n            );\n            distance = self.compute_quad_segs(\n                tmp[2],\n                tmp[3],\n                tmp[4],\n                distance,\n                half_t,\n                max_t,\n                point_index,\n                tolerance,\n            );\n        } else {\n            let d = p0.distance(p2);\n            let prev_d = distance;\n            distance += d;\n            if distance > prev_d {\n                debug_assert!(point_index < self.points.len());\n                self.segments.push(Segment {\n                    distance,\n                    point_index,\n                    t_value: max_t,\n                    kind: SegmentType::Quad,\n                });\n            }\n        }\n\n        distance\n    }\n\n    fn compute_cubic_segs(\n        &mut self,\n        p0: Point,\n        p1: Point,\n        p2: Point,\n        p3: Point,\n        mut distance: f32,\n        min_t: u32,\n        max_t: u32,\n        point_index: usize,\n        tolerance: f32,\n    ) -> f32 {\n        if t_span_big_enough(max_t - min_t) != 0 && cubic_too_curvy(p0, p1, p2, p3, tolerance) {\n            let mut tmp = [Point::zero(); 7];\n            let half_t = (min_t + max_t) >> 1;\n\n            path_geometry::chop_cubic_at2(\n                &[p0, p1, p2, p3],\n                NormalizedF32Exclusive::HALF,\n                &mut tmp,\n            );\n            distance = self.compute_cubic_segs(\n                tmp[0],\n                tmp[1],\n                tmp[2],\n                tmp[3],\n                distance,\n                min_t,\n                half_t,\n                point_index,\n                tolerance,\n            );\n            distance = self.compute_cubic_segs(\n                tmp[3],\n                tmp[4],\n                tmp[5],\n                tmp[6],\n                distance,\n                half_t,\n                max_t,\n                point_index,\n                tolerance,\n            );\n        } else {\n            let d = p0.distance(p3);\n            let prev_d = distance;\n            distance += d;\n            if distance > prev_d {\n                debug_assert!(point_index < self.points.len());\n                self.segments.push(Segment {\n                    distance,\n                    point_index,\n                    t_value: max_t,\n                    kind: SegmentType::Cubic,\n                });\n            }\n        }\n\n        distance\n    }\n}\n\nfn find_segment(base: &[Segment], key: f32) -> i32 {\n    let mut lo = 0u32;\n    let mut hi = (base.len() - 1) as u32;\n\n    while lo < hi {\n        let mid = (hi + lo) >> 1;\n        if base[mid as usize].distance < key {\n            lo = mid + 1;\n        } else {\n            hi = mid;\n        }\n    }\n\n    if base[hi as usize].distance < key {\n        hi += 1;\n        hi = !hi;\n    } else if key < base[hi as usize].distance {\n        hi = !hi;\n    }\n\n    hi as i32\n}\n\nfn compute_pos_tan(\n    points: &[Point],\n    seg_kind: SegmentType,\n    t: NormalizedF32,\n    pos: Option<&mut Point>,\n    tangent: Option<&mut Point>,\n) {\n    match seg_kind {\n        SegmentType::Line => {\n            if let Some(pos) = pos {\n                *pos = Point::from_xy(\n                    interp(points[0].x, points[1].x, t),\n                    interp(points[0].y, points[1].y, t),\n                );\n            }\n\n            if let Some(tangent) = tangent {\n                tangent.set_normalize(points[1].x - points[0].x, points[1].y - points[0].y);\n            }\n        }\n        SegmentType::Quad => {\n            let src = array_ref![points, 0, 3];\n            if let Some(pos) = pos {\n                *pos = path_geometry::eval_quad_at(src, t);\n            }\n\n            if let Some(tangent) = tangent {\n                *tangent = path_geometry::eval_quad_tangent_at(src, t);\n                tangent.normalize();\n            }\n        }\n        SegmentType::Cubic => {\n            let src = array_ref![points, 0, 4];\n            if let Some(pos) = pos {\n                *pos = path_geometry::eval_cubic_pos_at(src, t);\n            }\n\n            if let Some(tangent) = tangent {\n                *tangent = path_geometry::eval_cubic_tangent_at(src, t);\n                tangent.normalize();\n            }\n        }\n    }\n}\n\nfn segment_to(\n    points: &[Point],\n    seg_kind: SegmentType,\n    start_t: NormalizedF32,\n    stop_t: NormalizedF32,\n    pb: &mut PathBuilder,\n) {\n    debug_assert!(start_t <= stop_t);\n\n    if start_t == stop_t {\n        if let Some(pt) = pb.last_point() {\n            // If the dash as a zero-length on segment, add a corresponding zero-length line.\n            // The stroke code will add end caps to zero length lines as appropriate.\n            pb.line_to(pt.x, pt.y);\n        }\n\n        return;\n    }\n\n    match seg_kind {\n        SegmentType::Line => {\n            if stop_t == NormalizedF32::ONE {\n                pb.line_to(points[1].x, points[1].y);\n            } else {\n                pb.line_to(\n                    interp(points[0].x, points[1].x, stop_t),\n                    interp(points[0].y, points[1].y, stop_t),\n                );\n            }\n        }\n        SegmentType::Quad => {\n            let mut tmp0 = [Point::zero(); 5];\n            let mut tmp1 = [Point::zero(); 5];\n            if start_t == NormalizedF32::ZERO {\n                if stop_t == NormalizedF32::ONE {\n                    pb.quad_to_pt(points[1], points[2]);\n                } else {\n                    let stop_t = NormalizedF32Exclusive::new_bounded(stop_t.get());\n                    path_geometry::chop_quad_at(points, stop_t, &mut tmp0);\n                    pb.quad_to_pt(tmp0[1], tmp0[2]);\n                }\n            } else {\n                let start_tt = NormalizedF32Exclusive::new_bounded(start_t.get());\n                path_geometry::chop_quad_at(points, start_tt, &mut tmp0);\n                if stop_t == NormalizedF32::ONE {\n                    pb.quad_to_pt(tmp0[3], tmp0[4]);\n                } else {\n                    let new_t = (stop_t.get() - start_t.get()) / (1.0 - start_t.get());\n                    let new_t = NormalizedF32Exclusive::new_bounded(new_t);\n                    path_geometry::chop_quad_at(&tmp0[2..], new_t, &mut tmp1);\n                    pb.quad_to_pt(tmp1[1], tmp1[2]);\n                }\n            }\n        }\n        SegmentType::Cubic => {\n            let mut tmp0 = [Point::zero(); 7];\n            let mut tmp1 = [Point::zero(); 7];\n            if start_t == NormalizedF32::ZERO {\n                if stop_t == NormalizedF32::ONE {\n                    pb.cubic_to_pt(points[1], points[2], points[3]);\n                } else {\n                    let stop_t = NormalizedF32Exclusive::new_bounded(stop_t.get());\n                    path_geometry::chop_cubic_at2(array_ref![points, 0, 4], stop_t, &mut tmp0);\n                    pb.cubic_to_pt(tmp0[1], tmp0[2], tmp0[3]);\n                }\n            } else {\n                let start_tt = NormalizedF32Exclusive::new_bounded(start_t.get());\n                path_geometry::chop_cubic_at2(array_ref![points, 0, 4], start_tt, &mut tmp0);\n                if stop_t == NormalizedF32::ONE {\n                    pb.cubic_to_pt(tmp0[4], tmp0[5], tmp0[6]);\n                } else {\n                    let new_t = (stop_t.get() - start_t.get()) / (1.0 - start_t.get());\n                    let new_t = NormalizedF32Exclusive::new_bounded(new_t);\n                    path_geometry::chop_cubic_at2(array_ref![tmp0, 3, 4], new_t, &mut tmp1);\n                    pb.cubic_to_pt(tmp1[1], tmp1[2], tmp1[3]);\n                }\n            }\n        }\n    }\n}\n\nfn t_span_big_enough(t_span: u32) -> u32 {\n    debug_assert!(t_span <= MAX_T_VALUE);\n    t_span >> 10\n}\n\nfn quad_too_curvy(p0: Point, p1: Point, p2: Point, tolerance: f32) -> bool {\n    // diff = (a/4 + b/2 + c/4) - (a/2 + c/2)\n    // diff = -a/4 + b/2 - c/4\n    let dx = (p1.x).half() - (p0.x + p2.x).half().half();\n    let dy = (p1.y).half() - (p0.y + p2.y).half().half();\n\n    let dist = dx.abs().max(dy.abs());\n    dist > tolerance\n}\n\nfn cubic_too_curvy(p0: Point, p1: Point, p2: Point, p3: Point, tolerance: f32) -> bool {\n    let n0 = cheap_dist_exceeds_limit(\n        p1,\n        interp_safe(p0.x, p3.x, 1.0 / 3.0),\n        interp_safe(p0.y, p3.y, 1.0 / 3.0),\n        tolerance,\n    );\n\n    let n1 = cheap_dist_exceeds_limit(\n        p2,\n        interp_safe(p0.x, p3.x, 2.0 / 3.0),\n        interp_safe(p0.y, p3.y, 2.0 / 3.0),\n        tolerance,\n    );\n\n    n0 || n1\n}\n\nfn cheap_dist_exceeds_limit(pt: Point, x: f32, y: f32, tolerance: f32) -> bool {\n    let dist = (x - pt.x).abs().max((y - pt.y).abs());\n    // just made up the 1/2\n    dist > tolerance\n}\n\n/// Linearly interpolate between A and B, based on t.\n///\n/// If t is 0, return A. If t is 1, return B else interpolate.\nfn interp(a: f32, b: f32, t: NormalizedF32) -> f32 {\n    a + (b - a) * t.get()\n}\n\nfn interp_safe(a: f32, b: f32, t: f32) -> f32 {\n    debug_assert!(t >= 0.0 && t <= 1.0);\n    a + (b - a) * t\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/f32x2_t.rs",
      "sha256": "cd99d6e1fa00ed9c544af718b3f01b68a6eb500d183d3eeced804effb96878f8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse crate::NoStdFloat;\n\n// Right now, there are no visible benefits of using SIMD for f32x2. So we don't.\n/// A pair of f32 numbers.\n///\n/// Mainly for internal use. Do not rely on it!\n#[allow(non_camel_case_types)]\n#[derive(Copy, Clone, Default, PartialEq, Debug)]\npub struct f32x2(pub [f32; 2]);\n\nimpl f32x2 {\n    /// Creates a new pair.\n    pub fn new(a: f32, b: f32) -> f32x2 {\n        f32x2([a, b])\n    }\n\n    /// Creates a new pair from a single value.\n    pub fn splat(x: f32) -> f32x2 {\n        f32x2([x, x])\n    }\n\n    /// Returns an absolute value.\n    pub fn abs(self) -> f32x2 {\n        f32x2([self.x().abs(), self.y().abs()])\n    }\n\n    /// Returns a minimum value.\n    pub fn min(self, other: f32x2) -> f32x2 {\n        f32x2([pmin(self.x(), other.x()), pmin(self.y(), other.y())])\n    }\n\n    /// Returns a maximum value.\n    pub fn max(self, other: f32x2) -> f32x2 {\n        f32x2([pmax(self.x(), other.x()), pmax(self.y(), other.y())])\n    }\n\n    /// Returns a maximum of both values.\n    pub fn max_component(self) -> f32 {\n        pmax(self.x(), self.y())\n    }\n\n    /// Returns the first value.\n    pub fn x(&self) -> f32 {\n        self.0[0]\n    }\n\n    /// Returns the second value.\n    pub fn y(&self) -> f32 {\n        self.0[1]\n    }\n}\n\nimpl core::ops::Add<f32x2> for f32x2 {\n    type Output = f32x2;\n\n    fn add(self, other: f32x2) -> f32x2 {\n        f32x2([self.x() + other.x(), self.y() + other.y()])\n    }\n}\n\nimpl core::ops::Sub<f32x2> for f32x2 {\n    type Output = f32x2;\n\n    fn sub(self, other: f32x2) -> f32x2 {\n        f32x2([self.x() - other.x(), self.y() - other.y()])\n    }\n}\n\nimpl core::ops::Mul<f32x2> for f32x2 {\n    type Output = f32x2;\n\n    fn mul(self, other: f32x2) -> f32x2 {\n        f32x2([self.x() * other.x(), self.y() * other.y()])\n    }\n}\n\nimpl core::ops::Div<f32x2> for f32x2 {\n    type Output = f32x2;\n\n    fn div(self, other: f32x2) -> f32x2 {\n        f32x2([self.x() / other.x(), self.y() / other.y()])\n    }\n}\n\n// A faster and more forgiving f32 min/max implementation.\n//\n// Unlike std one, we do not care about NaN.\n\nfn pmax(a: f32, b: f32) -> f32 {\n    if a < b {\n        b\n    } else {\n        a\n    }\n}\n\nfn pmin(a: f32, b: f32) -> f32 {\n    if b < a {\n        b\n    } else {\n        a\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/f32x4_t.rs",
      "sha256": "6328e5670e9dffa3443b4ab2d7c7f1ab36e2ac14511c54c824e782c89a955607",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Right now, there are no visible benefits of using SIMD for f32x4. So we don't.\n#[derive(Default, Clone, Copy, PartialEq, Debug)]\n#[repr(C, align(16))]\npub struct f32x4(pub [f32; 4]);\n\nimpl f32x4 {\n    pub fn max(self, rhs: Self) -> Self {\n        Self([\n            self.0[0].max(rhs.0[0]),\n            self.0[1].max(rhs.0[1]),\n            self.0[2].max(rhs.0[2]),\n            self.0[3].max(rhs.0[3]),\n        ])\n    }\n\n    pub fn min(self, rhs: Self) -> Self {\n        Self([\n            self.0[0].min(rhs.0[0]),\n            self.0[1].min(rhs.0[1]),\n            self.0[2].min(rhs.0[2]),\n            self.0[3].min(rhs.0[3]),\n        ])\n    }\n}\n\nimpl core::ops::Add for f32x4 {\n    type Output = Self;\n\n    fn add(self, rhs: Self) -> Self::Output {\n        Self([\n            self.0[0] + rhs.0[0],\n            self.0[1] + rhs.0[1],\n            self.0[2] + rhs.0[2],\n            self.0[3] + rhs.0[3],\n        ])\n    }\n}\n\nimpl core::ops::AddAssign for f32x4 {\n    fn add_assign(&mut self, rhs: f32x4) {\n        *self = *self + rhs;\n    }\n}\n\nimpl core::ops::Sub for f32x4 {\n    type Output = Self;\n\n    fn sub(self, rhs: Self) -> Self::Output {\n        Self([\n            self.0[0] - rhs.0[0],\n            self.0[1] - rhs.0[1],\n            self.0[2] - rhs.0[2],\n            self.0[3] - rhs.0[3],\n        ])\n    }\n}\n\nimpl core::ops::Mul for f32x4 {\n    type Output = Self;\n\n    fn mul(self, rhs: Self) -> Self::Output {\n        Self([\n            self.0[0] * rhs.0[0],\n            self.0[1] * rhs.0[1],\n            self.0[2] * rhs.0[2],\n            self.0[3] * rhs.0[3],\n        ])\n    }\n}\n\nimpl core::ops::MulAssign for f32x4 {\n    fn mul_assign(&mut self, rhs: f32x4) {\n        *self = *self * rhs;\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/floating_point.rs",
      "sha256": "ef655a1eb3146fd0a77c57b584f164af73b51e56d36c485ef67fe139bbde11af",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse crate::scalar::Scalar;\n\npub use strict_num::{FiniteF32, NonZeroPositiveF32, NormalizedF32};\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse crate::NoStdFloat;\n\npub(crate) const FLOAT_PI: f32 = 3.14159265;\n\nconst MAX_I32_FITS_IN_F32: f32 = 2147483520.0;\nconst MIN_I32_FITS_IN_F32: f32 = -MAX_I32_FITS_IN_F32;\n\n// TODO: is there an std alternative?\n/// Custom float to integer conversion routines.\npub trait SaturateCast<T>: Sized {\n    /// Return the closest integer for the given float.\n    fn saturate_from(n: T) -> Self;\n}\n\nimpl SaturateCast<f32> for i32 {\n    /// Return the closest integer for the given float.\n    ///\n    /// Returns MAX_I32_FITS_IN_F32 for NaN.\n    fn saturate_from(mut x: f32) -> Self {\n        x = if x < MAX_I32_FITS_IN_F32 {\n            x\n        } else {\n            MAX_I32_FITS_IN_F32\n        };\n        x = if x > MIN_I32_FITS_IN_F32 {\n            x\n        } else {\n            MIN_I32_FITS_IN_F32\n        };\n        x as i32\n    }\n}\n\nimpl SaturateCast<f64> for i32 {\n    /// Return the closest integer for the given double.\n    ///\n    /// Returns i32::MAX for NaN.\n    fn saturate_from(mut x: f64) -> Self {\n        x = if x < i32::MAX as f64 {\n            x\n        } else {\n            i32::MAX as f64\n        };\n        x = if x > i32::MIN as f64 {\n            x\n        } else {\n            i32::MIN as f64\n        };\n        x as i32\n    }\n}\n\n/// Custom float to integer rounding routines.\n#[allow(missing_docs)]\npub trait SaturateRound<T>: SaturateCast<T> {\n    fn saturate_floor(n: T) -> Self;\n    fn saturate_ceil(n: T) -> Self;\n    fn saturate_round(n: T) -> Self;\n}\n\nimpl SaturateRound<f32> for i32 {\n    fn saturate_floor(x: f32) -> Self {\n        Self::saturate_from(x.floor())\n    }\n\n    fn saturate_ceil(x: f32) -> Self {\n        Self::saturate_from(x.ceil())\n    }\n\n    fn saturate_round(x: f32) -> Self {\n        Self::saturate_from(x.floor() + 0.5)\n    }\n}\n\n/// Return the float as a 2s compliment int. Just to be used to compare floats\n/// to each other or against positive float-bit-constants (like 0). This does\n/// not return the int equivalent of the float, just something cheaper for\n/// compares-only.\npub(crate) fn f32_as_2s_compliment(x: f32) -> i32 {\n    sign_bit_to_2s_compliment(bytemuck::cast(x))\n}\n\n/// Convert a sign-bit int (i.e. float interpreted as int) into a 2s compliement\n/// int. This also converts -0 (0x80000000) to 0. Doing this to a float allows\n/// it to be compared using normal C operators (<, <=, etc.)\nfn sign_bit_to_2s_compliment(mut x: i32) -> i32 {\n    if x < 0 {\n        x &= 0x7FFFFFFF;\n        x = -x;\n    }\n\n    x\n}\n\n/// An immutable `f32` that is larger than 0 but less then 1.\n#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Default, Debug)]\n#[repr(transparent)]\npub struct NormalizedF32Exclusive(FiniteF32);\n\nimpl NormalizedF32Exclusive {\n    /// Just a random, valid number.\n    pub const ANY: Self = Self::HALF;\n\n    /// A predefined 0.5 value.\n    pub const HALF: Self = NormalizedF32Exclusive(unsafe { FiniteF32::new_unchecked(0.5) });\n\n    /// Creates a `NormalizedF32Exclusive`.\n    pub fn new(n: f32) -> Option<Self> {\n        if n > 0.0 && n < 1.0 {\n            // `n` is guarantee to be finite after the bounds check.\n            FiniteF32::new(n).map(NormalizedF32Exclusive)\n        } else {\n            None\n        }\n    }\n\n    /// Creates a `NormalizedF32Exclusive` clamping the given value.\n    ///\n    /// Returns zero in case of NaN or infinity.\n    pub fn new_bounded(n: f32) -> Self {\n        let n = n.bound(core::f32::EPSILON, 1.0 - core::f32::EPSILON);\n        // `n` is guarantee to be finite after clamping.\n        debug_assert!(n.is_finite());\n        NormalizedF32Exclusive(unsafe { FiniteF32::new_unchecked(n) })\n    }\n\n    /// Returns the value as a primitive type.\n    pub fn get(self) -> f32 {\n        self.0.get()\n    }\n\n    /// Returns the value as a `FiniteF32`.\n    pub fn to_normalized(self) -> NormalizedF32 {\n        // NormalizedF32 is (0,1), while NormalizedF32 is [0,1], so it will always fit.\n        unsafe { NormalizedF32::new_unchecked(self.0.get()) }\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/lib.rs",
      "sha256": "497bff2609b15972184c9730facc3d08082d7371c6e23f40065f45b5acf66135",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n//! A [tiny-skia](https://github.com/RazrFalcon/tiny-skia) Bezier path implementation.\n//!\n//! Provides a memory-efficient Bezier path container, path builder, path stroker and path dasher.\n//!\n//! Also provides some basic geometry types, but they will be moved to an external crate eventually.\n//!\n//! Note that all types use single precision floats (`f32`), just like [Skia](https://skia.org/).\n\n#![no_std]\n#![warn(missing_docs)]\n#![warn(missing_copy_implementations)]\n#![warn(missing_debug_implementations)]\n#![allow(clippy::approx_constant)]\n#![allow(clippy::collapsible_if)]\n#![allow(clippy::eq_op)]\n#![allow(clippy::excessive_precision)]\n#![allow(clippy::identity_op)]\n#![allow(clippy::manual_range_contains)]\n#![allow(clippy::neg_cmp_op_on_partial_ord)]\n#![allow(clippy::too_many_arguments)]\n#![allow(clippy::upper_case_acronyms)]\n#![allow(clippy::wrong_self_convention)]\n\n#[cfg(not(any(feature = \"std\", feature = \"no-std-float\")))]\ncompile_error!(\"You have to activate either the `std` or the `no-std-float` feature.\");\n\n#[cfg(feature = \"std\")]\nextern crate std;\n\nextern crate alloc;\n\nmod dash;\nmod f32x2_t;\nmod f32x4_t;\nmod floating_point;\nmod path;\nmod path_builder;\npub mod path_geometry;\nmod rect;\nmod scalar;\nmod size;\nmod stroker;\nmod transform;\n\npub use dash::StrokeDash;\npub use f32x2_t::f32x2;\npub use floating_point::*;\npub use path::*;\npub use path_builder::*;\npub use rect::*;\npub use scalar::*;\npub use size::*;\npub use stroker::*;\npub use transform::*;\n\n/// An integer length that is guarantee to be > 0\ntype LengthU32 = core::num::NonZeroU32;\n\n/// A point.\n///\n/// Doesn't guarantee to be finite.\n#[allow(missing_docs)]\n#[repr(C)]\n#[derive(Copy, Clone, PartialEq, Default, Debug)]\npub struct Point {\n    pub x: f32,\n    pub y: f32,\n}\n\nimpl From<(f32, f32)> for Point {\n    #[inline]\n    fn from(v: (f32, f32)) -> Self {\n        Point { x: v.0, y: v.1 }\n    }\n}\n\nimpl Point {\n    /// Creates a new `Point`.\n    pub fn from_xy(x: f32, y: f32) -> Self {\n        Point { x, y }\n    }\n\n    /// Creates a new `Point` from `f32x2`.\n    pub fn from_f32x2(r: f32x2) -> Self {\n        Point::from_xy(r.x(), r.y())\n    }\n\n    /// Converts a `Point` into a `f32x2`.\n    pub fn to_f32x2(&self) -> f32x2 {\n        f32x2::new(self.x, self.y)\n    }\n\n    /// Creates a point at 0x0 position.\n    pub fn zero() -> Self {\n        Point { x: 0.0, y: 0.0 }\n    }\n\n    /// Returns true if x and y are both zero.\n    pub fn is_zero(&self) -> bool {\n        self.x == 0.0 && self.y == 0.0\n    }\n\n    /// Returns true if both x and y are measurable values.\n    ///\n    /// Both values are other than infinities and NaN.\n    pub fn is_finite(&self) -> bool {\n        (self.x * self.y).is_finite()\n    }\n\n    /// Checks that two `Point`s are almost equal.\n    pub(crate) fn almost_equal(&self, other: Point) -> bool {\n        !(*self - other).can_normalize()\n    }\n\n    /// Checks that two `Point`s are almost equal using the specified tolerance.\n    pub(crate) fn equals_within_tolerance(&self, other: Point, tolerance: f32) -> bool {\n        (self.x - other.x).is_nearly_zero_within_tolerance(tolerance)\n            && (self.y - other.y).is_nearly_zero_within_tolerance(tolerance)\n    }\n\n    /// Scales (fX, fY) so that length() returns one, while preserving ratio of fX to fY,\n    /// if possible.\n    ///\n    /// If prior length is nearly zero, sets vector to (0, 0) and returns\n    /// false; otherwise returns true.\n    pub fn normalize(&mut self) -> bool {\n        self.set_length_from(self.x, self.y, 1.0)\n    }\n\n    /// Sets vector to (x, y) scaled so length() returns one, and so that (x, y)\n    /// is proportional to (x, y).\n    ///\n    /// If (x, y) length is nearly zero, sets vector to (0, 0) and returns false;\n    /// otherwise returns true.\n    pub fn set_normalize(&mut self, x: f32, y: f32) -> bool {\n        self.set_length_from(x, y, 1.0)\n    }\n\n    pub(crate) fn can_normalize(&self) -> bool {\n        self.x.is_finite() && self.y.is_finite() && (self.x != 0.0 || self.y != 0.0)\n    }\n\n    /// Returns the Euclidean distance from origin.\n    pub fn length(&self) -> f32 {\n        let mag2 = self.x * self.x + self.y * self.y;\n        if mag2.is_finite() {\n            mag2.sqrt()\n        } else {\n            let xx = f64::from(self.x);\n            let yy = f64::from(self.y);\n            (xx * xx + yy * yy).sqrt() as f32\n        }\n    }\n\n    /// Scales vector so that distanceToOrigin() returns length, if possible.\n    ///\n    /// If former length is nearly zero, sets vector to (0, 0) and return false;\n    /// otherwise returns true.\n    pub fn set_length(&mut self, length: f32) -> bool {\n        self.set_length_from(self.x, self.y, length)\n    }\n\n    /// Sets vector to (x, y) scaled to length, if possible.\n    ///\n    /// If former length is nearly zero, sets vector to (0, 0) and return false;\n    /// otherwise returns true.\n    pub fn set_length_from(&mut self, x: f32, y: f32, length: f32) -> bool {\n        set_point_length(self, x, y, length, &mut None)\n    }\n\n    /// Returns the Euclidean distance from origin.\n    pub fn distance(&self, other: Point) -> f32 {\n        (*self - other).length()\n    }\n\n    /// Returns the dot product of two points.\n    pub fn dot(&self, other: Point) -> f32 {\n        self.x * other.x + self.y * other.y\n    }\n\n    /// Returns the cross product of vector and vec.\n    ///\n    /// Vector and vec form three-dimensional vectors with z-axis value equal to zero.\n    /// The cross product is a three-dimensional vector with x-axis and y-axis values\n    /// equal to zero. The cross product z-axis component is returned.\n    pub fn cross(&self, other: Point) -> f32 {\n        self.x * other.y - self.y * other.x\n    }\n\n    pub(crate) fn distance_to_sqd(&self, pt: Point) -> f32 {\n        let dx = self.x - pt.x;\n        let dy = self.y - pt.y;\n        dx * dx + dy * dy\n    }\n\n    pub(crate) fn length_sqd(&self) -> f32 {\n        self.dot(*self)\n    }\n\n    /// Scales Point in-place by scale.\n    pub fn scale(&mut self, scale: f32) {\n        self.x *= scale;\n        self.y *= scale;\n    }\n\n    pub(crate) fn scaled(&self, scale: f32) -> Self {\n        Point::from_xy(self.x * scale, self.y * scale)\n    }\n\n    pub(crate) fn swap_coords(&mut self) {\n        core::mem::swap(&mut self.x, &mut self.y);\n    }\n\n    pub(crate) fn rotate_cw(&mut self) {\n        self.swap_coords();\n        self.x = -self.x;\n    }\n\n    pub(crate) fn rotate_ccw(&mut self) {\n        self.swap_coords();\n        self.y = -self.y;\n    }\n}\n\n// We have to worry about 2 tricky conditions:\n// 1. underflow of mag2 (compared against nearlyzero^2)\n// 2. overflow of mag2 (compared w/ isfinite)\n//\n// If we underflow, we return false. If we overflow, we compute again using\n// doubles, which is much slower (3x in a desktop test) but will not overflow.\nfn set_point_length(\n    pt: &mut Point,\n    mut x: f32,\n    mut y: f32,\n    length: f32,\n    orig_length: &mut Option<f32>,\n) -> bool {\n    // our mag2 step overflowed to infinity, so use doubles instead.\n    // much slower, but needed when x or y are very large, other wise we\n    // divide by inf. and return (0,0) vector.\n    let xx = x as f64;\n    let yy = y as f64;\n    let dmag = (xx * xx + yy * yy).sqrt();\n    let dscale = length as f64 / dmag;\n    x *= dscale as f32;\n    y *= dscale as f32;\n\n    // check if we're not finite, or we're zero-length\n    if !x.is_finite() || !y.is_finite() || (x == 0.0 && y == 0.0) {\n        *pt = Point::zero();\n        return false;\n    }\n\n    let mut mag = 0.0;\n    if orig_length.is_some() {\n        mag = dmag as f32;\n    }\n\n    *pt = Point::from_xy(x, y);\n\n    if orig_length.is_some() {\n        *orig_length = Some(mag);\n    }\n\n    true\n}\n\nimpl core::ops::Neg for Point {\n    type Output = Point;\n\n    fn neg(self) -> Self::Output {\n        Point {\n            x: -self.x,\n            y: -self.y,\n        }\n    }\n}\n\nimpl core::ops::Add for Point {\n    type Output = Point;\n\n    fn add(self, other: Point) -> Self::Output {\n        Point::from_xy(self.x + other.x, self.y + other.y)\n    }\n}\n\nimpl core::ops::AddAssign for Point {\n    fn add_assign(&mut self, other: Point) {\n        self.x += other.x;\n        self.y += other.y;\n    }\n}\n\nimpl core::ops::Sub for Point {\n    type Output = Point;\n\n    fn sub(self, other: Point) -> Self::Output {\n        Point::from_xy(self.x - other.x, self.y - other.y)\n    }\n}\n\nimpl core::ops::SubAssign for Point {\n    fn sub_assign(&mut self, other: Point) {\n        self.x -= other.x;\n        self.y -= other.y;\n    }\n}\n\nimpl core::ops::Mul for Point {\n    type Output = Point;\n\n    fn mul(self, other: Point) -> Self::Output {\n        Point::from_xy(self.x * other.x, self.y * other.y)\n    }\n}\n\nimpl core::ops::MulAssign for Point {\n    fn mul_assign(&mut self, other: Point) {\n        self.x *= other.x;\n        self.y *= other.y;\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/path.rs",
      "sha256": "41d0090cfd4a5d9240801f946304f575dee70809e9f97938acb654e8fd435c1c",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse alloc::vec::Vec;\n\nuse crate::path_builder::PathBuilder;\nuse crate::transform::Transform;\nuse crate::{Point, Rect};\n\n/// A path verb.\n#[allow(missing_docs)]\n#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]\npub enum PathVerb {\n    Move,\n    Line,\n    Quad,\n    Cubic,\n    Close,\n}\n\n/// A Bezier path.\n///\n/// Can be created via [`PathBuilder`].\n/// Where [`PathBuilder`] can be created from the [`Path`] using [`clear`] to reuse the allocation.\n///\n/// Path is immutable and uses compact storage, where segment types and numbers are stored\n/// separately. Use can access path segments via [`Path::verbs`] and [`Path::points`],\n/// or via [`Path::segments`]\n///\n/// # Guarantees\n///\n/// - Has a valid, precomputed bounds.\n/// - All points are finite.\n/// - Has at least two segments.\n/// - Each contour starts with a MoveTo.\n/// - No duplicated Move.\n/// - No duplicated Close.\n/// - Zero-length contours are allowed.\n///\n/// [`PathBuilder`]: struct.PathBuilder.html\n/// [`clear`]: struct.Path.html#method.clear\n#[derive(Clone, PartialEq)]\npub struct Path {\n    pub(crate) verbs: Vec<PathVerb>,\n    pub(crate) points: Vec<Point>,\n    pub(crate) bounds: Rect,\n}\n\nimpl Path {\n    /// Returns the number of segments in the path.\n    pub fn len(&self) -> usize {\n        self.verbs.len()\n    }\n\n    /// Returns the bounds of the path's points.\n    ///\n    /// The value is already calculated.\n    pub fn bounds(&self) -> Rect {\n        self.bounds\n    }\n\n    /// Returns an internal vector of verbs.\n    pub fn verbs(&self) -> &[PathVerb] {\n        &self.verbs\n    }\n\n    /// Returns an internal vector of points.\n    pub fn points(&self) -> &[Point] {\n        &self.points\n    }\n\n    /// Returns a transformed in-place path.\n    ///\n    /// Some points may become NaN/inf therefore this method can fail.\n    pub fn transform(mut self, ts: Transform) -> Option<Self> {\n        if ts.is_identity() {\n            return Some(self);\n        }\n\n        ts.map_points(&mut self.points);\n\n        // Update bounds.\n        self.bounds = Rect::from_points(&self.points)?;\n\n        Some(self)\n    }\n\n    /// Returns an iterator over path's segments.\n    pub fn segments(&self) -> PathSegmentsIter {\n        PathSegmentsIter {\n            path: self,\n            verb_index: 0,\n            points_index: 0,\n            is_auto_close: false,\n            last_move_to: Point::zero(),\n            last_point: Point::zero(),\n        }\n    }\n\n    /// Clears the path and returns a `PathBuilder` that will reuse an allocated memory.\n    pub fn clear(mut self) -> PathBuilder {\n        self.verbs.clear();\n        self.points.clear();\n\n        PathBuilder {\n            verbs: self.verbs,\n            points: self.points,\n            last_move_to_index: 0,\n            move_to_required: true,\n        }\n    }\n}\n\nimpl core::fmt::Debug for Path {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        use core::fmt::Write;\n\n        let mut s = alloc::string::String::new();\n        for segment in self.segments() {\n            match segment {\n                PathSegment::MoveTo(p) => s.write_fmt(format_args!(\"M {} {} \", p.x, p.y))?,\n                PathSegment::LineTo(p) => s.write_fmt(format_args!(\"L {} {} \", p.x, p.y))?,\n                PathSegment::QuadTo(p0, p1) => {\n                    s.write_fmt(format_args!(\"Q {} {} {} {} \", p0.x, p0.y, p1.x, p1.y))?\n                }\n                PathSegment::CubicTo(p0, p1, p2) => s.write_fmt(format_args!(\n                    \"C {} {} {} {} {} {} \",\n                    p0.x, p0.y, p1.x, p1.y, p2.x, p2.y\n                ))?,\n                PathSegment::Close => s.write_fmt(format_args!(\"Z \"))?,\n            }\n        }\n\n        s.pop(); // ' '\n\n        f.debug_struct(\"Path\")\n            .field(\"segments\", &s)\n            .field(\"bounds\", &self.bounds)\n            .finish()\n    }\n}\n\n/// A path segment.\n#[allow(missing_docs)]\n#[derive(Copy, Clone, PartialEq, Debug)]\npub enum PathSegment {\n    MoveTo(Point),\n    LineTo(Point),\n    QuadTo(Point, Point),\n    CubicTo(Point, Point, Point),\n    Close,\n}\n\n/// A path segments iterator.\n#[allow(missing_debug_implementations)]\n#[derive(Clone)]\npub struct PathSegmentsIter<'a> {\n    path: &'a Path,\n    verb_index: usize,\n    points_index: usize,\n\n    is_auto_close: bool,\n    last_move_to: Point,\n    last_point: Point,\n}\n\nimpl<'a> PathSegmentsIter<'a> {\n    /// Sets the auto closing mode. Off by default.\n    ///\n    /// When enabled, emits an additional `PathSegment::Line` from the current position\n    /// to the previous `PathSegment::Move`. And only then emits `PathSegment::Close`.\n    pub fn set_auto_close(&mut self, flag: bool) {\n        self.is_auto_close = flag;\n    }\n\n    pub(crate) fn auto_close(&mut self) -> PathSegment {\n        if self.is_auto_close && self.last_point != self.last_move_to {\n            self.verb_index -= 1;\n            PathSegment::LineTo(self.last_move_to)\n        } else {\n            PathSegment::Close\n        }\n    }\n\n    pub(crate) fn has_valid_tangent(&self) -> bool {\n        let mut iter = self.clone();\n        while let Some(segment) = iter.next() {\n            match segment {\n                PathSegment::MoveTo(_) => {\n                    return false;\n                }\n                PathSegment::LineTo(p) => {\n                    if iter.last_point == p {\n                        continue;\n                    }\n\n                    return true;\n                }\n                PathSegment::QuadTo(p1, p2) => {\n                    if iter.last_point == p1 && iter.last_point == p2 {\n                        continue;\n                    }\n\n                    return true;\n                }\n                PathSegment::CubicTo(p1, p2, p3) => {\n                    if iter.last_point == p1 && iter.last_point == p2 && iter.last_point == p3 {\n                        continue;\n                    }\n\n                    return true;\n                }\n                PathSegment::Close => {\n                    return false;\n                }\n            }\n        }\n\n        false\n    }\n\n    /// Returns the current verb.\n    pub fn curr_verb(&self) -> PathVerb {\n        self.path.verbs[self.verb_index - 1]\n    }\n\n    /// Returns the next verb.\n    pub fn next_verb(&self) -> Option<PathVerb> {\n        self.path.verbs.get(self.verb_index).cloned()\n    }\n}\n\nimpl<'a> Iterator for PathSegmentsIter<'a> {\n    type Item = PathSegment;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.verb_index < self.path.verbs.len() {\n            let verb = self.path.verbs[self.verb_index];\n            self.verb_index += 1;\n\n            match verb {\n                PathVerb::Move => {\n                    self.points_index += 1;\n                    self.last_move_to = self.path.points[self.points_index - 1];\n                    self.last_point = self.last_move_to;\n                    Some(PathSegment::MoveTo(self.last_move_to))\n                }\n                PathVerb::Line => {\n                    self.points_index += 1;\n                    self.last_point = self.path.points[self.points_index - 1];\n                    Some(PathSegment::LineTo(self.last_point))\n                }\n                PathVerb::Quad => {\n                    self.points_index += 2;\n                    self.last_point = self.path.points[self.points_index - 1];\n                    Some(PathSegment::QuadTo(\n                        self.path.points[self.points_index - 2],\n                        self.last_point,\n                    ))\n                }\n                PathVerb::Cubic => {\n                    self.points_index += 3;\n                    self.last_point = self.path.points[self.points_index - 1];\n                    Some(PathSegment::CubicTo(\n                        self.path.points[self.points_index - 3],\n                        self.path.points[self.points_index - 2],\n                        self.last_point,\n                    ))\n                }\n                PathVerb::Close => {\n                    let seg = self.auto_close();\n                    self.last_point = self.last_move_to;\n                    Some(seg)\n                }\n            }\n        } else {\n            None\n        }\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/path_builder.rs",
      "sha256": "28c18ba8da6cdb85a08bc423175248c9a4d8d6736a2a1e4e389dce5fab2435c5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// NOTE: this is not SkPathBuilder, but rather a reimplementation of SkPath.\n\nuse alloc::vec;\nuse alloc::vec::Vec;\n\nuse crate::{Path, Point, Rect};\n\nuse crate::path::PathVerb;\nuse crate::path_geometry;\nuse crate::scalar::{Scalar, SCALAR_ROOT_2_OVER_2};\n\n#[derive(Copy, Clone, PartialEq, Debug)]\npub(crate) enum PathDirection {\n    /// Clockwise direction for adding closed contours.\n    CW,\n    /// Counter-clockwise direction for adding closed contours.\n    CCW,\n}\n\n/// A path builder.\n#[derive(Clone, Default, Debug)]\npub struct PathBuilder {\n    pub(crate) verbs: Vec<PathVerb>,\n    pub(crate) points: Vec<Point>,\n    pub(crate) last_move_to_index: usize,\n    pub(crate) move_to_required: bool,\n}\n\nimpl PathBuilder {\n    /// Creates a new builder.\n    pub fn new() -> Self {\n        PathBuilder {\n            verbs: Vec::new(),\n            points: Vec::new(),\n            last_move_to_index: 0,\n            move_to_required: true,\n        }\n    }\n\n    /// Creates a new builder with a specified capacity.\n    ///\n    /// Number of points depends on a verb type:\n    ///\n    /// - Move - 1\n    /// - Line - 1\n    /// - Quad - 2\n    /// - Cubic - 3\n    /// - Close - 0\n    pub fn with_capacity(verbs_capacity: usize, points_capacity: usize) -> Self {\n        PathBuilder {\n            verbs: Vec::with_capacity(verbs_capacity),\n            points: Vec::with_capacity(points_capacity),\n            last_move_to_index: 0,\n            move_to_required: true,\n        }\n    }\n\n    /// Creates a new `Path` from `Rect`.\n    ///\n    /// Never fails since `Rect` is always valid.\n    ///\n    /// Segments are created clockwise: TopLeft -> TopRight -> BottomRight -> BottomLeft\n    ///\n    /// The contour is closed.\n    pub fn from_rect(rect: Rect) -> Path {\n        let verbs = vec![\n            PathVerb::Move,\n            PathVerb::Line,\n            PathVerb::Line,\n            PathVerb::Line,\n            PathVerb::Close,\n        ];\n\n        let points = vec![\n            Point::from_xy(rect.left(), rect.top()),\n            Point::from_xy(rect.right(), rect.top()),\n            Point::from_xy(rect.right(), rect.bottom()),\n            Point::from_xy(rect.left(), rect.bottom()),\n        ];\n\n        Path {\n            bounds: rect,\n            verbs,\n            points,\n        }\n    }\n\n    /// Creates a new `Path` from a circle.\n    ///\n    /// See [`PathBuilder::push_circle`] for details.\n    pub fn from_circle(cx: f32, cy: f32, radius: f32) -> Option<Path> {\n        let mut b = PathBuilder::new();\n        b.push_circle(cx, cy, radius);\n        b.finish()\n    }\n\n    /// Creates a new `Path` from an oval.\n    ///\n    /// See [`PathBuilder::push_oval`] for details.\n    pub fn from_oval(oval: Rect) -> Option<Path> {\n        let mut b = PathBuilder::new();\n        b.push_oval(oval);\n        b.finish()\n    }\n\n    pub(crate) fn reserve(&mut self, additional_verbs: usize, additional_points: usize) {\n        self.verbs.reserve(additional_verbs);\n        self.points.reserve(additional_points);\n    }\n\n    /// Returns the current number of segments in the builder.\n    pub fn len(&self) -> usize {\n        self.verbs.len()\n    }\n\n    /// Checks if the builder has any segments added.\n    pub fn is_empty(&self) -> bool {\n        self.verbs.is_empty()\n    }\n\n    /// Adds beginning of a contour.\n    ///\n    /// Multiple continuous MoveTo segments are not allowed.\n    /// If the previous segment was also MoveTo, it will be overwritten with the current one.\n    pub fn move_to(&mut self, x: f32, y: f32) {\n        if let Some(PathVerb::Move) = self.verbs.last() {\n            let last_idx = self.points.len() - 1;\n            self.points[last_idx] = Point::from_xy(x, y);\n        } else {\n            self.last_move_to_index = self.points.len();\n            self.move_to_required = false;\n\n            self.verbs.push(PathVerb::Move);\n            self.points.push(Point::from_xy(x, y));\n        }\n    }\n\n    fn inject_move_to_if_needed(&mut self) {\n        if self.move_to_required {\n            match self.points.get(self.last_move_to_index).cloned() {\n                Some(p) => self.move_to(p.x, p.y),\n                None => self.move_to(0.0, 0.0),\n            }\n        }\n    }\n\n    /// Adds a line from the last point.\n    ///\n    /// - If `Path` is empty - adds Move(0, 0) first.\n    /// - If `Path` ends with Close - adds Move(last_x, last_y) first.\n    pub fn line_to(&mut self, x: f32, y: f32) {\n        self.inject_move_to_if_needed();\n\n        self.verbs.push(PathVerb::Line);\n        self.points.push(Point::from_xy(x, y));\n    }\n\n    /// Adds a quad curve from the last point to `x`, `y`.\n    ///\n    /// - If `Path` is empty - adds Move(0, 0) first.\n    /// - If `Path` ends with Close - adds Move(last_x, last_y) first.\n    pub fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) {\n        self.inject_move_to_if_needed();\n\n        self.verbs.push(PathVerb::Quad);\n        self.points.push(Point::from_xy(x1, y1));\n        self.points.push(Point::from_xy(x, y));\n    }\n\n    pub(crate) fn quad_to_pt(&mut self, p1: Point, p: Point) {\n        self.quad_to(p1.x, p1.y, p.x, p.y);\n    }\n\n    // We do not support conic segments, but Skia still relies on them from time to time.\n    // This method will simply convert the input data into quad segments.\n    pub(crate) fn conic_to(&mut self, x1: f32, y1: f32, x: f32, y: f32, weight: f32) {\n        // check for <= 0 or NaN with this test\n        if !(weight > 0.0) {\n            self.line_to(x, y);\n        } else if !weight.is_finite() {\n            self.line_to(x1, y1);\n            self.line_to(x, y);\n        } else if weight == 1.0 {\n            self.quad_to(x1, y1, x, y);\n        } else {\n            self.inject_move_to_if_needed();\n\n            let last = self.last_point().unwrap();\n            let quadder = path_geometry::AutoConicToQuads::compute(\n                last,\n                Point::from_xy(x1, y1),\n                Point::from_xy(x, y),\n                weight,\n            );\n            if let Some(quadder) = quadder {\n                // Points are ordered as: 0 - 1 2 - 3 4 - 5 6 - ..\n                // `count` is a number of pairs +1\n                let mut offset = 1;\n                for _ in 0..quadder.len {\n                    let pt1 = quadder.points[offset + 0];\n                    let pt2 = quadder.points[offset + 1];\n                    self.quad_to(pt1.x, pt1.y, pt2.x, pt2.y);\n                    offset += 2;\n                }\n            }\n        }\n    }\n\n    pub(crate) fn conic_points_to(&mut self, pt1: Point, pt2: Point, weight: f32) {\n        self.conic_to(pt1.x, pt1.y, pt2.x, pt2.y, weight);\n    }\n\n    /// Adds a cubic curve from the last point to `x`, `y`.\n    ///\n    /// - If `Path` is empty - adds Move(0, 0) first.\n    /// - If `Path` ends with Close - adds Move(last_x, last_y) first.\n    pub fn cubic_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {\n        self.inject_move_to_if_needed();\n\n        self.verbs.push(PathVerb::Cubic);\n        self.points.push(Point::from_xy(x1, y1));\n        self.points.push(Point::from_xy(x2, y2));\n        self.points.push(Point::from_xy(x, y));\n    }\n\n    pub(crate) fn cubic_to_pt(&mut self, p1: Point, p2: Point, p: Point) {\n        self.cubic_to(p1.x, p1.y, p2.x, p2.y, p.x, p.y);\n    }\n\n    /// Closes the current contour.\n    ///\n    /// A closed contour connects the first and the last Point\n    /// with a line, forming a continuous loop.\n    ///\n    /// Does nothing when `Path` is empty or already closed.\n    ///\n    /// Open and closed contour will be filled the same way.\n    /// Stroking an open contour will add LineCap at contour's start and end.\n    /// Stroking an closed contour will add LineJoin at contour's start and end.\n    pub fn close(&mut self) {\n        // don't add a close if it's the first verb or a repeat\n        if !self.verbs.is_empty() {\n            if self.verbs.last().cloned() != Some(PathVerb::Close) {\n                self.verbs.push(PathVerb::Close);\n            }\n        }\n\n        self.move_to_required = true;\n    }\n\n    /// Returns the last point if any.\n    pub fn last_point(&self) -> Option<Point> {\n        self.points.last().cloned()\n    }\n\n    pub(crate) fn set_last_point(&mut self, pt: Point) {\n        match self.points.last_mut() {\n            Some(last) => *last = pt,\n            None => self.move_to(pt.x, pt.y),\n        }\n    }\n\n    pub(crate) fn is_zero_length_since_point(&self, start_pt_index: usize) -> bool {\n        let count = self.points.len() - start_pt_index;\n        if count < 2 {\n            return true;\n        }\n\n        let first = self.points[start_pt_index];\n        for i in 1..count {\n            if first != self.points[start_pt_index + i] {\n                return false;\n            }\n        }\n\n        true\n    }\n\n    /// Adds a rectangle contour.\n    ///\n    /// The contour is closed and has a clock-wise direction.\n    pub fn push_rect(&mut self, rect: Rect) {\n        self.move_to(rect.left(), rect.top());\n        self.line_to(rect.right(), rect.top());\n        self.line_to(rect.right(), rect.bottom());\n        self.line_to(rect.left(), rect.bottom());\n        self.close();\n    }\n\n    /// Adds an oval contour bounded by the provided rectangle.\n    ///\n    /// The contour is closed and has a clock-wise direction.\n    pub fn push_oval(&mut self, oval: Rect) {\n        let cx = oval.left().half() + oval.right().half();\n        let cy = oval.top().half() + oval.bottom().half();\n\n        let oval_points = [\n            Point::from_xy(cx, oval.bottom()),\n            Point::from_xy(oval.left(), cy),\n            Point::from_xy(cx, oval.top()),\n            Point::from_xy(oval.right(), cy),\n        ];\n\n        let rect_points = [\n            Point::from_xy(oval.right(), oval.bottom()),\n            Point::from_xy(oval.left(), oval.bottom()),\n            Point::from_xy(oval.left(), oval.top()),\n            Point::from_xy(oval.right(), oval.top()),\n        ];\n\n        let weight = SCALAR_ROOT_2_OVER_2;\n        self.move_to(oval_points[3].x, oval_points[3].y);\n        for (p1, p2) in rect_points.iter().zip(oval_points.iter()) {\n            self.conic_points_to(*p1, *p2, weight);\n        }\n        self.close();\n    }\n\n    /// Adds a circle contour.\n    ///\n    /// The contour is closed and has a clock-wise direction.\n    ///\n    /// Does nothing when:\n    /// - `radius` <= 0\n    /// - any value is not finite or really large\n    pub fn push_circle(&mut self, x: f32, y: f32, r: f32) {\n        if let Some(r) = Rect::from_xywh(x - r, y - r, r + r, r + r) {\n            self.push_oval(r);\n        }\n    }\n\n    /// Adds a path.\n    pub fn push_path(&mut self, other: &Path) {\n        self.last_move_to_index = self.points.len();\n\n        self.verbs.extend_from_slice(&other.verbs);\n        self.points.extend_from_slice(&other.points);\n    }\n\n    pub(crate) fn push_path_builder(&mut self, other: &PathBuilder) {\n        if other.is_empty() {\n            return;\n        }\n\n        if self.last_move_to_index != 0 {\n            self.last_move_to_index = self.points.len() + other.last_move_to_index;\n        }\n\n        self.verbs.extend_from_slice(&other.verbs);\n        self.points.extend_from_slice(&other.points);\n    }\n\n    /// Appends, in a reverse order, the first contour of path ignoring path's last point.\n    pub(crate) fn reverse_path_to(&mut self, other: &PathBuilder) {\n        if other.is_empty() {\n            return;\n        }\n\n        debug_assert_eq!(other.verbs[0], PathVerb::Move);\n\n        let mut points_offset = other.points.len() - 1;\n        for verb in other.verbs.iter().rev() {\n            match verb {\n                PathVerb::Move => {\n                    // if the path has multiple contours, stop after reversing the last\n                    break;\n                }\n                PathVerb::Line => {\n                    // We're moving one point back manually, to prevent points_offset overflow.\n                    let pt = other.points[points_offset - 1];\n                    points_offset -= 1;\n                    self.line_to(pt.x, pt.y);\n                }\n                PathVerb::Quad => {\n                    let pt1 = other.points[points_offset - 1];\n                    let pt2 = other.points[points_offset - 2];\n                    points_offset -= 2;\n                    self.quad_to(pt1.x, pt1.y, pt2.x, pt2.y);\n                }\n                PathVerb::Cubic => {\n                    let pt1 = other.points[points_offset - 1];\n                    let pt2 = other.points[points_offset - 2];\n                    let pt3 = other.points[points_offset - 3];\n                    points_offset -= 3;\n                    self.cubic_to(pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y);\n                }\n                PathVerb::Close => {}\n            }\n        }\n    }\n\n    /// Reset the builder.\n    ///\n    /// Memory is not deallocated.\n    pub fn clear(&mut self) {\n        self.verbs.clear();\n        self.points.clear();\n        self.last_move_to_index = 0;\n        self.move_to_required = true;\n    }\n\n    /// Finishes the builder and returns a `Path`.\n    ///\n    /// Returns `None` when `Path` is empty or has invalid bounds.\n    pub fn finish(self) -> Option<Path> {\n        if self.is_empty() {\n            return None;\n        }\n\n        // Just a move to? Bail.\n        if self.verbs.len() == 1 {\n            return None;\n        }\n\n        let bounds = Rect::from_points(&self.points)?;\n\n        Some(Path {\n            bounds,\n            verbs: self.verbs,\n            points: self.points,\n        })\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/path_geometry.rs",
      "sha256": "3203df234be68484f7b4fd2e0ace6a4a868b234010e146b9b2a9305188ee19cb",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n//! A collection of functions to work with Bezier paths.\n//!\n//! Mainly for internal use. Do not rely on it!\n\n#![allow(missing_docs)]\n\nuse crate::{Point, Transform};\n\nuse crate::f32x2_t::f32x2;\nuse crate::floating_point::FLOAT_PI;\nuse crate::scalar::{Scalar, SCALAR_NEARLY_ZERO, SCALAR_ROOT_2_OVER_2};\n\nuse crate::floating_point::{NormalizedF32, NormalizedF32Exclusive};\nuse crate::path_builder::PathDirection;\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse crate::NoStdFloat;\n\n// use for : eval(t) == A * t^2 + B * t + C\n#[derive(Clone, Copy, Default, Debug)]\npub struct QuadCoeff {\n    pub a: f32x2,\n    pub b: f32x2,\n    pub c: f32x2,\n}\n\nimpl QuadCoeff {\n    pub fn from_points(points: &[Point; 3]) -> Self {\n        let c = points[0].to_f32x2();\n        let p1 = points[1].to_f32x2();\n        let p2 = points[2].to_f32x2();\n        let b = times_2(p1 - c);\n        let a = p2 - times_2(p1) + c;\n\n        QuadCoeff { a, b, c }\n    }\n\n    pub fn eval(&self, t: f32x2) -> f32x2 {\n        (self.a * t + self.b) * t + self.c\n    }\n}\n\n#[derive(Clone, Copy, Default, Debug)]\npub struct CubicCoeff {\n    pub a: f32x2,\n    pub b: f32x2,\n    pub c: f32x2,\n    pub d: f32x2,\n}\n\nimpl CubicCoeff {\n    pub fn from_points(points: &[Point; 4]) -> Self {\n        let p0 = points[0].to_f32x2();\n        let p1 = points[1].to_f32x2();\n        let p2 = points[2].to_f32x2();\n        let p3 = points[3].to_f32x2();\n        let three = f32x2::splat(3.0);\n\n        CubicCoeff {\n            a: p3 + three * (p1 - p2) - p0,\n            b: three * (p2 - times_2(p1) + p0),\n            c: three * (p1 - p0),\n            d: p0,\n        }\n    }\n\n    pub fn eval(&self, t: f32x2) -> f32x2 {\n        ((self.a * t + self.b) * t + self.c) * t + self.d\n    }\n}\n\n// TODO: to a custom type?\npub fn new_t_values() -> [NormalizedF32Exclusive; 3] {\n    [\n        NormalizedF32Exclusive::ANY,\n        NormalizedF32Exclusive::ANY,\n        NormalizedF32Exclusive::ANY,\n    ]\n}\n\npub fn chop_quad_at(src: &[Point], t: NormalizedF32Exclusive, dst: &mut [Point; 5]) {\n    let p0 = src[0].to_f32x2();\n    let p1 = src[1].to_f32x2();\n    let p2 = src[2].to_f32x2();\n    let tt = f32x2::splat(t.get());\n\n    let p01 = interp(p0, p1, tt);\n    let p12 = interp(p1, p2, tt);\n\n    dst[0] = Point::from_f32x2(p0);\n    dst[1] = Point::from_f32x2(p01);\n    dst[2] = Point::from_f32x2(interp(p01, p12, tt));\n    dst[3] = Point::from_f32x2(p12);\n    dst[4] = Point::from_f32x2(p2);\n}\n\n// From Numerical Recipes in C.\n//\n// Q = -1/2 (B + sign(B) sqrt[B*B - 4*A*C])\n// x1 = Q / A\n// x2 = C / Q\npub fn find_unit_quad_roots(\n    a: f32,\n    b: f32,\n    c: f32,\n    roots: &mut [NormalizedF32Exclusive; 3],\n) -> usize {\n    if a == 0.0 {\n        if let Some(r) = valid_unit_divide(-c, b) {\n            roots[0] = r;\n            return 1;\n        } else {\n            return 0;\n        }\n    }\n\n    // use doubles so we don't overflow temporarily trying to compute R\n    let mut dr = f64::from(b) * f64::from(b) - 4.0 * f64::from(a) * f64::from(c);\n    if dr < 0.0 {\n        return 0;\n    }\n    dr = dr.sqrt();\n    let r = dr as f32;\n    if !r.is_finite() {\n        return 0;\n    }\n\n    let q = if b < 0.0 {\n        -(b - r) / 2.0\n    } else {\n        -(b + r) / 2.0\n    };\n\n    let mut roots_offset = 0;\n    if let Some(r) = valid_unit_divide(q, a) {\n        roots[roots_offset] = r;\n        roots_offset += 1;\n    }\n\n    if let Some(r) = valid_unit_divide(c, q) {\n        roots[roots_offset] = r;\n        roots_offset += 1;\n    }\n\n    if roots_offset == 2 {\n        if roots[0].get() > roots[1].get() {\n            roots.swap(0, 1);\n        } else if roots[0] == roots[1] {\n            // nearly-equal?\n            roots_offset -= 1; // skip the double root\n        }\n    }\n\n    roots_offset\n}\n\npub fn chop_cubic_at2(src: &[Point; 4], t: NormalizedF32Exclusive, dst: &mut [Point]) {\n    let p0 = src[0].to_f32x2();\n    let p1 = src[1].to_f32x2();\n    let p2 = src[2].to_f32x2();\n    let p3 = src[3].to_f32x2();\n    let tt = f32x2::splat(t.get());\n\n    let ab = interp(p0, p1, tt);\n    let bc = interp(p1, p2, tt);\n    let cd = interp(p2, p3, tt);\n    let abc = interp(ab, bc, tt);\n    let bcd = interp(bc, cd, tt);\n    let abcd = interp(abc, bcd, tt);\n\n    dst[0] = Point::from_f32x2(p0);\n    dst[1] = Point::from_f32x2(ab);\n    dst[2] = Point::from_f32x2(abc);\n    dst[3] = Point::from_f32x2(abcd);\n    dst[4] = Point::from_f32x2(bcd);\n    dst[5] = Point::from_f32x2(cd);\n    dst[6] = Point::from_f32x2(p3);\n}\n\npub fn valid_unit_divide(mut numer: f32, mut denom: f32) -> Option<NormalizedF32Exclusive> {\n    if numer < 0.0 {\n        numer = -numer;\n        denom = -denom;\n    }\n\n    if denom == 0.0 || numer == 0.0 || numer >= denom {\n        return None;\n    }\n\n    let r = numer / denom;\n    NormalizedF32Exclusive::new(r)\n}\n\nfn interp(v0: f32x2, v1: f32x2, t: f32x2) -> f32x2 {\n    v0 + (v1 - v0) * t\n}\n\nfn times_2(value: f32x2) -> f32x2 {\n    value + value\n}\n\n// F(t)    = a (1 - t) ^ 2 + 2 b t (1 - t) + c t ^ 2\n// F'(t)   = 2 (b - a) + 2 (a - 2b + c) t\n// F''(t)  = 2 (a - 2b + c)\n//\n// A = 2 (b - a)\n// B = 2 (a - 2b + c)\n//\n// Maximum curvature for a quadratic means solving\n// Fx' Fx'' + Fy' Fy'' = 0\n//\n// t = - (Ax Bx + Ay By) / (Bx ^ 2 + By ^ 2)\npub(crate) fn find_quad_max_curvature(src: &[Point; 3]) -> NormalizedF32 {\n    let ax = src[1].x - src[0].x;\n    let ay = src[1].y - src[0].y;\n    let bx = src[0].x - src[1].x - src[1].x + src[2].x;\n    let by = src[0].y - src[1].y - src[1].y + src[2].y;\n\n    let mut numer = -(ax * bx + ay * by);\n    let mut denom = bx * bx + by * by;\n    if denom < 0.0 {\n        numer = -numer;\n        denom = -denom;\n    }\n\n    if numer <= 0.0 {\n        return NormalizedF32::ZERO;\n    }\n\n    if numer >= denom {\n        // Also catches denom=0\n        return NormalizedF32::ONE;\n    }\n\n    let t = numer / denom;\n    NormalizedF32::new(t).unwrap()\n}\n\npub(crate) fn eval_quad_at(src: &[Point; 3], t: NormalizedF32) -> Point {\n    Point::from_f32x2(QuadCoeff::from_points(src).eval(f32x2::splat(t.get())))\n}\n\npub(crate) fn eval_quad_tangent_at(src: &[Point; 3], tol: NormalizedF32) -> Point {\n    // The derivative equation is 2(b - a +(a - 2b +c)t). This returns a\n    // zero tangent vector when t is 0 or 1, and the control point is equal\n    // to the end point. In this case, use the quad end points to compute the tangent.\n    if (tol == NormalizedF32::ZERO && src[0] == src[1])\n        || (tol == NormalizedF32::ONE && src[1] == src[2])\n    {\n        return src[2] - src[0];\n    }\n\n    let p0 = src[0].to_f32x2();\n    let p1 = src[1].to_f32x2();\n    let p2 = src[2].to_f32x2();\n\n    let b = p1 - p0;\n    let a = p2 - p1 - b;\n    let t = a * f32x2::splat(tol.get()) + b;\n\n    Point::from_f32x2(t + t)\n}\n\n// Looking for F' dot F'' == 0\n//\n// A = b - a\n// B = c - 2b + a\n// C = d - 3c + 3b - a\n//\n// F' = 3Ct^2 + 6Bt + 3A\n// F'' = 6Ct + 6B\n//\n// F' dot F'' -> CCt^3 + 3BCt^2 + (2BB + CA)t + AB\npub fn find_cubic_max_curvature<'a>(\n    src: &[Point; 4],\n    t_values: &'a mut [NormalizedF32; 3],\n) -> &'a [NormalizedF32] {\n    let mut coeff_x = formulate_f1_dot_f2(&[src[0].x, src[1].x, src[2].x, src[3].x]);\n    let coeff_y = formulate_f1_dot_f2(&[src[0].y, src[1].y, src[2].y, src[3].y]);\n\n    for i in 0..4 {\n        coeff_x[i] += coeff_y[i];\n    }\n\n    let len = solve_cubic_poly(&coeff_x, t_values);\n    &t_values[0..len]\n}\n\n// Looking for F' dot F'' == 0\n//\n// A = b - a\n// B = c - 2b + a\n// C = d - 3c + 3b - a\n//\n// F' = 3Ct^2 + 6Bt + 3A\n// F'' = 6Ct + 6B\n//\n// F' dot F'' -> CCt^3 + 3BCt^2 + (2BB + CA)t + AB\nfn formulate_f1_dot_f2(src: &[f32; 4]) -> [f32; 4] {\n    let a = src[1] - src[0];\n    let b = src[2] - 2.0 * src[1] + src[0];\n    let c = src[3] + 3.0 * (src[1] - src[2]) - src[0];\n\n    [c * c, 3.0 * b * c, 2.0 * b * b + c * a, a * b]\n}\n\n/// Solve coeff(t) == 0, returning the number of roots that lie withing 0 < t < 1.\n/// coeff[0]t^3 + coeff[1]t^2 + coeff[2]t + coeff[3]\n///\n/// Eliminates repeated roots (so that all t_values are distinct, and are always\n/// in increasing order.\nfn solve_cubic_poly(coeff: &[f32; 4], t_values: &mut [NormalizedF32; 3]) -> usize {\n    if coeff[0].is_nearly_zero() {\n        // we're just a quadratic\n        let mut tmp_t = new_t_values();\n        let count = find_unit_quad_roots(coeff[1], coeff[2], coeff[3], &mut tmp_t);\n        for i in 0..count {\n            t_values[i] = tmp_t[i].to_normalized();\n        }\n\n        return count;\n    }\n\n    debug_assert!(coeff[0] != 0.0);\n\n    let inva = coeff[0].invert();\n    let a = coeff[1] * inva;\n    let b = coeff[2] * inva;\n    let c = coeff[3] * inva;\n\n    let q = (a * a - b * 3.0) / 9.0;\n    let r = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;\n\n    let q3 = q * q * q;\n    let r2_minus_q3 = r * r - q3;\n    let adiv3 = a / 3.0;\n\n    if r2_minus_q3 < 0.0 {\n        // we have 3 real roots\n        // the divide/root can, due to finite precisions, be slightly outside of -1...1\n        let theta = (r / q3.sqrt()).bound(-1.0, 1.0).acos();\n        let neg2_root_q = -2.0 * q.sqrt();\n\n        t_values[0] = NormalizedF32::new_clamped(neg2_root_q * (theta / 3.0).cos() - adiv3);\n        t_values[1] = NormalizedF32::new_clamped(\n            neg2_root_q * ((theta + 2.0 * FLOAT_PI) / 3.0).cos() - adiv3,\n        );\n        t_values[2] = NormalizedF32::new_clamped(\n            neg2_root_q * ((theta - 2.0 * FLOAT_PI) / 3.0).cos() - adiv3,\n        );\n\n        // now sort the roots\n        sort_array3(t_values);\n        collapse_duplicates3(t_values)\n    } else {\n        // we have 1 real root\n        let mut a = r.abs() + r2_minus_q3.sqrt();\n        a = scalar_cube_root(a);\n        if r > 0.0 {\n            a = -a;\n        }\n\n        if a != 0.0 {\n            a += q / a;\n        }\n\n        t_values[0] = NormalizedF32::new_clamped(a - adiv3);\n        1\n    }\n}\n\nfn sort_array3(array: &mut [NormalizedF32; 3]) {\n    if array[0] > array[1] {\n        array.swap(0, 1);\n    }\n\n    if array[1] > array[2] {\n        array.swap(1, 2);\n    }\n\n    if array[0] > array[1] {\n        array.swap(0, 1);\n    }\n}\n\nfn collapse_duplicates3(array: &mut [NormalizedF32; 3]) -> usize {\n    let mut len = 3;\n\n    if array[1] == array[2] {\n        len = 2;\n    }\n\n    if array[0] == array[1] {\n        len = 1;\n    }\n\n    len\n}\n\nfn scalar_cube_root(x: f32) -> f32 {\n    x.powf(0.3333333)\n}\n\n// This is SkEvalCubicAt split into three functions.\npub(crate) fn eval_cubic_pos_at(src: &[Point; 4], t: NormalizedF32) -> Point {\n    Point::from_f32x2(CubicCoeff::from_points(src).eval(f32x2::splat(t.get())))\n}\n\n// This is SkEvalCubicAt split into three functions.\npub(crate) fn eval_cubic_tangent_at(src: &[Point; 4], t: NormalizedF32) -> Point {\n    // The derivative equation returns a zero tangent vector when t is 0 or 1, and the\n    // adjacent control point is equal to the end point. In this case, use the\n    // next control point or the end points to compute the tangent.\n    if (t.get() == 0.0 && src[0] == src[1]) || (t.get() == 1.0 && src[2] == src[3]) {\n        let mut tangent = if t.get() == 0.0 {\n            src[2] - src[0]\n        } else {\n            src[3] - src[1]\n        };\n\n        if tangent.x == 0.0 && tangent.y == 0.0 {\n            tangent = src[3] - src[0];\n        }\n\n        tangent\n    } else {\n        eval_cubic_derivative(src, t)\n    }\n}\n\nfn eval_cubic_derivative(src: &[Point; 4], t: NormalizedF32) -> Point {\n    let p0 = src[0].to_f32x2();\n    let p1 = src[1].to_f32x2();\n    let p2 = src[2].to_f32x2();\n    let p3 = src[3].to_f32x2();\n\n    let coeff = QuadCoeff {\n        a: p3 + f32x2::splat(3.0) * (p1 - p2) - p0,\n        b: times_2(p2 - times_2(p1) + p0),\n        c: p1 - p0,\n    };\n\n    Point::from_f32x2(coeff.eval(f32x2::splat(t.get())))\n}\n\n// http://www.faculty.idc.ac.il/arik/quality/appendixA.html\n//\n// Inflection means that curvature is zero.\n// Curvature is [F' x F''] / [F'^3]\n// So we solve F'x X F''y - F'y X F''y == 0\n// After some canceling of the cubic term, we get\n// A = b - a\n// B = c - 2b + a\n// C = d - 3c + 3b - a\n// (BxCy - ByCx)t^2 + (AxCy - AyCx)t + AxBy - AyBx == 0\npub(crate) fn find_cubic_inflections<'a>(\n    src: &[Point; 4],\n    t_values: &'a mut [NormalizedF32Exclusive; 3],\n) -> &'a [NormalizedF32Exclusive] {\n    let ax = src[1].x - src[0].x;\n    let ay = src[1].y - src[0].y;\n    let bx = src[2].x - 2.0 * src[1].x + src[0].x;\n    let by = src[2].y - 2.0 * src[1].y + src[0].y;\n    let cx = src[3].x + 3.0 * (src[1].x - src[2].x) - src[0].x;\n    let cy = src[3].y + 3.0 * (src[1].y - src[2].y) - src[0].y;\n\n    let len = find_unit_quad_roots(\n        bx * cy - by * cx,\n        ax * cy - ay * cx,\n        ax * by - ay * bx,\n        t_values,\n    );\n\n    &t_values[0..len]\n}\n\n// Return location (in t) of cubic cusp, if there is one.\n// Note that classify cubic code does not reliably return all cusp'd cubics, so\n// it is not called here.\npub(crate) fn find_cubic_cusp(src: &[Point; 4]) -> Option<NormalizedF32Exclusive> {\n    // When the adjacent control point matches the end point, it behaves as if\n    // the cubic has a cusp: there's a point of max curvature where the derivative\n    // goes to zero. Ideally, this would be where t is zero or one, but math\n    // error makes not so. It is not uncommon to create cubics this way; skip them.\n    if src[0] == src[1] {\n        return None;\n    }\n\n    if src[2] == src[3] {\n        return None;\n    }\n\n    // Cubics only have a cusp if the line segments formed by the control and end points cross.\n    // Detect crossing if line ends are on opposite sides of plane formed by the other line.\n    if on_same_side(src, 0, 2) || on_same_side(src, 2, 0) {\n        return None;\n    }\n\n    // Cubics may have multiple points of maximum curvature, although at most only\n    // one is a cusp.\n    let mut t_values = [NormalizedF32::ZERO; 3];\n    let max_curvature = find_cubic_max_curvature(src, &mut t_values);\n    for test_t in max_curvature {\n        if 0.0 >= test_t.get() || test_t.get() >= 1.0 {\n            // no need to consider max curvature on the end\n            continue;\n        }\n\n        // A cusp is at the max curvature, and also has a derivative close to zero.\n        // Choose the 'close to zero' meaning by comparing the derivative length\n        // with the overall cubic size.\n        let d_pt = eval_cubic_derivative(src, *test_t);\n        let d_pt_magnitude = d_pt.length_sqd();\n        let precision = calc_cubic_precision(src);\n        if d_pt_magnitude < precision {\n            // All three max curvature t values may be close to the cusp;\n            // return the first one.\n            return Some(NormalizedF32Exclusive::new_bounded(test_t.get()));\n        }\n    }\n\n    None\n}\n\n// Returns true if both points src[testIndex], src[testIndex+1] are in the same half plane defined\n// by the line segment src[lineIndex], src[lineIndex+1].\nfn on_same_side(src: &[Point; 4], test_index: usize, line_index: usize) -> bool {\n    let origin = src[line_index];\n    let line = src[line_index + 1] - origin;\n    let mut crosses = [0.0, 0.0];\n    for index in 0..2 {\n        let test_line = src[test_index + index] - origin;\n        crosses[index] = line.cross(test_line);\n    }\n\n    crosses[0] * crosses[1] >= 0.0\n}\n\n// Returns a constant proportional to the dimensions of the cubic.\n// Constant found through experimentation -- maybe there's a better way....\nfn calc_cubic_precision(src: &[Point; 4]) -> f32 {\n    (src[1].distance_to_sqd(src[0])\n        + src[2].distance_to_sqd(src[1])\n        + src[3].distance_to_sqd(src[2]))\n        * 1e-8\n}\n\n#[derive(Copy, Clone, Default, Debug)]\npub(crate) struct Conic {\n    pub points: [Point; 3],\n    pub weight: f32,\n}\n\nimpl Conic {\n    pub fn new(pt0: Point, pt1: Point, pt2: Point, weight: f32) -> Self {\n        Conic {\n            points: [pt0, pt1, pt2],\n            weight,\n        }\n    }\n\n    pub fn from_points(points: &[Point], weight: f32) -> Self {\n        Conic {\n            points: [points[0], points[1], points[2]],\n            weight,\n        }\n    }\n\n    fn compute_quad_pow2(&self, tolerance: f32) -> Option<u8> {\n        if tolerance < 0.0 || !tolerance.is_finite() {\n            return None;\n        }\n\n        if !self.points[0].is_finite() || !self.points[1].is_finite() || !self.points[2].is_finite()\n        {\n            return None;\n        }\n\n        // Limit the number of suggested quads to approximate a conic\n        const MAX_CONIC_TO_QUAD_POW2: usize = 4;\n\n        // \"High order approximation of conic sections by quadratic splines\"\n        // by Michael Floater, 1993\n        let a = self.weight - 1.0;\n        let k = a / (4.0 * (2.0 + a));\n        let x = k * (self.points[0].x - 2.0 * self.points[1].x + self.points[2].x);\n        let y = k * (self.points[0].y - 2.0 * self.points[1].y + self.points[2].y);\n\n        let mut error = (x * x + y * y).sqrt();\n        let mut pow2 = 0;\n        for _ in 0..MAX_CONIC_TO_QUAD_POW2 {\n            if error <= tolerance {\n                break;\n            }\n\n            error *= 0.25;\n            pow2 += 1;\n        }\n\n        // Unlike Skia, we always expect `pow2` to be at least 1.\n        // Otherwise it produces ugly results.\n        Some(pow2.max(1))\n    }\n\n    // Chop this conic into N quads, stored continuously in pts[], where\n    // N = 1 << pow2. The amount of storage needed is (1 + 2 * N)\n    pub fn chop_into_quads_pow2(&self, pow2: u8, points: &mut [Point]) -> u8 {\n        debug_assert!(pow2 < 5);\n\n        points[0] = self.points[0];\n        subdivide(self, &mut points[1..], pow2);\n\n        let quad_count = 1 << pow2;\n        let pt_count = 2 * quad_count + 1;\n        if points.iter().take(pt_count).any(|n| !n.is_finite()) {\n            // if we generated a non-finite, pin ourselves to the middle of the hull,\n            // as our first and last are already on the first/last pts of the hull.\n            for p in points.iter_mut().take(pt_count - 1).skip(1) {\n                *p = self.points[1];\n            }\n        }\n\n        1 << pow2\n    }\n\n    fn chop(&self) -> (Conic, Conic) {\n        let scale = f32x2::splat((1.0 + self.weight).invert());\n        let new_w = subdivide_weight_value(self.weight);\n\n        let p0 = self.points[0].to_f32x2();\n        let p1 = self.points[1].to_f32x2();\n        let p2 = self.points[2].to_f32x2();\n        let ww = f32x2::splat(self.weight);\n\n        let wp1 = ww * p1;\n        let m = (p0 + times_2(wp1) + p2) * scale * f32x2::splat(0.5);\n        let mut m_pt = Point::from_f32x2(m);\n        if !m_pt.is_finite() {\n            let w_d = self.weight as f64;\n            let w_2 = w_d * 2.0;\n            let scale_half = 1.0 / (1.0 + w_d) * 0.5;\n            m_pt.x = ((self.points[0].x as f64\n                + w_2 * self.points[1].x as f64\n                + self.points[2].x as f64)\n                * scale_half) as f32;\n\n            m_pt.y = ((self.points[0].y as f64\n                + w_2 * self.points[1].y as f64\n                + self.points[2].y as f64)\n                * scale_half) as f32;\n        }\n\n        (\n            Conic {\n                points: [self.points[0], Point::from_f32x2((p0 + wp1) * scale), m_pt],\n                weight: new_w,\n            },\n            Conic {\n                points: [m_pt, Point::from_f32x2((wp1 + p2) * scale), self.points[2]],\n                weight: new_w,\n            },\n        )\n    }\n\n    pub fn build_unit_arc(\n        u_start: Point,\n        u_stop: Point,\n        dir: PathDirection,\n        user_transform: Transform,\n        dst: &mut [Conic; 5],\n    ) -> Option<&[Conic]> {\n        // rotate by x,y so that u_start is (1.0)\n        let x = u_start.dot(u_stop);\n        let mut y = u_start.cross(u_stop);\n\n        let abs_y = y.abs();\n\n        // check for (effectively) coincident vectors\n        // this can happen if our angle is nearly 0 or nearly 180 (y == 0)\n        // ... we use the dot-prod to distinguish between 0 and 180 (x > 0)\n        if abs_y <= SCALAR_NEARLY_ZERO\n            && x > 0.0\n            && ((y >= 0.0 && dir == PathDirection::CW) || (y <= 0.0 && dir == PathDirection::CCW))\n        {\n            return None;\n        }\n\n        if dir == PathDirection::CCW {\n            y = -y;\n        }\n\n        // We decide to use 1-conic per quadrant of a circle. What quadrant does [xy] lie in?\n        //      0 == [0  .. 90)\n        //      1 == [90 ..180)\n        //      2 == [180..270)\n        //      3 == [270..360)\n        //\n        let mut quadrant = 0;\n        if y == 0.0 {\n            quadrant = 2; // 180\n            debug_assert!((x + 1.0) <= SCALAR_NEARLY_ZERO);\n        } else if x == 0.0 {\n            debug_assert!(abs_y - 1.0 <= SCALAR_NEARLY_ZERO);\n            quadrant = if y > 0.0 { 1 } else { 3 }; // 90 / 270\n        } else {\n            if y < 0.0 {\n                quadrant += 2;\n            }\n\n            if (x < 0.0) != (y < 0.0) {\n                quadrant += 1;\n            }\n        }\n\n        let quadrant_points = [\n            Point::from_xy(1.0, 0.0),\n            Point::from_xy(1.0, 1.0),\n            Point::from_xy(0.0, 1.0),\n            Point::from_xy(-1.0, 1.0),\n            Point::from_xy(-1.0, 0.0),\n            Point::from_xy(-1.0, -1.0),\n            Point::from_xy(0.0, -1.0),\n            Point::from_xy(1.0, -1.0),\n        ];\n\n        const QUADRANT_WEIGHT: f32 = SCALAR_ROOT_2_OVER_2;\n\n        let mut conic_count = quadrant;\n        for i in 0..conic_count {\n            dst[i] = Conic::from_points(&quadrant_points[i * 2..], QUADRANT_WEIGHT);\n        }\n\n        // Now compute any remaing (sub-90-degree) arc for the last conic\n        let final_pt = Point::from_xy(x, y);\n        let last_q = quadrant_points[quadrant * 2]; // will already be a unit-vector\n        let dot = last_q.dot(final_pt);\n        debug_assert!(0.0 <= dot && dot <= 1.0 + SCALAR_NEARLY_ZERO);\n\n        if dot < 1.0 {\n            let mut off_curve = Point::from_xy(last_q.x + x, last_q.y + y);\n            // compute the bisector vector, and then rescale to be the off-curve point.\n            // we compute its length from cos(theta/2) = length / 1, using half-angle identity we get\n            // length = sqrt(2 / (1 + cos(theta)). We already have cos() when to computed the dot.\n            // This is nice, since our computed weight is cos(theta/2) as well!\n            let cos_theta_over_2 = ((1.0 + dot) / 2.0).sqrt();\n            off_curve.set_length(cos_theta_over_2.invert());\n            if !last_q.almost_equal(off_curve) {\n                dst[conic_count] = Conic::new(last_q, off_curve, final_pt, cos_theta_over_2);\n                conic_count += 1;\n            }\n        }\n\n        // now handle counter-clockwise and the initial unitStart rotation\n        let mut transform = Transform::from_sin_cos(u_start.y, u_start.x);\n        if dir == PathDirection::CCW {\n            transform = transform.pre_scale(1.0, -1.0);\n        }\n\n        transform = transform.post_concat(user_transform);\n\n        for conic in dst.iter_mut().take(conic_count) {\n            transform.map_points(&mut conic.points);\n        }\n\n        if conic_count == 0 {\n            None\n        } else {\n            Some(&dst[0..conic_count])\n        }\n    }\n}\n\nfn subdivide_weight_value(w: f32) -> f32 {\n    (0.5 + w * 0.5).sqrt()\n}\n\nfn subdivide<'a>(src: &Conic, mut points: &'a mut [Point], mut level: u8) -> &'a mut [Point] {\n    if level == 0 {\n        points[0] = src.points[1];\n        points[1] = src.points[2];\n        &mut points[2..]\n    } else {\n        let mut dst = src.chop();\n\n        let start_y = src.points[0].y;\n        let end_y = src.points[2].y;\n        if between(start_y, src.points[1].y, end_y) {\n            // If the input is monotonic and the output is not, the scan converter hangs.\n            // Ensure that the chopped conics maintain their y-order.\n            let mid_y = dst.0.points[2].y;\n            if !between(start_y, mid_y, end_y) {\n                // If the computed midpoint is outside the ends, move it to the closer one.\n                let closer_y = if (mid_y - start_y).abs() < (mid_y - end_y).abs() {\n                    start_y\n                } else {\n                    end_y\n                };\n                dst.0.points[2].y = closer_y;\n                dst.1.points[0].y = closer_y;\n            }\n\n            if !between(start_y, dst.0.points[1].y, dst.0.points[2].y) {\n                // If the 1st control is not between the start and end, put it at the start.\n                // This also reduces the quad to a line.\n                dst.0.points[1].y = start_y;\n            }\n\n            if !between(dst.1.points[0].y, dst.1.points[1].y, end_y) {\n                // If the 2nd control is not between the start and end, put it at the end.\n                // This also reduces the quad to a line.\n                dst.1.points[1].y = end_y;\n            }\n\n            // Verify that all five points are in order.\n            debug_assert!(between(start_y, dst.0.points[1].y, dst.0.points[2].y));\n            debug_assert!(between(\n                dst.0.points[1].y,\n                dst.0.points[2].y,\n                dst.1.points[1].y\n            ));\n            debug_assert!(between(dst.0.points[2].y, dst.1.points[1].y, end_y));\n        }\n\n        level -= 1;\n        points = subdivide(&dst.0, points, level);\n        subdivide(&dst.1, points, level)\n    }\n}\n\n// This was originally developed and tested for pathops: see SkOpTypes.h\n// returns true if (a <= b <= c) || (a >= b >= c)\nfn between(a: f32, b: f32, c: f32) -> bool {\n    (a - b) * (c - b) <= 0.0\n}\n\npub(crate) struct AutoConicToQuads {\n    pub points: [Point; 64],\n    pub len: u8, // the number of quads\n}\n\nimpl AutoConicToQuads {\n    pub fn compute(pt0: Point, pt1: Point, pt2: Point, weight: f32) -> Option<Self> {\n        let conic = Conic::new(pt0, pt1, pt2, weight);\n        let pow2 = conic.compute_quad_pow2(0.25)?;\n        let mut points = [Point::zero(); 64];\n        let len = conic.chop_into_quads_pow2(pow2, &mut points);\n        Some(AutoConicToQuads { points, len })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn eval_cubic_at_1() {\n        let src = [\n            Point::from_xy(30.0, 40.0),\n            Point::from_xy(30.0, 40.0),\n            Point::from_xy(171.0, 45.0),\n            Point::from_xy(180.0, 155.0),\n        ];\n\n        assert_eq!(\n            eval_cubic_pos_at(&src, NormalizedF32::ZERO),\n            Point::from_xy(30.0, 40.0)\n        );\n        assert_eq!(\n            eval_cubic_tangent_at(&src, NormalizedF32::ZERO),\n            Point::from_xy(141.0, 5.0)\n        );\n    }\n\n    #[test]\n    fn find_cubic_max_curvature_1() {\n        let src = [\n            Point::from_xy(20.0, 160.0),\n            Point::from_xy(20.0001, 160.0),\n            Point::from_xy(160.0, 20.0),\n            Point::from_xy(160.0001, 20.0),\n        ];\n\n        let mut t_values = [NormalizedF32::ZERO; 3];\n        let t_values = find_cubic_max_curvature(&src, &mut t_values);\n\n        assert_eq!(\n            &t_values,\n            &[\n                NormalizedF32::ZERO,\n                NormalizedF32::new_clamped(0.5),\n                NormalizedF32::ONE,\n            ]\n        );\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/rect.rs",
      "sha256": "d8da6ff60134d50ad36f52f05c097eaefe5c31d08eff30af68c21cbc42da72dd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse core::convert::TryFrom;\n\nuse crate::{FiniteF32, IntSize, LengthU32, PathBuilder, Point, SaturateRound, Size, Transform};\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse crate::NoStdFloat;\n\n/// An integer rectangle.\n///\n/// # Guarantees\n///\n/// - Width and height are in 1..=i32::MAX range.\n/// - x+width and y+height does not overflow.\n#[allow(missing_docs)]\n#[derive(Copy, Clone, PartialEq, Debug)]\npub struct IntRect {\n    x: i32,\n    y: i32,\n    width: LengthU32,\n    height: LengthU32,\n}\n\nimpl IntRect {\n    /// Creates a new `IntRect`.\n    pub fn from_xywh(x: i32, y: i32, width: u32, height: u32) -> Option<Self> {\n        x.checked_add(i32::try_from(width).ok()?)?;\n        y.checked_add(i32::try_from(height).ok()?)?;\n\n        Some(IntRect {\n            x,\n            y,\n            width: LengthU32::new(width)?,\n            height: LengthU32::new(height)?,\n        })\n    }\n\n    /// Creates a new `IntRect`.\n    pub fn from_ltrb(left: i32, top: i32, right: i32, bottom: i32) -> Option<Self> {\n        let width = u32::try_from(right.checked_sub(left)?).ok()?;\n        let height = u32::try_from(bottom.checked_sub(top)?).ok()?;\n        IntRect::from_xywh(left, top, width, height)\n    }\n\n    /// Returns rect's X position.\n    pub fn x(&self) -> i32 {\n        self.x\n    }\n\n    /// Returns rect's Y position.\n    pub fn y(&self) -> i32 {\n        self.y\n    }\n\n    /// Returns rect's width.\n    pub fn width(&self) -> u32 {\n        self.width.get()\n    }\n\n    /// Returns rect's height.\n    pub fn height(&self) -> u32 {\n        self.height.get()\n    }\n\n    /// Returns rect's left edge.\n    pub fn left(&self) -> i32 {\n        self.x\n    }\n\n    /// Returns rect's top edge.\n    pub fn top(&self) -> i32 {\n        self.y\n    }\n\n    /// Returns rect's right edge.\n    pub fn right(&self) -> i32 {\n        // No overflow is guaranteed by constructors.\n        self.x + self.width.get() as i32\n    }\n\n    /// Returns rect's bottom edge.\n    pub fn bottom(&self) -> i32 {\n        // No overflow is guaranteed by constructors.\n        self.y + self.height.get() as i32\n    }\n\n    /// Returns rect's size.\n    pub fn size(&self) -> IntSize {\n        IntSize::from_wh_safe(self.width, self.height)\n    }\n\n    /// Checks that the rect is completely includes `other` Rect.\n    pub fn contains(&self, other: &Self) -> bool {\n        self.x <= other.x\n            && self.y <= other.y\n            && self.right() >= other.right()\n            && self.bottom() >= other.bottom()\n    }\n\n    /// Returns an intersection of two rectangles.\n    ///\n    /// Returns `None` otherwise.\n    pub fn intersect(&self, other: &Self) -> Option<Self> {\n        let left = self.x.max(other.x);\n        let top = self.y.max(other.y);\n\n        let right = self.right().min(other.right());\n        let bottom = self.bottom().min(other.bottom());\n\n        let w = u32::try_from(right.checked_sub(left)?).ok()?;\n        let h = u32::try_from(bottom.checked_sub(top)?).ok()?;\n\n        IntRect::from_xywh(left, top, w, h)\n    }\n\n    /// Insets the rectangle.\n    pub fn inset(&self, dx: i32, dy: i32) -> Option<Self> {\n        IntRect::from_ltrb(\n            self.left() + dx,\n            self.top() + dy,\n            self.right() - dx,\n            self.bottom() - dy,\n        )\n    }\n\n    /// Outsets the rectangle.\n    pub fn make_outset(&self, dx: i32, dy: i32) -> Option<Self> {\n        IntRect::from_ltrb(\n            self.left().saturating_sub(dx),\n            self.top().saturating_sub(dy),\n            self.right().saturating_add(dx),\n            self.bottom().saturating_add(dy),\n        )\n    }\n\n    /// Translates the rect by the specified offset.\n    pub fn translate(&self, tx: i32, ty: i32) -> Option<Self> {\n        IntRect::from_xywh(self.x() + tx, self.y() + ty, self.width(), self.height())\n    }\n\n    /// Translates the rect to the specified position.\n    pub fn translate_to(&self, x: i32, y: i32) -> Option<Self> {\n        IntRect::from_xywh(x, y, self.width(), self.height())\n    }\n\n    /// Converts into `Rect`.\n    pub fn to_rect(&self) -> Rect {\n        // Can't fail, because `IntRect` is always valid.\n        Rect::from_ltrb(\n            self.x as f32,\n            self.y as f32,\n            self.x as f32 + self.width.get() as f32,\n            self.y as f32 + self.height.get() as f32,\n        )\n        .unwrap()\n    }\n}\n\n#[cfg(test)]\nmod int_rect_tests {\n    use super::*;\n\n    #[test]\n    fn tests() {\n        assert_eq!(IntRect::from_xywh(0, 0, 0, 0), None);\n        assert_eq!(IntRect::from_xywh(0, 0, 1, 0), None);\n        assert_eq!(IntRect::from_xywh(0, 0, 0, 1), None);\n\n        assert_eq!(\n            IntRect::from_xywh(0, 0, core::u32::MAX, core::u32::MAX),\n            None\n        );\n        assert_eq!(IntRect::from_xywh(0, 0, 1, core::u32::MAX), None);\n        assert_eq!(IntRect::from_xywh(0, 0, core::u32::MAX, 1), None);\n\n        assert_eq!(IntRect::from_xywh(core::i32::MAX, 0, 1, 1), None);\n        assert_eq!(IntRect::from_xywh(0, core::i32::MAX, 1, 1), None);\n\n        {\n            // No intersection.\n            let r1 = IntRect::from_xywh(1, 2, 3, 4).unwrap();\n            let r2 = IntRect::from_xywh(11, 12, 13, 14).unwrap();\n            assert_eq!(r1.intersect(&r2), None);\n        }\n\n        {\n            // Second inside the first one.\n            let r1 = IntRect::from_xywh(1, 2, 30, 40).unwrap();\n            let r2 = IntRect::from_xywh(11, 12, 13, 14).unwrap();\n            assert_eq!(r1.intersect(&r2), IntRect::from_xywh(11, 12, 13, 14));\n        }\n\n        {\n            // Partial overlap.\n            let r1 = IntRect::from_xywh(1, 2, 30, 40).unwrap();\n            let r2 = IntRect::from_xywh(11, 12, 50, 60).unwrap();\n            assert_eq!(r1.intersect(&r2), IntRect::from_xywh(11, 12, 20, 30));\n        }\n    }\n}\n\n/// A rectangle defined by left, top, right and bottom edges.\n///\n/// Can have zero width and/or height. But not a negative one.\n///\n/// # Guarantees\n///\n/// - All values are finite.\n/// - Left edge is <= right.\n/// - Top edge is <= bottom.\n/// - Width and height are <= f32::MAX.\n#[allow(missing_docs)]\n#[derive(Copy, Clone, PartialEq)]\npub struct Rect {\n    left: FiniteF32,\n    top: FiniteF32,\n    right: FiniteF32,\n    bottom: FiniteF32,\n}\n\nimpl core::fmt::Debug for Rect {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        f.debug_struct(\"Rect\")\n            .field(\"left\", &self.left.get())\n            .field(\"top\", &self.top.get())\n            .field(\"right\", &self.right.get())\n            .field(\"bottom\", &self.bottom.get())\n            .finish()\n    }\n}\n\nimpl Rect {\n    /// Creates new `Rect`.\n    pub fn from_ltrb(left: f32, top: f32, right: f32, bottom: f32) -> Option<Self> {\n        let left = FiniteF32::new(left)?;\n        let top = FiniteF32::new(top)?;\n        let right = FiniteF32::new(right)?;\n        let bottom = FiniteF32::new(bottom)?;\n\n        if left.get() <= right.get() && top.get() <= bottom.get() {\n            // Width and height must not overflow.\n            checked_f32_sub(right.get(), left.get())?;\n            checked_f32_sub(bottom.get(), top.get())?;\n\n            Some(Rect {\n                left,\n                top,\n                right,\n                bottom,\n            })\n        } else {\n            None\n        }\n    }\n\n    /// Creates new `Rect`.\n    pub fn from_xywh(x: f32, y: f32, w: f32, h: f32) -> Option<Self> {\n        Rect::from_ltrb(x, y, w + x, h + y)\n    }\n\n    /// Returns the left edge.\n    pub fn left(&self) -> f32 {\n        self.left.get()\n    }\n\n    /// Returns the top edge.\n    pub fn top(&self) -> f32 {\n        self.top.get()\n    }\n\n    /// Returns the right edge.\n    pub fn right(&self) -> f32 {\n        self.right.get()\n    }\n\n    /// Returns the bottom edge.\n    pub fn bottom(&self) -> f32 {\n        self.bottom.get()\n    }\n\n    /// Returns rect's X position.\n    pub fn x(&self) -> f32 {\n        self.left.get()\n    }\n\n    /// Returns rect's Y position.\n    pub fn y(&self) -> f32 {\n        self.top.get()\n    }\n\n    /// Returns rect's width.\n    #[inline]\n    pub fn width(&self) -> f32 {\n        self.right.get() - self.left.get()\n    }\n\n    /// Returns rect's height.\n    #[inline]\n    pub fn height(&self) -> f32 {\n        self.bottom.get() - self.top.get()\n    }\n\n    /// Converts into an `IntRect` by adding 0.5 and discarding the fractional portion.\n    ///\n    /// Width and height are guarantee to be >= 1.\n    pub fn round(&self) -> Option<IntRect> {\n        IntRect::from_xywh(\n            i32::saturate_round(self.x()),\n            i32::saturate_round(self.y()),\n            core::cmp::max(1, i32::saturate_round(self.width()) as u32),\n            core::cmp::max(1, i32::saturate_round(self.height()) as u32),\n        )\n    }\n\n    /// Converts into an `IntRect` rounding outwards.\n    ///\n    /// Width and height are guarantee to be >= 1.\n    pub fn round_out(&self) -> Option<IntRect> {\n        IntRect::from_xywh(\n            i32::saturate_floor(self.x()),\n            i32::saturate_floor(self.y()),\n            core::cmp::max(1, i32::saturate_ceil(self.width()) as u32),\n            core::cmp::max(1, i32::saturate_ceil(self.height()) as u32),\n        )\n    }\n\n    /// Returns an intersection of two rectangles.\n    ///\n    /// Returns `None` otherwise.\n    pub fn intersect(&self, other: &Self) -> Option<Self> {\n        let left = self.x().max(other.x());\n        let top = self.y().max(other.y());\n\n        let right = self.right().min(other.right());\n        let bottom = self.bottom().min(other.bottom());\n\n        Rect::from_ltrb(left, top, right, bottom)\n    }\n\n    /// Creates a Rect from Point array.\n    ///\n    /// Returns None if count is zero or if Point array contains an infinity or NaN.\n    pub fn from_points(points: &[Point]) -> Option<Self> {\n        use crate::f32x4_t::f32x4;\n\n        if points.is_empty() {\n            return None;\n        }\n\n        let mut offset = 0;\n        let mut min;\n        let mut max;\n        if points.len() & 1 != 0 {\n            let pt = points[0];\n            min = f32x4([pt.x, pt.y, pt.x, pt.y]);\n            max = min;\n            offset += 1;\n        } else {\n            let pt0 = points[0];\n            let pt1 = points[1];\n            min = f32x4([pt0.x, pt0.y, pt1.x, pt1.y]);\n            max = min;\n            offset += 2;\n        }\n\n        let mut accum = f32x4::default();\n        while offset != points.len() {\n            let pt0 = points[offset + 0];\n            let pt1 = points[offset + 1];\n            let xy = f32x4([pt0.x, pt0.y, pt1.x, pt1.y]);\n\n            accum *= xy;\n            min = min.min(xy);\n            max = max.max(xy);\n            offset += 2;\n        }\n\n        let all_finite = accum * f32x4::default() == f32x4::default();\n        let min: [f32; 4] = min.0;\n        let max: [f32; 4] = max.0;\n        if all_finite {\n            Rect::from_ltrb(\n                min[0].min(min[2]),\n                min[1].min(min[3]),\n                max[0].max(max[2]),\n                max[1].max(max[3]),\n            )\n        } else {\n            None\n        }\n    }\n\n    /// Insets the rectangle by the specified offset.\n    pub fn inset(&mut self, dx: f32, dy: f32) -> Option<Self> {\n        Rect::from_ltrb(\n            self.left() + dx,\n            self.top() + dy,\n            self.right() - dx,\n            self.bottom() - dy,\n        )\n    }\n\n    /// Outsets the rectangle by the specified offset.\n    pub fn outset(&mut self, dx: f32, dy: f32) -> Option<Self> {\n        self.inset(-dx, -dy)\n    }\n\n    /// Transforms the rect using the provided `Transform`.\n    ///\n    /// This method is expensive.\n    pub fn transform(&self, ts: Transform) -> Option<Self> {\n        if !ts.is_identity() {\n            // TODO: remove allocation\n            let mut path = PathBuilder::from_rect(*self);\n            path = path.transform(ts)?;\n            Some(path.bounds())\n        } else {\n            Some(*self)\n        }\n    }\n\n    /// Applies a bounding box transform.\n    pub fn bbox_transform(&self, bbox: NonZeroRect) -> Self {\n        let x = self.x() * bbox.width() + bbox.x();\n        let y = self.y() * bbox.height() + bbox.y();\n        let w = self.width() * bbox.width();\n        let h = self.height() * bbox.height();\n        Self::from_xywh(x, y, w, h).unwrap()\n    }\n\n    /// Converts into [`NonZeroRect`].\n    pub fn to_non_zero_rect(&self) -> Option<NonZeroRect> {\n        NonZeroRect::from_xywh(self.x(), self.y(), self.width(), self.height())\n    }\n}\n\nfn checked_f32_sub(a: f32, b: f32) -> Option<f32> {\n    debug_assert!(a.is_finite());\n    debug_assert!(b.is_finite());\n\n    let n = a as f64 - b as f64;\n    // Not sure if this is perfectly correct.\n    if n > core::f32::MIN as f64 && n < core::f32::MAX as f64 {\n        Some(n as f32)\n    } else {\n        None\n    }\n}\n\n#[cfg(test)]\nmod rect_tests {\n    use super::*;\n\n    #[test]\n    fn tests() {\n        assert_eq!(Rect::from_ltrb(10.0, 10.0, 5.0, 10.0), None);\n        assert_eq!(Rect::from_ltrb(10.0, 10.0, 10.0, 5.0), None);\n        assert_eq!(Rect::from_ltrb(core::f32::NAN, 10.0, 10.0, 10.0), None);\n        assert_eq!(Rect::from_ltrb(10.0, core::f32::NAN, 10.0, 10.0), None);\n        assert_eq!(Rect::from_ltrb(10.0, 10.0, core::f32::NAN, 10.0), None);\n        assert_eq!(Rect::from_ltrb(10.0, 10.0, 10.0, core::f32::NAN), None);\n        assert_eq!(Rect::from_ltrb(10.0, 10.0, 10.0, core::f32::INFINITY), None);\n\n        let rect = Rect::from_ltrb(10.0, 20.0, 30.0, 40.0).unwrap();\n        assert_eq!(rect.left(), 10.0);\n        assert_eq!(rect.top(), 20.0);\n        assert_eq!(rect.right(), 30.0);\n        assert_eq!(rect.bottom(), 40.0);\n        assert_eq!(rect.width(), 20.0);\n        assert_eq!(rect.height(), 20.0);\n\n        let rect = Rect::from_ltrb(-30.0, 20.0, -10.0, 40.0).unwrap();\n        assert_eq!(rect.width(), 20.0);\n        assert_eq!(rect.height(), 20.0);\n    }\n\n    #[test]\n    fn round_overflow() {\n        // minimum value that cause overflow\n        // because i32::MAX has no exact conversion to f32\n        let x = 128.0;\n        // maximum width\n        let width = i32::MAX as f32;\n\n        let rect = Rect::from_xywh(x, 0.0, width, 1.0).unwrap();\n        assert_eq!(rect.round(), None);\n        assert_eq!(rect.round_out(), None);\n    }\n}\n\n/// A rectangle defined by left, top, right and bottom edges.\n///\n/// Similar to [`Rect`], but width and height guarantee to be non-zero and positive.\n///\n/// # Guarantees\n///\n/// - All values are finite.\n/// - Left edge is < right.\n/// - Top edge is < bottom.\n/// - Width and height are <= f32::MAX.\n/// - Width and height are > 0.0\n#[allow(missing_docs)]\n#[derive(Copy, Clone, PartialEq)]\npub struct NonZeroRect {\n    left: FiniteF32,\n    top: FiniteF32,\n    right: FiniteF32,\n    bottom: FiniteF32,\n}\n\nimpl core::fmt::Debug for NonZeroRect {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        f.debug_struct(\"NonZeroRect\")\n            .field(\"left\", &self.left.get())\n            .field(\"top\", &self.top.get())\n            .field(\"right\", &self.right.get())\n            .field(\"bottom\", &self.bottom.get())\n            .finish()\n    }\n}\n\nimpl NonZeroRect {\n    /// Creates new `NonZeroRect`.\n    pub fn from_ltrb(left: f32, top: f32, right: f32, bottom: f32) -> Option<Self> {\n        let left = FiniteF32::new(left)?;\n        let top = FiniteF32::new(top)?;\n        let right = FiniteF32::new(right)?;\n        let bottom = FiniteF32::new(bottom)?;\n\n        if left.get() < right.get() && top.get() < bottom.get() {\n            // Width and height must not overflow.\n            checked_f32_sub(right.get(), left.get())?;\n            checked_f32_sub(bottom.get(), top.get())?;\n\n            Some(Self {\n                left,\n                top,\n                right,\n                bottom,\n            })\n        } else {\n            None\n        }\n    }\n\n    /// Creates new `NonZeroRect`.\n    pub fn from_xywh(x: f32, y: f32, w: f32, h: f32) -> Option<Self> {\n        Self::from_ltrb(x, y, w + x, h + y)\n    }\n\n    /// Returns the left edge.\n    pub fn left(&self) -> f32 {\n        self.left.get()\n    }\n\n    /// Returns the top edge.\n    pub fn top(&self) -> f32 {\n        self.top.get()\n    }\n\n    /// Returns the right edge.\n    pub fn right(&self) -> f32 {\n        self.right.get()\n    }\n\n    /// Returns the bottom edge.\n    pub fn bottom(&self) -> f32 {\n        self.bottom.get()\n    }\n\n    /// Returns rect's X position.\n    pub fn x(&self) -> f32 {\n        self.left.get()\n    }\n\n    /// Returns rect's Y position.\n    pub fn y(&self) -> f32 {\n        self.top.get()\n    }\n\n    /// Returns rect's width.\n    pub fn width(&self) -> f32 {\n        self.right.get() - self.left.get()\n    }\n\n    /// Returns rect's height.\n    pub fn height(&self) -> f32 {\n        self.bottom.get() - self.top.get()\n    }\n\n    /// Returns rect's size.\n    pub fn size(&self) -> Size {\n        Size::from_wh(self.width(), self.height()).unwrap()\n    }\n\n    /// Translates the rect to the specified position.\n    pub fn translate_to(&self, x: f32, y: f32) -> Option<Self> {\n        Self::from_xywh(x, y, self.width(), self.height())\n    }\n\n    /// Transforms the rect using the provided `Transform`.\n    ///\n    /// This method is expensive.\n    pub fn transform(&self, ts: Transform) -> Option<Self> {\n        if !ts.is_identity() {\n            // TODO: remove allocation\n            let mut path = PathBuilder::from_rect(self.to_rect());\n            path = path.transform(ts)?;\n            path.bounds().to_non_zero_rect()\n        } else {\n            Some(*self)\n        }\n    }\n\n    /// Applies a bounding box transform.\n    pub fn bbox_transform(&self, bbox: NonZeroRect) -> Self {\n        let x = self.x() * bbox.width() + bbox.x();\n        let y = self.y() * bbox.height() + bbox.y();\n        let w = self.width() * bbox.width();\n        let h = self.height() * bbox.height();\n        Self::from_xywh(x, y, w, h).unwrap()\n    }\n\n    /// Converts into [`Rect`].\n    pub fn to_rect(&self) -> Rect {\n        Rect::from_xywh(self.x(), self.y(), self.width(), self.height()).unwrap()\n    }\n\n    /// Converts into [`IntRect`].\n    pub fn to_int_rect(&self) -> IntRect {\n        IntRect::from_xywh(\n            self.x().floor() as i32,\n            self.y().floor() as i32,\n            core::cmp::max(1, self.width().ceil() as u32),\n            core::cmp::max(1, self.height().ceil() as u32),\n        )\n        .unwrap()\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/scalar.rs",
      "sha256": "f6ece3dfbc76a30a3b51a2bafe43addbd59840a84cb94a4c58fb9e718e362706",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse crate::floating_point::f32_as_2s_compliment;\n\n#[allow(missing_docs)]\npub const SCALAR_MAX: f32 = 3.402823466e+38;\n#[allow(missing_docs)]\npub const SCALAR_NEARLY_ZERO: f32 = 1.0 / (1 << 12) as f32;\n#[allow(missing_docs)]\npub const SCALAR_ROOT_2_OVER_2: f32 = 0.707106781;\n\n/// Float number extension methods.\n///\n/// Mainly for internal use. Do not rely on it!\n#[allow(missing_docs)]\npub trait Scalar {\n    fn half(self) -> Self;\n    fn ave(self, other: Self) -> Self;\n    fn sqr(self) -> Self;\n    fn invert(self) -> Self;\n    fn bound(self, min: Self, max: Self) -> Self;\n    fn is_nearly_equal(self, other: Self) -> bool;\n    fn is_nearly_zero(self) -> bool;\n    fn is_nearly_zero_within_tolerance(self, tolerance: Self) -> bool;\n    fn almost_dequal_ulps(self, other: Self) -> bool;\n}\n\nimpl Scalar for f32 {\n    fn half(self) -> f32 {\n        self * 0.5\n    }\n\n    fn ave(self, other: Self) -> f32 {\n        (self + other) * 0.5\n    }\n\n    fn sqr(self) -> f32 {\n        self * self\n    }\n\n    fn invert(self) -> f32 {\n        1.0 / self\n    }\n\n    // Works just like SkTPin, returning `max` for NaN/inf\n    /// A non-panicking clamp.\n    fn bound(self, min: Self, max: Self) -> Self {\n        max.min(self).max(min)\n    }\n\n    fn is_nearly_equal(self, other: Self) -> bool {\n        (self - other).abs() <= SCALAR_NEARLY_ZERO\n    }\n\n    fn is_nearly_zero(self) -> bool {\n        self.is_nearly_zero_within_tolerance(SCALAR_NEARLY_ZERO)\n    }\n\n    fn is_nearly_zero_within_tolerance(self, tolerance: Self) -> bool {\n        debug_assert!(tolerance >= 0.0);\n        self.abs() <= tolerance\n    }\n\n    // From SkPathOpsTypes.\n    fn almost_dequal_ulps(self, other: Self) -> bool {\n        const ULPS_EPSILON: i32 = 16;\n        let a_bits = f32_as_2s_compliment(self);\n        let b_bits = f32_as_2s_compliment(other);\n        // Find the difference in ULPs.\n        a_bits < b_bits + ULPS_EPSILON && b_bits < a_bits + ULPS_EPSILON\n    }\n}\n\n#[allow(missing_docs)]\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\npub trait NoStdFloat {\n    fn trunc(self) -> Self;\n    fn sqrt(self) -> Self;\n    fn abs(self) -> Self;\n    fn sin(self) -> Self;\n    fn cos(self) -> Self;\n    fn ceil(self) -> Self;\n    fn floor(self) -> Self;\n    fn round(self) -> Self;\n    fn powf(self, y: Self) -> Self;\n    fn acos(self) -> Self;\n}\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nimpl NoStdFloat for f32 {\n    fn trunc(self) -> Self {\n        libm::truncf(self)\n    }\n    fn sqrt(self) -> Self {\n        libm::sqrtf(self)\n    }\n    fn abs(self) -> Self {\n        libm::fabsf(self)\n    }\n    fn sin(self) -> Self {\n        libm::sinf(self)\n    }\n    fn cos(self) -> Self {\n        libm::cosf(self)\n    }\n    fn ceil(self) -> Self {\n        libm::ceilf(self)\n    }\n    fn floor(self) -> Self {\n        libm::floorf(self)\n    }\n    fn round(self) -> Self {\n        libm::roundf(self)\n    }\n    fn powf(self, y: Self) -> Self {\n        libm::powf(self, y)\n    }\n    fn acos(self) -> Self {\n        libm::acosf(self)\n    }\n}\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nimpl NoStdFloat for f64 {\n    fn trunc(self) -> Self {\n        libm::trunc(self)\n    }\n    fn sqrt(self) -> Self {\n        libm::sqrt(self)\n    }\n    fn abs(self) -> Self {\n        libm::fabs(self)\n    }\n    fn sin(self) -> Self {\n        libm::sin(self)\n    }\n    fn cos(self) -> Self {\n        libm::cos(self)\n    }\n    fn ceil(self) -> Self {\n        libm::ceil(self)\n    }\n    fn floor(self) -> Self {\n        libm::floor(self)\n    }\n    fn round(self) -> Self {\n        libm::round(self)\n    }\n    fn powf(self, y: Self) -> Self {\n        libm::pow(self, y)\n    }\n    fn acos(self) -> Self {\n        libm::acos(self)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn bound() {\n        assert_eq!(core::f32::NAN.bound(0.0, 1.0), 1.0);\n        assert_eq!(core::f32::INFINITY.bound(0.0, 1.0), 1.0);\n        assert_eq!(core::f32::NEG_INFINITY.bound(0.0, 1.0), 0.0);\n        assert_eq!(core::f32::EPSILON.bound(0.0, 1.0), core::f32::EPSILON);\n        assert_eq!(0.5.bound(0.0, 1.0), 0.5);\n        assert_eq!((-1.0).bound(0.0, 1.0), 0.0);\n        assert_eq!(2.0.bound(0.0, 1.0), 1.0);\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/size.rs",
      "sha256": "2a887b25bee4194b730283f3e09ea8647af1f4584c2ba5d415024b0485022107",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse strict_num::NonZeroPositiveF32;\n\nuse crate::{IntRect, LengthU32, NonZeroRect, Rect};\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse crate::NoStdFloat;\n\n/// An integer size.\n///\n/// # Guarantees\n///\n/// - Width and height are positive and non-zero.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub struct IntSize {\n    width: LengthU32,\n    height: LengthU32,\n}\n\nimpl IntSize {\n    /// Creates a new `IntSize` from width and height.\n    pub fn from_wh(width: u32, height: u32) -> Option<Self> {\n        Some(IntSize {\n            width: LengthU32::new(width)?,\n            height: LengthU32::new(height)?,\n        })\n    }\n\n    pub(crate) fn from_wh_safe(width: LengthU32, height: LengthU32) -> Self {\n        IntSize { width, height }\n    }\n\n    /// Returns width.\n    pub fn width(&self) -> u32 {\n        self.width.get()\n    }\n\n    /// Returns height.\n    pub fn height(&self) -> u32 {\n        self.height.get()\n    }\n\n    /// Returns width and height as a tuple.\n    pub fn dimensions(&self) -> (u32, u32) {\n        (self.width(), self.height())\n    }\n\n    /// Scales current size by the specified factor.\n    #[inline]\n    pub fn scale_by(&self, factor: f32) -> Option<Self> {\n        Self::from_wh(\n            (self.width() as f32 * factor).round() as u32,\n            (self.height() as f32 * factor).round() as u32,\n        )\n    }\n\n    /// Scales current size to the specified size.\n    #[inline]\n    pub fn scale_to(&self, to: Self) -> Self {\n        size_scale(*self, to, false)\n    }\n\n    /// Scales current size to the specified width.\n    #[inline]\n    pub fn scale_to_width(&self, new_width: u32) -> Option<Self> {\n        let new_height = (new_width as f32 * self.height() as f32 / self.width() as f32).ceil();\n        Self::from_wh(new_width, new_height as u32)\n    }\n\n    /// Scales current size to the specified height.\n    #[inline]\n    pub fn scale_to_height(&self, new_height: u32) -> Option<Self> {\n        let new_width = (new_height as f32 * self.width() as f32 / self.height() as f32).ceil();\n        Self::from_wh(new_width as u32, new_height)\n    }\n\n    /// Converts into [`Size`].\n    pub fn to_size(&self) -> Size {\n        Size::from_wh(self.width() as f32, self.height() as f32).unwrap()\n    }\n\n    /// Converts into [`IntRect`] at the provided position.\n    pub fn to_int_rect(&self, x: i32, y: i32) -> IntRect {\n        IntRect::from_xywh(x, y, self.width(), self.height()).unwrap()\n    }\n}\n\nfn size_scale(s1: IntSize, s2: IntSize, expand: bool) -> IntSize {\n    let rw = (s2.height() as f32 * s1.width() as f32 / s1.height() as f32).ceil() as u32;\n    let with_h = if expand {\n        rw <= s2.width()\n    } else {\n        rw >= s2.width()\n    };\n\n    if !with_h {\n        IntSize::from_wh(rw, s2.height()).unwrap()\n    } else {\n        let h = (s2.width() as f32 * s1.height() as f32 / s1.width() as f32).ceil() as u32;\n        IntSize::from_wh(s2.width(), h).unwrap()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn int_size_tests() {\n        assert_eq!(IntSize::from_wh(0, 0), None);\n        assert_eq!(IntSize::from_wh(1, 0), None);\n        assert_eq!(IntSize::from_wh(0, 1), None);\n\n        let size = IntSize::from_wh(3, 4).unwrap();\n        assert_eq!(\n            size.to_int_rect(1, 2),\n            IntRect::from_xywh(1, 2, 3, 4).unwrap()\n        );\n    }\n}\n\n/// A size.\n///\n/// # Guarantees\n///\n/// - Width and height are positive, non-zero and finite.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub struct Size {\n    width: NonZeroPositiveF32,\n    height: NonZeroPositiveF32,\n}\n\nimpl Size {\n    /// Creates a new `Size` from width and height.\n    pub fn from_wh(width: f32, height: f32) -> Option<Self> {\n        Some(Size {\n            width: NonZeroPositiveF32::new(width)?,\n            height: NonZeroPositiveF32::new(height)?,\n        })\n    }\n\n    /// Returns width.\n    pub fn width(&self) -> f32 {\n        self.width.get()\n    }\n\n    /// Returns height.\n    pub fn height(&self) -> f32 {\n        self.height.get()\n    }\n\n    /// Scales current size to specified size.\n    pub fn scale_to(&self, to: Self) -> Self {\n        size_scale_f64(*self, to, false)\n    }\n\n    /// Expands current size to specified size.\n    pub fn expand_to(&self, to: Self) -> Self {\n        size_scale_f64(*self, to, true)\n    }\n\n    /// Converts into [`IntSize`].\n    pub fn to_int_size(&self) -> IntSize {\n        IntSize::from_wh(\n            core::cmp::max(1, self.width().round() as u32),\n            core::cmp::max(1, self.height().round() as u32),\n        )\n        .unwrap()\n    }\n\n    /// Converts the current size to `Rect` at provided position.\n    pub fn to_rect(&self, x: f32, y: f32) -> Option<Rect> {\n        Rect::from_xywh(x, y, self.width.get(), self.height.get())\n    }\n\n    /// Converts the current size to `NonZeroRect` at provided position.\n    pub fn to_non_zero_rect(&self, x: f32, y: f32) -> NonZeroRect {\n        NonZeroRect::from_xywh(x, y, self.width.get(), self.height.get()).unwrap()\n    }\n}\n\nfn size_scale_f64(s1: Size, s2: Size, expand: bool) -> Size {\n    let rw = s2.height.get() * s1.width.get() / s1.height.get();\n    let with_h = if expand {\n        rw <= s2.width.get()\n    } else {\n        rw >= s2.width.get()\n    };\n    if !with_h {\n        Size::from_wh(rw, s2.height.get()).unwrap()\n    } else {\n        let h = s2.width.get() * s1.height.get() / s1.width.get();\n        Size::from_wh(s2.width.get(), h).unwrap()\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/stroker.rs",
      "sha256": "e3a53080763ec4dca637b33aea663f17c697450ff0080f37219fb53b634ab94d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2008 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Based on SkStroke.cpp\n\nuse crate::{Path, Point, Transform};\n\nuse crate::dash::StrokeDash;\nuse crate::floating_point::{NonZeroPositiveF32, NormalizedF32, NormalizedF32Exclusive};\nuse crate::path::{PathSegment, PathSegmentsIter};\nuse crate::path_builder::{PathBuilder, PathDirection};\nuse crate::path_geometry;\nuse crate::scalar::{Scalar, SCALAR_NEARLY_ZERO, SCALAR_ROOT_2_OVER_2};\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse crate::NoStdFloat;\n\nstruct SwappableBuilders<'a> {\n    inner: &'a mut PathBuilder,\n    outer: &'a mut PathBuilder,\n}\n\nimpl<'a> SwappableBuilders<'a> {\n    fn swap(&mut self) {\n        // Skia swaps pointers to inner and outer builders during joining,\n        // but not builders itself. So a simple `core::mem::swap` will produce invalid results.\n        // And if we try to use use `core::mem::swap` on references, like below,\n        // borrow checker will be unhappy.\n        // That's why we need this wrapper. Maybe there is a better solution.\n        core::mem::swap(&mut self.inner, &mut self.outer);\n    }\n}\n\n/// Stroke properties.\n#[derive(Clone, PartialEq, Debug)]\npub struct Stroke {\n    /// A stroke thickness.\n    ///\n    /// Must be >= 0.\n    ///\n    /// When set to 0, a hairline stroking will be used.\n    ///\n    /// Default: 1.0\n    pub width: f32,\n\n    /// The limit at which a sharp corner is drawn beveled.\n    ///\n    /// Default: 4.0\n    pub miter_limit: f32,\n\n    /// A stroke line cap.\n    ///\n    /// Default: Butt\n    pub line_cap: LineCap,\n\n    /// A stroke line join.\n    ///\n    /// Default: Miter\n    pub line_join: LineJoin,\n\n    /// A stroke dashing properties.\n    ///\n    /// Default: None\n    pub dash: Option<StrokeDash>,\n}\n\nimpl Default for Stroke {\n    fn default() -> Self {\n        Stroke {\n            width: 1.0,\n            miter_limit: 4.0,\n            line_cap: LineCap::default(),\n            line_join: LineJoin::default(),\n            dash: None,\n        }\n    }\n}\n\n/// Draws at the beginning and end of an open path contour.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub enum LineCap {\n    /// No stroke extension.\n    Butt,\n    /// Adds circle.\n    Round,\n    /// Adds square.\n    Square,\n}\n\nimpl Default for LineCap {\n    fn default() -> Self {\n        LineCap::Butt\n    }\n}\n\n/// Specifies how corners are drawn when a shape is stroked.\n///\n/// Join affects the four corners of a stroked rectangle, and the connected segments in a\n/// stroked path.\n///\n/// Choose miter join to draw sharp corners. Choose round join to draw a circle with a\n/// radius equal to the stroke width on top of the corner. Choose bevel join to minimally\n/// connect the thick strokes.\n///\n/// The fill path constructed to describe the stroked path respects the join setting but may\n/// not contain the actual join. For instance, a fill path constructed with round joins does\n/// not necessarily include circles at each connected segment.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub enum LineJoin {\n    /// Extends to miter limit.\n    Miter,\n    /// Adds circle.\n    Round,\n    /// Connects outside edges.\n    Bevel,\n}\n\nimpl Default for LineJoin {\n    fn default() -> Self {\n        LineJoin::Miter\n    }\n}\n\nconst QUAD_RECURSIVE_LIMIT: usize = 3;\n\n// quads with extreme widths (e.g. (0,1) (1,6) (0,3) width=5e7) recurse to point of failure\n// largest seen for normal cubics: 5, 26\n// largest seen for normal quads: 11\nconst RECURSIVE_LIMITS: [i32; 4] = [5 * 3, 26 * 3, 11 * 3, 11 * 3]; // 3x limits seen in practice\n\ntype CapProc = fn(\n    pivot: Point,\n    normal: Point,\n    stop: Point,\n    other_path: Option<&PathBuilder>,\n    path: &mut PathBuilder,\n);\n\ntype JoinProc = fn(\n    before_unit_normal: Point,\n    pivot: Point,\n    after_unit_normal: Point,\n    radius: f32,\n    inv_miter_limit: f32,\n    prev_is_line: bool,\n    curr_is_line: bool,\n    builders: SwappableBuilders,\n);\n\n#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]\nenum ReductionType {\n    Point,       // all curve points are practically identical\n    Line,        // the control point is on the line between the ends\n    Quad,        // the control point is outside the line between the ends\n    Degenerate,  // the control point is on the line but outside the ends\n    Degenerate2, // two control points are on the line but outside ends (cubic)\n    Degenerate3, // three areas of max curvature found (for cubic)\n}\n\n#[derive(Copy, Clone, PartialEq, Debug)]\nenum StrokeType {\n    Outer = 1, // use sign-opposite values later to flip perpendicular axis\n    Inner = -1,\n}\n\n#[derive(Copy, Clone, PartialEq, Debug)]\nenum ResultType {\n    Split,      // the caller should split the quad stroke in two\n    Degenerate, // the caller should add a line\n    Quad,       // the caller should (continue to try to) add a quad stroke\n}\n\n#[derive(Copy, Clone, PartialEq, Debug)]\nenum IntersectRayType {\n    CtrlPt,\n    ResultType,\n}\n\nimpl Path {\n    /// Returns a stoked path.\n    ///\n    /// `resolution_scale` can be obtained via\n    /// [`compute_resolution_scale`](PathStroker::compute_resolution_scale).\n    ///\n    /// If you plan stroking multiple paths, you can try using [`PathStroker`]\n    /// which will preserve temporary allocations required during stroking.\n    /// This might improve performance a bit.\n    pub fn stroke(&self, stroke: &Stroke, resolution_scale: f32) -> Option<Path> {\n        PathStroker::new().stroke(self, stroke, resolution_scale)\n    }\n}\n\n/// A path stroker.\n#[allow(missing_debug_implementations)]\n#[derive(Clone)]\npub struct PathStroker {\n    radius: f32,\n    inv_miter_limit: f32,\n    res_scale: f32,\n    inv_res_scale: f32,\n    inv_res_scale_squared: f32,\n\n    first_normal: Point,\n    prev_normal: Point,\n    first_unit_normal: Point,\n    prev_unit_normal: Point,\n\n    // on original path\n    first_pt: Point,\n    prev_pt: Point,\n\n    first_outer_pt: Point,\n    first_outer_pt_index_in_contour: usize,\n    segment_count: i32,\n    prev_is_line: bool,\n\n    capper: CapProc,\n    joiner: JoinProc,\n\n    // outer is our working answer, inner is temp\n    inner: PathBuilder,\n    outer: PathBuilder,\n    cusper: PathBuilder,\n\n    stroke_type: StrokeType,\n\n    recursion_depth: i32, // track stack depth to abort if numerics run amok\n    found_tangents: bool, // do less work until tangents meet (cubic)\n    join_completed: bool, // previous join was not degenerate\n}\n\nimpl Default for PathStroker {\n    fn default() -> Self {\n        PathStroker::new()\n    }\n}\n\nimpl PathStroker {\n    /// Creates a new PathStroker.\n    pub fn new() -> Self {\n        PathStroker {\n            radius: 0.0,\n            inv_miter_limit: 0.0,\n            res_scale: 1.0,\n            inv_res_scale: 1.0,\n            inv_res_scale_squared: 1.0,\n\n            first_normal: Point::zero(),\n            prev_normal: Point::zero(),\n            first_unit_normal: Point::zero(),\n            prev_unit_normal: Point::zero(),\n\n            first_pt: Point::zero(),\n            prev_pt: Point::zero(),\n\n            first_outer_pt: Point::zero(),\n            first_outer_pt_index_in_contour: 0,\n            segment_count: -1,\n            prev_is_line: false,\n\n            capper: butt_capper,\n            joiner: miter_joiner,\n\n            inner: PathBuilder::new(),\n            outer: PathBuilder::new(),\n            cusper: PathBuilder::new(),\n\n            stroke_type: StrokeType::Outer,\n\n            recursion_depth: 0,\n            found_tangents: false,\n            join_completed: false,\n        }\n    }\n\n    /// Computes a resolution scale.\n    ///\n    /// Resolution scale is the \"intended\" resolution for the output. Default is 1.0.\n    ///\n    /// Larger values (res > 1) indicate that the result should be more precise, since it will\n    /// be zoomed up, and small errors will be magnified.\n    ///\n    /// Smaller values (0 < res < 1) indicate that the result can be less precise, since it will\n    /// be zoomed down, and small errors may be invisible.\n    pub fn compute_resolution_scale(ts: &Transform) -> f32 {\n        let sx = Point::from_xy(ts.sx, ts.kx).length();\n        let sy = Point::from_xy(ts.ky, ts.sy).length();\n        if sx.is_finite() && sy.is_finite() {\n            let scale = sx.max(sy);\n            if scale > 0.0 {\n                return scale;\n            }\n        }\n\n        1.0\n    }\n\n    /// Stokes the path.\n    ///\n    /// Can be called multiple times to reuse allocated buffers.\n    ///\n    /// `resolution_scale` can be obtained via\n    /// [`compute_resolution_scale`](Self::compute_resolution_scale).\n    pub fn stroke(&mut self, path: &Path, stroke: &Stroke, resolution_scale: f32) -> Option<Path> {\n        let width = NonZeroPositiveF32::new(stroke.width)?;\n        self.stroke_inner(\n            path,\n            width,\n            stroke.miter_limit,\n            stroke.line_cap,\n            stroke.line_join,\n            resolution_scale,\n        )\n    }\n\n    fn stroke_inner(\n        &mut self,\n        path: &Path,\n        width: NonZeroPositiveF32,\n        miter_limit: f32,\n        line_cap: LineCap,\n        mut line_join: LineJoin,\n        res_scale: f32,\n    ) -> Option<Path> {\n        // TODO: stroke_rect optimization\n\n        let mut inv_miter_limit = 0.0;\n\n        if line_join == LineJoin::Miter {\n            if miter_limit <= 1.0 {\n                line_join = LineJoin::Bevel;\n            } else {\n                inv_miter_limit = miter_limit.invert();\n            }\n        }\n\n        self.res_scale = res_scale;\n        // The '4' below matches the fill scan converter's error term.\n        self.inv_res_scale = (res_scale * 4.0).invert();\n        self.inv_res_scale_squared = self.inv_res_scale.sqr();\n\n        self.radius = width.get().half();\n        self.inv_miter_limit = inv_miter_limit;\n\n        self.first_normal = Point::zero();\n        self.prev_normal = Point::zero();\n        self.first_unit_normal = Point::zero();\n        self.prev_unit_normal = Point::zero();\n\n        self.first_pt = Point::zero();\n        self.prev_pt = Point::zero();\n\n        self.first_outer_pt = Point::zero();\n        self.first_outer_pt_index_in_contour = 0;\n        self.segment_count = -1;\n        self.prev_is_line = false;\n\n        self.capper = cap_factory(line_cap);\n        self.joiner = join_factory(line_join);\n\n        // Need some estimate of how large our final result (fOuter)\n        // and our per-contour temp (fInner) will be, so we don't spend\n        // extra time repeatedly growing these arrays.\n        //\n        // 1x for inner == 'wag' (worst contour length would be better guess)\n        self.inner.clear();\n        self.inner.reserve(path.verbs.len(), path.points.len());\n\n        // 3x for result == inner + outer + join (swag)\n        self.outer.clear();\n        self.outer\n            .reserve(path.verbs.len() * 3, path.points.len() * 3);\n\n        self.cusper.clear();\n\n        self.stroke_type = StrokeType::Outer;\n\n        self.recursion_depth = 0;\n        self.found_tangents = false;\n        self.join_completed = false;\n\n        let mut last_segment_is_line = false;\n        let mut iter = path.segments();\n        iter.set_auto_close(true);\n        while let Some(segment) = iter.next() {\n            match segment {\n                PathSegment::MoveTo(p) => {\n                    self.move_to(p);\n                }\n                PathSegment::LineTo(p) => {\n                    self.line_to(p, Some(&iter));\n                    last_segment_is_line = true;\n                }\n                PathSegment::QuadTo(p1, p2) => {\n                    self.quad_to(p1, p2);\n                    last_segment_is_line = false;\n                }\n                PathSegment::CubicTo(p1, p2, p3) => {\n                    self.cubic_to(p1, p2, p3);\n                    last_segment_is_line = false;\n                }\n                PathSegment::Close => {\n                    if line_cap != LineCap::Butt {\n                        // If the stroke consists of a moveTo followed by a close, treat it\n                        // as if it were followed by a zero-length line. Lines without length\n                        // can have square and round end caps.\n                        if self.has_only_move_to() {\n                            self.line_to(self.move_to_pt(), None);\n                            last_segment_is_line = true;\n                            continue;\n                        }\n\n                        // If the stroke consists of a moveTo followed by one or more zero-length\n                        // verbs, then followed by a close, treat is as if it were followed by a\n                        // zero-length line. Lines without length can have square & round end caps.\n                        if self.is_current_contour_empty() {\n                            last_segment_is_line = true;\n                            continue;\n                        }\n                    }\n\n                    self.close(last_segment_is_line);\n                }\n            }\n        }\n\n        self.finish(last_segment_is_line)\n    }\n\n    fn builders(&mut self) -> SwappableBuilders {\n        SwappableBuilders {\n            inner: &mut self.inner,\n            outer: &mut self.outer,\n        }\n    }\n\n    fn move_to_pt(&self) -> Point {\n        self.first_pt\n    }\n\n    fn move_to(&mut self, p: Point) {\n        if self.segment_count > 0 {\n            self.finish_contour(false, false);\n        }\n\n        self.segment_count = 0;\n        self.first_pt = p;\n        self.prev_pt = p;\n        self.join_completed = false;\n    }\n\n    fn line_to(&mut self, p: Point, iter: Option<&PathSegmentsIter>) {\n        let teeny_line = self\n            .prev_pt\n            .equals_within_tolerance(p, SCALAR_NEARLY_ZERO * self.inv_res_scale);\n        if fn_ptr_eq(self.capper, butt_capper) && teeny_line {\n            return;\n        }\n\n        if teeny_line && (self.join_completed || iter.map(|i| i.has_valid_tangent()) == Some(true))\n        {\n            return;\n        }\n\n        let mut normal = Point::zero();\n        let mut unit_normal = Point::zero();\n        if !self.pre_join_to(p, true, &mut normal, &mut unit_normal) {\n            return;\n        }\n\n        self.outer.line_to(p.x + normal.x, p.y + normal.y);\n        self.inner.line_to(p.x - normal.x, p.y - normal.y);\n\n        self.post_join_to(p, normal, unit_normal);\n    }\n\n    fn quad_to(&mut self, p1: Point, p2: Point) {\n        let quad = [self.prev_pt, p1, p2];\n        let (reduction, reduction_type) = check_quad_linear(&quad);\n        if reduction_type == ReductionType::Point {\n            // If the stroke consists of a moveTo followed by a degenerate curve, treat it\n            // as if it were followed by a zero-length line. Lines without length\n            // can have square and round end caps.\n            self.line_to(p2, None);\n            return;\n        }\n\n        if reduction_type == ReductionType::Line {\n            self.line_to(p2, None);\n            return;\n        }\n\n        if reduction_type == ReductionType::Degenerate {\n            self.line_to(reduction, None);\n            let save_joiner = self.joiner;\n            self.joiner = round_joiner;\n            self.line_to(p2, None);\n            self.joiner = save_joiner;\n            return;\n        }\n\n        debug_assert_eq!(reduction_type, ReductionType::Quad);\n\n        let mut normal_ab = Point::zero();\n        let mut unit_ab = Point::zero();\n        let mut normal_bc = Point::zero();\n        let mut unit_bc = Point::zero();\n        if !self.pre_join_to(p1, false, &mut normal_ab, &mut unit_ab) {\n            self.line_to(p2, None);\n            return;\n        }\n\n        let mut quad_points = QuadConstruct::default();\n        self.init_quad(\n            StrokeType::Outer,\n            NormalizedF32::ZERO,\n            NormalizedF32::ONE,\n            &mut quad_points,\n        );\n        self.quad_stroke(&quad, &mut quad_points);\n        self.init_quad(\n            StrokeType::Inner,\n            NormalizedF32::ZERO,\n            NormalizedF32::ONE,\n            &mut quad_points,\n        );\n        self.quad_stroke(&quad, &mut quad_points);\n\n        let ok = set_normal_unit_normal(\n            quad[1],\n            quad[2],\n            self.res_scale,\n            self.radius,\n            &mut normal_bc,\n            &mut unit_bc,\n        );\n        if !ok {\n            normal_bc = normal_ab;\n            unit_bc = unit_ab;\n        }\n\n        self.post_join_to(p2, normal_bc, unit_bc);\n    }\n\n    fn cubic_to(&mut self, pt1: Point, pt2: Point, pt3: Point) {\n        let cubic = [self.prev_pt, pt1, pt2, pt3];\n        let mut reduction = [Point::zero(); 3];\n        let mut tangent_pt = Point::zero();\n        let reduction_type = check_cubic_linear(&cubic, &mut reduction, Some(&mut tangent_pt));\n        if reduction_type == ReductionType::Point {\n            // If the stroke consists of a moveTo followed by a degenerate curve, treat it\n            // as if it were followed by a zero-length line. Lines without length\n            // can have square and round end caps.\n            self.line_to(pt3, None);\n            return;\n        }\n\n        if reduction_type == ReductionType::Line {\n            self.line_to(pt3, None);\n            return;\n        }\n\n        if ReductionType::Degenerate <= reduction_type\n            && ReductionType::Degenerate3 >= reduction_type\n        {\n            self.line_to(reduction[0], None);\n            let save_joiner = self.joiner;\n            self.joiner = round_joiner;\n            if ReductionType::Degenerate2 <= reduction_type {\n                self.line_to(reduction[1], None);\n            }\n\n            if ReductionType::Degenerate3 == reduction_type {\n                self.line_to(reduction[2], None);\n            }\n\n            self.line_to(pt3, None);\n            self.joiner = save_joiner;\n            return;\n        }\n\n        debug_assert_eq!(reduction_type, ReductionType::Quad);\n        let mut normal_ab = Point::zero();\n        let mut unit_ab = Point::zero();\n        let mut normal_cd = Point::zero();\n        let mut unit_cd = Point::zero();\n        if !self.pre_join_to(tangent_pt, false, &mut normal_ab, &mut unit_ab) {\n            self.line_to(pt3, None);\n            return;\n        }\n\n        let mut t_values = path_geometry::new_t_values();\n        let t_values = path_geometry::find_cubic_inflections(&cubic, &mut t_values);\n        let mut last_t = NormalizedF32::ZERO;\n        for index in 0..=t_values.len() {\n            let next_t = t_values\n                .get(index)\n                .cloned()\n                .map(|n| n.to_normalized())\n                .unwrap_or(NormalizedF32::ONE);\n\n            let mut quad_points = QuadConstruct::default();\n            self.init_quad(StrokeType::Outer, last_t, next_t, &mut quad_points);\n            self.cubic_stroke(&cubic, &mut quad_points);\n            self.init_quad(StrokeType::Inner, last_t, next_t, &mut quad_points);\n            self.cubic_stroke(&cubic, &mut quad_points);\n            last_t = next_t;\n        }\n\n        if let Some(cusp) = path_geometry::find_cubic_cusp(&cubic) {\n            let cusp_loc = path_geometry::eval_cubic_pos_at(&cubic, cusp.to_normalized());\n            self.cusper.push_circle(cusp_loc.x, cusp_loc.y, self.radius);\n        }\n\n        // emit the join even if one stroke succeeded but the last one failed\n        // this avoids reversing an inner stroke with a partial path followed by another moveto\n        self.set_cubic_end_normal(&cubic, normal_ab, unit_ab, &mut normal_cd, &mut unit_cd);\n\n        self.post_join_to(pt3, normal_cd, unit_cd);\n    }\n\n    fn cubic_stroke(&mut self, cubic: &[Point; 4], quad_points: &mut QuadConstruct) -> bool {\n        if !self.found_tangents {\n            let result_type = self.tangents_meet(cubic, quad_points);\n            if result_type != ResultType::Quad {\n                let ok = points_within_dist(\n                    quad_points.quad[0],\n                    quad_points.quad[2],\n                    self.inv_res_scale,\n                );\n                if (result_type == ResultType::Degenerate || ok)\n                    && self.cubic_mid_on_line(cubic, quad_points)\n                {\n                    self.add_degenerate_line(quad_points);\n                    return true;\n                }\n            } else {\n                self.found_tangents = true;\n            }\n        }\n\n        if self.found_tangents {\n            let result_type = self.compare_quad_cubic(cubic, quad_points);\n            if result_type == ResultType::Quad {\n                let stroke = &quad_points.quad;\n                if self.stroke_type == StrokeType::Outer {\n                    self.outer\n                        .quad_to(stroke[1].x, stroke[1].y, stroke[2].x, stroke[2].y);\n                } else {\n                    self.inner\n                        .quad_to(stroke[1].x, stroke[1].y, stroke[2].x, stroke[2].y);\n                }\n\n                return true;\n            }\n\n            if result_type == ResultType::Degenerate {\n                if !quad_points.opposite_tangents {\n                    self.add_degenerate_line(quad_points);\n                    return true;\n                }\n            }\n        }\n\n        if !quad_points.quad[2].x.is_finite() || !quad_points.quad[2].x.is_finite() {\n            return false; // just abort if projected quad isn't representable\n        }\n\n        self.recursion_depth += 1;\n        if self.recursion_depth > RECURSIVE_LIMITS[self.found_tangents as usize] {\n            return false; // just abort if projected quad isn't representable\n        }\n\n        let mut half = QuadConstruct::default();\n        if !half.init_with_start(quad_points) {\n            self.add_degenerate_line(quad_points);\n            self.recursion_depth -= 1;\n            return true;\n        }\n\n        if !self.cubic_stroke(cubic, &mut half) {\n            return false;\n        }\n\n        if !half.init_with_end(quad_points) {\n            self.add_degenerate_line(quad_points);\n            self.recursion_depth -= 1;\n            return true;\n        }\n\n        if !self.cubic_stroke(cubic, &mut half) {\n            return false;\n        }\n\n        self.recursion_depth -= 1;\n        true\n    }\n\n    fn cubic_mid_on_line(&self, cubic: &[Point; 4], quad_points: &mut QuadConstruct) -> bool {\n        let mut stroke_mid = Point::zero();\n        self.cubic_quad_mid(cubic, quad_points, &mut stroke_mid);\n        let dist = pt_to_line(stroke_mid, quad_points.quad[0], quad_points.quad[2]);\n        dist < self.inv_res_scale_squared\n    }\n\n    fn cubic_quad_mid(&self, cubic: &[Point; 4], quad_points: &mut QuadConstruct, mid: &mut Point) {\n        let mut cubic_mid_pt = Point::zero();\n        self.cubic_perp_ray(cubic, quad_points.mid_t, &mut cubic_mid_pt, mid, None);\n    }\n\n    // Given a cubic and t, return the point on curve,\n    // its perpendicular, and the perpendicular tangent.\n    fn cubic_perp_ray(\n        &self,\n        cubic: &[Point; 4],\n        t: NormalizedF32,\n        t_pt: &mut Point,\n        on_pt: &mut Point,\n        tangent: Option<&mut Point>,\n    ) {\n        *t_pt = path_geometry::eval_cubic_pos_at(cubic, t);\n        let mut dxy = path_geometry::eval_cubic_tangent_at(cubic, t);\n\n        let mut chopped = [Point::zero(); 7];\n        if dxy.x == 0.0 && dxy.y == 0.0 {\n            let mut c_points: &[Point] = cubic;\n            if t.get().is_nearly_zero() {\n                dxy = cubic[2] - cubic[0];\n            } else if (1.0 - t.get()).is_nearly_zero() {\n                dxy = cubic[3] - cubic[1];\n            } else {\n                // If the cubic inflection falls on the cusp, subdivide the cubic\n                // to find the tangent at that point.\n                //\n                // Unwrap never fails, because we already checked that `t` is not 0/1,\n                let t = NormalizedF32Exclusive::new(t.get()).unwrap();\n                path_geometry::chop_cubic_at2(cubic, t, &mut chopped);\n                dxy = chopped[3] - chopped[2];\n                if dxy.x == 0.0 && dxy.y == 0.0 {\n                    dxy = chopped[3] - chopped[1];\n                    c_points = &chopped;\n                }\n            }\n\n            if dxy.x == 0.0 && dxy.y == 0.0 {\n                dxy = c_points[3] - c_points[0];\n            }\n        }\n\n        self.set_ray_points(*t_pt, &mut dxy, on_pt, tangent);\n    }\n\n    fn set_cubic_end_normal(\n        &mut self,\n        cubic: &[Point; 4],\n        normal_ab: Point,\n        unit_normal_ab: Point,\n        normal_cd: &mut Point,\n        unit_normal_cd: &mut Point,\n    ) {\n        let mut ab = cubic[1] - cubic[0];\n        let mut cd = cubic[3] - cubic[2];\n\n        let mut degenerate_ab = degenerate_vector(ab);\n        let mut degenerate_cb = degenerate_vector(cd);\n\n        if degenerate_ab && degenerate_cb {\n            *normal_cd = normal_ab;\n            *unit_normal_cd = unit_normal_ab;\n            return;\n        }\n\n        if degenerate_ab {\n            ab = cubic[2] - cubic[0];\n            degenerate_ab = degenerate_vector(ab);\n        }\n\n        if degenerate_cb {\n            cd = cubic[3] - cubic[1];\n            degenerate_cb = degenerate_vector(cd);\n        }\n\n        if degenerate_ab || degenerate_cb {\n            *normal_cd = normal_ab;\n            *unit_normal_cd = unit_normal_ab;\n            return;\n        }\n\n        let res = set_normal_unit_normal2(cd, self.radius, normal_cd, unit_normal_cd);\n        debug_assert!(res);\n    }\n\n    fn compare_quad_cubic(\n        &self,\n        cubic: &[Point; 4],\n        quad_points: &mut QuadConstruct,\n    ) -> ResultType {\n        // get the quadratic approximation of the stroke\n        self.cubic_quad_ends(cubic, quad_points);\n        let result_type = self.intersect_ray(IntersectRayType::CtrlPt, quad_points);\n        if result_type != ResultType::Quad {\n            return result_type;\n        }\n\n        // project a ray from the curve to the stroke\n        // points near midpoint on quad, midpoint on cubic\n        let mut ray0 = Point::zero();\n        let mut ray1 = Point::zero();\n        self.cubic_perp_ray(cubic, quad_points.mid_t, &mut ray1, &mut ray0, None);\n        self.stroke_close_enough(&quad_points.quad.clone(), &[ray0, ray1], quad_points)\n    }\n\n    // Given a cubic and a t range, find the start and end if they haven't been found already.\n    fn cubic_quad_ends(&self, cubic: &[Point; 4], quad_points: &mut QuadConstruct) {\n        if !quad_points.start_set {\n            let mut cubic_start_pt = Point::zero();\n            self.cubic_perp_ray(\n                cubic,\n                quad_points.start_t,\n                &mut cubic_start_pt,\n                &mut quad_points.quad[0],\n                Some(&mut quad_points.tangent_start),\n            );\n            quad_points.start_set = true;\n        }\n\n        if !quad_points.end_set {\n            let mut cubic_end_pt = Point::zero();\n            self.cubic_perp_ray(\n                cubic,\n                quad_points.end_t,\n                &mut cubic_end_pt,\n                &mut quad_points.quad[2],\n                Some(&mut quad_points.tangent_end),\n            );\n            quad_points.end_set = true;\n        }\n    }\n\n    fn close(&mut self, is_line: bool) {\n        self.finish_contour(true, is_line);\n    }\n\n    fn finish_contour(&mut self, close: bool, curr_is_line: bool) {\n        if self.segment_count > 0 {\n            if close {\n                (self.joiner)(\n                    self.prev_unit_normal,\n                    self.prev_pt,\n                    self.first_unit_normal,\n                    self.radius,\n                    self.inv_miter_limit,\n                    self.prev_is_line,\n                    curr_is_line,\n                    self.builders(),\n                );\n                self.outer.close();\n\n                // now add inner as its own contour\n                let pt = self.inner.last_point().unwrap_or_default();\n                self.outer.move_to(pt.x, pt.y);\n                self.outer.reverse_path_to(&self.inner);\n                self.outer.close();\n            } else {\n                // add caps to start and end\n\n                // cap the end\n                let pt = self.inner.last_point().unwrap_or_default();\n                let other_path = if curr_is_line {\n                    Some(&self.inner)\n                } else {\n                    None\n                };\n                (self.capper)(\n                    self.prev_pt,\n                    self.prev_normal,\n                    pt,\n                    other_path,\n                    &mut self.outer,\n                );\n                self.outer.reverse_path_to(&self.inner);\n\n                // cap the start\n                let other_path = if self.prev_is_line {\n                    Some(&self.inner)\n                } else {\n                    None\n                };\n                (self.capper)(\n                    self.first_pt,\n                    -self.first_normal,\n                    self.first_outer_pt,\n                    other_path,\n                    &mut self.outer,\n                );\n                self.outer.close();\n            }\n\n            if !self.cusper.is_empty() {\n                self.outer.push_path_builder(&self.cusper);\n                self.cusper.clear();\n            }\n        }\n\n        // since we may re-use `inner`, we rewind instead of reset, to save on\n        // reallocating its internal storage.\n        self.inner.clear();\n        self.segment_count = -1;\n        self.first_outer_pt_index_in_contour = self.outer.points.len();\n    }\n\n    fn pre_join_to(\n        &mut self,\n        p: Point,\n        curr_is_line: bool,\n        normal: &mut Point,\n        unit_normal: &mut Point,\n    ) -> bool {\n        debug_assert!(self.segment_count >= 0);\n\n        let prev_x = self.prev_pt.x;\n        let prev_y = self.prev_pt.y;\n\n        let normal_set = set_normal_unit_normal(\n            self.prev_pt,\n            p,\n            self.res_scale,\n            self.radius,\n            normal,\n            unit_normal,\n        );\n        if !normal_set {\n            if fn_ptr_eq(self.capper, butt_capper) {\n                return false;\n            }\n\n            // Square caps and round caps draw even if the segment length is zero.\n            // Since the zero length segment has no direction, set the orientation\n            // to upright as the default orientation.\n            *normal = Point::from_xy(self.radius, 0.0);\n            *unit_normal = Point::from_xy(1.0, 0.0);\n        }\n\n        if self.segment_count == 0 {\n            self.first_normal = *normal;\n            self.first_unit_normal = *unit_normal;\n            self.first_outer_pt = Point::from_xy(prev_x + normal.x, prev_y + normal.y);\n\n            self.outer\n                .move_to(self.first_outer_pt.x, self.first_outer_pt.y);\n            self.inner.move_to(prev_x - normal.x, prev_y - normal.y);\n        } else {\n            // we have a previous segment\n            (self.joiner)(\n                self.prev_unit_normal,\n                self.prev_pt,\n                *unit_normal,\n                self.radius,\n                self.inv_miter_limit,\n                self.prev_is_line,\n                curr_is_line,\n                self.builders(),\n            );\n        }\n        self.prev_is_line = curr_is_line;\n        true\n    }\n\n    fn post_join_to(&mut self, p: Point, normal: Point, unit_normal: Point) {\n        self.join_completed = true;\n        self.prev_pt = p;\n        self.prev_unit_normal = unit_normal;\n        self.prev_normal = normal;\n        self.segment_count += 1;\n    }\n\n    fn init_quad(\n        &mut self,\n        stroke_type: StrokeType,\n        start: NormalizedF32,\n        end: NormalizedF32,\n        quad_points: &mut QuadConstruct,\n    ) {\n        self.stroke_type = stroke_type;\n        self.found_tangents = false;\n        quad_points.init(start, end);\n    }\n\n    fn quad_stroke(&mut self, quad: &[Point; 3], quad_points: &mut QuadConstruct) -> bool {\n        let result_type = self.compare_quad_quad(quad, quad_points);\n        if result_type == ResultType::Quad {\n            let path = if self.stroke_type == StrokeType::Outer {\n                &mut self.outer\n            } else {\n                &mut self.inner\n            };\n\n            path.quad_to(\n                quad_points.quad[1].x,\n                quad_points.quad[1].y,\n                quad_points.quad[2].x,\n                quad_points.quad[2].y,\n            );\n\n            return true;\n        }\n\n        if result_type == ResultType::Degenerate {\n            self.add_degenerate_line(quad_points);\n            return true;\n        }\n\n        self.recursion_depth += 1;\n        if self.recursion_depth > RECURSIVE_LIMITS[QUAD_RECURSIVE_LIMIT] {\n            return false; // just abort if projected quad isn't representable\n        }\n\n        let mut half = QuadConstruct::default();\n        half.init_with_start(quad_points);\n        if !self.quad_stroke(quad, &mut half) {\n            return false;\n        }\n\n        half.init_with_end(quad_points);\n        if !self.quad_stroke(quad, &mut half) {\n            return false;\n        }\n\n        self.recursion_depth -= 1;\n        true\n    }\n\n    fn compare_quad_quad(\n        &mut self,\n        quad: &[Point; 3],\n        quad_points: &mut QuadConstruct,\n    ) -> ResultType {\n        // get the quadratic approximation of the stroke\n        if !quad_points.start_set {\n            let mut quad_start_pt = Point::zero();\n            self.quad_perp_ray(\n                quad,\n                quad_points.start_t,\n                &mut quad_start_pt,\n                &mut quad_points.quad[0],\n                Some(&mut quad_points.tangent_start),\n            );\n            quad_points.start_set = true;\n        }\n\n        if !quad_points.end_set {\n            let mut quad_end_pt = Point::zero();\n            self.quad_perp_ray(\n                quad,\n                quad_points.end_t,\n                &mut quad_end_pt,\n                &mut quad_points.quad[2],\n                Some(&mut quad_points.tangent_end),\n            );\n            quad_points.end_set = true;\n        }\n\n        let result_type = self.intersect_ray(IntersectRayType::CtrlPt, quad_points);\n        if result_type != ResultType::Quad {\n            return result_type;\n        }\n\n        // project a ray from the curve to the stroke\n        let mut ray0 = Point::zero();\n        let mut ray1 = Point::zero();\n        self.quad_perp_ray(quad, quad_points.mid_t, &mut ray1, &mut ray0, None);\n        self.stroke_close_enough(&quad_points.quad.clone(), &[ray0, ray1], quad_points)\n    }\n\n    // Given a point on the curve and its derivative, scale the derivative by the radius, and\n    // compute the perpendicular point and its tangent.\n    fn set_ray_points(\n        &self,\n        tp: Point,\n        dxy: &mut Point,\n        on_p: &mut Point,\n        mut tangent: Option<&mut Point>,\n    ) {\n        if !dxy.set_length(self.radius) {\n            *dxy = Point::from_xy(self.radius, 0.0);\n        }\n\n        let axis_flip = self.stroke_type as i32 as f32; // go opposite ways for outer, inner\n        on_p.x = tp.x + axis_flip * dxy.y;\n        on_p.y = tp.y - axis_flip * dxy.x;\n\n        if let Some(ref mut tangent) = tangent {\n            tangent.x = on_p.x + dxy.x;\n            tangent.y = on_p.y + dxy.y;\n        }\n    }\n\n    // Given a quad and t, return the point on curve,\n    // its perpendicular, and the perpendicular tangent.\n    fn quad_perp_ray(\n        &self,\n        quad: &[Point; 3],\n        t: NormalizedF32,\n        tp: &mut Point,\n        on_p: &mut Point,\n        tangent: Option<&mut Point>,\n    ) {\n        *tp = path_geometry::eval_quad_at(quad, t);\n        let mut dxy = path_geometry::eval_quad_tangent_at(quad, t);\n\n        if dxy.is_zero() {\n            dxy = quad[2] - quad[0];\n        }\n\n        self.set_ray_points(*tp, &mut dxy, on_p, tangent);\n    }\n\n    fn add_degenerate_line(&mut self, quad_points: &QuadConstruct) {\n        if self.stroke_type == StrokeType::Outer {\n            self.outer\n                .line_to(quad_points.quad[2].x, quad_points.quad[2].y);\n        } else {\n            self.inner\n                .line_to(quad_points.quad[2].x, quad_points.quad[2].y);\n        }\n    }\n\n    fn stroke_close_enough(\n        &self,\n        stroke: &[Point; 3],\n        ray: &[Point; 2],\n        quad_points: &mut QuadConstruct,\n    ) -> ResultType {\n        let half = NormalizedF32::new_clamped(0.5);\n        let stroke_mid = path_geometry::eval_quad_at(stroke, half);\n        // measure the distance from the curve to the quad-stroke midpoint, compare to radius\n        if points_within_dist(ray[0], stroke_mid, self.inv_res_scale) {\n            // if the difference is small\n            if sharp_angle(&quad_points.quad) {\n                return ResultType::Split;\n            }\n\n            return ResultType::Quad;\n        }\n\n        // measure the distance to quad's bounds (quick reject)\n        // an alternative : look for point in triangle\n        if !pt_in_quad_bounds(stroke, ray[0], self.inv_res_scale) {\n            // if far, subdivide\n            return ResultType::Split;\n        }\n\n        // measure the curve ray distance to the quad-stroke\n        let mut roots = path_geometry::new_t_values();\n        let roots = intersect_quad_ray(ray, stroke, &mut roots);\n        if roots.len() != 1 {\n            return ResultType::Split;\n        }\n\n        let quad_pt = path_geometry::eval_quad_at(stroke, roots[0].to_normalized());\n        let error = self.inv_res_scale * (1.0 - (roots[0].get() - 0.5).abs() * 2.0);\n        if points_within_dist(ray[0], quad_pt, error) {\n            // if the difference is small, we're done\n            if sharp_angle(&quad_points.quad) {\n                return ResultType::Split;\n            }\n\n            return ResultType::Quad;\n        }\n\n        // otherwise, subdivide\n        ResultType::Split\n    }\n\n    // Find the intersection of the stroke tangents to construct a stroke quad.\n    // Return whether the stroke is a degenerate (a line), a quad, or must be split.\n    // Optionally compute the quad's control point.\n    fn intersect_ray(\n        &self,\n        intersect_ray_type: IntersectRayType,\n        quad_points: &mut QuadConstruct,\n    ) -> ResultType {\n        let start = quad_points.quad[0];\n        let end = quad_points.quad[2];\n        let a_len = quad_points.tangent_start - start;\n        let b_len = quad_points.tangent_end - end;\n\n        // Slopes match when denom goes to zero:\n        //                   axLen / ayLen ==                   bxLen / byLen\n        // (ayLen * byLen) * axLen / ayLen == (ayLen * byLen) * bxLen / byLen\n        //          byLen  * axLen         ==  ayLen          * bxLen\n        //          byLen  * axLen         -   ayLen          * bxLen         ( == denom )\n        let denom = a_len.cross(b_len);\n        if denom == 0.0 || !denom.is_finite() {\n            quad_points.opposite_tangents = a_len.dot(b_len) < 0.0;\n            return ResultType::Degenerate;\n        }\n\n        quad_points.opposite_tangents = false;\n        let ab0 = start - end;\n        let mut numer_a = b_len.cross(ab0);\n        let numer_b = a_len.cross(ab0);\n        if (numer_a >= 0.0) == (numer_b >= 0.0) {\n            // if the control point is outside the quad ends\n\n            // if the perpendicular distances from the quad points to the opposite tangent line\n            // are small, a straight line is good enough\n            let dist1 = pt_to_line(start, end, quad_points.tangent_end);\n            let dist2 = pt_to_line(end, start, quad_points.tangent_start);\n            if dist1.max(dist2) <= self.inv_res_scale_squared {\n                return ResultType::Degenerate;\n            }\n\n            return ResultType::Split;\n        }\n\n        // check to see if the denominator is teeny relative to the numerator\n        // if the offset by one will be lost, the ratio is too large\n        numer_a /= denom;\n        let valid_divide = numer_a > numer_a - 1.0;\n        if valid_divide {\n            if intersect_ray_type == IntersectRayType::CtrlPt {\n                // the intersection of the tangents need not be on the tangent segment\n                // so 0 <= numerA <= 1 is not necessarily true\n                quad_points.quad[1].x =\n                    start.x * (1.0 - numer_a) + quad_points.tangent_start.x * numer_a;\n                quad_points.quad[1].y =\n                    start.y * (1.0 - numer_a) + quad_points.tangent_start.y * numer_a;\n            }\n\n            return ResultType::Quad;\n        }\n\n        quad_points.opposite_tangents = a_len.dot(b_len) < 0.0;\n\n        // if the lines are parallel, straight line is good enough\n        ResultType::Degenerate\n    }\n\n    // Given a cubic and a t-range, determine if the stroke can be described by a quadratic.\n    fn tangents_meet(&self, cubic: &[Point; 4], quad_points: &mut QuadConstruct) -> ResultType {\n        self.cubic_quad_ends(cubic, quad_points);\n        self.intersect_ray(IntersectRayType::ResultType, quad_points)\n    }\n\n    fn finish(&mut self, is_line: bool) -> Option<Path> {\n        self.finish_contour(false, is_line);\n\n        // Swap out the outer builder.\n        let mut buf = PathBuilder::new();\n        core::mem::swap(&mut self.outer, &mut buf);\n\n        buf.finish()\n    }\n\n    fn has_only_move_to(&self) -> bool {\n        self.segment_count == 0\n    }\n\n    fn is_current_contour_empty(&self) -> bool {\n        self.inner.is_zero_length_since_point(0)\n            && self\n                .outer\n                .is_zero_length_since_point(self.first_outer_pt_index_in_contour)\n    }\n}\n\nfn cap_factory(cap: LineCap) -> CapProc {\n    match cap {\n        LineCap::Butt => butt_capper,\n        LineCap::Round => round_capper,\n        LineCap::Square => square_capper,\n    }\n}\n\nfn butt_capper(_: Point, _: Point, stop: Point, _: Option<&PathBuilder>, path: &mut PathBuilder) {\n    path.line_to(stop.x, stop.y);\n}\n\nfn round_capper(\n    pivot: Point,\n    normal: Point,\n    stop: Point,\n    _: Option<&PathBuilder>,\n    path: &mut PathBuilder,\n) {\n    let mut parallel = normal;\n    parallel.rotate_cw();\n\n    let projected_center = pivot + parallel;\n\n    path.conic_points_to(\n        projected_center + normal,\n        projected_center,\n        SCALAR_ROOT_2_OVER_2,\n    );\n    path.conic_points_to(projected_center - normal, stop, SCALAR_ROOT_2_OVER_2);\n}\n\nfn square_capper(\n    pivot: Point,\n    normal: Point,\n    stop: Point,\n    other_path: Option<&PathBuilder>,\n    path: &mut PathBuilder,\n) {\n    let mut parallel = normal;\n    parallel.rotate_cw();\n\n    if other_path.is_some() {\n        path.set_last_point(Point::from_xy(\n            pivot.x + normal.x + parallel.x,\n            pivot.y + normal.y + parallel.y,\n        ));\n        path.line_to(\n            pivot.x - normal.x + parallel.x,\n            pivot.y - normal.y + parallel.y,\n        );\n    } else {\n        path.line_to(\n            pivot.x + normal.x + parallel.x,\n            pivot.y + normal.y + parallel.y,\n        );\n        path.line_to(\n            pivot.x - normal.x + parallel.x,\n            pivot.y - normal.y + parallel.y,\n        );\n        path.line_to(stop.x, stop.y);\n    }\n}\n\nfn join_factory(join: LineJoin) -> JoinProc {\n    match join {\n        LineJoin::Miter => miter_joiner,\n        LineJoin::Round => round_joiner,\n        LineJoin::Bevel => bevel_joiner,\n    }\n}\n\nfn is_clockwise(before: Point, after: Point) -> bool {\n    before.x * after.y > before.y * after.x\n}\n\n#[derive(Copy, Clone, PartialEq, Debug)]\nenum AngleType {\n    Nearly180,\n    Sharp,\n    Shallow,\n    NearlyLine,\n}\n\nfn dot_to_angle_type(dot: f32) -> AngleType {\n    if dot >= 0.0 {\n        // shallow or line\n        if (1.0 - dot).is_nearly_zero() {\n            AngleType::NearlyLine\n        } else {\n            AngleType::Shallow\n        }\n    } else {\n        // sharp or 180\n        if (1.0 + dot).is_nearly_zero() {\n            AngleType::Nearly180\n        } else {\n            AngleType::Sharp\n        }\n    }\n}\n\nfn handle_inner_join(pivot: Point, after: Point, inner: &mut PathBuilder) {\n    // In the degenerate case that the stroke radius is larger than our segments\n    // just connecting the two inner segments may \"show through\" as a funny\n    // diagonal. To pseudo-fix this, we go through the pivot point. This adds\n    // an extra point/edge, but I can't see a cheap way to know when this is\n    // not needed :(\n    inner.line_to(pivot.x, pivot.y);\n\n    inner.line_to(pivot.x - after.x, pivot.y - after.y);\n}\n\nfn bevel_joiner(\n    before_unit_normal: Point,\n    pivot: Point,\n    after_unit_normal: Point,\n    radius: f32,\n    _: f32,\n    _: bool,\n    _: bool,\n    mut builders: SwappableBuilders,\n) {\n    let mut after = after_unit_normal.scaled(radius);\n\n    if !is_clockwise(before_unit_normal, after_unit_normal) {\n        builders.swap();\n        after = -after;\n    }\n\n    builders.outer.line_to(pivot.x + after.x, pivot.y + after.y);\n    handle_inner_join(pivot, after, builders.inner);\n}\n\nfn round_joiner(\n    before_unit_normal: Point,\n    pivot: Point,\n    after_unit_normal: Point,\n    radius: f32,\n    _: f32,\n    _: bool,\n    _: bool,\n    mut builders: SwappableBuilders,\n) {\n    let dot_prod = before_unit_normal.dot(after_unit_normal);\n    let angle_type = dot_to_angle_type(dot_prod);\n\n    if angle_type == AngleType::NearlyLine {\n        return;\n    }\n\n    let mut before = before_unit_normal;\n    let mut after = after_unit_normal;\n    let mut dir = PathDirection::CW;\n\n    if !is_clockwise(before, after) {\n        builders.swap();\n        before = -before;\n        after = -after;\n        dir = PathDirection::CCW;\n    }\n\n    let ts = Transform::from_row(radius, 0.0, 0.0, radius, pivot.x, pivot.y);\n\n    let mut conics = [path_geometry::Conic::default(); 5];\n    let conics = path_geometry::Conic::build_unit_arc(before, after, dir, ts, &mut conics);\n    if let Some(conics) = conics {\n        for conic in conics {\n            builders\n                .outer\n                .conic_points_to(conic.points[1], conic.points[2], conic.weight);\n        }\n\n        after.scale(radius);\n        handle_inner_join(pivot, after, builders.inner);\n    }\n}\n\nfn miter_joiner(\n    before_unit_normal: Point,\n    pivot: Point,\n    after_unit_normal: Point,\n    radius: f32,\n    inv_miter_limit: f32,\n    prev_is_line: bool,\n    mut curr_is_line: bool,\n    mut builders: SwappableBuilders,\n) {\n    fn do_blunt(\n        builders: SwappableBuilders,\n        pivot: Point,\n        radius: f32,\n        curr_is_line: bool,\n        mut after: Point,\n    ) {\n        after.scale(radius);\n        if !curr_is_line {\n            builders.outer.line_to(pivot.x + after.x, pivot.y + after.y);\n        }\n\n        handle_inner_join(pivot, after, builders.inner);\n    }\n\n    fn do_miter(\n        builders: SwappableBuilders,\n        pivot: Point,\n        radius: f32,\n        prev_is_line: bool,\n        curr_is_line: bool,\n        mid: Point,\n        after: Point,\n    ) {\n        if prev_is_line {\n            builders\n                .outer\n                .set_last_point(Point::from_xy(pivot.x + mid.x, pivot.y + mid.y));\n        } else {\n            builders.outer.line_to(pivot.x + mid.x, pivot.y + mid.y);\n        }\n\n        do_blunt(builders, pivot, radius, curr_is_line, after);\n    }\n\n    // negate the dot since we're using normals instead of tangents\n    let dot_prod = before_unit_normal.dot(after_unit_normal);\n    let angle_type = dot_to_angle_type(dot_prod);\n    let mut before = before_unit_normal;\n    let mut after = after_unit_normal;\n    let mut mid;\n\n    if angle_type == AngleType::NearlyLine {\n        return;\n    }\n\n    if angle_type == AngleType::Nearly180 {\n        curr_is_line = false;\n        do_blunt(builders, pivot, radius, curr_is_line, after);\n        return;\n    }\n\n    let ccw = !is_clockwise(before, after);\n    if ccw {\n        builders.swap();\n        before = -before;\n        after = -after;\n    }\n\n    // Before we enter the world of square-roots and divides,\n    // check if we're trying to join an upright right angle\n    // (common case for stroking rectangles). If so, special case\n    // that (for speed an accuracy).\n    // Note: we only need to check one normal if dot==0\n    if dot_prod == 0.0 && inv_miter_limit <= SCALAR_ROOT_2_OVER_2 {\n        mid = (before + after).scaled(radius);\n        do_miter(\n            builders,\n            pivot,\n            radius,\n            prev_is_line,\n            curr_is_line,\n            mid,\n            after,\n        );\n        return;\n    }\n\n    // midLength = radius / sinHalfAngle\n    // if (midLength > miterLimit * radius) abort\n    // if (radius / sinHalf > miterLimit * radius) abort\n    // if (1 / sinHalf > miterLimit) abort\n    // if (1 / miterLimit > sinHalf) abort\n    // My dotProd is opposite sign, since it is built from normals and not tangents\n    // hence 1 + dot instead of 1 - dot in the formula\n    let sin_half_angle = (1.0 + dot_prod).half().sqrt();\n    if sin_half_angle < inv_miter_limit {\n        curr_is_line = false;\n        do_blunt(builders, pivot, radius, curr_is_line, after);\n        return;\n    }\n\n    // choose the most accurate way to form the initial mid-vector\n    if angle_type == AngleType::Sharp {\n        mid = Point::from_xy(after.y - before.y, before.x - after.x);\n        if ccw {\n            mid = -mid;\n        }\n    } else {\n        mid = Point::from_xy(before.x + after.x, before.y + after.y);\n    }\n\n    mid.set_length(radius / sin_half_angle);\n    do_miter(\n        builders,\n        pivot,\n        radius,\n        prev_is_line,\n        curr_is_line,\n        mid,\n        after,\n    );\n}\n\nfn set_normal_unit_normal(\n    before: Point,\n    after: Point,\n    scale: f32,\n    radius: f32,\n    normal: &mut Point,\n    unit_normal: &mut Point,\n) -> bool {\n    if !unit_normal.set_normalize((after.x - before.x) * scale, (after.y - before.y) * scale) {\n        return false;\n    }\n\n    unit_normal.rotate_ccw();\n    *normal = unit_normal.scaled(radius);\n    true\n}\n\nfn set_normal_unit_normal2(\n    vec: Point,\n    radius: f32,\n    normal: &mut Point,\n    unit_normal: &mut Point,\n) -> bool {\n    if !unit_normal.set_normalize(vec.x, vec.y) {\n        return false;\n    }\n\n    unit_normal.rotate_ccw();\n    *normal = unit_normal.scaled(radius);\n    true\n}\n\nfn fn_ptr_eq(f1: CapProc, f2: CapProc) -> bool {\n    core::ptr::eq(f1 as *const (), f2 as *const ())\n}\n\n#[derive(Debug)]\nstruct QuadConstruct {\n    // The state of the quad stroke under construction.\n    quad: [Point; 3],       // the stroked quad parallel to the original curve\n    tangent_start: Point,   // a point tangent to quad[0]\n    tangent_end: Point,     // a point tangent to quad[2]\n    start_t: NormalizedF32, // a segment of the original curve\n    mid_t: NormalizedF32,\n    end_t: NormalizedF32,\n    start_set: bool, // state to share common points across structs\n    end_set: bool,\n    opposite_tangents: bool, // set if coincident tangents have opposite directions\n}\n\nimpl Default for QuadConstruct {\n    fn default() -> Self {\n        Self {\n            quad: Default::default(),\n            tangent_start: Point::default(),\n            tangent_end: Point::default(),\n            start_t: NormalizedF32::ZERO,\n            mid_t: NormalizedF32::ZERO,\n            end_t: NormalizedF32::ZERO,\n            start_set: false,\n            end_set: false,\n            opposite_tangents: false,\n        }\n    }\n}\n\nimpl QuadConstruct {\n    // return false if start and end are too close to have a unique middle\n    fn init(&mut self, start: NormalizedF32, end: NormalizedF32) -> bool {\n        self.start_t = start;\n        self.mid_t = NormalizedF32::new_clamped((start.get() + end.get()).half());\n        self.end_t = end;\n        self.start_set = false;\n        self.end_set = false;\n        self.start_t < self.mid_t && self.mid_t < self.end_t\n    }\n\n    fn init_with_start(&mut self, parent: &Self) -> bool {\n        if !self.init(parent.start_t, parent.mid_t) {\n            return false;\n        }\n\n        self.quad[0] = parent.quad[0];\n        self.tangent_start = parent.tangent_start;\n        self.start_set = true;\n        true\n    }\n\n    fn init_with_end(&mut self, parent: &Self) -> bool {\n        if !self.init(parent.mid_t, parent.end_t) {\n            return false;\n        }\n\n        self.quad[2] = parent.quad[2];\n        self.tangent_end = parent.tangent_end;\n        self.end_set = true;\n        true\n    }\n}\n\nfn check_quad_linear(quad: &[Point; 3]) -> (Point, ReductionType) {\n    let degenerate_ab = degenerate_vector(quad[1] - quad[0]);\n    let degenerate_bc = degenerate_vector(quad[2] - quad[1]);\n    if degenerate_ab & degenerate_bc {\n        return (Point::zero(), ReductionType::Point);\n    }\n\n    if degenerate_ab | degenerate_bc {\n        return (Point::zero(), ReductionType::Line);\n    }\n\n    if !quad_in_line(quad) {\n        return (Point::zero(), ReductionType::Quad);\n    }\n\n    let t = path_geometry::find_quad_max_curvature(quad);\n    if t == NormalizedF32::ZERO || t == NormalizedF32::ONE {\n        return (Point::zero(), ReductionType::Line);\n    }\n\n    (\n        path_geometry::eval_quad_at(quad, t),\n        ReductionType::Degenerate,\n    )\n}\n\nfn degenerate_vector(v: Point) -> bool {\n    !v.can_normalize()\n}\n\n/// Given quad, see if all there points are in a line.\n/// Return true if the inside point is close to a line connecting the outermost points.\n///\n/// Find the outermost point by looking for the largest difference in X or Y.\n/// Since the XOR of the indices is 3  (0 ^ 1 ^ 2)\n/// the missing index equals: outer_1 ^ outer_2 ^ 3.\nfn quad_in_line(quad: &[Point; 3]) -> bool {\n    let mut pt_max = -1.0;\n    let mut outer1 = 0;\n    let mut outer2 = 0;\n    for index in 0..2 {\n        for inner in index + 1..3 {\n            let test_diff = quad[inner] - quad[index];\n            let test_max = test_diff.x.abs().max(test_diff.y.abs());\n            if pt_max < test_max {\n                outer1 = index;\n                outer2 = inner;\n                pt_max = test_max;\n            }\n        }\n    }\n\n    debug_assert!(outer1 <= 1);\n    debug_assert!(outer2 >= 1 && outer2 <= 2);\n    debug_assert!(outer1 < outer2);\n\n    let mid = outer1 ^ outer2 ^ 3;\n    const CURVATURE_SLOP: f32 = 0.000005; // this multiplier is pulled out of the air\n    let line_slop = pt_max * pt_max * CURVATURE_SLOP;\n    pt_to_line(quad[mid], quad[outer1], quad[outer2]) <= line_slop\n}\n\n// returns the distance squared from the point to the line\nfn pt_to_line(pt: Point, line_start: Point, line_end: Point) -> f32 {\n    let dxy = line_end - line_start;\n    let ab0 = pt - line_start;\n    let numer = dxy.dot(ab0);\n    let denom = dxy.dot(dxy);\n    let t = numer / denom;\n    if t >= 0.0 && t <= 1.0 {\n        let hit = Point::from_xy(\n            line_start.x * (1.0 - t) + line_end.x * t,\n            line_start.y * (1.0 - t) + line_end.y * t,\n        );\n        hit.distance_to_sqd(pt)\n    } else {\n        pt.distance_to_sqd(line_start)\n    }\n}\n\n// Intersect the line with the quad and return the t values on the quad where the line crosses.\nfn intersect_quad_ray<'a>(\n    line: &[Point; 2],\n    quad: &[Point; 3],\n    roots: &'a mut [NormalizedF32Exclusive; 3],\n) -> &'a [NormalizedF32Exclusive] {\n    let vec = line[1] - line[0];\n    let mut r = [0.0; 3];\n    for n in 0..3 {\n        r[n] = (quad[n].y - line[0].y) * vec.x - (quad[n].x - line[0].x) * vec.y;\n    }\n    let mut a = r[2];\n    let mut b = r[1];\n    let c = r[0];\n    a += c - 2.0 * b; // A = a - 2*b + c\n    b -= c; // B = -(b - c)\n\n    let len = path_geometry::find_unit_quad_roots(a, 2.0 * b, c, roots);\n    &roots[0..len]\n}\n\nfn points_within_dist(near_pt: Point, far_pt: Point, limit: f32) -> bool {\n    near_pt.distance_to_sqd(far_pt) <= limit * limit\n}\n\nfn sharp_angle(quad: &[Point; 3]) -> bool {\n    let mut smaller = quad[1] - quad[0];\n    let mut larger = quad[1] - quad[2];\n    let smaller_len = smaller.length_sqd();\n    let mut larger_len = larger.length_sqd();\n    if smaller_len > larger_len {\n        core::mem::swap(&mut smaller, &mut larger);\n        larger_len = smaller_len;\n    }\n\n    if !smaller.set_length(larger_len) {\n        return false;\n    }\n\n    let dot = smaller.dot(larger);\n    dot > 0.0\n}\n\n// Return true if the point is close to the bounds of the quad. This is used as a quick reject.\nfn pt_in_quad_bounds(quad: &[Point; 3], pt: Point, inv_res_scale: f32) -> bool {\n    let x_min = quad[0].x.min(quad[1].x).min(quad[2].x);\n    if pt.x + inv_res_scale < x_min {\n        return false;\n    }\n\n    let x_max = quad[0].x.max(quad[1].x).max(quad[2].x);\n    if pt.x - inv_res_scale > x_max {\n        return false;\n    }\n\n    let y_min = quad[0].y.min(quad[1].y).min(quad[2].y);\n    if pt.y + inv_res_scale < y_min {\n        return false;\n    }\n\n    let y_max = quad[0].y.max(quad[1].y).max(quad[2].y);\n    if pt.y - inv_res_scale > y_max {\n        return false;\n    }\n\n    true\n}\n\nfn check_cubic_linear(\n    cubic: &[Point; 4],\n    reduction: &mut [Point; 3],\n    tangent_pt: Option<&mut Point>,\n) -> ReductionType {\n    let degenerate_ab = degenerate_vector(cubic[1] - cubic[0]);\n    let degenerate_bc = degenerate_vector(cubic[2] - cubic[1]);\n    let degenerate_cd = degenerate_vector(cubic[3] - cubic[2]);\n    if degenerate_ab & degenerate_bc & degenerate_cd {\n        return ReductionType::Point;\n    }\n\n    if degenerate_ab as i32 + degenerate_bc as i32 + degenerate_cd as i32 == 2 {\n        return ReductionType::Line;\n    }\n\n    if !cubic_in_line(cubic) {\n        if let Some(tangent_pt) = tangent_pt {\n            *tangent_pt = if degenerate_ab { cubic[2] } else { cubic[1] };\n        }\n\n        return ReductionType::Quad;\n    }\n\n    let mut t_values = [NormalizedF32::ZERO; 3];\n    let t_values = path_geometry::find_cubic_max_curvature(cubic, &mut t_values);\n    let mut r_count = 0;\n    // Now loop over the t-values, and reject any that evaluate to either end-point\n    for t in t_values {\n        if 0.0 >= t.get() || t.get() >= 1.0 {\n            continue;\n        }\n\n        reduction[r_count] = path_geometry::eval_cubic_pos_at(cubic, *t);\n        if reduction[r_count] != cubic[0] && reduction[r_count] != cubic[3] {\n            r_count += 1;\n        }\n    }\n\n    match r_count {\n        0 => ReductionType::Line,\n        1 => ReductionType::Degenerate,\n        2 => ReductionType::Degenerate2,\n        3 => ReductionType::Degenerate3,\n        _ => unreachable!(),\n    }\n}\n\n/// Given a cubic, determine if all four points are in a line.\n///\n/// Return true if the inner points is close to a line connecting the outermost points.\n///\n/// Find the outermost point by looking for the largest difference in X or Y.\n/// Given the indices of the outermost points, and that outer_1 is greater than outer_2,\n/// this table shows the index of the smaller of the remaining points:\n///\n/// ```text\n///                   outer_2\n///               0    1    2    3\n///   outer_1     ----------------\n///      0     |  -    2    1    1\n///      1     |  -    -    0    0\n///      2     |  -    -    -    0\n///      3     |  -    -    -    -\n/// ```\n///\n/// If outer_1 == 0 and outer_2 == 1, the smaller of the remaining indices (2 and 3) is 2.\n///\n/// This table can be collapsed to: (1 + (2 >> outer_2)) >> outer_1\n///\n/// Given three indices (outer_1 outer_2 mid_1) from 0..3, the remaining index is:\n///\n/// ```text\n/// mid_2 == (outer_1 ^ outer_2 ^ mid_1)\n/// ```\nfn cubic_in_line(cubic: &[Point; 4]) -> bool {\n    let mut pt_max = -1.0;\n    let mut outer1 = 0;\n    let mut outer2 = 0;\n    for index in 0..3 {\n        for inner in index + 1..4 {\n            let test_diff = cubic[inner] - cubic[index];\n            let test_max = test_diff.x.abs().max(test_diff.y.abs());\n            if pt_max < test_max {\n                outer1 = index;\n                outer2 = inner;\n                pt_max = test_max;\n            }\n        }\n    }\n    debug_assert!(outer1 <= 2);\n    debug_assert!(outer2 >= 1 && outer2 <= 3);\n    debug_assert!(outer1 < outer2);\n    let mid1 = (1 + (2 >> outer2)) >> outer1;\n    debug_assert!(mid1 <= 2);\n    debug_assert!(outer1 != mid1 && outer2 != mid1);\n    let mid2 = outer1 ^ outer2 ^ mid1;\n    debug_assert!(mid2 >= 1 && mid2 <= 3);\n    debug_assert!(mid2 != outer1 && mid2 != outer2 && mid2 != mid1);\n    debug_assert!(((1 << outer1) | (1 << outer2) | (1 << mid1) | (1 << mid2)) == 0x0f);\n    let line_slop = pt_max * pt_max * 0.00001; // this multiplier is pulled out of the air\n\n    pt_to_line(cubic[mid1], cubic[outer1], cubic[outer2]) <= line_slop\n        && pt_to_line(cubic[mid2], cubic[outer1], cubic[outer2]) <= line_slop\n}\n\n#[rustfmt::skip]\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    impl PathSegment {\n        fn new_move_to(x: f32, y: f32) -> Self {\n            PathSegment::MoveTo(Point::from_xy(x, y))\n        }\n\n        fn new_line_to(x: f32, y: f32) -> Self {\n            PathSegment::LineTo(Point::from_xy(x, y))\n        }\n\n        // fn new_quad_to(x1: f32, y1: f32, x: f32, y: f32) -> Self {\n        //     PathSegment::QuadTo(Point::from_xy(x1, y1), Point::from_xy(x, y))\n        // }\n\n        // fn new_cubic_to(x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) -> Self {\n        //     PathSegment::CubicTo(Point::from_xy(x1, y1), Point::from_xy(x2, y2), Point::from_xy(x, y))\n        // }\n\n        fn new_close() -> Self {\n            PathSegment::Close\n        }\n    }\n\n    // Make sure that subpath auto-closing is enabled.\n    #[test]\n    fn auto_close() {\n        // A triangle.\n        let mut pb = PathBuilder::new();\n        pb.move_to(10.0, 10.0);\n        pb.line_to(20.0, 50.0);\n        pb.line_to(30.0, 10.0);\n        pb.close();\n        let path = pb.finish().unwrap();\n\n        let stroke = Stroke::default();\n        let stroke_path = PathStroker::new().stroke(&path, &stroke, 1.0).unwrap();\n\n        let mut iter = stroke_path.segments();\n        iter.set_auto_close(true);\n\n        assert_eq!(iter.next().unwrap(), PathSegment::new_move_to(10.485071, 9.878732));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(20.485071, 49.878731));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(20.0, 50.0));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(19.514929, 49.878731));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(29.514929, 9.878732));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(30.0, 10.0));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(30.0, 10.5));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(10.0, 10.5));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(10.0, 10.0));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(10.485071, 9.878732));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_close());\n        assert_eq!(iter.next().unwrap(), PathSegment::new_move_to(9.3596115, 9.5));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(30.640388, 9.5));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(20.485071, 50.121269));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(19.514929, 50.121269));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(9.514929, 10.121268));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_line_to(9.3596115, 9.5));\n        assert_eq!(iter.next().unwrap(), PathSegment::new_close());\n    }\n\n    // From skia/tests/StrokeTest.cpp\n    #[test]\n    fn cubic_1() {\n        let mut pb = PathBuilder::new();\n        pb.move_to(51.0161362, 1511.52478);\n        pb.cubic_to(\n            51.0161362, 1511.52478,\n            51.0161362, 1511.52478,\n            51.0161362, 1511.52478,\n        );\n        let path = pb.finish().unwrap();\n\n        let mut stroke = Stroke::default();\n        stroke.width = 0.394537568;\n\n        assert!(PathStroker::new().stroke(&path, &stroke, 1.0).is_none());\n    }\n\n    // From skia/tests/StrokeTest.cpp\n    #[test]\n    fn cubic_2() {\n        let mut pb = PathBuilder::new();\n        pb.move_to(f32::from_bits(0x424c1086), f32::from_bits(0x44bcf0cb)); // 51.0161362, 1511.52478\n        pb.cubic_to(\n            f32::from_bits(0x424c107c), f32::from_bits(0x44bcf0cb), // 51.0160980, 1511.52478\n            f32::from_bits(0x424c10c2), f32::from_bits(0x44bcf0cb), // 51.0163651, 1511.52478\n            f32::from_bits(0x424c1119), f32::from_bits(0x44bcf0ca), // 51.0166969, 1511.52466\n        );\n        let path = pb.finish().unwrap();\n\n        let mut stroke = Stroke::default();\n        stroke.width = 0.394537568;\n\n        assert!(PathStroker::new().stroke(&path, &stroke, 1.0).is_some());\n    }\n\n    // From skia/tests/StrokeTest.cpp\n    // From skbug.com/6491. The large stroke width can cause numerical instabilities.\n    #[test]\n    fn big() {\n        // Skia uses `kStrokeAndFill_Style` here, but we do not support it.\n\n        let mut pb = PathBuilder::new();\n        pb.move_to(f32::from_bits(0x46380000), f32::from_bits(0xc6380000)); // 11776, -11776\n        pb.line_to(f32::from_bits(0x46a00000), f32::from_bits(0xc6a00000)); // 20480, -20480\n        pb.line_to(f32::from_bits(0x468c0000), f32::from_bits(0xc68c0000)); // 17920, -17920\n        pb.line_to(f32::from_bits(0x46100000), f32::from_bits(0xc6100000)); // 9216, -9216\n        pb.line_to(f32::from_bits(0x46380000), f32::from_bits(0xc6380000)); // 11776, -11776\n        pb.close();\n        let path = pb.finish().unwrap();\n\n        let mut stroke = Stroke::default();\n        stroke.width = 1.49679073e+10;\n\n        assert!(PathStroker::new().stroke(&path, &stroke, 1.0).is_some());\n    }\n\n    // From skia/tests/StrokerTest.cpp\n    #[test]\n    fn quad_stroker_one_off() {\n        let mut pb = PathBuilder::new();\n        pb.move_to(f32::from_bits(0x43c99223), f32::from_bits(0x42b7417e));\n        pb.quad_to(\n            f32::from_bits(0x4285d839), f32::from_bits(0x43ed6645),\n            f32::from_bits(0x43c941c8), f32::from_bits(0x42b3ace3),\n        );\n        let path = pb.finish().unwrap();\n\n        let mut stroke = Stroke::default();\n        stroke.width = 164.683548;\n\n        assert!(PathStroker::new().stroke(&path, &stroke, 1.0).is_some());\n    }\n\n    // From skia/tests/StrokerTest.cpp\n    #[test]\n    fn cubic_stroker_one_off() {\n        let mut pb = PathBuilder::new();\n        pb.move_to(f32::from_bits(0x433f5370), f32::from_bits(0x43d1f4b3));\n        pb.cubic_to(\n            f32::from_bits(0x4331cb76), f32::from_bits(0x43ea3340),\n            f32::from_bits(0x4388f498), f32::from_bits(0x42f7f08d),\n            f32::from_bits(0x43f1cd32), f32::from_bits(0x42802ec1),\n        );\n        let path = pb.finish().unwrap();\n\n        let mut stroke = Stroke::default();\n        stroke.width = 42.835968;\n\n        assert!(PathStroker::new().stroke(&path, &stroke, 1.0).is_some());\n    }\n}\n"
    },
    {
      "package": "tiny-skia-path@0.10.0",
      "sourcePath": "src/transform.rs",
      "sha256": "a84e29e3a0819fd563b55a5570deadb332ef2e2008cfbc102176ec37df3ad61b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2006 The Android Open Source Project\n// Copyright 2020 Yevhenii Reizner\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nuse crate::{NonZeroRect, Point};\n\nuse crate::scalar::{Scalar, SCALAR_NEARLY_ZERO};\n\n#[cfg(all(not(feature = \"std\"), feature = \"no-std-float\"))]\nuse crate::NoStdFloat;\n\n/// An affine transformation matrix.\n///\n/// Unlike other types, doesn't guarantee to be valid. This is Skia quirk.\n/// Meaning Transform(0, 0, 0, 0, 0, 0) is ok, while it's technically not.\n/// Non-finite values are also not an error.\n#[allow(missing_docs)]\n#[derive(Copy, Clone, PartialEq, Debug)]\npub struct Transform {\n    pub sx: f32,\n    pub kx: f32,\n    pub ky: f32,\n    pub sy: f32,\n    pub tx: f32,\n    pub ty: f32,\n}\n\nimpl Default for Transform {\n    fn default() -> Self {\n        Transform {\n            sx: 1.0,\n            kx: 0.0,\n            ky: 0.0,\n            sy: 1.0,\n            tx: 0.0,\n            ty: 0.0,\n        }\n    }\n}\n\nimpl Transform {\n    /// Creates an identity transform.\n    pub fn identity() -> Self {\n        Transform::default()\n    }\n\n    /// Creates a new `Transform`.\n    ///\n    /// We are using column-major-column-vector matrix notation, therefore it's ky-kx, not kx-ky.\n    pub fn from_row(sx: f32, ky: f32, kx: f32, sy: f32, tx: f32, ty: f32) -> Self {\n        Transform {\n            sx,\n            ky,\n            kx,\n            sy,\n            tx,\n            ty,\n        }\n    }\n\n    /// Creates a new translating `Transform`.\n    pub fn from_translate(tx: f32, ty: f32) -> Self {\n        Transform::from_row(1.0, 0.0, 0.0, 1.0, tx, ty)\n    }\n\n    /// Creates a new scaling `Transform`.\n    pub fn from_scale(sx: f32, sy: f32) -> Self {\n        Transform::from_row(sx, 0.0, 0.0, sy, 0.0, 0.0)\n    }\n\n    /// Creates a new skewing `Transform`.\n    pub fn from_skew(kx: f32, ky: f32) -> Self {\n        Transform::from_row(1.0, ky, kx, 1.0, 0.0, 0.0)\n    }\n\n    /// Creates a new rotating `Transform`.\n    ///\n    /// `angle` in degrees.\n    pub fn from_rotate(angle: f32) -> Self {\n        let v = angle.to_radians();\n        let a = v.cos();\n        let b = v.sin();\n        let c = -b;\n        let d = a;\n        Transform::from_row(a, b, c, d, 0.0, 0.0)\n    }\n\n    /// Creates a new rotating `Transform` at the specified position.\n    ///\n    /// `angle` in degrees.\n    pub fn from_rotate_at(angle: f32, tx: f32, ty: f32) -> Self {\n        let mut ts = Self::default();\n        ts = ts.pre_translate(tx, ty);\n        ts = ts.pre_concat(Transform::from_rotate(angle));\n        ts = ts.pre_translate(-tx, -ty);\n        ts\n    }\n\n    /// Converts `Rect` into a bounding box `Transform`.\n    #[inline]\n    pub fn from_bbox(bbox: NonZeroRect) -> Self {\n        Transform::from_row(bbox.width(), 0.0, 0.0, bbox.height(), bbox.x(), bbox.y())\n    }\n\n    /// Checks that transform is finite.\n    pub fn is_finite(&self) -> bool {\n        self.sx.is_finite()\n            && self.ky.is_finite()\n            && self.kx.is_finite()\n            && self.sy.is_finite()\n            && self.tx.is_finite()\n            && self.ty.is_finite()\n    }\n\n    /// Checks that transform is finite and has non-zero scale.\n    pub fn is_valid(&self) -> bool {\n        if self.is_finite() {\n            let (sx, sy) = self.get_scale();\n            if sx.is_nearly_zero() || sy.is_nearly_zero() {\n                false\n            } else {\n                true\n            }\n        } else {\n            false\n        }\n    }\n\n    /// Checks that transform is identity.\n    pub fn is_identity(&self) -> bool {\n        *self == Transform::default()\n    }\n\n    /// Checks that transform is scale-only.\n    pub fn is_scale(&self) -> bool {\n        self.has_scale() && !self.has_skew() && !self.has_translate()\n    }\n\n    /// Checks that transform is skew-only.\n    pub fn is_skew(&self) -> bool {\n        !self.has_scale() && self.has_skew() && !self.has_translate()\n    }\n\n    /// Checks that transform is translate-only.\n    pub fn is_translate(&self) -> bool {\n        !self.has_scale() && !self.has_skew() && self.has_translate()\n    }\n\n    /// Checks that transform contains only scale and translate.\n    pub fn is_scale_translate(&self) -> bool {\n        (self.has_scale() || self.has_translate()) && !self.has_skew()\n    }\n\n    /// Checks that transform contains a scale part.\n    pub fn has_scale(&self) -> bool {\n        self.sx != 1.0 || self.sy != 1.0\n    }\n\n    /// Checks that transform contains a skew part.\n    pub fn has_skew(&self) -> bool {\n        self.kx != 0.0 || self.ky != 0.0\n    }\n\n    /// Checks that transform contains a translate part.\n    pub fn has_translate(&self) -> bool {\n        self.tx != 0.0 || self.ty != 0.0\n    }\n\n    /// Returns transform's scale part.\n    pub fn get_scale(&self) -> (f32, f32) {\n        let x_scale = (self.sx * self.sx + self.kx * self.kx).sqrt();\n        let y_scale = (self.ky * self.ky + self.sy * self.sy).sqrt();\n        (x_scale, y_scale)\n    }\n\n    /// Pre-scales the current transform.\n    #[must_use]\n    pub fn pre_scale(&self, sx: f32, sy: f32) -> Self {\n        self.pre_concat(Transform::from_scale(sx, sy))\n    }\n\n    /// Post-scales the current transform.\n    #[must_use]\n    pub fn post_scale(&self, sx: f32, sy: f32) -> Self {\n        self.post_concat(Transform::from_scale(sx, sy))\n    }\n\n    /// Pre-translates the current transform.\n    #[must_use]\n    pub fn pre_translate(&self, tx: f32, ty: f32) -> Self {\n        self.pre_concat(Transform::from_translate(tx, ty))\n    }\n\n    /// Post-translates the current transform.\n    #[must_use]\n    pub fn post_translate(&self, tx: f32, ty: f32) -> Self {\n        self.post_concat(Transform::from_translate(tx, ty))\n    }\n\n    /// Pre-rotates the current transform.\n    ///\n    /// `angle` in degrees.\n    #[must_use]\n    pub fn pre_rotate(&self, angle: f32) -> Self {\n        self.pre_concat(Transform::from_rotate(angle))\n    }\n\n    /// Post-rotates the current transform.\n    ///\n    /// `angle` in degrees.\n    #[must_use]\n    pub fn post_rotate(&self, angle: f32) -> Self {\n        self.post_concat(Transform::from_rotate(angle))\n    }\n\n    /// Pre-rotates the current transform by the specified position.\n    ///\n    /// `angle` in degrees.\n    #[must_use]\n    pub fn pre_rotate_at(&self, angle: f32, tx: f32, ty: f32) -> Self {\n        self.pre_concat(Transform::from_rotate_at(angle, tx, ty))\n    }\n\n    /// Post-rotates the current transform by the specified position.\n    ///\n    /// `angle` in degrees.\n    #[must_use]\n    pub fn post_rotate_at(&self, angle: f32, tx: f32, ty: f32) -> Self {\n        self.post_concat(Transform::from_rotate_at(angle, tx, ty))\n    }\n\n    /// Pre-concats the current transform.\n    #[must_use]\n    pub fn pre_concat(&self, other: Self) -> Self {\n        concat(*self, other)\n    }\n\n    /// Post-concats the current transform.\n    #[must_use]\n    pub fn post_concat(&self, other: Self) -> Self {\n        concat(other, *self)\n    }\n\n    pub(crate) fn from_sin_cos(sin: f32, cos: f32) -> Self {\n        Transform::from_row(cos, sin, -sin, cos, 0.0, 0.0)\n    }\n\n    /// Transforms a points using the current transform.\n    pub fn map_point(&self, point: &mut Point) {\n        if self.is_identity() {\n            // Do nothing.\n        } else if self.is_translate() {\n            point.x += self.tx;\n            point.y += self.ty;\n        } else if self.is_scale_translate() {\n            point.x = point.x * self.sx + self.tx;\n            point.y = point.y * self.sy + self.ty;\n        } else {\n            let x = point.x * self.sx + point.y * self.kx + self.tx;\n            let y = point.x * self.ky + point.y * self.sy + self.ty;\n            point.x = x;\n            point.y = y;\n        }\n    }\n\n    /// Transforms a slice of points using the current transform.\n    pub fn map_points(&self, points: &mut [Point]) {\n        if points.is_empty() {\n            return;\n        }\n\n        // TODO: simd\n\n        if self.is_identity() {\n            // Do nothing.\n        } else if self.is_translate() {\n            for p in points {\n                p.x += self.tx;\n                p.y += self.ty;\n            }\n        } else if self.is_scale_translate() {\n            for p in points {\n                p.x = p.x * self.sx + self.tx;\n                p.y = p.y * self.sy + self.ty;\n            }\n        } else {\n            for p in points {\n                let x = p.x * self.sx + p.y * self.kx + self.tx;\n                let y = p.x * self.ky + p.y * self.sy + self.ty;\n                p.x = x;\n                p.y = y;\n            }\n        }\n    }\n\n    /// Returns an inverted transform.\n    pub fn invert(&self) -> Option<Self> {\n        // Allow the trivial case to be inlined.\n        if self.is_identity() {\n            return Some(*self);\n        }\n\n        invert(self)\n    }\n}\n\nfn invert(ts: &Transform) -> Option<Transform> {\n    debug_assert!(!ts.is_identity());\n\n    if ts.is_scale_translate() {\n        if ts.has_scale() {\n            let inv_x = ts.sx.invert();\n            let inv_y = ts.sy.invert();\n            Some(Transform::from_row(\n                inv_x,\n                0.0,\n                0.0,\n                inv_y,\n                -ts.tx * inv_x,\n                -ts.ty * inv_y,\n            ))\n        } else {\n            // translate only\n            Some(Transform::from_translate(-ts.tx, -ts.ty))\n        }\n    } else {\n        let inv_det = inv_determinant(ts)?;\n        let inv_ts = compute_inv(ts, inv_det);\n\n        if inv_ts.is_finite() {\n            Some(inv_ts)\n        } else {\n            None\n        }\n    }\n}\n\nfn inv_determinant(ts: &Transform) -> Option<f64> {\n    let det = dcross(ts.sx as f64, ts.sy as f64, ts.kx as f64, ts.ky as f64);\n\n    // Since the determinant is on the order of the cube of the matrix members,\n    // compare to the cube of the default nearly-zero constant (although an\n    // estimate of the condition number would be better if it wasn't so expensive).\n    let tolerance = SCALAR_NEARLY_ZERO * SCALAR_NEARLY_ZERO * SCALAR_NEARLY_ZERO;\n    if (det as f32).is_nearly_zero_within_tolerance(tolerance) {\n        None\n    } else {\n        Some(1.0 / det)\n    }\n}\n\nfn compute_inv(ts: &Transform, inv_det: f64) -> Transform {\n    Transform::from_row(\n        (ts.sy as f64 * inv_det) as f32,\n        (-ts.ky as f64 * inv_det) as f32,\n        (-ts.kx as f64 * inv_det) as f32,\n        (ts.sx as f64 * inv_det) as f32,\n        dcross_dscale(ts.kx, ts.ty, ts.sy, ts.tx, inv_det),\n        dcross_dscale(ts.ky, ts.tx, ts.sx, ts.ty, inv_det),\n    )\n}\n\nfn dcross(a: f64, b: f64, c: f64, d: f64) -> f64 {\n    a * b - c * d\n}\n\nfn dcross_dscale(a: f32, b: f32, c: f32, d: f32, scale: f64) -> f32 {\n    (dcross(a as f64, b as f64, c as f64, d as f64) * scale) as f32\n}\n\nfn concat(a: Transform, b: Transform) -> Transform {\n    if a.is_identity() {\n        b\n    } else if b.is_identity() {\n        a\n    } else if !a.has_skew() && !b.has_skew() {\n        // just scale and translate\n        Transform::from_row(\n            a.sx * b.sx,\n            0.0,\n            0.0,\n            a.sy * b.sy,\n            a.sx * b.tx + a.tx,\n            a.sy * b.ty + a.ty,\n        )\n    } else {\n        Transform::from_row(\n            mul_add_mul(a.sx, b.sx, a.kx, b.ky),\n            mul_add_mul(a.ky, b.sx, a.sy, b.ky),\n            mul_add_mul(a.sx, b.kx, a.kx, b.sy),\n            mul_add_mul(a.ky, b.kx, a.sy, b.sy),\n            mul_add_mul(a.sx, b.tx, a.kx, b.ty) + a.tx,\n            mul_add_mul(a.ky, b.tx, a.sy, b.ty) + a.ty,\n        )\n    }\n}\n\nfn mul_add_mul(a: f32, b: f32, c: f32, d: f32) -> f32 {\n    (f64::from(a) * f64::from(b) + f64::from(c) * f64::from(d)) as f32\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn transform() {\n        assert_eq!(\n            Transform::identity(),\n            Transform::from_row(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)\n        );\n\n        assert_eq!(\n            Transform::from_scale(1.0, 2.0),\n            Transform::from_row(1.0, 0.0, 0.0, 2.0, 0.0, 0.0)\n        );\n\n        assert_eq!(\n            Transform::from_skew(2.0, 3.0),\n            Transform::from_row(1.0, 3.0, 2.0, 1.0, 0.0, 0.0)\n        );\n\n        assert_eq!(\n            Transform::from_translate(5.0, 6.0),\n            Transform::from_row(1.0, 0.0, 0.0, 1.0, 5.0, 6.0)\n        );\n\n        let ts = Transform::identity();\n        assert_eq!(ts.is_identity(), true);\n        assert_eq!(ts.is_scale(), false);\n        assert_eq!(ts.is_skew(), false);\n        assert_eq!(ts.is_translate(), false);\n        assert_eq!(ts.is_scale_translate(), false);\n        assert_eq!(ts.has_scale(), false);\n        assert_eq!(ts.has_skew(), false);\n        assert_eq!(ts.has_translate(), false);\n\n        let ts = Transform::from_scale(2.0, 3.0);\n        assert_eq!(ts.is_identity(), false);\n        assert_eq!(ts.is_scale(), true);\n        assert_eq!(ts.is_skew(), false);\n        assert_eq!(ts.is_translate(), false);\n        assert_eq!(ts.is_scale_translate(), true);\n        assert_eq!(ts.has_scale(), true);\n        assert_eq!(ts.has_skew(), false);\n        assert_eq!(ts.has_translate(), false);\n\n        let ts = Transform::from_skew(2.0, 3.0);\n        assert_eq!(ts.is_identity(), false);\n        assert_eq!(ts.is_scale(), false);\n        assert_eq!(ts.is_skew(), true);\n        assert_eq!(ts.is_translate(), false);\n        assert_eq!(ts.is_scale_translate(), false);\n        assert_eq!(ts.has_scale(), false);\n        assert_eq!(ts.has_skew(), true);\n        assert_eq!(ts.has_translate(), false);\n\n        let ts = Transform::from_translate(2.0, 3.0);\n        assert_eq!(ts.is_identity(), false);\n        assert_eq!(ts.is_scale(), false);\n        assert_eq!(ts.is_skew(), false);\n        assert_eq!(ts.is_translate(), true);\n        assert_eq!(ts.is_scale_translate(), true);\n        assert_eq!(ts.has_scale(), false);\n        assert_eq!(ts.has_skew(), false);\n        assert_eq!(ts.has_translate(), true);\n\n        let ts = Transform::from_row(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\n        assert_eq!(ts.is_identity(), false);\n        assert_eq!(ts.is_scale(), false);\n        assert_eq!(ts.is_skew(), false);\n        assert_eq!(ts.is_translate(), false);\n        assert_eq!(ts.is_scale_translate(), false);\n        assert_eq!(ts.has_scale(), true);\n        assert_eq!(ts.has_skew(), true);\n        assert_eq!(ts.has_translate(), true);\n\n        let ts = Transform::from_scale(1.0, 1.0);\n        assert_eq!(ts.has_scale(), false);\n\n        let ts = Transform::from_skew(0.0, 0.0);\n        assert_eq!(ts.has_skew(), false);\n\n        let ts = Transform::from_translate(0.0, 0.0);\n        assert_eq!(ts.has_translate(), false);\n    }\n\n    #[test]\n    fn concat() {\n        let mut ts = Transform::from_row(1.2, 3.4, -5.6, -7.8, 1.2, 3.4);\n        ts = ts.pre_scale(2.0, -4.0);\n        assert_eq!(ts, Transform::from_row(2.4, 6.8, 22.4, 31.2, 1.2, 3.4));\n\n        let mut ts = Transform::from_row(1.2, 3.4, -5.6, -7.8, 1.2, 3.4);\n        ts = ts.post_scale(2.0, -4.0);\n        assert_eq!(ts, Transform::from_row(2.4, -13.6, -11.2, 31.2, 2.4, -13.6));\n    }\n}\n"
    },
    {
      "package": "tinyvec@1.13.3",
      "sourcePath": "LICENSE-APACHE.md",
      "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
    },
    {
      "package": "tinyvec@1.13.3",
      "sourcePath": "LICENSE-MIT.md",
      "sha256": "fd80a26fbb3f644af1fa994134446702932968519797227e07a1368dea80f0bc",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
    },
    {
      "package": "tinyvec@1.13.3",
      "sourcePath": "LICENSE-ZLIB.md",
      "sha256": "84b34dd7608f7fb9b17bd588a6bf392bf7de504e2716f024a77d89f1b145a151",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Copyright (c) 2019 Daniel \"Lokathor\" Gee.\n\nThis software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source distribution.\n"
    },
    {
      "package": "tokio@1.53.1",
      "sourcePath": "README.md",
      "sha256": "d66d59d170ce56b4f80e16e7564fe91ca611daffffe82a8625a9a67bb85c8800",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "*[TokioConf 2026 program and tickets are now available!](https://tokioconf.com)*\n\n---\n\n# Tokio\n\nA runtime for writing reliable, asynchronous, and slim applications with\nthe Rust programming language. It is:\n\n* **Fast**: Tokio's zero-cost abstractions give you bare-metal\n  performance.\n\n* **Reliable**: Tokio leverages Rust's ownership, type system, and\n  concurrency model to reduce bugs and ensure thread safety.\n\n* **Scalable**: Tokio has a minimal footprint, and handles backpressure\n  and cancellation naturally.\n\n[![Crates.io][crates-badge]][crates-url]\n[![MIT licensed][mit-badge]][mit-url]\n[![Build Status][actions-badge]][actions-url]\n[![Discord chat][discord-badge]][discord-url]\n\n[crates-badge]: https://img.shields.io/crates/v/tokio.svg\n[crates-url]: https://crates.io/crates/tokio\n[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg\n[mit-url]: https://github.com/tokio-rs/tokio/blob/master/LICENSE\n[actions-badge]: https://github.com/tokio-rs/tokio/workflows/CI/badge.svg\n[actions-url]: https://github.com/tokio-rs/tokio/actions?query=workflow%3ACI+branch%3Amaster\n[discord-badge]: https://img.shields.io/discord/500028886025895936.svg?logo=discord&style=flat-square\n[discord-url]: https://discord.gg/tokio\n\n[Website](https://tokio.rs) |\n[Guides](https://tokio.rs/tokio/tutorial) |\n[API Docs](https://docs.rs/tokio/latest/tokio) |\n[Chat](https://discord.gg/tokio)\n\n## Overview\n\nTokio is an event-driven, non-blocking I/O platform for writing\nasynchronous applications with the Rust programming language. At a high\nlevel, it provides a few major components:\n\n* A multithreaded, work-stealing based task [scheduler].\n* A reactor backed by the operating system's event queue (epoll, kqueue,\n  IOCP, etc.).\n* Asynchronous [TCP and UDP][net] sockets.\n\nThese components provide the runtime components necessary for building\nan asynchronous application.\n\n[net]: https://docs.rs/tokio/latest/tokio/net/index.html\n[scheduler]: https://docs.rs/tokio/latest/tokio/runtime/index.html\n\n## Example\n\nA basic TCP echo server with Tokio.\n\nMake sure you enable the full features of the tokio crate on Cargo.toml:\n\n```toml\n[dependencies]\ntokio = { version = \"1.53.1\", features = [\"full\"] }\n```\nThen, on your main.rs:\n\n```rust,no_run\nuse tokio::net::TcpListener;\nuse tokio::io::{AsyncReadExt, AsyncWriteExt};\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn std::error::Error>> {\n    let listener = TcpListener::bind(\"127.0.0.1:8080\").await?;\n\n    loop {\n        let (mut socket, _) = listener.accept().await?;\n\n        tokio::spawn(async move {\n            let mut buf = [0; 1024];\n\n            // In a loop, read data from the socket and write the data back.\n            loop {\n                let n = match socket.read(&mut buf).await {\n                    // socket closed\n                    Ok(0) => return,\n                    Ok(n) => n,\n                    Err(e) => {\n                        eprintln!(\"failed to read from socket; err = {:?}\", e);\n                        return;\n                    }\n                };\n\n                // Write the data back\n                if let Err(e) = socket.write_all(&buf[0..n]).await {\n                    eprintln!(\"failed to write to socket; err = {:?}\", e);\n                    return;\n                }\n            }\n        });\n    }\n}\n```\n\nMore examples can be found [here][examples]. For a larger \"real world\" example, see the\n[mini-redis] repository.\n\n[examples]: https://github.com/tokio-rs/tokio/tree/master/examples\n[mini-redis]: https://github.com/tokio-rs/mini-redis/\n\nTo see a list of the available feature flags that can be enabled, check our\n[docs][feature-flag-docs].\n\n## Getting Help\n\nFirst, see if the answer to your question can be found in the [Guides] or the\n[API documentation]. If the answer is not there, there is an active community in\nthe [Tokio Discord server][chat]. We would be happy to try to answer your\nquestion. You can also ask your question on [the discussions page][discussions].\n\n[Guides]: https://tokio.rs/tokio/tutorial\n[API documentation]: https://docs.rs/tokio/latest/tokio\n[chat]: https://discord.gg/tokio\n[discussions]: https://github.com/tokio-rs/tokio/discussions\n[feature-flag-docs]: https://docs.rs/tokio/#feature-flags\n\n## Contributing\n\n:balloon: Thanks for your help improving the project! We are so happy to have\nyou! We have a [contributing guide][guide] to help you get involved in the Tokio\nproject.\n\n[guide]: https://github.com/tokio-rs/tokio/blob/master/docs/contributing/README.md\n\n## Related Projects\n\nIn addition to the crates in this repository, the Tokio project also maintains\nseveral other libraries, including:\n\n* [`axum`]: A web application framework that focuses on ergonomics and modularity.\n\n* [`hyper`]: A fast and correct HTTP/1.1 and HTTP/2 implementation for Rust.\n\n* [`tonic`]: A gRPC over HTTP/2 implementation focused on high performance, interoperability, and flexibility.\n\n* [`warp`]: A super-easy, composable, web server framework for warp speeds.\n\n* [`tower`]: A library of modular and reusable components for building robust networking clients and servers.\n\n* [`tracing`] (formerly `tokio-trace`): A framework for application-level tracing and async-aware diagnostics.\n\n* [`mio`]: A low-level, cross-platform abstraction over OS I/O APIs that powers `tokio`.\n\n* [`bytes`]: Utilities for working with bytes, including efficient byte buffers.\n\n* [`loom`]: A testing tool for concurrent Rust code.\n\n[`axum`]: https://github.com/tokio-rs/axum\n[`warp`]: https://github.com/seanmonstar/warp\n[`hyper`]: https://github.com/hyperium/hyper\n[`tonic`]: https://github.com/hyperium/tonic\n[`tower`]: https://github.com/tower-rs/tower\n[`loom`]: https://github.com/tokio-rs/loom\n[`tracing`]: https://github.com/tokio-rs/tracing\n[`mio`]: https://github.com/tokio-rs/mio\n[`bytes`]: https://github.com/tokio-rs/bytes\n\n## Changelog\n\nThe Tokio repository contains multiple crates. Each crate has its own changelog.\n\n * `tokio` - [view changelog](https://github.com/tokio-rs/tokio/blob/master/tokio/CHANGELOG.md)\n * `tokio-util` - [view changelog](https://github.com/tokio-rs/tokio/blob/master/tokio-util/CHANGELOG.md)\n * `tokio-stream` - [view changelog](https://github.com/tokio-rs/tokio/blob/master/tokio-stream/CHANGELOG.md)\n * `tokio-macros` - [view changelog](https://github.com/tokio-rs/tokio/blob/master/tokio-macros/CHANGELOG.md)\n * `tokio-test` - [view changelog](https://github.com/tokio-rs/tokio/blob/master/tokio-test/CHANGELOG.md)\n\n## Supported Rust Versions\n\n<!--\nWhen updating this, also update:\n- .github/workflows/ci.yml\n- CONTRIBUTING.md\n- README.md\n- tokio/README.md\n- tokio/Cargo.toml\n- tokio-util/Cargo.toml\n- tokio-test/Cargo.toml\n- tokio-stream/Cargo.toml\n-->\n\nTokio will keep a rolling MSRV (minimum supported rust version) policy of **at\nleast** 6 months. When increasing the MSRV, the new Rust version must have been\nreleased at least six months ago. The current MSRV is 1.71.\n\nNote that the MSRV is not increased automatically, and only as part of a minor\nrelease. The MSRV history for past minor releases can be found below:\n\n * 1.48 to now  - Rust 1.71\n * 1.39 to 1.47 - Rust 1.70\n * 1.30 to 1.38 - Rust 1.63\n * 1.27 to 1.29 - Rust 1.56\n * 1.17 to 1.26 - Rust 1.49\n * 1.15 to 1.16 - Rust 1.46\n * 1.0 to 1.14 - Rust 1.45\n\nNote that although we try to avoid the situation where a dependency transitively\nincreases the MSRV of Tokio, we do not guarantee that this does not happen.\nHowever, every minor release will have some set of versions of dependencies that\nworks with the MSRV of that minor release.\n\n## Release schedule\n\nTokio doesn't follow a fixed release schedule, but we typically make one minor\nrelease each month. We make patch releases for bugfixes as necessary.\n\n## Bug patching policy\n\nFor the purposes of making patch releases with bugfixes, we have designated\ncertain minor releases as LTS (long term support) releases. Whenever a bug\nwarrants a patch release with a fix for the bug, it will be backported and\nreleased as a new patch release for each LTS minor version. Our current LTS\nreleases are:\n\n * `1.47.x` - LTS release until September 2026. (MSRV 1.70)\n * `1.51.x` - LTS release until March 2027. (MSRV 1.71)\n\nEach LTS release will continue to receive backported fixes for at least a year.\nIf you wish to use a fixed minor release in your project, we recommend that you\nuse an LTS release.\n\nTo use a fixed minor version, you can specify the version with a tilde. For\nexample, to specify that you wish to use the newest `1.47.x` patch release, you\ncan use the following dependency specification:\n```text\ntokio = { version = \"~1.47\", features = [...] }\n```\n\n### Previous LTS releases\n\n * `1.8.x` - LTS release until February 2022.\n * `1.14.x` - LTS release until June 2022.\n * `1.18.x` - LTS release until June 2023.\n * `1.20.x` - LTS release until September 2023.\n * `1.25.x` - LTS release until March 2024.\n * `1.32.x` - LTS release until September 2024.\n * `1.36.x` - LTS release until March 2025.\n * `1.38.x` - LTS release until July 2025.\n * `1.43.x` - LTS release until March 2026.\n\n## License\n\nThis project is licensed under the [MIT license].\n\n[MIT license]: https://github.com/tokio-rs/tokio/blob/master/LICENSE\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in Tokio by you shall be licensed as MIT, without any additional\nterms or conditions.\n"
    },
    {
      "package": "ttf-parser@0.18.1",
      "sourcePath": "README.md",
      "sha256": "f2d796cd4a2acc5b881ee245b8187793452367cce94ce7af247e0d2b748a5c1d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "## ttf-parser\n![Build Status](https://github.com/RazrFalcon/ttf-parser/workflows/Rust/badge.svg)\n[![Crates.io](https://img.shields.io/crates/v/ttf-parser.svg)](https://crates.io/crates/ttf-parser)\n[![Documentation](https://docs.rs/ttf-parser/badge.svg)](https://docs.rs/ttf-parser)\n[![Rust 1.42+](https://img.shields.io/badge/rust-1.42+-orange.svg)](https://www.rust-lang.org)\n![](https://img.shields.io/badge/unsafe-forbidden-brightgreen.svg)\n\nA high-level, safe, zero-allocation TrueType font parser.\n\nSupports [TrueType](https://docs.microsoft.com/en-us/typography/truetype/),\n[OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/)\nand [AAT](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html)\nfonts.\n\nCan be used as Rust and as C library.\n\n### Features\n\n- A high-level API for most common properties, hiding all parsing and data resolving logic.\n- A low-level, but safe API to access TrueType tables data.\n- Highly configurable. You can disable most of the features, reducing binary size.\n  You can also parse TrueType tables separately, without loading the whole font/face.\n- Zero heap allocations.\n- Zero unsafe.\n- Zero dependencies.\n- `no_std`/WASM compatible.\n- A basic [C API](./c-api).\n- Fast.\n- Stateless. All parsing methods are immutable.\n- Simple and maintainable code (no magic numbers).\n\n### Safety\n\n- The library must not panic. Any panic considered as a critical bug and should be reported.\n- The library forbids unsafe code.\n- No heap allocations, so crash due to OOM is not possible.\n- All recursive methods have a depth limit.\n- Technically, should use less than 64KiB of stack in the worst case scenario.\n- Most of arithmetic operations are checked.\n- Most of numeric casts are checked.\n\n### Alternatives\n\nIt's very hard to compare different libraries, so we are using table-based comparison.\nThere are roughly three types of TrueType tables:\n\n- A table with a list of properties (like `head`, `OS/2`, etc.).<br/>\n  If a library tries to parse it at all then we mark it as supported.\n- A table that contains a single type of data (`glyf`, `CFF` (kinda), `hmtx`, etc.).<br/>\n  Can only be supported or not.\n- A table that contains multiple subtables (`cmap`, `kern`, `GPOS`, etc.).<br/>\n  Can be partially supported and we note which subtables are actually supported.\n\n| Feature/Library   | ttf-parser             | FreeType            | stb_truetype                   |\n| ----------------- | :--------------------: | :-----------------: | :----------------------------: |\n| Memory safe       | ✓                      |                     |                                |\n| Thread safe       | ✓                      |                     | ~ (mostly reentrant)           |\n| Zero allocation   | ✓                      |                     |                                |\n| Variable fonts    | ✓                      | ✓                   |                                |\n| Rendering         | -<sup>1</sup>          | ✓                   | ~ (very primitive)             |\n| `ankr` table      | ✓                      |                     |                                |\n| `avar` table      | ✓                      | ✓                   |                                |\n| `bdat` table      |                        | ✓                   |                                |\n| `bloc` table      |                        | ✓                   |                                |\n| `CBDT` table      | ✓                      | ✓                   |                                |\n| `CBLC` table      | ✓                      | ✓                   |                                |\n| `COLR` table      |                        | ✓                   |                                |\n| `CPAL` table      |                        | ✓                   |                                |\n| `CFF `&nbsp;table | ✓                      | ✓                   | ~ (no `seac` support)          |\n| `CFF2` table      | ✓                      | ✓                   |                                |\n| `cmap` table      | ~ (no 8)               | ✓                   | ~ (no 2,8,10,14; Unicode-only) |\n| `EBDT` table      |                        | ✓                   |                                |\n| `EBLC` table      |                        | ✓                   |                                |\n| `feat` table      | ✓                      |                     |                                |\n| `fvar` table      | ✓                      | ✓                   |                                |\n| `gasp` table      |                        | ✓                   |                                |\n| `GDEF` table      | ~                      |                     |                                |\n| `glyf` table      | ~<sup>2</sup>          | ✓                   | ~<sup>2</sup>                  |\n| `GPOS` table      | ✓                      |                     | ~ (only 2)                     |\n| `GSUB` table      | ✓                      |                     |                                |\n| `gvar` table      | ✓                      | ✓                   |                                |\n| `head` table      | ✓                      | ✓                   | ✓                              |\n| `hhea` table      | ✓                      | ✓                   | ✓                              |\n| `hmtx` table      | ✓                      | ✓                   | ✓                              |\n| `HVAR` table      | ✓                      | ✓                   |                                |\n| `kern` table      | ✓                      | ~ (only 0)          | ~ (only 0)                     |\n| `kerx` table      | ✓                      |                     |                                |\n| `MATH` table      | ✓                      |                     |                                |\n| `maxp` table      | ✓                      | ✓                   | ✓                              |\n| `morx` table      | ✓                      |                     |                                |\n| `MVAR` table      | ✓                      | ✓                   |                                |\n| `name` table      | ✓                      | ✓                   |                                |\n| `OS/2` table      | ✓                      | ✓                   |                                |\n| `post` table      | ✓                      | ✓                   |                                |\n| `sbix` table      | ~ (PNG only)           | ~ (PNG only)        |                                |\n| `SVG `&nbsp;table | ✓                      | ✓                   | ✓                              |\n| `trak` table      | ✓                      |                     |                                |\n| `vhea` table      | ✓                      | ✓                   |                                |\n| `vmtx` table      | ✓                      | ✓                   |                                |\n| `VORG` table      | ✓                      | ✓                   |                                |\n| `VVAR` table      | ✓                      | ✓                   |                                |\n| Language          | Rust + C API           | C                   | C                              |\n| Tested version    | 0.17.0                 | 2.12.0              | 1.24                           |\n| License           | MIT / Apache-2.0       | FTL / GPLv2         | public domain                  |\n\nLegend:\n\n- ✓ - supported\n- ~ - partial\n- *nothing* - not supported\n\nNotes:\n\n1. While `ttf-parser` doesn't support rendering by itself,\n   there are multiple rendering libraries on top of it:\n   [rusttype](https://gitlab.redox-os.org/redox-os/rusttype),\n   [ab-glyph](https://github.com/alexheretic/ab-glyph)\n   and [fontdue](https://github.com/mooman219/fontdue).\n2. Matching points are not supported.\n\n### Performance\n\nTrueType fonts designed for fast querying, so most of the methods are very fast.\nThe main exception is glyph outlining. Glyphs can be stored using two different methods:\nusing [Glyph Data Format](https://docs.microsoft.com/en-us/typography/opentype/spec/glyf)\nand [Compact Font Format](http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5176.CFF.pdf) (pdf).\nThe first one is fairly simple which makes it faster to process.\nThe second one is basically a tiny language with a stack-based VM, which makes it way harder to process.\n\nThe [benchmark](./benches/outline/) tests how long it takes to outline all glyphs in a font.\n\nx86 (AMD 3700X)\n\n| Table/Library | ttf-parser     | FreeType   | stb_truetype   |\n| ------------- | -------------: | ---------: | -------------: |\n| `glyf`        |   `0.901 ms`   | `1.171 ms` | **`0.675 ms`** |\n| `gvar`        | **`2.972 ms`** | `4.132 ms` |              - |\n| `CFF`         | **`1.197 ms`** | `5.647 ms` |   `2.813 ms`   |\n| `CFF2`        | **`1.968 ms`** | `6.392 ms` |              - |\n\nARM (Apple M1)\n\n| Table/Library | ttf-parser     | FreeType   | stb_truetype   |\n| ------------- | -------------: | ---------: | -------------: |\n| `glyf`        | **`0.550 ms`** | `0.854 ms` |   `0.703 ms`   |\n| `gvar`        | **`2.270 ms`** | `4.594 ms` |              - |\n| `CFF`         | **`1.054 ms`** | `5.223 ms` |   `3.262 ms`   |\n| `CFF2`        | **`1.765 ms`** | `5.995 ms` |              - |\n\n**Note:** FreeType is surprisingly slow, so I'm worried that I've messed something up.\n\nAnd here are some methods benchmarks:\n\n```text\ntest outline_glyph_276_from_cff2 ... bench:         867 ns/iter (+/- 15)\ntest from_data_otf_cff           ... bench:         968 ns/iter (+/- 13)\ntest from_data_otf_cff2          ... bench:         887 ns/iter (+/- 25)\ntest outline_glyph_276_from_cff  ... bench:         678 ns/iter (+/- 41)\ntest outline_glyph_276_from_glyf ... bench:         649 ns/iter (+/- 11)\ntest outline_glyph_8_from_cff2   ... bench:         534 ns/iter (+/- 14)\ntest from_data_ttf               ... bench:         467 ns/iter (+/- 11)\ntest glyph_name_post_276         ... bench:         223 ns/iter (+/- 5)\ntest outline_glyph_8_from_cff    ... bench:         315 ns/iter (+/- 13)\ntest outline_glyph_8_from_glyf   ... bench:         291 ns/iter (+/- 5)\ntest family_name                 ... bench:         183 ns/iter (+/- 102)\ntest glyph_name_cff_276          ... bench:          62 ns/iter (+/- 1)\ntest glyph_index_u41             ... bench:          16 ns/iter (+/- 0)\ntest glyph_name_cff_8            ... bench:           5 ns/iter (+/- 0)\ntest glyph_name_post_8           ... bench:           2 ns/iter (+/- 0)\ntest subscript_metrics           ... bench:           2 ns/iter (+/- 0)\ntest glyph_hor_advance           ... bench:           2 ns/iter (+/- 0)\ntest glyph_hor_side_bearing      ... bench:           2 ns/iter (+/- 0)\ntest glyph_name_8                ... bench:           1 ns/iter (+/- 0)\ntest ascender                    ... bench:           1 ns/iter (+/- 0)\ntest underline_metrics           ... bench:           1 ns/iter (+/- 0)\ntest strikeout_metrics           ... bench:           1 ns/iter (+/- 0)\ntest x_height                    ... bench:           1 ns/iter (+/- 0)\ntest units_per_em                ... bench:         0.5 ns/iter (+/- 0)\ntest width                       ... bench:         0.2 ns/iter (+/- 0)\n```\n\n### License\n\nLicensed under either of\n\n- Apache License, Version 2.0\n  ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license\n  ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "ttf-parser@0.18.1",
      "sourcePath": "src/tables/cff/std_names.rs",
      "sha256": "28f192e64551773c97d0457ddabc774cfabe535585a2ef65f37ca48022221923",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "pub const STANDARD_NAMES: &[&str] = &[\n    \".notdef\",\n    \"space\",\n    \"exclam\",\n    \"quotedbl\",\n    \"numbersign\",\n    \"dollar\",\n    \"percent\",\n    \"ampersand\",\n    \"quoteright\",\n    \"parenleft\",\n    \"parenright\",\n    \"asterisk\",\n    \"plus\",\n    \"comma\",\n    \"hyphen\",\n    \"period\",\n    \"slash\",\n    \"zero\",\n    \"one\",\n    \"two\",\n    \"three\",\n    \"four\",\n    \"five\",\n    \"six\",\n    \"seven\",\n    \"eight\",\n    \"nine\",\n    \"colon\",\n    \"semicolon\",\n    \"less\",\n    \"equal\",\n    \"greater\",\n    \"question\",\n    \"at\",\n    \"A\",\n    \"B\",\n    \"C\",\n    \"D\",\n    \"E\",\n    \"F\",\n    \"G\",\n    \"H\",\n    \"I\",\n    \"J\",\n    \"K\",\n    \"L\",\n    \"M\",\n    \"N\",\n    \"O\",\n    \"P\",\n    \"Q\",\n    \"R\",\n    \"S\",\n    \"T\",\n    \"U\",\n    \"V\",\n    \"W\",\n    \"X\",\n    \"Y\",\n    \"Z\",\n    \"bracketleft\",\n    \"backslash\",\n    \"bracketright\",\n    \"asciicircum\",\n    \"underscore\",\n    \"quoteleft\",\n    \"a\",\n    \"b\",\n    \"c\",\n    \"d\",\n    \"e\",\n    \"f\",\n    \"g\",\n    \"h\",\n    \"i\",\n    \"j\",\n    \"k\",\n    \"l\",\n    \"m\",\n    \"n\",\n    \"o\",\n    \"p\",\n    \"q\",\n    \"r\",\n    \"s\",\n    \"t\",\n    \"u\",\n    \"v\",\n    \"w\",\n    \"x\",\n    \"y\",\n    \"z\",\n    \"braceleft\",\n    \"bar\",\n    \"braceright\",\n    \"asciitilde\",\n    \"exclamdown\",\n    \"cent\",\n    \"sterling\",\n    \"fraction\",\n    \"yen\",\n    \"florin\",\n    \"section\",\n    \"currency\",\n    \"quotesingle\",\n    \"quotedblleft\",\n    \"guillemotleft\",\n    \"guilsinglleft\",\n    \"guilsinglright\",\n    \"fi\",\n    \"fl\",\n    \"endash\",\n    \"dagger\",\n    \"daggerdbl\",\n    \"periodcentered\",\n    \"paragraph\",\n    \"bullet\",\n    \"quotesinglbase\",\n    \"quotedblbase\",\n    \"quotedblright\",\n    \"guillemotright\",\n    \"ellipsis\",\n    \"perthousand\",\n    \"questiondown\",\n    \"grave\",\n    \"acute\",\n    \"circumflex\",\n    \"tilde\",\n    \"macron\",\n    \"breve\",\n    \"dotaccent\",\n    \"dieresis\",\n    \"ring\",\n    \"cedilla\",\n    \"hungarumlaut\",\n    \"ogonek\",\n    \"caron\",\n    \"emdash\",\n    \"AE\",\n    \"ordfeminine\",\n    \"Lslash\",\n    \"Oslash\",\n    \"OE\",\n    \"ordmasculine\",\n    \"ae\",\n    \"dotlessi\",\n    \"lslash\",\n    \"oslash\",\n    \"oe\",\n    \"germandbls\",\n    \"onesuperior\",\n    \"logicalnot\",\n    \"mu\",\n    \"trademark\",\n    \"Eth\",\n    \"onehalf\",\n    \"plusminus\",\n    \"Thorn\",\n    \"onequarter\",\n    \"divide\",\n    \"brokenbar\",\n    \"degree\",\n    \"thorn\",\n    \"threequarters\",\n    \"twosuperior\",\n    \"registered\",\n    \"minus\",\n    \"eth\",\n    \"multiply\",\n    \"threesuperior\",\n    \"copyright\",\n    \"Aacute\",\n    \"Acircumflex\",\n    \"Adieresis\",\n    \"Agrave\",\n    \"Aring\",\n    \"Atilde\",\n    \"Ccedilla\",\n    \"Eacute\",\n    \"Ecircumflex\",\n    \"Edieresis\",\n    \"Egrave\",\n    \"Iacute\",\n    \"Icircumflex\",\n    \"Idieresis\",\n    \"Igrave\",\n    \"Ntilde\",\n    \"Oacute\",\n    \"Ocircumflex\",\n    \"Odieresis\",\n    \"Ograve\",\n    \"Otilde\",\n    \"Scaron\",\n    \"Uacute\",\n    \"Ucircumflex\",\n    \"Udieresis\",\n    \"Ugrave\",\n    \"Yacute\",\n    \"Ydieresis\",\n    \"Zcaron\",\n    \"aacute\",\n    \"acircumflex\",\n    \"adieresis\",\n    \"agrave\",\n    \"aring\",\n    \"atilde\",\n    \"ccedilla\",\n    \"eacute\",\n    \"ecircumflex\",\n    \"edieresis\",\n    \"egrave\",\n    \"iacute\",\n    \"icircumflex\",\n    \"idieresis\",\n    \"igrave\",\n    \"ntilde\",\n    \"oacute\",\n    \"ocircumflex\",\n    \"odieresis\",\n    \"ograve\",\n    \"otilde\",\n    \"scaron\",\n    \"uacute\",\n    \"ucircumflex\",\n    \"udieresis\",\n    \"ugrave\",\n    \"yacute\",\n    \"ydieresis\",\n    \"zcaron\",\n    \"exclamsmall\",\n    \"Hungarumlautsmall\",\n    \"dollaroldstyle\",\n    \"dollarsuperior\",\n    \"ampersandsmall\",\n    \"Acutesmall\",\n    \"parenleftsuperior\",\n    \"parenrightsuperior\",\n    \"twodotenleader\",\n    \"onedotenleader\",\n    \"zerooldstyle\",\n    \"oneoldstyle\",\n    \"twooldstyle\",\n    \"threeoldstyle\",\n    \"fouroldstyle\",\n    \"fiveoldstyle\",\n    \"sixoldstyle\",\n    \"sevenoldstyle\",\n    \"eightoldstyle\",\n    \"nineoldstyle\",\n    \"commasuperior\",\n    \"threequartersemdash\",\n    \"periodsuperior\",\n    \"questionsmall\",\n    \"asuperior\",\n    \"bsuperior\",\n    \"centsuperior\",\n    \"dsuperior\",\n    \"esuperior\",\n    \"isuperior\",\n    \"lsuperior\",\n    \"msuperior\",\n    \"nsuperior\",\n    \"osuperior\",\n    \"rsuperior\",\n    \"ssuperior\",\n    \"tsuperior\",\n    \"ff\",\n    \"ffi\",\n    \"ffl\",\n    \"parenleftinferior\",\n    \"parenrightinferior\",\n    \"Circumflexsmall\",\n    \"hyphensuperior\",\n    \"Gravesmall\",\n    \"Asmall\",\n    \"Bsmall\",\n    \"Csmall\",\n    \"Dsmall\",\n    \"Esmall\",\n    \"Fsmall\",\n    \"Gsmall\",\n    \"Hsmall\",\n    \"Ismall\",\n    \"Jsmall\",\n    \"Ksmall\",\n    \"Lsmall\",\n    \"Msmall\",\n    \"Nsmall\",\n    \"Osmall\",\n    \"Psmall\",\n    \"Qsmall\",\n    \"Rsmall\",\n    \"Ssmall\",\n    \"Tsmall\",\n    \"Usmall\",\n    \"Vsmall\",\n    \"Wsmall\",\n    \"Xsmall\",\n    \"Ysmall\",\n    \"Zsmall\",\n    \"colonmonetary\",\n    \"onefitted\",\n    \"rupiah\",\n    \"Tildesmall\",\n    \"exclamdownsmall\",\n    \"centoldstyle\",\n    \"Lslashsmall\",\n    \"Scaronsmall\",\n    \"Zcaronsmall\",\n    \"Dieresissmall\",\n    \"Brevesmall\",\n    \"Caronsmall\",\n    \"Dotaccentsmall\",\n    \"Macronsmall\",\n    \"figuredash\",\n    \"hypheninferior\",\n    \"Ogoneksmall\",\n    \"Ringsmall\",\n    \"Cedillasmall\",\n    \"questiondownsmall\",\n    \"oneeighth\",\n    \"threeeighths\",\n    \"fiveeighths\",\n    \"seveneighths\",\n    \"onethird\",\n    \"twothirds\",\n    \"zerosuperior\",\n    \"foursuperior\",\n    \"fivesuperior\",\n    \"sixsuperior\",\n    \"sevensuperior\",\n    \"eightsuperior\",\n    \"ninesuperior\",\n    \"zeroinferior\",\n    \"oneinferior\",\n    \"twoinferior\",\n    \"threeinferior\",\n    \"fourinferior\",\n    \"fiveinferior\",\n    \"sixinferior\",\n    \"seveninferior\",\n    \"eightinferior\",\n    \"nineinferior\",\n    \"centinferior\",\n    \"dollarinferior\",\n    \"periodinferior\",\n    \"commainferior\",\n    \"Agravesmall\",\n    \"Aacutesmall\",\n    \"Acircumflexsmall\",\n    \"Atildesmall\",\n    \"Adieresissmall\",\n    \"Aringsmall\",\n    \"AEsmall\",\n    \"Ccedillasmall\",\n    \"Egravesmall\",\n    \"Eacutesmall\",\n    \"Ecircumflexsmall\",\n    \"Edieresissmall\",\n    \"Igravesmall\",\n    \"Iacutesmall\",\n    \"Icircumflexsmall\",\n    \"Idieresissmall\",\n    \"Ethsmall\",\n    \"Ntildesmall\",\n    \"Ogravesmall\",\n    \"Oacutesmall\",\n    \"Ocircumflexsmall\",\n    \"Otildesmall\",\n    \"Odieresissmall\",\n    \"OEsmall\",\n    \"Oslashsmall\",\n    \"Ugravesmall\",\n    \"Uacutesmall\",\n    \"Ucircumflexsmall\",\n    \"Udieresissmall\",\n    \"Yacutesmall\",\n    \"Thornsmall\",\n    \"Ydieresissmall\",\n    \"001.000\",\n    \"001.001\",\n    \"001.002\",\n    \"001.003\",\n    \"Black\",\n    \"Bold\",\n    \"Book\",\n    \"Light\",\n    \"Medium\",\n    \"Regular\",\n    \"Roman\",\n    \"Semibold\",\n];\n"
    },
    {
      "package": "ttf-parser@0.18.1",
      "sourcePath": "src/tables/name.rs",
      "sha256": "12ff8509c8fc14c12a244bc5b76ef43556d2d6800336e30d8ed9c96b9274bab8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "//! A [Naming Table](\n//! https://docs.microsoft.com/en-us/typography/opentype/spec/name) implementation.\n\n#[cfg(feature = \"std\")]\nuse std::string::String;\n#[cfg(feature = \"std\")]\nuse std::vec::Vec;\n\nuse crate::parser::{FromData, LazyArray16, Offset, Offset16, Stream};\nuse crate::Language;\n\n/// A list of [name ID](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids)'s.\npub mod name_id {\n    #![allow(missing_docs)]\n\n    pub const COPYRIGHT_NOTICE: u16 = 0;\n    pub const FAMILY: u16 = 1;\n    pub const SUBFAMILY: u16 = 2;\n    pub const UNIQUE_ID: u16 = 3;\n    pub const FULL_NAME: u16 = 4;\n    pub const VERSION: u16 = 5;\n    pub const POST_SCRIPT_NAME: u16 = 6;\n    pub const TRADEMARK: u16 = 7;\n    pub const MANUFACTURER: u16 = 8;\n    pub const DESIGNER: u16 = 9;\n    pub const DESCRIPTION: u16 = 10;\n    pub const VENDOR_URL: u16 = 11;\n    pub const DESIGNER_URL: u16 = 12;\n    pub const LICENSE: u16 = 13;\n    pub const LICENSE_URL: u16 = 14;\n    //        RESERVED                                  = 15\n    pub const TYPOGRAPHIC_FAMILY: u16 = 16;\n    pub const TYPOGRAPHIC_SUBFAMILY: u16 = 17;\n    pub const COMPATIBLE_FULL: u16 = 18;\n    pub const SAMPLE_TEXT: u16 = 19;\n    pub const POST_SCRIPT_CID: u16 = 20;\n    pub const WWS_FAMILY: u16 = 21;\n    pub const WWS_SUBFAMILY: u16 = 22;\n    pub const LIGHT_BACKGROUND_PALETTE: u16 = 23;\n    pub const DARK_BACKGROUND_PALETTE: u16 = 24;\n    pub const VARIATIONS_POST_SCRIPT_NAME_PREFIX: u16 = 25;\n}\n\n/// A [platform ID](https://docs.microsoft.com/en-us/typography/opentype/spec/name#platform-ids).\n#[allow(missing_docs)]\n#[derive(Clone, Copy, PartialEq, Eq, Debug)]\npub enum PlatformId {\n    Unicode,\n    Macintosh,\n    Iso,\n    Windows,\n    Custom,\n}\n\nimpl FromData for PlatformId {\n    const SIZE: usize = 2;\n\n    #[inline]\n    fn parse(data: &[u8]) -> Option<Self> {\n        match u16::parse(data)? {\n            0 => Some(PlatformId::Unicode),\n            1 => Some(PlatformId::Macintosh),\n            2 => Some(PlatformId::Iso),\n            3 => Some(PlatformId::Windows),\n            4 => Some(PlatformId::Custom),\n            _ => None,\n        }\n    }\n}\n\n#[inline]\nfn is_unicode_encoding(platform_id: PlatformId, encoding_id: u16) -> bool {\n    // https://docs.microsoft.com/en-us/typography/opentype/spec/name#windows-encoding-ids\n    const WINDOWS_SYMBOL_ENCODING_ID: u16 = 0;\n    const WINDOWS_UNICODE_BMP_ENCODING_ID: u16 = 1;\n\n    match platform_id {\n        PlatformId::Unicode => true,\n        PlatformId::Windows => matches!(\n            encoding_id,\n            WINDOWS_SYMBOL_ENCODING_ID | WINDOWS_UNICODE_BMP_ENCODING_ID\n        ),\n        _ => false,\n    }\n}\n\n#[derive(Clone, Copy)]\nstruct NameRecord {\n    platform_id: PlatformId,\n    encoding_id: u16,\n    language_id: u16,\n    name_id: u16,\n    length: u16,\n    offset: Offset16,\n}\n\nimpl FromData for NameRecord {\n    const SIZE: usize = 12;\n\n    #[inline]\n    fn parse(data: &[u8]) -> Option<Self> {\n        let mut s = Stream::new(data);\n        Some(NameRecord {\n            platform_id: s.read::<PlatformId>()?,\n            encoding_id: s.read::<u16>()?,\n            language_id: s.read::<u16>()?,\n            name_id: s.read::<u16>()?,\n            length: s.read::<u16>()?,\n            offset: s.read::<Offset16>()?,\n        })\n    }\n}\n\n/// A [Name Record](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-records).\n#[derive(Clone, Copy)]\npub struct Name<'a> {\n    /// A platform ID.\n    pub platform_id: PlatformId,\n    /// A platform-specific encoding ID.\n    pub encoding_id: u16,\n    /// A language ID.\n    pub language_id: u16,\n    /// A [Name ID](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids).\n    ///\n    /// A predefined list of ID's can be found in the [`name_id`](name_id/index.html) module.\n    pub name_id: u16,\n    /// A raw name data.\n    ///\n    /// Can be in any encoding. Can be empty.\n    pub name: &'a [u8],\n}\n\nimpl<'a> Name<'a> {\n    /// Returns the Name's data as a UTF-8 string.\n    ///\n    /// Only Unicode names are supported. And since they are stored as UTF-16BE,\n    /// we can't return `&str` and have to allocate a `String`.\n    ///\n    /// Supports:\n    /// - Unicode Platform ID\n    /// - Windows Platform ID + Symbol\n    /// - Windows Platform ID + Unicode BMP\n    #[cfg(feature = \"std\")]\n    #[inline(never)]\n    pub fn to_string(&self) -> Option<String> {\n        if self.is_unicode() {\n            self.name_from_utf16_be()\n        } else {\n            None\n        }\n    }\n\n    /// Checks that the current Name data has a Unicode encoding.\n    #[inline]\n    pub fn is_unicode(&self) -> bool {\n        is_unicode_encoding(self.platform_id, self.encoding_id)\n    }\n\n    #[cfg(feature = \"std\")]\n    #[inline(never)]\n    fn name_from_utf16_be(&self) -> Option<String> {\n        let mut name: Vec<u16> = Vec::new();\n        for c in LazyArray16::<u16>::new(self.name) {\n            name.push(c);\n        }\n\n        String::from_utf16(&name).ok()\n    }\n\n    /// Returns a Name language.\n    pub fn language(&self) -> Language {\n        if self.platform_id == PlatformId::Windows {\n            Language::windows_language(self.language_id)\n        } else if self.platform_id == PlatformId::Macintosh\n            && self.encoding_id == 0\n            && self.language_id == 0\n        {\n            Language::English_UnitedStates\n        } else {\n            Language::Unknown\n        }\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl<'a> core::fmt::Debug for Name<'a> {\n    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {\n        let name = self.to_string();\n        f.debug_struct(\"Name\")\n            .field(\"name\", &name.as_deref().unwrap_or(\"unsupported encoding\"))\n            .field(\"platform_id\", &self.platform_id)\n            .field(\"encoding_id\", &self.encoding_id)\n            .field(\"language_id\", &self.language_id)\n            .field(\"language\", &self.language())\n            .field(\"name_id\", &self.name_id)\n            .finish()\n    }\n}\n\n#[cfg(not(feature = \"std\"))]\nimpl<'a> core::fmt::Debug for Name<'a> {\n    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {\n        f.debug_struct(\"Name\")\n            .field(\"name\", &self.name)\n            .field(\"platform_id\", &self.platform_id)\n            .field(\"encoding_id\", &self.encoding_id)\n            .field(\"language_id\", &self.language_id)\n            .field(\"language\", &self.language())\n            .field(\"name_id\", &self.name_id)\n            .finish()\n    }\n}\n\n/// A list of face names.\n#[derive(Clone, Copy, Default)]\npub struct Names<'a> {\n    records: LazyArray16<'a, NameRecord>,\n    storage: &'a [u8],\n}\n\nimpl<'a> Names<'a> {\n    /// Returns a name at index.\n    pub fn get(&self, index: u16) -> Option<Name<'a>> {\n        let record = self.records.get(index)?;\n        let name_start = record.offset.to_usize();\n        let name_end = name_start + usize::from(record.length);\n        let name = self.storage.get(name_start..name_end)?;\n        Some(Name {\n            platform_id: record.platform_id,\n            encoding_id: record.encoding_id,\n            language_id: record.language_id,\n            name_id: record.name_id,\n            name,\n        })\n    }\n\n    /// Returns a number of name records.\n    pub fn len(&self) -> u16 {\n        self.records.len()\n    }\n\n    /// Checks if there are any name records.\n    pub fn is_empty(&self) -> bool {\n        self.records.is_empty()\n    }\n}\n\nimpl core::fmt::Debug for Names<'_> {\n    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {\n        write!(f, \"Names {{ ... }}\")\n    }\n}\n\nimpl<'a> IntoIterator for Names<'a> {\n    type Item = Name<'a>;\n    type IntoIter = NamesIter<'a>;\n\n    #[inline]\n    fn into_iter(self) -> Self::IntoIter {\n        NamesIter {\n            names: self,\n            index: 0,\n        }\n    }\n}\n\n/// An iterator over face names.\n#[derive(Clone, Copy)]\n#[allow(missing_debug_implementations)]\npub struct NamesIter<'a> {\n    names: Names<'a>,\n    index: u16,\n}\n\nimpl<'a> Iterator for NamesIter<'a> {\n    type Item = Name<'a>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.index < self.names.len() {\n            self.index += 1;\n            self.names.get(self.index - 1)\n        } else {\n            None\n        }\n    }\n\n    #[inline]\n    fn count(self) -> usize {\n        usize::from(self.names.len().saturating_sub(self.index))\n    }\n}\n\n/// A [Naming Table](\n/// https://docs.microsoft.com/en-us/typography/opentype/spec/name).\n#[derive(Clone, Copy, Default, Debug)]\npub struct Table<'a> {\n    /// A list of names.\n    pub names: Names<'a>,\n}\n\nimpl<'a> Table<'a> {\n    /// Parses a table from raw data.\n    pub fn parse(data: &'a [u8]) -> Option<Self> {\n        // https://docs.microsoft.com/en-us/typography/opentype/spec/name#naming-table-format-1\n        const LANG_TAG_RECORD_SIZE: u16 = 4;\n\n        let mut s = Stream::new(data);\n        let version = s.read::<u16>()?;\n        let count = s.read::<u16>()?;\n        let storage_offset = s.read::<Offset16>()?.to_usize();\n\n        if version == 0 {\n            // Do nothing.\n        } else if version == 1 {\n            let lang_tag_count = s.read::<u16>()?;\n            let lang_tag_len = lang_tag_count.checked_mul(LANG_TAG_RECORD_SIZE)?;\n            s.advance(usize::from(lang_tag_len)); // langTagRecords\n        } else {\n            // Unsupported version.\n            return None;\n        }\n\n        let records = s.read_array16::<NameRecord>(count)?;\n\n        if s.offset() < storage_offset {\n            s.advance(storage_offset - s.offset());\n        }\n\n        let storage = s.tail()?;\n\n        Some(Table {\n            names: Names { records, storage },\n        })\n    }\n}\n"
    },
    {
      "package": "ttf-parser@0.18.1",
      "sourcePath": "src/tables/post.rs",
      "sha256": "8736dfc782c57e17690b1aed11020e49709b4580f34e989b7263b4e9311648b8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "//! A [PostScript Table](\n//! https://docs.microsoft.com/en-us/typography/opentype/spec/post) implementation.\n\nuse crate::parser::{Fixed, LazyArray16, Stream};\n#[cfg(feature = \"glyph-names\")]\nuse crate::GlyphId;\nuse crate::LineMetrics;\n\nconst ITALIC_ANGLE_OFFSET: usize = 4;\nconst UNDERLINE_POSITION_OFFSET: usize = 8;\nconst UNDERLINE_THICKNESS_OFFSET: usize = 10;\nconst IS_FIXED_PITCH_OFFSET: usize = 12;\n\n// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6post.html\n/// A list of Macintosh glyph names.\n#[cfg(feature = \"glyph-names\")]\nconst MACINTOSH_NAMES: &[&str] = &[\n    \".notdef\",\n    \".null\",\n    \"nonmarkingreturn\",\n    \"space\",\n    \"exclam\",\n    \"quotedbl\",\n    \"numbersign\",\n    \"dollar\",\n    \"percent\",\n    \"ampersand\",\n    \"quotesingle\",\n    \"parenleft\",\n    \"parenright\",\n    \"asterisk\",\n    \"plus\",\n    \"comma\",\n    \"hyphen\",\n    \"period\",\n    \"slash\",\n    \"zero\",\n    \"one\",\n    \"two\",\n    \"three\",\n    \"four\",\n    \"five\",\n    \"six\",\n    \"seven\",\n    \"eight\",\n    \"nine\",\n    \"colon\",\n    \"semicolon\",\n    \"less\",\n    \"equal\",\n    \"greater\",\n    \"question\",\n    \"at\",\n    \"A\",\n    \"B\",\n    \"C\",\n    \"D\",\n    \"E\",\n    \"F\",\n    \"G\",\n    \"H\",\n    \"I\",\n    \"J\",\n    \"K\",\n    \"L\",\n    \"M\",\n    \"N\",\n    \"O\",\n    \"P\",\n    \"Q\",\n    \"R\",\n    \"S\",\n    \"T\",\n    \"U\",\n    \"V\",\n    \"W\",\n    \"X\",\n    \"Y\",\n    \"Z\",\n    \"bracketleft\",\n    \"backslash\",\n    \"bracketright\",\n    \"asciicircum\",\n    \"underscore\",\n    \"grave\",\n    \"a\",\n    \"b\",\n    \"c\",\n    \"d\",\n    \"e\",\n    \"f\",\n    \"g\",\n    \"h\",\n    \"i\",\n    \"j\",\n    \"k\",\n    \"l\",\n    \"m\",\n    \"n\",\n    \"o\",\n    \"p\",\n    \"q\",\n    \"r\",\n    \"s\",\n    \"t\",\n    \"u\",\n    \"v\",\n    \"w\",\n    \"x\",\n    \"y\",\n    \"z\",\n    \"braceleft\",\n    \"bar\",\n    \"braceright\",\n    \"asciitilde\",\n    \"Adieresis\",\n    \"Aring\",\n    \"Ccedilla\",\n    \"Eacute\",\n    \"Ntilde\",\n    \"Odieresis\",\n    \"Udieresis\",\n    \"aacute\",\n    \"agrave\",\n    \"acircumflex\",\n    \"adieresis\",\n    \"atilde\",\n    \"aring\",\n    \"ccedilla\",\n    \"eacute\",\n    \"egrave\",\n    \"ecircumflex\",\n    \"edieresis\",\n    \"iacute\",\n    \"igrave\",\n    \"icircumflex\",\n    \"idieresis\",\n    \"ntilde\",\n    \"oacute\",\n    \"ograve\",\n    \"ocircumflex\",\n    \"odieresis\",\n    \"otilde\",\n    \"uacute\",\n    \"ugrave\",\n    \"ucircumflex\",\n    \"udieresis\",\n    \"dagger\",\n    \"degree\",\n    \"cent\",\n    \"sterling\",\n    \"section\",\n    \"bullet\",\n    \"paragraph\",\n    \"germandbls\",\n    \"registered\",\n    \"copyright\",\n    \"trademark\",\n    \"acute\",\n    \"dieresis\",\n    \"notequal\",\n    \"AE\",\n    \"Oslash\",\n    \"infinity\",\n    \"plusminus\",\n    \"lessequal\",\n    \"greaterequal\",\n    \"yen\",\n    \"mu\",\n    \"partialdiff\",\n    \"summation\",\n    \"product\",\n    \"pi\",\n    \"integral\",\n    \"ordfeminine\",\n    \"ordmasculine\",\n    \"Omega\",\n    \"ae\",\n    \"oslash\",\n    \"questiondown\",\n    \"exclamdown\",\n    \"logicalnot\",\n    \"radical\",\n    \"florin\",\n    \"approxequal\",\n    \"Delta\",\n    \"guillemotleft\",\n    \"guillemotright\",\n    \"ellipsis\",\n    \"nonbreakingspace\",\n    \"Agrave\",\n    \"Atilde\",\n    \"Otilde\",\n    \"OE\",\n    \"oe\",\n    \"endash\",\n    \"emdash\",\n    \"quotedblleft\",\n    \"quotedblright\",\n    \"quoteleft\",\n    \"quoteright\",\n    \"divide\",\n    \"lozenge\",\n    \"ydieresis\",\n    \"Ydieresis\",\n    \"fraction\",\n    \"currency\",\n    \"guilsinglleft\",\n    \"guilsinglright\",\n    \"fi\",\n    \"fl\",\n    \"daggerdbl\",\n    \"periodcentered\",\n    \"quotesinglbase\",\n    \"quotedblbase\",\n    \"perthousand\",\n    \"Acircumflex\",\n    \"Ecircumflex\",\n    \"Aacute\",\n    \"Edieresis\",\n    \"Egrave\",\n    \"Iacute\",\n    \"Icircumflex\",\n    \"Idieresis\",\n    \"Igrave\",\n    \"Oacute\",\n    \"Ocircumflex\",\n    \"apple\",\n    \"Ograve\",\n    \"Uacute\",\n    \"Ucircumflex\",\n    \"Ugrave\",\n    \"dotlessi\",\n    \"circumflex\",\n    \"tilde\",\n    \"macron\",\n    \"breve\",\n    \"dotaccent\",\n    \"ring\",\n    \"cedilla\",\n    \"hungarumlaut\",\n    \"ogonek\",\n    \"caron\",\n    \"Lslash\",\n    \"lslash\",\n    \"Scaron\",\n    \"scaron\",\n    \"Zcaron\",\n    \"zcaron\",\n    \"brokenbar\",\n    \"Eth\",\n    \"eth\",\n    \"Yacute\",\n    \"yacute\",\n    \"Thorn\",\n    \"thorn\",\n    \"minus\",\n    \"multiply\",\n    \"onesuperior\",\n    \"twosuperior\",\n    \"threesuperior\",\n    \"onehalf\",\n    \"onequarter\",\n    \"threequarters\",\n    \"franc\",\n    \"Gbreve\",\n    \"gbreve\",\n    \"Idotaccent\",\n    \"Scedilla\",\n    \"scedilla\",\n    \"Cacute\",\n    \"cacute\",\n    \"Ccaron\",\n    \"ccaron\",\n    \"dcroat\",\n];\n\n/// An iterator over glyph names.\n///\n/// The `post` table doesn't provide the glyph names count,\n/// so we have to simply iterate over all of them to find it out.\n#[derive(Clone, Copy, Default)]\npub struct Names<'a> {\n    data: &'a [u8],\n    offset: usize,\n}\n\nimpl core::fmt::Debug for Names<'_> {\n    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {\n        write!(f, \"Names {{ ... }}\")\n    }\n}\n\nimpl<'a> Iterator for Names<'a> {\n    type Item = &'a str;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        // Glyph names are stored as Pascal Strings.\n        // Meaning u8 (len) + [u8] (data).\n\n        if self.offset >= self.data.len() {\n            return None;\n        }\n\n        let len = self.data[self.offset];\n        self.offset += 1;\n\n        // An empty name is an error.\n        if len == 0 {\n            return None;\n        }\n\n        let name = self.data.get(self.offset..self.offset + usize::from(len))?;\n        self.offset += usize::from(len);\n        core::str::from_utf8(name).ok()\n    }\n}\n\n/// A [PostScript Table](https://docs.microsoft.com/en-us/typography/opentype/spec/post).\n#[derive(Clone, Copy, Debug)]\npub struct Table<'a> {\n    /// Italic angle in counter-clockwise degrees from the vertical.\n    pub italic_angle: f32,\n    /// Underline metrics.\n    pub underline_metrics: LineMetrics,\n    /// Flag that indicates that the font is monospaced.\n    pub is_monospaced: bool,\n\n    glyph_indexes: LazyArray16<'a, u16>,\n    names_data: &'a [u8],\n}\n\nimpl<'a> Table<'a> {\n    /// Parses a table from raw data.\n    pub fn parse(data: &'a [u8]) -> Option<Self> {\n        // Do not check the exact length, because some fonts include\n        // padding in table's length in table records, which is incorrect.\n        if data.len() < 32 {\n            return None;\n        }\n\n        let version = Stream::new(data).read::<u32>()?;\n        if !(version == 0x00010000\n            || version == 0x00020000\n            || version == 0x00025000\n            || version == 0x00030000\n            || version == 0x00040000)\n        {\n            return None;\n        }\n\n        let italic_angle = Stream::read_at::<Fixed>(data, ITALIC_ANGLE_OFFSET)?.0;\n\n        let underline_metrics = LineMetrics {\n            position: Stream::read_at::<i16>(data, UNDERLINE_POSITION_OFFSET)?,\n            thickness: Stream::read_at::<i16>(data, UNDERLINE_THICKNESS_OFFSET)?,\n        };\n\n        let is_monospaced = Stream::read_at::<u32>(data, IS_FIXED_PITCH_OFFSET)? != 0;\n\n        let mut names_data: &[u8] = &[];\n        let mut glyph_indexes = LazyArray16::default();\n        // Only version 2.0 of the table has data at the end.\n        if version == 0x00020000 {\n            let mut s = Stream::new_at(data, 32)?;\n            let indexes_count = s.read::<u16>()?;\n            glyph_indexes = s.read_array16::<u16>(indexes_count)?;\n            names_data = s.tail()?;\n        }\n\n        Some(Table {\n            italic_angle,\n            underline_metrics,\n            is_monospaced,\n            names_data,\n            glyph_indexes,\n        })\n    }\n\n    /// Returns a glyph name by ID.\n    #[cfg(feature = \"glyph-names\")]\n    pub fn glyph_name(&self, glyph_id: GlyphId) -> Option<&'a str> {\n        let mut index = self.glyph_indexes.get(glyph_id.0)?;\n\n        // 'If the name index is between 0 and 257, treat the name index\n        // as a glyph index in the Macintosh standard order.'\n        if usize::from(index) < MACINTOSH_NAMES.len() {\n            Some(MACINTOSH_NAMES[usize::from(index)])\n        } else {\n            // 'If the name index is between 258 and 65535, then subtract 258 and use that\n            // to index into the list of Pascal strings at the end of the table.'\n            index -= MACINTOSH_NAMES.len() as u16;\n            self.names().nth(usize::from(index))\n        }\n    }\n\n    /// Returns a glyph ID by a name.\n    #[cfg(feature = \"glyph-names\")]\n    pub fn glyph_index_by_name(&self, name: &str) -> Option<GlyphId> {\n        let id = if let Some(index) = MACINTOSH_NAMES.iter().position(|n| *n == name) {\n            self.glyph_indexes\n                .into_iter()\n                .position(|i| usize::from(i) == index)?\n        } else {\n            let mut index = self.names().position(|n| n == name)?;\n            index += MACINTOSH_NAMES.len();\n            self.glyph_indexes\n                .into_iter()\n                .position(|i| usize::from(i) == index)?\n        };\n\n        Some(GlyphId(id as u16))\n    }\n\n    /// Returns an iterator over glyph names.\n    ///\n    /// Default/predefined names are not included. Just the one in the font file.\n    pub fn names(&self) -> Names<'a> {\n        Names {\n            data: self.names_data,\n            offset: 0,\n        }\n    }\n}\n"
    },
    {
      "package": "ttf-parser@0.19.2",
      "sourcePath": "README.md",
      "sha256": "827bef54227d335ccbc62b1ca799ada622dd0584c57a41a17175dd195d2fe11a",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "## ttf-parser\n![Build Status](https://github.com/RazrFalcon/ttf-parser/workflows/Rust/badge.svg)\n[![Crates.io](https://img.shields.io/crates/v/ttf-parser.svg)](https://crates.io/crates/ttf-parser)\n[![Documentation](https://docs.rs/ttf-parser/badge.svg)](https://docs.rs/ttf-parser)\n[![Rust 1.42+](https://img.shields.io/badge/rust-1.42+-orange.svg)](https://www.rust-lang.org)\n![](https://img.shields.io/badge/unsafe-forbidden-brightgreen.svg)\n\nA high-level, safe, zero-allocation TrueType font parser.\n\nSupports [TrueType](https://docs.microsoft.com/en-us/typography/truetype/),\n[OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/)\nand [AAT](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html)\nfonts.\n\nCan be used as Rust and as C library.\n\n### Features\n\n- A high-level API for most common properties, hiding all parsing and data resolving logic.\n- A low-level, but safe API to access TrueType tables data.\n- Highly configurable. You can disable most of the features, reducing binary size.\n  You can also parse TrueType tables separately, without loading the whole font/face.\n- Zero heap allocations.\n- Zero unsafe.\n- Zero dependencies.\n- `no_std`/WASM compatible.\n- A basic [C API](./c-api).\n- Fast.\n- Stateless. All parsing methods are immutable.\n- Simple and maintainable code (no magic numbers).\n\n### Safety\n\n- The library must not panic. Any panic considered as a critical bug and should be reported.\n- The library forbids unsafe code.\n- No heap allocations, so crash due to OOM is not possible.\n- All recursive methods have a depth limit.\n- Technically, should use less than 64KiB of stack in the worst case scenario.\n- Most of arithmetic operations are checked.\n- Most of numeric casts are checked.\n\n### Alternatives\n\nIt's very hard to compare different libraries, so we are using table-based comparison.\nThere are roughly three types of TrueType tables:\n\n- A table with a list of properties (like `head`, `OS/2`, etc.).<br/>\n  If a library tries to parse it at all then we mark it as supported.\n- A table that contains a single type of data (`glyf`, `CFF` (kinda), `hmtx`, etc.).<br/>\n  Can only be supported or not.\n- A table that contains multiple subtables (`cmap`, `kern`, `GPOS`, etc.).<br/>\n  Can be partially supported and we note which subtables are actually supported.\n\n| Feature/Library   | ttf-parser             | FreeType            | stb_truetype                   |\n| ----------------- | :--------------------: | :-----------------: | :----------------------------: |\n| Memory safe       | ✓                      |                     |                                |\n| Thread safe       | ✓                      |                     | ~ (mostly reentrant)           |\n| Zero allocation   | ✓                      |                     |                                |\n| Variable fonts    | ✓                      | ✓                   |                                |\n| Rendering         | -<sup>1</sup>          | ✓                   | ~ (very primitive)             |\n| `ankr` table      | ✓                      |                     |                                |\n| `avar` table      | ✓                      | ✓                   |                                |\n| `bdat` table      | ~ (no 4)               | ✓                   |                                |\n| `bloc` table      | ✓                      | ✓                   |                                |\n| `CBDT` table      | ~ (no 8, 9)            | ✓                   |                                |\n| `CBLC` table      | ✓                      | ✓                   |                                |\n| `COLR` table      |                        | ✓                   |                                |\n| `CPAL` table      |                        | ✓                   |                                |\n| `CFF `&nbsp;table | ✓                      | ✓                   | ~ (no `seac` support)          |\n| `CFF2` table      | ✓                      | ✓                   |                                |\n| `cmap` table      | ~ (no 8)               | ✓                   | ~ (no 2,8,10,14; Unicode-only) |\n| `EBDT` table      | ~ (no 8, 9)            | ✓                   |                                |\n| `EBLC` table      | ✓                      | ✓                   |                                |\n| `feat` table      | ✓                      |                     |                                |\n| `fvar` table      | ✓                      | ✓                   |                                |\n| `gasp` table      |                        | ✓                   |                                |\n| `GDEF` table      | ~                      |                     |                                |\n| `glyf` table      | ~<sup>2</sup>          | ✓                   | ~<sup>2</sup>                  |\n| `GPOS` table      | ✓                      |                     | ~ (only 2)                     |\n| `GSUB` table      | ✓                      |                     |                                |\n| `gvar` table      | ✓                      | ✓                   |                                |\n| `head` table      | ✓                      | ✓                   | ✓                              |\n| `hhea` table      | ✓                      | ✓                   | ✓                              |\n| `hmtx` table      | ✓                      | ✓                   | ✓                              |\n| `HVAR` table      | ✓                      | ✓                   |                                |\n| `kern` table      | ✓                      | ~ (only 0)          | ~ (only 0)                     |\n| `kerx` table      | ✓                      |                     |                                |\n| `MATH` table      | ✓                      |                     |                                |\n| `maxp` table      | ✓                      | ✓                   | ✓                              |\n| `morx` table      | ✓                      |                     |                                |\n| `MVAR` table      | ✓                      | ✓                   |                                |\n| `name` table      | ✓                      | ✓                   |                                |\n| `OS/2` table      | ✓                      | ✓                   |                                |\n| `post` table      | ✓                      | ✓                   |                                |\n| `sbix` table      | ~ (PNG only)           | ~ (PNG only)        |                                |\n| `SVG `&nbsp;table | ✓                      | ✓                   | ✓                              |\n| `trak` table      | ✓                      |                     |                                |\n| `vhea` table      | ✓                      | ✓                   |                                |\n| `vmtx` table      | ✓                      | ✓                   |                                |\n| `VORG` table      | ✓                      | ✓                   |                                |\n| `VVAR` table      | ✓                      | ✓                   |                                |\n| Language          | Rust + C API           | C                   | C                              |\n| Tested version    | 0.17.0                 | 2.12.0              | 1.24                           |\n| License           | MIT / Apache-2.0       | FTL / GPLv2         | public domain                  |\n\nLegend:\n\n- ✓ - supported\n- ~ - partial\n- *nothing* - not supported\n\nNotes:\n\n1. While `ttf-parser` doesn't support rendering by itself,\n   there are multiple rendering libraries on top of it:\n   [rusttype](https://gitlab.redox-os.org/redox-os/rusttype),\n   [ab-glyph](https://github.com/alexheretic/ab-glyph)\n   and [fontdue](https://github.com/mooman219/fontdue).\n2. Matching points are not supported.\n\n### Performance\n\nTrueType fonts designed for fast querying, so most of the methods are very fast.\nThe main exception is glyph outlining. Glyphs can be stored using two different methods:\nusing [Glyph Data Format](https://docs.microsoft.com/en-us/typography/opentype/spec/glyf)\nand [Compact Font Format](http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5176.CFF.pdf) (pdf).\nThe first one is fairly simple which makes it faster to process.\nThe second one is basically a tiny language with a stack-based VM, which makes it way harder to process.\n\nThe [benchmark](./benches/outline/) tests how long it takes to outline all glyphs in a font.\n\nx86 (AMD 3700X)\n\n| Table/Library | ttf-parser     | FreeType   | stb_truetype   |\n| ------------- | -------------: | ---------: | -------------: |\n| `glyf`        |   `0.901 ms`   | `1.171 ms` | **`0.675 ms`** |\n| `gvar`        | **`2.972 ms`** | `4.132 ms` |              - |\n| `CFF`         | **`1.197 ms`** | `5.647 ms` |   `2.813 ms`   |\n| `CFF2`        | **`1.968 ms`** | `6.392 ms` |              - |\n\nARM (Apple M1)\n\n| Table/Library | ttf-parser     | FreeType   | stb_truetype   |\n| ------------- | -------------: | ---------: | -------------: |\n| `glyf`        | **`0.550 ms`** | `0.854 ms` |   `0.703 ms`   |\n| `gvar`        | **`2.270 ms`** | `4.594 ms` |              - |\n| `CFF`         | **`1.054 ms`** | `5.223 ms` |   `3.262 ms`   |\n| `CFF2`        | **`1.765 ms`** | `5.995 ms` |              - |\n\n**Note:** FreeType is surprisingly slow, so I'm worried that I've messed something up.\n\nAnd here are some methods benchmarks:\n\n```text\ntest outline_glyph_276_from_cff2 ... bench:         867 ns/iter (+/- 15)\ntest from_data_otf_cff           ... bench:         968 ns/iter (+/- 13)\ntest from_data_otf_cff2          ... bench:         887 ns/iter (+/- 25)\ntest outline_glyph_276_from_cff  ... bench:         678 ns/iter (+/- 41)\ntest outline_glyph_276_from_glyf ... bench:         649 ns/iter (+/- 11)\ntest outline_glyph_8_from_cff2   ... bench:         534 ns/iter (+/- 14)\ntest from_data_ttf               ... bench:         467 ns/iter (+/- 11)\ntest glyph_name_post_276         ... bench:         223 ns/iter (+/- 5)\ntest outline_glyph_8_from_cff    ... bench:         315 ns/iter (+/- 13)\ntest outline_glyph_8_from_glyf   ... bench:         291 ns/iter (+/- 5)\ntest family_name                 ... bench:         183 ns/iter (+/- 102)\ntest glyph_name_cff_276          ... bench:          62 ns/iter (+/- 1)\ntest glyph_index_u41             ... bench:          16 ns/iter (+/- 0)\ntest glyph_name_cff_8            ... bench:           5 ns/iter (+/- 0)\ntest glyph_name_post_8           ... bench:           2 ns/iter (+/- 0)\ntest subscript_metrics           ... bench:           2 ns/iter (+/- 0)\ntest glyph_hor_advance           ... bench:           2 ns/iter (+/- 0)\ntest glyph_hor_side_bearing      ... bench:           2 ns/iter (+/- 0)\ntest glyph_name_8                ... bench:           1 ns/iter (+/- 0)\ntest ascender                    ... bench:           1 ns/iter (+/- 0)\ntest underline_metrics           ... bench:           1 ns/iter (+/- 0)\ntest strikeout_metrics           ... bench:           1 ns/iter (+/- 0)\ntest x_height                    ... bench:           1 ns/iter (+/- 0)\ntest units_per_em                ... bench:         0.5 ns/iter (+/- 0)\ntest width                       ... bench:         0.2 ns/iter (+/- 0)\n```\n\n### License\n\nLicensed under either of\n\n- Apache License, Version 2.0\n  ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license\n  ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "ttf-parser@0.19.2",
      "sourcePath": "src/tables/cff/std_names.rs",
      "sha256": "28f192e64551773c97d0457ddabc774cfabe535585a2ef65f37ca48022221923",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "pub const STANDARD_NAMES: &[&str] = &[\n    \".notdef\",\n    \"space\",\n    \"exclam\",\n    \"quotedbl\",\n    \"numbersign\",\n    \"dollar\",\n    \"percent\",\n    \"ampersand\",\n    \"quoteright\",\n    \"parenleft\",\n    \"parenright\",\n    \"asterisk\",\n    \"plus\",\n    \"comma\",\n    \"hyphen\",\n    \"period\",\n    \"slash\",\n    \"zero\",\n    \"one\",\n    \"two\",\n    \"three\",\n    \"four\",\n    \"five\",\n    \"six\",\n    \"seven\",\n    \"eight\",\n    \"nine\",\n    \"colon\",\n    \"semicolon\",\n    \"less\",\n    \"equal\",\n    \"greater\",\n    \"question\",\n    \"at\",\n    \"A\",\n    \"B\",\n    \"C\",\n    \"D\",\n    \"E\",\n    \"F\",\n    \"G\",\n    \"H\",\n    \"I\",\n    \"J\",\n    \"K\",\n    \"L\",\n    \"M\",\n    \"N\",\n    \"O\",\n    \"P\",\n    \"Q\",\n    \"R\",\n    \"S\",\n    \"T\",\n    \"U\",\n    \"V\",\n    \"W\",\n    \"X\",\n    \"Y\",\n    \"Z\",\n    \"bracketleft\",\n    \"backslash\",\n    \"bracketright\",\n    \"asciicircum\",\n    \"underscore\",\n    \"quoteleft\",\n    \"a\",\n    \"b\",\n    \"c\",\n    \"d\",\n    \"e\",\n    \"f\",\n    \"g\",\n    \"h\",\n    \"i\",\n    \"j\",\n    \"k\",\n    \"l\",\n    \"m\",\n    \"n\",\n    \"o\",\n    \"p\",\n    \"q\",\n    \"r\",\n    \"s\",\n    \"t\",\n    \"u\",\n    \"v\",\n    \"w\",\n    \"x\",\n    \"y\",\n    \"z\",\n    \"braceleft\",\n    \"bar\",\n    \"braceright\",\n    \"asciitilde\",\n    \"exclamdown\",\n    \"cent\",\n    \"sterling\",\n    \"fraction\",\n    \"yen\",\n    \"florin\",\n    \"section\",\n    \"currency\",\n    \"quotesingle\",\n    \"quotedblleft\",\n    \"guillemotleft\",\n    \"guilsinglleft\",\n    \"guilsinglright\",\n    \"fi\",\n    \"fl\",\n    \"endash\",\n    \"dagger\",\n    \"daggerdbl\",\n    \"periodcentered\",\n    \"paragraph\",\n    \"bullet\",\n    \"quotesinglbase\",\n    \"quotedblbase\",\n    \"quotedblright\",\n    \"guillemotright\",\n    \"ellipsis\",\n    \"perthousand\",\n    \"questiondown\",\n    \"grave\",\n    \"acute\",\n    \"circumflex\",\n    \"tilde\",\n    \"macron\",\n    \"breve\",\n    \"dotaccent\",\n    \"dieresis\",\n    \"ring\",\n    \"cedilla\",\n    \"hungarumlaut\",\n    \"ogonek\",\n    \"caron\",\n    \"emdash\",\n    \"AE\",\n    \"ordfeminine\",\n    \"Lslash\",\n    \"Oslash\",\n    \"OE\",\n    \"ordmasculine\",\n    \"ae\",\n    \"dotlessi\",\n    \"lslash\",\n    \"oslash\",\n    \"oe\",\n    \"germandbls\",\n    \"onesuperior\",\n    \"logicalnot\",\n    \"mu\",\n    \"trademark\",\n    \"Eth\",\n    \"onehalf\",\n    \"plusminus\",\n    \"Thorn\",\n    \"onequarter\",\n    \"divide\",\n    \"brokenbar\",\n    \"degree\",\n    \"thorn\",\n    \"threequarters\",\n    \"twosuperior\",\n    \"registered\",\n    \"minus\",\n    \"eth\",\n    \"multiply\",\n    \"threesuperior\",\n    \"copyright\",\n    \"Aacute\",\n    \"Acircumflex\",\n    \"Adieresis\",\n    \"Agrave\",\n    \"Aring\",\n    \"Atilde\",\n    \"Ccedilla\",\n    \"Eacute\",\n    \"Ecircumflex\",\n    \"Edieresis\",\n    \"Egrave\",\n    \"Iacute\",\n    \"Icircumflex\",\n    \"Idieresis\",\n    \"Igrave\",\n    \"Ntilde\",\n    \"Oacute\",\n    \"Ocircumflex\",\n    \"Odieresis\",\n    \"Ograve\",\n    \"Otilde\",\n    \"Scaron\",\n    \"Uacute\",\n    \"Ucircumflex\",\n    \"Udieresis\",\n    \"Ugrave\",\n    \"Yacute\",\n    \"Ydieresis\",\n    \"Zcaron\",\n    \"aacute\",\n    \"acircumflex\",\n    \"adieresis\",\n    \"agrave\",\n    \"aring\",\n    \"atilde\",\n    \"ccedilla\",\n    \"eacute\",\n    \"ecircumflex\",\n    \"edieresis\",\n    \"egrave\",\n    \"iacute\",\n    \"icircumflex\",\n    \"idieresis\",\n    \"igrave\",\n    \"ntilde\",\n    \"oacute\",\n    \"ocircumflex\",\n    \"odieresis\",\n    \"ograve\",\n    \"otilde\",\n    \"scaron\",\n    \"uacute\",\n    \"ucircumflex\",\n    \"udieresis\",\n    \"ugrave\",\n    \"yacute\",\n    \"ydieresis\",\n    \"zcaron\",\n    \"exclamsmall\",\n    \"Hungarumlautsmall\",\n    \"dollaroldstyle\",\n    \"dollarsuperior\",\n    \"ampersandsmall\",\n    \"Acutesmall\",\n    \"parenleftsuperior\",\n    \"parenrightsuperior\",\n    \"twodotenleader\",\n    \"onedotenleader\",\n    \"zerooldstyle\",\n    \"oneoldstyle\",\n    \"twooldstyle\",\n    \"threeoldstyle\",\n    \"fouroldstyle\",\n    \"fiveoldstyle\",\n    \"sixoldstyle\",\n    \"sevenoldstyle\",\n    \"eightoldstyle\",\n    \"nineoldstyle\",\n    \"commasuperior\",\n    \"threequartersemdash\",\n    \"periodsuperior\",\n    \"questionsmall\",\n    \"asuperior\",\n    \"bsuperior\",\n    \"centsuperior\",\n    \"dsuperior\",\n    \"esuperior\",\n    \"isuperior\",\n    \"lsuperior\",\n    \"msuperior\",\n    \"nsuperior\",\n    \"osuperior\",\n    \"rsuperior\",\n    \"ssuperior\",\n    \"tsuperior\",\n    \"ff\",\n    \"ffi\",\n    \"ffl\",\n    \"parenleftinferior\",\n    \"parenrightinferior\",\n    \"Circumflexsmall\",\n    \"hyphensuperior\",\n    \"Gravesmall\",\n    \"Asmall\",\n    \"Bsmall\",\n    \"Csmall\",\n    \"Dsmall\",\n    \"Esmall\",\n    \"Fsmall\",\n    \"Gsmall\",\n    \"Hsmall\",\n    \"Ismall\",\n    \"Jsmall\",\n    \"Ksmall\",\n    \"Lsmall\",\n    \"Msmall\",\n    \"Nsmall\",\n    \"Osmall\",\n    \"Psmall\",\n    \"Qsmall\",\n    \"Rsmall\",\n    \"Ssmall\",\n    \"Tsmall\",\n    \"Usmall\",\n    \"Vsmall\",\n    \"Wsmall\",\n    \"Xsmall\",\n    \"Ysmall\",\n    \"Zsmall\",\n    \"colonmonetary\",\n    \"onefitted\",\n    \"rupiah\",\n    \"Tildesmall\",\n    \"exclamdownsmall\",\n    \"centoldstyle\",\n    \"Lslashsmall\",\n    \"Scaronsmall\",\n    \"Zcaronsmall\",\n    \"Dieresissmall\",\n    \"Brevesmall\",\n    \"Caronsmall\",\n    \"Dotaccentsmall\",\n    \"Macronsmall\",\n    \"figuredash\",\n    \"hypheninferior\",\n    \"Ogoneksmall\",\n    \"Ringsmall\",\n    \"Cedillasmall\",\n    \"questiondownsmall\",\n    \"oneeighth\",\n    \"threeeighths\",\n    \"fiveeighths\",\n    \"seveneighths\",\n    \"onethird\",\n    \"twothirds\",\n    \"zerosuperior\",\n    \"foursuperior\",\n    \"fivesuperior\",\n    \"sixsuperior\",\n    \"sevensuperior\",\n    \"eightsuperior\",\n    \"ninesuperior\",\n    \"zeroinferior\",\n    \"oneinferior\",\n    \"twoinferior\",\n    \"threeinferior\",\n    \"fourinferior\",\n    \"fiveinferior\",\n    \"sixinferior\",\n    \"seveninferior\",\n    \"eightinferior\",\n    \"nineinferior\",\n    \"centinferior\",\n    \"dollarinferior\",\n    \"periodinferior\",\n    \"commainferior\",\n    \"Agravesmall\",\n    \"Aacutesmall\",\n    \"Acircumflexsmall\",\n    \"Atildesmall\",\n    \"Adieresissmall\",\n    \"Aringsmall\",\n    \"AEsmall\",\n    \"Ccedillasmall\",\n    \"Egravesmall\",\n    \"Eacutesmall\",\n    \"Ecircumflexsmall\",\n    \"Edieresissmall\",\n    \"Igravesmall\",\n    \"Iacutesmall\",\n    \"Icircumflexsmall\",\n    \"Idieresissmall\",\n    \"Ethsmall\",\n    \"Ntildesmall\",\n    \"Ogravesmall\",\n    \"Oacutesmall\",\n    \"Ocircumflexsmall\",\n    \"Otildesmall\",\n    \"Odieresissmall\",\n    \"OEsmall\",\n    \"Oslashsmall\",\n    \"Ugravesmall\",\n    \"Uacutesmall\",\n    \"Ucircumflexsmall\",\n    \"Udieresissmall\",\n    \"Yacutesmall\",\n    \"Thornsmall\",\n    \"Ydieresissmall\",\n    \"001.000\",\n    \"001.001\",\n    \"001.002\",\n    \"001.003\",\n    \"Black\",\n    \"Bold\",\n    \"Book\",\n    \"Light\",\n    \"Medium\",\n    \"Regular\",\n    \"Roman\",\n    \"Semibold\",\n];\n"
    },
    {
      "package": "ttf-parser@0.19.2",
      "sourcePath": "src/tables/name.rs",
      "sha256": "12ff8509c8fc14c12a244bc5b76ef43556d2d6800336e30d8ed9c96b9274bab8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "//! A [Naming Table](\n//! https://docs.microsoft.com/en-us/typography/opentype/spec/name) implementation.\n\n#[cfg(feature = \"std\")]\nuse std::string::String;\n#[cfg(feature = \"std\")]\nuse std::vec::Vec;\n\nuse crate::parser::{FromData, LazyArray16, Offset, Offset16, Stream};\nuse crate::Language;\n\n/// A list of [name ID](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids)'s.\npub mod name_id {\n    #![allow(missing_docs)]\n\n    pub const COPYRIGHT_NOTICE: u16 = 0;\n    pub const FAMILY: u16 = 1;\n    pub const SUBFAMILY: u16 = 2;\n    pub const UNIQUE_ID: u16 = 3;\n    pub const FULL_NAME: u16 = 4;\n    pub const VERSION: u16 = 5;\n    pub const POST_SCRIPT_NAME: u16 = 6;\n    pub const TRADEMARK: u16 = 7;\n    pub const MANUFACTURER: u16 = 8;\n    pub const DESIGNER: u16 = 9;\n    pub const DESCRIPTION: u16 = 10;\n    pub const VENDOR_URL: u16 = 11;\n    pub const DESIGNER_URL: u16 = 12;\n    pub const LICENSE: u16 = 13;\n    pub const LICENSE_URL: u16 = 14;\n    //        RESERVED                                  = 15\n    pub const TYPOGRAPHIC_FAMILY: u16 = 16;\n    pub const TYPOGRAPHIC_SUBFAMILY: u16 = 17;\n    pub const COMPATIBLE_FULL: u16 = 18;\n    pub const SAMPLE_TEXT: u16 = 19;\n    pub const POST_SCRIPT_CID: u16 = 20;\n    pub const WWS_FAMILY: u16 = 21;\n    pub const WWS_SUBFAMILY: u16 = 22;\n    pub const LIGHT_BACKGROUND_PALETTE: u16 = 23;\n    pub const DARK_BACKGROUND_PALETTE: u16 = 24;\n    pub const VARIATIONS_POST_SCRIPT_NAME_PREFIX: u16 = 25;\n}\n\n/// A [platform ID](https://docs.microsoft.com/en-us/typography/opentype/spec/name#platform-ids).\n#[allow(missing_docs)]\n#[derive(Clone, Copy, PartialEq, Eq, Debug)]\npub enum PlatformId {\n    Unicode,\n    Macintosh,\n    Iso,\n    Windows,\n    Custom,\n}\n\nimpl FromData for PlatformId {\n    const SIZE: usize = 2;\n\n    #[inline]\n    fn parse(data: &[u8]) -> Option<Self> {\n        match u16::parse(data)? {\n            0 => Some(PlatformId::Unicode),\n            1 => Some(PlatformId::Macintosh),\n            2 => Some(PlatformId::Iso),\n            3 => Some(PlatformId::Windows),\n            4 => Some(PlatformId::Custom),\n            _ => None,\n        }\n    }\n}\n\n#[inline]\nfn is_unicode_encoding(platform_id: PlatformId, encoding_id: u16) -> bool {\n    // https://docs.microsoft.com/en-us/typography/opentype/spec/name#windows-encoding-ids\n    const WINDOWS_SYMBOL_ENCODING_ID: u16 = 0;\n    const WINDOWS_UNICODE_BMP_ENCODING_ID: u16 = 1;\n\n    match platform_id {\n        PlatformId::Unicode => true,\n        PlatformId::Windows => matches!(\n            encoding_id,\n            WINDOWS_SYMBOL_ENCODING_ID | WINDOWS_UNICODE_BMP_ENCODING_ID\n        ),\n        _ => false,\n    }\n}\n\n#[derive(Clone, Copy)]\nstruct NameRecord {\n    platform_id: PlatformId,\n    encoding_id: u16,\n    language_id: u16,\n    name_id: u16,\n    length: u16,\n    offset: Offset16,\n}\n\nimpl FromData for NameRecord {\n    const SIZE: usize = 12;\n\n    #[inline]\n    fn parse(data: &[u8]) -> Option<Self> {\n        let mut s = Stream::new(data);\n        Some(NameRecord {\n            platform_id: s.read::<PlatformId>()?,\n            encoding_id: s.read::<u16>()?,\n            language_id: s.read::<u16>()?,\n            name_id: s.read::<u16>()?,\n            length: s.read::<u16>()?,\n            offset: s.read::<Offset16>()?,\n        })\n    }\n}\n\n/// A [Name Record](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-records).\n#[derive(Clone, Copy)]\npub struct Name<'a> {\n    /// A platform ID.\n    pub platform_id: PlatformId,\n    /// A platform-specific encoding ID.\n    pub encoding_id: u16,\n    /// A language ID.\n    pub language_id: u16,\n    /// A [Name ID](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids).\n    ///\n    /// A predefined list of ID's can be found in the [`name_id`](name_id/index.html) module.\n    pub name_id: u16,\n    /// A raw name data.\n    ///\n    /// Can be in any encoding. Can be empty.\n    pub name: &'a [u8],\n}\n\nimpl<'a> Name<'a> {\n    /// Returns the Name's data as a UTF-8 string.\n    ///\n    /// Only Unicode names are supported. And since they are stored as UTF-16BE,\n    /// we can't return `&str` and have to allocate a `String`.\n    ///\n    /// Supports:\n    /// - Unicode Platform ID\n    /// - Windows Platform ID + Symbol\n    /// - Windows Platform ID + Unicode BMP\n    #[cfg(feature = \"std\")]\n    #[inline(never)]\n    pub fn to_string(&self) -> Option<String> {\n        if self.is_unicode() {\n            self.name_from_utf16_be()\n        } else {\n            None\n        }\n    }\n\n    /// Checks that the current Name data has a Unicode encoding.\n    #[inline]\n    pub fn is_unicode(&self) -> bool {\n        is_unicode_encoding(self.platform_id, self.encoding_id)\n    }\n\n    #[cfg(feature = \"std\")]\n    #[inline(never)]\n    fn name_from_utf16_be(&self) -> Option<String> {\n        let mut name: Vec<u16> = Vec::new();\n        for c in LazyArray16::<u16>::new(self.name) {\n            name.push(c);\n        }\n\n        String::from_utf16(&name).ok()\n    }\n\n    /// Returns a Name language.\n    pub fn language(&self) -> Language {\n        if self.platform_id == PlatformId::Windows {\n            Language::windows_language(self.language_id)\n        } else if self.platform_id == PlatformId::Macintosh\n            && self.encoding_id == 0\n            && self.language_id == 0\n        {\n            Language::English_UnitedStates\n        } else {\n            Language::Unknown\n        }\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl<'a> core::fmt::Debug for Name<'a> {\n    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {\n        let name = self.to_string();\n        f.debug_struct(\"Name\")\n            .field(\"name\", &name.as_deref().unwrap_or(\"unsupported encoding\"))\n            .field(\"platform_id\", &self.platform_id)\n            .field(\"encoding_id\", &self.encoding_id)\n            .field(\"language_id\", &self.language_id)\n            .field(\"language\", &self.language())\n            .field(\"name_id\", &self.name_id)\n            .finish()\n    }\n}\n\n#[cfg(not(feature = \"std\"))]\nimpl<'a> core::fmt::Debug for Name<'a> {\n    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {\n        f.debug_struct(\"Name\")\n            .field(\"name\", &self.name)\n            .field(\"platform_id\", &self.platform_id)\n            .field(\"encoding_id\", &self.encoding_id)\n            .field(\"language_id\", &self.language_id)\n            .field(\"language\", &self.language())\n            .field(\"name_id\", &self.name_id)\n            .finish()\n    }\n}\n\n/// A list of face names.\n#[derive(Clone, Copy, Default)]\npub struct Names<'a> {\n    records: LazyArray16<'a, NameRecord>,\n    storage: &'a [u8],\n}\n\nimpl<'a> Names<'a> {\n    /// Returns a name at index.\n    pub fn get(&self, index: u16) -> Option<Name<'a>> {\n        let record = self.records.get(index)?;\n        let name_start = record.offset.to_usize();\n        let name_end = name_start + usize::from(record.length);\n        let name = self.storage.get(name_start..name_end)?;\n        Some(Name {\n            platform_id: record.platform_id,\n            encoding_id: record.encoding_id,\n            language_id: record.language_id,\n            name_id: record.name_id,\n            name,\n        })\n    }\n\n    /// Returns a number of name records.\n    pub fn len(&self) -> u16 {\n        self.records.len()\n    }\n\n    /// Checks if there are any name records.\n    pub fn is_empty(&self) -> bool {\n        self.records.is_empty()\n    }\n}\n\nimpl core::fmt::Debug for Names<'_> {\n    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {\n        write!(f, \"Names {{ ... }}\")\n    }\n}\n\nimpl<'a> IntoIterator for Names<'a> {\n    type Item = Name<'a>;\n    type IntoIter = NamesIter<'a>;\n\n    #[inline]\n    fn into_iter(self) -> Self::IntoIter {\n        NamesIter {\n            names: self,\n            index: 0,\n        }\n    }\n}\n\n/// An iterator over face names.\n#[derive(Clone, Copy)]\n#[allow(missing_debug_implementations)]\npub struct NamesIter<'a> {\n    names: Names<'a>,\n    index: u16,\n}\n\nimpl<'a> Iterator for NamesIter<'a> {\n    type Item = Name<'a>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.index < self.names.len() {\n            self.index += 1;\n            self.names.get(self.index - 1)\n        } else {\n            None\n        }\n    }\n\n    #[inline]\n    fn count(self) -> usize {\n        usize::from(self.names.len().saturating_sub(self.index))\n    }\n}\n\n/// A [Naming Table](\n/// https://docs.microsoft.com/en-us/typography/opentype/spec/name).\n#[derive(Clone, Copy, Default, Debug)]\npub struct Table<'a> {\n    /// A list of names.\n    pub names: Names<'a>,\n}\n\nimpl<'a> Table<'a> {\n    /// Parses a table from raw data.\n    pub fn parse(data: &'a [u8]) -> Option<Self> {\n        // https://docs.microsoft.com/en-us/typography/opentype/spec/name#naming-table-format-1\n        const LANG_TAG_RECORD_SIZE: u16 = 4;\n\n        let mut s = Stream::new(data);\n        let version = s.read::<u16>()?;\n        let count = s.read::<u16>()?;\n        let storage_offset = s.read::<Offset16>()?.to_usize();\n\n        if version == 0 {\n            // Do nothing.\n        } else if version == 1 {\n            let lang_tag_count = s.read::<u16>()?;\n            let lang_tag_len = lang_tag_count.checked_mul(LANG_TAG_RECORD_SIZE)?;\n            s.advance(usize::from(lang_tag_len)); // langTagRecords\n        } else {\n            // Unsupported version.\n            return None;\n        }\n\n        let records = s.read_array16::<NameRecord>(count)?;\n\n        if s.offset() < storage_offset {\n            s.advance(storage_offset - s.offset());\n        }\n\n        let storage = s.tail()?;\n\n        Some(Table {\n            names: Names { records, storage },\n        })\n    }\n}\n"
    },
    {
      "package": "ttf-parser@0.19.2",
      "sourcePath": "src/tables/post.rs",
      "sha256": "8736dfc782c57e17690b1aed11020e49709b4580f34e989b7263b4e9311648b8",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "//! A [PostScript Table](\n//! https://docs.microsoft.com/en-us/typography/opentype/spec/post) implementation.\n\nuse crate::parser::{Fixed, LazyArray16, Stream};\n#[cfg(feature = \"glyph-names\")]\nuse crate::GlyphId;\nuse crate::LineMetrics;\n\nconst ITALIC_ANGLE_OFFSET: usize = 4;\nconst UNDERLINE_POSITION_OFFSET: usize = 8;\nconst UNDERLINE_THICKNESS_OFFSET: usize = 10;\nconst IS_FIXED_PITCH_OFFSET: usize = 12;\n\n// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6post.html\n/// A list of Macintosh glyph names.\n#[cfg(feature = \"glyph-names\")]\nconst MACINTOSH_NAMES: &[&str] = &[\n    \".notdef\",\n    \".null\",\n    \"nonmarkingreturn\",\n    \"space\",\n    \"exclam\",\n    \"quotedbl\",\n    \"numbersign\",\n    \"dollar\",\n    \"percent\",\n    \"ampersand\",\n    \"quotesingle\",\n    \"parenleft\",\n    \"parenright\",\n    \"asterisk\",\n    \"plus\",\n    \"comma\",\n    \"hyphen\",\n    \"period\",\n    \"slash\",\n    \"zero\",\n    \"one\",\n    \"two\",\n    \"three\",\n    \"four\",\n    \"five\",\n    \"six\",\n    \"seven\",\n    \"eight\",\n    \"nine\",\n    \"colon\",\n    \"semicolon\",\n    \"less\",\n    \"equal\",\n    \"greater\",\n    \"question\",\n    \"at\",\n    \"A\",\n    \"B\",\n    \"C\",\n    \"D\",\n    \"E\",\n    \"F\",\n    \"G\",\n    \"H\",\n    \"I\",\n    \"J\",\n    \"K\",\n    \"L\",\n    \"M\",\n    \"N\",\n    \"O\",\n    \"P\",\n    \"Q\",\n    \"R\",\n    \"S\",\n    \"T\",\n    \"U\",\n    \"V\",\n    \"W\",\n    \"X\",\n    \"Y\",\n    \"Z\",\n    \"bracketleft\",\n    \"backslash\",\n    \"bracketright\",\n    \"asciicircum\",\n    \"underscore\",\n    \"grave\",\n    \"a\",\n    \"b\",\n    \"c\",\n    \"d\",\n    \"e\",\n    \"f\",\n    \"g\",\n    \"h\",\n    \"i\",\n    \"j\",\n    \"k\",\n    \"l\",\n    \"m\",\n    \"n\",\n    \"o\",\n    \"p\",\n    \"q\",\n    \"r\",\n    \"s\",\n    \"t\",\n    \"u\",\n    \"v\",\n    \"w\",\n    \"x\",\n    \"y\",\n    \"z\",\n    \"braceleft\",\n    \"bar\",\n    \"braceright\",\n    \"asciitilde\",\n    \"Adieresis\",\n    \"Aring\",\n    \"Ccedilla\",\n    \"Eacute\",\n    \"Ntilde\",\n    \"Odieresis\",\n    \"Udieresis\",\n    \"aacute\",\n    \"agrave\",\n    \"acircumflex\",\n    \"adieresis\",\n    \"atilde\",\n    \"aring\",\n    \"ccedilla\",\n    \"eacute\",\n    \"egrave\",\n    \"ecircumflex\",\n    \"edieresis\",\n    \"iacute\",\n    \"igrave\",\n    \"icircumflex\",\n    \"idieresis\",\n    \"ntilde\",\n    \"oacute\",\n    \"ograve\",\n    \"ocircumflex\",\n    \"odieresis\",\n    \"otilde\",\n    \"uacute\",\n    \"ugrave\",\n    \"ucircumflex\",\n    \"udieresis\",\n    \"dagger\",\n    \"degree\",\n    \"cent\",\n    \"sterling\",\n    \"section\",\n    \"bullet\",\n    \"paragraph\",\n    \"germandbls\",\n    \"registered\",\n    \"copyright\",\n    \"trademark\",\n    \"acute\",\n    \"dieresis\",\n    \"notequal\",\n    \"AE\",\n    \"Oslash\",\n    \"infinity\",\n    \"plusminus\",\n    \"lessequal\",\n    \"greaterequal\",\n    \"yen\",\n    \"mu\",\n    \"partialdiff\",\n    \"summation\",\n    \"product\",\n    \"pi\",\n    \"integral\",\n    \"ordfeminine\",\n    \"ordmasculine\",\n    \"Omega\",\n    \"ae\",\n    \"oslash\",\n    \"questiondown\",\n    \"exclamdown\",\n    \"logicalnot\",\n    \"radical\",\n    \"florin\",\n    \"approxequal\",\n    \"Delta\",\n    \"guillemotleft\",\n    \"guillemotright\",\n    \"ellipsis\",\n    \"nonbreakingspace\",\n    \"Agrave\",\n    \"Atilde\",\n    \"Otilde\",\n    \"OE\",\n    \"oe\",\n    \"endash\",\n    \"emdash\",\n    \"quotedblleft\",\n    \"quotedblright\",\n    \"quoteleft\",\n    \"quoteright\",\n    \"divide\",\n    \"lozenge\",\n    \"ydieresis\",\n    \"Ydieresis\",\n    \"fraction\",\n    \"currency\",\n    \"guilsinglleft\",\n    \"guilsinglright\",\n    \"fi\",\n    \"fl\",\n    \"daggerdbl\",\n    \"periodcentered\",\n    \"quotesinglbase\",\n    \"quotedblbase\",\n    \"perthousand\",\n    \"Acircumflex\",\n    \"Ecircumflex\",\n    \"Aacute\",\n    \"Edieresis\",\n    \"Egrave\",\n    \"Iacute\",\n    \"Icircumflex\",\n    \"Idieresis\",\n    \"Igrave\",\n    \"Oacute\",\n    \"Ocircumflex\",\n    \"apple\",\n    \"Ograve\",\n    \"Uacute\",\n    \"Ucircumflex\",\n    \"Ugrave\",\n    \"dotlessi\",\n    \"circumflex\",\n    \"tilde\",\n    \"macron\",\n    \"breve\",\n    \"dotaccent\",\n    \"ring\",\n    \"cedilla\",\n    \"hungarumlaut\",\n    \"ogonek\",\n    \"caron\",\n    \"Lslash\",\n    \"lslash\",\n    \"Scaron\",\n    \"scaron\",\n    \"Zcaron\",\n    \"zcaron\",\n    \"brokenbar\",\n    \"Eth\",\n    \"eth\",\n    \"Yacute\",\n    \"yacute\",\n    \"Thorn\",\n    \"thorn\",\n    \"minus\",\n    \"multiply\",\n    \"onesuperior\",\n    \"twosuperior\",\n    \"threesuperior\",\n    \"onehalf\",\n    \"onequarter\",\n    \"threequarters\",\n    \"franc\",\n    \"Gbreve\",\n    \"gbreve\",\n    \"Idotaccent\",\n    \"Scedilla\",\n    \"scedilla\",\n    \"Cacute\",\n    \"cacute\",\n    \"Ccaron\",\n    \"ccaron\",\n    \"dcroat\",\n];\n\n/// An iterator over glyph names.\n///\n/// The `post` table doesn't provide the glyph names count,\n/// so we have to simply iterate over all of them to find it out.\n#[derive(Clone, Copy, Default)]\npub struct Names<'a> {\n    data: &'a [u8],\n    offset: usize,\n}\n\nimpl core::fmt::Debug for Names<'_> {\n    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {\n        write!(f, \"Names {{ ... }}\")\n    }\n}\n\nimpl<'a> Iterator for Names<'a> {\n    type Item = &'a str;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        // Glyph names are stored as Pascal Strings.\n        // Meaning u8 (len) + [u8] (data).\n\n        if self.offset >= self.data.len() {\n            return None;\n        }\n\n        let len = self.data[self.offset];\n        self.offset += 1;\n\n        // An empty name is an error.\n        if len == 0 {\n            return None;\n        }\n\n        let name = self.data.get(self.offset..self.offset + usize::from(len))?;\n        self.offset += usize::from(len);\n        core::str::from_utf8(name).ok()\n    }\n}\n\n/// A [PostScript Table](https://docs.microsoft.com/en-us/typography/opentype/spec/post).\n#[derive(Clone, Copy, Debug)]\npub struct Table<'a> {\n    /// Italic angle in counter-clockwise degrees from the vertical.\n    pub italic_angle: f32,\n    /// Underline metrics.\n    pub underline_metrics: LineMetrics,\n    /// Flag that indicates that the font is monospaced.\n    pub is_monospaced: bool,\n\n    glyph_indexes: LazyArray16<'a, u16>,\n    names_data: &'a [u8],\n}\n\nimpl<'a> Table<'a> {\n    /// Parses a table from raw data.\n    pub fn parse(data: &'a [u8]) -> Option<Self> {\n        // Do not check the exact length, because some fonts include\n        // padding in table's length in table records, which is incorrect.\n        if data.len() < 32 {\n            return None;\n        }\n\n        let version = Stream::new(data).read::<u32>()?;\n        if !(version == 0x00010000\n            || version == 0x00020000\n            || version == 0x00025000\n            || version == 0x00030000\n            || version == 0x00040000)\n        {\n            return None;\n        }\n\n        let italic_angle = Stream::read_at::<Fixed>(data, ITALIC_ANGLE_OFFSET)?.0;\n\n        let underline_metrics = LineMetrics {\n            position: Stream::read_at::<i16>(data, UNDERLINE_POSITION_OFFSET)?,\n            thickness: Stream::read_at::<i16>(data, UNDERLINE_THICKNESS_OFFSET)?,\n        };\n\n        let is_monospaced = Stream::read_at::<u32>(data, IS_FIXED_PITCH_OFFSET)? != 0;\n\n        let mut names_data: &[u8] = &[];\n        let mut glyph_indexes = LazyArray16::default();\n        // Only version 2.0 of the table has data at the end.\n        if version == 0x00020000 {\n            let mut s = Stream::new_at(data, 32)?;\n            let indexes_count = s.read::<u16>()?;\n            glyph_indexes = s.read_array16::<u16>(indexes_count)?;\n            names_data = s.tail()?;\n        }\n\n        Some(Table {\n            italic_angle,\n            underline_metrics,\n            is_monospaced,\n            names_data,\n            glyph_indexes,\n        })\n    }\n\n    /// Returns a glyph name by ID.\n    #[cfg(feature = \"glyph-names\")]\n    pub fn glyph_name(&self, glyph_id: GlyphId) -> Option<&'a str> {\n        let mut index = self.glyph_indexes.get(glyph_id.0)?;\n\n        // 'If the name index is between 0 and 257, treat the name index\n        // as a glyph index in the Macintosh standard order.'\n        if usize::from(index) < MACINTOSH_NAMES.len() {\n            Some(MACINTOSH_NAMES[usize::from(index)])\n        } else {\n            // 'If the name index is between 258 and 65535, then subtract 258 and use that\n            // to index into the list of Pascal strings at the end of the table.'\n            index -= MACINTOSH_NAMES.len() as u16;\n            self.names().nth(usize::from(index))\n        }\n    }\n\n    /// Returns a glyph ID by a name.\n    #[cfg(feature = \"glyph-names\")]\n    pub fn glyph_index_by_name(&self, name: &str) -> Option<GlyphId> {\n        let id = if let Some(index) = MACINTOSH_NAMES.iter().position(|n| *n == name) {\n            self.glyph_indexes\n                .into_iter()\n                .position(|i| usize::from(i) == index)?\n        } else {\n            let mut index = self.names().position(|n| n == name)?;\n            index += MACINTOSH_NAMES.len();\n            self.glyph_indexes\n                .into_iter()\n                .position(|i| usize::from(i) == index)?\n        };\n\n        Some(GlyphId(id as u16))\n    }\n\n    /// Returns an iterator over glyph names.\n    ///\n    /// Default/predefined names are not included. Just the one in the font file.\n    pub fn names(&self) -> Names<'a> {\n        Names {\n            data: self.names_data,\n            offset: 0,\n        }\n    }\n}\n"
    },
    {
      "package": "unicode-bidi@0.3.18",
      "sourcePath": "src/char_data/mod.rs",
      "sha256": "8cbdcaacddb3dd9b70d615693fa73d0e7dca6332102a95f0d3ce447df7645284",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Servo Project Developers. See the\n// COPYRIGHT file at the top-level directory of this distribution.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Accessor for `Bidi_Class` property from Unicode Character Database (UCD)\n\nmod tables;\n\npub use self::tables::{BidiClass, UNICODE_VERSION};\n#[cfg(feature = \"hardcoded-data\")]\nuse core::char;\n#[cfg(feature = \"hardcoded-data\")]\nuse core::cmp::Ordering::{Equal, Greater, Less};\n\n#[cfg(feature = \"hardcoded-data\")]\nuse self::tables::bidi_class_table;\nuse crate::data_source::BidiMatchedOpeningBracket;\nuse crate::BidiClass::*;\n#[cfg(feature = \"hardcoded-data\")]\nuse crate::BidiDataSource;\n/// Hardcoded Bidi data that ships with the unicode-bidi crate.\n///\n/// This can be enabled with the default `hardcoded-data` Cargo feature.\n#[cfg(feature = \"hardcoded-data\")]\npub struct HardcodedBidiData;\n\n#[cfg(feature = \"hardcoded-data\")]\nimpl BidiDataSource for HardcodedBidiData {\n    fn bidi_class(&self, c: char) -> BidiClass {\n        bsearch_range_value_table(c, bidi_class_table)\n    }\n}\n\n/// Find the `BidiClass` of a single char.\n#[cfg(feature = \"hardcoded-data\")]\npub fn bidi_class(c: char) -> BidiClass {\n    bsearch_range_value_table(c, bidi_class_table)\n}\n\n/// If this character is a bracket according to BidiBrackets.txt,\n/// return the corresponding *normalized* *opening bracket* of the pair,\n/// and whether or not it itself is an opening bracket.\npub(crate) fn bidi_matched_opening_bracket(c: char) -> Option<BidiMatchedOpeningBracket> {\n    for pair in self::tables::bidi_pairs_table {\n        if pair.0 == c || pair.1 == c {\n            let skeleton = pair.2.unwrap_or(pair.0);\n            return Some(BidiMatchedOpeningBracket {\n                opening: skeleton,\n                is_open: pair.0 == c,\n            });\n        }\n    }\n    None\n}\n\npub fn is_rtl(bidi_class: BidiClass) -> bool {\n    matches!(bidi_class, RLE | RLO | RLI)\n}\n\n#[cfg(feature = \"hardcoded-data\")]\nfn bsearch_range_value_table(c: char, r: &'static [(char, char, BidiClass)]) -> BidiClass {\n    match r.binary_search_by(|&(lo, hi, _)| {\n        if lo <= c && c <= hi {\n            Equal\n        } else if hi < c {\n            Less\n        } else {\n            Greater\n        }\n    }) {\n        Ok(idx) => {\n            let (_, _, cat) = r[idx];\n            cat\n        }\n        // UCD/extracted/DerivedBidiClass.txt: \"All code points not explicitly listed\n        // for Bidi_Class have the value Left_To_Right (L).\"\n        Err(_) => L,\n    }\n}\n\n#[cfg(all(test, feature = \"hardcoded-data\"))]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_ascii() {\n        assert_eq!(bidi_class('\\u{0000}'), BN);\n        assert_eq!(bidi_class('\\u{0040}'), ON);\n        assert_eq!(bidi_class('\\u{0041}'), L);\n        assert_eq!(bidi_class('\\u{0062}'), L);\n        assert_eq!(bidi_class('\\u{007F}'), BN);\n    }\n\n    #[test]\n    fn test_bmp() {\n        // Hebrew\n        assert_eq!(bidi_class('\\u{0590}'), R);\n        assert_eq!(bidi_class('\\u{05D0}'), R);\n        assert_eq!(bidi_class('\\u{05D1}'), R);\n        assert_eq!(bidi_class('\\u{05FF}'), R);\n\n        // Arabic\n        assert_eq!(bidi_class('\\u{0600}'), AN);\n        assert_eq!(bidi_class('\\u{0627}'), AL);\n        assert_eq!(bidi_class('\\u{07BF}'), AL);\n\n        // Default R + Arabic Extras\n        assert_eq!(bidi_class('\\u{07C0}'), R);\n        assert_eq!(bidi_class('\\u{085F}'), R);\n        assert_eq!(bidi_class('\\u{0860}'), AL);\n        assert_eq!(bidi_class('\\u{0870}'), AL);\n        assert_eq!(bidi_class('\\u{089F}'), NSM);\n        assert_eq!(bidi_class('\\u{08A0}'), AL);\n        assert_eq!(bidi_class('\\u{089F}'), NSM);\n        assert_eq!(bidi_class('\\u{08FF}'), NSM);\n\n        // Default ET\n        assert_eq!(bidi_class('\\u{20A0}'), ET);\n        assert_eq!(bidi_class('\\u{20CF}'), ET);\n\n        // Arabic Presentation Forms\n        assert_eq!(bidi_class('\\u{FB1D}'), R);\n        assert_eq!(bidi_class('\\u{FB4F}'), R);\n        assert_eq!(bidi_class('\\u{FB50}'), AL);\n        assert_eq!(bidi_class('\\u{FDCF}'), ON);\n        assert_eq!(bidi_class('\\u{FDF0}'), AL);\n        assert_eq!(bidi_class('\\u{FDFF}'), ON);\n        assert_eq!(bidi_class('\\u{FE70}'), AL);\n        assert_eq!(bidi_class('\\u{FEFE}'), AL);\n        assert_eq!(bidi_class('\\u{FEFF}'), BN);\n\n        // noncharacters\n        assert_eq!(bidi_class('\\u{FDD0}'), L);\n        assert_eq!(bidi_class('\\u{FDD1}'), L);\n        assert_eq!(bidi_class('\\u{FDEE}'), L);\n        assert_eq!(bidi_class('\\u{FDEF}'), L);\n        assert_eq!(bidi_class('\\u{FFFE}'), L);\n        assert_eq!(bidi_class('\\u{FFFF}'), L);\n    }\n\n    #[test]\n    fn test_smp() {\n        // Default AL + R\n        assert_eq!(bidi_class('\\u{10800}'), R);\n        assert_eq!(bidi_class('\\u{10FFF}'), R);\n        assert_eq!(bidi_class('\\u{1E800}'), R);\n        assert_eq!(bidi_class('\\u{1EDFF}'), R);\n        assert_eq!(bidi_class('\\u{1EE00}'), AL);\n        assert_eq!(bidi_class('\\u{1EEFF}'), AL);\n        assert_eq!(bidi_class('\\u{1EF00}'), R);\n        assert_eq!(bidi_class('\\u{1EFFF}'), R);\n    }\n\n    #[test]\n    fn test_unassigned_planes() {\n        assert_eq!(bidi_class('\\u{30000}'), L);\n        assert_eq!(bidi_class('\\u{40000}'), L);\n        assert_eq!(bidi_class('\\u{50000}'), L);\n        assert_eq!(bidi_class('\\u{60000}'), L);\n        assert_eq!(bidi_class('\\u{70000}'), L);\n        assert_eq!(bidi_class('\\u{80000}'), L);\n        assert_eq!(bidi_class('\\u{90000}'), L);\n        assert_eq!(bidi_class('\\u{a0000}'), L);\n    }\n}\n"
    },
    {
      "package": "unicode-bidi@0.3.18",
      "sourcePath": "src/data_source.rs",
      "sha256": "36fa0785e51c549c1f72f09040cfe515b848d1b23fb30d469770a6b4b17b49df",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Servo Project Developers. See the\n// COPYRIGHT file at the top-level directory of this distribution.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::BidiClass;\n\n/// This is the return value of [`BidiDataSource::bidi_matched_opening_bracket()`].\n///\n/// It represents the matching *normalized* opening bracket for a given bracket in a bracket pair,\n/// and whether or not that bracket is opening.\n#[derive(Debug, Copy, Clone)]\npub struct BidiMatchedOpeningBracket {\n    /// The corresponding opening bracket in this bracket pair, normalized\n    ///\n    /// In case of opening brackets, this will be the bracket itself, except for when the bracket\n    /// is not normalized, in which case it will be the normalized form.\n    pub opening: char,\n    /// Whether or not the requested bracket was an opening bracket. True for opening\n    pub is_open: bool,\n}\n\n/// This trait abstracts over a data source that is able to produce the Unicode Bidi class for a given\n/// character\npub trait BidiDataSource {\n    fn bidi_class(&self, c: char) -> BidiClass;\n    /// If this character is a bracket according to BidiBrackets.txt,\n    /// return the corresponding *normalized* *opening bracket* of the pair,\n    /// and whether or not it itself is an opening bracket.\n    ///\n    /// This effectively buckets brackets into equivalence classes keyed on the\n    /// normalized opening bracket.\n    ///\n    /// The default implementation will pull in a small amount of hardcoded data,\n    /// regardless of the `hardcoded-data` feature. This is in part for convenience\n    /// (since this data is small and changes less often), and in part so that this method can be\n    /// added without needing a breaking version bump.\n    /// Override this method in your custom data source to prevent the use of hardcoded data.\n    fn bidi_matched_opening_bracket(&self, c: char) -> Option<BidiMatchedOpeningBracket> {\n        crate::char_data::bidi_matched_opening_bracket(c)\n    }\n}\n"
    },
    {
      "package": "unicode-bidi@0.3.18",
      "sourcePath": "src/deprecated.rs",
      "sha256": "f94c0e75dec7e70cb9802e26b7f82fe618dcdd50e9973927bacd4eccc6899c62",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Servo Project Developers. See the\n// COPYRIGHT file at the top-level directory of this distribution.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! This module holds deprecated assets only.\n\nuse super::*;\n\n/// Find the level runs within a line and return them in visual order.\n///\n/// NOTE: This implementation is incomplete. The algorithm needs information about the text,\n/// including original `BidiClass` property of each character, to be able to perform correctly.\n/// Please see [`BidiInfo::visual_runs()`](../struct.BidiInfo.html#method.visual_runs) for the\n/// improved implementation.\n///\n/// `line` is a range of bytes indices within `levels`.\n///\n/// <http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels>\n#[deprecated(\n    since = \"0.3.0\",\n    note = \"please use `BidiInfo::visual_runs()` instead.\"\n)]\npub fn visual_runs(line: Range<usize>, levels: &[Level]) -> Vec<LevelRun> {\n    assert!(line.start <= levels.len());\n    assert!(line.end <= levels.len());\n\n    let mut runs = Vec::new();\n\n    // Find consecutive level runs.\n    let mut start = line.start;\n    let mut run_level = levels[start];\n    let mut min_level = run_level;\n    let mut max_level = run_level;\n\n    for (i, &new_level) in levels.iter().enumerate().take(line.end).skip(start + 1) {\n        if new_level != run_level {\n            // End of the previous run, start of a new one.\n            runs.push(start..i);\n            start = i;\n            run_level = new_level;\n\n            min_level = cmp::min(run_level, min_level);\n            max_level = cmp::max(run_level, max_level);\n        }\n    }\n    runs.push(start..line.end);\n\n    let run_count = runs.len();\n\n    // Re-order the odd runs.\n    // <http://www.unicode.org/reports/tr9/#L2>\n\n    // Stop at the lowest *odd* level.\n    min_level = min_level.new_lowest_ge_rtl().expect(\"Level error\");\n\n    while max_level >= min_level {\n        // Look for the start of a sequence of consecutive runs of max_level or higher.\n        let mut seq_start = 0;\n        while seq_start < run_count {\n            if levels[runs[seq_start].start] < max_level {\n                seq_start += 1;\n                continue;\n            }\n\n            // Found the start of a sequence. Now find the end.\n            let mut seq_end = seq_start + 1;\n\n            while seq_end < run_count && levels[runs[seq_end].start] >= max_level {\n                seq_end += 1;\n            }\n\n            // Reverse the runs within this sequence.\n            runs[seq_start..seq_end].reverse();\n\n            seq_start = seq_end;\n        }\n\n        max_level\n            .lower(1)\n            .expect(\"Lowering embedding level below zero\");\n    }\n\n    runs\n}\n"
    },
    {
      "package": "unicode-bidi@0.3.18",
      "sourcePath": "src/explicit.rs",
      "sha256": "86c3c55bf2cc90aab1411aac6cf05de505ca74e44a76fe829572dd7dc4dd2aa3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Servo Project Developers. See the\n// COPYRIGHT file at the top-level directory of this distribution.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! 3.3.2 Explicit Levels and Directions\n//!\n//! <http://www.unicode.org/reports/tr9/#Explicit_Levels_and_Directions>\n\n#[cfg(feature = \"smallvec\")]\nuse smallvec::{smallvec, SmallVec};\n\nuse super::char_data::{\n    is_rtl,\n    BidiClass::{self, *},\n};\nuse super::level::Level;\nuse super::prepare::removed_by_x9;\nuse super::LevelRunVec;\nuse super::TextSource;\n\n/// Compute explicit embedding levels for one paragraph of text (X1-X8), and identify\n/// level runs (BD7) for use when determining Isolating Run Sequences (X10).\n///\n/// `processing_classes[i]` must contain the `BidiClass` of the char at byte index `i`,\n/// for each char in `text`.\n///\n/// `runs` returns the list of level runs (BD7) of the text.\n#[cfg_attr(feature = \"flame_it\", flamer::flame)]\npub fn compute<'a, T: TextSource<'a> + ?Sized>(\n    text: &'a T,\n    para_level: Level,\n    original_classes: &[BidiClass],\n    levels: &mut [Level],\n    processing_classes: &mut [BidiClass],\n    runs: &mut LevelRunVec,\n) {\n    assert_eq!(text.len(), original_classes.len());\n\n    // <http://www.unicode.org/reports/tr9/#X1>\n    #[cfg(feature = \"smallvec\")]\n    let mut stack: SmallVec<[Status; 8]> = smallvec![Status {\n        level: para_level,\n        status: OverrideStatus::Neutral,\n    }];\n    #[cfg(not(feature = \"smallvec\"))]\n    let mut stack = vec![Status {\n        level: para_level,\n        status: OverrideStatus::Neutral,\n    }];\n\n    let mut overflow_isolate_count = 0u32;\n    let mut overflow_embedding_count = 0u32;\n    let mut valid_isolate_count = 0u32;\n\n    let mut current_run_level = Level::ltr();\n    let mut current_run_start = 0;\n\n    for (i, len) in text.indices_lengths() {\n        let last = stack.last().unwrap();\n\n        match original_classes[i] {\n            // Rules X2-X5c\n            RLE | LRE | RLO | LRO | RLI | LRI | FSI => {\n                // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n                levels[i] = last.level;\n\n                // X5a-X5c: Isolate initiators get the level of the last entry on the stack.\n                let is_isolate = matches!(original_classes[i], RLI | LRI | FSI);\n                if is_isolate {\n                    // Redundant due to \"Retaining explicit formatting characters\" step.\n                    // levels[i] = last.level;\n                    match last.status {\n                        OverrideStatus::RTL => processing_classes[i] = R,\n                        OverrideStatus::LTR => processing_classes[i] = L,\n                        _ => {}\n                    }\n                }\n\n                let new_level = if is_rtl(original_classes[i]) {\n                    last.level.new_explicit_next_rtl()\n                } else {\n                    last.level.new_explicit_next_ltr()\n                };\n\n                if new_level.is_ok() && overflow_isolate_count == 0 && overflow_embedding_count == 0\n                {\n                    let new_level = new_level.unwrap();\n\n                    stack.push(Status {\n                        level: new_level,\n                        status: match original_classes[i] {\n                            RLO => OverrideStatus::RTL,\n                            LRO => OverrideStatus::LTR,\n                            RLI | LRI | FSI => OverrideStatus::Isolate,\n                            _ => OverrideStatus::Neutral,\n                        },\n                    });\n\n                    if is_isolate {\n                        valid_isolate_count += 1;\n                    } else {\n                        // The spec doesn't explicitly mention this step, but it is necessary.\n                        // See the reference implementations for comparison.\n                        levels[i] = new_level;\n                    }\n                } else if is_isolate {\n                    overflow_isolate_count += 1;\n                } else if overflow_isolate_count == 0 {\n                    overflow_embedding_count += 1;\n                }\n\n                if !is_isolate {\n                    // X9 +\n                    // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n                    // (PDF handled below)\n                    processing_classes[i] = BN;\n                }\n            }\n\n            // <http://www.unicode.org/reports/tr9/#X6a>\n            PDI => {\n                if overflow_isolate_count > 0 {\n                    overflow_isolate_count -= 1;\n                } else if valid_isolate_count > 0 {\n                    overflow_embedding_count = 0;\n\n                    while !matches!(\n                        stack.pop(),\n                        None | Some(Status {\n                            status: OverrideStatus::Isolate,\n                            ..\n                        })\n                    ) {}\n\n                    valid_isolate_count -= 1;\n                }\n\n                let last = stack.last().unwrap();\n                levels[i] = last.level;\n\n                match last.status {\n                    OverrideStatus::RTL => processing_classes[i] = R,\n                    OverrideStatus::LTR => processing_classes[i] = L,\n                    _ => {}\n                }\n            }\n\n            // <http://www.unicode.org/reports/tr9/#X7>\n            PDF => {\n                if overflow_isolate_count > 0 {\n                    // do nothing\n                } else if overflow_embedding_count > 0 {\n                    overflow_embedding_count -= 1;\n                } else if last.status != OverrideStatus::Isolate && stack.len() >= 2 {\n                    stack.pop();\n                }\n\n                // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n                levels[i] = stack.last().unwrap().level;\n                // X9 part of retaining explicit formatting characters.\n                processing_classes[i] = BN;\n            }\n\n            // Nothing.\n            // BN case moved down to X6, see <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n            B => {}\n\n            // <http://www.unicode.org/reports/tr9/#X6>\n            _ => {\n                levels[i] = last.level;\n\n                // This condition is not in the spec, but I am pretty sure that is a spec bug.\n                // https://www.unicode.org/L2/L2023/23014-amd-to-uax9.pdf\n                if original_classes[i] != BN {\n                    match last.status {\n                        OverrideStatus::RTL => processing_classes[i] = R,\n                        OverrideStatus::LTR => processing_classes[i] = L,\n                        _ => {}\n                    }\n                }\n            }\n        }\n\n        // Handle multi-byte characters.\n        for j in 1..len {\n            levels[i + j] = levels[i];\n            processing_classes[i + j] = processing_classes[i];\n        }\n\n        // Identify level runs to be passed to prepare::isolating_run_sequences().\n        if i == 0 {\n            // Initialize for the first (or only) run.\n            current_run_level = levels[i];\n        } else {\n            // Check if we need to start a new level run.\n            // <https://www.unicode.org/reports/tr9/#BD7>\n            if !removed_by_x9(original_classes[i]) && levels[i] != current_run_level {\n                // End the last run and start a new one.\n                runs.push(current_run_start..i);\n                current_run_level = levels[i];\n                current_run_start = i;\n            }\n        }\n    }\n\n    // Append the trailing level run, if non-empty.\n    if levels.len() > current_run_start {\n        runs.push(current_run_start..levels.len());\n    }\n}\n\n/// Entries in the directional status stack:\nstruct Status {\n    level: Level,\n    status: OverrideStatus,\n}\n\n#[derive(PartialEq)]\nenum OverrideStatus {\n    Neutral,\n    RTL,\n    LTR,\n    Isolate,\n}\n"
    },
    {
      "package": "unicode-bidi@0.3.18",
      "sourcePath": "src/format_chars.rs",
      "sha256": "678399fec3f4bfaf4093f38cfdb8956288313386dc3511dab9fb58164e8dc01b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2017 The Servo Project Developers. See the\n// COPYRIGHT file at the top-level directory of this distribution.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Directional Formatting Characters\n//!\n//! <http://www.unicode.org/reports/tr9/#Directional_Formatting_Characters>\n\n// == Implicit ==\n/// ARABIC LETTER MARK\npub const ALM: char = '\\u{061C}';\n/// LEFT-TO-RIGHT MARK\npub const LRM: char = '\\u{200E}';\n/// RIGHT-TO-LEFT MARK\npub const RLM: char = '\\u{200F}';\n\n// == Explicit Isolates ==\n/// LEFT‑TO‑RIGHT ISOLATE\npub const LRI: char = '\\u{2066}';\n/// RIGHT‑TO‑LEFT ISOLATE\npub const RLI: char = '\\u{2067}';\n/// FIRST STRONG ISOLATE\npub const FSI: char = '\\u{2068}';\n/// POP DIRECTIONAL ISOLATE\npub const PDI: char = '\\u{2069}';\n\n// == Explicit Embeddings and Overrides ==\n/// LEFT-TO-RIGHT EMBEDDING\npub const LRE: char = '\\u{202A}';\n/// RIGHT-TO-LEFT EMBEDDING\npub const RLE: char = '\\u{202B}';\n/// POP DIRECTIONAL FORMATTING\npub const PDF: char = '\\u{202C}';\n/// LEFT-TO-RIGHT OVERRIDE\npub const LRO: char = '\\u{202D}';\n/// RIGHT-TO-LEFT OVERRIDE\npub const RLO: char = '\\u{202E}';\n"
    },
    {
      "package": "unicode-bidi@0.3.18",
      "sourcePath": "src/implicit.rs",
      "sha256": "8d5b003464aee3f333785c6170a884945251f39601e4ea658e669a2ad575d588",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Servo Project Developers. See the\n// COPYRIGHT file at the top-level directory of this distribution.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! 3.3.4 - 3.3.6. Resolve implicit levels and types.\n\n#[cfg(not(feature = \"smallvec\"))]\nuse alloc::vec::Vec;\nuse core::cmp::max;\n#[cfg(feature = \"smallvec\")]\nuse smallvec::SmallVec;\n\nuse super::char_data::BidiClass::{self, *};\nuse super::level::Level;\nuse super::prepare::{not_removed_by_x9, IsolatingRunSequence};\nuse super::{BidiDataSource, TextSource};\n\n/// 3.3.4 Resolving Weak Types\n///\n/// <http://www.unicode.org/reports/tr9/#Resolving_Weak_Types>\n#[cfg_attr(feature = \"flame_it\", flamer::flame)]\npub fn resolve_weak<'a, T: TextSource<'a> + ?Sized>(\n    text: &'a T,\n    sequence: &IsolatingRunSequence,\n    processing_classes: &mut [BidiClass],\n) {\n    // Note: The spec treats these steps as individual passes that are applied one after the other\n    // on the entire IsolatingRunSequence at once. We instead collapse it into a single iteration,\n    // which is straightforward for rules that are based on the state of the current character, but not\n    // for rules that care about surrounding characters. To deal with them, we retain additional state\n    // about previous character classes that may have since been changed by later rules.\n\n    // The previous class for the purposes of rule W4/W6, not tracking changes made after or during W4.\n    let mut prev_class_before_w4 = sequence.sos;\n    // The previous class for the purposes of rule W5.\n    let mut prev_class_before_w5 = sequence.sos;\n    // The previous class for the purposes of rule W1, not tracking changes from any other rules.\n    let mut prev_class_before_w1 = sequence.sos;\n    let mut last_strong_is_al = false;\n    #[cfg(feature = \"smallvec\")]\n    let mut et_run_indices = SmallVec::<[usize; 8]>::new(); // for W5\n    #[cfg(not(feature = \"smallvec\"))]\n    let mut et_run_indices = Vec::new(); // for W5\n    #[cfg(feature = \"smallvec\")]\n    let mut bn_run_indices = SmallVec::<[usize; 8]>::new(); // for W5 +  <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n    #[cfg(not(feature = \"smallvec\"))]\n    let mut bn_run_indices = Vec::new(); // for W5 +  <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n\n    for (run_index, level_run) in sequence.runs.iter().enumerate() {\n        for i in &mut level_run.clone() {\n            if processing_classes[i] == BN {\n                // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n                // Keeps track of bn runs for W5 in case we see an ET.\n                bn_run_indices.push(i);\n                // BNs aren't real, skip over them.\n                continue;\n            }\n\n            // Store the processing class of all rules before W2/W1.\n            // Used to keep track of the last strong character for W2. W3 is able to insert new strong\n            // characters, so we don't want to be misled by it.\n            let mut w2_processing_class = processing_classes[i];\n\n            // <http://www.unicode.org/reports/tr9/#W1>\n            //\n\n            if processing_classes[i] == NSM {\n                processing_classes[i] = match prev_class_before_w1 {\n                    RLI | LRI | FSI | PDI => ON,\n                    _ => prev_class_before_w1,\n                };\n                // W1 occurs before W2, update this.\n                w2_processing_class = processing_classes[i];\n            }\n\n            prev_class_before_w1 = processing_classes[i];\n\n            // <http://www.unicode.org/reports/tr9/#W2>\n            // <http://www.unicode.org/reports/tr9/#W3>\n            //\n            match processing_classes[i] {\n                EN => {\n                    if last_strong_is_al {\n                        // W2. If previous strong char was AL, change EN to AN.\n                        processing_classes[i] = AN;\n                    }\n                }\n                // W3.\n                AL => processing_classes[i] = R,\n                _ => {}\n            }\n\n            // update last_strong_is_al.\n            match w2_processing_class {\n                L | R => {\n                    last_strong_is_al = false;\n                }\n                AL => {\n                    last_strong_is_al = true;\n                }\n                _ => {}\n            }\n\n            let class_before_w456 = processing_classes[i];\n\n            // <http://www.unicode.org/reports/tr9/#W4>\n            // <http://www.unicode.org/reports/tr9/#W5>\n            // <http://www.unicode.org/reports/tr9/#W6> (separators only)\n            // (see below for W6 terminator code)\n            //\n            match processing_classes[i] {\n                // <http://www.unicode.org/reports/tr9/#W6>\n                EN => {\n                    // W5. If a run of ETs is adjacent to an EN, change the ETs to EN.\n                    for j in &et_run_indices {\n                        processing_classes[*j] = EN;\n                    }\n                    et_run_indices.clear();\n                }\n\n                // <http://www.unicode.org/reports/tr9/#W4>\n                // <http://www.unicode.org/reports/tr9/#W6>\n                ES | CS => {\n                    // See https://github.com/servo/unicode-bidi/issues/86 for improving this.\n                    // We want to make sure we check the correct next character by skipping past the rest\n                    // of this one.\n                    if let Some((_, char_len)) = text.char_at(i) {\n                        let mut next_class = sequence\n                            .iter_forwards_from(i + char_len, run_index)\n                            .map(|j| processing_classes[j])\n                            // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n                            .find(not_removed_by_x9)\n                            .unwrap_or(sequence.eos);\n                        if next_class == EN && last_strong_is_al {\n                            // Apply W2 to next_class. We know that last_strong_is_al\n                            // has no chance of changing on this character so we can still assume its value\n                            // will be the same by the time we get to it.\n                            next_class = AN;\n                        }\n                        processing_classes[i] =\n                            match (prev_class_before_w4, processing_classes[i], next_class) {\n                                // W4\n                                (EN, ES, EN) | (EN, CS, EN) => EN,\n                                // W4\n                                (AN, CS, AN) => AN,\n                                // W6 (separators only)\n                                (_, _, _) => ON,\n                            };\n\n                        // W6 + <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n                        // We have to do this before W5 gets its grubby hands on these characters and thinks\n                        // they're part of an ET run.\n                        // We check for ON to ensure that we had hit the W6 branch above, since this `ES | CS` match\n                        // arm handles both W4 and W6.\n                        if processing_classes[i] == ON {\n                            for idx in sequence.iter_backwards_from(i, run_index) {\n                                let class = &mut processing_classes[idx];\n                                if *class != BN {\n                                    break;\n                                }\n                                *class = ON;\n                            }\n                            for idx in sequence.iter_forwards_from(i + char_len, run_index) {\n                                let class = &mut processing_classes[idx];\n                                if *class != BN {\n                                    break;\n                                }\n                                *class = ON;\n                            }\n                        }\n                    } else {\n                        // We're in the middle of a character, copy over work done for previous bytes\n                        // since it's going to be the same answer.\n                        processing_classes[i] = processing_classes[i - 1];\n                    }\n                }\n                // <http://www.unicode.org/reports/tr9/#W5>\n                ET => {\n                    match prev_class_before_w5 {\n                        EN => processing_classes[i] = EN,\n                        _ => {\n                            // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n                            // If there was a BN run before this, that's now a part of this ET run.\n                            et_run_indices.extend(bn_run_indices.clone());\n\n                            // In case this is followed by an EN.\n                            et_run_indices.push(i);\n                        }\n                    }\n                }\n                _ => {}\n            }\n\n            // Common loop iteration code\n            //\n\n            // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n            // BN runs would have already continued the loop, clear them before we get to the next one.\n            bn_run_indices.clear();\n\n            // W6 above only deals with separators, so it doesn't change anything W5 cares about,\n            // so we still can update this after running that part of W6.\n            prev_class_before_w5 = processing_classes[i];\n\n            // <http://www.unicode.org/reports/tr9/#W6> (terminators only)\n            // (see above for W6 separator code)\n            //\n            if prev_class_before_w5 != ET {\n                // W6. If we didn't find an adjacent EN, turn any ETs into ON instead.\n                for j in &et_run_indices {\n                    processing_classes[*j] = ON;\n                }\n                et_run_indices.clear();\n            }\n\n            // We stashed this before W4/5/6 could get their grubby hands on it, and it's not\n            // used in the W6 terminator code below so we can update it now.\n            prev_class_before_w4 = class_before_w456;\n        }\n    }\n    // Rerun this check in case we ended with a sequence of BNs (i.e., we'd never\n    // hit the end of the for loop above).\n    // W6. If we didn't find an adjacent EN, turn any ETs into ON instead.\n    for j in &et_run_indices {\n        processing_classes[*j] = ON;\n    }\n    et_run_indices.clear();\n\n    // W7. If the previous strong char was L, change EN to L.\n    let mut last_strong_is_l = sequence.sos == L;\n    for i in sequence.runs.iter().cloned().flatten() {\n        match processing_classes[i] {\n            EN if last_strong_is_l => {\n                processing_classes[i] = L;\n            }\n            L => {\n                last_strong_is_l = true;\n            }\n            R | AL => {\n                last_strong_is_l = false;\n            }\n            // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n            // Already scanning past BN here.\n            _ => {}\n        }\n    }\n}\n\n#[cfg(feature = \"smallvec\")]\ntype BracketPairVec = SmallVec<[BracketPair; 8]>;\n#[cfg(not(feature = \"smallvec\"))]\ntype BracketPairVec = Vec<BracketPair>;\n\n/// 3.3.5 Resolving Neutral Types\n///\n/// <http://www.unicode.org/reports/tr9/#Resolving_Neutral_Types>\n#[cfg_attr(feature = \"flame_it\", flamer::flame)]\npub fn resolve_neutral<'a, D: BidiDataSource, T: TextSource<'a> + ?Sized>(\n    text: &'a T,\n    data_source: &D,\n    sequence: &IsolatingRunSequence,\n    levels: &[Level],\n    original_classes: &[BidiClass],\n    processing_classes: &mut [BidiClass],\n) {\n    // e = embedding direction\n    let e: BidiClass = levels[sequence.runs[0].start].bidi_class();\n    let not_e = if e == BidiClass::L {\n        BidiClass::R\n    } else {\n        BidiClass::L\n    };\n    // N0. Process bracket pairs.\n\n    // > Identify the bracket pairs in the current isolating run sequence according to BD16.\n    // We use processing_classes, not original_classes, due to BD14/BD15\n    let mut bracket_pairs = BracketPairVec::new();\n    identify_bracket_pairs(\n        text,\n        data_source,\n        sequence,\n        processing_classes,\n        &mut bracket_pairs,\n    );\n\n    // > For each bracket-pair element in the list of pairs of text positions\n    //\n    // Note: Rust ranges are interpreted as [start..end), be careful using `pair` directly\n    // for indexing as it will include the opening bracket pair but not the closing one.\n    for pair in bracket_pairs {\n        #[cfg(feature = \"std\")]\n        debug_assert!(\n            pair.start < processing_classes.len(),\n            \"identify_bracket_pairs returned a range that is out of bounds!\"\n        );\n        #[cfg(feature = \"std\")]\n        debug_assert!(\n            pair.end < processing_classes.len(),\n            \"identify_bracket_pairs returned a range that is out of bounds!\"\n        );\n        let mut found_e = false;\n        let mut found_not_e = false;\n        let mut class_to_set = None;\n\n        let start_char_len =\n            T::char_len(text.subrange(pair.start..pair.end).chars().next().unwrap());\n        // > Inspect the bidirectional types of the characters enclosed within the bracket pair.\n        //\n        // `pair` is [start, end) so we will end up processing the opening character but not the closing one.\n        //\n        for enclosed_i in sequence.iter_forwards_from(pair.start + start_char_len, pair.start_run) {\n            if enclosed_i >= pair.end {\n                #[cfg(feature = \"std\")]\n                debug_assert!(\n                    enclosed_i == pair.end,\n                    \"If we skipped past this, the iterator is broken\"\n                );\n                break;\n            }\n            let class = processing_classes[enclosed_i];\n            if class == e {\n                found_e = true;\n            } else if class == not_e {\n                found_not_e = true;\n            } else if matches!(class, BidiClass::EN | BidiClass::AN) {\n                // > Within this scope, bidirectional types EN and AN are treated as R.\n                if e == BidiClass::L {\n                    found_not_e = true;\n                } else {\n                    found_e = true;\n                }\n            }\n\n            // If we have found a character with the class of the embedding direction\n            // we can bail early.\n            if found_e {\n                break;\n            }\n        }\n        // > If any strong type (either L or R) matching the embedding direction is found\n        if found_e {\n            // > .. set the type for both brackets in the pair to match the embedding direction\n            class_to_set = Some(e);\n        // > Otherwise, if there is a strong type it must be opposite the embedding direction\n        } else if found_not_e {\n            // > Therefore, test for an established context with a preceding strong type by\n            // > checking backwards before the opening paired bracket\n            // > until the first strong type (L, R, or sos) is found.\n            // (see note above about processing_classes and character boundaries)\n            let mut previous_strong = sequence\n                .iter_backwards_from(pair.start, pair.start_run)\n                .map(|i| processing_classes[i])\n                .find(|class| {\n                    matches!(\n                        class,\n                        BidiClass::L | BidiClass::R | BidiClass::EN | BidiClass::AN\n                    )\n                })\n                .unwrap_or(sequence.sos);\n\n            // > Within this scope, bidirectional types EN and AN are treated as R.\n            if matches!(previous_strong, BidiClass::EN | BidiClass::AN) {\n                previous_strong = BidiClass::R;\n            }\n\n            // > If the preceding strong type is also opposite the embedding direction,\n            // > context is established,\n            // > so set the type for both brackets in the pair to that direction.\n            // AND\n            // > Otherwise set the type for both brackets in the pair to the embedding direction.\n            // > Either way it gets set to previous_strong\n            //\n            // Both branches amount to setting the type to the strong type.\n            class_to_set = Some(previous_strong);\n        }\n\n        if let Some(class_to_set) = class_to_set {\n            // Update all processing classes corresponding to the start and end elements, as requested.\n            // We should include all bytes of the character, not the first one.\n            let end_char_len =\n                T::char_len(text.subrange(pair.end..text.len()).chars().next().unwrap());\n            for class in &mut processing_classes[pair.start..pair.start + start_char_len] {\n                *class = class_to_set;\n            }\n            for class in &mut processing_classes[pair.end..pair.end + end_char_len] {\n                *class = class_to_set;\n            }\n            // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n            for idx in sequence.iter_backwards_from(pair.start, pair.start_run) {\n                let class = &mut processing_classes[idx];\n                if *class != BN {\n                    break;\n                }\n                *class = class_to_set;\n            }\n            // > Any number of characters that had original bidirectional character type NSM prior to the application of\n            // > W1 that immediately follow a paired bracket which changed to L or R under N0 should change to match the type of their preceding bracket.\n\n            // This rule deals with sequences of NSMs, so we can just update them all at once, we don't need to worry\n            // about character boundaries. We do need to be careful to skip the full set of bytes for the parentheses characters.\n            let nsm_start = pair.start + start_char_len;\n            for idx in sequence.iter_forwards_from(nsm_start, pair.start_run) {\n                let class = original_classes[idx];\n                if class == BidiClass::NSM || processing_classes[idx] == BN {\n                    processing_classes[idx] = class_to_set;\n                } else {\n                    break;\n                }\n            }\n            let nsm_end = pair.end + end_char_len;\n            for idx in sequence.iter_forwards_from(nsm_end, pair.end_run) {\n                let class = original_classes[idx];\n                if class == BidiClass::NSM || processing_classes[idx] == BN {\n                    processing_classes[idx] = class_to_set;\n                } else {\n                    break;\n                }\n            }\n        }\n        // > Otherwise, there are no strong types within the bracket pair\n        // > Therefore, do not set the type for that bracket pair\n    }\n\n    // N1 and N2.\n    // Indices of every byte in this isolating run sequence\n    let mut indices = sequence.runs.iter().flat_map(Clone::clone);\n    let mut prev_class = sequence.sos;\n    while let Some(mut i) = indices.next() {\n        // Process sequences of NI characters.\n        #[cfg(feature = \"smallvec\")]\n        let mut ni_run = SmallVec::<[usize; 8]>::new();\n        #[cfg(not(feature = \"smallvec\"))]\n        let mut ni_run = Vec::new();\n        // The BN is for <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n        if is_NI(processing_classes[i]) || processing_classes[i] == BN {\n            // Consume a run of consecutive NI characters.\n            ni_run.push(i);\n            let mut next_class;\n            loop {\n                match indices.next() {\n                    Some(j) => {\n                        i = j;\n                        next_class = processing_classes[j];\n                        // The BN is for <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n                        if is_NI(next_class) || next_class == BN {\n                            ni_run.push(i);\n                        } else {\n                            break;\n                        }\n                    }\n                    None => {\n                        next_class = sequence.eos;\n                        break;\n                    }\n                };\n            }\n            // N1-N2.\n            //\n            // <http://www.unicode.org/reports/tr9/#N1>\n            // <http://www.unicode.org/reports/tr9/#N2>\n            let new_class = match (prev_class, next_class) {\n                (L, L) => L,\n                (R, R)\n                | (R, AN)\n                | (R, EN)\n                | (AN, R)\n                | (AN, AN)\n                | (AN, EN)\n                | (EN, R)\n                | (EN, AN)\n                | (EN, EN) => R,\n                (_, _) => e,\n            };\n            for j in &ni_run {\n                processing_classes[*j] = new_class;\n            }\n            ni_run.clear();\n        }\n        prev_class = processing_classes[i];\n    }\n}\n\nstruct BracketPair {\n    /// The text-relative index of the opening bracket.\n    start: usize,\n    /// The text-relative index of the closing bracket.\n    end: usize,\n    /// The index of the run (in the run sequence) that the opening bracket is in.\n    start_run: usize,\n    /// The index of the run (in the run sequence) that the closing bracket is in.\n    end_run: usize,\n}\n/// 3.1.3 Identifying Bracket Pairs\n///\n/// Returns all paired brackets in the source, as indices into the\n/// text source.\n///\n/// <https://www.unicode.org/reports/tr9/#BD16>\nfn identify_bracket_pairs<'a, T: TextSource<'a> + ?Sized, D: BidiDataSource>(\n    text: &'a T,\n    data_source: &D,\n    run_sequence: &IsolatingRunSequence,\n    original_classes: &[BidiClass],\n    bracket_pairs: &mut BracketPairVec,\n) {\n    #[cfg(feature = \"smallvec\")]\n    let mut stack = SmallVec::<[(char, usize, usize); 8]>::new();\n    #[cfg(not(feature = \"smallvec\"))]\n    let mut stack = Vec::new();\n\n    for (run_index, level_run) in run_sequence.runs.iter().enumerate() {\n        for (i, ch) in text.subrange(level_run.clone()).char_indices() {\n            let actual_index = level_run.start + i;\n\n            // All paren characters are ON.\n            // From BidiBrackets.txt:\n            // > The Unicode property value stability policy guarantees that characters\n            // > which have bpt=o or bpt=c also have bc=ON and Bidi_M=Y\n            if original_classes[actual_index] != BidiClass::ON {\n                continue;\n            }\n\n            if let Some(matched) = data_source.bidi_matched_opening_bracket(ch) {\n                if matched.is_open {\n                    // > If an opening paired bracket is found ...\n\n                    // > ... and there is no room in the stack,\n                    // > stop processing BD16 for the remainder of the isolating run sequence.\n                    if stack.len() >= 63 {\n                        break;\n                    }\n                    // > ... push its Bidi_Paired_Bracket property value and its text position onto the stack\n                    stack.push((matched.opening, actual_index, run_index))\n                } else {\n                    // > If a closing paired bracket is found, do the following\n\n                    // > Declare a variable that holds a reference to the current stack element\n                    // > and initialize it with the top element of the stack.\n                    // AND\n                    // > Else, if the current stack element is not at the bottom of the stack\n                    for (stack_index, element) in stack.iter().enumerate().rev() {\n                        // > Compare the closing paired bracket being inspected or its canonical\n                        // > equivalent to the bracket in the current stack element.\n                        if element.0 == matched.opening {\n                            // > If the values match, meaning the two characters form a bracket pair, then\n\n                            // > Append the text position in the current stack element together with the\n                            // > text position of the closing paired bracket to the list.\n                            let pair = BracketPair {\n                                start: element.1,\n                                end: actual_index,\n                                start_run: element.2,\n                                end_run: run_index,\n                            };\n                            bracket_pairs.push(pair);\n\n                            // > Pop the stack through the current stack element inclusively.\n                            stack.truncate(stack_index);\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    // > Sort the list of pairs of text positions in ascending order based on\n    // > the text position of the opening paired bracket.\n    bracket_pairs.sort_by_key(|r| r.start);\n}\n\n/// 3.3.6 Resolving Implicit Levels\n///\n/// Returns the maximum embedding level in the paragraph.\n///\n/// <http://www.unicode.org/reports/tr9/#Resolving_Implicit_Levels>\n#[cfg_attr(feature = \"flame_it\", flamer::flame)]\npub fn resolve_levels(processing_classes: &[BidiClass], levels: &mut [Level]) -> Level {\n    let mut max_level = Level::ltr();\n    assert_eq!(processing_classes.len(), levels.len());\n    for i in 0..levels.len() {\n        match (levels[i].is_rtl(), processing_classes[i]) {\n            (false, AN) | (false, EN) => levels[i].raise(2).expect(\"Level number error\"),\n            (false, R) | (true, L) | (true, EN) | (true, AN) => {\n                levels[i].raise(1).expect(\"Level number error\")\n            }\n            // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters> handled here\n            (_, _) => {}\n        }\n        max_level = max(max_level, levels[i]);\n    }\n\n    max_level\n}\n\n/// Neutral or Isolate formatting character (B, S, WS, ON, FSI, LRI, RLI, PDI)\n///\n/// <http://www.unicode.org/reports/tr9/#NI>\n#[allow(non_snake_case)]\nfn is_NI(class: BidiClass) -> bool {\n    matches!(class, B | S | WS | ON | FSI | LRI | RLI | PDI)\n}\n"
    },
    {
      "package": "unicode-bidi@0.3.18",
      "sourcePath": "src/level.rs",
      "sha256": "ce1eaa9940f1b90bc59aba296488b8cd128aefeb4b6b2e3ecc34da26c569150b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2017 The Servo Project Developers. See the\n// COPYRIGHT file at the top-level directory of this distribution.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Bidi Embedding Level\n//!\n//! See [`Level`](struct.Level.html) for more details.\n//!\n//! <http://www.unicode.org/reports/tr9/#BD2>\n\nuse alloc::{\n    string::{String, ToString},\n    vec::Vec,\n};\nuse core::slice;\n\nuse super::char_data::BidiClass;\n\n/// Embedding Level\n///\n/// Embedding Levels are numbers between 0 and 126 (inclusive), where even values denote a\n/// left-to-right (LTR) direction and odd values a right-to-left (RTL) direction.\n///\n/// This struct maintains a *valid* status for level numbers, meaning that creating a new level, or\n/// mutating an existing level, with the value smaller than `0` (before conversion to `u8`) or\n/// larger than 125 results in an `Error`.\n///\n/// <http://www.unicode.org/reports/tr9/#BD2>\n#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]\n#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]\n#[repr(transparent)]\npub struct Level(u8);\n\npub const LTR_LEVEL: Level = Level(0);\npub const RTL_LEVEL: Level = Level(1);\n\nconst MAX_DEPTH: u8 = 125;\n/// During explicit level resolution, embedding level can go as high as `max_depth`.\npub const MAX_EXPLICIT_DEPTH: u8 = MAX_DEPTH;\n/// During implicit level resolution, embedding level can go as high as `max_depth + 1`.\npub const MAX_IMPLICIT_DEPTH: u8 = MAX_DEPTH + 1;\n\n/// Errors that can occur on Level creation or mutation\n#[derive(Debug, PartialEq)]\npub enum Error {\n    /// Out-of-range (invalid) embedding level number.\n    OutOfRangeNumber,\n}\n\nimpl Level {\n    /// New LTR level with smallest number value (0).\n    #[inline]\n    pub fn ltr() -> Level {\n        LTR_LEVEL\n    }\n\n    /// New RTL level with smallest number value (1).\n    #[inline]\n    pub fn rtl() -> Level {\n        RTL_LEVEL\n    }\n\n    /// Maximum depth of the directional status stack during implicit resolutions.\n    pub fn max_implicit_depth() -> u8 {\n        MAX_IMPLICIT_DEPTH\n    }\n\n    /// Maximum depth of the directional status stack during explicit resolutions.\n    pub fn max_explicit_depth() -> u8 {\n        MAX_EXPLICIT_DEPTH\n    }\n\n    // == Inquiries ==\n\n    /// Create new level, fail if number is larger than `max_depth + 1`.\n    #[inline]\n    pub fn new(number: u8) -> Result<Level, Error> {\n        if number <= MAX_IMPLICIT_DEPTH {\n            Ok(Level(number))\n        } else {\n            Err(Error::OutOfRangeNumber)\n        }\n    }\n\n    /// Create new level, fail if number is larger than `max_depth`.\n    #[inline]\n    pub fn new_explicit(number: u8) -> Result<Level, Error> {\n        if number <= MAX_EXPLICIT_DEPTH {\n            Ok(Level(number))\n        } else {\n            Err(Error::OutOfRangeNumber)\n        }\n    }\n\n    // == Inquiries ==\n\n    /// The level number.\n    #[inline]\n    pub fn number(&self) -> u8 {\n        self.0\n    }\n\n    /// If this level is left-to-right.\n    #[inline]\n    pub fn is_ltr(&self) -> bool {\n        self.0 % 2 == 0\n    }\n\n    /// If this level is right-to-left.\n    #[inline]\n    pub fn is_rtl(&self) -> bool {\n        self.0 % 2 == 1\n    }\n\n    // == Mutators ==\n\n    /// Raise level by `amount`, fail if number is larger than `max_depth + 1`.\n    #[inline]\n    pub fn raise(&mut self, amount: u8) -> Result<(), Error> {\n        match self.0.checked_add(amount) {\n            Some(number) => {\n                if number <= MAX_IMPLICIT_DEPTH {\n                    self.0 = number;\n                    Ok(())\n                } else {\n                    Err(Error::OutOfRangeNumber)\n                }\n            }\n            None => Err(Error::OutOfRangeNumber),\n        }\n    }\n\n    /// Raise level by `amount`, fail if number is larger than `max_depth`.\n    #[inline]\n    pub fn raise_explicit(&mut self, amount: u8) -> Result<(), Error> {\n        match self.0.checked_add(amount) {\n            Some(number) => {\n                if number <= MAX_EXPLICIT_DEPTH {\n                    self.0 = number;\n                    Ok(())\n                } else {\n                    Err(Error::OutOfRangeNumber)\n                }\n            }\n            None => Err(Error::OutOfRangeNumber),\n        }\n    }\n\n    /// Lower level by `amount`, fail if number goes below zero.\n    #[inline]\n    pub fn lower(&mut self, amount: u8) -> Result<(), Error> {\n        match self.0.checked_sub(amount) {\n            Some(number) => {\n                self.0 = number;\n                Ok(())\n            }\n            None => Err(Error::OutOfRangeNumber),\n        }\n    }\n\n    // == Helpers ==\n\n    /// The next LTR (even) level greater than this, or fail if number is larger than `max_depth`.\n    #[inline]\n    pub fn new_explicit_next_ltr(&self) -> Result<Level, Error> {\n        Level::new_explicit((self.0 + 2) & !1)\n    }\n\n    /// The next RTL (odd) level greater than this, or fail if number is larger than `max_depth`.\n    #[inline]\n    pub fn new_explicit_next_rtl(&self) -> Result<Level, Error> {\n        Level::new_explicit((self.0 + 1) | 1)\n    }\n\n    /// The lowest RTL (odd) level greater than or equal to this, or fail if number is larger than\n    /// `max_depth + 1`.\n    #[inline]\n    pub fn new_lowest_ge_rtl(&self) -> Result<Level, Error> {\n        Level::new(self.0 | 1)\n    }\n\n    /// Generate a character type based on a level (as specified in steps X10 and N2).\n    #[inline]\n    pub fn bidi_class(&self) -> BidiClass {\n        if self.is_rtl() {\n            BidiClass::R\n        } else {\n            BidiClass::L\n        }\n    }\n\n    pub fn vec(v: &[u8]) -> Vec<Level> {\n        v.iter().map(|&x| x.into()).collect()\n    }\n\n    /// Converts a byte slice to a slice of Levels\n    ///\n    /// Does _not_ check if each level is within bounds (`<=` [`MAX_IMPLICIT_DEPTH`]),\n    /// which is not a requirement for safety but is a requirement for correctness of the algorithm.\n    pub fn from_slice_unchecked(v: &[u8]) -> &[Level] {\n        debug_assert_eq!(core::mem::size_of::<u8>(), core::mem::size_of::<Level>());\n        unsafe {\n            // Safety: The two arrays are the same size and layout-compatible since\n            // Level is `repr(transparent)` over `u8`\n            slice::from_raw_parts(v as *const [u8] as *const u8 as *const Level, v.len())\n        }\n    }\n}\n\n/// If levels has any RTL (odd) level\n///\n/// This information is usually used to skip re-ordering of text when no RTL level is present\n#[inline]\npub fn has_rtl(levels: &[Level]) -> bool {\n    levels.iter().any(|&lvl| lvl.is_rtl())\n}\n\nimpl From<Level> for u8 {\n    /// Convert to the level number\n    #[inline]\n    fn from(val: Level) -> Self {\n        val.number()\n    }\n}\n\nimpl From<u8> for Level {\n    /// Create level by number\n    #[inline]\n    fn from(number: u8) -> Level {\n        Level::new(number).expect(\"Level number error\")\n    }\n}\n\n/// Used for matching levels in conformance tests\nimpl<'a> PartialEq<&'a str> for Level {\n    #[inline]\n    fn eq(&self, s: &&'a str) -> bool {\n        *s == \"x\" || *s == self.0.to_string()\n    }\n}\n\n/// Used for matching levels in conformance tests\nimpl PartialEq<String> for Level {\n    #[inline]\n    fn eq(&self, s: &String) -> bool {\n        self == &s.as_str()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_new() {\n        assert_eq!(Level::new(0), Ok(Level(0)));\n        assert_eq!(Level::new(1), Ok(Level(1)));\n        assert_eq!(Level::new(10), Ok(Level(10)));\n        assert_eq!(Level::new(125), Ok(Level(125)));\n        assert_eq!(Level::new(126), Ok(Level(126)));\n        assert_eq!(Level::new(127), Err(Error::OutOfRangeNumber));\n        assert_eq!(Level::new(255), Err(Error::OutOfRangeNumber));\n    }\n\n    #[test]\n    fn test_new_explicit() {\n        assert_eq!(Level::new_explicit(0), Ok(Level(0)));\n        assert_eq!(Level::new_explicit(1), Ok(Level(1)));\n        assert_eq!(Level::new_explicit(10), Ok(Level(10)));\n        assert_eq!(Level::new_explicit(125), Ok(Level(125)));\n        assert_eq!(Level::new_explicit(126), Err(Error::OutOfRangeNumber));\n        assert_eq!(Level::new_explicit(255), Err(Error::OutOfRangeNumber));\n    }\n\n    #[test]\n    fn test_is_ltr() {\n        assert_eq!(Level(0).is_ltr(), true);\n        assert_eq!(Level(1).is_ltr(), false);\n        assert_eq!(Level(10).is_ltr(), true);\n        assert_eq!(Level(11).is_ltr(), false);\n        assert_eq!(Level(124).is_ltr(), true);\n        assert_eq!(Level(125).is_ltr(), false);\n    }\n\n    #[test]\n    fn test_is_rtl() {\n        assert_eq!(Level(0).is_rtl(), false);\n        assert_eq!(Level(1).is_rtl(), true);\n        assert_eq!(Level(10).is_rtl(), false);\n        assert_eq!(Level(11).is_rtl(), true);\n        assert_eq!(Level(124).is_rtl(), false);\n        assert_eq!(Level(125).is_rtl(), true);\n    }\n\n    #[test]\n    fn test_raise() {\n        let mut level = Level::ltr();\n        assert_eq!(level.number(), 0);\n        assert!(level.raise(100).is_ok());\n        assert_eq!(level.number(), 100);\n        assert!(level.raise(26).is_ok());\n        assert_eq!(level.number(), 126);\n        assert!(level.raise(1).is_err()); // invalid!\n        assert!(level.raise(250).is_err()); // overflow!\n        assert_eq!(level.number(), 126);\n    }\n\n    #[test]\n    fn test_raise_explicit() {\n        let mut level = Level::ltr();\n        assert_eq!(level.number(), 0);\n        assert!(level.raise_explicit(100).is_ok());\n        assert_eq!(level.number(), 100);\n        assert!(level.raise_explicit(25).is_ok());\n        assert_eq!(level.number(), 125);\n        assert!(level.raise_explicit(1).is_err()); // invalid!\n        assert!(level.raise_explicit(250).is_err()); // overflow!\n        assert_eq!(level.number(), 125);\n    }\n\n    #[test]\n    fn test_lower() {\n        let mut level = Level::rtl();\n        assert_eq!(level.number(), 1);\n        assert!(level.lower(1).is_ok());\n        assert_eq!(level.number(), 0);\n        assert!(level.lower(1).is_err()); // underflow!\n        assert!(level.lower(250).is_err()); // underflow!\n        assert_eq!(level.number(), 0);\n    }\n\n    #[test]\n    fn test_has_rtl() {\n        assert_eq!(has_rtl(&Level::vec(&[0, 0, 0])), false);\n        assert_eq!(has_rtl(&Level::vec(&[0, 1, 0])), true);\n        assert_eq!(has_rtl(&Level::vec(&[0, 2, 0])), false);\n        assert_eq!(has_rtl(&Level::vec(&[0, 125, 0])), true);\n        assert_eq!(has_rtl(&Level::vec(&[0, 126, 0])), false);\n    }\n\n    #[test]\n    fn test_into() {\n        let level = Level::rtl();\n        let number: u8 = level.into();\n        assert_eq!(1u8, number);\n    }\n\n    #[test]\n    fn test_vec() {\n        assert_eq!(\n            Level::vec(&[0, 1, 125]),\n            vec![Level(0), Level(1), Level(125)]\n        );\n    }\n\n    #[test]\n    fn test_str_eq() {\n        assert_eq!(Level::vec(&[0, 1, 4, 125]), vec![\"0\", \"1\", \"x\", \"125\"]);\n        assert_ne!(Level::vec(&[0, 1, 4, 125]), vec![\"0\", \"1\", \"5\", \"125\"]);\n    }\n\n    #[test]\n    fn test_string_eq() {\n        assert_eq!(\n            Level::vec(&[0, 1, 4, 125]),\n            vec![\"0\".to_string(), \"1\".to_string(), \"x\".to_string(), \"125\".to_string()]\n        );\n    }\n}\n\n#[cfg(all(feature = \"serde\", test))]\nmod serde_tests {\n    use super::*;\n    use serde_test::{assert_tokens, Token};\n\n    #[test]\n    fn test_statics() {\n        assert_tokens(\n            &Level::ltr(),\n            &[Token::NewtypeStruct { name: \"Level\" }, Token::U8(0)],\n        );\n        assert_tokens(\n            &Level::rtl(),\n            &[Token::NewtypeStruct { name: \"Level\" }, Token::U8(1)],\n        );\n    }\n\n    #[test]\n    fn test_new() {\n        let level = Level::new(42).unwrap();\n        assert_tokens(\n            &level,\n            &[Token::NewtypeStruct { name: \"Level\" }, Token::U8(42)],\n        );\n    }\n}\n"
    },
    {
      "package": "unicode-bidi@0.3.18",
      "sourcePath": "src/lib.rs",
      "sha256": "8a611ccb9d56c176f8428edc14b1e6fc1fbe8ed22bc72118fb987e6a29638197",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Servo Project Developers. See the\n// COPYRIGHT file at the top-level directory of this distribution.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! This crate implements the [Unicode Bidirectional Algorithm][tr9] for display of mixed\n//! right-to-left and left-to-right text.  It is written in safe Rust, compatible with the\n//! current stable release.\n//!\n//! ## Example\n//!\n//! ```rust\n//! # #[cfg(feature = \"hardcoded-data\")] {\n//! use unicode_bidi::BidiInfo;\n//!\n//! // This example text is defined using `concat!` because some browsers\n//! // and text editors have trouble displaying bidi strings.\n//! let text = concat![\n//!   \"א\",\n//!   \"ב\",\n//!   \"ג\",\n//!   \"a\",\n//!   \"b\",\n//!   \"c\",\n//! ];\n//!\n//! // Resolve embedding levels within the text.  Pass `None` to detect the\n//! // paragraph level automatically.\n//! let bidi_info = BidiInfo::new(&text, None);\n//!\n//! // This paragraph has embedding level 1 because its first strong character is RTL.\n//! assert_eq!(bidi_info.paragraphs.len(), 1);\n//! let para = &bidi_info.paragraphs[0];\n//! assert_eq!(para.level.number(), 1);\n//! assert_eq!(para.level.is_rtl(), true);\n//!\n//! // Re-ordering is done after wrapping each paragraph into a sequence of\n//! // lines. For this example, I'll just use a single line that spans the\n//! // entire paragraph.\n//! let line = para.range.clone();\n//!\n//! let display = bidi_info.reorder_line(para, line);\n//! assert_eq!(display, concat![\n//!   \"a\",\n//!   \"b\",\n//!   \"c\",\n//!   \"ג\",\n//!   \"ב\",\n//!   \"א\",\n//! ]);\n//! # } // feature = \"hardcoded-data\"\n//! ```\n//!\n//! # Features\n//!\n//! - `std`: Enabled by default, but can be disabled to make `unicode_bidi`\n//!   `#![no_std]` + `alloc` compatible.\n//! - `hardcoded-data`: Enabled by default. Includes hardcoded Unicode bidi data and more convenient APIs.\n//! - `serde`: Adds [`serde::Serialize`] and [`serde::Deserialize`]\n//!   implementations to relevant types.\n//!\n//! [tr9]: <http://www.unicode.org/reports/tr9/>\n\n#![no_std]\n// We need to link to std to make doc tests work on older Rust versions\n#[cfg(feature = \"std\")]\nextern crate std;\n#[macro_use]\nextern crate alloc;\n#[cfg(feature = \"smallvec\")]\nextern crate smallvec;\n\npub mod data_source;\npub mod deprecated;\npub mod format_chars;\npub mod level;\npub mod utf16;\n\nmod char_data;\nmod explicit;\nmod implicit;\nmod prepare;\n\npub use crate::char_data::{BidiClass, UNICODE_VERSION};\npub use crate::data_source::BidiDataSource;\npub use crate::level::{Level, LTR_LEVEL, RTL_LEVEL};\npub use crate::prepare::{LevelRun, LevelRunVec};\n\n#[cfg(feature = \"hardcoded-data\")]\npub use crate::char_data::{bidi_class, HardcodedBidiData};\n\nuse alloc::borrow::Cow;\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse core::char;\nuse core::cmp;\nuse core::iter::repeat;\nuse core::ops::Range;\nuse core::str::CharIndices;\n#[cfg(feature = \"smallvec\")]\nuse smallvec::SmallVec;\n\nuse crate::format_chars as chars;\nuse crate::BidiClass::*;\n\n/// Trait that abstracts over a text source for use by the bidi algorithms.\n/// We implement this for str (UTF-8) and for [u16] (UTF-16, native-endian).\n/// (For internal unicode-bidi use; API may be unstable.)\n/// This trait is sealed and cannot be implemented for types outside this crate.\npub trait TextSource<'text>: private::Sealed {\n    type CharIter: Iterator<Item = char>;\n    type CharIndexIter: Iterator<Item = (usize, char)>;\n    type IndexLenIter: Iterator<Item = (usize, usize)>;\n\n    /// Return the length of the text in code units.\n    #[doc(hidden)]\n    fn len(&self) -> usize;\n\n    /// Get the character at a given code unit index, along with its length in code units.\n    /// Returns None if index is out of range, or points inside a multi-code-unit character.\n    /// Returns REPLACEMENT_CHARACTER for any unpaired surrogates in UTF-16.\n    #[doc(hidden)]\n    fn char_at(&self, index: usize) -> Option<(char, usize)>;\n\n    /// Return a subrange of the text, indexed by code units.\n    /// (We don't implement all of the Index trait, just the minimum we use.)\n    #[doc(hidden)]\n    fn subrange(&self, range: Range<usize>) -> &Self;\n\n    /// An iterator over the text returning Unicode characters,\n    /// REPLACEMENT_CHAR for invalid code units.\n    #[doc(hidden)]\n    fn chars(&'text self) -> Self::CharIter;\n\n    /// An iterator over the text returning (index, char) tuples,\n    /// where index is the starting code-unit index of the character,\n    /// and char is its Unicode value (or REPLACEMENT_CHAR if invalid).\n    #[doc(hidden)]\n    fn char_indices(&'text self) -> Self::CharIndexIter;\n\n    /// An iterator over the text returning (index, length) tuples,\n    /// where index is the starting code-unit index of the character,\n    /// and length is its length in code units.\n    #[doc(hidden)]\n    fn indices_lengths(&'text self) -> Self::IndexLenIter;\n\n    /// Number of code units the given character uses.\n    #[doc(hidden)]\n    fn char_len(ch: char) -> usize;\n}\n\nmod private {\n    pub trait Sealed {}\n\n    // Implement for str and [u16] only.\n    impl Sealed for str {}\n    impl Sealed for [u16] {}\n}\n\n#[derive(PartialEq, Debug)]\npub enum Direction {\n    Ltr,\n    Rtl,\n    Mixed,\n}\n\n/// Bidi information about a single paragraph\n#[derive(Clone, Debug, PartialEq)]\npub struct ParagraphInfo {\n    /// The paragraphs boundaries within the text, as byte indices.\n    ///\n    /// TODO: Shrink this to only include the starting index?\n    pub range: Range<usize>,\n\n    /// The paragraph embedding level.\n    ///\n    /// <http://www.unicode.org/reports/tr9/#BD4>\n    pub level: Level,\n}\n\nimpl ParagraphInfo {\n    /// Gets the length of the paragraph in the source text.\n    pub fn len(&self) -> usize {\n        self.range.end - self.range.start\n    }\n}\n\n/// Initial bidi information of the text.\n///\n/// Contains the text paragraphs and `BidiClass` of its characters.\n#[derive(PartialEq, Debug)]\npub struct InitialInfo<'text> {\n    /// The text\n    pub text: &'text str,\n\n    /// The BidiClass of the character at each byte in the text.\n    /// If a character is multiple bytes, its class will appear multiple times in the vector.\n    pub original_classes: Vec<BidiClass>,\n\n    /// The boundaries and level of each paragraph within the text.\n    pub paragraphs: Vec<ParagraphInfo>,\n}\n\nimpl<'text> InitialInfo<'text> {\n    /// Find the paragraphs and BidiClasses in a string of text.\n    ///\n    /// <http://www.unicode.org/reports/tr9/#The_Paragraph_Level>\n    ///\n    /// Also sets the class for each First Strong Isolate initiator (FSI) to LRI or RLI if a strong\n    /// character is found before the matching PDI.  If no strong character is found, the class will\n    /// remain FSI, and it's up to later stages to treat these as LRI when needed.\n    ///\n    /// The `hardcoded-data` Cargo feature (enabled by default) must be enabled to use this.\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[cfg(feature = \"hardcoded-data\")]\n    pub fn new(text: &str, default_para_level: Option<Level>) -> InitialInfo<'_> {\n        Self::new_with_data_source(&HardcodedBidiData, text, default_para_level)\n    }\n\n    /// Find the paragraphs and BidiClasses in a string of text, with a custom [`BidiDataSource`]\n    /// for Bidi data. If you just wish to use the hardcoded Bidi data, please use [`InitialInfo::new()`]\n    /// instead (enabled with tbe default `hardcoded-data` Cargo feature)\n    ///\n    /// <http://www.unicode.org/reports/tr9/#The_Paragraph_Level>\n    ///\n    /// Also sets the class for each First Strong Isolate initiator (FSI) to LRI or RLI if a strong\n    /// character is found before the matching PDI.  If no strong character is found, the class will\n    /// remain FSI, and it's up to later stages to treat these as LRI when needed.\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn new_with_data_source<'a, D: BidiDataSource>(\n        data_source: &D,\n        text: &'a str,\n        default_para_level: Option<Level>,\n    ) -> InitialInfo<'a> {\n        InitialInfoExt::new_with_data_source(data_source, text, default_para_level).base\n    }\n}\n\n/// Extended version of InitialInfo (not public API).\n#[derive(PartialEq, Debug)]\nstruct InitialInfoExt<'text> {\n    /// The base InitialInfo for the text, recording its paragraphs and bidi classes.\n    base: InitialInfo<'text>,\n\n    /// Parallel to base.paragraphs, records whether each paragraph is \"pure LTR\" that\n    /// requires no further bidi processing (i.e. there are no RTL characters or bidi\n    /// control codes present), and whether any bidi isolation controls are present.\n    flags: Vec<ParagraphInfoFlags>,\n}\n\n#[derive(PartialEq, Debug)]\nstruct ParagraphInfoFlags {\n    is_pure_ltr: bool,\n    has_isolate_controls: bool,\n}\n\nimpl<'text> InitialInfoExt<'text> {\n    /// Find the paragraphs and BidiClasses in a string of text, with a custom [`BidiDataSource`]\n    /// for Bidi data. If you just wish to use the hardcoded Bidi data, please use [`InitialInfo::new()`]\n    /// instead (enabled with tbe default `hardcoded-data` Cargo feature)\n    ///\n    /// <http://www.unicode.org/reports/tr9/#The_Paragraph_Level>\n    ///\n    /// Also sets the class for each First Strong Isolate initiator (FSI) to LRI or RLI if a strong\n    /// character is found before the matching PDI.  If no strong character is found, the class will\n    /// remain FSI, and it's up to later stages to treat these as LRI when needed.\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn new_with_data_source<'a, D: BidiDataSource>(\n        data_source: &D,\n        text: &'a str,\n        default_para_level: Option<Level>,\n    ) -> InitialInfoExt<'a> {\n        let mut paragraphs = Vec::<ParagraphInfo>::new();\n        let mut flags = Vec::<ParagraphInfoFlags>::new();\n        let (original_classes, _, _, _) = compute_initial_info(\n            data_source,\n            text,\n            default_para_level,\n            Some((&mut paragraphs, &mut flags)),\n        );\n\n        InitialInfoExt {\n            base: InitialInfo {\n                text,\n                original_classes,\n                paragraphs,\n            },\n            flags,\n        }\n    }\n}\n\n/// Implementation of initial-info computation for both BidiInfo and ParagraphBidiInfo.\n/// To treat the text as (potentially) multiple paragraphs, the caller should pass the\n/// pair of optional outparam arrays to receive the ParagraphInfo and pure-ltr flags\n/// for each paragraph. Passing None for split_paragraphs will ignore any paragraph-\n/// separator characters in the text, treating it just as a single paragraph.\n/// Returns the array of BidiClass values for each code unit of the text, along with\n/// the embedding level and pure-ltr flag for the *last* (or only) paragraph.\nfn compute_initial_info<'a, D: BidiDataSource, T: TextSource<'a> + ?Sized>(\n    data_source: &D,\n    text: &'a T,\n    default_para_level: Option<Level>,\n    mut split_paragraphs: Option<(&mut Vec<ParagraphInfo>, &mut Vec<ParagraphInfoFlags>)>,\n) -> (Vec<BidiClass>, Level, bool, bool) {\n    let mut original_classes = Vec::with_capacity(text.len());\n\n    // The stack contains the starting code unit index for each nested isolate we're inside.\n    #[cfg(feature = \"smallvec\")]\n    let mut isolate_stack = SmallVec::<[usize; 8]>::new();\n    #[cfg(not(feature = \"smallvec\"))]\n    let mut isolate_stack = Vec::new();\n\n    debug_assert!(\n        if let Some((ref paragraphs, ref flags)) = split_paragraphs {\n            paragraphs.is_empty() && flags.is_empty()\n        } else {\n            true\n        }\n    );\n\n    let mut para_start = 0;\n    let mut para_level = default_para_level;\n\n    // Per-paragraph flag: can subsequent processing be skipped? Set to false if any\n    // RTL characters or bidi control characters are encountered in the paragraph.\n    let mut is_pure_ltr = true;\n    // Set to true if any bidi isolation controls are present in the paragraph.\n    let mut has_isolate_controls = false;\n\n    #[cfg(feature = \"flame_it\")]\n    flame::start(\"compute_initial_info(): iter text.char_indices()\");\n\n    for (i, c) in text.char_indices() {\n        let class = data_source.bidi_class(c);\n\n        #[cfg(feature = \"flame_it\")]\n        flame::start(\"original_classes.extend()\");\n\n        let len = T::char_len(c);\n        original_classes.extend(repeat(class).take(len));\n\n        #[cfg(feature = \"flame_it\")]\n        flame::end(\"original_classes.extend()\");\n\n        match class {\n            B => {\n                if let Some((ref mut paragraphs, ref mut flags)) = split_paragraphs {\n                    // P1. Split the text into separate paragraphs. The paragraph separator is kept\n                    // with the previous paragraph.\n                    let para_end = i + len;\n                    paragraphs.push(ParagraphInfo {\n                        range: para_start..para_end,\n                        // P3. If no character is found in p2, set the paragraph level to zero.\n                        level: para_level.unwrap_or(LTR_LEVEL),\n                    });\n                    flags.push(ParagraphInfoFlags {\n                        is_pure_ltr,\n                        has_isolate_controls,\n                    });\n                    // Reset state for the start of the next paragraph.\n                    para_start = para_end;\n                    // TODO: Support defaulting to direction of previous paragraph\n                    //\n                    // <http://www.unicode.org/reports/tr9/#HL1>\n                    para_level = default_para_level;\n                    is_pure_ltr = true;\n                    has_isolate_controls = false;\n                    isolate_stack.clear();\n                }\n            }\n\n            L | R | AL => {\n                if class != L {\n                    is_pure_ltr = false;\n                }\n                match isolate_stack.last() {\n                    Some(&start) => {\n                        if original_classes[start] == FSI {\n                            // X5c. If the first strong character between FSI and its matching\n                            // PDI is R or AL, treat it as RLI. Otherwise, treat it as LRI.\n                            for j in 0..T::char_len(chars::FSI) {\n                                original_classes[start + j] = if class == L { LRI } else { RLI };\n                            }\n                        }\n                    }\n\n                    None => {\n                        if para_level.is_none() {\n                            // P2. Find the first character of type L, AL, or R, while skipping\n                            // any characters between an isolate initiator and its matching\n                            // PDI.\n                            para_level = Some(if class != L { RTL_LEVEL } else { LTR_LEVEL });\n                        }\n                    }\n                }\n            }\n\n            AN | LRE | RLE | LRO | RLO => {\n                is_pure_ltr = false;\n            }\n\n            RLI | LRI | FSI => {\n                is_pure_ltr = false;\n                has_isolate_controls = true;\n                isolate_stack.push(i);\n            }\n\n            PDI => {\n                isolate_stack.pop();\n            }\n\n            _ => {}\n        }\n    }\n\n    if let Some((paragraphs, flags)) = split_paragraphs {\n        if para_start < text.len() {\n            paragraphs.push(ParagraphInfo {\n                range: para_start..text.len(),\n                level: para_level.unwrap_or(LTR_LEVEL),\n            });\n            flags.push(ParagraphInfoFlags {\n                is_pure_ltr,\n                has_isolate_controls,\n            });\n        }\n        debug_assert_eq!(paragraphs.len(), flags.len());\n    }\n    debug_assert_eq!(original_classes.len(), text.len());\n\n    #[cfg(feature = \"flame_it\")]\n    flame::end(\"compute_initial_info(): iter text.char_indices()\");\n\n    (\n        original_classes,\n        para_level.unwrap_or(LTR_LEVEL),\n        is_pure_ltr,\n        has_isolate_controls,\n    )\n}\n\n/// Bidi information of the text.\n///\n/// The `original_classes` and `levels` vectors are indexed by byte offsets into the text.  If a\n/// character is multiple bytes wide, then its class and level will appear multiple times in these\n/// vectors.\n// TODO: Impl `struct StringProperty<T> { values: Vec<T> }` and use instead of Vec<T>\n#[derive(Debug, PartialEq)]\npub struct BidiInfo<'text> {\n    /// The text\n    pub text: &'text str,\n\n    /// The BidiClass of the character at each byte in the text.\n    pub original_classes: Vec<BidiClass>,\n\n    /// The directional embedding level of each byte in the text.\n    pub levels: Vec<Level>,\n\n    /// The boundaries and paragraph embedding level of each paragraph within the text.\n    ///\n    /// TODO: Use SmallVec or similar to avoid overhead when there are only one or two paragraphs?\n    /// Or just don't include the first paragraph, which always starts at 0?\n    pub paragraphs: Vec<ParagraphInfo>,\n}\n\nimpl<'text> BidiInfo<'text> {\n    /// Split the text into paragraphs and determine the bidi embedding levels for each paragraph.\n    ///\n    ///\n    /// The `hardcoded-data` Cargo feature (enabled by default) must be enabled to use this.\n    ///\n    /// TODO: In early steps, check for special cases that allow later steps to be skipped. like\n    /// text that is entirely LTR.  See the `nsBidi` class from Gecko for comparison.\n    ///\n    /// TODO: Support auto-RTL base direction\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[cfg(feature = \"hardcoded-data\")]\n    #[inline]\n    pub fn new(text: &str, default_para_level: Option<Level>) -> BidiInfo<'_> {\n        Self::new_with_data_source(&HardcodedBidiData, text, default_para_level)\n    }\n\n    /// Split the text into paragraphs and determine the bidi embedding levels for each paragraph, with a custom [`BidiDataSource`]\n    /// for Bidi data. If you just wish to use the hardcoded Bidi data, please use [`BidiInfo::new()`]\n    /// instead (enabled with tbe default `hardcoded-data` Cargo feature).\n    ///\n    /// TODO: In early steps, check for special cases that allow later steps to be skipped. like\n    /// text that is entirely LTR.  See the `nsBidi` class from Gecko for comparison.\n    ///\n    /// TODO: Support auto-RTL base direction\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn new_with_data_source<'a, D: BidiDataSource>(\n        data_source: &D,\n        text: &'a str,\n        default_para_level: Option<Level>,\n    ) -> BidiInfo<'a> {\n        let InitialInfoExt { base, flags, .. } =\n            InitialInfoExt::new_with_data_source(data_source, text, default_para_level);\n\n        let mut levels = Vec::<Level>::with_capacity(text.len());\n        let mut processing_classes = base.original_classes.clone();\n\n        for (para, flags) in base.paragraphs.iter().zip(flags.iter()) {\n            let text = &text[para.range.clone()];\n            let original_classes = &base.original_classes[para.range.clone()];\n\n            compute_bidi_info_for_para(\n                data_source,\n                para,\n                flags.is_pure_ltr,\n                flags.has_isolate_controls,\n                text,\n                original_classes,\n                &mut processing_classes,\n                &mut levels,\n            );\n        }\n\n        BidiInfo {\n            text,\n            original_classes: base.original_classes,\n            paragraphs: base.paragraphs,\n            levels,\n        }\n    }\n\n    /// Produce the levels for this paragraph as needed for reordering, one level per *byte*\n    /// in the paragraph. The returned vector includes bytes that are not included\n    /// in the `line`, but will not adjust them.\n    ///\n    /// This runs [Rule L1], you can run\n    /// [Rule L2] by calling [`Self::reorder_visual()`].\n    /// If doing so, you may prefer to use [`Self::reordered_levels_per_char()`] instead\n    /// to avoid non-byte indices.\n    ///\n    /// For an all-in-one reordering solution, consider using [`Self::reorder_visual()`].\n    ///\n    /// [Rule L1]: https://www.unicode.org/reports/tr9/#L1\n    /// [Rule L2]: https://www.unicode.org/reports/tr9/#L2\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reordered_levels(&self, para: &ParagraphInfo, line: Range<usize>) -> Vec<Level> {\n        assert!(line.start <= self.levels.len());\n        assert!(line.end <= self.levels.len());\n\n        let mut levels = self.levels.clone();\n        let line_classes = &self.original_classes[line.clone()];\n        let line_levels = &mut levels[line.clone()];\n\n        reorder_levels(\n            line_classes,\n            line_levels,\n            self.text.subrange(line),\n            para.level,\n        );\n\n        levels\n    }\n\n    /// Produce the levels for this paragraph as needed for reordering, one level per *character*\n    /// in the paragraph. The returned vector includes characters that are not included\n    /// in the `line`, but will not adjust them.\n    ///\n    /// This runs [Rule L1], you can run\n    /// [Rule L2] by calling [`Self::reorder_visual()`].\n    /// If doing so, you may prefer to use [`Self::reordered_levels_per_char()`] instead\n    /// to avoid non-byte indices.\n    ///\n    /// For an all-in-one reordering solution, consider using [`Self::reorder_visual()`].\n    ///\n    /// [Rule L1]: https://www.unicode.org/reports/tr9/#L1\n    /// [Rule L2]: https://www.unicode.org/reports/tr9/#L2\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reordered_levels_per_char(\n        &self,\n        para: &ParagraphInfo,\n        line: Range<usize>,\n    ) -> Vec<Level> {\n        let levels = self.reordered_levels(para, line);\n        self.text.char_indices().map(|(i, _)| levels[i]).collect()\n    }\n\n    /// Re-order a line based on resolved levels and return the line in display order.\n    ///\n    /// This does not apply [Rule L3] or [Rule L4] around combining characters or mirroring.\n    ///\n    /// [Rule L3]: https://www.unicode.org/reports/tr9/#L3\n    /// [Rule L4]: https://www.unicode.org/reports/tr9/#L4\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reorder_line(&self, para: &ParagraphInfo, line: Range<usize>) -> Cow<'text, str> {\n        if !level::has_rtl(&self.levels[line.clone()]) {\n            return self.text[line].into();\n        }\n        let (levels, runs) = self.visual_runs(para, line.clone());\n        reorder_line(self.text, line, levels, runs)\n    }\n\n    /// Reorders pre-calculated levels of a sequence of characters.\n    ///\n    /// NOTE: This is a convenience method that does not use a `Paragraph`  object. It is\n    /// intended to be used when an application has determined the levels of the objects (character sequences)\n    /// and just needs to have them reordered.\n    ///\n    /// the index map will result in `indexMap[visualIndex]==logicalIndex`.\n    ///\n    /// This only runs [Rule L2](http://www.unicode.org/reports/tr9/#L2) as it does not have\n    /// information about the actual text.\n    ///\n    /// Furthermore, if `levels` is an array that is aligned with code units, bytes within a codepoint may be\n    /// reversed. You may need to fix up the map to deal with this. Alternatively, only pass in arrays where each `Level`\n    /// is for a single code point.\n    ///\n    ///\n    ///   # # Example\n    /// ```\n    /// use unicode_bidi::BidiInfo;\n    /// use unicode_bidi::Level;\n    ///\n    /// let l0 = Level::from(0);\n    /// let l1 = Level::from(1);\n    /// let l2 = Level::from(2);\n    ///\n    /// let levels = vec![l0, l0, l0, l0];\n    /// let index_map = BidiInfo::reorder_visual(&levels);\n    /// assert_eq!(levels.len(), index_map.len());\n    /// assert_eq!(index_map, [0, 1, 2, 3]);\n    ///\n    /// let levels: Vec<Level> = vec![l0, l0, l0, l1, l1, l1, l2, l2];\n    /// let index_map = BidiInfo::reorder_visual(&levels);\n    /// assert_eq!(levels.len(), index_map.len());\n    /// assert_eq!(index_map, [0, 1, 2, 6, 7, 5, 4, 3]);\n    /// ```\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[inline]\n    pub fn reorder_visual(levels: &[Level]) -> Vec<usize> {\n        reorder_visual(levels)\n    }\n\n    /// Find the level runs within a line and return them in visual order.\n    ///\n    /// `line` is a range of bytes indices within `levels`.\n    ///\n    /// The first return value is a vector of levels used by the reordering algorithm,\n    /// i.e. the result of [Rule L1]. The second return value is a vector of level runs,\n    /// the result of [Rule L2], showing the visual order that each level run (a run of text with the\n    /// same level) should be displayed. Within each run, the display order can be checked\n    /// against the Level vector.\n    ///\n    /// This does not handle [Rule L3] (combining characters) or [Rule L4] (mirroring),\n    /// as that should be handled by the engine using this API.\n    ///\n    /// Conceptually, this is the same as running [`Self::reordered_levels()`] followed by\n    /// [`Self::reorder_visual()`], however it returns the result as a list of level runs instead\n    /// of producing a level map, since one may wish to deal with the fact that this is operating on\n    /// byte rather than character indices.\n    ///\n    /// <http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels>\n    ///\n    /// [Rule L1]: https://www.unicode.org/reports/tr9/#L1\n    /// [Rule L2]: https://www.unicode.org/reports/tr9/#L2\n    /// [Rule L3]: https://www.unicode.org/reports/tr9/#L3\n    /// [Rule L4]: https://www.unicode.org/reports/tr9/#L4\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[inline]\n    pub fn visual_runs(\n        &self,\n        para: &ParagraphInfo,\n        line: Range<usize>,\n    ) -> (Vec<Level>, Vec<LevelRun>) {\n        let levels = self.reordered_levels(para, line.clone());\n        visual_runs_for_line(levels, &line)\n    }\n\n    /// If processed text has any computed RTL levels\n    ///\n    /// This information is usually used to skip re-ordering of text when no RTL level is present\n    #[inline]\n    pub fn has_rtl(&self) -> bool {\n        level::has_rtl(&self.levels)\n    }\n}\n\n/// Bidi information of text treated as a single paragraph.\n///\n/// The `original_classes` and `levels` vectors are indexed by byte offsets into the text.  If a\n/// character is multiple bytes wide, then its class and level will appear multiple times in these\n/// vectors.\n#[derive(Debug, PartialEq)]\npub struct ParagraphBidiInfo<'text> {\n    /// The text\n    pub text: &'text str,\n\n    /// The BidiClass of the character at each byte in the text.\n    pub original_classes: Vec<BidiClass>,\n\n    /// The directional embedding level of each byte in the text.\n    pub levels: Vec<Level>,\n\n    /// The paragraph embedding level.\n    pub paragraph_level: Level,\n\n    /// Whether the paragraph is purely LTR.\n    pub is_pure_ltr: bool,\n}\n\nimpl<'text> ParagraphBidiInfo<'text> {\n    /// Determine the bidi embedding level.\n    ///\n    ///\n    /// The `hardcoded-data` Cargo feature (enabled by default) must be enabled to use this.\n    ///\n    /// TODO: In early steps, check for special cases that allow later steps to be skipped. like\n    /// text that is entirely LTR.  See the `nsBidi` class from Gecko for comparison.\n    ///\n    /// TODO: Support auto-RTL base direction\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[cfg(feature = \"hardcoded-data\")]\n    #[inline]\n    pub fn new(text: &str, default_para_level: Option<Level>) -> ParagraphBidiInfo<'_> {\n        Self::new_with_data_source(&HardcodedBidiData, text, default_para_level)\n    }\n\n    /// Determine the bidi embedding level, with a custom [`BidiDataSource`]\n    /// for Bidi data. If you just wish to use the hardcoded Bidi data, please use [`BidiInfo::new()`]\n    /// instead (enabled with tbe default `hardcoded-data` Cargo feature).\n    ///\n    /// (This is the single-paragraph equivalent of BidiInfo::new_with_data_source,\n    /// and should be kept in sync with it.\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn new_with_data_source<'a, D: BidiDataSource>(\n        data_source: &D,\n        text: &'a str,\n        default_para_level: Option<Level>,\n    ) -> ParagraphBidiInfo<'a> {\n        // Here we could create a ParagraphInitialInfo struct to parallel the one\n        // used by BidiInfo, but there doesn't seem any compelling reason for it.\n        let (original_classes, paragraph_level, is_pure_ltr, has_isolate_controls) =\n            compute_initial_info(data_source, text, default_para_level, None);\n\n        let mut levels = Vec::<Level>::with_capacity(text.len());\n        let mut processing_classes = original_classes.clone();\n\n        let para_info = ParagraphInfo {\n            range: Range {\n                start: 0,\n                end: text.len(),\n            },\n            level: paragraph_level,\n        };\n\n        compute_bidi_info_for_para(\n            data_source,\n            &para_info,\n            is_pure_ltr,\n            has_isolate_controls,\n            text,\n            &original_classes,\n            &mut processing_classes,\n            &mut levels,\n        );\n\n        ParagraphBidiInfo {\n            text,\n            original_classes,\n            levels,\n            paragraph_level,\n            is_pure_ltr,\n        }\n    }\n\n    /// Produce the levels for this paragraph as needed for reordering, one level per *byte*\n    /// in the paragraph. The returned vector includes bytes that are not included\n    /// in the `line`, but will not adjust them.\n    ///\n    /// See BidiInfo::reordered_levels for details.\n    ///\n    /// (This should be kept in sync with BidiInfo::reordered_levels.)\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reordered_levels(&self, line: Range<usize>) -> Vec<Level> {\n        assert!(line.start <= self.levels.len());\n        assert!(line.end <= self.levels.len());\n\n        let mut levels = self.levels.clone();\n        let line_classes = &self.original_classes[line.clone()];\n        let line_levels = &mut levels[line.clone()];\n\n        reorder_levels(\n            line_classes,\n            line_levels,\n            self.text.subrange(line),\n            self.paragraph_level,\n        );\n\n        levels\n    }\n\n    /// Produce the levels for this paragraph as needed for reordering, one level per *character*\n    /// in the paragraph. The returned vector includes characters that are not included\n    /// in the `line`, but will not adjust them.\n    ///\n    /// See BidiInfo::reordered_levels_per_char for details.\n    ///\n    /// (This should be kept in sync with BidiInfo::reordered_levels_per_char.)\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reordered_levels_per_char(&self, line: Range<usize>) -> Vec<Level> {\n        let levels = self.reordered_levels(line);\n        self.text.char_indices().map(|(i, _)| levels[i]).collect()\n    }\n\n    /// Re-order a line based on resolved levels and return the line in display order.\n    ///\n    /// See BidiInfo::reorder_line for details.\n    ///\n    /// (This should be kept in sync with BidiInfo::reorder_line.)\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reorder_line(&self, line: Range<usize>) -> Cow<'text, str> {\n        if !level::has_rtl(&self.levels[line.clone()]) {\n            return self.text[line].into();\n        }\n\n        let (levels, runs) = self.visual_runs(line.clone());\n\n        reorder_line(self.text, line, levels, runs)\n    }\n\n    /// Reorders pre-calculated levels of a sequence of characters.\n    ///\n    /// See BidiInfo::reorder_visual for details.\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[inline]\n    pub fn reorder_visual(levels: &[Level]) -> Vec<usize> {\n        reorder_visual(levels)\n    }\n\n    /// Find the level runs within a line and return them in visual order.\n    ///\n    /// `line` is a range of bytes indices within `levels`.\n    ///\n    /// See BidiInfo::visual_runs for details.\n    ///\n    /// (This should be kept in sync with BidiInfo::visual_runs.)\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[inline]\n    pub fn visual_runs(&self, line: Range<usize>) -> (Vec<Level>, Vec<LevelRun>) {\n        let levels = self.reordered_levels(line.clone());\n        visual_runs_for_line(levels, &line)\n    }\n\n    /// If processed text has any computed RTL levels\n    ///\n    /// This information is usually used to skip re-ordering of text when no RTL level is present\n    #[inline]\n    pub fn has_rtl(&self) -> bool {\n        !self.is_pure_ltr\n    }\n\n    /// Return the paragraph's Direction (Ltr, Rtl, or Mixed) based on its levels.\n    #[inline]\n    pub fn direction(&self) -> Direction {\n        para_direction(&self.levels)\n    }\n}\n\n/// Return a line of the text in display order based on resolved levels.\n///\n/// `text`   the full text passed to the `BidiInfo` or `ParagraphBidiInfo` for analysis\n/// `line`   a range of byte indices within `text` corresponding to one line\n/// `levels` array of `Level` values, with `line`'s levels reordered into visual order\n/// `runs`   array of `LevelRun`s in visual order\n///\n/// (`levels` and `runs` are the result of calling `BidiInfo::visual_runs()` or\n/// `ParagraphBidiInfo::visual_runs()` for the line of interest.)\n///\n/// Returns: the reordered text of the line.\n///\n/// This does not apply [Rule L3] or [Rule L4] around combining characters or mirroring.\n///\n/// [Rule L3]: https://www.unicode.org/reports/tr9/#L3\n/// [Rule L4]: https://www.unicode.org/reports/tr9/#L4\nfn reorder_line(\n    text: &str,\n    line: Range<usize>,\n    levels: Vec<Level>,\n    runs: Vec<LevelRun>,\n) -> Cow<'_, str> {\n    // If all isolating run sequences are LTR, no reordering is needed\n    if runs.iter().all(|run| levels[run.start].is_ltr()) {\n        return text[line].into();\n    }\n\n    let mut result = String::with_capacity(line.len());\n    for run in runs {\n        if levels[run.start].is_rtl() {\n            result.extend(text[run].chars().rev());\n        } else {\n            result.push_str(&text[run]);\n        }\n    }\n    result.into()\n}\n\n/// Find the level runs within a line and return them in visual order.\n///\n/// `line` is a range of code-unit indices within `levels`.\n///\n/// The first return value is a vector of levels used by the reordering algorithm,\n/// i.e. the result of [Rule L1]. The second return value is a vector of level runs,\n/// the result of [Rule L2], showing the visual order that each level run (a run of text with the\n/// same level) should be displayed. Within each run, the display order can be checked\n/// against the Level vector.\n///\n/// This does not handle [Rule L3] (combining characters) or [Rule L4] (mirroring),\n/// as that should be handled by the engine using this API.\n///\n/// Conceptually, this is the same as running [`reordered_levels()`] followed by\n/// [`reorder_visual()`], however it returns the result as a list of level runs instead\n/// of producing a level map, since one may wish to deal with the fact that this is operating on\n/// byte rather than character indices.\n///\n/// <http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels>\n///\n/// [Rule L1]: https://www.unicode.org/reports/tr9/#L1\n/// [Rule L2]: https://www.unicode.org/reports/tr9/#L2\n/// [Rule L3]: https://www.unicode.org/reports/tr9/#L3\n/// [Rule L4]: https://www.unicode.org/reports/tr9/#L4\nfn visual_runs_for_line(levels: Vec<Level>, line: &Range<usize>) -> (Vec<Level>, Vec<LevelRun>) {\n    // Find consecutive level runs.\n    let mut runs = Vec::new();\n    let mut start = line.start;\n    let mut run_level = levels[start];\n    let mut min_level = run_level;\n    let mut max_level = run_level;\n\n    for (i, &new_level) in levels.iter().enumerate().take(line.end).skip(start + 1) {\n        if new_level != run_level {\n            // End of the previous run, start of a new one.\n            runs.push(start..i);\n            start = i;\n            run_level = new_level;\n            min_level = cmp::min(run_level, min_level);\n            max_level = cmp::max(run_level, max_level);\n        }\n    }\n    runs.push(start..line.end);\n\n    let run_count = runs.len();\n\n    // Re-order the odd runs.\n    // <http://www.unicode.org/reports/tr9/#L2>\n\n    // Stop at the lowest *odd* level.\n    min_level = min_level.new_lowest_ge_rtl().expect(\"Level error\");\n    // This loop goes through contiguous chunks of level runs that have a level\n    // ≥ max_level and reverses their contents, reducing max_level by 1 each time.\n    while max_level >= min_level {\n        // Look for the start of a sequence of consecutive runs of max_level or higher.\n        let mut seq_start = 0;\n        while seq_start < run_count {\n            if levels[runs[seq_start].start] < max_level {\n                seq_start += 1;\n                continue;\n            }\n\n            // Found the start of a sequence. Now find the end.\n            let mut seq_end = seq_start + 1;\n            while seq_end < run_count {\n                if levels[runs[seq_end].start] < max_level {\n                    break;\n                }\n                seq_end += 1;\n            }\n            // Reverse the runs within this sequence.\n            runs[seq_start..seq_end].reverse();\n\n            seq_start = seq_end;\n        }\n        max_level\n            .lower(1)\n            .expect(\"Lowering embedding level below zero\");\n    }\n    (levels, runs)\n}\n\n/// Reorders pre-calculated levels of a sequence of characters.\n///\n/// NOTE: This is a convenience method that does not use a `Paragraph`  object. It is\n/// intended to be used when an application has determined the levels of the objects (character sequences)\n/// and just needs to have them reordered.\n///\n/// the index map will result in `indexMap[visualIndex]==logicalIndex`.\n///\n/// This only runs [Rule L2](http://www.unicode.org/reports/tr9/#L2) as it does not have\n/// information about the actual text.\n///\n/// Furthermore, if `levels` is an array that is aligned with code units, bytes within a codepoint may be\n/// reversed. You may need to fix up the map to deal with this. Alternatively, only pass in arrays where each `Level`\n/// is for a single code point.\nfn reorder_visual(levels: &[Level]) -> Vec<usize> {\n    // Gets the next range of characters after start_index with a level greater\n    // than or equal to `max`\n    fn next_range(levels: &[level::Level], mut start_index: usize, max: Level) -> Range<usize> {\n        if levels.is_empty() || start_index >= levels.len() {\n            return start_index..start_index;\n        }\n        while let Some(l) = levels.get(start_index) {\n            if *l >= max {\n                break;\n            }\n            start_index += 1;\n        }\n\n        if levels.get(start_index).is_none() {\n            // If at the end of the array, adding one will\n            // produce an out-of-range end element\n            return start_index..start_index;\n        }\n\n        let mut end_index = start_index + 1;\n        while let Some(l) = levels.get(end_index) {\n            if *l < max {\n                return start_index..end_index;\n            }\n            end_index += 1;\n        }\n\n        start_index..end_index\n    }\n\n    // This implementation is similar to the L2 implementation in `visual_runs()`\n    // but it cannot benefit from a precalculated LevelRun vector so needs to be different.\n\n    if levels.is_empty() {\n        return vec![];\n    }\n\n    // Get the min and max levels\n    let (mut min, mut max) = levels\n        .iter()\n        .fold((levels[0], levels[0]), |(min, max), &l| {\n            (cmp::min(min, l), cmp::max(max, l))\n        });\n\n    // Initialize an index map\n    let mut result: Vec<usize> = (0..levels.len()).collect();\n\n    if min == max && min.is_ltr() {\n        // Everything is LTR and at the same level, do nothing\n        return result;\n    }\n\n    // Stop at the lowest *odd* level, since everything below that\n    // is LTR and does not need further reordering\n    min = min.new_lowest_ge_rtl().expect(\"Level error\");\n\n    // For each max level, take all contiguous chunks of\n    // levels ≥ max and reverse them\n    //\n    // We can do this check with the original levels instead of checking reorderings because all\n    // prior reorderings will have been for contiguous chunks of levels >> max, which will\n    // be a subset of these chunks anyway.\n    while min <= max {\n        let mut range = 0..0;\n        loop {\n            range = next_range(levels, range.end, max);\n            result[range.clone()].reverse();\n\n            if range.end >= levels.len() {\n                break;\n            }\n        }\n\n        max.lower(1).expect(\"Level error\");\n    }\n\n    result\n}\n\n/// The core of BidiInfo initialization, factored out into a function that both\n/// the utf-8 and utf-16 versions of BidiInfo can use.\nfn compute_bidi_info_for_para<'a, D: BidiDataSource, T: TextSource<'a> + ?Sized>(\n    data_source: &D,\n    para: &ParagraphInfo,\n    is_pure_ltr: bool,\n    has_isolate_controls: bool,\n    text: &'a T,\n    original_classes: &[BidiClass],\n    processing_classes: &mut [BidiClass],\n    levels: &mut Vec<Level>,\n) {\n    let new_len = levels.len() + para.range.len();\n    levels.resize(new_len, para.level);\n    if para.level == LTR_LEVEL && is_pure_ltr {\n        return;\n    }\n\n    let processing_classes = &mut processing_classes[para.range.clone()];\n    let levels = &mut levels[para.range.clone()];\n    let mut level_runs = LevelRunVec::new();\n\n    explicit::compute(\n        text,\n        para.level,\n        original_classes,\n        levels,\n        processing_classes,\n        &mut level_runs,\n    );\n\n    let mut sequences = prepare::IsolatingRunSequenceVec::new();\n    prepare::isolating_run_sequences(\n        para.level,\n        original_classes,\n        levels,\n        level_runs,\n        has_isolate_controls,\n        &mut sequences,\n    );\n    for sequence in &sequences {\n        implicit::resolve_weak(text, sequence, processing_classes);\n        implicit::resolve_neutral(\n            text,\n            data_source,\n            sequence,\n            levels,\n            original_classes,\n            processing_classes,\n        );\n    }\n\n    implicit::resolve_levels(processing_classes, levels);\n\n    assign_levels_to_removed_chars(para.level, original_classes, levels);\n}\n\n/// Produce the levels for this paragraph as needed for reordering, one level per *code unit*\n/// in the paragraph. The returned vector includes code units that are not included\n/// in the `line`, but will not adjust them.\n///\n/// This runs [Rule L1]\n///\n/// [Rule L1]: https://www.unicode.org/reports/tr9/#L1\nfn reorder_levels<'a, T: TextSource<'a> + ?Sized>(\n    line_classes: &[BidiClass],\n    line_levels: &mut [Level],\n    line_text: &'a T,\n    para_level: Level,\n) {\n    // Reset some whitespace chars to paragraph level.\n    // <http://www.unicode.org/reports/tr9/#L1>\n    let mut reset_from: Option<usize> = Some(0);\n    let mut reset_to: Option<usize> = None;\n    let mut prev_level = para_level;\n    for ((i, c), (_, length)) in line_text.char_indices().zip(line_text.indices_lengths()) {\n        match line_classes[i] {\n            // Segment separator, Paragraph separator\n            B | S => {\n                assert_eq!(reset_to, None);\n                reset_to = Some(i + T::char_len(c));\n                if reset_from.is_none() {\n                    reset_from = Some(i);\n                }\n            }\n            // Whitespace, isolate formatting\n            WS | FSI | LRI | RLI | PDI => {\n                if reset_from.is_none() {\n                    reset_from = Some(i);\n                }\n            }\n            // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n            // same as above + set the level\n            RLE | LRE | RLO | LRO | PDF | BN => {\n                if reset_from.is_none() {\n                    reset_from = Some(i);\n                }\n                // also set the level to previous\n                for level in &mut line_levels[i..i + length] {\n                    *level = prev_level;\n                }\n            }\n            _ => {\n                reset_from = None;\n            }\n        }\n        if let (Some(from), Some(to)) = (reset_from, reset_to) {\n            for level in &mut line_levels[from..to] {\n                *level = para_level;\n            }\n            reset_from = None;\n            reset_to = None;\n        }\n        prev_level = line_levels[i];\n    }\n    if let Some(from) = reset_from {\n        for level in &mut line_levels[from..] {\n            *level = para_level;\n        }\n    }\n}\n\n/// Contains a reference of `BidiInfo` and one of its `paragraphs`.\n/// And it supports all operation in the `Paragraph` that needs also its\n/// `BidiInfo` such as `direction`.\n#[derive(Debug)]\npub struct Paragraph<'a, 'text> {\n    pub info: &'a BidiInfo<'text>,\n    pub para: &'a ParagraphInfo,\n}\n\nimpl<'a, 'text> Paragraph<'a, 'text> {\n    #[inline]\n    pub fn new(info: &'a BidiInfo<'text>, para: &'a ParagraphInfo) -> Paragraph<'a, 'text> {\n        Paragraph { info, para }\n    }\n\n    /// Returns if the paragraph is Left direction, right direction or mixed.\n    #[inline]\n    pub fn direction(&self) -> Direction {\n        para_direction(&self.info.levels[self.para.range.clone()])\n    }\n\n    /// Returns the `Level` of a certain character in the paragraph.\n    #[inline]\n    pub fn level_at(&self, pos: usize) -> Level {\n        let actual_position = self.para.range.start + pos;\n        self.info.levels[actual_position]\n    }\n}\n\n/// Return the directionality of the paragraph (Left, Right or Mixed) from its levels.\n#[cfg_attr(feature = \"flame_it\", flamer::flame)]\nfn para_direction(levels: &[Level]) -> Direction {\n    let mut ltr = false;\n    let mut rtl = false;\n    for level in levels {\n        if level.is_ltr() {\n            ltr = true;\n            if rtl {\n                return Direction::Mixed;\n            }\n        }\n\n        if level.is_rtl() {\n            rtl = true;\n            if ltr {\n                return Direction::Mixed;\n            }\n        }\n    }\n\n    if ltr {\n        return Direction::Ltr;\n    }\n\n    Direction::Rtl\n}\n\n/// Assign levels to characters removed by rule X9.\n///\n/// The levels assigned to these characters are not specified by the algorithm.  This function\n/// assigns each one the level of the previous character, to avoid breaking level runs.\n#[cfg_attr(feature = \"flame_it\", flamer::flame)]\nfn assign_levels_to_removed_chars(para_level: Level, classes: &[BidiClass], levels: &mut [Level]) {\n    for i in 0..levels.len() {\n        if prepare::removed_by_x9(classes[i]) {\n            levels[i] = if i > 0 { levels[i - 1] } else { para_level };\n        }\n    }\n}\n\n/// Get the base direction of the text provided according to the Unicode Bidirectional Algorithm.\n///\n/// See rules P2 and P3.\n///\n/// The base direction is derived from the first character in the string with bidi character type\n/// L, R, or AL. If the first such character has type L, Direction::Ltr is returned. If the first\n/// such character has type R or AL, Direction::Rtl is returned.\n///\n/// If the string does not contain any character of these types (outside of embedded isolate runs),\n/// then Direction::Mixed is returned (but should be considered as meaning \"neutral\" or \"unknown\",\n/// not in fact mixed directions).\n///\n/// This is a lightweight function for use when only the base direction is needed and no further\n/// bidi processing of the text is needed.\n///\n/// If the text contains paragraph separators, this function considers only the first paragraph.\n#[cfg(feature = \"hardcoded-data\")]\n#[inline]\npub fn get_base_direction<'a, T: TextSource<'a> + ?Sized>(text: &'a T) -> Direction {\n    get_base_direction_with_data_source(&HardcodedBidiData, text)\n}\n\n/// Get the base direction of the text provided according to the Unicode Bidirectional Algorithm,\n/// considering the full text if the first paragraph is all-neutral.\n///\n/// This is the same as get_base_direction except that it does not stop at the first block\n/// separator, but just resets the embedding level and continues to look for a strongly-\n/// directional character. So the result will be the base direction of the first paragraph\n/// that is not purely neutral characters.\n#[cfg(feature = \"hardcoded-data\")]\n#[inline]\npub fn get_base_direction_full<'a, T: TextSource<'a> + ?Sized>(text: &'a T) -> Direction {\n    get_base_direction_full_with_data_source(&HardcodedBidiData, text)\n}\n\n#[inline]\npub fn get_base_direction_with_data_source<'a, D: BidiDataSource, T: TextSource<'a> + ?Sized>(\n    data_source: &D,\n    text: &'a T,\n) -> Direction {\n    get_base_direction_impl(data_source, text, false)\n}\n\n#[inline]\npub fn get_base_direction_full_with_data_source<\n    'a,\n    D: BidiDataSource,\n    T: TextSource<'a> + ?Sized,\n>(\n    data_source: &D,\n    text: &'a T,\n) -> Direction {\n    get_base_direction_impl(data_source, text, true)\n}\n\nfn get_base_direction_impl<'a, D: BidiDataSource, T: TextSource<'a> + ?Sized>(\n    data_source: &D,\n    text: &'a T,\n    use_full_text: bool,\n) -> Direction {\n    let mut isolate_level = 0;\n    for c in text.chars() {\n        match data_source.bidi_class(c) {\n            LRI | RLI | FSI => isolate_level += 1,\n            PDI if isolate_level > 0 => isolate_level -= 1,\n            L if isolate_level == 0 => return Direction::Ltr,\n            R | AL if isolate_level == 0 => return Direction::Rtl,\n            B if !use_full_text => break,\n            B if use_full_text => isolate_level = 0,\n            _ => (),\n        }\n    }\n    // If no strong char was found, return Mixed. Normally this will be treated as Ltr by callers\n    // (see rule P3), but we don't map this to Ltr here so that a caller that wants to apply other\n    // heuristics to an all-neutral paragraph can tell the difference.\n    Direction::Mixed\n}\n\n/// Implementation of TextSource for UTF-8 text (a string slice).\nimpl<'text> TextSource<'text> for str {\n    type CharIter = core::str::Chars<'text>;\n    type CharIndexIter = core::str::CharIndices<'text>;\n    type IndexLenIter = Utf8IndexLenIter<'text>;\n\n    #[inline]\n    fn len(&self) -> usize {\n        (self as &str).len()\n    }\n    #[inline]\n    fn char_at(&self, index: usize) -> Option<(char, usize)> {\n        if let Some(slice) = self.get(index..) {\n            if let Some(ch) = slice.chars().next() {\n                return Some((ch, ch.len_utf8()));\n            }\n        }\n        None\n    }\n    #[inline]\n    fn subrange(&self, range: Range<usize>) -> &Self {\n        &(self as &str)[range]\n    }\n    #[inline]\n    fn chars(&'text self) -> Self::CharIter {\n        (self as &str).chars()\n    }\n    #[inline]\n    fn char_indices(&'text self) -> Self::CharIndexIter {\n        (self as &str).char_indices()\n    }\n    #[inline]\n    fn indices_lengths(&'text self) -> Self::IndexLenIter {\n        Utf8IndexLenIter::new(self)\n    }\n    #[inline]\n    fn char_len(ch: char) -> usize {\n        ch.len_utf8()\n    }\n}\n\n/// Iterator over (UTF-8) string slices returning (index, char_len) tuple.\n#[derive(Debug)]\npub struct Utf8IndexLenIter<'text> {\n    iter: CharIndices<'text>,\n}\n\nimpl<'text> Utf8IndexLenIter<'text> {\n    #[inline]\n    pub fn new(text: &'text str) -> Self {\n        Utf8IndexLenIter {\n            iter: text.char_indices(),\n        }\n    }\n}\n\nimpl Iterator for Utf8IndexLenIter<'_> {\n    type Item = (usize, usize);\n\n    #[inline]\n    fn next(&mut self) -> Option<Self::Item> {\n        if let Some((pos, ch)) = self.iter.next() {\n            return Some((pos, ch.len_utf8()));\n        }\n        None\n    }\n}\n\n#[cfg(test)]\nfn to_utf16(s: &str) -> Vec<u16> {\n    s.encode_utf16().collect()\n}\n\n#[cfg(test)]\n#[cfg(feature = \"hardcoded-data\")]\nmod tests {\n    use super::*;\n\n    use utf16::{\n        BidiInfo as BidiInfoU16, InitialInfo as InitialInfoU16, Paragraph as ParagraphU16,\n        ParagraphBidiInfo as ParagraphBidiInfoU16,\n    };\n\n    #[test]\n    fn test_utf16_text_source() {\n        let text: &[u16] =\n            &[0x41, 0xD801, 0xDC01, 0x20, 0xD800, 0x20, 0xDFFF, 0x20, 0xDC00, 0xD800];\n        assert_eq!(text.char_at(0), Some(('A', 1)));\n        assert_eq!(text.char_at(1), Some(('\\u{10401}', 2)));\n        assert_eq!(text.char_at(2), None);\n        assert_eq!(text.char_at(3), Some((' ', 1)));\n        assert_eq!(text.char_at(4), Some((char::REPLACEMENT_CHARACTER, 1)));\n        assert_eq!(text.char_at(5), Some((' ', 1)));\n        assert_eq!(text.char_at(6), Some((char::REPLACEMENT_CHARACTER, 1)));\n        assert_eq!(text.char_at(7), Some((' ', 1)));\n        assert_eq!(text.char_at(8), Some((char::REPLACEMENT_CHARACTER, 1)));\n        assert_eq!(text.char_at(9), Some((char::REPLACEMENT_CHARACTER, 1)));\n        assert_eq!(text.char_at(10), None);\n    }\n\n    #[test]\n    fn test_utf16_char_iter() {\n        let text: &[u16] =\n            &[0x41, 0xD801, 0xDC01, 0x20, 0xD800, 0x20, 0xDFFF, 0x20, 0xDC00, 0xD800];\n        assert_eq!(text.len(), 10);\n        assert_eq!(text.chars().count(), 9);\n        let mut chars = text.chars();\n        assert_eq!(chars.next(), Some('A'));\n        assert_eq!(chars.next(), Some('\\u{10401}'));\n        assert_eq!(chars.next(), Some(' '));\n        assert_eq!(chars.next(), Some('\\u{FFFD}'));\n        assert_eq!(chars.next(), Some(' '));\n        assert_eq!(chars.next(), Some('\\u{FFFD}'));\n        assert_eq!(chars.next(), Some(' '));\n        assert_eq!(chars.next(), Some('\\u{FFFD}'));\n        assert_eq!(chars.next(), Some('\\u{FFFD}'));\n        assert_eq!(chars.next(), None);\n    }\n\n    #[test]\n    fn test_initial_text_info() {\n        let tests = vec![\n            (\n                // text\n                \"a1\",\n                // expected bidi classes per utf-8 byte\n                vec![L, EN],\n                // expected paragraph-info for utf-8\n                vec![ParagraphInfo {\n                    range: 0..2,\n                    level: LTR_LEVEL,\n                }],\n                // expected bidi classes per utf-16 code unit\n                vec![L, EN],\n                // expected paragraph-info for utf-16\n                vec![ParagraphInfo {\n                    range: 0..2,\n                    level: LTR_LEVEL,\n                }],\n            ),\n            (\n                // Arabic, space, Hebrew\n                \"\\u{0639} \\u{05D0}\",\n                vec![AL, AL, WS, R, R],\n                vec![ParagraphInfo {\n                    range: 0..5,\n                    level: RTL_LEVEL,\n                }],\n                vec![AL, WS, R],\n                vec![ParagraphInfo {\n                    range: 0..3,\n                    level: RTL_LEVEL,\n                }],\n            ),\n            (\n                // SMP characters from Kharoshthi, Cuneiform, Adlam:\n                \"\\u{10A00}\\u{12000}\\u{1E900}\",\n                vec![R, R, R, R, L, L, L, L, R, R, R, R],\n                vec![ParagraphInfo {\n                    range: 0..12,\n                    level: RTL_LEVEL,\n                }],\n                vec![R, R, L, L, R, R],\n                vec![ParagraphInfo {\n                    range: 0..6,\n                    level: RTL_LEVEL,\n                }],\n            ),\n            (\n                \"a\\u{2029}b\",\n                vec![L, B, B, B, L],\n                vec![\n                    ParagraphInfo {\n                        range: 0..4,\n                        level: LTR_LEVEL,\n                    },\n                    ParagraphInfo {\n                        range: 4..5,\n                        level: LTR_LEVEL,\n                    },\n                ],\n                vec![L, B, L],\n                vec![\n                    ParagraphInfo {\n                        range: 0..2,\n                        level: LTR_LEVEL,\n                    },\n                    ParagraphInfo {\n                        range: 2..3,\n                        level: LTR_LEVEL,\n                    },\n                ],\n            ),\n            (\n                \"\\u{2068}א\\u{2069}a\", // U+2068 FSI, U+2069 PDI\n                vec![RLI, RLI, RLI, R, R, PDI, PDI, PDI, L],\n                vec![ParagraphInfo {\n                    range: 0..9,\n                    level: LTR_LEVEL,\n                }],\n                vec![RLI, R, PDI, L],\n                vec![ParagraphInfo {\n                    range: 0..4,\n                    level: LTR_LEVEL,\n                }],\n            ),\n        ];\n\n        for t in tests {\n            assert_eq!(\n                InitialInfo::new(t.0, None),\n                InitialInfo {\n                    text: t.0,\n                    original_classes: t.1,\n                    paragraphs: t.2,\n                }\n            );\n            let text = &to_utf16(t.0);\n            assert_eq!(\n                InitialInfoU16::new(text, None),\n                InitialInfoU16 {\n                    text,\n                    original_classes: t.3,\n                    paragraphs: t.4,\n                }\n            );\n        }\n    }\n\n    #[test]\n    #[cfg(feature = \"hardcoded-data\")]\n    fn test_process_text() {\n        let tests = vec![\n            (\n                // text\n                \"\",\n                // base level\n                Some(RTL_LEVEL),\n                // levels\n                Level::vec(&[]),\n                // original_classes\n                vec![],\n                // paragraphs\n                vec![],\n                // levels_u16\n                Level::vec(&[]),\n                // original_classes_u16\n                vec![],\n                // paragraphs_u16\n                vec![],\n            ),\n            (\n                // text\n                \"abc123\",\n                // base level\n                Some(LTR_LEVEL),\n                // levels\n                Level::vec(&[0, 0, 0, 0, 0, 0]),\n                // original_classes\n                vec![L, L, L, EN, EN, EN],\n                // paragraphs\n                vec![ParagraphInfo {\n                    range: 0..6,\n                    level: LTR_LEVEL,\n                }],\n                // levels_u16\n                Level::vec(&[0, 0, 0, 0, 0, 0]),\n                // original_classes_u16\n                vec![L, L, L, EN, EN, EN],\n                // paragraphs_u16\n                vec![ParagraphInfo {\n                    range: 0..6,\n                    level: LTR_LEVEL,\n                }],\n            ),\n            (\n                \"abc \\u{05D0}\\u{05D1}\\u{05D2}\",\n                Some(LTR_LEVEL),\n                Level::vec(&[0, 0, 0, 0, 1, 1, 1, 1, 1, 1]),\n                vec![L, L, L, WS, R, R, R, R, R, R],\n                vec![ParagraphInfo {\n                    range: 0..10,\n                    level: LTR_LEVEL,\n                }],\n                Level::vec(&[0, 0, 0, 0, 1, 1, 1]),\n                vec![L, L, L, WS, R, R, R],\n                vec![ParagraphInfo {\n                    range: 0..7,\n                    level: LTR_LEVEL,\n                }],\n            ),\n            (\n                \"abc \\u{05D0}\\u{05D1}\\u{05D2}\",\n                Some(RTL_LEVEL),\n                Level::vec(&[2, 2, 2, 1, 1, 1, 1, 1, 1, 1]),\n                vec![L, L, L, WS, R, R, R, R, R, R],\n                vec![ParagraphInfo {\n                    range: 0..10,\n                    level: RTL_LEVEL,\n                }],\n                Level::vec(&[2, 2, 2, 1, 1, 1, 1]),\n                vec![L, L, L, WS, R, R, R],\n                vec![ParagraphInfo {\n                    range: 0..7,\n                    level: RTL_LEVEL,\n                }],\n            ),\n            (\n                \"\\u{05D0}\\u{05D1}\\u{05D2} abc\",\n                Some(LTR_LEVEL),\n                Level::vec(&[1, 1, 1, 1, 1, 1, 0, 0, 0, 0]),\n                vec![R, R, R, R, R, R, WS, L, L, L],\n                vec![ParagraphInfo {\n                    range: 0..10,\n                    level: LTR_LEVEL,\n                }],\n                Level::vec(&[1, 1, 1, 0, 0, 0, 0]),\n                vec![R, R, R, WS, L, L, L],\n                vec![ParagraphInfo {\n                    range: 0..7,\n                    level: LTR_LEVEL,\n                }],\n            ),\n            (\n                \"\\u{05D0}\\u{05D1}\\u{05D2} abc\",\n                None,\n                Level::vec(&[1, 1, 1, 1, 1, 1, 1, 2, 2, 2]),\n                vec![R, R, R, R, R, R, WS, L, L, L],\n                vec![ParagraphInfo {\n                    range: 0..10,\n                    level: RTL_LEVEL,\n                }],\n                Level::vec(&[1, 1, 1, 1, 2, 2, 2]),\n                vec![R, R, R, WS, L, L, L],\n                vec![ParagraphInfo {\n                    range: 0..7,\n                    level: RTL_LEVEL,\n                }],\n            ),\n            (\n                \"\\u{063A}2\\u{0638} \\u{05D0}2\\u{05D2}\",\n                Some(LTR_LEVEL),\n                Level::vec(&[1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1]),\n                vec![AL, AL, EN, AL, AL, WS, R, R, EN, R, R],\n                vec![ParagraphInfo {\n                    range: 0..11,\n                    level: LTR_LEVEL,\n                }],\n                Level::vec(&[1, 2, 1, 1, 1, 2, 1]),\n                vec![AL, EN, AL, WS, R, EN, R],\n                vec![ParagraphInfo {\n                    range: 0..7,\n                    level: LTR_LEVEL,\n                }],\n            ),\n            (\n                \"a א.\\nג\",\n                None,\n                Level::vec(&[0, 0, 1, 1, 0, 0, 1, 1]),\n                vec![L, WS, R, R, CS, B, R, R],\n                vec![\n                    ParagraphInfo {\n                        range: 0..6,\n                        level: LTR_LEVEL,\n                    },\n                    ParagraphInfo {\n                        range: 6..8,\n                        level: RTL_LEVEL,\n                    },\n                ],\n                Level::vec(&[0, 0, 1, 0, 0, 1]),\n                vec![L, WS, R, CS, B, R],\n                vec![\n                    ParagraphInfo {\n                        range: 0..5,\n                        level: LTR_LEVEL,\n                    },\n                    ParagraphInfo {\n                        range: 5..6,\n                        level: RTL_LEVEL,\n                    },\n                ],\n            ),\n            // BidiTest:69635 (AL ET EN)\n            (\n                \"\\u{060B}\\u{20CF}\\u{06F9}\",\n                None,\n                Level::vec(&[1, 1, 1, 1, 1, 2, 2]),\n                vec![AL, AL, ET, ET, ET, EN, EN],\n                vec![ParagraphInfo {\n                    range: 0..7,\n                    level: RTL_LEVEL,\n                }],\n                Level::vec(&[1, 1, 2]),\n                vec![AL, ET, EN],\n                vec![ParagraphInfo {\n                    range: 0..3,\n                    level: RTL_LEVEL,\n                }],\n            ),\n        ];\n\n        for t in tests {\n            assert_eq!(\n                BidiInfo::new(t.0, t.1),\n                BidiInfo {\n                    text: t.0,\n                    levels: t.2.clone(),\n                    original_classes: t.3.clone(),\n                    paragraphs: t.4.clone(),\n                }\n            );\n            // If it was empty, also test that ParagraphBidiInfo handles it safely.\n            if t.4.len() == 0 {\n                assert_eq!(\n                    ParagraphBidiInfo::new(t.0, t.1),\n                    ParagraphBidiInfo {\n                        text: t.0,\n                        original_classes: t.3.clone(),\n                        levels: t.2.clone(),\n                        paragraph_level: RTL_LEVEL,\n                        is_pure_ltr: true,\n                    }\n                )\n            }\n            // If it was a single paragraph, also test ParagraphBidiInfo.\n            if t.4.len() == 1 {\n                assert_eq!(\n                    ParagraphBidiInfo::new(t.0, t.1),\n                    ParagraphBidiInfo {\n                        text: t.0,\n                        original_classes: t.3,\n                        levels: t.2.clone(),\n                        paragraph_level: t.4[0].level,\n                        is_pure_ltr: !level::has_rtl(&t.2),\n                    }\n                )\n            }\n            let text = &to_utf16(t.0);\n            assert_eq!(\n                BidiInfoU16::new(text, t.1),\n                BidiInfoU16 {\n                    text,\n                    levels: t.5.clone(),\n                    original_classes: t.6.clone(),\n                    paragraphs: t.7.clone(),\n                }\n            );\n            if t.7.len() == 1 {\n                assert_eq!(\n                    ParagraphBidiInfoU16::new(text, t.1),\n                    ParagraphBidiInfoU16 {\n                        text: text,\n                        original_classes: t.6.clone(),\n                        levels: t.5.clone(),\n                        paragraph_level: t.7[0].level,\n                        is_pure_ltr: !level::has_rtl(&t.5),\n                    }\n                )\n            }\n        }\n    }\n\n    #[test]\n    #[cfg(feature = \"hardcoded-data\")]\n    fn test_paragraph_bidi_info() {\n        // Passing text that includes a paragraph break to the ParagraphBidiInfo API:\n        // this is a misuse of the API by the client, but our behavior is safe &\n        // consistent. The embedded paragraph break acts like a separator (tab) would.\n        let tests = vec![\n            (\n                \"a א.\\nג\",\n                None,\n                // utf-8 results:\n                vec![L, WS, R, R, CS, B, R, R],\n                Level::vec(&[0, 0, 1, 1, 1, 1, 1, 1]),\n                // utf-16 results:\n                vec![L, WS, R, CS, B, R],\n                Level::vec(&[0, 0, 1, 1, 1, 1]),\n                // paragraph level; is_pure_ltr\n                LTR_LEVEL,\n                false,\n            ),\n            (\n                \"\\u{5d1} a.\\nb.\",\n                None,\n                // utf-8 results:\n                vec![R, R, WS, L, CS, B, L, CS],\n                Level::vec(&[1, 1, 1, 2, 2, 2, 2, 1]),\n                // utf-16 results:\n                vec![R, WS, L, CS, B, L, CS],\n                Level::vec(&[1, 1, 2, 2, 2, 2, 1]),\n                // paragraph level; is_pure_ltr\n                RTL_LEVEL,\n                false,\n            ),\n            (\n                \"a א.\\tג\",\n                None,\n                // utf-8 results:\n                vec![L, WS, R, R, CS, S, R, R],\n                Level::vec(&[0, 0, 1, 1, 1, 1, 1, 1]),\n                // utf-16 results:\n                vec![L, WS, R, CS, S, R],\n                Level::vec(&[0, 0, 1, 1, 1, 1]),\n                // paragraph level; is_pure_ltr\n                LTR_LEVEL,\n                false,\n            ),\n            (\n                \"\\u{5d1} a.\\tb.\",\n                None,\n                // utf-8 results:\n                vec![R, R, WS, L, CS, S, L, CS],\n                Level::vec(&[1, 1, 1, 2, 2, 2, 2, 1]),\n                // utf-16 results:\n                vec![R, WS, L, CS, S, L, CS],\n                Level::vec(&[1, 1, 2, 2, 2, 2, 1]),\n                // paragraph level; is_pure_ltr\n                RTL_LEVEL,\n                false,\n            ),\n        ];\n\n        for t in tests {\n            assert_eq!(\n                ParagraphBidiInfo::new(t.0, t.1),\n                ParagraphBidiInfo {\n                    text: t.0,\n                    original_classes: t.2,\n                    levels: t.3,\n                    paragraph_level: t.6,\n                    is_pure_ltr: t.7,\n                }\n            );\n            let text = &to_utf16(t.0);\n            assert_eq!(\n                ParagraphBidiInfoU16::new(text, t.1),\n                ParagraphBidiInfoU16 {\n                    text: text,\n                    original_classes: t.4,\n                    levels: t.5,\n                    paragraph_level: t.6,\n                    is_pure_ltr: t.7,\n                }\n            );\n        }\n    }\n\n    #[test]\n    #[cfg(feature = \"hardcoded-data\")]\n    fn test_bidi_info_has_rtl() {\n        let tests = vec![\n            // ASCII only\n            (\"123\", None, false),\n            (\"123\", Some(LTR_LEVEL), false),\n            (\"123\", Some(RTL_LEVEL), false),\n            (\"abc\", None, false),\n            (\"abc\", Some(LTR_LEVEL), false),\n            (\"abc\", Some(RTL_LEVEL), false),\n            (\"abc 123\", None, false),\n            (\"abc\\n123\", None, false),\n            // With Hebrew\n            (\"\\u{05D0}\\u{05D1}\\u{05BC}\\u{05D2}\", None, true),\n            (\"\\u{05D0}\\u{05D1}\\u{05BC}\\u{05D2}\", Some(LTR_LEVEL), true),\n            (\"\\u{05D0}\\u{05D1}\\u{05BC}\\u{05D2}\", Some(RTL_LEVEL), true),\n            (\"abc \\u{05D0}\\u{05D1}\\u{05BC}\\u{05D2}\", None, true),\n            (\"abc\\n\\u{05D0}\\u{05D1}\\u{05BC}\\u{05D2}\", None, true),\n            (\"\\u{05D0}\\u{05D1}\\u{05BC}\\u{05D2} abc\", None, true),\n            (\"\\u{05D0}\\u{05D1}\\u{05BC}\\u{05D2}\\nabc\", None, true),\n            (\"\\u{05D0}\\u{05D1}\\u{05BC}\\u{05D2} 123\", None, true),\n            (\"\\u{05D0}\\u{05D1}\\u{05BC}\\u{05D2}\\n123\", None, true),\n        ];\n\n        for t in tests {\n            assert_eq!(BidiInfo::new(t.0, t.1).has_rtl(), t.2);\n            assert_eq!(BidiInfoU16::new(&to_utf16(t.0), t.1).has_rtl(), t.2);\n        }\n    }\n\n    #[cfg(feature = \"hardcoded-data\")]\n    fn reorder_paras(text: &str) -> Vec<Cow<'_, str>> {\n        let bidi_info = BidiInfo::new(text, None);\n        bidi_info\n            .paragraphs\n            .iter()\n            .map(|para| bidi_info.reorder_line(para, para.range.clone()))\n            .collect()\n    }\n\n    #[cfg(feature = \"hardcoded-data\")]\n    fn reorder_paras_u16(text: &[u16]) -> Vec<Cow<'_, [u16]>> {\n        let bidi_info = BidiInfoU16::new(text, None);\n        bidi_info\n            .paragraphs\n            .iter()\n            .map(|para| bidi_info.reorder_line(para, para.range.clone()))\n            .collect()\n    }\n\n    #[test]\n    #[cfg(feature = \"hardcoded-data\")]\n    fn test_reorder_line() {\n        let tests = vec![\n            // Bidi_Class: L L L B L L L B L L L\n            (\"abc\\ndef\\nghi\", vec![\"abc\\n\", \"def\\n\", \"ghi\"]),\n            // Bidi_Class: L L EN B L L EN B L L EN\n            (\"ab1\\nde2\\ngh3\", vec![\"ab1\\n\", \"de2\\n\", \"gh3\"]),\n            // Bidi_Class: L L L B AL AL AL\n            (\"abc\\nابج\", vec![\"abc\\n\", \"جبا\"]),\n            // Bidi_Class: AL AL AL B L L L\n            (\n                \"\\u{0627}\\u{0628}\\u{062C}\\nabc\",\n                vec![\"\\n\\u{062C}\\u{0628}\\u{0627}\", \"abc\"],\n            ),\n            (\"1.-2\", vec![\"1.-2\"]),\n            (\"1-.2\", vec![\"1-.2\"]),\n            (\"abc אבג\", vec![\"abc גבא\"]),\n            // Numbers being weak LTR characters, cannot reorder strong RTL\n            (\"123 \\u{05D0}\\u{05D1}\\u{05D2}\", vec![\"גבא 123\"]),\n            (\"abc\\u{202A}def\", vec![\"abc\\u{202A}def\"]),\n            (\n                \"abc\\u{202A}def\\u{202C}ghi\",\n                vec![\"abc\\u{202A}def\\u{202C}ghi\"],\n            ),\n            (\n                \"abc\\u{2066}def\\u{2069}ghi\",\n                vec![\"abc\\u{2066}def\\u{2069}ghi\"],\n            ),\n            // Testing for RLE Character\n            (\"\\u{202B}abc אבג\\u{202C}\", vec![\"\\u{202b}גבא abc\\u{202c}\"]),\n            // Testing neutral characters\n            (\"\\u{05D0}בג? אבג\", vec![\"גבא ?גבא\"]),\n            // Testing neutral characters with special case\n            (\"A אבג?\", vec![\"A גבא?\"]),\n            // Testing neutral characters with Implicit RTL Marker\n            (\"A אבג?\\u{200F}\", vec![\"A \\u{200F}?גבא\"]),\n            (\"\\u{05D0}בג abc\", vec![\"abc גבא\"]),\n            (\"abc\\u{2067}.-\\u{2069}ghi\", vec![\"abc\\u{2067}-.\\u{2069}ghi\"]),\n            (\n                \"Hello, \\u{2068}\\u{202E}world\\u{202C}\\u{2069}!\",\n                vec![\"Hello, \\u{2068}\\u{202E}\\u{202C}dlrow\\u{2069}!\"],\n            ),\n            // With mirrorable characters in RTL run\n            (\"\\u{05D0}(ב)ג.\", vec![\".ג)ב(א\"]),\n            // With mirrorable characters on level boundary\n            (\"\\u{05D0}ב(גד[&ef].)gh\", vec![\"gh).]ef&[דג(בא\"]),\n        ];\n\n        for t in tests {\n            assert_eq!(reorder_paras(t.0), t.1);\n            let expect_utf16 = t.1.iter().map(|v| to_utf16(v)).collect::<Vec<_>>();\n            assert_eq!(reorder_paras_u16(&to_utf16(t.0)), expect_utf16);\n        }\n    }\n\n    fn reordered_levels_for_paras(text: &str) -> Vec<Vec<Level>> {\n        let bidi_info = BidiInfo::new(text, None);\n        bidi_info\n            .paragraphs\n            .iter()\n            .map(|para| bidi_info.reordered_levels(para, para.range.clone()))\n            .collect()\n    }\n\n    fn reordered_levels_per_char_for_paras(text: &str) -> Vec<Vec<Level>> {\n        let bidi_info = BidiInfo::new(text, None);\n        bidi_info\n            .paragraphs\n            .iter()\n            .map(|para| bidi_info.reordered_levels_per_char(para, para.range.clone()))\n            .collect()\n    }\n\n    fn reordered_levels_for_paras_u16(text: &[u16]) -> Vec<Vec<Level>> {\n        let bidi_info = BidiInfoU16::new(text, None);\n        bidi_info\n            .paragraphs\n            .iter()\n            .map(|para| bidi_info.reordered_levels(para, para.range.clone()))\n            .collect()\n    }\n\n    fn reordered_levels_per_char_for_paras_u16(text: &[u16]) -> Vec<Vec<Level>> {\n        let bidi_info = BidiInfoU16::new(text, None);\n        bidi_info\n            .paragraphs\n            .iter()\n            .map(|para| bidi_info.reordered_levels_per_char(para, para.range.clone()))\n            .collect()\n    }\n\n    #[test]\n    #[cfg(feature = \"hardcoded-data\")]\n    // See issue #138\n    fn test_reordered_levels_range() {\n        //                |---------------|\n        let s = \"\\u{202a}A\\u{202c}\\u{202a}A\\u{202c}\";\n        let range = 4..11;\n        assert!(s.get(range.clone()).is_some());\n\n        let bidi = BidiInfo::new(s, None);\n        let (_, runs) = bidi.visual_runs(&bidi.paragraphs[0], range);\n\n        for run in runs {\n            let _ = &s[run]; // should be valid slice of s\n        }\n    }\n\n    #[test]\n    #[cfg(feature = \"hardcoded-data\")]\n    fn test_reordered_levels() {\n        let tests = vec![\n            // BidiTest:946 (LRI PDI)\n            (\n                \"\\u{2067}\\u{2069}\",\n                vec![Level::vec(&[0, 0, 0, 0, 0, 0])],\n                vec![Level::vec(&[0, 0])],\n                vec![Level::vec(&[0, 0])],\n            ),\n            // BidiTest:69635 (AL ET EN)\n            (\n                \"\\u{060B}\\u{20CF}\\u{06F9}\",\n                vec![Level::vec(&[1, 1, 1, 1, 1, 2, 2])],\n                vec![Level::vec(&[1, 1, 2])],\n                vec![Level::vec(&[1, 1, 2])],\n            ),\n        ];\n\n        for t in tests {\n            assert_eq!(reordered_levels_for_paras(t.0), t.1);\n            assert_eq!(reordered_levels_per_char_for_paras(t.0), t.2);\n            let text = &to_utf16(t.0);\n            assert_eq!(reordered_levels_for_paras_u16(text), t.3);\n            assert_eq!(reordered_levels_per_char_for_paras_u16(text), t.2);\n        }\n\n        let tests = vec![\n            // BidiTest:291284 (AN RLI PDF R)\n            (\n                \"\\u{0605}\\u{2067}\\u{202C}\\u{0590}\",\n                vec![&[\"2\", \"2\", \"0\", \"0\", \"0\", \"x\", \"x\", \"x\", \"1\", \"1\"]],\n                vec![&[\"2\", \"0\", \"x\", \"1\"]],\n                vec![&[\"2\", \"0\", \"x\", \"1\"]],\n            ),\n        ];\n\n        for t in tests {\n            assert_eq!(reordered_levels_for_paras(t.0), t.1);\n            assert_eq!(reordered_levels_per_char_for_paras(t.0), t.2);\n            let text = &to_utf16(t.0);\n            assert_eq!(reordered_levels_for_paras_u16(text), t.3);\n            assert_eq!(reordered_levels_per_char_for_paras_u16(text), t.2);\n        }\n\n        let text = \"aa טֶ\";\n        let bidi_info = BidiInfo::new(text, None);\n        assert_eq!(\n            bidi_info.reordered_levels(&bidi_info.paragraphs[0], 3..7),\n            Level::vec(&[0, 0, 0, 1, 1, 1, 1]),\n        );\n\n        let text = &to_utf16(text);\n        let bidi_info = BidiInfoU16::new(text, None);\n        assert_eq!(\n            bidi_info.reordered_levels(&bidi_info.paragraphs[0], 1..4),\n            Level::vec(&[0, 0, 0, 1, 1]),\n        );\n    }\n\n    #[test]\n    fn test_paragraph_info_len() {\n        let text = \"hello world\";\n        let bidi_info = BidiInfo::new(text, None);\n        assert_eq!(bidi_info.paragraphs.len(), 1);\n        assert_eq!(bidi_info.paragraphs[0].len(), text.len());\n\n        let text2 = \"How are you\";\n        let whole_text = format!(\"{}\\n{}\", text, text2);\n        let bidi_info = BidiInfo::new(&whole_text, None);\n        assert_eq!(bidi_info.paragraphs.len(), 2);\n\n        // The first paragraph include the paragraph separator.\n        // TODO: investigate if the paragraph separator character\n        // should not be part of any paragraph.\n        assert_eq!(bidi_info.paragraphs[0].len(), text.len() + 1);\n        assert_eq!(bidi_info.paragraphs[1].len(), text2.len());\n\n        let text = &to_utf16(text);\n        let bidi_info = BidiInfoU16::new(text, None);\n        assert_eq!(bidi_info.paragraphs.len(), 1);\n        assert_eq!(bidi_info.paragraphs[0].len(), text.len());\n\n        let text2 = &to_utf16(text2);\n        let whole_text = &to_utf16(&whole_text);\n        let bidi_info = BidiInfoU16::new(&whole_text, None);\n        assert_eq!(bidi_info.paragraphs.len(), 2);\n\n        assert_eq!(bidi_info.paragraphs[0].len(), text.len() + 1);\n        assert_eq!(bidi_info.paragraphs[1].len(), text2.len());\n    }\n\n    #[test]\n    fn test_direction() {\n        let ltr_text = \"hello world\";\n        let rtl_text = \"أهلا بكم\";\n        let all_paragraphs = format!(\"{}\\n{}\\n{}{}\", ltr_text, rtl_text, ltr_text, rtl_text);\n        let bidi_info = BidiInfo::new(&all_paragraphs, None);\n        assert_eq!(bidi_info.paragraphs.len(), 3);\n        let p_ltr = Paragraph::new(&bidi_info, &bidi_info.paragraphs[0]);\n        let p_rtl = Paragraph::new(&bidi_info, &bidi_info.paragraphs[1]);\n        let p_mixed = Paragraph::new(&bidi_info, &bidi_info.paragraphs[2]);\n        assert_eq!(p_ltr.direction(), Direction::Ltr);\n        assert_eq!(p_rtl.direction(), Direction::Rtl);\n        assert_eq!(p_mixed.direction(), Direction::Mixed);\n\n        let all_paragraphs = &to_utf16(&all_paragraphs);\n        let bidi_info = BidiInfoU16::new(&all_paragraphs, None);\n        assert_eq!(bidi_info.paragraphs.len(), 3);\n        let p_ltr = ParagraphU16::new(&bidi_info, &bidi_info.paragraphs[0]);\n        let p_rtl = ParagraphU16::new(&bidi_info, &bidi_info.paragraphs[1]);\n        let p_mixed = ParagraphU16::new(&bidi_info, &bidi_info.paragraphs[2]);\n        assert_eq!(p_ltr.direction(), Direction::Ltr);\n        assert_eq!(p_rtl.direction(), Direction::Rtl);\n        assert_eq!(p_mixed.direction(), Direction::Mixed);\n    }\n\n    #[test]\n    fn test_edge_cases_direction() {\n        // No paragraphs for empty text.\n        let empty = \"\";\n        let bidi_info = BidiInfo::new(empty, Option::from(RTL_LEVEL));\n        assert_eq!(bidi_info.paragraphs.len(), 0);\n\n        let empty = &to_utf16(empty);\n        let bidi_info = BidiInfoU16::new(empty, Option::from(RTL_LEVEL));\n        assert_eq!(bidi_info.paragraphs.len(), 0);\n\n        let tests = vec![\n            // The paragraph separator will take the value of the default direction\n            // which is left to right.\n            (\"\\n\", None, Direction::Ltr),\n            // The paragraph separator will take the value of the given initial direction\n            // which is left to right.\n            (\"\\n\", Option::from(LTR_LEVEL), Direction::Ltr),\n            // The paragraph separator will take the value of the given initial direction\n            // which is right to left.\n            (\"\\n\", Option::from(RTL_LEVEL), Direction::Rtl),\n        ];\n\n        for t in tests {\n            let bidi_info = BidiInfo::new(t.0, t.1);\n            assert_eq!(bidi_info.paragraphs.len(), 1);\n            let p = Paragraph::new(&bidi_info, &bidi_info.paragraphs[0]);\n            assert_eq!(p.direction(), t.2);\n            let text = &to_utf16(t.0);\n            let bidi_info = BidiInfoU16::new(text, t.1);\n            let p = ParagraphU16::new(&bidi_info, &bidi_info.paragraphs[0]);\n            assert_eq!(p.direction(), t.2);\n        }\n    }\n\n    #[test]\n    fn test_level_at() {\n        let ltr_text = \"hello world\";\n        let rtl_text = \"أهلا بكم\";\n        let all_paragraphs = format!(\"{}\\n{}\\n{}{}\", ltr_text, rtl_text, ltr_text, rtl_text);\n        let bidi_info = BidiInfo::new(&all_paragraphs, None);\n        assert_eq!(bidi_info.paragraphs.len(), 3);\n\n        let p_ltr = Paragraph::new(&bidi_info, &bidi_info.paragraphs[0]);\n        let p_rtl = Paragraph::new(&bidi_info, &bidi_info.paragraphs[1]);\n        let p_mixed = Paragraph::new(&bidi_info, &bidi_info.paragraphs[2]);\n\n        assert_eq!(p_ltr.level_at(0), LTR_LEVEL);\n        assert_eq!(p_rtl.level_at(0), RTL_LEVEL);\n        assert_eq!(p_mixed.level_at(0), LTR_LEVEL);\n        assert_eq!(p_mixed.info.levels.len(), 54);\n        assert_eq!(p_mixed.para.range.start, 28);\n        assert_eq!(p_mixed.level_at(ltr_text.len()), RTL_LEVEL);\n\n        let all_paragraphs = &to_utf16(&all_paragraphs);\n        let bidi_info = BidiInfoU16::new(&all_paragraphs, None);\n        assert_eq!(bidi_info.paragraphs.len(), 3);\n\n        let p_ltr = ParagraphU16::new(&bidi_info, &bidi_info.paragraphs[0]);\n        let p_rtl = ParagraphU16::new(&bidi_info, &bidi_info.paragraphs[1]);\n        let p_mixed = ParagraphU16::new(&bidi_info, &bidi_info.paragraphs[2]);\n\n        assert_eq!(p_ltr.level_at(0), LTR_LEVEL);\n        assert_eq!(p_rtl.level_at(0), RTL_LEVEL);\n        assert_eq!(p_mixed.level_at(0), LTR_LEVEL);\n        assert_eq!(p_mixed.info.levels.len(), 40);\n        assert_eq!(p_mixed.para.range.start, 21);\n        assert_eq!(p_mixed.level_at(ltr_text.len()), RTL_LEVEL);\n    }\n\n    #[test]\n    fn test_get_base_direction() {\n        let tests = vec![\n            (\"\", Direction::Mixed), // return Mixed if no strong character found\n            (\"123[]-+\\u{2019}\\u{2060}\\u{00bf}?\", Direction::Mixed),\n            (\"3.14\\npi\", Direction::Mixed), // only first paragraph is considered\n            (\"[123 'abc']\", Direction::Ltr),\n            (\"[123 '\\u{0628}' abc\", Direction::Rtl),\n            (\"[123 '\\u{2066}abc\\u{2069}'\\u{0628}]\", Direction::Rtl), // embedded isolate is ignored\n            (\"[123 '\\u{2066}abc\\u{2068}'\\u{0628}]\", Direction::Mixed),\n        ];\n\n        for t in tests {\n            assert_eq!(get_base_direction(t.0), t.1);\n            let text = &to_utf16(t.0);\n            assert_eq!(get_base_direction(text.as_slice()), t.1);\n        }\n    }\n\n    #[test]\n    fn test_get_base_direction_full() {\n        let tests = vec![\n            (\"\", Direction::Mixed), // return Mixed if no strong character found\n            (\"123[]-+\\u{2019}\\u{2060}\\u{00bf}?\", Direction::Mixed),\n            (\"3.14\\npi\", Direction::Ltr), // direction taken from the second paragraph\n            (\"3.14\\n\\u{05D0}\", Direction::Rtl), // direction taken from the second paragraph\n            (\"[123 'abc']\", Direction::Ltr),\n            (\"[123 '\\u{0628}' abc\", Direction::Rtl),\n            (\"[123 '\\u{2066}abc\\u{2069}'\\u{0628}]\", Direction::Rtl), // embedded isolate is ignored\n            (\"[123 '\\u{2066}abc\\u{2068}'\\u{0628}]\", Direction::Mixed),\n            (\"[123 '\\u{2066}abc\\u{2068}'\\n\\u{0628}]\", Direction::Rtl), // \\n resets embedding level\n        ];\n\n        for t in tests {\n            assert_eq!(get_base_direction_full(t.0), t.1);\n            let text = &to_utf16(t.0);\n            assert_eq!(get_base_direction_full(text.as_slice()), t.1);\n        }\n    }\n}\n\n#[cfg(all(feature = \"serde\", feature = \"hardcoded-data\", test))]\nmod serde_tests {\n    use super::*;\n    use serde_test::{assert_tokens, Token};\n\n    #[test]\n    fn test_levels() {\n        let text = \"abc אבג\";\n        let bidi_info = BidiInfo::new(text, None);\n        let levels = bidi_info.levels;\n        assert_eq!(text.as_bytes().len(), 10);\n        assert_eq!(levels.len(), 10);\n        assert_tokens(\n            &levels,\n            &[\n                Token::Seq { len: Some(10) },\n                Token::NewtypeStruct { name: \"Level\" },\n                Token::U8(0),\n                Token::NewtypeStruct { name: \"Level\" },\n                Token::U8(0),\n                Token::NewtypeStruct { name: \"Level\" },\n                Token::U8(0),\n                Token::NewtypeStruct { name: \"Level\" },\n                Token::U8(0),\n                Token::NewtypeStruct { name: \"Level\" },\n                Token::U8(1),\n                Token::NewtypeStruct { name: \"Level\" },\n                Token::U8(1),\n                Token::NewtypeStruct { name: \"Level\" },\n                Token::U8(1),\n                Token::NewtypeStruct { name: \"Level\" },\n                Token::U8(1),\n                Token::NewtypeStruct { name: \"Level\" },\n                Token::U8(1),\n                Token::NewtypeStruct { name: \"Level\" },\n                Token::U8(1),\n                Token::SeqEnd,\n            ],\n        );\n    }\n}\n"
    },
    {
      "package": "unicode-bidi@0.3.18",
      "sourcePath": "src/prepare.rs",
      "sha256": "aeb8b88cfb2d2e6b74473f5903205dd3683d57abcc8801de7b9fdea6a432a0fe",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2015 The Servo Project Developers. See the\n// COPYRIGHT file at the top-level directory of this distribution.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! 3.3.3 Preparations for Implicit Processing\n//!\n//! <http://www.unicode.org/reports/tr9/#Preparations_for_Implicit_Processing>\n\nuse alloc::vec::Vec;\nuse core::cmp::max;\nuse core::ops::Range;\n#[cfg(feature = \"smallvec\")]\nuse smallvec::{smallvec, SmallVec};\n\nuse super::level::Level;\nuse super::BidiClass::{self, *};\n\n/// A maximal substring of characters with the same embedding level.\n///\n/// Represented as a range of byte indices.\npub type LevelRun = Range<usize>;\n\n#[cfg(feature = \"smallvec\")]\npub type LevelRunVec = SmallVec<[LevelRun; 8]>;\n#[cfg(not(feature = \"smallvec\"))]\npub type LevelRunVec = Vec<LevelRun>;\n\n/// Output of `isolating_run_sequences` (steps X9-X10)\n#[derive(Debug, PartialEq)]\npub struct IsolatingRunSequence {\n    pub runs: Vec<LevelRun>,\n    pub sos: BidiClass, // Start-of-sequence type.\n    pub eos: BidiClass, // End-of-sequence type.\n}\n\n#[cfg(feature = \"smallvec\")]\npub type IsolatingRunSequenceVec = SmallVec<[IsolatingRunSequence; 8]>;\n#[cfg(not(feature = \"smallvec\"))]\npub type IsolatingRunSequenceVec = Vec<IsolatingRunSequence>;\n\n/// Compute the set of isolating run sequences.\n///\n/// An isolating run sequence is a maximal sequence of level runs such that for all level runs\n/// except the last one in the sequence, the last character of the run is an isolate initiator\n/// whose matching PDI is the first character of the next level run in the sequence.\n///\n/// Note: This function does *not* return the sequences in order by their first characters.\n#[cfg_attr(feature = \"flame_it\", flamer::flame)]\npub fn isolating_run_sequences(\n    para_level: Level,\n    original_classes: &[BidiClass],\n    levels: &[Level],\n    runs: LevelRunVec,\n    has_isolate_controls: bool,\n    isolating_run_sequences: &mut IsolatingRunSequenceVec,\n) {\n    // Per http://www.unicode.org/reports/tr9/#BD13:\n    // \"In the absence of isolate initiators, each isolating run sequence in a paragraph\n    //  consists of exactly one level run, and each level run constitutes a separate\n    //  isolating run sequence.\"\n    // We can take a simplified path to handle this case.\n    if !has_isolate_controls {\n        isolating_run_sequences.reserve_exact(runs.len());\n        for run in runs {\n            // Determine the `sos` and `eos` class for the sequence.\n            // <http://www.unicode.org/reports/tr9/#X10>\n\n            let run_levels = &levels[run.clone()];\n            let run_classes = &original_classes[run.clone()];\n            let seq_level = run_levels[run_classes\n                .iter()\n                .position(|c| not_removed_by_x9(c))\n                .unwrap_or(0)];\n\n            let end_level = run_levels[run_classes\n                .iter()\n                .rposition(|c| not_removed_by_x9(c))\n                .unwrap_or(run.end - run.start - 1)];\n\n            // Get the level of the last non-removed char before the run.\n            let pred_level = match original_classes[..run.start]\n                .iter()\n                .rposition(not_removed_by_x9)\n            {\n                Some(idx) => levels[idx],\n                None => para_level,\n            };\n\n            // Get the level of the next non-removed char after the run.\n            let succ_level = match original_classes[run.end..]\n                .iter()\n                .position(not_removed_by_x9)\n            {\n                Some(idx) => levels[run.end + idx],\n                None => para_level,\n            };\n\n            isolating_run_sequences.push(IsolatingRunSequence {\n                runs: vec![run],\n                sos: max(seq_level, pred_level).bidi_class(),\n                eos: max(end_level, succ_level).bidi_class(),\n            });\n        }\n        return;\n    }\n\n    // Compute the set of isolating run sequences.\n    // <http://www.unicode.org/reports/tr9/#BD13>\n    let mut sequences = Vec::with_capacity(runs.len());\n\n    // When we encounter an isolate initiator, we push the current sequence onto the\n    // stack so we can resume it after the matching PDI.\n    #[cfg(feature = \"smallvec\")]\n    let mut stack: SmallVec<[Vec<Range<usize>>; 8]> = smallvec![vec![]];\n    #[cfg(not(feature = \"smallvec\"))]\n    let mut stack = vec![vec![]];\n\n    for run in runs {\n        assert!(!run.is_empty());\n        assert!(!stack.is_empty());\n\n        let start_class = original_classes[run.start];\n        // > In rule X10, [..] skip over any BNs when [..].\n        // > Do the same when determining if the last character of the sequence is an isolate initiator.\n        //\n        // <https://www.unicode.org/reports/tr9/#Retaining_Explicit_Formatting_Characters>\n        let end_class = original_classes[run.start..run.end]\n            .iter()\n            .copied()\n            .rev()\n            .find(not_removed_by_x9)\n            .unwrap_or(start_class);\n\n        let mut sequence = if start_class == PDI && stack.len() > 1 {\n            // Continue a previous sequence interrupted by an isolate.\n            stack.pop().unwrap()\n        } else {\n            // Start a new sequence.\n            Vec::new()\n        };\n\n        sequence.push(run);\n\n        if matches!(end_class, RLI | LRI | FSI) {\n            // Resume this sequence after the isolate.\n            stack.push(sequence);\n        } else {\n            // This sequence is finished.\n            sequences.push(sequence);\n        }\n    }\n    // Pop any remaining sequences off the stack.\n    sequences.extend(stack.into_iter().rev().filter(|seq| !seq.is_empty()));\n\n    // Determine the `sos` and `eos` class for each sequence.\n    // <http://www.unicode.org/reports/tr9/#X10>\n    for sequence in sequences {\n        assert!(!sequence.is_empty());\n\n        let start_of_seq = sequence[0].start;\n        let runs_len = sequence.len();\n        let end_of_seq = sequence[runs_len - 1].end;\n\n        let mut result = IsolatingRunSequence {\n            runs: sequence,\n            sos: L,\n            eos: L,\n        };\n\n        // > (not counting characters removed by X9)\n        let seq_level = levels[result\n            .iter_forwards_from(start_of_seq, 0)\n            .find(|i| not_removed_by_x9(&original_classes[*i]))\n            .unwrap_or(start_of_seq)];\n\n        // XXXManishearth the spec talks of a start and end level,\n        // but for a given IRS the two should be equivalent, yes?\n        let end_level = levels[result\n            .iter_backwards_from(end_of_seq, runs_len - 1)\n            .find(|i| not_removed_by_x9(&original_classes[*i]))\n            .unwrap_or(end_of_seq - 1)];\n\n        #[cfg(test)]\n        for idx in result.runs.clone().into_iter().flatten() {\n            if not_removed_by_x9(&original_classes[idx]) {\n                assert_eq!(seq_level, levels[idx]);\n            }\n        }\n\n        // Get the level of the last non-removed char before the runs.\n        let pred_level = match original_classes[..start_of_seq]\n            .iter()\n            .rposition(not_removed_by_x9)\n        {\n            Some(idx) => levels[idx],\n            None => para_level,\n        };\n\n        // Get the last non-removed character to check if it is an isolate initiator.\n        // The spec calls for an unmatched one, but matched isolate initiators\n        // will never be at the end of a level run (otherwise there would be more to the run).\n        // We unwrap_or(BN) because BN marks removed classes and it won't matter for the check.\n        let last_non_removed = original_classes[..end_of_seq]\n            .iter()\n            .copied()\n            .rev()\n            .find(not_removed_by_x9)\n            .unwrap_or(BN);\n\n        // Get the level of the next non-removed char after the runs.\n        let succ_level = if matches!(last_non_removed, RLI | LRI | FSI) {\n            para_level\n        } else {\n            match original_classes[end_of_seq..]\n                .iter()\n                .position(not_removed_by_x9)\n            {\n                Some(idx) => levels[end_of_seq + idx],\n                None => para_level,\n            }\n        };\n\n        result.sos = max(seq_level, pred_level).bidi_class();\n        result.eos = max(end_level, succ_level).bidi_class();\n\n        isolating_run_sequences.push(result);\n    }\n}\n\nimpl IsolatingRunSequence {\n    /// Given a text-relative position `pos` and an index of the level run it is in,\n    /// produce an iterator of all characters after and pos (`pos..`) that are in this\n    /// run sequence\n    pub(crate) fn iter_forwards_from(\n        &self,\n        pos: usize,\n        level_run_index: usize,\n    ) -> impl Iterator<Item = usize> + '_ {\n        let runs = &self.runs[level_run_index..];\n\n        // Check that it is in range\n        // (we can't use contains() since we want an inclusive range)\n        #[cfg(feature = \"std\")]\n        debug_assert!(runs[0].start <= pos && pos <= runs[0].end);\n\n        (pos..runs[0].end).chain(runs[1..].iter().flat_map(Clone::clone))\n    }\n\n    /// Given a text-relative position `pos` and an index of the level run it is in,\n    /// produce an iterator of all characters before and excludingpos (`..pos`) that are in this\n    /// run sequence\n    pub(crate) fn iter_backwards_from(\n        &self,\n        pos: usize,\n        level_run_index: usize,\n    ) -> impl Iterator<Item = usize> + '_ {\n        let prev_runs = &self.runs[..level_run_index];\n        let current = &self.runs[level_run_index];\n\n        // Check that it is in range\n        // (we can't use contains() since we want an inclusive range)\n        #[cfg(feature = \"std\")]\n        debug_assert!(current.start <= pos && pos <= current.end);\n\n        (current.start..pos)\n            .rev()\n            .chain(prev_runs.iter().rev().flat_map(Clone::clone))\n    }\n}\n\n/// Finds the level runs in a paragraph.\n///\n/// <http://www.unicode.org/reports/tr9/#BD7>\n///\n/// This is only used by tests; normally level runs are identified during explicit::compute.\n#[cfg(test)]\nfn level_runs(levels: &[Level], original_classes: &[BidiClass]) -> Vec<LevelRun> {\n    assert_eq!(levels.len(), original_classes.len());\n\n    let mut runs = Vec::new();\n    if levels.is_empty() {\n        return runs;\n    }\n\n    let mut current_run_level = levels[0];\n    let mut current_run_start = 0;\n    for i in 1..levels.len() {\n        if !removed_by_x9(original_classes[i]) && levels[i] != current_run_level {\n            // End the last run and start a new one.\n            runs.push(current_run_start..i);\n            current_run_level = levels[i];\n            current_run_start = i;\n        }\n    }\n    runs.push(current_run_start..levels.len());\n\n    runs\n}\n\n/// Should this character be ignored in steps after X9?\n///\n/// <http://www.unicode.org/reports/tr9/#X9>\npub fn removed_by_x9(class: BidiClass) -> bool {\n    matches!(class, RLE | LRE | RLO | LRO | PDF | BN)\n}\n\n// For use as a predicate for `position` / `rposition`\npub fn not_removed_by_x9(class: &BidiClass) -> bool {\n    !removed_by_x9(*class)\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_level_runs() {\n        assert_eq!(level_runs(&Level::vec(&[]), &[]), &[]);\n        assert_eq!(\n            level_runs(&Level::vec(&[0, 0, 0, 1, 1, 2, 0, 0]), &[L; 8]),\n            &[0..3, 3..5, 5..6, 6..8]\n        );\n    }\n\n    // From <http://www.unicode.org/reports/tr9/#BD13>\n    #[rustfmt::skip]\n    #[test]\n    fn test_isolating_run_sequences() {\n\n        // == Example 1 ==\n        // text1·RLE·text2·PDF·RLE·text3·PDF·text4\n        // index        0    1  2    3    4  5    6  7\n        let classes = &[L, RLE, L, PDF, RLE, L, PDF, L];\n        let levels =  &[0,   1, 1,   1,   1, 1,   1, 0];\n        let para_level = Level::ltr();\n        let mut sequences = IsolatingRunSequenceVec::new();\n        isolating_run_sequences(\n            para_level,\n            classes,\n            &Level::vec(levels),\n            level_runs(&Level::vec(levels), classes).into(),\n            false,\n            &mut sequences);\n        sequences.sort_by(|a, b| a.runs[0].clone().cmp(b.runs[0].clone()));\n        assert_eq!(\n            sequences.iter().map(|s| s.runs.clone()).collect::<Vec<_>>(),\n            vec![vec![0..2], vec![2..7], vec![7..8]]\n        );\n\n        // == Example 2 ==\n        // text1·RLI·text2·PDI·RLI·text3·PDI·text4\n        // index        0    1  2    3    4  5    6  7\n        let classes = &[L, RLI, L, PDI, RLI, L, PDI, L];\n        let levels =  &[0,   0, 1,   0,   0, 1,   0, 0];\n        let para_level = Level::ltr();\n        let mut sequences = IsolatingRunSequenceVec::new();\n        isolating_run_sequences(\n            para_level,\n            classes,\n            &Level::vec(levels),\n            level_runs(&Level::vec(levels), classes).into(),\n            true,\n            &mut sequences);\n        sequences.sort_by(|a, b| a.runs[0].clone().cmp(b.runs[0].clone()));\n        assert_eq!(\n            sequences.iter().map(|s| s.runs.clone()).collect::<Vec<_>>(),\n            vec![vec![0..2, 3..5, 6..8], vec![2..3], vec![5..6]]\n        );\n\n        // == Example 3 ==\n        // text1·RLI·text2·LRI·text3·RLE·text4·PDF·text5·PDI·text6·PDI·text7\n        // index        0    1  2    3  4    5  6    7  8    9  10  11  12\n        let classes = &[L, RLI, L, LRI, L, RLE, L, PDF, L, PDI, L, PDI,  L];\n        let levels =  &[0,   0, 1,   1, 2,   3, 3,   3, 2,   1, 1,   0,  0];\n        let para_level = Level::ltr();\n        let mut sequences = IsolatingRunSequenceVec::new();\n        isolating_run_sequences(\n            para_level,\n            classes,\n            &Level::vec(levels),\n            level_runs(&Level::vec(levels), classes).into(),\n            true,\n            &mut sequences);\n        sequences.sort_by(|a, b| a.runs[0].clone().cmp(b.runs[0].clone()));\n        assert_eq!(\n            sequences.iter().map(|s| s.runs.clone()).collect::<Vec<_>>(),\n            vec![vec![0..2, 11..13], vec![2..4, 9..11], vec![4..6], vec![6..8], vec![8..9]]\n        );\n    }\n\n    // From <http://www.unicode.org/reports/tr9/#X10>\n    #[rustfmt::skip]\n    #[test]\n    fn test_isolating_run_sequences_sos_and_eos() {\n\n        // == Example 1 ==\n        // text1·RLE·text2·LRE·text3·PDF·text4·PDF·RLE·text5·PDF·text6\n        // index        0    1  2    3  4    5  6    7    8  9   10  11\n        let classes = &[L, RLE, L, LRE, L, PDF, L, PDF, RLE, L, PDF,  L];\n        let levels =  &[0,   1, 1,   2, 2,   2, 1,   1,   1, 1,   1,  0];\n        let para_level = Level::ltr();\n        let mut sequences = IsolatingRunSequenceVec::new();\n        isolating_run_sequences(\n            para_level,\n            classes,\n            &Level::vec(levels),\n            level_runs(&Level::vec(levels), classes).into(),\n            false,\n            &mut sequences);\n        sequences.sort_by(|a, b| a.runs[0].clone().cmp(b.runs[0].clone()));\n\n        // text1\n        assert_eq!(\n            &sequences[0],\n            &IsolatingRunSequence {\n                runs: vec![0..2],\n                sos: L,\n                eos: R,\n            }\n        );\n\n        // text2\n        assert_eq!(\n            &sequences[1],\n            &IsolatingRunSequence {\n                runs: vec![2..4],\n                sos: R,\n                eos: L,\n            }\n        );\n\n        // text3\n        assert_eq!(\n            &sequences[2],\n            &IsolatingRunSequence {\n                runs: vec![4..6],\n                sos: L,\n                eos: L,\n            }\n        );\n\n        // text4 text5\n        assert_eq!(\n            &sequences[3],\n            &IsolatingRunSequence {\n                runs: vec![6..11],\n                sos: L,\n                eos: R,\n            }\n        );\n\n        // text6\n        assert_eq!(\n            &sequences[4],\n            &IsolatingRunSequence {\n                runs: vec![11..12],\n                sos: R,\n                eos: L,\n            }\n        );\n\n        // == Example 2 ==\n        // text1·RLI·text2·LRI·text3·PDI·text4·PDI·RLI·text5·PDI·text6\n        // index        0    1  2    3  4    5  6    7    8  9   10  11\n        let classes = &[L, RLI, L, LRI, L, PDI, L, PDI, RLI, L, PDI,  L];\n        let levels =  &[0,   0, 1,   1, 2,   1, 1,   0,   0, 1,   0,  0];\n        let para_level = Level::ltr();\n        let mut sequences = IsolatingRunSequenceVec::new();\n        isolating_run_sequences(\n            para_level,\n            classes,\n            &Level::vec(levels),\n            level_runs(&Level::vec(levels), classes).into(),\n            true,\n            &mut sequences);\n        sequences.sort_by(|a, b| a.runs[0].clone().cmp(b.runs[0].clone()));\n\n        // text1·RLI·PDI·RLI·PDI·text6\n        assert_eq!(\n            &sequences[0],\n            &IsolatingRunSequence {\n                runs: vec![0..2, 7..9, 10..12],\n                sos: L,\n                eos: L,\n            }\n        );\n\n        // text2·LRI·PDI·text4\n        assert_eq!(\n            &sequences[1],\n            &IsolatingRunSequence {\n                runs: vec![2..4, 5..7],\n                sos: R,\n                eos: R,\n            }\n        );\n\n        // text3\n        assert_eq!(\n            &sequences[2],\n            &IsolatingRunSequence {\n                runs: vec![4..5],\n                sos: L,\n                eos: L,\n            }\n        );\n\n        // text5\n        assert_eq!(\n            &sequences[3],\n            &IsolatingRunSequence {\n                runs: vec![9..10],\n                sos: R,\n                eos: R,\n            }\n        );\n    }\n\n    #[test]\n    fn test_removed_by_x9() {\n        let rem_classes = &[RLE, LRE, RLO, LRO, PDF, BN];\n        let not_classes = &[L, RLI, AL, LRI, PDI];\n        for x in rem_classes {\n            assert_eq!(removed_by_x9(*x), true);\n        }\n        for x in not_classes {\n            assert_eq!(removed_by_x9(*x), false);\n        }\n    }\n\n    #[test]\n    fn test_not_removed_by_x9() {\n        let non_x9_classes = &[L, R, AL, EN, ES, ET, AN, CS, NSM, B, S, WS, ON, LRI, RLI, FSI, PDI];\n        for x in non_x9_classes {\n            assert_eq!(not_removed_by_x9(&x), true);\n        }\n    }\n}\n"
    },
    {
      "package": "unicode-bidi@0.3.18",
      "sourcePath": "src/utf16.rs",
      "sha256": "12ee177127a0b5b0350a1fcc1edf7387c26b51ec5654f724629aab723881c313",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2023 The Mozilla Foundation. See the\n// COPYRIGHT file at the top-level directory of this distribution.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse super::TextSource;\n\nuse alloc::borrow::Cow;\nuse alloc::vec::Vec;\nuse core::char;\nuse core::ops::Range;\n\nuse crate::{\n    compute_bidi_info_for_para, compute_initial_info, level, para_direction, reorder_levels,\n    reorder_visual, visual_runs_for_line,\n};\nuse crate::{\n    BidiClass, BidiDataSource, Direction, Level, LevelRun, ParagraphInfo, ParagraphInfoFlags,\n};\n\n#[cfg(feature = \"hardcoded-data\")]\nuse crate::HardcodedBidiData;\n\n/// Initial bidi information of the text (UTF-16 version).\n///\n/// Contains the text paragraphs and `BidiClass` of its characters.\n#[derive(PartialEq, Debug)]\npub struct InitialInfo<'text> {\n    /// The text\n    pub text: &'text [u16],\n\n    /// The BidiClass of the character at each code unit in the text.\n    /// If a character is multiple code units, its class will appear multiple times in the vector.\n    pub original_classes: Vec<BidiClass>,\n\n    /// The boundaries and level of each paragraph within the text.\n    pub paragraphs: Vec<ParagraphInfo>,\n}\n\nimpl<'text> InitialInfo<'text> {\n    /// Find the paragraphs and BidiClasses in a string of text.\n    ///\n    /// <http://www.unicode.org/reports/tr9/#The_Paragraph_Level>\n    ///\n    /// Also sets the class for each First Strong Isolate initiator (FSI) to LRI or RLI if a strong\n    /// character is found before the matching PDI.  If no strong character is found, the class will\n    /// remain FSI, and it's up to later stages to treat these as LRI when needed.\n    ///\n    /// The `hardcoded-data` Cargo feature (enabled by default) must be enabled to use this.\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[cfg(feature = \"hardcoded-data\")]\n    pub fn new(text: &[u16], default_para_level: Option<Level>) -> InitialInfo<'_> {\n        Self::new_with_data_source(&HardcodedBidiData, text, default_para_level)\n    }\n\n    /// Find the paragraphs and BidiClasses in a string of text, with a custom [`BidiDataSource`]\n    /// for Bidi data. If you just wish to use the hardcoded Bidi data, please use [`InitialInfo::new()`]\n    /// instead (enabled with tbe default `hardcoded-data` Cargo feature)\n    ///\n    /// <http://www.unicode.org/reports/tr9/#The_Paragraph_Level>\n    ///\n    /// Also sets the class for each First Strong Isolate initiator (FSI) to LRI or RLI if a strong\n    /// character is found before the matching PDI.  If no strong character is found, the class will\n    /// remain FSI, and it's up to later stages to treat these as LRI when needed.\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn new_with_data_source<'a, D: BidiDataSource>(\n        data_source: &D,\n        text: &'a [u16],\n        default_para_level: Option<Level>,\n    ) -> InitialInfo<'a> {\n        InitialInfoExt::new_with_data_source(data_source, text, default_para_level).base\n    }\n}\n\n/// Extended version of InitialInfo (not public API).\n#[derive(PartialEq, Debug)]\nstruct InitialInfoExt<'text> {\n    /// The base InitialInfo for the text, recording its paragraphs and bidi classes.\n    base: InitialInfo<'text>,\n\n    /// Parallel to base.paragraphs, records whether each paragraph is \"pure LTR\" that\n    /// requires no further bidi processing (i.e. there are no RTL characters or bidi\n    /// control codes present).\n    flags: Vec<ParagraphInfoFlags>,\n}\n\nimpl<'text> InitialInfoExt<'text> {\n    /// Find the paragraphs and BidiClasses in a string of text, with a custom [`BidiDataSource`]\n    /// for Bidi data. If you just wish to use the hardcoded Bidi data, please use [`InitialInfo::new()`]\n    /// instead (enabled with tbe default `hardcoded-data` Cargo feature)\n    ///\n    /// <http://www.unicode.org/reports/tr9/#The_Paragraph_Level>\n    ///\n    /// Also sets the class for each First Strong Isolate initiator (FSI) to LRI or RLI if a strong\n    /// character is found before the matching PDI.  If no strong character is found, the class will\n    /// remain FSI, and it's up to later stages to treat these as LRI when needed.\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn new_with_data_source<'a, D: BidiDataSource>(\n        data_source: &D,\n        text: &'a [u16],\n        default_para_level: Option<Level>,\n    ) -> InitialInfoExt<'a> {\n        let mut paragraphs = Vec::<ParagraphInfo>::new();\n        let mut flags = Vec::<ParagraphInfoFlags>::new();\n        let (original_classes, _, _, _) = compute_initial_info(\n            data_source,\n            text,\n            default_para_level,\n            Some((&mut paragraphs, &mut flags)),\n        );\n\n        InitialInfoExt {\n            base: InitialInfo {\n                text,\n                original_classes,\n                paragraphs,\n            },\n            flags,\n        }\n    }\n}\n\n/// Bidi information of the text (UTF-16 version).\n///\n/// The `original_classes` and `levels` vectors are indexed by code unit offsets into the text.  If a\n/// character is multiple code units wide, then its class and level will appear multiple times in these\n/// vectors.\n// TODO: Impl `struct StringProperty<T> { values: Vec<T> }` and use instead of Vec<T>\n#[derive(Debug, PartialEq)]\npub struct BidiInfo<'text> {\n    /// The text\n    pub text: &'text [u16],\n\n    /// The BidiClass of the character at each byte in the text.\n    pub original_classes: Vec<BidiClass>,\n\n    /// The directional embedding level of each byte in the text.\n    pub levels: Vec<Level>,\n\n    /// The boundaries and paragraph embedding level of each paragraph within the text.\n    ///\n    /// TODO: Use SmallVec or similar to avoid overhead when there are only one or two paragraphs?\n    /// Or just don't include the first paragraph, which always starts at 0?\n    pub paragraphs: Vec<ParagraphInfo>,\n}\n\nimpl<'text> BidiInfo<'text> {\n    /// Split the text into paragraphs and determine the bidi embedding levels for each paragraph.\n    ///\n    ///\n    /// The `hardcoded-data` Cargo feature (enabled by default) must be enabled to use this.\n    ///\n    /// TODO: In early steps, check for special cases that allow later steps to be skipped. like\n    /// text that is entirely LTR.  See the `nsBidi` class from Gecko for comparison.\n    ///\n    /// TODO: Support auto-RTL base direction\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[cfg(feature = \"hardcoded-data\")]\n    #[inline]\n    pub fn new(text: &[u16], default_para_level: Option<Level>) -> BidiInfo<'_> {\n        Self::new_with_data_source(&HardcodedBidiData, text, default_para_level)\n    }\n\n    /// Split the text into paragraphs and determine the bidi embedding levels for each paragraph, with a custom [`BidiDataSource`]\n    /// for Bidi data. If you just wish to use the hardcoded Bidi data, please use [`BidiInfo::new()`]\n    /// instead (enabled with tbe default `hardcoded-data` Cargo feature).\n    ///\n    /// TODO: In early steps, check for special cases that allow later steps to be skipped. like\n    /// text that is entirely LTR.  See the `nsBidi` class from Gecko for comparison.\n    ///\n    /// TODO: Support auto-RTL base direction\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn new_with_data_source<'a, D: BidiDataSource>(\n        data_source: &D,\n        text: &'a [u16],\n        default_para_level: Option<Level>,\n    ) -> BidiInfo<'a> {\n        let InitialInfoExt { base, flags, .. } =\n            InitialInfoExt::new_with_data_source(data_source, text, default_para_level);\n\n        let mut levels = Vec::<Level>::with_capacity(text.len());\n        let mut processing_classes = base.original_classes.clone();\n\n        for (para, flags) in base.paragraphs.iter().zip(flags.iter()) {\n            let text = &text[para.range.clone()];\n            let original_classes = &base.original_classes[para.range.clone()];\n\n            compute_bidi_info_for_para(\n                data_source,\n                para,\n                flags.is_pure_ltr,\n                flags.has_isolate_controls,\n                text,\n                original_classes,\n                &mut processing_classes,\n                &mut levels,\n            );\n        }\n\n        BidiInfo {\n            text,\n            original_classes: base.original_classes,\n            paragraphs: base.paragraphs,\n            levels,\n        }\n    }\n\n    /// Produce the levels for this paragraph as needed for reordering, one level per *byte*\n    /// in the paragraph. The returned vector includes bytes that are not included\n    /// in the `line`, but will not adjust them.\n    ///\n    /// This runs [Rule L1], you can run\n    /// [Rule L2] by calling [`Self::reorder_visual()`].\n    /// If doing so, you may prefer to use [`Self::reordered_levels_per_char()`] instead\n    /// to avoid non-byte indices.\n    ///\n    /// For an all-in-one reordering solution, consider using [`Self::reorder_visual()`].\n    ///\n    /// [Rule L1]: https://www.unicode.org/reports/tr9/#L1\n    /// [Rule L2]: https://www.unicode.org/reports/tr9/#L2\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reordered_levels(&self, para: &ParagraphInfo, line: Range<usize>) -> Vec<Level> {\n        assert!(line.start <= self.levels.len());\n        assert!(line.end <= self.levels.len());\n\n        let mut levels = self.levels.clone();\n        let line_classes = &self.original_classes[line.clone()];\n        let line_levels = &mut levels[line.clone()];\n        let line_str: &[u16] = &self.text[line.clone()];\n\n        reorder_levels(line_classes, line_levels, line_str, para.level);\n\n        levels\n    }\n\n    /// Produce the levels for this paragraph as needed for reordering, one level per *character*\n    /// in the paragraph. The returned vector includes characters that are not included\n    /// in the `line`, but will not adjust them.\n    ///\n    /// This runs [Rule L1], you can run\n    /// [Rule L2] by calling [`Self::reorder_visual()`].\n    /// If doing so, you may prefer to use [`Self::reordered_levels_per_char()`] instead\n    /// to avoid non-byte indices.\n    ///\n    /// For an all-in-one reordering solution, consider using [`Self::reorder_visual()`].\n    ///\n    /// [Rule L1]: https://www.unicode.org/reports/tr9/#L1\n    /// [Rule L2]: https://www.unicode.org/reports/tr9/#L2\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reordered_levels_per_char(\n        &self,\n        para: &ParagraphInfo,\n        line: Range<usize>,\n    ) -> Vec<Level> {\n        let levels = self.reordered_levels(para, line);\n        self.text.char_indices().map(|(i, _)| levels[i]).collect()\n    }\n\n    /// Re-order a line based on resolved levels and return the line in display order.\n    ///\n    /// This does not apply [Rule L3] or [Rule L4] around combining characters or mirroring.\n    ///\n    /// [Rule L3]: https://www.unicode.org/reports/tr9/#L3\n    /// [Rule L4]: https://www.unicode.org/reports/tr9/#L4\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reorder_line(&self, para: &ParagraphInfo, line: Range<usize>) -> Cow<'text, [u16]> {\n        if !level::has_rtl(&self.levels[line.clone()]) {\n            return self.text[line].into();\n        }\n        let (levels, runs) = self.visual_runs(para, line.clone());\n        reorder_line(self.text, line, levels, runs)\n    }\n\n    /// Reorders pre-calculated levels of a sequence of characters.\n    ///\n    /// NOTE: This is a convenience method that does not use a `Paragraph`  object. It is\n    /// intended to be used when an application has determined the levels of the objects (character sequences)\n    /// and just needs to have them reordered.\n    ///\n    /// the index map will result in `indexMap[visualIndex]==logicalIndex`.\n    ///\n    /// This only runs [Rule L2](http://www.unicode.org/reports/tr9/#L2) as it does not have\n    /// information about the actual text.\n    ///\n    /// Furthermore, if `levels` is an array that is aligned with code units, bytes within a codepoint may be\n    /// reversed. You may need to fix up the map to deal with this. Alternatively, only pass in arrays where each `Level`\n    /// is for a single code point.\n    ///\n    ///\n    ///   # # Example\n    /// ```\n    /// use unicode_bidi::BidiInfo;\n    /// use unicode_bidi::Level;\n    ///\n    /// let l0 = Level::from(0);\n    /// let l1 = Level::from(1);\n    /// let l2 = Level::from(2);\n    ///\n    /// let levels = vec![l0, l0, l0, l0];\n    /// let index_map = BidiInfo::reorder_visual(&levels);\n    /// assert_eq!(levels.len(), index_map.len());\n    /// assert_eq!(index_map, [0, 1, 2, 3]);\n    ///\n    /// let levels: Vec<Level> = vec![l0, l0, l0, l1, l1, l1, l2, l2];\n    /// let index_map = BidiInfo::reorder_visual(&levels);\n    /// assert_eq!(levels.len(), index_map.len());\n    /// assert_eq!(index_map, [0, 1, 2, 6, 7, 5, 4, 3]);\n    /// ```\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[inline]\n    pub fn reorder_visual(levels: &[Level]) -> Vec<usize> {\n        reorder_visual(levels)\n    }\n\n    /// Find the level runs within a line and return them in visual order.\n    ///\n    /// `line` is a range of bytes indices within `levels`.\n    ///\n    /// The first return value is a vector of levels used by the reordering algorithm,\n    /// i.e. the result of [Rule L1]. The second return value is a vector of level runs,\n    /// the result of [Rule L2], showing the visual order that each level run (a run of text with the\n    /// same level) should be displayed. Within each run, the display order can be checked\n    /// against the Level vector.\n    ///\n    /// This does not handle [Rule L3] (combining characters) or [Rule L4] (mirroring),\n    /// as that should be handled by the engine using this API.\n    ///\n    /// Conceptually, this is the same as running [`Self::reordered_levels()`] followed by\n    /// [`Self::reorder_visual()`], however it returns the result as a list of level runs instead\n    /// of producing a level map, since one may wish to deal with the fact that this is operating on\n    /// byte rather than character indices.\n    ///\n    /// <http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels>\n    ///\n    /// [Rule L1]: https://www.unicode.org/reports/tr9/#L1\n    /// [Rule L2]: https://www.unicode.org/reports/tr9/#L2\n    /// [Rule L3]: https://www.unicode.org/reports/tr9/#L3\n    /// [Rule L4]: https://www.unicode.org/reports/tr9/#L4\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[inline]\n    pub fn visual_runs(\n        &self,\n        para: &ParagraphInfo,\n        line: Range<usize>,\n    ) -> (Vec<Level>, Vec<LevelRun>) {\n        let levels = self.reordered_levels(para, line.clone());\n        visual_runs_for_line(levels, &line)\n    }\n\n    /// If processed text has any computed RTL levels\n    ///\n    /// This information is usually used to skip re-ordering of text when no RTL level is present\n    #[inline]\n    pub fn has_rtl(&self) -> bool {\n        level::has_rtl(&self.levels)\n    }\n}\n\n/// Bidi information of text treated as a single paragraph.\n///\n/// The `original_classes` and `levels` vectors are indexed by code unit offsets into the text.  If a\n/// character is multiple code units wide, then its class and level will appear multiple times in these\n/// vectors.\n#[derive(Debug, PartialEq)]\npub struct ParagraphBidiInfo<'text> {\n    /// The text\n    pub text: &'text [u16],\n\n    /// The BidiClass of the character at each byte in the text.\n    pub original_classes: Vec<BidiClass>,\n\n    /// The directional embedding level of each byte in the text.\n    pub levels: Vec<Level>,\n\n    /// The paragraph embedding level.\n    pub paragraph_level: Level,\n\n    /// Whether the paragraph is purely LTR.\n    pub is_pure_ltr: bool,\n}\n\nimpl<'text> ParagraphBidiInfo<'text> {\n    /// Determine the bidi embedding level.\n    ///\n    ///\n    /// The `hardcoded-data` Cargo feature (enabled by default) must be enabled to use this.\n    ///\n    /// TODO: In early steps, check for special cases that allow later steps to be skipped. like\n    /// text that is entirely LTR.  See the `nsBidi` class from Gecko for comparison.\n    ///\n    /// TODO: Support auto-RTL base direction\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[cfg(feature = \"hardcoded-data\")]\n    #[inline]\n    pub fn new(text: &[u16], default_para_level: Option<Level>) -> ParagraphBidiInfo<'_> {\n        Self::new_with_data_source(&HardcodedBidiData, text, default_para_level)\n    }\n\n    /// Determine the bidi embedding level, with a custom [`BidiDataSource`]\n    /// for Bidi data. If you just wish to use the hardcoded Bidi data, please use [`BidiInfo::new()`]\n    /// instead (enabled with tbe default `hardcoded-data` Cargo feature).\n    ///\n    /// (This is the single-paragraph equivalent of BidiInfo::new_with_data_source,\n    /// and should be kept in sync with it.\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn new_with_data_source<'a, D: BidiDataSource>(\n        data_source: &D,\n        text: &'a [u16],\n        default_para_level: Option<Level>,\n    ) -> ParagraphBidiInfo<'a> {\n        // Here we could create a ParagraphInitialInfo struct to parallel the one\n        // used by BidiInfo, but there doesn't seem any compelling reason for it.\n        let (original_classes, paragraph_level, is_pure_ltr, has_isolate_controls) =\n            compute_initial_info(data_source, text, default_para_level, None);\n\n        let mut levels = Vec::<Level>::with_capacity(text.len());\n        let mut processing_classes = original_classes.clone();\n\n        let para_info = ParagraphInfo {\n            range: Range {\n                start: 0,\n                end: text.len(),\n            },\n            level: paragraph_level,\n        };\n\n        compute_bidi_info_for_para(\n            data_source,\n            &para_info,\n            is_pure_ltr,\n            has_isolate_controls,\n            text,\n            &original_classes,\n            &mut processing_classes,\n            &mut levels,\n        );\n\n        ParagraphBidiInfo {\n            text,\n            original_classes,\n            levels,\n            paragraph_level,\n            is_pure_ltr,\n        }\n    }\n\n    /// Produce the levels for this paragraph as needed for reordering, one level per *code unit*\n    /// in the paragraph. The returned vector includes code units that are not included\n    /// in the `line`, but will not adjust them.\n    ///\n    /// See BidiInfo::reordered_levels for details.\n    ///\n    /// (This should be kept in sync with BidiInfo::reordered_levels.)\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reordered_levels(&self, line: Range<usize>) -> Vec<Level> {\n        assert!(line.start <= self.levels.len());\n        assert!(line.end <= self.levels.len());\n\n        let mut levels = self.levels.clone();\n        let line_classes = &self.original_classes[line.clone()];\n        let line_levels = &mut levels[line.clone()];\n\n        reorder_levels(\n            line_classes,\n            line_levels,\n            self.text.subrange(line),\n            self.paragraph_level,\n        );\n\n        levels\n    }\n\n    /// Produce the levels for this paragraph as needed for reordering, one level per *character*\n    /// in the paragraph. The returned vector includes characters that are not included\n    /// in the `line`, but will not adjust them.\n    ///\n    /// See BidiInfo::reordered_levels_per_char for details.\n    ///\n    /// (This should be kept in sync with BidiInfo::reordered_levels_per_char.)\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reordered_levels_per_char(&self, line: Range<usize>) -> Vec<Level> {\n        let levels = self.reordered_levels(line);\n        self.text.char_indices().map(|(i, _)| levels[i]).collect()\n    }\n\n    /// Re-order a line based on resolved levels and return the line in display order.\n    ///\n    /// See BidiInfo::reorder_line for details.\n    ///\n    /// (This should be kept in sync with BidiInfo::reorder_line.)\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    pub fn reorder_line(&self, line: Range<usize>) -> Cow<'text, [u16]> {\n        if !level::has_rtl(&self.levels[line.clone()]) {\n            return self.text[line].into();\n        }\n        let (levels, runs) = self.visual_runs(line.clone());\n        reorder_line(self.text, line, levels, runs)\n    }\n\n    /// Reorders pre-calculated levels of a sequence of characters.\n    ///\n    /// See BidiInfo::reorder_visual for details.\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[inline]\n    pub fn reorder_visual(levels: &[Level]) -> Vec<usize> {\n        reorder_visual(levels)\n    }\n\n    /// Find the level runs within a line and return them in visual order.\n    ///\n    /// `line` is a range of code-unit indices within `levels`.\n    ///\n    /// See `BidiInfo::visual_runs` for details.\n    ///\n    /// (This should be kept in sync with BidiInfo::visual_runs.)\n    #[cfg_attr(feature = \"flame_it\", flamer::flame)]\n    #[inline]\n    pub fn visual_runs(&self, line: Range<usize>) -> (Vec<Level>, Vec<LevelRun>) {\n        let levels = self.reordered_levels(line.clone());\n        visual_runs_for_line(levels, &line)\n    }\n\n    /// If processed text has any computed RTL levels\n    ///\n    /// This information is usually used to skip re-ordering of text when no RTL level is present\n    #[inline]\n    pub fn has_rtl(&self) -> bool {\n        !self.is_pure_ltr\n    }\n\n    /// Return the paragraph's Direction (Ltr, Rtl, or Mixed) based on its levels.\n    #[inline]\n    pub fn direction(&self) -> Direction {\n        para_direction(&self.levels)\n    }\n}\n\n/// Return a line of the text in display order based on resolved levels.\n///\n/// `text`   the full text passed to the `BidiInfo` or `ParagraphBidiInfo` for analysis\n/// `line`   a range of byte indices within `text` corresponding to one line\n/// `levels` array of `Level` values, with `line`'s levels reordered into visual order\n/// `runs`   array of `LevelRun`s in visual order\n///\n/// (`levels` and `runs` are the result of calling `BidiInfo::visual_runs()` or\n/// `ParagraphBidiInfo::visual_runs()` for the line of interest.)\n///\n/// Returns: the reordered text of the line.\n///\n/// This does not apply [Rule L3] or [Rule L4] around combining characters or mirroring.\n///\n/// [Rule L3]: https://www.unicode.org/reports/tr9/#L3\n/// [Rule L4]: https://www.unicode.org/reports/tr9/#L4\nfn reorder_line(\n    text: &[u16],\n    line: Range<usize>,\n    levels: Vec<Level>,\n    runs: Vec<LevelRun>,\n) -> Cow<'_, [u16]> {\n    // If all isolating run sequences are LTR, no reordering is needed\n    if runs.iter().all(|run| levels[run.start].is_ltr()) {\n        return text[line].into();\n    }\n\n    let mut result = Vec::<u16>::with_capacity(line.len());\n    for run in runs {\n        if levels[run.start].is_rtl() {\n            let mut buf = [0; 2];\n            for c in text[run].chars().rev() {\n                result.extend(c.encode_utf16(&mut buf).iter());\n            }\n        } else {\n            result.extend(text[run].iter());\n        }\n    }\n    result.into()\n}\n\n/// Contains a reference of `BidiInfo` and one of its `paragraphs`.\n/// And it supports all operation in the `Paragraph` that needs also its\n/// `BidiInfo` such as `direction`.\n#[derive(Debug)]\npub struct Paragraph<'a, 'text> {\n    pub info: &'a BidiInfo<'text>,\n    pub para: &'a ParagraphInfo,\n}\n\nimpl<'a, 'text> Paragraph<'a, 'text> {\n    #[inline]\n    pub fn new(info: &'a BidiInfo<'text>, para: &'a ParagraphInfo) -> Paragraph<'a, 'text> {\n        Paragraph { info, para }\n    }\n\n    /// Returns if the paragraph is Left direction, right direction or mixed.\n    #[inline]\n    pub fn direction(&self) -> Direction {\n        para_direction(&self.info.levels[self.para.range.clone()])\n    }\n\n    /// Returns the `Level` of a certain character in the paragraph.\n    #[inline]\n    pub fn level_at(&self, pos: usize) -> Level {\n        let actual_position = self.para.range.start + pos;\n        self.info.levels[actual_position]\n    }\n}\n\n/// Implementation of TextSource for UTF-16 text in a [u16] array.\n/// Note that there could be unpaired surrogates present!\n\n// Convenience functions to check whether a UTF16 code unit is a surrogate.\n#[inline]\nfn is_high_surrogate(code: u16) -> bool {\n    (code & 0xFC00) == 0xD800\n}\n#[inline]\nfn is_low_surrogate(code: u16) -> bool {\n    (code & 0xFC00) == 0xDC00\n}\n\nimpl<'text> TextSource<'text> for [u16] {\n    type CharIter = Utf16CharIter<'text>;\n    type CharIndexIter = Utf16CharIndexIter<'text>;\n    type IndexLenIter = Utf16IndexLenIter<'text>;\n\n    #[inline]\n    fn len(&self) -> usize {\n        (self as &[u16]).len()\n    }\n    fn char_at(&self, index: usize) -> Option<(char, usize)> {\n        if index >= self.len() {\n            return None;\n        }\n        // Get the indicated code unit and try simply converting it to a char;\n        // this will fail if it is half of a surrogate pair.\n        let c = self[index];\n        if let Some(ch) = char::from_u32(c.into()) {\n            return Some((ch, 1));\n        }\n        // If it's a low surrogate, and was immediately preceded by a high surrogate,\n        // then we're in the middle of a (valid) character, and should return None.\n        if is_low_surrogate(c) && index > 0 && is_high_surrogate(self[index - 1]) {\n            return None;\n        }\n        // Otherwise, try to decode, returning REPLACEMENT_CHARACTER for errors.\n        if let Some(ch) = char::decode_utf16(self[index..].iter().cloned()).next() {\n            if let Ok(ch) = ch {\n                // This must be a surrogate pair, otherwise char::from_u32() above should\n                // have succeeded!\n                debug_assert!(ch.len_utf16() == 2, \"BMP should have already been handled\");\n                return Some((ch, ch.len_utf16()));\n            }\n        } else {\n            debug_assert!(\n                false,\n                \"Why did decode_utf16 return None when we're not at the end?\"\n            );\n            return None;\n        }\n        // Failed to decode UTF-16: we must have encountered an unpaired surrogate.\n        // Return REPLACEMENT_CHARACTER (not None), to continue processing the following text\n        // and keep indexing correct.\n        Some((char::REPLACEMENT_CHARACTER, 1))\n    }\n    #[inline]\n    fn subrange(&self, range: Range<usize>) -> &Self {\n        &(self as &[u16])[range]\n    }\n    #[inline]\n    fn chars(&'text self) -> Self::CharIter {\n        Utf16CharIter::new(self)\n    }\n    #[inline]\n    fn char_indices(&'text self) -> Self::CharIndexIter {\n        Utf16CharIndexIter::new(self)\n    }\n    #[inline]\n    fn indices_lengths(&'text self) -> Self::IndexLenIter {\n        Utf16IndexLenIter::new(self)\n    }\n    #[inline]\n    fn char_len(ch: char) -> usize {\n        ch.len_utf16()\n    }\n}\n\n/// Iterator over UTF-16 text in a [u16] slice, returning (index, char_len) tuple.\n#[derive(Debug)]\npub struct Utf16IndexLenIter<'text> {\n    text: &'text [u16],\n    cur_pos: usize,\n}\n\nimpl<'text> Utf16IndexLenIter<'text> {\n    #[inline]\n    pub fn new(text: &'text [u16]) -> Self {\n        Utf16IndexLenIter { text, cur_pos: 0 }\n    }\n}\n\nimpl Iterator for Utf16IndexLenIter<'_> {\n    type Item = (usize, usize);\n\n    #[inline]\n    fn next(&mut self) -> Option<Self::Item> {\n        if let Some((_, char_len)) = self.text.char_at(self.cur_pos) {\n            let result = (self.cur_pos, char_len);\n            self.cur_pos += char_len;\n            return Some(result);\n        }\n        None\n    }\n}\n\n/// Iterator over UTF-16 text in a [u16] slice, returning (index, char) tuple.\n#[derive(Debug)]\npub struct Utf16CharIndexIter<'text> {\n    text: &'text [u16],\n    cur_pos: usize,\n}\n\nimpl<'text> Utf16CharIndexIter<'text> {\n    pub fn new(text: &'text [u16]) -> Self {\n        Utf16CharIndexIter { text, cur_pos: 0 }\n    }\n}\n\nimpl Iterator for Utf16CharIndexIter<'_> {\n    type Item = (usize, char);\n\n    fn next(&mut self) -> Option<Self::Item> {\n        if let Some((ch, char_len)) = self.text.char_at(self.cur_pos) {\n            let result = (self.cur_pos, ch);\n            self.cur_pos += char_len;\n            return Some(result);\n        }\n        None\n    }\n}\n\n/// Iterator over UTF-16 text in a [u16] slice, returning Unicode chars.\n/// (Unlike the other iterators above, this also supports reverse iteration.)\n#[derive(Debug)]\npub struct Utf16CharIter<'text> {\n    text: &'text [u16],\n    cur_pos: usize,\n    end_pos: usize,\n}\n\nimpl<'text> Utf16CharIter<'text> {\n    pub fn new(text: &'text [u16]) -> Self {\n        Utf16CharIter {\n            text,\n            cur_pos: 0,\n            end_pos: text.len(),\n        }\n    }\n}\n\nimpl Iterator for Utf16CharIter<'_> {\n    type Item = char;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        if let Some((ch, char_len)) = self.text.char_at(self.cur_pos) {\n            self.cur_pos += char_len;\n            return Some(ch);\n        }\n        None\n    }\n}\n\nimpl DoubleEndedIterator for Utf16CharIter<'_> {\n    fn next_back(&mut self) -> Option<Self::Item> {\n        if self.end_pos <= self.cur_pos {\n            return None;\n        }\n        self.end_pos -= 1;\n        if let Some(ch) = char::from_u32(self.text[self.end_pos] as u32) {\n            return Some(ch);\n        }\n        if self.end_pos > self.cur_pos {\n            if let Some((ch, char_len)) = self.text.char_at(self.end_pos - 1) {\n                if char_len == 2 {\n                    self.end_pos -= 1;\n                    return Some(ch);\n                }\n            }\n        }\n        Some(char::REPLACEMENT_CHARACTER)\n    }\n}\n"
    },
    {
      "package": "unicode-bidi-mirroring@0.1.0",
      "sourcePath": "README.md",
      "sha256": "b184c317d71abff063675c1a7170f155c18b37663644afe77e7dfee7f57b5cc0",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "## unicode-bidi-mirroring\n[![Crates.io](https://img.shields.io/crates/v/unicode-bidi-mirroring.svg)](https://crates.io/crates/unicode-bidi-mirroring)\n[![Documentation](https://docs.rs/unicode-bidi-mirroring/badge.svg)](https://docs.rs/unicode-bidi-mirroring)\n\nThis library implements\n[Unicode Bidi Mirroring](https://unicode.org/reports/tr44/#BidiMirroring.txt) property detection.\n\n```rust\nuse unicode_bidi_mirroring::*;\n\nassert_eq!(get_mirrored('A'), None);\nassert_eq!(get_mirrored('\\u{2039}'), Some('\\u{203A}'));\nassert_eq!(get_mirrored('\\u{203A}'), Some('\\u{2039}'));\n\nassert_eq!(is_mirroring('A'), false);\nassert_eq!(is_mirroring('\\u{29C4}'), true);\nassert_eq!(is_mirroring('\\u{22FF}'), true);\n```\n\n### License\n\nLicensed under either of\n\n- Apache License, Version 2.0\n  ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license\n  ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "unicode-ccc@0.1.2",
      "sourcePath": "README.md",
      "sha256": "dd9213583228412ac610e974abd07208935a797903fc7b829e91f7cabd4ddec3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "## unicode-ccc\n[![Crates.io](https://img.shields.io/crates/v/unicode-ccc.svg)](https://crates.io/crates/unicode-ccc)\n[![Documentation](https://docs.rs/unicode-ccc/badge.svg)](https://docs.rs/unicode-ccc)\n\nThis library implements\n[Unicode Canonical Combining Class](https://unicode.org/reports/tr44/#Canonical_Combining_Class_Values) detection.\n\n```rust\nuse unicode_ccc::*;\n\nassert_eq!(get_canonical_combining_class('A'), CanonicalCombiningClass::NotReordered);\nassert_eq!(get_canonical_combining_class('\\u{0A3C}'), CanonicalCombiningClass::Nukta);\nassert_eq!(get_canonical_combining_class('\\u{18A9}'), CanonicalCombiningClass::AboveLeft);\n```\n\n### License\n\nLicensed under either of\n\n- Apache License, Version 2.0\n  ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license\n  ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "unicode-ident@1.0.26",
      "sourcePath": "README.md",
      "sha256": "085da9383f04b605f1c8726dbbc2dfb134e2c0ab662f3c40c6b78be858ab651e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Unicode ident\n=============\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/unicode--ident-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/unicode-ident)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/unicode-ident.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/unicode-ident)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-unicode--ident-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/unicode-ident)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/unicode-ident/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/unicode-ident/actions?query=branch%3Amaster)\n\nImplementation of [Unicode Standard Annex #31][tr31] for determining which\n`char` values are valid in programming language identifiers.\n\n[tr31]: https://www.unicode.org/reports/tr31/\n\nThis crate is a better optimized implementation of the older `unicode-xid`\ncrate. This crate uses less static storage, and is able to classify both ASCII\nand non-ASCII codepoints with better performance, 6&times; faster than\n`unicode-xid`.\n\n<br>\n\n## Comparison of performance\n\nThe following table shows a comparison between five Unicode identifier\nimplementations.\n\n- `unicode-ident` is this crate;\n- [`unicode-xid`] is a widely used crate run by the \"unicode-rs\" org;\n- `ucd-trie` and `fst` are two data structures supported by the [`ucd-generate`] tool;\n- [`roaring`] is a Rust implementation of Roaring bitmap.\n\nThe *static storage* column shows the total size of `static` tables that the\ncrate bakes into your binary, measured in 1000s of bytes.\n\nThe remaining columns show the **cost per call** to evaluate whether a single\n`char` has the XID\\_Start or XID\\_Continue Unicode property, comparing across\ndifferent ratios of ASCII to non-ASCII codepoints in the input data.\n\n[`unicode-xid`]: https://github.com/unicode-rs/unicode-xid\n[`ucd-generate`]: https://github.com/BurntSushi/ucd-generate\n[`roaring`]: https://github.com/RoaringBitmap/roaring-rs\n\n| | static storage | 0% nonascii | 1% | 10% | 100% nonascii |\n|---|---|---|---|---|---|\n| **`unicode-ident`** | 10.3 K | 0.36 ns | 0.37 ns | 0.37 ns | 0.43 ns |\n| **`unicode-xid`** | 12.2 K | 1.63 ns | 1.70 ns | 1.82 ns | 4.56 ns |\n| **`ucd-trie`** | 10.8 K | 1.01 ns | 0.73 ns | 0.97 ns | 1.09 ns |\n| **`fst`** | 149 K | 22.0 ns | 21.9 ns | 20.9 ns | 10.5 ns |\n| **`roaring`** | 66.1 K | 1.91 ns | 1.90 ns | 1.94 ns | 2.67 ns |\n\nSource code for the benchmark is provided in the *bench* directory of this repo\nand may be repeated by running `cargo criterion`.\n\n<br>\n\n## Comparison of data structures\n\n#### unicode-xid\n\nThey use a sorted array of character ranges, and do a binary search to look up\nwhether a given character lands inside one of those ranges.\n\n```rust\nstatic XID_Continue_table: [(char, char); 763] = [\n    ('\\u{30}', '\\u{39}'),  // 0-9\n    ('\\u{41}', '\\u{5a}'),  // A-Z\n    …\n    ('\\u{e0100}', '\\u{e01ef}'),\n];\n```\n\nThe static storage used by this data structure scales with the number of\ncontiguous ranges of identifier codepoints in Unicode. Every table entry\nconsumes 8 bytes, because it consists of a pair of 32-bit `char` values.\n\nIn some ranges of the Unicode codepoint space, this is quite a sparse\nrepresentation &ndash; there are some ranges where tens of thousands of adjacent\ncodepoints are all valid identifier characters. In other places, the\nrepresentation is quite inefficient. A characater like `µ` (U+00B5) which is\nsurrounded by non-identifier codepoints consumes 64 bits in the table, while it\nwould be just 1 bit in a dense bitmap.\n\nOn a system with 64-byte cache lines, binary searching the table touches 7 cache\nlines on average. Each cache line fits only 8 table entries. Additionally, the\nbranching performed during the binary search is probably mostly unpredictable to\nthe branch predictor.\n\nOverall, the crate ends up being about 6&times; slower on non-ASCII input\ncompared to the fastest crate.\n\nA potential improvement would be to pack the table entries more compactly.\nRust's `char` type is a 21-bit integer padded to 32 bits, which means every\ntable entry is holding 22 bits of wasted space, adding up to 3.9 K. They could\ninstead fit every table entry into 6 bytes, leaving out some of the padding, for\na 25% improvement in space used. With some cleverness it may be possible to fit\nin 5 bytes or even 4 bytes by storing a low char and an extent, instead of low\nchar and high char. I don't expect that performance would improve much but this\ncould be the most efficient for space across all the libraries, needing only\nabout 7 K to store.\n\n#### ucd-trie\n\nTheir data structure is a compressed trie set specifically tailored for Unicode\ncodepoints. The design is credited to Raph Levien in [rust-lang/rust#33098].\n\n[rust-lang/rust#33098]: https://github.com/rust-lang/rust/pull/33098\n\n```rust\npub struct TrieSet {\n    tree1_level1: &'static [u64; 32],\n    tree2_level1: &'static [u8; 992],\n    tree2_level2: &'static [u64],\n    tree3_level1: &'static [u8; 256],\n    tree3_level2: &'static [u8],\n    tree3_level3: &'static [u64],\n}\n```\n\nIt represents codepoint sets using a trie to achieve prefix compression. The\nfinal states of the trie are embedded in leaves or \"chunks\", where each chunk is\na 64-bit integer. Each bit position of the integer corresponds to whether a\nparticular codepoint is in the set or not. These chunks are not just a compact\nrepresentation of the final states of the trie, but are also a form of suffix\ncompression. In particular, if multiple ranges of 64 contiguous codepoints have\nthe same Unicode properties, then they all map to the same chunk in the final\nlevel of the trie.\n\nBeing tailored for Unicode codepoints, this trie is partitioned into three\ndisjoint sets: tree1, tree2, tree3. The first set corresponds to codepoints \\[0,\n0x800), the second \\[0x800, 0x10000) and the third \\[0x10000, 0x110000). These\npartitions conveniently correspond to the space of 1 or 2 byte UTF-8 encoded\ncodepoints, 3 byte UTF-8 encoded codepoints and 4 byte UTF-8 encoded codepoints,\nrespectively.\n\nLookups in this data structure are significantly more efficient than binary\nsearch. A lookup touches either 1, 2, or 3 cache lines based on which of the\ntrie partitions is being accessed.\n\nOne possible performance improvement would be for this crate to expose a way to\nquery based on a UTF-8 encoded string, returning the Unicode property\ncorresponding to the first character in the string. Without such an API, the\ncaller is required to tokenize their UTF-8 encoded input data into `char`, hand\nthe `char` into `ucd-trie`, only for `ucd-trie` to undo that work by converting\nback into the variable-length representation for trie traversal.\n\n#### fst\n\nUses a [finite state transducer][fst]. This representation is built into\n[ucd-generate] but I am not aware of any advantage over the `ucd-trie`\nrepresentation. In particular `ucd-trie` is optimized for storing Unicode\nproperties while `fst` is not.\n\n[fst]: https://github.com/BurntSushi/fst\n[ucd-generate]: https://github.com/BurntSushi/ucd-generate\n\nAs far as I can tell, the main thing that causes `fst` to have large size and\nslow lookups for this use case relative to `ucd-trie` is that it does not\nspecialize for the fact that only 21 of the 32 bits in a `char` are meaningful.\nThere are some dense arrays in the structure with large ranges that could never\npossibly be used.\n\n#### roaring\n\nThis crate is a pure-Rust implementation of [Roaring Bitmap], a data structure\ndesigned for storing sets of 32-bit unsigned integers.\n\n[Roaring Bitmap]: https://roaringbitmap.org/about/\n\nRoaring bitmaps are compressed bitmaps which tend to outperform conventional\ncompressed bitmaps such as WAH, EWAH or Concise. In some instances, they can be\nhundreds of times faster and they often offer significantly better compression.\n\nIn this use case the performance was reasonably competitive but still\nsubstantially slower than the Unicode-optimized crates. Meanwhile the\ncompression was significantly worse, requiring 6&times; as much storage for the\ndata structure.\n\nI also benchmarked the [`croaring`] crate which is an FFI wrapper around the C\nreference implementation of Roaring Bitmap. This crate was consistently about\n15% slower than pure-Rust `roaring`, which could just be FFI overhead. I did not\ninvestigate further.\n\n[`croaring`]: https://crates.io/crates/croaring\n\n#### unicode-ident\n\nThis crate is most similar to the `ucd-trie` library, in that it's based on\nbitmaps stored in the leafs of a trie representation, achieving both prefix\ncompression and suffix compression.\n\nThe key differences are:\n\n- Uses a single 2-level trie, rather than 3 disjoint partitions of different\n  depth each.\n- Uses significantly larger chunks: 512 bits rather than 64 bits.\n- Compresses the XID\\_Start and XID\\_Continue properties together\n  simultaneously, rather than duplicating identical trie leaf chunks across the\n  two.\n\nThe following diagram show the XID\\_Start and XID\\_Continue Unicode boolean\nproperties in uncompressed form, in row-major order:\n\n<table>\n<tr><th>XID_Start</th><th>XID_Continue</th></tr>\n<tr>\n<td><img alt=\"XID_Start bitmap\" width=\"256\" src=\"https://user-images.githubusercontent.com/1940490/168647353-c6eeb922-afec-49b2-9ef5-c03e9d1e0760.png\"></td>\n<td><img alt=\"XID_Continue bitmap\" width=\"256\" src=\"https://user-images.githubusercontent.com/1940490/168647367-f447cca7-2362-4d7d-8cd7-d21c011d329b.png\"></td>\n</tr>\n</table>\n\nUncompressed, these would take 140 K to store, which is beyond what would be\nreasonable. However, as you can see there is a large degree of similarity\nbetween the two bitmaps and across the rows, which lends well to compression.\n\nThis crate stores one 512-bit \"row\" of the above bitmaps in the leaf level of a\ntrie, and a single additional level to index into the leafs. There are 134\nunique 512-bit chunks across the two bitmaps.\n\nThe chunk size of 512 bits is selected as the size that minimizes the total size\nof the data structure. A smaller chunk, like 256 or 128 bits, would achieve\nbetter deduplication but require a larger index. A larger chunk would increase\nredundancy in the leaf bitmaps. 512 bit chunks are the optimum for total size of\nthe index plus leaf bitmaps.\n\nThe chunk data is compressed using the Kuhn–Munkres algorithm for bipartite\nmatching to eliminate redundancies between the second half of any chunk and the\nfirst half of any other chunk. This achieves an additional 9% compression of the\nleaf level, leaving 122 chunks that can be indexed at the half-chunk level using\nan 8-bit index. Note that this is not the same as using chunks which are half\nthe size, because it does not necessitate raising the size of the trie's first\nlevel.\n\nIn contrast to binary search or the `ucd-trie` crate, performing lookups in this\ndata structure is straight-line code with no need for branching.\n\n```asm\nis_xid_start:\n\tmov eax, edi\n\tshr eax, 9\n\tcmp edi, 261632\n\tmov ecx, offset unicode_ident::tables::TRIE_START+17\n\tlea rax, [rax + unicode_ident::tables::TRIE_START]\n\tcmovb rcx, rax\n\tmovzx eax, byte ptr [rcx]\n\tmov ecx, 1539\n\tbextr ecx, edi, ecx\n\tand edi, 7\n\tshl eax, 5\n\tmovzx eax, byte ptr [rax + rcx + unicode_ident::tables::LEAF]\n\tbt eax, edi\n\tsetb al\n\tret\n```\n\n<br>\n\n## License\n\nUse of the Unicode Character Database, as this crate does, is governed by the <a\nhref=\"LICENSE-UNICODE\">Unicode license</a>.\n\nAll intellectual property within this crate that is **not generated** using the\nUnicode Character Database as input is licensed under either of <a\nhref=\"LICENSE-APACHE\">Apache License, Version 2.0</a> or <a\nhref=\"LICENSE-MIT\">MIT license</a> at your option.\n\nThe **generated** files incorporate tabular data derived from the Unicode\nCharacter Database, together with intellectual property from the original source\ncode content of the crate. One must comply with the terms of both the Unicode\nLicense Agreement and either of the Apache license or MIT license when those\ngenerated files are involved.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe licensed as just described, without any additional terms or conditions.\n"
    },
    {
      "package": "unicode-script@0.5.8",
      "sourcePath": "scripts/unicode.py",
      "sha256": "72f5fed57ffcbff045013c8101e875596ce8eeedde2c979f7cb904c315f3c32f",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "#!/usr/bin/env python\n#\n# Copyright 2011-2015 The Rust Project Developers. See the COPYRIGHT\n# file at the top-level directory of this distribution and at\n# http://rust-lang.org/COPYRIGHT.\n#\n# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n# option. This file may not be copied, modified, or distributed\n# except according to those terms.\n\n# This script uses the following Unicode tables:\n# - PropertyValueAliases.txt\n# - ScriptExtensions.txt\n# - Scripts.txt\n#\n# Since this should not require frequent updates, we just store this\n# out-of-line and check the unicode.rs file into git.\n\nimport fileinput, re, os, sys\n\npreamble = '''// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n// NOTE: The following code was generated by \"scripts/unicode.py\", do not edit directly\n\n#![allow(missing_docs, non_upper_case_globals, non_snake_case)]\n\npub use tables_impl::*;\n\n#[rustfmt::skip]\nmod tables_impl {\nuse crate::ScriptExtension;\n'''\n\n# Close `mod impl {`\nending='''\n}\n'''\n\nUNICODE_VERSION = (17, 0, 0)\n\nUNICODE_VERSION_NUMBER = \"%s.%s.%s\" %UNICODE_VERSION\n\ndef escape_char(c):\n    return \"'\\\\u{%x}'\" % c\n\ndef fetch(f):\n    if not os.path.exists(os.path.basename(f)):\n        if \"emoji\" in f:\n            os.system(\"curl -O https://www.unicode.org/Public/emoji/%s.%s/%s\"\n                      % (UNICODE_VERSION[0], UNICODE_VERSION[1], f))\n        else:\n            os.system(\"curl -O https://www.unicode.org/Public/%s/ucd/%s\"\n                      % (UNICODE_VERSION_NUMBER, f))\n\n    if not os.path.exists(os.path.basename(f)):\n        sys.stderr.write(\"cannot load %s\" % f)\n        exit(1)\n\ndef group_cats(cats):\n    cats_out = {}\n    for cat in cats:\n        cats_out[cat] = group_cat(cats[cat])\n    return cats_out\n\ndef aliases():\n    \"\"\"\n    Fetch the shorthand aliases for each longhand Script name\n    \"\"\"\n    fetch(\"PropertyValueAliases.txt\")\n    longforms = {}\n    shortforms = {}\n    re1 = re.compile(r\"^ *sc *; *(\\w+) *; *(\\w+)\")\n    for line in fileinput.input(os.path.basename(\"PropertyValueAliases.txt\")):\n        m = re1.match(line)\n        if m:\n            l = m.group(2).strip()\n            s = m.group(1).strip()\n            assert(s not in longforms)\n            assert(l not in shortforms)\n            longforms[s] = l\n            shortforms[l] = s\n        else:\n            continue\n\n    return (longforms, shortforms)\n\ndef format_table_content(f, content, indent):\n    line = \" \"*indent\n    first = True\n    for chunk in content.split(\",\"):\n        if len(line) + len(chunk) < 98:\n            if first:\n                line += chunk\n            else:\n                line += \", \" + chunk\n            first = False\n        else:\n            f.write(line + \",\\n\")\n            line = \" \"*indent + chunk\n    f.write(line)\n\n# Implementation from unicode-segmentation\ndef load_properties(f, interestingprops):\n    fetch(f)\n    props = {}\n    # Note: these regexes are different from those in unicode-segmentation,\n    # becase we need to handle spaces here\n    re1 = re.compile(r\"^ *([0-9A-F]+) *; *([^#]+) *#\")\n    re2 = re.compile(r\"^ *([0-9A-F]+)\\.\\.([0-9A-F]+) *; *([^#]+) *#\")\n\n    for line in fileinput.input(os.path.basename(f)):\n        prop = None\n        d_lo = 0\n        d_hi = 0\n        m = re1.match(line)\n        if m:\n            d_lo = m.group(1)\n            d_hi = m.group(1)\n            prop = m.group(2).strip()\n        else:\n            m = re2.match(line)\n            if m:\n                d_lo = m.group(1)\n                d_hi = m.group(2)\n                prop = m.group(3).strip()\n            else:\n                continue\n        if interestingprops and prop not in interestingprops:\n            continue\n        d_lo = int(d_lo, 16)\n        d_hi = int(d_hi, 16)\n        if prop not in props:\n            props[prop] = []\n        props[prop].append((d_lo, d_hi))\n\n    return props\n\n# Implementation from unicode-segmentation\ndef emit_table(f, name, t_data, t_type = \"&'static [(char, char)]\", is_pub=True,\n        pfun=lambda x: \"(%s,%s)\" % (escape_char(x[0]), escape_char(x[1])), is_const=True):\n    pub_string = \"const\"\n    if not is_const:\n        pub_string = \"let\"\n    if is_pub:\n        pub_string = \"pub \" + pub_string\n    f.write(\"    %s %s: %s = &[\\n\" % (pub_string, name, t_type))\n    data = \"\"\n    first = True\n    for dat in t_data:\n        if not first:\n            data += \",\"\n        first = False\n        data += pfun(dat)\n    format_table_content(f, data, 8)\n    f.write(\"\\n    ];\\n\\n\")\n\ndef emit_search(f):\n    f.write(\"\"\"\npub fn bsearch_range_value_table<T: Copy>(c: char, r: &'static [(char, char, T)]) -> Option<T> {\n    use core::cmp::Ordering::{Equal, Less, Greater};\n    match r.binary_search_by(|&(lo, hi, _)| {\n        if lo <= c && c <= hi { Equal }\n        else if hi < c { Less }\n        else { Greater }\n    }) {\n        Ok(idx) => {\n            let (_, _, cat) = r[idx];\n            Some(cat)\n        }\n        Err(_) => None\n    }\n}\n\n#[inline]\npub fn get_script(c: char) -> Option<Script> {\n    bsearch_range_value_table(c, SCRIPTS)\n}\n\n#[inline]\npub fn get_script_extension(c: char) -> Option<ScriptExtension> {\n    bsearch_range_value_table(c, SCRIPT_EXTENSIONS)\n}\n\"\"\")\n\ndef emit_enums(f, script_list, extension_list, longforms):\n    \"\"\"\n    Emit the Script and ScriptExtension enums as well as any related utility functions\n    \"\"\"\n\n    f.write(\"\"\"\n#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]\n#[non_exhaustive]\n#[allow(non_camel_case_types)]\n#[repr(u8)]\n/// A value of the `Script` property\npub enum Script {\n    /// Unknown script\n    Unknown = 0xFF,\n    /// Zyyy\n    Common = 0xFE,\n    /// Zinh,\n    Inherited = 0xFD,\n\"\"\")\n    for (i, script) in enumerate(script_list):\n        f.write(\"    /// %s\\n    %s = %s,\\n\" % (script, longforms[script], i))\n    f.write(\"}\\n\")\n    f.write(\"pub const NEXT_SCRIPT: u8 = %s;\" % len(script_list))\n    f.write(\"\"\"\n\npub mod script_extensions {\n    use crate::ScriptExtension;\n    pub const COMMON: ScriptExtension = ScriptExtension::new_common();\n    pub const INHERITED: ScriptExtension = ScriptExtension::new_inherited();\n    pub const UNKNOWN: ScriptExtension = ScriptExtension::new_unknown();\n\"\"\")\n    for (i, script) in enumerate(script_list):\n        first = 0\n        second = 0\n        third = 0\n        # need to replace L because `hex()` will spit out an L suffix for larger numbers\n        if i < 64:\n            first = hex(1 << i).replace(\"L\", \"\")\n        elif i < 128:\n            second = hex(1 << (i - 64)).replace(\"L\", \"\")\n        else:\n            third = hex(1 << (i - 128)).replace(\"L\", \"\")\n        f.write(\"    /// %s\\n    pub const %s: ScriptExtension = ScriptExtension::new(%s, %s, %s);\\n\" %\n                (longforms[script], longforms[script].upper(), first, second, third))\n        if script != longforms[script]:\n            f.write(\"    /// %s\\n    pub const %s: ScriptExtension = %s;\\n\" %\n                    (longforms[script], script.upper(), longforms[script].upper()))\n    for ext in extension_list:\n        longform = \", \".join([longforms[s] for s in ext])\n        name = \"_\".join([s.upper() for s in ext])\n        expr = ext[0].upper()\n        for e in ext[1:]:\n            expr = \"%s.union(%s)\" % (expr, e.upper())\n        f.write(\"    /// %s\\n    pub const %s: ScriptExtension = %s;\\n\" % (longform, name, expr))\n    f.write(\"\"\"}\n\n\"\"\")\n\n    # Generate implementation for the `Script`\n    generate_script_impl(f)\n\n\ndef generate_script_impl(f):\n    \"\"\"Generates an `impl Script { ... }` section with all the required functions\"\"\"\n\n    # Open `impl Script` section.\n    f.write(\"\"\"impl Script {\n\"\"\")\n\n    # Generate impl of `inner_full_name`.\n    f.write(\"\"\"\n    #[inline]\n    pub(crate) fn inner_full_name(self) -> &'static str {\n        match self {\n            Script::Unknown => \"Unknown\",\n            Script::Common => \"Common\",\n            Script::Inherited => \"Inherited\",\n\"\"\")\n    for script in script_list:\n        f.write(\"            Script::%s => \\\"%s\\\",\\n\" % (longforms[script], longforms[script]))\n    f.write(\"\"\"        }\n    }\n\"\"\")\n\n    # Generate impl of `inner_from_full_name`.\n    f.write(\"\"\"\n    #[inline]\n    pub(crate) fn inner_from_full_name(input: &str) -> Option<Self> {\n        match input {\n            \"Unknown\" => Some(Script::Unknown),\n            \"Common\" => Some(Script::Common),\n            \"Inherited\" => Some(Script::Inherited),\n\"\"\")\n    for script in script_list:\n        f.write(\"            \\\"%s\\\" => Some(Script::%s),\\n\" % (longforms[script], longforms[script]))\n    f.write(\"            _ => None,\\n\" )\n    f.write(\"\"\"        }\n    }\n\"\"\")\n\n    # Generate impl of `inner_short_name`\n    f.write(\"\"\"\n    #[inline]\n    pub(crate) fn inner_short_name(self) -> &'static str {\n        match self {\n            Script::Unknown => \"Zzzz\",\n            Script::Common => \"Zyyy\",\n            Script::Inherited => \"Zinh\",\n\"\"\")\n    for script in script_list:\n        f.write(\"            Script::%s => \\\"%s\\\",\\n\" % (longforms[script], script))\n    f.write(\"\"\"        }\n    }\n\"\"\")\n\n    # Generate impl of `inner_from_short_name`\n    f.write(\"\"\"\n    #[inline]\n    pub(crate) fn inner_from_short_name(input: &str) -> Option<Self> {\n        match input {\n            \"Zzzz\" => Some(Script::Unknown),\n            \"Zyyy\" => Some(Script::Common),\n            \"Zinh\" => Some(Script::Inherited),\n\"\"\")\n    for script in script_list:\n        f.write(\"            \\\"%s\\\" => Some(Script::%s),\\n\" % (script, longforms[script]))\n    f.write(\"\"\"        _ => None,\\n\"\"\")\n    f.write(\"\"\"        }\n    }\n\"\"\")\n\n    # Generate impl of `for_integer`\n    f.write(\"\"\"\n    #[inline]\n    pub(crate) fn for_integer(value: u8) -> Self {\n        match value {\n\"\"\")\n    for (i, script) in enumerate(script_list):\n        f.write(\"            %s => Script::%s,\\n\" % (i, longforms[script]))\n    f.write(\"\"\"            _ => unreachable!(),\n        }\n    }\n\"\"\")\n\n    # Close `impl Script` section\n    f.write(\"\"\"\n}\n\"\"\")\n\ndef extension_name(ext):\n    \"\"\"Get the rust source for a given ScriptExtension\"\"\"\n    return \"script_extensions::%s\" % \"_\".join([e.upper() for e in ext])\n\n\nif __name__ == \"__main__\":\n    r = \"tables.rs\"\n    if os.path.exists(r):\n        os.remove(r)\n    with open(r, \"w\") as rf:\n        # write the file's preamble\n        rf.write(preamble)\n        rf.write(\"\"\"\n/// The version of [Unicode](http://www.unicode.org/)\n/// that this version of unicode-script is based on.\npub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);\n\"\"\" % UNICODE_VERSION)\n\n\n        (longforms, shortforms) = aliases()\n\n        scripts = load_properties(\"Scripts.txt\", [])\n\n        script_table = []\n        script_list = []\n\n        for script in scripts:\n            if script not in [\"Common\", \"Unknown\", \"Inherited\"]:\n                script_list.append(shortforms[script])\n            script_table.extend([(x, y, shortforms[script]) for (x, y) in scripts[script]])\n        script_list.sort()\n        script_table.sort(key=lambda w: w[0])\n\n\n        extensions = load_properties(\"ScriptExtensions.txt\", [])\n        extension_table = []\n        extension_list = []\n\n        for ext in extensions:\n            split = ext.split(\" \")\n            split.sort()\n            output_ext = [ext]\n            if len(split) > 1:\n                extension_list.append(split)\n                output_ext = split\n            extension_table.extend([(x, y, output_ext) for (x, y) in extensions[ext]])\n        extension_table.sort(key=lambda w: w[0])\n\n\n        emit_enums(rf, script_list, extension_list, longforms)\n        emit_search(rf)\n\n        emit_table(rf, \"SCRIPTS\", script_table, t_type = \"&'static [(char, char, Script)]\",\n                   is_pub=False , pfun=lambda x: \"(%s,%s, Script::%s)\" % (escape_char(x[0]), escape_char(x[1]), longforms[x[2]]))\n        emit_table(rf, \"SCRIPT_EXTENSIONS\", extension_table, t_type = \"&'static [(char, char, ScriptExtension)]\",\n                   is_pub=False , pfun=lambda x: \"(%s,%s,%s)\" % (escape_char(x[0]), escape_char(x[1]), extension_name(x[2])))\n\n        # emit_table(rf, \"FOObar\", properties)\n\n        rf.write(ending)\n"
    },
    {
      "package": "unicode-script@0.5.8",
      "sourcePath": "src/tables.rs",
      "sha256": "036be4f0b3284a737fc58071a8017ab64c08d040e00846978aa5d9add793cf3b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n// NOTE: The following code was generated by \"scripts/unicode.py\", do not edit directly\n\n#![allow(missing_docs, non_upper_case_globals, non_snake_case)]\n\npub use tables_impl::*;\n\n#[rustfmt::skip]\nmod tables_impl {\nuse crate::ScriptExtension;\n\n/// The version of [Unicode](http://www.unicode.org/)\n/// that this version of unicode-script is based on.\npub const UNICODE_VERSION: (u64, u64, u64) = (17, 0, 0);\n\n#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]\n#[non_exhaustive]\n#[allow(non_camel_case_types)]\n#[repr(u8)]\n/// A value of the `Script` property\npub enum Script {\n    /// Unknown script\n    Unknown = 0xFF,\n    /// Zyyy\n    Common = 0xFE,\n    /// Zinh,\n    Inherited = 0xFD,\n    /// Adlm\n    Adlam = 0,\n    /// Aghb\n    Caucasian_Albanian = 1,\n    /// Ahom\n    Ahom = 2,\n    /// Arab\n    Arabic = 3,\n    /// Armi\n    Imperial_Aramaic = 4,\n    /// Armn\n    Armenian = 5,\n    /// Avst\n    Avestan = 6,\n    /// Bali\n    Balinese = 7,\n    /// Bamu\n    Bamum = 8,\n    /// Bass\n    Bassa_Vah = 9,\n    /// Batk\n    Batak = 10,\n    /// Beng\n    Bengali = 11,\n    /// Berf\n    Beria_Erfe = 12,\n    /// Bhks\n    Bhaiksuki = 13,\n    /// Bopo\n    Bopomofo = 14,\n    /// Brah\n    Brahmi = 15,\n    /// Brai\n    Braille = 16,\n    /// Bugi\n    Buginese = 17,\n    /// Buhd\n    Buhid = 18,\n    /// Cakm\n    Chakma = 19,\n    /// Cans\n    Canadian_Aboriginal = 20,\n    /// Cari\n    Carian = 21,\n    /// Cham\n    Cham = 22,\n    /// Cher\n    Cherokee = 23,\n    /// Chrs\n    Chorasmian = 24,\n    /// Copt\n    Coptic = 25,\n    /// Cpmn\n    Cypro_Minoan = 26,\n    /// Cprt\n    Cypriot = 27,\n    /// Cyrl\n    Cyrillic = 28,\n    /// Deva\n    Devanagari = 29,\n    /// Diak\n    Dives_Akuru = 30,\n    /// Dogr\n    Dogra = 31,\n    /// Dsrt\n    Deseret = 32,\n    /// Dupl\n    Duployan = 33,\n    /// Egyp\n    Egyptian_Hieroglyphs = 34,\n    /// Elba\n    Elbasan = 35,\n    /// Elym\n    Elymaic = 36,\n    /// Ethi\n    Ethiopic = 37,\n    /// Gara\n    Garay = 38,\n    /// Geor\n    Georgian = 39,\n    /// Glag\n    Glagolitic = 40,\n    /// Gong\n    Gunjala_Gondi = 41,\n    /// Gonm\n    Masaram_Gondi = 42,\n    /// Goth\n    Gothic = 43,\n    /// Gran\n    Grantha = 44,\n    /// Grek\n    Greek = 45,\n    /// Gujr\n    Gujarati = 46,\n    /// Gukh\n    Gurung_Khema = 47,\n    /// Guru\n    Gurmukhi = 48,\n    /// Hang\n    Hangul = 49,\n    /// Hani\n    Han = 50,\n    /// Hano\n    Hanunoo = 51,\n    /// Hatr\n    Hatran = 52,\n    /// Hebr\n    Hebrew = 53,\n    /// Hira\n    Hiragana = 54,\n    /// Hluw\n    Anatolian_Hieroglyphs = 55,\n    /// Hmng\n    Pahawh_Hmong = 56,\n    /// Hmnp\n    Nyiakeng_Puachue_Hmong = 57,\n    /// Hung\n    Old_Hungarian = 58,\n    /// Ital\n    Old_Italic = 59,\n    /// Java\n    Javanese = 60,\n    /// Kali\n    Kayah_Li = 61,\n    /// Kana\n    Katakana = 62,\n    /// Kawi\n    Kawi = 63,\n    /// Khar\n    Kharoshthi = 64,\n    /// Khmr\n    Khmer = 65,\n    /// Khoj\n    Khojki = 66,\n    /// Kits\n    Khitan_Small_Script = 67,\n    /// Knda\n    Kannada = 68,\n    /// Krai\n    Kirat_Rai = 69,\n    /// Kthi\n    Kaithi = 70,\n    /// Lana\n    Tai_Tham = 71,\n    /// Laoo\n    Lao = 72,\n    /// Latn\n    Latin = 73,\n    /// Lepc\n    Lepcha = 74,\n    /// Limb\n    Limbu = 75,\n    /// Lina\n    Linear_A = 76,\n    /// Linb\n    Linear_B = 77,\n    /// Lisu\n    Lisu = 78,\n    /// Lyci\n    Lycian = 79,\n    /// Lydi\n    Lydian = 80,\n    /// Mahj\n    Mahajani = 81,\n    /// Maka\n    Makasar = 82,\n    /// Mand\n    Mandaic = 83,\n    /// Mani\n    Manichaean = 84,\n    /// Marc\n    Marchen = 85,\n    /// Medf\n    Medefaidrin = 86,\n    /// Mend\n    Mende_Kikakui = 87,\n    /// Merc\n    Meroitic_Cursive = 88,\n    /// Mero\n    Meroitic_Hieroglyphs = 89,\n    /// Mlym\n    Malayalam = 90,\n    /// Modi\n    Modi = 91,\n    /// Mong\n    Mongolian = 92,\n    /// Mroo\n    Mro = 93,\n    /// Mtei\n    Meetei_Mayek = 94,\n    /// Mult\n    Multani = 95,\n    /// Mymr\n    Myanmar = 96,\n    /// Nagm\n    Nag_Mundari = 97,\n    /// Nand\n    Nandinagari = 98,\n    /// Narb\n    Old_North_Arabian = 99,\n    /// Nbat\n    Nabataean = 100,\n    /// Newa\n    Newa = 101,\n    /// Nkoo\n    Nko = 102,\n    /// Nshu\n    Nushu = 103,\n    /// Ogam\n    Ogham = 104,\n    /// Olck\n    Ol_Chiki = 105,\n    /// Onao\n    Ol_Onal = 106,\n    /// Orkh\n    Old_Turkic = 107,\n    /// Orya\n    Oriya = 108,\n    /// Osge\n    Osage = 109,\n    /// Osma\n    Osmanya = 110,\n    /// Ougr\n    Old_Uyghur = 111,\n    /// Palm\n    Palmyrene = 112,\n    /// Pauc\n    Pau_Cin_Hau = 113,\n    /// Perm\n    Old_Permic = 114,\n    /// Phag\n    Phags_Pa = 115,\n    /// Phli\n    Inscriptional_Pahlavi = 116,\n    /// Phlp\n    Psalter_Pahlavi = 117,\n    /// Phnx\n    Phoenician = 118,\n    /// Plrd\n    Miao = 119,\n    /// Prti\n    Inscriptional_Parthian = 120,\n    /// Rjng\n    Rejang = 121,\n    /// Rohg\n    Hanifi_Rohingya = 122,\n    /// Runr\n    Runic = 123,\n    /// Samr\n    Samaritan = 124,\n    /// Sarb\n    Old_South_Arabian = 125,\n    /// Saur\n    Saurashtra = 126,\n    /// Sgnw\n    SignWriting = 127,\n    /// Shaw\n    Shavian = 128,\n    /// Shrd\n    Sharada = 129,\n    /// Sidd\n    Siddham = 130,\n    /// Sidt\n    Sidetic = 131,\n    /// Sind\n    Khudawadi = 132,\n    /// Sinh\n    Sinhala = 133,\n    /// Sogd\n    Sogdian = 134,\n    /// Sogo\n    Old_Sogdian = 135,\n    /// Sora\n    Sora_Sompeng = 136,\n    /// Soyo\n    Soyombo = 137,\n    /// Sund\n    Sundanese = 138,\n    /// Sunu\n    Sunuwar = 139,\n    /// Sylo\n    Syloti_Nagri = 140,\n    /// Syrc\n    Syriac = 141,\n    /// Tagb\n    Tagbanwa = 142,\n    /// Takr\n    Takri = 143,\n    /// Tale\n    Tai_Le = 144,\n    /// Talu\n    New_Tai_Lue = 145,\n    /// Taml\n    Tamil = 146,\n    /// Tang\n    Tangut = 147,\n    /// Tavt\n    Tai_Viet = 148,\n    /// Tayo\n    Tai_Yo = 149,\n    /// Telu\n    Telugu = 150,\n    /// Tfng\n    Tifinagh = 151,\n    /// Tglg\n    Tagalog = 152,\n    /// Thaa\n    Thaana = 153,\n    /// Thai\n    Thai = 154,\n    /// Tibt\n    Tibetan = 155,\n    /// Tirh\n    Tirhuta = 156,\n    /// Tnsa\n    Tangsa = 157,\n    /// Todr\n    Todhri = 158,\n    /// Tols\n    Tolong_Siki = 159,\n    /// Toto\n    Toto = 160,\n    /// Tutg\n    Tulu_Tigalari = 161,\n    /// Ugar\n    Ugaritic = 162,\n    /// Vaii\n    Vai = 163,\n    /// Vith\n    Vithkuqi = 164,\n    /// Wara\n    Warang_Citi = 165,\n    /// Wcho\n    Wancho = 166,\n    /// Xpeo\n    Old_Persian = 167,\n    /// Xsux\n    Cuneiform = 168,\n    /// Yezi\n    Yezidi = 169,\n    /// Yiii\n    Yi = 170,\n    /// Zanb\n    Zanabazar_Square = 171,\n}\npub const NEXT_SCRIPT: u8 = 172;\n\npub mod script_extensions {\n    use crate::ScriptExtension;\n    pub const COMMON: ScriptExtension = ScriptExtension::new_common();\n    pub const INHERITED: ScriptExtension = ScriptExtension::new_inherited();\n    pub const UNKNOWN: ScriptExtension = ScriptExtension::new_unknown();\n    /// Adlam\n    pub const ADLAM: ScriptExtension = ScriptExtension::new(0x1, 0, 0);\n    /// Adlam\n    pub const ADLM: ScriptExtension = ADLAM;\n    /// Caucasian_Albanian\n    pub const CAUCASIAN_ALBANIAN: ScriptExtension = ScriptExtension::new(0x2, 0, 0);\n    /// Caucasian_Albanian\n    pub const AGHB: ScriptExtension = CAUCASIAN_ALBANIAN;\n    /// Ahom\n    pub const AHOM: ScriptExtension = ScriptExtension::new(0x4, 0, 0);\n    /// Arabic\n    pub const ARABIC: ScriptExtension = ScriptExtension::new(0x8, 0, 0);\n    /// Arabic\n    pub const ARAB: ScriptExtension = ARABIC;\n    /// Imperial_Aramaic\n    pub const IMPERIAL_ARAMAIC: ScriptExtension = ScriptExtension::new(0x10, 0, 0);\n    /// Imperial_Aramaic\n    pub const ARMI: ScriptExtension = IMPERIAL_ARAMAIC;\n    /// Armenian\n    pub const ARMENIAN: ScriptExtension = ScriptExtension::new(0x20, 0, 0);\n    /// Armenian\n    pub const ARMN: ScriptExtension = ARMENIAN;\n    /// Avestan\n    pub const AVESTAN: ScriptExtension = ScriptExtension::new(0x40, 0, 0);\n    /// Avestan\n    pub const AVST: ScriptExtension = AVESTAN;\n    /// Balinese\n    pub const BALINESE: ScriptExtension = ScriptExtension::new(0x80, 0, 0);\n    /// Balinese\n    pub const BALI: ScriptExtension = BALINESE;\n    /// Bamum\n    pub const BAMUM: ScriptExtension = ScriptExtension::new(0x100, 0, 0);\n    /// Bamum\n    pub const BAMU: ScriptExtension = BAMUM;\n    /// Bassa_Vah\n    pub const BASSA_VAH: ScriptExtension = ScriptExtension::new(0x200, 0, 0);\n    /// Bassa_Vah\n    pub const BASS: ScriptExtension = BASSA_VAH;\n    /// Batak\n    pub const BATAK: ScriptExtension = ScriptExtension::new(0x400, 0, 0);\n    /// Batak\n    pub const BATK: ScriptExtension = BATAK;\n    /// Bengali\n    pub const BENGALI: ScriptExtension = ScriptExtension::new(0x800, 0, 0);\n    /// Bengali\n    pub const BENG: ScriptExtension = BENGALI;\n    /// Beria_Erfe\n    pub const BERIA_ERFE: ScriptExtension = ScriptExtension::new(0x1000, 0, 0);\n    /// Beria_Erfe\n    pub const BERF: ScriptExtension = BERIA_ERFE;\n    /// Bhaiksuki\n    pub const BHAIKSUKI: ScriptExtension = ScriptExtension::new(0x2000, 0, 0);\n    /// Bhaiksuki\n    pub const BHKS: ScriptExtension = BHAIKSUKI;\n    /// Bopomofo\n    pub const BOPOMOFO: ScriptExtension = ScriptExtension::new(0x4000, 0, 0);\n    /// Bopomofo\n    pub const BOPO: ScriptExtension = BOPOMOFO;\n    /// Brahmi\n    pub const BRAHMI: ScriptExtension = ScriptExtension::new(0x8000, 0, 0);\n    /// Brahmi\n    pub const BRAH: ScriptExtension = BRAHMI;\n    /// Braille\n    pub const BRAILLE: ScriptExtension = ScriptExtension::new(0x10000, 0, 0);\n    /// Braille\n    pub const BRAI: ScriptExtension = BRAILLE;\n    /// Buginese\n    pub const BUGINESE: ScriptExtension = ScriptExtension::new(0x20000, 0, 0);\n    /// Buginese\n    pub const BUGI: ScriptExtension = BUGINESE;\n    /// Buhid\n    pub const BUHID: ScriptExtension = ScriptExtension::new(0x40000, 0, 0);\n    /// Buhid\n    pub const BUHD: ScriptExtension = BUHID;\n    /// Chakma\n    pub const CHAKMA: ScriptExtension = ScriptExtension::new(0x80000, 0, 0);\n    /// Chakma\n    pub const CAKM: ScriptExtension = CHAKMA;\n    /// Canadian_Aboriginal\n    pub const CANADIAN_ABORIGINAL: ScriptExtension = ScriptExtension::new(0x100000, 0, 0);\n    /// Canadian_Aboriginal\n    pub const CANS: ScriptExtension = CANADIAN_ABORIGINAL;\n    /// Carian\n    pub const CARIAN: ScriptExtension = ScriptExtension::new(0x200000, 0, 0);\n    /// Carian\n    pub const CARI: ScriptExtension = CARIAN;\n    /// Cham\n    pub const CHAM: ScriptExtension = ScriptExtension::new(0x400000, 0, 0);\n    /// Cherokee\n    pub const CHEROKEE: ScriptExtension = ScriptExtension::new(0x800000, 0, 0);\n    /// Cherokee\n    pub const CHER: ScriptExtension = CHEROKEE;\n    /// Chorasmian\n    pub const CHORASMIAN: ScriptExtension = ScriptExtension::new(0x1000000, 0, 0);\n    /// Chorasmian\n    pub const CHRS: ScriptExtension = CHORASMIAN;\n    /// Coptic\n    pub const COPTIC: ScriptExtension = ScriptExtension::new(0x2000000, 0, 0);\n    /// Coptic\n    pub const COPT: ScriptExtension = COPTIC;\n    /// Cypro_Minoan\n    pub const CYPRO_MINOAN: ScriptExtension = ScriptExtension::new(0x4000000, 0, 0);\n    /// Cypro_Minoan\n    pub const CPMN: ScriptExtension = CYPRO_MINOAN;\n    /// Cypriot\n    pub const CYPRIOT: ScriptExtension = ScriptExtension::new(0x8000000, 0, 0);\n    /// Cypriot\n    pub const CPRT: ScriptExtension = CYPRIOT;\n    /// Cyrillic\n    pub const CYRILLIC: ScriptExtension = ScriptExtension::new(0x10000000, 0, 0);\n    /// Cyrillic\n    pub const CYRL: ScriptExtension = CYRILLIC;\n    /// Devanagari\n    pub const DEVANAGARI: ScriptExtension = ScriptExtension::new(0x20000000, 0, 0);\n    /// Devanagari\n    pub const DEVA: ScriptExtension = DEVANAGARI;\n    /// Dives_Akuru\n    pub const DIVES_AKURU: ScriptExtension = ScriptExtension::new(0x40000000, 0, 0);\n    /// Dives_Akuru\n    pub const DIAK: ScriptExtension = DIVES_AKURU;\n    /// Dogra\n    pub const DOGRA: ScriptExtension = ScriptExtension::new(0x80000000, 0, 0);\n    /// Dogra\n    pub const DOGR: ScriptExtension = DOGRA;\n    /// Deseret\n    pub const DESERET: ScriptExtension = ScriptExtension::new(0x100000000, 0, 0);\n    /// Deseret\n    pub const DSRT: ScriptExtension = DESERET;\n    /// Duployan\n    pub const DUPLOYAN: ScriptExtension = ScriptExtension::new(0x200000000, 0, 0);\n    /// Duployan\n    pub const DUPL: ScriptExtension = DUPLOYAN;\n    /// Egyptian_Hieroglyphs\n    pub const EGYPTIAN_HIEROGLYPHS: ScriptExtension = ScriptExtension::new(0x400000000, 0, 0);\n    /// Egyptian_Hieroglyphs\n    pub const EGYP: ScriptExtension = EGYPTIAN_HIEROGLYPHS;\n    /// Elbasan\n    pub const ELBASAN: ScriptExtension = ScriptExtension::new(0x800000000, 0, 0);\n    /// Elbasan\n    pub const ELBA: ScriptExtension = ELBASAN;\n    /// Elymaic\n    pub const ELYMAIC: ScriptExtension = ScriptExtension::new(0x1000000000, 0, 0);\n    /// Elymaic\n    pub const ELYM: ScriptExtension = ELYMAIC;\n    /// Ethiopic\n    pub const ETHIOPIC: ScriptExtension = ScriptExtension::new(0x2000000000, 0, 0);\n    /// Ethiopic\n    pub const ETHI: ScriptExtension = ETHIOPIC;\n    /// Garay\n    pub const GARAY: ScriptExtension = ScriptExtension::new(0x4000000000, 0, 0);\n    /// Garay\n    pub const GARA: ScriptExtension = GARAY;\n    /// Georgian\n    pub const GEORGIAN: ScriptExtension = ScriptExtension::new(0x8000000000, 0, 0);\n    /// Georgian\n    pub const GEOR: ScriptExtension = GEORGIAN;\n    /// Glagolitic\n    pub const GLAGOLITIC: ScriptExtension = ScriptExtension::new(0x10000000000, 0, 0);\n    /// Glagolitic\n    pub const GLAG: ScriptExtension = GLAGOLITIC;\n    /// Gunjala_Gondi\n    pub const GUNJALA_GONDI: ScriptExtension = ScriptExtension::new(0x20000000000, 0, 0);\n    /// Gunjala_Gondi\n    pub const GONG: ScriptExtension = GUNJALA_GONDI;\n    /// Masaram_Gondi\n    pub const MASARAM_GONDI: ScriptExtension = ScriptExtension::new(0x40000000000, 0, 0);\n    /// Masaram_Gondi\n    pub const GONM: ScriptExtension = MASARAM_GONDI;\n    /// Gothic\n    pub const GOTHIC: ScriptExtension = ScriptExtension::new(0x80000000000, 0, 0);\n    /// Gothic\n    pub const GOTH: ScriptExtension = GOTHIC;\n    /// Grantha\n    pub const GRANTHA: ScriptExtension = ScriptExtension::new(0x100000000000, 0, 0);\n    /// Grantha\n    pub const GRAN: ScriptExtension = GRANTHA;\n    /// Greek\n    pub const GREEK: ScriptExtension = ScriptExtension::new(0x200000000000, 0, 0);\n    /// Greek\n    pub const GREK: ScriptExtension = GREEK;\n    /// Gujarati\n    pub const GUJARATI: ScriptExtension = ScriptExtension::new(0x400000000000, 0, 0);\n    /// Gujarati\n    pub const GUJR: ScriptExtension = GUJARATI;\n    /// Gurung_Khema\n    pub const GURUNG_KHEMA: ScriptExtension = ScriptExtension::new(0x800000000000, 0, 0);\n    /// Gurung_Khema\n    pub const GUKH: ScriptExtension = GURUNG_KHEMA;\n    /// Gurmukhi\n    pub const GURMUKHI: ScriptExtension = ScriptExtension::new(0x1000000000000, 0, 0);\n    /// Gurmukhi\n    pub const GURU: ScriptExtension = GURMUKHI;\n    /// Hangul\n    pub const HANGUL: ScriptExtension = ScriptExtension::new(0x2000000000000, 0, 0);\n    /// Hangul\n    pub const HANG: ScriptExtension = HANGUL;\n    /// Han\n    pub const HAN: ScriptExtension = ScriptExtension::new(0x4000000000000, 0, 0);\n    /// Han\n    pub const HANI: ScriptExtension = HAN;\n    /// Hanunoo\n    pub const HANUNOO: ScriptExtension = ScriptExtension::new(0x8000000000000, 0, 0);\n    /// Hanunoo\n    pub const HANO: ScriptExtension = HANUNOO;\n    /// Hatran\n    pub const HATRAN: ScriptExtension = ScriptExtension::new(0x10000000000000, 0, 0);\n    /// Hatran\n    pub const HATR: ScriptExtension = HATRAN;\n    /// Hebrew\n    pub const HEBREW: ScriptExtension = ScriptExtension::new(0x20000000000000, 0, 0);\n    /// Hebrew\n    pub const HEBR: ScriptExtension = HEBREW;\n    /// Hiragana\n    pub const HIRAGANA: ScriptExtension = ScriptExtension::new(0x40000000000000, 0, 0);\n    /// Hiragana\n    pub const HIRA: ScriptExtension = HIRAGANA;\n    /// Anatolian_Hieroglyphs\n    pub const ANATOLIAN_HIEROGLYPHS: ScriptExtension = ScriptExtension::new(0x80000000000000, 0, 0);\n    /// Anatolian_Hieroglyphs\n    pub const HLUW: ScriptExtension = ANATOLIAN_HIEROGLYPHS;\n    /// Pahawh_Hmong\n    pub const PAHAWH_HMONG: ScriptExtension = ScriptExtension::new(0x100000000000000, 0, 0);\n    /// Pahawh_Hmong\n    pub const HMNG: ScriptExtension = PAHAWH_HMONG;\n    /// Nyiakeng_Puachue_Hmong\n    pub const NYIAKENG_PUACHUE_HMONG: ScriptExtension = ScriptExtension::new(0x200000000000000, 0, 0);\n    /// Nyiakeng_Puachue_Hmong\n    pub const HMNP: ScriptExtension = NYIAKENG_PUACHUE_HMONG;\n    /// Old_Hungarian\n    pub const OLD_HUNGARIAN: ScriptExtension = ScriptExtension::new(0x400000000000000, 0, 0);\n    /// Old_Hungarian\n    pub const HUNG: ScriptExtension = OLD_HUNGARIAN;\n    /// Old_Italic\n    pub const OLD_ITALIC: ScriptExtension = ScriptExtension::new(0x800000000000000, 0, 0);\n    /// Old_Italic\n    pub const ITAL: ScriptExtension = OLD_ITALIC;\n    /// Javanese\n    pub const JAVANESE: ScriptExtension = ScriptExtension::new(0x1000000000000000, 0, 0);\n    /// Javanese\n    pub const JAVA: ScriptExtension = JAVANESE;\n    /// Kayah_Li\n    pub const KAYAH_LI: ScriptExtension = ScriptExtension::new(0x2000000000000000, 0, 0);\n    /// Kayah_Li\n    pub const KALI: ScriptExtension = KAYAH_LI;\n    /// Katakana\n    pub const KATAKANA: ScriptExtension = ScriptExtension::new(0x4000000000000000, 0, 0);\n    /// Katakana\n    pub const KANA: ScriptExtension = KATAKANA;\n    /// Kawi\n    pub const KAWI: ScriptExtension = ScriptExtension::new(0x8000000000000000, 0, 0);\n    /// Kharoshthi\n    pub const KHAROSHTHI: ScriptExtension = ScriptExtension::new(0, 0x1, 0);\n    /// Kharoshthi\n    pub const KHAR: ScriptExtension = KHAROSHTHI;\n    /// Khmer\n    pub const KHMER: ScriptExtension = ScriptExtension::new(0, 0x2, 0);\n    /// Khmer\n    pub const KHMR: ScriptExtension = KHMER;\n    /// Khojki\n    pub const KHOJKI: ScriptExtension = ScriptExtension::new(0, 0x4, 0);\n    /// Khojki\n    pub const KHOJ: ScriptExtension = KHOJKI;\n    /// Khitan_Small_Script\n    pub const KHITAN_SMALL_SCRIPT: ScriptExtension = ScriptExtension::new(0, 0x8, 0);\n    /// Khitan_Small_Script\n    pub const KITS: ScriptExtension = KHITAN_SMALL_SCRIPT;\n    /// Kannada\n    pub const KANNADA: ScriptExtension = ScriptExtension::new(0, 0x10, 0);\n    /// Kannada\n    pub const KNDA: ScriptExtension = KANNADA;\n    /// Kirat_Rai\n    pub const KIRAT_RAI: ScriptExtension = ScriptExtension::new(0, 0x20, 0);\n    /// Kirat_Rai\n    pub const KRAI: ScriptExtension = KIRAT_RAI;\n    /// Kaithi\n    pub const KAITHI: ScriptExtension = ScriptExtension::new(0, 0x40, 0);\n    /// Kaithi\n    pub const KTHI: ScriptExtension = KAITHI;\n    /// Tai_Tham\n    pub const TAI_THAM: ScriptExtension = ScriptExtension::new(0, 0x80, 0);\n    /// Tai_Tham\n    pub const LANA: ScriptExtension = TAI_THAM;\n    /// Lao\n    pub const LAO: ScriptExtension = ScriptExtension::new(0, 0x100, 0);\n    /// Lao\n    pub const LAOO: ScriptExtension = LAO;\n    /// Latin\n    pub const LATIN: ScriptExtension = ScriptExtension::new(0, 0x200, 0);\n    /// Latin\n    pub const LATN: ScriptExtension = LATIN;\n    /// Lepcha\n    pub const LEPCHA: ScriptExtension = ScriptExtension::new(0, 0x400, 0);\n    /// Lepcha\n    pub const LEPC: ScriptExtension = LEPCHA;\n    /// Limbu\n    pub const LIMBU: ScriptExtension = ScriptExtension::new(0, 0x800, 0);\n    /// Limbu\n    pub const LIMB: ScriptExtension = LIMBU;\n    /// Linear_A\n    pub const LINEAR_A: ScriptExtension = ScriptExtension::new(0, 0x1000, 0);\n    /// Linear_A\n    pub const LINA: ScriptExtension = LINEAR_A;\n    /// Linear_B\n    pub const LINEAR_B: ScriptExtension = ScriptExtension::new(0, 0x2000, 0);\n    /// Linear_B\n    pub const LINB: ScriptExtension = LINEAR_B;\n    /// Lisu\n    pub const LISU: ScriptExtension = ScriptExtension::new(0, 0x4000, 0);\n    /// Lycian\n    pub const LYCIAN: ScriptExtension = ScriptExtension::new(0, 0x8000, 0);\n    /// Lycian\n    pub const LYCI: ScriptExtension = LYCIAN;\n    /// Lydian\n    pub const LYDIAN: ScriptExtension = ScriptExtension::new(0, 0x10000, 0);\n    /// Lydian\n    pub const LYDI: ScriptExtension = LYDIAN;\n    /// Mahajani\n    pub const MAHAJANI: ScriptExtension = ScriptExtension::new(0, 0x20000, 0);\n    /// Mahajani\n    pub const MAHJ: ScriptExtension = MAHAJANI;\n    /// Makasar\n    pub const MAKASAR: ScriptExtension = ScriptExtension::new(0, 0x40000, 0);\n    /// Makasar\n    pub const MAKA: ScriptExtension = MAKASAR;\n    /// Mandaic\n    pub const MANDAIC: ScriptExtension = ScriptExtension::new(0, 0x80000, 0);\n    /// Mandaic\n    pub const MAND: ScriptExtension = MANDAIC;\n    /// Manichaean\n    pub const MANICHAEAN: ScriptExtension = ScriptExtension::new(0, 0x100000, 0);\n    /// Manichaean\n    pub const MANI: ScriptExtension = MANICHAEAN;\n    /// Marchen\n    pub const MARCHEN: ScriptExtension = ScriptExtension::new(0, 0x200000, 0);\n    /// Marchen\n    pub const MARC: ScriptExtension = MARCHEN;\n    /// Medefaidrin\n    pub const MEDEFAIDRIN: ScriptExtension = ScriptExtension::new(0, 0x400000, 0);\n    /// Medefaidrin\n    pub const MEDF: ScriptExtension = MEDEFAIDRIN;\n    /// Mende_Kikakui\n    pub const MENDE_KIKAKUI: ScriptExtension = ScriptExtension::new(0, 0x800000, 0);\n    /// Mende_Kikakui\n    pub const MEND: ScriptExtension = MENDE_KIKAKUI;\n    /// Meroitic_Cursive\n    pub const MEROITIC_CURSIVE: ScriptExtension = ScriptExtension::new(0, 0x1000000, 0);\n    /// Meroitic_Cursive\n    pub const MERC: ScriptExtension = MEROITIC_CURSIVE;\n    /// Meroitic_Hieroglyphs\n    pub const MEROITIC_HIEROGLYPHS: ScriptExtension = ScriptExtension::new(0, 0x2000000, 0);\n    /// Meroitic_Hieroglyphs\n    pub const MERO: ScriptExtension = MEROITIC_HIEROGLYPHS;\n    /// Malayalam\n    pub const MALAYALAM: ScriptExtension = ScriptExtension::new(0, 0x4000000, 0);\n    /// Malayalam\n    pub const MLYM: ScriptExtension = MALAYALAM;\n    /// Modi\n    pub const MODI: ScriptExtension = ScriptExtension::new(0, 0x8000000, 0);\n    /// Mongolian\n    pub const MONGOLIAN: ScriptExtension = ScriptExtension::new(0, 0x10000000, 0);\n    /// Mongolian\n    pub const MONG: ScriptExtension = MONGOLIAN;\n    /// Mro\n    pub const MRO: ScriptExtension = ScriptExtension::new(0, 0x20000000, 0);\n    /// Mro\n    pub const MROO: ScriptExtension = MRO;\n    /// Meetei_Mayek\n    pub const MEETEI_MAYEK: ScriptExtension = ScriptExtension::new(0, 0x40000000, 0);\n    /// Meetei_Mayek\n    pub const MTEI: ScriptExtension = MEETEI_MAYEK;\n    /// Multani\n    pub const MULTANI: ScriptExtension = ScriptExtension::new(0, 0x80000000, 0);\n    /// Multani\n    pub const MULT: ScriptExtension = MULTANI;\n    /// Myanmar\n    pub const MYANMAR: ScriptExtension = ScriptExtension::new(0, 0x100000000, 0);\n    /// Myanmar\n    pub const MYMR: ScriptExtension = MYANMAR;\n    /// Nag_Mundari\n    pub const NAG_MUNDARI: ScriptExtension = ScriptExtension::new(0, 0x200000000, 0);\n    /// Nag_Mundari\n    pub const NAGM: ScriptExtension = NAG_MUNDARI;\n    /// Nandinagari\n    pub const NANDINAGARI: ScriptExtension = ScriptExtension::new(0, 0x400000000, 0);\n    /// Nandinagari\n    pub const NAND: ScriptExtension = NANDINAGARI;\n    /// Old_North_Arabian\n    pub const OLD_NORTH_ARABIAN: ScriptExtension = ScriptExtension::new(0, 0x800000000, 0);\n    /// Old_North_Arabian\n    pub const NARB: ScriptExtension = OLD_NORTH_ARABIAN;\n    /// Nabataean\n    pub const NABATAEAN: ScriptExtension = ScriptExtension::new(0, 0x1000000000, 0);\n    /// Nabataean\n    pub const NBAT: ScriptExtension = NABATAEAN;\n    /// Newa\n    pub const NEWA: ScriptExtension = ScriptExtension::new(0, 0x2000000000, 0);\n    /// Nko\n    pub const NKO: ScriptExtension = ScriptExtension::new(0, 0x4000000000, 0);\n    /// Nko\n    pub const NKOO: ScriptExtension = NKO;\n    /// Nushu\n    pub const NUSHU: ScriptExtension = ScriptExtension::new(0, 0x8000000000, 0);\n    /// Nushu\n    pub const NSHU: ScriptExtension = NUSHU;\n    /// Ogham\n    pub const OGHAM: ScriptExtension = ScriptExtension::new(0, 0x10000000000, 0);\n    /// Ogham\n    pub const OGAM: ScriptExtension = OGHAM;\n    /// Ol_Chiki\n    pub const OL_CHIKI: ScriptExtension = ScriptExtension::new(0, 0x20000000000, 0);\n    /// Ol_Chiki\n    pub const OLCK: ScriptExtension = OL_CHIKI;\n    /// Ol_Onal\n    pub const OL_ONAL: ScriptExtension = ScriptExtension::new(0, 0x40000000000, 0);\n    /// Ol_Onal\n    pub const ONAO: ScriptExtension = OL_ONAL;\n    /// Old_Turkic\n    pub const OLD_TURKIC: ScriptExtension = ScriptExtension::new(0, 0x80000000000, 0);\n    /// Old_Turkic\n    pub const ORKH: ScriptExtension = OLD_TURKIC;\n    /// Oriya\n    pub const ORIYA: ScriptExtension = ScriptExtension::new(0, 0x100000000000, 0);\n    /// Oriya\n    pub const ORYA: ScriptExtension = ORIYA;\n    /// Osage\n    pub const OSAGE: ScriptExtension = ScriptExtension::new(0, 0x200000000000, 0);\n    /// Osage\n    pub const OSGE: ScriptExtension = OSAGE;\n    /// Osmanya\n    pub const OSMANYA: ScriptExtension = ScriptExtension::new(0, 0x400000000000, 0);\n    /// Osmanya\n    pub const OSMA: ScriptExtension = OSMANYA;\n    /// Old_Uyghur\n    pub const OLD_UYGHUR: ScriptExtension = ScriptExtension::new(0, 0x800000000000, 0);\n    /// Old_Uyghur\n    pub const OUGR: ScriptExtension = OLD_UYGHUR;\n    /// Palmyrene\n    pub const PALMYRENE: ScriptExtension = ScriptExtension::new(0, 0x1000000000000, 0);\n    /// Palmyrene\n    pub const PALM: ScriptExtension = PALMYRENE;\n    /// Pau_Cin_Hau\n    pub const PAU_CIN_HAU: ScriptExtension = ScriptExtension::new(0, 0x2000000000000, 0);\n    /// Pau_Cin_Hau\n    pub const PAUC: ScriptExtension = PAU_CIN_HAU;\n    /// Old_Permic\n    pub const OLD_PERMIC: ScriptExtension = ScriptExtension::new(0, 0x4000000000000, 0);\n    /// Old_Permic\n    pub const PERM: ScriptExtension = OLD_PERMIC;\n    /// Phags_Pa\n    pub const PHAGS_PA: ScriptExtension = ScriptExtension::new(0, 0x8000000000000, 0);\n    /// Phags_Pa\n    pub const PHAG: ScriptExtension = PHAGS_PA;\n    /// Inscriptional_Pahlavi\n    pub const INSCRIPTIONAL_PAHLAVI: ScriptExtension = ScriptExtension::new(0, 0x10000000000000, 0);\n    /// Inscriptional_Pahlavi\n    pub const PHLI: ScriptExtension = INSCRIPTIONAL_PAHLAVI;\n    /// Psalter_Pahlavi\n    pub const PSALTER_PAHLAVI: ScriptExtension = ScriptExtension::new(0, 0x20000000000000, 0);\n    /// Psalter_Pahlavi\n    pub const PHLP: ScriptExtension = PSALTER_PAHLAVI;\n    /// Phoenician\n    pub const PHOENICIAN: ScriptExtension = ScriptExtension::new(0, 0x40000000000000, 0);\n    /// Phoenician\n    pub const PHNX: ScriptExtension = PHOENICIAN;\n    /// Miao\n    pub const MIAO: ScriptExtension = ScriptExtension::new(0, 0x80000000000000, 0);\n    /// Miao\n    pub const PLRD: ScriptExtension = MIAO;\n    /// Inscriptional_Parthian\n    pub const INSCRIPTIONAL_PARTHIAN: ScriptExtension = ScriptExtension::new(0, 0x100000000000000, 0);\n    /// Inscriptional_Parthian\n    pub const PRTI: ScriptExtension = INSCRIPTIONAL_PARTHIAN;\n    /// Rejang\n    pub const REJANG: ScriptExtension = ScriptExtension::new(0, 0x200000000000000, 0);\n    /// Rejang\n    pub const RJNG: ScriptExtension = REJANG;\n    /// Hanifi_Rohingya\n    pub const HANIFI_ROHINGYA: ScriptExtension = ScriptExtension::new(0, 0x400000000000000, 0);\n    /// Hanifi_Rohingya\n    pub const ROHG: ScriptExtension = HANIFI_ROHINGYA;\n    /// Runic\n    pub const RUNIC: ScriptExtension = ScriptExtension::new(0, 0x800000000000000, 0);\n    /// Runic\n    pub const RUNR: ScriptExtension = RUNIC;\n    /// Samaritan\n    pub const SAMARITAN: ScriptExtension = ScriptExtension::new(0, 0x1000000000000000, 0);\n    /// Samaritan\n    pub const SAMR: ScriptExtension = SAMARITAN;\n    /// Old_South_Arabian\n    pub const OLD_SOUTH_ARABIAN: ScriptExtension = ScriptExtension::new(0, 0x2000000000000000, 0);\n    /// Old_South_Arabian\n    pub const SARB: ScriptExtension = OLD_SOUTH_ARABIAN;\n    /// Saurashtra\n    pub const SAURASHTRA: ScriptExtension = ScriptExtension::new(0, 0x4000000000000000, 0);\n    /// Saurashtra\n    pub const SAUR: ScriptExtension = SAURASHTRA;\n    /// SignWriting\n    pub const SIGNWRITING: ScriptExtension = ScriptExtension::new(0, 0x8000000000000000, 0);\n    /// SignWriting\n    pub const SGNW: ScriptExtension = SIGNWRITING;\n    /// Shavian\n    pub const SHAVIAN: ScriptExtension = ScriptExtension::new(0, 0, 0x1);\n    /// Shavian\n    pub const SHAW: ScriptExtension = SHAVIAN;\n    /// Sharada\n    pub const SHARADA: ScriptExtension = ScriptExtension::new(0, 0, 0x2);\n    /// Sharada\n    pub const SHRD: ScriptExtension = SHARADA;\n    /// Siddham\n    pub const SIDDHAM: ScriptExtension = ScriptExtension::new(0, 0, 0x4);\n    /// Siddham\n    pub const SIDD: ScriptExtension = SIDDHAM;\n    /// Sidetic\n    pub const SIDETIC: ScriptExtension = ScriptExtension::new(0, 0, 0x8);\n    /// Sidetic\n    pub const SIDT: ScriptExtension = SIDETIC;\n    /// Khudawadi\n    pub const KHUDAWADI: ScriptExtension = ScriptExtension::new(0, 0, 0x10);\n    /// Khudawadi\n    pub const SIND: ScriptExtension = KHUDAWADI;\n    /// Sinhala\n    pub const SINHALA: ScriptExtension = ScriptExtension::new(0, 0, 0x20);\n    /// Sinhala\n    pub const SINH: ScriptExtension = SINHALA;\n    /// Sogdian\n    pub const SOGDIAN: ScriptExtension = ScriptExtension::new(0, 0, 0x40);\n    /// Sogdian\n    pub const SOGD: ScriptExtension = SOGDIAN;\n    /// Old_Sogdian\n    pub const OLD_SOGDIAN: ScriptExtension = ScriptExtension::new(0, 0, 0x80);\n    /// Old_Sogdian\n    pub const SOGO: ScriptExtension = OLD_SOGDIAN;\n    /// Sora_Sompeng\n    pub const SORA_SOMPENG: ScriptExtension = ScriptExtension::new(0, 0, 0x100);\n    /// Sora_Sompeng\n    pub const SORA: ScriptExtension = SORA_SOMPENG;\n    /// Soyombo\n    pub const SOYOMBO: ScriptExtension = ScriptExtension::new(0, 0, 0x200);\n    /// Soyombo\n    pub const SOYO: ScriptExtension = SOYOMBO;\n    /// Sundanese\n    pub const SUNDANESE: ScriptExtension = ScriptExtension::new(0, 0, 0x400);\n    /// Sundanese\n    pub const SUND: ScriptExtension = SUNDANESE;\n    /// Sunuwar\n    pub const SUNUWAR: ScriptExtension = ScriptExtension::new(0, 0, 0x800);\n    /// Sunuwar\n    pub const SUNU: ScriptExtension = SUNUWAR;\n    /// Syloti_Nagri\n    pub const SYLOTI_NAGRI: ScriptExtension = ScriptExtension::new(0, 0, 0x1000);\n    /// Syloti_Nagri\n    pub const SYLO: ScriptExtension = SYLOTI_NAGRI;\n    /// Syriac\n    pub const SYRIAC: ScriptExtension = ScriptExtension::new(0, 0, 0x2000);\n    /// Syriac\n    pub const SYRC: ScriptExtension = SYRIAC;\n    /// Tagbanwa\n    pub const TAGBANWA: ScriptExtension = ScriptExtension::new(0, 0, 0x4000);\n    /// Tagbanwa\n    pub const TAGB: ScriptExtension = TAGBANWA;\n    /// Takri\n    pub const TAKRI: ScriptExtension = ScriptExtension::new(0, 0, 0x8000);\n    /// Takri\n    pub const TAKR: ScriptExtension = TAKRI;\n    /// Tai_Le\n    pub const TAI_LE: ScriptExtension = ScriptExtension::new(0, 0, 0x10000);\n    /// Tai_Le\n    pub const TALE: ScriptExtension = TAI_LE;\n    /// New_Tai_Lue\n    pub const NEW_TAI_LUE: ScriptExtension = ScriptExtension::new(0, 0, 0x20000);\n    /// New_Tai_Lue\n    pub const TALU: ScriptExtension = NEW_TAI_LUE;\n    /// Tamil\n    pub const TAMIL: ScriptExtension = ScriptExtension::new(0, 0, 0x40000);\n    /// Tamil\n    pub const TAML: ScriptExtension = TAMIL;\n    /// Tangut\n    pub const TANGUT: ScriptExtension = ScriptExtension::new(0, 0, 0x80000);\n    /// Tangut\n    pub const TANG: ScriptExtension = TANGUT;\n    /// Tai_Viet\n    pub const TAI_VIET: ScriptExtension = ScriptExtension::new(0, 0, 0x100000);\n    /// Tai_Viet\n    pub const TAVT: ScriptExtension = TAI_VIET;\n    /// Tai_Yo\n    pub const TAI_YO: ScriptExtension = ScriptExtension::new(0, 0, 0x200000);\n    /// Tai_Yo\n    pub const TAYO: ScriptExtension = TAI_YO;\n    /// Telugu\n    pub const TELUGU: ScriptExtension = ScriptExtension::new(0, 0, 0x400000);\n    /// Telugu\n    pub const TELU: ScriptExtension = TELUGU;\n    /// Tifinagh\n    pub const TIFINAGH: ScriptExtension = ScriptExtension::new(0, 0, 0x800000);\n    /// Tifinagh\n    pub const TFNG: ScriptExtension = TIFINAGH;\n    /// Tagalog\n    pub const TAGALOG: ScriptExtension = ScriptExtension::new(0, 0, 0x1000000);\n    /// Tagalog\n    pub const TGLG: ScriptExtension = TAGALOG;\n    /// Thaana\n    pub const THAANA: ScriptExtension = ScriptExtension::new(0, 0, 0x2000000);\n    /// Thaana\n    pub const THAA: ScriptExtension = THAANA;\n    /// Thai\n    pub const THAI: ScriptExtension = ScriptExtension::new(0, 0, 0x4000000);\n    /// Tibetan\n    pub const TIBETAN: ScriptExtension = ScriptExtension::new(0, 0, 0x8000000);\n    /// Tibetan\n    pub const TIBT: ScriptExtension = TIBETAN;\n    /// Tirhuta\n    pub const TIRHUTA: ScriptExtension = ScriptExtension::new(0, 0, 0x10000000);\n    /// Tirhuta\n    pub const TIRH: ScriptExtension = TIRHUTA;\n    /// Tangsa\n    pub const TANGSA: ScriptExtension = ScriptExtension::new(0, 0, 0x20000000);\n    /// Tangsa\n    pub const TNSA: ScriptExtension = TANGSA;\n    /// Todhri\n    pub const TODHRI: ScriptExtension = ScriptExtension::new(0, 0, 0x40000000);\n    /// Todhri\n    pub const TODR: ScriptExtension = TODHRI;\n    /// Tolong_Siki\n    pub const TOLONG_SIKI: ScriptExtension = ScriptExtension::new(0, 0, 0x80000000);\n    /// Tolong_Siki\n    pub const TOLS: ScriptExtension = TOLONG_SIKI;\n    /// Toto\n    pub const TOTO: ScriptExtension = ScriptExtension::new(0, 0, 0x100000000);\n    /// Tulu_Tigalari\n    pub const TULU_TIGALARI: ScriptExtension = ScriptExtension::new(0, 0, 0x200000000);\n    /// Tulu_Tigalari\n    pub const TUTG: ScriptExtension = TULU_TIGALARI;\n    /// Ugaritic\n    pub const UGARITIC: ScriptExtension = ScriptExtension::new(0, 0, 0x400000000);\n    /// Ugaritic\n    pub const UGAR: ScriptExtension = UGARITIC;\n    /// Vai\n    pub const VAI: ScriptExtension = ScriptExtension::new(0, 0, 0x800000000);\n    /// Vai\n    pub const VAII: ScriptExtension = VAI;\n    /// Vithkuqi\n    pub const VITHKUQI: ScriptExtension = ScriptExtension::new(0, 0, 0x1000000000);\n    /// Vithkuqi\n    pub const VITH: ScriptExtension = VITHKUQI;\n    /// Warang_Citi\n    pub const WARANG_CITI: ScriptExtension = ScriptExtension::new(0, 0, 0x2000000000);\n    /// Warang_Citi\n    pub const WARA: ScriptExtension = WARANG_CITI;\n    /// Wancho\n    pub const WANCHO: ScriptExtension = ScriptExtension::new(0, 0, 0x4000000000);\n    /// Wancho\n    pub const WCHO: ScriptExtension = WANCHO;\n    /// Old_Persian\n    pub const OLD_PERSIAN: ScriptExtension = ScriptExtension::new(0, 0, 0x8000000000);\n    /// Old_Persian\n    pub const XPEO: ScriptExtension = OLD_PERSIAN;\n    /// Cuneiform\n    pub const CUNEIFORM: ScriptExtension = ScriptExtension::new(0, 0, 0x10000000000);\n    /// Cuneiform\n    pub const XSUX: ScriptExtension = CUNEIFORM;\n    /// Yezidi\n    pub const YEZIDI: ScriptExtension = ScriptExtension::new(0, 0, 0x20000000000);\n    /// Yezidi\n    pub const YEZI: ScriptExtension = YEZIDI;\n    /// Yi\n    pub const YI: ScriptExtension = ScriptExtension::new(0, 0, 0x40000000000);\n    /// Yi\n    pub const YIII: ScriptExtension = YI;\n    /// Zanabazar_Square\n    pub const ZANABAZAR_SQUARE: ScriptExtension = ScriptExtension::new(0, 0, 0x80000000000);\n    /// Zanabazar_Square\n    pub const ZANB: ScriptExtension = ZANABAZAR_SQUARE;\n    /// Avestan, Carian, Coptic, Duployan, Elbasan, Georgian, Glagolitic, Gunjala_Gondi, Gothic, Greek, Han, Latin, Lydian, Mahajani, Old_Permic, Shavian\n    pub const AVST_CARI_COPT_DUPL_ELBA_GEOR_GLAG_GONG_GOTH_GREK_HANI_LATN_LYDI_MAHJ_PERM_SHAW: ScriptExtension = AVST.union(CARI).union(COPT).union(DUPL).union(ELBA).union(GEOR).union(GLAG).union(GONG).union(GOTH).union(GREK).union(HANI).union(LATN).union(LYDI).union(MAHJ).union(PERM).union(SHAW);\n    /// Bengali, Cyrillic, Devanagari, Latin, Lisu, Thai, Toto\n    pub const BENG_CYRL_DEVA_LATN_LISU_THAI_TOTO: ScriptExtension = BENG.union(CYRL).union(DEVA).union(LATN).union(LISU).union(THAI).union(TOTO);\n    /// Bopomofo, Latin\n    pub const BOPO_LATN: ScriptExtension = BOPO.union(LATN);\n    /// Latin, Lisu\n    pub const LATN_LISU: ScriptExtension = LATN.union(LISU);\n    /// Latin, Thai\n    pub const LATN_THAI: ScriptExtension = LATN.union(THAI);\n    /// Cherokee, Coptic, Cyrillic, Greek, Latin, Old_Permic, Sunuwar, Tai_Le\n    pub const CHER_COPT_CYRL_GREK_LATN_PERM_SUNU_TALE: ScriptExtension = CHER.union(COPT).union(CYRL).union(GREK).union(LATN).union(PERM).union(SUNU).union(TALE);\n    /// Cherokee, Cyrillic, Greek, Latin, Osage, Sunuwar, Tai_Le, Todhri\n    pub const CHER_CYRL_GREK_LATN_OSGE_SUNU_TALE_TODR: ScriptExtension = CHER.union(CYRL).union(GREK).union(LATN).union(OSGE).union(SUNU).union(TALE).union(TODR);\n    /// Cherokee, Cyrillic, Latin, Tifinagh\n    pub const CHER_CYRL_LATN_TFNG: ScriptExtension = CHER.union(CYRL).union(LATN).union(TFNG);\n    /// Glagolitic, Latin, Sunuwar, Syriac, Thai\n    pub const GLAG_LATN_SUNU_SYRC_THAI: ScriptExtension = GLAG.union(LATN).union(SUNU).union(SYRC).union(THAI);\n    /// Caucasian_Albanian, Cherokee, Coptic, Cyrillic, Gothic, Greek, Latin, Osage, Syriac, Tifinagh, Todhri\n    pub const AGHB_CHER_COPT_CYRL_GOTH_GREK_LATN_OSGE_SYRC_TFNG_TODR: ScriptExtension = AGHB.union(CHER).union(COPT).union(CYRL).union(GOTH).union(GREK).union(LATN).union(OSGE).union(SYRC).union(TFNG).union(TODR);\n    /// Coptic, Elbasan, Glagolitic, Gothic, Katakana, Latin\n    pub const COPT_ELBA_GLAG_GOTH_KANA_LATN: ScriptExtension = COPT.union(ELBA).union(GLAG).union(GOTH).union(KANA).union(LATN);\n    /// Cyrillic, Greek, Latin, Old_Permic, Tifinagh\n    pub const CYRL_GREK_LATN_PERM_TFNG: ScriptExtension = CYRL.union(GREK).union(LATN).union(PERM).union(TFNG);\n    /// Coptic, Duployan, Hebrew, Latin, Old_Permic, Syriac, Tai_Le, Tifinagh, Todhri\n    pub const COPT_DUPL_HEBR_LATN_PERM_SYRC_TALE_TFNG_TODR: ScriptExtension = COPT.union(DUPL).union(HEBR).union(LATN).union(PERM).union(SYRC).union(TALE).union(TFNG).union(TODR);\n    /// Armenian, Cyrillic, Duployan, Gothic, Greek, Hebrew, Latin, Old_Permic, Syriac, Tai_Le, Tifinagh\n    pub const ARMN_CYRL_DUPL_GOTH_GREK_HEBR_LATN_PERM_SYRC_TALE_TFNG: ScriptExtension = ARMN.union(CYRL).union(DUPL).union(GOTH).union(GREK).union(HEBR).union(LATN).union(PERM).union(SYRC).union(TALE).union(TFNG);\n    /// Latin, Tifinagh\n    pub const LATN_TFNG: ScriptExtension = LATN.union(TFNG);\n    /// Duployan, Latin, Syriac\n    pub const DUPL_LATN_SYRC: ScriptExtension = DUPL.union(LATN).union(SYRC);\n    /// Cherokee, Cyrillic, Latin, Osage\n    pub const CHER_CYRL_LATN_OSGE: ScriptExtension = CHER.union(CYRL).union(LATN).union(OSGE);\n    /// Cherokee, Latin, Tai_Le\n    pub const CHER_LATN_TALE: ScriptExtension = CHER.union(LATN).union(TALE);\n    /// Latin, Sunuwar\n    pub const LATN_SUNU: ScriptExtension = LATN.union(SUNU);\n    /// Ethiopic, Latin\n    pub const ETHI_LATN: ScriptExtension = ETHI.union(LATN);\n    /// Cyrillic, Latin, Todhri\n    pub const CYRL_LATN_TODR: ScriptExtension = CYRL.union(LATN).union(TODR);\n    /// Greek, Latin, Old_Permic, Todhri\n    pub const GREK_LATN_PERM_TODR: ScriptExtension = GREK.union(LATN).union(PERM).union(TODR);\n    /// Cherokee, Duployan, Katakana, Latin, Syriac, Tifinagh\n    pub const CHER_DUPL_KANA_LATN_SYRC_TFNG: ScriptExtension = CHER.union(DUPL).union(KANA).union(LATN).union(SYRC).union(TFNG);\n    /// Cherokee, Duployan, Latin, Syriac\n    pub const CHER_DUPL_LATN_SYRC: ScriptExtension = CHER.union(DUPL).union(LATN).union(SYRC);\n    /// Latin, Syriac\n    pub const LATN_SYRC: ScriptExtension = LATN.union(SYRC);\n    /// Latin, Sunuwar, Syriac\n    pub const LATN_SUNU_SYRC: ScriptExtension = LATN.union(SUNU).union(SYRC);\n    /// Cherokee, Latin, Syriac\n    pub const CHER_LATN_SYRC: ScriptExtension = CHER.union(LATN).union(SYRC);\n    /// Caucasian_Albanian, Cherokee, Gothic, Latin, Sunuwar, Syriac, Thai\n    pub const AGHB_CHER_GOTH_LATN_SUNU_SYRC_THAI: ScriptExtension = AGHB.union(CHER).union(GOTH).union(LATN).union(SUNU).union(SYRC).union(THAI);\n    /// Latin, Osage\n    pub const LATN_OSGE: ScriptExtension = LATN.union(OSGE);\n    /// Caucasian_Albanian, Latin, Todhri\n    pub const AGHB_LATN_TODR: ScriptExtension = AGHB.union(LATN).union(TODR);\n    /// Coptic, Greek\n    pub const COPT_GREK: ScriptExtension = COPT.union(GREK);\n    /// Cyrillic, Old_Permic\n    pub const CYRL_PERM: ScriptExtension = CYRL.union(PERM);\n    /// Cyrillic, Glagolitic\n    pub const CYRL_GLAG: ScriptExtension = CYRL.union(GLAG);\n    /// Cyrillic, Latin\n    pub const CYRL_LATN: ScriptExtension = CYRL.union(LATN);\n    /// Armenian, Georgian, Glagolitic\n    pub const ARMN_GEOR_GLAG: ScriptExtension = ARMN.union(GEOR).union(GLAG);\n    /// Arabic, Garay, Nko, Hanifi_Rohingya, Syriac, Thaana, Yezidi\n    pub const ARAB_GARA_NKOO_ROHG_SYRC_THAA_YEZI: ScriptExtension = ARAB.union(GARA).union(NKOO).union(ROHG).union(SYRC).union(THAA).union(YEZI);\n    /// Arabic, Syriac, Thaana\n    pub const ARAB_SYRC_THAA: ScriptExtension = ARAB.union(SYRC).union(THAA);\n    /// Adlam, Arabic, Garay, Nko, Hanifi_Rohingya, Syriac, Thaana, Yezidi\n    pub const ADLM_ARAB_GARA_NKOO_ROHG_SYRC_THAA_YEZI: ScriptExtension = ADLM.union(ARAB).union(GARA).union(NKOO).union(ROHG).union(SYRC).union(THAA).union(YEZI);\n    /// Adlam, Arabic, Mandaic, Manichaean, Old_Uyghur, Psalter_Pahlavi, Hanifi_Rohingya, Sogdian, Syriac\n    pub const ADLM_ARAB_MAND_MANI_OUGR_PHLP_ROHG_SOGD_SYRC: ScriptExtension = ADLM.union(ARAB).union(MAND).union(MANI).union(OUGR).union(PHLP).union(ROHG).union(SOGD).union(SYRC);\n    /// Arabic, Syriac\n    pub const ARAB_SYRC: ScriptExtension = ARAB.union(SYRC);\n    /// Arabic, Thaana, Yezidi\n    pub const ARAB_THAA_YEZI: ScriptExtension = ARAB.union(THAA).union(YEZI);\n    /// Arabic, Hanifi_Rohingya\n    pub const ARAB_ROHG: ScriptExtension = ARAB.union(ROHG);\n    /// Bengali, Devanagari, Grantha, Gujarati, Gurmukhi, Kannada, Latin, Malayalam, Nandinagari, Newa, Oriya, Sharada, Tamil, Telugu, Tirhuta\n    pub const BENG_DEVA_GRAN_GUJR_GURU_KNDA_LATN_MLYM_NAND_NEWA_ORYA_SHRD_TAML_TELU_TIRH: ScriptExtension = BENG.union(DEVA).union(GRAN).union(GUJR).union(GURU).union(KNDA).union(LATN).union(MLYM).union(NAND).union(NEWA).union(ORYA).union(SHRD).union(TAML).union(TELU).union(TIRH);\n    /// Bengali, Devanagari, Grantha, Gujarati, Gurmukhi, Kannada, Latin, Malayalam, Newa, Oriya, Tamil, Telugu, Tirhuta\n    pub const BENG_DEVA_GRAN_GUJR_GURU_KNDA_LATN_MLYM_NEWA_ORYA_TAML_TELU_TIRH: ScriptExtension = BENG.union(DEVA).union(GRAN).union(GUJR).union(GURU).union(KNDA).union(LATN).union(MLYM).union(NEWA).union(ORYA).union(TAML).union(TELU).union(TIRH);\n    /// Bengali, Devanagari, Dogra, Gunjala_Gondi, Masaram_Gondi, Grantha, Gujarati, Gurmukhi, Kannada, Mahajani, Malayalam, Nandinagari, Ol_Onal, Oriya, Khudawadi, Sinhala, Syloti_Nagri, Takri, Tamil, Telugu, Tirhuta\n    pub const BENG_DEVA_DOGR_GONG_GONM_GRAN_GUJR_GURU_KNDA_MAHJ_MLYM_NAND_ONAO_ORYA_SIND_SINH_SYLO_TAKR_TAML_TELU_TIRH: ScriptExtension = BENG.union(DEVA).union(DOGR).union(GONG).union(GONM).union(GRAN).union(GUJR).union(GURU).union(KNDA).union(MAHJ).union(MLYM).union(NAND).union(ONAO).union(ORYA).union(SIND).union(SINH).union(SYLO).union(TAKR).union(TAML).union(TELU).union(TIRH);\n    /// Bengali, Devanagari, Dogra, Gunjala_Gondi, Masaram_Gondi, Grantha, Gujarati, Gurung_Khema, Gurmukhi, Kannada, Limbu, Mahajani, Malayalam, Nandinagari, Ol_Onal, Oriya, Khudawadi, Sinhala, Syloti_Nagri, Takri, Tamil, Telugu, Tirhuta\n    pub const BENG_DEVA_DOGR_GONG_GONM_GRAN_GUJR_GUKH_GURU_KNDA_LIMB_MAHJ_MLYM_NAND_ONAO_ORYA_SIND_SINH_SYLO_TAKR_TAML_TELU_TIRH: ScriptExtension = BENG.union(DEVA).union(DOGR).union(GONG).union(GONM).union(GRAN).union(GUJR).union(GUKH).union(GURU).union(KNDA).union(LIMB).union(MAHJ).union(MLYM).union(NAND).union(ONAO).union(ORYA).union(SIND).union(SINH).union(SYLO).union(TAKR).union(TAML).union(TELU).union(TIRH);\n    /// Devanagari, Dogra, Kaithi, Mahajani\n    pub const DEVA_DOGR_KTHI_MAHJ: ScriptExtension = DEVA.union(DOGR).union(KTHI).union(MAHJ);\n    /// Bengali, Chakma, Syloti_Nagri\n    pub const BENG_CAKM_SYLO: ScriptExtension = BENG.union(CAKM).union(SYLO);\n    /// Gurmukhi, Multani\n    pub const GURU_MULT: ScriptExtension = GURU.union(MULT);\n    /// Gujarati, Khojki\n    pub const GUJR_KHOJ: ScriptExtension = GUJR.union(KHOJ);\n    /// Grantha, Tamil\n    pub const GRAN_TAML: ScriptExtension = GRAN.union(TAML);\n    /// Kannada, Nandinagari, Tulu_Tigalari\n    pub const KNDA_NAND_TUTG: ScriptExtension = KNDA.union(NAND).union(TUTG);\n    /// Chakma, Myanmar, Tai_Le\n    pub const CAKM_MYMR_TALE: ScriptExtension = CAKM.union(MYMR).union(TALE);\n    /// Georgian, Glagolitic, Latin\n    pub const GEOR_GLAG_LATN: ScriptExtension = GEOR.union(GLAG).union(LATN);\n    /// Buhid, Hanunoo, Tagbanwa, Tagalog\n    pub const BUHD_HANO_TAGB_TGLG: ScriptExtension = BUHD.union(HANO).union(TAGB).union(TGLG);\n    /// Mongolian, Phags_Pa\n    pub const MONG_PHAG: ScriptExtension = MONG.union(PHAG);\n    /// Bengali, Devanagari, Grantha, Kannada\n    pub const BENG_DEVA_GRAN_KNDA: ScriptExtension = BENG.union(DEVA).union(GRAN).union(KNDA);\n    /// Devanagari, Grantha, Kannada\n    pub const DEVA_GRAN_KNDA: ScriptExtension = DEVA.union(GRAN).union(KNDA);\n    /// Bengali, Devanagari, Newa, Telugu, Tirhuta\n    pub const BENG_DEVA_NEWA_TELU_TIRH: ScriptExtension = BENG.union(DEVA).union(NEWA).union(TELU).union(TIRH);\n    /// Bengali, Devanagari, Telugu\n    pub const BENG_DEVA_TELU: ScriptExtension = BENG.union(DEVA).union(TELU);\n    /// Devanagari, Newa, Sharada\n    pub const DEVA_NEWA_SHRD: ScriptExtension = DEVA.union(NEWA).union(SHRD);\n    /// Bengali, Devanagari, Newa, Telugu\n    pub const BENG_DEVA_NEWA_TELU: ScriptExtension = BENG.union(DEVA).union(NEWA).union(TELU);\n    /// Devanagari, Sharada\n    pub const DEVA_SHRD: ScriptExtension = DEVA.union(SHRD);\n    /// Devanagari, Kannada, Malayalam, Oriya, Tamil, Telugu\n    pub const DEVA_KNDA_MLYM_ORYA_TAML_TELU: ScriptExtension = DEVA.union(KNDA).union(MLYM).union(ORYA).union(TAML).union(TELU);\n    /// Bengali, Devanagari\n    pub const BENG_DEVA: ScriptExtension = BENG.union(DEVA);\n    /// Devanagari, Newa, Tirhuta\n    pub const DEVA_NEWA_TIRH: ScriptExtension = DEVA.union(NEWA).union(TIRH);\n    /// Devanagari, Nandinagari, Newa\n    pub const DEVA_NAND_NEWA: ScriptExtension = DEVA.union(NAND).union(NEWA);\n    /// Bengali, Devanagari, Sharada\n    pub const BENG_DEVA_SHRD: ScriptExtension = BENG.union(DEVA).union(SHRD);\n    /// Devanagari, Newa\n    pub const DEVA_NEWA: ScriptExtension = DEVA.union(NEWA);\n    /// Bengali, Devanagari, Newa, Sharada\n    pub const BENG_DEVA_NEWA_SHRD: ScriptExtension = BENG.union(DEVA).union(NEWA).union(SHRD);\n    /// Bengali, Devanagari, Grantha, Kannada, Malayalam, Nandinagari, Oriya, Sinhala, Telugu, Tirhuta, Tulu_Tigalari\n    pub const BENG_DEVA_GRAN_KNDA_MLYM_NAND_ORYA_SINH_TELU_TIRH_TUTG: ScriptExtension = BENG.union(DEVA).union(GRAN).union(KNDA).union(MLYM).union(NAND).union(ORYA).union(SINH).union(TELU).union(TIRH).union(TUTG);\n    /// Devanagari, Grantha\n    pub const DEVA_GRAN: ScriptExtension = DEVA.union(GRAN);\n    /// Devanagari, Grantha, Kannada, Tulu_Tigalari\n    pub const DEVA_GRAN_KNDA_TUTG: ScriptExtension = DEVA.union(GRAN).union(KNDA).union(TUTG);\n    /// Cyrillic, Latin, Syriac\n    pub const CYRL_LATN_SYRC: ScriptExtension = CYRL.union(LATN).union(SYRC);\n    /// Latin, Mongolian, Phags_Pa\n    pub const LATN_MONG_PHAG: ScriptExtension = LATN.union(MONG).union(PHAG);\n    /// Adlam, Arabic\n    pub const ADLM_ARAB: ScriptExtension = ADLM.union(ARAB);\n    /// Carian, Georgian, Glagolitic, Old_Hungarian, Lycian, Old_Turkic\n    pub const CARI_GEOR_GLAG_HUNG_LYCI_ORKH: ScriptExtension = CARI.union(GEOR).union(GLAG).union(HUNG).union(LYCI).union(ORKH);\n    /// Carian, Greek, Old_Hungarian, Meroitic_Hieroglyphs\n    pub const CARI_GREK_HUNG_MERO: ScriptExtension = CARI.union(GREK).union(HUNG).union(MERO);\n    /// Devanagari, Grantha, Latin\n    pub const DEVA_GRAN_LATN: ScriptExtension = DEVA.union(GRAN).union(LATN);\n    /// Coptic, Latin\n    pub const COPT_LATN: ScriptExtension = COPT.union(LATN);\n    /// Avestan, Old_Turkic\n    pub const AVST_ORKH: ScriptExtension = AVST.union(ORKH);\n    /// Avestan, Carian, Georgian, Old_Hungarian, Kaithi, Lydian, Samaritan\n    pub const AVST_CARI_GEOR_HUNG_KTHI_LYDI_SAMR: ScriptExtension = AVST.union(CARI).union(GEOR).union(HUNG).union(KTHI).union(LYDI).union(SAMR);\n    /// Adlam, Arabic, Old_Hungarian\n    pub const ADLM_ARAB_HUNG: ScriptExtension = ADLM.union(ARAB).union(HUNG);\n    /// Han, Tangut\n    pub const HANI_TANG: ScriptExtension = HANI.union(TANG);\n    /// Bopomofo, Hangul, Han, Hiragana, Katakana, Mongolian, Yi\n    pub const BOPO_HANG_HANI_HIRA_KANA_MONG_YIII: ScriptExtension = BOPO.union(HANG).union(HANI).union(HIRA).union(KANA).union(MONG).union(YIII);\n    /// Bopomofo, Hangul, Han, Hiragana, Katakana, Mongolian, Phags_Pa, Yi\n    pub const BOPO_HANG_HANI_HIRA_KANA_MONG_PHAG_YIII: ScriptExtension = BOPO.union(HANG).union(HANI).union(HIRA).union(KANA).union(MONG).union(PHAG).union(YIII);\n    /// Bopomofo, Hangul, Han, Hiragana, Katakana\n    pub const BOPO_HANG_HANI_HIRA_KANA: ScriptExtension = BOPO.union(HANG).union(HANI).union(HIRA).union(KANA);\n    /// Bopomofo, Hangul, Han, Hiragana, Katakana, Mongolian, Tibetan, Yi\n    pub const BOPO_HANG_HANI_HIRA_KANA_MONG_TIBT_YIII: ScriptExtension = BOPO.union(HANG).union(HANI).union(HIRA).union(KANA).union(MONG).union(TIBT).union(YIII);\n    /// Bopomofo, Hangul, Han, Hiragana, Katakana, Lisu, Mongolian, Tibetan, Yi\n    pub const BOPO_HANG_HANI_HIRA_KANA_LISU_MONG_TIBT_YIII: ScriptExtension = BOPO.union(HANG).union(HANI).union(HIRA).union(KANA).union(LISU).union(MONG).union(TIBT).union(YIII);\n    /// Bopomofo, Hangul, Han, Hiragana, Katakana, Yi\n    pub const BOPO_HANG_HANI_HIRA_KANA_YIII: ScriptExtension = BOPO.union(HANG).union(HANI).union(HIRA).union(KANA).union(YIII);\n    /// Bopomofo, Han\n    pub const BOPO_HANI: ScriptExtension = BOPO.union(HANI);\n    /// Hiragana, Katakana\n    pub const HIRA_KANA: ScriptExtension = HIRA.union(KANA);\n    /// Han, Hiragana, Katakana\n    pub const HANI_HIRA_KANA: ScriptExtension = HANI.union(HIRA).union(KANA);\n    /// Han, Latin\n    pub const HANI_LATN: ScriptExtension = HANI.union(LATN);\n    /// Devanagari, Dogra, Gujarati, Gurmukhi, Khojki, Kannada, Kaithi, Mahajani, Malayalam, Modi, Nandinagari, Sharada, Khudawadi, Takri, Tirhuta, Tulu_Tigalari\n    pub const DEVA_DOGR_GUJR_GURU_KHOJ_KNDA_KTHI_MAHJ_MLYM_MODI_NAND_SHRD_SIND_TAKR_TIRH_TUTG: ScriptExtension = DEVA.union(DOGR).union(GUJR).union(GURU).union(KHOJ).union(KNDA).union(KTHI).union(MAHJ).union(MLYM).union(MODI).union(NAND).union(SHRD).union(SIND).union(TAKR).union(TIRH).union(TUTG);\n    /// Devanagari, Dogra, Gujarati, Gurmukhi, Khojki, Kannada, Kaithi, Mahajani, Modi, Nandinagari, Sharada, Khudawadi, Takri, Tirhuta, Tulu_Tigalari\n    pub const DEVA_DOGR_GUJR_GURU_KHOJ_KNDA_KTHI_MAHJ_MODI_NAND_SHRD_SIND_TAKR_TIRH_TUTG: ScriptExtension = DEVA.union(DOGR).union(GUJR).union(GURU).union(KHOJ).union(KNDA).union(KTHI).union(MAHJ).union(MODI).union(NAND).union(SHRD).union(SIND).union(TAKR).union(TIRH).union(TUTG);\n    /// Devanagari, Dogra, Gujarati, Gurmukhi, Khojki, Kaithi, Mahajani, Modi, Khudawadi, Takri, Tirhuta\n    pub const DEVA_DOGR_GUJR_GURU_KHOJ_KTHI_MAHJ_MODI_SIND_TAKR_TIRH: ScriptExtension = DEVA.union(DOGR).union(GUJR).union(GURU).union(KHOJ).union(KTHI).union(MAHJ).union(MODI).union(SIND).union(TAKR).union(TIRH);\n    /// Devanagari, Dogra, Gujarati, Gurmukhi, Khojki, Kaithi, Mahajani, Modi, Sharada, Khudawadi, Takri, Tirhuta\n    pub const DEVA_DOGR_GUJR_GURU_KHOJ_KTHI_MAHJ_MODI_SHRD_SIND_TAKR_TIRH: ScriptExtension = DEVA.union(DOGR).union(GUJR).union(GURU).union(KHOJ).union(KTHI).union(MAHJ).union(MODI).union(SHRD).union(SIND).union(TAKR).union(TIRH);\n    /// Bengali, Devanagari, Tulu_Tigalari\n    pub const BENG_DEVA_TUTG: ScriptExtension = BENG.union(DEVA).union(TUTG);\n    /// Devanagari, Tamil\n    pub const DEVA_TAML: ScriptExtension = DEVA.union(TAML);\n    /// Kayah_Li, Latin, Myanmar\n    pub const KALI_LATN_MYMR: ScriptExtension = KALI.union(LATN).union(MYMR);\n    /// Buginese, Javanese\n    pub const BUGI_JAVA: ScriptExtension = BUGI.union(JAVA);\n    /// Arabic, Nko\n    pub const ARAB_NKOO: ScriptExtension = ARAB.union(NKOO);\n    /// Arabic, Thaana\n    pub const ARAB_THAA: ScriptExtension = ARAB.union(THAA);\n    /// Cypro_Minoan, Cypriot, Linear_B\n    pub const CPMN_CPRT_LINB: ScriptExtension = CPMN.union(CPRT).union(LINB);\n    /// Cypriot, Linear_B\n    pub const CPRT_LINB: ScriptExtension = CPRT.union(LINB);\n    /// Cypriot, Linear_A, Linear_B\n    pub const CPRT_LINA_LINB: ScriptExtension = CPRT.union(LINA).union(LINB);\n    /// Arabic, Coptic\n    pub const ARAB_COPT: ScriptExtension = ARAB.union(COPT);\n    /// Manichaean, Old_Uyghur\n    pub const MANI_OUGR: ScriptExtension = MANI.union(OUGR);\n}\n\nimpl Script {\n\n    #[inline]\n    pub(crate) fn inner_full_name(self) -> &'static str {\n        match self {\n            Script::Unknown => \"Unknown\",\n            Script::Common => \"Common\",\n            Script::Inherited => \"Inherited\",\n            Script::Adlam => \"Adlam\",\n            Script::Caucasian_Albanian => \"Caucasian_Albanian\",\n            Script::Ahom => \"Ahom\",\n            Script::Arabic => \"Arabic\",\n            Script::Imperial_Aramaic => \"Imperial_Aramaic\",\n            Script::Armenian => \"Armenian\",\n            Script::Avestan => \"Avestan\",\n            Script::Balinese => \"Balinese\",\n            Script::Bamum => \"Bamum\",\n            Script::Bassa_Vah => \"Bassa_Vah\",\n            Script::Batak => \"Batak\",\n            Script::Bengali => \"Bengali\",\n            Script::Beria_Erfe => \"Beria_Erfe\",\n            Script::Bhaiksuki => \"Bhaiksuki\",\n            Script::Bopomofo => \"Bopomofo\",\n            Script::Brahmi => \"Brahmi\",\n            Script::Braille => \"Braille\",\n            Script::Buginese => \"Buginese\",\n            Script::Buhid => \"Buhid\",\n            Script::Chakma => \"Chakma\",\n            Script::Canadian_Aboriginal => \"Canadian_Aboriginal\",\n            Script::Carian => \"Carian\",\n            Script::Cham => \"Cham\",\n            Script::Cherokee => \"Cherokee\",\n            Script::Chorasmian => \"Chorasmian\",\n            Script::Coptic => \"Coptic\",\n            Script::Cypro_Minoan => \"Cypro_Minoan\",\n            Script::Cypriot => \"Cypriot\",\n            Script::Cyrillic => \"Cyrillic\",\n            Script::Devanagari => \"Devanagari\",\n            Script::Dives_Akuru => \"Dives_Akuru\",\n            Script::Dogra => \"Dogra\",\n            Script::Deseret => \"Deseret\",\n            Script::Duployan => \"Duployan\",\n            Script::Egyptian_Hieroglyphs => \"Egyptian_Hieroglyphs\",\n            Script::Elbasan => \"Elbasan\",\n            Script::Elymaic => \"Elymaic\",\n            Script::Ethiopic => \"Ethiopic\",\n            Script::Garay => \"Garay\",\n            Script::Georgian => \"Georgian\",\n            Script::Glagolitic => \"Glagolitic\",\n            Script::Gunjala_Gondi => \"Gunjala_Gondi\",\n            Script::Masaram_Gondi => \"Masaram_Gondi\",\n            Script::Gothic => \"Gothic\",\n            Script::Grantha => \"Grantha\",\n            Script::Greek => \"Greek\",\n            Script::Gujarati => \"Gujarati\",\n            Script::Gurung_Khema => \"Gurung_Khema\",\n            Script::Gurmukhi => \"Gurmukhi\",\n            Script::Hangul => \"Hangul\",\n            Script::Han => \"Han\",\n            Script::Hanunoo => \"Hanunoo\",\n            Script::Hatran => \"Hatran\",\n            Script::Hebrew => \"Hebrew\",\n            Script::Hiragana => \"Hiragana\",\n            Script::Anatolian_Hieroglyphs => \"Anatolian_Hieroglyphs\",\n            Script::Pahawh_Hmong => \"Pahawh_Hmong\",\n            Script::Nyiakeng_Puachue_Hmong => \"Nyiakeng_Puachue_Hmong\",\n            Script::Old_Hungarian => \"Old_Hungarian\",\n            Script::Old_Italic => \"Old_Italic\",\n            Script::Javanese => \"Javanese\",\n            Script::Kayah_Li => \"Kayah_Li\",\n            Script::Katakana => \"Katakana\",\n            Script::Kawi => \"Kawi\",\n            Script::Kharoshthi => \"Kharoshthi\",\n            Script::Khmer => \"Khmer\",\n            Script::Khojki => \"Khojki\",\n            Script::Khitan_Small_Script => \"Khitan_Small_Script\",\n            Script::Kannada => \"Kannada\",\n            Script::Kirat_Rai => \"Kirat_Rai\",\n            Script::Kaithi => \"Kaithi\",\n            Script::Tai_Tham => \"Tai_Tham\",\n            Script::Lao => \"Lao\",\n            Script::Latin => \"Latin\",\n            Script::Lepcha => \"Lepcha\",\n            Script::Limbu => \"Limbu\",\n            Script::Linear_A => \"Linear_A\",\n            Script::Linear_B => \"Linear_B\",\n            Script::Lisu => \"Lisu\",\n            Script::Lycian => \"Lycian\",\n            Script::Lydian => \"Lydian\",\n            Script::Mahajani => \"Mahajani\",\n            Script::Makasar => \"Makasar\",\n            Script::Mandaic => \"Mandaic\",\n            Script::Manichaean => \"Manichaean\",\n            Script::Marchen => \"Marchen\",\n            Script::Medefaidrin => \"Medefaidrin\",\n            Script::Mende_Kikakui => \"Mende_Kikakui\",\n            Script::Meroitic_Cursive => \"Meroitic_Cursive\",\n            Script::Meroitic_Hieroglyphs => \"Meroitic_Hieroglyphs\",\n            Script::Malayalam => \"Malayalam\",\n            Script::Modi => \"Modi\",\n            Script::Mongolian => \"Mongolian\",\n            Script::Mro => \"Mro\",\n            Script::Meetei_Mayek => \"Meetei_Mayek\",\n            Script::Multani => \"Multani\",\n            Script::Myanmar => \"Myanmar\",\n            Script::Nag_Mundari => \"Nag_Mundari\",\n            Script::Nandinagari => \"Nandinagari\",\n            Script::Old_North_Arabian => \"Old_North_Arabian\",\n            Script::Nabataean => \"Nabataean\",\n            Script::Newa => \"Newa\",\n            Script::Nko => \"Nko\",\n            Script::Nushu => \"Nushu\",\n            Script::Ogham => \"Ogham\",\n            Script::Ol_Chiki => \"Ol_Chiki\",\n            Script::Ol_Onal => \"Ol_Onal\",\n            Script::Old_Turkic => \"Old_Turkic\",\n            Script::Oriya => \"Oriya\",\n            Script::Osage => \"Osage\",\n            Script::Osmanya => \"Osmanya\",\n            Script::Old_Uyghur => \"Old_Uyghur\",\n            Script::Palmyrene => \"Palmyrene\",\n            Script::Pau_Cin_Hau => \"Pau_Cin_Hau\",\n            Script::Old_Permic => \"Old_Permic\",\n            Script::Phags_Pa => \"Phags_Pa\",\n            Script::Inscriptional_Pahlavi => \"Inscriptional_Pahlavi\",\n            Script::Psalter_Pahlavi => \"Psalter_Pahlavi\",\n            Script::Phoenician => \"Phoenician\",\n            Script::Miao => \"Miao\",\n            Script::Inscriptional_Parthian => \"Inscriptional_Parthian\",\n            Script::Rejang => \"Rejang\",\n            Script::Hanifi_Rohingya => \"Hanifi_Rohingya\",\n            Script::Runic => \"Runic\",\n            Script::Samaritan => \"Samaritan\",\n            Script::Old_South_Arabian => \"Old_South_Arabian\",\n            Script::Saurashtra => \"Saurashtra\",\n            Script::SignWriting => \"SignWriting\",\n            Script::Shavian => \"Shavian\",\n            Script::Sharada => \"Sharada\",\n            Script::Siddham => \"Siddham\",\n            Script::Sidetic => \"Sidetic\",\n            Script::Khudawadi => \"Khudawadi\",\n            Script::Sinhala => \"Sinhala\",\n            Script::Sogdian => \"Sogdian\",\n            Script::Old_Sogdian => \"Old_Sogdian\",\n            Script::Sora_Sompeng => \"Sora_Sompeng\",\n            Script::Soyombo => \"Soyombo\",\n            Script::Sundanese => \"Sundanese\",\n            Script::Sunuwar => \"Sunuwar\",\n            Script::Syloti_Nagri => \"Syloti_Nagri\",\n            Script::Syriac => \"Syriac\",\n            Script::Tagbanwa => \"Tagbanwa\",\n            Script::Takri => \"Takri\",\n            Script::Tai_Le => \"Tai_Le\",\n            Script::New_Tai_Lue => \"New_Tai_Lue\",\n            Script::Tamil => \"Tamil\",\n            Script::Tangut => \"Tangut\",\n            Script::Tai_Viet => \"Tai_Viet\",\n            Script::Tai_Yo => \"Tai_Yo\",\n            Script::Telugu => \"Telugu\",\n            Script::Tifinagh => \"Tifinagh\",\n            Script::Tagalog => \"Tagalog\",\n            Script::Thaana => \"Thaana\",\n            Script::Thai => \"Thai\",\n            Script::Tibetan => \"Tibetan\",\n            Script::Tirhuta => \"Tirhuta\",\n            Script::Tangsa => \"Tangsa\",\n            Script::Todhri => \"Todhri\",\n            Script::Tolong_Siki => \"Tolong_Siki\",\n            Script::Toto => \"Toto\",\n            Script::Tulu_Tigalari => \"Tulu_Tigalari\",\n            Script::Ugaritic => \"Ugaritic\",\n            Script::Vai => \"Vai\",\n            Script::Vithkuqi => \"Vithkuqi\",\n            Script::Warang_Citi => \"Warang_Citi\",\n            Script::Wancho => \"Wancho\",\n            Script::Old_Persian => \"Old_Persian\",\n            Script::Cuneiform => \"Cuneiform\",\n            Script::Yezidi => \"Yezidi\",\n            Script::Yi => \"Yi\",\n            Script::Zanabazar_Square => \"Zanabazar_Square\",\n        }\n    }\n\n    #[inline]\n    pub(crate) fn inner_from_full_name(input: &str) -> Option<Self> {\n        match input {\n            \"Unknown\" => Some(Script::Unknown),\n            \"Common\" => Some(Script::Common),\n            \"Inherited\" => Some(Script::Inherited),\n            \"Adlam\" => Some(Script::Adlam),\n            \"Caucasian_Albanian\" => Some(Script::Caucasian_Albanian),\n            \"Ahom\" => Some(Script::Ahom),\n            \"Arabic\" => Some(Script::Arabic),\n            \"Imperial_Aramaic\" => Some(Script::Imperial_Aramaic),\n            \"Armenian\" => Some(Script::Armenian),\n            \"Avestan\" => Some(Script::Avestan),\n            \"Balinese\" => Some(Script::Balinese),\n            \"Bamum\" => Some(Script::Bamum),\n            \"Bassa_Vah\" => Some(Script::Bassa_Vah),\n            \"Batak\" => Some(Script::Batak),\n            \"Bengali\" => Some(Script::Bengali),\n            \"Beria_Erfe\" => Some(Script::Beria_Erfe),\n            \"Bhaiksuki\" => Some(Script::Bhaiksuki),\n            \"Bopomofo\" => Some(Script::Bopomofo),\n            \"Brahmi\" => Some(Script::Brahmi),\n            \"Braille\" => Some(Script::Braille),\n            \"Buginese\" => Some(Script::Buginese),\n            \"Buhid\" => Some(Script::Buhid),\n            \"Chakma\" => Some(Script::Chakma),\n            \"Canadian_Aboriginal\" => Some(Script::Canadian_Aboriginal),\n            \"Carian\" => Some(Script::Carian),\n            \"Cham\" => Some(Script::Cham),\n            \"Cherokee\" => Some(Script::Cherokee),\n            \"Chorasmian\" => Some(Script::Chorasmian),\n            \"Coptic\" => Some(Script::Coptic),\n            \"Cypro_Minoan\" => Some(Script::Cypro_Minoan),\n            \"Cypriot\" => Some(Script::Cypriot),\n            \"Cyrillic\" => Some(Script::Cyrillic),\n            \"Devanagari\" => Some(Script::Devanagari),\n            \"Dives_Akuru\" => Some(Script::Dives_Akuru),\n            \"Dogra\" => Some(Script::Dogra),\n            \"Deseret\" => Some(Script::Deseret),\n            \"Duployan\" => Some(Script::Duployan),\n            \"Egyptian_Hieroglyphs\" => Some(Script::Egyptian_Hieroglyphs),\n            \"Elbasan\" => Some(Script::Elbasan),\n            \"Elymaic\" => Some(Script::Elymaic),\n            \"Ethiopic\" => Some(Script::Ethiopic),\n            \"Garay\" => Some(Script::Garay),\n            \"Georgian\" => Some(Script::Georgian),\n            \"Glagolitic\" => Some(Script::Glagolitic),\n            \"Gunjala_Gondi\" => Some(Script::Gunjala_Gondi),\n            \"Masaram_Gondi\" => Some(Script::Masaram_Gondi),\n            \"Gothic\" => Some(Script::Gothic),\n            \"Grantha\" => Some(Script::Grantha),\n            \"Greek\" => Some(Script::Greek),\n            \"Gujarati\" => Some(Script::Gujarati),\n            \"Gurung_Khema\" => Some(Script::Gurung_Khema),\n            \"Gurmukhi\" => Some(Script::Gurmukhi),\n            \"Hangul\" => Some(Script::Hangul),\n            \"Han\" => Some(Script::Han),\n            \"Hanunoo\" => Some(Script::Hanunoo),\n            \"Hatran\" => Some(Script::Hatran),\n            \"Hebrew\" => Some(Script::Hebrew),\n            \"Hiragana\" => Some(Script::Hiragana),\n            \"Anatolian_Hieroglyphs\" => Some(Script::Anatolian_Hieroglyphs),\n            \"Pahawh_Hmong\" => Some(Script::Pahawh_Hmong),\n            \"Nyiakeng_Puachue_Hmong\" => Some(Script::Nyiakeng_Puachue_Hmong),\n            \"Old_Hungarian\" => Some(Script::Old_Hungarian),\n            \"Old_Italic\" => Some(Script::Old_Italic),\n            \"Javanese\" => Some(Script::Javanese),\n            \"Kayah_Li\" => Some(Script::Kayah_Li),\n            \"Katakana\" => Some(Script::Katakana),\n            \"Kawi\" => Some(Script::Kawi),\n            \"Kharoshthi\" => Some(Script::Kharoshthi),\n            \"Khmer\" => Some(Script::Khmer),\n            \"Khojki\" => Some(Script::Khojki),\n            \"Khitan_Small_Script\" => Some(Script::Khitan_Small_Script),\n            \"Kannada\" => Some(Script::Kannada),\n            \"Kirat_Rai\" => Some(Script::Kirat_Rai),\n            \"Kaithi\" => Some(Script::Kaithi),\n            \"Tai_Tham\" => Some(Script::Tai_Tham),\n            \"Lao\" => Some(Script::Lao),\n            \"Latin\" => Some(Script::Latin),\n            \"Lepcha\" => Some(Script::Lepcha),\n            \"Limbu\" => Some(Script::Limbu),\n            \"Linear_A\" => Some(Script::Linear_A),\n            \"Linear_B\" => Some(Script::Linear_B),\n            \"Lisu\" => Some(Script::Lisu),\n            \"Lycian\" => Some(Script::Lycian),\n            \"Lydian\" => Some(Script::Lydian),\n            \"Mahajani\" => Some(Script::Mahajani),\n            \"Makasar\" => Some(Script::Makasar),\n            \"Mandaic\" => Some(Script::Mandaic),\n            \"Manichaean\" => Some(Script::Manichaean),\n            \"Marchen\" => Some(Script::Marchen),\n            \"Medefaidrin\" => Some(Script::Medefaidrin),\n            \"Mende_Kikakui\" => Some(Script::Mende_Kikakui),\n            \"Meroitic_Cursive\" => Some(Script::Meroitic_Cursive),\n            \"Meroitic_Hieroglyphs\" => Some(Script::Meroitic_Hieroglyphs),\n            \"Malayalam\" => Some(Script::Malayalam),\n            \"Modi\" => Some(Script::Modi),\n            \"Mongolian\" => Some(Script::Mongolian),\n            \"Mro\" => Some(Script::Mro),\n            \"Meetei_Mayek\" => Some(Script::Meetei_Mayek),\n            \"Multani\" => Some(Script::Multani),\n            \"Myanmar\" => Some(Script::Myanmar),\n            \"Nag_Mundari\" => Some(Script::Nag_Mundari),\n            \"Nandinagari\" => Some(Script::Nandinagari),\n            \"Old_North_Arabian\" => Some(Script::Old_North_Arabian),\n            \"Nabataean\" => Some(Script::Nabataean),\n            \"Newa\" => Some(Script::Newa),\n            \"Nko\" => Some(Script::Nko),\n            \"Nushu\" => Some(Script::Nushu),\n            \"Ogham\" => Some(Script::Ogham),\n            \"Ol_Chiki\" => Some(Script::Ol_Chiki),\n            \"Ol_Onal\" => Some(Script::Ol_Onal),\n            \"Old_Turkic\" => Some(Script::Old_Turkic),\n            \"Oriya\" => Some(Script::Oriya),\n            \"Osage\" => Some(Script::Osage),\n            \"Osmanya\" => Some(Script::Osmanya),\n            \"Old_Uyghur\" => Some(Script::Old_Uyghur),\n            \"Palmyrene\" => Some(Script::Palmyrene),\n            \"Pau_Cin_Hau\" => Some(Script::Pau_Cin_Hau),\n            \"Old_Permic\" => Some(Script::Old_Permic),\n            \"Phags_Pa\" => Some(Script::Phags_Pa),\n            \"Inscriptional_Pahlavi\" => Some(Script::Inscriptional_Pahlavi),\n            \"Psalter_Pahlavi\" => Some(Script::Psalter_Pahlavi),\n            \"Phoenician\" => Some(Script::Phoenician),\n            \"Miao\" => Some(Script::Miao),\n            \"Inscriptional_Parthian\" => Some(Script::Inscriptional_Parthian),\n            \"Rejang\" => Some(Script::Rejang),\n            \"Hanifi_Rohingya\" => Some(Script::Hanifi_Rohingya),\n            \"Runic\" => Some(Script::Runic),\n            \"Samaritan\" => Some(Script::Samaritan),\n            \"Old_South_Arabian\" => Some(Script::Old_South_Arabian),\n            \"Saurashtra\" => Some(Script::Saurashtra),\n            \"SignWriting\" => Some(Script::SignWriting),\n            \"Shavian\" => Some(Script::Shavian),\n            \"Sharada\" => Some(Script::Sharada),\n            \"Siddham\" => Some(Script::Siddham),\n            \"Sidetic\" => Some(Script::Sidetic),\n            \"Khudawadi\" => Some(Script::Khudawadi),\n            \"Sinhala\" => Some(Script::Sinhala),\n            \"Sogdian\" => Some(Script::Sogdian),\n            \"Old_Sogdian\" => Some(Script::Old_Sogdian),\n            \"Sora_Sompeng\" => Some(Script::Sora_Sompeng),\n            \"Soyombo\" => Some(Script::Soyombo),\n            \"Sundanese\" => Some(Script::Sundanese),\n            \"Sunuwar\" => Some(Script::Sunuwar),\n            \"Syloti_Nagri\" => Some(Script::Syloti_Nagri),\n            \"Syriac\" => Some(Script::Syriac),\n            \"Tagbanwa\" => Some(Script::Tagbanwa),\n            \"Takri\" => Some(Script::Takri),\n            \"Tai_Le\" => Some(Script::Tai_Le),\n            \"New_Tai_Lue\" => Some(Script::New_Tai_Lue),\n            \"Tamil\" => Some(Script::Tamil),\n            \"Tangut\" => Some(Script::Tangut),\n            \"Tai_Viet\" => Some(Script::Tai_Viet),\n            \"Tai_Yo\" => Some(Script::Tai_Yo),\n            \"Telugu\" => Some(Script::Telugu),\n            \"Tifinagh\" => Some(Script::Tifinagh),\n            \"Tagalog\" => Some(Script::Tagalog),\n            \"Thaana\" => Some(Script::Thaana),\n            \"Thai\" => Some(Script::Thai),\n            \"Tibetan\" => Some(Script::Tibetan),\n            \"Tirhuta\" => Some(Script::Tirhuta),\n            \"Tangsa\" => Some(Script::Tangsa),\n            \"Todhri\" => Some(Script::Todhri),\n            \"Tolong_Siki\" => Some(Script::Tolong_Siki),\n            \"Toto\" => Some(Script::Toto),\n            \"Tulu_Tigalari\" => Some(Script::Tulu_Tigalari),\n            \"Ugaritic\" => Some(Script::Ugaritic),\n            \"Vai\" => Some(Script::Vai),\n            \"Vithkuqi\" => Some(Script::Vithkuqi),\n            \"Warang_Citi\" => Some(Script::Warang_Citi),\n            \"Wancho\" => Some(Script::Wancho),\n            \"Old_Persian\" => Some(Script::Old_Persian),\n            \"Cuneiform\" => Some(Script::Cuneiform),\n            \"Yezidi\" => Some(Script::Yezidi),\n            \"Yi\" => Some(Script::Yi),\n            \"Zanabazar_Square\" => Some(Script::Zanabazar_Square),\n            _ => None,\n        }\n    }\n\n    #[inline]\n    pub(crate) fn inner_short_name(self) -> &'static str {\n        match self {\n            Script::Unknown => \"Zzzz\",\n            Script::Common => \"Zyyy\",\n            Script::Inherited => \"Zinh\",\n            Script::Adlam => \"Adlm\",\n            Script::Caucasian_Albanian => \"Aghb\",\n            Script::Ahom => \"Ahom\",\n            Script::Arabic => \"Arab\",\n            Script::Imperial_Aramaic => \"Armi\",\n            Script::Armenian => \"Armn\",\n            Script::Avestan => \"Avst\",\n            Script::Balinese => \"Bali\",\n            Script::Bamum => \"Bamu\",\n            Script::Bassa_Vah => \"Bass\",\n            Script::Batak => \"Batk\",\n            Script::Bengali => \"Beng\",\n            Script::Beria_Erfe => \"Berf\",\n            Script::Bhaiksuki => \"Bhks\",\n            Script::Bopomofo => \"Bopo\",\n            Script::Brahmi => \"Brah\",\n            Script::Braille => \"Brai\",\n            Script::Buginese => \"Bugi\",\n            Script::Buhid => \"Buhd\",\n            Script::Chakma => \"Cakm\",\n            Script::Canadian_Aboriginal => \"Cans\",\n            Script::Carian => \"Cari\",\n            Script::Cham => \"Cham\",\n            Script::Cherokee => \"Cher\",\n            Script::Chorasmian => \"Chrs\",\n            Script::Coptic => \"Copt\",\n            Script::Cypro_Minoan => \"Cpmn\",\n            Script::Cypriot => \"Cprt\",\n            Script::Cyrillic => \"Cyrl\",\n            Script::Devanagari => \"Deva\",\n            Script::Dives_Akuru => \"Diak\",\n            Script::Dogra => \"Dogr\",\n            Script::Deseret => \"Dsrt\",\n            Script::Duployan => \"Dupl\",\n            Script::Egyptian_Hieroglyphs => \"Egyp\",\n            Script::Elbasan => \"Elba\",\n            Script::Elymaic => \"Elym\",\n            Script::Ethiopic => \"Ethi\",\n            Script::Garay => \"Gara\",\n            Script::Georgian => \"Geor\",\n            Script::Glagolitic => \"Glag\",\n            Script::Gunjala_Gondi => \"Gong\",\n            Script::Masaram_Gondi => \"Gonm\",\n            Script::Gothic => \"Goth\",\n            Script::Grantha => \"Gran\",\n            Script::Greek => \"Grek\",\n            Script::Gujarati => \"Gujr\",\n            Script::Gurung_Khema => \"Gukh\",\n            Script::Gurmukhi => \"Guru\",\n            Script::Hangul => \"Hang\",\n            Script::Han => \"Hani\",\n            Script::Hanunoo => \"Hano\",\n            Script::Hatran => \"Hatr\",\n            Script::Hebrew => \"Hebr\",\n            Script::Hiragana => \"Hira\",\n            Script::Anatolian_Hieroglyphs => \"Hluw\",\n            Script::Pahawh_Hmong => \"Hmng\",\n            Script::Nyiakeng_Puachue_Hmong => \"Hmnp\",\n            Script::Old_Hungarian => \"Hung\",\n            Script::Old_Italic => \"Ital\",\n            Script::Javanese => \"Java\",\n            Script::Kayah_Li => \"Kali\",\n            Script::Katakana => \"Kana\",\n            Script::Kawi => \"Kawi\",\n            Script::Kharoshthi => \"Khar\",\n            Script::Khmer => \"Khmr\",\n            Script::Khojki => \"Khoj\",\n            Script::Khitan_Small_Script => \"Kits\",\n            Script::Kannada => \"Knda\",\n            Script::Kirat_Rai => \"Krai\",\n            Script::Kaithi => \"Kthi\",\n            Script::Tai_Tham => \"Lana\",\n            Script::Lao => \"Laoo\",\n            Script::Latin => \"Latn\",\n            Script::Lepcha => \"Lepc\",\n            Script::Limbu => \"Limb\",\n            Script::Linear_A => \"Lina\",\n            Script::Linear_B => \"Linb\",\n            Script::Lisu => \"Lisu\",\n            Script::Lycian => \"Lyci\",\n            Script::Lydian => \"Lydi\",\n            Script::Mahajani => \"Mahj\",\n            Script::Makasar => \"Maka\",\n            Script::Mandaic => \"Mand\",\n            Script::Manichaean => \"Mani\",\n            Script::Marchen => \"Marc\",\n            Script::Medefaidrin => \"Medf\",\n            Script::Mende_Kikakui => \"Mend\",\n            Script::Meroitic_Cursive => \"Merc\",\n            Script::Meroitic_Hieroglyphs => \"Mero\",\n            Script::Malayalam => \"Mlym\",\n            Script::Modi => \"Modi\",\n            Script::Mongolian => \"Mong\",\n            Script::Mro => \"Mroo\",\n            Script::Meetei_Mayek => \"Mtei\",\n            Script::Multani => \"Mult\",\n            Script::Myanmar => \"Mymr\",\n            Script::Nag_Mundari => \"Nagm\",\n            Script::Nandinagari => \"Nand\",\n            Script::Old_North_Arabian => \"Narb\",\n            Script::Nabataean => \"Nbat\",\n            Script::Newa => \"Newa\",\n            Script::Nko => \"Nkoo\",\n            Script::Nushu => \"Nshu\",\n            Script::Ogham => \"Ogam\",\n            Script::Ol_Chiki => \"Olck\",\n            Script::Ol_Onal => \"Onao\",\n            Script::Old_Turkic => \"Orkh\",\n            Script::Oriya => \"Orya\",\n            Script::Osage => \"Osge\",\n            Script::Osmanya => \"Osma\",\n            Script::Old_Uyghur => \"Ougr\",\n            Script::Palmyrene => \"Palm\",\n            Script::Pau_Cin_Hau => \"Pauc\",\n            Script::Old_Permic => \"Perm\",\n            Script::Phags_Pa => \"Phag\",\n            Script::Inscriptional_Pahlavi => \"Phli\",\n            Script::Psalter_Pahlavi => \"Phlp\",\n            Script::Phoenician => \"Phnx\",\n            Script::Miao => \"Plrd\",\n            Script::Inscriptional_Parthian => \"Prti\",\n            Script::Rejang => \"Rjng\",\n            Script::Hanifi_Rohingya => \"Rohg\",\n            Script::Runic => \"Runr\",\n            Script::Samaritan => \"Samr\",\n            Script::Old_South_Arabian => \"Sarb\",\n            Script::Saurashtra => \"Saur\",\n            Script::SignWriting => \"Sgnw\",\n            Script::Shavian => \"Shaw\",\n            Script::Sharada => \"Shrd\",\n            Script::Siddham => \"Sidd\",\n            Script::Sidetic => \"Sidt\",\n            Script::Khudawadi => \"Sind\",\n            Script::Sinhala => \"Sinh\",\n            Script::Sogdian => \"Sogd\",\n            Script::Old_Sogdian => \"Sogo\",\n            Script::Sora_Sompeng => \"Sora\",\n            Script::Soyombo => \"Soyo\",\n            Script::Sundanese => \"Sund\",\n            Script::Sunuwar => \"Sunu\",\n            Script::Syloti_Nagri => \"Sylo\",\n            Script::Syriac => \"Syrc\",\n            Script::Tagbanwa => \"Tagb\",\n            Script::Takri => \"Takr\",\n            Script::Tai_Le => \"Tale\",\n            Script::New_Tai_Lue => \"Talu\",\n            Script::Tamil => \"Taml\",\n            Script::Tangut => \"Tang\",\n            Script::Tai_Viet => \"Tavt\",\n            Script::Tai_Yo => \"Tayo\",\n            Script::Telugu => \"Telu\",\n            Script::Tifinagh => \"Tfng\",\n            Script::Tagalog => \"Tglg\",\n            Script::Thaana => \"Thaa\",\n            Script::Thai => \"Thai\",\n            Script::Tibetan => \"Tibt\",\n            Script::Tirhuta => \"Tirh\",\n            Script::Tangsa => \"Tnsa\",\n            Script::Todhri => \"Todr\",\n            Script::Tolong_Siki => \"Tols\",\n            Script::Toto => \"Toto\",\n            Script::Tulu_Tigalari => \"Tutg\",\n            Script::Ugaritic => \"Ugar\",\n            Script::Vai => \"Vaii\",\n            Script::Vithkuqi => \"Vith\",\n            Script::Warang_Citi => \"Wara\",\n            Script::Wancho => \"Wcho\",\n            Script::Old_Persian => \"Xpeo\",\n            Script::Cuneiform => \"Xsux\",\n            Script::Yezidi => \"Yezi\",\n            Script::Yi => \"Yiii\",\n            Script::Zanabazar_Square => \"Zanb\",\n        }\n    }\n\n    #[inline]\n    pub(crate) fn inner_from_short_name(input: &str) -> Option<Self> {\n        match input {\n            \"Zzzz\" => Some(Script::Unknown),\n            \"Zyyy\" => Some(Script::Common),\n            \"Zinh\" => Some(Script::Inherited),\n            \"Adlm\" => Some(Script::Adlam),\n            \"Aghb\" => Some(Script::Caucasian_Albanian),\n            \"Ahom\" => Some(Script::Ahom),\n            \"Arab\" => Some(Script::Arabic),\n            \"Armi\" => Some(Script::Imperial_Aramaic),\n            \"Armn\" => Some(Script::Armenian),\n            \"Avst\" => Some(Script::Avestan),\n            \"Bali\" => Some(Script::Balinese),\n            \"Bamu\" => Some(Script::Bamum),\n            \"Bass\" => Some(Script::Bassa_Vah),\n            \"Batk\" => Some(Script::Batak),\n            \"Beng\" => Some(Script::Bengali),\n            \"Berf\" => Some(Script::Beria_Erfe),\n            \"Bhks\" => Some(Script::Bhaiksuki),\n            \"Bopo\" => Some(Script::Bopomofo),\n            \"Brah\" => Some(Script::Brahmi),\n            \"Brai\" => Some(Script::Braille),\n            \"Bugi\" => Some(Script::Buginese),\n            \"Buhd\" => Some(Script::Buhid),\n            \"Cakm\" => Some(Script::Chakma),\n            \"Cans\" => Some(Script::Canadian_Aboriginal),\n            \"Cari\" => Some(Script::Carian),\n            \"Cham\" => Some(Script::Cham),\n            \"Cher\" => Some(Script::Cherokee),\n            \"Chrs\" => Some(Script::Chorasmian),\n            \"Copt\" => Some(Script::Coptic),\n            \"Cpmn\" => Some(Script::Cypro_Minoan),\n            \"Cprt\" => Some(Script::Cypriot),\n            \"Cyrl\" => Some(Script::Cyrillic),\n            \"Deva\" => Some(Script::Devanagari),\n            \"Diak\" => Some(Script::Dives_Akuru),\n            \"Dogr\" => Some(Script::Dogra),\n            \"Dsrt\" => Some(Script::Deseret),\n            \"Dupl\" => Some(Script::Duployan),\n            \"Egyp\" => Some(Script::Egyptian_Hieroglyphs),\n            \"Elba\" => Some(Script::Elbasan),\n            \"Elym\" => Some(Script::Elymaic),\n            \"Ethi\" => Some(Script::Ethiopic),\n            \"Gara\" => Some(Script::Garay),\n            \"Geor\" => Some(Script::Georgian),\n            \"Glag\" => Some(Script::Glagolitic),\n            \"Gong\" => Some(Script::Gunjala_Gondi),\n            \"Gonm\" => Some(Script::Masaram_Gondi),\n            \"Goth\" => Some(Script::Gothic),\n            \"Gran\" => Some(Script::Grantha),\n            \"Grek\" => Some(Script::Greek),\n            \"Gujr\" => Some(Script::Gujarati),\n            \"Gukh\" => Some(Script::Gurung_Khema),\n            \"Guru\" => Some(Script::Gurmukhi),\n            \"Hang\" => Some(Script::Hangul),\n            \"Hani\" => Some(Script::Han),\n            \"Hano\" => Some(Script::Hanunoo),\n            \"Hatr\" => Some(Script::Hatran),\n            \"Hebr\" => Some(Script::Hebrew),\n            \"Hira\" => Some(Script::Hiragana),\n            \"Hluw\" => Some(Script::Anatolian_Hieroglyphs),\n            \"Hmng\" => Some(Script::Pahawh_Hmong),\n            \"Hmnp\" => Some(Script::Nyiakeng_Puachue_Hmong),\n            \"Hung\" => Some(Script::Old_Hungarian),\n            \"Ital\" => Some(Script::Old_Italic),\n            \"Java\" => Some(Script::Javanese),\n            \"Kali\" => Some(Script::Kayah_Li),\n            \"Kana\" => Some(Script::Katakana),\n            \"Kawi\" => Some(Script::Kawi),\n            \"Khar\" => Some(Script::Kharoshthi),\n            \"Khmr\" => Some(Script::Khmer),\n            \"Khoj\" => Some(Script::Khojki),\n            \"Kits\" => Some(Script::Khitan_Small_Script),\n            \"Knda\" => Some(Script::Kannada),\n            \"Krai\" => Some(Script::Kirat_Rai),\n            \"Kthi\" => Some(Script::Kaithi),\n            \"Lana\" => Some(Script::Tai_Tham),\n            \"Laoo\" => Some(Script::Lao),\n            \"Latn\" => Some(Script::Latin),\n            \"Lepc\" => Some(Script::Lepcha),\n            \"Limb\" => Some(Script::Limbu),\n            \"Lina\" => Some(Script::Linear_A),\n            \"Linb\" => Some(Script::Linear_B),\n            \"Lisu\" => Some(Script::Lisu),\n            \"Lyci\" => Some(Script::Lycian),\n            \"Lydi\" => Some(Script::Lydian),\n            \"Mahj\" => Some(Script::Mahajani),\n            \"Maka\" => Some(Script::Makasar),\n            \"Mand\" => Some(Script::Mandaic),\n            \"Mani\" => Some(Script::Manichaean),\n            \"Marc\" => Some(Script::Marchen),\n            \"Medf\" => Some(Script::Medefaidrin),\n            \"Mend\" => Some(Script::Mende_Kikakui),\n            \"Merc\" => Some(Script::Meroitic_Cursive),\n            \"Mero\" => Some(Script::Meroitic_Hieroglyphs),\n            \"Mlym\" => Some(Script::Malayalam),\n            \"Modi\" => Some(Script::Modi),\n            \"Mong\" => Some(Script::Mongolian),\n            \"Mroo\" => Some(Script::Mro),\n            \"Mtei\" => Some(Script::Meetei_Mayek),\n            \"Mult\" => Some(Script::Multani),\n            \"Mymr\" => Some(Script::Myanmar),\n            \"Nagm\" => Some(Script::Nag_Mundari),\n            \"Nand\" => Some(Script::Nandinagari),\n            \"Narb\" => Some(Script::Old_North_Arabian),\n            \"Nbat\" => Some(Script::Nabataean),\n            \"Newa\" => Some(Script::Newa),\n            \"Nkoo\" => Some(Script::Nko),\n            \"Nshu\" => Some(Script::Nushu),\n            \"Ogam\" => Some(Script::Ogham),\n            \"Olck\" => Some(Script::Ol_Chiki),\n            \"Onao\" => Some(Script::Ol_Onal),\n            \"Orkh\" => Some(Script::Old_Turkic),\n            \"Orya\" => Some(Script::Oriya),\n            \"Osge\" => Some(Script::Osage),\n            \"Osma\" => Some(Script::Osmanya),\n            \"Ougr\" => Some(Script::Old_Uyghur),\n            \"Palm\" => Some(Script::Palmyrene),\n            \"Pauc\" => Some(Script::Pau_Cin_Hau),\n            \"Perm\" => Some(Script::Old_Permic),\n            \"Phag\" => Some(Script::Phags_Pa),\n            \"Phli\" => Some(Script::Inscriptional_Pahlavi),\n            \"Phlp\" => Some(Script::Psalter_Pahlavi),\n            \"Phnx\" => Some(Script::Phoenician),\n            \"Plrd\" => Some(Script::Miao),\n            \"Prti\" => Some(Script::Inscriptional_Parthian),\n            \"Rjng\" => Some(Script::Rejang),\n            \"Rohg\" => Some(Script::Hanifi_Rohingya),\n            \"Runr\" => Some(Script::Runic),\n            \"Samr\" => Some(Script::Samaritan),\n            \"Sarb\" => Some(Script::Old_South_Arabian),\n            \"Saur\" => Some(Script::Saurashtra),\n            \"Sgnw\" => Some(Script::SignWriting),\n            \"Shaw\" => Some(Script::Shavian),\n            \"Shrd\" => Some(Script::Sharada),\n            \"Sidd\" => Some(Script::Siddham),\n            \"Sidt\" => Some(Script::Sidetic),\n            \"Sind\" => Some(Script::Khudawadi),\n            \"Sinh\" => Some(Script::Sinhala),\n            \"Sogd\" => Some(Script::Sogdian),\n            \"Sogo\" => Some(Script::Old_Sogdian),\n            \"Sora\" => Some(Script::Sora_Sompeng),\n            \"Soyo\" => Some(Script::Soyombo),\n            \"Sund\" => Some(Script::Sundanese),\n            \"Sunu\" => Some(Script::Sunuwar),\n            \"Sylo\" => Some(Script::Syloti_Nagri),\n            \"Syrc\" => Some(Script::Syriac),\n            \"Tagb\" => Some(Script::Tagbanwa),\n            \"Takr\" => Some(Script::Takri),\n            \"Tale\" => Some(Script::Tai_Le),\n            \"Talu\" => Some(Script::New_Tai_Lue),\n            \"Taml\" => Some(Script::Tamil),\n            \"Tang\" => Some(Script::Tangut),\n            \"Tavt\" => Some(Script::Tai_Viet),\n            \"Tayo\" => Some(Script::Tai_Yo),\n            \"Telu\" => Some(Script::Telugu),\n            \"Tfng\" => Some(Script::Tifinagh),\n            \"Tglg\" => Some(Script::Tagalog),\n            \"Thaa\" => Some(Script::Thaana),\n            \"Thai\" => Some(Script::Thai),\n            \"Tibt\" => Some(Script::Tibetan),\n            \"Tirh\" => Some(Script::Tirhuta),\n            \"Tnsa\" => Some(Script::Tangsa),\n            \"Todr\" => Some(Script::Todhri),\n            \"Tols\" => Some(Script::Tolong_Siki),\n            \"Toto\" => Some(Script::Toto),\n            \"Tutg\" => Some(Script::Tulu_Tigalari),\n            \"Ugar\" => Some(Script::Ugaritic),\n            \"Vaii\" => Some(Script::Vai),\n            \"Vith\" => Some(Script::Vithkuqi),\n            \"Wara\" => Some(Script::Warang_Citi),\n            \"Wcho\" => Some(Script::Wancho),\n            \"Xpeo\" => Some(Script::Old_Persian),\n            \"Xsux\" => Some(Script::Cuneiform),\n            \"Yezi\" => Some(Script::Yezidi),\n            \"Yiii\" => Some(Script::Yi),\n            \"Zanb\" => Some(Script::Zanabazar_Square),\n        _ => None,\n        }\n    }\n\n    #[inline]\n    pub(crate) fn for_integer(value: u8) -> Self {\n        match value {\n            0 => Script::Adlam,\n            1 => Script::Caucasian_Albanian,\n            2 => Script::Ahom,\n            3 => Script::Arabic,\n            4 => Script::Imperial_Aramaic,\n            5 => Script::Armenian,\n            6 => Script::Avestan,\n            7 => Script::Balinese,\n            8 => Script::Bamum,\n            9 => Script::Bassa_Vah,\n            10 => Script::Batak,\n            11 => Script::Bengali,\n            12 => Script::Beria_Erfe,\n            13 => Script::Bhaiksuki,\n            14 => Script::Bopomofo,\n            15 => Script::Brahmi,\n            16 => Script::Braille,\n            17 => Script::Buginese,\n            18 => Script::Buhid,\n            19 => Script::Chakma,\n            20 => Script::Canadian_Aboriginal,\n            21 => Script::Carian,\n            22 => Script::Cham,\n            23 => Script::Cherokee,\n            24 => Script::Chorasmian,\n            25 => Script::Coptic,\n            26 => Script::Cypro_Minoan,\n            27 => Script::Cypriot,\n            28 => Script::Cyrillic,\n            29 => Script::Devanagari,\n            30 => Script::Dives_Akuru,\n            31 => Script::Dogra,\n            32 => Script::Deseret,\n            33 => Script::Duployan,\n            34 => Script::Egyptian_Hieroglyphs,\n            35 => Script::Elbasan,\n            36 => Script::Elymaic,\n            37 => Script::Ethiopic,\n            38 => Script::Garay,\n            39 => Script::Georgian,\n            40 => Script::Glagolitic,\n            41 => Script::Gunjala_Gondi,\n            42 => Script::Masaram_Gondi,\n            43 => Script::Gothic,\n            44 => Script::Grantha,\n            45 => Script::Greek,\n            46 => Script::Gujarati,\n            47 => Script::Gurung_Khema,\n            48 => Script::Gurmukhi,\n            49 => Script::Hangul,\n            50 => Script::Han,\n            51 => Script::Hanunoo,\n            52 => Script::Hatran,\n            53 => Script::Hebrew,\n            54 => Script::Hiragana,\n            55 => Script::Anatolian_Hieroglyphs,\n            56 => Script::Pahawh_Hmong,\n            57 => Script::Nyiakeng_Puachue_Hmong,\n            58 => Script::Old_Hungarian,\n            59 => Script::Old_Italic,\n            60 => Script::Javanese,\n            61 => Script::Kayah_Li,\n            62 => Script::Katakana,\n            63 => Script::Kawi,\n            64 => Script::Kharoshthi,\n            65 => Script::Khmer,\n            66 => Script::Khojki,\n            67 => Script::Khitan_Small_Script,\n            68 => Script::Kannada,\n            69 => Script::Kirat_Rai,\n            70 => Script::Kaithi,\n            71 => Script::Tai_Tham,\n            72 => Script::Lao,\n            73 => Script::Latin,\n            74 => Script::Lepcha,\n            75 => Script::Limbu,\n            76 => Script::Linear_A,\n            77 => Script::Linear_B,\n            78 => Script::Lisu,\n            79 => Script::Lycian,\n            80 => Script::Lydian,\n            81 => Script::Mahajani,\n            82 => Script::Makasar,\n            83 => Script::Mandaic,\n            84 => Script::Manichaean,\n            85 => Script::Marchen,\n            86 => Script::Medefaidrin,\n            87 => Script::Mende_Kikakui,\n            88 => Script::Meroitic_Cursive,\n            89 => Script::Meroitic_Hieroglyphs,\n            90 => Script::Malayalam,\n            91 => Script::Modi,\n            92 => Script::Mongolian,\n            93 => Script::Mro,\n            94 => Script::Meetei_Mayek,\n            95 => Script::Multani,\n            96 => Script::Myanmar,\n            97 => Script::Nag_Mundari,\n            98 => Script::Nandinagari,\n            99 => Script::Old_North_Arabian,\n            100 => Script::Nabataean,\n            101 => Script::Newa,\n            102 => Script::Nko,\n            103 => Script::Nushu,\n            104 => Script::Ogham,\n            105 => Script::Ol_Chiki,\n            106 => Script::Ol_Onal,\n            107 => Script::Old_Turkic,\n            108 => Script::Oriya,\n            109 => Script::Osage,\n            110 => Script::Osmanya,\n            111 => Script::Old_Uyghur,\n            112 => Script::Palmyrene,\n            113 => Script::Pau_Cin_Hau,\n            114 => Script::Old_Permic,\n            115 => Script::Phags_Pa,\n            116 => Script::Inscriptional_Pahlavi,\n            117 => Script::Psalter_Pahlavi,\n            118 => Script::Phoenician,\n            119 => Script::Miao,\n            120 => Script::Inscriptional_Parthian,\n            121 => Script::Rejang,\n            122 => Script::Hanifi_Rohingya,\n            123 => Script::Runic,\n            124 => Script::Samaritan,\n            125 => Script::Old_South_Arabian,\n            126 => Script::Saurashtra,\n            127 => Script::SignWriting,\n            128 => Script::Shavian,\n            129 => Script::Sharada,\n            130 => Script::Siddham,\n            131 => Script::Sidetic,\n            132 => Script::Khudawadi,\n            133 => Script::Sinhala,\n            134 => Script::Sogdian,\n            135 => Script::Old_Sogdian,\n            136 => Script::Sora_Sompeng,\n            137 => Script::Soyombo,\n            138 => Script::Sundanese,\n            139 => Script::Sunuwar,\n            140 => Script::Syloti_Nagri,\n            141 => Script::Syriac,\n            142 => Script::Tagbanwa,\n            143 => Script::Takri,\n            144 => Script::Tai_Le,\n            145 => Script::New_Tai_Lue,\n            146 => Script::Tamil,\n            147 => Script::Tangut,\n            148 => Script::Tai_Viet,\n            149 => Script::Tai_Yo,\n            150 => Script::Telugu,\n            151 => Script::Tifinagh,\n            152 => Script::Tagalog,\n            153 => Script::Thaana,\n            154 => Script::Thai,\n            155 => Script::Tibetan,\n            156 => Script::Tirhuta,\n            157 => Script::Tangsa,\n            158 => Script::Todhri,\n            159 => Script::Tolong_Siki,\n            160 => Script::Toto,\n            161 => Script::Tulu_Tigalari,\n            162 => Script::Ugaritic,\n            163 => Script::Vai,\n            164 => Script::Vithkuqi,\n            165 => Script::Warang_Citi,\n            166 => Script::Wancho,\n            167 => Script::Old_Persian,\n            168 => Script::Cuneiform,\n            169 => Script::Yezidi,\n            170 => Script::Yi,\n            171 => Script::Zanabazar_Square,\n            _ => unreachable!(),\n        }\n    }\n\n}\n\npub fn bsearch_range_value_table<T: Copy>(c: char, r: &'static [(char, char, T)]) -> Option<T> {\n    use core::cmp::Ordering::{Equal, Less, Greater};\n    match r.binary_search_by(|&(lo, hi, _)| {\n        if lo <= c && c <= hi { Equal }\n        else if hi < c { Less }\n        else { Greater }\n    }) {\n        Ok(idx) => {\n            let (_, _, cat) = r[idx];\n            Some(cat)\n        }\n        Err(_) => None\n    }\n}\n\n#[inline]\npub fn get_script(c: char) -> Option<Script> {\n    bsearch_range_value_table(c, SCRIPTS)\n}\n\n#[inline]\npub fn get_script_extension(c: char) -> Option<ScriptExtension> {\n    bsearch_range_value_table(c, SCRIPT_EXTENSIONS)\n}\n    const SCRIPTS: &'static [(char, char, Script)] = &[\n        ('\\u{0}', '\\u{1f}',  Script::Common), ('\\u{20}', '\\u{20}',  Script::Common), ('\\u{21}',\n        '\\u{23}',  Script::Common), ('\\u{24}', '\\u{24}',  Script::Common), ('\\u{25}', '\\u{27}',\n         Script::Common), ('\\u{28}', '\\u{28}',  Script::Common), ('\\u{29}', '\\u{29}',\n         Script::Common), ('\\u{2a}', '\\u{2a}',  Script::Common), ('\\u{2b}', '\\u{2b}',\n         Script::Common), ('\\u{2c}', '\\u{2c}',  Script::Common), ('\\u{2d}', '\\u{2d}',\n         Script::Common), ('\\u{2e}', '\\u{2f}',  Script::Common), ('\\u{30}', '\\u{39}',\n         Script::Common), ('\\u{3a}', '\\u{3b}',  Script::Common), ('\\u{3c}', '\\u{3e}',\n         Script::Common), ('\\u{3f}', '\\u{40}',  Script::Common), ('\\u{41}', '\\u{5a}',\n         Script::Latin), ('\\u{5b}', '\\u{5b}',  Script::Common), ('\\u{5c}', '\\u{5c}',\n         Script::Common), ('\\u{5d}', '\\u{5d}',  Script::Common), ('\\u{5e}', '\\u{5e}',\n         Script::Common), ('\\u{5f}', '\\u{5f}',  Script::Common), ('\\u{60}', '\\u{60}',\n         Script::Common), ('\\u{61}', '\\u{7a}',  Script::Latin), ('\\u{7b}', '\\u{7b}',\n         Script::Common), ('\\u{7c}', '\\u{7c}',  Script::Common), ('\\u{7d}', '\\u{7d}',\n         Script::Common), ('\\u{7e}', '\\u{7e}',  Script::Common), ('\\u{7f}', '\\u{9f}',\n         Script::Common), ('\\u{a0}', '\\u{a0}',  Script::Common), ('\\u{a1}', '\\u{a1}',\n         Script::Common), ('\\u{a2}', '\\u{a5}',  Script::Common), ('\\u{a6}', '\\u{a6}',\n         Script::Common), ('\\u{a7}', '\\u{a7}',  Script::Common), ('\\u{a8}', '\\u{a8}',\n         Script::Common), ('\\u{a9}', '\\u{a9}',  Script::Common), ('\\u{aa}', '\\u{aa}',\n         Script::Latin), ('\\u{ab}', '\\u{ab}',  Script::Common), ('\\u{ac}', '\\u{ac}',\n         Script::Common), ('\\u{ad}', '\\u{ad}',  Script::Common), ('\\u{ae}', '\\u{ae}',\n         Script::Common), ('\\u{af}', '\\u{af}',  Script::Common), ('\\u{b0}', '\\u{b0}',\n         Script::Common), ('\\u{b1}', '\\u{b1}',  Script::Common), ('\\u{b2}', '\\u{b3}',\n         Script::Common), ('\\u{b4}', '\\u{b4}',  Script::Common), ('\\u{b5}', '\\u{b5}',\n         Script::Common), ('\\u{b6}', '\\u{b7}',  Script::Common), ('\\u{b8}', '\\u{b8}',\n         Script::Common), ('\\u{b9}', '\\u{b9}',  Script::Common), ('\\u{ba}', '\\u{ba}',\n         Script::Latin), ('\\u{bb}', '\\u{bb}',  Script::Common), ('\\u{bc}', '\\u{be}',\n         Script::Common), ('\\u{bf}', '\\u{bf}',  Script::Common), ('\\u{c0}', '\\u{d6}',\n         Script::Latin), ('\\u{d7}', '\\u{d7}',  Script::Common), ('\\u{d8}', '\\u{f6}',\n         Script::Latin), ('\\u{f7}', '\\u{f7}',  Script::Common), ('\\u{f8}', '\\u{1ba}',\n         Script::Latin), ('\\u{1bb}', '\\u{1bb}',  Script::Latin), ('\\u{1bc}', '\\u{1bf}',\n         Script::Latin), ('\\u{1c0}', '\\u{1c3}',  Script::Latin), ('\\u{1c4}', '\\u{293}',\n         Script::Latin), ('\\u{294}', '\\u{295}',  Script::Latin), ('\\u{296}', '\\u{2af}',\n         Script::Latin), ('\\u{2b0}', '\\u{2b8}',  Script::Latin), ('\\u{2b9}', '\\u{2c1}',\n         Script::Common), ('\\u{2c2}', '\\u{2c5}',  Script::Common), ('\\u{2c6}', '\\u{2d1}',\n         Script::Common), ('\\u{2d2}', '\\u{2df}',  Script::Common), ('\\u{2e0}', '\\u{2e4}',\n         Script::Latin), ('\\u{2e5}', '\\u{2e9}',  Script::Common), ('\\u{2ea}', '\\u{2eb}',\n         Script::Bopomofo), ('\\u{2ec}', '\\u{2ec}',  Script::Common), ('\\u{2ed}', '\\u{2ed}',\n         Script::Common), ('\\u{2ee}', '\\u{2ee}',  Script::Common), ('\\u{2ef}', '\\u{2ff}',\n         Script::Common), ('\\u{300}', '\\u{36f}',  Script::Inherited), ('\\u{370}', '\\u{373}',\n         Script::Greek), ('\\u{374}', '\\u{374}',  Script::Common), ('\\u{375}', '\\u{375}',\n         Script::Greek), ('\\u{376}', '\\u{377}',  Script::Greek), ('\\u{37a}', '\\u{37a}',\n         Script::Greek), ('\\u{37b}', '\\u{37d}',  Script::Greek), ('\\u{37e}', '\\u{37e}',\n         Script::Common), ('\\u{37f}', '\\u{37f}',  Script::Greek), ('\\u{384}', '\\u{384}',\n         Script::Greek), ('\\u{385}', '\\u{385}',  Script::Common), ('\\u{386}', '\\u{386}',\n         Script::Greek), ('\\u{387}', '\\u{387}',  Script::Common), ('\\u{388}', '\\u{38a}',\n         Script::Greek), ('\\u{38c}', '\\u{38c}',  Script::Greek), ('\\u{38e}', '\\u{3a1}',\n         Script::Greek), ('\\u{3a3}', '\\u{3e1}',  Script::Greek), ('\\u{3e2}', '\\u{3ef}',\n         Script::Coptic), ('\\u{3f0}', '\\u{3f5}',  Script::Greek), ('\\u{3f6}', '\\u{3f6}',\n         Script::Greek), ('\\u{3f7}', '\\u{3ff}',  Script::Greek), ('\\u{400}', '\\u{481}',\n         Script::Cyrillic), ('\\u{482}', '\\u{482}',  Script::Cyrillic), ('\\u{483}', '\\u{484}',\n         Script::Cyrillic), ('\\u{485}', '\\u{486}',  Script::Inherited), ('\\u{487}', '\\u{487}',\n         Script::Cyrillic), ('\\u{488}', '\\u{489}',  Script::Cyrillic), ('\\u{48a}', '\\u{52f}',\n         Script::Cyrillic), ('\\u{531}', '\\u{556}',  Script::Armenian), ('\\u{559}', '\\u{559}',\n         Script::Armenian), ('\\u{55a}', '\\u{55f}',  Script::Armenian), ('\\u{560}', '\\u{588}',\n         Script::Armenian), ('\\u{589}', '\\u{589}',  Script::Armenian), ('\\u{58a}', '\\u{58a}',\n         Script::Armenian), ('\\u{58d}', '\\u{58e}',  Script::Armenian), ('\\u{58f}', '\\u{58f}',\n         Script::Armenian), ('\\u{591}', '\\u{5bd}',  Script::Hebrew), ('\\u{5be}', '\\u{5be}',\n         Script::Hebrew), ('\\u{5bf}', '\\u{5bf}',  Script::Hebrew), ('\\u{5c0}', '\\u{5c0}',\n         Script::Hebrew), ('\\u{5c1}', '\\u{5c2}',  Script::Hebrew), ('\\u{5c3}', '\\u{5c3}',\n         Script::Hebrew), ('\\u{5c4}', '\\u{5c5}',  Script::Hebrew), ('\\u{5c6}', '\\u{5c6}',\n         Script::Hebrew), ('\\u{5c7}', '\\u{5c7}',  Script::Hebrew), ('\\u{5d0}', '\\u{5ea}',\n         Script::Hebrew), ('\\u{5ef}', '\\u{5f2}',  Script::Hebrew), ('\\u{5f3}', '\\u{5f4}',\n         Script::Hebrew), ('\\u{600}', '\\u{604}',  Script::Arabic), ('\\u{605}', '\\u{605}',\n         Script::Common), ('\\u{606}', '\\u{608}',  Script::Arabic), ('\\u{609}', '\\u{60a}',\n         Script::Arabic), ('\\u{60b}', '\\u{60b}',  Script::Arabic), ('\\u{60c}', '\\u{60c}',\n         Script::Common), ('\\u{60d}', '\\u{60d}',  Script::Arabic), ('\\u{60e}', '\\u{60f}',\n         Script::Arabic), ('\\u{610}', '\\u{61a}',  Script::Arabic), ('\\u{61b}', '\\u{61b}',\n         Script::Common), ('\\u{61c}', '\\u{61c}',  Script::Arabic), ('\\u{61d}', '\\u{61e}',\n         Script::Arabic), ('\\u{61f}', '\\u{61f}',  Script::Common), ('\\u{620}', '\\u{63f}',\n         Script::Arabic), ('\\u{640}', '\\u{640}',  Script::Common), ('\\u{641}', '\\u{64a}',\n         Script::Arabic), ('\\u{64b}', '\\u{655}',  Script::Inherited), ('\\u{656}', '\\u{65f}',\n         Script::Arabic), ('\\u{660}', '\\u{669}',  Script::Arabic), ('\\u{66a}', '\\u{66d}',\n         Script::Arabic), ('\\u{66e}', '\\u{66f}',  Script::Arabic), ('\\u{670}', '\\u{670}',\n         Script::Inherited), ('\\u{671}', '\\u{6d3}',  Script::Arabic), ('\\u{6d4}', '\\u{6d4}',\n         Script::Arabic), ('\\u{6d5}', '\\u{6d5}',  Script::Arabic), ('\\u{6d6}', '\\u{6dc}',\n         Script::Arabic), ('\\u{6dd}', '\\u{6dd}',  Script::Common), ('\\u{6de}', '\\u{6de}',\n         Script::Arabic), ('\\u{6df}', '\\u{6e4}',  Script::Arabic), ('\\u{6e5}', '\\u{6e6}',\n         Script::Arabic), ('\\u{6e7}', '\\u{6e8}',  Script::Arabic), ('\\u{6e9}', '\\u{6e9}',\n         Script::Arabic), ('\\u{6ea}', '\\u{6ed}',  Script::Arabic), ('\\u{6ee}', '\\u{6ef}',\n         Script::Arabic), ('\\u{6f0}', '\\u{6f9}',  Script::Arabic), ('\\u{6fa}', '\\u{6fc}',\n         Script::Arabic), ('\\u{6fd}', '\\u{6fe}',  Script::Arabic), ('\\u{6ff}', '\\u{6ff}',\n         Script::Arabic), ('\\u{700}', '\\u{70d}',  Script::Syriac), ('\\u{70f}', '\\u{70f}',\n         Script::Syriac), ('\\u{710}', '\\u{710}',  Script::Syriac), ('\\u{711}', '\\u{711}',\n         Script::Syriac), ('\\u{712}', '\\u{72f}',  Script::Syriac), ('\\u{730}', '\\u{74a}',\n         Script::Syriac), ('\\u{74d}', '\\u{74f}',  Script::Syriac), ('\\u{750}', '\\u{77f}',\n         Script::Arabic), ('\\u{780}', '\\u{7a5}',  Script::Thaana), ('\\u{7a6}', '\\u{7b0}',\n         Script::Thaana), ('\\u{7b1}', '\\u{7b1}',  Script::Thaana), ('\\u{7c0}', '\\u{7c9}',\n         Script::Nko), ('\\u{7ca}', '\\u{7ea}',  Script::Nko), ('\\u{7eb}', '\\u{7f3}',  Script::Nko),\n        ('\\u{7f4}', '\\u{7f5}',  Script::Nko), ('\\u{7f6}', '\\u{7f6}',  Script::Nko), ('\\u{7f7}',\n        '\\u{7f9}',  Script::Nko), ('\\u{7fa}', '\\u{7fa}',  Script::Nko), ('\\u{7fd}', '\\u{7fd}',\n         Script::Nko), ('\\u{7fe}', '\\u{7ff}',  Script::Nko), ('\\u{800}', '\\u{815}',\n         Script::Samaritan), ('\\u{816}', '\\u{819}',  Script::Samaritan), ('\\u{81a}', '\\u{81a}',\n         Script::Samaritan), ('\\u{81b}', '\\u{823}',  Script::Samaritan), ('\\u{824}', '\\u{824}',\n         Script::Samaritan), ('\\u{825}', '\\u{827}',  Script::Samaritan), ('\\u{828}', '\\u{828}',\n         Script::Samaritan), ('\\u{829}', '\\u{82d}',  Script::Samaritan), ('\\u{830}', '\\u{83e}',\n         Script::Samaritan), ('\\u{840}', '\\u{858}',  Script::Mandaic), ('\\u{859}', '\\u{85b}',\n         Script::Mandaic), ('\\u{85e}', '\\u{85e}',  Script::Mandaic), ('\\u{860}', '\\u{86a}',\n         Script::Syriac), ('\\u{870}', '\\u{887}',  Script::Arabic), ('\\u{888}', '\\u{888}',\n         Script::Arabic), ('\\u{889}', '\\u{88f}',  Script::Arabic), ('\\u{890}', '\\u{891}',\n         Script::Arabic), ('\\u{897}', '\\u{89f}',  Script::Arabic), ('\\u{8a0}', '\\u{8c8}',\n         Script::Arabic), ('\\u{8c9}', '\\u{8c9}',  Script::Arabic), ('\\u{8ca}', '\\u{8e1}',\n         Script::Arabic), ('\\u{8e2}', '\\u{8e2}',  Script::Common), ('\\u{8e3}', '\\u{8ff}',\n         Script::Arabic), ('\\u{900}', '\\u{902}',  Script::Devanagari), ('\\u{903}', '\\u{903}',\n         Script::Devanagari), ('\\u{904}', '\\u{939}',  Script::Devanagari), ('\\u{93a}', '\\u{93a}',\n         Script::Devanagari), ('\\u{93b}', '\\u{93b}',  Script::Devanagari), ('\\u{93c}', '\\u{93c}',\n         Script::Devanagari), ('\\u{93d}', '\\u{93d}',  Script::Devanagari), ('\\u{93e}', '\\u{940}',\n         Script::Devanagari), ('\\u{941}', '\\u{948}',  Script::Devanagari), ('\\u{949}', '\\u{94c}',\n         Script::Devanagari), ('\\u{94d}', '\\u{94d}',  Script::Devanagari), ('\\u{94e}', '\\u{94f}',\n         Script::Devanagari), ('\\u{950}', '\\u{950}',  Script::Devanagari), ('\\u{951}', '\\u{954}',\n         Script::Inherited), ('\\u{955}', '\\u{957}',  Script::Devanagari), ('\\u{958}', '\\u{961}',\n         Script::Devanagari), ('\\u{962}', '\\u{963}',  Script::Devanagari), ('\\u{964}', '\\u{965}',\n         Script::Common), ('\\u{966}', '\\u{96f}',  Script::Devanagari), ('\\u{970}', '\\u{970}',\n         Script::Devanagari), ('\\u{971}', '\\u{971}',  Script::Devanagari), ('\\u{972}', '\\u{97f}',\n         Script::Devanagari), ('\\u{980}', '\\u{980}',  Script::Bengali), ('\\u{981}', '\\u{981}',\n         Script::Bengali), ('\\u{982}', '\\u{983}',  Script::Bengali), ('\\u{985}', '\\u{98c}',\n         Script::Bengali), ('\\u{98f}', '\\u{990}',  Script::Bengali), ('\\u{993}', '\\u{9a8}',\n         Script::Bengali), ('\\u{9aa}', '\\u{9b0}',  Script::Bengali), ('\\u{9b2}', '\\u{9b2}',\n         Script::Bengali), ('\\u{9b6}', '\\u{9b9}',  Script::Bengali), ('\\u{9bc}', '\\u{9bc}',\n         Script::Bengali), ('\\u{9bd}', '\\u{9bd}',  Script::Bengali), ('\\u{9be}', '\\u{9c0}',\n         Script::Bengali), ('\\u{9c1}', '\\u{9c4}',  Script::Bengali), ('\\u{9c7}', '\\u{9c8}',\n         Script::Bengali), ('\\u{9cb}', '\\u{9cc}',  Script::Bengali), ('\\u{9cd}', '\\u{9cd}',\n         Script::Bengali), ('\\u{9ce}', '\\u{9ce}',  Script::Bengali), ('\\u{9d7}', '\\u{9d7}',\n         Script::Bengali), ('\\u{9dc}', '\\u{9dd}',  Script::Bengali), ('\\u{9df}', '\\u{9e1}',\n         Script::Bengali), ('\\u{9e2}', '\\u{9e3}',  Script::Bengali), ('\\u{9e6}', '\\u{9ef}',\n         Script::Bengali), ('\\u{9f0}', '\\u{9f1}',  Script::Bengali), ('\\u{9f2}', '\\u{9f3}',\n         Script::Bengali), ('\\u{9f4}', '\\u{9f9}',  Script::Bengali), ('\\u{9fa}', '\\u{9fa}',\n         Script::Bengali), ('\\u{9fb}', '\\u{9fb}',  Script::Bengali), ('\\u{9fc}', '\\u{9fc}',\n         Script::Bengali), ('\\u{9fd}', '\\u{9fd}',  Script::Bengali), ('\\u{9fe}', '\\u{9fe}',\n         Script::Bengali), ('\\u{a01}', '\\u{a02}',  Script::Gurmukhi), ('\\u{a03}', '\\u{a03}',\n         Script::Gurmukhi), ('\\u{a05}', '\\u{a0a}',  Script::Gurmukhi), ('\\u{a0f}', '\\u{a10}',\n         Script::Gurmukhi), ('\\u{a13}', '\\u{a28}',  Script::Gurmukhi), ('\\u{a2a}', '\\u{a30}',\n         Script::Gurmukhi), ('\\u{a32}', '\\u{a33}',  Script::Gurmukhi), ('\\u{a35}', '\\u{a36}',\n         Script::Gurmukhi), ('\\u{a38}', '\\u{a39}',  Script::Gurmukhi), ('\\u{a3c}', '\\u{a3c}',\n         Script::Gurmukhi), ('\\u{a3e}', '\\u{a40}',  Script::Gurmukhi), ('\\u{a41}', '\\u{a42}',\n         Script::Gurmukhi), ('\\u{a47}', '\\u{a48}',  Script::Gurmukhi), ('\\u{a4b}', '\\u{a4d}',\n         Script::Gurmukhi), ('\\u{a51}', '\\u{a51}',  Script::Gurmukhi), ('\\u{a59}', '\\u{a5c}',\n         Script::Gurmukhi), ('\\u{a5e}', '\\u{a5e}',  Script::Gurmukhi), ('\\u{a66}', '\\u{a6f}',\n         Script::Gurmukhi), ('\\u{a70}', '\\u{a71}',  Script::Gurmukhi), ('\\u{a72}', '\\u{a74}',\n         Script::Gurmukhi), ('\\u{a75}', '\\u{a75}',  Script::Gurmukhi), ('\\u{a76}', '\\u{a76}',\n         Script::Gurmukhi), ('\\u{a81}', '\\u{a82}',  Script::Gujarati), ('\\u{a83}', '\\u{a83}',\n         Script::Gujarati), ('\\u{a85}', '\\u{a8d}',  Script::Gujarati), ('\\u{a8f}', '\\u{a91}',\n         Script::Gujarati), ('\\u{a93}', '\\u{aa8}',  Script::Gujarati), ('\\u{aaa}', '\\u{ab0}',\n         Script::Gujarati), ('\\u{ab2}', '\\u{ab3}',  Script::Gujarati), ('\\u{ab5}', '\\u{ab9}',\n         Script::Gujarati), ('\\u{abc}', '\\u{abc}',  Script::Gujarati), ('\\u{abd}', '\\u{abd}',\n         Script::Gujarati), ('\\u{abe}', '\\u{ac0}',  Script::Gujarati), ('\\u{ac1}', '\\u{ac5}',\n         Script::Gujarati), ('\\u{ac7}', '\\u{ac8}',  Script::Gujarati), ('\\u{ac9}', '\\u{ac9}',\n         Script::Gujarati), ('\\u{acb}', '\\u{acc}',  Script::Gujarati), ('\\u{acd}', '\\u{acd}',\n         Script::Gujarati), ('\\u{ad0}', '\\u{ad0}',  Script::Gujarati), ('\\u{ae0}', '\\u{ae1}',\n         Script::Gujarati), ('\\u{ae2}', '\\u{ae3}',  Script::Gujarati), ('\\u{ae6}', '\\u{aef}',\n         Script::Gujarati), ('\\u{af0}', '\\u{af0}',  Script::Gujarati), ('\\u{af1}', '\\u{af1}',\n         Script::Gujarati), ('\\u{af9}', '\\u{af9}',  Script::Gujarati), ('\\u{afa}', '\\u{aff}',\n         Script::Gujarati), ('\\u{b01}', '\\u{b01}',  Script::Oriya), ('\\u{b02}', '\\u{b03}',\n         Script::Oriya), ('\\u{b05}', '\\u{b0c}',  Script::Oriya), ('\\u{b0f}', '\\u{b10}',\n         Script::Oriya), ('\\u{b13}', '\\u{b28}',  Script::Oriya), ('\\u{b2a}', '\\u{b30}',\n         Script::Oriya), ('\\u{b32}', '\\u{b33}',  Script::Oriya), ('\\u{b35}', '\\u{b39}',\n         Script::Oriya), ('\\u{b3c}', '\\u{b3c}',  Script::Oriya), ('\\u{b3d}', '\\u{b3d}',\n         Script::Oriya), ('\\u{b3e}', '\\u{b3e}',  Script::Oriya), ('\\u{b3f}', '\\u{b3f}',\n         Script::Oriya), ('\\u{b40}', '\\u{b40}',  Script::Oriya), ('\\u{b41}', '\\u{b44}',\n         Script::Oriya), ('\\u{b47}', '\\u{b48}',  Script::Oriya), ('\\u{b4b}', '\\u{b4c}',\n         Script::Oriya), ('\\u{b4d}', '\\u{b4d}',  Script::Oriya), ('\\u{b55}', '\\u{b56}',\n         Script::Oriya), ('\\u{b57}', '\\u{b57}',  Script::Oriya), ('\\u{b5c}', '\\u{b5d}',\n         Script::Oriya), ('\\u{b5f}', '\\u{b61}',  Script::Oriya), ('\\u{b62}', '\\u{b63}',\n         Script::Oriya), ('\\u{b66}', '\\u{b6f}',  Script::Oriya), ('\\u{b70}', '\\u{b70}',\n         Script::Oriya), ('\\u{b71}', '\\u{b71}',  Script::Oriya), ('\\u{b72}', '\\u{b77}',\n         Script::Oriya), ('\\u{b82}', '\\u{b82}',  Script::Tamil), ('\\u{b83}', '\\u{b83}',\n         Script::Tamil), ('\\u{b85}', '\\u{b8a}',  Script::Tamil), ('\\u{b8e}', '\\u{b90}',\n         Script::Tamil), ('\\u{b92}', '\\u{b95}',  Script::Tamil), ('\\u{b99}', '\\u{b9a}',\n         Script::Tamil), ('\\u{b9c}', '\\u{b9c}',  Script::Tamil), ('\\u{b9e}', '\\u{b9f}',\n         Script::Tamil), ('\\u{ba3}', '\\u{ba4}',  Script::Tamil), ('\\u{ba8}', '\\u{baa}',\n         Script::Tamil), ('\\u{bae}', '\\u{bb9}',  Script::Tamil), ('\\u{bbe}', '\\u{bbf}',\n         Script::Tamil), ('\\u{bc0}', '\\u{bc0}',  Script::Tamil), ('\\u{bc1}', '\\u{bc2}',\n         Script::Tamil), ('\\u{bc6}', '\\u{bc8}',  Script::Tamil), ('\\u{bca}', '\\u{bcc}',\n         Script::Tamil), ('\\u{bcd}', '\\u{bcd}',  Script::Tamil), ('\\u{bd0}', '\\u{bd0}',\n         Script::Tamil), ('\\u{bd7}', '\\u{bd7}',  Script::Tamil), ('\\u{be6}', '\\u{bef}',\n         Script::Tamil), ('\\u{bf0}', '\\u{bf2}',  Script::Tamil), ('\\u{bf3}', '\\u{bf8}',\n         Script::Tamil), ('\\u{bf9}', '\\u{bf9}',  Script::Tamil), ('\\u{bfa}', '\\u{bfa}',\n         Script::Tamil), ('\\u{c00}', '\\u{c00}',  Script::Telugu), ('\\u{c01}', '\\u{c03}',\n         Script::Telugu), ('\\u{c04}', '\\u{c04}',  Script::Telugu), ('\\u{c05}', '\\u{c0c}',\n         Script::Telugu), ('\\u{c0e}', '\\u{c10}',  Script::Telugu), ('\\u{c12}', '\\u{c28}',\n         Script::Telugu), ('\\u{c2a}', '\\u{c39}',  Script::Telugu), ('\\u{c3c}', '\\u{c3c}',\n         Script::Telugu), ('\\u{c3d}', '\\u{c3d}',  Script::Telugu), ('\\u{c3e}', '\\u{c40}',\n         Script::Telugu), ('\\u{c41}', '\\u{c44}',  Script::Telugu), ('\\u{c46}', '\\u{c48}',\n         Script::Telugu), ('\\u{c4a}', '\\u{c4d}',  Script::Telugu), ('\\u{c55}', '\\u{c56}',\n         Script::Telugu), ('\\u{c58}', '\\u{c5a}',  Script::Telugu), ('\\u{c5c}', '\\u{c5d}',\n         Script::Telugu), ('\\u{c60}', '\\u{c61}',  Script::Telugu), ('\\u{c62}', '\\u{c63}',\n         Script::Telugu), ('\\u{c66}', '\\u{c6f}',  Script::Telugu), ('\\u{c77}', '\\u{c77}',\n         Script::Telugu), ('\\u{c78}', '\\u{c7e}',  Script::Telugu), ('\\u{c7f}', '\\u{c7f}',\n         Script::Telugu), ('\\u{c80}', '\\u{c80}',  Script::Kannada), ('\\u{c81}', '\\u{c81}',\n         Script::Kannada), ('\\u{c82}', '\\u{c83}',  Script::Kannada), ('\\u{c84}', '\\u{c84}',\n         Script::Kannada), ('\\u{c85}', '\\u{c8c}',  Script::Kannada), ('\\u{c8e}', '\\u{c90}',\n         Script::Kannada), ('\\u{c92}', '\\u{ca8}',  Script::Kannada), ('\\u{caa}', '\\u{cb3}',\n         Script::Kannada), ('\\u{cb5}', '\\u{cb9}',  Script::Kannada), ('\\u{cbc}', '\\u{cbc}',\n         Script::Kannada), ('\\u{cbd}', '\\u{cbd}',  Script::Kannada), ('\\u{cbe}', '\\u{cbe}',\n         Script::Kannada), ('\\u{cbf}', '\\u{cbf}',  Script::Kannada), ('\\u{cc0}', '\\u{cc4}',\n         Script::Kannada), ('\\u{cc6}', '\\u{cc6}',  Script::Kannada), ('\\u{cc7}', '\\u{cc8}',\n         Script::Kannada), ('\\u{cca}', '\\u{ccb}',  Script::Kannada), ('\\u{ccc}', '\\u{ccd}',\n         Script::Kannada), ('\\u{cd5}', '\\u{cd6}',  Script::Kannada), ('\\u{cdc}', '\\u{cde}',\n         Script::Kannada), ('\\u{ce0}', '\\u{ce1}',  Script::Kannada), ('\\u{ce2}', '\\u{ce3}',\n         Script::Kannada), ('\\u{ce6}', '\\u{cef}',  Script::Kannada), ('\\u{cf1}', '\\u{cf2}',\n         Script::Kannada), ('\\u{cf3}', '\\u{cf3}',  Script::Kannada), ('\\u{d00}', '\\u{d01}',\n         Script::Malayalam), ('\\u{d02}', '\\u{d03}',  Script::Malayalam), ('\\u{d04}', '\\u{d0c}',\n         Script::Malayalam), ('\\u{d0e}', '\\u{d10}',  Script::Malayalam), ('\\u{d12}', '\\u{d3a}',\n         Script::Malayalam), ('\\u{d3b}', '\\u{d3c}',  Script::Malayalam), ('\\u{d3d}', '\\u{d3d}',\n         Script::Malayalam), ('\\u{d3e}', '\\u{d40}',  Script::Malayalam), ('\\u{d41}', '\\u{d44}',\n         Script::Malayalam), ('\\u{d46}', '\\u{d48}',  Script::Malayalam), ('\\u{d4a}', '\\u{d4c}',\n         Script::Malayalam), ('\\u{d4d}', '\\u{d4d}',  Script::Malayalam), ('\\u{d4e}', '\\u{d4e}',\n         Script::Malayalam), ('\\u{d4f}', '\\u{d4f}',  Script::Malayalam), ('\\u{d54}', '\\u{d56}',\n         Script::Malayalam), ('\\u{d57}', '\\u{d57}',  Script::Malayalam), ('\\u{d58}', '\\u{d5e}',\n         Script::Malayalam), ('\\u{d5f}', '\\u{d61}',  Script::Malayalam), ('\\u{d62}', '\\u{d63}',\n         Script::Malayalam), ('\\u{d66}', '\\u{d6f}',  Script::Malayalam), ('\\u{d70}', '\\u{d78}',\n         Script::Malayalam), ('\\u{d79}', '\\u{d79}',  Script::Malayalam), ('\\u{d7a}', '\\u{d7f}',\n         Script::Malayalam), ('\\u{d81}', '\\u{d81}',  Script::Sinhala), ('\\u{d82}', '\\u{d83}',\n         Script::Sinhala), ('\\u{d85}', '\\u{d96}',  Script::Sinhala), ('\\u{d9a}', '\\u{db1}',\n         Script::Sinhala), ('\\u{db3}', '\\u{dbb}',  Script::Sinhala), ('\\u{dbd}', '\\u{dbd}',\n         Script::Sinhala), ('\\u{dc0}', '\\u{dc6}',  Script::Sinhala), ('\\u{dca}', '\\u{dca}',\n         Script::Sinhala), ('\\u{dcf}', '\\u{dd1}',  Script::Sinhala), ('\\u{dd2}', '\\u{dd4}',\n         Script::Sinhala), ('\\u{dd6}', '\\u{dd6}',  Script::Sinhala), ('\\u{dd8}', '\\u{ddf}',\n         Script::Sinhala), ('\\u{de6}', '\\u{def}',  Script::Sinhala), ('\\u{df2}', '\\u{df3}',\n         Script::Sinhala), ('\\u{df4}', '\\u{df4}',  Script::Sinhala), ('\\u{e01}', '\\u{e30}',\n         Script::Thai), ('\\u{e31}', '\\u{e31}',  Script::Thai), ('\\u{e32}', '\\u{e33}',\n         Script::Thai), ('\\u{e34}', '\\u{e3a}',  Script::Thai), ('\\u{e3f}', '\\u{e3f}',\n         Script::Common), ('\\u{e40}', '\\u{e45}',  Script::Thai), ('\\u{e46}', '\\u{e46}',\n         Script::Thai), ('\\u{e47}', '\\u{e4e}',  Script::Thai), ('\\u{e4f}', '\\u{e4f}',\n         Script::Thai), ('\\u{e50}', '\\u{e59}',  Script::Thai), ('\\u{e5a}', '\\u{e5b}',\n         Script::Thai), ('\\u{e81}', '\\u{e82}',  Script::Lao), ('\\u{e84}', '\\u{e84}',  Script::Lao),\n        ('\\u{e86}', '\\u{e8a}',  Script::Lao), ('\\u{e8c}', '\\u{ea3}',  Script::Lao), ('\\u{ea5}',\n        '\\u{ea5}',  Script::Lao), ('\\u{ea7}', '\\u{eb0}',  Script::Lao), ('\\u{eb1}', '\\u{eb1}',\n         Script::Lao), ('\\u{eb2}', '\\u{eb3}',  Script::Lao), ('\\u{eb4}', '\\u{ebc}',  Script::Lao),\n        ('\\u{ebd}', '\\u{ebd}',  Script::Lao), ('\\u{ec0}', '\\u{ec4}',  Script::Lao), ('\\u{ec6}',\n        '\\u{ec6}',  Script::Lao), ('\\u{ec8}', '\\u{ece}',  Script::Lao), ('\\u{ed0}', '\\u{ed9}',\n         Script::Lao), ('\\u{edc}', '\\u{edf}',  Script::Lao), ('\\u{f00}', '\\u{f00}',\n         Script::Tibetan), ('\\u{f01}', '\\u{f03}',  Script::Tibetan), ('\\u{f04}', '\\u{f12}',\n         Script::Tibetan), ('\\u{f13}', '\\u{f13}',  Script::Tibetan), ('\\u{f14}', '\\u{f14}',\n         Script::Tibetan), ('\\u{f15}', '\\u{f17}',  Script::Tibetan), ('\\u{f18}', '\\u{f19}',\n         Script::Tibetan), ('\\u{f1a}', '\\u{f1f}',  Script::Tibetan), ('\\u{f20}', '\\u{f29}',\n         Script::Tibetan), ('\\u{f2a}', '\\u{f33}',  Script::Tibetan), ('\\u{f34}', '\\u{f34}',\n         Script::Tibetan), ('\\u{f35}', '\\u{f35}',  Script::Tibetan), ('\\u{f36}', '\\u{f36}',\n         Script::Tibetan), ('\\u{f37}', '\\u{f37}',  Script::Tibetan), ('\\u{f38}', '\\u{f38}',\n         Script::Tibetan), ('\\u{f39}', '\\u{f39}',  Script::Tibetan), ('\\u{f3a}', '\\u{f3a}',\n         Script::Tibetan), ('\\u{f3b}', '\\u{f3b}',  Script::Tibetan), ('\\u{f3c}', '\\u{f3c}',\n         Script::Tibetan), ('\\u{f3d}', '\\u{f3d}',  Script::Tibetan), ('\\u{f3e}', '\\u{f3f}',\n         Script::Tibetan), ('\\u{f40}', '\\u{f47}',  Script::Tibetan), ('\\u{f49}', '\\u{f6c}',\n         Script::Tibetan), ('\\u{f71}', '\\u{f7e}',  Script::Tibetan), ('\\u{f7f}', '\\u{f7f}',\n         Script::Tibetan), ('\\u{f80}', '\\u{f84}',  Script::Tibetan), ('\\u{f85}', '\\u{f85}',\n         Script::Tibetan), ('\\u{f86}', '\\u{f87}',  Script::Tibetan), ('\\u{f88}', '\\u{f8c}',\n         Script::Tibetan), ('\\u{f8d}', '\\u{f97}',  Script::Tibetan), ('\\u{f99}', '\\u{fbc}',\n         Script::Tibetan), ('\\u{fbe}', '\\u{fc5}',  Script::Tibetan), ('\\u{fc6}', '\\u{fc6}',\n         Script::Tibetan), ('\\u{fc7}', '\\u{fcc}',  Script::Tibetan), ('\\u{fce}', '\\u{fcf}',\n         Script::Tibetan), ('\\u{fd0}', '\\u{fd4}',  Script::Tibetan), ('\\u{fd5}', '\\u{fd8}',\n         Script::Common), ('\\u{fd9}', '\\u{fda}',  Script::Tibetan), ('\\u{1000}', '\\u{102a}',\n         Script::Myanmar), ('\\u{102b}', '\\u{102c}',  Script::Myanmar), ('\\u{102d}', '\\u{1030}',\n         Script::Myanmar), ('\\u{1031}', '\\u{1031}',  Script::Myanmar), ('\\u{1032}', '\\u{1037}',\n         Script::Myanmar), ('\\u{1038}', '\\u{1038}',  Script::Myanmar), ('\\u{1039}', '\\u{103a}',\n         Script::Myanmar), ('\\u{103b}', '\\u{103c}',  Script::Myanmar), ('\\u{103d}', '\\u{103e}',\n         Script::Myanmar), ('\\u{103f}', '\\u{103f}',  Script::Myanmar), ('\\u{1040}', '\\u{1049}',\n         Script::Myanmar), ('\\u{104a}', '\\u{104f}',  Script::Myanmar), ('\\u{1050}', '\\u{1055}',\n         Script::Myanmar), ('\\u{1056}', '\\u{1057}',  Script::Myanmar), ('\\u{1058}', '\\u{1059}',\n         Script::Myanmar), ('\\u{105a}', '\\u{105d}',  Script::Myanmar), ('\\u{105e}', '\\u{1060}',\n         Script::Myanmar), ('\\u{1061}', '\\u{1061}',  Script::Myanmar), ('\\u{1062}', '\\u{1064}',\n         Script::Myanmar), ('\\u{1065}', '\\u{1066}',  Script::Myanmar), ('\\u{1067}', '\\u{106d}',\n         Script::Myanmar), ('\\u{106e}', '\\u{1070}',  Script::Myanmar), ('\\u{1071}', '\\u{1074}',\n         Script::Myanmar), ('\\u{1075}', '\\u{1081}',  Script::Myanmar), ('\\u{1082}', '\\u{1082}',\n         Script::Myanmar), ('\\u{1083}', '\\u{1084}',  Script::Myanmar), ('\\u{1085}', '\\u{1086}',\n         Script::Myanmar), ('\\u{1087}', '\\u{108c}',  Script::Myanmar), ('\\u{108d}', '\\u{108d}',\n         Script::Myanmar), ('\\u{108e}', '\\u{108e}',  Script::Myanmar), ('\\u{108f}', '\\u{108f}',\n         Script::Myanmar), ('\\u{1090}', '\\u{1099}',  Script::Myanmar), ('\\u{109a}', '\\u{109c}',\n         Script::Myanmar), ('\\u{109d}', '\\u{109d}',  Script::Myanmar), ('\\u{109e}', '\\u{109f}',\n         Script::Myanmar), ('\\u{10a0}', '\\u{10c5}',  Script::Georgian), ('\\u{10c7}', '\\u{10c7}',\n         Script::Georgian), ('\\u{10cd}', '\\u{10cd}',  Script::Georgian), ('\\u{10d0}', '\\u{10fa}',\n         Script::Georgian), ('\\u{10fb}', '\\u{10fb}',  Script::Common), ('\\u{10fc}', '\\u{10fc}',\n         Script::Georgian), ('\\u{10fd}', '\\u{10ff}',  Script::Georgian), ('\\u{1100}', '\\u{11ff}',\n         Script::Hangul), ('\\u{1200}', '\\u{1248}',  Script::Ethiopic), ('\\u{124a}', '\\u{124d}',\n         Script::Ethiopic), ('\\u{1250}', '\\u{1256}',  Script::Ethiopic), ('\\u{1258}', '\\u{1258}',\n         Script::Ethiopic), ('\\u{125a}', '\\u{125d}',  Script::Ethiopic), ('\\u{1260}', '\\u{1288}',\n         Script::Ethiopic), ('\\u{128a}', '\\u{128d}',  Script::Ethiopic), ('\\u{1290}', '\\u{12b0}',\n         Script::Ethiopic), ('\\u{12b2}', '\\u{12b5}',  Script::Ethiopic), ('\\u{12b8}', '\\u{12be}',\n         Script::Ethiopic), ('\\u{12c0}', '\\u{12c0}',  Script::Ethiopic), ('\\u{12c2}', '\\u{12c5}',\n         Script::Ethiopic), ('\\u{12c8}', '\\u{12d6}',  Script::Ethiopic), ('\\u{12d8}', '\\u{1310}',\n         Script::Ethiopic), ('\\u{1312}', '\\u{1315}',  Script::Ethiopic), ('\\u{1318}', '\\u{135a}',\n         Script::Ethiopic), ('\\u{135d}', '\\u{135f}',  Script::Ethiopic), ('\\u{1360}', '\\u{1368}',\n         Script::Ethiopic), ('\\u{1369}', '\\u{137c}',  Script::Ethiopic), ('\\u{1380}', '\\u{138f}',\n         Script::Ethiopic), ('\\u{1390}', '\\u{1399}',  Script::Ethiopic), ('\\u{13a0}', '\\u{13f5}',\n         Script::Cherokee), ('\\u{13f8}', '\\u{13fd}',  Script::Cherokee), ('\\u{1400}', '\\u{1400}',\n         Script::Canadian_Aboriginal), ('\\u{1401}', '\\u{166c}',  Script::Canadian_Aboriginal),\n        ('\\u{166d}', '\\u{166d}',  Script::Canadian_Aboriginal), ('\\u{166e}', '\\u{166e}',\n         Script::Canadian_Aboriginal), ('\\u{166f}', '\\u{167f}',  Script::Canadian_Aboriginal),\n        ('\\u{1680}', '\\u{1680}',  Script::Ogham), ('\\u{1681}', '\\u{169a}',  Script::Ogham),\n        ('\\u{169b}', '\\u{169b}',  Script::Ogham), ('\\u{169c}', '\\u{169c}',  Script::Ogham),\n        ('\\u{16a0}', '\\u{16ea}',  Script::Runic), ('\\u{16eb}', '\\u{16ed}',  Script::Common),\n        ('\\u{16ee}', '\\u{16f0}',  Script::Runic), ('\\u{16f1}', '\\u{16f8}',  Script::Runic),\n        ('\\u{1700}', '\\u{1711}',  Script::Tagalog), ('\\u{1712}', '\\u{1714}',  Script::Tagalog),\n        ('\\u{1715}', '\\u{1715}',  Script::Tagalog), ('\\u{171f}', '\\u{171f}',  Script::Tagalog),\n        ('\\u{1720}', '\\u{1731}',  Script::Hanunoo), ('\\u{1732}', '\\u{1733}',  Script::Hanunoo),\n        ('\\u{1734}', '\\u{1734}',  Script::Hanunoo), ('\\u{1735}', '\\u{1736}',  Script::Common),\n        ('\\u{1740}', '\\u{1751}',  Script::Buhid), ('\\u{1752}', '\\u{1753}',  Script::Buhid),\n        ('\\u{1760}', '\\u{176c}',  Script::Tagbanwa), ('\\u{176e}', '\\u{1770}',  Script::Tagbanwa),\n        ('\\u{1772}', '\\u{1773}',  Script::Tagbanwa), ('\\u{1780}', '\\u{17b3}',  Script::Khmer),\n        ('\\u{17b4}', '\\u{17b5}',  Script::Khmer), ('\\u{17b6}', '\\u{17b6}',  Script::Khmer),\n        ('\\u{17b7}', '\\u{17bd}',  Script::Khmer), ('\\u{17be}', '\\u{17c5}',  Script::Khmer),\n        ('\\u{17c6}', '\\u{17c6}',  Script::Khmer), ('\\u{17c7}', '\\u{17c8}',  Script::Khmer),\n        ('\\u{17c9}', '\\u{17d3}',  Script::Khmer), ('\\u{17d4}', '\\u{17d6}',  Script::Khmer),\n        ('\\u{17d7}', '\\u{17d7}',  Script::Khmer), ('\\u{17d8}', '\\u{17da}',  Script::Khmer),\n        ('\\u{17db}', '\\u{17db}',  Script::Khmer), ('\\u{17dc}', '\\u{17dc}',  Script::Khmer),\n        ('\\u{17dd}', '\\u{17dd}',  Script::Khmer), ('\\u{17e0}', '\\u{17e9}',  Script::Khmer),\n        ('\\u{17f0}', '\\u{17f9}',  Script::Khmer), ('\\u{1800}', '\\u{1801}',  Script::Mongolian),\n        ('\\u{1802}', '\\u{1803}',  Script::Common), ('\\u{1804}', '\\u{1804}',  Script::Mongolian),\n        ('\\u{1805}', '\\u{1805}',  Script::Common), ('\\u{1806}', '\\u{1806}',  Script::Mongolian),\n        ('\\u{1807}', '\\u{180a}',  Script::Mongolian), ('\\u{180b}', '\\u{180d}',  Script::Mongolian),\n        ('\\u{180e}', '\\u{180e}',  Script::Mongolian), ('\\u{180f}', '\\u{180f}',  Script::Mongolian),\n        ('\\u{1810}', '\\u{1819}',  Script::Mongolian), ('\\u{1820}', '\\u{1842}',  Script::Mongolian),\n        ('\\u{1843}', '\\u{1843}',  Script::Mongolian), ('\\u{1844}', '\\u{1878}',  Script::Mongolian),\n        ('\\u{1880}', '\\u{1884}',  Script::Mongolian), ('\\u{1885}', '\\u{1886}',  Script::Mongolian),\n        ('\\u{1887}', '\\u{18a8}',  Script::Mongolian), ('\\u{18a9}', '\\u{18a9}',  Script::Mongolian),\n        ('\\u{18aa}', '\\u{18aa}',  Script::Mongolian), ('\\u{18b0}', '\\u{18f5}',\n         Script::Canadian_Aboriginal), ('\\u{1900}', '\\u{191e}',  Script::Limbu), ('\\u{1920}',\n        '\\u{1922}',  Script::Limbu), ('\\u{1923}', '\\u{1926}',  Script::Limbu), ('\\u{1927}',\n        '\\u{1928}',  Script::Limbu), ('\\u{1929}', '\\u{192b}',  Script::Limbu), ('\\u{1930}',\n        '\\u{1931}',  Script::Limbu), ('\\u{1932}', '\\u{1932}',  Script::Limbu), ('\\u{1933}',\n        '\\u{1938}',  Script::Limbu), ('\\u{1939}', '\\u{193b}',  Script::Limbu), ('\\u{1940}',\n        '\\u{1940}',  Script::Limbu), ('\\u{1944}', '\\u{1945}',  Script::Limbu), ('\\u{1946}',\n        '\\u{194f}',  Script::Limbu), ('\\u{1950}', '\\u{196d}',  Script::Tai_Le), ('\\u{1970}',\n        '\\u{1974}',  Script::Tai_Le), ('\\u{1980}', '\\u{19ab}',  Script::New_Tai_Lue), ('\\u{19b0}',\n        '\\u{19c9}',  Script::New_Tai_Lue), ('\\u{19d0}', '\\u{19d9}',  Script::New_Tai_Lue),\n        ('\\u{19da}', '\\u{19da}',  Script::New_Tai_Lue), ('\\u{19de}', '\\u{19df}',\n         Script::New_Tai_Lue), ('\\u{19e0}', '\\u{19ff}',  Script::Khmer), ('\\u{1a00}', '\\u{1a16}',\n         Script::Buginese), ('\\u{1a17}', '\\u{1a18}',  Script::Buginese), ('\\u{1a19}', '\\u{1a1a}',\n         Script::Buginese), ('\\u{1a1b}', '\\u{1a1b}',  Script::Buginese), ('\\u{1a1e}', '\\u{1a1f}',\n         Script::Buginese), ('\\u{1a20}', '\\u{1a54}',  Script::Tai_Tham), ('\\u{1a55}', '\\u{1a55}',\n         Script::Tai_Tham), ('\\u{1a56}', '\\u{1a56}',  Script::Tai_Tham), ('\\u{1a57}', '\\u{1a57}',\n         Script::Tai_Tham), ('\\u{1a58}', '\\u{1a5e}',  Script::Tai_Tham), ('\\u{1a60}', '\\u{1a60}',\n         Script::Tai_Tham), ('\\u{1a61}', '\\u{1a61}',  Script::Tai_Tham), ('\\u{1a62}', '\\u{1a62}',\n         Script::Tai_Tham), ('\\u{1a63}', '\\u{1a64}',  Script::Tai_Tham), ('\\u{1a65}', '\\u{1a6c}',\n         Script::Tai_Tham), ('\\u{1a6d}', '\\u{1a72}',  Script::Tai_Tham), ('\\u{1a73}', '\\u{1a7c}',\n         Script::Tai_Tham), ('\\u{1a7f}', '\\u{1a7f}',  Script::Tai_Tham), ('\\u{1a80}', '\\u{1a89}',\n         Script::Tai_Tham), ('\\u{1a90}', '\\u{1a99}',  Script::Tai_Tham), ('\\u{1aa0}', '\\u{1aa6}',\n         Script::Tai_Tham), ('\\u{1aa7}', '\\u{1aa7}',  Script::Tai_Tham), ('\\u{1aa8}', '\\u{1aad}',\n         Script::Tai_Tham), ('\\u{1ab0}', '\\u{1abd}',  Script::Inherited), ('\\u{1abe}', '\\u{1abe}',\n         Script::Inherited), ('\\u{1abf}', '\\u{1add}',  Script::Inherited), ('\\u{1ae0}', '\\u{1aeb}',\n         Script::Inherited), ('\\u{1b00}', '\\u{1b03}',  Script::Balinese), ('\\u{1b04}', '\\u{1b04}',\n         Script::Balinese), ('\\u{1b05}', '\\u{1b33}',  Script::Balinese), ('\\u{1b34}', '\\u{1b34}',\n         Script::Balinese), ('\\u{1b35}', '\\u{1b35}',  Script::Balinese), ('\\u{1b36}', '\\u{1b3a}',\n         Script::Balinese), ('\\u{1b3b}', '\\u{1b3b}',  Script::Balinese), ('\\u{1b3c}', '\\u{1b3c}',\n         Script::Balinese), ('\\u{1b3d}', '\\u{1b41}',  Script::Balinese), ('\\u{1b42}', '\\u{1b42}',\n         Script::Balinese), ('\\u{1b43}', '\\u{1b44}',  Script::Balinese), ('\\u{1b45}', '\\u{1b4c}',\n         Script::Balinese), ('\\u{1b4e}', '\\u{1b4f}',  Script::Balinese), ('\\u{1b50}', '\\u{1b59}',\n         Script::Balinese), ('\\u{1b5a}', '\\u{1b60}',  Script::Balinese), ('\\u{1b61}', '\\u{1b6a}',\n         Script::Balinese), ('\\u{1b6b}', '\\u{1b73}',  Script::Balinese), ('\\u{1b74}', '\\u{1b7c}',\n         Script::Balinese), ('\\u{1b7d}', '\\u{1b7f}',  Script::Balinese), ('\\u{1b80}', '\\u{1b81}',\n         Script::Sundanese), ('\\u{1b82}', '\\u{1b82}',  Script::Sundanese), ('\\u{1b83}', '\\u{1ba0}',\n         Script::Sundanese), ('\\u{1ba1}', '\\u{1ba1}',  Script::Sundanese), ('\\u{1ba2}', '\\u{1ba5}',\n         Script::Sundanese), ('\\u{1ba6}', '\\u{1ba7}',  Script::Sundanese), ('\\u{1ba8}', '\\u{1ba9}',\n         Script::Sundanese), ('\\u{1baa}', '\\u{1baa}',  Script::Sundanese), ('\\u{1bab}', '\\u{1bad}',\n         Script::Sundanese), ('\\u{1bae}', '\\u{1baf}',  Script::Sundanese), ('\\u{1bb0}', '\\u{1bb9}',\n         Script::Sundanese), ('\\u{1bba}', '\\u{1bbf}',  Script::Sundanese), ('\\u{1bc0}', '\\u{1be5}',\n         Script::Batak), ('\\u{1be6}', '\\u{1be6}',  Script::Batak), ('\\u{1be7}', '\\u{1be7}',\n         Script::Batak), ('\\u{1be8}', '\\u{1be9}',  Script::Batak), ('\\u{1bea}', '\\u{1bec}',\n         Script::Batak), ('\\u{1bed}', '\\u{1bed}',  Script::Batak), ('\\u{1bee}', '\\u{1bee}',\n         Script::Batak), ('\\u{1bef}', '\\u{1bf1}',  Script::Batak), ('\\u{1bf2}', '\\u{1bf3}',\n         Script::Batak), ('\\u{1bfc}', '\\u{1bff}',  Script::Batak), ('\\u{1c00}', '\\u{1c23}',\n         Script::Lepcha), ('\\u{1c24}', '\\u{1c2b}',  Script::Lepcha), ('\\u{1c2c}', '\\u{1c33}',\n         Script::Lepcha), ('\\u{1c34}', '\\u{1c35}',  Script::Lepcha), ('\\u{1c36}', '\\u{1c37}',\n         Script::Lepcha), ('\\u{1c3b}', '\\u{1c3f}',  Script::Lepcha), ('\\u{1c40}', '\\u{1c49}',\n         Script::Lepcha), ('\\u{1c4d}', '\\u{1c4f}',  Script::Lepcha), ('\\u{1c50}', '\\u{1c59}',\n         Script::Ol_Chiki), ('\\u{1c5a}', '\\u{1c77}',  Script::Ol_Chiki), ('\\u{1c78}', '\\u{1c7d}',\n         Script::Ol_Chiki), ('\\u{1c7e}', '\\u{1c7f}',  Script::Ol_Chiki), ('\\u{1c80}', '\\u{1c8a}',\n         Script::Cyrillic), ('\\u{1c90}', '\\u{1cba}',  Script::Georgian), ('\\u{1cbd}', '\\u{1cbf}',\n         Script::Georgian), ('\\u{1cc0}', '\\u{1cc7}',  Script::Sundanese), ('\\u{1cd0}', '\\u{1cd2}',\n         Script::Inherited), ('\\u{1cd3}', '\\u{1cd3}',  Script::Common), ('\\u{1cd4}', '\\u{1ce0}',\n         Script::Inherited), ('\\u{1ce1}', '\\u{1ce1}',  Script::Common), ('\\u{1ce2}', '\\u{1ce8}',\n         Script::Inherited), ('\\u{1ce9}', '\\u{1cec}',  Script::Common), ('\\u{1ced}', '\\u{1ced}',\n         Script::Inherited), ('\\u{1cee}', '\\u{1cf3}',  Script::Common), ('\\u{1cf4}', '\\u{1cf4}',\n         Script::Inherited), ('\\u{1cf5}', '\\u{1cf6}',  Script::Common), ('\\u{1cf7}', '\\u{1cf7}',\n         Script::Common), ('\\u{1cf8}', '\\u{1cf9}',  Script::Inherited), ('\\u{1cfa}', '\\u{1cfa}',\n         Script::Common), ('\\u{1d00}', '\\u{1d25}',  Script::Latin), ('\\u{1d26}', '\\u{1d2a}',\n         Script::Greek), ('\\u{1d2b}', '\\u{1d2b}',  Script::Cyrillic), ('\\u{1d2c}', '\\u{1d5c}',\n         Script::Latin), ('\\u{1d5d}', '\\u{1d61}',  Script::Greek), ('\\u{1d62}', '\\u{1d65}',\n         Script::Latin), ('\\u{1d66}', '\\u{1d6a}',  Script::Greek), ('\\u{1d6b}', '\\u{1d77}',\n         Script::Latin), ('\\u{1d78}', '\\u{1d78}',  Script::Cyrillic), ('\\u{1d79}', '\\u{1d9a}',\n         Script::Latin), ('\\u{1d9b}', '\\u{1dbe}',  Script::Latin), ('\\u{1dbf}', '\\u{1dbf}',\n         Script::Greek), ('\\u{1dc0}', '\\u{1dff}',  Script::Inherited), ('\\u{1e00}', '\\u{1eff}',\n         Script::Latin), ('\\u{1f00}', '\\u{1f15}',  Script::Greek), ('\\u{1f18}', '\\u{1f1d}',\n         Script::Greek), ('\\u{1f20}', '\\u{1f45}',  Script::Greek), ('\\u{1f48}', '\\u{1f4d}',\n         Script::Greek), ('\\u{1f50}', '\\u{1f57}',  Script::Greek), ('\\u{1f59}', '\\u{1f59}',\n         Script::Greek), ('\\u{1f5b}', '\\u{1f5b}',  Script::Greek), ('\\u{1f5d}', '\\u{1f5d}',\n         Script::Greek), ('\\u{1f5f}', '\\u{1f7d}',  Script::Greek), ('\\u{1f80}', '\\u{1fb4}',\n         Script::Greek), ('\\u{1fb6}', '\\u{1fbc}',  Script::Greek), ('\\u{1fbd}', '\\u{1fbd}',\n         Script::Greek), ('\\u{1fbe}', '\\u{1fbe}',  Script::Greek), ('\\u{1fbf}', '\\u{1fc1}',\n         Script::Greek), ('\\u{1fc2}', '\\u{1fc4}',  Script::Greek), ('\\u{1fc6}', '\\u{1fcc}',\n         Script::Greek), ('\\u{1fcd}', '\\u{1fcf}',  Script::Greek), ('\\u{1fd0}', '\\u{1fd3}',\n         Script::Greek), ('\\u{1fd6}', '\\u{1fdb}',  Script::Greek), ('\\u{1fdd}', '\\u{1fdf}',\n         Script::Greek), ('\\u{1fe0}', '\\u{1fec}',  Script::Greek), ('\\u{1fed}', '\\u{1fef}',\n         Script::Greek), ('\\u{1ff2}', '\\u{1ff4}',  Script::Greek), ('\\u{1ff6}', '\\u{1ffc}',\n         Script::Greek), ('\\u{1ffd}', '\\u{1ffe}',  Script::Greek), ('\\u{2000}', '\\u{200a}',\n         Script::Common), ('\\u{200b}', '\\u{200b}',  Script::Common), ('\\u{200c}', '\\u{200d}',\n         Script::Inherited), ('\\u{200e}', '\\u{200f}',  Script::Common), ('\\u{2010}', '\\u{2015}',\n         Script::Common), ('\\u{2016}', '\\u{2017}',  Script::Common), ('\\u{2018}', '\\u{2018}',\n         Script::Common), ('\\u{2019}', '\\u{2019}',  Script::Common), ('\\u{201a}', '\\u{201a}',\n         Script::Common), ('\\u{201b}', '\\u{201c}',  Script::Common), ('\\u{201d}', '\\u{201d}',\n         Script::Common), ('\\u{201e}', '\\u{201e}',  Script::Common), ('\\u{201f}', '\\u{201f}',\n         Script::Common), ('\\u{2020}', '\\u{2027}',  Script::Common), ('\\u{2028}', '\\u{2028}',\n         Script::Common), ('\\u{2029}', '\\u{2029}',  Script::Common), ('\\u{202a}', '\\u{202e}',\n         Script::Common), ('\\u{202f}', '\\u{202f}',  Script::Common), ('\\u{2030}', '\\u{2038}',\n         Script::Common), ('\\u{2039}', '\\u{2039}',  Script::Common), ('\\u{203a}', '\\u{203a}',\n         Script::Common), ('\\u{203b}', '\\u{203e}',  Script::Common), ('\\u{203f}', '\\u{2040}',\n         Script::Common), ('\\u{2041}', '\\u{2043}',  Script::Common), ('\\u{2044}', '\\u{2044}',\n         Script::Common), ('\\u{2045}', '\\u{2045}',  Script::Common), ('\\u{2046}', '\\u{2046}',\n         Script::Common), ('\\u{2047}', '\\u{2051}',  Script::Common), ('\\u{2052}', '\\u{2052}',\n         Script::Common), ('\\u{2053}', '\\u{2053}',  Script::Common), ('\\u{2054}', '\\u{2054}',\n         Script::Common), ('\\u{2055}', '\\u{205e}',  Script::Common), ('\\u{205f}', '\\u{205f}',\n         Script::Common), ('\\u{2060}', '\\u{2064}',  Script::Common), ('\\u{2066}', '\\u{206f}',\n         Script::Common), ('\\u{2070}', '\\u{2070}',  Script::Common), ('\\u{2071}', '\\u{2071}',\n         Script::Latin), ('\\u{2074}', '\\u{2079}',  Script::Common), ('\\u{207a}', '\\u{207c}',\n         Script::Common), ('\\u{207d}', '\\u{207d}',  Script::Common), ('\\u{207e}', '\\u{207e}',\n         Script::Common), ('\\u{207f}', '\\u{207f}',  Script::Latin), ('\\u{2080}', '\\u{2089}',\n         Script::Common), ('\\u{208a}', '\\u{208c}',  Script::Common), ('\\u{208d}', '\\u{208d}',\n         Script::Common), ('\\u{208e}', '\\u{208e}',  Script::Common), ('\\u{2090}', '\\u{209c}',\n         Script::Latin), ('\\u{20a0}', '\\u{20c1}',  Script::Common), ('\\u{20d0}', '\\u{20dc}',\n         Script::Inherited), ('\\u{20dd}', '\\u{20e0}',  Script::Inherited), ('\\u{20e1}', '\\u{20e1}',\n         Script::Inherited), ('\\u{20e2}', '\\u{20e4}',  Script::Inherited), ('\\u{20e5}', '\\u{20f0}',\n         Script::Inherited), ('\\u{2100}', '\\u{2101}',  Script::Common), ('\\u{2102}', '\\u{2102}',\n         Script::Common), ('\\u{2103}', '\\u{2106}',  Script::Common), ('\\u{2107}', '\\u{2107}',\n         Script::Common), ('\\u{2108}', '\\u{2109}',  Script::Common), ('\\u{210a}', '\\u{2113}',\n         Script::Common), ('\\u{2114}', '\\u{2114}',  Script::Common), ('\\u{2115}', '\\u{2115}',\n         Script::Common), ('\\u{2116}', '\\u{2117}',  Script::Common), ('\\u{2118}', '\\u{2118}',\n         Script::Common), ('\\u{2119}', '\\u{211d}',  Script::Common), ('\\u{211e}', '\\u{2123}',\n         Script::Common), ('\\u{2124}', '\\u{2124}',  Script::Common), ('\\u{2125}', '\\u{2125}',\n         Script::Common), ('\\u{2126}', '\\u{2126}',  Script::Greek), ('\\u{2127}', '\\u{2127}',\n         Script::Common), ('\\u{2128}', '\\u{2128}',  Script::Common), ('\\u{2129}', '\\u{2129}',\n         Script::Common), ('\\u{212a}', '\\u{212b}',  Script::Latin), ('\\u{212c}', '\\u{212d}',\n         Script::Common), ('\\u{212e}', '\\u{212e}',  Script::Common), ('\\u{212f}', '\\u{2131}',\n         Script::Common), ('\\u{2132}', '\\u{2132}',  Script::Latin), ('\\u{2133}', '\\u{2134}',\n         Script::Common), ('\\u{2135}', '\\u{2138}',  Script::Common), ('\\u{2139}', '\\u{2139}',\n         Script::Common), ('\\u{213a}', '\\u{213b}',  Script::Common), ('\\u{213c}', '\\u{213f}',\n         Script::Common), ('\\u{2140}', '\\u{2144}',  Script::Common), ('\\u{2145}', '\\u{2149}',\n         Script::Common), ('\\u{214a}', '\\u{214a}',  Script::Common), ('\\u{214b}', '\\u{214b}',\n         Script::Common), ('\\u{214c}', '\\u{214d}',  Script::Common), ('\\u{214e}', '\\u{214e}',\n         Script::Latin), ('\\u{214f}', '\\u{214f}',  Script::Common), ('\\u{2150}', '\\u{215f}',\n         Script::Common), ('\\u{2160}', '\\u{2182}',  Script::Latin), ('\\u{2183}', '\\u{2184}',\n         Script::Latin), ('\\u{2185}', '\\u{2188}',  Script::Latin), ('\\u{2189}', '\\u{2189}',\n         Script::Common), ('\\u{218a}', '\\u{218b}',  Script::Common), ('\\u{2190}', '\\u{2194}',\n         Script::Common), ('\\u{2195}', '\\u{2199}',  Script::Common), ('\\u{219a}', '\\u{219b}',\n         Script::Common), ('\\u{219c}', '\\u{219f}',  Script::Common), ('\\u{21a0}', '\\u{21a0}',\n         Script::Common), ('\\u{21a1}', '\\u{21a2}',  Script::Common), ('\\u{21a3}', '\\u{21a3}',\n         Script::Common), ('\\u{21a4}', '\\u{21a5}',  Script::Common), ('\\u{21a6}', '\\u{21a6}',\n         Script::Common), ('\\u{21a7}', '\\u{21ad}',  Script::Common), ('\\u{21ae}', '\\u{21ae}',\n         Script::Common), ('\\u{21af}', '\\u{21cd}',  Script::Common), ('\\u{21ce}', '\\u{21cf}',\n         Script::Common), ('\\u{21d0}', '\\u{21d1}',  Script::Common), ('\\u{21d2}', '\\u{21d2}',\n         Script::Common), ('\\u{21d3}', '\\u{21d3}',  Script::Common), ('\\u{21d4}', '\\u{21d4}',\n         Script::Common), ('\\u{21d5}', '\\u{21f3}',  Script::Common), ('\\u{21f4}', '\\u{22ff}',\n         Script::Common), ('\\u{2300}', '\\u{2307}',  Script::Common), ('\\u{2308}', '\\u{2308}',\n         Script::Common), ('\\u{2309}', '\\u{2309}',  Script::Common), ('\\u{230a}', '\\u{230a}',\n         Script::Common), ('\\u{230b}', '\\u{230b}',  Script::Common), ('\\u{230c}', '\\u{231f}',\n         Script::Common), ('\\u{2320}', '\\u{2321}',  Script::Common), ('\\u{2322}', '\\u{2328}',\n         Script::Common), ('\\u{2329}', '\\u{2329}',  Script::Common), ('\\u{232a}', '\\u{232a}',\n         Script::Common), ('\\u{232b}', '\\u{237b}',  Script::Common), ('\\u{237c}', '\\u{237c}',\n         Script::Common), ('\\u{237d}', '\\u{239a}',  Script::Common), ('\\u{239b}', '\\u{23b3}',\n         Script::Common), ('\\u{23b4}', '\\u{23db}',  Script::Common), ('\\u{23dc}', '\\u{23e1}',\n         Script::Common), ('\\u{23e2}', '\\u{2429}',  Script::Common), ('\\u{2440}', '\\u{244a}',\n         Script::Common), ('\\u{2460}', '\\u{249b}',  Script::Common), ('\\u{249c}', '\\u{24e9}',\n         Script::Common), ('\\u{24ea}', '\\u{24ff}',  Script::Common), ('\\u{2500}', '\\u{25b6}',\n         Script::Common), ('\\u{25b7}', '\\u{25b7}',  Script::Common), ('\\u{25b8}', '\\u{25c0}',\n         Script::Common), ('\\u{25c1}', '\\u{25c1}',  Script::Common), ('\\u{25c2}', '\\u{25f7}',\n         Script::Common), ('\\u{25f8}', '\\u{25ff}',  Script::Common), ('\\u{2600}', '\\u{266e}',\n         Script::Common), ('\\u{266f}', '\\u{266f}',  Script::Common), ('\\u{2670}', '\\u{2767}',\n         Script::Common), ('\\u{2768}', '\\u{2768}',  Script::Common), ('\\u{2769}', '\\u{2769}',\n         Script::Common), ('\\u{276a}', '\\u{276a}',  Script::Common), ('\\u{276b}', '\\u{276b}',\n         Script::Common), ('\\u{276c}', '\\u{276c}',  Script::Common), ('\\u{276d}', '\\u{276d}',\n         Script::Common), ('\\u{276e}', '\\u{276e}',  Script::Common), ('\\u{276f}', '\\u{276f}',\n         Script::Common), ('\\u{2770}', '\\u{2770}',  Script::Common), ('\\u{2771}', '\\u{2771}',\n         Script::Common), ('\\u{2772}', '\\u{2772}',  Script::Common), ('\\u{2773}', '\\u{2773}',\n         Script::Common), ('\\u{2774}', '\\u{2774}',  Script::Common), ('\\u{2775}', '\\u{2775}',\n         Script::Common), ('\\u{2776}', '\\u{2793}',  Script::Common), ('\\u{2794}', '\\u{27bf}',\n         Script::Common), ('\\u{27c0}', '\\u{27c4}',  Script::Common), ('\\u{27c5}', '\\u{27c5}',\n         Script::Common), ('\\u{27c6}', '\\u{27c6}',  Script::Common), ('\\u{27c7}', '\\u{27e5}',\n         Script::Common), ('\\u{27e6}', '\\u{27e6}',  Script::Common), ('\\u{27e7}', '\\u{27e7}',\n         Script::Common), ('\\u{27e8}', '\\u{27e8}',  Script::Common), ('\\u{27e9}', '\\u{27e9}',\n         Script::Common), ('\\u{27ea}', '\\u{27ea}',  Script::Common), ('\\u{27eb}', '\\u{27eb}',\n         Script::Common), ('\\u{27ec}', '\\u{27ec}',  Script::Common), ('\\u{27ed}', '\\u{27ed}',\n         Script::Common), ('\\u{27ee}', '\\u{27ee}',  Script::Common), ('\\u{27ef}', '\\u{27ef}',\n         Script::Common), ('\\u{27f0}', '\\u{27ff}',  Script::Common), ('\\u{2800}', '\\u{28ff}',\n         Script::Braille), ('\\u{2900}', '\\u{2982}',  Script::Common), ('\\u{2983}', '\\u{2983}',\n         Script::Common), ('\\u{2984}', '\\u{2984}',  Script::Common), ('\\u{2985}', '\\u{2985}',\n         Script::Common), ('\\u{2986}', '\\u{2986}',  Script::Common), ('\\u{2987}', '\\u{2987}',\n         Script::Common), ('\\u{2988}', '\\u{2988}',  Script::Common), ('\\u{2989}', '\\u{2989}',\n         Script::Common), ('\\u{298a}', '\\u{298a}',  Script::Common), ('\\u{298b}', '\\u{298b}',\n         Script::Common), ('\\u{298c}', '\\u{298c}',  Script::Common), ('\\u{298d}', '\\u{298d}',\n         Script::Common), ('\\u{298e}', '\\u{298e}',  Script::Common), ('\\u{298f}', '\\u{298f}',\n         Script::Common), ('\\u{2990}', '\\u{2990}',  Script::Common), ('\\u{2991}', '\\u{2991}',\n         Script::Common), ('\\u{2992}', '\\u{2992}',  Script::Common), ('\\u{2993}', '\\u{2993}',\n         Script::Common), ('\\u{2994}', '\\u{2994}',  Script::Common), ('\\u{2995}', '\\u{2995}',\n         Script::Common), ('\\u{2996}', '\\u{2996}',  Script::Common), ('\\u{2997}', '\\u{2997}',\n         Script::Common), ('\\u{2998}', '\\u{2998}',  Script::Common), ('\\u{2999}', '\\u{29d7}',\n         Script::Common), ('\\u{29d8}', '\\u{29d8}',  Script::Common), ('\\u{29d9}', '\\u{29d9}',\n         Script::Common), ('\\u{29da}', '\\u{29da}',  Script::Common), ('\\u{29db}', '\\u{29db}',\n         Script::Common), ('\\u{29dc}', '\\u{29fb}',  Script::Common), ('\\u{29fc}', '\\u{29fc}',\n         Script::Common), ('\\u{29fd}', '\\u{29fd}',  Script::Common), ('\\u{29fe}', '\\u{2aff}',\n         Script::Common), ('\\u{2b00}', '\\u{2b2f}',  Script::Common), ('\\u{2b30}', '\\u{2b44}',\n         Script::Common), ('\\u{2b45}', '\\u{2b46}',  Script::Common), ('\\u{2b47}', '\\u{2b4c}',\n         Script::Common), ('\\u{2b4d}', '\\u{2b73}',  Script::Common), ('\\u{2b76}', '\\u{2bff}',\n         Script::Common), ('\\u{2c00}', '\\u{2c5f}',  Script::Glagolitic), ('\\u{2c60}', '\\u{2c7b}',\n         Script::Latin), ('\\u{2c7c}', '\\u{2c7d}',  Script::Latin), ('\\u{2c7e}', '\\u{2c7f}',\n         Script::Latin), ('\\u{2c80}', '\\u{2ce4}',  Script::Coptic), ('\\u{2ce5}', '\\u{2cea}',\n         Script::Coptic), ('\\u{2ceb}', '\\u{2cee}',  Script::Coptic), ('\\u{2cef}', '\\u{2cf1}',\n         Script::Coptic), ('\\u{2cf2}', '\\u{2cf3}',  Script::Coptic), ('\\u{2cf9}', '\\u{2cfc}',\n         Script::Coptic), ('\\u{2cfd}', '\\u{2cfd}',  Script::Coptic), ('\\u{2cfe}', '\\u{2cff}',\n         Script::Coptic), ('\\u{2d00}', '\\u{2d25}',  Script::Georgian), ('\\u{2d27}', '\\u{2d27}',\n         Script::Georgian), ('\\u{2d2d}', '\\u{2d2d}',  Script::Georgian), ('\\u{2d30}', '\\u{2d67}',\n         Script::Tifinagh), ('\\u{2d6f}', '\\u{2d6f}',  Script::Tifinagh), ('\\u{2d70}', '\\u{2d70}',\n         Script::Tifinagh), ('\\u{2d7f}', '\\u{2d7f}',  Script::Tifinagh), ('\\u{2d80}', '\\u{2d96}',\n         Script::Ethiopic), ('\\u{2da0}', '\\u{2da6}',  Script::Ethiopic), ('\\u{2da8}', '\\u{2dae}',\n         Script::Ethiopic), ('\\u{2db0}', '\\u{2db6}',  Script::Ethiopic), ('\\u{2db8}', '\\u{2dbe}',\n         Script::Ethiopic), ('\\u{2dc0}', '\\u{2dc6}',  Script::Ethiopic), ('\\u{2dc8}', '\\u{2dce}',\n         Script::Ethiopic), ('\\u{2dd0}', '\\u{2dd6}',  Script::Ethiopic), ('\\u{2dd8}', '\\u{2dde}',\n         Script::Ethiopic), ('\\u{2de0}', '\\u{2dff}',  Script::Cyrillic), ('\\u{2e00}', '\\u{2e01}',\n         Script::Common), ('\\u{2e02}', '\\u{2e02}',  Script::Common), ('\\u{2e03}', '\\u{2e03}',\n         Script::Common), ('\\u{2e04}', '\\u{2e04}',  Script::Common), ('\\u{2e05}', '\\u{2e05}',\n         Script::Common), ('\\u{2e06}', '\\u{2e08}',  Script::Common), ('\\u{2e09}', '\\u{2e09}',\n         Script::Common), ('\\u{2e0a}', '\\u{2e0a}',  Script::Common), ('\\u{2e0b}', '\\u{2e0b}',\n         Script::Common), ('\\u{2e0c}', '\\u{2e0c}',  Script::Common), ('\\u{2e0d}', '\\u{2e0d}',\n         Script::Common), ('\\u{2e0e}', '\\u{2e16}',  Script::Common), ('\\u{2e17}', '\\u{2e17}',\n         Script::Common), ('\\u{2e18}', '\\u{2e19}',  Script::Common), ('\\u{2e1a}', '\\u{2e1a}',\n         Script::Common), ('\\u{2e1b}', '\\u{2e1b}',  Script::Common), ('\\u{2e1c}', '\\u{2e1c}',\n         Script::Common), ('\\u{2e1d}', '\\u{2e1d}',  Script::Common), ('\\u{2e1e}', '\\u{2e1f}',\n         Script::Common), ('\\u{2e20}', '\\u{2e20}',  Script::Common), ('\\u{2e21}', '\\u{2e21}',\n         Script::Common), ('\\u{2e22}', '\\u{2e22}',  Script::Common), ('\\u{2e23}', '\\u{2e23}',\n         Script::Common), ('\\u{2e24}', '\\u{2e24}',  Script::Common), ('\\u{2e25}', '\\u{2e25}',\n         Script::Common), ('\\u{2e26}', '\\u{2e26}',  Script::Common), ('\\u{2e27}', '\\u{2e27}',\n         Script::Common), ('\\u{2e28}', '\\u{2e28}',  Script::Common), ('\\u{2e29}', '\\u{2e29}',\n         Script::Common), ('\\u{2e2a}', '\\u{2e2e}',  Script::Common), ('\\u{2e2f}', '\\u{2e2f}',\n         Script::Common), ('\\u{2e30}', '\\u{2e39}',  Script::Common), ('\\u{2e3a}', '\\u{2e3b}',\n         Script::Common), ('\\u{2e3c}', '\\u{2e3f}',  Script::Common), ('\\u{2e40}', '\\u{2e40}',\n         Script::Common), ('\\u{2e41}', '\\u{2e41}',  Script::Common), ('\\u{2e42}', '\\u{2e42}',\n         Script::Common), ('\\u{2e43}', '\\u{2e4f}',  Script::Common), ('\\u{2e50}', '\\u{2e51}',\n         Script::Common), ('\\u{2e52}', '\\u{2e54}',  Script::Common), ('\\u{2e55}', '\\u{2e55}',\n         Script::Common), ('\\u{2e56}', '\\u{2e56}',  Script::Common), ('\\u{2e57}', '\\u{2e57}',\n         Script::Common), ('\\u{2e58}', '\\u{2e58}',  Script::Common), ('\\u{2e59}', '\\u{2e59}',\n         Script::Common), ('\\u{2e5a}', '\\u{2e5a}',  Script::Common), ('\\u{2e5b}', '\\u{2e5b}',\n         Script::Common), ('\\u{2e5c}', '\\u{2e5c}',  Script::Common), ('\\u{2e5d}', '\\u{2e5d}',\n         Script::Common), ('\\u{2e80}', '\\u{2e99}',  Script::Han), ('\\u{2e9b}', '\\u{2ef3}',\n         Script::Han), ('\\u{2f00}', '\\u{2fd5}',  Script::Han), ('\\u{2ff0}', '\\u{2fff}',\n         Script::Common), ('\\u{3000}', '\\u{3000}',  Script::Common), ('\\u{3001}', '\\u{3003}',\n         Script::Common), ('\\u{3004}', '\\u{3004}',  Script::Common), ('\\u{3005}', '\\u{3005}',\n         Script::Han), ('\\u{3006}', '\\u{3006}',  Script::Common), ('\\u{3007}', '\\u{3007}',\n         Script::Han), ('\\u{3008}', '\\u{3008}',  Script::Common), ('\\u{3009}', '\\u{3009}',\n         Script::Common), ('\\u{300a}', '\\u{300a}',  Script::Common), ('\\u{300b}', '\\u{300b}',\n         Script::Common), ('\\u{300c}', '\\u{300c}',  Script::Common), ('\\u{300d}', '\\u{300d}',\n         Script::Common), ('\\u{300e}', '\\u{300e}',  Script::Common), ('\\u{300f}', '\\u{300f}',\n         Script::Common), ('\\u{3010}', '\\u{3010}',  Script::Common), ('\\u{3011}', '\\u{3011}',\n         Script::Common), ('\\u{3012}', '\\u{3013}',  Script::Common), ('\\u{3014}', '\\u{3014}',\n         Script::Common), ('\\u{3015}', '\\u{3015}',  Script::Common), ('\\u{3016}', '\\u{3016}',\n         Script::Common), ('\\u{3017}', '\\u{3017}',  Script::Common), ('\\u{3018}', '\\u{3018}',\n         Script::Common), ('\\u{3019}', '\\u{3019}',  Script::Common), ('\\u{301a}', '\\u{301a}',\n         Script::Common), ('\\u{301b}', '\\u{301b}',  Script::Common), ('\\u{301c}', '\\u{301c}',\n         Script::Common), ('\\u{301d}', '\\u{301d}',  Script::Common), ('\\u{301e}', '\\u{301f}',\n         Script::Common), ('\\u{3020}', '\\u{3020}',  Script::Common), ('\\u{3021}', '\\u{3029}',\n         Script::Han), ('\\u{302a}', '\\u{302d}',  Script::Inherited), ('\\u{302e}', '\\u{302f}',\n         Script::Hangul), ('\\u{3030}', '\\u{3030}',  Script::Common), ('\\u{3031}', '\\u{3035}',\n         Script::Common), ('\\u{3036}', '\\u{3037}',  Script::Common), ('\\u{3038}', '\\u{303a}',\n         Script::Han), ('\\u{303b}', '\\u{303b}',  Script::Han), ('\\u{303c}', '\\u{303c}',\n         Script::Common), ('\\u{303d}', '\\u{303d}',  Script::Common), ('\\u{303e}', '\\u{303f}',\n         Script::Common), ('\\u{3041}', '\\u{3096}',  Script::Hiragana), ('\\u{3099}', '\\u{309a}',\n         Script::Inherited), ('\\u{309b}', '\\u{309c}',  Script::Common), ('\\u{309d}', '\\u{309e}',\n         Script::Hiragana), ('\\u{309f}', '\\u{309f}',  Script::Hiragana), ('\\u{30a0}', '\\u{30a0}',\n         Script::Common), ('\\u{30a1}', '\\u{30fa}',  Script::Katakana), ('\\u{30fb}', '\\u{30fb}',\n         Script::Common), ('\\u{30fc}', '\\u{30fc}',  Script::Common), ('\\u{30fd}', '\\u{30fe}',\n         Script::Katakana), ('\\u{30ff}', '\\u{30ff}',  Script::Katakana), ('\\u{3105}', '\\u{312f}',\n         Script::Bopomofo), ('\\u{3131}', '\\u{318e}',  Script::Hangul), ('\\u{3190}', '\\u{3191}',\n         Script::Common), ('\\u{3192}', '\\u{3195}',  Script::Common), ('\\u{3196}', '\\u{319f}',\n         Script::Common), ('\\u{31a0}', '\\u{31bf}',  Script::Bopomofo), ('\\u{31c0}', '\\u{31e5}',\n         Script::Common), ('\\u{31ef}', '\\u{31ef}',  Script::Common), ('\\u{31f0}', '\\u{31ff}',\n         Script::Katakana), ('\\u{3200}', '\\u{321e}',  Script::Hangul), ('\\u{3220}', '\\u{3229}',\n         Script::Common), ('\\u{322a}', '\\u{3247}',  Script::Common), ('\\u{3248}', '\\u{324f}',\n         Script::Common), ('\\u{3250}', '\\u{3250}',  Script::Common), ('\\u{3251}', '\\u{325f}',\n         Script::Common), ('\\u{3260}', '\\u{327e}',  Script::Hangul), ('\\u{327f}', '\\u{327f}',\n         Script::Common), ('\\u{3280}', '\\u{3289}',  Script::Common), ('\\u{328a}', '\\u{32b0}',\n         Script::Common), ('\\u{32b1}', '\\u{32bf}',  Script::Common), ('\\u{32c0}', '\\u{32cf}',\n         Script::Common), ('\\u{32d0}', '\\u{32fe}',  Script::Katakana), ('\\u{32ff}', '\\u{32ff}',\n         Script::Common), ('\\u{3300}', '\\u{3357}',  Script::Katakana), ('\\u{3358}', '\\u{33ff}',\n         Script::Common), ('\\u{3400}', '\\u{4dbf}',  Script::Han), ('\\u{4dc0}', '\\u{4dff}',\n         Script::Common), ('\\u{4e00}', '\\u{9fff}',  Script::Han), ('\\u{a000}', '\\u{a014}',\n         Script::Yi), ('\\u{a015}', '\\u{a015}',  Script::Yi), ('\\u{a016}', '\\u{a48c}',  Script::Yi),\n        ('\\u{a490}', '\\u{a4c6}',  Script::Yi), ('\\u{a4d0}', '\\u{a4f7}',  Script::Lisu), ('\\u{a4f8}',\n        '\\u{a4fd}',  Script::Lisu), ('\\u{a4fe}', '\\u{a4ff}',  Script::Lisu), ('\\u{a500}',\n        '\\u{a60b}',  Script::Vai), ('\\u{a60c}', '\\u{a60c}',  Script::Vai), ('\\u{a60d}', '\\u{a60f}',\n         Script::Vai), ('\\u{a610}', '\\u{a61f}',  Script::Vai), ('\\u{a620}', '\\u{a629}',\n         Script::Vai), ('\\u{a62a}', '\\u{a62b}',  Script::Vai), ('\\u{a640}', '\\u{a66d}',\n         Script::Cyrillic), ('\\u{a66e}', '\\u{a66e}',  Script::Cyrillic), ('\\u{a66f}', '\\u{a66f}',\n         Script::Cyrillic), ('\\u{a670}', '\\u{a672}',  Script::Cyrillic), ('\\u{a673}', '\\u{a673}',\n         Script::Cyrillic), ('\\u{a674}', '\\u{a67d}',  Script::Cyrillic), ('\\u{a67e}', '\\u{a67e}',\n         Script::Cyrillic), ('\\u{a67f}', '\\u{a67f}',  Script::Cyrillic), ('\\u{a680}', '\\u{a69b}',\n         Script::Cyrillic), ('\\u{a69c}', '\\u{a69d}',  Script::Cyrillic), ('\\u{a69e}', '\\u{a69f}',\n         Script::Cyrillic), ('\\u{a6a0}', '\\u{a6e5}',  Script::Bamum), ('\\u{a6e6}', '\\u{a6ef}',\n         Script::Bamum), ('\\u{a6f0}', '\\u{a6f1}',  Script::Bamum), ('\\u{a6f2}', '\\u{a6f7}',\n         Script::Bamum), ('\\u{a700}', '\\u{a716}',  Script::Common), ('\\u{a717}', '\\u{a71f}',\n         Script::Common), ('\\u{a720}', '\\u{a721}',  Script::Common), ('\\u{a722}', '\\u{a76f}',\n         Script::Latin), ('\\u{a770}', '\\u{a770}',  Script::Latin), ('\\u{a771}', '\\u{a787}',\n         Script::Latin), ('\\u{a788}', '\\u{a788}',  Script::Common), ('\\u{a789}', '\\u{a78a}',\n         Script::Common), ('\\u{a78b}', '\\u{a78e}',  Script::Latin), ('\\u{a78f}', '\\u{a78f}',\n         Script::Latin), ('\\u{a790}', '\\u{a7dc}',  Script::Latin), ('\\u{a7f1}', '\\u{a7f4}',\n         Script::Latin), ('\\u{a7f5}', '\\u{a7f6}',  Script::Latin), ('\\u{a7f7}', '\\u{a7f7}',\n         Script::Latin), ('\\u{a7f8}', '\\u{a7f9}',  Script::Latin), ('\\u{a7fa}', '\\u{a7fa}',\n         Script::Latin), ('\\u{a7fb}', '\\u{a7ff}',  Script::Latin), ('\\u{a800}', '\\u{a801}',\n         Script::Syloti_Nagri), ('\\u{a802}', '\\u{a802}',  Script::Syloti_Nagri), ('\\u{a803}',\n        '\\u{a805}',  Script::Syloti_Nagri), ('\\u{a806}', '\\u{a806}',  Script::Syloti_Nagri),\n        ('\\u{a807}', '\\u{a80a}',  Script::Syloti_Nagri), ('\\u{a80b}', '\\u{a80b}',\n         Script::Syloti_Nagri), ('\\u{a80c}', '\\u{a822}',  Script::Syloti_Nagri), ('\\u{a823}',\n        '\\u{a824}',  Script::Syloti_Nagri), ('\\u{a825}', '\\u{a826}',  Script::Syloti_Nagri),\n        ('\\u{a827}', '\\u{a827}',  Script::Syloti_Nagri), ('\\u{a828}', '\\u{a82b}',\n         Script::Syloti_Nagri), ('\\u{a82c}', '\\u{a82c}',  Script::Syloti_Nagri), ('\\u{a830}',\n        '\\u{a835}',  Script::Common), ('\\u{a836}', '\\u{a837}',  Script::Common), ('\\u{a838}',\n        '\\u{a838}',  Script::Common), ('\\u{a839}', '\\u{a839}',  Script::Common), ('\\u{a840}',\n        '\\u{a873}',  Script::Phags_Pa), ('\\u{a874}', '\\u{a877}',  Script::Phags_Pa), ('\\u{a880}',\n        '\\u{a881}',  Script::Saurashtra), ('\\u{a882}', '\\u{a8b3}',  Script::Saurashtra),\n        ('\\u{a8b4}', '\\u{a8c3}',  Script::Saurashtra), ('\\u{a8c4}', '\\u{a8c5}',\n         Script::Saurashtra), ('\\u{a8ce}', '\\u{a8cf}',  Script::Saurashtra), ('\\u{a8d0}',\n        '\\u{a8d9}',  Script::Saurashtra), ('\\u{a8e0}', '\\u{a8f1}',  Script::Devanagari),\n        ('\\u{a8f2}', '\\u{a8f7}',  Script::Devanagari), ('\\u{a8f8}', '\\u{a8fa}',\n         Script::Devanagari), ('\\u{a8fb}', '\\u{a8fb}',  Script::Devanagari), ('\\u{a8fc}',\n        '\\u{a8fc}',  Script::Devanagari), ('\\u{a8fd}', '\\u{a8fe}',  Script::Devanagari),\n        ('\\u{a8ff}', '\\u{a8ff}',  Script::Devanagari), ('\\u{a900}', '\\u{a909}',  Script::Kayah_Li),\n        ('\\u{a90a}', '\\u{a925}',  Script::Kayah_Li), ('\\u{a926}', '\\u{a92d}',  Script::Kayah_Li),\n        ('\\u{a92e}', '\\u{a92e}',  Script::Common), ('\\u{a92f}', '\\u{a92f}',  Script::Kayah_Li),\n        ('\\u{a930}', '\\u{a946}',  Script::Rejang), ('\\u{a947}', '\\u{a951}',  Script::Rejang),\n        ('\\u{a952}', '\\u{a953}',  Script::Rejang), ('\\u{a95f}', '\\u{a95f}',  Script::Rejang),\n        ('\\u{a960}', '\\u{a97c}',  Script::Hangul), ('\\u{a980}', '\\u{a982}',  Script::Javanese),\n        ('\\u{a983}', '\\u{a983}',  Script::Javanese), ('\\u{a984}', '\\u{a9b2}',  Script::Javanese),\n        ('\\u{a9b3}', '\\u{a9b3}',  Script::Javanese), ('\\u{a9b4}', '\\u{a9b5}',  Script::Javanese),\n        ('\\u{a9b6}', '\\u{a9b9}',  Script::Javanese), ('\\u{a9ba}', '\\u{a9bb}',  Script::Javanese),\n        ('\\u{a9bc}', '\\u{a9bd}',  Script::Javanese), ('\\u{a9be}', '\\u{a9c0}',  Script::Javanese),\n        ('\\u{a9c1}', '\\u{a9cd}',  Script::Javanese), ('\\u{a9cf}', '\\u{a9cf}',  Script::Common),\n        ('\\u{a9d0}', '\\u{a9d9}',  Script::Javanese), ('\\u{a9de}', '\\u{a9df}',  Script::Javanese),\n        ('\\u{a9e0}', '\\u{a9e4}',  Script::Myanmar), ('\\u{a9e5}', '\\u{a9e5}',  Script::Myanmar),\n        ('\\u{a9e6}', '\\u{a9e6}',  Script::Myanmar), ('\\u{a9e7}', '\\u{a9ef}',  Script::Myanmar),\n        ('\\u{a9f0}', '\\u{a9f9}',  Script::Myanmar), ('\\u{a9fa}', '\\u{a9fe}',  Script::Myanmar),\n        ('\\u{aa00}', '\\u{aa28}',  Script::Cham), ('\\u{aa29}', '\\u{aa2e}',  Script::Cham),\n        ('\\u{aa2f}', '\\u{aa30}',  Script::Cham), ('\\u{aa31}', '\\u{aa32}',  Script::Cham),\n        ('\\u{aa33}', '\\u{aa34}',  Script::Cham), ('\\u{aa35}', '\\u{aa36}',  Script::Cham),\n        ('\\u{aa40}', '\\u{aa42}',  Script::Cham), ('\\u{aa43}', '\\u{aa43}',  Script::Cham),\n        ('\\u{aa44}', '\\u{aa4b}',  Script::Cham), ('\\u{aa4c}', '\\u{aa4c}',  Script::Cham),\n        ('\\u{aa4d}', '\\u{aa4d}',  Script::Cham), ('\\u{aa50}', '\\u{aa59}',  Script::Cham),\n        ('\\u{aa5c}', '\\u{aa5f}',  Script::Cham), ('\\u{aa60}', '\\u{aa6f}',  Script::Myanmar),\n        ('\\u{aa70}', '\\u{aa70}',  Script::Myanmar), ('\\u{aa71}', '\\u{aa76}',  Script::Myanmar),\n        ('\\u{aa77}', '\\u{aa79}',  Script::Myanmar), ('\\u{aa7a}', '\\u{aa7a}',  Script::Myanmar),\n        ('\\u{aa7b}', '\\u{aa7b}',  Script::Myanmar), ('\\u{aa7c}', '\\u{aa7c}',  Script::Myanmar),\n        ('\\u{aa7d}', '\\u{aa7d}',  Script::Myanmar), ('\\u{aa7e}', '\\u{aa7f}',  Script::Myanmar),\n        ('\\u{aa80}', '\\u{aaaf}',  Script::Tai_Viet), ('\\u{aab0}', '\\u{aab0}',  Script::Tai_Viet),\n        ('\\u{aab1}', '\\u{aab1}',  Script::Tai_Viet), ('\\u{aab2}', '\\u{aab4}',  Script::Tai_Viet),\n        ('\\u{aab5}', '\\u{aab6}',  Script::Tai_Viet), ('\\u{aab7}', '\\u{aab8}',  Script::Tai_Viet),\n        ('\\u{aab9}', '\\u{aabd}',  Script::Tai_Viet), ('\\u{aabe}', '\\u{aabf}',  Script::Tai_Viet),\n        ('\\u{aac0}', '\\u{aac0}',  Script::Tai_Viet), ('\\u{aac1}', '\\u{aac1}',  Script::Tai_Viet),\n        ('\\u{aac2}', '\\u{aac2}',  Script::Tai_Viet), ('\\u{aadb}', '\\u{aadc}',  Script::Tai_Viet),\n        ('\\u{aadd}', '\\u{aadd}',  Script::Tai_Viet), ('\\u{aade}', '\\u{aadf}',  Script::Tai_Viet),\n        ('\\u{aae0}', '\\u{aaea}',  Script::Meetei_Mayek), ('\\u{aaeb}', '\\u{aaeb}',\n         Script::Meetei_Mayek), ('\\u{aaec}', '\\u{aaed}',  Script::Meetei_Mayek), ('\\u{aaee}',\n        '\\u{aaef}',  Script::Meetei_Mayek), ('\\u{aaf0}', '\\u{aaf1}',  Script::Meetei_Mayek),\n        ('\\u{aaf2}', '\\u{aaf2}',  Script::Meetei_Mayek), ('\\u{aaf3}', '\\u{aaf4}',\n         Script::Meetei_Mayek), ('\\u{aaf5}', '\\u{aaf5}',  Script::Meetei_Mayek), ('\\u{aaf6}',\n        '\\u{aaf6}',  Script::Meetei_Mayek), ('\\u{ab01}', '\\u{ab06}',  Script::Ethiopic),\n        ('\\u{ab09}', '\\u{ab0e}',  Script::Ethiopic), ('\\u{ab11}', '\\u{ab16}',  Script::Ethiopic),\n        ('\\u{ab20}', '\\u{ab26}',  Script::Ethiopic), ('\\u{ab28}', '\\u{ab2e}',  Script::Ethiopic),\n        ('\\u{ab30}', '\\u{ab5a}',  Script::Latin), ('\\u{ab5b}', '\\u{ab5b}',  Script::Common),\n        ('\\u{ab5c}', '\\u{ab5f}',  Script::Latin), ('\\u{ab60}', '\\u{ab64}',  Script::Latin),\n        ('\\u{ab65}', '\\u{ab65}',  Script::Greek), ('\\u{ab66}', '\\u{ab68}',  Script::Latin),\n        ('\\u{ab69}', '\\u{ab69}',  Script::Latin), ('\\u{ab6a}', '\\u{ab6b}',  Script::Common),\n        ('\\u{ab70}', '\\u{abbf}',  Script::Cherokee), ('\\u{abc0}', '\\u{abe2}',\n         Script::Meetei_Mayek), ('\\u{abe3}', '\\u{abe4}',  Script::Meetei_Mayek), ('\\u{abe5}',\n        '\\u{abe5}',  Script::Meetei_Mayek), ('\\u{abe6}', '\\u{abe7}',  Script::Meetei_Mayek),\n        ('\\u{abe8}', '\\u{abe8}',  Script::Meetei_Mayek), ('\\u{abe9}', '\\u{abea}',\n         Script::Meetei_Mayek), ('\\u{abeb}', '\\u{abeb}',  Script::Meetei_Mayek), ('\\u{abec}',\n        '\\u{abec}',  Script::Meetei_Mayek), ('\\u{abed}', '\\u{abed}',  Script::Meetei_Mayek),\n        ('\\u{abf0}', '\\u{abf9}',  Script::Meetei_Mayek), ('\\u{ac00}', '\\u{d7a3}',  Script::Hangul),\n        ('\\u{d7b0}', '\\u{d7c6}',  Script::Hangul), ('\\u{d7cb}', '\\u{d7fb}',  Script::Hangul),\n        ('\\u{f900}', '\\u{fa6d}',  Script::Han), ('\\u{fa70}', '\\u{fad9}',  Script::Han), ('\\u{fb00}',\n        '\\u{fb06}',  Script::Latin), ('\\u{fb13}', '\\u{fb17}',  Script::Armenian), ('\\u{fb1d}',\n        '\\u{fb1d}',  Script::Hebrew), ('\\u{fb1e}', '\\u{fb1e}',  Script::Hebrew), ('\\u{fb1f}',\n        '\\u{fb28}',  Script::Hebrew), ('\\u{fb29}', '\\u{fb29}',  Script::Hebrew), ('\\u{fb2a}',\n        '\\u{fb36}',  Script::Hebrew), ('\\u{fb38}', '\\u{fb3c}',  Script::Hebrew), ('\\u{fb3e}',\n        '\\u{fb3e}',  Script::Hebrew), ('\\u{fb40}', '\\u{fb41}',  Script::Hebrew), ('\\u{fb43}',\n        '\\u{fb44}',  Script::Hebrew), ('\\u{fb46}', '\\u{fb4f}',  Script::Hebrew), ('\\u{fb50}',\n        '\\u{fbb1}',  Script::Arabic), ('\\u{fbb2}', '\\u{fbc2}',  Script::Arabic), ('\\u{fbc3}',\n        '\\u{fbd2}',  Script::Arabic), ('\\u{fbd3}', '\\u{fd3d}',  Script::Arabic), ('\\u{fd3e}',\n        '\\u{fd3e}',  Script::Common), ('\\u{fd3f}', '\\u{fd3f}',  Script::Common), ('\\u{fd40}',\n        '\\u{fd4f}',  Script::Arabic), ('\\u{fd50}', '\\u{fd8f}',  Script::Arabic), ('\\u{fd90}',\n        '\\u{fd91}',  Script::Arabic), ('\\u{fd92}', '\\u{fdc7}',  Script::Arabic), ('\\u{fdc8}',\n        '\\u{fdcf}',  Script::Arabic), ('\\u{fdf0}', '\\u{fdfb}',  Script::Arabic), ('\\u{fdfc}',\n        '\\u{fdfc}',  Script::Arabic), ('\\u{fdfd}', '\\u{fdff}',  Script::Arabic), ('\\u{fe00}',\n        '\\u{fe0f}',  Script::Inherited), ('\\u{fe10}', '\\u{fe16}',  Script::Common), ('\\u{fe17}',\n        '\\u{fe17}',  Script::Common), ('\\u{fe18}', '\\u{fe18}',  Script::Common), ('\\u{fe19}',\n        '\\u{fe19}',  Script::Common), ('\\u{fe20}', '\\u{fe2d}',  Script::Inherited), ('\\u{fe2e}',\n        '\\u{fe2f}',  Script::Cyrillic), ('\\u{fe30}', '\\u{fe30}',  Script::Common), ('\\u{fe31}',\n        '\\u{fe32}',  Script::Common), ('\\u{fe33}', '\\u{fe34}',  Script::Common), ('\\u{fe35}',\n        '\\u{fe35}',  Script::Common), ('\\u{fe36}', '\\u{fe36}',  Script::Common), ('\\u{fe37}',\n        '\\u{fe37}',  Script::Common), ('\\u{fe38}', '\\u{fe38}',  Script::Common), ('\\u{fe39}',\n        '\\u{fe39}',  Script::Common), ('\\u{fe3a}', '\\u{fe3a}',  Script::Common), ('\\u{fe3b}',\n        '\\u{fe3b}',  Script::Common), ('\\u{fe3c}', '\\u{fe3c}',  Script::Common), ('\\u{fe3d}',\n        '\\u{fe3d}',  Script::Common), ('\\u{fe3e}', '\\u{fe3e}',  Script::Common), ('\\u{fe3f}',\n        '\\u{fe3f}',  Script::Common), ('\\u{fe40}', '\\u{fe40}',  Script::Common), ('\\u{fe41}',\n        '\\u{fe41}',  Script::Common), ('\\u{fe42}', '\\u{fe42}',  Script::Common), ('\\u{fe43}',\n        '\\u{fe43}',  Script::Common), ('\\u{fe44}', '\\u{fe44}',  Script::Common), ('\\u{fe45}',\n        '\\u{fe46}',  Script::Common), ('\\u{fe47}', '\\u{fe47}',  Script::Common), ('\\u{fe48}',\n        '\\u{fe48}',  Script::Common), ('\\u{fe49}', '\\u{fe4c}',  Script::Common), ('\\u{fe4d}',\n        '\\u{fe4f}',  Script::Common), ('\\u{fe50}', '\\u{fe52}',  Script::Common), ('\\u{fe54}',\n        '\\u{fe57}',  Script::Common), ('\\u{fe58}', '\\u{fe58}',  Script::Common), ('\\u{fe59}',\n        '\\u{fe59}',  Script::Common), ('\\u{fe5a}', '\\u{fe5a}',  Script::Common), ('\\u{fe5b}',\n        '\\u{fe5b}',  Script::Common), ('\\u{fe5c}', '\\u{fe5c}',  Script::Common), ('\\u{fe5d}',\n        '\\u{fe5d}',  Script::Common), ('\\u{fe5e}', '\\u{fe5e}',  Script::Common), ('\\u{fe5f}',\n        '\\u{fe61}',  Script::Common), ('\\u{fe62}', '\\u{fe62}',  Script::Common), ('\\u{fe63}',\n        '\\u{fe63}',  Script::Common), ('\\u{fe64}', '\\u{fe66}',  Script::Common), ('\\u{fe68}',\n        '\\u{fe68}',  Script::Common), ('\\u{fe69}', '\\u{fe69}',  Script::Common), ('\\u{fe6a}',\n        '\\u{fe6b}',  Script::Common), ('\\u{fe70}', '\\u{fe74}',  Script::Arabic), ('\\u{fe76}',\n        '\\u{fefc}',  Script::Arabic), ('\\u{feff}', '\\u{feff}',  Script::Common), ('\\u{ff01}',\n        '\\u{ff03}',  Script::Common), ('\\u{ff04}', '\\u{ff04}',  Script::Common), ('\\u{ff05}',\n        '\\u{ff07}',  Script::Common), ('\\u{ff08}', '\\u{ff08}',  Script::Common), ('\\u{ff09}',\n        '\\u{ff09}',  Script::Common), ('\\u{ff0a}', '\\u{ff0a}',  Script::Common), ('\\u{ff0b}',\n        '\\u{ff0b}',  Script::Common), ('\\u{ff0c}', '\\u{ff0c}',  Script::Common), ('\\u{ff0d}',\n        '\\u{ff0d}',  Script::Common), ('\\u{ff0e}', '\\u{ff0f}',  Script::Common), ('\\u{ff10}',\n        '\\u{ff19}',  Script::Common), ('\\u{ff1a}', '\\u{ff1b}',  Script::Common), ('\\u{ff1c}',\n        '\\u{ff1e}',  Script::Common), ('\\u{ff1f}', '\\u{ff20}',  Script::Common), ('\\u{ff21}',\n        '\\u{ff3a}',  Script::Latin), ('\\u{ff3b}', '\\u{ff3b}',  Script::Common), ('\\u{ff3c}',\n        '\\u{ff3c}',  Script::Common), ('\\u{ff3d}', '\\u{ff3d}',  Script::Common), ('\\u{ff3e}',\n        '\\u{ff3e}',  Script::Common), ('\\u{ff3f}', '\\u{ff3f}',  Script::Common), ('\\u{ff40}',\n        '\\u{ff40}',  Script::Common), ('\\u{ff41}', '\\u{ff5a}',  Script::Latin), ('\\u{ff5b}',\n        '\\u{ff5b}',  Script::Common), ('\\u{ff5c}', '\\u{ff5c}',  Script::Common), ('\\u{ff5d}',\n        '\\u{ff5d}',  Script::Common), ('\\u{ff5e}', '\\u{ff5e}',  Script::Common), ('\\u{ff5f}',\n        '\\u{ff5f}',  Script::Common), ('\\u{ff60}', '\\u{ff60}',  Script::Common), ('\\u{ff61}',\n        '\\u{ff61}',  Script::Common), ('\\u{ff62}', '\\u{ff62}',  Script::Common), ('\\u{ff63}',\n        '\\u{ff63}',  Script::Common), ('\\u{ff64}', '\\u{ff65}',  Script::Common), ('\\u{ff66}',\n        '\\u{ff6f}',  Script::Katakana), ('\\u{ff70}', '\\u{ff70}',  Script::Common), ('\\u{ff71}',\n        '\\u{ff9d}',  Script::Katakana), ('\\u{ff9e}', '\\u{ff9f}',  Script::Common), ('\\u{ffa0}',\n        '\\u{ffbe}',  Script::Hangul), ('\\u{ffc2}', '\\u{ffc7}',  Script::Hangul), ('\\u{ffca}',\n        '\\u{ffcf}',  Script::Hangul), ('\\u{ffd2}', '\\u{ffd7}',  Script::Hangul), ('\\u{ffda}',\n        '\\u{ffdc}',  Script::Hangul), ('\\u{ffe0}', '\\u{ffe1}',  Script::Common), ('\\u{ffe2}',\n        '\\u{ffe2}',  Script::Common), ('\\u{ffe3}', '\\u{ffe3}',  Script::Common), ('\\u{ffe4}',\n        '\\u{ffe4}',  Script::Common), ('\\u{ffe5}', '\\u{ffe6}',  Script::Common), ('\\u{ffe8}',\n        '\\u{ffe8}',  Script::Common), ('\\u{ffe9}', '\\u{ffec}',  Script::Common), ('\\u{ffed}',\n        '\\u{ffee}',  Script::Common), ('\\u{fff9}', '\\u{fffb}',  Script::Common), ('\\u{fffc}',\n        '\\u{fffd}',  Script::Common), ('\\u{10000}', '\\u{1000b}',  Script::Linear_B), ('\\u{1000d}',\n        '\\u{10026}',  Script::Linear_B), ('\\u{10028}', '\\u{1003a}',  Script::Linear_B),\n        ('\\u{1003c}', '\\u{1003d}',  Script::Linear_B), ('\\u{1003f}', '\\u{1004d}',\n         Script::Linear_B), ('\\u{10050}', '\\u{1005d}',  Script::Linear_B), ('\\u{10080}',\n        '\\u{100fa}',  Script::Linear_B), ('\\u{10100}', '\\u{10102}',  Script::Common), ('\\u{10107}',\n        '\\u{10133}',  Script::Common), ('\\u{10137}', '\\u{1013f}',  Script::Common), ('\\u{10140}',\n        '\\u{10174}',  Script::Greek), ('\\u{10175}', '\\u{10178}',  Script::Greek), ('\\u{10179}',\n        '\\u{10189}',  Script::Greek), ('\\u{1018a}', '\\u{1018b}',  Script::Greek), ('\\u{1018c}',\n        '\\u{1018e}',  Script::Greek), ('\\u{10190}', '\\u{1019c}',  Script::Common), ('\\u{101a0}',\n        '\\u{101a0}',  Script::Greek), ('\\u{101d0}', '\\u{101fc}',  Script::Common), ('\\u{101fd}',\n        '\\u{101fd}',  Script::Inherited), ('\\u{10280}', '\\u{1029c}',  Script::Lycian), ('\\u{102a0}',\n        '\\u{102d0}',  Script::Carian), ('\\u{102e0}', '\\u{102e0}',  Script::Inherited), ('\\u{102e1}',\n        '\\u{102fb}',  Script::Common), ('\\u{10300}', '\\u{1031f}',  Script::Old_Italic),\n        ('\\u{10320}', '\\u{10323}',  Script::Old_Italic), ('\\u{1032d}', '\\u{1032f}',\n         Script::Old_Italic), ('\\u{10330}', '\\u{10340}',  Script::Gothic), ('\\u{10341}',\n        '\\u{10341}',  Script::Gothic), ('\\u{10342}', '\\u{10349}',  Script::Gothic), ('\\u{1034a}',\n        '\\u{1034a}',  Script::Gothic), ('\\u{10350}', '\\u{10375}',  Script::Old_Permic),\n        ('\\u{10376}', '\\u{1037a}',  Script::Old_Permic), ('\\u{10380}', '\\u{1039d}',\n         Script::Ugaritic), ('\\u{1039f}', '\\u{1039f}',  Script::Ugaritic), ('\\u{103a0}',\n        '\\u{103c3}',  Script::Old_Persian), ('\\u{103c8}', '\\u{103cf}',  Script::Old_Persian),\n        ('\\u{103d0}', '\\u{103d0}',  Script::Old_Persian), ('\\u{103d1}', '\\u{103d5}',\n         Script::Old_Persian), ('\\u{10400}', '\\u{1044f}',  Script::Deseret), ('\\u{10450}',\n        '\\u{1047f}',  Script::Shavian), ('\\u{10480}', '\\u{1049d}',  Script::Osmanya), ('\\u{104a0}',\n        '\\u{104a9}',  Script::Osmanya), ('\\u{104b0}', '\\u{104d3}',  Script::Osage), ('\\u{104d8}',\n        '\\u{104fb}',  Script::Osage), ('\\u{10500}', '\\u{10527}',  Script::Elbasan), ('\\u{10530}',\n        '\\u{10563}',  Script::Caucasian_Albanian), ('\\u{1056f}', '\\u{1056f}',\n         Script::Caucasian_Albanian), ('\\u{10570}', '\\u{1057a}',  Script::Vithkuqi), ('\\u{1057c}',\n        '\\u{1058a}',  Script::Vithkuqi), ('\\u{1058c}', '\\u{10592}',  Script::Vithkuqi),\n        ('\\u{10594}', '\\u{10595}',  Script::Vithkuqi), ('\\u{10597}', '\\u{105a1}',\n         Script::Vithkuqi), ('\\u{105a3}', '\\u{105b1}',  Script::Vithkuqi), ('\\u{105b3}',\n        '\\u{105b9}',  Script::Vithkuqi), ('\\u{105bb}', '\\u{105bc}',  Script::Vithkuqi),\n        ('\\u{105c0}', '\\u{105f3}',  Script::Todhri), ('\\u{10600}', '\\u{10736}',  Script::Linear_A),\n        ('\\u{10740}', '\\u{10755}',  Script::Linear_A), ('\\u{10760}', '\\u{10767}',\n         Script::Linear_A), ('\\u{10780}', '\\u{10785}',  Script::Latin), ('\\u{10787}', '\\u{107b0}',\n         Script::Latin), ('\\u{107b2}', '\\u{107ba}',  Script::Latin), ('\\u{10800}', '\\u{10805}',\n         Script::Cypriot), ('\\u{10808}', '\\u{10808}',  Script::Cypriot), ('\\u{1080a}', '\\u{10835}',\n         Script::Cypriot), ('\\u{10837}', '\\u{10838}',  Script::Cypriot), ('\\u{1083c}', '\\u{1083c}',\n         Script::Cypriot), ('\\u{1083f}', '\\u{1083f}',  Script::Cypriot), ('\\u{10840}', '\\u{10855}',\n         Script::Imperial_Aramaic), ('\\u{10857}', '\\u{10857}',  Script::Imperial_Aramaic),\n        ('\\u{10858}', '\\u{1085f}',  Script::Imperial_Aramaic), ('\\u{10860}', '\\u{10876}',\n         Script::Palmyrene), ('\\u{10877}', '\\u{10878}',  Script::Palmyrene), ('\\u{10879}',\n        '\\u{1087f}',  Script::Palmyrene), ('\\u{10880}', '\\u{1089e}',  Script::Nabataean),\n        ('\\u{108a7}', '\\u{108af}',  Script::Nabataean), ('\\u{108e0}', '\\u{108f2}',  Script::Hatran),\n        ('\\u{108f4}', '\\u{108f5}',  Script::Hatran), ('\\u{108fb}', '\\u{108ff}',  Script::Hatran),\n        ('\\u{10900}', '\\u{10915}',  Script::Phoenician), ('\\u{10916}', '\\u{1091b}',\n         Script::Phoenician), ('\\u{1091f}', '\\u{1091f}',  Script::Phoenician), ('\\u{10920}',\n        '\\u{10939}',  Script::Lydian), ('\\u{1093f}', '\\u{1093f}',  Script::Lydian), ('\\u{10940}',\n        '\\u{10959}',  Script::Sidetic), ('\\u{10980}', '\\u{1099f}',  Script::Meroitic_Hieroglyphs),\n        ('\\u{109a0}', '\\u{109b7}',  Script::Meroitic_Cursive), ('\\u{109bc}', '\\u{109bd}',\n         Script::Meroitic_Cursive), ('\\u{109be}', '\\u{109bf}',  Script::Meroitic_Cursive),\n        ('\\u{109c0}', '\\u{109cf}',  Script::Meroitic_Cursive), ('\\u{109d2}', '\\u{109ff}',\n         Script::Meroitic_Cursive), ('\\u{10a00}', '\\u{10a00}',  Script::Kharoshthi), ('\\u{10a01}',\n        '\\u{10a03}',  Script::Kharoshthi), ('\\u{10a05}', '\\u{10a06}',  Script::Kharoshthi),\n        ('\\u{10a0c}', '\\u{10a0f}',  Script::Kharoshthi), ('\\u{10a10}', '\\u{10a13}',\n         Script::Kharoshthi), ('\\u{10a15}', '\\u{10a17}',  Script::Kharoshthi), ('\\u{10a19}',\n        '\\u{10a35}',  Script::Kharoshthi), ('\\u{10a38}', '\\u{10a3a}',  Script::Kharoshthi),\n        ('\\u{10a3f}', '\\u{10a3f}',  Script::Kharoshthi), ('\\u{10a40}', '\\u{10a48}',\n         Script::Kharoshthi), ('\\u{10a50}', '\\u{10a58}',  Script::Kharoshthi), ('\\u{10a60}',\n        '\\u{10a7c}',  Script::Old_South_Arabian), ('\\u{10a7d}', '\\u{10a7e}',\n         Script::Old_South_Arabian), ('\\u{10a7f}', '\\u{10a7f}',  Script::Old_South_Arabian),\n        ('\\u{10a80}', '\\u{10a9c}',  Script::Old_North_Arabian), ('\\u{10a9d}', '\\u{10a9f}',\n         Script::Old_North_Arabian), ('\\u{10ac0}', '\\u{10ac7}',  Script::Manichaean), ('\\u{10ac8}',\n        '\\u{10ac8}',  Script::Manichaean), ('\\u{10ac9}', '\\u{10ae4}',  Script::Manichaean),\n        ('\\u{10ae5}', '\\u{10ae6}',  Script::Manichaean), ('\\u{10aeb}', '\\u{10aef}',\n         Script::Manichaean), ('\\u{10af0}', '\\u{10af6}',  Script::Manichaean), ('\\u{10b00}',\n        '\\u{10b35}',  Script::Avestan), ('\\u{10b39}', '\\u{10b3f}',  Script::Avestan), ('\\u{10b40}',\n        '\\u{10b55}',  Script::Inscriptional_Parthian), ('\\u{10b58}', '\\u{10b5f}',\n         Script::Inscriptional_Parthian), ('\\u{10b60}', '\\u{10b72}',\n         Script::Inscriptional_Pahlavi), ('\\u{10b78}', '\\u{10b7f}',  Script::Inscriptional_Pahlavi),\n        ('\\u{10b80}', '\\u{10b91}',  Script::Psalter_Pahlavi), ('\\u{10b99}', '\\u{10b9c}',\n         Script::Psalter_Pahlavi), ('\\u{10ba9}', '\\u{10baf}',  Script::Psalter_Pahlavi),\n        ('\\u{10c00}', '\\u{10c48}',  Script::Old_Turkic), ('\\u{10c80}', '\\u{10cb2}',\n         Script::Old_Hungarian), ('\\u{10cc0}', '\\u{10cf2}',  Script::Old_Hungarian), ('\\u{10cfa}',\n        '\\u{10cff}',  Script::Old_Hungarian), ('\\u{10d00}', '\\u{10d23}',  Script::Hanifi_Rohingya),\n        ('\\u{10d24}', '\\u{10d27}',  Script::Hanifi_Rohingya), ('\\u{10d30}', '\\u{10d39}',\n         Script::Hanifi_Rohingya), ('\\u{10d40}', '\\u{10d49}',  Script::Garay), ('\\u{10d4a}',\n        '\\u{10d4d}',  Script::Garay), ('\\u{10d4e}', '\\u{10d4e}',  Script::Garay), ('\\u{10d4f}',\n        '\\u{10d4f}',  Script::Garay), ('\\u{10d50}', '\\u{10d65}',  Script::Garay), ('\\u{10d69}',\n        '\\u{10d6d}',  Script::Garay), ('\\u{10d6e}', '\\u{10d6e}',  Script::Garay), ('\\u{10d6f}',\n        '\\u{10d6f}',  Script::Garay), ('\\u{10d70}', '\\u{10d85}',  Script::Garay), ('\\u{10d8e}',\n        '\\u{10d8f}',  Script::Garay), ('\\u{10e60}', '\\u{10e7e}',  Script::Arabic), ('\\u{10e80}',\n        '\\u{10ea9}',  Script::Yezidi), ('\\u{10eab}', '\\u{10eac}',  Script::Yezidi), ('\\u{10ead}',\n        '\\u{10ead}',  Script::Yezidi), ('\\u{10eb0}', '\\u{10eb1}',  Script::Yezidi), ('\\u{10ec2}',\n        '\\u{10ec4}',  Script::Arabic), ('\\u{10ec5}', '\\u{10ec5}',  Script::Arabic), ('\\u{10ec6}',\n        '\\u{10ec7}',  Script::Arabic), ('\\u{10ed0}', '\\u{10ed0}',  Script::Arabic), ('\\u{10ed1}',\n        '\\u{10ed8}',  Script::Arabic), ('\\u{10efa}', '\\u{10eff}',  Script::Arabic), ('\\u{10f00}',\n        '\\u{10f1c}',  Script::Old_Sogdian), ('\\u{10f1d}', '\\u{10f26}',  Script::Old_Sogdian),\n        ('\\u{10f27}', '\\u{10f27}',  Script::Old_Sogdian), ('\\u{10f30}', '\\u{10f45}',\n         Script::Sogdian), ('\\u{10f46}', '\\u{10f50}',  Script::Sogdian), ('\\u{10f51}', '\\u{10f54}',\n         Script::Sogdian), ('\\u{10f55}', '\\u{10f59}',  Script::Sogdian), ('\\u{10f70}', '\\u{10f81}',\n         Script::Old_Uyghur), ('\\u{10f82}', '\\u{10f85}',  Script::Old_Uyghur), ('\\u{10f86}',\n        '\\u{10f89}',  Script::Old_Uyghur), ('\\u{10fb0}', '\\u{10fc4}',  Script::Chorasmian),\n        ('\\u{10fc5}', '\\u{10fcb}',  Script::Chorasmian), ('\\u{10fe0}', '\\u{10ff6}',\n         Script::Elymaic), ('\\u{11000}', '\\u{11000}',  Script::Brahmi), ('\\u{11001}', '\\u{11001}',\n         Script::Brahmi), ('\\u{11002}', '\\u{11002}',  Script::Brahmi), ('\\u{11003}', '\\u{11037}',\n         Script::Brahmi), ('\\u{11038}', '\\u{11046}',  Script::Brahmi), ('\\u{11047}', '\\u{1104d}',\n         Script::Brahmi), ('\\u{11052}', '\\u{11065}',  Script::Brahmi), ('\\u{11066}', '\\u{1106f}',\n         Script::Brahmi), ('\\u{11070}', '\\u{11070}',  Script::Brahmi), ('\\u{11071}', '\\u{11072}',\n         Script::Brahmi), ('\\u{11073}', '\\u{11074}',  Script::Brahmi), ('\\u{11075}', '\\u{11075}',\n         Script::Brahmi), ('\\u{1107f}', '\\u{1107f}',  Script::Brahmi), ('\\u{11080}', '\\u{11081}',\n         Script::Kaithi), ('\\u{11082}', '\\u{11082}',  Script::Kaithi), ('\\u{11083}', '\\u{110af}',\n         Script::Kaithi), ('\\u{110b0}', '\\u{110b2}',  Script::Kaithi), ('\\u{110b3}', '\\u{110b6}',\n         Script::Kaithi), ('\\u{110b7}', '\\u{110b8}',  Script::Kaithi), ('\\u{110b9}', '\\u{110ba}',\n         Script::Kaithi), ('\\u{110bb}', '\\u{110bc}',  Script::Kaithi), ('\\u{110bd}', '\\u{110bd}',\n         Script::Kaithi), ('\\u{110be}', '\\u{110c1}',  Script::Kaithi), ('\\u{110c2}', '\\u{110c2}',\n         Script::Kaithi), ('\\u{110cd}', '\\u{110cd}',  Script::Kaithi), ('\\u{110d0}', '\\u{110e8}',\n         Script::Sora_Sompeng), ('\\u{110f0}', '\\u{110f9}',  Script::Sora_Sompeng), ('\\u{11100}',\n        '\\u{11102}',  Script::Chakma), ('\\u{11103}', '\\u{11126}',  Script::Chakma), ('\\u{11127}',\n        '\\u{1112b}',  Script::Chakma), ('\\u{1112c}', '\\u{1112c}',  Script::Chakma), ('\\u{1112d}',\n        '\\u{11134}',  Script::Chakma), ('\\u{11136}', '\\u{1113f}',  Script::Chakma), ('\\u{11140}',\n        '\\u{11143}',  Script::Chakma), ('\\u{11144}', '\\u{11144}',  Script::Chakma), ('\\u{11145}',\n        '\\u{11146}',  Script::Chakma), ('\\u{11147}', '\\u{11147}',  Script::Chakma), ('\\u{11150}',\n        '\\u{11172}',  Script::Mahajani), ('\\u{11173}', '\\u{11173}',  Script::Mahajani),\n        ('\\u{11174}', '\\u{11175}',  Script::Mahajani), ('\\u{11176}', '\\u{11176}',\n         Script::Mahajani), ('\\u{11180}', '\\u{11181}',  Script::Sharada), ('\\u{11182}', '\\u{11182}',\n         Script::Sharada), ('\\u{11183}', '\\u{111b2}',  Script::Sharada), ('\\u{111b3}', '\\u{111b5}',\n         Script::Sharada), ('\\u{111b6}', '\\u{111be}',  Script::Sharada), ('\\u{111bf}', '\\u{111c0}',\n         Script::Sharada), ('\\u{111c1}', '\\u{111c4}',  Script::Sharada), ('\\u{111c5}', '\\u{111c8}',\n         Script::Sharada), ('\\u{111c9}', '\\u{111cc}',  Script::Sharada), ('\\u{111cd}', '\\u{111cd}',\n         Script::Sharada), ('\\u{111ce}', '\\u{111ce}',  Script::Sharada), ('\\u{111cf}', '\\u{111cf}',\n         Script::Sharada), ('\\u{111d0}', '\\u{111d9}',  Script::Sharada), ('\\u{111da}', '\\u{111da}',\n         Script::Sharada), ('\\u{111db}', '\\u{111db}',  Script::Sharada), ('\\u{111dc}', '\\u{111dc}',\n         Script::Sharada), ('\\u{111dd}', '\\u{111df}',  Script::Sharada), ('\\u{111e1}', '\\u{111f4}',\n         Script::Sinhala), ('\\u{11200}', '\\u{11211}',  Script::Khojki), ('\\u{11213}', '\\u{1122b}',\n         Script::Khojki), ('\\u{1122c}', '\\u{1122e}',  Script::Khojki), ('\\u{1122f}', '\\u{11231}',\n         Script::Khojki), ('\\u{11232}', '\\u{11233}',  Script::Khojki), ('\\u{11234}', '\\u{11234}',\n         Script::Khojki), ('\\u{11235}', '\\u{11235}',  Script::Khojki), ('\\u{11236}', '\\u{11237}',\n         Script::Khojki), ('\\u{11238}', '\\u{1123d}',  Script::Khojki), ('\\u{1123e}', '\\u{1123e}',\n         Script::Khojki), ('\\u{1123f}', '\\u{11240}',  Script::Khojki), ('\\u{11241}', '\\u{11241}',\n         Script::Khojki), ('\\u{11280}', '\\u{11286}',  Script::Multani), ('\\u{11288}', '\\u{11288}',\n         Script::Multani), ('\\u{1128a}', '\\u{1128d}',  Script::Multani), ('\\u{1128f}', '\\u{1129d}',\n         Script::Multani), ('\\u{1129f}', '\\u{112a8}',  Script::Multani), ('\\u{112a9}', '\\u{112a9}',\n         Script::Multani), ('\\u{112b0}', '\\u{112de}',  Script::Khudawadi), ('\\u{112df}',\n        '\\u{112df}',  Script::Khudawadi), ('\\u{112e0}', '\\u{112e2}',  Script::Khudawadi),\n        ('\\u{112e3}', '\\u{112ea}',  Script::Khudawadi), ('\\u{112f0}', '\\u{112f9}',\n         Script::Khudawadi), ('\\u{11300}', '\\u{11301}',  Script::Grantha), ('\\u{11302}',\n        '\\u{11303}',  Script::Grantha), ('\\u{11305}', '\\u{1130c}',  Script::Grantha), ('\\u{1130f}',\n        '\\u{11310}',  Script::Grantha), ('\\u{11313}', '\\u{11328}',  Script::Grantha), ('\\u{1132a}',\n        '\\u{11330}',  Script::Grantha), ('\\u{11332}', '\\u{11333}',  Script::Grantha), ('\\u{11335}',\n        '\\u{11339}',  Script::Grantha), ('\\u{1133b}', '\\u{1133b}',  Script::Inherited),\n        ('\\u{1133c}', '\\u{1133c}',  Script::Grantha), ('\\u{1133d}', '\\u{1133d}',  Script::Grantha),\n        ('\\u{1133e}', '\\u{1133f}',  Script::Grantha), ('\\u{11340}', '\\u{11340}',  Script::Grantha),\n        ('\\u{11341}', '\\u{11344}',  Script::Grantha), ('\\u{11347}', '\\u{11348}',  Script::Grantha),\n        ('\\u{1134b}', '\\u{1134d}',  Script::Grantha), ('\\u{11350}', '\\u{11350}',  Script::Grantha),\n        ('\\u{11357}', '\\u{11357}',  Script::Grantha), ('\\u{1135d}', '\\u{11361}',  Script::Grantha),\n        ('\\u{11362}', '\\u{11363}',  Script::Grantha), ('\\u{11366}', '\\u{1136c}',  Script::Grantha),\n        ('\\u{11370}', '\\u{11374}',  Script::Grantha), ('\\u{11380}', '\\u{11389}',\n         Script::Tulu_Tigalari), ('\\u{1138b}', '\\u{1138b}',  Script::Tulu_Tigalari), ('\\u{1138e}',\n        '\\u{1138e}',  Script::Tulu_Tigalari), ('\\u{11390}', '\\u{113b5}',  Script::Tulu_Tigalari),\n        ('\\u{113b7}', '\\u{113b7}',  Script::Tulu_Tigalari), ('\\u{113b8}', '\\u{113ba}',\n         Script::Tulu_Tigalari), ('\\u{113bb}', '\\u{113c0}',  Script::Tulu_Tigalari), ('\\u{113c2}',\n        '\\u{113c2}',  Script::Tulu_Tigalari), ('\\u{113c5}', '\\u{113c5}',  Script::Tulu_Tigalari),\n        ('\\u{113c7}', '\\u{113ca}',  Script::Tulu_Tigalari), ('\\u{113cc}', '\\u{113cd}',\n         Script::Tulu_Tigalari), ('\\u{113ce}', '\\u{113ce}',  Script::Tulu_Tigalari), ('\\u{113cf}',\n        '\\u{113cf}',  Script::Tulu_Tigalari), ('\\u{113d0}', '\\u{113d0}',  Script::Tulu_Tigalari),\n        ('\\u{113d1}', '\\u{113d1}',  Script::Tulu_Tigalari), ('\\u{113d2}', '\\u{113d2}',\n         Script::Tulu_Tigalari), ('\\u{113d3}', '\\u{113d3}',  Script::Tulu_Tigalari), ('\\u{113d4}',\n        '\\u{113d5}',  Script::Tulu_Tigalari), ('\\u{113d7}', '\\u{113d8}',  Script::Tulu_Tigalari),\n        ('\\u{113e1}', '\\u{113e2}',  Script::Tulu_Tigalari), ('\\u{11400}', '\\u{11434}',\n         Script::Newa), ('\\u{11435}', '\\u{11437}',  Script::Newa), ('\\u{11438}', '\\u{1143f}',\n         Script::Newa), ('\\u{11440}', '\\u{11441}',  Script::Newa), ('\\u{11442}', '\\u{11444}',\n         Script::Newa), ('\\u{11445}', '\\u{11445}',  Script::Newa), ('\\u{11446}', '\\u{11446}',\n         Script::Newa), ('\\u{11447}', '\\u{1144a}',  Script::Newa), ('\\u{1144b}', '\\u{1144f}',\n         Script::Newa), ('\\u{11450}', '\\u{11459}',  Script::Newa), ('\\u{1145a}', '\\u{1145b}',\n         Script::Newa), ('\\u{1145d}', '\\u{1145d}',  Script::Newa), ('\\u{1145e}', '\\u{1145e}',\n         Script::Newa), ('\\u{1145f}', '\\u{11461}',  Script::Newa), ('\\u{11480}', '\\u{114af}',\n         Script::Tirhuta), ('\\u{114b0}', '\\u{114b2}',  Script::Tirhuta), ('\\u{114b3}', '\\u{114b8}',\n         Script::Tirhuta), ('\\u{114b9}', '\\u{114b9}',  Script::Tirhuta), ('\\u{114ba}', '\\u{114ba}',\n         Script::Tirhuta), ('\\u{114bb}', '\\u{114be}',  Script::Tirhuta), ('\\u{114bf}', '\\u{114c0}',\n         Script::Tirhuta), ('\\u{114c1}', '\\u{114c1}',  Script::Tirhuta), ('\\u{114c2}', '\\u{114c3}',\n         Script::Tirhuta), ('\\u{114c4}', '\\u{114c5}',  Script::Tirhuta), ('\\u{114c6}', '\\u{114c6}',\n         Script::Tirhuta), ('\\u{114c7}', '\\u{114c7}',  Script::Tirhuta), ('\\u{114d0}', '\\u{114d9}',\n         Script::Tirhuta), ('\\u{11580}', '\\u{115ae}',  Script::Siddham), ('\\u{115af}', '\\u{115b1}',\n         Script::Siddham), ('\\u{115b2}', '\\u{115b5}',  Script::Siddham), ('\\u{115b8}', '\\u{115bb}',\n         Script::Siddham), ('\\u{115bc}', '\\u{115bd}',  Script::Siddham), ('\\u{115be}', '\\u{115be}',\n         Script::Siddham), ('\\u{115bf}', '\\u{115c0}',  Script::Siddham), ('\\u{115c1}', '\\u{115d7}',\n         Script::Siddham), ('\\u{115d8}', '\\u{115db}',  Script::Siddham), ('\\u{115dc}', '\\u{115dd}',\n         Script::Siddham), ('\\u{11600}', '\\u{1162f}',  Script::Modi), ('\\u{11630}', '\\u{11632}',\n         Script::Modi), ('\\u{11633}', '\\u{1163a}',  Script::Modi), ('\\u{1163b}', '\\u{1163c}',\n         Script::Modi), ('\\u{1163d}', '\\u{1163d}',  Script::Modi), ('\\u{1163e}', '\\u{1163e}',\n         Script::Modi), ('\\u{1163f}', '\\u{11640}',  Script::Modi), ('\\u{11641}', '\\u{11643}',\n         Script::Modi), ('\\u{11644}', '\\u{11644}',  Script::Modi), ('\\u{11650}', '\\u{11659}',\n         Script::Modi), ('\\u{11660}', '\\u{1166c}',  Script::Mongolian), ('\\u{11680}', '\\u{116aa}',\n         Script::Takri), ('\\u{116ab}', '\\u{116ab}',  Script::Takri), ('\\u{116ac}', '\\u{116ac}',\n         Script::Takri), ('\\u{116ad}', '\\u{116ad}',  Script::Takri), ('\\u{116ae}', '\\u{116af}',\n         Script::Takri), ('\\u{116b0}', '\\u{116b5}',  Script::Takri), ('\\u{116b6}', '\\u{116b6}',\n         Script::Takri), ('\\u{116b7}', '\\u{116b7}',  Script::Takri), ('\\u{116b8}', '\\u{116b8}',\n         Script::Takri), ('\\u{116b9}', '\\u{116b9}',  Script::Takri), ('\\u{116c0}', '\\u{116c9}',\n         Script::Takri), ('\\u{116d0}', '\\u{116e3}',  Script::Myanmar), ('\\u{11700}', '\\u{1171a}',\n         Script::Ahom), ('\\u{1171d}', '\\u{1171d}',  Script::Ahom), ('\\u{1171e}', '\\u{1171e}',\n         Script::Ahom), ('\\u{1171f}', '\\u{1171f}',  Script::Ahom), ('\\u{11720}', '\\u{11721}',\n         Script::Ahom), ('\\u{11722}', '\\u{11725}',  Script::Ahom), ('\\u{11726}', '\\u{11726}',\n         Script::Ahom), ('\\u{11727}', '\\u{1172b}',  Script::Ahom), ('\\u{11730}', '\\u{11739}',\n         Script::Ahom), ('\\u{1173a}', '\\u{1173b}',  Script::Ahom), ('\\u{1173c}', '\\u{1173e}',\n         Script::Ahom), ('\\u{1173f}', '\\u{1173f}',  Script::Ahom), ('\\u{11740}', '\\u{11746}',\n         Script::Ahom), ('\\u{11800}', '\\u{1182b}',  Script::Dogra), ('\\u{1182c}', '\\u{1182e}',\n         Script::Dogra), ('\\u{1182f}', '\\u{11837}',  Script::Dogra), ('\\u{11838}', '\\u{11838}',\n         Script::Dogra), ('\\u{11839}', '\\u{1183a}',  Script::Dogra), ('\\u{1183b}', '\\u{1183b}',\n         Script::Dogra), ('\\u{118a0}', '\\u{118df}',  Script::Warang_Citi), ('\\u{118e0}',\n        '\\u{118e9}',  Script::Warang_Citi), ('\\u{118ea}', '\\u{118f2}',  Script::Warang_Citi),\n        ('\\u{118ff}', '\\u{118ff}',  Script::Warang_Citi), ('\\u{11900}', '\\u{11906}',\n         Script::Dives_Akuru), ('\\u{11909}', '\\u{11909}',  Script::Dives_Akuru), ('\\u{1190c}',\n        '\\u{11913}',  Script::Dives_Akuru), ('\\u{11915}', '\\u{11916}',  Script::Dives_Akuru),\n        ('\\u{11918}', '\\u{1192f}',  Script::Dives_Akuru), ('\\u{11930}', '\\u{11935}',\n         Script::Dives_Akuru), ('\\u{11937}', '\\u{11938}',  Script::Dives_Akuru), ('\\u{1193b}',\n        '\\u{1193c}',  Script::Dives_Akuru), ('\\u{1193d}', '\\u{1193d}',  Script::Dives_Akuru),\n        ('\\u{1193e}', '\\u{1193e}',  Script::Dives_Akuru), ('\\u{1193f}', '\\u{1193f}',\n         Script::Dives_Akuru), ('\\u{11940}', '\\u{11940}',  Script::Dives_Akuru), ('\\u{11941}',\n        '\\u{11941}',  Script::Dives_Akuru), ('\\u{11942}', '\\u{11942}',  Script::Dives_Akuru),\n        ('\\u{11943}', '\\u{11943}',  Script::Dives_Akuru), ('\\u{11944}', '\\u{11946}',\n         Script::Dives_Akuru), ('\\u{11950}', '\\u{11959}',  Script::Dives_Akuru), ('\\u{119a0}',\n        '\\u{119a7}',  Script::Nandinagari), ('\\u{119aa}', '\\u{119d0}',  Script::Nandinagari),\n        ('\\u{119d1}', '\\u{119d3}',  Script::Nandinagari), ('\\u{119d4}', '\\u{119d7}',\n         Script::Nandinagari), ('\\u{119da}', '\\u{119db}',  Script::Nandinagari), ('\\u{119dc}',\n        '\\u{119df}',  Script::Nandinagari), ('\\u{119e0}', '\\u{119e0}',  Script::Nandinagari),\n        ('\\u{119e1}', '\\u{119e1}',  Script::Nandinagari), ('\\u{119e2}', '\\u{119e2}',\n         Script::Nandinagari), ('\\u{119e3}', '\\u{119e3}',  Script::Nandinagari), ('\\u{119e4}',\n        '\\u{119e4}',  Script::Nandinagari), ('\\u{11a00}', '\\u{11a00}',  Script::Zanabazar_Square),\n        ('\\u{11a01}', '\\u{11a0a}',  Script::Zanabazar_Square), ('\\u{11a0b}', '\\u{11a32}',\n         Script::Zanabazar_Square), ('\\u{11a33}', '\\u{11a38}',  Script::Zanabazar_Square),\n        ('\\u{11a39}', '\\u{11a39}',  Script::Zanabazar_Square), ('\\u{11a3a}', '\\u{11a3a}',\n         Script::Zanabazar_Square), ('\\u{11a3b}', '\\u{11a3e}',  Script::Zanabazar_Square),\n        ('\\u{11a3f}', '\\u{11a46}',  Script::Zanabazar_Square), ('\\u{11a47}', '\\u{11a47}',\n         Script::Zanabazar_Square), ('\\u{11a50}', '\\u{11a50}',  Script::Soyombo), ('\\u{11a51}',\n        '\\u{11a56}',  Script::Soyombo), ('\\u{11a57}', '\\u{11a58}',  Script::Soyombo), ('\\u{11a59}',\n        '\\u{11a5b}',  Script::Soyombo), ('\\u{11a5c}', '\\u{11a89}',  Script::Soyombo), ('\\u{11a8a}',\n        '\\u{11a96}',  Script::Soyombo), ('\\u{11a97}', '\\u{11a97}',  Script::Soyombo), ('\\u{11a98}',\n        '\\u{11a99}',  Script::Soyombo), ('\\u{11a9a}', '\\u{11a9c}',  Script::Soyombo), ('\\u{11a9d}',\n        '\\u{11a9d}',  Script::Soyombo), ('\\u{11a9e}', '\\u{11aa2}',  Script::Soyombo), ('\\u{11ab0}',\n        '\\u{11abf}',  Script::Canadian_Aboriginal), ('\\u{11ac0}', '\\u{11af8}',\n         Script::Pau_Cin_Hau), ('\\u{11b00}', '\\u{11b09}',  Script::Devanagari), ('\\u{11b60}',\n        '\\u{11b60}',  Script::Sharada), ('\\u{11b61}', '\\u{11b61}',  Script::Sharada), ('\\u{11b62}',\n        '\\u{11b64}',  Script::Sharada), ('\\u{11b65}', '\\u{11b65}',  Script::Sharada), ('\\u{11b66}',\n        '\\u{11b66}',  Script::Sharada), ('\\u{11b67}', '\\u{11b67}',  Script::Sharada), ('\\u{11bc0}',\n        '\\u{11be0}',  Script::Sunuwar), ('\\u{11be1}', '\\u{11be1}',  Script::Sunuwar), ('\\u{11bf0}',\n        '\\u{11bf9}',  Script::Sunuwar), ('\\u{11c00}', '\\u{11c08}',  Script::Bhaiksuki),\n        ('\\u{11c0a}', '\\u{11c2e}',  Script::Bhaiksuki), ('\\u{11c2f}', '\\u{11c2f}',\n         Script::Bhaiksuki), ('\\u{11c30}', '\\u{11c36}',  Script::Bhaiksuki), ('\\u{11c38}',\n        '\\u{11c3d}',  Script::Bhaiksuki), ('\\u{11c3e}', '\\u{11c3e}',  Script::Bhaiksuki),\n        ('\\u{11c3f}', '\\u{11c3f}',  Script::Bhaiksuki), ('\\u{11c40}', '\\u{11c40}',\n         Script::Bhaiksuki), ('\\u{11c41}', '\\u{11c45}',  Script::Bhaiksuki), ('\\u{11c50}',\n        '\\u{11c59}',  Script::Bhaiksuki), ('\\u{11c5a}', '\\u{11c6c}',  Script::Bhaiksuki),\n        ('\\u{11c70}', '\\u{11c71}',  Script::Marchen), ('\\u{11c72}', '\\u{11c8f}',  Script::Marchen),\n        ('\\u{11c92}', '\\u{11ca7}',  Script::Marchen), ('\\u{11ca9}', '\\u{11ca9}',  Script::Marchen),\n        ('\\u{11caa}', '\\u{11cb0}',  Script::Marchen), ('\\u{11cb1}', '\\u{11cb1}',  Script::Marchen),\n        ('\\u{11cb2}', '\\u{11cb3}',  Script::Marchen), ('\\u{11cb4}', '\\u{11cb4}',  Script::Marchen),\n        ('\\u{11cb5}', '\\u{11cb6}',  Script::Marchen), ('\\u{11d00}', '\\u{11d06}',\n         Script::Masaram_Gondi), ('\\u{11d08}', '\\u{11d09}',  Script::Masaram_Gondi), ('\\u{11d0b}',\n        '\\u{11d30}',  Script::Masaram_Gondi), ('\\u{11d31}', '\\u{11d36}',  Script::Masaram_Gondi),\n        ('\\u{11d3a}', '\\u{11d3a}',  Script::Masaram_Gondi), ('\\u{11d3c}', '\\u{11d3d}',\n         Script::Masaram_Gondi), ('\\u{11d3f}', '\\u{11d45}',  Script::Masaram_Gondi), ('\\u{11d46}',\n        '\\u{11d46}',  Script::Masaram_Gondi), ('\\u{11d47}', '\\u{11d47}',  Script::Masaram_Gondi),\n        ('\\u{11d50}', '\\u{11d59}',  Script::Masaram_Gondi), ('\\u{11d60}', '\\u{11d65}',\n         Script::Gunjala_Gondi), ('\\u{11d67}', '\\u{11d68}',  Script::Gunjala_Gondi), ('\\u{11d6a}',\n        '\\u{11d89}',  Script::Gunjala_Gondi), ('\\u{11d8a}', '\\u{11d8e}',  Script::Gunjala_Gondi),\n        ('\\u{11d90}', '\\u{11d91}',  Script::Gunjala_Gondi), ('\\u{11d93}', '\\u{11d94}',\n         Script::Gunjala_Gondi), ('\\u{11d95}', '\\u{11d95}',  Script::Gunjala_Gondi), ('\\u{11d96}',\n        '\\u{11d96}',  Script::Gunjala_Gondi), ('\\u{11d97}', '\\u{11d97}',  Script::Gunjala_Gondi),\n        ('\\u{11d98}', '\\u{11d98}',  Script::Gunjala_Gondi), ('\\u{11da0}', '\\u{11da9}',\n         Script::Gunjala_Gondi), ('\\u{11db0}', '\\u{11dd8}',  Script::Tolong_Siki), ('\\u{11dd9}',\n        '\\u{11dd9}',  Script::Tolong_Siki), ('\\u{11dda}', '\\u{11ddb}',  Script::Tolong_Siki),\n        ('\\u{11de0}', '\\u{11de9}',  Script::Tolong_Siki), ('\\u{11ee0}', '\\u{11ef2}',\n         Script::Makasar), ('\\u{11ef3}', '\\u{11ef4}',  Script::Makasar), ('\\u{11ef5}', '\\u{11ef6}',\n         Script::Makasar), ('\\u{11ef7}', '\\u{11ef8}',  Script::Makasar), ('\\u{11f00}', '\\u{11f01}',\n         Script::Kawi), ('\\u{11f02}', '\\u{11f02}',  Script::Kawi), ('\\u{11f03}', '\\u{11f03}',\n         Script::Kawi), ('\\u{11f04}', '\\u{11f10}',  Script::Kawi), ('\\u{11f12}', '\\u{11f33}',\n         Script::Kawi), ('\\u{11f34}', '\\u{11f35}',  Script::Kawi), ('\\u{11f36}', '\\u{11f3a}',\n         Script::Kawi), ('\\u{11f3e}', '\\u{11f3f}',  Script::Kawi), ('\\u{11f40}', '\\u{11f40}',\n         Script::Kawi), ('\\u{11f41}', '\\u{11f41}',  Script::Kawi), ('\\u{11f42}', '\\u{11f42}',\n         Script::Kawi), ('\\u{11f43}', '\\u{11f4f}',  Script::Kawi), ('\\u{11f50}', '\\u{11f59}',\n         Script::Kawi), ('\\u{11f5a}', '\\u{11f5a}',  Script::Kawi), ('\\u{11fb0}', '\\u{11fb0}',\n         Script::Lisu), ('\\u{11fc0}', '\\u{11fd4}',  Script::Tamil), ('\\u{11fd5}', '\\u{11fdc}',\n         Script::Tamil), ('\\u{11fdd}', '\\u{11fe0}',  Script::Tamil), ('\\u{11fe1}', '\\u{11ff1}',\n         Script::Tamil), ('\\u{11fff}', '\\u{11fff}',  Script::Tamil), ('\\u{12000}', '\\u{12399}',\n         Script::Cuneiform), ('\\u{12400}', '\\u{1246e}',  Script::Cuneiform), ('\\u{12470}',\n        '\\u{12474}',  Script::Cuneiform), ('\\u{12480}', '\\u{12543}',  Script::Cuneiform),\n        ('\\u{12f90}', '\\u{12ff0}',  Script::Cypro_Minoan), ('\\u{12ff1}', '\\u{12ff2}',\n         Script::Cypro_Minoan), ('\\u{13000}', '\\u{1342f}',  Script::Egyptian_Hieroglyphs),\n        ('\\u{13430}', '\\u{1343f}',  Script::Egyptian_Hieroglyphs), ('\\u{13440}', '\\u{13440}',\n         Script::Egyptian_Hieroglyphs), ('\\u{13441}', '\\u{13446}',  Script::Egyptian_Hieroglyphs),\n        ('\\u{13447}', '\\u{13455}',  Script::Egyptian_Hieroglyphs), ('\\u{13460}', '\\u{143fa}',\n         Script::Egyptian_Hieroglyphs), ('\\u{14400}', '\\u{14646}',  Script::Anatolian_Hieroglyphs),\n        ('\\u{16100}', '\\u{1611d}',  Script::Gurung_Khema), ('\\u{1611e}', '\\u{16129}',\n         Script::Gurung_Khema), ('\\u{1612a}', '\\u{1612c}',  Script::Gurung_Khema), ('\\u{1612d}',\n        '\\u{1612f}',  Script::Gurung_Khema), ('\\u{16130}', '\\u{16139}',  Script::Gurung_Khema),\n        ('\\u{16800}', '\\u{16a38}',  Script::Bamum), ('\\u{16a40}', '\\u{16a5e}',  Script::Mro),\n        ('\\u{16a60}', '\\u{16a69}',  Script::Mro), ('\\u{16a6e}', '\\u{16a6f}',  Script::Mro),\n        ('\\u{16a70}', '\\u{16abe}',  Script::Tangsa), ('\\u{16ac0}', '\\u{16ac9}',  Script::Tangsa),\n        ('\\u{16ad0}', '\\u{16aed}',  Script::Bassa_Vah), ('\\u{16af0}', '\\u{16af4}',\n         Script::Bassa_Vah), ('\\u{16af5}', '\\u{16af5}',  Script::Bassa_Vah), ('\\u{16b00}',\n        '\\u{16b2f}',  Script::Pahawh_Hmong), ('\\u{16b30}', '\\u{16b36}',  Script::Pahawh_Hmong),\n        ('\\u{16b37}', '\\u{16b3b}',  Script::Pahawh_Hmong), ('\\u{16b3c}', '\\u{16b3f}',\n         Script::Pahawh_Hmong), ('\\u{16b40}', '\\u{16b43}',  Script::Pahawh_Hmong), ('\\u{16b44}',\n        '\\u{16b44}',  Script::Pahawh_Hmong), ('\\u{16b45}', '\\u{16b45}',  Script::Pahawh_Hmong),\n        ('\\u{16b50}', '\\u{16b59}',  Script::Pahawh_Hmong), ('\\u{16b5b}', '\\u{16b61}',\n         Script::Pahawh_Hmong), ('\\u{16b63}', '\\u{16b77}',  Script::Pahawh_Hmong), ('\\u{16b7d}',\n        '\\u{16b8f}',  Script::Pahawh_Hmong), ('\\u{16d40}', '\\u{16d42}',  Script::Kirat_Rai),\n        ('\\u{16d43}', '\\u{16d6a}',  Script::Kirat_Rai), ('\\u{16d6b}', '\\u{16d6c}',\n         Script::Kirat_Rai), ('\\u{16d6d}', '\\u{16d6f}',  Script::Kirat_Rai), ('\\u{16d70}',\n        '\\u{16d79}',  Script::Kirat_Rai), ('\\u{16e40}', '\\u{16e7f}',  Script::Medefaidrin),\n        ('\\u{16e80}', '\\u{16e96}',  Script::Medefaidrin), ('\\u{16e97}', '\\u{16e9a}',\n         Script::Medefaidrin), ('\\u{16ea0}', '\\u{16eb8}',  Script::Beria_Erfe), ('\\u{16ebb}',\n        '\\u{16ed3}',  Script::Beria_Erfe), ('\\u{16f00}', '\\u{16f4a}',  Script::Miao), ('\\u{16f4f}',\n        '\\u{16f4f}',  Script::Miao), ('\\u{16f50}', '\\u{16f50}',  Script::Miao), ('\\u{16f51}',\n        '\\u{16f87}',  Script::Miao), ('\\u{16f8f}', '\\u{16f92}',  Script::Miao), ('\\u{16f93}',\n        '\\u{16f9f}',  Script::Miao), ('\\u{16fe0}', '\\u{16fe0}',  Script::Tangut), ('\\u{16fe1}',\n        '\\u{16fe1}',  Script::Nushu), ('\\u{16fe2}', '\\u{16fe2}',  Script::Han), ('\\u{16fe3}',\n        '\\u{16fe3}',  Script::Han), ('\\u{16fe4}', '\\u{16fe4}',  Script::Khitan_Small_Script),\n        ('\\u{16ff0}', '\\u{16ff1}',  Script::Han), ('\\u{16ff2}', '\\u{16ff3}',  Script::Han),\n        ('\\u{16ff4}', '\\u{16ff6}',  Script::Han), ('\\u{17000}', '\\u{18aff}',  Script::Tangut),\n        ('\\u{18b00}', '\\u{18cd5}',  Script::Khitan_Small_Script), ('\\u{18cff}', '\\u{18cff}',\n         Script::Khitan_Small_Script), ('\\u{18d00}', '\\u{18d1e}',  Script::Tangut), ('\\u{18d80}',\n        '\\u{18df2}',  Script::Tangut), ('\\u{1aff0}', '\\u{1aff3}',  Script::Katakana), ('\\u{1aff5}',\n        '\\u{1affb}',  Script::Katakana), ('\\u{1affd}', '\\u{1affe}',  Script::Katakana),\n        ('\\u{1b000}', '\\u{1b000}',  Script::Katakana), ('\\u{1b001}', '\\u{1b11f}',\n         Script::Hiragana), ('\\u{1b120}', '\\u{1b122}',  Script::Katakana), ('\\u{1b132}',\n        '\\u{1b132}',  Script::Hiragana), ('\\u{1b150}', '\\u{1b152}',  Script::Hiragana),\n        ('\\u{1b155}', '\\u{1b155}',  Script::Katakana), ('\\u{1b164}', '\\u{1b167}',\n         Script::Katakana), ('\\u{1b170}', '\\u{1b2fb}',  Script::Nushu), ('\\u{1bc00}', '\\u{1bc6a}',\n         Script::Duployan), ('\\u{1bc70}', '\\u{1bc7c}',  Script::Duployan), ('\\u{1bc80}',\n        '\\u{1bc88}',  Script::Duployan), ('\\u{1bc90}', '\\u{1bc99}',  Script::Duployan),\n        ('\\u{1bc9c}', '\\u{1bc9c}',  Script::Duployan), ('\\u{1bc9d}', '\\u{1bc9e}',\n         Script::Duployan), ('\\u{1bc9f}', '\\u{1bc9f}',  Script::Duployan), ('\\u{1bca0}',\n        '\\u{1bca3}',  Script::Common), ('\\u{1cc00}', '\\u{1ccef}',  Script::Common), ('\\u{1ccf0}',\n        '\\u{1ccf9}',  Script::Common), ('\\u{1ccfa}', '\\u{1ccfc}',  Script::Common), ('\\u{1cd00}',\n        '\\u{1ceb3}',  Script::Common), ('\\u{1ceba}', '\\u{1ced0}',  Script::Common), ('\\u{1cee0}',\n        '\\u{1ceef}',  Script::Common), ('\\u{1cef0}', '\\u{1cef0}',  Script::Common), ('\\u{1cf00}',\n        '\\u{1cf2d}',  Script::Inherited), ('\\u{1cf30}', '\\u{1cf46}',  Script::Inherited),\n        ('\\u{1cf50}', '\\u{1cfc3}',  Script::Common), ('\\u{1d000}', '\\u{1d0f5}',  Script::Common),\n        ('\\u{1d100}', '\\u{1d126}',  Script::Common), ('\\u{1d129}', '\\u{1d164}',  Script::Common),\n        ('\\u{1d165}', '\\u{1d166}',  Script::Common), ('\\u{1d167}', '\\u{1d169}',  Script::Inherited),\n        ('\\u{1d16a}', '\\u{1d16c}',  Script::Common), ('\\u{1d16d}', '\\u{1d172}',  Script::Common),\n        ('\\u{1d173}', '\\u{1d17a}',  Script::Common), ('\\u{1d17b}', '\\u{1d182}',  Script::Inherited),\n        ('\\u{1d183}', '\\u{1d184}',  Script::Common), ('\\u{1d185}', '\\u{1d18b}',  Script::Inherited),\n        ('\\u{1d18c}', '\\u{1d1a9}',  Script::Common), ('\\u{1d1aa}', '\\u{1d1ad}',  Script::Inherited),\n        ('\\u{1d1ae}', '\\u{1d1ea}',  Script::Common), ('\\u{1d200}', '\\u{1d241}',  Script::Greek),\n        ('\\u{1d242}', '\\u{1d244}',  Script::Greek), ('\\u{1d245}', '\\u{1d245}',  Script::Greek),\n        ('\\u{1d2c0}', '\\u{1d2d3}',  Script::Common), ('\\u{1d2e0}', '\\u{1d2f3}',  Script::Common),\n        ('\\u{1d300}', '\\u{1d356}',  Script::Common), ('\\u{1d360}', '\\u{1d378}',  Script::Common),\n        ('\\u{1d400}', '\\u{1d454}',  Script::Common), ('\\u{1d456}', '\\u{1d49c}',  Script::Common),\n        ('\\u{1d49e}', '\\u{1d49f}',  Script::Common), ('\\u{1d4a2}', '\\u{1d4a2}',  Script::Common),\n        ('\\u{1d4a5}', '\\u{1d4a6}',  Script::Common), ('\\u{1d4a9}', '\\u{1d4ac}',  Script::Common),\n        ('\\u{1d4ae}', '\\u{1d4b9}',  Script::Common), ('\\u{1d4bb}', '\\u{1d4bb}',  Script::Common),\n        ('\\u{1d4bd}', '\\u{1d4c3}',  Script::Common), ('\\u{1d4c5}', '\\u{1d505}',  Script::Common),\n        ('\\u{1d507}', '\\u{1d50a}',  Script::Common), ('\\u{1d50d}', '\\u{1d514}',  Script::Common),\n        ('\\u{1d516}', '\\u{1d51c}',  Script::Common), ('\\u{1d51e}', '\\u{1d539}',  Script::Common),\n        ('\\u{1d53b}', '\\u{1d53e}',  Script::Common), ('\\u{1d540}', '\\u{1d544}',  Script::Common),\n        ('\\u{1d546}', '\\u{1d546}',  Script::Common), ('\\u{1d54a}', '\\u{1d550}',  Script::Common),\n        ('\\u{1d552}', '\\u{1d6a5}',  Script::Common), ('\\u{1d6a8}', '\\u{1d6c0}',  Script::Common),\n        ('\\u{1d6c1}', '\\u{1d6c1}',  Script::Common), ('\\u{1d6c2}', '\\u{1d6da}',  Script::Common),\n        ('\\u{1d6db}', '\\u{1d6db}',  Script::Common), ('\\u{1d6dc}', '\\u{1d6fa}',  Script::Common),\n        ('\\u{1d6fb}', '\\u{1d6fb}',  Script::Common), ('\\u{1d6fc}', '\\u{1d714}',  Script::Common),\n        ('\\u{1d715}', '\\u{1d715}',  Script::Common), ('\\u{1d716}', '\\u{1d734}',  Script::Common),\n        ('\\u{1d735}', '\\u{1d735}',  Script::Common), ('\\u{1d736}', '\\u{1d74e}',  Script::Common),\n        ('\\u{1d74f}', '\\u{1d74f}',  Script::Common), ('\\u{1d750}', '\\u{1d76e}',  Script::Common),\n        ('\\u{1d76f}', '\\u{1d76f}',  Script::Common), ('\\u{1d770}', '\\u{1d788}',  Script::Common),\n        ('\\u{1d789}', '\\u{1d789}',  Script::Common), ('\\u{1d78a}', '\\u{1d7a8}',  Script::Common),\n        ('\\u{1d7a9}', '\\u{1d7a9}',  Script::Common), ('\\u{1d7aa}', '\\u{1d7c2}',  Script::Common),\n        ('\\u{1d7c3}', '\\u{1d7c3}',  Script::Common), ('\\u{1d7c4}', '\\u{1d7cb}',  Script::Common),\n        ('\\u{1d7ce}', '\\u{1d7ff}',  Script::Common), ('\\u{1d800}', '\\u{1d9ff}',\n         Script::SignWriting), ('\\u{1da00}', '\\u{1da36}',  Script::SignWriting), ('\\u{1da37}',\n        '\\u{1da3a}',  Script::SignWriting), ('\\u{1da3b}', '\\u{1da6c}',  Script::SignWriting),\n        ('\\u{1da6d}', '\\u{1da74}',  Script::SignWriting), ('\\u{1da75}', '\\u{1da75}',\n         Script::SignWriting), ('\\u{1da76}', '\\u{1da83}',  Script::SignWriting), ('\\u{1da84}',\n        '\\u{1da84}',  Script::SignWriting), ('\\u{1da85}', '\\u{1da86}',  Script::SignWriting),\n        ('\\u{1da87}', '\\u{1da8b}',  Script::SignWriting), ('\\u{1da9b}', '\\u{1da9f}',\n         Script::SignWriting), ('\\u{1daa1}', '\\u{1daaf}',  Script::SignWriting), ('\\u{1df00}',\n        '\\u{1df09}',  Script::Latin), ('\\u{1df0a}', '\\u{1df0a}',  Script::Latin), ('\\u{1df0b}',\n        '\\u{1df1e}',  Script::Latin), ('\\u{1df25}', '\\u{1df2a}',  Script::Latin), ('\\u{1e000}',\n        '\\u{1e006}',  Script::Glagolitic), ('\\u{1e008}', '\\u{1e018}',  Script::Glagolitic),\n        ('\\u{1e01b}', '\\u{1e021}',  Script::Glagolitic), ('\\u{1e023}', '\\u{1e024}',\n         Script::Glagolitic), ('\\u{1e026}', '\\u{1e02a}',  Script::Glagolitic), ('\\u{1e030}',\n        '\\u{1e06d}',  Script::Cyrillic), ('\\u{1e08f}', '\\u{1e08f}',  Script::Cyrillic),\n        ('\\u{1e100}', '\\u{1e12c}',  Script::Nyiakeng_Puachue_Hmong), ('\\u{1e130}', '\\u{1e136}',\n         Script::Nyiakeng_Puachue_Hmong), ('\\u{1e137}', '\\u{1e13d}',\n         Script::Nyiakeng_Puachue_Hmong), ('\\u{1e140}', '\\u{1e149}',\n         Script::Nyiakeng_Puachue_Hmong), ('\\u{1e14e}', '\\u{1e14e}',\n         Script::Nyiakeng_Puachue_Hmong), ('\\u{1e14f}', '\\u{1e14f}',\n         Script::Nyiakeng_Puachue_Hmong), ('\\u{1e290}', '\\u{1e2ad}',  Script::Toto), ('\\u{1e2ae}',\n        '\\u{1e2ae}',  Script::Toto), ('\\u{1e2c0}', '\\u{1e2eb}',  Script::Wancho), ('\\u{1e2ec}',\n        '\\u{1e2ef}',  Script::Wancho), ('\\u{1e2f0}', '\\u{1e2f9}',  Script::Wancho), ('\\u{1e2ff}',\n        '\\u{1e2ff}',  Script::Wancho), ('\\u{1e4d0}', '\\u{1e4ea}',  Script::Nag_Mundari),\n        ('\\u{1e4eb}', '\\u{1e4eb}',  Script::Nag_Mundari), ('\\u{1e4ec}', '\\u{1e4ef}',\n         Script::Nag_Mundari), ('\\u{1e4f0}', '\\u{1e4f9}',  Script::Nag_Mundari), ('\\u{1e5d0}',\n        '\\u{1e5ed}',  Script::Ol_Onal), ('\\u{1e5ee}', '\\u{1e5ef}',  Script::Ol_Onal), ('\\u{1e5f0}',\n        '\\u{1e5f0}',  Script::Ol_Onal), ('\\u{1e5f1}', '\\u{1e5fa}',  Script::Ol_Onal), ('\\u{1e5ff}',\n        '\\u{1e5ff}',  Script::Ol_Onal), ('\\u{1e6c0}', '\\u{1e6de}',  Script::Tai_Yo), ('\\u{1e6e0}',\n        '\\u{1e6e2}',  Script::Tai_Yo), ('\\u{1e6e3}', '\\u{1e6e3}',  Script::Tai_Yo), ('\\u{1e6e4}',\n        '\\u{1e6e5}',  Script::Tai_Yo), ('\\u{1e6e6}', '\\u{1e6e6}',  Script::Tai_Yo), ('\\u{1e6e7}',\n        '\\u{1e6ed}',  Script::Tai_Yo), ('\\u{1e6ee}', '\\u{1e6ef}',  Script::Tai_Yo), ('\\u{1e6f0}',\n        '\\u{1e6f4}',  Script::Tai_Yo), ('\\u{1e6f5}', '\\u{1e6f5}',  Script::Tai_Yo), ('\\u{1e6fe}',\n        '\\u{1e6fe}',  Script::Tai_Yo), ('\\u{1e6ff}', '\\u{1e6ff}',  Script::Tai_Yo), ('\\u{1e7e0}',\n        '\\u{1e7e6}',  Script::Ethiopic), ('\\u{1e7e8}', '\\u{1e7eb}',  Script::Ethiopic),\n        ('\\u{1e7ed}', '\\u{1e7ee}',  Script::Ethiopic), ('\\u{1e7f0}', '\\u{1e7fe}',\n         Script::Ethiopic), ('\\u{1e800}', '\\u{1e8c4}',  Script::Mende_Kikakui), ('\\u{1e8c7}',\n        '\\u{1e8cf}',  Script::Mende_Kikakui), ('\\u{1e8d0}', '\\u{1e8d6}',  Script::Mende_Kikakui),\n        ('\\u{1e900}', '\\u{1e943}',  Script::Adlam), ('\\u{1e944}', '\\u{1e94a}',  Script::Adlam),\n        ('\\u{1e94b}', '\\u{1e94b}',  Script::Adlam), ('\\u{1e950}', '\\u{1e959}',  Script::Adlam),\n        ('\\u{1e95e}', '\\u{1e95f}',  Script::Adlam), ('\\u{1ec71}', '\\u{1ecab}',  Script::Common),\n        ('\\u{1ecac}', '\\u{1ecac}',  Script::Common), ('\\u{1ecad}', '\\u{1ecaf}',  Script::Common),\n        ('\\u{1ecb0}', '\\u{1ecb0}',  Script::Common), ('\\u{1ecb1}', '\\u{1ecb4}',  Script::Common),\n        ('\\u{1ed01}', '\\u{1ed2d}',  Script::Common), ('\\u{1ed2e}', '\\u{1ed2e}',  Script::Common),\n        ('\\u{1ed2f}', '\\u{1ed3d}',  Script::Common), ('\\u{1ee00}', '\\u{1ee03}',  Script::Arabic),\n        ('\\u{1ee05}', '\\u{1ee1f}',  Script::Arabic), ('\\u{1ee21}', '\\u{1ee22}',  Script::Arabic),\n        ('\\u{1ee24}', '\\u{1ee24}',  Script::Arabic), ('\\u{1ee27}', '\\u{1ee27}',  Script::Arabic),\n        ('\\u{1ee29}', '\\u{1ee32}',  Script::Arabic), ('\\u{1ee34}', '\\u{1ee37}',  Script::Arabic),\n        ('\\u{1ee39}', '\\u{1ee39}',  Script::Arabic), ('\\u{1ee3b}', '\\u{1ee3b}',  Script::Arabic),\n        ('\\u{1ee42}', '\\u{1ee42}',  Script::Arabic), ('\\u{1ee47}', '\\u{1ee47}',  Script::Arabic),\n        ('\\u{1ee49}', '\\u{1ee49}',  Script::Arabic), ('\\u{1ee4b}', '\\u{1ee4b}',  Script::Arabic),\n        ('\\u{1ee4d}', '\\u{1ee4f}',  Script::Arabic), ('\\u{1ee51}', '\\u{1ee52}',  Script::Arabic),\n        ('\\u{1ee54}', '\\u{1ee54}',  Script::Arabic), ('\\u{1ee57}', '\\u{1ee57}',  Script::Arabic),\n        ('\\u{1ee59}', '\\u{1ee59}',  Script::Arabic), ('\\u{1ee5b}', '\\u{1ee5b}',  Script::Arabic),\n        ('\\u{1ee5d}', '\\u{1ee5d}',  Script::Arabic), ('\\u{1ee5f}', '\\u{1ee5f}',  Script::Arabic),\n        ('\\u{1ee61}', '\\u{1ee62}',  Script::Arabic), ('\\u{1ee64}', '\\u{1ee64}',  Script::Arabic),\n        ('\\u{1ee67}', '\\u{1ee6a}',  Script::Arabic), ('\\u{1ee6c}', '\\u{1ee72}',  Script::Arabic),\n        ('\\u{1ee74}', '\\u{1ee77}',  Script::Arabic), ('\\u{1ee79}', '\\u{1ee7c}',  Script::Arabic),\n        ('\\u{1ee7e}', '\\u{1ee7e}',  Script::Arabic), ('\\u{1ee80}', '\\u{1ee89}',  Script::Arabic),\n        ('\\u{1ee8b}', '\\u{1ee9b}',  Script::Arabic), ('\\u{1eea1}', '\\u{1eea3}',  Script::Arabic),\n        ('\\u{1eea5}', '\\u{1eea9}',  Script::Arabic), ('\\u{1eeab}', '\\u{1eebb}',  Script::Arabic),\n        ('\\u{1eef0}', '\\u{1eef1}',  Script::Arabic), ('\\u{1f000}', '\\u{1f02b}',  Script::Common),\n        ('\\u{1f030}', '\\u{1f093}',  Script::Common), ('\\u{1f0a0}', '\\u{1f0ae}',  Script::Common),\n        ('\\u{1f0b1}', '\\u{1f0bf}',  Script::Common), ('\\u{1f0c1}', '\\u{1f0cf}',  Script::Common),\n        ('\\u{1f0d1}', '\\u{1f0f5}',  Script::Common), ('\\u{1f100}', '\\u{1f10c}',  Script::Common),\n        ('\\u{1f10d}', '\\u{1f1ad}',  Script::Common), ('\\u{1f1e6}', '\\u{1f1ff}',  Script::Common),\n        ('\\u{1f200}', '\\u{1f200}',  Script::Hiragana), ('\\u{1f201}', '\\u{1f202}',  Script::Common),\n        ('\\u{1f210}', '\\u{1f23b}',  Script::Common), ('\\u{1f240}', '\\u{1f248}',  Script::Common),\n        ('\\u{1f250}', '\\u{1f251}',  Script::Common), ('\\u{1f260}', '\\u{1f265}',  Script::Common),\n        ('\\u{1f300}', '\\u{1f3fa}',  Script::Common), ('\\u{1f3fb}', '\\u{1f3ff}',  Script::Common),\n        ('\\u{1f400}', '\\u{1f6d8}',  Script::Common), ('\\u{1f6dc}', '\\u{1f6ec}',  Script::Common),\n        ('\\u{1f6f0}', '\\u{1f6fc}',  Script::Common), ('\\u{1f700}', '\\u{1f7d9}',  Script::Common),\n        ('\\u{1f7e0}', '\\u{1f7eb}',  Script::Common), ('\\u{1f7f0}', '\\u{1f7f0}',  Script::Common),\n        ('\\u{1f800}', '\\u{1f80b}',  Script::Common), ('\\u{1f810}', '\\u{1f847}',  Script::Common),\n        ('\\u{1f850}', '\\u{1f859}',  Script::Common), ('\\u{1f860}', '\\u{1f887}',  Script::Common),\n        ('\\u{1f890}', '\\u{1f8ad}',  Script::Common), ('\\u{1f8b0}', '\\u{1f8bb}',  Script::Common),\n        ('\\u{1f8c0}', '\\u{1f8c1}',  Script::Common), ('\\u{1f8d0}', '\\u{1f8d8}',  Script::Common),\n        ('\\u{1f900}', '\\u{1fa57}',  Script::Common), ('\\u{1fa60}', '\\u{1fa6d}',  Script::Common),\n        ('\\u{1fa70}', '\\u{1fa7c}',  Script::Common), ('\\u{1fa80}', '\\u{1fa8a}',  Script::Common),\n        ('\\u{1fa8e}', '\\u{1fac6}',  Script::Common), ('\\u{1fac8}', '\\u{1fac8}',  Script::Common),\n        ('\\u{1facd}', '\\u{1fadc}',  Script::Common), ('\\u{1fadf}', '\\u{1faea}',  Script::Common),\n        ('\\u{1faef}', '\\u{1faf8}',  Script::Common), ('\\u{1fb00}', '\\u{1fb92}',  Script::Common),\n        ('\\u{1fb94}', '\\u{1fbef}',  Script::Common), ('\\u{1fbf0}', '\\u{1fbf9}',  Script::Common),\n        ('\\u{1fbfa}', '\\u{1fbfa}',  Script::Common), ('\\u{20000}', '\\u{2a6df}',  Script::Han),\n        ('\\u{2a700}', '\\u{2b81d}',  Script::Han), ('\\u{2b820}', '\\u{2cead}',  Script::Han),\n        ('\\u{2ceb0}', '\\u{2ebe0}',  Script::Han), ('\\u{2ebf0}', '\\u{2ee5d}',  Script::Han),\n        ('\\u{2f800}', '\\u{2fa1d}',  Script::Han), ('\\u{30000}', '\\u{3134a}',  Script::Han),\n        ('\\u{31350}', '\\u{33479}',  Script::Han), ('\\u{e0001}', '\\u{e0001}',  Script::Common),\n        ('\\u{e0020}', '\\u{e007f}',  Script::Common), ('\\u{e0100}', '\\u{e01ef}',  Script::Inherited)\n    ];\n\n    const SCRIPT_EXTENSIONS: &'static [(char, char, ScriptExtension)] = &[\n        ('\\u{b7}', '\\u{b7}',\n        script_extensions::AVST_CARI_COPT_DUPL_ELBA_GEOR_GLAG_GONG_GOTH_GREK_HANI_LATN_LYDI_MAHJ_PERM_SHAW),\n        ('\\u{2bc}', '\\u{2bc}', script_extensions::BENG_CYRL_DEVA_LATN_LISU_THAI_TOTO), ('\\u{2c7}',\n        '\\u{2c7}', script_extensions::BOPO_LATN), ('\\u{2c9}', '\\u{2cb}',\n        script_extensions::BOPO_LATN), ('\\u{2cd}', '\\u{2cd}', script_extensions::LATN_LISU),\n        ('\\u{2d7}', '\\u{2d7}', script_extensions::LATN_THAI), ('\\u{2d9}', '\\u{2d9}',\n        script_extensions::BOPO_LATN), ('\\u{300}', '\\u{300}',\n        script_extensions::CHER_COPT_CYRL_GREK_LATN_PERM_SUNU_TALE), ('\\u{301}', '\\u{301}',\n        script_extensions::CHER_CYRL_GREK_LATN_OSGE_SUNU_TALE_TODR), ('\\u{302}', '\\u{302}',\n        script_extensions::CHER_CYRL_LATN_TFNG), ('\\u{303}', '\\u{303}',\n        script_extensions::GLAG_LATN_SUNU_SYRC_THAI), ('\\u{304}', '\\u{304}',\n        script_extensions::AGHB_CHER_COPT_CYRL_GOTH_GREK_LATN_OSGE_SYRC_TFNG_TODR), ('\\u{305}',\n        '\\u{305}', script_extensions::COPT_ELBA_GLAG_GOTH_KANA_LATN), ('\\u{306}', '\\u{306}',\n        script_extensions::CYRL_GREK_LATN_PERM_TFNG), ('\\u{307}', '\\u{307}',\n        script_extensions::COPT_DUPL_HEBR_LATN_PERM_SYRC_TALE_TFNG_TODR), ('\\u{308}', '\\u{308}',\n        script_extensions::ARMN_CYRL_DUPL_GOTH_GREK_HEBR_LATN_PERM_SYRC_TALE_TFNG), ('\\u{309}',\n        '\\u{309}', script_extensions::LATN_TFNG), ('\\u{30a}', '\\u{30a}',\n        script_extensions::DUPL_LATN_SYRC), ('\\u{30b}', '\\u{30b}',\n        script_extensions::CHER_CYRL_LATN_OSGE), ('\\u{30c}', '\\u{30c}',\n        script_extensions::CHER_LATN_TALE), ('\\u{30d}', '\\u{30d}', script_extensions::LATN_SUNU),\n        ('\\u{30e}', '\\u{30e}', script_extensions::ETHI_LATN), ('\\u{310}', '\\u{310}',\n        script_extensions::LATN_SUNU), ('\\u{311}', '\\u{311}', script_extensions::CYRL_LATN_TODR),\n        ('\\u{313}', '\\u{313}', script_extensions::GREK_LATN_PERM_TODR), ('\\u{323}', '\\u{323}',\n        script_extensions::CHER_DUPL_KANA_LATN_SYRC_TFNG), ('\\u{324}', '\\u{324}',\n        script_extensions::CHER_DUPL_LATN_SYRC), ('\\u{325}', '\\u{325}',\n        script_extensions::LATN_SYRC), ('\\u{32d}', '\\u{32d}', script_extensions::LATN_SUNU_SYRC),\n        ('\\u{32e}', '\\u{32e}', script_extensions::LATN_SYRC), ('\\u{330}', '\\u{330}',\n        script_extensions::CHER_LATN_SYRC), ('\\u{331}', '\\u{331}',\n        script_extensions::AGHB_CHER_GOTH_LATN_SUNU_SYRC_THAI), ('\\u{342}', '\\u{342}',\n        script_extensions::GREK), ('\\u{345}', '\\u{345}', script_extensions::GREK), ('\\u{358}',\n        '\\u{358}', script_extensions::LATN_OSGE), ('\\u{35e}', '\\u{35e}',\n        script_extensions::AGHB_LATN_TODR), ('\\u{363}', '\\u{36f}', script_extensions::LATN),\n        ('\\u{374}', '\\u{374}', script_extensions::COPT_GREK), ('\\u{375}', '\\u{375}',\n        script_extensions::COPT_GREK), ('\\u{483}', '\\u{483}', script_extensions::CYRL_PERM),\n        ('\\u{484}', '\\u{484}', script_extensions::CYRL_GLAG), ('\\u{485}', '\\u{486}',\n        script_extensions::CYRL_LATN), ('\\u{487}', '\\u{487}', script_extensions::CYRL_GLAG),\n        ('\\u{589}', '\\u{589}', script_extensions::ARMN_GEOR_GLAG), ('\\u{60c}', '\\u{60c}',\n        script_extensions::ARAB_GARA_NKOO_ROHG_SYRC_THAA_YEZI), ('\\u{61b}', '\\u{61b}',\n        script_extensions::ARAB_GARA_NKOO_ROHG_SYRC_THAA_YEZI), ('\\u{61c}', '\\u{61c}',\n        script_extensions::ARAB_SYRC_THAA), ('\\u{61f}', '\\u{61f}',\n        script_extensions::ADLM_ARAB_GARA_NKOO_ROHG_SYRC_THAA_YEZI), ('\\u{640}', '\\u{640}',\n        script_extensions::ADLM_ARAB_MAND_MANI_OUGR_PHLP_ROHG_SOGD_SYRC), ('\\u{64b}', '\\u{655}',\n        script_extensions::ARAB_SYRC), ('\\u{660}', '\\u{669}', script_extensions::ARAB_THAA_YEZI),\n        ('\\u{670}', '\\u{670}', script_extensions::ARAB_SYRC), ('\\u{6d4}', '\\u{6d4}',\n        script_extensions::ARAB_ROHG), ('\\u{951}', '\\u{951}',\n        script_extensions::BENG_DEVA_GRAN_GUJR_GURU_KNDA_LATN_MLYM_NAND_NEWA_ORYA_SHRD_TAML_TELU_TIRH),\n        ('\\u{952}', '\\u{952}',\n        script_extensions::BENG_DEVA_GRAN_GUJR_GURU_KNDA_LATN_MLYM_NEWA_ORYA_TAML_TELU_TIRH),\n        ('\\u{964}', '\\u{964}',\n        script_extensions::BENG_DEVA_DOGR_GONG_GONM_GRAN_GUJR_GURU_KNDA_MAHJ_MLYM_NAND_ONAO_ORYA_SIND_SINH_SYLO_TAKR_TAML_TELU_TIRH),\n        ('\\u{965}', '\\u{965}',\n        script_extensions::BENG_DEVA_DOGR_GONG_GONM_GRAN_GUJR_GUKH_GURU_KNDA_LIMB_MAHJ_MLYM_NAND_ONAO_ORYA_SIND_SINH_SYLO_TAKR_TAML_TELU_TIRH),\n        ('\\u{966}', '\\u{96f}', script_extensions::DEVA_DOGR_KTHI_MAHJ), ('\\u{9e6}', '\\u{9ef}',\n        script_extensions::BENG_CAKM_SYLO), ('\\u{a66}', '\\u{a6f}', script_extensions::GURU_MULT),\n        ('\\u{ae6}', '\\u{aef}', script_extensions::GUJR_KHOJ), ('\\u{be6}', '\\u{bef}',\n        script_extensions::GRAN_TAML), ('\\u{bf0}', '\\u{bf2}', script_extensions::GRAN_TAML),\n        ('\\u{bf3}', '\\u{bf3}', script_extensions::GRAN_TAML), ('\\u{ce6}', '\\u{cef}',\n        script_extensions::KNDA_NAND_TUTG), ('\\u{1040}', '\\u{1049}',\n        script_extensions::CAKM_MYMR_TALE), ('\\u{10fb}', '\\u{10fb}',\n        script_extensions::GEOR_GLAG_LATN), ('\\u{16eb}', '\\u{16ed}', script_extensions::RUNR),\n        ('\\u{1735}', '\\u{1736}', script_extensions::BUHD_HANO_TAGB_TGLG), ('\\u{1802}', '\\u{1803}',\n        script_extensions::MONG_PHAG), ('\\u{1805}', '\\u{1805}', script_extensions::MONG_PHAG),\n        ('\\u{1cd0}', '\\u{1cd0}', script_extensions::BENG_DEVA_GRAN_KNDA), ('\\u{1cd1}', '\\u{1cd1}',\n        script_extensions::DEVA), ('\\u{1cd2}', '\\u{1cd2}', script_extensions::BENG_DEVA_GRAN_KNDA),\n        ('\\u{1cd3}', '\\u{1cd3}', script_extensions::DEVA_GRAN_KNDA), ('\\u{1cd4}', '\\u{1cd4}',\n        script_extensions::DEVA), ('\\u{1cd5}', '\\u{1cd5}',\n        script_extensions::BENG_DEVA_NEWA_TELU_TIRH), ('\\u{1cd6}', '\\u{1cd6}',\n        script_extensions::BENG_DEVA_TELU), ('\\u{1cd7}', '\\u{1cd7}',\n        script_extensions::DEVA_NEWA_SHRD), ('\\u{1cd8}', '\\u{1cd8}',\n        script_extensions::BENG_DEVA_NEWA_TELU), ('\\u{1cd9}', '\\u{1cd9}',\n        script_extensions::DEVA_SHRD), ('\\u{1cda}', '\\u{1cda}',\n        script_extensions::DEVA_KNDA_MLYM_ORYA_TAML_TELU), ('\\u{1cdb}', '\\u{1cdb}',\n        script_extensions::DEVA), ('\\u{1cdc}', '\\u{1cdd}', script_extensions::DEVA_SHRD),\n        ('\\u{1cde}', '\\u{1cdf}', script_extensions::DEVA), ('\\u{1ce0}', '\\u{1ce0}',\n        script_extensions::DEVA_SHRD), ('\\u{1ce1}', '\\u{1ce1}', script_extensions::BENG_DEVA),\n        ('\\u{1ce2}', '\\u{1ce2}', script_extensions::DEVA_NEWA_TIRH), ('\\u{1ce3}', '\\u{1ce8}',\n        script_extensions::DEVA), ('\\u{1ce9}', '\\u{1ce9}', script_extensions::DEVA_NAND_NEWA),\n        ('\\u{1cea}', '\\u{1cea}', script_extensions::BENG_DEVA_SHRD), ('\\u{1ceb}', '\\u{1ceb}',\n        script_extensions::DEVA_NEWA), ('\\u{1cec}', '\\u{1cec}', script_extensions::DEVA),\n        ('\\u{1ced}', '\\u{1ced}', script_extensions::BENG_DEVA_NEWA_SHRD), ('\\u{1cee}', '\\u{1cf1}',\n        script_extensions::DEVA), ('\\u{1cf2}', '\\u{1cf2}',\n        script_extensions::BENG_DEVA_GRAN_KNDA_MLYM_NAND_ORYA_SINH_TELU_TIRH_TUTG), ('\\u{1cf3}',\n        '\\u{1cf3}', script_extensions::DEVA_GRAN), ('\\u{1cf4}', '\\u{1cf4}',\n        script_extensions::DEVA_GRAN_KNDA_TUTG), ('\\u{1cf5}', '\\u{1cf6}',\n        script_extensions::BENG_DEVA), ('\\u{1cf7}', '\\u{1cf7}', script_extensions::BENG),\n        ('\\u{1cf8}', '\\u{1cf9}', script_extensions::DEVA_GRAN), ('\\u{1cfa}', '\\u{1cfa}',\n        script_extensions::NAND), ('\\u{1dc0}', '\\u{1dc1}', script_extensions::GREK), ('\\u{1df8}',\n        '\\u{1df8}', script_extensions::CYRL_LATN_SYRC), ('\\u{1dfa}', '\\u{1dfa}',\n        script_extensions::SYRC), ('\\u{202f}', '\\u{202f}', script_extensions::LATN_MONG_PHAG),\n        ('\\u{204f}', '\\u{204f}', script_extensions::ADLM_ARAB), ('\\u{205a}', '\\u{205a}',\n        script_extensions::CARI_GEOR_GLAG_HUNG_LYCI_ORKH), ('\\u{205d}', '\\u{205d}',\n        script_extensions::CARI_GREK_HUNG_MERO), ('\\u{20f0}', '\\u{20f0}',\n        script_extensions::DEVA_GRAN_LATN), ('\\u{2e17}', '\\u{2e17}', script_extensions::COPT_LATN),\n        ('\\u{2e30}', '\\u{2e30}', script_extensions::AVST_ORKH), ('\\u{2e31}', '\\u{2e31}',\n        script_extensions::AVST_CARI_GEOR_HUNG_KTHI_LYDI_SAMR), ('\\u{2e3c}', '\\u{2e3c}',\n        script_extensions::DUPL), ('\\u{2e41}', '\\u{2e41}', script_extensions::ADLM_ARAB_HUNG),\n        ('\\u{2e43}', '\\u{2e43}', script_extensions::CYRL_GLAG), ('\\u{2ff0}', '\\u{2fff}',\n        script_extensions::HANI_TANG), ('\\u{3001}', '\\u{3001}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_MONG_YIII), ('\\u{3002}', '\\u{3002}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_MONG_PHAG_YIII), ('\\u{3003}', '\\u{3003}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\\u{3006}', '\\u{3006}',\n        script_extensions::HANI), ('\\u{3008}', '\\u{3008}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_MONG_TIBT_YIII), ('\\u{3009}', '\\u{3009}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_MONG_TIBT_YIII), ('\\u{300a}', '\\u{300a}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_LISU_MONG_TIBT_YIII), ('\\u{300b}', '\\u{300b}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_LISU_MONG_TIBT_YIII), ('\\u{300c}', '\\u{300c}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{300d}', '\\u{300d}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{300e}', '\\u{300e}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{300f}', '\\u{300f}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{3010}', '\\u{3010}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{3011}', '\\u{3011}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{3013}', '\\u{3013}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\\u{3014}', '\\u{3014}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{3015}', '\\u{3015}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{3016}', '\\u{3016}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{3017}', '\\u{3017}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{3018}', '\\u{3018}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{3019}', '\\u{3019}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{301a}', '\\u{301a}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{301b}', '\\u{301b}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{301c}', '\\u{301c}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\\u{301d}', '\\u{301d}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\\u{301e}', '\\u{301f}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\\u{302a}', '\\u{302d}',\n        script_extensions::BOPO_HANI), ('\\u{3030}', '\\u{3030}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\\u{3031}', '\\u{3035}',\n        script_extensions::HIRA_KANA), ('\\u{3037}', '\\u{3037}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\\u{303c}', '\\u{303c}',\n        script_extensions::HANI_HIRA_KANA), ('\\u{303d}', '\\u{303d}',\n        script_extensions::HANI_HIRA_KANA), ('\\u{303e}', '\\u{303f}', script_extensions::HANI),\n        ('\\u{3099}', '\\u{309a}', script_extensions::HIRA_KANA), ('\\u{309b}', '\\u{309c}',\n        script_extensions::HIRA_KANA), ('\\u{30a0}', '\\u{30a0}', script_extensions::HIRA_KANA),\n        ('\\u{30fb}', '\\u{30fb}', script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{30fc}',\n        '\\u{30fc}', script_extensions::HIRA_KANA), ('\\u{3190}', '\\u{3191}',\n        script_extensions::HANI), ('\\u{3192}', '\\u{3195}', script_extensions::HANI), ('\\u{3196}',\n        '\\u{319f}', script_extensions::HANI), ('\\u{31c0}', '\\u{31e5}', script_extensions::HANI),\n        ('\\u{31ef}', '\\u{31ef}', script_extensions::HANI_TANG), ('\\u{3220}', '\\u{3229}',\n        script_extensions::HANI), ('\\u{322a}', '\\u{3247}', script_extensions::HANI), ('\\u{3280}',\n        '\\u{3289}', script_extensions::HANI), ('\\u{328a}', '\\u{32b0}', script_extensions::HANI),\n        ('\\u{32c0}', '\\u{32cb}', script_extensions::HANI), ('\\u{32ff}', '\\u{32ff}',\n        script_extensions::HANI), ('\\u{3358}', '\\u{3370}', script_extensions::HANI), ('\\u{337b}',\n        '\\u{337f}', script_extensions::HANI), ('\\u{33e0}', '\\u{33fe}', script_extensions::HANI),\n        ('\\u{a66f}', '\\u{a66f}', script_extensions::CYRL_GLAG), ('\\u{a700}', '\\u{a707}',\n        script_extensions::HANI_LATN), ('\\u{a830}', '\\u{a832}',\n        script_extensions::DEVA_DOGR_GUJR_GURU_KHOJ_KNDA_KTHI_MAHJ_MLYM_MODI_NAND_SHRD_SIND_TAKR_TIRH_TUTG),\n        ('\\u{a833}', '\\u{a835}',\n        script_extensions::DEVA_DOGR_GUJR_GURU_KHOJ_KNDA_KTHI_MAHJ_MODI_NAND_SHRD_SIND_TAKR_TIRH_TUTG),\n        ('\\u{a836}', '\\u{a837}',\n        script_extensions::DEVA_DOGR_GUJR_GURU_KHOJ_KTHI_MAHJ_MODI_SIND_TAKR_TIRH), ('\\u{a838}',\n        '\\u{a838}', script_extensions::DEVA_DOGR_GUJR_GURU_KHOJ_KTHI_MAHJ_MODI_SHRD_SIND_TAKR_TIRH),\n        ('\\u{a839}', '\\u{a839}',\n        script_extensions::DEVA_DOGR_GUJR_GURU_KHOJ_KTHI_MAHJ_MODI_SIND_TAKR_TIRH), ('\\u{a8f1}',\n        '\\u{a8f1}', script_extensions::BENG_DEVA_TUTG), ('\\u{a8f3}', '\\u{a8f3}',\n        script_extensions::DEVA_TAML), ('\\u{a92e}', '\\u{a92e}', script_extensions::KALI_LATN_MYMR),\n        ('\\u{a9cf}', '\\u{a9cf}', script_extensions::BUGI_JAVA), ('\\u{fd3e}', '\\u{fd3e}',\n        script_extensions::ARAB_NKOO), ('\\u{fd3f}', '\\u{fd3f}', script_extensions::ARAB_NKOO),\n        ('\\u{fdf2}', '\\u{fdf2}', script_extensions::ARAB_THAA), ('\\u{fdfd}', '\\u{fdfd}',\n        script_extensions::ARAB_THAA), ('\\u{fe45}', '\\u{fe46}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA), ('\\u{ff61}', '\\u{ff61}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{ff62}', '\\u{ff62}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{ff63}', '\\u{ff63}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{ff64}', '\\u{ff65}',\n        script_extensions::BOPO_HANG_HANI_HIRA_KANA_YIII), ('\\u{ff70}', '\\u{ff70}',\n        script_extensions::HIRA_KANA), ('\\u{ff9e}', '\\u{ff9f}', script_extensions::HIRA_KANA),\n        ('\\u{10100}', '\\u{10101}', script_extensions::CPMN_CPRT_LINB), ('\\u{10102}', '\\u{10102}',\n        script_extensions::CPRT_LINB), ('\\u{10107}', '\\u{10133}',\n        script_extensions::CPRT_LINA_LINB), ('\\u{10137}', '\\u{1013f}',\n        script_extensions::CPRT_LINB), ('\\u{102e0}', '\\u{102e0}', script_extensions::ARAB_COPT),\n        ('\\u{102e1}', '\\u{102fb}', script_extensions::ARAB_COPT), ('\\u{10af2}', '\\u{10af2}',\n        script_extensions::MANI_OUGR), ('\\u{11301}', '\\u{11301}', script_extensions::GRAN_TAML),\n        ('\\u{11303}', '\\u{11303}', script_extensions::GRAN_TAML), ('\\u{1133b}', '\\u{1133c}',\n        script_extensions::GRAN_TAML), ('\\u{11fd0}', '\\u{11fd1}', script_extensions::GRAN_TAML),\n        ('\\u{11fd3}', '\\u{11fd3}', script_extensions::GRAN_TAML), ('\\u{1bca0}', '\\u{1bca3}',\n        script_extensions::DUPL), ('\\u{1d360}', '\\u{1d371}', script_extensions::HANI), ('\\u{1f250}',\n        '\\u{1f251}', script_extensions::HANI)\n    ];\n\n\n}\n"
    },
    {
      "package": "unicode-segmentation@1.13.3",
      "sourcePath": "src/grapheme.rs",
      "sha256": "730d50fb3d2858840e61ed3805a67336fd0b02c0e6bb9192306511ae6adfdbb3",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse crate::tables::grapheme::GraphemeCat;\nuse core::cmp;\n\n/// External iterator for grapheme clusters and byte offsets.\n///\n/// This struct is created by the [`grapheme_indices`] method on the [`UnicodeSegmentation`]\n/// trait. See its documentation for more.\n///\n/// [`grapheme_indices`]: trait.UnicodeSegmentation.html#tymethod.grapheme_indices\n/// [`UnicodeSegmentation`]: trait.UnicodeSegmentation.html\n#[derive(Debug, Clone)]\npub struct GraphemeIndices<'a> {\n    start_offset: usize,\n    iter: Graphemes<'a>,\n}\n\nimpl<'a> GraphemeIndices<'a> {\n    #[inline]\n    /// View the underlying data (the part yet to be iterated) as a slice of the original string.\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::UnicodeSegmentation;\n    /// let mut iter = \"abc\".grapheme_indices(true);\n    /// assert_eq!(iter.as_str(), \"abc\");\n    /// iter.next();\n    /// assert_eq!(iter.as_str(), \"bc\");\n    /// iter.next();\n    /// iter.next();\n    /// assert_eq!(iter.as_str(), \"\");\n    /// ```\n    pub fn as_str(&self) -> &'a str {\n        self.iter.as_str()\n    }\n}\n\nimpl<'a> Iterator for GraphemeIndices<'a> {\n    type Item = (usize, &'a str);\n\n    #[inline]\n    fn next(&mut self) -> Option<(usize, &'a str)> {\n        self.iter\n            .next()\n            .map(|s| (s.as_ptr() as usize - self.start_offset, s))\n    }\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.iter.size_hint()\n    }\n}\n\nimpl<'a> DoubleEndedIterator for GraphemeIndices<'a> {\n    #[inline]\n    fn next_back(&mut self) -> Option<(usize, &'a str)> {\n        self.iter\n            .next_back()\n            .map(|s| (s.as_ptr() as usize - self.start_offset, s))\n    }\n}\n\n/// External iterator for a string's\n/// [grapheme clusters](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries).\n///\n/// This struct is created by the [`graphemes`] method on the [`UnicodeSegmentation`] trait. See its\n/// documentation for more.\n///\n/// [`graphemes`]: trait.UnicodeSegmentation.html#tymethod.graphemes\n/// [`UnicodeSegmentation`]: trait.UnicodeSegmentation.html\n#[derive(Clone, Debug)]\npub struct Graphemes<'a> {\n    string: &'a str,\n    cursor: GraphemeCursor,\n    cursor_back: GraphemeCursor,\n}\n\nimpl<'a> Graphemes<'a> {\n    #[inline]\n    /// View the underlying data (the part yet to be iterated) as a slice of the original string.\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::UnicodeSegmentation;\n    /// let mut iter = \"abc\".graphemes(true);\n    /// assert_eq!(iter.as_str(), \"abc\");\n    /// iter.next();\n    /// assert_eq!(iter.as_str(), \"bc\");\n    /// iter.next();\n    /// iter.next();\n    /// assert_eq!(iter.as_str(), \"\");\n    /// ```\n    pub fn as_str(&self) -> &'a str {\n        &self.string[self.cursor.cur_cursor()..self.cursor_back.cur_cursor()]\n    }\n}\n\nimpl<'a> Iterator for Graphemes<'a> {\n    type Item = &'a str;\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let slen = self.cursor_back.cur_cursor() - self.cursor.cur_cursor();\n        (cmp::min(slen, 1), Some(slen))\n    }\n\n    #[inline]\n    fn next(&mut self) -> Option<&'a str> {\n        let start = self.cursor.cur_cursor();\n        if start == self.cursor_back.cur_cursor() {\n            return None;\n        }\n        let next = self.cursor.next_boundary(self.string, 0).unwrap().unwrap();\n        Some(&self.string[start..next])\n    }\n}\n\nimpl<'a> DoubleEndedIterator for Graphemes<'a> {\n    #[inline]\n    fn next_back(&mut self) -> Option<&'a str> {\n        let end = self.cursor_back.cur_cursor();\n        if end == self.cursor.cur_cursor() {\n            return None;\n        }\n        let prev = self\n            .cursor_back\n            .prev_boundary(self.string, 0)\n            .unwrap()\n            .unwrap();\n        Some(&self.string[prev..end])\n    }\n}\n\n#[inline]\npub fn new_graphemes(s: &str, is_extended: bool) -> Graphemes<'_> {\n    let len = s.len();\n    Graphemes {\n        string: s,\n        cursor: GraphemeCursor::new(0, len, is_extended),\n        cursor_back: GraphemeCursor::new(len, len, is_extended),\n    }\n}\n\n#[inline]\npub fn new_grapheme_indices(s: &str, is_extended: bool) -> GraphemeIndices<'_> {\n    GraphemeIndices {\n        start_offset: s.as_ptr() as usize,\n        iter: new_graphemes(s, is_extended),\n    }\n}\n\n/// maybe unify with PairResult?\n/// An enum describing information about a potential boundary.\n#[derive(PartialEq, Eq, Clone, Debug)]\nenum GraphemeState {\n    /// No information is known.\n    Unknown,\n    /// It is known to not be a boundary.\n    NotBreak,\n    /// It is known to be a boundary.\n    Break,\n    /// The codepoint after it has Indic_Conjunct_Break=Consonant,\n    /// so there is a break before so a boundary if it is preceded by another\n    /// InCB=Consonant follwoed by a sequence consisting of one or more InCB=Linker\n    /// and zero or more InCB = Extend (in any order).\n    InCbConsonant,\n    /// The codepoint after is a Regional Indicator Symbol, so a boundary iff\n    /// it is preceded by an even number of RIS codepoints. (GB12, GB13)\n    Regional,\n    /// The codepoint after is Extended_Pictographic,\n    /// so whether it's a boundary depends on pre-context according to GB11.\n    Emoji {\n        /// Whether the ZWJ char has been seen already an only a \"\\p{Extended_Pictographic} Extend*\"\n        /// part of GB11 has to be checked\n        seen_zwj: bool,\n    },\n}\n\n/// Cursor-based segmenter for grapheme clusters.\n///\n/// This allows working with ropes and other datastructures where the string is not contiguous or\n/// fully known at initialization time.\n#[derive(Clone, Debug)]\npub struct GraphemeCursor {\n    /// Current cursor position.\n    offset: usize,\n    /// Total length of the string.\n    len: usize,\n    /// A config flag indicating whether this cursor computes legacy or extended\n    /// grapheme cluster boundaries (enables GB9a and GB9b if set).\n    is_extended: bool,\n    /// Information about the potential boundary at `offset`\n    state: GraphemeState,\n    /// Category of codepoint immediately preceding cursor, if known.\n    cat_before: Option<GraphemeCat>,\n    /// Category of codepoint immediately after cursor, if known.\n    cat_after: Option<GraphemeCat>,\n    /// If set, at least one more codepoint immediately preceding this offset\n    /// is needed to resolve whether there's a boundary at `offset`.\n    pre_context_offset: Option<usize>,\n    /// The number of `InCB=Linker` codepoints preceding `offset`\n    /// (potentially intermingled with `InCB=Extend`).\n    incb_linker_count: Option<usize>,\n    /// The number of RIS codepoints preceding `offset`. If `pre_context_offset`\n    /// is set, then counts the number of RIS between that and `offset`, otherwise\n    /// is an accurate count relative to the string.\n    ris_count: Option<usize>,\n    /// Set if a call to `prev_boundary` or `next_boundary` was suspended due\n    /// to needing more input.\n    resuming: bool,\n    /// Cached grapheme category and associated scalar value range.\n    grapheme_cat_cache: (u32, u32, GraphemeCat),\n}\n\n/// An error return indicating that not enough content was available in the\n/// provided chunk to satisfy the query, and that more content must be provided.\n#[derive(PartialEq, Eq, Debug)]\npub enum GraphemeIncomplete {\n    /// More pre-context is needed. The caller should call `provide_context`\n    /// with a chunk ending at the offset given, then retry the query. This\n    /// will only be returned if the `chunk_start` parameter is nonzero.\n    PreContext(usize),\n\n    /// When requesting `prev_boundary`, the cursor is moving past the beginning\n    /// of the current chunk, so the chunk before that is requested. This will\n    /// only be returned if the `chunk_start` parameter is nonzero.\n    PrevChunk,\n\n    /// When requesting `next_boundary`, the cursor is moving past the end of the\n    /// current chunk, so the chunk after that is requested. This will only be\n    /// returned if the chunk ends before the `len` parameter provided on\n    /// creation of the cursor.\n    NextChunk, // requesting chunk following the one given\n\n    /// An error returned when the chunk given does not contain the cursor position.\n    InvalidOffset,\n}\n\n// An enum describing the result from lookup of a pair of categories.\n#[derive(PartialEq, Eq)]\nenum PairResult {\n    /// definitely not a break\n    NotBreak,\n    /// definitely a break\n    Break,\n    /// a break iff not in extended mode\n    Extended,\n    /// a break unless in extended mode and preceded by\n    /// a sequence of 0 or more InCB=Extend and one or more\n    /// InCB = Linker (in any order),\n    /// preceded by another InCB=Consonant\n    InCbConsonant,\n    /// a break if preceded by an even number of RIS\n    Regional,\n    /// a break if preceded by emoji base and (Extend)*\n    Emoji,\n}\n\n#[inline]\nfn check_pair(before: GraphemeCat, after: GraphemeCat) -> PairResult {\n    use self::PairResult::*;\n    use crate::tables::grapheme::GraphemeCat::*;\n    match (before, after) {\n        (GC_CR, GC_LF) => NotBreak,                                 // GB3\n        (GC_Control | GC_CR | GC_LF, _) => Break,                   // GB4\n        (_, GC_Control | GC_CR | GC_LF) => Break,                   // GB5\n        (GC_L, GC_L | GC_V | GC_LV | GC_LVT) => NotBreak,           // GB6\n        (GC_LV | GC_V, GC_V | GC_T) => NotBreak,                    // GB7\n        (GC_LVT | GC_T, GC_T) => NotBreak,                          // GB8\n        (_, GC_Extend | GC_ZWJ) => NotBreak,                        // GB9\n        (_, GC_SpacingMark) => Extended,                            // GB9a\n        (GC_Prepend, _) => Extended,                                // GB9b\n        (_, GC_InCB_Consonant) => InCbConsonant,                    // GB9c\n        (GC_ZWJ, GC_Extended_Pictographic) => Emoji,                // GB11\n        (GC_Regional_Indicator, GC_Regional_Indicator) => Regional, // GB12, GB13\n        (_, _) => Break,                                            // GB999\n    }\n}\n\nimpl GraphemeCursor {\n    /// Create a new cursor. The string and initial offset are given at creation\n    /// time, but the contents of the string are not. The `is_extended` parameter\n    /// controls whether extended grapheme clusters are selected.\n    ///\n    /// The `offset` parameter must be on a codepoint boundary.\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::GraphemeCursor;\n    /// let s = \"हिन्दी\";\n    /// let mut legacy = GraphemeCursor::new(0, s.len(), false);\n    /// assert_eq!(legacy.next_boundary(s, 0), Ok(Some(\"ह\".len())));\n    /// let mut extended = GraphemeCursor::new(0, s.len(), true);\n    /// assert_eq!(extended.next_boundary(s, 0), Ok(Some(\"हि\".len())));\n    /// ```\n    pub fn new(offset: usize, len: usize, is_extended: bool) -> GraphemeCursor {\n        let state = if offset == 0 || offset == len {\n            GraphemeState::Break\n        } else {\n            GraphemeState::Unknown\n        };\n        GraphemeCursor {\n            offset,\n            len,\n            state,\n            is_extended,\n            cat_before: None,\n            cat_after: None,\n            pre_context_offset: None,\n            incb_linker_count: None,\n            ris_count: None,\n            resuming: false,\n            grapheme_cat_cache: (0, 0, GraphemeCat::GC_Control),\n        }\n    }\n\n    fn grapheme_category(&mut self, ch: char) -> GraphemeCat {\n        use crate::tables::grapheme as gr;\n        use crate::tables::grapheme::GraphemeCat::*;\n\n        if ch <= '\\u{7e}' {\n            // Special-case optimization for ascii, except U+007F.  This\n            // improves performance even for many primarily non-ascii texts,\n            // due to use of punctuation and white space characters from the\n            // ascii range.\n            if ch >= '\\u{20}' {\n                GC_Any\n            } else if ch == '\\n' {\n                GC_LF\n            } else if ch == '\\r' {\n                GC_CR\n            } else {\n                GC_Control\n            }\n        } else {\n            // If this char isn't within the cached range, update the cache to the\n            // range that includes it.\n            if (ch as u32) < self.grapheme_cat_cache.0 || (ch as u32) > self.grapheme_cat_cache.1 {\n                self.grapheme_cat_cache = gr::grapheme_category(ch);\n            }\n            self.grapheme_cat_cache.2\n        }\n    }\n\n    // Not sure I'm gonna keep this, the advantage over new() seems thin.\n\n    /// Set the cursor to a new location in the same string.\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::GraphemeCursor;\n    /// let s = \"abcd\";\n    /// let mut cursor = GraphemeCursor::new(0, s.len(), false);\n    /// assert_eq!(cursor.cur_cursor(), 0);\n    /// cursor.set_cursor(2);\n    /// assert_eq!(cursor.cur_cursor(), 2);\n    /// ```\n    pub fn set_cursor(&mut self, offset: usize) {\n        if offset != self.offset {\n            self.offset = offset;\n            self.state = if offset == 0 || offset == self.len {\n                GraphemeState::Break\n            } else {\n                GraphemeState::Unknown\n            };\n            // reset state derived from text around cursor\n            self.cat_before = None;\n            self.cat_after = None;\n            self.incb_linker_count = None;\n            self.ris_count = None;\n        }\n    }\n\n    #[inline]\n    /// The current offset of the cursor. Equal to the last value provided to\n    /// `new()` or `set_cursor()`, or returned from `next_boundary()` or\n    /// `prev_boundary()`.\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::GraphemeCursor;\n    /// // Two flags (🇷🇸🇮🇴), each flag is two RIS codepoints, each RIS is 4 bytes.\n    /// let flags = \"\\u{1F1F7}\\u{1F1F8}\\u{1F1EE}\\u{1F1F4}\";\n    /// let mut cursor = GraphemeCursor::new(4, flags.len(), false);\n    /// assert_eq!(cursor.cur_cursor(), 4);\n    /// assert_eq!(cursor.next_boundary(flags, 0), Ok(Some(8)));\n    /// assert_eq!(cursor.cur_cursor(), 8);\n    /// ```\n    pub fn cur_cursor(&self) -> usize {\n        self.offset\n    }\n\n    /// Provide additional pre-context when it is needed to decide a boundary.\n    /// The end of the chunk must coincide with the value given in the\n    /// `GraphemeIncomplete::PreContext` request.\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete};\n    /// let flags = \"\\u{1F1F7}\\u{1F1F8}\\u{1F1EE}\\u{1F1F4}\";\n    /// let mut cursor = GraphemeCursor::new(8, flags.len(), false);\n    /// // Not enough pre-context to decide if there's a boundary between the two flags.\n    /// assert_eq!(cursor.is_boundary(&flags[8..], 8), Err(GraphemeIncomplete::PreContext(8)));\n    /// // Provide one more Regional Indicator Symbol of pre-context\n    /// cursor.provide_context(&flags[4..8], 4);\n    /// // Still not enough context to decide.\n    /// assert_eq!(cursor.is_boundary(&flags[8..], 8), Err(GraphemeIncomplete::PreContext(4)));\n    /// // Provide additional requested context.\n    /// cursor.provide_context(&flags[0..4], 0);\n    /// // That's enough to decide (it always is when context goes to the start of the string)\n    /// assert_eq!(cursor.is_boundary(&flags[8..], 8), Ok(true));\n    /// ```\n    pub fn provide_context(&mut self, chunk: &str, chunk_start: usize) {\n        use crate::tables::grapheme as gr;\n        assert!(chunk_start.saturating_add(chunk.len()) == self.pre_context_offset.unwrap());\n        self.pre_context_offset = None;\n        if self.is_extended && chunk_start + chunk.len() == self.offset {\n            let ch = chunk.chars().next_back().unwrap();\n            if self.grapheme_category(ch) == gr::GC_Prepend {\n                self.decide(false); // GB9b\n                return;\n            }\n        }\n        match self.state {\n            GraphemeState::InCbConsonant => self.handle_incb_consonant(chunk, chunk_start),\n            GraphemeState::Regional => self.handle_regional(chunk, chunk_start),\n            GraphemeState::Emoji { seen_zwj } => self.handle_emoji(chunk, chunk_start, seen_zwj),\n            _ => {\n                if self.cat_before.is_none() && self.offset == chunk.len() + chunk_start {\n                    let ch = chunk.chars().next_back().unwrap();\n                    self.cat_before = Some(self.grapheme_category(ch));\n                }\n            }\n        }\n    }\n\n    #[inline]\n    fn decide(&mut self, is_break: bool) {\n        self.state = if is_break {\n            GraphemeState::Break\n        } else {\n            GraphemeState::NotBreak\n        };\n    }\n\n    #[inline]\n    fn decision(&mut self, is_break: bool) -> Result<bool, GraphemeIncomplete> {\n        self.decide(is_break);\n        Ok(is_break)\n    }\n\n    #[inline]\n    fn is_boundary_result(&self) -> Result<bool, GraphemeIncomplete> {\n        if self.state == GraphemeState::Break {\n            Ok(true)\n        } else if self.state == GraphemeState::NotBreak {\n            Ok(false)\n        } else if let Some(pre_context_offset) = self.pre_context_offset {\n            Err(GraphemeIncomplete::PreContext(pre_context_offset))\n        } else {\n            unreachable!(\"inconsistent state\");\n        }\n    }\n\n    /// For handling rule GB9c:\n    ///\n    /// There's an `InCB=Consonant` after this, and we need to look back\n    /// to verify whether there should be a break.\n    ///\n    /// Seek backward to find an `InCB=Linker` preceded by an `InCB=Consonsnt`\n    /// (potentially separated by some number of `InCB=Linker` or `InCB=Extend`).\n    /// If we find the consonant in question, then there's no break; if we find a consonant\n    /// with no linker, or a non-linker non-extend non-consonant, or the start of text, there's a break;\n    /// otherwise we need more context\n    #[inline]\n    fn handle_incb_consonant(&mut self, chunk: &str, chunk_start: usize) {\n        use crate::tables::{self, grapheme as gr};\n\n        // GB9c only applies to extended grapheme clusters\n        if !self.is_extended {\n            self.decide(true);\n            return;\n        }\n\n        let mut incb_linker_count = self.incb_linker_count.unwrap_or(0);\n\n        for ch in chunk.chars().rev() {\n            if tables::is_incb_linker(ch) {\n                // We found an InCB linker\n                incb_linker_count += 1;\n                self.incb_linker_count = Some(incb_linker_count);\n            } else if tables::derived_property::InCB_Extend(ch) {\n                // We ignore InCB extends, continue\n            } else {\n                // Prev character is neither linker nor extend, break suppressed iff it's InCB=Consonant\n                let result = !(self.incb_linker_count.unwrap_or(0) > 0\n                    && self.grapheme_category(ch) == gr::GC_InCB_Consonant);\n                self.decide(result);\n                return;\n            }\n        }\n\n        if chunk_start == 0 {\n            // Start of text and we still haven't found a consonant, so break\n            self.decide(true);\n        } else {\n            // We need more context\n            self.pre_context_offset = Some(chunk_start);\n            self.state = GraphemeState::InCbConsonant;\n        }\n    }\n\n    #[inline]\n    fn handle_regional(&mut self, chunk: &str, chunk_start: usize) {\n        use crate::tables::grapheme as gr;\n        let mut ris_count = self.ris_count.unwrap_or(0);\n        for ch in chunk.chars().rev() {\n            if self.grapheme_category(ch) != gr::GC_Regional_Indicator {\n                self.ris_count = Some(ris_count);\n                self.decide(ris_count % 2 == 0);\n                return;\n            }\n            ris_count += 1;\n        }\n        self.ris_count = Some(ris_count);\n        if chunk_start == 0 {\n            self.decide(ris_count % 2 == 0);\n        } else {\n            self.pre_context_offset = Some(chunk_start);\n            self.state = GraphemeState::Regional;\n        }\n    }\n\n    #[inline]\n    fn handle_emoji(&mut self, chunk: &str, chunk_start: usize, mut seen_zwj: bool) {\n        // \\p{Extended_Pictographic} Extend* ZWJ \t× \t\\p{Extended_Pictographic}\n        use crate::tables::grapheme as gr;\n        let mut iter = chunk.chars().rev();\n        if !seen_zwj {\n            if let Some(ch) = iter.next() {\n                if self.grapheme_category(ch) != gr::GC_ZWJ {\n                    self.decide(true);\n                    return;\n                } else {\n                    seen_zwj = true;\n                }\n            }\n        }\n        for ch in iter {\n            match self.grapheme_category(ch) {\n                gr::GC_Extend => (),\n                gr::GC_Extended_Pictographic => {\n                    self.decide(false);\n                    return;\n                }\n                _ => {\n                    self.decide(true);\n                    return;\n                }\n            }\n        }\n        if chunk_start == 0 {\n            self.decide(true);\n        } else {\n            self.pre_context_offset = Some(chunk_start);\n            self.state = GraphemeState::Emoji { seen_zwj };\n        }\n    }\n\n    #[inline]\n    /// Determine whether the current cursor location is a grapheme cluster boundary.\n    /// Only a part of the string need be supplied. If `chunk_start` is nonzero or\n    /// the length of `chunk` is not equal to `len` on creation, then this method\n    /// may return `GraphemeIncomplete::PreContext`. The caller should then\n    /// call `provide_context` with the requested chunk, then retry calling this\n    /// method.\n    ///\n    /// For partial chunks, if the cursor is not at the beginning or end of the\n    /// string, the chunk should contain at least the codepoint following the cursor.\n    /// If the string is nonempty, the chunk must be nonempty.\n    ///\n    /// All calls should have consistent chunk contents (ie, if a chunk provides\n    /// content for a given slice, all further chunks covering that slice must have\n    /// the same content for it).\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::GraphemeCursor;\n    /// let flags = \"\\u{1F1F7}\\u{1F1F8}\\u{1F1EE}\\u{1F1F4}\";\n    /// let mut cursor = GraphemeCursor::new(8, flags.len(), false);\n    /// assert_eq!(cursor.is_boundary(flags, 0), Ok(true));\n    /// cursor.set_cursor(12);\n    /// assert_eq!(cursor.is_boundary(flags, 0), Ok(false));\n    /// ```\n    pub fn is_boundary(\n        &mut self,\n        chunk: &str,\n        chunk_start: usize,\n    ) -> Result<bool, GraphemeIncomplete> {\n        use crate::tables::grapheme as gr;\n        if self.state == GraphemeState::Break {\n            return Ok(true);\n        }\n        if self.state == GraphemeState::NotBreak {\n            return Ok(false);\n        }\n        if (self.offset < chunk_start || self.offset >= chunk_start.saturating_add(chunk.len()))\n            && (self.offset > chunk_start.saturating_add(chunk.len()) || self.cat_after.is_none())\n        {\n            return Err(GraphemeIncomplete::InvalidOffset);\n        }\n        if let Some(pre_context_offset) = self.pre_context_offset {\n            return Err(GraphemeIncomplete::PreContext(pre_context_offset));\n        }\n        let offset_in_chunk = self.offset.saturating_sub(chunk_start);\n        if self.cat_after.is_none() {\n            let ch = chunk[offset_in_chunk..].chars().next().unwrap();\n            self.cat_after = Some(self.grapheme_category(ch));\n        }\n        if self.offset == chunk_start {\n            let mut need_pre_context = true;\n            match self.cat_after.unwrap() {\n                gr::GC_InCB_Consonant => self.state = GraphemeState::InCbConsonant,\n                gr::GC_Regional_Indicator => self.state = GraphemeState::Regional,\n                gr::GC_Extended_Pictographic => {\n                    self.state = GraphemeState::Emoji { seen_zwj: false }\n                }\n                _ => need_pre_context = self.cat_before.is_none(),\n            }\n            if need_pre_context {\n                self.pre_context_offset = Some(chunk_start);\n                return Err(GraphemeIncomplete::PreContext(chunk_start));\n            }\n        }\n        if self.cat_before.is_none() {\n            let ch = chunk[..offset_in_chunk].chars().next_back().unwrap();\n            self.cat_before = Some(self.grapheme_category(ch));\n        }\n        match check_pair(self.cat_before.unwrap(), self.cat_after.unwrap()) {\n            PairResult::NotBreak => self.decision(false),\n            PairResult::Break => self.decision(true),\n            PairResult::Extended => {\n                let is_extended = self.is_extended;\n                self.decision(!is_extended)\n            }\n            PairResult::InCbConsonant => {\n                self.handle_incb_consonant(&chunk[..offset_in_chunk], chunk_start);\n                self.is_boundary_result()\n            }\n            PairResult::Regional => {\n                if let Some(ris_count) = self.ris_count {\n                    return self.decision((ris_count % 2) == 0);\n                }\n                self.handle_regional(&chunk[..offset_in_chunk], chunk_start);\n                self.is_boundary_result()\n            }\n            PairResult::Emoji => {\n                self.handle_emoji(&chunk[..offset_in_chunk], chunk_start, false);\n                self.is_boundary_result()\n            }\n        }\n    }\n\n    #[inline]\n    /// Find the next boundary after the current cursor position. Only a part of\n    /// the string need be supplied. If the chunk is incomplete, then this\n    /// method might return `GraphemeIncomplete::PreContext` or\n    /// `GraphemeIncomplete::NextChunk`. In the former case, the caller should\n    /// call `provide_context` with the requested chunk, then retry. In the\n    /// latter case, the caller should provide the chunk following the one\n    /// given, then retry.\n    ///\n    /// See `is_boundary` for expectations on the provided chunk.\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::GraphemeCursor;\n    /// let flags = \"\\u{1F1F7}\\u{1F1F8}\\u{1F1EE}\\u{1F1F4}\";\n    /// let mut cursor = GraphemeCursor::new(4, flags.len(), false);\n    /// assert_eq!(cursor.next_boundary(flags, 0), Ok(Some(8)));\n    /// assert_eq!(cursor.next_boundary(flags, 0), Ok(Some(16)));\n    /// assert_eq!(cursor.next_boundary(flags, 0), Ok(None));\n    /// ```\n    ///\n    /// And an example that uses partial strings:\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete};\n    /// let s = \"abcd\";\n    /// let mut cursor = GraphemeCursor::new(0, s.len(), false);\n    /// assert_eq!(cursor.next_boundary(&s[..2], 0), Ok(Some(1)));\n    /// assert_eq!(cursor.next_boundary(&s[..2], 0), Err(GraphemeIncomplete::NextChunk));\n    /// assert_eq!(cursor.next_boundary(&s[2..4], 2), Ok(Some(2)));\n    /// assert_eq!(cursor.next_boundary(&s[2..4], 2), Ok(Some(3)));\n    /// assert_eq!(cursor.next_boundary(&s[2..4], 2), Ok(Some(4)));\n    /// assert_eq!(cursor.next_boundary(&s[2..4], 2), Ok(None));\n    /// ```\n    pub fn next_boundary(\n        &mut self,\n        chunk: &str,\n        chunk_start: usize,\n    ) -> Result<Option<usize>, GraphemeIncomplete> {\n        if self.offset == self.len {\n            return Ok(None);\n        }\n        let mut iter = chunk[self.offset.saturating_sub(chunk_start)..].chars();\n        let mut ch = match iter.next() {\n            Some(ch) => ch,\n            None => return Err(GraphemeIncomplete::NextChunk),\n        };\n        loop {\n            if self.resuming {\n                if self.cat_after.is_none() {\n                    self.cat_after = Some(self.grapheme_category(ch));\n                }\n            } else {\n                self.offset = self.offset.saturating_add(ch.len_utf8());\n                self.state = GraphemeState::Unknown;\n                self.cat_before = self.cat_after.take();\n                if self.cat_before.is_none() {\n                    self.cat_before = Some(self.grapheme_category(ch));\n                }\n                if crate::tables::is_incb_linker(ch) {\n                    self.incb_linker_count = Some(self.incb_linker_count.map_or(1, |c| c + 1));\n                } else if !crate::tables::derived_property::InCB_Extend(ch) {\n                    self.incb_linker_count = Some(0);\n                }\n                if self.cat_before.unwrap() == GraphemeCat::GC_Regional_Indicator {\n                    self.ris_count = self.ris_count.map(|c| c + 1);\n                } else {\n                    self.ris_count = Some(0);\n                }\n                if let Some(next_ch) = iter.next() {\n                    ch = next_ch;\n                    self.cat_after = Some(self.grapheme_category(ch));\n                } else if self.offset == self.len {\n                    self.decide(true);\n                } else {\n                    self.resuming = true;\n                    return Err(GraphemeIncomplete::NextChunk);\n                }\n            }\n            self.resuming = true;\n            if self.is_boundary(chunk, chunk_start)? {\n                self.resuming = false;\n                return Ok(Some(self.offset));\n            }\n            self.resuming = false;\n        }\n    }\n\n    /// Find the previous boundary after the current cursor position. Only a part\n    /// of the string need be supplied. If the chunk is incomplete, then this\n    /// method might return `GraphemeIncomplete::PreContext` or\n    /// `GraphemeIncomplete::PrevChunk`. In the former case, the caller should\n    /// call `provide_context` with the requested chunk, then retry. In the\n    /// latter case, the caller should provide the chunk preceding the one\n    /// given, then retry.\n    ///\n    /// See `is_boundary` for expectations on the provided chunk.\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::GraphemeCursor;\n    /// let flags = \"\\u{1F1F7}\\u{1F1F8}\\u{1F1EE}\\u{1F1F4}\";\n    /// let mut cursor = GraphemeCursor::new(12, flags.len(), false);\n    /// assert_eq!(cursor.prev_boundary(flags, 0), Ok(Some(8)));\n    /// assert_eq!(cursor.prev_boundary(flags, 0), Ok(Some(0)));\n    /// assert_eq!(cursor.prev_boundary(flags, 0), Ok(None));\n    /// ```\n    ///\n    /// And an example that uses partial strings (note the exact return is not\n    /// guaranteed, and may be `PrevChunk` or `PreContext` arbitrarily):\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete};\n    /// let s = \"abcd\";\n    /// let mut cursor = GraphemeCursor::new(4, s.len(), false);\n    /// assert_eq!(cursor.prev_boundary(&s[2..4], 2), Ok(Some(3)));\n    /// assert_eq!(cursor.prev_boundary(&s[2..4], 2), Err(GraphemeIncomplete::PrevChunk));\n    /// assert_eq!(cursor.prev_boundary(&s[0..2], 0), Ok(Some(2)));\n    /// assert_eq!(cursor.prev_boundary(&s[0..2], 0), Ok(Some(1)));\n    /// assert_eq!(cursor.prev_boundary(&s[0..2], 0), Ok(Some(0)));\n    /// assert_eq!(cursor.prev_boundary(&s[0..2], 0), Ok(None));\n    /// ```\n    pub fn prev_boundary(\n        &mut self,\n        chunk: &str,\n        chunk_start: usize,\n    ) -> Result<Option<usize>, GraphemeIncomplete> {\n        if self.offset == 0 {\n            return Ok(None);\n        }\n        if self.offset == chunk_start {\n            return Err(GraphemeIncomplete::PrevChunk);\n        }\n        let mut iter = chunk[..self.offset.saturating_sub(chunk_start)]\n            .chars()\n            .rev();\n        let mut ch = iter.next().unwrap();\n        loop {\n            if self.offset == chunk_start {\n                self.resuming = true;\n                return Err(GraphemeIncomplete::PrevChunk);\n            }\n            if self.resuming {\n                self.cat_before = Some(self.grapheme_category(ch));\n            } else {\n                self.offset -= ch.len_utf8();\n                self.cat_after = self.cat_before.take();\n                self.state = GraphemeState::Unknown;\n                if let Some(incb_linker_count) = self.incb_linker_count {\n                    self.incb_linker_count =\n                        if incb_linker_count > 0 && crate::tables::is_incb_linker(ch) {\n                            Some(incb_linker_count - 1)\n                        } else if crate::tables::derived_property::InCB_Extend(ch) {\n                            Some(incb_linker_count)\n                        } else {\n                            None\n                        };\n                }\n                if let Some(ris_count) = self.ris_count {\n                    self.ris_count = if ris_count > 0 {\n                        Some(ris_count - 1)\n                    } else {\n                        None\n                    };\n                }\n                if let Some(prev_ch) = iter.next() {\n                    ch = prev_ch;\n                    self.cat_before = Some(self.grapheme_category(ch));\n                } else if self.offset == 0 {\n                    self.decide(true);\n                } else {\n                    self.resuming = true;\n                    self.cat_after = Some(self.grapheme_category(ch));\n                    return Err(GraphemeIncomplete::PrevChunk);\n                }\n            }\n            self.resuming = true;\n            if self.is_boundary(chunk, chunk_start)? {\n                self.resuming = false;\n                return Ok(Some(self.offset));\n            }\n            self.resuming = false;\n        }\n    }\n}\n\n#[test]\nfn test_grapheme_cursor_ris_precontext() {\n    let s = \"\\u{1f1fa}\\u{1f1f8}\\u{1f1fa}\\u{1f1f8}\\u{1f1fa}\\u{1f1f8}\";\n    let mut c = GraphemeCursor::new(8, s.len(), true);\n    assert_eq!(\n        c.is_boundary(&s[4..], 4),\n        Err(GraphemeIncomplete::PreContext(4))\n    );\n    c.provide_context(&s[..4], 0);\n    assert_eq!(c.is_boundary(&s[4..], 4), Ok(true));\n}\n\n#[test]\nfn test_grapheme_cursor_chunk_start_require_precontext() {\n    let s = \"\\r\\n\";\n    let mut c = GraphemeCursor::new(1, s.len(), true);\n    assert_eq!(\n        c.is_boundary(&s[1..], 1),\n        Err(GraphemeIncomplete::PreContext(1))\n    );\n    c.provide_context(&s[..1], 0);\n    assert_eq!(c.is_boundary(&s[1..], 1), Ok(false));\n}\n\n#[test]\nfn test_grapheme_cursor_prev_boundary() {\n    let s = \"abcd\";\n    let mut c = GraphemeCursor::new(3, s.len(), true);\n    assert_eq!(\n        c.prev_boundary(&s[2..], 2),\n        Err(GraphemeIncomplete::PrevChunk)\n    );\n    assert_eq!(c.prev_boundary(&s[..2], 0), Ok(Some(2)));\n}\n\n#[test]\nfn test_grapheme_cursor_prev_boundary_chunk_start() {\n    let s = \"abcd\";\n    let mut c = GraphemeCursor::new(2, s.len(), true);\n    assert_eq!(\n        c.prev_boundary(&s[2..], 2),\n        Err(GraphemeIncomplete::PrevChunk)\n    );\n    assert_eq!(c.prev_boundary(&s[..2], 0), Ok(Some(1)));\n}\n\n#[test]\nfn test_grapheme_cursor_boundary_with_zwj_on_chunk_start() {\n    use GraphemeIncomplete::*;\n\n    let chunk0 = \"👩\"; // 4 bytes\n    let chunk1 = \"\\u{200d}🔬\"; // 3 bytes + 4 bytes\n\n    let full_len = chunk0.len() + chunk1.len();\n\n    let mut cur = GraphemeCursor::new(0, full_len, true);\n    assert_eq!(cur.next_boundary(chunk0, 0), Err(NextChunk));\n    match cur.next_boundary(chunk1, chunk0.len()) {\n        Ok(res) => assert_eq!(res, Some(11)),\n        Err(PreContext(_)) => {\n            cur.provide_context(chunk0, 0);\n            assert_eq!(cur.next_boundary(chunk1, chunk0.len()), Ok(Some(11)));\n        }\n        _ => unreachable!(),\n    }\n}\n\n#[test]\nfn test_grapheme_cursor_emoji_no_zwj() {\n    use GraphemeIncomplete::*;\n    let chunk0 = \"🍒\"; // 4 bytes\n    let chunk1 = \"🥑\"; // 4 bytes\n    let full_len = chunk0.len() + chunk1.len();\n\n    let mut c = GraphemeCursor::new(0, full_len, true);\n    assert_eq!(c.next_boundary(chunk0, 0), Err(NextChunk));\n    assert_eq!(\n        c.next_boundary(chunk1, chunk0.len()),\n        Err(PreContext(chunk0.len()))\n    );\n    c.provide_context(chunk0, 0);\n    assert_eq!(c.next_boundary(chunk1, chunk0.len()), Ok(Some(4)));\n    assert_eq!(c.next_boundary(chunk1, chunk0.len()), Ok(Some(8)));\n    assert_eq!(c.next_boundary(chunk1, chunk0.len()), Ok(None));\n}\n\n#[test]\nfn test_grapheme_cursor_emoji_chunk_boundary_before_zwj() {\n    use GraphemeIncomplete::*;\n    let chunk0 = \"🍒\"; // 4 bytes\n    let chunk1 = \"\\u{200d}🥑\"; // 3 + 4 bytes\n    let full_len = chunk0.len() + chunk1.len(); // 11\n\n    let mut c = GraphemeCursor::new(0, full_len, true);\n    assert_eq!(c.next_boundary(chunk0, 0), Err(NextChunk));\n    assert_eq!(\n        c.next_boundary(chunk1, chunk0.len()),\n        Err(PreContext(chunk0.len()))\n    );\n    c.provide_context(chunk0, 0);\n    assert_eq!(c.next_boundary(chunk1, chunk0.len()), Ok(Some(11)));\n    assert_eq!(c.next_boundary(chunk1, chunk0.len()), Ok(None));\n}\n\n#[test]\nfn test_grapheme_cursor_emoji_chunk_boundary_after_zwj() {\n    use GraphemeIncomplete::*;\n    let chunk0 = \"🍒\\u{200d}\"; // 4 + 3 bytes\n    let chunk1 = \"🥑\"; // 4 bytes\n    let full_len = chunk0.len() + chunk1.len(); // 11\n\n    let mut c = GraphemeCursor::new(0, full_len, true);\n    assert_eq!(c.next_boundary(chunk0, 0), Err(NextChunk));\n    assert_eq!(\n        c.next_boundary(chunk1, chunk0.len()),\n        Err(PreContext(chunk0.len()))\n    );\n    c.provide_context(chunk0, 0);\n    assert_eq!(c.next_boundary(chunk1, chunk0.len()), Ok(Some(11)));\n    assert_eq!(c.next_boundary(chunk1, chunk0.len()), Ok(None));\n}\n\n#[test]\nfn test_grapheme_cursor_emoji_zwj_across_chunks() {\n    use GraphemeIncomplete::*;\n    let chunk0 = \"🍒\"; // 4 bytes\n    let chunk1 = \"\\u{200d}\"; // 3 bytes\n    let chunk2 = \"🥑\"; // 4 bytes\n    let full_len = chunk0.len() + chunk1.len() + chunk2.len(); // 11\n    let chunk2_start = chunk0.len() + chunk1.len();\n\n    let mut c = GraphemeCursor::new(0, full_len, true);\n    assert_eq!(c.next_boundary(chunk0, 0), Err(NextChunk));\n    assert_eq!(c.next_boundary(chunk1, chunk0.len()), Err(NextChunk));\n    assert_eq!(\n        c.next_boundary(chunk2, chunk2_start),\n        Err(PreContext(chunk2_start))\n    );\n    c.provide_context(chunk1, chunk0.len());\n    assert_eq!(\n        c.next_boundary(chunk2, chunk2_start),\n        Err(PreContext(chunk0.len()))\n    );\n    c.provide_context(chunk0, 0);\n    assert_eq!(c.next_boundary(chunk2, chunk2_start), Ok(Some(11)));\n    assert_eq!(c.next_boundary(chunk2, chunk2_start), Ok(None));\n}\n"
    },
    {
      "package": "unicode-segmentation@1.13.3",
      "sourcePath": "src/lib.rs",
      "sha256": "3f5ddecddefa2caea4182b51bb5075a856ae542277a50c10a1a2216c54d86aac",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n//! Iterators which split strings on Grapheme Cluster, Word, or Sentence boundaries, according\n//! to the [Unicode Standard Annex #29](https://www.unicode.org/reports/tr29/) rules.\n//!\n//! ```rust\n//! use unicode_segmentation::UnicodeSegmentation;\n//!\n//! fn main() {\n//!     let s = \"a̐éö̲\\r\\n\";\n//!     let g = s.graphemes(true).collect::<Vec<&str>>();\n//!     let b: &[_] = &[\"a̐\", \"é\", \"ö̲\", \"\\r\\n\"];\n//!     assert_eq!(g, b);\n//!\n//!     let s = \"The quick (\\\"brown\\\") fox can't jump 32.3 feet, right?\";\n//!     let w = s.unicode_words().collect::<Vec<&str>>();\n//!     let b: &[_] = &[\"The\", \"quick\", \"brown\", \"fox\", \"can't\", \"jump\", \"32.3\", \"feet\", \"right\"];\n//!     assert_eq!(w, b);\n//!\n//!     let s = \"The quick (\\\"brown\\\")  fox\";\n//!     let w = s.split_word_bounds().collect::<Vec<&str>>();\n//!     let b: &[_] = &[\"The\", \" \", \"quick\", \" \", \"(\", \"\\\"\", \"brown\", \"\\\"\", \")\", \"  \", \"fox\"];\n//!     assert_eq!(w, b);\n//! }\n//! ```\n//!\n//! # no_std\n//!\n//! unicode-segmentation does not depend on libstd, so it can be used in crates\n//! with the `#![no_std]` attribute.\n//!\n//! # crates.io\n//!\n//! You can use this package in your project by adding the following\n//! to your `Cargo.toml`:\n//!\n//! ```toml\n//! [dependencies]\n//! unicode-segmentation = \"1\"\n//! ```\n\n#![deny(missing_docs, unsafe_code)]\n#![doc(\n    html_logo_url = \"https://unicode-rs.github.io/unicode-rs_sm.png\",\n    html_favicon_url = \"https://unicode-rs.github.io/unicode-rs_sm.png\"\n)]\n#![no_std]\n\n#[cfg(test)]\nextern crate std;\n\npub use grapheme::{GraphemeCursor, GraphemeIncomplete};\npub use grapheme::{GraphemeIndices, Graphemes};\npub use sentence::{USentenceBoundIndices, USentenceBounds, UnicodeSentences};\npub use tables::UNICODE_VERSION;\npub use word::{UWordBoundIndices, UWordBounds, UnicodeWordIndices, UnicodeWords};\n\nmod grapheme;\nmod sentence;\n#[rustfmt::skip]\nmod tables;\nmod word;\n\n/// Methods for segmenting strings according to\n/// [Unicode Standard Annex #29](http://www.unicode.org/reports/tr29/).\npub trait UnicodeSegmentation {\n    /// Returns an iterator over the [grapheme clusters][graphemes] of `self`.\n    ///\n    /// [graphemes]: http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries\n    ///\n    /// If `is_extended` is true, the iterator is over the\n    /// *extended grapheme clusters*;\n    /// otherwise, the iterator is over the *legacy grapheme clusters*.\n    /// [UAX#29](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)\n    /// recommends extended grapheme cluster boundaries for general processing.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use self::unicode_segmentation::UnicodeSegmentation;\n    /// let gr1 = UnicodeSegmentation::graphemes(\"a\\u{310}e\\u{301}o\\u{308}\\u{332}\", true)\n    ///           .collect::<Vec<&str>>();\n    /// let b: &[_] = &[\"a\\u{310}\", \"e\\u{301}\", \"o\\u{308}\\u{332}\"];\n    ///\n    /// assert_eq!(&gr1[..], b);\n    ///\n    /// let gr2 = UnicodeSegmentation::graphemes(\"a\\r\\nb🇷🇺🇸🇹\", true).collect::<Vec<&str>>();\n    /// let b: &[_] = &[\"a\", \"\\r\\n\", \"b\", \"🇷🇺\", \"🇸🇹\"];\n    ///\n    /// assert_eq!(&gr2[..], b);\n    /// ```\n    fn graphemes(&self, is_extended: bool) -> Graphemes<'_>;\n\n    /// Returns an iterator over the grapheme clusters of `self` and their\n    /// byte offsets. See `graphemes()` for more information.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # use self::unicode_segmentation::UnicodeSegmentation;\n    /// let gr_inds = UnicodeSegmentation::grapheme_indices(\"a̐éö̲\\r\\n\", true)\n    ///               .collect::<Vec<(usize, &str)>>();\n    /// let b: &[_] = &[(0, \"a̐\"), (3, \"é\"), (6, \"ö̲\"), (11, \"\\r\\n\")];\n    ///\n    /// assert_eq!(&gr_inds[..], b);\n    /// ```\n    fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices<'_>;\n\n    /// Returns an iterator over the words of `self`, separated on\n    /// [UAX#29 word boundaries](http://www.unicode.org/reports/tr29/#Word_Boundaries).\n    ///\n    /// Here, \"words\" are just those substrings which, after splitting on\n    /// UAX#29 word boundaries, contain any alphanumeric characters. That is, the\n    /// substring must contain at least one character with the\n    /// [Alphabetic](http://unicode.org/reports/tr44/#Alphabetic)\n    /// property, or with\n    /// [General_Category=Number](http://unicode.org/reports/tr44/#General_Category_Values).\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use self::unicode_segmentation::UnicodeSegmentation;\n    /// let uws = \"The quick (\\\"brown\\\") fox can't jump 32.3 feet, right?\";\n    /// let uw1 = uws.unicode_words().collect::<Vec<&str>>();\n    /// let b: &[_] = &[\"The\", \"quick\", \"brown\", \"fox\", \"can't\", \"jump\", \"32.3\", \"feet\", \"right\"];\n    ///\n    /// assert_eq!(&uw1[..], b);\n    /// ```\n    fn unicode_words(&self) -> UnicodeWords<'_>;\n\n    /// Returns an iterator over the words of `self`, separated on\n    /// [UAX#29 word boundaries](http://www.unicode.org/reports/tr29/#Word_Boundaries), and their\n    /// offsets.\n    ///\n    /// Here, \"words\" are just those substrings which, after splitting on\n    /// UAX#29 word boundaries, contain any alphanumeric characters. That is, the\n    /// substring must contain at least one character with the\n    /// [Alphabetic](http://unicode.org/reports/tr44/#Alphabetic)\n    /// property, or with\n    /// [General_Category=Number](http://unicode.org/reports/tr44/#General_Category_Values).\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use self::unicode_segmentation::UnicodeSegmentation;\n    /// let uwis = \"The quick (\\\"brown\\\") fox can't jump 32.3 feet, right?\";\n    /// let uwi1 = uwis.unicode_word_indices().collect::<Vec<(usize, &str)>>();\n    /// let b: &[_] = &[(0, \"The\"), (4, \"quick\"), (12, \"brown\"), (20, \"fox\"), (24, \"can't\"),\n    ///                 (30, \"jump\"), (35, \"32.3\"), (40, \"feet\"), (46, \"right\")];\n    ///\n    /// assert_eq!(&uwi1[..], b);\n    /// ```\n    fn unicode_word_indices(&self) -> UnicodeWordIndices<'_>;\n\n    /// Returns an iterator over substrings of `self` separated on\n    /// [UAX#29 word boundaries](http://www.unicode.org/reports/tr29/#Word_Boundaries).\n    ///\n    /// The concatenation of the substrings returned by this function is just the original string.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use self::unicode_segmentation::UnicodeSegmentation;\n    /// let swu1 = \"The quick (\\\"brown\\\")  fox\".split_word_bounds().collect::<Vec<&str>>();\n    /// let b: &[_] = &[\"The\", \" \", \"quick\", \" \", \"(\", \"\\\"\", \"brown\", \"\\\"\", \")\", \"  \", \"fox\"];\n    ///\n    /// assert_eq!(&swu1[..], b);\n    /// ```\n    fn split_word_bounds(&self) -> UWordBounds<'_>;\n\n    /// Returns an iterator over substrings of `self`, split on UAX#29 word boundaries,\n    /// and their offsets. See `split_word_bounds()` for more information.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use self::unicode_segmentation::UnicodeSegmentation;\n    /// let swi1 = \"Brr, it's 29.3°F!\".split_word_bound_indices().collect::<Vec<(usize, &str)>>();\n    /// let b: &[_] = &[(0, \"Brr\"), (3, \",\"), (4, \" \"), (5, \"it's\"), (9, \" \"), (10, \"29.3\"),\n    ///                 (14, \"°\"), (16, \"F\"), (17, \"!\")];\n    ///\n    /// assert_eq!(&swi1[..], b);\n    /// ```\n    fn split_word_bound_indices(&self) -> UWordBoundIndices<'_>;\n\n    /// Returns an iterator over substrings of `self` separated on\n    /// [UAX#29 sentence boundaries](http://www.unicode.org/reports/tr29/#Sentence_Boundaries).\n    ///\n    /// Here, \"sentences\" are just those substrings which, after splitting on\n    /// UAX#29 sentence boundaries, contain any alphanumeric characters. That is, the\n    /// substring must contain at least one character with the\n    /// [Alphabetic](http://unicode.org/reports/tr44/#Alphabetic)\n    /// property, or with\n    /// [General_Category=Number](http://unicode.org/reports/tr44/#General_Category_Values).\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use self::unicode_segmentation::UnicodeSegmentation;\n    /// let uss = \"Mr. Fox jumped. [...] The dog was too lazy.\";\n    /// let us1 = uss.unicode_sentences().collect::<Vec<&str>>();\n    /// let b: &[_] = &[\"Mr. \", \"Fox jumped. \", \"The dog was too lazy.\"];\n    ///\n    /// assert_eq!(&us1[..], b);\n    /// ```\n    fn unicode_sentences(&self) -> UnicodeSentences<'_>;\n\n    /// Returns an iterator over substrings of `self` separated on\n    /// [UAX#29 sentence boundaries](http://www.unicode.org/reports/tr29/#Sentence_Boundaries).\n    ///\n    /// The concatenation of the substrings returned by this function is just the original string.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use self::unicode_segmentation::UnicodeSegmentation;\n    /// let ssbs = \"Mr. Fox jumped. [...] The dog was too lazy.\";\n    /// let ssb1 = ssbs.split_sentence_bounds().collect::<Vec<&str>>();\n    /// let b: &[_] = &[\"Mr. \", \"Fox jumped. \", \"[...] \", \"The dog was too lazy.\"];\n    ///\n    /// assert_eq!(&ssb1[..], b);\n    /// ```\n    fn split_sentence_bounds(&self) -> USentenceBounds<'_>;\n\n    /// Returns an iterator over substrings of `self`, split on UAX#29 sentence boundaries,\n    /// and their offsets. See `split_sentence_bounds()` for more information.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use self::unicode_segmentation::UnicodeSegmentation;\n    /// let ssis = \"Mr. Fox jumped. [...] The dog was too lazy.\";\n    /// let ssi1 = ssis.split_sentence_bound_indices().collect::<Vec<(usize, &str)>>();\n    /// let b: &[_] = &[(0, \"Mr. \"), (4, \"Fox jumped. \"), (16, \"[...] \"),\n    ///                 (22, \"The dog was too lazy.\")];\n    ///\n    /// assert_eq!(&ssi1[..], b);\n    /// ```\n    fn split_sentence_bound_indices(&self) -> USentenceBoundIndices<'_>;\n}\n\nimpl UnicodeSegmentation for str {\n    #[inline]\n    fn graphemes(&self, is_extended: bool) -> Graphemes<'_> {\n        grapheme::new_graphemes(self, is_extended)\n    }\n\n    #[inline]\n    fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices<'_> {\n        grapheme::new_grapheme_indices(self, is_extended)\n    }\n\n    #[inline]\n    fn unicode_words(&self) -> UnicodeWords<'_> {\n        word::new_unicode_words(self)\n    }\n\n    #[inline]\n    fn unicode_word_indices(&self) -> UnicodeWordIndices<'_> {\n        word::new_unicode_word_indices(self)\n    }\n\n    #[inline]\n    fn split_word_bounds(&self) -> UWordBounds<'_> {\n        word::new_word_bounds(self)\n    }\n\n    #[inline]\n    fn split_word_bound_indices(&self) -> UWordBoundIndices<'_> {\n        word::new_word_bound_indices(self)\n    }\n\n    #[inline]\n    fn unicode_sentences(&self) -> UnicodeSentences<'_> {\n        sentence::new_unicode_sentences(self)\n    }\n\n    #[inline]\n    fn split_sentence_bounds(&self) -> USentenceBounds<'_> {\n        sentence::new_sentence_bounds(self)\n    }\n\n    #[inline]\n    fn split_sentence_bound_indices(&self) -> USentenceBoundIndices<'_> {\n        sentence::new_sentence_bound_indices(self)\n    }\n}\n"
    },
    {
      "package": "unicode-segmentation@1.13.3",
      "sourcePath": "src/sentence.rs",
      "sha256": "7fe9496fbd694f335359be8ccd12980680e880cbf40b61141bbfb9f95e8b589d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse core::cmp;\nuse core::iter::Filter;\n\n// All of the logic for forward iteration over sentences\nmod fwd {\n    use crate::tables::sentence::SentenceCat;\n    use core::cmp;\n\n    // Describe a parsed part of source string as described in this table:\n    // https://unicode.org/reports/tr29/#Default_Sentence_Boundaries\n    #[derive(Debug, Clone, Copy, PartialEq, Eq)]\n    enum StatePart {\n        Sot,\n        Eot,\n        Other,\n        CR,\n        LF,\n        Sep,\n        ATerm,\n        UpperLower,\n        ClosePlus,\n        SpPlus,\n        STerm,\n    }\n\n    #[derive(Debug, Clone, PartialEq, Eq)]\n    struct SentenceBreaksState(pub [StatePart; 4]);\n\n    const INITIAL_STATE: SentenceBreaksState = SentenceBreaksState([\n        StatePart::Sot,\n        StatePart::Sot,\n        StatePart::Sot,\n        StatePart::Sot,\n    ]);\n\n    #[derive(Debug, Clone)]\n    pub struct SentenceBreaks<'a> {\n        pub string: &'a str,\n        pos: usize,\n        state: SentenceBreaksState,\n    }\n\n    impl SentenceBreaksState {\n        // Attempt to advance the internal state by one part\n        // Whitespace and some punctutation will be collapsed\n        fn next(&self, cat: SentenceCat) -> SentenceBreaksState {\n            let &SentenceBreaksState(parts) = self;\n            let parts = match (parts[3], cat) {\n                (StatePart::ClosePlus, SentenceCat::SC_Close) => parts,\n                (StatePart::SpPlus, SentenceCat::SC_Sp) => parts,\n                _ => [\n                    parts[1],\n                    parts[2],\n                    parts[3],\n                    match cat {\n                        SentenceCat::SC_CR => StatePart::CR,\n                        SentenceCat::SC_LF => StatePart::LF,\n                        SentenceCat::SC_Sep => StatePart::Sep,\n                        SentenceCat::SC_ATerm => StatePart::ATerm,\n                        SentenceCat::SC_Upper | SentenceCat::SC_Lower => StatePart::UpperLower,\n                        SentenceCat::SC_Close => StatePart::ClosePlus,\n                        SentenceCat::SC_Sp => StatePart::SpPlus,\n                        SentenceCat::SC_STerm => StatePart::STerm,\n                        _ => StatePart::Other,\n                    },\n                ],\n            };\n            SentenceBreaksState(parts)\n        }\n\n        fn end(&self) -> SentenceBreaksState {\n            let &SentenceBreaksState(parts) = self;\n            SentenceBreaksState([parts[1], parts[2], parts[3], StatePart::Eot])\n        }\n\n        // Helper function to check if state head matches a single `StatePart`\n        fn match1(&self, part: StatePart) -> bool {\n            let &SentenceBreaksState(parts) = self;\n            part == parts[3]\n        }\n\n        // Helper function to check if first two `StateParts` in state match\n        // the given two\n        fn match2(&self, part1: StatePart, part2: StatePart) -> bool {\n            let &SentenceBreaksState(parts) = self;\n            part1 == parts[2] && part2 == parts[3]\n        }\n    }\n\n    // https://unicode.org/reports/tr29/#SB8\n    // TODO cache this, it is currently quadratic\n    fn match_sb8(state: &SentenceBreaksState, ahead: &str) -> bool {\n        let &SentenceBreaksState(parts) = state;\n        let mut idx = if parts[3] == StatePart::SpPlus { 2 } else { 3 };\n        if parts[idx] == StatePart::ClosePlus {\n            idx -= 1\n        }\n\n        if parts[idx] == StatePart::ATerm {\n            use crate::tables::sentence as se;\n\n            for next_char in ahead.chars() {\n                //( ¬(OLetter | Upper | Lower | ParaSep | SATerm) )* Lower\n                match se::sentence_category(next_char).2 {\n                    se::SC_Lower => return true,\n                    se::SC_OLetter\n                    | se::SC_Upper\n                    | se::SC_Sep\n                    | se::SC_CR\n                    | se::SC_LF\n                    | se::SC_STerm\n                    | se::SC_ATerm => return false,\n                    _ => continue,\n                }\n            }\n        }\n\n        false\n    }\n\n    // https://unicode.org/reports/tr29/#SB8a\n    fn match_sb8a(state: &SentenceBreaksState) -> bool {\n        // SATerm Close* Sp*\n        let &SentenceBreaksState(parts) = state;\n        let mut idx = if parts[3] == StatePart::SpPlus { 2 } else { 3 };\n        if parts[idx] == StatePart::ClosePlus {\n            idx -= 1\n        }\n        parts[idx] == StatePart::STerm || parts[idx] == StatePart::ATerm\n    }\n\n    // https://unicode.org/reports/tr29/#SB9\n    fn match_sb9(state: &SentenceBreaksState) -> bool {\n        // SATerm Close*\n        let &SentenceBreaksState(parts) = state;\n        let idx = if parts[3] == StatePart::ClosePlus {\n            2\n        } else {\n            3\n        };\n        parts[idx] == StatePart::STerm || parts[idx] == StatePart::ATerm\n    }\n\n    // https://unicode.org/reports/tr29/#SB11\n    fn match_sb11(state: &SentenceBreaksState) -> bool {\n        // SATerm Close* Sp* ParaSep?\n        let &SentenceBreaksState(parts) = state;\n        let mut idx = match parts[3] {\n            StatePart::Sep | StatePart::CR | StatePart::LF => 2,\n            _ => 3,\n        };\n\n        if parts[idx] == StatePart::SpPlus {\n            idx -= 1\n        }\n        if parts[idx] == StatePart::ClosePlus {\n            idx -= 1\n        }\n\n        parts[idx] == StatePart::STerm || parts[idx] == StatePart::ATerm\n    }\n\n    impl<'a> Iterator for SentenceBreaks<'a> {\n        // Returns the index of the character which follows a break\n        type Item = usize;\n\n        #[inline]\n        fn size_hint(&self) -> (usize, Option<usize>) {\n            let slen = self.string.len();\n            // A sentence could be one character\n            (cmp::min(slen, 2), Some(slen + 1))\n        }\n\n        #[inline]\n        fn next(&mut self) -> Option<usize> {\n            use crate::tables::sentence as se;\n\n            for next_char in self.string[self.pos..].chars() {\n                let position_before = self.pos;\n                let state_before = self.state.clone();\n\n                let next_cat = se::sentence_category(next_char).2;\n\n                self.pos += next_char.len_utf8();\n                self.state = self.state.next(next_cat);\n\n                match next_cat {\n                    // SB1 https://unicode.org/reports/tr29/#SB1\n                    _ if state_before.match1(StatePart::Sot) => return Some(position_before),\n\n                    // SB2 is handled when inner iterator (chars) is finished\n\n                    // SB3 https://unicode.org/reports/tr29/#SB3\n                    SentenceCat::SC_LF if state_before.match1(StatePart::CR) => continue,\n\n                    // SB4 https://unicode.org/reports/tr29/#SB4\n                    _ if state_before.match1(StatePart::Sep)\n                        || state_before.match1(StatePart::CR)\n                        || state_before.match1(StatePart::LF) =>\n                    {\n                        return Some(position_before)\n                    }\n\n                    // SB5 https://unicode.org/reports/tr29/#SB5\n                    SentenceCat::SC_Extend | SentenceCat::SC_Format => self.state = state_before,\n\n                    // SB6 https://unicode.org/reports/tr29/#SB6\n                    SentenceCat::SC_Numeric if state_before.match1(StatePart::ATerm) => continue,\n\n                    // SB7 https://unicode.org/reports/tr29/#SB7\n                    SentenceCat::SC_Upper\n                        if state_before.match2(StatePart::UpperLower, StatePart::ATerm) =>\n                    {\n                        continue\n                    }\n\n                    // SB8 https://unicode.org/reports/tr29/#SB8\n                    _ if match_sb8(&state_before, &self.string[position_before..]) => continue,\n\n                    // SB8a https://unicode.org/reports/tr29/#SB8a\n                    SentenceCat::SC_SContinue | SentenceCat::SC_STerm | SentenceCat::SC_ATerm\n                        if match_sb8a(&state_before) =>\n                    {\n                        continue\n                    }\n\n                    // SB9 https://unicode.org/reports/tr29/#SB9\n                    SentenceCat::SC_Close\n                    | SentenceCat::SC_Sp\n                    | SentenceCat::SC_Sep\n                    | SentenceCat::SC_CR\n                    | SentenceCat::SC_LF\n                        if match_sb9(&state_before) =>\n                    {\n                        continue\n                    }\n\n                    // SB10 https://unicode.org/reports/tr29/#SB10\n                    SentenceCat::SC_Sp\n                    | SentenceCat::SC_Sep\n                    | SentenceCat::SC_CR\n                    | SentenceCat::SC_LF\n                        if match_sb8a(&state_before) =>\n                    {\n                        continue\n                    }\n\n                    // SB11 https://unicode.org/reports/tr29/#SB11\n                    _ if match_sb11(&state_before) => return Some(position_before),\n\n                    // SB998 https://unicode.org/reports/tr29/#SB998\n                    _ => continue,\n                }\n            }\n\n            // SB2 https://unicode.org/reports/tr29/#SB2\n            if self.state.match1(StatePart::Sot) || self.state.match1(StatePart::Eot) {\n                None\n            } else {\n                self.state = self.state.end();\n                Some(self.pos)\n            }\n        }\n    }\n\n    pub fn new_sentence_breaks(source: &str) -> SentenceBreaks<'_> {\n        SentenceBreaks {\n            string: source,\n            pos: 0,\n            state: INITIAL_STATE,\n        }\n    }\n}\n\n/// An iterator over the substrings of a string which, after splitting the string on\n/// [sentence boundaries](http://www.unicode.org/reports/tr29/#Sentence_Boundaries),\n/// contain any characters with the\n/// [Alphabetic](http://unicode.org/reports/tr44/#Alphabetic)\n/// property, or with\n/// [General_Category=Number](http://unicode.org/reports/tr44/#General_Category_Values).\n///\n/// This struct is created by the [`unicode_sentences`] method on the [`UnicodeSegmentation`]\n/// trait. See its documentation for more.\n///\n/// [`unicode_sentences`]: trait.UnicodeSegmentation.html#tymethod.unicode_sentences\n/// [`UnicodeSegmentation`]: trait.UnicodeSegmentation.html\n#[derive(Debug, Clone)]\npub struct UnicodeSentences<'a> {\n    inner: Filter<USentenceBounds<'a>, fn(&&str) -> bool>,\n}\n\n/// External iterator for a string's\n/// [sentence boundaries](http://www.unicode.org/reports/tr29/#Sentence_Boundaries).\n///\n/// This struct is created by the [`split_sentence_bounds`] method on the [`UnicodeSegmentation`]\n/// trait. See its documentation for more.\n///\n/// [`split_sentence_bounds`]: trait.UnicodeSegmentation.html#tymethod.split_sentence_bounds\n/// [`UnicodeSegmentation`]: trait.UnicodeSegmentation.html\n#[derive(Debug, Clone)]\npub struct USentenceBounds<'a> {\n    iter: fwd::SentenceBreaks<'a>,\n    sentence_start: Option<usize>,\n}\n\n/// External iterator for sentence boundaries and byte offsets.\n///\n/// This struct is created by the [`split_sentence_bound_indices`] method on the\n/// [`UnicodeSegmentation`] trait. See its documentation for more.\n///\n/// [`split_sentence_bound_indices`]: trait.UnicodeSegmentation.html#tymethod.split_sentence_bound_indices\n/// [`UnicodeSegmentation`]: trait.UnicodeSegmentation.html\n#[derive(Debug, Clone)]\npub struct USentenceBoundIndices<'a> {\n    start_offset: usize,\n    iter: USentenceBounds<'a>,\n}\n\n#[inline]\npub fn new_sentence_bounds(source: &str) -> USentenceBounds<'_> {\n    USentenceBounds {\n        iter: fwd::new_sentence_breaks(source),\n        sentence_start: None,\n    }\n}\n\n#[inline]\npub fn new_sentence_bound_indices(source: &str) -> USentenceBoundIndices<'_> {\n    USentenceBoundIndices {\n        start_offset: source.as_ptr() as usize,\n        iter: new_sentence_bounds(source),\n    }\n}\n\n#[inline]\npub fn new_unicode_sentences(s: &str) -> UnicodeSentences<'_> {\n    use super::UnicodeSegmentation;\n    use crate::tables::util::is_alphanumeric;\n\n    fn has_alphanumeric(s: &&str) -> bool {\n        s.chars().any(is_alphanumeric)\n    }\n    let has_alphanumeric: fn(&&str) -> bool = has_alphanumeric; // coerce to fn pointer\n\n    UnicodeSentences {\n        inner: s.split_sentence_bounds().filter(has_alphanumeric),\n    }\n}\n\nimpl<'a> Iterator for UnicodeSentences<'a> {\n    type Item = &'a str;\n\n    #[inline]\n    fn next(&mut self) -> Option<&'a str> {\n        self.inner.next()\n    }\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.inner.size_hint()\n    }\n}\n\nimpl<'a> Iterator for USentenceBounds<'a> {\n    type Item = &'a str;\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let (lower, upper) = self.iter.size_hint();\n        (cmp::max(0, lower - 1), upper.map(|u| cmp::max(0, u - 1)))\n    }\n\n    #[inline]\n    fn next(&mut self) -> Option<&'a str> {\n        if self.sentence_start.is_none() {\n            if let Some(start_pos) = self.iter.next() {\n                self.sentence_start = Some(start_pos)\n            } else {\n                return None;\n            }\n        }\n\n        if let Some(break_pos) = self.iter.next() {\n            let start_pos = self.sentence_start.unwrap();\n            let sentence = &self.iter.string[start_pos..break_pos];\n            self.sentence_start = Some(break_pos);\n            Some(sentence)\n        } else {\n            None\n        }\n    }\n}\n\nimpl<'a> Iterator for USentenceBoundIndices<'a> {\n    type Item = (usize, &'a str);\n\n    #[inline]\n    fn next(&mut self) -> Option<(usize, &'a str)> {\n        self.iter\n            .next()\n            .map(|s| (s.as_ptr() as usize - self.start_offset, s))\n    }\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.iter.size_hint()\n    }\n}\n"
    },
    {
      "package": "unicode-segmentation@1.13.3",
      "sourcePath": "src/tables.rs",
      "sha256": "089c221918a60e8672ed8eda73d27f195dcc404f91b9e71b57c0b5e348e7aeef",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n// NOTE: The following code was generated by \"scripts/unicode.py\", do not edit directly\n\n#![allow(missing_docs, non_upper_case_globals, non_snake_case)]\n\n/// The version of [Unicode](http://www.unicode.org/)\n/// that this version of unicode-segmentation is based on.\npub const UNICODE_VERSION: (u64, u64, u64) = (17, 0, 0);\n\nconst UNICODE_VERSION_U8: (u8, u8, u8) = (17, 0, 0);\n\npub mod util {\n    #[inline]\n    pub fn bsearch_range_table(c: char, r: &[(char,char)]) -> bool {\n        use core::cmp::Ordering::{Equal, Less, Greater};\n        r.binary_search_by(|&(lo,hi)| {\n            if lo <= c && c <= hi { Equal }\n            else if hi < c { Less }\n            else { Greater }\n        }).is_ok()\n    }\n\n    #[inline]\n    fn is_alphabetic(c: char) -> bool {\n        if super::UNICODE_VERSION_U8 == char::UNICODE_VERSION {\n            c.is_alphabetic()\n        } else {\n            match c {\n                'a' ..= 'z' | 'A' ..= 'Z' => true,\n                c if c > '\\x7f' => super::derived_property::Alphabetic(c),\n                _ => false,\n            }\n        }\n    }\n\n    #[inline]\n    fn is_numeric(c: char) -> bool {\n        if super::UNICODE_VERSION_U8 == char::UNICODE_VERSION {\n            c.is_numeric()\n        } else {\n            match c {\n                '0' ..= '9' => true,\n                c if c > '\\x7f' => super::general_category::N(c),\n                _ => false,\n            }\n        }\n    }\n\n    #[inline]\n    pub fn is_alphanumeric(c: char) -> bool {\n        is_alphabetic(c) || is_numeric(c)\n    }\n}\n\npub mod general_category {\n    const N_table: &[(char, char)] = &[\n        ('\\u{30}', '\\u{39}'), ('\\u{b2}', '\\u{b3}'), ('\\u{b9}', '\\u{b9}'), ('\\u{bc}', '\\u{be}'),\n        ('\\u{660}', '\\u{669}'), ('\\u{6f0}', '\\u{6f9}'), ('\\u{7c0}', '\\u{7c9}'), ('\\u{966}',\n        '\\u{96f}'), ('\\u{9e6}', '\\u{9ef}'), ('\\u{9f4}', '\\u{9f9}'), ('\\u{a66}', '\\u{a6f}'),\n        ('\\u{ae6}', '\\u{aef}'), ('\\u{b66}', '\\u{b6f}'), ('\\u{b72}', '\\u{b77}'), ('\\u{be6}',\n        '\\u{bf2}'), ('\\u{c66}', '\\u{c6f}'), ('\\u{c78}', '\\u{c7e}'), ('\\u{ce6}', '\\u{cef}'),\n        ('\\u{d58}', '\\u{d5e}'), ('\\u{d66}', '\\u{d78}'), ('\\u{de6}', '\\u{def}'), ('\\u{e50}',\n        '\\u{e59}'), ('\\u{ed0}', '\\u{ed9}'), ('\\u{f20}', '\\u{f33}'), ('\\u{1040}', '\\u{1049}'),\n        ('\\u{1090}', '\\u{1099}'), ('\\u{1369}', '\\u{137c}'), ('\\u{16ee}', '\\u{16f0}'), ('\\u{17e0}',\n        '\\u{17e9}'), ('\\u{17f0}', '\\u{17f9}'), ('\\u{1810}', '\\u{1819}'), ('\\u{1946}', '\\u{194f}'),\n        ('\\u{19d0}', '\\u{19da}'), ('\\u{1a80}', '\\u{1a89}'), ('\\u{1a90}', '\\u{1a99}'), ('\\u{1b50}',\n        '\\u{1b59}'), ('\\u{1bb0}', '\\u{1bb9}'), ('\\u{1c40}', '\\u{1c49}'), ('\\u{1c50}', '\\u{1c59}'),\n        ('\\u{2070}', '\\u{2070}'), ('\\u{2074}', '\\u{2079}'), ('\\u{2080}', '\\u{2089}'), ('\\u{2150}',\n        '\\u{2182}'), ('\\u{2185}', '\\u{2189}'), ('\\u{2460}', '\\u{249b}'), ('\\u{24ea}', '\\u{24ff}'),\n        ('\\u{2776}', '\\u{2793}'), ('\\u{2cfd}', '\\u{2cfd}'), ('\\u{3007}', '\\u{3007}'), ('\\u{3021}',\n        '\\u{3029}'), ('\\u{3038}', '\\u{303a}'), ('\\u{3192}', '\\u{3195}'), ('\\u{3220}', '\\u{3229}'),\n        ('\\u{3248}', '\\u{324f}'), ('\\u{3251}', '\\u{325f}'), ('\\u{3280}', '\\u{3289}'), ('\\u{32b1}',\n        '\\u{32bf}'), ('\\u{a620}', '\\u{a629}'), ('\\u{a6e6}', '\\u{a6ef}'), ('\\u{a830}', '\\u{a835}'),\n        ('\\u{a8d0}', '\\u{a8d9}'), ('\\u{a900}', '\\u{a909}'), ('\\u{a9d0}', '\\u{a9d9}'), ('\\u{a9f0}',\n        '\\u{a9f9}'), ('\\u{aa50}', '\\u{aa59}'), ('\\u{abf0}', '\\u{abf9}'), ('\\u{ff10}', '\\u{ff19}'),\n        ('\\u{10107}', '\\u{10133}'), ('\\u{10140}', '\\u{10178}'), ('\\u{1018a}', '\\u{1018b}'),\n        ('\\u{102e1}', '\\u{102fb}'), ('\\u{10320}', '\\u{10323}'), ('\\u{10341}', '\\u{10341}'),\n        ('\\u{1034a}', '\\u{1034a}'), ('\\u{103d1}', '\\u{103d5}'), ('\\u{104a0}', '\\u{104a9}'),\n        ('\\u{10858}', '\\u{1085f}'), ('\\u{10879}', '\\u{1087f}'), ('\\u{108a7}', '\\u{108af}'),\n        ('\\u{108fb}', '\\u{108ff}'), ('\\u{10916}', '\\u{1091b}'), ('\\u{109bc}', '\\u{109bd}'),\n        ('\\u{109c0}', '\\u{109cf}'), ('\\u{109d2}', '\\u{109ff}'), ('\\u{10a40}', '\\u{10a48}'),\n        ('\\u{10a7d}', '\\u{10a7e}'), ('\\u{10a9d}', '\\u{10a9f}'), ('\\u{10aeb}', '\\u{10aef}'),\n        ('\\u{10b58}', '\\u{10b5f}'), ('\\u{10b78}', '\\u{10b7f}'), ('\\u{10ba9}', '\\u{10baf}'),\n        ('\\u{10cfa}', '\\u{10cff}'), ('\\u{10d30}', '\\u{10d39}'), ('\\u{10d40}', '\\u{10d49}'),\n        ('\\u{10e60}', '\\u{10e7e}'), ('\\u{10f1d}', '\\u{10f26}'), ('\\u{10f51}', '\\u{10f54}'),\n        ('\\u{10fc5}', '\\u{10fcb}'), ('\\u{11052}', '\\u{1106f}'), ('\\u{110f0}', '\\u{110f9}'),\n        ('\\u{11136}', '\\u{1113f}'), ('\\u{111d0}', '\\u{111d9}'), ('\\u{111e1}', '\\u{111f4}'),\n        ('\\u{112f0}', '\\u{112f9}'), ('\\u{11450}', '\\u{11459}'), ('\\u{114d0}', '\\u{114d9}'),\n        ('\\u{11650}', '\\u{11659}'), ('\\u{116c0}', '\\u{116c9}'), ('\\u{116d0}', '\\u{116e3}'),\n        ('\\u{11730}', '\\u{1173b}'), ('\\u{118e0}', '\\u{118f2}'), ('\\u{11950}', '\\u{11959}'),\n        ('\\u{11bf0}', '\\u{11bf9}'), ('\\u{11c50}', '\\u{11c6c}'), ('\\u{11d50}', '\\u{11d59}'),\n        ('\\u{11da0}', '\\u{11da9}'), ('\\u{11de0}', '\\u{11de9}'), ('\\u{11f50}', '\\u{11f59}'),\n        ('\\u{11fc0}', '\\u{11fd4}'), ('\\u{12400}', '\\u{1246e}'), ('\\u{16130}', '\\u{16139}'),\n        ('\\u{16a60}', '\\u{16a69}'), ('\\u{16ac0}', '\\u{16ac9}'), ('\\u{16b50}', '\\u{16b59}'),\n        ('\\u{16b5b}', '\\u{16b61}'), ('\\u{16d70}', '\\u{16d79}'), ('\\u{16e80}', '\\u{16e96}'),\n        ('\\u{16ff4}', '\\u{16ff6}'), ('\\u{1ccf0}', '\\u{1ccf9}'), ('\\u{1d2c0}', '\\u{1d2d3}'),\n        ('\\u{1d2e0}', '\\u{1d2f3}'), ('\\u{1d360}', '\\u{1d378}'), ('\\u{1d7ce}', '\\u{1d7ff}'),\n        ('\\u{1e140}', '\\u{1e149}'), ('\\u{1e2f0}', '\\u{1e2f9}'), ('\\u{1e4f0}', '\\u{1e4f9}'),\n        ('\\u{1e5f1}', '\\u{1e5fa}'), ('\\u{1e8c7}', '\\u{1e8cf}'), ('\\u{1e950}', '\\u{1e959}'),\n        ('\\u{1ec71}', '\\u{1ecab}'), ('\\u{1ecad}', '\\u{1ecaf}'), ('\\u{1ecb1}', '\\u{1ecb4}'),\n        ('\\u{1ed01}', '\\u{1ed2d}'), ('\\u{1ed2f}', '\\u{1ed3d}'), ('\\u{1f100}', '\\u{1f10c}'),\n        ('\\u{1fbf0}', '\\u{1fbf9}')\n    ];\n\n    #[inline]\n    pub fn N(c: char) -> bool {\n        super::util::bsearch_range_table(c, N_table)\n    }\n\n}\n\npub mod derived_property {\n    const Alphabetic_table: &[(char, char)] = &[\n        ('\\u{41}', '\\u{5a}'), ('\\u{61}', '\\u{7a}'), ('\\u{aa}', '\\u{aa}'), ('\\u{b5}', '\\u{b5}'),\n        ('\\u{ba}', '\\u{ba}'), ('\\u{c0}', '\\u{d6}'), ('\\u{d8}', '\\u{f6}'), ('\\u{f8}', '\\u{2c1}'),\n        ('\\u{2c6}', '\\u{2d1}'), ('\\u{2e0}', '\\u{2e4}'), ('\\u{2ec}', '\\u{2ec}'), ('\\u{2ee}',\n        '\\u{2ee}'), ('\\u{345}', '\\u{345}'), ('\\u{363}', '\\u{374}'), ('\\u{376}', '\\u{377}'),\n        ('\\u{37a}', '\\u{37d}'), ('\\u{37f}', '\\u{37f}'), ('\\u{386}', '\\u{386}'), ('\\u{388}',\n        '\\u{38a}'), ('\\u{38c}', '\\u{38c}'), ('\\u{38e}', '\\u{3a1}'), ('\\u{3a3}', '\\u{3f5}'),\n        ('\\u{3f7}', '\\u{481}'), ('\\u{48a}', '\\u{52f}'), ('\\u{531}', '\\u{556}'), ('\\u{559}',\n        '\\u{559}'), ('\\u{560}', '\\u{588}'), ('\\u{5b0}', '\\u{5bd}'), ('\\u{5bf}', '\\u{5bf}'),\n        ('\\u{5c1}', '\\u{5c2}'), ('\\u{5c4}', '\\u{5c5}'), ('\\u{5c7}', '\\u{5c7}'), ('\\u{5d0}',\n        '\\u{5ea}'), ('\\u{5ef}', '\\u{5f2}'), ('\\u{610}', '\\u{61a}'), ('\\u{620}', '\\u{657}'),\n        ('\\u{659}', '\\u{65f}'), ('\\u{66e}', '\\u{6d3}'), ('\\u{6d5}', '\\u{6dc}'), ('\\u{6e1}',\n        '\\u{6e8}'), ('\\u{6ed}', '\\u{6ef}'), ('\\u{6fa}', '\\u{6fc}'), ('\\u{6ff}', '\\u{6ff}'),\n        ('\\u{710}', '\\u{73f}'), ('\\u{74d}', '\\u{7b1}'), ('\\u{7ca}', '\\u{7ea}'), ('\\u{7f4}',\n        '\\u{7f5}'), ('\\u{7fa}', '\\u{7fa}'), ('\\u{800}', '\\u{817}'), ('\\u{81a}', '\\u{82c}'),\n        ('\\u{840}', '\\u{858}'), ('\\u{860}', '\\u{86a}'), ('\\u{870}', '\\u{887}'), ('\\u{889}',\n        '\\u{88f}'), ('\\u{897}', '\\u{897}'), ('\\u{8a0}', '\\u{8c9}'), ('\\u{8d4}', '\\u{8df}'),\n        ('\\u{8e3}', '\\u{8e9}'), ('\\u{8f0}', '\\u{93b}'), ('\\u{93d}', '\\u{94c}'), ('\\u{94e}',\n        '\\u{950}'), ('\\u{955}', '\\u{963}'), ('\\u{971}', '\\u{983}'), ('\\u{985}', '\\u{98c}'),\n        ('\\u{98f}', '\\u{990}'), ('\\u{993}', '\\u{9a8}'), ('\\u{9aa}', '\\u{9b0}'), ('\\u{9b2}',\n        '\\u{9b2}'), ('\\u{9b6}', '\\u{9b9}'), ('\\u{9bd}', '\\u{9c4}'), ('\\u{9c7}', '\\u{9c8}'),\n        ('\\u{9cb}', '\\u{9cc}'), ('\\u{9ce}', '\\u{9ce}'), ('\\u{9d7}', '\\u{9d7}'), ('\\u{9dc}',\n        '\\u{9dd}'), ('\\u{9df}', '\\u{9e3}'), ('\\u{9f0}', '\\u{9f1}'), ('\\u{9fc}', '\\u{9fc}'),\n        ('\\u{a01}', '\\u{a03}'), ('\\u{a05}', '\\u{a0a}'), ('\\u{a0f}', '\\u{a10}'), ('\\u{a13}',\n        '\\u{a28}'), ('\\u{a2a}', '\\u{a30}'), ('\\u{a32}', '\\u{a33}'), ('\\u{a35}', '\\u{a36}'),\n        ('\\u{a38}', '\\u{a39}'), ('\\u{a3e}', '\\u{a42}'), ('\\u{a47}', '\\u{a48}'), ('\\u{a4b}',\n        '\\u{a4c}'), ('\\u{a51}', '\\u{a51}'), ('\\u{a59}', '\\u{a5c}'), ('\\u{a5e}', '\\u{a5e}'),\n        ('\\u{a70}', '\\u{a75}'), ('\\u{a81}', '\\u{a83}'), ('\\u{a85}', '\\u{a8d}'), ('\\u{a8f}',\n        '\\u{a91}'), ('\\u{a93}', '\\u{aa8}'), ('\\u{aaa}', '\\u{ab0}'), ('\\u{ab2}', '\\u{ab3}'),\n        ('\\u{ab5}', '\\u{ab9}'), ('\\u{abd}', '\\u{ac5}'), ('\\u{ac7}', '\\u{ac9}'), ('\\u{acb}',\n        '\\u{acc}'), ('\\u{ad0}', '\\u{ad0}'), ('\\u{ae0}', '\\u{ae3}'), ('\\u{af9}', '\\u{afc}'),\n        ('\\u{b01}', '\\u{b03}'), ('\\u{b05}', '\\u{b0c}'), ('\\u{b0f}', '\\u{b10}'), ('\\u{b13}',\n        '\\u{b28}'), ('\\u{b2a}', '\\u{b30}'), ('\\u{b32}', '\\u{b33}'), ('\\u{b35}', '\\u{b39}'),\n        ('\\u{b3d}', '\\u{b44}'), ('\\u{b47}', '\\u{b48}'), ('\\u{b4b}', '\\u{b4c}'), ('\\u{b56}',\n        '\\u{b57}'), ('\\u{b5c}', '\\u{b5d}'), ('\\u{b5f}', '\\u{b63}'), ('\\u{b71}', '\\u{b71}'),\n        ('\\u{b82}', '\\u{b83}'), ('\\u{b85}', '\\u{b8a}'), ('\\u{b8e}', '\\u{b90}'), ('\\u{b92}',\n        '\\u{b95}'), ('\\u{b99}', '\\u{b9a}'), ('\\u{b9c}', '\\u{b9c}'), ('\\u{b9e}', '\\u{b9f}'),\n        ('\\u{ba3}', '\\u{ba4}'), ('\\u{ba8}', '\\u{baa}'), ('\\u{bae}', '\\u{bb9}'), ('\\u{bbe}',\n        '\\u{bc2}'), ('\\u{bc6}', '\\u{bc8}'), ('\\u{bca}', '\\u{bcc}'), ('\\u{bd0}', '\\u{bd0}'),\n        ('\\u{bd7}', '\\u{bd7}'), ('\\u{c00}', '\\u{c0c}'), ('\\u{c0e}', '\\u{c10}'), ('\\u{c12}',\n        '\\u{c28}'), ('\\u{c2a}', '\\u{c39}'), ('\\u{c3d}', '\\u{c44}'), ('\\u{c46}', '\\u{c48}'),\n        ('\\u{c4a}', '\\u{c4c}'), ('\\u{c55}', '\\u{c56}'), ('\\u{c58}', '\\u{c5a}'), ('\\u{c5c}',\n        '\\u{c5d}'), ('\\u{c60}', '\\u{c63}'), ('\\u{c80}', '\\u{c83}'), ('\\u{c85}', '\\u{c8c}'),\n        ('\\u{c8e}', '\\u{c90}'), ('\\u{c92}', '\\u{ca8}'), ('\\u{caa}', '\\u{cb3}'), ('\\u{cb5}',\n        '\\u{cb9}'), ('\\u{cbd}', '\\u{cc4}'), ('\\u{cc6}', '\\u{cc8}'), ('\\u{cca}', '\\u{ccc}'),\n        ('\\u{cd5}', '\\u{cd6}'), ('\\u{cdc}', '\\u{cde}'), ('\\u{ce0}', '\\u{ce3}'), ('\\u{cf1}',\n        '\\u{cf3}'), ('\\u{d00}', '\\u{d0c}'), ('\\u{d0e}', '\\u{d10}'), ('\\u{d12}', '\\u{d3a}'),\n        ('\\u{d3d}', '\\u{d44}'), ('\\u{d46}', '\\u{d48}'), ('\\u{d4a}', '\\u{d4c}'), ('\\u{d4e}',\n        '\\u{d4e}'), ('\\u{d54}', '\\u{d57}'), ('\\u{d5f}', '\\u{d63}'), ('\\u{d7a}', '\\u{d7f}'),\n        ('\\u{d81}', '\\u{d83}'), ('\\u{d85}', '\\u{d96}'), ('\\u{d9a}', '\\u{db1}'), ('\\u{db3}',\n        '\\u{dbb}'), ('\\u{dbd}', '\\u{dbd}'), ('\\u{dc0}', '\\u{dc6}'), ('\\u{dcf}', '\\u{dd4}'),\n        ('\\u{dd6}', '\\u{dd6}'), ('\\u{dd8}', '\\u{ddf}'), ('\\u{df2}', '\\u{df3}'), ('\\u{e01}',\n        '\\u{e3a}'), ('\\u{e40}', '\\u{e46}'), ('\\u{e4d}', '\\u{e4d}'), ('\\u{e81}', '\\u{e82}'),\n        ('\\u{e84}', '\\u{e84}'), ('\\u{e86}', '\\u{e8a}'), ('\\u{e8c}', '\\u{ea3}'), ('\\u{ea5}',\n        '\\u{ea5}'), ('\\u{ea7}', '\\u{eb9}'), ('\\u{ebb}', '\\u{ebd}'), ('\\u{ec0}', '\\u{ec4}'),\n        ('\\u{ec6}', '\\u{ec6}'), ('\\u{ecd}', '\\u{ecd}'), ('\\u{edc}', '\\u{edf}'), ('\\u{f00}',\n        '\\u{f00}'), ('\\u{f40}', '\\u{f47}'), ('\\u{f49}', '\\u{f6c}'), ('\\u{f71}', '\\u{f83}'),\n        ('\\u{f88}', '\\u{f97}'), ('\\u{f99}', '\\u{fbc}'), ('\\u{1000}', '\\u{1036}'), ('\\u{1038}',\n        '\\u{1038}'), ('\\u{103b}', '\\u{103f}'), ('\\u{1050}', '\\u{108f}'), ('\\u{109a}', '\\u{109d}'),\n        ('\\u{10a0}', '\\u{10c5}'), ('\\u{10c7}', '\\u{10c7}'), ('\\u{10cd}', '\\u{10cd}'), ('\\u{10d0}',\n        '\\u{10fa}'), ('\\u{10fc}', '\\u{1248}'), ('\\u{124a}', '\\u{124d}'), ('\\u{1250}', '\\u{1256}'),\n        ('\\u{1258}', '\\u{1258}'), ('\\u{125a}', '\\u{125d}'), ('\\u{1260}', '\\u{1288}'), ('\\u{128a}',\n        '\\u{128d}'), ('\\u{1290}', '\\u{12b0}'), ('\\u{12b2}', '\\u{12b5}'), ('\\u{12b8}', '\\u{12be}'),\n        ('\\u{12c0}', '\\u{12c0}'), ('\\u{12c2}', '\\u{12c5}'), ('\\u{12c8}', '\\u{12d6}'), ('\\u{12d8}',\n        '\\u{1310}'), ('\\u{1312}', '\\u{1315}'), ('\\u{1318}', '\\u{135a}'), ('\\u{1380}', '\\u{138f}'),\n        ('\\u{13a0}', '\\u{13f5}'), ('\\u{13f8}', '\\u{13fd}'), ('\\u{1401}', '\\u{166c}'), ('\\u{166f}',\n        '\\u{167f}'), ('\\u{1681}', '\\u{169a}'), ('\\u{16a0}', '\\u{16ea}'), ('\\u{16ee}', '\\u{16f8}'),\n        ('\\u{1700}', '\\u{1713}'), ('\\u{171f}', '\\u{1733}'), ('\\u{1740}', '\\u{1753}'), ('\\u{1760}',\n        '\\u{176c}'), ('\\u{176e}', '\\u{1770}'), ('\\u{1772}', '\\u{1773}'), ('\\u{1780}', '\\u{17b3}'),\n        ('\\u{17b6}', '\\u{17c8}'), ('\\u{17d7}', '\\u{17d7}'), ('\\u{17dc}', '\\u{17dc}'), ('\\u{1820}',\n        '\\u{1878}'), ('\\u{1880}', '\\u{18aa}'), ('\\u{18b0}', '\\u{18f5}'), ('\\u{1900}', '\\u{191e}'),\n        ('\\u{1920}', '\\u{192b}'), ('\\u{1930}', '\\u{1938}'), ('\\u{1950}', '\\u{196d}'), ('\\u{1970}',\n        '\\u{1974}'), ('\\u{1980}', '\\u{19ab}'), ('\\u{19b0}', '\\u{19c9}'), ('\\u{1a00}', '\\u{1a1b}'),\n        ('\\u{1a20}', '\\u{1a5e}'), ('\\u{1a61}', '\\u{1a74}'), ('\\u{1aa7}', '\\u{1aa7}'), ('\\u{1abf}',\n        '\\u{1ac0}'), ('\\u{1acc}', '\\u{1ace}'), ('\\u{1b00}', '\\u{1b33}'), ('\\u{1b35}', '\\u{1b43}'),\n        ('\\u{1b45}', '\\u{1b4c}'), ('\\u{1b80}', '\\u{1ba9}'), ('\\u{1bac}', '\\u{1baf}'), ('\\u{1bba}',\n        '\\u{1be5}'), ('\\u{1be7}', '\\u{1bf1}'), ('\\u{1c00}', '\\u{1c36}'), ('\\u{1c4d}', '\\u{1c4f}'),\n        ('\\u{1c5a}', '\\u{1c7d}'), ('\\u{1c80}', '\\u{1c8a}'), ('\\u{1c90}', '\\u{1cba}'), ('\\u{1cbd}',\n        '\\u{1cbf}'), ('\\u{1ce9}', '\\u{1cec}'), ('\\u{1cee}', '\\u{1cf3}'), ('\\u{1cf5}', '\\u{1cf6}'),\n        ('\\u{1cfa}', '\\u{1cfa}'), ('\\u{1d00}', '\\u{1dbf}'), ('\\u{1dd3}', '\\u{1df4}'), ('\\u{1e00}',\n        '\\u{1f15}'), ('\\u{1f18}', '\\u{1f1d}'), ('\\u{1f20}', '\\u{1f45}'), ('\\u{1f48}', '\\u{1f4d}'),\n        ('\\u{1f50}', '\\u{1f57}'), ('\\u{1f59}', '\\u{1f59}'), ('\\u{1f5b}', '\\u{1f5b}'), ('\\u{1f5d}',\n        '\\u{1f5d}'), ('\\u{1f5f}', '\\u{1f7d}'), ('\\u{1f80}', '\\u{1fb4}'), ('\\u{1fb6}', '\\u{1fbc}'),\n        ('\\u{1fbe}', '\\u{1fbe}'), ('\\u{1fc2}', '\\u{1fc4}'), ('\\u{1fc6}', '\\u{1fcc}'), ('\\u{1fd0}',\n        '\\u{1fd3}'), ('\\u{1fd6}', '\\u{1fdb}'), ('\\u{1fe0}', '\\u{1fec}'), ('\\u{1ff2}', '\\u{1ff4}'),\n        ('\\u{1ff6}', '\\u{1ffc}'), ('\\u{2071}', '\\u{2071}'), ('\\u{207f}', '\\u{207f}'), ('\\u{2090}',\n        '\\u{209c}'), ('\\u{2102}', '\\u{2102}'), ('\\u{2107}', '\\u{2107}'), ('\\u{210a}', '\\u{2113}'),\n        ('\\u{2115}', '\\u{2115}'), ('\\u{2119}', '\\u{211d}'), ('\\u{2124}', '\\u{2124}'), ('\\u{2126}',\n        '\\u{2126}'), ('\\u{2128}', '\\u{2128}'), ('\\u{212a}', '\\u{212d}'), ('\\u{212f}', '\\u{2139}'),\n        ('\\u{213c}', '\\u{213f}'), ('\\u{2145}', '\\u{2149}'), ('\\u{214e}', '\\u{214e}'), ('\\u{2160}',\n        '\\u{2188}'), ('\\u{24b6}', '\\u{24e9}'), ('\\u{2c00}', '\\u{2ce4}'), ('\\u{2ceb}', '\\u{2cee}'),\n        ('\\u{2cf2}', '\\u{2cf3}'), ('\\u{2d00}', '\\u{2d25}'), ('\\u{2d27}', '\\u{2d27}'), ('\\u{2d2d}',\n        '\\u{2d2d}'), ('\\u{2d30}', '\\u{2d67}'), ('\\u{2d6f}', '\\u{2d6f}'), ('\\u{2d80}', '\\u{2d96}'),\n        ('\\u{2da0}', '\\u{2da6}'), ('\\u{2da8}', '\\u{2dae}'), ('\\u{2db0}', '\\u{2db6}'), ('\\u{2db8}',\n        '\\u{2dbe}'), ('\\u{2dc0}', '\\u{2dc6}'), ('\\u{2dc8}', '\\u{2dce}'), ('\\u{2dd0}', '\\u{2dd6}'),\n        ('\\u{2dd8}', '\\u{2dde}'), ('\\u{2de0}', '\\u{2dff}'), ('\\u{2e2f}', '\\u{2e2f}'), ('\\u{3005}',\n        '\\u{3007}'), ('\\u{3021}', '\\u{3029}'), ('\\u{3031}', '\\u{3035}'), ('\\u{3038}', '\\u{303c}'),\n        ('\\u{3041}', '\\u{3096}'), ('\\u{309d}', '\\u{309f}'), ('\\u{30a1}', '\\u{30fa}'), ('\\u{30fc}',\n        '\\u{30ff}'), ('\\u{3105}', '\\u{312f}'), ('\\u{3131}', '\\u{318e}'), ('\\u{31a0}', '\\u{31bf}'),\n        ('\\u{31f0}', '\\u{31ff}'), ('\\u{3400}', '\\u{4dbf}'), ('\\u{4e00}', '\\u{a48c}'), ('\\u{a4d0}',\n        '\\u{a4fd}'), ('\\u{a500}', '\\u{a60c}'), ('\\u{a610}', '\\u{a61f}'), ('\\u{a62a}', '\\u{a62b}'),\n        ('\\u{a640}', '\\u{a66e}'), ('\\u{a674}', '\\u{a67b}'), ('\\u{a67f}', '\\u{a6ef}'), ('\\u{a717}',\n        '\\u{a71f}'), ('\\u{a722}', '\\u{a788}'), ('\\u{a78b}', '\\u{a7dc}'), ('\\u{a7f1}', '\\u{a805}'),\n        ('\\u{a807}', '\\u{a827}'), ('\\u{a840}', '\\u{a873}'), ('\\u{a880}', '\\u{a8c3}'), ('\\u{a8c5}',\n        '\\u{a8c5}'), ('\\u{a8f2}', '\\u{a8f7}'), ('\\u{a8fb}', '\\u{a8fb}'), ('\\u{a8fd}', '\\u{a8ff}'),\n        ('\\u{a90a}', '\\u{a92a}'), ('\\u{a930}', '\\u{a952}'), ('\\u{a960}', '\\u{a97c}'), ('\\u{a980}',\n        '\\u{a9b2}'), ('\\u{a9b4}', '\\u{a9bf}'), ('\\u{a9cf}', '\\u{a9cf}'), ('\\u{a9e0}', '\\u{a9ef}'),\n        ('\\u{a9fa}', '\\u{a9fe}'), ('\\u{aa00}', '\\u{aa36}'), ('\\u{aa40}', '\\u{aa4d}'), ('\\u{aa60}',\n        '\\u{aa76}'), ('\\u{aa7a}', '\\u{aabe}'), ('\\u{aac0}', '\\u{aac0}'), ('\\u{aac2}', '\\u{aac2}'),\n        ('\\u{aadb}', '\\u{aadd}'), ('\\u{aae0}', '\\u{aaef}'), ('\\u{aaf2}', '\\u{aaf5}'), ('\\u{ab01}',\n        '\\u{ab06}'), ('\\u{ab09}', '\\u{ab0e}'), ('\\u{ab11}', '\\u{ab16}'), ('\\u{ab20}', '\\u{ab26}'),\n        ('\\u{ab28}', '\\u{ab2e}'), ('\\u{ab30}', '\\u{ab5a}'), ('\\u{ab5c}', '\\u{ab69}'), ('\\u{ab70}',\n        '\\u{abea}'), ('\\u{ac00}', '\\u{d7a3}'), ('\\u{d7b0}', '\\u{d7c6}'), ('\\u{d7cb}', '\\u{d7fb}'),\n        ('\\u{f900}', '\\u{fa6d}'), ('\\u{fa70}', '\\u{fad9}'), ('\\u{fb00}', '\\u{fb06}'), ('\\u{fb13}',\n        '\\u{fb17}'), ('\\u{fb1d}', '\\u{fb28}'), ('\\u{fb2a}', '\\u{fb36}'), ('\\u{fb38}', '\\u{fb3c}'),\n        ('\\u{fb3e}', '\\u{fb3e}'), ('\\u{fb40}', '\\u{fb41}'), ('\\u{fb43}', '\\u{fb44}'), ('\\u{fb46}',\n        '\\u{fbb1}'), ('\\u{fbd3}', '\\u{fd3d}'), ('\\u{fd50}', '\\u{fd8f}'), ('\\u{fd92}', '\\u{fdc7}'),\n        ('\\u{fdf0}', '\\u{fdfb}'), ('\\u{fe70}', '\\u{fe74}'), ('\\u{fe76}', '\\u{fefc}'), ('\\u{ff21}',\n        '\\u{ff3a}'), ('\\u{ff41}', '\\u{ff5a}'), ('\\u{ff66}', '\\u{ffbe}'), ('\\u{ffc2}', '\\u{ffc7}'),\n        ('\\u{ffca}', '\\u{ffcf}'), ('\\u{ffd2}', '\\u{ffd7}'), ('\\u{ffda}', '\\u{ffdc}'), ('\\u{10000}',\n        '\\u{1000b}'), ('\\u{1000d}', '\\u{10026}'), ('\\u{10028}', '\\u{1003a}'), ('\\u{1003c}',\n        '\\u{1003d}'), ('\\u{1003f}', '\\u{1004d}'), ('\\u{10050}', '\\u{1005d}'), ('\\u{10080}',\n        '\\u{100fa}'), ('\\u{10140}', '\\u{10174}'), ('\\u{10280}', '\\u{1029c}'), ('\\u{102a0}',\n        '\\u{102d0}'), ('\\u{10300}', '\\u{1031f}'), ('\\u{1032d}', '\\u{1034a}'), ('\\u{10350}',\n        '\\u{1037a}'), ('\\u{10380}', '\\u{1039d}'), ('\\u{103a0}', '\\u{103c3}'), ('\\u{103c8}',\n        '\\u{103cf}'), ('\\u{103d1}', '\\u{103d5}'), ('\\u{10400}', '\\u{1049d}'), ('\\u{104b0}',\n        '\\u{104d3}'), ('\\u{104d8}', '\\u{104fb}'), ('\\u{10500}', '\\u{10527}'), ('\\u{10530}',\n        '\\u{10563}'), ('\\u{10570}', '\\u{1057a}'), ('\\u{1057c}', '\\u{1058a}'), ('\\u{1058c}',\n        '\\u{10592}'), ('\\u{10594}', '\\u{10595}'), ('\\u{10597}', '\\u{105a1}'), ('\\u{105a3}',\n        '\\u{105b1}'), ('\\u{105b3}', '\\u{105b9}'), ('\\u{105bb}', '\\u{105bc}'), ('\\u{105c0}',\n        '\\u{105f3}'), ('\\u{10600}', '\\u{10736}'), ('\\u{10740}', '\\u{10755}'), ('\\u{10760}',\n        '\\u{10767}'), ('\\u{10780}', '\\u{10785}'), ('\\u{10787}', '\\u{107b0}'), ('\\u{107b2}',\n        '\\u{107ba}'), ('\\u{10800}', '\\u{10805}'), ('\\u{10808}', '\\u{10808}'), ('\\u{1080a}',\n        '\\u{10835}'), ('\\u{10837}', '\\u{10838}'), ('\\u{1083c}', '\\u{1083c}'), ('\\u{1083f}',\n        '\\u{10855}'), ('\\u{10860}', '\\u{10876}'), ('\\u{10880}', '\\u{1089e}'), ('\\u{108e0}',\n        '\\u{108f2}'), ('\\u{108f4}', '\\u{108f5}'), ('\\u{10900}', '\\u{10915}'), ('\\u{10920}',\n        '\\u{10939}'), ('\\u{10940}', '\\u{10959}'), ('\\u{10980}', '\\u{109b7}'), ('\\u{109be}',\n        '\\u{109bf}'), ('\\u{10a00}', '\\u{10a03}'), ('\\u{10a05}', '\\u{10a06}'), ('\\u{10a0c}',\n        '\\u{10a13}'), ('\\u{10a15}', '\\u{10a17}'), ('\\u{10a19}', '\\u{10a35}'), ('\\u{10a60}',\n        '\\u{10a7c}'), ('\\u{10a80}', '\\u{10a9c}'), ('\\u{10ac0}', '\\u{10ac7}'), ('\\u{10ac9}',\n        '\\u{10ae4}'), ('\\u{10b00}', '\\u{10b35}'), ('\\u{10b40}', '\\u{10b55}'), ('\\u{10b60}',\n        '\\u{10b72}'), ('\\u{10b80}', '\\u{10b91}'), ('\\u{10c00}', '\\u{10c48}'), ('\\u{10c80}',\n        '\\u{10cb2}'), ('\\u{10cc0}', '\\u{10cf2}'), ('\\u{10d00}', '\\u{10d27}'), ('\\u{10d4a}',\n        '\\u{10d65}'), ('\\u{10d69}', '\\u{10d69}'), ('\\u{10d6f}', '\\u{10d85}'), ('\\u{10e80}',\n        '\\u{10ea9}'), ('\\u{10eab}', '\\u{10eac}'), ('\\u{10eb0}', '\\u{10eb1}'), ('\\u{10ec2}',\n        '\\u{10ec7}'), ('\\u{10efa}', '\\u{10efc}'), ('\\u{10f00}', '\\u{10f1c}'), ('\\u{10f27}',\n        '\\u{10f27}'), ('\\u{10f30}', '\\u{10f45}'), ('\\u{10f70}', '\\u{10f81}'), ('\\u{10fb0}',\n        '\\u{10fc4}'), ('\\u{10fe0}', '\\u{10ff6}'), ('\\u{11000}', '\\u{11045}'), ('\\u{11071}',\n        '\\u{11075}'), ('\\u{11080}', '\\u{110b8}'), ('\\u{110c2}', '\\u{110c2}'), ('\\u{110d0}',\n        '\\u{110e8}'), ('\\u{11100}', '\\u{11132}'), ('\\u{11144}', '\\u{11147}'), ('\\u{11150}',\n        '\\u{11172}'), ('\\u{11176}', '\\u{11176}'), ('\\u{11180}', '\\u{111bf}'), ('\\u{111c1}',\n        '\\u{111c4}'), ('\\u{111ce}', '\\u{111cf}'), ('\\u{111da}', '\\u{111da}'), ('\\u{111dc}',\n        '\\u{111dc}'), ('\\u{11200}', '\\u{11211}'), ('\\u{11213}', '\\u{11234}'), ('\\u{11237}',\n        '\\u{11237}'), ('\\u{1123e}', '\\u{11241}'), ('\\u{11280}', '\\u{11286}'), ('\\u{11288}',\n        '\\u{11288}'), ('\\u{1128a}', '\\u{1128d}'), ('\\u{1128f}', '\\u{1129d}'), ('\\u{1129f}',\n        '\\u{112a8}'), ('\\u{112b0}', '\\u{112e8}'), ('\\u{11300}', '\\u{11303}'), ('\\u{11305}',\n        '\\u{1130c}'), ('\\u{1130f}', '\\u{11310}'), ('\\u{11313}', '\\u{11328}'), ('\\u{1132a}',\n        '\\u{11330}'), ('\\u{11332}', '\\u{11333}'), ('\\u{11335}', '\\u{11339}'), ('\\u{1133d}',\n        '\\u{11344}'), ('\\u{11347}', '\\u{11348}'), ('\\u{1134b}', '\\u{1134c}'), ('\\u{11350}',\n        '\\u{11350}'), ('\\u{11357}', '\\u{11357}'), ('\\u{1135d}', '\\u{11363}'), ('\\u{11380}',\n        '\\u{11389}'), ('\\u{1138b}', '\\u{1138b}'), ('\\u{1138e}', '\\u{1138e}'), ('\\u{11390}',\n        '\\u{113b5}'), ('\\u{113b7}', '\\u{113c0}'), ('\\u{113c2}', '\\u{113c2}'), ('\\u{113c5}',\n        '\\u{113c5}'), ('\\u{113c7}', '\\u{113ca}'), ('\\u{113cc}', '\\u{113cd}'), ('\\u{113d1}',\n        '\\u{113d1}'), ('\\u{113d3}', '\\u{113d3}'), ('\\u{11400}', '\\u{11441}'), ('\\u{11443}',\n        '\\u{11445}'), ('\\u{11447}', '\\u{1144a}'), ('\\u{1145f}', '\\u{11461}'), ('\\u{11480}',\n        '\\u{114c1}'), ('\\u{114c4}', '\\u{114c5}'), ('\\u{114c7}', '\\u{114c7}'), ('\\u{11580}',\n        '\\u{115b5}'), ('\\u{115b8}', '\\u{115be}'), ('\\u{115d8}', '\\u{115dd}'), ('\\u{11600}',\n        '\\u{1163e}'), ('\\u{11640}', '\\u{11640}'), ('\\u{11644}', '\\u{11644}'), ('\\u{11680}',\n        '\\u{116b5}'), ('\\u{116b8}', '\\u{116b8}'), ('\\u{11700}', '\\u{1171a}'), ('\\u{1171d}',\n        '\\u{1172a}'), ('\\u{11740}', '\\u{11746}'), ('\\u{11800}', '\\u{11838}'), ('\\u{118a0}',\n        '\\u{118df}'), ('\\u{118ff}', '\\u{11906}'), ('\\u{11909}', '\\u{11909}'), ('\\u{1190c}',\n        '\\u{11913}'), ('\\u{11915}', '\\u{11916}'), ('\\u{11918}', '\\u{11935}'), ('\\u{11937}',\n        '\\u{11938}'), ('\\u{1193b}', '\\u{1193c}'), ('\\u{1193f}', '\\u{11942}'), ('\\u{119a0}',\n        '\\u{119a7}'), ('\\u{119aa}', '\\u{119d7}'), ('\\u{119da}', '\\u{119df}'), ('\\u{119e1}',\n        '\\u{119e1}'), ('\\u{119e3}', '\\u{119e4}'), ('\\u{11a00}', '\\u{11a32}'), ('\\u{11a35}',\n        '\\u{11a3e}'), ('\\u{11a50}', '\\u{11a97}'), ('\\u{11a9d}', '\\u{11a9d}'), ('\\u{11ab0}',\n        '\\u{11af8}'), ('\\u{11b60}', '\\u{11b67}'), ('\\u{11bc0}', '\\u{11be0}'), ('\\u{11c00}',\n        '\\u{11c08}'), ('\\u{11c0a}', '\\u{11c36}'), ('\\u{11c38}', '\\u{11c3e}'), ('\\u{11c40}',\n        '\\u{11c40}'), ('\\u{11c72}', '\\u{11c8f}'), ('\\u{11c92}', '\\u{11ca7}'), ('\\u{11ca9}',\n        '\\u{11cb6}'), ('\\u{11d00}', '\\u{11d06}'), ('\\u{11d08}', '\\u{11d09}'), ('\\u{11d0b}',\n        '\\u{11d36}'), ('\\u{11d3a}', '\\u{11d3a}'), ('\\u{11d3c}', '\\u{11d3d}'), ('\\u{11d3f}',\n        '\\u{11d41}'), ('\\u{11d43}', '\\u{11d43}'), ('\\u{11d46}', '\\u{11d47}'), ('\\u{11d60}',\n        '\\u{11d65}'), ('\\u{11d67}', '\\u{11d68}'), ('\\u{11d6a}', '\\u{11d8e}'), ('\\u{11d90}',\n        '\\u{11d91}'), ('\\u{11d93}', '\\u{11d96}'), ('\\u{11d98}', '\\u{11d98}'), ('\\u{11db0}',\n        '\\u{11ddb}'), ('\\u{11ee0}', '\\u{11ef6}'), ('\\u{11f00}', '\\u{11f10}'), ('\\u{11f12}',\n        '\\u{11f3a}'), ('\\u{11f3e}', '\\u{11f40}'), ('\\u{11fb0}', '\\u{11fb0}'), ('\\u{12000}',\n        '\\u{12399}'), ('\\u{12400}', '\\u{1246e}'), ('\\u{12480}', '\\u{12543}'), ('\\u{12f90}',\n        '\\u{12ff0}'), ('\\u{13000}', '\\u{1342f}'), ('\\u{13441}', '\\u{13446}'), ('\\u{13460}',\n        '\\u{143fa}'), ('\\u{14400}', '\\u{14646}'), ('\\u{16100}', '\\u{1612e}'), ('\\u{16800}',\n        '\\u{16a38}'), ('\\u{16a40}', '\\u{16a5e}'), ('\\u{16a70}', '\\u{16abe}'), ('\\u{16ad0}',\n        '\\u{16aed}'), ('\\u{16b00}', '\\u{16b2f}'), ('\\u{16b40}', '\\u{16b43}'), ('\\u{16b63}',\n        '\\u{16b77}'), ('\\u{16b7d}', '\\u{16b8f}'), ('\\u{16d40}', '\\u{16d6c}'), ('\\u{16e40}',\n        '\\u{16e7f}'), ('\\u{16ea0}', '\\u{16eb8}'), ('\\u{16ebb}', '\\u{16ed3}'), ('\\u{16f00}',\n        '\\u{16f4a}'), ('\\u{16f4f}', '\\u{16f87}'), ('\\u{16f8f}', '\\u{16f9f}'), ('\\u{16fe0}',\n        '\\u{16fe1}'), ('\\u{16fe3}', '\\u{16fe3}'), ('\\u{16ff0}', '\\u{16ff6}'), ('\\u{17000}',\n        '\\u{18cd5}'), ('\\u{18cff}', '\\u{18d1e}'), ('\\u{18d80}', '\\u{18df2}'), ('\\u{1aff0}',\n        '\\u{1aff3}'), ('\\u{1aff5}', '\\u{1affb}'), ('\\u{1affd}', '\\u{1affe}'), ('\\u{1b000}',\n        '\\u{1b122}'), ('\\u{1b132}', '\\u{1b132}'), ('\\u{1b150}', '\\u{1b152}'), ('\\u{1b155}',\n        '\\u{1b155}'), ('\\u{1b164}', '\\u{1b167}'), ('\\u{1b170}', '\\u{1b2fb}'), ('\\u{1bc00}',\n        '\\u{1bc6a}'), ('\\u{1bc70}', '\\u{1bc7c}'), ('\\u{1bc80}', '\\u{1bc88}'), ('\\u{1bc90}',\n        '\\u{1bc99}'), ('\\u{1bc9e}', '\\u{1bc9e}'), ('\\u{1d400}', '\\u{1d454}'), ('\\u{1d456}',\n        '\\u{1d49c}'), ('\\u{1d49e}', '\\u{1d49f}'), ('\\u{1d4a2}', '\\u{1d4a2}'), ('\\u{1d4a5}',\n        '\\u{1d4a6}'), ('\\u{1d4a9}', '\\u{1d4ac}'), ('\\u{1d4ae}', '\\u{1d4b9}'), ('\\u{1d4bb}',\n        '\\u{1d4bb}'), ('\\u{1d4bd}', '\\u{1d4c3}'), ('\\u{1d4c5}', '\\u{1d505}'), ('\\u{1d507}',\n        '\\u{1d50a}'), ('\\u{1d50d}', '\\u{1d514}'), ('\\u{1d516}', '\\u{1d51c}'), ('\\u{1d51e}',\n        '\\u{1d539}'), ('\\u{1d53b}', '\\u{1d53e}'), ('\\u{1d540}', '\\u{1d544}'), ('\\u{1d546}',\n        '\\u{1d546}'), ('\\u{1d54a}', '\\u{1d550}'), ('\\u{1d552}', '\\u{1d6a5}'), ('\\u{1d6a8}',\n        '\\u{1d6c0}'), ('\\u{1d6c2}', '\\u{1d6da}'), ('\\u{1d6dc}', '\\u{1d6fa}'), ('\\u{1d6fc}',\n        '\\u{1d714}'), ('\\u{1d716}', '\\u{1d734}'), ('\\u{1d736}', '\\u{1d74e}'), ('\\u{1d750}',\n        '\\u{1d76e}'), ('\\u{1d770}', '\\u{1d788}'), ('\\u{1d78a}', '\\u{1d7a8}'), ('\\u{1d7aa}',\n        '\\u{1d7c2}'), ('\\u{1d7c4}', '\\u{1d7cb}'), ('\\u{1df00}', '\\u{1df1e}'), ('\\u{1df25}',\n        '\\u{1df2a}'), ('\\u{1e000}', '\\u{1e006}'), ('\\u{1e008}', '\\u{1e018}'), ('\\u{1e01b}',\n        '\\u{1e021}'), ('\\u{1e023}', '\\u{1e024}'), ('\\u{1e026}', '\\u{1e02a}'), ('\\u{1e030}',\n        '\\u{1e06d}'), ('\\u{1e08f}', '\\u{1e08f}'), ('\\u{1e100}', '\\u{1e12c}'), ('\\u{1e137}',\n        '\\u{1e13d}'), ('\\u{1e14e}', '\\u{1e14e}'), ('\\u{1e290}', '\\u{1e2ad}'), ('\\u{1e2c0}',\n        '\\u{1e2eb}'), ('\\u{1e4d0}', '\\u{1e4eb}'), ('\\u{1e5d0}', '\\u{1e5ed}'), ('\\u{1e5f0}',\n        '\\u{1e5f0}'), ('\\u{1e6c0}', '\\u{1e6de}'), ('\\u{1e6e0}', '\\u{1e6f5}'), ('\\u{1e6fe}',\n        '\\u{1e6ff}'), ('\\u{1e7e0}', '\\u{1e7e6}'), ('\\u{1e7e8}', '\\u{1e7eb}'), ('\\u{1e7ed}',\n        '\\u{1e7ee}'), ('\\u{1e7f0}', '\\u{1e7fe}'), ('\\u{1e800}', '\\u{1e8c4}'), ('\\u{1e900}',\n        '\\u{1e943}'), ('\\u{1e947}', '\\u{1e947}'), ('\\u{1e94b}', '\\u{1e94b}'), ('\\u{1ee00}',\n        '\\u{1ee03}'), ('\\u{1ee05}', '\\u{1ee1f}'), ('\\u{1ee21}', '\\u{1ee22}'), ('\\u{1ee24}',\n        '\\u{1ee24}'), ('\\u{1ee27}', '\\u{1ee27}'), ('\\u{1ee29}', '\\u{1ee32}'), ('\\u{1ee34}',\n        '\\u{1ee37}'), ('\\u{1ee39}', '\\u{1ee39}'), ('\\u{1ee3b}', '\\u{1ee3b}'), ('\\u{1ee42}',\n        '\\u{1ee42}'), ('\\u{1ee47}', '\\u{1ee47}'), ('\\u{1ee49}', '\\u{1ee49}'), ('\\u{1ee4b}',\n        '\\u{1ee4b}'), ('\\u{1ee4d}', '\\u{1ee4f}'), ('\\u{1ee51}', '\\u{1ee52}'), ('\\u{1ee54}',\n        '\\u{1ee54}'), ('\\u{1ee57}', '\\u{1ee57}'), ('\\u{1ee59}', '\\u{1ee59}'), ('\\u{1ee5b}',\n        '\\u{1ee5b}'), ('\\u{1ee5d}', '\\u{1ee5d}'), ('\\u{1ee5f}', '\\u{1ee5f}'), ('\\u{1ee61}',\n        '\\u{1ee62}'), ('\\u{1ee64}', '\\u{1ee64}'), ('\\u{1ee67}', '\\u{1ee6a}'), ('\\u{1ee6c}',\n        '\\u{1ee72}'), ('\\u{1ee74}', '\\u{1ee77}'), ('\\u{1ee79}', '\\u{1ee7c}'), ('\\u{1ee7e}',\n        '\\u{1ee7e}'), ('\\u{1ee80}', '\\u{1ee89}'), ('\\u{1ee8b}', '\\u{1ee9b}'), ('\\u{1eea1}',\n        '\\u{1eea3}'), ('\\u{1eea5}', '\\u{1eea9}'), ('\\u{1eeab}', '\\u{1eebb}'), ('\\u{1f130}',\n        '\\u{1f149}'), ('\\u{1f150}', '\\u{1f169}'), ('\\u{1f170}', '\\u{1f189}'), ('\\u{20000}',\n        '\\u{2a6df}'), ('\\u{2a700}', '\\u{2b81d}'), ('\\u{2b820}', '\\u{2cead}'), ('\\u{2ceb0}',\n        '\\u{2ebe0}'), ('\\u{2ebf0}', '\\u{2ee5d}'), ('\\u{2f800}', '\\u{2fa1d}'), ('\\u{30000}',\n        '\\u{3134a}'), ('\\u{31350}', '\\u{33479}')\n    ];\n\n    #[inline]\n    pub fn Alphabetic(c: char) -> bool {\n        super::util::bsearch_range_table(c, Alphabetic_table)\n    }\n\n    const InCB_Extend_table: &[(char, char)] = &[\n        ('\\u{300}', '\\u{36f}'), ('\\u{483}', '\\u{489}'), ('\\u{591}', '\\u{5bd}'), ('\\u{5bf}',\n        '\\u{5bf}'), ('\\u{5c1}', '\\u{5c2}'), ('\\u{5c4}', '\\u{5c5}'), ('\\u{5c7}', '\\u{5c7}'),\n        ('\\u{610}', '\\u{61a}'), ('\\u{64b}', '\\u{65f}'), ('\\u{670}', '\\u{670}'), ('\\u{6d6}',\n        '\\u{6dc}'), ('\\u{6df}', '\\u{6e4}'), ('\\u{6e7}', '\\u{6e8}'), ('\\u{6ea}', '\\u{6ed}'),\n        ('\\u{711}', '\\u{711}'), ('\\u{730}', '\\u{74a}'), ('\\u{7a6}', '\\u{7b0}'), ('\\u{7eb}',\n        '\\u{7f3}'), ('\\u{7fd}', '\\u{7fd}'), ('\\u{816}', '\\u{819}'), ('\\u{81b}', '\\u{823}'),\n        ('\\u{825}', '\\u{827}'), ('\\u{829}', '\\u{82d}'), ('\\u{859}', '\\u{85b}'), ('\\u{897}',\n        '\\u{89f}'), ('\\u{8ca}', '\\u{8e1}'), ('\\u{8e3}', '\\u{902}'), ('\\u{93a}', '\\u{93a}'),\n        ('\\u{93c}', '\\u{93c}'), ('\\u{941}', '\\u{948}'), ('\\u{951}', '\\u{957}'), ('\\u{962}',\n        '\\u{963}'), ('\\u{981}', '\\u{981}'), ('\\u{9bc}', '\\u{9bc}'), ('\\u{9be}', '\\u{9be}'),\n        ('\\u{9c1}', '\\u{9c4}'), ('\\u{9d7}', '\\u{9d7}'), ('\\u{9e2}', '\\u{9e3}'), ('\\u{9fe}',\n        '\\u{9fe}'), ('\\u{a01}', '\\u{a02}'), ('\\u{a3c}', '\\u{a3c}'), ('\\u{a41}', '\\u{a42}'),\n        ('\\u{a47}', '\\u{a48}'), ('\\u{a4b}', '\\u{a4d}'), ('\\u{a51}', '\\u{a51}'), ('\\u{a70}',\n        '\\u{a71}'), ('\\u{a75}', '\\u{a75}'), ('\\u{a81}', '\\u{a82}'), ('\\u{abc}', '\\u{abc}'),\n        ('\\u{ac1}', '\\u{ac5}'), ('\\u{ac7}', '\\u{ac8}'), ('\\u{ae2}', '\\u{ae3}'), ('\\u{afa}',\n        '\\u{aff}'), ('\\u{b01}', '\\u{b01}'), ('\\u{b3c}', '\\u{b3c}'), ('\\u{b3e}', '\\u{b3f}'),\n        ('\\u{b41}', '\\u{b44}'), ('\\u{b55}', '\\u{b57}'), ('\\u{b62}', '\\u{b63}'), ('\\u{b82}',\n        '\\u{b82}'), ('\\u{bbe}', '\\u{bbe}'), ('\\u{bc0}', '\\u{bc0}'), ('\\u{bcd}', '\\u{bcd}'),\n        ('\\u{bd7}', '\\u{bd7}'), ('\\u{c00}', '\\u{c00}'), ('\\u{c04}', '\\u{c04}'), ('\\u{c3c}',\n        '\\u{c3c}'), ('\\u{c3e}', '\\u{c40}'), ('\\u{c46}', '\\u{c48}'), ('\\u{c4a}', '\\u{c4c}'),\n        ('\\u{c55}', '\\u{c56}'), ('\\u{c62}', '\\u{c63}'), ('\\u{c81}', '\\u{c81}'), ('\\u{cbc}',\n        '\\u{cbc}'), ('\\u{cbf}', '\\u{cc0}'), ('\\u{cc2}', '\\u{cc2}'), ('\\u{cc6}', '\\u{cc8}'),\n        ('\\u{cca}', '\\u{ccd}'), ('\\u{cd5}', '\\u{cd6}'), ('\\u{ce2}', '\\u{ce3}'), ('\\u{d00}',\n        '\\u{d01}'), ('\\u{d3b}', '\\u{d3c}'), ('\\u{d3e}', '\\u{d3e}'), ('\\u{d41}', '\\u{d44}'),\n        ('\\u{d57}', '\\u{d57}'), ('\\u{d62}', '\\u{d63}'), ('\\u{d81}', '\\u{d81}'), ('\\u{dca}',\n        '\\u{dca}'), ('\\u{dcf}', '\\u{dcf}'), ('\\u{dd2}', '\\u{dd4}'), ('\\u{dd6}', '\\u{dd6}'),\n        ('\\u{ddf}', '\\u{ddf}'), ('\\u{e31}', '\\u{e31}'), ('\\u{e34}', '\\u{e3a}'), ('\\u{e47}',\n        '\\u{e4e}'), ('\\u{eb1}', '\\u{eb1}'), ('\\u{eb4}', '\\u{ebc}'), ('\\u{ec8}', '\\u{ece}'),\n        ('\\u{f18}', '\\u{f19}'), ('\\u{f35}', '\\u{f35}'), ('\\u{f37}', '\\u{f37}'), ('\\u{f39}',\n        '\\u{f39}'), ('\\u{f71}', '\\u{f7e}'), ('\\u{f80}', '\\u{f84}'), ('\\u{f86}', '\\u{f87}'),\n        ('\\u{f8d}', '\\u{f97}'), ('\\u{f99}', '\\u{fbc}'), ('\\u{fc6}', '\\u{fc6}'), ('\\u{102d}',\n        '\\u{1030}'), ('\\u{1032}', '\\u{1037}'), ('\\u{103a}', '\\u{103a}'), ('\\u{103d}', '\\u{103e}'),\n        ('\\u{1058}', '\\u{1059}'), ('\\u{105e}', '\\u{1060}'), ('\\u{1071}', '\\u{1074}'), ('\\u{1082}',\n        '\\u{1082}'), ('\\u{1085}', '\\u{1086}'), ('\\u{108d}', '\\u{108d}'), ('\\u{109d}', '\\u{109d}'),\n        ('\\u{135d}', '\\u{135f}'), ('\\u{1712}', '\\u{1715}'), ('\\u{1732}', '\\u{1734}'), ('\\u{1752}',\n        '\\u{1753}'), ('\\u{1772}', '\\u{1773}'), ('\\u{17b4}', '\\u{17b5}'), ('\\u{17b7}', '\\u{17bd}'),\n        ('\\u{17c6}', '\\u{17c6}'), ('\\u{17c9}', '\\u{17d1}'), ('\\u{17d3}', '\\u{17d3}'), ('\\u{17dd}',\n        '\\u{17dd}'), ('\\u{180b}', '\\u{180d}'), ('\\u{180f}', '\\u{180f}'), ('\\u{1885}', '\\u{1886}'),\n        ('\\u{18a9}', '\\u{18a9}'), ('\\u{1920}', '\\u{1922}'), ('\\u{1927}', '\\u{1928}'), ('\\u{1932}',\n        '\\u{1932}'), ('\\u{1939}', '\\u{193b}'), ('\\u{1a17}', '\\u{1a18}'), ('\\u{1a1b}', '\\u{1a1b}'),\n        ('\\u{1a56}', '\\u{1a56}'), ('\\u{1a58}', '\\u{1a5e}'), ('\\u{1a62}', '\\u{1a62}'), ('\\u{1a65}',\n        '\\u{1a6c}'), ('\\u{1a73}', '\\u{1a7c}'), ('\\u{1a7f}', '\\u{1a7f}'), ('\\u{1ab0}', '\\u{1add}'),\n        ('\\u{1ae0}', '\\u{1aeb}'), ('\\u{1b00}', '\\u{1b03}'), ('\\u{1b34}', '\\u{1b3d}'), ('\\u{1b42}',\n        '\\u{1b43}'), ('\\u{1b6b}', '\\u{1b73}'), ('\\u{1b80}', '\\u{1b81}'), ('\\u{1ba2}', '\\u{1ba5}'),\n        ('\\u{1ba8}', '\\u{1baa}'), ('\\u{1bac}', '\\u{1bad}'), ('\\u{1be6}', '\\u{1be6}'), ('\\u{1be8}',\n        '\\u{1be9}'), ('\\u{1bed}', '\\u{1bed}'), ('\\u{1bef}', '\\u{1bf3}'), ('\\u{1c2c}', '\\u{1c33}'),\n        ('\\u{1c36}', '\\u{1c37}'), ('\\u{1cd0}', '\\u{1cd2}'), ('\\u{1cd4}', '\\u{1ce0}'), ('\\u{1ce2}',\n        '\\u{1ce8}'), ('\\u{1ced}', '\\u{1ced}'), ('\\u{1cf4}', '\\u{1cf4}'), ('\\u{1cf8}', '\\u{1cf9}'),\n        ('\\u{1dc0}', '\\u{1dff}'), ('\\u{200d}', '\\u{200d}'), ('\\u{20d0}', '\\u{20f0}'), ('\\u{2cef}',\n        '\\u{2cf1}'), ('\\u{2d7f}', '\\u{2d7f}'), ('\\u{2de0}', '\\u{2dff}'), ('\\u{302a}', '\\u{302f}'),\n        ('\\u{3099}', '\\u{309a}'), ('\\u{a66f}', '\\u{a672}'), ('\\u{a674}', '\\u{a67d}'), ('\\u{a69e}',\n        '\\u{a69f}'), ('\\u{a6f0}', '\\u{a6f1}'), ('\\u{a802}', '\\u{a802}'), ('\\u{a806}', '\\u{a806}'),\n        ('\\u{a80b}', '\\u{a80b}'), ('\\u{a825}', '\\u{a826}'), ('\\u{a82c}', '\\u{a82c}'), ('\\u{a8c4}',\n        '\\u{a8c5}'), ('\\u{a8e0}', '\\u{a8f1}'), ('\\u{a8ff}', '\\u{a8ff}'), ('\\u{a926}', '\\u{a92d}'),\n        ('\\u{a947}', '\\u{a951}'), ('\\u{a953}', '\\u{a953}'), ('\\u{a980}', '\\u{a982}'), ('\\u{a9b3}',\n        '\\u{a9b3}'), ('\\u{a9b6}', '\\u{a9b9}'), ('\\u{a9bc}', '\\u{a9bd}'), ('\\u{a9e5}', '\\u{a9e5}'),\n        ('\\u{aa29}', '\\u{aa2e}'), ('\\u{aa31}', '\\u{aa32}'), ('\\u{aa35}', '\\u{aa36}'), ('\\u{aa43}',\n        '\\u{aa43}'), ('\\u{aa4c}', '\\u{aa4c}'), ('\\u{aa7c}', '\\u{aa7c}'), ('\\u{aab0}', '\\u{aab0}'),\n        ('\\u{aab2}', '\\u{aab4}'), ('\\u{aab7}', '\\u{aab8}'), ('\\u{aabe}', '\\u{aabf}'), ('\\u{aac1}',\n        '\\u{aac1}'), ('\\u{aaec}', '\\u{aaed}'), ('\\u{abe5}', '\\u{abe5}'), ('\\u{abe8}', '\\u{abe8}'),\n        ('\\u{abed}', '\\u{abed}'), ('\\u{fb1e}', '\\u{fb1e}'), ('\\u{fe00}', '\\u{fe0f}'), ('\\u{fe20}',\n        '\\u{fe2f}'), ('\\u{ff9e}', '\\u{ff9f}'), ('\\u{101fd}', '\\u{101fd}'), ('\\u{102e0}',\n        '\\u{102e0}'), ('\\u{10376}', '\\u{1037a}'), ('\\u{10a01}', '\\u{10a03}'), ('\\u{10a05}',\n        '\\u{10a06}'), ('\\u{10a0c}', '\\u{10a0f}'), ('\\u{10a38}', '\\u{10a3a}'), ('\\u{10ae5}',\n        '\\u{10ae6}'), ('\\u{10d24}', '\\u{10d27}'), ('\\u{10d69}', '\\u{10d6d}'), ('\\u{10eab}',\n        '\\u{10eac}'), ('\\u{10efa}', '\\u{10eff}'), ('\\u{10f46}', '\\u{10f50}'), ('\\u{10f82}',\n        '\\u{10f85}'), ('\\u{11001}', '\\u{11001}'), ('\\u{11038}', '\\u{11046}'), ('\\u{11070}',\n        '\\u{11070}'), ('\\u{11073}', '\\u{11074}'), ('\\u{1107f}', '\\u{11081}'), ('\\u{110b3}',\n        '\\u{110b6}'), ('\\u{110b9}', '\\u{110ba}'), ('\\u{110c2}', '\\u{110c2}'), ('\\u{11100}',\n        '\\u{11102}'), ('\\u{11127}', '\\u{1112b}'), ('\\u{1112d}', '\\u{11132}'), ('\\u{11134}',\n        '\\u{11134}'), ('\\u{11173}', '\\u{11173}'), ('\\u{11180}', '\\u{11181}'), ('\\u{111b6}',\n        '\\u{111be}'), ('\\u{111c0}', '\\u{111c0}'), ('\\u{111c9}', '\\u{111cc}'), ('\\u{111cf}',\n        '\\u{111cf}'), ('\\u{1122f}', '\\u{11231}'), ('\\u{11234}', '\\u{11237}'), ('\\u{1123e}',\n        '\\u{1123e}'), ('\\u{11241}', '\\u{11241}'), ('\\u{112df}', '\\u{112df}'), ('\\u{112e3}',\n        '\\u{112ea}'), ('\\u{11300}', '\\u{11301}'), ('\\u{1133b}', '\\u{1133c}'), ('\\u{1133e}',\n        '\\u{1133e}'), ('\\u{11340}', '\\u{11340}'), ('\\u{1134d}', '\\u{1134d}'), ('\\u{11357}',\n        '\\u{11357}'), ('\\u{11366}', '\\u{1136c}'), ('\\u{11370}', '\\u{11374}'), ('\\u{113b8}',\n        '\\u{113b8}'), ('\\u{113bb}', '\\u{113c0}'), ('\\u{113c2}', '\\u{113c2}'), ('\\u{113c5}',\n        '\\u{113c5}'), ('\\u{113c7}', '\\u{113c9}'), ('\\u{113ce}', '\\u{113cf}'), ('\\u{113d2}',\n        '\\u{113d2}'), ('\\u{113e1}', '\\u{113e2}'), ('\\u{11438}', '\\u{1143f}'), ('\\u{11442}',\n        '\\u{11444}'), ('\\u{11446}', '\\u{11446}'), ('\\u{1145e}', '\\u{1145e}'), ('\\u{114b0}',\n        '\\u{114b0}'), ('\\u{114b3}', '\\u{114b8}'), ('\\u{114ba}', '\\u{114ba}'), ('\\u{114bd}',\n        '\\u{114bd}'), ('\\u{114bf}', '\\u{114c0}'), ('\\u{114c2}', '\\u{114c3}'), ('\\u{115af}',\n        '\\u{115af}'), ('\\u{115b2}', '\\u{115b5}'), ('\\u{115bc}', '\\u{115bd}'), ('\\u{115bf}',\n        '\\u{115c0}'), ('\\u{115dc}', '\\u{115dd}'), ('\\u{11633}', '\\u{1163a}'), ('\\u{1163d}',\n        '\\u{1163d}'), ('\\u{1163f}', '\\u{11640}'), ('\\u{116ab}', '\\u{116ab}'), ('\\u{116ad}',\n        '\\u{116ad}'), ('\\u{116b0}', '\\u{116b7}'), ('\\u{1171d}', '\\u{1171d}'), ('\\u{1171f}',\n        '\\u{1171f}'), ('\\u{11722}', '\\u{11725}'), ('\\u{11727}', '\\u{1172b}'), ('\\u{1182f}',\n        '\\u{11837}'), ('\\u{11839}', '\\u{1183a}'), ('\\u{11930}', '\\u{11930}'), ('\\u{1193b}',\n        '\\u{1193d}'), ('\\u{11943}', '\\u{11943}'), ('\\u{119d4}', '\\u{119d7}'), ('\\u{119da}',\n        '\\u{119db}'), ('\\u{119e0}', '\\u{119e0}'), ('\\u{11a01}', '\\u{11a0a}'), ('\\u{11a33}',\n        '\\u{11a38}'), ('\\u{11a3b}', '\\u{11a3e}'), ('\\u{11a51}', '\\u{11a56}'), ('\\u{11a59}',\n        '\\u{11a5b}'), ('\\u{11a8a}', '\\u{11a96}'), ('\\u{11a98}', '\\u{11a98}'), ('\\u{11b60}',\n        '\\u{11b60}'), ('\\u{11b62}', '\\u{11b64}'), ('\\u{11b66}', '\\u{11b66}'), ('\\u{11c30}',\n        '\\u{11c36}'), ('\\u{11c38}', '\\u{11c3d}'), ('\\u{11c3f}', '\\u{11c3f}'), ('\\u{11c92}',\n        '\\u{11ca7}'), ('\\u{11caa}', '\\u{11cb0}'), ('\\u{11cb2}', '\\u{11cb3}'), ('\\u{11cb5}',\n        '\\u{11cb6}'), ('\\u{11d31}', '\\u{11d36}'), ('\\u{11d3a}', '\\u{11d3a}'), ('\\u{11d3c}',\n        '\\u{11d3d}'), ('\\u{11d3f}', '\\u{11d45}'), ('\\u{11d47}', '\\u{11d47}'), ('\\u{11d90}',\n        '\\u{11d91}'), ('\\u{11d95}', '\\u{11d95}'), ('\\u{11d97}', '\\u{11d97}'), ('\\u{11ef3}',\n        '\\u{11ef4}'), ('\\u{11f00}', '\\u{11f01}'), ('\\u{11f36}', '\\u{11f3a}'), ('\\u{11f40}',\n        '\\u{11f41}'), ('\\u{11f5a}', '\\u{11f5a}'), ('\\u{13440}', '\\u{13440}'), ('\\u{13447}',\n        '\\u{13455}'), ('\\u{1611e}', '\\u{16129}'), ('\\u{1612d}', '\\u{1612f}'), ('\\u{16af0}',\n        '\\u{16af4}'), ('\\u{16b30}', '\\u{16b36}'), ('\\u{16f4f}', '\\u{16f4f}'), ('\\u{16f8f}',\n        '\\u{16f92}'), ('\\u{16fe4}', '\\u{16fe4}'), ('\\u{16ff0}', '\\u{16ff1}'), ('\\u{1bc9d}',\n        '\\u{1bc9e}'), ('\\u{1cf00}', '\\u{1cf2d}'), ('\\u{1cf30}', '\\u{1cf46}'), ('\\u{1d165}',\n        '\\u{1d169}'), ('\\u{1d16d}', '\\u{1d172}'), ('\\u{1d17b}', '\\u{1d182}'), ('\\u{1d185}',\n        '\\u{1d18b}'), ('\\u{1d1aa}', '\\u{1d1ad}'), ('\\u{1d242}', '\\u{1d244}'), ('\\u{1da00}',\n        '\\u{1da36}'), ('\\u{1da3b}', '\\u{1da6c}'), ('\\u{1da75}', '\\u{1da75}'), ('\\u{1da84}',\n        '\\u{1da84}'), ('\\u{1da9b}', '\\u{1da9f}'), ('\\u{1daa1}', '\\u{1daaf}'), ('\\u{1e000}',\n        '\\u{1e006}'), ('\\u{1e008}', '\\u{1e018}'), ('\\u{1e01b}', '\\u{1e021}'), ('\\u{1e023}',\n        '\\u{1e024}'), ('\\u{1e026}', '\\u{1e02a}'), ('\\u{1e08f}', '\\u{1e08f}'), ('\\u{1e130}',\n        '\\u{1e136}'), ('\\u{1e2ae}', '\\u{1e2ae}'), ('\\u{1e2ec}', '\\u{1e2ef}'), ('\\u{1e4ec}',\n        '\\u{1e4ef}'), ('\\u{1e5ee}', '\\u{1e5ef}'), ('\\u{1e6e3}', '\\u{1e6e3}'), ('\\u{1e6e6}',\n        '\\u{1e6e6}'), ('\\u{1e6ee}', '\\u{1e6ef}'), ('\\u{1e6f5}', '\\u{1e6f5}'), ('\\u{1e8d0}',\n        '\\u{1e8d6}'), ('\\u{1e944}', '\\u{1e94a}'), ('\\u{1f3fb}', '\\u{1f3ff}'), ('\\u{e0020}',\n        '\\u{e007f}'), ('\\u{e0100}', '\\u{e01ef}')\n    ];\n\n    #[inline]\n    pub fn InCB_Extend(c: char) -> bool {\n        super::util::bsearch_range_table(c, InCB_Extend_table)\n    }\n\n}\n\npub fn is_incb_linker(c: char) -> bool {\n    matches!(c, | '\\u{94D}' | '\\u{9CD}' | '\\u{ACD}' | '\\u{B4D}' | '\\u{C4D}' | '\\u{D4D}' | '\\u{1039}' | '\\u{17D2}' | '\\u{1A60}' | '\\u{1B44}' | '\\u{1BAB}' | '\\u{A9C0}' | '\\u{AAF6}' | '\\u{10A3F}' | '\\u{11133}' | '\\u{113D0}' | '\\u{1193E}' | '\\u{11A47}' | '\\u{11A99}' | '\\u{11F42}')\n}\n\npub mod grapheme {\n    use core::result::Result::{Ok, Err};\n\n    pub use self::GraphemeCat::*;\n\n    #[allow(non_camel_case_types)]\n    #[derive(Clone, Copy, PartialEq, Eq, Debug)]\n    pub enum GraphemeCat {\n        GC_Any,\n        GC_CR,\n        GC_Control,\n        GC_Extend,\n        GC_Extended_Pictographic,\n        GC_InCB_Consonant,\n        GC_L,\n        GC_LF,\n        GC_LV,\n        GC_LVT,\n        GC_Prepend,\n        GC_Regional_Indicator,\n        GC_SpacingMark,\n        GC_T,\n        GC_V,\n        GC_ZWJ,\n    }\n\n    fn bsearch_range_value_table(c: char, r: &[(char, char, GraphemeCat)], default_lower: u32, default_upper: u32) -> (u32, u32, GraphemeCat) {\n        use core::cmp::Ordering::{Equal, Less, Greater};\n        match r.binary_search_by(|&(lo, hi, _)| {\n            if lo <= c && c <= hi { Equal }\n            else if hi < c { Less }\n            else { Greater }\n        }) {\n            Ok(idx) => {\n                let (lower, upper, cat) = r[idx];\n                (lower as u32, upper as u32, cat)\n            }\n            Err(idx) => {\n                (\n                    if idx > 0 { r[idx-1].1 as u32 + 1 } else { default_lower },\n                    r.get(idx).map(|c|c.0 as u32 - 1).unwrap_or(default_upper),\n                    GC_Any,\n                )\n            }\n        }\n    }\n\n    pub fn grapheme_category(c: char) -> (u32, u32, GraphemeCat) {\n        // Perform a quick O(1) lookup in a precomputed table to determine\n        // the slice of the range table to search in.\n        let lookup_interval = 0x80;\n        let idx = (c as u32 / lookup_interval) as usize;\n        let range = grapheme_cat_lookup.get(idx..(idx + 2)).map_or(\n          // If the `idx` is outside of the precomputed table - use the slice\n          // starting from the last covered index in the precomputed table and\n          // ending with the length of the range table.\n          1612..1618,\n          |r| (r[0] as usize)..((r[1] + 1) as usize)\n        );\n\n        // Compute pessimistic default lower and upper bounds on the category.\n        // If character doesn't map to any range and there is no adjacent range\n        // in the table slice - these bounds has to apply.\n        let lower = idx as u32 * lookup_interval;\n        let upper = lower + lookup_interval - 1;\n        bsearch_range_value_table(c, &grapheme_cat_table[range], lower, upper)\n    }\n\n    const grapheme_cat_lookup: &[u16] = &[\n        0, 5, 9, 9, 9, 9, 9, 10, 10, 10, 11, 11, 16, 21, 26, 29, 32, 37, 41, 56, 75, 85, 101, 119,\n        128, 141, 154, 167, 177, 181, 185, 192, 197, 214, 221, 222, 224, 224, 224, 225, 225, 225,\n        225, 225, 225, 225, 225, 229, 238, 241, 243, 251, 251, 265, 267, 276, 292, 296, 304, 304,\n        305, 305, 305, 305, 305, 313, 314, 316, 318, 318, 318, 320, 323, 323, 324, 324, 328, 349,\n        366, 384, 388, 388, 388, 389, 389, 389, 389, 393, 393, 393, 394, 395, 396, 396, 396, 396,\n        396, 399, 400, 400, 400, 400, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,\n        402, 402, 402, 404, 406, 406, 406, 413, 418, 423, 438, 451, 462, 462, 470, 479, 489, 497,\n        507, 515, 525, 534, 543, 553, 561, 571, 579, 589, 598, 607, 617, 625, 635, 643, 653, 662,\n        671, 681, 689, 699, 707, 717, 726, 735, 745, 753, 763, 771, 781, 790, 799, 809, 817, 827,\n        835, 845, 854, 863, 873, 881, 891, 899, 909, 918, 927, 937, 945, 955, 963, 973, 982, 991,\n        1001, 1009, 1019, 1027, 1037, 1046, 1055, 1065, 1073, 1083, 1091, 1101, 1110, 1119, 1129,\n        1137, 1147, 1155, 1165, 1174, 1183, 1193, 1201, 1211, 1219, 1229, 1238, 1247, 1257, 1265,\n        1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270,\n        1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270,\n        1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270,\n        1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270,\n        1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1271, 1271, 1271, 1271,\n        1271, 1271, 1273, 1274, 1274, 1276, 1276, 1276, 1276, 1277, 1277, 1278, 1279, 1279, 1279,\n        1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1288, 1289, 1289, 1289,\n        1289, 1289, 1291, 1291, 1291, 1293, 1294, 1295, 1301, 1310, 1319, 1329, 1335, 1338, 1352,\n        1368, 1375, 1386, 1386, 1394, 1400, 1405, 1411, 1411, 1415, 1415, 1429, 1435, 1446, 1451,\n        1457, 1457, 1462, 1469, 1475, 1481, 1481, 1483, 1493, 1493, 1493, 1493, 1493, 1493, 1493,\n        1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,\n        1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,\n        1493, 1493, 1493, 1493, 1493, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496,\n        1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496,\n        1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496,\n        1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496,\n        1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496,\n        1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496,\n        1496, 1496, 1496, 1496, 1496, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,\n        1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1500, 1501, 1501, 1501, 1501, 1503,\n        1503, 1503, 1503, 1504, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,\n        1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,\n        1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,\n        1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,\n        1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,\n        1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,\n        1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,\n        1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,\n        1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,\n        1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,\n        1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1510, 1510, 1510, 1510, 1510, 1510, 1510,\n        1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,\n        1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,\n        1512, 1512, 1512, 1512, 1515, 1518, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519, 1519,\n        1519, 1519, 1519, 1519, 1519, 1519, 1519, 1522, 1525, 1525, 1525, 1525, 1525, 1525, 1525,\n        1525, 1525, 1525, 1525, 1530, 1531, 1532, 1532, 1532, 1534, 1534, 1534, 1534, 1535, 1535,\n        1536, 1536, 1540, 1540, 1540, 1540, 1541, 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542,\n        1542, 1542, 1542, 1542, 1542, 1542, 1544, 1549, 1551, 1555, 1561, 1561, 1562, 1569, 1569,\n        1570, 1575, 1591, 1592, 1598, 1598, 1599, 1602, 1607, 1609, 1610, 1611, 1612, 1612, 1612,\n        1612, 1612, 1612, 1612, 1612, 1612, 1612\n    ];\n\n    const grapheme_cat_table: &[(char, char, GraphemeCat)] = &[\n        ('\\u{0}', '\\u{9}', GC_Control), ('\\u{a}', '\\u{a}', GC_LF), ('\\u{b}', '\\u{c}', GC_Control),\n        ('\\u{d}', '\\u{d}', GC_CR), ('\\u{e}', '\\u{1f}', GC_Control), ('\\u{7f}', '\\u{9f}',\n        GC_Control), ('\\u{a9}', '\\u{a9}', GC_Extended_Pictographic), ('\\u{ad}', '\\u{ad}',\n        GC_Control), ('\\u{ae}', '\\u{ae}', GC_Extended_Pictographic), ('\\u{300}', '\\u{36f}',\n        GC_Extend), ('\\u{483}', '\\u{489}', GC_Extend), ('\\u{591}', '\\u{5bd}', GC_Extend),\n        ('\\u{5bf}', '\\u{5bf}', GC_Extend), ('\\u{5c1}', '\\u{5c2}', GC_Extend), ('\\u{5c4}', '\\u{5c5}',\n        GC_Extend), ('\\u{5c7}', '\\u{5c7}', GC_Extend), ('\\u{600}', '\\u{605}', GC_Prepend),\n        ('\\u{610}', '\\u{61a}', GC_Extend), ('\\u{61c}', '\\u{61c}', GC_Control), ('\\u{64b}',\n        '\\u{65f}', GC_Extend), ('\\u{670}', '\\u{670}', GC_Extend), ('\\u{6d6}', '\\u{6dc}', GC_Extend),\n        ('\\u{6dd}', '\\u{6dd}', GC_Prepend), ('\\u{6df}', '\\u{6e4}', GC_Extend), ('\\u{6e7}',\n        '\\u{6e8}', GC_Extend), ('\\u{6ea}', '\\u{6ed}', GC_Extend), ('\\u{70f}', '\\u{70f}',\n        GC_Prepend), ('\\u{711}', '\\u{711}', GC_Extend), ('\\u{730}', '\\u{74a}', GC_Extend),\n        ('\\u{7a6}', '\\u{7b0}', GC_Extend), ('\\u{7eb}', '\\u{7f3}', GC_Extend), ('\\u{7fd}', '\\u{7fd}',\n        GC_Extend), ('\\u{816}', '\\u{819}', GC_Extend), ('\\u{81b}', '\\u{823}', GC_Extend),\n        ('\\u{825}', '\\u{827}', GC_Extend), ('\\u{829}', '\\u{82d}', GC_Extend), ('\\u{859}', '\\u{85b}',\n        GC_Extend), ('\\u{890}', '\\u{891}', GC_Prepend), ('\\u{897}', '\\u{89f}', GC_Extend),\n        ('\\u{8ca}', '\\u{8e1}', GC_Extend), ('\\u{8e2}', '\\u{8e2}', GC_Prepend), ('\\u{8e3}',\n        '\\u{902}', GC_Extend), ('\\u{903}', '\\u{903}', GC_SpacingMark), ('\\u{915}', '\\u{939}',\n        GC_InCB_Consonant), ('\\u{93a}', '\\u{93a}', GC_Extend), ('\\u{93b}', '\\u{93b}',\n        GC_SpacingMark), ('\\u{93c}', '\\u{93c}', GC_Extend), ('\\u{93e}', '\\u{940}', GC_SpacingMark),\n        ('\\u{941}', '\\u{948}', GC_Extend), ('\\u{949}', '\\u{94c}', GC_SpacingMark), ('\\u{94d}',\n        '\\u{94d}', GC_Extend), ('\\u{94e}', '\\u{94f}', GC_SpacingMark), ('\\u{951}', '\\u{957}',\n        GC_Extend), ('\\u{958}', '\\u{95f}', GC_InCB_Consonant), ('\\u{962}', '\\u{963}', GC_Extend),\n        ('\\u{978}', '\\u{97f}', GC_InCB_Consonant), ('\\u{981}', '\\u{981}', GC_Extend), ('\\u{982}',\n        '\\u{983}', GC_SpacingMark), ('\\u{995}', '\\u{9a8}', GC_InCB_Consonant), ('\\u{9aa}',\n        '\\u{9b0}', GC_InCB_Consonant), ('\\u{9b2}', '\\u{9b2}', GC_InCB_Consonant), ('\\u{9b6}',\n        '\\u{9b9}', GC_InCB_Consonant), ('\\u{9bc}', '\\u{9bc}', GC_Extend), ('\\u{9be}', '\\u{9be}',\n        GC_Extend), ('\\u{9bf}', '\\u{9c0}', GC_SpacingMark), ('\\u{9c1}', '\\u{9c4}', GC_Extend),\n        ('\\u{9c7}', '\\u{9c8}', GC_SpacingMark), ('\\u{9cb}', '\\u{9cc}', GC_SpacingMark), ('\\u{9cd}',\n        '\\u{9cd}', GC_Extend), ('\\u{9d7}', '\\u{9d7}', GC_Extend), ('\\u{9dc}', '\\u{9dd}',\n        GC_InCB_Consonant), ('\\u{9df}', '\\u{9df}', GC_InCB_Consonant), ('\\u{9e2}', '\\u{9e3}',\n        GC_Extend), ('\\u{9f0}', '\\u{9f1}', GC_InCB_Consonant), ('\\u{9fe}', '\\u{9fe}', GC_Extend),\n        ('\\u{a01}', '\\u{a02}', GC_Extend), ('\\u{a03}', '\\u{a03}', GC_SpacingMark), ('\\u{a3c}',\n        '\\u{a3c}', GC_Extend), ('\\u{a3e}', '\\u{a40}', GC_SpacingMark), ('\\u{a41}', '\\u{a42}',\n        GC_Extend), ('\\u{a47}', '\\u{a48}', GC_Extend), ('\\u{a4b}', '\\u{a4d}', GC_Extend),\n        ('\\u{a51}', '\\u{a51}', GC_Extend), ('\\u{a70}', '\\u{a71}', GC_Extend), ('\\u{a75}', '\\u{a75}',\n        GC_Extend), ('\\u{a81}', '\\u{a82}', GC_Extend), ('\\u{a83}', '\\u{a83}', GC_SpacingMark),\n        ('\\u{a95}', '\\u{aa8}', GC_InCB_Consonant), ('\\u{aaa}', '\\u{ab0}', GC_InCB_Consonant),\n        ('\\u{ab2}', '\\u{ab3}', GC_InCB_Consonant), ('\\u{ab5}', '\\u{ab9}', GC_InCB_Consonant),\n        ('\\u{abc}', '\\u{abc}', GC_Extend), ('\\u{abe}', '\\u{ac0}', GC_SpacingMark), ('\\u{ac1}',\n        '\\u{ac5}', GC_Extend), ('\\u{ac7}', '\\u{ac8}', GC_Extend), ('\\u{ac9}', '\\u{ac9}',\n        GC_SpacingMark), ('\\u{acb}', '\\u{acc}', GC_SpacingMark), ('\\u{acd}', '\\u{acd}', GC_Extend),\n        ('\\u{ae2}', '\\u{ae3}', GC_Extend), ('\\u{af9}', '\\u{af9}', GC_InCB_Consonant), ('\\u{afa}',\n        '\\u{aff}', GC_Extend), ('\\u{b01}', '\\u{b01}', GC_Extend), ('\\u{b02}', '\\u{b03}',\n        GC_SpacingMark), ('\\u{b15}', '\\u{b28}', GC_InCB_Consonant), ('\\u{b2a}', '\\u{b30}',\n        GC_InCB_Consonant), ('\\u{b32}', '\\u{b33}', GC_InCB_Consonant), ('\\u{b35}', '\\u{b39}',\n        GC_InCB_Consonant), ('\\u{b3c}', '\\u{b3c}', GC_Extend), ('\\u{b3e}', '\\u{b3f}', GC_Extend),\n        ('\\u{b40}', '\\u{b40}', GC_SpacingMark), ('\\u{b41}', '\\u{b44}', GC_Extend), ('\\u{b47}',\n        '\\u{b48}', GC_SpacingMark), ('\\u{b4b}', '\\u{b4c}', GC_SpacingMark), ('\\u{b4d}', '\\u{b4d}',\n        GC_Extend), ('\\u{b55}', '\\u{b57}', GC_Extend), ('\\u{b5c}', '\\u{b5d}', GC_InCB_Consonant),\n        ('\\u{b5f}', '\\u{b5f}', GC_InCB_Consonant), ('\\u{b62}', '\\u{b63}', GC_Extend), ('\\u{b71}',\n        '\\u{b71}', GC_InCB_Consonant), ('\\u{b82}', '\\u{b82}', GC_Extend), ('\\u{bbe}', '\\u{bbe}',\n        GC_Extend), ('\\u{bbf}', '\\u{bbf}', GC_SpacingMark), ('\\u{bc0}', '\\u{bc0}', GC_Extend),\n        ('\\u{bc1}', '\\u{bc2}', GC_SpacingMark), ('\\u{bc6}', '\\u{bc8}', GC_SpacingMark), ('\\u{bca}',\n        '\\u{bcc}', GC_SpacingMark), ('\\u{bcd}', '\\u{bcd}', GC_Extend), ('\\u{bd7}', '\\u{bd7}',\n        GC_Extend), ('\\u{c00}', '\\u{c00}', GC_Extend), ('\\u{c01}', '\\u{c03}', GC_SpacingMark),\n        ('\\u{c04}', '\\u{c04}', GC_Extend), ('\\u{c15}', '\\u{c28}', GC_InCB_Consonant), ('\\u{c2a}',\n        '\\u{c39}', GC_InCB_Consonant), ('\\u{c3c}', '\\u{c3c}', GC_Extend), ('\\u{c3e}', '\\u{c40}',\n        GC_Extend), ('\\u{c41}', '\\u{c44}', GC_SpacingMark), ('\\u{c46}', '\\u{c48}', GC_Extend),\n        ('\\u{c4a}', '\\u{c4d}', GC_Extend), ('\\u{c55}', '\\u{c56}', GC_Extend), ('\\u{c58}', '\\u{c5a}',\n        GC_InCB_Consonant), ('\\u{c62}', '\\u{c63}', GC_Extend), ('\\u{c81}', '\\u{c81}', GC_Extend),\n        ('\\u{c82}', '\\u{c83}', GC_SpacingMark), ('\\u{cbc}', '\\u{cbc}', GC_Extend), ('\\u{cbe}',\n        '\\u{cbe}', GC_SpacingMark), ('\\u{cbf}', '\\u{cc0}', GC_Extend), ('\\u{cc1}', '\\u{cc1}',\n        GC_SpacingMark), ('\\u{cc2}', '\\u{cc2}', GC_Extend), ('\\u{cc3}', '\\u{cc4}', GC_SpacingMark),\n        ('\\u{cc6}', '\\u{cc8}', GC_Extend), ('\\u{cca}', '\\u{ccd}', GC_Extend), ('\\u{cd5}', '\\u{cd6}',\n        GC_Extend), ('\\u{ce2}', '\\u{ce3}', GC_Extend), ('\\u{cf3}', '\\u{cf3}', GC_SpacingMark),\n        ('\\u{d00}', '\\u{d01}', GC_Extend), ('\\u{d02}', '\\u{d03}', GC_SpacingMark), ('\\u{d15}',\n        '\\u{d3a}', GC_InCB_Consonant), ('\\u{d3b}', '\\u{d3c}', GC_Extend), ('\\u{d3e}', '\\u{d3e}',\n        GC_Extend), ('\\u{d3f}', '\\u{d40}', GC_SpacingMark), ('\\u{d41}', '\\u{d44}', GC_Extend),\n        ('\\u{d46}', '\\u{d48}', GC_SpacingMark), ('\\u{d4a}', '\\u{d4c}', GC_SpacingMark), ('\\u{d4d}',\n        '\\u{d4d}', GC_Extend), ('\\u{d4e}', '\\u{d4e}', GC_Prepend), ('\\u{d57}', '\\u{d57}',\n        GC_Extend), ('\\u{d62}', '\\u{d63}', GC_Extend), ('\\u{d81}', '\\u{d81}', GC_Extend),\n        ('\\u{d82}', '\\u{d83}', GC_SpacingMark), ('\\u{dca}', '\\u{dca}', GC_Extend), ('\\u{dcf}',\n        '\\u{dcf}', GC_Extend), ('\\u{dd0}', '\\u{dd1}', GC_SpacingMark), ('\\u{dd2}', '\\u{dd4}',\n        GC_Extend), ('\\u{dd6}', '\\u{dd6}', GC_Extend), ('\\u{dd8}', '\\u{dde}', GC_SpacingMark),\n        ('\\u{ddf}', '\\u{ddf}', GC_Extend), ('\\u{df2}', '\\u{df3}', GC_SpacingMark), ('\\u{e31}',\n        '\\u{e31}', GC_Extend), ('\\u{e33}', '\\u{e33}', GC_SpacingMark), ('\\u{e34}', '\\u{e3a}',\n        GC_Extend), ('\\u{e47}', '\\u{e4e}', GC_Extend), ('\\u{eb1}', '\\u{eb1}', GC_Extend),\n        ('\\u{eb3}', '\\u{eb3}', GC_SpacingMark), ('\\u{eb4}', '\\u{ebc}', GC_Extend), ('\\u{ec8}',\n        '\\u{ece}', GC_Extend), ('\\u{f18}', '\\u{f19}', GC_Extend), ('\\u{f35}', '\\u{f35}', GC_Extend),\n        ('\\u{f37}', '\\u{f37}', GC_Extend), ('\\u{f39}', '\\u{f39}', GC_Extend), ('\\u{f3e}', '\\u{f3f}',\n        GC_SpacingMark), ('\\u{f71}', '\\u{f7e}', GC_Extend), ('\\u{f7f}', '\\u{f7f}', GC_SpacingMark),\n        ('\\u{f80}', '\\u{f84}', GC_Extend), ('\\u{f86}', '\\u{f87}', GC_Extend), ('\\u{f8d}', '\\u{f97}',\n        GC_Extend), ('\\u{f99}', '\\u{fbc}', GC_Extend), ('\\u{fc6}', '\\u{fc6}', GC_Extend),\n        ('\\u{1000}', '\\u{102a}', GC_InCB_Consonant), ('\\u{102d}', '\\u{1030}', GC_Extend),\n        ('\\u{1031}', '\\u{1031}', GC_SpacingMark), ('\\u{1032}', '\\u{1037}', GC_Extend), ('\\u{1039}',\n        '\\u{103a}', GC_Extend), ('\\u{103b}', '\\u{103c}', GC_SpacingMark), ('\\u{103d}', '\\u{103e}',\n        GC_Extend), ('\\u{103f}', '\\u{103f}', GC_InCB_Consonant), ('\\u{1050}', '\\u{1055}',\n        GC_InCB_Consonant), ('\\u{1056}', '\\u{1057}', GC_SpacingMark), ('\\u{1058}', '\\u{1059}',\n        GC_Extend), ('\\u{105a}', '\\u{105d}', GC_InCB_Consonant), ('\\u{105e}', '\\u{1060}',\n        GC_Extend), ('\\u{1061}', '\\u{1061}', GC_InCB_Consonant), ('\\u{1065}', '\\u{1066}',\n        GC_InCB_Consonant), ('\\u{106e}', '\\u{1070}', GC_InCB_Consonant), ('\\u{1071}', '\\u{1074}',\n        GC_Extend), ('\\u{1075}', '\\u{1081}', GC_InCB_Consonant), ('\\u{1082}', '\\u{1082}',\n        GC_Extend), ('\\u{1084}', '\\u{1084}', GC_SpacingMark), ('\\u{1085}', '\\u{1086}', GC_Extend),\n        ('\\u{108d}', '\\u{108d}', GC_Extend), ('\\u{108e}', '\\u{108e}', GC_InCB_Consonant),\n        ('\\u{109d}', '\\u{109d}', GC_Extend), ('\\u{1100}', '\\u{115f}', GC_L), ('\\u{1160}',\n        '\\u{11a7}', GC_V), ('\\u{11a8}', '\\u{11ff}', GC_T), ('\\u{135d}', '\\u{135f}', GC_Extend),\n        ('\\u{1712}', '\\u{1715}', GC_Extend), ('\\u{1732}', '\\u{1734}', GC_Extend), ('\\u{1752}',\n        '\\u{1753}', GC_Extend), ('\\u{1772}', '\\u{1773}', GC_Extend), ('\\u{1780}', '\\u{17b3}',\n        GC_InCB_Consonant), ('\\u{17b4}', '\\u{17b5}', GC_Extend), ('\\u{17b6}', '\\u{17b6}',\n        GC_SpacingMark), ('\\u{17b7}', '\\u{17bd}', GC_Extend), ('\\u{17be}', '\\u{17c5}',\n        GC_SpacingMark), ('\\u{17c6}', '\\u{17c6}', GC_Extend), ('\\u{17c7}', '\\u{17c8}',\n        GC_SpacingMark), ('\\u{17c9}', '\\u{17d3}', GC_Extend), ('\\u{17dd}', '\\u{17dd}', GC_Extend),\n        ('\\u{180b}', '\\u{180d}', GC_Extend), ('\\u{180e}', '\\u{180e}', GC_Control), ('\\u{180f}',\n        '\\u{180f}', GC_Extend), ('\\u{1885}', '\\u{1886}', GC_Extend), ('\\u{18a9}', '\\u{18a9}',\n        GC_Extend), ('\\u{1920}', '\\u{1922}', GC_Extend), ('\\u{1923}', '\\u{1926}', GC_SpacingMark),\n        ('\\u{1927}', '\\u{1928}', GC_Extend), ('\\u{1929}', '\\u{192b}', GC_SpacingMark), ('\\u{1930}',\n        '\\u{1931}', GC_SpacingMark), ('\\u{1932}', '\\u{1932}', GC_Extend), ('\\u{1933}', '\\u{1938}',\n        GC_SpacingMark), ('\\u{1939}', '\\u{193b}', GC_Extend), ('\\u{1a17}', '\\u{1a18}', GC_Extend),\n        ('\\u{1a19}', '\\u{1a1a}', GC_SpacingMark), ('\\u{1a1b}', '\\u{1a1b}', GC_Extend), ('\\u{1a20}',\n        '\\u{1a54}', GC_InCB_Consonant), ('\\u{1a55}', '\\u{1a55}', GC_SpacingMark), ('\\u{1a56}',\n        '\\u{1a56}', GC_Extend), ('\\u{1a57}', '\\u{1a57}', GC_SpacingMark), ('\\u{1a58}', '\\u{1a5e}',\n        GC_Extend), ('\\u{1a60}', '\\u{1a60}', GC_Extend), ('\\u{1a62}', '\\u{1a62}', GC_Extend),\n        ('\\u{1a65}', '\\u{1a6c}', GC_Extend), ('\\u{1a6d}', '\\u{1a72}', GC_SpacingMark), ('\\u{1a73}',\n        '\\u{1a7c}', GC_Extend), ('\\u{1a7f}', '\\u{1a7f}', GC_Extend), ('\\u{1ab0}', '\\u{1add}',\n        GC_Extend), ('\\u{1ae0}', '\\u{1aeb}', GC_Extend), ('\\u{1b00}', '\\u{1b03}', GC_Extend),\n        ('\\u{1b04}', '\\u{1b04}', GC_SpacingMark), ('\\u{1b0b}', '\\u{1b0c}', GC_InCB_Consonant),\n        ('\\u{1b13}', '\\u{1b33}', GC_InCB_Consonant), ('\\u{1b34}', '\\u{1b3d}', GC_Extend),\n        ('\\u{1b3e}', '\\u{1b41}', GC_SpacingMark), ('\\u{1b42}', '\\u{1b44}', GC_Extend), ('\\u{1b45}',\n        '\\u{1b4c}', GC_InCB_Consonant), ('\\u{1b6b}', '\\u{1b73}', GC_Extend), ('\\u{1b80}',\n        '\\u{1b81}', GC_Extend), ('\\u{1b82}', '\\u{1b82}', GC_SpacingMark), ('\\u{1b83}', '\\u{1ba0}',\n        GC_InCB_Consonant), ('\\u{1ba1}', '\\u{1ba1}', GC_SpacingMark), ('\\u{1ba2}', '\\u{1ba5}',\n        GC_Extend), ('\\u{1ba6}', '\\u{1ba7}', GC_SpacingMark), ('\\u{1ba8}', '\\u{1bad}', GC_Extend),\n        ('\\u{1bae}', '\\u{1baf}', GC_InCB_Consonant), ('\\u{1bbb}', '\\u{1bbd}', GC_InCB_Consonant),\n        ('\\u{1be6}', '\\u{1be6}', GC_Extend), ('\\u{1be7}', '\\u{1be7}', GC_SpacingMark), ('\\u{1be8}',\n        '\\u{1be9}', GC_Extend), ('\\u{1bea}', '\\u{1bec}', GC_SpacingMark), ('\\u{1bed}', '\\u{1bed}',\n        GC_Extend), ('\\u{1bee}', '\\u{1bee}', GC_SpacingMark), ('\\u{1bef}', '\\u{1bf3}', GC_Extend),\n        ('\\u{1c24}', '\\u{1c2b}', GC_SpacingMark), ('\\u{1c2c}', '\\u{1c33}', GC_Extend), ('\\u{1c34}',\n        '\\u{1c35}', GC_SpacingMark), ('\\u{1c36}', '\\u{1c37}', GC_Extend), ('\\u{1cd0}', '\\u{1cd2}',\n        GC_Extend), ('\\u{1cd4}', '\\u{1ce0}', GC_Extend), ('\\u{1ce1}', '\\u{1ce1}', GC_SpacingMark),\n        ('\\u{1ce2}', '\\u{1ce8}', GC_Extend), ('\\u{1ced}', '\\u{1ced}', GC_Extend), ('\\u{1cf4}',\n        '\\u{1cf4}', GC_Extend), ('\\u{1cf7}', '\\u{1cf7}', GC_SpacingMark), ('\\u{1cf8}', '\\u{1cf9}',\n        GC_Extend), ('\\u{1dc0}', '\\u{1dff}', GC_Extend), ('\\u{200b}', '\\u{200b}', GC_Control),\n        ('\\u{200c}', '\\u{200c}', GC_Extend), ('\\u{200d}', '\\u{200d}', GC_ZWJ), ('\\u{200e}',\n        '\\u{200f}', GC_Control), ('\\u{2028}', '\\u{202e}', GC_Control), ('\\u{203c}', '\\u{203c}',\n        GC_Extended_Pictographic), ('\\u{2049}', '\\u{2049}', GC_Extended_Pictographic), ('\\u{2060}',\n        '\\u{206f}', GC_Control), ('\\u{20d0}', '\\u{20f0}', GC_Extend), ('\\u{2122}', '\\u{2122}',\n        GC_Extended_Pictographic), ('\\u{2139}', '\\u{2139}', GC_Extended_Pictographic), ('\\u{2194}',\n        '\\u{2199}', GC_Extended_Pictographic), ('\\u{21a9}', '\\u{21aa}', GC_Extended_Pictographic),\n        ('\\u{231a}', '\\u{231b}', GC_Extended_Pictographic), ('\\u{2328}', '\\u{2328}',\n        GC_Extended_Pictographic), ('\\u{23cf}', '\\u{23cf}', GC_Extended_Pictographic), ('\\u{23e9}',\n        '\\u{23f3}', GC_Extended_Pictographic), ('\\u{23f8}', '\\u{23fa}', GC_Extended_Pictographic),\n        ('\\u{24c2}', '\\u{24c2}', GC_Extended_Pictographic), ('\\u{25aa}', '\\u{25ab}',\n        GC_Extended_Pictographic), ('\\u{25b6}', '\\u{25b6}', GC_Extended_Pictographic), ('\\u{25c0}',\n        '\\u{25c0}', GC_Extended_Pictographic), ('\\u{25fb}', '\\u{25fe}', GC_Extended_Pictographic),\n        ('\\u{2600}', '\\u{2604}', GC_Extended_Pictographic), ('\\u{260e}', '\\u{260e}',\n        GC_Extended_Pictographic), ('\\u{2611}', '\\u{2611}', GC_Extended_Pictographic), ('\\u{2614}',\n        '\\u{2615}', GC_Extended_Pictographic), ('\\u{2618}', '\\u{2618}', GC_Extended_Pictographic),\n        ('\\u{261d}', '\\u{261d}', GC_Extended_Pictographic), ('\\u{2620}', '\\u{2620}',\n        GC_Extended_Pictographic), ('\\u{2622}', '\\u{2623}', GC_Extended_Pictographic), ('\\u{2626}',\n        '\\u{2626}', GC_Extended_Pictographic), ('\\u{262a}', '\\u{262a}', GC_Extended_Pictographic),\n        ('\\u{262e}', '\\u{262f}', GC_Extended_Pictographic), ('\\u{2638}', '\\u{263a}',\n        GC_Extended_Pictographic), ('\\u{2640}', '\\u{2640}', GC_Extended_Pictographic), ('\\u{2642}',\n        '\\u{2642}', GC_Extended_Pictographic), ('\\u{2648}', '\\u{2653}', GC_Extended_Pictographic),\n        ('\\u{265f}', '\\u{2660}', GC_Extended_Pictographic), ('\\u{2663}', '\\u{2663}',\n        GC_Extended_Pictographic), ('\\u{2665}', '\\u{2666}', GC_Extended_Pictographic), ('\\u{2668}',\n        '\\u{2668}', GC_Extended_Pictographic), ('\\u{267b}', '\\u{267b}', GC_Extended_Pictographic),\n        ('\\u{267e}', '\\u{267f}', GC_Extended_Pictographic), ('\\u{2692}', '\\u{2697}',\n        GC_Extended_Pictographic), ('\\u{2699}', '\\u{2699}', GC_Extended_Pictographic), ('\\u{269b}',\n        '\\u{269c}', GC_Extended_Pictographic), ('\\u{26a0}', '\\u{26a1}', GC_Extended_Pictographic),\n        ('\\u{26a7}', '\\u{26a7}', GC_Extended_Pictographic), ('\\u{26aa}', '\\u{26ab}',\n        GC_Extended_Pictographic), ('\\u{26b0}', '\\u{26b1}', GC_Extended_Pictographic), ('\\u{26bd}',\n        '\\u{26be}', GC_Extended_Pictographic), ('\\u{26c4}', '\\u{26c5}', GC_Extended_Pictographic),\n        ('\\u{26c8}', '\\u{26c8}', GC_Extended_Pictographic), ('\\u{26ce}', '\\u{26cf}',\n        GC_Extended_Pictographic), ('\\u{26d1}', '\\u{26d1}', GC_Extended_Pictographic), ('\\u{26d3}',\n        '\\u{26d4}', GC_Extended_Pictographic), ('\\u{26e9}', '\\u{26ea}', GC_Extended_Pictographic),\n        ('\\u{26f0}', '\\u{26f5}', GC_Extended_Pictographic), ('\\u{26f7}', '\\u{26fa}',\n        GC_Extended_Pictographic), ('\\u{26fd}', '\\u{26fd}', GC_Extended_Pictographic), ('\\u{2702}',\n        '\\u{2702}', GC_Extended_Pictographic), ('\\u{2705}', '\\u{2705}', GC_Extended_Pictographic),\n        ('\\u{2708}', '\\u{270d}', GC_Extended_Pictographic), ('\\u{270f}', '\\u{270f}',\n        GC_Extended_Pictographic), ('\\u{2712}', '\\u{2712}', GC_Extended_Pictographic), ('\\u{2714}',\n        '\\u{2714}', GC_Extended_Pictographic), ('\\u{2716}', '\\u{2716}', GC_Extended_Pictographic),\n        ('\\u{271d}', '\\u{271d}', GC_Extended_Pictographic), ('\\u{2721}', '\\u{2721}',\n        GC_Extended_Pictographic), ('\\u{2728}', '\\u{2728}', GC_Extended_Pictographic), ('\\u{2733}',\n        '\\u{2734}', GC_Extended_Pictographic), ('\\u{2744}', '\\u{2744}', GC_Extended_Pictographic),\n        ('\\u{2747}', '\\u{2747}', GC_Extended_Pictographic), ('\\u{274c}', '\\u{274c}',\n        GC_Extended_Pictographic), ('\\u{274e}', '\\u{274e}', GC_Extended_Pictographic), ('\\u{2753}',\n        '\\u{2755}', GC_Extended_Pictographic), ('\\u{2757}', '\\u{2757}', GC_Extended_Pictographic),\n        ('\\u{2763}', '\\u{2764}', GC_Extended_Pictographic), ('\\u{2795}', '\\u{2797}',\n        GC_Extended_Pictographic), ('\\u{27a1}', '\\u{27a1}', GC_Extended_Pictographic), ('\\u{27b0}',\n        '\\u{27b0}', GC_Extended_Pictographic), ('\\u{27bf}', '\\u{27bf}', GC_Extended_Pictographic),\n        ('\\u{2934}', '\\u{2935}', GC_Extended_Pictographic), ('\\u{2b05}', '\\u{2b07}',\n        GC_Extended_Pictographic), ('\\u{2b1b}', '\\u{2b1c}', GC_Extended_Pictographic), ('\\u{2b50}',\n        '\\u{2b50}', GC_Extended_Pictographic), ('\\u{2b55}', '\\u{2b55}', GC_Extended_Pictographic),\n        ('\\u{2cef}', '\\u{2cf1}', GC_Extend), ('\\u{2d7f}', '\\u{2d7f}', GC_Extend), ('\\u{2de0}',\n        '\\u{2dff}', GC_Extend), ('\\u{302a}', '\\u{302f}', GC_Extend), ('\\u{3030}', '\\u{3030}',\n        GC_Extended_Pictographic), ('\\u{303d}', '\\u{303d}', GC_Extended_Pictographic), ('\\u{3099}',\n        '\\u{309a}', GC_Extend), ('\\u{3297}', '\\u{3297}', GC_Extended_Pictographic), ('\\u{3299}',\n        '\\u{3299}', GC_Extended_Pictographic), ('\\u{a66f}', '\\u{a672}', GC_Extend), ('\\u{a674}',\n        '\\u{a67d}', GC_Extend), ('\\u{a69e}', '\\u{a69f}', GC_Extend), ('\\u{a6f0}', '\\u{a6f1}',\n        GC_Extend), ('\\u{a802}', '\\u{a802}', GC_Extend), ('\\u{a806}', '\\u{a806}', GC_Extend),\n        ('\\u{a80b}', '\\u{a80b}', GC_Extend), ('\\u{a823}', '\\u{a824}', GC_SpacingMark), ('\\u{a825}',\n        '\\u{a826}', GC_Extend), ('\\u{a827}', '\\u{a827}', GC_SpacingMark), ('\\u{a82c}', '\\u{a82c}',\n        GC_Extend), ('\\u{a880}', '\\u{a881}', GC_SpacingMark), ('\\u{a8b4}', '\\u{a8c3}',\n        GC_SpacingMark), ('\\u{a8c4}', '\\u{a8c5}', GC_Extend), ('\\u{a8e0}', '\\u{a8f1}', GC_Extend),\n        ('\\u{a8ff}', '\\u{a8ff}', GC_Extend), ('\\u{a926}', '\\u{a92d}', GC_Extend), ('\\u{a947}',\n        '\\u{a951}', GC_Extend), ('\\u{a952}', '\\u{a952}', GC_SpacingMark), ('\\u{a953}', '\\u{a953}',\n        GC_Extend), ('\\u{a960}', '\\u{a97c}', GC_L), ('\\u{a980}', '\\u{a982}', GC_Extend),\n        ('\\u{a983}', '\\u{a983}', GC_SpacingMark), ('\\u{a989}', '\\u{a98b}', GC_InCB_Consonant),\n        ('\\u{a98f}', '\\u{a9b2}', GC_InCB_Consonant), ('\\u{a9b3}', '\\u{a9b3}', GC_Extend),\n        ('\\u{a9b4}', '\\u{a9b5}', GC_SpacingMark), ('\\u{a9b6}', '\\u{a9b9}', GC_Extend), ('\\u{a9ba}',\n        '\\u{a9bb}', GC_SpacingMark), ('\\u{a9bc}', '\\u{a9bd}', GC_Extend), ('\\u{a9be}', '\\u{a9bf}',\n        GC_SpacingMark), ('\\u{a9c0}', '\\u{a9c0}', GC_Extend), ('\\u{a9e0}', '\\u{a9e4}',\n        GC_InCB_Consonant), ('\\u{a9e5}', '\\u{a9e5}', GC_Extend), ('\\u{a9e7}', '\\u{a9ef}',\n        GC_InCB_Consonant), ('\\u{a9fa}', '\\u{a9fe}', GC_InCB_Consonant), ('\\u{aa29}', '\\u{aa2e}',\n        GC_Extend), ('\\u{aa2f}', '\\u{aa30}', GC_SpacingMark), ('\\u{aa31}', '\\u{aa32}', GC_Extend),\n        ('\\u{aa33}', '\\u{aa34}', GC_SpacingMark), ('\\u{aa35}', '\\u{aa36}', GC_Extend), ('\\u{aa43}',\n        '\\u{aa43}', GC_Extend), ('\\u{aa4c}', '\\u{aa4c}', GC_Extend), ('\\u{aa4d}', '\\u{aa4d}',\n        GC_SpacingMark), ('\\u{aa60}', '\\u{aa6f}', GC_InCB_Consonant), ('\\u{aa71}', '\\u{aa73}',\n        GC_InCB_Consonant), ('\\u{aa7a}', '\\u{aa7a}', GC_InCB_Consonant), ('\\u{aa7c}', '\\u{aa7c}',\n        GC_Extend), ('\\u{aa7e}', '\\u{aa7f}', GC_InCB_Consonant), ('\\u{aab0}', '\\u{aab0}',\n        GC_Extend), ('\\u{aab2}', '\\u{aab4}', GC_Extend), ('\\u{aab7}', '\\u{aab8}', GC_Extend),\n        ('\\u{aabe}', '\\u{aabf}', GC_Extend), ('\\u{aac1}', '\\u{aac1}', GC_Extend), ('\\u{aae0}',\n        '\\u{aaea}', GC_InCB_Consonant), ('\\u{aaeb}', '\\u{aaeb}', GC_SpacingMark), ('\\u{aaec}',\n        '\\u{aaed}', GC_Extend), ('\\u{aaee}', '\\u{aaef}', GC_SpacingMark), ('\\u{aaf5}', '\\u{aaf5}',\n        GC_SpacingMark), ('\\u{aaf6}', '\\u{aaf6}', GC_Extend), ('\\u{abc0}', '\\u{abda}',\n        GC_InCB_Consonant), ('\\u{abe3}', '\\u{abe4}', GC_SpacingMark), ('\\u{abe5}', '\\u{abe5}',\n        GC_Extend), ('\\u{abe6}', '\\u{abe7}', GC_SpacingMark), ('\\u{abe8}', '\\u{abe8}', GC_Extend),\n        ('\\u{abe9}', '\\u{abea}', GC_SpacingMark), ('\\u{abec}', '\\u{abec}', GC_SpacingMark),\n        ('\\u{abed}', '\\u{abed}', GC_Extend), ('\\u{ac00}', '\\u{ac00}', GC_LV), ('\\u{ac01}',\n        '\\u{ac1b}', GC_LVT), ('\\u{ac1c}', '\\u{ac1c}', GC_LV), ('\\u{ac1d}', '\\u{ac37}', GC_LVT),\n        ('\\u{ac38}', '\\u{ac38}', GC_LV), ('\\u{ac39}', '\\u{ac53}', GC_LVT), ('\\u{ac54}', '\\u{ac54}',\n        GC_LV), ('\\u{ac55}', '\\u{ac6f}', GC_LVT), ('\\u{ac70}', '\\u{ac70}', GC_LV), ('\\u{ac71}',\n        '\\u{ac8b}', GC_LVT), ('\\u{ac8c}', '\\u{ac8c}', GC_LV), ('\\u{ac8d}', '\\u{aca7}', GC_LVT),\n        ('\\u{aca8}', '\\u{aca8}', GC_LV), ('\\u{aca9}', '\\u{acc3}', GC_LVT), ('\\u{acc4}', '\\u{acc4}',\n        GC_LV), ('\\u{acc5}', '\\u{acdf}', GC_LVT), ('\\u{ace0}', '\\u{ace0}', GC_LV), ('\\u{ace1}',\n        '\\u{acfb}', GC_LVT), ('\\u{acfc}', '\\u{acfc}', GC_LV), ('\\u{acfd}', '\\u{ad17}', GC_LVT),\n        ('\\u{ad18}', '\\u{ad18}', GC_LV), ('\\u{ad19}', '\\u{ad33}', GC_LVT), ('\\u{ad34}', '\\u{ad34}',\n        GC_LV), ('\\u{ad35}', '\\u{ad4f}', GC_LVT), ('\\u{ad50}', '\\u{ad50}', GC_LV), ('\\u{ad51}',\n        '\\u{ad6b}', GC_LVT), ('\\u{ad6c}', '\\u{ad6c}', GC_LV), ('\\u{ad6d}', '\\u{ad87}', GC_LVT),\n        ('\\u{ad88}', '\\u{ad88}', GC_LV), ('\\u{ad89}', '\\u{ada3}', GC_LVT), ('\\u{ada4}', '\\u{ada4}',\n        GC_LV), ('\\u{ada5}', '\\u{adbf}', GC_LVT), ('\\u{adc0}', '\\u{adc0}', GC_LV), ('\\u{adc1}',\n        '\\u{addb}', GC_LVT), ('\\u{addc}', '\\u{addc}', GC_LV), ('\\u{addd}', '\\u{adf7}', GC_LVT),\n        ('\\u{adf8}', '\\u{adf8}', GC_LV), ('\\u{adf9}', '\\u{ae13}', GC_LVT), ('\\u{ae14}', '\\u{ae14}',\n        GC_LV), ('\\u{ae15}', '\\u{ae2f}', GC_LVT), ('\\u{ae30}', '\\u{ae30}', GC_LV), ('\\u{ae31}',\n        '\\u{ae4b}', GC_LVT), ('\\u{ae4c}', '\\u{ae4c}', GC_LV), ('\\u{ae4d}', '\\u{ae67}', GC_LVT),\n        ('\\u{ae68}', '\\u{ae68}', GC_LV), ('\\u{ae69}', '\\u{ae83}', GC_LVT), ('\\u{ae84}', '\\u{ae84}',\n        GC_LV), ('\\u{ae85}', '\\u{ae9f}', GC_LVT), ('\\u{aea0}', '\\u{aea0}', GC_LV), ('\\u{aea1}',\n        '\\u{aebb}', GC_LVT), ('\\u{aebc}', '\\u{aebc}', GC_LV), ('\\u{aebd}', '\\u{aed7}', GC_LVT),\n        ('\\u{aed8}', '\\u{aed8}', GC_LV), ('\\u{aed9}', '\\u{aef3}', GC_LVT), ('\\u{aef4}', '\\u{aef4}',\n        GC_LV), ('\\u{aef5}', '\\u{af0f}', GC_LVT), ('\\u{af10}', '\\u{af10}', GC_LV), ('\\u{af11}',\n        '\\u{af2b}', GC_LVT), ('\\u{af2c}', '\\u{af2c}', GC_LV), ('\\u{af2d}', '\\u{af47}', GC_LVT),\n        ('\\u{af48}', '\\u{af48}', GC_LV), ('\\u{af49}', '\\u{af63}', GC_LVT), ('\\u{af64}', '\\u{af64}',\n        GC_LV), ('\\u{af65}', '\\u{af7f}', GC_LVT), ('\\u{af80}', '\\u{af80}', GC_LV), ('\\u{af81}',\n        '\\u{af9b}', GC_LVT), ('\\u{af9c}', '\\u{af9c}', GC_LV), ('\\u{af9d}', '\\u{afb7}', GC_LVT),\n        ('\\u{afb8}', '\\u{afb8}', GC_LV), ('\\u{afb9}', '\\u{afd3}', GC_LVT), ('\\u{afd4}', '\\u{afd4}',\n        GC_LV), ('\\u{afd5}', '\\u{afef}', GC_LVT), ('\\u{aff0}', '\\u{aff0}', GC_LV), ('\\u{aff1}',\n        '\\u{b00b}', GC_LVT), ('\\u{b00c}', '\\u{b00c}', GC_LV), ('\\u{b00d}', '\\u{b027}', GC_LVT),\n        ('\\u{b028}', '\\u{b028}', GC_LV), ('\\u{b029}', '\\u{b043}', GC_LVT), ('\\u{b044}', '\\u{b044}',\n        GC_LV), ('\\u{b045}', '\\u{b05f}', GC_LVT), ('\\u{b060}', '\\u{b060}', GC_LV), ('\\u{b061}',\n        '\\u{b07b}', GC_LVT), ('\\u{b07c}', '\\u{b07c}', GC_LV), ('\\u{b07d}', '\\u{b097}', GC_LVT),\n        ('\\u{b098}', '\\u{b098}', GC_LV), ('\\u{b099}', '\\u{b0b3}', GC_LVT), ('\\u{b0b4}', '\\u{b0b4}',\n        GC_LV), ('\\u{b0b5}', '\\u{b0cf}', GC_LVT), ('\\u{b0d0}', '\\u{b0d0}', GC_LV), ('\\u{b0d1}',\n        '\\u{b0eb}', GC_LVT), ('\\u{b0ec}', '\\u{b0ec}', GC_LV), ('\\u{b0ed}', '\\u{b107}', GC_LVT),\n        ('\\u{b108}', '\\u{b108}', GC_LV), ('\\u{b109}', '\\u{b123}', GC_LVT), ('\\u{b124}', '\\u{b124}',\n        GC_LV), ('\\u{b125}', '\\u{b13f}', GC_LVT), ('\\u{b140}', '\\u{b140}', GC_LV), ('\\u{b141}',\n        '\\u{b15b}', GC_LVT), ('\\u{b15c}', '\\u{b15c}', GC_LV), ('\\u{b15d}', '\\u{b177}', GC_LVT),\n        ('\\u{b178}', '\\u{b178}', GC_LV), ('\\u{b179}', '\\u{b193}', GC_LVT), ('\\u{b194}', '\\u{b194}',\n        GC_LV), ('\\u{b195}', '\\u{b1af}', GC_LVT), ('\\u{b1b0}', '\\u{b1b0}', GC_LV), ('\\u{b1b1}',\n        '\\u{b1cb}', GC_LVT), ('\\u{b1cc}', '\\u{b1cc}', GC_LV), ('\\u{b1cd}', '\\u{b1e7}', GC_LVT),\n        ('\\u{b1e8}', '\\u{b1e8}', GC_LV), ('\\u{b1e9}', '\\u{b203}', GC_LVT), ('\\u{b204}', '\\u{b204}',\n        GC_LV), ('\\u{b205}', '\\u{b21f}', GC_LVT), ('\\u{b220}', '\\u{b220}', GC_LV), ('\\u{b221}',\n        '\\u{b23b}', GC_LVT), ('\\u{b23c}', '\\u{b23c}', GC_LV), ('\\u{b23d}', '\\u{b257}', GC_LVT),\n        ('\\u{b258}', '\\u{b258}', GC_LV), ('\\u{b259}', '\\u{b273}', GC_LVT), ('\\u{b274}', '\\u{b274}',\n        GC_LV), ('\\u{b275}', '\\u{b28f}', GC_LVT), ('\\u{b290}', '\\u{b290}', GC_LV), ('\\u{b291}',\n        '\\u{b2ab}', GC_LVT), ('\\u{b2ac}', '\\u{b2ac}', GC_LV), ('\\u{b2ad}', '\\u{b2c7}', GC_LVT),\n        ('\\u{b2c8}', '\\u{b2c8}', GC_LV), ('\\u{b2c9}', '\\u{b2e3}', GC_LVT), ('\\u{b2e4}', '\\u{b2e4}',\n        GC_LV), ('\\u{b2e5}', '\\u{b2ff}', GC_LVT), ('\\u{b300}', '\\u{b300}', GC_LV), ('\\u{b301}',\n        '\\u{b31b}', GC_LVT), ('\\u{b31c}', '\\u{b31c}', GC_LV), ('\\u{b31d}', '\\u{b337}', GC_LVT),\n        ('\\u{b338}', '\\u{b338}', GC_LV), ('\\u{b339}', '\\u{b353}', GC_LVT), ('\\u{b354}', '\\u{b354}',\n        GC_LV), ('\\u{b355}', '\\u{b36f}', GC_LVT), ('\\u{b370}', '\\u{b370}', GC_LV), ('\\u{b371}',\n        '\\u{b38b}', GC_LVT), ('\\u{b38c}', '\\u{b38c}', GC_LV), ('\\u{b38d}', '\\u{b3a7}', GC_LVT),\n        ('\\u{b3a8}', '\\u{b3a8}', GC_LV), ('\\u{b3a9}', '\\u{b3c3}', GC_LVT), ('\\u{b3c4}', '\\u{b3c4}',\n        GC_LV), ('\\u{b3c5}', '\\u{b3df}', GC_LVT), ('\\u{b3e0}', '\\u{b3e0}', GC_LV), ('\\u{b3e1}',\n        '\\u{b3fb}', GC_LVT), ('\\u{b3fc}', '\\u{b3fc}', GC_LV), ('\\u{b3fd}', '\\u{b417}', GC_LVT),\n        ('\\u{b418}', '\\u{b418}', GC_LV), ('\\u{b419}', '\\u{b433}', GC_LVT), ('\\u{b434}', '\\u{b434}',\n        GC_LV), ('\\u{b435}', '\\u{b44f}', GC_LVT), ('\\u{b450}', '\\u{b450}', GC_LV), ('\\u{b451}',\n        '\\u{b46b}', GC_LVT), ('\\u{b46c}', '\\u{b46c}', GC_LV), ('\\u{b46d}', '\\u{b487}', GC_LVT),\n        ('\\u{b488}', '\\u{b488}', GC_LV), ('\\u{b489}', '\\u{b4a3}', GC_LVT), ('\\u{b4a4}', '\\u{b4a4}',\n        GC_LV), ('\\u{b4a5}', '\\u{b4bf}', GC_LVT), ('\\u{b4c0}', '\\u{b4c0}', GC_LV), ('\\u{b4c1}',\n        '\\u{b4db}', GC_LVT), ('\\u{b4dc}', '\\u{b4dc}', GC_LV), ('\\u{b4dd}', '\\u{b4f7}', GC_LVT),\n        ('\\u{b4f8}', '\\u{b4f8}', GC_LV), ('\\u{b4f9}', '\\u{b513}', GC_LVT), ('\\u{b514}', '\\u{b514}',\n        GC_LV), ('\\u{b515}', '\\u{b52f}', GC_LVT), ('\\u{b530}', '\\u{b530}', GC_LV), ('\\u{b531}',\n        '\\u{b54b}', GC_LVT), ('\\u{b54c}', '\\u{b54c}', GC_LV), ('\\u{b54d}', '\\u{b567}', GC_LVT),\n        ('\\u{b568}', '\\u{b568}', GC_LV), ('\\u{b569}', '\\u{b583}', GC_LVT), ('\\u{b584}', '\\u{b584}',\n        GC_LV), ('\\u{b585}', '\\u{b59f}', GC_LVT), ('\\u{b5a0}', '\\u{b5a0}', GC_LV), ('\\u{b5a1}',\n        '\\u{b5bb}', GC_LVT), ('\\u{b5bc}', '\\u{b5bc}', GC_LV), ('\\u{b5bd}', '\\u{b5d7}', GC_LVT),\n        ('\\u{b5d8}', '\\u{b5d8}', GC_LV), ('\\u{b5d9}', '\\u{b5f3}', GC_LVT), ('\\u{b5f4}', '\\u{b5f4}',\n        GC_LV), ('\\u{b5f5}', '\\u{b60f}', GC_LVT), ('\\u{b610}', '\\u{b610}', GC_LV), ('\\u{b611}',\n        '\\u{b62b}', GC_LVT), ('\\u{b62c}', '\\u{b62c}', GC_LV), ('\\u{b62d}', '\\u{b647}', GC_LVT),\n        ('\\u{b648}', '\\u{b648}', GC_LV), ('\\u{b649}', '\\u{b663}', GC_LVT), ('\\u{b664}', '\\u{b664}',\n        GC_LV), ('\\u{b665}', '\\u{b67f}', GC_LVT), ('\\u{b680}', '\\u{b680}', GC_LV), ('\\u{b681}',\n        '\\u{b69b}', GC_LVT), ('\\u{b69c}', '\\u{b69c}', GC_LV), ('\\u{b69d}', '\\u{b6b7}', GC_LVT),\n        ('\\u{b6b8}', '\\u{b6b8}', GC_LV), ('\\u{b6b9}', '\\u{b6d3}', GC_LVT), ('\\u{b6d4}', '\\u{b6d4}',\n        GC_LV), ('\\u{b6d5}', '\\u{b6ef}', GC_LVT), ('\\u{b6f0}', '\\u{b6f0}', GC_LV), ('\\u{b6f1}',\n        '\\u{b70b}', GC_LVT), ('\\u{b70c}', '\\u{b70c}', GC_LV), ('\\u{b70d}', '\\u{b727}', GC_LVT),\n        ('\\u{b728}', '\\u{b728}', GC_LV), ('\\u{b729}', '\\u{b743}', GC_LVT), ('\\u{b744}', '\\u{b744}',\n        GC_LV), ('\\u{b745}', '\\u{b75f}', GC_LVT), ('\\u{b760}', '\\u{b760}', GC_LV), ('\\u{b761}',\n        '\\u{b77b}', GC_LVT), ('\\u{b77c}', '\\u{b77c}', GC_LV), ('\\u{b77d}', '\\u{b797}', GC_LVT),\n        ('\\u{b798}', '\\u{b798}', GC_LV), ('\\u{b799}', '\\u{b7b3}', GC_LVT), ('\\u{b7b4}', '\\u{b7b4}',\n        GC_LV), ('\\u{b7b5}', '\\u{b7cf}', GC_LVT), ('\\u{b7d0}', '\\u{b7d0}', GC_LV), ('\\u{b7d1}',\n        '\\u{b7eb}', GC_LVT), ('\\u{b7ec}', '\\u{b7ec}', GC_LV), ('\\u{b7ed}', '\\u{b807}', GC_LVT),\n        ('\\u{b808}', '\\u{b808}', GC_LV), ('\\u{b809}', '\\u{b823}', GC_LVT), ('\\u{b824}', '\\u{b824}',\n        GC_LV), ('\\u{b825}', '\\u{b83f}', GC_LVT), ('\\u{b840}', '\\u{b840}', GC_LV), ('\\u{b841}',\n        '\\u{b85b}', GC_LVT), ('\\u{b85c}', '\\u{b85c}', GC_LV), ('\\u{b85d}', '\\u{b877}', GC_LVT),\n        ('\\u{b878}', '\\u{b878}', GC_LV), ('\\u{b879}', '\\u{b893}', GC_LVT), ('\\u{b894}', '\\u{b894}',\n        GC_LV), ('\\u{b895}', '\\u{b8af}', GC_LVT), ('\\u{b8b0}', '\\u{b8b0}', GC_LV), ('\\u{b8b1}',\n        '\\u{b8cb}', GC_LVT), ('\\u{b8cc}', '\\u{b8cc}', GC_LV), ('\\u{b8cd}', '\\u{b8e7}', GC_LVT),\n        ('\\u{b8e8}', '\\u{b8e8}', GC_LV), ('\\u{b8e9}', '\\u{b903}', GC_LVT), ('\\u{b904}', '\\u{b904}',\n        GC_LV), ('\\u{b905}', '\\u{b91f}', GC_LVT), ('\\u{b920}', '\\u{b920}', GC_LV), ('\\u{b921}',\n        '\\u{b93b}', GC_LVT), ('\\u{b93c}', '\\u{b93c}', GC_LV), ('\\u{b93d}', '\\u{b957}', GC_LVT),\n        ('\\u{b958}', '\\u{b958}', GC_LV), ('\\u{b959}', '\\u{b973}', GC_LVT), ('\\u{b974}', '\\u{b974}',\n        GC_LV), ('\\u{b975}', '\\u{b98f}', GC_LVT), ('\\u{b990}', '\\u{b990}', GC_LV), ('\\u{b991}',\n        '\\u{b9ab}', GC_LVT), ('\\u{b9ac}', '\\u{b9ac}', GC_LV), ('\\u{b9ad}', '\\u{b9c7}', GC_LVT),\n        ('\\u{b9c8}', '\\u{b9c8}', GC_LV), ('\\u{b9c9}', '\\u{b9e3}', GC_LVT), ('\\u{b9e4}', '\\u{b9e4}',\n        GC_LV), ('\\u{b9e5}', '\\u{b9ff}', GC_LVT), ('\\u{ba00}', '\\u{ba00}', GC_LV), ('\\u{ba01}',\n        '\\u{ba1b}', GC_LVT), ('\\u{ba1c}', '\\u{ba1c}', GC_LV), ('\\u{ba1d}', '\\u{ba37}', GC_LVT),\n        ('\\u{ba38}', '\\u{ba38}', GC_LV), ('\\u{ba39}', '\\u{ba53}', GC_LVT), ('\\u{ba54}', '\\u{ba54}',\n        GC_LV), ('\\u{ba55}', '\\u{ba6f}', GC_LVT), ('\\u{ba70}', '\\u{ba70}', GC_LV), ('\\u{ba71}',\n        '\\u{ba8b}', GC_LVT), ('\\u{ba8c}', '\\u{ba8c}', GC_LV), ('\\u{ba8d}', '\\u{baa7}', GC_LVT),\n        ('\\u{baa8}', '\\u{baa8}', GC_LV), ('\\u{baa9}', '\\u{bac3}', GC_LVT), ('\\u{bac4}', '\\u{bac4}',\n        GC_LV), ('\\u{bac5}', '\\u{badf}', GC_LVT), ('\\u{bae0}', '\\u{bae0}', GC_LV), ('\\u{bae1}',\n        '\\u{bafb}', GC_LVT), ('\\u{bafc}', '\\u{bafc}', GC_LV), ('\\u{bafd}', '\\u{bb17}', GC_LVT),\n        ('\\u{bb18}', '\\u{bb18}', GC_LV), ('\\u{bb19}', '\\u{bb33}', GC_LVT), ('\\u{bb34}', '\\u{bb34}',\n        GC_LV), ('\\u{bb35}', '\\u{bb4f}', GC_LVT), ('\\u{bb50}', '\\u{bb50}', GC_LV), ('\\u{bb51}',\n        '\\u{bb6b}', GC_LVT), ('\\u{bb6c}', '\\u{bb6c}', GC_LV), ('\\u{bb6d}', '\\u{bb87}', GC_LVT),\n        ('\\u{bb88}', '\\u{bb88}', GC_LV), ('\\u{bb89}', '\\u{bba3}', GC_LVT), ('\\u{bba4}', '\\u{bba4}',\n        GC_LV), ('\\u{bba5}', '\\u{bbbf}', GC_LVT), ('\\u{bbc0}', '\\u{bbc0}', GC_LV), ('\\u{bbc1}',\n        '\\u{bbdb}', GC_LVT), ('\\u{bbdc}', '\\u{bbdc}', GC_LV), ('\\u{bbdd}', '\\u{bbf7}', GC_LVT),\n        ('\\u{bbf8}', '\\u{bbf8}', GC_LV), ('\\u{bbf9}', '\\u{bc13}', GC_LVT), ('\\u{bc14}', '\\u{bc14}',\n        GC_LV), ('\\u{bc15}', '\\u{bc2f}', GC_LVT), ('\\u{bc30}', '\\u{bc30}', GC_LV), ('\\u{bc31}',\n        '\\u{bc4b}', GC_LVT), ('\\u{bc4c}', '\\u{bc4c}', GC_LV), ('\\u{bc4d}', '\\u{bc67}', GC_LVT),\n        ('\\u{bc68}', '\\u{bc68}', GC_LV), ('\\u{bc69}', '\\u{bc83}', GC_LVT), ('\\u{bc84}', '\\u{bc84}',\n        GC_LV), ('\\u{bc85}', '\\u{bc9f}', GC_LVT), ('\\u{bca0}', '\\u{bca0}', GC_LV), ('\\u{bca1}',\n        '\\u{bcbb}', GC_LVT), ('\\u{bcbc}', '\\u{bcbc}', GC_LV), ('\\u{bcbd}', '\\u{bcd7}', GC_LVT),\n        ('\\u{bcd8}', '\\u{bcd8}', GC_LV), ('\\u{bcd9}', '\\u{bcf3}', GC_LVT), ('\\u{bcf4}', '\\u{bcf4}',\n        GC_LV), ('\\u{bcf5}', '\\u{bd0f}', GC_LVT), ('\\u{bd10}', '\\u{bd10}', GC_LV), ('\\u{bd11}',\n        '\\u{bd2b}', GC_LVT), ('\\u{bd2c}', '\\u{bd2c}', GC_LV), ('\\u{bd2d}', '\\u{bd47}', GC_LVT),\n        ('\\u{bd48}', '\\u{bd48}', GC_LV), ('\\u{bd49}', '\\u{bd63}', GC_LVT), ('\\u{bd64}', '\\u{bd64}',\n        GC_LV), ('\\u{bd65}', '\\u{bd7f}', GC_LVT), ('\\u{bd80}', '\\u{bd80}', GC_LV), ('\\u{bd81}',\n        '\\u{bd9b}', GC_LVT), ('\\u{bd9c}', '\\u{bd9c}', GC_LV), ('\\u{bd9d}', '\\u{bdb7}', GC_LVT),\n        ('\\u{bdb8}', '\\u{bdb8}', GC_LV), ('\\u{bdb9}', '\\u{bdd3}', GC_LVT), ('\\u{bdd4}', '\\u{bdd4}',\n        GC_LV), ('\\u{bdd5}', '\\u{bdef}', GC_LVT), ('\\u{bdf0}', '\\u{bdf0}', GC_LV), ('\\u{bdf1}',\n        '\\u{be0b}', GC_LVT), ('\\u{be0c}', '\\u{be0c}', GC_LV), ('\\u{be0d}', '\\u{be27}', GC_LVT),\n        ('\\u{be28}', '\\u{be28}', GC_LV), ('\\u{be29}', '\\u{be43}', GC_LVT), ('\\u{be44}', '\\u{be44}',\n        GC_LV), ('\\u{be45}', '\\u{be5f}', GC_LVT), ('\\u{be60}', '\\u{be60}', GC_LV), ('\\u{be61}',\n        '\\u{be7b}', GC_LVT), ('\\u{be7c}', '\\u{be7c}', GC_LV), ('\\u{be7d}', '\\u{be97}', GC_LVT),\n        ('\\u{be98}', '\\u{be98}', GC_LV), ('\\u{be99}', '\\u{beb3}', GC_LVT), ('\\u{beb4}', '\\u{beb4}',\n        GC_LV), ('\\u{beb5}', '\\u{becf}', GC_LVT), ('\\u{bed0}', '\\u{bed0}', GC_LV), ('\\u{bed1}',\n        '\\u{beeb}', GC_LVT), ('\\u{beec}', '\\u{beec}', GC_LV), ('\\u{beed}', '\\u{bf07}', GC_LVT),\n        ('\\u{bf08}', '\\u{bf08}', GC_LV), ('\\u{bf09}', '\\u{bf23}', GC_LVT), ('\\u{bf24}', '\\u{bf24}',\n        GC_LV), ('\\u{bf25}', '\\u{bf3f}', GC_LVT), ('\\u{bf40}', '\\u{bf40}', GC_LV), ('\\u{bf41}',\n        '\\u{bf5b}', GC_LVT), ('\\u{bf5c}', '\\u{bf5c}', GC_LV), ('\\u{bf5d}', '\\u{bf77}', GC_LVT),\n        ('\\u{bf78}', '\\u{bf78}', GC_LV), ('\\u{bf79}', '\\u{bf93}', GC_LVT), ('\\u{bf94}', '\\u{bf94}',\n        GC_LV), ('\\u{bf95}', '\\u{bfaf}', GC_LVT), ('\\u{bfb0}', '\\u{bfb0}', GC_LV), ('\\u{bfb1}',\n        '\\u{bfcb}', GC_LVT), ('\\u{bfcc}', '\\u{bfcc}', GC_LV), ('\\u{bfcd}', '\\u{bfe7}', GC_LVT),\n        ('\\u{bfe8}', '\\u{bfe8}', GC_LV), ('\\u{bfe9}', '\\u{c003}', GC_LVT), ('\\u{c004}', '\\u{c004}',\n        GC_LV), ('\\u{c005}', '\\u{c01f}', GC_LVT), ('\\u{c020}', '\\u{c020}', GC_LV), ('\\u{c021}',\n        '\\u{c03b}', GC_LVT), ('\\u{c03c}', '\\u{c03c}', GC_LV), ('\\u{c03d}', '\\u{c057}', GC_LVT),\n        ('\\u{c058}', '\\u{c058}', GC_LV), ('\\u{c059}', '\\u{c073}', GC_LVT), ('\\u{c074}', '\\u{c074}',\n        GC_LV), ('\\u{c075}', '\\u{c08f}', GC_LVT), ('\\u{c090}', '\\u{c090}', GC_LV), ('\\u{c091}',\n        '\\u{c0ab}', GC_LVT), ('\\u{c0ac}', '\\u{c0ac}', GC_LV), ('\\u{c0ad}', '\\u{c0c7}', GC_LVT),\n        ('\\u{c0c8}', '\\u{c0c8}', GC_LV), ('\\u{c0c9}', '\\u{c0e3}', GC_LVT), ('\\u{c0e4}', '\\u{c0e4}',\n        GC_LV), ('\\u{c0e5}', '\\u{c0ff}', GC_LVT), ('\\u{c100}', '\\u{c100}', GC_LV), ('\\u{c101}',\n        '\\u{c11b}', GC_LVT), ('\\u{c11c}', '\\u{c11c}', GC_LV), ('\\u{c11d}', '\\u{c137}', GC_LVT),\n        ('\\u{c138}', '\\u{c138}', GC_LV), ('\\u{c139}', '\\u{c153}', GC_LVT), ('\\u{c154}', '\\u{c154}',\n        GC_LV), ('\\u{c155}', '\\u{c16f}', GC_LVT), ('\\u{c170}', '\\u{c170}', GC_LV), ('\\u{c171}',\n        '\\u{c18b}', GC_LVT), ('\\u{c18c}', '\\u{c18c}', GC_LV), ('\\u{c18d}', '\\u{c1a7}', GC_LVT),\n        ('\\u{c1a8}', '\\u{c1a8}', GC_LV), ('\\u{c1a9}', '\\u{c1c3}', GC_LVT), ('\\u{c1c4}', '\\u{c1c4}',\n        GC_LV), ('\\u{c1c5}', '\\u{c1df}', GC_LVT), ('\\u{c1e0}', '\\u{c1e0}', GC_LV), ('\\u{c1e1}',\n        '\\u{c1fb}', GC_LVT), ('\\u{c1fc}', '\\u{c1fc}', GC_LV), ('\\u{c1fd}', '\\u{c217}', GC_LVT),\n        ('\\u{c218}', '\\u{c218}', GC_LV), ('\\u{c219}', '\\u{c233}', GC_LVT), ('\\u{c234}', '\\u{c234}',\n        GC_LV), ('\\u{c235}', '\\u{c24f}', GC_LVT), ('\\u{c250}', '\\u{c250}', GC_LV), ('\\u{c251}',\n        '\\u{c26b}', GC_LVT), ('\\u{c26c}', '\\u{c26c}', GC_LV), ('\\u{c26d}', '\\u{c287}', GC_LVT),\n        ('\\u{c288}', '\\u{c288}', GC_LV), ('\\u{c289}', '\\u{c2a3}', GC_LVT), ('\\u{c2a4}', '\\u{c2a4}',\n        GC_LV), ('\\u{c2a5}', '\\u{c2bf}', GC_LVT), ('\\u{c2c0}', '\\u{c2c0}', GC_LV), ('\\u{c2c1}',\n        '\\u{c2db}', GC_LVT), ('\\u{c2dc}', '\\u{c2dc}', GC_LV), ('\\u{c2dd}', '\\u{c2f7}', GC_LVT),\n        ('\\u{c2f8}', '\\u{c2f8}', GC_LV), ('\\u{c2f9}', '\\u{c313}', GC_LVT), ('\\u{c314}', '\\u{c314}',\n        GC_LV), ('\\u{c315}', '\\u{c32f}', GC_LVT), ('\\u{c330}', '\\u{c330}', GC_LV), ('\\u{c331}',\n        '\\u{c34b}', GC_LVT), ('\\u{c34c}', '\\u{c34c}', GC_LV), ('\\u{c34d}', '\\u{c367}', GC_LVT),\n        ('\\u{c368}', '\\u{c368}', GC_LV), ('\\u{c369}', '\\u{c383}', GC_LVT), ('\\u{c384}', '\\u{c384}',\n        GC_LV), ('\\u{c385}', '\\u{c39f}', GC_LVT), ('\\u{c3a0}', '\\u{c3a0}', GC_LV), ('\\u{c3a1}',\n        '\\u{c3bb}', GC_LVT), ('\\u{c3bc}', '\\u{c3bc}', GC_LV), ('\\u{c3bd}', '\\u{c3d7}', GC_LVT),\n        ('\\u{c3d8}', '\\u{c3d8}', GC_LV), ('\\u{c3d9}', '\\u{c3f3}', GC_LVT), ('\\u{c3f4}', '\\u{c3f4}',\n        GC_LV), ('\\u{c3f5}', '\\u{c40f}', GC_LVT), ('\\u{c410}', '\\u{c410}', GC_LV), ('\\u{c411}',\n        '\\u{c42b}', GC_LVT), ('\\u{c42c}', '\\u{c42c}', GC_LV), ('\\u{c42d}', '\\u{c447}', GC_LVT),\n        ('\\u{c448}', '\\u{c448}', GC_LV), ('\\u{c449}', '\\u{c463}', GC_LVT), ('\\u{c464}', '\\u{c464}',\n        GC_LV), ('\\u{c465}', '\\u{c47f}', GC_LVT), ('\\u{c480}', '\\u{c480}', GC_LV), ('\\u{c481}',\n        '\\u{c49b}', GC_LVT), ('\\u{c49c}', '\\u{c49c}', GC_LV), ('\\u{c49d}', '\\u{c4b7}', GC_LVT),\n        ('\\u{c4b8}', '\\u{c4b8}', GC_LV), ('\\u{c4b9}', '\\u{c4d3}', GC_LVT), ('\\u{c4d4}', '\\u{c4d4}',\n        GC_LV), ('\\u{c4d5}', '\\u{c4ef}', GC_LVT), ('\\u{c4f0}', '\\u{c4f0}', GC_LV), ('\\u{c4f1}',\n        '\\u{c50b}', GC_LVT), ('\\u{c50c}', '\\u{c50c}', GC_LV), ('\\u{c50d}', '\\u{c527}', GC_LVT),\n        ('\\u{c528}', '\\u{c528}', GC_LV), ('\\u{c529}', '\\u{c543}', GC_LVT), ('\\u{c544}', '\\u{c544}',\n        GC_LV), ('\\u{c545}', '\\u{c55f}', GC_LVT), ('\\u{c560}', '\\u{c560}', GC_LV), ('\\u{c561}',\n        '\\u{c57b}', GC_LVT), ('\\u{c57c}', '\\u{c57c}', GC_LV), ('\\u{c57d}', '\\u{c597}', GC_LVT),\n        ('\\u{c598}', '\\u{c598}', GC_LV), ('\\u{c599}', '\\u{c5b3}', GC_LVT), ('\\u{c5b4}', '\\u{c5b4}',\n        GC_LV), ('\\u{c5b5}', '\\u{c5cf}', GC_LVT), ('\\u{c5d0}', '\\u{c5d0}', GC_LV), ('\\u{c5d1}',\n        '\\u{c5eb}', GC_LVT), ('\\u{c5ec}', '\\u{c5ec}', GC_LV), ('\\u{c5ed}', '\\u{c607}', GC_LVT),\n        ('\\u{c608}', '\\u{c608}', GC_LV), ('\\u{c609}', '\\u{c623}', GC_LVT), ('\\u{c624}', '\\u{c624}',\n        GC_LV), ('\\u{c625}', '\\u{c63f}', GC_LVT), ('\\u{c640}', '\\u{c640}', GC_LV), ('\\u{c641}',\n        '\\u{c65b}', GC_LVT), ('\\u{c65c}', '\\u{c65c}', GC_LV), ('\\u{c65d}', '\\u{c677}', GC_LVT),\n        ('\\u{c678}', '\\u{c678}', GC_LV), ('\\u{c679}', '\\u{c693}', GC_LVT), ('\\u{c694}', '\\u{c694}',\n        GC_LV), ('\\u{c695}', '\\u{c6af}', GC_LVT), ('\\u{c6b0}', '\\u{c6b0}', GC_LV), ('\\u{c6b1}',\n        '\\u{c6cb}', GC_LVT), ('\\u{c6cc}', '\\u{c6cc}', GC_LV), ('\\u{c6cd}', '\\u{c6e7}', GC_LVT),\n        ('\\u{c6e8}', '\\u{c6e8}', GC_LV), ('\\u{c6e9}', '\\u{c703}', GC_LVT), ('\\u{c704}', '\\u{c704}',\n        GC_LV), ('\\u{c705}', '\\u{c71f}', GC_LVT), ('\\u{c720}', '\\u{c720}', GC_LV), ('\\u{c721}',\n        '\\u{c73b}', GC_LVT), ('\\u{c73c}', '\\u{c73c}', GC_LV), ('\\u{c73d}', '\\u{c757}', GC_LVT),\n        ('\\u{c758}', '\\u{c758}', GC_LV), ('\\u{c759}', '\\u{c773}', GC_LVT), ('\\u{c774}', '\\u{c774}',\n        GC_LV), ('\\u{c775}', '\\u{c78f}', GC_LVT), ('\\u{c790}', '\\u{c790}', GC_LV), ('\\u{c791}',\n        '\\u{c7ab}', GC_LVT), ('\\u{c7ac}', '\\u{c7ac}', GC_LV), ('\\u{c7ad}', '\\u{c7c7}', GC_LVT),\n        ('\\u{c7c8}', '\\u{c7c8}', GC_LV), ('\\u{c7c9}', '\\u{c7e3}', GC_LVT), ('\\u{c7e4}', '\\u{c7e4}',\n        GC_LV), ('\\u{c7e5}', '\\u{c7ff}', GC_LVT), ('\\u{c800}', '\\u{c800}', GC_LV), ('\\u{c801}',\n        '\\u{c81b}', GC_LVT), ('\\u{c81c}', '\\u{c81c}', GC_LV), ('\\u{c81d}', '\\u{c837}', GC_LVT),\n        ('\\u{c838}', '\\u{c838}', GC_LV), ('\\u{c839}', '\\u{c853}', GC_LVT), ('\\u{c854}', '\\u{c854}',\n        GC_LV), ('\\u{c855}', '\\u{c86f}', GC_LVT), ('\\u{c870}', '\\u{c870}', GC_LV), ('\\u{c871}',\n        '\\u{c88b}', GC_LVT), ('\\u{c88c}', '\\u{c88c}', GC_LV), ('\\u{c88d}', '\\u{c8a7}', GC_LVT),\n        ('\\u{c8a8}', '\\u{c8a8}', GC_LV), ('\\u{c8a9}', '\\u{c8c3}', GC_LVT), ('\\u{c8c4}', '\\u{c8c4}',\n        GC_LV), ('\\u{c8c5}', '\\u{c8df}', GC_LVT), ('\\u{c8e0}', '\\u{c8e0}', GC_LV), ('\\u{c8e1}',\n        '\\u{c8fb}', GC_LVT), ('\\u{c8fc}', '\\u{c8fc}', GC_LV), ('\\u{c8fd}', '\\u{c917}', GC_LVT),\n        ('\\u{c918}', '\\u{c918}', GC_LV), ('\\u{c919}', '\\u{c933}', GC_LVT), ('\\u{c934}', '\\u{c934}',\n        GC_LV), ('\\u{c935}', '\\u{c94f}', GC_LVT), ('\\u{c950}', '\\u{c950}', GC_LV), ('\\u{c951}',\n        '\\u{c96b}', GC_LVT), ('\\u{c96c}', '\\u{c96c}', GC_LV), ('\\u{c96d}', '\\u{c987}', GC_LVT),\n        ('\\u{c988}', '\\u{c988}', GC_LV), ('\\u{c989}', '\\u{c9a3}', GC_LVT), ('\\u{c9a4}', '\\u{c9a4}',\n        GC_LV), ('\\u{c9a5}', '\\u{c9bf}', GC_LVT), ('\\u{c9c0}', '\\u{c9c0}', GC_LV), ('\\u{c9c1}',\n        '\\u{c9db}', GC_LVT), ('\\u{c9dc}', '\\u{c9dc}', GC_LV), ('\\u{c9dd}', '\\u{c9f7}', GC_LVT),\n        ('\\u{c9f8}', '\\u{c9f8}', GC_LV), ('\\u{c9f9}', '\\u{ca13}', GC_LVT), ('\\u{ca14}', '\\u{ca14}',\n        GC_LV), ('\\u{ca15}', '\\u{ca2f}', GC_LVT), ('\\u{ca30}', '\\u{ca30}', GC_LV), ('\\u{ca31}',\n        '\\u{ca4b}', GC_LVT), ('\\u{ca4c}', '\\u{ca4c}', GC_LV), ('\\u{ca4d}', '\\u{ca67}', GC_LVT),\n        ('\\u{ca68}', '\\u{ca68}', GC_LV), ('\\u{ca69}', '\\u{ca83}', GC_LVT), ('\\u{ca84}', '\\u{ca84}',\n        GC_LV), ('\\u{ca85}', '\\u{ca9f}', GC_LVT), ('\\u{caa0}', '\\u{caa0}', GC_LV), ('\\u{caa1}',\n        '\\u{cabb}', GC_LVT), ('\\u{cabc}', '\\u{cabc}', GC_LV), ('\\u{cabd}', '\\u{cad7}', GC_LVT),\n        ('\\u{cad8}', '\\u{cad8}', GC_LV), ('\\u{cad9}', '\\u{caf3}', GC_LVT), ('\\u{caf4}', '\\u{caf4}',\n        GC_LV), ('\\u{caf5}', '\\u{cb0f}', GC_LVT), ('\\u{cb10}', '\\u{cb10}', GC_LV), ('\\u{cb11}',\n        '\\u{cb2b}', GC_LVT), ('\\u{cb2c}', '\\u{cb2c}', GC_LV), ('\\u{cb2d}', '\\u{cb47}', GC_LVT),\n        ('\\u{cb48}', '\\u{cb48}', GC_LV), ('\\u{cb49}', '\\u{cb63}', GC_LVT), ('\\u{cb64}', '\\u{cb64}',\n        GC_LV), ('\\u{cb65}', '\\u{cb7f}', GC_LVT), ('\\u{cb80}', '\\u{cb80}', GC_LV), ('\\u{cb81}',\n        '\\u{cb9b}', GC_LVT), ('\\u{cb9c}', '\\u{cb9c}', GC_LV), ('\\u{cb9d}', '\\u{cbb7}', GC_LVT),\n        ('\\u{cbb8}', '\\u{cbb8}', GC_LV), ('\\u{cbb9}', '\\u{cbd3}', GC_LVT), ('\\u{cbd4}', '\\u{cbd4}',\n        GC_LV), ('\\u{cbd5}', '\\u{cbef}', GC_LVT), ('\\u{cbf0}', '\\u{cbf0}', GC_LV), ('\\u{cbf1}',\n        '\\u{cc0b}', GC_LVT), ('\\u{cc0c}', '\\u{cc0c}', GC_LV), ('\\u{cc0d}', '\\u{cc27}', GC_LVT),\n        ('\\u{cc28}', '\\u{cc28}', GC_LV), ('\\u{cc29}', '\\u{cc43}', GC_LVT), ('\\u{cc44}', '\\u{cc44}',\n        GC_LV), ('\\u{cc45}', '\\u{cc5f}', GC_LVT), ('\\u{cc60}', '\\u{cc60}', GC_LV), ('\\u{cc61}',\n        '\\u{cc7b}', GC_LVT), ('\\u{cc7c}', '\\u{cc7c}', GC_LV), ('\\u{cc7d}', '\\u{cc97}', GC_LVT),\n        ('\\u{cc98}', '\\u{cc98}', GC_LV), ('\\u{cc99}', '\\u{ccb3}', GC_LVT), ('\\u{ccb4}', '\\u{ccb4}',\n        GC_LV), ('\\u{ccb5}', '\\u{cccf}', GC_LVT), ('\\u{ccd0}', '\\u{ccd0}', GC_LV), ('\\u{ccd1}',\n        '\\u{cceb}', GC_LVT), ('\\u{ccec}', '\\u{ccec}', GC_LV), ('\\u{cced}', '\\u{cd07}', GC_LVT),\n        ('\\u{cd08}', '\\u{cd08}', GC_LV), ('\\u{cd09}', '\\u{cd23}', GC_LVT), ('\\u{cd24}', '\\u{cd24}',\n        GC_LV), ('\\u{cd25}', '\\u{cd3f}', GC_LVT), ('\\u{cd40}', '\\u{cd40}', GC_LV), ('\\u{cd41}',\n        '\\u{cd5b}', GC_LVT), ('\\u{cd5c}', '\\u{cd5c}', GC_LV), ('\\u{cd5d}', '\\u{cd77}', GC_LVT),\n        ('\\u{cd78}', '\\u{cd78}', GC_LV), ('\\u{cd79}', '\\u{cd93}', GC_LVT), ('\\u{cd94}', '\\u{cd94}',\n        GC_LV), ('\\u{cd95}', '\\u{cdaf}', GC_LVT), ('\\u{cdb0}', '\\u{cdb0}', GC_LV), ('\\u{cdb1}',\n        '\\u{cdcb}', GC_LVT), ('\\u{cdcc}', '\\u{cdcc}', GC_LV), ('\\u{cdcd}', '\\u{cde7}', GC_LVT),\n        ('\\u{cde8}', '\\u{cde8}', GC_LV), ('\\u{cde9}', '\\u{ce03}', GC_LVT), ('\\u{ce04}', '\\u{ce04}',\n        GC_LV), ('\\u{ce05}', '\\u{ce1f}', GC_LVT), ('\\u{ce20}', '\\u{ce20}', GC_LV), ('\\u{ce21}',\n        '\\u{ce3b}', GC_LVT), ('\\u{ce3c}', '\\u{ce3c}', GC_LV), ('\\u{ce3d}', '\\u{ce57}', GC_LVT),\n        ('\\u{ce58}', '\\u{ce58}', GC_LV), ('\\u{ce59}', '\\u{ce73}', GC_LVT), ('\\u{ce74}', '\\u{ce74}',\n        GC_LV), ('\\u{ce75}', '\\u{ce8f}', GC_LVT), ('\\u{ce90}', '\\u{ce90}', GC_LV), ('\\u{ce91}',\n        '\\u{ceab}', GC_LVT), ('\\u{ceac}', '\\u{ceac}', GC_LV), ('\\u{cead}', '\\u{cec7}', GC_LVT),\n        ('\\u{cec8}', '\\u{cec8}', GC_LV), ('\\u{cec9}', '\\u{cee3}', GC_LVT), ('\\u{cee4}', '\\u{cee4}',\n        GC_LV), ('\\u{cee5}', '\\u{ceff}', GC_LVT), ('\\u{cf00}', '\\u{cf00}', GC_LV), ('\\u{cf01}',\n        '\\u{cf1b}', GC_LVT), ('\\u{cf1c}', '\\u{cf1c}', GC_LV), ('\\u{cf1d}', '\\u{cf37}', GC_LVT),\n        ('\\u{cf38}', '\\u{cf38}', GC_LV), ('\\u{cf39}', '\\u{cf53}', GC_LVT), ('\\u{cf54}', '\\u{cf54}',\n        GC_LV), ('\\u{cf55}', '\\u{cf6f}', GC_LVT), ('\\u{cf70}', '\\u{cf70}', GC_LV), ('\\u{cf71}',\n        '\\u{cf8b}', GC_LVT), ('\\u{cf8c}', '\\u{cf8c}', GC_LV), ('\\u{cf8d}', '\\u{cfa7}', GC_LVT),\n        ('\\u{cfa8}', '\\u{cfa8}', GC_LV), ('\\u{cfa9}', '\\u{cfc3}', GC_LVT), ('\\u{cfc4}', '\\u{cfc4}',\n        GC_LV), ('\\u{cfc5}', '\\u{cfdf}', GC_LVT), ('\\u{cfe0}', '\\u{cfe0}', GC_LV), ('\\u{cfe1}',\n        '\\u{cffb}', GC_LVT), ('\\u{cffc}', '\\u{cffc}', GC_LV), ('\\u{cffd}', '\\u{d017}', GC_LVT),\n        ('\\u{d018}', '\\u{d018}', GC_LV), ('\\u{d019}', '\\u{d033}', GC_LVT), ('\\u{d034}', '\\u{d034}',\n        GC_LV), ('\\u{d035}', '\\u{d04f}', GC_LVT), ('\\u{d050}', '\\u{d050}', GC_LV), ('\\u{d051}',\n        '\\u{d06b}', GC_LVT), ('\\u{d06c}', '\\u{d06c}', GC_LV), ('\\u{d06d}', '\\u{d087}', GC_LVT),\n        ('\\u{d088}', '\\u{d088}', GC_LV), ('\\u{d089}', '\\u{d0a3}', GC_LVT), ('\\u{d0a4}', '\\u{d0a4}',\n        GC_LV), ('\\u{d0a5}', '\\u{d0bf}', GC_LVT), ('\\u{d0c0}', '\\u{d0c0}', GC_LV), ('\\u{d0c1}',\n        '\\u{d0db}', GC_LVT), ('\\u{d0dc}', '\\u{d0dc}', GC_LV), ('\\u{d0dd}', '\\u{d0f7}', GC_LVT),\n        ('\\u{d0f8}', '\\u{d0f8}', GC_LV), ('\\u{d0f9}', '\\u{d113}', GC_LVT), ('\\u{d114}', '\\u{d114}',\n        GC_LV), ('\\u{d115}', '\\u{d12f}', GC_LVT), ('\\u{d130}', '\\u{d130}', GC_LV), ('\\u{d131}',\n        '\\u{d14b}', GC_LVT), ('\\u{d14c}', '\\u{d14c}', GC_LV), ('\\u{d14d}', '\\u{d167}', GC_LVT),\n        ('\\u{d168}', '\\u{d168}', GC_LV), ('\\u{d169}', '\\u{d183}', GC_LVT), ('\\u{d184}', '\\u{d184}',\n        GC_LV), ('\\u{d185}', '\\u{d19f}', GC_LVT), ('\\u{d1a0}', '\\u{d1a0}', GC_LV), ('\\u{d1a1}',\n        '\\u{d1bb}', GC_LVT), ('\\u{d1bc}', '\\u{d1bc}', GC_LV), ('\\u{d1bd}', '\\u{d1d7}', GC_LVT),\n        ('\\u{d1d8}', '\\u{d1d8}', GC_LV), ('\\u{d1d9}', '\\u{d1f3}', GC_LVT), ('\\u{d1f4}', '\\u{d1f4}',\n        GC_LV), ('\\u{d1f5}', '\\u{d20f}', GC_LVT), ('\\u{d210}', '\\u{d210}', GC_LV), ('\\u{d211}',\n        '\\u{d22b}', GC_LVT), ('\\u{d22c}', '\\u{d22c}', GC_LV), ('\\u{d22d}', '\\u{d247}', GC_LVT),\n        ('\\u{d248}', '\\u{d248}', GC_LV), ('\\u{d249}', '\\u{d263}', GC_LVT), ('\\u{d264}', '\\u{d264}',\n        GC_LV), ('\\u{d265}', '\\u{d27f}', GC_LVT), ('\\u{d280}', '\\u{d280}', GC_LV), ('\\u{d281}',\n        '\\u{d29b}', GC_LVT), ('\\u{d29c}', '\\u{d29c}', GC_LV), ('\\u{d29d}', '\\u{d2b7}', GC_LVT),\n        ('\\u{d2b8}', '\\u{d2b8}', GC_LV), ('\\u{d2b9}', '\\u{d2d3}', GC_LVT), ('\\u{d2d4}', '\\u{d2d4}',\n        GC_LV), ('\\u{d2d5}', '\\u{d2ef}', GC_LVT), ('\\u{d2f0}', '\\u{d2f0}', GC_LV), ('\\u{d2f1}',\n        '\\u{d30b}', GC_LVT), ('\\u{d30c}', '\\u{d30c}', GC_LV), ('\\u{d30d}', '\\u{d327}', GC_LVT),\n        ('\\u{d328}', '\\u{d328}', GC_LV), ('\\u{d329}', '\\u{d343}', GC_LVT), ('\\u{d344}', '\\u{d344}',\n        GC_LV), ('\\u{d345}', '\\u{d35f}', GC_LVT), ('\\u{d360}', '\\u{d360}', GC_LV), ('\\u{d361}',\n        '\\u{d37b}', GC_LVT), ('\\u{d37c}', '\\u{d37c}', GC_LV), ('\\u{d37d}', '\\u{d397}', GC_LVT),\n        ('\\u{d398}', '\\u{d398}', GC_LV), ('\\u{d399}', '\\u{d3b3}', GC_LVT), ('\\u{d3b4}', '\\u{d3b4}',\n        GC_LV), ('\\u{d3b5}', '\\u{d3cf}', GC_LVT), ('\\u{d3d0}', '\\u{d3d0}', GC_LV), ('\\u{d3d1}',\n        '\\u{d3eb}', GC_LVT), ('\\u{d3ec}', '\\u{d3ec}', GC_LV), ('\\u{d3ed}', '\\u{d407}', GC_LVT),\n        ('\\u{d408}', '\\u{d408}', GC_LV), ('\\u{d409}', '\\u{d423}', GC_LVT), ('\\u{d424}', '\\u{d424}',\n        GC_LV), ('\\u{d425}', '\\u{d43f}', GC_LVT), ('\\u{d440}', '\\u{d440}', GC_LV), ('\\u{d441}',\n        '\\u{d45b}', GC_LVT), ('\\u{d45c}', '\\u{d45c}', GC_LV), ('\\u{d45d}', '\\u{d477}', GC_LVT),\n        ('\\u{d478}', '\\u{d478}', GC_LV), ('\\u{d479}', '\\u{d493}', GC_LVT), ('\\u{d494}', '\\u{d494}',\n        GC_LV), ('\\u{d495}', '\\u{d4af}', GC_LVT), ('\\u{d4b0}', '\\u{d4b0}', GC_LV), ('\\u{d4b1}',\n        '\\u{d4cb}', GC_LVT), ('\\u{d4cc}', '\\u{d4cc}', GC_LV), ('\\u{d4cd}', '\\u{d4e7}', GC_LVT),\n        ('\\u{d4e8}', '\\u{d4e8}', GC_LV), ('\\u{d4e9}', '\\u{d503}', GC_LVT), ('\\u{d504}', '\\u{d504}',\n        GC_LV), ('\\u{d505}', '\\u{d51f}', GC_LVT), ('\\u{d520}', '\\u{d520}', GC_LV), ('\\u{d521}',\n        '\\u{d53b}', GC_LVT), ('\\u{d53c}', '\\u{d53c}', GC_LV), ('\\u{d53d}', '\\u{d557}', GC_LVT),\n        ('\\u{d558}', '\\u{d558}', GC_LV), ('\\u{d559}', '\\u{d573}', GC_LVT), ('\\u{d574}', '\\u{d574}',\n        GC_LV), ('\\u{d575}', '\\u{d58f}', GC_LVT), ('\\u{d590}', '\\u{d590}', GC_LV), ('\\u{d591}',\n        '\\u{d5ab}', GC_LVT), ('\\u{d5ac}', '\\u{d5ac}', GC_LV), ('\\u{d5ad}', '\\u{d5c7}', GC_LVT),\n        ('\\u{d5c8}', '\\u{d5c8}', GC_LV), ('\\u{d5c9}', '\\u{d5e3}', GC_LVT), ('\\u{d5e4}', '\\u{d5e4}',\n        GC_LV), ('\\u{d5e5}', '\\u{d5ff}', GC_LVT), ('\\u{d600}', '\\u{d600}', GC_LV), ('\\u{d601}',\n        '\\u{d61b}', GC_LVT), ('\\u{d61c}', '\\u{d61c}', GC_LV), ('\\u{d61d}', '\\u{d637}', GC_LVT),\n        ('\\u{d638}', '\\u{d638}', GC_LV), ('\\u{d639}', '\\u{d653}', GC_LVT), ('\\u{d654}', '\\u{d654}',\n        GC_LV), ('\\u{d655}', '\\u{d66f}', GC_LVT), ('\\u{d670}', '\\u{d670}', GC_LV), ('\\u{d671}',\n        '\\u{d68b}', GC_LVT), ('\\u{d68c}', '\\u{d68c}', GC_LV), ('\\u{d68d}', '\\u{d6a7}', GC_LVT),\n        ('\\u{d6a8}', '\\u{d6a8}', GC_LV), ('\\u{d6a9}', '\\u{d6c3}', GC_LVT), ('\\u{d6c4}', '\\u{d6c4}',\n        GC_LV), ('\\u{d6c5}', '\\u{d6df}', GC_LVT), ('\\u{d6e0}', '\\u{d6e0}', GC_LV), ('\\u{d6e1}',\n        '\\u{d6fb}', GC_LVT), ('\\u{d6fc}', '\\u{d6fc}', GC_LV), ('\\u{d6fd}', '\\u{d717}', GC_LVT),\n        ('\\u{d718}', '\\u{d718}', GC_LV), ('\\u{d719}', '\\u{d733}', GC_LVT), ('\\u{d734}', '\\u{d734}',\n        GC_LV), ('\\u{d735}', '\\u{d74f}', GC_LVT), ('\\u{d750}', '\\u{d750}', GC_LV), ('\\u{d751}',\n        '\\u{d76b}', GC_LVT), ('\\u{d76c}', '\\u{d76c}', GC_LV), ('\\u{d76d}', '\\u{d787}', GC_LVT),\n        ('\\u{d788}', '\\u{d788}', GC_LV), ('\\u{d789}', '\\u{d7a3}', GC_LVT), ('\\u{d7b0}', '\\u{d7c6}',\n        GC_V), ('\\u{d7cb}', '\\u{d7fb}', GC_T), ('\\u{fb1e}', '\\u{fb1e}', GC_Extend), ('\\u{fe00}',\n        '\\u{fe0f}', GC_Extend), ('\\u{fe20}', '\\u{fe2f}', GC_Extend), ('\\u{feff}', '\\u{feff}',\n        GC_Control), ('\\u{ff9e}', '\\u{ff9f}', GC_Extend), ('\\u{fff0}', '\\u{fffb}', GC_Control),\n        ('\\u{101fd}', '\\u{101fd}', GC_Extend), ('\\u{102e0}', '\\u{102e0}', GC_Extend), ('\\u{10376}',\n        '\\u{1037a}', GC_Extend), ('\\u{10a00}', '\\u{10a00}', GC_InCB_Consonant), ('\\u{10a01}',\n        '\\u{10a03}', GC_Extend), ('\\u{10a05}', '\\u{10a06}', GC_Extend), ('\\u{10a0c}', '\\u{10a0f}',\n        GC_Extend), ('\\u{10a10}', '\\u{10a13}', GC_InCB_Consonant), ('\\u{10a15}', '\\u{10a17}',\n        GC_InCB_Consonant), ('\\u{10a19}', '\\u{10a35}', GC_InCB_Consonant), ('\\u{10a38}',\n        '\\u{10a3a}', GC_Extend), ('\\u{10a3f}', '\\u{10a3f}', GC_Extend), ('\\u{10ae5}', '\\u{10ae6}',\n        GC_Extend), ('\\u{10d24}', '\\u{10d27}', GC_Extend), ('\\u{10d69}', '\\u{10d6d}', GC_Extend),\n        ('\\u{10eab}', '\\u{10eac}', GC_Extend), ('\\u{10efa}', '\\u{10eff}', GC_Extend), ('\\u{10f46}',\n        '\\u{10f50}', GC_Extend), ('\\u{10f82}', '\\u{10f85}', GC_Extend), ('\\u{11000}', '\\u{11000}',\n        GC_SpacingMark), ('\\u{11001}', '\\u{11001}', GC_Extend), ('\\u{11002}', '\\u{11002}',\n        GC_SpacingMark), ('\\u{11038}', '\\u{11046}', GC_Extend), ('\\u{11070}', '\\u{11070}',\n        GC_Extend), ('\\u{11073}', '\\u{11074}', GC_Extend), ('\\u{1107f}', '\\u{11081}', GC_Extend),\n        ('\\u{11082}', '\\u{11082}', GC_SpacingMark), ('\\u{110b0}', '\\u{110b2}', GC_SpacingMark),\n        ('\\u{110b3}', '\\u{110b6}', GC_Extend), ('\\u{110b7}', '\\u{110b8}', GC_SpacingMark),\n        ('\\u{110b9}', '\\u{110ba}', GC_Extend), ('\\u{110bd}', '\\u{110bd}', GC_Prepend), ('\\u{110c2}',\n        '\\u{110c2}', GC_Extend), ('\\u{110cd}', '\\u{110cd}', GC_Prepend), ('\\u{11100}', '\\u{11102}',\n        GC_Extend), ('\\u{11103}', '\\u{11126}', GC_InCB_Consonant), ('\\u{11127}', '\\u{1112b}',\n        GC_Extend), ('\\u{1112c}', '\\u{1112c}', GC_SpacingMark), ('\\u{1112d}', '\\u{11134}',\n        GC_Extend), ('\\u{11144}', '\\u{11144}', GC_InCB_Consonant), ('\\u{11145}', '\\u{11146}',\n        GC_SpacingMark), ('\\u{11147}', '\\u{11147}', GC_InCB_Consonant), ('\\u{11173}', '\\u{11173}',\n        GC_Extend), ('\\u{11180}', '\\u{11181}', GC_Extend), ('\\u{11182}', '\\u{11182}',\n        GC_SpacingMark), ('\\u{111b3}', '\\u{111b5}', GC_SpacingMark), ('\\u{111b6}', '\\u{111be}',\n        GC_Extend), ('\\u{111bf}', '\\u{111bf}', GC_SpacingMark), ('\\u{111c0}', '\\u{111c0}',\n        GC_Extend), ('\\u{111c2}', '\\u{111c3}', GC_Prepend), ('\\u{111c9}', '\\u{111cc}', GC_Extend),\n        ('\\u{111ce}', '\\u{111ce}', GC_SpacingMark), ('\\u{111cf}', '\\u{111cf}', GC_Extend),\n        ('\\u{1122c}', '\\u{1122e}', GC_SpacingMark), ('\\u{1122f}', '\\u{11231}', GC_Extend),\n        ('\\u{11232}', '\\u{11233}', GC_SpacingMark), ('\\u{11234}', '\\u{11237}', GC_Extend),\n        ('\\u{1123e}', '\\u{1123e}', GC_Extend), ('\\u{11241}', '\\u{11241}', GC_Extend), ('\\u{112df}',\n        '\\u{112df}', GC_Extend), ('\\u{112e0}', '\\u{112e2}', GC_SpacingMark), ('\\u{112e3}',\n        '\\u{112ea}', GC_Extend), ('\\u{11300}', '\\u{11301}', GC_Extend), ('\\u{11302}', '\\u{11303}',\n        GC_SpacingMark), ('\\u{1133b}', '\\u{1133c}', GC_Extend), ('\\u{1133e}', '\\u{1133e}',\n        GC_Extend), ('\\u{1133f}', '\\u{1133f}', GC_SpacingMark), ('\\u{11340}', '\\u{11340}',\n        GC_Extend), ('\\u{11341}', '\\u{11344}', GC_SpacingMark), ('\\u{11347}', '\\u{11348}',\n        GC_SpacingMark), ('\\u{1134b}', '\\u{1134c}', GC_SpacingMark), ('\\u{1134d}', '\\u{1134d}',\n        GC_Extend), ('\\u{11357}', '\\u{11357}', GC_Extend), ('\\u{11362}', '\\u{11363}',\n        GC_SpacingMark), ('\\u{11366}', '\\u{1136c}', GC_Extend), ('\\u{11370}', '\\u{11374}',\n        GC_Extend), ('\\u{11380}', '\\u{11389}', GC_InCB_Consonant), ('\\u{1138b}', '\\u{1138b}',\n        GC_InCB_Consonant), ('\\u{1138e}', '\\u{1138e}', GC_InCB_Consonant), ('\\u{11390}',\n        '\\u{113b5}', GC_InCB_Consonant), ('\\u{113b8}', '\\u{113b8}', GC_Extend), ('\\u{113b9}',\n        '\\u{113ba}', GC_SpacingMark), ('\\u{113bb}', '\\u{113c0}', GC_Extend), ('\\u{113c2}',\n        '\\u{113c2}', GC_Extend), ('\\u{113c5}', '\\u{113c5}', GC_Extend), ('\\u{113c7}', '\\u{113c9}',\n        GC_Extend), ('\\u{113ca}', '\\u{113ca}', GC_SpacingMark), ('\\u{113cc}', '\\u{113cd}',\n        GC_SpacingMark), ('\\u{113ce}', '\\u{113d0}', GC_Extend), ('\\u{113d1}', '\\u{113d1}',\n        GC_Prepend), ('\\u{113d2}', '\\u{113d2}', GC_Extend), ('\\u{113e1}', '\\u{113e2}', GC_Extend),\n        ('\\u{11435}', '\\u{11437}', GC_SpacingMark), ('\\u{11438}', '\\u{1143f}', GC_Extend),\n        ('\\u{11440}', '\\u{11441}', GC_SpacingMark), ('\\u{11442}', '\\u{11444}', GC_Extend),\n        ('\\u{11445}', '\\u{11445}', GC_SpacingMark), ('\\u{11446}', '\\u{11446}', GC_Extend),\n        ('\\u{1145e}', '\\u{1145e}', GC_Extend), ('\\u{114b0}', '\\u{114b0}', GC_Extend), ('\\u{114b1}',\n        '\\u{114b2}', GC_SpacingMark), ('\\u{114b3}', '\\u{114b8}', GC_Extend), ('\\u{114b9}',\n        '\\u{114b9}', GC_SpacingMark), ('\\u{114ba}', '\\u{114ba}', GC_Extend), ('\\u{114bb}',\n        '\\u{114bc}', GC_SpacingMark), ('\\u{114bd}', '\\u{114bd}', GC_Extend), ('\\u{114be}',\n        '\\u{114be}', GC_SpacingMark), ('\\u{114bf}', '\\u{114c0}', GC_Extend), ('\\u{114c1}',\n        '\\u{114c1}', GC_SpacingMark), ('\\u{114c2}', '\\u{114c3}', GC_Extend), ('\\u{115af}',\n        '\\u{115af}', GC_Extend), ('\\u{115b0}', '\\u{115b1}', GC_SpacingMark), ('\\u{115b2}',\n        '\\u{115b5}', GC_Extend), ('\\u{115b8}', '\\u{115bb}', GC_SpacingMark), ('\\u{115bc}',\n        '\\u{115bd}', GC_Extend), ('\\u{115be}', '\\u{115be}', GC_SpacingMark), ('\\u{115bf}',\n        '\\u{115c0}', GC_Extend), ('\\u{115dc}', '\\u{115dd}', GC_Extend), ('\\u{11630}', '\\u{11632}',\n        GC_SpacingMark), ('\\u{11633}', '\\u{1163a}', GC_Extend), ('\\u{1163b}', '\\u{1163c}',\n        GC_SpacingMark), ('\\u{1163d}', '\\u{1163d}', GC_Extend), ('\\u{1163e}', '\\u{1163e}',\n        GC_SpacingMark), ('\\u{1163f}', '\\u{11640}', GC_Extend), ('\\u{116ab}', '\\u{116ab}',\n        GC_Extend), ('\\u{116ac}', '\\u{116ac}', GC_SpacingMark), ('\\u{116ad}', '\\u{116ad}',\n        GC_Extend), ('\\u{116ae}', '\\u{116af}', GC_SpacingMark), ('\\u{116b0}', '\\u{116b7}',\n        GC_Extend), ('\\u{1171d}', '\\u{1171d}', GC_Extend), ('\\u{1171e}', '\\u{1171e}',\n        GC_SpacingMark), ('\\u{1171f}', '\\u{1171f}', GC_Extend), ('\\u{11722}', '\\u{11725}',\n        GC_Extend), ('\\u{11726}', '\\u{11726}', GC_SpacingMark), ('\\u{11727}', '\\u{1172b}',\n        GC_Extend), ('\\u{1182c}', '\\u{1182e}', GC_SpacingMark), ('\\u{1182f}', '\\u{11837}',\n        GC_Extend), ('\\u{11838}', '\\u{11838}', GC_SpacingMark), ('\\u{11839}', '\\u{1183a}',\n        GC_Extend), ('\\u{11900}', '\\u{11906}', GC_InCB_Consonant), ('\\u{11909}', '\\u{11909}',\n        GC_InCB_Consonant), ('\\u{1190c}', '\\u{11913}', GC_InCB_Consonant), ('\\u{11915}',\n        '\\u{11916}', GC_InCB_Consonant), ('\\u{11918}', '\\u{1192f}', GC_InCB_Consonant),\n        ('\\u{11930}', '\\u{11930}', GC_Extend), ('\\u{11931}', '\\u{11935}', GC_SpacingMark),\n        ('\\u{11937}', '\\u{11938}', GC_SpacingMark), ('\\u{1193b}', '\\u{1193e}', GC_Extend),\n        ('\\u{1193f}', '\\u{1193f}', GC_Prepend), ('\\u{11940}', '\\u{11940}', GC_SpacingMark),\n        ('\\u{11941}', '\\u{11941}', GC_Prepend), ('\\u{11942}', '\\u{11942}', GC_SpacingMark),\n        ('\\u{11943}', '\\u{11943}', GC_Extend), ('\\u{119d1}', '\\u{119d3}', GC_SpacingMark),\n        ('\\u{119d4}', '\\u{119d7}', GC_Extend), ('\\u{119da}', '\\u{119db}', GC_Extend), ('\\u{119dc}',\n        '\\u{119df}', GC_SpacingMark), ('\\u{119e0}', '\\u{119e0}', GC_Extend), ('\\u{119e4}',\n        '\\u{119e4}', GC_SpacingMark), ('\\u{11a00}', '\\u{11a00}', GC_InCB_Consonant), ('\\u{11a01}',\n        '\\u{11a0a}', GC_Extend), ('\\u{11a0b}', '\\u{11a32}', GC_InCB_Consonant), ('\\u{11a33}',\n        '\\u{11a38}', GC_Extend), ('\\u{11a39}', '\\u{11a39}', GC_SpacingMark), ('\\u{11a3b}',\n        '\\u{11a3e}', GC_Extend), ('\\u{11a47}', '\\u{11a47}', GC_Extend), ('\\u{11a50}', '\\u{11a50}',\n        GC_InCB_Consonant), ('\\u{11a51}', '\\u{11a56}', GC_Extend), ('\\u{11a57}', '\\u{11a58}',\n        GC_SpacingMark), ('\\u{11a59}', '\\u{11a5b}', GC_Extend), ('\\u{11a5c}', '\\u{11a83}',\n        GC_InCB_Consonant), ('\\u{11a84}', '\\u{11a89}', GC_Prepend), ('\\u{11a8a}', '\\u{11a96}',\n        GC_Extend), ('\\u{11a97}', '\\u{11a97}', GC_SpacingMark), ('\\u{11a98}', '\\u{11a99}',\n        GC_Extend), ('\\u{11b60}', '\\u{11b60}', GC_Extend), ('\\u{11b61}', '\\u{11b61}',\n        GC_SpacingMark), ('\\u{11b62}', '\\u{11b64}', GC_Extend), ('\\u{11b65}', '\\u{11b65}',\n        GC_SpacingMark), ('\\u{11b66}', '\\u{11b66}', GC_Extend), ('\\u{11b67}', '\\u{11b67}',\n        GC_SpacingMark), ('\\u{11c2f}', '\\u{11c2f}', GC_SpacingMark), ('\\u{11c30}', '\\u{11c36}',\n        GC_Extend), ('\\u{11c38}', '\\u{11c3d}', GC_Extend), ('\\u{11c3e}', '\\u{11c3e}',\n        GC_SpacingMark), ('\\u{11c3f}', '\\u{11c3f}', GC_Extend), ('\\u{11c92}', '\\u{11ca7}',\n        GC_Extend), ('\\u{11ca9}', '\\u{11ca9}', GC_SpacingMark), ('\\u{11caa}', '\\u{11cb0}',\n        GC_Extend), ('\\u{11cb1}', '\\u{11cb1}', GC_SpacingMark), ('\\u{11cb2}', '\\u{11cb3}',\n        GC_Extend), ('\\u{11cb4}', '\\u{11cb4}', GC_SpacingMark), ('\\u{11cb5}', '\\u{11cb6}',\n        GC_Extend), ('\\u{11d31}', '\\u{11d36}', GC_Extend), ('\\u{11d3a}', '\\u{11d3a}', GC_Extend),\n        ('\\u{11d3c}', '\\u{11d3d}', GC_Extend), ('\\u{11d3f}', '\\u{11d45}', GC_Extend), ('\\u{11d46}',\n        '\\u{11d46}', GC_Prepend), ('\\u{11d47}', '\\u{11d47}', GC_Extend), ('\\u{11d8a}', '\\u{11d8e}',\n        GC_SpacingMark), ('\\u{11d90}', '\\u{11d91}', GC_Extend), ('\\u{11d93}', '\\u{11d94}',\n        GC_SpacingMark), ('\\u{11d95}', '\\u{11d95}', GC_Extend), ('\\u{11d96}', '\\u{11d96}',\n        GC_SpacingMark), ('\\u{11d97}', '\\u{11d97}', GC_Extend), ('\\u{11ef3}', '\\u{11ef4}',\n        GC_Extend), ('\\u{11ef5}', '\\u{11ef6}', GC_SpacingMark), ('\\u{11f00}', '\\u{11f01}',\n        GC_Extend), ('\\u{11f02}', '\\u{11f02}', GC_Prepend), ('\\u{11f03}', '\\u{11f03}',\n        GC_SpacingMark), ('\\u{11f04}', '\\u{11f10}', GC_InCB_Consonant), ('\\u{11f12}', '\\u{11f33}',\n        GC_InCB_Consonant), ('\\u{11f34}', '\\u{11f35}', GC_SpacingMark), ('\\u{11f36}', '\\u{11f3a}',\n        GC_Extend), ('\\u{11f3e}', '\\u{11f3f}', GC_SpacingMark), ('\\u{11f40}', '\\u{11f42}',\n        GC_Extend), ('\\u{11f5a}', '\\u{11f5a}', GC_Extend), ('\\u{13430}', '\\u{1343f}', GC_Control),\n        ('\\u{13440}', '\\u{13440}', GC_Extend), ('\\u{13447}', '\\u{13455}', GC_Extend), ('\\u{1611e}',\n        '\\u{16129}', GC_Extend), ('\\u{1612a}', '\\u{1612c}', GC_SpacingMark), ('\\u{1612d}',\n        '\\u{1612f}', GC_Extend), ('\\u{16af0}', '\\u{16af4}', GC_Extend), ('\\u{16b30}', '\\u{16b36}',\n        GC_Extend), ('\\u{16d63}', '\\u{16d63}', GC_V), ('\\u{16d67}', '\\u{16d6a}', GC_V),\n        ('\\u{16f4f}', '\\u{16f4f}', GC_Extend), ('\\u{16f51}', '\\u{16f87}', GC_SpacingMark),\n        ('\\u{16f8f}', '\\u{16f92}', GC_Extend), ('\\u{16fe4}', '\\u{16fe4}', GC_Extend), ('\\u{16ff0}',\n        '\\u{16ff1}', GC_Extend), ('\\u{1bc9d}', '\\u{1bc9e}', GC_Extend), ('\\u{1bca0}', '\\u{1bca3}',\n        GC_Control), ('\\u{1cf00}', '\\u{1cf2d}', GC_Extend), ('\\u{1cf30}', '\\u{1cf46}', GC_Extend),\n        ('\\u{1d165}', '\\u{1d169}', GC_Extend), ('\\u{1d16d}', '\\u{1d172}', GC_Extend), ('\\u{1d173}',\n        '\\u{1d17a}', GC_Control), ('\\u{1d17b}', '\\u{1d182}', GC_Extend), ('\\u{1d185}', '\\u{1d18b}',\n        GC_Extend), ('\\u{1d1aa}', '\\u{1d1ad}', GC_Extend), ('\\u{1d242}', '\\u{1d244}', GC_Extend),\n        ('\\u{1da00}', '\\u{1da36}', GC_Extend), ('\\u{1da3b}', '\\u{1da6c}', GC_Extend), ('\\u{1da75}',\n        '\\u{1da75}', GC_Extend), ('\\u{1da84}', '\\u{1da84}', GC_Extend), ('\\u{1da9b}', '\\u{1da9f}',\n        GC_Extend), ('\\u{1daa1}', '\\u{1daaf}', GC_Extend), ('\\u{1e000}', '\\u{1e006}', GC_Extend),\n        ('\\u{1e008}', '\\u{1e018}', GC_Extend), ('\\u{1e01b}', '\\u{1e021}', GC_Extend), ('\\u{1e023}',\n        '\\u{1e024}', GC_Extend), ('\\u{1e026}', '\\u{1e02a}', GC_Extend), ('\\u{1e08f}', '\\u{1e08f}',\n        GC_Extend), ('\\u{1e130}', '\\u{1e136}', GC_Extend), ('\\u{1e2ae}', '\\u{1e2ae}', GC_Extend),\n        ('\\u{1e2ec}', '\\u{1e2ef}', GC_Extend), ('\\u{1e4ec}', '\\u{1e4ef}', GC_Extend), ('\\u{1e5ee}',\n        '\\u{1e5ef}', GC_Extend), ('\\u{1e6e3}', '\\u{1e6e3}', GC_Extend), ('\\u{1e6e6}', '\\u{1e6e6}',\n        GC_Extend), ('\\u{1e6ee}', '\\u{1e6ef}', GC_Extend), ('\\u{1e6f5}', '\\u{1e6f5}', GC_Extend),\n        ('\\u{1e8d0}', '\\u{1e8d6}', GC_Extend), ('\\u{1e944}', '\\u{1e94a}', GC_Extend), ('\\u{1f004}',\n        '\\u{1f004}', GC_Extended_Pictographic), ('\\u{1f02c}', '\\u{1f02f}',\n        GC_Extended_Pictographic), ('\\u{1f094}', '\\u{1f09f}', GC_Extended_Pictographic),\n        ('\\u{1f0af}', '\\u{1f0b0}', GC_Extended_Pictographic), ('\\u{1f0c0}', '\\u{1f0c0}',\n        GC_Extended_Pictographic), ('\\u{1f0cf}', '\\u{1f0d0}', GC_Extended_Pictographic),\n        ('\\u{1f0f6}', '\\u{1f0ff}', GC_Extended_Pictographic), ('\\u{1f170}', '\\u{1f171}',\n        GC_Extended_Pictographic), ('\\u{1f17e}', '\\u{1f17f}', GC_Extended_Pictographic),\n        ('\\u{1f18e}', '\\u{1f18e}', GC_Extended_Pictographic), ('\\u{1f191}', '\\u{1f19a}',\n        GC_Extended_Pictographic), ('\\u{1f1ae}', '\\u{1f1e5}', GC_Extended_Pictographic),\n        ('\\u{1f1e6}', '\\u{1f1ff}', GC_Regional_Indicator), ('\\u{1f201}', '\\u{1f20f}',\n        GC_Extended_Pictographic), ('\\u{1f21a}', '\\u{1f21a}', GC_Extended_Pictographic),\n        ('\\u{1f22f}', '\\u{1f22f}', GC_Extended_Pictographic), ('\\u{1f232}', '\\u{1f23a}',\n        GC_Extended_Pictographic), ('\\u{1f23c}', '\\u{1f23f}', GC_Extended_Pictographic),\n        ('\\u{1f249}', '\\u{1f25f}', GC_Extended_Pictographic), ('\\u{1f266}', '\\u{1f321}',\n        GC_Extended_Pictographic), ('\\u{1f324}', '\\u{1f393}', GC_Extended_Pictographic),\n        ('\\u{1f396}', '\\u{1f397}', GC_Extended_Pictographic), ('\\u{1f399}', '\\u{1f39b}',\n        GC_Extended_Pictographic), ('\\u{1f39e}', '\\u{1f3f0}', GC_Extended_Pictographic),\n        ('\\u{1f3f3}', '\\u{1f3f5}', GC_Extended_Pictographic), ('\\u{1f3f7}', '\\u{1f3fa}',\n        GC_Extended_Pictographic), ('\\u{1f3fb}', '\\u{1f3ff}', GC_Extend), ('\\u{1f400}', '\\u{1f4fd}',\n        GC_Extended_Pictographic), ('\\u{1f4ff}', '\\u{1f53d}', GC_Extended_Pictographic),\n        ('\\u{1f549}', '\\u{1f54e}', GC_Extended_Pictographic), ('\\u{1f550}', '\\u{1f567}',\n        GC_Extended_Pictographic), ('\\u{1f56f}', '\\u{1f570}', GC_Extended_Pictographic),\n        ('\\u{1f573}', '\\u{1f57a}', GC_Extended_Pictographic), ('\\u{1f587}', '\\u{1f587}',\n        GC_Extended_Pictographic), ('\\u{1f58a}', '\\u{1f58d}', GC_Extended_Pictographic),\n        ('\\u{1f590}', '\\u{1f590}', GC_Extended_Pictographic), ('\\u{1f595}', '\\u{1f596}',\n        GC_Extended_Pictographic), ('\\u{1f5a4}', '\\u{1f5a5}', GC_Extended_Pictographic),\n        ('\\u{1f5a8}', '\\u{1f5a8}', GC_Extended_Pictographic), ('\\u{1f5b1}', '\\u{1f5b2}',\n        GC_Extended_Pictographic), ('\\u{1f5bc}', '\\u{1f5bc}', GC_Extended_Pictographic),\n        ('\\u{1f5c2}', '\\u{1f5c4}', GC_Extended_Pictographic), ('\\u{1f5d1}', '\\u{1f5d3}',\n        GC_Extended_Pictographic), ('\\u{1f5dc}', '\\u{1f5de}', GC_Extended_Pictographic),\n        ('\\u{1f5e1}', '\\u{1f5e1}', GC_Extended_Pictographic), ('\\u{1f5e3}', '\\u{1f5e3}',\n        GC_Extended_Pictographic), ('\\u{1f5e8}', '\\u{1f5e8}', GC_Extended_Pictographic),\n        ('\\u{1f5ef}', '\\u{1f5ef}', GC_Extended_Pictographic), ('\\u{1f5f3}', '\\u{1f5f3}',\n        GC_Extended_Pictographic), ('\\u{1f5fa}', '\\u{1f64f}', GC_Extended_Pictographic),\n        ('\\u{1f680}', '\\u{1f6c5}', GC_Extended_Pictographic), ('\\u{1f6cb}', '\\u{1f6d2}',\n        GC_Extended_Pictographic), ('\\u{1f6d5}', '\\u{1f6e5}', GC_Extended_Pictographic),\n        ('\\u{1f6e9}', '\\u{1f6e9}', GC_Extended_Pictographic), ('\\u{1f6eb}', '\\u{1f6f0}',\n        GC_Extended_Pictographic), ('\\u{1f6f3}', '\\u{1f6ff}', GC_Extended_Pictographic),\n        ('\\u{1f7da}', '\\u{1f7ff}', GC_Extended_Pictographic), ('\\u{1f80c}', '\\u{1f80f}',\n        GC_Extended_Pictographic), ('\\u{1f848}', '\\u{1f84f}', GC_Extended_Pictographic),\n        ('\\u{1f85a}', '\\u{1f85f}', GC_Extended_Pictographic), ('\\u{1f888}', '\\u{1f88f}',\n        GC_Extended_Pictographic), ('\\u{1f8ae}', '\\u{1f8af}', GC_Extended_Pictographic),\n        ('\\u{1f8bc}', '\\u{1f8bf}', GC_Extended_Pictographic), ('\\u{1f8c2}', '\\u{1f8cf}',\n        GC_Extended_Pictographic), ('\\u{1f8d9}', '\\u{1f8ff}', GC_Extended_Pictographic),\n        ('\\u{1f90c}', '\\u{1f93a}', GC_Extended_Pictographic), ('\\u{1f93c}', '\\u{1f945}',\n        GC_Extended_Pictographic), ('\\u{1f947}', '\\u{1f9ff}', GC_Extended_Pictographic),\n        ('\\u{1fa58}', '\\u{1fa5f}', GC_Extended_Pictographic), ('\\u{1fa6e}', '\\u{1faff}',\n        GC_Extended_Pictographic), ('\\u{1fc00}', '\\u{1fffd}', GC_Extended_Pictographic),\n        ('\\u{e0000}', '\\u{e001f}', GC_Control), ('\\u{e0020}', '\\u{e007f}', GC_Extend), ('\\u{e0080}',\n        '\\u{e00ff}', GC_Control), ('\\u{e0100}', '\\u{e01ef}', GC_Extend), ('\\u{e01f0}', '\\u{e0fff}',\n        GC_Control)\n    ];\n\n}\n\npub mod word {\n    use core::result::Result::{Ok, Err};\n\n    pub use self::WordCat::*;\n\n    #[allow(non_camel_case_types)]\n    #[derive(Clone, Copy, PartialEq, Eq, Debug)]\n    pub enum WordCat {\n        WC_ALetter,\n        WC_Any,\n        WC_CR,\n        WC_Double_Quote,\n        WC_Extend,\n        WC_ExtendNumLet,\n        WC_Format,\n        WC_Hebrew_Letter,\n        WC_Katakana,\n        WC_LF,\n        WC_MidLetter,\n        WC_MidNum,\n        WC_MidNumLet,\n        WC_Newline,\n        WC_Numeric,\n        WC_Regional_Indicator,\n        WC_Single_Quote,\n        WC_WSegSpace,\n        WC_ZWJ,\n    }\n\n    fn bsearch_range_value_table(c: char, r: &[(char, char, WordCat)], default_lower: u32, default_upper: u32) -> (u32, u32, WordCat) {\n        use core::cmp::Ordering::{Equal, Less, Greater};\n        match r.binary_search_by(|&(lo, hi, _)| {\n            if lo <= c && c <= hi { Equal }\n            else if hi < c { Less }\n            else { Greater }\n        }) {\n            Ok(idx) => {\n                let (lower, upper, cat) = r[idx];\n                (lower as u32, upper as u32, cat)\n            }\n            Err(idx) => {\n                (\n                    if idx > 0 { r[idx-1].1 as u32 + 1 } else { default_lower },\n                    r.get(idx).map(|c|c.0 as u32 - 1).unwrap_or(default_upper),\n                    WC_Any,\n                )\n            }\n        }\n    }\n\n    pub fn word_category(c: char) -> (u32, u32, WordCat) {\n        // Perform a quick O(1) lookup in a precomputed table to determine\n        // the slice of the range table to search in.\n        let lookup_interval = 0x80;\n        let idx = (c as u32 / lookup_interval) as usize;\n        let range = word_cat_lookup.get(idx..(idx + 2)).map_or(\n          // If the `idx` is outside of the precomputed table - use the slice\n          // starting from the last covered index in the precomputed table and\n          // ending with the length of the range table.\n          1097..1100,\n          |r| (r[0] as usize)..((r[1] + 1) as usize)\n        );\n\n        // Compute pessimistic default lower and upper bounds on the category.\n        // If character doesn't map to any range and there is no adjacent range\n        // in the table slice - these bounds has to apply.\n        let lower = idx as u32 * lookup_interval;\n        let upper = lower + lookup_interval - 1;\n        bsearch_range_value_table(c, &word_cat_table[range], lower, upper)\n    }\n\n    const word_cat_lookup: &[u16] = &[\n        0, 14, 23, 23, 23, 23, 25, 31, 37, 37, 39, 44, 56, 67, 79, 83, 93, 104, 111, 121, 143, 162,\n        180, 198, 215, 231, 250, 266, 278, 282, 286, 295, 301, 308, 316, 316, 316, 321, 329, 333,\n        336, 336, 336, 336, 336, 338, 342, 351, 354, 359, 365, 369, 370, 375, 379, 385, 392, 398,\n        410, 410, 412, 412, 412, 421, 431, 450, 452, 465, 466, 466, 466, 466, 466, 466, 467, 467,\n        467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 471, 477, 487, 488,\n        488, 488, 488, 493, 497, 498, 501, 501, 502, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503,\n        503, 503, 505, 505, 505, 512, 516, 516, 517, 527, 536, 542, 549, 557, 566, 572, 576, 576,\n        576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576,\n        576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576,\n        576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576,\n        576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576,\n        576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 579, 579, 579, 579,\n        579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579,\n        579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579,\n        579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579,\n        579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 590, 591, 591, 591, 592,\n        595, 605, 607, 616, 624, 630, 631, 632, 633, 633, 636, 640, 644, 644, 648, 651, 659, 659,\n        659, 662, 665, 672, 675, 678, 680, 690, 694, 697, 698, 699, 701, 707, 708, 708, 713, 717,\n        721, 729, 737, 747, 756, 762, 770, 788, 802, 808, 813, 813, 818, 822, 827, 829, 829, 831,\n        833, 846, 853, 862, 866, 867, 869, 875, 878, 890, 898, 898, 900, 909, 910, 910, 910, 910,\n        910, 910, 910, 910, 911, 912, 912, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 913,\n        913, 913, 913, 913, 913, 913, 913, 913, 913, 913, 914, 914, 914, 914, 914, 914, 914, 914,\n        914, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919,\n        919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, 920, 920, 920, 920,\n        920, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921,\n        921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921,\n        921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921,\n        921, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,\n        924, 927, 931, 936, 937, 937, 937, 939, 939, 940, 942, 945, 952, 952, 952, 952, 952, 952,\n        952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952,\n        952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952,\n        952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952,\n        952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952,\n        952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952,\n        952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952,\n        952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 955, 956, 956, 959,\n        959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, 959,\n        959, 959, 959, 961, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,\n        965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 965,\n        966, 966, 966, 966, 966, 968, 968, 968, 968, 971, 974, 975, 975, 975, 975, 976, 984, 993,\n        993, 993, 997, 1001, 1006, 1006, 1006, 1006, 1006, 1009, 1012, 1012, 1012, 1012, 1012, 1012,\n        1012, 1012, 1012, 1014, 1014, 1020, 1021, 1026, 1026, 1026, 1031, 1031, 1031, 1031, 1034,\n        1034, 1038, 1038, 1048, 1048, 1052, 1052, 1054, 1058, 1058, 1058, 1058, 1058, 1058, 1058,\n        1058, 1058, 1058, 1086, 1091, 1091, 1091, 1091, 1091, 1093, 1095, 1095, 1095, 1095, 1096,\n        1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096,\n        1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097\n    ];\n\n    const word_cat_table: &[(char, char, WordCat)] = &[\n        ('\\u{a}', '\\u{a}', WC_LF), ('\\u{b}', '\\u{c}', WC_Newline), ('\\u{d}', '\\u{d}', WC_CR),\n        ('\\u{20}', '\\u{20}', WC_WSegSpace), ('\\u{22}', '\\u{22}', WC_Double_Quote), ('\\u{27}',\n        '\\u{27}', WC_Single_Quote), ('\\u{2c}', '\\u{2c}', WC_MidNum), ('\\u{2e}', '\\u{2e}',\n        WC_MidNumLet), ('\\u{30}', '\\u{39}', WC_Numeric), ('\\u{3a}', '\\u{3a}', WC_MidLetter),\n        ('\\u{3b}', '\\u{3b}', WC_MidNum), ('\\u{41}', '\\u{5a}', WC_ALetter), ('\\u{5f}', '\\u{5f}',\n        WC_ExtendNumLet), ('\\u{61}', '\\u{7a}', WC_ALetter), ('\\u{85}', '\\u{85}', WC_Newline),\n        ('\\u{aa}', '\\u{aa}', WC_ALetter), ('\\u{ad}', '\\u{ad}', WC_Format), ('\\u{b5}', '\\u{b5}',\n        WC_ALetter), ('\\u{b7}', '\\u{b7}', WC_MidLetter), ('\\u{b8}', '\\u{b8}', WC_ALetter),\n        ('\\u{ba}', '\\u{ba}', WC_ALetter), ('\\u{c0}', '\\u{d6}', WC_ALetter), ('\\u{d8}', '\\u{f6}',\n        WC_ALetter), ('\\u{f8}', '\\u{2d7}', WC_ALetter), ('\\u{2de}', '\\u{2ff}', WC_ALetter),\n        ('\\u{300}', '\\u{36f}', WC_Extend), ('\\u{370}', '\\u{374}', WC_ALetter), ('\\u{376}',\n        '\\u{377}', WC_ALetter), ('\\u{37a}', '\\u{37d}', WC_ALetter), ('\\u{37e}', '\\u{37e}',\n        WC_MidNum), ('\\u{37f}', '\\u{37f}', WC_ALetter), ('\\u{386}', '\\u{386}', WC_ALetter),\n        ('\\u{387}', '\\u{387}', WC_MidLetter), ('\\u{388}', '\\u{38a}', WC_ALetter), ('\\u{38c}',\n        '\\u{38c}', WC_ALetter), ('\\u{38e}', '\\u{3a1}', WC_ALetter), ('\\u{3a3}', '\\u{3f5}',\n        WC_ALetter), ('\\u{3f7}', '\\u{481}', WC_ALetter), ('\\u{483}', '\\u{489}', WC_Extend),\n        ('\\u{48a}', '\\u{52f}', WC_ALetter), ('\\u{531}', '\\u{556}', WC_ALetter), ('\\u{559}',\n        '\\u{55c}', WC_ALetter), ('\\u{55e}', '\\u{55e}', WC_ALetter), ('\\u{55f}', '\\u{55f}',\n        WC_MidLetter), ('\\u{560}', '\\u{588}', WC_ALetter), ('\\u{589}', '\\u{589}', WC_MidNum),\n        ('\\u{58a}', '\\u{58a}', WC_ALetter), ('\\u{591}', '\\u{5bd}', WC_Extend), ('\\u{5bf}',\n        '\\u{5bf}', WC_Extend), ('\\u{5c1}', '\\u{5c2}', WC_Extend), ('\\u{5c4}', '\\u{5c5}', WC_Extend),\n        ('\\u{5c7}', '\\u{5c7}', WC_Extend), ('\\u{5d0}', '\\u{5ea}', WC_Hebrew_Letter), ('\\u{5ef}',\n        '\\u{5f2}', WC_Hebrew_Letter), ('\\u{5f3}', '\\u{5f3}', WC_ALetter), ('\\u{5f4}', '\\u{5f4}',\n        WC_MidLetter), ('\\u{600}', '\\u{605}', WC_Numeric), ('\\u{60c}', '\\u{60d}', WC_MidNum),\n        ('\\u{610}', '\\u{61a}', WC_Extend), ('\\u{61c}', '\\u{61c}', WC_Format), ('\\u{620}', '\\u{64a}',\n        WC_ALetter), ('\\u{64b}', '\\u{65f}', WC_Extend), ('\\u{660}', '\\u{669}', WC_Numeric),\n        ('\\u{66b}', '\\u{66b}', WC_Numeric), ('\\u{66c}', '\\u{66c}', WC_MidNum), ('\\u{66e}',\n        '\\u{66f}', WC_ALetter), ('\\u{670}', '\\u{670}', WC_Extend), ('\\u{671}', '\\u{6d3}',\n        WC_ALetter), ('\\u{6d5}', '\\u{6d5}', WC_ALetter), ('\\u{6d6}', '\\u{6dc}', WC_Extend),\n        ('\\u{6dd}', '\\u{6dd}', WC_Numeric), ('\\u{6df}', '\\u{6e4}', WC_Extend), ('\\u{6e5}',\n        '\\u{6e6}', WC_ALetter), ('\\u{6e7}', '\\u{6e8}', WC_Extend), ('\\u{6ea}', '\\u{6ed}',\n        WC_Extend), ('\\u{6ee}', '\\u{6ef}', WC_ALetter), ('\\u{6f0}', '\\u{6f9}', WC_Numeric),\n        ('\\u{6fa}', '\\u{6fc}', WC_ALetter), ('\\u{6ff}', '\\u{6ff}', WC_ALetter), ('\\u{70f}',\n        '\\u{710}', WC_ALetter), ('\\u{711}', '\\u{711}', WC_Extend), ('\\u{712}', '\\u{72f}',\n        WC_ALetter), ('\\u{730}', '\\u{74a}', WC_Extend), ('\\u{74d}', '\\u{7a5}', WC_ALetter),\n        ('\\u{7a6}', '\\u{7b0}', WC_Extend), ('\\u{7b1}', '\\u{7b1}', WC_ALetter), ('\\u{7c0}',\n        '\\u{7c9}', WC_Numeric), ('\\u{7ca}', '\\u{7ea}', WC_ALetter), ('\\u{7eb}', '\\u{7f3}',\n        WC_Extend), ('\\u{7f4}', '\\u{7f5}', WC_ALetter), ('\\u{7f8}', '\\u{7f8}', WC_MidNum),\n        ('\\u{7fa}', '\\u{7fa}', WC_ALetter), ('\\u{7fd}', '\\u{7fd}', WC_Extend), ('\\u{800}',\n        '\\u{815}', WC_ALetter), ('\\u{816}', '\\u{819}', WC_Extend), ('\\u{81a}', '\\u{81a}',\n        WC_ALetter), ('\\u{81b}', '\\u{823}', WC_Extend), ('\\u{824}', '\\u{824}', WC_ALetter),\n        ('\\u{825}', '\\u{827}', WC_Extend), ('\\u{828}', '\\u{828}', WC_ALetter), ('\\u{829}',\n        '\\u{82d}', WC_Extend), ('\\u{840}', '\\u{858}', WC_ALetter), ('\\u{859}', '\\u{85b}',\n        WC_Extend), ('\\u{860}', '\\u{86a}', WC_ALetter), ('\\u{870}', '\\u{887}', WC_ALetter),\n        ('\\u{889}', '\\u{88f}', WC_ALetter), ('\\u{890}', '\\u{891}', WC_Numeric), ('\\u{897}',\n        '\\u{89f}', WC_Extend), ('\\u{8a0}', '\\u{8c9}', WC_ALetter), ('\\u{8ca}', '\\u{8e1}',\n        WC_Extend), ('\\u{8e2}', '\\u{8e2}', WC_Numeric), ('\\u{8e3}', '\\u{903}', WC_Extend),\n        ('\\u{904}', '\\u{939}', WC_ALetter), ('\\u{93a}', '\\u{93c}', WC_Extend), ('\\u{93d}',\n        '\\u{93d}', WC_ALetter), ('\\u{93e}', '\\u{94f}', WC_Extend), ('\\u{950}', '\\u{950}',\n        WC_ALetter), ('\\u{951}', '\\u{957}', WC_Extend), ('\\u{958}', '\\u{961}', WC_ALetter),\n        ('\\u{962}', '\\u{963}', WC_Extend), ('\\u{966}', '\\u{96f}', WC_Numeric), ('\\u{971}',\n        '\\u{980}', WC_ALetter), ('\\u{981}', '\\u{983}', WC_Extend), ('\\u{985}', '\\u{98c}',\n        WC_ALetter), ('\\u{98f}', '\\u{990}', WC_ALetter), ('\\u{993}', '\\u{9a8}', WC_ALetter),\n        ('\\u{9aa}', '\\u{9b0}', WC_ALetter), ('\\u{9b2}', '\\u{9b2}', WC_ALetter), ('\\u{9b6}',\n        '\\u{9b9}', WC_ALetter), ('\\u{9bc}', '\\u{9bc}', WC_Extend), ('\\u{9bd}', '\\u{9bd}',\n        WC_ALetter), ('\\u{9be}', '\\u{9c4}', WC_Extend), ('\\u{9c7}', '\\u{9c8}', WC_Extend),\n        ('\\u{9cb}', '\\u{9cd}', WC_Extend), ('\\u{9ce}', '\\u{9ce}', WC_ALetter), ('\\u{9d7}',\n        '\\u{9d7}', WC_Extend), ('\\u{9dc}', '\\u{9dd}', WC_ALetter), ('\\u{9df}', '\\u{9e1}',\n        WC_ALetter), ('\\u{9e2}', '\\u{9e3}', WC_Extend), ('\\u{9e6}', '\\u{9ef}', WC_Numeric),\n        ('\\u{9f0}', '\\u{9f1}', WC_ALetter), ('\\u{9fc}', '\\u{9fc}', WC_ALetter), ('\\u{9fe}',\n        '\\u{9fe}', WC_Extend), ('\\u{a01}', '\\u{a03}', WC_Extend), ('\\u{a05}', '\\u{a0a}',\n        WC_ALetter), ('\\u{a0f}', '\\u{a10}', WC_ALetter), ('\\u{a13}', '\\u{a28}', WC_ALetter),\n        ('\\u{a2a}', '\\u{a30}', WC_ALetter), ('\\u{a32}', '\\u{a33}', WC_ALetter), ('\\u{a35}',\n        '\\u{a36}', WC_ALetter), ('\\u{a38}', '\\u{a39}', WC_ALetter), ('\\u{a3c}', '\\u{a3c}',\n        WC_Extend), ('\\u{a3e}', '\\u{a42}', WC_Extend), ('\\u{a47}', '\\u{a48}', WC_Extend),\n        ('\\u{a4b}', '\\u{a4d}', WC_Extend), ('\\u{a51}', '\\u{a51}', WC_Extend), ('\\u{a59}', '\\u{a5c}',\n        WC_ALetter), ('\\u{a5e}', '\\u{a5e}', WC_ALetter), ('\\u{a66}', '\\u{a6f}', WC_Numeric),\n        ('\\u{a70}', '\\u{a71}', WC_Extend), ('\\u{a72}', '\\u{a74}', WC_ALetter), ('\\u{a75}',\n        '\\u{a75}', WC_Extend), ('\\u{a81}', '\\u{a83}', WC_Extend), ('\\u{a85}', '\\u{a8d}',\n        WC_ALetter), ('\\u{a8f}', '\\u{a91}', WC_ALetter), ('\\u{a93}', '\\u{aa8}', WC_ALetter),\n        ('\\u{aaa}', '\\u{ab0}', WC_ALetter), ('\\u{ab2}', '\\u{ab3}', WC_ALetter), ('\\u{ab5}',\n        '\\u{ab9}', WC_ALetter), ('\\u{abc}', '\\u{abc}', WC_Extend), ('\\u{abd}', '\\u{abd}',\n        WC_ALetter), ('\\u{abe}', '\\u{ac5}', WC_Extend), ('\\u{ac7}', '\\u{ac9}', WC_Extend),\n        ('\\u{acb}', '\\u{acd}', WC_Extend), ('\\u{ad0}', '\\u{ad0}', WC_ALetter), ('\\u{ae0}',\n        '\\u{ae1}', WC_ALetter), ('\\u{ae2}', '\\u{ae3}', WC_Extend), ('\\u{ae6}', '\\u{aef}',\n        WC_Numeric), ('\\u{af9}', '\\u{af9}', WC_ALetter), ('\\u{afa}', '\\u{aff}', WC_Extend),\n        ('\\u{b01}', '\\u{b03}', WC_Extend), ('\\u{b05}', '\\u{b0c}', WC_ALetter), ('\\u{b0f}',\n        '\\u{b10}', WC_ALetter), ('\\u{b13}', '\\u{b28}', WC_ALetter), ('\\u{b2a}', '\\u{b30}',\n        WC_ALetter), ('\\u{b32}', '\\u{b33}', WC_ALetter), ('\\u{b35}', '\\u{b39}', WC_ALetter),\n        ('\\u{b3c}', '\\u{b3c}', WC_Extend), ('\\u{b3d}', '\\u{b3d}', WC_ALetter), ('\\u{b3e}',\n        '\\u{b44}', WC_Extend), ('\\u{b47}', '\\u{b48}', WC_Extend), ('\\u{b4b}', '\\u{b4d}', WC_Extend),\n        ('\\u{b55}', '\\u{b57}', WC_Extend), ('\\u{b5c}', '\\u{b5d}', WC_ALetter), ('\\u{b5f}',\n        '\\u{b61}', WC_ALetter), ('\\u{b62}', '\\u{b63}', WC_Extend), ('\\u{b66}', '\\u{b6f}',\n        WC_Numeric), ('\\u{b71}', '\\u{b71}', WC_ALetter), ('\\u{b82}', '\\u{b82}', WC_Extend),\n        ('\\u{b83}', '\\u{b83}', WC_ALetter), ('\\u{b85}', '\\u{b8a}', WC_ALetter), ('\\u{b8e}',\n        '\\u{b90}', WC_ALetter), ('\\u{b92}', '\\u{b95}', WC_ALetter), ('\\u{b99}', '\\u{b9a}',\n        WC_ALetter), ('\\u{b9c}', '\\u{b9c}', WC_ALetter), ('\\u{b9e}', '\\u{b9f}', WC_ALetter),\n        ('\\u{ba3}', '\\u{ba4}', WC_ALetter), ('\\u{ba8}', '\\u{baa}', WC_ALetter), ('\\u{bae}',\n        '\\u{bb9}', WC_ALetter), ('\\u{bbe}', '\\u{bc2}', WC_Extend), ('\\u{bc6}', '\\u{bc8}',\n        WC_Extend), ('\\u{bca}', '\\u{bcd}', WC_Extend), ('\\u{bd0}', '\\u{bd0}', WC_ALetter),\n        ('\\u{bd7}', '\\u{bd7}', WC_Extend), ('\\u{be6}', '\\u{bef}', WC_Numeric), ('\\u{c00}',\n        '\\u{c04}', WC_Extend), ('\\u{c05}', '\\u{c0c}', WC_ALetter), ('\\u{c0e}', '\\u{c10}',\n        WC_ALetter), ('\\u{c12}', '\\u{c28}', WC_ALetter), ('\\u{c2a}', '\\u{c39}', WC_ALetter),\n        ('\\u{c3c}', '\\u{c3c}', WC_Extend), ('\\u{c3d}', '\\u{c3d}', WC_ALetter), ('\\u{c3e}',\n        '\\u{c44}', WC_Extend), ('\\u{c46}', '\\u{c48}', WC_Extend), ('\\u{c4a}', '\\u{c4d}', WC_Extend),\n        ('\\u{c55}', '\\u{c56}', WC_Extend), ('\\u{c58}', '\\u{c5a}', WC_ALetter), ('\\u{c5c}',\n        '\\u{c5d}', WC_ALetter), ('\\u{c60}', '\\u{c61}', WC_ALetter), ('\\u{c62}', '\\u{c63}',\n        WC_Extend), ('\\u{c66}', '\\u{c6f}', WC_Numeric), ('\\u{c80}', '\\u{c80}', WC_ALetter),\n        ('\\u{c81}', '\\u{c83}', WC_Extend), ('\\u{c85}', '\\u{c8c}', WC_ALetter), ('\\u{c8e}',\n        '\\u{c90}', WC_ALetter), ('\\u{c92}', '\\u{ca8}', WC_ALetter), ('\\u{caa}', '\\u{cb3}',\n        WC_ALetter), ('\\u{cb5}', '\\u{cb9}', WC_ALetter), ('\\u{cbc}', '\\u{cbc}', WC_Extend),\n        ('\\u{cbd}', '\\u{cbd}', WC_ALetter), ('\\u{cbe}', '\\u{cc4}', WC_Extend), ('\\u{cc6}',\n        '\\u{cc8}', WC_Extend), ('\\u{cca}', '\\u{ccd}', WC_Extend), ('\\u{cd5}', '\\u{cd6}', WC_Extend),\n        ('\\u{cdc}', '\\u{cde}', WC_ALetter), ('\\u{ce0}', '\\u{ce1}', WC_ALetter), ('\\u{ce2}',\n        '\\u{ce3}', WC_Extend), ('\\u{ce6}', '\\u{cef}', WC_Numeric), ('\\u{cf1}', '\\u{cf2}',\n        WC_ALetter), ('\\u{cf3}', '\\u{cf3}', WC_Extend), ('\\u{d00}', '\\u{d03}', WC_Extend),\n        ('\\u{d04}', '\\u{d0c}', WC_ALetter), ('\\u{d0e}', '\\u{d10}', WC_ALetter), ('\\u{d12}',\n        '\\u{d3a}', WC_ALetter), ('\\u{d3b}', '\\u{d3c}', WC_Extend), ('\\u{d3d}', '\\u{d3d}',\n        WC_ALetter), ('\\u{d3e}', '\\u{d44}', WC_Extend), ('\\u{d46}', '\\u{d48}', WC_Extend),\n        ('\\u{d4a}', '\\u{d4d}', WC_Extend), ('\\u{d4e}', '\\u{d4e}', WC_ALetter), ('\\u{d54}',\n        '\\u{d56}', WC_ALetter), ('\\u{d57}', '\\u{d57}', WC_Extend), ('\\u{d5f}', '\\u{d61}',\n        WC_ALetter), ('\\u{d62}', '\\u{d63}', WC_Extend), ('\\u{d66}', '\\u{d6f}', WC_Numeric),\n        ('\\u{d7a}', '\\u{d7f}', WC_ALetter), ('\\u{d81}', '\\u{d83}', WC_Extend), ('\\u{d85}',\n        '\\u{d96}', WC_ALetter), ('\\u{d9a}', '\\u{db1}', WC_ALetter), ('\\u{db3}', '\\u{dbb}',\n        WC_ALetter), ('\\u{dbd}', '\\u{dbd}', WC_ALetter), ('\\u{dc0}', '\\u{dc6}', WC_ALetter),\n        ('\\u{dca}', '\\u{dca}', WC_Extend), ('\\u{dcf}', '\\u{dd4}', WC_Extend), ('\\u{dd6}', '\\u{dd6}',\n        WC_Extend), ('\\u{dd8}', '\\u{ddf}', WC_Extend), ('\\u{de6}', '\\u{def}', WC_Numeric),\n        ('\\u{df2}', '\\u{df3}', WC_Extend), ('\\u{e31}', '\\u{e31}', WC_Extend), ('\\u{e34}', '\\u{e3a}',\n        WC_Extend), ('\\u{e47}', '\\u{e4e}', WC_Extend), ('\\u{e50}', '\\u{e59}', WC_Numeric),\n        ('\\u{eb1}', '\\u{eb1}', WC_Extend), ('\\u{eb4}', '\\u{ebc}', WC_Extend), ('\\u{ec8}', '\\u{ece}',\n        WC_Extend), ('\\u{ed0}', '\\u{ed9}', WC_Numeric), ('\\u{f00}', '\\u{f00}', WC_ALetter),\n        ('\\u{f18}', '\\u{f19}', WC_Extend), ('\\u{f20}', '\\u{f29}', WC_Numeric), ('\\u{f35}',\n        '\\u{f35}', WC_Extend), ('\\u{f37}', '\\u{f37}', WC_Extend), ('\\u{f39}', '\\u{f39}', WC_Extend),\n        ('\\u{f3e}', '\\u{f3f}', WC_Extend), ('\\u{f40}', '\\u{f47}', WC_ALetter), ('\\u{f49}',\n        '\\u{f6c}', WC_ALetter), ('\\u{f71}', '\\u{f84}', WC_Extend), ('\\u{f86}', '\\u{f87}',\n        WC_Extend), ('\\u{f88}', '\\u{f8c}', WC_ALetter), ('\\u{f8d}', '\\u{f97}', WC_Extend),\n        ('\\u{f99}', '\\u{fbc}', WC_Extend), ('\\u{fc6}', '\\u{fc6}', WC_Extend), ('\\u{102b}',\n        '\\u{103e}', WC_Extend), ('\\u{1040}', '\\u{1049}', WC_Numeric), ('\\u{1056}', '\\u{1059}',\n        WC_Extend), ('\\u{105e}', '\\u{1060}', WC_Extend), ('\\u{1062}', '\\u{1064}', WC_Extend),\n        ('\\u{1067}', '\\u{106d}', WC_Extend), ('\\u{1071}', '\\u{1074}', WC_Extend), ('\\u{1082}',\n        '\\u{108d}', WC_Extend), ('\\u{108f}', '\\u{108f}', WC_Extend), ('\\u{1090}', '\\u{1099}',\n        WC_Numeric), ('\\u{109a}', '\\u{109d}', WC_Extend), ('\\u{10a0}', '\\u{10c5}', WC_ALetter),\n        ('\\u{10c7}', '\\u{10c7}', WC_ALetter), ('\\u{10cd}', '\\u{10cd}', WC_ALetter), ('\\u{10d0}',\n        '\\u{10fa}', WC_ALetter), ('\\u{10fc}', '\\u{1248}', WC_ALetter), ('\\u{124a}', '\\u{124d}',\n        WC_ALetter), ('\\u{1250}', '\\u{1256}', WC_ALetter), ('\\u{1258}', '\\u{1258}', WC_ALetter),\n        ('\\u{125a}', '\\u{125d}', WC_ALetter), ('\\u{1260}', '\\u{1288}', WC_ALetter), ('\\u{128a}',\n        '\\u{128d}', WC_ALetter), ('\\u{1290}', '\\u{12b0}', WC_ALetter), ('\\u{12b2}', '\\u{12b5}',\n        WC_ALetter), ('\\u{12b8}', '\\u{12be}', WC_ALetter), ('\\u{12c0}', '\\u{12c0}', WC_ALetter),\n        ('\\u{12c2}', '\\u{12c5}', WC_ALetter), ('\\u{12c8}', '\\u{12d6}', WC_ALetter), ('\\u{12d8}',\n        '\\u{1310}', WC_ALetter), ('\\u{1312}', '\\u{1315}', WC_ALetter), ('\\u{1318}', '\\u{135a}',\n        WC_ALetter), ('\\u{135d}', '\\u{135f}', WC_Extend), ('\\u{1380}', '\\u{138f}', WC_ALetter),\n        ('\\u{13a0}', '\\u{13f5}', WC_ALetter), ('\\u{13f8}', '\\u{13fd}', WC_ALetter), ('\\u{1401}',\n        '\\u{166c}', WC_ALetter), ('\\u{166f}', '\\u{167f}', WC_ALetter), ('\\u{1680}', '\\u{1680}',\n        WC_WSegSpace), ('\\u{1681}', '\\u{169a}', WC_ALetter), ('\\u{16a0}', '\\u{16ea}', WC_ALetter),\n        ('\\u{16ee}', '\\u{16f8}', WC_ALetter), ('\\u{1700}', '\\u{1711}', WC_ALetter), ('\\u{1712}',\n        '\\u{1715}', WC_Extend), ('\\u{171f}', '\\u{1731}', WC_ALetter), ('\\u{1732}', '\\u{1734}',\n        WC_Extend), ('\\u{1740}', '\\u{1751}', WC_ALetter), ('\\u{1752}', '\\u{1753}', WC_Extend),\n        ('\\u{1760}', '\\u{176c}', WC_ALetter), ('\\u{176e}', '\\u{1770}', WC_ALetter), ('\\u{1772}',\n        '\\u{1773}', WC_Extend), ('\\u{17b4}', '\\u{17d3}', WC_Extend), ('\\u{17dd}', '\\u{17dd}',\n        WC_Extend), ('\\u{17e0}', '\\u{17e9}', WC_Numeric), ('\\u{180b}', '\\u{180d}', WC_Extend),\n        ('\\u{180e}', '\\u{180e}', WC_Format), ('\\u{180f}', '\\u{180f}', WC_Extend), ('\\u{1810}',\n        '\\u{1819}', WC_Numeric), ('\\u{1820}', '\\u{1878}', WC_ALetter), ('\\u{1880}', '\\u{1884}',\n        WC_ALetter), ('\\u{1885}', '\\u{1886}', WC_Extend), ('\\u{1887}', '\\u{18a8}', WC_ALetter),\n        ('\\u{18a9}', '\\u{18a9}', WC_Extend), ('\\u{18aa}', '\\u{18aa}', WC_ALetter), ('\\u{18b0}',\n        '\\u{18f5}', WC_ALetter), ('\\u{1900}', '\\u{191e}', WC_ALetter), ('\\u{1920}', '\\u{192b}',\n        WC_Extend), ('\\u{1930}', '\\u{193b}', WC_Extend), ('\\u{1946}', '\\u{194f}', WC_Numeric),\n        ('\\u{19d0}', '\\u{19da}', WC_Numeric), ('\\u{1a00}', '\\u{1a16}', WC_ALetter), ('\\u{1a17}',\n        '\\u{1a1b}', WC_Extend), ('\\u{1a55}', '\\u{1a5e}', WC_Extend), ('\\u{1a60}', '\\u{1a7c}',\n        WC_Extend), ('\\u{1a7f}', '\\u{1a7f}', WC_Extend), ('\\u{1a80}', '\\u{1a89}', WC_Numeric),\n        ('\\u{1a90}', '\\u{1a99}', WC_Numeric), ('\\u{1ab0}', '\\u{1add}', WC_Extend), ('\\u{1ae0}',\n        '\\u{1aeb}', WC_Extend), ('\\u{1b00}', '\\u{1b04}', WC_Extend), ('\\u{1b05}', '\\u{1b33}',\n        WC_ALetter), ('\\u{1b34}', '\\u{1b44}', WC_Extend), ('\\u{1b45}', '\\u{1b4c}', WC_ALetter),\n        ('\\u{1b50}', '\\u{1b59}', WC_Numeric), ('\\u{1b6b}', '\\u{1b73}', WC_Extend), ('\\u{1b80}',\n        '\\u{1b82}', WC_Extend), ('\\u{1b83}', '\\u{1ba0}', WC_ALetter), ('\\u{1ba1}', '\\u{1bad}',\n        WC_Extend), ('\\u{1bae}', '\\u{1baf}', WC_ALetter), ('\\u{1bb0}', '\\u{1bb9}', WC_Numeric),\n        ('\\u{1bba}', '\\u{1be5}', WC_ALetter), ('\\u{1be6}', '\\u{1bf3}', WC_Extend), ('\\u{1c00}',\n        '\\u{1c23}', WC_ALetter), ('\\u{1c24}', '\\u{1c37}', WC_Extend), ('\\u{1c40}', '\\u{1c49}',\n        WC_Numeric), ('\\u{1c4d}', '\\u{1c4f}', WC_ALetter), ('\\u{1c50}', '\\u{1c59}', WC_Numeric),\n        ('\\u{1c5a}', '\\u{1c7d}', WC_ALetter), ('\\u{1c80}', '\\u{1c8a}', WC_ALetter), ('\\u{1c90}',\n        '\\u{1cba}', WC_ALetter), ('\\u{1cbd}', '\\u{1cbf}', WC_ALetter), ('\\u{1cd0}', '\\u{1cd2}',\n        WC_Extend), ('\\u{1cd4}', '\\u{1ce8}', WC_Extend), ('\\u{1ce9}', '\\u{1cec}', WC_ALetter),\n        ('\\u{1ced}', '\\u{1ced}', WC_Extend), ('\\u{1cee}', '\\u{1cf3}', WC_ALetter), ('\\u{1cf4}',\n        '\\u{1cf4}', WC_Extend), ('\\u{1cf5}', '\\u{1cf6}', WC_ALetter), ('\\u{1cf7}', '\\u{1cf9}',\n        WC_Extend), ('\\u{1cfa}', '\\u{1cfa}', WC_ALetter), ('\\u{1d00}', '\\u{1dbf}', WC_ALetter),\n        ('\\u{1dc0}', '\\u{1dff}', WC_Extend), ('\\u{1e00}', '\\u{1f15}', WC_ALetter), ('\\u{1f18}',\n        '\\u{1f1d}', WC_ALetter), ('\\u{1f20}', '\\u{1f45}', WC_ALetter), ('\\u{1f48}', '\\u{1f4d}',\n        WC_ALetter), ('\\u{1f50}', '\\u{1f57}', WC_ALetter), ('\\u{1f59}', '\\u{1f59}', WC_ALetter),\n        ('\\u{1f5b}', '\\u{1f5b}', WC_ALetter), ('\\u{1f5d}', '\\u{1f5d}', WC_ALetter), ('\\u{1f5f}',\n        '\\u{1f7d}', WC_ALetter), ('\\u{1f80}', '\\u{1fb4}', WC_ALetter), ('\\u{1fb6}', '\\u{1fbc}',\n        WC_ALetter), ('\\u{1fbe}', '\\u{1fbe}', WC_ALetter), ('\\u{1fc2}', '\\u{1fc4}', WC_ALetter),\n        ('\\u{1fc6}', '\\u{1fcc}', WC_ALetter), ('\\u{1fd0}', '\\u{1fd3}', WC_ALetter), ('\\u{1fd6}',\n        '\\u{1fdb}', WC_ALetter), ('\\u{1fe0}', '\\u{1fec}', WC_ALetter), ('\\u{1ff2}', '\\u{1ff4}',\n        WC_ALetter), ('\\u{1ff6}', '\\u{1ffc}', WC_ALetter), ('\\u{2000}', '\\u{2006}', WC_WSegSpace),\n        ('\\u{2008}', '\\u{200a}', WC_WSegSpace), ('\\u{200c}', '\\u{200c}', WC_Extend), ('\\u{200d}',\n        '\\u{200d}', WC_ZWJ), ('\\u{200e}', '\\u{200f}', WC_Format), ('\\u{2018}', '\\u{2019}',\n        WC_MidNumLet), ('\\u{2024}', '\\u{2024}', WC_MidNumLet), ('\\u{2027}', '\\u{2027}',\n        WC_MidLetter), ('\\u{2028}', '\\u{2029}', WC_Newline), ('\\u{202a}', '\\u{202e}', WC_Format),\n        ('\\u{202f}', '\\u{202f}', WC_ExtendNumLet), ('\\u{203f}', '\\u{2040}', WC_ExtendNumLet),\n        ('\\u{2044}', '\\u{2044}', WC_MidNum), ('\\u{2054}', '\\u{2054}', WC_ExtendNumLet), ('\\u{205f}',\n        '\\u{205f}', WC_WSegSpace), ('\\u{2060}', '\\u{2064}', WC_Format), ('\\u{2066}', '\\u{206f}',\n        WC_Format), ('\\u{2071}', '\\u{2071}', WC_ALetter), ('\\u{207f}', '\\u{207f}', WC_ALetter),\n        ('\\u{2090}', '\\u{209c}', WC_ALetter), ('\\u{20d0}', '\\u{20f0}', WC_Extend), ('\\u{2102}',\n        '\\u{2102}', WC_ALetter), ('\\u{2107}', '\\u{2107}', WC_ALetter), ('\\u{210a}', '\\u{2113}',\n        WC_ALetter), ('\\u{2115}', '\\u{2115}', WC_ALetter), ('\\u{2119}', '\\u{211d}', WC_ALetter),\n        ('\\u{2124}', '\\u{2124}', WC_ALetter), ('\\u{2126}', '\\u{2126}', WC_ALetter), ('\\u{2128}',\n        '\\u{2128}', WC_ALetter), ('\\u{212a}', '\\u{212d}', WC_ALetter), ('\\u{212f}', '\\u{2139}',\n        WC_ALetter), ('\\u{213c}', '\\u{213f}', WC_ALetter), ('\\u{2145}', '\\u{2149}', WC_ALetter),\n        ('\\u{214e}', '\\u{214e}', WC_ALetter), ('\\u{2160}', '\\u{2188}', WC_ALetter), ('\\u{24b6}',\n        '\\u{24e9}', WC_ALetter), ('\\u{2c00}', '\\u{2ce4}', WC_ALetter), ('\\u{2ceb}', '\\u{2cee}',\n        WC_ALetter), ('\\u{2cef}', '\\u{2cf1}', WC_Extend), ('\\u{2cf2}', '\\u{2cf3}', WC_ALetter),\n        ('\\u{2d00}', '\\u{2d25}', WC_ALetter), ('\\u{2d27}', '\\u{2d27}', WC_ALetter), ('\\u{2d2d}',\n        '\\u{2d2d}', WC_ALetter), ('\\u{2d30}', '\\u{2d67}', WC_ALetter), ('\\u{2d6f}', '\\u{2d6f}',\n        WC_ALetter), ('\\u{2d7f}', '\\u{2d7f}', WC_Extend), ('\\u{2d80}', '\\u{2d96}', WC_ALetter),\n        ('\\u{2da0}', '\\u{2da6}', WC_ALetter), ('\\u{2da8}', '\\u{2dae}', WC_ALetter), ('\\u{2db0}',\n        '\\u{2db6}', WC_ALetter), ('\\u{2db8}', '\\u{2dbe}', WC_ALetter), ('\\u{2dc0}', '\\u{2dc6}',\n        WC_ALetter), ('\\u{2dc8}', '\\u{2dce}', WC_ALetter), ('\\u{2dd0}', '\\u{2dd6}', WC_ALetter),\n        ('\\u{2dd8}', '\\u{2dde}', WC_ALetter), ('\\u{2de0}', '\\u{2dff}', WC_Extend), ('\\u{2e2f}',\n        '\\u{2e2f}', WC_ALetter), ('\\u{3000}', '\\u{3000}', WC_WSegSpace), ('\\u{3005}', '\\u{3005}',\n        WC_ALetter), ('\\u{302a}', '\\u{302f}', WC_Extend), ('\\u{3031}', '\\u{3035}', WC_Katakana),\n        ('\\u{303b}', '\\u{303c}', WC_ALetter), ('\\u{3099}', '\\u{309a}', WC_Extend), ('\\u{309b}',\n        '\\u{309c}', WC_Katakana), ('\\u{30a0}', '\\u{30fa}', WC_Katakana), ('\\u{30fc}', '\\u{30ff}',\n        WC_Katakana), ('\\u{3105}', '\\u{312f}', WC_ALetter), ('\\u{3131}', '\\u{318e}', WC_ALetter),\n        ('\\u{31a0}', '\\u{31bf}', WC_ALetter), ('\\u{31f0}', '\\u{31ff}', WC_Katakana), ('\\u{32d0}',\n        '\\u{32fe}', WC_Katakana), ('\\u{3300}', '\\u{3357}', WC_Katakana), ('\\u{a000}', '\\u{a48c}',\n        WC_ALetter), ('\\u{a4d0}', '\\u{a4fd}', WC_ALetter), ('\\u{a500}', '\\u{a60c}', WC_ALetter),\n        ('\\u{a610}', '\\u{a61f}', WC_ALetter), ('\\u{a620}', '\\u{a629}', WC_Numeric), ('\\u{a62a}',\n        '\\u{a62b}', WC_ALetter), ('\\u{a640}', '\\u{a66e}', WC_ALetter), ('\\u{a66f}', '\\u{a672}',\n        WC_Extend), ('\\u{a674}', '\\u{a67d}', WC_Extend), ('\\u{a67f}', '\\u{a69d}', WC_ALetter),\n        ('\\u{a69e}', '\\u{a69f}', WC_Extend), ('\\u{a6a0}', '\\u{a6ef}', WC_ALetter), ('\\u{a6f0}',\n        '\\u{a6f1}', WC_Extend), ('\\u{a708}', '\\u{a7dc}', WC_ALetter), ('\\u{a7f1}', '\\u{a801}',\n        WC_ALetter), ('\\u{a802}', '\\u{a802}', WC_Extend), ('\\u{a803}', '\\u{a805}', WC_ALetter),\n        ('\\u{a806}', '\\u{a806}', WC_Extend), ('\\u{a807}', '\\u{a80a}', WC_ALetter), ('\\u{a80b}',\n        '\\u{a80b}', WC_Extend), ('\\u{a80c}', '\\u{a822}', WC_ALetter), ('\\u{a823}', '\\u{a827}',\n        WC_Extend), ('\\u{a82c}', '\\u{a82c}', WC_Extend), ('\\u{a840}', '\\u{a873}', WC_ALetter),\n        ('\\u{a880}', '\\u{a881}', WC_Extend), ('\\u{a882}', '\\u{a8b3}', WC_ALetter), ('\\u{a8b4}',\n        '\\u{a8c5}', WC_Extend), ('\\u{a8d0}', '\\u{a8d9}', WC_Numeric), ('\\u{a8e0}', '\\u{a8f1}',\n        WC_Extend), ('\\u{a8f2}', '\\u{a8f7}', WC_ALetter), ('\\u{a8fb}', '\\u{a8fb}', WC_ALetter),\n        ('\\u{a8fd}', '\\u{a8fe}', WC_ALetter), ('\\u{a8ff}', '\\u{a8ff}', WC_Extend), ('\\u{a900}',\n        '\\u{a909}', WC_Numeric), ('\\u{a90a}', '\\u{a925}', WC_ALetter), ('\\u{a926}', '\\u{a92d}',\n        WC_Extend), ('\\u{a930}', '\\u{a946}', WC_ALetter), ('\\u{a947}', '\\u{a953}', WC_Extend),\n        ('\\u{a960}', '\\u{a97c}', WC_ALetter), ('\\u{a980}', '\\u{a983}', WC_Extend), ('\\u{a984}',\n        '\\u{a9b2}', WC_ALetter), ('\\u{a9b3}', '\\u{a9c0}', WC_Extend), ('\\u{a9cf}', '\\u{a9cf}',\n        WC_ALetter), ('\\u{a9d0}', '\\u{a9d9}', WC_Numeric), ('\\u{a9e5}', '\\u{a9e5}', WC_Extend),\n        ('\\u{a9f0}', '\\u{a9f9}', WC_Numeric), ('\\u{aa00}', '\\u{aa28}', WC_ALetter), ('\\u{aa29}',\n        '\\u{aa36}', WC_Extend), ('\\u{aa40}', '\\u{aa42}', WC_ALetter), ('\\u{aa43}', '\\u{aa43}',\n        WC_Extend), ('\\u{aa44}', '\\u{aa4b}', WC_ALetter), ('\\u{aa4c}', '\\u{aa4d}', WC_Extend),\n        ('\\u{aa50}', '\\u{aa59}', WC_Numeric), ('\\u{aa7b}', '\\u{aa7d}', WC_Extend), ('\\u{aab0}',\n        '\\u{aab0}', WC_Extend), ('\\u{aab2}', '\\u{aab4}', WC_Extend), ('\\u{aab7}', '\\u{aab8}',\n        WC_Extend), ('\\u{aabe}', '\\u{aabf}', WC_Extend), ('\\u{aac1}', '\\u{aac1}', WC_Extend),\n        ('\\u{aae0}', '\\u{aaea}', WC_ALetter), ('\\u{aaeb}', '\\u{aaef}', WC_Extend), ('\\u{aaf2}',\n        '\\u{aaf4}', WC_ALetter), ('\\u{aaf5}', '\\u{aaf6}', WC_Extend), ('\\u{ab01}', '\\u{ab06}',\n        WC_ALetter), ('\\u{ab09}', '\\u{ab0e}', WC_ALetter), ('\\u{ab11}', '\\u{ab16}', WC_ALetter),\n        ('\\u{ab20}', '\\u{ab26}', WC_ALetter), ('\\u{ab28}', '\\u{ab2e}', WC_ALetter), ('\\u{ab30}',\n        '\\u{ab69}', WC_ALetter), ('\\u{ab70}', '\\u{abe2}', WC_ALetter), ('\\u{abe3}', '\\u{abea}',\n        WC_Extend), ('\\u{abec}', '\\u{abed}', WC_Extend), ('\\u{abf0}', '\\u{abf9}', WC_Numeric),\n        ('\\u{ac00}', '\\u{d7a3}', WC_ALetter), ('\\u{d7b0}', '\\u{d7c6}', WC_ALetter), ('\\u{d7cb}',\n        '\\u{d7fb}', WC_ALetter), ('\\u{fb00}', '\\u{fb06}', WC_ALetter), ('\\u{fb13}', '\\u{fb17}',\n        WC_ALetter), ('\\u{fb1d}', '\\u{fb1d}', WC_Hebrew_Letter), ('\\u{fb1e}', '\\u{fb1e}',\n        WC_Extend), ('\\u{fb1f}', '\\u{fb28}', WC_Hebrew_Letter), ('\\u{fb2a}', '\\u{fb36}',\n        WC_Hebrew_Letter), ('\\u{fb38}', '\\u{fb3c}', WC_Hebrew_Letter), ('\\u{fb3e}', '\\u{fb3e}',\n        WC_Hebrew_Letter), ('\\u{fb40}', '\\u{fb41}', WC_Hebrew_Letter), ('\\u{fb43}', '\\u{fb44}',\n        WC_Hebrew_Letter), ('\\u{fb46}', '\\u{fb4f}', WC_Hebrew_Letter), ('\\u{fb50}', '\\u{fbb1}',\n        WC_ALetter), ('\\u{fbd3}', '\\u{fd3d}', WC_ALetter), ('\\u{fd50}', '\\u{fd8f}', WC_ALetter),\n        ('\\u{fd92}', '\\u{fdc7}', WC_ALetter), ('\\u{fdf0}', '\\u{fdfb}', WC_ALetter), ('\\u{fe00}',\n        '\\u{fe0f}', WC_Extend), ('\\u{fe13}', '\\u{fe13}', WC_MidLetter), ('\\u{fe20}', '\\u{fe2f}',\n        WC_Extend), ('\\u{fe33}', '\\u{fe34}', WC_ExtendNumLet), ('\\u{fe4d}', '\\u{fe4f}',\n        WC_ExtendNumLet), ('\\u{fe50}', '\\u{fe50}', WC_MidNum), ('\\u{fe52}', '\\u{fe52}',\n        WC_MidNumLet), ('\\u{fe54}', '\\u{fe54}', WC_MidNum), ('\\u{fe55}', '\\u{fe55}', WC_MidLetter),\n        ('\\u{fe70}', '\\u{fe74}', WC_ALetter), ('\\u{fe76}', '\\u{fefc}', WC_ALetter), ('\\u{feff}',\n        '\\u{feff}', WC_Format), ('\\u{ff07}', '\\u{ff07}', WC_MidNumLet), ('\\u{ff0c}', '\\u{ff0c}',\n        WC_MidNum), ('\\u{ff0e}', '\\u{ff0e}', WC_MidNumLet), ('\\u{ff10}', '\\u{ff19}', WC_Numeric),\n        ('\\u{ff1a}', '\\u{ff1a}', WC_MidLetter), ('\\u{ff1b}', '\\u{ff1b}', WC_MidNum), ('\\u{ff21}',\n        '\\u{ff3a}', WC_ALetter), ('\\u{ff3f}', '\\u{ff3f}', WC_ExtendNumLet), ('\\u{ff41}', '\\u{ff5a}',\n        WC_ALetter), ('\\u{ff66}', '\\u{ff9d}', WC_Katakana), ('\\u{ff9e}', '\\u{ff9f}', WC_Extend),\n        ('\\u{ffa0}', '\\u{ffbe}', WC_ALetter), ('\\u{ffc2}', '\\u{ffc7}', WC_ALetter), ('\\u{ffca}',\n        '\\u{ffcf}', WC_ALetter), ('\\u{ffd2}', '\\u{ffd7}', WC_ALetter), ('\\u{ffda}', '\\u{ffdc}',\n        WC_ALetter), ('\\u{fff9}', '\\u{fffb}', WC_Format), ('\\u{10000}', '\\u{1000b}', WC_ALetter),\n        ('\\u{1000d}', '\\u{10026}', WC_ALetter), ('\\u{10028}', '\\u{1003a}', WC_ALetter),\n        ('\\u{1003c}', '\\u{1003d}', WC_ALetter), ('\\u{1003f}', '\\u{1004d}', WC_ALetter),\n        ('\\u{10050}', '\\u{1005d}', WC_ALetter), ('\\u{10080}', '\\u{100fa}', WC_ALetter),\n        ('\\u{10140}', '\\u{10174}', WC_ALetter), ('\\u{101fd}', '\\u{101fd}', WC_Extend), ('\\u{10280}',\n        '\\u{1029c}', WC_ALetter), ('\\u{102a0}', '\\u{102d0}', WC_ALetter), ('\\u{102e0}', '\\u{102e0}',\n        WC_Extend), ('\\u{10300}', '\\u{1031f}', WC_ALetter), ('\\u{1032d}', '\\u{1034a}', WC_ALetter),\n        ('\\u{10350}', '\\u{10375}', WC_ALetter), ('\\u{10376}', '\\u{1037a}', WC_Extend), ('\\u{10380}',\n        '\\u{1039d}', WC_ALetter), ('\\u{103a0}', '\\u{103c3}', WC_ALetter), ('\\u{103c8}', '\\u{103cf}',\n        WC_ALetter), ('\\u{103d1}', '\\u{103d5}', WC_ALetter), ('\\u{10400}', '\\u{1049d}', WC_ALetter),\n        ('\\u{104a0}', '\\u{104a9}', WC_Numeric), ('\\u{104b0}', '\\u{104d3}', WC_ALetter),\n        ('\\u{104d8}', '\\u{104fb}', WC_ALetter), ('\\u{10500}', '\\u{10527}', WC_ALetter),\n        ('\\u{10530}', '\\u{10563}', WC_ALetter), ('\\u{10570}', '\\u{1057a}', WC_ALetter),\n        ('\\u{1057c}', '\\u{1058a}', WC_ALetter), ('\\u{1058c}', '\\u{10592}', WC_ALetter),\n        ('\\u{10594}', '\\u{10595}', WC_ALetter), ('\\u{10597}', '\\u{105a1}', WC_ALetter),\n        ('\\u{105a3}', '\\u{105b1}', WC_ALetter), ('\\u{105b3}', '\\u{105b9}', WC_ALetter),\n        ('\\u{105bb}', '\\u{105bc}', WC_ALetter), ('\\u{105c0}', '\\u{105f3}', WC_ALetter),\n        ('\\u{10600}', '\\u{10736}', WC_ALetter), ('\\u{10740}', '\\u{10755}', WC_ALetter),\n        ('\\u{10760}', '\\u{10767}', WC_ALetter), ('\\u{10780}', '\\u{10785}', WC_ALetter),\n        ('\\u{10787}', '\\u{107b0}', WC_ALetter), ('\\u{107b2}', '\\u{107ba}', WC_ALetter),\n        ('\\u{10800}', '\\u{10805}', WC_ALetter), ('\\u{10808}', '\\u{10808}', WC_ALetter),\n        ('\\u{1080a}', '\\u{10835}', WC_ALetter), ('\\u{10837}', '\\u{10838}', WC_ALetter),\n        ('\\u{1083c}', '\\u{1083c}', WC_ALetter), ('\\u{1083f}', '\\u{10855}', WC_ALetter),\n        ('\\u{10860}', '\\u{10876}', WC_ALetter), ('\\u{10880}', '\\u{1089e}', WC_ALetter),\n        ('\\u{108e0}', '\\u{108f2}', WC_ALetter), ('\\u{108f4}', '\\u{108f5}', WC_ALetter),\n        ('\\u{10900}', '\\u{10915}', WC_ALetter), ('\\u{10920}', '\\u{10939}', WC_ALetter),\n        ('\\u{10940}', '\\u{10959}', WC_ALetter), ('\\u{10980}', '\\u{109b7}', WC_ALetter),\n        ('\\u{109be}', '\\u{109bf}', WC_ALetter), ('\\u{10a00}', '\\u{10a00}', WC_ALetter),\n        ('\\u{10a01}', '\\u{10a03}', WC_Extend), ('\\u{10a05}', '\\u{10a06}', WC_Extend), ('\\u{10a0c}',\n        '\\u{10a0f}', WC_Extend), ('\\u{10a10}', '\\u{10a13}', WC_ALetter), ('\\u{10a15}', '\\u{10a17}',\n        WC_ALetter), ('\\u{10a19}', '\\u{10a35}', WC_ALetter), ('\\u{10a38}', '\\u{10a3a}', WC_Extend),\n        ('\\u{10a3f}', '\\u{10a3f}', WC_Extend), ('\\u{10a60}', '\\u{10a7c}', WC_ALetter), ('\\u{10a80}',\n        '\\u{10a9c}', WC_ALetter), ('\\u{10ac0}', '\\u{10ac7}', WC_ALetter), ('\\u{10ac9}', '\\u{10ae4}',\n        WC_ALetter), ('\\u{10ae5}', '\\u{10ae6}', WC_Extend), ('\\u{10b00}', '\\u{10b35}', WC_ALetter),\n        ('\\u{10b40}', '\\u{10b55}', WC_ALetter), ('\\u{10b60}', '\\u{10b72}', WC_ALetter),\n        ('\\u{10b80}', '\\u{10b91}', WC_ALetter), ('\\u{10c00}', '\\u{10c48}', WC_ALetter),\n        ('\\u{10c80}', '\\u{10cb2}', WC_ALetter), ('\\u{10cc0}', '\\u{10cf2}', WC_ALetter),\n        ('\\u{10d00}', '\\u{10d23}', WC_ALetter), ('\\u{10d24}', '\\u{10d27}', WC_Extend), ('\\u{10d30}',\n        '\\u{10d39}', WC_Numeric), ('\\u{10d40}', '\\u{10d49}', WC_Numeric), ('\\u{10d4a}', '\\u{10d65}',\n        WC_ALetter), ('\\u{10d69}', '\\u{10d6d}', WC_Extend), ('\\u{10d6f}', '\\u{10d85}', WC_ALetter),\n        ('\\u{10e80}', '\\u{10ea9}', WC_ALetter), ('\\u{10eab}', '\\u{10eac}', WC_Extend), ('\\u{10eb0}',\n        '\\u{10eb1}', WC_ALetter), ('\\u{10ec2}', '\\u{10ec7}', WC_ALetter), ('\\u{10efa}', '\\u{10eff}',\n        WC_Extend), ('\\u{10f00}', '\\u{10f1c}', WC_ALetter), ('\\u{10f27}', '\\u{10f27}', WC_ALetter),\n        ('\\u{10f30}', '\\u{10f45}', WC_ALetter), ('\\u{10f46}', '\\u{10f50}', WC_Extend), ('\\u{10f70}',\n        '\\u{10f81}', WC_ALetter), ('\\u{10f82}', '\\u{10f85}', WC_Extend), ('\\u{10fb0}', '\\u{10fc4}',\n        WC_ALetter), ('\\u{10fe0}', '\\u{10ff6}', WC_ALetter), ('\\u{11000}', '\\u{11002}', WC_Extend),\n        ('\\u{11003}', '\\u{11037}', WC_ALetter), ('\\u{11038}', '\\u{11046}', WC_Extend), ('\\u{11066}',\n        '\\u{1106f}', WC_Numeric), ('\\u{11070}', '\\u{11070}', WC_Extend), ('\\u{11071}', '\\u{11072}',\n        WC_ALetter), ('\\u{11073}', '\\u{11074}', WC_Extend), ('\\u{11075}', '\\u{11075}', WC_ALetter),\n        ('\\u{1107f}', '\\u{11082}', WC_Extend), ('\\u{11083}', '\\u{110af}', WC_ALetter), ('\\u{110b0}',\n        '\\u{110ba}', WC_Extend), ('\\u{110bd}', '\\u{110bd}', WC_Numeric), ('\\u{110c2}', '\\u{110c2}',\n        WC_Extend), ('\\u{110cd}', '\\u{110cd}', WC_Numeric), ('\\u{110d0}', '\\u{110e8}', WC_ALetter),\n        ('\\u{110f0}', '\\u{110f9}', WC_Numeric), ('\\u{11100}', '\\u{11102}', WC_Extend), ('\\u{11103}',\n        '\\u{11126}', WC_ALetter), ('\\u{11127}', '\\u{11134}', WC_Extend), ('\\u{11136}', '\\u{1113f}',\n        WC_Numeric), ('\\u{11144}', '\\u{11144}', WC_ALetter), ('\\u{11145}', '\\u{11146}', WC_Extend),\n        ('\\u{11147}', '\\u{11147}', WC_ALetter), ('\\u{11150}', '\\u{11172}', WC_ALetter),\n        ('\\u{11173}', '\\u{11173}', WC_Extend), ('\\u{11176}', '\\u{11176}', WC_ALetter), ('\\u{11180}',\n        '\\u{11182}', WC_Extend), ('\\u{11183}', '\\u{111b2}', WC_ALetter), ('\\u{111b3}', '\\u{111c0}',\n        WC_Extend), ('\\u{111c1}', '\\u{111c4}', WC_ALetter), ('\\u{111c9}', '\\u{111cc}', WC_Extend),\n        ('\\u{111ce}', '\\u{111cf}', WC_Extend), ('\\u{111d0}', '\\u{111d9}', WC_Numeric), ('\\u{111da}',\n        '\\u{111da}', WC_ALetter), ('\\u{111dc}', '\\u{111dc}', WC_ALetter), ('\\u{11200}', '\\u{11211}',\n        WC_ALetter), ('\\u{11213}', '\\u{1122b}', WC_ALetter), ('\\u{1122c}', '\\u{11237}', WC_Extend),\n        ('\\u{1123e}', '\\u{1123e}', WC_Extend), ('\\u{1123f}', '\\u{11240}', WC_ALetter), ('\\u{11241}',\n        '\\u{11241}', WC_Extend), ('\\u{11280}', '\\u{11286}', WC_ALetter), ('\\u{11288}', '\\u{11288}',\n        WC_ALetter), ('\\u{1128a}', '\\u{1128d}', WC_ALetter), ('\\u{1128f}', '\\u{1129d}', WC_ALetter),\n        ('\\u{1129f}', '\\u{112a8}', WC_ALetter), ('\\u{112b0}', '\\u{112de}', WC_ALetter),\n        ('\\u{112df}', '\\u{112ea}', WC_Extend), ('\\u{112f0}', '\\u{112f9}', WC_Numeric), ('\\u{11300}',\n        '\\u{11303}', WC_Extend), ('\\u{11305}', '\\u{1130c}', WC_ALetter), ('\\u{1130f}', '\\u{11310}',\n        WC_ALetter), ('\\u{11313}', '\\u{11328}', WC_ALetter), ('\\u{1132a}', '\\u{11330}', WC_ALetter),\n        ('\\u{11332}', '\\u{11333}', WC_ALetter), ('\\u{11335}', '\\u{11339}', WC_ALetter),\n        ('\\u{1133b}', '\\u{1133c}', WC_Extend), ('\\u{1133d}', '\\u{1133d}', WC_ALetter), ('\\u{1133e}',\n        '\\u{11344}', WC_Extend), ('\\u{11347}', '\\u{11348}', WC_Extend), ('\\u{1134b}', '\\u{1134d}',\n        WC_Extend), ('\\u{11350}', '\\u{11350}', WC_ALetter), ('\\u{11357}', '\\u{11357}', WC_Extend),\n        ('\\u{1135d}', '\\u{11361}', WC_ALetter), ('\\u{11362}', '\\u{11363}', WC_Extend), ('\\u{11366}',\n        '\\u{1136c}', WC_Extend), ('\\u{11370}', '\\u{11374}', WC_Extend), ('\\u{11380}', '\\u{11389}',\n        WC_ALetter), ('\\u{1138b}', '\\u{1138b}', WC_ALetter), ('\\u{1138e}', '\\u{1138e}', WC_ALetter),\n        ('\\u{11390}', '\\u{113b5}', WC_ALetter), ('\\u{113b7}', '\\u{113b7}', WC_ALetter),\n        ('\\u{113b8}', '\\u{113c0}', WC_Extend), ('\\u{113c2}', '\\u{113c2}', WC_Extend), ('\\u{113c5}',\n        '\\u{113c5}', WC_Extend), ('\\u{113c7}', '\\u{113ca}', WC_Extend), ('\\u{113cc}', '\\u{113d0}',\n        WC_Extend), ('\\u{113d1}', '\\u{113d1}', WC_ALetter), ('\\u{113d2}', '\\u{113d2}', WC_Extend),\n        ('\\u{113d3}', '\\u{113d3}', WC_ALetter), ('\\u{113e1}', '\\u{113e2}', WC_Extend), ('\\u{11400}',\n        '\\u{11434}', WC_ALetter), ('\\u{11435}', '\\u{11446}', WC_Extend), ('\\u{11447}', '\\u{1144a}',\n        WC_ALetter), ('\\u{11450}', '\\u{11459}', WC_Numeric), ('\\u{1145e}', '\\u{1145e}', WC_Extend),\n        ('\\u{1145f}', '\\u{11461}', WC_ALetter), ('\\u{11480}', '\\u{114af}', WC_ALetter),\n        ('\\u{114b0}', '\\u{114c3}', WC_Extend), ('\\u{114c4}', '\\u{114c5}', WC_ALetter), ('\\u{114c7}',\n        '\\u{114c7}', WC_ALetter), ('\\u{114d0}', '\\u{114d9}', WC_Numeric), ('\\u{11580}', '\\u{115ae}',\n        WC_ALetter), ('\\u{115af}', '\\u{115b5}', WC_Extend), ('\\u{115b8}', '\\u{115c0}', WC_Extend),\n        ('\\u{115d8}', '\\u{115db}', WC_ALetter), ('\\u{115dc}', '\\u{115dd}', WC_Extend), ('\\u{11600}',\n        '\\u{1162f}', WC_ALetter), ('\\u{11630}', '\\u{11640}', WC_Extend), ('\\u{11644}', '\\u{11644}',\n        WC_ALetter), ('\\u{11650}', '\\u{11659}', WC_Numeric), ('\\u{11680}', '\\u{116aa}', WC_ALetter),\n        ('\\u{116ab}', '\\u{116b7}', WC_Extend), ('\\u{116b8}', '\\u{116b8}', WC_ALetter), ('\\u{116c0}',\n        '\\u{116c9}', WC_Numeric), ('\\u{116d0}', '\\u{116e3}', WC_Numeric), ('\\u{1171d}', '\\u{1172b}',\n        WC_Extend), ('\\u{11730}', '\\u{11739}', WC_Numeric), ('\\u{11800}', '\\u{1182b}', WC_ALetter),\n        ('\\u{1182c}', '\\u{1183a}', WC_Extend), ('\\u{118a0}', '\\u{118df}', WC_ALetter), ('\\u{118e0}',\n        '\\u{118e9}', WC_Numeric), ('\\u{118ff}', '\\u{11906}', WC_ALetter), ('\\u{11909}', '\\u{11909}',\n        WC_ALetter), ('\\u{1190c}', '\\u{11913}', WC_ALetter), ('\\u{11915}', '\\u{11916}', WC_ALetter),\n        ('\\u{11918}', '\\u{1192f}', WC_ALetter), ('\\u{11930}', '\\u{11935}', WC_Extend), ('\\u{11937}',\n        '\\u{11938}', WC_Extend), ('\\u{1193b}', '\\u{1193e}', WC_Extend), ('\\u{1193f}', '\\u{1193f}',\n        WC_ALetter), ('\\u{11940}', '\\u{11940}', WC_Extend), ('\\u{11941}', '\\u{11941}', WC_ALetter),\n        ('\\u{11942}', '\\u{11943}', WC_Extend), ('\\u{11950}', '\\u{11959}', WC_Numeric), ('\\u{119a0}',\n        '\\u{119a7}', WC_ALetter), ('\\u{119aa}', '\\u{119d0}', WC_ALetter), ('\\u{119d1}', '\\u{119d7}',\n        WC_Extend), ('\\u{119da}', '\\u{119e0}', WC_Extend), ('\\u{119e1}', '\\u{119e1}', WC_ALetter),\n        ('\\u{119e3}', '\\u{119e3}', WC_ALetter), ('\\u{119e4}', '\\u{119e4}', WC_Extend), ('\\u{11a00}',\n        '\\u{11a00}', WC_ALetter), ('\\u{11a01}', '\\u{11a0a}', WC_Extend), ('\\u{11a0b}', '\\u{11a32}',\n        WC_ALetter), ('\\u{11a33}', '\\u{11a39}', WC_Extend), ('\\u{11a3a}', '\\u{11a3a}', WC_ALetter),\n        ('\\u{11a3b}', '\\u{11a3e}', WC_Extend), ('\\u{11a47}', '\\u{11a47}', WC_Extend), ('\\u{11a50}',\n        '\\u{11a50}', WC_ALetter), ('\\u{11a51}', '\\u{11a5b}', WC_Extend), ('\\u{11a5c}', '\\u{11a89}',\n        WC_ALetter), ('\\u{11a8a}', '\\u{11a99}', WC_Extend), ('\\u{11a9d}', '\\u{11a9d}', WC_ALetter),\n        ('\\u{11ab0}', '\\u{11af8}', WC_ALetter), ('\\u{11b60}', '\\u{11b67}', WC_Extend), ('\\u{11bc0}',\n        '\\u{11be0}', WC_ALetter), ('\\u{11bf0}', '\\u{11bf9}', WC_Numeric), ('\\u{11c00}', '\\u{11c08}',\n        WC_ALetter), ('\\u{11c0a}', '\\u{11c2e}', WC_ALetter), ('\\u{11c2f}', '\\u{11c36}', WC_Extend),\n        ('\\u{11c38}', '\\u{11c3f}', WC_Extend), ('\\u{11c40}', '\\u{11c40}', WC_ALetter), ('\\u{11c50}',\n        '\\u{11c59}', WC_Numeric), ('\\u{11c72}', '\\u{11c8f}', WC_ALetter), ('\\u{11c92}', '\\u{11ca7}',\n        WC_Extend), ('\\u{11ca9}', '\\u{11cb6}', WC_Extend), ('\\u{11d00}', '\\u{11d06}', WC_ALetter),\n        ('\\u{11d08}', '\\u{11d09}', WC_ALetter), ('\\u{11d0b}', '\\u{11d30}', WC_ALetter),\n        ('\\u{11d31}', '\\u{11d36}', WC_Extend), ('\\u{11d3a}', '\\u{11d3a}', WC_Extend), ('\\u{11d3c}',\n        '\\u{11d3d}', WC_Extend), ('\\u{11d3f}', '\\u{11d45}', WC_Extend), ('\\u{11d46}', '\\u{11d46}',\n        WC_ALetter), ('\\u{11d47}', '\\u{11d47}', WC_Extend), ('\\u{11d50}', '\\u{11d59}', WC_Numeric),\n        ('\\u{11d60}', '\\u{11d65}', WC_ALetter), ('\\u{11d67}', '\\u{11d68}', WC_ALetter),\n        ('\\u{11d6a}', '\\u{11d89}', WC_ALetter), ('\\u{11d8a}', '\\u{11d8e}', WC_Extend), ('\\u{11d90}',\n        '\\u{11d91}', WC_Extend), ('\\u{11d93}', '\\u{11d97}', WC_Extend), ('\\u{11d98}', '\\u{11d98}',\n        WC_ALetter), ('\\u{11da0}', '\\u{11da9}', WC_Numeric), ('\\u{11db0}', '\\u{11ddb}', WC_ALetter),\n        ('\\u{11de0}', '\\u{11de9}', WC_Numeric), ('\\u{11ee0}', '\\u{11ef2}', WC_ALetter),\n        ('\\u{11ef3}', '\\u{11ef6}', WC_Extend), ('\\u{11f00}', '\\u{11f01}', WC_Extend), ('\\u{11f02}',\n        '\\u{11f02}', WC_ALetter), ('\\u{11f03}', '\\u{11f03}', WC_Extend), ('\\u{11f04}', '\\u{11f10}',\n        WC_ALetter), ('\\u{11f12}', '\\u{11f33}', WC_ALetter), ('\\u{11f34}', '\\u{11f3a}', WC_Extend),\n        ('\\u{11f3e}', '\\u{11f42}', WC_Extend), ('\\u{11f50}', '\\u{11f59}', WC_Numeric), ('\\u{11f5a}',\n        '\\u{11f5a}', WC_Extend), ('\\u{11fb0}', '\\u{11fb0}', WC_ALetter), ('\\u{12000}', '\\u{12399}',\n        WC_ALetter), ('\\u{12400}', '\\u{1246e}', WC_ALetter), ('\\u{12480}', '\\u{12543}', WC_ALetter),\n        ('\\u{12f90}', '\\u{12ff0}', WC_ALetter), ('\\u{13000}', '\\u{1342f}', WC_ALetter),\n        ('\\u{13430}', '\\u{1343f}', WC_Format), ('\\u{13440}', '\\u{13440}', WC_Extend), ('\\u{13441}',\n        '\\u{13446}', WC_ALetter), ('\\u{13447}', '\\u{13455}', WC_Extend), ('\\u{13460}', '\\u{143fa}',\n        WC_ALetter), ('\\u{14400}', '\\u{14646}', WC_ALetter), ('\\u{16100}', '\\u{1611d}', WC_ALetter),\n        ('\\u{1611e}', '\\u{1612f}', WC_Extend), ('\\u{16130}', '\\u{16139}', WC_Numeric), ('\\u{16800}',\n        '\\u{16a38}', WC_ALetter), ('\\u{16a40}', '\\u{16a5e}', WC_ALetter), ('\\u{16a60}', '\\u{16a69}',\n        WC_Numeric), ('\\u{16a70}', '\\u{16abe}', WC_ALetter), ('\\u{16ac0}', '\\u{16ac9}', WC_Numeric),\n        ('\\u{16ad0}', '\\u{16aed}', WC_ALetter), ('\\u{16af0}', '\\u{16af4}', WC_Extend), ('\\u{16b00}',\n        '\\u{16b2f}', WC_ALetter), ('\\u{16b30}', '\\u{16b36}', WC_Extend), ('\\u{16b40}', '\\u{16b43}',\n        WC_ALetter), ('\\u{16b50}', '\\u{16b59}', WC_Numeric), ('\\u{16b63}', '\\u{16b77}', WC_ALetter),\n        ('\\u{16b7d}', '\\u{16b8f}', WC_ALetter), ('\\u{16d40}', '\\u{16d6c}', WC_ALetter),\n        ('\\u{16d70}', '\\u{16d79}', WC_Numeric), ('\\u{16e40}', '\\u{16e7f}', WC_ALetter),\n        ('\\u{16ea0}', '\\u{16eb8}', WC_ALetter), ('\\u{16ebb}', '\\u{16ed3}', WC_ALetter),\n        ('\\u{16f00}', '\\u{16f4a}', WC_ALetter), ('\\u{16f4f}', '\\u{16f4f}', WC_Extend), ('\\u{16f50}',\n        '\\u{16f50}', WC_ALetter), ('\\u{16f51}', '\\u{16f87}', WC_Extend), ('\\u{16f8f}', '\\u{16f92}',\n        WC_Extend), ('\\u{16f93}', '\\u{16f9f}', WC_ALetter), ('\\u{16fe0}', '\\u{16fe1}', WC_ALetter),\n        ('\\u{16fe3}', '\\u{16fe3}', WC_ALetter), ('\\u{16fe4}', '\\u{16fe4}', WC_Extend), ('\\u{16ff0}',\n        '\\u{16ff1}', WC_Extend), ('\\u{1aff0}', '\\u{1aff3}', WC_Katakana), ('\\u{1aff5}', '\\u{1affb}',\n        WC_Katakana), ('\\u{1affd}', '\\u{1affe}', WC_Katakana), ('\\u{1b000}', '\\u{1b000}',\n        WC_Katakana), ('\\u{1b120}', '\\u{1b122}', WC_Katakana), ('\\u{1b155}', '\\u{1b155}',\n        WC_Katakana), ('\\u{1b164}', '\\u{1b167}', WC_Katakana), ('\\u{1bc00}', '\\u{1bc6a}',\n        WC_ALetter), ('\\u{1bc70}', '\\u{1bc7c}', WC_ALetter), ('\\u{1bc80}', '\\u{1bc88}', WC_ALetter),\n        ('\\u{1bc90}', '\\u{1bc99}', WC_ALetter), ('\\u{1bc9d}', '\\u{1bc9e}', WC_Extend), ('\\u{1bca0}',\n        '\\u{1bca3}', WC_Format), ('\\u{1ccf0}', '\\u{1ccf9}', WC_Numeric), ('\\u{1cf00}', '\\u{1cf2d}',\n        WC_Extend), ('\\u{1cf30}', '\\u{1cf46}', WC_Extend), ('\\u{1d165}', '\\u{1d169}', WC_Extend),\n        ('\\u{1d16d}', '\\u{1d172}', WC_Extend), ('\\u{1d173}', '\\u{1d17a}', WC_Format), ('\\u{1d17b}',\n        '\\u{1d182}', WC_Extend), ('\\u{1d185}', '\\u{1d18b}', WC_Extend), ('\\u{1d1aa}', '\\u{1d1ad}',\n        WC_Extend), ('\\u{1d242}', '\\u{1d244}', WC_Extend), ('\\u{1d400}', '\\u{1d454}', WC_ALetter),\n        ('\\u{1d456}', '\\u{1d49c}', WC_ALetter), ('\\u{1d49e}', '\\u{1d49f}', WC_ALetter),\n        ('\\u{1d4a2}', '\\u{1d4a2}', WC_ALetter), ('\\u{1d4a5}', '\\u{1d4a6}', WC_ALetter),\n        ('\\u{1d4a9}', '\\u{1d4ac}', WC_ALetter), ('\\u{1d4ae}', '\\u{1d4b9}', WC_ALetter),\n        ('\\u{1d4bb}', '\\u{1d4bb}', WC_ALetter), ('\\u{1d4bd}', '\\u{1d4c3}', WC_ALetter),\n        ('\\u{1d4c5}', '\\u{1d505}', WC_ALetter), ('\\u{1d507}', '\\u{1d50a}', WC_ALetter),\n        ('\\u{1d50d}', '\\u{1d514}', WC_ALetter), ('\\u{1d516}', '\\u{1d51c}', WC_ALetter),\n        ('\\u{1d51e}', '\\u{1d539}', WC_ALetter), ('\\u{1d53b}', '\\u{1d53e}', WC_ALetter),\n        ('\\u{1d540}', '\\u{1d544}', WC_ALetter), ('\\u{1d546}', '\\u{1d546}', WC_ALetter),\n        ('\\u{1d54a}', '\\u{1d550}', WC_ALetter), ('\\u{1d552}', '\\u{1d6a5}', WC_ALetter),\n        ('\\u{1d6a8}', '\\u{1d6c0}', WC_ALetter), ('\\u{1d6c2}', '\\u{1d6da}', WC_ALetter),\n        ('\\u{1d6dc}', '\\u{1d6fa}', WC_ALetter), ('\\u{1d6fc}', '\\u{1d714}', WC_ALetter),\n        ('\\u{1d716}', '\\u{1d734}', WC_ALetter), ('\\u{1d736}', '\\u{1d74e}', WC_ALetter),\n        ('\\u{1d750}', '\\u{1d76e}', WC_ALetter), ('\\u{1d770}', '\\u{1d788}', WC_ALetter),\n        ('\\u{1d78a}', '\\u{1d7a8}', WC_ALetter), ('\\u{1d7aa}', '\\u{1d7c2}', WC_ALetter),\n        ('\\u{1d7c4}', '\\u{1d7cb}', WC_ALetter), ('\\u{1d7ce}', '\\u{1d7ff}', WC_Numeric),\n        ('\\u{1da00}', '\\u{1da36}', WC_Extend), ('\\u{1da3b}', '\\u{1da6c}', WC_Extend), ('\\u{1da75}',\n        '\\u{1da75}', WC_Extend), ('\\u{1da84}', '\\u{1da84}', WC_Extend), ('\\u{1da9b}', '\\u{1da9f}',\n        WC_Extend), ('\\u{1daa1}', '\\u{1daaf}', WC_Extend), ('\\u{1df00}', '\\u{1df1e}', WC_ALetter),\n        ('\\u{1df25}', '\\u{1df2a}', WC_ALetter), ('\\u{1e000}', '\\u{1e006}', WC_Extend), ('\\u{1e008}',\n        '\\u{1e018}', WC_Extend), ('\\u{1e01b}', '\\u{1e021}', WC_Extend), ('\\u{1e023}', '\\u{1e024}',\n        WC_Extend), ('\\u{1e026}', '\\u{1e02a}', WC_Extend), ('\\u{1e030}', '\\u{1e06d}', WC_ALetter),\n        ('\\u{1e08f}', '\\u{1e08f}', WC_Extend), ('\\u{1e100}', '\\u{1e12c}', WC_ALetter), ('\\u{1e130}',\n        '\\u{1e136}', WC_Extend), ('\\u{1e137}', '\\u{1e13d}', WC_ALetter), ('\\u{1e140}', '\\u{1e149}',\n        WC_Numeric), ('\\u{1e14e}', '\\u{1e14e}', WC_ALetter), ('\\u{1e290}', '\\u{1e2ad}', WC_ALetter),\n        ('\\u{1e2ae}', '\\u{1e2ae}', WC_Extend), ('\\u{1e2c0}', '\\u{1e2eb}', WC_ALetter), ('\\u{1e2ec}',\n        '\\u{1e2ef}', WC_Extend), ('\\u{1e2f0}', '\\u{1e2f9}', WC_Numeric), ('\\u{1e4d0}', '\\u{1e4eb}',\n        WC_ALetter), ('\\u{1e4ec}', '\\u{1e4ef}', WC_Extend), ('\\u{1e4f0}', '\\u{1e4f9}', WC_Numeric),\n        ('\\u{1e5d0}', '\\u{1e5ed}', WC_ALetter), ('\\u{1e5ee}', '\\u{1e5ef}', WC_Extend), ('\\u{1e5f0}',\n        '\\u{1e5f0}', WC_ALetter), ('\\u{1e5f1}', '\\u{1e5fa}', WC_Numeric), ('\\u{1e6c0}', '\\u{1e6de}',\n        WC_ALetter), ('\\u{1e6e0}', '\\u{1e6e2}', WC_ALetter), ('\\u{1e6e3}', '\\u{1e6e3}', WC_Extend),\n        ('\\u{1e6e4}', '\\u{1e6e5}', WC_ALetter), ('\\u{1e6e6}', '\\u{1e6e6}', WC_Extend), ('\\u{1e6e7}',\n        '\\u{1e6ed}', WC_ALetter), ('\\u{1e6ee}', '\\u{1e6ef}', WC_Extend), ('\\u{1e6f0}', '\\u{1e6f4}',\n        WC_ALetter), ('\\u{1e6f5}', '\\u{1e6f5}', WC_Extend), ('\\u{1e6fe}', '\\u{1e6ff}', WC_ALetter),\n        ('\\u{1e7e0}', '\\u{1e7e6}', WC_ALetter), ('\\u{1e7e8}', '\\u{1e7eb}', WC_ALetter),\n        ('\\u{1e7ed}', '\\u{1e7ee}', WC_ALetter), ('\\u{1e7f0}', '\\u{1e7fe}', WC_ALetter),\n        ('\\u{1e800}', '\\u{1e8c4}', WC_ALetter), ('\\u{1e8d0}', '\\u{1e8d6}', WC_Extend), ('\\u{1e900}',\n        '\\u{1e943}', WC_ALetter), ('\\u{1e944}', '\\u{1e94a}', WC_Extend), ('\\u{1e94b}', '\\u{1e94b}',\n        WC_ALetter), ('\\u{1e950}', '\\u{1e959}', WC_Numeric), ('\\u{1ee00}', '\\u{1ee03}', WC_ALetter),\n        ('\\u{1ee05}', '\\u{1ee1f}', WC_ALetter), ('\\u{1ee21}', '\\u{1ee22}', WC_ALetter),\n        ('\\u{1ee24}', '\\u{1ee24}', WC_ALetter), ('\\u{1ee27}', '\\u{1ee27}', WC_ALetter),\n        ('\\u{1ee29}', '\\u{1ee32}', WC_ALetter), ('\\u{1ee34}', '\\u{1ee37}', WC_ALetter),\n        ('\\u{1ee39}', '\\u{1ee39}', WC_ALetter), ('\\u{1ee3b}', '\\u{1ee3b}', WC_ALetter),\n        ('\\u{1ee42}', '\\u{1ee42}', WC_ALetter), ('\\u{1ee47}', '\\u{1ee47}', WC_ALetter),\n        ('\\u{1ee49}', '\\u{1ee49}', WC_ALetter), ('\\u{1ee4b}', '\\u{1ee4b}', WC_ALetter),\n        ('\\u{1ee4d}', '\\u{1ee4f}', WC_ALetter), ('\\u{1ee51}', '\\u{1ee52}', WC_ALetter),\n        ('\\u{1ee54}', '\\u{1ee54}', WC_ALetter), ('\\u{1ee57}', '\\u{1ee57}', WC_ALetter),\n        ('\\u{1ee59}', '\\u{1ee59}', WC_ALetter), ('\\u{1ee5b}', '\\u{1ee5b}', WC_ALetter),\n        ('\\u{1ee5d}', '\\u{1ee5d}', WC_ALetter), ('\\u{1ee5f}', '\\u{1ee5f}', WC_ALetter),\n        ('\\u{1ee61}', '\\u{1ee62}', WC_ALetter), ('\\u{1ee64}', '\\u{1ee64}', WC_ALetter),\n        ('\\u{1ee67}', '\\u{1ee6a}', WC_ALetter), ('\\u{1ee6c}', '\\u{1ee72}', WC_ALetter),\n        ('\\u{1ee74}', '\\u{1ee77}', WC_ALetter), ('\\u{1ee79}', '\\u{1ee7c}', WC_ALetter),\n        ('\\u{1ee7e}', '\\u{1ee7e}', WC_ALetter), ('\\u{1ee80}', '\\u{1ee89}', WC_ALetter),\n        ('\\u{1ee8b}', '\\u{1ee9b}', WC_ALetter), ('\\u{1eea1}', '\\u{1eea3}', WC_ALetter),\n        ('\\u{1eea5}', '\\u{1eea9}', WC_ALetter), ('\\u{1eeab}', '\\u{1eebb}', WC_ALetter),\n        ('\\u{1f130}', '\\u{1f149}', WC_ALetter), ('\\u{1f150}', '\\u{1f169}', WC_ALetter),\n        ('\\u{1f170}', '\\u{1f189}', WC_ALetter), ('\\u{1f1e6}', '\\u{1f1ff}', WC_Regional_Indicator),\n        ('\\u{1f3fb}', '\\u{1f3ff}', WC_Extend), ('\\u{1fbf0}', '\\u{1fbf9}', WC_Numeric), ('\\u{e0001}',\n        '\\u{e0001}', WC_Format), ('\\u{e0020}', '\\u{e007f}', WC_Extend), ('\\u{e0100}', '\\u{e01ef}',\n        WC_Extend)\n    ];\n\n}\npub mod emoji {\n    use core::result::Result::{Ok, Err};\n\n    pub use self::EmojiCat::*;\n\n    #[allow(non_camel_case_types)]\n    #[derive(Clone, Copy, PartialEq, Eq, Debug)]\n    pub enum EmojiCat {\n        EC_Any,\n        EC_Extended_Pictographic,\n    }\n\n    fn bsearch_range_value_table(c: char, r: &[(char, char, EmojiCat)], default_lower: u32, default_upper: u32) -> (u32, u32, EmojiCat) {\n        use core::cmp::Ordering::{Equal, Less, Greater};\n        match r.binary_search_by(|&(lo, hi, _)| {\n            if lo <= c && c <= hi { Equal }\n            else if hi < c { Less }\n            else { Greater }\n        }) {\n            Ok(idx) => {\n                let (lower, upper, cat) = r[idx];\n                (lower as u32, upper as u32, cat)\n            }\n            Err(idx) => {\n                (\n                    if idx > 0 { r[idx-1].1 as u32 + 1 } else { default_lower },\n                    r.get(idx).map(|c|c.0 as u32 - 1).unwrap_or(default_upper),\n                    EC_Any,\n                )\n            }\n        }\n    }\n\n    pub fn emoji_category(c: char) -> (u32, u32, EmojiCat) {\n        // Perform a quick O(1) lookup in a precomputed table to determine\n        // the slice of the range table to search in.\n        let lookup_interval = 0x80;\n        let idx = (c as u32 / lookup_interval) as usize;\n        let range = emoji_cat_lookup.get(idx..(idx + 2)).map_or(\n          // If the `idx` is outside of the precomputed table - use the slice\n          // starting from the last covered index in the precomputed table and\n          // ending with the length of the range table.\n          155..156,\n          |r| (r[0] as usize)..((r[1] + 1) as usize)\n        );\n\n        // Compute pessimistic default lower and upper bounds on the category.\n        // If character doesn't map to any range and there is no adjacent range\n        // in the table slice - these bounds has to apply.\n        let lower = idx as u32 * lookup_interval;\n        let upper = lower + lookup_interval - 1;\n        bsearch_range_value_table(c, &emoji_cat_table[range], lower, upper)\n    }\n\n    const emoji_cat_lookup: &[u8] = &[\n        0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n        2, 2, 2, 4, 4, 6, 8, 8, 8, 10, 13, 13, 14, 14, 18, 39, 56, 74, 78, 78, 78, 79, 79, 79, 79,\n        83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 85, 85, 85, 85, 85, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,\n        87, 87, 87, 87, 87, 87, 87, 87, 87, 89, 94, 96, 99, 105, 105, 106, 112, 112, 113, 118, 134,\n        135, 141, 141, 142, 145, 150, 152, 153, 154, 155, 155, 155, 155, 155, 155, 155, 155, 155,\n        155\n    ];\n\n    const emoji_cat_table: &[(char, char, EmojiCat)] = &[\n        ('\\u{a9}', '\\u{a9}', EC_Extended_Pictographic), ('\\u{ae}', '\\u{ae}',\n        EC_Extended_Pictographic), ('\\u{203c}', '\\u{203c}', EC_Extended_Pictographic), ('\\u{2049}',\n        '\\u{2049}', EC_Extended_Pictographic), ('\\u{2122}', '\\u{2122}', EC_Extended_Pictographic),\n        ('\\u{2139}', '\\u{2139}', EC_Extended_Pictographic), ('\\u{2194}', '\\u{2199}',\n        EC_Extended_Pictographic), ('\\u{21a9}', '\\u{21aa}', EC_Extended_Pictographic), ('\\u{231a}',\n        '\\u{231b}', EC_Extended_Pictographic), ('\\u{2328}', '\\u{2328}', EC_Extended_Pictographic),\n        ('\\u{23cf}', '\\u{23cf}', EC_Extended_Pictographic), ('\\u{23e9}', '\\u{23f3}',\n        EC_Extended_Pictographic), ('\\u{23f8}', '\\u{23fa}', EC_Extended_Pictographic), ('\\u{24c2}',\n        '\\u{24c2}', EC_Extended_Pictographic), ('\\u{25aa}', '\\u{25ab}', EC_Extended_Pictographic),\n        ('\\u{25b6}', '\\u{25b6}', EC_Extended_Pictographic), ('\\u{25c0}', '\\u{25c0}',\n        EC_Extended_Pictographic), ('\\u{25fb}', '\\u{25fe}', EC_Extended_Pictographic), ('\\u{2600}',\n        '\\u{2604}', EC_Extended_Pictographic), ('\\u{260e}', '\\u{260e}', EC_Extended_Pictographic),\n        ('\\u{2611}', '\\u{2611}', EC_Extended_Pictographic), ('\\u{2614}', '\\u{2615}',\n        EC_Extended_Pictographic), ('\\u{2618}', '\\u{2618}', EC_Extended_Pictographic), ('\\u{261d}',\n        '\\u{261d}', EC_Extended_Pictographic), ('\\u{2620}', '\\u{2620}', EC_Extended_Pictographic),\n        ('\\u{2622}', '\\u{2623}', EC_Extended_Pictographic), ('\\u{2626}', '\\u{2626}',\n        EC_Extended_Pictographic), ('\\u{262a}', '\\u{262a}', EC_Extended_Pictographic), ('\\u{262e}',\n        '\\u{262f}', EC_Extended_Pictographic), ('\\u{2638}', '\\u{263a}', EC_Extended_Pictographic),\n        ('\\u{2640}', '\\u{2640}', EC_Extended_Pictographic), ('\\u{2642}', '\\u{2642}',\n        EC_Extended_Pictographic), ('\\u{2648}', '\\u{2653}', EC_Extended_Pictographic), ('\\u{265f}',\n        '\\u{2660}', EC_Extended_Pictographic), ('\\u{2663}', '\\u{2663}', EC_Extended_Pictographic),\n        ('\\u{2665}', '\\u{2666}', EC_Extended_Pictographic), ('\\u{2668}', '\\u{2668}',\n        EC_Extended_Pictographic), ('\\u{267b}', '\\u{267b}', EC_Extended_Pictographic), ('\\u{267e}',\n        '\\u{267f}', EC_Extended_Pictographic), ('\\u{2692}', '\\u{2697}', EC_Extended_Pictographic),\n        ('\\u{2699}', '\\u{2699}', EC_Extended_Pictographic), ('\\u{269b}', '\\u{269c}',\n        EC_Extended_Pictographic), ('\\u{26a0}', '\\u{26a1}', EC_Extended_Pictographic), ('\\u{26a7}',\n        '\\u{26a7}', EC_Extended_Pictographic), ('\\u{26aa}', '\\u{26ab}', EC_Extended_Pictographic),\n        ('\\u{26b0}', '\\u{26b1}', EC_Extended_Pictographic), ('\\u{26bd}', '\\u{26be}',\n        EC_Extended_Pictographic), ('\\u{26c4}', '\\u{26c5}', EC_Extended_Pictographic), ('\\u{26c8}',\n        '\\u{26c8}', EC_Extended_Pictographic), ('\\u{26ce}', '\\u{26cf}', EC_Extended_Pictographic),\n        ('\\u{26d1}', '\\u{26d1}', EC_Extended_Pictographic), ('\\u{26d3}', '\\u{26d4}',\n        EC_Extended_Pictographic), ('\\u{26e9}', '\\u{26ea}', EC_Extended_Pictographic), ('\\u{26f0}',\n        '\\u{26f5}', EC_Extended_Pictographic), ('\\u{26f7}', '\\u{26fa}', EC_Extended_Pictographic),\n        ('\\u{26fd}', '\\u{26fd}', EC_Extended_Pictographic), ('\\u{2702}', '\\u{2702}',\n        EC_Extended_Pictographic), ('\\u{2705}', '\\u{2705}', EC_Extended_Pictographic), ('\\u{2708}',\n        '\\u{270d}', EC_Extended_Pictographic), ('\\u{270f}', '\\u{270f}', EC_Extended_Pictographic),\n        ('\\u{2712}', '\\u{2712}', EC_Extended_Pictographic), ('\\u{2714}', '\\u{2714}',\n        EC_Extended_Pictographic), ('\\u{2716}', '\\u{2716}', EC_Extended_Pictographic), ('\\u{271d}',\n        '\\u{271d}', EC_Extended_Pictographic), ('\\u{2721}', '\\u{2721}', EC_Extended_Pictographic),\n        ('\\u{2728}', '\\u{2728}', EC_Extended_Pictographic), ('\\u{2733}', '\\u{2734}',\n        EC_Extended_Pictographic), ('\\u{2744}', '\\u{2744}', EC_Extended_Pictographic), ('\\u{2747}',\n        '\\u{2747}', EC_Extended_Pictographic), ('\\u{274c}', '\\u{274c}', EC_Extended_Pictographic),\n        ('\\u{274e}', '\\u{274e}', EC_Extended_Pictographic), ('\\u{2753}', '\\u{2755}',\n        EC_Extended_Pictographic), ('\\u{2757}', '\\u{2757}', EC_Extended_Pictographic), ('\\u{2763}',\n        '\\u{2764}', EC_Extended_Pictographic), ('\\u{2795}', '\\u{2797}', EC_Extended_Pictographic),\n        ('\\u{27a1}', '\\u{27a1}', EC_Extended_Pictographic), ('\\u{27b0}', '\\u{27b0}',\n        EC_Extended_Pictographic), ('\\u{27bf}', '\\u{27bf}', EC_Extended_Pictographic), ('\\u{2934}',\n        '\\u{2935}', EC_Extended_Pictographic), ('\\u{2b05}', '\\u{2b07}', EC_Extended_Pictographic),\n        ('\\u{2b1b}', '\\u{2b1c}', EC_Extended_Pictographic), ('\\u{2b50}', '\\u{2b50}',\n        EC_Extended_Pictographic), ('\\u{2b55}', '\\u{2b55}', EC_Extended_Pictographic), ('\\u{3030}',\n        '\\u{3030}', EC_Extended_Pictographic), ('\\u{303d}', '\\u{303d}', EC_Extended_Pictographic),\n        ('\\u{3297}', '\\u{3297}', EC_Extended_Pictographic), ('\\u{3299}', '\\u{3299}',\n        EC_Extended_Pictographic), ('\\u{1f004}', '\\u{1f004}', EC_Extended_Pictographic),\n        ('\\u{1f02c}', '\\u{1f02f}', EC_Extended_Pictographic), ('\\u{1f094}', '\\u{1f09f}',\n        EC_Extended_Pictographic), ('\\u{1f0af}', '\\u{1f0b0}', EC_Extended_Pictographic),\n        ('\\u{1f0c0}', '\\u{1f0c0}', EC_Extended_Pictographic), ('\\u{1f0cf}', '\\u{1f0d0}',\n        EC_Extended_Pictographic), ('\\u{1f0f6}', '\\u{1f0ff}', EC_Extended_Pictographic),\n        ('\\u{1f170}', '\\u{1f171}', EC_Extended_Pictographic), ('\\u{1f17e}', '\\u{1f17f}',\n        EC_Extended_Pictographic), ('\\u{1f18e}', '\\u{1f18e}', EC_Extended_Pictographic),\n        ('\\u{1f191}', '\\u{1f19a}', EC_Extended_Pictographic), ('\\u{1f1ae}', '\\u{1f1e5}',\n        EC_Extended_Pictographic), ('\\u{1f201}', '\\u{1f20f}', EC_Extended_Pictographic),\n        ('\\u{1f21a}', '\\u{1f21a}', EC_Extended_Pictographic), ('\\u{1f22f}', '\\u{1f22f}',\n        EC_Extended_Pictographic), ('\\u{1f232}', '\\u{1f23a}', EC_Extended_Pictographic),\n        ('\\u{1f23c}', '\\u{1f23f}', EC_Extended_Pictographic), ('\\u{1f249}', '\\u{1f25f}',\n        EC_Extended_Pictographic), ('\\u{1f266}', '\\u{1f321}', EC_Extended_Pictographic),\n        ('\\u{1f324}', '\\u{1f393}', EC_Extended_Pictographic), ('\\u{1f396}', '\\u{1f397}',\n        EC_Extended_Pictographic), ('\\u{1f399}', '\\u{1f39b}', EC_Extended_Pictographic),\n        ('\\u{1f39e}', '\\u{1f3f0}', EC_Extended_Pictographic), ('\\u{1f3f3}', '\\u{1f3f5}',\n        EC_Extended_Pictographic), ('\\u{1f3f7}', '\\u{1f3fa}', EC_Extended_Pictographic),\n        ('\\u{1f400}', '\\u{1f4fd}', EC_Extended_Pictographic), ('\\u{1f4ff}', '\\u{1f53d}',\n        EC_Extended_Pictographic), ('\\u{1f549}', '\\u{1f54e}', EC_Extended_Pictographic),\n        ('\\u{1f550}', '\\u{1f567}', EC_Extended_Pictographic), ('\\u{1f56f}', '\\u{1f570}',\n        EC_Extended_Pictographic), ('\\u{1f573}', '\\u{1f57a}', EC_Extended_Pictographic),\n        ('\\u{1f587}', '\\u{1f587}', EC_Extended_Pictographic), ('\\u{1f58a}', '\\u{1f58d}',\n        EC_Extended_Pictographic), ('\\u{1f590}', '\\u{1f590}', EC_Extended_Pictographic),\n        ('\\u{1f595}', '\\u{1f596}', EC_Extended_Pictographic), ('\\u{1f5a4}', '\\u{1f5a5}',\n        EC_Extended_Pictographic), ('\\u{1f5a8}', '\\u{1f5a8}', EC_Extended_Pictographic),\n        ('\\u{1f5b1}', '\\u{1f5b2}', EC_Extended_Pictographic), ('\\u{1f5bc}', '\\u{1f5bc}',\n        EC_Extended_Pictographic), ('\\u{1f5c2}', '\\u{1f5c4}', EC_Extended_Pictographic),\n        ('\\u{1f5d1}', '\\u{1f5d3}', EC_Extended_Pictographic), ('\\u{1f5dc}', '\\u{1f5de}',\n        EC_Extended_Pictographic), ('\\u{1f5e1}', '\\u{1f5e1}', EC_Extended_Pictographic),\n        ('\\u{1f5e3}', '\\u{1f5e3}', EC_Extended_Pictographic), ('\\u{1f5e8}', '\\u{1f5e8}',\n        EC_Extended_Pictographic), ('\\u{1f5ef}', '\\u{1f5ef}', EC_Extended_Pictographic),\n        ('\\u{1f5f3}', '\\u{1f5f3}', EC_Extended_Pictographic), ('\\u{1f5fa}', '\\u{1f64f}',\n        EC_Extended_Pictographic), ('\\u{1f680}', '\\u{1f6c5}', EC_Extended_Pictographic),\n        ('\\u{1f6cb}', '\\u{1f6d2}', EC_Extended_Pictographic), ('\\u{1f6d5}', '\\u{1f6e5}',\n        EC_Extended_Pictographic), ('\\u{1f6e9}', '\\u{1f6e9}', EC_Extended_Pictographic),\n        ('\\u{1f6eb}', '\\u{1f6f0}', EC_Extended_Pictographic), ('\\u{1f6f3}', '\\u{1f6ff}',\n        EC_Extended_Pictographic), ('\\u{1f7da}', '\\u{1f7ff}', EC_Extended_Pictographic),\n        ('\\u{1f80c}', '\\u{1f80f}', EC_Extended_Pictographic), ('\\u{1f848}', '\\u{1f84f}',\n        EC_Extended_Pictographic), ('\\u{1f85a}', '\\u{1f85f}', EC_Extended_Pictographic),\n        ('\\u{1f888}', '\\u{1f88f}', EC_Extended_Pictographic), ('\\u{1f8ae}', '\\u{1f8af}',\n        EC_Extended_Pictographic), ('\\u{1f8bc}', '\\u{1f8bf}', EC_Extended_Pictographic),\n        ('\\u{1f8c2}', '\\u{1f8cf}', EC_Extended_Pictographic), ('\\u{1f8d9}', '\\u{1f8ff}',\n        EC_Extended_Pictographic), ('\\u{1f90c}', '\\u{1f93a}', EC_Extended_Pictographic),\n        ('\\u{1f93c}', '\\u{1f945}', EC_Extended_Pictographic), ('\\u{1f947}', '\\u{1f9ff}',\n        EC_Extended_Pictographic), ('\\u{1fa58}', '\\u{1fa5f}', EC_Extended_Pictographic),\n        ('\\u{1fa6e}', '\\u{1faff}', EC_Extended_Pictographic), ('\\u{1fc00}', '\\u{1fffd}',\n        EC_Extended_Pictographic)\n    ];\n\n}\npub mod sentence {\n    use core::result::Result::{Ok, Err};\n\n    pub use self::SentenceCat::*;\n\n    #[allow(non_camel_case_types)]\n    #[derive(Clone, Copy, PartialEq, Eq, Debug)]\n    pub enum SentenceCat {\n        SC_ATerm,\n        SC_Any,\n        SC_CR,\n        SC_Close,\n        SC_Extend,\n        SC_Format,\n        SC_LF,\n        SC_Lower,\n        SC_Numeric,\n        SC_OLetter,\n        SC_SContinue,\n        SC_STerm,\n        SC_Sep,\n        SC_Sp,\n        SC_Upper,\n    }\n\n    fn bsearch_range_value_table(c: char, r: &[(char, char, SentenceCat)], default_lower: u32, default_upper: u32) -> (u32, u32, SentenceCat) {\n        use core::cmp::Ordering::{Equal, Less, Greater};\n        match r.binary_search_by(|&(lo, hi, _)| {\n            if lo <= c && c <= hi { Equal }\n            else if hi < c { Less }\n            else { Greater }\n        }) {\n            Ok(idx) => {\n                let (lower, upper, cat) = r[idx];\n                (lower as u32, upper as u32, cat)\n            }\n            Err(idx) => {\n                (\n                    if idx > 0 { r[idx-1].1 as u32 + 1 } else { default_lower },\n                    r.get(idx).map(|c|c.0 as u32 - 1).unwrap_or(default_upper),\n                    SC_Any,\n                )\n            }\n        }\n    }\n\n    pub fn sentence_category(c: char) -> (u32, u32, SentenceCat) {\n        // Perform a quick O(1) lookup in a precomputed table to determine\n        // the slice of the range table to search in.\n        let lookup_interval = 0x80;\n        let idx = (c as u32 / lookup_interval) as usize;\n        let range = sentence_cat_lookup.get(idx..(idx + 2)).map_or(\n          // If the `idx` is outside of the precomputed table - use the slice\n          // starting from the last covered index in the precomputed table and\n          // ending with the length of the range table.\n          2484..2495,\n          |r| (r[0] as usize)..((r[1] + 1) as usize)\n        );\n\n        // Compute pessimistic default lower and upper bounds on the category.\n        // If character doesn't map to any range and there is no adjacent range\n        // in the table slice - these bounds has to apply.\n        let lower = idx as u32 * lookup_interval;\n        let upper = lower + lookup_interval - 1;\n        bsearch_range_value_table(c, &sentence_cat_table[range], lower, upper)\n    }\n\n    const sentence_cat_lookup: &[u16] = &[\n        0, 19, 31, 154, 247, 314, 323, 334, 376, 410, 529, 580, 589, 600, 613, 619, 630, 644, 651,\n        662, 684, 703, 721, 739, 756, 772, 791, 807, 819, 826, 841, 851, 857, 872, 883, 883, 883,\n        888, 896, 902, 905, 905, 905, 905, 905, 908, 913, 923, 930, 939, 945, 952, 955, 961, 967,\n        977, 984, 992, 1006, 1006, 1008, 1136, 1255, 1273, 1294, 1314, 1317, 1342, 1346, 1346, 1346,\n        1348, 1348, 1348, 1350, 1350, 1350, 1350, 1350, 1352, 1354, 1354, 1354, 1354, 1357, 1357,\n        1357, 1357, 1357, 1375, 1483, 1489, 1499, 1508, 1508, 1508, 1508, 1519, 1524, 1525, 1528,\n        1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528,\n        1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528,\n        1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528,\n        1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529,\n        1529, 1529, 1529, 1529, 1532, 1532, 1532, 1587, 1620, 1703, 1785, 1796, 1806, 1813, 1824,\n        1835, 1852, 1859, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,\n        1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,\n        1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,\n        1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,\n        1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,\n        1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,\n        1865, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868,\n        1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868,\n        1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868,\n        1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868,\n        1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1868, 1869, 1870, 1880, 1881, 1881,\n        1881, 1883, 1886, 1904, 1906, 1923, 1931, 1937, 1938, 1939, 1940, 1940, 1943, 1947, 1951,\n        1953, 1957, 1960, 1968, 1968, 1968, 1971, 1976, 1983, 1986, 1989, 1991, 2002, 2006, 2009,\n        2010, 2011, 2013, 2021, 2022, 2022, 2027, 2032, 2037, 2046, 2055, 2066, 2078, 2086, 2095,\n        2113, 2128, 2135, 2140, 2140, 2147, 2152, 2157, 2162, 2162, 2164, 2167, 2182, 2189, 2199,\n        2204, 2205, 2207, 2214, 2217, 2229, 2237, 2237, 2240, 2250, 2251, 2251, 2251, 2251, 2251,\n        2251, 2251, 2251, 2252, 2253, 2253, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254,\n        2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2254, 2255, 2255, 2255,\n        2255, 2255, 2255, 2255, 2255, 2255, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260,\n        2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260, 2260,\n        2260, 2260, 2260, 2260, 2260, 2260, 2260, 2261, 2261, 2261, 2261, 2261, 2262, 2262, 2262,\n        2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262,\n        2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262,\n        2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262, 2262,\n        2262, 2262, 2262, 2262, 2262, 2262, 2265, 2265, 2265, 2265, 2265, 2265, 2265, 2265, 2265,\n        2265, 2265, 2265, 2265, 2265, 2265, 2265, 2265, 2265, 2269, 2274, 2281, 2282, 2282, 2282,\n        2285, 2285, 2287, 2290, 2293, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301,\n        2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301,\n        2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301,\n        2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301, 2301,\n        2301, 2301, 2301, 2302, 2303, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304,\n        2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304,\n        2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304,\n        2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304,\n        2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2307, 2307,\n        2307, 2312, 2312, 2312, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313,\n        2313, 2313, 2313, 2313, 2313, 2313, 2313, 2313, 2315, 2320, 2320, 2320, 2320, 2320, 2320,\n        2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320,\n        2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2320, 2321, 2321, 2321, 2321,\n        2321, 2323, 2323, 2323, 2323, 2326, 2329, 2330, 2330, 2330, 2330, 2335, 2348, 2360, 2365,\n        2370, 2376, 2382, 2390, 2390, 2390, 2390, 2390, 2393, 2397, 2397, 2397, 2397, 2397, 2397,\n        2397, 2397, 2397, 2401, 2401, 2407, 2408, 2413, 2413, 2413, 2418, 2418, 2418, 2418, 2421,\n        2421, 2425, 2425, 2435, 2435, 2439, 2439, 2441, 2446, 2446, 2446, 2446, 2446, 2446, 2446,\n        2446, 2446, 2446, 2474, 2479, 2479, 2479, 2479, 2479, 2481, 2482, 2482, 2482, 2482, 2482,\n        2482, 2482, 2482, 2482, 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483,\n        2484, 2484, 2484, 2484, 2484, 2484, 2484, 2484\n    ];\n\n    const sentence_cat_table: &[(char, char, SentenceCat)] = &[\n        ('\\u{9}', '\\u{9}', SC_Sp), ('\\u{a}', '\\u{a}', SC_LF), ('\\u{b}', '\\u{c}', SC_Sp), ('\\u{d}',\n        '\\u{d}', SC_CR), ('\\u{20}', '\\u{20}', SC_Sp), ('\\u{21}', '\\u{21}', SC_STerm), ('\\u{22}',\n        '\\u{22}', SC_Close), ('\\u{27}', '\\u{29}', SC_Close), ('\\u{2c}', '\\u{2d}', SC_SContinue),\n        ('\\u{2e}', '\\u{2e}', SC_ATerm), ('\\u{30}', '\\u{39}', SC_Numeric), ('\\u{3a}', '\\u{3b}',\n        SC_SContinue), ('\\u{3f}', '\\u{3f}', SC_STerm), ('\\u{41}', '\\u{5a}', SC_Upper), ('\\u{5b}',\n        '\\u{5b}', SC_Close), ('\\u{5d}', '\\u{5d}', SC_Close), ('\\u{61}', '\\u{7a}', SC_Lower),\n        ('\\u{7b}', '\\u{7b}', SC_Close), ('\\u{7d}', '\\u{7d}', SC_Close), ('\\u{85}', '\\u{85}',\n        SC_Sep), ('\\u{a0}', '\\u{a0}', SC_Sp), ('\\u{aa}', '\\u{aa}', SC_Lower), ('\\u{ab}', '\\u{ab}',\n        SC_Close), ('\\u{ad}', '\\u{ad}', SC_Format), ('\\u{b5}', '\\u{b5}', SC_Lower), ('\\u{ba}',\n        '\\u{ba}', SC_Lower), ('\\u{bb}', '\\u{bb}', SC_Close), ('\\u{c0}', '\\u{d6}', SC_Upper),\n        ('\\u{d8}', '\\u{de}', SC_Upper), ('\\u{df}', '\\u{f6}', SC_Lower), ('\\u{f8}', '\\u{ff}',\n        SC_Lower), ('\\u{100}', '\\u{100}', SC_Upper), ('\\u{101}', '\\u{101}', SC_Lower), ('\\u{102}',\n        '\\u{102}', SC_Upper), ('\\u{103}', '\\u{103}', SC_Lower), ('\\u{104}', '\\u{104}', SC_Upper),\n        ('\\u{105}', '\\u{105}', SC_Lower), ('\\u{106}', '\\u{106}', SC_Upper), ('\\u{107}', '\\u{107}',\n        SC_Lower), ('\\u{108}', '\\u{108}', SC_Upper), ('\\u{109}', '\\u{109}', SC_Lower), ('\\u{10a}',\n        '\\u{10a}', SC_Upper), ('\\u{10b}', '\\u{10b}', SC_Lower), ('\\u{10c}', '\\u{10c}', SC_Upper),\n        ('\\u{10d}', '\\u{10d}', SC_Lower), ('\\u{10e}', '\\u{10e}', SC_Upper), ('\\u{10f}', '\\u{10f}',\n        SC_Lower), ('\\u{110}', '\\u{110}', SC_Upper), ('\\u{111}', '\\u{111}', SC_Lower), ('\\u{112}',\n        '\\u{112}', SC_Upper), ('\\u{113}', '\\u{113}', SC_Lower), ('\\u{114}', '\\u{114}', SC_Upper),\n        ('\\u{115}', '\\u{115}', SC_Lower), ('\\u{116}', '\\u{116}', SC_Upper), ('\\u{117}', '\\u{117}',\n        SC_Lower), ('\\u{118}', '\\u{118}', SC_Upper), ('\\u{119}', '\\u{119}', SC_Lower), ('\\u{11a}',\n        '\\u{11a}', SC_Upper), ('\\u{11b}', '\\u{11b}', SC_Lower), ('\\u{11c}', '\\u{11c}', SC_Upper),\n        ('\\u{11d}', '\\u{11d}', SC_Lower), ('\\u{11e}', '\\u{11e}', SC_Upper), ('\\u{11f}', '\\u{11f}',\n        SC_Lower), ('\\u{120}', '\\u{120}', SC_Upper), ('\\u{121}', '\\u{121}', SC_Lower), ('\\u{122}',\n        '\\u{122}', SC_Upper), ('\\u{123}', '\\u{123}', SC_Lower), ('\\u{124}', '\\u{124}', SC_Upper),\n        ('\\u{125}', '\\u{125}', SC_Lower), ('\\u{126}', '\\u{126}', SC_Upper), ('\\u{127}', '\\u{127}',\n        SC_Lower), ('\\u{128}', '\\u{128}', SC_Upper), ('\\u{129}', '\\u{129}', SC_Lower), ('\\u{12a}',\n        '\\u{12a}', SC_Upper), ('\\u{12b}', '\\u{12b}', SC_Lower), ('\\u{12c}', '\\u{12c}', SC_Upper),\n        ('\\u{12d}', '\\u{12d}', SC_Lower), ('\\u{12e}', '\\u{12e}', SC_Upper), ('\\u{12f}', '\\u{12f}',\n        SC_Lower), ('\\u{130}', '\\u{130}', SC_Upper), ('\\u{131}', '\\u{131}', SC_Lower), ('\\u{132}',\n        '\\u{132}', SC_Upper), ('\\u{133}', '\\u{133}', SC_Lower), ('\\u{134}', '\\u{134}', SC_Upper),\n        ('\\u{135}', '\\u{135}', SC_Lower), ('\\u{136}', '\\u{136}', SC_Upper), ('\\u{137}', '\\u{138}',\n        SC_Lower), ('\\u{139}', '\\u{139}', SC_Upper), ('\\u{13a}', '\\u{13a}', SC_Lower), ('\\u{13b}',\n        '\\u{13b}', SC_Upper), ('\\u{13c}', '\\u{13c}', SC_Lower), ('\\u{13d}', '\\u{13d}', SC_Upper),\n        ('\\u{13e}', '\\u{13e}', SC_Lower), ('\\u{13f}', '\\u{13f}', SC_Upper), ('\\u{140}', '\\u{140}',\n        SC_Lower), ('\\u{141}', '\\u{141}', SC_Upper), ('\\u{142}', '\\u{142}', SC_Lower), ('\\u{143}',\n        '\\u{143}', SC_Upper), ('\\u{144}', '\\u{144}', SC_Lower), ('\\u{145}', '\\u{145}', SC_Upper),\n        ('\\u{146}', '\\u{146}', SC_Lower), ('\\u{147}', '\\u{147}', SC_Upper), ('\\u{148}', '\\u{149}',\n        SC_Lower), ('\\u{14a}', '\\u{14a}', SC_Upper), ('\\u{14b}', '\\u{14b}', SC_Lower), ('\\u{14c}',\n        '\\u{14c}', SC_Upper), ('\\u{14d}', '\\u{14d}', SC_Lower), ('\\u{14e}', '\\u{14e}', SC_Upper),\n        ('\\u{14f}', '\\u{14f}', SC_Lower), ('\\u{150}', '\\u{150}', SC_Upper), ('\\u{151}', '\\u{151}',\n        SC_Lower), ('\\u{152}', '\\u{152}', SC_Upper), ('\\u{153}', '\\u{153}', SC_Lower), ('\\u{154}',\n        '\\u{154}', SC_Upper), ('\\u{155}', '\\u{155}', SC_Lower), ('\\u{156}', '\\u{156}', SC_Upper),\n        ('\\u{157}', '\\u{157}', SC_Lower), ('\\u{158}', '\\u{158}', SC_Upper), ('\\u{159}', '\\u{159}',\n        SC_Lower), ('\\u{15a}', '\\u{15a}', SC_Upper), ('\\u{15b}', '\\u{15b}', SC_Lower), ('\\u{15c}',\n        '\\u{15c}', SC_Upper), ('\\u{15d}', '\\u{15d}', SC_Lower), ('\\u{15e}', '\\u{15e}', SC_Upper),\n        ('\\u{15f}', '\\u{15f}', SC_Lower), ('\\u{160}', '\\u{160}', SC_Upper), ('\\u{161}', '\\u{161}',\n        SC_Lower), ('\\u{162}', '\\u{162}', SC_Upper), ('\\u{163}', '\\u{163}', SC_Lower), ('\\u{164}',\n        '\\u{164}', SC_Upper), ('\\u{165}', '\\u{165}', SC_Lower), ('\\u{166}', '\\u{166}', SC_Upper),\n        ('\\u{167}', '\\u{167}', SC_Lower), ('\\u{168}', '\\u{168}', SC_Upper), ('\\u{169}', '\\u{169}',\n        SC_Lower), ('\\u{16a}', '\\u{16a}', SC_Upper), ('\\u{16b}', '\\u{16b}', SC_Lower), ('\\u{16c}',\n        '\\u{16c}', SC_Upper), ('\\u{16d}', '\\u{16d}', SC_Lower), ('\\u{16e}', '\\u{16e}', SC_Upper),\n        ('\\u{16f}', '\\u{16f}', SC_Lower), ('\\u{170}', '\\u{170}', SC_Upper), ('\\u{171}', '\\u{171}',\n        SC_Lower), ('\\u{172}', '\\u{172}', SC_Upper), ('\\u{173}', '\\u{173}', SC_Lower), ('\\u{174}',\n        '\\u{174}', SC_Upper), ('\\u{175}', '\\u{175}', SC_Lower), ('\\u{176}', '\\u{176}', SC_Upper),\n        ('\\u{177}', '\\u{177}', SC_Lower), ('\\u{178}', '\\u{179}', SC_Upper), ('\\u{17a}', '\\u{17a}',\n        SC_Lower), ('\\u{17b}', '\\u{17b}', SC_Upper), ('\\u{17c}', '\\u{17c}', SC_Lower), ('\\u{17d}',\n        '\\u{17d}', SC_Upper), ('\\u{17e}', '\\u{180}', SC_Lower), ('\\u{181}', '\\u{182}', SC_Upper),\n        ('\\u{183}', '\\u{183}', SC_Lower), ('\\u{184}', '\\u{184}', SC_Upper), ('\\u{185}', '\\u{185}',\n        SC_Lower), ('\\u{186}', '\\u{187}', SC_Upper), ('\\u{188}', '\\u{188}', SC_Lower), ('\\u{189}',\n        '\\u{18b}', SC_Upper), ('\\u{18c}', '\\u{18d}', SC_Lower), ('\\u{18e}', '\\u{191}', SC_Upper),\n        ('\\u{192}', '\\u{192}', SC_Lower), ('\\u{193}', '\\u{194}', SC_Upper), ('\\u{195}', '\\u{195}',\n        SC_Lower), ('\\u{196}', '\\u{198}', SC_Upper), ('\\u{199}', '\\u{19b}', SC_Lower), ('\\u{19c}',\n        '\\u{19d}', SC_Upper), ('\\u{19e}', '\\u{19e}', SC_Lower), ('\\u{19f}', '\\u{1a0}', SC_Upper),\n        ('\\u{1a1}', '\\u{1a1}', SC_Lower), ('\\u{1a2}', '\\u{1a2}', SC_Upper), ('\\u{1a3}', '\\u{1a3}',\n        SC_Lower), ('\\u{1a4}', '\\u{1a4}', SC_Upper), ('\\u{1a5}', '\\u{1a5}', SC_Lower), ('\\u{1a6}',\n        '\\u{1a7}', SC_Upper), ('\\u{1a8}', '\\u{1a8}', SC_Lower), ('\\u{1a9}', '\\u{1a9}', SC_Upper),\n        ('\\u{1aa}', '\\u{1ab}', SC_Lower), ('\\u{1ac}', '\\u{1ac}', SC_Upper), ('\\u{1ad}', '\\u{1ad}',\n        SC_Lower), ('\\u{1ae}', '\\u{1af}', SC_Upper), ('\\u{1b0}', '\\u{1b0}', SC_Lower), ('\\u{1b1}',\n        '\\u{1b3}', SC_Upper), ('\\u{1b4}', '\\u{1b4}', SC_Lower), ('\\u{1b5}', '\\u{1b5}', SC_Upper),\n        ('\\u{1b6}', '\\u{1b6}', SC_Lower), ('\\u{1b7}', '\\u{1b8}', SC_Upper), ('\\u{1b9}', '\\u{1ba}',\n        SC_Lower), ('\\u{1bb}', '\\u{1bb}', SC_OLetter), ('\\u{1bc}', '\\u{1bc}', SC_Upper), ('\\u{1bd}',\n        '\\u{1bf}', SC_Lower), ('\\u{1c0}', '\\u{1c3}', SC_OLetter), ('\\u{1c4}', '\\u{1c5}', SC_Upper),\n        ('\\u{1c6}', '\\u{1c6}', SC_Lower), ('\\u{1c7}', '\\u{1c8}', SC_Upper), ('\\u{1c9}', '\\u{1c9}',\n        SC_Lower), ('\\u{1ca}', '\\u{1cb}', SC_Upper), ('\\u{1cc}', '\\u{1cc}', SC_Lower), ('\\u{1cd}',\n        '\\u{1cd}', SC_Upper), ('\\u{1ce}', '\\u{1ce}', SC_Lower), ('\\u{1cf}', '\\u{1cf}', SC_Upper),\n        ('\\u{1d0}', '\\u{1d0}', SC_Lower), ('\\u{1d1}', '\\u{1d1}', SC_Upper), ('\\u{1d2}', '\\u{1d2}',\n        SC_Lower), ('\\u{1d3}', '\\u{1d3}', SC_Upper), ('\\u{1d4}', '\\u{1d4}', SC_Lower), ('\\u{1d5}',\n        '\\u{1d5}', SC_Upper), ('\\u{1d6}', '\\u{1d6}', SC_Lower), ('\\u{1d7}', '\\u{1d7}', SC_Upper),\n        ('\\u{1d8}', '\\u{1d8}', SC_Lower), ('\\u{1d9}', '\\u{1d9}', SC_Upper), ('\\u{1da}', '\\u{1da}',\n        SC_Lower), ('\\u{1db}', '\\u{1db}', SC_Upper), ('\\u{1dc}', '\\u{1dd}', SC_Lower), ('\\u{1de}',\n        '\\u{1de}', SC_Upper), ('\\u{1df}', '\\u{1df}', SC_Lower), ('\\u{1e0}', '\\u{1e0}', SC_Upper),\n        ('\\u{1e1}', '\\u{1e1}', SC_Lower), ('\\u{1e2}', '\\u{1e2}', SC_Upper), ('\\u{1e3}', '\\u{1e3}',\n        SC_Lower), ('\\u{1e4}', '\\u{1e4}', SC_Upper), ('\\u{1e5}', '\\u{1e5}', SC_Lower), ('\\u{1e6}',\n        '\\u{1e6}', SC_Upper), ('\\u{1e7}', '\\u{1e7}', SC_Lower), ('\\u{1e8}', '\\u{1e8}', SC_Upper),\n        ('\\u{1e9}', '\\u{1e9}', SC_Lower), ('\\u{1ea}', '\\u{1ea}', SC_Upper), ('\\u{1eb}', '\\u{1eb}',\n        SC_Lower), ('\\u{1ec}', '\\u{1ec}', SC_Upper), ('\\u{1ed}', '\\u{1ed}', SC_Lower), ('\\u{1ee}',\n        '\\u{1ee}', SC_Upper), ('\\u{1ef}', '\\u{1f0}', SC_Lower), ('\\u{1f1}', '\\u{1f2}', SC_Upper),\n        ('\\u{1f3}', '\\u{1f3}', SC_Lower), ('\\u{1f4}', '\\u{1f4}', SC_Upper), ('\\u{1f5}', '\\u{1f5}',\n        SC_Lower), ('\\u{1f6}', '\\u{1f8}', SC_Upper), ('\\u{1f9}', '\\u{1f9}', SC_Lower), ('\\u{1fa}',\n        '\\u{1fa}', SC_Upper), ('\\u{1fb}', '\\u{1fb}', SC_Lower), ('\\u{1fc}', '\\u{1fc}', SC_Upper),\n        ('\\u{1fd}', '\\u{1fd}', SC_Lower), ('\\u{1fe}', '\\u{1fe}', SC_Upper), ('\\u{1ff}', '\\u{1ff}',\n        SC_Lower), ('\\u{200}', '\\u{200}', SC_Upper), ('\\u{201}', '\\u{201}', SC_Lower), ('\\u{202}',\n        '\\u{202}', SC_Upper), ('\\u{203}', '\\u{203}', SC_Lower), ('\\u{204}', '\\u{204}', SC_Upper),\n        ('\\u{205}', '\\u{205}', SC_Lower), ('\\u{206}', '\\u{206}', SC_Upper), ('\\u{207}', '\\u{207}',\n        SC_Lower), ('\\u{208}', '\\u{208}', SC_Upper), ('\\u{209}', '\\u{209}', SC_Lower), ('\\u{20a}',\n        '\\u{20a}', SC_Upper), ('\\u{20b}', '\\u{20b}', SC_Lower), ('\\u{20c}', '\\u{20c}', SC_Upper),\n        ('\\u{20d}', '\\u{20d}', SC_Lower), ('\\u{20e}', '\\u{20e}', SC_Upper), ('\\u{20f}', '\\u{20f}',\n        SC_Lower), ('\\u{210}', '\\u{210}', SC_Upper), ('\\u{211}', '\\u{211}', SC_Lower), ('\\u{212}',\n        '\\u{212}', SC_Upper), ('\\u{213}', '\\u{213}', SC_Lower), ('\\u{214}', '\\u{214}', SC_Upper),\n        ('\\u{215}', '\\u{215}', SC_Lower), ('\\u{216}', '\\u{216}', SC_Upper), ('\\u{217}', '\\u{217}',\n        SC_Lower), ('\\u{218}', '\\u{218}', SC_Upper), ('\\u{219}', '\\u{219}', SC_Lower), ('\\u{21a}',\n        '\\u{21a}', SC_Upper), ('\\u{21b}', '\\u{21b}', SC_Lower), ('\\u{21c}', '\\u{21c}', SC_Upper),\n        ('\\u{21d}', '\\u{21d}', SC_Lower), ('\\u{21e}', '\\u{21e}', SC_Upper), ('\\u{21f}', '\\u{21f}',\n        SC_Lower), ('\\u{220}', '\\u{220}', SC_Upper), ('\\u{221}', '\\u{221}', SC_Lower), ('\\u{222}',\n        '\\u{222}', SC_Upper), ('\\u{223}', '\\u{223}', SC_Lower), ('\\u{224}', '\\u{224}', SC_Upper),\n        ('\\u{225}', '\\u{225}', SC_Lower), ('\\u{226}', '\\u{226}', SC_Upper), ('\\u{227}', '\\u{227}',\n        SC_Lower), ('\\u{228}', '\\u{228}', SC_Upper), ('\\u{229}', '\\u{229}', SC_Lower), ('\\u{22a}',\n        '\\u{22a}', SC_Upper), ('\\u{22b}', '\\u{22b}', SC_Lower), ('\\u{22c}', '\\u{22c}', SC_Upper),\n        ('\\u{22d}', '\\u{22d}', SC_Lower), ('\\u{22e}', '\\u{22e}', SC_Upper), ('\\u{22f}', '\\u{22f}',\n        SC_Lower), ('\\u{230}', '\\u{230}', SC_Upper), ('\\u{231}', '\\u{231}', SC_Lower), ('\\u{232}',\n        '\\u{232}', SC_Upper), ('\\u{233}', '\\u{239}', SC_Lower), ('\\u{23a}', '\\u{23b}', SC_Upper),\n        ('\\u{23c}', '\\u{23c}', SC_Lower), ('\\u{23d}', '\\u{23e}', SC_Upper), ('\\u{23f}', '\\u{240}',\n        SC_Lower), ('\\u{241}', '\\u{241}', SC_Upper), ('\\u{242}', '\\u{242}', SC_Lower), ('\\u{243}',\n        '\\u{246}', SC_Upper), ('\\u{247}', '\\u{247}', SC_Lower), ('\\u{248}', '\\u{248}', SC_Upper),\n        ('\\u{249}', '\\u{249}', SC_Lower), ('\\u{24a}', '\\u{24a}', SC_Upper), ('\\u{24b}', '\\u{24b}',\n        SC_Lower), ('\\u{24c}', '\\u{24c}', SC_Upper), ('\\u{24d}', '\\u{24d}', SC_Lower), ('\\u{24e}',\n        '\\u{24e}', SC_Upper), ('\\u{24f}', '\\u{293}', SC_Lower), ('\\u{294}', '\\u{295}', SC_OLetter),\n        ('\\u{296}', '\\u{2b8}', SC_Lower), ('\\u{2b9}', '\\u{2bf}', SC_OLetter), ('\\u{2c0}', '\\u{2c1}',\n        SC_Lower), ('\\u{2c6}', '\\u{2d1}', SC_OLetter), ('\\u{2e0}', '\\u{2e4}', SC_Lower), ('\\u{2ec}',\n        '\\u{2ec}', SC_OLetter), ('\\u{2ee}', '\\u{2ee}', SC_OLetter), ('\\u{300}', '\\u{36f}',\n        SC_Extend), ('\\u{370}', '\\u{370}', SC_Upper), ('\\u{371}', '\\u{371}', SC_Lower), ('\\u{372}',\n        '\\u{372}', SC_Upper), ('\\u{373}', '\\u{373}', SC_Lower), ('\\u{374}', '\\u{374}', SC_OLetter),\n        ('\\u{376}', '\\u{376}', SC_Upper), ('\\u{377}', '\\u{377}', SC_Lower), ('\\u{37a}', '\\u{37d}',\n        SC_Lower), ('\\u{37e}', '\\u{37e}', SC_SContinue), ('\\u{37f}', '\\u{37f}', SC_Upper),\n        ('\\u{386}', '\\u{386}', SC_Upper), ('\\u{388}', '\\u{38a}', SC_Upper), ('\\u{38c}', '\\u{38c}',\n        SC_Upper), ('\\u{38e}', '\\u{38f}', SC_Upper), ('\\u{390}', '\\u{390}', SC_Lower), ('\\u{391}',\n        '\\u{3a1}', SC_Upper), ('\\u{3a3}', '\\u{3ab}', SC_Upper), ('\\u{3ac}', '\\u{3ce}', SC_Lower),\n        ('\\u{3cf}', '\\u{3cf}', SC_Upper), ('\\u{3d0}', '\\u{3d1}', SC_Lower), ('\\u{3d2}', '\\u{3d4}',\n        SC_Upper), ('\\u{3d5}', '\\u{3d7}', SC_Lower), ('\\u{3d8}', '\\u{3d8}', SC_Upper), ('\\u{3d9}',\n        '\\u{3d9}', SC_Lower), ('\\u{3da}', '\\u{3da}', SC_Upper), ('\\u{3db}', '\\u{3db}', SC_Lower),\n        ('\\u{3dc}', '\\u{3dc}', SC_Upper), ('\\u{3dd}', '\\u{3dd}', SC_Lower), ('\\u{3de}', '\\u{3de}',\n        SC_Upper), ('\\u{3df}', '\\u{3df}', SC_Lower), ('\\u{3e0}', '\\u{3e0}', SC_Upper), ('\\u{3e1}',\n        '\\u{3e1}', SC_Lower), ('\\u{3e2}', '\\u{3e2}', SC_Upper), ('\\u{3e3}', '\\u{3e3}', SC_Lower),\n        ('\\u{3e4}', '\\u{3e4}', SC_Upper), ('\\u{3e5}', '\\u{3e5}', SC_Lower), ('\\u{3e6}', '\\u{3e6}',\n        SC_Upper), ('\\u{3e7}', '\\u{3e7}', SC_Lower), ('\\u{3e8}', '\\u{3e8}', SC_Upper), ('\\u{3e9}',\n        '\\u{3e9}', SC_Lower), ('\\u{3ea}', '\\u{3ea}', SC_Upper), ('\\u{3eb}', '\\u{3eb}', SC_Lower),\n        ('\\u{3ec}', '\\u{3ec}', SC_Upper), ('\\u{3ed}', '\\u{3ed}', SC_Lower), ('\\u{3ee}', '\\u{3ee}',\n        SC_Upper), ('\\u{3ef}', '\\u{3f3}', SC_Lower), ('\\u{3f4}', '\\u{3f4}', SC_Upper), ('\\u{3f5}',\n        '\\u{3f5}', SC_Lower), ('\\u{3f7}', '\\u{3f7}', SC_Upper), ('\\u{3f8}', '\\u{3f8}', SC_Lower),\n        ('\\u{3f9}', '\\u{3fa}', SC_Upper), ('\\u{3fb}', '\\u{3fc}', SC_Lower), ('\\u{3fd}', '\\u{42f}',\n        SC_Upper), ('\\u{430}', '\\u{45f}', SC_Lower), ('\\u{460}', '\\u{460}', SC_Upper), ('\\u{461}',\n        '\\u{461}', SC_Lower), ('\\u{462}', '\\u{462}', SC_Upper), ('\\u{463}', '\\u{463}', SC_Lower),\n        ('\\u{464}', '\\u{464}', SC_Upper), ('\\u{465}', '\\u{465}', SC_Lower), ('\\u{466}', '\\u{466}',\n        SC_Upper), ('\\u{467}', '\\u{467}', SC_Lower), ('\\u{468}', '\\u{468}', SC_Upper), ('\\u{469}',\n        '\\u{469}', SC_Lower), ('\\u{46a}', '\\u{46a}', SC_Upper), ('\\u{46b}', '\\u{46b}', SC_Lower),\n        ('\\u{46c}', '\\u{46c}', SC_Upper), ('\\u{46d}', '\\u{46d}', SC_Lower), ('\\u{46e}', '\\u{46e}',\n        SC_Upper), ('\\u{46f}', '\\u{46f}', SC_Lower), ('\\u{470}', '\\u{470}', SC_Upper), ('\\u{471}',\n        '\\u{471}', SC_Lower), ('\\u{472}', '\\u{472}', SC_Upper), ('\\u{473}', '\\u{473}', SC_Lower),\n        ('\\u{474}', '\\u{474}', SC_Upper), ('\\u{475}', '\\u{475}', SC_Lower), ('\\u{476}', '\\u{476}',\n        SC_Upper), ('\\u{477}', '\\u{477}', SC_Lower), ('\\u{478}', '\\u{478}', SC_Upper), ('\\u{479}',\n        '\\u{479}', SC_Lower), ('\\u{47a}', '\\u{47a}', SC_Upper), ('\\u{47b}', '\\u{47b}', SC_Lower),\n        ('\\u{47c}', '\\u{47c}', SC_Upper), ('\\u{47d}', '\\u{47d}', SC_Lower), ('\\u{47e}', '\\u{47e}',\n        SC_Upper), ('\\u{47f}', '\\u{47f}', SC_Lower), ('\\u{480}', '\\u{480}', SC_Upper), ('\\u{481}',\n        '\\u{481}', SC_Lower), ('\\u{483}', '\\u{489}', SC_Extend), ('\\u{48a}', '\\u{48a}', SC_Upper),\n        ('\\u{48b}', '\\u{48b}', SC_Lower), ('\\u{48c}', '\\u{48c}', SC_Upper), ('\\u{48d}', '\\u{48d}',\n        SC_Lower), ('\\u{48e}', '\\u{48e}', SC_Upper), ('\\u{48f}', '\\u{48f}', SC_Lower), ('\\u{490}',\n        '\\u{490}', SC_Upper), ('\\u{491}', '\\u{491}', SC_Lower), ('\\u{492}', '\\u{492}', SC_Upper),\n        ('\\u{493}', '\\u{493}', SC_Lower), ('\\u{494}', '\\u{494}', SC_Upper), ('\\u{495}', '\\u{495}',\n        SC_Lower), ('\\u{496}', '\\u{496}', SC_Upper), ('\\u{497}', '\\u{497}', SC_Lower), ('\\u{498}',\n        '\\u{498}', SC_Upper), ('\\u{499}', '\\u{499}', SC_Lower), ('\\u{49a}', '\\u{49a}', SC_Upper),\n        ('\\u{49b}', '\\u{49b}', SC_Lower), ('\\u{49c}', '\\u{49c}', SC_Upper), ('\\u{49d}', '\\u{49d}',\n        SC_Lower), ('\\u{49e}', '\\u{49e}', SC_Upper), ('\\u{49f}', '\\u{49f}', SC_Lower), ('\\u{4a0}',\n        '\\u{4a0}', SC_Upper), ('\\u{4a1}', '\\u{4a1}', SC_Lower), ('\\u{4a2}', '\\u{4a2}', SC_Upper),\n        ('\\u{4a3}', '\\u{4a3}', SC_Lower), ('\\u{4a4}', '\\u{4a4}', SC_Upper), ('\\u{4a5}', '\\u{4a5}',\n        SC_Lower), ('\\u{4a6}', '\\u{4a6}', SC_Upper), ('\\u{4a7}', '\\u{4a7}', SC_Lower), ('\\u{4a8}',\n        '\\u{4a8}', SC_Upper), ('\\u{4a9}', '\\u{4a9}', SC_Lower), ('\\u{4aa}', '\\u{4aa}', SC_Upper),\n        ('\\u{4ab}', '\\u{4ab}', SC_Lower), ('\\u{4ac}', '\\u{4ac}', SC_Upper), ('\\u{4ad}', '\\u{4ad}',\n        SC_Lower), ('\\u{4ae}', '\\u{4ae}', SC_Upper), ('\\u{4af}', '\\u{4af}', SC_Lower), ('\\u{4b0}',\n        '\\u{4b0}', SC_Upper), ('\\u{4b1}', '\\u{4b1}', SC_Lower), ('\\u{4b2}', '\\u{4b2}', SC_Upper),\n        ('\\u{4b3}', '\\u{4b3}', SC_Lower), ('\\u{4b4}', '\\u{4b4}', SC_Upper), ('\\u{4b5}', '\\u{4b5}',\n        SC_Lower), ('\\u{4b6}', '\\u{4b6}', SC_Upper), ('\\u{4b7}', '\\u{4b7}', SC_Lower), ('\\u{4b8}',\n        '\\u{4b8}', SC_Upper), ('\\u{4b9}', '\\u{4b9}', SC_Lower), ('\\u{4ba}', '\\u{4ba}', SC_Upper),\n        ('\\u{4bb}', '\\u{4bb}', SC_Lower), ('\\u{4bc}', '\\u{4bc}', SC_Upper), ('\\u{4bd}', '\\u{4bd}',\n        SC_Lower), ('\\u{4be}', '\\u{4be}', SC_Upper), ('\\u{4bf}', '\\u{4bf}', SC_Lower), ('\\u{4c0}',\n        '\\u{4c1}', SC_Upper), ('\\u{4c2}', '\\u{4c2}', SC_Lower), ('\\u{4c3}', '\\u{4c3}', SC_Upper),\n        ('\\u{4c4}', '\\u{4c4}', SC_Lower), ('\\u{4c5}', '\\u{4c5}', SC_Upper), ('\\u{4c6}', '\\u{4c6}',\n        SC_Lower), ('\\u{4c7}', '\\u{4c7}', SC_Upper), ('\\u{4c8}', '\\u{4c8}', SC_Lower), ('\\u{4c9}',\n        '\\u{4c9}', SC_Upper), ('\\u{4ca}', '\\u{4ca}', SC_Lower), ('\\u{4cb}', '\\u{4cb}', SC_Upper),\n        ('\\u{4cc}', '\\u{4cc}', SC_Lower), ('\\u{4cd}', '\\u{4cd}', SC_Upper), ('\\u{4ce}', '\\u{4cf}',\n        SC_Lower), ('\\u{4d0}', '\\u{4d0}', SC_Upper), ('\\u{4d1}', '\\u{4d1}', SC_Lower), ('\\u{4d2}',\n        '\\u{4d2}', SC_Upper), ('\\u{4d3}', '\\u{4d3}', SC_Lower), ('\\u{4d4}', '\\u{4d4}', SC_Upper),\n        ('\\u{4d5}', '\\u{4d5}', SC_Lower), ('\\u{4d6}', '\\u{4d6}', SC_Upper), ('\\u{4d7}', '\\u{4d7}',\n        SC_Lower), ('\\u{4d8}', '\\u{4d8}', SC_Upper), ('\\u{4d9}', '\\u{4d9}', SC_Lower), ('\\u{4da}',\n        '\\u{4da}', SC_Upper), ('\\u{4db}', '\\u{4db}', SC_Lower), ('\\u{4dc}', '\\u{4dc}', SC_Upper),\n        ('\\u{4dd}', '\\u{4dd}', SC_Lower), ('\\u{4de}', '\\u{4de}', SC_Upper), ('\\u{4df}', '\\u{4df}',\n        SC_Lower), ('\\u{4e0}', '\\u{4e0}', SC_Upper), ('\\u{4e1}', '\\u{4e1}', SC_Lower), ('\\u{4e2}',\n        '\\u{4e2}', SC_Upper), ('\\u{4e3}', '\\u{4e3}', SC_Lower), ('\\u{4e4}', '\\u{4e4}', SC_Upper),\n        ('\\u{4e5}', '\\u{4e5}', SC_Lower), ('\\u{4e6}', '\\u{4e6}', SC_Upper), ('\\u{4e7}', '\\u{4e7}',\n        SC_Lower), ('\\u{4e8}', '\\u{4e8}', SC_Upper), ('\\u{4e9}', '\\u{4e9}', SC_Lower), ('\\u{4ea}',\n        '\\u{4ea}', SC_Upper), ('\\u{4eb}', '\\u{4eb}', SC_Lower), ('\\u{4ec}', '\\u{4ec}', SC_Upper),\n        ('\\u{4ed}', '\\u{4ed}', SC_Lower), ('\\u{4ee}', '\\u{4ee}', SC_Upper), ('\\u{4ef}', '\\u{4ef}',\n        SC_Lower), ('\\u{4f0}', '\\u{4f0}', SC_Upper), ('\\u{4f1}', '\\u{4f1}', SC_Lower), ('\\u{4f2}',\n        '\\u{4f2}', SC_Upper), ('\\u{4f3}', '\\u{4f3}', SC_Lower), ('\\u{4f4}', '\\u{4f4}', SC_Upper),\n        ('\\u{4f5}', '\\u{4f5}', SC_Lower), ('\\u{4f6}', '\\u{4f6}', SC_Upper), ('\\u{4f7}', '\\u{4f7}',\n        SC_Lower), ('\\u{4f8}', '\\u{4f8}', SC_Upper), ('\\u{4f9}', '\\u{4f9}', SC_Lower), ('\\u{4fa}',\n        '\\u{4fa}', SC_Upper), ('\\u{4fb}', '\\u{4fb}', SC_Lower), ('\\u{4fc}', '\\u{4fc}', SC_Upper),\n        ('\\u{4fd}', '\\u{4fd}', SC_Lower), ('\\u{4fe}', '\\u{4fe}', SC_Upper), ('\\u{4ff}', '\\u{4ff}',\n        SC_Lower), ('\\u{500}', '\\u{500}', SC_Upper), ('\\u{501}', '\\u{501}', SC_Lower), ('\\u{502}',\n        '\\u{502}', SC_Upper), ('\\u{503}', '\\u{503}', SC_Lower), ('\\u{504}', '\\u{504}', SC_Upper),\n        ('\\u{505}', '\\u{505}', SC_Lower), ('\\u{506}', '\\u{506}', SC_Upper), ('\\u{507}', '\\u{507}',\n        SC_Lower), ('\\u{508}', '\\u{508}', SC_Upper), ('\\u{509}', '\\u{509}', SC_Lower), ('\\u{50a}',\n        '\\u{50a}', SC_Upper), ('\\u{50b}', '\\u{50b}', SC_Lower), ('\\u{50c}', '\\u{50c}', SC_Upper),\n        ('\\u{50d}', '\\u{50d}', SC_Lower), ('\\u{50e}', '\\u{50e}', SC_Upper), ('\\u{50f}', '\\u{50f}',\n        SC_Lower), ('\\u{510}', '\\u{510}', SC_Upper), ('\\u{511}', '\\u{511}', SC_Lower), ('\\u{512}',\n        '\\u{512}', SC_Upper), ('\\u{513}', '\\u{513}', SC_Lower), ('\\u{514}', '\\u{514}', SC_Upper),\n        ('\\u{515}', '\\u{515}', SC_Lower), ('\\u{516}', '\\u{516}', SC_Upper), ('\\u{517}', '\\u{517}',\n        SC_Lower), ('\\u{518}', '\\u{518}', SC_Upper), ('\\u{519}', '\\u{519}', SC_Lower), ('\\u{51a}',\n        '\\u{51a}', SC_Upper), ('\\u{51b}', '\\u{51b}', SC_Lower), ('\\u{51c}', '\\u{51c}', SC_Upper),\n        ('\\u{51d}', '\\u{51d}', SC_Lower), ('\\u{51e}', '\\u{51e}', SC_Upper), ('\\u{51f}', '\\u{51f}',\n        SC_Lower), ('\\u{520}', '\\u{520}', SC_Upper), ('\\u{521}', '\\u{521}', SC_Lower), ('\\u{522}',\n        '\\u{522}', SC_Upper), ('\\u{523}', '\\u{523}', SC_Lower), ('\\u{524}', '\\u{524}', SC_Upper),\n        ('\\u{525}', '\\u{525}', SC_Lower), ('\\u{526}', '\\u{526}', SC_Upper), ('\\u{527}', '\\u{527}',\n        SC_Lower), ('\\u{528}', '\\u{528}', SC_Upper), ('\\u{529}', '\\u{529}', SC_Lower), ('\\u{52a}',\n        '\\u{52a}', SC_Upper), ('\\u{52b}', '\\u{52b}', SC_Lower), ('\\u{52c}', '\\u{52c}', SC_Upper),\n        ('\\u{52d}', '\\u{52d}', SC_Lower), ('\\u{52e}', '\\u{52e}', SC_Upper), ('\\u{52f}', '\\u{52f}',\n        SC_Lower), ('\\u{531}', '\\u{556}', SC_Upper), ('\\u{559}', '\\u{559}', SC_OLetter), ('\\u{55d}',\n        '\\u{55d}', SC_SContinue), ('\\u{560}', '\\u{588}', SC_Lower), ('\\u{589}', '\\u{589}',\n        SC_STerm), ('\\u{591}', '\\u{5bd}', SC_Extend), ('\\u{5bf}', '\\u{5bf}', SC_Extend), ('\\u{5c1}',\n        '\\u{5c2}', SC_Extend), ('\\u{5c4}', '\\u{5c5}', SC_Extend), ('\\u{5c7}', '\\u{5c7}', SC_Extend),\n        ('\\u{5d0}', '\\u{5ea}', SC_OLetter), ('\\u{5ef}', '\\u{5f3}', SC_OLetter), ('\\u{600}',\n        '\\u{605}', SC_Numeric), ('\\u{60c}', '\\u{60d}', SC_SContinue), ('\\u{610}', '\\u{61a}',\n        SC_Extend), ('\\u{61c}', '\\u{61c}', SC_Format), ('\\u{61d}', '\\u{61f}', SC_STerm), ('\\u{620}',\n        '\\u{64a}', SC_OLetter), ('\\u{64b}', '\\u{65f}', SC_Extend), ('\\u{660}', '\\u{669}',\n        SC_Numeric), ('\\u{66b}', '\\u{66c}', SC_Numeric), ('\\u{66e}', '\\u{66f}', SC_OLetter),\n        ('\\u{670}', '\\u{670}', SC_Extend), ('\\u{671}', '\\u{6d3}', SC_OLetter), ('\\u{6d4}',\n        '\\u{6d4}', SC_STerm), ('\\u{6d5}', '\\u{6d5}', SC_OLetter), ('\\u{6d6}', '\\u{6dc}', SC_Extend),\n        ('\\u{6dd}', '\\u{6dd}', SC_Numeric), ('\\u{6df}', '\\u{6e4}', SC_Extend), ('\\u{6e5}',\n        '\\u{6e6}', SC_OLetter), ('\\u{6e7}', '\\u{6e8}', SC_Extend), ('\\u{6ea}', '\\u{6ed}',\n        SC_Extend), ('\\u{6ee}', '\\u{6ef}', SC_OLetter), ('\\u{6f0}', '\\u{6f9}', SC_Numeric),\n        ('\\u{6fa}', '\\u{6fc}', SC_OLetter), ('\\u{6ff}', '\\u{6ff}', SC_OLetter), ('\\u{700}',\n        '\\u{702}', SC_STerm), ('\\u{70f}', '\\u{70f}', SC_Format), ('\\u{710}', '\\u{710}', SC_OLetter),\n        ('\\u{711}', '\\u{711}', SC_Extend), ('\\u{712}', '\\u{72f}', SC_OLetter), ('\\u{730}',\n        '\\u{74a}', SC_Extend), ('\\u{74d}', '\\u{7a5}', SC_OLetter), ('\\u{7a6}', '\\u{7b0}',\n        SC_Extend), ('\\u{7b1}', '\\u{7b1}', SC_OLetter), ('\\u{7c0}', '\\u{7c9}', SC_Numeric),\n        ('\\u{7ca}', '\\u{7ea}', SC_OLetter), ('\\u{7eb}', '\\u{7f3}', SC_Extend), ('\\u{7f4}',\n        '\\u{7f5}', SC_OLetter), ('\\u{7f8}', '\\u{7f8}', SC_SContinue), ('\\u{7f9}', '\\u{7f9}',\n        SC_STerm), ('\\u{7fa}', '\\u{7fa}', SC_OLetter), ('\\u{7fd}', '\\u{7fd}', SC_Extend),\n        ('\\u{800}', '\\u{815}', SC_OLetter), ('\\u{816}', '\\u{819}', SC_Extend), ('\\u{81a}',\n        '\\u{81a}', SC_OLetter), ('\\u{81b}', '\\u{823}', SC_Extend), ('\\u{824}', '\\u{824}',\n        SC_OLetter), ('\\u{825}', '\\u{827}', SC_Extend), ('\\u{828}', '\\u{828}', SC_OLetter),\n        ('\\u{829}', '\\u{82d}', SC_Extend), ('\\u{837}', '\\u{837}', SC_STerm), ('\\u{839}', '\\u{839}',\n        SC_STerm), ('\\u{83d}', '\\u{83e}', SC_STerm), ('\\u{840}', '\\u{858}', SC_OLetter), ('\\u{859}',\n        '\\u{85b}', SC_Extend), ('\\u{860}', '\\u{86a}', SC_OLetter), ('\\u{870}', '\\u{887}',\n        SC_OLetter), ('\\u{889}', '\\u{88f}', SC_OLetter), ('\\u{890}', '\\u{891}', SC_Numeric),\n        ('\\u{897}', '\\u{89f}', SC_Extend), ('\\u{8a0}', '\\u{8c9}', SC_OLetter), ('\\u{8ca}',\n        '\\u{8e1}', SC_Extend), ('\\u{8e2}', '\\u{8e2}', SC_Numeric), ('\\u{8e3}', '\\u{903}',\n        SC_Extend), ('\\u{904}', '\\u{939}', SC_OLetter), ('\\u{93a}', '\\u{93c}', SC_Extend),\n        ('\\u{93d}', '\\u{93d}', SC_OLetter), ('\\u{93e}', '\\u{94f}', SC_Extend), ('\\u{950}',\n        '\\u{950}', SC_OLetter), ('\\u{951}', '\\u{957}', SC_Extend), ('\\u{958}', '\\u{961}',\n        SC_OLetter), ('\\u{962}', '\\u{963}', SC_Extend), ('\\u{964}', '\\u{965}', SC_STerm),\n        ('\\u{966}', '\\u{96f}', SC_Numeric), ('\\u{971}', '\\u{980}', SC_OLetter), ('\\u{981}',\n        '\\u{983}', SC_Extend), ('\\u{985}', '\\u{98c}', SC_OLetter), ('\\u{98f}', '\\u{990}',\n        SC_OLetter), ('\\u{993}', '\\u{9a8}', SC_OLetter), ('\\u{9aa}', '\\u{9b0}', SC_OLetter),\n        ('\\u{9b2}', '\\u{9b2}', SC_OLetter), ('\\u{9b6}', '\\u{9b9}', SC_OLetter), ('\\u{9bc}',\n        '\\u{9bc}', SC_Extend), ('\\u{9bd}', '\\u{9bd}', SC_OLetter), ('\\u{9be}', '\\u{9c4}',\n        SC_Extend), ('\\u{9c7}', '\\u{9c8}', SC_Extend), ('\\u{9cb}', '\\u{9cd}', SC_Extend),\n        ('\\u{9ce}', '\\u{9ce}', SC_OLetter), ('\\u{9d7}', '\\u{9d7}', SC_Extend), ('\\u{9dc}',\n        '\\u{9dd}', SC_OLetter), ('\\u{9df}', '\\u{9e1}', SC_OLetter), ('\\u{9e2}', '\\u{9e3}',\n        SC_Extend), ('\\u{9e6}', '\\u{9ef}', SC_Numeric), ('\\u{9f0}', '\\u{9f1}', SC_OLetter),\n        ('\\u{9fc}', '\\u{9fc}', SC_OLetter), ('\\u{9fe}', '\\u{9fe}', SC_Extend), ('\\u{a01}',\n        '\\u{a03}', SC_Extend), ('\\u{a05}', '\\u{a0a}', SC_OLetter), ('\\u{a0f}', '\\u{a10}',\n        SC_OLetter), ('\\u{a13}', '\\u{a28}', SC_OLetter), ('\\u{a2a}', '\\u{a30}', SC_OLetter),\n        ('\\u{a32}', '\\u{a33}', SC_OLetter), ('\\u{a35}', '\\u{a36}', SC_OLetter), ('\\u{a38}',\n        '\\u{a39}', SC_OLetter), ('\\u{a3c}', '\\u{a3c}', SC_Extend), ('\\u{a3e}', '\\u{a42}',\n        SC_Extend), ('\\u{a47}', '\\u{a48}', SC_Extend), ('\\u{a4b}', '\\u{a4d}', SC_Extend),\n        ('\\u{a51}', '\\u{a51}', SC_Extend), ('\\u{a59}', '\\u{a5c}', SC_OLetter), ('\\u{a5e}',\n        '\\u{a5e}', SC_OLetter), ('\\u{a66}', '\\u{a6f}', SC_Numeric), ('\\u{a70}', '\\u{a71}',\n        SC_Extend), ('\\u{a72}', '\\u{a74}', SC_OLetter), ('\\u{a75}', '\\u{a75}', SC_Extend),\n        ('\\u{a81}', '\\u{a83}', SC_Extend), ('\\u{a85}', '\\u{a8d}', SC_OLetter), ('\\u{a8f}',\n        '\\u{a91}', SC_OLetter), ('\\u{a93}', '\\u{aa8}', SC_OLetter), ('\\u{aaa}', '\\u{ab0}',\n        SC_OLetter), ('\\u{ab2}', '\\u{ab3}', SC_OLetter), ('\\u{ab5}', '\\u{ab9}', SC_OLetter),\n        ('\\u{abc}', '\\u{abc}', SC_Extend), ('\\u{abd}', '\\u{abd}', SC_OLetter), ('\\u{abe}',\n        '\\u{ac5}', SC_Extend), ('\\u{ac7}', '\\u{ac9}', SC_Extend), ('\\u{acb}', '\\u{acd}', SC_Extend),\n        ('\\u{ad0}', '\\u{ad0}', SC_OLetter), ('\\u{ae0}', '\\u{ae1}', SC_OLetter), ('\\u{ae2}',\n        '\\u{ae3}', SC_Extend), ('\\u{ae6}', '\\u{aef}', SC_Numeric), ('\\u{af9}', '\\u{af9}',\n        SC_OLetter), ('\\u{afa}', '\\u{aff}', SC_Extend), ('\\u{b01}', '\\u{b03}', SC_Extend),\n        ('\\u{b05}', '\\u{b0c}', SC_OLetter), ('\\u{b0f}', '\\u{b10}', SC_OLetter), ('\\u{b13}',\n        '\\u{b28}', SC_OLetter), ('\\u{b2a}', '\\u{b30}', SC_OLetter), ('\\u{b32}', '\\u{b33}',\n        SC_OLetter), ('\\u{b35}', '\\u{b39}', SC_OLetter), ('\\u{b3c}', '\\u{b3c}', SC_Extend),\n        ('\\u{b3d}', '\\u{b3d}', SC_OLetter), ('\\u{b3e}', '\\u{b44}', SC_Extend), ('\\u{b47}',\n        '\\u{b48}', SC_Extend), ('\\u{b4b}', '\\u{b4d}', SC_Extend), ('\\u{b55}', '\\u{b57}', SC_Extend),\n        ('\\u{b5c}', '\\u{b5d}', SC_OLetter), ('\\u{b5f}', '\\u{b61}', SC_OLetter), ('\\u{b62}',\n        '\\u{b63}', SC_Extend), ('\\u{b66}', '\\u{b6f}', SC_Numeric), ('\\u{b71}', '\\u{b71}',\n        SC_OLetter), ('\\u{b82}', '\\u{b82}', SC_Extend), ('\\u{b83}', '\\u{b83}', SC_OLetter),\n        ('\\u{b85}', '\\u{b8a}', SC_OLetter), ('\\u{b8e}', '\\u{b90}', SC_OLetter), ('\\u{b92}',\n        '\\u{b95}', SC_OLetter), ('\\u{b99}', '\\u{b9a}', SC_OLetter), ('\\u{b9c}', '\\u{b9c}',\n        SC_OLetter), ('\\u{b9e}', '\\u{b9f}', SC_OLetter), ('\\u{ba3}', '\\u{ba4}', SC_OLetter),\n        ('\\u{ba8}', '\\u{baa}', SC_OLetter), ('\\u{bae}', '\\u{bb9}', SC_OLetter), ('\\u{bbe}',\n        '\\u{bc2}', SC_Extend), ('\\u{bc6}', '\\u{bc8}', SC_Extend), ('\\u{bca}', '\\u{bcd}', SC_Extend),\n        ('\\u{bd0}', '\\u{bd0}', SC_OLetter), ('\\u{bd7}', '\\u{bd7}', SC_Extend), ('\\u{be6}',\n        '\\u{bef}', SC_Numeric), ('\\u{c00}', '\\u{c04}', SC_Extend), ('\\u{c05}', '\\u{c0c}',\n        SC_OLetter), ('\\u{c0e}', '\\u{c10}', SC_OLetter), ('\\u{c12}', '\\u{c28}', SC_OLetter),\n        ('\\u{c2a}', '\\u{c39}', SC_OLetter), ('\\u{c3c}', '\\u{c3c}', SC_Extend), ('\\u{c3d}',\n        '\\u{c3d}', SC_OLetter), ('\\u{c3e}', '\\u{c44}', SC_Extend), ('\\u{c46}', '\\u{c48}',\n        SC_Extend), ('\\u{c4a}', '\\u{c4d}', SC_Extend), ('\\u{c55}', '\\u{c56}', SC_Extend),\n        ('\\u{c58}', '\\u{c5a}', SC_OLetter), ('\\u{c5c}', '\\u{c5d}', SC_OLetter), ('\\u{c60}',\n        '\\u{c61}', SC_OLetter), ('\\u{c62}', '\\u{c63}', SC_Extend), ('\\u{c66}', '\\u{c6f}',\n        SC_Numeric), ('\\u{c80}', '\\u{c80}', SC_OLetter), ('\\u{c81}', '\\u{c83}', SC_Extend),\n        ('\\u{c85}', '\\u{c8c}', SC_OLetter), ('\\u{c8e}', '\\u{c90}', SC_OLetter), ('\\u{c92}',\n        '\\u{ca8}', SC_OLetter), ('\\u{caa}', '\\u{cb3}', SC_OLetter), ('\\u{cb5}', '\\u{cb9}',\n        SC_OLetter), ('\\u{cbc}', '\\u{cbc}', SC_Extend), ('\\u{cbd}', '\\u{cbd}', SC_OLetter),\n        ('\\u{cbe}', '\\u{cc4}', SC_Extend), ('\\u{cc6}', '\\u{cc8}', SC_Extend), ('\\u{cca}', '\\u{ccd}',\n        SC_Extend), ('\\u{cd5}', '\\u{cd6}', SC_Extend), ('\\u{cdc}', '\\u{cde}', SC_OLetter),\n        ('\\u{ce0}', '\\u{ce1}', SC_OLetter), ('\\u{ce2}', '\\u{ce3}', SC_Extend), ('\\u{ce6}',\n        '\\u{cef}', SC_Numeric), ('\\u{cf1}', '\\u{cf2}', SC_OLetter), ('\\u{cf3}', '\\u{cf3}',\n        SC_Extend), ('\\u{d00}', '\\u{d03}', SC_Extend), ('\\u{d04}', '\\u{d0c}', SC_OLetter),\n        ('\\u{d0e}', '\\u{d10}', SC_OLetter), ('\\u{d12}', '\\u{d3a}', SC_OLetter), ('\\u{d3b}',\n        '\\u{d3c}', SC_Extend), ('\\u{d3d}', '\\u{d3d}', SC_OLetter), ('\\u{d3e}', '\\u{d44}',\n        SC_Extend), ('\\u{d46}', '\\u{d48}', SC_Extend), ('\\u{d4a}', '\\u{d4d}', SC_Extend),\n        ('\\u{d4e}', '\\u{d4e}', SC_OLetter), ('\\u{d54}', '\\u{d56}', SC_OLetter), ('\\u{d57}',\n        '\\u{d57}', SC_Extend), ('\\u{d5f}', '\\u{d61}', SC_OLetter), ('\\u{d62}', '\\u{d63}',\n        SC_Extend), ('\\u{d66}', '\\u{d6f}', SC_Numeric), ('\\u{d7a}', '\\u{d7f}', SC_OLetter),\n        ('\\u{d81}', '\\u{d83}', SC_Extend), ('\\u{d85}', '\\u{d96}', SC_OLetter), ('\\u{d9a}',\n        '\\u{db1}', SC_OLetter), ('\\u{db3}', '\\u{dbb}', SC_OLetter), ('\\u{dbd}', '\\u{dbd}',\n        SC_OLetter), ('\\u{dc0}', '\\u{dc6}', SC_OLetter), ('\\u{dca}', '\\u{dca}', SC_Extend),\n        ('\\u{dcf}', '\\u{dd4}', SC_Extend), ('\\u{dd6}', '\\u{dd6}', SC_Extend), ('\\u{dd8}', '\\u{ddf}',\n        SC_Extend), ('\\u{de6}', '\\u{def}', SC_Numeric), ('\\u{df2}', '\\u{df3}', SC_Extend),\n        ('\\u{e01}', '\\u{e30}', SC_OLetter), ('\\u{e31}', '\\u{e31}', SC_Extend), ('\\u{e32}',\n        '\\u{e33}', SC_OLetter), ('\\u{e34}', '\\u{e3a}', SC_Extend), ('\\u{e40}', '\\u{e46}',\n        SC_OLetter), ('\\u{e47}', '\\u{e4e}', SC_Extend), ('\\u{e50}', '\\u{e59}', SC_Numeric),\n        ('\\u{e81}', '\\u{e82}', SC_OLetter), ('\\u{e84}', '\\u{e84}', SC_OLetter), ('\\u{e86}',\n        '\\u{e8a}', SC_OLetter), ('\\u{e8c}', '\\u{ea3}', SC_OLetter), ('\\u{ea5}', '\\u{ea5}',\n        SC_OLetter), ('\\u{ea7}', '\\u{eb0}', SC_OLetter), ('\\u{eb1}', '\\u{eb1}', SC_Extend),\n        ('\\u{eb2}', '\\u{eb3}', SC_OLetter), ('\\u{eb4}', '\\u{ebc}', SC_Extend), ('\\u{ebd}',\n        '\\u{ebd}', SC_OLetter), ('\\u{ec0}', '\\u{ec4}', SC_OLetter), ('\\u{ec6}', '\\u{ec6}',\n        SC_OLetter), ('\\u{ec8}', '\\u{ece}', SC_Extend), ('\\u{ed0}', '\\u{ed9}', SC_Numeric),\n        ('\\u{edc}', '\\u{edf}', SC_OLetter), ('\\u{f00}', '\\u{f00}', SC_OLetter), ('\\u{f18}',\n        '\\u{f19}', SC_Extend), ('\\u{f20}', '\\u{f29}', SC_Numeric), ('\\u{f35}', '\\u{f35}',\n        SC_Extend), ('\\u{f37}', '\\u{f37}', SC_Extend), ('\\u{f39}', '\\u{f39}', SC_Extend),\n        ('\\u{f3a}', '\\u{f3d}', SC_Close), ('\\u{f3e}', '\\u{f3f}', SC_Extend), ('\\u{f40}', '\\u{f47}',\n        SC_OLetter), ('\\u{f49}', '\\u{f6c}', SC_OLetter), ('\\u{f71}', '\\u{f84}', SC_Extend),\n        ('\\u{f86}', '\\u{f87}', SC_Extend), ('\\u{f88}', '\\u{f8c}', SC_OLetter), ('\\u{f8d}',\n        '\\u{f97}', SC_Extend), ('\\u{f99}', '\\u{fbc}', SC_Extend), ('\\u{fc6}', '\\u{fc6}', SC_Extend),\n        ('\\u{1000}', '\\u{102a}', SC_OLetter), ('\\u{102b}', '\\u{103e}', SC_Extend), ('\\u{103f}',\n        '\\u{103f}', SC_OLetter), ('\\u{1040}', '\\u{1049}', SC_Numeric), ('\\u{104a}', '\\u{104b}',\n        SC_STerm), ('\\u{1050}', '\\u{1055}', SC_OLetter), ('\\u{1056}', '\\u{1059}', SC_Extend),\n        ('\\u{105a}', '\\u{105d}', SC_OLetter), ('\\u{105e}', '\\u{1060}', SC_Extend), ('\\u{1061}',\n        '\\u{1061}', SC_OLetter), ('\\u{1062}', '\\u{1064}', SC_Extend), ('\\u{1065}', '\\u{1066}',\n        SC_OLetter), ('\\u{1067}', '\\u{106d}', SC_Extend), ('\\u{106e}', '\\u{1070}', SC_OLetter),\n        ('\\u{1071}', '\\u{1074}', SC_Extend), ('\\u{1075}', '\\u{1081}', SC_OLetter), ('\\u{1082}',\n        '\\u{108d}', SC_Extend), ('\\u{108e}', '\\u{108e}', SC_OLetter), ('\\u{108f}', '\\u{108f}',\n        SC_Extend), ('\\u{1090}', '\\u{1099}', SC_Numeric), ('\\u{109a}', '\\u{109d}', SC_Extend),\n        ('\\u{10a0}', '\\u{10c5}', SC_Upper), ('\\u{10c7}', '\\u{10c7}', SC_Upper), ('\\u{10cd}',\n        '\\u{10cd}', SC_Upper), ('\\u{10d0}', '\\u{10fa}', SC_OLetter), ('\\u{10fc}', '\\u{10fc}',\n        SC_Lower), ('\\u{10fd}', '\\u{1248}', SC_OLetter), ('\\u{124a}', '\\u{124d}', SC_OLetter),\n        ('\\u{1250}', '\\u{1256}', SC_OLetter), ('\\u{1258}', '\\u{1258}', SC_OLetter), ('\\u{125a}',\n        '\\u{125d}', SC_OLetter), ('\\u{1260}', '\\u{1288}', SC_OLetter), ('\\u{128a}', '\\u{128d}',\n        SC_OLetter), ('\\u{1290}', '\\u{12b0}', SC_OLetter), ('\\u{12b2}', '\\u{12b5}', SC_OLetter),\n        ('\\u{12b8}', '\\u{12be}', SC_OLetter), ('\\u{12c0}', '\\u{12c0}', SC_OLetter), ('\\u{12c2}',\n        '\\u{12c5}', SC_OLetter), ('\\u{12c8}', '\\u{12d6}', SC_OLetter), ('\\u{12d8}', '\\u{1310}',\n        SC_OLetter), ('\\u{1312}', '\\u{1315}', SC_OLetter), ('\\u{1318}', '\\u{135a}', SC_OLetter),\n        ('\\u{135d}', '\\u{135f}', SC_Extend), ('\\u{1362}', '\\u{1362}', SC_STerm), ('\\u{1367}',\n        '\\u{1368}', SC_STerm), ('\\u{1380}', '\\u{138f}', SC_OLetter), ('\\u{13a0}', '\\u{13f5}',\n        SC_Upper), ('\\u{13f8}', '\\u{13fd}', SC_Lower), ('\\u{1401}', '\\u{166c}', SC_OLetter),\n        ('\\u{166e}', '\\u{166e}', SC_STerm), ('\\u{166f}', '\\u{167f}', SC_OLetter), ('\\u{1680}',\n        '\\u{1680}', SC_Sp), ('\\u{1681}', '\\u{169a}', SC_OLetter), ('\\u{169b}', '\\u{169c}',\n        SC_Close), ('\\u{16a0}', '\\u{16ea}', SC_OLetter), ('\\u{16ee}', '\\u{16f8}', SC_OLetter),\n        ('\\u{1700}', '\\u{1711}', SC_OLetter), ('\\u{1712}', '\\u{1715}', SC_Extend), ('\\u{171f}',\n        '\\u{1731}', SC_OLetter), ('\\u{1732}', '\\u{1734}', SC_Extend), ('\\u{1735}', '\\u{1736}',\n        SC_STerm), ('\\u{1740}', '\\u{1751}', SC_OLetter), ('\\u{1752}', '\\u{1753}', SC_Extend),\n        ('\\u{1760}', '\\u{176c}', SC_OLetter), ('\\u{176e}', '\\u{1770}', SC_OLetter), ('\\u{1772}',\n        '\\u{1773}', SC_Extend), ('\\u{1780}', '\\u{17b3}', SC_OLetter), ('\\u{17b4}', '\\u{17d3}',\n        SC_Extend), ('\\u{17d4}', '\\u{17d5}', SC_STerm), ('\\u{17d7}', '\\u{17d7}', SC_OLetter),\n        ('\\u{17dc}', '\\u{17dc}', SC_OLetter), ('\\u{17dd}', '\\u{17dd}', SC_Extend), ('\\u{17e0}',\n        '\\u{17e9}', SC_Numeric), ('\\u{1802}', '\\u{1802}', SC_SContinue), ('\\u{1803}', '\\u{1803}',\n        SC_STerm), ('\\u{1808}', '\\u{1808}', SC_SContinue), ('\\u{1809}', '\\u{1809}', SC_STerm),\n        ('\\u{180b}', '\\u{180d}', SC_Extend), ('\\u{180e}', '\\u{180e}', SC_Format), ('\\u{180f}',\n        '\\u{180f}', SC_Extend), ('\\u{1810}', '\\u{1819}', SC_Numeric), ('\\u{1820}', '\\u{1878}',\n        SC_OLetter), ('\\u{1880}', '\\u{1884}', SC_OLetter), ('\\u{1885}', '\\u{1886}', SC_Extend),\n        ('\\u{1887}', '\\u{18a8}', SC_OLetter), ('\\u{18a9}', '\\u{18a9}', SC_Extend), ('\\u{18aa}',\n        '\\u{18aa}', SC_OLetter), ('\\u{18b0}', '\\u{18f5}', SC_OLetter), ('\\u{1900}', '\\u{191e}',\n        SC_OLetter), ('\\u{1920}', '\\u{192b}', SC_Extend), ('\\u{1930}', '\\u{193b}', SC_Extend),\n        ('\\u{1944}', '\\u{1945}', SC_STerm), ('\\u{1946}', '\\u{194f}', SC_Numeric), ('\\u{1950}',\n        '\\u{196d}', SC_OLetter), ('\\u{1970}', '\\u{1974}', SC_OLetter), ('\\u{1980}', '\\u{19ab}',\n        SC_OLetter), ('\\u{19b0}', '\\u{19c9}', SC_OLetter), ('\\u{19d0}', '\\u{19da}', SC_Numeric),\n        ('\\u{1a00}', '\\u{1a16}', SC_OLetter), ('\\u{1a17}', '\\u{1a1b}', SC_Extend), ('\\u{1a20}',\n        '\\u{1a54}', SC_OLetter), ('\\u{1a55}', '\\u{1a5e}', SC_Extend), ('\\u{1a60}', '\\u{1a7c}',\n        SC_Extend), ('\\u{1a7f}', '\\u{1a7f}', SC_Extend), ('\\u{1a80}', '\\u{1a89}', SC_Numeric),\n        ('\\u{1a90}', '\\u{1a99}', SC_Numeric), ('\\u{1aa7}', '\\u{1aa7}', SC_OLetter), ('\\u{1aa8}',\n        '\\u{1aab}', SC_STerm), ('\\u{1ab0}', '\\u{1add}', SC_Extend), ('\\u{1ae0}', '\\u{1aeb}',\n        SC_Extend), ('\\u{1b00}', '\\u{1b04}', SC_Extend), ('\\u{1b05}', '\\u{1b33}', SC_OLetter),\n        ('\\u{1b34}', '\\u{1b44}', SC_Extend), ('\\u{1b45}', '\\u{1b4c}', SC_OLetter), ('\\u{1b4e}',\n        '\\u{1b4f}', SC_STerm), ('\\u{1b50}', '\\u{1b59}', SC_Numeric), ('\\u{1b5a}', '\\u{1b5b}',\n        SC_STerm), ('\\u{1b5e}', '\\u{1b5f}', SC_STerm), ('\\u{1b6b}', '\\u{1b73}', SC_Extend),\n        ('\\u{1b7d}', '\\u{1b7f}', SC_STerm), ('\\u{1b80}', '\\u{1b82}', SC_Extend), ('\\u{1b83}',\n        '\\u{1ba0}', SC_OLetter), ('\\u{1ba1}', '\\u{1bad}', SC_Extend), ('\\u{1bae}', '\\u{1baf}',\n        SC_OLetter), ('\\u{1bb0}', '\\u{1bb9}', SC_Numeric), ('\\u{1bba}', '\\u{1be5}', SC_OLetter),\n        ('\\u{1be6}', '\\u{1bf3}', SC_Extend), ('\\u{1c00}', '\\u{1c23}', SC_OLetter), ('\\u{1c24}',\n        '\\u{1c37}', SC_Extend), ('\\u{1c3b}', '\\u{1c3c}', SC_STerm), ('\\u{1c40}', '\\u{1c49}',\n        SC_Numeric), ('\\u{1c4d}', '\\u{1c4f}', SC_OLetter), ('\\u{1c50}', '\\u{1c59}', SC_Numeric),\n        ('\\u{1c5a}', '\\u{1c7d}', SC_OLetter), ('\\u{1c7e}', '\\u{1c7f}', SC_STerm), ('\\u{1c80}',\n        '\\u{1c88}', SC_Lower), ('\\u{1c89}', '\\u{1c89}', SC_Upper), ('\\u{1c8a}', '\\u{1c8a}',\n        SC_Lower), ('\\u{1c90}', '\\u{1cba}', SC_OLetter), ('\\u{1cbd}', '\\u{1cbf}', SC_OLetter),\n        ('\\u{1cd0}', '\\u{1cd2}', SC_Extend), ('\\u{1cd4}', '\\u{1ce8}', SC_Extend), ('\\u{1ce9}',\n        '\\u{1cec}', SC_OLetter), ('\\u{1ced}', '\\u{1ced}', SC_Extend), ('\\u{1cee}', '\\u{1cf3}',\n        SC_OLetter), ('\\u{1cf4}', '\\u{1cf4}', SC_Extend), ('\\u{1cf5}', '\\u{1cf6}', SC_OLetter),\n        ('\\u{1cf7}', '\\u{1cf9}', SC_Extend), ('\\u{1cfa}', '\\u{1cfa}', SC_OLetter), ('\\u{1d00}',\n        '\\u{1dbf}', SC_Lower), ('\\u{1dc0}', '\\u{1dff}', SC_Extend), ('\\u{1e00}', '\\u{1e00}',\n        SC_Upper), ('\\u{1e01}', '\\u{1e01}', SC_Lower), ('\\u{1e02}', '\\u{1e02}', SC_Upper),\n        ('\\u{1e03}', '\\u{1e03}', SC_Lower), ('\\u{1e04}', '\\u{1e04}', SC_Upper), ('\\u{1e05}',\n        '\\u{1e05}', SC_Lower), ('\\u{1e06}', '\\u{1e06}', SC_Upper), ('\\u{1e07}', '\\u{1e07}',\n        SC_Lower), ('\\u{1e08}', '\\u{1e08}', SC_Upper), ('\\u{1e09}', '\\u{1e09}', SC_Lower),\n        ('\\u{1e0a}', '\\u{1e0a}', SC_Upper), ('\\u{1e0b}', '\\u{1e0b}', SC_Lower), ('\\u{1e0c}',\n        '\\u{1e0c}', SC_Upper), ('\\u{1e0d}', '\\u{1e0d}', SC_Lower), ('\\u{1e0e}', '\\u{1e0e}',\n        SC_Upper), ('\\u{1e0f}', '\\u{1e0f}', SC_Lower), ('\\u{1e10}', '\\u{1e10}', SC_Upper),\n        ('\\u{1e11}', '\\u{1e11}', SC_Lower), ('\\u{1e12}', '\\u{1e12}', SC_Upper), ('\\u{1e13}',\n        '\\u{1e13}', SC_Lower), ('\\u{1e14}', '\\u{1e14}', SC_Upper), ('\\u{1e15}', '\\u{1e15}',\n        SC_Lower), ('\\u{1e16}', '\\u{1e16}', SC_Upper), ('\\u{1e17}', '\\u{1e17}', SC_Lower),\n        ('\\u{1e18}', '\\u{1e18}', SC_Upper), ('\\u{1e19}', '\\u{1e19}', SC_Lower), ('\\u{1e1a}',\n        '\\u{1e1a}', SC_Upper), ('\\u{1e1b}', '\\u{1e1b}', SC_Lower), ('\\u{1e1c}', '\\u{1e1c}',\n        SC_Upper), ('\\u{1e1d}', '\\u{1e1d}', SC_Lower), ('\\u{1e1e}', '\\u{1e1e}', SC_Upper),\n        ('\\u{1e1f}', '\\u{1e1f}', SC_Lower), ('\\u{1e20}', '\\u{1e20}', SC_Upper), ('\\u{1e21}',\n        '\\u{1e21}', SC_Lower), ('\\u{1e22}', '\\u{1e22}', SC_Upper), ('\\u{1e23}', '\\u{1e23}',\n        SC_Lower), ('\\u{1e24}', '\\u{1e24}', SC_Upper), ('\\u{1e25}', '\\u{1e25}', SC_Lower),\n        ('\\u{1e26}', '\\u{1e26}', SC_Upper), ('\\u{1e27}', '\\u{1e27}', SC_Lower), ('\\u{1e28}',\n        '\\u{1e28}', SC_Upper), ('\\u{1e29}', '\\u{1e29}', SC_Lower), ('\\u{1e2a}', '\\u{1e2a}',\n        SC_Upper), ('\\u{1e2b}', '\\u{1e2b}', SC_Lower), ('\\u{1e2c}', '\\u{1e2c}', SC_Upper),\n        ('\\u{1e2d}', '\\u{1e2d}', SC_Lower), ('\\u{1e2e}', '\\u{1e2e}', SC_Upper), ('\\u{1e2f}',\n        '\\u{1e2f}', SC_Lower), ('\\u{1e30}', '\\u{1e30}', SC_Upper), ('\\u{1e31}', '\\u{1e31}',\n        SC_Lower), ('\\u{1e32}', '\\u{1e32}', SC_Upper), ('\\u{1e33}', '\\u{1e33}', SC_Lower),\n        ('\\u{1e34}', '\\u{1e34}', SC_Upper), ('\\u{1e35}', '\\u{1e35}', SC_Lower), ('\\u{1e36}',\n        '\\u{1e36}', SC_Upper), ('\\u{1e37}', '\\u{1e37}', SC_Lower), ('\\u{1e38}', '\\u{1e38}',\n        SC_Upper), ('\\u{1e39}', '\\u{1e39}', SC_Lower), ('\\u{1e3a}', '\\u{1e3a}', SC_Upper),\n        ('\\u{1e3b}', '\\u{1e3b}', SC_Lower), ('\\u{1e3c}', '\\u{1e3c}', SC_Upper), ('\\u{1e3d}',\n        '\\u{1e3d}', SC_Lower), ('\\u{1e3e}', '\\u{1e3e}', SC_Upper), ('\\u{1e3f}', '\\u{1e3f}',\n        SC_Lower), ('\\u{1e40}', '\\u{1e40}', SC_Upper), ('\\u{1e41}', '\\u{1e41}', SC_Lower),\n        ('\\u{1e42}', '\\u{1e42}', SC_Upper), ('\\u{1e43}', '\\u{1e43}', SC_Lower), ('\\u{1e44}',\n        '\\u{1e44}', SC_Upper), ('\\u{1e45}', '\\u{1e45}', SC_Lower), ('\\u{1e46}', '\\u{1e46}',\n        SC_Upper), ('\\u{1e47}', '\\u{1e47}', SC_Lower), ('\\u{1e48}', '\\u{1e48}', SC_Upper),\n        ('\\u{1e49}', '\\u{1e49}', SC_Lower), ('\\u{1e4a}', '\\u{1e4a}', SC_Upper), ('\\u{1e4b}',\n        '\\u{1e4b}', SC_Lower), ('\\u{1e4c}', '\\u{1e4c}', SC_Upper), ('\\u{1e4d}', '\\u{1e4d}',\n        SC_Lower), ('\\u{1e4e}', '\\u{1e4e}', SC_Upper), ('\\u{1e4f}', '\\u{1e4f}', SC_Lower),\n        ('\\u{1e50}', '\\u{1e50}', SC_Upper), ('\\u{1e51}', '\\u{1e51}', SC_Lower), ('\\u{1e52}',\n        '\\u{1e52}', SC_Upper), ('\\u{1e53}', '\\u{1e53}', SC_Lower), ('\\u{1e54}', '\\u{1e54}',\n        SC_Upper), ('\\u{1e55}', '\\u{1e55}', SC_Lower), ('\\u{1e56}', '\\u{1e56}', SC_Upper),\n        ('\\u{1e57}', '\\u{1e57}', SC_Lower), ('\\u{1e58}', '\\u{1e58}', SC_Upper), ('\\u{1e59}',\n        '\\u{1e59}', SC_Lower), ('\\u{1e5a}', '\\u{1e5a}', SC_Upper), ('\\u{1e5b}', '\\u{1e5b}',\n        SC_Lower), ('\\u{1e5c}', '\\u{1e5c}', SC_Upper), ('\\u{1e5d}', '\\u{1e5d}', SC_Lower),\n        ('\\u{1e5e}', '\\u{1e5e}', SC_Upper), ('\\u{1e5f}', '\\u{1e5f}', SC_Lower), ('\\u{1e60}',\n        '\\u{1e60}', SC_Upper), ('\\u{1e61}', '\\u{1e61}', SC_Lower), ('\\u{1e62}', '\\u{1e62}',\n        SC_Upper), ('\\u{1e63}', '\\u{1e63}', SC_Lower), ('\\u{1e64}', '\\u{1e64}', SC_Upper),\n        ('\\u{1e65}', '\\u{1e65}', SC_Lower), ('\\u{1e66}', '\\u{1e66}', SC_Upper), ('\\u{1e67}',\n        '\\u{1e67}', SC_Lower), ('\\u{1e68}', '\\u{1e68}', SC_Upper), ('\\u{1e69}', '\\u{1e69}',\n        SC_Lower), ('\\u{1e6a}', '\\u{1e6a}', SC_Upper), ('\\u{1e6b}', '\\u{1e6b}', SC_Lower),\n        ('\\u{1e6c}', '\\u{1e6c}', SC_Upper), ('\\u{1e6d}', '\\u{1e6d}', SC_Lower), ('\\u{1e6e}',\n        '\\u{1e6e}', SC_Upper), ('\\u{1e6f}', '\\u{1e6f}', SC_Lower), ('\\u{1e70}', '\\u{1e70}',\n        SC_Upper), ('\\u{1e71}', '\\u{1e71}', SC_Lower), ('\\u{1e72}', '\\u{1e72}', SC_Upper),\n        ('\\u{1e73}', '\\u{1e73}', SC_Lower), ('\\u{1e74}', '\\u{1e74}', SC_Upper), ('\\u{1e75}',\n        '\\u{1e75}', SC_Lower), ('\\u{1e76}', '\\u{1e76}', SC_Upper), ('\\u{1e77}', '\\u{1e77}',\n        SC_Lower), ('\\u{1e78}', '\\u{1e78}', SC_Upper), ('\\u{1e79}', '\\u{1e79}', SC_Lower),\n        ('\\u{1e7a}', '\\u{1e7a}', SC_Upper), ('\\u{1e7b}', '\\u{1e7b}', SC_Lower), ('\\u{1e7c}',\n        '\\u{1e7c}', SC_Upper), ('\\u{1e7d}', '\\u{1e7d}', SC_Lower), ('\\u{1e7e}', '\\u{1e7e}',\n        SC_Upper), ('\\u{1e7f}', '\\u{1e7f}', SC_Lower), ('\\u{1e80}', '\\u{1e80}', SC_Upper),\n        ('\\u{1e81}', '\\u{1e81}', SC_Lower), ('\\u{1e82}', '\\u{1e82}', SC_Upper), ('\\u{1e83}',\n        '\\u{1e83}', SC_Lower), ('\\u{1e84}', '\\u{1e84}', SC_Upper), ('\\u{1e85}', '\\u{1e85}',\n        SC_Lower), ('\\u{1e86}', '\\u{1e86}', SC_Upper), ('\\u{1e87}', '\\u{1e87}', SC_Lower),\n        ('\\u{1e88}', '\\u{1e88}', SC_Upper), ('\\u{1e89}', '\\u{1e89}', SC_Lower), ('\\u{1e8a}',\n        '\\u{1e8a}', SC_Upper), ('\\u{1e8b}', '\\u{1e8b}', SC_Lower), ('\\u{1e8c}', '\\u{1e8c}',\n        SC_Upper), ('\\u{1e8d}', '\\u{1e8d}', SC_Lower), ('\\u{1e8e}', '\\u{1e8e}', SC_Upper),\n        ('\\u{1e8f}', '\\u{1e8f}', SC_Lower), ('\\u{1e90}', '\\u{1e90}', SC_Upper), ('\\u{1e91}',\n        '\\u{1e91}', SC_Lower), ('\\u{1e92}', '\\u{1e92}', SC_Upper), ('\\u{1e93}', '\\u{1e93}',\n        SC_Lower), ('\\u{1e94}', '\\u{1e94}', SC_Upper), ('\\u{1e95}', '\\u{1e9d}', SC_Lower),\n        ('\\u{1e9e}', '\\u{1e9e}', SC_Upper), ('\\u{1e9f}', '\\u{1e9f}', SC_Lower), ('\\u{1ea0}',\n        '\\u{1ea0}', SC_Upper), ('\\u{1ea1}', '\\u{1ea1}', SC_Lower), ('\\u{1ea2}', '\\u{1ea2}',\n        SC_Upper), ('\\u{1ea3}', '\\u{1ea3}', SC_Lower), ('\\u{1ea4}', '\\u{1ea4}', SC_Upper),\n        ('\\u{1ea5}', '\\u{1ea5}', SC_Lower), ('\\u{1ea6}', '\\u{1ea6}', SC_Upper), ('\\u{1ea7}',\n        '\\u{1ea7}', SC_Lower), ('\\u{1ea8}', '\\u{1ea8}', SC_Upper), ('\\u{1ea9}', '\\u{1ea9}',\n        SC_Lower), ('\\u{1eaa}', '\\u{1eaa}', SC_Upper), ('\\u{1eab}', '\\u{1eab}', SC_Lower),\n        ('\\u{1eac}', '\\u{1eac}', SC_Upper), ('\\u{1ead}', '\\u{1ead}', SC_Lower), ('\\u{1eae}',\n        '\\u{1eae}', SC_Upper), ('\\u{1eaf}', '\\u{1eaf}', SC_Lower), ('\\u{1eb0}', '\\u{1eb0}',\n        SC_Upper), ('\\u{1eb1}', '\\u{1eb1}', SC_Lower), ('\\u{1eb2}', '\\u{1eb2}', SC_Upper),\n        ('\\u{1eb3}', '\\u{1eb3}', SC_Lower), ('\\u{1eb4}', '\\u{1eb4}', SC_Upper), ('\\u{1eb5}',\n        '\\u{1eb5}', SC_Lower), ('\\u{1eb6}', '\\u{1eb6}', SC_Upper), ('\\u{1eb7}', '\\u{1eb7}',\n        SC_Lower), ('\\u{1eb8}', '\\u{1eb8}', SC_Upper), ('\\u{1eb9}', '\\u{1eb9}', SC_Lower),\n        ('\\u{1eba}', '\\u{1eba}', SC_Upper), ('\\u{1ebb}', '\\u{1ebb}', SC_Lower), ('\\u{1ebc}',\n        '\\u{1ebc}', SC_Upper), ('\\u{1ebd}', '\\u{1ebd}', SC_Lower), ('\\u{1ebe}', '\\u{1ebe}',\n        SC_Upper), ('\\u{1ebf}', '\\u{1ebf}', SC_Lower), ('\\u{1ec0}', '\\u{1ec0}', SC_Upper),\n        ('\\u{1ec1}', '\\u{1ec1}', SC_Lower), ('\\u{1ec2}', '\\u{1ec2}', SC_Upper), ('\\u{1ec3}',\n        '\\u{1ec3}', SC_Lower), ('\\u{1ec4}', '\\u{1ec4}', SC_Upper), ('\\u{1ec5}', '\\u{1ec5}',\n        SC_Lower), ('\\u{1ec6}', '\\u{1ec6}', SC_Upper), ('\\u{1ec7}', '\\u{1ec7}', SC_Lower),\n        ('\\u{1ec8}', '\\u{1ec8}', SC_Upper), ('\\u{1ec9}', '\\u{1ec9}', SC_Lower), ('\\u{1eca}',\n        '\\u{1eca}', SC_Upper), ('\\u{1ecb}', '\\u{1ecb}', SC_Lower), ('\\u{1ecc}', '\\u{1ecc}',\n        SC_Upper), ('\\u{1ecd}', '\\u{1ecd}', SC_Lower), ('\\u{1ece}', '\\u{1ece}', SC_Upper),\n        ('\\u{1ecf}', '\\u{1ecf}', SC_Lower), ('\\u{1ed0}', '\\u{1ed0}', SC_Upper), ('\\u{1ed1}',\n        '\\u{1ed1}', SC_Lower), ('\\u{1ed2}', '\\u{1ed2}', SC_Upper), ('\\u{1ed3}', '\\u{1ed3}',\n        SC_Lower), ('\\u{1ed4}', '\\u{1ed4}', SC_Upper), ('\\u{1ed5}', '\\u{1ed5}', SC_Lower),\n        ('\\u{1ed6}', '\\u{1ed6}', SC_Upper), ('\\u{1ed7}', '\\u{1ed7}', SC_Lower), ('\\u{1ed8}',\n        '\\u{1ed8}', SC_Upper), ('\\u{1ed9}', '\\u{1ed9}', SC_Lower), ('\\u{1eda}', '\\u{1eda}',\n        SC_Upper), ('\\u{1edb}', '\\u{1edb}', SC_Lower), ('\\u{1edc}', '\\u{1edc}', SC_Upper),\n        ('\\u{1edd}', '\\u{1edd}', SC_Lower), ('\\u{1ede}', '\\u{1ede}', SC_Upper), ('\\u{1edf}',\n        '\\u{1edf}', SC_Lower), ('\\u{1ee0}', '\\u{1ee0}', SC_Upper), ('\\u{1ee1}', '\\u{1ee1}',\n        SC_Lower), ('\\u{1ee2}', '\\u{1ee2}', SC_Upper), ('\\u{1ee3}', '\\u{1ee3}', SC_Lower),\n        ('\\u{1ee4}', '\\u{1ee4}', SC_Upper), ('\\u{1ee5}', '\\u{1ee5}', SC_Lower), ('\\u{1ee6}',\n        '\\u{1ee6}', SC_Upper), ('\\u{1ee7}', '\\u{1ee7}', SC_Lower), ('\\u{1ee8}', '\\u{1ee8}',\n        SC_Upper), ('\\u{1ee9}', '\\u{1ee9}', SC_Lower), ('\\u{1eea}', '\\u{1eea}', SC_Upper),\n        ('\\u{1eeb}', '\\u{1eeb}', SC_Lower), ('\\u{1eec}', '\\u{1eec}', SC_Upper), ('\\u{1eed}',\n        '\\u{1eed}', SC_Lower), ('\\u{1eee}', '\\u{1eee}', SC_Upper), ('\\u{1eef}', '\\u{1eef}',\n        SC_Lower), ('\\u{1ef0}', '\\u{1ef0}', SC_Upper), ('\\u{1ef1}', '\\u{1ef1}', SC_Lower),\n        ('\\u{1ef2}', '\\u{1ef2}', SC_Upper), ('\\u{1ef3}', '\\u{1ef3}', SC_Lower), ('\\u{1ef4}',\n        '\\u{1ef4}', SC_Upper), ('\\u{1ef5}', '\\u{1ef5}', SC_Lower), ('\\u{1ef6}', '\\u{1ef6}',\n        SC_Upper), ('\\u{1ef7}', '\\u{1ef7}', SC_Lower), ('\\u{1ef8}', '\\u{1ef8}', SC_Upper),\n        ('\\u{1ef9}', '\\u{1ef9}', SC_Lower), ('\\u{1efa}', '\\u{1efa}', SC_Upper), ('\\u{1efb}',\n        '\\u{1efb}', SC_Lower), ('\\u{1efc}', '\\u{1efc}', SC_Upper), ('\\u{1efd}', '\\u{1efd}',\n        SC_Lower), ('\\u{1efe}', '\\u{1efe}', SC_Upper), ('\\u{1eff}', '\\u{1f07}', SC_Lower),\n        ('\\u{1f08}', '\\u{1f0f}', SC_Upper), ('\\u{1f10}', '\\u{1f15}', SC_Lower), ('\\u{1f18}',\n        '\\u{1f1d}', SC_Upper), ('\\u{1f20}', '\\u{1f27}', SC_Lower), ('\\u{1f28}', '\\u{1f2f}',\n        SC_Upper), ('\\u{1f30}', '\\u{1f37}', SC_Lower), ('\\u{1f38}', '\\u{1f3f}', SC_Upper),\n        ('\\u{1f40}', '\\u{1f45}', SC_Lower), ('\\u{1f48}', '\\u{1f4d}', SC_Upper), ('\\u{1f50}',\n        '\\u{1f57}', SC_Lower), ('\\u{1f59}', '\\u{1f59}', SC_Upper), ('\\u{1f5b}', '\\u{1f5b}',\n        SC_Upper), ('\\u{1f5d}', '\\u{1f5d}', SC_Upper), ('\\u{1f5f}', '\\u{1f5f}', SC_Upper),\n        ('\\u{1f60}', '\\u{1f67}', SC_Lower), ('\\u{1f68}', '\\u{1f6f}', SC_Upper), ('\\u{1f70}',\n        '\\u{1f7d}', SC_Lower), ('\\u{1f80}', '\\u{1f87}', SC_Lower), ('\\u{1f88}', '\\u{1f8f}',\n        SC_Upper), ('\\u{1f90}', '\\u{1f97}', SC_Lower), ('\\u{1f98}', '\\u{1f9f}', SC_Upper),\n        ('\\u{1fa0}', '\\u{1fa7}', SC_Lower), ('\\u{1fa8}', '\\u{1faf}', SC_Upper), ('\\u{1fb0}',\n        '\\u{1fb4}', SC_Lower), ('\\u{1fb6}', '\\u{1fb7}', SC_Lower), ('\\u{1fb8}', '\\u{1fbc}',\n        SC_Upper), ('\\u{1fbe}', '\\u{1fbe}', SC_Lower), ('\\u{1fc2}', '\\u{1fc4}', SC_Lower),\n        ('\\u{1fc6}', '\\u{1fc7}', SC_Lower), ('\\u{1fc8}', '\\u{1fcc}', SC_Upper), ('\\u{1fd0}',\n        '\\u{1fd3}', SC_Lower), ('\\u{1fd6}', '\\u{1fd7}', SC_Lower), ('\\u{1fd8}', '\\u{1fdb}',\n        SC_Upper), ('\\u{1fe0}', '\\u{1fe7}', SC_Lower), ('\\u{1fe8}', '\\u{1fec}', SC_Upper),\n        ('\\u{1ff2}', '\\u{1ff4}', SC_Lower), ('\\u{1ff6}', '\\u{1ff7}', SC_Lower), ('\\u{1ff8}',\n        '\\u{1ffc}', SC_Upper), ('\\u{2000}', '\\u{200a}', SC_Sp), ('\\u{200b}', '\\u{200b}', SC_Format),\n        ('\\u{200c}', '\\u{200d}', SC_Extend), ('\\u{200e}', '\\u{200f}', SC_Format), ('\\u{2013}',\n        '\\u{2014}', SC_SContinue), ('\\u{2018}', '\\u{201f}', SC_Close), ('\\u{2024}', '\\u{2024}',\n        SC_ATerm), ('\\u{2028}', '\\u{2029}', SC_Sep), ('\\u{202a}', '\\u{202e}', SC_Format),\n        ('\\u{202f}', '\\u{202f}', SC_Sp), ('\\u{2039}', '\\u{203a}', SC_Close), ('\\u{203c}',\n        '\\u{203d}', SC_STerm), ('\\u{2045}', '\\u{2046}', SC_Close), ('\\u{2047}', '\\u{2049}',\n        SC_STerm), ('\\u{205f}', '\\u{205f}', SC_Sp), ('\\u{2060}', '\\u{2064}', SC_Format),\n        ('\\u{2066}', '\\u{206f}', SC_Format), ('\\u{2071}', '\\u{2071}', SC_Lower), ('\\u{207d}',\n        '\\u{207e}', SC_Close), ('\\u{207f}', '\\u{207f}', SC_Lower), ('\\u{208d}', '\\u{208e}',\n        SC_Close), ('\\u{2090}', '\\u{209c}', SC_Lower), ('\\u{20d0}', '\\u{20f0}', SC_Extend),\n        ('\\u{2102}', '\\u{2102}', SC_Upper), ('\\u{2107}', '\\u{2107}', SC_Upper), ('\\u{210a}',\n        '\\u{210a}', SC_Lower), ('\\u{210b}', '\\u{210d}', SC_Upper), ('\\u{210e}', '\\u{210f}',\n        SC_Lower), ('\\u{2110}', '\\u{2112}', SC_Upper), ('\\u{2113}', '\\u{2113}', SC_Lower),\n        ('\\u{2115}', '\\u{2115}', SC_Upper), ('\\u{2119}', '\\u{211d}', SC_Upper), ('\\u{2124}',\n        '\\u{2124}', SC_Upper), ('\\u{2126}', '\\u{2126}', SC_Upper), ('\\u{2128}', '\\u{2128}',\n        SC_Upper), ('\\u{212a}', '\\u{212d}', SC_Upper), ('\\u{212f}', '\\u{212f}', SC_Lower),\n        ('\\u{2130}', '\\u{2133}', SC_Upper), ('\\u{2134}', '\\u{2134}', SC_Lower), ('\\u{2135}',\n        '\\u{2138}', SC_OLetter), ('\\u{2139}', '\\u{2139}', SC_Lower), ('\\u{213c}', '\\u{213d}',\n        SC_Lower), ('\\u{213e}', '\\u{213f}', SC_Upper), ('\\u{2145}', '\\u{2145}', SC_Upper),\n        ('\\u{2146}', '\\u{2149}', SC_Lower), ('\\u{214e}', '\\u{214e}', SC_Lower), ('\\u{2160}',\n        '\\u{216f}', SC_Upper), ('\\u{2170}', '\\u{217f}', SC_Lower), ('\\u{2180}', '\\u{2182}',\n        SC_OLetter), ('\\u{2183}', '\\u{2183}', SC_Upper), ('\\u{2184}', '\\u{2184}', SC_Lower),\n        ('\\u{2185}', '\\u{2188}', SC_OLetter), ('\\u{2308}', '\\u{230b}', SC_Close), ('\\u{2329}',\n        '\\u{232a}', SC_Close), ('\\u{24b6}', '\\u{24cf}', SC_Upper), ('\\u{24d0}', '\\u{24e9}',\n        SC_Lower), ('\\u{275b}', '\\u{2760}', SC_Close), ('\\u{2768}', '\\u{2775}', SC_Close),\n        ('\\u{27c5}', '\\u{27c6}', SC_Close), ('\\u{27e6}', '\\u{27ef}', SC_Close), ('\\u{2983}',\n        '\\u{2998}', SC_Close), ('\\u{29d8}', '\\u{29db}', SC_Close), ('\\u{29fc}', '\\u{29fd}',\n        SC_Close), ('\\u{2c00}', '\\u{2c2f}', SC_Upper), ('\\u{2c30}', '\\u{2c5f}', SC_Lower),\n        ('\\u{2c60}', '\\u{2c60}', SC_Upper), ('\\u{2c61}', '\\u{2c61}', SC_Lower), ('\\u{2c62}',\n        '\\u{2c64}', SC_Upper), ('\\u{2c65}', '\\u{2c66}', SC_Lower), ('\\u{2c67}', '\\u{2c67}',\n        SC_Upper), ('\\u{2c68}', '\\u{2c68}', SC_Lower), ('\\u{2c69}', '\\u{2c69}', SC_Upper),\n        ('\\u{2c6a}', '\\u{2c6a}', SC_Lower), ('\\u{2c6b}', '\\u{2c6b}', SC_Upper), ('\\u{2c6c}',\n        '\\u{2c6c}', SC_Lower), ('\\u{2c6d}', '\\u{2c70}', SC_Upper), ('\\u{2c71}', '\\u{2c71}',\n        SC_Lower), ('\\u{2c72}', '\\u{2c72}', SC_Upper), ('\\u{2c73}', '\\u{2c74}', SC_Lower),\n        ('\\u{2c75}', '\\u{2c75}', SC_Upper), ('\\u{2c76}', '\\u{2c7d}', SC_Lower), ('\\u{2c7e}',\n        '\\u{2c80}', SC_Upper), ('\\u{2c81}', '\\u{2c81}', SC_Lower), ('\\u{2c82}', '\\u{2c82}',\n        SC_Upper), ('\\u{2c83}', '\\u{2c83}', SC_Lower), ('\\u{2c84}', '\\u{2c84}', SC_Upper),\n        ('\\u{2c85}', '\\u{2c85}', SC_Lower), ('\\u{2c86}', '\\u{2c86}', SC_Upper), ('\\u{2c87}',\n        '\\u{2c87}', SC_Lower), ('\\u{2c88}', '\\u{2c88}', SC_Upper), ('\\u{2c89}', '\\u{2c89}',\n        SC_Lower), ('\\u{2c8a}', '\\u{2c8a}', SC_Upper), ('\\u{2c8b}', '\\u{2c8b}', SC_Lower),\n        ('\\u{2c8c}', '\\u{2c8c}', SC_Upper), ('\\u{2c8d}', '\\u{2c8d}', SC_Lower), ('\\u{2c8e}',\n        '\\u{2c8e}', SC_Upper), ('\\u{2c8f}', '\\u{2c8f}', SC_Lower), ('\\u{2c90}', '\\u{2c90}',\n        SC_Upper), ('\\u{2c91}', '\\u{2c91}', SC_Lower), ('\\u{2c92}', '\\u{2c92}', SC_Upper),\n        ('\\u{2c93}', '\\u{2c93}', SC_Lower), ('\\u{2c94}', '\\u{2c94}', SC_Upper), ('\\u{2c95}',\n        '\\u{2c95}', SC_Lower), ('\\u{2c96}', '\\u{2c96}', SC_Upper), ('\\u{2c97}', '\\u{2c97}',\n        SC_Lower), ('\\u{2c98}', '\\u{2c98}', SC_Upper), ('\\u{2c99}', '\\u{2c99}', SC_Lower),\n        ('\\u{2c9a}', '\\u{2c9a}', SC_Upper), ('\\u{2c9b}', '\\u{2c9b}', SC_Lower), ('\\u{2c9c}',\n        '\\u{2c9c}', SC_Upper), ('\\u{2c9d}', '\\u{2c9d}', SC_Lower), ('\\u{2c9e}', '\\u{2c9e}',\n        SC_Upper), ('\\u{2c9f}', '\\u{2c9f}', SC_Lower), ('\\u{2ca0}', '\\u{2ca0}', SC_Upper),\n        ('\\u{2ca1}', '\\u{2ca1}', SC_Lower), ('\\u{2ca2}', '\\u{2ca2}', SC_Upper), ('\\u{2ca3}',\n        '\\u{2ca3}', SC_Lower), ('\\u{2ca4}', '\\u{2ca4}', SC_Upper), ('\\u{2ca5}', '\\u{2ca5}',\n        SC_Lower), ('\\u{2ca6}', '\\u{2ca6}', SC_Upper), ('\\u{2ca7}', '\\u{2ca7}', SC_Lower),\n        ('\\u{2ca8}', '\\u{2ca8}', SC_Upper), ('\\u{2ca9}', '\\u{2ca9}', SC_Lower), ('\\u{2caa}',\n        '\\u{2caa}', SC_Upper), ('\\u{2cab}', '\\u{2cab}', SC_Lower), ('\\u{2cac}', '\\u{2cac}',\n        SC_Upper), ('\\u{2cad}', '\\u{2cad}', SC_Lower), ('\\u{2cae}', '\\u{2cae}', SC_Upper),\n        ('\\u{2caf}', '\\u{2caf}', SC_Lower), ('\\u{2cb0}', '\\u{2cb0}', SC_Upper), ('\\u{2cb1}',\n        '\\u{2cb1}', SC_Lower), ('\\u{2cb2}', '\\u{2cb2}', SC_Upper), ('\\u{2cb3}', '\\u{2cb3}',\n        SC_Lower), ('\\u{2cb4}', '\\u{2cb4}', SC_Upper), ('\\u{2cb5}', '\\u{2cb5}', SC_Lower),\n        ('\\u{2cb6}', '\\u{2cb6}', SC_Upper), ('\\u{2cb7}', '\\u{2cb7}', SC_Lower), ('\\u{2cb8}',\n        '\\u{2cb8}', SC_Upper), ('\\u{2cb9}', '\\u{2cb9}', SC_Lower), ('\\u{2cba}', '\\u{2cba}',\n        SC_Upper), ('\\u{2cbb}', '\\u{2cbb}', SC_Lower), ('\\u{2cbc}', '\\u{2cbc}', SC_Upper),\n        ('\\u{2cbd}', '\\u{2cbd}', SC_Lower), ('\\u{2cbe}', '\\u{2cbe}', SC_Upper), ('\\u{2cbf}',\n        '\\u{2cbf}', SC_Lower), ('\\u{2cc0}', '\\u{2cc0}', SC_Upper), ('\\u{2cc1}', '\\u{2cc1}',\n        SC_Lower), ('\\u{2cc2}', '\\u{2cc2}', SC_Upper), ('\\u{2cc3}', '\\u{2cc3}', SC_Lower),\n        ('\\u{2cc4}', '\\u{2cc4}', SC_Upper), ('\\u{2cc5}', '\\u{2cc5}', SC_Lower), ('\\u{2cc6}',\n        '\\u{2cc6}', SC_Upper), ('\\u{2cc7}', '\\u{2cc7}', SC_Lower), ('\\u{2cc8}', '\\u{2cc8}',\n        SC_Upper), ('\\u{2cc9}', '\\u{2cc9}', SC_Lower), ('\\u{2cca}', '\\u{2cca}', SC_Upper),\n        ('\\u{2ccb}', '\\u{2ccb}', SC_Lower), ('\\u{2ccc}', '\\u{2ccc}', SC_Upper), ('\\u{2ccd}',\n        '\\u{2ccd}', SC_Lower), ('\\u{2cce}', '\\u{2cce}', SC_Upper), ('\\u{2ccf}', '\\u{2ccf}',\n        SC_Lower), ('\\u{2cd0}', '\\u{2cd0}', SC_Upper), ('\\u{2cd1}', '\\u{2cd1}', SC_Lower),\n        ('\\u{2cd2}', '\\u{2cd2}', SC_Upper), ('\\u{2cd3}', '\\u{2cd3}', SC_Lower), ('\\u{2cd4}',\n        '\\u{2cd4}', SC_Upper), ('\\u{2cd5}', '\\u{2cd5}', SC_Lower), ('\\u{2cd6}', '\\u{2cd6}',\n        SC_Upper), ('\\u{2cd7}', '\\u{2cd7}', SC_Lower), ('\\u{2cd8}', '\\u{2cd8}', SC_Upper),\n        ('\\u{2cd9}', '\\u{2cd9}', SC_Lower), ('\\u{2cda}', '\\u{2cda}', SC_Upper), ('\\u{2cdb}',\n        '\\u{2cdb}', SC_Lower), ('\\u{2cdc}', '\\u{2cdc}', SC_Upper), ('\\u{2cdd}', '\\u{2cdd}',\n        SC_Lower), ('\\u{2cde}', '\\u{2cde}', SC_Upper), ('\\u{2cdf}', '\\u{2cdf}', SC_Lower),\n        ('\\u{2ce0}', '\\u{2ce0}', SC_Upper), ('\\u{2ce1}', '\\u{2ce1}', SC_Lower), ('\\u{2ce2}',\n        '\\u{2ce2}', SC_Upper), ('\\u{2ce3}', '\\u{2ce4}', SC_Lower), ('\\u{2ceb}', '\\u{2ceb}',\n        SC_Upper), ('\\u{2cec}', '\\u{2cec}', SC_Lower), ('\\u{2ced}', '\\u{2ced}', SC_Upper),\n        ('\\u{2cee}', '\\u{2cee}', SC_Lower), ('\\u{2cef}', '\\u{2cf1}', SC_Extend), ('\\u{2cf2}',\n        '\\u{2cf2}', SC_Upper), ('\\u{2cf3}', '\\u{2cf3}', SC_Lower), ('\\u{2cf9}', '\\u{2cfb}',\n        SC_STerm), ('\\u{2d00}', '\\u{2d25}', SC_Lower), ('\\u{2d27}', '\\u{2d27}', SC_Lower),\n        ('\\u{2d2d}', '\\u{2d2d}', SC_Lower), ('\\u{2d30}', '\\u{2d67}', SC_OLetter), ('\\u{2d6f}',\n        '\\u{2d6f}', SC_OLetter), ('\\u{2d7f}', '\\u{2d7f}', SC_Extend), ('\\u{2d80}', '\\u{2d96}',\n        SC_OLetter), ('\\u{2da0}', '\\u{2da6}', SC_OLetter), ('\\u{2da8}', '\\u{2dae}', SC_OLetter),\n        ('\\u{2db0}', '\\u{2db6}', SC_OLetter), ('\\u{2db8}', '\\u{2dbe}', SC_OLetter), ('\\u{2dc0}',\n        '\\u{2dc6}', SC_OLetter), ('\\u{2dc8}', '\\u{2dce}', SC_OLetter), ('\\u{2dd0}', '\\u{2dd6}',\n        SC_OLetter), ('\\u{2dd8}', '\\u{2dde}', SC_OLetter), ('\\u{2de0}', '\\u{2dff}', SC_Extend),\n        ('\\u{2e00}', '\\u{2e0d}', SC_Close), ('\\u{2e1c}', '\\u{2e1d}', SC_Close), ('\\u{2e20}',\n        '\\u{2e29}', SC_Close), ('\\u{2e2e}', '\\u{2e2e}', SC_STerm), ('\\u{2e2f}', '\\u{2e2f}',\n        SC_OLetter), ('\\u{2e3c}', '\\u{2e3c}', SC_STerm), ('\\u{2e42}', '\\u{2e42}', SC_Close),\n        ('\\u{2e53}', '\\u{2e54}', SC_STerm), ('\\u{2e55}', '\\u{2e5c}', SC_Close), ('\\u{3000}',\n        '\\u{3000}', SC_Sp), ('\\u{3001}', '\\u{3001}', SC_SContinue), ('\\u{3002}', '\\u{3002}',\n        SC_STerm), ('\\u{3005}', '\\u{3007}', SC_OLetter), ('\\u{3008}', '\\u{3011}', SC_Close),\n        ('\\u{3014}', '\\u{301b}', SC_Close), ('\\u{301d}', '\\u{301f}', SC_Close), ('\\u{3021}',\n        '\\u{3029}', SC_OLetter), ('\\u{302a}', '\\u{302f}', SC_Extend), ('\\u{3031}', '\\u{3035}',\n        SC_OLetter), ('\\u{3038}', '\\u{303c}', SC_OLetter), ('\\u{3041}', '\\u{3096}', SC_OLetter),\n        ('\\u{3099}', '\\u{309a}', SC_Extend), ('\\u{309d}', '\\u{309f}', SC_OLetter), ('\\u{30a1}',\n        '\\u{30fa}', SC_OLetter), ('\\u{30fc}', '\\u{30ff}', SC_OLetter), ('\\u{3105}', '\\u{312f}',\n        SC_OLetter), ('\\u{3131}', '\\u{318e}', SC_OLetter), ('\\u{31a0}', '\\u{31bf}', SC_OLetter),\n        ('\\u{31f0}', '\\u{31ff}', SC_OLetter), ('\\u{3400}', '\\u{4dbf}', SC_OLetter), ('\\u{4e00}',\n        '\\u{a48c}', SC_OLetter), ('\\u{a4d0}', '\\u{a4fd}', SC_OLetter), ('\\u{a4ff}', '\\u{a4ff}',\n        SC_STerm), ('\\u{a500}', '\\u{a60c}', SC_OLetter), ('\\u{a60e}', '\\u{a60f}', SC_STerm),\n        ('\\u{a610}', '\\u{a61f}', SC_OLetter), ('\\u{a620}', '\\u{a629}', SC_Numeric), ('\\u{a62a}',\n        '\\u{a62b}', SC_OLetter), ('\\u{a640}', '\\u{a640}', SC_Upper), ('\\u{a641}', '\\u{a641}',\n        SC_Lower), ('\\u{a642}', '\\u{a642}', SC_Upper), ('\\u{a643}', '\\u{a643}', SC_Lower),\n        ('\\u{a644}', '\\u{a644}', SC_Upper), ('\\u{a645}', '\\u{a645}', SC_Lower), ('\\u{a646}',\n        '\\u{a646}', SC_Upper), ('\\u{a647}', '\\u{a647}', SC_Lower), ('\\u{a648}', '\\u{a648}',\n        SC_Upper), ('\\u{a649}', '\\u{a649}', SC_Lower), ('\\u{a64a}', '\\u{a64a}', SC_Upper),\n        ('\\u{a64b}', '\\u{a64b}', SC_Lower), ('\\u{a64c}', '\\u{a64c}', SC_Upper), ('\\u{a64d}',\n        '\\u{a64d}', SC_Lower), ('\\u{a64e}', '\\u{a64e}', SC_Upper), ('\\u{a64f}', '\\u{a64f}',\n        SC_Lower), ('\\u{a650}', '\\u{a650}', SC_Upper), ('\\u{a651}', '\\u{a651}', SC_Lower),\n        ('\\u{a652}', '\\u{a652}', SC_Upper), ('\\u{a653}', '\\u{a653}', SC_Lower), ('\\u{a654}',\n        '\\u{a654}', SC_Upper), ('\\u{a655}', '\\u{a655}', SC_Lower), ('\\u{a656}', '\\u{a656}',\n        SC_Upper), ('\\u{a657}', '\\u{a657}', SC_Lower), ('\\u{a658}', '\\u{a658}', SC_Upper),\n        ('\\u{a659}', '\\u{a659}', SC_Lower), ('\\u{a65a}', '\\u{a65a}', SC_Upper), ('\\u{a65b}',\n        '\\u{a65b}', SC_Lower), ('\\u{a65c}', '\\u{a65c}', SC_Upper), ('\\u{a65d}', '\\u{a65d}',\n        SC_Lower), ('\\u{a65e}', '\\u{a65e}', SC_Upper), ('\\u{a65f}', '\\u{a65f}', SC_Lower),\n        ('\\u{a660}', '\\u{a660}', SC_Upper), ('\\u{a661}', '\\u{a661}', SC_Lower), ('\\u{a662}',\n        '\\u{a662}', SC_Upper), ('\\u{a663}', '\\u{a663}', SC_Lower), ('\\u{a664}', '\\u{a664}',\n        SC_Upper), ('\\u{a665}', '\\u{a665}', SC_Lower), ('\\u{a666}', '\\u{a666}', SC_Upper),\n        ('\\u{a667}', '\\u{a667}', SC_Lower), ('\\u{a668}', '\\u{a668}', SC_Upper), ('\\u{a669}',\n        '\\u{a669}', SC_Lower), ('\\u{a66a}', '\\u{a66a}', SC_Upper), ('\\u{a66b}', '\\u{a66b}',\n        SC_Lower), ('\\u{a66c}', '\\u{a66c}', SC_Upper), ('\\u{a66d}', '\\u{a66d}', SC_Lower),\n        ('\\u{a66e}', '\\u{a66e}', SC_OLetter), ('\\u{a66f}', '\\u{a672}', SC_Extend), ('\\u{a674}',\n        '\\u{a67d}', SC_Extend), ('\\u{a67f}', '\\u{a67f}', SC_OLetter), ('\\u{a680}', '\\u{a680}',\n        SC_Upper), ('\\u{a681}', '\\u{a681}', SC_Lower), ('\\u{a682}', '\\u{a682}', SC_Upper),\n        ('\\u{a683}', '\\u{a683}', SC_Lower), ('\\u{a684}', '\\u{a684}', SC_Upper), ('\\u{a685}',\n        '\\u{a685}', SC_Lower), ('\\u{a686}', '\\u{a686}', SC_Upper), ('\\u{a687}', '\\u{a687}',\n        SC_Lower), ('\\u{a688}', '\\u{a688}', SC_Upper), ('\\u{a689}', '\\u{a689}', SC_Lower),\n        ('\\u{a68a}', '\\u{a68a}', SC_Upper), ('\\u{a68b}', '\\u{a68b}', SC_Lower), ('\\u{a68c}',\n        '\\u{a68c}', SC_Upper), ('\\u{a68d}', '\\u{a68d}', SC_Lower), ('\\u{a68e}', '\\u{a68e}',\n        SC_Upper), ('\\u{a68f}', '\\u{a68f}', SC_Lower), ('\\u{a690}', '\\u{a690}', SC_Upper),\n        ('\\u{a691}', '\\u{a691}', SC_Lower), ('\\u{a692}', '\\u{a692}', SC_Upper), ('\\u{a693}',\n        '\\u{a693}', SC_Lower), ('\\u{a694}', '\\u{a694}', SC_Upper), ('\\u{a695}', '\\u{a695}',\n        SC_Lower), ('\\u{a696}', '\\u{a696}', SC_Upper), ('\\u{a697}', '\\u{a697}', SC_Lower),\n        ('\\u{a698}', '\\u{a698}', SC_Upper), ('\\u{a699}', '\\u{a699}', SC_Lower), ('\\u{a69a}',\n        '\\u{a69a}', SC_Upper), ('\\u{a69b}', '\\u{a69d}', SC_Lower), ('\\u{a69e}', '\\u{a69f}',\n        SC_Extend), ('\\u{a6a0}', '\\u{a6ef}', SC_OLetter), ('\\u{a6f0}', '\\u{a6f1}', SC_Extend),\n        ('\\u{a6f3}', '\\u{a6f3}', SC_STerm), ('\\u{a6f7}', '\\u{a6f7}', SC_STerm), ('\\u{a717}',\n        '\\u{a71f}', SC_OLetter), ('\\u{a722}', '\\u{a722}', SC_Upper), ('\\u{a723}', '\\u{a723}',\n        SC_Lower), ('\\u{a724}', '\\u{a724}', SC_Upper), ('\\u{a725}', '\\u{a725}', SC_Lower),\n        ('\\u{a726}', '\\u{a726}', SC_Upper), ('\\u{a727}', '\\u{a727}', SC_Lower), ('\\u{a728}',\n        '\\u{a728}', SC_Upper), ('\\u{a729}', '\\u{a729}', SC_Lower), ('\\u{a72a}', '\\u{a72a}',\n        SC_Upper), ('\\u{a72b}', '\\u{a72b}', SC_Lower), ('\\u{a72c}', '\\u{a72c}', SC_Upper),\n        ('\\u{a72d}', '\\u{a72d}', SC_Lower), ('\\u{a72e}', '\\u{a72e}', SC_Upper), ('\\u{a72f}',\n        '\\u{a731}', SC_Lower), ('\\u{a732}', '\\u{a732}', SC_Upper), ('\\u{a733}', '\\u{a733}',\n        SC_Lower), ('\\u{a734}', '\\u{a734}', SC_Upper), ('\\u{a735}', '\\u{a735}', SC_Lower),\n        ('\\u{a736}', '\\u{a736}', SC_Upper), ('\\u{a737}', '\\u{a737}', SC_Lower), ('\\u{a738}',\n        '\\u{a738}', SC_Upper), ('\\u{a739}', '\\u{a739}', SC_Lower), ('\\u{a73a}', '\\u{a73a}',\n        SC_Upper), ('\\u{a73b}', '\\u{a73b}', SC_Lower), ('\\u{a73c}', '\\u{a73c}', SC_Upper),\n        ('\\u{a73d}', '\\u{a73d}', SC_Lower), ('\\u{a73e}', '\\u{a73e}', SC_Upper), ('\\u{a73f}',\n        '\\u{a73f}', SC_Lower), ('\\u{a740}', '\\u{a740}', SC_Upper), ('\\u{a741}', '\\u{a741}',\n        SC_Lower), ('\\u{a742}', '\\u{a742}', SC_Upper), ('\\u{a743}', '\\u{a743}', SC_Lower),\n        ('\\u{a744}', '\\u{a744}', SC_Upper), ('\\u{a745}', '\\u{a745}', SC_Lower), ('\\u{a746}',\n        '\\u{a746}', SC_Upper), ('\\u{a747}', '\\u{a747}', SC_Lower), ('\\u{a748}', '\\u{a748}',\n        SC_Upper), ('\\u{a749}', '\\u{a749}', SC_Lower), ('\\u{a74a}', '\\u{a74a}', SC_Upper),\n        ('\\u{a74b}', '\\u{a74b}', SC_Lower), ('\\u{a74c}', '\\u{a74c}', SC_Upper), ('\\u{a74d}',\n        '\\u{a74d}', SC_Lower), ('\\u{a74e}', '\\u{a74e}', SC_Upper), ('\\u{a74f}', '\\u{a74f}',\n        SC_Lower), ('\\u{a750}', '\\u{a750}', SC_Upper), ('\\u{a751}', '\\u{a751}', SC_Lower),\n        ('\\u{a752}', '\\u{a752}', SC_Upper), ('\\u{a753}', '\\u{a753}', SC_Lower), ('\\u{a754}',\n        '\\u{a754}', SC_Upper), ('\\u{a755}', '\\u{a755}', SC_Lower), ('\\u{a756}', '\\u{a756}',\n        SC_Upper), ('\\u{a757}', '\\u{a757}', SC_Lower), ('\\u{a758}', '\\u{a758}', SC_Upper),\n        ('\\u{a759}', '\\u{a759}', SC_Lower), ('\\u{a75a}', '\\u{a75a}', SC_Upper), ('\\u{a75b}',\n        '\\u{a75b}', SC_Lower), ('\\u{a75c}', '\\u{a75c}', SC_Upper), ('\\u{a75d}', '\\u{a75d}',\n        SC_Lower), ('\\u{a75e}', '\\u{a75e}', SC_Upper), ('\\u{a75f}', '\\u{a75f}', SC_Lower),\n        ('\\u{a760}', '\\u{a760}', SC_Upper), ('\\u{a761}', '\\u{a761}', SC_Lower), ('\\u{a762}',\n        '\\u{a762}', SC_Upper), ('\\u{a763}', '\\u{a763}', SC_Lower), ('\\u{a764}', '\\u{a764}',\n        SC_Upper), ('\\u{a765}', '\\u{a765}', SC_Lower), ('\\u{a766}', '\\u{a766}', SC_Upper),\n        ('\\u{a767}', '\\u{a767}', SC_Lower), ('\\u{a768}', '\\u{a768}', SC_Upper), ('\\u{a769}',\n        '\\u{a769}', SC_Lower), ('\\u{a76a}', '\\u{a76a}', SC_Upper), ('\\u{a76b}', '\\u{a76b}',\n        SC_Lower), ('\\u{a76c}', '\\u{a76c}', SC_Upper), ('\\u{a76d}', '\\u{a76d}', SC_Lower),\n        ('\\u{a76e}', '\\u{a76e}', SC_Upper), ('\\u{a76f}', '\\u{a778}', SC_Lower), ('\\u{a779}',\n        '\\u{a779}', SC_Upper), ('\\u{a77a}', '\\u{a77a}', SC_Lower), ('\\u{a77b}', '\\u{a77b}',\n        SC_Upper), ('\\u{a77c}', '\\u{a77c}', SC_Lower), ('\\u{a77d}', '\\u{a77e}', SC_Upper),\n        ('\\u{a77f}', '\\u{a77f}', SC_Lower), ('\\u{a780}', '\\u{a780}', SC_Upper), ('\\u{a781}',\n        '\\u{a781}', SC_Lower), ('\\u{a782}', '\\u{a782}', SC_Upper), ('\\u{a783}', '\\u{a783}',\n        SC_Lower), ('\\u{a784}', '\\u{a784}', SC_Upper), ('\\u{a785}', '\\u{a785}', SC_Lower),\n        ('\\u{a786}', '\\u{a786}', SC_Upper), ('\\u{a787}', '\\u{a787}', SC_Lower), ('\\u{a788}',\n        '\\u{a788}', SC_OLetter), ('\\u{a78b}', '\\u{a78b}', SC_Upper), ('\\u{a78c}', '\\u{a78c}',\n        SC_Lower), ('\\u{a78d}', '\\u{a78d}', SC_Upper), ('\\u{a78e}', '\\u{a78e}', SC_Lower),\n        ('\\u{a78f}', '\\u{a78f}', SC_OLetter), ('\\u{a790}', '\\u{a790}', SC_Upper), ('\\u{a791}',\n        '\\u{a791}', SC_Lower), ('\\u{a792}', '\\u{a792}', SC_Upper), ('\\u{a793}', '\\u{a795}',\n        SC_Lower), ('\\u{a796}', '\\u{a796}', SC_Upper), ('\\u{a797}', '\\u{a797}', SC_Lower),\n        ('\\u{a798}', '\\u{a798}', SC_Upper), ('\\u{a799}', '\\u{a799}', SC_Lower), ('\\u{a79a}',\n        '\\u{a79a}', SC_Upper), ('\\u{a79b}', '\\u{a79b}', SC_Lower), ('\\u{a79c}', '\\u{a79c}',\n        SC_Upper), ('\\u{a79d}', '\\u{a79d}', SC_Lower), ('\\u{a79e}', '\\u{a79e}', SC_Upper),\n        ('\\u{a79f}', '\\u{a79f}', SC_Lower), ('\\u{a7a0}', '\\u{a7a0}', SC_Upper), ('\\u{a7a1}',\n        '\\u{a7a1}', SC_Lower), ('\\u{a7a2}', '\\u{a7a2}', SC_Upper), ('\\u{a7a3}', '\\u{a7a3}',\n        SC_Lower), ('\\u{a7a4}', '\\u{a7a4}', SC_Upper), ('\\u{a7a5}', '\\u{a7a5}', SC_Lower),\n        ('\\u{a7a6}', '\\u{a7a6}', SC_Upper), ('\\u{a7a7}', '\\u{a7a7}', SC_Lower), ('\\u{a7a8}',\n        '\\u{a7a8}', SC_Upper), ('\\u{a7a9}', '\\u{a7a9}', SC_Lower), ('\\u{a7aa}', '\\u{a7ae}',\n        SC_Upper), ('\\u{a7af}', '\\u{a7af}', SC_Lower), ('\\u{a7b0}', '\\u{a7b4}', SC_Upper),\n        ('\\u{a7b5}', '\\u{a7b5}', SC_Lower), ('\\u{a7b6}', '\\u{a7b6}', SC_Upper), ('\\u{a7b7}',\n        '\\u{a7b7}', SC_Lower), ('\\u{a7b8}', '\\u{a7b8}', SC_Upper), ('\\u{a7b9}', '\\u{a7b9}',\n        SC_Lower), ('\\u{a7ba}', '\\u{a7ba}', SC_Upper), ('\\u{a7bb}', '\\u{a7bb}', SC_Lower),\n        ('\\u{a7bc}', '\\u{a7bc}', SC_Upper), ('\\u{a7bd}', '\\u{a7bd}', SC_Lower), ('\\u{a7be}',\n        '\\u{a7be}', SC_Upper), ('\\u{a7bf}', '\\u{a7bf}', SC_Lower), ('\\u{a7c0}', '\\u{a7c0}',\n        SC_Upper), ('\\u{a7c1}', '\\u{a7c1}', SC_Lower), ('\\u{a7c2}', '\\u{a7c2}', SC_Upper),\n        ('\\u{a7c3}', '\\u{a7c3}', SC_Lower), ('\\u{a7c4}', '\\u{a7c7}', SC_Upper), ('\\u{a7c8}',\n        '\\u{a7c8}', SC_Lower), ('\\u{a7c9}', '\\u{a7c9}', SC_Upper), ('\\u{a7ca}', '\\u{a7ca}',\n        SC_Lower), ('\\u{a7cb}', '\\u{a7cc}', SC_Upper), ('\\u{a7cd}', '\\u{a7cd}', SC_Lower),\n        ('\\u{a7ce}', '\\u{a7ce}', SC_Upper), ('\\u{a7cf}', '\\u{a7cf}', SC_Lower), ('\\u{a7d0}',\n        '\\u{a7d0}', SC_Upper), ('\\u{a7d1}', '\\u{a7d1}', SC_Lower), ('\\u{a7d2}', '\\u{a7d2}',\n        SC_Upper), ('\\u{a7d3}', '\\u{a7d3}', SC_Lower), ('\\u{a7d4}', '\\u{a7d4}', SC_Upper),\n        ('\\u{a7d5}', '\\u{a7d5}', SC_Lower), ('\\u{a7d6}', '\\u{a7d6}', SC_Upper), ('\\u{a7d7}',\n        '\\u{a7d7}', SC_Lower), ('\\u{a7d8}', '\\u{a7d8}', SC_Upper), ('\\u{a7d9}', '\\u{a7d9}',\n        SC_Lower), ('\\u{a7da}', '\\u{a7da}', SC_Upper), ('\\u{a7db}', '\\u{a7db}', SC_Lower),\n        ('\\u{a7dc}', '\\u{a7dc}', SC_Upper), ('\\u{a7f1}', '\\u{a7f4}', SC_Lower), ('\\u{a7f5}',\n        '\\u{a7f5}', SC_Upper), ('\\u{a7f6}', '\\u{a7f6}', SC_Lower), ('\\u{a7f7}', '\\u{a7f7}',\n        SC_OLetter), ('\\u{a7f8}', '\\u{a7fa}', SC_Lower), ('\\u{a7fb}', '\\u{a801}', SC_OLetter),\n        ('\\u{a802}', '\\u{a802}', SC_Extend), ('\\u{a803}', '\\u{a805}', SC_OLetter), ('\\u{a806}',\n        '\\u{a806}', SC_Extend), ('\\u{a807}', '\\u{a80a}', SC_OLetter), ('\\u{a80b}', '\\u{a80b}',\n        SC_Extend), ('\\u{a80c}', '\\u{a822}', SC_OLetter), ('\\u{a823}', '\\u{a827}', SC_Extend),\n        ('\\u{a82c}', '\\u{a82c}', SC_Extend), ('\\u{a840}', '\\u{a873}', SC_OLetter), ('\\u{a876}',\n        '\\u{a877}', SC_STerm), ('\\u{a880}', '\\u{a881}', SC_Extend), ('\\u{a882}', '\\u{a8b3}',\n        SC_OLetter), ('\\u{a8b4}', '\\u{a8c5}', SC_Extend), ('\\u{a8ce}', '\\u{a8cf}', SC_STerm),\n        ('\\u{a8d0}', '\\u{a8d9}', SC_Numeric), ('\\u{a8e0}', '\\u{a8f1}', SC_Extend), ('\\u{a8f2}',\n        '\\u{a8f7}', SC_OLetter), ('\\u{a8fb}', '\\u{a8fb}', SC_OLetter), ('\\u{a8fd}', '\\u{a8fe}',\n        SC_OLetter), ('\\u{a8ff}', '\\u{a8ff}', SC_Extend), ('\\u{a900}', '\\u{a909}', SC_Numeric),\n        ('\\u{a90a}', '\\u{a925}', SC_OLetter), ('\\u{a926}', '\\u{a92d}', SC_Extend), ('\\u{a92f}',\n        '\\u{a92f}', SC_STerm), ('\\u{a930}', '\\u{a946}', SC_OLetter), ('\\u{a947}', '\\u{a953}',\n        SC_Extend), ('\\u{a960}', '\\u{a97c}', SC_OLetter), ('\\u{a980}', '\\u{a983}', SC_Extend),\n        ('\\u{a984}', '\\u{a9b2}', SC_OLetter), ('\\u{a9b3}', '\\u{a9c0}', SC_Extend), ('\\u{a9c8}',\n        '\\u{a9c9}', SC_STerm), ('\\u{a9cf}', '\\u{a9cf}', SC_OLetter), ('\\u{a9d0}', '\\u{a9d9}',\n        SC_Numeric), ('\\u{a9e0}', '\\u{a9e4}', SC_OLetter), ('\\u{a9e5}', '\\u{a9e5}', SC_Extend),\n        ('\\u{a9e6}', '\\u{a9ef}', SC_OLetter), ('\\u{a9f0}', '\\u{a9f9}', SC_Numeric), ('\\u{a9fa}',\n        '\\u{a9fe}', SC_OLetter), ('\\u{aa00}', '\\u{aa28}', SC_OLetter), ('\\u{aa29}', '\\u{aa36}',\n        SC_Extend), ('\\u{aa40}', '\\u{aa42}', SC_OLetter), ('\\u{aa43}', '\\u{aa43}', SC_Extend),\n        ('\\u{aa44}', '\\u{aa4b}', SC_OLetter), ('\\u{aa4c}', '\\u{aa4d}', SC_Extend), ('\\u{aa50}',\n        '\\u{aa59}', SC_Numeric), ('\\u{aa5d}', '\\u{aa5f}', SC_STerm), ('\\u{aa60}', '\\u{aa76}',\n        SC_OLetter), ('\\u{aa7a}', '\\u{aa7a}', SC_OLetter), ('\\u{aa7b}', '\\u{aa7d}', SC_Extend),\n        ('\\u{aa7e}', '\\u{aaaf}', SC_OLetter), ('\\u{aab0}', '\\u{aab0}', SC_Extend), ('\\u{aab1}',\n        '\\u{aab1}', SC_OLetter), ('\\u{aab2}', '\\u{aab4}', SC_Extend), ('\\u{aab5}', '\\u{aab6}',\n        SC_OLetter), ('\\u{aab7}', '\\u{aab8}', SC_Extend), ('\\u{aab9}', '\\u{aabd}', SC_OLetter),\n        ('\\u{aabe}', '\\u{aabf}', SC_Extend), ('\\u{aac0}', '\\u{aac0}', SC_OLetter), ('\\u{aac1}',\n        '\\u{aac1}', SC_Extend), ('\\u{aac2}', '\\u{aac2}', SC_OLetter), ('\\u{aadb}', '\\u{aadd}',\n        SC_OLetter), ('\\u{aae0}', '\\u{aaea}', SC_OLetter), ('\\u{aaeb}', '\\u{aaef}', SC_Extend),\n        ('\\u{aaf0}', '\\u{aaf1}', SC_STerm), ('\\u{aaf2}', '\\u{aaf4}', SC_OLetter), ('\\u{aaf5}',\n        '\\u{aaf6}', SC_Extend), ('\\u{ab01}', '\\u{ab06}', SC_OLetter), ('\\u{ab09}', '\\u{ab0e}',\n        SC_OLetter), ('\\u{ab11}', '\\u{ab16}', SC_OLetter), ('\\u{ab20}', '\\u{ab26}', SC_OLetter),\n        ('\\u{ab28}', '\\u{ab2e}', SC_OLetter), ('\\u{ab30}', '\\u{ab5a}', SC_Lower), ('\\u{ab5c}',\n        '\\u{ab69}', SC_Lower), ('\\u{ab70}', '\\u{abbf}', SC_Lower), ('\\u{abc0}', '\\u{abe2}',\n        SC_OLetter), ('\\u{abe3}', '\\u{abea}', SC_Extend), ('\\u{abeb}', '\\u{abeb}', SC_STerm),\n        ('\\u{abec}', '\\u{abed}', SC_Extend), ('\\u{abf0}', '\\u{abf9}', SC_Numeric), ('\\u{ac00}',\n        '\\u{d7a3}', SC_OLetter), ('\\u{d7b0}', '\\u{d7c6}', SC_OLetter), ('\\u{d7cb}', '\\u{d7fb}',\n        SC_OLetter), ('\\u{f900}', '\\u{fa6d}', SC_OLetter), ('\\u{fa70}', '\\u{fad9}', SC_OLetter),\n        ('\\u{fb00}', '\\u{fb06}', SC_Lower), ('\\u{fb13}', '\\u{fb17}', SC_Lower), ('\\u{fb1d}',\n        '\\u{fb1d}', SC_OLetter), ('\\u{fb1e}', '\\u{fb1e}', SC_Extend), ('\\u{fb1f}', '\\u{fb28}',\n        SC_OLetter), ('\\u{fb2a}', '\\u{fb36}', SC_OLetter), ('\\u{fb38}', '\\u{fb3c}', SC_OLetter),\n        ('\\u{fb3e}', '\\u{fb3e}', SC_OLetter), ('\\u{fb40}', '\\u{fb41}', SC_OLetter), ('\\u{fb43}',\n        '\\u{fb44}', SC_OLetter), ('\\u{fb46}', '\\u{fbb1}', SC_OLetter), ('\\u{fbd3}', '\\u{fd3d}',\n        SC_OLetter), ('\\u{fd3e}', '\\u{fd3f}', SC_Close), ('\\u{fd50}', '\\u{fd8f}', SC_OLetter),\n        ('\\u{fd92}', '\\u{fdc7}', SC_OLetter), ('\\u{fdf0}', '\\u{fdfb}', SC_OLetter), ('\\u{fe00}',\n        '\\u{fe0f}', SC_Extend), ('\\u{fe10}', '\\u{fe11}', SC_SContinue), ('\\u{fe12}', '\\u{fe12}',\n        SC_STerm), ('\\u{fe13}', '\\u{fe14}', SC_SContinue), ('\\u{fe15}', '\\u{fe16}', SC_STerm),\n        ('\\u{fe17}', '\\u{fe18}', SC_Close), ('\\u{fe20}', '\\u{fe2f}', SC_Extend), ('\\u{fe31}',\n        '\\u{fe32}', SC_SContinue), ('\\u{fe35}', '\\u{fe44}', SC_Close), ('\\u{fe47}', '\\u{fe48}',\n        SC_Close), ('\\u{fe50}', '\\u{fe51}', SC_SContinue), ('\\u{fe52}', '\\u{fe52}', SC_ATerm),\n        ('\\u{fe54}', '\\u{fe55}', SC_SContinue), ('\\u{fe56}', '\\u{fe57}', SC_STerm), ('\\u{fe58}',\n        '\\u{fe58}', SC_SContinue), ('\\u{fe59}', '\\u{fe5e}', SC_Close), ('\\u{fe63}', '\\u{fe63}',\n        SC_SContinue), ('\\u{fe70}', '\\u{fe74}', SC_OLetter), ('\\u{fe76}', '\\u{fefc}', SC_OLetter),\n        ('\\u{feff}', '\\u{feff}', SC_Format), ('\\u{ff01}', '\\u{ff01}', SC_STerm), ('\\u{ff08}',\n        '\\u{ff09}', SC_Close), ('\\u{ff0c}', '\\u{ff0d}', SC_SContinue), ('\\u{ff0e}', '\\u{ff0e}',\n        SC_ATerm), ('\\u{ff10}', '\\u{ff19}', SC_Numeric), ('\\u{ff1a}', '\\u{ff1b}', SC_SContinue),\n        ('\\u{ff1f}', '\\u{ff1f}', SC_STerm), ('\\u{ff21}', '\\u{ff3a}', SC_Upper), ('\\u{ff3b}',\n        '\\u{ff3b}', SC_Close), ('\\u{ff3d}', '\\u{ff3d}', SC_Close), ('\\u{ff41}', '\\u{ff5a}',\n        SC_Lower), ('\\u{ff5b}', '\\u{ff5b}', SC_Close), ('\\u{ff5d}', '\\u{ff5d}', SC_Close),\n        ('\\u{ff5f}', '\\u{ff60}', SC_Close), ('\\u{ff61}', '\\u{ff61}', SC_STerm), ('\\u{ff62}',\n        '\\u{ff63}', SC_Close), ('\\u{ff64}', '\\u{ff64}', SC_SContinue), ('\\u{ff66}', '\\u{ff9d}',\n        SC_OLetter), ('\\u{ff9e}', '\\u{ff9f}', SC_Extend), ('\\u{ffa0}', '\\u{ffbe}', SC_OLetter),\n        ('\\u{ffc2}', '\\u{ffc7}', SC_OLetter), ('\\u{ffca}', '\\u{ffcf}', SC_OLetter), ('\\u{ffd2}',\n        '\\u{ffd7}', SC_OLetter), ('\\u{ffda}', '\\u{ffdc}', SC_OLetter), ('\\u{fff9}', '\\u{fffb}',\n        SC_Format), ('\\u{10000}', '\\u{1000b}', SC_OLetter), ('\\u{1000d}', '\\u{10026}', SC_OLetter),\n        ('\\u{10028}', '\\u{1003a}', SC_OLetter), ('\\u{1003c}', '\\u{1003d}', SC_OLetter),\n        ('\\u{1003f}', '\\u{1004d}', SC_OLetter), ('\\u{10050}', '\\u{1005d}', SC_OLetter),\n        ('\\u{10080}', '\\u{100fa}', SC_OLetter), ('\\u{10140}', '\\u{10174}', SC_OLetter),\n        ('\\u{101fd}', '\\u{101fd}', SC_Extend), ('\\u{10280}', '\\u{1029c}', SC_OLetter), ('\\u{102a0}',\n        '\\u{102d0}', SC_OLetter), ('\\u{102e0}', '\\u{102e0}', SC_Extend), ('\\u{10300}', '\\u{1031f}',\n        SC_OLetter), ('\\u{1032d}', '\\u{1034a}', SC_OLetter), ('\\u{10350}', '\\u{10375}', SC_OLetter),\n        ('\\u{10376}', '\\u{1037a}', SC_Extend), ('\\u{10380}', '\\u{1039d}', SC_OLetter), ('\\u{103a0}',\n        '\\u{103c3}', SC_OLetter), ('\\u{103c8}', '\\u{103cf}', SC_OLetter), ('\\u{103d1}', '\\u{103d5}',\n        SC_OLetter), ('\\u{10400}', '\\u{10427}', SC_Upper), ('\\u{10428}', '\\u{1044f}', SC_Lower),\n        ('\\u{10450}', '\\u{1049d}', SC_OLetter), ('\\u{104a0}', '\\u{104a9}', SC_Numeric),\n        ('\\u{104b0}', '\\u{104d3}', SC_Upper), ('\\u{104d8}', '\\u{104fb}', SC_Lower), ('\\u{10500}',\n        '\\u{10527}', SC_OLetter), ('\\u{10530}', '\\u{10563}', SC_OLetter), ('\\u{10570}', '\\u{1057a}',\n        SC_Upper), ('\\u{1057c}', '\\u{1058a}', SC_Upper), ('\\u{1058c}', '\\u{10592}', SC_Upper),\n        ('\\u{10594}', '\\u{10595}', SC_Upper), ('\\u{10597}', '\\u{105a1}', SC_Lower), ('\\u{105a3}',\n        '\\u{105b1}', SC_Lower), ('\\u{105b3}', '\\u{105b9}', SC_Lower), ('\\u{105bb}', '\\u{105bc}',\n        SC_Lower), ('\\u{105c0}', '\\u{105f3}', SC_OLetter), ('\\u{10600}', '\\u{10736}', SC_OLetter),\n        ('\\u{10740}', '\\u{10755}', SC_OLetter), ('\\u{10760}', '\\u{10767}', SC_OLetter),\n        ('\\u{10780}', '\\u{10780}', SC_Lower), ('\\u{10781}', '\\u{10782}', SC_OLetter), ('\\u{10783}',\n        '\\u{10785}', SC_Lower), ('\\u{10787}', '\\u{107b0}', SC_Lower), ('\\u{107b2}', '\\u{107ba}',\n        SC_Lower), ('\\u{10800}', '\\u{10805}', SC_OLetter), ('\\u{10808}', '\\u{10808}', SC_OLetter),\n        ('\\u{1080a}', '\\u{10835}', SC_OLetter), ('\\u{10837}', '\\u{10838}', SC_OLetter),\n        ('\\u{1083c}', '\\u{1083c}', SC_OLetter), ('\\u{1083f}', '\\u{10855}', SC_OLetter),\n        ('\\u{10860}', '\\u{10876}', SC_OLetter), ('\\u{10880}', '\\u{1089e}', SC_OLetter),\n        ('\\u{108e0}', '\\u{108f2}', SC_OLetter), ('\\u{108f4}', '\\u{108f5}', SC_OLetter),\n        ('\\u{10900}', '\\u{10915}', SC_OLetter), ('\\u{10920}', '\\u{10939}', SC_OLetter),\n        ('\\u{10940}', '\\u{10959}', SC_OLetter), ('\\u{10980}', '\\u{109b7}', SC_OLetter),\n        ('\\u{109be}', '\\u{109bf}', SC_OLetter), ('\\u{10a00}', '\\u{10a00}', SC_OLetter),\n        ('\\u{10a01}', '\\u{10a03}', SC_Extend), ('\\u{10a05}', '\\u{10a06}', SC_Extend), ('\\u{10a0c}',\n        '\\u{10a0f}', SC_Extend), ('\\u{10a10}', '\\u{10a13}', SC_OLetter), ('\\u{10a15}', '\\u{10a17}',\n        SC_OLetter), ('\\u{10a19}', '\\u{10a35}', SC_OLetter), ('\\u{10a38}', '\\u{10a3a}', SC_Extend),\n        ('\\u{10a3f}', '\\u{10a3f}', SC_Extend), ('\\u{10a56}', '\\u{10a57}', SC_STerm), ('\\u{10a60}',\n        '\\u{10a7c}', SC_OLetter), ('\\u{10a80}', '\\u{10a9c}', SC_OLetter), ('\\u{10ac0}', '\\u{10ac7}',\n        SC_OLetter), ('\\u{10ac9}', '\\u{10ae4}', SC_OLetter), ('\\u{10ae5}', '\\u{10ae6}', SC_Extend),\n        ('\\u{10b00}', '\\u{10b35}', SC_OLetter), ('\\u{10b40}', '\\u{10b55}', SC_OLetter),\n        ('\\u{10b60}', '\\u{10b72}', SC_OLetter), ('\\u{10b80}', '\\u{10b91}', SC_OLetter),\n        ('\\u{10c00}', '\\u{10c48}', SC_OLetter), ('\\u{10c80}', '\\u{10cb2}', SC_Upper), ('\\u{10cc0}',\n        '\\u{10cf2}', SC_Lower), ('\\u{10d00}', '\\u{10d23}', SC_OLetter), ('\\u{10d24}', '\\u{10d27}',\n        SC_Extend), ('\\u{10d30}', '\\u{10d39}', SC_Numeric), ('\\u{10d40}', '\\u{10d49}', SC_Numeric),\n        ('\\u{10d4a}', '\\u{10d4f}', SC_OLetter), ('\\u{10d50}', '\\u{10d65}', SC_Upper), ('\\u{10d69}',\n        '\\u{10d6d}', SC_Extend), ('\\u{10d6f}', '\\u{10d6f}', SC_OLetter), ('\\u{10d70}', '\\u{10d85}',\n        SC_Lower), ('\\u{10e80}', '\\u{10ea9}', SC_OLetter), ('\\u{10eab}', '\\u{10eac}', SC_Extend),\n        ('\\u{10eb0}', '\\u{10eb1}', SC_OLetter), ('\\u{10ec2}', '\\u{10ec7}', SC_OLetter),\n        ('\\u{10efa}', '\\u{10eff}', SC_Extend), ('\\u{10f00}', '\\u{10f1c}', SC_OLetter), ('\\u{10f27}',\n        '\\u{10f27}', SC_OLetter), ('\\u{10f30}', '\\u{10f45}', SC_OLetter), ('\\u{10f46}', '\\u{10f50}',\n        SC_Extend), ('\\u{10f55}', '\\u{10f59}', SC_STerm), ('\\u{10f70}', '\\u{10f81}', SC_OLetter),\n        ('\\u{10f82}', '\\u{10f85}', SC_Extend), ('\\u{10f86}', '\\u{10f89}', SC_STerm), ('\\u{10fb0}',\n        '\\u{10fc4}', SC_OLetter), ('\\u{10fe0}', '\\u{10ff6}', SC_OLetter), ('\\u{11000}', '\\u{11002}',\n        SC_Extend), ('\\u{11003}', '\\u{11037}', SC_OLetter), ('\\u{11038}', '\\u{11046}', SC_Extend),\n        ('\\u{11047}', '\\u{11048}', SC_STerm), ('\\u{11066}', '\\u{1106f}', SC_Numeric), ('\\u{11070}',\n        '\\u{11070}', SC_Extend), ('\\u{11071}', '\\u{11072}', SC_OLetter), ('\\u{11073}', '\\u{11074}',\n        SC_Extend), ('\\u{11075}', '\\u{11075}', SC_OLetter), ('\\u{1107f}', '\\u{11082}', SC_Extend),\n        ('\\u{11083}', '\\u{110af}', SC_OLetter), ('\\u{110b0}', '\\u{110ba}', SC_Extend), ('\\u{110bd}',\n        '\\u{110bd}', SC_Numeric), ('\\u{110be}', '\\u{110c1}', SC_STerm), ('\\u{110c2}', '\\u{110c2}',\n        SC_Extend), ('\\u{110cd}', '\\u{110cd}', SC_Numeric), ('\\u{110d0}', '\\u{110e8}', SC_OLetter),\n        ('\\u{110f0}', '\\u{110f9}', SC_Numeric), ('\\u{11100}', '\\u{11102}', SC_Extend), ('\\u{11103}',\n        '\\u{11126}', SC_OLetter), ('\\u{11127}', '\\u{11134}', SC_Extend), ('\\u{11136}', '\\u{1113f}',\n        SC_Numeric), ('\\u{11141}', '\\u{11143}', SC_STerm), ('\\u{11144}', '\\u{11144}', SC_OLetter),\n        ('\\u{11145}', '\\u{11146}', SC_Extend), ('\\u{11147}', '\\u{11147}', SC_OLetter), ('\\u{11150}',\n        '\\u{11172}', SC_OLetter), ('\\u{11173}', '\\u{11173}', SC_Extend), ('\\u{11176}', '\\u{11176}',\n        SC_OLetter), ('\\u{11180}', '\\u{11182}', SC_Extend), ('\\u{11183}', '\\u{111b2}', SC_OLetter),\n        ('\\u{111b3}', '\\u{111c0}', SC_Extend), ('\\u{111c1}', '\\u{111c4}', SC_OLetter), ('\\u{111c5}',\n        '\\u{111c6}', SC_STerm), ('\\u{111c9}', '\\u{111cc}', SC_Extend), ('\\u{111cd}', '\\u{111cd}',\n        SC_STerm), ('\\u{111ce}', '\\u{111cf}', SC_Extend), ('\\u{111d0}', '\\u{111d9}', SC_Numeric),\n        ('\\u{111da}', '\\u{111da}', SC_OLetter), ('\\u{111dc}', '\\u{111dc}', SC_OLetter),\n        ('\\u{111de}', '\\u{111df}', SC_STerm), ('\\u{11200}', '\\u{11211}', SC_OLetter), ('\\u{11213}',\n        '\\u{1122b}', SC_OLetter), ('\\u{1122c}', '\\u{11237}', SC_Extend), ('\\u{11238}', '\\u{11239}',\n        SC_STerm), ('\\u{1123b}', '\\u{1123c}', SC_STerm), ('\\u{1123e}', '\\u{1123e}', SC_Extend),\n        ('\\u{1123f}', '\\u{11240}', SC_OLetter), ('\\u{11241}', '\\u{11241}', SC_Extend), ('\\u{11280}',\n        '\\u{11286}', SC_OLetter), ('\\u{11288}', '\\u{11288}', SC_OLetter), ('\\u{1128a}', '\\u{1128d}',\n        SC_OLetter), ('\\u{1128f}', '\\u{1129d}', SC_OLetter), ('\\u{1129f}', '\\u{112a8}', SC_OLetter),\n        ('\\u{112a9}', '\\u{112a9}', SC_STerm), ('\\u{112b0}', '\\u{112de}', SC_OLetter), ('\\u{112df}',\n        '\\u{112ea}', SC_Extend), ('\\u{112f0}', '\\u{112f9}', SC_Numeric), ('\\u{11300}', '\\u{11303}',\n        SC_Extend), ('\\u{11305}', '\\u{1130c}', SC_OLetter), ('\\u{1130f}', '\\u{11310}', SC_OLetter),\n        ('\\u{11313}', '\\u{11328}', SC_OLetter), ('\\u{1132a}', '\\u{11330}', SC_OLetter),\n        ('\\u{11332}', '\\u{11333}', SC_OLetter), ('\\u{11335}', '\\u{11339}', SC_OLetter),\n        ('\\u{1133b}', '\\u{1133c}', SC_Extend), ('\\u{1133d}', '\\u{1133d}', SC_OLetter), ('\\u{1133e}',\n        '\\u{11344}', SC_Extend), ('\\u{11347}', '\\u{11348}', SC_Extend), ('\\u{1134b}', '\\u{1134d}',\n        SC_Extend), ('\\u{11350}', '\\u{11350}', SC_OLetter), ('\\u{11357}', '\\u{11357}', SC_Extend),\n        ('\\u{1135d}', '\\u{11361}', SC_OLetter), ('\\u{11362}', '\\u{11363}', SC_Extend), ('\\u{11366}',\n        '\\u{1136c}', SC_Extend), ('\\u{11370}', '\\u{11374}', SC_Extend), ('\\u{11380}', '\\u{11389}',\n        SC_OLetter), ('\\u{1138b}', '\\u{1138b}', SC_OLetter), ('\\u{1138e}', '\\u{1138e}', SC_OLetter),\n        ('\\u{11390}', '\\u{113b5}', SC_OLetter), ('\\u{113b7}', '\\u{113b7}', SC_OLetter),\n        ('\\u{113b8}', '\\u{113c0}', SC_Extend), ('\\u{113c2}', '\\u{113c2}', SC_Extend), ('\\u{113c5}',\n        '\\u{113c5}', SC_Extend), ('\\u{113c7}', '\\u{113ca}', SC_Extend), ('\\u{113cc}', '\\u{113d0}',\n        SC_Extend), ('\\u{113d1}', '\\u{113d1}', SC_OLetter), ('\\u{113d2}', '\\u{113d2}', SC_Extend),\n        ('\\u{113d3}', '\\u{113d3}', SC_OLetter), ('\\u{113d4}', '\\u{113d5}', SC_STerm), ('\\u{113e1}',\n        '\\u{113e2}', SC_Extend), ('\\u{11400}', '\\u{11434}', SC_OLetter), ('\\u{11435}', '\\u{11446}',\n        SC_Extend), ('\\u{11447}', '\\u{1144a}', SC_OLetter), ('\\u{1144b}', '\\u{1144c}', SC_STerm),\n        ('\\u{11450}', '\\u{11459}', SC_Numeric), ('\\u{1145e}', '\\u{1145e}', SC_Extend), ('\\u{1145f}',\n        '\\u{11461}', SC_OLetter), ('\\u{11480}', '\\u{114af}', SC_OLetter), ('\\u{114b0}', '\\u{114c3}',\n        SC_Extend), ('\\u{114c4}', '\\u{114c5}', SC_OLetter), ('\\u{114c7}', '\\u{114c7}', SC_OLetter),\n        ('\\u{114d0}', '\\u{114d9}', SC_Numeric), ('\\u{11580}', '\\u{115ae}', SC_OLetter),\n        ('\\u{115af}', '\\u{115b5}', SC_Extend), ('\\u{115b8}', '\\u{115c0}', SC_Extend), ('\\u{115c2}',\n        '\\u{115c3}', SC_STerm), ('\\u{115c9}', '\\u{115d7}', SC_STerm), ('\\u{115d8}', '\\u{115db}',\n        SC_OLetter), ('\\u{115dc}', '\\u{115dd}', SC_Extend), ('\\u{11600}', '\\u{1162f}', SC_OLetter),\n        ('\\u{11630}', '\\u{11640}', SC_Extend), ('\\u{11641}', '\\u{11642}', SC_STerm), ('\\u{11644}',\n        '\\u{11644}', SC_OLetter), ('\\u{11650}', '\\u{11659}', SC_Numeric), ('\\u{11680}', '\\u{116aa}',\n        SC_OLetter), ('\\u{116ab}', '\\u{116b7}', SC_Extend), ('\\u{116b8}', '\\u{116b8}', SC_OLetter),\n        ('\\u{116c0}', '\\u{116c9}', SC_Numeric), ('\\u{116d0}', '\\u{116e3}', SC_Numeric),\n        ('\\u{11700}', '\\u{1171a}', SC_OLetter), ('\\u{1171d}', '\\u{1172b}', SC_Extend), ('\\u{11730}',\n        '\\u{11739}', SC_Numeric), ('\\u{1173c}', '\\u{1173e}', SC_STerm), ('\\u{11740}', '\\u{11746}',\n        SC_OLetter), ('\\u{11800}', '\\u{1182b}', SC_OLetter), ('\\u{1182c}', '\\u{1183a}', SC_Extend),\n        ('\\u{118a0}', '\\u{118bf}', SC_Upper), ('\\u{118c0}', '\\u{118df}', SC_Lower), ('\\u{118e0}',\n        '\\u{118e9}', SC_Numeric), ('\\u{118ff}', '\\u{11906}', SC_OLetter), ('\\u{11909}', '\\u{11909}',\n        SC_OLetter), ('\\u{1190c}', '\\u{11913}', SC_OLetter), ('\\u{11915}', '\\u{11916}', SC_OLetter),\n        ('\\u{11918}', '\\u{1192f}', SC_OLetter), ('\\u{11930}', '\\u{11935}', SC_Extend), ('\\u{11937}',\n        '\\u{11938}', SC_Extend), ('\\u{1193b}', '\\u{1193e}', SC_Extend), ('\\u{1193f}', '\\u{1193f}',\n        SC_OLetter), ('\\u{11940}', '\\u{11940}', SC_Extend), ('\\u{11941}', '\\u{11941}', SC_OLetter),\n        ('\\u{11942}', '\\u{11943}', SC_Extend), ('\\u{11944}', '\\u{11944}', SC_STerm), ('\\u{11946}',\n        '\\u{11946}', SC_STerm), ('\\u{11950}', '\\u{11959}', SC_Numeric), ('\\u{119a0}', '\\u{119a7}',\n        SC_OLetter), ('\\u{119aa}', '\\u{119d0}', SC_OLetter), ('\\u{119d1}', '\\u{119d7}', SC_Extend),\n        ('\\u{119da}', '\\u{119e0}', SC_Extend), ('\\u{119e1}', '\\u{119e1}', SC_OLetter), ('\\u{119e3}',\n        '\\u{119e3}', SC_OLetter), ('\\u{119e4}', '\\u{119e4}', SC_Extend), ('\\u{11a00}', '\\u{11a00}',\n        SC_OLetter), ('\\u{11a01}', '\\u{11a0a}', SC_Extend), ('\\u{11a0b}', '\\u{11a32}', SC_OLetter),\n        ('\\u{11a33}', '\\u{11a39}', SC_Extend), ('\\u{11a3a}', '\\u{11a3a}', SC_OLetter), ('\\u{11a3b}',\n        '\\u{11a3e}', SC_Extend), ('\\u{11a42}', '\\u{11a43}', SC_STerm), ('\\u{11a47}', '\\u{11a47}',\n        SC_Extend), ('\\u{11a50}', '\\u{11a50}', SC_OLetter), ('\\u{11a51}', '\\u{11a5b}', SC_Extend),\n        ('\\u{11a5c}', '\\u{11a89}', SC_OLetter), ('\\u{11a8a}', '\\u{11a99}', SC_Extend), ('\\u{11a9b}',\n        '\\u{11a9c}', SC_STerm), ('\\u{11a9d}', '\\u{11a9d}', SC_OLetter), ('\\u{11ab0}', '\\u{11af8}',\n        SC_OLetter), ('\\u{11b60}', '\\u{11b67}', SC_Extend), ('\\u{11bc0}', '\\u{11be0}', SC_OLetter),\n        ('\\u{11bf0}', '\\u{11bf9}', SC_Numeric), ('\\u{11c00}', '\\u{11c08}', SC_OLetter),\n        ('\\u{11c0a}', '\\u{11c2e}', SC_OLetter), ('\\u{11c2f}', '\\u{11c36}', SC_Extend), ('\\u{11c38}',\n        '\\u{11c3f}', SC_Extend), ('\\u{11c40}', '\\u{11c40}', SC_OLetter), ('\\u{11c41}', '\\u{11c42}',\n        SC_STerm), ('\\u{11c50}', '\\u{11c59}', SC_Numeric), ('\\u{11c72}', '\\u{11c8f}', SC_OLetter),\n        ('\\u{11c92}', '\\u{11ca7}', SC_Extend), ('\\u{11ca9}', '\\u{11cb6}', SC_Extend), ('\\u{11d00}',\n        '\\u{11d06}', SC_OLetter), ('\\u{11d08}', '\\u{11d09}', SC_OLetter), ('\\u{11d0b}', '\\u{11d30}',\n        SC_OLetter), ('\\u{11d31}', '\\u{11d36}', SC_Extend), ('\\u{11d3a}', '\\u{11d3a}', SC_Extend),\n        ('\\u{11d3c}', '\\u{11d3d}', SC_Extend), ('\\u{11d3f}', '\\u{11d45}', SC_Extend), ('\\u{11d46}',\n        '\\u{11d46}', SC_OLetter), ('\\u{11d47}', '\\u{11d47}', SC_Extend), ('\\u{11d50}', '\\u{11d59}',\n        SC_Numeric), ('\\u{11d60}', '\\u{11d65}', SC_OLetter), ('\\u{11d67}', '\\u{11d68}', SC_OLetter),\n        ('\\u{11d6a}', '\\u{11d89}', SC_OLetter), ('\\u{11d8a}', '\\u{11d8e}', SC_Extend), ('\\u{11d90}',\n        '\\u{11d91}', SC_Extend), ('\\u{11d93}', '\\u{11d97}', SC_Extend), ('\\u{11d98}', '\\u{11d98}',\n        SC_OLetter), ('\\u{11da0}', '\\u{11da9}', SC_Numeric), ('\\u{11db0}', '\\u{11ddb}', SC_OLetter),\n        ('\\u{11de0}', '\\u{11de9}', SC_Numeric), ('\\u{11ee0}', '\\u{11ef2}', SC_OLetter),\n        ('\\u{11ef3}', '\\u{11ef6}', SC_Extend), ('\\u{11ef7}', '\\u{11ef8}', SC_STerm), ('\\u{11f00}',\n        '\\u{11f01}', SC_Extend), ('\\u{11f02}', '\\u{11f02}', SC_OLetter), ('\\u{11f03}', '\\u{11f03}',\n        SC_Extend), ('\\u{11f04}', '\\u{11f10}', SC_OLetter), ('\\u{11f12}', '\\u{11f33}', SC_OLetter),\n        ('\\u{11f34}', '\\u{11f3a}', SC_Extend), ('\\u{11f3e}', '\\u{11f42}', SC_Extend), ('\\u{11f43}',\n        '\\u{11f44}', SC_STerm), ('\\u{11f50}', '\\u{11f59}', SC_Numeric), ('\\u{11f5a}', '\\u{11f5a}',\n        SC_Extend), ('\\u{11fb0}', '\\u{11fb0}', SC_OLetter), ('\\u{12000}', '\\u{12399}', SC_OLetter),\n        ('\\u{12400}', '\\u{1246e}', SC_OLetter), ('\\u{12480}', '\\u{12543}', SC_OLetter),\n        ('\\u{12f90}', '\\u{12ff0}', SC_OLetter), ('\\u{13000}', '\\u{1342f}', SC_OLetter),\n        ('\\u{13430}', '\\u{1343f}', SC_Format), ('\\u{13440}', '\\u{13440}', SC_Extend), ('\\u{13441}',\n        '\\u{13446}', SC_OLetter), ('\\u{13447}', '\\u{13455}', SC_Extend), ('\\u{13460}', '\\u{143fa}',\n        SC_OLetter), ('\\u{14400}', '\\u{14646}', SC_OLetter), ('\\u{16100}', '\\u{1611d}', SC_OLetter),\n        ('\\u{1611e}', '\\u{1612f}', SC_Extend), ('\\u{16130}', '\\u{16139}', SC_Numeric), ('\\u{16800}',\n        '\\u{16a38}', SC_OLetter), ('\\u{16a40}', '\\u{16a5e}', SC_OLetter), ('\\u{16a60}', '\\u{16a69}',\n        SC_Numeric), ('\\u{16a6e}', '\\u{16a6f}', SC_STerm), ('\\u{16a70}', '\\u{16abe}', SC_OLetter),\n        ('\\u{16ac0}', '\\u{16ac9}', SC_Numeric), ('\\u{16ad0}', '\\u{16aed}', SC_OLetter),\n        ('\\u{16af0}', '\\u{16af4}', SC_Extend), ('\\u{16af5}', '\\u{16af5}', SC_STerm), ('\\u{16b00}',\n        '\\u{16b2f}', SC_OLetter), ('\\u{16b30}', '\\u{16b36}', SC_Extend), ('\\u{16b37}', '\\u{16b38}',\n        SC_STerm), ('\\u{16b40}', '\\u{16b43}', SC_OLetter), ('\\u{16b44}', '\\u{16b44}', SC_STerm),\n        ('\\u{16b50}', '\\u{16b59}', SC_Numeric), ('\\u{16b63}', '\\u{16b77}', SC_OLetter),\n        ('\\u{16b7d}', '\\u{16b8f}', SC_OLetter), ('\\u{16d40}', '\\u{16d6c}', SC_OLetter),\n        ('\\u{16d6e}', '\\u{16d6f}', SC_STerm), ('\\u{16d70}', '\\u{16d79}', SC_Numeric), ('\\u{16e40}',\n        '\\u{16e5f}', SC_Upper), ('\\u{16e60}', '\\u{16e7f}', SC_Lower), ('\\u{16e98}', '\\u{16e98}',\n        SC_STerm), ('\\u{16ea0}', '\\u{16eb8}', SC_Upper), ('\\u{16ebb}', '\\u{16ed3}', SC_Lower),\n        ('\\u{16f00}', '\\u{16f4a}', SC_OLetter), ('\\u{16f4f}', '\\u{16f4f}', SC_Extend), ('\\u{16f50}',\n        '\\u{16f50}', SC_OLetter), ('\\u{16f51}', '\\u{16f87}', SC_Extend), ('\\u{16f8f}', '\\u{16f92}',\n        SC_Extend), ('\\u{16f93}', '\\u{16f9f}', SC_OLetter), ('\\u{16fe0}', '\\u{16fe1}', SC_OLetter),\n        ('\\u{16fe3}', '\\u{16fe3}', SC_OLetter), ('\\u{16fe4}', '\\u{16fe4}', SC_Extend), ('\\u{16ff0}',\n        '\\u{16ff1}', SC_Extend), ('\\u{16ff2}', '\\u{16ff6}', SC_OLetter), ('\\u{17000}', '\\u{18cd5}',\n        SC_OLetter), ('\\u{18cff}', '\\u{18d1e}', SC_OLetter), ('\\u{18d80}', '\\u{18df2}', SC_OLetter),\n        ('\\u{1aff0}', '\\u{1aff3}', SC_OLetter), ('\\u{1aff5}', '\\u{1affb}', SC_OLetter),\n        ('\\u{1affd}', '\\u{1affe}', SC_OLetter), ('\\u{1b000}', '\\u{1b122}', SC_OLetter),\n        ('\\u{1b132}', '\\u{1b132}', SC_OLetter), ('\\u{1b150}', '\\u{1b152}', SC_OLetter),\n        ('\\u{1b155}', '\\u{1b155}', SC_OLetter), ('\\u{1b164}', '\\u{1b167}', SC_OLetter),\n        ('\\u{1b170}', '\\u{1b2fb}', SC_OLetter), ('\\u{1bc00}', '\\u{1bc6a}', SC_OLetter),\n        ('\\u{1bc70}', '\\u{1bc7c}', SC_OLetter), ('\\u{1bc80}', '\\u{1bc88}', SC_OLetter),\n        ('\\u{1bc90}', '\\u{1bc99}', SC_OLetter), ('\\u{1bc9d}', '\\u{1bc9e}', SC_Extend), ('\\u{1bc9f}',\n        '\\u{1bc9f}', SC_STerm), ('\\u{1bca0}', '\\u{1bca3}', SC_Format), ('\\u{1ccf0}', '\\u{1ccf9}',\n        SC_Numeric), ('\\u{1cf00}', '\\u{1cf2d}', SC_Extend), ('\\u{1cf30}', '\\u{1cf46}', SC_Extend),\n        ('\\u{1d165}', '\\u{1d169}', SC_Extend), ('\\u{1d16d}', '\\u{1d172}', SC_Extend), ('\\u{1d173}',\n        '\\u{1d17a}', SC_Format), ('\\u{1d17b}', '\\u{1d182}', SC_Extend), ('\\u{1d185}', '\\u{1d18b}',\n        SC_Extend), ('\\u{1d1aa}', '\\u{1d1ad}', SC_Extend), ('\\u{1d242}', '\\u{1d244}', SC_Extend),\n        ('\\u{1d400}', '\\u{1d419}', SC_Upper), ('\\u{1d41a}', '\\u{1d433}', SC_Lower), ('\\u{1d434}',\n        '\\u{1d44d}', SC_Upper), ('\\u{1d44e}', '\\u{1d454}', SC_Lower), ('\\u{1d456}', '\\u{1d467}',\n        SC_Lower), ('\\u{1d468}', '\\u{1d481}', SC_Upper), ('\\u{1d482}', '\\u{1d49b}', SC_Lower),\n        ('\\u{1d49c}', '\\u{1d49c}', SC_Upper), ('\\u{1d49e}', '\\u{1d49f}', SC_Upper), ('\\u{1d4a2}',\n        '\\u{1d4a2}', SC_Upper), ('\\u{1d4a5}', '\\u{1d4a6}', SC_Upper), ('\\u{1d4a9}', '\\u{1d4ac}',\n        SC_Upper), ('\\u{1d4ae}', '\\u{1d4b5}', SC_Upper), ('\\u{1d4b6}', '\\u{1d4b9}', SC_Lower),\n        ('\\u{1d4bb}', '\\u{1d4bb}', SC_Lower), ('\\u{1d4bd}', '\\u{1d4c3}', SC_Lower), ('\\u{1d4c5}',\n        '\\u{1d4cf}', SC_Lower), ('\\u{1d4d0}', '\\u{1d4e9}', SC_Upper), ('\\u{1d4ea}', '\\u{1d503}',\n        SC_Lower), ('\\u{1d504}', '\\u{1d505}', SC_Upper), ('\\u{1d507}', '\\u{1d50a}', SC_Upper),\n        ('\\u{1d50d}', '\\u{1d514}', SC_Upper), ('\\u{1d516}', '\\u{1d51c}', SC_Upper), ('\\u{1d51e}',\n        '\\u{1d537}', SC_Lower), ('\\u{1d538}', '\\u{1d539}', SC_Upper), ('\\u{1d53b}', '\\u{1d53e}',\n        SC_Upper), ('\\u{1d540}', '\\u{1d544}', SC_Upper), ('\\u{1d546}', '\\u{1d546}', SC_Upper),\n        ('\\u{1d54a}', '\\u{1d550}', SC_Upper), ('\\u{1d552}', '\\u{1d56b}', SC_Lower), ('\\u{1d56c}',\n        '\\u{1d585}', SC_Upper), ('\\u{1d586}', '\\u{1d59f}', SC_Lower), ('\\u{1d5a0}', '\\u{1d5b9}',\n        SC_Upper), ('\\u{1d5ba}', '\\u{1d5d3}', SC_Lower), ('\\u{1d5d4}', '\\u{1d5ed}', SC_Upper),\n        ('\\u{1d5ee}', '\\u{1d607}', SC_Lower), ('\\u{1d608}', '\\u{1d621}', SC_Upper), ('\\u{1d622}',\n        '\\u{1d63b}', SC_Lower), ('\\u{1d63c}', '\\u{1d655}', SC_Upper), ('\\u{1d656}', '\\u{1d66f}',\n        SC_Lower), ('\\u{1d670}', '\\u{1d689}', SC_Upper), ('\\u{1d68a}', '\\u{1d6a5}', SC_Lower),\n        ('\\u{1d6a8}', '\\u{1d6c0}', SC_Upper), ('\\u{1d6c2}', '\\u{1d6da}', SC_Lower), ('\\u{1d6dc}',\n        '\\u{1d6e1}', SC_Lower), ('\\u{1d6e2}', '\\u{1d6fa}', SC_Upper), ('\\u{1d6fc}', '\\u{1d714}',\n        SC_Lower), ('\\u{1d716}', '\\u{1d71b}', SC_Lower), ('\\u{1d71c}', '\\u{1d734}', SC_Upper),\n        ('\\u{1d736}', '\\u{1d74e}', SC_Lower), ('\\u{1d750}', '\\u{1d755}', SC_Lower), ('\\u{1d756}',\n        '\\u{1d76e}', SC_Upper), ('\\u{1d770}', '\\u{1d788}', SC_Lower), ('\\u{1d78a}', '\\u{1d78f}',\n        SC_Lower), ('\\u{1d790}', '\\u{1d7a8}', SC_Upper), ('\\u{1d7aa}', '\\u{1d7c2}', SC_Lower),\n        ('\\u{1d7c4}', '\\u{1d7c9}', SC_Lower), ('\\u{1d7ca}', '\\u{1d7ca}', SC_Upper), ('\\u{1d7cb}',\n        '\\u{1d7cb}', SC_Lower), ('\\u{1d7ce}', '\\u{1d7ff}', SC_Numeric), ('\\u{1da00}', '\\u{1da36}',\n        SC_Extend), ('\\u{1da3b}', '\\u{1da6c}', SC_Extend), ('\\u{1da75}', '\\u{1da75}', SC_Extend),\n        ('\\u{1da84}', '\\u{1da84}', SC_Extend), ('\\u{1da88}', '\\u{1da88}', SC_STerm), ('\\u{1da9b}',\n        '\\u{1da9f}', SC_Extend), ('\\u{1daa1}', '\\u{1daaf}', SC_Extend), ('\\u{1df00}', '\\u{1df09}',\n        SC_Lower), ('\\u{1df0a}', '\\u{1df0a}', SC_OLetter), ('\\u{1df0b}', '\\u{1df1e}', SC_Lower),\n        ('\\u{1df25}', '\\u{1df2a}', SC_Lower), ('\\u{1e000}', '\\u{1e006}', SC_Extend), ('\\u{1e008}',\n        '\\u{1e018}', SC_Extend), ('\\u{1e01b}', '\\u{1e021}', SC_Extend), ('\\u{1e023}', '\\u{1e024}',\n        SC_Extend), ('\\u{1e026}', '\\u{1e02a}', SC_Extend), ('\\u{1e030}', '\\u{1e06d}', SC_Lower),\n        ('\\u{1e08f}', '\\u{1e08f}', SC_Extend), ('\\u{1e100}', '\\u{1e12c}', SC_OLetter), ('\\u{1e130}',\n        '\\u{1e136}', SC_Extend), ('\\u{1e137}', '\\u{1e13d}', SC_OLetter), ('\\u{1e140}', '\\u{1e149}',\n        SC_Numeric), ('\\u{1e14e}', '\\u{1e14e}', SC_OLetter), ('\\u{1e290}', '\\u{1e2ad}', SC_OLetter),\n        ('\\u{1e2ae}', '\\u{1e2ae}', SC_Extend), ('\\u{1e2c0}', '\\u{1e2eb}', SC_OLetter), ('\\u{1e2ec}',\n        '\\u{1e2ef}', SC_Extend), ('\\u{1e2f0}', '\\u{1e2f9}', SC_Numeric), ('\\u{1e4d0}', '\\u{1e4eb}',\n        SC_OLetter), ('\\u{1e4ec}', '\\u{1e4ef}', SC_Extend), ('\\u{1e4f0}', '\\u{1e4f9}', SC_Numeric),\n        ('\\u{1e5d0}', '\\u{1e5ed}', SC_OLetter), ('\\u{1e5ee}', '\\u{1e5ef}', SC_Extend), ('\\u{1e5f0}',\n        '\\u{1e5f0}', SC_OLetter), ('\\u{1e5f1}', '\\u{1e5fa}', SC_Numeric), ('\\u{1e6c0}', '\\u{1e6de}',\n        SC_OLetter), ('\\u{1e6e0}', '\\u{1e6e2}', SC_OLetter), ('\\u{1e6e3}', '\\u{1e6e3}', SC_Extend),\n        ('\\u{1e6e4}', '\\u{1e6e5}', SC_OLetter), ('\\u{1e6e6}', '\\u{1e6e6}', SC_Extend), ('\\u{1e6e7}',\n        '\\u{1e6ed}', SC_OLetter), ('\\u{1e6ee}', '\\u{1e6ef}', SC_Extend), ('\\u{1e6f0}', '\\u{1e6f4}',\n        SC_OLetter), ('\\u{1e6f5}', '\\u{1e6f5}', SC_Extend), ('\\u{1e6fe}', '\\u{1e6ff}', SC_OLetter),\n        ('\\u{1e7e0}', '\\u{1e7e6}', SC_OLetter), ('\\u{1e7e8}', '\\u{1e7eb}', SC_OLetter),\n        ('\\u{1e7ed}', '\\u{1e7ee}', SC_OLetter), ('\\u{1e7f0}', '\\u{1e7fe}', SC_OLetter),\n        ('\\u{1e800}', '\\u{1e8c4}', SC_OLetter), ('\\u{1e8d0}', '\\u{1e8d6}', SC_Extend), ('\\u{1e900}',\n        '\\u{1e921}', SC_Upper), ('\\u{1e922}', '\\u{1e943}', SC_Lower), ('\\u{1e944}', '\\u{1e94a}',\n        SC_Extend), ('\\u{1e94b}', '\\u{1e94b}', SC_OLetter), ('\\u{1e950}', '\\u{1e959}', SC_Numeric),\n        ('\\u{1ee00}', '\\u{1ee03}', SC_OLetter), ('\\u{1ee05}', '\\u{1ee1f}', SC_OLetter),\n        ('\\u{1ee21}', '\\u{1ee22}', SC_OLetter), ('\\u{1ee24}', '\\u{1ee24}', SC_OLetter),\n        ('\\u{1ee27}', '\\u{1ee27}', SC_OLetter), ('\\u{1ee29}', '\\u{1ee32}', SC_OLetter),\n        ('\\u{1ee34}', '\\u{1ee37}', SC_OLetter), ('\\u{1ee39}', '\\u{1ee39}', SC_OLetter),\n        ('\\u{1ee3b}', '\\u{1ee3b}', SC_OLetter), ('\\u{1ee42}', '\\u{1ee42}', SC_OLetter),\n        ('\\u{1ee47}', '\\u{1ee47}', SC_OLetter), ('\\u{1ee49}', '\\u{1ee49}', SC_OLetter),\n        ('\\u{1ee4b}', '\\u{1ee4b}', SC_OLetter), ('\\u{1ee4d}', '\\u{1ee4f}', SC_OLetter),\n        ('\\u{1ee51}', '\\u{1ee52}', SC_OLetter), ('\\u{1ee54}', '\\u{1ee54}', SC_OLetter),\n        ('\\u{1ee57}', '\\u{1ee57}', SC_OLetter), ('\\u{1ee59}', '\\u{1ee59}', SC_OLetter),\n        ('\\u{1ee5b}', '\\u{1ee5b}', SC_OLetter), ('\\u{1ee5d}', '\\u{1ee5d}', SC_OLetter),\n        ('\\u{1ee5f}', '\\u{1ee5f}', SC_OLetter), ('\\u{1ee61}', '\\u{1ee62}', SC_OLetter),\n        ('\\u{1ee64}', '\\u{1ee64}', SC_OLetter), ('\\u{1ee67}', '\\u{1ee6a}', SC_OLetter),\n        ('\\u{1ee6c}', '\\u{1ee72}', SC_OLetter), ('\\u{1ee74}', '\\u{1ee77}', SC_OLetter),\n        ('\\u{1ee79}', '\\u{1ee7c}', SC_OLetter), ('\\u{1ee7e}', '\\u{1ee7e}', SC_OLetter),\n        ('\\u{1ee80}', '\\u{1ee89}', SC_OLetter), ('\\u{1ee8b}', '\\u{1ee9b}', SC_OLetter),\n        ('\\u{1eea1}', '\\u{1eea3}', SC_OLetter), ('\\u{1eea5}', '\\u{1eea9}', SC_OLetter),\n        ('\\u{1eeab}', '\\u{1eebb}', SC_OLetter), ('\\u{1f130}', '\\u{1f149}', SC_Upper), ('\\u{1f150}',\n        '\\u{1f169}', SC_Upper), ('\\u{1f170}', '\\u{1f189}', SC_Upper), ('\\u{1f676}', '\\u{1f678}',\n        SC_Close), ('\\u{1fbf0}', '\\u{1fbf9}', SC_Numeric), ('\\u{20000}', '\\u{2a6df}', SC_OLetter),\n        ('\\u{2a700}', '\\u{2b81d}', SC_OLetter), ('\\u{2b820}', '\\u{2cead}', SC_OLetter),\n        ('\\u{2ceb0}', '\\u{2ebe0}', SC_OLetter), ('\\u{2ebf0}', '\\u{2ee5d}', SC_OLetter),\n        ('\\u{2f800}', '\\u{2fa1d}', SC_OLetter), ('\\u{30000}', '\\u{3134a}', SC_OLetter),\n        ('\\u{31350}', '\\u{33479}', SC_OLetter), ('\\u{e0001}', '\\u{e0001}', SC_Format), ('\\u{e0020}',\n        '\\u{e007f}', SC_Extend), ('\\u{e0100}', '\\u{e01ef}', SC_Extend)\n    ];\n\n}\n"
    },
    {
      "package": "unicode-segmentation@1.13.3",
      "sourcePath": "src/word.rs",
      "sha256": "27d8f79071f57e314053d0c9dda0d39eb10c66343d2069e9ba22a8629e1ddef4",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse core::cmp;\nuse core::iter::Filter;\n\nuse crate::tables::word::WordCat;\n\n/// An iterator over the substrings of a string which, after splitting the string on\n/// [word boundaries](http://www.unicode.org/reports/tr29/#Word_Boundaries),\n/// contain any characters with the\n/// [Alphabetic](http://unicode.org/reports/tr44/#Alphabetic)\n/// property, or with\n/// [General_Category=Number](http://unicode.org/reports/tr44/#General_Category_Values).\n///\n/// This struct is created by the [`unicode_words`] method on the [`UnicodeSegmentation`] trait. See\n/// its documentation for more.\n///\n/// [`unicode_words`]: trait.UnicodeSegmentation.html#tymethod.unicode_words\n/// [`UnicodeSegmentation`]: trait.UnicodeSegmentation.html\n#[derive(Debug)]\npub struct UnicodeWords<'a> {\n    inner: WordsIter<'a>,\n}\n\nimpl<'a> Iterator for UnicodeWords<'a> {\n    type Item = &'a str;\n    #[inline]\n    fn next(&mut self) -> Option<Self::Item> {\n        match &mut self.inner {\n            WordsIter::Ascii(i) => i.next(),\n            WordsIter::Unicode(i) => i.next(),\n        }\n    }\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        match &self.inner {\n            WordsIter::Ascii(i) => i.size_hint(),\n            WordsIter::Unicode(i) => i.size_hint(),\n        }\n    }\n}\nimpl<'a> DoubleEndedIterator for UnicodeWords<'a> {\n    #[inline]\n    fn next_back(&mut self) -> Option<Self::Item> {\n        match &mut self.inner {\n            WordsIter::Ascii(i) => i.next_back(),\n            WordsIter::Unicode(i) => i.next_back(),\n        }\n    }\n}\n\n/// An iterator over the substrings of a string which, after splitting the string on\n/// [word boundaries](http://www.unicode.org/reports/tr29/#Word_Boundaries),\n/// contain any characters with the\n/// [Alphabetic](http://unicode.org/reports/tr44/#Alphabetic)\n/// property, or with\n/// [General_Category=Number](http://unicode.org/reports/tr44/#General_Category_Values).\n/// This iterator also provides the byte offsets for each substring.\n///\n/// This struct is created by the [`unicode_word_indices`] method on the [`UnicodeSegmentation`] trait. See\n/// its documentation for more.\n///\n/// [`unicode_word_indices`]: trait.UnicodeSegmentation.html#tymethod.unicode_word_indices\n/// [`UnicodeSegmentation`]: trait.UnicodeSegmentation.html\n#[derive(Debug)]\npub struct UnicodeWordIndices<'a> {\n    inner: IndicesIter<'a>,\n}\n\nimpl<'a> Iterator for UnicodeWordIndices<'a> {\n    type Item = (usize, &'a str);\n    #[inline]\n    fn next(&mut self) -> Option<Self::Item> {\n        match &mut self.inner {\n            IndicesIter::Ascii(i) => i.next(),\n            IndicesIter::Unicode(i) => i.next(),\n        }\n    }\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        match &self.inner {\n            IndicesIter::Ascii(i) => i.size_hint(),\n            IndicesIter::Unicode(i) => i.size_hint(),\n        }\n    }\n}\nimpl<'a> DoubleEndedIterator for UnicodeWordIndices<'a> {\n    #[inline]\n    fn next_back(&mut self) -> Option<Self::Item> {\n        match &mut self.inner {\n            IndicesIter::Ascii(i) => i.next_back(),\n            IndicesIter::Unicode(i) => i.next_back(),\n        }\n    }\n}\n\n/// External iterator for a string's\n/// [word boundaries](http://www.unicode.org/reports/tr29/#Word_Boundaries).\n///\n/// This struct is created by the [`split_word_bounds`] method on the [`UnicodeSegmentation`]\n/// trait. See its documentation for more.\n///\n/// [`split_word_bounds`]: trait.UnicodeSegmentation.html#tymethod.split_word_bounds\n/// [`UnicodeSegmentation`]: trait.UnicodeSegmentation.html\n#[derive(Debug, Clone)]\npub struct UWordBounds<'a> {\n    string: &'a str,\n    cat: Option<WordCat>,\n    catb: Option<WordCat>,\n}\n\n/// External iterator for word boundaries and byte offsets.\n///\n/// This struct is created by the [`split_word_bound_indices`] method on the\n/// [`UnicodeSegmentation`] trait. See its documentation for more.\n///\n/// [`split_word_bound_indices`]: trait.UnicodeSegmentation.html#tymethod.split_word_bound_indices\n/// [`UnicodeSegmentation`]: trait.UnicodeSegmentation.html\n#[derive(Debug, Clone)]\npub struct UWordBoundIndices<'a> {\n    start_offset: usize,\n    iter: UWordBounds<'a>,\n}\n\nimpl<'a> UWordBoundIndices<'a> {\n    #[inline]\n    /// View the underlying data (the part yet to be iterated) as a slice of the original string.\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::UnicodeSegmentation;\n    /// let mut iter = \"Hello world\".split_word_bound_indices();\n    /// assert_eq!(iter.as_str(), \"Hello world\");\n    /// iter.next();\n    /// assert_eq!(iter.as_str(), \" world\");\n    /// iter.next();\n    /// assert_eq!(iter.as_str(), \"world\");\n    /// ```\n    pub fn as_str(&self) -> &'a str {\n        self.iter.as_str()\n    }\n}\n\nimpl<'a> Iterator for UWordBoundIndices<'a> {\n    type Item = (usize, &'a str);\n\n    #[inline]\n    fn next(&mut self) -> Option<(usize, &'a str)> {\n        self.iter\n            .next()\n            .map(|s| (s.as_ptr() as usize - self.start_offset, s))\n    }\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.iter.size_hint()\n    }\n}\n\nimpl<'a> DoubleEndedIterator for UWordBoundIndices<'a> {\n    #[inline]\n    fn next_back(&mut self) -> Option<(usize, &'a str)> {\n        self.iter\n            .next_back()\n            .map(|s| (s.as_ptr() as usize - self.start_offset, s))\n    }\n}\n\n// state machine for word boundary rules\n#[derive(Clone, Copy, PartialEq, Eq, Debug)]\nenum UWordBoundsState {\n    Start,\n    Letter,\n    HLetter,\n    Numeric,\n    Katakana,\n    ExtendNumLet,\n    Regional(RegionalState),\n    FormatExtend(FormatExtendType),\n    Zwj,\n    Emoji,\n    WSegSpace,\n}\n\n// subtypes for FormatExtend state in UWordBoundsState\n#[derive(Clone, Copy, PartialEq, Eq, Debug)]\nenum FormatExtendType {\n    AcceptAny,\n    AcceptNone,\n    RequireLetter,\n    RequireHLetter,\n    AcceptQLetter,\n    RequireNumeric,\n}\n\n#[derive(Clone, Copy, PartialEq, Eq, Debug)]\nenum RegionalState {\n    Half,\n    Full,\n    Unknown,\n}\n\nfn is_emoji(ch: char) -> bool {\n    use crate::tables::emoji;\n    emoji::emoji_category(ch).2 == emoji::EmojiCat::EC_Extended_Pictographic\n}\n\nimpl<'a> Iterator for UWordBounds<'a> {\n    type Item = &'a str;\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let slen = self.string.len();\n        (cmp::min(slen, 1), Some(slen))\n    }\n\n    #[inline]\n    fn next(&mut self) -> Option<&'a str> {\n        use self::FormatExtendType::*;\n        use self::UWordBoundsState::*;\n        use crate::tables::word as wd;\n        if self.string.is_empty() {\n            return None;\n        }\n\n        let mut take_curr = true;\n        let mut take_cat = true;\n        let mut idx = 0;\n        let mut saveidx = 0;\n        let mut state = Start;\n        let mut cat = wd::WC_Any;\n        let mut savecat = wd::WC_Any;\n\n        // If extend/format/zwj were skipped. Handles precedence of WB3d over WB4\n        let mut skipped_format_extend = false;\n        for (curr, ch) in self.string.char_indices() {\n            idx = curr;\n            // Whether or not the previous category was ZWJ\n            // ZWJs get collapsed, so this handles precedence of WB3c over WB4\n            let prev_zwj = cat == wd::WC_ZWJ;\n            // if there's a category cached, grab it\n            cat = match self.cat {\n                None => wd::word_category(ch).2,\n                _ => self.cat.take().unwrap(),\n            };\n            take_cat = true;\n\n            // handle rule WB4\n            // just skip all format, extend, and zwj chars\n            // note that Start is a special case: if there's a bunch of Format | Extend\n            // characters at the beginning of a block of text, dump them out as one unit.\n            //\n            // (This is not obvious from the wording of UAX#29, but if you look at the\n            // test cases http://www.unicode.org/Public/UNIDATA/auxiliary/WordBreakTest.txt\n            // then the \"correct\" interpretation of WB4 becomes apparent.)\n            if state != Start {\n                match cat {\n                    wd::WC_Extend | wd::WC_Format | wd::WC_ZWJ => {\n                        skipped_format_extend = true;\n                        continue;\n                    }\n                    _ => {}\n                }\n            }\n\n            // rule WB3c\n            // WB4 makes all ZWJs collapse into the previous state\n            // but you can still be in a Zwj state if you started with Zwj\n            //\n            // This means that an EP + Zwj will collapse into EP, which is wrong,\n            // since EP+EP is not a boundary but EP+ZWJ+EP is\n            //\n            // Thus, we separately keep track of whether or not the last character\n            // was a ZWJ. This is an additional bit of state tracked outside of the\n            // state enum; the state enum represents the last non-zwj state encountered.\n            // When prev_zwj is true, for the purposes of WB3c, we are in the Zwj state,\n            // however we are in the previous state for the purposes of all other rules.\n            if prev_zwj && is_emoji(ch) {\n                state = Emoji;\n                continue;\n            }\n            // Don't use `continue` in this match without updating `cat`\n            state = match state {\n                Start if cat == wd::WC_CR => {\n                    idx += match self.get_next_cat(idx) {\n                        Some(wd::WC_LF) => 1, // rule WB3\n                        _ => 0,\n                    };\n                    break; // rule WB3a\n                }\n                Start => match cat {\n                    wd::WC_ALetter => Letter,            // rule WB5, WB6, WB9, WB13a\n                    wd::WC_Hebrew_Letter => HLetter,     // rule WB5, WB6, WB7a, WB7b, WB9, WB13a\n                    wd::WC_Numeric => Numeric,           // rule WB8, WB10, WB12, WB13a\n                    wd::WC_Katakana => Katakana,         // rule WB13, WB13a\n                    wd::WC_ExtendNumLet => ExtendNumLet, // rule WB13a, WB13b\n                    wd::WC_Regional_Indicator => Regional(RegionalState::Half), // rule WB13c\n                    wd::WC_LF | wd::WC_Newline => break, // rule WB3a\n                    wd::WC_ZWJ => Zwj,                   // rule WB3c\n                    wd::WC_WSegSpace => WSegSpace,       // rule WB3d\n                    _ => {\n                        if let Some(ncat) = self.get_next_cat(idx) {\n                            // rule WB4\n                            if ncat == wd::WC_Format || ncat == wd::WC_Extend || ncat == wd::WC_ZWJ\n                            {\n                                state = FormatExtend(AcceptNone);\n                                self.cat = Some(ncat);\n                                continue;\n                            }\n                        }\n                        break; // rule WB999\n                    }\n                },\n                WSegSpace => match cat {\n                    wd::WC_WSegSpace if !skipped_format_extend => WSegSpace,\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                Zwj => {\n                    // We already handle WB3c above.\n                    take_curr = false;\n                    break;\n                }\n                Letter | HLetter => match cat {\n                    wd::WC_ALetter => Letter,            // rule WB5\n                    wd::WC_Hebrew_Letter => HLetter,     // rule WB5\n                    wd::WC_Numeric => Numeric,           // rule WB9\n                    wd::WC_ExtendNumLet => ExtendNumLet, // rule WB13a\n                    wd::WC_Double_Quote if state == HLetter => {\n                        savecat = cat;\n                        saveidx = idx;\n                        FormatExtend(RequireHLetter) // rule WB7b\n                    }\n                    wd::WC_Single_Quote if state == HLetter => {\n                        FormatExtend(AcceptQLetter) // rule WB7a\n                    }\n                    wd::WC_MidLetter | wd::WC_MidNumLet | wd::WC_Single_Quote => {\n                        savecat = cat;\n                        saveidx = idx;\n                        FormatExtend(RequireLetter) // rule WB6\n                    }\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                Numeric => match cat {\n                    wd::WC_Numeric => Numeric,           // rule WB8\n                    wd::WC_ALetter => Letter,            // rule WB10\n                    wd::WC_Hebrew_Letter => HLetter,     // rule WB10\n                    wd::WC_ExtendNumLet => ExtendNumLet, // rule WB13a\n                    wd::WC_MidNum | wd::WC_MidNumLet | wd::WC_Single_Quote => {\n                        savecat = cat;\n                        saveidx = idx;\n                        FormatExtend(RequireNumeric) // rule WB12\n                    }\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                Katakana => match cat {\n                    wd::WC_Katakana => Katakana,         // rule WB13\n                    wd::WC_ExtendNumLet => ExtendNumLet, // rule WB13a\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                ExtendNumLet => match cat {\n                    wd::WC_ExtendNumLet => ExtendNumLet, // rule WB13a\n                    wd::WC_ALetter => Letter,            // rule WB13b\n                    wd::WC_Hebrew_Letter => HLetter,     // rule WB13b\n                    wd::WC_Numeric => Numeric,           // rule WB13b\n                    wd::WC_Katakana => Katakana,         // rule WB13b\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                Regional(RegionalState::Full) => {\n                    // if it reaches here we've gone too far,\n                    // a full flag can only compose with ZWJ/Extend/Format\n                    // proceeding it.\n                    take_curr = false;\n                    break;\n                }\n                Regional(RegionalState::Half) => match cat {\n                    wd::WC_Regional_Indicator => Regional(RegionalState::Full), // rule WB13c\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                Regional(_) => {\n                    unreachable!(\"RegionalState::Unknown should not occur on forward iteration\")\n                }\n                Emoji => {\n                    // We already handle WB3c above. If you've reached this point, the emoji sequence is over.\n                    take_curr = false;\n                    break;\n                }\n                FormatExtend(t) => match t {\n                    // handle FormatExtends depending on what type\n                    RequireNumeric if cat == wd::WC_Numeric => Numeric, // rule WB11\n                    RequireLetter | AcceptQLetter if cat == wd::WC_ALetter => Letter, // rule WB7\n                    RequireLetter | AcceptQLetter if cat == wd::WC_Hebrew_Letter => HLetter, // WB7a\n                    RequireHLetter if cat == wd::WC_Hebrew_Letter => HLetter, // rule WB7b\n                    AcceptNone | AcceptQLetter => {\n                        take_curr = false; // emit all the Format|Extend characters\n                        take_cat = false;\n                        break;\n                    }\n                    _ => break, // rewind (in if statement below)\n                },\n            }\n        }\n\n        if let FormatExtend(t) = state {\n            // we were looking for something and didn't find it; we have to back up\n            if t == RequireLetter || t == RequireHLetter || t == RequireNumeric {\n                idx = saveidx;\n                cat = savecat;\n                take_curr = false;\n            }\n        }\n\n        self.cat = if take_curr {\n            idx = idx + self.string[idx..].chars().next().unwrap().len_utf8();\n            None\n        } else if take_cat {\n            Some(cat)\n        } else {\n            None\n        };\n\n        let retstr = &self.string[..idx];\n        self.string = &self.string[idx..];\n        Some(retstr)\n    }\n}\n\nimpl<'a> DoubleEndedIterator for UWordBounds<'a> {\n    #[inline]\n    fn next_back(&mut self) -> Option<&'a str> {\n        use self::FormatExtendType::*;\n        use self::UWordBoundsState::*;\n        use crate::tables::word as wd;\n        if self.string.is_empty() {\n            return None;\n        }\n\n        let mut take_curr = true;\n        let mut take_cat = true;\n        let mut idx = self.string.len();\n        idx -= self.string.chars().next_back().unwrap().len_utf8();\n        let mut previdx = idx;\n        let mut saveidx = idx;\n        let mut state = Start;\n        let mut savestate = Start;\n        let mut cat = wd::WC_Any;\n\n        // WB3c is context-sensitive (ZWJ + Extended_Pictographic),\n        // while WB4 collapses Extend/Format and would otherwise hide that context.\n        // We therefore keep this context outside the main state machine:\n        // whether the nearest non-(Extend|Format) char to the right is emoji.\n        let mut right_significant_is_emoji: bool = false;\n\n        let mut skipped_format_extend = false;\n\n        for (curr, ch) in self.string.char_indices().rev() {\n            previdx = idx;\n            idx = curr;\n\n            // if there's a category cached, grab it\n            cat = match self.catb {\n                None => wd::word_category(ch).2,\n                _ => self.catb.take().unwrap(),\n            };\n            take_cat = true;\n\n            // backward iterator over word boundaries. Mostly the same as the forward\n            // iterator, with two weirdnesses:\n            // (1) If we encounter a single quote in the Start state, we have to check for a\n            //     Hebrew Letter immediately before it.\n            // (2) Format and Extend char handling takes some gymnastics.\n\n            // Reverse-direction WB3c check: when we encounter ZWJ and the nearest\n            // significant right-side char is emoji, do not break here.\n            if cat == wd::WC_ZWJ && state != Zwj && right_significant_is_emoji {\n                continue;\n            }\n\n            // Keep the right-side WB3c context up to date as we move left.\n            // Ignore Extend/Format here to mirror WB4 collapsing behavior.\n            if cat != wd::WC_Extend && cat != wd::WC_Format {\n                right_significant_is_emoji = is_emoji(ch);\n            }\n\n            if cat == wd::WC_Extend || cat == wd::WC_Format || (cat == wd::WC_ZWJ && state != Zwj) {\n                // WB3c has more priority so we should not\n                // fold in that case\n                if !matches!(state, FormatExtend(_) | Start) {\n                    saveidx = previdx;\n                    savestate = state;\n                    state = FormatExtend(AcceptNone);\n                }\n\n                if state != Start {\n                    continue;\n                }\n            } else if state == FormatExtend(AcceptNone) {\n                // finished a scan of some Format|Extend chars, restore previous state\n                state = savestate;\n                previdx = saveidx;\n                take_cat = false;\n                skipped_format_extend = true;\n            }\n\n            // Don't use `continue` in this match without updating `catb`\n            state = match state {\n                Start | FormatExtend(AcceptAny) => match cat {\n                    wd::WC_ALetter => Letter,            // rule WB5, WB7, WB10, WB13b\n                    wd::WC_Hebrew_Letter => HLetter,     // rule WB5, WB7, WB7c, WB10, WB13b\n                    wd::WC_Numeric => Numeric,           // rule WB8, WB9, WB11, WB13b\n                    wd::WC_Katakana => Katakana,         // rule WB13, WB13b\n                    wd::WC_ExtendNumLet => ExtendNumLet, // rule WB13a\n                    wd::WC_Regional_Indicator => Regional(RegionalState::Unknown), // rule WB13c\n                    // rule WB4:\n                    wd::WC_Extend | wd::WC_Format | wd::WC_ZWJ => FormatExtend(AcceptAny),\n                    wd::WC_Single_Quote => {\n                        saveidx = idx;\n                        FormatExtend(AcceptQLetter) // rule WB7a\n                    }\n                    wd::WC_WSegSpace => WSegSpace,\n                    wd::WC_CR | wd::WC_LF | wd::WC_Newline => {\n                        if state == Start {\n                            if cat == wd::WC_LF {\n                                idx -= match self.get_prev_cat(idx) {\n                                    Some(wd::WC_CR) => 1, // rule WB3\n                                    _ => 0,\n                                };\n                            }\n                        } else {\n                            take_curr = false;\n                        }\n                        break; // rule WB3a\n                    }\n                    _ if is_emoji(ch) => Zwj,\n                    _ => break, // rule WB999\n                },\n                Zwj => match cat {\n                    // rule WB3c\n                    wd::WC_ZWJ => FormatExtend(AcceptAny),\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                WSegSpace => match cat {\n                    // rule WB3d\n                    wd::WC_WSegSpace if !skipped_format_extend => WSegSpace,\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                Letter | HLetter => match cat {\n                    wd::WC_ALetter => Letter,            // rule WB5\n                    wd::WC_Hebrew_Letter => HLetter,     // rule WB5\n                    wd::WC_Numeric => Numeric,           // rule WB10\n                    wd::WC_ExtendNumLet => ExtendNumLet, // rule WB13b\n                    wd::WC_Double_Quote if state == HLetter => {\n                        saveidx = previdx;\n                        FormatExtend(RequireHLetter) // rule WB7c\n                    }\n                    wd::WC_MidLetter | wd::WC_MidNumLet | wd::WC_Single_Quote => {\n                        saveidx = previdx;\n                        FormatExtend(RequireLetter) // rule WB7\n                    }\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                Numeric => match cat {\n                    wd::WC_Numeric => Numeric,           // rule WB8\n                    wd::WC_ALetter => Letter,            // rule WB9\n                    wd::WC_Hebrew_Letter => HLetter,     // rule WB9\n                    wd::WC_ExtendNumLet => ExtendNumLet, // rule WB13b\n                    wd::WC_MidNum | wd::WC_MidNumLet | wd::WC_Single_Quote => {\n                        saveidx = previdx;\n                        FormatExtend(RequireNumeric) // rule WB11\n                    }\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                Katakana => match cat {\n                    wd::WC_Katakana => Katakana,         // rule WB13\n                    wd::WC_ExtendNumLet => ExtendNumLet, // rule WB13b\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                ExtendNumLet => match cat {\n                    wd::WC_ExtendNumLet => ExtendNumLet, // rule WB13a\n                    wd::WC_ALetter => Letter,            // rule WB13a\n                    wd::WC_Hebrew_Letter => HLetter,     // rule WB13a\n                    wd::WC_Numeric => Numeric,           // rule WB13a\n                    wd::WC_Katakana => Katakana,         // rule WB13a\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                Regional(mut regional_state) => match cat {\n                    // rule WB13c\n                    wd::WC_Regional_Indicator => {\n                        if regional_state == RegionalState::Unknown {\n                            let count = self.string[..previdx]\n                                .chars()\n                                .rev()\n                                .map(|c| wd::word_category(c).2)\n                                .filter(|&c| {\n                                    !(c == wd::WC_ZWJ || c == wd::WC_Extend || c == wd::WC_Format)\n                                })\n                                .take_while(|&c| c == wd::WC_Regional_Indicator)\n                                .count();\n                            regional_state = if count % 2 == 0 {\n                                RegionalState::Full\n                            } else {\n                                RegionalState::Half\n                            };\n                        }\n                        if regional_state == RegionalState::Full {\n                            take_curr = false;\n                            break;\n                        } else {\n                            Regional(RegionalState::Full)\n                        }\n                    }\n                    _ => {\n                        take_curr = false;\n                        break;\n                    }\n                },\n                Emoji => {\n                    if is_emoji(ch) {\n                        // rule WB3c\n                        Zwj\n                    } else {\n                        take_curr = false;\n                        break;\n                    }\n                }\n                FormatExtend(t) => match t {\n                    RequireNumeric if cat == wd::WC_Numeric => Numeric, // rule WB12\n                    RequireLetter if cat == wd::WC_ALetter => Letter,   // rule WB6\n                    RequireLetter if cat == wd::WC_Hebrew_Letter => HLetter, // rule WB6\n                    AcceptQLetter if cat == wd::WC_Hebrew_Letter => HLetter, // rule WB7a\n                    RequireHLetter if cat == wd::WC_Hebrew_Letter => HLetter, // rule WB7b\n                    _ => break,                                         // backtrack will happens\n                },\n            }\n        }\n\n        if let FormatExtend(t) = state {\n            // if we required something but didn't find it, backtrack\n            if t == RequireLetter\n                || t == RequireHLetter\n                || t == RequireNumeric\n                || t == AcceptNone\n                || t == AcceptQLetter\n            {\n                previdx = saveidx;\n                take_cat = false;\n                take_curr = false;\n            }\n        }\n\n        self.catb = if take_curr {\n            None\n        } else {\n            idx = previdx;\n            if take_cat {\n                Some(cat)\n            } else {\n                None\n            }\n        };\n\n        let retstr = &self.string[idx..];\n        self.string = &self.string[..idx];\n        Some(retstr)\n    }\n}\n\nimpl<'a> UWordBounds<'a> {\n    #[inline]\n    /// View the underlying data (the part yet to be iterated) as a slice of the original string.\n    ///\n    /// ```rust\n    /// # use unicode_segmentation::UnicodeSegmentation;\n    /// let mut iter = \"Hello world\".split_word_bounds();\n    /// assert_eq!(iter.as_str(), \"Hello world\");\n    /// iter.next();\n    /// assert_eq!(iter.as_str(), \" world\");\n    /// iter.next();\n    /// assert_eq!(iter.as_str(), \"world\");\n    /// ```\n    pub fn as_str(&self) -> &'a str {\n        self.string\n    }\n\n    #[inline]\n    fn get_next_cat(&self, idx: usize) -> Option<WordCat> {\n        use crate::tables::word as wd;\n        let nidx = idx + self.string[idx..].chars().next().unwrap().len_utf8();\n        if nidx < self.string.len() {\n            let nch = self.string[nidx..].chars().next().unwrap();\n            Some(wd::word_category(nch).2)\n        } else {\n            None\n        }\n    }\n\n    #[inline]\n    fn get_prev_cat(&self, idx: usize) -> Option<WordCat> {\n        use crate::tables::word as wd;\n        if idx > 0 {\n            let nch = self.string[..idx].chars().next_back().unwrap();\n            Some(wd::word_category(nch).2)\n        } else {\n            None\n        }\n    }\n}\n\n/// ASCII‑fast‑path word‑boundary iterator for strings that contain only ASCII characters.\n///\n/// Since we handle only ASCII characters, we can use a much simpler set of\n/// word break values than the full Unicode algorithm.\n/// https://www.unicode.org/reports/tr29/#Table_Word_Break_Property_Values\n///\n/// | Word_Break value | ASCII code points that belong to it                             |\n/// | -----------------| --------------------------------------------------------------- |\n/// | CR               | U+000D (CR)                                                     |\n/// | LF               | U+000A (LF)                                                     |\n/// | Newline          | U+000B (VT), U+000C (FF)                                        |\n/// | Single_Quote     | U+0027 (')                                                      |\n/// | Double_Quote     | U+0022 (\")                                                      |\n/// | MidNumLet        | U+002E (.) FULL STOP                                            |\n/// | MidLetter        | U+003A (:) COLON                                                |\n/// | MidNum           | U+002C (,), U+003B (;)                                          |\n/// | Numeric          | U+0030 – U+0039 (0 … 9)                                         |\n/// | ALetter          | U+0041 – U+005A (A … Z), U+0061 – U+007A (a … z)                |\n/// | ExtendNumLet     | U+005F (_) underscore                                           |\n/// | WSegSpace        | U+0020 (SPACE)                                                  |\n///\n/// The macro MidNumLetQ boils down to: U+002E (.) FULL STOP and U+0027 (')\n/// AHLetter is the same as ALetter, so we don't need to distinguish it.\n///\n/// Any other single ASCII byte is its own boundary (the default WB999).\n#[derive(Debug)]\nstruct AsciiWordBoundIter<'a> {\n    rest: &'a str,\n    offset: usize,\n}\n\nimpl<'a> AsciiWordBoundIter<'a> {\n    pub fn new(s: &'a str) -> Self {\n        AsciiWordBoundIter { rest: s, offset: 0 }\n    }\n\n    #[inline]\n    fn is_core(b: u8) -> bool {\n        b.is_ascii_alphanumeric() || b == b'_'\n    }\n\n    #[inline]\n    fn is_infix(b: u8, prev: u8, next: u8) -> bool {\n        match b {\n            // Numeric separators such as \"1,000\" or \"3.14\" (WB11/WB12)\n            //\n            // \"Numeric (MidNum | MidNumLetQ) Numeric\"\n            b'.' | b',' | b';' | b'\\'' if prev.is_ascii_digit() && next.is_ascii_digit() => true,\n\n            // Dot or colon inside an alphabetic word (\"e.g.\", \"http://\") (WB6/WB7)\n            //\n            // \"(MidLetter | MidNumLetQ) AHLetter (MidLetter | MidNumLetQ)\"\n            // MidLetter  = b':'\n            // MidNumLetQ = b'.' | b'\\''\n            b'\\'' | b'.' | b':' if prev.is_ascii_alphabetic() && next.is_ascii_alphabetic() => true,\n            _ => false,\n        }\n    }\n}\n\nimpl<'a> Iterator for AsciiWordBoundIter<'a> {\n    type Item = (usize, &'a str);\n\n    #[inline]\n    fn next(&mut self) -> Option<Self::Item> {\n        if self.rest.is_empty() {\n            return None;\n        }\n\n        let bytes = self.rest.as_bytes();\n        let len = bytes.len();\n\n        // 1) Keep horizontal whitespace together.\n        // Spec: WB3d joins adjacent *WSegSpace* into a single segment.\n        if bytes[0] == b' ' {\n            let mut i = 1;\n            while i < len && bytes[i] == b' ' {\n                i += 1;\n            }\n            let word = &self.rest[..i];\n            let pos = self.offset;\n            self.rest = &self.rest[i..];\n            self.offset += i;\n            return Some((pos, word));\n        }\n\n        // 2) Core-run (letters/digits/underscore + infix)\n        // Spec: ALetter × ALetter, Numeric × Numeric etc. (WB5–WB13b)\n        if Self::is_core(bytes[0]) {\n            let mut i = 1;\n            while i < len {\n                let b = bytes[i];\n                if Self::is_core(b)\n                    || (i + 1 < len && Self::is_infix(b, bytes[i - 1], bytes[i + 1]))\n                {\n                    i += 1;\n                } else {\n                    break;\n                }\n            }\n            let word = &self.rest[..i];\n            let pos = self.offset;\n            self.rest = &self.rest[i..];\n            self.offset += i;\n            return Some((pos, word));\n        }\n\n        // 3) Do not break within CRLF.\n        // Spec: WB3 treats CR+LF as a single non‑breaking pair.\n        if bytes[0] == b'\\r' && len >= 2 && bytes[1] == b'\\n' {\n            let word = &self.rest[..2];\n            let pos = self.offset;\n            self.rest = &self.rest[2..];\n            self.offset += 2;\n            Some((pos, word))\n        } else {\n            // 4) Otherwise, break everywhere\n            // Spec: the catch‑all rule WB999.\n            let word = &self.rest[..1];\n            let pos = self.offset;\n            self.rest = &self.rest[1..];\n            self.offset += 1;\n            Some((pos, word))\n        }\n    }\n}\n\nimpl<'a> DoubleEndedIterator for AsciiWordBoundIter<'a> {\n    fn next_back(&mut self) -> Option<(usize, &'a str)> {\n        let rest = self.rest;\n        if rest.is_empty() {\n            return None;\n        }\n        let bytes = rest.as_bytes();\n        let len = bytes.len();\n\n        // 1) Group runs of spaces\n        // Spec: WB3d joins adjacent *WSegSpace* into a single segment.\n        if bytes[len - 1] == b' ' {\n            // find start of this last run of spaces\n            let mut start = len - 1;\n            while start > 0 && bytes[start - 1] == b' ' {\n                start -= 1;\n            }\n            let word = &rest[start..];\n            let pos = self.offset + start;\n            self.rest = &rest[..start];\n            return Some((pos, word));\n        }\n\n        // 2) Trailing Core-run (letters/digits/underscore + infix)\n        // Spec: ALetter × ALetter, Numeric × Numeric etc. (WB5–WB13b)\n        if Self::is_core(bytes[len - 1]) {\n            // scan backwards as long as we see `is_core` or an `is_infix`\n            let mut start = len - 1;\n            while start > 0 {\n                let b = bytes[start - 1];\n                let prev = if start >= 2 { bytes[start - 2] } else { b };\n                let next = bytes[start]; // the byte we just included\n                if Self::is_core(b) || Self::is_infix(b, prev, next) {\n                    start -= 1;\n                } else {\n                    break;\n                }\n            }\n            let word = &rest[start..];\n            let pos = self.offset + start;\n            self.rest = &rest[..start];\n            return Some((pos, word));\n        }\n\n        // 3) Non-core: CR+LF as one token, otherwise single char\n        // Spec: WB3 treats CR+LF as a single non‑breaking pair.\n        if len >= 2 && bytes[len - 2] == b'\\r' && bytes[len - 1] == b'\\n' {\n            let start = len - 2;\n            let word = &rest[start..];\n            let pos = self.offset + start;\n            self.rest = &rest[..start];\n            return Some((pos, word));\n        }\n\n        // 4) Fallback – every other byte is its own segment\n        // Spec: the catch‑all rule WB999.\n        let start = len - 1;\n        let word = &rest[start..];\n        let pos = self.offset + start;\n        self.rest = &rest[..start];\n        Some((pos, word))\n    }\n}\n\n#[inline]\nfn ascii_word_ok(t: &(usize, &str)) -> bool {\n    has_ascii_alphanumeric(&t.1)\n}\n#[inline]\nfn unicode_word_ok(t: &(usize, &str)) -> bool {\n    has_alphanumeric(&t.1)\n}\n\ntype AsciiWordsIter<'a> = Filter<\n    core::iter::Map<AsciiWordBoundIter<'a>, fn((usize, &'a str)) -> &'a str>,\n    fn(&&'a str) -> bool,\n>;\ntype UnicodeWordsIter<'a> = Filter<UWordBounds<'a>, fn(&&'a str) -> bool>;\ntype AsciiIndicesIter<'a> = Filter<AsciiWordBoundIter<'a>, fn(&(usize, &'a str)) -> bool>;\ntype UnicodeIndicesIter<'a> = Filter<UWordBoundIndices<'a>, fn(&(usize, &'a str)) -> bool>;\n\n#[derive(Debug)]\nenum WordsIter<'a> {\n    Ascii(AsciiWordsIter<'a>),\n    Unicode(UnicodeWordsIter<'a>),\n}\n\n#[derive(Debug)]\nenum IndicesIter<'a> {\n    Ascii(AsciiIndicesIter<'a>),\n    Unicode(UnicodeIndicesIter<'a>),\n}\n\n#[inline]\npub fn new_unicode_words(s: &str) -> UnicodeWords<'_> {\n    let inner = if s.is_ascii() {\n        WordsIter::Ascii(new_unicode_words_ascii(s))\n    } else {\n        WordsIter::Unicode(new_unicode_words_general(s))\n    };\n    UnicodeWords { inner }\n}\n\n#[inline]\npub fn new_unicode_word_indices(s: &str) -> UnicodeWordIndices<'_> {\n    let inner = if s.is_ascii() {\n        IndicesIter::Ascii(new_ascii_word_bound_indices(s).filter(ascii_word_ok))\n    } else {\n        IndicesIter::Unicode(new_word_bound_indices(s).filter(unicode_word_ok))\n    };\n    UnicodeWordIndices { inner }\n}\n\n#[inline]\npub fn new_word_bounds(s: &str) -> UWordBounds<'_> {\n    UWordBounds {\n        string: s,\n        cat: None,\n        catb: None,\n    }\n}\n\n#[inline]\npub fn new_word_bound_indices(s: &str) -> UWordBoundIndices<'_> {\n    UWordBoundIndices {\n        start_offset: s.as_ptr() as usize,\n        iter: new_word_bounds(s),\n    }\n}\n\n#[inline]\nfn new_ascii_word_bound_indices(s: &str) -> AsciiWordBoundIter<'_> {\n    AsciiWordBoundIter::new(s)\n}\n\n#[inline]\nfn has_alphanumeric(s: &&str) -> bool {\n    use crate::tables::util::is_alphanumeric;\n\n    s.chars().any(is_alphanumeric)\n}\n\n#[inline]\nfn has_ascii_alphanumeric(s: &&str) -> bool {\n    s.chars().any(|c| c.is_ascii_alphanumeric())\n}\n\n#[inline(always)]\nfn strip_pos((_, w): (usize, &str)) -> &str {\n    w\n}\n\n#[inline]\nfn new_unicode_words_ascii<'a>(s: &'a str) -> AsciiWordsIter<'a> {\n    new_ascii_word_bound_indices(s)\n        .map(strip_pos as fn(_) -> _)\n        .filter(has_ascii_alphanumeric)\n}\n\n#[inline]\nfn new_unicode_words_general<'a>(s: &'a str) -> UnicodeWordsIter<'a> {\n    new_word_bounds(s).filter(has_alphanumeric)\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::word::{\n        new_ascii_word_bound_indices, new_unicode_words_ascii, new_word_bound_indices,\n    };\n    use std::string::String;\n    use std::vec;\n    use std::vec::Vec;\n\n    use proptest::prelude::*;\n\n    #[test]\n    fn test_syriac_abbr_mark() {\n        use crate::tables::word as wd;\n        let (_, _, cat) = wd::word_category('\\u{70f}');\n        assert_eq!(cat, wd::WC_ALetter);\n    }\n\n    #[test]\n    fn test_end_of_ayah_cat() {\n        use crate::tables::word as wd;\n        let (_, _, cat) = wd::word_category('\\u{6dd}');\n        assert_eq!(cat, wd::WC_Numeric);\n    }\n\n    #[test]\n    fn test_ascii_word_bound_indices_various_cases() {\n        let s = \"Hello, world!\";\n        let words: Vec<(usize, &str)> = new_ascii_word_bound_indices(s).collect();\n        let expected = vec![\n            (0, \"Hello\"), // simple letters\n            (5, \",\"),\n            (6, \" \"),     // space after comma\n            (7, \"world\"), // skip comma+space, stop at '!'\n            (12, \"!\"),    // punctuation at the end\n        ];\n        assert_eq!(words, expected);\n    }\n\n    #[test]\n    fn test_ascii_word_indices_various_cases() {\n        let s = \"Hello, world! can't e.g. var1 123,456 foo_bar example.com 127.0.0.1:9090\";\n        let words: Vec<&str> = new_unicode_words_ascii(s).collect();\n        let expected = vec![\n            (\"Hello\"), // simple letters\n            (\"world\"), // skip comma+space, stop at '!'\n            (\"can't\"), // apostrophe joins letters\n            (\"e.g\"),\n            (\"var1\"),\n            (\"123,456\"), // digits+comma+digits\n            (\"foo_bar\"),\n            (\"example.com\"),\n            (\"127.0.0.1\"),\n            (\"9090\"), // port number\n        ];\n        assert_eq!(words, expected);\n    }\n\n    /// Strategy that yields every code-point from NUL (0) to DEL (127).\n    fn ascii_char() -> impl Strategy<Value = char> {\n        (0u8..=127).prop_map(|b| b as char)\n    }\n\n    proptest! {\n        #![proptest_config(ProptestConfig::with_cases(10000))]\n        /// Fast path must equal general path for any ASCII input.\n        #[test]\n        fn proptest_ascii_matches_unicode_word_indices(\n            // Vec<char> → String, length 0‒99\n            s in proptest::collection::vec(ascii_char(), 0..100)\n                   .prop_map(|v| v.into_iter().collect::<String>())\n        ) {\n            let fast: Vec<(usize, &str)> = new_ascii_word_bound_indices(&s).collect();\n            let uni:  Vec<(usize, &str)> = new_word_bound_indices(&s).collect();\n\n            prop_assert_eq!(fast, uni);\n        }\n\n        /// Fast path must equal general path for any ASCII input, forwards and backwards.\n        #[test]\n        fn proptest_ascii_matches_unicode_word_indices_rev(\n            // Vec<char> → String, length 0‒99\n            s in proptest::collection::vec(ascii_char(), 0..100)\n                   .prop_map(|v| v.into_iter().collect::<String>())\n        ) {\n            let fast_rev: Vec<(usize, &str)> = new_ascii_word_bound_indices(&s).rev().collect();\n            let uni_rev : Vec<(usize, &str)> = new_word_bound_indices(&s).rev().collect();\n            prop_assert_eq!(fast_rev, uni_rev);\n        }\n    }\n}\n"
    },
    {
      "package": "unicode-segmentation@1.13.3",
      "sourcePath": "tests/test.rs",
      "sha256": "5d21ec5b729a0f0554f247c28cf8636e0929468bbcb8c0540ee0cf96b7bdb3ef",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse quickcheck::quickcheck;\nuse unicode_segmentation::UnicodeSegmentation;\n\n#[rustfmt::skip]\nmod testdata;\n\n#[test]\nfn test_graphemes() {\n    use crate::testdata::{TEST_DIFF, TEST_SAME};\n\n    pub const EXTRA_DIFF: &[(&str, &[&str], &[&str])] = &[\n        // Official test suite doesn't include two Prepend chars between two other chars.\n        (\n            \"\\u{20}\\u{600}\\u{600}\\u{20}\",\n            &[\"\\u{20}\", \"\\u{600}\\u{600}\\u{20}\"],\n            &[\"\\u{20}\", \"\\u{600}\", \"\\u{600}\", \"\\u{20}\"],\n        ),\n        // Test for Prepend followed by two Any chars\n        (\n            \"\\u{600}\\u{20}\\u{20}\",\n            &[\"\\u{600}\\u{20}\", \"\\u{20}\"],\n            &[\"\\u{600}\", \"\\u{20}\", \"\\u{20}\"],\n        ),\n    ];\n\n    pub const EXTRA_SAME: &[(&str, &[&str])] = &[\n        // family emoji (more than two emoji joined by ZWJ)\n        (\n            \"\\u{1f468}\\u{200d}\\u{1f467}\\u{200d}\\u{1f466}\",\n            &[\"\\u{1f468}\\u{200d}\\u{1f467}\\u{200d}\\u{1f466}\"],\n        ),\n        // cartwheel emoji followed by two fitzpatrick skin tone modifiers\n        // (test case from issue #19)\n        (\n            \"\\u{1F938}\\u{1F3FE}\\u{1F3FE}\",\n            &[\"\\u{1F938}\\u{1F3FE}\\u{1F3FE}\"],\n        ),\n    ];\n\n    for &(s, g) in TEST_SAME.iter().chain(EXTRA_SAME) {\n        // test forward iterator\n        let our_extended: Vec<_> = UnicodeSegmentation::graphemes(s, true).collect();\n        let our_legacy: Vec<_> = UnicodeSegmentation::graphemes(s, false).collect();\n        assert_eq!(our_extended, g, \"{s:?} extended\");\n        assert_eq!(our_legacy, g, \"{s:?} legacy\");\n\n        // test reverse iterator\n        assert!(UnicodeSegmentation::graphemes(s, true)\n            .rev()\n            .eq(g.iter().rev().cloned()));\n        assert!(UnicodeSegmentation::graphemes(s, false)\n            .rev()\n            .eq(g.iter().rev().cloned()));\n    }\n\n    for &(s, gt, gf) in TEST_DIFF.iter().chain(EXTRA_DIFF) {\n        // test forward iterator\n        assert!(UnicodeSegmentation::graphemes(s, true).eq(gt.iter().cloned()));\n        assert!(UnicodeSegmentation::graphemes(s, false).eq(gf.iter().cloned()));\n\n        // test reverse iterator\n        assert!(UnicodeSegmentation::graphemes(s, true)\n            .rev()\n            .eq(gt.iter().rev().cloned()));\n        assert!(UnicodeSegmentation::graphemes(s, false)\n            .rev()\n            .eq(gf.iter().rev().cloned()));\n    }\n\n    // test the indices iterators\n    let s = \"a̐éö̲\\r\\n\";\n    let gr_inds = UnicodeSegmentation::grapheme_indices(s, true).collect::<Vec<(usize, &str)>>();\n    let b: &[_] = &[(0, \"a̐\"), (3, \"é\"), (6, \"ö̲\"), (11, \"\\r\\n\")];\n    assert_eq!(gr_inds, b);\n    let gr_inds = UnicodeSegmentation::grapheme_indices(s, true)\n        .rev()\n        .collect::<Vec<(usize, &str)>>();\n    let b: &[_] = &[(11, \"\\r\\n\"), (6, \"ö̲\"), (3, \"é\"), (0, \"a̐\")];\n    assert_eq!(gr_inds, b);\n    let mut gr_inds_iter = UnicodeSegmentation::grapheme_indices(s, true);\n    {\n        let gr_inds = gr_inds_iter.by_ref();\n        let e1 = gr_inds.size_hint();\n        assert_eq!(e1, (1, Some(13)));\n        let c = gr_inds.count();\n        assert_eq!(c, 4);\n    }\n    let e2 = gr_inds_iter.size_hint();\n    assert_eq!(e2, (0, Some(0)));\n\n    // make sure the reverse iterator does the right thing with \"\\n\" at beginning of string\n    let s = \"\\n\\r\\n\\r\";\n    let gr = UnicodeSegmentation::graphemes(s, true)\n        .rev()\n        .collect::<Vec<&str>>();\n    let b: &[_] = &[\"\\r\", \"\\r\\n\", \"\\n\"];\n    assert_eq!(gr, b);\n}\n\n#[test]\nfn test_words() {\n    use crate::testdata::TEST_WORD;\n\n    // Unicode's official tests don't really test longer chains of flag emoji\n    // TODO This could be improved with more tests like flag emoji with interspersed Extend chars and ZWJ\n    const EXTRA_TESTS: &[(&str, &[&str])] = &[\n        (\n            \"🇦🇫🇦🇽🇦🇱🇩🇿🇦🇸🇦🇩🇦🇴\",\n            &[\"🇦🇫\", \"🇦🇽\", \"🇦🇱\", \"🇩🇿\", \"🇦🇸\", \"🇦🇩\", \"🇦🇴\"],\n        ),\n        (\"🇦🇫🇦🇽🇦🇱🇩🇿🇦🇸🇦🇩🇦\", &[\"🇦🇫\", \"🇦🇽\", \"🇦🇱\", \"🇩🇿\", \"🇦🇸\", \"🇦🇩\", \"🇦\"]),\n        (\n            \"🇦a🇫🇦🇽a🇦🇱🇩🇿🇦🇸🇦🇩🇦\",\n            &[\"🇦\", \"a\", \"🇫🇦\", \"🇽\", \"a\", \"🇦🇱\", \"🇩🇿\", \"🇦🇸\", \"🇦🇩\", \"🇦\"],\n        ),\n        (\n            \"\\u{1f468}\\u{200d}\\u{1f468}\\u{200d}\\u{1f466}\",\n            &[\"\\u{1f468}\\u{200d}\\u{1f468}\\u{200d}\\u{1f466}\"],\n        ),\n        (\"😌👎🏼\", &[\"😌\", \"👎🏼\"]),\n        // perhaps wrong, spaces should not be included?\n        (\"hello world\", &[\"hello\", \" \", \"world\"]),\n        (\"🇨🇦🇨🇭🇿🇲🇿 hi\", &[\"🇨🇦\", \"🇨🇭\", \"🇿🇲\", \"🇿\", \" \", \"hi\"]),\n    ];\n    for &(s, w) in TEST_WORD.iter().chain(EXTRA_TESTS.iter()) {\n        macro_rules! assert_ {\n            ($test:expr, $exp:expr, $name:expr) => {\n                // collect into vector for better diagnostics in failure case\n                let testing = $test.collect::<Vec<_>>();\n                let expected = $exp.collect::<Vec<_>>();\n                assert_eq!(\n                    testing, expected,\n                    \"{} test for testcase ({:?}, {:?}) failed.\",\n                    $name, s, w\n                )\n            };\n        }\n        // test forward iterator\n        assert_!(\n            s.split_word_bounds(),\n            w.iter().cloned(),\n            \"Forward word boundaries\"\n        );\n\n        // test reverse iterator\n        assert_!(\n            s.split_word_bounds().rev(),\n            w.iter().rev().cloned(),\n            \"Reverse word boundaries\"\n        );\n\n        // generate offsets from word string lengths\n        let mut indices = vec![0];\n        for i in w.iter().cloned().map(|s| s.len()).scan(0, |t, n| {\n            *t += n;\n            Some(*t)\n        }) {\n            indices.push(i);\n        }\n        indices.pop();\n        let indices = indices;\n\n        // test forward indices iterator\n        assert_!(\n            s.split_word_bound_indices().map(|(l, _)| l),\n            indices.iter().cloned(),\n            \"Forward word indices\"\n        );\n\n        // test backward indices iterator\n        assert_!(\n            s.split_word_bound_indices().rev().map(|(l, _)| l),\n            indices.iter().rev().cloned(),\n            \"Reverse word indices\"\n        );\n    }\n}\n\n#[test]\nfn test_sentences() {\n    use crate::testdata::TEST_SENTENCE;\n\n    for &(s, w) in TEST_SENTENCE.iter() {\n        macro_rules! assert_ {\n            ($test:expr, $exp:expr, $name:expr) => {\n                // collect into vector for better diagnostics in failure case\n                let testing = $test.collect::<Vec<_>>();\n                let expected = $exp.collect::<Vec<_>>();\n                assert_eq!(\n                    testing, expected,\n                    \"{} test for testcase ({:?}, {:?}) failed.\",\n                    $name, s, w\n                )\n            };\n        }\n\n        assert_!(\n            s.split_sentence_bounds(),\n            w.iter().cloned(),\n            \"Forward sentence boundaries\"\n        );\n    }\n}\n\nquickcheck! {\n    fn quickcheck_forward_reverse_graphemes_extended(s: String) -> bool {\n        let a = s.graphemes(true).collect::<Vec<_>>();\n        let mut b = s.graphemes(true).rev().collect::<Vec<_>>();\n        b.reverse();\n        a == b\n    }\n\n    fn quickcheck_forward_reverse_graphemes_legacy(s: String) -> bool {\n        let a = s.graphemes(false).collect::<Vec<_>>();\n        let mut b = s.graphemes(false).rev().collect::<Vec<_>>();\n        b.reverse();\n        a == b\n    }\n\n    fn quickcheck_join_graphemes(s: String) -> bool {\n        let a = s.graphemes(true).collect::<String>();\n        let b = s.graphemes(false).collect::<String>();\n        a == s && b == s\n    }\n\n    fn quickcheck_forward_reverse_words(s: String) -> bool {\n        let a = s.split_word_bounds().collect::<Vec<_>>();\n        let mut b = s.split_word_bounds().rev().collect::<Vec<_>>();\n        b.reverse();\n        a == b\n    }\n\n    fn quickcheck_join_words(s: String) -> bool {\n        let a = s.split_word_bounds().collect::<String>();\n        a == s\n    }\n}\n"
    },
    {
      "package": "unicode-segmentation@1.13.3",
      "sourcePath": "tests/testdata/mod.rs",
      "sha256": "52b9609d96660413c21f51e8f9d15667213f628c05b7c228e54585865bd4c373",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\n// NOTE: The following code was generated by \"scripts/unicode.py\", do not edit directly\n\n#![allow(missing_docs, non_upper_case_globals, non_snake_case)]\n    // official Unicode test data\n    // http://www.unicode.org/Public/17.0.0/ucd/auxiliary/GraphemeBreakTest.txt\n    pub const TEST_SAME: &[(&str, &[&str])] = &[\n        (\"\\u{d}\\u{d}\", &[\"\\u{d}\", \"\\u{d}\"]), (\"\\u{d}\\u{308}\\u{d}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{d}\\u{a}\", &[\"\\u{d}\\u{a}\"]), (\"\\u{d}\\u{308}\\u{a}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{d}\\u{0}\", &[\"\\u{d}\", \"\\u{0}\"]), (\"\\u{d}\\u{308}\\u{0}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{d}\\u{94d}\", &[\"\\u{d}\", \"\\u{94d}\"]), (\"\\u{d}\\u{308}\\u{94d}\", &[\"\\u{d}\",\n        \"\\u{308}\\u{94d}\"]), (\"\\u{d}\\u{300}\", &[\"\\u{d}\", \"\\u{300}\"]), (\"\\u{d}\\u{308}\\u{300}\",\n        &[\"\\u{d}\", \"\\u{308}\\u{300}\"]), (\"\\u{d}\\u{200c}\", &[\"\\u{d}\", \"\\u{200c}\"]),\n        (\"\\u{d}\\u{308}\\u{200c}\", &[\"\\u{d}\", \"\\u{308}\\u{200c}\"]), (\"\\u{d}\\u{200d}\", &[\"\\u{d}\",\n        \"\\u{200d}\"]), (\"\\u{d}\\u{308}\\u{200d}\", &[\"\\u{d}\", \"\\u{308}\\u{200d}\"]), (\"\\u{d}\\u{1f1e6}\",\n        &[\"\\u{d}\", \"\\u{1f1e6}\"]), (\"\\u{d}\\u{308}\\u{1f1e6}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{d}\\u{6dd}\", &[\"\\u{d}\", \"\\u{6dd}\"]), (\"\\u{d}\\u{308}\\u{6dd}\", &[\"\\u{d}\", \"\\u{308}\",\n        \"\\u{6dd}\"]), (\"\\u{d}\\u{903}\", &[\"\\u{d}\", \"\\u{903}\"]), (\"\\u{d}\\u{1100}\", &[\"\\u{d}\",\n        \"\\u{1100}\"]), (\"\\u{d}\\u{308}\\u{1100}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{1100}\"]), (\"\\u{d}\\u{1160}\",\n        &[\"\\u{d}\", \"\\u{1160}\"]), (\"\\u{d}\\u{308}\\u{1160}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{1160}\"]),\n        (\"\\u{d}\\u{11a8}\", &[\"\\u{d}\", \"\\u{11a8}\"]), (\"\\u{d}\\u{308}\\u{11a8}\", &[\"\\u{d}\", \"\\u{308}\",\n        \"\\u{11a8}\"]), (\"\\u{d}\\u{ac00}\", &[\"\\u{d}\", \"\\u{ac00}\"]), (\"\\u{d}\\u{308}\\u{ac00}\", &[\"\\u{d}\",\n        \"\\u{308}\", \"\\u{ac00}\"]), (\"\\u{d}\\u{ac01}\", &[\"\\u{d}\", \"\\u{ac01}\"]), (\"\\u{d}\\u{308}\\u{ac01}\",\n        &[\"\\u{d}\", \"\\u{308}\", \"\\u{ac01}\"]), (\"\\u{d}\\u{915}\", &[\"\\u{d}\", \"\\u{915}\"]),\n        (\"\\u{d}\\u{308}\\u{915}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{915}\"]), (\"\\u{d}\\u{a9}\", &[\"\\u{d}\",\n        \"\\u{a9}\"]), (\"\\u{d}\\u{308}\\u{a9}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{a9}\"]), (\"\\u{d}\\u{20}\",\n        &[\"\\u{d}\", \"\\u{20}\"]), (\"\\u{d}\\u{308}\\u{20}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{d}\\u{378}\", &[\"\\u{d}\", \"\\u{378}\"]), (\"\\u{d}\\u{308}\\u{378}\", &[\"\\u{d}\", \"\\u{308}\",\n        \"\\u{378}\"]), (\"\\u{a}\\u{d}\", &[\"\\u{a}\", \"\\u{d}\"]), (\"\\u{a}\\u{308}\\u{d}\", &[\"\\u{a}\",\n        \"\\u{308}\", \"\\u{d}\"]), (\"\\u{a}\\u{a}\", &[\"\\u{a}\", \"\\u{a}\"]), (\"\\u{a}\\u{308}\\u{a}\", &[\"\\u{a}\",\n        \"\\u{308}\", \"\\u{a}\"]), (\"\\u{a}\\u{0}\", &[\"\\u{a}\", \"\\u{0}\"]), (\"\\u{a}\\u{308}\\u{0}\", &[\"\\u{a}\",\n        \"\\u{308}\", \"\\u{0}\"]), (\"\\u{a}\\u{94d}\", &[\"\\u{a}\", \"\\u{94d}\"]), (\"\\u{a}\\u{308}\\u{94d}\",\n        &[\"\\u{a}\", \"\\u{308}\\u{94d}\"]), (\"\\u{a}\\u{300}\", &[\"\\u{a}\", \"\\u{300}\"]),\n        (\"\\u{a}\\u{308}\\u{300}\", &[\"\\u{a}\", \"\\u{308}\\u{300}\"]), (\"\\u{a}\\u{200c}\", &[\"\\u{a}\",\n        \"\\u{200c}\"]), (\"\\u{a}\\u{308}\\u{200c}\", &[\"\\u{a}\", \"\\u{308}\\u{200c}\"]), (\"\\u{a}\\u{200d}\",\n        &[\"\\u{a}\", \"\\u{200d}\"]), (\"\\u{a}\\u{308}\\u{200d}\", &[\"\\u{a}\", \"\\u{308}\\u{200d}\"]),\n        (\"\\u{a}\\u{1f1e6}\", &[\"\\u{a}\", \"\\u{1f1e6}\"]), (\"\\u{a}\\u{308}\\u{1f1e6}\", &[\"\\u{a}\", \"\\u{308}\",\n        \"\\u{1f1e6}\"]), (\"\\u{a}\\u{6dd}\", &[\"\\u{a}\", \"\\u{6dd}\"]), (\"\\u{a}\\u{308}\\u{6dd}\", &[\"\\u{a}\",\n        \"\\u{308}\", \"\\u{6dd}\"]), (\"\\u{a}\\u{903}\", &[\"\\u{a}\", \"\\u{903}\"]), (\"\\u{a}\\u{1100}\",\n        &[\"\\u{a}\", \"\\u{1100}\"]), (\"\\u{a}\\u{308}\\u{1100}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{1100}\"]),\n        (\"\\u{a}\\u{1160}\", &[\"\\u{a}\", \"\\u{1160}\"]), (\"\\u{a}\\u{308}\\u{1160}\", &[\"\\u{a}\", \"\\u{308}\",\n        \"\\u{1160}\"]), (\"\\u{a}\\u{11a8}\", &[\"\\u{a}\", \"\\u{11a8}\"]), (\"\\u{a}\\u{308}\\u{11a8}\", &[\"\\u{a}\",\n        \"\\u{308}\", \"\\u{11a8}\"]), (\"\\u{a}\\u{ac00}\", &[\"\\u{a}\", \"\\u{ac00}\"]), (\"\\u{a}\\u{308}\\u{ac00}\",\n        &[\"\\u{a}\", \"\\u{308}\", \"\\u{ac00}\"]), (\"\\u{a}\\u{ac01}\", &[\"\\u{a}\", \"\\u{ac01}\"]),\n        (\"\\u{a}\\u{308}\\u{ac01}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{ac01}\"]), (\"\\u{a}\\u{915}\", &[\"\\u{a}\",\n        \"\\u{915}\"]), (\"\\u{a}\\u{308}\\u{915}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{915}\"]), (\"\\u{a}\\u{a9}\",\n        &[\"\\u{a}\", \"\\u{a9}\"]), (\"\\u{a}\\u{308}\\u{a9}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{a}\\u{20}\", &[\"\\u{a}\", \"\\u{20}\"]), (\"\\u{a}\\u{308}\\u{20}\", &[\"\\u{a}\", \"\\u{308}\",\n        \"\\u{20}\"]), (\"\\u{a}\\u{378}\", &[\"\\u{a}\", \"\\u{378}\"]), (\"\\u{a}\\u{308}\\u{378}\", &[\"\\u{a}\",\n        \"\\u{308}\", \"\\u{378}\"]), (\"\\u{0}\\u{d}\", &[\"\\u{0}\", \"\\u{d}\"]), (\"\\u{0}\\u{308}\\u{d}\",\n        &[\"\\u{0}\", \"\\u{308}\", \"\\u{d}\"]), (\"\\u{0}\\u{a}\", &[\"\\u{0}\", \"\\u{a}\"]), (\"\\u{0}\\u{308}\\u{a}\",\n        &[\"\\u{0}\", \"\\u{308}\", \"\\u{a}\"]), (\"\\u{0}\\u{0}\", &[\"\\u{0}\", \"\\u{0}\"]), (\"\\u{0}\\u{308}\\u{0}\",\n        &[\"\\u{0}\", \"\\u{308}\", \"\\u{0}\"]), (\"\\u{0}\\u{94d}\", &[\"\\u{0}\", \"\\u{94d}\"]),\n        (\"\\u{0}\\u{308}\\u{94d}\", &[\"\\u{0}\", \"\\u{308}\\u{94d}\"]), (\"\\u{0}\\u{300}\", &[\"\\u{0}\",\n        \"\\u{300}\"]), (\"\\u{0}\\u{308}\\u{300}\", &[\"\\u{0}\", \"\\u{308}\\u{300}\"]), (\"\\u{0}\\u{200c}\",\n        &[\"\\u{0}\", \"\\u{200c}\"]), (\"\\u{0}\\u{308}\\u{200c}\", &[\"\\u{0}\", \"\\u{308}\\u{200c}\"]),\n        (\"\\u{0}\\u{200d}\", &[\"\\u{0}\", \"\\u{200d}\"]), (\"\\u{0}\\u{308}\\u{200d}\", &[\"\\u{0}\",\n        \"\\u{308}\\u{200d}\"]), (\"\\u{0}\\u{1f1e6}\", &[\"\\u{0}\", \"\\u{1f1e6}\"]), (\"\\u{0}\\u{308}\\u{1f1e6}\",\n        &[\"\\u{0}\", \"\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{0}\\u{6dd}\", &[\"\\u{0}\", \"\\u{6dd}\"]),\n        (\"\\u{0}\\u{308}\\u{6dd}\", &[\"\\u{0}\", \"\\u{308}\", \"\\u{6dd}\"]), (\"\\u{0}\\u{903}\", &[\"\\u{0}\",\n        \"\\u{903}\"]), (\"\\u{0}\\u{1100}\", &[\"\\u{0}\", \"\\u{1100}\"]), (\"\\u{0}\\u{308}\\u{1100}\", &[\"\\u{0}\",\n        \"\\u{308}\", \"\\u{1100}\"]), (\"\\u{0}\\u{1160}\", &[\"\\u{0}\", \"\\u{1160}\"]), (\"\\u{0}\\u{308}\\u{1160}\",\n        &[\"\\u{0}\", \"\\u{308}\", \"\\u{1160}\"]), (\"\\u{0}\\u{11a8}\", &[\"\\u{0}\", \"\\u{11a8}\"]),\n        (\"\\u{0}\\u{308}\\u{11a8}\", &[\"\\u{0}\", \"\\u{308}\", \"\\u{11a8}\"]), (\"\\u{0}\\u{ac00}\", &[\"\\u{0}\",\n        \"\\u{ac00}\"]), (\"\\u{0}\\u{308}\\u{ac00}\", &[\"\\u{0}\", \"\\u{308}\", \"\\u{ac00}\"]), (\"\\u{0}\\u{ac01}\",\n        &[\"\\u{0}\", \"\\u{ac01}\"]), (\"\\u{0}\\u{308}\\u{ac01}\", &[\"\\u{0}\", \"\\u{308}\", \"\\u{ac01}\"]),\n        (\"\\u{0}\\u{915}\", &[\"\\u{0}\", \"\\u{915}\"]), (\"\\u{0}\\u{308}\\u{915}\", &[\"\\u{0}\", \"\\u{308}\",\n        \"\\u{915}\"]), (\"\\u{0}\\u{a9}\", &[\"\\u{0}\", \"\\u{a9}\"]), (\"\\u{0}\\u{308}\\u{a9}\", &[\"\\u{0}\",\n        \"\\u{308}\", \"\\u{a9}\"]), (\"\\u{0}\\u{20}\", &[\"\\u{0}\", \"\\u{20}\"]), (\"\\u{0}\\u{308}\\u{20}\",\n        &[\"\\u{0}\", \"\\u{308}\", \"\\u{20}\"]), (\"\\u{0}\\u{378}\", &[\"\\u{0}\", \"\\u{378}\"]),\n        (\"\\u{0}\\u{308}\\u{378}\", &[\"\\u{0}\", \"\\u{308}\", \"\\u{378}\"]), (\"\\u{94d}\\u{d}\", &[\"\\u{94d}\",\n        \"\\u{d}\"]), (\"\\u{94d}\\u{308}\\u{d}\", &[\"\\u{94d}\\u{308}\", \"\\u{d}\"]), (\"\\u{94d}\\u{a}\",\n        &[\"\\u{94d}\", \"\\u{a}\"]), (\"\\u{94d}\\u{308}\\u{a}\", &[\"\\u{94d}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{94d}\\u{0}\", &[\"\\u{94d}\", \"\\u{0}\"]), (\"\\u{94d}\\u{308}\\u{0}\", &[\"\\u{94d}\\u{308}\",\n        \"\\u{0}\"]), (\"\\u{94d}\\u{94d}\", &[\"\\u{94d}\\u{94d}\"]), (\"\\u{94d}\\u{308}\\u{94d}\",\n        &[\"\\u{94d}\\u{308}\\u{94d}\"]), (\"\\u{94d}\\u{300}\", &[\"\\u{94d}\\u{300}\"]),\n        (\"\\u{94d}\\u{308}\\u{300}\", &[\"\\u{94d}\\u{308}\\u{300}\"]), (\"\\u{94d}\\u{200c}\",\n        &[\"\\u{94d}\\u{200c}\"]), (\"\\u{94d}\\u{308}\\u{200c}\", &[\"\\u{94d}\\u{308}\\u{200c}\"]),\n        (\"\\u{94d}\\u{200d}\", &[\"\\u{94d}\\u{200d}\"]), (\"\\u{94d}\\u{308}\\u{200d}\",\n        &[\"\\u{94d}\\u{308}\\u{200d}\"]), (\"\\u{94d}\\u{1f1e6}\", &[\"\\u{94d}\", \"\\u{1f1e6}\"]),\n        (\"\\u{94d}\\u{308}\\u{1f1e6}\", &[\"\\u{94d}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{94d}\\u{6dd}\",\n        &[\"\\u{94d}\", \"\\u{6dd}\"]), (\"\\u{94d}\\u{308}\\u{6dd}\", &[\"\\u{94d}\\u{308}\", \"\\u{6dd}\"]),\n        (\"\\u{94d}\\u{1100}\", &[\"\\u{94d}\", \"\\u{1100}\"]), (\"\\u{94d}\\u{308}\\u{1100}\",\n        &[\"\\u{94d}\\u{308}\", \"\\u{1100}\"]), (\"\\u{94d}\\u{1160}\", &[\"\\u{94d}\", \"\\u{1160}\"]),\n        (\"\\u{94d}\\u{308}\\u{1160}\", &[\"\\u{94d}\\u{308}\", \"\\u{1160}\"]), (\"\\u{94d}\\u{11a8}\",\n        &[\"\\u{94d}\", \"\\u{11a8}\"]), (\"\\u{94d}\\u{308}\\u{11a8}\", &[\"\\u{94d}\\u{308}\", \"\\u{11a8}\"]),\n        (\"\\u{94d}\\u{ac00}\", &[\"\\u{94d}\", \"\\u{ac00}\"]), (\"\\u{94d}\\u{308}\\u{ac00}\",\n        &[\"\\u{94d}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{94d}\\u{ac01}\", &[\"\\u{94d}\", \"\\u{ac01}\"]),\n        (\"\\u{94d}\\u{308}\\u{ac01}\", &[\"\\u{94d}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{94d}\\u{915}\", &[\"\\u{94d}\",\n        \"\\u{915}\"]), (\"\\u{94d}\\u{308}\\u{915}\", &[\"\\u{94d}\\u{308}\", \"\\u{915}\"]), (\"\\u{94d}\\u{a9}\",\n        &[\"\\u{94d}\", \"\\u{a9}\"]), (\"\\u{94d}\\u{308}\\u{a9}\", &[\"\\u{94d}\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{94d}\\u{20}\", &[\"\\u{94d}\", \"\\u{20}\"]), (\"\\u{94d}\\u{308}\\u{20}\", &[\"\\u{94d}\\u{308}\",\n        \"\\u{20}\"]), (\"\\u{94d}\\u{378}\", &[\"\\u{94d}\", \"\\u{378}\"]), (\"\\u{94d}\\u{308}\\u{378}\",\n        &[\"\\u{94d}\\u{308}\", \"\\u{378}\"]), (\"\\u{300}\\u{d}\", &[\"\\u{300}\", \"\\u{d}\"]),\n        (\"\\u{300}\\u{308}\\u{d}\", &[\"\\u{300}\\u{308}\", \"\\u{d}\"]), (\"\\u{300}\\u{a}\", &[\"\\u{300}\",\n        \"\\u{a}\"]), (\"\\u{300}\\u{308}\\u{a}\", &[\"\\u{300}\\u{308}\", \"\\u{a}\"]), (\"\\u{300}\\u{0}\",\n        &[\"\\u{300}\", \"\\u{0}\"]), (\"\\u{300}\\u{308}\\u{0}\", &[\"\\u{300}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{300}\\u{94d}\", &[\"\\u{300}\\u{94d}\"]), (\"\\u{300}\\u{308}\\u{94d}\",\n        &[\"\\u{300}\\u{308}\\u{94d}\"]), (\"\\u{300}\\u{300}\", &[\"\\u{300}\\u{300}\"]),\n        (\"\\u{300}\\u{308}\\u{300}\", &[\"\\u{300}\\u{308}\\u{300}\"]), (\"\\u{300}\\u{200c}\",\n        &[\"\\u{300}\\u{200c}\"]), (\"\\u{300}\\u{308}\\u{200c}\", &[\"\\u{300}\\u{308}\\u{200c}\"]),\n        (\"\\u{300}\\u{200d}\", &[\"\\u{300}\\u{200d}\"]), (\"\\u{300}\\u{308}\\u{200d}\",\n        &[\"\\u{300}\\u{308}\\u{200d}\"]), (\"\\u{300}\\u{1f1e6}\", &[\"\\u{300}\", \"\\u{1f1e6}\"]),\n        (\"\\u{300}\\u{308}\\u{1f1e6}\", &[\"\\u{300}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{300}\\u{6dd}\",\n        &[\"\\u{300}\", \"\\u{6dd}\"]), (\"\\u{300}\\u{308}\\u{6dd}\", &[\"\\u{300}\\u{308}\", \"\\u{6dd}\"]),\n        (\"\\u{300}\\u{1100}\", &[\"\\u{300}\", \"\\u{1100}\"]), (\"\\u{300}\\u{308}\\u{1100}\",\n        &[\"\\u{300}\\u{308}\", \"\\u{1100}\"]), (\"\\u{300}\\u{1160}\", &[\"\\u{300}\", \"\\u{1160}\"]),\n        (\"\\u{300}\\u{308}\\u{1160}\", &[\"\\u{300}\\u{308}\", \"\\u{1160}\"]), (\"\\u{300}\\u{11a8}\",\n        &[\"\\u{300}\", \"\\u{11a8}\"]), (\"\\u{300}\\u{308}\\u{11a8}\", &[\"\\u{300}\\u{308}\", \"\\u{11a8}\"]),\n        (\"\\u{300}\\u{ac00}\", &[\"\\u{300}\", \"\\u{ac00}\"]), (\"\\u{300}\\u{308}\\u{ac00}\",\n        &[\"\\u{300}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{300}\\u{ac01}\", &[\"\\u{300}\", \"\\u{ac01}\"]),\n        (\"\\u{300}\\u{308}\\u{ac01}\", &[\"\\u{300}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{300}\\u{915}\", &[\"\\u{300}\",\n        \"\\u{915}\"]), (\"\\u{300}\\u{308}\\u{915}\", &[\"\\u{300}\\u{308}\", \"\\u{915}\"]), (\"\\u{300}\\u{a9}\",\n        &[\"\\u{300}\", \"\\u{a9}\"]), (\"\\u{300}\\u{308}\\u{a9}\", &[\"\\u{300}\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{300}\\u{20}\", &[\"\\u{300}\", \"\\u{20}\"]), (\"\\u{300}\\u{308}\\u{20}\", &[\"\\u{300}\\u{308}\",\n        \"\\u{20}\"]), (\"\\u{300}\\u{378}\", &[\"\\u{300}\", \"\\u{378}\"]), (\"\\u{300}\\u{308}\\u{378}\",\n        &[\"\\u{300}\\u{308}\", \"\\u{378}\"]), (\"\\u{200c}\\u{d}\", &[\"\\u{200c}\", \"\\u{d}\"]),\n        (\"\\u{200c}\\u{308}\\u{d}\", &[\"\\u{200c}\\u{308}\", \"\\u{d}\"]), (\"\\u{200c}\\u{a}\", &[\"\\u{200c}\",\n        \"\\u{a}\"]), (\"\\u{200c}\\u{308}\\u{a}\", &[\"\\u{200c}\\u{308}\", \"\\u{a}\"]), (\"\\u{200c}\\u{0}\",\n        &[\"\\u{200c}\", \"\\u{0}\"]), (\"\\u{200c}\\u{308}\\u{0}\", &[\"\\u{200c}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{200c}\\u{94d}\", &[\"\\u{200c}\\u{94d}\"]), (\"\\u{200c}\\u{308}\\u{94d}\",\n        &[\"\\u{200c}\\u{308}\\u{94d}\"]), (\"\\u{200c}\\u{300}\", &[\"\\u{200c}\\u{300}\"]),\n        (\"\\u{200c}\\u{308}\\u{300}\", &[\"\\u{200c}\\u{308}\\u{300}\"]), (\"\\u{200c}\\u{200c}\",\n        &[\"\\u{200c}\\u{200c}\"]), (\"\\u{200c}\\u{308}\\u{200c}\", &[\"\\u{200c}\\u{308}\\u{200c}\"]),\n        (\"\\u{200c}\\u{200d}\", &[\"\\u{200c}\\u{200d}\"]), (\"\\u{200c}\\u{308}\\u{200d}\",\n        &[\"\\u{200c}\\u{308}\\u{200d}\"]), (\"\\u{200c}\\u{1f1e6}\", &[\"\\u{200c}\", \"\\u{1f1e6}\"]),\n        (\"\\u{200c}\\u{308}\\u{1f1e6}\", &[\"\\u{200c}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{200c}\\u{6dd}\",\n        &[\"\\u{200c}\", \"\\u{6dd}\"]), (\"\\u{200c}\\u{308}\\u{6dd}\", &[\"\\u{200c}\\u{308}\", \"\\u{6dd}\"]),\n        (\"\\u{200c}\\u{1100}\", &[\"\\u{200c}\", \"\\u{1100}\"]), (\"\\u{200c}\\u{308}\\u{1100}\",\n        &[\"\\u{200c}\\u{308}\", \"\\u{1100}\"]), (\"\\u{200c}\\u{1160}\", &[\"\\u{200c}\", \"\\u{1160}\"]),\n        (\"\\u{200c}\\u{308}\\u{1160}\", &[\"\\u{200c}\\u{308}\", \"\\u{1160}\"]), (\"\\u{200c}\\u{11a8}\",\n        &[\"\\u{200c}\", \"\\u{11a8}\"]), (\"\\u{200c}\\u{308}\\u{11a8}\", &[\"\\u{200c}\\u{308}\", \"\\u{11a8}\"]),\n        (\"\\u{200c}\\u{ac00}\", &[\"\\u{200c}\", \"\\u{ac00}\"]), (\"\\u{200c}\\u{308}\\u{ac00}\",\n        &[\"\\u{200c}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{200c}\\u{ac01}\", &[\"\\u{200c}\", \"\\u{ac01}\"]),\n        (\"\\u{200c}\\u{308}\\u{ac01}\", &[\"\\u{200c}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{200c}\\u{915}\",\n        &[\"\\u{200c}\", \"\\u{915}\"]), (\"\\u{200c}\\u{308}\\u{915}\", &[\"\\u{200c}\\u{308}\", \"\\u{915}\"]),\n        (\"\\u{200c}\\u{a9}\", &[\"\\u{200c}\", \"\\u{a9}\"]), (\"\\u{200c}\\u{308}\\u{a9}\", &[\"\\u{200c}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{200c}\\u{20}\", &[\"\\u{200c}\", \"\\u{20}\"]), (\"\\u{200c}\\u{308}\\u{20}\",\n        &[\"\\u{200c}\\u{308}\", \"\\u{20}\"]), (\"\\u{200c}\\u{378}\", &[\"\\u{200c}\", \"\\u{378}\"]),\n        (\"\\u{200c}\\u{308}\\u{378}\", &[\"\\u{200c}\\u{308}\", \"\\u{378}\"]), (\"\\u{200d}\\u{d}\", &[\"\\u{200d}\",\n        \"\\u{d}\"]), (\"\\u{200d}\\u{308}\\u{d}\", &[\"\\u{200d}\\u{308}\", \"\\u{d}\"]), (\"\\u{200d}\\u{a}\",\n        &[\"\\u{200d}\", \"\\u{a}\"]), (\"\\u{200d}\\u{308}\\u{a}\", &[\"\\u{200d}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{200d}\\u{0}\", &[\"\\u{200d}\", \"\\u{0}\"]), (\"\\u{200d}\\u{308}\\u{0}\", &[\"\\u{200d}\\u{308}\",\n        \"\\u{0}\"]), (\"\\u{200d}\\u{94d}\", &[\"\\u{200d}\\u{94d}\"]), (\"\\u{200d}\\u{308}\\u{94d}\",\n        &[\"\\u{200d}\\u{308}\\u{94d}\"]), (\"\\u{200d}\\u{300}\", &[\"\\u{200d}\\u{300}\"]),\n        (\"\\u{200d}\\u{308}\\u{300}\", &[\"\\u{200d}\\u{308}\\u{300}\"]), (\"\\u{200d}\\u{200c}\",\n        &[\"\\u{200d}\\u{200c}\"]), (\"\\u{200d}\\u{308}\\u{200c}\", &[\"\\u{200d}\\u{308}\\u{200c}\"]),\n        (\"\\u{200d}\\u{200d}\", &[\"\\u{200d}\\u{200d}\"]), (\"\\u{200d}\\u{308}\\u{200d}\",\n        &[\"\\u{200d}\\u{308}\\u{200d}\"]), (\"\\u{200d}\\u{1f1e6}\", &[\"\\u{200d}\", \"\\u{1f1e6}\"]),\n        (\"\\u{200d}\\u{308}\\u{1f1e6}\", &[\"\\u{200d}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{200d}\\u{6dd}\",\n        &[\"\\u{200d}\", \"\\u{6dd}\"]), (\"\\u{200d}\\u{308}\\u{6dd}\", &[\"\\u{200d}\\u{308}\", \"\\u{6dd}\"]),\n        (\"\\u{200d}\\u{1100}\", &[\"\\u{200d}\", \"\\u{1100}\"]), (\"\\u{200d}\\u{308}\\u{1100}\",\n        &[\"\\u{200d}\\u{308}\", \"\\u{1100}\"]), (\"\\u{200d}\\u{1160}\", &[\"\\u{200d}\", \"\\u{1160}\"]),\n        (\"\\u{200d}\\u{308}\\u{1160}\", &[\"\\u{200d}\\u{308}\", \"\\u{1160}\"]), (\"\\u{200d}\\u{11a8}\",\n        &[\"\\u{200d}\", \"\\u{11a8}\"]), (\"\\u{200d}\\u{308}\\u{11a8}\", &[\"\\u{200d}\\u{308}\", \"\\u{11a8}\"]),\n        (\"\\u{200d}\\u{ac00}\", &[\"\\u{200d}\", \"\\u{ac00}\"]), (\"\\u{200d}\\u{308}\\u{ac00}\",\n        &[\"\\u{200d}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{200d}\\u{ac01}\", &[\"\\u{200d}\", \"\\u{ac01}\"]),\n        (\"\\u{200d}\\u{308}\\u{ac01}\", &[\"\\u{200d}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{200d}\\u{915}\",\n        &[\"\\u{200d}\", \"\\u{915}\"]), (\"\\u{200d}\\u{308}\\u{915}\", &[\"\\u{200d}\\u{308}\", \"\\u{915}\"]),\n        (\"\\u{200d}\\u{a9}\", &[\"\\u{200d}\", \"\\u{a9}\"]), (\"\\u{200d}\\u{308}\\u{a9}\", &[\"\\u{200d}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{200d}\\u{20}\", &[\"\\u{200d}\", \"\\u{20}\"]), (\"\\u{200d}\\u{308}\\u{20}\",\n        &[\"\\u{200d}\\u{308}\", \"\\u{20}\"]), (\"\\u{200d}\\u{378}\", &[\"\\u{200d}\", \"\\u{378}\"]),\n        (\"\\u{200d}\\u{308}\\u{378}\", &[\"\\u{200d}\\u{308}\", \"\\u{378}\"]), (\"\\u{1f1e6}\\u{d}\",\n        &[\"\\u{1f1e6}\", \"\\u{d}\"]), (\"\\u{1f1e6}\\u{308}\\u{d}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{1f1e6}\\u{a}\", &[\"\\u{1f1e6}\", \"\\u{a}\"]), (\"\\u{1f1e6}\\u{308}\\u{a}\", &[\"\\u{1f1e6}\\u{308}\",\n        \"\\u{a}\"]), (\"\\u{1f1e6}\\u{0}\", &[\"\\u{1f1e6}\", \"\\u{0}\"]), (\"\\u{1f1e6}\\u{308}\\u{0}\",\n        &[\"\\u{1f1e6}\\u{308}\", \"\\u{0}\"]), (\"\\u{1f1e6}\\u{94d}\", &[\"\\u{1f1e6}\\u{94d}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{94d}\", &[\"\\u{1f1e6}\\u{308}\\u{94d}\"]), (\"\\u{1f1e6}\\u{300}\",\n        &[\"\\u{1f1e6}\\u{300}\"]), (\"\\u{1f1e6}\\u{308}\\u{300}\", &[\"\\u{1f1e6}\\u{308}\\u{300}\"]),\n        (\"\\u{1f1e6}\\u{200c}\", &[\"\\u{1f1e6}\\u{200c}\"]), (\"\\u{1f1e6}\\u{308}\\u{200c}\",\n        &[\"\\u{1f1e6}\\u{308}\\u{200c}\"]), (\"\\u{1f1e6}\\u{200d}\", &[\"\\u{1f1e6}\\u{200d}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{200d}\", &[\"\\u{1f1e6}\\u{308}\\u{200d}\"]), (\"\\u{1f1e6}\\u{1f1e6}\",\n        &[\"\\u{1f1e6}\\u{1f1e6}\"]), (\"\\u{1f1e6}\\u{308}\\u{1f1e6}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{1f1e6}\\u{6dd}\", &[\"\\u{1f1e6}\", \"\\u{6dd}\"]), (\"\\u{1f1e6}\\u{308}\\u{6dd}\",\n        &[\"\\u{1f1e6}\\u{308}\", \"\\u{6dd}\"]), (\"\\u{1f1e6}\\u{1100}\", &[\"\\u{1f1e6}\", \"\\u{1100}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{1100}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{1100}\"]), (\"\\u{1f1e6}\\u{1160}\",\n        &[\"\\u{1f1e6}\", \"\\u{1160}\"]), (\"\\u{1f1e6}\\u{308}\\u{1160}\", &[\"\\u{1f1e6}\\u{308}\",\n        \"\\u{1160}\"]), (\"\\u{1f1e6}\\u{11a8}\", &[\"\\u{1f1e6}\", \"\\u{11a8}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{11a8}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{11a8}\"]), (\"\\u{1f1e6}\\u{ac00}\",\n        &[\"\\u{1f1e6}\", \"\\u{ac00}\"]), (\"\\u{1f1e6}\\u{308}\\u{ac00}\", &[\"\\u{1f1e6}\\u{308}\",\n        \"\\u{ac00}\"]), (\"\\u{1f1e6}\\u{ac01}\", &[\"\\u{1f1e6}\", \"\\u{ac01}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{ac01}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{1f1e6}\\u{915}\",\n        &[\"\\u{1f1e6}\", \"\\u{915}\"]), (\"\\u{1f1e6}\\u{308}\\u{915}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{915}\"]),\n        (\"\\u{1f1e6}\\u{a9}\", &[\"\\u{1f1e6}\", \"\\u{a9}\"]), (\"\\u{1f1e6}\\u{308}\\u{a9}\",\n        &[\"\\u{1f1e6}\\u{308}\", \"\\u{a9}\"]), (\"\\u{1f1e6}\\u{20}\", &[\"\\u{1f1e6}\", \"\\u{20}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{20}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{20}\"]), (\"\\u{1f1e6}\\u{378}\",\n        &[\"\\u{1f1e6}\", \"\\u{378}\"]), (\"\\u{1f1e6}\\u{308}\\u{378}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{378}\"]),\n        (\"\\u{6dd}\\u{d}\", &[\"\\u{6dd}\", \"\\u{d}\"]), (\"\\u{6dd}\\u{308}\\u{d}\", &[\"\\u{6dd}\\u{308}\",\n        \"\\u{d}\"]), (\"\\u{6dd}\\u{a}\", &[\"\\u{6dd}\", \"\\u{a}\"]), (\"\\u{6dd}\\u{308}\\u{a}\",\n        &[\"\\u{6dd}\\u{308}\", \"\\u{a}\"]), (\"\\u{6dd}\\u{0}\", &[\"\\u{6dd}\", \"\\u{0}\"]),\n        (\"\\u{6dd}\\u{308}\\u{0}\", &[\"\\u{6dd}\\u{308}\", \"\\u{0}\"]), (\"\\u{6dd}\\u{94d}\",\n        &[\"\\u{6dd}\\u{94d}\"]), (\"\\u{6dd}\\u{308}\\u{94d}\", &[\"\\u{6dd}\\u{308}\\u{94d}\"]),\n        (\"\\u{6dd}\\u{300}\", &[\"\\u{6dd}\\u{300}\"]), (\"\\u{6dd}\\u{308}\\u{300}\",\n        &[\"\\u{6dd}\\u{308}\\u{300}\"]), (\"\\u{6dd}\\u{200c}\", &[\"\\u{6dd}\\u{200c}\"]),\n        (\"\\u{6dd}\\u{308}\\u{200c}\", &[\"\\u{6dd}\\u{308}\\u{200c}\"]), (\"\\u{6dd}\\u{200d}\",\n        &[\"\\u{6dd}\\u{200d}\"]), (\"\\u{6dd}\\u{308}\\u{200d}\", &[\"\\u{6dd}\\u{308}\\u{200d}\"]),\n        (\"\\u{6dd}\\u{308}\\u{1f1e6}\", &[\"\\u{6dd}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{6dd}\\u{308}\\u{6dd}\",\n        &[\"\\u{6dd}\\u{308}\", \"\\u{6dd}\"]), (\"\\u{6dd}\\u{308}\\u{1100}\", &[\"\\u{6dd}\\u{308}\",\n        \"\\u{1100}\"]), (\"\\u{6dd}\\u{308}\\u{1160}\", &[\"\\u{6dd}\\u{308}\", \"\\u{1160}\"]),\n        (\"\\u{6dd}\\u{308}\\u{11a8}\", &[\"\\u{6dd}\\u{308}\", \"\\u{11a8}\"]), (\"\\u{6dd}\\u{308}\\u{ac00}\",\n        &[\"\\u{6dd}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{6dd}\\u{308}\\u{ac01}\", &[\"\\u{6dd}\\u{308}\",\n        \"\\u{ac01}\"]), (\"\\u{6dd}\\u{308}\\u{915}\", &[\"\\u{6dd}\\u{308}\", \"\\u{915}\"]),\n        (\"\\u{6dd}\\u{308}\\u{a9}\", &[\"\\u{6dd}\\u{308}\", \"\\u{a9}\"]), (\"\\u{6dd}\\u{308}\\u{20}\",\n        &[\"\\u{6dd}\\u{308}\", \"\\u{20}\"]), (\"\\u{6dd}\\u{308}\\u{378}\", &[\"\\u{6dd}\\u{308}\", \"\\u{378}\"]),\n        (\"\\u{903}\\u{d}\", &[\"\\u{903}\", \"\\u{d}\"]), (\"\\u{903}\\u{308}\\u{d}\", &[\"\\u{903}\\u{308}\",\n        \"\\u{d}\"]), (\"\\u{903}\\u{a}\", &[\"\\u{903}\", \"\\u{a}\"]), (\"\\u{903}\\u{308}\\u{a}\",\n        &[\"\\u{903}\\u{308}\", \"\\u{a}\"]), (\"\\u{903}\\u{0}\", &[\"\\u{903}\", \"\\u{0}\"]),\n        (\"\\u{903}\\u{308}\\u{0}\", &[\"\\u{903}\\u{308}\", \"\\u{0}\"]), (\"\\u{903}\\u{94d}\",\n        &[\"\\u{903}\\u{94d}\"]), (\"\\u{903}\\u{308}\\u{94d}\", &[\"\\u{903}\\u{308}\\u{94d}\"]),\n        (\"\\u{903}\\u{300}\", &[\"\\u{903}\\u{300}\"]), (\"\\u{903}\\u{308}\\u{300}\",\n        &[\"\\u{903}\\u{308}\\u{300}\"]), (\"\\u{903}\\u{200c}\", &[\"\\u{903}\\u{200c}\"]),\n        (\"\\u{903}\\u{308}\\u{200c}\", &[\"\\u{903}\\u{308}\\u{200c}\"]), (\"\\u{903}\\u{200d}\",\n        &[\"\\u{903}\\u{200d}\"]), (\"\\u{903}\\u{308}\\u{200d}\", &[\"\\u{903}\\u{308}\\u{200d}\"]),\n        (\"\\u{903}\\u{1f1e6}\", &[\"\\u{903}\", \"\\u{1f1e6}\"]), (\"\\u{903}\\u{308}\\u{1f1e6}\",\n        &[\"\\u{903}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{903}\\u{6dd}\", &[\"\\u{903}\", \"\\u{6dd}\"]),\n        (\"\\u{903}\\u{308}\\u{6dd}\", &[\"\\u{903}\\u{308}\", \"\\u{6dd}\"]), (\"\\u{903}\\u{1100}\", &[\"\\u{903}\",\n        \"\\u{1100}\"]), (\"\\u{903}\\u{308}\\u{1100}\", &[\"\\u{903}\\u{308}\", \"\\u{1100}\"]),\n        (\"\\u{903}\\u{1160}\", &[\"\\u{903}\", \"\\u{1160}\"]), (\"\\u{903}\\u{308}\\u{1160}\",\n        &[\"\\u{903}\\u{308}\", \"\\u{1160}\"]), (\"\\u{903}\\u{11a8}\", &[\"\\u{903}\", \"\\u{11a8}\"]),\n        (\"\\u{903}\\u{308}\\u{11a8}\", &[\"\\u{903}\\u{308}\", \"\\u{11a8}\"]), (\"\\u{903}\\u{ac00}\",\n        &[\"\\u{903}\", \"\\u{ac00}\"]), (\"\\u{903}\\u{308}\\u{ac00}\", &[\"\\u{903}\\u{308}\", \"\\u{ac00}\"]),\n        (\"\\u{903}\\u{ac01}\", &[\"\\u{903}\", \"\\u{ac01}\"]), (\"\\u{903}\\u{308}\\u{ac01}\",\n        &[\"\\u{903}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{903}\\u{915}\", &[\"\\u{903}\", \"\\u{915}\"]),\n        (\"\\u{903}\\u{308}\\u{915}\", &[\"\\u{903}\\u{308}\", \"\\u{915}\"]), (\"\\u{903}\\u{a9}\", &[\"\\u{903}\",\n        \"\\u{a9}\"]), (\"\\u{903}\\u{308}\\u{a9}\", &[\"\\u{903}\\u{308}\", \"\\u{a9}\"]), (\"\\u{903}\\u{20}\",\n        &[\"\\u{903}\", \"\\u{20}\"]), (\"\\u{903}\\u{308}\\u{20}\", &[\"\\u{903}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{903}\\u{378}\", &[\"\\u{903}\", \"\\u{378}\"]), (\"\\u{903}\\u{308}\\u{378}\", &[\"\\u{903}\\u{308}\",\n        \"\\u{378}\"]), (\"\\u{1100}\\u{d}\", &[\"\\u{1100}\", \"\\u{d}\"]), (\"\\u{1100}\\u{308}\\u{d}\",\n        &[\"\\u{1100}\\u{308}\", \"\\u{d}\"]), (\"\\u{1100}\\u{a}\", &[\"\\u{1100}\", \"\\u{a}\"]),\n        (\"\\u{1100}\\u{308}\\u{a}\", &[\"\\u{1100}\\u{308}\", \"\\u{a}\"]), (\"\\u{1100}\\u{0}\", &[\"\\u{1100}\",\n        \"\\u{0}\"]), (\"\\u{1100}\\u{308}\\u{0}\", &[\"\\u{1100}\\u{308}\", \"\\u{0}\"]), (\"\\u{1100}\\u{94d}\",\n        &[\"\\u{1100}\\u{94d}\"]), (\"\\u{1100}\\u{308}\\u{94d}\", &[\"\\u{1100}\\u{308}\\u{94d}\"]),\n        (\"\\u{1100}\\u{300}\", &[\"\\u{1100}\\u{300}\"]), (\"\\u{1100}\\u{308}\\u{300}\",\n        &[\"\\u{1100}\\u{308}\\u{300}\"]), (\"\\u{1100}\\u{200c}\", &[\"\\u{1100}\\u{200c}\"]),\n        (\"\\u{1100}\\u{308}\\u{200c}\", &[\"\\u{1100}\\u{308}\\u{200c}\"]), (\"\\u{1100}\\u{200d}\",\n        &[\"\\u{1100}\\u{200d}\"]), (\"\\u{1100}\\u{308}\\u{200d}\", &[\"\\u{1100}\\u{308}\\u{200d}\"]),\n        (\"\\u{1100}\\u{1f1e6}\", &[\"\\u{1100}\", \"\\u{1f1e6}\"]), (\"\\u{1100}\\u{308}\\u{1f1e6}\",\n        &[\"\\u{1100}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{1100}\\u{6dd}\", &[\"\\u{1100}\", \"\\u{6dd}\"]),\n        (\"\\u{1100}\\u{308}\\u{6dd}\", &[\"\\u{1100}\\u{308}\", \"\\u{6dd}\"]), (\"\\u{1100}\\u{1100}\",\n        &[\"\\u{1100}\\u{1100}\"]), (\"\\u{1100}\\u{308}\\u{1100}\", &[\"\\u{1100}\\u{308}\", \"\\u{1100}\"]),\n        (\"\\u{1100}\\u{1160}\", &[\"\\u{1100}\\u{1160}\"]), (\"\\u{1100}\\u{308}\\u{1160}\",\n        &[\"\\u{1100}\\u{308}\", \"\\u{1160}\"]), (\"\\u{1100}\\u{11a8}\", &[\"\\u{1100}\", \"\\u{11a8}\"]),\n        (\"\\u{1100}\\u{308}\\u{11a8}\", &[\"\\u{1100}\\u{308}\", \"\\u{11a8}\"]), (\"\\u{1100}\\u{ac00}\",\n        &[\"\\u{1100}\\u{ac00}\"]), (\"\\u{1100}\\u{308}\\u{ac00}\", &[\"\\u{1100}\\u{308}\", \"\\u{ac00}\"]),\n        (\"\\u{1100}\\u{ac01}\", &[\"\\u{1100}\\u{ac01}\"]), (\"\\u{1100}\\u{308}\\u{ac01}\",\n        &[\"\\u{1100}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{1100}\\u{915}\", &[\"\\u{1100}\", \"\\u{915}\"]),\n        (\"\\u{1100}\\u{308}\\u{915}\", &[\"\\u{1100}\\u{308}\", \"\\u{915}\"]), (\"\\u{1100}\\u{a9}\",\n        &[\"\\u{1100}\", \"\\u{a9}\"]), (\"\\u{1100}\\u{308}\\u{a9}\", &[\"\\u{1100}\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{1100}\\u{20}\", &[\"\\u{1100}\", \"\\u{20}\"]), (\"\\u{1100}\\u{308}\\u{20}\", &[\"\\u{1100}\\u{308}\",\n        \"\\u{20}\"]), (\"\\u{1100}\\u{378}\", &[\"\\u{1100}\", \"\\u{378}\"]), (\"\\u{1100}\\u{308}\\u{378}\",\n        &[\"\\u{1100}\\u{308}\", \"\\u{378}\"]), (\"\\u{1160}\\u{d}\", &[\"\\u{1160}\", \"\\u{d}\"]),\n        (\"\\u{1160}\\u{308}\\u{d}\", &[\"\\u{1160}\\u{308}\", \"\\u{d}\"]), (\"\\u{1160}\\u{a}\", &[\"\\u{1160}\",\n        \"\\u{a}\"]), (\"\\u{1160}\\u{308}\\u{a}\", &[\"\\u{1160}\\u{308}\", \"\\u{a}\"]), (\"\\u{1160}\\u{0}\",\n        &[\"\\u{1160}\", \"\\u{0}\"]), (\"\\u{1160}\\u{308}\\u{0}\", &[\"\\u{1160}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{1160}\\u{94d}\", &[\"\\u{1160}\\u{94d}\"]), (\"\\u{1160}\\u{308}\\u{94d}\",\n        &[\"\\u{1160}\\u{308}\\u{94d}\"]), (\"\\u{1160}\\u{300}\", &[\"\\u{1160}\\u{300}\"]),\n        (\"\\u{1160}\\u{308}\\u{300}\", &[\"\\u{1160}\\u{308}\\u{300}\"]), (\"\\u{1160}\\u{200c}\",\n        &[\"\\u{1160}\\u{200c}\"]), (\"\\u{1160}\\u{308}\\u{200c}\", &[\"\\u{1160}\\u{308}\\u{200c}\"]),\n        (\"\\u{1160}\\u{200d}\", &[\"\\u{1160}\\u{200d}\"]), (\"\\u{1160}\\u{308}\\u{200d}\",\n        &[\"\\u{1160}\\u{308}\\u{200d}\"]), (\"\\u{1160}\\u{1f1e6}\", &[\"\\u{1160}\", \"\\u{1f1e6}\"]),\n        (\"\\u{1160}\\u{308}\\u{1f1e6}\", &[\"\\u{1160}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{1160}\\u{6dd}\",\n        &[\"\\u{1160}\", \"\\u{6dd}\"]), (\"\\u{1160}\\u{308}\\u{6dd}\", &[\"\\u{1160}\\u{308}\", \"\\u{6dd}\"]),\n        (\"\\u{1160}\\u{1100}\", &[\"\\u{1160}\", \"\\u{1100}\"]), (\"\\u{1160}\\u{308}\\u{1100}\",\n        &[\"\\u{1160}\\u{308}\", \"\\u{1100}\"]), (\"\\u{1160}\\u{1160}\", &[\"\\u{1160}\\u{1160}\"]),\n        (\"\\u{1160}\\u{308}\\u{1160}\", &[\"\\u{1160}\\u{308}\", \"\\u{1160}\"]), (\"\\u{1160}\\u{11a8}\",\n        &[\"\\u{1160}\\u{11a8}\"]), (\"\\u{1160}\\u{308}\\u{11a8}\", &[\"\\u{1160}\\u{308}\", \"\\u{11a8}\"]),\n        (\"\\u{1160}\\u{ac00}\", &[\"\\u{1160}\", \"\\u{ac00}\"]), (\"\\u{1160}\\u{308}\\u{ac00}\",\n        &[\"\\u{1160}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{1160}\\u{ac01}\", &[\"\\u{1160}\", \"\\u{ac01}\"]),\n        (\"\\u{1160}\\u{308}\\u{ac01}\", &[\"\\u{1160}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{1160}\\u{915}\",\n        &[\"\\u{1160}\", \"\\u{915}\"]), (\"\\u{1160}\\u{308}\\u{915}\", &[\"\\u{1160}\\u{308}\", \"\\u{915}\"]),\n        (\"\\u{1160}\\u{a9}\", &[\"\\u{1160}\", \"\\u{a9}\"]), (\"\\u{1160}\\u{308}\\u{a9}\", &[\"\\u{1160}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{1160}\\u{20}\", &[\"\\u{1160}\", \"\\u{20}\"]), (\"\\u{1160}\\u{308}\\u{20}\",\n        &[\"\\u{1160}\\u{308}\", \"\\u{20}\"]), (\"\\u{1160}\\u{378}\", &[\"\\u{1160}\", \"\\u{378}\"]),\n        (\"\\u{1160}\\u{308}\\u{378}\", &[\"\\u{1160}\\u{308}\", \"\\u{378}\"]), (\"\\u{11a8}\\u{d}\", &[\"\\u{11a8}\",\n        \"\\u{d}\"]), (\"\\u{11a8}\\u{308}\\u{d}\", &[\"\\u{11a8}\\u{308}\", \"\\u{d}\"]), (\"\\u{11a8}\\u{a}\",\n        &[\"\\u{11a8}\", \"\\u{a}\"]), (\"\\u{11a8}\\u{308}\\u{a}\", &[\"\\u{11a8}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{11a8}\\u{0}\", &[\"\\u{11a8}\", \"\\u{0}\"]), (\"\\u{11a8}\\u{308}\\u{0}\", &[\"\\u{11a8}\\u{308}\",\n        \"\\u{0}\"]), (\"\\u{11a8}\\u{94d}\", &[\"\\u{11a8}\\u{94d}\"]), (\"\\u{11a8}\\u{308}\\u{94d}\",\n        &[\"\\u{11a8}\\u{308}\\u{94d}\"]), (\"\\u{11a8}\\u{300}\", &[\"\\u{11a8}\\u{300}\"]),\n        (\"\\u{11a8}\\u{308}\\u{300}\", &[\"\\u{11a8}\\u{308}\\u{300}\"]), (\"\\u{11a8}\\u{200c}\",\n        &[\"\\u{11a8}\\u{200c}\"]), (\"\\u{11a8}\\u{308}\\u{200c}\", &[\"\\u{11a8}\\u{308}\\u{200c}\"]),\n        (\"\\u{11a8}\\u{200d}\", &[\"\\u{11a8}\\u{200d}\"]), (\"\\u{11a8}\\u{308}\\u{200d}\",\n        &[\"\\u{11a8}\\u{308}\\u{200d}\"]), (\"\\u{11a8}\\u{1f1e6}\", &[\"\\u{11a8}\", \"\\u{1f1e6}\"]),\n        (\"\\u{11a8}\\u{308}\\u{1f1e6}\", &[\"\\u{11a8}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{11a8}\\u{6dd}\",\n        &[\"\\u{11a8}\", \"\\u{6dd}\"]), (\"\\u{11a8}\\u{308}\\u{6dd}\", &[\"\\u{11a8}\\u{308}\", \"\\u{6dd}\"]),\n        (\"\\u{11a8}\\u{1100}\", &[\"\\u{11a8}\", \"\\u{1100}\"]), (\"\\u{11a8}\\u{308}\\u{1100}\",\n        &[\"\\u{11a8}\\u{308}\", \"\\u{1100}\"]), (\"\\u{11a8}\\u{1160}\", &[\"\\u{11a8}\", \"\\u{1160}\"]),\n        (\"\\u{11a8}\\u{308}\\u{1160}\", &[\"\\u{11a8}\\u{308}\", \"\\u{1160}\"]), (\"\\u{11a8}\\u{11a8}\",\n        &[\"\\u{11a8}\\u{11a8}\"]), (\"\\u{11a8}\\u{308}\\u{11a8}\", &[\"\\u{11a8}\\u{308}\", \"\\u{11a8}\"]),\n        (\"\\u{11a8}\\u{ac00}\", &[\"\\u{11a8}\", \"\\u{ac00}\"]), (\"\\u{11a8}\\u{308}\\u{ac00}\",\n        &[\"\\u{11a8}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{11a8}\\u{ac01}\", &[\"\\u{11a8}\", \"\\u{ac01}\"]),\n        (\"\\u{11a8}\\u{308}\\u{ac01}\", &[\"\\u{11a8}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{11a8}\\u{915}\",\n        &[\"\\u{11a8}\", \"\\u{915}\"]), (\"\\u{11a8}\\u{308}\\u{915}\", &[\"\\u{11a8}\\u{308}\", \"\\u{915}\"]),\n        (\"\\u{11a8}\\u{a9}\", &[\"\\u{11a8}\", \"\\u{a9}\"]), (\"\\u{11a8}\\u{308}\\u{a9}\", &[\"\\u{11a8}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{11a8}\\u{20}\", &[\"\\u{11a8}\", \"\\u{20}\"]), (\"\\u{11a8}\\u{308}\\u{20}\",\n        &[\"\\u{11a8}\\u{308}\", \"\\u{20}\"]), (\"\\u{11a8}\\u{378}\", &[\"\\u{11a8}\", \"\\u{378}\"]),\n        (\"\\u{11a8}\\u{308}\\u{378}\", &[\"\\u{11a8}\\u{308}\", \"\\u{378}\"]), (\"\\u{ac00}\\u{d}\", &[\"\\u{ac00}\",\n        \"\\u{d}\"]), (\"\\u{ac00}\\u{308}\\u{d}\", &[\"\\u{ac00}\\u{308}\", \"\\u{d}\"]), (\"\\u{ac00}\\u{a}\",\n        &[\"\\u{ac00}\", \"\\u{a}\"]), (\"\\u{ac00}\\u{308}\\u{a}\", &[\"\\u{ac00}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{ac00}\\u{0}\", &[\"\\u{ac00}\", \"\\u{0}\"]), (\"\\u{ac00}\\u{308}\\u{0}\", &[\"\\u{ac00}\\u{308}\",\n        \"\\u{0}\"]), (\"\\u{ac00}\\u{94d}\", &[\"\\u{ac00}\\u{94d}\"]), (\"\\u{ac00}\\u{308}\\u{94d}\",\n        &[\"\\u{ac00}\\u{308}\\u{94d}\"]), (\"\\u{ac00}\\u{300}\", &[\"\\u{ac00}\\u{300}\"]),\n        (\"\\u{ac00}\\u{308}\\u{300}\", &[\"\\u{ac00}\\u{308}\\u{300}\"]), (\"\\u{ac00}\\u{200c}\",\n        &[\"\\u{ac00}\\u{200c}\"]), (\"\\u{ac00}\\u{308}\\u{200c}\", &[\"\\u{ac00}\\u{308}\\u{200c}\"]),\n        (\"\\u{ac00}\\u{200d}\", &[\"\\u{ac00}\\u{200d}\"]), (\"\\u{ac00}\\u{308}\\u{200d}\",\n        &[\"\\u{ac00}\\u{308}\\u{200d}\"]), (\"\\u{ac00}\\u{1f1e6}\", &[\"\\u{ac00}\", \"\\u{1f1e6}\"]),\n        (\"\\u{ac00}\\u{308}\\u{1f1e6}\", &[\"\\u{ac00}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{ac00}\\u{6dd}\",\n        &[\"\\u{ac00}\", \"\\u{6dd}\"]), (\"\\u{ac00}\\u{308}\\u{6dd}\", &[\"\\u{ac00}\\u{308}\", \"\\u{6dd}\"]),\n        (\"\\u{ac00}\\u{1100}\", &[\"\\u{ac00}\", \"\\u{1100}\"]), (\"\\u{ac00}\\u{308}\\u{1100}\",\n        &[\"\\u{ac00}\\u{308}\", \"\\u{1100}\"]), (\"\\u{ac00}\\u{1160}\", &[\"\\u{ac00}\\u{1160}\"]),\n        (\"\\u{ac00}\\u{308}\\u{1160}\", &[\"\\u{ac00}\\u{308}\", \"\\u{1160}\"]), (\"\\u{ac00}\\u{11a8}\",\n        &[\"\\u{ac00}\\u{11a8}\"]), (\"\\u{ac00}\\u{308}\\u{11a8}\", &[\"\\u{ac00}\\u{308}\", \"\\u{11a8}\"]),\n        (\"\\u{ac00}\\u{ac00}\", &[\"\\u{ac00}\", \"\\u{ac00}\"]), (\"\\u{ac00}\\u{308}\\u{ac00}\",\n        &[\"\\u{ac00}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{ac00}\\u{ac01}\", &[\"\\u{ac00}\", \"\\u{ac01}\"]),\n        (\"\\u{ac00}\\u{308}\\u{ac01}\", &[\"\\u{ac00}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{ac00}\\u{915}\",\n        &[\"\\u{ac00}\", \"\\u{915}\"]), (\"\\u{ac00}\\u{308}\\u{915}\", &[\"\\u{ac00}\\u{308}\", \"\\u{915}\"]),\n        (\"\\u{ac00}\\u{a9}\", &[\"\\u{ac00}\", \"\\u{a9}\"]), (\"\\u{ac00}\\u{308}\\u{a9}\", &[\"\\u{ac00}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{ac00}\\u{20}\", &[\"\\u{ac00}\", \"\\u{20}\"]), (\"\\u{ac00}\\u{308}\\u{20}\",\n        &[\"\\u{ac00}\\u{308}\", \"\\u{20}\"]), (\"\\u{ac00}\\u{378}\", &[\"\\u{ac00}\", \"\\u{378}\"]),\n        (\"\\u{ac00}\\u{308}\\u{378}\", &[\"\\u{ac00}\\u{308}\", \"\\u{378}\"]), (\"\\u{ac01}\\u{d}\", &[\"\\u{ac01}\",\n        \"\\u{d}\"]), (\"\\u{ac01}\\u{308}\\u{d}\", &[\"\\u{ac01}\\u{308}\", \"\\u{d}\"]), (\"\\u{ac01}\\u{a}\",\n        &[\"\\u{ac01}\", \"\\u{a}\"]), (\"\\u{ac01}\\u{308}\\u{a}\", &[\"\\u{ac01}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{ac01}\\u{0}\", &[\"\\u{ac01}\", \"\\u{0}\"]), (\"\\u{ac01}\\u{308}\\u{0}\", &[\"\\u{ac01}\\u{308}\",\n        \"\\u{0}\"]), (\"\\u{ac01}\\u{94d}\", &[\"\\u{ac01}\\u{94d}\"]), (\"\\u{ac01}\\u{308}\\u{94d}\",\n        &[\"\\u{ac01}\\u{308}\\u{94d}\"]), (\"\\u{ac01}\\u{300}\", &[\"\\u{ac01}\\u{300}\"]),\n        (\"\\u{ac01}\\u{308}\\u{300}\", &[\"\\u{ac01}\\u{308}\\u{300}\"]), (\"\\u{ac01}\\u{200c}\",\n        &[\"\\u{ac01}\\u{200c}\"]), (\"\\u{ac01}\\u{308}\\u{200c}\", &[\"\\u{ac01}\\u{308}\\u{200c}\"]),\n        (\"\\u{ac01}\\u{200d}\", &[\"\\u{ac01}\\u{200d}\"]), (\"\\u{ac01}\\u{308}\\u{200d}\",\n        &[\"\\u{ac01}\\u{308}\\u{200d}\"]), (\"\\u{ac01}\\u{1f1e6}\", &[\"\\u{ac01}\", \"\\u{1f1e6}\"]),\n        (\"\\u{ac01}\\u{308}\\u{1f1e6}\", &[\"\\u{ac01}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{ac01}\\u{6dd}\",\n        &[\"\\u{ac01}\", \"\\u{6dd}\"]), (\"\\u{ac01}\\u{308}\\u{6dd}\", &[\"\\u{ac01}\\u{308}\", \"\\u{6dd}\"]),\n        (\"\\u{ac01}\\u{1100}\", &[\"\\u{ac01}\", \"\\u{1100}\"]), (\"\\u{ac01}\\u{308}\\u{1100}\",\n        &[\"\\u{ac01}\\u{308}\", \"\\u{1100}\"]), (\"\\u{ac01}\\u{1160}\", &[\"\\u{ac01}\", \"\\u{1160}\"]),\n        (\"\\u{ac01}\\u{308}\\u{1160}\", &[\"\\u{ac01}\\u{308}\", \"\\u{1160}\"]), (\"\\u{ac01}\\u{11a8}\",\n        &[\"\\u{ac01}\\u{11a8}\"]), (\"\\u{ac01}\\u{308}\\u{11a8}\", &[\"\\u{ac01}\\u{308}\", \"\\u{11a8}\"]),\n        (\"\\u{ac01}\\u{ac00}\", &[\"\\u{ac01}\", \"\\u{ac00}\"]), (\"\\u{ac01}\\u{308}\\u{ac00}\",\n        &[\"\\u{ac01}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{ac01}\\u{ac01}\", &[\"\\u{ac01}\", \"\\u{ac01}\"]),\n        (\"\\u{ac01}\\u{308}\\u{ac01}\", &[\"\\u{ac01}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{ac01}\\u{915}\",\n        &[\"\\u{ac01}\", \"\\u{915}\"]), (\"\\u{ac01}\\u{308}\\u{915}\", &[\"\\u{ac01}\\u{308}\", \"\\u{915}\"]),\n        (\"\\u{ac01}\\u{a9}\", &[\"\\u{ac01}\", \"\\u{a9}\"]), (\"\\u{ac01}\\u{308}\\u{a9}\", &[\"\\u{ac01}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{ac01}\\u{20}\", &[\"\\u{ac01}\", \"\\u{20}\"]), (\"\\u{ac01}\\u{308}\\u{20}\",\n        &[\"\\u{ac01}\\u{308}\", \"\\u{20}\"]), (\"\\u{ac01}\\u{378}\", &[\"\\u{ac01}\", \"\\u{378}\"]),\n        (\"\\u{ac01}\\u{308}\\u{378}\", &[\"\\u{ac01}\\u{308}\", \"\\u{378}\"]), (\"\\u{915}\\u{d}\", &[\"\\u{915}\",\n        \"\\u{d}\"]), (\"\\u{915}\\u{308}\\u{d}\", &[\"\\u{915}\\u{308}\", \"\\u{d}\"]), (\"\\u{915}\\u{a}\",\n        &[\"\\u{915}\", \"\\u{a}\"]), (\"\\u{915}\\u{308}\\u{a}\", &[\"\\u{915}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{915}\\u{0}\", &[\"\\u{915}\", \"\\u{0}\"]), (\"\\u{915}\\u{308}\\u{0}\", &[\"\\u{915}\\u{308}\",\n        \"\\u{0}\"]), (\"\\u{915}\\u{94d}\", &[\"\\u{915}\\u{94d}\"]), (\"\\u{915}\\u{308}\\u{94d}\",\n        &[\"\\u{915}\\u{308}\\u{94d}\"]), (\"\\u{915}\\u{300}\", &[\"\\u{915}\\u{300}\"]),\n        (\"\\u{915}\\u{308}\\u{300}\", &[\"\\u{915}\\u{308}\\u{300}\"]), (\"\\u{915}\\u{200c}\",\n        &[\"\\u{915}\\u{200c}\"]), (\"\\u{915}\\u{308}\\u{200c}\", &[\"\\u{915}\\u{308}\\u{200c}\"]),\n        (\"\\u{915}\\u{200d}\", &[\"\\u{915}\\u{200d}\"]), (\"\\u{915}\\u{308}\\u{200d}\",\n        &[\"\\u{915}\\u{308}\\u{200d}\"]), (\"\\u{915}\\u{1f1e6}\", &[\"\\u{915}\", \"\\u{1f1e6}\"]),\n        (\"\\u{915}\\u{308}\\u{1f1e6}\", &[\"\\u{915}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{915}\\u{6dd}\",\n        &[\"\\u{915}\", \"\\u{6dd}\"]), (\"\\u{915}\\u{308}\\u{6dd}\", &[\"\\u{915}\\u{308}\", \"\\u{6dd}\"]),\n        (\"\\u{915}\\u{1100}\", &[\"\\u{915}\", \"\\u{1100}\"]), (\"\\u{915}\\u{308}\\u{1100}\",\n        &[\"\\u{915}\\u{308}\", \"\\u{1100}\"]), (\"\\u{915}\\u{1160}\", &[\"\\u{915}\", \"\\u{1160}\"]),\n        (\"\\u{915}\\u{308}\\u{1160}\", &[\"\\u{915}\\u{308}\", \"\\u{1160}\"]), (\"\\u{915}\\u{11a8}\",\n        &[\"\\u{915}\", \"\\u{11a8}\"]), (\"\\u{915}\\u{308}\\u{11a8}\", &[\"\\u{915}\\u{308}\", \"\\u{11a8}\"]),\n        (\"\\u{915}\\u{ac00}\", &[\"\\u{915}\", \"\\u{ac00}\"]), (\"\\u{915}\\u{308}\\u{ac00}\",\n        &[\"\\u{915}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{915}\\u{ac01}\", &[\"\\u{915}\", \"\\u{ac01}\"]),\n        (\"\\u{915}\\u{308}\\u{ac01}\", &[\"\\u{915}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{915}\\u{915}\", &[\"\\u{915}\",\n        \"\\u{915}\"]), (\"\\u{915}\\u{308}\\u{915}\", &[\"\\u{915}\\u{308}\", \"\\u{915}\"]), (\"\\u{915}\\u{a9}\",\n        &[\"\\u{915}\", \"\\u{a9}\"]), (\"\\u{915}\\u{308}\\u{a9}\", &[\"\\u{915}\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{915}\\u{20}\", &[\"\\u{915}\", \"\\u{20}\"]), (\"\\u{915}\\u{308}\\u{20}\", &[\"\\u{915}\\u{308}\",\n        \"\\u{20}\"]), (\"\\u{915}\\u{378}\", &[\"\\u{915}\", \"\\u{378}\"]), (\"\\u{915}\\u{308}\\u{378}\",\n        &[\"\\u{915}\\u{308}\", \"\\u{378}\"]), (\"\\u{a9}\\u{d}\", &[\"\\u{a9}\", \"\\u{d}\"]),\n        (\"\\u{a9}\\u{308}\\u{d}\", &[\"\\u{a9}\\u{308}\", \"\\u{d}\"]), (\"\\u{a9}\\u{a}\", &[\"\\u{a9}\", \"\\u{a}\"]),\n        (\"\\u{a9}\\u{308}\\u{a}\", &[\"\\u{a9}\\u{308}\", \"\\u{a}\"]), (\"\\u{a9}\\u{0}\", &[\"\\u{a9}\", \"\\u{0}\"]),\n        (\"\\u{a9}\\u{308}\\u{0}\", &[\"\\u{a9}\\u{308}\", \"\\u{0}\"]), (\"\\u{a9}\\u{94d}\", &[\"\\u{a9}\\u{94d}\"]),\n        (\"\\u{a9}\\u{308}\\u{94d}\", &[\"\\u{a9}\\u{308}\\u{94d}\"]), (\"\\u{a9}\\u{300}\", &[\"\\u{a9}\\u{300}\"]),\n        (\"\\u{a9}\\u{308}\\u{300}\", &[\"\\u{a9}\\u{308}\\u{300}\"]), (\"\\u{a9}\\u{200c}\",\n        &[\"\\u{a9}\\u{200c}\"]), (\"\\u{a9}\\u{308}\\u{200c}\", &[\"\\u{a9}\\u{308}\\u{200c}\"]),\n        (\"\\u{a9}\\u{200d}\", &[\"\\u{a9}\\u{200d}\"]), (\"\\u{a9}\\u{308}\\u{200d}\",\n        &[\"\\u{a9}\\u{308}\\u{200d}\"]), (\"\\u{a9}\\u{1f1e6}\", &[\"\\u{a9}\", \"\\u{1f1e6}\"]),\n        (\"\\u{a9}\\u{308}\\u{1f1e6}\", &[\"\\u{a9}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{a9}\\u{6dd}\", &[\"\\u{a9}\",\n        \"\\u{6dd}\"]), (\"\\u{a9}\\u{308}\\u{6dd}\", &[\"\\u{a9}\\u{308}\", \"\\u{6dd}\"]), (\"\\u{a9}\\u{1100}\",\n        &[\"\\u{a9}\", \"\\u{1100}\"]), (\"\\u{a9}\\u{308}\\u{1100}\", &[\"\\u{a9}\\u{308}\", \"\\u{1100}\"]),\n        (\"\\u{a9}\\u{1160}\", &[\"\\u{a9}\", \"\\u{1160}\"]), (\"\\u{a9}\\u{308}\\u{1160}\", &[\"\\u{a9}\\u{308}\",\n        \"\\u{1160}\"]), (\"\\u{a9}\\u{11a8}\", &[\"\\u{a9}\", \"\\u{11a8}\"]), (\"\\u{a9}\\u{308}\\u{11a8}\",\n        &[\"\\u{a9}\\u{308}\", \"\\u{11a8}\"]), (\"\\u{a9}\\u{ac00}\", &[\"\\u{a9}\", \"\\u{ac00}\"]),\n        (\"\\u{a9}\\u{308}\\u{ac00}\", &[\"\\u{a9}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{a9}\\u{ac01}\", &[\"\\u{a9}\",\n        \"\\u{ac01}\"]), (\"\\u{a9}\\u{308}\\u{ac01}\", &[\"\\u{a9}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{a9}\\u{915}\",\n        &[\"\\u{a9}\", \"\\u{915}\"]), (\"\\u{a9}\\u{308}\\u{915}\", &[\"\\u{a9}\\u{308}\", \"\\u{915}\"]),\n        (\"\\u{a9}\\u{a9}\", &[\"\\u{a9}\", \"\\u{a9}\"]), (\"\\u{a9}\\u{308}\\u{a9}\", &[\"\\u{a9}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{a9}\\u{20}\", &[\"\\u{a9}\", \"\\u{20}\"]), (\"\\u{a9}\\u{308}\\u{20}\",\n        &[\"\\u{a9}\\u{308}\", \"\\u{20}\"]), (\"\\u{a9}\\u{378}\", &[\"\\u{a9}\", \"\\u{378}\"]),\n        (\"\\u{a9}\\u{308}\\u{378}\", &[\"\\u{a9}\\u{308}\", \"\\u{378}\"]), (\"\\u{20}\\u{d}\", &[\"\\u{20}\",\n        \"\\u{d}\"]), (\"\\u{20}\\u{308}\\u{d}\", &[\"\\u{20}\\u{308}\", \"\\u{d}\"]), (\"\\u{20}\\u{a}\", &[\"\\u{20}\",\n        \"\\u{a}\"]), (\"\\u{20}\\u{308}\\u{a}\", &[\"\\u{20}\\u{308}\", \"\\u{a}\"]), (\"\\u{20}\\u{0}\", &[\"\\u{20}\",\n        \"\\u{0}\"]), (\"\\u{20}\\u{308}\\u{0}\", &[\"\\u{20}\\u{308}\", \"\\u{0}\"]), (\"\\u{20}\\u{94d}\",\n        &[\"\\u{20}\\u{94d}\"]), (\"\\u{20}\\u{308}\\u{94d}\", &[\"\\u{20}\\u{308}\\u{94d}\"]), (\"\\u{20}\\u{300}\",\n        &[\"\\u{20}\\u{300}\"]), (\"\\u{20}\\u{308}\\u{300}\", &[\"\\u{20}\\u{308}\\u{300}\"]), (\"\\u{20}\\u{200c}\",\n        &[\"\\u{20}\\u{200c}\"]), (\"\\u{20}\\u{308}\\u{200c}\", &[\"\\u{20}\\u{308}\\u{200c}\"]),\n        (\"\\u{20}\\u{200d}\", &[\"\\u{20}\\u{200d}\"]), (\"\\u{20}\\u{308}\\u{200d}\",\n        &[\"\\u{20}\\u{308}\\u{200d}\"]), (\"\\u{20}\\u{1f1e6}\", &[\"\\u{20}\", \"\\u{1f1e6}\"]),\n        (\"\\u{20}\\u{308}\\u{1f1e6}\", &[\"\\u{20}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{20}\\u{6dd}\", &[\"\\u{20}\",\n        \"\\u{6dd}\"]), (\"\\u{20}\\u{308}\\u{6dd}\", &[\"\\u{20}\\u{308}\", \"\\u{6dd}\"]), (\"\\u{20}\\u{1100}\",\n        &[\"\\u{20}\", \"\\u{1100}\"]), (\"\\u{20}\\u{308}\\u{1100}\", &[\"\\u{20}\\u{308}\", \"\\u{1100}\"]),\n        (\"\\u{20}\\u{1160}\", &[\"\\u{20}\", \"\\u{1160}\"]), (\"\\u{20}\\u{308}\\u{1160}\", &[\"\\u{20}\\u{308}\",\n        \"\\u{1160}\"]), (\"\\u{20}\\u{11a8}\", &[\"\\u{20}\", \"\\u{11a8}\"]), (\"\\u{20}\\u{308}\\u{11a8}\",\n        &[\"\\u{20}\\u{308}\", \"\\u{11a8}\"]), (\"\\u{20}\\u{ac00}\", &[\"\\u{20}\", \"\\u{ac00}\"]),\n        (\"\\u{20}\\u{308}\\u{ac00}\", &[\"\\u{20}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{20}\\u{ac01}\", &[\"\\u{20}\",\n        \"\\u{ac01}\"]), (\"\\u{20}\\u{308}\\u{ac01}\", &[\"\\u{20}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{20}\\u{915}\",\n        &[\"\\u{20}\", \"\\u{915}\"]), (\"\\u{20}\\u{308}\\u{915}\", &[\"\\u{20}\\u{308}\", \"\\u{915}\"]),\n        (\"\\u{20}\\u{a9}\", &[\"\\u{20}\", \"\\u{a9}\"]), (\"\\u{20}\\u{308}\\u{a9}\", &[\"\\u{20}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{20}\\u{20}\", &[\"\\u{20}\", \"\\u{20}\"]), (\"\\u{20}\\u{308}\\u{20}\",\n        &[\"\\u{20}\\u{308}\", \"\\u{20}\"]), (\"\\u{20}\\u{378}\", &[\"\\u{20}\", \"\\u{378}\"]),\n        (\"\\u{20}\\u{308}\\u{378}\", &[\"\\u{20}\\u{308}\", \"\\u{378}\"]), (\"\\u{378}\\u{d}\", &[\"\\u{378}\",\n        \"\\u{d}\"]), (\"\\u{378}\\u{308}\\u{d}\", &[\"\\u{378}\\u{308}\", \"\\u{d}\"]), (\"\\u{378}\\u{a}\",\n        &[\"\\u{378}\", \"\\u{a}\"]), (\"\\u{378}\\u{308}\\u{a}\", &[\"\\u{378}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{378}\\u{0}\", &[\"\\u{378}\", \"\\u{0}\"]), (\"\\u{378}\\u{308}\\u{0}\", &[\"\\u{378}\\u{308}\",\n        \"\\u{0}\"]), (\"\\u{378}\\u{94d}\", &[\"\\u{378}\\u{94d}\"]), (\"\\u{378}\\u{308}\\u{94d}\",\n        &[\"\\u{378}\\u{308}\\u{94d}\"]), (\"\\u{378}\\u{300}\", &[\"\\u{378}\\u{300}\"]),\n        (\"\\u{378}\\u{308}\\u{300}\", &[\"\\u{378}\\u{308}\\u{300}\"]), (\"\\u{378}\\u{200c}\",\n        &[\"\\u{378}\\u{200c}\"]), (\"\\u{378}\\u{308}\\u{200c}\", &[\"\\u{378}\\u{308}\\u{200c}\"]),\n        (\"\\u{378}\\u{200d}\", &[\"\\u{378}\\u{200d}\"]), (\"\\u{378}\\u{308}\\u{200d}\",\n        &[\"\\u{378}\\u{308}\\u{200d}\"]), (\"\\u{378}\\u{1f1e6}\", &[\"\\u{378}\", \"\\u{1f1e6}\"]),\n        (\"\\u{378}\\u{308}\\u{1f1e6}\", &[\"\\u{378}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{378}\\u{6dd}\",\n        &[\"\\u{378}\", \"\\u{6dd}\"]), (\"\\u{378}\\u{308}\\u{6dd}\", &[\"\\u{378}\\u{308}\", \"\\u{6dd}\"]),\n        (\"\\u{378}\\u{1100}\", &[\"\\u{378}\", \"\\u{1100}\"]), (\"\\u{378}\\u{308}\\u{1100}\",\n        &[\"\\u{378}\\u{308}\", \"\\u{1100}\"]), (\"\\u{378}\\u{1160}\", &[\"\\u{378}\", \"\\u{1160}\"]),\n        (\"\\u{378}\\u{308}\\u{1160}\", &[\"\\u{378}\\u{308}\", \"\\u{1160}\"]), (\"\\u{378}\\u{11a8}\",\n        &[\"\\u{378}\", \"\\u{11a8}\"]), (\"\\u{378}\\u{308}\\u{11a8}\", &[\"\\u{378}\\u{308}\", \"\\u{11a8}\"]),\n        (\"\\u{378}\\u{ac00}\", &[\"\\u{378}\", \"\\u{ac00}\"]), (\"\\u{378}\\u{308}\\u{ac00}\",\n        &[\"\\u{378}\\u{308}\", \"\\u{ac00}\"]), (\"\\u{378}\\u{ac01}\", &[\"\\u{378}\", \"\\u{ac01}\"]),\n        (\"\\u{378}\\u{308}\\u{ac01}\", &[\"\\u{378}\\u{308}\", \"\\u{ac01}\"]), (\"\\u{378}\\u{915}\", &[\"\\u{378}\",\n        \"\\u{915}\"]), (\"\\u{378}\\u{308}\\u{915}\", &[\"\\u{378}\\u{308}\", \"\\u{915}\"]), (\"\\u{378}\\u{a9}\",\n        &[\"\\u{378}\", \"\\u{a9}\"]), (\"\\u{378}\\u{308}\\u{a9}\", &[\"\\u{378}\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{378}\\u{20}\", &[\"\\u{378}\", \"\\u{20}\"]), (\"\\u{378}\\u{308}\\u{20}\", &[\"\\u{378}\\u{308}\",\n        \"\\u{20}\"]), (\"\\u{378}\\u{378}\", &[\"\\u{378}\", \"\\u{378}\"]), (\"\\u{378}\\u{308}\\u{378}\",\n        &[\"\\u{378}\\u{308}\", \"\\u{378}\"]), (\"\\u{d}\\u{a}\\u{61}\\u{a}\\u{308}\", &[\"\\u{d}\\u{a}\", \"\\u{61}\",\n        \"\\u{a}\", \"\\u{308}\"]), (\"\\u{61}\\u{308}\", &[\"\\u{61}\\u{308}\"]), (\"\\u{20}\\u{200d}\\u{646}\",\n        &[\"\\u{20}\\u{200d}\", \"\\u{646}\"]), (\"\\u{646}\\u{200d}\\u{20}\", &[\"\\u{646}\\u{200d}\", \"\\u{20}\"]),\n        (\"\\u{1100}\\u{1100}\", &[\"\\u{1100}\\u{1100}\"]), (\"\\u{ac00}\\u{11a8}\\u{1100}\",\n        &[\"\\u{ac00}\\u{11a8}\", \"\\u{1100}\"]), (\"\\u{ac01}\\u{11a8}\\u{1100}\", &[\"\\u{ac01}\\u{11a8}\",\n        \"\\u{1100}\"]), (\"\\u{1f1e6}\\u{1f1e7}\\u{1f1e8}\\u{62}\", &[\"\\u{1f1e6}\\u{1f1e7}\", \"\\u{1f1e8}\",\n        \"\\u{62}\"]), (\"\\u{61}\\u{1f1e6}\\u{1f1e7}\\u{1f1e8}\\u{62}\", &[\"\\u{61}\", \"\\u{1f1e6}\\u{1f1e7}\",\n        \"\\u{1f1e8}\", \"\\u{62}\"]), (\"\\u{61}\\u{1f1e6}\\u{1f1e7}\\u{200d}\\u{1f1e8}\\u{62}\", &[\"\\u{61}\",\n        \"\\u{1f1e6}\\u{1f1e7}\\u{200d}\", \"\\u{1f1e8}\", \"\\u{62}\"]),\n        (\"\\u{61}\\u{1f1e6}\\u{200d}\\u{1f1e7}\\u{1f1e8}\\u{62}\", &[\"\\u{61}\", \"\\u{1f1e6}\\u{200d}\",\n        \"\\u{1f1e7}\\u{1f1e8}\", \"\\u{62}\"]), (\"\\u{61}\\u{1f1e6}\\u{1f1e7}\\u{1f1e8}\\u{1f1e9}\\u{62}\",\n        &[\"\\u{61}\", \"\\u{1f1e6}\\u{1f1e7}\", \"\\u{1f1e8}\\u{1f1e9}\", \"\\u{62}\"]), (\"\\u{61}\\u{200d}\",\n        &[\"\\u{61}\\u{200d}\"]), (\"\\u{61}\\u{308}\\u{62}\", &[\"\\u{61}\\u{308}\", \"\\u{62}\"]),\n        (\"\\u{1f476}\\u{1f3ff}\\u{1f476}\", &[\"\\u{1f476}\\u{1f3ff}\", \"\\u{1f476}\"]),\n        (\"\\u{61}\\u{1f3ff}\\u{1f476}\", &[\"\\u{61}\\u{1f3ff}\", \"\\u{1f476}\"]),\n        (\"\\u{61}\\u{1f3ff}\\u{1f476}\\u{200d}\\u{1f6d1}\", &[\"\\u{61}\\u{1f3ff}\",\n        \"\\u{1f476}\\u{200d}\\u{1f6d1}\"]), (\"\\u{1f476}\\u{1f3ff}\\u{308}\\u{200d}\\u{1f476}\\u{1f3ff}\",\n        &[\"\\u{1f476}\\u{1f3ff}\\u{308}\\u{200d}\\u{1f476}\\u{1f3ff}\"]), (\"\\u{1f6d1}\\u{200d}\\u{1f6d1}\",\n        &[\"\\u{1f6d1}\\u{200d}\\u{1f6d1}\"]), (\"\\u{61}\\u{200d}\\u{1f6d1}\", &[\"\\u{61}\\u{200d}\",\n        \"\\u{1f6d1}\"]), (\"\\u{2701}\\u{200d}\\u{2701}\", &[\"\\u{2701}\\u{200d}\", \"\\u{2701}\"]),\n        (\"\\u{61}\\u{200d}\\u{2701}\", &[\"\\u{61}\\u{200d}\", \"\\u{2701}\"]), (\"\\u{915}\\u{924}\", &[\"\\u{915}\",\n        \"\\u{924}\"]), (\"\\u{915}\\u{94d}\\u{61}\", &[\"\\u{915}\\u{94d}\", \"\\u{61}\"]),\n        (\"\\u{61}\\u{94d}\\u{924}\", &[\"\\u{61}\\u{94d}\", \"\\u{924}\"]), (\"\\u{3f}\\u{94d}\\u{924}\",\n        &[\"\\u{3f}\\u{94d}\", \"\\u{924}\"])\n    ];\n\n    pub const TEST_DIFF: &[(&str, &[&str], &[&str])] = &[\n        (\"\\u{d}\\u{308}\\u{903}\", &[\"\\u{d}\", \"\\u{308}\\u{903}\"], &[\"\\u{d}\", \"\\u{308}\", \"\\u{903}\"]),\n        (\"\\u{a}\\u{308}\\u{903}\", &[\"\\u{a}\", \"\\u{308}\\u{903}\"], &[\"\\u{a}\", \"\\u{308}\", \"\\u{903}\"]),\n        (\"\\u{0}\\u{308}\\u{903}\", &[\"\\u{0}\", \"\\u{308}\\u{903}\"], &[\"\\u{0}\", \"\\u{308}\", \"\\u{903}\"]),\n        (\"\\u{94d}\\u{903}\", &[\"\\u{94d}\\u{903}\"], &[\"\\u{94d}\", \"\\u{903}\"]), (\"\\u{94d}\\u{308}\\u{903}\",\n        &[\"\\u{94d}\\u{308}\\u{903}\"], &[\"\\u{94d}\\u{308}\", \"\\u{903}\"]), (\"\\u{300}\\u{903}\",\n        &[\"\\u{300}\\u{903}\"], &[\"\\u{300}\", \"\\u{903}\"]), (\"\\u{300}\\u{308}\\u{903}\",\n        &[\"\\u{300}\\u{308}\\u{903}\"], &[\"\\u{300}\\u{308}\", \"\\u{903}\"]), (\"\\u{200c}\\u{903}\",\n        &[\"\\u{200c}\\u{903}\"], &[\"\\u{200c}\", \"\\u{903}\"]), (\"\\u{200c}\\u{308}\\u{903}\",\n        &[\"\\u{200c}\\u{308}\\u{903}\"], &[\"\\u{200c}\\u{308}\", \"\\u{903}\"]), (\"\\u{200d}\\u{903}\",\n        &[\"\\u{200d}\\u{903}\"], &[\"\\u{200d}\", \"\\u{903}\"]), (\"\\u{200d}\\u{308}\\u{903}\",\n        &[\"\\u{200d}\\u{308}\\u{903}\"], &[\"\\u{200d}\\u{308}\", \"\\u{903}\"]), (\"\\u{1f1e6}\\u{903}\",\n        &[\"\\u{1f1e6}\\u{903}\"], &[\"\\u{1f1e6}\", \"\\u{903}\"]), (\"\\u{1f1e6}\\u{308}\\u{903}\",\n        &[\"\\u{1f1e6}\\u{308}\\u{903}\"], &[\"\\u{1f1e6}\\u{308}\", \"\\u{903}\"]), (\"\\u{6dd}\\u{1f1e6}\",\n        &[\"\\u{6dd}\\u{1f1e6}\"], &[\"\\u{6dd}\", \"\\u{1f1e6}\"]), (\"\\u{6dd}\\u{6dd}\", &[\"\\u{6dd}\\u{6dd}\"],\n        &[\"\\u{6dd}\", \"\\u{6dd}\"]), (\"\\u{6dd}\\u{903}\", &[\"\\u{6dd}\\u{903}\"], &[\"\\u{6dd}\", \"\\u{903}\"]),\n        (\"\\u{6dd}\\u{308}\\u{903}\", &[\"\\u{6dd}\\u{308}\\u{903}\"], &[\"\\u{6dd}\\u{308}\", \"\\u{903}\"]),\n        (\"\\u{6dd}\\u{1100}\", &[\"\\u{6dd}\\u{1100}\"], &[\"\\u{6dd}\", \"\\u{1100}\"]), (\"\\u{6dd}\\u{1160}\",\n        &[\"\\u{6dd}\\u{1160}\"], &[\"\\u{6dd}\", \"\\u{1160}\"]), (\"\\u{6dd}\\u{11a8}\", &[\"\\u{6dd}\\u{11a8}\"],\n        &[\"\\u{6dd}\", \"\\u{11a8}\"]), (\"\\u{6dd}\\u{ac00}\", &[\"\\u{6dd}\\u{ac00}\"], &[\"\\u{6dd}\",\n        \"\\u{ac00}\"]), (\"\\u{6dd}\\u{ac01}\", &[\"\\u{6dd}\\u{ac01}\"], &[\"\\u{6dd}\", \"\\u{ac01}\"]),\n        (\"\\u{6dd}\\u{915}\", &[\"\\u{6dd}\\u{915}\"], &[\"\\u{6dd}\", \"\\u{915}\"]), (\"\\u{6dd}\\u{a9}\",\n        &[\"\\u{6dd}\\u{a9}\"], &[\"\\u{6dd}\", \"\\u{a9}\"]), (\"\\u{6dd}\\u{20}\", &[\"\\u{6dd}\\u{20}\"],\n        &[\"\\u{6dd}\", \"\\u{20}\"]), (\"\\u{6dd}\\u{378}\", &[\"\\u{6dd}\\u{378}\"], &[\"\\u{6dd}\", \"\\u{378}\"]),\n        (\"\\u{903}\\u{903}\", &[\"\\u{903}\\u{903}\"], &[\"\\u{903}\", \"\\u{903}\"]), (\"\\u{903}\\u{308}\\u{903}\",\n        &[\"\\u{903}\\u{308}\\u{903}\"], &[\"\\u{903}\\u{308}\", \"\\u{903}\"]), (\"\\u{1100}\\u{903}\",\n        &[\"\\u{1100}\\u{903}\"], &[\"\\u{1100}\", \"\\u{903}\"]), (\"\\u{1100}\\u{308}\\u{903}\",\n        &[\"\\u{1100}\\u{308}\\u{903}\"], &[\"\\u{1100}\\u{308}\", \"\\u{903}\"]), (\"\\u{1160}\\u{903}\",\n        &[\"\\u{1160}\\u{903}\"], &[\"\\u{1160}\", \"\\u{903}\"]), (\"\\u{1160}\\u{308}\\u{903}\",\n        &[\"\\u{1160}\\u{308}\\u{903}\"], &[\"\\u{1160}\\u{308}\", \"\\u{903}\"]), (\"\\u{11a8}\\u{903}\",\n        &[\"\\u{11a8}\\u{903}\"], &[\"\\u{11a8}\", \"\\u{903}\"]), (\"\\u{11a8}\\u{308}\\u{903}\",\n        &[\"\\u{11a8}\\u{308}\\u{903}\"], &[\"\\u{11a8}\\u{308}\", \"\\u{903}\"]), (\"\\u{ac00}\\u{903}\",\n        &[\"\\u{ac00}\\u{903}\"], &[\"\\u{ac00}\", \"\\u{903}\"]), (\"\\u{ac00}\\u{308}\\u{903}\",\n        &[\"\\u{ac00}\\u{308}\\u{903}\"], &[\"\\u{ac00}\\u{308}\", \"\\u{903}\"]), (\"\\u{ac01}\\u{903}\",\n        &[\"\\u{ac01}\\u{903}\"], &[\"\\u{ac01}\", \"\\u{903}\"]), (\"\\u{ac01}\\u{308}\\u{903}\",\n        &[\"\\u{ac01}\\u{308}\\u{903}\"], &[\"\\u{ac01}\\u{308}\", \"\\u{903}\"]), (\"\\u{915}\\u{903}\",\n        &[\"\\u{915}\\u{903}\"], &[\"\\u{915}\", \"\\u{903}\"]), (\"\\u{915}\\u{308}\\u{903}\",\n        &[\"\\u{915}\\u{308}\\u{903}\"], &[\"\\u{915}\\u{308}\", \"\\u{903}\"]), (\"\\u{a9}\\u{903}\",\n        &[\"\\u{a9}\\u{903}\"], &[\"\\u{a9}\", \"\\u{903}\"]), (\"\\u{a9}\\u{308}\\u{903}\",\n        &[\"\\u{a9}\\u{308}\\u{903}\"], &[\"\\u{a9}\\u{308}\", \"\\u{903}\"]), (\"\\u{20}\\u{903}\",\n        &[\"\\u{20}\\u{903}\"], &[\"\\u{20}\", \"\\u{903}\"]), (\"\\u{20}\\u{308}\\u{903}\",\n        &[\"\\u{20}\\u{308}\\u{903}\"], &[\"\\u{20}\\u{308}\", \"\\u{903}\"]), (\"\\u{378}\\u{903}\",\n        &[\"\\u{378}\\u{903}\"], &[\"\\u{378}\", \"\\u{903}\"]), (\"\\u{378}\\u{308}\\u{903}\",\n        &[\"\\u{378}\\u{308}\\u{903}\"], &[\"\\u{378}\\u{308}\", \"\\u{903}\"]), (\"\\u{61}\\u{903}\\u{62}\",\n        &[\"\\u{61}\\u{903}\", \"\\u{62}\"], &[\"\\u{61}\", \"\\u{903}\", \"\\u{62}\"]), (\"\\u{61}\\u{600}\\u{62}\",\n        &[\"\\u{61}\", \"\\u{600}\\u{62}\"], &[\"\\u{61}\", \"\\u{600}\", \"\\u{62}\"]), (\"\\u{915}\\u{94d}\\u{924}\",\n        &[\"\\u{915}\\u{94d}\\u{924}\"], &[\"\\u{915}\\u{94d}\", \"\\u{924}\"]),\n        (\"\\u{915}\\u{94d}\\u{94d}\\u{924}\", &[\"\\u{915}\\u{94d}\\u{94d}\\u{924}\"],\n        &[\"\\u{915}\\u{94d}\\u{94d}\", \"\\u{924}\"]), (\"\\u{915}\\u{94d}\\u{200d}\\u{924}\",\n        &[\"\\u{915}\\u{94d}\\u{200d}\\u{924}\"], &[\"\\u{915}\\u{94d}\\u{200d}\", \"\\u{924}\"]),\n        (\"\\u{915}\\u{93c}\\u{200d}\\u{94d}\\u{924}\", &[\"\\u{915}\\u{93c}\\u{200d}\\u{94d}\\u{924}\"],\n        &[\"\\u{915}\\u{93c}\\u{200d}\\u{94d}\", \"\\u{924}\"]), (\"\\u{915}\\u{93c}\\u{94d}\\u{200d}\\u{924}\",\n        &[\"\\u{915}\\u{93c}\\u{94d}\\u{200d}\\u{924}\"], &[\"\\u{915}\\u{93c}\\u{94d}\\u{200d}\", \"\\u{924}\"]),\n        (\"\\u{915}\\u{94d}\\u{924}\\u{94d}\\u{92f}\", &[\"\\u{915}\\u{94d}\\u{924}\\u{94d}\\u{92f}\"],\n        &[\"\\u{915}\\u{94d}\", \"\\u{924}\\u{94d}\", \"\\u{92f}\"]), (\"\\u{915}\\u{94d}\\u{94d}\\u{924}\",\n        &[\"\\u{915}\\u{94d}\\u{94d}\\u{924}\"], &[\"\\u{915}\\u{94d}\\u{94d}\", \"\\u{924}\"]),\n        (\"\\u{ab8}\\u{afb}\\u{acd}\\u{ab8}\\u{afb}\", &[\"\\u{ab8}\\u{afb}\\u{acd}\\u{ab8}\\u{afb}\"],\n        &[\"\\u{ab8}\\u{afb}\\u{acd}\", \"\\u{ab8}\\u{afb}\"]), (\"\\u{1019}\\u{1039}\\u{1018}\\u{102c}\\u{1037}\",\n        &[\"\\u{1019}\\u{1039}\\u{1018}\", \"\\u{102c}\\u{1037}\"], &[\"\\u{1019}\\u{1039}\", \"\\u{1018}\",\n        \"\\u{102c}\\u{1037}\"]), (\"\\u{1004}\\u{103a}\\u{1039}\\u{1011}\\u{1039}\\u{1011}\",\n        &[\"\\u{1004}\\u{103a}\\u{1039}\\u{1011}\\u{1039}\\u{1011}\"], &[\"\\u{1004}\\u{103a}\\u{1039}\",\n        \"\\u{1011}\\u{1039}\", \"\\u{1011}\"]),\n        (\"\\u{1b12}\\u{1b01}\\u{1b32}\\u{1b44}\\u{1b2f}\\u{1b32}\\u{1b44}\\u{1b22}\\u{1b44}\\u{1b2c}\\u{1b32}\\u{1b44}\\u{1b22}\\u{1b38}\",\n        &[\"\\u{1b12}\\u{1b01}\", \"\\u{1b32}\\u{1b44}\\u{1b2f}\",\n        \"\\u{1b32}\\u{1b44}\\u{1b22}\\u{1b44}\\u{1b2c}\", \"\\u{1b32}\\u{1b44}\\u{1b22}\\u{1b38}\"],\n        &[\"\\u{1b12}\\u{1b01}\", \"\\u{1b32}\\u{1b44}\", \"\\u{1b2f}\", \"\\u{1b32}\\u{1b44}\",\n        \"\\u{1b22}\\u{1b44}\", \"\\u{1b2c}\", \"\\u{1b32}\\u{1b44}\", \"\\u{1b22}\\u{1b38}\"]),\n        (\"\\u{179f}\\u{17d2}\\u{178f}\\u{17d2}\\u{179a}\\u{17b8}\",\n        &[\"\\u{179f}\\u{17d2}\\u{178f}\\u{17d2}\\u{179a}\\u{17b8}\"], &[\"\\u{179f}\\u{17d2}\",\n        \"\\u{178f}\\u{17d2}\", \"\\u{179a}\\u{17b8}\"]), (\"\\u{1b26}\\u{1b17}\\u{1b44}\\u{1b13}\", &[\"\\u{1b26}\",\n        \"\\u{1b17}\\u{1b44}\\u{1b13}\"], &[\"\\u{1b26}\", \"\\u{1b17}\\u{1b44}\", \"\\u{1b13}\"]),\n        (\"\\u{1b27}\\u{1b13}\\u{1b44}\\u{1b0b}\\u{1b0b}\\u{1b04}\", &[\"\\u{1b27}\",\n        \"\\u{1b13}\\u{1b44}\\u{1b0b}\", \"\\u{1b0b}\\u{1b04}\"], &[\"\\u{1b27}\", \"\\u{1b13}\\u{1b44}\",\n        \"\\u{1b0b}\", \"\\u{1b0b}\", \"\\u{1b04}\"]), (\"\\u{1795}\\u{17d2}\\u{17af}\\u{1798}\",\n        &[\"\\u{1795}\\u{17d2}\\u{17af}\", \"\\u{1798}\"], &[\"\\u{1795}\\u{17d2}\", \"\\u{17af}\", \"\\u{1798}\"]),\n        (\"\\u{17a0}\\u{17d2}\\u{17ab}\\u{1791}\\u{17d0}\\u{1799}\", &[\"\\u{17a0}\\u{17d2}\\u{17ab}\",\n        \"\\u{1791}\\u{17d0}\", \"\\u{1799}\"], &[\"\\u{17a0}\\u{17d2}\", \"\\u{17ab}\", \"\\u{1791}\\u{17d0}\",\n        \"\\u{1799}\"])\n    ];\n\n    // official Unicode test data\n    // http://www.unicode.org/Public/17.0.0/ucd/auxiliary/WordBreakTest.txt\n    pub const TEST_WORD: &[(&str, &[&str])] = &[\n        (\"\\u{d}\\u{d}\", &[\"\\u{d}\", \"\\u{d}\"]), (\"\\u{d}\\u{308}\\u{d}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{d}\\u{a}\", &[\"\\u{d}\\u{a}\"]), (\"\\u{d}\\u{308}\\u{a}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{d}\\u{b}\", &[\"\\u{d}\", \"\\u{b}\"]), (\"\\u{d}\\u{308}\\u{b}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{d}\\u{300}\", &[\"\\u{d}\", \"\\u{300}\"]), (\"\\u{d}\\u{308}\\u{300}\", &[\"\\u{d}\",\n        \"\\u{308}\\u{300}\"]), (\"\\u{d}\\u{ad}\", &[\"\\u{d}\", \"\\u{ad}\"]), (\"\\u{d}\\u{308}\\u{ad}\", &[\"\\u{d}\",\n        \"\\u{308}\\u{ad}\"]), (\"\\u{d}\\u{3031}\", &[\"\\u{d}\", \"\\u{3031}\"]), (\"\\u{d}\\u{308}\\u{3031}\",\n        &[\"\\u{d}\", \"\\u{308}\", \"\\u{3031}\"]), (\"\\u{d}\\u{24c2}\", &[\"\\u{d}\", \"\\u{24c2}\"]),\n        (\"\\u{d}\\u{308}\\u{24c2}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{24c2}\"]), (\"\\u{d}\\u{41}\", &[\"\\u{d}\",\n        \"\\u{41}\"]), (\"\\u{d}\\u{308}\\u{41}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{41}\"]), (\"\\u{d}\\u{3a}\",\n        &[\"\\u{d}\", \"\\u{3a}\"]), (\"\\u{d}\\u{308}\\u{3a}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{3a}\"]),\n        (\"\\u{d}\\u{2c}\", &[\"\\u{d}\", \"\\u{2c}\"]), (\"\\u{d}\\u{308}\\u{2c}\", &[\"\\u{d}\", \"\\u{308}\",\n        \"\\u{2c}\"]), (\"\\u{d}\\u{2e}\", &[\"\\u{d}\", \"\\u{2e}\"]), (\"\\u{d}\\u{308}\\u{2e}\", &[\"\\u{d}\",\n        \"\\u{308}\", \"\\u{2e}\"]), (\"\\u{d}\\u{30}\", &[\"\\u{d}\", \"\\u{30}\"]), (\"\\u{d}\\u{308}\\u{30}\",\n        &[\"\\u{d}\", \"\\u{308}\", \"\\u{30}\"]), (\"\\u{d}\\u{5f}\", &[\"\\u{d}\", \"\\u{5f}\"]),\n        (\"\\u{d}\\u{308}\\u{5f}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{5f}\"]), (\"\\u{d}\\u{1f1e6}\", &[\"\\u{d}\",\n        \"\\u{1f1e6}\"]), (\"\\u{d}\\u{308}\\u{1f1e6}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{d}\\u{5d0}\", &[\"\\u{d}\", \"\\u{5d0}\"]), (\"\\u{d}\\u{308}\\u{5d0}\", &[\"\\u{d}\", \"\\u{308}\",\n        \"\\u{5d0}\"]), (\"\\u{d}\\u{22}\", &[\"\\u{d}\", \"\\u{22}\"]), (\"\\u{d}\\u{308}\\u{22}\", &[\"\\u{d}\",\n        \"\\u{308}\", \"\\u{22}\"]), (\"\\u{d}\\u{27}\", &[\"\\u{d}\", \"\\u{27}\"]), (\"\\u{d}\\u{308}\\u{27}\",\n        &[\"\\u{d}\", \"\\u{308}\", \"\\u{27}\"]), (\"\\u{d}\\u{200d}\", &[\"\\u{d}\", \"\\u{200d}\"]),\n        (\"\\u{d}\\u{308}\\u{200d}\", &[\"\\u{d}\", \"\\u{308}\\u{200d}\"]), (\"\\u{d}\\u{a9}\", &[\"\\u{d}\",\n        \"\\u{a9}\"]), (\"\\u{d}\\u{308}\\u{a9}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{a9}\"]), (\"\\u{d}\\u{20}\",\n        &[\"\\u{d}\", \"\\u{20}\"]), (\"\\u{d}\\u{308}\\u{20}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{d}\\u{0}\", &[\"\\u{d}\", \"\\u{0}\"]), (\"\\u{d}\\u{308}\\u{0}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{d}\\u{61}\\u{2060}\", &[\"\\u{d}\", \"\\u{61}\\u{2060}\"]), (\"\\u{d}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{d}\", \"\\u{308}\", \"\\u{61}\\u{2060}\"]), (\"\\u{d}\\u{61}\\u{3a}\", &[\"\\u{d}\", \"\\u{61}\",\n        \"\\u{3a}\"]), (\"\\u{d}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{d}\\u{61}\\u{27}\", &[\"\\u{d}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{d}\\u{308}\\u{61}\\u{27}\",\n        &[\"\\u{d}\", \"\\u{308}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{d}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{d}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{d}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{d}\", \"\\u{308}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{d}\\u{61}\\u{2c}\", &[\"\\u{d}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{d}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{d}\\u{31}\\u{3a}\", &[\"\\u{d}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{d}\\u{308}\\u{31}\\u{3a}\",\n        &[\"\\u{d}\", \"\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{d}\\u{31}\\u{27}\", &[\"\\u{d}\", \"\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{d}\\u{308}\\u{31}\\u{27}\", &[\"\\u{d}\", \"\\u{308}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{d}\\u{31}\\u{2c}\", &[\"\\u{d}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{d}\\u{308}\\u{31}\\u{2c}\",\n        &[\"\\u{d}\", \"\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{d}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{d}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{d}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{d}\", \"\\u{308}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{a}\\u{d}\", &[\"\\u{a}\", \"\\u{d}\"]), (\"\\u{a}\\u{308}\\u{d}\",\n        &[\"\\u{a}\", \"\\u{308}\", \"\\u{d}\"]), (\"\\u{a}\\u{a}\", &[\"\\u{a}\", \"\\u{a}\"]), (\"\\u{a}\\u{308}\\u{a}\",\n        &[\"\\u{a}\", \"\\u{308}\", \"\\u{a}\"]), (\"\\u{a}\\u{b}\", &[\"\\u{a}\", \"\\u{b}\"]), (\"\\u{a}\\u{308}\\u{b}\",\n        &[\"\\u{a}\", \"\\u{308}\", \"\\u{b}\"]), (\"\\u{a}\\u{300}\", &[\"\\u{a}\", \"\\u{300}\"]),\n        (\"\\u{a}\\u{308}\\u{300}\", &[\"\\u{a}\", \"\\u{308}\\u{300}\"]), (\"\\u{a}\\u{ad}\", &[\"\\u{a}\",\n        \"\\u{ad}\"]), (\"\\u{a}\\u{308}\\u{ad}\", &[\"\\u{a}\", \"\\u{308}\\u{ad}\"]), (\"\\u{a}\\u{3031}\",\n        &[\"\\u{a}\", \"\\u{3031}\"]), (\"\\u{a}\\u{308}\\u{3031}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{3031}\"]),\n        (\"\\u{a}\\u{24c2}\", &[\"\\u{a}\", \"\\u{24c2}\"]), (\"\\u{a}\\u{308}\\u{24c2}\", &[\"\\u{a}\", \"\\u{308}\",\n        \"\\u{24c2}\"]), (\"\\u{a}\\u{41}\", &[\"\\u{a}\", \"\\u{41}\"]), (\"\\u{a}\\u{308}\\u{41}\", &[\"\\u{a}\",\n        \"\\u{308}\", \"\\u{41}\"]), (\"\\u{a}\\u{3a}\", &[\"\\u{a}\", \"\\u{3a}\"]), (\"\\u{a}\\u{308}\\u{3a}\",\n        &[\"\\u{a}\", \"\\u{308}\", \"\\u{3a}\"]), (\"\\u{a}\\u{2c}\", &[\"\\u{a}\", \"\\u{2c}\"]),\n        (\"\\u{a}\\u{308}\\u{2c}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{2c}\"]), (\"\\u{a}\\u{2e}\", &[\"\\u{a}\",\n        \"\\u{2e}\"]), (\"\\u{a}\\u{308}\\u{2e}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{2e}\"]), (\"\\u{a}\\u{30}\",\n        &[\"\\u{a}\", \"\\u{30}\"]), (\"\\u{a}\\u{308}\\u{30}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{30}\"]),\n        (\"\\u{a}\\u{5f}\", &[\"\\u{a}\", \"\\u{5f}\"]), (\"\\u{a}\\u{308}\\u{5f}\", &[\"\\u{a}\", \"\\u{308}\",\n        \"\\u{5f}\"]), (\"\\u{a}\\u{1f1e6}\", &[\"\\u{a}\", \"\\u{1f1e6}\"]), (\"\\u{a}\\u{308}\\u{1f1e6}\",\n        &[\"\\u{a}\", \"\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{a}\\u{5d0}\", &[\"\\u{a}\", \"\\u{5d0}\"]),\n        (\"\\u{a}\\u{308}\\u{5d0}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{5d0}\"]), (\"\\u{a}\\u{22}\", &[\"\\u{a}\",\n        \"\\u{22}\"]), (\"\\u{a}\\u{308}\\u{22}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{22}\"]), (\"\\u{a}\\u{27}\",\n        &[\"\\u{a}\", \"\\u{27}\"]), (\"\\u{a}\\u{308}\\u{27}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{27}\"]),\n        (\"\\u{a}\\u{200d}\", &[\"\\u{a}\", \"\\u{200d}\"]), (\"\\u{a}\\u{308}\\u{200d}\", &[\"\\u{a}\",\n        \"\\u{308}\\u{200d}\"]), (\"\\u{a}\\u{a9}\", &[\"\\u{a}\", \"\\u{a9}\"]), (\"\\u{a}\\u{308}\\u{a9}\",\n        &[\"\\u{a}\", \"\\u{308}\", \"\\u{a9}\"]), (\"\\u{a}\\u{20}\", &[\"\\u{a}\", \"\\u{20}\"]),\n        (\"\\u{a}\\u{308}\\u{20}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{20}\"]), (\"\\u{a}\\u{0}\", &[\"\\u{a}\",\n        \"\\u{0}\"]), (\"\\u{a}\\u{308}\\u{0}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{0}\"]), (\"\\u{a}\\u{61}\\u{2060}\",\n        &[\"\\u{a}\", \"\\u{61}\\u{2060}\"]), (\"\\u{a}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{a}\", \"\\u{308}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{a}\\u{61}\\u{3a}\", &[\"\\u{a}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{a}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{a}\\u{61}\\u{27}\", &[\"\\u{a}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{a}\\u{308}\\u{61}\\u{27}\",\n        &[\"\\u{a}\", \"\\u{308}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{a}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{a}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{a}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{a}\", \"\\u{308}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{a}\\u{61}\\u{2c}\", &[\"\\u{a}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{a}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{a}\\u{31}\\u{3a}\", &[\"\\u{a}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{a}\\u{308}\\u{31}\\u{3a}\",\n        &[\"\\u{a}\", \"\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{a}\\u{31}\\u{27}\", &[\"\\u{a}\", \"\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{a}\\u{308}\\u{31}\\u{27}\", &[\"\\u{a}\", \"\\u{308}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{a}\\u{31}\\u{2c}\", &[\"\\u{a}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{a}\\u{308}\\u{31}\\u{2c}\",\n        &[\"\\u{a}\", \"\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{a}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{a}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{a}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{a}\", \"\\u{308}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{b}\\u{d}\", &[\"\\u{b}\", \"\\u{d}\"]), (\"\\u{b}\\u{308}\\u{d}\",\n        &[\"\\u{b}\", \"\\u{308}\", \"\\u{d}\"]), (\"\\u{b}\\u{a}\", &[\"\\u{b}\", \"\\u{a}\"]), (\"\\u{b}\\u{308}\\u{a}\",\n        &[\"\\u{b}\", \"\\u{308}\", \"\\u{a}\"]), (\"\\u{b}\\u{b}\", &[\"\\u{b}\", \"\\u{b}\"]), (\"\\u{b}\\u{308}\\u{b}\",\n        &[\"\\u{b}\", \"\\u{308}\", \"\\u{b}\"]), (\"\\u{b}\\u{300}\", &[\"\\u{b}\", \"\\u{300}\"]),\n        (\"\\u{b}\\u{308}\\u{300}\", &[\"\\u{b}\", \"\\u{308}\\u{300}\"]), (\"\\u{b}\\u{ad}\", &[\"\\u{b}\",\n        \"\\u{ad}\"]), (\"\\u{b}\\u{308}\\u{ad}\", &[\"\\u{b}\", \"\\u{308}\\u{ad}\"]), (\"\\u{b}\\u{3031}\",\n        &[\"\\u{b}\", \"\\u{3031}\"]), (\"\\u{b}\\u{308}\\u{3031}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{3031}\"]),\n        (\"\\u{b}\\u{24c2}\", &[\"\\u{b}\", \"\\u{24c2}\"]), (\"\\u{b}\\u{308}\\u{24c2}\", &[\"\\u{b}\", \"\\u{308}\",\n        \"\\u{24c2}\"]), (\"\\u{b}\\u{41}\", &[\"\\u{b}\", \"\\u{41}\"]), (\"\\u{b}\\u{308}\\u{41}\", &[\"\\u{b}\",\n        \"\\u{308}\", \"\\u{41}\"]), (\"\\u{b}\\u{3a}\", &[\"\\u{b}\", \"\\u{3a}\"]), (\"\\u{b}\\u{308}\\u{3a}\",\n        &[\"\\u{b}\", \"\\u{308}\", \"\\u{3a}\"]), (\"\\u{b}\\u{2c}\", &[\"\\u{b}\", \"\\u{2c}\"]),\n        (\"\\u{b}\\u{308}\\u{2c}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{2c}\"]), (\"\\u{b}\\u{2e}\", &[\"\\u{b}\",\n        \"\\u{2e}\"]), (\"\\u{b}\\u{308}\\u{2e}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{2e}\"]), (\"\\u{b}\\u{30}\",\n        &[\"\\u{b}\", \"\\u{30}\"]), (\"\\u{b}\\u{308}\\u{30}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{30}\"]),\n        (\"\\u{b}\\u{5f}\", &[\"\\u{b}\", \"\\u{5f}\"]), (\"\\u{b}\\u{308}\\u{5f}\", &[\"\\u{b}\", \"\\u{308}\",\n        \"\\u{5f}\"]), (\"\\u{b}\\u{1f1e6}\", &[\"\\u{b}\", \"\\u{1f1e6}\"]), (\"\\u{b}\\u{308}\\u{1f1e6}\",\n        &[\"\\u{b}\", \"\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{b}\\u{5d0}\", &[\"\\u{b}\", \"\\u{5d0}\"]),\n        (\"\\u{b}\\u{308}\\u{5d0}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{5d0}\"]), (\"\\u{b}\\u{22}\", &[\"\\u{b}\",\n        \"\\u{22}\"]), (\"\\u{b}\\u{308}\\u{22}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{22}\"]), (\"\\u{b}\\u{27}\",\n        &[\"\\u{b}\", \"\\u{27}\"]), (\"\\u{b}\\u{308}\\u{27}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{27}\"]),\n        (\"\\u{b}\\u{200d}\", &[\"\\u{b}\", \"\\u{200d}\"]), (\"\\u{b}\\u{308}\\u{200d}\", &[\"\\u{b}\",\n        \"\\u{308}\\u{200d}\"]), (\"\\u{b}\\u{a9}\", &[\"\\u{b}\", \"\\u{a9}\"]), (\"\\u{b}\\u{308}\\u{a9}\",\n        &[\"\\u{b}\", \"\\u{308}\", \"\\u{a9}\"]), (\"\\u{b}\\u{20}\", &[\"\\u{b}\", \"\\u{20}\"]),\n        (\"\\u{b}\\u{308}\\u{20}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{20}\"]), (\"\\u{b}\\u{0}\", &[\"\\u{b}\",\n        \"\\u{0}\"]), (\"\\u{b}\\u{308}\\u{0}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{0}\"]), (\"\\u{b}\\u{61}\\u{2060}\",\n        &[\"\\u{b}\", \"\\u{61}\\u{2060}\"]), (\"\\u{b}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{b}\", \"\\u{308}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{b}\\u{61}\\u{3a}\", &[\"\\u{b}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{b}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{b}\\u{61}\\u{27}\", &[\"\\u{b}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{b}\\u{308}\\u{61}\\u{27}\",\n        &[\"\\u{b}\", \"\\u{308}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{b}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{b}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{b}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{b}\", \"\\u{308}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{b}\\u{61}\\u{2c}\", &[\"\\u{b}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{b}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{b}\\u{31}\\u{3a}\", &[\"\\u{b}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{b}\\u{308}\\u{31}\\u{3a}\",\n        &[\"\\u{b}\", \"\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{b}\\u{31}\\u{27}\", &[\"\\u{b}\", \"\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{b}\\u{308}\\u{31}\\u{27}\", &[\"\\u{b}\", \"\\u{308}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{b}\\u{31}\\u{2c}\", &[\"\\u{b}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{b}\\u{308}\\u{31}\\u{2c}\",\n        &[\"\\u{b}\", \"\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{b}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{b}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{b}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{b}\", \"\\u{308}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{300}\\u{d}\", &[\"\\u{300}\", \"\\u{d}\"]),\n        (\"\\u{300}\\u{308}\\u{d}\", &[\"\\u{300}\\u{308}\", \"\\u{d}\"]), (\"\\u{300}\\u{a}\", &[\"\\u{300}\",\n        \"\\u{a}\"]), (\"\\u{300}\\u{308}\\u{a}\", &[\"\\u{300}\\u{308}\", \"\\u{a}\"]), (\"\\u{300}\\u{b}\",\n        &[\"\\u{300}\", \"\\u{b}\"]), (\"\\u{300}\\u{308}\\u{b}\", &[\"\\u{300}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{300}\\u{300}\", &[\"\\u{300}\\u{300}\"]), (\"\\u{300}\\u{308}\\u{300}\",\n        &[\"\\u{300}\\u{308}\\u{300}\"]), (\"\\u{300}\\u{ad}\", &[\"\\u{300}\\u{ad}\"]), (\"\\u{300}\\u{308}\\u{ad}\",\n        &[\"\\u{300}\\u{308}\\u{ad}\"]), (\"\\u{300}\\u{3031}\", &[\"\\u{300}\", \"\\u{3031}\"]),\n        (\"\\u{300}\\u{308}\\u{3031}\", &[\"\\u{300}\\u{308}\", \"\\u{3031}\"]), (\"\\u{300}\\u{24c2}\",\n        &[\"\\u{300}\", \"\\u{24c2}\"]), (\"\\u{300}\\u{308}\\u{24c2}\", &[\"\\u{300}\\u{308}\", \"\\u{24c2}\"]),\n        (\"\\u{300}\\u{41}\", &[\"\\u{300}\", \"\\u{41}\"]), (\"\\u{300}\\u{308}\\u{41}\", &[\"\\u{300}\\u{308}\",\n        \"\\u{41}\"]), (\"\\u{300}\\u{3a}\", &[\"\\u{300}\", \"\\u{3a}\"]), (\"\\u{300}\\u{308}\\u{3a}\",\n        &[\"\\u{300}\\u{308}\", \"\\u{3a}\"]), (\"\\u{300}\\u{2c}\", &[\"\\u{300}\", \"\\u{2c}\"]),\n        (\"\\u{300}\\u{308}\\u{2c}\", &[\"\\u{300}\\u{308}\", \"\\u{2c}\"]), (\"\\u{300}\\u{2e}\", &[\"\\u{300}\",\n        \"\\u{2e}\"]), (\"\\u{300}\\u{308}\\u{2e}\", &[\"\\u{300}\\u{308}\", \"\\u{2e}\"]), (\"\\u{300}\\u{30}\",\n        &[\"\\u{300}\", \"\\u{30}\"]), (\"\\u{300}\\u{308}\\u{30}\", &[\"\\u{300}\\u{308}\", \"\\u{30}\"]),\n        (\"\\u{300}\\u{5f}\", &[\"\\u{300}\", \"\\u{5f}\"]), (\"\\u{300}\\u{308}\\u{5f}\", &[\"\\u{300}\\u{308}\",\n        \"\\u{5f}\"]), (\"\\u{300}\\u{1f1e6}\", &[\"\\u{300}\", \"\\u{1f1e6}\"]), (\"\\u{300}\\u{308}\\u{1f1e6}\",\n        &[\"\\u{300}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{300}\\u{5d0}\", &[\"\\u{300}\", \"\\u{5d0}\"]),\n        (\"\\u{300}\\u{308}\\u{5d0}\", &[\"\\u{300}\\u{308}\", \"\\u{5d0}\"]), (\"\\u{300}\\u{22}\", &[\"\\u{300}\",\n        \"\\u{22}\"]), (\"\\u{300}\\u{308}\\u{22}\", &[\"\\u{300}\\u{308}\", \"\\u{22}\"]), (\"\\u{300}\\u{27}\",\n        &[\"\\u{300}\", \"\\u{27}\"]), (\"\\u{300}\\u{308}\\u{27}\", &[\"\\u{300}\\u{308}\", \"\\u{27}\"]),\n        (\"\\u{300}\\u{200d}\", &[\"\\u{300}\\u{200d}\"]), (\"\\u{300}\\u{308}\\u{200d}\",\n        &[\"\\u{300}\\u{308}\\u{200d}\"]), (\"\\u{300}\\u{a9}\", &[\"\\u{300}\", \"\\u{a9}\"]),\n        (\"\\u{300}\\u{308}\\u{a9}\", &[\"\\u{300}\\u{308}\", \"\\u{a9}\"]), (\"\\u{300}\\u{20}\", &[\"\\u{300}\",\n        \"\\u{20}\"]), (\"\\u{300}\\u{308}\\u{20}\", &[\"\\u{300}\\u{308}\", \"\\u{20}\"]), (\"\\u{300}\\u{0}\",\n        &[\"\\u{300}\", \"\\u{0}\"]), (\"\\u{300}\\u{308}\\u{0}\", &[\"\\u{300}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{300}\\u{61}\\u{2060}\", &[\"\\u{300}\", \"\\u{61}\\u{2060}\"]), (\"\\u{300}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{300}\\u{308}\", \"\\u{61}\\u{2060}\"]), (\"\\u{300}\\u{61}\\u{3a}\", &[\"\\u{300}\", \"\\u{61}\",\n        \"\\u{3a}\"]), (\"\\u{300}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{300}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{300}\\u{61}\\u{27}\", &[\"\\u{300}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{300}\\u{308}\\u{61}\\u{27}\",\n        &[\"\\u{300}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{300}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{300}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{300}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{300}\\u{308}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{300}\\u{61}\\u{2c}\", &[\"\\u{300}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{300}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{300}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{300}\\u{31}\\u{3a}\", &[\"\\u{300}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{300}\\u{308}\\u{31}\\u{3a}\",\n        &[\"\\u{300}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{300}\\u{31}\\u{27}\", &[\"\\u{300}\", \"\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{300}\\u{308}\\u{31}\\u{27}\", &[\"\\u{300}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{300}\\u{31}\\u{2c}\", &[\"\\u{300}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{300}\\u{308}\\u{31}\\u{2c}\",\n        &[\"\\u{300}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{300}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{300}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{300}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{300}\\u{308}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{ad}\\u{d}\", &[\"\\u{ad}\", \"\\u{d}\"]), (\"\\u{ad}\\u{308}\\u{d}\",\n        &[\"\\u{ad}\\u{308}\", \"\\u{d}\"]), (\"\\u{ad}\\u{a}\", &[\"\\u{ad}\", \"\\u{a}\"]), (\"\\u{ad}\\u{308}\\u{a}\",\n        &[\"\\u{ad}\\u{308}\", \"\\u{a}\"]), (\"\\u{ad}\\u{b}\", &[\"\\u{ad}\", \"\\u{b}\"]), (\"\\u{ad}\\u{308}\\u{b}\",\n        &[\"\\u{ad}\\u{308}\", \"\\u{b}\"]), (\"\\u{ad}\\u{300}\", &[\"\\u{ad}\\u{300}\"]),\n        (\"\\u{ad}\\u{308}\\u{300}\", &[\"\\u{ad}\\u{308}\\u{300}\"]), (\"\\u{ad}\\u{ad}\", &[\"\\u{ad}\\u{ad}\"]),\n        (\"\\u{ad}\\u{308}\\u{ad}\", &[\"\\u{ad}\\u{308}\\u{ad}\"]), (\"\\u{ad}\\u{3031}\", &[\"\\u{ad}\",\n        \"\\u{3031}\"]), (\"\\u{ad}\\u{308}\\u{3031}\", &[\"\\u{ad}\\u{308}\", \"\\u{3031}\"]), (\"\\u{ad}\\u{24c2}\",\n        &[\"\\u{ad}\", \"\\u{24c2}\"]), (\"\\u{ad}\\u{308}\\u{24c2}\", &[\"\\u{ad}\\u{308}\", \"\\u{24c2}\"]),\n        (\"\\u{ad}\\u{41}\", &[\"\\u{ad}\", \"\\u{41}\"]), (\"\\u{ad}\\u{308}\\u{41}\", &[\"\\u{ad}\\u{308}\",\n        \"\\u{41}\"]), (\"\\u{ad}\\u{3a}\", &[\"\\u{ad}\", \"\\u{3a}\"]), (\"\\u{ad}\\u{308}\\u{3a}\",\n        &[\"\\u{ad}\\u{308}\", \"\\u{3a}\"]), (\"\\u{ad}\\u{2c}\", &[\"\\u{ad}\", \"\\u{2c}\"]),\n        (\"\\u{ad}\\u{308}\\u{2c}\", &[\"\\u{ad}\\u{308}\", \"\\u{2c}\"]), (\"\\u{ad}\\u{2e}\", &[\"\\u{ad}\",\n        \"\\u{2e}\"]), (\"\\u{ad}\\u{308}\\u{2e}\", &[\"\\u{ad}\\u{308}\", \"\\u{2e}\"]), (\"\\u{ad}\\u{30}\",\n        &[\"\\u{ad}\", \"\\u{30}\"]), (\"\\u{ad}\\u{308}\\u{30}\", &[\"\\u{ad}\\u{308}\", \"\\u{30}\"]),\n        (\"\\u{ad}\\u{5f}\", &[\"\\u{ad}\", \"\\u{5f}\"]), (\"\\u{ad}\\u{308}\\u{5f}\", &[\"\\u{ad}\\u{308}\",\n        \"\\u{5f}\"]), (\"\\u{ad}\\u{1f1e6}\", &[\"\\u{ad}\", \"\\u{1f1e6}\"]), (\"\\u{ad}\\u{308}\\u{1f1e6}\",\n        &[\"\\u{ad}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{ad}\\u{5d0}\", &[\"\\u{ad}\", \"\\u{5d0}\"]),\n        (\"\\u{ad}\\u{308}\\u{5d0}\", &[\"\\u{ad}\\u{308}\", \"\\u{5d0}\"]), (\"\\u{ad}\\u{22}\", &[\"\\u{ad}\",\n        \"\\u{22}\"]), (\"\\u{ad}\\u{308}\\u{22}\", &[\"\\u{ad}\\u{308}\", \"\\u{22}\"]), (\"\\u{ad}\\u{27}\",\n        &[\"\\u{ad}\", \"\\u{27}\"]), (\"\\u{ad}\\u{308}\\u{27}\", &[\"\\u{ad}\\u{308}\", \"\\u{27}\"]),\n        (\"\\u{ad}\\u{200d}\", &[\"\\u{ad}\\u{200d}\"]), (\"\\u{ad}\\u{308}\\u{200d}\",\n        &[\"\\u{ad}\\u{308}\\u{200d}\"]), (\"\\u{ad}\\u{a9}\", &[\"\\u{ad}\", \"\\u{a9}\"]),\n        (\"\\u{ad}\\u{308}\\u{a9}\", &[\"\\u{ad}\\u{308}\", \"\\u{a9}\"]), (\"\\u{ad}\\u{20}\", &[\"\\u{ad}\",\n        \"\\u{20}\"]), (\"\\u{ad}\\u{308}\\u{20}\", &[\"\\u{ad}\\u{308}\", \"\\u{20}\"]), (\"\\u{ad}\\u{0}\",\n        &[\"\\u{ad}\", \"\\u{0}\"]), (\"\\u{ad}\\u{308}\\u{0}\", &[\"\\u{ad}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{ad}\\u{61}\\u{2060}\", &[\"\\u{ad}\", \"\\u{61}\\u{2060}\"]), (\"\\u{ad}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{ad}\\u{308}\", \"\\u{61}\\u{2060}\"]), (\"\\u{ad}\\u{61}\\u{3a}\", &[\"\\u{ad}\", \"\\u{61}\",\n        \"\\u{3a}\"]), (\"\\u{ad}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{ad}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{ad}\\u{61}\\u{27}\", &[\"\\u{ad}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{ad}\\u{308}\\u{61}\\u{27}\",\n        &[\"\\u{ad}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{ad}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{ad}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{ad}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{ad}\\u{308}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{ad}\\u{61}\\u{2c}\", &[\"\\u{ad}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{ad}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{ad}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{ad}\\u{31}\\u{3a}\", &[\"\\u{ad}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{ad}\\u{308}\\u{31}\\u{3a}\",\n        &[\"\\u{ad}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{ad}\\u{31}\\u{27}\", &[\"\\u{ad}\", \"\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{ad}\\u{308}\\u{31}\\u{27}\", &[\"\\u{ad}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{ad}\\u{31}\\u{2c}\", &[\"\\u{ad}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{ad}\\u{308}\\u{31}\\u{2c}\",\n        &[\"\\u{ad}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{ad}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{ad}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{ad}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{ad}\\u{308}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{3031}\\u{d}\", &[\"\\u{3031}\", \"\\u{d}\"]),\n        (\"\\u{3031}\\u{308}\\u{d}\", &[\"\\u{3031}\\u{308}\", \"\\u{d}\"]), (\"\\u{3031}\\u{a}\", &[\"\\u{3031}\",\n        \"\\u{a}\"]), (\"\\u{3031}\\u{308}\\u{a}\", &[\"\\u{3031}\\u{308}\", \"\\u{a}\"]), (\"\\u{3031}\\u{b}\",\n        &[\"\\u{3031}\", \"\\u{b}\"]), (\"\\u{3031}\\u{308}\\u{b}\", &[\"\\u{3031}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{3031}\\u{300}\", &[\"\\u{3031}\\u{300}\"]), (\"\\u{3031}\\u{308}\\u{300}\",\n        &[\"\\u{3031}\\u{308}\\u{300}\"]), (\"\\u{3031}\\u{ad}\", &[\"\\u{3031}\\u{ad}\"]),\n        (\"\\u{3031}\\u{308}\\u{ad}\", &[\"\\u{3031}\\u{308}\\u{ad}\"]), (\"\\u{3031}\\u{3031}\",\n        &[\"\\u{3031}\\u{3031}\"]), (\"\\u{3031}\\u{308}\\u{3031}\", &[\"\\u{3031}\\u{308}\\u{3031}\"]),\n        (\"\\u{3031}\\u{24c2}\", &[\"\\u{3031}\", \"\\u{24c2}\"]), (\"\\u{3031}\\u{308}\\u{24c2}\",\n        &[\"\\u{3031}\\u{308}\", \"\\u{24c2}\"]), (\"\\u{3031}\\u{41}\", &[\"\\u{3031}\", \"\\u{41}\"]),\n        (\"\\u{3031}\\u{308}\\u{41}\", &[\"\\u{3031}\\u{308}\", \"\\u{41}\"]), (\"\\u{3031}\\u{3a}\", &[\"\\u{3031}\",\n        \"\\u{3a}\"]), (\"\\u{3031}\\u{308}\\u{3a}\", &[\"\\u{3031}\\u{308}\", \"\\u{3a}\"]), (\"\\u{3031}\\u{2c}\",\n        &[\"\\u{3031}\", \"\\u{2c}\"]), (\"\\u{3031}\\u{308}\\u{2c}\", &[\"\\u{3031}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{3031}\\u{2e}\", &[\"\\u{3031}\", \"\\u{2e}\"]), (\"\\u{3031}\\u{308}\\u{2e}\", &[\"\\u{3031}\\u{308}\",\n        \"\\u{2e}\"]), (\"\\u{3031}\\u{30}\", &[\"\\u{3031}\", \"\\u{30}\"]), (\"\\u{3031}\\u{308}\\u{30}\",\n        &[\"\\u{3031}\\u{308}\", \"\\u{30}\"]), (\"\\u{3031}\\u{5f}\", &[\"\\u{3031}\\u{5f}\"]),\n        (\"\\u{3031}\\u{308}\\u{5f}\", &[\"\\u{3031}\\u{308}\\u{5f}\"]), (\"\\u{3031}\\u{1f1e6}\", &[\"\\u{3031}\",\n        \"\\u{1f1e6}\"]), (\"\\u{3031}\\u{308}\\u{1f1e6}\", &[\"\\u{3031}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{3031}\\u{5d0}\", &[\"\\u{3031}\", \"\\u{5d0}\"]), (\"\\u{3031}\\u{308}\\u{5d0}\",\n        &[\"\\u{3031}\\u{308}\", \"\\u{5d0}\"]), (\"\\u{3031}\\u{22}\", &[\"\\u{3031}\", \"\\u{22}\"]),\n        (\"\\u{3031}\\u{308}\\u{22}\", &[\"\\u{3031}\\u{308}\", \"\\u{22}\"]), (\"\\u{3031}\\u{27}\", &[\"\\u{3031}\",\n        \"\\u{27}\"]), (\"\\u{3031}\\u{308}\\u{27}\", &[\"\\u{3031}\\u{308}\", \"\\u{27}\"]), (\"\\u{3031}\\u{200d}\",\n        &[\"\\u{3031}\\u{200d}\"]), (\"\\u{3031}\\u{308}\\u{200d}\", &[\"\\u{3031}\\u{308}\\u{200d}\"]),\n        (\"\\u{3031}\\u{a9}\", &[\"\\u{3031}\", \"\\u{a9}\"]), (\"\\u{3031}\\u{308}\\u{a9}\", &[\"\\u{3031}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{3031}\\u{20}\", &[\"\\u{3031}\", \"\\u{20}\"]), (\"\\u{3031}\\u{308}\\u{20}\",\n        &[\"\\u{3031}\\u{308}\", \"\\u{20}\"]), (\"\\u{3031}\\u{0}\", &[\"\\u{3031}\", \"\\u{0}\"]),\n        (\"\\u{3031}\\u{308}\\u{0}\", &[\"\\u{3031}\\u{308}\", \"\\u{0}\"]), (\"\\u{3031}\\u{61}\\u{2060}\",\n        &[\"\\u{3031}\", \"\\u{61}\\u{2060}\"]), (\"\\u{3031}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{3031}\\u{308}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{3031}\\u{61}\\u{3a}\", &[\"\\u{3031}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{3031}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{3031}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{3031}\\u{61}\\u{27}\", &[\"\\u{3031}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{3031}\\u{308}\\u{61}\\u{27}\",\n        &[\"\\u{3031}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{3031}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{3031}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{3031}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{3031}\\u{308}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{3031}\\u{61}\\u{2c}\", &[\"\\u{3031}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{3031}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{3031}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{3031}\\u{31}\\u{3a}\", &[\"\\u{3031}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{3031}\\u{308}\\u{31}\\u{3a}\",\n        &[\"\\u{3031}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{3031}\\u{31}\\u{27}\", &[\"\\u{3031}\", \"\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{3031}\\u{308}\\u{31}\\u{27}\", &[\"\\u{3031}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{3031}\\u{31}\\u{2c}\", &[\"\\u{3031}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{3031}\\u{308}\\u{31}\\u{2c}\",\n        &[\"\\u{3031}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]), (\"\\u{3031}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{3031}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{3031}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{3031}\\u{308}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{24c2}\\u{d}\", &[\"\\u{24c2}\", \"\\u{d}\"]),\n        (\"\\u{24c2}\\u{308}\\u{d}\", &[\"\\u{24c2}\\u{308}\", \"\\u{d}\"]), (\"\\u{24c2}\\u{a}\", &[\"\\u{24c2}\",\n        \"\\u{a}\"]), (\"\\u{24c2}\\u{308}\\u{a}\", &[\"\\u{24c2}\\u{308}\", \"\\u{a}\"]), (\"\\u{24c2}\\u{b}\",\n        &[\"\\u{24c2}\", \"\\u{b}\"]), (\"\\u{24c2}\\u{308}\\u{b}\", &[\"\\u{24c2}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{24c2}\\u{300}\", &[\"\\u{24c2}\\u{300}\"]), (\"\\u{24c2}\\u{308}\\u{300}\",\n        &[\"\\u{24c2}\\u{308}\\u{300}\"]), (\"\\u{24c2}\\u{ad}\", &[\"\\u{24c2}\\u{ad}\"]),\n        (\"\\u{24c2}\\u{308}\\u{ad}\", &[\"\\u{24c2}\\u{308}\\u{ad}\"]), (\"\\u{24c2}\\u{3031}\", &[\"\\u{24c2}\",\n        \"\\u{3031}\"]), (\"\\u{24c2}\\u{308}\\u{3031}\", &[\"\\u{24c2}\\u{308}\", \"\\u{3031}\"]),\n        (\"\\u{24c2}\\u{24c2}\", &[\"\\u{24c2}\\u{24c2}\"]), (\"\\u{24c2}\\u{308}\\u{24c2}\",\n        &[\"\\u{24c2}\\u{308}\\u{24c2}\"]), (\"\\u{24c2}\\u{41}\", &[\"\\u{24c2}\\u{41}\"]),\n        (\"\\u{24c2}\\u{308}\\u{41}\", &[\"\\u{24c2}\\u{308}\\u{41}\"]), (\"\\u{24c2}\\u{3a}\", &[\"\\u{24c2}\",\n        \"\\u{3a}\"]), (\"\\u{24c2}\\u{308}\\u{3a}\", &[\"\\u{24c2}\\u{308}\", \"\\u{3a}\"]), (\"\\u{24c2}\\u{2c}\",\n        &[\"\\u{24c2}\", \"\\u{2c}\"]), (\"\\u{24c2}\\u{308}\\u{2c}\", &[\"\\u{24c2}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{24c2}\\u{2e}\", &[\"\\u{24c2}\", \"\\u{2e}\"]), (\"\\u{24c2}\\u{308}\\u{2e}\", &[\"\\u{24c2}\\u{308}\",\n        \"\\u{2e}\"]), (\"\\u{24c2}\\u{30}\", &[\"\\u{24c2}\\u{30}\"]), (\"\\u{24c2}\\u{308}\\u{30}\",\n        &[\"\\u{24c2}\\u{308}\\u{30}\"]), (\"\\u{24c2}\\u{5f}\", &[\"\\u{24c2}\\u{5f}\"]),\n        (\"\\u{24c2}\\u{308}\\u{5f}\", &[\"\\u{24c2}\\u{308}\\u{5f}\"]), (\"\\u{24c2}\\u{1f1e6}\", &[\"\\u{24c2}\",\n        \"\\u{1f1e6}\"]), (\"\\u{24c2}\\u{308}\\u{1f1e6}\", &[\"\\u{24c2}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{24c2}\\u{5d0}\", &[\"\\u{24c2}\\u{5d0}\"]), (\"\\u{24c2}\\u{308}\\u{5d0}\",\n        &[\"\\u{24c2}\\u{308}\\u{5d0}\"]), (\"\\u{24c2}\\u{22}\", &[\"\\u{24c2}\", \"\\u{22}\"]),\n        (\"\\u{24c2}\\u{308}\\u{22}\", &[\"\\u{24c2}\\u{308}\", \"\\u{22}\"]), (\"\\u{24c2}\\u{27}\", &[\"\\u{24c2}\",\n        \"\\u{27}\"]), (\"\\u{24c2}\\u{308}\\u{27}\", &[\"\\u{24c2}\\u{308}\", \"\\u{27}\"]), (\"\\u{24c2}\\u{200d}\",\n        &[\"\\u{24c2}\\u{200d}\"]), (\"\\u{24c2}\\u{308}\\u{200d}\", &[\"\\u{24c2}\\u{308}\\u{200d}\"]),\n        (\"\\u{24c2}\\u{a9}\", &[\"\\u{24c2}\", \"\\u{a9}\"]), (\"\\u{24c2}\\u{308}\\u{a9}\", &[\"\\u{24c2}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{24c2}\\u{20}\", &[\"\\u{24c2}\", \"\\u{20}\"]), (\"\\u{24c2}\\u{308}\\u{20}\",\n        &[\"\\u{24c2}\\u{308}\", \"\\u{20}\"]), (\"\\u{24c2}\\u{0}\", &[\"\\u{24c2}\", \"\\u{0}\"]),\n        (\"\\u{24c2}\\u{308}\\u{0}\", &[\"\\u{24c2}\\u{308}\", \"\\u{0}\"]), (\"\\u{24c2}\\u{61}\\u{2060}\",\n        &[\"\\u{24c2}\\u{61}\\u{2060}\"]), (\"\\u{24c2}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{24c2}\\u{308}\\u{61}\\u{2060}\"]), (\"\\u{24c2}\\u{61}\\u{3a}\", &[\"\\u{24c2}\\u{61}\",\n        \"\\u{3a}\"]), (\"\\u{24c2}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{24c2}\\u{308}\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{24c2}\\u{61}\\u{27}\", &[\"\\u{24c2}\\u{61}\", \"\\u{27}\"]), (\"\\u{24c2}\\u{308}\\u{61}\\u{27}\",\n        &[\"\\u{24c2}\\u{308}\\u{61}\", \"\\u{27}\"]), (\"\\u{24c2}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{24c2}\\u{61}\",\n        \"\\u{27}\\u{2060}\"]), (\"\\u{24c2}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{24c2}\\u{308}\\u{61}\",\n        \"\\u{27}\\u{2060}\"]), (\"\\u{24c2}\\u{61}\\u{2c}\", &[\"\\u{24c2}\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{24c2}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{24c2}\\u{308}\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{24c2}\\u{31}\\u{3a}\", &[\"\\u{24c2}\\u{31}\", \"\\u{3a}\"]), (\"\\u{24c2}\\u{308}\\u{31}\\u{3a}\",\n        &[\"\\u{24c2}\\u{308}\\u{31}\", \"\\u{3a}\"]), (\"\\u{24c2}\\u{31}\\u{27}\", &[\"\\u{24c2}\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{24c2}\\u{308}\\u{31}\\u{27}\", &[\"\\u{24c2}\\u{308}\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{24c2}\\u{31}\\u{2c}\", &[\"\\u{24c2}\\u{31}\", \"\\u{2c}\"]), (\"\\u{24c2}\\u{308}\\u{31}\\u{2c}\",\n        &[\"\\u{24c2}\\u{308}\\u{31}\", \"\\u{2c}\"]), (\"\\u{24c2}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{24c2}\\u{31}\",\n        \"\\u{2e}\\u{2060}\"]), (\"\\u{24c2}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{24c2}\\u{308}\\u{31}\",\n        \"\\u{2e}\\u{2060}\"]), (\"\\u{41}\\u{d}\", &[\"\\u{41}\", \"\\u{d}\"]), (\"\\u{41}\\u{308}\\u{d}\",\n        &[\"\\u{41}\\u{308}\", \"\\u{d}\"]), (\"\\u{41}\\u{a}\", &[\"\\u{41}\", \"\\u{a}\"]), (\"\\u{41}\\u{308}\\u{a}\",\n        &[\"\\u{41}\\u{308}\", \"\\u{a}\"]), (\"\\u{41}\\u{b}\", &[\"\\u{41}\", \"\\u{b}\"]), (\"\\u{41}\\u{308}\\u{b}\",\n        &[\"\\u{41}\\u{308}\", \"\\u{b}\"]), (\"\\u{41}\\u{300}\", &[\"\\u{41}\\u{300}\"]),\n        (\"\\u{41}\\u{308}\\u{300}\", &[\"\\u{41}\\u{308}\\u{300}\"]), (\"\\u{41}\\u{ad}\", &[\"\\u{41}\\u{ad}\"]),\n        (\"\\u{41}\\u{308}\\u{ad}\", &[\"\\u{41}\\u{308}\\u{ad}\"]), (\"\\u{41}\\u{3031}\", &[\"\\u{41}\",\n        \"\\u{3031}\"]), (\"\\u{41}\\u{308}\\u{3031}\", &[\"\\u{41}\\u{308}\", \"\\u{3031}\"]), (\"\\u{41}\\u{24c2}\",\n        &[\"\\u{41}\\u{24c2}\"]), (\"\\u{41}\\u{308}\\u{24c2}\", &[\"\\u{41}\\u{308}\\u{24c2}\"]),\n        (\"\\u{41}\\u{41}\", &[\"\\u{41}\\u{41}\"]), (\"\\u{41}\\u{308}\\u{41}\", &[\"\\u{41}\\u{308}\\u{41}\"]),\n        (\"\\u{41}\\u{3a}\", &[\"\\u{41}\", \"\\u{3a}\"]), (\"\\u{41}\\u{308}\\u{3a}\", &[\"\\u{41}\\u{308}\",\n        \"\\u{3a}\"]), (\"\\u{41}\\u{2c}\", &[\"\\u{41}\", \"\\u{2c}\"]), (\"\\u{41}\\u{308}\\u{2c}\",\n        &[\"\\u{41}\\u{308}\", \"\\u{2c}\"]), (\"\\u{41}\\u{2e}\", &[\"\\u{41}\", \"\\u{2e}\"]),\n        (\"\\u{41}\\u{308}\\u{2e}\", &[\"\\u{41}\\u{308}\", \"\\u{2e}\"]), (\"\\u{41}\\u{30}\", &[\"\\u{41}\\u{30}\"]),\n        (\"\\u{41}\\u{308}\\u{30}\", &[\"\\u{41}\\u{308}\\u{30}\"]), (\"\\u{41}\\u{5f}\", &[\"\\u{41}\\u{5f}\"]),\n        (\"\\u{41}\\u{308}\\u{5f}\", &[\"\\u{41}\\u{308}\\u{5f}\"]), (\"\\u{41}\\u{1f1e6}\", &[\"\\u{41}\",\n        \"\\u{1f1e6}\"]), (\"\\u{41}\\u{308}\\u{1f1e6}\", &[\"\\u{41}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{41}\\u{5d0}\", &[\"\\u{41}\\u{5d0}\"]), (\"\\u{41}\\u{308}\\u{5d0}\", &[\"\\u{41}\\u{308}\\u{5d0}\"]),\n        (\"\\u{41}\\u{22}\", &[\"\\u{41}\", \"\\u{22}\"]), (\"\\u{41}\\u{308}\\u{22}\", &[\"\\u{41}\\u{308}\",\n        \"\\u{22}\"]), (\"\\u{41}\\u{27}\", &[\"\\u{41}\", \"\\u{27}\"]), (\"\\u{41}\\u{308}\\u{27}\",\n        &[\"\\u{41}\\u{308}\", \"\\u{27}\"]), (\"\\u{41}\\u{200d}\", &[\"\\u{41}\\u{200d}\"]),\n        (\"\\u{41}\\u{308}\\u{200d}\", &[\"\\u{41}\\u{308}\\u{200d}\"]), (\"\\u{41}\\u{a9}\", &[\"\\u{41}\",\n        \"\\u{a9}\"]), (\"\\u{41}\\u{308}\\u{a9}\", &[\"\\u{41}\\u{308}\", \"\\u{a9}\"]), (\"\\u{41}\\u{20}\",\n        &[\"\\u{41}\", \"\\u{20}\"]), (\"\\u{41}\\u{308}\\u{20}\", &[\"\\u{41}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{41}\\u{0}\", &[\"\\u{41}\", \"\\u{0}\"]), (\"\\u{41}\\u{308}\\u{0}\", &[\"\\u{41}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{41}\\u{61}\\u{2060}\", &[\"\\u{41}\\u{61}\\u{2060}\"]), (\"\\u{41}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{41}\\u{308}\\u{61}\\u{2060}\"]), (\"\\u{41}\\u{61}\\u{3a}\", &[\"\\u{41}\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{41}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{41}\\u{308}\\u{61}\", \"\\u{3a}\"]), (\"\\u{41}\\u{61}\\u{27}\",\n        &[\"\\u{41}\\u{61}\", \"\\u{27}\"]), (\"\\u{41}\\u{308}\\u{61}\\u{27}\", &[\"\\u{41}\\u{308}\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{41}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{41}\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{41}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{41}\\u{308}\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{41}\\u{61}\\u{2c}\", &[\"\\u{41}\\u{61}\", \"\\u{2c}\"]), (\"\\u{41}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{41}\\u{308}\\u{61}\", \"\\u{2c}\"]), (\"\\u{41}\\u{31}\\u{3a}\", &[\"\\u{41}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{41}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{41}\\u{308}\\u{31}\", \"\\u{3a}\"]), (\"\\u{41}\\u{31}\\u{27}\",\n        &[\"\\u{41}\\u{31}\", \"\\u{27}\"]), (\"\\u{41}\\u{308}\\u{31}\\u{27}\", &[\"\\u{41}\\u{308}\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{41}\\u{31}\\u{2c}\", &[\"\\u{41}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{41}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{41}\\u{308}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{41}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{41}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{41}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{41}\\u{308}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{3a}\\u{d}\", &[\"\\u{3a}\", \"\\u{d}\"]), (\"\\u{3a}\\u{308}\\u{d}\", &[\"\\u{3a}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{3a}\\u{a}\", &[\"\\u{3a}\", \"\\u{a}\"]), (\"\\u{3a}\\u{308}\\u{a}\", &[\"\\u{3a}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{3a}\\u{b}\", &[\"\\u{3a}\", \"\\u{b}\"]), (\"\\u{3a}\\u{308}\\u{b}\", &[\"\\u{3a}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{3a}\\u{300}\", &[\"\\u{3a}\\u{300}\"]), (\"\\u{3a}\\u{308}\\u{300}\", &[\"\\u{3a}\\u{308}\\u{300}\"]),\n        (\"\\u{3a}\\u{ad}\", &[\"\\u{3a}\\u{ad}\"]), (\"\\u{3a}\\u{308}\\u{ad}\", &[\"\\u{3a}\\u{308}\\u{ad}\"]),\n        (\"\\u{3a}\\u{3031}\", &[\"\\u{3a}\", \"\\u{3031}\"]), (\"\\u{3a}\\u{308}\\u{3031}\", &[\"\\u{3a}\\u{308}\",\n        \"\\u{3031}\"]), (\"\\u{3a}\\u{24c2}\", &[\"\\u{3a}\", \"\\u{24c2}\"]), (\"\\u{3a}\\u{308}\\u{24c2}\",\n        &[\"\\u{3a}\\u{308}\", \"\\u{24c2}\"]), (\"\\u{3a}\\u{41}\", &[\"\\u{3a}\", \"\\u{41}\"]),\n        (\"\\u{3a}\\u{308}\\u{41}\", &[\"\\u{3a}\\u{308}\", \"\\u{41}\"]), (\"\\u{3a}\\u{3a}\", &[\"\\u{3a}\",\n        \"\\u{3a}\"]), (\"\\u{3a}\\u{308}\\u{3a}\", &[\"\\u{3a}\\u{308}\", \"\\u{3a}\"]), (\"\\u{3a}\\u{2c}\",\n        &[\"\\u{3a}\", \"\\u{2c}\"]), (\"\\u{3a}\\u{308}\\u{2c}\", &[\"\\u{3a}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{3a}\\u{2e}\", &[\"\\u{3a}\", \"\\u{2e}\"]), (\"\\u{3a}\\u{308}\\u{2e}\", &[\"\\u{3a}\\u{308}\",\n        \"\\u{2e}\"]), (\"\\u{3a}\\u{30}\", &[\"\\u{3a}\", \"\\u{30}\"]), (\"\\u{3a}\\u{308}\\u{30}\",\n        &[\"\\u{3a}\\u{308}\", \"\\u{30}\"]), (\"\\u{3a}\\u{5f}\", &[\"\\u{3a}\", \"\\u{5f}\"]),\n        (\"\\u{3a}\\u{308}\\u{5f}\", &[\"\\u{3a}\\u{308}\", \"\\u{5f}\"]), (\"\\u{3a}\\u{1f1e6}\", &[\"\\u{3a}\",\n        \"\\u{1f1e6}\"]), (\"\\u{3a}\\u{308}\\u{1f1e6}\", &[\"\\u{3a}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{3a}\\u{5d0}\", &[\"\\u{3a}\", \"\\u{5d0}\"]), (\"\\u{3a}\\u{308}\\u{5d0}\", &[\"\\u{3a}\\u{308}\",\n        \"\\u{5d0}\"]), (\"\\u{3a}\\u{22}\", &[\"\\u{3a}\", \"\\u{22}\"]), (\"\\u{3a}\\u{308}\\u{22}\",\n        &[\"\\u{3a}\\u{308}\", \"\\u{22}\"]), (\"\\u{3a}\\u{27}\", &[\"\\u{3a}\", \"\\u{27}\"]),\n        (\"\\u{3a}\\u{308}\\u{27}\", &[\"\\u{3a}\\u{308}\", \"\\u{27}\"]), (\"\\u{3a}\\u{200d}\",\n        &[\"\\u{3a}\\u{200d}\"]), (\"\\u{3a}\\u{308}\\u{200d}\", &[\"\\u{3a}\\u{308}\\u{200d}\"]),\n        (\"\\u{3a}\\u{a9}\", &[\"\\u{3a}\", \"\\u{a9}\"]), (\"\\u{3a}\\u{308}\\u{a9}\", &[\"\\u{3a}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{3a}\\u{20}\", &[\"\\u{3a}\", \"\\u{20}\"]), (\"\\u{3a}\\u{308}\\u{20}\",\n        &[\"\\u{3a}\\u{308}\", \"\\u{20}\"]), (\"\\u{3a}\\u{0}\", &[\"\\u{3a}\", \"\\u{0}\"]), (\"\\u{3a}\\u{308}\\u{0}\",\n        &[\"\\u{3a}\\u{308}\", \"\\u{0}\"]), (\"\\u{3a}\\u{61}\\u{2060}\", &[\"\\u{3a}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{3a}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{3a}\\u{308}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{3a}\\u{61}\\u{3a}\", &[\"\\u{3a}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{3a}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{3a}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{3a}\\u{61}\\u{27}\", &[\"\\u{3a}\", \"\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{3a}\\u{308}\\u{61}\\u{27}\", &[\"\\u{3a}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{3a}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{3a}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{3a}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{3a}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{3a}\\u{61}\\u{2c}\", &[\"\\u{3a}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{3a}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{3a}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{3a}\\u{31}\\u{3a}\", &[\"\\u{3a}\", \"\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{3a}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{3a}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{3a}\\u{31}\\u{27}\", &[\"\\u{3a}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{3a}\\u{308}\\u{31}\\u{27}\",\n        &[\"\\u{3a}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{3a}\\u{31}\\u{2c}\", &[\"\\u{3a}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{3a}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{3a}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{3a}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{3a}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{3a}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{3a}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{2c}\\u{d}\", &[\"\\u{2c}\", \"\\u{d}\"]), (\"\\u{2c}\\u{308}\\u{d}\", &[\"\\u{2c}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{2c}\\u{a}\", &[\"\\u{2c}\", \"\\u{a}\"]), (\"\\u{2c}\\u{308}\\u{a}\", &[\"\\u{2c}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{2c}\\u{b}\", &[\"\\u{2c}\", \"\\u{b}\"]), (\"\\u{2c}\\u{308}\\u{b}\", &[\"\\u{2c}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{2c}\\u{300}\", &[\"\\u{2c}\\u{300}\"]), (\"\\u{2c}\\u{308}\\u{300}\", &[\"\\u{2c}\\u{308}\\u{300}\"]),\n        (\"\\u{2c}\\u{ad}\", &[\"\\u{2c}\\u{ad}\"]), (\"\\u{2c}\\u{308}\\u{ad}\", &[\"\\u{2c}\\u{308}\\u{ad}\"]),\n        (\"\\u{2c}\\u{3031}\", &[\"\\u{2c}\", \"\\u{3031}\"]), (\"\\u{2c}\\u{308}\\u{3031}\", &[\"\\u{2c}\\u{308}\",\n        \"\\u{3031}\"]), (\"\\u{2c}\\u{24c2}\", &[\"\\u{2c}\", \"\\u{24c2}\"]), (\"\\u{2c}\\u{308}\\u{24c2}\",\n        &[\"\\u{2c}\\u{308}\", \"\\u{24c2}\"]), (\"\\u{2c}\\u{41}\", &[\"\\u{2c}\", \"\\u{41}\"]),\n        (\"\\u{2c}\\u{308}\\u{41}\", &[\"\\u{2c}\\u{308}\", \"\\u{41}\"]), (\"\\u{2c}\\u{3a}\", &[\"\\u{2c}\",\n        \"\\u{3a}\"]), (\"\\u{2c}\\u{308}\\u{3a}\", &[\"\\u{2c}\\u{308}\", \"\\u{3a}\"]), (\"\\u{2c}\\u{2c}\",\n        &[\"\\u{2c}\", \"\\u{2c}\"]), (\"\\u{2c}\\u{308}\\u{2c}\", &[\"\\u{2c}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{2c}\\u{2e}\", &[\"\\u{2c}\", \"\\u{2e}\"]), (\"\\u{2c}\\u{308}\\u{2e}\", &[\"\\u{2c}\\u{308}\",\n        \"\\u{2e}\"]), (\"\\u{2c}\\u{30}\", &[\"\\u{2c}\", \"\\u{30}\"]), (\"\\u{2c}\\u{308}\\u{30}\",\n        &[\"\\u{2c}\\u{308}\", \"\\u{30}\"]), (\"\\u{2c}\\u{5f}\", &[\"\\u{2c}\", \"\\u{5f}\"]),\n        (\"\\u{2c}\\u{308}\\u{5f}\", &[\"\\u{2c}\\u{308}\", \"\\u{5f}\"]), (\"\\u{2c}\\u{1f1e6}\", &[\"\\u{2c}\",\n        \"\\u{1f1e6}\"]), (\"\\u{2c}\\u{308}\\u{1f1e6}\", &[\"\\u{2c}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{2c}\\u{5d0}\", &[\"\\u{2c}\", \"\\u{5d0}\"]), (\"\\u{2c}\\u{308}\\u{5d0}\", &[\"\\u{2c}\\u{308}\",\n        \"\\u{5d0}\"]), (\"\\u{2c}\\u{22}\", &[\"\\u{2c}\", \"\\u{22}\"]), (\"\\u{2c}\\u{308}\\u{22}\",\n        &[\"\\u{2c}\\u{308}\", \"\\u{22}\"]), (\"\\u{2c}\\u{27}\", &[\"\\u{2c}\", \"\\u{27}\"]),\n        (\"\\u{2c}\\u{308}\\u{27}\", &[\"\\u{2c}\\u{308}\", \"\\u{27}\"]), (\"\\u{2c}\\u{200d}\",\n        &[\"\\u{2c}\\u{200d}\"]), (\"\\u{2c}\\u{308}\\u{200d}\", &[\"\\u{2c}\\u{308}\\u{200d}\"]),\n        (\"\\u{2c}\\u{a9}\", &[\"\\u{2c}\", \"\\u{a9}\"]), (\"\\u{2c}\\u{308}\\u{a9}\", &[\"\\u{2c}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{2c}\\u{20}\", &[\"\\u{2c}\", \"\\u{20}\"]), (\"\\u{2c}\\u{308}\\u{20}\",\n        &[\"\\u{2c}\\u{308}\", \"\\u{20}\"]), (\"\\u{2c}\\u{0}\", &[\"\\u{2c}\", \"\\u{0}\"]), (\"\\u{2c}\\u{308}\\u{0}\",\n        &[\"\\u{2c}\\u{308}\", \"\\u{0}\"]), (\"\\u{2c}\\u{61}\\u{2060}\", &[\"\\u{2c}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{2c}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{2c}\\u{308}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{2c}\\u{61}\\u{3a}\", &[\"\\u{2c}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{2c}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{2c}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{2c}\\u{61}\\u{27}\", &[\"\\u{2c}\", \"\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{2c}\\u{308}\\u{61}\\u{27}\", &[\"\\u{2c}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{2c}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{2c}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{2c}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{2c}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{2c}\\u{61}\\u{2c}\", &[\"\\u{2c}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{2c}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{2c}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{2c}\\u{31}\\u{3a}\", &[\"\\u{2c}\", \"\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{2c}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{2c}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{2c}\\u{31}\\u{27}\", &[\"\\u{2c}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{2c}\\u{308}\\u{31}\\u{27}\",\n        &[\"\\u{2c}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{2c}\\u{31}\\u{2c}\", &[\"\\u{2c}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{2c}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{2c}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{2c}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{2c}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{2c}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{2c}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{2e}\\u{d}\", &[\"\\u{2e}\", \"\\u{d}\"]), (\"\\u{2e}\\u{308}\\u{d}\", &[\"\\u{2e}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{2e}\\u{a}\", &[\"\\u{2e}\", \"\\u{a}\"]), (\"\\u{2e}\\u{308}\\u{a}\", &[\"\\u{2e}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{2e}\\u{b}\", &[\"\\u{2e}\", \"\\u{b}\"]), (\"\\u{2e}\\u{308}\\u{b}\", &[\"\\u{2e}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{2e}\\u{300}\", &[\"\\u{2e}\\u{300}\"]), (\"\\u{2e}\\u{308}\\u{300}\", &[\"\\u{2e}\\u{308}\\u{300}\"]),\n        (\"\\u{2e}\\u{ad}\", &[\"\\u{2e}\\u{ad}\"]), (\"\\u{2e}\\u{308}\\u{ad}\", &[\"\\u{2e}\\u{308}\\u{ad}\"]),\n        (\"\\u{2e}\\u{3031}\", &[\"\\u{2e}\", \"\\u{3031}\"]), (\"\\u{2e}\\u{308}\\u{3031}\", &[\"\\u{2e}\\u{308}\",\n        \"\\u{3031}\"]), (\"\\u{2e}\\u{24c2}\", &[\"\\u{2e}\", \"\\u{24c2}\"]), (\"\\u{2e}\\u{308}\\u{24c2}\",\n        &[\"\\u{2e}\\u{308}\", \"\\u{24c2}\"]), (\"\\u{2e}\\u{41}\", &[\"\\u{2e}\", \"\\u{41}\"]),\n        (\"\\u{2e}\\u{308}\\u{41}\", &[\"\\u{2e}\\u{308}\", \"\\u{41}\"]), (\"\\u{2e}\\u{3a}\", &[\"\\u{2e}\",\n        \"\\u{3a}\"]), (\"\\u{2e}\\u{308}\\u{3a}\", &[\"\\u{2e}\\u{308}\", \"\\u{3a}\"]), (\"\\u{2e}\\u{2c}\",\n        &[\"\\u{2e}\", \"\\u{2c}\"]), (\"\\u{2e}\\u{308}\\u{2c}\", &[\"\\u{2e}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{2e}\\u{2e}\", &[\"\\u{2e}\", \"\\u{2e}\"]), (\"\\u{2e}\\u{308}\\u{2e}\", &[\"\\u{2e}\\u{308}\",\n        \"\\u{2e}\"]), (\"\\u{2e}\\u{30}\", &[\"\\u{2e}\", \"\\u{30}\"]), (\"\\u{2e}\\u{308}\\u{30}\",\n        &[\"\\u{2e}\\u{308}\", \"\\u{30}\"]), (\"\\u{2e}\\u{5f}\", &[\"\\u{2e}\", \"\\u{5f}\"]),\n        (\"\\u{2e}\\u{308}\\u{5f}\", &[\"\\u{2e}\\u{308}\", \"\\u{5f}\"]), (\"\\u{2e}\\u{1f1e6}\", &[\"\\u{2e}\",\n        \"\\u{1f1e6}\"]), (\"\\u{2e}\\u{308}\\u{1f1e6}\", &[\"\\u{2e}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{2e}\\u{5d0}\", &[\"\\u{2e}\", \"\\u{5d0}\"]), (\"\\u{2e}\\u{308}\\u{5d0}\", &[\"\\u{2e}\\u{308}\",\n        \"\\u{5d0}\"]), (\"\\u{2e}\\u{22}\", &[\"\\u{2e}\", \"\\u{22}\"]), (\"\\u{2e}\\u{308}\\u{22}\",\n        &[\"\\u{2e}\\u{308}\", \"\\u{22}\"]), (\"\\u{2e}\\u{27}\", &[\"\\u{2e}\", \"\\u{27}\"]),\n        (\"\\u{2e}\\u{308}\\u{27}\", &[\"\\u{2e}\\u{308}\", \"\\u{27}\"]), (\"\\u{2e}\\u{200d}\",\n        &[\"\\u{2e}\\u{200d}\"]), (\"\\u{2e}\\u{308}\\u{200d}\", &[\"\\u{2e}\\u{308}\\u{200d}\"]),\n        (\"\\u{2e}\\u{a9}\", &[\"\\u{2e}\", \"\\u{a9}\"]), (\"\\u{2e}\\u{308}\\u{a9}\", &[\"\\u{2e}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{2e}\\u{20}\", &[\"\\u{2e}\", \"\\u{20}\"]), (\"\\u{2e}\\u{308}\\u{20}\",\n        &[\"\\u{2e}\\u{308}\", \"\\u{20}\"]), (\"\\u{2e}\\u{0}\", &[\"\\u{2e}\", \"\\u{0}\"]), (\"\\u{2e}\\u{308}\\u{0}\",\n        &[\"\\u{2e}\\u{308}\", \"\\u{0}\"]), (\"\\u{2e}\\u{61}\\u{2060}\", &[\"\\u{2e}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{2e}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{2e}\\u{308}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{2e}\\u{61}\\u{3a}\", &[\"\\u{2e}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{2e}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{2e}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{2e}\\u{61}\\u{27}\", &[\"\\u{2e}\", \"\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{2e}\\u{308}\\u{61}\\u{27}\", &[\"\\u{2e}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{2e}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{2e}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{2e}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{2e}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{2e}\\u{61}\\u{2c}\", &[\"\\u{2e}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{2e}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{2e}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{2e}\\u{31}\\u{3a}\", &[\"\\u{2e}\", \"\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{2e}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{2e}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{2e}\\u{31}\\u{27}\", &[\"\\u{2e}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{2e}\\u{308}\\u{31}\\u{27}\",\n        &[\"\\u{2e}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{2e}\\u{31}\\u{2c}\", &[\"\\u{2e}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{2e}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{2e}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{2e}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{2e}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{2e}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{2e}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{30}\\u{d}\", &[\"\\u{30}\", \"\\u{d}\"]), (\"\\u{30}\\u{308}\\u{d}\", &[\"\\u{30}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{30}\\u{a}\", &[\"\\u{30}\", \"\\u{a}\"]), (\"\\u{30}\\u{308}\\u{a}\", &[\"\\u{30}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{30}\\u{b}\", &[\"\\u{30}\", \"\\u{b}\"]), (\"\\u{30}\\u{308}\\u{b}\", &[\"\\u{30}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{30}\\u{300}\", &[\"\\u{30}\\u{300}\"]), (\"\\u{30}\\u{308}\\u{300}\", &[\"\\u{30}\\u{308}\\u{300}\"]),\n        (\"\\u{30}\\u{ad}\", &[\"\\u{30}\\u{ad}\"]), (\"\\u{30}\\u{308}\\u{ad}\", &[\"\\u{30}\\u{308}\\u{ad}\"]),\n        (\"\\u{30}\\u{3031}\", &[\"\\u{30}\", \"\\u{3031}\"]), (\"\\u{30}\\u{308}\\u{3031}\", &[\"\\u{30}\\u{308}\",\n        \"\\u{3031}\"]), (\"\\u{30}\\u{24c2}\", &[\"\\u{30}\\u{24c2}\"]), (\"\\u{30}\\u{308}\\u{24c2}\",\n        &[\"\\u{30}\\u{308}\\u{24c2}\"]), (\"\\u{30}\\u{41}\", &[\"\\u{30}\\u{41}\"]), (\"\\u{30}\\u{308}\\u{41}\",\n        &[\"\\u{30}\\u{308}\\u{41}\"]), (\"\\u{30}\\u{3a}\", &[\"\\u{30}\", \"\\u{3a}\"]), (\"\\u{30}\\u{308}\\u{3a}\",\n        &[\"\\u{30}\\u{308}\", \"\\u{3a}\"]), (\"\\u{30}\\u{2c}\", &[\"\\u{30}\", \"\\u{2c}\"]),\n        (\"\\u{30}\\u{308}\\u{2c}\", &[\"\\u{30}\\u{308}\", \"\\u{2c}\"]), (\"\\u{30}\\u{2e}\", &[\"\\u{30}\",\n        \"\\u{2e}\"]), (\"\\u{30}\\u{308}\\u{2e}\", &[\"\\u{30}\\u{308}\", \"\\u{2e}\"]), (\"\\u{30}\\u{30}\",\n        &[\"\\u{30}\\u{30}\"]), (\"\\u{30}\\u{308}\\u{30}\", &[\"\\u{30}\\u{308}\\u{30}\"]), (\"\\u{30}\\u{5f}\",\n        &[\"\\u{30}\\u{5f}\"]), (\"\\u{30}\\u{308}\\u{5f}\", &[\"\\u{30}\\u{308}\\u{5f}\"]), (\"\\u{30}\\u{1f1e6}\",\n        &[\"\\u{30}\", \"\\u{1f1e6}\"]), (\"\\u{30}\\u{308}\\u{1f1e6}\", &[\"\\u{30}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{30}\\u{5d0}\", &[\"\\u{30}\\u{5d0}\"]), (\"\\u{30}\\u{308}\\u{5d0}\", &[\"\\u{30}\\u{308}\\u{5d0}\"]),\n        (\"\\u{30}\\u{22}\", &[\"\\u{30}\", \"\\u{22}\"]), (\"\\u{30}\\u{308}\\u{22}\", &[\"\\u{30}\\u{308}\",\n        \"\\u{22}\"]), (\"\\u{30}\\u{27}\", &[\"\\u{30}\", \"\\u{27}\"]), (\"\\u{30}\\u{308}\\u{27}\",\n        &[\"\\u{30}\\u{308}\", \"\\u{27}\"]), (\"\\u{30}\\u{200d}\", &[\"\\u{30}\\u{200d}\"]),\n        (\"\\u{30}\\u{308}\\u{200d}\", &[\"\\u{30}\\u{308}\\u{200d}\"]), (\"\\u{30}\\u{a9}\", &[\"\\u{30}\",\n        \"\\u{a9}\"]), (\"\\u{30}\\u{308}\\u{a9}\", &[\"\\u{30}\\u{308}\", \"\\u{a9}\"]), (\"\\u{30}\\u{20}\",\n        &[\"\\u{30}\", \"\\u{20}\"]), (\"\\u{30}\\u{308}\\u{20}\", &[\"\\u{30}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{30}\\u{0}\", &[\"\\u{30}\", \"\\u{0}\"]), (\"\\u{30}\\u{308}\\u{0}\", &[\"\\u{30}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{30}\\u{61}\\u{2060}\", &[\"\\u{30}\\u{61}\\u{2060}\"]), (\"\\u{30}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{30}\\u{308}\\u{61}\\u{2060}\"]), (\"\\u{30}\\u{61}\\u{3a}\", &[\"\\u{30}\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{30}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{30}\\u{308}\\u{61}\", \"\\u{3a}\"]), (\"\\u{30}\\u{61}\\u{27}\",\n        &[\"\\u{30}\\u{61}\", \"\\u{27}\"]), (\"\\u{30}\\u{308}\\u{61}\\u{27}\", &[\"\\u{30}\\u{308}\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{30}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{30}\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{30}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{30}\\u{308}\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{30}\\u{61}\\u{2c}\", &[\"\\u{30}\\u{61}\", \"\\u{2c}\"]), (\"\\u{30}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{30}\\u{308}\\u{61}\", \"\\u{2c}\"]), (\"\\u{30}\\u{31}\\u{3a}\", &[\"\\u{30}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{30}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{30}\\u{308}\\u{31}\", \"\\u{3a}\"]), (\"\\u{30}\\u{31}\\u{27}\",\n        &[\"\\u{30}\\u{31}\", \"\\u{27}\"]), (\"\\u{30}\\u{308}\\u{31}\\u{27}\", &[\"\\u{30}\\u{308}\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{30}\\u{31}\\u{2c}\", &[\"\\u{30}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{30}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{30}\\u{308}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{30}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{30}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{30}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{30}\\u{308}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{5f}\\u{d}\", &[\"\\u{5f}\", \"\\u{d}\"]), (\"\\u{5f}\\u{308}\\u{d}\", &[\"\\u{5f}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{5f}\\u{a}\", &[\"\\u{5f}\", \"\\u{a}\"]), (\"\\u{5f}\\u{308}\\u{a}\", &[\"\\u{5f}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{5f}\\u{b}\", &[\"\\u{5f}\", \"\\u{b}\"]), (\"\\u{5f}\\u{308}\\u{b}\", &[\"\\u{5f}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{5f}\\u{300}\", &[\"\\u{5f}\\u{300}\"]), (\"\\u{5f}\\u{308}\\u{300}\", &[\"\\u{5f}\\u{308}\\u{300}\"]),\n        (\"\\u{5f}\\u{ad}\", &[\"\\u{5f}\\u{ad}\"]), (\"\\u{5f}\\u{308}\\u{ad}\", &[\"\\u{5f}\\u{308}\\u{ad}\"]),\n        (\"\\u{5f}\\u{3031}\", &[\"\\u{5f}\\u{3031}\"]), (\"\\u{5f}\\u{308}\\u{3031}\",\n        &[\"\\u{5f}\\u{308}\\u{3031}\"]), (\"\\u{5f}\\u{24c2}\", &[\"\\u{5f}\\u{24c2}\"]),\n        (\"\\u{5f}\\u{308}\\u{24c2}\", &[\"\\u{5f}\\u{308}\\u{24c2}\"]), (\"\\u{5f}\\u{41}\", &[\"\\u{5f}\\u{41}\"]),\n        (\"\\u{5f}\\u{308}\\u{41}\", &[\"\\u{5f}\\u{308}\\u{41}\"]), (\"\\u{5f}\\u{3a}\", &[\"\\u{5f}\", \"\\u{3a}\"]),\n        (\"\\u{5f}\\u{308}\\u{3a}\", &[\"\\u{5f}\\u{308}\", \"\\u{3a}\"]), (\"\\u{5f}\\u{2c}\", &[\"\\u{5f}\",\n        \"\\u{2c}\"]), (\"\\u{5f}\\u{308}\\u{2c}\", &[\"\\u{5f}\\u{308}\", \"\\u{2c}\"]), (\"\\u{5f}\\u{2e}\",\n        &[\"\\u{5f}\", \"\\u{2e}\"]), (\"\\u{5f}\\u{308}\\u{2e}\", &[\"\\u{5f}\\u{308}\", \"\\u{2e}\"]),\n        (\"\\u{5f}\\u{30}\", &[\"\\u{5f}\\u{30}\"]), (\"\\u{5f}\\u{308}\\u{30}\", &[\"\\u{5f}\\u{308}\\u{30}\"]),\n        (\"\\u{5f}\\u{5f}\", &[\"\\u{5f}\\u{5f}\"]), (\"\\u{5f}\\u{308}\\u{5f}\", &[\"\\u{5f}\\u{308}\\u{5f}\"]),\n        (\"\\u{5f}\\u{1f1e6}\", &[\"\\u{5f}\", \"\\u{1f1e6}\"]), (\"\\u{5f}\\u{308}\\u{1f1e6}\", &[\"\\u{5f}\\u{308}\",\n        \"\\u{1f1e6}\"]), (\"\\u{5f}\\u{5d0}\", &[\"\\u{5f}\\u{5d0}\"]), (\"\\u{5f}\\u{308}\\u{5d0}\",\n        &[\"\\u{5f}\\u{308}\\u{5d0}\"]), (\"\\u{5f}\\u{22}\", &[\"\\u{5f}\", \"\\u{22}\"]), (\"\\u{5f}\\u{308}\\u{22}\",\n        &[\"\\u{5f}\\u{308}\", \"\\u{22}\"]), (\"\\u{5f}\\u{27}\", &[\"\\u{5f}\", \"\\u{27}\"]),\n        (\"\\u{5f}\\u{308}\\u{27}\", &[\"\\u{5f}\\u{308}\", \"\\u{27}\"]), (\"\\u{5f}\\u{200d}\",\n        &[\"\\u{5f}\\u{200d}\"]), (\"\\u{5f}\\u{308}\\u{200d}\", &[\"\\u{5f}\\u{308}\\u{200d}\"]),\n        (\"\\u{5f}\\u{a9}\", &[\"\\u{5f}\", \"\\u{a9}\"]), (\"\\u{5f}\\u{308}\\u{a9}\", &[\"\\u{5f}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{5f}\\u{20}\", &[\"\\u{5f}\", \"\\u{20}\"]), (\"\\u{5f}\\u{308}\\u{20}\",\n        &[\"\\u{5f}\\u{308}\", \"\\u{20}\"]), (\"\\u{5f}\\u{0}\", &[\"\\u{5f}\", \"\\u{0}\"]), (\"\\u{5f}\\u{308}\\u{0}\",\n        &[\"\\u{5f}\\u{308}\", \"\\u{0}\"]), (\"\\u{5f}\\u{61}\\u{2060}\", &[\"\\u{5f}\\u{61}\\u{2060}\"]),\n        (\"\\u{5f}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{5f}\\u{308}\\u{61}\\u{2060}\"]), (\"\\u{5f}\\u{61}\\u{3a}\",\n        &[\"\\u{5f}\\u{61}\", \"\\u{3a}\"]), (\"\\u{5f}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{5f}\\u{308}\\u{61}\",\n        \"\\u{3a}\"]), (\"\\u{5f}\\u{61}\\u{27}\", &[\"\\u{5f}\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{5f}\\u{308}\\u{61}\\u{27}\", &[\"\\u{5f}\\u{308}\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{5f}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{5f}\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{5f}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{5f}\\u{308}\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{5f}\\u{61}\\u{2c}\", &[\"\\u{5f}\\u{61}\", \"\\u{2c}\"]), (\"\\u{5f}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{5f}\\u{308}\\u{61}\", \"\\u{2c}\"]), (\"\\u{5f}\\u{31}\\u{3a}\", &[\"\\u{5f}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{5f}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{5f}\\u{308}\\u{31}\", \"\\u{3a}\"]), (\"\\u{5f}\\u{31}\\u{27}\",\n        &[\"\\u{5f}\\u{31}\", \"\\u{27}\"]), (\"\\u{5f}\\u{308}\\u{31}\\u{27}\", &[\"\\u{5f}\\u{308}\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{5f}\\u{31}\\u{2c}\", &[\"\\u{5f}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{5f}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{5f}\\u{308}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{5f}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{5f}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{5f}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{5f}\\u{308}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{1f1e6}\\u{d}\", &[\"\\u{1f1e6}\", \"\\u{d}\"]), (\"\\u{1f1e6}\\u{308}\\u{d}\", &[\"\\u{1f1e6}\\u{308}\",\n        \"\\u{d}\"]), (\"\\u{1f1e6}\\u{a}\", &[\"\\u{1f1e6}\", \"\\u{a}\"]), (\"\\u{1f1e6}\\u{308}\\u{a}\",\n        &[\"\\u{1f1e6}\\u{308}\", \"\\u{a}\"]), (\"\\u{1f1e6}\\u{b}\", &[\"\\u{1f1e6}\", \"\\u{b}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{b}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{b}\"]), (\"\\u{1f1e6}\\u{300}\",\n        &[\"\\u{1f1e6}\\u{300}\"]), (\"\\u{1f1e6}\\u{308}\\u{300}\", &[\"\\u{1f1e6}\\u{308}\\u{300}\"]),\n        (\"\\u{1f1e6}\\u{ad}\", &[\"\\u{1f1e6}\\u{ad}\"]), (\"\\u{1f1e6}\\u{308}\\u{ad}\",\n        &[\"\\u{1f1e6}\\u{308}\\u{ad}\"]), (\"\\u{1f1e6}\\u{3031}\", &[\"\\u{1f1e6}\", \"\\u{3031}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{3031}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{3031}\"]), (\"\\u{1f1e6}\\u{24c2}\",\n        &[\"\\u{1f1e6}\", \"\\u{24c2}\"]), (\"\\u{1f1e6}\\u{308}\\u{24c2}\", &[\"\\u{1f1e6}\\u{308}\",\n        \"\\u{24c2}\"]), (\"\\u{1f1e6}\\u{41}\", &[\"\\u{1f1e6}\", \"\\u{41}\"]), (\"\\u{1f1e6}\\u{308}\\u{41}\",\n        &[\"\\u{1f1e6}\\u{308}\", \"\\u{41}\"]), (\"\\u{1f1e6}\\u{3a}\", &[\"\\u{1f1e6}\", \"\\u{3a}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{3a}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{3a}\"]), (\"\\u{1f1e6}\\u{2c}\",\n        &[\"\\u{1f1e6}\", \"\\u{2c}\"]), (\"\\u{1f1e6}\\u{308}\\u{2c}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{1f1e6}\\u{2e}\", &[\"\\u{1f1e6}\", \"\\u{2e}\"]), (\"\\u{1f1e6}\\u{308}\\u{2e}\",\n        &[\"\\u{1f1e6}\\u{308}\", \"\\u{2e}\"]), (\"\\u{1f1e6}\\u{30}\", &[\"\\u{1f1e6}\", \"\\u{30}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{30}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{30}\"]), (\"\\u{1f1e6}\\u{5f}\",\n        &[\"\\u{1f1e6}\", \"\\u{5f}\"]), (\"\\u{1f1e6}\\u{308}\\u{5f}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{5f}\"]),\n        (\"\\u{1f1e6}\\u{1f1e6}\", &[\"\\u{1f1e6}\\u{1f1e6}\"]), (\"\\u{1f1e6}\\u{308}\\u{1f1e6}\",\n        &[\"\\u{1f1e6}\\u{308}\\u{1f1e6}\"]), (\"\\u{1f1e6}\\u{5d0}\", &[\"\\u{1f1e6}\", \"\\u{5d0}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{5d0}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{5d0}\"]), (\"\\u{1f1e6}\\u{22}\",\n        &[\"\\u{1f1e6}\", \"\\u{22}\"]), (\"\\u{1f1e6}\\u{308}\\u{22}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{1f1e6}\\u{27}\", &[\"\\u{1f1e6}\", \"\\u{27}\"]), (\"\\u{1f1e6}\\u{308}\\u{27}\",\n        &[\"\\u{1f1e6}\\u{308}\", \"\\u{27}\"]), (\"\\u{1f1e6}\\u{200d}\", &[\"\\u{1f1e6}\\u{200d}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{200d}\", &[\"\\u{1f1e6}\\u{308}\\u{200d}\"]), (\"\\u{1f1e6}\\u{a9}\",\n        &[\"\\u{1f1e6}\", \"\\u{a9}\"]), (\"\\u{1f1e6}\\u{308}\\u{a9}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{1f1e6}\\u{20}\", &[\"\\u{1f1e6}\", \"\\u{20}\"]), (\"\\u{1f1e6}\\u{308}\\u{20}\",\n        &[\"\\u{1f1e6}\\u{308}\", \"\\u{20}\"]), (\"\\u{1f1e6}\\u{0}\", &[\"\\u{1f1e6}\", \"\\u{0}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{0}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{0}\"]), (\"\\u{1f1e6}\\u{61}\\u{2060}\",\n        &[\"\\u{1f1e6}\", \"\\u{61}\\u{2060}\"]), (\"\\u{1f1e6}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{1f1e6}\\u{308}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{1f1e6}\\u{61}\\u{3a}\", &[\"\\u{1f1e6}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{1f1e6}\\u{61}\\u{27}\", &[\"\\u{1f1e6}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{61}\\u{27}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{1f1e6}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{1f1e6}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{1f1e6}\\u{61}\\u{2c}\", &[\"\\u{1f1e6}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{1f1e6}\\u{31}\\u{3a}\", &[\"\\u{1f1e6}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{1f1e6}\\u{31}\\u{27}\", &[\"\\u{1f1e6}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{31}\\u{27}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{1f1e6}\\u{31}\\u{2c}\", &[\"\\u{1f1e6}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{1f1e6}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{1f1e6}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{1f1e6}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{1f1e6}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{5d0}\\u{d}\", &[\"\\u{5d0}\", \"\\u{d}\"]), (\"\\u{5d0}\\u{308}\\u{d}\", &[\"\\u{5d0}\\u{308}\",\n        \"\\u{d}\"]), (\"\\u{5d0}\\u{a}\", &[\"\\u{5d0}\", \"\\u{a}\"]), (\"\\u{5d0}\\u{308}\\u{a}\",\n        &[\"\\u{5d0}\\u{308}\", \"\\u{a}\"]), (\"\\u{5d0}\\u{b}\", &[\"\\u{5d0}\", \"\\u{b}\"]),\n        (\"\\u{5d0}\\u{308}\\u{b}\", &[\"\\u{5d0}\\u{308}\", \"\\u{b}\"]), (\"\\u{5d0}\\u{300}\",\n        &[\"\\u{5d0}\\u{300}\"]), (\"\\u{5d0}\\u{308}\\u{300}\", &[\"\\u{5d0}\\u{308}\\u{300}\"]),\n        (\"\\u{5d0}\\u{ad}\", &[\"\\u{5d0}\\u{ad}\"]), (\"\\u{5d0}\\u{308}\\u{ad}\", &[\"\\u{5d0}\\u{308}\\u{ad}\"]),\n        (\"\\u{5d0}\\u{3031}\", &[\"\\u{5d0}\", \"\\u{3031}\"]), (\"\\u{5d0}\\u{308}\\u{3031}\",\n        &[\"\\u{5d0}\\u{308}\", \"\\u{3031}\"]), (\"\\u{5d0}\\u{24c2}\", &[\"\\u{5d0}\\u{24c2}\"]),\n        (\"\\u{5d0}\\u{308}\\u{24c2}\", &[\"\\u{5d0}\\u{308}\\u{24c2}\"]), (\"\\u{5d0}\\u{41}\",\n        &[\"\\u{5d0}\\u{41}\"]), (\"\\u{5d0}\\u{308}\\u{41}\", &[\"\\u{5d0}\\u{308}\\u{41}\"]), (\"\\u{5d0}\\u{3a}\",\n        &[\"\\u{5d0}\", \"\\u{3a}\"]), (\"\\u{5d0}\\u{308}\\u{3a}\", &[\"\\u{5d0}\\u{308}\", \"\\u{3a}\"]),\n        (\"\\u{5d0}\\u{2c}\", &[\"\\u{5d0}\", \"\\u{2c}\"]), (\"\\u{5d0}\\u{308}\\u{2c}\", &[\"\\u{5d0}\\u{308}\",\n        \"\\u{2c}\"]), (\"\\u{5d0}\\u{2e}\", &[\"\\u{5d0}\", \"\\u{2e}\"]), (\"\\u{5d0}\\u{308}\\u{2e}\",\n        &[\"\\u{5d0}\\u{308}\", \"\\u{2e}\"]), (\"\\u{5d0}\\u{30}\", &[\"\\u{5d0}\\u{30}\"]),\n        (\"\\u{5d0}\\u{308}\\u{30}\", &[\"\\u{5d0}\\u{308}\\u{30}\"]), (\"\\u{5d0}\\u{5f}\", &[\"\\u{5d0}\\u{5f}\"]),\n        (\"\\u{5d0}\\u{308}\\u{5f}\", &[\"\\u{5d0}\\u{308}\\u{5f}\"]), (\"\\u{5d0}\\u{1f1e6}\", &[\"\\u{5d0}\",\n        \"\\u{1f1e6}\"]), (\"\\u{5d0}\\u{308}\\u{1f1e6}\", &[\"\\u{5d0}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{5d0}\\u{5d0}\", &[\"\\u{5d0}\\u{5d0}\"]), (\"\\u{5d0}\\u{308}\\u{5d0}\",\n        &[\"\\u{5d0}\\u{308}\\u{5d0}\"]), (\"\\u{5d0}\\u{22}\", &[\"\\u{5d0}\", \"\\u{22}\"]),\n        (\"\\u{5d0}\\u{308}\\u{22}\", &[\"\\u{5d0}\\u{308}\", \"\\u{22}\"]), (\"\\u{5d0}\\u{27}\",\n        &[\"\\u{5d0}\\u{27}\"]), (\"\\u{5d0}\\u{308}\\u{27}\", &[\"\\u{5d0}\\u{308}\\u{27}\"]),\n        (\"\\u{5d0}\\u{200d}\", &[\"\\u{5d0}\\u{200d}\"]), (\"\\u{5d0}\\u{308}\\u{200d}\",\n        &[\"\\u{5d0}\\u{308}\\u{200d}\"]), (\"\\u{5d0}\\u{a9}\", &[\"\\u{5d0}\", \"\\u{a9}\"]),\n        (\"\\u{5d0}\\u{308}\\u{a9}\", &[\"\\u{5d0}\\u{308}\", \"\\u{a9}\"]), (\"\\u{5d0}\\u{20}\", &[\"\\u{5d0}\",\n        \"\\u{20}\"]), (\"\\u{5d0}\\u{308}\\u{20}\", &[\"\\u{5d0}\\u{308}\", \"\\u{20}\"]), (\"\\u{5d0}\\u{0}\",\n        &[\"\\u{5d0}\", \"\\u{0}\"]), (\"\\u{5d0}\\u{308}\\u{0}\", &[\"\\u{5d0}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{5d0}\\u{61}\\u{2060}\", &[\"\\u{5d0}\\u{61}\\u{2060}\"]), (\"\\u{5d0}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{5d0}\\u{308}\\u{61}\\u{2060}\"]), (\"\\u{5d0}\\u{61}\\u{3a}\", &[\"\\u{5d0}\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{5d0}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{5d0}\\u{308}\\u{61}\", \"\\u{3a}\"]), (\"\\u{5d0}\\u{61}\\u{27}\",\n        &[\"\\u{5d0}\\u{61}\", \"\\u{27}\"]), (\"\\u{5d0}\\u{308}\\u{61}\\u{27}\", &[\"\\u{5d0}\\u{308}\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{5d0}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{5d0}\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{5d0}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{5d0}\\u{308}\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{5d0}\\u{61}\\u{2c}\", &[\"\\u{5d0}\\u{61}\", \"\\u{2c}\"]), (\"\\u{5d0}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{5d0}\\u{308}\\u{61}\", \"\\u{2c}\"]), (\"\\u{5d0}\\u{31}\\u{3a}\", &[\"\\u{5d0}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{5d0}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{5d0}\\u{308}\\u{31}\", \"\\u{3a}\"]), (\"\\u{5d0}\\u{31}\\u{27}\",\n        &[\"\\u{5d0}\\u{31}\", \"\\u{27}\"]), (\"\\u{5d0}\\u{308}\\u{31}\\u{27}\", &[\"\\u{5d0}\\u{308}\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{5d0}\\u{31}\\u{2c}\", &[\"\\u{5d0}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{5d0}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{5d0}\\u{308}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{5d0}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{5d0}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{5d0}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{5d0}\\u{308}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{22}\\u{d}\", &[\"\\u{22}\", \"\\u{d}\"]), (\"\\u{22}\\u{308}\\u{d}\", &[\"\\u{22}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{22}\\u{a}\", &[\"\\u{22}\", \"\\u{a}\"]), (\"\\u{22}\\u{308}\\u{a}\", &[\"\\u{22}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{22}\\u{b}\", &[\"\\u{22}\", \"\\u{b}\"]), (\"\\u{22}\\u{308}\\u{b}\", &[\"\\u{22}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{22}\\u{300}\", &[\"\\u{22}\\u{300}\"]), (\"\\u{22}\\u{308}\\u{300}\", &[\"\\u{22}\\u{308}\\u{300}\"]),\n        (\"\\u{22}\\u{ad}\", &[\"\\u{22}\\u{ad}\"]), (\"\\u{22}\\u{308}\\u{ad}\", &[\"\\u{22}\\u{308}\\u{ad}\"]),\n        (\"\\u{22}\\u{3031}\", &[\"\\u{22}\", \"\\u{3031}\"]), (\"\\u{22}\\u{308}\\u{3031}\", &[\"\\u{22}\\u{308}\",\n        \"\\u{3031}\"]), (\"\\u{22}\\u{24c2}\", &[\"\\u{22}\", \"\\u{24c2}\"]), (\"\\u{22}\\u{308}\\u{24c2}\",\n        &[\"\\u{22}\\u{308}\", \"\\u{24c2}\"]), (\"\\u{22}\\u{41}\", &[\"\\u{22}\", \"\\u{41}\"]),\n        (\"\\u{22}\\u{308}\\u{41}\", &[\"\\u{22}\\u{308}\", \"\\u{41}\"]), (\"\\u{22}\\u{3a}\", &[\"\\u{22}\",\n        \"\\u{3a}\"]), (\"\\u{22}\\u{308}\\u{3a}\", &[\"\\u{22}\\u{308}\", \"\\u{3a}\"]), (\"\\u{22}\\u{2c}\",\n        &[\"\\u{22}\", \"\\u{2c}\"]), (\"\\u{22}\\u{308}\\u{2c}\", &[\"\\u{22}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{22}\\u{2e}\", &[\"\\u{22}\", \"\\u{2e}\"]), (\"\\u{22}\\u{308}\\u{2e}\", &[\"\\u{22}\\u{308}\",\n        \"\\u{2e}\"]), (\"\\u{22}\\u{30}\", &[\"\\u{22}\", \"\\u{30}\"]), (\"\\u{22}\\u{308}\\u{30}\",\n        &[\"\\u{22}\\u{308}\", \"\\u{30}\"]), (\"\\u{22}\\u{5f}\", &[\"\\u{22}\", \"\\u{5f}\"]),\n        (\"\\u{22}\\u{308}\\u{5f}\", &[\"\\u{22}\\u{308}\", \"\\u{5f}\"]), (\"\\u{22}\\u{1f1e6}\", &[\"\\u{22}\",\n        \"\\u{1f1e6}\"]), (\"\\u{22}\\u{308}\\u{1f1e6}\", &[\"\\u{22}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{22}\\u{5d0}\", &[\"\\u{22}\", \"\\u{5d0}\"]), (\"\\u{22}\\u{308}\\u{5d0}\", &[\"\\u{22}\\u{308}\",\n        \"\\u{5d0}\"]), (\"\\u{22}\\u{22}\", &[\"\\u{22}\", \"\\u{22}\"]), (\"\\u{22}\\u{308}\\u{22}\",\n        &[\"\\u{22}\\u{308}\", \"\\u{22}\"]), (\"\\u{22}\\u{27}\", &[\"\\u{22}\", \"\\u{27}\"]),\n        (\"\\u{22}\\u{308}\\u{27}\", &[\"\\u{22}\\u{308}\", \"\\u{27}\"]), (\"\\u{22}\\u{200d}\",\n        &[\"\\u{22}\\u{200d}\"]), (\"\\u{22}\\u{308}\\u{200d}\", &[\"\\u{22}\\u{308}\\u{200d}\"]),\n        (\"\\u{22}\\u{a9}\", &[\"\\u{22}\", \"\\u{a9}\"]), (\"\\u{22}\\u{308}\\u{a9}\", &[\"\\u{22}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{22}\\u{20}\", &[\"\\u{22}\", \"\\u{20}\"]), (\"\\u{22}\\u{308}\\u{20}\",\n        &[\"\\u{22}\\u{308}\", \"\\u{20}\"]), (\"\\u{22}\\u{0}\", &[\"\\u{22}\", \"\\u{0}\"]), (\"\\u{22}\\u{308}\\u{0}\",\n        &[\"\\u{22}\\u{308}\", \"\\u{0}\"]), (\"\\u{22}\\u{61}\\u{2060}\", &[\"\\u{22}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{22}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{22}\\u{308}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{22}\\u{61}\\u{3a}\", &[\"\\u{22}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{22}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{22}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{22}\\u{61}\\u{27}\", &[\"\\u{22}\", \"\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{22}\\u{308}\\u{61}\\u{27}\", &[\"\\u{22}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{22}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{22}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{22}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{22}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{22}\\u{61}\\u{2c}\", &[\"\\u{22}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{22}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{22}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{22}\\u{31}\\u{3a}\", &[\"\\u{22}\", \"\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{22}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{22}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{22}\\u{31}\\u{27}\", &[\"\\u{22}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{22}\\u{308}\\u{31}\\u{27}\",\n        &[\"\\u{22}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{22}\\u{31}\\u{2c}\", &[\"\\u{22}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{22}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{22}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{22}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{22}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{22}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{22}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{27}\\u{d}\", &[\"\\u{27}\", \"\\u{d}\"]), (\"\\u{27}\\u{308}\\u{d}\", &[\"\\u{27}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{27}\\u{a}\", &[\"\\u{27}\", \"\\u{a}\"]), (\"\\u{27}\\u{308}\\u{a}\", &[\"\\u{27}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{27}\\u{b}\", &[\"\\u{27}\", \"\\u{b}\"]), (\"\\u{27}\\u{308}\\u{b}\", &[\"\\u{27}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{27}\\u{300}\", &[\"\\u{27}\\u{300}\"]), (\"\\u{27}\\u{308}\\u{300}\", &[\"\\u{27}\\u{308}\\u{300}\"]),\n        (\"\\u{27}\\u{ad}\", &[\"\\u{27}\\u{ad}\"]), (\"\\u{27}\\u{308}\\u{ad}\", &[\"\\u{27}\\u{308}\\u{ad}\"]),\n        (\"\\u{27}\\u{3031}\", &[\"\\u{27}\", \"\\u{3031}\"]), (\"\\u{27}\\u{308}\\u{3031}\", &[\"\\u{27}\\u{308}\",\n        \"\\u{3031}\"]), (\"\\u{27}\\u{24c2}\", &[\"\\u{27}\", \"\\u{24c2}\"]), (\"\\u{27}\\u{308}\\u{24c2}\",\n        &[\"\\u{27}\\u{308}\", \"\\u{24c2}\"]), (\"\\u{27}\\u{41}\", &[\"\\u{27}\", \"\\u{41}\"]),\n        (\"\\u{27}\\u{308}\\u{41}\", &[\"\\u{27}\\u{308}\", \"\\u{41}\"]), (\"\\u{27}\\u{3a}\", &[\"\\u{27}\",\n        \"\\u{3a}\"]), (\"\\u{27}\\u{308}\\u{3a}\", &[\"\\u{27}\\u{308}\", \"\\u{3a}\"]), (\"\\u{27}\\u{2c}\",\n        &[\"\\u{27}\", \"\\u{2c}\"]), (\"\\u{27}\\u{308}\\u{2c}\", &[\"\\u{27}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{27}\\u{2e}\", &[\"\\u{27}\", \"\\u{2e}\"]), (\"\\u{27}\\u{308}\\u{2e}\", &[\"\\u{27}\\u{308}\",\n        \"\\u{2e}\"]), (\"\\u{27}\\u{30}\", &[\"\\u{27}\", \"\\u{30}\"]), (\"\\u{27}\\u{308}\\u{30}\",\n        &[\"\\u{27}\\u{308}\", \"\\u{30}\"]), (\"\\u{27}\\u{5f}\", &[\"\\u{27}\", \"\\u{5f}\"]),\n        (\"\\u{27}\\u{308}\\u{5f}\", &[\"\\u{27}\\u{308}\", \"\\u{5f}\"]), (\"\\u{27}\\u{1f1e6}\", &[\"\\u{27}\",\n        \"\\u{1f1e6}\"]), (\"\\u{27}\\u{308}\\u{1f1e6}\", &[\"\\u{27}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{27}\\u{5d0}\", &[\"\\u{27}\", \"\\u{5d0}\"]), (\"\\u{27}\\u{308}\\u{5d0}\", &[\"\\u{27}\\u{308}\",\n        \"\\u{5d0}\"]), (\"\\u{27}\\u{22}\", &[\"\\u{27}\", \"\\u{22}\"]), (\"\\u{27}\\u{308}\\u{22}\",\n        &[\"\\u{27}\\u{308}\", \"\\u{22}\"]), (\"\\u{27}\\u{27}\", &[\"\\u{27}\", \"\\u{27}\"]),\n        (\"\\u{27}\\u{308}\\u{27}\", &[\"\\u{27}\\u{308}\", \"\\u{27}\"]), (\"\\u{27}\\u{200d}\",\n        &[\"\\u{27}\\u{200d}\"]), (\"\\u{27}\\u{308}\\u{200d}\", &[\"\\u{27}\\u{308}\\u{200d}\"]),\n        (\"\\u{27}\\u{a9}\", &[\"\\u{27}\", \"\\u{a9}\"]), (\"\\u{27}\\u{308}\\u{a9}\", &[\"\\u{27}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{27}\\u{20}\", &[\"\\u{27}\", \"\\u{20}\"]), (\"\\u{27}\\u{308}\\u{20}\",\n        &[\"\\u{27}\\u{308}\", \"\\u{20}\"]), (\"\\u{27}\\u{0}\", &[\"\\u{27}\", \"\\u{0}\"]), (\"\\u{27}\\u{308}\\u{0}\",\n        &[\"\\u{27}\\u{308}\", \"\\u{0}\"]), (\"\\u{27}\\u{61}\\u{2060}\", &[\"\\u{27}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{27}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{27}\\u{308}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{27}\\u{61}\\u{3a}\", &[\"\\u{27}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{27}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{27}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{27}\\u{61}\\u{27}\", &[\"\\u{27}\", \"\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{27}\\u{308}\\u{61}\\u{27}\", &[\"\\u{27}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{27}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{27}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{27}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{27}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{27}\\u{61}\\u{2c}\", &[\"\\u{27}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{27}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{27}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{27}\\u{31}\\u{3a}\", &[\"\\u{27}\", \"\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{27}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{27}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{27}\\u{31}\\u{27}\", &[\"\\u{27}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{27}\\u{308}\\u{31}\\u{27}\",\n        &[\"\\u{27}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{27}\\u{31}\\u{2c}\", &[\"\\u{27}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{27}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{27}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{27}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{27}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{27}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{27}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{200d}\\u{d}\", &[\"\\u{200d}\", \"\\u{d}\"]), (\"\\u{200d}\\u{308}\\u{d}\", &[\"\\u{200d}\\u{308}\",\n        \"\\u{d}\"]), (\"\\u{200d}\\u{a}\", &[\"\\u{200d}\", \"\\u{a}\"]), (\"\\u{200d}\\u{308}\\u{a}\",\n        &[\"\\u{200d}\\u{308}\", \"\\u{a}\"]), (\"\\u{200d}\\u{b}\", &[\"\\u{200d}\", \"\\u{b}\"]),\n        (\"\\u{200d}\\u{308}\\u{b}\", &[\"\\u{200d}\\u{308}\", \"\\u{b}\"]), (\"\\u{200d}\\u{300}\",\n        &[\"\\u{200d}\\u{300}\"]), (\"\\u{200d}\\u{308}\\u{300}\", &[\"\\u{200d}\\u{308}\\u{300}\"]),\n        (\"\\u{200d}\\u{ad}\", &[\"\\u{200d}\\u{ad}\"]), (\"\\u{200d}\\u{308}\\u{ad}\",\n        &[\"\\u{200d}\\u{308}\\u{ad}\"]), (\"\\u{200d}\\u{3031}\", &[\"\\u{200d}\", \"\\u{3031}\"]),\n        (\"\\u{200d}\\u{308}\\u{3031}\", &[\"\\u{200d}\\u{308}\", \"\\u{3031}\"]), (\"\\u{200d}\\u{24c2}\",\n        &[\"\\u{200d}\\u{24c2}\"]), (\"\\u{200d}\\u{308}\\u{24c2}\", &[\"\\u{200d}\\u{308}\", \"\\u{24c2}\"]),\n        (\"\\u{200d}\\u{41}\", &[\"\\u{200d}\", \"\\u{41}\"]), (\"\\u{200d}\\u{308}\\u{41}\", &[\"\\u{200d}\\u{308}\",\n        \"\\u{41}\"]), (\"\\u{200d}\\u{3a}\", &[\"\\u{200d}\", \"\\u{3a}\"]), (\"\\u{200d}\\u{308}\\u{3a}\",\n        &[\"\\u{200d}\\u{308}\", \"\\u{3a}\"]), (\"\\u{200d}\\u{2c}\", &[\"\\u{200d}\", \"\\u{2c}\"]),\n        (\"\\u{200d}\\u{308}\\u{2c}\", &[\"\\u{200d}\\u{308}\", \"\\u{2c}\"]), (\"\\u{200d}\\u{2e}\", &[\"\\u{200d}\",\n        \"\\u{2e}\"]), (\"\\u{200d}\\u{308}\\u{2e}\", &[\"\\u{200d}\\u{308}\", \"\\u{2e}\"]), (\"\\u{200d}\\u{30}\",\n        &[\"\\u{200d}\", \"\\u{30}\"]), (\"\\u{200d}\\u{308}\\u{30}\", &[\"\\u{200d}\\u{308}\", \"\\u{30}\"]),\n        (\"\\u{200d}\\u{5f}\", &[\"\\u{200d}\", \"\\u{5f}\"]), (\"\\u{200d}\\u{308}\\u{5f}\", &[\"\\u{200d}\\u{308}\",\n        \"\\u{5f}\"]), (\"\\u{200d}\\u{1f1e6}\", &[\"\\u{200d}\", \"\\u{1f1e6}\"]), (\"\\u{200d}\\u{308}\\u{1f1e6}\",\n        &[\"\\u{200d}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{200d}\\u{5d0}\", &[\"\\u{200d}\", \"\\u{5d0}\"]),\n        (\"\\u{200d}\\u{308}\\u{5d0}\", &[\"\\u{200d}\\u{308}\", \"\\u{5d0}\"]), (\"\\u{200d}\\u{22}\",\n        &[\"\\u{200d}\", \"\\u{22}\"]), (\"\\u{200d}\\u{308}\\u{22}\", &[\"\\u{200d}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{200d}\\u{27}\", &[\"\\u{200d}\", \"\\u{27}\"]), (\"\\u{200d}\\u{308}\\u{27}\", &[\"\\u{200d}\\u{308}\",\n        \"\\u{27}\"]), (\"\\u{200d}\\u{200d}\", &[\"\\u{200d}\\u{200d}\"]), (\"\\u{200d}\\u{308}\\u{200d}\",\n        &[\"\\u{200d}\\u{308}\\u{200d}\"]), (\"\\u{200d}\\u{a9}\", &[\"\\u{200d}\\u{a9}\"]),\n        (\"\\u{200d}\\u{308}\\u{a9}\", &[\"\\u{200d}\\u{308}\", \"\\u{a9}\"]), (\"\\u{200d}\\u{20}\", &[\"\\u{200d}\",\n        \"\\u{20}\"]), (\"\\u{200d}\\u{308}\\u{20}\", &[\"\\u{200d}\\u{308}\", \"\\u{20}\"]), (\"\\u{200d}\\u{0}\",\n        &[\"\\u{200d}\", \"\\u{0}\"]), (\"\\u{200d}\\u{308}\\u{0}\", &[\"\\u{200d}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{200d}\\u{61}\\u{2060}\", &[\"\\u{200d}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{200d}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{200d}\\u{308}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{200d}\\u{61}\\u{3a}\", &[\"\\u{200d}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{200d}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{200d}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{200d}\\u{61}\\u{27}\", &[\"\\u{200d}\", \"\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{200d}\\u{308}\\u{61}\\u{27}\", &[\"\\u{200d}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{200d}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{200d}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{200d}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{200d}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{200d}\\u{61}\\u{2c}\", &[\"\\u{200d}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{200d}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{200d}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{200d}\\u{31}\\u{3a}\", &[\"\\u{200d}\", \"\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{200d}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{200d}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{200d}\\u{31}\\u{27}\", &[\"\\u{200d}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{200d}\\u{308}\\u{31}\\u{27}\",\n        &[\"\\u{200d}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{200d}\\u{31}\\u{2c}\", &[\"\\u{200d}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{200d}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{200d}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{200d}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{200d}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{200d}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{200d}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{a9}\\u{d}\", &[\"\\u{a9}\", \"\\u{d}\"]), (\"\\u{a9}\\u{308}\\u{d}\", &[\"\\u{a9}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{a9}\\u{a}\", &[\"\\u{a9}\", \"\\u{a}\"]), (\"\\u{a9}\\u{308}\\u{a}\", &[\"\\u{a9}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{a9}\\u{b}\", &[\"\\u{a9}\", \"\\u{b}\"]), (\"\\u{a9}\\u{308}\\u{b}\", &[\"\\u{a9}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{a9}\\u{300}\", &[\"\\u{a9}\\u{300}\"]), (\"\\u{a9}\\u{308}\\u{300}\", &[\"\\u{a9}\\u{308}\\u{300}\"]),\n        (\"\\u{a9}\\u{ad}\", &[\"\\u{a9}\\u{ad}\"]), (\"\\u{a9}\\u{308}\\u{ad}\", &[\"\\u{a9}\\u{308}\\u{ad}\"]),\n        (\"\\u{a9}\\u{3031}\", &[\"\\u{a9}\", \"\\u{3031}\"]), (\"\\u{a9}\\u{308}\\u{3031}\", &[\"\\u{a9}\\u{308}\",\n        \"\\u{3031}\"]), (\"\\u{a9}\\u{24c2}\", &[\"\\u{a9}\", \"\\u{24c2}\"]), (\"\\u{a9}\\u{308}\\u{24c2}\",\n        &[\"\\u{a9}\\u{308}\", \"\\u{24c2}\"]), (\"\\u{a9}\\u{41}\", &[\"\\u{a9}\", \"\\u{41}\"]),\n        (\"\\u{a9}\\u{308}\\u{41}\", &[\"\\u{a9}\\u{308}\", \"\\u{41}\"]), (\"\\u{a9}\\u{3a}\", &[\"\\u{a9}\",\n        \"\\u{3a}\"]), (\"\\u{a9}\\u{308}\\u{3a}\", &[\"\\u{a9}\\u{308}\", \"\\u{3a}\"]), (\"\\u{a9}\\u{2c}\",\n        &[\"\\u{a9}\", \"\\u{2c}\"]), (\"\\u{a9}\\u{308}\\u{2c}\", &[\"\\u{a9}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{a9}\\u{2e}\", &[\"\\u{a9}\", \"\\u{2e}\"]), (\"\\u{a9}\\u{308}\\u{2e}\", &[\"\\u{a9}\\u{308}\",\n        \"\\u{2e}\"]), (\"\\u{a9}\\u{30}\", &[\"\\u{a9}\", \"\\u{30}\"]), (\"\\u{a9}\\u{308}\\u{30}\",\n        &[\"\\u{a9}\\u{308}\", \"\\u{30}\"]), (\"\\u{a9}\\u{5f}\", &[\"\\u{a9}\", \"\\u{5f}\"]),\n        (\"\\u{a9}\\u{308}\\u{5f}\", &[\"\\u{a9}\\u{308}\", \"\\u{5f}\"]), (\"\\u{a9}\\u{1f1e6}\", &[\"\\u{a9}\",\n        \"\\u{1f1e6}\"]), (\"\\u{a9}\\u{308}\\u{1f1e6}\", &[\"\\u{a9}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{a9}\\u{5d0}\", &[\"\\u{a9}\", \"\\u{5d0}\"]), (\"\\u{a9}\\u{308}\\u{5d0}\", &[\"\\u{a9}\\u{308}\",\n        \"\\u{5d0}\"]), (\"\\u{a9}\\u{22}\", &[\"\\u{a9}\", \"\\u{22}\"]), (\"\\u{a9}\\u{308}\\u{22}\",\n        &[\"\\u{a9}\\u{308}\", \"\\u{22}\"]), (\"\\u{a9}\\u{27}\", &[\"\\u{a9}\", \"\\u{27}\"]),\n        (\"\\u{a9}\\u{308}\\u{27}\", &[\"\\u{a9}\\u{308}\", \"\\u{27}\"]), (\"\\u{a9}\\u{200d}\",\n        &[\"\\u{a9}\\u{200d}\"]), (\"\\u{a9}\\u{308}\\u{200d}\", &[\"\\u{a9}\\u{308}\\u{200d}\"]),\n        (\"\\u{a9}\\u{a9}\", &[\"\\u{a9}\", \"\\u{a9}\"]), (\"\\u{a9}\\u{308}\\u{a9}\", &[\"\\u{a9}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{a9}\\u{20}\", &[\"\\u{a9}\", \"\\u{20}\"]), (\"\\u{a9}\\u{308}\\u{20}\",\n        &[\"\\u{a9}\\u{308}\", \"\\u{20}\"]), (\"\\u{a9}\\u{0}\", &[\"\\u{a9}\", \"\\u{0}\"]), (\"\\u{a9}\\u{308}\\u{0}\",\n        &[\"\\u{a9}\\u{308}\", \"\\u{0}\"]), (\"\\u{a9}\\u{61}\\u{2060}\", &[\"\\u{a9}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{a9}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{a9}\\u{308}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{a9}\\u{61}\\u{3a}\", &[\"\\u{a9}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{a9}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{a9}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{a9}\\u{61}\\u{27}\", &[\"\\u{a9}\", \"\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{a9}\\u{308}\\u{61}\\u{27}\", &[\"\\u{a9}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{a9}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{a9}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{a9}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{a9}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{a9}\\u{61}\\u{2c}\", &[\"\\u{a9}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{a9}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{a9}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{a9}\\u{31}\\u{3a}\", &[\"\\u{a9}\", \"\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{a9}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{a9}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{a9}\\u{31}\\u{27}\", &[\"\\u{a9}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{a9}\\u{308}\\u{31}\\u{27}\",\n        &[\"\\u{a9}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{a9}\\u{31}\\u{2c}\", &[\"\\u{a9}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{a9}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{a9}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{a9}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{a9}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{a9}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{a9}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{20}\\u{d}\", &[\"\\u{20}\", \"\\u{d}\"]), (\"\\u{20}\\u{308}\\u{d}\", &[\"\\u{20}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{20}\\u{a}\", &[\"\\u{20}\", \"\\u{a}\"]), (\"\\u{20}\\u{308}\\u{a}\", &[\"\\u{20}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{20}\\u{b}\", &[\"\\u{20}\", \"\\u{b}\"]), (\"\\u{20}\\u{308}\\u{b}\", &[\"\\u{20}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{20}\\u{300}\", &[\"\\u{20}\\u{300}\"]), (\"\\u{20}\\u{308}\\u{300}\", &[\"\\u{20}\\u{308}\\u{300}\"]),\n        (\"\\u{20}\\u{ad}\", &[\"\\u{20}\\u{ad}\"]), (\"\\u{20}\\u{308}\\u{ad}\", &[\"\\u{20}\\u{308}\\u{ad}\"]),\n        (\"\\u{20}\\u{3031}\", &[\"\\u{20}\", \"\\u{3031}\"]), (\"\\u{20}\\u{308}\\u{3031}\", &[\"\\u{20}\\u{308}\",\n        \"\\u{3031}\"]), (\"\\u{20}\\u{24c2}\", &[\"\\u{20}\", \"\\u{24c2}\"]), (\"\\u{20}\\u{308}\\u{24c2}\",\n        &[\"\\u{20}\\u{308}\", \"\\u{24c2}\"]), (\"\\u{20}\\u{41}\", &[\"\\u{20}\", \"\\u{41}\"]),\n        (\"\\u{20}\\u{308}\\u{41}\", &[\"\\u{20}\\u{308}\", \"\\u{41}\"]), (\"\\u{20}\\u{3a}\", &[\"\\u{20}\",\n        \"\\u{3a}\"]), (\"\\u{20}\\u{308}\\u{3a}\", &[\"\\u{20}\\u{308}\", \"\\u{3a}\"]), (\"\\u{20}\\u{2c}\",\n        &[\"\\u{20}\", \"\\u{2c}\"]), (\"\\u{20}\\u{308}\\u{2c}\", &[\"\\u{20}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{20}\\u{2e}\", &[\"\\u{20}\", \"\\u{2e}\"]), (\"\\u{20}\\u{308}\\u{2e}\", &[\"\\u{20}\\u{308}\",\n        \"\\u{2e}\"]), (\"\\u{20}\\u{30}\", &[\"\\u{20}\", \"\\u{30}\"]), (\"\\u{20}\\u{308}\\u{30}\",\n        &[\"\\u{20}\\u{308}\", \"\\u{30}\"]), (\"\\u{20}\\u{5f}\", &[\"\\u{20}\", \"\\u{5f}\"]),\n        (\"\\u{20}\\u{308}\\u{5f}\", &[\"\\u{20}\\u{308}\", \"\\u{5f}\"]), (\"\\u{20}\\u{1f1e6}\", &[\"\\u{20}\",\n        \"\\u{1f1e6}\"]), (\"\\u{20}\\u{308}\\u{1f1e6}\", &[\"\\u{20}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{20}\\u{5d0}\", &[\"\\u{20}\", \"\\u{5d0}\"]), (\"\\u{20}\\u{308}\\u{5d0}\", &[\"\\u{20}\\u{308}\",\n        \"\\u{5d0}\"]), (\"\\u{20}\\u{22}\", &[\"\\u{20}\", \"\\u{22}\"]), (\"\\u{20}\\u{308}\\u{22}\",\n        &[\"\\u{20}\\u{308}\", \"\\u{22}\"]), (\"\\u{20}\\u{27}\", &[\"\\u{20}\", \"\\u{27}\"]),\n        (\"\\u{20}\\u{308}\\u{27}\", &[\"\\u{20}\\u{308}\", \"\\u{27}\"]), (\"\\u{20}\\u{200d}\",\n        &[\"\\u{20}\\u{200d}\"]), (\"\\u{20}\\u{308}\\u{200d}\", &[\"\\u{20}\\u{308}\\u{200d}\"]),\n        (\"\\u{20}\\u{a9}\", &[\"\\u{20}\", \"\\u{a9}\"]), (\"\\u{20}\\u{308}\\u{a9}\", &[\"\\u{20}\\u{308}\",\n        \"\\u{a9}\"]), (\"\\u{20}\\u{20}\", &[\"\\u{20}\\u{20}\"]), (\"\\u{20}\\u{308}\\u{20}\", &[\"\\u{20}\\u{308}\",\n        \"\\u{20}\"]), (\"\\u{20}\\u{0}\", &[\"\\u{20}\", \"\\u{0}\"]), (\"\\u{20}\\u{308}\\u{0}\", &[\"\\u{20}\\u{308}\",\n        \"\\u{0}\"]), (\"\\u{20}\\u{61}\\u{2060}\", &[\"\\u{20}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{20}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{20}\\u{308}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{20}\\u{61}\\u{3a}\", &[\"\\u{20}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{20}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{20}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{20}\\u{61}\\u{27}\", &[\"\\u{20}\", \"\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{20}\\u{308}\\u{61}\\u{27}\", &[\"\\u{20}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{20}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{20}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{20}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{20}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{20}\\u{61}\\u{2c}\", &[\"\\u{20}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{20}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{20}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{20}\\u{31}\\u{3a}\", &[\"\\u{20}\", \"\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{20}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{20}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{20}\\u{31}\\u{27}\", &[\"\\u{20}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{20}\\u{308}\\u{31}\\u{27}\",\n        &[\"\\u{20}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{20}\\u{31}\\u{2c}\", &[\"\\u{20}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{20}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{20}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{20}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{20}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{20}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{20}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{0}\\u{d}\", &[\"\\u{0}\", \"\\u{d}\"]), (\"\\u{0}\\u{308}\\u{d}\", &[\"\\u{0}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{0}\\u{a}\", &[\"\\u{0}\", \"\\u{a}\"]), (\"\\u{0}\\u{308}\\u{a}\", &[\"\\u{0}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{0}\\u{b}\", &[\"\\u{0}\", \"\\u{b}\"]), (\"\\u{0}\\u{308}\\u{b}\", &[\"\\u{0}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{0}\\u{300}\", &[\"\\u{0}\\u{300}\"]), (\"\\u{0}\\u{308}\\u{300}\", &[\"\\u{0}\\u{308}\\u{300}\"]),\n        (\"\\u{0}\\u{ad}\", &[\"\\u{0}\\u{ad}\"]), (\"\\u{0}\\u{308}\\u{ad}\", &[\"\\u{0}\\u{308}\\u{ad}\"]),\n        (\"\\u{0}\\u{3031}\", &[\"\\u{0}\", \"\\u{3031}\"]), (\"\\u{0}\\u{308}\\u{3031}\", &[\"\\u{0}\\u{308}\",\n        \"\\u{3031}\"]), (\"\\u{0}\\u{24c2}\", &[\"\\u{0}\", \"\\u{24c2}\"]), (\"\\u{0}\\u{308}\\u{24c2}\",\n        &[\"\\u{0}\\u{308}\", \"\\u{24c2}\"]), (\"\\u{0}\\u{41}\", &[\"\\u{0}\", \"\\u{41}\"]),\n        (\"\\u{0}\\u{308}\\u{41}\", &[\"\\u{0}\\u{308}\", \"\\u{41}\"]), (\"\\u{0}\\u{3a}\", &[\"\\u{0}\", \"\\u{3a}\"]),\n        (\"\\u{0}\\u{308}\\u{3a}\", &[\"\\u{0}\\u{308}\", \"\\u{3a}\"]), (\"\\u{0}\\u{2c}\", &[\"\\u{0}\", \"\\u{2c}\"]),\n        (\"\\u{0}\\u{308}\\u{2c}\", &[\"\\u{0}\\u{308}\", \"\\u{2c}\"]), (\"\\u{0}\\u{2e}\", &[\"\\u{0}\", \"\\u{2e}\"]),\n        (\"\\u{0}\\u{308}\\u{2e}\", &[\"\\u{0}\\u{308}\", \"\\u{2e}\"]), (\"\\u{0}\\u{30}\", &[\"\\u{0}\", \"\\u{30}\"]),\n        (\"\\u{0}\\u{308}\\u{30}\", &[\"\\u{0}\\u{308}\", \"\\u{30}\"]), (\"\\u{0}\\u{5f}\", &[\"\\u{0}\", \"\\u{5f}\"]),\n        (\"\\u{0}\\u{308}\\u{5f}\", &[\"\\u{0}\\u{308}\", \"\\u{5f}\"]), (\"\\u{0}\\u{1f1e6}\", &[\"\\u{0}\",\n        \"\\u{1f1e6}\"]), (\"\\u{0}\\u{308}\\u{1f1e6}\", &[\"\\u{0}\\u{308}\", \"\\u{1f1e6}\"]), (\"\\u{0}\\u{5d0}\",\n        &[\"\\u{0}\", \"\\u{5d0}\"]), (\"\\u{0}\\u{308}\\u{5d0}\", &[\"\\u{0}\\u{308}\", \"\\u{5d0}\"]),\n        (\"\\u{0}\\u{22}\", &[\"\\u{0}\", \"\\u{22}\"]), (\"\\u{0}\\u{308}\\u{22}\", &[\"\\u{0}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{0}\\u{27}\", &[\"\\u{0}\", \"\\u{27}\"]), (\"\\u{0}\\u{308}\\u{27}\", &[\"\\u{0}\\u{308}\", \"\\u{27}\"]),\n        (\"\\u{0}\\u{200d}\", &[\"\\u{0}\\u{200d}\"]), (\"\\u{0}\\u{308}\\u{200d}\", &[\"\\u{0}\\u{308}\\u{200d}\"]),\n        (\"\\u{0}\\u{a9}\", &[\"\\u{0}\", \"\\u{a9}\"]), (\"\\u{0}\\u{308}\\u{a9}\", &[\"\\u{0}\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{0}\\u{20}\", &[\"\\u{0}\", \"\\u{20}\"]), (\"\\u{0}\\u{308}\\u{20}\", &[\"\\u{0}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{0}\\u{0}\", &[\"\\u{0}\", \"\\u{0}\"]), (\"\\u{0}\\u{308}\\u{0}\", &[\"\\u{0}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{0}\\u{61}\\u{2060}\", &[\"\\u{0}\", \"\\u{61}\\u{2060}\"]), (\"\\u{0}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{0}\\u{308}\", \"\\u{61}\\u{2060}\"]), (\"\\u{0}\\u{61}\\u{3a}\", &[\"\\u{0}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{0}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{0}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{0}\\u{61}\\u{27}\",\n        &[\"\\u{0}\", \"\\u{61}\", \"\\u{27}\"]), (\"\\u{0}\\u{308}\\u{61}\\u{27}\", &[\"\\u{0}\\u{308}\", \"\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{0}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{0}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{0}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{0}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{0}\\u{61}\\u{2c}\", &[\"\\u{0}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{0}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{0}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]), (\"\\u{0}\\u{31}\\u{3a}\", &[\"\\u{0}\", \"\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{0}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{0}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{0}\\u{31}\\u{27}\", &[\"\\u{0}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{0}\\u{308}\\u{31}\\u{27}\",\n        &[\"\\u{0}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{0}\\u{31}\\u{2c}\", &[\"\\u{0}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{0}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{0}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{0}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{0}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{0}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{0}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{61}\\u{2060}\\u{d}\", &[\"\\u{61}\\u{2060}\", \"\\u{d}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{d}\",\n        &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{d}\"]), (\"\\u{61}\\u{2060}\\u{a}\", &[\"\\u{61}\\u{2060}\", \"\\u{a}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{a}\", &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{a}\"]), (\"\\u{61}\\u{2060}\\u{b}\",\n        &[\"\\u{61}\\u{2060}\", \"\\u{b}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{b}\", &[\"\\u{61}\\u{2060}\\u{308}\",\n        \"\\u{b}\"]), (\"\\u{61}\\u{2060}\\u{300}\", &[\"\\u{61}\\u{2060}\\u{300}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{300}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{300}\"]),\n        (\"\\u{61}\\u{2060}\\u{ad}\", &[\"\\u{61}\\u{2060}\\u{ad}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{ad}\",\n        &[\"\\u{61}\\u{2060}\\u{308}\\u{ad}\"]), (\"\\u{61}\\u{2060}\\u{3031}\", &[\"\\u{61}\\u{2060}\",\n        \"\\u{3031}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{3031}\", &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{3031}\"]),\n        (\"\\u{61}\\u{2060}\\u{24c2}\", &[\"\\u{61}\\u{2060}\\u{24c2}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{24c2}\",\n        &[\"\\u{61}\\u{2060}\\u{308}\\u{24c2}\"]), (\"\\u{61}\\u{2060}\\u{41}\", &[\"\\u{61}\\u{2060}\\u{41}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{41}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{41}\"]), (\"\\u{61}\\u{2060}\\u{3a}\",\n        &[\"\\u{61}\\u{2060}\", \"\\u{3a}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{3a}\", &[\"\\u{61}\\u{2060}\\u{308}\",\n        \"\\u{3a}\"]), (\"\\u{61}\\u{2060}\\u{2c}\", &[\"\\u{61}\\u{2060}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{2c}\", &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2060}\\u{2e}\", &[\"\\u{61}\\u{2060}\", \"\\u{2e}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{2e}\",\n        &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{2e}\"]), (\"\\u{61}\\u{2060}\\u{30}\", &[\"\\u{61}\\u{2060}\\u{30}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{30}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{30}\"]), (\"\\u{61}\\u{2060}\\u{5f}\",\n        &[\"\\u{61}\\u{2060}\\u{5f}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{5f}\",\n        &[\"\\u{61}\\u{2060}\\u{308}\\u{5f}\"]), (\"\\u{61}\\u{2060}\\u{1f1e6}\", &[\"\\u{61}\\u{2060}\",\n        \"\\u{1f1e6}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{1f1e6}\", &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{61}\\u{2060}\\u{5d0}\", &[\"\\u{61}\\u{2060}\\u{5d0}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{5d0}\",\n        &[\"\\u{61}\\u{2060}\\u{308}\\u{5d0}\"]), (\"\\u{61}\\u{2060}\\u{22}\", &[\"\\u{61}\\u{2060}\", \"\\u{22}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{22}\", &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{61}\\u{2060}\\u{27}\", &[\"\\u{61}\\u{2060}\", \"\\u{27}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{27}\",\n        &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{27}\"]), (\"\\u{61}\\u{2060}\\u{200d}\",\n        &[\"\\u{61}\\u{2060}\\u{200d}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{200d}\",\n        &[\"\\u{61}\\u{2060}\\u{308}\\u{200d}\"]), (\"\\u{61}\\u{2060}\\u{a9}\", &[\"\\u{61}\\u{2060}\",\n        \"\\u{a9}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{a9}\", &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{61}\\u{2060}\\u{20}\", &[\"\\u{61}\\u{2060}\", \"\\u{20}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{20}\",\n        &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{20}\"]), (\"\\u{61}\\u{2060}\\u{0}\", &[\"\\u{61}\\u{2060}\",\n        \"\\u{0}\"]), (\"\\u{61}\\u{2060}\\u{308}\\u{0}\", &[\"\\u{61}\\u{2060}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{61}\\u{2060}\\u{61}\\u{2060}\", &[\"\\u{61}\\u{2060}\\u{61}\\u{2060}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{61}\\u{2060}\"]),\n        (\"\\u{61}\\u{2060}\\u{61}\\u{3a}\", &[\"\\u{61}\\u{2060}\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{61}\\u{2060}\\u{61}\\u{27}\", &[\"\\u{61}\\u{2060}\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{61}\\u{27}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{2060}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{61}\\u{2060}\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{61}\",\n        \"\\u{27}\\u{2060}\"]), (\"\\u{61}\\u{2060}\\u{61}\\u{2c}\", &[\"\\u{61}\\u{2060}\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2060}\\u{31}\\u{3a}\", &[\"\\u{61}\\u{2060}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{61}\\u{2060}\\u{31}\\u{27}\", &[\"\\u{61}\\u{2060}\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{31}\\u{27}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{2060}\\u{31}\\u{2c}\", &[\"\\u{61}\\u{2060}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2060}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{61}\\u{2060}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{61}\\u{2060}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{61}\\u{2060}\\u{308}\\u{31}\",\n        \"\\u{2e}\\u{2060}\"]), (\"\\u{61}\\u{3a}\\u{d}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{d}\"]),\n        (\"\\u{61}\\u{3a}\\u{308}\\u{d}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{d}\"]), (\"\\u{61}\\u{3a}\\u{a}\",\n        &[\"\\u{61}\", \"\\u{3a}\", \"\\u{a}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{a}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\",\n        \"\\u{a}\"]), (\"\\u{61}\\u{3a}\\u{b}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{b}\"]),\n        (\"\\u{61}\\u{3a}\\u{308}\\u{b}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{b}\"]), (\"\\u{61}\\u{3a}\\u{300}\",\n        &[\"\\u{61}\", \"\\u{3a}\\u{300}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{300}\", &[\"\\u{61}\",\n        \"\\u{3a}\\u{308}\\u{300}\"]), (\"\\u{61}\\u{3a}\\u{ad}\", &[\"\\u{61}\", \"\\u{3a}\\u{ad}\"]),\n        (\"\\u{61}\\u{3a}\\u{308}\\u{ad}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\\u{ad}\"]), (\"\\u{61}\\u{3a}\\u{3031}\",\n        &[\"\\u{61}\", \"\\u{3a}\", \"\\u{3031}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{3031}\", &[\"\\u{61}\",\n        \"\\u{3a}\\u{308}\", \"\\u{3031}\"]), (\"\\u{61}\\u{3a}\\u{24c2}\", &[\"\\u{61}\\u{3a}\\u{24c2}\"]),\n        (\"\\u{61}\\u{3a}\\u{308}\\u{24c2}\", &[\"\\u{61}\\u{3a}\\u{308}\\u{24c2}\"]), (\"\\u{61}\\u{3a}\\u{41}\",\n        &[\"\\u{61}\\u{3a}\\u{41}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{41}\", &[\"\\u{61}\\u{3a}\\u{308}\\u{41}\"]),\n        (\"\\u{61}\\u{3a}\\u{3a}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{3a}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{3a}\",\n        &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{3a}\"]), (\"\\u{61}\\u{3a}\\u{2c}\", &[\"\\u{61}\", \"\\u{3a}\",\n        \"\\u{2c}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{2c}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{3a}\\u{2e}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{2e}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{2e}\",\n        &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{2e}\"]), (\"\\u{61}\\u{3a}\\u{30}\", &[\"\\u{61}\", \"\\u{3a}\",\n        \"\\u{30}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{30}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{30}\"]),\n        (\"\\u{61}\\u{3a}\\u{5f}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{5f}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{5f}\",\n        &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{5f}\"]), (\"\\u{61}\\u{3a}\\u{1f1e6}\", &[\"\\u{61}\", \"\\u{3a}\",\n        \"\\u{1f1e6}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{1f1e6}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{61}\\u{3a}\\u{5d0}\", &[\"\\u{61}\\u{3a}\\u{5d0}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{5d0}\",\n        &[\"\\u{61}\\u{3a}\\u{308}\\u{5d0}\"]), (\"\\u{61}\\u{3a}\\u{22}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{22}\"]),\n        (\"\\u{61}\\u{3a}\\u{308}\\u{22}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{61}\\u{3a}\\u{27}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{27}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{27}\",\n        &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{27}\"]), (\"\\u{61}\\u{3a}\\u{200d}\", &[\"\\u{61}\",\n        \"\\u{3a}\\u{200d}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{200d}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\\u{200d}\"]),\n        (\"\\u{61}\\u{3a}\\u{a9}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{a9}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{a9}\",\n        &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{a9}\"]), (\"\\u{61}\\u{3a}\\u{20}\", &[\"\\u{61}\", \"\\u{3a}\",\n        \"\\u{20}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{20}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{61}\\u{3a}\\u{0}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{0}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{0}\",\n        &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{0}\"]), (\"\\u{61}\\u{3a}\\u{61}\\u{2060}\",\n        &[\"\\u{61}\\u{3a}\\u{61}\\u{2060}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{61}\\u{3a}\\u{308}\\u{61}\\u{2060}\"]), (\"\\u{61}\\u{3a}\\u{61}\\u{3a}\",\n        &[\"\\u{61}\\u{3a}\\u{61}\", \"\\u{3a}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{61}\\u{3a}\\u{308}\\u{61}\", \"\\u{3a}\"]), (\"\\u{61}\\u{3a}\\u{61}\\u{27}\",\n        &[\"\\u{61}\\u{3a}\\u{61}\", \"\\u{27}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{61}\\u{27}\",\n        &[\"\\u{61}\\u{3a}\\u{308}\\u{61}\", \"\\u{27}\"]), (\"\\u{61}\\u{3a}\\u{61}\\u{27}\\u{2060}\",\n        &[\"\\u{61}\\u{3a}\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{61}\\u{27}\\u{2060}\",\n        &[\"\\u{61}\\u{3a}\\u{308}\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{61}\\u{3a}\\u{61}\\u{2c}\",\n        &[\"\\u{61}\\u{3a}\\u{61}\", \"\\u{2c}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{61}\\u{3a}\\u{308}\\u{61}\", \"\\u{2c}\"]), (\"\\u{61}\\u{3a}\\u{31}\\u{3a}\", &[\"\\u{61}\",\n        \"\\u{3a}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{61}\",\n        \"\\u{3a}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{61}\\u{3a}\\u{31}\\u{27}\", &[\"\\u{61}\", \"\\u{3a}\",\n        \"\\u{31}\", \"\\u{27}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{31}\\u{27}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\",\n        \"\\u{31}\", \"\\u{27}\"]), (\"\\u{61}\\u{3a}\\u{31}\\u{2c}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{61}\\u{3a}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{31}\",\n        \"\\u{2e}\\u{2060}\"]), (\"\\u{61}\\u{3a}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{61}\", \"\\u{3a}\\u{308}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{61}\\u{27}\\u{d}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{d}\"]),\n        (\"\\u{61}\\u{27}\\u{308}\\u{d}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{d}\"]), (\"\\u{61}\\u{27}\\u{a}\",\n        &[\"\\u{61}\", \"\\u{27}\", \"\\u{a}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{a}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\",\n        \"\\u{a}\"]), (\"\\u{61}\\u{27}\\u{b}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{b}\"]),\n        (\"\\u{61}\\u{27}\\u{308}\\u{b}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{b}\"]), (\"\\u{61}\\u{27}\\u{300}\",\n        &[\"\\u{61}\", \"\\u{27}\\u{300}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{300}\", &[\"\\u{61}\",\n        \"\\u{27}\\u{308}\\u{300}\"]), (\"\\u{61}\\u{27}\\u{ad}\", &[\"\\u{61}\", \"\\u{27}\\u{ad}\"]),\n        (\"\\u{61}\\u{27}\\u{308}\\u{ad}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\\u{ad}\"]), (\"\\u{61}\\u{27}\\u{3031}\",\n        &[\"\\u{61}\", \"\\u{27}\", \"\\u{3031}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{3031}\", &[\"\\u{61}\",\n        \"\\u{27}\\u{308}\", \"\\u{3031}\"]), (\"\\u{61}\\u{27}\\u{24c2}\", &[\"\\u{61}\\u{27}\\u{24c2}\"]),\n        (\"\\u{61}\\u{27}\\u{308}\\u{24c2}\", &[\"\\u{61}\\u{27}\\u{308}\\u{24c2}\"]), (\"\\u{61}\\u{27}\\u{41}\",\n        &[\"\\u{61}\\u{27}\\u{41}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{41}\", &[\"\\u{61}\\u{27}\\u{308}\\u{41}\"]),\n        (\"\\u{61}\\u{27}\\u{3a}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{3a}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{3a}\",\n        &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{3a}\"]), (\"\\u{61}\\u{27}\\u{2c}\", &[\"\\u{61}\", \"\\u{27}\",\n        \"\\u{2c}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{2c}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{27}\\u{2e}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{2e}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{2e}\",\n        &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{2e}\"]), (\"\\u{61}\\u{27}\\u{30}\", &[\"\\u{61}\", \"\\u{27}\",\n        \"\\u{30}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{30}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{30}\"]),\n        (\"\\u{61}\\u{27}\\u{5f}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{5f}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{5f}\",\n        &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{5f}\"]), (\"\\u{61}\\u{27}\\u{1f1e6}\", &[\"\\u{61}\", \"\\u{27}\",\n        \"\\u{1f1e6}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{1f1e6}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{61}\\u{27}\\u{5d0}\", &[\"\\u{61}\\u{27}\\u{5d0}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{5d0}\",\n        &[\"\\u{61}\\u{27}\\u{308}\\u{5d0}\"]), (\"\\u{61}\\u{27}\\u{22}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{22}\"]),\n        (\"\\u{61}\\u{27}\\u{308}\\u{22}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{61}\\u{27}\\u{27}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{27}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{27}\",\n        &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{27}\"]), (\"\\u{61}\\u{27}\\u{200d}\", &[\"\\u{61}\",\n        \"\\u{27}\\u{200d}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{200d}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\\u{200d}\"]),\n        (\"\\u{61}\\u{27}\\u{a9}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{a9}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{a9}\",\n        &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{a9}\"]), (\"\\u{61}\\u{27}\\u{20}\", &[\"\\u{61}\", \"\\u{27}\",\n        \"\\u{20}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{20}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{61}\\u{27}\\u{0}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{0}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{0}\",\n        &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{0}\"]), (\"\\u{61}\\u{27}\\u{61}\\u{2060}\",\n        &[\"\\u{61}\\u{27}\\u{61}\\u{2060}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{61}\\u{27}\\u{308}\\u{61}\\u{2060}\"]), (\"\\u{61}\\u{27}\\u{61}\\u{3a}\",\n        &[\"\\u{61}\\u{27}\\u{61}\", \"\\u{3a}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{61}\\u{27}\\u{308}\\u{61}\", \"\\u{3a}\"]), (\"\\u{61}\\u{27}\\u{61}\\u{27}\",\n        &[\"\\u{61}\\u{27}\\u{61}\", \"\\u{27}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{61}\\u{27}\",\n        &[\"\\u{61}\\u{27}\\u{308}\\u{61}\", \"\\u{27}\"]), (\"\\u{61}\\u{27}\\u{61}\\u{27}\\u{2060}\",\n        &[\"\\u{61}\\u{27}\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{61}\\u{27}\\u{2060}\",\n        &[\"\\u{61}\\u{27}\\u{308}\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{61}\\u{27}\\u{61}\\u{2c}\",\n        &[\"\\u{61}\\u{27}\\u{61}\", \"\\u{2c}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{61}\\u{2c}\",\n        &[\"\\u{61}\\u{27}\\u{308}\\u{61}\", \"\\u{2c}\"]), (\"\\u{61}\\u{27}\\u{31}\\u{3a}\", &[\"\\u{61}\",\n        \"\\u{27}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{61}\",\n        \"\\u{27}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{61}\\u{27}\\u{31}\\u{27}\", &[\"\\u{61}\", \"\\u{27}\",\n        \"\\u{31}\", \"\\u{27}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{31}\\u{27}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\",\n        \"\\u{31}\", \"\\u{27}\"]), (\"\\u{61}\\u{27}\\u{31}\\u{2c}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{61}\\u{27}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{61}\", \"\\u{27}\", \"\\u{31}\",\n        \"\\u{2e}\\u{2060}\"]), (\"\\u{61}\\u{27}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{61}\", \"\\u{27}\\u{308}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{d}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\",\n        \"\\u{d}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{d}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\",\n        \"\\u{d}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{a}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{a}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{a}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{b}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{b}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{b}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{300}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{300}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{300}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\\u{300}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{ad}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{ad}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{ad}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\\u{ad}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{3031}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{3031}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{3031}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{3031}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{24c2}\", &[\"\\u{61}\\u{27}\\u{2060}\\u{24c2}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{24c2}\", &[\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{24c2}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{41}\", &[\"\\u{61}\\u{27}\\u{2060}\\u{41}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{41}\", &[\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{41}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{3a}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{3a}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{3a}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{3a}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{2c}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{2c}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{2e}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{2e}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{2e}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{2e}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{30}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{30}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{30}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{30}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{5f}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{5f}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{5f}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{5f}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{1f1e6}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{1f1e6}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{1f1e6}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{5d0}\", &[\"\\u{61}\\u{27}\\u{2060}\\u{5d0}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{5d0}\", &[\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{5d0}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{22}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{22}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{22}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{27}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{27}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{200d}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{200d}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{200d}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\\u{200d}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{a9}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{a9}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{a9}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{20}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{20}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{20}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{0}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{0}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{0}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{61}\\u{2060}\", &[\"\\u{61}\\u{27}\\u{2060}\\u{61}\\u{2060}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{61}\\u{2060}\",\n        &[\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{61}\\u{2060}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{61}\\u{3a}\",\n        &[\"\\u{61}\\u{27}\\u{2060}\\u{61}\", \"\\u{3a}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{61}\\u{3a}\",\n        &[\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{61}\", \"\\u{3a}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{61}\\u{27}\",\n        &[\"\\u{61}\\u{27}\\u{2060}\\u{61}\", \"\\u{27}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{61}\\u{27}\",\n        &[\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{61}\\u{27}\\u{2060}\\u{61}\",\n        \"\\u{27}\\u{2060}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{61}\\u{27}\\u{2060}\",\n        &[\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{61}\\u{2c}\", &[\"\\u{61}\\u{27}\\u{2060}\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{61}\",\n        \"\\u{2c}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{31}\\u{3a}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\",\n        \"\\u{31}\", \"\\u{3a}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{31}\\u{27}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\",\n        \"\\u{31}\", \"\\u{27}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{31}\\u{27}\", &[\"\\u{61}\",\n        \"\\u{27}\\u{2060}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{31}\\u{2c}\",\n        &[\"\\u{61}\", \"\\u{27}\\u{2060}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{61}\", \"\\u{27}\\u{2060}\",\n        \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{61}\\u{27}\\u{2060}\\u{308}\\u{31}\\u{2e}\\u{2060}\",\n        &[\"\\u{61}\", \"\\u{27}\\u{2060}\\u{308}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{61}\\u{2c}\\u{d}\",\n        &[\"\\u{61}\", \"\\u{2c}\", \"\\u{d}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{d}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\",\n        \"\\u{d}\"]), (\"\\u{61}\\u{2c}\\u{a}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{a}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{a}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{a}\"]), (\"\\u{61}\\u{2c}\\u{b}\",\n        &[\"\\u{61}\", \"\\u{2c}\", \"\\u{b}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{b}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\",\n        \"\\u{b}\"]), (\"\\u{61}\\u{2c}\\u{300}\", &[\"\\u{61}\", \"\\u{2c}\\u{300}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{300}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\\u{300}\"]), (\"\\u{61}\\u{2c}\\u{ad}\",\n        &[\"\\u{61}\", \"\\u{2c}\\u{ad}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{ad}\", &[\"\\u{61}\",\n        \"\\u{2c}\\u{308}\\u{ad}\"]), (\"\\u{61}\\u{2c}\\u{3031}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{3031}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{3031}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{3031}\"]),\n        (\"\\u{61}\\u{2c}\\u{24c2}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{24c2}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{24c2}\",\n        &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{24c2}\"]), (\"\\u{61}\\u{2c}\\u{41}\", &[\"\\u{61}\", \"\\u{2c}\",\n        \"\\u{41}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{41}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{41}\"]),\n        (\"\\u{61}\\u{2c}\\u{3a}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{3a}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{3a}\",\n        &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{3a}\"]), (\"\\u{61}\\u{2c}\\u{2c}\", &[\"\\u{61}\", \"\\u{2c}\",\n        \"\\u{2c}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{2c}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2c}\\u{2e}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{2e}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{2e}\",\n        &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{2e}\"]), (\"\\u{61}\\u{2c}\\u{30}\", &[\"\\u{61}\", \"\\u{2c}\",\n        \"\\u{30}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{30}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{30}\"]),\n        (\"\\u{61}\\u{2c}\\u{5f}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{5f}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{5f}\",\n        &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{5f}\"]), (\"\\u{61}\\u{2c}\\u{1f1e6}\", &[\"\\u{61}\", \"\\u{2c}\",\n        \"\\u{1f1e6}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{1f1e6}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{61}\\u{2c}\\u{5d0}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{5d0}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{5d0}\",\n        &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{5d0}\"]), (\"\\u{61}\\u{2c}\\u{22}\", &[\"\\u{61}\", \"\\u{2c}\",\n        \"\\u{22}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{22}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{61}\\u{2c}\\u{27}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{27}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{27}\",\n        &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{27}\"]), (\"\\u{61}\\u{2c}\\u{200d}\", &[\"\\u{61}\",\n        \"\\u{2c}\\u{200d}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{200d}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\\u{200d}\"]),\n        (\"\\u{61}\\u{2c}\\u{a9}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{a9}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{a9}\",\n        &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{a9}\"]), (\"\\u{61}\\u{2c}\\u{20}\", &[\"\\u{61}\", \"\\u{2c}\",\n        \"\\u{20}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{20}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{61}\\u{2c}\\u{0}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{0}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{0}\",\n        &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{0}\"]), (\"\\u{61}\\u{2c}\\u{61}\\u{2060}\", &[\"\\u{61}\", \"\\u{2c}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{61}\\u{2c}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{61}\\u{2c}\\u{61}\\u{3a}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{61}\\u{2c}\\u{61}\\u{27}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{61}\\u{27}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{2c}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{61}\",\n        \"\\u{27}\\u{2060}\"]), (\"\\u{61}\\u{2c}\\u{61}\\u{2c}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2c}\\u{31}\\u{3a}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{61}\\u{2c}\\u{31}\\u{27}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{31}\\u{27}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{61}\\u{2c}\\u{31}\\u{2c}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{61}\\u{2c}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{61}\\u{2c}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{61}\", \"\\u{2c}\\u{308}\", \"\\u{31}\",\n        \"\\u{2e}\\u{2060}\"]), (\"\\u{31}\\u{3a}\\u{d}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{d}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{d}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{d}\"]), (\"\\u{31}\\u{3a}\\u{a}\",\n        &[\"\\u{31}\", \"\\u{3a}\", \"\\u{a}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{a}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\",\n        \"\\u{a}\"]), (\"\\u{31}\\u{3a}\\u{b}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{b}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{b}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{b}\"]), (\"\\u{31}\\u{3a}\\u{300}\",\n        &[\"\\u{31}\", \"\\u{3a}\\u{300}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{300}\", &[\"\\u{31}\",\n        \"\\u{3a}\\u{308}\\u{300}\"]), (\"\\u{31}\\u{3a}\\u{ad}\", &[\"\\u{31}\", \"\\u{3a}\\u{ad}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{ad}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\\u{ad}\"]), (\"\\u{31}\\u{3a}\\u{3031}\",\n        &[\"\\u{31}\", \"\\u{3a}\", \"\\u{3031}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{3031}\", &[\"\\u{31}\",\n        \"\\u{3a}\\u{308}\", \"\\u{3031}\"]), (\"\\u{31}\\u{3a}\\u{24c2}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{24c2}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{24c2}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{24c2}\"]),\n        (\"\\u{31}\\u{3a}\\u{41}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{41}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{41}\",\n        &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{41}\"]), (\"\\u{31}\\u{3a}\\u{3a}\", &[\"\\u{31}\", \"\\u{3a}\",\n        \"\\u{3a}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{3a}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{3a}\\u{2c}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{2c}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{2c}\",\n        &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{2c}\"]), (\"\\u{31}\\u{3a}\\u{2e}\", &[\"\\u{31}\", \"\\u{3a}\",\n        \"\\u{2e}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{2e}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{2e}\"]),\n        (\"\\u{31}\\u{3a}\\u{30}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{30}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{30}\",\n        &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{30}\"]), (\"\\u{31}\\u{3a}\\u{5f}\", &[\"\\u{31}\", \"\\u{3a}\",\n        \"\\u{5f}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{5f}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{5f}\"]),\n        (\"\\u{31}\\u{3a}\\u{1f1e6}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{1f1e6}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{1f1e6}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{31}\\u{3a}\\u{5d0}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{5d0}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{5d0}\",\n        &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{5d0}\"]), (\"\\u{31}\\u{3a}\\u{22}\", &[\"\\u{31}\", \"\\u{3a}\",\n        \"\\u{22}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{22}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{31}\\u{3a}\\u{27}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{27}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{27}\",\n        &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{27}\"]), (\"\\u{31}\\u{3a}\\u{200d}\", &[\"\\u{31}\",\n        \"\\u{3a}\\u{200d}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{200d}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\\u{200d}\"]),\n        (\"\\u{31}\\u{3a}\\u{a9}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{a9}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{a9}\",\n        &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{a9}\"]), (\"\\u{31}\\u{3a}\\u{20}\", &[\"\\u{31}\", \"\\u{3a}\",\n        \"\\u{20}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{20}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{31}\\u{3a}\\u{0}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{0}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{0}\",\n        &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{0}\"]), (\"\\u{31}\\u{3a}\\u{61}\\u{2060}\", &[\"\\u{31}\", \"\\u{3a}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{31}\\u{3a}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{31}\\u{3a}\\u{61}\\u{3a}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{3a}\\u{61}\\u{27}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{61}\\u{27}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{3a}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{61}\",\n        \"\\u{27}\\u{2060}\"]), (\"\\u{31}\\u{3a}\\u{61}\\u{2c}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{3a}\\u{31}\\u{3a}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{3a}\\u{31}\\u{27}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{31}\\u{27}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{3a}\\u{31}\\u{2c}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{3a}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{31}\\u{3a}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{31}\", \"\\u{3a}\\u{308}\", \"\\u{31}\",\n        \"\\u{2e}\\u{2060}\"]), (\"\\u{31}\\u{27}\\u{d}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{d}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{d}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{d}\"]), (\"\\u{31}\\u{27}\\u{a}\",\n        &[\"\\u{31}\", \"\\u{27}\", \"\\u{a}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{a}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\",\n        \"\\u{a}\"]), (\"\\u{31}\\u{27}\\u{b}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{b}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{b}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{b}\"]), (\"\\u{31}\\u{27}\\u{300}\",\n        &[\"\\u{31}\", \"\\u{27}\\u{300}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{300}\", &[\"\\u{31}\",\n        \"\\u{27}\\u{308}\\u{300}\"]), (\"\\u{31}\\u{27}\\u{ad}\", &[\"\\u{31}\", \"\\u{27}\\u{ad}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{ad}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\\u{ad}\"]), (\"\\u{31}\\u{27}\\u{3031}\",\n        &[\"\\u{31}\", \"\\u{27}\", \"\\u{3031}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{3031}\", &[\"\\u{31}\",\n        \"\\u{27}\\u{308}\", \"\\u{3031}\"]), (\"\\u{31}\\u{27}\\u{24c2}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{24c2}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{24c2}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{24c2}\"]),\n        (\"\\u{31}\\u{27}\\u{41}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{41}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{41}\",\n        &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{41}\"]), (\"\\u{31}\\u{27}\\u{3a}\", &[\"\\u{31}\", \"\\u{27}\",\n        \"\\u{3a}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{3a}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{27}\\u{2c}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{2c}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{2c}\",\n        &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{2c}\"]), (\"\\u{31}\\u{27}\\u{2e}\", &[\"\\u{31}\", \"\\u{27}\",\n        \"\\u{2e}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{2e}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{2e}\"]),\n        (\"\\u{31}\\u{27}\\u{30}\", &[\"\\u{31}\\u{27}\\u{30}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{30}\",\n        &[\"\\u{31}\\u{27}\\u{308}\\u{30}\"]), (\"\\u{31}\\u{27}\\u{5f}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{5f}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{5f}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{5f}\"]),\n        (\"\\u{31}\\u{27}\\u{1f1e6}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{1f1e6}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{1f1e6}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{31}\\u{27}\\u{5d0}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{5d0}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{5d0}\",\n        &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{5d0}\"]), (\"\\u{31}\\u{27}\\u{22}\", &[\"\\u{31}\", \"\\u{27}\",\n        \"\\u{22}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{22}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{31}\\u{27}\\u{27}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{27}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{27}\",\n        &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{27}\"]), (\"\\u{31}\\u{27}\\u{200d}\", &[\"\\u{31}\",\n        \"\\u{27}\\u{200d}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{200d}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\\u{200d}\"]),\n        (\"\\u{31}\\u{27}\\u{a9}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{a9}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{a9}\",\n        &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{a9}\"]), (\"\\u{31}\\u{27}\\u{20}\", &[\"\\u{31}\", \"\\u{27}\",\n        \"\\u{20}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{20}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{31}\\u{27}\\u{0}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{0}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{0}\",\n        &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{0}\"]), (\"\\u{31}\\u{27}\\u{61}\\u{2060}\", &[\"\\u{31}\", \"\\u{27}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{31}\\u{27}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{31}\\u{27}\\u{61}\\u{3a}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{27}\\u{61}\\u{27}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{61}\\u{27}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{27}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{61}\",\n        \"\\u{27}\\u{2060}\"]), (\"\\u{31}\\u{27}\\u{61}\\u{2c}\", &[\"\\u{31}\", \"\\u{27}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{31}\", \"\\u{27}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{27}\\u{31}\\u{3a}\", &[\"\\u{31}\\u{27}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{31}\\u{27}\\u{308}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{27}\\u{31}\\u{27}\", &[\"\\u{31}\\u{27}\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{31}\\u{27}\", &[\"\\u{31}\\u{27}\\u{308}\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{27}\\u{31}\\u{2c}\", &[\"\\u{31}\\u{27}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{31}\\u{27}\\u{308}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{27}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{31}\\u{27}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{31}\\u{27}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{31}\\u{27}\\u{308}\\u{31}\",\n        \"\\u{2e}\\u{2060}\"]), (\"\\u{31}\\u{2c}\\u{d}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{d}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{d}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{d}\"]), (\"\\u{31}\\u{2c}\\u{a}\",\n        &[\"\\u{31}\", \"\\u{2c}\", \"\\u{a}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{a}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\",\n        \"\\u{a}\"]), (\"\\u{31}\\u{2c}\\u{b}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{b}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{b}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{b}\"]), (\"\\u{31}\\u{2c}\\u{300}\",\n        &[\"\\u{31}\", \"\\u{2c}\\u{300}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{300}\", &[\"\\u{31}\",\n        \"\\u{2c}\\u{308}\\u{300}\"]), (\"\\u{31}\\u{2c}\\u{ad}\", &[\"\\u{31}\", \"\\u{2c}\\u{ad}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{ad}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\\u{ad}\"]), (\"\\u{31}\\u{2c}\\u{3031}\",\n        &[\"\\u{31}\", \"\\u{2c}\", \"\\u{3031}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{3031}\", &[\"\\u{31}\",\n        \"\\u{2c}\\u{308}\", \"\\u{3031}\"]), (\"\\u{31}\\u{2c}\\u{24c2}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{24c2}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{24c2}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{24c2}\"]),\n        (\"\\u{31}\\u{2c}\\u{41}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{41}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{41}\",\n        &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{41}\"]), (\"\\u{31}\\u{2c}\\u{3a}\", &[\"\\u{31}\", \"\\u{2c}\",\n        \"\\u{3a}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{3a}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{2c}\\u{2c}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{2c}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{2c}\",\n        &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{2c}\"]), (\"\\u{31}\\u{2c}\\u{2e}\", &[\"\\u{31}\", \"\\u{2c}\",\n        \"\\u{2e}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{2e}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{2e}\"]),\n        (\"\\u{31}\\u{2c}\\u{30}\", &[\"\\u{31}\\u{2c}\\u{30}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{30}\",\n        &[\"\\u{31}\\u{2c}\\u{308}\\u{30}\"]), (\"\\u{31}\\u{2c}\\u{5f}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{5f}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{5f}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{5f}\"]),\n        (\"\\u{31}\\u{2c}\\u{1f1e6}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{1f1e6}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{1f1e6}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{31}\\u{2c}\\u{5d0}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{5d0}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{5d0}\",\n        &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{5d0}\"]), (\"\\u{31}\\u{2c}\\u{22}\", &[\"\\u{31}\", \"\\u{2c}\",\n        \"\\u{22}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{22}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{31}\\u{2c}\\u{27}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{27}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{27}\",\n        &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{27}\"]), (\"\\u{31}\\u{2c}\\u{200d}\", &[\"\\u{31}\",\n        \"\\u{2c}\\u{200d}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{200d}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\\u{200d}\"]),\n        (\"\\u{31}\\u{2c}\\u{a9}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{a9}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{a9}\",\n        &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{a9}\"]), (\"\\u{31}\\u{2c}\\u{20}\", &[\"\\u{31}\", \"\\u{2c}\",\n        \"\\u{20}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{20}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{31}\\u{2c}\\u{0}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{0}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{0}\",\n        &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{0}\"]), (\"\\u{31}\\u{2c}\\u{61}\\u{2060}\", &[\"\\u{31}\", \"\\u{2c}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{31}\\u{2c}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{31}\\u{2c}\\u{61}\\u{3a}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{2c}\\u{61}\\u{27}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{61}\\u{27}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{2c}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{61}\",\n        \"\\u{27}\\u{2060}\"]), (\"\\u{31}\\u{2c}\\u{61}\\u{2c}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{31}\", \"\\u{2c}\\u{308}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{2c}\\u{31}\\u{3a}\", &[\"\\u{31}\\u{2c}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{31}\\u{2c}\\u{308}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{2c}\\u{31}\\u{27}\", &[\"\\u{31}\\u{2c}\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{31}\\u{27}\", &[\"\\u{31}\\u{2c}\\u{308}\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{2c}\\u{31}\\u{2c}\", &[\"\\u{31}\\u{2c}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{31}\\u{2c}\\u{308}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{2c}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{31}\\u{2c}\\u{31}\", \"\\u{2e}\\u{2060}\"]),\n        (\"\\u{31}\\u{2c}\\u{308}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{31}\\u{2c}\\u{308}\\u{31}\",\n        \"\\u{2e}\\u{2060}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{d}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{d}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{d}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{d}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{a}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{a}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{a}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{a}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{b}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{b}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{b}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{b}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{300}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{300}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{300}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\\u{300}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{ad}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{ad}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{ad}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\\u{ad}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{3031}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{3031}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{3031}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{3031}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{24c2}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{24c2}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{24c2}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{24c2}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{41}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{41}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{41}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{41}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{3a}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{3a}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{2c}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{2c}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{2e}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{2e}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{2e}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{2e}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{30}\", &[\"\\u{31}\\u{2e}\\u{2060}\\u{30}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{30}\", &[\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{30}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{5f}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{5f}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{5f}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{5f}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{1f1e6}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{1f1e6}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{1f1e6}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{1f1e6}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{5d0}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{5d0}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{5d0}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{5d0}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{22}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{22}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{22}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{22}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{27}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{27}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{200d}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{200d}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{200d}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\\u{200d}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{a9}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{a9}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{a9}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{a9}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{20}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{20}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{20}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{20}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{0}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{0}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{0}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{0}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{61}\\u{2060}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{61}\\u{2060}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{61}\\u{2060}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\",\n        \"\\u{61}\\u{2060}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{61}\\u{3a}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\",\n        \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{61}\\u{3a}\", &[\"\\u{31}\",\n        \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{61}\", \"\\u{3a}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{61}\\u{27}\",\n        &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{61}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{61}\\u{27}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{61}\",\n        \"\\u{27}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{61}\\u{27}\\u{2060}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\",\n        \"\\u{61}\", \"\\u{27}\\u{2060}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{61}\\u{27}\\u{2060}\",\n        &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{61}\", \"\\u{27}\\u{2060}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{61}\\u{2c}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\", \"\\u{61}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{61}\\u{2c}\", &[\"\\u{31}\", \"\\u{2e}\\u{2060}\\u{308}\", \"\\u{61}\",\n        \"\\u{2c}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{31}\\u{3a}\", &[\"\\u{31}\\u{2e}\\u{2060}\\u{31}\", \"\\u{3a}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{31}\\u{3a}\", &[\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{31}\",\n        \"\\u{3a}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{31}\\u{27}\", &[\"\\u{31}\\u{2e}\\u{2060}\\u{31}\", \"\\u{27}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{31}\\u{27}\", &[\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{31}\",\n        \"\\u{27}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{31}\\u{2c}\", &[\"\\u{31}\\u{2e}\\u{2060}\\u{31}\", \"\\u{2c}\"]),\n        (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{31}\\u{2c}\", &[\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{31}\",\n        \"\\u{2c}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{31}\\u{2e}\\u{2060}\", &[\"\\u{31}\\u{2e}\\u{2060}\\u{31}\",\n        \"\\u{2e}\\u{2060}\"]), (\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{31}\\u{2e}\\u{2060}\",\n        &[\"\\u{31}\\u{2e}\\u{2060}\\u{308}\\u{31}\", \"\\u{2e}\\u{2060}\"]), (\"\\u{d}\\u{a}\\u{61}\\u{a}\\u{308}\",\n        &[\"\\u{d}\\u{a}\", \"\\u{61}\", \"\\u{a}\", \"\\u{308}\"]), (\"\\u{61}\\u{308}\", &[\"\\u{61}\\u{308}\"]),\n        (\"\\u{20}\\u{200d}\\u{646}\", &[\"\\u{20}\\u{200d}\", \"\\u{646}\"]), (\"\\u{646}\\u{200d}\\u{20}\",\n        &[\"\\u{646}\\u{200d}\", \"\\u{20}\"]),\n        (\"\\u{671}\\u{644}\\u{631}\\u{64e}\\u{651}\\u{62d}\\u{650}\\u{64a}\\u{645}\\u{650}\\u{20}\\u{6dd}\\u{661}\",\n        &[\"\\u{671}\\u{644}\\u{631}\\u{64e}\\u{651}\\u{62d}\\u{650}\\u{64a}\\u{645}\\u{650}\", \"\\u{20}\",\n        \"\\u{6dd}\\u{661}\"]),\n        (\"\\u{721}\\u{719}\\u{721}\\u{718}\\u{72a}\\u{710}\\u{20}\\u{70f}\\u{71d}\\u{717}\",\n        &[\"\\u{721}\\u{719}\\u{721}\\u{718}\\u{72a}\\u{710}\", \"\\u{20}\", \"\\u{70f}\\u{71d}\\u{717}\"]),\n        (\"\\u{72c}\\u{70f}\\u{72b}\\u{712}\\u{718}\", &[\"\\u{72c}\\u{70f}\\u{72b}\\u{712}\\u{718}\"]),\n        (\"\\u{41}\\u{41}\\u{41}\", &[\"\\u{41}\\u{41}\\u{41}\"]), (\"\\u{41}\\u{3a}\\u{41}\",\n        &[\"\\u{41}\\u{3a}\\u{41}\"]), (\"\\u{41}\\u{3a}\\u{3a}\\u{41}\", &[\"\\u{41}\", \"\\u{3a}\", \"\\u{3a}\",\n        \"\\u{41}\"]), (\"\\u{5d0}\\u{27}\", &[\"\\u{5d0}\\u{27}\"]), (\"\\u{5d0}\\u{22}\\u{5d0}\",\n        &[\"\\u{5d0}\\u{22}\\u{5d0}\"]), (\"\\u{41}\\u{30}\\u{30}\\u{41}\", &[\"\\u{41}\\u{30}\\u{30}\\u{41}\"]),\n        (\"\\u{30}\\u{2c}\\u{30}\", &[\"\\u{30}\\u{2c}\\u{30}\"]), (\"\\u{30}\\u{2c}\\u{2c}\\u{30}\", &[\"\\u{30}\",\n        \"\\u{2c}\", \"\\u{2c}\", \"\\u{30}\"]), (\"\\u{3031}\\u{3031}\", &[\"\\u{3031}\\u{3031}\"]),\n        (\"\\u{41}\\u{5f}\\u{30}\\u{5f}\\u{3031}\\u{5f}\", &[\"\\u{41}\\u{5f}\\u{30}\\u{5f}\\u{3031}\\u{5f}\"]),\n        (\"\\u{41}\\u{5f}\\u{5f}\\u{41}\", &[\"\\u{41}\\u{5f}\\u{5f}\\u{41}\"]),\n        (\"\\u{1f1e6}\\u{1f1e7}\\u{1f1e8}\\u{62}\", &[\"\\u{1f1e6}\\u{1f1e7}\", \"\\u{1f1e8}\", \"\\u{62}\"]),\n        (\"\\u{61}\\u{1f1e6}\\u{1f1e7}\\u{1f1e8}\\u{62}\", &[\"\\u{61}\", \"\\u{1f1e6}\\u{1f1e7}\", \"\\u{1f1e8}\",\n        \"\\u{62}\"]), (\"\\u{61}\\u{1f1e6}\\u{1f1e7}\\u{200d}\\u{1f1e8}\\u{62}\", &[\"\\u{61}\",\n        \"\\u{1f1e6}\\u{1f1e7}\\u{200d}\", \"\\u{1f1e8}\", \"\\u{62}\"]),\n        (\"\\u{61}\\u{1f1e6}\\u{200d}\\u{1f1e7}\\u{1f1e8}\\u{62}\", &[\"\\u{61}\",\n        \"\\u{1f1e6}\\u{200d}\\u{1f1e7}\", \"\\u{1f1e8}\", \"\\u{62}\"]),\n        (\"\\u{61}\\u{1f1e6}\\u{1f1e7}\\u{1f1e8}\\u{1f1e9}\\u{62}\", &[\"\\u{61}\", \"\\u{1f1e6}\\u{1f1e7}\",\n        \"\\u{1f1e8}\\u{1f1e9}\", \"\\u{62}\"]), (\"\\u{1f476}\\u{1f3ff}\\u{1f476}\", &[\"\\u{1f476}\\u{1f3ff}\",\n        \"\\u{1f476}\"]), (\"\\u{1f6d1}\\u{200d}\\u{1f6d1}\", &[\"\\u{1f6d1}\\u{200d}\\u{1f6d1}\"]),\n        (\"\\u{61}\\u{200d}\\u{1f6d1}\", &[\"\\u{61}\\u{200d}\\u{1f6d1}\"]), (\"\\u{2701}\\u{200d}\\u{2701}\",\n        &[\"\\u{2701}\\u{200d}\", \"\\u{2701}\"]), (\"\\u{61}\\u{200d}\\u{2701}\", &[\"\\u{61}\\u{200d}\",\n        \"\\u{2701}\"]), (\"\\u{1f476}\\u{1f3ff}\\u{308}\\u{200d}\\u{1f476}\\u{1f3ff}\",\n        &[\"\\u{1f476}\\u{1f3ff}\\u{308}\\u{200d}\\u{1f476}\\u{1f3ff}\"]), (\"\\u{1f6d1}\\u{1f3ff}\",\n        &[\"\\u{1f6d1}\\u{1f3ff}\"]), (\"\\u{200d}\\u{1f6d1}\\u{1f3ff}\", &[\"\\u{200d}\\u{1f6d1}\\u{1f3ff}\"]),\n        (\"\\u{200d}\\u{1f6d1}\", &[\"\\u{200d}\\u{1f6d1}\"]), (\"\\u{200d}\\u{1f6d1}\",\n        &[\"\\u{200d}\\u{1f6d1}\"]), (\"\\u{1f6d1}\\u{1f6d1}\", &[\"\\u{1f6d1}\", \"\\u{1f6d1}\"]),\n        (\"\\u{61}\\u{308}\\u{200d}\\u{308}\\u{62}\", &[\"\\u{61}\\u{308}\\u{200d}\\u{308}\\u{62}\"]),\n        (\"\\u{61}\\u{20}\\u{20}\\u{62}\", &[\"\\u{61}\", \"\\u{20}\\u{20}\", \"\\u{62}\"]),\n        (\"\\u{31}\\u{3a}\\u{3a}\\u{31}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{3a}\", \"\\u{31}\"]),\n        (\"\\u{31}\\u{5f}\\u{31}\\u{3a}\\u{3a}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{3a}\", \"\\u{3a}\",\n        \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{3a}\\u{3a}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{61}\", \"\\u{3a}\",\n        \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{31}\\u{3a}\\u{3a}\\u{61}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{3a}\",\n        \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{3a}\\u{3a}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{3a}\\u{3a}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{31}\\u{3a}\\u{2e}\\u{31}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{2e}\",\n        \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{3a}\\u{2e}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{3a}\\u{2e}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{31}\\u{3a}\\u{2e}\\u{61}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{2e}\",\n        \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{3a}\\u{2e}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{3a}\\u{2e}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{31}\\u{3a}\\u{2c}\\u{31}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{2c}\",\n        \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{3a}\\u{2c}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{3a}\\u{2c}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{31}\\u{3a}\\u{2c}\\u{61}\", &[\"\\u{31}\", \"\\u{3a}\", \"\\u{2c}\",\n        \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{3a}\\u{2c}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{3a}\\u{2c}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{31}\\u{2e}\\u{3a}\\u{31}\", &[\"\\u{31}\", \"\\u{2e}\", \"\\u{3a}\",\n        \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2e}\\u{3a}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2e}\\u{3a}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{31}\\u{2e}\\u{3a}\\u{61}\", &[\"\\u{31}\", \"\\u{2e}\", \"\\u{3a}\",\n        \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2e}\\u{3a}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2e}\\u{3a}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{31}\\u{2e}\\u{2e}\\u{31}\", &[\"\\u{31}\", \"\\u{2e}\", \"\\u{2e}\",\n        \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2e}\\u{2e}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2e}\\u{2e}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{31}\\u{2e}\\u{2e}\\u{61}\", &[\"\\u{31}\", \"\\u{2e}\", \"\\u{2e}\",\n        \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2e}\\u{2e}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2e}\\u{2e}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{31}\\u{2e}\\u{2c}\\u{31}\", &[\"\\u{31}\", \"\\u{2e}\", \"\\u{2c}\",\n        \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2e}\\u{2c}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2e}\\u{2c}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{31}\\u{2e}\\u{2c}\\u{61}\", &[\"\\u{31}\", \"\\u{2e}\", \"\\u{2c}\",\n        \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2e}\\u{2c}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2e}\\u{2c}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{31}\\u{2c}\\u{3a}\\u{31}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{3a}\",\n        \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2c}\\u{3a}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2c}\\u{3a}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{31}\\u{2c}\\u{3a}\\u{61}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{3a}\",\n        \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2c}\\u{3a}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2c}\\u{3a}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{31}\\u{2c}\\u{2e}\\u{31}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{2e}\",\n        \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2c}\\u{2e}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2c}\\u{2e}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{31}\\u{2c}\\u{2e}\\u{61}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{2e}\",\n        \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2c}\\u{2e}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2c}\\u{2e}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{31}\\u{2c}\\u{2c}\\u{31}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{2c}\",\n        \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2c}\\u{2c}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2c}\\u{2c}\\u{31}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{31}\\u{2c}\\u{2c}\\u{61}\", &[\"\\u{31}\", \"\\u{2c}\", \"\\u{2c}\",\n        \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{31}\\u{2c}\\u{2c}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{31}\\u{5f}\\u{61}\\u{2c}\\u{2c}\\u{61}\", &[\"\\u{31}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{61}\\u{3a}\\u{3a}\\u{31}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{3a}\",\n        \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{3a}\\u{3a}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{3a}\\u{3a}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{61}\\u{3a}\\u{3a}\\u{61}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{3a}\",\n        \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{3a}\\u{3a}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{3a}\\u{3a}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{61}\\u{3a}\\u{2e}\\u{31}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{2e}\",\n        \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{3a}\\u{2e}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{3a}\\u{2e}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{61}\\u{3a}\\u{2e}\\u{61}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{2e}\",\n        \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{3a}\\u{2e}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{3a}\\u{2e}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{61}\\u{3a}\\u{2c}\\u{31}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{2c}\",\n        \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{3a}\\u{2c}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{3a}\\u{2c}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{61}\\u{3a}\\u{2c}\\u{61}\", &[\"\\u{61}\", \"\\u{3a}\", \"\\u{2c}\",\n        \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{3a}\\u{2c}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{3a}\",\n        \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{3a}\\u{2c}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{3a}\", \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{61}\\u{2e}\\u{3a}\\u{31}\", &[\"\\u{61}\", \"\\u{2e}\", \"\\u{3a}\",\n        \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2e}\\u{3a}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2e}\\u{3a}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{61}\\u{2e}\\u{3a}\\u{61}\", &[\"\\u{61}\", \"\\u{2e}\", \"\\u{3a}\",\n        \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2e}\\u{3a}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2e}\\u{3a}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{61}\\u{2e}\\u{2e}\\u{31}\", &[\"\\u{61}\", \"\\u{2e}\", \"\\u{2e}\",\n        \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2e}\\u{2e}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2e}\\u{2e}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{61}\\u{2e}\\u{2e}\\u{61}\", &[\"\\u{61}\", \"\\u{2e}\", \"\\u{2e}\",\n        \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2e}\\u{2e}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2e}\\u{2e}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{61}\\u{2e}\\u{2c}\\u{31}\", &[\"\\u{61}\", \"\\u{2e}\", \"\\u{2c}\",\n        \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2e}\\u{2c}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2e}\\u{2c}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{61}\\u{2e}\\u{2c}\\u{61}\", &[\"\\u{61}\", \"\\u{2e}\", \"\\u{2c}\",\n        \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2e}\\u{2c}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2e}\",\n        \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2e}\\u{2c}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2e}\", \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{61}\\u{2c}\\u{3a}\\u{31}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{3a}\",\n        \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2c}\\u{3a}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2c}\\u{3a}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{3a}\", \"\\u{31}\"]), (\"\\u{61}\\u{2c}\\u{3a}\\u{61}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{3a}\",\n        \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2c}\\u{3a}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2c}\\u{3a}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{3a}\", \"\\u{61}\"]), (\"\\u{61}\\u{2c}\\u{2e}\\u{31}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{2e}\",\n        \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2c}\\u{2e}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2c}\\u{2e}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{2e}\", \"\\u{31}\"]), (\"\\u{61}\\u{2c}\\u{2e}\\u{61}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{2e}\",\n        \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2c}\\u{2e}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2c}\\u{2e}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{2e}\", \"\\u{61}\"]), (\"\\u{61}\\u{2c}\\u{2c}\\u{31}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{2c}\",\n        \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2c}\\u{2c}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2c}\\u{2c}\\u{31}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{2c}\", \"\\u{31}\"]), (\"\\u{61}\\u{2c}\\u{2c}\\u{61}\", &[\"\\u{61}\", \"\\u{2c}\", \"\\u{2c}\",\n        \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{31}\\u{2c}\\u{2c}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{31}\", \"\\u{2c}\",\n        \"\\u{2c}\", \"\\u{61}\"]), (\"\\u{61}\\u{5f}\\u{61}\\u{2c}\\u{2c}\\u{61}\", &[\"\\u{61}\\u{5f}\\u{61}\",\n        \"\\u{2c}\", \"\\u{2c}\", \"\\u{61}\"])\n    ];\n\n    // official Unicode test data\n    // http://www.unicode.org/Public/17.0.0/ucd/auxiliary/SentenceBreakTest.txt\n    pub const TEST_SENTENCE: &[(&str, &[&str])] = &[\n        (\"\\u{d}\\u{d}\", &[\"\\u{d}\", \"\\u{d}\"]), (\"\\u{d}\\u{308}\\u{d}\", &[\"\\u{d}\", \"\\u{308}\\u{d}\"]),\n        (\"\\u{d}\\u{a}\", &[\"\\u{d}\\u{a}\"]), (\"\\u{d}\\u{308}\\u{a}\", &[\"\\u{d}\", \"\\u{308}\\u{a}\"]),\n        (\"\\u{d}\\u{300}\", &[\"\\u{d}\", \"\\u{300}\"]), (\"\\u{d}\\u{308}\\u{300}\", &[\"\\u{d}\",\n        \"\\u{308}\\u{300}\"]), (\"\\u{d}\\u{ad}\", &[\"\\u{d}\", \"\\u{ad}\"]), (\"\\u{d}\\u{308}\\u{ad}\", &[\"\\u{d}\",\n        \"\\u{308}\\u{ad}\"]), (\"\\u{d}\\u{85}\", &[\"\\u{d}\", \"\\u{85}\"]), (\"\\u{d}\\u{308}\\u{85}\", &[\"\\u{d}\",\n        \"\\u{308}\\u{85}\"]), (\"\\u{d}\\u{9}\", &[\"\\u{d}\", \"\\u{9}\"]), (\"\\u{d}\\u{308}\\u{9}\", &[\"\\u{d}\",\n        \"\\u{308}\\u{9}\"]), (\"\\u{d}\\u{61}\", &[\"\\u{d}\", \"\\u{61}\"]), (\"\\u{d}\\u{308}\\u{61}\", &[\"\\u{d}\",\n        \"\\u{308}\\u{61}\"]), (\"\\u{d}\\u{41}\", &[\"\\u{d}\", \"\\u{41}\"]), (\"\\u{d}\\u{308}\\u{41}\", &[\"\\u{d}\",\n        \"\\u{308}\\u{41}\"]), (\"\\u{d}\\u{1bb}\", &[\"\\u{d}\", \"\\u{1bb}\"]), (\"\\u{d}\\u{308}\\u{1bb}\",\n        &[\"\\u{d}\", \"\\u{308}\\u{1bb}\"]), (\"\\u{d}\\u{30}\", &[\"\\u{d}\", \"\\u{30}\"]), (\"\\u{d}\\u{308}\\u{30}\",\n        &[\"\\u{d}\", \"\\u{308}\\u{30}\"]), (\"\\u{d}\\u{2e}\", &[\"\\u{d}\", \"\\u{2e}\"]), (\"\\u{d}\\u{308}\\u{2e}\",\n        &[\"\\u{d}\", \"\\u{308}\\u{2e}\"]), (\"\\u{d}\\u{21}\", &[\"\\u{d}\", \"\\u{21}\"]), (\"\\u{d}\\u{308}\\u{21}\",\n        &[\"\\u{d}\", \"\\u{308}\\u{21}\"]), (\"\\u{d}\\u{22}\", &[\"\\u{d}\", \"\\u{22}\"]), (\"\\u{d}\\u{308}\\u{22}\",\n        &[\"\\u{d}\", \"\\u{308}\\u{22}\"]), (\"\\u{d}\\u{2c}\", &[\"\\u{d}\", \"\\u{2c}\"]), (\"\\u{d}\\u{308}\\u{2c}\",\n        &[\"\\u{d}\", \"\\u{308}\\u{2c}\"]), (\"\\u{d}\\u{0}\", &[\"\\u{d}\", \"\\u{0}\"]), (\"\\u{d}\\u{308}\\u{0}\",\n        &[\"\\u{d}\", \"\\u{308}\\u{0}\"]), (\"\\u{a}\\u{d}\", &[\"\\u{a}\", \"\\u{d}\"]), (\"\\u{a}\\u{308}\\u{d}\",\n        &[\"\\u{a}\", \"\\u{308}\\u{d}\"]), (\"\\u{a}\\u{a}\", &[\"\\u{a}\", \"\\u{a}\"]), (\"\\u{a}\\u{308}\\u{a}\",\n        &[\"\\u{a}\", \"\\u{308}\\u{a}\"]), (\"\\u{a}\\u{300}\", &[\"\\u{a}\", \"\\u{300}\"]),\n        (\"\\u{a}\\u{308}\\u{300}\", &[\"\\u{a}\", \"\\u{308}\\u{300}\"]), (\"\\u{a}\\u{ad}\", &[\"\\u{a}\",\n        \"\\u{ad}\"]), (\"\\u{a}\\u{308}\\u{ad}\", &[\"\\u{a}\", \"\\u{308}\\u{ad}\"]), (\"\\u{a}\\u{85}\", &[\"\\u{a}\",\n        \"\\u{85}\"]), (\"\\u{a}\\u{308}\\u{85}\", &[\"\\u{a}\", \"\\u{308}\\u{85}\"]), (\"\\u{a}\\u{9}\", &[\"\\u{a}\",\n        \"\\u{9}\"]), (\"\\u{a}\\u{308}\\u{9}\", &[\"\\u{a}\", \"\\u{308}\\u{9}\"]), (\"\\u{a}\\u{61}\", &[\"\\u{a}\",\n        \"\\u{61}\"]), (\"\\u{a}\\u{308}\\u{61}\", &[\"\\u{a}\", \"\\u{308}\\u{61}\"]), (\"\\u{a}\\u{41}\", &[\"\\u{a}\",\n        \"\\u{41}\"]), (\"\\u{a}\\u{308}\\u{41}\", &[\"\\u{a}\", \"\\u{308}\\u{41}\"]), (\"\\u{a}\\u{1bb}\", &[\"\\u{a}\",\n        \"\\u{1bb}\"]), (\"\\u{a}\\u{308}\\u{1bb}\", &[\"\\u{a}\", \"\\u{308}\\u{1bb}\"]), (\"\\u{a}\\u{30}\",\n        &[\"\\u{a}\", \"\\u{30}\"]), (\"\\u{a}\\u{308}\\u{30}\", &[\"\\u{a}\", \"\\u{308}\\u{30}\"]), (\"\\u{a}\\u{2e}\",\n        &[\"\\u{a}\", \"\\u{2e}\"]), (\"\\u{a}\\u{308}\\u{2e}\", &[\"\\u{a}\", \"\\u{308}\\u{2e}\"]), (\"\\u{a}\\u{21}\",\n        &[\"\\u{a}\", \"\\u{21}\"]), (\"\\u{a}\\u{308}\\u{21}\", &[\"\\u{a}\", \"\\u{308}\\u{21}\"]), (\"\\u{a}\\u{22}\",\n        &[\"\\u{a}\", \"\\u{22}\"]), (\"\\u{a}\\u{308}\\u{22}\", &[\"\\u{a}\", \"\\u{308}\\u{22}\"]), (\"\\u{a}\\u{2c}\",\n        &[\"\\u{a}\", \"\\u{2c}\"]), (\"\\u{a}\\u{308}\\u{2c}\", &[\"\\u{a}\", \"\\u{308}\\u{2c}\"]), (\"\\u{a}\\u{0}\",\n        &[\"\\u{a}\", \"\\u{0}\"]), (\"\\u{a}\\u{308}\\u{0}\", &[\"\\u{a}\", \"\\u{308}\\u{0}\"]), (\"\\u{300}\\u{d}\",\n        &[\"\\u{300}\\u{d}\"]), (\"\\u{300}\\u{308}\\u{d}\", &[\"\\u{300}\\u{308}\\u{d}\"]), (\"\\u{300}\\u{a}\",\n        &[\"\\u{300}\\u{a}\"]), (\"\\u{300}\\u{308}\\u{a}\", &[\"\\u{300}\\u{308}\\u{a}\"]), (\"\\u{300}\\u{300}\",\n        &[\"\\u{300}\\u{300}\"]), (\"\\u{300}\\u{308}\\u{300}\", &[\"\\u{300}\\u{308}\\u{300}\"]),\n        (\"\\u{300}\\u{ad}\", &[\"\\u{300}\\u{ad}\"]), (\"\\u{300}\\u{308}\\u{ad}\", &[\"\\u{300}\\u{308}\\u{ad}\"]),\n        (\"\\u{300}\\u{85}\", &[\"\\u{300}\\u{85}\"]), (\"\\u{300}\\u{308}\\u{85}\", &[\"\\u{300}\\u{308}\\u{85}\"]),\n        (\"\\u{300}\\u{9}\", &[\"\\u{300}\\u{9}\"]), (\"\\u{300}\\u{308}\\u{9}\", &[\"\\u{300}\\u{308}\\u{9}\"]),\n        (\"\\u{300}\\u{61}\", &[\"\\u{300}\\u{61}\"]), (\"\\u{300}\\u{308}\\u{61}\", &[\"\\u{300}\\u{308}\\u{61}\"]),\n        (\"\\u{300}\\u{41}\", &[\"\\u{300}\\u{41}\"]), (\"\\u{300}\\u{308}\\u{41}\", &[\"\\u{300}\\u{308}\\u{41}\"]),\n        (\"\\u{300}\\u{1bb}\", &[\"\\u{300}\\u{1bb}\"]), (\"\\u{300}\\u{308}\\u{1bb}\",\n        &[\"\\u{300}\\u{308}\\u{1bb}\"]), (\"\\u{300}\\u{30}\", &[\"\\u{300}\\u{30}\"]), (\"\\u{300}\\u{308}\\u{30}\",\n        &[\"\\u{300}\\u{308}\\u{30}\"]), (\"\\u{300}\\u{2e}\", &[\"\\u{300}\\u{2e}\"]), (\"\\u{300}\\u{308}\\u{2e}\",\n        &[\"\\u{300}\\u{308}\\u{2e}\"]), (\"\\u{300}\\u{21}\", &[\"\\u{300}\\u{21}\"]), (\"\\u{300}\\u{308}\\u{21}\",\n        &[\"\\u{300}\\u{308}\\u{21}\"]), (\"\\u{300}\\u{22}\", &[\"\\u{300}\\u{22}\"]), (\"\\u{300}\\u{308}\\u{22}\",\n        &[\"\\u{300}\\u{308}\\u{22}\"]), (\"\\u{300}\\u{2c}\", &[\"\\u{300}\\u{2c}\"]), (\"\\u{300}\\u{308}\\u{2c}\",\n        &[\"\\u{300}\\u{308}\\u{2c}\"]), (\"\\u{300}\\u{0}\", &[\"\\u{300}\\u{0}\"]), (\"\\u{300}\\u{308}\\u{0}\",\n        &[\"\\u{300}\\u{308}\\u{0}\"]), (\"\\u{ad}\\u{d}\", &[\"\\u{ad}\\u{d}\"]), (\"\\u{ad}\\u{308}\\u{d}\",\n        &[\"\\u{ad}\\u{308}\\u{d}\"]), (\"\\u{ad}\\u{a}\", &[\"\\u{ad}\\u{a}\"]), (\"\\u{ad}\\u{308}\\u{a}\",\n        &[\"\\u{ad}\\u{308}\\u{a}\"]), (\"\\u{ad}\\u{300}\", &[\"\\u{ad}\\u{300}\"]), (\"\\u{ad}\\u{308}\\u{300}\",\n        &[\"\\u{ad}\\u{308}\\u{300}\"]), (\"\\u{ad}\\u{ad}\", &[\"\\u{ad}\\u{ad}\"]), (\"\\u{ad}\\u{308}\\u{ad}\",\n        &[\"\\u{ad}\\u{308}\\u{ad}\"]), (\"\\u{ad}\\u{85}\", &[\"\\u{ad}\\u{85}\"]), (\"\\u{ad}\\u{308}\\u{85}\",\n        &[\"\\u{ad}\\u{308}\\u{85}\"]), (\"\\u{ad}\\u{9}\", &[\"\\u{ad}\\u{9}\"]), (\"\\u{ad}\\u{308}\\u{9}\",\n        &[\"\\u{ad}\\u{308}\\u{9}\"]), (\"\\u{ad}\\u{61}\", &[\"\\u{ad}\\u{61}\"]), (\"\\u{ad}\\u{308}\\u{61}\",\n        &[\"\\u{ad}\\u{308}\\u{61}\"]), (\"\\u{ad}\\u{41}\", &[\"\\u{ad}\\u{41}\"]), (\"\\u{ad}\\u{308}\\u{41}\",\n        &[\"\\u{ad}\\u{308}\\u{41}\"]), (\"\\u{ad}\\u{1bb}\", &[\"\\u{ad}\\u{1bb}\"]), (\"\\u{ad}\\u{308}\\u{1bb}\",\n        &[\"\\u{ad}\\u{308}\\u{1bb}\"]), (\"\\u{ad}\\u{30}\", &[\"\\u{ad}\\u{30}\"]), (\"\\u{ad}\\u{308}\\u{30}\",\n        &[\"\\u{ad}\\u{308}\\u{30}\"]), (\"\\u{ad}\\u{2e}\", &[\"\\u{ad}\\u{2e}\"]), (\"\\u{ad}\\u{308}\\u{2e}\",\n        &[\"\\u{ad}\\u{308}\\u{2e}\"]), (\"\\u{ad}\\u{21}\", &[\"\\u{ad}\\u{21}\"]), (\"\\u{ad}\\u{308}\\u{21}\",\n        &[\"\\u{ad}\\u{308}\\u{21}\"]), (\"\\u{ad}\\u{22}\", &[\"\\u{ad}\\u{22}\"]), (\"\\u{ad}\\u{308}\\u{22}\",\n        &[\"\\u{ad}\\u{308}\\u{22}\"]), (\"\\u{ad}\\u{2c}\", &[\"\\u{ad}\\u{2c}\"]), (\"\\u{ad}\\u{308}\\u{2c}\",\n        &[\"\\u{ad}\\u{308}\\u{2c}\"]), (\"\\u{ad}\\u{0}\", &[\"\\u{ad}\\u{0}\"]), (\"\\u{ad}\\u{308}\\u{0}\",\n        &[\"\\u{ad}\\u{308}\\u{0}\"]), (\"\\u{85}\\u{d}\", &[\"\\u{85}\", \"\\u{d}\"]), (\"\\u{85}\\u{308}\\u{d}\",\n        &[\"\\u{85}\", \"\\u{308}\\u{d}\"]), (\"\\u{85}\\u{a}\", &[\"\\u{85}\", \"\\u{a}\"]), (\"\\u{85}\\u{308}\\u{a}\",\n        &[\"\\u{85}\", \"\\u{308}\\u{a}\"]), (\"\\u{85}\\u{300}\", &[\"\\u{85}\", \"\\u{300}\"]),\n        (\"\\u{85}\\u{308}\\u{300}\", &[\"\\u{85}\", \"\\u{308}\\u{300}\"]), (\"\\u{85}\\u{ad}\", &[\"\\u{85}\",\n        \"\\u{ad}\"]), (\"\\u{85}\\u{308}\\u{ad}\", &[\"\\u{85}\", \"\\u{308}\\u{ad}\"]), (\"\\u{85}\\u{85}\",\n        &[\"\\u{85}\", \"\\u{85}\"]), (\"\\u{85}\\u{308}\\u{85}\", &[\"\\u{85}\", \"\\u{308}\\u{85}\"]),\n        (\"\\u{85}\\u{9}\", &[\"\\u{85}\", \"\\u{9}\"]), (\"\\u{85}\\u{308}\\u{9}\", &[\"\\u{85}\", \"\\u{308}\\u{9}\"]),\n        (\"\\u{85}\\u{61}\", &[\"\\u{85}\", \"\\u{61}\"]), (\"\\u{85}\\u{308}\\u{61}\", &[\"\\u{85}\",\n        \"\\u{308}\\u{61}\"]), (\"\\u{85}\\u{41}\", &[\"\\u{85}\", \"\\u{41}\"]), (\"\\u{85}\\u{308}\\u{41}\",\n        &[\"\\u{85}\", \"\\u{308}\\u{41}\"]), (\"\\u{85}\\u{1bb}\", &[\"\\u{85}\", \"\\u{1bb}\"]),\n        (\"\\u{85}\\u{308}\\u{1bb}\", &[\"\\u{85}\", \"\\u{308}\\u{1bb}\"]), (\"\\u{85}\\u{30}\", &[\"\\u{85}\",\n        \"\\u{30}\"]), (\"\\u{85}\\u{308}\\u{30}\", &[\"\\u{85}\", \"\\u{308}\\u{30}\"]), (\"\\u{85}\\u{2e}\",\n        &[\"\\u{85}\", \"\\u{2e}\"]), (\"\\u{85}\\u{308}\\u{2e}\", &[\"\\u{85}\", \"\\u{308}\\u{2e}\"]),\n        (\"\\u{85}\\u{21}\", &[\"\\u{85}\", \"\\u{21}\"]), (\"\\u{85}\\u{308}\\u{21}\", &[\"\\u{85}\",\n        \"\\u{308}\\u{21}\"]), (\"\\u{85}\\u{22}\", &[\"\\u{85}\", \"\\u{22}\"]), (\"\\u{85}\\u{308}\\u{22}\",\n        &[\"\\u{85}\", \"\\u{308}\\u{22}\"]), (\"\\u{85}\\u{2c}\", &[\"\\u{85}\", \"\\u{2c}\"]),\n        (\"\\u{85}\\u{308}\\u{2c}\", &[\"\\u{85}\", \"\\u{308}\\u{2c}\"]), (\"\\u{85}\\u{0}\", &[\"\\u{85}\",\n        \"\\u{0}\"]), (\"\\u{85}\\u{308}\\u{0}\", &[\"\\u{85}\", \"\\u{308}\\u{0}\"]), (\"\\u{9}\\u{d}\",\n        &[\"\\u{9}\\u{d}\"]), (\"\\u{9}\\u{308}\\u{d}\", &[\"\\u{9}\\u{308}\\u{d}\"]), (\"\\u{9}\\u{a}\",\n        &[\"\\u{9}\\u{a}\"]), (\"\\u{9}\\u{308}\\u{a}\", &[\"\\u{9}\\u{308}\\u{a}\"]), (\"\\u{9}\\u{300}\",\n        &[\"\\u{9}\\u{300}\"]), (\"\\u{9}\\u{308}\\u{300}\", &[\"\\u{9}\\u{308}\\u{300}\"]), (\"\\u{9}\\u{ad}\",\n        &[\"\\u{9}\\u{ad}\"]), (\"\\u{9}\\u{308}\\u{ad}\", &[\"\\u{9}\\u{308}\\u{ad}\"]), (\"\\u{9}\\u{85}\",\n        &[\"\\u{9}\\u{85}\"]), (\"\\u{9}\\u{308}\\u{85}\", &[\"\\u{9}\\u{308}\\u{85}\"]), (\"\\u{9}\\u{9}\",\n        &[\"\\u{9}\\u{9}\"]), (\"\\u{9}\\u{308}\\u{9}\", &[\"\\u{9}\\u{308}\\u{9}\"]), (\"\\u{9}\\u{61}\",\n        &[\"\\u{9}\\u{61}\"]), (\"\\u{9}\\u{308}\\u{61}\", &[\"\\u{9}\\u{308}\\u{61}\"]), (\"\\u{9}\\u{41}\",\n        &[\"\\u{9}\\u{41}\"]), (\"\\u{9}\\u{308}\\u{41}\", &[\"\\u{9}\\u{308}\\u{41}\"]), (\"\\u{9}\\u{1bb}\",\n        &[\"\\u{9}\\u{1bb}\"]), (\"\\u{9}\\u{308}\\u{1bb}\", &[\"\\u{9}\\u{308}\\u{1bb}\"]), (\"\\u{9}\\u{30}\",\n        &[\"\\u{9}\\u{30}\"]), (\"\\u{9}\\u{308}\\u{30}\", &[\"\\u{9}\\u{308}\\u{30}\"]), (\"\\u{9}\\u{2e}\",\n        &[\"\\u{9}\\u{2e}\"]), (\"\\u{9}\\u{308}\\u{2e}\", &[\"\\u{9}\\u{308}\\u{2e}\"]), (\"\\u{9}\\u{21}\",\n        &[\"\\u{9}\\u{21}\"]), (\"\\u{9}\\u{308}\\u{21}\", &[\"\\u{9}\\u{308}\\u{21}\"]), (\"\\u{9}\\u{22}\",\n        &[\"\\u{9}\\u{22}\"]), (\"\\u{9}\\u{308}\\u{22}\", &[\"\\u{9}\\u{308}\\u{22}\"]), (\"\\u{9}\\u{2c}\",\n        &[\"\\u{9}\\u{2c}\"]), (\"\\u{9}\\u{308}\\u{2c}\", &[\"\\u{9}\\u{308}\\u{2c}\"]), (\"\\u{9}\\u{0}\",\n        &[\"\\u{9}\\u{0}\"]), (\"\\u{9}\\u{308}\\u{0}\", &[\"\\u{9}\\u{308}\\u{0}\"]), (\"\\u{61}\\u{d}\",\n        &[\"\\u{61}\\u{d}\"]), (\"\\u{61}\\u{308}\\u{d}\", &[\"\\u{61}\\u{308}\\u{d}\"]), (\"\\u{61}\\u{a}\",\n        &[\"\\u{61}\\u{a}\"]), (\"\\u{61}\\u{308}\\u{a}\", &[\"\\u{61}\\u{308}\\u{a}\"]), (\"\\u{61}\\u{300}\",\n        &[\"\\u{61}\\u{300}\"]), (\"\\u{61}\\u{308}\\u{300}\", &[\"\\u{61}\\u{308}\\u{300}\"]), (\"\\u{61}\\u{ad}\",\n        &[\"\\u{61}\\u{ad}\"]), (\"\\u{61}\\u{308}\\u{ad}\", &[\"\\u{61}\\u{308}\\u{ad}\"]), (\"\\u{61}\\u{85}\",\n        &[\"\\u{61}\\u{85}\"]), (\"\\u{61}\\u{308}\\u{85}\", &[\"\\u{61}\\u{308}\\u{85}\"]), (\"\\u{61}\\u{9}\",\n        &[\"\\u{61}\\u{9}\"]), (\"\\u{61}\\u{308}\\u{9}\", &[\"\\u{61}\\u{308}\\u{9}\"]), (\"\\u{61}\\u{61}\",\n        &[\"\\u{61}\\u{61}\"]), (\"\\u{61}\\u{308}\\u{61}\", &[\"\\u{61}\\u{308}\\u{61}\"]), (\"\\u{61}\\u{41}\",\n        &[\"\\u{61}\\u{41}\"]), (\"\\u{61}\\u{308}\\u{41}\", &[\"\\u{61}\\u{308}\\u{41}\"]), (\"\\u{61}\\u{1bb}\",\n        &[\"\\u{61}\\u{1bb}\"]), (\"\\u{61}\\u{308}\\u{1bb}\", &[\"\\u{61}\\u{308}\\u{1bb}\"]), (\"\\u{61}\\u{30}\",\n        &[\"\\u{61}\\u{30}\"]), (\"\\u{61}\\u{308}\\u{30}\", &[\"\\u{61}\\u{308}\\u{30}\"]), (\"\\u{61}\\u{2e}\",\n        &[\"\\u{61}\\u{2e}\"]), (\"\\u{61}\\u{308}\\u{2e}\", &[\"\\u{61}\\u{308}\\u{2e}\"]), (\"\\u{61}\\u{21}\",\n        &[\"\\u{61}\\u{21}\"]), (\"\\u{61}\\u{308}\\u{21}\", &[\"\\u{61}\\u{308}\\u{21}\"]), (\"\\u{61}\\u{22}\",\n        &[\"\\u{61}\\u{22}\"]), (\"\\u{61}\\u{308}\\u{22}\", &[\"\\u{61}\\u{308}\\u{22}\"]), (\"\\u{61}\\u{2c}\",\n        &[\"\\u{61}\\u{2c}\"]), (\"\\u{61}\\u{308}\\u{2c}\", &[\"\\u{61}\\u{308}\\u{2c}\"]), (\"\\u{61}\\u{0}\",\n        &[\"\\u{61}\\u{0}\"]), (\"\\u{61}\\u{308}\\u{0}\", &[\"\\u{61}\\u{308}\\u{0}\"]), (\"\\u{41}\\u{d}\",\n        &[\"\\u{41}\\u{d}\"]), (\"\\u{41}\\u{308}\\u{d}\", &[\"\\u{41}\\u{308}\\u{d}\"]), (\"\\u{41}\\u{a}\",\n        &[\"\\u{41}\\u{a}\"]), (\"\\u{41}\\u{308}\\u{a}\", &[\"\\u{41}\\u{308}\\u{a}\"]), (\"\\u{41}\\u{300}\",\n        &[\"\\u{41}\\u{300}\"]), (\"\\u{41}\\u{308}\\u{300}\", &[\"\\u{41}\\u{308}\\u{300}\"]), (\"\\u{41}\\u{ad}\",\n        &[\"\\u{41}\\u{ad}\"]), (\"\\u{41}\\u{308}\\u{ad}\", &[\"\\u{41}\\u{308}\\u{ad}\"]), (\"\\u{41}\\u{85}\",\n        &[\"\\u{41}\\u{85}\"]), (\"\\u{41}\\u{308}\\u{85}\", &[\"\\u{41}\\u{308}\\u{85}\"]), (\"\\u{41}\\u{9}\",\n        &[\"\\u{41}\\u{9}\"]), (\"\\u{41}\\u{308}\\u{9}\", &[\"\\u{41}\\u{308}\\u{9}\"]), (\"\\u{41}\\u{61}\",\n        &[\"\\u{41}\\u{61}\"]), (\"\\u{41}\\u{308}\\u{61}\", &[\"\\u{41}\\u{308}\\u{61}\"]), (\"\\u{41}\\u{41}\",\n        &[\"\\u{41}\\u{41}\"]), (\"\\u{41}\\u{308}\\u{41}\", &[\"\\u{41}\\u{308}\\u{41}\"]), (\"\\u{41}\\u{1bb}\",\n        &[\"\\u{41}\\u{1bb}\"]), (\"\\u{41}\\u{308}\\u{1bb}\", &[\"\\u{41}\\u{308}\\u{1bb}\"]), (\"\\u{41}\\u{30}\",\n        &[\"\\u{41}\\u{30}\"]), (\"\\u{41}\\u{308}\\u{30}\", &[\"\\u{41}\\u{308}\\u{30}\"]), (\"\\u{41}\\u{2e}\",\n        &[\"\\u{41}\\u{2e}\"]), (\"\\u{41}\\u{308}\\u{2e}\", &[\"\\u{41}\\u{308}\\u{2e}\"]), (\"\\u{41}\\u{21}\",\n        &[\"\\u{41}\\u{21}\"]), (\"\\u{41}\\u{308}\\u{21}\", &[\"\\u{41}\\u{308}\\u{21}\"]), (\"\\u{41}\\u{22}\",\n        &[\"\\u{41}\\u{22}\"]), (\"\\u{41}\\u{308}\\u{22}\", &[\"\\u{41}\\u{308}\\u{22}\"]), (\"\\u{41}\\u{2c}\",\n        &[\"\\u{41}\\u{2c}\"]), (\"\\u{41}\\u{308}\\u{2c}\", &[\"\\u{41}\\u{308}\\u{2c}\"]), (\"\\u{41}\\u{0}\",\n        &[\"\\u{41}\\u{0}\"]), (\"\\u{41}\\u{308}\\u{0}\", &[\"\\u{41}\\u{308}\\u{0}\"]), (\"\\u{1bb}\\u{d}\",\n        &[\"\\u{1bb}\\u{d}\"]), (\"\\u{1bb}\\u{308}\\u{d}\", &[\"\\u{1bb}\\u{308}\\u{d}\"]), (\"\\u{1bb}\\u{a}\",\n        &[\"\\u{1bb}\\u{a}\"]), (\"\\u{1bb}\\u{308}\\u{a}\", &[\"\\u{1bb}\\u{308}\\u{a}\"]), (\"\\u{1bb}\\u{300}\",\n        &[\"\\u{1bb}\\u{300}\"]), (\"\\u{1bb}\\u{308}\\u{300}\", &[\"\\u{1bb}\\u{308}\\u{300}\"]),\n        (\"\\u{1bb}\\u{ad}\", &[\"\\u{1bb}\\u{ad}\"]), (\"\\u{1bb}\\u{308}\\u{ad}\", &[\"\\u{1bb}\\u{308}\\u{ad}\"]),\n        (\"\\u{1bb}\\u{85}\", &[\"\\u{1bb}\\u{85}\"]), (\"\\u{1bb}\\u{308}\\u{85}\", &[\"\\u{1bb}\\u{308}\\u{85}\"]),\n        (\"\\u{1bb}\\u{9}\", &[\"\\u{1bb}\\u{9}\"]), (\"\\u{1bb}\\u{308}\\u{9}\", &[\"\\u{1bb}\\u{308}\\u{9}\"]),\n        (\"\\u{1bb}\\u{61}\", &[\"\\u{1bb}\\u{61}\"]), (\"\\u{1bb}\\u{308}\\u{61}\", &[\"\\u{1bb}\\u{308}\\u{61}\"]),\n        (\"\\u{1bb}\\u{41}\", &[\"\\u{1bb}\\u{41}\"]), (\"\\u{1bb}\\u{308}\\u{41}\", &[\"\\u{1bb}\\u{308}\\u{41}\"]),\n        (\"\\u{1bb}\\u{1bb}\", &[\"\\u{1bb}\\u{1bb}\"]), (\"\\u{1bb}\\u{308}\\u{1bb}\",\n        &[\"\\u{1bb}\\u{308}\\u{1bb}\"]), (\"\\u{1bb}\\u{30}\", &[\"\\u{1bb}\\u{30}\"]), (\"\\u{1bb}\\u{308}\\u{30}\",\n        &[\"\\u{1bb}\\u{308}\\u{30}\"]), (\"\\u{1bb}\\u{2e}\", &[\"\\u{1bb}\\u{2e}\"]), (\"\\u{1bb}\\u{308}\\u{2e}\",\n        &[\"\\u{1bb}\\u{308}\\u{2e}\"]), (\"\\u{1bb}\\u{21}\", &[\"\\u{1bb}\\u{21}\"]), (\"\\u{1bb}\\u{308}\\u{21}\",\n        &[\"\\u{1bb}\\u{308}\\u{21}\"]), (\"\\u{1bb}\\u{22}\", &[\"\\u{1bb}\\u{22}\"]), (\"\\u{1bb}\\u{308}\\u{22}\",\n        &[\"\\u{1bb}\\u{308}\\u{22}\"]), (\"\\u{1bb}\\u{2c}\", &[\"\\u{1bb}\\u{2c}\"]), (\"\\u{1bb}\\u{308}\\u{2c}\",\n        &[\"\\u{1bb}\\u{308}\\u{2c}\"]), (\"\\u{1bb}\\u{0}\", &[\"\\u{1bb}\\u{0}\"]), (\"\\u{1bb}\\u{308}\\u{0}\",\n        &[\"\\u{1bb}\\u{308}\\u{0}\"]), (\"\\u{30}\\u{d}\", &[\"\\u{30}\\u{d}\"]), (\"\\u{30}\\u{308}\\u{d}\",\n        &[\"\\u{30}\\u{308}\\u{d}\"]), (\"\\u{30}\\u{a}\", &[\"\\u{30}\\u{a}\"]), (\"\\u{30}\\u{308}\\u{a}\",\n        &[\"\\u{30}\\u{308}\\u{a}\"]), (\"\\u{30}\\u{300}\", &[\"\\u{30}\\u{300}\"]), (\"\\u{30}\\u{308}\\u{300}\",\n        &[\"\\u{30}\\u{308}\\u{300}\"]), (\"\\u{30}\\u{ad}\", &[\"\\u{30}\\u{ad}\"]), (\"\\u{30}\\u{308}\\u{ad}\",\n        &[\"\\u{30}\\u{308}\\u{ad}\"]), (\"\\u{30}\\u{85}\", &[\"\\u{30}\\u{85}\"]), (\"\\u{30}\\u{308}\\u{85}\",\n        &[\"\\u{30}\\u{308}\\u{85}\"]), (\"\\u{30}\\u{9}\", &[\"\\u{30}\\u{9}\"]), (\"\\u{30}\\u{308}\\u{9}\",\n        &[\"\\u{30}\\u{308}\\u{9}\"]), (\"\\u{30}\\u{61}\", &[\"\\u{30}\\u{61}\"]), (\"\\u{30}\\u{308}\\u{61}\",\n        &[\"\\u{30}\\u{308}\\u{61}\"]), (\"\\u{30}\\u{41}\", &[\"\\u{30}\\u{41}\"]), (\"\\u{30}\\u{308}\\u{41}\",\n        &[\"\\u{30}\\u{308}\\u{41}\"]), (\"\\u{30}\\u{1bb}\", &[\"\\u{30}\\u{1bb}\"]), (\"\\u{30}\\u{308}\\u{1bb}\",\n        &[\"\\u{30}\\u{308}\\u{1bb}\"]), (\"\\u{30}\\u{30}\", &[\"\\u{30}\\u{30}\"]), (\"\\u{30}\\u{308}\\u{30}\",\n        &[\"\\u{30}\\u{308}\\u{30}\"]), (\"\\u{30}\\u{2e}\", &[\"\\u{30}\\u{2e}\"]), (\"\\u{30}\\u{308}\\u{2e}\",\n        &[\"\\u{30}\\u{308}\\u{2e}\"]), (\"\\u{30}\\u{21}\", &[\"\\u{30}\\u{21}\"]), (\"\\u{30}\\u{308}\\u{21}\",\n        &[\"\\u{30}\\u{308}\\u{21}\"]), (\"\\u{30}\\u{22}\", &[\"\\u{30}\\u{22}\"]), (\"\\u{30}\\u{308}\\u{22}\",\n        &[\"\\u{30}\\u{308}\\u{22}\"]), (\"\\u{30}\\u{2c}\", &[\"\\u{30}\\u{2c}\"]), (\"\\u{30}\\u{308}\\u{2c}\",\n        &[\"\\u{30}\\u{308}\\u{2c}\"]), (\"\\u{30}\\u{0}\", &[\"\\u{30}\\u{0}\"]), (\"\\u{30}\\u{308}\\u{0}\",\n        &[\"\\u{30}\\u{308}\\u{0}\"]), (\"\\u{2e}\\u{d}\", &[\"\\u{2e}\\u{d}\"]), (\"\\u{2e}\\u{308}\\u{d}\",\n        &[\"\\u{2e}\\u{308}\\u{d}\"]), (\"\\u{2e}\\u{a}\", &[\"\\u{2e}\\u{a}\"]), (\"\\u{2e}\\u{308}\\u{a}\",\n        &[\"\\u{2e}\\u{308}\\u{a}\"]), (\"\\u{2e}\\u{300}\", &[\"\\u{2e}\\u{300}\"]), (\"\\u{2e}\\u{308}\\u{300}\",\n        &[\"\\u{2e}\\u{308}\\u{300}\"]), (\"\\u{2e}\\u{ad}\", &[\"\\u{2e}\\u{ad}\"]), (\"\\u{2e}\\u{308}\\u{ad}\",\n        &[\"\\u{2e}\\u{308}\\u{ad}\"]), (\"\\u{2e}\\u{85}\", &[\"\\u{2e}\\u{85}\"]), (\"\\u{2e}\\u{308}\\u{85}\",\n        &[\"\\u{2e}\\u{308}\\u{85}\"]), (\"\\u{2e}\\u{9}\", &[\"\\u{2e}\\u{9}\"]), (\"\\u{2e}\\u{308}\\u{9}\",\n        &[\"\\u{2e}\\u{308}\\u{9}\"]), (\"\\u{2e}\\u{61}\", &[\"\\u{2e}\\u{61}\"]), (\"\\u{2e}\\u{308}\\u{61}\",\n        &[\"\\u{2e}\\u{308}\\u{61}\"]), (\"\\u{2e}\\u{41}\", &[\"\\u{2e}\", \"\\u{41}\"]), (\"\\u{2e}\\u{308}\\u{41}\",\n        &[\"\\u{2e}\\u{308}\", \"\\u{41}\"]), (\"\\u{2e}\\u{1bb}\", &[\"\\u{2e}\", \"\\u{1bb}\"]),\n        (\"\\u{2e}\\u{308}\\u{1bb}\", &[\"\\u{2e}\\u{308}\", \"\\u{1bb}\"]), (\"\\u{2e}\\u{30}\",\n        &[\"\\u{2e}\\u{30}\"]), (\"\\u{2e}\\u{308}\\u{30}\", &[\"\\u{2e}\\u{308}\\u{30}\"]), (\"\\u{2e}\\u{2e}\",\n        &[\"\\u{2e}\\u{2e}\"]), (\"\\u{2e}\\u{308}\\u{2e}\", &[\"\\u{2e}\\u{308}\\u{2e}\"]), (\"\\u{2e}\\u{21}\",\n        &[\"\\u{2e}\\u{21}\"]), (\"\\u{2e}\\u{308}\\u{21}\", &[\"\\u{2e}\\u{308}\\u{21}\"]), (\"\\u{2e}\\u{22}\",\n        &[\"\\u{2e}\\u{22}\"]), (\"\\u{2e}\\u{308}\\u{22}\", &[\"\\u{2e}\\u{308}\\u{22}\"]), (\"\\u{2e}\\u{2c}\",\n        &[\"\\u{2e}\\u{2c}\"]), (\"\\u{2e}\\u{308}\\u{2c}\", &[\"\\u{2e}\\u{308}\\u{2c}\"]), (\"\\u{2e}\\u{0}\",\n        &[\"\\u{2e}\", \"\\u{0}\"]), (\"\\u{2e}\\u{308}\\u{0}\", &[\"\\u{2e}\\u{308}\", \"\\u{0}\"]), (\"\\u{21}\\u{d}\",\n        &[\"\\u{21}\\u{d}\"]), (\"\\u{21}\\u{308}\\u{d}\", &[\"\\u{21}\\u{308}\\u{d}\"]), (\"\\u{21}\\u{a}\",\n        &[\"\\u{21}\\u{a}\"]), (\"\\u{21}\\u{308}\\u{a}\", &[\"\\u{21}\\u{308}\\u{a}\"]), (\"\\u{21}\\u{300}\",\n        &[\"\\u{21}\\u{300}\"]), (\"\\u{21}\\u{308}\\u{300}\", &[\"\\u{21}\\u{308}\\u{300}\"]), (\"\\u{21}\\u{ad}\",\n        &[\"\\u{21}\\u{ad}\"]), (\"\\u{21}\\u{308}\\u{ad}\", &[\"\\u{21}\\u{308}\\u{ad}\"]), (\"\\u{21}\\u{85}\",\n        &[\"\\u{21}\\u{85}\"]), (\"\\u{21}\\u{308}\\u{85}\", &[\"\\u{21}\\u{308}\\u{85}\"]), (\"\\u{21}\\u{9}\",\n        &[\"\\u{21}\\u{9}\"]), (\"\\u{21}\\u{308}\\u{9}\", &[\"\\u{21}\\u{308}\\u{9}\"]), (\"\\u{21}\\u{61}\",\n        &[\"\\u{21}\", \"\\u{61}\"]), (\"\\u{21}\\u{308}\\u{61}\", &[\"\\u{21}\\u{308}\", \"\\u{61}\"]),\n        (\"\\u{21}\\u{41}\", &[\"\\u{21}\", \"\\u{41}\"]), (\"\\u{21}\\u{308}\\u{41}\", &[\"\\u{21}\\u{308}\",\n        \"\\u{41}\"]), (\"\\u{21}\\u{1bb}\", &[\"\\u{21}\", \"\\u{1bb}\"]), (\"\\u{21}\\u{308}\\u{1bb}\",\n        &[\"\\u{21}\\u{308}\", \"\\u{1bb}\"]), (\"\\u{21}\\u{30}\", &[\"\\u{21}\", \"\\u{30}\"]),\n        (\"\\u{21}\\u{308}\\u{30}\", &[\"\\u{21}\\u{308}\", \"\\u{30}\"]), (\"\\u{21}\\u{2e}\", &[\"\\u{21}\\u{2e}\"]),\n        (\"\\u{21}\\u{308}\\u{2e}\", &[\"\\u{21}\\u{308}\\u{2e}\"]), (\"\\u{21}\\u{21}\", &[\"\\u{21}\\u{21}\"]),\n        (\"\\u{21}\\u{308}\\u{21}\", &[\"\\u{21}\\u{308}\\u{21}\"]), (\"\\u{21}\\u{22}\", &[\"\\u{21}\\u{22}\"]),\n        (\"\\u{21}\\u{308}\\u{22}\", &[\"\\u{21}\\u{308}\\u{22}\"]), (\"\\u{21}\\u{2c}\", &[\"\\u{21}\\u{2c}\"]),\n        (\"\\u{21}\\u{308}\\u{2c}\", &[\"\\u{21}\\u{308}\\u{2c}\"]), (\"\\u{21}\\u{0}\", &[\"\\u{21}\", \"\\u{0}\"]),\n        (\"\\u{21}\\u{308}\\u{0}\", &[\"\\u{21}\\u{308}\", \"\\u{0}\"]), (\"\\u{22}\\u{d}\", &[\"\\u{22}\\u{d}\"]),\n        (\"\\u{22}\\u{308}\\u{d}\", &[\"\\u{22}\\u{308}\\u{d}\"]), (\"\\u{22}\\u{a}\", &[\"\\u{22}\\u{a}\"]),\n        (\"\\u{22}\\u{308}\\u{a}\", &[\"\\u{22}\\u{308}\\u{a}\"]), (\"\\u{22}\\u{300}\", &[\"\\u{22}\\u{300}\"]),\n        (\"\\u{22}\\u{308}\\u{300}\", &[\"\\u{22}\\u{308}\\u{300}\"]), (\"\\u{22}\\u{ad}\", &[\"\\u{22}\\u{ad}\"]),\n        (\"\\u{22}\\u{308}\\u{ad}\", &[\"\\u{22}\\u{308}\\u{ad}\"]), (\"\\u{22}\\u{85}\", &[\"\\u{22}\\u{85}\"]),\n        (\"\\u{22}\\u{308}\\u{85}\", &[\"\\u{22}\\u{308}\\u{85}\"]), (\"\\u{22}\\u{9}\", &[\"\\u{22}\\u{9}\"]),\n        (\"\\u{22}\\u{308}\\u{9}\", &[\"\\u{22}\\u{308}\\u{9}\"]), (\"\\u{22}\\u{61}\", &[\"\\u{22}\\u{61}\"]),\n        (\"\\u{22}\\u{308}\\u{61}\", &[\"\\u{22}\\u{308}\\u{61}\"]), (\"\\u{22}\\u{41}\", &[\"\\u{22}\\u{41}\"]),\n        (\"\\u{22}\\u{308}\\u{41}\", &[\"\\u{22}\\u{308}\\u{41}\"]), (\"\\u{22}\\u{1bb}\", &[\"\\u{22}\\u{1bb}\"]),\n        (\"\\u{22}\\u{308}\\u{1bb}\", &[\"\\u{22}\\u{308}\\u{1bb}\"]), (\"\\u{22}\\u{30}\", &[\"\\u{22}\\u{30}\"]),\n        (\"\\u{22}\\u{308}\\u{30}\", &[\"\\u{22}\\u{308}\\u{30}\"]), (\"\\u{22}\\u{2e}\", &[\"\\u{22}\\u{2e}\"]),\n        (\"\\u{22}\\u{308}\\u{2e}\", &[\"\\u{22}\\u{308}\\u{2e}\"]), (\"\\u{22}\\u{21}\", &[\"\\u{22}\\u{21}\"]),\n        (\"\\u{22}\\u{308}\\u{21}\", &[\"\\u{22}\\u{308}\\u{21}\"]), (\"\\u{22}\\u{22}\", &[\"\\u{22}\\u{22}\"]),\n        (\"\\u{22}\\u{308}\\u{22}\", &[\"\\u{22}\\u{308}\\u{22}\"]), (\"\\u{22}\\u{2c}\", &[\"\\u{22}\\u{2c}\"]),\n        (\"\\u{22}\\u{308}\\u{2c}\", &[\"\\u{22}\\u{308}\\u{2c}\"]), (\"\\u{22}\\u{0}\", &[\"\\u{22}\\u{0}\"]),\n        (\"\\u{22}\\u{308}\\u{0}\", &[\"\\u{22}\\u{308}\\u{0}\"]), (\"\\u{2c}\\u{d}\", &[\"\\u{2c}\\u{d}\"]),\n        (\"\\u{2c}\\u{308}\\u{d}\", &[\"\\u{2c}\\u{308}\\u{d}\"]), (\"\\u{2c}\\u{a}\", &[\"\\u{2c}\\u{a}\"]),\n        (\"\\u{2c}\\u{308}\\u{a}\", &[\"\\u{2c}\\u{308}\\u{a}\"]), (\"\\u{2c}\\u{300}\", &[\"\\u{2c}\\u{300}\"]),\n        (\"\\u{2c}\\u{308}\\u{300}\", &[\"\\u{2c}\\u{308}\\u{300}\"]), (\"\\u{2c}\\u{ad}\", &[\"\\u{2c}\\u{ad}\"]),\n        (\"\\u{2c}\\u{308}\\u{ad}\", &[\"\\u{2c}\\u{308}\\u{ad}\"]), (\"\\u{2c}\\u{85}\", &[\"\\u{2c}\\u{85}\"]),\n        (\"\\u{2c}\\u{308}\\u{85}\", &[\"\\u{2c}\\u{308}\\u{85}\"]), (\"\\u{2c}\\u{9}\", &[\"\\u{2c}\\u{9}\"]),\n        (\"\\u{2c}\\u{308}\\u{9}\", &[\"\\u{2c}\\u{308}\\u{9}\"]), (\"\\u{2c}\\u{61}\", &[\"\\u{2c}\\u{61}\"]),\n        (\"\\u{2c}\\u{308}\\u{61}\", &[\"\\u{2c}\\u{308}\\u{61}\"]), (\"\\u{2c}\\u{41}\", &[\"\\u{2c}\\u{41}\"]),\n        (\"\\u{2c}\\u{308}\\u{41}\", &[\"\\u{2c}\\u{308}\\u{41}\"]), (\"\\u{2c}\\u{1bb}\", &[\"\\u{2c}\\u{1bb}\"]),\n        (\"\\u{2c}\\u{308}\\u{1bb}\", &[\"\\u{2c}\\u{308}\\u{1bb}\"]), (\"\\u{2c}\\u{30}\", &[\"\\u{2c}\\u{30}\"]),\n        (\"\\u{2c}\\u{308}\\u{30}\", &[\"\\u{2c}\\u{308}\\u{30}\"]), (\"\\u{2c}\\u{2e}\", &[\"\\u{2c}\\u{2e}\"]),\n        (\"\\u{2c}\\u{308}\\u{2e}\", &[\"\\u{2c}\\u{308}\\u{2e}\"]), (\"\\u{2c}\\u{21}\", &[\"\\u{2c}\\u{21}\"]),\n        (\"\\u{2c}\\u{308}\\u{21}\", &[\"\\u{2c}\\u{308}\\u{21}\"]), (\"\\u{2c}\\u{22}\", &[\"\\u{2c}\\u{22}\"]),\n        (\"\\u{2c}\\u{308}\\u{22}\", &[\"\\u{2c}\\u{308}\\u{22}\"]), (\"\\u{2c}\\u{2c}\", &[\"\\u{2c}\\u{2c}\"]),\n        (\"\\u{2c}\\u{308}\\u{2c}\", &[\"\\u{2c}\\u{308}\\u{2c}\"]), (\"\\u{2c}\\u{0}\", &[\"\\u{2c}\\u{0}\"]),\n        (\"\\u{2c}\\u{308}\\u{0}\", &[\"\\u{2c}\\u{308}\\u{0}\"]), (\"\\u{0}\\u{d}\", &[\"\\u{0}\\u{d}\"]),\n        (\"\\u{0}\\u{308}\\u{d}\", &[\"\\u{0}\\u{308}\\u{d}\"]), (\"\\u{0}\\u{a}\", &[\"\\u{0}\\u{a}\"]),\n        (\"\\u{0}\\u{308}\\u{a}\", &[\"\\u{0}\\u{308}\\u{a}\"]), (\"\\u{0}\\u{300}\", &[\"\\u{0}\\u{300}\"]),\n        (\"\\u{0}\\u{308}\\u{300}\", &[\"\\u{0}\\u{308}\\u{300}\"]), (\"\\u{0}\\u{ad}\", &[\"\\u{0}\\u{ad}\"]),\n        (\"\\u{0}\\u{308}\\u{ad}\", &[\"\\u{0}\\u{308}\\u{ad}\"]), (\"\\u{0}\\u{85}\", &[\"\\u{0}\\u{85}\"]),\n        (\"\\u{0}\\u{308}\\u{85}\", &[\"\\u{0}\\u{308}\\u{85}\"]), (\"\\u{0}\\u{9}\", &[\"\\u{0}\\u{9}\"]),\n        (\"\\u{0}\\u{308}\\u{9}\", &[\"\\u{0}\\u{308}\\u{9}\"]), (\"\\u{0}\\u{61}\", &[\"\\u{0}\\u{61}\"]),\n        (\"\\u{0}\\u{308}\\u{61}\", &[\"\\u{0}\\u{308}\\u{61}\"]), (\"\\u{0}\\u{41}\", &[\"\\u{0}\\u{41}\"]),\n        (\"\\u{0}\\u{308}\\u{41}\", &[\"\\u{0}\\u{308}\\u{41}\"]), (\"\\u{0}\\u{1bb}\", &[\"\\u{0}\\u{1bb}\"]),\n        (\"\\u{0}\\u{308}\\u{1bb}\", &[\"\\u{0}\\u{308}\\u{1bb}\"]), (\"\\u{0}\\u{30}\", &[\"\\u{0}\\u{30}\"]),\n        (\"\\u{0}\\u{308}\\u{30}\", &[\"\\u{0}\\u{308}\\u{30}\"]), (\"\\u{0}\\u{2e}\", &[\"\\u{0}\\u{2e}\"]),\n        (\"\\u{0}\\u{308}\\u{2e}\", &[\"\\u{0}\\u{308}\\u{2e}\"]), (\"\\u{0}\\u{21}\", &[\"\\u{0}\\u{21}\"]),\n        (\"\\u{0}\\u{308}\\u{21}\", &[\"\\u{0}\\u{308}\\u{21}\"]), (\"\\u{0}\\u{22}\", &[\"\\u{0}\\u{22}\"]),\n        (\"\\u{0}\\u{308}\\u{22}\", &[\"\\u{0}\\u{308}\\u{22}\"]), (\"\\u{0}\\u{2c}\", &[\"\\u{0}\\u{2c}\"]),\n        (\"\\u{0}\\u{308}\\u{2c}\", &[\"\\u{0}\\u{308}\\u{2c}\"]), (\"\\u{0}\\u{0}\", &[\"\\u{0}\\u{0}\"]),\n        (\"\\u{0}\\u{308}\\u{0}\", &[\"\\u{0}\\u{308}\\u{0}\"]), (\"\\u{d}\\u{a}\\u{61}\\u{a}\\u{308}\",\n        &[\"\\u{d}\\u{a}\", \"\\u{61}\\u{a}\", \"\\u{308}\"]), (\"\\u{61}\\u{308}\", &[\"\\u{61}\\u{308}\"]),\n        (\"\\u{20}\\u{200d}\\u{646}\", &[\"\\u{20}\\u{200d}\\u{646}\"]), (\"\\u{646}\\u{200d}\\u{20}\",\n        &[\"\\u{646}\\u{200d}\\u{20}\"]),\n        (\"\\u{28}\\u{22}\\u{47}\\u{6f}\\u{2e}\\u{22}\\u{29}\\u{20}\\u{28}\\u{48}\\u{65}\\u{20}\\u{64}\\u{69}\\u{64}\\u{2e}\\u{29}\",\n        &[\"\\u{28}\\u{22}\\u{47}\\u{6f}\\u{2e}\\u{22}\\u{29}\\u{20}\",\n        \"\\u{28}\\u{48}\\u{65}\\u{20}\\u{64}\\u{69}\\u{64}\\u{2e}\\u{29}\"]),\n        (\"\\u{28}\\u{201c}\\u{47}\\u{6f}\\u{3f}\\u{201d}\\u{29}\\u{20}\\u{28}\\u{48}\\u{65}\\u{20}\\u{64}\\u{69}\\u{64}\\u{2e}\\u{29}\",\n        &[\"\\u{28}\\u{201c}\\u{47}\\u{6f}\\u{3f}\\u{201d}\\u{29}\\u{20}\",\n        \"\\u{28}\\u{48}\\u{65}\\u{20}\\u{64}\\u{69}\\u{64}\\u{2e}\\u{29}\"]),\n        (\"\\u{55}\\u{2e}\\u{53}\\u{2e}\\u{41}\\u{300}\\u{2e}\\u{20}\\u{69}\\u{73}\",\n        &[\"\\u{55}\\u{2e}\\u{53}\\u{2e}\\u{41}\\u{300}\\u{2e}\\u{20}\\u{69}\\u{73}\"]),\n        (\"\\u{55}\\u{2e}\\u{53}\\u{2e}\\u{41}\\u{300}\\u{3f}\\u{20}\\u{48}\\u{65}\",\n        &[\"\\u{55}\\u{2e}\\u{53}\\u{2e}\\u{41}\\u{300}\\u{3f}\\u{20}\", \"\\u{48}\\u{65}\"]),\n        (\"\\u{55}\\u{2e}\\u{53}\\u{2e}\\u{41}\\u{300}\\u{2e}\",\n        &[\"\\u{55}\\u{2e}\\u{53}\\u{2e}\\u{41}\\u{300}\\u{2e}\"]), (\"\\u{33}\\u{2e}\\u{34}\",\n        &[\"\\u{33}\\u{2e}\\u{34}\"]), (\"\\u{63}\\u{2e}\\u{64}\", &[\"\\u{63}\\u{2e}\\u{64}\"]),\n        (\"\\u{43}\\u{2e}\\u{64}\", &[\"\\u{43}\\u{2e}\\u{64}\"]), (\"\\u{63}\\u{2e}\\u{44}\",\n        &[\"\\u{63}\\u{2e}\\u{44}\"]), (\"\\u{43}\\u{2e}\\u{44}\", &[\"\\u{43}\\u{2e}\\u{44}\"]),\n        (\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\\u{74}\\u{68}\\u{65}\",\n        &[\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\\u{74}\\u{68}\\u{65}\"]),\n        (\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\\u{54}\\u{68}\\u{65}\",\n        &[\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\", \"\\u{54}\\u{68}\\u{65}\"]),\n        (\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\\u{2018}\\u{28}\\u{74}\\u{68}\\u{65}\",\n        &[\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\\u{2018}\\u{28}\\u{74}\\u{68}\\u{65}\"]),\n        (\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\\u{2018}\\u{28}\\u{54}\\u{68}\\u{65}\",\n        &[\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\", \"\\u{2018}\\u{28}\\u{54}\\u{68}\\u{65}\"]),\n        (\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\\u{308}\\u{74}\\u{68}\\u{65}\",\n        &[\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\\u{308}\\u{74}\\u{68}\\u{65}\"]),\n        (\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\\u{308}\\u{54}\\u{68}\\u{65}\",\n        &[\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{a0}\\u{308}\", \"\\u{54}\\u{68}\\u{65}\"]),\n        (\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{308}\\u{54}\\u{68}\\u{65}\",\n        &[\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{2019}\\u{308}\", \"\\u{54}\\u{68}\\u{65}\"]),\n        (\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{a}\\u{308}\\u{54}\\u{68}\\u{65}\",\n        &[\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{29}\\u{a}\", \"\\u{308}\\u{54}\\u{68}\\u{65}\"]),\n        (\"\\u{74}\\u{68}\\u{65}\\u{20}\\u{72}\\u{65}\\u{73}\\u{70}\\u{2e}\\u{20}\\u{6c}\\u{65}\\u{61}\\u{64}\\u{65}\\u{72}\\u{73}\\u{20}\\u{61}\\u{72}\\u{65}\",\n        &[\"\\u{74}\\u{68}\\u{65}\\u{20}\\u{72}\\u{65}\\u{73}\\u{70}\\u{2e}\\u{20}\\u{6c}\\u{65}\\u{61}\\u{64}\\u{65}\\u{72}\\u{73}\\u{20}\\u{61}\\u{72}\\u{65}\"]),\n        (\"\\u{5b57}\\u{2e}\\u{5b57}\", &[\"\\u{5b57}\\u{2e}\", \"\\u{5b57}\"]),\n        (\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{5b83}\", &[\"\\u{65}\\u{74}\\u{63}\\u{2e}\", \"\\u{5b83}\"]),\n        (\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{3002}\", &[\"\\u{65}\\u{74}\\u{63}\\u{2e}\\u{3002}\"]),\n        (\"\\u{5b57}\\u{3002}\\u{5b83}\", &[\"\\u{5b57}\\u{3002}\", \"\\u{5b83}\"]), (\"\\u{21}\\u{20}\\u{20}\",\n        &[\"\\u{21}\\u{20}\\u{20}\"]), (\"\\u{61}\\u{2e}\", &[\"\\u{61}\\u{2e}\"]), (\"\\u{61}\\u{2e}\\u{d}\\u{a}\",\n        &[\"\\u{61}\\u{2e}\\u{d}\\u{a}\"]), (\"\\u{61}\\u{2e}\\u{d}\\u{a}\\u{20}\", &[\"\\u{61}\\u{2e}\\u{d}\\u{a}\",\n        \"\\u{20}\"]), (\"\\u{61}\\u{2e}\\u{d}\\u{a}\\u{61}\", &[\"\\u{61}\\u{2e}\\u{d}\\u{a}\", \"\\u{61}\"]),\n        (\"\\u{41}\\u{2e}\\u{d}\\u{a}\\u{41}\", &[\"\\u{41}\\u{2e}\\u{d}\\u{a}\", \"\\u{41}\"]),\n        (\"\\u{2060}\\u{28}\\u{2060}\\u{22}\\u{2060}\\u{47}\\u{2060}\\u{6f}\\u{2060}\\u{2e}\\u{2060}\\u{22}\\u{2060}\\u{29}\\u{2060}\\u{20}\\u{2060}\\u{28}\\u{2060}\\u{48}\\u{2060}\\u{65}\\u{2060}\\u{20}\\u{2060}\\u{64}\\u{2060}\\u{69}\\u{2060}\\u{64}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{28}\\u{2060}\\u{22}\\u{2060}\\u{47}\\u{2060}\\u{6f}\\u{2060}\\u{2e}\\u{2060}\\u{22}\\u{2060}\\u{29}\\u{2060}\\u{20}\\u{2060}\",\n        \"\\u{28}\\u{2060}\\u{48}\\u{2060}\\u{65}\\u{2060}\\u{20}\\u{2060}\\u{64}\\u{2060}\\u{69}\\u{2060}\\u{64}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{28}\\u{2060}\\u{201c}\\u{2060}\\u{47}\\u{2060}\\u{6f}\\u{2060}\\u{3f}\\u{2060}\\u{201d}\\u{2060}\\u{29}\\u{2060}\\u{20}\\u{2060}\\u{28}\\u{2060}\\u{48}\\u{2060}\\u{65}\\u{2060}\\u{20}\\u{2060}\\u{64}\\u{2060}\\u{69}\\u{2060}\\u{64}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{28}\\u{2060}\\u{201c}\\u{2060}\\u{47}\\u{2060}\\u{6f}\\u{2060}\\u{3f}\\u{2060}\\u{201d}\\u{2060}\\u{29}\\u{2060}\\u{20}\\u{2060}\",\n        \"\\u{28}\\u{2060}\\u{48}\\u{2060}\\u{65}\\u{2060}\\u{20}\\u{2060}\\u{64}\\u{2060}\\u{69}\\u{2060}\\u{64}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{55}\\u{2060}\\u{2e}\\u{2060}\\u{53}\\u{2060}\\u{2e}\\u{2060}\\u{41}\\u{2060}\\u{300}\\u{2e}\\u{2060}\\u{20}\\u{2060}\\u{69}\\u{2060}\\u{73}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{55}\\u{2060}\\u{2e}\\u{2060}\\u{53}\\u{2060}\\u{2e}\\u{2060}\\u{41}\\u{2060}\\u{300}\\u{2e}\\u{2060}\\u{20}\\u{2060}\\u{69}\\u{2060}\\u{73}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{55}\\u{2060}\\u{2e}\\u{2060}\\u{53}\\u{2060}\\u{2e}\\u{2060}\\u{41}\\u{2060}\\u{300}\\u{3f}\\u{2060}\\u{20}\\u{2060}\\u{48}\\u{2060}\\u{65}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{55}\\u{2060}\\u{2e}\\u{2060}\\u{53}\\u{2060}\\u{2e}\\u{2060}\\u{41}\\u{2060}\\u{300}\\u{3f}\\u{2060}\\u{20}\\u{2060}\",\n        \"\\u{48}\\u{2060}\\u{65}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{55}\\u{2060}\\u{2e}\\u{2060}\\u{53}\\u{2060}\\u{2e}\\u{2060}\\u{41}\\u{2060}\\u{300}\\u{2e}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{55}\\u{2060}\\u{2e}\\u{2060}\\u{53}\\u{2060}\\u{2e}\\u{2060}\\u{41}\\u{2060}\\u{300}\\u{2e}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{33}\\u{2060}\\u{2e}\\u{2060}\\u{34}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{33}\\u{2060}\\u{2e}\\u{2060}\\u{34}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{64}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{64}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{43}\\u{2060}\\u{2e}\\u{2060}\\u{64}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{43}\\u{2060}\\u{2e}\\u{2060}\\u{64}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{44}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{44}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{43}\\u{2060}\\u{2e}\\u{2060}\\u{44}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{43}\\u{2060}\\u{2e}\\u{2060}\\u{44}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\\u{74}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\\u{74}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\\u{54}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\",\n        \"\\u{54}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\\u{2018}\\u{2060}\\u{28}\\u{2060}\\u{74}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\\u{2018}\\u{2060}\\u{28}\\u{2060}\\u{74}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\\u{2018}\\u{2060}\\u{28}\\u{2060}\\u{54}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\",\n        \"\\u{2018}\\u{2060}\\u{28}\\u{2060}\\u{54}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\\u{308}\\u{74}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\\u{308}\\u{74}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\\u{308}\\u{54}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{a0}\\u{2060}\\u{308}\",\n        \"\\u{54}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{308}\\u{54}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{2019}\\u{2060}\\u{308}\",\n        \"\\u{54}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{a}\\u{2060}\\u{308}\\u{2060}\\u{54}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{29}\\u{2060}\\u{a}\",\n        \"\\u{2060}\\u{308}\\u{2060}\\u{54}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{74}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{20}\\u{2060}\\u{72}\\u{2060}\\u{65}\\u{2060}\\u{73}\\u{2060}\\u{70}\\u{2060}\\u{2e}\\u{2060}\\u{20}\\u{2060}\\u{6c}\\u{2060}\\u{65}\\u{2060}\\u{61}\\u{2060}\\u{64}\\u{2060}\\u{65}\\u{2060}\\u{72}\\u{2060}\\u{73}\\u{2060}\\u{20}\\u{2060}\\u{61}\\u{2060}\\u{72}\\u{2060}\\u{65}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{74}\\u{2060}\\u{68}\\u{2060}\\u{65}\\u{2060}\\u{20}\\u{2060}\\u{72}\\u{2060}\\u{65}\\u{2060}\\u{73}\\u{2060}\\u{70}\\u{2060}\\u{2e}\\u{2060}\\u{20}\\u{2060}\\u{6c}\\u{2060}\\u{65}\\u{2060}\\u{61}\\u{2060}\\u{64}\\u{2060}\\u{65}\\u{2060}\\u{72}\\u{2060}\\u{73}\\u{2060}\\u{20}\\u{2060}\\u{61}\\u{2060}\\u{72}\\u{2060}\\u{65}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{5b57}\\u{2060}\\u{2e}\\u{2060}\\u{5b57}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{5b57}\\u{2060}\\u{2e}\\u{2060}\", \"\\u{5b57}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{5b83}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\",\n        \"\\u{5b83}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{3002}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{65}\\u{2060}\\u{74}\\u{2060}\\u{63}\\u{2060}\\u{2e}\\u{2060}\\u{3002}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{5b57}\\u{2060}\\u{3002}\\u{2060}\\u{5b83}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{5b57}\\u{2060}\\u{3002}\\u{2060}\", \"\\u{5b83}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{21}\\u{2060}\\u{20}\\u{2060}\\u{20}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{21}\\u{2060}\\u{20}\\u{2060}\\u{20}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{61}\\u{2060}\\u{2e}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{61}\\u{2060}\\u{2e}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{61}\\u{2060}\\u{2e}\\u{2060}\\u{d}\\u{2060}\\u{a}\\u{2060}\",\n        &[\"\\u{2060}\\u{61}\\u{2060}\\u{2e}\\u{2060}\\u{d}\", \"\\u{2060}\\u{a}\", \"\\u{2060}\"]),\n        (\"\\u{2060}\\u{61}\\u{2060}\\u{2e}\\u{2060}\\u{d}\\u{2060}\\u{a}\\u{20}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{61}\\u{2060}\\u{2e}\\u{2060}\\u{d}\", \"\\u{2060}\\u{a}\", \"\\u{20}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{61}\\u{2060}\\u{2e}\\u{2060}\\u{d}\\u{2060}\\u{a}\\u{61}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{61}\\u{2060}\\u{2e}\\u{2060}\\u{d}\", \"\\u{2060}\\u{a}\", \"\\u{61}\\u{2060}\\u{2060}\"]),\n        (\"\\u{2060}\\u{41}\\u{2060}\\u{2e}\\u{2060}\\u{d}\\u{2060}\\u{a}\\u{41}\\u{2060}\\u{2060}\",\n        &[\"\\u{2060}\\u{41}\\u{2060}\\u{2e}\\u{2060}\\u{d}\", \"\\u{2060}\\u{a}\", \"\\u{41}\\u{2060}\\u{2060}\"])\n    ];\n\n"
    },
    {
      "package": "unicode-vo@0.1.0",
      "sourcePath": "README.md",
      "sha256": "a9987359b5014cd79ac4b68d63d5a9c58b181b67908a13258b2c6084918fc2ed",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "## unicode-vo\n[![Crates.io](https://img.shields.io/crates/v/unicode-vo.svg)](https://crates.io/crates/unicode-vo)\n[![Documentation](https://docs.rs/unicode-vo/badge.svg)](https://docs.rs/unicode-vo)\n\nThis library implements\n[Unicode Vertical_Orientation Property](https://www.unicode.org/reports/tr50/tr50-19.html)\n(annex #50).\n\n```rust\nuse unicode_vo::*;\n\nassert_eq!(char_orientation('A'), Orientation::Rotated);\nassert_eq!(char_orientation('本'), Orientation::Upright);\n```\n\n### License\n\nLicensed under either of\n\n- Apache License, Version 2.0\n  ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license\n  ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    },
    {
      "package": "usvg@0.34.1",
      "sourcePath": "LICENSE.txt",
      "sha256": "fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n    means each individual or legal entity that creates, contributes to\n    the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n    means the combination of the Contributions of others (if any) used\n    by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n    means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n    means Source Code Form to which the initial Contributor has attached\n    the notice in Exhibit A, the Executable Form of such Source Code\n    Form, and Modifications of such Source Code Form, in each case\n    including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n    means\n\n    (a) that the initial Contributor has attached the notice described\n        in Exhibit B to the Covered Software; or\n\n    (b) that the Covered Software was made available under the terms of\n        version 1.1 or earlier of the License, but not also under the\n        terms of a Secondary License.\n\n1.6. \"Executable Form\"\n    means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n    means a work that combines Covered Software with other material, in \n    a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n    means this document.\n\n1.9. \"Licensable\"\n    means having the right to grant, to the maximum extent possible,\n    whether at the time of the initial grant or subsequently, any and\n    all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n    means any of the following:\n\n    (a) any file in Source Code Form that results from an addition to,\n        deletion from, or modification of the contents of Covered\n        Software; or\n\n    (b) any new file in Source Code Form that contains any Covered\n        Software.\n\n1.11. \"Patent Claims\" of a Contributor\n    means any patent claim(s), including without limitation, method,\n    process, and apparatus claims, in any patent Licensable by such\n    Contributor that would be infringed, but for the grant of the\n    License, by the making, using, selling, offering for sale, having\n    made, import, or transfer of either its Contributions or its\n    Contributor Version.\n\n1.12. \"Secondary License\"\n    means either the GNU General Public License, Version 2.0, the GNU\n    Lesser General Public License, Version 2.1, the GNU Affero General\n    Public License, Version 3.0, or any later versions of those\n    licenses.\n\n1.13. \"Source Code Form\"\n    means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n    means an individual or a legal entity exercising rights under this\n    License. For legal entities, \"You\" includes any entity that\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n    Licensable by such Contributor to use, reproduce, make available,\n    modify, display, perform, distribute, and otherwise exploit its\n    Contributions, either on an unmodified basis, with Modifications, or\n    as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n    for sale, have made, import, and otherwise transfer either its\n    Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n    or\n\n(b) for infringements caused by: (i) Your and any other third party's\n    modifications of Covered Software, or (ii) the combination of its\n    Contributions with other software (except as part of its Contributor\n    Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n    its Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\n    Form, as described in Section 3.1, and You must inform recipients of\n    the Executable Form how they can obtain a copy of such Source Code\n    Form by reasonable means in a timely manner, at a charge no more\n    than the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\n    License, or sublicense it under different terms, provided that the\n    license for the Executable Form does not attempt to limit or alter\n    the recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n*                                                                      *\n*  6. Disclaimer of Warranty                                           *\n*  -------------------------                                           *\n*                                                                      *\n*  Covered Software is provided under this License on an \"as is\"       *\n*  basis, without warranty of any kind, either expressed, implied, or  *\n*  statutory, including, without limitation, warranties that the       *\n*  Covered Software is free of defects, merchantable, fit for a        *\n*  particular purpose or non-infringing. The entire risk as to the     *\n*  quality and performance of the Covered Software is with You.        *\n*  Should any Covered Software prove defective in any respect, You     *\n*  (not any Contributor) assume the cost of any necessary servicing,   *\n*  repair, or correction. This disclaimer of warranty constitutes an   *\n*  essential part of this License. No use of any Covered Software is   *\n*  authorized under this License except under this disclaimer.         *\n*                                                                      *\n************************************************************************\n\n************************************************************************\n*                                                                      *\n*  7. Limitation of Liability                                          *\n*  --------------------------                                          *\n*                                                                      *\n*  Under no circumstances and under no legal theory, whether tort      *\n*  (including negligence), contract, or otherwise, shall any           *\n*  Contributor, or anyone who distributes Covered Software as          *\n*  permitted above, be liable to You for any direct, indirect,         *\n*  special, incidental, or consequential damages of any character      *\n*  including, without limitation, damages for lost profits, loss of    *\n*  goodwill, work stoppage, computer failure or malfunction, or any    *\n*  and all other commercial damages or losses, even if such party      *\n*  shall have been informed of the possibility of such damages. This   *\n*  limitation of liability shall not apply to liability for death or   *\n*  personal injury resulting from such party's negligence to the       *\n*  extent applicable law prohibits such limitation. Some               *\n*  jurisdictions do not allow the exclusion or limitation of           *\n*  incidental or consequential damages, so this exclusion and          *\n*  limitation may not apply to You.                                    *\n*                                                                      *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\n  This Source Code Form is subject to the terms of the Mozilla Public\n  License, v. 2.0. If a copy of the MPL was not distributed with this\n  file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\n  This Source Code Form is \"Incompatible With Secondary Licenses\", as\n  defined by the Mozilla Public License, v. 2.0.\n"
    },
    {
      "package": "usvg@0.34.1",
      "sourcePath": "README.md",
      "sha256": "933cd0966ff12346d555d36f0f20ba1281f9b4009f9f48bfd810351f9e0d27bf",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# usvg\n[![Crates.io](https://img.shields.io/crates/v/usvg.svg)](https://crates.io/crates/usvg)\n[![Documentation](https://docs.rs/usvg/badge.svg)](https://docs.rs/usvg)\n[![Rust 1.65+](https://img.shields.io/badge/rust-1.65+-orange.svg)](https://www.rust-lang.org)\n\n`usvg` (micro SVG) is an [SVG] parser that tries to solve most of SVG complexity.\n\nSVG is notoriously hard to parse. `usvg` presents a layer between an XML library and\na potential SVG rendering library. It will parse an input SVG into a strongly-typed tree structure\nwere all the elements, attributes, references and other SVG features are already resolved\nand presented in a simplest way possible.\nSo a caller doesn't have to worry about most of the issues related to SVG parsing\nand can focus just on the rendering part.\n\n## Features\n\n- All supported attributes are resolved.\n  No need to worry about inheritable, implicit and default attributes\n- CSS will be applied\n- Only simple paths\n  - Basic shapes (like `rect` and `circle`) will be converted into paths\n  - Paths contain only absolute *MoveTo*, *LineTo*, *QuadTo*, *CurveTo* and *ClosePath* segments.\n    ArcTo, implicit and relative segments will be converted\n- `use` will be resolved and replaced with the reference content\n- Nested `svg` will be resolved\n- Invalid, malformed elements will be removed\n- Relative length units (mm, em, etc.) will be converted into pixels/points\n- External images will be loaded\n- Internal, base64 images will be decoded\n- All references (like `#elem` and `url(#elem)`) will be resolved\n- `switch` will be resolved\n- Text elements, which are probably the hardest part of SVG, will be completely resolved.\n  This includes all the attributes resolving, whitespaces preprocessing (`xml:space`),\n  text chunks and spans resolving\n- Markers will be converted into regular elements. No need to place them manually\n- All filters are supported. Including filter functions, like `filter=\"contrast(50%)\"`\n- Recursive elements will be detected an removed\n\n## Limitations\n\n- Unsupported SVG features will be ignored\n- CSS support is minimal\n- Only [static](http://www.w3.org/TR/SVG11/feature#SVG-static) SVG features,\n  e.g. no `a`, `view`, `cursor`, `script`, no events and no animations\n- Text elements must be converted into paths before writing to SVG\n\n## License\n\n*usvg* is licensed under the [MPLv2.0](https://www.mozilla.org/en-US/MPL/).\n\n[SVG]: https://en.wikipedia.org/wiki/Scalable_Vector_Graphics\n"
    },
    {
      "package": "usvg-parser@0.34.0",
      "sourcePath": "LICENSE.txt",
      "sha256": "fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n    means each individual or legal entity that creates, contributes to\n    the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n    means the combination of the Contributions of others (if any) used\n    by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n    means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n    means Source Code Form to which the initial Contributor has attached\n    the notice in Exhibit A, the Executable Form of such Source Code\n    Form, and Modifications of such Source Code Form, in each case\n    including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n    means\n\n    (a) that the initial Contributor has attached the notice described\n        in Exhibit B to the Covered Software; or\n\n    (b) that the Covered Software was made available under the terms of\n        version 1.1 or earlier of the License, but not also under the\n        terms of a Secondary License.\n\n1.6. \"Executable Form\"\n    means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n    means a work that combines Covered Software with other material, in \n    a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n    means this document.\n\n1.9. \"Licensable\"\n    means having the right to grant, to the maximum extent possible,\n    whether at the time of the initial grant or subsequently, any and\n    all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n    means any of the following:\n\n    (a) any file in Source Code Form that results from an addition to,\n        deletion from, or modification of the contents of Covered\n        Software; or\n\n    (b) any new file in Source Code Form that contains any Covered\n        Software.\n\n1.11. \"Patent Claims\" of a Contributor\n    means any patent claim(s), including without limitation, method,\n    process, and apparatus claims, in any patent Licensable by such\n    Contributor that would be infringed, but for the grant of the\n    License, by the making, using, selling, offering for sale, having\n    made, import, or transfer of either its Contributions or its\n    Contributor Version.\n\n1.12. \"Secondary License\"\n    means either the GNU General Public License, Version 2.0, the GNU\n    Lesser General Public License, Version 2.1, the GNU Affero General\n    Public License, Version 3.0, or any later versions of those\n    licenses.\n\n1.13. \"Source Code Form\"\n    means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n    means an individual or a legal entity exercising rights under this\n    License. For legal entities, \"You\" includes any entity that\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n    Licensable by such Contributor to use, reproduce, make available,\n    modify, display, perform, distribute, and otherwise exploit its\n    Contributions, either on an unmodified basis, with Modifications, or\n    as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n    for sale, have made, import, and otherwise transfer either its\n    Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n    or\n\n(b) for infringements caused by: (i) Your and any other third party's\n    modifications of Covered Software, or (ii) the combination of its\n    Contributions with other software (except as part of its Contributor\n    Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n    its Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\n    Form, as described in Section 3.1, and You must inform recipients of\n    the Executable Form how they can obtain a copy of such Source Code\n    Form by reasonable means in a timely manner, at a charge no more\n    than the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\n    License, or sublicense it under different terms, provided that the\n    license for the Executable Form does not attempt to limit or alter\n    the recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n*                                                                      *\n*  6. Disclaimer of Warranty                                           *\n*  -------------------------                                           *\n*                                                                      *\n*  Covered Software is provided under this License on an \"as is\"       *\n*  basis, without warranty of any kind, either expressed, implied, or  *\n*  statutory, including, without limitation, warranties that the       *\n*  Covered Software is free of defects, merchantable, fit for a        *\n*  particular purpose or non-infringing. The entire risk as to the     *\n*  quality and performance of the Covered Software is with You.        *\n*  Should any Covered Software prove defective in any respect, You     *\n*  (not any Contributor) assume the cost of any necessary servicing,   *\n*  repair, or correction. This disclaimer of warranty constitutes an   *\n*  essential part of this License. No use of any Covered Software is   *\n*  authorized under this License except under this disclaimer.         *\n*                                                                      *\n************************************************************************\n\n************************************************************************\n*                                                                      *\n*  7. Limitation of Liability                                          *\n*  --------------------------                                          *\n*                                                                      *\n*  Under no circumstances and under no legal theory, whether tort      *\n*  (including negligence), contract, or otherwise, shall any           *\n*  Contributor, or anyone who distributes Covered Software as          *\n*  permitted above, be liable to You for any direct, indirect,         *\n*  special, incidental, or consequential damages of any character      *\n*  including, without limitation, damages for lost profits, loss of    *\n*  goodwill, work stoppage, computer failure or malfunction, or any    *\n*  and all other commercial damages or losses, even if such party      *\n*  shall have been informed of the possibility of such damages. This   *\n*  limitation of liability shall not apply to liability for death or   *\n*  personal injury resulting from such party's negligence to the       *\n*  extent applicable law prohibits such limitation. Some               *\n*  jurisdictions do not allow the exclusion or limitation of           *\n*  incidental or consequential damages, so this exclusion and          *\n*  limitation may not apply to You.                                    *\n*                                                                      *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\n  This Source Code Form is subject to the terms of the Mozilla Public\n  License, v. 2.0. If a copy of the MPL was not distributed with this\n  file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\n  This Source Code Form is \"Incompatible With Secondary Licenses\", as\n  defined by the Mozilla Public License, v. 2.0.\n"
    },
    {
      "package": "usvg-parser@0.34.0",
      "sourcePath": "README.md",
      "sha256": "946a3a0d51b2784bc4b35701cf5d857d504caea2f730abfdd2f6e56451bbb6fd",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# usvg\n[![Crates.io](https://img.shields.io/crates/v/usvg-parser.svg)](https://crates.io/crates/usvg-parser)\n[![Documentation](https://docs.rs/usvg/badge.svg)](https://docs.rs/usvg-parser)\n[![Rust 1.65+](https://img.shields.io/badge/rust-1.65+-orange.svg)](https://www.rust-lang.org)\n\n`usvg-parser` is an [SVG] parser used by [usvg].\n\n## License\n\n*usvg-parser* is licensed under the [MPLv2.0](https://www.mozilla.org/en-US/MPL/).\n\n[SVG]: https://en.wikipedia.org/wiki/Scalable_Vector_Graphics\n[usvg]: https://github.com/RazrFalcon/resvg/tree/master/crates/usvg\n"
    },
    {
      "package": "usvg-text-layout@0.34.0",
      "sourcePath": "LICENSE.txt",
      "sha256": "fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n    means each individual or legal entity that creates, contributes to\n    the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n    means the combination of the Contributions of others (if any) used\n    by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n    means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n    means Source Code Form to which the initial Contributor has attached\n    the notice in Exhibit A, the Executable Form of such Source Code\n    Form, and Modifications of such Source Code Form, in each case\n    including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n    means\n\n    (a) that the initial Contributor has attached the notice described\n        in Exhibit B to the Covered Software; or\n\n    (b) that the Covered Software was made available under the terms of\n        version 1.1 or earlier of the License, but not also under the\n        terms of a Secondary License.\n\n1.6. \"Executable Form\"\n    means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n    means a work that combines Covered Software with other material, in \n    a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n    means this document.\n\n1.9. \"Licensable\"\n    means having the right to grant, to the maximum extent possible,\n    whether at the time of the initial grant or subsequently, any and\n    all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n    means any of the following:\n\n    (a) any file in Source Code Form that results from an addition to,\n        deletion from, or modification of the contents of Covered\n        Software; or\n\n    (b) any new file in Source Code Form that contains any Covered\n        Software.\n\n1.11. \"Patent Claims\" of a Contributor\n    means any patent claim(s), including without limitation, method,\n    process, and apparatus claims, in any patent Licensable by such\n    Contributor that would be infringed, but for the grant of the\n    License, by the making, using, selling, offering for sale, having\n    made, import, or transfer of either its Contributions or its\n    Contributor Version.\n\n1.12. \"Secondary License\"\n    means either the GNU General Public License, Version 2.0, the GNU\n    Lesser General Public License, Version 2.1, the GNU Affero General\n    Public License, Version 3.0, or any later versions of those\n    licenses.\n\n1.13. \"Source Code Form\"\n    means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n    means an individual or a legal entity exercising rights under this\n    License. For legal entities, \"You\" includes any entity that\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n    Licensable by such Contributor to use, reproduce, make available,\n    modify, display, perform, distribute, and otherwise exploit its\n    Contributions, either on an unmodified basis, with Modifications, or\n    as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n    for sale, have made, import, and otherwise transfer either its\n    Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n    or\n\n(b) for infringements caused by: (i) Your and any other third party's\n    modifications of Covered Software, or (ii) the combination of its\n    Contributions with other software (except as part of its Contributor\n    Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n    its Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\n    Form, as described in Section 3.1, and You must inform recipients of\n    the Executable Form how they can obtain a copy of such Source Code\n    Form by reasonable means in a timely manner, at a charge no more\n    than the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\n    License, or sublicense it under different terms, provided that the\n    license for the Executable Form does not attempt to limit or alter\n    the recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n*                                                                      *\n*  6. Disclaimer of Warranty                                           *\n*  -------------------------                                           *\n*                                                                      *\n*  Covered Software is provided under this License on an \"as is\"       *\n*  basis, without warranty of any kind, either expressed, implied, or  *\n*  statutory, including, without limitation, warranties that the       *\n*  Covered Software is free of defects, merchantable, fit for a        *\n*  particular purpose or non-infringing. The entire risk as to the     *\n*  quality and performance of the Covered Software is with You.        *\n*  Should any Covered Software prove defective in any respect, You     *\n*  (not any Contributor) assume the cost of any necessary servicing,   *\n*  repair, or correction. This disclaimer of warranty constitutes an   *\n*  essential part of this License. No use of any Covered Software is   *\n*  authorized under this License except under this disclaimer.         *\n*                                                                      *\n************************************************************************\n\n************************************************************************\n*                                                                      *\n*  7. Limitation of Liability                                          *\n*  --------------------------                                          *\n*                                                                      *\n*  Under no circumstances and under no legal theory, whether tort      *\n*  (including negligence), contract, or otherwise, shall any           *\n*  Contributor, or anyone who distributes Covered Software as          *\n*  permitted above, be liable to You for any direct, indirect,         *\n*  special, incidental, or consequential damages of any character      *\n*  including, without limitation, damages for lost profits, loss of    *\n*  goodwill, work stoppage, computer failure or malfunction, or any    *\n*  and all other commercial damages or losses, even if such party      *\n*  shall have been informed of the possibility of such damages. This   *\n*  limitation of liability shall not apply to liability for death or   *\n*  personal injury resulting from such party's negligence to the       *\n*  extent applicable law prohibits such limitation. Some               *\n*  jurisdictions do not allow the exclusion or limitation of           *\n*  incidental or consequential damages, so this exclusion and          *\n*  limitation may not apply to You.                                    *\n*                                                                      *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\n  This Source Code Form is subject to the terms of the Mozilla Public\n  License, v. 2.0. If a copy of the MPL was not distributed with this\n  file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\n  This Source Code Form is \"Incompatible With Secondary Licenses\", as\n  defined by the Mozilla Public License, v. 2.0.\n"
    },
    {
      "package": "usvg-tree@0.34.0",
      "sourcePath": "LICENSE.txt",
      "sha256": "fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n    means each individual or legal entity that creates, contributes to\n    the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n    means the combination of the Contributions of others (if any) used\n    by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n    means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n    means Source Code Form to which the initial Contributor has attached\n    the notice in Exhibit A, the Executable Form of such Source Code\n    Form, and Modifications of such Source Code Form, in each case\n    including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n    means\n\n    (a) that the initial Contributor has attached the notice described\n        in Exhibit B to the Covered Software; or\n\n    (b) that the Covered Software was made available under the terms of\n        version 1.1 or earlier of the License, but not also under the\n        terms of a Secondary License.\n\n1.6. \"Executable Form\"\n    means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n    means a work that combines Covered Software with other material, in \n    a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n    means this document.\n\n1.9. \"Licensable\"\n    means having the right to grant, to the maximum extent possible,\n    whether at the time of the initial grant or subsequently, any and\n    all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n    means any of the following:\n\n    (a) any file in Source Code Form that results from an addition to,\n        deletion from, or modification of the contents of Covered\n        Software; or\n\n    (b) any new file in Source Code Form that contains any Covered\n        Software.\n\n1.11. \"Patent Claims\" of a Contributor\n    means any patent claim(s), including without limitation, method,\n    process, and apparatus claims, in any patent Licensable by such\n    Contributor that would be infringed, but for the grant of the\n    License, by the making, using, selling, offering for sale, having\n    made, import, or transfer of either its Contributions or its\n    Contributor Version.\n\n1.12. \"Secondary License\"\n    means either the GNU General Public License, Version 2.0, the GNU\n    Lesser General Public License, Version 2.1, the GNU Affero General\n    Public License, Version 3.0, or any later versions of those\n    licenses.\n\n1.13. \"Source Code Form\"\n    means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n    means an individual or a legal entity exercising rights under this\n    License. For legal entities, \"You\" includes any entity that\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n    Licensable by such Contributor to use, reproduce, make available,\n    modify, display, perform, distribute, and otherwise exploit its\n    Contributions, either on an unmodified basis, with Modifications, or\n    as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n    for sale, have made, import, and otherwise transfer either its\n    Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n    or\n\n(b) for infringements caused by: (i) Your and any other third party's\n    modifications of Covered Software, or (ii) the combination of its\n    Contributions with other software (except as part of its Contributor\n    Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n    its Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\n    Form, as described in Section 3.1, and You must inform recipients of\n    the Executable Form how they can obtain a copy of such Source Code\n    Form by reasonable means in a timely manner, at a charge no more\n    than the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\n    License, or sublicense it under different terms, provided that the\n    license for the Executable Form does not attempt to limit or alter\n    the recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n*                                                                      *\n*  6. Disclaimer of Warranty                                           *\n*  -------------------------                                           *\n*                                                                      *\n*  Covered Software is provided under this License on an \"as is\"       *\n*  basis, without warranty of any kind, either expressed, implied, or  *\n*  statutory, including, without limitation, warranties that the       *\n*  Covered Software is free of defects, merchantable, fit for a        *\n*  particular purpose or non-infringing. The entire risk as to the     *\n*  quality and performance of the Covered Software is with You.        *\n*  Should any Covered Software prove defective in any respect, You     *\n*  (not any Contributor) assume the cost of any necessary servicing,   *\n*  repair, or correction. This disclaimer of warranty constitutes an   *\n*  essential part of this License. No use of any Covered Software is   *\n*  authorized under this License except under this disclaimer.         *\n*                                                                      *\n************************************************************************\n\n************************************************************************\n*                                                                      *\n*  7. Limitation of Liability                                          *\n*  --------------------------                                          *\n*                                                                      *\n*  Under no circumstances and under no legal theory, whether tort      *\n*  (including negligence), contract, or otherwise, shall any           *\n*  Contributor, or anyone who distributes Covered Software as          *\n*  permitted above, be liable to You for any direct, indirect,         *\n*  special, incidental, or consequential damages of any character      *\n*  including, without limitation, damages for lost profits, loss of    *\n*  goodwill, work stoppage, computer failure or malfunction, or any    *\n*  and all other commercial damages or losses, even if such party      *\n*  shall have been informed of the possibility of such damages. This   *\n*  limitation of liability shall not apply to liability for death or   *\n*  personal injury resulting from such party's negligence to the       *\n*  extent applicable law prohibits such limitation. Some               *\n*  jurisdictions do not allow the exclusion or limitation of           *\n*  incidental or consequential damages, so this exclusion and          *\n*  limitation may not apply to You.                                    *\n*                                                                      *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\n  This Source Code Form is subject to the terms of the Mozilla Public\n  License, v. 2.0. If a copy of the MPL was not distributed with this\n  file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\n  This Source Code Form is \"Incompatible With Secondary Licenses\", as\n  defined by the Mozilla Public License, v. 2.0.\n"
    },
    {
      "package": "usvg-tree@0.34.0",
      "sourcePath": "README.md",
      "sha256": "786c014e4957b1df55104bd20bbe012d7fa78391a0898b1e4561c8b604830413",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# usvg-tree\n[![Crates.io](https://img.shields.io/crates/v/usvg-tree.svg)](https://crates.io/crates/usvg-tree)\n[![Documentation](https://docs.rs/usvg/badge.svg)](https://docs.rs/usvg-tree)\n[![Rust 1.65+](https://img.shields.io/badge/rust-1.65+-orange.svg)](https://www.rust-lang.org)\n\n`usvg-tree` is an [SVG] tree representation used by [usvg].\n\n## License\n\n*usvg-tree* is licensed under the [MPLv2.0](https://www.mozilla.org/en-US/MPL/).\n\n[SVG]: https://en.wikipedia.org/wiki/Scalable_Vector_Graphics\n[usvg]: https://github.com/RazrFalcon/resvg/tree/master/crates/usvg\n"
    },
    {
      "package": "version_check@0.9.5",
      "sourcePath": "README.md",
      "sha256": "ac2a0a360812436bd5798f5fe2affe7d6ed9eb7f15d6e4d73931e95b437560f2",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# version\\_check\n\n[![Build Status](https://github.com/SergioBenitez/version_check/workflows/CI/badge.svg)](https://github.com/SergioBenitez/version_check/actions)\n[![Current Crates.io Version](https://img.shields.io/crates/v/version_check.svg)](https://crates.io/crates/version_check)\n[![rustdocs on docs.rs](https://docs.rs/version_check/badge.svg)](https://docs.rs/version_check)\n\nThis tiny crate checks that the running or installed `rustc` meets some version\nrequirements. The version is queried by calling the Rust compiler with\n`--version`. The path to the compiler is determined first via the `RUSTC`\nenvironment variable. If it is not set, then `rustc` is used. If that fails, no\ndetermination is made, and calls return `None`.\n\n## Usage\n\nAdd to your `Cargo.toml` file, typically as a build dependency:\n\n```toml\n[build-dependencies]\nversion_check = \"0.9\"\n```\n\n`version_check` is compatible and compiles with Rust 1.0.0 and beyond.\n\n## Examples\n\nSet a `cfg` flag in `build.rs` if the running compiler was determined to be\nat least version `1.13.0`:\n\n```rust\nextern crate version_check as rustc;\n\nif rustc::is_min_version(\"1.13.0\").unwrap_or(false) {\n    println!(\"cargo:rustc-cfg=question_mark_operator\");\n}\n```\n\nCheck that the running compiler was released on or after `2018-12-18`:\n\n```rust\nextern crate version_check as rustc;\n\nmatch rustc::is_min_date(\"2018-12-18\") {\n    Some(true) => \"Yep! It's recent!\",\n    Some(false) => \"No, it's older.\",\n    None => \"Couldn't determine the rustc version.\"\n};\n```\n\nCheck that the running compiler supports feature flags:\n\n```rust\nextern crate version_check as rustc;\n\nmatch rustc::is_feature_flaggable() {\n    Some(true) => \"Yes! It's a dev or nightly release!\",\n    Some(false) => \"No, it's stable or beta.\",\n    None => \"Couldn't determine the rustc version.\"\n};\n```\n\nSee the [rustdocs](https://docs.rs/version_check) for more examples and complete\ndocumentation.\n\n## Alternatives\n\nThis crate is dead simple with no dependencies. If you need something more and\ndon't care about panicking if the version cannot be obtained, or if you don't\nmind adding dependencies, see [rustc_version]. If you'd instead prefer a feature\ndetection library that works by dynamically invoking `rustc` with a\nrepresentative code sample, see [autocfg].\n\n[rustc_version]: https://crates.io/crates/rustc_version\n[autocfg]: https://crates.io/crates/autocfg\n\n## License\n\n`version_check` is licensed under either of the following, at your option:\n\n * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n * MIT License ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n"
    },
    {
      "package": "wasm-bindgen@0.2.92",
      "sourcePath": "README.md",
      "sha256": "36a2db1bda9f5fc21d8d6ed8d34a13fb049a1db642129d0d1af269634a068a33",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "<div align=\"center\">\n\n  <h1><code>wasm-bindgen</code></h1>\n\n  <p>\n    <strong>Facilitating high-level interactions between Wasm modules and JavaScript.</strong>\n  </p>\n\n  <p>\n    <a href=\"https://github.com/rustwasm/wasm-bindgen/actions/workflows/main.yml?query=branch%3Amain\"><img src=\"https://github.com/rustwasm/wasm-bindgen/actions/workflows/main.yml/badge.svg?branch=main\" alt=\"Build Status\" /></a>\n    <a href=\"https://crates.io/crates/wasm-bindgen\"><img src=\"https://img.shields.io/crates/v/wasm-bindgen.svg?style=flat-square\" alt=\"Crates.io version\" /></a>\n    <a href=\"https://crates.io/crates/wasm-bindgen\"><img src=\"https://img.shields.io/crates/d/wasm-bindgen.svg?style=flat-square\" alt=\"Download\" /></a>\n    <a href=\"https://docs.rs/wasm-bindgen\"><img src=\"https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square\" alt=\"docs.rs docs\" /></a>\n  </p>\n\n  <h3>\n    <a href=\"https://rustwasm.github.io/wasm-bindgen/\">Guide (main branch)</a>\n    <span> | </span>\n    <a href=\"https://docs.rs/wasm-bindgen\">API Docs</a>\n    <span> | </span>\n    <a href=\"https://github.com/rustwasm/wasm-bindgen/blob/master/CONTRIBUTING.md\">Contributing</a>\n    <span> | </span>\n    <a href=\"https://discord.gg/xMZ7CCY\">Chat</a>\n  </h3>\n\n  <sub>Built with 🦀🕸 by <a href=\"https://rustwasm.github.io/\">The Rust and WebAssembly Working Group</a></sub>\n</div>\n\n## Install `wasm-bindgen-cli`\n\nYou can install it using `cargo install`:\n\n```\ncargo install wasm-bindgen-cli\n```\n\nOr, you can download it from the\n[release page](https://github.com/rustwasm/wasm-bindgen/releases).\n\nIf you have [`cargo-binstall`](https://crates.io/crates/cargo-binstall) installed,\nthen you can install the pre-built artifacts by running:\n\n```\ncargo binstall wasm-bindgen-cli\n```\n\n## Example\n\nImport JavaScript things into Rust and export Rust things to JavaScript.\n\n```rust\nuse wasm_bindgen::prelude::*;\n\n// Import the `window.alert` function from the Web.\n#[wasm_bindgen]\nextern \"C\" {\n    fn alert(s: &str);\n}\n\n// Export a `greet` function from Rust to JavaScript, that alerts a\n// hello message.\n#[wasm_bindgen]\npub fn greet(name: &str) {\n    alert(&format!(\"Hello, {}!\", name));\n}\n```\n\nUse exported Rust things from JavaScript with ECMAScript modules!\n\n```js\nimport { greet } from \"./hello_world\";\n\ngreet(\"World!\");\n```\n\n## Features\n\n* **Lightweight.** Only pay for what you use. `wasm-bindgen` only generates\n  bindings and glue for the JavaScript imports you actually use and Rust\n  functionality that you export. For example, importing and using the\n  `document.querySelector` method doesn't cause `Node.prototype.appendChild` or\n  `window.alert` to be included in the bindings as well.\n\n* **ECMAScript modules.** Just import WebAssembly modules the same way you would\n  import JavaScript modules. Future compatible with [WebAssembly modules and\n  ECMAScript modules integration][wasm-es-modules].\n\n* **Designed with the [\"Web IDL bindings\" proposal][webidl-bindings] in mind.**\n  Eventually, there won't be any JavaScript shims between Rust-generated wasm\n  functions and native DOM methods. Because the wasm functions are statically\n  type checked, some of those native methods' dynamic type checks should become\n  unnecessary, promising to unlock even-faster-than-JavaScript DOM access.\n\n[wasm-es-modules]: https://github.com/WebAssembly/esm-integration\n[webidl-bindings]: https://github.com/WebAssembly/proposals/issues/8\n\n## Guide\n\n[**📚 Read the `wasm-bindgen` guide here! 📚**](https://rustwasm.github.io/docs/wasm-bindgen/)\n\nYou can find general documentation about using Rust and WebAssembly together\n[here](https://rustwasm.github.io/docs).\n\n## API Docs\n\n- [wasm-bindgen](https://docs.rs/wasm-bindgen)\n- [js-sys](https://docs.rs/js-sys)\n- [web-sys](https://docs.rs/web-sys)\n- [wasm-bindgen-futures](https://docs.rs/wasm-bindgen-futures)\n\n## License\n\nThis project is licensed under either of\n\n * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\n   http://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or\n   http://opensource.org/licenses/MIT)\n\nat your option.\n\n## Contribution\n\n**[See the \"Contributing\" section of the guide for information on\nhacking on `wasm-bindgen`!][contributing]**\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this project by you, as defined in the Apache-2.0 license,\nshall be dual licensed as above, without any additional terms or conditions.\n\n[contributing]: https://rustwasm.github.io/docs/wasm-bindgen/contributing/index.html\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/Devices/Dvd/mod.rs",
      "sha256": "ae2a6b6a13ac3770e8907e7ce28c0dcb8c0cfa015ee161d2565518c2a3dc3693",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AACS_BINDING_NONCE {\n    pub BindingNonce: [u8; 16],\n    pub MAC: [u8; 16],\n}\nimpl Default for AACS_BINDING_NONCE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AACS_CERTIFICATE {\n    pub Nonce: [u8; 20],\n    pub Certificate: [u8; 92],\n}\nimpl Default for AACS_CERTIFICATE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AACS_CHALLENGE_KEY {\n    pub EllipticCurvePoint: [u8; 40],\n    pub Signature: [u8; 40],\n}\nimpl Default for AACS_CHALLENGE_KEY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AACS_MEDIA_ID {\n    pub MediaID: [u8; 16],\n    pub MAC: [u8; 16],\n}\nimpl Default for AACS_MEDIA_ID {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AACS_READ_BINDING_NONCE {\n    pub SessionId: u32,\n    pub NumberOfSectors: u32,\n    pub StartLba: u64,\n    pub Anonymous: AACS_READ_BINDING_NONCE_0,\n}\nimpl Default for AACS_READ_BINDING_NONCE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union AACS_READ_BINDING_NONCE_0 {\n    pub Handle: super::super::Foundation::HANDLE,\n    pub ForceStructureLengthToMatch64bit: u64,\n}\nimpl Default for AACS_READ_BINDING_NONCE_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct AACS_SEND_CERTIFICATE {\n    pub SessionId: u32,\n    pub Certificate: AACS_CERTIFICATE,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct AACS_SEND_CHALLENGE_KEY {\n    pub SessionId: u32,\n    pub ChallengeKey: AACS_CHALLENGE_KEY,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AACS_SERIAL_NUMBER {\n    pub PrerecordedSerialNumber: [u8; 16],\n    pub MAC: [u8; 16],\n}\nimpl Default for AACS_SERIAL_NUMBER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AACS_VOLUME_ID {\n    pub VolumeID: [u8; 16],\n    pub MAC: [u8; 16],\n}\nimpl Default for AACS_VOLUME_ID {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct BD_DISC_WRITE_PROTECT_PAC {\n    pub Header: BD_PAC_HEADER,\n    pub KnownPACEntireDiscFlags: u8,\n    pub Reserved1: [u8; 3],\n    pub WriteProtectControlByte: u8,\n    pub Reserved2: [u8; 7],\n    pub WriteProtectPassword: [u8; 32],\n}\nimpl Default for BD_DISC_WRITE_PROTECT_PAC {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct BD_PAC_HEADER {\n    pub PACId: [u8; 3],\n    pub PACFormatNumber: u8,\n    pub PACUpdateCount: [u8; 4],\n    pub UnknownPACRules: [u8; 4],\n    pub UnkownPACEntireDiscFlag: u8,\n    pub Reserved1: [u8; 2],\n    pub NumberOfSegments: u8,\n    pub Segments: [u8; 256],\n    pub Reserved2: [u8; 112],\n}\nimpl Default for BD_PAC_HEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type DISC_CONTROL_BLOCK_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_ASF {\n    pub Reserved0: [u8; 3],\n    pub _bitfield: u8,\n}\nimpl Default for DVD_ASF {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_BCA_DESCRIPTOR {\n    pub BCAInformation: [u8; 1],\n}\nimpl Default for DVD_BCA_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_BD_SPARE_AREA_INFORMATION {\n    pub Reserved1: [u8; 4],\n    pub NumberOfFreeSpareBlocks: [u8; 4],\n    pub NumberOfAllocatedSpareBlocks: [u8; 4],\n}\nimpl Default for DVD_BD_SPARE_AREA_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DVD_CGMS_COPY_ONCE: u32 = 16u32;\npub const DVD_CGMS_COPY_PERMITTED: u32 = 0u32;\npub const DVD_CGMS_COPY_PROTECT_MASK: u32 = 24u32;\npub const DVD_CGMS_NO_COPY: u32 = 24u32;\npub const DVD_CGMS_RESERVED_MASK: u32 = 120u32;\npub const DVD_COPYRIGHTED: u32 = 64u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct DVD_COPYRIGHT_DESCRIPTOR {\n    pub CopyrightProtectionType: u8,\n    pub RegionManagementInformation: u8,\n    pub Reserved: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR {\n    pub Anonymous: DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0,\n    pub Reserved0: [u8; 3],\n}\nimpl Default for DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0 {\n    pub Dvdrom: DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0_0,\n    pub DvdRecordable_Version1: DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0_1,\n    pub Dvdram: DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0_2,\n    pub DvdRecordable: DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0_3,\n    pub CPR_MAI: u8,\n}\nimpl Default for DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0_1 {\n    pub _bitfield: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0_3 {\n    pub _bitfield: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0_2 {\n    pub Reserved0003: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DVD_COPYRIGHT_MANAGEMENT_DESCRIPTOR_0_0 {\n    pub _bitfield: u8,\n}\npub const DVD_COPYRIGHT_MASK: u32 = 64u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct DVD_COPY_PROTECT_KEY {\n    pub KeyLength: u32,\n    pub SessionId: u32,\n    pub KeyType: DVD_KEY_TYPE,\n    pub KeyFlags: u32,\n    pub Parameters: DVD_COPY_PROTECT_KEY_0,\n    pub KeyData: [u8; 1],\n}\nimpl Default for DVD_COPY_PROTECT_KEY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union DVD_COPY_PROTECT_KEY_0 {\n    pub FileHandle: super::super::Foundation::HANDLE,\n    pub TitleOffset: i64,\n}\nimpl Default for DVD_COPY_PROTECT_KEY_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct DVD_DESCRIPTOR_HEADER {\n    pub Length: u16,\n    pub Reserved: [u8; 2],\n    pub Data: [u8; 1],\n}\nimpl Default for DVD_DESCRIPTOR_HEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DISC_CONTROL_BLOCK_HEADER {\n    pub ContentDescriptor: [u8; 4],\n    pub ProhibitedActions: DVD_DISC_CONTROL_BLOCK_HEADER_0,\n    pub VendorId: [u8; 32],\n}\nimpl Default for DVD_DISC_CONTROL_BLOCK_HEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DVD_DISC_CONTROL_BLOCK_HEADER_0 {\n    pub Anonymous: DVD_DISC_CONTROL_BLOCK_HEADER_0_0,\n    pub AsByte: [u8; 4],\n}\nimpl Default for DVD_DISC_CONTROL_BLOCK_HEADER_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DISC_CONTROL_BLOCK_HEADER_0_0 {\n    pub ReservedDoNotUse_UseAsByteInstead_0: [u8; 3],\n    pub _bitfield: u8,\n}\nimpl Default for DVD_DISC_CONTROL_BLOCK_HEADER_0_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DISC_CONTROL_BLOCK_LIST {\n    pub header: DVD_DISC_CONTROL_BLOCK_HEADER,\n    pub Reserved0: u8,\n    pub ReadabldDCBs: u8,\n    pub Reserved1: u8,\n    pub WritableDCBs: u8,\n    pub Dcbs: [DVD_DISC_CONTROL_BLOCK_LIST_DCB; 1],\n}\nimpl Default for DVD_DISC_CONTROL_BLOCK_LIST {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DISC_CONTROL_BLOCK_LIST_DCB {\n    pub DcbIdentifier: [u8; 4],\n}\nimpl Default for DVD_DISC_CONTROL_BLOCK_LIST_DCB {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DISC_CONTROL_BLOCK_SESSION {\n    pub header: DVD_DISC_CONTROL_BLOCK_HEADER,\n    pub SessionNumber: [u8; 2],\n    pub Reserved0: [u8; 22],\n    pub DiscID: [u8; 32],\n    pub Reserved1: [u8; 32],\n    pub SessionItem: [DVD_DISC_CONTROL_BLOCK_SESSION_ITEM; 504],\n    pub Reserved2: [u8; 24576],\n}\nimpl Default for DVD_DISC_CONTROL_BLOCK_SESSION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DISC_CONTROL_BLOCK_SESSION_ITEM {\n    pub AsByte: [u8; 16],\n}\nimpl Default for DVD_DISC_CONTROL_BLOCK_SESSION_ITEM {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DISC_CONTROL_BLOCK_WRITE_INHIBIT {\n    pub header: DVD_DISC_CONTROL_BLOCK_HEADER,\n    pub UpdateCount: [u8; 4],\n    pub WriteProtectActions: DVD_DISC_CONTROL_BLOCK_WRITE_INHIBIT_0,\n    pub Reserved0: [u8; 16],\n    pub UpdatePassword: [u8; 32],\n    pub Reserved1: [u8; 32672],\n}\nimpl Default for DVD_DISC_CONTROL_BLOCK_WRITE_INHIBIT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DVD_DISC_CONTROL_BLOCK_WRITE_INHIBIT_0 {\n    pub Anonymous: DVD_DISC_CONTROL_BLOCK_WRITE_INHIBIT_0_0,\n    pub AsByte: [u8; 4],\n}\nimpl Default for DVD_DISC_CONTROL_BLOCK_WRITE_INHIBIT_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DISC_CONTROL_BLOCK_WRITE_INHIBIT_0_0 {\n    pub ReservedDoNotUse_UseAsByteInstead_0: [u8; 3],\n    pub _bitfield: u8,\n}\nimpl Default for DVD_DISC_CONTROL_BLOCK_WRITE_INHIBIT_0_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DISK_KEY_DESCRIPTOR {\n    pub DiskKeyData: [u8; 2048],\n}\nimpl Default for DVD_DISK_KEY_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DUAL_LAYER_JUMP_INTERVAL_SIZE {\n    pub Reserved1: [u8; 4],\n    pub JumpIntervalSize: [u8; 4],\n}\nimpl Default for DVD_DUAL_LAYER_JUMP_INTERVAL_SIZE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DUAL_LAYER_MANUAL_LAYER_JUMP {\n    pub Reserved1: [u8; 4],\n    pub ManualJumpLayerAddress: [u8; 4],\n}\nimpl Default for DVD_DUAL_LAYER_MANUAL_LAYER_JUMP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DUAL_LAYER_MIDDLE_ZONE_START_ADDRESS {\n    pub _bitfield: u8,\n    pub Reserved1: [u8; 3],\n    pub ShiftedMiddleAreaStartAddress: [u8; 4],\n}\nimpl Default for DVD_DUAL_LAYER_MIDDLE_ZONE_START_ADDRESS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DUAL_LAYER_RECORDING_INFORMATION {\n    pub _bitfield: u8,\n    pub Reserved1: [u8; 3],\n    pub Layer0Sectors: [u8; 4],\n}\nimpl Default for DVD_DUAL_LAYER_RECORDING_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_DUAL_LAYER_REMAPPING_INFORMATION {\n    pub Reserved1: [u8; 4],\n    pub RemappingAddress: [u8; 4],\n}\nimpl Default for DVD_DUAL_LAYER_REMAPPING_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_FULL_LAYER_DESCRIPTOR {\n    pub commonHeader: DVD_LAYER_DESCRIPTOR,\n    pub MediaSpecific: [u8; 2031],\n}\nimpl Default for DVD_FULL_LAYER_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type DVD_KEY_TYPE = i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct DVD_LAYER_DESCRIPTOR {\n    pub _bitfield1: u8,\n    pub _bitfield2: u8,\n    pub _bitfield3: u8,\n    pub _bitfield4: u8,\n    pub StartingDataSector: u32,\n    pub EndDataSector: u32,\n    pub EndLayerZeroSector: u32,\n    pub _bitfield5: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_LIST_OF_RECOGNIZED_FORMAT_LAYERS {\n    pub TypeCodeOfFormatLayer: [u8; 2],\n}\nimpl Default for DVD_LIST_OF_RECOGNIZED_FORMAT_LAYERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DVD_LIST_OF_RECOGNIZED_FORMAT_LAYERS_TYPE_CODE {\n    pub NumberOfRecognizedFormatLayers: u8,\n    pub _bitfield: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_MANUFACTURER_DESCRIPTOR {\n    pub ManufacturingInformation: [u8; 2048],\n}\nimpl Default for DVD_MANUFACTURER_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DVD_NOT_COPYRIGHTED: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_PRERECORDED_INFORMATION {\n    pub FieldID_1: u8,\n    pub DiscApplicationCode: u8,\n    pub DiscPhysicalCode: u8,\n    pub LastAddressOfDataRecordableArea: [u8; 3],\n    pub _bitfield: u8,\n    pub Reserved0: u8,\n    pub FieldID_2: u8,\n    pub OpcSuggestedCode: u8,\n    pub WavelengthCode: u8,\n    pub WriteStrategyCode: [u8; 4],\n    pub Reserved2: u8,\n    pub FieldID_3: u8,\n    pub ManufacturerId_3: [u8; 6],\n    pub Reserved3: u8,\n    pub FieldID_4: u8,\n    pub ManufacturerId_4: [u8; 6],\n    pub Reserved4: u8,\n    pub FieldID_5: u8,\n    pub ManufacturerId_5: [u8; 6],\n    pub Reserved5: u8,\n    pub Reserved99: [u8; 24],\n}\nimpl Default for DVD_PRERECORDED_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DVD_RAM_MEDIUM_STATUS {\n    pub _bitfield: u8,\n    pub DiscTypeIdentification: u8,\n    pub Reserved2: u8,\n    pub MediaSpecificWriteInhibitInformation: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_RAM_RECORDING_TYPE {\n    pub _bitfield: u8,\n    pub Reserved2: [u8; 3],\n}\nimpl Default for DVD_RAM_RECORDING_TYPE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_RAM_SPARE_AREA_INFORMATION {\n    pub FreePrimarySpareSectors: [u8; 4],\n    pub FreeSupplementalSpareSectors: [u8; 4],\n    pub AllocatedSupplementalSpareSectors: [u8; 4],\n}\nimpl Default for DVD_RAM_SPARE_AREA_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct DVD_READ_STRUCTURE {\n    pub BlockByteOffset: i64,\n    pub Format: DVD_STRUCTURE_FORMAT,\n    pub SessionId: u32,\n    pub LayerNumber: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_RECORDING_MANAGEMENT_AREA_DATA {\n    pub LastRecordedRMASectorNumber: [u8; 4],\n    pub RMDBytes: [u8; 1],\n}\nimpl Default for DVD_RECORDING_MANAGEMENT_AREA_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DVD_REGION {\n    pub CopySystem: u8,\n    pub RegionData: u8,\n    pub SystemRegion: u8,\n    pub ResetCount: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DVD_RPC_KEY {\n    pub _bitfield: u8,\n    pub RegionMask: u8,\n    pub RpcScheme: u8,\n    pub Reserved02: u8,\n}\npub const DVD_SECTOR_NOT_PROTECTED: u32 = 0u32;\npub const DVD_SECTOR_PROTECTED: u32 = 32u32;\npub const DVD_SECTOR_PROTECT_MASK: u32 = 32u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_SET_RPC_KEY {\n    pub PreferredDriveRegionCode: u8,\n    pub Reserved: [u8; 3],\n}\nimpl Default for DVD_SET_RPC_KEY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type DVD_STRUCTURE_FORMAT = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_STRUCTURE_LIST_ENTRY {\n    pub FormatCode: u8,\n    pub _bitfield: u8,\n    pub FormatLength: [u8; 2],\n}\nimpl Default for DVD_STRUCTURE_LIST_ENTRY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_UNIQUE_DISC_IDENTIFIER {\n    pub Reserved0: [u8; 2],\n    pub RandomNumber: [u8; 2],\n    pub Year: [u8; 4],\n    pub Month: [u8; 2],\n    pub Day: [u8; 2],\n    pub Hour: [u8; 2],\n    pub Minute: [u8; 2],\n    pub Second: [u8; 2],\n}\nimpl Default for DVD_UNIQUE_DISC_IDENTIFIER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DVD_WRITE_PROTECTION_STATUS {\n    pub _bitfield: u8,\n    pub Reserved1: [u8; 3],\n}\nimpl Default for DVD_WRITE_PROTECTION_STATUS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DiscControlBlockList: DISC_CONTROL_BLOCK_TYPE = -1i32;\npub const DvdAsf: DVD_KEY_TYPE = 5i32;\npub const DvdBCADescriptor: DVD_STRUCTURE_FORMAT = 3i32;\npub const DvdBusKey1: DVD_KEY_TYPE = 2i32;\npub const DvdBusKey2: DVD_KEY_TYPE = 3i32;\npub const DvdChallengeKey: DVD_KEY_TYPE = 1i32;\npub const DvdCopyrightDescriptor: DVD_STRUCTURE_FORMAT = 1i32;\npub const DvdDiskKey: DVD_KEY_TYPE = 128i32;\npub const DvdDiskKeyDescriptor: DVD_STRUCTURE_FORMAT = 2i32;\npub const DvdGetRpcKey: DVD_KEY_TYPE = 8i32;\npub const DvdInvalidateAGID: DVD_KEY_TYPE = 63i32;\npub const DvdManufacturerDescriptor: DVD_STRUCTURE_FORMAT = 4i32;\npub const DvdMaxDescriptor: DVD_STRUCTURE_FORMAT = 5i32;\npub const DvdPhysicalDescriptor: DVD_STRUCTURE_FORMAT = 0i32;\npub const DvdSetRpcKey: DVD_KEY_TYPE = 6i32;\npub const DvdTitleKey: DVD_KEY_TYPE = 4i32;\npub const FormattingDiscControlBlock: DISC_CONTROL_BLOCK_TYPE = 1178878720i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct HD_DVD_R_MEDIUM_STATUS {\n    pub _bitfield: u8,\n    pub NumberOfRemainingRMDsInRDZ: u8,\n    pub NumberOfRemainingRMDsInCurrentRMZ: [u8; 2],\n}\nimpl Default for HD_DVD_R_MEDIUM_STATUS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const IOCTL_AACS_END_SESSION: u32 = 3363020u32;\npub const IOCTL_AACS_GENERATE_BINDING_NONCE: u32 = 3395824u32;\npub const IOCTL_AACS_GET_CERTIFICATE: u32 = 3363028u32;\npub const IOCTL_AACS_GET_CHALLENGE_KEY: u32 = 3363032u32;\npub const IOCTL_AACS_READ_BINDING_NONCE: u32 = 3363052u32;\npub const IOCTL_AACS_READ_MEDIA_ID: u32 = 3363048u32;\npub const IOCTL_AACS_READ_MEDIA_KEY_BLOCK: u32 = 3363012u32;\npub const IOCTL_AACS_READ_MEDIA_KEY_BLOCK_SIZE: u32 = 3363008u32;\npub const IOCTL_AACS_READ_SERIAL_NUMBER: u32 = 3363044u32;\npub const IOCTL_AACS_READ_VOLUME_ID: u32 = 3363040u32;\npub const IOCTL_AACS_SEND_CERTIFICATE: u32 = 3363024u32;\npub const IOCTL_AACS_SEND_CHALLENGE_KEY: u32 = 3363036u32;\npub const IOCTL_AACS_START_SESSION: u32 = 3363016u32;\npub const IOCTL_DVD_BASE: i32 = 51i32;\npub const IOCTL_DVD_END_SESSION: u32 = 3362828u32;\npub const IOCTL_DVD_GET_REGION: u32 = 3362836u32;\npub const IOCTL_DVD_READ_KEY: u32 = 3362820u32;\npub const IOCTL_DVD_READ_STRUCTURE: u32 = 3363136u32;\npub const IOCTL_DVD_SEND_KEY: u32 = 3362824u32;\npub const IOCTL_DVD_SEND_KEY2: u32 = 3395608u32;\npub const IOCTL_DVD_SET_READ_AHEAD: u32 = 3362832u32;\npub const IOCTL_DVD_START_SESSION: u32 = 3362816u32;\npub const IOCTL_STORAGE_SET_READ_AHEAD: u32 = 2966528u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_SET_READ_AHEAD {\n    pub TriggerAddress: i64,\n    pub TargetAddress: i64,\n}\npub const SessionInfoDiscControlBlock: DISC_CONTROL_BLOCK_TYPE = 1396982528i32;\npub const WriteInhibitDiscControlBlock: DISC_CONTROL_BLOCK_TYPE = 1464091392i32;\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/Devices/PortableDevices/mod.rs",
      "sha256": "30a07e881cd819096e03a2c67ef7f5f398d7cbd556e3d5bd6e3ec7dd7f80c0e7",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "windows_link::link!(\"dmprocessxmlfiltered.dll\" \"system\" fn DMProcessConfigXMLFiltered(pszxmlin : windows_sys::core::PCWSTR, rgszallowedcspnodes : *const windows_sys::core::PCWSTR, dwnumallowedcspnodes : u32, pbstrxmlout : *mut windows_sys::core::BSTR) -> windows_sys::core::HRESULT);\npub const CLSID_WPD_NAMESPACE_EXTENSION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x35786d3c_b075_49b9_88dd_029876e11c01);\npub type DELETE_OBJECT_OPTIONS = i32;\npub type DEVICE_RADIO_STATE = i32;\npub const DEVPKEY_MTPBTH_IsConnected: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0xea1237fa_589d_4472_84e4_0abe36fd62ef), pid: 2 };\npub const DEVSVCTYPE_ABSTRACT: u32 = 1u32;\npub const DEVSVCTYPE_DEFAULT: u32 = 0u32;\npub const DEVSVC_SERVICEINFO_VERSION: u32 = 100u32;\npub const DRS_HW_RADIO_OFF: DEVICE_RADIO_STATE = 2i32;\npub const DRS_HW_RADIO_OFF_UNCONTROLLABLE: DEVICE_RADIO_STATE = 6i32;\npub const DRS_HW_RADIO_ON_UNCONTROLLABLE: DEVICE_RADIO_STATE = 4i32;\npub const DRS_RADIO_INVALID: DEVICE_RADIO_STATE = 5i32;\npub const DRS_RADIO_MAX: DEVICE_RADIO_STATE = 6i32;\npub const DRS_RADIO_ON: DEVICE_RADIO_STATE = 0i32;\npub const DRS_SW_HW_RADIO_OFF: DEVICE_RADIO_STATE = 3i32;\npub const DRS_SW_RADIO_OFF: DEVICE_RADIO_STATE = 1i32;\npub const ENUM_AnchorResults_AnchorStateInvalid: u32 = 1u32;\npub const ENUM_AnchorResults_AnchorStateNormal: u32 = 0u32;\npub const ENUM_AnchorResults_AnchorStateOld: u32 = 2u32;\npub const ENUM_AnchorResults_ItemStateChanged: u32 = 4u32;\npub const ENUM_AnchorResults_ItemStateCreated: u32 = 2u32;\npub const ENUM_AnchorResults_ItemStateDeleted: u32 = 1u32;\npub const ENUM_AnchorResults_ItemStateInvalid: u32 = 0u32;\npub const ENUM_AnchorResults_ItemStateUpdated: u32 = 3u32;\npub const ENUM_CalendarObj_BusyStatusBusy: u32 = 1u32;\npub const ENUM_CalendarObj_BusyStatusFree: u32 = 0u32;\npub const ENUM_CalendarObj_BusyStatusOutOfOffice: u32 = 2u32;\npub const ENUM_CalendarObj_BusyStatusTentative: u32 = 3u32;\npub const ENUM_DeviceMetadataObj_DefaultCABFalse: u32 = 0u32;\npub const ENUM_DeviceMetadataObj_DefaultCABTrue: u32 = 1u32;\npub const ENUM_MessageObj_PatternInstanceFirst: u32 = 1u32;\npub const ENUM_MessageObj_PatternInstanceFourth: u32 = 4u32;\npub const ENUM_MessageObj_PatternInstanceLast: u32 = 5u32;\npub const ENUM_MessageObj_PatternInstanceNone: u32 = 0u32;\npub const ENUM_MessageObj_PatternInstanceSecond: u32 = 2u32;\npub const ENUM_MessageObj_PatternInstanceThird: u32 = 3u32;\npub const ENUM_MessageObj_PatternTypeDaily: u32 = 1u32;\npub const ENUM_MessageObj_PatternTypeMonthly: u32 = 3u32;\npub const ENUM_MessageObj_PatternTypeWeekly: u32 = 2u32;\npub const ENUM_MessageObj_PatternTypeYearly: u32 = 4u32;\npub const ENUM_MessageObj_PriorityHighest: u32 = 2u32;\npub const ENUM_MessageObj_PriorityLowest: u32 = 0u32;\npub const ENUM_MessageObj_PriorityNormal: u32 = 1u32;\npub const ENUM_MessageObj_ReadFalse: u32 = 0u32;\npub const ENUM_MessageObj_ReadTrue: u32 = 255u32;\npub const ENUM_StatusSvc_ChargingActive: u32 = 1u32;\npub const ENUM_StatusSvc_ChargingInactive: u32 = 0u32;\npub const ENUM_StatusSvc_ChargingUnknown: u32 = 2u32;\npub const ENUM_StatusSvc_RoamingActive: u32 = 1u32;\npub const ENUM_StatusSvc_RoamingInactive: u32 = 0u32;\npub const ENUM_StatusSvc_RoamingUnknown: u32 = 2u32;\npub const ENUM_SyncSvc_SyncObjectReferencesDisabled: u32 = 0u32;\npub const ENUM_SyncSvc_SyncObjectReferencesEnabled: u32 = 255u32;\npub const ENUM_TaskObj_CompleteFalse: u32 = 0u32;\npub const ENUM_TaskObj_CompleteTrue: u32 = 255u32;\npub const E_WPD_DEVICE_ALREADY_OPENED: windows_sys::core::HRESULT = 0x802A0001_u32 as _;\npub const E_WPD_DEVICE_IS_HUNG: windows_sys::core::HRESULT = 0x802A0006_u32 as _;\npub const E_WPD_DEVICE_NOT_OPEN: windows_sys::core::HRESULT = 0x802A0002_u32 as _;\npub const E_WPD_OBJECT_ALREADY_ATTACHED_TO_DEVICE: windows_sys::core::HRESULT = 0x802A0003_u32 as _;\npub const E_WPD_OBJECT_ALREADY_ATTACHED_TO_SERVICE: windows_sys::core::HRESULT = 0x802A00CA_u32 as _;\npub const E_WPD_OBJECT_NOT_ATTACHED_TO_DEVICE: windows_sys::core::HRESULT = 0x802A0004_u32 as _;\npub const E_WPD_OBJECT_NOT_ATTACHED_TO_SERVICE: windows_sys::core::HRESULT = 0x802A00CB_u32 as _;\npub const E_WPD_OBJECT_NOT_COMMITED: windows_sys::core::HRESULT = 0x802A0005_u32 as _;\npub const E_WPD_SERVICE_ALREADY_OPENED: windows_sys::core::HRESULT = 0x802A00C8_u32 as _;\npub const E_WPD_SERVICE_BAD_PARAMETER_ORDER: windows_sys::core::HRESULT = 0x802A00CC_u32 as _;\npub const E_WPD_SERVICE_NOT_OPEN: windows_sys::core::HRESULT = 0x802A00C9_u32 as _;\npub const E_WPD_SMS_INVALID_MESSAGE_BODY: windows_sys::core::HRESULT = 0x802A0065_u32 as _;\npub const E_WPD_SMS_INVALID_RECIPIENT: windows_sys::core::HRESULT = 0x802A0064_u32 as _;\npub const E_WPD_SMS_SERVICE_UNAVAILABLE: windows_sys::core::HRESULT = 0x802A0066_u32 as _;\npub const EnumBthMtpConnectors: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa1570149_e645_4f43_8b0d_409b061db2fc);\npub const FACILITY_WPD: u32 = 42u32;\npub const FLAG_MessageObj_DayOfWeekFriday: u32 = 32u32;\npub const FLAG_MessageObj_DayOfWeekMonday: u32 = 2u32;\npub const FLAG_MessageObj_DayOfWeekNone: u32 = 0u32;\npub const FLAG_MessageObj_DayOfWeekSaturday: u32 = 64u32;\npub const FLAG_MessageObj_DayOfWeekSunday: u32 = 1u32;\npub const FLAG_MessageObj_DayOfWeekThursday: u32 = 16u32;\npub const FLAG_MessageObj_DayOfWeekTuesday: u32 = 4u32;\npub const FLAG_MessageObj_DayOfWeekWednesday: u32 = 8u32;\npub const GUID_DEVINTERFACE_WPD: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6ac27878_a6fa_4155_ba85_f98f491d4f33);\npub const GUID_DEVINTERFACE_WPD_PRIVATE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba0c718f_4ded_49b7_bdd3_fabe28661211);\npub const GUID_DEVINTERFACE_WPD_SERVICE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9ef44f80_3d64_4246_a6aa_206f328d1edc);\npub const IOCTL_WPD_MESSAGE_READWRITE_ACCESS: u32 = 4243720u32;\npub const IOCTL_WPD_MESSAGE_READ_ACCESS: u32 = 4210952u32;\npub const NAME_3GPP2File: windows_sys::core::PCWSTR = windows_sys::core::w!(\"3GPP2File\");\npub const NAME_3GPPFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"3GPPFile\");\npub const NAME_AACFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AACFile\");\npub const NAME_AIFFFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AIFFFile\");\npub const NAME_AMRFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AMRFile\");\npub const NAME_ASFFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ASFFile\");\npub const NAME_ASXPlaylist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ASXPlaylist\");\npub const NAME_ATSCTSFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ATSCTSFile\");\npub const NAME_AVCHDFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AVCHDFile\");\npub const NAME_AVIFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AVIFile\");\npub const NAME_AbstractActivity: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractActivity\");\npub const NAME_AbstractActivityOccurrence: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractActivityOccurrence\");\npub const NAME_AbstractAudioAlbum: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractAudioAlbum\");\npub const NAME_AbstractAudioPlaylist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractAudioPlaylist\");\npub const NAME_AbstractAudioVideoAlbum: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractAudioVideoAlbum\");\npub const NAME_AbstractChapteredProduction: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractChapteredProduction\");\npub const NAME_AbstractContact: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractContact\");\npub const NAME_AbstractContactGroup: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractContactGroup\");\npub const NAME_AbstractDocument: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractDocument\");\npub const NAME_AbstractImageAlbum: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractImageAlbum\");\npub const NAME_AbstractMediacast: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractMediacast\");\npub const NAME_AbstractMessage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractMessage\");\npub const NAME_AbstractMessageFolder: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractMessageFolder\");\npub const NAME_AbstractMultimediaAlbum: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractMultimediaAlbum\");\npub const NAME_AbstractNote: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractNote\");\npub const NAME_AbstractTask: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractTask\");\npub const NAME_AbstractVideoAlbum: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractVideoAlbum\");\npub const NAME_AbstractVideoPlaylist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AbstractVideoPlaylist\");\npub const NAME_AnchorResults: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnchorResults\");\npub const NAME_AnchorResults_Anchor: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Anchor\");\npub const NAME_AnchorResults_AnchorState: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnchorState\");\npub const NAME_AnchorResults_ResultObjectID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ResultObjectID\");\npub const NAME_AnchorSyncKnowledge: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnchorSyncKnowledge\");\npub const NAME_AnchorSyncSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnchorSync\");\npub const NAME_AnchorSyncSvc_BeginSync: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BeginSync\");\npub const NAME_AnchorSyncSvc_CurrentAnchor: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnchorCurrentAnchor\");\npub const NAME_AnchorSyncSvc_EndSync: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EndSync\");\npub const NAME_AnchorSyncSvc_FilterType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FilterType\");\npub const NAME_AnchorSyncSvc_GetChangesSinceAnchor: windows_sys::core::PCWSTR = windows_sys::core::w!(\"GetChangesSinceAnchor\");\npub const NAME_AnchorSyncSvc_KnowledgeObjectID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnchorKnowledgeObjectID\");\npub const NAME_AnchorSyncSvc_LastSyncProxyID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnchorLastSyncProxyID\");\npub const NAME_AnchorSyncSvc_LocalOnlyDelete: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LocalOnlyDelete\");\npub const NAME_AnchorSyncSvc_ProviderVersion: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnchorProviderVersion\");\npub const NAME_AnchorSyncSvc_ReplicaID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnchorReplicaID\");\npub const NAME_AnchorSyncSvc_SyncFormat: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SyncFormat\");\npub const NAME_AnchorSyncSvc_VersionProps: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnchorVersionProps\");\npub const NAME_Association: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Association\");\npub const NAME_AudibleFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AudibleFile\");\npub const NAME_AudioObj_AudioBitDepth: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AudioBitDepth\");\npub const NAME_AudioObj_AudioBitRate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AudioBitRate\");\npub const NAME_AudioObj_AudioBlockAlignment: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AudioBlockAlignment\");\npub const NAME_AudioObj_AudioFormatCode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AudioFormatCode\");\npub const NAME_AudioObj_Channels: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Channels\");\npub const NAME_AudioObj_Lyrics: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Lyrics\");\npub const NAME_BMPImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BMPImage\");\npub const NAME_CIFFImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CIFFImage\");\npub const NAME_CalendarObj_Accepted: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Accepted\");\npub const NAME_CalendarObj_BeginDateTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BeginDateTime\");\npub const NAME_CalendarObj_BusyStatus: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusyStatus\");\npub const NAME_CalendarObj_Declined: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Declined\");\npub const NAME_CalendarObj_EndDateTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EndDateTime\");\npub const NAME_CalendarObj_Location: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Location\");\npub const NAME_CalendarObj_PatternDuration: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternDuration\");\npub const NAME_CalendarObj_PatternStartTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternStartTime\");\npub const NAME_CalendarObj_ReminderOffset: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ReminderOffset\");\npub const NAME_CalendarObj_Tentative: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Tentative\");\npub const NAME_CalendarObj_TimeZone: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TimeZone\");\npub const NAME_CalendarSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Calendar\");\npub const NAME_CalendarSvc_SyncWindowEnd: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SyncWindowEnd\");\npub const NAME_CalendarSvc_SyncWindowStart: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SyncWindowStart\");\npub const NAME_ContactObj_AnniversaryDate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AnniversaryDate\");\npub const NAME_ContactObj_Assistant: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Assistant\");\npub const NAME_ContactObj_Birthdate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Birthdate\");\npub const NAME_ContactObj_BusinessAddressCity: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessAddressCity\");\npub const NAME_ContactObj_BusinessAddressCountry: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessAddressCountry\");\npub const NAME_ContactObj_BusinessAddressFull: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessAddressFull\");\npub const NAME_ContactObj_BusinessAddressLine2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessAddressLine2\");\npub const NAME_ContactObj_BusinessAddressPostalCode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessAddressPostalCode\");\npub const NAME_ContactObj_BusinessAddressRegion: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessAddressRegion\");\npub const NAME_ContactObj_BusinessAddressStreet: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessAddressStreet\");\npub const NAME_ContactObj_BusinessEmail: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessEmail\");\npub const NAME_ContactObj_BusinessEmail2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessEmail2\");\npub const NAME_ContactObj_BusinessFax: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessFax\");\npub const NAME_ContactObj_BusinessPhone: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessPhone\");\npub const NAME_ContactObj_BusinessPhone2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessPhone2\");\npub const NAME_ContactObj_BusinessWebAddress: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BusinessWebAddress\");\npub const NAME_ContactObj_Children: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Children\");\npub const NAME_ContactObj_Email: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Email\");\npub const NAME_ContactObj_FamilyName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FamilyName\");\npub const NAME_ContactObj_Fax: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Fax\");\npub const NAME_ContactObj_GivenName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"GivenName\");\npub const NAME_ContactObj_IMAddress: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IMAddress\");\npub const NAME_ContactObj_IMAddress2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IMAddress2\");\npub const NAME_ContactObj_IMAddress3: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IMAddress3\");\npub const NAME_ContactObj_MiddleNames: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MiddleNames\");\npub const NAME_ContactObj_MobilePhone: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MobilePhone\");\npub const NAME_ContactObj_MobilePhone2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MobilePhone2\");\npub const NAME_ContactObj_Organization: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Organization\");\npub const NAME_ContactObj_OtherAddressCity: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OtherAddressCity\");\npub const NAME_ContactObj_OtherAddressCountry: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OtherAddressCountry\");\npub const NAME_ContactObj_OtherAddressFull: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OtherAddressFull\");\npub const NAME_ContactObj_OtherAddressLine2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OtherAddressLine2\");\npub const NAME_ContactObj_OtherAddressPostalCode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OtherAddressPostalCode\");\npub const NAME_ContactObj_OtherAddressRegion: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OtherAddressRegion\");\npub const NAME_ContactObj_OtherAddressStreet: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OtherAddressStreet\");\npub const NAME_ContactObj_OtherEmail: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OtherEmail\");\npub const NAME_ContactObj_OtherPhone: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OtherPhone\");\npub const NAME_ContactObj_Pager: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Pager\");\npub const NAME_ContactObj_PersonalAddressCity: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalAddressCity\");\npub const NAME_ContactObj_PersonalAddressCountry: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalAddressCountry\");\npub const NAME_ContactObj_PersonalAddressFull: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalAddressFull\");\npub const NAME_ContactObj_PersonalAddressLine2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalAddressLine2\");\npub const NAME_ContactObj_PersonalAddressPostalCode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalAddressPostalCode\");\npub const NAME_ContactObj_PersonalAddressRegion: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalAddressRegion\");\npub const NAME_ContactObj_PersonalAddressStreet: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalAddressStreet\");\npub const NAME_ContactObj_PersonalEmail: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalEmail\");\npub const NAME_ContactObj_PersonalEmail2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalEmail2\");\npub const NAME_ContactObj_PersonalFax: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalFax\");\npub const NAME_ContactObj_PersonalPhone: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalPhone\");\npub const NAME_ContactObj_PersonalPhone2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalPhone2\");\npub const NAME_ContactObj_PersonalWebAddress: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersonalWebAddress\");\npub const NAME_ContactObj_Phone: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Phone\");\npub const NAME_ContactObj_PhoneticFamilyName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PhoneticFamilyName\");\npub const NAME_ContactObj_PhoneticGivenName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PhoneticGivenName\");\npub const NAME_ContactObj_PhoneticOrganization: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PhoneticOrganization\");\npub const NAME_ContactObj_Ringtone: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Ringtone\");\npub const NAME_ContactObj_Role: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Role\");\npub const NAME_ContactObj_Spouse: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Spouse\");\npub const NAME_ContactObj_Suffix: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Suffix\");\npub const NAME_ContactObj_Title: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Title\");\npub const NAME_ContactObj_WebAddress: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WebAddress\");\npub const NAME_ContactSvc_SyncWithPhoneOnly: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FilterType\");\npub const NAME_ContactsSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Contacts\");\npub const NAME_DPOFDocument: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DPOFDocument\");\npub const NAME_DVBTSFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DVBTSFile\");\npub const NAME_DeviceExecutable: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DeviceExecutable\");\npub const NAME_DeviceMetadataCAB: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DeviceMetadataCAB\");\npub const NAME_DeviceMetadataObj_ContentID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ContentID\");\npub const NAME_DeviceMetadataObj_DefaultCAB: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DefaultCAB\");\npub const NAME_DeviceMetadataSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Metadata\");\npub const NAME_DeviceScript: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DeviceScript\");\npub const NAME_EXIFImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EXIFImage\");\npub const NAME_ExcelDocument: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ExcelDocument\");\npub const NAME_FLACFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FLACFile\");\npub const NAME_FirmwareFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FirmwareFile\");\npub const NAME_FlashPixImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FlashPixImage\");\npub const NAME_FullEnumSyncKnowledge: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FullEnumSyncKnowledge\");\npub const NAME_FullEnumSyncSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FullEnumSync\");\npub const NAME_FullEnumSyncSvc_BeginSync: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BeginSync\");\npub const NAME_FullEnumSyncSvc_EndSync: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EndSync\");\npub const NAME_FullEnumSyncSvc_FilterType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FilterType\");\npub const NAME_FullEnumSyncSvc_KnowledgeObjectID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FullEnumKnowledgeObjectID\");\npub const NAME_FullEnumSyncSvc_LastSyncProxyID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FullEnumLastSyncProxyID\");\npub const NAME_FullEnumSyncSvc_LocalOnlyDelete: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LocalOnlyDelete\");\npub const NAME_FullEnumSyncSvc_ProviderVersion: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FullEnumProviderVersion\");\npub const NAME_FullEnumSyncSvc_ReplicaID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FullEnumReplicaID\");\npub const NAME_FullEnumSyncSvc_SyncFormat: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SyncFormat\");\npub const NAME_FullEnumSyncSvc_VersionProps: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FullEnumVersionProps\");\npub const NAME_GIFImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"GIFImage\");\npub const NAME_GenericObj_AllowedFolderContents: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AllowedFolderContents\");\npub const NAME_GenericObj_AssociationDesc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AssociationDesc\");\npub const NAME_GenericObj_AssociationType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AssociationType\");\npub const NAME_GenericObj_Copyright: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Copyright\");\npub const NAME_GenericObj_Corrupt: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Corrupt\");\npub const NAME_GenericObj_DRMStatus: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRMStatus\");\npub const NAME_GenericObj_DateAccessed: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DateAccessed\");\npub const NAME_GenericObj_DateAdded: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DateAdded\");\npub const NAME_GenericObj_DateAuthored: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DateAuthored\");\npub const NAME_GenericObj_DateCreated: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DateCreated\");\npub const NAME_GenericObj_DateModified: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DateModified\");\npub const NAME_GenericObj_DateRevised: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DateRevised\");\npub const NAME_GenericObj_Description: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Description\");\npub const NAME_GenericObj_Hidden: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Hidden\");\npub const NAME_GenericObj_Keywords: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Keywords\");\npub const NAME_GenericObj_LanguageLocale: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LanguageLocale\");\npub const NAME_GenericObj_Name: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Name\");\npub const NAME_GenericObj_NonConsumable: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NonConsumable\");\npub const NAME_GenericObj_ObjectFileName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ObjectFileName\");\npub const NAME_GenericObj_ObjectFormat: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ObjectFormat\");\npub const NAME_GenericObj_ObjectID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ObjectID\");\npub const NAME_GenericObj_ObjectSize: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ObjectSize\");\npub const NAME_GenericObj_ParentID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ParentID\");\npub const NAME_GenericObj_PersistentUID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PersistentUID\");\npub const NAME_GenericObj_PropertyBag: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PropertyBag\");\npub const NAME_GenericObj_ProtectionStatus: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ProtectionStatus\");\npub const NAME_GenericObj_ReferenceParentID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ReferenceParentID\");\npub const NAME_GenericObj_StorageID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"StorageID\");\npub const NAME_GenericObj_SubDescription: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubDescription\");\npub const NAME_GenericObj_SyncID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SyncID\");\npub const NAME_GenericObj_SystemObject: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SystemObject\");\npub const NAME_GenericObj_TimeToLive: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TimeToLive\");\npub const NAME_HDPhotoImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HDPhotoImage\");\npub const NAME_HTMLDocument: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HTMLDocument\");\npub const NAME_HintsSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Hints\");\npub const NAME_ICalendarActivity: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ICalendar\");\npub const NAME_ImageObj_Aperature: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Aperature\");\npub const NAME_ImageObj_Exposure: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Exposure\");\npub const NAME_ImageObj_ISOSpeed: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ISOSpeed\");\npub const NAME_ImageObj_ImageBitDepth: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ImageBitDepth\");\npub const NAME_ImageObj_IsColorCorrected: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IsColorCorrected\");\npub const NAME_ImageObj_IsCropped: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IsCropped\");\npub const NAME_JFIFImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"JFIFImage\");\npub const NAME_JP2Image: windows_sys::core::PCWSTR = windows_sys::core::w!(\"JP2Image\");\npub const NAME_JPEGXRImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"JPEGXRImage\");\npub const NAME_JPXImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"JPXImage\");\npub const NAME_M3UPlaylist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"M3UPlaylist\");\npub const NAME_MHTDocument: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MHTDocument\");\npub const NAME_MP3File: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MP3File\");\npub const NAME_MPEG2File: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MPEG2File\");\npub const NAME_MPEG4File: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MPEG4File\");\npub const NAME_MPEGFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MPEGFile\");\npub const NAME_MPLPlaylist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MPLPlaylist\");\npub const NAME_MediaObj_AlbumArtist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AlbumArtist\");\npub const NAME_MediaObj_AlbumName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AlbumName\");\npub const NAME_MediaObj_Artist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Artist\");\npub const NAME_MediaObj_AudioEncodingProfile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AudioEncodingProfile\");\npub const NAME_MediaObj_BitRateType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BitRateType\");\npub const NAME_MediaObj_BookmarkByte: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BookmarkByte\");\npub const NAME_MediaObj_BookmarkObject: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BookmarkObject\");\npub const NAME_MediaObj_BookmarkTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BookmarkTime\");\npub const NAME_MediaObj_BufferSize: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BufferSize\");\npub const NAME_MediaObj_Composer: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Composer\");\npub const NAME_MediaObj_Credits: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Credits\");\npub const NAME_MediaObj_DateOriginalRelease: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DateOriginalRelease\");\npub const NAME_MediaObj_Duration: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Duration\");\npub const NAME_MediaObj_Editor: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Editor\");\npub const NAME_MediaObj_EffectiveRating: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EffectiveRating\");\npub const NAME_MediaObj_EncodingProfile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EncodingProfile\");\npub const NAME_MediaObj_EncodingQuality: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EncodingQuality\");\npub const NAME_MediaObj_Genre: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Genre\");\npub const NAME_MediaObj_GeographicOrigin: windows_sys::core::PCWSTR = windows_sys::core::w!(\"GeographicOrigin\");\npub const NAME_MediaObj_Height: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Height\");\npub const NAME_MediaObj_MediaType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MediaType\");\npub const NAME_MediaObj_MediaUID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MediaUID\");\npub const NAME_MediaObj_Mood: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Mood\");\npub const NAME_MediaObj_Owner: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Owner\");\npub const NAME_MediaObj_ParentalRating: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ParentalRating\");\npub const NAME_MediaObj_Producer: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Producer\");\npub const NAME_MediaObj_SampleRate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SampleRate\");\npub const NAME_MediaObj_SkipCount: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SkipCount\");\npub const NAME_MediaObj_SubscriptionContentID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubscriptionContentID\");\npub const NAME_MediaObj_Subtitle: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Subtitle\");\npub const NAME_MediaObj_TotalBitRate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TotalBitRate\");\npub const NAME_MediaObj_Track: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Track\");\npub const NAME_MediaObj_URLLink: windows_sys::core::PCWSTR = windows_sys::core::w!(\"URLLink\");\npub const NAME_MediaObj_URLSource: windows_sys::core::PCWSTR = windows_sys::core::w!(\"URLSource\");\npub const NAME_MediaObj_UseCount: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UseCount\");\npub const NAME_MediaObj_UserRating: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UserRating\");\npub const NAME_MediaObj_WebMaster: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WebMaster\");\npub const NAME_MediaObj_Width: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Width\");\npub const NAME_MessageObj_BCC: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BCC\");\npub const NAME_MessageObj_Body: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Body\");\npub const NAME_MessageObj_CC: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CC\");\npub const NAME_MessageObj_Category: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Category\");\npub const NAME_MessageObj_PatternDayOfMonth: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternDayOfMonth\");\npub const NAME_MessageObj_PatternDayOfWeek: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternDayOfWeek\");\npub const NAME_MessageObj_PatternDeleteDates: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternDeleteDates\");\npub const NAME_MessageObj_PatternInstance: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternInstance\");\npub const NAME_MessageObj_PatternMonthOfYear: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternMonthOfYear\");\npub const NAME_MessageObj_PatternOriginalDateTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternOriginalDateTime\");\npub const NAME_MessageObj_PatternPeriod: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternPeriod\");\npub const NAME_MessageObj_PatternType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternType\");\npub const NAME_MessageObj_PatternValidEndDate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternValidEndDate\");\npub const NAME_MessageObj_PatternValidStartDate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PatternValidStartDate\");\npub const NAME_MessageObj_Priority: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Priority\");\npub const NAME_MessageObj_Read: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Read\");\npub const NAME_MessageObj_ReceivedTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ReceivedTime\");\npub const NAME_MessageObj_Sender: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Sender\");\npub const NAME_MessageObj_Subject: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Subject\");\npub const NAME_MessageObj_To: windows_sys::core::PCWSTR = windows_sys::core::w!(\"To\");\npub const NAME_MessageSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Message\");\npub const NAME_NotesSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Notes\");\npub const NAME_OGGFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OGGFile\");\npub const NAME_PCDImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PCDImage\");\npub const NAME_PICTImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PICTImage\");\npub const NAME_PNGImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PNGImage\");\npub const NAME_PSLPlaylist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PSLPlaylist\");\npub const NAME_PowerPointDocument: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PowerPointDocument\");\npub const NAME_QCELPFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"QCELPFile\");\npub const NAME_RingtonesSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Ringtones\");\npub const NAME_RingtonesSvc_DefaultRingtone: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DefaultRingtone\");\npub const NAME_Services_ServiceDisplayName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ServiceDisplayName\");\npub const NAME_Services_ServiceIcon: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ServiceIcon\");\npub const NAME_Services_ServiceLocale: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ServiceLocale\");\npub const NAME_StatusSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Status\");\npub const NAME_StatusSvc_BatteryLife: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BatteryLife\");\npub const NAME_StatusSvc_ChargingState: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ChargingState\");\npub const NAME_StatusSvc_MissedCalls: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MissedCalls\");\npub const NAME_StatusSvc_NetworkName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NetworkName\");\npub const NAME_StatusSvc_NetworkType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NetworkType\");\npub const NAME_StatusSvc_NewPictures: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NewPictures\");\npub const NAME_StatusSvc_Roaming: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Roaming\");\npub const NAME_StatusSvc_SignalStrength: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SignalStrength\");\npub const NAME_StatusSvc_StorageCapacity: windows_sys::core::PCWSTR = windows_sys::core::w!(\"StorageCapacity\");\npub const NAME_StatusSvc_StorageFreeSpace: windows_sys::core::PCWSTR = windows_sys::core::w!(\"StorageFreeSpace\");\npub const NAME_StatusSvc_TextMessages: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TextMessages\");\npub const NAME_StatusSvc_VoiceMail: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VoiceMail\");\npub const NAME_SyncObj_LastAuthorProxyID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LastAuthorProxyID\");\npub const NAME_SyncSvc_BeginSync: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BeginSync\");\npub const NAME_SyncSvc_EndSync: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EndSync\");\npub const NAME_SyncSvc_FilterType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FilterType\");\npub const NAME_SyncSvc_LocalOnlyDelete: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LocalOnlyDelete\");\npub const NAME_SyncSvc_SyncFormat: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SyncFormat\");\npub const NAME_SyncSvc_SyncObjectReferences: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SyncObjectReferences\");\npub const NAME_TIFFEPImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TIFFEPImage\");\npub const NAME_TIFFITImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TIFFITImage\");\npub const NAME_TIFFImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TIFFImage\");\npub const NAME_TaskObj_BeginDate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BeginDate\");\npub const NAME_TaskObj_Complete: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Complete\");\npub const NAME_TaskObj_EndDate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EndDate\");\npub const NAME_TaskObj_ReminderDateTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ReminderDateTime\");\npub const NAME_TasksSvc: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Tasks\");\npub const NAME_TasksSvc_SyncActiveOnly: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FilterType\");\npub const NAME_TextDocument: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TextDocument\");\npub const NAME_Undefined: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Undefined\");\npub const NAME_UndefinedAudio: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UndefinedAudio\");\npub const NAME_UndefinedCollection: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UndefinedCollection\");\npub const NAME_UndefinedDocument: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UndefinedDocument\");\npub const NAME_UndefinedVideo: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UndefinedVideo\");\npub const NAME_UnknownImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UnknownImage\");\npub const NAME_VCalendar1Activity: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VCalendar1\");\npub const NAME_VCard2Contact: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VCard2Contact\");\npub const NAME_VCard3Contact: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VCard3Contact\");\npub const NAME_VideoObj_KeyFrameDistance: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyFrameDistance\");\npub const NAME_VideoObj_ScanType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ScanType\");\npub const NAME_VideoObj_Source: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Source\");\npub const NAME_VideoObj_VideoBitRate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VideoBitRate\");\npub const NAME_VideoObj_VideoFormatCode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VideoFormatCode\");\npub const NAME_VideoObj_VideoFrameRate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VideoFrameRate\");\npub const NAME_WAVFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WAVFile\");\npub const NAME_WBMPImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WBMPImage\");\npub const NAME_WMAFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WMAFile\");\npub const NAME_WMVFile: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WMVFile\");\npub const NAME_WPLPlaylist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WPLPlaylist\");\npub const NAME_WordDocument: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WordDocument\");\npub const NAME_XMLDocument: windows_sys::core::PCWSTR = windows_sys::core::w!(\"XMLDocument\");\npub const PORTABLE_DEVICE_DELETE_NO_RECURSION: DELETE_OBJECT_OPTIONS = 0i32;\npub const PORTABLE_DEVICE_DELETE_WITH_RECURSION: DELETE_OBJECT_OPTIONS = 1i32;\npub const PORTABLE_DEVICE_DRM_SCHEME_PDDRM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PDDRM\");\npub const PORTABLE_DEVICE_DRM_SCHEME_WMDRM10_PD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WMDRM10-PD\");\npub const PORTABLE_DEVICE_ICON: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Icons\");\npub const PORTABLE_DEVICE_IS_MASS_STORAGE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PortableDeviceIsMassStorage\");\npub const PORTABLE_DEVICE_NAMESPACE_EXCLUDE_FROM_SHELL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PortableDeviceNameSpaceExcludeFromShell\");\npub const PORTABLE_DEVICE_NAMESPACE_THUMBNAIL_CONTENT_TYPES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PortableDeviceNameSpaceThumbnailContentTypes\");\npub const PORTABLE_DEVICE_NAMESPACE_TIMEOUT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PortableDeviceNameSpaceTimeout\");\npub const PORTABLE_DEVICE_TYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PortableDeviceType\");\npub const PortableDevice: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x728a21c5_3d9e_48d7_9810_864848f0f404);\npub const PortableDeviceDispatchFactory: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x43232233_8338_4658_ae01_0b4ae830b6b0);\npub const PortableDeviceFTM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf7c0039a_4762_488a_b4b3_760ef9a1ba9b);\npub const PortableDeviceKeyCollection: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xde2d022d_2480_43be_97f0_d1fa2cf98f4f);\npub const PortableDeviceManager: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0af10cec_2ecd_4b92_9581_34f6ae0637f3);\npub const PortableDevicePropVariantCollection: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x08a99e2f_6d6d_4b80_af5a_baf2bcbe4cb9);\npub const PortableDeviceService: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xef5db4c2_9312_422c_9152_411cd9c4dd84);\npub const PortableDeviceServiceFTM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1649b154_c794_497a_9b03_f3f0121302f3);\npub const PortableDeviceValues: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0c15d503_d017_47ce_9016_7b3f978721cc);\npub const PortableDeviceValuesCollection: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3882134d_14cf_4220_9cb4_435f86d83f60);\npub const PortableDeviceWebControl: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x186dd02c_2dec_41b5_a7d4_b59056fade51);\npub const RANGEMAX_MessageObj_PatternDayOfMonth: u32 = 31u32;\npub const RANGEMAX_MessageObj_PatternMonthOfYear: u32 = 12u32;\npub const RANGEMAX_StatusSvc_BatteryLife: u32 = 100u32;\npub const RANGEMAX_StatusSvc_MissedCalls: u32 = 255u32;\npub const RANGEMAX_StatusSvc_NewPictures: u32 = 65535u32;\npub const RANGEMAX_StatusSvc_SignalStrength: u32 = 4u32;\npub const RANGEMAX_StatusSvc_TextMessages: u32 = 255u32;\npub const RANGEMAX_StatusSvc_VoiceMail: u32 = 255u32;\npub const RANGEMIN_MessageObj_PatternDayOfMonth: u32 = 1u32;\npub const RANGEMIN_MessageObj_PatternMonthOfYear: u32 = 1u32;\npub const RANGEMIN_StatusSvc_BatteryLife: u32 = 0u32;\npub const RANGEMIN_StatusSvc_SignalStrength: u32 = 0u32;\npub const RANGESTEP_MessageObj_PatternDayOfMonth: u32 = 1u32;\npub const RANGESTEP_MessageObj_PatternMonthOfYear: u32 = 1u32;\npub const RANGESTEP_StatusSvc_BatteryLife: u32 = 1u32;\npub const RANGESTEP_StatusSvc_SignalStrength: u32 = 1u32;\npub const SMS_BINARY_MESSAGE: SMS_MESSAGE_TYPES = 1i32;\npub const SMS_ENCODING_7_BIT: WPD_SMS_ENCODING_TYPES = 0i32;\npub const SMS_ENCODING_8_BIT: WPD_SMS_ENCODING_TYPES = 1i32;\npub const SMS_ENCODING_UTF_16: WPD_SMS_ENCODING_TYPES = 2i32;\npub type SMS_MESSAGE_TYPES = i32;\npub const SMS_TEXT_MESSAGE: SMS_MESSAGE_TYPES = 0i32;\npub const SRS_RADIO_DISABLED: SYSTEM_RADIO_STATE = 1i32;\npub const SRS_RADIO_ENABLED: SYSTEM_RADIO_STATE = 0i32;\npub const STR_WPDNSE_FAST_ENUM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WPDNSE Fast Enum\");\npub const STR_WPDNSE_SIMPLE_ITEM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WPDNSE SimpleItem\");\npub const SYNCSVC_FILTER_CALENDAR_WINDOW_WITH_RECURRENCE: u32 = 3u32;\npub const SYNCSVC_FILTER_CONTACTS_WITH_PHONE: u32 = 1u32;\npub const SYNCSVC_FILTER_NONE: u32 = 0u32;\npub const SYNCSVC_FILTER_TASK_ACTIVE: u32 = 2u32;\npub type SYSTEM_RADIO_STATE = i32;\npub const TYPE_AnchorSyncSvc: u32 = 1u32;\npub const TYPE_CalendarSvc: u32 = 0u32;\npub const TYPE_ContactsSvc: u32 = 0u32;\npub const TYPE_DeviceMetadataSvc: u32 = 0u32;\npub const TYPE_FullEnumSyncSvc: u32 = 1u32;\npub const TYPE_HintsSvc: u32 = 0u32;\npub const TYPE_MessageSvc: u32 = 0u32;\npub const TYPE_NotesSvc: u32 = 0u32;\npub const TYPE_RingtonesSvc: u32 = 0u32;\npub const TYPE_StatusSvc: u32 = 0u32;\npub const TYPE_TasksSvc: u32 = 0u32;\npub const WPDNSE_OBJECT_HAS_ALBUM_ART: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x34d71409_4b47_4d80_aaac_3a28a4a3b3e6), pid: 6 };\npub const WPDNSE_OBJECT_HAS_AUDIO_CLIP: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x34d71409_4b47_4d80_aaac_3a28a4a3b3e6), pid: 5 };\npub const WPDNSE_OBJECT_HAS_CONTACT_PHOTO: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x34d71409_4b47_4d80_aaac_3a28a4a3b3e6), pid: 2 };\npub const WPDNSE_OBJECT_HAS_ICON: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x34d71409_4b47_4d80_aaac_3a28a4a3b3e6), pid: 4 };\npub const WPDNSE_OBJECT_HAS_THUMBNAIL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x34d71409_4b47_4d80_aaac_3a28a4a3b3e6), pid: 3 };\npub const WPDNSE_OBJECT_OPTIMAL_READ_BLOCK_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x34d71409_4b47_4d80_aaac_3a28a4a3b3e6), pid: 7 };\npub const WPDNSE_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x34d71409_4b47_4d80_aaac_3a28a4a3b3e6);\npub const WPDNSE_PROPSHEET_CONTENT_DETAILS: u32 = 32u32;\npub const WPDNSE_PROPSHEET_CONTENT_GENERAL: u32 = 4u32;\npub const WPDNSE_PROPSHEET_CONTENT_REFERENCES: u32 = 8u32;\npub const WPDNSE_PROPSHEET_CONTENT_RESOURCES: u32 = 16u32;\npub const WPDNSE_PROPSHEET_DEVICE_GENERAL: u32 = 1u32;\npub const WPDNSE_PROPSHEET_STORAGE_GENERAL: u32 = 2u32;\npub const WPD_API_OPTIONS_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x10e54a3e_052d_4777_a13c_de7614be2bc4);\npub const WPD_API_OPTION_IOCTL_ACCESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x10e54a3e_052d_4777_a13c_de7614be2bc4), pid: 3 };\npub const WPD_API_OPTION_USE_CLEAR_DATA_STREAM: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x10e54a3e_052d_4777_a13c_de7614be2bc4), pid: 2 };\npub const WPD_APPOINTMENT_ACCEPTED_ATTENDEES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf99efd03_431d_40d8_a1c9_4e220d9c88d3), pid: 10 };\npub const WPD_APPOINTMENT_DECLINED_ATTENDEES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf99efd03_431d_40d8_a1c9_4e220d9c88d3), pid: 13 };\npub const WPD_APPOINTMENT_LOCATION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf99efd03_431d_40d8_a1c9_4e220d9c88d3), pid: 3 };\npub const WPD_APPOINTMENT_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf99efd03_431d_40d8_a1c9_4e220d9c88d3);\npub const WPD_APPOINTMENT_OPTIONAL_ATTENDEES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf99efd03_431d_40d8_a1c9_4e220d9c88d3), pid: 9 };\npub const WPD_APPOINTMENT_REQUIRED_ATTENDEES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf99efd03_431d_40d8_a1c9_4e220d9c88d3), pid: 8 };\npub const WPD_APPOINTMENT_RESOURCES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf99efd03_431d_40d8_a1c9_4e220d9c88d3), pid: 11 };\npub const WPD_APPOINTMENT_TENTATIVE_ATTENDEES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf99efd03_431d_40d8_a1c9_4e220d9c88d3), pid: 12 };\npub const WPD_APPOINTMENT_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf99efd03_431d_40d8_a1c9_4e220d9c88d3), pid: 7 };\npub const WPD_AUDIO_BITRATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb324f56a_dc5d_46e5_b6df_d2ea414888c6), pid: 9 };\npub const WPD_AUDIO_BIT_DEPTH: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb324f56a_dc5d_46e5_b6df_d2ea414888c6), pid: 12 };\npub const WPD_AUDIO_BLOCK_ALIGNMENT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb324f56a_dc5d_46e5_b6df_d2ea414888c6), pid: 13 };\npub const WPD_AUDIO_CHANNEL_COUNT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb324f56a_dc5d_46e5_b6df_d2ea414888c6), pid: 10 };\npub const WPD_AUDIO_FORMAT_CODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb324f56a_dc5d_46e5_b6df_d2ea414888c6), pid: 11 };\npub type WPD_BITRATE_TYPES = i32;\npub const WPD_BITRATE_TYPE_DISCRETE: WPD_BITRATE_TYPES = 1i32;\npub const WPD_BITRATE_TYPE_FREE: WPD_BITRATE_TYPES = 3i32;\npub const WPD_BITRATE_TYPE_UNUSED: WPD_BITRATE_TYPES = 0i32;\npub const WPD_BITRATE_TYPE_VARIABLE: WPD_BITRATE_TYPES = 2i32;\npub type WPD_CAPTURE_MODES = i32;\npub const WPD_CAPTURE_MODE_BURST: WPD_CAPTURE_MODES = 2i32;\npub const WPD_CAPTURE_MODE_NORMAL: WPD_CAPTURE_MODES = 1i32;\npub const WPD_CAPTURE_MODE_TIMELAPSE: WPD_CAPTURE_MODES = 3i32;\npub const WPD_CAPTURE_MODE_UNDEFINED: WPD_CAPTURE_MODES = 0i32;\npub const WPD_CATEGORY_CAPABILITIES: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356);\npub const WPD_CATEGORY_COMMON: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a);\npub const WPD_CATEGORY_DEVICE_HINTS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0d5fb92b_cb46_4c4f_8343_0bc3d3f17c84);\npub const WPD_CATEGORY_MEDIA_CAPTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x59b433ba_fe44_4d8d_808c_6bcb9b0f15e8);\npub const WPD_CATEGORY_MTP_EXT_VENDOR_OPERATIONS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56);\npub const WPD_CATEGORY_NETWORK_CONFIGURATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x78f9c6fc_79b8_473c_9060_6bd23dd072c4);\npub const WPD_CATEGORY_NULL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000000_0000_0000_0000_000000000000);\npub const WPD_CATEGORY_OBJECT_ENUMERATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb7474e91_e7f8_4ad9_b400_ad1a4b58eeec);\npub const WPD_CATEGORY_OBJECT_MANAGEMENT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089);\npub const WPD_CATEGORY_OBJECT_PROPERTIES: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804);\npub const WPD_CATEGORY_OBJECT_PROPERTIES_BULK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e);\npub const WPD_CATEGORY_OBJECT_RESOURCES: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a);\npub const WPD_CATEGORY_SERVICE_CAPABILITIES: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89);\npub const WPD_CATEGORY_SERVICE_COMMON: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x322f071d_36ef_477f_b4b5_6f52d734baee);\npub const WPD_CATEGORY_SERVICE_METHODS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2d521ca8_c1b0_4268_a342_cf19321569bc);\npub const WPD_CATEGORY_SMS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xafc25d66_fe0d_4114_9097_970c93e920d1);\npub const WPD_CATEGORY_STILL_IMAGE_CAPTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4fcd6982_22a2_4b05_a48b_62d38bf27b32);\npub const WPD_CATEGORY_STORAGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd8f907a6_34cc_45fa_97fb_d007fa47ec94);\npub const WPD_CLASS_EXTENSION_OPTIONS_DEVICE_IDENTIFICATION_VALUES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x3e3595da_4d71_49fe_a0b4_d4406c3ae93f), pid: 3 };\npub const WPD_CLASS_EXTENSION_OPTIONS_DONT_REGISTER_WPD_DEVICE_INTERFACE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x6309ffef_a87c_4ca7_8434_797576e40a96), pid: 3 };\npub const WPD_CLASS_EXTENSION_OPTIONS_MULTITRANSPORT_MODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x3e3595da_4d71_49fe_a0b4_d4406c3ae93f), pid: 2 };\npub const WPD_CLASS_EXTENSION_OPTIONS_REGISTER_WPD_PRIVATE_DEVICE_INTERFACE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x6309ffef_a87c_4ca7_8434_797576e40a96), pid: 4 };\npub const WPD_CLASS_EXTENSION_OPTIONS_SILENCE_AUTOPLAY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x65c160f8_1367_4ce2_939d_8310839f0d30), pid: 2 };\npub const WPD_CLASS_EXTENSION_OPTIONS_SUPPORTED_CONTENT_TYPES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x6309ffef_a87c_4ca7_8434_797576e40a96), pid: 2 };\npub const WPD_CLASS_EXTENSION_OPTIONS_TRANSPORT_BANDWIDTH: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x3e3595da_4d71_49fe_a0b4_d4406c3ae93f), pid: 4 };\npub const WPD_CLASS_EXTENSION_OPTIONS_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6309ffef_a87c_4ca7_8434_797576e40a96);\npub const WPD_CLASS_EXTENSION_OPTIONS_V2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3e3595da_4d71_49fe_a0b4_d4406c3ae93f);\npub const WPD_CLASS_EXTENSION_OPTIONS_V3: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x65c160f8_1367_4ce2_939d_8310839f0d30);\npub const WPD_CLASS_EXTENSION_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x33fb0d11_64a3_4fac_b4c7_3dfeaa99b051);\npub const WPD_CLASS_EXTENSION_V2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7f0779b5_fa2b_4766_9cb2_f73ba30b6758);\npub const WPD_CLIENT_DESIRED_ACCESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 9 };\npub const WPD_CLIENT_EVENT_COOKIE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 11 };\npub const WPD_CLIENT_INFORMATION_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859);\npub const WPD_CLIENT_MAJOR_VERSION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 3 };\npub const WPD_CLIENT_MANUAL_CLOSE_ON_DISCONNECT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 13 };\npub const WPD_CLIENT_MINIMUM_RESULTS_BUFFER_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 12 };\npub const WPD_CLIENT_MINOR_VERSION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 4 };\npub const WPD_CLIENT_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 2 };\npub const WPD_CLIENT_REVISION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 5 };\npub const WPD_CLIENT_SECURITY_QUALITY_OF_SERVICE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 8 };\npub const WPD_CLIENT_SHARE_MODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 10 };\npub const WPD_CLIENT_WMDRM_APPLICATION_CERTIFICATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 7 };\npub const WPD_CLIENT_WMDRM_APPLICATION_PRIVATE_KEY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x204d9f0c_2292_4080_9f42_40664e70f859), pid: 6 };\npub const WPD_COLOR_CORRECTED_STATUS_CORRECTED: WPD_COLOR_CORRECTED_STATUS_VALUES = 1i32;\npub const WPD_COLOR_CORRECTED_STATUS_NOT_CORRECTED: WPD_COLOR_CORRECTED_STATUS_VALUES = 0i32;\npub const WPD_COLOR_CORRECTED_STATUS_SHOULD_NOT_BE_CORRECTED: WPD_COLOR_CORRECTED_STATUS_VALUES = 2i32;\npub type WPD_COLOR_CORRECTED_STATUS_VALUES = i32;\npub const WPD_COMMAND_ACCESS_FROM_ATTRIBUTE_WITH_METHOD_ACCESS: WPD_COMMAND_ACCESS_TYPES = 16i32;\npub const WPD_COMMAND_ACCESS_FROM_PROPERTY_WITH_FILE_ACCESS: WPD_COMMAND_ACCESS_TYPES = 8i32;\npub const WPD_COMMAND_ACCESS_FROM_PROPERTY_WITH_STGM_ACCESS: WPD_COMMAND_ACCESS_TYPES = 4i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WPD_COMMAND_ACCESS_LOOKUP_ENTRY {\n    pub Command: super::super::Foundation::PROPERTYKEY,\n    pub AccessType: u32,\n    pub AccessProperty: super::super::Foundation::PROPERTYKEY,\n}\npub const WPD_COMMAND_ACCESS_READ: WPD_COMMAND_ACCESS_TYPES = 1i32;\npub const WPD_COMMAND_ACCESS_READWRITE: WPD_COMMAND_ACCESS_TYPES = 3i32;\npub type WPD_COMMAND_ACCESS_TYPES = i32;\npub const WPD_COMMAND_CAPABILITIES_GET_COMMAND_OPTIONS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 3 };\npub const WPD_COMMAND_CAPABILITIES_GET_EVENT_OPTIONS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 11 };\npub const WPD_COMMAND_CAPABILITIES_GET_FIXED_PROPERTY_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 9 };\npub const WPD_COMMAND_CAPABILITIES_GET_FUNCTIONAL_OBJECTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 5 };\npub const WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_COMMANDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 2 };\npub const WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_CONTENT_TYPES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 6 };\npub const WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_EVENTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 10 };\npub const WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_FORMATS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 7 };\npub const WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_FORMAT_PROPERTIES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 8 };\npub const WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_FUNCTIONAL_CATEGORIES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 4 };\npub const WPD_COMMAND_CLASS_EXTENSION_REGISTER_SERVICE_INTERFACES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7f0779b5_fa2b_4766_9cb2_f73ba30b6758), pid: 2 };\npub const WPD_COMMAND_CLASS_EXTENSION_UNREGISTER_SERVICE_INTERFACES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7f0779b5_fa2b_4766_9cb2_f73ba30b6758), pid: 3 };\npub const WPD_COMMAND_CLASS_EXTENSION_WRITE_DEVICE_INFORMATION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x33fb0d11_64a3_4fac_b4c7_3dfeaa99b051), pid: 2 };\npub const WPD_COMMAND_COMMIT_KEYPAIR: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x78f9c6fc_79b8_473c_9060_6bd23dd072c4), pid: 3 };\npub const WPD_COMMAND_COMMON_GET_OBJECT_IDS_FROM_PERSISTENT_UNIQUE_IDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 3 };\npub const WPD_COMMAND_COMMON_RESET_DEVICE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 2 };\npub const WPD_COMMAND_COMMON_SAVE_CLIENT_INFORMATION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 4 };\npub const WPD_COMMAND_DEVICE_HINTS_GET_CONTENT_LOCATION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0d5fb92b_cb46_4c4f_8343_0bc3d3f17c84), pid: 2 };\npub const WPD_COMMAND_GENERATE_KEYPAIR: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x78f9c6fc_79b8_473c_9060_6bd23dd072c4), pid: 2 };\npub const WPD_COMMAND_MEDIA_CAPTURE_PAUSE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x59b433ba_fe44_4d8d_808c_6bcb9b0f15e8), pid: 4 };\npub const WPD_COMMAND_MEDIA_CAPTURE_START: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x59b433ba_fe44_4d8d_808c_6bcb9b0f15e8), pid: 2 };\npub const WPD_COMMAND_MEDIA_CAPTURE_STOP: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x59b433ba_fe44_4d8d_808c_6bcb9b0f15e8), pid: 3 };\npub const WPD_COMMAND_MTP_EXT_END_DATA_TRANSFER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 17 };\npub const WPD_COMMAND_MTP_EXT_EXECUTE_COMMAND_WITHOUT_DATA_PHASE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 12 };\npub const WPD_COMMAND_MTP_EXT_EXECUTE_COMMAND_WITH_DATA_TO_READ: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 13 };\npub const WPD_COMMAND_MTP_EXT_EXECUTE_COMMAND_WITH_DATA_TO_WRITE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 14 };\npub const WPD_COMMAND_MTP_EXT_GET_SUPPORTED_VENDOR_OPCODES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 11 };\npub const WPD_COMMAND_MTP_EXT_GET_VENDOR_EXTENSION_DESCRIPTION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 18 };\npub const WPD_COMMAND_MTP_EXT_READ_DATA: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 15 };\npub const WPD_COMMAND_MTP_EXT_WRITE_DATA: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 16 };\npub const WPD_COMMAND_OBJECT_ENUMERATION_END_FIND: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb7474e91_e7f8_4ad9_b400_ad1a4b58eeec), pid: 4 };\npub const WPD_COMMAND_OBJECT_ENUMERATION_FIND_NEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb7474e91_e7f8_4ad9_b400_ad1a4b58eeec), pid: 3 };\npub const WPD_COMMAND_OBJECT_ENUMERATION_START_FIND: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb7474e91_e7f8_4ad9_b400_ad1a4b58eeec), pid: 2 };\npub const WPD_COMMAND_OBJECT_MANAGEMENT_COMMIT_OBJECT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 5 };\npub const WPD_COMMAND_OBJECT_MANAGEMENT_COPY_OBJECTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 9 };\npub const WPD_COMMAND_OBJECT_MANAGEMENT_CREATE_OBJECT_WITH_PROPERTIES_AND_DATA: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 3 };\npub const WPD_COMMAND_OBJECT_MANAGEMENT_CREATE_OBJECT_WITH_PROPERTIES_ONLY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 2 };\npub const WPD_COMMAND_OBJECT_MANAGEMENT_DELETE_OBJECTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 7 };\npub const WPD_COMMAND_OBJECT_MANAGEMENT_MOVE_OBJECTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 8 };\npub const WPD_COMMAND_OBJECT_MANAGEMENT_REVERT_OBJECT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 6 };\npub const WPD_COMMAND_OBJECT_MANAGEMENT_UPDATE_OBJECT_WITH_PROPERTIES_AND_DATA: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 10 };\npub const WPD_COMMAND_OBJECT_MANAGEMENT_WRITE_OBJECT_DATA: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 4 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_END: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 7 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_NEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 6 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_START: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 5 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_LIST_END: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 4 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_LIST_NEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 3 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_LIST_START: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 2 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_END: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 10 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_NEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 9 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_START: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 8 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_DELETE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 7 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_GET: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 4 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_GET_ALL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 6 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_GET_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 3 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_GET_SUPPORTED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 2 };\npub const WPD_COMMAND_OBJECT_PROPERTIES_SET: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 5 };\npub const WPD_COMMAND_OBJECT_RESOURCES_CLOSE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 7 };\npub const WPD_COMMAND_OBJECT_RESOURCES_COMMIT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 12 };\npub const WPD_COMMAND_OBJECT_RESOURCES_CREATE_RESOURCE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 9 };\npub const WPD_COMMAND_OBJECT_RESOURCES_DELETE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 8 };\npub const WPD_COMMAND_OBJECT_RESOURCES_GET_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 3 };\npub const WPD_COMMAND_OBJECT_RESOURCES_GET_SUPPORTED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 2 };\npub const WPD_COMMAND_OBJECT_RESOURCES_OPEN: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 4 };\npub const WPD_COMMAND_OBJECT_RESOURCES_READ: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 5 };\npub const WPD_COMMAND_OBJECT_RESOURCES_REVERT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 10 };\npub const WPD_COMMAND_OBJECT_RESOURCES_SEEK: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 11 };\npub const WPD_COMMAND_OBJECT_RESOURCES_SEEK_IN_UNITS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 13 };\npub const WPD_COMMAND_OBJECT_RESOURCES_WRITE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 6 };\npub const WPD_COMMAND_PROCESS_WIRELESS_PROFILE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x78f9c6fc_79b8_473c_9060_6bd23dd072c4), pid: 4 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_COMMAND_OPTIONS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 16 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_EVENT_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 11 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_EVENT_PARAMETER_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 12 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_FORMAT_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 7 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_FORMAT_PROPERTY_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 9 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_FORMAT_RENDERING_PROFILES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 14 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_INHERITED_SERVICES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 13 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_METHOD_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 4 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_METHOD_PARAMETER_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 5 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_COMMANDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 15 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_EVENTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 10 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_FORMATS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 6 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_FORMAT_PROPERTIES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 8 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_METHODS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 2 };\npub const WPD_COMMAND_SERVICE_CAPABILITIES_GET_SUPPORTED_METHODS_BY_FORMAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 3 };\npub const WPD_COMMAND_SERVICE_COMMON_GET_SERVICE_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x322f071d_36ef_477f_b4b5_6f52d734baee), pid: 2 };\npub const WPD_COMMAND_SERVICE_METHODS_CANCEL_INVOKE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2d521ca8_c1b0_4268_a342_cf19321569bc), pid: 3 };\npub const WPD_COMMAND_SERVICE_METHODS_END_INVOKE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2d521ca8_c1b0_4268_a342_cf19321569bc), pid: 4 };\npub const WPD_COMMAND_SERVICE_METHODS_START_INVOKE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2d521ca8_c1b0_4268_a342_cf19321569bc), pid: 2 };\npub const WPD_COMMAND_SMS_SEND: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xafc25d66_fe0d_4114_9097_970c93e920d1), pid: 2 };\npub const WPD_COMMAND_STILL_IMAGE_CAPTURE_INITIATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4fcd6982_22a2_4b05_a48b_62d38bf27b32), pid: 2 };\npub const WPD_COMMAND_STORAGE_EJECT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xd8f907a6_34cc_45fa_97fb_d007fa47ec94), pid: 4 };\npub const WPD_COMMAND_STORAGE_FORMAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xd8f907a6_34cc_45fa_97fb_d007fa47ec94), pid: 2 };\npub const WPD_COMMON_INFORMATION_BODY_TEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb28ae94b_05a4_4e8e_be01_72cc7e099d8f), pid: 3 };\npub const WPD_COMMON_INFORMATION_END_DATETIME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb28ae94b_05a4_4e8e_be01_72cc7e099d8f), pid: 6 };\npub const WPD_COMMON_INFORMATION_NOTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb28ae94b_05a4_4e8e_be01_72cc7e099d8f), pid: 7 };\npub const WPD_COMMON_INFORMATION_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb28ae94b_05a4_4e8e_be01_72cc7e099d8f);\npub const WPD_COMMON_INFORMATION_PRIORITY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb28ae94b_05a4_4e8e_be01_72cc7e099d8f), pid: 4 };\npub const WPD_COMMON_INFORMATION_START_DATETIME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb28ae94b_05a4_4e8e_be01_72cc7e099d8f), pid: 5 };\npub const WPD_COMMON_INFORMATION_SUBJECT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb28ae94b_05a4_4e8e_be01_72cc7e099d8f), pid: 2 };\npub const WPD_CONTACT_ANNIVERSARY_DATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 62 };\npub const WPD_CONTACT_ASSISTANT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 61 };\npub const WPD_CONTACT_BIRTHDATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 57 };\npub const WPD_CONTACT_BUSINESS_EMAIL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 34 };\npub const WPD_CONTACT_BUSINESS_EMAIL2: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 35 };\npub const WPD_CONTACT_BUSINESS_FAX: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 45 };\npub const WPD_CONTACT_BUSINESS_FULL_POSTAL_ADDRESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 17 };\npub const WPD_CONTACT_BUSINESS_PHONE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 40 };\npub const WPD_CONTACT_BUSINESS_PHONE2: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 41 };\npub const WPD_CONTACT_BUSINESS_POSTAL_ADDRESS_CITY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 20 };\npub const WPD_CONTACT_BUSINESS_POSTAL_ADDRESS_COUNTRY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 23 };\npub const WPD_CONTACT_BUSINESS_POSTAL_ADDRESS_LINE1: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 18 };\npub const WPD_CONTACT_BUSINESS_POSTAL_ADDRESS_LINE2: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 19 };\npub const WPD_CONTACT_BUSINESS_POSTAL_ADDRESS_POSTAL_CODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 22 };\npub const WPD_CONTACT_BUSINESS_POSTAL_ADDRESS_REGION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 21 };\npub const WPD_CONTACT_BUSINESS_WEB_ADDRESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 50 };\npub const WPD_CONTACT_CHILDREN: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 60 };\npub const WPD_CONTACT_COMPANY_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 54 };\npub const WPD_CONTACT_DISPLAY_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 2 };\npub const WPD_CONTACT_FIRST_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 3 };\npub const WPD_CONTACT_INSTANT_MESSENGER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 51 };\npub const WPD_CONTACT_INSTANT_MESSENGER2: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 52 };\npub const WPD_CONTACT_INSTANT_MESSENGER3: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 53 };\npub const WPD_CONTACT_LAST_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 5 };\npub const WPD_CONTACT_MIDDLE_NAMES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 4 };\npub const WPD_CONTACT_MOBILE_PHONE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 42 };\npub const WPD_CONTACT_MOBILE_PHONE2: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 43 };\npub const WPD_CONTACT_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b);\npub const WPD_CONTACT_OTHER_EMAILS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 36 };\npub const WPD_CONTACT_OTHER_FULL_POSTAL_ADDRESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 24 };\npub const WPD_CONTACT_OTHER_PHONES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 47 };\npub const WPD_CONTACT_OTHER_POSTAL_ADDRESS_CITY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 27 };\npub const WPD_CONTACT_OTHER_POSTAL_ADDRESS_LINE1: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 25 };\npub const WPD_CONTACT_OTHER_POSTAL_ADDRESS_LINE2: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 26 };\npub const WPD_CONTACT_OTHER_POSTAL_ADDRESS_POSTAL_CODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 29 };\npub const WPD_CONTACT_OTHER_POSTAL_ADDRESS_POSTAL_COUNTRY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 30 };\npub const WPD_CONTACT_OTHER_POSTAL_ADDRESS_REGION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 28 };\npub const WPD_CONTACT_PAGER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 46 };\npub const WPD_CONTACT_PERSONAL_EMAIL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 32 };\npub const WPD_CONTACT_PERSONAL_EMAIL2: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 33 };\npub const WPD_CONTACT_PERSONAL_FAX: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 44 };\npub const WPD_CONTACT_PERSONAL_FULL_POSTAL_ADDRESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 10 };\npub const WPD_CONTACT_PERSONAL_PHONE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 38 };\npub const WPD_CONTACT_PERSONAL_PHONE2: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 39 };\npub const WPD_CONTACT_PERSONAL_POSTAL_ADDRESS_CITY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 13 };\npub const WPD_CONTACT_PERSONAL_POSTAL_ADDRESS_COUNTRY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 16 };\npub const WPD_CONTACT_PERSONAL_POSTAL_ADDRESS_LINE1: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 11 };\npub const WPD_CONTACT_PERSONAL_POSTAL_ADDRESS_LINE2: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 12 };\npub const WPD_CONTACT_PERSONAL_POSTAL_ADDRESS_POSTAL_CODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 15 };\npub const WPD_CONTACT_PERSONAL_POSTAL_ADDRESS_REGION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 14 };\npub const WPD_CONTACT_PERSONAL_WEB_ADDRESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 49 };\npub const WPD_CONTACT_PHONETIC_COMPANY_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 55 };\npub const WPD_CONTACT_PHONETIC_FIRST_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 8 };\npub const WPD_CONTACT_PHONETIC_LAST_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 9 };\npub const WPD_CONTACT_PREFIX: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 6 };\npub const WPD_CONTACT_PRIMARY_EMAIL_ADDRESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 31 };\npub const WPD_CONTACT_PRIMARY_FAX: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 58 };\npub const WPD_CONTACT_PRIMARY_PHONE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 37 };\npub const WPD_CONTACT_PRIMARY_WEB_ADDRESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 48 };\npub const WPD_CONTACT_RINGTONE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 63 };\npub const WPD_CONTACT_ROLE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 56 };\npub const WPD_CONTACT_SPOUSE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 59 };\npub const WPD_CONTACT_SUFFIX: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xfbd4fdab_987d_4777_b3f9_726185a9312b), pid: 7 };\npub const WPD_CONTENT_TYPE_ALL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x80e170d2_1055_4a3e_b952_82cc4f8a8689);\npub const WPD_CONTENT_TYPE_APPOINTMENT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0fed060e_8793_4b1e_90c9_48ac389ac631);\npub const WPD_CONTENT_TYPE_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4ad2c85e_5e2d_45e5_8864_4f229e3c6cf0);\npub const WPD_CONTENT_TYPE_AUDIO_ALBUM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xaa18737e_5009_48fa_ae21_85f24383b4e6);\npub const WPD_CONTENT_TYPE_CALENDAR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa1fd5967_6023_49a0_9df1_f8060be751b0);\npub const WPD_CONTENT_TYPE_CERTIFICATE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdc3876e8_a948_4060_9050_cbd77e8a3d87);\npub const WPD_CONTENT_TYPE_CONTACT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xeaba8313_4525_4707_9f0e_87c6808e9435);\npub const WPD_CONTENT_TYPE_CONTACT_GROUP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x346b8932_4c36_40d8_9415_1828291f9de9);\npub const WPD_CONTENT_TYPE_DOCUMENT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x680adf52_950a_4041_9b41_65e393648155);\npub const WPD_CONTENT_TYPE_EMAIL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8038044a_7e51_4f8f_883d_1d0623d14533);\npub const WPD_CONTENT_TYPE_FOLDER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x27e2e392_a111_48e0_ab0c_e17705a05f85);\npub const WPD_CONTENT_TYPE_FUNCTIONAL_OBJECT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x99ed0160_17ff_4c44_9d98_1d7a6f941921);\npub const WPD_CONTENT_TYPE_GENERIC_FILE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0085e0a6_8d34_45d7_bc5c_447e59c73d48);\npub const WPD_CONTENT_TYPE_GENERIC_MESSAGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe80eaaf8_b2db_4133_b67e_1bef4b4a6e5f);\npub const WPD_CONTENT_TYPE_IMAGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xef2107d5_a52a_4243_a26b_62d4176d7603);\npub const WPD_CONTENT_TYPE_IMAGE_ALBUM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x75793148_15f5_4a30_a813_54ed8a37e226);\npub const WPD_CONTENT_TYPE_MEDIA_CAST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x5e88b3cc_3e65_4e62_bfff_229495253ab0);\npub const WPD_CONTENT_TYPE_MEMO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9cd20ecf_3b50_414f_a641_e473ffe45751);\npub const WPD_CONTENT_TYPE_MIXED_CONTENT_ALBUM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00f0c3ac_a593_49ac_9219_24abca5a2563);\npub const WPD_CONTENT_TYPE_NETWORK_ASSOCIATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x031da7ee_18c8_4205_847e_89a11261d0f3);\npub const WPD_CONTENT_TYPE_PLAYLIST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1a33f7e4_af13_48f5_994e_77369dfe04a3);\npub const WPD_CONTENT_TYPE_PROGRAM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd269f96a_247c_4bff_98fb_97f3c49220e6);\npub const WPD_CONTENT_TYPE_SECTION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x821089f5_1d91_4dc9_be3c_bbb1b35b18ce);\npub const WPD_CONTENT_TYPE_TASK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x63252f2c_887f_4cb6_b1ac_d29855dcef6c);\npub const WPD_CONTENT_TYPE_TELEVISION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x60a169cf_f2ae_4e21_9375_9677f11c1c6e);\npub const WPD_CONTENT_TYPE_UNSPECIFIED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x28d8d31e_249c_454e_aabc_34883168e634);\npub const WPD_CONTENT_TYPE_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9261b03c_3d78_4519_85e3_02c5e1f50bb9);\npub const WPD_CONTENT_TYPE_VIDEO_ALBUM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x012b0db7_d4c1_45d6_b081_94b87779614f);\npub const WPD_CONTENT_TYPE_WIRELESS_PROFILE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0bac070a_9f5f_4da4_a8f6_3de44d68fd6c);\npub const WPD_CONTROL_FUNCTION_GENERIC_MESSAGE: u32 = 66u32;\npub const WPD_CROPPED_STATUS_CROPPED: WPD_CROPPED_STATUS_VALUES = 1i32;\npub const WPD_CROPPED_STATUS_NOT_CROPPED: WPD_CROPPED_STATUS_VALUES = 0i32;\npub const WPD_CROPPED_STATUS_SHOULD_NOT_BE_CROPPED: WPD_CROPPED_STATUS_VALUES = 2i32;\npub type WPD_CROPPED_STATUS_VALUES = i32;\npub const WPD_DEVICE_DATETIME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 11 };\npub const WPD_DEVICE_EDP_IDENTITY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x6c2b878c_c2ec_490d_b425_d7a75e23e5ed), pid: 1 };\npub const WPD_DEVICE_FIRMWARE_VERSION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 3 };\npub const WPD_DEVICE_FRIENDLY_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 12 };\npub const WPD_DEVICE_FUNCTIONAL_UNIQUE_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x463dd662_7fc4_4291_911c_7f4c9cca9799), pid: 2 };\npub const WPD_DEVICE_MANUFACTURER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 7 };\npub const WPD_DEVICE_MODEL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 8 };\npub const WPD_DEVICE_MODEL_UNIQUE_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x463dd662_7fc4_4291_911c_7f4c9cca9799), pid: 3 };\npub const WPD_DEVICE_NETWORK_IDENTIFIER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 16 };\npub const WPD_DEVICE_OBJECT_ID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DEVICE\");\npub const WPD_DEVICE_POWER_LEVEL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 4 };\npub const WPD_DEVICE_POWER_SOURCE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 5 };\npub const WPD_DEVICE_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc);\npub const WPD_DEVICE_PROPERTIES_V2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x463dd662_7fc4_4291_911c_7f4c9cca9799);\npub const WPD_DEVICE_PROPERTIES_V3: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6c2b878c_c2ec_490d_b425_d7a75e23e5ed);\npub const WPD_DEVICE_PROTOCOL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 6 };\npub const WPD_DEVICE_SERIAL_NUMBER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 9 };\npub const WPD_DEVICE_SUPPORTED_DRM_SCHEMES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 13 };\npub const WPD_DEVICE_SUPPORTED_FORMATS_ARE_ORDERED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 14 };\npub const WPD_DEVICE_SUPPORTS_NON_CONSUMABLE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 10 };\npub const WPD_DEVICE_SYNC_PARTNER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 2 };\npub const WPD_DEVICE_TRANSPORT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x463dd662_7fc4_4291_911c_7f4c9cca9799), pid: 4 };\npub type WPD_DEVICE_TRANSPORTS = i32;\npub const WPD_DEVICE_TRANSPORT_BLUETOOTH: WPD_DEVICE_TRANSPORTS = 3i32;\npub const WPD_DEVICE_TRANSPORT_IP: WPD_DEVICE_TRANSPORTS = 2i32;\npub const WPD_DEVICE_TRANSPORT_UNSPECIFIED: WPD_DEVICE_TRANSPORTS = 0i32;\npub const WPD_DEVICE_TRANSPORT_USB: WPD_DEVICE_TRANSPORTS = 1i32;\npub const WPD_DEVICE_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x26d4979a_e643_4626_9e2b_736dc0c92fdc), pid: 15 };\npub type WPD_DEVICE_TYPES = i32;\npub const WPD_DEVICE_TYPE_AUDIO_RECORDER: WPD_DEVICE_TYPES = 6i32;\npub const WPD_DEVICE_TYPE_CAMERA: WPD_DEVICE_TYPES = 1i32;\npub const WPD_DEVICE_TYPE_GENERIC: WPD_DEVICE_TYPES = 0i32;\npub const WPD_DEVICE_TYPE_MEDIA_PLAYER: WPD_DEVICE_TYPES = 2i32;\npub const WPD_DEVICE_TYPE_PERSONAL_INFORMATION_MANAGER: WPD_DEVICE_TYPES = 5i32;\npub const WPD_DEVICE_TYPE_PHONE: WPD_DEVICE_TYPES = 3i32;\npub const WPD_DEVICE_TYPE_VIDEO: WPD_DEVICE_TYPES = 4i32;\npub const WPD_DEVICE_USE_DEVICE_STAGE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x463dd662_7fc4_4291_911c_7f4c9cca9799), pid: 5 };\npub const WPD_DOCUMENT_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0b110203_eb95_4f02_93e0_97c631493ad5);\npub type WPD_EFFECT_MODES = i32;\npub const WPD_EFFECT_MODE_BLACK_AND_WHITE: WPD_EFFECT_MODES = 2i32;\npub const WPD_EFFECT_MODE_COLOR: WPD_EFFECT_MODES = 1i32;\npub const WPD_EFFECT_MODE_SEPIA: WPD_EFFECT_MODES = 3i32;\npub const WPD_EFFECT_MODE_UNDEFINED: WPD_EFFECT_MODES = 0i32;\npub const WPD_EMAIL_BCC_LINE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x41f8f65a_5484_4782_b13d_4740dd7c37c5), pid: 4 };\npub const WPD_EMAIL_CC_LINE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x41f8f65a_5484_4782_b13d_4740dd7c37c5), pid: 3 };\npub const WPD_EMAIL_HAS_ATTACHMENTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x41f8f65a_5484_4782_b13d_4740dd7c37c5), pid: 9 };\npub const WPD_EMAIL_HAS_BEEN_READ: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x41f8f65a_5484_4782_b13d_4740dd7c37c5), pid: 7 };\npub const WPD_EMAIL_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x41f8f65a_5484_4782_b13d_4740dd7c37c5);\npub const WPD_EMAIL_RECEIVED_TIME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x41f8f65a_5484_4782_b13d_4740dd7c37c5), pid: 8 };\npub const WPD_EMAIL_SENDER_ADDRESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x41f8f65a_5484_4782_b13d_4740dd7c37c5), pid: 10 };\npub const WPD_EMAIL_TO_LINE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x41f8f65a_5484_4782_b13d_4740dd7c37c5), pid: 2 };\npub const WPD_EVENT_ATTRIBUTES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x10c96578_2e81_4111_adde_e08ca6138f6d);\npub const WPD_EVENT_ATTRIBUTE_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x10c96578_2e81_4111_adde_e08ca6138f6d), pid: 2 };\npub const WPD_EVENT_ATTRIBUTE_OPTIONS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x10c96578_2e81_4111_adde_e08ca6138f6d), pid: 4 };\npub const WPD_EVENT_ATTRIBUTE_PARAMETERS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x10c96578_2e81_4111_adde_e08ca6138f6d), pid: 3 };\npub const WPD_EVENT_DEVICE_CAPABILITIES_UPDATED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36885aa1_cd54_4daa_b3d0_afb3e03f5999);\npub const WPD_EVENT_DEVICE_REMOVED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe4cbca1b_6918_48b9_85ee_02be7c850af9);\npub const WPD_EVENT_DEVICE_RESET: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7755cf53_c1ed_44f3_b5a2_451e2c376b27);\npub const WPD_EVENT_MTP_VENDOR_EXTENDED_EVENTS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000000_5738_4ff2_8445_be3126691059);\npub const WPD_EVENT_NOTIFICATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2ba2e40a_6b4c_4295_bb43_26322b99aeb2);\npub const WPD_EVENT_OBJECT_ADDED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa726da95_e207_4b02_8d44_bef2e86cbffc);\npub const WPD_EVENT_OBJECT_REMOVED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbe82ab88_a52c_4823_96e5_d0272671fc38);\npub const WPD_EVENT_OBJECT_TRANSFER_REQUESTED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8d16a0a1_f2c6_41da_8f19_5e53721adbf2);\npub const WPD_EVENT_OBJECT_UPDATED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1445a759_2e01_485d_9f27_ff07dae697ab);\npub const WPD_EVENT_OPTIONS_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb3d8dad7_a361_4b83_8a48_5b02ce10713b);\npub const WPD_EVENT_OPTION_IS_AUTOPLAY_EVENT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3d8dad7_a361_4b83_8a48_5b02ce10713b), pid: 3 };\npub const WPD_EVENT_OPTION_IS_BROADCAST_EVENT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3d8dad7_a361_4b83_8a48_5b02ce10713b), pid: 2 };\npub const WPD_EVENT_PARAMETER_CHILD_HIERARCHY_CHANGED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x15ab1953_f817_4fef_a921_5676e838f6e0), pid: 8 };\npub const WPD_EVENT_PARAMETER_EVENT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x15ab1953_f817_4fef_a921_5676e838f6e0), pid: 3 };\npub const WPD_EVENT_PARAMETER_OBJECT_CREATION_COOKIE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x15ab1953_f817_4fef_a921_5676e838f6e0), pid: 7 };\npub const WPD_EVENT_PARAMETER_OBJECT_PARENT_PERSISTENT_UNIQUE_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x15ab1953_f817_4fef_a921_5676e838f6e0), pid: 6 };\npub const WPD_EVENT_PARAMETER_OPERATION_PROGRESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x15ab1953_f817_4fef_a921_5676e838f6e0), pid: 5 };\npub const WPD_EVENT_PARAMETER_OPERATION_STATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x15ab1953_f817_4fef_a921_5676e838f6e0), pid: 4 };\npub const WPD_EVENT_PARAMETER_PNP_DEVICE_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x15ab1953_f817_4fef_a921_5676e838f6e0), pid: 2 };\npub const WPD_EVENT_PARAMETER_SERVICE_METHOD_CONTEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x52807b8a_4914_4323_9b9a_74f654b2b846), pid: 2 };\npub const WPD_EVENT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x15ab1953_f817_4fef_a921_5676e838f6e0);\npub const WPD_EVENT_PROPERTIES_V2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x52807b8a_4914_4323_9b9a_74f654b2b846);\npub const WPD_EVENT_SERVICE_METHOD_COMPLETE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8a33f5f8_0acc_4d9b_9cc4_112d353b86ca);\npub const WPD_EVENT_STORAGE_FORMAT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3782616b_22bc_4474_a251_3070f8d38857);\npub type WPD_EXPOSURE_METERING_MODES = i32;\npub const WPD_EXPOSURE_METERING_MODE_AVERAGE: WPD_EXPOSURE_METERING_MODES = 1i32;\npub const WPD_EXPOSURE_METERING_MODE_CENTER_SPOT: WPD_EXPOSURE_METERING_MODES = 4i32;\npub const WPD_EXPOSURE_METERING_MODE_CENTER_WEIGHTED_AVERAGE: WPD_EXPOSURE_METERING_MODES = 2i32;\npub const WPD_EXPOSURE_METERING_MODE_MULTI_SPOT: WPD_EXPOSURE_METERING_MODES = 3i32;\npub const WPD_EXPOSURE_METERING_MODE_UNDEFINED: WPD_EXPOSURE_METERING_MODES = 0i32;\npub type WPD_EXPOSURE_PROGRAM_MODES = i32;\npub const WPD_EXPOSURE_PROGRAM_MODE_ACTION: WPD_EXPOSURE_PROGRAM_MODES = 6i32;\npub const WPD_EXPOSURE_PROGRAM_MODE_APERTURE_PRIORITY: WPD_EXPOSURE_PROGRAM_MODES = 3i32;\npub const WPD_EXPOSURE_PROGRAM_MODE_AUTO: WPD_EXPOSURE_PROGRAM_MODES = 2i32;\npub const WPD_EXPOSURE_PROGRAM_MODE_CREATIVE: WPD_EXPOSURE_PROGRAM_MODES = 5i32;\npub const WPD_EXPOSURE_PROGRAM_MODE_MANUAL: WPD_EXPOSURE_PROGRAM_MODES = 1i32;\npub const WPD_EXPOSURE_PROGRAM_MODE_PORTRAIT: WPD_EXPOSURE_PROGRAM_MODES = 7i32;\npub const WPD_EXPOSURE_PROGRAM_MODE_SHUTTER_PRIORITY: WPD_EXPOSURE_PROGRAM_MODES = 4i32;\npub const WPD_EXPOSURE_PROGRAM_MODE_UNDEFINED: WPD_EXPOSURE_PROGRAM_MODES = 0i32;\npub type WPD_FLASH_MODES = i32;\npub const WPD_FLASH_MODE_AUTO: WPD_FLASH_MODES = 1i32;\npub const WPD_FLASH_MODE_EXTERNAL_SYNC: WPD_FLASH_MODES = 6i32;\npub const WPD_FLASH_MODE_FILL: WPD_FLASH_MODES = 3i32;\npub const WPD_FLASH_MODE_OFF: WPD_FLASH_MODES = 2i32;\npub const WPD_FLASH_MODE_RED_EYE_AUTO: WPD_FLASH_MODES = 4i32;\npub const WPD_FLASH_MODE_RED_EYE_FILL: WPD_FLASH_MODES = 5i32;\npub const WPD_FLASH_MODE_UNDEFINED: WPD_FLASH_MODES = 0i32;\npub const WPD_FOCUS_AUTOMATIC: WPD_FOCUS_MODES = 2i32;\npub const WPD_FOCUS_AUTOMATIC_MACRO: WPD_FOCUS_MODES = 3i32;\npub const WPD_FOCUS_MANUAL: WPD_FOCUS_MODES = 1i32;\npub type WPD_FOCUS_METERING_MODES = i32;\npub const WPD_FOCUS_METERING_MODE_CENTER_SPOT: WPD_FOCUS_METERING_MODES = 1i32;\npub const WPD_FOCUS_METERING_MODE_MULTI_SPOT: WPD_FOCUS_METERING_MODES = 2i32;\npub const WPD_FOCUS_METERING_MODE_UNDEFINED: WPD_FOCUS_METERING_MODES = 0i32;\npub type WPD_FOCUS_MODES = i32;\npub const WPD_FOCUS_UNDEFINED: WPD_FOCUS_MODES = 0i32;\npub const WPD_FOLDER_CONTENT_TYPES_ALLOWED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7e9a7abf_e568_4b34_aa2f_13bb12ab177d), pid: 2 };\npub const WPD_FOLDER_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7e9a7abf_e568_4b34_aa2f_13bb12ab177d);\npub const WPD_FORMAT_ATTRIBUTES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa0a02000_bcaf_4be8_b3f5_233f231cf58f);\npub const WPD_FORMAT_ATTRIBUTE_MIMETYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xa0a02000_bcaf_4be8_b3f5_233f231cf58f), pid: 3 };\npub const WPD_FORMAT_ATTRIBUTE_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xa0a02000_bcaf_4be8_b3f5_233f231cf58f), pid: 2 };\npub const WPD_FUNCTIONAL_CATEGORY_ALL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2d8a6512_a74c_448e_ba8a_f4ac07c49399);\npub const WPD_FUNCTIONAL_CATEGORY_AUDIO_CAPTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3f2a1919_c7c2_4a00_855d_f57cf06debbb);\npub const WPD_FUNCTIONAL_CATEGORY_DEVICE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x08ea466b_e3a4_4336_a1f3_a44d2b5c438c);\npub const WPD_FUNCTIONAL_CATEGORY_NETWORK_CONFIGURATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x48f4db72_7c6a_4ab0_9e1a_470e3cdbf26a);\npub const WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x08600ba4_a7ba_4a01_ab0e_0065d0a356d3);\npub const WPD_FUNCTIONAL_CATEGORY_SMS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0044a0b1_c1e9_4afd_b358_a62c6117c9cf);\npub const WPD_FUNCTIONAL_CATEGORY_STILL_IMAGE_CAPTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x613ca327_ab93_4900_b4fa_895bb5874b79);\npub const WPD_FUNCTIONAL_CATEGORY_STORAGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x23f05bbc_15de_4c2a_a55b_a9af5ce412ef);\npub const WPD_FUNCTIONAL_CATEGORY_VIDEO_CAPTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe23e5f6b_7243_43aa_8df1_0eb3d968a918);\npub const WPD_FUNCTIONAL_OBJECT_CATEGORY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x8f052d93_abca_4fc5_a5ac_b01df4dbe598), pid: 2 };\npub const WPD_FUNCTIONAL_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8f052d93_abca_4fc5_a5ac_b01df4dbe598);\npub const WPD_IMAGE_BITDEPTH: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x63d64908_9fa1_479f_85ba_9952216447db), pid: 3 };\npub const WPD_IMAGE_COLOR_CORRECTED_STATUS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x63d64908_9fa1_479f_85ba_9952216447db), pid: 5 };\npub const WPD_IMAGE_CROPPED_STATUS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x63d64908_9fa1_479f_85ba_9952216447db), pid: 4 };\npub const WPD_IMAGE_EXPOSURE_INDEX: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x63d64908_9fa1_479f_85ba_9952216447db), pid: 8 };\npub const WPD_IMAGE_EXPOSURE_TIME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x63d64908_9fa1_479f_85ba_9952216447db), pid: 7 };\npub const WPD_IMAGE_FNUMBER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x63d64908_9fa1_479f_85ba_9952216447db), pid: 6 };\npub const WPD_IMAGE_HORIZONTAL_RESOLUTION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x63d64908_9fa1_479f_85ba_9952216447db), pid: 9 };\npub const WPD_IMAGE_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x63d64908_9fa1_479f_85ba_9952216447db);\npub const WPD_IMAGE_VERTICAL_RESOLUTION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x63d64908_9fa1_479f_85ba_9952216447db), pid: 10 };\npub const WPD_MEDIA_ALBUM_ARTIST: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 25 };\npub const WPD_MEDIA_ARTIST: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 24 };\npub const WPD_MEDIA_AUDIO_ENCODING_PROFILE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 49 };\npub const WPD_MEDIA_BITRATE_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 3 };\npub const WPD_MEDIA_BUY_NOW: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 20 };\npub const WPD_MEDIA_BYTE_BOOKMARK: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 36 };\npub const WPD_MEDIA_COMPOSER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 11 };\npub const WPD_MEDIA_COPYRIGHT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 4 };\npub const WPD_MEDIA_DESCRIPTION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 31 };\npub const WPD_MEDIA_DESTINATION_URL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 30 };\npub const WPD_MEDIA_DURATION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 19 };\npub const WPD_MEDIA_EFFECTIVE_RATING: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 12 };\npub const WPD_MEDIA_ENCODING_PROFILE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 21 };\npub const WPD_MEDIA_GENRE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 32 };\npub const WPD_MEDIA_GUID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 38 };\npub const WPD_MEDIA_HEIGHT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 23 };\npub const WPD_MEDIA_LAST_ACCESSED_TIME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 8 };\npub const WPD_MEDIA_LAST_BUILD_DATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 35 };\npub const WPD_MEDIA_MANAGING_EDITOR: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 27 };\npub const WPD_MEDIA_META_GENRE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 10 };\npub const WPD_MEDIA_OBJECT_BOOKMARK: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 34 };\npub const WPD_MEDIA_OWNER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 26 };\npub const WPD_MEDIA_PARENTAL_RATING: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 9 };\npub const WPD_MEDIA_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8);\npub const WPD_MEDIA_RELEASE_DATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 14 };\npub const WPD_MEDIA_SAMPLE_RATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 15 };\npub const WPD_MEDIA_SKIP_COUNT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 7 };\npub const WPD_MEDIA_SOURCE_URL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 29 };\npub const WPD_MEDIA_STAR_RATING: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 16 };\npub const WPD_MEDIA_SUBSCRIPTION_CONTENT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 5 };\npub const WPD_MEDIA_SUB_DESCRIPTION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 39 };\npub const WPD_MEDIA_SUB_TITLE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 13 };\npub const WPD_MEDIA_TIME_BOOKMARK: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 33 };\npub const WPD_MEDIA_TIME_TO_LIVE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 37 };\npub const WPD_MEDIA_TITLE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 18 };\npub const WPD_MEDIA_TOTAL_BITRATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 2 };\npub const WPD_MEDIA_USER_EFFECTIVE_RATING: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 17 };\npub const WPD_MEDIA_USE_COUNT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 6 };\npub const WPD_MEDIA_WEBMASTER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 28 };\npub const WPD_MEDIA_WIDTH: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2ed8ba05_0ad3_42dc_b0d0_bc95ac396ac8), pid: 22 };\npub const WPD_MEMO_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x5ffbfc7b_7483_41ad_afb9_da3f4e592b8d);\npub type WPD_META_GENRES = i32;\npub const WPD_META_GENRE_AUDIO_PODCAST: WPD_META_GENRES = 64i32;\npub const WPD_META_GENRE_FEATURE_FILM_VIDEO_FILE: WPD_META_GENRES = 37i32;\npub const WPD_META_GENRE_GENERIC_MUSIC_AUDIO_FILE: WPD_META_GENRES = 1i32;\npub const WPD_META_GENRE_GENERIC_NON_AUDIO_NON_VIDEO: WPD_META_GENRES = 48i32;\npub const WPD_META_GENRE_GENERIC_NON_MUSIC_AUDIO_FILE: WPD_META_GENRES = 17i32;\npub const WPD_META_GENRE_GENERIC_VIDEO_FILE: WPD_META_GENRES = 33i32;\npub const WPD_META_GENRE_HOME_VIDEO_FILE: WPD_META_GENRES = 36i32;\npub const WPD_META_GENRE_MIXED_PODCAST: WPD_META_GENRES = 66i32;\npub const WPD_META_GENRE_MUSIC_VIDEO_FILE: WPD_META_GENRES = 35i32;\npub const WPD_META_GENRE_NEWS_VIDEO_FILE: WPD_META_GENRES = 34i32;\npub const WPD_META_GENRE_PHOTO_MONTAGE_VIDEO_FILE: WPD_META_GENRES = 40i32;\npub const WPD_META_GENRE_SPOKEN_WORD_AUDIO_BOOK_FILES: WPD_META_GENRES = 18i32;\npub const WPD_META_GENRE_SPOKEN_WORD_FILES_NON_AUDIO_BOOK: WPD_META_GENRES = 19i32;\npub const WPD_META_GENRE_SPOKEN_WORD_NEWS: WPD_META_GENRES = 20i32;\npub const WPD_META_GENRE_SPOKEN_WORD_TALK_SHOWS: WPD_META_GENRES = 21i32;\npub const WPD_META_GENRE_TELEVISION_VIDEO_FILE: WPD_META_GENRES = 38i32;\npub const WPD_META_GENRE_TRAINING_EDUCATIONAL_VIDEO_FILE: WPD_META_GENRES = 39i32;\npub const WPD_META_GENRE_UNUSED: WPD_META_GENRES = 0i32;\npub const WPD_META_GENRE_VIDEO_PODCAST: WPD_META_GENRES = 65i32;\npub const WPD_METHOD_ATTRIBUTES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf17a5071_f039_44af_8efe_432cf32e432a);\npub const WPD_METHOD_ATTRIBUTE_ACCESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf17a5071_f039_44af_8efe_432cf32e432a), pid: 4 };\npub const WPD_METHOD_ATTRIBUTE_ASSOCIATED_FORMAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf17a5071_f039_44af_8efe_432cf32e432a), pid: 3 };\npub const WPD_METHOD_ATTRIBUTE_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf17a5071_f039_44af_8efe_432cf32e432a), pid: 2 };\npub const WPD_METHOD_ATTRIBUTE_PARAMETERS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf17a5071_f039_44af_8efe_432cf32e432a), pid: 5 };\npub const WPD_MUSIC_ALBUM: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb324f56a_dc5d_46e5_b6df_d2ea414888c6), pid: 3 };\npub const WPD_MUSIC_LYRICS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb324f56a_dc5d_46e5_b6df_d2ea414888c6), pid: 6 };\npub const WPD_MUSIC_MOOD: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb324f56a_dc5d_46e5_b6df_d2ea414888c6), pid: 8 };\npub const WPD_MUSIC_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb324f56a_dc5d_46e5_b6df_d2ea414888c6);\npub const WPD_MUSIC_TRACK: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb324f56a_dc5d_46e5_b6df_d2ea414888c6), pid: 4 };\npub const WPD_NETWORK_ASSOCIATION_HOST_NETWORK_IDENTIFIERS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe4c93c1f_b203_43f1_a100_5a07d11b0274), pid: 2 };\npub const WPD_NETWORK_ASSOCIATION_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe4c93c1f_b203_43f1_a100_5a07d11b0274);\npub const WPD_NETWORK_ASSOCIATION_X509V3SEQUENCE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe4c93c1f_b203_43f1_a100_5a07d11b0274), pid: 3 };\npub const WPD_OBJECT_BACK_REFERENCES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 21 };\npub const WPD_OBJECT_CAN_DELETE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 26 };\npub const WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 23 };\npub const WPD_OBJECT_CONTENT_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 7 };\npub const WPD_OBJECT_DATE_AUTHORED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 20 };\npub const WPD_OBJECT_DATE_CREATED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 18 };\npub const WPD_OBJECT_DATE_MODIFIED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 19 };\npub const WPD_OBJECT_FORMAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 6 };\npub const WPD_OBJECT_FORMAT_3G2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9850000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_3G2A: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1a11202d_8759_4e34_ba5e_b1211087eee4);\npub const WPD_OBJECT_FORMAT_3GP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9840000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_3GPA: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe5172730_f971_41ef_a10b_2271a0019d7a);\npub const WPD_OBJECT_FORMAT_AAC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9030000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_ABSTRACT_CONTACT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbb810000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_ABSTRACT_CONTACT_GROUP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba060000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_ABSTRACT_MEDIA_CAST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba0b0000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_AIFF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30070000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_ALL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc1f62eb2_4bb3_479c_9cfa_05b5f3a57b22);\npub const WPD_OBJECT_FORMAT_AMR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9080000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_ASF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x300c0000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_ASXPLAYLIST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba130000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_ATSCTS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9870000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_AUDIBLE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9040000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_AVCHD: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9860000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_AVI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x300a0000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_BMP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x38040000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_CIFF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x38050000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_DPOF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30060000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_DVBTS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9880000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_EXECUTABLE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30030000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_EXIF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x38010000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_FLAC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9060000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_FLASHPIX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x38030000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_GIF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x38070000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_HTML: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30050000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_ICALENDAR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbe030000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_ICON: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x077232ed_102c_4638_9c22_83f142bfc822);\npub const WPD_OBJECT_FORMAT_JFIF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x38080000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_JP2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x380f0000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_JPEGXR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb8040000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_JPX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x38100000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_M3UPLAYLIST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba110000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_M4A: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30aba7ac_6ffd_4c23_a359_3e9b52f3f1c8);\npub const WPD_OBJECT_FORMAT_MHT_COMPILED_HTML: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba840000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_MICROSOFT_EXCEL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba850000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_MICROSOFT_POWERPOINT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba860000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_MICROSOFT_WFC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb1040000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_MICROSOFT_WORD: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba830000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_MKV: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9900000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_MP2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9830000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_MP3: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30090000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_MP4: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9820000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_MPEG: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x300b0000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_MPLPLAYLIST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba120000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_NETWORK_ASSOCIATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb1020000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_OGG: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9020000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_PCD: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x38090000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_PICT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x380a0000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_PLSPLAYLIST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba140000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_PNG: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x380b0000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_PROPERTIES_ONLY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30010000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_QCELP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9070000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_SCRIPT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30020000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_TEXT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30040000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_TIFF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x380d0000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_TIFFEP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x38020000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_TIFFIT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x380e0000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_UNSPECIFIED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30000000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_VCALENDAR1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbe020000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_VCARD2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbb820000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_VCARD3: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbb830000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_WAVE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30080000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_WBMP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb8030000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_WINDOWSIMAGEFORMAT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb8810000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_WMA: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9010000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_WMV: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9810000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_WPLPLAYLIST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba100000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_X509V3CERTIFICATE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb1030000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_FORMAT_XML: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xba820000_ae6c_4804_98ba_c57b46965fe7);\npub const WPD_OBJECT_GENERATE_THUMBNAIL_FROM_RESOURCE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 24 };\npub const WPD_OBJECT_HINT_LOCATION_DISPLAY_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 25 };\npub const WPD_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 2 };\npub const WPD_OBJECT_ISHIDDEN: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 9 };\npub const WPD_OBJECT_ISSYSTEM: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 10 };\npub const WPD_OBJECT_IS_DRM_PROTECTED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 17 };\npub const WPD_OBJECT_KEYWORDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 15 };\npub const WPD_OBJECT_LANGUAGE_LOCALE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 27 };\npub const WPD_OBJECT_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 4 };\npub const WPD_OBJECT_NON_CONSUMABLE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 13 };\npub const WPD_OBJECT_ORIGINAL_FILE_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 12 };\npub const WPD_OBJECT_PARENT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 3 };\npub const WPD_OBJECT_PERSISTENT_UNIQUE_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 5 };\npub const WPD_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c);\npub const WPD_OBJECT_PROPERTIES_V2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0373cd3d_4a46_40d7_b4d8_73e8da74e775);\npub const WPD_OBJECT_REFERENCES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 14 };\npub const WPD_OBJECT_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 11 };\npub const WPD_OBJECT_SUPPORTED_UNITS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0373cd3d_4a46_40d7_b4d8_73e8da74e775), pid: 2 };\npub const WPD_OBJECT_SYNC_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef6b490d_5cd8_437a_affc_da8b60ee4a3c), pid: 16 };\npub type WPD_OPERATION_STATES = i32;\npub const WPD_OPERATION_STATE_ABORTED: WPD_OPERATION_STATES = 6i32;\npub const WPD_OPERATION_STATE_CANCELLED: WPD_OPERATION_STATES = 4i32;\npub const WPD_OPERATION_STATE_FINISHED: WPD_OPERATION_STATES = 5i32;\npub const WPD_OPERATION_STATE_PAUSED: WPD_OPERATION_STATES = 3i32;\npub const WPD_OPERATION_STATE_RUNNING: WPD_OPERATION_STATES = 2i32;\npub const WPD_OPERATION_STATE_STARTED: WPD_OPERATION_STATES = 1i32;\npub const WPD_OPERATION_STATE_UNSPECIFIED: WPD_OPERATION_STATES = 0i32;\npub const WPD_OPTION_OBJECT_MANAGEMENT_RECURSIVE_DELETE_SUPPORTED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 5001 };\npub const WPD_OPTION_OBJECT_RESOURCES_NO_INPUT_BUFFER_ON_READ: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 5003 };\npub const WPD_OPTION_OBJECT_RESOURCES_SEEK_ON_READ_SUPPORTED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 5001 };\npub const WPD_OPTION_OBJECT_RESOURCES_SEEK_ON_WRITE_SUPPORTED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 5002 };\npub const WPD_OPTION_SMS_BINARY_MESSAGE_SUPPORTED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xafc25d66_fe0d_4114_9097_970c93e920d1), pid: 5001 };\npub const WPD_OPTION_VALID_OBJECT_IDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 5001 };\npub const WPD_PARAMETER_ATTRIBUTES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58);\npub const WPD_PARAMETER_ATTRIBUTE_DEFAULT_VALUE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 5 };\npub const WPD_PARAMETER_ATTRIBUTE_ENUMERATION_ELEMENTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 9 };\npub const WPD_PARAMETER_ATTRIBUTE_FORM: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 4 };\npub const WPD_PARAMETER_ATTRIBUTE_FORM_ENUMERATION: WpdParameterAttributeForm = 2i32;\npub const WPD_PARAMETER_ATTRIBUTE_FORM_OBJECT_IDENTIFIER: WpdParameterAttributeForm = 4i32;\npub const WPD_PARAMETER_ATTRIBUTE_FORM_RANGE: WpdParameterAttributeForm = 1i32;\npub const WPD_PARAMETER_ATTRIBUTE_FORM_REGULAR_EXPRESSION: WpdParameterAttributeForm = 3i32;\npub const WPD_PARAMETER_ATTRIBUTE_FORM_UNSPECIFIED: WpdParameterAttributeForm = 0i32;\npub const WPD_PARAMETER_ATTRIBUTE_MAX_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 11 };\npub const WPD_PARAMETER_ATTRIBUTE_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 13 };\npub const WPD_PARAMETER_ATTRIBUTE_ORDER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 2 };\npub const WPD_PARAMETER_ATTRIBUTE_RANGE_MAX: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 7 };\npub const WPD_PARAMETER_ATTRIBUTE_RANGE_MIN: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 6 };\npub const WPD_PARAMETER_ATTRIBUTE_RANGE_STEP: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 8 };\npub const WPD_PARAMETER_ATTRIBUTE_REGULAR_EXPRESSION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 10 };\npub const WPD_PARAMETER_ATTRIBUTE_USAGE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 3 };\npub const WPD_PARAMETER_ATTRIBUTE_VARTYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe6864dd7_f325_45ea_a1d5_97cf73b6ca58), pid: 12 };\npub const WPD_PARAMETER_USAGE_IN: WPD_PARAMETER_USAGE_TYPES = 1i32;\npub const WPD_PARAMETER_USAGE_INOUT: WPD_PARAMETER_USAGE_TYPES = 3i32;\npub const WPD_PARAMETER_USAGE_OUT: WPD_PARAMETER_USAGE_TYPES = 2i32;\npub const WPD_PARAMETER_USAGE_RETURN: WPD_PARAMETER_USAGE_TYPES = 0i32;\npub type WPD_PARAMETER_USAGE_TYPES = i32;\npub type WPD_POWER_SOURCES = i32;\npub const WPD_POWER_SOURCE_BATTERY: WPD_POWER_SOURCES = 0i32;\npub const WPD_POWER_SOURCE_EXTERNAL: WPD_POWER_SOURCES = 1i32;\npub const WPD_PROPERTIES_MTP_VENDOR_EXTENDED_DEVICE_PROPS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4d545058_8900_40b3_8f1d_dc246e1e8370);\npub const WPD_PROPERTIES_MTP_VENDOR_EXTENDED_OBJECT_PROPS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4d545058_4fce_4578_95c8_8698a9bc0f49);\npub const WPD_PROPERTY_ATTRIBUTES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37);\npub const WPD_PROPERTY_ATTRIBUTES_V2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x5d9da160_74ae_43cc_85a9_fe555a80798e);\npub const WPD_PROPERTY_ATTRIBUTE_CAN_DELETE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 5 };\npub const WPD_PROPERTY_ATTRIBUTE_CAN_READ: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 3 };\npub const WPD_PROPERTY_ATTRIBUTE_CAN_WRITE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 4 };\npub const WPD_PROPERTY_ATTRIBUTE_DEFAULT_VALUE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 6 };\npub const WPD_PROPERTY_ATTRIBUTE_ENUMERATION_ELEMENTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 11 };\npub const WPD_PROPERTY_ATTRIBUTE_FAST_PROPERTY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 7 };\npub const WPD_PROPERTY_ATTRIBUTE_FORM: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 2 };\npub const WPD_PROPERTY_ATTRIBUTE_FORM_ENUMERATION: WpdAttributeForm = 2i32;\npub const WPD_PROPERTY_ATTRIBUTE_FORM_OBJECT_IDENTIFIER: WpdAttributeForm = 4i32;\npub const WPD_PROPERTY_ATTRIBUTE_FORM_RANGE: WpdAttributeForm = 1i32;\npub const WPD_PROPERTY_ATTRIBUTE_FORM_REGULAR_EXPRESSION: WpdAttributeForm = 3i32;\npub const WPD_PROPERTY_ATTRIBUTE_FORM_UNSPECIFIED: WpdAttributeForm = 0i32;\npub const WPD_PROPERTY_ATTRIBUTE_MAX_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 13 };\npub const WPD_PROPERTY_ATTRIBUTE_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x5d9da160_74ae_43cc_85a9_fe555a80798e), pid: 2 };\npub const WPD_PROPERTY_ATTRIBUTE_RANGE_MAX: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 9 };\npub const WPD_PROPERTY_ATTRIBUTE_RANGE_MIN: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 8 };\npub const WPD_PROPERTY_ATTRIBUTE_RANGE_STEP: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 10 };\npub const WPD_PROPERTY_ATTRIBUTE_REGULAR_EXPRESSION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xab7943d8_6332_445f_a00d_8d5ef1e96f37), pid: 12 };\npub const WPD_PROPERTY_ATTRIBUTE_VARTYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x5d9da160_74ae_43cc_85a9_fe555a80798e), pid: 3 };\npub const WPD_PROPERTY_CAPABILITIES_COMMAND: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1002 };\npub const WPD_PROPERTY_CAPABILITIES_COMMAND_OPTIONS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1003 };\npub const WPD_PROPERTY_CAPABILITIES_CONTENT_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1008 };\npub const WPD_PROPERTY_CAPABILITIES_CONTENT_TYPES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1007 };\npub const WPD_PROPERTY_CAPABILITIES_EVENT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1014 };\npub const WPD_PROPERTY_CAPABILITIES_EVENT_OPTIONS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1015 };\npub const WPD_PROPERTY_CAPABILITIES_FORMAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1010 };\npub const WPD_PROPERTY_CAPABILITIES_FORMATS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1009 };\npub const WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORIES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1004 };\npub const WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1005 };\npub const WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_OBJECTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1006 };\npub const WPD_PROPERTY_CAPABILITIES_PROPERTY_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1012 };\npub const WPD_PROPERTY_CAPABILITIES_PROPERTY_KEYS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1011 };\npub const WPD_PROPERTY_CAPABILITIES_SUPPORTED_COMMANDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1001 };\npub const WPD_PROPERTY_CAPABILITIES_SUPPORTED_EVENTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0cabec78_6b74_41c6_9216_2639d1fce356), pid: 1013 };\npub const WPD_PROPERTY_CLASS_EXTENSION_DEVICE_INFORMATION_VALUES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x33fb0d11_64a3_4fac_b4c7_3dfeaa99b051), pid: 1001 };\npub const WPD_PROPERTY_CLASS_EXTENSION_DEVICE_INFORMATION_WRITE_RESULTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x33fb0d11_64a3_4fac_b4c7_3dfeaa99b051), pid: 1002 };\npub const WPD_PROPERTY_CLASS_EXTENSION_SERVICE_INTERFACES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7f0779b5_fa2b_4766_9cb2_f73ba30b6758), pid: 1002 };\npub const WPD_PROPERTY_CLASS_EXTENSION_SERVICE_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7f0779b5_fa2b_4766_9cb2_f73ba30b6758), pid: 1001 };\npub const WPD_PROPERTY_CLASS_EXTENSION_SERVICE_REGISTRATION_RESULTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7f0779b5_fa2b_4766_9cb2_f73ba30b6758), pid: 1003 };\npub const WPD_PROPERTY_COMMON_ACTIVITY_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 1011 };\npub const WPD_PROPERTY_COMMON_CLIENT_INFORMATION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 1009 };\npub const WPD_PROPERTY_COMMON_CLIENT_INFORMATION_CONTEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 1010 };\npub const WPD_PROPERTY_COMMON_COMMAND_CATEGORY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 1001 };\npub const WPD_PROPERTY_COMMON_COMMAND_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 1002 };\npub const WPD_PROPERTY_COMMON_COMMAND_TARGET: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 1006 };\npub const WPD_PROPERTY_COMMON_DRIVER_ERROR_CODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 1004 };\npub const WPD_PROPERTY_COMMON_HRESULT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 1003 };\npub const WPD_PROPERTY_COMMON_OBJECT_IDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 1008 };\npub const WPD_PROPERTY_COMMON_PERSISTENT_UNIQUE_IDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf0422a9c_5dc8_4440_b5bd_5df28835658a), pid: 1007 };\npub const WPD_PROPERTY_DEVICE_HINTS_CONTENT_LOCATIONS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0d5fb92b_cb46_4c4f_8343_0bc3d3f17c84), pid: 1002 };\npub const WPD_PROPERTY_DEVICE_HINTS_CONTENT_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x0d5fb92b_cb46_4c4f_8343_0bc3d3f17c84), pid: 1001 };\npub const WPD_PROPERTY_MTP_EXT_EVENT_PARAMS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_ef88_4e4d_95c3_4f327f728a96), pid: 1011 };\npub const WPD_PROPERTY_MTP_EXT_OPERATION_CODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1001 };\npub const WPD_PROPERTY_MTP_EXT_OPERATION_PARAMS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1002 };\npub const WPD_PROPERTY_MTP_EXT_OPTIMAL_TRANSFER_BUFFER_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1013 };\npub const WPD_PROPERTY_MTP_EXT_RESPONSE_CODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1003 };\npub const WPD_PROPERTY_MTP_EXT_RESPONSE_PARAMS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1004 };\npub const WPD_PROPERTY_MTP_EXT_TRANSFER_CONTEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1006 };\npub const WPD_PROPERTY_MTP_EXT_TRANSFER_DATA: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1012 };\npub const WPD_PROPERTY_MTP_EXT_TRANSFER_NUM_BYTES_READ: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1009 };\npub const WPD_PROPERTY_MTP_EXT_TRANSFER_NUM_BYTES_TO_READ: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1008 };\npub const WPD_PROPERTY_MTP_EXT_TRANSFER_NUM_BYTES_TO_WRITE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1010 };\npub const WPD_PROPERTY_MTP_EXT_TRANSFER_NUM_BYTES_WRITTEN: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1011 };\npub const WPD_PROPERTY_MTP_EXT_TRANSFER_TOTAL_DATA_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1007 };\npub const WPD_PROPERTY_MTP_EXT_VENDOR_EXTENSION_DESCRIPTION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1014 };\npub const WPD_PROPERTY_MTP_EXT_VENDOR_OPERATION_CODES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d545058_1a2e_4106_a357_771e0819fc56), pid: 1005 };\npub const WPD_PROPERTY_NULL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x00000000_0000_0000_0000_000000000000), pid: 0 };\npub const WPD_PROPERTY_OBJECT_ENUMERATION_CONTEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb7474e91_e7f8_4ad9_b400_ad1a4b58eeec), pid: 1004 };\npub const WPD_PROPERTY_OBJECT_ENUMERATION_FILTER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb7474e91_e7f8_4ad9_b400_ad1a4b58eeec), pid: 1002 };\npub const WPD_PROPERTY_OBJECT_ENUMERATION_NUM_OBJECTS_REQUESTED: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb7474e91_e7f8_4ad9_b400_ad1a4b58eeec), pid: 1005 };\npub const WPD_PROPERTY_OBJECT_ENUMERATION_OBJECT_IDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb7474e91_e7f8_4ad9_b400_ad1a4b58eeec), pid: 1003 };\npub const WPD_PROPERTY_OBJECT_ENUMERATION_PARENT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb7474e91_e7f8_4ad9_b400_ad1a4b58eeec), pid: 1001 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_CONTEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1002 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_COPY_RESULTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1013 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_CREATION_PROPERTIES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1001 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_DATA: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1005 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_OPTIONS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1007 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1010 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_DESTINATION_FOLDER_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1011 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_MOVE_RESULTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1012 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_NUM_BYTES_TO_WRITE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1003 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_NUM_BYTES_WRITTEN: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1004 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_FORMAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1016 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1006 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1009 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_OPTIMAL_TRANSFER_BUFFER_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1008 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_PROPERTY_KEYS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1015 };\npub const WPD_PROPERTY_OBJECT_MANAGEMENT_UPDATE_PROPERTIES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xef1e43dd_a9ed_4341_8bcc_186192aea089), pid: 1014 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 1002 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_BULK_DEPTH: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 1005 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_BULK_OBJECT_FORMAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 1007 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_BULK_OBJECT_IDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 1001 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_BULK_PARENT_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 1006 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_BULK_PROPERTY_KEYS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 1004 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_BULK_VALUES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 1003 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_BULK_WRITE_RESULTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x11c824dd_04cd_4e4e_8c7b_f6efb794d84e), pid: 1008 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 1001 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 1003 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_DELETE_RESULTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 1006 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_KEYS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 1002 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_VALUES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 1004 };\npub const WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_WRITE_RESULTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x9e5582e4_0814_44e6_981a_b2998d583804), pid: 1005 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_ACCESS_MODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1002 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1005 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_DATA: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1010 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_READ: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1007 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1006 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_WRITE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1008 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_WRITTEN: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1009 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1001 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1011 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_POSITION_FROM_START: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1014 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1004 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1003 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_SEEK_OFFSET: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1012 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_SEEK_ORIGIN_FLAG: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1013 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_STREAM_UNITS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1016 };\npub const WPD_PROPERTY_OBJECT_RESOURCES_SUPPORTS_UNITS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb3a2b22d_a595_4108_be0a_fc3c965f3d4a), pid: 1015 };\npub const WPD_PROPERTY_PUBLIC_KEY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x78f9c6fc_79b8_473c_9060_6bd23dd072c4), pid: 1001 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_COMMAND: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1018 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_COMMAND_OPTIONS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1019 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_EVENT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1012 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_EVENT_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1013 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1002 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_FORMATS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1007 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_FORMAT_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1008 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_INHERITANCE_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1014 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_INHERITED_SERVICES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1015 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_METHOD: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1003 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_METHOD_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1004 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1005 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_PARAMETER_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1006 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_ATTRIBUTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1010 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_PROPERTY_KEYS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1009 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_RENDERING_PROFILES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1016 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_COMMANDS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1017 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_EVENTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1011 };\npub const WPD_PROPERTY_SERVICE_CAPABILITIES_SUPPORTED_METHODS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x24457e74_2e9f_44f9_8c57_1d1bcb170b89), pid: 1001 };\npub const WPD_PROPERTY_SERVICE_METHOD: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2d521ca8_c1b0_4268_a342_cf19321569bc), pid: 1001 };\npub const WPD_PROPERTY_SERVICE_METHOD_CONTEXT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2d521ca8_c1b0_4268_a342_cf19321569bc), pid: 1004 };\npub const WPD_PROPERTY_SERVICE_METHOD_HRESULT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2d521ca8_c1b0_4268_a342_cf19321569bc), pid: 1005 };\npub const WPD_PROPERTY_SERVICE_METHOD_PARAMETER_VALUES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2d521ca8_c1b0_4268_a342_cf19321569bc), pid: 1002 };\npub const WPD_PROPERTY_SERVICE_METHOD_RESULT_VALUES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2d521ca8_c1b0_4268_a342_cf19321569bc), pid: 1003 };\npub const WPD_PROPERTY_SERVICE_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x322f071d_36ef_477f_b4b5_6f52d734baee), pid: 1001 };\npub const WPD_PROPERTY_SMS_BINARY_MESSAGE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xafc25d66_fe0d_4114_9097_970c93e920d1), pid: 1004 };\npub const WPD_PROPERTY_SMS_MESSAGE_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xafc25d66_fe0d_4114_9097_970c93e920d1), pid: 1002 };\npub const WPD_PROPERTY_SMS_RECIPIENT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xafc25d66_fe0d_4114_9097_970c93e920d1), pid: 1001 };\npub const WPD_PROPERTY_SMS_TEXT_MESSAGE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xafc25d66_fe0d_4114_9097_970c93e920d1), pid: 1003 };\npub const WPD_PROPERTY_STORAGE_DESTINATION_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xd8f907a6_34cc_45fa_97fb_d007fa47ec94), pid: 1002 };\npub const WPD_PROPERTY_STORAGE_OBJECT_ID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xd8f907a6_34cc_45fa_97fb_d007fa47ec94), pid: 1001 };\npub const WPD_RENDERING_INFORMATION_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc53d039f_ee23_4a31_8590_7639879870b4);\npub const WPD_RENDERING_INFORMATION_PROFILES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xc53d039f_ee23_4a31_8590_7639879870b4), pid: 2 };\npub const WPD_RENDERING_INFORMATION_PROFILE_ENTRY_CREATABLE_RESOURCES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xc53d039f_ee23_4a31_8590_7639879870b4), pid: 4 };\npub const WPD_RENDERING_INFORMATION_PROFILE_ENTRY_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xc53d039f_ee23_4a31_8590_7639879870b4), pid: 3 };\npub type WPD_RENDERING_INFORMATION_PROFILE_ENTRY_TYPES = i32;\npub const WPD_RENDERING_INFORMATION_PROFILE_ENTRY_TYPE_OBJECT: WPD_RENDERING_INFORMATION_PROFILE_ENTRY_TYPES = 0i32;\npub const WPD_RENDERING_INFORMATION_PROFILE_ENTRY_TYPE_RESOURCE: WPD_RENDERING_INFORMATION_PROFILE_ENTRY_TYPES = 1i32;\npub const WPD_RESOURCE_ALBUM_ART: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf02aa354_2300_4e2d_a1b9_3b6730f7fa21), pid: 0 };\npub const WPD_RESOURCE_ATTRIBUTES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1eb6f604_9278_429f_93cc_5bb8c06656b6);\npub const WPD_RESOURCE_ATTRIBUTE_CAN_DELETE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1eb6f604_9278_429f_93cc_5bb8c06656b6), pid: 5 };\npub const WPD_RESOURCE_ATTRIBUTE_CAN_READ: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1eb6f604_9278_429f_93cc_5bb8c06656b6), pid: 3 };\npub const WPD_RESOURCE_ATTRIBUTE_CAN_WRITE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1eb6f604_9278_429f_93cc_5bb8c06656b6), pid: 4 };\npub const WPD_RESOURCE_ATTRIBUTE_FORMAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1eb6f604_9278_429f_93cc_5bb8c06656b6), pid: 8 };\npub const WPD_RESOURCE_ATTRIBUTE_OPTIMAL_READ_BUFFER_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1eb6f604_9278_429f_93cc_5bb8c06656b6), pid: 6 };\npub const WPD_RESOURCE_ATTRIBUTE_OPTIMAL_WRITE_BUFFER_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1eb6f604_9278_429f_93cc_5bb8c06656b6), pid: 7 };\npub const WPD_RESOURCE_ATTRIBUTE_RESOURCE_KEY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1eb6f604_9278_429f_93cc_5bb8c06656b6), pid: 9 };\npub const WPD_RESOURCE_ATTRIBUTE_TOTAL_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1eb6f604_9278_429f_93cc_5bb8c06656b6), pid: 2 };\npub const WPD_RESOURCE_AUDIO_CLIP: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x3bc13982_85b1_48e0_95a6_8d3ad06be117), pid: 0 };\npub const WPD_RESOURCE_BRANDING_ART: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb633b1ae_6caf_4a87_9589_22ded6dd5899), pid: 0 };\npub const WPD_RESOURCE_CONTACT_PHOTO: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x2c4d6803_80ea_4580_af9a_5be1a23eddcb), pid: 0 };\npub const WPD_RESOURCE_DEFAULT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe81e79be_34f0_41bf_b53f_f1a06ae87842), pid: 0 };\npub const WPD_RESOURCE_GENERIC: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb9b9f515_ba70_4647_94dc_fa4925e95a07), pid: 0 };\npub const WPD_RESOURCE_ICON: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf195fed8_aa28_4ee3_b153_e182dd5edc39), pid: 0 };\npub const WPD_RESOURCE_THUMBNAIL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xc7c407ba_98fa_46b5_9960_23fec124cfde), pid: 0 };\npub const WPD_RESOURCE_VIDEO_CLIP: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xb566ee42_6368_4290_8662_70182fb79f20), pid: 0 };\npub const WPD_SECTION_DATA_LENGTH: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x516afd2b_c64e_44f0_98dc_bee1c88f7d66), pid: 3 };\npub const WPD_SECTION_DATA_OFFSET: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x516afd2b_c64e_44f0_98dc_bee1c88f7d66), pid: 2 };\npub const WPD_SECTION_DATA_REFERENCED_OBJECT_RESOURCE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x516afd2b_c64e_44f0_98dc_bee1c88f7d66), pid: 5 };\npub const WPD_SECTION_DATA_UNITS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x516afd2b_c64e_44f0_98dc_bee1c88f7d66), pid: 4 };\npub const WPD_SECTION_DATA_UNITS_BYTES: WPD_SECTION_DATA_UNITS_VALUES = 0i32;\npub const WPD_SECTION_DATA_UNITS_MILLISECONDS: WPD_SECTION_DATA_UNITS_VALUES = 1i32;\npub type WPD_SECTION_DATA_UNITS_VALUES = i32;\npub const WPD_SECTION_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x516afd2b_c64e_44f0_98dc_bee1c88f7d66);\npub const WPD_SERVICE_INHERITANCE_IMPLEMENTATION: WPD_SERVICE_INHERITANCE_TYPES = 0i32;\npub type WPD_SERVICE_INHERITANCE_TYPES = i32;\npub const WPD_SERVICE_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7510698a_cb54_481c_b8db_0d75c93f1c06);\npub const WPD_SERVICE_VERSION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7510698a_cb54_481c_b8db_0d75c93f1c06), pid: 2 };\npub const WPD_SMS_ENCODING: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7e1074cc_50ff_4dd1_a742_53be6f093a0d), pid: 5 };\npub type WPD_SMS_ENCODING_TYPES = i32;\npub const WPD_SMS_MAX_PAYLOAD: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7e1074cc_50ff_4dd1_a742_53be6f093a0d), pid: 4 };\npub const WPD_SMS_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7e1074cc_50ff_4dd1_a742_53be6f093a0d);\npub const WPD_SMS_PROVIDER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7e1074cc_50ff_4dd1_a742_53be6f093a0d), pid: 2 };\npub const WPD_SMS_TIMEOUT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x7e1074cc_50ff_4dd1_a742_53be6f093a0d), pid: 3 };\npub const WPD_STILL_IMAGE_ARTIST: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 29 };\npub const WPD_STILL_IMAGE_BURST_INTERVAL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 24 };\npub const WPD_STILL_IMAGE_BURST_NUMBER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 23 };\npub const WPD_STILL_IMAGE_CAMERA_MANUFACTURER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 31 };\npub const WPD_STILL_IMAGE_CAMERA_MODEL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 30 };\npub const WPD_STILL_IMAGE_CAPTURE_DELAY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 17 };\npub const WPD_STILL_IMAGE_CAPTURE_FORMAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 3 };\npub const WPD_STILL_IMAGE_CAPTURE_MODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 18 };\npub const WPD_STILL_IMAGE_CAPTURE_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260);\npub const WPD_STILL_IMAGE_CAPTURE_RESOLUTION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 2 };\npub const WPD_STILL_IMAGE_COMPRESSION_SETTING: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 4 };\npub const WPD_STILL_IMAGE_CONTRAST: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 19 };\npub const WPD_STILL_IMAGE_DIGITAL_ZOOM: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 21 };\npub const WPD_STILL_IMAGE_EFFECT_MODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 22 };\npub const WPD_STILL_IMAGE_EXPOSURE_BIAS_COMPENSATION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 16 };\npub const WPD_STILL_IMAGE_EXPOSURE_INDEX: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 15 };\npub const WPD_STILL_IMAGE_EXPOSURE_METERING_MODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 11 };\npub const WPD_STILL_IMAGE_EXPOSURE_PROGRAM_MODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 14 };\npub const WPD_STILL_IMAGE_EXPOSURE_TIME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 13 };\npub const WPD_STILL_IMAGE_FLASH_MODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 12 };\npub const WPD_STILL_IMAGE_FNUMBER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 7 };\npub const WPD_STILL_IMAGE_FOCAL_LENGTH: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 8 };\npub const WPD_STILL_IMAGE_FOCUS_DISTANCE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 9 };\npub const WPD_STILL_IMAGE_FOCUS_METERING_MODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 27 };\npub const WPD_STILL_IMAGE_FOCUS_MODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 10 };\npub const WPD_STILL_IMAGE_RGB_GAIN: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 6 };\npub const WPD_STILL_IMAGE_SHARPNESS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 20 };\npub const WPD_STILL_IMAGE_TIMELAPSE_INTERVAL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 26 };\npub const WPD_STILL_IMAGE_TIMELAPSE_NUMBER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 25 };\npub const WPD_STILL_IMAGE_UPLOAD_URL: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 28 };\npub const WPD_STILL_IMAGE_WHITE_BALANCE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x58c571ec_1bcb_42a7_8ac5_bb291573a260), pid: 5 };\npub const WPD_STORAGE_ACCESS_CAPABILITY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a), pid: 11 };\npub const WPD_STORAGE_ACCESS_CAPABILITY_READWRITE: WPD_STORAGE_ACCESS_CAPABILITY_VALUES = 0i32;\npub const WPD_STORAGE_ACCESS_CAPABILITY_READ_ONLY_WITHOUT_OBJECT_DELETION: WPD_STORAGE_ACCESS_CAPABILITY_VALUES = 1i32;\npub const WPD_STORAGE_ACCESS_CAPABILITY_READ_ONLY_WITH_OBJECT_DELETION: WPD_STORAGE_ACCESS_CAPABILITY_VALUES = 2i32;\npub type WPD_STORAGE_ACCESS_CAPABILITY_VALUES = i32;\npub const WPD_STORAGE_CAPACITY: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a), pid: 4 };\npub const WPD_STORAGE_CAPACITY_IN_OBJECTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a), pid: 10 };\npub const WPD_STORAGE_DESCRIPTION: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a), pid: 7 };\npub const WPD_STORAGE_FILE_SYSTEM_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a), pid: 3 };\npub const WPD_STORAGE_FREE_SPACE_IN_BYTES: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a), pid: 5 };\npub const WPD_STORAGE_FREE_SPACE_IN_OBJECTS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a), pid: 6 };\npub const WPD_STORAGE_MAX_OBJECT_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a), pid: 9 };\npub const WPD_STORAGE_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a);\npub const WPD_STORAGE_SERIAL_NUMBER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a), pid: 8 };\npub const WPD_STORAGE_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x01a3057a_74d6_4e80_bea7_dc4c212ce50a), pid: 2 };\npub const WPD_STORAGE_TYPE_FIXED_RAM: WPD_STORAGE_TYPE_VALUES = 3i32;\npub const WPD_STORAGE_TYPE_FIXED_ROM: WPD_STORAGE_TYPE_VALUES = 1i32;\npub const WPD_STORAGE_TYPE_REMOVABLE_RAM: WPD_STORAGE_TYPE_VALUES = 4i32;\npub const WPD_STORAGE_TYPE_REMOVABLE_ROM: WPD_STORAGE_TYPE_VALUES = 2i32;\npub const WPD_STORAGE_TYPE_UNDEFINED: WPD_STORAGE_TYPE_VALUES = 0i32;\npub type WPD_STORAGE_TYPE_VALUES = i32;\npub type WPD_STREAM_UNITS = i32;\npub const WPD_STREAM_UNITS_BYTES: WPD_STREAM_UNITS = 0i32;\npub const WPD_STREAM_UNITS_FRAMES: WPD_STREAM_UNITS = 1i32;\npub const WPD_STREAM_UNITS_MICROSECONDS: WPD_STREAM_UNITS = 8i32;\npub const WPD_STREAM_UNITS_MILLISECONDS: WPD_STREAM_UNITS = 4i32;\npub const WPD_STREAM_UNITS_ROWS: WPD_STREAM_UNITS = 2i32;\npub const WPD_TASK_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe354e95e_d8a0_4637_a03a_0cb26838dbc7);\npub const WPD_TASK_OWNER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe354e95e_d8a0_4637_a03a_0cb26838dbc7), pid: 11 };\npub const WPD_TASK_PERCENT_COMPLETE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe354e95e_d8a0_4637_a03a_0cb26838dbc7), pid: 8 };\npub const WPD_TASK_REMINDER_DATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe354e95e_d8a0_4637_a03a_0cb26838dbc7), pid: 10 };\npub const WPD_TASK_STATUS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe354e95e_d8a0_4637_a03a_0cb26838dbc7), pid: 6 };\npub const WPD_VIDEO_AUTHOR: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 2 };\npub const WPD_VIDEO_BITRATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 13 };\npub const WPD_VIDEO_BUFFER_SIZE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 8 };\npub const WPD_VIDEO_CREDITS: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 9 };\npub const WPD_VIDEO_FOURCC_CODE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 14 };\npub const WPD_VIDEO_FRAMERATE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 15 };\npub const WPD_VIDEO_KEY_FRAME_DISTANCE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 10 };\npub const WPD_VIDEO_OBJECT_PROPERTIES_V1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a);\npub const WPD_VIDEO_QUALITY_SETTING: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 11 };\npub const WPD_VIDEO_RECORDEDTV_CHANNEL_NUMBER: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 5 };\npub const WPD_VIDEO_RECORDEDTV_REPEAT: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 7 };\npub const WPD_VIDEO_RECORDEDTV_STATION_NAME: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 4 };\npub const WPD_VIDEO_SCAN_TYPE: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x346f2163_f998_4146_8b01_d19b4c00de9a), pid: 12 };\npub type WPD_VIDEO_SCAN_TYPES = i32;\npub const WPD_VIDEO_SCAN_TYPE_FIELD_INTERLEAVED_LOWER_FIRST: WPD_VIDEO_SCAN_TYPES = 3i32;\npub const WPD_VIDEO_SCAN_TYPE_FIELD_INTERLEAVED_UPPER_FIRST: WPD_VIDEO_SCAN_TYPES = 2i32;\npub const WPD_VIDEO_SCAN_TYPE_FIELD_SINGLE_LOWER_FIRST: WPD_VIDEO_SCAN_TYPES = 5i32;\npub const WPD_VIDEO_SCAN_TYPE_FIELD_SINGLE_UPPER_FIRST: WPD_VIDEO_SCAN_TYPES = 4i32;\npub const WPD_VIDEO_SCAN_TYPE_MIXED_INTERLACE: WPD_VIDEO_SCAN_TYPES = 6i32;\npub const WPD_VIDEO_SCAN_TYPE_MIXED_INTERLACE_AND_PROGRESSIVE: WPD_VIDEO_SCAN_TYPES = 7i32;\npub const WPD_VIDEO_SCAN_TYPE_PROGRESSIVE: WPD_VIDEO_SCAN_TYPES = 1i32;\npub const WPD_VIDEO_SCAN_TYPE_UNUSED: WPD_VIDEO_SCAN_TYPES = 0i32;\npub const WPD_WHITE_BALANCE_AUTOMATIC: WPD_WHITE_BALANCE_SETTINGS = 2i32;\npub const WPD_WHITE_BALANCE_DAYLIGHT: WPD_WHITE_BALANCE_SETTINGS = 4i32;\npub const WPD_WHITE_BALANCE_FLASH: WPD_WHITE_BALANCE_SETTINGS = 7i32;\npub const WPD_WHITE_BALANCE_FLORESCENT: WPD_WHITE_BALANCE_SETTINGS = 5i32;\npub const WPD_WHITE_BALANCE_MANUAL: WPD_WHITE_BALANCE_SETTINGS = 1i32;\npub const WPD_WHITE_BALANCE_ONE_PUSH_AUTOMATIC: WPD_WHITE_BALANCE_SETTINGS = 3i32;\npub type WPD_WHITE_BALANCE_SETTINGS = i32;\npub const WPD_WHITE_BALANCE_TUNGSTEN: WPD_WHITE_BALANCE_SETTINGS = 6i32;\npub const WPD_WHITE_BALANCE_UNDEFINED: WPD_WHITE_BALANCE_SETTINGS = 0i32;\npub type WpdAttributeForm = i32;\npub type WpdParameterAttributeForm = i32;\npub const WpdSerializer: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0b91a74b_ad7c_4a9d_b563_29eef9167172);\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/Globalization/mod.rs",
      "sha256": "facc448ddb31d22eadbd2b71d9a151d5b9523f1daf1a501f1da7e9696588e908",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "windows_link::link!(\"kernel32.dll\" \"system\" fn AdjustCalendarDate(lpcaldatetime : *mut CALDATETIME, calunit : CALDATETIME_DATEUNIT, amount : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn CompareStringA(locale : u32, dwcmpflags : u32, lpstring1 : *const i8, cchcount1 : i32, lpstring2 : *const i8, cchcount2 : i32) -> COMPARESTRING_RESULT);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn CompareStringEx(lplocalename : windows_sys::core::PCWSTR, dwcmpflags : COMPARE_STRING_FLAGS, lpstring1 : windows_sys::core::PCWSTR, cchcount1 : i32, lpstring2 : windows_sys::core::PCWSTR, cchcount2 : i32, lpversioninformation : *const NLSVERSIONINFO, lpreserved : *const core::ffi::c_void, lparam : super::Foundation:: LPARAM) -> COMPARESTRING_RESULT);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn CompareStringOrdinal(lpstring1 : windows_sys::core::PCWSTR, cchcount1 : i32, lpstring2 : windows_sys::core::PCWSTR, cchcount2 : i32, bignorecase : windows_sys::core::BOOL) -> COMPARESTRING_RESULT);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn CompareStringW(locale : u32, dwcmpflags : u32, lpstring1 : windows_sys::core::PCWSTR, cchcount1 : i32, lpstring2 : windows_sys::core::PCWSTR, cchcount2 : i32) -> COMPARESTRING_RESULT);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn ConvertCalDateTimeToSystemTime(lpcaldatetime : *const CALDATETIME, lpsystime : *mut super::Foundation:: SYSTEMTIME) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn ConvertDefaultLocale(locale : u32) -> u32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn ConvertSystemTimeToCalDateTime(lpsystime : *const super::Foundation:: SYSTEMTIME, calid : u32, lpcaldatetime : *mut CALDATETIME) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumCalendarInfoA(lpcalinfoenumproc : CALINFO_ENUMPROCA, locale : u32, calendar : u32, caltype : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumCalendarInfoExA(lpcalinfoenumprocex : CALINFO_ENUMPROCEXA, locale : u32, calendar : u32, caltype : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumCalendarInfoExEx(pcalinfoenumprocexex : CALINFO_ENUMPROCEXEX, lplocalename : windows_sys::core::PCWSTR, calendar : u32, lpreserved : windows_sys::core::PCWSTR, caltype : u32, lparam : super::Foundation:: LPARAM) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumCalendarInfoExW(lpcalinfoenumprocex : CALINFO_ENUMPROCEXW, locale : u32, calendar : u32, caltype : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumCalendarInfoW(lpcalinfoenumproc : CALINFO_ENUMPROCW, locale : u32, calendar : u32, caltype : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumDateFormatsA(lpdatefmtenumproc : DATEFMT_ENUMPROCA, locale : u32, dwflags : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumDateFormatsExA(lpdatefmtenumprocex : DATEFMT_ENUMPROCEXA, locale : u32, dwflags : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumDateFormatsExEx(lpdatefmtenumprocexex : DATEFMT_ENUMPROCEXEX, lplocalename : windows_sys::core::PCWSTR, dwflags : ENUM_DATE_FORMATS_FLAGS, lparam : super::Foundation:: LPARAM) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumDateFormatsExW(lpdatefmtenumprocex : DATEFMT_ENUMPROCEXW, locale : u32, dwflags : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumDateFormatsW(lpdatefmtenumproc : DATEFMT_ENUMPROCW, locale : u32, dwflags : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumLanguageGroupLocalesA(lplanggrouplocaleenumproc : LANGGROUPLOCALE_ENUMPROCA, languagegroup : u32, dwflags : u32, lparam : isize) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumLanguageGroupLocalesW(lplanggrouplocaleenumproc : LANGGROUPLOCALE_ENUMPROCW, languagegroup : u32, dwflags : u32, lparam : isize) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumSystemCodePagesA(lpcodepageenumproc : CODEPAGE_ENUMPROCA, dwflags : ENUM_SYSTEM_CODE_PAGES_FLAGS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumSystemCodePagesW(lpcodepageenumproc : CODEPAGE_ENUMPROCW, dwflags : ENUM_SYSTEM_CODE_PAGES_FLAGS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumSystemGeoID(geoclass : u32, parentgeoid : i32, lpgeoenumproc : GEO_ENUMPROC) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumSystemGeoNames(geoclass : u32, geoenumproc : GEO_ENUMNAMEPROC, data : super::Foundation:: LPARAM) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumSystemLanguageGroupsA(lplanguagegroupenumproc : LANGUAGEGROUP_ENUMPROCA, dwflags : ENUM_SYSTEM_LANGUAGE_GROUPS_FLAGS, lparam : isize) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumSystemLanguageGroupsW(lplanguagegroupenumproc : LANGUAGEGROUP_ENUMPROCW, dwflags : ENUM_SYSTEM_LANGUAGE_GROUPS_FLAGS, lparam : isize) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumSystemLocalesA(lplocaleenumproc : LOCALE_ENUMPROCA, dwflags : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumSystemLocalesEx(lplocaleenumprocex : LOCALE_ENUMPROCEX, dwflags : u32, lparam : super::Foundation:: LPARAM, lpreserved : *const core::ffi::c_void) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumSystemLocalesW(lplocaleenumproc : LOCALE_ENUMPROCW, dwflags : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumTimeFormatsA(lptimefmtenumproc : TIMEFMT_ENUMPROCA, locale : u32, dwflags : TIME_FORMAT_FLAGS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumTimeFormatsEx(lptimefmtenumprocex : TIMEFMT_ENUMPROCEX, lplocalename : windows_sys::core::PCWSTR, dwflags : u32, lparam : super::Foundation:: LPARAM) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumTimeFormatsW(lptimefmtenumproc : TIMEFMT_ENUMPROCW, locale : u32, dwflags : TIME_FORMAT_FLAGS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumUILanguagesA(lpuilanguageenumproc : UILANGUAGE_ENUMPROCA, dwflags : u32, lparam : isize) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn EnumUILanguagesW(lpuilanguageenumproc : UILANGUAGE_ENUMPROCW, dwflags : u32, lparam : isize) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn FindNLSString(locale : u32, dwfindnlsstringflags : u32, lpstringsource : windows_sys::core::PCWSTR, cchsource : i32, lpstringvalue : windows_sys::core::PCWSTR, cchvalue : i32, pcchfound : *mut i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn FindNLSStringEx(lplocalename : windows_sys::core::PCWSTR, dwfindnlsstringflags : u32, lpstringsource : windows_sys::core::PCWSTR, cchsource : i32, lpstringvalue : windows_sys::core::PCWSTR, cchvalue : i32, pcchfound : *mut i32, lpversioninformation : *const NLSVERSIONINFO, lpreserved : *const core::ffi::c_void, sorthandle : super::Foundation:: LPARAM) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn FindStringOrdinal(dwfindstringordinalflags : u32, lpstringsource : windows_sys::core::PCWSTR, cchsource : i32, lpstringvalue : windows_sys::core::PCWSTR, cchvalue : i32, bignorecase : windows_sys::core::BOOL) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn FoldStringA(dwmapflags : FOLD_STRING_MAP_FLAGS, lpsrcstr : windows_sys::core::PCSTR, cchsrc : i32, lpdeststr : windows_sys::core::PSTR, cchdest : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn FoldStringW(dwmapflags : FOLD_STRING_MAP_FLAGS, lpsrcstr : windows_sys::core::PCWSTR, cchsrc : i32, lpdeststr : windows_sys::core::PWSTR, cchdest : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetACP() -> u32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCPInfo(codepage : u32, lpcpinfo : *mut CPINFO) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCPInfoExA(codepage : u32, dwflags : u32, lpcpinfoex : *mut CPINFOEXA) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCPInfoExW(codepage : u32, dwflags : u32, lpcpinfoex : *mut CPINFOEXW) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCalendarDateFormatEx(lpszlocale : windows_sys::core::PCWSTR, dwflags : u32, lpcaldatetime : *const CALDATETIME, lpformat : windows_sys::core::PCWSTR, lpdatestr : windows_sys::core::PWSTR, cchdate : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCalendarInfoA(locale : u32, calendar : u32, caltype : u32, lpcaldata : windows_sys::core::PSTR, cchdata : i32, lpvalue : *mut u32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCalendarInfoEx(lplocalename : windows_sys::core::PCWSTR, calendar : u32, lpreserved : windows_sys::core::PCWSTR, caltype : u32, lpcaldata : windows_sys::core::PWSTR, cchdata : i32, lpvalue : *mut u32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCalendarInfoW(locale : u32, calendar : u32, caltype : u32, lpcaldata : windows_sys::core::PWSTR, cchdata : i32, lpvalue : *mut u32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCalendarSupportedDateRange(calendar : u32, lpcalmindatetime : *mut CALDATETIME, lpcalmaxdatetime : *mut CALDATETIME) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCurrencyFormatA(locale : u32, dwflags : u32, lpvalue : windows_sys::core::PCSTR, lpformat : *const CURRENCYFMTA, lpcurrencystr : windows_sys::core::PSTR, cchcurrency : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCurrencyFormatEx(lplocalename : windows_sys::core::PCWSTR, dwflags : u32, lpvalue : windows_sys::core::PCWSTR, lpformat : *const CURRENCYFMTW, lpcurrencystr : windows_sys::core::PWSTR, cchcurrency : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetCurrencyFormatW(locale : u32, dwflags : u32, lpvalue : windows_sys::core::PCWSTR, lpformat : *const CURRENCYFMTW, lpcurrencystr : windows_sys::core::PWSTR, cchcurrency : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetDateFormatA(locale : u32, dwflags : u32, lpdate : *const super::Foundation:: SYSTEMTIME, lpformat : windows_sys::core::PCSTR, lpdatestr : windows_sys::core::PSTR, cchdate : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetDateFormatEx(lplocalename : windows_sys::core::PCWSTR, dwflags : ENUM_DATE_FORMATS_FLAGS, lpdate : *const super::Foundation:: SYSTEMTIME, lpformat : windows_sys::core::PCWSTR, lpdatestr : windows_sys::core::PWSTR, cchdate : i32, lpcalendar : windows_sys::core::PCWSTR) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetDateFormatW(locale : u32, dwflags : u32, lpdate : *const super::Foundation:: SYSTEMTIME, lpformat : windows_sys::core::PCWSTR, lpdatestr : windows_sys::core::PWSTR, cchdate : i32) -> i32);\nwindows_link::link!(\"bcp47mrm.dll\" \"system\" fn GetDistanceOfClosestLanguageInList(pszlanguage : windows_sys::core::PCWSTR, pszlanguageslist : windows_sys::core::PCWSTR, wchlistdelimiter : u16, pclosestdistance : *mut f64) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetDurationFormat(locale : u32, dwflags : u32, lpduration : *const super::Foundation:: SYSTEMTIME, ullduration : u64, lpformat : windows_sys::core::PCWSTR, lpdurationstr : windows_sys::core::PWSTR, cchduration : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetDurationFormatEx(lplocalename : windows_sys::core::PCWSTR, dwflags : u32, lpduration : *const super::Foundation:: SYSTEMTIME, ullduration : u64, lpformat : windows_sys::core::PCWSTR, lpdurationstr : windows_sys::core::PWSTR, cchduration : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetFileMUIInfo(dwflags : u32, pcwszfilepath : windows_sys::core::PCWSTR, pfilemuiinfo : *mut FILEMUIINFO, pcbfilemuiinfo : *mut u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetFileMUIPath(dwflags : u32, pcwszfilepath : windows_sys::core::PCWSTR, pwszlanguage : windows_sys::core::PWSTR, pcchlanguage : *mut u32, pwszfilemuipath : windows_sys::core::PWSTR, pcchfilemuipath : *mut u32, pululenumerator : *mut u64) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetGeoInfoA(location : i32, geotype : SYSGEOTYPE, lpgeodata : windows_sys::core::PSTR, cchdata : i32, langid : u16) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetGeoInfoEx(location : windows_sys::core::PCWSTR, geotype : SYSGEOTYPE, geodata : windows_sys::core::PWSTR, geodatacount : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetGeoInfoW(location : i32, geotype : SYSGEOTYPE, lpgeodata : windows_sys::core::PWSTR, cchdata : i32, langid : u16) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetLocaleInfoA(locale : u32, lctype : u32, lplcdata : windows_sys::core::PSTR, cchdata : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetLocaleInfoEx(lplocalename : windows_sys::core::PCWSTR, lctype : u32, lplcdata : windows_sys::core::PWSTR, cchdata : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetLocaleInfoW(locale : u32, lctype : u32, lplcdata : windows_sys::core::PWSTR, cchdata : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetNLSVersion(function : u32, locale : u32, lpversioninformation : *mut NLSVERSIONINFO) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetNLSVersionEx(function : u32, lplocalename : windows_sys::core::PCWSTR, lpversioninformation : *mut NLSVERSIONINFOEX) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetNumberFormatA(locale : u32, dwflags : u32, lpvalue : windows_sys::core::PCSTR, lpformat : *const NUMBERFMTA, lpnumberstr : windows_sys::core::PSTR, cchnumber : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetNumberFormatEx(lplocalename : windows_sys::core::PCWSTR, dwflags : u32, lpvalue : windows_sys::core::PCWSTR, lpformat : *const NUMBERFMTW, lpnumberstr : windows_sys::core::PWSTR, cchnumber : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetNumberFormatW(locale : u32, dwflags : u32, lpvalue : windows_sys::core::PCWSTR, lpformat : *const NUMBERFMTW, lpnumberstr : windows_sys::core::PWSTR, cchnumber : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetOEMCP() -> u32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetProcessPreferredUILanguages(dwflags : u32, pulnumlanguages : *mut u32, pwszlanguagesbuffer : windows_sys::core::PWSTR, pcchlanguagesbuffer : *mut u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetStringScripts(dwflags : u32, lpstring : windows_sys::core::PCWSTR, cchstring : i32, lpscripts : windows_sys::core::PWSTR, cchscripts : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetStringTypeA(locale : u32, dwinfotype : u32, lpsrcstr : windows_sys::core::PCSTR, cchsrc : i32, lpchartype : *mut u16) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetStringTypeExA(locale : u32, dwinfotype : u32, lpsrcstr : windows_sys::core::PCSTR, cchsrc : i32, lpchartype : *mut u16) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetStringTypeExW(locale : u32, dwinfotype : u32, lpsrcstr : windows_sys::core::PCWSTR, cchsrc : i32, lpchartype : *mut u16) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetStringTypeW(dwinfotype : u32, lpsrcstr : windows_sys::core::PCWSTR, cchsrc : i32, lpchartype : *mut u16) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetSystemDefaultLCID() -> u32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetSystemDefaultLangID() -> u16);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetSystemDefaultLocaleName(lplocalename : windows_sys::core::PWSTR, cchlocalename : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetSystemDefaultUILanguage() -> u16);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetSystemPreferredUILanguages(dwflags : u32, pulnumlanguages : *mut u32, pwszlanguagesbuffer : windows_sys::core::PWSTR, pcchlanguagesbuffer : *mut u32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdi32.dll\" \"system\" fn GetTextCharset(hdc : super::Graphics::Gdi:: HDC) -> i32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdi32.dll\" \"system\" fn GetTextCharsetInfo(hdc : super::Graphics::Gdi:: HDC, lpsig : *mut FONTSIGNATURE, dwflags : u32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetThreadLocale() -> u32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetThreadPreferredUILanguages(dwflags : u32, pulnumlanguages : *mut u32, pwszlanguagesbuffer : windows_sys::core::PWSTR, pcchlanguagesbuffer : *mut u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetThreadUILanguage() -> u16);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetTimeFormatA(locale : u32, dwflags : u32, lptime : *const super::Foundation:: SYSTEMTIME, lpformat : windows_sys::core::PCSTR, lptimestr : windows_sys::core::PSTR, cchtime : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetTimeFormatEx(lplocalename : windows_sys::core::PCWSTR, dwflags : TIME_FORMAT_FLAGS, lptime : *const super::Foundation:: SYSTEMTIME, lpformat : windows_sys::core::PCWSTR, lptimestr : windows_sys::core::PWSTR, cchtime : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetTimeFormatW(locale : u32, dwflags : u32, lptime : *const super::Foundation:: SYSTEMTIME, lpformat : windows_sys::core::PCWSTR, lptimestr : windows_sys::core::PWSTR, cchtime : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetUILanguageInfo(dwflags : u32, pwmszlanguage : windows_sys::core::PCWSTR, pwszfallbacklanguages : windows_sys::core::PWSTR, pcchfallbacklanguages : *mut u32, pattributes : *mut u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetUserDefaultGeoName(geoname : windows_sys::core::PWSTR, geonamecount : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetUserDefaultLCID() -> u32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetUserDefaultLangID() -> u16);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetUserDefaultLocaleName(lplocalename : windows_sys::core::PWSTR, cchlocalename : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetUserDefaultUILanguage() -> u16);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetUserGeoID(geoclass : SYSGEOCLASS) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn GetUserPreferredUILanguages(dwflags : u32, pulnumlanguages : *mut u32, pwszlanguagesbuffer : windows_sys::core::PWSTR, pcchlanguagesbuffer : *mut u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"normaliz.dll\" \"system\" fn IdnToAscii(dwflags : u32, lpunicodecharstr : windows_sys::core::PCWSTR, cchunicodechar : i32, lpasciicharstr : windows_sys::core::PWSTR, cchasciichar : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IdnToNameprepUnicode(dwflags : u32, lpunicodecharstr : windows_sys::core::PCWSTR, cchunicodechar : i32, lpnameprepcharstr : windows_sys::core::PWSTR, cchnameprepchar : i32) -> i32);\nwindows_link::link!(\"normaliz.dll\" \"system\" fn IdnToUnicode(dwflags : u32, lpasciicharstr : windows_sys::core::PCWSTR, cchasciichar : i32, lpunicodecharstr : windows_sys::core::PWSTR, cchunicodechar : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IsCalendarLeapYear(calid : u32, year : u32, era : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IsDBCSLeadByte(testchar : u8) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IsDBCSLeadByteEx(codepage : u32, testchar : u8) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IsNLSDefinedString(function : u32, dwflags : u32, lpversioninformation : *const NLSVERSIONINFO, lpstring : windows_sys::core::PCWSTR, cchstr : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IsNormalizedString(normform : NORM_FORM, lpstring : windows_sys::core::PCWSTR, cwlength : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"advapi32.dll\" \"system\" fn IsTextUnicode(lpv : *const core::ffi::c_void, isize : i32, lpiresult : *mut IS_TEXT_UNICODE_RESULT) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IsValidCodePage(codepage : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IsValidLanguageGroup(languagegroup : u32, dwflags : ENUM_SYSTEM_LANGUAGE_GROUPS_FLAGS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IsValidLocale(locale : u32, dwflags : IS_VALID_LOCALE_FLAGS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IsValidLocaleName(lplocalename : windows_sys::core::PCWSTR) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn IsValidNLSVersion(function : u32, lplocalename : windows_sys::core::PCWSTR, lpversioninformation : *const NLSVERSIONINFOEX) -> u32);\nwindows_link::link!(\"bcp47mrm.dll\" \"system\" fn IsWellFormedTag(psztag : windows_sys::core::PCWSTR) -> u8);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn LCIDToLocaleName(locale : u32, lpname : windows_sys::core::PWSTR, cchname : i32, dwflags : u32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn LCMapStringA(locale : u32, dwmapflags : u32, lpsrcstr : windows_sys::core::PCSTR, cchsrc : i32, lpdeststr : windows_sys::core::PSTR, cchdest : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn LCMapStringEx(lplocalename : windows_sys::core::PCWSTR, dwmapflags : u32, lpsrcstr : windows_sys::core::PCWSTR, cchsrc : i32, lpdeststr : windows_sys::core::PWSTR, cchdest : i32, lpversioninformation : *const NLSVERSIONINFO, lpreserved : *const core::ffi::c_void, sorthandle : super::Foundation:: LPARAM) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn LCMapStringW(locale : u32, dwmapflags : u32, lpsrcstr : windows_sys::core::PCWSTR, cchsrc : i32, lpdeststr : windows_sys::core::PWSTR, cchdest : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn LocaleNameToLCID(lpname : windows_sys::core::PCWSTR, dwflags : u32) -> u32);\nwindows_link::link!(\"elscore.dll\" \"system\" fn MappingDoAction(pbag : *mut MAPPING_PROPERTY_BAG, dwrangeindex : u32, pszactionid : windows_sys::core::PCWSTR) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"elscore.dll\" \"system\" fn MappingFreePropertyBag(pbag : *const MAPPING_PROPERTY_BAG) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"elscore.dll\" \"system\" fn MappingFreeServices(pserviceinfo : *const MAPPING_SERVICE_INFO) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"elscore.dll\" \"system\" fn MappingGetServices(poptions : *const MAPPING_ENUM_OPTIONS, prgservices : *mut *mut MAPPING_SERVICE_INFO, pdwservicescount : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"elscore.dll\" \"system\" fn MappingRecognizeText(pserviceinfo : *const MAPPING_SERVICE_INFO, psztext : windows_sys::core::PCWSTR, dwlength : u32, dwindex : u32, poptions : *const MAPPING_OPTIONS, pbag : *mut MAPPING_PROPERTY_BAG) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn MultiByteToWideChar(codepage : u32, dwflags : MULTI_BYTE_TO_WIDE_CHAR_FLAGS, lpmultibytestr : windows_sys::core::PCSTR, cbmultibyte : i32, lpwidecharstr : windows_sys::core::PWSTR, cchwidechar : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn NormalizeString(normform : NORM_FORM, lpsrcstring : windows_sys::core::PCWSTR, cwsrclength : i32, lpdststring : windows_sys::core::PWSTR, cwdstlength : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn NotifyUILanguageChange(dwflags : u32, pcwstrnewlanguage : windows_sys::core::PCWSTR, pcwstrpreviouslanguage : windows_sys::core::PCWSTR, dwreserved : u32, pdwstatusrtrn : *mut u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn ResolveLocaleName(lpnametoresolve : windows_sys::core::PCWSTR, lplocalename : windows_sys::core::PWSTR, cchlocalename : i32) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn RestoreThreadPreferredUILanguages(snapshot : HSAVEDUILANGUAGES));\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptApplyDigitSubstitution(psds : *const SCRIPT_DIGITSUBSTITUTE, psc : *mut SCRIPT_CONTROL, pss : *mut SCRIPT_STATE) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptApplyLogicalWidth(pidx : *const i32, cchars : i32, cglyphs : i32, pwlogclust : *const u16, psva : *const SCRIPT_VISATTR, piadvance : *const i32, psa : *const SCRIPT_ANALYSIS, pabc : *mut super::Graphics::Gdi:: ABC, pijustify : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptBreak(pwcchars : windows_sys::core::PCWSTR, cchars : i32, psa : *const SCRIPT_ANALYSIS, psla : *mut SCRIPT_LOGATTR) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptCPtoX(icp : i32, ftrailing : windows_sys::core::BOOL, cchars : i32, cglyphs : i32, pwlogclust : *const u16, psva : *const SCRIPT_VISATTR, piadvance : *const i32, psa : *const SCRIPT_ANALYSIS, pix : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptCacheGetHeight(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, tmheight : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptFreeCache(psc : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptGetCMap(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, pwcinchars : windows_sys::core::PCWSTR, cchars : i32, dwflags : u32, pwoutglyphs : *mut u16) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptGetFontAlternateGlyphs(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, psa : *const SCRIPT_ANALYSIS, tagscript : u32, taglangsys : u32, tagfeature : u32, wglyphid : u16, cmaxalternates : i32, palternateglyphs : *mut u16, pcalternates : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptGetFontFeatureTags(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, psa : *const SCRIPT_ANALYSIS, tagscript : u32, taglangsys : u32, cmaxtags : i32, pfeaturetags : *mut u32, pctags : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptGetFontLanguageTags(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, psa : *const SCRIPT_ANALYSIS, tagscript : u32, cmaxtags : i32, plangsystags : *mut u32, pctags : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptGetFontProperties(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, sfp : *mut SCRIPT_FONTPROPERTIES) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptGetFontScriptTags(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, psa : *const SCRIPT_ANALYSIS, cmaxtags : i32, pscripttags : *mut u32, pctags : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptGetGlyphABCWidth(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, wglyph : u16, pabc : *mut super::Graphics::Gdi:: ABC) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptGetLogicalWidths(psa : *const SCRIPT_ANALYSIS, cchars : i32, cglyphs : i32, piglyphwidth : *const i32, pwlogclust : *const u16, psva : *const SCRIPT_VISATTR, pidx : *const i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptGetProperties(ppsp : *mut *mut *mut SCRIPT_PROPERTIES, pinumscripts : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptIsComplex(pwcinchars : windows_sys::core::PCWSTR, cinchars : i32, dwflags : SCRIPT_IS_COMPLEX_FLAGS) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptItemize(pwcinchars : windows_sys::core::PCWSTR, cinchars : i32, cmaxitems : i32, pscontrol : *const SCRIPT_CONTROL, psstate : *const SCRIPT_STATE, pitems : *mut SCRIPT_ITEM, pcitems : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptItemizeOpenType(pwcinchars : windows_sys::core::PCWSTR, cinchars : i32, cmaxitems : i32, pscontrol : *const SCRIPT_CONTROL, psstate : *const SCRIPT_STATE, pitems : *mut SCRIPT_ITEM, pscripttags : *mut u32, pcitems : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptJustify(psva : *const SCRIPT_VISATTR, piadvance : *const i32, cglyphs : i32, idx : i32, iminkashida : i32, pijustify : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptLayout(cruns : i32, pblevel : *const u8, pivisualtological : *mut i32, pilogicaltovisual : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptPlace(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, pwglyphs : *const u16, cglyphs : i32, psva : *const SCRIPT_VISATTR, psa : *mut SCRIPT_ANALYSIS, piadvance : *mut i32, pgoffset : *mut GOFFSET, pabc : *mut super::Graphics::Gdi:: ABC) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptPlaceOpenType(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, psa : *mut SCRIPT_ANALYSIS, tagscript : u32, taglangsys : u32, rcrangechars : *const i32, rprangeproperties : *const *const TEXTRANGE_PROPERTIES, cranges : i32, pwcchars : windows_sys::core::PCWSTR, pwlogclust : *const u16, pcharprops : *const SCRIPT_CHARPROP, cchars : i32, pwglyphs : *const u16, pglyphprops : *const SCRIPT_GLYPHPROP, cglyphs : i32, piadvance : *mut i32, pgoffset : *mut GOFFSET, pabc : *mut super::Graphics::Gdi:: ABC) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptPositionSingleGlyph(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, psa : *const SCRIPT_ANALYSIS, tagscript : u32, taglangsys : u32, tagfeature : u32, lparameter : i32, wglyphid : u16, iadvance : i32, goffset : GOFFSET, pioutadvance : *mut i32, poutgoffset : *mut GOFFSET) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptRecordDigitSubstitution(locale : u32, psds : *mut SCRIPT_DIGITSUBSTITUTE) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptShape(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, pwcchars : windows_sys::core::PCWSTR, cchars : i32, cmaxglyphs : i32, psa : *mut SCRIPT_ANALYSIS, pwoutglyphs : *mut u16, pwlogclust : *mut u16, psva : *mut SCRIPT_VISATTR, pcglyphs : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptShapeOpenType(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, psa : *mut SCRIPT_ANALYSIS, tagscript : u32, taglangsys : u32, rcrangechars : *const i32, rprangeproperties : *const *const TEXTRANGE_PROPERTIES, cranges : i32, pwcchars : windows_sys::core::PCWSTR, cchars : i32, cmaxglyphs : i32, pwlogclust : *mut u16, pcharprops : *mut SCRIPT_CHARPROP, pwoutglyphs : *mut u16, poutglyphprops : *mut SCRIPT_GLYPHPROP, pcglyphs : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptStringAnalyse(hdc : super::Graphics::Gdi:: HDC, pstring : *const core::ffi::c_void, cstring : i32, cglyphs : i32, icharset : i32, dwflags : u32, ireqwidth : i32, pscontrol : *const SCRIPT_CONTROL, psstate : *const SCRIPT_STATE, pidx : *const i32, ptabdef : *const SCRIPT_TABDEF, pbinclass : *const u8, pssa : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptStringCPtoX(ssa : *const core::ffi::c_void, icp : i32, ftrailing : windows_sys::core::BOOL, px : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptStringFree(pssa : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptStringGetLogicalWidths(ssa : *const core::ffi::c_void, pidx : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptStringGetOrder(ssa : *const core::ffi::c_void, puorder : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptStringOut(ssa : *const core::ffi::c_void, ix : i32, iy : i32, uoptions : super::Graphics::Gdi:: ETO_OPTIONS, prc : *const super::Foundation:: RECT, iminsel : i32, imaxsel : i32, fdisabled : windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptStringValidate(ssa : *const core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptStringXtoCP(ssa : *const core::ffi::c_void, ix : i32, pich : *mut i32, pitrailing : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptString_pLogAttr(ssa : *const core::ffi::c_void) -> *mut SCRIPT_LOGATTR);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptString_pSize(ssa : *const core::ffi::c_void) -> *mut super::Foundation:: SIZE);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptString_pcOutChars(ssa : *const core::ffi::c_void) -> *mut i32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptSubstituteSingleGlyph(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, psa : *const SCRIPT_ANALYSIS, tagscript : u32, taglangsys : u32, tagfeature : u32, lparameter : i32, wglyphid : u16, pwoutglyphid : *mut u16) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptTextOut(hdc : super::Graphics::Gdi:: HDC, psc : *mut *mut core::ffi::c_void, x : i32, y : i32, fuoptions : u32, lprc : *const super::Foundation:: RECT, psa : *const SCRIPT_ANALYSIS, pwcreserved : windows_sys::core::PCWSTR, ireserved : i32, pwglyphs : *const u16, cglyphs : i32, piadvance : *const i32, pijustify : *const i32, pgoffset : *const GOFFSET) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"usp10.dll\" \"system\" fn ScriptXtoCP(ix : i32, cchars : i32, cglyphs : i32, pwlogclust : *const u16, psva : *const SCRIPT_VISATTR, piadvance : *const i32, psa : *const SCRIPT_ANALYSIS, picp : *mut i32, pitrailing : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetCalendarInfoA(locale : u32, calendar : u32, caltype : u32, lpcaldata : windows_sys::core::PCSTR) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetCalendarInfoW(locale : u32, calendar : u32, caltype : u32, lpcaldata : windows_sys::core::PCWSTR) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetLocaleInfoA(locale : u32, lctype : u32, lplcdata : windows_sys::core::PCSTR) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetLocaleInfoW(locale : u32, lctype : u32, lplcdata : windows_sys::core::PCWSTR) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetProcessPreferredUILanguages(dwflags : u32, pwszlanguagesbuffer : windows_sys::core::PCWSTR, pulnumlanguages : *mut u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetThreadLocale(locale : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetThreadPreferredUILanguages(dwflags : u32, pwszlanguagesbuffer : windows_sys::core::PCWSTR, pulnumlanguages : *mut u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetThreadPreferredUILanguages2(flags : u32, languages : windows_sys::core::PCWSTR, numlanguagesset : *mut u32, snapshot : *mut HSAVEDUILANGUAGES) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetThreadUILanguage(langid : u16) -> u16);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetUserGeoID(geoid : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn SetUserGeoName(geoname : windows_sys::core::PCWSTR) -> windows_sys::core::BOOL);\nwindows_link::link!(\"gdi32.dll\" \"system\" fn TranslateCharsetInfo(lpsrc : *mut u32, lpcs : *mut CHARSETINFO, dwflags : TRANSLATE_CHARSET_INFO_FLAGS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn UCNV_FROM_U_CALLBACK_ESCAPE(context : *const core::ffi::c_void, fromuargs : *mut UConverterFromUnicodeArgs, codeunits : *const u16, length : i32, codepoint : i32, reason : UConverterCallbackReason, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn UCNV_FROM_U_CALLBACK_SKIP(context : *const core::ffi::c_void, fromuargs : *mut UConverterFromUnicodeArgs, codeunits : *const u16, length : i32, codepoint : i32, reason : UConverterCallbackReason, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn UCNV_FROM_U_CALLBACK_STOP(context : *const core::ffi::c_void, fromuargs : *mut UConverterFromUnicodeArgs, codeunits : *const u16, length : i32, codepoint : i32, reason : UConverterCallbackReason, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn UCNV_FROM_U_CALLBACK_SUBSTITUTE(context : *const core::ffi::c_void, fromuargs : *mut UConverterFromUnicodeArgs, codeunits : *const u16, length : i32, codepoint : i32, reason : UConverterCallbackReason, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn UCNV_TO_U_CALLBACK_ESCAPE(context : *const core::ffi::c_void, touargs : *mut UConverterToUnicodeArgs, codeunits : windows_sys::core::PCSTR, length : i32, reason : UConverterCallbackReason, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn UCNV_TO_U_CALLBACK_SKIP(context : *const core::ffi::c_void, touargs : *mut UConverterToUnicodeArgs, codeunits : windows_sys::core::PCSTR, length : i32, reason : UConverterCallbackReason, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn UCNV_TO_U_CALLBACK_STOP(context : *const core::ffi::c_void, touargs : *mut UConverterToUnicodeArgs, codeunits : windows_sys::core::PCSTR, length : i32, reason : UConverterCallbackReason, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn UCNV_TO_U_CALLBACK_SUBSTITUTE(context : *const core::ffi::c_void, touargs : *mut UConverterToUnicodeArgs, codeunits : windows_sys::core::PCSTR, length : i32, reason : UConverterCallbackReason, err : *mut UErrorCode));\nwindows_link::link!(\"kernel32.dll\" \"system\" fn UpdateCalendarDayOfWeek(lpcaldatetime : *mut CALDATETIME) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn VerifyScripts(dwflags : u32, lplocalescripts : windows_sys::core::PCWSTR, cchlocalescripts : i32, lptestscripts : windows_sys::core::PCWSTR, cchtestscripts : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn WideCharToMultiByte(codepage : u32, dwflags : u32, lpwidecharstr : windows_sys::core::PCWSTR, cchwidechar : i32, lpmultibytestr : windows_sys::core::PSTR, cbmultibyte : i32, lpdefaultchar : windows_sys::core::PCSTR, lpuseddefaultchar : *mut windows_sys::core::BOOL) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrcatA(lpstring1 : windows_sys::core::PSTR, lpstring2 : windows_sys::core::PCSTR) -> windows_sys::core::PSTR);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrcatW(lpstring1 : windows_sys::core::PWSTR, lpstring2 : windows_sys::core::PCWSTR) -> windows_sys::core::PWSTR);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrcmpA(lpstring1 : windows_sys::core::PCSTR, lpstring2 : windows_sys::core::PCSTR) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrcmpW(lpstring1 : windows_sys::core::PCWSTR, lpstring2 : windows_sys::core::PCWSTR) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrcmpiA(lpstring1 : windows_sys::core::PCSTR, lpstring2 : windows_sys::core::PCSTR) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrcmpiW(lpstring1 : windows_sys::core::PCWSTR, lpstring2 : windows_sys::core::PCWSTR) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrcpyA(lpstring1 : windows_sys::core::PSTR, lpstring2 : windows_sys::core::PCSTR) -> windows_sys::core::PSTR);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrcpyW(lpstring1 : windows_sys::core::PWSTR, lpstring2 : windows_sys::core::PCWSTR) -> windows_sys::core::PWSTR);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrcpynA(lpstring1 : windows_sys::core::PSTR, lpstring2 : windows_sys::core::PCSTR, imaxlength : i32) -> windows_sys::core::PSTR);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrcpynW(lpstring1 : windows_sys::core::PWSTR, lpstring2 : windows_sys::core::PCWSTR, imaxlength : i32) -> windows_sys::core::PWSTR);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrlenA(lpstring : windows_sys::core::PCSTR) -> i32);\nwindows_link::link!(\"kernel32.dll\" \"system\" fn lstrlenW(lpstring : windows_sys::core::PCWSTR) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_UCharsToChars(us : *const u16, cs : windows_sys::core::PCSTR, length : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_austrcpy(dst : windows_sys::core::PCSTR, src : *const u16) -> windows_sys::core::PSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_austrncpy(dst : windows_sys::core::PCSTR, src : *const u16, n : i32) -> windows_sys::core::PSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_catclose(catd : *mut UResourceBundle));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_catgets(catd : *mut UResourceBundle, set_num : i32, msg_num : i32, s : *const u16, len : *mut i32, ec : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_catopen(name : windows_sys::core::PCSTR, locale : windows_sys::core::PCSTR, ec : *mut UErrorCode) -> *mut UResourceBundle);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_charAge(c : i32, versionarray : *mut u8));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_charDigitValue(c : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_charDirection(c : i32) -> UCharDirection);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_charFromName(namechoice : UCharNameChoice, name : windows_sys::core::PCSTR, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_charMirror(c : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_charName(code : i32, namechoice : UCharNameChoice, buffer : windows_sys::core::PCSTR, bufferlength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_charType(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_charsToUChars(cs : windows_sys::core::PCSTR, us : *mut u16, length : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_cleanup());\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_countChar32(s : *const u16, length : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_digit(ch : i32, radix : i8) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_enumCharNames(start : i32, limit : i32, r#fn : *mut UEnumCharNamesFn, context : *mut core::ffi::c_void, namechoice : UCharNameChoice, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_enumCharTypes(enumrange : *mut UCharEnumTypeRange, context : *const core::ffi::c_void));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_errorName(code : UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_foldCase(c : i32, options : u32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_forDigit(digit : i32, radix : i8) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn u_formatMessage(locale : windows_sys::core::PCSTR, pattern : *const u16, patternlength : i32, result : *mut u16, resultlength : i32, status : *mut UErrorCode, ...) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn u_formatMessageWithError(locale : windows_sys::core::PCSTR, pattern : *const u16, patternlength : i32, result : *mut u16, resultlength : i32, parseerror : *mut UParseError, status : *mut UErrorCode, ...) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getBidiPairedBracket(c : i32) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn u_getBinaryPropertySet(property : UProperty, perrorcode : *mut UErrorCode) -> *mut USet);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getCombiningClass(c : i32) -> u8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getDataVersion(dataversionfillin : *mut u8, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getFC_NFKC_Closure(c : i32, dest : *mut u16, destcapacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn u_getIntPropertyMap(property : UProperty, perrorcode : *mut UErrorCode) -> *mut UCPMap);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getIntPropertyMaxValue(which : UProperty) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getIntPropertyMinValue(which : UProperty) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getIntPropertyValue(c : i32, which : UProperty) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getNumericValue(c : i32) -> f64);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getPropertyEnum(alias : windows_sys::core::PCSTR) -> UProperty);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getPropertyName(property : UProperty, namechoice : UPropertyNameChoice) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getPropertyValueEnum(property : UProperty, alias : windows_sys::core::PCSTR) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getPropertyValueName(property : UProperty, value : i32, namechoice : UPropertyNameChoice) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getUnicodeVersion(versionarray : *mut u8));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_getVersion(versionarray : *mut u8));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_hasBinaryProperty(c : i32, which : UProperty) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_init(status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isIDIgnorable(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isIDPart(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isIDStart(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isISOControl(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isJavaIDPart(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isJavaIDStart(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isJavaSpaceChar(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isMirrored(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isUAlphabetic(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isULowercase(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isUUppercase(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isUWhiteSpace(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isWhitespace(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isalnum(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isalpha(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isbase(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isblank(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_iscntrl(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isdefined(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isdigit(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isgraph(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_islower(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isprint(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_ispunct(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isspace(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_istitle(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isupper(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_isxdigit(c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_memcasecmp(s1 : *const u16, s2 : *const u16, length : i32, options : u32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_memchr(s : *const u16, c : u16, count : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_memchr32(s : *const u16, c : i32, count : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_memcmp(buf1 : *const u16, buf2 : *const u16, count : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_memcmpCodePointOrder(s1 : *const u16, s2 : *const u16, count : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_memcpy(dest : *mut u16, src : *const u16, count : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_memmove(dest : *mut u16, src : *const u16, count : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_memrchr(s : *const u16, c : u16, count : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_memrchr32(s : *const u16, c : i32, count : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_memset(dest : *mut u16, c : u16, count : i32) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn u_parseMessage(locale : windows_sys::core::PCSTR, pattern : *const u16, patternlength : i32, source : *const u16, sourcelength : i32, status : *mut UErrorCode, ...));\nwindows_link::link!(\"icuin.dll\" \"C\" fn u_parseMessageWithError(locale : windows_sys::core::PCSTR, pattern : *const u16, patternlength : i32, source : *const u16, sourcelength : i32, parseerror : *mut UParseError, status : *mut UErrorCode, ...));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_setMemoryFunctions(context : *const core::ffi::c_void, a : *mut UMemAllocFn, r : *mut UMemReallocFn, f : *mut UMemFreeFn, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_shapeArabic(source : *const u16, sourcelength : i32, dest : *mut u16, destsize : i32, options : u32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strCaseCompare(s1 : *const u16, length1 : i32, s2 : *const u16, length2 : i32, options : u32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strCompare(s1 : *const u16, length1 : i32, s2 : *const u16, length2 : i32, codepointorder : i8) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strCompareIter(iter1 : *mut UCharIterator, iter2 : *mut UCharIterator, codepointorder : i8) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strFindFirst(s : *const u16, length : i32, substring : *const u16, sublength : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strFindLast(s : *const u16, length : i32, substring : *const u16, sublength : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strFoldCase(dest : *mut u16, destcapacity : i32, src : *const u16, srclength : i32, options : u32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strFromJavaModifiedUTF8WithSub(dest : *mut u16, destcapacity : i32, pdestlength : *mut i32, src : windows_sys::core::PCSTR, srclength : i32, subchar : i32, pnumsubstitutions : *mut i32, perrorcode : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strFromUTF32(dest : *mut u16, destcapacity : i32, pdestlength : *mut i32, src : *const i32, srclength : i32, perrorcode : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strFromUTF32WithSub(dest : *mut u16, destcapacity : i32, pdestlength : *mut i32, src : *const i32, srclength : i32, subchar : i32, pnumsubstitutions : *mut i32, perrorcode : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strFromUTF8(dest : *mut u16, destcapacity : i32, pdestlength : *mut i32, src : windows_sys::core::PCSTR, srclength : i32, perrorcode : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strFromUTF8Lenient(dest : *mut u16, destcapacity : i32, pdestlength : *mut i32, src : windows_sys::core::PCSTR, srclength : i32, perrorcode : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strFromUTF8WithSub(dest : *mut u16, destcapacity : i32, pdestlength : *mut i32, src : windows_sys::core::PCSTR, srclength : i32, subchar : i32, pnumsubstitutions : *mut i32, perrorcode : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strFromWCS(dest : *mut u16, destcapacity : i32, pdestlength : *mut i32, src : windows_sys::core::PCWSTR, srclength : i32, perrorcode : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strHasMoreChar32Than(s : *const u16, length : i32, number : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strToJavaModifiedUTF8(dest : windows_sys::core::PCSTR, destcapacity : i32, pdestlength : *mut i32, src : *const u16, srclength : i32, perrorcode : *mut UErrorCode) -> windows_sys::core::PSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strToLower(dest : *mut u16, destcapacity : i32, src : *const u16, srclength : i32, locale : windows_sys::core::PCSTR, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strToTitle(dest : *mut u16, destcapacity : i32, src : *const u16, srclength : i32, titleiter : *mut UBreakIterator, locale : windows_sys::core::PCSTR, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strToUTF32(dest : *mut i32, destcapacity : i32, pdestlength : *mut i32, src : *const u16, srclength : i32, perrorcode : *mut UErrorCode) -> *mut i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strToUTF32WithSub(dest : *mut i32, destcapacity : i32, pdestlength : *mut i32, src : *const u16, srclength : i32, subchar : i32, pnumsubstitutions : *mut i32, perrorcode : *mut UErrorCode) -> *mut i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strToUTF8(dest : windows_sys::core::PCSTR, destcapacity : i32, pdestlength : *mut i32, src : *const u16, srclength : i32, perrorcode : *mut UErrorCode) -> windows_sys::core::PSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strToUTF8WithSub(dest : windows_sys::core::PCSTR, destcapacity : i32, pdestlength : *mut i32, src : *const u16, srclength : i32, subchar : i32, pnumsubstitutions : *mut i32, perrorcode : *mut UErrorCode) -> windows_sys::core::PSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strToUpper(dest : *mut u16, destcapacity : i32, src : *const u16, srclength : i32, locale : windows_sys::core::PCSTR, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strToWCS(dest : windows_sys::core::PCWSTR, destcapacity : i32, pdestlength : *mut i32, src : *const u16, srclength : i32, perrorcode : *mut UErrorCode) -> windows_sys::core::PWSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strcasecmp(s1 : *const u16, s2 : *const u16, options : u32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strcat(dst : *mut u16, src : *const u16) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strchr(s : *const u16, c : u16) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strchr32(s : *const u16, c : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strcmp(s1 : *const u16, s2 : *const u16) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strcmpCodePointOrder(s1 : *const u16, s2 : *const u16) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strcpy(dst : *mut u16, src : *const u16) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strcspn(string : *const u16, matchset : *const u16) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strlen(s : *const u16) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strncasecmp(s1 : *const u16, s2 : *const u16, n : i32, options : u32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strncat(dst : *mut u16, src : *const u16, n : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strncmp(ucs1 : *const u16, ucs2 : *const u16, n : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strncmpCodePointOrder(s1 : *const u16, s2 : *const u16, n : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strncpy(dst : *mut u16, src : *const u16, n : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strpbrk(string : *const u16, matchset : *const u16) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strrchr(s : *const u16, c : u16) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strrchr32(s : *const u16, c : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strrstr(s : *const u16, substring : *const u16) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strspn(string : *const u16, matchset : *const u16) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strstr(s : *const u16, substring : *const u16) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_strtok_r(src : *mut u16, delim : *const u16, savestate : *mut *mut u16) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_tolower(c : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_totitle(c : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_toupper(c : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_uastrcpy(dst : *mut u16, src : windows_sys::core::PCSTR) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_uastrncpy(dst : *mut u16, src : windows_sys::core::PCSTR, n : i32) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_unescape(src : windows_sys::core::PCSTR, dest : *mut u16, destcapacity : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_unescapeAt(charat : UNESCAPE_CHAR_AT, offset : *mut i32, length : i32, context : *mut core::ffi::c_void) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_versionFromString(versionarray : *mut u8, versionstring : windows_sys::core::PCSTR));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_versionFromUString(versionarray : *mut u8, versionstring : *const u16));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn u_versionToString(versionarray : *const u8, versionstring : windows_sys::core::PCSTR));\nwindows_link::link!(\"icuin.dll\" \"C\" fn u_vformatMessage(locale : windows_sys::core::PCSTR, pattern : *const u16, patternlength : i32, result : *mut u16, resultlength : i32, ap : *mut i8, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn u_vformatMessageWithError(locale : windows_sys::core::PCSTR, pattern : *const u16, patternlength : i32, result : *mut u16, resultlength : i32, parseerror : *mut UParseError, ap : *mut i8, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn u_vparseMessage(locale : windows_sys::core::PCSTR, pattern : *const u16, patternlength : i32, source : *const u16, sourcelength : i32, ap : *mut i8, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn u_vparseMessageWithError(locale : windows_sys::core::PCSTR, pattern : *const u16, patternlength : i32, source : *const u16, sourcelength : i32, ap : *mut i8, parseerror : *mut UParseError, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_close(pbidi : *mut UBiDi));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_countParagraphs(pbidi : *mut UBiDi) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_countRuns(pbidi : *mut UBiDi, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getBaseDirection(text : *const u16, length : i32) -> UBiDiDirection);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getClassCallback(pbidi : *mut UBiDi, r#fn : *mut UBiDiClassCallback, context : *const *const core::ffi::c_void));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getCustomizedClass(pbidi : *mut UBiDi, c : i32) -> UCharDirection);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getDirection(pbidi : *const UBiDi) -> UBiDiDirection);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getLength(pbidi : *const UBiDi) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getLevelAt(pbidi : *const UBiDi, charindex : i32) -> u8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getLevels(pbidi : *mut UBiDi, perrorcode : *mut UErrorCode) -> *mut u8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getLogicalIndex(pbidi : *mut UBiDi, visualindex : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getLogicalMap(pbidi : *mut UBiDi, indexmap : *mut i32, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getLogicalRun(pbidi : *const UBiDi, logicalposition : i32, plogicallimit : *mut i32, plevel : *mut u8));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getParaLevel(pbidi : *const UBiDi) -> u8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getParagraph(pbidi : *const UBiDi, charindex : i32, pparastart : *mut i32, pparalimit : *mut i32, pparalevel : *mut u8, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getParagraphByIndex(pbidi : *const UBiDi, paraindex : i32, pparastart : *mut i32, pparalimit : *mut i32, pparalevel : *mut u8, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getProcessedLength(pbidi : *const UBiDi) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getReorderingMode(pbidi : *mut UBiDi) -> UBiDiReorderingMode);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getReorderingOptions(pbidi : *mut UBiDi) -> u32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getResultLength(pbidi : *const UBiDi) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getText(pbidi : *const UBiDi) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getVisualIndex(pbidi : *mut UBiDi, logicalindex : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getVisualMap(pbidi : *mut UBiDi, indexmap : *mut i32, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_getVisualRun(pbidi : *mut UBiDi, runindex : i32, plogicalstart : *mut i32, plength : *mut i32) -> UBiDiDirection);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_invertMap(srcmap : *const i32, destmap : *mut i32, length : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_isInverse(pbidi : *mut UBiDi) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_isOrderParagraphsLTR(pbidi : *mut UBiDi) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_open() -> *mut UBiDi);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_openSized(maxlength : i32, maxruncount : i32, perrorcode : *mut UErrorCode) -> *mut UBiDi);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_orderParagraphsLTR(pbidi : *mut UBiDi, orderparagraphsltr : i8));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_reorderLogical(levels : *const u8, length : i32, indexmap : *mut i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_reorderVisual(levels : *const u8, length : i32, indexmap : *mut i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_setClassCallback(pbidi : *mut UBiDi, newfn : UBiDiClassCallback, newcontext : *const core::ffi::c_void, oldfn : *mut UBiDiClassCallback, oldcontext : *const *const core::ffi::c_void, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_setContext(pbidi : *mut UBiDi, prologue : *const u16, prolength : i32, epilogue : *const u16, epilength : i32, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_setInverse(pbidi : *mut UBiDi, isinverse : i8));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_setLine(pparabidi : *const UBiDi, start : i32, limit : i32, plinebidi : *mut UBiDi, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_setPara(pbidi : *mut UBiDi, text : *const u16, length : i32, paralevel : u8, embeddinglevels : *mut u8, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_setReorderingMode(pbidi : *mut UBiDi, reorderingmode : UBiDiReorderingMode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_setReorderingOptions(pbidi : *mut UBiDi, reorderingoptions : u32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_writeReordered(pbidi : *mut UBiDi, dest : *mut u16, destsize : i32, options : u16, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubidi_writeReverse(src : *const u16, srclength : i32, dest : *mut u16, destsize : i32, options : u16, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubiditransform_close(pbiditransform : *mut UBiDiTransform));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubiditransform_open(perrorcode : *mut UErrorCode) -> *mut UBiDiTransform);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubiditransform_transform(pbiditransform : *mut UBiDiTransform, src : *const u16, srclength : i32, dest : *mut u16, destsize : i32, inparalevel : u8, inorder : UBiDiOrder, outparalevel : u8, outorder : UBiDiOrder, domirroring : UBiDiMirroring, shapingoptions : u32, perrorcode : *mut UErrorCode) -> u32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ublock_getCode(c : i32) -> UBlockCode);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_close(bi : *mut UBreakIterator));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_countAvailable() -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_current(bi : *const UBreakIterator) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_first(bi : *mut UBreakIterator) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_following(bi : *mut UBreakIterator, offset : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_getAvailable(index : i32) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_getBinaryRules(bi : *mut UBreakIterator, binaryrules : *mut u8, rulescapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_getLocaleByType(bi : *const UBreakIterator, r#type : ULocDataLocaleType, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_getRuleStatus(bi : *mut UBreakIterator) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_getRuleStatusVec(bi : *mut UBreakIterator, fillinvec : *mut i32, capacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_isBoundary(bi : *mut UBreakIterator, offset : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_last(bi : *mut UBreakIterator) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_next(bi : *mut UBreakIterator) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_open(r#type : UBreakIteratorType, locale : windows_sys::core::PCSTR, text : *const u16, textlength : i32, status : *mut UErrorCode) -> *mut UBreakIterator);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_openBinaryRules(binaryrules : *const u8, ruleslength : i32, text : *const u16, textlength : i32, status : *mut UErrorCode) -> *mut UBreakIterator);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_openRules(rules : *const u16, ruleslength : i32, text : *const u16, textlength : i32, parseerr : *mut UParseError, status : *mut UErrorCode) -> *mut UBreakIterator);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_preceding(bi : *mut UBreakIterator, offset : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_previous(bi : *mut UBreakIterator) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_refreshUText(bi : *mut UBreakIterator, text : *mut UText, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_safeClone(bi : *const UBreakIterator, stackbuffer : *mut core::ffi::c_void, pbuffersize : *mut i32, status : *mut UErrorCode) -> *mut UBreakIterator);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_setText(bi : *mut UBreakIterator, text : *const u16, textlength : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ubrk_setUText(bi : *mut UBreakIterator, text : *mut UText, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_add(cal : *mut *mut core::ffi::c_void, field : UCalendarDateFields, amount : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_clear(calendar : *mut *mut core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_clearField(cal : *mut *mut core::ffi::c_void, field : UCalendarDateFields));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_clone(cal : *const *const core::ffi::c_void, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_close(cal : *mut *mut core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_countAvailable() -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_equivalentTo(cal1 : *const *const core::ffi::c_void, cal2 : *const *const core::ffi::c_void) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_get(cal : *const *const core::ffi::c_void, field : UCalendarDateFields, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getAttribute(cal : *const *const core::ffi::c_void, attr : UCalendarAttribute) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getAvailable(localeindex : i32) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getCanonicalTimeZoneID(id : *const u16, len : i32, result : *mut u16, resultcapacity : i32, issystemid : *mut i8, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getDSTSavings(zoneid : *const u16, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getDayOfWeekType(cal : *const *const core::ffi::c_void, dayofweek : UCalendarDaysOfWeek, status : *mut UErrorCode) -> UCalendarWeekdayType);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getDefaultTimeZone(result : *mut u16, resultcapacity : i32, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getFieldDifference(cal : *mut *mut core::ffi::c_void, target : f64, field : UCalendarDateFields, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getGregorianChange(cal : *const *const core::ffi::c_void, perrorcode : *mut UErrorCode) -> f64);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucal_getHostTimeZone(result : *mut u16, resultcapacity : i32, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getKeywordValuesForLocale(key : windows_sys::core::PCSTR, locale : windows_sys::core::PCSTR, commonlyused : i8, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getLimit(cal : *const *const core::ffi::c_void, field : UCalendarDateFields, r#type : UCalendarLimitType, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getLocaleByType(cal : *const *const core::ffi::c_void, r#type : ULocDataLocaleType, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getMillis(cal : *const *const core::ffi::c_void, status : *mut UErrorCode) -> f64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getNow() -> f64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getTZDataVersion(status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getTimeZoneDisplayName(cal : *const *const core::ffi::c_void, r#type : UCalendarDisplayNameType, locale : windows_sys::core::PCSTR, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getTimeZoneID(cal : *const *const core::ffi::c_void, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getTimeZoneIDForWindowsID(winid : *const u16, len : i32, region : windows_sys::core::PCSTR, id : *mut u16, idcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getTimeZoneTransitionDate(cal : *const *const core::ffi::c_void, r#type : UTimeZoneTransitionType, transition : *mut f64, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getType(cal : *const *const core::ffi::c_void, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getWeekendTransition(cal : *const *const core::ffi::c_void, dayofweek : UCalendarDaysOfWeek, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_getWindowsTimeZoneID(id : *const u16, len : i32, winid : *mut u16, winidcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_inDaylightTime(cal : *const *const core::ffi::c_void, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_isSet(cal : *const *const core::ffi::c_void, field : UCalendarDateFields) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_isWeekend(cal : *const *const core::ffi::c_void, date : f64, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_open(zoneid : *const u16, len : i32, locale : windows_sys::core::PCSTR, r#type : UCalendarType, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_openCountryTimeZones(country : windows_sys::core::PCSTR, ec : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_openTimeZoneIDEnumeration(zonetype : USystemTimeZoneType, region : windows_sys::core::PCSTR, rawoffset : *const i32, ec : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_openTimeZones(ec : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_roll(cal : *mut *mut core::ffi::c_void, field : UCalendarDateFields, amount : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_set(cal : *mut *mut core::ffi::c_void, field : UCalendarDateFields, value : i32));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_setAttribute(cal : *mut *mut core::ffi::c_void, attr : UCalendarAttribute, newvalue : i32));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_setDate(cal : *mut *mut core::ffi::c_void, year : i32, month : i32, date : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_setDateTime(cal : *mut *mut core::ffi::c_void, year : i32, month : i32, date : i32, hour : i32, minute : i32, second : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_setDefaultTimeZone(zoneid : *const u16, ec : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_setGregorianChange(cal : *mut *mut core::ffi::c_void, date : f64, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_setMillis(cal : *mut *mut core::ffi::c_void, datetime : f64, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucal_setTimeZone(cal : *mut *mut core::ffi::c_void, zoneid : *const u16, len : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_close(csm : *mut UCaseMap));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_getBreakIterator(csm : *const UCaseMap) -> *mut UBreakIterator);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_getLocale(csm : *const UCaseMap) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_getOptions(csm : *const UCaseMap) -> u32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_open(locale : windows_sys::core::PCSTR, options : u32, perrorcode : *mut UErrorCode) -> *mut UCaseMap);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_setBreakIterator(csm : *mut UCaseMap, itertoadopt : *mut UBreakIterator, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_setLocale(csm : *mut UCaseMap, locale : windows_sys::core::PCSTR, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_setOptions(csm : *mut UCaseMap, options : u32, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_toTitle(csm : *mut UCaseMap, dest : *mut u16, destcapacity : i32, src : *const u16, srclength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_utf8FoldCase(csm : *const UCaseMap, dest : windows_sys::core::PCSTR, destcapacity : i32, src : windows_sys::core::PCSTR, srclength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_utf8ToLower(csm : *const UCaseMap, dest : windows_sys::core::PCSTR, destcapacity : i32, src : windows_sys::core::PCSTR, srclength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_utf8ToTitle(csm : *mut UCaseMap, dest : windows_sys::core::PCSTR, destcapacity : i32, src : windows_sys::core::PCSTR, srclength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucasemap_utf8ToUpper(csm : *const UCaseMap, dest : windows_sys::core::PCSTR, destcapacity : i32, src : windows_sys::core::PCSTR, srclength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_close(ucfpos : *mut UConstrainedFieldPosition));\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_constrainCategory(ucfpos : *mut UConstrainedFieldPosition, category : i32, ec : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_constrainField(ucfpos : *mut UConstrainedFieldPosition, category : i32, field : i32, ec : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_getCategory(ucfpos : *const UConstrainedFieldPosition, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_getField(ucfpos : *const UConstrainedFieldPosition, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_getIndexes(ucfpos : *const UConstrainedFieldPosition, pstart : *mut i32, plimit : *mut i32, ec : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_getInt64IterationContext(ucfpos : *const UConstrainedFieldPosition, ec : *mut UErrorCode) -> i64);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_matchesField(ucfpos : *const UConstrainedFieldPosition, category : i32, field : i32, ec : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_open(ec : *mut UErrorCode) -> *mut UConstrainedFieldPosition);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_reset(ucfpos : *mut UConstrainedFieldPosition, ec : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_setInt64IterationContext(ucfpos : *mut UConstrainedFieldPosition, context : i64, ec : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn ucfpos_setState(ucfpos : *mut UConstrainedFieldPosition, category : i32, field : i32, start : i32, limit : i32, ec : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_cbFromUWriteBytes(args : *mut UConverterFromUnicodeArgs, source : windows_sys::core::PCSTR, length : i32, offsetindex : i32, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_cbFromUWriteSub(args : *mut UConverterFromUnicodeArgs, offsetindex : i32, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_cbFromUWriteUChars(args : *mut UConverterFromUnicodeArgs, source : *const *const u16, sourcelimit : *const u16, offsetindex : i32, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_cbToUWriteSub(args : *mut UConverterToUnicodeArgs, offsetindex : i32, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_cbToUWriteUChars(args : *mut UConverterToUnicodeArgs, source : *const u16, length : i32, offsetindex : i32, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_close(converter : *mut UConverter));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_compareNames(name1 : windows_sys::core::PCSTR, name2 : windows_sys::core::PCSTR) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_convert(toconvertername : windows_sys::core::PCSTR, fromconvertername : windows_sys::core::PCSTR, target : windows_sys::core::PCSTR, targetcapacity : i32, source : windows_sys::core::PCSTR, sourcelength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_convertEx(targetcnv : *mut UConverter, sourcecnv : *mut UConverter, target : *mut *mut i8, targetlimit : windows_sys::core::PCSTR, source : *const *const i8, sourcelimit : windows_sys::core::PCSTR, pivotstart : *mut u16, pivotsource : *mut *mut u16, pivottarget : *mut *mut u16, pivotlimit : *const u16, reset : i8, flush : i8, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_countAliases(alias : windows_sys::core::PCSTR, perrorcode : *mut UErrorCode) -> u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_countAvailable() -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_countStandards() -> u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_detectUnicodeSignature(source : windows_sys::core::PCSTR, sourcelength : i32, signaturelength : *mut i32, perrorcode : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_fixFileSeparator(cnv : *const UConverter, source : *mut u16, sourcelen : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_flushCache() -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_fromAlgorithmic(cnv : *mut UConverter, algorithmictype : UConverterType, target : windows_sys::core::PCSTR, targetcapacity : i32, source : windows_sys::core::PCSTR, sourcelength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_fromUChars(cnv : *mut UConverter, dest : windows_sys::core::PCSTR, destcapacity : i32, src : *const u16, srclength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_fromUCountPending(cnv : *const UConverter, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_fromUnicode(converter : *mut UConverter, target : *mut *mut i8, targetlimit : windows_sys::core::PCSTR, source : *const *const u16, sourcelimit : *const u16, offsets : *mut i32, flush : i8, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getAlias(alias : windows_sys::core::PCSTR, n : u16, perrorcode : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getAliases(alias : windows_sys::core::PCSTR, aliases : *const *const i8, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getAvailableName(n : i32) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getCCSID(converter : *const UConverter, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getCanonicalName(alias : windows_sys::core::PCSTR, standard : windows_sys::core::PCSTR, perrorcode : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getDefaultName() -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getDisplayName(converter : *const UConverter, displaylocale : windows_sys::core::PCSTR, displayname : *mut u16, displaynamecapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getFromUCallBack(converter : *const UConverter, action : *mut UConverterFromUCallback, context : *const *const core::ffi::c_void));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getInvalidChars(converter : *const UConverter, errbytes : windows_sys::core::PCSTR, len : *mut i8, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getInvalidUChars(converter : *const UConverter, erruchars : *mut u16, len : *mut i8, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getMaxCharSize(converter : *const UConverter) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getMinCharSize(converter : *const UConverter) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getName(converter : *const UConverter, err : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getNextUChar(converter : *mut UConverter, source : *const *const i8, sourcelimit : windows_sys::core::PCSTR, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getPlatform(converter : *const UConverter, err : *mut UErrorCode) -> UConverterPlatform);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getStandard(n : u16, perrorcode : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getStandardName(name : windows_sys::core::PCSTR, standard : windows_sys::core::PCSTR, perrorcode : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getStarters(converter : *const UConverter, starters : *mut i8, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getSubstChars(converter : *const UConverter, subchars : windows_sys::core::PCSTR, len : *mut i8, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getToUCallBack(converter : *const UConverter, action : *mut UConverterToUCallback, context : *const *const core::ffi::c_void));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getType(converter : *const UConverter) -> UConverterType);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_getUnicodeSet(cnv : *const UConverter, setfillin : *mut USet, whichset : UConverterUnicodeSet, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_isAmbiguous(cnv : *const UConverter) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_isFixedWidth(cnv : *mut UConverter, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_open(convertername : windows_sys::core::PCSTR, err : *mut UErrorCode) -> *mut UConverter);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_openAllNames(perrorcode : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_openCCSID(codepage : i32, platform : UConverterPlatform, err : *mut UErrorCode) -> *mut UConverter);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_openPackage(packagename : windows_sys::core::PCSTR, convertername : windows_sys::core::PCSTR, err : *mut UErrorCode) -> *mut UConverter);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_openStandardNames(convname : windows_sys::core::PCSTR, standard : windows_sys::core::PCSTR, perrorcode : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_openU(name : *const u16, err : *mut UErrorCode) -> *mut UConverter);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_reset(converter : *mut UConverter));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_resetFromUnicode(converter : *mut UConverter));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_resetToUnicode(converter : *mut UConverter));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_safeClone(cnv : *const UConverter, stackbuffer : *mut core::ffi::c_void, pbuffersize : *mut i32, status : *mut UErrorCode) -> *mut UConverter);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_setDefaultName(name : windows_sys::core::PCSTR));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_setFallback(cnv : *mut UConverter, usesfallback : i8));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_setFromUCallBack(converter : *mut UConverter, newaction : UConverterFromUCallback, newcontext : *const core::ffi::c_void, oldaction : *mut UConverterFromUCallback, oldcontext : *const *const core::ffi::c_void, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_setSubstChars(converter : *mut UConverter, subchars : windows_sys::core::PCSTR, len : i8, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_setSubstString(cnv : *mut UConverter, s : *const u16, length : i32, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_setToUCallBack(converter : *mut UConverter, newaction : UConverterToUCallback, newcontext : *const core::ffi::c_void, oldaction : *mut UConverterToUCallback, oldcontext : *const *const core::ffi::c_void, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_toAlgorithmic(algorithmictype : UConverterType, cnv : *mut UConverter, target : windows_sys::core::PCSTR, targetcapacity : i32, source : windows_sys::core::PCSTR, sourcelength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_toUChars(cnv : *mut UConverter, dest : *mut u16, destcapacity : i32, src : windows_sys::core::PCSTR, srclength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_toUCountPending(cnv : *const UConverter, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_toUnicode(converter : *mut UConverter, target : *mut *mut u16, targetlimit : *const u16, source : *const *const i8, sourcelimit : windows_sys::core::PCSTR, offsets : *mut i32, flush : i8, err : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnv_usesFallback(cnv : *const UConverter) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnvsel_close(sel : *mut UConverterSelector));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnvsel_open(converterlist : *const *const i8, converterlistsize : i32, excludedcodepoints : *const USet, whichset : UConverterUnicodeSet, status : *mut UErrorCode) -> *mut UConverterSelector);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnvsel_openFromSerialized(buffer : *const core::ffi::c_void, length : i32, status : *mut UErrorCode) -> *mut UConverterSelector);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnvsel_selectForString(sel : *const UConverterSelector, s : *const u16, length : i32, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnvsel_selectForUTF8(sel : *const UConverterSelector, s : windows_sys::core::PCSTR, length : i32, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucnvsel_serialize(sel : *const UConverterSelector, buffer : *mut core::ffi::c_void, buffercapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_cloneBinary(coll : *const UCollator, buffer : *mut u8, capacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_close(coll : *mut UCollator));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_closeElements(elems : *mut UCollationElements));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_countAvailable() -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_equal(coll : *const UCollator, source : *const u16, sourcelength : i32, target : *const u16, targetlength : i32) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getAttribute(coll : *const UCollator, attr : UColAttribute, status : *mut UErrorCode) -> UColAttributeValue);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getAvailable(localeindex : i32) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getBound(source : *const u8, sourcelength : i32, boundtype : UColBoundMode, nooflevels : u32, result : *mut u8, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getContractionsAndExpansions(coll : *const UCollator, contractions : *mut USet, expansions : *mut USet, addprefixes : i8, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getDisplayName(objloc : windows_sys::core::PCSTR, disploc : windows_sys::core::PCSTR, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getEquivalentReorderCodes(reordercode : i32, dest : *mut i32, destcapacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getFunctionalEquivalent(result : windows_sys::core::PCSTR, resultcapacity : i32, keyword : windows_sys::core::PCSTR, locale : windows_sys::core::PCSTR, isavailable : *mut i8, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getKeywordValues(keyword : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getKeywordValuesForLocale(key : windows_sys::core::PCSTR, locale : windows_sys::core::PCSTR, commonlyused : i8, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getKeywords(status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getLocaleByType(coll : *const UCollator, r#type : ULocDataLocaleType, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getMaxExpansion(elems : *const UCollationElements, order : i32) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getMaxVariable(coll : *const UCollator) -> UColReorderCode);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getOffset(elems : *const UCollationElements) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getReorderCodes(coll : *const UCollator, dest : *mut i32, destcapacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getRules(coll : *const UCollator, length : *mut i32) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getRulesEx(coll : *const UCollator, delta : UColRuleOption, buffer : *mut u16, bufferlen : i32) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getSortKey(coll : *const UCollator, source : *const u16, sourcelength : i32, result : *mut u8, resultlength : i32) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getStrength(coll : *const UCollator) -> UColAttributeValue);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getTailoredSet(coll : *const UCollator, status : *mut UErrorCode) -> *mut USet);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getUCAVersion(coll : *const UCollator, info : *mut u8));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getVariableTop(coll : *const UCollator, status : *mut UErrorCode) -> u32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_getVersion(coll : *const UCollator, info : *mut u8));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_greater(coll : *const UCollator, source : *const u16, sourcelength : i32, target : *const u16, targetlength : i32) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_greaterOrEqual(coll : *const UCollator, source : *const u16, sourcelength : i32, target : *const u16, targetlength : i32) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_keyHashCode(key : *const u8, length : i32) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_mergeSortkeys(src1 : *const u8, src1length : i32, src2 : *const u8, src2length : i32, dest : *mut u8, destcapacity : i32) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_next(elems : *mut UCollationElements, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_nextSortKeyPart(coll : *const UCollator, iter : *mut UCharIterator, state : *mut u32, dest : *mut u8, count : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_open(loc : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UCollator);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_openAvailableLocales(status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_openBinary(bin : *const u8, length : i32, base : *const UCollator, status : *mut UErrorCode) -> *mut UCollator);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_openElements(coll : *const UCollator, text : *const u16, textlength : i32, status : *mut UErrorCode) -> *mut UCollationElements);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_openRules(rules : *const u16, ruleslength : i32, normalizationmode : UColAttributeValue, strength : UColAttributeValue, parseerror : *mut UParseError, status : *mut UErrorCode) -> *mut UCollator);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_previous(elems : *mut UCollationElements, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_primaryOrder(order : i32) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_reset(elems : *mut UCollationElements));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_safeClone(coll : *const UCollator, stackbuffer : *mut core::ffi::c_void, pbuffersize : *mut i32, status : *mut UErrorCode) -> *mut UCollator);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_secondaryOrder(order : i32) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_setAttribute(coll : *mut UCollator, attr : UColAttribute, value : UColAttributeValue, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_setMaxVariable(coll : *mut UCollator, group : UColReorderCode, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_setOffset(elems : *mut UCollationElements, offset : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_setReorderCodes(coll : *mut UCollator, reordercodes : *const i32, reordercodeslength : i32, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_setStrength(coll : *mut UCollator, strength : UColAttributeValue));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_setText(elems : *mut UCollationElements, text : *const u16, textlength : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_strcoll(coll : *const UCollator, source : *const u16, sourcelength : i32, target : *const u16, targetlength : i32) -> UCollationResult);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_strcollIter(coll : *const UCollator, siter : *mut UCharIterator, titer : *mut UCharIterator, status : *mut UErrorCode) -> UCollationResult);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_strcollUTF8(coll : *const UCollator, source : windows_sys::core::PCSTR, sourcelength : i32, target : windows_sys::core::PCSTR, targetlength : i32, status : *mut UErrorCode) -> UCollationResult);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucol_tertiaryOrder(order : i32) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucpmap_get(map : *const UCPMap, c : i32) -> u32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucpmap_getRange(map : *const UCPMap, start : i32, option : UCPMapRangeOption, surrogatevalue : u32, filter : *mut UCPMapValueFilter, context : *const core::ffi::c_void, pvalue : *mut u32) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucptrie_close(trie : *mut UCPTrie));\nwindows_link::link!(\"icu.dll\" \"C\" fn ucptrie_get(trie : *const UCPTrie, c : i32) -> u32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucptrie_getRange(trie : *const UCPTrie, start : i32, option : UCPMapRangeOption, surrogatevalue : u32, filter : *mut UCPMapValueFilter, context : *const core::ffi::c_void, pvalue : *mut u32) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucptrie_getType(trie : *const UCPTrie) -> UCPTrieType);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucptrie_getValueWidth(trie : *const UCPTrie) -> UCPTrieValueWidth);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucptrie_internalSmallIndex(trie : *const UCPTrie, c : i32) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucptrie_internalSmallU8Index(trie : *const UCPTrie, lt1 : i32, t2 : u8, t3 : u8) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucptrie_internalU8PrevIndex(trie : *const UCPTrie, c : i32, start : *const u8, src : *const u8) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucptrie_openFromBinary(r#type : UCPTrieType, valuewidth : UCPTrieValueWidth, data : *const core::ffi::c_void, length : i32, pactuallength : *mut i32, perrorcode : *mut UErrorCode) -> *mut UCPTrie);\nwindows_link::link!(\"icu.dll\" \"C\" fn ucptrie_toBinary(trie : *const UCPTrie, data : *mut core::ffi::c_void, capacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_close(ucsd : *mut UCharsetDetector));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_detect(ucsd : *mut UCharsetDetector, status : *mut UErrorCode) -> *mut UCharsetMatch);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_detectAll(ucsd : *mut UCharsetDetector, matchesfound : *mut i32, status : *mut UErrorCode) -> *mut *mut UCharsetMatch);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_enableInputFilter(ucsd : *mut UCharsetDetector, filter : i8) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_getAllDetectableCharsets(ucsd : *const UCharsetDetector, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_getConfidence(ucsm : *const UCharsetMatch, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_getLanguage(ucsm : *const UCharsetMatch, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_getName(ucsm : *const UCharsetMatch, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_getUChars(ucsm : *const UCharsetMatch, buf : *mut u16, cap : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_isInputFilterEnabled(ucsd : *const UCharsetDetector) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_open(status : *mut UErrorCode) -> *mut UCharsetDetector);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_setDeclaredEncoding(ucsd : *mut UCharsetDetector, encoding : windows_sys::core::PCSTR, length : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ucsdet_setText(ucsd : *mut UCharsetDetector, textin : windows_sys::core::PCSTR, len : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_countCurrencies(locale : windows_sys::core::PCSTR, date : f64, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_forLocale(locale : windows_sys::core::PCSTR, buff : *mut u16, buffcapacity : i32, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_forLocaleAndDate(locale : windows_sys::core::PCSTR, date : f64, index : i32, buff : *mut u16, buffcapacity : i32, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_getDefaultFractionDigits(currency : *const u16, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_getDefaultFractionDigitsForUsage(currency : *const u16, usage : UCurrencyUsage, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_getKeywordValuesForLocale(key : windows_sys::core::PCSTR, locale : windows_sys::core::PCSTR, commonlyused : i8, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_getName(currency : *const u16, locale : windows_sys::core::PCSTR, namestyle : UCurrNameStyle, ischoiceformat : *mut i8, len : *mut i32, ec : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_getNumericCode(currency : *const u16) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_getPluralName(currency : *const u16, locale : windows_sys::core::PCSTR, ischoiceformat : *mut i8, pluralcount : windows_sys::core::PCSTR, len : *mut i32, ec : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_getRoundingIncrement(currency : *const u16, ec : *mut UErrorCode) -> f64);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_getRoundingIncrementForUsage(currency : *const u16, usage : UCurrencyUsage, ec : *mut UErrorCode) -> f64);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_isAvailable(isocode : *const u16, from : f64, to : f64, errorcode : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_openISOCurrencies(currtype : u32, perrorcode : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_register(isocode : *const u16, locale : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut core::ffi::c_void);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ucurr_unregister(key : *mut core::ffi::c_void, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_adoptNumberFormat(fmt : *mut *mut core::ffi::c_void, numberformattoadopt : *mut *mut core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_adoptNumberFormatForFields(fmt : *mut *mut core::ffi::c_void, fields : *const u16, numberformattoset : *mut *mut core::ffi::c_void, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_applyPattern(format : *mut *mut core::ffi::c_void, localized : i8, pattern : *const u16, patternlength : i32));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_clone(fmt : *const *const core::ffi::c_void, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_close(format : *mut *mut core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_countAvailable() -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_countSymbols(fmt : *const *const core::ffi::c_void, r#type : UDateFormatSymbolType) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_format(format : *const *const core::ffi::c_void, datetoformat : f64, result : *mut u16, resultlength : i32, position : *mut UFieldPosition, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_formatCalendar(format : *const *const core::ffi::c_void, calendar : *mut *mut core::ffi::c_void, result : *mut u16, capacity : i32, position : *mut UFieldPosition, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_formatCalendarForFields(format : *const *const core::ffi::c_void, calendar : *mut *mut core::ffi::c_void, result : *mut u16, capacity : i32, fpositer : *mut UFieldPositionIterator, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_formatForFields(format : *const *const core::ffi::c_void, datetoformat : f64, result : *mut u16, resultlength : i32, fpositer : *mut UFieldPositionIterator, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_get2DigitYearStart(fmt : *const *const core::ffi::c_void, status : *mut UErrorCode) -> f64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_getAvailable(localeindex : i32) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_getBooleanAttribute(fmt : *const *const core::ffi::c_void, attr : UDateFormatBooleanAttribute, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_getCalendar(fmt : *const *const core::ffi::c_void) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_getContext(fmt : *const *const core::ffi::c_void, r#type : UDisplayContextType, status : *mut UErrorCode) -> UDisplayContext);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_getLocaleByType(fmt : *const *const core::ffi::c_void, r#type : ULocDataLocaleType, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_getNumberFormat(fmt : *const *const core::ffi::c_void) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_getNumberFormatForField(fmt : *const *const core::ffi::c_void, field : u16) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_getSymbols(fmt : *const *const core::ffi::c_void, r#type : UDateFormatSymbolType, symbolindex : i32, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_isLenient(fmt : *const *const core::ffi::c_void) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_open(timestyle : UDateFormatStyle, datestyle : UDateFormatStyle, locale : windows_sys::core::PCSTR, tzid : *const u16, tzidlength : i32, pattern : *const u16, patternlength : i32, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_parse(format : *const *const core::ffi::c_void, text : *const u16, textlength : i32, parsepos : *mut i32, status : *mut UErrorCode) -> f64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_parseCalendar(format : *const *const core::ffi::c_void, calendar : *mut *mut core::ffi::c_void, text : *const u16, textlength : i32, parsepos : *mut i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_set2DigitYearStart(fmt : *mut *mut core::ffi::c_void, d : f64, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_setBooleanAttribute(fmt : *mut *mut core::ffi::c_void, attr : UDateFormatBooleanAttribute, newvalue : i8, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_setCalendar(fmt : *mut *mut core::ffi::c_void, calendartoset : *const *const core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_setContext(fmt : *mut *mut core::ffi::c_void, value : UDisplayContext, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_setLenient(fmt : *mut *mut core::ffi::c_void, islenient : i8));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_setNumberFormat(fmt : *mut *mut core::ffi::c_void, numberformattoset : *const *const core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_setSymbols(format : *mut *mut core::ffi::c_void, r#type : UDateFormatSymbolType, symbolindex : i32, value : *mut u16, valuelength : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_toCalendarDateField(field : UDateFormatField) -> UCalendarDateFields);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udat_toPattern(fmt : *const *const core::ffi::c_void, localized : i8, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_addPattern(dtpg : *mut *mut core::ffi::c_void, pattern : *const u16, patternlength : i32, r#override : i8, conflictingpattern : *mut u16, capacity : i32, plength : *mut i32, perrorcode : *mut UErrorCode) -> UDateTimePatternConflict);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_clone(dtpg : *const *const core::ffi::c_void, perrorcode : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_close(dtpg : *mut *mut core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_getAppendItemFormat(dtpg : *const *const core::ffi::c_void, field : UDateTimePatternField, plength : *mut i32) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_getAppendItemName(dtpg : *const *const core::ffi::c_void, field : UDateTimePatternField, plength : *mut i32) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_getBaseSkeleton(unuseddtpg : *mut *mut core::ffi::c_void, pattern : *const u16, length : i32, baseskeleton : *mut u16, capacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_getBestPattern(dtpg : *mut *mut core::ffi::c_void, skeleton : *const u16, length : i32, bestpattern : *mut u16, capacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_getBestPatternWithOptions(dtpg : *mut *mut core::ffi::c_void, skeleton : *const u16, length : i32, options : UDateTimePatternMatchOptions, bestpattern : *mut u16, capacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_getDateTimeFormat(dtpg : *const *const core::ffi::c_void, plength : *mut i32) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_getDecimal(dtpg : *const *const core::ffi::c_void, plength : *mut i32) -> *mut u16);\nwindows_link::link!(\"icu.dll\" \"C\" fn udatpg_getFieldDisplayName(dtpg : *const *const core::ffi::c_void, field : UDateTimePatternField, width : UDateTimePGDisplayWidth, fieldname : *mut u16, capacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_getPatternForSkeleton(dtpg : *const *const core::ffi::c_void, skeleton : *const u16, skeletonlength : i32, plength : *mut i32) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_getSkeleton(unuseddtpg : *mut *mut core::ffi::c_void, pattern : *const u16, length : i32, skeleton : *mut u16, capacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_open(locale : windows_sys::core::PCSTR, perrorcode : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_openBaseSkeletons(dtpg : *const *const core::ffi::c_void, perrorcode : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_openEmpty(perrorcode : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_openSkeletons(dtpg : *const *const core::ffi::c_void, perrorcode : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_replaceFieldTypes(dtpg : *mut *mut core::ffi::c_void, pattern : *const u16, patternlength : i32, skeleton : *const u16, skeletonlength : i32, dest : *mut u16, destcapacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_replaceFieldTypesWithOptions(dtpg : *mut *mut core::ffi::c_void, pattern : *const u16, patternlength : i32, skeleton : *const u16, skeletonlength : i32, options : UDateTimePatternMatchOptions, dest : *mut u16, destcapacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_setAppendItemFormat(dtpg : *mut *mut core::ffi::c_void, field : UDateTimePatternField, value : *const u16, length : i32));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_setAppendItemName(dtpg : *mut *mut core::ffi::c_void, field : UDateTimePatternField, value : *const u16, length : i32));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_setDateTimeFormat(dtpg : *const *const core::ffi::c_void, dtformat : *const u16, length : i32));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udatpg_setDecimal(dtpg : *mut *mut core::ffi::c_void, decimal : *const u16, length : i32));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udtitvfmt_close(formatter : *mut UDateIntervalFormat));\nwindows_link::link!(\"icu.dll\" \"C\" fn udtitvfmt_closeResult(uresult : *mut UFormattedDateInterval));\nwindows_link::link!(\"icuin.dll\" \"C\" fn udtitvfmt_format(formatter : *const UDateIntervalFormat, fromdate : f64, todate : f64, result : *mut u16, resultcapacity : i32, position : *mut UFieldPosition, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn udtitvfmt_open(locale : windows_sys::core::PCSTR, skeleton : *const u16, skeletonlength : i32, tzid : *const u16, tzidlength : i32, status : *mut UErrorCode) -> *mut UDateIntervalFormat);\nwindows_link::link!(\"icu.dll\" \"C\" fn udtitvfmt_openResult(ec : *mut UErrorCode) -> *mut UFormattedDateInterval);\nwindows_link::link!(\"icu.dll\" \"C\" fn udtitvfmt_resultAsValue(uresult : *const UFormattedDateInterval, ec : *mut UErrorCode) -> *mut UFormattedValue);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uenum_close(en : *mut UEnumeration));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uenum_count(en : *mut UEnumeration, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uenum_next(en : *mut UEnumeration, resultlength : *mut i32, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uenum_openCharStringsEnumeration(strings : *const *const i8, count : i32, ec : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uenum_openUCharStringsEnumeration(strings : *const *const u16, count : i32, ec : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uenum_reset(en : *mut UEnumeration, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uenum_unext(en : *mut UEnumeration, resultlength : *mut i32, status : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufieldpositer_close(fpositer : *mut UFieldPositionIterator));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufieldpositer_next(fpositer : *mut UFieldPositionIterator, beginindex : *mut i32, endindex : *mut i32) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufieldpositer_open(status : *mut UErrorCode) -> *mut UFieldPositionIterator);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_close(fmt : *mut *mut core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_getArrayItemByIndex(fmt : *mut *mut core::ffi::c_void, n : i32, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_getArrayLength(fmt : *const *const core::ffi::c_void, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_getDate(fmt : *const *const core::ffi::c_void, status : *mut UErrorCode) -> f64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_getDecNumChars(fmt : *mut *mut core::ffi::c_void, len : *mut i32, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_getDouble(fmt : *mut *mut core::ffi::c_void, status : *mut UErrorCode) -> f64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_getInt64(fmt : *mut *mut core::ffi::c_void, status : *mut UErrorCode) -> i64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_getLong(fmt : *mut *mut core::ffi::c_void, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_getObject(fmt : *const *const core::ffi::c_void, status : *mut UErrorCode) -> *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_getType(fmt : *const *const core::ffi::c_void, status : *mut UErrorCode) -> UFormattableType);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_getUChars(fmt : *mut *mut core::ffi::c_void, len : *mut i32, status : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_isNumeric(fmt : *const *const core::ffi::c_void) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ufmt_open(status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icu.dll\" \"C\" fn ufmtval_getString(ufmtval : *const UFormattedValue, plength : *mut i32, ec : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icu.dll\" \"C\" fn ufmtval_nextPosition(ufmtval : *const UFormattedValue, ucfpos : *mut UConstrainedFieldPosition, ec : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ugender_getInstance(locale : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UGenderInfo);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ugender_getListGender(genderinfo : *const UGenderInfo, genders : *const UGender, size : i32, status : *mut UErrorCode) -> UGender);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uidna_close(idna : *mut UIDNA));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uidna_labelToASCII(idna : *const UIDNA, label : *const u16, length : i32, dest : *mut u16, capacity : i32, pinfo : *mut UIDNAInfo, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uidna_labelToASCII_UTF8(idna : *const UIDNA, label : windows_sys::core::PCSTR, length : i32, dest : windows_sys::core::PCSTR, capacity : i32, pinfo : *mut UIDNAInfo, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uidna_labelToUnicode(idna : *const UIDNA, label : *const u16, length : i32, dest : *mut u16, capacity : i32, pinfo : *mut UIDNAInfo, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uidna_labelToUnicodeUTF8(idna : *const UIDNA, label : windows_sys::core::PCSTR, length : i32, dest : windows_sys::core::PCSTR, capacity : i32, pinfo : *mut UIDNAInfo, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uidna_nameToASCII(idna : *const UIDNA, name : *const u16, length : i32, dest : *mut u16, capacity : i32, pinfo : *mut UIDNAInfo, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uidna_nameToASCII_UTF8(idna : *const UIDNA, name : windows_sys::core::PCSTR, length : i32, dest : windows_sys::core::PCSTR, capacity : i32, pinfo : *mut UIDNAInfo, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uidna_nameToUnicode(idna : *const UIDNA, name : *const u16, length : i32, dest : *mut u16, capacity : i32, pinfo : *mut UIDNAInfo, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uidna_nameToUnicodeUTF8(idna : *const UIDNA, name : windows_sys::core::PCSTR, length : i32, dest : windows_sys::core::PCSTR, capacity : i32, pinfo : *mut UIDNAInfo, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uidna_openUTS46(options : u32, perrorcode : *mut UErrorCode) -> *mut UIDNA);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uiter_current32(iter : *mut UCharIterator) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uiter_getState(iter : *const UCharIterator) -> u32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uiter_next32(iter : *mut UCharIterator) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uiter_previous32(iter : *mut UCharIterator) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uiter_setState(iter : *mut UCharIterator, state : u32, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uiter_setString(iter : *mut UCharIterator, s : *const u16, length : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uiter_setUTF16BE(iter : *mut UCharIterator, s : windows_sys::core::PCSTR, length : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uiter_setUTF8(iter : *mut UCharIterator, s : windows_sys::core::PCSTR, length : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_close(ldn : *mut ULocaleDisplayNames));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_getContext(ldn : *const ULocaleDisplayNames, r#type : UDisplayContextType, perrorcode : *mut UErrorCode) -> UDisplayContext);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_getDialectHandling(ldn : *const ULocaleDisplayNames) -> UDialectHandling);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_getLocale(ldn : *const ULocaleDisplayNames) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_keyDisplayName(ldn : *const ULocaleDisplayNames, key : windows_sys::core::PCSTR, result : *mut u16, maxresultsize : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_keyValueDisplayName(ldn : *const ULocaleDisplayNames, key : windows_sys::core::PCSTR, value : windows_sys::core::PCSTR, result : *mut u16, maxresultsize : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_languageDisplayName(ldn : *const ULocaleDisplayNames, lang : windows_sys::core::PCSTR, result : *mut u16, maxresultsize : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_localeDisplayName(ldn : *const ULocaleDisplayNames, locale : windows_sys::core::PCSTR, result : *mut u16, maxresultsize : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_open(locale : windows_sys::core::PCSTR, dialecthandling : UDialectHandling, perrorcode : *mut UErrorCode) -> *mut ULocaleDisplayNames);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_openForContext(locale : windows_sys::core::PCSTR, contexts : *mut UDisplayContext, length : i32, perrorcode : *mut UErrorCode) -> *mut ULocaleDisplayNames);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_regionDisplayName(ldn : *const ULocaleDisplayNames, region : windows_sys::core::PCSTR, result : *mut u16, maxresultsize : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_scriptCodeDisplayName(ldn : *const ULocaleDisplayNames, scriptcode : UScriptCode, result : *mut u16, maxresultsize : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_scriptDisplayName(ldn : *const ULocaleDisplayNames, script : windows_sys::core::PCSTR, result : *mut u16, maxresultsize : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uldn_variantDisplayName(ldn : *const ULocaleDisplayNames, variant : windows_sys::core::PCSTR, result : *mut u16, maxresultsize : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ulistfmt_close(listfmt : *mut UListFormatter));\nwindows_link::link!(\"icu.dll\" \"C\" fn ulistfmt_closeResult(uresult : *mut UFormattedList));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ulistfmt_format(listfmt : *const UListFormatter, strings : *const *const u16, stringlengths : *const i32, stringcount : i32, result : *mut u16, resultcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ulistfmt_formatStringsToResult(listfmt : *const UListFormatter, strings : *const *const u16, stringlengths : *const i32, stringcount : i32, uresult : *mut UFormattedList, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ulistfmt_open(locale : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UListFormatter);\nwindows_link::link!(\"icu.dll\" \"C\" fn ulistfmt_openForType(locale : windows_sys::core::PCSTR, r#type : UListFormatterType, width : UListFormatterWidth, status : *mut UErrorCode) -> *mut UListFormatter);\nwindows_link::link!(\"icu.dll\" \"C\" fn ulistfmt_openResult(ec : *mut UErrorCode) -> *mut UFormattedList);\nwindows_link::link!(\"icu.dll\" \"C\" fn ulistfmt_resultAsValue(uresult : *const UFormattedList, ec : *mut UErrorCode) -> *mut UFormattedValue);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_acceptLanguage(result : windows_sys::core::PCSTR, resultavailable : i32, outresult : *mut UAcceptResult, acceptlist : *const *const i8, acceptlistcount : i32, availablelocales : *mut UEnumeration, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_acceptLanguageFromHTTP(result : windows_sys::core::PCSTR, resultavailable : i32, outresult : *mut UAcceptResult, httpacceptlanguage : windows_sys::core::PCSTR, availablelocales : *mut UEnumeration, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_addLikelySubtags(localeid : windows_sys::core::PCSTR, maximizedlocaleid : windows_sys::core::PCSTR, maximizedlocaleidcapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_canonicalize(localeid : windows_sys::core::PCSTR, name : windows_sys::core::PCSTR, namecapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_countAvailable() -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_forLanguageTag(langtag : windows_sys::core::PCSTR, localeid : windows_sys::core::PCSTR, localeidcapacity : i32, parsedlength : *mut i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getAvailable(n : i32) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getBaseName(localeid : windows_sys::core::PCSTR, name : windows_sys::core::PCSTR, namecapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getCharacterOrientation(localeid : windows_sys::core::PCSTR, status : *mut UErrorCode) -> ULayoutType);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getCountry(localeid : windows_sys::core::PCSTR, country : windows_sys::core::PCSTR, countrycapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getDefault() -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getDisplayCountry(locale : windows_sys::core::PCSTR, displaylocale : windows_sys::core::PCSTR, country : *mut u16, countrycapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getDisplayKeyword(keyword : windows_sys::core::PCSTR, displaylocale : windows_sys::core::PCSTR, dest : *mut u16, destcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getDisplayKeywordValue(locale : windows_sys::core::PCSTR, keyword : windows_sys::core::PCSTR, displaylocale : windows_sys::core::PCSTR, dest : *mut u16, destcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getDisplayLanguage(locale : windows_sys::core::PCSTR, displaylocale : windows_sys::core::PCSTR, language : *mut u16, languagecapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getDisplayName(localeid : windows_sys::core::PCSTR, inlocaleid : windows_sys::core::PCSTR, result : *mut u16, maxresultsize : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getDisplayScript(locale : windows_sys::core::PCSTR, displaylocale : windows_sys::core::PCSTR, script : *mut u16, scriptcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getDisplayVariant(locale : windows_sys::core::PCSTR, displaylocale : windows_sys::core::PCSTR, variant : *mut u16, variantcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getISO3Country(localeid : windows_sys::core::PCSTR) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getISO3Language(localeid : windows_sys::core::PCSTR) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getISOCountries() -> *mut *mut i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getISOLanguages() -> *mut *mut i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getKeywordValue(localeid : windows_sys::core::PCSTR, keywordname : windows_sys::core::PCSTR, buffer : windows_sys::core::PCSTR, buffercapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getLCID(localeid : windows_sys::core::PCSTR) -> u32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getLanguage(localeid : windows_sys::core::PCSTR, language : windows_sys::core::PCSTR, languagecapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getLineOrientation(localeid : windows_sys::core::PCSTR, status : *mut UErrorCode) -> ULayoutType);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getLocaleForLCID(hostid : u32, locale : windows_sys::core::PCSTR, localecapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getName(localeid : windows_sys::core::PCSTR, name : windows_sys::core::PCSTR, namecapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getParent(localeid : windows_sys::core::PCSTR, parent : windows_sys::core::PCSTR, parentcapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getScript(localeid : windows_sys::core::PCSTR, script : windows_sys::core::PCSTR, scriptcapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_getVariant(localeid : windows_sys::core::PCSTR, variant : windows_sys::core::PCSTR, variantcapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_isRightToLeft(locale : windows_sys::core::PCSTR) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_minimizeSubtags(localeid : windows_sys::core::PCSTR, minimizedlocaleid : windows_sys::core::PCSTR, minimizedlocaleidcapacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn uloc_openAvailableByType(r#type : ULocAvailableType, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_openKeywords(localeid : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_setDefault(localeid : windows_sys::core::PCSTR, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_setKeywordValue(keywordname : windows_sys::core::PCSTR, keywordvalue : windows_sys::core::PCSTR, buffer : windows_sys::core::PCSTR, buffercapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_toLanguageTag(localeid : windows_sys::core::PCSTR, langtag : windows_sys::core::PCSTR, langtagcapacity : i32, strict : i8, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_toLegacyKey(keyword : windows_sys::core::PCSTR) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_toLegacyType(keyword : windows_sys::core::PCSTR, value : windows_sys::core::PCSTR) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_toUnicodeLocaleKey(keyword : windows_sys::core::PCSTR) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uloc_toUnicodeLocaleType(keyword : windows_sys::core::PCSTR, value : windows_sys::core::PCSTR) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_close(uld : *mut ULocaleData));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_getCLDRVersion(versionarray : *mut u8, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_getDelimiter(uld : *mut ULocaleData, r#type : ULocaleDataDelimiterType, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_getExemplarSet(uld : *mut ULocaleData, fillin : *mut USet, options : u32, extype : ULocaleDataExemplarSetType, status : *mut UErrorCode) -> *mut USet);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_getLocaleDisplayPattern(uld : *mut ULocaleData, pattern : *mut u16, patterncapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_getLocaleSeparator(uld : *mut ULocaleData, separator : *mut u16, separatorcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_getMeasurementSystem(localeid : windows_sys::core::PCSTR, status : *mut UErrorCode) -> UMeasurementSystem);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_getNoSubstitute(uld : *mut ULocaleData) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_getPaperSize(localeid : windows_sys::core::PCSTR, height : *mut i32, width : *mut i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_open(localeid : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut ULocaleData);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ulocdata_setNoSubstitute(uld : *mut ULocaleData, setting : i8));\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_applyPattern(fmt : *mut *mut core::ffi::c_void, pattern : *const u16, patternlength : i32, parseerror : *mut UParseError, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_autoQuoteApostrophe(pattern : *const u16, patternlength : i32, dest : *mut u16, destcapacity : i32, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_clone(fmt : *const *const core::ffi::c_void, status : *mut UErrorCode) -> *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_close(format : *mut *mut core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_format(fmt : *const *const core::ffi::c_void, result : *mut u16, resultlength : i32, status : *mut UErrorCode, ...) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_getLocale(fmt : *const *const core::ffi::c_void) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_open(pattern : *const u16, patternlength : i32, locale : windows_sys::core::PCSTR, parseerror : *mut UParseError, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_parse(fmt : *const *const core::ffi::c_void, source : *const u16, sourcelength : i32, count : *mut i32, status : *mut UErrorCode, ...));\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_setLocale(fmt : *mut *mut core::ffi::c_void, locale : windows_sys::core::PCSTR));\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_toPattern(fmt : *const *const core::ffi::c_void, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_vformat(fmt : *const *const core::ffi::c_void, result : *mut u16, resultlength : i32, ap : *mut i8, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn umsg_vparse(fmt : *const *const core::ffi::c_void, source : *const u16, sourcelength : i32, count : *mut i32, ap : *mut i8, status : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn umutablecptrie_buildImmutable(trie : *mut UMutableCPTrie, r#type : UCPTrieType, valuewidth : UCPTrieValueWidth, perrorcode : *mut UErrorCode) -> *mut UCPTrie);\nwindows_link::link!(\"icu.dll\" \"C\" fn umutablecptrie_clone(other : *const UMutableCPTrie, perrorcode : *mut UErrorCode) -> *mut UMutableCPTrie);\nwindows_link::link!(\"icu.dll\" \"C\" fn umutablecptrie_close(trie : *mut UMutableCPTrie));\nwindows_link::link!(\"icu.dll\" \"C\" fn umutablecptrie_fromUCPMap(map : *const UCPMap, perrorcode : *mut UErrorCode) -> *mut UMutableCPTrie);\nwindows_link::link!(\"icu.dll\" \"C\" fn umutablecptrie_fromUCPTrie(trie : *const UCPTrie, perrorcode : *mut UErrorCode) -> *mut UMutableCPTrie);\nwindows_link::link!(\"icu.dll\" \"C\" fn umutablecptrie_get(trie : *const UMutableCPTrie, c : i32) -> u32);\nwindows_link::link!(\"icu.dll\" \"C\" fn umutablecptrie_getRange(trie : *const UMutableCPTrie, start : i32, option : UCPMapRangeOption, surrogatevalue : u32, filter : *mut UCPMapValueFilter, context : *const core::ffi::c_void, pvalue : *mut u32) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn umutablecptrie_open(initialvalue : u32, errorvalue : u32, perrorcode : *mut UErrorCode) -> *mut UMutableCPTrie);\nwindows_link::link!(\"icu.dll\" \"C\" fn umutablecptrie_set(trie : *mut UMutableCPTrie, c : i32, value : u32, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn umutablecptrie_setRange(trie : *mut UMutableCPTrie, start : i32, end : i32, value : u32, perrorcode : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_append(norm2 : *const UNormalizer2, first : *mut u16, firstlength : i32, firstcapacity : i32, second : *const u16, secondlength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_close(norm2 : *mut UNormalizer2));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_composePair(norm2 : *const UNormalizer2, a : i32, b : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_getCombiningClass(norm2 : *const UNormalizer2, c : i32) -> u8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_getDecomposition(norm2 : *const UNormalizer2, c : i32, decomposition : *mut u16, capacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_getInstance(packagename : windows_sys::core::PCSTR, name : windows_sys::core::PCSTR, mode : UNormalization2Mode, perrorcode : *mut UErrorCode) -> *mut UNormalizer2);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_getNFCInstance(perrorcode : *mut UErrorCode) -> *mut UNormalizer2);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_getNFDInstance(perrorcode : *mut UErrorCode) -> *mut UNormalizer2);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_getNFKCCasefoldInstance(perrorcode : *mut UErrorCode) -> *mut UNormalizer2);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_getNFKCInstance(perrorcode : *mut UErrorCode) -> *mut UNormalizer2);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_getNFKDInstance(perrorcode : *mut UErrorCode) -> *mut UNormalizer2);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_getRawDecomposition(norm2 : *const UNormalizer2, c : i32, decomposition : *mut u16, capacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_hasBoundaryAfter(norm2 : *const UNormalizer2, c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_hasBoundaryBefore(norm2 : *const UNormalizer2, c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_isInert(norm2 : *const UNormalizer2, c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_isNormalized(norm2 : *const UNormalizer2, s : *const u16, length : i32, perrorcode : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_normalize(norm2 : *const UNormalizer2, src : *const u16, length : i32, dest : *mut u16, capacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_normalizeSecondAndAppend(norm2 : *const UNormalizer2, first : *mut u16, firstlength : i32, firstcapacity : i32, second : *const u16, secondlength : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_openFiltered(norm2 : *const UNormalizer2, filterset : *const USet, perrorcode : *mut UErrorCode) -> *mut UNormalizer2);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_quickCheck(norm2 : *const UNormalizer2, s : *const u16, length : i32, perrorcode : *mut UErrorCode) -> UNormalizationCheckResult);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm2_spanQuickCheckYes(norm2 : *const UNormalizer2, s : *const u16, length : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn unorm_compare(s1 : *const u16, length1 : i32, s2 : *const u16, length2 : i32, options : u32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_applyPattern(format : *mut *mut core::ffi::c_void, localized : i8, pattern : *const u16, patternlength : i32, parseerror : *mut UParseError, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_clone(fmt : *const *const core::ffi::c_void, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_close(fmt : *mut *mut core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_countAvailable() -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_format(fmt : *const *const core::ffi::c_void, number : i32, result : *mut u16, resultlength : i32, pos : *mut UFieldPosition, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_formatDecimal(fmt : *const *const core::ffi::c_void, number : windows_sys::core::PCSTR, length : i32, result : *mut u16, resultlength : i32, pos : *mut UFieldPosition, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_formatDouble(fmt : *const *const core::ffi::c_void, number : f64, result : *mut u16, resultlength : i32, pos : *mut UFieldPosition, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_formatDoubleCurrency(fmt : *const *const core::ffi::c_void, number : f64, currency : *mut u16, result : *mut u16, resultlength : i32, pos : *mut UFieldPosition, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_formatDoubleForFields(format : *const *const core::ffi::c_void, number : f64, result : *mut u16, resultlength : i32, fpositer : *mut UFieldPositionIterator, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_formatInt64(fmt : *const *const core::ffi::c_void, number : i64, result : *mut u16, resultlength : i32, pos : *mut UFieldPosition, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_formatUFormattable(fmt : *const *const core::ffi::c_void, number : *const *const core::ffi::c_void, result : *mut u16, resultlength : i32, pos : *mut UFieldPosition, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_getAttribute(fmt : *const *const core::ffi::c_void, attr : UNumberFormatAttribute) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_getAvailable(localeindex : i32) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_getContext(fmt : *const *const core::ffi::c_void, r#type : UDisplayContextType, status : *mut UErrorCode) -> UDisplayContext);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_getDoubleAttribute(fmt : *const *const core::ffi::c_void, attr : UNumberFormatAttribute) -> f64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_getLocaleByType(fmt : *const *const core::ffi::c_void, r#type : ULocDataLocaleType, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_getSymbol(fmt : *const *const core::ffi::c_void, symbol : UNumberFormatSymbol, buffer : *mut u16, size : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_getTextAttribute(fmt : *const *const core::ffi::c_void, tag : UNumberFormatTextAttribute, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_open(style : UNumberFormatStyle, pattern : *const u16, patternlength : i32, locale : windows_sys::core::PCSTR, parseerr : *mut UParseError, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_parse(fmt : *const *const core::ffi::c_void, text : *const u16, textlength : i32, parsepos : *mut i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_parseDecimal(fmt : *const *const core::ffi::c_void, text : *const u16, textlength : i32, parsepos : *mut i32, outbuf : windows_sys::core::PCSTR, outbuflength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_parseDouble(fmt : *const *const core::ffi::c_void, text : *const u16, textlength : i32, parsepos : *mut i32, status : *mut UErrorCode) -> f64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_parseDoubleCurrency(fmt : *const *const core::ffi::c_void, text : *const u16, textlength : i32, parsepos : *mut i32, currency : *mut u16, status : *mut UErrorCode) -> f64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_parseInt64(fmt : *const *const core::ffi::c_void, text : *const u16, textlength : i32, parsepos : *mut i32, status : *mut UErrorCode) -> i64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_parseToUFormattable(fmt : *const *const core::ffi::c_void, result : *mut *mut core::ffi::c_void, text : *const u16, textlength : i32, parsepos : *mut i32, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_setAttribute(fmt : *mut *mut core::ffi::c_void, attr : UNumberFormatAttribute, newvalue : i32));\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_setContext(fmt : *mut *mut core::ffi::c_void, value : UDisplayContext, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_setDoubleAttribute(fmt : *mut *mut core::ffi::c_void, attr : UNumberFormatAttribute, newvalue : f64));\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_setSymbol(fmt : *mut *mut core::ffi::c_void, symbol : UNumberFormatSymbol, value : *const u16, length : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_setTextAttribute(fmt : *mut *mut core::ffi::c_void, tag : UNumberFormatTextAttribute, newvalue : *const u16, newvaluelength : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn unum_toPattern(fmt : *const *const core::ffi::c_void, ispatternlocalized : i8, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_close(uformatter : *mut UNumberFormatter));\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_closeResult(uresult : *mut UFormattedNumber));\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_formatDecimal(uformatter : *const UNumberFormatter, value : windows_sys::core::PCSTR, valuelen : i32, uresult : *mut UFormattedNumber, ec : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_formatDouble(uformatter : *const UNumberFormatter, value : f64, uresult : *mut UFormattedNumber, ec : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_formatInt(uformatter : *const UNumberFormatter, value : i64, uresult : *mut UFormattedNumber, ec : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_openForSkeletonAndLocale(skeleton : *const u16, skeletonlen : i32, locale : windows_sys::core::PCSTR, ec : *mut UErrorCode) -> *mut UNumberFormatter);\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_openForSkeletonAndLocaleWithError(skeleton : *const u16, skeletonlen : i32, locale : windows_sys::core::PCSTR, perror : *mut UParseError, ec : *mut UErrorCode) -> *mut UNumberFormatter);\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_openResult(ec : *mut UErrorCode) -> *mut UFormattedNumber);\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_resultAsValue(uresult : *const UFormattedNumber, ec : *mut UErrorCode) -> *mut UFormattedValue);\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_resultGetAllFieldPositions(uresult : *const UFormattedNumber, ufpositer : *mut UFieldPositionIterator, ec : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_resultNextFieldPosition(uresult : *const UFormattedNumber, ufpos : *mut UFieldPosition, ec : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icu.dll\" \"C\" fn unumf_resultToString(uresult : *const UFormattedNumber, buffer : *mut u16, buffercapacity : i32, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unumsys_close(unumsys : *mut UNumberingSystem));\nwindows_link::link!(\"icuin.dll\" \"C\" fn unumsys_getDescription(unumsys : *const UNumberingSystem, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unumsys_getName(unumsys : *const UNumberingSystem) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unumsys_getRadix(unumsys : *const UNumberingSystem) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unumsys_isAlgorithmic(unumsys : *const UNumberingSystem) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unumsys_open(locale : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UNumberingSystem);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unumsys_openAvailableNames(status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn unumsys_openByName(name : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UNumberingSystem);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uplrules_close(uplrules : *mut UPluralRules));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uplrules_getKeywords(uplrules : *const UPluralRules, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uplrules_open(locale : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UPluralRules);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uplrules_openForType(locale : windows_sys::core::PCSTR, r#type : UPluralType, status : *mut UErrorCode) -> *mut UPluralRules);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uplrules_select(uplrules : *const UPluralRules, number : f64, keyword : *mut u16, capacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn uplrules_selectFormatted(uplrules : *const UPluralRules, number : *const UFormattedNumber, keyword : *mut u16, capacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_appendReplacement(regexp : *mut URegularExpression, replacementtext : *const u16, replacementlength : i32, destbuf : *mut *mut u16, destcapacity : *mut i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_appendReplacementUText(regexp : *mut URegularExpression, replacementtext : *mut UText, dest : *mut UText, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_appendTail(regexp : *mut URegularExpression, destbuf : *mut *mut u16, destcapacity : *mut i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_appendTailUText(regexp : *mut URegularExpression, dest : *mut UText, status : *mut UErrorCode) -> *mut UText);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_clone(regexp : *const URegularExpression, status : *mut UErrorCode) -> *mut URegularExpression);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_close(regexp : *mut URegularExpression));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_end(regexp : *mut URegularExpression, groupnum : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_end64(regexp : *mut URegularExpression, groupnum : i32, status : *mut UErrorCode) -> i64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_find(regexp : *mut URegularExpression, startindex : i32, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_find64(regexp : *mut URegularExpression, startindex : i64, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_findNext(regexp : *mut URegularExpression, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_flags(regexp : *const URegularExpression, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_getFindProgressCallback(regexp : *const URegularExpression, callback : *mut URegexFindProgressCallback, context : *const *const core::ffi::c_void, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_getMatchCallback(regexp : *const URegularExpression, callback : *mut URegexMatchCallback, context : *const *const core::ffi::c_void, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_getStackLimit(regexp : *const URegularExpression, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_getText(regexp : *mut URegularExpression, textlength : *mut i32, status : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_getTimeLimit(regexp : *const URegularExpression, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_getUText(regexp : *mut URegularExpression, dest : *mut UText, status : *mut UErrorCode) -> *mut UText);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_group(regexp : *mut URegularExpression, groupnum : i32, dest : *mut u16, destcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_groupCount(regexp : *mut URegularExpression, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_groupNumberFromCName(regexp : *mut URegularExpression, groupname : windows_sys::core::PCSTR, namelength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_groupNumberFromName(regexp : *mut URegularExpression, groupname : *const u16, namelength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_groupUText(regexp : *mut URegularExpression, groupnum : i32, dest : *mut UText, grouplength : *mut i64, status : *mut UErrorCode) -> *mut UText);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_hasAnchoringBounds(regexp : *const URegularExpression, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_hasTransparentBounds(regexp : *const URegularExpression, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_hitEnd(regexp : *const URegularExpression, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_lookingAt(regexp : *mut URegularExpression, startindex : i32, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_lookingAt64(regexp : *mut URegularExpression, startindex : i64, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_matches(regexp : *mut URegularExpression, startindex : i32, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_matches64(regexp : *mut URegularExpression, startindex : i64, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_open(pattern : *const u16, patternlength : i32, flags : u32, pe : *mut UParseError, status : *mut UErrorCode) -> *mut URegularExpression);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_openC(pattern : windows_sys::core::PCSTR, flags : u32, pe : *mut UParseError, status : *mut UErrorCode) -> *mut URegularExpression);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_openUText(pattern : *mut UText, flags : u32, pe : *mut UParseError, status : *mut UErrorCode) -> *mut URegularExpression);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_pattern(regexp : *const URegularExpression, patlength : *mut i32, status : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_patternUText(regexp : *const URegularExpression, status : *mut UErrorCode) -> *mut UText);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_refreshUText(regexp : *mut URegularExpression, text : *mut UText, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_regionEnd(regexp : *const URegularExpression, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_regionEnd64(regexp : *const URegularExpression, status : *mut UErrorCode) -> i64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_regionStart(regexp : *const URegularExpression, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_regionStart64(regexp : *const URegularExpression, status : *mut UErrorCode) -> i64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_replaceAll(regexp : *mut URegularExpression, replacementtext : *const u16, replacementlength : i32, destbuf : *mut u16, destcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_replaceAllUText(regexp : *mut URegularExpression, replacement : *mut UText, dest : *mut UText, status : *mut UErrorCode) -> *mut UText);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_replaceFirst(regexp : *mut URegularExpression, replacementtext : *const u16, replacementlength : i32, destbuf : *mut u16, destcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_replaceFirstUText(regexp : *mut URegularExpression, replacement : *mut UText, dest : *mut UText, status : *mut UErrorCode) -> *mut UText);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_requireEnd(regexp : *const URegularExpression, status : *mut UErrorCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_reset(regexp : *mut URegularExpression, index : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_reset64(regexp : *mut URegularExpression, index : i64, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_setFindProgressCallback(regexp : *mut URegularExpression, callback : URegexFindProgressCallback, context : *const core::ffi::c_void, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_setMatchCallback(regexp : *mut URegularExpression, callback : URegexMatchCallback, context : *const core::ffi::c_void, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_setRegion(regexp : *mut URegularExpression, regionstart : i32, regionlimit : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_setRegion64(regexp : *mut URegularExpression, regionstart : i64, regionlimit : i64, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_setRegionAndStart(regexp : *mut URegularExpression, regionstart : i64, regionlimit : i64, startindex : i64, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_setStackLimit(regexp : *mut URegularExpression, limit : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_setText(regexp : *mut URegularExpression, text : *const u16, textlength : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_setTimeLimit(regexp : *mut URegularExpression, limit : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_setUText(regexp : *mut URegularExpression, text : *mut UText, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_split(regexp : *mut URegularExpression, destbuf : *mut u16, destcapacity : i32, requiredcapacity : *mut i32, destfields : *mut *mut u16, destfieldscapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_splitUText(regexp : *mut URegularExpression, destfields : *mut *mut UText, destfieldscapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_start(regexp : *mut URegularExpression, groupnum : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_start64(regexp : *mut URegularExpression, groupnum : i32, status : *mut UErrorCode) -> i64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_useAnchoringBounds(regexp : *mut URegularExpression, b : i8, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregex_useTransparentBounds(regexp : *mut URegularExpression, b : i8, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_areEqual(uregion : *const URegion, otherregion : *const URegion) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_contains(uregion : *const URegion, otherregion : *const URegion) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getAvailable(r#type : URegionType, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getContainedRegions(uregion : *const URegion, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getContainedRegionsOfType(uregion : *const URegion, r#type : URegionType, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getContainingRegion(uregion : *const URegion) -> *mut URegion);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getContainingRegionOfType(uregion : *const URegion, r#type : URegionType) -> *mut URegion);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getNumericCode(uregion : *const URegion) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getPreferredValues(uregion : *const URegion, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getRegionCode(uregion : *const URegion) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getRegionFromCode(regioncode : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut URegion);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getRegionFromNumericCode(code : i32, status : *mut UErrorCode) -> *mut URegion);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uregion_getType(uregion : *const URegion) -> URegionType);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ureldatefmt_close(reldatefmt : *mut URelativeDateTimeFormatter));\nwindows_link::link!(\"icu.dll\" \"C\" fn ureldatefmt_closeResult(ufrdt : *mut UFormattedRelativeDateTime));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ureldatefmt_combineDateAndTime(reldatefmt : *const URelativeDateTimeFormatter, relativedatestring : *const u16, relativedatestringlen : i32, timestring : *const u16, timestringlen : i32, result : *mut u16, resultcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ureldatefmt_format(reldatefmt : *const URelativeDateTimeFormatter, offset : f64, unit : URelativeDateTimeUnit, result : *mut u16, resultcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn ureldatefmt_formatNumeric(reldatefmt : *const URelativeDateTimeFormatter, offset : f64, unit : URelativeDateTimeUnit, result : *mut u16, resultcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icu.dll\" \"C\" fn ureldatefmt_formatNumericToResult(reldatefmt : *const URelativeDateTimeFormatter, offset : f64, unit : URelativeDateTimeUnit, result : *mut UFormattedRelativeDateTime, status : *mut UErrorCode));\nwindows_link::link!(\"icu.dll\" \"C\" fn ureldatefmt_formatToResult(reldatefmt : *const URelativeDateTimeFormatter, offset : f64, unit : URelativeDateTimeUnit, result : *mut UFormattedRelativeDateTime, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn ureldatefmt_open(locale : windows_sys::core::PCSTR, nftoadopt : *mut *mut core::ffi::c_void, width : UDateRelativeDateTimeFormatterStyle, capitalizationcontext : UDisplayContext, status : *mut UErrorCode) -> *mut URelativeDateTimeFormatter);\nwindows_link::link!(\"icu.dll\" \"C\" fn ureldatefmt_openResult(ec : *mut UErrorCode) -> *mut UFormattedRelativeDateTime);\nwindows_link::link!(\"icu.dll\" \"C\" fn ureldatefmt_resultAsValue(ufrdt : *const UFormattedRelativeDateTime, ec : *mut UErrorCode) -> *mut UFormattedValue);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_close(resourcebundle : *mut UResourceBundle));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getBinary(resourcebundle : *const UResourceBundle, len : *mut i32, status : *mut UErrorCode) -> *mut u8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getByIndex(resourcebundle : *const UResourceBundle, indexr : i32, fillin : *mut UResourceBundle, status : *mut UErrorCode) -> *mut UResourceBundle);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getByKey(resourcebundle : *const UResourceBundle, key : windows_sys::core::PCSTR, fillin : *mut UResourceBundle, status : *mut UErrorCode) -> *mut UResourceBundle);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getInt(resourcebundle : *const UResourceBundle, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getIntVector(resourcebundle : *const UResourceBundle, len : *mut i32, status : *mut UErrorCode) -> *mut i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getKey(resourcebundle : *const UResourceBundle) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getLocaleByType(resourcebundle : *const UResourceBundle, r#type : ULocDataLocaleType, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getNextResource(resourcebundle : *mut UResourceBundle, fillin : *mut UResourceBundle, status : *mut UErrorCode) -> *mut UResourceBundle);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getNextString(resourcebundle : *mut UResourceBundle, len : *mut i32, key : *const *const i8, status : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getSize(resourcebundle : *const UResourceBundle) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getString(resourcebundle : *const UResourceBundle, len : *mut i32, status : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getStringByIndex(resourcebundle : *const UResourceBundle, indexs : i32, len : *mut i32, status : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getStringByKey(resb : *const UResourceBundle, key : windows_sys::core::PCSTR, len : *mut i32, status : *mut UErrorCode) -> *mut u16);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getType(resourcebundle : *const UResourceBundle) -> UResType);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getUInt(resourcebundle : *const UResourceBundle, status : *mut UErrorCode) -> u32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getUTF8String(resb : *const UResourceBundle, dest : windows_sys::core::PCSTR, length : *mut i32, forcecopy : i8, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getUTF8StringByIndex(resb : *const UResourceBundle, stringindex : i32, dest : windows_sys::core::PCSTR, plength : *mut i32, forcecopy : i8, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getUTF8StringByKey(resb : *const UResourceBundle, key : windows_sys::core::PCSTR, dest : windows_sys::core::PCSTR, plength : *mut i32, forcecopy : i8, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_getVersion(resb : *const UResourceBundle, versioninfo : *mut u8));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_hasNext(resourcebundle : *const UResourceBundle) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_open(packagename : windows_sys::core::PCSTR, locale : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UResourceBundle);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_openAvailableLocales(packagename : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_openDirect(packagename : windows_sys::core::PCSTR, locale : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UResourceBundle);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_openU(packagename : *const u16, locale : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UResourceBundle);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn ures_resetIterator(resourcebundle : *mut UResourceBundle));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_breaksBetweenLetters(script : UScriptCode) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_getCode(nameorabbrorlocale : windows_sys::core::PCSTR, fillin : *mut UScriptCode, capacity : i32, err : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_getName(scriptcode : UScriptCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_getSampleString(script : UScriptCode, dest : *mut u16, capacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_getScript(codepoint : i32, err : *mut UErrorCode) -> UScriptCode);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_getScriptExtensions(c : i32, scripts : *mut UScriptCode, capacity : i32, errorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_getShortName(scriptcode : UScriptCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_getUsage(script : UScriptCode) -> UScriptUsage);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_hasScript(c : i32, sc : UScriptCode) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_isCased(script : UScriptCode) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uscript_isRightToLeft(script : UScriptCode) -> i8);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_close(searchiter : *mut UStringSearch));\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_first(strsrch : *mut UStringSearch, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_following(strsrch : *mut UStringSearch, position : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_getAttribute(strsrch : *const UStringSearch, attribute : USearchAttribute) -> USearchAttributeValue);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_getBreakIterator(strsrch : *const UStringSearch) -> *mut UBreakIterator);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_getCollator(strsrch : *const UStringSearch) -> *mut UCollator);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_getMatchedLength(strsrch : *const UStringSearch) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_getMatchedStart(strsrch : *const UStringSearch) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_getMatchedText(strsrch : *const UStringSearch, result : *mut u16, resultcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_getOffset(strsrch : *const UStringSearch) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_getPattern(strsrch : *const UStringSearch, length : *mut i32) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_getText(strsrch : *const UStringSearch, length : *mut i32) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_last(strsrch : *mut UStringSearch, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_next(strsrch : *mut UStringSearch, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_open(pattern : *const u16, patternlength : i32, text : *const u16, textlength : i32, locale : windows_sys::core::PCSTR, breakiter : *mut UBreakIterator, status : *mut UErrorCode) -> *mut UStringSearch);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_openFromCollator(pattern : *const u16, patternlength : i32, text : *const u16, textlength : i32, collator : *const UCollator, breakiter : *mut UBreakIterator, status : *mut UErrorCode) -> *mut UStringSearch);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_preceding(strsrch : *mut UStringSearch, position : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_previous(strsrch : *mut UStringSearch, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_reset(strsrch : *mut UStringSearch));\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_setAttribute(strsrch : *mut UStringSearch, attribute : USearchAttribute, value : USearchAttributeValue, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_setBreakIterator(strsrch : *mut UStringSearch, breakiter : *mut UBreakIterator, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_setCollator(strsrch : *mut UStringSearch, collator : *const UCollator, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_setOffset(strsrch : *mut UStringSearch, position : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_setPattern(strsrch : *mut UStringSearch, pattern : *const u16, patternlength : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn usearch_setText(strsrch : *mut UStringSearch, text : *const u16, textlength : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_add(set : *mut USet, c : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_addAll(set : *mut USet, additionalset : *const USet));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_addAllCodePoints(set : *mut USet, str : *const u16, strlen : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_addRange(set : *mut USet, start : i32, end : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_addString(set : *mut USet, str : *const u16, strlen : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_applyIntPropertyValue(set : *mut USet, prop : UProperty, value : i32, ec : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_applyPattern(set : *mut USet, pattern : *const u16, patternlength : i32, options : u32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_applyPropertyAlias(set : *mut USet, prop : *const u16, proplength : i32, value : *const u16, valuelength : i32, ec : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_charAt(set : *const USet, charindex : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_clear(set : *mut USet));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_clone(set : *const USet) -> *mut USet);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_cloneAsThawed(set : *const USet) -> *mut USet);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_close(set : *mut USet));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_closeOver(set : *mut USet, attributes : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_compact(set : *mut USet));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_complement(set : *mut USet));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_complementAll(set : *mut USet, complement : *const USet));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_contains(set : *const USet, c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_containsAll(set1 : *const USet, set2 : *const USet) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_containsAllCodePoints(set : *const USet, str : *const u16, strlen : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_containsNone(set1 : *const USet, set2 : *const USet) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_containsRange(set : *const USet, start : i32, end : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_containsSome(set1 : *const USet, set2 : *const USet) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_containsString(set : *const USet, str : *const u16, strlen : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_equals(set1 : *const USet, set2 : *const USet) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_freeze(set : *mut USet));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_getItem(set : *const USet, itemindex : i32, start : *mut i32, end : *mut i32, str : *mut u16, strcapacity : i32, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_getItemCount(set : *const USet) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_getSerializedRange(set : *const USerializedSet, rangeindex : i32, pstart : *mut i32, pend : *mut i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_getSerializedRangeCount(set : *const USerializedSet) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_getSerializedSet(fillset : *mut USerializedSet, src : *const u16, srclength : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_indexOf(set : *const USet, c : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_isEmpty(set : *const USet) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_isFrozen(set : *const USet) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_open(start : i32, end : i32) -> *mut USet);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_openEmpty() -> *mut USet);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_openPattern(pattern : *const u16, patternlength : i32, ec : *mut UErrorCode) -> *mut USet);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_openPatternOptions(pattern : *const u16, patternlength : i32, options : u32, ec : *mut UErrorCode) -> *mut USet);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_remove(set : *mut USet, c : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_removeAll(set : *mut USet, removeset : *const USet));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_removeAllStrings(set : *mut USet));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_removeRange(set : *mut USet, start : i32, end : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_removeString(set : *mut USet, str : *const u16, strlen : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_resemblesPattern(pattern : *const u16, patternlength : i32, pos : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_retain(set : *mut USet, start : i32, end : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_retainAll(set : *mut USet, retain : *const USet));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_serialize(set : *const USet, dest : *mut u16, destcapacity : i32, perrorcode : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_serializedContains(set : *const USerializedSet, c : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_set(set : *mut USet, start : i32, end : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_setSerializedToOne(fillset : *mut USerializedSet, c : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_size(set : *const USet) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_span(set : *const USet, s : *const u16, length : i32, spancondition : USetSpanCondition) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_spanBack(set : *const USet, s : *const u16, length : i32, spancondition : USetSpanCondition) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_spanBackUTF8(set : *const USet, s : windows_sys::core::PCSTR, length : i32, spancondition : USetSpanCondition) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_spanUTF8(set : *const USet, s : windows_sys::core::PCSTR, length : i32, spancondition : USetSpanCondition) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn uset_toPattern(set : *const USet, result : *mut u16, resultcapacity : i32, escapeunprintable : i8, ec : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_areConfusable(sc : *const USpoofChecker, id1 : *const u16, length1 : i32, id2 : *const u16, length2 : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_areConfusableUTF8(sc : *const USpoofChecker, id1 : windows_sys::core::PCSTR, length1 : i32, id2 : windows_sys::core::PCSTR, length2 : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_check(sc : *const USpoofChecker, id : *const u16, length : i32, position : *mut i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_check2(sc : *const USpoofChecker, id : *const u16, length : i32, checkresult : *mut USpoofCheckResult, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_check2UTF8(sc : *const USpoofChecker, id : windows_sys::core::PCSTR, length : i32, checkresult : *mut USpoofCheckResult, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_checkUTF8(sc : *const USpoofChecker, id : windows_sys::core::PCSTR, length : i32, position : *mut i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_clone(sc : *const USpoofChecker, status : *mut UErrorCode) -> *mut USpoofChecker);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_close(sc : *mut USpoofChecker));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_closeCheckResult(checkresult : *mut USpoofCheckResult));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getAllowedChars(sc : *const USpoofChecker, status : *mut UErrorCode) -> *mut USet);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getAllowedLocales(sc : *mut USpoofChecker, status : *mut UErrorCode) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getCheckResultChecks(checkresult : *const USpoofCheckResult, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getCheckResultNumerics(checkresult : *const USpoofCheckResult, status : *mut UErrorCode) -> *mut USet);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getCheckResultRestrictionLevel(checkresult : *const USpoofCheckResult, status : *mut UErrorCode) -> URestrictionLevel);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getChecks(sc : *const USpoofChecker, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getInclusionSet(status : *mut UErrorCode) -> *mut USet);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getRecommendedSet(status : *mut UErrorCode) -> *mut USet);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getRestrictionLevel(sc : *const USpoofChecker) -> URestrictionLevel);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getSkeleton(sc : *const USpoofChecker, r#type : u32, id : *const u16, length : i32, dest : *mut u16, destcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_getSkeletonUTF8(sc : *const USpoofChecker, r#type : u32, id : windows_sys::core::PCSTR, length : i32, dest : windows_sys::core::PCSTR, destcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_open(status : *mut UErrorCode) -> *mut USpoofChecker);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_openCheckResult(status : *mut UErrorCode) -> *mut USpoofCheckResult);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_openFromSerialized(data : *const core::ffi::c_void, length : i32, pactuallength : *mut i32, perrorcode : *mut UErrorCode) -> *mut USpoofChecker);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_openFromSource(confusables : windows_sys::core::PCSTR, confusableslen : i32, confusableswholescript : windows_sys::core::PCSTR, confusableswholescriptlen : i32, errtype : *mut i32, pe : *mut UParseError, status : *mut UErrorCode) -> *mut USpoofChecker);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_serialize(sc : *mut USpoofChecker, data : *mut core::ffi::c_void, capacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_setAllowedChars(sc : *mut USpoofChecker, chars : *const USet, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_setAllowedLocales(sc : *mut USpoofChecker, localeslist : windows_sys::core::PCSTR, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_setChecks(sc : *mut USpoofChecker, checks : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn uspoof_setRestrictionLevel(sc : *mut USpoofChecker, restrictionlevel : URestrictionLevel));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn usprep_close(profile : *mut UStringPrepProfile));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn usprep_open(path : windows_sys::core::PCSTR, filename : windows_sys::core::PCSTR, status : *mut UErrorCode) -> *mut UStringPrepProfile);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn usprep_openByType(r#type : UStringPrepProfileType, status : *mut UErrorCode) -> *mut UStringPrepProfile);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn usprep_prepare(prep : *const UStringPrepProfile, src : *const u16, srclength : i32, dest : *mut u16, destcapacity : i32, options : i32, parseerror : *mut UParseError, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_char32At(ut : *mut UText, nativeindex : i64) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_clone(dest : *mut UText, src : *const UText, deep : i8, readonly : i8, status : *mut UErrorCode) -> *mut UText);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_close(ut : *mut UText) -> *mut UText);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_copy(ut : *mut UText, nativestart : i64, nativelimit : i64, destindex : i64, r#move : i8, status : *mut UErrorCode));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_current32(ut : *mut UText) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_equals(a : *const UText, b : *const UText) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_extract(ut : *mut UText, nativestart : i64, nativelimit : i64, dest : *mut u16, destcapacity : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_freeze(ut : *mut UText));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_getNativeIndex(ut : *const UText) -> i64);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_getPreviousNativeIndex(ut : *mut UText) -> i64);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_hasMetaData(ut : *const UText) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_isLengthExpensive(ut : *const UText) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_isWritable(ut : *const UText) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_moveIndex32(ut : *mut UText, delta : i32) -> i8);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_nativeLength(ut : *mut UText) -> i64);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_next32(ut : *mut UText) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_next32From(ut : *mut UText, nativeindex : i64) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_openUChars(ut : *mut UText, s : *const u16, length : i64, status : *mut UErrorCode) -> *mut UText);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_openUTF8(ut : *mut UText, s : windows_sys::core::PCSTR, length : i64, status : *mut UErrorCode) -> *mut UText);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_previous32(ut : *mut UText) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_previous32From(ut : *mut UText, nativeindex : i64) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_replace(ut : *mut UText, nativestart : i64, nativelimit : i64, replacementtext : *const u16, replacementlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_setNativeIndex(ut : *mut UText, nativeindex : i64));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utext_setup(ut : *mut UText, extraspace : i32, status : *mut UErrorCode) -> *mut UText);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utf8_appendCharSafeBody(s : *mut u8, i : i32, length : i32, c : i32, piserror : *mut i8) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utf8_back1SafeBody(s : *const u8, start : i32, i : i32) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utf8_nextCharSafeBody(s : *const u8, pi : *mut i32, length : i32, c : i32, strict : i8) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utf8_prevCharSafeBody(s : *const u8, start : i32, pi : *mut i32, c : i32, strict : i8) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utmscale_fromInt64(othertime : i64, timescale : UDateTimeScale, status : *mut UErrorCode) -> i64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utmscale_getTimeScaleValue(timescale : UDateTimeScale, value : UTimeScaleValue, status : *mut UErrorCode) -> i64);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utmscale_toInt64(universaltime : i64, timescale : UDateTimeScale, status : *mut UErrorCode) -> i64);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utrace_format(outbuf : windows_sys::core::PCSTR, capacity : i32, indent : i32, fmt : windows_sys::core::PCSTR, ...) -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utrace_functionName(fnnumber : i32) -> windows_sys::core::PCSTR);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utrace_getFunctions(context : *const *const core::ffi::c_void, e : *mut UTraceEntry, x : *mut UTraceExit, d : *mut UTraceData));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utrace_getLevel() -> i32);\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utrace_setFunctions(context : *const core::ffi::c_void, e : UTraceEntry, x : UTraceExit, d : UTraceData));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utrace_setLevel(tracelevel : i32));\nwindows_link::link!(\"icuuc.dll\" \"C\" fn utrace_vformat(outbuf : windows_sys::core::PCSTR, capacity : i32, indent : i32, fmt : windows_sys::core::PCSTR, args : *mut i8) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_clone(trans : *const *const core::ffi::c_void, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_close(trans : *mut *mut core::ffi::c_void));\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_countAvailableIDs() -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_getSourceSet(trans : *const *const core::ffi::c_void, ignorefilter : i8, fillin : *mut USet, status : *mut UErrorCode) -> *mut USet);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_getUnicodeID(trans : *const *const core::ffi::c_void, resultlength : *mut i32) -> *mut u16);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_openIDs(perrorcode : *mut UErrorCode) -> *mut UEnumeration);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_openInverse(trans : *const *const core::ffi::c_void, status : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_openU(id : *const u16, idlength : i32, dir : UTransDirection, rules : *const u16, ruleslength : i32, parseerror : *mut UParseError, perrorcode : *mut UErrorCode) -> *mut *mut core::ffi::c_void);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_register(adoptedtrans : *mut *mut core::ffi::c_void, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_setFilter(trans : *mut *mut core::ffi::c_void, filterpattern : *const u16, filterpatternlen : i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_toRules(trans : *const *const core::ffi::c_void, escapeunprintable : i8, result : *mut u16, resultlength : i32, status : *mut UErrorCode) -> i32);\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_trans(trans : *const *const core::ffi::c_void, rep : *mut *mut core::ffi::c_void, repfunc : *const UReplaceableCallbacks, start : i32, limit : *mut i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_transIncremental(trans : *const *const core::ffi::c_void, rep : *mut *mut core::ffi::c_void, repfunc : *const UReplaceableCallbacks, pos : *mut UTransPosition, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_transIncrementalUChars(trans : *const *const core::ffi::c_void, text : *mut u16, textlength : *mut i32, textcapacity : i32, pos : *mut UTransPosition, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_transUChars(trans : *const *const core::ffi::c_void, text : *mut u16, textlength : *mut i32, textcapacity : i32, start : i32, limit : *mut i32, status : *mut UErrorCode));\nwindows_link::link!(\"icuin.dll\" \"C\" fn utrans_unregisterID(id : *const u16, idlength : i32));\npub const ALL_SERVICES: u32 = 0u32;\npub const ALL_SERVICE_TYPES: u32 = 0u32;\npub const C1_ALPHA: u32 = 256u32;\npub const C1_BLANK: u32 = 64u32;\npub const C1_CNTRL: u32 = 32u32;\npub const C1_DEFINED: u32 = 512u32;\npub const C1_DIGIT: u32 = 4u32;\npub const C1_LOWER: u32 = 2u32;\npub const C1_PUNCT: u32 = 16u32;\npub const C1_SPACE: u32 = 8u32;\npub const C1_UPPER: u32 = 1u32;\npub const C1_XDIGIT: u32 = 128u32;\npub const C2_ARABICNUMBER: u32 = 6u32;\npub const C2_BLOCKSEPARATOR: u32 = 8u32;\npub const C2_COMMONSEPARATOR: u32 = 7u32;\npub const C2_EUROPENUMBER: u32 = 3u32;\npub const C2_EUROPESEPARATOR: u32 = 4u32;\npub const C2_EUROPETERMINATOR: u32 = 5u32;\npub const C2_LEFTTORIGHT: u32 = 1u32;\npub const C2_NOTAPPLICABLE: u32 = 0u32;\npub const C2_OTHERNEUTRAL: u32 = 11u32;\npub const C2_RIGHTTOLEFT: u32 = 2u32;\npub const C2_SEGMENTSEPARATOR: u32 = 9u32;\npub const C2_WHITESPACE: u32 = 10u32;\npub const C3_ALPHA: u32 = 32768u32;\npub const C3_DIACRITIC: u32 = 2u32;\npub const C3_FULLWIDTH: u32 = 128u32;\npub const C3_HALFWIDTH: u32 = 64u32;\npub const C3_HIGHSURROGATE: u32 = 2048u32;\npub const C3_HIRAGANA: u32 = 32u32;\npub const C3_IDEOGRAPH: u32 = 256u32;\npub const C3_KASHIDA: u32 = 512u32;\npub const C3_KATAKANA: u32 = 16u32;\npub const C3_LEXICAL: u32 = 1024u32;\npub const C3_LOWSURROGATE: u32 = 4096u32;\npub const C3_NONSPACING: u32 = 1u32;\npub const C3_NOTAPPLICABLE: u32 = 0u32;\npub const C3_SYMBOL: u32 = 8u32;\npub const C3_VOWELMARK: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CALDATETIME {\n    pub CalId: u32,\n    pub Era: u32,\n    pub Year: u32,\n    pub Month: u32,\n    pub Day: u32,\n    pub DayOfWeek: u32,\n    pub Hour: u32,\n    pub Minute: u32,\n    pub Second: u32,\n    pub Tick: u32,\n}\npub type CALDATETIME_DATEUNIT = i32;\npub type CALINFO_ENUMPROCA = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCSTR) -> windows_sys::core::BOOL>;\npub type CALINFO_ENUMPROCEXA = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCSTR, param1: u32) -> windows_sys::core::BOOL>;\npub type CALINFO_ENUMPROCEXEX = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR, param1: u32, param2: windows_sys::core::PCWSTR, param3: super::Foundation::LPARAM) -> windows_sys::core::BOOL>;\npub type CALINFO_ENUMPROCEXW = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR, param1: u32) -> windows_sys::core::BOOL>;\npub type CALINFO_ENUMPROCW = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR) -> windows_sys::core::BOOL>;\npub const CAL_GREGORIAN: u32 = 1u32;\npub const CAL_GREGORIAN_ARABIC: u32 = 10u32;\npub const CAL_GREGORIAN_ME_FRENCH: u32 = 9u32;\npub const CAL_GREGORIAN_US: u32 = 2u32;\npub const CAL_GREGORIAN_XLIT_ENGLISH: u32 = 11u32;\npub const CAL_GREGORIAN_XLIT_FRENCH: u32 = 12u32;\npub const CAL_HEBREW: u32 = 8u32;\npub const CAL_HIJRI: u32 = 6u32;\npub const CAL_ICALINTVALUE: u32 = 1u32;\npub const CAL_ITWODIGITYEARMAX: u32 = 48u32;\npub const CAL_IYEAROFFSETRANGE: u32 = 3u32;\npub const CAL_JAPAN: u32 = 3u32;\npub const CAL_KOREA: u32 = 5u32;\npub const CAL_NOUSEROVERRIDE: u32 = 2147483648u32;\npub const CAL_PERSIAN: u32 = 22u32;\npub const CAL_RETURN_GENITIVE_NAMES: u32 = 268435456u32;\npub const CAL_RETURN_NUMBER: u32 = 536870912u32;\npub const CAL_SABBREVDAYNAME1: u32 = 14u32;\npub const CAL_SABBREVDAYNAME2: u32 = 15u32;\npub const CAL_SABBREVDAYNAME3: u32 = 16u32;\npub const CAL_SABBREVDAYNAME4: u32 = 17u32;\npub const CAL_SABBREVDAYNAME5: u32 = 18u32;\npub const CAL_SABBREVDAYNAME6: u32 = 19u32;\npub const CAL_SABBREVDAYNAME7: u32 = 20u32;\npub const CAL_SABBREVERASTRING: u32 = 57u32;\npub const CAL_SABBREVMONTHNAME1: u32 = 34u32;\npub const CAL_SABBREVMONTHNAME10: u32 = 43u32;\npub const CAL_SABBREVMONTHNAME11: u32 = 44u32;\npub const CAL_SABBREVMONTHNAME12: u32 = 45u32;\npub const CAL_SABBREVMONTHNAME13: u32 = 46u32;\npub const CAL_SABBREVMONTHNAME2: u32 = 35u32;\npub const CAL_SABBREVMONTHNAME3: u32 = 36u32;\npub const CAL_SABBREVMONTHNAME4: u32 = 37u32;\npub const CAL_SABBREVMONTHNAME5: u32 = 38u32;\npub const CAL_SABBREVMONTHNAME6: u32 = 39u32;\npub const CAL_SABBREVMONTHNAME7: u32 = 40u32;\npub const CAL_SABBREVMONTHNAME8: u32 = 41u32;\npub const CAL_SABBREVMONTHNAME9: u32 = 42u32;\npub const CAL_SCALNAME: u32 = 2u32;\npub const CAL_SDAYNAME1: u32 = 7u32;\npub const CAL_SDAYNAME2: u32 = 8u32;\npub const CAL_SDAYNAME3: u32 = 9u32;\npub const CAL_SDAYNAME4: u32 = 10u32;\npub const CAL_SDAYNAME5: u32 = 11u32;\npub const CAL_SDAYNAME6: u32 = 12u32;\npub const CAL_SDAYNAME7: u32 = 13u32;\npub const CAL_SENGLISHABBREVERANAME: u32 = 60u32;\npub const CAL_SENGLISHERANAME: u32 = 59u32;\npub const CAL_SERASTRING: u32 = 4u32;\npub const CAL_SJAPANESEERAFIRSTYEAR: u32 = 61u32;\npub const CAL_SLONGDATE: u32 = 6u32;\npub const CAL_SMONTHDAY: u32 = 56u32;\npub const CAL_SMONTHNAME1: u32 = 21u32;\npub const CAL_SMONTHNAME10: u32 = 30u32;\npub const CAL_SMONTHNAME11: u32 = 31u32;\npub const CAL_SMONTHNAME12: u32 = 32u32;\npub const CAL_SMONTHNAME13: u32 = 33u32;\npub const CAL_SMONTHNAME2: u32 = 22u32;\npub const CAL_SMONTHNAME3: u32 = 23u32;\npub const CAL_SMONTHNAME4: u32 = 24u32;\npub const CAL_SMONTHNAME5: u32 = 25u32;\npub const CAL_SMONTHNAME6: u32 = 26u32;\npub const CAL_SMONTHNAME7: u32 = 27u32;\npub const CAL_SMONTHNAME8: u32 = 28u32;\npub const CAL_SMONTHNAME9: u32 = 29u32;\npub const CAL_SRELATIVELONGDATE: u32 = 58u32;\npub const CAL_SSHORTDATE: u32 = 5u32;\npub const CAL_SSHORTESTDAYNAME1: u32 = 49u32;\npub const CAL_SSHORTESTDAYNAME2: u32 = 50u32;\npub const CAL_SSHORTESTDAYNAME3: u32 = 51u32;\npub const CAL_SSHORTESTDAYNAME4: u32 = 52u32;\npub const CAL_SSHORTESTDAYNAME5: u32 = 53u32;\npub const CAL_SSHORTESTDAYNAME6: u32 = 54u32;\npub const CAL_SSHORTESTDAYNAME7: u32 = 55u32;\npub const CAL_SYEARMONTH: u32 = 47u32;\npub const CAL_TAIWAN: u32 = 4u32;\npub const CAL_THAI: u32 = 7u32;\npub const CAL_UMALQURA: u32 = 23u32;\npub const CAL_USE_CP_ACP: u32 = 1073741824u32;\npub const CANITER_SKIP_ZEROES: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CHARSETINFO {\n    pub ciCharset: u32,\n    pub ciACP: u32,\n    pub fs: FONTSIGNATURE,\n}\npub const CMLangConvertCharset: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd66d6f99_cdaa_11d0_b822_00c04fc9b31f);\npub const CMLangString: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc04d65cf_b70d_11d0_b188_00aa0038c969);\npub const CMultiLanguage: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x275c23e2_3747_11d0_9fea_00aa003f8646);\npub type CODEPAGE_ENUMPROCA = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCSTR) -> windows_sys::core::BOOL>;\npub type CODEPAGE_ENUMPROCW = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR) -> windows_sys::core::BOOL>;\npub type COMPARESTRING_RESULT = i32;\npub const COMPARE_STRING: SYSNLS_FUNCTION = 1i32;\npub type COMPARE_STRING_FLAGS = u32;\npub type CORRECTIVE_ACTION = i32;\npub const CORRECTIVE_ACTION_DELETE: CORRECTIVE_ACTION = 3i32;\npub const CORRECTIVE_ACTION_GET_SUGGESTIONS: CORRECTIVE_ACTION = 1i32;\npub const CORRECTIVE_ACTION_NONE: CORRECTIVE_ACTION = 0i32;\npub const CORRECTIVE_ACTION_REPLACE: CORRECTIVE_ACTION = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CPINFO {\n    pub MaxCharSize: u32,\n    pub DefaultChar: [u8; 2],\n    pub LeadByte: [u8; 12],\n}\nimpl Default for CPINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CPINFOEXA {\n    pub MaxCharSize: u32,\n    pub DefaultChar: [u8; 2],\n    pub LeadByte: [u8; 12],\n    pub UnicodeDefaultChar: u16,\n    pub CodePage: u32,\n    pub CodePageName: [i8; 260],\n}\nimpl Default for CPINFOEXA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CPINFOEXW {\n    pub MaxCharSize: u32,\n    pub DefaultChar: [u8; 2],\n    pub LeadByte: [u8; 12],\n    pub UnicodeDefaultChar: u16,\n    pub CodePage: u32,\n    pub CodePageName: [u16; 260],\n}\nimpl Default for CPINFOEXW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CPIOD_FORCE_PROMPT: i32 = -2147483648i32;\npub const CPIOD_PEEK: i32 = 1073741824i32;\npub const CP_ACP: u32 = 0u32;\npub const CP_INSTALLED: ENUM_SYSTEM_CODE_PAGES_FLAGS = 1u32;\npub const CP_MACCP: u32 = 2u32;\npub const CP_OEMCP: u32 = 1u32;\npub const CP_SUPPORTED: ENUM_SYSTEM_CODE_PAGES_FLAGS = 2u32;\npub const CP_SYMBOL: u32 = 42u32;\npub const CP_THREAD_ACP: u32 = 3u32;\npub const CP_UTF7: u32 = 65000u32;\npub const CP_UTF8: u32 = 65001u32;\npub const CSTR_EQUAL: COMPARESTRING_RESULT = 2i32;\npub const CSTR_GREATER_THAN: COMPARESTRING_RESULT = 3i32;\npub const CSTR_LESS_THAN: COMPARESTRING_RESULT = 1i32;\npub const CTRY_ALBANIA: u32 = 355u32;\npub const CTRY_ALGERIA: u32 = 213u32;\npub const CTRY_ARGENTINA: u32 = 54u32;\npub const CTRY_ARMENIA: u32 = 374u32;\npub const CTRY_AUSTRALIA: u32 = 61u32;\npub const CTRY_AUSTRIA: u32 = 43u32;\npub const CTRY_AZERBAIJAN: u32 = 994u32;\npub const CTRY_BAHRAIN: u32 = 973u32;\npub const CTRY_BELARUS: u32 = 375u32;\npub const CTRY_BELGIUM: u32 = 32u32;\npub const CTRY_BELIZE: u32 = 501u32;\npub const CTRY_BOLIVIA: u32 = 591u32;\npub const CTRY_BRAZIL: u32 = 55u32;\npub const CTRY_BRUNEI_DARUSSALAM: u32 = 673u32;\npub const CTRY_BULGARIA: u32 = 359u32;\npub const CTRY_CANADA: u32 = 2u32;\npub const CTRY_CARIBBEAN: u32 = 1u32;\npub const CTRY_CHILE: u32 = 56u32;\npub const CTRY_COLOMBIA: u32 = 57u32;\npub const CTRY_COSTA_RICA: u32 = 506u32;\npub const CTRY_CROATIA: u32 = 385u32;\npub const CTRY_CZECH: u32 = 420u32;\npub const CTRY_DEFAULT: u32 = 0u32;\npub const CTRY_DENMARK: u32 = 45u32;\npub const CTRY_DOMINICAN_REPUBLIC: u32 = 1u32;\npub const CTRY_ECUADOR: u32 = 593u32;\npub const CTRY_EGYPT: u32 = 20u32;\npub const CTRY_EL_SALVADOR: u32 = 503u32;\npub const CTRY_ESTONIA: u32 = 372u32;\npub const CTRY_FAEROE_ISLANDS: u32 = 298u32;\npub const CTRY_FINLAND: u32 = 358u32;\npub const CTRY_FRANCE: u32 = 33u32;\npub const CTRY_GEORGIA: u32 = 995u32;\npub const CTRY_GERMANY: u32 = 49u32;\npub const CTRY_GREECE: u32 = 30u32;\npub const CTRY_GUATEMALA: u32 = 502u32;\npub const CTRY_HONDURAS: u32 = 504u32;\npub const CTRY_HONG_KONG: u32 = 852u32;\npub const CTRY_HUNGARY: u32 = 36u32;\npub const CTRY_ICELAND: u32 = 354u32;\npub const CTRY_INDIA: u32 = 91u32;\npub const CTRY_INDONESIA: u32 = 62u32;\npub const CTRY_IRAN: u32 = 981u32;\npub const CTRY_IRAQ: u32 = 964u32;\npub const CTRY_IRELAND: u32 = 353u32;\npub const CTRY_ISRAEL: u32 = 972u32;\npub const CTRY_ITALY: u32 = 39u32;\npub const CTRY_JAMAICA: u32 = 1u32;\npub const CTRY_JAPAN: u32 = 81u32;\npub const CTRY_JORDAN: u32 = 962u32;\npub const CTRY_KAZAKSTAN: u32 = 7u32;\npub const CTRY_KENYA: u32 = 254u32;\npub const CTRY_KUWAIT: u32 = 965u32;\npub const CTRY_KYRGYZSTAN: u32 = 996u32;\npub const CTRY_LATVIA: u32 = 371u32;\npub const CTRY_LEBANON: u32 = 961u32;\npub const CTRY_LIBYA: u32 = 218u32;\npub const CTRY_LIECHTENSTEIN: u32 = 41u32;\npub const CTRY_LITHUANIA: u32 = 370u32;\npub const CTRY_LUXEMBOURG: u32 = 352u32;\npub const CTRY_MACAU: u32 = 853u32;\npub const CTRY_MACEDONIA: u32 = 389u32;\npub const CTRY_MALAYSIA: u32 = 60u32;\npub const CTRY_MALDIVES: u32 = 960u32;\npub const CTRY_MEXICO: u32 = 52u32;\npub const CTRY_MONACO: u32 = 33u32;\npub const CTRY_MONGOLIA: u32 = 976u32;\npub const CTRY_MOROCCO: u32 = 212u32;\npub const CTRY_NETHERLANDS: u32 = 31u32;\npub const CTRY_NEW_ZEALAND: u32 = 64u32;\npub const CTRY_NICARAGUA: u32 = 505u32;\npub const CTRY_NORWAY: u32 = 47u32;\npub const CTRY_OMAN: u32 = 968u32;\npub const CTRY_PAKISTAN: u32 = 92u32;\npub const CTRY_PANAMA: u32 = 507u32;\npub const CTRY_PARAGUAY: u32 = 595u32;\npub const CTRY_PERU: u32 = 51u32;\npub const CTRY_PHILIPPINES: u32 = 63u32;\npub const CTRY_POLAND: u32 = 48u32;\npub const CTRY_PORTUGAL: u32 = 351u32;\npub const CTRY_PRCHINA: u32 = 86u32;\npub const CTRY_PUERTO_RICO: u32 = 1u32;\npub const CTRY_QATAR: u32 = 974u32;\npub const CTRY_ROMANIA: u32 = 40u32;\npub const CTRY_RUSSIA: u32 = 7u32;\npub const CTRY_SAUDI_ARABIA: u32 = 966u32;\npub const CTRY_SERBIA: u32 = 381u32;\npub const CTRY_SINGAPORE: u32 = 65u32;\npub const CTRY_SLOVAK: u32 = 421u32;\npub const CTRY_SLOVENIA: u32 = 386u32;\npub const CTRY_SOUTH_AFRICA: u32 = 27u32;\npub const CTRY_SOUTH_KOREA: u32 = 82u32;\npub const CTRY_SPAIN: u32 = 34u32;\npub const CTRY_SWEDEN: u32 = 46u32;\npub const CTRY_SWITZERLAND: u32 = 41u32;\npub const CTRY_SYRIA: u32 = 963u32;\npub const CTRY_TAIWAN: u32 = 886u32;\npub const CTRY_TATARSTAN: u32 = 7u32;\npub const CTRY_THAILAND: u32 = 66u32;\npub const CTRY_TRINIDAD_Y_TOBAGO: u32 = 1u32;\npub const CTRY_TUNISIA: u32 = 216u32;\npub const CTRY_TURKEY: u32 = 90u32;\npub const CTRY_UAE: u32 = 971u32;\npub const CTRY_UKRAINE: u32 = 380u32;\npub const CTRY_UNITED_KINGDOM: u32 = 44u32;\npub const CTRY_UNITED_STATES: u32 = 1u32;\npub const CTRY_URUGUAY: u32 = 598u32;\npub const CTRY_UZBEKISTAN: u32 = 7u32;\npub const CTRY_VENEZUELA: u32 = 58u32;\npub const CTRY_VIET_NAM: u32 = 84u32;\npub const CTRY_YEMEN: u32 = 967u32;\npub const CTRY_ZIMBABWE: u32 = 263u32;\npub const CT_CTYPE1: u32 = 1u32;\npub const CT_CTYPE2: u32 = 2u32;\npub const CT_CTYPE3: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CURRENCYFMTA {\n    pub NumDigits: u32,\n    pub LeadingZero: u32,\n    pub Grouping: u32,\n    pub lpDecimalSep: windows_sys::core::PSTR,\n    pub lpThousandSep: windows_sys::core::PSTR,\n    pub NegativeOrder: u32,\n    pub PositiveOrder: u32,\n    pub lpCurrencySymbol: windows_sys::core::PSTR,\n}\nimpl Default for CURRENCYFMTA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CURRENCYFMTW {\n    pub NumDigits: u32,\n    pub LeadingZero: u32,\n    pub Grouping: u32,\n    pub lpDecimalSep: windows_sys::core::PWSTR,\n    pub lpThousandSep: windows_sys::core::PWSTR,\n    pub NegativeOrder: u32,\n    pub PositiveOrder: u32,\n    pub lpCurrencySymbol: windows_sys::core::PWSTR,\n}\nimpl Default for CURRENCYFMTW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type DATEFMT_ENUMPROCA = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCSTR) -> windows_sys::core::BOOL>;\npub type DATEFMT_ENUMPROCEXA = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCSTR, param1: u32) -> windows_sys::core::BOOL>;\npub type DATEFMT_ENUMPROCEXEX = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR, param1: u32, param2: super::Foundation::LPARAM) -> windows_sys::core::BOOL>;\npub type DATEFMT_ENUMPROCEXW = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR, param1: u32) -> windows_sys::core::BOOL>;\npub type DATEFMT_ENUMPROCW = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR) -> windows_sys::core::BOOL>;\npub const DATE_AUTOLAYOUT: ENUM_DATE_FORMATS_FLAGS = 64u32;\npub const DATE_LONGDATE: ENUM_DATE_FORMATS_FLAGS = 2u32;\npub const DATE_LTRREADING: ENUM_DATE_FORMATS_FLAGS = 16u32;\npub const DATE_MONTHDAY: ENUM_DATE_FORMATS_FLAGS = 128u32;\npub const DATE_RTLREADING: ENUM_DATE_FORMATS_FLAGS = 32u32;\npub const DATE_SHORTDATE: ENUM_DATE_FORMATS_FLAGS = 1u32;\npub const DATE_USE_ALT_CALENDAR: ENUM_DATE_FORMATS_FLAGS = 4u32;\npub const DATE_YEARMONTH: ENUM_DATE_FORMATS_FLAGS = 8u32;\npub const DayUnit: CALDATETIME_DATEUNIT = 4i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DetectEncodingInfo {\n    pub nLangID: u32,\n    pub nCodePage: u32,\n    pub nDocPercent: i32,\n    pub nConfidence: i32,\n}\npub const ELS_GUID_LANGUAGE_DETECTION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xcf7e00b1_909b_4d95_a8f4_611f7c377702);\npub const ELS_GUID_SCRIPT_DETECTION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2d64b439_6caf_4f6b_b688_e5d0f4faa7d7);\npub const ELS_GUID_TRANSLITERATION_BENGALI_TO_LATIN: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf4dfd825_91a4_489f_855e_9ad9bee55727);\npub const ELS_GUID_TRANSLITERATION_CYRILLIC_TO_LATIN: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3dd12a98_5afd_4903_a13f_e17e6c0bfe01);\npub const ELS_GUID_TRANSLITERATION_DEVANAGARI_TO_LATIN: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc4a4dcfe_2661_4d02_9835_f48187109803);\npub const ELS_GUID_TRANSLITERATION_HANGUL_DECOMPOSITION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4ba2a721_e43d_41b7_b330_536ae1e48863);\npub const ELS_GUID_TRANSLITERATION_HANS_TO_HANT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3caccdc8_5590_42dc_9a7b_b5a6b5b3b63b);\npub const ELS_GUID_TRANSLITERATION_HANT_TO_HANS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa3a8333b_f4fc_42f6_a0c4_0462fe7317cb);\npub const ELS_GUID_TRANSLITERATION_MALAYALAM_TO_LATIN: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd8b983b1_f8bf_4a2b_bcd5_5b5ea20613e1);\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct ENUMTEXTMETRICA {\n    pub etmNewTextMetricEx: NEWTEXTMETRICEXA,\n    pub etmAxesList: super::Graphics::Gdi::AXESLISTA,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct ENUMTEXTMETRICW {\n    pub etmNewTextMetricEx: NEWTEXTMETRICEXW,\n    pub etmAxesList: super::Graphics::Gdi::AXESLISTW,\n}\npub const ENUM_ALL_CALENDARS: u32 = 4294967295u32;\npub type ENUM_DATE_FORMATS_FLAGS = u32;\npub type ENUM_SYSTEM_CODE_PAGES_FLAGS = u32;\npub type ENUM_SYSTEM_LANGUAGE_GROUPS_FLAGS = u32;\npub const EraUnit: CALDATETIME_DATEUNIT = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILEMUIINFO {\n    pub dwSize: u32,\n    pub dwVersion: u32,\n    pub dwFileType: u32,\n    pub pChecksum: [u8; 16],\n    pub pServiceChecksum: [u8; 16],\n    pub dwLanguageNameOffset: u32,\n    pub dwTypeIDMainSize: u32,\n    pub dwTypeIDMainOffset: u32,\n    pub dwTypeNameMainOffset: u32,\n    pub dwTypeIDMUISize: u32,\n    pub dwTypeIDMUIOffset: u32,\n    pub dwTypeNameMUIOffset: u32,\n    pub abBuffer: [u8; 8],\n}\nimpl Default for FILEMUIINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FIND_ENDSWITH: u32 = 2097152u32;\npub const FIND_FROMEND: u32 = 8388608u32;\npub const FIND_FROMSTART: u32 = 4194304u32;\npub const FIND_STARTSWITH: u32 = 1048576u32;\npub type FOLD_STRING_MAP_FLAGS = u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FONTSIGNATURE {\n    pub fsUsb: [u32; 4],\n    pub fsCsb: [u32; 2],\n}\nimpl Default for FONTSIGNATURE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const GEOCLASS_ALL: SYSGEOCLASS = 0i32;\npub const GEOCLASS_NATION: SYSGEOCLASS = 16i32;\npub const GEOCLASS_REGION: SYSGEOCLASS = 14i32;\npub const GEOID_NOT_AVAILABLE: i32 = -1i32;\npub const GEO_CURRENCYCODE: SYSGEOTYPE = 15i32;\npub const GEO_CURRENCYSYMBOL: SYSGEOTYPE = 16i32;\npub const GEO_DIALINGCODE: SYSGEOTYPE = 14i32;\npub type GEO_ENUMNAMEPROC = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR, param1: super::Foundation::LPARAM) -> windows_sys::core::BOOL>;\npub type GEO_ENUMPROC = Option<unsafe extern \"system\" fn(param0: i32) -> windows_sys::core::BOOL>;\npub const GEO_FRIENDLYNAME: SYSGEOTYPE = 8i32;\npub const GEO_ID: SYSGEOTYPE = 18i32;\npub const GEO_ISO2: SYSGEOTYPE = 4i32;\npub const GEO_ISO3: SYSGEOTYPE = 5i32;\npub const GEO_ISO_UN_NUMBER: SYSGEOTYPE = 12i32;\npub const GEO_LATITUDE: SYSGEOTYPE = 2i32;\npub const GEO_LCID: SYSGEOTYPE = 7i32;\npub const GEO_LONGITUDE: SYSGEOTYPE = 3i32;\npub const GEO_NAME: SYSGEOTYPE = 17i32;\npub const GEO_NATION: SYSGEOTYPE = 1i32;\npub const GEO_OFFICIALLANGUAGES: SYSGEOTYPE = 11i32;\npub const GEO_OFFICIALNAME: SYSGEOTYPE = 9i32;\npub const GEO_PARENT: SYSGEOTYPE = 13i32;\npub const GEO_RFC1766: SYSGEOTYPE = 6i32;\npub const GEO_TIMEZONES: SYSGEOTYPE = 10i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GOFFSET {\n    pub du: i32,\n    pub dv: i32,\n}\npub const GSS_ALLOW_INHERITED_COMMON: u32 = 1u32;\npub const HIGHLEVEL_SERVICE_TYPES: u32 = 1u32;\npub const HIGH_SURROGATE_END: u32 = 56319u32;\npub const HIGH_SURROGATE_START: u32 = 55296u32;\npub type HSAVEDUILANGUAGES = *mut core::ffi::c_void;\npub const HourUnit: CALDATETIME_DATEUNIT = 5i32;\npub const IDN_ALLOW_UNASSIGNED: u32 = 1u32;\npub const IDN_EMAIL_ADDRESS: u32 = 4u32;\npub const IDN_RAW_PUNYCODE: u32 = 8u32;\npub const IDN_USE_STD3_ASCII_RULES: u32 = 2u32;\npub const IS_TEXT_UNICODE_ASCII16: IS_TEXT_UNICODE_RESULT = 1u32;\npub const IS_TEXT_UNICODE_CONTROLS: IS_TEXT_UNICODE_RESULT = 4u32;\npub const IS_TEXT_UNICODE_ILLEGAL_CHARS: IS_TEXT_UNICODE_RESULT = 256u32;\npub const IS_TEXT_UNICODE_NOT_ASCII_MASK: IS_TEXT_UNICODE_RESULT = 61440u32;\npub const IS_TEXT_UNICODE_NOT_UNICODE_MASK: IS_TEXT_UNICODE_RESULT = 3840u32;\npub const IS_TEXT_UNICODE_NULL_BYTES: IS_TEXT_UNICODE_RESULT = 4096u32;\npub const IS_TEXT_UNICODE_ODD_LENGTH: IS_TEXT_UNICODE_RESULT = 512u32;\npub type IS_TEXT_UNICODE_RESULT = u32;\npub const IS_TEXT_UNICODE_REVERSE_ASCII16: IS_TEXT_UNICODE_RESULT = 16u32;\npub const IS_TEXT_UNICODE_REVERSE_CONTROLS: IS_TEXT_UNICODE_RESULT = 64u32;\npub const IS_TEXT_UNICODE_REVERSE_MASK: IS_TEXT_UNICODE_RESULT = 240u32;\npub const IS_TEXT_UNICODE_REVERSE_SIGNATURE: IS_TEXT_UNICODE_RESULT = 128u32;\npub const IS_TEXT_UNICODE_REVERSE_STATISTICS: IS_TEXT_UNICODE_RESULT = 32u32;\npub const IS_TEXT_UNICODE_SIGNATURE: IS_TEXT_UNICODE_RESULT = 8u32;\npub const IS_TEXT_UNICODE_STATISTICS: IS_TEXT_UNICODE_RESULT = 2u32;\npub const IS_TEXT_UNICODE_UNICODE_MASK: IS_TEXT_UNICODE_RESULT = 15u32;\npub type IS_VALID_LOCALE_FLAGS = u32;\npub type LANGGROUPLOCALE_ENUMPROCA = Option<unsafe extern \"system\" fn(param0: u32, param1: u32, param2: windows_sys::core::PCSTR, param3: isize) -> windows_sys::core::BOOL>;\npub type LANGGROUPLOCALE_ENUMPROCW = Option<unsafe extern \"system\" fn(param0: u32, param1: u32, param2: windows_sys::core::PCWSTR, param3: isize) -> windows_sys::core::BOOL>;\npub type LANGUAGEGROUP_ENUMPROCA = Option<unsafe extern \"system\" fn(param0: u32, param1: windows_sys::core::PCSTR, param2: windows_sys::core::PCSTR, param3: u32, param4: isize) -> windows_sys::core::BOOL>;\npub type LANGUAGEGROUP_ENUMPROCW = Option<unsafe extern \"system\" fn(param0: u32, param1: windows_sys::core::PCWSTR, param2: windows_sys::core::PCWSTR, param3: u32, param4: isize) -> windows_sys::core::BOOL>;\npub const LANG_SYSTEM_DEFAULT: i32 = 2048i32;\npub const LANG_USER_DEFAULT: i32 = 1024i32;\npub const LCID_ALTERNATE_SORTS: u32 = 4u32;\npub const LCID_INSTALLED: IS_VALID_LOCALE_FLAGS = 1u32;\npub const LCID_SUPPORTED: IS_VALID_LOCALE_FLAGS = 2u32;\npub const LCMAP_BYTEREV: u32 = 2048u32;\npub const LCMAP_FULLWIDTH: u32 = 8388608u32;\npub const LCMAP_HALFWIDTH: u32 = 4194304u32;\npub const LCMAP_HASH: u32 = 262144u32;\npub const LCMAP_HIRAGANA: u32 = 1048576u32;\npub const LCMAP_KATAKANA: u32 = 2097152u32;\npub const LCMAP_LINGUISTIC_CASING: u32 = 16777216u32;\npub const LCMAP_LOWERCASE: u32 = 256u32;\npub const LCMAP_SIMPLIFIED_CHINESE: u32 = 33554432u32;\npub const LCMAP_SORTHANDLE: u32 = 536870912u32;\npub const LCMAP_SORTKEY: u32 = 1024u32;\npub const LCMAP_TITLECASE: u32 = 768u32;\npub const LCMAP_TRADITIONAL_CHINESE: u32 = 67108864u32;\npub const LCMAP_UPPERCASE: u32 = 512u32;\npub const LGRPID_ARABIC: u32 = 13u32;\npub const LGRPID_ARMENIAN: u32 = 17u32;\npub const LGRPID_BALTIC: u32 = 3u32;\npub const LGRPID_CENTRAL_EUROPE: u32 = 2u32;\npub const LGRPID_CYRILLIC: u32 = 5u32;\npub const LGRPID_GEORGIAN: u32 = 16u32;\npub const LGRPID_GREEK: u32 = 4u32;\npub const LGRPID_HEBREW: u32 = 12u32;\npub const LGRPID_INDIC: u32 = 15u32;\npub const LGRPID_INSTALLED: ENUM_SYSTEM_LANGUAGE_GROUPS_FLAGS = 1u32;\npub const LGRPID_JAPANESE: u32 = 7u32;\npub const LGRPID_KOREAN: u32 = 8u32;\npub const LGRPID_SIMPLIFIED_CHINESE: u32 = 10u32;\npub const LGRPID_SUPPORTED: ENUM_SYSTEM_LANGUAGE_GROUPS_FLAGS = 2u32;\npub const LGRPID_THAI: u32 = 11u32;\npub const LGRPID_TRADITIONAL_CHINESE: u32 = 9u32;\npub const LGRPID_TURKIC: u32 = 6u32;\npub const LGRPID_TURKISH: u32 = 6u32;\npub const LGRPID_VIETNAMESE: u32 = 14u32;\npub const LGRPID_WESTERN_EUROPE: u32 = 1u32;\npub const LINGUISTIC_IGNORECASE: COMPARE_STRING_FLAGS = 16u32;\npub const LINGUISTIC_IGNOREDIACRITIC: COMPARE_STRING_FLAGS = 32u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LOCALESIGNATURE {\n    pub lsUsb: [u32; 4],\n    pub lsCsbDefault: [u32; 2],\n    pub lsCsbSupported: [u32; 2],\n}\nimpl Default for LOCALESIGNATURE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const LOCALE_ALL: u32 = 0u32;\npub const LOCALE_ALLOW_NEUTRAL_NAMES: u32 = 134217728u32;\npub const LOCALE_ALTERNATE_SORTS: u32 = 4u32;\npub type LOCALE_ENUMPROCA = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCSTR) -> windows_sys::core::BOOL>;\npub type LOCALE_ENUMPROCEX = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR, param1: u32, param2: super::Foundation::LPARAM) -> windows_sys::core::BOOL>;\npub type LOCALE_ENUMPROCW = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR) -> windows_sys::core::BOOL>;\npub const LOCALE_FONTSIGNATURE: u32 = 88u32;\npub const LOCALE_ICALENDARTYPE: u32 = 4105u32;\npub const LOCALE_ICENTURY: u32 = 36u32;\npub const LOCALE_ICONSTRUCTEDLOCALE: u32 = 125u32;\npub const LOCALE_ICOUNTRY: u32 = 5u32;\npub const LOCALE_ICURRDIGITS: u32 = 25u32;\npub const LOCALE_ICURRENCY: u32 = 27u32;\npub const LOCALE_IDATE: u32 = 33u32;\npub const LOCALE_IDAYLZERO: u32 = 38u32;\npub const LOCALE_IDEFAULTANSICODEPAGE: u32 = 4100u32;\npub const LOCALE_IDEFAULTCODEPAGE: u32 = 11u32;\npub const LOCALE_IDEFAULTCOUNTRY: u32 = 10u32;\npub const LOCALE_IDEFAULTEBCDICCODEPAGE: u32 = 4114u32;\npub const LOCALE_IDEFAULTLANGUAGE: u32 = 9u32;\npub const LOCALE_IDEFAULTMACCODEPAGE: u32 = 4113u32;\npub const LOCALE_IDIALINGCODE: u32 = 5u32;\npub const LOCALE_IDIGITS: u32 = 17u32;\npub const LOCALE_IDIGITSUBSTITUTION: u32 = 4116u32;\npub const LOCALE_IFIRSTDAYOFWEEK: u32 = 4108u32;\npub const LOCALE_IFIRSTWEEKOFYEAR: u32 = 4109u32;\npub const LOCALE_IGEOID: u32 = 91u32;\npub const LOCALE_IINTLCURRDIGITS: u32 = 26u32;\npub const LOCALE_ILANGUAGE: u32 = 1u32;\npub const LOCALE_ILDATE: u32 = 34u32;\npub const LOCALE_ILZERO: u32 = 18u32;\npub const LOCALE_IMEASURE: u32 = 13u32;\npub const LOCALE_IMONLZERO: u32 = 39u32;\npub const LOCALE_INEGATIVEPERCENT: u32 = 116u32;\npub const LOCALE_INEGCURR: u32 = 28u32;\npub const LOCALE_INEGNUMBER: u32 = 4112u32;\npub const LOCALE_INEGSEPBYSPACE: u32 = 87u32;\npub const LOCALE_INEGSIGNPOSN: u32 = 83u32;\npub const LOCALE_INEGSYMPRECEDES: u32 = 86u32;\npub const LOCALE_INEUTRAL: u32 = 113u32;\npub const LOCALE_IOPTIONALCALENDAR: u32 = 4107u32;\npub const LOCALE_IPAPERSIZE: u32 = 4106u32;\npub const LOCALE_IPOSITIVEPERCENT: u32 = 117u32;\npub const LOCALE_IPOSSEPBYSPACE: u32 = 85u32;\npub const LOCALE_IPOSSIGNPOSN: u32 = 82u32;\npub const LOCALE_IPOSSYMPRECEDES: u32 = 84u32;\npub const LOCALE_IREADINGLAYOUT: u32 = 112u32;\npub const LOCALE_ITIME: u32 = 35u32;\npub const LOCALE_ITIMEMARKPOSN: u32 = 4101u32;\npub const LOCALE_ITLZERO: u32 = 37u32;\npub const LOCALE_IUSEUTF8LEGACYACP: u32 = 1638u32;\npub const LOCALE_IUSEUTF8LEGACYOEMCP: u32 = 2457u32;\npub const LOCALE_NAME_INVARIANT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"\");\npub const LOCALE_NAME_SYSTEM_DEFAULT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"!x-sys-default-locale\");\npub const LOCALE_NEUTRALDATA: u32 = 16u32;\npub const LOCALE_NOUSEROVERRIDE: u32 = 2147483648u32;\npub const LOCALE_REPLACEMENT: u32 = 8u32;\npub const LOCALE_RETURN_GENITIVE_NAMES: u32 = 268435456u32;\npub const LOCALE_RETURN_NUMBER: u32 = 536870912u32;\npub const LOCALE_S1159: u32 = 40u32;\npub const LOCALE_S2359: u32 = 41u32;\npub const LOCALE_SABBREVCTRYNAME: u32 = 7u32;\npub const LOCALE_SABBREVDAYNAME1: u32 = 49u32;\npub const LOCALE_SABBREVDAYNAME2: u32 = 50u32;\npub const LOCALE_SABBREVDAYNAME3: u32 = 51u32;\npub const LOCALE_SABBREVDAYNAME4: u32 = 52u32;\npub const LOCALE_SABBREVDAYNAME5: u32 = 53u32;\npub const LOCALE_SABBREVDAYNAME6: u32 = 54u32;\npub const LOCALE_SABBREVDAYNAME7: u32 = 55u32;\npub const LOCALE_SABBREVLANGNAME: u32 = 3u32;\npub const LOCALE_SABBREVMONTHNAME1: u32 = 68u32;\npub const LOCALE_SABBREVMONTHNAME10: u32 = 77u32;\npub const LOCALE_SABBREVMONTHNAME11: u32 = 78u32;\npub const LOCALE_SABBREVMONTHNAME12: u32 = 79u32;\npub const LOCALE_SABBREVMONTHNAME13: u32 = 4111u32;\npub const LOCALE_SABBREVMONTHNAME2: u32 = 69u32;\npub const LOCALE_SABBREVMONTHNAME3: u32 = 70u32;\npub const LOCALE_SABBREVMONTHNAME4: u32 = 71u32;\npub const LOCALE_SABBREVMONTHNAME5: u32 = 72u32;\npub const LOCALE_SABBREVMONTHNAME6: u32 = 73u32;\npub const LOCALE_SABBREVMONTHNAME7: u32 = 74u32;\npub const LOCALE_SABBREVMONTHNAME8: u32 = 75u32;\npub const LOCALE_SABBREVMONTHNAME9: u32 = 76u32;\npub const LOCALE_SAM: u32 = 40u32;\npub const LOCALE_SCONSOLEFALLBACKNAME: u32 = 110u32;\npub const LOCALE_SCOUNTRY: u32 = 6u32;\npub const LOCALE_SCURRENCY: u32 = 20u32;\npub const LOCALE_SDATE: u32 = 29u32;\npub const LOCALE_SDAYNAME1: u32 = 42u32;\npub const LOCALE_SDAYNAME2: u32 = 43u32;\npub const LOCALE_SDAYNAME3: u32 = 44u32;\npub const LOCALE_SDAYNAME4: u32 = 45u32;\npub const LOCALE_SDAYNAME5: u32 = 46u32;\npub const LOCALE_SDAYNAME6: u32 = 47u32;\npub const LOCALE_SDAYNAME7: u32 = 48u32;\npub const LOCALE_SDECIMAL: u32 = 14u32;\npub const LOCALE_SDURATION: u32 = 93u32;\npub const LOCALE_SENGCOUNTRY: u32 = 4098u32;\npub const LOCALE_SENGCURRNAME: u32 = 4103u32;\npub const LOCALE_SENGLANGUAGE: u32 = 4097u32;\npub const LOCALE_SENGLISHCOUNTRYNAME: u32 = 4098u32;\npub const LOCALE_SENGLISHDISPLAYNAME: u32 = 114u32;\npub const LOCALE_SENGLISHLANGUAGENAME: u32 = 4097u32;\npub const LOCALE_SGROUPING: u32 = 16u32;\npub const LOCALE_SINTLSYMBOL: u32 = 21u32;\npub const LOCALE_SISO3166CTRYNAME: u32 = 90u32;\npub const LOCALE_SISO3166CTRYNAME2: u32 = 104u32;\npub const LOCALE_SISO639LANGNAME: u32 = 89u32;\npub const LOCALE_SISO639LANGNAME2: u32 = 103u32;\npub const LOCALE_SKEYBOARDSTOINSTALL: u32 = 94u32;\npub const LOCALE_SLANGDISPLAYNAME: u32 = 111u32;\npub const LOCALE_SLANGUAGE: u32 = 2u32;\npub const LOCALE_SLIST: u32 = 12u32;\npub const LOCALE_SLOCALIZEDCOUNTRYNAME: u32 = 6u32;\npub const LOCALE_SLOCALIZEDDISPLAYNAME: u32 = 2u32;\npub const LOCALE_SLOCALIZEDLANGUAGENAME: u32 = 111u32;\npub const LOCALE_SLONGDATE: u32 = 32u32;\npub const LOCALE_SMONDECIMALSEP: u32 = 22u32;\npub const LOCALE_SMONGROUPING: u32 = 24u32;\npub const LOCALE_SMONTHDAY: u32 = 120u32;\npub const LOCALE_SMONTHNAME1: u32 = 56u32;\npub const LOCALE_SMONTHNAME10: u32 = 65u32;\npub const LOCALE_SMONTHNAME11: u32 = 66u32;\npub const LOCALE_SMONTHNAME12: u32 = 67u32;\npub const LOCALE_SMONTHNAME13: u32 = 4110u32;\npub const LOCALE_SMONTHNAME2: u32 = 57u32;\npub const LOCALE_SMONTHNAME3: u32 = 58u32;\npub const LOCALE_SMONTHNAME4: u32 = 59u32;\npub const LOCALE_SMONTHNAME5: u32 = 60u32;\npub const LOCALE_SMONTHNAME6: u32 = 61u32;\npub const LOCALE_SMONTHNAME7: u32 = 62u32;\npub const LOCALE_SMONTHNAME8: u32 = 63u32;\npub const LOCALE_SMONTHNAME9: u32 = 64u32;\npub const LOCALE_SMONTHOUSANDSEP: u32 = 23u32;\npub const LOCALE_SNAME: u32 = 92u32;\npub const LOCALE_SNAN: u32 = 105u32;\npub const LOCALE_SNATIVECOUNTRYNAME: u32 = 8u32;\npub const LOCALE_SNATIVECTRYNAME: u32 = 8u32;\npub const LOCALE_SNATIVECURRNAME: u32 = 4104u32;\npub const LOCALE_SNATIVEDIGITS: u32 = 19u32;\npub const LOCALE_SNATIVEDISPLAYNAME: u32 = 115u32;\npub const LOCALE_SNATIVELANGNAME: u32 = 4u32;\npub const LOCALE_SNATIVELANGUAGENAME: u32 = 4u32;\npub const LOCALE_SNEGATIVESIGN: u32 = 81u32;\npub const LOCALE_SNEGINFINITY: u32 = 107u32;\npub const LOCALE_SOPENTYPELANGUAGETAG: u32 = 122u32;\npub const LOCALE_SPARENT: u32 = 109u32;\npub const LOCALE_SPECIFICDATA: u32 = 32u32;\npub const LOCALE_SPERCENT: u32 = 118u32;\npub const LOCALE_SPERMILLE: u32 = 119u32;\npub const LOCALE_SPM: u32 = 41u32;\npub const LOCALE_SPOSINFINITY: u32 = 106u32;\npub const LOCALE_SPOSITIVESIGN: u32 = 80u32;\npub const LOCALE_SRELATIVELONGDATE: u32 = 124u32;\npub const LOCALE_SSCRIPTS: u32 = 108u32;\npub const LOCALE_SSHORTDATE: u32 = 31u32;\npub const LOCALE_SSHORTESTAM: u32 = 126u32;\npub const LOCALE_SSHORTESTDAYNAME1: u32 = 96u32;\npub const LOCALE_SSHORTESTDAYNAME2: u32 = 97u32;\npub const LOCALE_SSHORTESTDAYNAME3: u32 = 98u32;\npub const LOCALE_SSHORTESTDAYNAME4: u32 = 99u32;\npub const LOCALE_SSHORTESTDAYNAME5: u32 = 100u32;\npub const LOCALE_SSHORTESTDAYNAME6: u32 = 101u32;\npub const LOCALE_SSHORTESTDAYNAME7: u32 = 102u32;\npub const LOCALE_SSHORTESTPM: u32 = 127u32;\npub const LOCALE_SSHORTTIME: u32 = 121u32;\npub const LOCALE_SSORTLOCALE: u32 = 123u32;\npub const LOCALE_SSORTNAME: u32 = 4115u32;\npub const LOCALE_STHOUSAND: u32 = 15u32;\npub const LOCALE_STIME: u32 = 30u32;\npub const LOCALE_STIMEFORMAT: u32 = 4099u32;\npub const LOCALE_SUPPLEMENTAL: u32 = 2u32;\npub const LOCALE_SYEARMONTH: u32 = 4102u32;\npub const LOCALE_SYSTEM_DEFAULT: u32 = 2048u32;\npub const LOCALE_USER_DEFAULT: u32 = 1024u32;\npub const LOCALE_USE_CP_ACP: u32 = 1073741824u32;\npub const LOCALE_WINDOWS: u32 = 1u32;\npub const LOWLEVEL_SERVICE_TYPES: u32 = 2u32;\npub const LOW_SURROGATE_END: u32 = 57343u32;\npub const LOW_SURROGATE_START: u32 = 56320u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MAPPING_DATA_RANGE {\n    pub dwStartIndex: u32,\n    pub dwEndIndex: u32,\n    pub pszDescription: windows_sys::core::PWSTR,\n    pub dwDescriptionLength: u32,\n    pub pData: *mut core::ffi::c_void,\n    pub dwDataSize: u32,\n    pub pszContentType: windows_sys::core::PWSTR,\n    pub prgActionIds: *mut windows_sys::core::PWSTR,\n    pub dwActionsCount: u32,\n    pub prgActionDisplayNames: *mut windows_sys::core::PWSTR,\n}\nimpl Default for MAPPING_DATA_RANGE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MAPPING_ENUM_OPTIONS {\n    pub Size: usize,\n    pub pszCategory: windows_sys::core::PWSTR,\n    pub pszInputLanguage: windows_sys::core::PWSTR,\n    pub pszOutputLanguage: windows_sys::core::PWSTR,\n    pub pszInputScript: windows_sys::core::PWSTR,\n    pub pszOutputScript: windows_sys::core::PWSTR,\n    pub pszInputContentType: windows_sys::core::PWSTR,\n    pub pszOutputContentType: windows_sys::core::PWSTR,\n    pub pGuid: *mut windows_sys::core::GUID,\n    pub _bitfield: u32,\n}\nimpl Default for MAPPING_ENUM_OPTIONS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MAPPING_OPTIONS {\n    pub Size: usize,\n    pub pszInputLanguage: windows_sys::core::PWSTR,\n    pub pszOutputLanguage: windows_sys::core::PWSTR,\n    pub pszInputScript: windows_sys::core::PWSTR,\n    pub pszOutputScript: windows_sys::core::PWSTR,\n    pub pszInputContentType: windows_sys::core::PWSTR,\n    pub pszOutputContentType: windows_sys::core::PWSTR,\n    pub pszUILanguage: windows_sys::core::PWSTR,\n    pub pfnRecognizeCallback: PFN_MAPPINGCALLBACKPROC,\n    pub pRecognizeCallerData: *mut core::ffi::c_void,\n    pub dwRecognizeCallerDataSize: u32,\n    pub pfnActionCallback: PFN_MAPPINGCALLBACKPROC,\n    pub pActionCallerData: *mut core::ffi::c_void,\n    pub dwActionCallerDataSize: u32,\n    pub dwServiceFlag: u32,\n    pub _bitfield: u32,\n}\nimpl Default for MAPPING_OPTIONS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MAPPING_PROPERTY_BAG {\n    pub Size: usize,\n    pub prgResultRanges: *mut MAPPING_DATA_RANGE,\n    pub dwRangesCount: u32,\n    pub pServiceData: *mut core::ffi::c_void,\n    pub dwServiceDataSize: u32,\n    pub pCallerData: *mut core::ffi::c_void,\n    pub dwCallerDataSize: u32,\n    pub pContext: *mut core::ffi::c_void,\n}\nimpl Default for MAPPING_PROPERTY_BAG {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MAPPING_SERVICE_INFO {\n    pub Size: usize,\n    pub pszCopyright: windows_sys::core::PWSTR,\n    pub wMajorVersion: u16,\n    pub wMinorVersion: u16,\n    pub wBuildVersion: u16,\n    pub wStepVersion: u16,\n    pub dwInputContentTypesCount: u32,\n    pub prgInputContentTypes: *mut windows_sys::core::PWSTR,\n    pub dwOutputContentTypesCount: u32,\n    pub prgOutputContentTypes: *mut windows_sys::core::PWSTR,\n    pub dwInputLanguagesCount: u32,\n    pub prgInputLanguages: *mut windows_sys::core::PWSTR,\n    pub dwOutputLanguagesCount: u32,\n    pub prgOutputLanguages: *mut windows_sys::core::PWSTR,\n    pub dwInputScriptsCount: u32,\n    pub prgInputScripts: *mut windows_sys::core::PWSTR,\n    pub dwOutputScriptsCount: u32,\n    pub prgOutputScripts: *mut windows_sys::core::PWSTR,\n    pub guid: windows_sys::core::GUID,\n    pub pszCategory: windows_sys::core::PWSTR,\n    pub pszDescription: windows_sys::core::PWSTR,\n    pub dwPrivateDataSize: u32,\n    pub pPrivateData: *mut core::ffi::c_void,\n    pub pContext: *mut core::ffi::c_void,\n    pub _bitfield: u32,\n}\nimpl Default for MAPPING_SERVICE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MAP_COMPOSITE: FOLD_STRING_MAP_FLAGS = 64u32;\npub const MAP_EXPAND_LIGATURES: FOLD_STRING_MAP_FLAGS = 8192u32;\npub const MAP_FOLDCZONE: FOLD_STRING_MAP_FLAGS = 16u32;\npub const MAP_FOLDDIGITS: FOLD_STRING_MAP_FLAGS = 128u32;\npub const MAP_PRECOMPOSED: FOLD_STRING_MAP_FLAGS = 32u32;\npub const MAX_DEFAULTCHAR: u32 = 2u32;\npub const MAX_LEADBYTES: u32 = 12u32;\npub const MAX_LOCALE_NAME: u32 = 32u32;\npub const MAX_MIMECP_NAME: u32 = 64u32;\npub const MAX_MIMECSET_NAME: u32 = 50u32;\npub const MAX_MIMEFACE_NAME: u32 = 32u32;\npub const MAX_RFC1766_NAME: u32 = 6u32;\npub const MAX_SCRIPT_NAME: u32 = 48u32;\npub const MB_COMPOSITE: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 2u32;\npub const MB_ERR_INVALID_CHARS: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 8u32;\npub const MB_PRECOMPOSED: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 1u32;\npub const MB_USEGLYPHCHARS: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 4u32;\npub type MIMECONTF = i32;\npub const MIMECONTF_BROWSER: MIMECONTF = 2i32;\npub const MIMECONTF_EXPORT: MIMECONTF = 1024i32;\npub const MIMECONTF_IMPORT: MIMECONTF = 8i32;\npub const MIMECONTF_MAILNEWS: MIMECONTF = 1i32;\npub const MIMECONTF_MIME_IE4: MIMECONTF = 268435456i32;\npub const MIMECONTF_MIME_LATEST: MIMECONTF = 536870912i32;\npub const MIMECONTF_MIME_REGISTRY: MIMECONTF = 1073741824i32;\npub const MIMECONTF_MINIMAL: MIMECONTF = 4i32;\npub const MIMECONTF_PRIVCONVERTER: MIMECONTF = 65536i32;\npub const MIMECONTF_SAVABLE_BROWSER: MIMECONTF = 512i32;\npub const MIMECONTF_SAVABLE_MAILNEWS: MIMECONTF = 256i32;\npub const MIMECONTF_VALID: MIMECONTF = 131072i32;\npub const MIMECONTF_VALID_NLS: MIMECONTF = 262144i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MIMECPINFO {\n    pub dwFlags: u32,\n    pub uiCodePage: u32,\n    pub uiFamilyCodePage: u32,\n    pub wszDescription: [u16; 64],\n    pub wszWebCharset: [u16; 50],\n    pub wszHeaderCharset: [u16; 50],\n    pub wszBodyCharset: [u16; 50],\n    pub wszFixedWidthFont: [u16; 32],\n    pub wszProportionalFont: [u16; 32],\n    pub bGDICharset: u8,\n}\nimpl Default for MIMECPINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MIMECSETINFO {\n    pub uiCodePage: u32,\n    pub uiInternetEncoding: u32,\n    pub wszCharset: [u16; 50],\n}\nimpl Default for MIMECSETINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MIN_SPELLING_NTDDI: u32 = 100794368u32;\npub type MLCONVCHAR = i32;\npub const MLCONVCHARF_AUTODETECT: MLCONVCHAR = 1i32;\npub const MLCONVCHARF_DETECTJPN: MLCONVCHAR = 32i32;\npub const MLCONVCHARF_ENTITIZE: MLCONVCHAR = 2i32;\npub const MLCONVCHARF_NAME_ENTITIZE: MLCONVCHAR = 4i32;\npub const MLCONVCHARF_NCR_ENTITIZE: MLCONVCHAR = 2i32;\npub const MLCONVCHARF_NOBESTFITCHARS: MLCONVCHAR = 16i32;\npub const MLCONVCHARF_USEDEFCHAR: MLCONVCHAR = 8i32;\npub type MLCP = i32;\npub type MLDETECTCP = i32;\npub const MLDETECTCP_7BIT: MLDETECTCP = 1i32;\npub const MLDETECTCP_8BIT: MLDETECTCP = 2i32;\npub const MLDETECTCP_DBCS: MLDETECTCP = 4i32;\npub const MLDETECTCP_HTML: MLDETECTCP = 8i32;\npub const MLDETECTCP_NONE: MLDETECTCP = 0i32;\npub const MLDETECTCP_NUMBER: MLDETECTCP = 16i32;\npub const MLDETECTF_BROWSER: MLCP = 2i32;\npub const MLDETECTF_EURO_UTF8: MLCP = 128i32;\npub const MLDETECTF_FILTER_SPECIALCHAR: MLCP = 64i32;\npub const MLDETECTF_MAILNEWS: MLCP = 1i32;\npub const MLDETECTF_PREFERRED_ONLY: MLCP = 32i32;\npub const MLDETECTF_PRESERVE_ORDER: MLCP = 16i32;\npub const MLDETECTF_VALID: MLCP = 4i32;\npub const MLDETECTF_VALID_NLS: MLCP = 8i32;\npub type MLSTR_FLAGS = i32;\npub const MLSTR_READ: MLSTR_FLAGS = 1i32;\npub const MLSTR_WRITE: MLSTR_FLAGS = 2i32;\npub const MUI_COMPLEX_SCRIPT_FILTER: u32 = 512u32;\npub const MUI_CONSOLE_FILTER: u32 = 256u32;\npub const MUI_FILEINFO_VERSION: u32 = 1u32;\npub const MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN: u32 = 2u32;\npub const MUI_FILETYPE_LANGUAGE_NEUTRAL_MUI: u32 = 4u32;\npub const MUI_FILETYPE_NOT_LANGUAGE_NEUTRAL: u32 = 1u32;\npub const MUI_FORMAT_INF_COMPAT: u32 = 2u32;\npub const MUI_FORMAT_REG_COMPAT: u32 = 1u32;\npub const MUI_FULL_LANGUAGE: u32 = 1u32;\npub const MUI_IMMUTABLE_LOOKUP: u32 = 16u32;\npub const MUI_LANGUAGE_EXACT: u32 = 16u32;\npub const MUI_LANGUAGE_ID: u32 = 4u32;\npub const MUI_LANGUAGE_INSTALLED: u32 = 32u32;\npub const MUI_LANGUAGE_LICENSED: u32 = 64u32;\npub const MUI_LANGUAGE_NAME: u32 = 8u32;\npub const MUI_LANG_NEUTRAL_PE_FILE: u32 = 256u32;\npub const MUI_LIP_LANGUAGE: u32 = 4u32;\npub const MUI_MACHINE_LANGUAGE_SETTINGS: u32 = 1024u32;\npub const MUI_MERGE_SYSTEM_FALLBACK: u32 = 16u32;\npub const MUI_MERGE_USER_FALLBACK: u32 = 32u32;\npub const MUI_NON_LANG_NEUTRAL_FILE: u32 = 512u32;\npub const MUI_PARTIAL_LANGUAGE: u32 = 2u32;\npub const MUI_QUERY_CHECKSUM: u32 = 2u32;\npub const MUI_QUERY_LANGUAGE_NAME: u32 = 4u32;\npub const MUI_QUERY_RESOURCE_TYPES: u32 = 8u32;\npub const MUI_QUERY_TYPE: u32 = 1u32;\npub const MUI_RESET_FILTERS: u32 = 1u32;\npub const MUI_SKIP_STRING_CACHE: u32 = 8u32;\npub const MUI_THREAD_LANGUAGES: u32 = 64u32;\npub const MUI_USER_PREFERRED_UI_LANGUAGES: u32 = 16u32;\npub const MUI_USE_INSTALLED_LANGUAGES: u32 = 32u32;\npub const MUI_USE_SEARCH_ALL_LANGUAGES: u32 = 64u32;\npub const MUI_VERIFY_FILE_EXISTS: u32 = 4u32;\npub type MULTI_BYTE_TO_WIDE_CHAR_FLAGS = u32;\npub const MinuteUnit: CALDATETIME_DATEUNIT = 6i32;\npub const MonthUnit: CALDATETIME_DATEUNIT = 2i32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct NEWTEXTMETRICEXA {\n    pub ntmTm: super::Graphics::Gdi::NEWTEXTMETRICA,\n    pub ntmFontSig: FONTSIGNATURE,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct NEWTEXTMETRICEXW {\n    pub ntmTm: super::Graphics::Gdi::NEWTEXTMETRICW,\n    pub ntmFontSig: FONTSIGNATURE,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NLSVERSIONINFO {\n    pub dwNLSVersionInfoSize: u32,\n    pub dwNLSVersion: u32,\n    pub dwDefinedVersion: u32,\n    pub dwEffectiveId: u32,\n    pub guidCustomVersion: windows_sys::core::GUID,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NLSVERSIONINFOEX {\n    pub dwNLSVersionInfoSize: u32,\n    pub dwNLSVersion: u32,\n    pub dwDefinedVersion: u32,\n    pub dwEffectiveId: u32,\n    pub guidCustomVersion: windows_sys::core::GUID,\n}\npub const NLS_CP_CPINFO: u32 = 268435456u32;\npub const NLS_CP_MBTOWC: u32 = 1073741824u32;\npub const NLS_CP_WCTOMB: u32 = 2147483648u32;\npub type NORM_FORM = i32;\npub const NORM_IGNORECASE: COMPARE_STRING_FLAGS = 1u32;\npub const NORM_IGNOREKANATYPE: COMPARE_STRING_FLAGS = 65536u32;\npub const NORM_IGNORENONSPACE: COMPARE_STRING_FLAGS = 2u32;\npub const NORM_IGNORESYMBOLS: COMPARE_STRING_FLAGS = 4u32;\npub const NORM_IGNOREWIDTH: COMPARE_STRING_FLAGS = 131072u32;\npub const NORM_LINGUISTIC_CASING: COMPARE_STRING_FLAGS = 134217728u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NUMBERFMTA {\n    pub NumDigits: u32,\n    pub LeadingZero: u32,\n    pub Grouping: u32,\n    pub lpDecimalSep: windows_sys::core::PSTR,\n    pub lpThousandSep: windows_sys::core::PSTR,\n    pub NegativeOrder: u32,\n}\nimpl Default for NUMBERFMTA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NUMBERFMTW {\n    pub NumDigits: u32,\n    pub LeadingZero: u32,\n    pub Grouping: u32,\n    pub lpDecimalSep: windows_sys::core::PWSTR,\n    pub lpThousandSep: windows_sys::core::PWSTR,\n    pub NegativeOrder: u32,\n}\nimpl Default for NUMBERFMTW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const NUMSYS_NAME_CAPACITY: u32 = 8u32;\npub const NormalizationC: NORM_FORM = 1i32;\npub const NormalizationD: NORM_FORM = 2i32;\npub const NormalizationKC: NORM_FORM = 5i32;\npub const NormalizationKD: NORM_FORM = 6i32;\npub const NormalizationOther: NORM_FORM = 0i32;\npub const OFFLINE_SERVICES: u32 = 2u32;\npub const ONLINE_SERVICES: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct OPENTYPE_FEATURE_RECORD {\n    pub tagFeature: u32,\n    pub lParameter: i32,\n}\npub type PFN_MAPPINGCALLBACKPROC = Option<unsafe extern \"system\" fn(pbag: *mut MAPPING_PROPERTY_BAG, data: *mut core::ffi::c_void, dwdatasize: u32, result: windows_sys::core::HRESULT)>;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct RFC1766INFO {\n    pub lcid: u32,\n    pub wszRfc1766: [u16; 6],\n    pub wszLocaleName: [u16; 32],\n}\nimpl Default for RFC1766INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type SCRIPTCONTF = i32;\npub const SCRIPTCONTF_FIXED_FONT: SCRIPTFONTCONTF = 1i32;\npub const SCRIPTCONTF_PROPORTIONAL_FONT: SCRIPTFONTCONTF = 2i32;\npub const SCRIPTCONTF_SCRIPT_HIDE: SCRIPTFONTCONTF = 131072i32;\npub const SCRIPTCONTF_SCRIPT_SYSTEM: SCRIPTFONTCONTF = 262144i32;\npub const SCRIPTCONTF_SCRIPT_USER: SCRIPTFONTCONTF = 65536i32;\npub type SCRIPTFONTCONTF = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCRIPTFONTINFO {\n    pub scripts: i64,\n    pub wszFont: [u16; 32],\n}\nimpl Default for SCRIPTFONTINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCRIPTINFO {\n    pub ScriptId: u8,\n    pub uiCodePage: u32,\n    pub wszDescription: [u16; 48],\n    pub wszFixedWidthFont: [u16; 32],\n    pub wszProportionalFont: [u16; 32],\n}\nimpl Default for SCRIPTINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_ANALYSIS {\n    pub _bitfield: u16,\n    pub s: SCRIPT_STATE,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_CHARPROP {\n    pub _bitfield: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_CONTROL {\n    pub _bitfield: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_DIGITSUBSTITUTE {\n    pub _bitfield1: u32,\n    pub _bitfield2: u32,\n    pub dwReserved: u32,\n}\npub const SCRIPT_DIGITSUBSTITUTE_CONTEXT: u32 = 0u32;\npub const SCRIPT_DIGITSUBSTITUTE_NATIONAL: u32 = 2u32;\npub const SCRIPT_DIGITSUBSTITUTE_NONE: u32 = 1u32;\npub const SCRIPT_DIGITSUBSTITUTE_TRADITIONAL: u32 = 3u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_FONTPROPERTIES {\n    pub cBytes: i32,\n    pub wgBlank: u16,\n    pub wgDefault: u16,\n    pub wgInvalid: u16,\n    pub wgKashida: u16,\n    pub iKashidaWidth: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_GLYPHPROP {\n    pub sva: SCRIPT_VISATTR,\n    pub reserved: u16,\n}\npub type SCRIPT_IS_COMPLEX_FLAGS = u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_ITEM {\n    pub iCharPos: i32,\n    pub a: SCRIPT_ANALYSIS,\n}\npub type SCRIPT_JUSTIFY = i32;\npub const SCRIPT_JUSTIFY_ARABIC_ALEF: SCRIPT_JUSTIFY = 9i32;\npub const SCRIPT_JUSTIFY_ARABIC_BA: SCRIPT_JUSTIFY = 12i32;\npub const SCRIPT_JUSTIFY_ARABIC_BARA: SCRIPT_JUSTIFY = 13i32;\npub const SCRIPT_JUSTIFY_ARABIC_BLANK: SCRIPT_JUSTIFY = 1i32;\npub const SCRIPT_JUSTIFY_ARABIC_HA: SCRIPT_JUSTIFY = 10i32;\npub const SCRIPT_JUSTIFY_ARABIC_KASHIDA: SCRIPT_JUSTIFY = 8i32;\npub const SCRIPT_JUSTIFY_ARABIC_NORMAL: SCRIPT_JUSTIFY = 7i32;\npub const SCRIPT_JUSTIFY_ARABIC_RA: SCRIPT_JUSTIFY = 11i32;\npub const SCRIPT_JUSTIFY_ARABIC_SEEN: SCRIPT_JUSTIFY = 14i32;\npub const SCRIPT_JUSTIFY_ARABIC_SEEN_M: SCRIPT_JUSTIFY = 15i32;\npub const SCRIPT_JUSTIFY_BLANK: SCRIPT_JUSTIFY = 4i32;\npub const SCRIPT_JUSTIFY_CHARACTER: SCRIPT_JUSTIFY = 2i32;\npub const SCRIPT_JUSTIFY_NONE: SCRIPT_JUSTIFY = 0i32;\npub const SCRIPT_JUSTIFY_RESERVED1: SCRIPT_JUSTIFY = 3i32;\npub const SCRIPT_JUSTIFY_RESERVED2: SCRIPT_JUSTIFY = 5i32;\npub const SCRIPT_JUSTIFY_RESERVED3: SCRIPT_JUSTIFY = 6i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_LOGATTR {\n    pub _bitfield: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_PROPERTIES {\n    pub _bitfield1: u32,\n    pub _bitfield2: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_STATE {\n    pub _bitfield: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCRIPT_TABDEF {\n    pub cTabStops: i32,\n    pub iScale: i32,\n    pub pTabStops: *mut i32,\n    pub iTabOrigin: i32,\n}\nimpl Default for SCRIPT_TABDEF {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SCRIPT_TAG_UNKNOWN: u32 = 0u32;\npub const SCRIPT_UNDEFINED: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCRIPT_VISATTR {\n    pub _bitfield: u16,\n}\npub const SGCM_RTL: u32 = 1u32;\npub const SIC_ASCIIDIGIT: SCRIPT_IS_COMPLEX_FLAGS = 2u32;\npub const SIC_COMPLEX: SCRIPT_IS_COMPLEX_FLAGS = 1u32;\npub const SIC_NEUTRAL: SCRIPT_IS_COMPLEX_FLAGS = 4u32;\npub const SORTING_PARADIGM_ICU: u32 = 16777216u32;\npub const SORTING_PARADIGM_NLS: u32 = 0u32;\npub const SORT_DIGITSASNUMBERS: COMPARE_STRING_FLAGS = 8u32;\npub const SORT_STRINGSORT: COMPARE_STRING_FLAGS = 4096u32;\npub const SSA_BREAK: u32 = 64u32;\npub const SSA_CLIP: u32 = 4u32;\npub const SSA_DONTGLYPH: u32 = 1073741824u32;\npub const SSA_DZWG: u32 = 16u32;\npub const SSA_FALLBACK: u32 = 32u32;\npub const SSA_FIT: u32 = 8u32;\npub const SSA_FULLMEASURE: u32 = 67108864u32;\npub const SSA_GCP: u32 = 512u32;\npub const SSA_GLYPHS: u32 = 128u32;\npub const SSA_HIDEHOTKEY: u32 = 8192u32;\npub const SSA_HOTKEY: u32 = 1024u32;\npub const SSA_HOTKEYONLY: u32 = 9216u32;\npub const SSA_LAYOUTRTL: u32 = 536870912u32;\npub const SSA_LINK: u32 = 4096u32;\npub const SSA_LPKANSIFALLBACK: u32 = 134217728u32;\npub const SSA_METAFILE: u32 = 2048u32;\npub const SSA_NOKASHIDA: u32 = 2147483648u32;\npub const SSA_PASSWORD: u32 = 1u32;\npub const SSA_PIDX: u32 = 268435456u32;\npub const SSA_RTL: u32 = 256u32;\npub const SSA_TAB: u32 = 2u32;\npub type SYSGEOCLASS = i32;\npub type SYSGEOTYPE = i32;\npub type SYSNLS_FUNCTION = i32;\npub const SecondUnit: CALDATETIME_DATEUNIT = 7i32;\npub const SpellCheckerFactory: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7ab36653_1796_484b_bdfa_e74f1db7c1dc);\npub const TCI_SRCCHARSET: TRANSLATE_CHARSET_INFO_FLAGS = 1u32;\npub const TCI_SRCCODEPAGE: TRANSLATE_CHARSET_INFO_FLAGS = 2u32;\npub const TCI_SRCFONTSIG: TRANSLATE_CHARSET_INFO_FLAGS = 3u32;\npub const TCI_SRCLOCALE: TRANSLATE_CHARSET_INFO_FLAGS = 4096u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TEXTRANGE_PROPERTIES {\n    pub potfRecords: *mut OPENTYPE_FEATURE_RECORD,\n    pub cotfRecords: i32,\n}\nimpl Default for TEXTRANGE_PROPERTIES {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type TIMEFMT_ENUMPROCA = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCSTR) -> windows_sys::core::BOOL>;\npub type TIMEFMT_ENUMPROCEX = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR, param1: super::Foundation::LPARAM) -> windows_sys::core::BOOL>;\npub type TIMEFMT_ENUMPROCW = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR) -> windows_sys::core::BOOL>;\npub const TIME_FORCE24HOURFORMAT: TIME_FORMAT_FLAGS = 8u32;\npub type TIME_FORMAT_FLAGS = u32;\npub const TIME_NOMINUTESORSECONDS: TIME_FORMAT_FLAGS = 1u32;\npub const TIME_NOSECONDS: TIME_FORMAT_FLAGS = 2u32;\npub const TIME_NOTIMEMARKER: TIME_FORMAT_FLAGS = 4u32;\npub type TRANSLATE_CHARSET_INFO_FLAGS = u32;\npub const TickUnit: CALDATETIME_DATEUNIT = 8i32;\npub const U16_MAX_LENGTH: u32 = 2u32;\npub const U8_LEAD3_T1_BITS: windows_sys::core::PCSTR = windows_sys::core::s!(\" 000000000000\\u{10}00\");\npub const U8_LEAD4_T1_BITS: windows_sys::core::PCSTR = windows_sys::core::s!(\"\\u{0}\\u{0}\\u{0}\\u{0}\\u{0}\\u{0}\\u{0}\\u{0}\\u{1e}\\u{f}\\u{f}\\u{f}\\u{0}\\u{0}\\u{0}\\u{0}\");\npub const U8_MAX_LENGTH: u32 = 4u32;\npub type UAcceptResult = i32;\npub type UAlphabeticIndexLabelType = i32;\npub const UBIDI_DEFAULT_LTR: u32 = 254u32;\npub const UBIDI_DEFAULT_RTL: u32 = 255u32;\npub const UBIDI_DO_MIRRORING: u32 = 2u32;\npub const UBIDI_INSERT_LRM_FOR_NUMERIC: u32 = 4u32;\npub const UBIDI_KEEP_BASE_COMBINING: u32 = 1u32;\npub const UBIDI_LEVEL_OVERRIDE: u32 = 128u32;\npub const UBIDI_LOGICAL: UBiDiOrder = 0i32;\npub const UBIDI_LTR: UBiDiDirection = 0i32;\npub const UBIDI_MAP_NOWHERE: i32 = -1i32;\npub const UBIDI_MAX_EXPLICIT_LEVEL: u32 = 125u32;\npub const UBIDI_MIRRORING_OFF: UBiDiMirroring = 0i32;\npub const UBIDI_MIRRORING_ON: UBiDiMirroring = 1i32;\npub const UBIDI_MIXED: UBiDiDirection = 2i32;\npub const UBIDI_NEUTRAL: UBiDiDirection = 3i32;\npub const UBIDI_OPTION_DEFAULT: UBiDiReorderingOption = 0i32;\npub const UBIDI_OPTION_INSERT_MARKS: UBiDiReorderingOption = 1i32;\npub const UBIDI_OPTION_REMOVE_CONTROLS: UBiDiReorderingOption = 2i32;\npub const UBIDI_OPTION_STREAMING: UBiDiReorderingOption = 4i32;\npub const UBIDI_OUTPUT_REVERSE: u32 = 16u32;\npub const UBIDI_REMOVE_BIDI_CONTROLS: u32 = 8u32;\npub const UBIDI_REORDER_DEFAULT: UBiDiReorderingMode = 0i32;\npub const UBIDI_REORDER_GROUP_NUMBERS_WITH_R: UBiDiReorderingMode = 2i32;\npub const UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL: UBiDiReorderingMode = 6i32;\npub const UBIDI_REORDER_INVERSE_LIKE_DIRECT: UBiDiReorderingMode = 5i32;\npub const UBIDI_REORDER_INVERSE_NUMBERS_AS_L: UBiDiReorderingMode = 4i32;\npub const UBIDI_REORDER_NUMBERS_SPECIAL: UBiDiReorderingMode = 1i32;\npub const UBIDI_REORDER_RUNS_ONLY: UBiDiReorderingMode = 3i32;\npub const UBIDI_RTL: UBiDiDirection = 1i32;\npub const UBIDI_VISUAL: UBiDiOrder = 1i32;\npub const UBLOCK_ADLAM: UBlockCode = 263i32;\npub const UBLOCK_AEGEAN_NUMBERS: UBlockCode = 119i32;\npub const UBLOCK_AHOM: UBlockCode = 253i32;\npub const UBLOCK_ALCHEMICAL_SYMBOLS: UBlockCode = 208i32;\npub const UBLOCK_ALPHABETIC_PRESENTATION_FORMS: UBlockCode = 80i32;\npub const UBLOCK_ANATOLIAN_HIEROGLYPHS: UBlockCode = 254i32;\npub const UBLOCK_ANCIENT_GREEK_MUSICAL_NOTATION: UBlockCode = 126i32;\npub const UBLOCK_ANCIENT_GREEK_NUMBERS: UBlockCode = 127i32;\npub const UBLOCK_ANCIENT_SYMBOLS: UBlockCode = 165i32;\npub const UBLOCK_ARABIC: UBlockCode = 12i32;\npub const UBLOCK_ARABIC_EXTENDED_A: UBlockCode = 210i32;\npub const UBLOCK_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS: UBlockCode = 211i32;\npub const UBLOCK_ARABIC_PRESENTATION_FORMS_A: UBlockCode = 81i32;\npub const UBLOCK_ARABIC_PRESENTATION_FORMS_B: UBlockCode = 85i32;\npub const UBLOCK_ARABIC_SUPPLEMENT: UBlockCode = 128i32;\npub const UBLOCK_ARMENIAN: UBlockCode = 10i32;\npub const UBLOCK_ARROWS: UBlockCode = 46i32;\npub const UBLOCK_AVESTAN: UBlockCode = 188i32;\npub const UBLOCK_BALINESE: UBlockCode = 147i32;\npub const UBLOCK_BAMUM: UBlockCode = 177i32;\npub const UBLOCK_BAMUM_SUPPLEMENT: UBlockCode = 202i32;\npub const UBLOCK_BASIC_LATIN: UBlockCode = 1i32;\npub const UBLOCK_BASSA_VAH: UBlockCode = 221i32;\npub const UBLOCK_BATAK: UBlockCode = 199i32;\npub const UBLOCK_BENGALI: UBlockCode = 16i32;\npub const UBLOCK_BHAIKSUKI: UBlockCode = 264i32;\npub const UBLOCK_BLOCK_ELEMENTS: UBlockCode = 53i32;\npub const UBLOCK_BOPOMOFO: UBlockCode = 64i32;\npub const UBLOCK_BOPOMOFO_EXTENDED: UBlockCode = 67i32;\npub const UBLOCK_BOX_DRAWING: UBlockCode = 52i32;\npub const UBLOCK_BRAHMI: UBlockCode = 201i32;\npub const UBLOCK_BRAILLE_PATTERNS: UBlockCode = 57i32;\npub const UBLOCK_BUGINESE: UBlockCode = 129i32;\npub const UBLOCK_BUHID: UBlockCode = 100i32;\npub const UBLOCK_BYZANTINE_MUSICAL_SYMBOLS: UBlockCode = 91i32;\npub const UBLOCK_CARIAN: UBlockCode = 168i32;\npub const UBLOCK_CAUCASIAN_ALBANIAN: UBlockCode = 222i32;\npub const UBLOCK_CHAKMA: UBlockCode = 212i32;\npub const UBLOCK_CHAM: UBlockCode = 164i32;\npub const UBLOCK_CHEROKEE: UBlockCode = 32i32;\npub const UBLOCK_CHEROKEE_SUPPLEMENT: UBlockCode = 255i32;\npub const UBLOCK_CHESS_SYMBOLS: UBlockCode = 281i32;\npub const UBLOCK_CHORASMIAN: UBlockCode = 301i32;\npub const UBLOCK_CJK_COMPATIBILITY: UBlockCode = 69i32;\npub const UBLOCK_CJK_COMPATIBILITY_FORMS: UBlockCode = 83i32;\npub const UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS: UBlockCode = 79i32;\npub const UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT: UBlockCode = 95i32;\npub const UBLOCK_CJK_RADICALS_SUPPLEMENT: UBlockCode = 58i32;\npub const UBLOCK_CJK_STROKES: UBlockCode = 130i32;\npub const UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION: UBlockCode = 61i32;\npub const UBLOCK_CJK_UNIFIED_IDEOGRAPHS: UBlockCode = 71i32;\npub const UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A: UBlockCode = 70i32;\npub const UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B: UBlockCode = 94i32;\npub const UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C: UBlockCode = 197i32;\npub const UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D: UBlockCode = 209i32;\npub const UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_E: UBlockCode = 256i32;\npub const UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F: UBlockCode = 274i32;\npub const UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G: UBlockCode = 302i32;\npub const UBLOCK_COMBINING_DIACRITICAL_MARKS: UBlockCode = 7i32;\npub const UBLOCK_COMBINING_DIACRITICAL_MARKS_EXTENDED: UBlockCode = 224i32;\npub const UBLOCK_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT: UBlockCode = 131i32;\npub const UBLOCK_COMBINING_HALF_MARKS: UBlockCode = 82i32;\npub const UBLOCK_COMBINING_MARKS_FOR_SYMBOLS: UBlockCode = 43i32;\npub const UBLOCK_COMMON_INDIC_NUMBER_FORMS: UBlockCode = 178i32;\npub const UBLOCK_CONTROL_PICTURES: UBlockCode = 49i32;\npub const UBLOCK_COPTIC: UBlockCode = 132i32;\npub const UBLOCK_COPTIC_EPACT_NUMBERS: UBlockCode = 223i32;\npub const UBLOCK_COUNTING_ROD_NUMERALS: UBlockCode = 154i32;\npub const UBLOCK_CUNEIFORM: UBlockCode = 152i32;\npub const UBLOCK_CUNEIFORM_NUMBERS_AND_PUNCTUATION: UBlockCode = 153i32;\npub const UBLOCK_CURRENCY_SYMBOLS: UBlockCode = 42i32;\npub const UBLOCK_CYPRIOT_SYLLABARY: UBlockCode = 123i32;\npub const UBLOCK_CYRILLIC: UBlockCode = 9i32;\npub const UBLOCK_CYRILLIC_EXTENDED_A: UBlockCode = 158i32;\npub const UBLOCK_CYRILLIC_EXTENDED_B: UBlockCode = 160i32;\npub const UBLOCK_CYRILLIC_EXTENDED_C: UBlockCode = 265i32;\npub const UBLOCK_CYRILLIC_SUPPLEMENT: UBlockCode = 97i32;\npub const UBLOCK_CYRILLIC_SUPPLEMENTARY: UBlockCode = 97i32;\npub const UBLOCK_DESERET: UBlockCode = 90i32;\npub const UBLOCK_DEVANAGARI: UBlockCode = 15i32;\npub const UBLOCK_DEVANAGARI_EXTENDED: UBlockCode = 179i32;\npub const UBLOCK_DINGBATS: UBlockCode = 56i32;\npub const UBLOCK_DIVES_AKURU: UBlockCode = 303i32;\npub const UBLOCK_DOGRA: UBlockCode = 282i32;\npub const UBLOCK_DOMINO_TILES: UBlockCode = 171i32;\npub const UBLOCK_DUPLOYAN: UBlockCode = 225i32;\npub const UBLOCK_EARLY_DYNASTIC_CUNEIFORM: UBlockCode = 257i32;\npub const UBLOCK_EGYPTIAN_HIEROGLYPHS: UBlockCode = 194i32;\npub const UBLOCK_EGYPTIAN_HIEROGLYPH_FORMAT_CONTROLS: UBlockCode = 292i32;\npub const UBLOCK_ELBASAN: UBlockCode = 226i32;\npub const UBLOCK_ELYMAIC: UBlockCode = 293i32;\npub const UBLOCK_EMOTICONS: UBlockCode = 206i32;\npub const UBLOCK_ENCLOSED_ALPHANUMERICS: UBlockCode = 51i32;\npub const UBLOCK_ENCLOSED_ALPHANUMERIC_SUPPLEMENT: UBlockCode = 195i32;\npub const UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS: UBlockCode = 68i32;\npub const UBLOCK_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT: UBlockCode = 196i32;\npub const UBLOCK_ETHIOPIC: UBlockCode = 31i32;\npub const UBLOCK_ETHIOPIC_EXTENDED: UBlockCode = 133i32;\npub const UBLOCK_ETHIOPIC_EXTENDED_A: UBlockCode = 200i32;\npub const UBLOCK_ETHIOPIC_SUPPLEMENT: UBlockCode = 134i32;\npub const UBLOCK_GENERAL_PUNCTUATION: UBlockCode = 40i32;\npub const UBLOCK_GEOMETRIC_SHAPES: UBlockCode = 54i32;\npub const UBLOCK_GEOMETRIC_SHAPES_EXTENDED: UBlockCode = 227i32;\npub const UBLOCK_GEORGIAN: UBlockCode = 29i32;\npub const UBLOCK_GEORGIAN_EXTENDED: UBlockCode = 283i32;\npub const UBLOCK_GEORGIAN_SUPPLEMENT: UBlockCode = 135i32;\npub const UBLOCK_GLAGOLITIC: UBlockCode = 136i32;\npub const UBLOCK_GLAGOLITIC_SUPPLEMENT: UBlockCode = 266i32;\npub const UBLOCK_GOTHIC: UBlockCode = 89i32;\npub const UBLOCK_GRANTHA: UBlockCode = 228i32;\npub const UBLOCK_GREEK: UBlockCode = 8i32;\npub const UBLOCK_GREEK_EXTENDED: UBlockCode = 39i32;\npub const UBLOCK_GUJARATI: UBlockCode = 18i32;\npub const UBLOCK_GUNJALA_GONDI: UBlockCode = 284i32;\npub const UBLOCK_GURMUKHI: UBlockCode = 17i32;\npub const UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS: UBlockCode = 87i32;\npub const UBLOCK_HANGUL_COMPATIBILITY_JAMO: UBlockCode = 65i32;\npub const UBLOCK_HANGUL_JAMO: UBlockCode = 30i32;\npub const UBLOCK_HANGUL_JAMO_EXTENDED_A: UBlockCode = 180i32;\npub const UBLOCK_HANGUL_JAMO_EXTENDED_B: UBlockCode = 185i32;\npub const UBLOCK_HANGUL_SYLLABLES: UBlockCode = 74i32;\npub const UBLOCK_HANIFI_ROHINGYA: UBlockCode = 285i32;\npub const UBLOCK_HANUNOO: UBlockCode = 99i32;\npub const UBLOCK_HATRAN: UBlockCode = 258i32;\npub const UBLOCK_HEBREW: UBlockCode = 11i32;\npub const UBLOCK_HIGH_PRIVATE_USE_SURROGATES: UBlockCode = 76i32;\npub const UBLOCK_HIGH_SURROGATES: UBlockCode = 75i32;\npub const UBLOCK_HIRAGANA: UBlockCode = 62i32;\npub const UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS: UBlockCode = 60i32;\npub const UBLOCK_IDEOGRAPHIC_SYMBOLS_AND_PUNCTUATION: UBlockCode = 267i32;\npub const UBLOCK_IMPERIAL_ARAMAIC: UBlockCode = 186i32;\npub const UBLOCK_INDIC_SIYAQ_NUMBERS: UBlockCode = 286i32;\npub const UBLOCK_INSCRIPTIONAL_PAHLAVI: UBlockCode = 190i32;\npub const UBLOCK_INSCRIPTIONAL_PARTHIAN: UBlockCode = 189i32;\npub const UBLOCK_INVALID_CODE: UBlockCode = -1i32;\npub const UBLOCK_IPA_EXTENSIONS: UBlockCode = 5i32;\npub const UBLOCK_JAVANESE: UBlockCode = 181i32;\npub const UBLOCK_KAITHI: UBlockCode = 193i32;\npub const UBLOCK_KANA_EXTENDED_A: UBlockCode = 275i32;\npub const UBLOCK_KANA_SUPPLEMENT: UBlockCode = 203i32;\npub const UBLOCK_KANBUN: UBlockCode = 66i32;\npub const UBLOCK_KANGXI_RADICALS: UBlockCode = 59i32;\npub const UBLOCK_KANNADA: UBlockCode = 22i32;\npub const UBLOCK_KATAKANA: UBlockCode = 63i32;\npub const UBLOCK_KATAKANA_PHONETIC_EXTENSIONS: UBlockCode = 107i32;\npub const UBLOCK_KAYAH_LI: UBlockCode = 162i32;\npub const UBLOCK_KHAROSHTHI: UBlockCode = 137i32;\npub const UBLOCK_KHITAN_SMALL_SCRIPT: UBlockCode = 304i32;\npub const UBLOCK_KHMER: UBlockCode = 36i32;\npub const UBLOCK_KHMER_SYMBOLS: UBlockCode = 113i32;\npub const UBLOCK_KHOJKI: UBlockCode = 229i32;\npub const UBLOCK_KHUDAWADI: UBlockCode = 230i32;\npub const UBLOCK_LAO: UBlockCode = 26i32;\npub const UBLOCK_LATIN_1_SUPPLEMENT: UBlockCode = 2i32;\npub const UBLOCK_LATIN_EXTENDED_A: UBlockCode = 3i32;\npub const UBLOCK_LATIN_EXTENDED_ADDITIONAL: UBlockCode = 38i32;\npub const UBLOCK_LATIN_EXTENDED_B: UBlockCode = 4i32;\npub const UBLOCK_LATIN_EXTENDED_C: UBlockCode = 148i32;\npub const UBLOCK_LATIN_EXTENDED_D: UBlockCode = 149i32;\npub const UBLOCK_LATIN_EXTENDED_E: UBlockCode = 231i32;\npub const UBLOCK_LEPCHA: UBlockCode = 156i32;\npub const UBLOCK_LETTERLIKE_SYMBOLS: UBlockCode = 44i32;\npub const UBLOCK_LIMBU: UBlockCode = 111i32;\npub const UBLOCK_LINEAR_A: UBlockCode = 232i32;\npub const UBLOCK_LINEAR_B_IDEOGRAMS: UBlockCode = 118i32;\npub const UBLOCK_LINEAR_B_SYLLABARY: UBlockCode = 117i32;\npub const UBLOCK_LISU: UBlockCode = 176i32;\npub const UBLOCK_LISU_SUPPLEMENT: UBlockCode = 305i32;\npub const UBLOCK_LOW_SURROGATES: UBlockCode = 77i32;\npub const UBLOCK_LYCIAN: UBlockCode = 167i32;\npub const UBLOCK_LYDIAN: UBlockCode = 169i32;\npub const UBLOCK_MAHAJANI: UBlockCode = 233i32;\npub const UBLOCK_MAHJONG_TILES: UBlockCode = 170i32;\npub const UBLOCK_MAKASAR: UBlockCode = 287i32;\npub const UBLOCK_MALAYALAM: UBlockCode = 23i32;\npub const UBLOCK_MANDAIC: UBlockCode = 198i32;\npub const UBLOCK_MANICHAEAN: UBlockCode = 234i32;\npub const UBLOCK_MARCHEN: UBlockCode = 268i32;\npub const UBLOCK_MASARAM_GONDI: UBlockCode = 276i32;\npub const UBLOCK_MATHEMATICAL_ALPHANUMERIC_SYMBOLS: UBlockCode = 93i32;\npub const UBLOCK_MATHEMATICAL_OPERATORS: UBlockCode = 47i32;\npub const UBLOCK_MAYAN_NUMERALS: UBlockCode = 288i32;\npub const UBLOCK_MEDEFAIDRIN: UBlockCode = 289i32;\npub const UBLOCK_MEETEI_MAYEK: UBlockCode = 184i32;\npub const UBLOCK_MEETEI_MAYEK_EXTENSIONS: UBlockCode = 213i32;\npub const UBLOCK_MENDE_KIKAKUI: UBlockCode = 235i32;\npub const UBLOCK_MEROITIC_CURSIVE: UBlockCode = 214i32;\npub const UBLOCK_MEROITIC_HIEROGLYPHS: UBlockCode = 215i32;\npub const UBLOCK_MIAO: UBlockCode = 216i32;\npub const UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A: UBlockCode = 102i32;\npub const UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B: UBlockCode = 105i32;\npub const UBLOCK_MISCELLANEOUS_SYMBOLS: UBlockCode = 55i32;\npub const UBLOCK_MISCELLANEOUS_SYMBOLS_AND_ARROWS: UBlockCode = 115i32;\npub const UBLOCK_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS: UBlockCode = 205i32;\npub const UBLOCK_MISCELLANEOUS_TECHNICAL: UBlockCode = 48i32;\npub const UBLOCK_MODI: UBlockCode = 236i32;\npub const UBLOCK_MODIFIER_TONE_LETTERS: UBlockCode = 138i32;\npub const UBLOCK_MONGOLIAN: UBlockCode = 37i32;\npub const UBLOCK_MONGOLIAN_SUPPLEMENT: UBlockCode = 269i32;\npub const UBLOCK_MRO: UBlockCode = 237i32;\npub const UBLOCK_MULTANI: UBlockCode = 259i32;\npub const UBLOCK_MUSICAL_SYMBOLS: UBlockCode = 92i32;\npub const UBLOCK_MYANMAR: UBlockCode = 28i32;\npub const UBLOCK_MYANMAR_EXTENDED_A: UBlockCode = 182i32;\npub const UBLOCK_MYANMAR_EXTENDED_B: UBlockCode = 238i32;\npub const UBLOCK_NABATAEAN: UBlockCode = 239i32;\npub const UBLOCK_NANDINAGARI: UBlockCode = 294i32;\npub const UBLOCK_NEWA: UBlockCode = 270i32;\npub const UBLOCK_NEW_TAI_LUE: UBlockCode = 139i32;\npub const UBLOCK_NKO: UBlockCode = 146i32;\npub const UBLOCK_NO_BLOCK: UBlockCode = 0i32;\npub const UBLOCK_NUMBER_FORMS: UBlockCode = 45i32;\npub const UBLOCK_NUSHU: UBlockCode = 277i32;\npub const UBLOCK_NYIAKENG_PUACHUE_HMONG: UBlockCode = 295i32;\npub const UBLOCK_OGHAM: UBlockCode = 34i32;\npub const UBLOCK_OLD_HUNGARIAN: UBlockCode = 260i32;\npub const UBLOCK_OLD_ITALIC: UBlockCode = 88i32;\npub const UBLOCK_OLD_NORTH_ARABIAN: UBlockCode = 240i32;\npub const UBLOCK_OLD_PERMIC: UBlockCode = 241i32;\npub const UBLOCK_OLD_PERSIAN: UBlockCode = 140i32;\npub const UBLOCK_OLD_SOGDIAN: UBlockCode = 290i32;\npub const UBLOCK_OLD_SOUTH_ARABIAN: UBlockCode = 187i32;\npub const UBLOCK_OLD_TURKIC: UBlockCode = 191i32;\npub const UBLOCK_OL_CHIKI: UBlockCode = 157i32;\npub const UBLOCK_OPTICAL_CHARACTER_RECOGNITION: UBlockCode = 50i32;\npub const UBLOCK_ORIYA: UBlockCode = 19i32;\npub const UBLOCK_ORNAMENTAL_DINGBATS: UBlockCode = 242i32;\npub const UBLOCK_OSAGE: UBlockCode = 271i32;\npub const UBLOCK_OSMANYA: UBlockCode = 122i32;\npub const UBLOCK_OTTOMAN_SIYAQ_NUMBERS: UBlockCode = 296i32;\npub const UBLOCK_PAHAWH_HMONG: UBlockCode = 243i32;\npub const UBLOCK_PALMYRENE: UBlockCode = 244i32;\npub const UBLOCK_PAU_CIN_HAU: UBlockCode = 245i32;\npub const UBLOCK_PHAGS_PA: UBlockCode = 150i32;\npub const UBLOCK_PHAISTOS_DISC: UBlockCode = 166i32;\npub const UBLOCK_PHOENICIAN: UBlockCode = 151i32;\npub const UBLOCK_PHONETIC_EXTENSIONS: UBlockCode = 114i32;\npub const UBLOCK_PHONETIC_EXTENSIONS_SUPPLEMENT: UBlockCode = 141i32;\npub const UBLOCK_PLAYING_CARDS: UBlockCode = 204i32;\npub const UBLOCK_PRIVATE_USE: UBlockCode = 78i32;\npub const UBLOCK_PRIVATE_USE_AREA: UBlockCode = 78i32;\npub const UBLOCK_PSALTER_PAHLAVI: UBlockCode = 246i32;\npub const UBLOCK_REJANG: UBlockCode = 163i32;\npub const UBLOCK_RUMI_NUMERAL_SYMBOLS: UBlockCode = 192i32;\npub const UBLOCK_RUNIC: UBlockCode = 35i32;\npub const UBLOCK_SAMARITAN: UBlockCode = 172i32;\npub const UBLOCK_SAURASHTRA: UBlockCode = 161i32;\npub const UBLOCK_SHARADA: UBlockCode = 217i32;\npub const UBLOCK_SHAVIAN: UBlockCode = 121i32;\npub const UBLOCK_SHORTHAND_FORMAT_CONTROLS: UBlockCode = 247i32;\npub const UBLOCK_SIDDHAM: UBlockCode = 248i32;\npub const UBLOCK_SINHALA: UBlockCode = 24i32;\npub const UBLOCK_SINHALA_ARCHAIC_NUMBERS: UBlockCode = 249i32;\npub const UBLOCK_SMALL_FORM_VARIANTS: UBlockCode = 84i32;\npub const UBLOCK_SMALL_KANA_EXTENSION: UBlockCode = 297i32;\npub const UBLOCK_SOGDIAN: UBlockCode = 291i32;\npub const UBLOCK_SORA_SOMPENG: UBlockCode = 218i32;\npub const UBLOCK_SOYOMBO: UBlockCode = 278i32;\npub const UBLOCK_SPACING_MODIFIER_LETTERS: UBlockCode = 6i32;\npub const UBLOCK_SPECIALS: UBlockCode = 86i32;\npub const UBLOCK_SUNDANESE: UBlockCode = 155i32;\npub const UBLOCK_SUNDANESE_SUPPLEMENT: UBlockCode = 219i32;\npub const UBLOCK_SUPERSCRIPTS_AND_SUBSCRIPTS: UBlockCode = 41i32;\npub const UBLOCK_SUPPLEMENTAL_ARROWS_A: UBlockCode = 103i32;\npub const UBLOCK_SUPPLEMENTAL_ARROWS_B: UBlockCode = 104i32;\npub const UBLOCK_SUPPLEMENTAL_ARROWS_C: UBlockCode = 250i32;\npub const UBLOCK_SUPPLEMENTAL_MATHEMATICAL_OPERATORS: UBlockCode = 106i32;\npub const UBLOCK_SUPPLEMENTAL_PUNCTUATION: UBlockCode = 142i32;\npub const UBLOCK_SUPPLEMENTAL_SYMBOLS_AND_PICTOGRAPHS: UBlockCode = 261i32;\npub const UBLOCK_SUPPLEMENTARY_PRIVATE_USE_AREA_A: UBlockCode = 109i32;\npub const UBLOCK_SUPPLEMENTARY_PRIVATE_USE_AREA_B: UBlockCode = 110i32;\npub const UBLOCK_SUTTON_SIGNWRITING: UBlockCode = 262i32;\npub const UBLOCK_SYLOTI_NAGRI: UBlockCode = 143i32;\npub const UBLOCK_SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A: UBlockCode = 298i32;\npub const UBLOCK_SYMBOLS_FOR_LEGACY_COMPUTING: UBlockCode = 306i32;\npub const UBLOCK_SYRIAC: UBlockCode = 13i32;\npub const UBLOCK_SYRIAC_SUPPLEMENT: UBlockCode = 279i32;\npub const UBLOCK_TAGALOG: UBlockCode = 98i32;\npub const UBLOCK_TAGBANWA: UBlockCode = 101i32;\npub const UBLOCK_TAGS: UBlockCode = 96i32;\npub const UBLOCK_TAI_LE: UBlockCode = 112i32;\npub const UBLOCK_TAI_THAM: UBlockCode = 174i32;\npub const UBLOCK_TAI_VIET: UBlockCode = 183i32;\npub const UBLOCK_TAI_XUAN_JING_SYMBOLS: UBlockCode = 124i32;\npub const UBLOCK_TAKRI: UBlockCode = 220i32;\npub const UBLOCK_TAMIL: UBlockCode = 20i32;\npub const UBLOCK_TAMIL_SUPPLEMENT: UBlockCode = 299i32;\npub const UBLOCK_TANGUT: UBlockCode = 272i32;\npub const UBLOCK_TANGUT_COMPONENTS: UBlockCode = 273i32;\npub const UBLOCK_TANGUT_SUPPLEMENT: UBlockCode = 307i32;\npub const UBLOCK_TELUGU: UBlockCode = 21i32;\npub const UBLOCK_THAANA: UBlockCode = 14i32;\npub const UBLOCK_THAI: UBlockCode = 25i32;\npub const UBLOCK_TIBETAN: UBlockCode = 27i32;\npub const UBLOCK_TIFINAGH: UBlockCode = 144i32;\npub const UBLOCK_TIRHUTA: UBlockCode = 251i32;\npub const UBLOCK_TRANSPORT_AND_MAP_SYMBOLS: UBlockCode = 207i32;\npub const UBLOCK_UGARITIC: UBlockCode = 120i32;\npub const UBLOCK_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS: UBlockCode = 33i32;\npub const UBLOCK_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED: UBlockCode = 173i32;\npub const UBLOCK_VAI: UBlockCode = 159i32;\npub const UBLOCK_VARIATION_SELECTORS: UBlockCode = 108i32;\npub const UBLOCK_VARIATION_SELECTORS_SUPPLEMENT: UBlockCode = 125i32;\npub const UBLOCK_VEDIC_EXTENSIONS: UBlockCode = 175i32;\npub const UBLOCK_VERTICAL_FORMS: UBlockCode = 145i32;\npub const UBLOCK_WANCHO: UBlockCode = 300i32;\npub const UBLOCK_WARANG_CITI: UBlockCode = 252i32;\npub const UBLOCK_YEZIDI: UBlockCode = 308i32;\npub const UBLOCK_YIJING_HEXAGRAM_SYMBOLS: UBlockCode = 116i32;\npub const UBLOCK_YI_RADICALS: UBlockCode = 73i32;\npub const UBLOCK_YI_SYLLABLES: UBlockCode = 72i32;\npub const UBLOCK_ZANABAZAR_SQUARE: UBlockCode = 280i32;\npub const UBRK_CHARACTER: UBreakIteratorType = 0i32;\npub const UBRK_LINE: UBreakIteratorType = 2i32;\npub const UBRK_LINE_HARD: ULineBreakTag = 100i32;\npub const UBRK_LINE_HARD_LIMIT: ULineBreakTag = 200i32;\npub const UBRK_LINE_SOFT: ULineBreakTag = 0i32;\npub const UBRK_LINE_SOFT_LIMIT: ULineBreakTag = 100i32;\npub const UBRK_SENTENCE: UBreakIteratorType = 3i32;\npub const UBRK_SENTENCE_SEP: USentenceBreakTag = 100i32;\npub const UBRK_SENTENCE_SEP_LIMIT: USentenceBreakTag = 200i32;\npub const UBRK_SENTENCE_TERM: USentenceBreakTag = 0i32;\npub const UBRK_SENTENCE_TERM_LIMIT: USentenceBreakTag = 100i32;\npub const UBRK_WORD: UBreakIteratorType = 1i32;\npub const UBRK_WORD_IDEO: UWordBreak = 400i32;\npub const UBRK_WORD_IDEO_LIMIT: UWordBreak = 500i32;\npub const UBRK_WORD_KANA: UWordBreak = 300i32;\npub const UBRK_WORD_KANA_LIMIT: UWordBreak = 400i32;\npub const UBRK_WORD_LETTER: UWordBreak = 200i32;\npub const UBRK_WORD_LETTER_LIMIT: UWordBreak = 300i32;\npub const UBRK_WORD_NONE: UWordBreak = 0i32;\npub const UBRK_WORD_NONE_LIMIT: UWordBreak = 100i32;\npub const UBRK_WORD_NUMBER: UWordBreak = 100i32;\npub const UBRK_WORD_NUMBER_LIMIT: UWordBreak = 200i32;\npub type UBiDi = isize;\npub type UBiDiClassCallback = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, c: i32) -> UCharDirection>;\npub type UBiDiDirection = i32;\npub type UBiDiMirroring = i32;\npub type UBiDiOrder = i32;\npub type UBiDiReorderingMode = i32;\npub type UBiDiReorderingOption = i32;\npub type UBiDiTransform = isize;\npub type UBidiPairedBracketType = i32;\npub type UBlockCode = i32;\npub type UBreakIterator = isize;\npub type UBreakIteratorType = i32;\npub const UCAL_ACTUAL_MAXIMUM: UCalendarLimitType = 5i32;\npub const UCAL_ACTUAL_MINIMUM: UCalendarLimitType = 4i32;\npub const UCAL_AM: UCalendarAMPMs = 0i32;\npub const UCAL_AM_PM: UCalendarDateFields = 9i32;\npub const UCAL_APRIL: UCalendarMonths = 3i32;\npub const UCAL_AUGUST: UCalendarMonths = 7i32;\npub const UCAL_DATE: UCalendarDateFields = 5i32;\npub const UCAL_DAY_OF_MONTH: UCalendarDateFields = 5i32;\npub const UCAL_DAY_OF_WEEK: UCalendarDateFields = 7i32;\npub const UCAL_DAY_OF_WEEK_IN_MONTH: UCalendarDateFields = 8i32;\npub const UCAL_DAY_OF_YEAR: UCalendarDateFields = 6i32;\npub const UCAL_DECEMBER: UCalendarMonths = 11i32;\npub const UCAL_DEFAULT: UCalendarType = 0i32;\npub const UCAL_DOW_LOCAL: UCalendarDateFields = 18i32;\npub const UCAL_DST: UCalendarDisplayNameType = 2i32;\npub const UCAL_DST_OFFSET: UCalendarDateFields = 16i32;\npub const UCAL_ERA: UCalendarDateFields = 0i32;\npub const UCAL_EXTENDED_YEAR: UCalendarDateFields = 19i32;\npub const UCAL_FEBRUARY: UCalendarMonths = 1i32;\npub const UCAL_FIELD_COUNT: UCalendarDateFields = 23i32;\npub const UCAL_FIRST_DAY_OF_WEEK: UCalendarAttribute = 1i32;\npub const UCAL_FRIDAY: UCalendarDaysOfWeek = 6i32;\npub const UCAL_GREATEST_MINIMUM: UCalendarLimitType = 2i32;\npub const UCAL_GREGORIAN: UCalendarType = 1i32;\npub const UCAL_HOUR: UCalendarDateFields = 10i32;\npub const UCAL_HOUR_OF_DAY: UCalendarDateFields = 11i32;\npub const UCAL_IS_LEAP_MONTH: UCalendarDateFields = 22i32;\npub const UCAL_JANUARY: UCalendarMonths = 0i32;\npub const UCAL_JULIAN_DAY: UCalendarDateFields = 20i32;\npub const UCAL_JULY: UCalendarMonths = 6i32;\npub const UCAL_JUNE: UCalendarMonths = 5i32;\npub const UCAL_LEAST_MAXIMUM: UCalendarLimitType = 3i32;\npub const UCAL_LENIENT: UCalendarAttribute = 0i32;\npub const UCAL_MARCH: UCalendarMonths = 2i32;\npub const UCAL_MAXIMUM: UCalendarLimitType = 1i32;\npub const UCAL_MAY: UCalendarMonths = 4i32;\npub const UCAL_MILLISECOND: UCalendarDateFields = 14i32;\npub const UCAL_MILLISECONDS_IN_DAY: UCalendarDateFields = 21i32;\npub const UCAL_MINIMAL_DAYS_IN_FIRST_WEEK: UCalendarAttribute = 2i32;\npub const UCAL_MINIMUM: UCalendarLimitType = 0i32;\npub const UCAL_MINUTE: UCalendarDateFields = 12i32;\npub const UCAL_MONDAY: UCalendarDaysOfWeek = 2i32;\npub const UCAL_MONTH: UCalendarDateFields = 2i32;\npub const UCAL_NOVEMBER: UCalendarMonths = 10i32;\npub const UCAL_OCTOBER: UCalendarMonths = 9i32;\npub const UCAL_PM: UCalendarAMPMs = 1i32;\npub const UCAL_REPEATED_WALL_TIME: UCalendarAttribute = 3i32;\npub const UCAL_SATURDAY: UCalendarDaysOfWeek = 7i32;\npub const UCAL_SECOND: UCalendarDateFields = 13i32;\npub const UCAL_SEPTEMBER: UCalendarMonths = 8i32;\npub const UCAL_SHORT_DST: UCalendarDisplayNameType = 3i32;\npub const UCAL_SHORT_STANDARD: UCalendarDisplayNameType = 1i32;\npub const UCAL_SKIPPED_WALL_TIME: UCalendarAttribute = 4i32;\npub const UCAL_STANDARD: UCalendarDisplayNameType = 0i32;\npub const UCAL_SUNDAY: UCalendarDaysOfWeek = 1i32;\npub const UCAL_THURSDAY: UCalendarDaysOfWeek = 5i32;\npub const UCAL_TRADITIONAL: UCalendarType = 0i32;\npub const UCAL_TUESDAY: UCalendarDaysOfWeek = 3i32;\npub const UCAL_TZ_TRANSITION_NEXT: UTimeZoneTransitionType = 0i32;\npub const UCAL_TZ_TRANSITION_NEXT_INCLUSIVE: UTimeZoneTransitionType = 1i32;\npub const UCAL_TZ_TRANSITION_PREVIOUS: UTimeZoneTransitionType = 2i32;\npub const UCAL_TZ_TRANSITION_PREVIOUS_INCLUSIVE: UTimeZoneTransitionType = 3i32;\npub const UCAL_UNDECIMBER: UCalendarMonths = 12i32;\npub const UCAL_UNKNOWN_ZONE_ID: windows_sys::core::PCSTR = windows_sys::core::s!(\"Etc/Unknown\");\npub const UCAL_WALLTIME_FIRST: UCalendarWallTimeOption = 1i32;\npub const UCAL_WALLTIME_LAST: UCalendarWallTimeOption = 0i32;\npub const UCAL_WALLTIME_NEXT_VALID: UCalendarWallTimeOption = 2i32;\npub const UCAL_WEDNESDAY: UCalendarDaysOfWeek = 4i32;\npub const UCAL_WEEKDAY: UCalendarWeekdayType = 0i32;\npub const UCAL_WEEKEND: UCalendarWeekdayType = 1i32;\npub const UCAL_WEEKEND_CEASE: UCalendarWeekdayType = 3i32;\npub const UCAL_WEEKEND_ONSET: UCalendarWeekdayType = 2i32;\npub const UCAL_WEEK_OF_MONTH: UCalendarDateFields = 4i32;\npub const UCAL_WEEK_OF_YEAR: UCalendarDateFields = 3i32;\npub const UCAL_YEAR: UCalendarDateFields = 1i32;\npub const UCAL_YEAR_WOY: UCalendarDateFields = 17i32;\npub const UCAL_ZONE_OFFSET: UCalendarDateFields = 15i32;\npub const UCAL_ZONE_TYPE_ANY: USystemTimeZoneType = 0i32;\npub const UCAL_ZONE_TYPE_CANONICAL: USystemTimeZoneType = 1i32;\npub const UCAL_ZONE_TYPE_CANONICAL_LOCATION: USystemTimeZoneType = 2i32;\npub const UCHAR_AGE: UProperty = 16384i32;\npub const UCHAR_ALPHABETIC: UProperty = 0i32;\npub const UCHAR_ASCII_HEX_DIGIT: UProperty = 1i32;\npub const UCHAR_BIDI_CLASS: UProperty = 4096i32;\npub const UCHAR_BIDI_CONTROL: UProperty = 2i32;\npub const UCHAR_BIDI_MIRRORED: UProperty = 3i32;\npub const UCHAR_BIDI_MIRRORING_GLYPH: UProperty = 16385i32;\npub const UCHAR_BIDI_PAIRED_BRACKET: UProperty = 16397i32;\npub const UCHAR_BIDI_PAIRED_BRACKET_TYPE: UProperty = 4117i32;\npub const UCHAR_BINARY_START: UProperty = 0i32;\npub const UCHAR_BLOCK: UProperty = 4097i32;\npub const UCHAR_CANONICAL_COMBINING_CLASS: UProperty = 4098i32;\npub const UCHAR_CASED: UProperty = 49i32;\npub const UCHAR_CASE_FOLDING: UProperty = 16386i32;\npub const UCHAR_CASE_IGNORABLE: UProperty = 50i32;\npub const UCHAR_CASE_SENSITIVE: UProperty = 34i32;\npub const UCHAR_CHANGES_WHEN_CASEFOLDED: UProperty = 54i32;\npub const UCHAR_CHANGES_WHEN_CASEMAPPED: UProperty = 55i32;\npub const UCHAR_CHANGES_WHEN_LOWERCASED: UProperty = 51i32;\npub const UCHAR_CHANGES_WHEN_NFKC_CASEFOLDED: UProperty = 56i32;\npub const UCHAR_CHANGES_WHEN_TITLECASED: UProperty = 53i32;\npub const UCHAR_CHANGES_WHEN_UPPERCASED: UProperty = 52i32;\npub const UCHAR_DASH: UProperty = 4i32;\npub const UCHAR_DECOMPOSITION_TYPE: UProperty = 4099i32;\npub const UCHAR_DEFAULT_IGNORABLE_CODE_POINT: UProperty = 5i32;\npub const UCHAR_DEPRECATED: UProperty = 6i32;\npub const UCHAR_DIACRITIC: UProperty = 7i32;\npub const UCHAR_DOUBLE_START: UProperty = 12288i32;\npub const UCHAR_EAST_ASIAN_WIDTH: UProperty = 4100i32;\npub const UCHAR_EMOJI: UProperty = 57i32;\npub const UCHAR_EMOJI_COMPONENT: UProperty = 61i32;\npub const UCHAR_EMOJI_MODIFIER: UProperty = 59i32;\npub const UCHAR_EMOJI_MODIFIER_BASE: UProperty = 60i32;\npub const UCHAR_EMOJI_PRESENTATION: UProperty = 58i32;\npub const UCHAR_EXTENDED_PICTOGRAPHIC: UProperty = 64i32;\npub const UCHAR_EXTENDER: UProperty = 8i32;\npub const UCHAR_FULL_COMPOSITION_EXCLUSION: UProperty = 9i32;\npub const UCHAR_GENERAL_CATEGORY: UProperty = 4101i32;\npub const UCHAR_GENERAL_CATEGORY_MASK: UProperty = 8192i32;\npub const UCHAR_GRAPHEME_BASE: UProperty = 10i32;\npub const UCHAR_GRAPHEME_CLUSTER_BREAK: UProperty = 4114i32;\npub const UCHAR_GRAPHEME_EXTEND: UProperty = 11i32;\npub const UCHAR_GRAPHEME_LINK: UProperty = 12i32;\npub const UCHAR_HANGUL_SYLLABLE_TYPE: UProperty = 4107i32;\npub const UCHAR_HEX_DIGIT: UProperty = 13i32;\npub const UCHAR_HYPHEN: UProperty = 14i32;\npub const UCHAR_IDEOGRAPHIC: UProperty = 17i32;\npub const UCHAR_IDS_BINARY_OPERATOR: UProperty = 18i32;\npub const UCHAR_IDS_TRINARY_OPERATOR: UProperty = 19i32;\npub const UCHAR_ID_CONTINUE: UProperty = 15i32;\npub const UCHAR_ID_START: UProperty = 16i32;\npub const UCHAR_INDIC_POSITIONAL_CATEGORY: UProperty = 4118i32;\npub const UCHAR_INDIC_SYLLABIC_CATEGORY: UProperty = 4119i32;\npub const UCHAR_INT_START: UProperty = 4096i32;\npub const UCHAR_INVALID_CODE: UProperty = -1i32;\npub const UCHAR_JOINING_GROUP: UProperty = 4102i32;\npub const UCHAR_JOINING_TYPE: UProperty = 4103i32;\npub const UCHAR_JOIN_CONTROL: UProperty = 20i32;\npub const UCHAR_LEAD_CANONICAL_COMBINING_CLASS: UProperty = 4112i32;\npub const UCHAR_LINE_BREAK: UProperty = 4104i32;\npub const UCHAR_LOGICAL_ORDER_EXCEPTION: UProperty = 21i32;\npub const UCHAR_LOWERCASE: UProperty = 22i32;\npub const UCHAR_LOWERCASE_MAPPING: UProperty = 16388i32;\npub const UCHAR_MASK_START: UProperty = 8192i32;\npub const UCHAR_MATH: UProperty = 23i32;\npub const UCHAR_MAX_VALUE: u32 = 1114111u32;\npub const UCHAR_MIN_VALUE: u32 = 0u32;\npub const UCHAR_NAME: UProperty = 16389i32;\npub const UCHAR_NFC_INERT: UProperty = 39i32;\npub const UCHAR_NFC_QUICK_CHECK: UProperty = 4110i32;\npub const UCHAR_NFD_INERT: UProperty = 37i32;\npub const UCHAR_NFD_QUICK_CHECK: UProperty = 4108i32;\npub const UCHAR_NFKC_INERT: UProperty = 40i32;\npub const UCHAR_NFKC_QUICK_CHECK: UProperty = 4111i32;\npub const UCHAR_NFKD_INERT: UProperty = 38i32;\npub const UCHAR_NFKD_QUICK_CHECK: UProperty = 4109i32;\npub const UCHAR_NONCHARACTER_CODE_POINT: UProperty = 24i32;\npub const UCHAR_NUMERIC_TYPE: UProperty = 4105i32;\npub const UCHAR_NUMERIC_VALUE: UProperty = 12288i32;\npub const UCHAR_OTHER_PROPERTY_START: UProperty = 28672i32;\npub const UCHAR_PATTERN_SYNTAX: UProperty = 42i32;\npub const UCHAR_PATTERN_WHITE_SPACE: UProperty = 43i32;\npub const UCHAR_POSIX_ALNUM: UProperty = 44i32;\npub const UCHAR_POSIX_BLANK: UProperty = 45i32;\npub const UCHAR_POSIX_GRAPH: UProperty = 46i32;\npub const UCHAR_POSIX_PRINT: UProperty = 47i32;\npub const UCHAR_POSIX_XDIGIT: UProperty = 48i32;\npub const UCHAR_PREPENDED_CONCATENATION_MARK: UProperty = 63i32;\npub const UCHAR_QUOTATION_MARK: UProperty = 25i32;\npub const UCHAR_RADICAL: UProperty = 26i32;\npub const UCHAR_REGIONAL_INDICATOR: UProperty = 62i32;\npub const UCHAR_SCRIPT: UProperty = 4106i32;\npub const UCHAR_SCRIPT_EXTENSIONS: UProperty = 28672i32;\npub const UCHAR_SEGMENT_STARTER: UProperty = 41i32;\npub const UCHAR_SENTENCE_BREAK: UProperty = 4115i32;\npub const UCHAR_SIMPLE_CASE_FOLDING: UProperty = 16390i32;\npub const UCHAR_SIMPLE_LOWERCASE_MAPPING: UProperty = 16391i32;\npub const UCHAR_SIMPLE_TITLECASE_MAPPING: UProperty = 16392i32;\npub const UCHAR_SIMPLE_UPPERCASE_MAPPING: UProperty = 16393i32;\npub const UCHAR_SOFT_DOTTED: UProperty = 27i32;\npub const UCHAR_STRING_START: UProperty = 16384i32;\npub const UCHAR_S_TERM: UProperty = 35i32;\npub const UCHAR_TERMINAL_PUNCTUATION: UProperty = 28i32;\npub const UCHAR_TITLECASE_MAPPING: UProperty = 16394i32;\npub const UCHAR_TRAIL_CANONICAL_COMBINING_CLASS: UProperty = 4113i32;\npub const UCHAR_UNIFIED_IDEOGRAPH: UProperty = 29i32;\npub const UCHAR_UPPERCASE: UProperty = 30i32;\npub const UCHAR_UPPERCASE_MAPPING: UProperty = 16396i32;\npub const UCHAR_VARIATION_SELECTOR: UProperty = 36i32;\npub const UCHAR_VERTICAL_ORIENTATION: UProperty = 4120i32;\npub const UCHAR_WHITE_SPACE: UProperty = 31i32;\npub const UCHAR_WORD_BREAK: UProperty = 4116i32;\npub const UCHAR_XID_CONTINUE: UProperty = 32i32;\npub const UCHAR_XID_START: UProperty = 33i32;\npub const UCLN_NO_AUTO_CLEANUP: u32 = 1u32;\npub const UCNV_BOCU1: UConverterType = 28i32;\npub const UCNV_CESU8: UConverterType = 31i32;\npub const UCNV_CLONE: UConverterCallbackReason = 5i32;\npub const UCNV_CLOSE: UConverterCallbackReason = 4i32;\npub const UCNV_COMPOUND_TEXT: UConverterType = 33i32;\npub const UCNV_DBCS: UConverterType = 1i32;\npub const UCNV_EBCDIC_STATEFUL: UConverterType = 9i32;\npub const UCNV_ESCAPE_C: windows_sys::core::PCSTR = windows_sys::core::s!(\"C\");\npub const UCNV_ESCAPE_CSS2: windows_sys::core::PCSTR = windows_sys::core::s!(\"S\");\npub const UCNV_ESCAPE_JAVA: windows_sys::core::PCSTR = windows_sys::core::s!(\"J\");\npub const UCNV_ESCAPE_UNICODE: windows_sys::core::PCSTR = windows_sys::core::s!(\"U\");\npub const UCNV_ESCAPE_XML_DEC: windows_sys::core::PCSTR = windows_sys::core::s!(\"D\");\npub const UCNV_ESCAPE_XML_HEX: windows_sys::core::PCSTR = windows_sys::core::s!(\"X\");\npub const UCNV_HZ: UConverterType = 23i32;\npub const UCNV_IBM: UConverterPlatform = 0i32;\npub const UCNV_ILLEGAL: UConverterCallbackReason = 1i32;\npub const UCNV_IMAP_MAILBOX: UConverterType = 32i32;\npub const UCNV_IRREGULAR: UConverterCallbackReason = 2i32;\npub const UCNV_ISCII: UConverterType = 25i32;\npub const UCNV_ISO_2022: UConverterType = 10i32;\npub const UCNV_LATIN_1: UConverterType = 3i32;\npub const UCNV_LMBCS_1: UConverterType = 11i32;\npub const UCNV_LMBCS_11: UConverterType = 18i32;\npub const UCNV_LMBCS_16: UConverterType = 19i32;\npub const UCNV_LMBCS_17: UConverterType = 20i32;\npub const UCNV_LMBCS_18: UConverterType = 21i32;\npub const UCNV_LMBCS_19: UConverterType = 22i32;\npub const UCNV_LMBCS_2: UConverterType = 12i32;\npub const UCNV_LMBCS_3: UConverterType = 13i32;\npub const UCNV_LMBCS_4: UConverterType = 14i32;\npub const UCNV_LMBCS_5: UConverterType = 15i32;\npub const UCNV_LMBCS_6: UConverterType = 16i32;\npub const UCNV_LMBCS_8: UConverterType = 17i32;\npub const UCNV_LMBCS_LAST: UConverterType = 22i32;\npub const UCNV_LOCALE_OPTION_STRING: windows_sys::core::PCSTR = windows_sys::core::s!(\",locale=\");\npub const UCNV_MAX_CONVERTER_NAME_LENGTH: u32 = 60u32;\npub const UCNV_MBCS: UConverterType = 2i32;\npub const UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES: UConverterType = 34i32;\npub const UCNV_OPTION_SEP_STRING: windows_sys::core::PCSTR = windows_sys::core::s!(\",\");\npub const UCNV_RESET: UConverterCallbackReason = 3i32;\npub const UCNV_ROUNDTRIP_AND_FALLBACK_SET: UConverterUnicodeSet = 1i32;\npub const UCNV_ROUNDTRIP_SET: UConverterUnicodeSet = 0i32;\npub const UCNV_SBCS: UConverterType = 0i32;\npub const UCNV_SCSU: UConverterType = 24i32;\npub const UCNV_SI: u32 = 15u32;\npub const UCNV_SKIP_STOP_ON_ILLEGAL: windows_sys::core::PCSTR = windows_sys::core::s!(\"i\");\npub const UCNV_SO: u32 = 14u32;\npub const UCNV_SUB_STOP_ON_ILLEGAL: windows_sys::core::PCSTR = windows_sys::core::s!(\"i\");\npub const UCNV_SWAP_LFNL_OPTION_STRING: windows_sys::core::PCSTR = windows_sys::core::s!(\",swaplfnl\");\npub const UCNV_UNASSIGNED: UConverterCallbackReason = 0i32;\npub const UCNV_UNKNOWN: UConverterPlatform = -1i32;\npub const UCNV_UNSUPPORTED_CONVERTER: UConverterType = -1i32;\npub const UCNV_US_ASCII: UConverterType = 26i32;\npub const UCNV_UTF16: UConverterType = 29i32;\npub const UCNV_UTF16_BigEndian: UConverterType = 5i32;\npub const UCNV_UTF16_LittleEndian: UConverterType = 6i32;\npub const UCNV_UTF32: UConverterType = 30i32;\npub const UCNV_UTF32_BigEndian: UConverterType = 7i32;\npub const UCNV_UTF32_LittleEndian: UConverterType = 8i32;\npub const UCNV_UTF7: UConverterType = 27i32;\npub const UCNV_UTF8: UConverterType = 4i32;\npub const UCNV_VALUE_SEP_STRING: windows_sys::core::PCSTR = windows_sys::core::s!(\"=\");\npub const UCNV_VERSION_OPTION_STRING: windows_sys::core::PCSTR = windows_sys::core::s!(\",version=\");\npub const UCOL_ALTERNATE_HANDLING: UColAttribute = 1i32;\npub const UCOL_ATTRIBUTE_COUNT: UColAttribute = 8i32;\npub const UCOL_BOUND_LOWER: UColBoundMode = 0i32;\npub const UCOL_BOUND_UPPER: UColBoundMode = 1i32;\npub const UCOL_BOUND_UPPER_LONG: UColBoundMode = 2i32;\npub const UCOL_CASE_FIRST: UColAttribute = 2i32;\npub const UCOL_CASE_LEVEL: UColAttribute = 3i32;\npub const UCOL_CE_STRENGTH_LIMIT: UColAttributeValue = 3i32;\npub const UCOL_DECOMPOSITION_MODE: UColAttribute = 4i32;\npub const UCOL_DEFAULT: UColAttributeValue = -1i32;\npub const UCOL_DEFAULT_STRENGTH: UColAttributeValue = 2i32;\npub const UCOL_EQUAL: UCollationResult = 0i32;\npub const UCOL_FRENCH_COLLATION: UColAttribute = 0i32;\npub const UCOL_FULL_RULES: UColRuleOption = 1i32;\npub const UCOL_GREATER: UCollationResult = 1i32;\npub const UCOL_IDENTICAL: UColAttributeValue = 15i32;\npub const UCOL_LESS: UCollationResult = -1i32;\npub const UCOL_LOWER_FIRST: UColAttributeValue = 24i32;\npub const UCOL_NON_IGNORABLE: UColAttributeValue = 21i32;\npub const UCOL_NORMALIZATION_MODE: UColAttribute = 4i32;\npub const UCOL_NUMERIC_COLLATION: UColAttribute = 7i32;\npub const UCOL_OFF: UColAttributeValue = 16i32;\npub const UCOL_ON: UColAttributeValue = 17i32;\npub const UCOL_PRIMARY: UColAttributeValue = 0i32;\npub const UCOL_QUATERNARY: UColAttributeValue = 3i32;\npub const UCOL_REORDER_CODE_CURRENCY: UColReorderCode = 4099i32;\npub const UCOL_REORDER_CODE_DEFAULT: UColReorderCode = -1i32;\npub const UCOL_REORDER_CODE_DIGIT: UColReorderCode = 4100i32;\npub const UCOL_REORDER_CODE_FIRST: UColReorderCode = 4096i32;\npub const UCOL_REORDER_CODE_NONE: UColReorderCode = 103i32;\npub const UCOL_REORDER_CODE_OTHERS: UColReorderCode = 103i32;\npub const UCOL_REORDER_CODE_PUNCTUATION: UColReorderCode = 4097i32;\npub const UCOL_REORDER_CODE_SPACE: UColReorderCode = 4096i32;\npub const UCOL_REORDER_CODE_SYMBOL: UColReorderCode = 4098i32;\npub const UCOL_SECONDARY: UColAttributeValue = 1i32;\npub const UCOL_SHIFTED: UColAttributeValue = 20i32;\npub const UCOL_STRENGTH: UColAttribute = 5i32;\npub const UCOL_STRENGTH_LIMIT: UColAttributeValue = 16i32;\npub const UCOL_TAILORING_ONLY: UColRuleOption = 0i32;\npub const UCOL_TERTIARY: UColAttributeValue = 2i32;\npub const UCOL_UPPER_FIRST: UColAttributeValue = 25i32;\npub const UCONFIG_ENABLE_PLUGINS: u32 = 0u32;\npub const UCONFIG_FORMAT_FASTPATHS_49: u32 = 1u32;\npub const UCONFIG_HAVE_PARSEALLINPUT: u32 = 1u32;\npub const UCONFIG_NO_BREAK_ITERATION: u32 = 1u32;\npub const UCONFIG_NO_COLLATION: u32 = 1u32;\npub const UCONFIG_NO_CONVERSION: u32 = 0u32;\npub const UCONFIG_NO_FILE_IO: u32 = 0u32;\npub const UCONFIG_NO_FILTERED_BREAK_ITERATION: u32 = 0u32;\npub const UCONFIG_NO_FORMATTING: u32 = 1u32;\npub const UCONFIG_NO_IDNA: u32 = 1u32;\npub const UCONFIG_NO_LEGACY_CONVERSION: u32 = 1u32;\npub const UCONFIG_NO_NORMALIZATION: u32 = 0u32;\npub const UCONFIG_NO_REGULAR_EXPRESSIONS: u32 = 1u32;\npub const UCONFIG_NO_SERVICE: u32 = 0u32;\npub const UCONFIG_NO_TRANSLITERATION: u32 = 1u32;\npub const UCONFIG_ONLY_COLLATION: u32 = 0u32;\npub const UCONFIG_ONLY_HTML_CONVERSION: u32 = 0u32;\npub const UCPMAP_RANGE_FIXED_ALL_SURROGATES: UCPMapRangeOption = 2i32;\npub const UCPMAP_RANGE_FIXED_LEAD_SURROGATES: UCPMapRangeOption = 1i32;\npub const UCPMAP_RANGE_NORMAL: UCPMapRangeOption = 0i32;\npub type UCPMap = isize;\npub type UCPMapRangeOption = i32;\npub type UCPMapValueFilter = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, value: u32) -> u32>;\npub const UCPTRIE_ERROR_VALUE_NEG_DATA_OFFSET: i32 = 1i32;\npub const UCPTRIE_FAST_DATA_BLOCK_LENGTH: i32 = 64i32;\npub const UCPTRIE_FAST_DATA_MASK: i32 = 63i32;\npub const UCPTRIE_FAST_SHIFT: i32 = 6i32;\npub const UCPTRIE_HIGH_VALUE_NEG_DATA_OFFSET: i32 = 2i32;\npub const UCPTRIE_SMALL_MAX: i32 = 4095i32;\npub const UCPTRIE_TYPE_ANY: UCPTrieType = -1i32;\npub const UCPTRIE_TYPE_FAST: UCPTrieType = 0i32;\npub const UCPTRIE_TYPE_SMALL: UCPTrieType = 1i32;\npub const UCPTRIE_VALUE_BITS_16: UCPTrieValueWidth = 0i32;\npub const UCPTRIE_VALUE_BITS_32: UCPTrieValueWidth = 1i32;\npub const UCPTRIE_VALUE_BITS_8: UCPTrieValueWidth = 2i32;\npub const UCPTRIE_VALUE_BITS_ANY: UCPTrieValueWidth = -1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct UCPTrie {\n    pub index: *const u16,\n    pub data: UCPTrieData,\n    pub indexLength: i32,\n    pub dataLength: i32,\n    pub highStart: i32,\n    pub shifted12HighStart: u16,\n    pub r#type: i8,\n    pub valueWidth: i8,\n    pub reserved32: u32,\n    pub reserved16: u16,\n    pub index3NullOffset: u16,\n    pub dataNullOffset: i32,\n    pub nullValue: u32,\n}\nimpl Default for UCPTrie {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union UCPTrieData {\n    pub ptr0: *const core::ffi::c_void,\n    pub ptr16: *const u16,\n    pub ptr32: *const u32,\n    pub ptr8: *const u8,\n}\nimpl Default for UCPTrieData {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type UCPTrieType = i32;\npub type UCPTrieValueWidth = i32;\npub const UCURR_ALL: UCurrCurrencyType = 2147483647i32;\npub const UCURR_COMMON: UCurrCurrencyType = 1i32;\npub const UCURR_DEPRECATED: UCurrCurrencyType = 4i32;\npub const UCURR_LONG_NAME: UCurrNameStyle = 1i32;\npub const UCURR_NARROW_SYMBOL_NAME: UCurrNameStyle = 2i32;\npub const UCURR_NON_DEPRECATED: UCurrCurrencyType = 8i32;\npub const UCURR_SYMBOL_NAME: UCurrNameStyle = 0i32;\npub const UCURR_UNCOMMON: UCurrCurrencyType = 2i32;\npub const UCURR_USAGE_CASH: UCurrencyUsage = 1i32;\npub const UCURR_USAGE_STANDARD: UCurrencyUsage = 0i32;\npub type UCalendarAMPMs = i32;\npub type UCalendarAttribute = i32;\npub type UCalendarDateFields = i32;\npub type UCalendarDaysOfWeek = i32;\npub type UCalendarDisplayNameType = i32;\npub type UCalendarLimitType = i32;\npub type UCalendarMonths = i32;\npub type UCalendarType = i32;\npub type UCalendarWallTimeOption = i32;\npub type UCalendarWeekdayType = i32;\npub type UCaseMap = isize;\npub type UCharCategory = i32;\npub type UCharDirection = i32;\npub type UCharEnumTypeRange = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, start: i32, limit: i32, r#type: UCharCategory) -> i8>;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct UCharIterator {\n    pub context: *const core::ffi::c_void,\n    pub length: i32,\n    pub start: i32,\n    pub index: i32,\n    pub limit: i32,\n    pub reservedField: i32,\n    pub getIndex: UCharIteratorGetIndex,\n    pub r#move: UCharIteratorMove,\n    pub hasNext: UCharIteratorHasNext,\n    pub hasPrevious: UCharIteratorHasPrevious,\n    pub current: UCharIteratorCurrent,\n    pub next: UCharIteratorNext,\n    pub previous: UCharIteratorPrevious,\n    pub reservedFn: UCharIteratorReserved,\n    pub getState: UCharIteratorGetState,\n    pub setState: UCharIteratorSetState,\n}\nimpl Default for UCharIterator {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type UCharIteratorCurrent = Option<unsafe extern \"system\" fn(iter: *mut UCharIterator) -> i32>;\npub type UCharIteratorGetIndex = Option<unsafe extern \"system\" fn(iter: *mut UCharIterator, origin: UCharIteratorOrigin) -> i32>;\npub type UCharIteratorGetState = Option<unsafe extern \"system\" fn(iter: *const UCharIterator) -> u32>;\npub type UCharIteratorHasNext = Option<unsafe extern \"system\" fn(iter: *mut UCharIterator) -> i8>;\npub type UCharIteratorHasPrevious = Option<unsafe extern \"system\" fn(iter: *mut UCharIterator) -> i8>;\npub type UCharIteratorMove = Option<unsafe extern \"system\" fn(iter: *mut UCharIterator, delta: i32, origin: UCharIteratorOrigin) -> i32>;\npub type UCharIteratorNext = Option<unsafe extern \"system\" fn(iter: *mut UCharIterator) -> i32>;\npub type UCharIteratorOrigin = i32;\npub type UCharIteratorPrevious = Option<unsafe extern \"system\" fn(iter: *mut UCharIterator) -> i32>;\npub type UCharIteratorReserved = Option<unsafe extern \"system\" fn(iter: *mut UCharIterator, something: i32) -> i32>;\npub type UCharIteratorSetState = Option<unsafe extern \"system\" fn(iter: *mut UCharIterator, state: u32, perrorcode: *mut UErrorCode)>;\npub type UCharNameChoice = i32;\npub type UCharsetDetector = isize;\npub type UCharsetMatch = isize;\npub type UColAttribute = i32;\npub type UColAttributeValue = i32;\npub type UColBoundMode = i32;\npub type UColReorderCode = i32;\npub type UColRuleOption = i32;\npub type UCollationElements = isize;\npub type UCollationResult = i32;\npub type UCollator = isize;\npub type UConstrainedFieldPosition = isize;\npub type UConverter = isize;\npub type UConverterCallbackReason = i32;\npub type UConverterFromUCallback = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, args: *mut UConverterFromUnicodeArgs, codeunits: *const u16, length: i32, codepoint: i32, reason: UConverterCallbackReason, perrorcode: *mut UErrorCode)>;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct UConverterFromUnicodeArgs {\n    pub size: u16,\n    pub flush: i8,\n    pub converter: *mut UConverter,\n    pub source: *const u16,\n    pub sourceLimit: *const u16,\n    pub target: windows_sys::core::PSTR,\n    pub targetLimit: windows_sys::core::PCSTR,\n    pub offsets: *mut i32,\n}\nimpl Default for UConverterFromUnicodeArgs {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type UConverterPlatform = i32;\npub type UConverterSelector = isize;\npub type UConverterToUCallback = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, args: *mut UConverterToUnicodeArgs, codeunits: windows_sys::core::PCSTR, length: i32, reason: UConverterCallbackReason, perrorcode: *mut UErrorCode)>;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct UConverterToUnicodeArgs {\n    pub size: u16,\n    pub flush: i8,\n    pub converter: *mut UConverter,\n    pub source: windows_sys::core::PCSTR,\n    pub sourceLimit: windows_sys::core::PCSTR,\n    pub target: *mut u16,\n    pub targetLimit: *const u16,\n    pub offsets: *mut i32,\n}\nimpl Default for UConverterToUnicodeArgs {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type UConverterType = i32;\npub type UConverterUnicodeSet = i32;\npub type UCurrCurrencyType = i32;\npub type UCurrNameStyle = i32;\npub type UCurrencySpacing = i32;\npub type UCurrencyUsage = i32;\npub const UDATPG_ABBREVIATED: UDateTimePGDisplayWidth = 1i32;\npub const UDATPG_BASE_CONFLICT: UDateTimePatternConflict = 1i32;\npub const UDATPG_CONFLICT: UDateTimePatternConflict = 2i32;\npub const UDATPG_DAYPERIOD_FIELD: UDateTimePatternField = 10i32;\npub const UDATPG_DAY_FIELD: UDateTimePatternField = 9i32;\npub const UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD: UDateTimePatternField = 8i32;\npub const UDATPG_DAY_OF_YEAR_FIELD: UDateTimePatternField = 7i32;\npub const UDATPG_ERA_FIELD: UDateTimePatternField = 0i32;\npub const UDATPG_FIELD_COUNT: UDateTimePatternField = 16i32;\npub const UDATPG_FRACTIONAL_SECOND_FIELD: UDateTimePatternField = 14i32;\npub const UDATPG_HOUR_FIELD: UDateTimePatternField = 11i32;\npub const UDATPG_MATCH_ALL_FIELDS_LENGTH: UDateTimePatternMatchOptions = 65535i32;\npub const UDATPG_MATCH_HOUR_FIELD_LENGTH: UDateTimePatternMatchOptions = 2048i32;\npub const UDATPG_MATCH_NO_OPTIONS: UDateTimePatternMatchOptions = 0i32;\npub const UDATPG_MINUTE_FIELD: UDateTimePatternField = 12i32;\npub const UDATPG_MONTH_FIELD: UDateTimePatternField = 3i32;\npub const UDATPG_NARROW: UDateTimePGDisplayWidth = 2i32;\npub const UDATPG_NO_CONFLICT: UDateTimePatternConflict = 0i32;\npub const UDATPG_QUARTER_FIELD: UDateTimePatternField = 2i32;\npub const UDATPG_SECOND_FIELD: UDateTimePatternField = 13i32;\npub const UDATPG_WEEKDAY_FIELD: UDateTimePatternField = 6i32;\npub const UDATPG_WEEK_OF_MONTH_FIELD: UDateTimePatternField = 5i32;\npub const UDATPG_WEEK_OF_YEAR_FIELD: UDateTimePatternField = 4i32;\npub const UDATPG_WIDE: UDateTimePGDisplayWidth = 0i32;\npub const UDATPG_YEAR_FIELD: UDateTimePatternField = 1i32;\npub const UDATPG_ZONE_FIELD: UDateTimePatternField = 15i32;\npub const UDAT_ABBR_GENERIC_TZ: windows_sys::core::PCSTR = windows_sys::core::s!(\"v\");\npub const UDAT_ABBR_MONTH: windows_sys::core::PCSTR = windows_sys::core::s!(\"MMM\");\npub const UDAT_ABBR_MONTH_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"MMMd\");\npub const UDAT_ABBR_MONTH_WEEKDAY_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"MMMEd\");\npub const UDAT_ABBR_QUARTER: windows_sys::core::PCSTR = windows_sys::core::s!(\"QQQ\");\npub const UDAT_ABBR_SPECIFIC_TZ: windows_sys::core::PCSTR = windows_sys::core::s!(\"z\");\npub const UDAT_ABBR_UTC_TZ: windows_sys::core::PCSTR = windows_sys::core::s!(\"ZZZZ\");\npub const UDAT_ABBR_WEEKDAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"E\");\npub const UDAT_ABSOLUTE_DAY: UDateAbsoluteUnit = 7i32;\npub const UDAT_ABSOLUTE_FRIDAY: UDateAbsoluteUnit = 5i32;\npub const UDAT_ABSOLUTE_MONDAY: UDateAbsoluteUnit = 1i32;\npub const UDAT_ABSOLUTE_MONTH: UDateAbsoluteUnit = 9i32;\npub const UDAT_ABSOLUTE_NOW: UDateAbsoluteUnit = 11i32;\npub const UDAT_ABSOLUTE_SATURDAY: UDateAbsoluteUnit = 6i32;\npub const UDAT_ABSOLUTE_SUNDAY: UDateAbsoluteUnit = 0i32;\npub const UDAT_ABSOLUTE_THURSDAY: UDateAbsoluteUnit = 4i32;\npub const UDAT_ABSOLUTE_TUESDAY: UDateAbsoluteUnit = 2i32;\npub const UDAT_ABSOLUTE_UNIT_COUNT: UDateAbsoluteUnit = 12i32;\npub const UDAT_ABSOLUTE_WEDNESDAY: UDateAbsoluteUnit = 3i32;\npub const UDAT_ABSOLUTE_WEEK: UDateAbsoluteUnit = 8i32;\npub const UDAT_ABSOLUTE_YEAR: UDateAbsoluteUnit = 10i32;\npub const UDAT_AM_PMS: UDateFormatSymbolType = 5i32;\npub const UDAT_AM_PM_FIELD: UDateFormatField = 14i32;\npub const UDAT_AM_PM_MIDNIGHT_NOON_FIELD: UDateFormatField = 35i32;\npub const UDAT_BOOLEAN_ATTRIBUTE_COUNT: UDateFormatBooleanAttribute = 4i32;\npub const UDAT_CYCLIC_YEARS_ABBREVIATED: UDateFormatSymbolType = 23i32;\npub const UDAT_CYCLIC_YEARS_NARROW: UDateFormatSymbolType = 24i32;\npub const UDAT_CYCLIC_YEARS_WIDE: UDateFormatSymbolType = 22i32;\npub const UDAT_DATE_FIELD: UDateFormatField = 3i32;\npub const UDAT_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"d\");\npub const UDAT_DAY_OF_WEEK_FIELD: UDateFormatField = 9i32;\npub const UDAT_DAY_OF_WEEK_IN_MONTH_FIELD: UDateFormatField = 11i32;\npub const UDAT_DAY_OF_YEAR_FIELD: UDateFormatField = 10i32;\npub const UDAT_DEFAULT: UDateFormatStyle = 2i32;\npub const UDAT_DIRECTION_COUNT: UDateDirection = 6i32;\npub const UDAT_DIRECTION_LAST: UDateDirection = 1i32;\npub const UDAT_DIRECTION_LAST_2: UDateDirection = 0i32;\npub const UDAT_DIRECTION_NEXT: UDateDirection = 3i32;\npub const UDAT_DIRECTION_NEXT_2: UDateDirection = 4i32;\npub const UDAT_DIRECTION_PLAIN: UDateDirection = 5i32;\npub const UDAT_DIRECTION_THIS: UDateDirection = 2i32;\npub const UDAT_DOW_LOCAL_FIELD: UDateFormatField = 19i32;\npub const UDAT_ERAS: UDateFormatSymbolType = 0i32;\npub const UDAT_ERA_FIELD: UDateFormatField = 0i32;\npub const UDAT_ERA_NAMES: UDateFormatSymbolType = 7i32;\npub const UDAT_EXTENDED_YEAR_FIELD: UDateFormatField = 20i32;\npub const UDAT_FLEXIBLE_DAY_PERIOD_FIELD: UDateFormatField = 36i32;\npub const UDAT_FRACTIONAL_SECOND_FIELD: UDateFormatField = 8i32;\npub const UDAT_FULL: UDateFormatStyle = 0i32;\npub const UDAT_FULL_RELATIVE: UDateFormatStyle = 128i32;\npub const UDAT_GENERIC_TZ: windows_sys::core::PCSTR = windows_sys::core::s!(\"vvvv\");\npub const UDAT_HOUR: windows_sys::core::PCSTR = windows_sys::core::s!(\"j\");\npub const UDAT_HOUR0_FIELD: UDateFormatField = 16i32;\npub const UDAT_HOUR1_FIELD: UDateFormatField = 15i32;\npub const UDAT_HOUR24: windows_sys::core::PCSTR = windows_sys::core::s!(\"H\");\npub const UDAT_HOUR24_MINUTE: windows_sys::core::PCSTR = windows_sys::core::s!(\"Hm\");\npub const UDAT_HOUR24_MINUTE_SECOND: windows_sys::core::PCSTR = windows_sys::core::s!(\"Hms\");\npub const UDAT_HOUR_MINUTE: windows_sys::core::PCSTR = windows_sys::core::s!(\"jm\");\npub const UDAT_HOUR_MINUTE_SECOND: windows_sys::core::PCSTR = windows_sys::core::s!(\"jms\");\npub const UDAT_HOUR_OF_DAY0_FIELD: UDateFormatField = 5i32;\npub const UDAT_HOUR_OF_DAY1_FIELD: UDateFormatField = 4i32;\npub const UDAT_JULIAN_DAY_FIELD: UDateFormatField = 21i32;\npub const UDAT_LOCALIZED_CHARS: UDateFormatSymbolType = 6i32;\npub const UDAT_LOCATION_TZ: windows_sys::core::PCSTR = windows_sys::core::s!(\"VVVV\");\npub const UDAT_LONG: UDateFormatStyle = 1i32;\npub const UDAT_LONG_RELATIVE: UDateFormatStyle = 129i32;\npub const UDAT_MEDIUM: UDateFormatStyle = 2i32;\npub const UDAT_MEDIUM_RELATIVE: UDateFormatStyle = 130i32;\npub const UDAT_MILLISECONDS_IN_DAY_FIELD: UDateFormatField = 22i32;\npub const UDAT_MINUTE: windows_sys::core::PCSTR = windows_sys::core::s!(\"m\");\npub const UDAT_MINUTE_FIELD: UDateFormatField = 6i32;\npub const UDAT_MINUTE_SECOND: windows_sys::core::PCSTR = windows_sys::core::s!(\"ms\");\npub const UDAT_MONTH: windows_sys::core::PCSTR = windows_sys::core::s!(\"MMMM\");\npub const UDAT_MONTHS: UDateFormatSymbolType = 1i32;\npub const UDAT_MONTH_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"MMMMd\");\npub const UDAT_MONTH_FIELD: UDateFormatField = 2i32;\npub const UDAT_MONTH_WEEKDAY_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"MMMMEEEEd\");\npub const UDAT_NARROW_MONTHS: UDateFormatSymbolType = 8i32;\npub const UDAT_NARROW_WEEKDAYS: UDateFormatSymbolType = 9i32;\npub const UDAT_NONE: UDateFormatStyle = -1i32;\npub const UDAT_NUM_MONTH: windows_sys::core::PCSTR = windows_sys::core::s!(\"M\");\npub const UDAT_NUM_MONTH_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"Md\");\npub const UDAT_NUM_MONTH_WEEKDAY_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"MEd\");\npub const UDAT_PARSE_ALLOW_NUMERIC: UDateFormatBooleanAttribute = 1i32;\npub const UDAT_PARSE_ALLOW_WHITESPACE: UDateFormatBooleanAttribute = 0i32;\npub const UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH: UDateFormatBooleanAttribute = 3i32;\npub const UDAT_PARSE_PARTIAL_LITERAL_MATCH: UDateFormatBooleanAttribute = 2i32;\npub const UDAT_PATTERN: UDateFormatStyle = -2i32;\npub const UDAT_QUARTER: windows_sys::core::PCSTR = windows_sys::core::s!(\"QQQQ\");\npub const UDAT_QUARTERS: UDateFormatSymbolType = 16i32;\npub const UDAT_QUARTER_FIELD: UDateFormatField = 27i32;\npub const UDAT_RELATIVE: UDateFormatStyle = 128i32;\npub const UDAT_RELATIVE_DAYS: UDateRelativeUnit = 3i32;\npub const UDAT_RELATIVE_HOURS: UDateRelativeUnit = 2i32;\npub const UDAT_RELATIVE_MINUTES: UDateRelativeUnit = 1i32;\npub const UDAT_RELATIVE_MONTHS: UDateRelativeUnit = 5i32;\npub const UDAT_RELATIVE_SECONDS: UDateRelativeUnit = 0i32;\npub const UDAT_RELATIVE_UNIT_COUNT: UDateRelativeUnit = 7i32;\npub const UDAT_RELATIVE_WEEKS: UDateRelativeUnit = 4i32;\npub const UDAT_RELATIVE_YEARS: UDateRelativeUnit = 6i32;\npub const UDAT_REL_LITERAL_FIELD: URelativeDateTimeFormatterField = 0i32;\npub const UDAT_REL_NUMERIC_FIELD: URelativeDateTimeFormatterField = 1i32;\npub const UDAT_REL_UNIT_DAY: URelativeDateTimeUnit = 4i32;\npub const UDAT_REL_UNIT_FRIDAY: URelativeDateTimeUnit = 13i32;\npub const UDAT_REL_UNIT_HOUR: URelativeDateTimeUnit = 5i32;\npub const UDAT_REL_UNIT_MINUTE: URelativeDateTimeUnit = 6i32;\npub const UDAT_REL_UNIT_MONDAY: URelativeDateTimeUnit = 9i32;\npub const UDAT_REL_UNIT_MONTH: URelativeDateTimeUnit = 2i32;\npub const UDAT_REL_UNIT_QUARTER: URelativeDateTimeUnit = 1i32;\npub const UDAT_REL_UNIT_SATURDAY: URelativeDateTimeUnit = 14i32;\npub const UDAT_REL_UNIT_SECOND: URelativeDateTimeUnit = 7i32;\npub const UDAT_REL_UNIT_SUNDAY: URelativeDateTimeUnit = 8i32;\npub const UDAT_REL_UNIT_THURSDAY: URelativeDateTimeUnit = 12i32;\npub const UDAT_REL_UNIT_TUESDAY: URelativeDateTimeUnit = 10i32;\npub const UDAT_REL_UNIT_WEDNESDAY: URelativeDateTimeUnit = 11i32;\npub const UDAT_REL_UNIT_WEEK: URelativeDateTimeUnit = 3i32;\npub const UDAT_REL_UNIT_YEAR: URelativeDateTimeUnit = 0i32;\npub const UDAT_SECOND: windows_sys::core::PCSTR = windows_sys::core::s!(\"s\");\npub const UDAT_SECOND_FIELD: UDateFormatField = 7i32;\npub const UDAT_SHORT: UDateFormatStyle = 3i32;\npub const UDAT_SHORTER_WEEKDAYS: UDateFormatSymbolType = 20i32;\npub const UDAT_SHORT_MONTHS: UDateFormatSymbolType = 2i32;\npub const UDAT_SHORT_QUARTERS: UDateFormatSymbolType = 17i32;\npub const UDAT_SHORT_RELATIVE: UDateFormatStyle = 131i32;\npub const UDAT_SHORT_WEEKDAYS: UDateFormatSymbolType = 4i32;\npub const UDAT_SPECIFIC_TZ: windows_sys::core::PCSTR = windows_sys::core::s!(\"zzzz\");\npub const UDAT_STANDALONE_DAY_FIELD: UDateFormatField = 25i32;\npub const UDAT_STANDALONE_MONTHS: UDateFormatSymbolType = 10i32;\npub const UDAT_STANDALONE_MONTH_FIELD: UDateFormatField = 26i32;\npub const UDAT_STANDALONE_NARROW_MONTHS: UDateFormatSymbolType = 12i32;\npub const UDAT_STANDALONE_NARROW_WEEKDAYS: UDateFormatSymbolType = 15i32;\npub const UDAT_STANDALONE_QUARTERS: UDateFormatSymbolType = 18i32;\npub const UDAT_STANDALONE_QUARTER_FIELD: UDateFormatField = 28i32;\npub const UDAT_STANDALONE_SHORTER_WEEKDAYS: UDateFormatSymbolType = 21i32;\npub const UDAT_STANDALONE_SHORT_MONTHS: UDateFormatSymbolType = 11i32;\npub const UDAT_STANDALONE_SHORT_QUARTERS: UDateFormatSymbolType = 19i32;\npub const UDAT_STANDALONE_SHORT_WEEKDAYS: UDateFormatSymbolType = 14i32;\npub const UDAT_STANDALONE_WEEKDAYS: UDateFormatSymbolType = 13i32;\npub const UDAT_STYLE_LONG: UDateRelativeDateTimeFormatterStyle = 0i32;\npub const UDAT_STYLE_NARROW: UDateRelativeDateTimeFormatterStyle = 2i32;\npub const UDAT_STYLE_SHORT: UDateRelativeDateTimeFormatterStyle = 1i32;\npub const UDAT_TIMEZONE_FIELD: UDateFormatField = 17i32;\npub const UDAT_TIMEZONE_GENERIC_FIELD: UDateFormatField = 24i32;\npub const UDAT_TIMEZONE_ISO_FIELD: UDateFormatField = 32i32;\npub const UDAT_TIMEZONE_ISO_LOCAL_FIELD: UDateFormatField = 33i32;\npub const UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: UDateFormatField = 31i32;\npub const UDAT_TIMEZONE_RFC_FIELD: UDateFormatField = 23i32;\npub const UDAT_TIMEZONE_SPECIAL_FIELD: UDateFormatField = 29i32;\npub const UDAT_WEEKDAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"EEEE\");\npub const UDAT_WEEKDAYS: UDateFormatSymbolType = 3i32;\npub const UDAT_WEEK_OF_MONTH_FIELD: UDateFormatField = 13i32;\npub const UDAT_WEEK_OF_YEAR_FIELD: UDateFormatField = 12i32;\npub const UDAT_YEAR: windows_sys::core::PCSTR = windows_sys::core::s!(\"y\");\npub const UDAT_YEAR_ABBR_MONTH: windows_sys::core::PCSTR = windows_sys::core::s!(\"yMMM\");\npub const UDAT_YEAR_ABBR_MONTH_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"yMMMd\");\npub const UDAT_YEAR_ABBR_MONTH_WEEKDAY_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"yMMMEd\");\npub const UDAT_YEAR_ABBR_QUARTER: windows_sys::core::PCSTR = windows_sys::core::s!(\"yQQQ\");\npub const UDAT_YEAR_FIELD: UDateFormatField = 1i32;\npub const UDAT_YEAR_MONTH: windows_sys::core::PCSTR = windows_sys::core::s!(\"yMMMM\");\npub const UDAT_YEAR_MONTH_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"yMMMMd\");\npub const UDAT_YEAR_MONTH_WEEKDAY_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"yMMMMEEEEd\");\npub const UDAT_YEAR_NAME_FIELD: UDateFormatField = 30i32;\npub const UDAT_YEAR_NUM_MONTH: windows_sys::core::PCSTR = windows_sys::core::s!(\"yM\");\npub const UDAT_YEAR_NUM_MONTH_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"yMd\");\npub const UDAT_YEAR_NUM_MONTH_WEEKDAY_DAY: windows_sys::core::PCSTR = windows_sys::core::s!(\"yMEd\");\npub const UDAT_YEAR_QUARTER: windows_sys::core::PCSTR = windows_sys::core::s!(\"yQQQQ\");\npub const UDAT_YEAR_WOY_FIELD: UDateFormatField = 18i32;\npub const UDAT_ZODIAC_NAMES_ABBREVIATED: UDateFormatSymbolType = 26i32;\npub const UDAT_ZODIAC_NAMES_NARROW: UDateFormatSymbolType = 27i32;\npub const UDAT_ZODIAC_NAMES_WIDE: UDateFormatSymbolType = 25i32;\npub const UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE: UDisplayContext = 258i32;\npub const UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE: UDisplayContext = 257i32;\npub const UDISPCTX_CAPITALIZATION_FOR_STANDALONE: UDisplayContext = 260i32;\npub const UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU: UDisplayContext = 259i32;\npub const UDISPCTX_CAPITALIZATION_NONE: UDisplayContext = 256i32;\npub const UDISPCTX_DIALECT_NAMES: UDisplayContext = 1i32;\npub const UDISPCTX_LENGTH_FULL: UDisplayContext = 512i32;\npub const UDISPCTX_LENGTH_SHORT: UDisplayContext = 513i32;\npub const UDISPCTX_NO_SUBSTITUTE: UDisplayContext = 769i32;\npub const UDISPCTX_STANDARD_NAMES: UDisplayContext = 0i32;\npub const UDISPCTX_SUBSTITUTE: UDisplayContext = 768i32;\npub const UDISPCTX_TYPE_CAPITALIZATION: UDisplayContextType = 1i32;\npub const UDISPCTX_TYPE_DIALECT_HANDLING: UDisplayContextType = 0i32;\npub const UDISPCTX_TYPE_DISPLAY_LENGTH: UDisplayContextType = 2i32;\npub const UDISPCTX_TYPE_SUBSTITUTE_HANDLING: UDisplayContextType = 3i32;\npub const UDTS_DB2_TIME: UDateTimeScale = 8i32;\npub const UDTS_DOTNET_DATE_TIME: UDateTimeScale = 4i32;\npub const UDTS_EXCEL_TIME: UDateTimeScale = 7i32;\npub const UDTS_ICU4C_TIME: UDateTimeScale = 2i32;\npub const UDTS_JAVA_TIME: UDateTimeScale = 0i32;\npub const UDTS_MAC_OLD_TIME: UDateTimeScale = 5i32;\npub const UDTS_MAC_TIME: UDateTimeScale = 6i32;\npub const UDTS_UNIX_MICROSECONDS_TIME: UDateTimeScale = 9i32;\npub const UDTS_UNIX_TIME: UDateTimeScale = 1i32;\npub const UDTS_WINDOWS_FILE_TIME: UDateTimeScale = 3i32;\npub type UDateAbsoluteUnit = i32;\npub type UDateDirection = i32;\npub type UDateFormatBooleanAttribute = i32;\npub type UDateFormatField = i32;\npub type UDateFormatStyle = i32;\npub type UDateFormatSymbolType = i32;\npub type UDateFormatSymbols = isize;\npub type UDateIntervalFormat = isize;\npub type UDateRelativeDateTimeFormatterStyle = i32;\npub type UDateRelativeUnit = i32;\npub type UDateTimePGDisplayWidth = i32;\npub type UDateTimePatternConflict = i32;\npub type UDateTimePatternField = i32;\npub type UDateTimePatternMatchOptions = i32;\npub type UDateTimeScale = i32;\npub type UDecompositionType = i32;\npub type UDialectHandling = i32;\npub type UDisplayContext = i32;\npub type UDisplayContextType = i32;\npub type UEastAsianWidth = i32;\npub type UEnumCharNamesFn = Option<unsafe extern \"system\" fn(context: *mut core::ffi::c_void, code: i32, namechoice: UCharNameChoice, name: windows_sys::core::PCSTR, length: i32) -> i8>;\npub type UEnumeration = isize;\npub type UErrorCode = i32;\npub const UFIELD_CATEGORY_DATE: UFieldCategory = 1i32;\npub const UFIELD_CATEGORY_DATE_INTERVAL: UFieldCategory = 5i32;\npub const UFIELD_CATEGORY_DATE_INTERVAL_SPAN: UFieldCategory = 4101i32;\npub const UFIELD_CATEGORY_LIST: UFieldCategory = 3i32;\npub const UFIELD_CATEGORY_LIST_SPAN: UFieldCategory = 4099i32;\npub const UFIELD_CATEGORY_NUMBER: UFieldCategory = 2i32;\npub const UFIELD_CATEGORY_RELATIVE_DATETIME: UFieldCategory = 4i32;\npub const UFIELD_CATEGORY_UNDEFINED: UFieldCategory = 0i32;\npub const UFMT_ARRAY: UFormattableType = 4i32;\npub const UFMT_DATE: UFormattableType = 0i32;\npub const UFMT_DOUBLE: UFormattableType = 1i32;\npub const UFMT_INT64: UFormattableType = 5i32;\npub const UFMT_LONG: UFormattableType = 2i32;\npub const UFMT_OBJECT: UFormattableType = 6i32;\npub const UFMT_STRING: UFormattableType = 3i32;\npub type UFieldCategory = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct UFieldPosition {\n    pub field: i32,\n    pub beginIndex: i32,\n    pub endIndex: i32,\n}\npub type UFieldPositionIterator = isize;\npub type UFormattableType = i32;\npub type UFormattedDateInterval = isize;\npub type UFormattedList = isize;\npub type UFormattedNumber = isize;\npub type UFormattedNumberRange = isize;\npub type UFormattedRelativeDateTime = isize;\npub type UFormattedValue = isize;\npub const UGENDER_FEMALE: UGender = 1i32;\npub const UGENDER_MALE: UGender = 0i32;\npub const UGENDER_OTHER: UGender = 2i32;\npub type UGender = i32;\npub type UGenderInfo = isize;\npub type UGraphemeClusterBreak = i32;\npub type UHangulSyllableType = i32;\npub type UHashtable = isize;\npub type UIDNA = isize;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct UIDNAInfo {\n    pub size: i16,\n    pub isTransitionalDifferent: i8,\n    pub reservedB3: i8,\n    pub errors: u32,\n    pub reservedI2: i32,\n    pub reservedI3: i32,\n}\npub const UIDNA_CHECK_BIDI: i32 = 4i32;\npub const UIDNA_CHECK_CONTEXTJ: i32 = 8i32;\npub const UIDNA_CHECK_CONTEXTO: i32 = 64i32;\npub const UIDNA_DEFAULT: i32 = 0i32;\npub const UIDNA_ERROR_BIDI: i32 = 2048i32;\npub const UIDNA_ERROR_CONTEXTJ: i32 = 4096i32;\npub const UIDNA_ERROR_CONTEXTO_DIGITS: i32 = 16384i32;\npub const UIDNA_ERROR_CONTEXTO_PUNCTUATION: i32 = 8192i32;\npub const UIDNA_ERROR_DISALLOWED: i32 = 128i32;\npub const UIDNA_ERROR_DOMAIN_NAME_TOO_LONG: i32 = 4i32;\npub const UIDNA_ERROR_EMPTY_LABEL: i32 = 1i32;\npub const UIDNA_ERROR_HYPHEN_3_4: i32 = 32i32;\npub const UIDNA_ERROR_INVALID_ACE_LABEL: i32 = 1024i32;\npub const UIDNA_ERROR_LABEL_HAS_DOT: i32 = 512i32;\npub const UIDNA_ERROR_LABEL_TOO_LONG: i32 = 2i32;\npub const UIDNA_ERROR_LEADING_COMBINING_MARK: i32 = 64i32;\npub const UIDNA_ERROR_LEADING_HYPHEN: i32 = 8i32;\npub const UIDNA_ERROR_PUNYCODE: i32 = 256i32;\npub const UIDNA_ERROR_TRAILING_HYPHEN: i32 = 16i32;\npub const UIDNA_NONTRANSITIONAL_TO_ASCII: i32 = 16i32;\npub const UIDNA_NONTRANSITIONAL_TO_UNICODE: i32 = 32i32;\npub const UIDNA_USE_STD3_RULES: i32 = 2i32;\npub type UILANGUAGE_ENUMPROCA = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCSTR, param1: isize) -> windows_sys::core::BOOL>;\npub type UILANGUAGE_ENUMPROCW = Option<unsafe extern \"system\" fn(param0: windows_sys::core::PCWSTR, param1: isize) -> windows_sys::core::BOOL>;\npub const UITER_CURRENT: UCharIteratorOrigin = 1i32;\npub const UITER_LENGTH: UCharIteratorOrigin = 4i32;\npub const UITER_LIMIT: UCharIteratorOrigin = 2i32;\npub const UITER_START: UCharIteratorOrigin = 0i32;\npub const UITER_UNKNOWN_INDEX: i32 = -2i32;\npub const UITER_ZERO: UCharIteratorOrigin = 3i32;\npub type UIndicPositionalCategory = i32;\npub type UIndicSyllabicCategory = i32;\npub type UJoiningGroup = i32;\npub type UJoiningType = i32;\npub const ULDN_DIALECT_NAMES: UDialectHandling = 1i32;\npub const ULDN_STANDARD_NAMES: UDialectHandling = 0i32;\npub const ULISTFMT_ELEMENT_FIELD: UListFormatterField = 1i32;\npub const ULISTFMT_LITERAL_FIELD: UListFormatterField = 0i32;\npub const ULISTFMT_TYPE_AND: UListFormatterType = 0i32;\npub const ULISTFMT_TYPE_OR: UListFormatterType = 1i32;\npub const ULISTFMT_TYPE_UNITS: UListFormatterType = 2i32;\npub const ULISTFMT_WIDTH_NARROW: UListFormatterWidth = 2i32;\npub const ULISTFMT_WIDTH_SHORT: UListFormatterWidth = 1i32;\npub const ULISTFMT_WIDTH_WIDE: UListFormatterWidth = 0i32;\npub const ULOCDATA_ALT_QUOTATION_END: ULocaleDataDelimiterType = 3i32;\npub const ULOCDATA_ALT_QUOTATION_START: ULocaleDataDelimiterType = 2i32;\npub const ULOCDATA_ES_AUXILIARY: ULocaleDataExemplarSetType = 1i32;\npub const ULOCDATA_ES_INDEX: ULocaleDataExemplarSetType = 2i32;\npub const ULOCDATA_ES_PUNCTUATION: ULocaleDataExemplarSetType = 3i32;\npub const ULOCDATA_ES_STANDARD: ULocaleDataExemplarSetType = 0i32;\npub const ULOCDATA_QUOTATION_END: ULocaleDataDelimiterType = 1i32;\npub const ULOCDATA_QUOTATION_START: ULocaleDataDelimiterType = 0i32;\npub const ULOC_ACCEPT_FAILED: UAcceptResult = 0i32;\npub const ULOC_ACCEPT_FALLBACK: UAcceptResult = 2i32;\npub const ULOC_ACCEPT_VALID: UAcceptResult = 1i32;\npub const ULOC_ACTUAL_LOCALE: ULocDataLocaleType = 0i32;\npub const ULOC_AVAILABLE_DEFAULT: ULocAvailableType = 0i32;\npub const ULOC_AVAILABLE_ONLY_LEGACY_ALIASES: ULocAvailableType = 1i32;\npub const ULOC_AVAILABLE_WITH_LEGACY_ALIASES: ULocAvailableType = 2i32;\npub const ULOC_CANADA: windows_sys::core::PCSTR = windows_sys::core::s!(\"en_CA\");\npub const ULOC_CANADA_FRENCH: windows_sys::core::PCSTR = windows_sys::core::s!(\"fr_CA\");\npub const ULOC_CHINA: windows_sys::core::PCSTR = windows_sys::core::s!(\"zh_CN\");\npub const ULOC_CHINESE: windows_sys::core::PCSTR = windows_sys::core::s!(\"zh\");\npub const ULOC_COUNTRY_CAPACITY: u32 = 4u32;\npub const ULOC_ENGLISH: windows_sys::core::PCSTR = windows_sys::core::s!(\"en\");\npub const ULOC_FRANCE: windows_sys::core::PCSTR = windows_sys::core::s!(\"fr_FR\");\npub const ULOC_FRENCH: windows_sys::core::PCSTR = windows_sys::core::s!(\"fr\");\npub const ULOC_FULLNAME_CAPACITY: u32 = 157u32;\npub const ULOC_GERMAN: windows_sys::core::PCSTR = windows_sys::core::s!(\"de\");\npub const ULOC_GERMANY: windows_sys::core::PCSTR = windows_sys::core::s!(\"de_DE\");\npub const ULOC_ITALIAN: windows_sys::core::PCSTR = windows_sys::core::s!(\"it\");\npub const ULOC_ITALY: windows_sys::core::PCSTR = windows_sys::core::s!(\"it_IT\");\npub const ULOC_JAPAN: windows_sys::core::PCSTR = windows_sys::core::s!(\"ja_JP\");\npub const ULOC_JAPANESE: windows_sys::core::PCSTR = windows_sys::core::s!(\"ja\");\npub const ULOC_KEYWORDS_CAPACITY: u32 = 96u32;\npub const ULOC_KEYWORD_AND_VALUES_CAPACITY: u32 = 100u32;\npub const ULOC_KEYWORD_ASSIGN_UNICODE: u32 = 61u32;\npub const ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE: u32 = 59u32;\npub const ULOC_KEYWORD_SEPARATOR_UNICODE: u32 = 64u32;\npub const ULOC_KOREA: windows_sys::core::PCSTR = windows_sys::core::s!(\"ko_KR\");\npub const ULOC_KOREAN: windows_sys::core::PCSTR = windows_sys::core::s!(\"ko\");\npub const ULOC_LANG_CAPACITY: u32 = 12u32;\npub const ULOC_LAYOUT_BTT: ULayoutType = 3i32;\npub const ULOC_LAYOUT_LTR: ULayoutType = 0i32;\npub const ULOC_LAYOUT_RTL: ULayoutType = 1i32;\npub const ULOC_LAYOUT_TTB: ULayoutType = 2i32;\npub const ULOC_LAYOUT_UNKNOWN: ULayoutType = 4i32;\npub const ULOC_PRC: windows_sys::core::PCSTR = windows_sys::core::s!(\"zh_CN\");\npub const ULOC_SCRIPT_CAPACITY: u32 = 6u32;\npub const ULOC_SIMPLIFIED_CHINESE: windows_sys::core::PCSTR = windows_sys::core::s!(\"zh_CN\");\npub const ULOC_TAIWAN: windows_sys::core::PCSTR = windows_sys::core::s!(\"zh_TW\");\npub const ULOC_TRADITIONAL_CHINESE: windows_sys::core::PCSTR = windows_sys::core::s!(\"zh_TW\");\npub const ULOC_UK: windows_sys::core::PCSTR = windows_sys::core::s!(\"en_GB\");\npub const ULOC_US: windows_sys::core::PCSTR = windows_sys::core::s!(\"en_US\");\npub const ULOC_VALID_LOCALE: ULocDataLocaleType = 1i32;\npub type ULayoutType = i32;\npub type ULineBreak = i32;\npub type ULineBreakTag = i32;\npub type UListFormatter = isize;\npub type UListFormatterField = i32;\npub type UListFormatterType = i32;\npub type UListFormatterWidth = i32;\npub type ULocAvailableType = i32;\npub type ULocDataLocaleType = i32;\npub type ULocaleData = isize;\npub type ULocaleDataDelimiterType = i32;\npub type ULocaleDataExemplarSetType = i32;\npub type ULocaleDisplayNames = isize;\npub const UMEASFMT_WIDTH_COUNT: UMeasureFormatWidth = 4i32;\npub const UMEASFMT_WIDTH_NARROW: UMeasureFormatWidth = 2i32;\npub const UMEASFMT_WIDTH_NUMERIC: UMeasureFormatWidth = 3i32;\npub const UMEASFMT_WIDTH_SHORT: UMeasureFormatWidth = 1i32;\npub const UMEASFMT_WIDTH_WIDE: UMeasureFormatWidth = 0i32;\npub const UMSGPAT_APOS_DOUBLE_OPTIONAL: UMessagePatternApostropheMode = 0i32;\npub const UMSGPAT_APOS_DOUBLE_REQUIRED: UMessagePatternApostropheMode = 1i32;\npub const UMSGPAT_ARG_NAME_NOT_NUMBER: i32 = -1i32;\npub const UMSGPAT_ARG_NAME_NOT_VALID: i32 = -2i32;\npub const UMSGPAT_ARG_TYPE_CHOICE: UMessagePatternArgType = 2i32;\npub const UMSGPAT_ARG_TYPE_NONE: UMessagePatternArgType = 0i32;\npub const UMSGPAT_ARG_TYPE_PLURAL: UMessagePatternArgType = 3i32;\npub const UMSGPAT_ARG_TYPE_SELECT: UMessagePatternArgType = 4i32;\npub const UMSGPAT_ARG_TYPE_SELECTORDINAL: UMessagePatternArgType = 5i32;\npub const UMSGPAT_ARG_TYPE_SIMPLE: UMessagePatternArgType = 1i32;\npub const UMSGPAT_PART_TYPE_ARG_DOUBLE: UMessagePatternPartType = 13i32;\npub const UMSGPAT_PART_TYPE_ARG_INT: UMessagePatternPartType = 12i32;\npub const UMSGPAT_PART_TYPE_ARG_LIMIT: UMessagePatternPartType = 6i32;\npub const UMSGPAT_PART_TYPE_ARG_NAME: UMessagePatternPartType = 8i32;\npub const UMSGPAT_PART_TYPE_ARG_NUMBER: UMessagePatternPartType = 7i32;\npub const UMSGPAT_PART_TYPE_ARG_SELECTOR: UMessagePatternPartType = 11i32;\npub const UMSGPAT_PART_TYPE_ARG_START: UMessagePatternPartType = 5i32;\npub const UMSGPAT_PART_TYPE_ARG_STYLE: UMessagePatternPartType = 10i32;\npub const UMSGPAT_PART_TYPE_ARG_TYPE: UMessagePatternPartType = 9i32;\npub const UMSGPAT_PART_TYPE_INSERT_CHAR: UMessagePatternPartType = 3i32;\npub const UMSGPAT_PART_TYPE_MSG_LIMIT: UMessagePatternPartType = 1i32;\npub const UMSGPAT_PART_TYPE_MSG_START: UMessagePatternPartType = 0i32;\npub const UMSGPAT_PART_TYPE_REPLACE_NUMBER: UMessagePatternPartType = 4i32;\npub const UMSGPAT_PART_TYPE_SKIP_SYNTAX: UMessagePatternPartType = 2i32;\npub const UMS_SI: UMeasurementSystem = 0i32;\npub const UMS_UK: UMeasurementSystem = 2i32;\npub const UMS_US: UMeasurementSystem = 1i32;\npub type UMeasureFormatWidth = i32;\npub type UMeasurementSystem = i32;\npub type UMemAllocFn = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, size: usize) -> *mut core::ffi::c_void>;\npub type UMemFreeFn = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, mem: *mut core::ffi::c_void)>;\npub type UMemReallocFn = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, mem: *mut core::ffi::c_void, size: usize) -> *mut core::ffi::c_void>;\npub type UMessagePatternApostropheMode = i32;\npub type UMessagePatternArgType = i32;\npub type UMessagePatternPartType = i32;\npub type UMutableCPTrie = isize;\npub type UNESCAPE_CHAR_AT = Option<unsafe extern \"system\" fn(offset: i32, context: *mut core::ffi::c_void) -> u16>;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct UNICODERANGE {\n    pub wcFrom: u16,\n    pub wcTo: u16,\n}\npub const UNISCRIBE_OPENTYPE: u32 = 256u32;\npub const UNORM2_COMPOSE: UNormalization2Mode = 0i32;\npub const UNORM2_COMPOSE_CONTIGUOUS: UNormalization2Mode = 3i32;\npub const UNORM2_DECOMPOSE: UNormalization2Mode = 1i32;\npub const UNORM2_FCD: UNormalization2Mode = 2i32;\npub const UNORM_DEFAULT: UNormalizationMode = 4i32;\npub const UNORM_FCD: UNormalizationMode = 6i32;\npub const UNORM_INPUT_IS_FCD: u32 = 131072u32;\npub const UNORM_MAYBE: UNormalizationCheckResult = 2i32;\npub const UNORM_MODE_COUNT: UNormalizationMode = 7i32;\npub const UNORM_NFC: UNormalizationMode = 4i32;\npub const UNORM_NFD: UNormalizationMode = 2i32;\npub const UNORM_NFKC: UNormalizationMode = 5i32;\npub const UNORM_NFKD: UNormalizationMode = 3i32;\npub const UNORM_NO: UNormalizationCheckResult = 0i32;\npub const UNORM_NONE: UNormalizationMode = 1i32;\npub const UNORM_YES: UNormalizationCheckResult = 1i32;\npub const UNUM_CASH_CURRENCY: UNumberFormatStyle = 13i32;\npub const UNUM_COMPACT_FIELD: UNumberFormatFields = 12i32;\npub const UNUM_CURRENCY: UNumberFormatStyle = 2i32;\npub const UNUM_CURRENCY_ACCOUNTING: UNumberFormatStyle = 12i32;\npub const UNUM_CURRENCY_CODE: UNumberFormatTextAttribute = 5i32;\npub const UNUM_CURRENCY_FIELD: UNumberFormatFields = 7i32;\npub const UNUM_CURRENCY_INSERT: UCurrencySpacing = 2i32;\npub const UNUM_CURRENCY_ISO: UNumberFormatStyle = 10i32;\npub const UNUM_CURRENCY_MATCH: UCurrencySpacing = 0i32;\npub const UNUM_CURRENCY_PLURAL: UNumberFormatStyle = 11i32;\npub const UNUM_CURRENCY_SPACING_COUNT: UCurrencySpacing = 3i32;\npub const UNUM_CURRENCY_STANDARD: UNumberFormatStyle = 16i32;\npub const UNUM_CURRENCY_SURROUNDING_MATCH: UCurrencySpacing = 1i32;\npub const UNUM_CURRENCY_SYMBOL: UNumberFormatSymbol = 8i32;\npub const UNUM_CURRENCY_USAGE: UNumberFormatAttribute = 23i32;\npub const UNUM_DECIMAL: UNumberFormatStyle = 1i32;\npub const UNUM_DECIMAL_ALWAYS_SHOWN: UNumberFormatAttribute = 2i32;\npub const UNUM_DECIMAL_COMPACT_LONG: UNumberFormatStyle = 15i32;\npub const UNUM_DECIMAL_COMPACT_SHORT: UNumberFormatStyle = 14i32;\npub const UNUM_DECIMAL_SEPARATOR_ALWAYS: UNumberDecimalSeparatorDisplay = 1i32;\npub const UNUM_DECIMAL_SEPARATOR_AUTO: UNumberDecimalSeparatorDisplay = 0i32;\npub const UNUM_DECIMAL_SEPARATOR_COUNT: UNumberDecimalSeparatorDisplay = 2i32;\npub const UNUM_DECIMAL_SEPARATOR_FIELD: UNumberFormatFields = 2i32;\npub const UNUM_DECIMAL_SEPARATOR_SYMBOL: UNumberFormatSymbol = 0i32;\npub const UNUM_DEFAULT: UNumberFormatStyle = 1i32;\npub const UNUM_DEFAULT_RULESET: UNumberFormatTextAttribute = 6i32;\npub const UNUM_DIGIT_SYMBOL: UNumberFormatSymbol = 5i32;\npub const UNUM_DURATION: UNumberFormatStyle = 7i32;\npub const UNUM_EIGHT_DIGIT_SYMBOL: UNumberFormatSymbol = 25i32;\npub const UNUM_EXPONENTIAL_SYMBOL: UNumberFormatSymbol = 11i32;\npub const UNUM_EXPONENT_FIELD: UNumberFormatFields = 5i32;\npub const UNUM_EXPONENT_MULTIPLICATION_SYMBOL: UNumberFormatSymbol = 27i32;\npub const UNUM_EXPONENT_SIGN_FIELD: UNumberFormatFields = 4i32;\npub const UNUM_EXPONENT_SYMBOL_FIELD: UNumberFormatFields = 3i32;\npub const UNUM_FIVE_DIGIT_SYMBOL: UNumberFormatSymbol = 22i32;\npub const UNUM_FORMAT_ATTRIBUTE_VALUE_HIDDEN: UNumberFormatAttributeValue = 0i32;\npub const UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS: UNumberFormatAttribute = 4096i32;\npub const UNUM_FORMAT_WIDTH: UNumberFormatAttribute = 13i32;\npub const UNUM_FOUR_DIGIT_SYMBOL: UNumberFormatSymbol = 21i32;\npub const UNUM_FRACTION_DIGITS: UNumberFormatAttribute = 8i32;\npub const UNUM_FRACTION_FIELD: UNumberFormatFields = 1i32;\npub const UNUM_GROUPING_AUTO: UNumberGroupingStrategy = 2i32;\npub const UNUM_GROUPING_MIN2: UNumberGroupingStrategy = 1i32;\npub const UNUM_GROUPING_OFF: UNumberGroupingStrategy = 0i32;\npub const UNUM_GROUPING_ON_ALIGNED: UNumberGroupingStrategy = 3i32;\npub const UNUM_GROUPING_SEPARATOR_FIELD: UNumberFormatFields = 6i32;\npub const UNUM_GROUPING_SEPARATOR_SYMBOL: UNumberFormatSymbol = 1i32;\npub const UNUM_GROUPING_SIZE: UNumberFormatAttribute = 10i32;\npub const UNUM_GROUPING_THOUSANDS: UNumberGroupingStrategy = 4i32;\npub const UNUM_GROUPING_USED: UNumberFormatAttribute = 1i32;\npub const UNUM_IDENTITY_FALLBACK_APPROXIMATELY: UNumberRangeIdentityFallback = 2i32;\npub const UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE: UNumberRangeIdentityFallback = 1i32;\npub const UNUM_IDENTITY_FALLBACK_RANGE: UNumberRangeIdentityFallback = 3i32;\npub const UNUM_IDENTITY_FALLBACK_SINGLE_VALUE: UNumberRangeIdentityFallback = 0i32;\npub const UNUM_IDENTITY_RESULT_EQUAL_AFTER_ROUNDING: UNumberRangeIdentityResult = 1i32;\npub const UNUM_IDENTITY_RESULT_EQUAL_BEFORE_ROUNDING: UNumberRangeIdentityResult = 0i32;\npub const UNUM_IDENTITY_RESULT_NOT_EQUAL: UNumberRangeIdentityResult = 2i32;\npub const UNUM_IGNORE: UNumberFormatStyle = 0i32;\npub const UNUM_INFINITY_SYMBOL: UNumberFormatSymbol = 14i32;\npub const UNUM_INTEGER_DIGITS: UNumberFormatAttribute = 5i32;\npub const UNUM_INTEGER_FIELD: UNumberFormatFields = 0i32;\npub const UNUM_INTL_CURRENCY_SYMBOL: UNumberFormatSymbol = 9i32;\npub const UNUM_LENIENT_PARSE: UNumberFormatAttribute = 19i32;\npub const UNUM_LONG: UNumberCompactStyle = 1i32;\npub const UNUM_MAX_FRACTION_DIGITS: UNumberFormatAttribute = 6i32;\npub const UNUM_MAX_INTEGER_DIGITS: UNumberFormatAttribute = 3i32;\npub const UNUM_MAX_SIGNIFICANT_DIGITS: UNumberFormatAttribute = 18i32;\npub const UNUM_MEASURE_UNIT_FIELD: UNumberFormatFields = 11i32;\npub const UNUM_MINIMUM_GROUPING_DIGITS: UNumberFormatAttribute = 22i32;\npub const UNUM_MINUS_SIGN_SYMBOL: UNumberFormatSymbol = 6i32;\npub const UNUM_MIN_FRACTION_DIGITS: UNumberFormatAttribute = 7i32;\npub const UNUM_MIN_INTEGER_DIGITS: UNumberFormatAttribute = 4i32;\npub const UNUM_MIN_SIGNIFICANT_DIGITS: UNumberFormatAttribute = 17i32;\npub const UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL: UNumberFormatSymbol = 17i32;\npub const UNUM_MONETARY_SEPARATOR_SYMBOL: UNumberFormatSymbol = 10i32;\npub const UNUM_MULTIPLIER: UNumberFormatAttribute = 9i32;\npub const UNUM_NAN_SYMBOL: UNumberFormatSymbol = 15i32;\npub const UNUM_NEGATIVE_PREFIX: UNumberFormatTextAttribute = 2i32;\npub const UNUM_NEGATIVE_SUFFIX: UNumberFormatTextAttribute = 3i32;\npub const UNUM_NINE_DIGIT_SYMBOL: UNumberFormatSymbol = 26i32;\npub const UNUM_NUMBERING_SYSTEM: UNumberFormatStyle = 8i32;\npub const UNUM_ONE_DIGIT_SYMBOL: UNumberFormatSymbol = 18i32;\npub const UNUM_ORDINAL: UNumberFormatStyle = 6i32;\npub const UNUM_PADDING_CHARACTER: UNumberFormatTextAttribute = 4i32;\npub const UNUM_PADDING_POSITION: UNumberFormatAttribute = 14i32;\npub const UNUM_PAD_AFTER_PREFIX: UNumberFormatPadPosition = 1i32;\npub const UNUM_PAD_AFTER_SUFFIX: UNumberFormatPadPosition = 3i32;\npub const UNUM_PAD_BEFORE_PREFIX: UNumberFormatPadPosition = 0i32;\npub const UNUM_PAD_BEFORE_SUFFIX: UNumberFormatPadPosition = 2i32;\npub const UNUM_PAD_ESCAPE_SYMBOL: UNumberFormatSymbol = 13i32;\npub const UNUM_PARSE_ALL_INPUT: UNumberFormatAttribute = 20i32;\npub const UNUM_PARSE_CASE_SENSITIVE: UNumberFormatAttribute = 4099i32;\npub const UNUM_PARSE_DECIMAL_MARK_REQUIRED: UNumberFormatAttribute = 4098i32;\npub const UNUM_PARSE_INT_ONLY: UNumberFormatAttribute = 0i32;\npub const UNUM_PARSE_NO_EXPONENT: UNumberFormatAttribute = 4097i32;\npub const UNUM_PATTERN_DECIMAL: UNumberFormatStyle = 0i32;\npub const UNUM_PATTERN_RULEBASED: UNumberFormatStyle = 9i32;\npub const UNUM_PATTERN_SEPARATOR_SYMBOL: UNumberFormatSymbol = 2i32;\npub const UNUM_PERCENT: UNumberFormatStyle = 3i32;\npub const UNUM_PERCENT_FIELD: UNumberFormatFields = 8i32;\npub const UNUM_PERCENT_SYMBOL: UNumberFormatSymbol = 3i32;\npub const UNUM_PERMILL_FIELD: UNumberFormatFields = 9i32;\npub const UNUM_PERMILL_SYMBOL: UNumberFormatSymbol = 12i32;\npub const UNUM_PLUS_SIGN_SYMBOL: UNumberFormatSymbol = 7i32;\npub const UNUM_POSITIVE_PREFIX: UNumberFormatTextAttribute = 0i32;\npub const UNUM_POSITIVE_SUFFIX: UNumberFormatTextAttribute = 1i32;\npub const UNUM_PUBLIC_RULESETS: UNumberFormatTextAttribute = 7i32;\npub const UNUM_RANGE_COLLAPSE_ALL: UNumberRangeCollapse = 3i32;\npub const UNUM_RANGE_COLLAPSE_AUTO: UNumberRangeCollapse = 0i32;\npub const UNUM_RANGE_COLLAPSE_NONE: UNumberRangeCollapse = 1i32;\npub const UNUM_RANGE_COLLAPSE_UNIT: UNumberRangeCollapse = 2i32;\npub const UNUM_ROUNDING_INCREMENT: UNumberFormatAttribute = 12i32;\npub const UNUM_ROUNDING_MODE: UNumberFormatAttribute = 11i32;\npub const UNUM_ROUND_CEILING: UNumberFormatRoundingMode = 0i32;\npub const UNUM_ROUND_DOWN: UNumberFormatRoundingMode = 2i32;\npub const UNUM_ROUND_FLOOR: UNumberFormatRoundingMode = 1i32;\npub const UNUM_ROUND_HALFDOWN: UNumberFormatRoundingMode = 5i32;\npub const UNUM_ROUND_HALFEVEN: UNumberFormatRoundingMode = 4i32;\npub const UNUM_ROUND_HALFUP: UNumberFormatRoundingMode = 6i32;\npub const UNUM_ROUND_UNNECESSARY: UNumberFormatRoundingMode = 7i32;\npub const UNUM_ROUND_UP: UNumberFormatRoundingMode = 3i32;\npub const UNUM_SCALE: UNumberFormatAttribute = 21i32;\npub const UNUM_SCIENTIFIC: UNumberFormatStyle = 4i32;\npub const UNUM_SECONDARY_GROUPING_SIZE: UNumberFormatAttribute = 15i32;\npub const UNUM_SEVEN_DIGIT_SYMBOL: UNumberFormatSymbol = 24i32;\npub const UNUM_SHORT: UNumberCompactStyle = 0i32;\npub const UNUM_SIGNIFICANT_DIGITS_USED: UNumberFormatAttribute = 16i32;\npub const UNUM_SIGNIFICANT_DIGIT_SYMBOL: UNumberFormatSymbol = 16i32;\npub const UNUM_SIGN_ACCOUNTING: UNumberSignDisplay = 3i32;\npub const UNUM_SIGN_ACCOUNTING_ALWAYS: UNumberSignDisplay = 4i32;\npub const UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO: UNumberSignDisplay = 6i32;\npub const UNUM_SIGN_ALWAYS: UNumberSignDisplay = 1i32;\npub const UNUM_SIGN_ALWAYS_SHOWN: UNumberFormatAttribute = 4100i32;\npub const UNUM_SIGN_AUTO: UNumberSignDisplay = 0i32;\npub const UNUM_SIGN_COUNT: UNumberSignDisplay = 7i32;\npub const UNUM_SIGN_EXCEPT_ZERO: UNumberSignDisplay = 5i32;\npub const UNUM_SIGN_FIELD: UNumberFormatFields = 10i32;\npub const UNUM_SIGN_NEVER: UNumberSignDisplay = 2i32;\npub const UNUM_SIX_DIGIT_SYMBOL: UNumberFormatSymbol = 23i32;\npub const UNUM_SPELLOUT: UNumberFormatStyle = 5i32;\npub const UNUM_THREE_DIGIT_SYMBOL: UNumberFormatSymbol = 20i32;\npub const UNUM_TWO_DIGIT_SYMBOL: UNumberFormatSymbol = 19i32;\npub const UNUM_UNIT_WIDTH_COUNT: UNumberUnitWidth = 5i32;\npub const UNUM_UNIT_WIDTH_FULL_NAME: UNumberUnitWidth = 2i32;\npub const UNUM_UNIT_WIDTH_HIDDEN: UNumberUnitWidth = 4i32;\npub const UNUM_UNIT_WIDTH_ISO_CODE: UNumberUnitWidth = 3i32;\npub const UNUM_UNIT_WIDTH_NARROW: UNumberUnitWidth = 0i32;\npub const UNUM_UNIT_WIDTH_SHORT: UNumberUnitWidth = 1i32;\npub const UNUM_ZERO_DIGIT_SYMBOL: UNumberFormatSymbol = 4i32;\npub type UNormalization2Mode = i32;\npub type UNormalizationCheckResult = i32;\npub type UNormalizationMode = i32;\npub type UNormalizer2 = isize;\npub type UNumberCompactStyle = i32;\npub type UNumberDecimalSeparatorDisplay = i32;\npub type UNumberFormatAttribute = i32;\npub type UNumberFormatAttributeValue = i32;\npub type UNumberFormatFields = i32;\npub type UNumberFormatPadPosition = i32;\npub type UNumberFormatRoundingMode = i32;\npub type UNumberFormatStyle = i32;\npub type UNumberFormatSymbol = i32;\npub type UNumberFormatTextAttribute = i32;\npub type UNumberFormatter = isize;\npub type UNumberGroupingStrategy = i32;\npub type UNumberRangeCollapse = i32;\npub type UNumberRangeIdentityFallback = i32;\npub type UNumberRangeIdentityResult = i32;\npub type UNumberSignDisplay = i32;\npub type UNumberUnitWidth = i32;\npub type UNumberingSystem = isize;\npub type UNumericType = i32;\npub const UPLURAL_TYPE_CARDINAL: UPluralType = 0i32;\npub const UPLURAL_TYPE_ORDINAL: UPluralType = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct UParseError {\n    pub line: i32,\n    pub offset: i32,\n    pub preContext: [u16; 16],\n    pub postContext: [u16; 16],\n}\nimpl Default for UParseError {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type UPluralRules = isize;\npub type UPluralType = i32;\npub type UProperty = i32;\npub type UPropertyNameChoice = i32;\npub const UREGEX_CASE_INSENSITIVE: URegexpFlag = 2i32;\npub const UREGEX_COMMENTS: URegexpFlag = 4i32;\npub const UREGEX_DOTALL: URegexpFlag = 32i32;\npub const UREGEX_ERROR_ON_UNKNOWN_ESCAPES: URegexpFlag = 512i32;\npub const UREGEX_LITERAL: URegexpFlag = 16i32;\npub const UREGEX_MULTILINE: URegexpFlag = 8i32;\npub const UREGEX_UNIX_LINES: URegexpFlag = 1i32;\npub const UREGEX_UWORD: URegexpFlag = 256i32;\npub const URES_ALIAS: UResType = 3i32;\npub const URES_ARRAY: UResType = 8i32;\npub const URES_BINARY: UResType = 1i32;\npub const URES_INT: UResType = 7i32;\npub const URES_INT_VECTOR: UResType = 14i32;\npub const URES_NONE: UResType = -1i32;\npub const URES_STRING: UResType = 0i32;\npub const URES_TABLE: UResType = 2i32;\npub const URGN_CONTINENT: URegionType = 3i32;\npub const URGN_DEPRECATED: URegionType = 6i32;\npub const URGN_GROUPING: URegionType = 5i32;\npub const URGN_SUBCONTINENT: URegionType = 4i32;\npub const URGN_TERRITORY: URegionType = 1i32;\npub const URGN_UNKNOWN: URegionType = 0i32;\npub const URGN_WORLD: URegionType = 2i32;\npub type URegexFindProgressCallback = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, matchindex: i64) -> i8>;\npub type URegexMatchCallback = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, steps: i32) -> i8>;\npub type URegexpFlag = i32;\npub type URegion = isize;\npub type URegionType = i32;\npub type URegularExpression = isize;\npub type URelativeDateTimeFormatter = isize;\npub type URelativeDateTimeFormatterField = i32;\npub type URelativeDateTimeUnit = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct UReplaceableCallbacks {\n    pub length: isize,\n    pub charAt: isize,\n    pub char32At: isize,\n    pub replace: isize,\n    pub extract: isize,\n    pub copy: isize,\n}\npub type UResType = i32;\npub type UResourceBundle = isize;\npub type URestrictionLevel = i32;\npub const USCRIPT_ADLAM: UScriptCode = 167i32;\npub const USCRIPT_AFAKA: UScriptCode = 147i32;\npub const USCRIPT_AHOM: UScriptCode = 161i32;\npub const USCRIPT_ANATOLIAN_HIEROGLYPHS: UScriptCode = 156i32;\npub const USCRIPT_ARABIC: UScriptCode = 2i32;\npub const USCRIPT_ARMENIAN: UScriptCode = 3i32;\npub const USCRIPT_AVESTAN: UScriptCode = 117i32;\npub const USCRIPT_BALINESE: UScriptCode = 62i32;\npub const USCRIPT_BAMUM: UScriptCode = 130i32;\npub const USCRIPT_BASSA_VAH: UScriptCode = 134i32;\npub const USCRIPT_BATAK: UScriptCode = 63i32;\npub const USCRIPT_BENGALI: UScriptCode = 4i32;\npub const USCRIPT_BHAIKSUKI: UScriptCode = 168i32;\npub const USCRIPT_BLISSYMBOLS: UScriptCode = 64i32;\npub const USCRIPT_BOOK_PAHLAVI: UScriptCode = 124i32;\npub const USCRIPT_BOPOMOFO: UScriptCode = 5i32;\npub const USCRIPT_BRAHMI: UScriptCode = 65i32;\npub const USCRIPT_BRAILLE: UScriptCode = 46i32;\npub const USCRIPT_BUGINESE: UScriptCode = 55i32;\npub const USCRIPT_BUHID: UScriptCode = 44i32;\npub const USCRIPT_CANADIAN_ABORIGINAL: UScriptCode = 40i32;\npub const USCRIPT_CARIAN: UScriptCode = 104i32;\npub const USCRIPT_CAUCASIAN_ALBANIAN: UScriptCode = 159i32;\npub const USCRIPT_CHAKMA: UScriptCode = 118i32;\npub const USCRIPT_CHAM: UScriptCode = 66i32;\npub const USCRIPT_CHEROKEE: UScriptCode = 6i32;\npub const USCRIPT_CHORASMIAN: UScriptCode = 189i32;\npub const USCRIPT_CIRTH: UScriptCode = 67i32;\npub const USCRIPT_COMMON: UScriptCode = 0i32;\npub const USCRIPT_COPTIC: UScriptCode = 7i32;\npub const USCRIPT_CUNEIFORM: UScriptCode = 101i32;\npub const USCRIPT_CYPRIOT: UScriptCode = 47i32;\npub const USCRIPT_CYRILLIC: UScriptCode = 8i32;\npub const USCRIPT_DEMOTIC_EGYPTIAN: UScriptCode = 69i32;\npub const USCRIPT_DESERET: UScriptCode = 9i32;\npub const USCRIPT_DEVANAGARI: UScriptCode = 10i32;\npub const USCRIPT_DIVES_AKURU: UScriptCode = 190i32;\npub const USCRIPT_DOGRA: UScriptCode = 178i32;\npub const USCRIPT_DUPLOYAN: UScriptCode = 135i32;\npub const USCRIPT_EASTERN_SYRIAC: UScriptCode = 97i32;\npub const USCRIPT_EGYPTIAN_HIEROGLYPHS: UScriptCode = 71i32;\npub const USCRIPT_ELBASAN: UScriptCode = 136i32;\npub const USCRIPT_ELYMAIC: UScriptCode = 185i32;\npub const USCRIPT_ESTRANGELO_SYRIAC: UScriptCode = 95i32;\npub const USCRIPT_ETHIOPIC: UScriptCode = 11i32;\npub const USCRIPT_GEORGIAN: UScriptCode = 12i32;\npub const USCRIPT_GLAGOLITIC: UScriptCode = 56i32;\npub const USCRIPT_GOTHIC: UScriptCode = 13i32;\npub const USCRIPT_GRANTHA: UScriptCode = 137i32;\npub const USCRIPT_GREEK: UScriptCode = 14i32;\npub const USCRIPT_GUJARATI: UScriptCode = 15i32;\npub const USCRIPT_GUNJALA_GONDI: UScriptCode = 179i32;\npub const USCRIPT_GURMUKHI: UScriptCode = 16i32;\npub const USCRIPT_HAN: UScriptCode = 17i32;\npub const USCRIPT_HANGUL: UScriptCode = 18i32;\npub const USCRIPT_HANIFI_ROHINGYA: UScriptCode = 182i32;\npub const USCRIPT_HANUNOO: UScriptCode = 43i32;\npub const USCRIPT_HAN_WITH_BOPOMOFO: UScriptCode = 172i32;\npub const USCRIPT_HARAPPAN_INDUS: UScriptCode = 77i32;\npub const USCRIPT_HATRAN: UScriptCode = 162i32;\npub const USCRIPT_HEBREW: UScriptCode = 19i32;\npub const USCRIPT_HIERATIC_EGYPTIAN: UScriptCode = 70i32;\npub const USCRIPT_HIRAGANA: UScriptCode = 20i32;\npub const USCRIPT_IMPERIAL_ARAMAIC: UScriptCode = 116i32;\npub const USCRIPT_INHERITED: UScriptCode = 1i32;\npub const USCRIPT_INSCRIPTIONAL_PAHLAVI: UScriptCode = 122i32;\npub const USCRIPT_INSCRIPTIONAL_PARTHIAN: UScriptCode = 125i32;\npub const USCRIPT_INVALID_CODE: UScriptCode = -1i32;\npub const USCRIPT_JAMO: UScriptCode = 173i32;\npub const USCRIPT_JAPANESE: UScriptCode = 105i32;\npub const USCRIPT_JAVANESE: UScriptCode = 78i32;\npub const USCRIPT_JURCHEN: UScriptCode = 148i32;\npub const USCRIPT_KAITHI: UScriptCode = 120i32;\npub const USCRIPT_KANNADA: UScriptCode = 21i32;\npub const USCRIPT_KATAKANA: UScriptCode = 22i32;\npub const USCRIPT_KATAKANA_OR_HIRAGANA: UScriptCode = 54i32;\npub const USCRIPT_KAYAH_LI: UScriptCode = 79i32;\npub const USCRIPT_KHAROSHTHI: UScriptCode = 57i32;\npub const USCRIPT_KHITAN_SMALL_SCRIPT: UScriptCode = 191i32;\npub const USCRIPT_KHMER: UScriptCode = 23i32;\npub const USCRIPT_KHOJKI: UScriptCode = 157i32;\npub const USCRIPT_KHUDAWADI: UScriptCode = 145i32;\npub const USCRIPT_KHUTSURI: UScriptCode = 72i32;\npub const USCRIPT_KOREAN: UScriptCode = 119i32;\npub const USCRIPT_KPELLE: UScriptCode = 138i32;\npub const USCRIPT_LANNA: UScriptCode = 106i32;\npub const USCRIPT_LAO: UScriptCode = 24i32;\npub const USCRIPT_LATIN: UScriptCode = 25i32;\npub const USCRIPT_LATIN_FRAKTUR: UScriptCode = 80i32;\npub const USCRIPT_LATIN_GAELIC: UScriptCode = 81i32;\npub const USCRIPT_LEPCHA: UScriptCode = 82i32;\npub const USCRIPT_LIMBU: UScriptCode = 48i32;\npub const USCRIPT_LINEAR_A: UScriptCode = 83i32;\npub const USCRIPT_LINEAR_B: UScriptCode = 49i32;\npub const USCRIPT_LISU: UScriptCode = 131i32;\npub const USCRIPT_LOMA: UScriptCode = 139i32;\npub const USCRIPT_LYCIAN: UScriptCode = 107i32;\npub const USCRIPT_LYDIAN: UScriptCode = 108i32;\npub const USCRIPT_MAHAJANI: UScriptCode = 160i32;\npub const USCRIPT_MAKASAR: UScriptCode = 180i32;\npub const USCRIPT_MALAYALAM: UScriptCode = 26i32;\npub const USCRIPT_MANDAEAN: UScriptCode = 84i32;\npub const USCRIPT_MANDAIC: UScriptCode = 84i32;\npub const USCRIPT_MANICHAEAN: UScriptCode = 121i32;\npub const USCRIPT_MARCHEN: UScriptCode = 169i32;\npub const USCRIPT_MASARAM_GONDI: UScriptCode = 175i32;\npub const USCRIPT_MATHEMATICAL_NOTATION: UScriptCode = 128i32;\npub const USCRIPT_MAYAN_HIEROGLYPHS: UScriptCode = 85i32;\npub const USCRIPT_MEDEFAIDRIN: UScriptCode = 181i32;\npub const USCRIPT_MEITEI_MAYEK: UScriptCode = 115i32;\npub const USCRIPT_MENDE: UScriptCode = 140i32;\npub const USCRIPT_MEROITIC: UScriptCode = 86i32;\npub const USCRIPT_MEROITIC_CURSIVE: UScriptCode = 141i32;\npub const USCRIPT_MEROITIC_HIEROGLYPHS: UScriptCode = 86i32;\npub const USCRIPT_MIAO: UScriptCode = 92i32;\npub const USCRIPT_MODI: UScriptCode = 163i32;\npub const USCRIPT_MONGOLIAN: UScriptCode = 27i32;\npub const USCRIPT_MOON: UScriptCode = 114i32;\npub const USCRIPT_MRO: UScriptCode = 149i32;\npub const USCRIPT_MULTANI: UScriptCode = 164i32;\npub const USCRIPT_MYANMAR: UScriptCode = 28i32;\npub const USCRIPT_NABATAEAN: UScriptCode = 143i32;\npub const USCRIPT_NAKHI_GEBA: UScriptCode = 132i32;\npub const USCRIPT_NANDINAGARI: UScriptCode = 187i32;\npub const USCRIPT_NEWA: UScriptCode = 170i32;\npub const USCRIPT_NEW_TAI_LUE: UScriptCode = 59i32;\npub const USCRIPT_NKO: UScriptCode = 87i32;\npub const USCRIPT_NUSHU: UScriptCode = 150i32;\npub const USCRIPT_NYIAKENG_PUACHUE_HMONG: UScriptCode = 186i32;\npub const USCRIPT_OGHAM: UScriptCode = 29i32;\npub const USCRIPT_OLD_CHURCH_SLAVONIC_CYRILLIC: UScriptCode = 68i32;\npub const USCRIPT_OLD_HUNGARIAN: UScriptCode = 76i32;\npub const USCRIPT_OLD_ITALIC: UScriptCode = 30i32;\npub const USCRIPT_OLD_NORTH_ARABIAN: UScriptCode = 142i32;\npub const USCRIPT_OLD_PERMIC: UScriptCode = 89i32;\npub const USCRIPT_OLD_PERSIAN: UScriptCode = 61i32;\npub const USCRIPT_OLD_SOGDIAN: UScriptCode = 184i32;\npub const USCRIPT_OLD_SOUTH_ARABIAN: UScriptCode = 133i32;\npub const USCRIPT_OL_CHIKI: UScriptCode = 109i32;\npub const USCRIPT_ORIYA: UScriptCode = 31i32;\npub const USCRIPT_ORKHON: UScriptCode = 88i32;\npub const USCRIPT_OSAGE: UScriptCode = 171i32;\npub const USCRIPT_OSMANYA: UScriptCode = 50i32;\npub const USCRIPT_PAHAWH_HMONG: UScriptCode = 75i32;\npub const USCRIPT_PALMYRENE: UScriptCode = 144i32;\npub const USCRIPT_PAU_CIN_HAU: UScriptCode = 165i32;\npub const USCRIPT_PHAGS_PA: UScriptCode = 90i32;\npub const USCRIPT_PHOENICIAN: UScriptCode = 91i32;\npub const USCRIPT_PHONETIC_POLLARD: UScriptCode = 92i32;\npub const USCRIPT_PSALTER_PAHLAVI: UScriptCode = 123i32;\npub const USCRIPT_REJANG: UScriptCode = 110i32;\npub const USCRIPT_RONGORONGO: UScriptCode = 93i32;\npub const USCRIPT_RUNIC: UScriptCode = 32i32;\npub const USCRIPT_SAMARITAN: UScriptCode = 126i32;\npub const USCRIPT_SARATI: UScriptCode = 94i32;\npub const USCRIPT_SAURASHTRA: UScriptCode = 111i32;\npub const USCRIPT_SHARADA: UScriptCode = 151i32;\npub const USCRIPT_SHAVIAN: UScriptCode = 51i32;\npub const USCRIPT_SIDDHAM: UScriptCode = 166i32;\npub const USCRIPT_SIGN_WRITING: UScriptCode = 112i32;\npub const USCRIPT_SIMPLIFIED_HAN: UScriptCode = 73i32;\npub const USCRIPT_SINDHI: UScriptCode = 145i32;\npub const USCRIPT_SINHALA: UScriptCode = 33i32;\npub const USCRIPT_SOGDIAN: UScriptCode = 183i32;\npub const USCRIPT_SORA_SOMPENG: UScriptCode = 152i32;\npub const USCRIPT_SOYOMBO: UScriptCode = 176i32;\npub const USCRIPT_SUNDANESE: UScriptCode = 113i32;\npub const USCRIPT_SYLOTI_NAGRI: UScriptCode = 58i32;\npub const USCRIPT_SYMBOLS: UScriptCode = 129i32;\npub const USCRIPT_SYMBOLS_EMOJI: UScriptCode = 174i32;\npub const USCRIPT_SYRIAC: UScriptCode = 34i32;\npub const USCRIPT_TAGALOG: UScriptCode = 42i32;\npub const USCRIPT_TAGBANWA: UScriptCode = 45i32;\npub const USCRIPT_TAI_LE: UScriptCode = 52i32;\npub const USCRIPT_TAI_VIET: UScriptCode = 127i32;\npub const USCRIPT_TAKRI: UScriptCode = 153i32;\npub const USCRIPT_TAMIL: UScriptCode = 35i32;\npub const USCRIPT_TANGUT: UScriptCode = 154i32;\npub const USCRIPT_TELUGU: UScriptCode = 36i32;\npub const USCRIPT_TENGWAR: UScriptCode = 98i32;\npub const USCRIPT_THAANA: UScriptCode = 37i32;\npub const USCRIPT_THAI: UScriptCode = 38i32;\npub const USCRIPT_TIBETAN: UScriptCode = 39i32;\npub const USCRIPT_TIFINAGH: UScriptCode = 60i32;\npub const USCRIPT_TIRHUTA: UScriptCode = 158i32;\npub const USCRIPT_TRADITIONAL_HAN: UScriptCode = 74i32;\npub const USCRIPT_UCAS: UScriptCode = 40i32;\npub const USCRIPT_UGARITIC: UScriptCode = 53i32;\npub const USCRIPT_UNKNOWN: UScriptCode = 103i32;\npub const USCRIPT_UNWRITTEN_LANGUAGES: UScriptCode = 102i32;\npub const USCRIPT_USAGE_ASPIRATIONAL: UScriptUsage = 4i32;\npub const USCRIPT_USAGE_EXCLUDED: UScriptUsage = 2i32;\npub const USCRIPT_USAGE_LIMITED_USE: UScriptUsage = 3i32;\npub const USCRIPT_USAGE_NOT_ENCODED: UScriptUsage = 0i32;\npub const USCRIPT_USAGE_RECOMMENDED: UScriptUsage = 5i32;\npub const USCRIPT_USAGE_UNKNOWN: UScriptUsage = 1i32;\npub const USCRIPT_VAI: UScriptCode = 99i32;\npub const USCRIPT_VISIBLE_SPEECH: UScriptCode = 100i32;\npub const USCRIPT_WANCHO: UScriptCode = 188i32;\npub const USCRIPT_WARANG_CITI: UScriptCode = 146i32;\npub const USCRIPT_WESTERN_SYRIAC: UScriptCode = 96i32;\npub const USCRIPT_WOLEAI: UScriptCode = 155i32;\npub const USCRIPT_YEZIDI: UScriptCode = 192i32;\npub const USCRIPT_YI: UScriptCode = 41i32;\npub const USCRIPT_ZANABAZAR_SQUARE: UScriptCode = 177i32;\npub const USEARCH_ANY_BASE_WEIGHT_IS_WILDCARD: USearchAttributeValue = 4i32;\npub const USEARCH_DEFAULT: USearchAttributeValue = -1i32;\npub const USEARCH_DONE: i32 = -1i32;\npub const USEARCH_ELEMENT_COMPARISON: USearchAttribute = 2i32;\npub const USEARCH_OFF: USearchAttributeValue = 0i32;\npub const USEARCH_ON: USearchAttributeValue = 1i32;\npub const USEARCH_OVERLAP: USearchAttribute = 0i32;\npub const USEARCH_PATTERN_BASE_WEIGHT_IS_WILDCARD: USearchAttributeValue = 3i32;\npub const USEARCH_STANDARD_ELEMENT_COMPARISON: USearchAttributeValue = 2i32;\npub const USET_ADD_CASE_MAPPINGS: i32 = 4i32;\npub const USET_CASE_INSENSITIVE: i32 = 2i32;\npub const USET_IGNORE_SPACE: i32 = 1i32;\npub const USET_SERIALIZED_STATIC_ARRAY_CAPACITY: i32 = 8i32;\npub const USET_SPAN_CONTAINED: USetSpanCondition = 1i32;\npub const USET_SPAN_NOT_CONTAINED: USetSpanCondition = 0i32;\npub const USET_SPAN_SIMPLE: USetSpanCondition = 2i32;\npub const USPOOF_ALL_CHECKS: USpoofChecks = 65535i32;\npub const USPOOF_ASCII: URestrictionLevel = 268435456i32;\npub const USPOOF_AUX_INFO: USpoofChecks = 1073741824i32;\npub const USPOOF_CHAR_LIMIT: USpoofChecks = 64i32;\npub const USPOOF_CONFUSABLE: USpoofChecks = 7i32;\npub const USPOOF_HIDDEN_OVERLAY: USpoofChecks = 256i32;\npub const USPOOF_HIGHLY_RESTRICTIVE: URestrictionLevel = 805306368i32;\npub const USPOOF_INVISIBLE: USpoofChecks = 32i32;\npub const USPOOF_MINIMALLY_RESTRICTIVE: URestrictionLevel = 1342177280i32;\npub const USPOOF_MIXED_NUMBERS: USpoofChecks = 128i32;\npub const USPOOF_MIXED_SCRIPT_CONFUSABLE: USpoofChecks = 2i32;\npub const USPOOF_MODERATELY_RESTRICTIVE: URestrictionLevel = 1073741824i32;\npub const USPOOF_RESTRICTION_LEVEL: USpoofChecks = 16i32;\npub const USPOOF_RESTRICTION_LEVEL_MASK: URestrictionLevel = 2130706432i32;\npub const USPOOF_SINGLE_SCRIPT_CONFUSABLE: USpoofChecks = 1i32;\npub const USPOOF_SINGLE_SCRIPT_RESTRICTIVE: URestrictionLevel = 536870912i32;\npub const USPOOF_UNRESTRICTIVE: URestrictionLevel = 1610612736i32;\npub const USPOOF_WHOLE_SCRIPT_CONFUSABLE: USpoofChecks = 4i32;\npub const USPREP_ALLOW_UNASSIGNED: u32 = 1u32;\npub const USPREP_DEFAULT: u32 = 0u32;\npub const USPREP_RFC3491_NAMEPREP: UStringPrepProfileType = 0i32;\npub const USPREP_RFC3530_NFS4_CIS_PREP: UStringPrepProfileType = 3i32;\npub const USPREP_RFC3530_NFS4_CS_PREP: UStringPrepProfileType = 1i32;\npub const USPREP_RFC3530_NFS4_CS_PREP_CI: UStringPrepProfileType = 2i32;\npub const USPREP_RFC3530_NFS4_MIXED_PREP_PREFIX: UStringPrepProfileType = 4i32;\npub const USPREP_RFC3530_NFS4_MIXED_PREP_SUFFIX: UStringPrepProfileType = 5i32;\npub const USPREP_RFC3722_ISCSI: UStringPrepProfileType = 6i32;\npub const USPREP_RFC3920_NODEPREP: UStringPrepProfileType = 7i32;\npub const USPREP_RFC3920_RESOURCEPREP: UStringPrepProfileType = 8i32;\npub const USPREP_RFC4011_MIB: UStringPrepProfileType = 9i32;\npub const USPREP_RFC4013_SASLPREP: UStringPrepProfileType = 10i32;\npub const USPREP_RFC4505_TRACE: UStringPrepProfileType = 11i32;\npub const USPREP_RFC4518_LDAP: UStringPrepProfileType = 12i32;\npub const USPREP_RFC4518_LDAP_CI: UStringPrepProfileType = 13i32;\npub const USP_E_SCRIPT_NOT_IN_FONT: windows_sys::core::HRESULT = 0x80040200_u32 as _;\npub const USTRINGTRIE_BUILD_FAST: UStringTrieBuildOption = 0i32;\npub const USTRINGTRIE_BUILD_SMALL: UStringTrieBuildOption = 1i32;\npub const USTRINGTRIE_FINAL_VALUE: UStringTrieResult = 2i32;\npub const USTRINGTRIE_INTERMEDIATE_VALUE: UStringTrieResult = 3i32;\npub const USTRINGTRIE_NO_MATCH: UStringTrieResult = 0i32;\npub const USTRINGTRIE_NO_VALUE: UStringTrieResult = 1i32;\npub type UScriptCode = i32;\npub type UScriptUsage = i32;\npub type USearch = isize;\npub type USearchAttribute = i32;\npub type USearchAttributeValue = i32;\npub type USentenceBreak = i32;\npub type USentenceBreakTag = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct USerializedSet {\n    pub array: *const u16,\n    pub bmpLength: i32,\n    pub length: i32,\n    pub staticArray: [u16; 8],\n}\nimpl Default for USerializedSet {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type USet = isize;\npub type USetSpanCondition = i32;\npub type USpoofCheckResult = isize;\npub type USpoofChecker = isize;\npub type USpoofChecks = i32;\npub type UStringCaseMapper = Option<unsafe extern \"system\" fn(csm: *const UCaseMap, dest: *mut u16, destcapacity: i32, src: *const u16, srclength: i32, perrorcode: *mut UErrorCode) -> i32>;\npub type UStringPrepProfile = isize;\npub type UStringPrepProfileType = i32;\npub type UStringSearch = isize;\npub type UStringTrieBuildOption = i32;\npub type UStringTrieResult = i32;\npub type USystemTimeZoneType = i32;\npub const UTEXT_MAGIC: i32 = 878368812i32;\npub const UTEXT_PROVIDER_HAS_META_DATA: i32 = 4i32;\npub const UTEXT_PROVIDER_LENGTH_IS_EXPENSIVE: i32 = 1i32;\npub const UTEXT_PROVIDER_OWNS_TEXT: i32 = 5i32;\npub const UTEXT_PROVIDER_STABLE_CHUNKS: i32 = 2i32;\npub const UTEXT_PROVIDER_WRITABLE: i32 = 3i32;\npub const UTF16_MAX_CHAR_LENGTH: u32 = 2u32;\npub const UTF32_MAX_CHAR_LENGTH: u32 = 1u32;\npub const UTF8_ERROR_VALUE_1: u32 = 21u32;\npub const UTF8_ERROR_VALUE_2: u32 = 159u32;\npub const UTF8_MAX_CHAR_LENGTH: u32 = 4u32;\npub const UTF_ERROR_VALUE: u32 = 65535u32;\npub const UTF_MAX_CHAR_LENGTH: u32 = 2u32;\npub const UTF_SIZE: u32 = 16u32;\npub const UTRACE_COLLATION_START: UTraceFunctionNumber = 8192i32;\npub const UTRACE_CONVERSION_START: UTraceFunctionNumber = 4096i32;\npub const UTRACE_ERROR: UTraceLevel = 0i32;\npub const UTRACE_FUNCTION_START: UTraceFunctionNumber = 0i32;\npub const UTRACE_INFO: UTraceLevel = 7i32;\npub const UTRACE_OFF: UTraceLevel = -1i32;\npub const UTRACE_OPEN_CLOSE: UTraceLevel = 5i32;\npub const UTRACE_UCNV_CLONE: UTraceFunctionNumber = 4099i32;\npub const UTRACE_UCNV_CLOSE: UTraceFunctionNumber = 4100i32;\npub const UTRACE_UCNV_FLUSH_CACHE: UTraceFunctionNumber = 4101i32;\npub const UTRACE_UCNV_LOAD: UTraceFunctionNumber = 4102i32;\npub const UTRACE_UCNV_OPEN: UTraceFunctionNumber = 4096i32;\npub const UTRACE_UCNV_OPEN_ALGORITHMIC: UTraceFunctionNumber = 4098i32;\npub const UTRACE_UCNV_OPEN_PACKAGE: UTraceFunctionNumber = 4097i32;\npub const UTRACE_UCNV_UNLOAD: UTraceFunctionNumber = 4103i32;\npub const UTRACE_UCOL_CLOSE: UTraceFunctionNumber = 8193i32;\npub const UTRACE_UCOL_GETLOCALE: UTraceFunctionNumber = 8196i32;\npub const UTRACE_UCOL_GET_SORTKEY: UTraceFunctionNumber = 8195i32;\npub const UTRACE_UCOL_NEXTSORTKEYPART: UTraceFunctionNumber = 8197i32;\npub const UTRACE_UCOL_OPEN: UTraceFunctionNumber = 8192i32;\npub const UTRACE_UCOL_OPEN_FROM_SHORT_STRING: UTraceFunctionNumber = 8199i32;\npub const UTRACE_UCOL_STRCOLL: UTraceFunctionNumber = 8194i32;\npub const UTRACE_UCOL_STRCOLLITER: UTraceFunctionNumber = 8198i32;\npub const UTRACE_UCOL_STRCOLLUTF8: UTraceFunctionNumber = 8200i32;\npub const UTRACE_UDATA_BUNDLE: UTraceFunctionNumber = 12289i32;\npub const UTRACE_UDATA_DATA_FILE: UTraceFunctionNumber = 12290i32;\npub const UTRACE_UDATA_RESOURCE: UTraceFunctionNumber = 12288i32;\npub const UTRACE_UDATA_RES_FILE: UTraceFunctionNumber = 12291i32;\npub const UTRACE_UDATA_START: UTraceFunctionNumber = 12288i32;\npub const UTRACE_U_CLEANUP: UTraceFunctionNumber = 1i32;\npub const UTRACE_U_INIT: UTraceFunctionNumber = 0i32;\npub const UTRACE_VERBOSE: UTraceLevel = 9i32;\npub const UTRACE_WARNING: UTraceLevel = 3i32;\npub const UTRANS_FORWARD: UTransDirection = 0i32;\npub const UTRANS_REVERSE: UTransDirection = 1i32;\npub const UTSV_EPOCH_OFFSET_VALUE: UTimeScaleValue = 1i32;\npub const UTSV_FROM_MAX_VALUE: UTimeScaleValue = 3i32;\npub const UTSV_FROM_MIN_VALUE: UTimeScaleValue = 2i32;\npub const UTSV_TO_MAX_VALUE: UTimeScaleValue = 5i32;\npub const UTSV_TO_MIN_VALUE: UTimeScaleValue = 4i32;\npub const UTSV_UNITS_VALUE: UTimeScaleValue = 0i32;\npub const UTZFMT_PARSE_OPTION_ALL_STYLES: UTimeZoneFormatParseOption = 1i32;\npub const UTZFMT_PARSE_OPTION_NONE: UTimeZoneFormatParseOption = 0i32;\npub const UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS: UTimeZoneFormatParseOption = 2i32;\npub const UTZFMT_PAT_COUNT: UTimeZoneFormatGMTOffsetPatternType = 6i32;\npub const UTZFMT_PAT_NEGATIVE_H: UTimeZoneFormatGMTOffsetPatternType = 5i32;\npub const UTZFMT_PAT_NEGATIVE_HM: UTimeZoneFormatGMTOffsetPatternType = 2i32;\npub const UTZFMT_PAT_NEGATIVE_HMS: UTimeZoneFormatGMTOffsetPatternType = 3i32;\npub const UTZFMT_PAT_POSITIVE_H: UTimeZoneFormatGMTOffsetPatternType = 4i32;\npub const UTZFMT_PAT_POSITIVE_HM: UTimeZoneFormatGMTOffsetPatternType = 0i32;\npub const UTZFMT_PAT_POSITIVE_HMS: UTimeZoneFormatGMTOffsetPatternType = 1i32;\npub const UTZFMT_STYLE_EXEMPLAR_LOCATION: UTimeZoneFormatStyle = 19i32;\npub const UTZFMT_STYLE_GENERIC_LOCATION: UTimeZoneFormatStyle = 0i32;\npub const UTZFMT_STYLE_GENERIC_LONG: UTimeZoneFormatStyle = 1i32;\npub const UTZFMT_STYLE_GENERIC_SHORT: UTimeZoneFormatStyle = 2i32;\npub const UTZFMT_STYLE_ISO_BASIC_FIXED: UTimeZoneFormatStyle = 9i32;\npub const UTZFMT_STYLE_ISO_BASIC_FULL: UTimeZoneFormatStyle = 11i32;\npub const UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED: UTimeZoneFormatStyle = 10i32;\npub const UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL: UTimeZoneFormatStyle = 12i32;\npub const UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT: UTimeZoneFormatStyle = 8i32;\npub const UTZFMT_STYLE_ISO_BASIC_SHORT: UTimeZoneFormatStyle = 7i32;\npub const UTZFMT_STYLE_ISO_EXTENDED_FIXED: UTimeZoneFormatStyle = 13i32;\npub const UTZFMT_STYLE_ISO_EXTENDED_FULL: UTimeZoneFormatStyle = 15i32;\npub const UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED: UTimeZoneFormatStyle = 14i32;\npub const UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL: UTimeZoneFormatStyle = 16i32;\npub const UTZFMT_STYLE_LOCALIZED_GMT: UTimeZoneFormatStyle = 5i32;\npub const UTZFMT_STYLE_LOCALIZED_GMT_SHORT: UTimeZoneFormatStyle = 6i32;\npub const UTZFMT_STYLE_SPECIFIC_LONG: UTimeZoneFormatStyle = 3i32;\npub const UTZFMT_STYLE_SPECIFIC_SHORT: UTimeZoneFormatStyle = 4i32;\npub const UTZFMT_STYLE_ZONE_ID: UTimeZoneFormatStyle = 17i32;\npub const UTZFMT_STYLE_ZONE_ID_SHORT: UTimeZoneFormatStyle = 18i32;\npub const UTZFMT_TIME_TYPE_DAYLIGHT: UTimeZoneFormatTimeType = 2i32;\npub const UTZFMT_TIME_TYPE_STANDARD: UTimeZoneFormatTimeType = 1i32;\npub const UTZFMT_TIME_TYPE_UNKNOWN: UTimeZoneFormatTimeType = 0i32;\npub const UTZNM_EXEMPLAR_LOCATION: UTimeZoneNameType = 64i32;\npub const UTZNM_LONG_DAYLIGHT: UTimeZoneNameType = 4i32;\npub const UTZNM_LONG_GENERIC: UTimeZoneNameType = 1i32;\npub const UTZNM_LONG_STANDARD: UTimeZoneNameType = 2i32;\npub const UTZNM_SHORT_DAYLIGHT: UTimeZoneNameType = 32i32;\npub const UTZNM_SHORT_GENERIC: UTimeZoneNameType = 8i32;\npub const UTZNM_SHORT_STANDARD: UTimeZoneNameType = 16i32;\npub const UTZNM_UNKNOWN: UTimeZoneNameType = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct UText {\n    pub magic: u32,\n    pub flags: i32,\n    pub providerProperties: i32,\n    pub sizeOfStruct: i32,\n    pub chunkNativeLimit: i64,\n    pub extraSize: i32,\n    pub nativeIndexingLimit: i32,\n    pub chunkNativeStart: i64,\n    pub chunkOffset: i32,\n    pub chunkLength: i32,\n    pub chunkContents: *const u16,\n    pub pFuncs: *const UTextFuncs,\n    pub pExtra: *mut core::ffi::c_void,\n    pub context: *const core::ffi::c_void,\n    pub p: *const core::ffi::c_void,\n    pub q: *const core::ffi::c_void,\n    pub r: *const core::ffi::c_void,\n    pub privP: *mut core::ffi::c_void,\n    pub a: i64,\n    pub b: i32,\n    pub c: i32,\n    pub privA: i64,\n    pub privB: i32,\n    pub privC: i32,\n}\nimpl Default for UText {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type UTextAccess = Option<unsafe extern \"system\" fn(ut: *mut UText, nativeindex: i64, forward: i8) -> i8>;\npub type UTextClone = Option<unsafe extern \"system\" fn(dest: *mut UText, src: *const UText, deep: i8, status: *mut UErrorCode) -> *mut UText>;\npub type UTextClose = Option<unsafe extern \"system\" fn(ut: *mut UText)>;\npub type UTextCopy = Option<unsafe extern \"system\" fn(ut: *mut UText, nativestart: i64, nativelimit: i64, nativedest: i64, r#move: i8, status: *mut UErrorCode)>;\npub type UTextExtract = Option<unsafe extern \"system\" fn(ut: *mut UText, nativestart: i64, nativelimit: i64, dest: *mut u16, destcapacity: i32, status: *mut UErrorCode) -> i32>;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct UTextFuncs {\n    pub tableSize: i32,\n    pub reserved1: i32,\n    pub reserved2: i32,\n    pub reserved3: i32,\n    pub clone: UTextClone,\n    pub nativeLength: UTextNativeLength,\n    pub access: UTextAccess,\n    pub extract: UTextExtract,\n    pub replace: UTextReplace,\n    pub copy: UTextCopy,\n    pub mapOffsetToNative: UTextMapOffsetToNative,\n    pub mapNativeIndexToUTF16: UTextMapNativeIndexToUTF16,\n    pub close: UTextClose,\n    pub spare1: UTextClose,\n    pub spare2: UTextClose,\n    pub spare3: UTextClose,\n}\npub type UTextMapNativeIndexToUTF16 = Option<unsafe extern \"system\" fn(ut: *const UText, nativeindex: i64) -> i32>;\npub type UTextMapOffsetToNative = Option<unsafe extern \"system\" fn(ut: *const UText) -> i64>;\npub type UTextNativeLength = Option<unsafe extern \"system\" fn(ut: *mut UText) -> i64>;\npub type UTextReplace = Option<unsafe extern \"system\" fn(ut: *mut UText, nativestart: i64, nativelimit: i64, replacementtext: *const u16, replacmentlength: i32, status: *mut UErrorCode) -> i32>;\npub type UTimeScaleValue = i32;\npub type UTimeZoneFormatGMTOffsetPatternType = i32;\npub type UTimeZoneFormatParseOption = i32;\npub type UTimeZoneFormatStyle = i32;\npub type UTimeZoneFormatTimeType = i32;\npub type UTimeZoneNameType = i32;\npub type UTimeZoneTransitionType = i32;\npub type UTraceData = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, fnnumber: i32, level: i32, fmt: windows_sys::core::PCSTR, args: *mut i8)>;\npub type UTraceEntry = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, fnnumber: i32)>;\npub type UTraceExit = Option<unsafe extern \"system\" fn(context: *const core::ffi::c_void, fnnumber: i32, fmt: windows_sys::core::PCSTR, args: *mut i8)>;\npub type UTraceFunctionNumber = i32;\npub type UTraceLevel = i32;\npub type UTransDirection = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct UTransPosition {\n    pub contextStart: i32,\n    pub contextLimit: i32,\n    pub start: i32,\n    pub limit: i32,\n}\npub type UVerticalOrientation = i32;\npub type UWordBreak = i32;\npub type UWordBreakValues = i32;\npub const U_ALPHAINDEX_INFLOW: UAlphabeticIndexLabelType = 2i32;\npub const U_ALPHAINDEX_NORMAL: UAlphabeticIndexLabelType = 0i32;\npub const U_ALPHAINDEX_OVERFLOW: UAlphabeticIndexLabelType = 3i32;\npub const U_ALPHAINDEX_UNDERFLOW: UAlphabeticIndexLabelType = 1i32;\npub const U_AMBIGUOUS_ALIAS_WARNING: UErrorCode = -122i32;\npub const U_ARABIC_NUMBER: UCharDirection = 5i32;\npub const U_ARGUMENT_TYPE_MISMATCH: UErrorCode = 65804i32;\npub const U_ASCII_FAMILY: u32 = 0u32;\npub const U_BAD_VARIABLE_DEFINITION: UErrorCode = 65536i32;\npub const U_BLOCK_SEPARATOR: UCharDirection = 7i32;\npub const U_BOUNDARY_NEUTRAL: UCharDirection = 18i32;\npub const U_BPT_CLOSE: UBidiPairedBracketType = 2i32;\npub const U_BPT_NONE: UBidiPairedBracketType = 0i32;\npub const U_BPT_OPEN: UBidiPairedBracketType = 1i32;\npub const U_BRK_ASSIGN_ERROR: UErrorCode = 66053i32;\npub const U_BRK_ERROR_START: UErrorCode = 66048i32;\npub const U_BRK_HEX_DIGITS_EXPECTED: UErrorCode = 66049i32;\npub const U_BRK_INIT_ERROR: UErrorCode = 66058i32;\npub const U_BRK_INTERNAL_ERROR: UErrorCode = 66048i32;\npub const U_BRK_MALFORMED_RULE_TAG: UErrorCode = 66061i32;\npub const U_BRK_MISMATCHED_PAREN: UErrorCode = 66055i32;\npub const U_BRK_NEW_LINE_IN_QUOTED_STRING: UErrorCode = 66056i32;\npub const U_BRK_RULE_EMPTY_SET: UErrorCode = 66059i32;\npub const U_BRK_RULE_SYNTAX: UErrorCode = 66051i32;\npub const U_BRK_SEMICOLON_EXPECTED: UErrorCode = 66050i32;\npub const U_BRK_UNCLOSED_SET: UErrorCode = 66052i32;\npub const U_BRK_UNDEFINED_VARIABLE: UErrorCode = 66057i32;\npub const U_BRK_UNRECOGNIZED_OPTION: UErrorCode = 66060i32;\npub const U_BRK_VARIABLE_REDFINITION: UErrorCode = 66054i32;\npub const U_BUFFER_OVERFLOW_ERROR: UErrorCode = 15i32;\npub const U_CE_NOT_FOUND_ERROR: UErrorCode = 21i32;\npub const U_CHAR16_IS_TYPEDEF: u32 = 1u32;\npub const U_CHARSET_FAMILY: u32 = 1u32;\npub const U_CHARSET_IS_UTF8: u32 = 1u32;\npub const U_CHAR_CATEGORY_COUNT: UCharCategory = 30i32;\npub const U_CHAR_NAME_ALIAS: UCharNameChoice = 3i32;\npub const U_CHECK_DYLOAD: u32 = 1u32;\npub const U_COLLATOR_VERSION_MISMATCH: UErrorCode = 28i32;\npub const U_COMBINED_IMPLEMENTATION: u32 = 1u32;\npub const U_COMBINING_SPACING_MARK: UCharCategory = 8i32;\npub const U_COMMON_NUMBER_SEPARATOR: UCharDirection = 6i32;\npub const U_COMPARE_CODE_POINT_ORDER: u32 = 32768u32;\npub const U_COMPARE_IGNORE_CASE: u32 = 65536u32;\npub const U_CONNECTOR_PUNCTUATION: UCharCategory = 22i32;\npub const U_CONTROL_CHAR: UCharCategory = 15i32;\npub const U_COPYRIGHT_STRING_LENGTH: u32 = 128u32;\npub const U_CPLUSPLUS_VERSION: u32 = 0u32;\npub const U_CURRENCY_SYMBOL: UCharCategory = 25i32;\npub const U_DASH_PUNCTUATION: UCharCategory = 19i32;\npub const U_DEBUG: u32 = 1u32;\npub const U_DECIMAL_DIGIT_NUMBER: UCharCategory = 9i32;\npub const U_DECIMAL_NUMBER_SYNTAX_ERROR: UErrorCode = 65808i32;\npub const U_DEFAULT_KEYWORD_MISSING: UErrorCode = 65807i32;\npub const U_DEFAULT_SHOW_DRAFT: u32 = 0u32;\npub const U_DEFINE_FALSE_AND_TRUE: u32 = 1u32;\npub const U_DIFFERENT_UCA_VERSION: UErrorCode = -121i32;\npub const U_DIR_NON_SPACING_MARK: UCharDirection = 17i32;\npub const U_DISABLE_RENAMING: u32 = 1u32;\npub const U_DT_CANONICAL: UDecompositionType = 1i32;\npub const U_DT_CIRCLE: UDecompositionType = 3i32;\npub const U_DT_COMPAT: UDecompositionType = 2i32;\npub const U_DT_FINAL: UDecompositionType = 4i32;\npub const U_DT_FONT: UDecompositionType = 5i32;\npub const U_DT_FRACTION: UDecompositionType = 6i32;\npub const U_DT_INITIAL: UDecompositionType = 7i32;\npub const U_DT_ISOLATED: UDecompositionType = 8i32;\npub const U_DT_MEDIAL: UDecompositionType = 9i32;\npub const U_DT_NARROW: UDecompositionType = 10i32;\npub const U_DT_NOBREAK: UDecompositionType = 11i32;\npub const U_DT_NONE: UDecompositionType = 0i32;\npub const U_DT_SMALL: UDecompositionType = 12i32;\npub const U_DT_SQUARE: UDecompositionType = 13i32;\npub const U_DT_SUB: UDecompositionType = 14i32;\npub const U_DT_SUPER: UDecompositionType = 15i32;\npub const U_DT_VERTICAL: UDecompositionType = 16i32;\npub const U_DT_WIDE: UDecompositionType = 17i32;\npub const U_DUPLICATE_KEYWORD: UErrorCode = 65805i32;\npub const U_EA_AMBIGUOUS: UEastAsianWidth = 1i32;\npub const U_EA_FULLWIDTH: UEastAsianWidth = 3i32;\npub const U_EA_HALFWIDTH: UEastAsianWidth = 2i32;\npub const U_EA_NARROW: UEastAsianWidth = 4i32;\npub const U_EA_NEUTRAL: UEastAsianWidth = 0i32;\npub const U_EA_WIDE: UEastAsianWidth = 5i32;\npub const U_EBCDIC_FAMILY: u32 = 1u32;\npub const U_EDITS_NO_RESET: u32 = 8192u32;\npub const U_ENABLE_DYLOAD: u32 = 1u32;\npub const U_ENABLE_TRACING: u32 = 0u32;\npub const U_ENCLOSING_MARK: UCharCategory = 7i32;\npub const U_END_PUNCTUATION: UCharCategory = 21i32;\npub const U_ENUM_OUT_OF_SYNC_ERROR: UErrorCode = 25i32;\npub const U_ERROR_WARNING_START: UErrorCode = -128i32;\npub const U_EUROPEAN_NUMBER: UCharDirection = 2i32;\npub const U_EUROPEAN_NUMBER_SEPARATOR: UCharDirection = 3i32;\npub const U_EUROPEAN_NUMBER_TERMINATOR: UCharDirection = 4i32;\npub const U_EXTENDED_CHAR_NAME: UCharNameChoice = 2i32;\npub const U_FILE_ACCESS_ERROR: UErrorCode = 4i32;\npub const U_FINAL_PUNCTUATION: UCharCategory = 29i32;\npub const U_FIRST_STRONG_ISOLATE: UCharDirection = 19i32;\npub const U_FMT_PARSE_ERROR_START: UErrorCode = 65792i32;\npub const U_FOLD_CASE_DEFAULT: u32 = 0u32;\npub const U_FOLD_CASE_EXCLUDE_SPECIAL_I: u32 = 1u32;\npub const U_FORMAT_CHAR: UCharCategory = 16i32;\npub const U_FORMAT_INEXACT_ERROR: UErrorCode = 65809i32;\npub const U_GCB_CONTROL: UGraphemeClusterBreak = 1i32;\npub const U_GCB_CR: UGraphemeClusterBreak = 2i32;\npub const U_GCB_EXTEND: UGraphemeClusterBreak = 3i32;\npub const U_GCB_E_BASE: UGraphemeClusterBreak = 13i32;\npub const U_GCB_E_BASE_GAZ: UGraphemeClusterBreak = 14i32;\npub const U_GCB_E_MODIFIER: UGraphemeClusterBreak = 15i32;\npub const U_GCB_GLUE_AFTER_ZWJ: UGraphemeClusterBreak = 16i32;\npub const U_GCB_L: UGraphemeClusterBreak = 4i32;\npub const U_GCB_LF: UGraphemeClusterBreak = 5i32;\npub const U_GCB_LV: UGraphemeClusterBreak = 6i32;\npub const U_GCB_LVT: UGraphemeClusterBreak = 7i32;\npub const U_GCB_OTHER: UGraphemeClusterBreak = 0i32;\npub const U_GCB_PREPEND: UGraphemeClusterBreak = 11i32;\npub const U_GCB_REGIONAL_INDICATOR: UGraphemeClusterBreak = 12i32;\npub const U_GCB_SPACING_MARK: UGraphemeClusterBreak = 10i32;\npub const U_GCB_T: UGraphemeClusterBreak = 8i32;\npub const U_GCB_V: UGraphemeClusterBreak = 9i32;\npub const U_GCB_ZWJ: UGraphemeClusterBreak = 17i32;\npub const U_GCC_MAJOR_MINOR: u32 = 0u32;\npub const U_GENERAL_OTHER_TYPES: UCharCategory = 0i32;\npub const U_HAVE_CHAR16_T: u32 = 1u32;\npub const U_HAVE_DEBUG_LOCATION_NEW: u32 = 1u32;\npub const U_HAVE_INTTYPES_H: u32 = 1u32;\npub const U_HAVE_LIB_SUFFIX: u32 = 1u32;\npub const U_HAVE_PLACEMENT_NEW: u32 = 0u32;\npub const U_HAVE_RBNF: u32 = 0u32;\npub const U_HAVE_RVALUE_REFERENCES: u32 = 1u32;\npub const U_HAVE_STDINT_H: u32 = 1u32;\npub const U_HAVE_STD_STRING: u32 = 0u32;\npub const U_HAVE_WCHAR_H: u32 = 0u32;\npub const U_HAVE_WCSCPY: u32 = 0u32;\npub const U_HIDE_DEPRECATED_API: u32 = 1u32;\npub const U_HIDE_DRAFT_API: u32 = 1u32;\npub const U_HIDE_INTERNAL_API: u32 = 1u32;\npub const U_HIDE_OBSOLETE_API: u32 = 1u32;\npub const U_HIDE_OBSOLETE_UTF_OLD_H: u32 = 0u32;\npub const U_HST_LEADING_JAMO: UHangulSyllableType = 1i32;\npub const U_HST_LVT_SYLLABLE: UHangulSyllableType = 5i32;\npub const U_HST_LV_SYLLABLE: UHangulSyllableType = 4i32;\npub const U_HST_NOT_APPLICABLE: UHangulSyllableType = 0i32;\npub const U_HST_TRAILING_JAMO: UHangulSyllableType = 3i32;\npub const U_HST_VOWEL_JAMO: UHangulSyllableType = 2i32;\npub const U_ICUDATA_TYPE_LETTER: windows_sys::core::PCSTR = windows_sys::core::s!(\"e\");\npub const U_ICU_DATA_KEY: windows_sys::core::PCSTR = windows_sys::core::s!(\"DataVersion\");\npub const U_ICU_VERSION_BUNDLE: windows_sys::core::PCSTR = windows_sys::core::s!(\"icuver\");\npub const U_IDNA_ACE_PREFIX_ERROR: UErrorCode = 66564i32;\npub const U_IDNA_CHECK_BIDI_ERROR: UErrorCode = 66562i32;\npub const U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR: UErrorCode = 66568i32;\npub const U_IDNA_ERROR_START: UErrorCode = 66560i32;\npub const U_IDNA_LABEL_TOO_LONG_ERROR: UErrorCode = 66566i32;\npub const U_IDNA_PROHIBITED_ERROR: UErrorCode = 66560i32;\npub const U_IDNA_STD3_ASCII_RULES_ERROR: UErrorCode = 66563i32;\npub const U_IDNA_UNASSIGNED_ERROR: UErrorCode = 66561i32;\npub const U_IDNA_VERIFICATION_ERROR: UErrorCode = 66565i32;\npub const U_IDNA_ZERO_LENGTH_LABEL_ERROR: UErrorCode = 66567i32;\npub const U_ILLEGAL_ARGUMENT_ERROR: UErrorCode = 1i32;\npub const U_ILLEGAL_CHARACTER: UErrorCode = 65567i32;\npub const U_ILLEGAL_CHAR_FOUND: UErrorCode = 12i32;\npub const U_ILLEGAL_CHAR_IN_SEGMENT: UErrorCode = 65564i32;\npub const U_ILLEGAL_ESCAPE_SEQUENCE: UErrorCode = 18i32;\npub const U_ILLEGAL_PAD_POSITION: UErrorCode = 65800i32;\npub const U_INDEX_OUTOFBOUNDS_ERROR: UErrorCode = 8i32;\npub const U_INITIAL_PUNCTUATION: UCharCategory = 28i32;\npub const U_INPC_BOTTOM: UIndicPositionalCategory = 1i32;\npub const U_INPC_BOTTOM_AND_LEFT: UIndicPositionalCategory = 2i32;\npub const U_INPC_BOTTOM_AND_RIGHT: UIndicPositionalCategory = 3i32;\npub const U_INPC_LEFT: UIndicPositionalCategory = 4i32;\npub const U_INPC_LEFT_AND_RIGHT: UIndicPositionalCategory = 5i32;\npub const U_INPC_NA: UIndicPositionalCategory = 0i32;\npub const U_INPC_OVERSTRUCK: UIndicPositionalCategory = 6i32;\npub const U_INPC_RIGHT: UIndicPositionalCategory = 7i32;\npub const U_INPC_TOP: UIndicPositionalCategory = 8i32;\npub const U_INPC_TOP_AND_BOTTOM: UIndicPositionalCategory = 9i32;\npub const U_INPC_TOP_AND_BOTTOM_AND_LEFT: UIndicPositionalCategory = 15i32;\npub const U_INPC_TOP_AND_BOTTOM_AND_RIGHT: UIndicPositionalCategory = 10i32;\npub const U_INPC_TOP_AND_LEFT: UIndicPositionalCategory = 11i32;\npub const U_INPC_TOP_AND_LEFT_AND_RIGHT: UIndicPositionalCategory = 12i32;\npub const U_INPC_TOP_AND_RIGHT: UIndicPositionalCategory = 13i32;\npub const U_INPC_VISUAL_ORDER_LEFT: UIndicPositionalCategory = 14i32;\npub const U_INSC_AVAGRAHA: UIndicSyllabicCategory = 1i32;\npub const U_INSC_BINDU: UIndicSyllabicCategory = 2i32;\npub const U_INSC_BRAHMI_JOINING_NUMBER: UIndicSyllabicCategory = 3i32;\npub const U_INSC_CANTILLATION_MARK: UIndicSyllabicCategory = 4i32;\npub const U_INSC_CONSONANT: UIndicSyllabicCategory = 5i32;\npub const U_INSC_CONSONANT_DEAD: UIndicSyllabicCategory = 6i32;\npub const U_INSC_CONSONANT_FINAL: UIndicSyllabicCategory = 7i32;\npub const U_INSC_CONSONANT_HEAD_LETTER: UIndicSyllabicCategory = 8i32;\npub const U_INSC_CONSONANT_INITIAL_POSTFIXED: UIndicSyllabicCategory = 9i32;\npub const U_INSC_CONSONANT_KILLER: UIndicSyllabicCategory = 10i32;\npub const U_INSC_CONSONANT_MEDIAL: UIndicSyllabicCategory = 11i32;\npub const U_INSC_CONSONANT_PLACEHOLDER: UIndicSyllabicCategory = 12i32;\npub const U_INSC_CONSONANT_PRECEDING_REPHA: UIndicSyllabicCategory = 13i32;\npub const U_INSC_CONSONANT_PREFIXED: UIndicSyllabicCategory = 14i32;\npub const U_INSC_CONSONANT_SUBJOINED: UIndicSyllabicCategory = 15i32;\npub const U_INSC_CONSONANT_SUCCEEDING_REPHA: UIndicSyllabicCategory = 16i32;\npub const U_INSC_CONSONANT_WITH_STACKER: UIndicSyllabicCategory = 17i32;\npub const U_INSC_GEMINATION_MARK: UIndicSyllabicCategory = 18i32;\npub const U_INSC_INVISIBLE_STACKER: UIndicSyllabicCategory = 19i32;\npub const U_INSC_JOINER: UIndicSyllabicCategory = 20i32;\npub const U_INSC_MODIFYING_LETTER: UIndicSyllabicCategory = 21i32;\npub const U_INSC_NON_JOINER: UIndicSyllabicCategory = 22i32;\npub const U_INSC_NUKTA: UIndicSyllabicCategory = 23i32;\npub const U_INSC_NUMBER: UIndicSyllabicCategory = 24i32;\npub const U_INSC_NUMBER_JOINER: UIndicSyllabicCategory = 25i32;\npub const U_INSC_OTHER: UIndicSyllabicCategory = 0i32;\npub const U_INSC_PURE_KILLER: UIndicSyllabicCategory = 26i32;\npub const U_INSC_REGISTER_SHIFTER: UIndicSyllabicCategory = 27i32;\npub const U_INSC_SYLLABLE_MODIFIER: UIndicSyllabicCategory = 28i32;\npub const U_INSC_TONE_LETTER: UIndicSyllabicCategory = 29i32;\npub const U_INSC_TONE_MARK: UIndicSyllabicCategory = 30i32;\npub const U_INSC_VIRAMA: UIndicSyllabicCategory = 31i32;\npub const U_INSC_VISARGA: UIndicSyllabicCategory = 32i32;\npub const U_INSC_VOWEL: UIndicSyllabicCategory = 33i32;\npub const U_INSC_VOWEL_DEPENDENT: UIndicSyllabicCategory = 34i32;\npub const U_INSC_VOWEL_INDEPENDENT: UIndicSyllabicCategory = 35i32;\npub const U_INTERNAL_PROGRAM_ERROR: UErrorCode = 5i32;\npub const U_INTERNAL_TRANSLITERATOR_ERROR: UErrorCode = 65568i32;\npub const U_INVALID_CHAR_FOUND: UErrorCode = 10i32;\npub const U_INVALID_FORMAT_ERROR: UErrorCode = 3i32;\npub const U_INVALID_FUNCTION: UErrorCode = 65570i32;\npub const U_INVALID_ID: UErrorCode = 65569i32;\npub const U_INVALID_PROPERTY_PATTERN: UErrorCode = 65561i32;\npub const U_INVALID_RBT_SYNTAX: UErrorCode = 65560i32;\npub const U_INVALID_STATE_ERROR: UErrorCode = 27i32;\npub const U_INVALID_TABLE_FILE: UErrorCode = 14i32;\npub const U_INVALID_TABLE_FORMAT: UErrorCode = 13i32;\npub const U_INVARIANT_CONVERSION_ERROR: UErrorCode = 26i32;\npub const U_IOSTREAM_SOURCE: u32 = 199711u32;\npub const U_IS_BIG_ENDIAN: u32 = 0u32;\npub const U_JG_AFRICAN_FEH: UJoiningGroup = 86i32;\npub const U_JG_AFRICAN_NOON: UJoiningGroup = 87i32;\npub const U_JG_AFRICAN_QAF: UJoiningGroup = 88i32;\npub const U_JG_AIN: UJoiningGroup = 1i32;\npub const U_JG_ALAPH: UJoiningGroup = 2i32;\npub const U_JG_ALEF: UJoiningGroup = 3i32;\npub const U_JG_BEH: UJoiningGroup = 4i32;\npub const U_JG_BETH: UJoiningGroup = 5i32;\npub const U_JG_BURUSHASKI_YEH_BARREE: UJoiningGroup = 54i32;\npub const U_JG_DAL: UJoiningGroup = 6i32;\npub const U_JG_DALATH_RISH: UJoiningGroup = 7i32;\npub const U_JG_E: UJoiningGroup = 8i32;\npub const U_JG_FARSI_YEH: UJoiningGroup = 55i32;\npub const U_JG_FE: UJoiningGroup = 51i32;\npub const U_JG_FEH: UJoiningGroup = 9i32;\npub const U_JG_FINAL_SEMKATH: UJoiningGroup = 10i32;\npub const U_JG_GAF: UJoiningGroup = 11i32;\npub const U_JG_GAMAL: UJoiningGroup = 12i32;\npub const U_JG_HAH: UJoiningGroup = 13i32;\npub const U_JG_HAMZA_ON_HEH_GOAL: UJoiningGroup = 14i32;\npub const U_JG_HANIFI_ROHINGYA_KINNA_YA: UJoiningGroup = 100i32;\npub const U_JG_HANIFI_ROHINGYA_PA: UJoiningGroup = 101i32;\npub const U_JG_HE: UJoiningGroup = 15i32;\npub const U_JG_HEH: UJoiningGroup = 16i32;\npub const U_JG_HEH_GOAL: UJoiningGroup = 17i32;\npub const U_JG_HETH: UJoiningGroup = 18i32;\npub const U_JG_KAF: UJoiningGroup = 19i32;\npub const U_JG_KAPH: UJoiningGroup = 20i32;\npub const U_JG_KHAPH: UJoiningGroup = 52i32;\npub const U_JG_KNOTTED_HEH: UJoiningGroup = 21i32;\npub const U_JG_LAM: UJoiningGroup = 22i32;\npub const U_JG_LAMADH: UJoiningGroup = 23i32;\npub const U_JG_MALAYALAM_BHA: UJoiningGroup = 89i32;\npub const U_JG_MALAYALAM_JA: UJoiningGroup = 90i32;\npub const U_JG_MALAYALAM_LLA: UJoiningGroup = 91i32;\npub const U_JG_MALAYALAM_LLLA: UJoiningGroup = 92i32;\npub const U_JG_MALAYALAM_NGA: UJoiningGroup = 93i32;\npub const U_JG_MALAYALAM_NNA: UJoiningGroup = 94i32;\npub const U_JG_MALAYALAM_NNNA: UJoiningGroup = 95i32;\npub const U_JG_MALAYALAM_NYA: UJoiningGroup = 96i32;\npub const U_JG_MALAYALAM_RA: UJoiningGroup = 97i32;\npub const U_JG_MALAYALAM_SSA: UJoiningGroup = 98i32;\npub const U_JG_MALAYALAM_TTA: UJoiningGroup = 99i32;\npub const U_JG_MANICHAEAN_ALEPH: UJoiningGroup = 58i32;\npub const U_JG_MANICHAEAN_AYIN: UJoiningGroup = 59i32;\npub const U_JG_MANICHAEAN_BETH: UJoiningGroup = 60i32;\npub const U_JG_MANICHAEAN_DALETH: UJoiningGroup = 61i32;\npub const U_JG_MANICHAEAN_DHAMEDH: UJoiningGroup = 62i32;\npub const U_JG_MANICHAEAN_FIVE: UJoiningGroup = 63i32;\npub const U_JG_MANICHAEAN_GIMEL: UJoiningGroup = 64i32;\npub const U_JG_MANICHAEAN_HETH: UJoiningGroup = 65i32;\npub const U_JG_MANICHAEAN_HUNDRED: UJoiningGroup = 66i32;\npub const U_JG_MANICHAEAN_KAPH: UJoiningGroup = 67i32;\npub const U_JG_MANICHAEAN_LAMEDH: UJoiningGroup = 68i32;\npub const U_JG_MANICHAEAN_MEM: UJoiningGroup = 69i32;\npub const U_JG_MANICHAEAN_NUN: UJoiningGroup = 70i32;\npub const U_JG_MANICHAEAN_ONE: UJoiningGroup = 71i32;\npub const U_JG_MANICHAEAN_PE: UJoiningGroup = 72i32;\npub const U_JG_MANICHAEAN_QOPH: UJoiningGroup = 73i32;\npub const U_JG_MANICHAEAN_RESH: UJoiningGroup = 74i32;\npub const U_JG_MANICHAEAN_SADHE: UJoiningGroup = 75i32;\npub const U_JG_MANICHAEAN_SAMEKH: UJoiningGroup = 76i32;\npub const U_JG_MANICHAEAN_TAW: UJoiningGroup = 77i32;\npub const U_JG_MANICHAEAN_TEN: UJoiningGroup = 78i32;\npub const U_JG_MANICHAEAN_TETH: UJoiningGroup = 79i32;\npub const U_JG_MANICHAEAN_THAMEDH: UJoiningGroup = 80i32;\npub const U_JG_MANICHAEAN_TWENTY: UJoiningGroup = 81i32;\npub const U_JG_MANICHAEAN_WAW: UJoiningGroup = 82i32;\npub const U_JG_MANICHAEAN_YODH: UJoiningGroup = 83i32;\npub const U_JG_MANICHAEAN_ZAYIN: UJoiningGroup = 84i32;\npub const U_JG_MEEM: UJoiningGroup = 24i32;\npub const U_JG_MIM: UJoiningGroup = 25i32;\npub const U_JG_NOON: UJoiningGroup = 26i32;\npub const U_JG_NO_JOINING_GROUP: UJoiningGroup = 0i32;\npub const U_JG_NUN: UJoiningGroup = 27i32;\npub const U_JG_NYA: UJoiningGroup = 56i32;\npub const U_JG_PE: UJoiningGroup = 28i32;\npub const U_JG_QAF: UJoiningGroup = 29i32;\npub const U_JG_QAPH: UJoiningGroup = 30i32;\npub const U_JG_REH: UJoiningGroup = 31i32;\npub const U_JG_REVERSED_PE: UJoiningGroup = 32i32;\npub const U_JG_ROHINGYA_YEH: UJoiningGroup = 57i32;\npub const U_JG_SAD: UJoiningGroup = 33i32;\npub const U_JG_SADHE: UJoiningGroup = 34i32;\npub const U_JG_SEEN: UJoiningGroup = 35i32;\npub const U_JG_SEMKATH: UJoiningGroup = 36i32;\npub const U_JG_SHIN: UJoiningGroup = 37i32;\npub const U_JG_STRAIGHT_WAW: UJoiningGroup = 85i32;\npub const U_JG_SWASH_KAF: UJoiningGroup = 38i32;\npub const U_JG_SYRIAC_WAW: UJoiningGroup = 39i32;\npub const U_JG_TAH: UJoiningGroup = 40i32;\npub const U_JG_TAW: UJoiningGroup = 41i32;\npub const U_JG_TEH_MARBUTA: UJoiningGroup = 42i32;\npub const U_JG_TEH_MARBUTA_GOAL: UJoiningGroup = 14i32;\npub const U_JG_TETH: UJoiningGroup = 43i32;\npub const U_JG_WAW: UJoiningGroup = 44i32;\npub const U_JG_YEH: UJoiningGroup = 45i32;\npub const U_JG_YEH_BARREE: UJoiningGroup = 46i32;\npub const U_JG_YEH_WITH_TAIL: UJoiningGroup = 47i32;\npub const U_JG_YUDH: UJoiningGroup = 48i32;\npub const U_JG_YUDH_HE: UJoiningGroup = 49i32;\npub const U_JG_ZAIN: UJoiningGroup = 50i32;\npub const U_JG_ZHAIN: UJoiningGroup = 53i32;\npub const U_JT_DUAL_JOINING: UJoiningType = 2i32;\npub const U_JT_JOIN_CAUSING: UJoiningType = 1i32;\npub const U_JT_LEFT_JOINING: UJoiningType = 3i32;\npub const U_JT_NON_JOINING: UJoiningType = 0i32;\npub const U_JT_RIGHT_JOINING: UJoiningType = 4i32;\npub const U_JT_TRANSPARENT: UJoiningType = 5i32;\npub const U_LB_ALPHABETIC: ULineBreak = 2i32;\npub const U_LB_AMBIGUOUS: ULineBreak = 1i32;\npub const U_LB_BREAK_AFTER: ULineBreak = 4i32;\npub const U_LB_BREAK_BEFORE: ULineBreak = 5i32;\npub const U_LB_BREAK_BOTH: ULineBreak = 3i32;\npub const U_LB_BREAK_SYMBOLS: ULineBreak = 27i32;\npub const U_LB_CARRIAGE_RETURN: ULineBreak = 10i32;\npub const U_LB_CLOSE_PARENTHESIS: ULineBreak = 36i32;\npub const U_LB_CLOSE_PUNCTUATION: ULineBreak = 8i32;\npub const U_LB_COMBINING_MARK: ULineBreak = 9i32;\npub const U_LB_COMPLEX_CONTEXT: ULineBreak = 24i32;\npub const U_LB_CONDITIONAL_JAPANESE_STARTER: ULineBreak = 37i32;\npub const U_LB_CONTINGENT_BREAK: ULineBreak = 7i32;\npub const U_LB_EXCLAMATION: ULineBreak = 11i32;\npub const U_LB_E_BASE: ULineBreak = 40i32;\npub const U_LB_E_MODIFIER: ULineBreak = 41i32;\npub const U_LB_GLUE: ULineBreak = 12i32;\npub const U_LB_H2: ULineBreak = 31i32;\npub const U_LB_H3: ULineBreak = 32i32;\npub const U_LB_HEBREW_LETTER: ULineBreak = 38i32;\npub const U_LB_HYPHEN: ULineBreak = 13i32;\npub const U_LB_IDEOGRAPHIC: ULineBreak = 14i32;\npub const U_LB_INFIX_NUMERIC: ULineBreak = 16i32;\npub const U_LB_INSEPARABLE: ULineBreak = 15i32;\npub const U_LB_INSEPERABLE: ULineBreak = 15i32;\npub const U_LB_JL: ULineBreak = 33i32;\npub const U_LB_JT: ULineBreak = 34i32;\npub const U_LB_JV: ULineBreak = 35i32;\npub const U_LB_LINE_FEED: ULineBreak = 17i32;\npub const U_LB_MANDATORY_BREAK: ULineBreak = 6i32;\npub const U_LB_NEXT_LINE: ULineBreak = 29i32;\npub const U_LB_NONSTARTER: ULineBreak = 18i32;\npub const U_LB_NUMERIC: ULineBreak = 19i32;\npub const U_LB_OPEN_PUNCTUATION: ULineBreak = 20i32;\npub const U_LB_POSTFIX_NUMERIC: ULineBreak = 21i32;\npub const U_LB_PREFIX_NUMERIC: ULineBreak = 22i32;\npub const U_LB_QUOTATION: ULineBreak = 23i32;\npub const U_LB_REGIONAL_INDICATOR: ULineBreak = 39i32;\npub const U_LB_SPACE: ULineBreak = 26i32;\npub const U_LB_SURROGATE: ULineBreak = 25i32;\npub const U_LB_UNKNOWN: ULineBreak = 0i32;\npub const U_LB_WORD_JOINER: ULineBreak = 30i32;\npub const U_LB_ZWJ: ULineBreak = 42i32;\npub const U_LB_ZWSPACE: ULineBreak = 28i32;\npub const U_LEFT_TO_RIGHT: UCharDirection = 0i32;\npub const U_LEFT_TO_RIGHT_EMBEDDING: UCharDirection = 11i32;\npub const U_LEFT_TO_RIGHT_ISOLATE: UCharDirection = 20i32;\npub const U_LEFT_TO_RIGHT_OVERRIDE: UCharDirection = 12i32;\npub const U_LETTER_NUMBER: UCharCategory = 10i32;\npub const U_LIB_SUFFIX_C_NAME_STRING: windows_sys::core::PCSTR = windows_sys::core::s!(\"\");\npub const U_LINE_SEPARATOR: UCharCategory = 13i32;\npub const U_LONG_PROPERTY_NAME: UPropertyNameChoice = 1i32;\npub const U_LOWERCASE_LETTER: UCharCategory = 2i32;\npub const U_MALFORMED_EXPONENTIAL_PATTERN: UErrorCode = 65795i32;\npub const U_MALFORMED_PRAGMA: UErrorCode = 65562i32;\npub const U_MALFORMED_RULE: UErrorCode = 65537i32;\npub const U_MALFORMED_SET: UErrorCode = 65538i32;\npub const U_MALFORMED_SYMBOL_REFERENCE: UErrorCode = 65539i32;\npub const U_MALFORMED_UNICODE_ESCAPE: UErrorCode = 65540i32;\npub const U_MALFORMED_VARIABLE_DEFINITION: UErrorCode = 65541i32;\npub const U_MALFORMED_VARIABLE_REFERENCE: UErrorCode = 65542i32;\npub const U_MATH_SYMBOL: UCharCategory = 24i32;\npub const U_MAX_VERSION_LENGTH: u32 = 4u32;\npub const U_MAX_VERSION_STRING_LENGTH: u32 = 20u32;\npub const U_MEMORY_ALLOCATION_ERROR: UErrorCode = 7i32;\npub const U_MESSAGE_PARSE_ERROR: UErrorCode = 6i32;\npub const U_MILLIS_PER_DAY: u32 = 86400000u32;\npub const U_MILLIS_PER_HOUR: u32 = 3600000u32;\npub const U_MILLIS_PER_MINUTE: u32 = 60000u32;\npub const U_MILLIS_PER_SECOND: u32 = 1000u32;\npub const U_MISMATCHED_SEGMENT_DELIMITERS: UErrorCode = 65543i32;\npub const U_MISPLACED_ANCHOR_START: UErrorCode = 65544i32;\npub const U_MISPLACED_COMPOUND_FILTER: UErrorCode = 65558i32;\npub const U_MISPLACED_CURSOR_OFFSET: UErrorCode = 65545i32;\npub const U_MISPLACED_QUANTIFIER: UErrorCode = 65546i32;\npub const U_MISSING_OPERATOR: UErrorCode = 65547i32;\npub const U_MISSING_RESOURCE_ERROR: UErrorCode = 2i32;\npub const U_MISSING_SEGMENT_CLOSE: UErrorCode = 65548i32;\npub const U_MODIFIER_LETTER: UCharCategory = 4i32;\npub const U_MODIFIER_SYMBOL: UCharCategory = 26i32;\npub const U_MULTIPLE_ANTE_CONTEXTS: UErrorCode = 65549i32;\npub const U_MULTIPLE_COMPOUND_FILTERS: UErrorCode = 65559i32;\npub const U_MULTIPLE_CURSORS: UErrorCode = 65550i32;\npub const U_MULTIPLE_DECIMAL_SEPARATORS: UErrorCode = 65793i32;\npub const U_MULTIPLE_DECIMAL_SEPERATORS: UErrorCode = 65793i32;\npub const U_MULTIPLE_EXPONENTIAL_SYMBOLS: UErrorCode = 65794i32;\npub const U_MULTIPLE_PAD_SPECIFIERS: UErrorCode = 65798i32;\npub const U_MULTIPLE_PERCENT_SYMBOLS: UErrorCode = 65796i32;\npub const U_MULTIPLE_PERMILL_SYMBOLS: UErrorCode = 65797i32;\npub const U_MULTIPLE_POST_CONTEXTS: UErrorCode = 65551i32;\npub const U_NON_SPACING_MARK: UCharCategory = 6i32;\npub const U_NO_DEFAULT_INCLUDE_UTF_HEADERS: u32 = 1u32;\npub const U_NO_SPACE_AVAILABLE: UErrorCode = 20i32;\npub const U_NO_WRITE_PERMISSION: UErrorCode = 30i32;\npub const U_NT_DECIMAL: UNumericType = 1i32;\npub const U_NT_DIGIT: UNumericType = 2i32;\npub const U_NT_NONE: UNumericType = 0i32;\npub const U_NT_NUMERIC: UNumericType = 3i32;\npub const U_NUMBER_ARG_OUTOFBOUNDS_ERROR: UErrorCode = 65810i32;\npub const U_NUMBER_SKELETON_SYNTAX_ERROR: UErrorCode = 65811i32;\npub const U_OMIT_UNCHANGED_TEXT: u32 = 16384u32;\npub const U_OTHER_LETTER: UCharCategory = 5i32;\npub const U_OTHER_NEUTRAL: UCharDirection = 10i32;\npub const U_OTHER_NUMBER: UCharCategory = 11i32;\npub const U_OTHER_PUNCTUATION: UCharCategory = 23i32;\npub const U_OTHER_SYMBOL: UCharCategory = 27i32;\npub const U_OVERRIDE_CXX_ALLOCATION: u32 = 1u32;\npub const U_PARAGRAPH_SEPARATOR: UCharCategory = 14i32;\npub const U_PARSE_CONTEXT_LEN: i32 = 16i32;\npub const U_PARSE_ERROR: UErrorCode = 9i32;\npub const U_PARSE_ERROR_START: UErrorCode = 65536i32;\npub const U_PATTERN_SYNTAX_ERROR: UErrorCode = 65799i32;\npub const U_PF_AIX: u32 = 3100u32;\npub const U_PF_ANDROID: u32 = 4050u32;\npub const U_PF_BROWSER_NATIVE_CLIENT: u32 = 4020u32;\npub const U_PF_BSD: u32 = 3000u32;\npub const U_PF_CYGWIN: u32 = 1900u32;\npub const U_PF_DARWIN: u32 = 3500u32;\npub const U_PF_EMSCRIPTEN: u32 = 5010u32;\npub const U_PF_FUCHSIA: u32 = 4100u32;\npub const U_PF_HPUX: u32 = 2100u32;\npub const U_PF_IPHONE: u32 = 3550u32;\npub const U_PF_IRIX: u32 = 3200u32;\npub const U_PF_LINUX: u32 = 4000u32;\npub const U_PF_MINGW: u32 = 1800u32;\npub const U_PF_OS390: u32 = 9000u32;\npub const U_PF_OS400: u32 = 9400u32;\npub const U_PF_QNX: u32 = 3700u32;\npub const U_PF_SOLARIS: u32 = 2600u32;\npub const U_PF_UNKNOWN: u32 = 0u32;\npub const U_PF_WINDOWS: u32 = 1000u32;\npub const U_PLATFORM: u32 = 1800u32;\npub const U_PLATFORM_HAS_WIN32_API: u32 = 1u32;\npub const U_PLATFORM_HAS_WINUWP_API: u32 = 0u32;\npub const U_PLATFORM_IMPLEMENTS_POSIX: u32 = 0u32;\npub const U_PLATFORM_IS_DARWIN_BASED: u32 = 1u32;\npub const U_PLATFORM_IS_LINUX_BASED: u32 = 1u32;\npub const U_PLATFORM_USES_ONLY_WIN32_API: u32 = 1u32;\npub const U_PLUGIN_CHANGED_LEVEL_WARNING: UErrorCode = -120i32;\npub const U_PLUGIN_DIDNT_SET_LEVEL: UErrorCode = 66817i32;\npub const U_PLUGIN_ERROR_START: UErrorCode = 66816i32;\npub const U_PLUGIN_TOO_HIGH: UErrorCode = 66816i32;\npub const U_POP_DIRECTIONAL_FORMAT: UCharDirection = 16i32;\npub const U_POP_DIRECTIONAL_ISOLATE: UCharDirection = 22i32;\npub const U_PRIMARY_TOO_LONG_ERROR: UErrorCode = 22i32;\npub const U_PRIVATE_USE_CHAR: UCharCategory = 17i32;\npub const U_REGEX_BAD_ESCAPE_SEQUENCE: UErrorCode = 66307i32;\npub const U_REGEX_BAD_INTERVAL: UErrorCode = 66312i32;\npub const U_REGEX_ERROR_START: UErrorCode = 66304i32;\npub const U_REGEX_INTERNAL_ERROR: UErrorCode = 66304i32;\npub const U_REGEX_INVALID_BACK_REF: UErrorCode = 66314i32;\npub const U_REGEX_INVALID_CAPTURE_GROUP_NAME: UErrorCode = 66325i32;\npub const U_REGEX_INVALID_FLAG: UErrorCode = 66315i32;\npub const U_REGEX_INVALID_RANGE: UErrorCode = 66320i32;\npub const U_REGEX_INVALID_STATE: UErrorCode = 66306i32;\npub const U_REGEX_LOOK_BEHIND_LIMIT: UErrorCode = 66316i32;\npub const U_REGEX_MAX_LT_MIN: UErrorCode = 66313i32;\npub const U_REGEX_MISMATCHED_PAREN: UErrorCode = 66310i32;\npub const U_REGEX_MISSING_CLOSE_BRACKET: UErrorCode = 66319i32;\npub const U_REGEX_NUMBER_TOO_BIG: UErrorCode = 66311i32;\npub const U_REGEX_PATTERN_TOO_BIG: UErrorCode = 66324i32;\npub const U_REGEX_PROPERTY_SYNTAX: UErrorCode = 66308i32;\npub const U_REGEX_RULE_SYNTAX: UErrorCode = 66305i32;\npub const U_REGEX_SET_CONTAINS_STRING: UErrorCode = 66317i32;\npub const U_REGEX_STACK_OVERFLOW: UErrorCode = 66321i32;\npub const U_REGEX_STOPPED_BY_CALLER: UErrorCode = 66323i32;\npub const U_REGEX_TIME_OUT: UErrorCode = 66322i32;\npub const U_REGEX_UNIMPLEMENTED: UErrorCode = 66309i32;\npub const U_RESOURCE_TYPE_MISMATCH: UErrorCode = 17i32;\npub const U_RIGHT_TO_LEFT: UCharDirection = 1i32;\npub const U_RIGHT_TO_LEFT_ARABIC: UCharDirection = 13i32;\npub const U_RIGHT_TO_LEFT_EMBEDDING: UCharDirection = 14i32;\npub const U_RIGHT_TO_LEFT_ISOLATE: UCharDirection = 21i32;\npub const U_RIGHT_TO_LEFT_OVERRIDE: UCharDirection = 15i32;\npub const U_RULE_MASK_ERROR: UErrorCode = 65557i32;\npub const U_SAFECLONE_ALLOCATED_WARNING: UErrorCode = -126i32;\npub const U_SB_ATERM: USentenceBreak = 1i32;\npub const U_SB_CLOSE: USentenceBreak = 2i32;\npub const U_SB_CR: USentenceBreak = 11i32;\npub const U_SB_EXTEND: USentenceBreak = 12i32;\npub const U_SB_FORMAT: USentenceBreak = 3i32;\npub const U_SB_LF: USentenceBreak = 13i32;\npub const U_SB_LOWER: USentenceBreak = 4i32;\npub const U_SB_NUMERIC: USentenceBreak = 5i32;\npub const U_SB_OLETTER: USentenceBreak = 6i32;\npub const U_SB_OTHER: USentenceBreak = 0i32;\npub const U_SB_SCONTINUE: USentenceBreak = 14i32;\npub const U_SB_SEP: USentenceBreak = 7i32;\npub const U_SB_SP: USentenceBreak = 8i32;\npub const U_SB_STERM: USentenceBreak = 9i32;\npub const U_SB_UPPER: USentenceBreak = 10i32;\npub const U_SEGMENT_SEPARATOR: UCharDirection = 8i32;\npub const U_SENTINEL: i32 = -1i32;\npub const U_SHAPE_AGGREGATE_TASHKEEL: u32 = 16384u32;\npub const U_SHAPE_AGGREGATE_TASHKEEL_MASK: u32 = 16384u32;\npub const U_SHAPE_AGGREGATE_TASHKEEL_NOOP: u32 = 0u32;\npub const U_SHAPE_DIGITS_ALEN2AN_INIT_AL: u32 = 128u32;\npub const U_SHAPE_DIGITS_ALEN2AN_INIT_LR: u32 = 96u32;\npub const U_SHAPE_DIGITS_AN2EN: u32 = 64u32;\npub const U_SHAPE_DIGITS_EN2AN: u32 = 32u32;\npub const U_SHAPE_DIGITS_MASK: u32 = 224u32;\npub const U_SHAPE_DIGITS_NOOP: u32 = 0u32;\npub const U_SHAPE_DIGITS_RESERVED: u32 = 160u32;\npub const U_SHAPE_DIGIT_TYPE_AN: u32 = 0u32;\npub const U_SHAPE_DIGIT_TYPE_AN_EXTENDED: u32 = 256u32;\npub const U_SHAPE_DIGIT_TYPE_MASK: u32 = 768u32;\npub const U_SHAPE_DIGIT_TYPE_RESERVED: u32 = 512u32;\npub const U_SHAPE_LAMALEF_AUTO: u32 = 65536u32;\npub const U_SHAPE_LAMALEF_BEGIN: u32 = 3u32;\npub const U_SHAPE_LAMALEF_END: u32 = 2u32;\npub const U_SHAPE_LAMALEF_MASK: u32 = 65539u32;\npub const U_SHAPE_LAMALEF_NEAR: u32 = 1u32;\npub const U_SHAPE_LAMALEF_RESIZE: u32 = 0u32;\npub const U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING: u32 = 3u32;\npub const U_SHAPE_LENGTH_FIXED_SPACES_AT_END: u32 = 2u32;\npub const U_SHAPE_LENGTH_FIXED_SPACES_NEAR: u32 = 1u32;\npub const U_SHAPE_LENGTH_GROW_SHRINK: u32 = 0u32;\npub const U_SHAPE_LENGTH_MASK: u32 = 65539u32;\npub const U_SHAPE_LETTERS_MASK: u32 = 24u32;\npub const U_SHAPE_LETTERS_NOOP: u32 = 0u32;\npub const U_SHAPE_LETTERS_SHAPE: u32 = 8u32;\npub const U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED: u32 = 24u32;\npub const U_SHAPE_LETTERS_UNSHAPE: u32 = 16u32;\npub const U_SHAPE_PRESERVE_PRESENTATION: u32 = 32768u32;\npub const U_SHAPE_PRESERVE_PRESENTATION_MASK: u32 = 32768u32;\npub const U_SHAPE_PRESERVE_PRESENTATION_NOOP: u32 = 0u32;\npub const U_SHAPE_SEEN_MASK: u32 = 7340032u32;\npub const U_SHAPE_SEEN_TWOCELL_NEAR: u32 = 2097152u32;\npub const U_SHAPE_SPACES_RELATIVE_TO_TEXT_BEGIN_END: u32 = 67108864u32;\npub const U_SHAPE_SPACES_RELATIVE_TO_TEXT_MASK: u32 = 67108864u32;\npub const U_SHAPE_TAIL_NEW_UNICODE: u32 = 134217728u32;\npub const U_SHAPE_TAIL_TYPE_MASK: u32 = 134217728u32;\npub const U_SHAPE_TASHKEEL_BEGIN: u32 = 262144u32;\npub const U_SHAPE_TASHKEEL_END: u32 = 393216u32;\npub const U_SHAPE_TASHKEEL_MASK: u32 = 917504u32;\npub const U_SHAPE_TASHKEEL_REPLACE_BY_TATWEEL: u32 = 786432u32;\npub const U_SHAPE_TASHKEEL_RESIZE: u32 = 524288u32;\npub const U_SHAPE_TEXT_DIRECTION_LOGICAL: u32 = 0u32;\npub const U_SHAPE_TEXT_DIRECTION_MASK: u32 = 4u32;\npub const U_SHAPE_TEXT_DIRECTION_VISUAL_LTR: u32 = 4u32;\npub const U_SHAPE_TEXT_DIRECTION_VISUAL_RTL: u32 = 0u32;\npub const U_SHAPE_YEHHAMZA_MASK: u32 = 58720256u32;\npub const U_SHAPE_YEHHAMZA_TWOCELL_NEAR: u32 = 16777216u32;\npub const U_SHORT_PROPERTY_NAME: UPropertyNameChoice = 0i32;\npub const U_SHOW_CPLUSPLUS_API: u32 = 0u32;\npub const U_SIZEOF_UCHAR: u32 = 2u32;\npub const U_SIZEOF_WCHAR_T: u32 = 1u32;\npub const U_SORT_KEY_TOO_SHORT_WARNING: UErrorCode = -123i32;\npub const U_SPACE_SEPARATOR: UCharCategory = 12i32;\npub const U_START_PUNCTUATION: UCharCategory = 20i32;\npub const U_STATE_OLD_WARNING: UErrorCode = -125i32;\npub const U_STATE_TOO_OLD_ERROR: UErrorCode = 23i32;\npub const U_STRINGPREP_CHECK_BIDI_ERROR: UErrorCode = 66562i32;\npub const U_STRINGPREP_PROHIBITED_ERROR: UErrorCode = 66560i32;\npub const U_STRINGPREP_UNASSIGNED_ERROR: UErrorCode = 66561i32;\npub const U_STRING_NOT_TERMINATED_WARNING: UErrorCode = -124i32;\npub const U_SURROGATE: UCharCategory = 18i32;\npub const U_TITLECASE_ADJUST_TO_CASED: u32 = 1024u32;\npub const U_TITLECASE_LETTER: UCharCategory = 3i32;\npub const U_TITLECASE_NO_BREAK_ADJUSTMENT: u32 = 512u32;\npub const U_TITLECASE_NO_LOWERCASE: u32 = 256u32;\npub const U_TITLECASE_SENTENCES: u32 = 64u32;\npub const U_TITLECASE_WHOLE_STRING: u32 = 32u32;\npub const U_TOO_MANY_ALIASES_ERROR: UErrorCode = 24i32;\npub const U_TRAILING_BACKSLASH: UErrorCode = 65552i32;\npub const U_TRUNCATED_CHAR_FOUND: UErrorCode = 11i32;\npub const U_UNASSIGNED: UCharCategory = 0i32;\npub const U_UNCLOSED_SEGMENT: UErrorCode = 65563i32;\npub const U_UNDEFINED_KEYWORD: UErrorCode = 65806i32;\npub const U_UNDEFINED_SEGMENT_REFERENCE: UErrorCode = 65553i32;\npub const U_UNDEFINED_VARIABLE: UErrorCode = 65554i32;\npub const U_UNEXPECTED_TOKEN: UErrorCode = 65792i32;\npub const U_UNICODE_CHAR_NAME: UCharNameChoice = 0i32;\npub const U_UNICODE_VERSION: windows_sys::core::PCSTR = windows_sys::core::s!(\"8.0\");\npub const U_UNMATCHED_BRACES: UErrorCode = 65801i32;\npub const U_UNQUOTED_SPECIAL: UErrorCode = 65555i32;\npub const U_UNSUPPORTED_ATTRIBUTE: UErrorCode = 65803i32;\npub const U_UNSUPPORTED_ERROR: UErrorCode = 16i32;\npub const U_UNSUPPORTED_ESCAPE_SEQUENCE: UErrorCode = 19i32;\npub const U_UNSUPPORTED_PROPERTY: UErrorCode = 65802i32;\npub const U_UNTERMINATED_QUOTE: UErrorCode = 65556i32;\npub const U_UPPERCASE_LETTER: UCharCategory = 1i32;\npub const U_USELESS_COLLATOR_ERROR: UErrorCode = 29i32;\npub const U_USING_DEFAULT_WARNING: UErrorCode = -127i32;\npub const U_USING_FALLBACK_WARNING: UErrorCode = -128i32;\npub const U_USING_ICU_NAMESPACE: u32 = 1u32;\npub const U_VARIABLE_RANGE_EXHAUSTED: UErrorCode = 65565i32;\npub const U_VARIABLE_RANGE_OVERLAP: UErrorCode = 65566i32;\npub const U_VO_ROTATED: UVerticalOrientation = 0i32;\npub const U_VO_TRANSFORMED_ROTATED: UVerticalOrientation = 1i32;\npub const U_VO_TRANSFORMED_UPRIGHT: UVerticalOrientation = 2i32;\npub const U_VO_UPRIGHT: UVerticalOrientation = 3i32;\npub const U_WB_ALETTER: UWordBreakValues = 1i32;\npub const U_WB_CR: UWordBreakValues = 8i32;\npub const U_WB_DOUBLE_QUOTE: UWordBreakValues = 16i32;\npub const U_WB_EXTEND: UWordBreakValues = 9i32;\npub const U_WB_EXTENDNUMLET: UWordBreakValues = 7i32;\npub const U_WB_E_BASE: UWordBreakValues = 17i32;\npub const U_WB_E_BASE_GAZ: UWordBreakValues = 18i32;\npub const U_WB_E_MODIFIER: UWordBreakValues = 19i32;\npub const U_WB_FORMAT: UWordBreakValues = 2i32;\npub const U_WB_GLUE_AFTER_ZWJ: UWordBreakValues = 20i32;\npub const U_WB_HEBREW_LETTER: UWordBreakValues = 14i32;\npub const U_WB_KATAKANA: UWordBreakValues = 3i32;\npub const U_WB_LF: UWordBreakValues = 10i32;\npub const U_WB_MIDLETTER: UWordBreakValues = 4i32;\npub const U_WB_MIDNUM: UWordBreakValues = 5i32;\npub const U_WB_MIDNUMLET: UWordBreakValues = 11i32;\npub const U_WB_NEWLINE: UWordBreakValues = 12i32;\npub const U_WB_NUMERIC: UWordBreakValues = 6i32;\npub const U_WB_OTHER: UWordBreakValues = 0i32;\npub const U_WB_REGIONAL_INDICATOR: UWordBreakValues = 13i32;\npub const U_WB_SINGLE_QUOTE: UWordBreakValues = 15i32;\npub const U_WB_WSEGSPACE: UWordBreakValues = 22i32;\npub const U_WB_ZWJ: UWordBreakValues = 21i32;\npub const U_WHITE_SPACE_NEUTRAL: UCharDirection = 9i32;\npub const U_ZERO_ERROR: UErrorCode = 0i32;\npub const VS_ALLOW_LATIN: u32 = 1u32;\npub const WC_COMPOSITECHECK: u32 = 512u32;\npub const WC_DEFAULTCHAR: u32 = 64u32;\npub const WC_DISCARDNS: u32 = 16u32;\npub const WC_ERR_INVALID_CHARS: u32 = 128u32;\npub const WC_NO_BEST_FIT_CHARS: u32 = 1024u32;\npub const WC_SEPCHARS: u32 = 32u32;\npub type WORDLIST_TYPE = i32;\npub const WORDLIST_TYPE_ADD: WORDLIST_TYPE = 1i32;\npub const WORDLIST_TYPE_AUTOCORRECT: WORDLIST_TYPE = 3i32;\npub const WORDLIST_TYPE_EXCLUDE: WORDLIST_TYPE = 2i32;\npub const WORDLIST_TYPE_IGNORE: WORDLIST_TYPE = 0i32;\npub const WeekUnit: CALDATETIME_DATEUNIT = 3i32;\npub const YearUnit: CALDATETIME_DATEUNIT = 1i32;\npub const sidArabic: SCRIPTCONTF = 9i32;\npub const sidArmenian: SCRIPTCONTF = 7i32;\npub const sidAsciiLatin: SCRIPTCONTF = 3i32;\npub const sidAsciiSym: SCRIPTCONTF = 2i32;\npub const sidBengali: SCRIPTCONTF = 11i32;\npub const sidBopomofo: SCRIPTCONTF = 25i32;\npub const sidBraille: SCRIPTCONTF = 31i32;\npub const sidBurmese: SCRIPTCONTF = 36i32;\npub const sidCanSyllabic: SCRIPTCONTF = 28i32;\npub const sidCherokee: SCRIPTCONTF = 29i32;\npub const sidCyrillic: SCRIPTCONTF = 6i32;\npub const sidDefault: SCRIPTCONTF = 0i32;\npub const sidDevanagari: SCRIPTCONTF = 10i32;\npub const sidEthiopic: SCRIPTCONTF = 27i32;\npub const sidFEFirst: SCRIPTCONTF = 23i32;\npub const sidFELast: SCRIPTCONTF = 26i32;\npub const sidGeorgian: SCRIPTCONTF = 22i32;\npub const sidGreek: SCRIPTCONTF = 5i32;\npub const sidGujarati: SCRIPTCONTF = 13i32;\npub const sidGurmukhi: SCRIPTCONTF = 12i32;\npub const sidHan: SCRIPTCONTF = 26i32;\npub const sidHangul: SCRIPTCONTF = 23i32;\npub const sidHebrew: SCRIPTCONTF = 8i32;\npub const sidKana: SCRIPTCONTF = 24i32;\npub const sidKannada: SCRIPTCONTF = 17i32;\npub const sidKhmer: SCRIPTCONTF = 37i32;\npub const sidLao: SCRIPTCONTF = 20i32;\npub const sidLatin: SCRIPTCONTF = 4i32;\npub const sidLim: SCRIPTCONTF = 41i32;\npub const sidMalayalam: SCRIPTCONTF = 18i32;\npub const sidMerge: SCRIPTCONTF = 1i32;\npub const sidMongolian: SCRIPTCONTF = 39i32;\npub const sidOgham: SCRIPTCONTF = 33i32;\npub const sidOriya: SCRIPTCONTF = 14i32;\npub const sidRunic: SCRIPTCONTF = 32i32;\npub const sidSinhala: SCRIPTCONTF = 34i32;\npub const sidSyriac: SCRIPTCONTF = 35i32;\npub const sidTamil: SCRIPTCONTF = 15i32;\npub const sidTelugu: SCRIPTCONTF = 16i32;\npub const sidThaana: SCRIPTCONTF = 38i32;\npub const sidThai: SCRIPTCONTF = 19i32;\npub const sidTibetan: SCRIPTCONTF = 21i32;\npub const sidUserDefined: SCRIPTCONTF = 40i32;\npub const sidYi: SCRIPTCONTF = 30i32;\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/Graphics/GdiPlus/mod.rs",
      "sha256": "e5f540c543525ebba49b84b6be089da723b7de7677b711753450828f0a0b2ef9",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "windows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathArc(path : *mut GpPath, x : f32, y : f32, width : f32, height : f32, startangle : f32, sweepangle : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathArcI(path : *mut GpPath, x : i32, y : i32, width : i32, height : i32, startangle : f32, sweepangle : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathBezier(path : *mut GpPath, x1 : f32, y1 : f32, x2 : f32, y2 : f32, x3 : f32, y3 : f32, x4 : f32, y4 : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathBezierI(path : *mut GpPath, x1 : i32, y1 : i32, x2 : i32, y2 : i32, x3 : i32, y3 : i32, x4 : i32, y4 : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathBeziers(path : *mut GpPath, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathBeziersI(path : *mut GpPath, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathClosedCurve(path : *mut GpPath, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathClosedCurve2(path : *mut GpPath, points : *const PointF, count : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathClosedCurve2I(path : *mut GpPath, points : *const Point, count : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathClosedCurveI(path : *mut GpPath, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathCurve(path : *mut GpPath, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathCurve2(path : *mut GpPath, points : *const PointF, count : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathCurve2I(path : *mut GpPath, points : *const Point, count : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathCurve3(path : *mut GpPath, points : *const PointF, count : i32, offset : i32, numberofsegments : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathCurve3I(path : *mut GpPath, points : *const Point, count : i32, offset : i32, numberofsegments : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathCurveI(path : *mut GpPath, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathEllipse(path : *mut GpPath, x : f32, y : f32, width : f32, height : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathEllipseI(path : *mut GpPath, x : i32, y : i32, width : i32, height : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathLine(path : *mut GpPath, x1 : f32, y1 : f32, x2 : f32, y2 : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathLine2(path : *mut GpPath, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathLine2I(path : *mut GpPath, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathLineI(path : *mut GpPath, x1 : i32, y1 : i32, x2 : i32, y2 : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathPath(path : *mut GpPath, addingpath : *const GpPath, connect : windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathPie(path : *mut GpPath, x : f32, y : f32, width : f32, height : f32, startangle : f32, sweepangle : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathPieI(path : *mut GpPath, x : i32, y : i32, width : i32, height : i32, startangle : f32, sweepangle : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathPolygon(path : *mut GpPath, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathPolygonI(path : *mut GpPath, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathRectangle(path : *mut GpPath, x : f32, y : f32, width : f32, height : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathRectangleI(path : *mut GpPath, x : i32, y : i32, width : i32, height : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathRectangles(path : *mut GpPath, rects : *const RectF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathRectanglesI(path : *mut GpPath, rects : *const Rect, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathString(path : *mut GpPath, string : windows_sys::core::PCWSTR, length : i32, family : *const GpFontFamily, style : i32, emsize : f32, layoutrect : *const RectF, format : *const GpStringFormat) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAddPathStringI(path : *mut GpPath, string : windows_sys::core::PCWSTR, length : i32, family : *const GpFontFamily, style : i32, emsize : f32, layoutrect : *const Rect, format : *const GpStringFormat) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipAlloc(size : usize) -> *mut core::ffi::c_void);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBeginContainer(graphics : *mut GpGraphics, dstrect : *const RectF, srcrect : *const RectF, unit : Unit, state : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBeginContainer2(graphics : *mut GpGraphics, state : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBeginContainerI(graphics : *mut GpGraphics, dstrect : *const Rect, srcrect : *const Rect, unit : Unit, state : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBitmapApplyEffect(bitmap : *mut GpBitmap, effect : *mut CGpEffect, roi : *mut super::super::Foundation:: RECT, useauxdata : windows_sys::core::BOOL, auxdata : *mut *mut core::ffi::c_void, auxdatasize : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBitmapConvertFormat(pinputbitmap : *mut GpBitmap, format : i32, dithertype : DitherType, palettetype : PaletteType, palette : *mut ColorPalette, alphathresholdpercent : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBitmapCreateApplyEffect(inputbitmaps : *mut *mut GpBitmap, numinputs : i32, effect : *mut CGpEffect, roi : *mut super::super::Foundation:: RECT, outputrect : *mut super::super::Foundation:: RECT, outputbitmap : *mut *mut GpBitmap, useauxdata : windows_sys::core::BOOL, auxdata : *mut *mut core::ffi::c_void, auxdatasize : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBitmapGetHistogram(bitmap : *mut GpBitmap, format : HistogramFormat, numberofentries : u32, channel0 : *mut u32, channel1 : *mut u32, channel2 : *mut u32, channel3 : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBitmapGetHistogramSize(format : HistogramFormat, numberofentries : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBitmapGetPixel(bitmap : *mut GpBitmap, x : i32, y : i32, color : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBitmapLockBits(bitmap : *mut GpBitmap, rect : *const Rect, flags : u32, format : i32, lockedbitmapdata : *mut BitmapData) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBitmapSetPixel(bitmap : *mut GpBitmap, x : i32, y : i32, color : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBitmapSetResolution(bitmap : *mut GpBitmap, xdpi : f32, ydpi : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipBitmapUnlockBits(bitmap : *mut GpBitmap, lockedbitmapdata : *mut BitmapData) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipClearPathMarkers(path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneBitmapArea(x : f32, y : f32, width : f32, height : f32, format : i32, srcbitmap : *mut GpBitmap, dstbitmap : *mut *mut GpBitmap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneBitmapAreaI(x : i32, y : i32, width : i32, height : i32, format : i32, srcbitmap : *mut GpBitmap, dstbitmap : *mut *mut GpBitmap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneBrush(brush : *mut GpBrush, clonebrush : *mut *mut GpBrush) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneCustomLineCap(customcap : *mut GpCustomLineCap, clonedcap : *mut *mut GpCustomLineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneFont(font : *mut GpFont, clonefont : *mut *mut GpFont) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneFontFamily(fontfamily : *mut GpFontFamily, clonedfontfamily : *mut *mut GpFontFamily) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneImage(image : *mut GpImage, cloneimage : *mut *mut GpImage) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneImageAttributes(imageattr : *const GpImageAttributes, cloneimageattr : *mut *mut GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneMatrix(matrix : *mut Matrix, clonematrix : *mut *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipClonePath(path : *mut GpPath, clonepath : *mut *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipClonePen(pen : *mut GpPen, clonepen : *mut *mut GpPen) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneRegion(region : *mut GpRegion, cloneregion : *mut *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCloneStringFormat(format : *const GpStringFormat, newformat : *mut *mut GpStringFormat) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipClosePathFigure(path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipClosePathFigures(path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCombineRegionPath(region : *mut GpRegion, path : *mut GpPath, combinemode : CombineMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCombineRegionRect(region : *mut GpRegion, rect : *const RectF, combinemode : CombineMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCombineRegionRectI(region : *mut GpRegion, rect : *const Rect, combinemode : CombineMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCombineRegionRegion(region : *mut GpRegion, region2 : *mut GpRegion, combinemode : CombineMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipComment(graphics : *mut GpGraphics, sizedata : u32, data : *const u8) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipConvertToEmfPlus(refgraphics : *const GpGraphics, metafile : *mut GpMetafile, conversionfailureflag : *mut i32, emftype : EmfType, description : windows_sys::core::PCWSTR, out_metafile : *mut *mut GpMetafile) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipConvertToEmfPlusToFile(refgraphics : *const GpGraphics, metafile : *mut GpMetafile, conversionfailureflag : *mut i32, filename : windows_sys::core::PCWSTR, emftype : EmfType, description : windows_sys::core::PCWSTR, out_metafile : *mut *mut GpMetafile) -> Status);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipConvertToEmfPlusToStream(refgraphics : *const GpGraphics, metafile : *mut GpMetafile, conversionfailureflag : *mut i32, stream : * mut core::ffi::c_void, emftype : EmfType, description : windows_sys::core::PCWSTR, out_metafile : *mut *mut GpMetafile) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateAdjustableArrowCap(height : f32, width : f32, isfilled : windows_sys::core::BOOL, cap : *mut *mut GpAdjustableArrowCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateBitmapFromFile(filename : windows_sys::core::PCWSTR, bitmap : *mut *mut GpBitmap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateBitmapFromFileICM(filename : windows_sys::core::PCWSTR, bitmap : *mut *mut GpBitmap) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateBitmapFromGdiDib(gdibitmapinfo : *const super::Gdi:: BITMAPINFO, gdibitmapdata : *mut core::ffi::c_void, bitmap : *mut *mut GpBitmap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateBitmapFromGraphics(width : i32, height : i32, target : *mut GpGraphics, bitmap : *mut *mut GpBitmap) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateBitmapFromHBITMAP(hbm : super::Gdi:: HBITMAP, hpal : super::Gdi:: HPALETTE, bitmap : *mut *mut GpBitmap) -> Status);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateBitmapFromHICON(hicon : super::super::UI::WindowsAndMessaging:: HICON, bitmap : *mut *mut GpBitmap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateBitmapFromResource(hinstance : super::super::Foundation:: HINSTANCE, lpbitmapname : windows_sys::core::PCWSTR, bitmap : *mut *mut GpBitmap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateBitmapFromScan0(width : i32, height : i32, stride : i32, format : i32, scan0 : *const u8, bitmap : *mut *mut GpBitmap) -> Status);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateBitmapFromStream(stream : * mut core::ffi::c_void, bitmap : *mut *mut GpBitmap) -> Status);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateBitmapFromStreamICM(stream : * mut core::ffi::c_void, bitmap : *mut *mut GpBitmap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateCachedBitmap(bitmap : *mut GpBitmap, graphics : *mut GpGraphics, cachedbitmap : *mut *mut GpCachedBitmap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateCustomLineCap(fillpath : *mut GpPath, strokepath : *mut GpPath, basecap : LineCap, baseinset : f32, customcap : *mut *mut GpCustomLineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateEffect(guid : windows_sys::core::GUID, effect : *mut *mut CGpEffect) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateFont(fontfamily : *const GpFontFamily, emsize : f32, style : i32, unit : Unit, font : *mut *mut GpFont) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateFontFamilyFromName(name : windows_sys::core::PCWSTR, fontcollection : *mut GpFontCollection, fontfamily : *mut *mut GpFontFamily) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateFontFromDC(hdc : super::Gdi:: HDC, font : *mut *mut GpFont) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateFontFromLogfontA(hdc : super::Gdi:: HDC, logfont : *const super::Gdi:: LOGFONTA, font : *mut *mut GpFont) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateFontFromLogfontW(hdc : super::Gdi:: HDC, logfont : *const super::Gdi:: LOGFONTW, font : *mut *mut GpFont) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateFromHDC(hdc : super::Gdi:: HDC, graphics : *mut *mut GpGraphics) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateFromHDC2(hdc : super::Gdi:: HDC, hdevice : super::super::Foundation:: HANDLE, graphics : *mut *mut GpGraphics) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateFromHWND(hwnd : super::super::Foundation:: HWND, graphics : *mut *mut GpGraphics) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateFromHWNDICM(hwnd : super::super::Foundation:: HWND, graphics : *mut *mut GpGraphics) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateHBITMAPFromBitmap(bitmap : *mut GpBitmap, hbmreturn : *mut super::Gdi:: HBITMAP, background : u32) -> Status);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateHICONFromBitmap(bitmap : *mut GpBitmap, hbmreturn : *mut super::super::UI::WindowsAndMessaging:: HICON) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateHalftonePalette() -> super::Gdi:: HPALETTE);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateHatchBrush(hatchstyle : HatchStyle, forecol : u32, backcol : u32, brush : *mut *mut GpHatch) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateImageAttributes(imageattr : *mut *mut GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateLineBrush(point1 : *const PointF, point2 : *const PointF, color1 : u32, color2 : u32, wrapmode : WrapMode, linegradient : *mut *mut GpLineGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateLineBrushFromRect(rect : *const RectF, color1 : u32, color2 : u32, mode : LinearGradientMode, wrapmode : WrapMode, linegradient : *mut *mut GpLineGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateLineBrushFromRectI(rect : *const Rect, color1 : u32, color2 : u32, mode : LinearGradientMode, wrapmode : WrapMode, linegradient : *mut *mut GpLineGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateLineBrushFromRectWithAngle(rect : *const RectF, color1 : u32, color2 : u32, angle : f32, isanglescalable : windows_sys::core::BOOL, wrapmode : WrapMode, linegradient : *mut *mut GpLineGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateLineBrushFromRectWithAngleI(rect : *const Rect, color1 : u32, color2 : u32, angle : f32, isanglescalable : windows_sys::core::BOOL, wrapmode : WrapMode, linegradient : *mut *mut GpLineGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateLineBrushI(point1 : *const Point, point2 : *const Point, color1 : u32, color2 : u32, wrapmode : WrapMode, linegradient : *mut *mut GpLineGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateMatrix(matrix : *mut *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateMatrix2(m11 : f32, m12 : f32, m21 : f32, m22 : f32, dx : f32, dy : f32, matrix : *mut *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateMatrix3(rect : *const RectF, dstplg : *const PointF, matrix : *mut *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateMatrix3I(rect : *const Rect, dstplg : *const Point, matrix : *mut *mut Matrix) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateMetafileFromEmf(hemf : super::Gdi:: HENHMETAFILE, deleteemf : windows_sys::core::BOOL, metafile : *mut *mut GpMetafile) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateMetafileFromFile(file : windows_sys::core::PCWSTR, metafile : *mut *mut GpMetafile) -> Status);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateMetafileFromStream(stream : * mut core::ffi::c_void, metafile : *mut *mut GpMetafile) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateMetafileFromWmf(hwmf : super::Gdi:: HMETAFILE, deletewmf : windows_sys::core::BOOL, wmfplaceablefileheader : *const WmfPlaceableFileHeader, metafile : *mut *mut GpMetafile) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateMetafileFromWmfFile(file : windows_sys::core::PCWSTR, wmfplaceablefileheader : *const WmfPlaceableFileHeader, metafile : *mut *mut GpMetafile) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreatePath(brushmode : FillMode, path : *mut *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreatePath2(param0 : *const PointF, param1 : *const u8, param2 : i32, param3 : FillMode, path : *mut *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreatePath2I(param0 : *const Point, param1 : *const u8, param2 : i32, param3 : FillMode, path : *mut *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreatePathGradient(points : *const PointF, count : i32, wrapmode : WrapMode, polygradient : *mut *mut GpPathGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreatePathGradientFromPath(path : *const GpPath, polygradient : *mut *mut GpPathGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreatePathGradientI(points : *const Point, count : i32, wrapmode : WrapMode, polygradient : *mut *mut GpPathGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreatePathIter(iterator : *mut *mut GpPathIterator, path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreatePen1(color : u32, width : f32, unit : Unit, pen : *mut *mut GpPen) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreatePen2(brush : *mut GpBrush, width : f32, unit : Unit, pen : *mut *mut GpPen) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateRegion(region : *mut *mut GpRegion) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateRegionHrgn(hrgn : super::Gdi:: HRGN, region : *mut *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateRegionPath(path : *mut GpPath, region : *mut *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateRegionRect(rect : *const RectF, region : *mut *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateRegionRectI(rect : *const Rect, region : *mut *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateRegionRgnData(regiondata : *const u8, size : i32, region : *mut *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateSolidFill(color : u32, brush : *mut *mut GpSolidFill) -> Status);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateStreamOnFile(filename : windows_sys::core::PCWSTR, access : u32, stream : *mut * mut core::ffi::c_void) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateStringFormat(formatattributes : i32, language : u16, format : *mut *mut GpStringFormat) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateTexture(image : *mut GpImage, wrapmode : WrapMode, texture : *mut *mut GpTexture) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateTexture2(image : *mut GpImage, wrapmode : WrapMode, x : f32, y : f32, width : f32, height : f32, texture : *mut *mut GpTexture) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateTexture2I(image : *mut GpImage, wrapmode : WrapMode, x : i32, y : i32, width : i32, height : i32, texture : *mut *mut GpTexture) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateTextureIA(image : *mut GpImage, imageattributes : *const GpImageAttributes, x : f32, y : f32, width : f32, height : f32, texture : *mut *mut GpTexture) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipCreateTextureIAI(image : *mut GpImage, imageattributes : *const GpImageAttributes, x : i32, y : i32, width : i32, height : i32, texture : *mut *mut GpTexture) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeleteBrush(brush : *mut GpBrush) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeleteCachedBitmap(cachedbitmap : *mut GpCachedBitmap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeleteCustomLineCap(customcap : *mut GpCustomLineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeleteEffect(effect : *mut CGpEffect) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeleteFont(font : *mut GpFont) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeleteFontFamily(fontfamily : *mut GpFontFamily) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeleteGraphics(graphics : *mut GpGraphics) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeleteMatrix(matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeletePath(path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeletePathIter(iterator : *mut GpPathIterator) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeletePen(pen : *mut GpPen) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeletePrivateFontCollection(fontcollection : *mut *mut GpFontCollection) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeleteRegion(region : *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDeleteStringFormat(format : *mut GpStringFormat) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDisposeImage(image : *mut GpImage) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDisposeImageAttributes(imageattr : *mut GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawArc(graphics : *mut GpGraphics, pen : *mut GpPen, x : f32, y : f32, width : f32, height : f32, startangle : f32, sweepangle : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawArcI(graphics : *mut GpGraphics, pen : *mut GpPen, x : i32, y : i32, width : i32, height : i32, startangle : f32, sweepangle : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawBezier(graphics : *mut GpGraphics, pen : *mut GpPen, x1 : f32, y1 : f32, x2 : f32, y2 : f32, x3 : f32, y3 : f32, x4 : f32, y4 : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawBezierI(graphics : *mut GpGraphics, pen : *mut GpPen, x1 : i32, y1 : i32, x2 : i32, y2 : i32, x3 : i32, y3 : i32, x4 : i32, y4 : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawBeziers(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawBeziersI(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawCachedBitmap(graphics : *mut GpGraphics, cachedbitmap : *mut GpCachedBitmap, x : i32, y : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawClosedCurve(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawClosedCurve2(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const PointF, count : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawClosedCurve2I(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const Point, count : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawClosedCurveI(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawCurve(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawCurve2(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const PointF, count : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawCurve2I(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const Point, count : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawCurve3(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const PointF, count : i32, offset : i32, numberofsegments : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawCurve3I(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const Point, count : i32, offset : i32, numberofsegments : i32, tension : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawCurveI(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawDriverString(graphics : *mut GpGraphics, text : *const u16, length : i32, font : *const GpFont, brush : *const GpBrush, positions : *const PointF, flags : i32, matrix : *const Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawEllipse(graphics : *mut GpGraphics, pen : *mut GpPen, x : f32, y : f32, width : f32, height : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawEllipseI(graphics : *mut GpGraphics, pen : *mut GpPen, x : i32, y : i32, width : i32, height : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImage(graphics : *mut GpGraphics, image : *mut GpImage, x : f32, y : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImageFX(graphics : *mut GpGraphics, image : *mut GpImage, source : *mut RectF, xform : *mut Matrix, effect : *mut CGpEffect, imageattributes : *mut GpImageAttributes, srcunit : Unit) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImageI(graphics : *mut GpGraphics, image : *mut GpImage, x : i32, y : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImagePointRect(graphics : *mut GpGraphics, image : *mut GpImage, x : f32, y : f32, srcx : f32, srcy : f32, srcwidth : f32, srcheight : f32, srcunit : Unit) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImagePointRectI(graphics : *mut GpGraphics, image : *mut GpImage, x : i32, y : i32, srcx : i32, srcy : i32, srcwidth : i32, srcheight : i32, srcunit : Unit) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImagePoints(graphics : *mut GpGraphics, image : *mut GpImage, dstpoints : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImagePointsI(graphics : *mut GpGraphics, image : *mut GpImage, dstpoints : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImagePointsRect(graphics : *mut GpGraphics, image : *mut GpImage, points : *const PointF, count : i32, srcx : f32, srcy : f32, srcwidth : f32, srcheight : f32, srcunit : Unit, imageattributes : *const GpImageAttributes, callback : isize, callbackdata : *mut core::ffi::c_void) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImagePointsRectI(graphics : *mut GpGraphics, image : *mut GpImage, points : *const Point, count : i32, srcx : i32, srcy : i32, srcwidth : i32, srcheight : i32, srcunit : Unit, imageattributes : *const GpImageAttributes, callback : isize, callbackdata : *mut core::ffi::c_void) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImageRect(graphics : *mut GpGraphics, image : *mut GpImage, x : f32, y : f32, width : f32, height : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImageRectI(graphics : *mut GpGraphics, image : *mut GpImage, x : i32, y : i32, width : i32, height : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImageRectRect(graphics : *mut GpGraphics, image : *mut GpImage, dstx : f32, dsty : f32, dstwidth : f32, dstheight : f32, srcx : f32, srcy : f32, srcwidth : f32, srcheight : f32, srcunit : Unit, imageattributes : *const GpImageAttributes, callback : isize, callbackdata : *mut core::ffi::c_void) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawImageRectRectI(graphics : *mut GpGraphics, image : *mut GpImage, dstx : i32, dsty : i32, dstwidth : i32, dstheight : i32, srcx : i32, srcy : i32, srcwidth : i32, srcheight : i32, srcunit : Unit, imageattributes : *const GpImageAttributes, callback : isize, callbackdata : *mut core::ffi::c_void) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawLine(graphics : *mut GpGraphics, pen : *mut GpPen, x1 : f32, y1 : f32, x2 : f32, y2 : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawLineI(graphics : *mut GpGraphics, pen : *mut GpPen, x1 : i32, y1 : i32, x2 : i32, y2 : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawLines(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawLinesI(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawPath(graphics : *mut GpGraphics, pen : *mut GpPen, path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawPie(graphics : *mut GpGraphics, pen : *mut GpPen, x : f32, y : f32, width : f32, height : f32, startangle : f32, sweepangle : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawPieI(graphics : *mut GpGraphics, pen : *mut GpPen, x : i32, y : i32, width : i32, height : i32, startangle : f32, sweepangle : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawPolygon(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawPolygonI(graphics : *mut GpGraphics, pen : *mut GpPen, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawRectangle(graphics : *mut GpGraphics, pen : *mut GpPen, x : f32, y : f32, width : f32, height : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawRectangleI(graphics : *mut GpGraphics, pen : *mut GpPen, x : i32, y : i32, width : i32, height : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawRectangles(graphics : *mut GpGraphics, pen : *mut GpPen, rects : *const RectF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawRectanglesI(graphics : *mut GpGraphics, pen : *mut GpPen, rects : *const Rect, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipDrawString(graphics : *mut GpGraphics, string : windows_sys::core::PCWSTR, length : i32, font : *const GpFont, layoutrect : *const RectF, stringformat : *const GpStringFormat, brush : *const GpBrush) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEmfToWmfBits(hemf : super::Gdi:: HENHMETAFILE, cbdata16 : u32, pdata16 : *mut u8, imapmode : i32, eflags : i32) -> u32);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEndContainer(graphics : *mut GpGraphics, state : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileDestPoint(graphics : *mut GpGraphics, metafile : *const GpMetafile, destpoint : *const PointF, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileDestPointI(graphics : *mut GpGraphics, metafile : *const GpMetafile, destpoint : *const Point, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileDestPoints(graphics : *mut GpGraphics, metafile : *const GpMetafile, destpoints : *const PointF, count : i32, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileDestPointsI(graphics : *mut GpGraphics, metafile : *const GpMetafile, destpoints : *const Point, count : i32, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileDestRect(graphics : *mut GpGraphics, metafile : *const GpMetafile, destrect : *const RectF, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileDestRectI(graphics : *mut GpGraphics, metafile : *const GpMetafile, destrect : *const Rect, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileSrcRectDestPoint(graphics : *mut GpGraphics, metafile : *const GpMetafile, destpoint : *const PointF, srcrect : *const RectF, srcunit : Unit, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileSrcRectDestPointI(graphics : *mut GpGraphics, metafile : *const GpMetafile, destpoint : *const Point, srcrect : *const Rect, srcunit : Unit, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileSrcRectDestPoints(graphics : *mut GpGraphics, metafile : *const GpMetafile, destpoints : *const PointF, count : i32, srcrect : *const RectF, srcunit : Unit, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileSrcRectDestPointsI(graphics : *mut GpGraphics, metafile : *const GpMetafile, destpoints : *const Point, count : i32, srcrect : *const Rect, srcunit : Unit, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileSrcRectDestRect(graphics : *mut GpGraphics, metafile : *const GpMetafile, destrect : *const RectF, srcrect : *const RectF, srcunit : Unit, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipEnumerateMetafileSrcRectDestRectI(graphics : *mut GpGraphics, metafile : *const GpMetafile, destrect : *const Rect, srcrect : *const Rect, srcunit : Unit, callback : isize, callbackdata : *mut core::ffi::c_void, imageattributes : *const GpImageAttributes) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillClosedCurve(graphics : *mut GpGraphics, brush : *mut GpBrush, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillClosedCurve2(graphics : *mut GpGraphics, brush : *mut GpBrush, points : *const PointF, count : i32, tension : f32, fillmode : FillMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillClosedCurve2I(graphics : *mut GpGraphics, brush : *mut GpBrush, points : *const Point, count : i32, tension : f32, fillmode : FillMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillClosedCurveI(graphics : *mut GpGraphics, brush : *mut GpBrush, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillEllipse(graphics : *mut GpGraphics, brush : *mut GpBrush, x : f32, y : f32, width : f32, height : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillEllipseI(graphics : *mut GpGraphics, brush : *mut GpBrush, x : i32, y : i32, width : i32, height : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillPath(graphics : *mut GpGraphics, brush : *mut GpBrush, path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillPie(graphics : *mut GpGraphics, brush : *mut GpBrush, x : f32, y : f32, width : f32, height : f32, startangle : f32, sweepangle : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillPieI(graphics : *mut GpGraphics, brush : *mut GpBrush, x : i32, y : i32, width : i32, height : i32, startangle : f32, sweepangle : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillPolygon(graphics : *mut GpGraphics, brush : *mut GpBrush, points : *const PointF, count : i32, fillmode : FillMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillPolygon2(graphics : *mut GpGraphics, brush : *mut GpBrush, points : *const PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillPolygon2I(graphics : *mut GpGraphics, brush : *mut GpBrush, points : *const Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillPolygonI(graphics : *mut GpGraphics, brush : *mut GpBrush, points : *const Point, count : i32, fillmode : FillMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillRectangle(graphics : *mut GpGraphics, brush : *mut GpBrush, x : f32, y : f32, width : f32, height : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillRectangleI(graphics : *mut GpGraphics, brush : *mut GpBrush, x : i32, y : i32, width : i32, height : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillRectangles(graphics : *mut GpGraphics, brush : *mut GpBrush, rects : *const RectF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillRectanglesI(graphics : *mut GpGraphics, brush : *mut GpBrush, rects : *const Rect, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFillRegion(graphics : *mut GpGraphics, brush : *mut GpBrush, region : *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFindFirstImageItem(image : *mut GpImage, item : *mut ImageItemData) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFindNextImageItem(image : *mut GpImage, item : *mut ImageItemData) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFlattenPath(path : *mut GpPath, matrix : *mut Matrix, flatness : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFlush(graphics : *mut GpGraphics, intention : FlushIntention) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipFree(ptr : *mut core::ffi::c_void));\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetAdjustableArrowCapFillState(cap : *mut GpAdjustableArrowCap, fillstate : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetAdjustableArrowCapHeight(cap : *mut GpAdjustableArrowCap, height : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetAdjustableArrowCapMiddleInset(cap : *mut GpAdjustableArrowCap, middleinset : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetAdjustableArrowCapWidth(cap : *mut GpAdjustableArrowCap, width : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetAllPropertyItems(image : *mut GpImage, totalbuffersize : u32, numproperties : u32, allitems : *mut PropertyItem) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetBrushType(brush : *mut GpBrush, r#type : *mut BrushType) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetCellAscent(family : *const GpFontFamily, style : i32, cellascent : *mut u16) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetCellDescent(family : *const GpFontFamily, style : i32, celldescent : *mut u16) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetClip(graphics : *mut GpGraphics, region : *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetClipBounds(graphics : *mut GpGraphics, rect : *mut RectF) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetClipBoundsI(graphics : *mut GpGraphics, rect : *mut Rect) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetCompositingMode(graphics : *mut GpGraphics, compositingmode : *mut CompositingMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetCompositingQuality(graphics : *mut GpGraphics, compositingquality : *mut CompositingQuality) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetCustomLineCapBaseCap(customcap : *mut GpCustomLineCap, basecap : *mut LineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetCustomLineCapBaseInset(customcap : *mut GpCustomLineCap, inset : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetCustomLineCapStrokeCaps(customcap : *mut GpCustomLineCap, startcap : *mut LineCap, endcap : *mut LineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetCustomLineCapStrokeJoin(customcap : *mut GpCustomLineCap, linejoin : *mut LineJoin) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetCustomLineCapType(customcap : *mut GpCustomLineCap, captype : *mut CustomLineCapType) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetCustomLineCapWidthScale(customcap : *mut GpCustomLineCap, widthscale : *mut f32) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetDC(graphics : *mut GpGraphics, hdc : *mut super::Gdi:: HDC) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetDpiX(graphics : *mut GpGraphics, dpi : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetDpiY(graphics : *mut GpGraphics, dpi : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetEffectParameterSize(effect : *mut CGpEffect, size : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetEffectParameters(effect : *mut CGpEffect, size : *mut u32, params : *mut core::ffi::c_void) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetEmHeight(family : *const GpFontFamily, style : i32, emheight : *mut u16) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetEncoderParameterList(image : *mut GpImage, clsidencoder : *const windows_sys::core::GUID, size : u32, buffer : *mut EncoderParameters) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetEncoderParameterListSize(image : *mut GpImage, clsidencoder : *const windows_sys::core::GUID, size : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetFamily(font : *mut GpFont, family : *mut *mut GpFontFamily) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetFamilyName(family : *const GpFontFamily, name : windows_sys::core::PWSTR, language : u16) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetFontCollectionFamilyCount(fontcollection : *mut GpFontCollection, numfound : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetFontCollectionFamilyList(fontcollection : *const GpFontCollection, numsought : i32, gpfamilies : *mut *mut GpFontFamily, numfound : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetFontHeight(font : *const GpFont, graphics : *const GpGraphics, height : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetFontHeightGivenDPI(font : *const GpFont, dpi : f32, height : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetFontSize(font : *mut GpFont, size : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetFontStyle(font : *mut GpFont, style : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetFontUnit(font : *mut GpFont, unit : *mut Unit) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetGenericFontFamilyMonospace(nativefamily : *mut *mut GpFontFamily) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetGenericFontFamilySansSerif(nativefamily : *mut *mut GpFontFamily) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetGenericFontFamilySerif(nativefamily : *mut *mut GpFontFamily) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetHatchBackgroundColor(brush : *mut GpHatch, backcol : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetHatchForegroundColor(brush : *mut GpHatch, forecol : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetHatchStyle(brush : *mut GpHatch, hatchstyle : *mut HatchStyle) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetHemfFromMetafile(metafile : *mut GpMetafile, hemf : *mut super::Gdi:: HENHMETAFILE) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageAttributesAdjustedPalette(imageattr : *mut GpImageAttributes, colorpalette : *mut ColorPalette, coloradjusttype : ColorAdjustType) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageBounds(image : *mut GpImage, srcrect : *mut RectF, srcunit : *mut Unit) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageDecoders(numdecoders : u32, size : u32, decoders : *mut ImageCodecInfo) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageDecodersSize(numdecoders : *mut u32, size : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageDimension(image : *mut GpImage, width : *mut f32, height : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageEncoders(numencoders : u32, size : u32, encoders : *mut ImageCodecInfo) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageEncodersSize(numencoders : *mut u32, size : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageFlags(image : *mut GpImage, flags : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageGraphicsContext(image : *mut GpImage, graphics : *mut *mut GpGraphics) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageHeight(image : *mut GpImage, height : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageHorizontalResolution(image : *mut GpImage, resolution : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageItemData(image : *mut GpImage, item : *mut ImageItemData) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImagePalette(image : *mut GpImage, palette : *mut ColorPalette, size : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImagePaletteSize(image : *mut GpImage, size : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImagePixelFormat(image : *mut GpImage, format : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageRawFormat(image : *mut GpImage, format : *mut windows_sys::core::GUID) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageThumbnail(image : *mut GpImage, thumbwidth : u32, thumbheight : u32, thumbimage : *mut *mut GpImage, callback : isize, callbackdata : *mut core::ffi::c_void) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageType(image : *mut GpImage, r#type : *mut ImageType) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageVerticalResolution(image : *mut GpImage, resolution : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetImageWidth(image : *mut GpImage, width : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetInterpolationMode(graphics : *mut GpGraphics, interpolationmode : *mut InterpolationMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLineBlend(brush : *mut GpLineGradient, blend : *mut f32, positions : *mut f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLineBlendCount(brush : *mut GpLineGradient, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLineColors(brush : *mut GpLineGradient, colors : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLineGammaCorrection(brush : *mut GpLineGradient, usegammacorrection : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLinePresetBlend(brush : *mut GpLineGradient, blend : *mut u32, positions : *mut f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLinePresetBlendCount(brush : *mut GpLineGradient, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLineRect(brush : *mut GpLineGradient, rect : *mut RectF) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLineRectI(brush : *mut GpLineGradient, rect : *mut Rect) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLineSpacing(family : *const GpFontFamily, style : i32, linespacing : *mut u16) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLineTransform(brush : *mut GpLineGradient, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLineWrapMode(brush : *mut GpLineGradient, wrapmode : *mut WrapMode) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLogFontA(font : *mut GpFont, graphics : *mut GpGraphics, logfonta : *mut super::Gdi:: LOGFONTA) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetLogFontW(font : *mut GpFont, graphics : *mut GpGraphics, logfontw : *mut super::Gdi:: LOGFONTW) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetMatrixElements(matrix : *const Matrix, matrixout : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetMetafileDownLevelRasterizationLimit(metafile : *const GpMetafile, metafilerasterizationlimitdpi : *mut u32) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetMetafileHeaderFromEmf(hemf : super::Gdi:: HENHMETAFILE, header : *mut MetafileHeader) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetMetafileHeaderFromFile(filename : windows_sys::core::PCWSTR, header : *mut MetafileHeader) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetMetafileHeaderFromMetafile(metafile : *mut GpMetafile, header : *mut MetafileHeader) -> Status);\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_System_Com\"))]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetMetafileHeaderFromStream(stream : * mut core::ffi::c_void, header : *mut MetafileHeader) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetMetafileHeaderFromWmf(hwmf : super::Gdi:: HMETAFILE, wmfplaceablefileheader : *const WmfPlaceableFileHeader, header : *mut MetafileHeader) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetNearestColor(graphics : *mut GpGraphics, argb : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPageScale(graphics : *mut GpGraphics, scale : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPageUnit(graphics : *mut GpGraphics, unit : *mut Unit) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathData(path : *mut GpPath, pathdata : *mut PathData) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathFillMode(path : *mut GpPath, fillmode : *mut FillMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientBlend(brush : *mut GpPathGradient, blend : *mut f32, positions : *mut f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientBlendCount(brush : *mut GpPathGradient, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientCenterColor(brush : *mut GpPathGradient, colors : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientCenterPoint(brush : *mut GpPathGradient, points : *mut PointF) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientCenterPointI(brush : *mut GpPathGradient, points : *mut Point) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientFocusScales(brush : *mut GpPathGradient, xscale : *mut f32, yscale : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientGammaCorrection(brush : *mut GpPathGradient, usegammacorrection : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientPath(brush : *mut GpPathGradient, path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientPointCount(brush : *mut GpPathGradient, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientPresetBlend(brush : *mut GpPathGradient, blend : *mut u32, positions : *mut f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientPresetBlendCount(brush : *mut GpPathGradient, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientRect(brush : *mut GpPathGradient, rect : *mut RectF) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientRectI(brush : *mut GpPathGradient, rect : *mut Rect) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientSurroundColorCount(brush : *mut GpPathGradient, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientSurroundColorsWithCount(brush : *const GpPathGradient, color : *mut u32, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientTransform(brush : *mut GpPathGradient, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathGradientWrapMode(brush : *mut GpPathGradient, wrapmode : *mut WrapMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathLastPoint(path : *mut GpPath, lastpoint : *mut PointF) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathPoints(param0 : *mut GpPath, points : *mut PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathPointsI(param0 : *mut GpPath, points : *mut Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathTypes(path : *const GpPath, types : *mut u8, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathWorldBounds(path : *mut GpPath, bounds : *mut RectF, matrix : *const Matrix, pen : *const GpPen) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPathWorldBoundsI(path : *mut GpPath, bounds : *mut Rect, matrix : *const Matrix, pen : *const GpPen) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenBrushFill(pen : *mut GpPen, brush : *mut *mut GpBrush) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenColor(pen : *mut GpPen, argb : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenCompoundArray(pen : *mut GpPen, dash : *mut f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenCompoundCount(pen : *mut GpPen, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenCustomEndCap(pen : *mut GpPen, customcap : *mut *mut GpCustomLineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenCustomStartCap(pen : *mut GpPen, customcap : *mut *mut GpCustomLineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenDashArray(pen : *mut GpPen, dash : *mut f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenDashCap197819(pen : *mut GpPen, dashcap : *mut DashCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenDashCount(pen : *mut GpPen, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenDashOffset(pen : *mut GpPen, offset : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenDashStyle(pen : *mut GpPen, dashstyle : *mut DashStyle) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenEndCap(pen : *mut GpPen, endcap : *mut LineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenFillType(pen : *mut GpPen, r#type : *mut PenType) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenLineJoin(pen : *mut GpPen, linejoin : *mut LineJoin) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenMiterLimit(pen : *mut GpPen, miterlimit : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenMode(pen : *mut GpPen, penmode : *mut PenAlignment) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenStartCap(pen : *mut GpPen, startcap : *mut LineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenTransform(pen : *mut GpPen, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenUnit(pen : *mut GpPen, unit : *mut Unit) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPenWidth(pen : *mut GpPen, width : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPixelOffsetMode(graphics : *mut GpGraphics, pixeloffsetmode : *mut PixelOffsetMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPointCount(path : *mut GpPath, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPropertyCount(image : *mut GpImage, numofproperty : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPropertyIdList(image : *mut GpImage, numofproperty : u32, list : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPropertyItem(image : *mut GpImage, propid : u32, propsize : u32, buffer : *mut PropertyItem) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPropertyItemSize(image : *mut GpImage, propid : u32, size : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetPropertySize(image : *mut GpImage, totalbuffersize : *mut u32, numproperties : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetRegionBounds(region : *mut GpRegion, graphics : *mut GpGraphics, rect : *mut RectF) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetRegionBoundsI(region : *mut GpRegion, graphics : *mut GpGraphics, rect : *mut Rect) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetRegionData(region : *mut GpRegion, buffer : *mut u8, buffersize : u32, sizefilled : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetRegionDataSize(region : *mut GpRegion, buffersize : *mut u32) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetRegionHRgn(region : *mut GpRegion, graphics : *mut GpGraphics, hrgn : *mut super::Gdi:: HRGN) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetRegionScans(region : *mut GpRegion, rects : *mut RectF, count : *mut i32, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetRegionScansCount(region : *mut GpRegion, count : *mut u32, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetRegionScansI(region : *mut GpRegion, rects : *mut Rect, count : *mut i32, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetRenderingOrigin(graphics : *mut GpGraphics, x : *mut i32, y : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetSmoothingMode(graphics : *mut GpGraphics, smoothingmode : *mut SmoothingMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetSolidFillColor(brush : *mut GpSolidFill, color : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetStringFormatAlign(format : *const GpStringFormat, align : *mut StringAlignment) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetStringFormatDigitSubstitution(format : *const GpStringFormat, language : *mut u16, substitute : *mut StringDigitSubstitute) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetStringFormatFlags(format : *const GpStringFormat, flags : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetStringFormatHotkeyPrefix(format : *const GpStringFormat, hotkeyprefix : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetStringFormatLineAlign(format : *const GpStringFormat, align : *mut StringAlignment) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetStringFormatMeasurableCharacterRangeCount(format : *const GpStringFormat, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetStringFormatTabStopCount(format : *const GpStringFormat, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetStringFormatTabStops(format : *const GpStringFormat, count : i32, firsttaboffset : *mut f32, tabstops : *mut f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetStringFormatTrimming(format : *const GpStringFormat, trimming : *mut StringTrimming) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetTextContrast(graphics : *mut GpGraphics, contrast : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetTextRenderingHint(graphics : *mut GpGraphics, mode : *mut TextRenderingHint) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetTextureImage(brush : *mut GpTexture, image : *mut *mut GpImage) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetTextureTransform(brush : *mut GpTexture, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetTextureWrapMode(brush : *mut GpTexture, wrapmode : *mut WrapMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetVisibleClipBounds(graphics : *mut GpGraphics, rect : *mut RectF) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetVisibleClipBoundsI(graphics : *mut GpGraphics, rect : *mut Rect) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGetWorldTransform(graphics : *mut GpGraphics, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGraphicsClear(graphics : *mut GpGraphics, color : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipGraphicsSetAbort(pgraphics : *mut GpGraphics, piabort : * mut core::ffi::c_void) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipImageForceValidation(image : *mut GpImage) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipImageGetFrameCount(image : *mut GpImage, dimensionid : *const windows_sys::core::GUID, count : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipImageGetFrameDimensionsCount(image : *mut GpImage, count : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipImageGetFrameDimensionsList(image : *mut GpImage, dimensionids : *mut windows_sys::core::GUID, count : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipImageRotateFlip(image : *mut GpImage, rftype : RotateFlipType) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipImageSelectActiveFrame(image : *mut GpImage, dimensionid : *const windows_sys::core::GUID, frameindex : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipImageSetAbort(pimage : *mut GpImage, piabort : * mut core::ffi::c_void) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipInitializePalette(palette : *mut ColorPalette, palettetype : PaletteType, optimalcolors : i32, usetransparentcolor : windows_sys::core::BOOL, bitmap : *mut GpBitmap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipInvertMatrix(matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsClipEmpty(graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsEmptyRegion(region : *mut GpRegion, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsEqualRegion(region : *mut GpRegion, region2 : *mut GpRegion, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsInfiniteRegion(region : *mut GpRegion, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsMatrixEqual(matrix : *const Matrix, matrix2 : *const Matrix, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsMatrixIdentity(matrix : *const Matrix, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsMatrixInvertible(matrix : *const Matrix, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsOutlineVisiblePathPoint(path : *mut GpPath, x : f32, y : f32, pen : *mut GpPen, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsOutlineVisiblePathPointI(path : *mut GpPath, x : i32, y : i32, pen : *mut GpPen, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsStyleAvailable(family : *const GpFontFamily, style : i32, isstyleavailable : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisibleClipEmpty(graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisiblePathPoint(path : *mut GpPath, x : f32, y : f32, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisiblePathPointI(path : *mut GpPath, x : i32, y : i32, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisiblePoint(graphics : *mut GpGraphics, x : f32, y : f32, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisiblePointI(graphics : *mut GpGraphics, x : i32, y : i32, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisibleRect(graphics : *mut GpGraphics, x : f32, y : f32, width : f32, height : f32, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisibleRectI(graphics : *mut GpGraphics, x : i32, y : i32, width : i32, height : i32, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisibleRegionPoint(region : *mut GpRegion, x : f32, y : f32, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisibleRegionPointI(region : *mut GpRegion, x : i32, y : i32, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisibleRegionRect(region : *mut GpRegion, x : f32, y : f32, width : f32, height : f32, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipIsVisibleRegionRectI(region : *mut GpRegion, x : i32, y : i32, width : i32, height : i32, graphics : *mut GpGraphics, result : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipLoadImageFromFile(filename : windows_sys::core::PCWSTR, image : *mut *mut GpImage) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipLoadImageFromFileICM(filename : windows_sys::core::PCWSTR, image : *mut *mut GpImage) -> Status);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipLoadImageFromStream(stream : * mut core::ffi::c_void, image : *mut *mut GpImage) -> Status);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipLoadImageFromStreamICM(stream : * mut core::ffi::c_void, image : *mut *mut GpImage) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipMeasureCharacterRanges(graphics : *mut GpGraphics, string : windows_sys::core::PCWSTR, length : i32, font : *const GpFont, layoutrect : *const RectF, stringformat : *const GpStringFormat, regioncount : i32, regions : *mut *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipMeasureDriverString(graphics : *mut GpGraphics, text : *const u16, length : i32, font : *const GpFont, positions : *const PointF, flags : i32, matrix : *const Matrix, boundingbox : *mut RectF) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipMeasureString(graphics : *mut GpGraphics, string : windows_sys::core::PCWSTR, length : i32, font : *const GpFont, layoutrect : *const RectF, stringformat : *const GpStringFormat, boundingbox : *mut RectF, codepointsfitted : *mut i32, linesfilled : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipMultiplyLineTransform(brush : *mut GpLineGradient, matrix : *const Matrix, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipMultiplyMatrix(matrix : *mut Matrix, matrix2 : *mut Matrix, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipMultiplyPathGradientTransform(brush : *mut GpPathGradient, matrix : *const Matrix, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipMultiplyPenTransform(pen : *mut GpPen, matrix : *const Matrix, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipMultiplyTextureTransform(brush : *mut GpTexture, matrix : *const Matrix, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipMultiplyWorldTransform(graphics : *mut GpGraphics, matrix : *const Matrix, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipNewInstalledFontCollection(fontcollection : *mut *mut GpFontCollection) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipNewPrivateFontCollection(fontcollection : *mut *mut GpFontCollection) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterCopyData(iterator : *mut GpPathIterator, resultcount : *mut i32, points : *mut PointF, types : *mut u8, startindex : i32, endindex : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterEnumerate(iterator : *mut GpPathIterator, resultcount : *mut i32, points : *mut PointF, types : *mut u8, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterGetCount(iterator : *mut GpPathIterator, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterGetSubpathCount(iterator : *mut GpPathIterator, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterHasCurve(iterator : *mut GpPathIterator, hascurve : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterIsValid(iterator : *mut GpPathIterator, valid : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterNextMarker(iterator : *mut GpPathIterator, resultcount : *mut i32, startindex : *mut i32, endindex : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterNextMarkerPath(iterator : *mut GpPathIterator, resultcount : *mut i32, path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterNextPathType(iterator : *mut GpPathIterator, resultcount : *mut i32, pathtype : *mut u8, startindex : *mut i32, endindex : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterNextSubpath(iterator : *mut GpPathIterator, resultcount : *mut i32, startindex : *mut i32, endindex : *mut i32, isclosed : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterNextSubpathPath(iterator : *mut GpPathIterator, resultcount : *mut i32, path : *mut GpPath, isclosed : *mut windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPathIterRewind(iterator : *mut GpPathIterator) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPlayMetafileRecord(metafile : *const GpMetafile, recordtype : EmfPlusRecordType, flags : u32, datasize : u32, data : *const u8) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPrivateAddFontFile(fontcollection : *mut GpFontCollection, filename : windows_sys::core::PCWSTR) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipPrivateAddMemoryFont(fontcollection : *mut GpFontCollection, memory : *const core::ffi::c_void, length : i32) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRecordMetafile(referencehdc : super::Gdi:: HDC, r#type : EmfType, framerect : *const RectF, frameunit : MetafileFrameUnit, description : windows_sys::core::PCWSTR, metafile : *mut *mut GpMetafile) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRecordMetafileFileName(filename : windows_sys::core::PCWSTR, referencehdc : super::Gdi:: HDC, r#type : EmfType, framerect : *const RectF, frameunit : MetafileFrameUnit, description : windows_sys::core::PCWSTR, metafile : *mut *mut GpMetafile) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRecordMetafileFileNameI(filename : windows_sys::core::PCWSTR, referencehdc : super::Gdi:: HDC, r#type : EmfType, framerect : *const Rect, frameunit : MetafileFrameUnit, description : windows_sys::core::PCWSTR, metafile : *mut *mut GpMetafile) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRecordMetafileI(referencehdc : super::Gdi:: HDC, r#type : EmfType, framerect : *const Rect, frameunit : MetafileFrameUnit, description : windows_sys::core::PCWSTR, metafile : *mut *mut GpMetafile) -> Status);\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_System_Com\"))]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRecordMetafileStream(stream : * mut core::ffi::c_void, referencehdc : super::Gdi:: HDC, r#type : EmfType, framerect : *const RectF, frameunit : MetafileFrameUnit, description : windows_sys::core::PCWSTR, metafile : *mut *mut GpMetafile) -> Status);\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_System_Com\"))]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRecordMetafileStreamI(stream : * mut core::ffi::c_void, referencehdc : super::Gdi:: HDC, r#type : EmfType, framerect : *const Rect, frameunit : MetafileFrameUnit, description : windows_sys::core::PCWSTR, metafile : *mut *mut GpMetafile) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipReleaseDC(graphics : *mut GpGraphics, hdc : super::Gdi:: HDC) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRemovePropertyItem(image : *mut GpImage, propid : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipResetClip(graphics : *mut GpGraphics) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipResetImageAttributes(imageattr : *mut GpImageAttributes, r#type : ColorAdjustType) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipResetLineTransform(brush : *mut GpLineGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipResetPageTransform(graphics : *mut GpGraphics) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipResetPath(path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipResetPathGradientTransform(brush : *mut GpPathGradient) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipResetPenTransform(pen : *mut GpPen) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipResetTextureTransform(brush : *mut GpTexture) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipResetWorldTransform(graphics : *mut GpGraphics) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRestoreGraphics(graphics : *mut GpGraphics, state : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipReversePath(path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRotateLineTransform(brush : *mut GpLineGradient, angle : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRotateMatrix(matrix : *mut Matrix, angle : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRotatePathGradientTransform(brush : *mut GpPathGradient, angle : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRotatePenTransform(pen : *mut GpPen, angle : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRotateTextureTransform(brush : *mut GpTexture, angle : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipRotateWorldTransform(graphics : *mut GpGraphics, angle : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSaveAdd(image : *mut GpImage, encoderparams : *const EncoderParameters) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSaveAddImage(image : *mut GpImage, newimage : *mut GpImage, encoderparams : *const EncoderParameters) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSaveGraphics(graphics : *mut GpGraphics, state : *mut u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSaveImageToFile(image : *mut GpImage, filename : windows_sys::core::PCWSTR, clsidencoder : *const windows_sys::core::GUID, encoderparams : *const EncoderParameters) -> Status);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSaveImageToStream(image : *mut GpImage, stream : * mut core::ffi::c_void, clsidencoder : *const windows_sys::core::GUID, encoderparams : *const EncoderParameters) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipScaleLineTransform(brush : *mut GpLineGradient, sx : f32, sy : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipScaleMatrix(matrix : *mut Matrix, scalex : f32, scaley : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipScalePathGradientTransform(brush : *mut GpPathGradient, sx : f32, sy : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipScalePenTransform(pen : *mut GpPen, sx : f32, sy : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipScaleTextureTransform(brush : *mut GpTexture, sx : f32, sy : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipScaleWorldTransform(graphics : *mut GpGraphics, sx : f32, sy : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetAdjustableArrowCapFillState(cap : *mut GpAdjustableArrowCap, fillstate : windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetAdjustableArrowCapHeight(cap : *mut GpAdjustableArrowCap, height : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetAdjustableArrowCapMiddleInset(cap : *mut GpAdjustableArrowCap, middleinset : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetAdjustableArrowCapWidth(cap : *mut GpAdjustableArrowCap, width : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetClipGraphics(graphics : *mut GpGraphics, srcgraphics : *mut GpGraphics, combinemode : CombineMode) -> Status);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetClipHrgn(graphics : *mut GpGraphics, hrgn : super::Gdi:: HRGN, combinemode : CombineMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetClipPath(graphics : *mut GpGraphics, path : *mut GpPath, combinemode : CombineMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetClipRect(graphics : *mut GpGraphics, x : f32, y : f32, width : f32, height : f32, combinemode : CombineMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetClipRectI(graphics : *mut GpGraphics, x : i32, y : i32, width : i32, height : i32, combinemode : CombineMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetClipRegion(graphics : *mut GpGraphics, region : *mut GpRegion, combinemode : CombineMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetCompositingMode(graphics : *mut GpGraphics, compositingmode : CompositingMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetCompositingQuality(graphics : *mut GpGraphics, compositingquality : CompositingQuality) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetCustomLineCapBaseCap(customcap : *mut GpCustomLineCap, basecap : LineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetCustomLineCapBaseInset(customcap : *mut GpCustomLineCap, inset : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetCustomLineCapStrokeCaps(customcap : *mut GpCustomLineCap, startcap : LineCap, endcap : LineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetCustomLineCapStrokeJoin(customcap : *mut GpCustomLineCap, linejoin : LineJoin) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetCustomLineCapWidthScale(customcap : *mut GpCustomLineCap, widthscale : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetEffectParameters(effect : *mut CGpEffect, params : *const core::ffi::c_void, size : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetEmpty(region : *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesCachedBackground(imageattr : *mut GpImageAttributes, enableflag : windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesColorKeys(imageattr : *mut GpImageAttributes, r#type : ColorAdjustType, enableflag : windows_sys::core::BOOL, colorlow : u32, colorhigh : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesColorMatrix(imageattr : *mut GpImageAttributes, r#type : ColorAdjustType, enableflag : windows_sys::core::BOOL, colormatrix : *const ColorMatrix, graymatrix : *const ColorMatrix, flags : ColorMatrixFlags) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesGamma(imageattr : *mut GpImageAttributes, r#type : ColorAdjustType, enableflag : windows_sys::core::BOOL, gamma : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesNoOp(imageattr : *mut GpImageAttributes, r#type : ColorAdjustType, enableflag : windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesOutputChannel(imageattr : *mut GpImageAttributes, r#type : ColorAdjustType, enableflag : windows_sys::core::BOOL, channelflags : ColorChannelFlags) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesOutputChannelColorProfile(imageattr : *mut GpImageAttributes, r#type : ColorAdjustType, enableflag : windows_sys::core::BOOL, colorprofilefilename : windows_sys::core::PCWSTR) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesRemapTable(imageattr : *mut GpImageAttributes, r#type : ColorAdjustType, enableflag : windows_sys::core::BOOL, mapsize : u32, map : *const ColorMap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesThreshold(imageattr : *mut GpImageAttributes, r#type : ColorAdjustType, enableflag : windows_sys::core::BOOL, threshold : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesToIdentity(imageattr : *mut GpImageAttributes, r#type : ColorAdjustType) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImageAttributesWrapMode(imageattr : *mut GpImageAttributes, wrap : WrapMode, argb : u32, clamp : windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetImagePalette(image : *mut GpImage, palette : *const ColorPalette) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetInfinite(region : *mut GpRegion) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetInterpolationMode(graphics : *mut GpGraphics, interpolationmode : InterpolationMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetLineBlend(brush : *mut GpLineGradient, blend : *const f32, positions : *const f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetLineColors(brush : *mut GpLineGradient, color1 : u32, color2 : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetLineGammaCorrection(brush : *mut GpLineGradient, usegammacorrection : windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetLineLinearBlend(brush : *mut GpLineGradient, focus : f32, scale : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetLinePresetBlend(brush : *mut GpLineGradient, blend : *const u32, positions : *const f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetLineSigmaBlend(brush : *mut GpLineGradient, focus : f32, scale : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetLineTransform(brush : *mut GpLineGradient, matrix : *const Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetLineWrapMode(brush : *mut GpLineGradient, wrapmode : WrapMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetMatrixElements(matrix : *mut Matrix, m11 : f32, m12 : f32, m21 : f32, m22 : f32, dx : f32, dy : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetMetafileDownLevelRasterizationLimit(metafile : *mut GpMetafile, metafilerasterizationlimitdpi : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPageScale(graphics : *mut GpGraphics, scale : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPageUnit(graphics : *mut GpGraphics, unit : Unit) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathFillMode(path : *mut GpPath, fillmode : FillMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientBlend(brush : *mut GpPathGradient, blend : *const f32, positions : *const f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientCenterColor(brush : *mut GpPathGradient, colors : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientCenterPoint(brush : *mut GpPathGradient, points : *const PointF) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientCenterPointI(brush : *mut GpPathGradient, points : *const Point) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientFocusScales(brush : *mut GpPathGradient, xscale : f32, yscale : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientGammaCorrection(brush : *mut GpPathGradient, usegammacorrection : windows_sys::core::BOOL) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientLinearBlend(brush : *mut GpPathGradient, focus : f32, scale : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientPath(brush : *mut GpPathGradient, path : *const GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientPresetBlend(brush : *mut GpPathGradient, blend : *const u32, positions : *const f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientSigmaBlend(brush : *mut GpPathGradient, focus : f32, scale : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientSurroundColorsWithCount(brush : *mut GpPathGradient, color : *const u32, count : *mut i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientTransform(brush : *mut GpPathGradient, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathGradientWrapMode(brush : *mut GpPathGradient, wrapmode : WrapMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPathMarker(path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenBrushFill(pen : *mut GpPen, brush : *mut GpBrush) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenColor(pen : *mut GpPen, argb : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenCompoundArray(pen : *mut GpPen, dash : *const f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenCustomEndCap(pen : *mut GpPen, customcap : *mut GpCustomLineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenCustomStartCap(pen : *mut GpPen, customcap : *mut GpCustomLineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenDashArray(pen : *mut GpPen, dash : *const f32, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenDashCap197819(pen : *mut GpPen, dashcap : DashCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenDashOffset(pen : *mut GpPen, offset : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenDashStyle(pen : *mut GpPen, dashstyle : DashStyle) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenEndCap(pen : *mut GpPen, endcap : LineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenLineCap197819(pen : *mut GpPen, startcap : LineCap, endcap : LineCap, dashcap : DashCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenLineJoin(pen : *mut GpPen, linejoin : LineJoin) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenMiterLimit(pen : *mut GpPen, miterlimit : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenMode(pen : *mut GpPen, penmode : PenAlignment) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenStartCap(pen : *mut GpPen, startcap : LineCap) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenTransform(pen : *mut GpPen, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenUnit(pen : *mut GpPen, unit : Unit) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPenWidth(pen : *mut GpPen, width : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPixelOffsetMode(graphics : *mut GpGraphics, pixeloffsetmode : PixelOffsetMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetPropertyItem(image : *mut GpImage, item : *const PropertyItem) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetRenderingOrigin(graphics : *mut GpGraphics, x : i32, y : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetSmoothingMode(graphics : *mut GpGraphics, smoothingmode : SmoothingMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetSolidFillColor(brush : *mut GpSolidFill, color : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetStringFormatAlign(format : *mut GpStringFormat, align : StringAlignment) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetStringFormatDigitSubstitution(format : *mut GpStringFormat, language : u16, substitute : StringDigitSubstitute) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetStringFormatFlags(format : *mut GpStringFormat, flags : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetStringFormatHotkeyPrefix(format : *mut GpStringFormat, hotkeyprefix : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetStringFormatLineAlign(format : *mut GpStringFormat, align : StringAlignment) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetStringFormatMeasurableCharacterRanges(format : *mut GpStringFormat, rangecount : i32, ranges : *const CharacterRange) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetStringFormatTabStops(format : *mut GpStringFormat, firsttaboffset : f32, count : i32, tabstops : *const f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetStringFormatTrimming(format : *mut GpStringFormat, trimming : StringTrimming) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetTextContrast(graphics : *mut GpGraphics, contrast : u32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetTextRenderingHint(graphics : *mut GpGraphics, mode : TextRenderingHint) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetTextureTransform(brush : *mut GpTexture, matrix : *const Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetTextureWrapMode(brush : *mut GpTexture, wrapmode : WrapMode) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipSetWorldTransform(graphics : *mut GpGraphics, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipShearMatrix(matrix : *mut Matrix, shearx : f32, sheary : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipStartPathFigure(path : *mut GpPath) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipStringFormatGetGenericDefault(format : *mut *mut GpStringFormat) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipStringFormatGetGenericTypographic(format : *mut *mut GpStringFormat) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTestControl(control : GpTestControlEnum, param1 : *mut core::ffi::c_void) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTransformMatrixPoints(matrix : *mut Matrix, pts : *mut PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTransformMatrixPointsI(matrix : *mut Matrix, pts : *mut Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTransformPath(path : *mut GpPath, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTransformPoints(graphics : *mut GpGraphics, destspace : CoordinateSpace, srcspace : CoordinateSpace, points : *mut PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTransformPointsI(graphics : *mut GpGraphics, destspace : CoordinateSpace, srcspace : CoordinateSpace, points : *mut Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTransformRegion(region : *mut GpRegion, matrix : *mut Matrix) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTranslateClip(graphics : *mut GpGraphics, dx : f32, dy : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTranslateClipI(graphics : *mut GpGraphics, dx : i32, dy : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTranslateLineTransform(brush : *mut GpLineGradient, dx : f32, dy : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTranslateMatrix(matrix : *mut Matrix, offsetx : f32, offsety : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTranslatePathGradientTransform(brush : *mut GpPathGradient, dx : f32, dy : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTranslatePenTransform(pen : *mut GpPen, dx : f32, dy : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTranslateRegion(region : *mut GpRegion, dx : f32, dy : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTranslateRegionI(region : *mut GpRegion, dx : i32, dy : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTranslateTextureTransform(brush : *mut GpTexture, dx : f32, dy : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipTranslateWorldTransform(graphics : *mut GpGraphics, dx : f32, dy : f32, order : MatrixOrder) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipVectorTransformMatrixPoints(matrix : *mut Matrix, pts : *mut PointF, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipVectorTransformMatrixPointsI(matrix : *mut Matrix, pts : *mut Point, count : i32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipWarpPath(path : *mut GpPath, matrix : *mut Matrix, points : *const PointF, count : i32, srcx : f32, srcy : f32, srcwidth : f32, srcheight : f32, warpmode : WarpMode, flatness : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipWidenPath(nativepath : *mut GpPath, pen : *mut GpPen, matrix : *mut Matrix, flatness : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdipWindingModeOutline(path : *mut GpPath, matrix : *mut Matrix, flatness : f32) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdiplusNotificationHook(token : *mut usize) -> Status);\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdiplusNotificationUnhook(token : usize));\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdiplusShutdown(token : usize));\nwindows_link::link!(\"gdiplus.dll\" \"system\" fn GdiplusStartup(token : *mut usize, input : *const GdiplusStartupInput, output : *mut GdiplusStartupOutput) -> Status);\npub const ALPHA_SHIFT: u32 = 24u32;\npub const Aborted: Status = 9i32;\npub const AccessDenied: Status = 12i32;\npub const AdjustBlackSaturation: CurveAdjustments = 7i32;\npub const AdjustContrast: CurveAdjustments = 2i32;\npub const AdjustDensity: CurveAdjustments = 1i32;\npub const AdjustExposure: CurveAdjustments = 0i32;\npub const AdjustHighlight: CurveAdjustments = 3i32;\npub const AdjustMidtone: CurveAdjustments = 5i32;\npub const AdjustShadow: CurveAdjustments = 4i32;\npub const AdjustWhiteSaturation: CurveAdjustments = 6i32;\npub const BLUE_SHIFT: u32 = 0u32;\npub type Bitmap = isize;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct BitmapData {\n    pub Width: u32,\n    pub Height: u32,\n    pub Stride: i32,\n    pub PixelFormat: i32,\n    pub Scan0: *mut core::ffi::c_void,\n    pub Reserved: usize,\n}\nimpl Default for BitmapData {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct Blur {\n    pub Base: Effect,\n}\npub const BlurEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x633c80a4_1843_482b_9ef2_be2834c5fdd4);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct BlurParams {\n    pub radius: f32,\n    pub expandEdge: windows_sys::core::BOOL,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct BrightnessContrast {\n    pub Base: Effect,\n}\npub const BrightnessContrastEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd3a1dbe1_8ec4_4c17_9f4c_ea97ad1c343d);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct BrightnessContrastParams {\n    pub brightnessLevel: i32,\n    pub contrastLevel: i32,\n}\npub type BrushType = i32;\npub const BrushTypeHatchFill: BrushType = 1i32;\npub const BrushTypeLinearGradient: BrushType = 4i32;\npub const BrushTypePathGradient: BrushType = 3i32;\npub const BrushTypeSolidColor: BrushType = 0i32;\npub const BrushTypeTextureFill: BrushType = 2i32;\npub type CGpEffect = isize;\npub type CachedBitmap = isize;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CharacterRange {\n    pub First: i32,\n    pub Length: i32,\n}\npub const CodecIImageBytes: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x025d1823_6c7d_447b_bbdb_a3cbc3dfa2fc);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct Color {\n    pub Argb: u32,\n}\nimpl Color {\n    pub const AliceBlue: i32 = -984833i32;\n    pub const AntiqueWhite: i32 = -332841i32;\n    pub const Aqua: i32 = -16711681i32;\n    pub const Aquamarine: i32 = -8388652i32;\n    pub const Azure: i32 = -983041i32;\n    pub const Beige: i32 = -657956i32;\n    pub const Bisque: i32 = -6972i32;\n    pub const Black: i32 = -16777216i32;\n    pub const BlanchedAlmond: i32 = -5171i32;\n    pub const Blue: i32 = -16776961i32;\n    pub const BlueViolet: i32 = -7722014i32;\n    pub const Brown: i32 = -5952982i32;\n    pub const BurlyWood: i32 = -2180985i32;\n    pub const CadetBlue: i32 = -10510688i32;\n    pub const Chartreuse: i32 = -8388864i32;\n    pub const Chocolate: i32 = -2987746i32;\n    pub const Coral: i32 = -32944i32;\n    pub const CornflowerBlue: i32 = -10185235i32;\n    pub const Cornsilk: i32 = -1828i32;\n    pub const Crimson: i32 = -2354116i32;\n    pub const Cyan: i32 = -16711681i32;\n    pub const DarkBlue: i32 = -16777077i32;\n    pub const DarkCyan: i32 = -16741493i32;\n    pub const DarkGoldenrod: i32 = -4684277i32;\n    pub const DarkGray: i32 = -5658199i32;\n    pub const DarkGreen: i32 = -16751616i32;\n    pub const DarkKhaki: i32 = -4343957i32;\n    pub const DarkMagenta: i32 = -7667573i32;\n    pub const DarkOliveGreen: i32 = -11179217i32;\n    pub const DarkOrange: i32 = -29696i32;\n    pub const DarkOrchid: i32 = -6737204i32;\n    pub const DarkRed: i32 = -7667712i32;\n    pub const DarkSalmon: i32 = -1468806i32;\n    pub const DarkSeaGreen: i32 = -7357301i32;\n    pub const DarkSlateBlue: i32 = -12042869i32;\n    pub const DarkSlateGray: i32 = -13676721i32;\n    pub const DarkTurquoise: i32 = -16724271i32;\n    pub const DarkViolet: i32 = -7077677i32;\n    pub const DeepPink: i32 = -60269i32;\n    pub const DeepSkyBlue: i32 = -16728065i32;\n    pub const DimGray: i32 = -9868951i32;\n    pub const DodgerBlue: i32 = -14774017i32;\n    pub const Firebrick: i32 = -5103070i32;\n    pub const FloralWhite: i32 = -1296i32;\n    pub const ForestGreen: i32 = -14513374i32;\n    pub const Fuchsia: i32 = -65281i32;\n    pub const Gainsboro: i32 = -2302756i32;\n    pub const GhostWhite: i32 = -460545i32;\n    pub const Gold: i32 = -10496i32;\n    pub const Goldenrod: i32 = -2448096i32;\n    pub const Gray: i32 = -8355712i32;\n    pub const Green: i32 = -16744448i32;\n    pub const GreenYellow: i32 = -5374161i32;\n    pub const Honeydew: i32 = -983056i32;\n    pub const HotPink: i32 = -38476i32;\n    pub const IndianRed: i32 = -3318692i32;\n    pub const Indigo: i32 = -11861886i32;\n    pub const Ivory: i32 = -16i32;\n    pub const Khaki: i32 = -989556i32;\n    pub const Lavender: i32 = -1644806i32;\n    pub const LavenderBlush: i32 = -3851i32;\n    pub const LawnGreen: i32 = -8586240i32;\n    pub const LemonChiffon: i32 = -1331i32;\n    pub const LightBlue: i32 = -5383962i32;\n    pub const LightCoral: i32 = -1015680i32;\n    pub const LightCyan: i32 = -2031617i32;\n    pub const LightGoldenrodYellow: i32 = -329006i32;\n    pub const LightGray: i32 = -2894893i32;\n    pub const LightGreen: i32 = -7278960i32;\n    pub const LightPink: i32 = -18751i32;\n    pub const LightSalmon: i32 = -24454i32;\n    pub const LightSeaGreen: i32 = -14634326i32;\n    pub const LightSkyBlue: i32 = -7876870i32;\n    pub const LightSlateGray: i32 = -8943463i32;\n    pub const LightSteelBlue: i32 = -5192482i32;\n    pub const LightYellow: i32 = -32i32;\n    pub const Lime: i32 = -16711936i32;\n    pub const LimeGreen: i32 = -13447886i32;\n    pub const Linen: i32 = -331546i32;\n    pub const Magenta: i32 = -65281i32;\n    pub const Maroon: i32 = -8388608i32;\n    pub const MediumAquamarine: i32 = -10039894i32;\n    pub const MediumBlue: i32 = -16777011i32;\n    pub const MediumOrchid: i32 = -4565549i32;\n    pub const MediumPurple: i32 = -7114533i32;\n    pub const MediumSeaGreen: i32 = -12799119i32;\n    pub const MediumSlateBlue: i32 = -8689426i32;\n    pub const MediumSpringGreen: i32 = -16713062i32;\n    pub const MediumTurquoise: i32 = -12004916i32;\n    pub const MediumVioletRed: i32 = -3730043i32;\n    pub const MidnightBlue: i32 = -15132304i32;\n    pub const MintCream: i32 = -655366i32;\n    pub const MistyRose: i32 = -6943i32;\n    pub const Moccasin: i32 = -6987i32;\n    pub const NavajoWhite: i32 = -8531i32;\n    pub const Navy: i32 = -16777088i32;\n    pub const OldLace: i32 = -133658i32;\n    pub const Olive: i32 = -8355840i32;\n    pub const OliveDrab: i32 = -9728477i32;\n    pub const Orange: i32 = -23296i32;\n    pub const OrangeRed: i32 = -47872i32;\n    pub const Orchid: i32 = -2461482i32;\n    pub const PaleGoldenrod: i32 = -1120086i32;\n    pub const PaleGreen: i32 = -6751336i32;\n    pub const PaleTurquoise: i32 = -5247250i32;\n    pub const PaleVioletRed: i32 = -2396013i32;\n    pub const PapayaWhip: i32 = -4139i32;\n    pub const PeachPuff: i32 = -9543i32;\n    pub const Peru: i32 = -3308225i32;\n    pub const Pink: i32 = -16181i32;\n    pub const Plum: i32 = -2252579i32;\n    pub const PowderBlue: i32 = -5185306i32;\n    pub const Purple: i32 = -8388480i32;\n    pub const Red: i32 = -65536i32;\n    pub const RosyBrown: i32 = -4419697i32;\n    pub const RoyalBlue: i32 = -12490271i32;\n    pub const SaddleBrown: i32 = -7650029i32;\n    pub const Salmon: i32 = -360334i32;\n    pub const SandyBrown: i32 = -744352i32;\n    pub const SeaGreen: i32 = -13726889i32;\n    pub const SeaShell: i32 = -2578i32;\n    pub const Sienna: i32 = -6270419i32;\n    pub const Silver: i32 = -4144960i32;\n    pub const SkyBlue: i32 = -7876885i32;\n    pub const SlateBlue: i32 = -9807155i32;\n    pub const SlateGray: i32 = -9404272i32;\n    pub const Snow: i32 = -1286i32;\n    pub const SpringGreen: i32 = -16711809i32;\n    pub const SteelBlue: i32 = -12156236i32;\n    pub const Tan: i32 = -2968436i32;\n    pub const Teal: i32 = -16744320i32;\n    pub const Thistle: i32 = -2572328i32;\n    pub const Tomato: i32 = -40121i32;\n    pub const Transparent: i32 = 16777215i32;\n    pub const Turquoise: i32 = -12525360i32;\n    pub const Violet: i32 = -1146130i32;\n    pub const Wheat: i32 = -663885i32;\n    pub const White: i32 = -1i32;\n    pub const WhiteSmoke: i32 = -657931i32;\n    pub const Yellow: i32 = -256i32;\n    pub const YellowGreen: i32 = -6632142i32;\n    pub const AlphaShift: i32 = 24i32;\n    pub const RedShift: i32 = 16i32;\n    pub const GreenShift: i32 = 8i32;\n    pub const BlueShift: i32 = 0i32;\n    pub const AlphaMask: i32 = -16777216i32;\n    pub const RedMask: i32 = 16711680i32;\n    pub const GreenMask: i32 = 65280i32;\n    pub const BlueMask: i32 = 255i32;\n}\npub type ColorAdjustType = i32;\npub const ColorAdjustTypeAny: ColorAdjustType = 6i32;\npub const ColorAdjustTypeBitmap: ColorAdjustType = 1i32;\npub const ColorAdjustTypeBrush: ColorAdjustType = 2i32;\npub const ColorAdjustTypeCount: ColorAdjustType = 5i32;\npub const ColorAdjustTypeDefault: ColorAdjustType = 0i32;\npub const ColorAdjustTypePen: ColorAdjustType = 3i32;\npub const ColorAdjustTypeText: ColorAdjustType = 4i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ColorBalance {\n    pub Base: Effect,\n}\npub const ColorBalanceEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x537e597d_251e_48da_9664_29ca496b70f8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ColorBalanceParams {\n    pub cyanRed: i32,\n    pub magentaGreen: i32,\n    pub yellowBlue: i32,\n}\npub type ColorChannelFlags = i32;\npub const ColorChannelFlagsC: ColorChannelFlags = 0i32;\npub const ColorChannelFlagsK: ColorChannelFlags = 3i32;\npub const ColorChannelFlagsLast: ColorChannelFlags = 4i32;\npub const ColorChannelFlagsM: ColorChannelFlags = 1i32;\npub const ColorChannelFlagsY: ColorChannelFlags = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ColorCurve {\n    pub Base: Effect,\n}\npub const ColorCurveEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdd6a0022_58e4_4a67_9d9b_d48eb881a53d);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ColorCurveParams {\n    pub adjustment: CurveAdjustments,\n    pub channel: CurveChannel,\n    pub adjustValue: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ColorLUT {\n    pub Base: Effect,\n}\npub const ColorLUTEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa7ce72a9_0f7f_40d7_b3cc_d0c02d5c3212);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ColorLUTParams {\n    pub lutB: [u8; 256],\n    pub lutG: [u8; 256],\n    pub lutR: [u8; 256],\n    pub lutA: [u8; 256],\n}\nimpl Default for ColorLUTParams {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ColorMap {\n    pub oldColor: Color,\n    pub newColor: Color,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ColorMatrix {\n    pub m: [f32; 25],\n}\nimpl Default for ColorMatrix {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ColorMatrixEffect {\n    pub Base: Effect,\n}\npub const ColorMatrixEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x718f2615_7933_40e3_a511_5f68fe14dd74);\npub type ColorMatrixFlags = i32;\npub const ColorMatrixFlagsAltGray: ColorMatrixFlags = 2i32;\npub const ColorMatrixFlagsDefault: ColorMatrixFlags = 0i32;\npub const ColorMatrixFlagsSkipGrays: ColorMatrixFlags = 1i32;\npub type ColorMode = i32;\npub const ColorModeARGB32: ColorMode = 0i32;\npub const ColorModeARGB64: ColorMode = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ColorPalette {\n    pub Flags: u32,\n    pub Count: u32,\n    pub Entries: [u32; 1],\n}\nimpl Default for ColorPalette {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type CombineMode = i32;\npub const CombineModeComplement: CombineMode = 5i32;\npub const CombineModeExclude: CombineMode = 4i32;\npub const CombineModeIntersect: CombineMode = 1i32;\npub const CombineModeReplace: CombineMode = 0i32;\npub const CombineModeUnion: CombineMode = 2i32;\npub const CombineModeXor: CombineMode = 3i32;\npub type CompositingMode = i32;\npub const CompositingModeSourceCopy: CompositingMode = 1i32;\npub const CompositingModeSourceOver: CompositingMode = 0i32;\npub type CompositingQuality = i32;\npub const CompositingQualityAssumeLinear: CompositingQuality = 4i32;\npub const CompositingQualityDefault: CompositingQuality = 0i32;\npub const CompositingQualityGammaCorrected: CompositingQuality = 3i32;\npub const CompositingQualityHighQuality: CompositingQuality = 2i32;\npub const CompositingQualityHighSpeed: CompositingQuality = 1i32;\npub const CompositingQualityInvalid: CompositingQuality = -1i32;\npub type ConvertToEmfPlusFlags = i32;\npub const ConvertToEmfPlusFlagsDefault: ConvertToEmfPlusFlags = 0i32;\npub const ConvertToEmfPlusFlagsInvalidRecord: ConvertToEmfPlusFlags = 4i32;\npub const ConvertToEmfPlusFlagsRopUsed: ConvertToEmfPlusFlags = 1i32;\npub const ConvertToEmfPlusFlagsText: ConvertToEmfPlusFlags = 2i32;\npub type CoordinateSpace = i32;\npub const CoordinateSpaceDevice: CoordinateSpace = 2i32;\npub const CoordinateSpacePage: CoordinateSpace = 1i32;\npub const CoordinateSpaceWorld: CoordinateSpace = 0i32;\npub type CurveAdjustments = i32;\npub type CurveChannel = i32;\npub const CurveChannelAll: CurveChannel = 0i32;\npub const CurveChannelBlue: CurveChannel = 3i32;\npub const CurveChannelGreen: CurveChannel = 2i32;\npub const CurveChannelRed: CurveChannel = 1i32;\npub type CustomLineCap = isize;\npub type CustomLineCapType = i32;\npub const CustomLineCapTypeAdjustableArrow: CustomLineCapType = 1i32;\npub const CustomLineCapTypeDefault: CustomLineCapType = 0i32;\npub type DashCap = i32;\npub const DashCapFlat: DashCap = 0i32;\npub const DashCapRound: DashCap = 2i32;\npub const DashCapTriangle: DashCap = 3i32;\npub type DashStyle = i32;\npub const DashStyleCustom: DashStyle = 5i32;\npub const DashStyleDash: DashStyle = 1i32;\npub const DashStyleDashDot: DashStyle = 3i32;\npub const DashStyleDashDotDot: DashStyle = 4i32;\npub const DashStyleDot: DashStyle = 2i32;\npub const DashStyleSolid: DashStyle = 0i32;\npub type DebugEventLevel = i32;\npub const DebugEventLevelFatal: DebugEventLevel = 0i32;\npub const DebugEventLevelWarning: DebugEventLevel = 1i32;\npub type DebugEventProc = Option<unsafe extern \"system\" fn(level: DebugEventLevel, message: windows_sys::core::PCSTR)>;\npub type DitherType = i32;\npub const DitherTypeDualSpiral4x4: DitherType = 7i32;\npub const DitherTypeDualSpiral8x8: DitherType = 8i32;\npub const DitherTypeErrorDiffusion: DitherType = 9i32;\npub const DitherTypeMax: DitherType = 10i32;\npub const DitherTypeNone: DitherType = 0i32;\npub const DitherTypeOrdered16x16: DitherType = 4i32;\npub const DitherTypeOrdered4x4: DitherType = 2i32;\npub const DitherTypeOrdered8x8: DitherType = 3i32;\npub const DitherTypeSolid: DitherType = 1i32;\npub const DitherTypeSpiral4x4: DitherType = 5i32;\npub const DitherTypeSpiral8x8: DitherType = 6i32;\npub type DrawImageAbort = Option<unsafe extern \"system\" fn() -> windows_sys::core::BOOL>;\npub type DriverStringOptions = i32;\npub const DriverStringOptionsCmapLookup: DriverStringOptions = 1i32;\npub const DriverStringOptionsLimitSubpixel: DriverStringOptions = 8i32;\npub const DriverStringOptionsRealizedAdvance: DriverStringOptions = 4i32;\npub const DriverStringOptionsVertical: DriverStringOptions = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ENHMETAHEADER3 {\n    pub iType: u32,\n    pub nSize: u32,\n    pub rclBounds: super::super::Foundation::RECTL,\n    pub rclFrame: super::super::Foundation::RECTL,\n    pub dSignature: u32,\n    pub nVersion: u32,\n    pub nBytes: u32,\n    pub nRecords: u32,\n    pub nHandles: u16,\n    pub sReserved: u16,\n    pub nDescription: u32,\n    pub offDescription: u32,\n    pub nPalEntries: u32,\n    pub szlDevice: super::super::Foundation::SIZE,\n    pub szlMillimeters: super::super::Foundation::SIZE,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct Effect {\n    pub lpVtbl: *mut *mut core::ffi::c_void,\n    pub nativeEffect: *mut CGpEffect,\n    pub auxDataSize: i32,\n    pub auxData: *mut core::ffi::c_void,\n    pub useAuxData: windows_sys::core::BOOL,\n}\nimpl Default for Effect {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const EmfPlusRecordTotal: EmfPlusRecordType = 16443i32;\npub type EmfPlusRecordType = i32;\npub const EmfPlusRecordTypeBeginContainer: EmfPlusRecordType = 16423i32;\npub const EmfPlusRecordTypeBeginContainerNoParams: EmfPlusRecordType = 16424i32;\npub const EmfPlusRecordTypeClear: EmfPlusRecordType = 16393i32;\npub const EmfPlusRecordTypeComment: EmfPlusRecordType = 16387i32;\npub const EmfPlusRecordTypeDrawArc: EmfPlusRecordType = 16402i32;\npub const EmfPlusRecordTypeDrawBeziers: EmfPlusRecordType = 16409i32;\npub const EmfPlusRecordTypeDrawClosedCurve: EmfPlusRecordType = 16407i32;\npub const EmfPlusRecordTypeDrawCurve: EmfPlusRecordType = 16408i32;\npub const EmfPlusRecordTypeDrawDriverString: EmfPlusRecordType = 16438i32;\npub const EmfPlusRecordTypeDrawEllipse: EmfPlusRecordType = 16399i32;\npub const EmfPlusRecordTypeDrawImage: EmfPlusRecordType = 16410i32;\npub const EmfPlusRecordTypeDrawImagePoints: EmfPlusRecordType = 16411i32;\npub const EmfPlusRecordTypeDrawLines: EmfPlusRecordType = 16397i32;\npub const EmfPlusRecordTypeDrawPath: EmfPlusRecordType = 16405i32;\npub const EmfPlusRecordTypeDrawPie: EmfPlusRecordType = 16401i32;\npub const EmfPlusRecordTypeDrawRects: EmfPlusRecordType = 16395i32;\npub const EmfPlusRecordTypeDrawString: EmfPlusRecordType = 16412i32;\npub const EmfPlusRecordTypeEndContainer: EmfPlusRecordType = 16425i32;\npub const EmfPlusRecordTypeEndOfFile: EmfPlusRecordType = 16386i32;\npub const EmfPlusRecordTypeFillClosedCurve: EmfPlusRecordType = 16406i32;\npub const EmfPlusRecordTypeFillEllipse: EmfPlusRecordType = 16398i32;\npub const EmfPlusRecordTypeFillPath: EmfPlusRecordType = 16404i32;\npub const EmfPlusRecordTypeFillPie: EmfPlusRecordType = 16400i32;\npub const EmfPlusRecordTypeFillPolygon: EmfPlusRecordType = 16396i32;\npub const EmfPlusRecordTypeFillRects: EmfPlusRecordType = 16394i32;\npub const EmfPlusRecordTypeFillRegion: EmfPlusRecordType = 16403i32;\npub const EmfPlusRecordTypeGetDC: EmfPlusRecordType = 16388i32;\npub const EmfPlusRecordTypeHeader: EmfPlusRecordType = 16385i32;\npub const EmfPlusRecordTypeInvalid: EmfPlusRecordType = 16384i32;\npub const EmfPlusRecordTypeMax: EmfPlusRecordType = 16442i32;\npub const EmfPlusRecordTypeMin: EmfPlusRecordType = 16385i32;\npub const EmfPlusRecordTypeMultiFormatEnd: EmfPlusRecordType = 16391i32;\npub const EmfPlusRecordTypeMultiFormatSection: EmfPlusRecordType = 16390i32;\npub const EmfPlusRecordTypeMultiFormatStart: EmfPlusRecordType = 16389i32;\npub const EmfPlusRecordTypeMultiplyWorldTransform: EmfPlusRecordType = 16428i32;\npub const EmfPlusRecordTypeObject: EmfPlusRecordType = 16392i32;\npub const EmfPlusRecordTypeOffsetClip: EmfPlusRecordType = 16437i32;\npub const EmfPlusRecordTypeResetClip: EmfPlusRecordType = 16433i32;\npub const EmfPlusRecordTypeResetWorldTransform: EmfPlusRecordType = 16427i32;\npub const EmfPlusRecordTypeRestore: EmfPlusRecordType = 16422i32;\npub const EmfPlusRecordTypeRotateWorldTransform: EmfPlusRecordType = 16431i32;\npub const EmfPlusRecordTypeSave: EmfPlusRecordType = 16421i32;\npub const EmfPlusRecordTypeScaleWorldTransform: EmfPlusRecordType = 16430i32;\npub const EmfPlusRecordTypeSerializableObject: EmfPlusRecordType = 16440i32;\npub const EmfPlusRecordTypeSetAntiAliasMode: EmfPlusRecordType = 16414i32;\npub const EmfPlusRecordTypeSetClipPath: EmfPlusRecordType = 16435i32;\npub const EmfPlusRecordTypeSetClipRect: EmfPlusRecordType = 16434i32;\npub const EmfPlusRecordTypeSetClipRegion: EmfPlusRecordType = 16436i32;\npub const EmfPlusRecordTypeSetCompositingMode: EmfPlusRecordType = 16419i32;\npub const EmfPlusRecordTypeSetCompositingQuality: EmfPlusRecordType = 16420i32;\npub const EmfPlusRecordTypeSetInterpolationMode: EmfPlusRecordType = 16417i32;\npub const EmfPlusRecordTypeSetPageTransform: EmfPlusRecordType = 16432i32;\npub const EmfPlusRecordTypeSetPixelOffsetMode: EmfPlusRecordType = 16418i32;\npub const EmfPlusRecordTypeSetRenderingOrigin: EmfPlusRecordType = 16413i32;\npub const EmfPlusRecordTypeSetTSClip: EmfPlusRecordType = 16442i32;\npub const EmfPlusRecordTypeSetTSGraphics: EmfPlusRecordType = 16441i32;\npub const EmfPlusRecordTypeSetTextContrast: EmfPlusRecordType = 16416i32;\npub const EmfPlusRecordTypeSetTextRenderingHint: EmfPlusRecordType = 16415i32;\npub const EmfPlusRecordTypeSetWorldTransform: EmfPlusRecordType = 16426i32;\npub const EmfPlusRecordTypeStrokeFillPath: EmfPlusRecordType = 16439i32;\npub const EmfPlusRecordTypeTranslateWorldTransform: EmfPlusRecordType = 16429i32;\npub const EmfRecordTypeAbortPath: EmfPlusRecordType = 68i32;\npub const EmfRecordTypeAlphaBlend: EmfPlusRecordType = 114i32;\npub const EmfRecordTypeAngleArc: EmfPlusRecordType = 41i32;\npub const EmfRecordTypeArc: EmfPlusRecordType = 45i32;\npub const EmfRecordTypeArcTo: EmfPlusRecordType = 55i32;\npub const EmfRecordTypeBeginPath: EmfPlusRecordType = 59i32;\npub const EmfRecordTypeBitBlt: EmfPlusRecordType = 76i32;\npub const EmfRecordTypeChord: EmfPlusRecordType = 46i32;\npub const EmfRecordTypeCloseFigure: EmfPlusRecordType = 61i32;\npub const EmfRecordTypeColorCorrectPalette: EmfPlusRecordType = 111i32;\npub const EmfRecordTypeColorMatchToTargetW: EmfPlusRecordType = 121i32;\npub const EmfRecordTypeCreateBrushIndirect: EmfPlusRecordType = 39i32;\npub const EmfRecordTypeCreateColorSpace: EmfPlusRecordType = 99i32;\npub const EmfRecordTypeCreateColorSpaceW: EmfPlusRecordType = 122i32;\npub const EmfRecordTypeCreateDIBPatternBrushPt: EmfPlusRecordType = 94i32;\npub const EmfRecordTypeCreateMonoBrush: EmfPlusRecordType = 93i32;\npub const EmfRecordTypeCreatePalette: EmfPlusRecordType = 49i32;\npub const EmfRecordTypeCreatePen: EmfPlusRecordType = 38i32;\npub const EmfRecordTypeDeleteColorSpace: EmfPlusRecordType = 101i32;\npub const EmfRecordTypeDeleteObject: EmfPlusRecordType = 40i32;\npub const EmfRecordTypeDrawEscape: EmfPlusRecordType = 105i32;\npub const EmfRecordTypeEOF: EmfPlusRecordType = 14i32;\npub const EmfRecordTypeEllipse: EmfPlusRecordType = 42i32;\npub const EmfRecordTypeEndPath: EmfPlusRecordType = 60i32;\npub const EmfRecordTypeExcludeClipRect: EmfPlusRecordType = 29i32;\npub const EmfRecordTypeExtCreateFontIndirect: EmfPlusRecordType = 82i32;\npub const EmfRecordTypeExtCreatePen: EmfPlusRecordType = 95i32;\npub const EmfRecordTypeExtEscape: EmfPlusRecordType = 106i32;\npub const EmfRecordTypeExtFloodFill: EmfPlusRecordType = 53i32;\npub const EmfRecordTypeExtSelectClipRgn: EmfPlusRecordType = 75i32;\npub const EmfRecordTypeExtTextOutA: EmfPlusRecordType = 83i32;\npub const EmfRecordTypeExtTextOutW: EmfPlusRecordType = 84i32;\npub const EmfRecordTypeFillPath: EmfPlusRecordType = 62i32;\npub const EmfRecordTypeFillRgn: EmfPlusRecordType = 71i32;\npub const EmfRecordTypeFlattenPath: EmfPlusRecordType = 65i32;\npub const EmfRecordTypeForceUFIMapping: EmfPlusRecordType = 109i32;\npub const EmfRecordTypeFrameRgn: EmfPlusRecordType = 72i32;\npub const EmfRecordTypeGLSBoundedRecord: EmfPlusRecordType = 103i32;\npub const EmfRecordTypeGLSRecord: EmfPlusRecordType = 102i32;\npub const EmfRecordTypeGdiComment: EmfPlusRecordType = 70i32;\npub const EmfRecordTypeGradientFill: EmfPlusRecordType = 118i32;\npub const EmfRecordTypeHeader: EmfPlusRecordType = 1i32;\npub const EmfRecordTypeIntersectClipRect: EmfPlusRecordType = 30i32;\npub const EmfRecordTypeInvertRgn: EmfPlusRecordType = 73i32;\npub const EmfRecordTypeLineTo: EmfPlusRecordType = 54i32;\npub const EmfRecordTypeMaskBlt: EmfPlusRecordType = 78i32;\npub const EmfRecordTypeMax: EmfPlusRecordType = 122i32;\npub const EmfRecordTypeMin: EmfPlusRecordType = 1i32;\npub const EmfRecordTypeModifyWorldTransform: EmfPlusRecordType = 36i32;\npub const EmfRecordTypeMoveToEx: EmfPlusRecordType = 27i32;\npub const EmfRecordTypeNamedEscape: EmfPlusRecordType = 110i32;\npub const EmfRecordTypeOffsetClipRgn: EmfPlusRecordType = 26i32;\npub const EmfRecordTypePaintRgn: EmfPlusRecordType = 74i32;\npub const EmfRecordTypePie: EmfPlusRecordType = 47i32;\npub const EmfRecordTypePixelFormat: EmfPlusRecordType = 104i32;\npub const EmfRecordTypePlgBlt: EmfPlusRecordType = 79i32;\npub const EmfRecordTypePolyBezier: EmfPlusRecordType = 2i32;\npub const EmfRecordTypePolyBezier16: EmfPlusRecordType = 85i32;\npub const EmfRecordTypePolyBezierTo: EmfPlusRecordType = 5i32;\npub const EmfRecordTypePolyBezierTo16: EmfPlusRecordType = 88i32;\npub const EmfRecordTypePolyDraw: EmfPlusRecordType = 56i32;\npub const EmfRecordTypePolyDraw16: EmfPlusRecordType = 92i32;\npub const EmfRecordTypePolyLineTo: EmfPlusRecordType = 6i32;\npub const EmfRecordTypePolyPolygon: EmfPlusRecordType = 8i32;\npub const EmfRecordTypePolyPolygon16: EmfPlusRecordType = 91i32;\npub const EmfRecordTypePolyPolyline: EmfPlusRecordType = 7i32;\npub const EmfRecordTypePolyPolyline16: EmfPlusRecordType = 90i32;\npub const EmfRecordTypePolyTextOutA: EmfPlusRecordType = 96i32;\npub const EmfRecordTypePolyTextOutW: EmfPlusRecordType = 97i32;\npub const EmfRecordTypePolygon: EmfPlusRecordType = 3i32;\npub const EmfRecordTypePolygon16: EmfPlusRecordType = 86i32;\npub const EmfRecordTypePolyline: EmfPlusRecordType = 4i32;\npub const EmfRecordTypePolyline16: EmfPlusRecordType = 87i32;\npub const EmfRecordTypePolylineTo16: EmfPlusRecordType = 89i32;\npub const EmfRecordTypeRealizePalette: EmfPlusRecordType = 52i32;\npub const EmfRecordTypeRectangle: EmfPlusRecordType = 43i32;\npub const EmfRecordTypeReserved_069: EmfPlusRecordType = 69i32;\npub const EmfRecordTypeReserved_117: EmfPlusRecordType = 117i32;\npub const EmfRecordTypeResizePalette: EmfPlusRecordType = 51i32;\npub const EmfRecordTypeRestoreDC: EmfPlusRecordType = 34i32;\npub const EmfRecordTypeRoundRect: EmfPlusRecordType = 44i32;\npub const EmfRecordTypeSaveDC: EmfPlusRecordType = 33i32;\npub const EmfRecordTypeScaleViewportExtEx: EmfPlusRecordType = 31i32;\npub const EmfRecordTypeScaleWindowExtEx: EmfPlusRecordType = 32i32;\npub const EmfRecordTypeSelectClipPath: EmfPlusRecordType = 67i32;\npub const EmfRecordTypeSelectObject: EmfPlusRecordType = 37i32;\npub const EmfRecordTypeSelectPalette: EmfPlusRecordType = 48i32;\npub const EmfRecordTypeSetArcDirection: EmfPlusRecordType = 57i32;\npub const EmfRecordTypeSetBkColor: EmfPlusRecordType = 25i32;\npub const EmfRecordTypeSetBkMode: EmfPlusRecordType = 18i32;\npub const EmfRecordTypeSetBrushOrgEx: EmfPlusRecordType = 13i32;\npub const EmfRecordTypeSetColorAdjustment: EmfPlusRecordType = 23i32;\npub const EmfRecordTypeSetColorSpace: EmfPlusRecordType = 100i32;\npub const EmfRecordTypeSetDIBitsToDevice: EmfPlusRecordType = 80i32;\npub const EmfRecordTypeSetICMMode: EmfPlusRecordType = 98i32;\npub const EmfRecordTypeSetICMProfileA: EmfPlusRecordType = 112i32;\npub const EmfRecordTypeSetICMProfileW: EmfPlusRecordType = 113i32;\npub const EmfRecordTypeSetLayout: EmfPlusRecordType = 115i32;\npub const EmfRecordTypeSetLinkedUFIs: EmfPlusRecordType = 119i32;\npub const EmfRecordTypeSetMapMode: EmfPlusRecordType = 17i32;\npub const EmfRecordTypeSetMapperFlags: EmfPlusRecordType = 16i32;\npub const EmfRecordTypeSetMetaRgn: EmfPlusRecordType = 28i32;\npub const EmfRecordTypeSetMiterLimit: EmfPlusRecordType = 58i32;\npub const EmfRecordTypeSetPaletteEntries: EmfPlusRecordType = 50i32;\npub const EmfRecordTypeSetPixelV: EmfPlusRecordType = 15i32;\npub const EmfRecordTypeSetPolyFillMode: EmfPlusRecordType = 19i32;\npub const EmfRecordTypeSetROP2: EmfPlusRecordType = 20i32;\npub const EmfRecordTypeSetStretchBltMode: EmfPlusRecordType = 21i32;\npub const EmfRecordTypeSetTextAlign: EmfPlusRecordType = 22i32;\npub const EmfRecordTypeSetTextColor: EmfPlusRecordType = 24i32;\npub const EmfRecordTypeSetTextJustification: EmfPlusRecordType = 120i32;\npub const EmfRecordTypeSetViewportExtEx: EmfPlusRecordType = 11i32;\npub const EmfRecordTypeSetViewportOrgEx: EmfPlusRecordType = 12i32;\npub const EmfRecordTypeSetWindowExtEx: EmfPlusRecordType = 9i32;\npub const EmfRecordTypeSetWindowOrgEx: EmfPlusRecordType = 10i32;\npub const EmfRecordTypeSetWorldTransform: EmfPlusRecordType = 35i32;\npub const EmfRecordTypeSmallTextOut: EmfPlusRecordType = 108i32;\npub const EmfRecordTypeStartDoc: EmfPlusRecordType = 107i32;\npub const EmfRecordTypeStretchBlt: EmfPlusRecordType = 77i32;\npub const EmfRecordTypeStretchDIBits: EmfPlusRecordType = 81i32;\npub const EmfRecordTypeStrokeAndFillPath: EmfPlusRecordType = 63i32;\npub const EmfRecordTypeStrokePath: EmfPlusRecordType = 64i32;\npub const EmfRecordTypeTransparentBlt: EmfPlusRecordType = 116i32;\npub const EmfRecordTypeWidenPath: EmfPlusRecordType = 66i32;\npub type EmfToWmfBitsFlags = i32;\npub const EmfToWmfBitsFlagsDefault: EmfToWmfBitsFlags = 0i32;\npub const EmfToWmfBitsFlagsEmbedEmf: EmfToWmfBitsFlags = 1i32;\npub const EmfToWmfBitsFlagsIncludePlaceable: EmfToWmfBitsFlags = 2i32;\npub const EmfToWmfBitsFlagsNoXORClip: EmfToWmfBitsFlags = 4i32;\npub type EmfType = i32;\npub const EmfTypeEmfOnly: EmfType = 3i32;\npub const EmfTypeEmfPlusDual: EmfType = 5i32;\npub const EmfTypeEmfPlusOnly: EmfType = 4i32;\npub const EncoderChrominanceTable: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf2e455dc_09b3_4316_8260_676ada32481c);\npub const EncoderColorDepth: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x66087055_ad66_4c7c_9a18_38a2310b8337);\npub const EncoderColorSpace: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xae7a62a0_ee2c_49d8_9d07_1ba8a927596e);\npub const EncoderCompression: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe09d739d_ccd4_44ee_8eba_3fbf8be4fc58);\npub const EncoderImageItems: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x63875e13_1f1d_45ab_9195_a29b6066a650);\npub const EncoderLuminanceTable: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xedb33bce_0266_4a77_b904_27216099e717);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct EncoderParameter {\n    pub Guid: windows_sys::core::GUID,\n    pub NumberOfValues: u32,\n    pub Type: u32,\n    pub Value: *mut core::ffi::c_void,\n}\nimpl Default for EncoderParameter {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type EncoderParameterValueType = i32;\npub const EncoderParameterValueTypeASCII: EncoderParameterValueType = 2i32;\npub const EncoderParameterValueTypeByte: EncoderParameterValueType = 1i32;\npub const EncoderParameterValueTypeLong: EncoderParameterValueType = 4i32;\npub const EncoderParameterValueTypeLongRange: EncoderParameterValueType = 6i32;\npub const EncoderParameterValueTypePointer: EncoderParameterValueType = 9i32;\npub const EncoderParameterValueTypeRational: EncoderParameterValueType = 5i32;\npub const EncoderParameterValueTypeRationalRange: EncoderParameterValueType = 8i32;\npub const EncoderParameterValueTypeShort: EncoderParameterValueType = 3i32;\npub const EncoderParameterValueTypeUndefined: EncoderParameterValueType = 7i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct EncoderParameters {\n    pub Count: u32,\n    pub Parameter: [EncoderParameter; 1],\n}\nimpl Default for EncoderParameters {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const EncoderQuality: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1d5be4b5_fa4a_452d_9cdd_5db35105e7eb);\npub const EncoderRenderMethod: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6d42c53a_229a_4825_8bb7_5c99e2b9a8b8);\npub const EncoderSaveAsCMYK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa219bbc9_0a9d_4005_a3ee_3a421b8bb06c);\npub const EncoderSaveFlag: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x292266fc_ac40_47bf_8cfc_a85b89a655de);\npub const EncoderScanMethod: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3a4e2661_3109_4e56_8536_42c156e7dcfa);\npub const EncoderTransformation: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8d0eb2d1_a58e_4ea8_aa14_108074b7b6f9);\npub type EncoderValue = i32;\npub const EncoderValueColorTypeCMYK: EncoderValue = 0i32;\npub const EncoderValueColorTypeGray: EncoderValue = 24i32;\npub const EncoderValueColorTypeRGB: EncoderValue = 25i32;\npub const EncoderValueColorTypeYCCK: EncoderValue = 1i32;\npub const EncoderValueCompressionCCITT3: EncoderValue = 3i32;\npub const EncoderValueCompressionCCITT4: EncoderValue = 4i32;\npub const EncoderValueCompressionLZW: EncoderValue = 2i32;\npub const EncoderValueCompressionNone: EncoderValue = 6i32;\npub const EncoderValueCompressionRle: EncoderValue = 5i32;\npub const EncoderValueFlush: EncoderValue = 20i32;\npub const EncoderValueFrameDimensionPage: EncoderValue = 23i32;\npub const EncoderValueFrameDimensionResolution: EncoderValue = 22i32;\npub const EncoderValueFrameDimensionTime: EncoderValue = 21i32;\npub const EncoderValueLastFrame: EncoderValue = 19i32;\npub const EncoderValueMultiFrame: EncoderValue = 18i32;\npub const EncoderValueRenderNonProgressive: EncoderValue = 12i32;\npub const EncoderValueRenderProgressive: EncoderValue = 11i32;\npub const EncoderValueScanMethodInterlaced: EncoderValue = 7i32;\npub const EncoderValueScanMethodNonInterlaced: EncoderValue = 8i32;\npub const EncoderValueTransformFlipHorizontal: EncoderValue = 16i32;\npub const EncoderValueTransformFlipVertical: EncoderValue = 17i32;\npub const EncoderValueTransformRotate180: EncoderValue = 14i32;\npub const EncoderValueTransformRotate270: EncoderValue = 15i32;\npub const EncoderValueTransformRotate90: EncoderValue = 13i32;\npub const EncoderValueVersionGif87: EncoderValue = 9i32;\npub const EncoderValueVersionGif89: EncoderValue = 10i32;\npub const EncoderVersion: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x24d18c76_814a_41a4_bf53_1c219cccf797);\npub type EnumerateMetafileProc = Option<unsafe extern \"system\" fn(param0: EmfPlusRecordType, param1: u32, param2: u32, param3: *const u8, param4: *mut core::ffi::c_void) -> windows_sys::core::BOOL>;\npub const FileNotFound: Status = 10i32;\npub type FillMode = i32;\npub const FillModeAlternate: FillMode = 0i32;\npub const FillModeWinding: FillMode = 1i32;\npub const FlatnessDefault: f32 = 0.25f32;\npub type FlushIntention = i32;\npub const FlushIntentionFlush: FlushIntention = 0i32;\npub const FlushIntentionSync: FlushIntention = 1i32;\npub type Font = isize;\npub type FontCollection = isize;\npub type FontFamily = isize;\npub const FontFamilyNotFound: Status = 14i32;\npub type FontStyle = i32;\npub const FontStyleBold: FontStyle = 1i32;\npub const FontStyleBoldItalic: FontStyle = 3i32;\npub const FontStyleItalic: FontStyle = 2i32;\npub const FontStyleNotFound: Status = 15i32;\npub const FontStyleRegular: FontStyle = 0i32;\npub const FontStyleStrikeout: FontStyle = 8i32;\npub const FontStyleUnderline: FontStyle = 4i32;\npub const FormatIDImageInformation: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe5836cbe_5eef_4f1d_acde_ae4c43b608ce);\npub const FormatIDJpegAppHeaders: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1c4afdcd_6177_43cf_abc7_5f51af39ee85);\npub const FrameDimensionPage: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7462dc86_6180_4c7e_8e3f_ee7333a7a483);\npub const FrameDimensionResolution: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x84236f7b_3bd3_428f_8dab_4ea1439ca315);\npub const FrameDimensionTime: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6aedbd6d_3fb5_418a_83a6_7f45229dc872);\npub const GDIP_EMFPLUSFLAGS_DISPLAY: u32 = 1u32;\npub const GDIP_EMFPLUS_RECORD_BASE: u32 = 16384u32;\npub const GDIP_WMF_RECORD_BASE: u32 = 65536u32;\npub const GREEN_SHIFT: u32 = 8u32;\npub const GdiplusNotInitialized: Status = 18i32;\npub const GdiplusStartupDefault: GdiplusStartupParams = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GdiplusStartupInput {\n    pub GdiplusVersion: u32,\n    pub DebugEventCallback: isize,\n    pub SuppressBackgroundThread: windows_sys::core::BOOL,\n    pub SuppressExternalCodecs: windows_sys::core::BOOL,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GdiplusStartupInputEx {\n    pub Base: GdiplusStartupInput,\n    pub StartupParameters: i32,\n}\npub const GdiplusStartupNoSetRound: GdiplusStartupParams = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GdiplusStartupOutput {\n    pub NotificationHook: isize,\n    pub NotificationUnhook: isize,\n}\npub type GdiplusStartupParams = i32;\npub const GdiplusStartupSetPSValue: GdiplusStartupParams = 2i32;\npub const GdiplusStartupTransparencyMask: GdiplusStartupParams = -16777216i32;\npub const GenericError: Status = 1i32;\npub type GenericFontFamily = i32;\npub const GenericFontFamilyMonospace: GenericFontFamily = 2i32;\npub const GenericFontFamilySansSerif: GenericFontFamily = 1i32;\npub const GenericFontFamilySerif: GenericFontFamily = 0i32;\npub type GetThumbnailImageAbort = Option<unsafe extern \"system\" fn() -> windows_sys::core::BOOL>;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpAdjustableArrowCap(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpBitmap(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpBrush(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpCachedBitmap(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpCustomLineCap(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpFont(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpFontCollection(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpFontFamily(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpGraphics(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpHatch(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpImage(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpImageAttributes(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpInstalledFontCollection(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpLineGradient(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpMetafile(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpPath(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpPathGradient(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpPathIterator(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpPen(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpPrivateFontCollection(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpRegion(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpSolidFill(pub u8);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpStringFormat(pub u8);\npub type GpTestControlEnum = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GpTexture(pub u8);\npub type HatchStyle = i32;\npub const HatchStyle05Percent: HatchStyle = 6i32;\npub const HatchStyle10Percent: HatchStyle = 7i32;\npub const HatchStyle20Percent: HatchStyle = 8i32;\npub const HatchStyle25Percent: HatchStyle = 9i32;\npub const HatchStyle30Percent: HatchStyle = 10i32;\npub const HatchStyle40Percent: HatchStyle = 11i32;\npub const HatchStyle50Percent: HatchStyle = 12i32;\npub const HatchStyle60Percent: HatchStyle = 13i32;\npub const HatchStyle70Percent: HatchStyle = 14i32;\npub const HatchStyle75Percent: HatchStyle = 15i32;\npub const HatchStyle80Percent: HatchStyle = 16i32;\npub const HatchStyle90Percent: HatchStyle = 17i32;\npub const HatchStyleBackwardDiagonal: HatchStyle = 3i32;\npub const HatchStyleCross: HatchStyle = 4i32;\npub const HatchStyleDarkDownwardDiagonal: HatchStyle = 20i32;\npub const HatchStyleDarkHorizontal: HatchStyle = 29i32;\npub const HatchStyleDarkUpwardDiagonal: HatchStyle = 21i32;\npub const HatchStyleDarkVertical: HatchStyle = 28i32;\npub const HatchStyleDashedDownwardDiagonal: HatchStyle = 30i32;\npub const HatchStyleDashedHorizontal: HatchStyle = 32i32;\npub const HatchStyleDashedUpwardDiagonal: HatchStyle = 31i32;\npub const HatchStyleDashedVertical: HatchStyle = 33i32;\npub const HatchStyleDiagonalBrick: HatchStyle = 38i32;\npub const HatchStyleDiagonalCross: HatchStyle = 5i32;\npub const HatchStyleDivot: HatchStyle = 42i32;\npub const HatchStyleDottedDiamond: HatchStyle = 44i32;\npub const HatchStyleDottedGrid: HatchStyle = 43i32;\npub const HatchStyleForwardDiagonal: HatchStyle = 2i32;\npub const HatchStyleHorizontal: HatchStyle = 0i32;\npub const HatchStyleHorizontalBrick: HatchStyle = 39i32;\npub const HatchStyleLargeCheckerBoard: HatchStyle = 50i32;\npub const HatchStyleLargeConfetti: HatchStyle = 35i32;\npub const HatchStyleLargeGrid: HatchStyle = 4i32;\npub const HatchStyleLightDownwardDiagonal: HatchStyle = 18i32;\npub const HatchStyleLightHorizontal: HatchStyle = 25i32;\npub const HatchStyleLightUpwardDiagonal: HatchStyle = 19i32;\npub const HatchStyleLightVertical: HatchStyle = 24i32;\npub const HatchStyleMax: HatchStyle = 52i32;\npub const HatchStyleMin: HatchStyle = 0i32;\npub const HatchStyleNarrowHorizontal: HatchStyle = 27i32;\npub const HatchStyleNarrowVertical: HatchStyle = 26i32;\npub const HatchStyleOutlinedDiamond: HatchStyle = 51i32;\npub const HatchStylePlaid: HatchStyle = 41i32;\npub const HatchStyleShingle: HatchStyle = 45i32;\npub const HatchStyleSmallCheckerBoard: HatchStyle = 49i32;\npub const HatchStyleSmallConfetti: HatchStyle = 34i32;\npub const HatchStyleSmallGrid: HatchStyle = 48i32;\npub const HatchStyleSolidDiamond: HatchStyle = 52i32;\npub const HatchStyleSphere: HatchStyle = 47i32;\npub const HatchStyleTotal: HatchStyle = 53i32;\npub const HatchStyleTrellis: HatchStyle = 46i32;\npub const HatchStyleVertical: HatchStyle = 1i32;\npub const HatchStyleWave: HatchStyle = 37i32;\npub const HatchStyleWeave: HatchStyle = 40i32;\npub const HatchStyleWideDownwardDiagonal: HatchStyle = 22i32;\npub const HatchStyleWideUpwardDiagonal: HatchStyle = 23i32;\npub const HatchStyleZigZag: HatchStyle = 36i32;\npub type HistogramFormat = i32;\npub const HistogramFormatA: HistogramFormat = 7i32;\npub const HistogramFormatARGB: HistogramFormat = 0i32;\npub const HistogramFormatB: HistogramFormat = 4i32;\npub const HistogramFormatG: HistogramFormat = 5i32;\npub const HistogramFormatGray: HistogramFormat = 3i32;\npub const HistogramFormatPARGB: HistogramFormat = 1i32;\npub const HistogramFormatR: HistogramFormat = 6i32;\npub const HistogramFormatRGB: HistogramFormat = 2i32;\npub type HotkeyPrefix = i32;\npub const HotkeyPrefixHide: HotkeyPrefix = 2i32;\npub const HotkeyPrefixNone: HotkeyPrefix = 0i32;\npub const HotkeyPrefixShow: HotkeyPrefix = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct HueSaturationLightness {\n    pub Base: Effect,\n}\npub const HueSaturationLightnessEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8b2dd6c3_eb07_4d87_a5f0_7108e26a9c5f);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct HueSaturationLightnessParams {\n    pub hueLevel: i32,\n    pub saturationLevel: i32,\n    pub lightnessLevel: i32,\n}\npub type Image = isize;\npub type ImageAbort = Option<unsafe extern \"system\" fn(param0: *mut core::ffi::c_void) -> windows_sys::core::BOOL>;\npub type ImageCodecFlags = i32;\npub const ImageCodecFlagsBlockingDecode: ImageCodecFlags = 32i32;\npub const ImageCodecFlagsBuiltin: ImageCodecFlags = 65536i32;\npub const ImageCodecFlagsDecoder: ImageCodecFlags = 2i32;\npub const ImageCodecFlagsEncoder: ImageCodecFlags = 1i32;\npub const ImageCodecFlagsSeekableEncode: ImageCodecFlags = 16i32;\npub const ImageCodecFlagsSupportBitmap: ImageCodecFlags = 4i32;\npub const ImageCodecFlagsSupportVector: ImageCodecFlags = 8i32;\npub const ImageCodecFlagsSystem: ImageCodecFlags = 131072i32;\npub const ImageCodecFlagsUser: ImageCodecFlags = 262144i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ImageCodecInfo {\n    pub Clsid: windows_sys::core::GUID,\n    pub FormatID: windows_sys::core::GUID,\n    pub CodecName: windows_sys::core::PCWSTR,\n    pub DllName: windows_sys::core::PCWSTR,\n    pub FormatDescription: windows_sys::core::PCWSTR,\n    pub FilenameExtension: windows_sys::core::PCWSTR,\n    pub MimeType: windows_sys::core::PCWSTR,\n    pub Flags: u32,\n    pub Version: u32,\n    pub SigCount: u32,\n    pub SigSize: u32,\n    pub SigPattern: *const u8,\n    pub SigMask: *const u8,\n}\nimpl Default for ImageCodecInfo {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type ImageFlags = i32;\npub const ImageFlagsCaching: ImageFlags = 131072i32;\npub const ImageFlagsColorSpaceCMYK: ImageFlags = 32i32;\npub const ImageFlagsColorSpaceGRAY: ImageFlags = 64i32;\npub const ImageFlagsColorSpaceRGB: ImageFlags = 16i32;\npub const ImageFlagsColorSpaceYCBCR: ImageFlags = 128i32;\npub const ImageFlagsColorSpaceYCCK: ImageFlags = 256i32;\npub const ImageFlagsHasAlpha: ImageFlags = 2i32;\npub const ImageFlagsHasRealDPI: ImageFlags = 4096i32;\npub const ImageFlagsHasRealPixelSize: ImageFlags = 8192i32;\npub const ImageFlagsHasTranslucent: ImageFlags = 4i32;\npub const ImageFlagsNone: ImageFlags = 0i32;\npub const ImageFlagsPartiallyScalable: ImageFlags = 8i32;\npub const ImageFlagsReadOnly: ImageFlags = 65536i32;\npub const ImageFlagsScalable: ImageFlags = 1i32;\npub const ImageFormatBMP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3cab_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatEMF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3cac_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatEXIF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3cb2_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatGIF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3cb0_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatHEIF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3cb6_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatIcon: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3cb5_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatJPEG: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3cae_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatMemoryBMP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3caa_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatPNG: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3caf_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatTIFF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3cb1_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatUndefined: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3ca9_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatWEBP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3cb7_0728_11d3_9d7b_0000f81ef32e);\npub const ImageFormatWMF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb96b3cad_0728_11d3_9d7b_0000f81ef32e);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ImageItemData {\n    pub Size: u32,\n    pub Position: u32,\n    pub Desc: *mut core::ffi::c_void,\n    pub DescSize: u32,\n    pub Data: *mut core::ffi::c_void,\n    pub DataSize: u32,\n    pub Cookie: u32,\n}\nimpl Default for ImageItemData {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type ImageLockMode = i32;\npub const ImageLockModeRead: ImageLockMode = 1i32;\npub const ImageLockModeUserInputBuf: ImageLockMode = 4i32;\npub const ImageLockModeWrite: ImageLockMode = 2i32;\npub type ImageType = i32;\npub const ImageTypeBitmap: ImageType = 1i32;\npub const ImageTypeMetafile: ImageType = 2i32;\npub const ImageTypeUnknown: ImageType = 0i32;\npub type InstalledFontCollection = isize;\npub const InsufficientBuffer: Status = 5i32;\npub type InterpolationMode = i32;\npub const InterpolationModeBicubic: InterpolationMode = 4i32;\npub const InterpolationModeBilinear: InterpolationMode = 3i32;\npub const InterpolationModeDefault: InterpolationMode = 0i32;\npub const InterpolationModeHighQuality: InterpolationMode = 2i32;\npub const InterpolationModeHighQualityBicubic: InterpolationMode = 7i32;\npub const InterpolationModeHighQualityBilinear: InterpolationMode = 6i32;\npub const InterpolationModeInvalid: InterpolationMode = -1i32;\npub const InterpolationModeLowQuality: InterpolationMode = 1i32;\npub const InterpolationModeNearestNeighbor: InterpolationMode = 5i32;\npub const InvalidParameter: Status = 2i32;\npub type ItemDataPosition = i32;\npub const ItemDataPositionAfterBits: ItemDataPosition = 2i32;\npub const ItemDataPositionAfterHeader: ItemDataPosition = 0i32;\npub const ItemDataPositionAfterPalette: ItemDataPosition = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct Levels {\n    pub Base: Effect,\n}\npub const LevelsEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x99c354ec_2a31_4f3a_8c34_17a803b33a25);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct LevelsParams {\n    pub highlight: i32,\n    pub midtone: i32,\n    pub shadow: i32,\n}\npub type LineCap = i32;\npub const LineCapAnchorMask: LineCap = 240i32;\npub const LineCapArrowAnchor: LineCap = 20i32;\npub const LineCapCustom: LineCap = 255i32;\npub const LineCapDiamondAnchor: LineCap = 19i32;\npub const LineCapFlat: LineCap = 0i32;\npub const LineCapNoAnchor: LineCap = 16i32;\npub const LineCapRound: LineCap = 2i32;\npub const LineCapRoundAnchor: LineCap = 18i32;\npub const LineCapSquare: LineCap = 1i32;\npub const LineCapSquareAnchor: LineCap = 17i32;\npub const LineCapTriangle: LineCap = 3i32;\npub type LineJoin = i32;\npub const LineJoinBevel: LineJoin = 1i32;\npub const LineJoinMiter: LineJoin = 0i32;\npub const LineJoinMiterClipped: LineJoin = 3i32;\npub const LineJoinRound: LineJoin = 2i32;\npub type LinearGradientMode = i32;\npub const LinearGradientModeBackwardDiagonal: LinearGradientMode = 3i32;\npub const LinearGradientModeForwardDiagonal: LinearGradientMode = 2i32;\npub const LinearGradientModeHorizontal: LinearGradientMode = 0i32;\npub const LinearGradientModeVertical: LinearGradientMode = 1i32;\npub type Matrix = isize;\npub type MatrixOrder = i32;\npub const MatrixOrderAppend: MatrixOrder = 1i32;\npub const MatrixOrderPrepend: MatrixOrder = 0i32;\npub type Metafile = isize;\npub type MetafileFrameUnit = i32;\npub const MetafileFrameUnitDocument: MetafileFrameUnit = 5i32;\npub const MetafileFrameUnitGdi: MetafileFrameUnit = 7i32;\npub const MetafileFrameUnitInch: MetafileFrameUnit = 4i32;\npub const MetafileFrameUnitMillimeter: MetafileFrameUnit = 6i32;\npub const MetafileFrameUnitPixel: MetafileFrameUnit = 2i32;\npub const MetafileFrameUnitPoint: MetafileFrameUnit = 3i32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct MetafileHeader {\n    pub Type: MetafileType,\n    pub Size: u32,\n    pub Version: u32,\n    pub EmfPlusFlags: u32,\n    pub DpiX: f32,\n    pub DpiY: f32,\n    pub X: i32,\n    pub Y: i32,\n    pub Width: i32,\n    pub Height: i32,\n    pub Anonymous: MetafileHeader_0,\n    pub EmfPlusHeaderSize: i32,\n    pub LogicalDpiX: i32,\n    pub LogicalDpiY: i32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for MetafileHeader {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub union MetafileHeader_0 {\n    pub WmfHeader: super::Gdi::METAHEADER,\n    pub EmfHeader: ENHMETAHEADER3,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for MetafileHeader_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type MetafileType = i32;\npub const MetafileTypeEmf: MetafileType = 3i32;\npub const MetafileTypeEmfPlusDual: MetafileType = 5i32;\npub const MetafileTypeEmfPlusOnly: MetafileType = 4i32;\npub const MetafileTypeInvalid: MetafileType = 0i32;\npub const MetafileTypeWmf: MetafileType = 1i32;\npub const MetafileTypeWmfPlaceable: MetafileType = 2i32;\npub const NotImplemented: Status = 6i32;\npub const NotTrueTypeFont: Status = 16i32;\npub type NotificationHookProc = Option<unsafe extern \"system\" fn(token: *mut usize) -> Status>;\npub type NotificationUnhookProc = Option<unsafe extern \"system\" fn(token: usize)>;\npub const ObjectBusy: Status = 4i32;\npub type ObjectType = i32;\npub const ObjectTypeBrush: ObjectType = 1i32;\npub const ObjectTypeCustomLineCap: ObjectType = 9i32;\npub const ObjectTypeFont: ObjectType = 6i32;\npub const ObjectTypeGraphics: ObjectType = 10i32;\npub const ObjectTypeImage: ObjectType = 5i32;\npub const ObjectTypeImageAttributes: ObjectType = 8i32;\npub const ObjectTypeInvalid: ObjectType = 0i32;\npub const ObjectTypeMax: ObjectType = 10i32;\npub const ObjectTypeMin: ObjectType = 1i32;\npub const ObjectTypePath: ObjectType = 3i32;\npub const ObjectTypePen: ObjectType = 2i32;\npub const ObjectTypeRegion: ObjectType = 4i32;\npub const ObjectTypeStringFormat: ObjectType = 7i32;\npub const Ok: Status = 0i32;\npub const OutOfMemory: Status = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PWMFRect16 {\n    pub Left: i16,\n    pub Top: i16,\n    pub Right: i16,\n    pub Bottom: i16,\n}\npub type PaletteFlags = i32;\npub const PaletteFlagsGrayScale: PaletteFlags = 2i32;\npub const PaletteFlagsHalftone: PaletteFlags = 4i32;\npub const PaletteFlagsHasAlpha: PaletteFlags = 1i32;\npub type PaletteType = i32;\npub const PaletteTypeCustom: PaletteType = 0i32;\npub const PaletteTypeFixedBW: PaletteType = 2i32;\npub const PaletteTypeFixedHalftone125: PaletteType = 6i32;\npub const PaletteTypeFixedHalftone216: PaletteType = 7i32;\npub const PaletteTypeFixedHalftone252: PaletteType = 8i32;\npub const PaletteTypeFixedHalftone256: PaletteType = 9i32;\npub const PaletteTypeFixedHalftone27: PaletteType = 4i32;\npub const PaletteTypeFixedHalftone64: PaletteType = 5i32;\npub const PaletteTypeFixedHalftone8: PaletteType = 3i32;\npub const PaletteTypeOptimal: PaletteType = 1i32;\npub type PathData = isize;\npub type PathPointType = i32;\npub const PathPointTypeBezier: PathPointType = 3i32;\npub const PathPointTypeBezier3: PathPointType = 3i32;\npub const PathPointTypeCloseSubpath: PathPointType = 128i32;\npub const PathPointTypeDashMode: PathPointType = 16i32;\npub const PathPointTypeLine: PathPointType = 1i32;\npub const PathPointTypePathMarker: PathPointType = 32i32;\npub const PathPointTypePathTypeMask: PathPointType = 7i32;\npub const PathPointTypeStart: PathPointType = 0i32;\npub type PenAlignment = i32;\npub const PenAlignmentCenter: PenAlignment = 0i32;\npub const PenAlignmentInset: PenAlignment = 1i32;\npub type PenType = i32;\npub const PenTypeHatchFill: PenType = 1i32;\npub const PenTypeLinearGradient: PenType = 4i32;\npub const PenTypePathGradient: PenType = 3i32;\npub const PenTypeSolidColor: PenType = 0i32;\npub const PenTypeTextureFill: PenType = 2i32;\npub const PenTypeUnknown: PenType = -1i32;\npub const PixelFormatAlpha: u32 = 262144u32;\npub const PixelFormatCanonical: u32 = 2097152u32;\npub const PixelFormatDontCare: u32 = 0u32;\npub const PixelFormatExtended: u32 = 1048576u32;\npub const PixelFormatGDI: u32 = 131072u32;\npub const PixelFormatIndexed: u32 = 65536u32;\npub const PixelFormatMax: u32 = 16u32;\npub const PixelFormatPAlpha: u32 = 524288u32;\npub const PixelFormatUndefined: u32 = 0u32;\npub type PixelOffsetMode = i32;\npub const PixelOffsetModeDefault: PixelOffsetMode = 0i32;\npub const PixelOffsetModeHalf: PixelOffsetMode = 4i32;\npub const PixelOffsetModeHighQuality: PixelOffsetMode = 2i32;\npub const PixelOffsetModeHighSpeed: PixelOffsetMode = 1i32;\npub const PixelOffsetModeInvalid: PixelOffsetMode = -1i32;\npub const PixelOffsetModeNone: PixelOffsetMode = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct Point {\n    pub X: i32,\n    pub Y: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PointF {\n    pub X: f32,\n    pub Y: f32,\n}\npub type PrivateFontCollection = isize;\npub const ProfileNotFound: Status = 21i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PropertyItem {\n    pub id: u32,\n    pub length: u32,\n    pub r#type: u16,\n    pub value: *mut core::ffi::c_void,\n}\nimpl Default for PropertyItem {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const PropertyNotFound: Status = 19i32;\npub const PropertyNotSupported: Status = 20i32;\npub const PropertyTagArtist: u32 = 315u32;\npub const PropertyTagBitsPerSample: u32 = 258u32;\npub const PropertyTagCellHeight: u32 = 265u32;\npub const PropertyTagCellWidth: u32 = 264u32;\npub const PropertyTagChrominanceTable: u32 = 20625u32;\npub const PropertyTagColorMap: u32 = 320u32;\npub const PropertyTagColorTransferFunction: u32 = 20506u32;\npub const PropertyTagCompression: u32 = 259u32;\npub const PropertyTagCopyright: u32 = 33432u32;\npub const PropertyTagDateTime: u32 = 306u32;\npub const PropertyTagDocumentName: u32 = 269u32;\npub const PropertyTagDotRange: u32 = 336u32;\npub const PropertyTagEquipMake: u32 = 271u32;\npub const PropertyTagEquipModel: u32 = 272u32;\npub const PropertyTagExifAperture: u32 = 37378u32;\npub const PropertyTagExifBrightness: u32 = 37379u32;\npub const PropertyTagExifCfaPattern: u32 = 41730u32;\npub const PropertyTagExifColorSpace: u32 = 40961u32;\npub const PropertyTagExifCompBPP: u32 = 37122u32;\npub const PropertyTagExifCompConfig: u32 = 37121u32;\npub const PropertyTagExifContrast: u32 = 41992u32;\npub const PropertyTagExifCustomRendered: u32 = 41985u32;\npub const PropertyTagExifDTDigSS: u32 = 37522u32;\npub const PropertyTagExifDTDigitized: u32 = 36868u32;\npub const PropertyTagExifDTOrig: u32 = 36867u32;\npub const PropertyTagExifDTOrigSS: u32 = 37521u32;\npub const PropertyTagExifDTSubsec: u32 = 37520u32;\npub const PropertyTagExifDeviceSettingDesc: u32 = 41995u32;\npub const PropertyTagExifDigitalZoomRatio: u32 = 41988u32;\npub const PropertyTagExifExposureBias: u32 = 37380u32;\npub const PropertyTagExifExposureIndex: u32 = 41493u32;\npub const PropertyTagExifExposureMode: u32 = 41986u32;\npub const PropertyTagExifExposureProg: u32 = 34850u32;\npub const PropertyTagExifExposureTime: u32 = 33434u32;\npub const PropertyTagExifFNumber: u32 = 33437u32;\npub const PropertyTagExifFPXVer: u32 = 40960u32;\npub const PropertyTagExifFileSource: u32 = 41728u32;\npub const PropertyTagExifFlash: u32 = 37385u32;\npub const PropertyTagExifFlashEnergy: u32 = 41483u32;\npub const PropertyTagExifFocalLength: u32 = 37386u32;\npub const PropertyTagExifFocalLengthIn35mmFilm: u32 = 41989u32;\npub const PropertyTagExifFocalResUnit: u32 = 41488u32;\npub const PropertyTagExifFocalXRes: u32 = 41486u32;\npub const PropertyTagExifFocalYRes: u32 = 41487u32;\npub const PropertyTagExifGainControl: u32 = 41991u32;\npub const PropertyTagExifIFD: u32 = 34665u32;\npub const PropertyTagExifISOSpeed: u32 = 34855u32;\npub const PropertyTagExifInterop: u32 = 40965u32;\npub const PropertyTagExifLightSource: u32 = 37384u32;\npub const PropertyTagExifMakerNote: u32 = 37500u32;\npub const PropertyTagExifMaxAperture: u32 = 37381u32;\npub const PropertyTagExifMeteringMode: u32 = 37383u32;\npub const PropertyTagExifOECF: u32 = 34856u32;\npub const PropertyTagExifPixXDim: u32 = 40962u32;\npub const PropertyTagExifPixYDim: u32 = 40963u32;\npub const PropertyTagExifRelatedWav: u32 = 40964u32;\npub const PropertyTagExifSaturation: u32 = 41993u32;\npub const PropertyTagExifSceneCaptureType: u32 = 41990u32;\npub const PropertyTagExifSceneType: u32 = 41729u32;\npub const PropertyTagExifSensingMethod: u32 = 41495u32;\npub const PropertyTagExifSharpness: u32 = 41994u32;\npub const PropertyTagExifShutterSpeed: u32 = 37377u32;\npub const PropertyTagExifSpatialFR: u32 = 41484u32;\npub const PropertyTagExifSpectralSense: u32 = 34852u32;\npub const PropertyTagExifSubjectArea: u32 = 37396u32;\npub const PropertyTagExifSubjectDist: u32 = 37382u32;\npub const PropertyTagExifSubjectDistanceRange: u32 = 41996u32;\npub const PropertyTagExifSubjectLoc: u32 = 41492u32;\npub const PropertyTagExifUniqueImageID: u32 = 42016u32;\npub const PropertyTagExifUserComment: u32 = 37510u32;\npub const PropertyTagExifVer: u32 = 36864u32;\npub const PropertyTagExifWhiteBalance: u32 = 41987u32;\npub const PropertyTagExtraSamples: u32 = 338u32;\npub const PropertyTagFillOrder: u32 = 266u32;\npub const PropertyTagFrameDelay: u32 = 20736u32;\npub const PropertyTagFreeByteCounts: u32 = 289u32;\npub const PropertyTagFreeOffset: u32 = 288u32;\npub const PropertyTagGamma: u32 = 769u32;\npub const PropertyTagGlobalPalette: u32 = 20738u32;\npub const PropertyTagGpsAltitude: u32 = 6u32;\npub const PropertyTagGpsAltitudeRef: u32 = 5u32;\npub const PropertyTagGpsAreaInformation: u32 = 28u32;\npub const PropertyTagGpsDate: u32 = 29u32;\npub const PropertyTagGpsDestBear: u32 = 24u32;\npub const PropertyTagGpsDestBearRef: u32 = 23u32;\npub const PropertyTagGpsDestDist: u32 = 26u32;\npub const PropertyTagGpsDestDistRef: u32 = 25u32;\npub const PropertyTagGpsDestLat: u32 = 20u32;\npub const PropertyTagGpsDestLatRef: u32 = 19u32;\npub const PropertyTagGpsDestLong: u32 = 22u32;\npub const PropertyTagGpsDestLongRef: u32 = 21u32;\npub const PropertyTagGpsDifferential: u32 = 30u32;\npub const PropertyTagGpsGpsDop: u32 = 11u32;\npub const PropertyTagGpsGpsMeasureMode: u32 = 10u32;\npub const PropertyTagGpsGpsSatellites: u32 = 8u32;\npub const PropertyTagGpsGpsStatus: u32 = 9u32;\npub const PropertyTagGpsGpsTime: u32 = 7u32;\npub const PropertyTagGpsIFD: u32 = 34853u32;\npub const PropertyTagGpsImgDir: u32 = 17u32;\npub const PropertyTagGpsImgDirRef: u32 = 16u32;\npub const PropertyTagGpsLatitude: u32 = 2u32;\npub const PropertyTagGpsLatitudeRef: u32 = 1u32;\npub const PropertyTagGpsLongitude: u32 = 4u32;\npub const PropertyTagGpsLongitudeRef: u32 = 3u32;\npub const PropertyTagGpsMapDatum: u32 = 18u32;\npub const PropertyTagGpsProcessingMethod: u32 = 27u32;\npub const PropertyTagGpsSpeed: u32 = 13u32;\npub const PropertyTagGpsSpeedRef: u32 = 12u32;\npub const PropertyTagGpsTrack: u32 = 15u32;\npub const PropertyTagGpsTrackRef: u32 = 14u32;\npub const PropertyTagGpsVer: u32 = 0u32;\npub const PropertyTagGrayResponseCurve: u32 = 291u32;\npub const PropertyTagGrayResponseUnit: u32 = 290u32;\npub const PropertyTagGridSize: u32 = 20497u32;\npub const PropertyTagHalftoneDegree: u32 = 20492u32;\npub const PropertyTagHalftoneHints: u32 = 321u32;\npub const PropertyTagHalftoneLPI: u32 = 20490u32;\npub const PropertyTagHalftoneLPIUnit: u32 = 20491u32;\npub const PropertyTagHalftoneMisc: u32 = 20494u32;\npub const PropertyTagHalftoneScreen: u32 = 20495u32;\npub const PropertyTagHalftoneShape: u32 = 20493u32;\npub const PropertyTagHostComputer: u32 = 316u32;\npub const PropertyTagICCProfile: u32 = 34675u32;\npub const PropertyTagICCProfileDescriptor: u32 = 770u32;\npub const PropertyTagImageDescription: u32 = 270u32;\npub const PropertyTagImageHeight: u32 = 257u32;\npub const PropertyTagImageTitle: u32 = 800u32;\npub const PropertyTagImageWidth: u32 = 256u32;\npub const PropertyTagIndexBackground: u32 = 20739u32;\npub const PropertyTagIndexTransparent: u32 = 20740u32;\npub const PropertyTagInkNames: u32 = 333u32;\npub const PropertyTagInkSet: u32 = 332u32;\npub const PropertyTagJPEGACTables: u32 = 521u32;\npub const PropertyTagJPEGDCTables: u32 = 520u32;\npub const PropertyTagJPEGInterFormat: u32 = 513u32;\npub const PropertyTagJPEGInterLength: u32 = 514u32;\npub const PropertyTagJPEGLosslessPredictors: u32 = 517u32;\npub const PropertyTagJPEGPointTransforms: u32 = 518u32;\npub const PropertyTagJPEGProc: u32 = 512u32;\npub const PropertyTagJPEGQTables: u32 = 519u32;\npub const PropertyTagJPEGQuality: u32 = 20496u32;\npub const PropertyTagJPEGRestartInterval: u32 = 515u32;\npub const PropertyTagLoopCount: u32 = 20737u32;\npub const PropertyTagLuminanceTable: u32 = 20624u32;\npub const PropertyTagMaxSampleValue: u32 = 281u32;\npub const PropertyTagMinSampleValue: u32 = 280u32;\npub const PropertyTagNewSubfileType: u32 = 254u32;\npub const PropertyTagNumberOfInks: u32 = 334u32;\npub const PropertyTagOrientation: u32 = 274u32;\npub const PropertyTagPageName: u32 = 285u32;\npub const PropertyTagPageNumber: u32 = 297u32;\npub const PropertyTagPaletteHistogram: u32 = 20755u32;\npub const PropertyTagPhotometricInterp: u32 = 262u32;\npub const PropertyTagPixelPerUnitX: u32 = 20753u32;\npub const PropertyTagPixelPerUnitY: u32 = 20754u32;\npub const PropertyTagPixelUnit: u32 = 20752u32;\npub const PropertyTagPlanarConfig: u32 = 284u32;\npub const PropertyTagPredictor: u32 = 317u32;\npub const PropertyTagPrimaryChromaticities: u32 = 319u32;\npub const PropertyTagPrintFlags: u32 = 20485u32;\npub const PropertyTagPrintFlagsBleedWidth: u32 = 20488u32;\npub const PropertyTagPrintFlagsBleedWidthScale: u32 = 20489u32;\npub const PropertyTagPrintFlagsCrop: u32 = 20487u32;\npub const PropertyTagPrintFlagsVersion: u32 = 20486u32;\npub const PropertyTagREFBlackWhite: u32 = 532u32;\npub const PropertyTagResolutionUnit: u32 = 296u32;\npub const PropertyTagResolutionXLengthUnit: u32 = 20483u32;\npub const PropertyTagResolutionXUnit: u32 = 20481u32;\npub const PropertyTagResolutionYLengthUnit: u32 = 20484u32;\npub const PropertyTagResolutionYUnit: u32 = 20482u32;\npub const PropertyTagRowsPerStrip: u32 = 278u32;\npub const PropertyTagSMaxSampleValue: u32 = 341u32;\npub const PropertyTagSMinSampleValue: u32 = 340u32;\npub const PropertyTagSRGBRenderingIntent: u32 = 771u32;\npub const PropertyTagSampleFormat: u32 = 339u32;\npub const PropertyTagSamplesPerPixel: u32 = 277u32;\npub const PropertyTagSoftwareUsed: u32 = 305u32;\npub const PropertyTagStripBytesCount: u32 = 279u32;\npub const PropertyTagStripOffsets: u32 = 273u32;\npub const PropertyTagSubfileType: u32 = 255u32;\npub const PropertyTagT4Option: u32 = 292u32;\npub const PropertyTagT6Option: u32 = 293u32;\npub const PropertyTagTargetPrinter: u32 = 337u32;\npub const PropertyTagThreshHolding: u32 = 263u32;\npub const PropertyTagThumbnailArtist: u32 = 20532u32;\npub const PropertyTagThumbnailBitsPerSample: u32 = 20514u32;\npub const PropertyTagThumbnailColorDepth: u32 = 20501u32;\npub const PropertyTagThumbnailCompressedSize: u32 = 20505u32;\npub const PropertyTagThumbnailCompression: u32 = 20515u32;\npub const PropertyTagThumbnailCopyRight: u32 = 20539u32;\npub const PropertyTagThumbnailData: u32 = 20507u32;\npub const PropertyTagThumbnailDateTime: u32 = 20531u32;\npub const PropertyTagThumbnailEquipMake: u32 = 20518u32;\npub const PropertyTagThumbnailEquipModel: u32 = 20519u32;\npub const PropertyTagThumbnailFormat: u32 = 20498u32;\npub const PropertyTagThumbnailHeight: u32 = 20500u32;\npub const PropertyTagThumbnailImageDescription: u32 = 20517u32;\npub const PropertyTagThumbnailImageHeight: u32 = 20513u32;\npub const PropertyTagThumbnailImageWidth: u32 = 20512u32;\npub const PropertyTagThumbnailOrientation: u32 = 20521u32;\npub const PropertyTagThumbnailPhotometricInterp: u32 = 20516u32;\npub const PropertyTagThumbnailPlanarConfig: u32 = 20527u32;\npub const PropertyTagThumbnailPlanes: u32 = 20502u32;\npub const PropertyTagThumbnailPrimaryChromaticities: u32 = 20534u32;\npub const PropertyTagThumbnailRawBytes: u32 = 20503u32;\npub const PropertyTagThumbnailRefBlackWhite: u32 = 20538u32;\npub const PropertyTagThumbnailResolutionUnit: u32 = 20528u32;\npub const PropertyTagThumbnailResolutionX: u32 = 20525u32;\npub const PropertyTagThumbnailResolutionY: u32 = 20526u32;\npub const PropertyTagThumbnailRowsPerStrip: u32 = 20523u32;\npub const PropertyTagThumbnailSamplesPerPixel: u32 = 20522u32;\npub const PropertyTagThumbnailSize: u32 = 20504u32;\npub const PropertyTagThumbnailSoftwareUsed: u32 = 20530u32;\npub const PropertyTagThumbnailStripBytesCount: u32 = 20524u32;\npub const PropertyTagThumbnailStripOffsets: u32 = 20520u32;\npub const PropertyTagThumbnailTransferFunction: u32 = 20529u32;\npub const PropertyTagThumbnailWhitePoint: u32 = 20533u32;\npub const PropertyTagThumbnailWidth: u32 = 20499u32;\npub const PropertyTagThumbnailYCbCrCoefficients: u32 = 20535u32;\npub const PropertyTagThumbnailYCbCrPositioning: u32 = 20537u32;\npub const PropertyTagThumbnailYCbCrSubsampling: u32 = 20536u32;\npub const PropertyTagTileByteCounts: u32 = 325u32;\npub const PropertyTagTileLength: u32 = 323u32;\npub const PropertyTagTileOffset: u32 = 324u32;\npub const PropertyTagTileWidth: u32 = 322u32;\npub const PropertyTagTransferFuncition: u32 = 301u32;\npub const PropertyTagTransferRange: u32 = 342u32;\npub const PropertyTagTypeASCII: u32 = 2u32;\npub const PropertyTagTypeByte: u32 = 1u32;\npub const PropertyTagTypeLong: u32 = 4u32;\npub const PropertyTagTypeRational: u32 = 5u32;\npub const PropertyTagTypeSLONG: u32 = 9u32;\npub const PropertyTagTypeSRational: u32 = 10u32;\npub const PropertyTagTypeShort: u32 = 3u32;\npub const PropertyTagTypeUndefined: u32 = 7u32;\npub const PropertyTagWhitePoint: u32 = 318u32;\npub const PropertyTagXPosition: u32 = 286u32;\npub const PropertyTagXResolution: u32 = 282u32;\npub const PropertyTagYCbCrCoefficients: u32 = 529u32;\npub const PropertyTagYCbCrPositioning: u32 = 531u32;\npub const PropertyTagYCbCrSubsampling: u32 = 530u32;\npub const PropertyTagYPosition: u32 = 287u32;\npub const PropertyTagYResolution: u32 = 283u32;\npub type QualityMode = i32;\npub const QualityModeDefault: QualityMode = 0i32;\npub const QualityModeHigh: QualityMode = 2i32;\npub const QualityModeInvalid: QualityMode = -1i32;\npub const QualityModeLow: QualityMode = 1i32;\npub const RED_SHIFT: u32 = 16u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct Rect {\n    pub X: i32,\n    pub Y: i32,\n    pub Width: i32,\n    pub Height: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct RectF {\n    pub X: f32,\n    pub Y: f32,\n    pub Width: f32,\n    pub Height: f32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct RedEyeCorrection {\n    pub Base: Effect,\n}\npub const RedEyeCorrectionEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x74d29d05_69a4_4266_9549_3cc52836b632);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct RedEyeCorrectionParams {\n    pub numberOfAreas: u32,\n    pub areas: *mut super::super::Foundation::RECT,\n}\nimpl Default for RedEyeCorrectionParams {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type Region = isize;\npub const Rotate180FlipNone: RotateFlipType = 2i32;\npub const Rotate180FlipX: RotateFlipType = 6i32;\npub const Rotate180FlipXY: RotateFlipType = 0i32;\npub const Rotate180FlipY: RotateFlipType = 4i32;\npub const Rotate270FlipNone: RotateFlipType = 3i32;\npub const Rotate270FlipX: RotateFlipType = 7i32;\npub const Rotate270FlipXY: RotateFlipType = 1i32;\npub const Rotate270FlipY: RotateFlipType = 5i32;\npub const Rotate90FlipNone: RotateFlipType = 1i32;\npub const Rotate90FlipX: RotateFlipType = 5i32;\npub const Rotate90FlipXY: RotateFlipType = 3i32;\npub const Rotate90FlipY: RotateFlipType = 7i32;\npub type RotateFlipType = i32;\npub const RotateNoneFlipNone: RotateFlipType = 0i32;\npub const RotateNoneFlipX: RotateFlipType = 4i32;\npub const RotateNoneFlipXY: RotateFlipType = 2i32;\npub const RotateNoneFlipY: RotateFlipType = 6i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct Sharpen {\n    pub Base: Effect,\n}\npub const SharpenEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x63cbf3ee_c526_402c_8f71_62c540bf5142);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SharpenParams {\n    pub radius: f32,\n    pub amount: f32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct Size {\n    pub Width: i32,\n    pub Height: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SizeF {\n    pub Width: f32,\n    pub Height: f32,\n}\npub type SmoothingMode = i32;\npub const SmoothingModeAntiAlias: SmoothingMode = 4i32;\npub const SmoothingModeAntiAlias8x4: SmoothingMode = 4i32;\npub const SmoothingModeAntiAlias8x8: SmoothingMode = 5i32;\npub const SmoothingModeDefault: SmoothingMode = 0i32;\npub const SmoothingModeHighQuality: SmoothingMode = 2i32;\npub const SmoothingModeHighSpeed: SmoothingMode = 1i32;\npub const SmoothingModeInvalid: SmoothingMode = -1i32;\npub const SmoothingModeNone: SmoothingMode = 3i32;\npub type Status = i32;\npub type StringAlignment = i32;\npub const StringAlignmentCenter: StringAlignment = 1i32;\npub const StringAlignmentFar: StringAlignment = 2i32;\npub const StringAlignmentNear: StringAlignment = 0i32;\npub type StringDigitSubstitute = i32;\npub const StringDigitSubstituteNational: StringDigitSubstitute = 2i32;\npub const StringDigitSubstituteNone: StringDigitSubstitute = 1i32;\npub const StringDigitSubstituteTraditional: StringDigitSubstitute = 3i32;\npub const StringDigitSubstituteUser: StringDigitSubstitute = 0i32;\npub type StringFormatFlags = i32;\npub const StringFormatFlagsBypassGDI: StringFormatFlags = -2147483648i32;\npub const StringFormatFlagsDirectionRightToLeft: StringFormatFlags = 1i32;\npub const StringFormatFlagsDirectionVertical: StringFormatFlags = 2i32;\npub const StringFormatFlagsDisplayFormatControl: StringFormatFlags = 32i32;\npub const StringFormatFlagsLineLimit: StringFormatFlags = 8192i32;\npub const StringFormatFlagsMeasureTrailingSpaces: StringFormatFlags = 2048i32;\npub const StringFormatFlagsNoClip: StringFormatFlags = 16384i32;\npub const StringFormatFlagsNoFitBlackBox: StringFormatFlags = 4i32;\npub const StringFormatFlagsNoFontFallback: StringFormatFlags = 1024i32;\npub const StringFormatFlagsNoWrap: StringFormatFlags = 4096i32;\npub type StringTrimming = i32;\npub const StringTrimmingCharacter: StringTrimming = 1i32;\npub const StringTrimmingEllipsisCharacter: StringTrimming = 3i32;\npub const StringTrimmingEllipsisPath: StringTrimming = 5i32;\npub const StringTrimmingEllipsisWord: StringTrimming = 4i32;\npub const StringTrimmingNone: StringTrimming = 0i32;\npub const StringTrimmingWord: StringTrimming = 2i32;\npub const TestControlForceBilinear: GpTestControlEnum = 0i32;\npub const TestControlGetBuildNumber: GpTestControlEnum = 2i32;\npub const TestControlNoICM: GpTestControlEnum = 1i32;\npub type TextRenderingHint = i32;\npub const TextRenderingHintAntiAlias: TextRenderingHint = 4i32;\npub const TextRenderingHintAntiAliasGridFit: TextRenderingHint = 3i32;\npub const TextRenderingHintClearTypeGridFit: TextRenderingHint = 5i32;\npub const TextRenderingHintSingleBitPerPixel: TextRenderingHint = 2i32;\npub const TextRenderingHintSingleBitPerPixelGridFit: TextRenderingHint = 1i32;\npub const TextRenderingHintSystemDefault: TextRenderingHint = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct Tint {\n    pub Base: Effect,\n}\npub const TintEffectGuid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1077af00_2848_4441_9489_44ad4c2d7a2c);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TintParams {\n    pub hue: i32,\n    pub amount: i32,\n}\npub type Unit = i32;\npub const UnitDisplay: Unit = 1i32;\npub const UnitDocument: Unit = 5i32;\npub const UnitInch: Unit = 4i32;\npub const UnitMillimeter: Unit = 6i32;\npub const UnitPixel: Unit = 2i32;\npub const UnitPoint: Unit = 3i32;\npub const UnitWorld: Unit = 0i32;\npub const UnknownImageFormat: Status = 13i32;\npub const UnsupportedGdiplusVersion: Status = 17i32;\npub const ValueOverflow: Status = 11i32;\npub type WarpMode = i32;\npub const WarpModeBilinear: WarpMode = 1i32;\npub const WarpModePerspective: WarpMode = 0i32;\npub const Win32Error: Status = 7i32;\n#[repr(C, packed(2))]\n#[derive(Clone, Copy, Default)]\npub struct WmfPlaceableFileHeader {\n    pub Key: u32,\n    pub Hmf: i16,\n    pub BoundingBox: PWMFRect16,\n    pub Inch: i16,\n    pub Reserved: u32,\n    pub Checksum: i16,\n}\npub const WmfRecordTypeAbortDoc: EmfPlusRecordType = 65618i32;\npub const WmfRecordTypeAnimatePalette: EmfPlusRecordType = 66614i32;\npub const WmfRecordTypeArc: EmfPlusRecordType = 67607i32;\npub const WmfRecordTypeBitBlt: EmfPlusRecordType = 67874i32;\npub const WmfRecordTypeChord: EmfPlusRecordType = 67632i32;\npub const WmfRecordTypeCreateBitmap: EmfPlusRecordType = 67326i32;\npub const WmfRecordTypeCreateBitmapIndirect: EmfPlusRecordType = 66301i32;\npub const WmfRecordTypeCreateBrush: EmfPlusRecordType = 65784i32;\npub const WmfRecordTypeCreateBrushIndirect: EmfPlusRecordType = 66300i32;\npub const WmfRecordTypeCreateFontIndirect: EmfPlusRecordType = 66299i32;\npub const WmfRecordTypeCreatePalette: EmfPlusRecordType = 65783i32;\npub const WmfRecordTypeCreatePatternBrush: EmfPlusRecordType = 66041i32;\npub const WmfRecordTypeCreatePenIndirect: EmfPlusRecordType = 66298i32;\npub const WmfRecordTypeCreateRegion: EmfPlusRecordType = 67327i32;\npub const WmfRecordTypeDIBBitBlt: EmfPlusRecordType = 67904i32;\npub const WmfRecordTypeDIBCreatePatternBrush: EmfPlusRecordType = 65858i32;\npub const WmfRecordTypeDIBStretchBlt: EmfPlusRecordType = 68417i32;\npub const WmfRecordTypeDeleteObject: EmfPlusRecordType = 66032i32;\npub const WmfRecordTypeDrawText: EmfPlusRecordType = 67119i32;\npub const WmfRecordTypeEllipse: EmfPlusRecordType = 66584i32;\npub const WmfRecordTypeEndDoc: EmfPlusRecordType = 65630i32;\npub const WmfRecordTypeEndPage: EmfPlusRecordType = 65616i32;\npub const WmfRecordTypeEscape: EmfPlusRecordType = 67110i32;\npub const WmfRecordTypeExcludeClipRect: EmfPlusRecordType = 66581i32;\npub const WmfRecordTypeExtFloodFill: EmfPlusRecordType = 66888i32;\npub const WmfRecordTypeExtTextOut: EmfPlusRecordType = 68146i32;\npub const WmfRecordTypeFillRegion: EmfPlusRecordType = 66088i32;\npub const WmfRecordTypeFloodFill: EmfPlusRecordType = 66585i32;\npub const WmfRecordTypeFrameRegion: EmfPlusRecordType = 66601i32;\npub const WmfRecordTypeIntersectClipRect: EmfPlusRecordType = 66582i32;\npub const WmfRecordTypeInvertRegion: EmfPlusRecordType = 65834i32;\npub const WmfRecordTypeLineTo: EmfPlusRecordType = 66067i32;\npub const WmfRecordTypeMoveTo: EmfPlusRecordType = 66068i32;\npub const WmfRecordTypeOffsetClipRgn: EmfPlusRecordType = 66080i32;\npub const WmfRecordTypeOffsetViewportOrg: EmfPlusRecordType = 66065i32;\npub const WmfRecordTypeOffsetWindowOrg: EmfPlusRecordType = 66063i32;\npub const WmfRecordTypePaintRegion: EmfPlusRecordType = 65835i32;\npub const WmfRecordTypePatBlt: EmfPlusRecordType = 67101i32;\npub const WmfRecordTypePie: EmfPlusRecordType = 67610i32;\npub const WmfRecordTypePolyPolygon: EmfPlusRecordType = 66872i32;\npub const WmfRecordTypePolygon: EmfPlusRecordType = 66340i32;\npub const WmfRecordTypePolyline: EmfPlusRecordType = 66341i32;\npub const WmfRecordTypeRealizePalette: EmfPlusRecordType = 65589i32;\npub const WmfRecordTypeRectangle: EmfPlusRecordType = 66587i32;\npub const WmfRecordTypeResetDC: EmfPlusRecordType = 65868i32;\npub const WmfRecordTypeResizePalette: EmfPlusRecordType = 65849i32;\npub const WmfRecordTypeRestoreDC: EmfPlusRecordType = 65831i32;\npub const WmfRecordTypeRoundRect: EmfPlusRecordType = 67100i32;\npub const WmfRecordTypeSaveDC: EmfPlusRecordType = 65566i32;\npub const WmfRecordTypeScaleViewportExt: EmfPlusRecordType = 66578i32;\npub const WmfRecordTypeScaleWindowExt: EmfPlusRecordType = 66576i32;\npub const WmfRecordTypeSelectClipRegion: EmfPlusRecordType = 65836i32;\npub const WmfRecordTypeSelectObject: EmfPlusRecordType = 65837i32;\npub const WmfRecordTypeSelectPalette: EmfPlusRecordType = 66100i32;\npub const WmfRecordTypeSetBkColor: EmfPlusRecordType = 66049i32;\npub const WmfRecordTypeSetBkMode: EmfPlusRecordType = 65794i32;\npub const WmfRecordTypeSetDIBToDev: EmfPlusRecordType = 68915i32;\npub const WmfRecordTypeSetLayout: EmfPlusRecordType = 65865i32;\npub const WmfRecordTypeSetMapMode: EmfPlusRecordType = 65795i32;\npub const WmfRecordTypeSetMapperFlags: EmfPlusRecordType = 66097i32;\npub const WmfRecordTypeSetPalEntries: EmfPlusRecordType = 65591i32;\npub const WmfRecordTypeSetPixel: EmfPlusRecordType = 66591i32;\npub const WmfRecordTypeSetPolyFillMode: EmfPlusRecordType = 65798i32;\npub const WmfRecordTypeSetROP2: EmfPlusRecordType = 65796i32;\npub const WmfRecordTypeSetRelAbs: EmfPlusRecordType = 65797i32;\npub const WmfRecordTypeSetStretchBltMode: EmfPlusRecordType = 65799i32;\npub const WmfRecordTypeSetTextAlign: EmfPlusRecordType = 65838i32;\npub const WmfRecordTypeSetTextCharExtra: EmfPlusRecordType = 65800i32;\npub const WmfRecordTypeSetTextColor: EmfPlusRecordType = 66057i32;\npub const WmfRecordTypeSetTextJustification: EmfPlusRecordType = 66058i32;\npub const WmfRecordTypeSetViewportExt: EmfPlusRecordType = 66062i32;\npub const WmfRecordTypeSetViewportOrg: EmfPlusRecordType = 66061i32;\npub const WmfRecordTypeSetWindowExt: EmfPlusRecordType = 66060i32;\npub const WmfRecordTypeSetWindowOrg: EmfPlusRecordType = 66059i32;\npub const WmfRecordTypeStartDoc: EmfPlusRecordType = 65869i32;\npub const WmfRecordTypeStartPage: EmfPlusRecordType = 65615i32;\npub const WmfRecordTypeStretchBlt: EmfPlusRecordType = 68387i32;\npub const WmfRecordTypeStretchDIB: EmfPlusRecordType = 69443i32;\npub const WmfRecordTypeTextOut: EmfPlusRecordType = 66849i32;\npub type WrapMode = i32;\npub const WrapModeClamp: WrapMode = 4i32;\npub const WrapModeTile: WrapMode = 0i32;\npub const WrapModeTileFlipX: WrapMode = 1i32;\npub const WrapModeTileFlipXY: WrapMode = 3i32;\npub const WrapModeTileFlipY: WrapMode = 2i32;\npub const WrongState: Status = 8i32;\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/Media/Audio/mod.rs",
      "sha256": "73a52845a0e993cf10b3fe573a77b67ea20d9f98fce39397cd9417778b48cf97",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "#[cfg(all(feature = \"Win32_System_Com_StructuredStorage\", feature = \"Win32_System_Variant\"))]\nwindows_link::link!(\"mmdevapi.dll\" \"system\" fn ActivateAudioInterfaceAsync(deviceinterfacepath : windows_sys::core::PCWSTR, riid : *const windows_sys::core::GUID, activationparams : *const super::super::System::Com::StructuredStorage:: PROPVARIANT, completionhandler : * mut core::ffi::c_void, activationoperation : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn CoRegisterMessageFilter(lpmessagefilter : * mut core::ffi::c_void, lplpmessagefilter : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"windows.media.mediacontrol.dll\" \"system\" fn CreateCaptureAudioStateMonitor(audiostatemonitor : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"windows.media.mediacontrol.dll\" \"system\" fn CreateCaptureAudioStateMonitorForCategory(category : AUDIO_STREAM_CATEGORY, audiostatemonitor : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"windows.media.mediacontrol.dll\" \"system\" fn CreateCaptureAudioStateMonitorForCategoryAndDeviceId(category : AUDIO_STREAM_CATEGORY, deviceid : windows_sys::core::PCWSTR, audiostatemonitor : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"windows.media.mediacontrol.dll\" \"system\" fn CreateCaptureAudioStateMonitorForCategoryAndDeviceRole(category : AUDIO_STREAM_CATEGORY, role : ERole, audiostatemonitor : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"windows.media.mediacontrol.dll\" \"system\" fn CreateRenderAudioStateMonitor(audiostatemonitor : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"windows.media.mediacontrol.dll\" \"system\" fn CreateRenderAudioStateMonitorForCategory(category : AUDIO_STREAM_CATEGORY, audiostatemonitor : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"windows.media.mediacontrol.dll\" \"system\" fn CreateRenderAudioStateMonitorForCategoryAndDeviceId(category : AUDIO_STREAM_CATEGORY, deviceid : windows_sys::core::PCWSTR, audiostatemonitor : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"windows.media.mediacontrol.dll\" \"system\" fn CreateRenderAudioStateMonitorForCategoryAndDeviceRole(category : AUDIO_STREAM_CATEGORY, role : ERole, audiostatemonitor : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"winmm.dll\" \"system\" fn PlaySoundA(pszsound : windows_sys::core::PCSTR, hmod : super::super::Foundation:: HMODULE, fdwsound : SND_FLAGS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn PlaySoundW(pszsound : windows_sys::core::PCWSTR, hmod : super::super::Foundation:: HMODULE, fdwsound : SND_FLAGS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverAddA(phadid : *mut HACMDRIVERID, hinstmodule : super::super::Foundation:: HINSTANCE, lparam : super::super::Foundation:: LPARAM, dwpriority : u32, fdwadd : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverAddW(phadid : *mut HACMDRIVERID, hinstmodule : super::super::Foundation:: HINSTANCE, lparam : super::super::Foundation:: LPARAM, dwpriority : u32, fdwadd : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverClose(had : HACMDRIVER, fdwclose : u32) -> u32);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverDetailsA(hadid : HACMDRIVERID, padd : *mut ACMDRIVERDETAILSA, fdwdetails : u32) -> u32);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverDetailsW(hadid : HACMDRIVERID, padd : *mut ACMDRIVERDETAILSW, fdwdetails : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverEnum(fncallback : ACMDRIVERENUMCB, dwinstance : usize, fdwenum : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverID(hao : HACMOBJ, phadid : *mut HACMDRIVERID, fdwdriverid : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverMessage(had : HACMDRIVER, umsg : u32, lparam1 : super::super::Foundation:: LPARAM, lparam2 : super::super::Foundation:: LPARAM) -> super::super::Foundation:: LRESULT);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverOpen(phad : *mut HACMDRIVER, hadid : HACMDRIVERID, fdwopen : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverPriority(hadid : HACMDRIVERID, dwpriority : u32, fdwpriority : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmDriverRemove(hadid : HACMDRIVERID, fdwremove : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFilterChooseA(pafltrc : *mut ACMFILTERCHOOSEA) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFilterChooseW(pafltrc : *mut ACMFILTERCHOOSEW) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFilterDetailsA(had : HACMDRIVER, pafd : *mut ACMFILTERDETAILSA, fdwdetails : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFilterDetailsW(had : HACMDRIVER, pafd : *mut ACMFILTERDETAILSW, fdwdetails : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFilterEnumA(had : HACMDRIVER, pafd : *mut ACMFILTERDETAILSA, fncallback : ACMFILTERENUMCBA, dwinstance : usize, fdwenum : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFilterEnumW(had : HACMDRIVER, pafd : *mut ACMFILTERDETAILSW, fncallback : ACMFILTERENUMCBW, dwinstance : usize, fdwenum : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFilterTagDetailsA(had : HACMDRIVER, paftd : *mut ACMFILTERTAGDETAILSA, fdwdetails : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFilterTagDetailsW(had : HACMDRIVER, paftd : *mut ACMFILTERTAGDETAILSW, fdwdetails : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFilterTagEnumA(had : HACMDRIVER, paftd : *mut ACMFILTERTAGDETAILSA, fncallback : ACMFILTERTAGENUMCBA, dwinstance : usize, fdwenum : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFilterTagEnumW(had : HACMDRIVER, paftd : *mut ACMFILTERTAGDETAILSW, fncallback : ACMFILTERTAGENUMCBW, dwinstance : usize, fdwenum : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatChooseA(pafmtc : *mut ACMFORMATCHOOSEA) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatChooseW(pafmtc : *mut ACMFORMATCHOOSEW) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatDetailsA(had : HACMDRIVER, pafd : *mut ACMFORMATDETAILSA, fdwdetails : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatDetailsW(had : HACMDRIVER, pafd : *mut tACMFORMATDETAILSW, fdwdetails : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatEnumA(had : HACMDRIVER, pafd : *mut ACMFORMATDETAILSA, fncallback : ACMFORMATENUMCBA, dwinstance : usize, fdwenum : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatEnumW(had : HACMDRIVER, pafd : *mut tACMFORMATDETAILSW, fncallback : ACMFORMATENUMCBW, dwinstance : usize, fdwenum : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatSuggest(had : HACMDRIVER, pwfxsrc : *mut WAVEFORMATEX, pwfxdst : *mut WAVEFORMATEX, cbwfxdst : u32, fdwsuggest : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatTagDetailsA(had : HACMDRIVER, paftd : *mut ACMFORMATTAGDETAILSA, fdwdetails : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatTagDetailsW(had : HACMDRIVER, paftd : *mut ACMFORMATTAGDETAILSW, fdwdetails : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatTagEnumA(had : HACMDRIVER, paftd : *mut ACMFORMATTAGDETAILSA, fncallback : ACMFORMATTAGENUMCBA, dwinstance : usize, fdwenum : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmFormatTagEnumW(had : HACMDRIVER, paftd : *mut ACMFORMATTAGDETAILSW, fncallback : ACMFORMATTAGENUMCBW, dwinstance : usize, fdwenum : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmGetVersion() -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmMetrics(hao : HACMOBJ, umetric : u32, pmetric : *mut core::ffi::c_void) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmStreamClose(has : HACMSTREAM, fdwclose : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmStreamConvert(has : HACMSTREAM, pash : *mut ACMSTREAMHEADER, fdwconvert : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmStreamMessage(has : HACMSTREAM, umsg : u32, lparam1 : super::super::Foundation:: LPARAM, lparam2 : super::super::Foundation:: LPARAM) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmStreamOpen(phas : *mut HACMSTREAM, had : HACMDRIVER, pwfxsrc : *mut WAVEFORMATEX, pwfxdst : *mut WAVEFORMATEX, pwfltr : *mut WAVEFILTER, dwcallback : usize, dwinstance : usize, fdwopen : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmStreamPrepareHeader(has : HACMSTREAM, pash : *mut ACMSTREAMHEADER, fdwprepare : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmStreamReset(has : HACMSTREAM, fdwreset : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmStreamSize(has : HACMSTREAM, cbinput : u32, pdwoutputbytes : *mut u32, fdwsize : u32) -> u32);\nwindows_link::link!(\"msacm32.dll\" \"system\" fn acmStreamUnprepareHeader(has : HACMSTREAM, pash : *mut ACMSTREAMHEADER, fdwunprepare : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn auxGetDevCapsA(udeviceid : usize, pac : *mut AUXCAPSA, cbac : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn auxGetDevCapsW(udeviceid : usize, pac : *mut AUXCAPSW, cbac : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn auxGetNumDevs() -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn auxGetVolume(udeviceid : u32, pdwvolume : *mut u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn auxOutMessage(udeviceid : u32, umsg : u32, dw1 : usize, dw2 : usize) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn auxSetVolume(udeviceid : u32, dwvolume : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiConnect(hmi : HMIDI, hmo : HMIDIOUT, preserved : *const core::ffi::c_void) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiDisconnect(hmi : HMIDI, hmo : HMIDIOUT, preserved : *const core::ffi::c_void) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInAddBuffer(hmi : HMIDIIN, pmh : *mut MIDIHDR, cbmh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInClose(hmi : HMIDIIN) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInGetDevCapsA(udeviceid : usize, pmic : *mut MIDIINCAPSA, cbmic : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInGetDevCapsW(udeviceid : usize, pmic : *mut MIDIINCAPSW, cbmic : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInGetErrorTextA(mmrerror : u32, psztext : windows_sys::core::PSTR, cchtext : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInGetErrorTextW(mmrerror : u32, psztext : windows_sys::core::PWSTR, cchtext : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInGetID(hmi : HMIDIIN, pudeviceid : *mut u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInGetNumDevs() -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInMessage(hmi : HMIDIIN, umsg : u32, dw1 : usize, dw2 : usize) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInOpen(phmi : *mut HMIDIIN, udeviceid : u32, dwcallback : usize, dwinstance : usize, fdwopen : MIDI_WAVE_OPEN_TYPE) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInPrepareHeader(hmi : HMIDIIN, pmh : *mut MIDIHDR, cbmh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInReset(hmi : HMIDIIN) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInStart(hmi : HMIDIIN) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInStop(hmi : HMIDIIN) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiInUnprepareHeader(hmi : HMIDIIN, pmh : *mut MIDIHDR, cbmh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutCacheDrumPatches(hmo : HMIDIOUT, upatch : u32, pwkya : *const u16, fucache : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutCachePatches(hmo : HMIDIOUT, ubank : u32, pwpa : *const u16, fucache : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutClose(hmo : HMIDIOUT) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutGetDevCapsA(udeviceid : usize, pmoc : *mut MIDIOUTCAPSA, cbmoc : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutGetDevCapsW(udeviceid : usize, pmoc : *mut MIDIOUTCAPSW, cbmoc : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutGetErrorTextA(mmrerror : u32, psztext : windows_sys::core::PSTR, cchtext : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutGetErrorTextW(mmrerror : u32, psztext : windows_sys::core::PWSTR, cchtext : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutGetID(hmo : HMIDIOUT, pudeviceid : *mut u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutGetNumDevs() -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutGetVolume(hmo : HMIDIOUT, pdwvolume : *mut u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutLongMsg(hmo : HMIDIOUT, pmh : *const MIDIHDR, cbmh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutMessage(hmo : HMIDIOUT, umsg : u32, dw1 : usize, dw2 : usize) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutOpen(phmo : *mut HMIDIOUT, udeviceid : u32, dwcallback : usize, dwinstance : usize, fdwopen : MIDI_WAVE_OPEN_TYPE) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutPrepareHeader(hmo : HMIDIOUT, pmh : *mut MIDIHDR, cbmh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutReset(hmo : HMIDIOUT) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutSetVolume(hmo : HMIDIOUT, dwvolume : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutShortMsg(hmo : HMIDIOUT, dwmsg : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiOutUnprepareHeader(hmo : HMIDIOUT, pmh : *mut MIDIHDR, cbmh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiStreamClose(hms : HMIDISTRM) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiStreamOpen(phms : *mut HMIDISTRM, pudeviceid : *mut u32, cmidi : u32, dwcallback : usize, dwinstance : usize, fdwopen : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiStreamOut(hms : HMIDISTRM, pmh : *mut MIDIHDR, cbmh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiStreamPause(hms : HMIDISTRM) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiStreamPosition(hms : HMIDISTRM, lpmmt : *mut super:: MMTIME, cbmmt : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiStreamProperty(hms : HMIDISTRM, lppropdata : *mut u8, dwproperty : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiStreamRestart(hms : HMIDISTRM) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn midiStreamStop(hms : HMIDISTRM) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerClose(hmx : HMIXER) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerGetControlDetailsA(hmxobj : HMIXEROBJ, pmxcd : *mut MIXERCONTROLDETAILS, fdwdetails : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerGetControlDetailsW(hmxobj : HMIXEROBJ, pmxcd : *mut MIXERCONTROLDETAILS, fdwdetails : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerGetDevCapsA(umxid : usize, pmxcaps : *mut MIXERCAPSA, cbmxcaps : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerGetDevCapsW(umxid : usize, pmxcaps : *mut MIXERCAPSW, cbmxcaps : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerGetID(hmxobj : HMIXEROBJ, pumxid : *mut u32, fdwid : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerGetLineControlsA(hmxobj : HMIXEROBJ, pmxlc : *mut MIXERLINECONTROLSA, fdwcontrols : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerGetLineControlsW(hmxobj : HMIXEROBJ, pmxlc : *mut MIXERLINECONTROLSW, fdwcontrols : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerGetLineInfoA(hmxobj : HMIXEROBJ, pmxl : *mut MIXERLINEA, fdwinfo : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerGetLineInfoW(hmxobj : HMIXEROBJ, pmxl : *mut MIXERLINEW, fdwinfo : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerGetNumDevs() -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerMessage(hmx : HMIXER, umsg : u32, dwparam1 : usize, dwparam2 : usize) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerOpen(phmx : *mut HMIXER, umxid : u32, dwcallback : usize, dwinstance : usize, fdwopen : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mixerSetControlDetails(hmxobj : HMIXEROBJ, pmxcd : *const MIXERCONTROLDETAILS, fdwdetails : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn sndPlaySoundA(pszsound : windows_sys::core::PCSTR, fusound : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn sndPlaySoundW(pszsound : windows_sys::core::PCWSTR, fusound : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInAddBuffer(hwi : HWAVEIN, pwh : *mut WAVEHDR, cbwh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInClose(hwi : HWAVEIN) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInGetDevCapsA(udeviceid : usize, pwic : *mut WAVEINCAPSA, cbwic : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInGetDevCapsW(udeviceid : usize, pwic : *mut WAVEINCAPSW, cbwic : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInGetErrorTextA(mmrerror : u32, psztext : windows_sys::core::PSTR, cchtext : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInGetErrorTextW(mmrerror : u32, psztext : windows_sys::core::PWSTR, cchtext : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInGetID(hwi : HWAVEIN, pudeviceid : *const u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInGetNumDevs() -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInGetPosition(hwi : HWAVEIN, pmmt : *mut super:: MMTIME, cbmmt : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInMessage(hwi : HWAVEIN, umsg : u32, dw1 : usize, dw2 : usize) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInOpen(phwi : *mut HWAVEIN, udeviceid : u32, pwfx : *const WAVEFORMATEX, dwcallback : usize, dwinstance : usize, fdwopen : MIDI_WAVE_OPEN_TYPE) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInPrepareHeader(hwi : HWAVEIN, pwh : *mut WAVEHDR, cbwh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInReset(hwi : HWAVEIN) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInStart(hwi : HWAVEIN) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInStop(hwi : HWAVEIN) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveInUnprepareHeader(hwi : HWAVEIN, pwh : *mut WAVEHDR, cbwh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutBreakLoop(hwo : HWAVEOUT) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutClose(hwo : HWAVEOUT) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutGetDevCapsA(udeviceid : usize, pwoc : *mut WAVEOUTCAPSA, cbwoc : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutGetDevCapsW(udeviceid : usize, pwoc : *mut WAVEOUTCAPSW, cbwoc : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutGetErrorTextA(mmrerror : u32, psztext : windows_sys::core::PSTR, cchtext : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutGetErrorTextW(mmrerror : u32, psztext : windows_sys::core::PWSTR, cchtext : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutGetID(hwo : HWAVEOUT, pudeviceid : *mut u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutGetNumDevs() -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutGetPitch(hwo : HWAVEOUT, pdwpitch : *mut u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutGetPlaybackRate(hwo : HWAVEOUT, pdwrate : *mut u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutGetPosition(hwo : HWAVEOUT, pmmt : *mut super:: MMTIME, cbmmt : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutGetVolume(hwo : HWAVEOUT, pdwvolume : *mut u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutMessage(hwo : HWAVEOUT, umsg : u32, dw1 : usize, dw2 : usize) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutOpen(phwo : *mut HWAVEOUT, udeviceid : u32, pwfx : *const WAVEFORMATEX, dwcallback : usize, dwinstance : usize, fdwopen : MIDI_WAVE_OPEN_TYPE) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutPause(hwo : HWAVEOUT) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutPrepareHeader(hwo : HWAVEOUT, pwh : *mut WAVEHDR, cbwh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutReset(hwo : HWAVEOUT) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutRestart(hwo : HWAVEOUT) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutSetPitch(hwo : HWAVEOUT, dwpitch : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutSetPlaybackRate(hwo : HWAVEOUT, dwrate : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutSetVolume(hwo : HWAVEOUT, dwvolume : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutUnprepareHeader(hwo : HWAVEOUT, pwh : *mut WAVEHDR, cbwh : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn waveOutWrite(hwo : HWAVEOUT, pwh : *mut WAVEHDR, cbwh : u32) -> u32);\npub const ACMDM_DRIVER_ABOUT: u32 = 24587u32;\npub const ACMDM_DRIVER_DETAILS: u32 = 24586u32;\npub const ACMDM_DRIVER_NOTIFY: u32 = 24577u32;\npub const ACMDM_FILTERTAG_DETAILS: u32 = 24626u32;\npub const ACMDM_FILTER_DETAILS: u32 = 24627u32;\npub const ACMDM_FORMATTAG_DETAILS: u32 = 24601u32;\npub const ACMDM_FORMAT_DETAILS: u32 = 24602u32;\npub const ACMDM_FORMAT_SUGGEST: u32 = 24603u32;\npub const ACMDM_HARDWARE_WAVE_CAPS_INPUT: u32 = 24596u32;\npub const ACMDM_HARDWARE_WAVE_CAPS_OUTPUT: u32 = 24597u32;\npub const ACMDM_RESERVED_HIGH: u32 = 28671u32;\npub const ACMDM_RESERVED_LOW: u32 = 24576u32;\npub const ACMDM_STREAM_CLOSE: u32 = 24653u32;\npub const ACMDM_STREAM_CONVERT: u32 = 24655u32;\npub const ACMDM_STREAM_OPEN: u32 = 24652u32;\npub const ACMDM_STREAM_PREPARE: u32 = 24657u32;\npub const ACMDM_STREAM_RESET: u32 = 24656u32;\npub const ACMDM_STREAM_SIZE: u32 = 24654u32;\npub const ACMDM_STREAM_UNPREPARE: u32 = 24658u32;\npub const ACMDM_STREAM_UPDATE: u32 = 24659u32;\npub const ACMDM_USER: u32 = 16384u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\n#[derive(Clone, Copy)]\npub struct ACMDRIVERDETAILSA {\n    pub cbStruct: u32,\n    pub fccType: u32,\n    pub fccComp: u32,\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vdwACM: u32,\n    pub vdwDriver: u32,\n    pub fdwSupport: u32,\n    pub cFormatTags: u32,\n    pub cFilterTags: u32,\n    pub hicon: super::super::UI::WindowsAndMessaging::HICON,\n    pub szShortName: [i8; 32],\n    pub szLongName: [i8; 128],\n    pub szCopyright: [i8; 80],\n    pub szLicensing: [i8; 128],\n    pub szFeatures: [i8; 512],\n}\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nimpl Default for ACMDRIVERDETAILSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\n#[derive(Clone, Copy)]\npub struct ACMDRIVERDETAILSW {\n    pub cbStruct: u32,\n    pub fccType: u32,\n    pub fccComp: u32,\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vdwACM: u32,\n    pub vdwDriver: u32,\n    pub fdwSupport: u32,\n    pub cFormatTags: u32,\n    pub cFilterTags: u32,\n    pub hicon: super::super::UI::WindowsAndMessaging::HICON,\n    pub szShortName: [u16; 32],\n    pub szLongName: [u16; 128],\n    pub szCopyright: [u16; 80],\n    pub szLicensing: [u16; 128],\n    pub szFeatures: [u16; 512],\n}\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nimpl Default for ACMDRIVERDETAILSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ACMDRIVERDETAILS_COPYRIGHT_CHARS: u32 = 80u32;\npub const ACMDRIVERDETAILS_FEATURES_CHARS: u32 = 512u32;\npub const ACMDRIVERDETAILS_LICENSING_CHARS: u32 = 128u32;\npub const ACMDRIVERDETAILS_LONGNAME_CHARS: u32 = 128u32;\npub const ACMDRIVERDETAILS_SHORTNAME_CHARS: u32 = 32u32;\npub const ACMDRIVERDETAILS_SUPPORTF_ASYNC: i32 = 16i32;\npub const ACMDRIVERDETAILS_SUPPORTF_CODEC: i32 = 1i32;\npub const ACMDRIVERDETAILS_SUPPORTF_CONVERTER: i32 = 2i32;\npub const ACMDRIVERDETAILS_SUPPORTF_DISABLED: i32 = -2147483648i32;\npub const ACMDRIVERDETAILS_SUPPORTF_FILTER: i32 = 4i32;\npub const ACMDRIVERDETAILS_SUPPORTF_HARDWARE: i32 = 8i32;\npub const ACMDRIVERDETAILS_SUPPORTF_LOCAL: i32 = 1073741824i32;\npub type ACMDRIVERENUMCB = Option<unsafe extern \"system\" fn(hadid: HACMDRIVERID, dwinstance: usize, fdwsupport: u32) -> windows_sys::core::BOOL>;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMDRVFORMATSUGGEST {\n    pub cbStruct: u32,\n    pub fdwSuggest: u32,\n    pub pwfxSrc: *mut WAVEFORMATEX,\n    pub cbwfxSrc: u32,\n    pub pwfxDst: *mut WAVEFORMATEX,\n    pub cbwfxDst: u32,\n}\nimpl Default for ACMDRVFORMATSUGGEST {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMDRVOPENDESCA {\n    pub cbStruct: u32,\n    pub fccType: u32,\n    pub fccComp: u32,\n    pub dwVersion: u32,\n    pub dwFlags: u32,\n    pub dwError: u32,\n    pub pszSectionName: windows_sys::core::PCSTR,\n    pub pszAliasName: windows_sys::core::PCSTR,\n    pub dnDevNode: u32,\n}\nimpl Default for ACMDRVOPENDESCA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMDRVOPENDESCW {\n    pub cbStruct: u32,\n    pub fccType: u32,\n    pub fccComp: u32,\n    pub dwVersion: u32,\n    pub dwFlags: u32,\n    pub dwError: u32,\n    pub pszSectionName: windows_sys::core::PCWSTR,\n    pub pszAliasName: windows_sys::core::PCWSTR,\n    pub dnDevNode: u32,\n}\nimpl Default for ACMDRVOPENDESCW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMDRVSTREAMHEADER {\n    pub cbStruct: u32,\n    pub fdwStatus: u32,\n    pub dwUser: usize,\n    pub pbSrc: *mut u8,\n    pub cbSrcLength: u32,\n    pub cbSrcLengthUsed: u32,\n    pub dwSrcUser: usize,\n    pub pbDst: *mut u8,\n    pub cbDstLength: u32,\n    pub cbDstLengthUsed: u32,\n    pub dwDstUser: usize,\n    pub fdwConvert: u32,\n    pub padshNext: *mut ACMDRVSTREAMHEADER,\n    pub fdwDriver: u32,\n    pub dwDriver: usize,\n    pub fdwPrepared: u32,\n    pub dwPrepared: usize,\n    pub pbPreparedSrc: *mut u8,\n    pub cbPreparedSrcLength: u32,\n    pub pbPreparedDst: *mut u8,\n    pub cbPreparedDstLength: u32,\n}\nimpl Default for ACMDRVSTREAMHEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMDRVSTREAMINSTANCE {\n    pub cbStruct: u32,\n    pub pwfxSrc: *mut WAVEFORMATEX,\n    pub pwfxDst: *mut WAVEFORMATEX,\n    pub pwfltr: *mut WAVEFILTER,\n    pub dwCallback: usize,\n    pub dwInstance: usize,\n    pub fdwOpen: u32,\n    pub fdwDriver: u32,\n    pub dwDriver: usize,\n    pub has: HACMSTREAM,\n}\nimpl Default for ACMDRVSTREAMINSTANCE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct ACMDRVSTREAMSIZE {\n    pub cbStruct: u32,\n    pub fdwSize: u32,\n    pub cbSrcLength: u32,\n    pub cbDstLength: u32,\n}\npub const ACMERR_BASE: u32 = 512u32;\npub const ACMERR_BUSY: u32 = 513u32;\npub const ACMERR_CANCELED: u32 = 515u32;\npub const ACMERR_NOTPOSSIBLE: u32 = 512u32;\npub const ACMERR_UNPREPARED: u32 = 514u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFILTERCHOOSEA {\n    pub cbStruct: u32,\n    pub fdwStyle: u32,\n    pub hwndOwner: super::super::Foundation::HWND,\n    pub pwfltr: *mut WAVEFILTER,\n    pub cbwfltr: u32,\n    pub pszTitle: windows_sys::core::PCSTR,\n    pub szFilterTag: [i8; 48],\n    pub szFilter: [i8; 128],\n    pub pszName: windows_sys::core::PSTR,\n    pub cchName: u32,\n    pub fdwEnum: u32,\n    pub pwfltrEnum: *mut WAVEFILTER,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub pszTemplateName: windows_sys::core::PCSTR,\n    pub lCustData: super::super::Foundation::LPARAM,\n    pub pfnHook: ACMFILTERCHOOSEHOOKPROCA,\n}\nimpl Default for ACMFILTERCHOOSEA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type ACMFILTERCHOOSEHOOKPROCA = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, umsg: u32, wparam: super::super::Foundation::WPARAM, lparam: super::super::Foundation::LPARAM) -> u32>;\npub type ACMFILTERCHOOSEHOOKPROCW = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, umsg: u32, wparam: super::super::Foundation::WPARAM, lparam: super::super::Foundation::LPARAM) -> u32>;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFILTERCHOOSEW {\n    pub cbStruct: u32,\n    pub fdwStyle: u32,\n    pub hwndOwner: super::super::Foundation::HWND,\n    pub pwfltr: *mut WAVEFILTER,\n    pub cbwfltr: u32,\n    pub pszTitle: windows_sys::core::PCWSTR,\n    pub szFilterTag: [u16; 48],\n    pub szFilter: [u16; 128],\n    pub pszName: windows_sys::core::PWSTR,\n    pub cchName: u32,\n    pub fdwEnum: u32,\n    pub pwfltrEnum: *mut WAVEFILTER,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub pszTemplateName: windows_sys::core::PCWSTR,\n    pub lCustData: super::super::Foundation::LPARAM,\n    pub pfnHook: ACMFILTERCHOOSEHOOKPROCW,\n}\nimpl Default for ACMFILTERCHOOSEW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ACMFILTERCHOOSE_STYLEF_CONTEXTHELP: i32 = 128i32;\npub const ACMFILTERCHOOSE_STYLEF_ENABLEHOOK: i32 = 8i32;\npub const ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATE: i32 = 16i32;\npub const ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATEHANDLE: i32 = 32i32;\npub const ACMFILTERCHOOSE_STYLEF_INITTOFILTERSTRUCT: i32 = 64i32;\npub const ACMFILTERCHOOSE_STYLEF_SHOWHELP: i32 = 4i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFILTERDETAILSA {\n    pub cbStruct: u32,\n    pub dwFilterIndex: u32,\n    pub dwFilterTag: u32,\n    pub fdwSupport: u32,\n    pub pwfltr: *mut WAVEFILTER,\n    pub cbwfltr: u32,\n    pub szFilter: [i8; 128],\n}\nimpl Default for ACMFILTERDETAILSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFILTERDETAILSW {\n    pub cbStruct: u32,\n    pub dwFilterIndex: u32,\n    pub dwFilterTag: u32,\n    pub fdwSupport: u32,\n    pub pwfltr: *mut WAVEFILTER,\n    pub cbwfltr: u32,\n    pub szFilter: [u16; 128],\n}\nimpl Default for ACMFILTERDETAILSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ACMFILTERDETAILS_FILTER_CHARS: u32 = 128u32;\npub type ACMFILTERENUMCBA = Option<unsafe extern \"system\" fn(hadid: HACMDRIVERID, pafd: *mut ACMFILTERDETAILSA, dwinstance: usize, fdwsupport: u32) -> windows_sys::core::BOOL>;\npub type ACMFILTERENUMCBW = Option<unsafe extern \"system\" fn(hadid: HACMDRIVERID, pafd: *mut ACMFILTERDETAILSW, dwinstance: usize, fdwsupport: u32) -> windows_sys::core::BOOL>;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFILTERTAGDETAILSA {\n    pub cbStruct: u32,\n    pub dwFilterTagIndex: u32,\n    pub dwFilterTag: u32,\n    pub cbFilterSize: u32,\n    pub fdwSupport: u32,\n    pub cStandardFilters: u32,\n    pub szFilterTag: [i8; 48],\n}\nimpl Default for ACMFILTERTAGDETAILSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFILTERTAGDETAILSW {\n    pub cbStruct: u32,\n    pub dwFilterTagIndex: u32,\n    pub dwFilterTag: u32,\n    pub cbFilterSize: u32,\n    pub fdwSupport: u32,\n    pub cStandardFilters: u32,\n    pub szFilterTag: [u16; 48],\n}\nimpl Default for ACMFILTERTAGDETAILSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ACMFILTERTAGDETAILS_FILTERTAG_CHARS: u32 = 48u32;\npub type ACMFILTERTAGENUMCBA = Option<unsafe extern \"system\" fn(hadid: HACMDRIVERID, paftd: *mut ACMFILTERTAGDETAILSA, dwinstance: usize, fdwsupport: u32) -> windows_sys::core::BOOL>;\npub type ACMFILTERTAGENUMCBW = Option<unsafe extern \"system\" fn(hadid: HACMDRIVERID, paftd: *mut ACMFILTERTAGDETAILSW, dwinstance: usize, fdwsupport: u32) -> windows_sys::core::BOOL>;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFORMATCHOOSEA {\n    pub cbStruct: u32,\n    pub fdwStyle: u32,\n    pub hwndOwner: super::super::Foundation::HWND,\n    pub pwfx: *mut WAVEFORMATEX,\n    pub cbwfx: u32,\n    pub pszTitle: windows_sys::core::PCSTR,\n    pub szFormatTag: [i8; 48],\n    pub szFormat: [i8; 128],\n    pub pszName: windows_sys::core::PSTR,\n    pub cchName: u32,\n    pub fdwEnum: u32,\n    pub pwfxEnum: *mut WAVEFORMATEX,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub pszTemplateName: windows_sys::core::PCSTR,\n    pub lCustData: super::super::Foundation::LPARAM,\n    pub pfnHook: ACMFORMATCHOOSEHOOKPROCA,\n}\nimpl Default for ACMFORMATCHOOSEA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type ACMFORMATCHOOSEHOOKPROCA = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, umsg: u32, wparam: super::super::Foundation::WPARAM, lparam: super::super::Foundation::LPARAM) -> u32>;\npub type ACMFORMATCHOOSEHOOKPROCW = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, umsg: u32, wparam: super::super::Foundation::WPARAM, lparam: super::super::Foundation::LPARAM) -> u32>;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFORMATCHOOSEW {\n    pub cbStruct: u32,\n    pub fdwStyle: u32,\n    pub hwndOwner: super::super::Foundation::HWND,\n    pub pwfx: *mut WAVEFORMATEX,\n    pub cbwfx: u32,\n    pub pszTitle: windows_sys::core::PCWSTR,\n    pub szFormatTag: [u16; 48],\n    pub szFormat: [u16; 128],\n    pub pszName: windows_sys::core::PWSTR,\n    pub cchName: u32,\n    pub fdwEnum: u32,\n    pub pwfxEnum: *mut WAVEFORMATEX,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub pszTemplateName: windows_sys::core::PCWSTR,\n    pub lCustData: super::super::Foundation::LPARAM,\n    pub pfnHook: ACMFORMATCHOOSEHOOKPROCW,\n}\nimpl Default for ACMFORMATCHOOSEW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ACMFORMATCHOOSE_STYLEF_CONTEXTHELP: i32 = 128i32;\npub const ACMFORMATCHOOSE_STYLEF_ENABLEHOOK: i32 = 8i32;\npub const ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE: i32 = 16i32;\npub const ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE: i32 = 32i32;\npub const ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT: i32 = 64i32;\npub const ACMFORMATCHOOSE_STYLEF_SHOWHELP: i32 = 4i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFORMATDETAILSA {\n    pub cbStruct: u32,\n    pub dwFormatIndex: u32,\n    pub dwFormatTag: u32,\n    pub fdwSupport: u32,\n    pub pwfx: *mut WAVEFORMATEX,\n    pub cbwfx: u32,\n    pub szFormat: [i8; 128],\n}\nimpl Default for ACMFORMATDETAILSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ACMFORMATDETAILS_FORMAT_CHARS: u32 = 128u32;\npub type ACMFORMATENUMCBA = Option<unsafe extern \"system\" fn(hadid: HACMDRIVERID, pafd: *mut ACMFORMATDETAILSA, dwinstance: usize, fdwsupport: u32) -> windows_sys::core::BOOL>;\npub type ACMFORMATENUMCBW = Option<unsafe extern \"system\" fn(hadid: HACMDRIVERID, pafd: *mut tACMFORMATDETAILSW, dwinstance: usize, fdwsupport: u32) -> windows_sys::core::BOOL>;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFORMATTAGDETAILSA {\n    pub cbStruct: u32,\n    pub dwFormatTagIndex: u32,\n    pub dwFormatTag: u32,\n    pub cbFormatSize: u32,\n    pub fdwSupport: u32,\n    pub cStandardFormats: u32,\n    pub szFormatTag: [i8; 48],\n}\nimpl Default for ACMFORMATTAGDETAILSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct ACMFORMATTAGDETAILSW {\n    pub cbStruct: u32,\n    pub dwFormatTagIndex: u32,\n    pub dwFormatTag: u32,\n    pub cbFormatSize: u32,\n    pub fdwSupport: u32,\n    pub cStandardFormats: u32,\n    pub szFormatTag: [u16; 48],\n}\nimpl Default for ACMFORMATTAGDETAILSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ACMFORMATTAGDETAILS_FORMATTAG_CHARS: u32 = 48u32;\npub type ACMFORMATTAGENUMCBA = Option<unsafe extern \"system\" fn(hadid: HACMDRIVERID, paftd: *mut ACMFORMATTAGDETAILSA, dwinstance: usize, fdwsupport: u32) -> windows_sys::core::BOOL>;\npub type ACMFORMATTAGENUMCBW = Option<unsafe extern \"system\" fn(hadid: HACMDRIVERID, paftd: *mut ACMFORMATTAGDETAILSW, dwinstance: usize, fdwsupport: u32) -> windows_sys::core::BOOL>;\npub const ACMHELPMSGCONTEXTHELP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"acmchoose_contexthelp\");\npub const ACMHELPMSGCONTEXTHELPA: windows_sys::core::PCSTR = windows_sys::core::s!(\"acmchoose_contexthelp\");\npub const ACMHELPMSGCONTEXTHELPW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"acmchoose_contexthelp\");\npub const ACMHELPMSGCONTEXTMENU: windows_sys::core::PCWSTR = windows_sys::core::w!(\"acmchoose_contextmenu\");\npub const ACMHELPMSGCONTEXTMENUA: windows_sys::core::PCSTR = windows_sys::core::s!(\"acmchoose_contextmenu\");\npub const ACMHELPMSGCONTEXTMENUW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"acmchoose_contextmenu\");\npub const ACMHELPMSGSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"acmchoose_help\");\npub const ACMHELPMSGSTRINGA: windows_sys::core::PCSTR = windows_sys::core::s!(\"acmchoose_help\");\npub const ACMHELPMSGSTRINGW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"acmchoose_help\");\n#[repr(C, packed(1))]\n#[cfg(target_arch = \"x86\")]\n#[derive(Clone, Copy)]\npub struct ACMSTREAMHEADER {\n    pub cbStruct: u32,\n    pub fdwStatus: u32,\n    pub dwUser: usize,\n    pub pbSrc: *mut u8,\n    pub cbSrcLength: u32,\n    pub cbSrcLengthUsed: u32,\n    pub dwSrcUser: usize,\n    pub pbDst: *mut u8,\n    pub cbDstLength: u32,\n    pub cbDstLengthUsed: u32,\n    pub dwDstUser: usize,\n    pub dwReservedDriver: [u32; 10],\n}\n#[cfg(target_arch = \"x86\")]\nimpl Default for ACMSTREAMHEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\n#[derive(Clone, Copy)]\npub struct ACMSTREAMHEADER {\n    pub cbStruct: u32,\n    pub fdwStatus: u32,\n    pub dwUser: usize,\n    pub pbSrc: *mut u8,\n    pub cbSrcLength: u32,\n    pub cbSrcLengthUsed: u32,\n    pub dwSrcUser: usize,\n    pub pbDst: *mut u8,\n    pub cbDstLength: u32,\n    pub cbDstLengthUsed: u32,\n    pub dwDstUser: usize,\n    pub dwReservedDriver: [u32; 15],\n}\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\nimpl Default for ACMSTREAMHEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ACMSTREAMHEADER_STATUSF_DONE: i32 = 65536i32;\npub const ACMSTREAMHEADER_STATUSF_INQUEUE: i32 = 1048576i32;\npub const ACMSTREAMHEADER_STATUSF_PREPARED: i32 = 131072i32;\npub const ACM_DRIVERADDF_FUNCTION: i32 = 3i32;\npub const ACM_DRIVERADDF_GLOBAL: i32 = 8i32;\npub const ACM_DRIVERADDF_LOCAL: i32 = 0i32;\npub const ACM_DRIVERADDF_NAME: i32 = 1i32;\npub const ACM_DRIVERADDF_NOTIFYHWND: i32 = 4i32;\npub const ACM_DRIVERADDF_TYPEMASK: i32 = 7i32;\npub const ACM_DRIVERENUMF_DISABLED: i32 = -2147483648i32;\npub const ACM_DRIVERENUMF_NOLOCAL: i32 = 1073741824i32;\npub const ACM_DRIVERPRIORITYF_ABLEMASK: i32 = 3i32;\npub const ACM_DRIVERPRIORITYF_BEGIN: i32 = 65536i32;\npub const ACM_DRIVERPRIORITYF_DEFERMASK: i32 = 196608i32;\npub const ACM_DRIVERPRIORITYF_DISABLE: i32 = 2i32;\npub const ACM_DRIVERPRIORITYF_ENABLE: i32 = 1i32;\npub const ACM_DRIVERPRIORITYF_END: i32 = 131072i32;\npub const ACM_FILTERDETAILSF_FILTER: i32 = 1i32;\npub const ACM_FILTERDETAILSF_INDEX: i32 = 0i32;\npub const ACM_FILTERDETAILSF_QUERYMASK: i32 = 15i32;\npub const ACM_FILTERENUMF_DWFILTERTAG: i32 = 65536i32;\npub const ACM_FILTERTAGDETAILSF_FILTERTAG: i32 = 1i32;\npub const ACM_FILTERTAGDETAILSF_INDEX: i32 = 0i32;\npub const ACM_FILTERTAGDETAILSF_LARGESTSIZE: i32 = 2i32;\npub const ACM_FILTERTAGDETAILSF_QUERYMASK: i32 = 15i32;\npub const ACM_FORMATDETAILSF_FORMAT: i32 = 1i32;\npub const ACM_FORMATDETAILSF_INDEX: i32 = 0i32;\npub const ACM_FORMATDETAILSF_QUERYMASK: i32 = 15i32;\npub const ACM_FORMATENUMF_CONVERT: i32 = 1048576i32;\npub const ACM_FORMATENUMF_HARDWARE: i32 = 4194304i32;\npub const ACM_FORMATENUMF_INPUT: i32 = 8388608i32;\npub const ACM_FORMATENUMF_NCHANNELS: i32 = 131072i32;\npub const ACM_FORMATENUMF_NSAMPLESPERSEC: i32 = 262144i32;\npub const ACM_FORMATENUMF_OUTPUT: i32 = 16777216i32;\npub const ACM_FORMATENUMF_SUGGEST: i32 = 2097152i32;\npub const ACM_FORMATENUMF_WBITSPERSAMPLE: i32 = 524288i32;\npub const ACM_FORMATENUMF_WFORMATTAG: i32 = 65536i32;\npub const ACM_FORMATSUGGESTF_NCHANNELS: i32 = 131072i32;\npub const ACM_FORMATSUGGESTF_NSAMPLESPERSEC: i32 = 262144i32;\npub const ACM_FORMATSUGGESTF_TYPEMASK: i32 = 16711680i32;\npub const ACM_FORMATSUGGESTF_WBITSPERSAMPLE: i32 = 524288i32;\npub const ACM_FORMATSUGGESTF_WFORMATTAG: i32 = 65536i32;\npub const ACM_FORMATTAGDETAILSF_FORMATTAG: i32 = 1i32;\npub const ACM_FORMATTAGDETAILSF_INDEX: i32 = 0i32;\npub const ACM_FORMATTAGDETAILSF_LARGESTSIZE: i32 = 2i32;\npub const ACM_FORMATTAGDETAILSF_QUERYMASK: i32 = 15i32;\npub const ACM_METRIC_COUNT_CODECS: u32 = 2u32;\npub const ACM_METRIC_COUNT_CONVERTERS: u32 = 3u32;\npub const ACM_METRIC_COUNT_DISABLED: u32 = 5u32;\npub const ACM_METRIC_COUNT_DRIVERS: u32 = 1u32;\npub const ACM_METRIC_COUNT_FILTERS: u32 = 4u32;\npub const ACM_METRIC_COUNT_HARDWARE: u32 = 6u32;\npub const ACM_METRIC_COUNT_LOCAL_CODECS: u32 = 21u32;\npub const ACM_METRIC_COUNT_LOCAL_CONVERTERS: u32 = 22u32;\npub const ACM_METRIC_COUNT_LOCAL_DISABLED: u32 = 24u32;\npub const ACM_METRIC_COUNT_LOCAL_DRIVERS: u32 = 20u32;\npub const ACM_METRIC_COUNT_LOCAL_FILTERS: u32 = 23u32;\npub const ACM_METRIC_DRIVER_PRIORITY: u32 = 101u32;\npub const ACM_METRIC_DRIVER_SUPPORT: u32 = 100u32;\npub const ACM_METRIC_HARDWARE_WAVE_INPUT: u32 = 30u32;\npub const ACM_METRIC_HARDWARE_WAVE_OUTPUT: u32 = 31u32;\npub const ACM_METRIC_MAX_SIZE_FILTER: u32 = 51u32;\npub const ACM_METRIC_MAX_SIZE_FORMAT: u32 = 50u32;\npub const ACM_STREAMCONVERTF_BLOCKALIGN: u32 = 4u32;\npub const ACM_STREAMCONVERTF_END: u32 = 32u32;\npub const ACM_STREAMCONVERTF_START: u32 = 16u32;\npub const ACM_STREAMOPENF_ASYNC: u32 = 2u32;\npub const ACM_STREAMOPENF_NONREALTIME: u32 = 4u32;\npub const ACM_STREAMOPENF_QUERY: u32 = 1u32;\npub const ACM_STREAMSIZEF_DESTINATION: i32 = 1i32;\npub const ACM_STREAMSIZEF_QUERYMASK: i32 = 15i32;\npub const ACM_STREAMSIZEF_SOURCE: i32 = 0i32;\npub type AMBISONICS_CHANNEL_ORDERING = i32;\npub const AMBISONICS_CHANNEL_ORDERING_ACN: AMBISONICS_CHANNEL_ORDERING = 0i32;\npub type AMBISONICS_NORMALIZATION = i32;\npub const AMBISONICS_NORMALIZATION_N3D: AMBISONICS_NORMALIZATION = 1i32;\npub const AMBISONICS_NORMALIZATION_SN3D: AMBISONICS_NORMALIZATION = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AMBISONICS_PARAMS {\n    pub u32Size: u32,\n    pub u32Version: u32,\n    pub u32Type: AMBISONICS_TYPE,\n    pub u32ChannelOrdering: AMBISONICS_CHANNEL_ORDERING,\n    pub u32Normalization: AMBISONICS_NORMALIZATION,\n    pub u32Order: u32,\n    pub u32NumChannels: u32,\n    pub pu32ChannelMap: *mut u32,\n}\nimpl Default for AMBISONICS_PARAMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const AMBISONICS_PARAM_VERSION_1: u32 = 1u32;\npub type AMBISONICS_TYPE = i32;\npub const AMBISONICS_TYPE_FULL3D: AMBISONICS_TYPE = 0i32;\npub const AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY: _AUDCLNT_BUFFERFLAGS = 1i32;\npub const AUDCLNT_BUFFERFLAGS_SILENT: _AUDCLNT_BUFFERFLAGS = 2i32;\npub const AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR: _AUDCLNT_BUFFERFLAGS = 4i32;\npub const AUDCLNT_E_ALREADY_INITIALIZED: windows_sys::core::HRESULT = 0x88890002_u32 as _;\npub const AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL: windows_sys::core::HRESULT = 0x88890013_u32 as _;\npub const AUDCLNT_E_BUFFER_ERROR: windows_sys::core::HRESULT = 0x88890018_u32 as _;\npub const AUDCLNT_E_BUFFER_OPERATION_PENDING: windows_sys::core::HRESULT = 0x8889000B_u32 as _;\npub const AUDCLNT_E_BUFFER_SIZE_ERROR: windows_sys::core::HRESULT = 0x88890016_u32 as _;\npub const AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED: windows_sys::core::HRESULT = 0x88890019_u32 as _;\npub const AUDCLNT_E_BUFFER_TOO_LARGE: windows_sys::core::HRESULT = 0x88890006_u32 as _;\npub const AUDCLNT_E_CPUUSAGE_EXCEEDED: windows_sys::core::HRESULT = 0x88890017_u32 as _;\npub const AUDCLNT_E_DEVICE_INVALIDATED: windows_sys::core::HRESULT = 0x88890004_u32 as _;\npub const AUDCLNT_E_DEVICE_IN_USE: windows_sys::core::HRESULT = 0x8889000A_u32 as _;\npub const AUDCLNT_E_EFFECT_NOT_AVAILABLE: windows_sys::core::HRESULT = 0x88890041_u32 as _;\npub const AUDCLNT_E_EFFECT_STATE_READ_ONLY: windows_sys::core::HRESULT = 0x88890042_u32 as _;\npub const AUDCLNT_E_ENDPOINT_CREATE_FAILED: windows_sys::core::HRESULT = 0x8889000F_u32 as _;\npub const AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE: windows_sys::core::HRESULT = 0x88890022_u32 as _;\npub const AUDCLNT_E_ENGINE_FORMAT_LOCKED: windows_sys::core::HRESULT = 0x88890029_u32 as _;\npub const AUDCLNT_E_ENGINE_PERIODICITY_LOCKED: windows_sys::core::HRESULT = 0x88890028_u32 as _;\npub const AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED: windows_sys::core::HRESULT = 0x88890011_u32 as _;\npub const AUDCLNT_E_EVENTHANDLE_NOT_SET: windows_sys::core::HRESULT = 0x88890014_u32 as _;\npub const AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED: windows_sys::core::HRESULT = 0x8889000E_u32 as _;\npub const AUDCLNT_E_EXCLUSIVE_MODE_ONLY: windows_sys::core::HRESULT = 0x88890012_u32 as _;\npub const AUDCLNT_E_HEADTRACKING_ENABLED: windows_sys::core::HRESULT = 0x88890030_u32 as _;\npub const AUDCLNT_E_HEADTRACKING_UNSUPPORTED: windows_sys::core::HRESULT = 0x88890040_u32 as _;\npub const AUDCLNT_E_INCORRECT_BUFFER_SIZE: windows_sys::core::HRESULT = 0x88890015_u32 as _;\npub const AUDCLNT_E_INVALID_DEVICE_PERIOD: windows_sys::core::HRESULT = 0x88890020_u32 as _;\npub const AUDCLNT_E_INVALID_SIZE: windows_sys::core::HRESULT = 0x88890009_u32 as _;\npub const AUDCLNT_E_INVALID_STREAM_FLAG: windows_sys::core::HRESULT = 0x88890021_u32 as _;\npub const AUDCLNT_E_NONOFFLOAD_MODE_ONLY: windows_sys::core::HRESULT = 0x88890025_u32 as _;\npub const AUDCLNT_E_NOT_INITIALIZED: windows_sys::core::HRESULT = 0x88890001_u32 as _;\npub const AUDCLNT_E_NOT_STOPPED: windows_sys::core::HRESULT = 0x88890005_u32 as _;\npub const AUDCLNT_E_OFFLOAD_MODE_ONLY: windows_sys::core::HRESULT = 0x88890024_u32 as _;\npub const AUDCLNT_E_OUT_OF_OFFLOAD_RESOURCES: windows_sys::core::HRESULT = 0x88890023_u32 as _;\npub const AUDCLNT_E_OUT_OF_ORDER: windows_sys::core::HRESULT = 0x88890007_u32 as _;\npub const AUDCLNT_E_RAW_MODE_UNSUPPORTED: windows_sys::core::HRESULT = 0x88890027_u32 as _;\npub const AUDCLNT_E_RESOURCES_INVALIDATED: windows_sys::core::HRESULT = 0x88890026_u32 as _;\npub const AUDCLNT_E_SERVICE_NOT_RUNNING: windows_sys::core::HRESULT = 0x88890010_u32 as _;\npub const AUDCLNT_E_THREAD_NOT_REGISTERED: windows_sys::core::HRESULT = 0x8889000C_u32 as _;\npub const AUDCLNT_E_UNSUPPORTED_FORMAT: windows_sys::core::HRESULT = 0x88890008_u32 as _;\npub const AUDCLNT_E_WRONG_ENDPOINT_TYPE: windows_sys::core::HRESULT = 0x88890003_u32 as _;\npub const AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE: u32 = 536870912u32;\npub const AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED: u32 = 1073741824u32;\npub const AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED: u32 = 268435456u32;\npub type AUDCLNT_SHAREMODE = i32;\npub const AUDCLNT_SHAREMODE_EXCLUSIVE: AUDCLNT_SHAREMODE = 1i32;\npub const AUDCLNT_SHAREMODE_SHARED: AUDCLNT_SHAREMODE = 0i32;\npub const AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM: u32 = 2147483648u32;\npub const AUDCLNT_STREAMFLAGS_CROSSPROCESS: u32 = 65536u32;\npub const AUDCLNT_STREAMFLAGS_EVENTCALLBACK: u32 = 262144u32;\npub const AUDCLNT_STREAMFLAGS_LOOPBACK: u32 = 131072u32;\npub const AUDCLNT_STREAMFLAGS_NOPERSIST: u32 = 524288u32;\npub const AUDCLNT_STREAMFLAGS_RATEADJUST: u32 = 1048576u32;\npub const AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY: u32 = 134217728u32;\npub type AUDCLNT_STREAMOPTIONS = i32;\npub const AUDCLNT_STREAMOPTIONS_AMBISONICS: AUDCLNT_STREAMOPTIONS = 4i32;\npub const AUDCLNT_STREAMOPTIONS_MATCH_FORMAT: AUDCLNT_STREAMOPTIONS = 2i32;\npub const AUDCLNT_STREAMOPTIONS_NONE: AUDCLNT_STREAMOPTIONS = 0i32;\npub const AUDCLNT_STREAMOPTIONS_RAW: AUDCLNT_STREAMOPTIONS = 1i32;\npub const AUDCLNT_S_BUFFER_EMPTY: windows_sys::core::HRESULT = 0x8890001_u32 as _;\npub const AUDCLNT_S_POSITION_STALLED: windows_sys::core::HRESULT = 0x8890003_u32 as _;\npub const AUDCLNT_S_THREAD_ALREADY_REGISTERED: windows_sys::core::HRESULT = 0x8890002_u32 as _;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AUDIOCLIENT_ACTIVATION_PARAMS {\n    pub ActivationType: AUDIOCLIENT_ACTIVATION_TYPE,\n    pub Anonymous: AUDIOCLIENT_ACTIVATION_PARAMS_0,\n}\nimpl Default for AUDIOCLIENT_ACTIVATION_PARAMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union AUDIOCLIENT_ACTIVATION_PARAMS_0 {\n    pub ProcessLoopbackParams: AUDIOCLIENT_PROCESS_LOOPBACK_PARAMS,\n}\nimpl Default for AUDIOCLIENT_ACTIVATION_PARAMS_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type AUDIOCLIENT_ACTIVATION_TYPE = i32;\npub const AUDIOCLIENT_ACTIVATION_TYPE_DEFAULT: AUDIOCLIENT_ACTIVATION_TYPE = 0i32;\npub const AUDIOCLIENT_ACTIVATION_TYPE_PROCESS_LOOPBACK: AUDIOCLIENT_ACTIVATION_TYPE = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct AUDIOCLIENT_PROCESS_LOOPBACK_PARAMS {\n    pub TargetProcessId: u32,\n    pub ProcessLoopbackMode: PROCESS_LOOPBACK_MODE,\n}\npub const AUDIOCLOCK_CHARACTERISTIC_FIXED_FREQ: u32 = 1u32;\npub type AUDIO_DUCKING_OPTIONS = i32;\npub const AUDIO_DUCKING_OPTIONS_DEFAULT: AUDIO_DUCKING_OPTIONS = 0i32;\npub const AUDIO_DUCKING_OPTIONS_DO_NOT_DUCK_OTHER_STREAMS: AUDIO_DUCKING_OPTIONS = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct AUDIO_EFFECT {\n    pub id: windows_sys::core::GUID,\n    pub canSetState: windows_sys::core::BOOL,\n    pub state: AUDIO_EFFECT_STATE,\n}\npub type AUDIO_EFFECT_STATE = i32;\npub const AUDIO_EFFECT_STATE_OFF: AUDIO_EFFECT_STATE = 0i32;\npub const AUDIO_EFFECT_STATE_ON: AUDIO_EFFECT_STATE = 1i32;\npub type AUDIO_STREAM_CATEGORY = i32;\npub type AUDIO_SYSTEMEFFECTS_PROPERTYSTORE_TYPE = i32;\npub const AUDIO_SYSTEMEFFECTS_PROPERTYSTORE_TYPE_DEFAULT: AUDIO_SYSTEMEFFECTS_PROPERTYSTORE_TYPE = 0i32;\npub const AUDIO_SYSTEMEFFECTS_PROPERTYSTORE_TYPE_ENUM_COUNT: AUDIO_SYSTEMEFFECTS_PROPERTYSTORE_TYPE = 3i32;\npub const AUDIO_SYSTEMEFFECTS_PROPERTYSTORE_TYPE_USER: AUDIO_SYSTEMEFFECTS_PROPERTYSTORE_TYPE = 1i32;\npub const AUDIO_SYSTEMEFFECTS_PROPERTYSTORE_TYPE_VOLATILE: AUDIO_SYSTEMEFFECTS_PROPERTYSTORE_TYPE = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AUDIO_VOLUME_NOTIFICATION_DATA {\n    pub guidEventContext: windows_sys::core::GUID,\n    pub bMuted: windows_sys::core::BOOL,\n    pub fMasterVolume: f32,\n    pub nChannels: u32,\n    pub afChannelVolumes: [f32; 1],\n}\nimpl Default for AUDIO_VOLUME_NOTIFICATION_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct AUXCAPS2A {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub wTechnology: u16,\n    pub wReserved1: u16,\n    pub dwSupport: u32,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for AUXCAPS2A {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct AUXCAPS2W {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub wTechnology: u16,\n    pub wReserved1: u16,\n    pub dwSupport: u32,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for AUXCAPS2W {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct AUXCAPSA {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub wTechnology: u16,\n    pub wReserved1: u16,\n    pub dwSupport: u32,\n}\nimpl Default for AUXCAPSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct AUXCAPSW {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub wTechnology: u16,\n    pub wReserved1: u16,\n    pub dwSupport: u32,\n}\nimpl Default for AUXCAPSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const AUXCAPS_AUXIN: u32 = 2u32;\npub const AUXCAPS_CDAUDIO: u32 = 1u32;\npub const AUXCAPS_LRVOLUME: u32 = 2u32;\npub const AUXCAPS_VOLUME: u32 = 1u32;\npub const AudioCategory_Alerts: AUDIO_STREAM_CATEGORY = 4i32;\npub const AudioCategory_Communications: AUDIO_STREAM_CATEGORY = 3i32;\npub const AudioCategory_FarFieldSpeech: AUDIO_STREAM_CATEGORY = 12i32;\npub const AudioCategory_ForegroundOnlyMedia: AUDIO_STREAM_CATEGORY = 1i32;\npub const AudioCategory_GameChat: AUDIO_STREAM_CATEGORY = 8i32;\npub const AudioCategory_GameEffects: AUDIO_STREAM_CATEGORY = 6i32;\npub const AudioCategory_GameMedia: AUDIO_STREAM_CATEGORY = 7i32;\npub const AudioCategory_Media: AUDIO_STREAM_CATEGORY = 11i32;\npub const AudioCategory_Movie: AUDIO_STREAM_CATEGORY = 10i32;\npub const AudioCategory_Other: AUDIO_STREAM_CATEGORY = 0i32;\npub const AudioCategory_SoundEffects: AUDIO_STREAM_CATEGORY = 5i32;\npub const AudioCategory_Speech: AUDIO_STREAM_CATEGORY = 9i32;\npub const AudioCategory_UniformSpeech: AUDIO_STREAM_CATEGORY = 13i32;\npub const AudioCategory_VoiceTyping: AUDIO_STREAM_CATEGORY = 14i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct AudioClient3ActivationParams {\n    pub tracingContextId: windows_sys::core::GUID,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct AudioClientProperties {\n    pub cbSize: u32,\n    pub bIsOffload: windows_sys::core::BOOL,\n    pub eCategory: AUDIO_STREAM_CATEGORY,\n    pub Options: AUDCLNT_STREAMOPTIONS,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AudioExtensionParams {\n    pub AddPageParam: super::super::Foundation::LPARAM,\n    pub pEndpoint: *mut core::ffi::c_void,\n    pub pPnpInterface: *mut core::ffi::c_void,\n    pub pPnpDevnode: *mut core::ffi::c_void,\n}\nimpl Default for AudioExtensionParams {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type AudioObjectType = i32;\npub const AudioObjectType_BackCenter: AudioObjectType = 131072i32;\npub const AudioObjectType_BackLeft: AudioObjectType = 128i32;\npub const AudioObjectType_BackRight: AudioObjectType = 256i32;\npub const AudioObjectType_BottomBackLeft: AudioObjectType = 32768i32;\npub const AudioObjectType_BottomBackRight: AudioObjectType = 65536i32;\npub const AudioObjectType_BottomFrontLeft: AudioObjectType = 8192i32;\npub const AudioObjectType_BottomFrontRight: AudioObjectType = 16384i32;\npub const AudioObjectType_Dynamic: AudioObjectType = 1i32;\npub const AudioObjectType_FrontCenter: AudioObjectType = 8i32;\npub const AudioObjectType_FrontLeft: AudioObjectType = 2i32;\npub const AudioObjectType_FrontRight: AudioObjectType = 4i32;\npub const AudioObjectType_LowFrequency: AudioObjectType = 16i32;\npub const AudioObjectType_None: AudioObjectType = 0i32;\npub const AudioObjectType_SideLeft: AudioObjectType = 32i32;\npub const AudioObjectType_SideRight: AudioObjectType = 64i32;\npub const AudioObjectType_TopBackLeft: AudioObjectType = 2048i32;\npub const AudioObjectType_TopBackRight: AudioObjectType = 4096i32;\npub const AudioObjectType_TopFrontLeft: AudioObjectType = 512i32;\npub const AudioObjectType_TopFrontRight: AudioObjectType = 1024i32;\npub type AudioSessionDisconnectReason = i32;\npub type AudioSessionState = i32;\npub const AudioSessionStateActive: AudioSessionState = 1i32;\npub const AudioSessionStateExpired: AudioSessionState = 2i32;\npub const AudioSessionStateInactive: AudioSessionState = 0i32;\npub type AudioStateMonitorSoundLevel = i32;\npub const CALLBACK_EVENT: MIDI_WAVE_OPEN_TYPE = 327680u32;\npub const CALLBACK_FUNCTION: MIDI_WAVE_OPEN_TYPE = 196608u32;\npub const CALLBACK_NULL: MIDI_WAVE_OPEN_TYPE = 0u32;\npub const CALLBACK_TASK: MIDI_WAVE_OPEN_TYPE = 131072u32;\npub const CALLBACK_THREAD: MIDI_WAVE_OPEN_TYPE = 131072u32;\npub const CALLBACK_TYPEMASK: MIDI_WAVE_OPEN_TYPE = 458752u32;\npub const CALLBACK_WINDOW: MIDI_WAVE_OPEN_TYPE = 65536u32;\npub const Connector: PartType = 0i32;\n#[repr(transparent)]\n#[derive(Clone, Copy)]\npub struct ConnectorType(pub i32);\nimpl ConnectorType {\n    pub const Unknown_Connector: Self = Self(0i32);\n    pub const Physical_Internal: Self = Self(1i32);\n    pub const Physical_External: Self = Self(2i32);\n    pub const Software_IO: Self = Self(3i32);\n    pub const Software_Fixed: Self = Self(4i32);\n    pub const Network: Self = Self(5i32);\n}\npub type DEVICE_STATE = u32;\npub const DEVICE_STATEMASK_ALL: u32 = 15u32;\npub const DEVICE_STATE_ACTIVE: DEVICE_STATE = 1u32;\npub const DEVICE_STATE_DISABLED: DEVICE_STATE = 2u32;\npub const DEVICE_STATE_NOTPRESENT: DEVICE_STATE = 4u32;\npub const DEVICE_STATE_UNPLUGGED: DEVICE_STATE = 8u32;\npub const DEVINTERFACE_AUDIO_CAPTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2eef81be_33fa_4800_9670_1cd474972c3f);\npub const DEVINTERFACE_AUDIO_RENDER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe6327cad_dcec_4949_ae8a_991e976a79d2);\npub const DEVINTERFACE_MIDI_INPUT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x504be32c_ccf6_4d2c_b73f_6f8b3747e22b);\npub const DEVINTERFACE_MIDI_OUTPUT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6dc23320_ab33_4ce4_80d4_bbb3ebbf2814);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DIRECTX_AUDIO_ACTIVATION_PARAMS {\n    pub cbDirectXAudioActivationParams: u32,\n    pub guidAudioSession: windows_sys::core::GUID,\n    pub dwAudioStreamFlags: u32,\n}\npub const DRVM_MAPPER: u32 = 8192u32;\npub const DRVM_MAPPER_STATUS: u32 = 8192u32;\npub const DRV_MAPPER_PREFERRED_INPUT_GET: u32 = 16384u32;\npub const DRV_MAPPER_PREFERRED_OUTPUT_GET: u32 = 16386u32;\npub type DataFlow = i32;\npub const DeviceTopology: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1df639d0_5ec1_47aa_9379_828dc1aa8c59);\npub const DigitalAudioDisplayDevice: EndpointFormFactor = 9i32;\npub const DisconnectReasonDeviceRemoval: AudioSessionDisconnectReason = 0i32;\npub const DisconnectReasonExclusiveModeOverride: AudioSessionDisconnectReason = 5i32;\npub const DisconnectReasonFormatChanged: AudioSessionDisconnectReason = 2i32;\npub const DisconnectReasonServerShutdown: AudioSessionDisconnectReason = 1i32;\npub const DisconnectReasonSessionDisconnected: AudioSessionDisconnectReason = 4i32;\npub const DisconnectReasonSessionLogoff: AudioSessionDisconnectReason = 3i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct ECHOWAVEFILTER {\n    pub wfltr: WAVEFILTER,\n    pub dwVolume: u32,\n    pub dwDelay: u32,\n}\npub type EDataFlow = i32;\npub const EDataFlow_enum_count: EDataFlow = 3i32;\npub const ENDPOINT_FORMAT_RESET_MIX_ONLY: u32 = 1u32;\npub const ENDPOINT_HARDWARE_SUPPORT_METER: u32 = 4u32;\npub const ENDPOINT_HARDWARE_SUPPORT_MUTE: u32 = 2u32;\npub const ENDPOINT_HARDWARE_SUPPORT_VOLUME: u32 = 1u32;\npub const ENDPOINT_SYSFX_DISABLED: u32 = 1u32;\npub const ENDPOINT_SYSFX_ENABLED: u32 = 0u32;\npub type ERole = i32;\npub const ERole_enum_count: ERole = 3i32;\npub const EVENTCONTEXT_VOLUMESLIDER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe2c2e9de_09b1_4b04_84e5_07931225ee04);\npub type EndpointFormFactor = i32;\npub const EndpointFormFactor_enum_count: EndpointFormFactor = 11i32;\npub const FILTERCHOOSE_CUSTOM_VERIFY: u32 = 2u32;\npub const FILTERCHOOSE_FILTERTAG_VERIFY: u32 = 0u32;\npub const FILTERCHOOSE_FILTER_VERIFY: u32 = 1u32;\npub const FILTERCHOOSE_MESSAGE: u32 = 0u32;\npub const FORMATCHOOSE_CUSTOM_VERIFY: u32 = 2u32;\npub const FORMATCHOOSE_FORMATTAG_VERIFY: u32 = 0u32;\npub const FORMATCHOOSE_FORMAT_VERIFY: u32 = 1u32;\npub const FORMATCHOOSE_MESSAGE: u32 = 0u32;\npub const Full: AudioStateMonitorSoundLevel = 2i32;\npub type HACMDRIVER = *mut core::ffi::c_void;\npub type HACMDRIVERID = *mut core::ffi::c_void;\npub type HACMOBJ = *mut core::ffi::c_void;\npub type HACMSTREAM = *mut core::ffi::c_void;\npub type HMIDI = *mut core::ffi::c_void;\npub type HMIDIIN = *mut core::ffi::c_void;\npub type HMIDIOUT = *mut core::ffi::c_void;\npub type HMIDISTRM = *mut core::ffi::c_void;\npub type HMIXER = *mut core::ffi::c_void;\npub type HMIXEROBJ = *mut core::ffi::c_void;\npub type HWAVE = *mut core::ffi::c_void;\npub type HWAVEIN = *mut core::ffi::c_void;\npub type HWAVEOUT = *mut core::ffi::c_void;\npub const Handset: EndpointFormFactor = 6i32;\npub const Headphones: EndpointFormFactor = 3i32;\npub const Headset: EndpointFormFactor = 5i32;\npub const In: DataFlow = 0i32;\npub type LPACMDRIVERPROC = Option<unsafe extern \"system\" fn(param0: usize, param1: HACMDRIVERID, param2: u32, param3: super::super::Foundation::LPARAM, param4: super::super::Foundation::LPARAM) -> super::super::Foundation::LRESULT>;\n#[cfg(feature = \"Win32_Media_Multimedia\")]\npub type LPMIDICALLBACK = Option<unsafe extern \"system\" fn(hdrvr: super::Multimedia::HDRVR, umsg: u32, dwuser: usize, dw1: usize, dw2: usize)>;\n#[cfg(feature = \"Win32_Media_Multimedia\")]\npub type LPWAVECALLBACK = Option<unsafe extern \"system\" fn(hdrvr: super::Multimedia::HDRVR, umsg: u32, dwuser: usize, dw1: usize, dw2: usize)>;\npub const LineLevel: EndpointFormFactor = 2i32;\npub const Low: AudioStateMonitorSoundLevel = 1i32;\npub const MEVT_COMMENT: u8 = 130u8;\npub const MEVT_F_CALLBACK: i32 = 1073741824i32;\npub const MEVT_F_LONG: i32 = -2147483648i32;\npub const MEVT_F_SHORT: i32 = 0i32;\npub const MEVT_LONGMSG: u8 = 128u8;\npub const MEVT_NOP: u8 = 2u8;\npub const MEVT_SHORTMSG: u8 = 0u8;\npub const MEVT_TEMPO: u8 = 1u8;\npub const MEVT_VERSION: u8 = 132u8;\npub const MHDR_DONE: u32 = 1u32;\npub const MHDR_INQUEUE: u32 = 4u32;\npub const MHDR_ISSTRM: u32 = 8u32;\npub const MHDR_PREPARED: u32 = 2u32;\npub const MIDICAPS_CACHE: u32 = 4u32;\npub const MIDICAPS_LRVOLUME: u32 = 2u32;\npub const MIDICAPS_STREAM: u32 = 8u32;\npub const MIDICAPS_VOLUME: u32 = 1u32;\npub const MIDIERR_BADOPENMODE: u32 = 70u32;\npub const MIDIERR_DONT_CONTINUE: u32 = 71u32;\npub const MIDIERR_INVALIDSETUP: u32 = 69u32;\npub const MIDIERR_LASTERROR: u32 = 71u32;\npub const MIDIERR_NODEVICE: u32 = 68u32;\npub const MIDIERR_NOMAP: u32 = 66u32;\npub const MIDIERR_NOTREADY: u32 = 67u32;\npub const MIDIERR_STILLPLAYING: u32 = 65u32;\npub const MIDIERR_UNPREPARED: u32 = 64u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIDIEVENT {\n    pub dwDeltaTime: u32,\n    pub dwStreamID: u32,\n    pub dwEvent: u32,\n    pub dwParms: [u32; 1],\n}\nimpl Default for MIDIEVENT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIDIHDR {\n    pub lpData: windows_sys::core::PSTR,\n    pub dwBufferLength: u32,\n    pub dwBytesRecorded: u32,\n    pub dwUser: usize,\n    pub dwFlags: u32,\n    pub lpNext: *mut MIDIHDR,\n    pub reserved: usize,\n    pub dwOffset: u32,\n    pub dwReserved: [usize; 8],\n}\nimpl Default for MIDIHDR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIDIINCAPS2A {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub dwSupport: u32,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for MIDIINCAPS2A {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIDIINCAPS2W {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub dwSupport: u32,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for MIDIINCAPS2W {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIDIINCAPSA {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub dwSupport: u32,\n}\nimpl Default for MIDIINCAPSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIDIINCAPSW {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub dwSupport: u32,\n}\nimpl Default for MIDIINCAPSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIDIOUTCAPS2A {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub wTechnology: u16,\n    pub wVoices: u16,\n    pub wNotes: u16,\n    pub wChannelMask: u16,\n    pub dwSupport: u32,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for MIDIOUTCAPS2A {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIDIOUTCAPS2W {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub wTechnology: u16,\n    pub wVoices: u16,\n    pub wNotes: u16,\n    pub wChannelMask: u16,\n    pub dwSupport: u32,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for MIDIOUTCAPS2W {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIDIOUTCAPSA {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub wTechnology: u16,\n    pub wVoices: u16,\n    pub wNotes: u16,\n    pub wChannelMask: u16,\n    pub dwSupport: u32,\n}\nimpl Default for MIDIOUTCAPSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIDIOUTCAPSW {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub wTechnology: u16,\n    pub wVoices: u16,\n    pub wNotes: u16,\n    pub wChannelMask: u16,\n    pub dwSupport: u32,\n}\nimpl Default for MIDIOUTCAPSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MIDIPATCHSIZE: u32 = 128u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIDIPROPTEMPO {\n    pub cbStruct: u32,\n    pub dwTempo: u32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIDIPROPTIMEDIV {\n    pub cbStruct: u32,\n    pub dwTimeDiv: u32,\n}\npub const MIDIPROP_GET: i32 = 1073741824i32;\npub const MIDIPROP_SET: i32 = -2147483648i32;\npub const MIDIPROP_TEMPO: i32 = 2i32;\npub const MIDIPROP_TIMEDIV: i32 = 1i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIDISTRMBUFFVER {\n    pub dwVersion: u32,\n    pub dwMid: u32,\n    pub dwOEMVersion: u32,\n}\npub const MIDISTRM_ERROR: i32 = -2i32;\npub const MIDI_CACHE_ALL: u32 = 1u32;\npub const MIDI_CACHE_BESTFIT: u32 = 2u32;\npub const MIDI_CACHE_QUERY: u32 = 3u32;\npub const MIDI_IO_STATUS: MIDI_WAVE_OPEN_TYPE = 32u32;\npub const MIDI_UNCACHE: u32 = 4u32;\npub type MIDI_WAVE_OPEN_TYPE = u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERCAPS2A {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub fdwSupport: u32,\n    pub cDestinations: u32,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for MIXERCAPS2A {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERCAPS2W {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub fdwSupport: u32,\n    pub cDestinations: u32,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for MIXERCAPS2W {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERCAPSA {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub fdwSupport: u32,\n    pub cDestinations: u32,\n}\nimpl Default for MIXERCAPSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERCAPSW {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub fdwSupport: u32,\n    pub cDestinations: u32,\n}\nimpl Default for MIXERCAPSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERCONTROLA {\n    pub cbStruct: u32,\n    pub dwControlID: u32,\n    pub dwControlType: u32,\n    pub fdwControl: u32,\n    pub cMultipleItems: u32,\n    pub szShortName: [i8; 16],\n    pub szName: [i8; 64],\n    pub Bounds: MIXERCONTROLA_0,\n    pub Metrics: MIXERCONTROLA_1,\n}\nimpl Default for MIXERCONTROLA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union MIXERCONTROLA_0 {\n    pub Anonymous1: MIXERCONTROLA_0_0,\n    pub Anonymous2: MIXERCONTROLA_0_1,\n    pub dwReserved: [u32; 6],\n}\nimpl Default for MIXERCONTROLA_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIXERCONTROLA_0_0 {\n    pub lMinimum: i32,\n    pub lMaximum: i32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIXERCONTROLA_0_1 {\n    pub dwMinimum: u32,\n    pub dwMaximum: u32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union MIXERCONTROLA_1 {\n    pub cSteps: u32,\n    pub cbCustomData: u32,\n    pub dwReserved: [u32; 6],\n}\nimpl Default for MIXERCONTROLA_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERCONTROLDETAILS {\n    pub cbStruct: u32,\n    pub dwControlID: u32,\n    pub cChannels: u32,\n    pub Anonymous: MIXERCONTROLDETAILS_0,\n    pub cbDetails: u32,\n    pub paDetails: *mut core::ffi::c_void,\n}\nimpl Default for MIXERCONTROLDETAILS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union MIXERCONTROLDETAILS_0 {\n    pub hwndOwner: super::super::Foundation::HWND,\n    pub cMultipleItems: u32,\n}\nimpl Default for MIXERCONTROLDETAILS_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIXERCONTROLDETAILS_BOOLEAN {\n    pub fValue: i32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERCONTROLDETAILS_LISTTEXTA {\n    pub dwParam1: u32,\n    pub dwParam2: u32,\n    pub szName: [i8; 64],\n}\nimpl Default for MIXERCONTROLDETAILS_LISTTEXTA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERCONTROLDETAILS_LISTTEXTW {\n    pub dwParam1: u32,\n    pub dwParam2: u32,\n    pub szName: [u16; 64],\n}\nimpl Default for MIXERCONTROLDETAILS_LISTTEXTW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIXERCONTROLDETAILS_SIGNED {\n    pub lValue: i32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIXERCONTROLDETAILS_UNSIGNED {\n    pub dwValue: u32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERCONTROLW {\n    pub cbStruct: u32,\n    pub dwControlID: u32,\n    pub dwControlType: u32,\n    pub fdwControl: u32,\n    pub cMultipleItems: u32,\n    pub szShortName: [u16; 16],\n    pub szName: [u16; 64],\n    pub Bounds: MIXERCONTROLW_0,\n    pub Metrics: MIXERCONTROLW_1,\n}\nimpl Default for MIXERCONTROLW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union MIXERCONTROLW_0 {\n    pub Anonymous1: MIXERCONTROLW_0_0,\n    pub Anonymous2: MIXERCONTROLW_0_1,\n    pub dwReserved: [u32; 6],\n}\nimpl Default for MIXERCONTROLW_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIXERCONTROLW_0_0 {\n    pub lMinimum: i32,\n    pub lMaximum: i32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIXERCONTROLW_0_1 {\n    pub dwMinimum: u32,\n    pub dwMaximum: u32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union MIXERCONTROLW_1 {\n    pub cSteps: u32,\n    pub cbCustomData: u32,\n    pub dwReserved: [u32; 6],\n}\nimpl Default for MIXERCONTROLW_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MIXERCONTROL_CONTROLF_DISABLED: i32 = -2147483648i32;\npub const MIXERCONTROL_CONTROLF_MULTIPLE: i32 = 2i32;\npub const MIXERCONTROL_CONTROLF_UNIFORM: i32 = 1i32;\npub const MIXERCONTROL_CONTROLTYPE_BASS: u32 = 1342373890u32;\npub const MIXERCONTROL_CONTROLTYPE_BASS_BOOST: u32 = 536945271u32;\npub const MIXERCONTROL_CONTROLTYPE_BOOLEAN: u32 = 536936448u32;\npub const MIXERCONTROL_CONTROLTYPE_BOOLEANMETER: u32 = 268500992u32;\npub const MIXERCONTROL_CONTROLTYPE_BUTTON: u32 = 553713664u32;\npub const MIXERCONTROL_CONTROLTYPE_CUSTOM: u32 = 0u32;\npub const MIXERCONTROL_CONTROLTYPE_DECIBELS: u32 = 805568512u32;\npub const MIXERCONTROL_CONTROLTYPE_EQUALIZER: u32 = 1342373892u32;\npub const MIXERCONTROL_CONTROLTYPE_FADER: u32 = 1342373888u32;\npub const MIXERCONTROL_CONTROLTYPE_LOUDNESS: u32 = 536936452u32;\npub const MIXERCONTROL_CONTROLTYPE_MICROTIME: u32 = 1610809344u32;\npub const MIXERCONTROL_CONTROLTYPE_MILLITIME: u32 = 1627586560u32;\npub const MIXERCONTROL_CONTROLTYPE_MIXER: u32 = 1895890945u32;\npub const MIXERCONTROL_CONTROLTYPE_MONO: u32 = 536936451u32;\npub const MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT: u32 = 1895890944u32;\npub const MIXERCONTROL_CONTROLTYPE_MUTE: u32 = 536936450u32;\npub const MIXERCONTROL_CONTROLTYPE_MUX: u32 = 1879113729u32;\npub const MIXERCONTROL_CONTROLTYPE_ONOFF: u32 = 536936449u32;\npub const MIXERCONTROL_CONTROLTYPE_PAN: u32 = 1073872897u32;\npub const MIXERCONTROL_CONTROLTYPE_PEAKMETER: u32 = 268566529u32;\npub const MIXERCONTROL_CONTROLTYPE_PERCENT: u32 = 805634048u32;\npub const MIXERCONTROL_CONTROLTYPE_QSOUNDPAN: u32 = 1073872898u32;\npub const MIXERCONTROL_CONTROLTYPE_SIGNED: u32 = 805437440u32;\npub const MIXERCONTROL_CONTROLTYPE_SIGNEDMETER: u32 = 268566528u32;\npub const MIXERCONTROL_CONTROLTYPE_SINGLESELECT: u32 = 1879113728u32;\npub const MIXERCONTROL_CONTROLTYPE_SLIDER: u32 = 1073872896u32;\npub const MIXERCONTROL_CONTROLTYPE_STEREOENH: u32 = 536936453u32;\npub const MIXERCONTROL_CONTROLTYPE_TREBLE: u32 = 1342373891u32;\npub const MIXERCONTROL_CONTROLTYPE_UNSIGNED: u32 = 805502976u32;\npub const MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER: u32 = 268632064u32;\npub const MIXERCONTROL_CONTROLTYPE_VOLUME: u32 = 1342373889u32;\npub const MIXERCONTROL_CT_CLASS_CUSTOM: i32 = 0i32;\npub const MIXERCONTROL_CT_CLASS_FADER: i32 = 1342177280i32;\npub const MIXERCONTROL_CT_CLASS_LIST: i32 = 1879048192i32;\npub const MIXERCONTROL_CT_CLASS_MASK: i32 = -268435456i32;\npub const MIXERCONTROL_CT_CLASS_METER: i32 = 268435456i32;\npub const MIXERCONTROL_CT_CLASS_NUMBER: i32 = 805306368i32;\npub const MIXERCONTROL_CT_CLASS_SLIDER: i32 = 1073741824i32;\npub const MIXERCONTROL_CT_CLASS_SWITCH: i32 = 536870912i32;\npub const MIXERCONTROL_CT_CLASS_TIME: i32 = 1610612736i32;\npub const MIXERCONTROL_CT_SC_LIST_MULTIPLE: i32 = 16777216i32;\npub const MIXERCONTROL_CT_SC_LIST_SINGLE: i32 = 0i32;\npub const MIXERCONTROL_CT_SC_METER_POLLED: i32 = 0i32;\npub const MIXERCONTROL_CT_SC_SWITCH_BOOLEAN: i32 = 0i32;\npub const MIXERCONTROL_CT_SC_SWITCH_BUTTON: i32 = 16777216i32;\npub const MIXERCONTROL_CT_SC_TIME_MICROSECS: i32 = 0i32;\npub const MIXERCONTROL_CT_SC_TIME_MILLISECS: i32 = 16777216i32;\npub const MIXERCONTROL_CT_SUBCLASS_MASK: i32 = 251658240i32;\npub const MIXERCONTROL_CT_UNITS_BOOLEAN: i32 = 65536i32;\npub const MIXERCONTROL_CT_UNITS_CUSTOM: i32 = 0i32;\npub const MIXERCONTROL_CT_UNITS_DECIBELS: i32 = 262144i32;\npub const MIXERCONTROL_CT_UNITS_MASK: i32 = 16711680i32;\npub const MIXERCONTROL_CT_UNITS_PERCENT: i32 = 327680i32;\npub const MIXERCONTROL_CT_UNITS_SIGNED: i32 = 131072i32;\npub const MIXERCONTROL_CT_UNITS_UNSIGNED: i32 = 196608i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERLINEA {\n    pub cbStruct: u32,\n    pub dwDestination: u32,\n    pub dwSource: u32,\n    pub dwLineID: u32,\n    pub fdwLine: u32,\n    pub dwUser: usize,\n    pub dwComponentType: MIXERLINE_COMPONENTTYPE,\n    pub cChannels: u32,\n    pub cConnections: u32,\n    pub cControls: u32,\n    pub szShortName: [i8; 16],\n    pub szName: [i8; 64],\n    pub Target: MIXERLINEA_0,\n}\nimpl Default for MIXERLINEA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERLINEA_0 {\n    pub dwType: u32,\n    pub dwDeviceID: u32,\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n}\nimpl Default for MIXERLINEA_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERLINECONTROLSA {\n    pub cbStruct: u32,\n    pub dwLineID: u32,\n    pub Anonymous: MIXERLINECONTROLSA_0,\n    pub cControls: u32,\n    pub cbmxctrl: u32,\n    pub pamxctrl: *mut MIXERCONTROLA,\n}\nimpl Default for MIXERLINECONTROLSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union MIXERLINECONTROLSA_0 {\n    pub dwControlID: u32,\n    pub dwControlType: u32,\n}\nimpl Default for MIXERLINECONTROLSA_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERLINECONTROLSW {\n    pub cbStruct: u32,\n    pub dwLineID: u32,\n    pub Anonymous: MIXERLINECONTROLSW_0,\n    pub cControls: u32,\n    pub cbmxctrl: u32,\n    pub pamxctrl: *mut MIXERCONTROLW,\n}\nimpl Default for MIXERLINECONTROLSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union MIXERLINECONTROLSW_0 {\n    pub dwControlID: u32,\n    pub dwControlType: u32,\n}\nimpl Default for MIXERLINECONTROLSW_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERLINEW {\n    pub cbStruct: u32,\n    pub dwDestination: u32,\n    pub dwSource: u32,\n    pub dwLineID: u32,\n    pub fdwLine: u32,\n    pub dwUser: usize,\n    pub dwComponentType: MIXERLINE_COMPONENTTYPE,\n    pub cChannels: u32,\n    pub cConnections: u32,\n    pub cControls: u32,\n    pub szShortName: [u16; 16],\n    pub szName: [u16; 64],\n    pub Target: MIXERLINEW_0,\n}\nimpl Default for MIXERLINEW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MIXERLINEW_0 {\n    pub dwType: u32,\n    pub dwDeviceID: u32,\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n}\nimpl Default for MIXERLINEW_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type MIXERLINE_COMPONENTTYPE = u32;\npub const MIXERLINE_COMPONENTTYPE_DST_DIGITAL: MIXERLINE_COMPONENTTYPE = 1u32;\npub const MIXERLINE_COMPONENTTYPE_DST_FIRST: i32 = 0i32;\npub const MIXERLINE_COMPONENTTYPE_DST_HEADPHONES: MIXERLINE_COMPONENTTYPE = 5u32;\npub const MIXERLINE_COMPONENTTYPE_DST_LAST: u32 = 8u32;\npub const MIXERLINE_COMPONENTTYPE_DST_LINE: MIXERLINE_COMPONENTTYPE = 2u32;\npub const MIXERLINE_COMPONENTTYPE_DST_MONITOR: MIXERLINE_COMPONENTTYPE = 3u32;\npub const MIXERLINE_COMPONENTTYPE_DST_SPEAKERS: MIXERLINE_COMPONENTTYPE = 4u32;\npub const MIXERLINE_COMPONENTTYPE_DST_TELEPHONE: MIXERLINE_COMPONENTTYPE = 6u32;\npub const MIXERLINE_COMPONENTTYPE_DST_UNDEFINED: MIXERLINE_COMPONENTTYPE = 0u32;\npub const MIXERLINE_COMPONENTTYPE_DST_VOICEIN: MIXERLINE_COMPONENTTYPE = 8u32;\npub const MIXERLINE_COMPONENTTYPE_DST_WAVEIN: MIXERLINE_COMPONENTTYPE = 7u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_ANALOG: MIXERLINE_COMPONENTTYPE = 4106u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY: MIXERLINE_COMPONENTTYPE = 4105u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC: MIXERLINE_COMPONENTTYPE = 4101u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_DIGITAL: MIXERLINE_COMPONENTTYPE = 4097u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_FIRST: i32 = 4096i32;\npub const MIXERLINE_COMPONENTTYPE_SRC_LAST: u32 = 4106u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_LINE: MIXERLINE_COMPONENTTYPE = 4098u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE: MIXERLINE_COMPONENTTYPE = 4099u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER: MIXERLINE_COMPONENTTYPE = 4103u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER: MIXERLINE_COMPONENTTYPE = 4100u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE: MIXERLINE_COMPONENTTYPE = 4102u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED: MIXERLINE_COMPONENTTYPE = 4096u32;\npub const MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT: MIXERLINE_COMPONENTTYPE = 4104u32;\npub const MIXERLINE_LINEF_ACTIVE: i32 = 1i32;\npub const MIXERLINE_LINEF_DISCONNECTED: i32 = 32768i32;\npub const MIXERLINE_LINEF_SOURCE: i32 = -2147483648i32;\npub const MIXERLINE_TARGETTYPE_AUX: u32 = 5u32;\npub const MIXERLINE_TARGETTYPE_MIDIIN: u32 = 4u32;\npub const MIXERLINE_TARGETTYPE_MIDIOUT: u32 = 3u32;\npub const MIXERLINE_TARGETTYPE_UNDEFINED: u32 = 0u32;\npub const MIXERLINE_TARGETTYPE_WAVEIN: u32 = 2u32;\npub const MIXERLINE_TARGETTYPE_WAVEOUT: u32 = 1u32;\npub const MIXERR_INVALCONTROL: u32 = 1025u32;\npub const MIXERR_INVALLINE: u32 = 1024u32;\npub const MIXERR_INVALVALUE: u32 = 1026u32;\npub const MIXERR_LASTERROR: u32 = 1026u32;\npub const MIXER_GETCONTROLDETAILSF_LISTTEXT: i32 = 1i32;\npub const MIXER_GETCONTROLDETAILSF_QUERYMASK: i32 = 15i32;\npub const MIXER_GETCONTROLDETAILSF_VALUE: i32 = 0i32;\npub const MIXER_GETLINECONTROLSF_ALL: i32 = 0i32;\npub const MIXER_GETLINECONTROLSF_ONEBYID: i32 = 1i32;\npub const MIXER_GETLINECONTROLSF_ONEBYTYPE: i32 = 2i32;\npub const MIXER_GETLINECONTROLSF_QUERYMASK: i32 = 15i32;\npub const MIXER_GETLINEINFOF_COMPONENTTYPE: i32 = 3i32;\npub const MIXER_GETLINEINFOF_DESTINATION: i32 = 0i32;\npub const MIXER_GETLINEINFOF_LINEID: i32 = 2i32;\npub const MIXER_GETLINEINFOF_QUERYMASK: i32 = 15i32;\npub const MIXER_GETLINEINFOF_SOURCE: i32 = 1i32;\npub const MIXER_GETLINEINFOF_TARGETTYPE: i32 = 4i32;\npub const MIXER_LONG_NAME_CHARS: u32 = 64u32;\npub const MIXER_OBJECTF_AUX: i32 = 1342177280i32;\npub const MIXER_OBJECTF_HANDLE: i32 = -2147483648i32;\npub const MIXER_OBJECTF_MIDIIN: i32 = 1073741824i32;\npub const MIXER_OBJECTF_MIDIOUT: i32 = 805306368i32;\npub const MIXER_OBJECTF_MIXER: i32 = 0i32;\npub const MIXER_OBJECTF_WAVEIN: i32 = 536870912i32;\npub const MIXER_OBJECTF_WAVEOUT: i32 = 268435456i32;\npub const MIXER_SETCONTROLDETAILSF_CUSTOM: i32 = 1i32;\npub const MIXER_SETCONTROLDETAILSF_QUERYMASK: i32 = 15i32;\npub const MIXER_SETCONTROLDETAILSF_VALUE: i32 = 0i32;\npub const MIXER_SHORT_NAME_CHARS: u32 = 16u32;\npub const MMDeviceEnumerator: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbcde0395_e52f_467c_8e3d_c4579291692e);\npub const MM_ACM_FILTERCHOOSE: u32 = 32768u32;\npub const MM_ACM_FORMATCHOOSE: u32 = 32768u32;\npub const MOD_FMSYNTH: u32 = 4u32;\npub const MOD_MAPPER: u32 = 5u32;\npub const MOD_MIDIPORT: u32 = 1u32;\npub const MOD_SQSYNTH: u32 = 3u32;\npub const MOD_SWSYNTH: u32 = 7u32;\npub const MOD_SYNTH: u32 = 2u32;\npub const MOD_WAVETABLE: u32 = 6u32;\npub const Microphone: EndpointFormFactor = 4i32;\npub const Muted: AudioStateMonitorSoundLevel = 0i32;\npub const Out: DataFlow = 1i32;\npub type PAudioStateMonitorCallback = Option<unsafe extern \"system\" fn(audiostatemonitor: *mut core::ffi::c_void, context: *const core::ffi::c_void)>;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct PCMWAVEFORMAT {\n    pub wf: WAVEFORMAT,\n    pub wBitsPerSample: u16,\n}\npub const PKEY_AudioEndpointLogo_IconEffects: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf1ab780d_2010_4ed3_a3a6_8b87f0f0c476), pid: 0 };\npub const PKEY_AudioEndpointLogo_IconPath: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf1ab780d_2010_4ed3_a3a6_8b87f0f0c476), pid: 1 };\npub const PKEY_AudioEndpointSettings_LaunchContract: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x14242002_0320_4de4_9555_a7d82b73c286), pid: 1 };\npub const PKEY_AudioEndpointSettings_MenuText: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x14242002_0320_4de4_9555_a7d82b73c286), pid: 0 };\npub const PKEY_AudioEndpoint_Association: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1da5d803_d492_4edd_8c23_e0c0ffee7f0e), pid: 2 };\npub const PKEY_AudioEndpoint_ControlPanelPageProvider: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1da5d803_d492_4edd_8c23_e0c0ffee7f0e), pid: 1 };\npub const PKEY_AudioEndpoint_Default_VolumeInDb: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1da5d803_d492_4edd_8c23_e0c0ffee7f0e), pid: 9 };\npub const PKEY_AudioEndpoint_Disable_SysFx: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1da5d803_d492_4edd_8c23_e0c0ffee7f0e), pid: 5 };\npub const PKEY_AudioEndpoint_FormFactor: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1da5d803_d492_4edd_8c23_e0c0ffee7f0e), pid: 0 };\npub const PKEY_AudioEndpoint_FullRangeSpeakers: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1da5d803_d492_4edd_8c23_e0c0ffee7f0e), pid: 6 };\npub const PKEY_AudioEndpoint_GUID: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1da5d803_d492_4edd_8c23_e0c0ffee7f0e), pid: 4 };\npub const PKEY_AudioEndpoint_JackSubType: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1da5d803_d492_4edd_8c23_e0c0ffee7f0e), pid: 8 };\npub const PKEY_AudioEndpoint_PhysicalSpeakers: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1da5d803_d492_4edd_8c23_e0c0ffee7f0e), pid: 3 };\npub const PKEY_AudioEndpoint_Supports_EventDriven_Mode: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0x1da5d803_d492_4edd_8c23_e0c0ffee7f0e), pid: 7 };\npub const PKEY_AudioEngine_DeviceFormat: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xf19f064d_082c_4e27_bc73_6882a1bb8e4c), pid: 0 };\npub const PKEY_AudioEngine_OEMFormat: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_sys::core::GUID::from_u128(0xe4870e26_3cc5_4cd2_ba46_ca0a9a70ed04), pid: 3 };\npub type PROCESS_LOOPBACK_MODE = i32;\npub const PROCESS_LOOPBACK_MODE_EXCLUDE_TARGET_PROCESS_TREE: PROCESS_LOOPBACK_MODE = 1i32;\npub const PROCESS_LOOPBACK_MODE_INCLUDE_TARGET_PROCESS_TREE: PROCESS_LOOPBACK_MODE = 0i32;\npub type PartType = i32;\npub const RemoteNetworkDevice: EndpointFormFactor = 0i32;\npub const SND_ALIAS: SND_FLAGS = 65536u32;\npub const SND_ALIAS_ID: SND_FLAGS = 1114112u32;\npub const SND_ALIAS_START: u32 = 0u32;\npub const SND_APPLICATION: SND_FLAGS = 128u32;\npub const SND_ASYNC: SND_FLAGS = 1u32;\npub const SND_FILENAME: SND_FLAGS = 131072u32;\npub type SND_FLAGS = u32;\npub const SND_LOOP: SND_FLAGS = 8u32;\npub const SND_MEMORY: SND_FLAGS = 4u32;\npub const SND_NODEFAULT: SND_FLAGS = 2u32;\npub const SND_NOSTOP: SND_FLAGS = 16u32;\npub const SND_NOWAIT: SND_FLAGS = 8192u32;\npub const SND_PURGE: SND_FLAGS = 64u32;\npub const SND_RESOURCE: SND_FLAGS = 262148u32;\npub const SND_RING: i32 = 1048576i32;\npub const SND_SENTRY: SND_FLAGS = 524288u32;\npub const SND_SYNC: SND_FLAGS = 0u32;\npub const SND_SYSTEM: SND_FLAGS = 2097152u32;\npub const SPATIAL_AUDIO_POSITION: u32 = 200u32;\npub const SPATIAL_AUDIO_STANDARD_COMMANDS_START: u32 = 200u32;\npub type SPATIAL_AUDIO_STREAM_OPTIONS = i32;\npub const SPATIAL_AUDIO_STREAM_OPTIONS_NONE: SPATIAL_AUDIO_STREAM_OPTIONS = 0i32;\npub const SPATIAL_AUDIO_STREAM_OPTIONS_OFFLOAD: SPATIAL_AUDIO_STREAM_OPTIONS = 1i32;\npub const SPDIF: EndpointFormFactor = 8i32;\npub const SPTLAUDCLNT_E_DESTROYED: windows_sys::core::HRESULT = 0x88890100_u32 as _;\npub const SPTLAUDCLNT_E_ERRORS_IN_OBJECT_CALLS: windows_sys::core::HRESULT = 0x88890105_u32 as _;\npub const SPTLAUDCLNT_E_INTERNAL: windows_sys::core::HRESULT = 0x8889010D_u32 as _;\npub const SPTLAUDCLNT_E_INVALID_LICENSE: windows_sys::core::HRESULT = 0x88890108_u32 as _;\npub const SPTLAUDCLNT_E_METADATA_FORMAT_NOT_SUPPORTED: windows_sys::core::HRESULT = 0x88890106_u32 as _;\npub const SPTLAUDCLNT_E_NO_MORE_OBJECTS: windows_sys::core::HRESULT = 0x88890103_u32 as _;\npub const SPTLAUDCLNT_E_OBJECT_ALREADY_ACTIVE: windows_sys::core::HRESULT = 0x8889010C_u32 as _;\npub const SPTLAUDCLNT_E_OUT_OF_ORDER: windows_sys::core::HRESULT = 0x88890101_u32 as _;\npub const SPTLAUDCLNT_E_PROPERTY_NOT_SUPPORTED: windows_sys::core::HRESULT = 0x88890104_u32 as _;\npub const SPTLAUDCLNT_E_RESOURCES_INVALIDATED: windows_sys::core::HRESULT = 0x88890102_u32 as _;\npub const SPTLAUDCLNT_E_STATIC_OBJECT_NOT_AVAILABLE: windows_sys::core::HRESULT = 0x8889010B_u32 as _;\npub const SPTLAUDCLNT_E_STREAM_NOT_AVAILABLE: windows_sys::core::HRESULT = 0x88890107_u32 as _;\npub const SPTLAUDCLNT_E_STREAM_NOT_STOPPED: windows_sys::core::HRESULT = 0x8889010A_u32 as _;\npub const SPTLAUD_MD_CLNT_E_ATTACH_FAILED_INTERNAL_BUFFER: windows_sys::core::HRESULT = 0x88890214_u32 as _;\npub const SPTLAUD_MD_CLNT_E_BUFFER_ALREADY_ATTACHED: windows_sys::core::HRESULT = 0x88890207_u32 as _;\npub const SPTLAUD_MD_CLNT_E_BUFFER_NOT_ATTACHED: windows_sys::core::HRESULT = 0x88890208_u32 as _;\npub const SPTLAUD_MD_CLNT_E_BUFFER_STILL_ATTACHED: windows_sys::core::HRESULT = 0x88890224_u32 as _;\npub const SPTLAUD_MD_CLNT_E_COMMAND_ALREADY_WRITTEN: windows_sys::core::HRESULT = 0x88890222_u32 as _;\npub const SPTLAUD_MD_CLNT_E_COMMAND_NOT_FOUND: windows_sys::core::HRESULT = 0x88890200_u32 as _;\npub const SPTLAUD_MD_CLNT_E_DETACH_FAILED_INTERNAL_BUFFER: windows_sys::core::HRESULT = 0x88890215_u32 as _;\npub const SPTLAUD_MD_CLNT_E_FORMAT_MISMATCH: windows_sys::core::HRESULT = 0x88890223_u32 as _;\npub const SPTLAUD_MD_CLNT_E_FRAMECOUNT_OUT_OF_RANGE: windows_sys::core::HRESULT = 0x88890209_u32 as _;\npub const SPTLAUD_MD_CLNT_E_FRAMEOFFSET_OUT_OF_RANGE: windows_sys::core::HRESULT = 0x88890218_u32 as _;\npub const SPTLAUD_MD_CLNT_E_INVALID_ARGS: windows_sys::core::HRESULT = 0x88890202_u32 as _;\npub const SPTLAUD_MD_CLNT_E_ITEMS_ALREADY_OPEN: windows_sys::core::HRESULT = 0x88890213_u32 as _;\npub const SPTLAUD_MD_CLNT_E_ITEMS_LOCKED_FOR_WRITING: windows_sys::core::HRESULT = 0x88890225_u32 as _;\npub const SPTLAUD_MD_CLNT_E_ITEM_COPY_OVERFLOW: windows_sys::core::HRESULT = 0x88890211_u32 as _;\npub const SPTLAUD_MD_CLNT_E_ITEM_MUST_HAVE_COMMANDS: windows_sys::core::HRESULT = 0x88890219_u32 as _;\npub const SPTLAUD_MD_CLNT_E_MEMORY_BOUNDS: windows_sys::core::HRESULT = 0x88890205_u32 as _;\npub const SPTLAUD_MD_CLNT_E_METADATA_FORMAT_NOT_FOUND: windows_sys::core::HRESULT = 0x88890203_u32 as _;\npub const SPTLAUD_MD_CLNT_E_NO_BUFFER_ATTACHED: windows_sys::core::HRESULT = 0x88890216_u32 as _;\npub const SPTLAUD_MD_CLNT_E_NO_ITEMOFFSET_WRITTEN: windows_sys::core::HRESULT = 0x88890220_u32 as _;\npub const SPTLAUD_MD_CLNT_E_NO_ITEMS_FOUND: windows_sys::core::HRESULT = 0x88890210_u32 as _;\npub const SPTLAUD_MD_CLNT_E_NO_ITEMS_OPEN: windows_sys::core::HRESULT = 0x88890212_u32 as _;\npub const SPTLAUD_MD_CLNT_E_NO_ITEMS_WRITTEN: windows_sys::core::HRESULT = 0x88890221_u32 as _;\npub const SPTLAUD_MD_CLNT_E_NO_MORE_COMMANDS: windows_sys::core::HRESULT = 0x88890206_u32 as _;\npub const SPTLAUD_MD_CLNT_E_NO_MORE_ITEMS: windows_sys::core::HRESULT = 0x88890217_u32 as _;\npub const SPTLAUD_MD_CLNT_E_OBJECT_NOT_INITIALIZED: windows_sys::core::HRESULT = 0x88890201_u32 as _;\npub const SPTLAUD_MD_CLNT_E_VALUE_BUFFER_INCORRECT_SIZE: windows_sys::core::HRESULT = 0x88890204_u32 as _;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SpatialAudioClientActivationParams {\n    pub tracingContextId: windows_sys::core::GUID,\n    pub appId: windows_sys::core::GUID,\n    pub majorVersion: i32,\n    pub minorVersion1: i32,\n    pub minorVersion2: i32,\n    pub minorVersion3: i32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct SpatialAudioHrtfActivationParams {\n    pub ObjectFormat: *const WAVEFORMATEX,\n    pub StaticObjectTypeMask: AudioObjectType,\n    pub MinDynamicObjectCount: u32,\n    pub MaxDynamicObjectCount: u32,\n    pub Category: AUDIO_STREAM_CATEGORY,\n    pub EventHandle: super::super::Foundation::HANDLE,\n    pub NotifyObject: *mut core::ffi::c_void,\n    pub DistanceDecay: *mut SpatialAudioHrtfDistanceDecay,\n    pub Directivity: *mut SpatialAudioHrtfDirectivityUnion,\n    pub Environment: *mut SpatialAudioHrtfEnvironmentType,\n    pub Orientation: *mut f32,\n}\nimpl Default for SpatialAudioHrtfActivationParams {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct SpatialAudioHrtfActivationParams2 {\n    pub ObjectFormat: *const WAVEFORMATEX,\n    pub StaticObjectTypeMask: AudioObjectType,\n    pub MinDynamicObjectCount: u32,\n    pub MaxDynamicObjectCount: u32,\n    pub Category: AUDIO_STREAM_CATEGORY,\n    pub EventHandle: super::super::Foundation::HANDLE,\n    pub NotifyObject: *mut core::ffi::c_void,\n    pub DistanceDecay: *mut SpatialAudioHrtfDistanceDecay,\n    pub Directivity: *mut SpatialAudioHrtfDirectivityUnion,\n    pub Environment: *mut SpatialAudioHrtfEnvironmentType,\n    pub Orientation: *mut f32,\n    pub Options: SPATIAL_AUDIO_STREAM_OPTIONS,\n}\nimpl Default for SpatialAudioHrtfActivationParams2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct SpatialAudioHrtfDirectivity {\n    pub Type: SpatialAudioHrtfDirectivityType,\n    pub Scaling: f32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct SpatialAudioHrtfDirectivityCardioid {\n    pub directivity: SpatialAudioHrtfDirectivity,\n    pub Order: f32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct SpatialAudioHrtfDirectivityCone {\n    pub directivity: SpatialAudioHrtfDirectivity,\n    pub InnerAngle: f32,\n    pub OuterAngle: f32,\n}\npub type SpatialAudioHrtfDirectivityType = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union SpatialAudioHrtfDirectivityUnion {\n    pub Cone: SpatialAudioHrtfDirectivityCone,\n    pub Cardiod: SpatialAudioHrtfDirectivityCardioid,\n    pub Omni: SpatialAudioHrtfDirectivity,\n}\nimpl Default for SpatialAudioHrtfDirectivityUnion {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SpatialAudioHrtfDirectivity_Cardioid: SpatialAudioHrtfDirectivityType = 1i32;\npub const SpatialAudioHrtfDirectivity_Cone: SpatialAudioHrtfDirectivityType = 2i32;\npub const SpatialAudioHrtfDirectivity_OmniDirectional: SpatialAudioHrtfDirectivityType = 0i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct SpatialAudioHrtfDistanceDecay {\n    pub Type: SpatialAudioHrtfDistanceDecayType,\n    pub MaxGain: f32,\n    pub MinGain: f32,\n    pub UnityGainDistance: f32,\n    pub CutoffDistance: f32,\n}\npub type SpatialAudioHrtfDistanceDecayType = i32;\npub const SpatialAudioHrtfDistanceDecay_CustomDecay: SpatialAudioHrtfDistanceDecayType = 1i32;\npub const SpatialAudioHrtfDistanceDecay_NaturalDecay: SpatialAudioHrtfDistanceDecayType = 0i32;\npub type SpatialAudioHrtfEnvironmentType = i32;\npub const SpatialAudioHrtfEnvironment_Average: SpatialAudioHrtfEnvironmentType = 4i32;\npub const SpatialAudioHrtfEnvironment_Large: SpatialAudioHrtfEnvironmentType = 2i32;\npub const SpatialAudioHrtfEnvironment_Medium: SpatialAudioHrtfEnvironmentType = 1i32;\npub const SpatialAudioHrtfEnvironment_Outdoors: SpatialAudioHrtfEnvironmentType = 3i32;\npub const SpatialAudioHrtfEnvironment_Small: SpatialAudioHrtfEnvironmentType = 0i32;\npub type SpatialAudioMetadataCopyMode = i32;\npub const SpatialAudioMetadataCopy_Append: SpatialAudioMetadataCopyMode = 1i32;\npub const SpatialAudioMetadataCopy_AppendMergeWithFirst: SpatialAudioMetadataCopyMode = 3i32;\npub const SpatialAudioMetadataCopy_AppendMergeWithLast: SpatialAudioMetadataCopyMode = 2i32;\npub const SpatialAudioMetadataCopy_Overwrite: SpatialAudioMetadataCopyMode = 0i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct SpatialAudioMetadataItemsInfo {\n    pub FrameCount: u16,\n    pub ItemCount: u16,\n    pub MaxItemCount: u16,\n    pub MaxValueBufferLength: u32,\n}\npub type SpatialAudioMetadataWriterOverflowMode = i32;\npub const SpatialAudioMetadataWriterOverflow_Fail: SpatialAudioMetadataWriterOverflowMode = 0i32;\npub const SpatialAudioMetadataWriterOverflow_MergeWithLast: SpatialAudioMetadataWriterOverflowMode = 2i32;\npub const SpatialAudioMetadataWriterOverflow_MergeWithNew: SpatialAudioMetadataWriterOverflowMode = 1i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct SpatialAudioObjectRenderStreamActivationParams {\n    pub ObjectFormat: *const WAVEFORMATEX,\n    pub StaticObjectTypeMask: AudioObjectType,\n    pub MinDynamicObjectCount: u32,\n    pub MaxDynamicObjectCount: u32,\n    pub Category: AUDIO_STREAM_CATEGORY,\n    pub EventHandle: super::super::Foundation::HANDLE,\n    pub NotifyObject: *mut core::ffi::c_void,\n}\nimpl Default for SpatialAudioObjectRenderStreamActivationParams {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct SpatialAudioObjectRenderStreamActivationParams2 {\n    pub ObjectFormat: *const WAVEFORMATEX,\n    pub StaticObjectTypeMask: AudioObjectType,\n    pub MinDynamicObjectCount: u32,\n    pub MaxDynamicObjectCount: u32,\n    pub Category: AUDIO_STREAM_CATEGORY,\n    pub EventHandle: super::super::Foundation::HANDLE,\n    pub NotifyObject: *mut core::ffi::c_void,\n    pub Options: SPATIAL_AUDIO_STREAM_OPTIONS,\n}\nimpl Default for SpatialAudioObjectRenderStreamActivationParams2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[cfg(all(feature = \"Win32_System_Com_StructuredStorage\", feature = \"Win32_System_Variant\"))]\n#[derive(Clone, Copy)]\npub struct SpatialAudioObjectRenderStreamForMetadataActivationParams {\n    pub ObjectFormat: *const WAVEFORMATEX,\n    pub StaticObjectTypeMask: AudioObjectType,\n    pub MinDynamicObjectCount: u32,\n    pub MaxDynamicObjectCount: u32,\n    pub Category: AUDIO_STREAM_CATEGORY,\n    pub EventHandle: super::super::Foundation::HANDLE,\n    pub MetadataFormatId: windows_sys::core::GUID,\n    pub MaxMetadataItemCount: u16,\n    pub MetadataActivationParams: *const super::super::System::Com::StructuredStorage::PROPVARIANT,\n    pub NotifyObject: *mut core::ffi::c_void,\n}\n#[cfg(all(feature = \"Win32_System_Com_StructuredStorage\", feature = \"Win32_System_Variant\"))]\nimpl Default for SpatialAudioObjectRenderStreamForMetadataActivationParams {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[cfg(all(feature = \"Win32_System_Com_StructuredStorage\", feature = \"Win32_System_Variant\"))]\n#[derive(Clone, Copy)]\npub struct SpatialAudioObjectRenderStreamForMetadataActivationParams2 {\n    pub ObjectFormat: *const WAVEFORMATEX,\n    pub StaticObjectTypeMask: AudioObjectType,\n    pub MinDynamicObjectCount: u32,\n    pub MaxDynamicObjectCount: u32,\n    pub Category: AUDIO_STREAM_CATEGORY,\n    pub EventHandle: super::super::Foundation::HANDLE,\n    pub MetadataFormatId: windows_sys::core::GUID,\n    pub MaxMetadataItemCount: u32,\n    pub MetadataActivationParams: *const super::super::System::Com::StructuredStorage::PROPVARIANT,\n    pub NotifyObject: *mut core::ffi::c_void,\n    pub Options: SPATIAL_AUDIO_STREAM_OPTIONS,\n}\n#[cfg(all(feature = \"Win32_System_Com_StructuredStorage\", feature = \"Win32_System_Variant\"))]\nimpl Default for SpatialAudioObjectRenderStreamForMetadataActivationParams2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const Speakers: EndpointFormFactor = 1i32;\npub const Subunit: PartType = 1i32;\npub const UnknownDigitalPassthrough: EndpointFormFactor = 7i32;\npub const UnknownFormFactor: EndpointFormFactor = 10i32;\npub const VIRTUAL_AUDIO_DEVICE_PROCESS_LOOPBACK: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VAD\\\\Process_Loopback\");\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct VOLUMEWAVEFILTER {\n    pub wfltr: WAVEFILTER,\n    pub dwVolume: u32,\n}\npub const WAVECAPS_LRVOLUME: u32 = 8u32;\npub const WAVECAPS_PITCH: u32 = 1u32;\npub const WAVECAPS_PLAYBACKRATE: u32 = 2u32;\npub const WAVECAPS_SAMPLEACCURATE: u32 = 32u32;\npub const WAVECAPS_SYNC: u32 = 16u32;\npub const WAVECAPS_VOLUME: u32 = 4u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEFILTER {\n    pub cbStruct: u32,\n    pub dwFilterTag: u32,\n    pub fdwFilter: u32,\n    pub dwReserved: [u32; 5],\n}\nimpl Default for WAVEFILTER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct WAVEFORMAT {\n    pub wFormatTag: u16,\n    pub nChannels: u16,\n    pub nSamplesPerSec: u32,\n    pub nAvgBytesPerSec: u32,\n    pub nBlockAlign: u16,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct WAVEFORMATEX {\n    pub wFormatTag: u16,\n    pub nChannels: u16,\n    pub nSamplesPerSec: u32,\n    pub nAvgBytesPerSec: u32,\n    pub nBlockAlign: u16,\n    pub wBitsPerSample: u16,\n    pub cbSize: u16,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEFORMATEXTENSIBLE {\n    pub Format: WAVEFORMATEX,\n    pub Samples: WAVEFORMATEXTENSIBLE_0,\n    pub dwChannelMask: u32,\n    pub SubFormat: windows_sys::core::GUID,\n}\nimpl Default for WAVEFORMATEXTENSIBLE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union WAVEFORMATEXTENSIBLE_0 {\n    pub wValidBitsPerSample: u16,\n    pub wSamplesPerBlock: u16,\n    pub wReserved: u16,\n}\nimpl Default for WAVEFORMATEXTENSIBLE_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEHDR {\n    pub lpData: windows_sys::core::PSTR,\n    pub dwBufferLength: u32,\n    pub dwBytesRecorded: u32,\n    pub dwUser: usize,\n    pub dwFlags: u32,\n    pub dwLoops: u32,\n    pub lpNext: *mut WAVEHDR,\n    pub reserved: usize,\n}\nimpl Default for WAVEHDR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEINCAPS2A {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub dwFormats: u32,\n    pub wChannels: u16,\n    pub wReserved1: u16,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for WAVEINCAPS2A {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEINCAPS2W {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub dwFormats: u32,\n    pub wChannels: u16,\n    pub wReserved1: u16,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for WAVEINCAPS2W {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEINCAPSA {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub dwFormats: u32,\n    pub wChannels: u16,\n    pub wReserved1: u16,\n}\nimpl Default for WAVEINCAPSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEINCAPSW {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub dwFormats: u32,\n    pub wChannels: u16,\n    pub wReserved1: u16,\n}\nimpl Default for WAVEINCAPSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WAVEIN_MAPPER_STATUS_DEVICE: u32 = 0u32;\npub const WAVEIN_MAPPER_STATUS_FORMAT: u32 = 2u32;\npub const WAVEIN_MAPPER_STATUS_MAPPED: u32 = 1u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEOUTCAPS2A {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub dwFormats: u32,\n    pub wChannels: u16,\n    pub wReserved1: u16,\n    pub dwSupport: u32,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for WAVEOUTCAPS2A {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEOUTCAPS2W {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub dwFormats: u32,\n    pub wChannels: u16,\n    pub wReserved1: u16,\n    pub dwSupport: u32,\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for WAVEOUTCAPS2W {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEOUTCAPSA {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [i8; 32],\n    pub dwFormats: u32,\n    pub wChannels: u16,\n    pub wReserved1: u16,\n    pub dwSupport: u32,\n}\nimpl Default for WAVEOUTCAPSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WAVEOUTCAPSW {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub vDriverVersion: u32,\n    pub szPname: [u16; 32],\n    pub dwFormats: u32,\n    pub wChannels: u16,\n    pub wReserved1: u16,\n    pub dwSupport: u32,\n}\nimpl Default for WAVEOUTCAPSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WAVEOUT_MAPPER_STATUS_DEVICE: u32 = 0u32;\npub const WAVEOUT_MAPPER_STATUS_FORMAT: u32 = 2u32;\npub const WAVEOUT_MAPPER_STATUS_MAPPED: u32 = 1u32;\npub const WAVERR_BADFORMAT: u32 = 32u32;\npub const WAVERR_LASTERROR: u32 = 35u32;\npub const WAVERR_STILLPLAYING: u32 = 33u32;\npub const WAVERR_SYNC: u32 = 35u32;\npub const WAVERR_UNPREPARED: u32 = 34u32;\npub const WAVE_ALLOWSYNC: MIDI_WAVE_OPEN_TYPE = 2u32;\npub const WAVE_FORMAT_1M08: u32 = 1u32;\npub const WAVE_FORMAT_1M16: u32 = 4u32;\npub const WAVE_FORMAT_1S08: u32 = 2u32;\npub const WAVE_FORMAT_1S16: u32 = 8u32;\npub const WAVE_FORMAT_2M08: u32 = 16u32;\npub const WAVE_FORMAT_2M16: u32 = 64u32;\npub const WAVE_FORMAT_2S08: u32 = 32u32;\npub const WAVE_FORMAT_2S16: u32 = 128u32;\npub const WAVE_FORMAT_44M08: u32 = 256u32;\npub const WAVE_FORMAT_44M16: u32 = 1024u32;\npub const WAVE_FORMAT_44S08: u32 = 512u32;\npub const WAVE_FORMAT_44S16: u32 = 2048u32;\npub const WAVE_FORMAT_48M08: u32 = 4096u32;\npub const WAVE_FORMAT_48M16: u32 = 16384u32;\npub const WAVE_FORMAT_48S08: u32 = 8192u32;\npub const WAVE_FORMAT_48S16: u32 = 32768u32;\npub const WAVE_FORMAT_4M08: u32 = 256u32;\npub const WAVE_FORMAT_4M16: u32 = 1024u32;\npub const WAVE_FORMAT_4S08: u32 = 512u32;\npub const WAVE_FORMAT_4S16: u32 = 2048u32;\npub const WAVE_FORMAT_96M08: u32 = 65536u32;\npub const WAVE_FORMAT_96M16: u32 = 262144u32;\npub const WAVE_FORMAT_96S08: u32 = 131072u32;\npub const WAVE_FORMAT_96S16: u32 = 524288u32;\npub const WAVE_FORMAT_DIRECT: MIDI_WAVE_OPEN_TYPE = 8u32;\npub const WAVE_FORMAT_DIRECT_QUERY: MIDI_WAVE_OPEN_TYPE = 9u32;\npub const WAVE_FORMAT_PCM: u32 = 1u32;\npub const WAVE_FORMAT_QUERY: MIDI_WAVE_OPEN_TYPE = 1u32;\npub const WAVE_INVALIDFORMAT: u32 = 0u32;\npub const WAVE_MAPPED: MIDI_WAVE_OPEN_TYPE = 4u32;\npub const WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE: MIDI_WAVE_OPEN_TYPE = 16u32;\npub const WAVE_MAPPER: u32 = 4294967295u32;\npub const WHDR_BEGINLOOP: u32 = 4u32;\npub const WHDR_DONE: u32 = 1u32;\npub const WHDR_ENDLOOP: u32 = 8u32;\npub const WHDR_INQUEUE: u32 = 16u32;\npub const WHDR_PREPARED: u32 = 2u32;\npub const WIDM_MAPPER_STATUS: u32 = 8192u32;\npub const WODM_MAPPER_STATUS: u32 = 8192u32;\npub type _AUDCLNT_BUFFERFLAGS = i32;\npub const eAll: EDataFlow = 2i32;\npub const eCapture: EDataFlow = 1i32;\npub const eCommunications: ERole = 2i32;\npub const eConsole: ERole = 0i32;\npub const eMultimedia: ERole = 1i32;\npub const eRender: EDataFlow = 0i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct tACMFORMATDETAILSW {\n    pub cbStruct: u32,\n    pub dwFormatIndex: u32,\n    pub dwFormatTag: u32,\n    pub fdwSupport: u32,\n    pub pwfx: *mut WAVEFORMATEX,\n    pub cbwfx: u32,\n    pub szFormat: [u16; 128],\n}\nimpl Default for tACMFORMATDETAILSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/Media/KernelStreaming/mod.rs",
      "sha256": "f06d581e4469bd5f50b77c5440993b54b35998da58439000feae29c143682e60",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "windows_link::link!(\"ksuser.dll\" \"system\" fn KsCreateAllocator(connectionhandle : super::super::Foundation:: HANDLE, allocatorframing : *const KSALLOCATOR_FRAMING, allocatorhandle : *mut super::super::Foundation:: HANDLE) -> u32);\nwindows_link::link!(\"ksuser.dll\" \"system\" fn KsCreateAllocator2(connectionhandle : super::super::Foundation:: HANDLE, allocatorframing : *const KSALLOCATOR_FRAMING, allocatorhandle : *mut super::super::Foundation:: HANDLE) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ksuser.dll\" \"system\" fn KsCreateClock(connectionhandle : super::super::Foundation:: HANDLE, clockcreate : *const KSCLOCK_CREATE, clockhandle : *mut super::super::Foundation:: HANDLE) -> u32);\nwindows_link::link!(\"ksuser.dll\" \"system\" fn KsCreateClock2(connectionhandle : super::super::Foundation:: HANDLE, clockcreate : *const KSCLOCK_CREATE, clockhandle : *mut super::super::Foundation:: HANDLE) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ksuser.dll\" \"system\" fn KsCreatePin(filterhandle : super::super::Foundation:: HANDLE, connect : *const KSPIN_CONNECT, desiredaccess : u32, connectionhandle : *mut super::super::Foundation:: HANDLE) -> u32);\nwindows_link::link!(\"ksuser.dll\" \"system\" fn KsCreatePin2(filterhandle : super::super::Foundation:: HANDLE, connect : *const KSPIN_CONNECT, desiredaccess : u32, connectionhandle : *mut super::super::Foundation:: HANDLE) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ksuser.dll\" \"system\" fn KsCreateTopologyNode(parenthandle : super::super::Foundation:: HANDLE, nodecreate : *const KSNODE_CREATE, desiredaccess : u32, nodehandle : *mut super::super::Foundation:: HANDLE) -> u32);\nwindows_link::link!(\"ksuser.dll\" \"system\" fn KsCreateTopologyNode2(parenthandle : super::super::Foundation:: HANDLE, nodecreate : *const KSNODE_CREATE, desiredaccess : u32, nodehandle : *mut super::super::Foundation:: HANDLE) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ksproxy.ax\" \"system\" fn KsGetMediaTypeCount(filterhandle : super::super::Foundation:: HANDLE, pinfactoryid : u32, mediatypecount : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ksproxy.ax\" \"system\" fn KsGetMultiplePinFactoryItems(filterhandle : super::super::Foundation:: HANDLE, pinfactoryid : u32, propertyid : u32, items : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ksproxy.ax\" \"system\" fn KsOpenDefaultDevice(category : *const windows_sys::core::GUID, access : u32, devicehandle : *mut super::super::Foundation:: HANDLE) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ksproxy.ax\" \"system\" fn KsResolveRequiredAttributes(datarange : *const KSDATAFORMAT, attributes : *const KSMULTIPLE_ITEM) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ksproxy.ax\" \"system\" fn KsSynchronousDeviceControl(handle : super::super::Foundation:: HANDLE, iocontrol : u32, inbuffer : *const core::ffi::c_void, inlength : u32, outbuffer : *mut core::ffi::c_void, outlength : u32, bytesreturned : *mut u32) -> windows_sys::core::HRESULT);\npub const AEC_MODE_FULL_DUPLEX: u32 = 2u32;\npub const AEC_MODE_HALF_DUPLEX: u32 = 1u32;\npub const AEC_MODE_PASS_THROUGH: u32 = 0u32;\npub const AEC_STATUS_FD_CURRENTLY_CONVERGED: u32 = 8u32;\npub const AEC_STATUS_FD_HISTORY_CONTINUOUSLY_CONVERGED: u32 = 1u32;\npub const AEC_STATUS_FD_HISTORY_PREVIOUSLY_DIVERGED: u32 = 2u32;\npub const AEC_STATUS_FD_HISTORY_UNINITIALIZED: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ALLOCATOR_PROPERTIES_EX {\n    pub cBuffers: i32,\n    pub cbBuffer: i32,\n    pub cbAlign: i32,\n    pub cbPrefix: i32,\n    pub MemoryType: windows_sys::core::GUID,\n    pub BusType: windows_sys::core::GUID,\n    pub State: PIPE_STATE,\n    pub Input: PIPE_TERMINATION,\n    pub Output: PIPE_TERMINATION,\n    pub Strategy: u32,\n    pub Flags: u32,\n    pub Weight: u32,\n    pub LogicalMemoryType: KS_LogicalMemoryType,\n    pub AllocatorPlace: PIPE_ALLOCATOR_PLACE,\n    pub Dimensions: PIPE_DIMENSIONS,\n    pub PhysicalRange: KS_FRAMING_RANGE,\n    pub PrevSegment: *mut core::ffi::c_void,\n    pub CountNextSegments: u32,\n    pub NextSegments: *mut *mut core::ffi::c_void,\n    pub InsideFactors: u32,\n    pub NumberPins: u32,\n}\nimpl Default for ALLOCATOR_PROPERTIES_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const APO_CLASS_UUID: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x5989fce8_9cd0_467d_8a6a_5419e31529d4);\npub const AUDIOENDPOINT_CLASS_UUID: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc166523c_fe0c_4a94_a586_f1a80cfbbf3e);\npub const AUDIOMODULE_MAX_DATA_SIZE: u32 = 64000u32;\npub const AUDIOMODULE_MAX_NAME_CCH_SIZE: u32 = 128u32;\npub type AUDIOPOSTURE_ORIENTATION = i32;\npub const AUDIOPOSTURE_ORIENTATION_NOTROTATED: AUDIOPOSTURE_ORIENTATION = 0i32;\npub const AUDIOPOSTURE_ORIENTATION_ROTATED180DEGREESCOUNTERCLOCKWISE: AUDIOPOSTURE_ORIENTATION = 2i32;\npub const AUDIOPOSTURE_ORIENTATION_ROTATED270DEGREESCOUNTERCLOCKWISE: AUDIOPOSTURE_ORIENTATION = 3i32;\npub const AUDIOPOSTURE_ORIENTATION_ROTATED90DEGREESCOUNTERCLOCKWISE: AUDIOPOSTURE_ORIENTATION = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AUDIORESOURCEMANAGEMENT_RESOURCEGROUP {\n    pub ResourceGroupAcquired: windows_sys::core::BOOL,\n    pub ResourceGroupName: [u16; 256],\n}\nimpl Default for AUDIORESOURCEMANAGEMENT_RESOURCEGROUP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type AUDIO_CURVE_TYPE = i32;\npub const AUDIO_CURVE_TYPE_NONE: AUDIO_CURVE_TYPE = 0i32;\npub const AUDIO_CURVE_TYPE_WINDOWS_FADE: AUDIO_CURVE_TYPE = 1i32;\npub const AUDIO_EFFECT_TYPE_ACOUSTIC_ECHO_CANCELLATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adbe_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_AUTOMATIC_GAIN_CONTROL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adc0_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_BASS_BOOST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adc5_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_BASS_MANAGEMENT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adca_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_BEAMFORMING: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adc1_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_CONSTANT_TONE_REMOVAL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adc2_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_DEEP_NOISE_SUPPRESSION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64add0_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_DYNAMIC_RANGE_COMPRESSION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adce_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_ENVIRONMENTAL_EFFECTS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adcb_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_EQUALIZER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adc3_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_FAR_FIELD_BEAMFORMING: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adcf_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_LOUDNESS_EQUALIZER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adc4_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_NOISE_SUPPRESSION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adbf_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_ROOM_CORRECTION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adc9_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_SPEAKER_COMPENSATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adcd_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_SPEAKER_FILL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adc8_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_SPEAKER_PROTECTION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adcc_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_VIRTUAL_HEADPHONES: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adc7_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_EFFECT_TYPE_VIRTUAL_SURROUND: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f64adc6_8211_11e2_8c70_2c27d7f001fa);\npub const AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x98951333_b9cd_48b1_a0a3_ff40682d73f7);\npub const AUDIO_SIGNALPROCESSINGMODE_DEFAULT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc18e2f7e_933d_4965_b7d1_1eef228d2af3);\npub const AUDIO_SIGNALPROCESSINGMODE_FAR_FIELD_SPEECH: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x28941cba_3be6_4a78_9a76_30fd91559b64);\npub const AUDIO_SIGNALPROCESSINGMODE_MEDIA: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4780004e_7133_41d8_8c74_660dadd2c0ee);\npub const AUDIO_SIGNALPROCESSINGMODE_MOVIE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb26feb0d_ec94_477c_9494_d1ab8e753f6e);\npub const AUDIO_SIGNALPROCESSINGMODE_NOTIFICATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9cf2a70b_f377_403b_bd6b_360863e0355c);\npub const AUDIO_SIGNALPROCESSINGMODE_RAW: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9e90ea20_b493_4fd1_a1a8_7e1361a956cf);\npub const AUDIO_SIGNALPROCESSINGMODE_SPEECH: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfc1cfc9b_b9d6_4cfa_b5e0_4bb2166878b2);\npub const AllocatorStrategy_DontCare: u32 = 0u32;\npub const AllocatorStrategy_MaximizeSpeed: u32 = 8u32;\npub const AllocatorStrategy_MinimizeFrameSize: u32 = 2u32;\npub const AllocatorStrategy_MinimizeNumberOfAllocators: u32 = 4u32;\npub const AllocatorStrategy_MinimizeNumberOfFrames: u32 = 1u32;\npub const BLUETOOTHLE_MIDI_SERVICE_UUID: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x03b80e5a_ede8_4b33_a751_6ce34ec4c700);\npub const BLUETOOTH_MIDI_DATAIO_CHARACTERISTIC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7772e5db_3868_4112_a1a9_f2669d106bf3);\npub const BUS_INTERFACE_REFERENCE_VERSION: u32 = 256u32;\npub type CAPTURE_MEMORY_ALLOCATION_FLAGS = i32;\npub const CASCADE_FORM: KSDS3D_HRTF_FILTER_METHOD = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CC_BYTE_PAIR {\n    pub Decoded: [u8; 2],\n    pub Reserved: u16,\n}\nimpl Default for CC_BYTE_PAIR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CC_HW_FIELD {\n    pub ScanlinesRequested: VBICODECFILTERING_SCANLINES,\n    pub fieldFlags: u32,\n    pub PictureNumber: i64,\n    pub Lines: [CC_BYTE_PAIR; 12],\n}\nimpl Default for CC_HW_FIELD {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CC_MAX_HW_DECODE_LINES: u32 = 12u32;\npub const CLSID_KsIBasicAudioInterfaceHandler: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb9f8ac3e_0f71_11d2_b72c_00c04fb6bd3d);\npub const CLSID_Proxy: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x17cca71b_ecd7_11d0_b908_00a0c9223196);\npub type CONSTRICTOR_OPTION = i32;\npub const CONSTRICTOR_OPTION_DISABLE: CONSTRICTOR_OPTION = 0i32;\npub const CONSTRICTOR_OPTION_MUTE: CONSTRICTOR_OPTION = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVCAPS {\n    pub CanRecord: i32,\n    pub CanRecordStrobe: i32,\n    pub HasAudio: i32,\n    pub HasVideo: i32,\n    pub UsesFiles: i32,\n    pub CanSave: i32,\n    pub DeviceType: i32,\n    pub TCRead: i32,\n    pub TCWrite: i32,\n    pub CTLRead: i32,\n    pub IndexRead: i32,\n    pub Preroll: i32,\n    pub Postroll: i32,\n    pub SyncAcc: i32,\n    pub NormRate: i32,\n    pub CanPreview: i32,\n    pub CanMonitorSrc: i32,\n    pub CanTest: i32,\n    pub VideoIn: i32,\n    pub AudioIn: i32,\n    pub Calibrate: i32,\n    pub SeekType: i32,\n    pub SimulatedHardware: i32,\n}\npub const DEVPKEY_KsAudio_Controller_DeviceInterface_Path: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x13e004d6_b066_43bd_913b_a415cd13da87), pid: 3 };\npub const DEVPKEY_KsAudio_PacketSize_Constraints: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x13e004d6_b066_43bd_913b_a415cd13da87), pid: 2 };\npub const DEVPKEY_KsAudio_PacketSize_Constraints2: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x9404f781_7191_409b_8b0b_80bf6ec229ae), pid: 2 };\npub const DIRECT_FORM: KSDS3D_HRTF_FILTER_METHOD = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DS3DVECTOR {\n    pub Anonymous1: DS3DVECTOR_0,\n    pub Anonymous2: DS3DVECTOR_1,\n    pub Anonymous3: DS3DVECTOR_2,\n}\nimpl Default for DS3DVECTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DS3DVECTOR_0 {\n    pub x: f32,\n    pub dvX: f32,\n}\nimpl Default for DS3DVECTOR_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DS3DVECTOR_1 {\n    pub y: f32,\n    pub dvY: f32,\n}\nimpl Default for DS3DVECTOR_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DS3DVECTOR_2 {\n    pub z: f32,\n    pub dvZ: f32,\n}\nimpl Default for DS3DVECTOR_2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DS3D_HRTF_VERSION_1: KSDS3D_HRTF_FILTER_VERSION = 0i32;\npub type EDeviceControlUseType = i32;\npub type EPcxConnectionType = i32;\npub type EPcxGenLocation = i32;\npub const EPcxGenLocation_enum_count: EPcxGenLocation = 4i32;\npub type EPcxGeoLocation = i32;\npub const EPcxGeoLocation_enum_count: EPcxGeoLocation = 16i32;\npub type EPxcPortConnection = i32;\npub const EVENTSETID_CROSSBAR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6a2e0641_28e4_11d0_a18c_00a0c9118956);\npub const EVENTSETID_TUNER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6a2e0606_28e4_11d0_a18c_00a0c9118956);\npub const EVENTSETID_VIDCAP_CAMERACONTROL_REGION_OF_INTEREST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2fdffc5d_c732_4ba6_b5df_6b4d7fc88b8b);\npub const EVENTSETID_VIDEODECODER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6a2e0621_28e4_11d0_a18c_00a0c9118956);\npub const FLOAT_COEFF: KSDS3D_HRTF_COEFF_FORMAT = 0i32;\npub type FRAMING_CACHE_OPS = i32;\npub type FRAMING_PROP = i32;\npub const FULL_FILTER: KSDS3D_HRTF_FILTER_QUALITY = 0i32;\npub const FramingProp_Ex: FRAMING_PROP = 3i32;\npub const FramingProp_None: FRAMING_PROP = 1i32;\npub const FramingProp_Old: FRAMING_PROP = 2i32;\npub const FramingProp_Uninitialized: FRAMING_PROP = 0i32;\npub const Framing_Cache_ReadLast: FRAMING_CACHE_OPS = 1i32;\npub const Framing_Cache_ReadOrig: FRAMING_CACHE_OPS = 2i32;\npub const Framing_Cache_Update: FRAMING_CACHE_OPS = 0i32;\npub const Framing_Cache_Write: FRAMING_CACHE_OPS = 3i32;\npub const GUID_NULL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000000_0000_0000_0000_000000000000);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct INTERLEAVED_AUDIO_FORMAT_INFORMATION {\n    pub Size: u32,\n    pub PrimaryChannelCount: u32,\n    pub PrimaryChannelStartPosition: u32,\n    pub PrimaryChannelMask: u32,\n    pub InterleavedChannelCount: u32,\n    pub InterleavedChannelStartPosition: u32,\n    pub InterleavedChannelMask: u32,\n}\npub const IOCTL_KS_DISABLE_EVENT: u32 = 3080203u32;\npub const IOCTL_KS_ENABLE_EVENT: u32 = 3080199u32;\npub const IOCTL_KS_HANDSHAKE: u32 = 3080223u32;\npub const IOCTL_KS_METHOD: u32 = 3080207u32;\npub const IOCTL_KS_PROPERTY: u32 = 3080195u32;\npub const IOCTL_KS_READ_STREAM: u32 = 3096599u32;\npub const IOCTL_KS_RESET_STATE: u32 = 3080219u32;\npub const IOCTL_KS_WRITE_STREAM: u32 = 3112979u32;\npub const JACKDESC2_DYNAMIC_FORMAT_CHANGE_CAPABILITY: u32 = 2u32;\npub const JACKDESC2_PRESENCE_DETECT_CAPABILITY: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAC3_ALTERNATE_AUDIO {\n    pub fStereo: windows_sys::core::BOOL,\n    pub DualMode: u32,\n}\npub const KSAC3_ALTERNATE_AUDIO_1: u32 = 1u32;\npub const KSAC3_ALTERNATE_AUDIO_2: u32 = 2u32;\npub const KSAC3_ALTERNATE_AUDIO_BOTH: u32 = 3u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAC3_BIT_STREAM_MODE {\n    pub BitStreamMode: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAC3_DIALOGUE_LEVEL {\n    pub DialogueLevel: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAC3_DOWNMIX {\n    pub fDownMix: windows_sys::core::BOOL,\n    pub fDolbySurround: windows_sys::core::BOOL,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAC3_ERROR_CONCEALMENT {\n    pub fRepeatPreviousBlock: windows_sys::core::BOOL,\n    pub fErrorInCurrentBlock: windows_sys::core::BOOL,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAC3_ROOM_TYPE {\n    pub fLargeRoom: windows_sys::core::BOOL,\n}\npub const KSAC3_SERVICE_COMMENTARY: u32 = 5u32;\npub const KSAC3_SERVICE_DIALOG_ONLY: u32 = 4u32;\npub const KSAC3_SERVICE_EMERGENCY_FLASH: u32 = 6u32;\npub const KSAC3_SERVICE_HEARING_IMPAIRED: u32 = 3u32;\npub const KSAC3_SERVICE_MAIN_AUDIO: u32 = 0u32;\npub const KSAC3_SERVICE_NO_DIALOG: u32 = 1u32;\npub const KSAC3_SERVICE_VISUALLY_IMPAIRED: u32 = 2u32;\npub const KSAC3_SERVICE_VOICE_OVER: u32 = 7u32;\npub const KSALGORITHMINSTANCE_SYSTEM_ACOUSTIC_ECHO_CANCEL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1c22c56d_9879_4f5b_a389_27996ddc2810);\npub const KSALGORITHMINSTANCE_SYSTEM_AGC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x950e55b9_877c_4c67_be08_e47b5611130a);\npub const KSALGORITHMINSTANCE_SYSTEM_MICROPHONE_ARRAY_PROCESSOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb6f5a0a0_9e61_4f8c_91e3_76cf0f3c471f);\npub const KSALGORITHMINSTANCE_SYSTEM_NOISE_SUPPRESS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x5ab0882e_7274_4516_877d_4eee99ba4fd0);\npub type KSALLOCATORMODE = i32;\npub const KSALLOCATOR_FLAG_2D_BUFFER_REQUIRED: u32 = 32768u32;\npub const KSALLOCATOR_FLAG_ALLOCATOR_EXISTS: u32 = 2048u32;\npub const KSALLOCATOR_FLAG_ATTENTION_STEPPING: u32 = 8192u32;\npub const KSALLOCATOR_FLAG_CAN_ALLOCATE: u32 = 64u32;\npub const KSALLOCATOR_FLAG_CYCLE: u32 = 1024u32;\npub const KSALLOCATOR_FLAG_DEVICE_SPECIFIC: u32 = 32u32;\npub const KSALLOCATOR_FLAG_ENABLE_CACHED_MDL: u32 = 16384u32;\npub const KSALLOCATOR_FLAG_INDEPENDENT_RANGES: u32 = 4096u32;\npub const KSALLOCATOR_FLAG_INSIST_ON_FRAMESIZE_RATIO: u32 = 128u32;\npub const KSALLOCATOR_FLAG_MULTIPLE_OUTPUT: u32 = 512u32;\npub const KSALLOCATOR_FLAG_NO_FRAME_INTEGRITY: u32 = 256u32;\npub const KSALLOCATOR_FLAG_PARTIAL_READ_SUPPORT: u32 = 16u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSALLOCATOR_FRAMING {\n    pub Anonymous1: KSALLOCATOR_FRAMING_0,\n    pub PoolType: u32,\n    pub Frames: u32,\n    pub FrameSize: u32,\n    pub Anonymous2: KSALLOCATOR_FRAMING_1,\n    pub Reserved: u32,\n}\nimpl Default for KSALLOCATOR_FRAMING {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSALLOCATOR_FRAMING_0 {\n    pub OptionsFlags: u32,\n    pub RequirementsFlags: u32,\n}\nimpl Default for KSALLOCATOR_FRAMING_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSALLOCATOR_FRAMING_1 {\n    pub FileAlignment: u32,\n    pub FramePitch: i32,\n}\nimpl Default for KSALLOCATOR_FRAMING_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSALLOCATOR_FRAMING_EX {\n    pub CountItems: u32,\n    pub PinFlags: u32,\n    pub OutputCompression: KS_COMPRESSION,\n    pub PinWeight: u32,\n    pub FramingItem: [KS_FRAMING_ITEM; 1],\n}\nimpl Default for KSALLOCATOR_FRAMING_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSALLOCATOR_OPTIONF_COMPATIBLE: u32 = 1u32;\npub const KSALLOCATOR_OPTIONF_SYSTEM_MEMORY: u32 = 2u32;\npub const KSALLOCATOR_OPTIONF_VALID: u32 = 3u32;\npub const KSALLOCATOR_REQUIREMENTF_FRAME_INTEGRITY: u32 = 4u32;\npub const KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER: u32 = 1u32;\npub const KSALLOCATOR_REQUIREMENTF_MUST_ALLOCATE: u32 = 8u32;\npub const KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY: u32 = 2147483648u32;\npub const KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY: u32 = 2u32;\npub const KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY_CUSTOM_ALLOCATION: u32 = 16u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSATTRIBUTE {\n    pub Size: u32,\n    pub Flags: u32,\n    pub Attribute: windows_sys::core::GUID,\n}\npub const KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe1f89eb5_5f46_419b_967b_ff6770b98401);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSATTRIBUTE_AUDIOSIGNALPROCESSING_MODE {\n    pub AttributeHeader: KSATTRIBUTE,\n    pub SignalProcessingMode: windows_sys::core::GUID,\n}\npub const KSATTRIBUTE_REQUIRED: u32 = 1u32;\npub const KSAUDDECOUTMODE_PCM_51: u32 = 2u32;\npub const KSAUDDECOUTMODE_SPDIFF: u32 = 4u32;\npub const KSAUDDECOUTMODE_STEREO_ANALOG: u32 = 1u32;\npub const KSAUDFNAME_3D_CENTER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9f0670b4_991f_11d2_ac4d_00c04f8efb68);\npub const KSAUDFNAME_3D_DEPTH: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x63ff5747_991f_11d2_ac4d_00c04f8efb68);\npub const KSAUDFNAME_3D_STEREO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fede2_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_ALTERNATE_MICROPHONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2bc31d6b_96e3_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_AUX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedfe_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_AUX_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedfd_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_AUX_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedfc_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_BASS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fede0_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_CD_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedfb_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_CD_IN_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedf3_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_CD_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedea_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_CD_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fede9_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_LINE_IN: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedf9_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_LINE_IN_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedf4_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_LINE_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedec_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_LINE_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedeb_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_MASTER_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fede4_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_MASTER_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fede3_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_MICROPHONE_BOOST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2bc31d6a_96e3_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_MIC_IN_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedf5_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_MIC_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedee_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_MIC_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185feded_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_MIDI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedf8_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_MIDI_IN_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedf2_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_MIDI_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fede8_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_MIDI_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fede7_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_MIDRANGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa2cbe478_ae84_49a1_8b72_4ad09b78ed34);\npub const KSAUDFNAME_MONO_MIX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00dff078_96e3_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_MONO_MIX_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2bc31d69_96e3_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_MONO_MIX_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x22b0eafe_96e3_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_MONO_OUT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf9b41dc3_96e2_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_MONO_OUT_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1ad247ec_96e3_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_MONO_OUT_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1ad247eb_96e3_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_PC_SPEAKER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedff_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_PC_SPEAKER_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedf1_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_PC_SPEAKER_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedf0_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_PEAKMETER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x57e24340_fc5b_4612_a562_72b11a29dfae);\npub const KSAUDFNAME_RECORDING_CONTROL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedfa_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_RECORDING_SOURCE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedef_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_STEREO_MIX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00dff077_96e3_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_STEREO_MIX_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x22b0eafd_96e3_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_STEREO_MIX_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1ad247ed_96e3_11d2_ac4c_00c04f8efb68);\npub const KSAUDFNAME_TREBLE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fede1_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x915daec4_a434_11d2_ac52_00c04f8efb68);\npub const KSAUDFNAME_VIDEO_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9b46e709_992a_11d2_ac4d_00c04f8efb68);\npub const KSAUDFNAME_VIDEO_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9b46e708_992a_11d2_ac4d_00c04f8efb68);\npub const KSAUDFNAME_VOLUME_CONTROL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedf7_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_WAVE_IN_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fedf6_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_WAVE_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fede6_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_WAVE_OUT_MIX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fee00_9905_11d1_95a9_00c04fb925d3);\npub const KSAUDFNAME_WAVE_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x185fede5_9905_11d1_95a9_00c04fb925d3);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIOENGINE_BUFFER_SIZE_RANGE {\n    pub MinBufferBytes: u32,\n    pub MaxBufferBytes: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIOENGINE_DESCRIPTOR {\n    pub nHostPinId: u32,\n    pub nOffloadPinId: u32,\n    pub nLoopbackPinId: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIOENGINE_DEVICECONTROLS {\n    pub Volume: EDeviceControlUseType,\n    pub Mute: EDeviceControlUseType,\n    pub PeakMeter: EDeviceControlUseType,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIOENGINE_VOLUMELEVEL {\n    pub TargetVolume: i32,\n    pub CurveType: AUDIO_CURVE_TYPE,\n    pub CurveDuration: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSAUDIOMODULE_DESCRIPTOR {\n    pub ClassId: windows_sys::core::GUID,\n    pub InstanceId: u32,\n    pub VersionMajor: u32,\n    pub VersionMinor: u32,\n    pub Name: [u16; 128],\n}\nimpl Default for KSAUDIOMODULE_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSAUDIOMODULE_NOTIFICATION {\n    pub Anonymous: KSAUDIOMODULE_NOTIFICATION_0,\n}\nimpl Default for KSAUDIOMODULE_NOTIFICATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSAUDIOMODULE_NOTIFICATION_0 {\n    pub ProviderId: KSAUDIOMODULE_NOTIFICATION_0_0,\n    pub Alignment: i64,\n}\nimpl Default for KSAUDIOMODULE_NOTIFICATION_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIOMODULE_NOTIFICATION_0_0 {\n    pub DeviceId: windows_sys::core::GUID,\n    pub ClassId: windows_sys::core::GUID,\n    pub InstanceId: u32,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSAUDIOMODULE_PROPERTY {\n    pub Property: KSIDENTIFIER,\n    pub ClassId: windows_sys::core::GUID,\n    pub InstanceId: u32,\n}\nimpl Default for KSAUDIOMODULE_PROPERTY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIO_CHANNEL_CONFIG {\n    pub ActiveSpeakerPositions: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIO_COPY_PROTECTION {\n    pub fCopyrighted: windows_sys::core::BOOL,\n    pub fOriginal: windows_sys::core::BOOL,\n}\npub const KSAUDIO_CPU_RESOURCES_HOST_CPU: u32 = 2147483647u32;\npub const KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIO_DYNAMIC_RANGE {\n    pub QuietCompression: u32,\n    pub LoudCompression: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIO_MICROPHONE_COORDINATES {\n    pub usType: u16,\n    pub wXCoord: i16,\n    pub wYCoord: i16,\n    pub wZCoord: i16,\n    pub wVerticalAngle: i16,\n    pub wHorizontalAngle: i16,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSAUDIO_MIC_ARRAY_GEOMETRY {\n    pub usVersion: u16,\n    pub usMicArrayType: u16,\n    pub wVerticalAngleBegin: i16,\n    pub wVerticalAngleEnd: i16,\n    pub wHorizontalAngleBegin: i16,\n    pub wHorizontalAngleEnd: i16,\n    pub usFrequencyBandLo: u16,\n    pub usFrequencyBandHi: u16,\n    pub usNumberOfMicrophones: u16,\n    pub KsMicCoord: [KSAUDIO_MICROPHONE_COORDINATES; 1],\n}\nimpl Default for KSAUDIO_MIC_ARRAY_GEOMETRY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSAUDIO_MIXCAP_TABLE {\n    pub InputChannels: u32,\n    pub OutputChannels: u32,\n    pub Capabilities: [KSAUDIO_MIX_CAPS; 1],\n}\nimpl Default for KSAUDIO_MIXCAP_TABLE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIO_MIXLEVEL {\n    pub Mute: windows_sys::core::BOOL,\n    pub Level: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSAUDIO_MIX_CAPS {\n    pub Mute: windows_sys::core::BOOL,\n    pub Minimum: i32,\n    pub Maximum: i32,\n    pub Anonymous: KSAUDIO_MIX_CAPS_0,\n}\nimpl Default for KSAUDIO_MIX_CAPS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSAUDIO_MIX_CAPS_0 {\n    pub Reset: i32,\n    pub Resolution: i32,\n}\nimpl Default for KSAUDIO_MIX_CAPS_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSAUDIO_PACKETSIZE_CONSTRAINTS {\n    pub MinPacketPeriodInHns: u32,\n    pub PacketSizeFileAlignment: u32,\n    pub Reserved: u32,\n    pub NumProcessingModeConstraints: u32,\n    pub ProcessingModeConstraints: [KSAUDIO_PACKETSIZE_PROCESSINGMODE_CONSTRAINT; 1],\n}\nimpl Default for KSAUDIO_PACKETSIZE_CONSTRAINTS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSAUDIO_PACKETSIZE_CONSTRAINTS2 {\n    pub MinPacketPeriodInHns: u32,\n    pub PacketSizeFileAlignment: u32,\n    pub MaxPacketSizeInBytes: u32,\n    pub NumProcessingModeConstraints: u32,\n    pub ProcessingModeConstraints: [KSAUDIO_PACKETSIZE_PROCESSINGMODE_CONSTRAINT; 1],\n}\nimpl Default for KSAUDIO_PACKETSIZE_CONSTRAINTS2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIO_PACKETSIZE_PROCESSINGMODE_CONSTRAINT {\n    pub ProcessingMode: windows_sys::core::GUID,\n    pub SamplesPerProcessingPacket: u32,\n    pub ProcessingPacketDurationInHns: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIO_POSITION {\n    pub PlayOffset: u64,\n    pub WriteOffset: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIO_POSITIONEX {\n    pub TimerFrequency: i64,\n    pub TimeStamp1: i64,\n    pub Position: KSAUDIO_POSITION,\n    pub TimeStamp2: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSAUDIO_PRESENTATION_POSITION {\n    pub u64PositionInBlocks: u64,\n    pub u64QPCPosition: u64,\n}\npub const KSAUDIO_QUALITY_ADVANCED: u32 = 3u32;\npub const KSAUDIO_QUALITY_BASIC: u32 = 2u32;\npub const KSAUDIO_QUALITY_PC: u32 = 1u32;\npub const KSAUDIO_QUALITY_WORST: u32 = 0u32;\npub const KSAUDIO_SPEAKER_DIRECTOUT: u32 = 0u32;\npub const KSAUDIO_SPEAKER_GROUND_FRONT_CENTER: u32 = 4u32;\npub const KSAUDIO_SPEAKER_GROUND_FRONT_LEFT: u32 = 1u32;\npub const KSAUDIO_SPEAKER_GROUND_FRONT_RIGHT: u32 = 2u32;\npub const KSAUDIO_SPEAKER_GROUND_REAR_LEFT: u32 = 16u32;\npub const KSAUDIO_SPEAKER_GROUND_REAR_RIGHT: u32 = 32u32;\npub const KSAUDIO_SPEAKER_MONO: u32 = 4u32;\npub const KSAUDIO_SPEAKER_SUPER_WOOFER: u32 = 8u32;\npub const KSAUDIO_SPEAKER_TOP_MIDDLE: u32 = 2048u32;\npub const KSAUDIO_STEREO_SPEAKER_GEOMETRY_HEADPHONE: i32 = -1i32;\npub const KSAUDIO_STEREO_SPEAKER_GEOMETRY_MAX: u32 = 180u32;\npub const KSAUDIO_STEREO_SPEAKER_GEOMETRY_MIN: u32 = 5u32;\npub const KSAUDIO_STEREO_SPEAKER_GEOMETRY_NARROW: u32 = 10u32;\npub const KSAUDIO_STEREO_SPEAKER_GEOMETRY_WIDE: u32 = 20u32;\npub const KSCAMERAPROFILE_BalancedVideoAndPhoto: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6b52b017_42c7_4a21_bfe3_23f009149887);\npub const KSCAMERAPROFILE_CompressedCamera: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0e34cdc1_27ad_437f_abde_02b629f37b44);\npub const KSCAMERAPROFILE_FLAGS_FACEDETECTION: u64 = 8u64;\npub const KSCAMERAPROFILE_FLAGS_PHOTOHDR: u64 = 4u64;\npub const KSCAMERAPROFILE_FLAGS_PREVIEW_RES_MUSTMATCH: u64 = 32u64;\npub const KSCAMERAPROFILE_FLAGS_VARIABLEPHOTOSEQUENCE: u64 = 16u64;\npub const KSCAMERAPROFILE_FLAGS_VIDEOHDR: u64 = 2u64;\npub const KSCAMERAPROFILE_FLAGS_VIDEOSTABLIZATION: u64 = 1u64;\npub const KSCAMERAPROFILE_FaceAuth_Mode: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x81361b22_700b_4546_a2d4_c52e907bfc27);\npub const KSCAMERAPROFILE_HDRWithWCGPhoto: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9bf6f1ff_b555_4625_b326_a46def318fb7);\npub const KSCAMERAPROFILE_HDRWithWCGVideo: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4b27c336_4924_4989_b994_fdaf1dc7cd85);\npub const KSCAMERAPROFILE_HighFrameRate: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x566e6113_8c35_48e7_b89f_d23fdc1219dc);\npub const KSCAMERAPROFILE_HighQualityPhoto: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x32440725_961b_4ca3_b5b2_854e719d9e1b);\npub const KSCAMERAPROFILE_Legacy: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb4894d81_62b7_4eec_8740_80658c4a9d3e);\npub const KSCAMERAPROFILE_PhotoSequence: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x02399d9d_4ee8_49ba_bc07_5ff156531413);\npub const KSCAMERAPROFILE_VariablePhotoSequence: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9ff2cb56_e75a_49b1_a928_9985d5946f87);\npub const KSCAMERAPROFILE_VideoConferencing: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc5444a88_e1bf_4597_b2dd_9e1ead864bb8);\npub const KSCAMERAPROFILE_VideoHDR8: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd4f3f4ec_bdff_4314_b1d4_008e281f74e7);\npub const KSCAMERAPROFILE_VideoRecording: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa0e517e8_8f8c_4f6f_9a57_46fc2f647ec0);\npub const KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_AUTO: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_FNF: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_HDR: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_ULTRALOWLIGHT: u64 = 8u64;\npub const KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_BLUR: u64 = 1u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_CONFIGCAPS {\n    pub Resolution: super::super::Foundation::SIZE,\n    pub MaxFrameRate: KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_CONFIGCAPS_0,\n    pub MaskResolution: super::super::Foundation::SIZE,\n    pub SubType: windows_sys::core::GUID,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_CONFIGCAPS_0 {\n    pub Numerator: i32,\n    pub Denominator: i32,\n}\npub const KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_MASK: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_SHALLOWFOCUS: u64 = 4u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_CAMERAOFFSET {\n    pub PitchAngle: i32,\n    pub YawAngle: i32,\n    pub Flag: u32,\n    pub Reserved: u32,\n}\npub const KSCAMERA_EXTENDEDPROP_CAPS_ASYNCCONTROL: u64 = 9223372036854775808u64;\npub const KSCAMERA_EXTENDEDPROP_CAPS_CANCELLABLE: u64 = 4611686018427387904u64;\npub const KSCAMERA_EXTENDEDPROP_CAPS_MASK: u64 = 18374686479671623680u64;\npub const KSCAMERA_EXTENDEDPROP_CAPS_RESERVED: u64 = 18374686479671623680u64;\npub const KSCAMERA_EXTENDEDPROP_DIGITALWINDOW_AUTOFACEFRAMING: u64 = 1u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_DIGITALWINDOW_CONFIGCAPS {\n    pub ResolutionX: i32,\n    pub ResolutionY: i32,\n    pub PorchTop: i32,\n    pub PorchLeft: i32,\n    pub PorchBottom: i32,\n    pub PorchRight: i32,\n    pub NonUpscalingWindowSize: i32,\n    pub MinWindowSize: i32,\n    pub MaxWindowSize: i32,\n    pub Reserved: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_DIGITALWINDOW_CONFIGCAPSHEADER {\n    pub Size: u32,\n    pub Count: u32,\n}\npub const KSCAMERA_EXTENDEDPROP_DIGITALWINDOW_MANUAL: u64 = 0u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_DIGITALWINDOW_SETTING {\n    pub OriginX: i32,\n    pub OriginY: i32,\n    pub WindowSize: i32,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_EVCOMPENSATION {\n    pub Mode: u32,\n    pub Min: i32,\n    pub Max: i32,\n    pub Value: i32,\n    pub Reserved: u64,\n}\npub const KSCAMERA_EXTENDEDPROP_EVCOMP_FULLSTEP: u64 = 16u64;\npub const KSCAMERA_EXTENDEDPROP_EVCOMP_HALFSTEP: u64 = 8u64;\npub const KSCAMERA_EXTENDEDPROP_EVCOMP_QUARTERSTEP: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_EVCOMP_SIXTHSTEP: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_EVCOMP_THIRDSTEP: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_ON: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_STARE: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_FACEAUTH_MODE_ALTERNATIVE_FRAME_ILLUMINATION: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_FACEAUTH_MODE_BACKGROUND_SUBTRACTION: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_FACEAUTH_MODE_DISABLED: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_FACEDETECTION_BLINK: u64 = 8u64;\npub const KSCAMERA_EXTENDEDPROP_FACEDETECTION_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_FACEDETECTION_ON: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_FACEDETECTION_PHOTO: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_FACEDETECTION_PREVIEW: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_FACEDETECTION_SMILE: u64 = 16u64;\npub const KSCAMERA_EXTENDEDPROP_FACEDETECTION_VIDEO: u64 = 2u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_FIELDOFVIEW {\n    pub NormalizedFocalLengthX: u32,\n    pub NormalizedFocalLengthY: u32,\n    pub Flag: u32,\n    pub Reserved: u32,\n}\npub const KSCAMERA_EXTENDEDPROP_FILTERSCOPE: u32 = 4294967295u32;\npub const KSCAMERA_EXTENDEDPROP_FLAG_CANCELOPERATION: u64 = 9223372036854775808u64;\npub const KSCAMERA_EXTENDEDPROP_FLAG_MASK: u64 = 18374686479671623680u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_ASSISTANT_AUTO: u64 = 256u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_ASSISTANT_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_ASSISTANT_ON: u64 = 128u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_AUTO: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_AUTO_ADJUSTABLEPOWER: u64 = 8u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_MULTIFLASHSUPPORTED: u64 = 64u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_ON: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_ON_ADJUSTABLEPOWER: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_REDEYEREDUCTION: u64 = 16u64;\npub const KSCAMERA_EXTENDEDPROP_FLASH_SINGLEFLASH: u64 = 32u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUSPRIORITY_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUSPRIORITY_ON: u64 = 1u64;\npub type KSCAMERA_EXTENDEDPROP_FOCUSSTATE = i32;\npub const KSCAMERA_EXTENDEDPROP_FOCUSSTATE_FAILED: KSCAMERA_EXTENDEDPROP_FOCUSSTATE = 4i32;\npub const KSCAMERA_EXTENDEDPROP_FOCUSSTATE_FOCUSED: KSCAMERA_EXTENDEDPROP_FOCUSSTATE = 3i32;\npub const KSCAMERA_EXTENDEDPROP_FOCUSSTATE_LOST: KSCAMERA_EXTENDEDPROP_FOCUSSTATE = 1i32;\npub const KSCAMERA_EXTENDEDPROP_FOCUSSTATE_SEARCHING: KSCAMERA_EXTENDEDPROP_FOCUSSTATE = 2i32;\npub const KSCAMERA_EXTENDEDPROP_FOCUSSTATE_UNINITIALIZED: KSCAMERA_EXTENDEDPROP_FOCUSSTATE = 0i32;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_CONTINUOUS: u64 = 256u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_CONTINUOUSLOCK: u64 = 512u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_DISTANCE_HYPERFOCAL: u64 = 33554432u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_DISTANCE_INFINITY: u64 = 16777216u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_DISTANCE_NEAREST: u64 = 67108864u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_DRIVERFALLBACK_OFF: u64 = 2048u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_FULLRANGE: u64 = 262144u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_HYPERFOCAL: u64 = 1048576u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_INFINITY: u64 = 524288u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_MACRO: u64 = 65536u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_NORMAL: u64 = 131072u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_REGIONBASED: u64 = 4096u64;\npub const KSCAMERA_EXTENDEDPROP_FOCUS_UNLOCK: u64 = 1024u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_HEADER {\n    pub Version: u32,\n    pub PinId: u32,\n    pub Size: u32,\n    pub Result: u32,\n    pub Flags: u64,\n    pub Capability: u64,\n}\npub const KSCAMERA_EXTENDEDPROP_HISTOGRAM_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_HISTOGRAM_ON: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALTERNATING_FRAME_ILLUMINATION: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALWAYS_ON: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_IRTORCHMODE_OFF: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_100: u64 = 8u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_12800: u64 = 1024u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_1600: u64 = 128u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_200: u64 = 16u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_25600: u64 = 2048u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_3200: u64 = 256u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_400: u64 = 32u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_50: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_6400: u64 = 512u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_80: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_800: u64 = 64u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_AUTO: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_ISO_MANUAL: u64 = 36028797018963968u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_METADATAINFO {\n    pub BufferAlignment: i32,\n    pub MaxMetadataBufferSize: u32,\n}\npub const KSCAMERA_EXTENDEDPROP_METADATA_ALIGNMENTREQUIRED: u64 = 256u64;\npub const KSCAMERA_EXTENDEDPROP_METADATA_MEMORYTYPE_MASK: u64 = 255u64;\npub const KSCAMERA_EXTENDEDPROP_METADATA_SYSTEMMEMORY: u64 = 1u64;\npub type KSCAMERA_EXTENDEDPROP_MetadataAlignment = i32;\npub const KSCAMERA_EXTENDEDPROP_MetadataAlignment_1024: KSCAMERA_EXTENDEDPROP_MetadataAlignment = 10i32;\npub const KSCAMERA_EXTENDEDPROP_MetadataAlignment_128: KSCAMERA_EXTENDEDPROP_MetadataAlignment = 7i32;\npub const KSCAMERA_EXTENDEDPROP_MetadataAlignment_16: KSCAMERA_EXTENDEDPROP_MetadataAlignment = 4i32;\npub const KSCAMERA_EXTENDEDPROP_MetadataAlignment_2048: KSCAMERA_EXTENDEDPROP_MetadataAlignment = 11i32;\npub const KSCAMERA_EXTENDEDPROP_MetadataAlignment_256: KSCAMERA_EXTENDEDPROP_MetadataAlignment = 8i32;\npub const KSCAMERA_EXTENDEDPROP_MetadataAlignment_32: KSCAMERA_EXTENDEDPROP_MetadataAlignment = 5i32;\npub const KSCAMERA_EXTENDEDPROP_MetadataAlignment_4096: KSCAMERA_EXTENDEDPROP_MetadataAlignment = 12i32;\npub const KSCAMERA_EXTENDEDPROP_MetadataAlignment_512: KSCAMERA_EXTENDEDPROP_MetadataAlignment = 9i32;\npub const KSCAMERA_EXTENDEDPROP_MetadataAlignment_64: KSCAMERA_EXTENDEDPROP_MetadataAlignment = 6i32;\npub const KSCAMERA_EXTENDEDPROP_MetadataAlignment_8192: KSCAMERA_EXTENDEDPROP_MetadataAlignment = 13i32;\npub const KSCAMERA_EXTENDEDPROP_OIS_AUTO: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_OIS_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_OIS_ON: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_OPTIMIZATION_DEFAULT: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_OPTIMIZATION_LATENCY: u64 = 8u64;\npub const KSCAMERA_EXTENDEDPROP_OPTIMIZATION_PHOTO: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_OPTIMIZATION_POWER: u64 = 16u64;\npub const KSCAMERA_EXTENDEDPROP_OPTIMIZATION_QUALITY: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_OPTIMIZATION_VIDEO: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_PHOTOCONFIRMATION_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_PHOTOCONFIRMATION_ON: u64 = 1u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_PHOTOMODE {\n    pub RequestedHistoryFrames: u32,\n    pub MaxHistoryFrames: u32,\n    pub SubMode: u32,\n    pub Reserved: u32,\n}\npub const KSCAMERA_EXTENDEDPROP_PHOTOMODE_NORMAL: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_PHOTOMODE_SEQUENCE: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_PHOTOMODE_SEQUENCE_SUB_NONE: u32 = 0u32;\npub const KSCAMERA_EXTENDEDPROP_PHOTOMODE_SEQUENCE_SUB_VARIABLE: u32 = 1u32;\npub const KSCAMERA_EXTENDEDPROP_PHOTOTHUMBNAIL_16X: u64 = 8u64;\npub const KSCAMERA_EXTENDEDPROP_PHOTOTHUMBNAIL_2X: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_PHOTOTHUMBNAIL_4X: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_PHOTOTHUMBNAIL_8X: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_PHOTOTHUMBNAIL_DISABLE: u64 = 0u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_PROFILE {\n    pub ProfileId: windows_sys::core::GUID,\n    pub Index: u32,\n    pub Reserved: u32,\n}\npub const KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_DYNAMIC: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_ON: u64 = 1u64;\npub type KSCAMERA_EXTENDEDPROP_ROITYPE = i32;\npub const KSCAMERA_EXTENDEDPROP_ROITYPE_FACE: KSCAMERA_EXTENDEDPROP_ROITYPE = 1i32;\npub const KSCAMERA_EXTENDEDPROP_ROITYPE_UNKNOWN: KSCAMERA_EXTENDEDPROP_ROITYPE = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_ROI_CONFIGCAPS {\n    pub ControlId: u32,\n    pub MaxNumberOfROIs: u32,\n    pub Capability: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_ROI_CONFIGCAPSHEADER {\n    pub Size: u32,\n    pub ConfigCapCount: u32,\n    pub Reserved: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_ROI_EXPOSURE {\n    pub ROIInfo: KSCAMERA_EXTENDEDPROP_ROI_INFO,\n    pub Reserved: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_ROI_FOCUS {\n    pub ROIInfo: KSCAMERA_EXTENDEDPROP_ROI_INFO,\n    pub Reserved: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_ROI_INFO {\n    pub Region: super::super::Foundation::RECT,\n    pub Flags: u64,\n    pub Weight: i32,\n    pub RegionOfInterestType: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_ROI_ISPCONTROL {\n    pub ControlId: u32,\n    pub ROICount: u32,\n    pub Result: u32,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_ROI_ISPCONTROLHEADER {\n    pub Size: u32,\n    pub ControlCount: u32,\n    pub Reserved: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_EXTENDEDPROP_ROI_WHITEBALANCE {\n    pub ROIInfo: KSCAMERA_EXTENDEDPROP_ROI_INFO,\n    pub Reserved: u64,\n}\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_AUTO: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_BACKLIT: u64 = 1024u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_BEACH: u64 = 32u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_CANDLELIGHT: u64 = 128u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_LANDSCAPE: u64 = 256u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_MACRO: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_MANUAL: u64 = 36028797018963968u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_NIGHT: u64 = 16u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_NIGHTPORTRAIT: u64 = 512u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_PORTRAIT: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_SNOW: u64 = 8u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_SPORT: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_SCENEMODE_SUNSET: u64 = 64u64;\npub const KSCAMERA_EXTENDEDPROP_SECUREMODE_DISABLED: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_SECUREMODE_ENABLED: u64 = 2u64;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSCAMERA_EXTENDEDPROP_VALUE {\n    pub Value: KSCAMERA_EXTENDEDPROP_VALUE_0,\n}\nimpl Default for KSCAMERA_EXTENDEDPROP_VALUE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSCAMERA_EXTENDEDPROP_VALUE_0 {\n    pub dbl: f64,\n    pub ull: u64,\n    pub ul: u32,\n    pub ratio: u64,\n    pub l: i32,\n    pub ll: i64,\n}\nimpl Default for KSCAMERA_EXTENDEDPROP_VALUE_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSCAMERA_EXTENDEDPROP_VFR_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_VFR_ON: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOHDR_AUTO: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOHDR_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOHDR_ON: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_AUTO: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_MANUAL: u64 = 2u64;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING {\n    pub Mode: u32,\n    pub Min: i32,\n    pub Max: i32,\n    pub Step: i32,\n    pub VideoProc: KSCAMERA_EXTENDEDPROP_VALUE,\n    pub Reserved: u64,\n}\nimpl Default for KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSCAMERA_EXTENDEDPROP_VIDEOSTABILIZATION_AUTO: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOSTABILIZATION_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOSTABILIZATION_ON: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_AUTO: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_OFF: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_ON: u64 = 4u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOTORCH_OFF: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOTORCH_ON: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_VIDEOTORCH_ON_ADJUSTABLEPOWER: u64 = 2u64;\npub const KSCAMERA_EXTENDEDPROP_WARMSTART_MODE_DISABLED: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_WARMSTART_MODE_ENABLED: u64 = 1u64;\npub type KSCAMERA_EXTENDEDPROP_WBPRESET = i32;\npub const KSCAMERA_EXTENDEDPROP_WBPRESET_CANDLELIGHT: KSCAMERA_EXTENDEDPROP_WBPRESET = 6i32;\npub const KSCAMERA_EXTENDEDPROP_WBPRESET_CLOUDY: KSCAMERA_EXTENDEDPROP_WBPRESET = 1i32;\npub const KSCAMERA_EXTENDEDPROP_WBPRESET_DAYLIGHT: KSCAMERA_EXTENDEDPROP_WBPRESET = 2i32;\npub const KSCAMERA_EXTENDEDPROP_WBPRESET_FLASH: KSCAMERA_EXTENDEDPROP_WBPRESET = 3i32;\npub const KSCAMERA_EXTENDEDPROP_WBPRESET_FLUORESCENT: KSCAMERA_EXTENDEDPROP_WBPRESET = 4i32;\npub const KSCAMERA_EXTENDEDPROP_WBPRESET_TUNGSTEN: KSCAMERA_EXTENDEDPROP_WBPRESET = 5i32;\npub type KSCAMERA_EXTENDEDPROP_WHITEBALANCE_MODE = i32;\npub const KSCAMERA_EXTENDEDPROP_WHITEBALANCE_PRESET: KSCAMERA_EXTENDEDPROP_WHITEBALANCE_MODE = 2i32;\npub const KSCAMERA_EXTENDEDPROP_WHITEBALANCE_TEMPERATURE: KSCAMERA_EXTENDEDPROP_WHITEBALANCE_MODE = 1i32;\npub const KSCAMERA_EXTENDEDPROP_ZOOM_DEFAULT: u64 = 0u64;\npub const KSCAMERA_EXTENDEDPROP_ZOOM_DIRECT: u64 = 1u64;\npub const KSCAMERA_EXTENDEDPROP_ZOOM_SMOOTH: u64 = 2u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_MAXVIDEOFPS_FORPHOTORES {\n    pub PhotoResWidth: u32,\n    pub PhotoResHeight: u32,\n    pub PreviewFPSNum: u32,\n    pub PreviewFPSDenom: u32,\n    pub CaptureFPSNum: u32,\n    pub CaptureFPSDenom: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSCAMERA_METADATA_BACKGROUNDSEGMENTATIONMASK {\n    pub Header: KSCAMERA_METADATA_ITEMHEADER,\n    pub MaskCoverageBoundingBox: super::super::Foundation::RECT,\n    pub MaskResolution: super::super::Foundation::SIZE,\n    pub ForegroundBoundingBox: super::super::Foundation::RECT,\n    pub MaskData: [u8; 1],\n}\nimpl Default for KSCAMERA_METADATA_BACKGROUNDSEGMENTATIONMASK {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_METADATA_CAPTURESTATS {\n    pub Header: KSCAMERA_METADATA_ITEMHEADER,\n    pub Flags: u32,\n    pub Reserved: u32,\n    pub ExposureTime: u64,\n    pub ExposureCompensationFlags: u64,\n    pub ExposureCompensationValue: i32,\n    pub IsoSpeed: u32,\n    pub FocusState: u32,\n    pub LensPosition: u32,\n    pub WhiteBalance: u32,\n    pub Flash: u32,\n    pub FlashPower: u32,\n    pub ZoomFactor: u32,\n    pub SceneMode: u64,\n    pub SensorFramerate: u64,\n}\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_EXPOSURECOMPENSATION: u32 = 2u32;\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_EXPOSURETIME: u32 = 1u32;\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_FLASH: u32 = 64u32;\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_FLASHPOWER: u32 = 128u32;\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_FOCUSSTATE: u32 = 8u32;\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_ISOSPEED: u32 = 4u32;\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_LENSPOSITION: u32 = 16u32;\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_SCENEMODE: u32 = 512u32;\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_SENSORFRAMERATE: u32 = 1024u32;\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_WHITEBALANCE: u32 = 32u32;\npub const KSCAMERA_METADATA_CAPTURESTATS_FLAG_ZOOMFACTOR: u32 = 256u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_METADATA_DIGITALWINDOW {\n    pub Header: KSCAMERA_METADATA_ITEMHEADER,\n    pub Window: KSCAMERA_EXTENDEDPROP_DIGITALWINDOW_SETTING,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_METADATA_FRAMEILLUMINATION {\n    pub Header: KSCAMERA_METADATA_ITEMHEADER,\n    pub Flags: u32,\n    pub Reserved: u32,\n}\npub const KSCAMERA_METADATA_FRAMEILLUMINATION_FLAG_ON: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_METADATA_ITEMHEADER {\n    pub MetadataId: u32,\n    pub Size: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_METADATA_PHOTOCONFIRMATION {\n    pub Header: KSCAMERA_METADATA_ITEMHEADER,\n    pub PhotoConfirmationIndex: u32,\n    pub Reserved: u32,\n}\npub type KSCAMERA_MetadataId = i32;\npub const KSCAMERA_PERFRAMESETTING_AUTO: u64 = 4294967296u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_PERFRAMESETTING_CAP_HEADER {\n    pub Size: u32,\n    pub ItemCount: u32,\n    pub Flags: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_PERFRAMESETTING_CAP_ITEM_HEADER {\n    pub Size: u32,\n    pub Type: u32,\n    pub Flags: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_PERFRAMESETTING_CUSTOM_ITEM {\n    pub Size: u32,\n    pub Reserved: u32,\n    pub Id: windows_sys::core::GUID,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_PERFRAMESETTING_FRAME_HEADER {\n    pub Size: u32,\n    pub Id: u32,\n    pub ItemCount: u32,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_PERFRAMESETTING_HEADER {\n    pub Size: u32,\n    pub FrameCount: u32,\n    pub Id: windows_sys::core::GUID,\n    pub Flags: u64,\n    pub LoopCount: u32,\n    pub Reserved: u32,\n}\npub const KSCAMERA_PERFRAMESETTING_ITEM_CUSTOM: KSCAMERA_PERFRAMESETTING_ITEM_TYPE = 7i32;\npub const KSCAMERA_PERFRAMESETTING_ITEM_EXPOSURE_COMPENSATION: KSCAMERA_PERFRAMESETTING_ITEM_TYPE = 3i32;\npub const KSCAMERA_PERFRAMESETTING_ITEM_EXPOSURE_TIME: KSCAMERA_PERFRAMESETTING_ITEM_TYPE = 1i32;\npub const KSCAMERA_PERFRAMESETTING_ITEM_FLASH: KSCAMERA_PERFRAMESETTING_ITEM_TYPE = 2i32;\npub const KSCAMERA_PERFRAMESETTING_ITEM_FOCUS: KSCAMERA_PERFRAMESETTING_ITEM_TYPE = 5i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_PERFRAMESETTING_ITEM_HEADER {\n    pub Size: u32,\n    pub Type: u32,\n    pub Flags: u64,\n}\npub const KSCAMERA_PERFRAMESETTING_ITEM_ISO: KSCAMERA_PERFRAMESETTING_ITEM_TYPE = 4i32;\npub const KSCAMERA_PERFRAMESETTING_ITEM_PHOTOCONFIRMATION: KSCAMERA_PERFRAMESETTING_ITEM_TYPE = 6i32;\npub type KSCAMERA_PERFRAMESETTING_ITEM_TYPE = i32;\npub const KSCAMERA_PERFRAMESETTING_MANUAL: u64 = 8589934592u64;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSCAMERA_PROFILE_CONCURRENCYINFO {\n    pub ReferenceGuid: windows_sys::core::GUID,\n    pub Reserved: u32,\n    pub ProfileCount: u32,\n    pub Profiles: *mut KSCAMERA_PROFILE_INFO,\n}\nimpl Default for KSCAMERA_PROFILE_CONCURRENCYINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSCAMERA_PROFILE_INFO {\n    pub ProfileId: windows_sys::core::GUID,\n    pub Index: u32,\n    pub PinCount: u32,\n    pub Pins: *mut KSCAMERA_PROFILE_PININFO,\n}\nimpl Default for KSCAMERA_PROFILE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_PROFILE_MEDIAINFO {\n    pub Resolution: KSCAMERA_PROFILE_MEDIAINFO_0,\n    pub MaxFrameRate: KSCAMERA_PROFILE_MEDIAINFO_1,\n    pub Flags: u64,\n    pub Data0: u32,\n    pub Data1: u32,\n    pub Data2: u32,\n    pub Data3: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_PROFILE_MEDIAINFO_1 {\n    pub Numerator: u32,\n    pub Denominator: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_PROFILE_MEDIAINFO_0 {\n    pub X: u32,\n    pub Y: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSCAMERA_PROFILE_PININFO {\n    pub PinCategory: windows_sys::core::GUID,\n    pub Anonymous: KSCAMERA_PROFILE_PININFO_0,\n    pub MediaInfoCount: u32,\n    pub MediaInfos: *mut KSCAMERA_PROFILE_MEDIAINFO,\n}\nimpl Default for KSCAMERA_PROFILE_PININFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSCAMERA_PROFILE_PININFO_0 {\n    pub Anonymous: KSCAMERA_PROFILE_PININFO_0_0,\n    pub Reserved: u32,\n}\nimpl Default for KSCAMERA_PROFILE_PININFO_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCAMERA_PROFILE_PININFO_0_0 {\n    pub PinIndex: u16,\n    pub ProfileSensorType: u16,\n}\npub const KSCATEGORY_ACOUSTIC_ECHO_CANCEL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbf963d80_c559_11d0_8a2b_00a0c9255ac1);\npub const KSCATEGORY_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6994ad04_93ef_11d0_a3cc_00a0c9223196);\npub const KSCATEGORY_BRIDGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x085aff00_62ce_11cf_a5d6_28db04c10000);\npub const KSCATEGORY_CAPTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x65e8773d_8f56_11d0_a3b9_00a0c9223196);\npub const KSCATEGORY_CLOCK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53172480_4791_11d0_a5d6_28db04c10000);\npub const KSCATEGORY_COMMUNICATIONSTRANSFORM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xcf1dda2c_9743_11d0_a3ee_00a0c9223196);\npub const KSCATEGORY_CROSSBAR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa799a801_a46d_11d0_a18c_00a02401dcd4);\npub const KSCATEGORY_DATACOMPRESSOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1e84c900_7e70_11d0_a5d6_28db04c10000);\npub const KSCATEGORY_DATADECOMPRESSOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2721ae20_7e70_11d0_a5d6_28db04c10000);\npub const KSCATEGORY_DATATRANSFORM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2eb07ea0_7e70_11d0_a5d6_28db04c10000);\npub const KSCATEGORY_ENCODER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x19689bf6_c384_48fd_ad51_90e58c79f70b);\npub const KSCATEGORY_ESCALANTE_PLATFORM_DRIVER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x74f3aea8_9768_11d1_8e07_00a0c95ec22e);\npub const KSCATEGORY_FILESYSTEM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x760fed5e_9357_11d0_a3cc_00a0c9223196);\npub const KSCATEGORY_INTERFACETRANSFORM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xcf1dda2d_9743_11d0_a3ee_00a0c9223196);\npub const KSCATEGORY_MEDIUMTRANSFORM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xcf1dda2e_9743_11d0_a3ee_00a0c9223196);\npub const KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x830a44f2_a32d_476b_be97_42845673b35a);\npub const KSCATEGORY_MIXER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xad809c00_7b88_11d0_a5d6_28db04c10000);\npub const KSCATEGORY_MULTIPLEXER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7a5de1d3_01a1_452c_b481_4fa2b96271e8);\npub const KSCATEGORY_NETWORK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x67c9cc3c_69c4_11d2_8759_00a0c9223196);\npub const KSCATEGORY_NETWORK_CAMERA: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb8238652_b500_41eb_b4f3_4234f7f5ae99);\npub const KSCATEGORY_PROXY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x97ebaaca_95bd_11d0_a3ea_00a0c9223196);\npub const KSCATEGORY_QUALITY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x97ebaacb_95bd_11d0_a3ea_00a0c9223196);\npub const KSCATEGORY_REALTIME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xeb115ffc_10c8_4964_831d_6dcb02e6f23f);\npub const KSCATEGORY_RENDER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x65e8773e_8f56_11d0_a3b9_00a0c9223196);\npub const KSCATEGORY_SENSOR_CAMERA: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x24e552d7_6523_47f7_a647_d3465bf1f5ca);\npub const KSCATEGORY_SENSOR_GROUP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x669c7214_0a88_4311_a7f3_4e79820e33bd);\npub const KSCATEGORY_SPLITTER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0a4252a0_7e70_11d0_a5d6_28db04c10000);\npub const KSCATEGORY_TEXT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6994ad06_93ef_11d0_a3cc_00a0c9223196);\npub const KSCATEGORY_TOPOLOGY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdda54a40_1e4c_11d1_a050_405705c10000);\npub const KSCATEGORY_TVAUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa799a802_a46d_11d0_a18c_00a02401dcd4);\npub const KSCATEGORY_TVTUNER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa799a800_a46d_11d0_a18c_00a02401dcd4);\npub const KSCATEGORY_VBICODEC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x07dad660_22f1_11d1_a9f4_00c04fbbde8f);\npub const KSCATEGORY_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6994ad05_93ef_11d0_a3cc_00a0c9223196);\npub const KSCATEGORY_VIDEO_CAMERA: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe5323777_f976_4f5b_9b55_b94699c46e44);\npub const KSCATEGORY_VIRTUAL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3503eac4_1f26_11d1_8ab0_00a0c9223196);\npub const KSCATEGORY_VPMUX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa799a803_a46d_11d0_a18c_00a02401dcd4);\npub const KSCATEGORY_WDMAUD_USE_PIN_NAME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x47a4fa20_a251_11d1_a050_0000f8004788);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCLOCK_CREATE {\n    pub CreateFlags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCOMPONENTID {\n    pub Manufacturer: windows_sys::core::GUID,\n    pub Product: windows_sys::core::GUID,\n    pub Component: windows_sys::core::GUID,\n    pub Name: windows_sys::core::GUID,\n    pub Version: u32,\n    pub Revision: u32,\n}\npub const KSCOMPONENTID_USBAUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8f1275f0_26e9_4264_ba4d_39fff01d94aa);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSCORRELATED_TIME {\n    pub Time: i64,\n    pub SystemTime: i64,\n}\npub const KSCREATE_ITEM_FREEONSTOP: u32 = 8u32;\npub const KSCREATE_ITEM_NOPARAMETERS: u32 = 4u32;\npub const KSCREATE_ITEM_SECURITYCHANGED: u32 = 1u32;\npub const KSCREATE_ITEM_WILDCARD: u32 = 2u32;\npub const KSCameraProfileSensorType_Custom: u32 = 128u32;\npub const KSCameraProfileSensorType_Depth: u32 = 4u32;\npub const KSCameraProfileSensorType_ImageSegmentation: u32 = 16u32;\npub const KSCameraProfileSensorType_Infrared: u32 = 2u32;\npub const KSCameraProfileSensorType_PoseTracking: u32 = 8u32;\npub const KSCameraProfileSensorType_RGB: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSDATAFORMAT {\n    pub Anonymous: KSDATAFORMAT_0,\n    pub Alignment: i64,\n}\nimpl Default for KSDATAFORMAT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSDATAFORMAT_0 {\n    pub FormatSize: u32,\n    pub Flags: u32,\n    pub SampleSize: u32,\n    pub Reserved: u32,\n    pub MajorFormat: windows_sys::core::GUID,\n    pub SubFormat: windows_sys::core::GUID,\n    pub Specifier: windows_sys::core::GUID,\n}\npub const KSDATAFORMAT_BIT_ATTRIBUTES: u32 = 1u32;\npub const KSDATAFORMAT_BIT_TEMPORAL_COMPRESSION: u32 = 0u32;\npub const KSDATAFORMAT_SPECIFIER_AC3_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d80e4_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SPECIFIER_ANALOGVIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0482dde0_7817_11cf_8a03_00aa006ecb65);\npub const KSDATAFORMAT_SPECIFIER_DIALECT_AC3_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b35_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b32_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b31_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b34_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b33_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_SPECIFIER_DSOUND: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x518590a2_a184_11d0_8522_00c04fd9baf3);\npub const KSDATAFORMAT_SPECIFIER_FILEHANDLE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x65e8773c_8f56_11d0_a3b9_00a0c9223196);\npub const KSDATAFORMAT_SPECIFIER_FILENAME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xaa797b40_e974_11cf_a5d6_28db04c10000);\npub const KSDATAFORMAT_SPECIFIER_H264_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2017be05_6629_4248_aaed_7e1a47bc9b9c);\npub const KSDATAFORMAT_SPECIFIER_IMAGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x692fa379_d3e8_4651_b5b4_0b94b013eeaf);\npub const KSDATAFORMAT_SPECIFIER_JPEG_IMAGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x692fa379_d3e8_4651_b5b4_0b94b013eeaf);\npub const KSDATAFORMAT_SPECIFIER_LPCM_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d80e6_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SPECIFIER_MPEG1_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x05589f82_c356_11ce_bf01_00aa0055595a);\npub const KSDATAFORMAT_SPECIFIER_MPEG2_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d80e5_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SPECIFIER_MPEG2_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d80e3_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SPECIFIER_NONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0f6417d6_c318_11d0_a43f_00a0c9223196);\npub const KSDATAFORMAT_SPECIFIER_VBI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf72a76e0_eb0a_11d0_ace4_0000c0cc16ba);\npub const KSDATAFORMAT_SPECIFIER_VC_ID: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xad98d184_aac3_11d0_a41c_00a0c9223196);\npub const KSDATAFORMAT_SPECIFIER_VIDEOINFO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x05589f80_c356_11ce_bf01_00aa0055595a);\npub const KSDATAFORMAT_SPECIFIER_VIDEOINFO2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf72a76a0_eb0a_11d0_ace4_0000c0cc16ba);\npub const KSDATAFORMAT_SPECIFIER_WAVEFORMATEX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x05589f81_c356_11ce_bf01_00aa0055595a);\npub const KSDATAFORMAT_SUBTYPE_AC3_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d802c_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SUBTYPE_ANALOG: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6dba3190_67bd_11cf_a0f7_0020afd156e4);\npub const KSDATAFORMAT_SUBTYPE_CC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x33214cc1_011f_11d2_b4b1_00a0d102cfbe);\npub const KSDATAFORMAT_SUBTYPE_D16: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000050_0004_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_DSS_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa0af4f82_e163_11d0_bad9_00609744111a);\npub const KSDATAFORMAT_SUBTYPE_DSS_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa0af4f81_e163_11d0_bad9_00609744111a);\npub const KSDATAFORMAT_SUBTYPE_DTS_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d8033_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_AAC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000006_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_ATRAC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000008_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000092_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000000a_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS_ATMOS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000010a_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT20: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000010c_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT21: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000030c_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000000c_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000000d_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DTS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000008_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DTSX_E1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000010b_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DTSX_E2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000030b_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000000b_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_MPEG1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000003_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_MPEG2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000004_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_MPEG3: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000005_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_ONE_BIT_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000009_0cea_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IEC61937_WMA_PRO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000164_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_IMAGE_RGB32: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000016_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_JPEG: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x19e4a5aa_5662_4fc5_a0c0_1758028e1057);\npub const KSDATAFORMAT_SUBTYPE_L16: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000051_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_L16_CUSTOM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000051_8000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_L16_IR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000051_0002_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_L8: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000032_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_L8_CUSTOM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000032_8000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_L8_IR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000032_0002_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_LPCM_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d8032_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SUBTYPE_Line21_BytePair: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6e8d4a22_310c_11d0_b79a_00aa003767a7);\npub const KSDATAFORMAT_SUBTYPE_Line21_GOPPacket: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6e8d4a23_310c_11d0_b79a_00aa003767a7);\npub const KSDATAFORMAT_SUBTYPE_MIDI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1d262760_e957_11cf_a5d6_28db04c10000);\npub const KSDATAFORMAT_SUBTYPE_MIDI_BUS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2ca15fa0_6cfe_11cf_a5d6_28db04c10000);\npub const KSDATAFORMAT_SUBTYPE_MJPG_CUSTOM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x47504a4d_8000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_MJPG_DEPTH: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x47504a4d_0004_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_MJPG_IR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x47504a4d_0002_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_MPEG1Packet: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb80_524f_11ce_9f53_0020af0ba770);\npub const KSDATAFORMAT_SUBTYPE_MPEG1Payload: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb81_524f_11ce_9f53_0020af0ba770);\npub const KSDATAFORMAT_SUBTYPE_MPEG1Video: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb86_524f_11ce_9f53_0020af0ba770);\npub const KSDATAFORMAT_SUBTYPE_MPEG2_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d802b_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SUBTYPE_MPEG2_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d8026_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SUBTYPE_MPEGLAYER3: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000055_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_MPEG_HEAAC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00001610_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_NABTS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf72a76e2_eb0a_11d0_ace4_0000c0cc16ba);\npub const KSDATAFORMAT_SUBTYPE_NABTS_FEC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe757bca1_39ac_11d1_a9f5_00c04fbbde8f);\npub const KSDATAFORMAT_SUBTYPE_NONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb8e_524f_11ce_9f53_0020af0ba770);\npub const KSDATAFORMAT_SUBTYPE_OVERLAY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb7f_524f_11ce_9f53_0020af0ba770);\npub const KSDATAFORMAT_SUBTYPE_PCM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000001_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_RAW8: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xca20d9a0_3e3e_11d1_9bf9_00c04fbbdebf);\npub const KSDATAFORMAT_SUBTYPE_RIFF: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4995daee_9ee6_11d0_a40e_00a0c9223196);\npub const KSDATAFORMAT_SUBTYPE_RIFFMIDI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4995daf0_9ee6_11d0_a40e_00a0c9223196);\npub const KSDATAFORMAT_SUBTYPE_RIFFWAVE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb8b_524f_11ce_9f53_0020af0ba770);\npub const KSDATAFORMAT_SUBTYPE_SDDS_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d8034_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SUBTYPE_STANDARD_AC3_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b25_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b22_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b21_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b24_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b23_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_SUBTYPE_SUBPICTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d802d_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_SUBTYPE_TELETEXT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf72a76e3_eb0a_11d0_ace4_0000c0cc16ba);\npub const KSDATAFORMAT_SUBTYPE_VPVBI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x5a9b6a41_1a22_11d1_bad9_00609744111a);\npub const KSDATAFORMAT_SUBTYPE_VPVideo: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x5a9b6a40_1a22_11d1_bad9_00609744111a);\npub const KSDATAFORMAT_SUBTYPE_WAVEFORMATEX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000000_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_WMAUDIO2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000161_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_WMAUDIO3: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000162_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_SUBTYPE_WMAUDIO_LOSSLESS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000163_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_TYPE_ANALOGAUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0482dee1_7817_11cf_8a03_00aa006ecb65);\npub const KSDATAFORMAT_TYPE_ANALOGVIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0482dde1_7817_11cf_8a03_00aa006ecb65);\npub const KSDATAFORMAT_TYPE_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x73647561_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_TYPE_AUXLine21Data: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x670aea80_3a82_11d0_b79b_00aa003767a7);\npub const KSDATAFORMAT_TYPE_DVD_ENCRYPTED_PACK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xed0b916a_044d_11d1_aa78_00c04fc31d60);\npub const KSDATAFORMAT_TYPE_IMAGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x72178c23_e45b_11d5_bc2a_00b0d0f3f4ab);\npub const KSDATAFORMAT_TYPE_MIDI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7364696d_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_TYPE_MPEG2_PES: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d8020_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_TYPE_MPEG2_PROGRAM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d8022_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_TYPE_MPEG2_TRANSPORT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d8023_db46_11cf_b4d1_00805f6cbbea);\npub const KSDATAFORMAT_TYPE_MUSIC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe725d360_62cc_11cf_a5d6_28db04c10000);\npub const KSDATAFORMAT_TYPE_NABTS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe757bca0_39ac_11d1_a9f5_00c04fbbde8f);\npub const KSDATAFORMAT_TYPE_STANDARD_ELEMENTARY_STREAM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b11_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_TYPE_STANDARD_PACK_HEADER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b13_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_TYPE_STANDARD_PES_PACKET: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x36523b12_8ee5_11d1_8ca3_0060b057664a);\npub const KSDATAFORMAT_TYPE_STREAM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb83_524f_11ce_9f53_0020af0ba770);\npub const KSDATAFORMAT_TYPE_TEXT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x73747874_0000_0010_8000_00aa00389b71);\npub const KSDATAFORMAT_TYPE_VBI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf72a76e1_eb0a_11d0_ace4_0000c0cc16ba);\npub const KSDATAFORMAT_TYPE_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x73646976_0000_0010_8000_00aa00389b71);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSDATARANGE_AUDIO {\n    pub DataRange: KSDATAFORMAT,\n    pub MaximumChannels: u32,\n    pub MinimumBitsPerSample: u32,\n    pub MaximumBitsPerSample: u32,\n    pub MinimumSampleFrequency: u32,\n    pub MaximumSampleFrequency: u32,\n}\nimpl Default for KSDATARANGE_AUDIO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSDATARANGE_BIT_ATTRIBUTES: u32 = 1u32;\npub const KSDATARANGE_BIT_REQUIRED_ATTRIBUTES: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSDATARANGE_MUSIC {\n    pub DataRange: KSDATAFORMAT,\n    pub Technology: windows_sys::core::GUID,\n    pub Channels: u32,\n    pub Notes: u32,\n    pub ChannelMask: u32,\n}\nimpl Default for KSDATARANGE_MUSIC {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSDEGRADESETID_Standard: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9f564180_704c_11d0_a5d6_28db04c10000);\npub type KSDEGRADE_STANDARD = i32;\npub const KSDEGRADE_STANDARD_COMPUTATION: KSDEGRADE_STANDARD = 2i32;\npub const KSDEGRADE_STANDARD_QUALITY: KSDEGRADE_STANDARD = 1i32;\npub const KSDEGRADE_STANDARD_SAMPLE: KSDEGRADE_STANDARD = 0i32;\npub const KSDEGRADE_STANDARD_SKIP: KSDEGRADE_STANDARD = 3i32;\npub const KSDEVICE_DESCRIPTOR_VERSION: u32 = 256u32;\npub const KSDEVICE_DESCRIPTOR_VERSION_2: u32 = 272u32;\npub const KSDEVICE_FLAG_ENABLE_QUERYINTERFACE: u32 = 4u32;\npub const KSDEVICE_FLAG_ENABLE_REMOTE_WAKEUP: u32 = 1u32;\npub const KSDEVICE_FLAG_LOWPOWER_PASSTHROUGH: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSDEVICE_PROFILE_INFO {\n    pub Type: u32,\n    pub Size: u32,\n    pub Anonymous: KSDEVICE_PROFILE_INFO_0,\n}\nimpl Default for KSDEVICE_PROFILE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSDEVICE_PROFILE_INFO_0 {\n    pub Camera: KSDEVICE_PROFILE_INFO_0_0,\n}\nimpl Default for KSDEVICE_PROFILE_INFO_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSDEVICE_PROFILE_INFO_0_0 {\n    pub Info: KSCAMERA_PROFILE_INFO,\n    pub Reserved: u32,\n    pub ConcurrencyCount: u32,\n    pub Concurrency: *mut KSCAMERA_PROFILE_CONCURRENCYINFO,\n}\nimpl Default for KSDEVICE_PROFILE_INFO_0_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSDEVICE_PROFILE_TYPE_CAMERA: u32 = 1u32;\npub const KSDEVICE_PROFILE_TYPE_UNKNOWN: u32 = 0u32;\npub type KSDEVICE_THERMAL_STATE = i32;\npub const KSDEVICE_THERMAL_STATE_HIGH: KSDEVICE_THERMAL_STATE = 1i32;\npub const KSDEVICE_THERMAL_STATE_LOW: KSDEVICE_THERMAL_STATE = 0i32;\npub const KSDISPATCH_FASTIO: u32 = 2147483648u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSDISPLAYCHANGE {\n    pub PelsWidth: u32,\n    pub PelsHeight: u32,\n    pub BitsPerPel: u32,\n    pub DeviceID: [u16; 1],\n}\nimpl Default for KSDISPLAYCHANGE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSDS3D_BUFFER_ALL {\n    pub Position: DS3DVECTOR,\n    pub Velocity: DS3DVECTOR,\n    pub InsideConeAngle: u32,\n    pub OutsideConeAngle: u32,\n    pub ConeOrientation: DS3DVECTOR,\n    pub ConeOutsideVolume: i32,\n    pub MinDistance: f32,\n    pub MaxDistance: f32,\n    pub Mode: u32,\n}\nimpl Default for KSDS3D_BUFFER_ALL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSDS3D_BUFFER_CONE_ANGLES {\n    pub InsideConeAngle: u32,\n    pub OutsideConeAngle: u32,\n}\npub const KSDS3D_COEFF_COUNT: KSDS3D_HRTF_COEFF_FORMAT = 2i32;\npub const KSDS3D_FILTER_METHOD_COUNT: KSDS3D_HRTF_FILTER_METHOD = 2i32;\npub const KSDS3D_FILTER_QUALITY_COUNT: KSDS3D_HRTF_FILTER_QUALITY = 2i32;\npub type KSDS3D_HRTF_COEFF_FORMAT = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSDS3D_HRTF_FILTER_FORMAT_MSG {\n    pub FilterMethod: KSDS3D_HRTF_FILTER_METHOD,\n    pub CoeffFormat: KSDS3D_HRTF_COEFF_FORMAT,\n    pub Version: KSDS3D_HRTF_FILTER_VERSION,\n    pub Reserved: u32,\n}\npub type KSDS3D_HRTF_FILTER_METHOD = i32;\npub type KSDS3D_HRTF_FILTER_QUALITY = i32;\npub type KSDS3D_HRTF_FILTER_VERSION = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSDS3D_HRTF_INIT_MSG {\n    pub Size: u32,\n    pub Quality: KSDS3D_HRTF_FILTER_QUALITY,\n    pub SampleRate: f32,\n    pub MaxFilterSize: u32,\n    pub FilterTransientMuteLength: u32,\n    pub FilterOverlapBufferLength: u32,\n    pub OutputOverlapBufferLength: u32,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSDS3D_HRTF_PARAMS_MSG {\n    pub Size: u32,\n    pub Enabled: u32,\n    pub SwapChannels: windows_sys::core::BOOL,\n    pub ZeroAzimuth: windows_sys::core::BOOL,\n    pub CrossFadeOutput: windows_sys::core::BOOL,\n    pub FilterSize: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSDS3D_ITD_PARAMS {\n    pub Channel: i32,\n    pub VolSmoothScale: f32,\n    pub TotalDryAttenuation: f32,\n    pub TotalWetAttenuation: f32,\n    pub SmoothFrequency: i32,\n    pub Delay: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSDS3D_ITD_PARAMS_MSG {\n    pub Enabled: u32,\n    pub LeftParams: KSDS3D_ITD_PARAMS,\n    pub RightParams: KSDS3D_ITD_PARAMS,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSDS3D_LISTENER_ALL {\n    pub Position: DS3DVECTOR,\n    pub Velocity: DS3DVECTOR,\n    pub OrientFront: DS3DVECTOR,\n    pub OrientTop: DS3DVECTOR,\n    pub DistanceFactor: f32,\n    pub RolloffFactor: f32,\n    pub DopplerFactor: f32,\n}\nimpl Default for KSDS3D_LISTENER_ALL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSDS3D_LISTENER_ORIENTATION {\n    pub Front: DS3DVECTOR,\n    pub Top: DS3DVECTOR,\n}\nimpl Default for KSDS3D_LISTENER_ORIENTATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSDSOUND_3D_MODE_DISABLE: u32 = 2u32;\npub const KSDSOUND_3D_MODE_HEADRELATIVE: u32 = 1u32;\npub const KSDSOUND_3D_MODE_NORMAL: u32 = 0u32;\npub const KSDSOUND_BUFFER_CTRL_3D: u32 = 1u32;\npub const KSDSOUND_BUFFER_CTRL_FREQUENCY: u32 = 2u32;\npub const KSDSOUND_BUFFER_CTRL_HRTF_3D: u32 = 1073741824u32;\npub const KSDSOUND_BUFFER_CTRL_PAN: u32 = 4u32;\npub const KSDSOUND_BUFFER_CTRL_POSITIONNOTIFY: u32 = 16u32;\npub const KSDSOUND_BUFFER_CTRL_VOLUME: u32 = 8u32;\npub const KSDSOUND_BUFFER_LOCHARDWARE: u32 = 4u32;\npub const KSDSOUND_BUFFER_LOCSOFTWARE: u32 = 8u32;\npub const KSDSOUND_BUFFER_PRIMARY: u32 = 1u32;\npub const KSDSOUND_BUFFER_STATIC: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSERROR {\n    pub Context: *mut core::ffi::c_void,\n    pub Status: u32,\n}\nimpl Default for KSERROR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSEVENTDATA {\n    pub NotificationType: u32,\n    pub Anonymous: KSEVENTDATA_0,\n}\nimpl Default for KSEVENTDATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSEVENTDATA_0 {\n    pub EventHandle: KSEVENTDATA_0_0,\n    pub SemaphoreHandle: KSEVENTDATA_0_1,\n    pub Alignment: KSEVENTDATA_0_2,\n}\nimpl Default for KSEVENTDATA_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSEVENTDATA_0_2 {\n    pub Unused: *mut core::ffi::c_void,\n    pub Alignment: [isize; 2],\n}\nimpl Default for KSEVENTDATA_0_2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSEVENTDATA_0_0 {\n    pub Event: super::super::Foundation::HANDLE,\n    pub Reserved: [usize; 2],\n}\nimpl Default for KSEVENTDATA_0_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSEVENTDATA_0_1 {\n    pub Semaphore: super::super::Foundation::HANDLE,\n    pub Reserved: u32,\n    pub Adjustment: i32,\n}\nimpl Default for KSEVENTDATA_0_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSEVENTF_DPC: u32 = 16u32;\npub const KSEVENTF_EVENT_HANDLE: u32 = 1u32;\npub const KSEVENTF_EVENT_OBJECT: u32 = 4u32;\npub const KSEVENTF_KSWORKITEM: u32 = 128u32;\npub const KSEVENTF_SEMAPHORE_HANDLE: u32 = 2u32;\npub const KSEVENTF_SEMAPHORE_OBJECT: u32 = 8u32;\npub const KSEVENTF_WORKITEM: u32 = 32u32;\npub const KSEVENTSETID_AudioControlChange: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe85e9698_fa2f_11d1_95bd_00c04fb925d3);\npub const KSEVENTSETID_CameraAsyncControl: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x22a11754_9701_4088_b33f_6b9cbc52df5e);\npub const KSEVENTSETID_CameraEvent: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7899b2e0_6b43_4964_9d2a_a21f4061f576);\npub const KSEVENTSETID_Clock: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x364d8e20_62c7_11cf_a5d6_28db04c10000);\npub const KSEVENTSETID_Connection: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7f4bcbe0_9ea5_11cf_a5d6_28db04c10000);\npub const KSEVENTSETID_Device: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x288296ec_9f94_41b4_a153_aa31aeecb33f);\npub const KSEVENTSETID_DynamicFormatChange: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x162ac456_83d7_4239_96df_c75ffa138bc6);\npub const KSEVENTSETID_EXTDEV_Command: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x109c7988_b3cb_11d2_b48e_006097b3391b);\npub const KSEVENTSETID_ExtendedCameraControl: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x571c92c9_13a2_47e3_a649_d2a778166384);\npub const KSEVENTSETID_LoopedStreaming: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4682b940_c6ef_11d0_96d8_00aa0051e51d);\npub const KSEVENTSETID_PinCapsChange: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdd4f192e_3b78_49ad_a534_2c315b822000);\npub const KSEVENTSETID_SoundDetector: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x69785c9b_fc2d_49d6_ac32_4799f87de9f6);\npub const KSEVENTSETID_StreamAllocator: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x75d95571_073c_11d0_a161_0020afd156e4);\npub const KSEVENTSETID_Telephony: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb77f12b4_ceb4_4484_8d5e_52c1e7d8762d);\npub const KSEVENTSETID_VIDCAPTOSTI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdb47de20_f628_11d1_ba41_00a0c90d2b05);\npub const KSEVENTSETID_VIDCAP_TVAUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6a2e0651_28e4_11d0_a18c_00a0c9118956);\npub const KSEVENTSETID_VPNotify: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x20c5598e_d3c8_11d0_8dfc_00c04fd7c08b);\npub const KSEVENTSETID_VPVBINotify: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xec529b01_1a1f_11d1_bad9_00609744111a);\npub const KSEVENTSETID_VolumeLimit: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xda168465_3a7c_4858_9d4a_3e8e24701aef);\npub type KSEVENT_AUDIO_CONTROL_CHANGE = i32;\npub type KSEVENT_CAMERACONTROL = i32;\npub const KSEVENT_CAMERACONTROL_FOCUS: KSEVENT_CAMERACONTROL = 0i32;\npub const KSEVENT_CAMERACONTROL_ZOOM: KSEVENT_CAMERACONTROL = 1i32;\npub type KSEVENT_CAMERAEVENT = i32;\npub const KSEVENT_CLOCK_INTERVAL_MARK: KSEVENT_CLOCK_POSITION = 0i32;\npub type KSEVENT_CLOCK_POSITION = i32;\npub const KSEVENT_CLOCK_POSITION_MARK: KSEVENT_CLOCK_POSITION = 1i32;\npub type KSEVENT_CONNECTION = i32;\npub const KSEVENT_CONNECTION_DATADISCONTINUITY: KSEVENT_CONNECTION = 1i32;\npub const KSEVENT_CONNECTION_ENDOFSTREAM: KSEVENT_CONNECTION = 4i32;\npub const KSEVENT_CONNECTION_POSITIONUPDATE: KSEVENT_CONNECTION = 0i32;\npub const KSEVENT_CONNECTION_PRIORITY: KSEVENT_CONNECTION = 3i32;\npub const KSEVENT_CONNECTION_TIMEDISCONTINUITY: KSEVENT_CONNECTION = 2i32;\npub const KSEVENT_CONTROL_CHANGE: KSEVENT_AUDIO_CONTROL_CHANGE = 0i32;\npub type KSEVENT_CROSSBAR = i32;\npub const KSEVENT_CROSSBAR_CHANGED: KSEVENT_CROSSBAR = 0i32;\npub type KSEVENT_DEVCMD = i32;\npub type KSEVENT_DEVICE = i32;\npub const KSEVENT_DEVICE_LOST: KSEVENT_DEVICE = 0i32;\npub const KSEVENT_DEVICE_PREEMPTED: KSEVENT_DEVICE = 1i32;\npub const KSEVENT_DEVICE_THERMAL_HIGH: KSEVENT_DEVICE = 2i32;\npub const KSEVENT_DEVICE_THERMAL_LOW: KSEVENT_DEVICE = 3i32;\npub type KSEVENT_DYNAMICFORMATCHANGE = i32;\npub const KSEVENT_DYNAMIC_FORMAT_CHANGE: KSEVENT_DYNAMICFORMATCHANGE = 0i32;\npub const KSEVENT_ENTRY_BUFFERED: u32 = 4u32;\npub const KSEVENT_ENTRY_DELETED: u32 = 1u32;\npub const KSEVENT_ENTRY_ONESHOT: u32 = 2u32;\npub const KSEVENT_EXTDEV_COMMAND_BUSRESET: KSEVENT_DEVCMD = 2i32;\npub const KSEVENT_EXTDEV_COMMAND_CONTROL_INTERIM_READY: KSEVENT_DEVCMD = 1i32;\npub const KSEVENT_EXTDEV_COMMAND_NOTIFY_INTERIM_READY: KSEVENT_DEVCMD = 0i32;\npub const KSEVENT_EXTDEV_NOTIFY_MEDIUM_CHANGE: KSEVENT_DEVCMD = 7i32;\npub const KSEVENT_EXTDEV_NOTIFY_REMOVAL: KSEVENT_DEVCMD = 6i32;\npub const KSEVENT_EXTDEV_OPERATION_MODE_UPDATE: KSEVENT_DEVCMD = 4i32;\npub const KSEVENT_EXTDEV_TIMECODE_UPDATE: KSEVENT_DEVCMD = 3i32;\npub const KSEVENT_EXTDEV_TRANSPORT_STATE_UPDATE: KSEVENT_DEVCMD = 5i32;\npub type KSEVENT_LOOPEDSTREAMING = i32;\npub const KSEVENT_LOOPEDSTREAMING_POSITION: KSEVENT_LOOPEDSTREAMING = 0i32;\npub const KSEVENT_PHOTO_SAMPLE_SCANNED: KSEVENT_CAMERAEVENT = 0i32;\npub type KSEVENT_PINCAPS_CHANGENOTIFICATIONS = i32;\npub const KSEVENT_PINCAPS_FORMATCHANGE: KSEVENT_PINCAPS_CHANGENOTIFICATIONS = 0i32;\npub const KSEVENT_PINCAPS_JACKINFOCHANGE: KSEVENT_PINCAPS_CHANGENOTIFICATIONS = 1i32;\npub type KSEVENT_SOUNDDETECTOR = i32;\npub const KSEVENT_SOUNDDETECTOR_MATCHDETECTED: KSEVENT_SOUNDDETECTOR = 1i32;\npub type KSEVENT_STREAMALLOCATOR = i32;\npub const KSEVENT_STREAMALLOCATOR_FREEFRAME: KSEVENT_STREAMALLOCATOR = 1i32;\npub const KSEVENT_STREAMALLOCATOR_INTERNAL_FREEFRAME: KSEVENT_STREAMALLOCATOR = 0i32;\npub type KSEVENT_TELEPHONY = i32;\npub const KSEVENT_TELEPHONY_ENDPOINTPAIRS_CHANGED: KSEVENT_TELEPHONY = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSEVENT_TIME_INTERVAL {\n    pub EventData: KSEVENTDATA,\n    pub TimeBase: i64,\n    pub Interval: i64,\n}\nimpl Default for KSEVENT_TIME_INTERVAL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSEVENT_TIME_MARK {\n    pub EventData: KSEVENTDATA,\n    pub MarkTime: i64,\n}\nimpl Default for KSEVENT_TIME_MARK {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KSEVENT_TUNER = i32;\npub const KSEVENT_TUNER_CHANGED: KSEVENT_TUNER = 0i32;\npub const KSEVENT_TUNER_INITIATE_SCAN: KSEVENT_TUNER = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSEVENT_TUNER_INITIATE_SCAN_S {\n    pub EventData: KSEVENTDATA,\n    pub StartFrequency: u32,\n    pub EndFrequency: u32,\n}\nimpl Default for KSEVENT_TUNER_INITIATE_SCAN_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KSEVENT_TVAUDIO = i32;\npub const KSEVENT_TVAUDIO_CHANGED: KSEVENT_TVAUDIO = 0i32;\npub const KSEVENT_TYPE_BASICSUPPORT: u32 = 512u32;\npub const KSEVENT_TYPE_ENABLE: u32 = 1u32;\npub const KSEVENT_TYPE_ENABLEBUFFERED: u32 = 4u32;\npub const KSEVENT_TYPE_ONESHOT: u32 = 2u32;\npub const KSEVENT_TYPE_QUERYBUFFER: u32 = 1024u32;\npub const KSEVENT_TYPE_SETSUPPORT: u32 = 256u32;\npub const KSEVENT_TYPE_TOPOLOGY: u32 = 268435456u32;\npub type KSEVENT_VIDCAPTOSTI = i32;\npub const KSEVENT_VIDCAPTOSTI_EXT_TRIGGER: KSEVENT_VIDCAPTOSTI = 0i32;\npub const KSEVENT_VIDCAP_AUTO_UPDATE: KSEVENT_VIDCAPTOSTI = 1i32;\npub const KSEVENT_VIDCAP_SEARCH: KSEVENT_VIDCAPTOSTI = 2i32;\npub type KSEVENT_VIDEODECODER = i32;\npub const KSEVENT_VIDEODECODER_CHANGED: KSEVENT_VIDEODECODER = 0i32;\npub type KSEVENT_VOLUMELIMIT = i32;\npub const KSEVENT_VOLUMELIMIT_CHANGED: KSEVENT_VOLUMELIMIT = 0i32;\npub type KSEVENT_VPNOTIFY = i32;\npub const KSEVENT_VPNOTIFY_FORMATCHANGE: KSEVENT_VPNOTIFY = 0i32;\npub type KSEVENT_VPVBINOTIFY = i32;\npub const KSEVENT_VPVBINOTIFY_FORMATCHANGE: KSEVENT_VPVBINOTIFY = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSE_NODE {\n    pub Event: KSIDENTIFIER,\n    pub NodeId: u32,\n    pub Reserved: u32,\n}\nimpl Default for KSE_NODE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSE_PIN {\n    pub Event: KSIDENTIFIER,\n    pub PinId: u32,\n    pub Reserved: u32,\n}\nimpl Default for KSE_PIN {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSFILTER_FLAG_CRITICAL_PROCESSING: u32 = 2u32;\npub const KSFILTER_FLAG_DENY_USERMODE_ACCESS: u32 = 2147483648u32;\npub const KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING: u32 = 1u32;\npub const KSFILTER_FLAG_HYPERCRITICAL_PROCESSING: u32 = 4u32;\npub const KSFILTER_FLAG_PRIORITIZE_REFERENCEGUID: u32 = 16u32;\npub const KSFILTER_FLAG_RECEIVE_ZERO_LENGTH_SAMPLES: u32 = 8u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSFRAMETIME {\n    pub Duration: i64,\n    pub FrameFlags: u32,\n    pub Reserved: u32,\n}\npub const KSFRAMETIME_VARIABLESIZE: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSGOP_USERDATA {\n    pub sc: u32,\n    pub reserved1: u32,\n    pub cFields: u8,\n    pub l21Data: [i8; 3],\n}\nimpl Default for KSGOP_USERDATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSIDENTIFIER {\n    pub Anonymous: KSIDENTIFIER_0,\n}\nimpl Default for KSIDENTIFIER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSIDENTIFIER_0 {\n    pub Anonymous: KSIDENTIFIER_0_0,\n    pub Alignment: i64,\n}\nimpl Default for KSIDENTIFIER_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSIDENTIFIER_0_0 {\n    pub Set: windows_sys::core::GUID,\n    pub Id: u32,\n    pub Flags: u32,\n}\npub const KSINTERFACESETID_FileIo: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8c6f932c_e771_11d0_b8ff_00a0c9223196);\npub const KSINTERFACESETID_Media: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3a13eb40_30a7_11d0_a5d6_28db04c10000);\npub const KSINTERFACESETID_Standard: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1a8766a0_62ce_11cf_a5d6_28db04c10000);\npub type KSINTERFACE_FILEIO = i32;\npub const KSINTERFACE_FILEIO_STREAMING: KSINTERFACE_FILEIO = 0i32;\npub type KSINTERFACE_MEDIA = i32;\npub const KSINTERFACE_MEDIA_MUSIC: KSINTERFACE_MEDIA = 0i32;\npub const KSINTERFACE_MEDIA_WAVE_BUFFERED: KSINTERFACE_MEDIA = 1i32;\npub const KSINTERFACE_MEDIA_WAVE_QUEUED: KSINTERFACE_MEDIA = 2i32;\npub type KSINTERFACE_STANDARD = i32;\npub const KSINTERFACE_STANDARD_CONTROL: KSINTERFACE_STANDARD = 2i32;\npub const KSINTERFACE_STANDARD_LOOPED_STREAMING: KSINTERFACE_STANDARD = 1i32;\npub const KSINTERFACE_STANDARD_STREAMING: KSINTERFACE_STANDARD = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSINTERVAL {\n    pub TimeBase: i64,\n    pub Interval: i64,\n}\npub type KSIOOPERATION = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSJACK_DESCRIPTION {\n    pub ChannelMapping: u32,\n    pub Color: u32,\n    pub ConnectionType: EPcxConnectionType,\n    pub GeoLocation: EPcxGeoLocation,\n    pub GenLocation: EPcxGenLocation,\n    pub PortConnection: EPxcPortConnection,\n    pub IsConnected: windows_sys::core::BOOL,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSJACK_DESCRIPTION2 {\n    pub DeviceStateInfo: u32,\n    pub JackCapabilities: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSJACK_DESCRIPTION3 {\n    pub ConfigId: u32,\n}\npub type KSJACK_SINK_CONNECTIONTYPE = i32;\npub const KSJACK_SINK_CONNECTIONTYPE_DISPLAYPORT: KSJACK_SINK_CONNECTIONTYPE = 1i32;\npub const KSJACK_SINK_CONNECTIONTYPE_HDMI: KSJACK_SINK_CONNECTIONTYPE = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSJACK_SINK_INFORMATION {\n    pub ConnType: KSJACK_SINK_CONNECTIONTYPE,\n    pub ManufacturerId: u16,\n    pub ProductId: u16,\n    pub AudioLatency: u16,\n    pub HDCPCapable: windows_sys::core::BOOL,\n    pub AICapable: windows_sys::core::BOOL,\n    pub SinkDescriptionLength: u8,\n    pub SinkDescription: [u16; 32],\n    pub PortId: super::super::Foundation::LUID,\n}\nimpl Default for KSJACK_SINK_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSMEDIUMSETID_MidiBus: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x05908040_3246_11d0_a5d6_28db04c10000);\npub const KSMEDIUMSETID_Standard: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4747b320_62ce_11cf_a5d6_28db04c10000);\npub const KSMEDIUMSETID_VPBus: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa18c15ec_ce43_11d0_abe7_00a0c9223196);\npub const KSMEDIUM_STANDARD_DEVIO: u32 = 0u32;\npub const KSMEDIUM_TYPE_ANYINSTANCE: u32 = 0u32;\npub const KSMEMORY_TYPE_DEVICE_UNKNOWN: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x091bb639_603f_11d1_b067_00a0c9062802);\npub const KSMEMORY_TYPE_KERNEL_NONPAGED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4a6d5fc4_7895_11d1_b069_00a0c9062802);\npub const KSMEMORY_TYPE_KERNEL_PAGED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd833f8f8_7894_11d1_b069_00a0c9062802);\npub const KSMEMORY_TYPE_SYSTEM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x091bb638_603f_11d1_b067_00a0c9062802);\npub const KSMEMORY_TYPE_USER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8cb0fc28_7893_11d1_b069_00a0c9062802);\npub const KSMETHODSETID_StreamAllocator: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xcf6e4341_ec87_11cf_a130_0020afd156e4);\npub const KSMETHODSETID_StreamIo: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x65d003ca_1523_11d2_b27a_00a0c9223196);\npub const KSMETHODSETID_Wavetable: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdcef31eb_d907_11d0_9583_00c04fb925d3);\npub type KSMETHOD_STREAMALLOCATOR = i32;\npub const KSMETHOD_STREAMALLOCATOR_ALLOC: KSMETHOD_STREAMALLOCATOR = 0i32;\npub const KSMETHOD_STREAMALLOCATOR_FREE: KSMETHOD_STREAMALLOCATOR = 1i32;\npub type KSMETHOD_STREAMIO = i32;\npub const KSMETHOD_STREAMIO_READ: KSMETHOD_STREAMIO = 0i32;\npub const KSMETHOD_STREAMIO_WRITE: KSMETHOD_STREAMIO = 1i32;\npub const KSMETHOD_TYPE_BASICSUPPORT: u32 = 512u32;\npub const KSMETHOD_TYPE_MODIFY: u32 = 3u32;\npub const KSMETHOD_TYPE_NONE: u32 = 0u32;\npub const KSMETHOD_TYPE_READ: u32 = 1u32;\npub const KSMETHOD_TYPE_SEND: u32 = 1u32;\npub const KSMETHOD_TYPE_SETSUPPORT: u32 = 256u32;\npub const KSMETHOD_TYPE_SOURCE: u32 = 4u32;\npub const KSMETHOD_TYPE_TOPOLOGY: u32 = 268435456u32;\npub const KSMETHOD_TYPE_WRITE: u32 = 2u32;\npub type KSMETHOD_WAVETABLE = i32;\npub const KSMETHOD_WAVETABLE_WAVE_ALLOC: KSMETHOD_WAVETABLE = 0i32;\npub const KSMETHOD_WAVETABLE_WAVE_FIND: KSMETHOD_WAVETABLE = 2i32;\npub const KSMETHOD_WAVETABLE_WAVE_FREE: KSMETHOD_WAVETABLE = 1i32;\npub const KSMETHOD_WAVETABLE_WAVE_WRITE: KSMETHOD_WAVETABLE = 3i32;\npub const KSMETHOD_WAVE_QUEUED_BREAKLOOP: u32 = 1u32;\npub const KSMFT_CATEGORY_AUDIO_DECODER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9ea73fb4_ef7a_4559_8d5d_719d8f0426c7);\npub const KSMFT_CATEGORY_AUDIO_EFFECT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x11064c48_3648_4ed0_932e_05ce8ac811b7);\npub const KSMFT_CATEGORY_AUDIO_ENCODER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x91c64bd0_f91e_4d8c_9276_db248279d975);\npub const KSMFT_CATEGORY_DEMULTIPLEXER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa8700a7a_939b_44c5_99d7_76226b23b3f1);\npub const KSMFT_CATEGORY_MULTIPLEXER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x059c561e_05ae_4b61_b69d_55b61ee54a7b);\npub const KSMFT_CATEGORY_OTHER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x90175d57_b7ea_4901_aeb3_933a8747756f);\npub const KSMFT_CATEGORY_VIDEO_DECODER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd6c02d4b_6833_45b4_971a_05a4b04bab91);\npub const KSMFT_CATEGORY_VIDEO_EFFECT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x12e17c21_532c_4a6e_8a1c_40825a736397);\npub const KSMFT_CATEGORY_VIDEO_ENCODER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf79eac7d_e545_4387_bdee_d647d7bde42a);\npub const KSMFT_CATEGORY_VIDEO_PROCESSOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x302ea3fc_aa5f_47f9_9f7a_c2188bb16302);\npub type KSMICARRAY_MICARRAYTYPE = i32;\npub const KSMICARRAY_MICARRAYTYPE_3D: KSMICARRAY_MICARRAYTYPE = 2i32;\npub const KSMICARRAY_MICARRAYTYPE_LINEAR: KSMICARRAY_MICARRAYTYPE = 0i32;\npub const KSMICARRAY_MICARRAYTYPE_PLANAR: KSMICARRAY_MICARRAYTYPE = 1i32;\npub type KSMICARRAY_MICTYPE = i32;\npub const KSMICARRAY_MICTYPE_8SHAPED: KSMICARRAY_MICTYPE = 5i32;\npub const KSMICARRAY_MICTYPE_CARDIOID: KSMICARRAY_MICTYPE = 2i32;\npub const KSMICARRAY_MICTYPE_HYPERCARDIOID: KSMICARRAY_MICTYPE = 4i32;\npub const KSMICARRAY_MICTYPE_OMNIDIRECTIONAL: KSMICARRAY_MICTYPE = 0i32;\npub const KSMICARRAY_MICTYPE_SUBCARDIOID: KSMICARRAY_MICTYPE = 1i32;\npub const KSMICARRAY_MICTYPE_SUPERCARDIOID: KSMICARRAY_MICTYPE = 3i32;\npub const KSMICARRAY_MICTYPE_VENDORDEFINED: KSMICARRAY_MICTYPE = 15i32;\npub const KSMPEGVIDMODE_LTRBOX: u32 = 2u32;\npub const KSMPEGVIDMODE_PANSCAN: u32 = 1u32;\npub const KSMPEGVIDMODE_SCALE: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSMPEGVID_RECT {\n    pub StartX: u32,\n    pub StartY: u32,\n    pub EndX: u32,\n    pub EndY: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSMULTIPLE_DATA_PROP {\n    pub Property: KSIDENTIFIER,\n    pub MultipleItem: KSMULTIPLE_ITEM,\n}\nimpl Default for KSMULTIPLE_DATA_PROP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSMULTIPLE_ITEM {\n    pub Size: u32,\n    pub Count: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSMUSICFORMAT {\n    pub TimeDeltaMs: u32,\n    pub ByteCount: u32,\n}\npub const KSMUSIC_TECHNOLOGY_FMSYNTH: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x252c5c80_62e9_11cf_a5d6_28db04c10000);\npub const KSMUSIC_TECHNOLOGY_PORT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x86c92e60_62e8_11cf_a5d6_28db04c10000);\npub const KSMUSIC_TECHNOLOGY_SQSYNTH: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0ecf4380_62e9_11cf_a5d6_28db04c10000);\npub const KSMUSIC_TECHNOLOGY_SWSYNTH: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x37407736_3620_11d1_85d3_0000f8754380);\npub const KSMUSIC_TECHNOLOGY_WAVETABLE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x394ec7c0_62e9_11cf_a5d6_28db04c10000);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSM_NODE {\n    pub Method: KSIDENTIFIER,\n    pub NodeId: u32,\n    pub Reserved: u32,\n}\nimpl Default for KSM_NODE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSNAME_Allocator: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x642f5d00_4791_11d0_a5d6_28db04c10000);\npub const KSNAME_Clock: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53172480_4791_11d0_a5d6_28db04c10000);\npub const KSNAME_Filter: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9b365890_165f_11d0_a195_0020afd156e4);\npub const KSNAME_Pin: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x146f1a80_4791_11d0_a5d6_28db04c10000);\npub const KSNAME_TopologyNode: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0621061a_ee75_11d0_b915_00a0c9223196);\npub const KSNODEPIN_AEC_CAPTURE_IN: u32 = 2u32;\npub const KSNODEPIN_AEC_CAPTURE_OUT: u32 = 3u32;\npub const KSNODEPIN_AEC_RENDER_IN: u32 = 1u32;\npub const KSNODEPIN_AEC_RENDER_OUT: u32 = 0u32;\npub const KSNODEPIN_DEMUX_IN: u32 = 0u32;\npub const KSNODEPIN_DEMUX_OUT: u32 = 1u32;\npub const KSNODEPIN_STANDARD_IN: u32 = 1u32;\npub const KSNODEPIN_STANDARD_OUT: u32 = 0u32;\npub const KSNODEPIN_SUM_MUX_IN: u32 = 1u32;\npub const KSNODEPIN_SUM_MUX_OUT: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSNODEPROPERTY {\n    pub Property: KSIDENTIFIER,\n    pub NodeId: u32,\n    pub Reserved: u32,\n}\nimpl Default for KSNODEPROPERTY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(target_arch = \"x86\")]\n#[derive(Clone, Copy)]\npub struct KSNODEPROPERTY_AUDIO_3D_LISTENER {\n    pub NodeProperty: KSNODEPROPERTY,\n    pub ListenerId: *mut core::ffi::c_void,\n    pub Reserved: u32,\n}\n#[cfg(target_arch = \"x86\")]\nimpl Default for KSNODEPROPERTY_AUDIO_3D_LISTENER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\n#[derive(Clone, Copy)]\npub struct KSNODEPROPERTY_AUDIO_3D_LISTENER {\n    pub NodeProperty: KSNODEPROPERTY,\n    pub ListenerId: *mut core::ffi::c_void,\n}\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\nimpl Default for KSNODEPROPERTY_AUDIO_3D_LISTENER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSNODEPROPERTY_AUDIO_CHANNEL {\n    pub NodeProperty: KSNODEPROPERTY,\n    pub Channel: i32,\n    pub Reserved: u32,\n}\nimpl Default for KSNODEPROPERTY_AUDIO_CHANNEL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSNODEPROPERTY_AUDIO_DEV_SPECIFIC {\n    pub NodeProperty: KSNODEPROPERTY,\n    pub DevSpecificId: u32,\n    pub DeviceInfo: u32,\n    pub Length: u32,\n}\nimpl Default for KSNODEPROPERTY_AUDIO_DEV_SPECIFIC {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(target_arch = \"x86\")]\n#[derive(Clone, Copy)]\npub struct KSNODEPROPERTY_AUDIO_PROPERTY {\n    pub NodeProperty: KSNODEPROPERTY,\n    pub AppContext: *mut core::ffi::c_void,\n    pub Length: u32,\n    pub Reserved: u32,\n}\n#[cfg(target_arch = \"x86\")]\nimpl Default for KSNODEPROPERTY_AUDIO_PROPERTY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\n#[derive(Clone, Copy)]\npub struct KSNODEPROPERTY_AUDIO_PROPERTY {\n    pub NodeProperty: KSNODEPROPERTY,\n    pub AppContext: *mut core::ffi::c_void,\n    pub Length: u32,\n}\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\nimpl Default for KSNODEPROPERTY_AUDIO_PROPERTY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSNODETYPE_1394_DA_STREAM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21fe6_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_1394_DV_STREAM_SOUNDTRACK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21fe7_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_3D_EFFECTS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x55515860_c559_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_ADC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4d837fe0_c555_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_AGC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe88c9ba0_c557_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_ANALOG_CONNECTOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21fe1_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_ANALOG_TAPE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220e7_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_AUDIO_ENGINE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x35caf6e4_f3b3_4168_bb4b_55e77a461c7e);\npub const KSNODETYPE_AUDIO_KEYWORDDETECTOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3817e0b8_df58_4375_b669_c49634331f9d);\npub const KSNODETYPE_AUDIO_LOOPBACK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8f42c0b2_91ce_4bcf_9ccd_0e599037ab35);\npub const KSNODETYPE_AUDIO_MODULE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x45aab42e_caeb_4052_8aa9_b38cb5109619);\npub const KSNODETYPE_BIDIRECTIONAL_UNDEFINED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21de0_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_CABLE_TUNER_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220ee_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_CD_PLAYER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220e3_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_CHORUS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x20173f20_c559_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_COMMUNICATION_SPEAKER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ce6_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_DAC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x507ae360_c554_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220e4_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220e5_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_DELAY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x144981e0_c558_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_DEMUX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc0eb67d4_e807_11d0_958a_00c04fb925d3);\npub const KSNODETYPE_DESKTOP_MICROPHONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21be2_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_DESKTOP_SPEAKER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ce4_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_DEV_SPECIFIC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x941c7ac0_c559_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_DIGITAL_AUDIO_INTERFACE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21fe2_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_DISPLAYPORT_INTERFACE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe47e4031_3ea6_418d_8f9b_b73843ccba97);\npub const KSNODETYPE_DOWN_LINE_PHONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ee3_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_DRM_DESCRAMBLE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xffbb6e3f_ccfe_4d84_90d9_421418b03a8e);\npub const KSNODETYPE_DSS_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220ef_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_DVD_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220eb_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_DYN_RANGE_COMPRESSOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x08c8a6a8_601f_4af8_8793_d905ff4ca97d);\npub const KSNODETYPE_ECHO_CANCELING_SPEAKERPHONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21de5_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_ECHO_SUPPRESSING_SPEAKERPHONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21de4_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_EMBEDDED_UNDEFINED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220e0_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_EQUALIZATION_NOISE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220e2_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_EQUALIZER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9d41b4a0_c557_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_EXTERNAL_UNDEFINED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21fe0_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_FM_RX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x834a733c_f485_41c0_a62b_513025014e40);\npub const KSNODETYPE_HANDSET: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21de1_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_HDMI_INTERFACE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd1b9cc2a_f519_417f_91c9_55fa65481001);\npub const KSNODETYPE_HEADPHONES: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ce2_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_HEADSET: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21de2_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ce3_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_INPUT_UNDEFINED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21be0_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_LEGACY_AUDIO_CONNECTOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21fe4_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220e1_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_LINE_CONNECTOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21fe3_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_LOUDNESS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x41887440_c558_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ce7_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_MICROPHONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21be1_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_MICROPHONE_ARRAY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21be5_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_MIDI_ELEMENT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x01c6fe66_6e48_4c65_ac9b_52db5d656c7e);\npub const KSNODETYPE_MIDI_JACK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x265e0c3f_fa39_4df3_ab04_be01b91e299a);\npub const KSNODETYPE_MINIDISK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220e6_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_MULTITRACK_RECORDER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220f2_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_MUTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x02b223c0_c557_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_MUX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2ceaf780_c556_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_NOISE_SUPPRESS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe07f903f_62fd_4e60_8cdd_dea7236665b5);\npub const KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21be4_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_OUTPUT_UNDEFINED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ce0_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_PARAMETRIC_EQUALIZER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x19bb3a6a_ce2b_4442_87ec_6727c3cab477);\npub const KSNODETYPE_PEAKMETER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa085651e_5f0d_4b36_a869_d195d6ab4b9e);\npub const KSNODETYPE_PERSONAL_MICROPHONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21be3_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_PHONE_LINE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ee1_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_PHONOGRAPH: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220e8_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_PROCESSING_MICROPHONE_ARRAY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21be6_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_PROLOGIC_DECODER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x831c2c80_c558_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_PROLOGIC_ENCODER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8074c5b2_3c66_11d2_b45a_3078302c2030);\npub const KSNODETYPE_RADIO_RECEIVER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220f0_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_RADIO_TRANSMITTER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220f1_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_REVERB: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xef0328e0_c558_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_ROOM_SPEAKER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ce5_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_SATELLITE_RECEIVER_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220ed_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_SPDIF_INTERFACE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21fe5_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_SPEAKER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ce1_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_SPEAKERPHONE_NO_ECHO_REDUCTION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21de3_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_SPEAKERS_STATIC_JACK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x28e04f87_4dbe_4f8d_8589_025d209dfb4a);\npub const KSNODETYPE_SRC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9db7b9e0_c555_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_STEREO_WIDE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa9e69800_c558_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_SUM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xda441a60_c556_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_SUPERMIX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe573adc0_c555_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_SYNTHESIZER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220f3_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_TELEPHONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ee2_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_TELEPHONY_BIDI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x686d7cc0_d903_4258_b443_3a3d3580741c);\npub const KSNODETYPE_TELEPHONY_UNDEFINED: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff21ee0_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_TONE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7607e580_c557_11d0_8a2b_00a0c9255ac1);\npub const KSNODETYPE_TV_TUNER_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220ec_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_UPDOWN_MIX: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb7edc5cf_7b63_4ee2_a100_29ee2cb6b2de);\npub const KSNODETYPE_VCR_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220e9_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_VIDEO_CAMERA_TERMINAL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff229e6_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_VIDEO_DISC_AUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff220ea_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_VIDEO_INPUT_MTT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff229e7_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_VIDEO_INPUT_TERMINAL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff229e2_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_VIDEO_OUTPUT_MTT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff229e8_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_VIDEO_OUTPUT_TERMINAL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff229e3_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_VIDEO_PROCESSING: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff229e5_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_VIDEO_SELECTOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff229e4_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_VIDEO_STREAMING: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdff229e1_f70f_11d0_b917_00a0c9223196);\npub const KSNODETYPE_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3a5acc00_c557_11d0_8a2b_00a0c9255ac1);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSNODE_CREATE {\n    pub CreateFlags: u32,\n    pub Node: u32,\n}\npub const KSNOTIFICATIONID_AudioModule: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9c2220f0_d9a6_4d5c_a036_573857fd50d2);\npub const KSNOTIFICATIONID_SoundDetector: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6389d844_bb32_4c4c_a802_f4b4b77afead);\npub type KSPEEKOPERATION = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPIN_CINSTANCES {\n    pub PossibleCount: u32,\n    pub CurrentCount: u32,\n}\npub type KSPIN_COMMUNICATION = i32;\npub const KSPIN_COMMUNICATION_BOTH: KSPIN_COMMUNICATION = 3i32;\npub const KSPIN_COMMUNICATION_BRIDGE: KSPIN_COMMUNICATION = 4i32;\npub const KSPIN_COMMUNICATION_NONE: KSPIN_COMMUNICATION = 0i32;\npub const KSPIN_COMMUNICATION_SINK: KSPIN_COMMUNICATION = 1i32;\npub const KSPIN_COMMUNICATION_SOURCE: KSPIN_COMMUNICATION = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPIN_CONNECT {\n    pub Interface: KSIDENTIFIER,\n    pub Medium: KSIDENTIFIER,\n    pub PinId: u32,\n    pub PinToHandle: super::super::Foundation::HANDLE,\n    pub Priority: KSPRIORITY,\n}\nimpl Default for KSPIN_CONNECT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KSPIN_DATAFLOW = i32;\npub const KSPIN_DATAFLOW_IN: KSPIN_DATAFLOW = 1i32;\npub const KSPIN_DATAFLOW_OUT: KSPIN_DATAFLOW = 2i32;\npub const KSPIN_FLAG_ASYNCHRONOUS_PROCESSING: u32 = 8u32;\npub const KSPIN_FLAG_CRITICAL_PROCESSING: u32 = 2u32;\npub const KSPIN_FLAG_DENY_USERMODE_ACCESS: u32 = 2147483648u32;\npub const KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING: u32 = 1u32;\npub const KSPIN_FLAG_DISTINCT_TRAILING_EDGE: u32 = 512u32;\npub const KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING: u32 = 16u32;\npub const KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT: u32 = 524288u32;\npub const KSPIN_FLAG_ENFORCE_FIFO: u32 = 128u32;\npub const KSPIN_FLAG_FIXED_FORMAT: u32 = 1048576u32;\npub const KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING: u32 = 64u32;\npub const KSPIN_FLAG_GENERATE_EOS_EVENTS: u32 = 2097152u32;\npub const KSPIN_FLAG_GENERATE_MAPPINGS: u32 = 256u32;\npub const KSPIN_FLAG_HYPERCRITICAL_PROCESSING: u32 = 4u32;\npub const KSPIN_FLAG_IMPLEMENT_CLOCK: u32 = 4194304u32;\npub const KSPIN_FLAG_INITIATE_PROCESSING_ON_EVERY_ARRIVAL: u32 = 32u32;\npub const KSPIN_FLAG_PROCESS_IF_ANY_IN_RUN_STATE: u32 = 16777216u32;\npub const KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY: u32 = 65536u32;\npub const KSPIN_FLAG_SOME_FRAMES_REQUIRED_FOR_PROCESSING: u32 = 8388608u32;\npub const KSPIN_FLAG_SPLITTER: u32 = 131072u32;\npub const KSPIN_FLAG_USE_STANDARD_TRANSPORT: u32 = 262144u32;\npub type KSPIN_MDL_CACHING_EVENT = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPIN_MDL_CACHING_NOTIFICATION {\n    pub Event: KSPIN_MDL_CACHING_EVENT,\n    pub Buffer: *mut core::ffi::c_void,\n}\nimpl Default for KSPIN_MDL_CACHING_NOTIFICATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPIN_MDL_CACHING_NOTIFICATION32 {\n    pub Event: KSPIN_MDL_CACHING_EVENT,\n    pub Buffer: u32,\n}\npub const KSPIN_MDL_CACHING_NOTIFY_ADDSAMPLE: KSPIN_MDL_CACHING_EVENT = 3i32;\npub const KSPIN_MDL_CACHING_NOTIFY_CLEANALL_NOWAIT: KSPIN_MDL_CACHING_EVENT = 2i32;\npub const KSPIN_MDL_CACHING_NOTIFY_CLEANALL_WAIT: KSPIN_MDL_CACHING_EVENT = 1i32;\npub const KSPIN_MDL_CACHING_NOTIFY_CLEANUP: KSPIN_MDL_CACHING_EVENT = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPIN_PHYSICALCONNECTION {\n    pub Size: u32,\n    pub Pin: u32,\n    pub SymbolicLinkName: [u16; 1],\n}\nimpl Default for KSPIN_PHYSICALCONNECTION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KSPPROPERTY_ALLOCATOR_MDLCACHING = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPRIORITY {\n    pub PriorityClass: u32,\n    pub PrioritySubClass: u32,\n}\npub const KSPRIORITY_EXCLUSIVE: u32 = 4294967295u32;\npub const KSPRIORITY_HIGH: u32 = 2147483648u32;\npub const KSPRIORITY_LOW: u32 = 1u32;\npub const KSPRIORITY_NORMAL: u32 = 1073741824u32;\npub const KSPROBE_ALLOCATEMDL: u32 = 16u32;\npub const KSPROBE_ALLOWFORMATCHANGE: u32 = 128u32;\npub const KSPROBE_MODIFY: u32 = 512u32;\npub const KSPROBE_PROBEANDLOCK: u32 = 32u32;\npub const KSPROBE_STREAMREAD: u32 = 0u32;\npub const KSPROBE_STREAMWRITE: u32 = 1u32;\npub const KSPROBE_SYSTEMADDRESS: u32 = 64u32;\npub const KSPROPERTYSETID_ExtendedCameraControl: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1cb79112_c0d2_4213_9ca6_cd4fdb927972);\npub const KSPROPERTYSETID_NetworkCameraControl: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0e780f09_5745_4e3a_bc9f_f226ea43a6ec);\npub const KSPROPERTYSETID_PerFrameSettingControl: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf1f3e261_dee6_4537_bff5_ee206db54aac);\npub type KSPROPERTY_AC3 = i32;\npub const KSPROPERTY_AC3_ALTERNATE_AUDIO: KSPROPERTY_AC3 = 2i32;\npub const KSPROPERTY_AC3_BIT_STREAM_MODE: KSPROPERTY_AC3 = 4i32;\npub const KSPROPERTY_AC3_DIALOGUE_LEVEL: KSPROPERTY_AC3 = 5i32;\npub const KSPROPERTY_AC3_DOWNMIX: KSPROPERTY_AC3 = 3i32;\npub const KSPROPERTY_AC3_ERROR_CONCEALMENT: KSPROPERTY_AC3 = 1i32;\npub const KSPROPERTY_AC3_LANGUAGE_CODE: KSPROPERTY_AC3 = 6i32;\npub const KSPROPERTY_AC3_ROOM_TYPE: KSPROPERTY_AC3 = 7i32;\npub const KSPROPERTY_ALLOCATOR_CLEANUP_CACHEDMDLPAGES: KSPPROPERTY_ALLOCATOR_MDLCACHING = 1i32;\npub type KSPROPERTY_ALLOCATOR_CONTROL = i32;\npub const KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_CAPS: KSPROPERTY_ALLOCATOR_CONTROL = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_CAPS_S {\n    pub InterleavedCapSupported: u32,\n}\npub const KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_INTERLEAVE: KSPROPERTY_ALLOCATOR_CONTROL = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_INTERLEAVE_S {\n    pub InterleavedCapPossible: u32,\n}\npub const KSPROPERTY_ALLOCATOR_CONTROL_HONOR_COUNT: KSPROPERTY_ALLOCATOR_CONTROL = 0i32;\npub const KSPROPERTY_ALLOCATOR_CONTROL_SURFACE_SIZE: KSPROPERTY_ALLOCATOR_CONTROL = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_ALLOCATOR_CONTROL_SURFACE_SIZE_S {\n    pub CX: u32,\n    pub CY: u32,\n}\npub const KSPROPERTY_ATN_READER: KSPROPERTY_TIMECODE = 1i32;\npub type KSPROPERTY_AUDDECOUT = i32;\npub const KSPROPERTY_AUDDECOUT_CUR_MODE: KSPROPERTY_AUDDECOUT = 1i32;\npub const KSPROPERTY_AUDDECOUT_MODES: KSPROPERTY_AUDDECOUT = 0i32;\npub type KSPROPERTY_AUDIO = i32;\npub type KSPROPERTY_AUDIOENGINE = i32;\npub const KSPROPERTY_AUDIOENGINE_BUFFER_SIZE_RANGE: KSPROPERTY_AUDIOENGINE = 7i32;\npub const KSPROPERTY_AUDIOENGINE_DESCRIPTOR: KSPROPERTY_AUDIOENGINE = 6i32;\npub const KSPROPERTY_AUDIOENGINE_DEVICECONTROLS: KSPROPERTY_AUDIOENGINE = 10i32;\npub const KSPROPERTY_AUDIOENGINE_DEVICEFORMAT: KSPROPERTY_AUDIOENGINE = 4i32;\npub const KSPROPERTY_AUDIOENGINE_GFXENABLE: KSPROPERTY_AUDIOENGINE = 1i32;\npub const KSPROPERTY_AUDIOENGINE_LFXENABLE: KSPROPERTY_AUDIOENGINE = 0i32;\npub const KSPROPERTY_AUDIOENGINE_LOOPBACK_PROTECTION: KSPROPERTY_AUDIOENGINE = 8i32;\npub const KSPROPERTY_AUDIOENGINE_MIXFORMAT: KSPROPERTY_AUDIOENGINE = 2i32;\npub const KSPROPERTY_AUDIOENGINE_SUPPORTEDDEVICEFORMATS: KSPROPERTY_AUDIOENGINE = 5i32;\npub const KSPROPERTY_AUDIOENGINE_VOLUMELEVEL: KSPROPERTY_AUDIOENGINE = 9i32;\npub type KSPROPERTY_AUDIOMODULE = i32;\npub const KSPROPERTY_AUDIOMODULE_COMMAND: KSPROPERTY_AUDIOMODULE = 2i32;\npub const KSPROPERTY_AUDIOMODULE_DESCRIPTORS: KSPROPERTY_AUDIOMODULE = 1i32;\npub const KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID: KSPROPERTY_AUDIOMODULE = 3i32;\npub type KSPROPERTY_AUDIOPOSTURE = i32;\npub const KSPROPERTY_AUDIOPOSTURE_ORIENTATION: KSPROPERTY_AUDIOPOSTURE = 1i32;\npub type KSPROPERTY_AUDIORESOURCEMANAGEMENT = i32;\npub const KSPROPERTY_AUDIORESOURCEMANAGEMENT_RESOURCEGROUP: KSPROPERTY_AUDIORESOURCEMANAGEMENT = 0i32;\npub type KSPROPERTY_AUDIOSIGNALPROCESSING = i32;\npub const KSPROPERTY_AUDIOSIGNALPROCESSING_MODES: KSPROPERTY_AUDIOSIGNALPROCESSING = 0i32;\npub const KSPROPERTY_AUDIO_3D_INTERFACE: KSPROPERTY_AUDIO = 36i32;\npub const KSPROPERTY_AUDIO_AGC: KSPROPERTY_AUDIO = 21i32;\npub const KSPROPERTY_AUDIO_ALGORITHM_INSTANCE: KSPROPERTY_AUDIO = 38i32;\npub const KSPROPERTY_AUDIO_BASS: KSPROPERTY_AUDIO = 14i32;\npub const KSPROPERTY_AUDIO_BASS_BOOST: KSPROPERTY_AUDIO = 17i32;\npub const KSPROPERTY_AUDIO_BUFFER_DURATION: u32 = 1u32;\npub const KSPROPERTY_AUDIO_CHANNEL_CONFIG: KSPROPERTY_AUDIO = 3i32;\npub const KSPROPERTY_AUDIO_CHORUS_LEVEL: KSPROPERTY_AUDIO = 27i32;\npub const KSPROPERTY_AUDIO_CHORUS_MODULATION_DEPTH: KSPROPERTY_AUDIO = 47i32;\npub const KSPROPERTY_AUDIO_CHORUS_MODULATION_RATE: KSPROPERTY_AUDIO = 46i32;\npub const KSPROPERTY_AUDIO_COPY_PROTECTION: KSPROPERTY_AUDIO = 2i32;\npub const KSPROPERTY_AUDIO_CPU_RESOURCES: KSPROPERTY_AUDIO = 33i32;\npub const KSPROPERTY_AUDIO_DELAY: KSPROPERTY_AUDIO = 22i32;\npub const KSPROPERTY_AUDIO_DEMUX_DEST: KSPROPERTY_AUDIO = 29i32;\npub const KSPROPERTY_AUDIO_DEV_SPECIFIC: KSPROPERTY_AUDIO = 28i32;\npub const KSPROPERTY_AUDIO_DYNAMIC_RANGE: KSPROPERTY_AUDIO = 6i32;\npub const KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE: KSPROPERTY_AUDIO = 9i32;\npub const KSPROPERTY_AUDIO_EQ_BANDS: KSPROPERTY_AUDIO = 20i32;\npub const KSPROPERTY_AUDIO_EQ_LEVEL: KSPROPERTY_AUDIO = 18i32;\npub const KSPROPERTY_AUDIO_FILTER_STATE: KSPROPERTY_AUDIO = 39i32;\npub const KSPROPERTY_AUDIO_LATENCY: KSPROPERTY_AUDIO = 1i32;\npub const KSPROPERTY_AUDIO_LINEAR_BUFFER_POSITION: KSPROPERTY_AUDIO = 54i32;\npub const KSPROPERTY_AUDIO_LOUDNESS: KSPROPERTY_AUDIO = 23i32;\npub const KSPROPERTY_AUDIO_MANUFACTURE_GUID: KSPROPERTY_AUDIO = 31i32;\npub const KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY: KSPROPERTY_AUDIO = 51i32;\npub const KSPROPERTY_AUDIO_MIC_SENSITIVITY: KSPROPERTY_AUDIO = 58i32;\npub const KSPROPERTY_AUDIO_MIC_SENSITIVITY2: KSPROPERTY_AUDIO = 60i32;\npub const KSPROPERTY_AUDIO_MIC_SNR: KSPROPERTY_AUDIO = 59i32;\npub const KSPROPERTY_AUDIO_MID: KSPROPERTY_AUDIO = 15i32;\npub const KSPROPERTY_AUDIO_MIX_LEVEL_CAPS: KSPROPERTY_AUDIO = 11i32;\npub const KSPROPERTY_AUDIO_MIX_LEVEL_TABLE: KSPROPERTY_AUDIO = 10i32;\npub const KSPROPERTY_AUDIO_MUTE: KSPROPERTY_AUDIO = 13i32;\npub const KSPROPERTY_AUDIO_MUX_SOURCE: KSPROPERTY_AUDIO = 12i32;\npub const KSPROPERTY_AUDIO_NUM_EQ_BANDS: KSPROPERTY_AUDIO = 19i32;\npub const KSPROPERTY_AUDIO_PEAKMETER: KSPROPERTY_AUDIO = 37i32;\npub const KSPROPERTY_AUDIO_PEAKMETER2: KSPROPERTY_AUDIO = 55i32;\npub const KSPROPERTY_AUDIO_PEQ_BAND_CENTER_FREQ: KSPROPERTY_AUDIO = 43i32;\npub const KSPROPERTY_AUDIO_PEQ_BAND_LEVEL: KSPROPERTY_AUDIO = 45i32;\npub const KSPROPERTY_AUDIO_PEQ_BAND_Q_FACTOR: KSPROPERTY_AUDIO = 44i32;\npub const KSPROPERTY_AUDIO_PEQ_MAX_BANDS: KSPROPERTY_AUDIO = 41i32;\npub const KSPROPERTY_AUDIO_PEQ_NUM_BANDS: KSPROPERTY_AUDIO = 42i32;\npub const KSPROPERTY_AUDIO_POSITION: KSPROPERTY_AUDIO = 5i32;\npub const KSPROPERTY_AUDIO_POSITIONEX: KSPROPERTY_AUDIO = 50i32;\npub const KSPROPERTY_AUDIO_PREFERRED_STATUS: KSPROPERTY_AUDIO = 40i32;\npub const KSPROPERTY_AUDIO_PRESENTATION_POSITION: KSPROPERTY_AUDIO = 52i32;\npub const KSPROPERTY_AUDIO_PRODUCT_GUID: KSPROPERTY_AUDIO = 32i32;\npub const KSPROPERTY_AUDIO_QUALITY: KSPROPERTY_AUDIO = 7i32;\npub const KSPROPERTY_AUDIO_REVERB_DELAY_FEEDBACK: KSPROPERTY_AUDIO = 49i32;\npub const KSPROPERTY_AUDIO_REVERB_LEVEL: KSPROPERTY_AUDIO = 26i32;\npub const KSPROPERTY_AUDIO_REVERB_TIME: KSPROPERTY_AUDIO = 48i32;\npub const KSPROPERTY_AUDIO_SAMPLING_RATE: KSPROPERTY_AUDIO = 8i32;\npub const KSPROPERTY_AUDIO_STEREO_ENHANCE: KSPROPERTY_AUDIO = 30i32;\npub const KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY: KSPROPERTY_AUDIO = 34i32;\npub const KSPROPERTY_AUDIO_SURROUND_ENCODE: KSPROPERTY_AUDIO = 35i32;\npub const KSPROPERTY_AUDIO_TREBLE: KSPROPERTY_AUDIO = 16i32;\npub const KSPROPERTY_AUDIO_VOLUMELEVEL: KSPROPERTY_AUDIO = 4i32;\npub const KSPROPERTY_AUDIO_VOLUMELIMIT_ENGAGED: KSPROPERTY_AUDIO = 57i32;\npub const KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_LASTBUFFER_POSITION: KSPROPERTY_AUDIO = 56i32;\npub const KSPROPERTY_AUDIO_WAVERT_CURRENT_WRITE_POSITION: KSPROPERTY_AUDIO = 53i32;\npub const KSPROPERTY_AUDIO_WIDENESS: KSPROPERTY_AUDIO = 25i32;\npub const KSPROPERTY_AUDIO_WIDE_MODE: KSPROPERTY_AUDIO = 24i32;\npub type KSPROPERTY_BIBLIOGRAPHIC = i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYGEOGRAPHIC: KSPROPERTY_BIBLIOGRAPHIC = 825570848i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYPERSONALNAME: KSPROPERTY_BIBLIOGRAPHIC = 808465952i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYRELATED: KSPROPERTY_BIBLIOGRAPHIC = 808728352i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYTITLE: KSPROPERTY_BIBLIOGRAPHIC = 808727584i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYTOPICALTERM: KSPROPERTY_BIBLIOGRAPHIC = 808793632i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYUNIFORMTITLE: KSPROPERTY_BIBLIOGRAPHIC = 808662816i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_ADDEDFORMAVAILABLE: KSPROPERTY_BIBLIOGRAPHIC = 808662304i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_AWARDS: KSPROPERTY_BIBLIOGRAPHIC = 909653280i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_BIBLIOGRAPHYNOTE: KSPROPERTY_BIBLIOGRAPHIC = 875574560i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_CATALOGINGSOURCE: KSPROPERTY_BIBLIOGRAPHIC = 808726560i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_CITATION: KSPROPERTY_BIBLIOGRAPHIC = 808531232i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_CONTENTSNOTE: KSPROPERTY_BIBLIOGRAPHIC = 892351776i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_CREATIONCREDIT: KSPROPERTY_BIBLIOGRAPHIC = 942683424i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_GENERALNOTE: KSPROPERTY_BIBLIOGRAPHIC = 808465696i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_INDEXTERMCURRICULUM: KSPROPERTY_BIBLIOGRAPHIC = 943011360i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_INDEXTERMGENRE: KSPROPERTY_BIBLIOGRAPHIC = 892679712i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_ISBN: KSPROPERTY_BIBLIOGRAPHIC = 808595488i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_ISSN: KSPROPERTY_BIBLIOGRAPHIC = 842149920i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_LCCN: KSPROPERTY_BIBLIOGRAPHIC = 808529952i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_LEADER: KSPROPERTY_BIBLIOGRAPHIC = 1380207648i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_MAINCORPORATEBODY: KSPROPERTY_BIBLIOGRAPHIC = 808530208i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_MAINMEETINGNAME: KSPROPERTY_BIBLIOGRAPHIC = 825307424i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_MAINPERSONALNAME: KSPROPERTY_BIBLIOGRAPHIC = 808464672i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_MAINUNIFORMTITLE: KSPROPERTY_BIBLIOGRAPHIC = 808661280i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_PARTICIPANT: KSPROPERTY_BIBLIOGRAPHIC = 825308448i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_PHYSICALDESCRIPTION: KSPROPERTY_BIBLIOGRAPHIC = 808465184i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_PUBLICATION: KSPROPERTY_BIBLIOGRAPHIC = 808858144i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_SERIESSTATEMENT: KSPROPERTY_BIBLIOGRAPHIC = 809055264i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_SERIESSTATEMENTPERSONALNAME: KSPROPERTY_BIBLIOGRAPHIC = 808466464i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_SERIESSTATEMENTUNIFORMTITLE: KSPROPERTY_BIBLIOGRAPHIC = 808663072i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_SUMMARY: KSPROPERTY_BIBLIOGRAPHIC = 808596768i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_SYSTEMDETAILS: KSPROPERTY_BIBLIOGRAPHIC = 942880032i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_TARGETAUDIENCE: KSPROPERTY_BIBLIOGRAPHIC = 825373984i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_TITLESTATEMENT: KSPROPERTY_BIBLIOGRAPHIC = 892613152i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_UNIFORMTITLE: KSPROPERTY_BIBLIOGRAPHIC = 808727072i32;\npub const KSPROPERTY_BIBLIOGRAPHIC_VARYINGFORMTITLE: KSPROPERTY_BIBLIOGRAPHIC = 909390368i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSPROPERTY_BOUNDS_LONG {\n    pub Anonymous1: KSPROPERTY_BOUNDS_LONG_0,\n    pub Anonymous2: KSPROPERTY_BOUNDS_LONG_1,\n}\nimpl Default for KSPROPERTY_BOUNDS_LONG {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_BOUNDS_LONG_0 {\n    pub SignedMinimum: i32,\n    pub SignedMaximum: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_BOUNDS_LONG_1 {\n    pub UnsignedMinimum: u32,\n    pub UnsignedMaximum: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSPROPERTY_BOUNDS_LONGLONG {\n    pub Anonymous1: KSPROPERTY_BOUNDS_LONGLONG_0,\n    pub Anonymous2: KSPROPERTY_BOUNDS_LONGLONG_1,\n}\nimpl Default for KSPROPERTY_BOUNDS_LONGLONG {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_BOUNDS_LONGLONG_0 {\n    pub SignedMinimum: i64,\n    pub SignedMaximum: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_BOUNDS_LONGLONG_1 {\n    pub UnsignedMinimum: u64,\n    pub UnsignedMaximum: u64,\n}\npub type KSPROPERTY_BTAUDIO = i32;\npub const KSPROPERTY_CAMERACONTROL_AUTO_EXPOSURE_PRIORITY: KSPROPERTY_VIDCAP_CAMERACONTROL = 19i32;\npub const KSPROPERTY_CAMERACONTROL_EXPOSURE: KSPROPERTY_VIDCAP_CAMERACONTROL = 4i32;\npub const KSPROPERTY_CAMERACONTROL_EXPOSURE_RELATIVE: KSPROPERTY_VIDCAP_CAMERACONTROL = 14i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_ADVANCEDPHOTO: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 33i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_BACKGROUNDSEGMENTATION: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 41i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_CAMERAANGLEOFFSET: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 17i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_DIGITALWINDOW: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 43i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_DIGITALWINDOW_CONFIGCAPS: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 42i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_END: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 44i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_END2: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 44i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_EVCOMPENSATION: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 16i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_EXPOSUREMODE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 12i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_EYEGAZECORRECTION: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 40i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_FACEAUTH_MODE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 35i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_FACEDETECTION: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 29i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_FIELDOFVIEW: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 15i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_FLASHMODE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 9i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_FOCUSMODE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 13i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_FOCUSPRIORITY: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 19i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_FOCUSSTATE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 20i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_HISTOGRAM: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 31i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_IRTORCHMODE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 38i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_ISO: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 14i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_ISO_ADVANCED: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 26i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_MAXVIDFPS_PHOTORES: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 5i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_MCC: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 25i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_METADATA: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 18i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_OIS: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 32i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_OPTIMIZATIONHINT: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 10i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOCONFIRMATION: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 23i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOFRAMERATE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 1i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMAXFRAMERATE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 2i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMODE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 0i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOTHUMBNAIL: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 6i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOTRIGGERTIME: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 3i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 34i32;\npub type KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_RELATIVEPANELOPTIMIZATION: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 39i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_ROI_CONFIGCAPS: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 21i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_ROI_ISPCONTROL: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 22i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_SCENEMODE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 7i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_SECURE_MODE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 36i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_TORCHMODE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 8i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_VFR: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 28i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOHDR: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 30i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOSTABILIZATION: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 27i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 37i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_WARMSTART: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 4i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_WHITEBALANCEMODE: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 11i32;\npub const KSPROPERTY_CAMERACONTROL_EXTENDED_ZOOM: KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY = 24i32;\npub const KSPROPERTY_CAMERACONTROL_FLAGS_ABSOLUTE: i32 = 0i32;\npub const KSPROPERTY_CAMERACONTROL_FLAGS_ASYNCHRONOUS: i32 = 4i32;\npub const KSPROPERTY_CAMERACONTROL_FLAGS_AUTO: i32 = 1i32;\npub const KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL: i32 = 2i32;\npub const KSPROPERTY_CAMERACONTROL_FLAGS_RELATIVE: i32 = 16i32;\npub type KSPROPERTY_CAMERACONTROL_FLASH = i32;\npub const KSPROPERTY_CAMERACONTROL_FLASH_AUTO: i32 = 2i32;\npub const KSPROPERTY_CAMERACONTROL_FLASH_FLAGS_AUTO: i32 = 1i32;\npub const KSPROPERTY_CAMERACONTROL_FLASH_FLAGS_MANUAL: i32 = 2i32;\npub const KSPROPERTY_CAMERACONTROL_FLASH_OFF: i32 = 0i32;\npub const KSPROPERTY_CAMERACONTROL_FLASH_ON: i32 = 1i32;\npub const KSPROPERTY_CAMERACONTROL_FLASH_PROPERTY_ID: KSPROPERTY_CAMERACONTROL_FLASH = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_CAMERACONTROL_FLASH_S {\n    pub Flash: u32,\n    pub Capabilities: u32,\n}\npub const KSPROPERTY_CAMERACONTROL_FOCAL_LENGTH: KSPROPERTY_VIDCAP_CAMERACONTROL = 18i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CAMERACONTROL_FOCAL_LENGTH_S {\n    pub Property: KSIDENTIFIER,\n    pub lOcularFocalLength: i32,\n    pub lObjectiveFocalLengthMin: i32,\n    pub lObjectiveFocalLengthMax: i32,\n}\nimpl Default for KSPROPERTY_CAMERACONTROL_FOCAL_LENGTH_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_CAMERACONTROL_FOCUS: KSPROPERTY_VIDCAP_CAMERACONTROL = 6i32;\npub const KSPROPERTY_CAMERACONTROL_FOCUS_RELATIVE: KSPROPERTY_VIDCAP_CAMERACONTROL = 16i32;\npub type KSPROPERTY_CAMERACONTROL_IMAGE_PIN_CAPABILITY = i32;\npub const KSPROPERTY_CAMERACONTROL_IMAGE_PIN_CAPABILITY_EXCLUSIVE_WITH_RECORD: i32 = 1i32;\npub const KSPROPERTY_CAMERACONTROL_IMAGE_PIN_CAPABILITY_PROPERTY_ID: KSPROPERTY_CAMERACONTROL_IMAGE_PIN_CAPABILITY = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_CAMERACONTROL_IMAGE_PIN_CAPABILITY_S {\n    pub Capabilities: u32,\n    pub Reserved0: u32,\n}\npub const KSPROPERTY_CAMERACONTROL_IMAGE_PIN_CAPABILITY_SEQUENCE_EXCLUSIVE_WITH_RECORD: i32 = 2i32;\npub const KSPROPERTY_CAMERACONTROL_IRIS: KSPROPERTY_VIDCAP_CAMERACONTROL = 5i32;\npub const KSPROPERTY_CAMERACONTROL_IRIS_RELATIVE: KSPROPERTY_VIDCAP_CAMERACONTROL = 15i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CAMERACONTROL_NODE_FOCAL_LENGTH_S {\n    pub NodeProperty: KSNODEPROPERTY,\n    pub lOcularFocalLength: i32,\n    pub lObjectiveFocalLengthMin: i32,\n    pub lObjectiveFocalLengthMax: i32,\n}\nimpl Default for KSPROPERTY_CAMERACONTROL_NODE_FOCAL_LENGTH_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CAMERACONTROL_NODE_S {\n    pub NodeProperty: KSP_NODE,\n    pub Value: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n}\nimpl Default for KSPROPERTY_CAMERACONTROL_NODE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CAMERACONTROL_NODE_S2 {\n    pub NodeProperty: KSP_NODE,\n    pub Value1: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n    pub Value2: i32,\n}\nimpl Default for KSPROPERTY_CAMERACONTROL_NODE_S2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_CAMERACONTROL_PAN: KSPROPERTY_VIDCAP_CAMERACONTROL = 0i32;\npub const KSPROPERTY_CAMERACONTROL_PANTILT: KSPROPERTY_VIDCAP_CAMERACONTROL = 9i32;\npub const KSPROPERTY_CAMERACONTROL_PANTILT_RELATIVE: KSPROPERTY_VIDCAP_CAMERACONTROL = 17i32;\npub const KSPROPERTY_CAMERACONTROL_PAN_RELATIVE: KSPROPERTY_VIDCAP_CAMERACONTROL = 10i32;\npub const KSPROPERTY_CAMERACONTROL_PERFRAMESETTING_CAPABILITY: KSPROPERTY_CAMERACONTROL_PERFRAMESETTING_PROPERTY = 0i32;\npub const KSPROPERTY_CAMERACONTROL_PERFRAMESETTING_CLEAR: KSPROPERTY_CAMERACONTROL_PERFRAMESETTING_PROPERTY = 2i32;\npub type KSPROPERTY_CAMERACONTROL_PERFRAMESETTING_PROPERTY = i32;\npub const KSPROPERTY_CAMERACONTROL_PERFRAMESETTING_SET: KSPROPERTY_CAMERACONTROL_PERFRAMESETTING_PROPERTY = 1i32;\npub const KSPROPERTY_CAMERACONTROL_PRIVACY: KSPROPERTY_VIDCAP_CAMERACONTROL = 8i32;\npub type KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST = i32;\npub const KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_CONFIG_EXPOSURE: i32 = 512i32;\npub const KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_CONFIG_FOCUS: i32 = 256i32;\npub const KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_CONFIG_WB: i32 = 1024i32;\npub const KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_CONVERGEMODE: i32 = 1073741824i32;\npub const KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_FLAGS_ASYNC: i32 = -2147483648i32;\npub const KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_FLAGS_AUTO: i32 = 1i32;\npub const KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_FLAGS_MANUAL: i32 = 2i32;\npub const KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_PROPERTY_ID: KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S {\n    pub FocusRect: super::super::Foundation::RECT,\n    pub AutoFocusLock: windows_sys::core::BOOL,\n    pub AutoExposureLock: windows_sys::core::BOOL,\n    pub AutoWhitebalanceLock: windows_sys::core::BOOL,\n    pub Anonymous: KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S_0,\n}\nimpl Default for KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S_0 {\n    pub Capabilities: u32,\n    pub Configuration: u32,\n}\nimpl Default for KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_CAMERACONTROL_ROLL: KSPROPERTY_VIDCAP_CAMERACONTROL = 2i32;\npub const KSPROPERTY_CAMERACONTROL_ROLL_RELATIVE: KSPROPERTY_VIDCAP_CAMERACONTROL = 12i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CAMERACONTROL_S {\n    pub Property: KSIDENTIFIER,\n    pub Value: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n}\nimpl Default for KSPROPERTY_CAMERACONTROL_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CAMERACONTROL_S2 {\n    pub Property: KSIDENTIFIER,\n    pub Value1: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n    pub Value2: i32,\n}\nimpl Default for KSPROPERTY_CAMERACONTROL_S2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_CAMERACONTROL_SCANMODE: KSPROPERTY_VIDCAP_CAMERACONTROL = 7i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CAMERACONTROL_S_EX {\n    pub Property: KSIDENTIFIER,\n    pub Value: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n    pub FocusRect: super::super::Foundation::RECT,\n}\nimpl Default for KSPROPERTY_CAMERACONTROL_S_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_CAMERACONTROL_TILT: KSPROPERTY_VIDCAP_CAMERACONTROL = 1i32;\npub const KSPROPERTY_CAMERACONTROL_TILT_RELATIVE: KSPROPERTY_VIDCAP_CAMERACONTROL = 11i32;\npub const KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_AUTO: i32 = 4i32;\npub const KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_FLAGS_AUTO: i32 = 1i32;\npub const KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_FLAGS_MANUAL: i32 = 2i32;\npub const KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_HIGH: i32 = 1i32;\npub const KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_LOW: i32 = 3i32;\npub const KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_MEDIUM: i32 = 2i32;\npub const KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_OFF: i32 = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S {\n    pub VideoStabilizationMode: u32,\n    pub Capabilities: u32,\n}\npub type KSPROPERTY_CAMERACONTROL_VIDEO_STABILIZATION_MODE = i32;\npub const KSPROPERTY_CAMERACONTROL_VIDEO_STABILIZATION_MODE_PROPERTY_ID: KSPROPERTY_CAMERACONTROL_VIDEO_STABILIZATION_MODE = 0i32;\npub const KSPROPERTY_CAMERACONTROL_ZOOM: KSPROPERTY_VIDCAP_CAMERACONTROL = 3i32;\npub const KSPROPERTY_CAMERACONTROL_ZOOM_RELATIVE: KSPROPERTY_VIDCAP_CAMERACONTROL = 13i32;\npub const KSPROPERTY_CAMERA_PHOTOTRIGGERTIME_CLEAR: KSPROPERTY_CAMERA_PHOTOTRIGGERTIME_FLAGS = 0i32;\npub type KSPROPERTY_CAMERA_PHOTOTRIGGERTIME_FLAGS = i32;\npub const KSPROPERTY_CAMERA_PHOTOTRIGGERTIME_SET: KSPROPERTY_CAMERA_PHOTOTRIGGERTIME_FLAGS = 1i32;\npub type KSPROPERTY_CLOCK = i32;\npub const KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME: KSPROPERTY_CLOCK = 3i32;\npub const KSPROPERTY_CLOCK_CORRELATEDTIME: KSPROPERTY_CLOCK = 2i32;\npub const KSPROPERTY_CLOCK_PHYSICALTIME: KSPROPERTY_CLOCK = 1i32;\npub const KSPROPERTY_CLOCK_RESOLUTION: KSPROPERTY_CLOCK = 4i32;\npub const KSPROPERTY_CLOCK_STATE: KSPROPERTY_CLOCK = 5i32;\npub const KSPROPERTY_CLOCK_TIME: KSPROPERTY_CLOCK = 0i32;\npub type KSPROPERTY_CONNECTION = i32;\npub const KSPROPERTY_CONNECTION_ACQUIREORDERING: KSPROPERTY_CONNECTION = 5i32;\npub const KSPROPERTY_CONNECTION_ALLOCATORFRAMING: KSPROPERTY_CONNECTION = 3i32;\npub const KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX: KSPROPERTY_CONNECTION = 6i32;\npub const KSPROPERTY_CONNECTION_DATAFORMAT: KSPROPERTY_CONNECTION = 2i32;\npub const KSPROPERTY_CONNECTION_PRIORITY: KSPROPERTY_CONNECTION = 1i32;\npub const KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT: KSPROPERTY_CONNECTION = 4i32;\npub const KSPROPERTY_CONNECTION_STARTAT: KSPROPERTY_CONNECTION = 7i32;\npub const KSPROPERTY_CONNECTION_STATE: KSPROPERTY_CONNECTION = 0i32;\npub type KSPROPERTY_COPYPROT = i32;\npub const KSPROPERTY_COPY_MACROVISION: KSPROPERTY_COPYPROT = 5i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CROSSBAR_ACTIVE_S {\n    pub Property: KSIDENTIFIER,\n    pub IndexInputPin: u32,\n    pub Active: u32,\n}\nimpl Default for KSPROPERTY_CROSSBAR_ACTIVE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_CROSSBAR_CAN_ROUTE: KSPROPERTY_VIDCAP_CROSSBAR = 2i32;\npub const KSPROPERTY_CROSSBAR_CAPS: KSPROPERTY_VIDCAP_CROSSBAR = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CROSSBAR_CAPS_S {\n    pub Property: KSIDENTIFIER,\n    pub NumberOfInputs: u32,\n    pub NumberOfOutputs: u32,\n}\nimpl Default for KSPROPERTY_CROSSBAR_CAPS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_CROSSBAR_INPUT_ACTIVE: KSPROPERTY_VIDCAP_CROSSBAR = 4i32;\npub const KSPROPERTY_CROSSBAR_PININFO: KSPROPERTY_VIDCAP_CROSSBAR = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CROSSBAR_PININFO_S {\n    pub Property: KSIDENTIFIER,\n    pub Direction: KSPIN_DATAFLOW,\n    pub Index: u32,\n    pub PinType: u32,\n    pub RelatedPinIndex: u32,\n    pub Medium: KSIDENTIFIER,\n}\nimpl Default for KSPROPERTY_CROSSBAR_PININFO_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_CROSSBAR_ROUTE: KSPROPERTY_VIDCAP_CROSSBAR = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_CROSSBAR_ROUTE_S {\n    pub Property: KSIDENTIFIER,\n    pub IndexInputPin: u32,\n    pub IndexOutputPin: u32,\n    pub CanRoute: u32,\n}\nimpl Default for KSPROPERTY_CROSSBAR_ROUTE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_CURRENT_CAPTURE_SURFACE: KSPROPERTY_VIDMEM_TRANSPORT = 3i32;\npub type KSPROPERTY_CYCLIC = i32;\npub const KSPROPERTY_CYCLIC_POSITION: KSPROPERTY_CYCLIC = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_DESCRIPTION {\n    pub AccessFlags: u32,\n    pub DescriptionSize: u32,\n    pub PropTypeSet: KSIDENTIFIER,\n    pub MembersListCount: u32,\n    pub Reserved: u32,\n}\nimpl Default for KSPROPERTY_DESCRIPTION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KSPROPERTY_DIRECTSOUND3DBUFFER = i32;\npub const KSPROPERTY_DIRECTSOUND3DBUFFER_ALL: KSPROPERTY_DIRECTSOUND3DBUFFER = 0i32;\npub const KSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES: KSPROPERTY_DIRECTSOUND3DBUFFER = 3i32;\npub const KSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION: KSPROPERTY_DIRECTSOUND3DBUFFER = 4i32;\npub const KSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME: KSPROPERTY_DIRECTSOUND3DBUFFER = 5i32;\npub const KSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE: KSPROPERTY_DIRECTSOUND3DBUFFER = 7i32;\npub const KSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE: KSPROPERTY_DIRECTSOUND3DBUFFER = 6i32;\npub const KSPROPERTY_DIRECTSOUND3DBUFFER_MODE: KSPROPERTY_DIRECTSOUND3DBUFFER = 8i32;\npub const KSPROPERTY_DIRECTSOUND3DBUFFER_POSITION: KSPROPERTY_DIRECTSOUND3DBUFFER = 1i32;\npub const KSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY: KSPROPERTY_DIRECTSOUND3DBUFFER = 2i32;\npub type KSPROPERTY_DIRECTSOUND3DLISTENER = i32;\npub const KSPROPERTY_DIRECTSOUND3DLISTENER_ALL: KSPROPERTY_DIRECTSOUND3DLISTENER = 0i32;\npub const KSPROPERTY_DIRECTSOUND3DLISTENER_ALLOCATION: KSPROPERTY_DIRECTSOUND3DLISTENER = 8i32;\npub const KSPROPERTY_DIRECTSOUND3DLISTENER_BATCH: KSPROPERTY_DIRECTSOUND3DLISTENER = 7i32;\npub const KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR: KSPROPERTY_DIRECTSOUND3DLISTENER = 4i32;\npub const KSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR: KSPROPERTY_DIRECTSOUND3DLISTENER = 6i32;\npub const KSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION: KSPROPERTY_DIRECTSOUND3DLISTENER = 3i32;\npub const KSPROPERTY_DIRECTSOUND3DLISTENER_POSITION: KSPROPERTY_DIRECTSOUND3DLISTENER = 1i32;\npub const KSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR: KSPROPERTY_DIRECTSOUND3DLISTENER = 5i32;\npub const KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY: KSPROPERTY_DIRECTSOUND3DLISTENER = 2i32;\npub const KSPROPERTY_DISPLAY_ADAPTER_GUID: KSPROPERTY_VIDMEM_TRANSPORT = 1i32;\npub type KSPROPERTY_DRMAUDIOSTREAM = i32;\npub const KSPROPERTY_DRMAUDIOSTREAM_CONTENTID: KSPROPERTY_DRMAUDIOSTREAM = 0i32;\npub const KSPROPERTY_DROPPEDFRAMES_CURRENT: KSPROPERTY_VIDCAP_DROPPEDFRAMES = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_DROPPEDFRAMES_CURRENT_S {\n    pub Property: KSIDENTIFIER,\n    pub PictureNumber: i64,\n    pub DropCount: i64,\n    pub AverageFrameSize: u32,\n}\nimpl Default for KSPROPERTY_DROPPEDFRAMES_CURRENT_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_DVDCOPY_CHLG_KEY: KSPROPERTY_COPYPROT = 1i32;\npub const KSPROPERTY_DVDCOPY_DEC_KEY2: KSPROPERTY_COPYPROT = 3i32;\npub const KSPROPERTY_DVDCOPY_DISC_KEY: KSPROPERTY_COPYPROT = 128i32;\npub const KSPROPERTY_DVDCOPY_DVD_KEY1: KSPROPERTY_COPYPROT = 2i32;\npub const KSPROPERTY_DVDCOPY_REGION: KSPROPERTY_COPYPROT = 6i32;\npub const KSPROPERTY_DVDCOPY_SET_COPY_STATE: KSPROPERTY_COPYPROT = 7i32;\npub const KSPROPERTY_DVDCOPY_TITLE_KEY: KSPROPERTY_COPYPROT = 4i32;\npub type KSPROPERTY_DVDSUBPIC = i32;\npub const KSPROPERTY_DVDSUBPIC_COMPOSIT_ON: KSPROPERTY_DVDSUBPIC = 2i32;\npub const KSPROPERTY_DVDSUBPIC_HLI: KSPROPERTY_DVDSUBPIC = 1i32;\npub const KSPROPERTY_DVDSUBPIC_PALETTE: KSPROPERTY_DVDSUBPIC = 0i32;\npub type KSPROPERTY_EXTDEVICE = i32;\npub const KSPROPERTY_EXTDEVICE_CAPABILITIES: KSPROPERTY_EXTDEVICE = 4i32;\npub const KSPROPERTY_EXTDEVICE_ID: KSPROPERTY_EXTDEVICE = 0i32;\npub const KSPROPERTY_EXTDEVICE_PORT: KSPROPERTY_EXTDEVICE = 3i32;\npub const KSPROPERTY_EXTDEVICE_POWER_STATE: KSPROPERTY_EXTDEVICE = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_EXTDEVICE_S {\n    pub Property: KSIDENTIFIER,\n    pub u: KSPROPERTY_EXTDEVICE_S_0,\n}\nimpl Default for KSPROPERTY_EXTDEVICE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSPROPERTY_EXTDEVICE_S_0 {\n    pub Capabilities: DEVCAPS,\n    pub DevPort: u32,\n    pub PowerState: u32,\n    pub pawchString: [u16; 260],\n    pub NodeUniqueID: [u32; 2],\n}\nimpl Default for KSPROPERTY_EXTDEVICE_S_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_EXTDEVICE_VERSION: KSPROPERTY_EXTDEVICE = 1i32;\npub type KSPROPERTY_EXTENSION_UNIT = i32;\npub const KSPROPERTY_EXTENSION_UNIT_CONTROL: KSPROPERTY_EXTENSION_UNIT = 1i32;\npub const KSPROPERTY_EXTENSION_UNIT_INFO: KSPROPERTY_EXTENSION_UNIT = 0i32;\npub const KSPROPERTY_EXTENSION_UNIT_PASS_THROUGH: KSPROPERTY_EXTENSION_UNIT = 65535i32;\npub type KSPROPERTY_EXTXPORT = i32;\npub const KSPROPERTY_EXTXPORT_ATN_SEARCH: KSPROPERTY_EXTXPORT = 8i32;\npub const KSPROPERTY_EXTXPORT_CAPABILITIES: KSPROPERTY_EXTXPORT = 0i32;\npub const KSPROPERTY_EXTXPORT_INPUT_SIGNAL_MODE: KSPROPERTY_EXTXPORT = 1i32;\npub const KSPROPERTY_EXTXPORT_LOAD_MEDIUM: KSPROPERTY_EXTXPORT = 3i32;\npub const KSPROPERTY_EXTXPORT_MEDIUM_INFO: KSPROPERTY_EXTXPORT = 4i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_EXTXPORT_NODE_S {\n    pub NodeProperty: KSP_NODE,\n    pub u: KSPROPERTY_EXTXPORT_NODE_S_0,\n}\nimpl Default for KSPROPERTY_EXTXPORT_NODE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSPROPERTY_EXTXPORT_NODE_S_0 {\n    pub Capabilities: u32,\n    pub SignalMode: u32,\n    pub LoadMedium: u32,\n    pub MediumInfo: MEDIUM_INFO,\n    pub XPrtState: TRANSPORT_STATE,\n    pub Timecode: KSPROPERTY_EXTXPORT_NODE_S_0_0,\n    pub dwTimecode: u32,\n    pub dwAbsTrackNumber: u32,\n    pub RawAVC: KSPROPERTY_EXTXPORT_NODE_S_0_1,\n}\nimpl Default for KSPROPERTY_EXTXPORT_NODE_S_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_EXTXPORT_NODE_S_0_1 {\n    pub PayloadSize: u32,\n    pub Payload: [u8; 512],\n}\nimpl Default for KSPROPERTY_EXTXPORT_NODE_S_0_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_EXTXPORT_NODE_S_0_0 {\n    pub frame: u8,\n    pub second: u8,\n    pub minute: u8,\n    pub hour: u8,\n}\npub const KSPROPERTY_EXTXPORT_OUTPUT_SIGNAL_MODE: KSPROPERTY_EXTXPORT = 2i32;\npub const KSPROPERTY_EXTXPORT_RTC_SEARCH: KSPROPERTY_EXTXPORT = 9i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_EXTXPORT_S {\n    pub Property: KSIDENTIFIER,\n    pub u: KSPROPERTY_EXTXPORT_S_0,\n}\nimpl Default for KSPROPERTY_EXTXPORT_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSPROPERTY_EXTXPORT_S_0 {\n    pub Capabilities: u32,\n    pub SignalMode: u32,\n    pub LoadMedium: u32,\n    pub MediumInfo: MEDIUM_INFO,\n    pub XPrtState: TRANSPORT_STATE,\n    pub Timecode: KSPROPERTY_EXTXPORT_S_0_0,\n    pub dwTimecode: u32,\n    pub dwAbsTrackNumber: u32,\n    pub RawAVC: KSPROPERTY_EXTXPORT_S_0_1,\n}\nimpl Default for KSPROPERTY_EXTXPORT_S_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_EXTXPORT_S_0_1 {\n    pub PayloadSize: u32,\n    pub Payload: [u8; 512],\n}\nimpl Default for KSPROPERTY_EXTXPORT_S_0_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_EXTXPORT_S_0_0 {\n    pub frame: u8,\n    pub second: u8,\n    pub minute: u8,\n    pub hour: u8,\n}\npub const KSPROPERTY_EXTXPORT_STATE: KSPROPERTY_EXTXPORT = 5i32;\npub const KSPROPERTY_EXTXPORT_STATE_NOTIFY: KSPROPERTY_EXTXPORT = 6i32;\npub const KSPROPERTY_EXTXPORT_TIMECODE_SEARCH: KSPROPERTY_EXTXPORT = 7i32;\npub const KSPROPERTY_FMRX_ANTENNAENDPOINTID: KSPROPERTY_FMRX_TOPOLOGY = 2i32;\npub type KSPROPERTY_FMRX_CONTROL = i32;\npub const KSPROPERTY_FMRX_ENDPOINTID: KSPROPERTY_FMRX_TOPOLOGY = 0i32;\npub const KSPROPERTY_FMRX_STATE: KSPROPERTY_FMRX_CONTROL = 0i32;\npub type KSPROPERTY_FMRX_TOPOLOGY = i32;\npub const KSPROPERTY_FMRX_VOLUME: KSPROPERTY_FMRX_TOPOLOGY = 1i32;\npub type KSPROPERTY_GENERAL = i32;\npub const KSPROPERTY_GENERAL_COMPONENTID: KSPROPERTY_GENERAL = 0i32;\npub type KSPROPERTY_HRTF3D = i32;\npub const KSPROPERTY_HRTF3D_FILTER_FORMAT: KSPROPERTY_HRTF3D = 2i32;\npub const KSPROPERTY_HRTF3D_INITIALIZE: KSPROPERTY_HRTF3D = 1i32;\npub const KSPROPERTY_HRTF3D_PARAMS: KSPROPERTY_HRTF3D = 0i32;\npub type KSPROPERTY_INTERLEAVEDAUDIO = i32;\npub const KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION: KSPROPERTY_INTERLEAVEDAUDIO = 1i32;\npub type KSPROPERTY_ITD3D = i32;\npub const KSPROPERTY_ITD3D_PARAMS: KSPROPERTY_ITD3D = 0i32;\npub type KSPROPERTY_JACK = i32;\npub const KSPROPERTY_JACK_CONTAINERID: KSPROPERTY_JACK = 4i32;\npub const KSPROPERTY_JACK_DESCRIPTION: KSPROPERTY_JACK = 1i32;\npub const KSPROPERTY_JACK_DESCRIPTION2: KSPROPERTY_JACK = 2i32;\npub const KSPROPERTY_JACK_DESCRIPTION3: KSPROPERTY_JACK = 5i32;\npub const KSPROPERTY_JACK_SINK_INFO: KSPROPERTY_JACK = 3i32;\npub const KSPROPERTY_MAP_CAPTURE_HANDLE_TO_VRAM_ADDRESS: KSPROPERTY_VIDMEM_TRANSPORT = 4i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_MEDIAAVAILABLE {\n    pub Earliest: i64,\n    pub Latest: i64,\n}\npub type KSPROPERTY_MEDIASEEKING = i32;\npub const KSPROPERTY_MEDIASEEKING_AVAILABLE: KSPROPERTY_MEDIASEEKING = 7i32;\npub const KSPROPERTY_MEDIASEEKING_CAPABILITIES: KSPROPERTY_MEDIASEEKING = 0i32;\npub const KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT: KSPROPERTY_MEDIASEEKING = 9i32;\npub const KSPROPERTY_MEDIASEEKING_DURATION: KSPROPERTY_MEDIASEEKING = 6i32;\npub const KSPROPERTY_MEDIASEEKING_FORMATS: KSPROPERTY_MEDIASEEKING = 1i32;\npub const KSPROPERTY_MEDIASEEKING_POSITION: KSPROPERTY_MEDIASEEKING = 3i32;\npub const KSPROPERTY_MEDIASEEKING_POSITIONS: KSPROPERTY_MEDIASEEKING = 5i32;\npub const KSPROPERTY_MEDIASEEKING_PREROLL: KSPROPERTY_MEDIASEEKING = 8i32;\npub const KSPROPERTY_MEDIASEEKING_STOPPOSITION: KSPROPERTY_MEDIASEEKING = 4i32;\npub const KSPROPERTY_MEDIASEEKING_TIMEFORMAT: KSPROPERTY_MEDIASEEKING = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_MEMBERSHEADER {\n    pub MembersFlags: u32,\n    pub MembersSize: u32,\n    pub MembersCount: u32,\n    pub Flags: u32,\n}\npub const KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL: u32 = 2u32;\npub const KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM: u32 = 4u32;\npub const KSPROPERTY_MEMBER_FLAG_DEFAULT: u32 = 1u32;\npub const KSPROPERTY_MEMBER_RANGES: u32 = 1u32;\npub const KSPROPERTY_MEMBER_STEPPEDRANGES: u32 = 2u32;\npub const KSPROPERTY_MEMBER_VALUES: u32 = 3u32;\npub const KSPROPERTY_MEMORY_TRANSPORT: i32 = 1i32;\npub type KSPROPERTY_MPEG2VID = i32;\npub const KSPROPERTY_MPEG2VID_16_9_PANSCAN: KSPROPERTY_MPEG2VID = 4i32;\npub const KSPROPERTY_MPEG2VID_16_9_RECT: KSPROPERTY_MPEG2VID = 3i32;\npub const KSPROPERTY_MPEG2VID_4_3_RECT: KSPROPERTY_MPEG2VID = 2i32;\npub const KSPROPERTY_MPEG2VID_CUR_MODE: KSPROPERTY_MPEG2VID = 1i32;\npub const KSPROPERTY_MPEG2VID_MODES: KSPROPERTY_MPEG2VID = 0i32;\npub type KSPROPERTY_MPEG4_MEDIATYPE_ATTRIBUTES = i32;\npub const KSPROPERTY_MPEG4_MEDIATYPE_SD_BOX: KSPROPERTY_MPEG4_MEDIATYPE_ATTRIBUTES = 1i32;\npub const KSPROPERTY_NETWORKCAMERACONTROL_EVENTTOPICS_XML: KSPROPERTY_NETWORKCAMERACONTROL_PROPERTY = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_NETWORKCAMERACONTROL_EVENT_INFO {\n    pub Header: KSCAMERA_METADATA_ITEMHEADER,\n    pub EventFilter: [u16; 1],\n}\nimpl Default for KSPROPERTY_NETWORKCAMERACONTROL_EVENT_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_NETWORKCAMERACONTROL_METADATA: KSPROPERTY_NETWORKCAMERACONTROL_PROPERTY = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_NETWORKCAMERACONTROL_METADATA_INFO {\n    pub MetadataItems: u32,\n    pub Size: u32,\n    pub PTZStatus: windows_sys::core::BOOL,\n    pub Events: windows_sys::core::BOOL,\n    pub Analytics: windows_sys::core::BOOL,\n    pub Reserved: windows_sys::core::BOOL,\n}\npub type KSPROPERTY_NETWORKCAMERACONTROL_METADATA_TYPE = i32;\npub const KSPROPERTY_NETWORKCAMERACONTROL_METADATA_TYPE_EVENTSINFO: KSPROPERTY_NETWORKCAMERACONTROL_METADATA_TYPE = 0i32;\npub const KSPROPERTY_NETWORKCAMERACONTROL_NTP: KSPROPERTY_NETWORKCAMERACONTROL_PROPERTY = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_NETWORKCAMERACONTROL_NTPINFO_HEADER {\n    pub Size: u32,\n    pub Type: KSPROPERTY_NETWORKCAMERACONTROL_NTPINFO_TYPE,\n}\npub type KSPROPERTY_NETWORKCAMERACONTROL_NTPINFO_TYPE = i32;\npub const KSPROPERTY_NETWORKCAMERACONTROL_NTPINFO_TYPE_CUSTOM: KSPROPERTY_NETWORKCAMERACONTROL_NTPINFO_TYPE = 2i32;\npub const KSPROPERTY_NETWORKCAMERACONTROL_NTPINFO_TYPE_DISABLE: KSPROPERTY_NETWORKCAMERACONTROL_NTPINFO_TYPE = 0i32;\npub const KSPROPERTY_NETWORKCAMERACONTROL_NTPINFO_TYPE_HOSTNTP: KSPROPERTY_NETWORKCAMERACONTROL_NTPINFO_TYPE = 1i32;\npub type KSPROPERTY_NETWORKCAMERACONTROL_PROPERTY = i32;\npub const KSPROPERTY_NETWORKCAMERACONTROL_URI: KSPROPERTY_NETWORKCAMERACONTROL_PROPERTY = 1i32;\npub const KSPROPERTY_ONESHOT_DISCONNECT: KSPROPERTY_BTAUDIO = 1i32;\npub const KSPROPERTY_ONESHOT_RECONNECT: KSPROPERTY_BTAUDIO = 0i32;\npub type KSPROPERTY_OVERLAYUPDATE = i32;\npub const KSPROPERTY_OVERLAYUPDATE_CLIPLIST: KSPROPERTY_OVERLAYUPDATE = 1i32;\npub const KSPROPERTY_OVERLAYUPDATE_COLORKEY: KSPROPERTY_OVERLAYUPDATE = 4i32;\npub const KSPROPERTY_OVERLAYUPDATE_COLORREF: KSPROPERTY_OVERLAYUPDATE = 268435456i32;\npub const KSPROPERTY_OVERLAYUPDATE_DISPLAYCHANGE: KSPROPERTY_OVERLAYUPDATE = 16i32;\npub const KSPROPERTY_OVERLAYUPDATE_INTERESTS: KSPROPERTY_OVERLAYUPDATE = 0i32;\npub const KSPROPERTY_OVERLAYUPDATE_PALETTE: KSPROPERTY_OVERLAYUPDATE = 2i32;\npub const KSPROPERTY_OVERLAYUPDATE_VIDEOPOSITION: KSPROPERTY_OVERLAYUPDATE = 8i32;\npub type KSPROPERTY_PIN = i32;\npub const KSPROPERTY_PIN_CATEGORY: KSPROPERTY_PIN = 11i32;\npub const KSPROPERTY_PIN_CINSTANCES: KSPROPERTY_PIN = 0i32;\npub const KSPROPERTY_PIN_COMMUNICATION: KSPROPERTY_PIN = 7i32;\npub const KSPROPERTY_PIN_CONSTRAINEDDATARANGES: KSPROPERTY_PIN = 13i32;\npub const KSPROPERTY_PIN_CTYPES: KSPROPERTY_PIN = 1i32;\npub const KSPROPERTY_PIN_DATAFLOW: KSPROPERTY_PIN = 2i32;\npub const KSPROPERTY_PIN_DATAINTERSECTION: KSPROPERTY_PIN = 4i32;\npub const KSPROPERTY_PIN_DATARANGES: KSPROPERTY_PIN = 3i32;\npub const KSPROPERTY_PIN_FLAGS_ATTRIBUTE_RANGE_AWARE: u32 = 1u32;\npub const KSPROPERTY_PIN_FLAGS_MASK: u32 = 1u32;\npub const KSPROPERTY_PIN_GLOBALCINSTANCES: KSPROPERTY_PIN = 8i32;\npub const KSPROPERTY_PIN_INTERFACES: KSPROPERTY_PIN = 5i32;\npub const KSPROPERTY_PIN_MEDIUMS: KSPROPERTY_PIN = 6i32;\npub const KSPROPERTY_PIN_MODEDATAFORMATS: KSPROPERTY_PIN = 16i32;\npub const KSPROPERTY_PIN_NAME: KSPROPERTY_PIN = 12i32;\npub const KSPROPERTY_PIN_NECESSARYINSTANCES: KSPROPERTY_PIN = 9i32;\npub const KSPROPERTY_PIN_PHYSICALCONNECTION: KSPROPERTY_PIN = 10i32;\npub const KSPROPERTY_PIN_PROPOSEDATAFORMAT: KSPROPERTY_PIN = 14i32;\npub const KSPROPERTY_PIN_PROPOSEDATAFORMAT2: KSPROPERTY_PIN = 15i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_POSITIONS {\n    pub Current: i64,\n    pub Stop: i64,\n    pub CurrentFlags: KS_SEEKING_FLAGS,\n    pub StopFlags: KS_SEEKING_FLAGS,\n}\npub const KSPROPERTY_PREFERRED_CAPTURE_SURFACE: KSPROPERTY_VIDMEM_TRANSPORT = 2i32;\npub type KSPROPERTY_QUALITY = i32;\npub const KSPROPERTY_QUALITY_ERROR: KSPROPERTY_QUALITY = 1i32;\npub const KSPROPERTY_QUALITY_REPORT: KSPROPERTY_QUALITY = 0i32;\npub const KSPROPERTY_RAW_AVC_CMD: KSPROPERTY_EXTXPORT = 10i32;\npub type KSPROPERTY_RTAUDIO = i32;\npub const KSPROPERTY_RTAUDIO_BUFFER: KSPROPERTY_RTAUDIO = 1i32;\npub const KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION: KSPROPERTY_RTAUDIO = 5i32;\npub const KSPROPERTY_RTAUDIO_CLOCKREGISTER: KSPROPERTY_RTAUDIO = 4i32;\npub const KSPROPERTY_RTAUDIO_GETPOSITIONFUNCTION: KSPROPERTY_RTAUDIO = 0i32;\npub const KSPROPERTY_RTAUDIO_GETREADPACKET: KSPROPERTY_RTAUDIO = 11i32;\npub const KSPROPERTY_RTAUDIO_HWLATENCY: KSPROPERTY_RTAUDIO = 2i32;\npub const KSPROPERTY_RTAUDIO_PACKETCOUNT: KSPROPERTY_RTAUDIO = 9i32;\npub const KSPROPERTY_RTAUDIO_PACKETVREGISTER: KSPROPERTY_RTAUDIO = 13i32;\npub const KSPROPERTY_RTAUDIO_POSITIONREGISTER: KSPROPERTY_RTAUDIO = 3i32;\npub const KSPROPERTY_RTAUDIO_PRESENTATION_POSITION: KSPROPERTY_RTAUDIO = 10i32;\npub const KSPROPERTY_RTAUDIO_QUERY_NOTIFICATION_SUPPORT: KSPROPERTY_RTAUDIO = 8i32;\npub const KSPROPERTY_RTAUDIO_REGISTER_NOTIFICATION_EVENT: KSPROPERTY_RTAUDIO = 6i32;\npub const KSPROPERTY_RTAUDIO_SETWRITEPACKET: KSPROPERTY_RTAUDIO = 12i32;\npub const KSPROPERTY_RTAUDIO_UNREGISTER_NOTIFICATION_EVENT: KSPROPERTY_RTAUDIO = 7i32;\npub const KSPROPERTY_RTC_READER: KSPROPERTY_TIMECODE = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_SELECTOR_NODE_S {\n    pub NodeProperty: KSP_NODE,\n    pub Value: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n}\nimpl Default for KSPROPERTY_SELECTOR_NODE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_SELECTOR_NUM_SOURCES: KSPROPERTY_VIDCAP_SELECTOR = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_SELECTOR_S {\n    pub Property: KSIDENTIFIER,\n    pub Value: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n}\nimpl Default for KSPROPERTY_SELECTOR_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_SELECTOR_SOURCE_NODE_ID: KSPROPERTY_VIDCAP_SELECTOR = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_SERIAL {\n    pub PropTypeSet: KSIDENTIFIER,\n    pub Id: u32,\n    pub PropertyLength: u32,\n}\nimpl Default for KSPROPERTY_SERIAL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_SERIALHDR {\n    pub PropertySet: windows_sys::core::GUID,\n    pub Count: u32,\n}\npub type KSPROPERTY_SOUNDDETECTOR = i32;\npub const KSPROPERTY_SOUNDDETECTOR_ARMED: KSPROPERTY_SOUNDDETECTOR = 3i32;\npub const KSPROPERTY_SOUNDDETECTOR_MATCHRESULT: KSPROPERTY_SOUNDDETECTOR = 4i32;\npub const KSPROPERTY_SOUNDDETECTOR_PATTERNS: KSPROPERTY_SOUNDDETECTOR = 2i32;\npub const KSPROPERTY_SOUNDDETECTOR_RESET: KSPROPERTY_SOUNDDETECTOR = 5i32;\npub const KSPROPERTY_SOUNDDETECTOR_STREAMINGSUPPORT: KSPROPERTY_SOUNDDETECTOR = 6i32;\npub const KSPROPERTY_SOUNDDETECTOR_SUPPORTEDPATTERNS: KSPROPERTY_SOUNDDETECTOR = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSPROPERTY_SPHLI {\n    pub HLISS: u16,\n    pub Reserved: u16,\n    pub StartPTM: u32,\n    pub EndPTM: u32,\n    pub StartX: u16,\n    pub StartY: u16,\n    pub StopX: u16,\n    pub StopY: u16,\n    pub ColCon: KS_COLCON,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_SPPAL {\n    pub sppal: [KS_DVD_YUV; 16],\n}\nimpl Default for KSPROPERTY_SPPAL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_STEPPING_LONG {\n    pub SteppingDelta: u32,\n    pub Reserved: u32,\n    pub Bounds: KSPROPERTY_BOUNDS_LONG,\n}\nimpl Default for KSPROPERTY_STEPPING_LONG {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_STEPPING_LONGLONG {\n    pub SteppingDelta: u64,\n    pub Bounds: KSPROPERTY_BOUNDS_LONGLONG,\n}\nimpl Default for KSPROPERTY_STEPPING_LONGLONG {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KSPROPERTY_STREAM = i32;\npub type KSPROPERTY_STREAMINTERFACE = i32;\npub const KSPROPERTY_STREAMINTERFACE_HEADERSIZE: KSPROPERTY_STREAMINTERFACE = 0i32;\npub const KSPROPERTY_STREAM_ALLOCATOR: KSPROPERTY_STREAM = 0i32;\npub const KSPROPERTY_STREAM_DEGRADATION: KSPROPERTY_STREAM = 2i32;\npub const KSPROPERTY_STREAM_FRAMETIME: KSPROPERTY_STREAM = 7i32;\npub const KSPROPERTY_STREAM_MASTERCLOCK: KSPROPERTY_STREAM = 3i32;\npub const KSPROPERTY_STREAM_PIPE_ID: KSPROPERTY_STREAM = 10i32;\npub const KSPROPERTY_STREAM_PRESENTATIONEXTENT: KSPROPERTY_STREAM = 6i32;\npub const KSPROPERTY_STREAM_PRESENTATIONTIME: KSPROPERTY_STREAM = 5i32;\npub const KSPROPERTY_STREAM_QUALITY: KSPROPERTY_STREAM = 1i32;\npub const KSPROPERTY_STREAM_RATE: KSPROPERTY_STREAM = 9i32;\npub const KSPROPERTY_STREAM_RATECAPABILITY: KSPROPERTY_STREAM = 8i32;\npub const KSPROPERTY_STREAM_TIMEFORMAT: KSPROPERTY_STREAM = 4i32;\npub const KSPROPERTY_TELEPHONY_CALLCONTROL: KSPROPERTY_TELEPHONY_CONTROL = 2i32;\npub const KSPROPERTY_TELEPHONY_CALLHOLD: KSPROPERTY_TELEPHONY_CONTROL = 4i32;\npub const KSPROPERTY_TELEPHONY_CALLINFO: KSPROPERTY_TELEPHONY_CONTROL = 1i32;\npub type KSPROPERTY_TELEPHONY_CONTROL = i32;\npub const KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR: KSPROPERTY_TELEPHONY_TOPOLOGY = 0i32;\npub const KSPROPERTY_TELEPHONY_MUTE_TX: KSPROPERTY_TELEPHONY_CONTROL = 5i32;\npub const KSPROPERTY_TELEPHONY_PROVIDERCHANGE: KSPROPERTY_TELEPHONY_CONTROL = 3i32;\npub const KSPROPERTY_TELEPHONY_PROVIDERID: KSPROPERTY_TELEPHONY_CONTROL = 0i32;\npub type KSPROPERTY_TELEPHONY_TOPOLOGY = i32;\npub const KSPROPERTY_TELEPHONY_VOLUME: KSPROPERTY_TELEPHONY_TOPOLOGY = 1i32;\npub type KSPROPERTY_TIMECODE = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TIMECODE_NODE_S {\n    pub NodeProperty: KSP_NODE,\n    pub TimecodeSamp: super::TIMECODE_SAMPLE,\n}\nimpl Default for KSPROPERTY_TIMECODE_NODE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TIMECODE_READER: KSPROPERTY_TIMECODE = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TIMECODE_S {\n    pub Property: KSIDENTIFIER,\n    pub TimecodeSamp: super::TIMECODE_SAMPLE,\n}\nimpl Default for KSPROPERTY_TIMECODE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KSPROPERTY_TOPOLOGY = i32;\npub type KSPROPERTY_TOPOLOGYNODE = i32;\npub const KSPROPERTY_TOPOLOGYNODE_ENABLE: KSPROPERTY_TOPOLOGYNODE = 1i32;\npub const KSPROPERTY_TOPOLOGYNODE_RESET: KSPROPERTY_TOPOLOGYNODE = 2i32;\npub const KSPROPERTY_TOPOLOGY_CATEGORIES: KSPROPERTY_TOPOLOGY = 0i32;\npub const KSPROPERTY_TOPOLOGY_CONNECTIONS: KSPROPERTY_TOPOLOGY = 2i32;\npub const KSPROPERTY_TOPOLOGY_NAME: KSPROPERTY_TOPOLOGY = 3i32;\npub const KSPROPERTY_TOPOLOGY_NODES: KSPROPERTY_TOPOLOGY = 1i32;\npub type KSPROPERTY_TUNER = i32;\npub const KSPROPERTY_TUNER_CAPS: KSPROPERTY_TUNER = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_CAPS_S {\n    pub Property: KSIDENTIFIER,\n    pub ModesSupported: u32,\n    pub VideoMedium: KSIDENTIFIER,\n    pub TVAudioMedium: KSIDENTIFIER,\n    pub RadioAudioMedium: KSIDENTIFIER,\n}\nimpl Default for KSPROPERTY_TUNER_CAPS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TUNER_FREQUENCY: KSPROPERTY_TUNER = 4i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_FREQUENCY_S {\n    pub Property: KSIDENTIFIER,\n    pub Frequency: u32,\n    pub LastFrequency: u32,\n    pub TuningFlags: u32,\n    pub VideoSubChannel: u32,\n    pub AudioSubChannel: u32,\n    pub Channel: u32,\n    pub Country: u32,\n}\nimpl Default for KSPROPERTY_TUNER_FREQUENCY_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TUNER_IF_MEDIUM: KSPROPERTY_TUNER = 7i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_IF_MEDIUM_S {\n    pub Property: KSIDENTIFIER,\n    pub IFMedium: KSIDENTIFIER,\n}\nimpl Default for KSPROPERTY_TUNER_IF_MEDIUM_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TUNER_INPUT: KSPROPERTY_TUNER = 5i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_INPUT_S {\n    pub Property: KSIDENTIFIER,\n    pub InputIndex: u32,\n}\nimpl Default for KSPROPERTY_TUNER_INPUT_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TUNER_MODE: KSPROPERTY_TUNER = 2i32;\npub type KSPROPERTY_TUNER_MODES = i32;\npub const KSPROPERTY_TUNER_MODE_AM_RADIO: KSPROPERTY_TUNER_MODES = 4i32;\npub const KSPROPERTY_TUNER_MODE_ATSC: KSPROPERTY_TUNER_MODES = 16i32;\npub const KSPROPERTY_TUNER_MODE_CAPS: KSPROPERTY_TUNER = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_MODE_CAPS_S {\n    pub Property: KSIDENTIFIER,\n    pub Mode: u32,\n    pub StandardsSupported: u32,\n    pub MinFrequency: u32,\n    pub MaxFrequency: u32,\n    pub TuningGranularity: u32,\n    pub NumberOfInputs: u32,\n    pub SettlingTime: u32,\n    pub Strategy: u32,\n}\nimpl Default for KSPROPERTY_TUNER_MODE_CAPS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TUNER_MODE_DSS: KSPROPERTY_TUNER_MODES = 8i32;\npub const KSPROPERTY_TUNER_MODE_FM_RADIO: KSPROPERTY_TUNER_MODES = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_MODE_S {\n    pub Property: KSIDENTIFIER,\n    pub Mode: u32,\n}\nimpl Default for KSPROPERTY_TUNER_MODE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TUNER_MODE_TV: KSPROPERTY_TUNER_MODES = 1i32;\npub const KSPROPERTY_TUNER_NETWORKTYPE_SCAN_CAPS: KSPROPERTY_TUNER = 11i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_NETWORKTYPE_SCAN_CAPS_S {\n    pub Property: KSIDENTIFIER,\n    pub NetworkType: windows_sys::core::GUID,\n    pub BufferSize: u32,\n    pub NetworkTunerCapabilities: *mut core::ffi::c_void,\n}\nimpl Default for KSPROPERTY_TUNER_NETWORKTYPE_SCAN_CAPS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TUNER_SCAN_CAPS: KSPROPERTY_TUNER = 8i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_SCAN_CAPS_S {\n    pub Property: KSIDENTIFIER,\n    pub fSupportsHardwareAssistedScanning: windows_sys::core::BOOL,\n    pub SupportedBroadcastStandards: u32,\n    pub GUIDBucket: *mut core::ffi::c_void,\n    pub lengthofBucket: u32,\n}\nimpl Default for KSPROPERTY_TUNER_SCAN_CAPS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TUNER_SCAN_STATUS: KSPROPERTY_TUNER = 9i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_SCAN_STATUS_S {\n    pub Property: KSIDENTIFIER,\n    pub LockStatus: TunerLockType,\n    pub CurrentFrequency: u32,\n}\nimpl Default for KSPROPERTY_TUNER_SCAN_STATUS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TUNER_STANDARD: KSPROPERTY_TUNER = 3i32;\npub const KSPROPERTY_TUNER_STANDARD_MODE: KSPROPERTY_TUNER = 10i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_STANDARD_MODE_S {\n    pub Property: KSIDENTIFIER,\n    pub AutoDetect: windows_sys::core::BOOL,\n}\nimpl Default for KSPROPERTY_TUNER_STANDARD_MODE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_STANDARD_S {\n    pub Property: KSIDENTIFIER,\n    pub Standard: u32,\n}\nimpl Default for KSPROPERTY_TUNER_STANDARD_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TUNER_STATUS: KSPROPERTY_TUNER = 6i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TUNER_STATUS_S {\n    pub Property: KSIDENTIFIER,\n    pub CurrentFrequency: u32,\n    pub PLLOffset: u32,\n    pub SignalStrength: u32,\n    pub Busy: u32,\n}\nimpl Default for KSPROPERTY_TUNER_STATUS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TVAUDIO_CAPS: KSPROPERTY_VIDCAP_TVAUDIO = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TVAUDIO_CAPS_S {\n    pub Property: KSIDENTIFIER,\n    pub Capabilities: u32,\n    pub InputMedium: KSIDENTIFIER,\n    pub OutputMedium: KSIDENTIFIER,\n}\nimpl Default for KSPROPERTY_TVAUDIO_CAPS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TVAUDIO_CURRENTLY_AVAILABLE_MODES: KSPROPERTY_VIDCAP_TVAUDIO = 2i32;\npub const KSPROPERTY_TVAUDIO_MODE: KSPROPERTY_VIDCAP_TVAUDIO = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_TVAUDIO_S {\n    pub Property: KSIDENTIFIER,\n    pub Mode: u32,\n}\nimpl Default for KSPROPERTY_TVAUDIO_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_TYPE_BASICSUPPORT: u32 = 512u32;\npub const KSPROPERTY_TYPE_COPYPAYLOAD: u32 = 2147483648u32;\npub const KSPROPERTY_TYPE_DEFAULTVALUES: u32 = 65536u32;\npub const KSPROPERTY_TYPE_FSFILTERSCOPE: u32 = 1073741824u32;\npub const KSPROPERTY_TYPE_GET: u32 = 1u32;\npub const KSPROPERTY_TYPE_GETPAYLOADSIZE: u32 = 4u32;\npub const KSPROPERTY_TYPE_HIGHPRIORITY: u32 = 134217728u32;\npub const KSPROPERTY_TYPE_RELATIONS: u32 = 1024u32;\npub const KSPROPERTY_TYPE_SERIALIZERAW: u32 = 8192u32;\npub const KSPROPERTY_TYPE_SERIALIZESET: u32 = 2048u32;\npub const KSPROPERTY_TYPE_SERIALIZESIZE: u32 = 32768u32;\npub const KSPROPERTY_TYPE_SET: u32 = 2u32;\npub const KSPROPERTY_TYPE_SETSUPPORT: u32 = 256u32;\npub const KSPROPERTY_TYPE_TOPOLOGY: u32 = 268435456u32;\npub const KSPROPERTY_TYPE_UNSERIALIZERAW: u32 = 16384u32;\npub const KSPROPERTY_TYPE_UNSERIALIZESET: u32 = 4096u32;\npub type KSPROPERTY_VBICAP = i32;\npub const KSPROPERTY_VBICAP_PROPERTIES_PROTECTION: KSPROPERTY_VBICAP = 1i32;\npub type KSPROPERTY_VBICODECFILTERING = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VBICODECFILTERING_CC_SUBSTREAMS_S {\n    pub Property: KSIDENTIFIER,\n    pub Substreams: VBICODECFILTERING_CC_SUBSTREAMS,\n}\nimpl Default for KSPROPERTY_VBICODECFILTERING_CC_SUBSTREAMS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VBICODECFILTERING_NABTS_SUBSTREAMS_S {\n    pub Property: KSIDENTIFIER,\n    pub Substreams: VBICODECFILTERING_NABTS_SUBSTREAMS,\n}\nimpl Default for KSPROPERTY_VBICODECFILTERING_NABTS_SUBSTREAMS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VBICODECFILTERING_SCANLINES_DISCOVERED_BIT_ARRAY: KSPROPERTY_VBICODECFILTERING = 2i32;\npub const KSPROPERTY_VBICODECFILTERING_SCANLINES_REQUESTED_BIT_ARRAY: KSPROPERTY_VBICODECFILTERING = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VBICODECFILTERING_SCANLINES_S {\n    pub Property: KSIDENTIFIER,\n    pub Scanlines: VBICODECFILTERING_SCANLINES,\n}\nimpl Default for KSPROPERTY_VBICODECFILTERING_SCANLINES_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VBICODECFILTERING_STATISTICS: KSPROPERTY_VBICODECFILTERING = 5i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VBICODECFILTERING_STATISTICS_CC_PIN_S {\n    pub Property: KSIDENTIFIER,\n    pub Statistics: VBICODECFILTERING_STATISTICS_CC_PIN,\n}\nimpl Default for KSPROPERTY_VBICODECFILTERING_STATISTICS_CC_PIN_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VBICODECFILTERING_STATISTICS_CC_S {\n    pub Property: KSIDENTIFIER,\n    pub Statistics: VBICODECFILTERING_STATISTICS_CC,\n}\nimpl Default for KSPROPERTY_VBICODECFILTERING_STATISTICS_CC_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_PIN_S {\n    pub Property: KSIDENTIFIER,\n    pub Statistics: VBICODECFILTERING_STATISTICS_COMMON_PIN,\n}\nimpl Default for KSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_PIN_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_S {\n    pub Property: KSIDENTIFIER,\n    pub Statistics: VBICODECFILTERING_STATISTICS_COMMON,\n}\nimpl Default for KSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_PIN_S {\n    pub Property: KSIDENTIFIER,\n    pub Statistics: VBICODECFILTERING_STATISTICS_NABTS_PIN,\n}\nimpl Default for KSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_PIN_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_S {\n    pub Property: KSIDENTIFIER,\n    pub Statistics: VBICODECFILTERING_STATISTICS_NABTS,\n}\nimpl Default for KSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VBICODECFILTERING_SUBSTREAMS_DISCOVERED_BIT_ARRAY: KSPROPERTY_VBICODECFILTERING = 4i32;\npub const KSPROPERTY_VBICODECFILTERING_SUBSTREAMS_REQUESTED_BIT_ARRAY: KSPROPERTY_VBICODECFILTERING = 3i32;\npub type KSPROPERTY_VIDCAP_CAMERACONTROL = i32;\npub type KSPROPERTY_VIDCAP_CROSSBAR = i32;\npub type KSPROPERTY_VIDCAP_DROPPEDFRAMES = i32;\npub type KSPROPERTY_VIDCAP_SELECTOR = i32;\npub type KSPROPERTY_VIDCAP_TVAUDIO = i32;\npub type KSPROPERTY_VIDCAP_VIDEOCOMPRESSION = i32;\npub type KSPROPERTY_VIDCAP_VIDEOCONTROL = i32;\npub type KSPROPERTY_VIDCAP_VIDEODECODER = i32;\npub type KSPROPERTY_VIDCAP_VIDEOENCODER = i32;\npub type KSPROPERTY_VIDCAP_VIDEOPROCAMP = i32;\npub const KSPROPERTY_VIDEOCOMPRESSION_GETINFO: KSPROPERTY_VIDCAP_VIDEOCOMPRESSION = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOCOMPRESSION_GETINFO_S {\n    pub Property: KSIDENTIFIER,\n    pub StreamIndex: u32,\n    pub DefaultKeyFrameRate: i32,\n    pub DefaultPFrameRate: i32,\n    pub DefaultQuality: i32,\n    pub NumberOfQualitySettings: i32,\n    pub Capabilities: i32,\n}\nimpl Default for KSPROPERTY_VIDEOCOMPRESSION_GETINFO_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEOCOMPRESSION_KEYFRAME_RATE: KSPROPERTY_VIDCAP_VIDEOCOMPRESSION = 1i32;\npub const KSPROPERTY_VIDEOCOMPRESSION_OVERRIDE_FRAME_SIZE: KSPROPERTY_VIDCAP_VIDEOCOMPRESSION = 5i32;\npub const KSPROPERTY_VIDEOCOMPRESSION_OVERRIDE_KEYFRAME: KSPROPERTY_VIDCAP_VIDEOCOMPRESSION = 4i32;\npub const KSPROPERTY_VIDEOCOMPRESSION_PFRAMES_PER_KEYFRAME: KSPROPERTY_VIDCAP_VIDEOCOMPRESSION = 2i32;\npub const KSPROPERTY_VIDEOCOMPRESSION_QUALITY: KSPROPERTY_VIDCAP_VIDEOCOMPRESSION = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOCOMPRESSION_S {\n    pub Property: KSIDENTIFIER,\n    pub StreamIndex: u32,\n    pub Value: i32,\n}\nimpl Default for KSPROPERTY_VIDEOCOMPRESSION_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOCOMPRESSION_S1 {\n    pub Property: KSIDENTIFIER,\n    pub StreamIndex: u32,\n    pub Value: i32,\n    pub Flags: u32,\n}\nimpl Default for KSPROPERTY_VIDEOCOMPRESSION_S1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEOCOMPRESSION_WINDOWSIZE: KSPROPERTY_VIDCAP_VIDEOCOMPRESSION = 6i32;\npub const KSPROPERTY_VIDEOCONTROL_ACTUAL_FRAME_RATE: KSPROPERTY_VIDCAP_VIDEOCONTROL = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOCONTROL_ACTUAL_FRAME_RATE_S {\n    pub Property: KSIDENTIFIER,\n    pub StreamIndex: u32,\n    pub RangeIndex: u32,\n    pub Dimensions: super::super::Foundation::SIZE,\n    pub CurrentActualFrameRate: i64,\n    pub CurrentMaxAvailableFrameRate: i64,\n}\nimpl Default for KSPROPERTY_VIDEOCONTROL_ACTUAL_FRAME_RATE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEOCONTROL_CAPS: KSPROPERTY_VIDCAP_VIDEOCONTROL = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOCONTROL_CAPS_S {\n    pub Property: KSIDENTIFIER,\n    pub StreamIndex: u32,\n    pub VideoControlCaps: u32,\n}\nimpl Default for KSPROPERTY_VIDEOCONTROL_CAPS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEOCONTROL_FRAME_RATES: KSPROPERTY_VIDCAP_VIDEOCONTROL = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOCONTROL_FRAME_RATES_S {\n    pub Property: KSIDENTIFIER,\n    pub StreamIndex: u32,\n    pub RangeIndex: u32,\n    pub Dimensions: super::super::Foundation::SIZE,\n}\nimpl Default for KSPROPERTY_VIDEOCONTROL_FRAME_RATES_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEOCONTROL_MODE: KSPROPERTY_VIDCAP_VIDEOCONTROL = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOCONTROL_MODE_S {\n    pub Property: KSIDENTIFIER,\n    pub StreamIndex: u32,\n    pub Mode: i32,\n}\nimpl Default for KSPROPERTY_VIDEOCONTROL_MODE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEODECODER_CAPS: KSPROPERTY_VIDCAP_VIDEODECODER = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEODECODER_CAPS_S {\n    pub Property: KSIDENTIFIER,\n    pub StandardsSupported: u32,\n    pub Capabilities: u32,\n    pub SettlingTime: u32,\n    pub HSyncPerVSync: u32,\n}\nimpl Default for KSPROPERTY_VIDEODECODER_CAPS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEODECODER_OUTPUT_ENABLE: KSPROPERTY_VIDCAP_VIDEODECODER = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEODECODER_S {\n    pub Property: KSIDENTIFIER,\n    pub Value: u32,\n}\nimpl Default for KSPROPERTY_VIDEODECODER_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEODECODER_STANDARD: KSPROPERTY_VIDCAP_VIDEODECODER = 1i32;\npub const KSPROPERTY_VIDEODECODER_STATUS: KSPROPERTY_VIDCAP_VIDEODECODER = 2i32;\npub const KSPROPERTY_VIDEODECODER_STATUS2: KSPROPERTY_VIDCAP_VIDEODECODER = 5i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEODECODER_STATUS2_S {\n    pub Property: KSIDENTIFIER,\n    pub NumberOfLines: u32,\n    pub SignalLocked: u32,\n    pub ChromaLock: u32,\n}\nimpl Default for KSPROPERTY_VIDEODECODER_STATUS2_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEODECODER_STATUS_S {\n    pub Property: KSIDENTIFIER,\n    pub NumberOfLines: u32,\n    pub SignalLocked: u32,\n}\nimpl Default for KSPROPERTY_VIDEODECODER_STATUS_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEODECODER_VCR_TIMING: KSPROPERTY_VIDCAP_VIDEODECODER = 4i32;\npub const KSPROPERTY_VIDEOENCODER_CAPS: KSPROPERTY_VIDCAP_VIDEOENCODER = 0i32;\npub const KSPROPERTY_VIDEOENCODER_CC_ENABLE: KSPROPERTY_VIDCAP_VIDEOENCODER = 3i32;\npub const KSPROPERTY_VIDEOENCODER_COPYPROTECTION: KSPROPERTY_VIDCAP_VIDEOENCODER = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOENCODER_S {\n    pub Property: KSIDENTIFIER,\n    pub Value: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n}\nimpl Default for KSPROPERTY_VIDEOENCODER_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEOENCODER_STANDARD: KSPROPERTY_VIDCAP_VIDEOENCODER = 1i32;\npub const KSPROPERTY_VIDEOPROCAMP_BACKLIGHT_COMPENSATION: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 8i32;\npub const KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 0i32;\npub const KSPROPERTY_VIDEOPROCAMP_COLORENABLE: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 6i32;\npub const KSPROPERTY_VIDEOPROCAMP_CONTRAST: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 1i32;\npub const KSPROPERTY_VIDEOPROCAMP_DIGITAL_MULTIPLIER: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 10i32;\npub const KSPROPERTY_VIDEOPROCAMP_DIGITAL_MULTIPLIER_LIMIT: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 11i32;\npub const KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO: i32 = 1i32;\npub const KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL: i32 = 2i32;\npub const KSPROPERTY_VIDEOPROCAMP_GAIN: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 9i32;\npub const KSPROPERTY_VIDEOPROCAMP_GAMMA: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 5i32;\npub const KSPROPERTY_VIDEOPROCAMP_HUE: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOPROCAMP_NODE_S {\n    pub NodeProperty: KSP_NODE,\n    pub Value: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n}\nimpl Default for KSPROPERTY_VIDEOPROCAMP_NODE_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOPROCAMP_NODE_S2 {\n    pub NodeProperty: KSP_NODE,\n    pub Value1: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n    pub Value2: i32,\n}\nimpl Default for KSPROPERTY_VIDEOPROCAMP_NODE_S2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 13i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOPROCAMP_S {\n    pub Property: KSIDENTIFIER,\n    pub Value: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n}\nimpl Default for KSPROPERTY_VIDEOPROCAMP_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSPROPERTY_VIDEOPROCAMP_S2 {\n    pub Property: KSIDENTIFIER,\n    pub Value1: i32,\n    pub Flags: u32,\n    pub Capabilities: u32,\n    pub Value2: i32,\n}\nimpl Default for KSPROPERTY_VIDEOPROCAMP_S2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSPROPERTY_VIDEOPROCAMP_SATURATION: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 3i32;\npub const KSPROPERTY_VIDEOPROCAMP_SHARPNESS: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 4i32;\npub const KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 7i32;\npub const KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE_COMPONENT: KSPROPERTY_VIDCAP_VIDEOPROCAMP = 12i32;\npub type KSPROPERTY_VIDMEM_TRANSPORT = i32;\npub type KSPROPERTY_VPCONFIG = i32;\npub const KSPROPERTY_VPCONFIG_DDRAWHANDLE: KSPROPERTY_VPCONFIG = 12i32;\npub const KSPROPERTY_VPCONFIG_DDRAWSURFACEHANDLE: KSPROPERTY_VPCONFIG = 14i32;\npub const KSPROPERTY_VPCONFIG_DECIMATIONCAPABILITY: KSPROPERTY_VPCONFIG = 10i32;\npub const KSPROPERTY_VPCONFIG_GETCONNECTINFO: KSPROPERTY_VPCONFIG = 1i32;\npub const KSPROPERTY_VPCONFIG_GETVIDEOFORMAT: KSPROPERTY_VPCONFIG = 7i32;\npub const KSPROPERTY_VPCONFIG_INFORMVPINPUT: KSPROPERTY_VPCONFIG = 5i32;\npub const KSPROPERTY_VPCONFIG_INVERTPOLARITY: KSPROPERTY_VPCONFIG = 9i32;\npub const KSPROPERTY_VPCONFIG_MAXPIXELRATE: KSPROPERTY_VPCONFIG = 4i32;\npub const KSPROPERTY_VPCONFIG_NUMCONNECTINFO: KSPROPERTY_VPCONFIG = 0i32;\npub const KSPROPERTY_VPCONFIG_NUMVIDEOFORMAT: KSPROPERTY_VPCONFIG = 6i32;\npub const KSPROPERTY_VPCONFIG_SCALEFACTOR: KSPROPERTY_VPCONFIG = 11i32;\npub const KSPROPERTY_VPCONFIG_SETCONNECTINFO: KSPROPERTY_VPCONFIG = 2i32;\npub const KSPROPERTY_VPCONFIG_SETVIDEOFORMAT: KSPROPERTY_VPCONFIG = 8i32;\npub const KSPROPERTY_VPCONFIG_SURFACEPARAMS: KSPROPERTY_VPCONFIG = 15i32;\npub const KSPROPERTY_VPCONFIG_VIDEOPORTID: KSPROPERTY_VPCONFIG = 13i32;\npub const KSPROPERTY_VPCONFIG_VPDATAINFO: KSPROPERTY_VPCONFIG = 3i32;\npub type KSPROPERTY_WAVE = i32;\npub const KSPROPERTY_WAVE_BUFFER: KSPROPERTY_WAVE = 3i32;\npub const KSPROPERTY_WAVE_COMPATIBLE_CAPABILITIES: KSPROPERTY_WAVE = 0i32;\npub const KSPROPERTY_WAVE_FREQUENCY: KSPROPERTY_WAVE = 4i32;\npub const KSPROPERTY_WAVE_INPUT_CAPABILITIES: KSPROPERTY_WAVE = 1i32;\npub const KSPROPERTY_WAVE_OUTPUT_CAPABILITIES: KSPROPERTY_WAVE = 2i32;\npub const KSPROPERTY_WAVE_PAN: KSPROPERTY_WAVE = 6i32;\npub const KSPROPERTY_WAVE_QUEUED_POSITION: u32 = 1u32;\npub const KSPROPERTY_WAVE_VOLUME: KSPROPERTY_WAVE = 5i32;\npub const KSPROPSETID_AC3: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbfabe720_6e1f_11d0_bcf2_444553540000);\npub const KSPROPSETID_Audio: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x45ffaaa0_6e1b_11d0_bcf2_444553540000);\npub const KSPROPSETID_AudioBufferDuration: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4e73c07f_23cc_4955_a7ea_3da502496290);\npub const KSPROPSETID_AudioDecoderOut: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6ca6e020_43bd_11d0_bd6a_003505c103a9);\npub const KSPROPSETID_AudioEngine: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3a2f82dc_886f_4baa_9eb4_082b9025c536);\npub const KSPROPSETID_AudioModule: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc034fdb0_ff75_47c8_aa3c_ee46716b50c6);\npub const KSPROPSETID_AudioPosture: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa3fb7b0d_474e_4f51_a379_51282dd4fa8f);\npub const KSPROPSETID_AudioResourceManagement: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd0b305e1_b2cc_484c_8f23_e5d28ad9cf88);\npub const KSPROPSETID_AudioSignalProcessing: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4f67b528_30c9_40de_b2fb_859ddd1f3470);\npub const KSPROPSETID_Bibliographic: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x07ba150e_e2b1_11d0_ac17_00a0c9223196);\npub const KSPROPSETID_BtAudio: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7fa06c40_b8f6_4c7e_8556_e8c33a12e54d);\npub const KSPROPSETID_Clock: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xdf12a4c0_ac17_11cf_a5d6_28db04c10000);\npub const KSPROPSETID_Connection: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1d58c920_ac9b_11cf_a5d6_28db04c10000);\npub const KSPROPSETID_CopyProt: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0e8a0a40_6aef_11d0_9ed0_00a024ca19b3);\npub const KSPROPSETID_Cyclic: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3ffeaea0_2bee_11cf_a5d6_28db04c10000);\npub const KSPROPSETID_DirectSound3DBuffer: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x437b3411_d060_11d0_8583_00c04fd9baf3);\npub const KSPROPSETID_DirectSound3DListener: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x437b3414_d060_11d0_8583_00c04fd9baf3);\npub const KSPROPSETID_DrmAudioStream: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2f2c8ddd_4198_4fac_ba29_61bb05b7de06);\npub const KSPROPSETID_DvdSubPic: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xac390460_43af_11d0_bd6a_003505c103a9);\npub const KSPROPSETID_FMRXControl: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x947bba3a_e8ee_4786_90c4_8428185f05be);\npub const KSPROPSETID_FMRXTopology: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0c46ce8f_dc2d_4204_9dc9_f58963366563);\npub const KSPROPSETID_General: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1464eda5_6a8f_11d1_9aa7_00a0c9223196);\npub const KSPROPSETID_Hrtf3d: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb66decb0_a083_11d0_851e_00c04fd9baf3);\npub const KSPROPSETID_InterleavedAudio: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe9ebe550_d619_4c0a_976b_7062322b3006);\npub const KSPROPSETID_Itd3d: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6429f090_9fd9_11d0_a75b_00a0c90365e3);\npub const KSPROPSETID_Jack: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4509f757_2d46_4637_8e62_ce7db944f57b);\npub const KSPROPSETID_MPEG4_MediaType_Attributes: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xff6c4bfa_07a9_4c7b_a237_672f9d68065f);\npub const KSPROPSETID_MediaSeeking: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xee904f0c_d09b_11d0_abe9_00a0c9223196);\npub const KSPROPSETID_MemoryTransport: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0a3d1c5d_5243_4819_9ed0_aee8044cee2b);\npub const KSPROPSETID_Mpeg2Vid: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc8e11b60_0cc9_11d0_bd69_003505c103a9);\npub const KSPROPSETID_OverlayUpdate: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x490ea5cf_7681_11d1_a21c_00a0c9223196);\npub const KSPROPSETID_Pin: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8c134960_51ad_11cf_878a_94f801c10000);\npub const KSPROPSETID_PinMDLCacheClearProp: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbd718a7b_97fc_40c7_88ce_d3ff06f55b16);\npub const KSPROPSETID_Quality: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd16ad380_ac1a_11cf_a5d6_28db04c10000);\npub const KSPROPSETID_RtAudio: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa855a48c_2f78_4729_9051_1968746b9eef);\npub const KSPROPSETID_SoundDetector: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x113c425e_fd17_4057_b422_ed4074f1afdf);\npub const KSPROPSETID_SoundDetector2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfe07e322_450c_4bd5_84ca_a948500ea6aa);\npub const KSPROPSETID_Stream: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x65aaba60_98ae_11cf_a10d_0020afd156e4);\npub const KSPROPSETID_StreamAllocator: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xcf6e4342_ec87_11cf_a130_0020afd156e4);\npub const KSPROPSETID_StreamInterface: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1fdd8ee1_9cd3_11d0_82aa_0000f822fe8a);\npub const KSPROPSETID_TSRateChange: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa503c5c0_1d1d_11d1_ad80_444553540000);\npub const KSPROPSETID_TelephonyControl: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb6df7eb1_d099_489f_a6a0_c0106f0887a7);\npub const KSPROPSETID_TelephonyTopology: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xabf25c7e_0e64_4e32_b190_d0f6d7c53e97);\npub const KSPROPSETID_Topology: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x720d4ac0_7533_11d0_a5d6_28db04c10000);\npub const KSPROPSETID_TopologyNode: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x45ffaaa1_6e1b_11d0_bcf2_444553540000);\npub const KSPROPSETID_VBICAP_PROPERTIES: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf162c607_7b35_496f_ad7f_2dca3b46b718);\npub const KSPROPSETID_VBICodecFiltering: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xcafeb0ca_8715_11d0_bd6a_0035c0edbabe);\npub const KSPROPSETID_VPConfig: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xbc29a660_30e3_11d0_9e69_00c04fd7c15b);\npub const KSPROPSETID_VPVBIConfig: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xec529b00_1a1f_11d1_bad9_00609744111a);\npub const KSPROPSETID_VramCapture: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe73face3_2880_4902_b799_88d0cd634e0f);\npub const KSPROPSETID_Wave: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x924e54b0_630f_11cf_ada7_08003e30494a);\npub const KSPROPTYPESETID_General: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x97e99ba0_bdea_11cf_a5d6_28db04c10000);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSP_NODE {\n    pub Property: KSIDENTIFIER,\n    pub NodeId: u32,\n    pub Reserved: u32,\n}\nimpl Default for KSP_NODE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSP_PIN {\n    pub Property: KSIDENTIFIER,\n    pub PinId: u32,\n    pub Anonymous: KSP_PIN_0,\n}\nimpl Default for KSP_PIN {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSP_PIN_0 {\n    pub Reserved: u32,\n    pub Flags: u32,\n}\nimpl Default for KSP_PIN_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSP_TIMEFORMAT {\n    pub Property: KSIDENTIFIER,\n    pub SourceFormat: windows_sys::core::GUID,\n    pub TargetFormat: windows_sys::core::GUID,\n    pub Time: i64,\n}\nimpl Default for KSP_TIMEFORMAT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSQUALITY {\n    pub Context: *mut core::ffi::c_void,\n    pub Proportion: u32,\n    pub DeltaTime: i64,\n}\nimpl Default for KSQUALITY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSQUALITY_MANAGER {\n    pub QualityManager: super::super::Foundation::HANDLE,\n    pub Context: *mut core::ffi::c_void,\n}\nimpl Default for KSQUALITY_MANAGER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSQUERYBUFFER {\n    pub Event: KSIDENTIFIER,\n    pub EventData: *mut KSEVENTDATA,\n    pub Reserved: *mut core::ffi::c_void,\n}\nimpl Default for KSQUERYBUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRATE {\n    pub PresentationStart: i64,\n    pub Duration: i64,\n    pub Interface: KSIDENTIFIER,\n    pub Rate: i32,\n    pub Flags: u32,\n}\nimpl Default for KSRATE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRATE_CAPABILITY {\n    pub Property: KSIDENTIFIER,\n    pub Rate: KSRATE,\n}\nimpl Default for KSRATE_CAPABILITY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSRATE_NOPRESENTATIONDURATION: u32 = 2u32;\npub const KSRATE_NOPRESENTATIONSTART: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRELATIVEEVENT {\n    pub Size: u32,\n    pub Flags: u32,\n    pub Anonymous: KSRELATIVEEVENT_0,\n    pub Reserved: *mut core::ffi::c_void,\n    pub Event: KSIDENTIFIER,\n    pub EventData: KSEVENTDATA,\n}\nimpl Default for KSRELATIVEEVENT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSRELATIVEEVENT_0 {\n    pub ObjectHandle: super::super::Foundation::HANDLE,\n    pub ObjectPointer: *mut core::ffi::c_void,\n}\nimpl Default for KSRELATIVEEVENT_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSRELATIVEEVENT_FLAG_HANDLE: u32 = 1u32;\npub const KSRELATIVEEVENT_FLAG_POINTER: u32 = 2u32;\npub type KSRESET = i32;\npub const KSRESET_BEGIN: KSRESET = 0i32;\npub const KSRESET_END: KSRESET = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSRESOLUTION {\n    pub Granularity: i64,\n    pub Error: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_BUFFER {\n    pub BufferAddress: *mut core::ffi::c_void,\n    pub ActualBufferSize: u32,\n    pub CallMemoryBarrier: windows_sys::core::BOOL,\n}\nimpl Default for KSRTAUDIO_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSRTAUDIO_BUFFER32 {\n    pub BufferAddress: u32,\n    pub ActualBufferSize: u32,\n    pub CallMemoryBarrier: windows_sys::core::BOOL,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_BUFFER_PROPERTY {\n    pub Property: KSIDENTIFIER,\n    pub BaseAddress: *mut core::ffi::c_void,\n    pub RequestedBufferSize: u32,\n}\nimpl Default for KSRTAUDIO_BUFFER_PROPERTY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_BUFFER_PROPERTY32 {\n    pub Property: KSIDENTIFIER,\n    pub BaseAddress: u32,\n    pub RequestedBufferSize: u32,\n}\nimpl Default for KSRTAUDIO_BUFFER_PROPERTY32 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION {\n    pub Property: KSIDENTIFIER,\n    pub BaseAddress: *mut core::ffi::c_void,\n    pub RequestedBufferSize: u32,\n    pub NotificationCount: u32,\n}\nimpl Default for KSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION32 {\n    pub Property: KSIDENTIFIER,\n    pub BaseAddress: u32,\n    pub RequestedBufferSize: u32,\n    pub NotificationCount: u32,\n}\nimpl Default for KSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION32 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSRTAUDIO_GETREADPACKET_INFO {\n    pub PacketNumber: u32,\n    pub Flags: u32,\n    pub PerformanceCounterValue: u64,\n    pub MoreData: windows_sys::core::BOOL,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSRTAUDIO_HWLATENCY {\n    pub FifoSize: u32,\n    pub ChipsetDelay: u32,\n    pub CodecDelay: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_HWREGISTER {\n    pub Register: *mut core::ffi::c_void,\n    pub Width: u32,\n    pub Numerator: u64,\n    pub Denominator: u64,\n    pub Accuracy: u32,\n}\nimpl Default for KSRTAUDIO_HWREGISTER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSRTAUDIO_HWREGISTER32 {\n    pub Register: u32,\n    pub Width: u32,\n    pub Numerator: u64,\n    pub Denominator: u64,\n    pub Accuracy: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_HWREGISTER_PROPERTY {\n    pub Property: KSIDENTIFIER,\n    pub BaseAddress: *mut core::ffi::c_void,\n}\nimpl Default for KSRTAUDIO_HWREGISTER_PROPERTY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_HWREGISTER_PROPERTY32 {\n    pub Property: KSIDENTIFIER,\n    pub BaseAddress: u32,\n}\nimpl Default for KSRTAUDIO_HWREGISTER_PROPERTY32 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY {\n    pub Property: KSIDENTIFIER,\n    pub NotificationEvent: super::super::Foundation::HANDLE,\n}\nimpl Default for KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY32 {\n    pub Property: KSIDENTIFIER,\n    pub NotificationEvent: u32,\n}\nimpl Default for KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY32 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_PACKETVREGISTER {\n    pub CompletedPacketCount: *mut u64,\n    pub CompletedPacketQPC: *mut u64,\n    pub CompletedPacketHash: *mut u64,\n}\nimpl Default for KSRTAUDIO_PACKETVREGISTER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSRTAUDIO_PACKETVREGISTER_PROPERTY {\n    pub Property: KSIDENTIFIER,\n    pub BaseAddress: *mut core::ffi::c_void,\n}\nimpl Default for KSRTAUDIO_PACKETVREGISTER_PROPERTY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSRTAUDIO_SETWRITEPACKET_INFO {\n    pub PacketNumber: u32,\n    pub Flags: u32,\n    pub EosPacketLength: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSSOUNDDETECTORPROPERTY {\n    pub Property: KSIDENTIFIER,\n    pub EventId: windows_sys::core::GUID,\n}\nimpl Default for KSSOUNDDETECTORPROPERTY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KSSTATE = i32;\npub const KSSTATE_ACQUIRE: KSSTATE = 1i32;\npub const KSSTATE_PAUSE: KSSTATE = 2i32;\npub const KSSTATE_RUN: KSSTATE = 3i32;\npub const KSSTATE_STOP: KSSTATE = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSSTREAMALLOCATOR_STATUS {\n    pub Framing: KSALLOCATOR_FRAMING,\n    pub AllocatedFrames: u32,\n    pub Reserved: u32,\n}\nimpl Default for KSSTREAMALLOCATOR_STATUS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSSTREAMALLOCATOR_STATUS_EX {\n    pub Framing: KSALLOCATOR_FRAMING_EX,\n    pub AllocatedFrames: u32,\n    pub Reserved: u32,\n}\nimpl Default for KSSTREAMALLOCATOR_STATUS_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSSTREAM_FAILUREEXCEPTION: u32 = 8192u32;\n#[repr(C)]\n#[cfg(target_arch = \"x86\")]\n#[derive(Clone, Copy)]\npub struct KSSTREAM_HEADER {\n    pub Size: u32,\n    pub TypeSpecificFlags: u32,\n    pub PresentationTime: KSTIME,\n    pub Duration: i64,\n    pub FrameExtent: u32,\n    pub DataUsed: u32,\n    pub Data: *mut core::ffi::c_void,\n    pub OptionsFlags: u32,\n}\n#[cfg(target_arch = \"x86\")]\nimpl Default for KSSTREAM_HEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\n#[derive(Clone, Copy)]\npub struct KSSTREAM_HEADER {\n    pub Size: u32,\n    pub TypeSpecificFlags: u32,\n    pub PresentationTime: KSTIME,\n    pub Duration: i64,\n    pub FrameExtent: u32,\n    pub DataUsed: u32,\n    pub Data: *mut core::ffi::c_void,\n    pub OptionsFlags: u32,\n    pub Reserved: u32,\n}\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\nimpl Default for KSSTREAM_HEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSSTREAM_HEADER_OPTIONSF_BUFFEREDTRANSFER: u32 = 1024u32;\npub const KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY: u32 = 4u32;\npub const KSSTREAM_HEADER_OPTIONSF_DURATIONVALID: u32 = 256u32;\npub const KSSTREAM_HEADER_OPTIONSF_ENDOFPHOTOSEQUENCE: u32 = 8192u32;\npub const KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM: u32 = 512u32;\npub const KSSTREAM_HEADER_OPTIONSF_FLUSHONPAUSE: u32 = 128u32;\npub const KSSTREAM_HEADER_OPTIONSF_FRAMEINFO: u32 = 16384u32;\npub const KSSTREAM_HEADER_OPTIONSF_LOOPEDDATA: u32 = 2147483648u32;\npub const KSSTREAM_HEADER_OPTIONSF_METADATA: u32 = 4096u32;\npub const KSSTREAM_HEADER_OPTIONSF_PERSIST_SAMPLE: u32 = 32768u32;\npub const KSSTREAM_HEADER_OPTIONSF_PREROLL: u32 = 2u32;\npub const KSSTREAM_HEADER_OPTIONSF_SAMPLE_PERSISTED: u32 = 65536u32;\npub const KSSTREAM_HEADER_OPTIONSF_SECUREBUFFERTRANSFER: u32 = 262144u32;\npub const KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT: u32 = 1u32;\npub const KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY: u32 = 64u32;\npub const KSSTREAM_HEADER_OPTIONSF_TIMEVALID: u32 = 16u32;\npub const KSSTREAM_HEADER_OPTIONSF_TYPECHANGED: u32 = 8u32;\npub const KSSTREAM_HEADER_OPTIONSF_VRAM_DATA_TRANSFER: u32 = 2048u32;\npub const KSSTREAM_HEADER_TRACK_COMPLETION_NUMBERS: u32 = 131072u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSSTREAM_METADATA_INFO {\n    pub BufferSize: u32,\n    pub UsedSize: u32,\n    pub Data: *mut core::ffi::c_void,\n    pub SystemVa: *mut core::ffi::c_void,\n    pub Flags: u32,\n    pub Reserved: u32,\n}\nimpl Default for KSSTREAM_METADATA_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSSTREAM_NONPAGED_DATA: u32 = 256u32;\npub const KSSTREAM_PAGED_DATA: u32 = 0u32;\npub const KSSTREAM_READ: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSSTREAM_SEGMENT {\n    pub KsInterfaceHandler: *mut core::ffi::c_void,\n    pub KsDataTypeHandler: *mut core::ffi::c_void,\n    pub IoOperation: KSIOOPERATION,\n    pub CompletionEvent: super::super::Foundation::HANDLE,\n}\nimpl Default for KSSTREAM_SEGMENT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSSTREAM_SYNCHRONOUS: u32 = 4096u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSSTREAM_UVC_METADATA {\n    pub StartOfFrameTimestamp: KSSTREAM_UVC_METADATATYPE_TIMESTAMP,\n    pub EndOfFrameTimestamp: KSSTREAM_UVC_METADATATYPE_TIMESTAMP,\n}\nimpl Default for KSSTREAM_UVC_METADATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSSTREAM_UVC_METADATATYPE_TIMESTAMP {\n    pub PresentationTimeStamp: u32,\n    pub SourceClockReference: u32,\n    pub Anonymous: KSSTREAM_UVC_METADATATYPE_TIMESTAMP_0,\n    pub Reserved0: u16,\n    pub Reserved1: u32,\n}\nimpl Default for KSSTREAM_UVC_METADATATYPE_TIMESTAMP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KSSTREAM_UVC_METADATATYPE_TIMESTAMP_0 {\n    pub Anonymous: KSSTREAM_UVC_METADATATYPE_TIMESTAMP_0_0,\n    pub SCRToken: u16,\n}\nimpl Default for KSSTREAM_UVC_METADATATYPE_TIMESTAMP_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSSTREAM_UVC_METADATATYPE_TIMESTAMP_0_0 {\n    pub _bitfield: u16,\n}\npub const KSSTREAM_UVC_SECURE_ATTRIBUTE_SIZE: u32 = 8192u32;\npub const KSSTREAM_WRITE: u32 = 1u32;\npub const KSSTRING_Allocator: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{642F5D00-4791-11D0-A5D6-28DB04C10000}\");\npub const KSSTRING_AllocatorEx: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{091BB63B-603F-11D1-B067-00A0C9062802}\");\npub const KSSTRING_Clock: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{53172480-4791-11D0-A5D6-28DB04C10000}\");\npub const KSSTRING_Filter: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{9B365890-165F-11D0-A195-0020AFD156E4}\");\npub const KSSTRING_Pin: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{146F1A80-4791-11D0-A5D6-28DB04C10000}\");\npub const KSSTRING_TopologyNode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{0621061A-EE75-11D0-B915-00A0C9223196}\");\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSTELEPHONY_CALLCONTROL {\n    pub CallType: TELEPHONY_CALLTYPE,\n    pub CallControlOp: TELEPHONY_CALLCONTROLOP,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSTELEPHONY_CALLINFO {\n    pub CallType: TELEPHONY_CALLTYPE,\n    pub CallState: TELEPHONY_CALLSTATE,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSTELEPHONY_PROVIDERCHANGE {\n    pub CallType: TELEPHONY_CALLTYPE,\n    pub ProviderChangeOp: TELEPHONY_PROVIDERCHANGEOP,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSTIME {\n    pub Time: i64,\n    pub Numerator: u32,\n    pub Denominator: u32,\n}\npub const KSTIME_FORMAT_BYTE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7b785571_8c82_11cf_bc0c_00aa00ac74f6);\npub const KSTIME_FORMAT_FIELD: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7b785573_8c82_11cf_bc0c_00aa00ac74f6);\npub const KSTIME_FORMAT_FRAME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7b785570_8c82_11cf_bc0c_00aa00ac74f6);\npub const KSTIME_FORMAT_MEDIA_TIME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7b785574_8c82_11cf_bc0c_00aa00ac74f6);\npub const KSTIME_FORMAT_SAMPLE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7b785572_8c82_11cf_bc0c_00aa00ac74f6);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSTOPOLOGY {\n    pub CategoriesCount: u32,\n    pub Categories: *const windows_sys::core::GUID,\n    pub TopologyNodesCount: u32,\n    pub TopologyNodes: *const windows_sys::core::GUID,\n    pub TopologyConnectionsCount: u32,\n    pub TopologyConnections: *const KSTOPOLOGY_CONNECTION,\n    pub TopologyNodesNames: *const windows_sys::core::GUID,\n    pub Reserved: u32,\n}\nimpl Default for KSTOPOLOGY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSTOPOLOGY_CONNECTION {\n    pub FromNode: u32,\n    pub FromNodePin: u32,\n    pub ToNode: u32,\n    pub ToNodePin: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSTOPOLOGY_ENDPOINTID {\n    pub TopologyName: [u16; 260],\n    pub PinId: u32,\n}\nimpl Default for KSTOPOLOGY_ENDPOINTID {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSTOPOLOGY_ENDPOINTIDPAIR {\n    pub RenderEndpoint: KSTOPOLOGY_ENDPOINTID,\n    pub CaptureEndpoint: KSTOPOLOGY_ENDPOINTID,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSVPMAXPIXELRATE {\n    pub Size: KS_AMVPSIZE,\n    pub MaxPixelsPerSecond: u32,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSVPSIZE_PROP {\n    pub Property: KSIDENTIFIER,\n    pub Size: KS_AMVPSIZE,\n}\nimpl Default for KSVPSIZE_PROP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSVPSURFACEPARAMS {\n    pub dwPitch: u32,\n    pub dwXOrigin: u32,\n    pub dwYOrigin: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSWAVETABLE_WAVE_DESC {\n    pub Identifier: KSIDENTIFIER,\n    pub Size: u32,\n    pub Looped: windows_sys::core::BOOL,\n    pub LoopPoint: u32,\n    pub InROM: windows_sys::core::BOOL,\n    pub Format: KSDATAFORMAT,\n}\nimpl Default for KSWAVETABLE_WAVE_DESC {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KSWAVE_BUFFER {\n    pub Attributes: u32,\n    pub BufferSize: u32,\n    pub BufferAddress: *mut core::ffi::c_void,\n}\nimpl Default for KSWAVE_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KSWAVE_BUFFER_ATTRIBUTEF_LOOPING: u32 = 1u32;\npub const KSWAVE_BUFFER_ATTRIBUTEF_STATIC: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSWAVE_COMPATCAPS {\n    pub ulDeviceType: u32,\n}\npub const KSWAVE_COMPATCAPS_INPUT: u32 = 0u32;\npub const KSWAVE_COMPATCAPS_OUTPUT: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSWAVE_INPUT_CAPABILITIES {\n    pub MaximumChannelsPerConnection: u32,\n    pub MinimumBitsPerSample: u32,\n    pub MaximumBitsPerSample: u32,\n    pub MinimumSampleFrequency: u32,\n    pub MaximumSampleFrequency: u32,\n    pub TotalConnections: u32,\n    pub ActiveConnections: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSWAVE_OUTPUT_CAPABILITIES {\n    pub MaximumChannelsPerConnection: u32,\n    pub MinimumBitsPerSample: u32,\n    pub MaximumBitsPerSample: u32,\n    pub MinimumSampleFrequency: u32,\n    pub MaximumSampleFrequency: u32,\n    pub TotalConnections: u32,\n    pub StaticConnections: u32,\n    pub StreamingConnections: u32,\n    pub ActiveConnections: u32,\n    pub ActiveStaticConnections: u32,\n    pub ActiveStreamingConnections: u32,\n    pub Total3DConnections: u32,\n    pub Static3DConnections: u32,\n    pub Streaming3DConnections: u32,\n    pub Active3DConnections: u32,\n    pub ActiveStatic3DConnections: u32,\n    pub ActiveStreaming3DConnections: u32,\n    pub TotalSampleMemory: u32,\n    pub FreeSampleMemory: u32,\n    pub LargestFreeContiguousSampleMemory: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KSWAVE_VOLUME {\n    pub LeftAttenuation: i32,\n    pub RightAttenuation: i32,\n}\npub const KS_AMCONTROL_COLORINFO_PRESENT: u32 = 128u32;\npub const KS_AMCONTROL_PAD_TO_16x9: u32 = 4u32;\npub const KS_AMCONTROL_PAD_TO_4x3: u32 = 2u32;\npub const KS_AMCONTROL_USED: u32 = 1u32;\npub type KS_AMPixAspectRatio = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_AMVPDATAINFO {\n    pub dwSize: u32,\n    pub dwMicrosecondsPerField: u32,\n    pub amvpDimInfo: KS_AMVPDIMINFO,\n    pub dwPictAspectRatioX: u32,\n    pub dwPictAspectRatioY: u32,\n    pub bEnableDoubleClock: windows_sys::core::BOOL,\n    pub bEnableVACT: windows_sys::core::BOOL,\n    pub bDataIsInterlaced: windows_sys::core::BOOL,\n    pub lHalfLinesOdd: i32,\n    pub bFieldPolarityInverted: windows_sys::core::BOOL,\n    pub dwNumLinesInVREF: u32,\n    pub lHalfLinesEven: i32,\n    pub dwReserved1: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_AMVPDIMINFO {\n    pub dwFieldWidth: u32,\n    pub dwFieldHeight: u32,\n    pub dwVBIWidth: u32,\n    pub dwVBIHeight: u32,\n    pub rcValidRegion: super::super::Foundation::RECT,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_AMVPSIZE {\n    pub dwWidth: u32,\n    pub dwHeight: u32,\n}\npub const KS_AMVP_BEST_BANDWIDTH: KS_AMVP_SELECTFORMATBY = 1i32;\npub const KS_AMVP_DO_NOT_CARE: KS_AMVP_SELECTFORMATBY = 0i32;\npub const KS_AMVP_INPUT_SAME_AS_OUTPUT: KS_AMVP_SELECTFORMATBY = 2i32;\npub type KS_AMVP_MODE = i32;\npub const KS_AMVP_MODE_BOBINTERLEAVED: KS_AMVP_MODE = 1i32;\npub const KS_AMVP_MODE_BOBNONINTERLEAVED: KS_AMVP_MODE = 2i32;\npub const KS_AMVP_MODE_SKIPEVEN: KS_AMVP_MODE = 3i32;\npub const KS_AMVP_MODE_SKIPODD: KS_AMVP_MODE = 4i32;\npub const KS_AMVP_MODE_WEAVE: KS_AMVP_MODE = 0i32;\npub type KS_AMVP_SELECTFORMATBY = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_AM_ExactRateChange {\n    pub OutputZeroTime: i64,\n    pub Rate: i32,\n}\npub type KS_AM_PROPERTY_TS_RATE_CHANGE = i32;\npub const KS_AM_RATE_ExactRateChange: KS_AM_PROPERTY_TS_RATE_CHANGE = 2i32;\npub const KS_AM_RATE_MaxFullDataRate: KS_AM_PROPERTY_TS_RATE_CHANGE = 3i32;\npub const KS_AM_RATE_SimpleRateChange: KS_AM_PROPERTY_TS_RATE_CHANGE = 1i32;\npub const KS_AM_RATE_Step: KS_AM_PROPERTY_TS_RATE_CHANGE = 4i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_AM_SimpleRateChange {\n    pub StartTime: i64,\n    pub Rate: i32,\n}\npub const KS_AM_UseNewCSSKey: i32 = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_ANALOGVIDEOINFO {\n    pub rcSource: super::super::Foundation::RECT,\n    pub rcTarget: super::super::Foundation::RECT,\n    pub dwActiveWidth: u32,\n    pub dwActiveHeight: u32,\n    pub AvgTimePerFrame: i64,\n}\npub type KS_AnalogVideoStandard = i32;\npub const KS_AnalogVideo_NTSC_433: KS_AnalogVideoStandard = 4i32;\npub const KS_AnalogVideo_NTSC_M: KS_AnalogVideoStandard = 1i32;\npub const KS_AnalogVideo_NTSC_M_J: KS_AnalogVideoStandard = 2i32;\npub const KS_AnalogVideo_NTSC_Mask: u32 = 7u32;\npub const KS_AnalogVideo_None: KS_AnalogVideoStandard = 0i32;\npub const KS_AnalogVideo_PAL_60: KS_AnalogVideoStandard = 2048i32;\npub const KS_AnalogVideo_PAL_B: KS_AnalogVideoStandard = 16i32;\npub const KS_AnalogVideo_PAL_D: KS_AnalogVideoStandard = 32i32;\npub const KS_AnalogVideo_PAL_G: KS_AnalogVideoStandard = 64i32;\npub const KS_AnalogVideo_PAL_H: KS_AnalogVideoStandard = 128i32;\npub const KS_AnalogVideo_PAL_I: KS_AnalogVideoStandard = 256i32;\npub const KS_AnalogVideo_PAL_M: KS_AnalogVideoStandard = 512i32;\npub const KS_AnalogVideo_PAL_Mask: u32 = 1052656u32;\npub const KS_AnalogVideo_PAL_N: KS_AnalogVideoStandard = 1024i32;\npub const KS_AnalogVideo_PAL_N_COMBO: KS_AnalogVideoStandard = 1048576i32;\npub const KS_AnalogVideo_SECAM_B: KS_AnalogVideoStandard = 4096i32;\npub const KS_AnalogVideo_SECAM_D: KS_AnalogVideoStandard = 8192i32;\npub const KS_AnalogVideo_SECAM_G: KS_AnalogVideoStandard = 16384i32;\npub const KS_AnalogVideo_SECAM_H: KS_AnalogVideoStandard = 32768i32;\npub const KS_AnalogVideo_SECAM_K: KS_AnalogVideoStandard = 65536i32;\npub const KS_AnalogVideo_SECAM_K1: KS_AnalogVideoStandard = 131072i32;\npub const KS_AnalogVideo_SECAM_L: KS_AnalogVideoStandard = 262144i32;\npub const KS_AnalogVideo_SECAM_L1: KS_AnalogVideoStandard = 524288i32;\npub const KS_AnalogVideo_SECAM_Mask: u32 = 1044480u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_BITMAPINFOHEADER {\n    pub biSize: u32,\n    pub biWidth: i32,\n    pub biHeight: i32,\n    pub biPlanes: u16,\n    pub biBitCount: u16,\n    pub biCompression: u32,\n    pub biSizeImage: u32,\n    pub biXPelsPerMeter: i32,\n    pub biYPelsPerMeter: i32,\n    pub biClrUsed: u32,\n    pub biClrImportant: u32,\n}\npub const KS_BI_BITFIELDS: i32 = 3i32;\npub const KS_BI_JPEG: i32 = 4i32;\npub const KS_BI_RGB: i32 = 0i32;\npub const KS_BI_RLE4: i32 = 2i32;\npub const KS_BI_RLE8: i32 = 1i32;\npub const KS_CAMERACONTROL_ASYNC_RESET: KS_CameraControlAsyncOperation = 3i32;\npub const KS_CAMERACONTROL_ASYNC_START: KS_CameraControlAsyncOperation = 1i32;\npub const KS_CAMERACONTROL_ASYNC_STOP: KS_CameraControlAsyncOperation = 2i32;\npub const KS_CAPTURE_ALLOC_INVALID: CAPTURE_MEMORY_ALLOCATION_FLAGS = 0i32;\npub const KS_CAPTURE_ALLOC_SECURE_BUFFER: CAPTURE_MEMORY_ALLOCATION_FLAGS = 16i32;\npub const KS_CAPTURE_ALLOC_SYSTEM: CAPTURE_MEMORY_ALLOCATION_FLAGS = 1i32;\npub const KS_CAPTURE_ALLOC_SYSTEM_AGP: CAPTURE_MEMORY_ALLOCATION_FLAGS = 4i32;\npub const KS_CAPTURE_ALLOC_VRAM: CAPTURE_MEMORY_ALLOCATION_FLAGS = 2i32;\npub const KS_CAPTURE_ALLOC_VRAM_MAPPED: CAPTURE_MEMORY_ALLOCATION_FLAGS = 8i32;\npub const KS_CC_SUBSTREAM_EVEN: i32 = 2i32;\npub const KS_CC_SUBSTREAM_FIELD1_MASK: i32 = 240i32;\npub const KS_CC_SUBSTREAM_FIELD2_MASK: i32 = 7936i32;\npub const KS_CC_SUBSTREAM_ODD: i32 = 1i32;\npub const KS_CC_SUBSTREAM_SERVICE_CC1: i32 = 16i32;\npub const KS_CC_SUBSTREAM_SERVICE_CC2: i32 = 32i32;\npub const KS_CC_SUBSTREAM_SERVICE_CC3: i32 = 256i32;\npub const KS_CC_SUBSTREAM_SERVICE_CC4: i32 = 512i32;\npub const KS_CC_SUBSTREAM_SERVICE_T1: i32 = 64i32;\npub const KS_CC_SUBSTREAM_SERVICE_T2: i32 = 128i32;\npub const KS_CC_SUBSTREAM_SERVICE_T3: i32 = 1024i32;\npub const KS_CC_SUBSTREAM_SERVICE_T4: i32 = 2048i32;\npub const KS_CC_SUBSTREAM_SERVICE_XDS: i32 = 4096i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_COLCON {\n    pub _bitfield1: u8,\n    pub _bitfield2: u8,\n    pub _bitfield3: u8,\n    pub _bitfield4: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_COMPRESSION {\n    pub RatioNumerator: u32,\n    pub RatioDenominator: u32,\n    pub RatioConstantMargin: u32,\n}\npub const KS_COPYPROTECT_RestrictDuplication: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_COPY_MACROVISION {\n    pub MACROVISIONLevel: u32,\n}\npub type KS_COPY_MACROVISION_LEVEL = i32;\npub type KS_CameraControlAsyncOperation = i32;\npub type KS_CompressionCaps = i32;\npub const KS_CompressionCaps_CanBFrame: KS_CompressionCaps = 8i32;\npub const KS_CompressionCaps_CanCrunch: KS_CompressionCaps = 2i32;\npub const KS_CompressionCaps_CanKeyFrame: KS_CompressionCaps = 4i32;\npub const KS_CompressionCaps_CanQuality: KS_CompressionCaps = 1i32;\npub const KS_CompressionCaps_CanWindow: KS_CompressionCaps = 16i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATAFORMAT_H264VIDEOINFO {\n    pub DataFormat: KSDATAFORMAT,\n    pub H264VideoInfoHeader: KS_H264VIDEOINFO,\n}\nimpl Default for KS_DATAFORMAT_H264VIDEOINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATAFORMAT_IMAGEINFO {\n    pub DataFormat: KSDATAFORMAT,\n    pub ImageInfoHeader: KS_BITMAPINFOHEADER,\n}\nimpl Default for KS_DATAFORMAT_IMAGEINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATAFORMAT_MPEGVIDEOINFO2 {\n    pub DataFormat: KSDATAFORMAT,\n    pub MpegVideoInfoHeader2: KS_MPEGVIDEOINFO2,\n}\nimpl Default for KS_DATAFORMAT_MPEGVIDEOINFO2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATAFORMAT_VBIINFOHEADER {\n    pub DataFormat: KSDATAFORMAT,\n    pub VBIInfoHeader: KS_VBIINFOHEADER,\n}\nimpl Default for KS_DATAFORMAT_VBIINFOHEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATAFORMAT_VIDEOINFOHEADER {\n    pub DataFormat: KSDATAFORMAT,\n    pub VideoInfoHeader: KS_VIDEOINFOHEADER,\n}\nimpl Default for KS_DATAFORMAT_VIDEOINFOHEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATAFORMAT_VIDEOINFOHEADER2 {\n    pub DataFormat: KSDATAFORMAT,\n    pub VideoInfoHeader2: KS_VIDEOINFOHEADER2,\n}\nimpl Default for KS_DATAFORMAT_VIDEOINFOHEADER2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATAFORMAT_VIDEOINFO_PALETTE {\n    pub DataFormat: KSDATAFORMAT,\n    pub VideoInfo: KS_VIDEOINFO,\n}\nimpl Default for KS_DATAFORMAT_VIDEOINFO_PALETTE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATARANGE_ANALOGVIDEO {\n    pub DataRange: KSDATAFORMAT,\n    pub AnalogVideoInfo: KS_ANALOGVIDEOINFO,\n}\nimpl Default for KS_DATARANGE_ANALOGVIDEO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATARANGE_H264_VIDEO {\n    pub DataRange: KSDATAFORMAT,\n    pub bFixedSizeSamples: windows_sys::core::BOOL,\n    pub bTemporalCompression: windows_sys::core::BOOL,\n    pub StreamDescriptionFlags: u32,\n    pub MemoryAllocationFlags: u32,\n    pub ConfigCaps: KS_VIDEO_STREAM_CONFIG_CAPS,\n    pub VideoInfoHeader: KS_H264VIDEOINFO,\n}\nimpl Default for KS_DATARANGE_H264_VIDEO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATARANGE_IMAGE {\n    pub DataRange: KSDATAFORMAT,\n    pub ConfigCaps: KS_VIDEO_STREAM_CONFIG_CAPS,\n    pub ImageInfoHeader: KS_BITMAPINFOHEADER,\n}\nimpl Default for KS_DATARANGE_IMAGE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATARANGE_MPEG1_VIDEO {\n    pub DataRange: KSDATAFORMAT,\n    pub bFixedSizeSamples: windows_sys::core::BOOL,\n    pub bTemporalCompression: windows_sys::core::BOOL,\n    pub StreamDescriptionFlags: u32,\n    pub MemoryAllocationFlags: u32,\n    pub ConfigCaps: KS_VIDEO_STREAM_CONFIG_CAPS,\n    pub VideoInfoHeader: KS_MPEG1VIDEOINFO,\n}\nimpl Default for KS_DATARANGE_MPEG1_VIDEO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATARANGE_MPEG2_VIDEO {\n    pub DataRange: KSDATAFORMAT,\n    pub bFixedSizeSamples: windows_sys::core::BOOL,\n    pub bTemporalCompression: windows_sys::core::BOOL,\n    pub StreamDescriptionFlags: u32,\n    pub MemoryAllocationFlags: u32,\n    pub ConfigCaps: KS_VIDEO_STREAM_CONFIG_CAPS,\n    pub VideoInfoHeader: KS_MPEGVIDEOINFO2,\n}\nimpl Default for KS_DATARANGE_MPEG2_VIDEO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATARANGE_VIDEO {\n    pub DataRange: KSDATAFORMAT,\n    pub bFixedSizeSamples: windows_sys::core::BOOL,\n    pub bTemporalCompression: windows_sys::core::BOOL,\n    pub StreamDescriptionFlags: u32,\n    pub MemoryAllocationFlags: u32,\n    pub ConfigCaps: KS_VIDEO_STREAM_CONFIG_CAPS,\n    pub VideoInfoHeader: KS_VIDEOINFOHEADER,\n}\nimpl Default for KS_DATARANGE_VIDEO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATARANGE_VIDEO2 {\n    pub DataRange: KSDATAFORMAT,\n    pub bFixedSizeSamples: windows_sys::core::BOOL,\n    pub bTemporalCompression: windows_sys::core::BOOL,\n    pub StreamDescriptionFlags: u32,\n    pub MemoryAllocationFlags: u32,\n    pub ConfigCaps: KS_VIDEO_STREAM_CONFIG_CAPS,\n    pub VideoInfoHeader: KS_VIDEOINFOHEADER2,\n}\nimpl Default for KS_DATARANGE_VIDEO2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATARANGE_VIDEO_PALETTE {\n    pub DataRange: KSDATAFORMAT,\n    pub bFixedSizeSamples: windows_sys::core::BOOL,\n    pub bTemporalCompression: windows_sys::core::BOOL,\n    pub StreamDescriptionFlags: u32,\n    pub MemoryAllocationFlags: u32,\n    pub ConfigCaps: KS_VIDEO_STREAM_CONFIG_CAPS,\n    pub VideoInfo: KS_VIDEOINFO,\n}\nimpl Default for KS_DATARANGE_VIDEO_PALETTE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DATARANGE_VIDEO_VBI {\n    pub DataRange: KSDATAFORMAT,\n    pub bFixedSizeSamples: windows_sys::core::BOOL,\n    pub bTemporalCompression: windows_sys::core::BOOL,\n    pub StreamDescriptionFlags: u32,\n    pub MemoryAllocationFlags: u32,\n    pub ConfigCaps: KS_VIDEO_STREAM_CONFIG_CAPS,\n    pub VBIInfoHeader: KS_VBIINFOHEADER,\n}\nimpl Default for KS_DATARANGE_VIDEO_VBI {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KS_DVDCOPYSTATE = i32;\npub const KS_DVDCOPYSTATE_AUTHENTICATION_NOT_REQUIRED: KS_DVDCOPYSTATE = 2i32;\npub const KS_DVDCOPYSTATE_AUTHENTICATION_REQUIRED: KS_DVDCOPYSTATE = 3i32;\npub const KS_DVDCOPYSTATE_DONE: KS_DVDCOPYSTATE = 4i32;\npub const KS_DVDCOPYSTATE_INITIALIZE: KS_DVDCOPYSTATE = 0i32;\npub const KS_DVDCOPYSTATE_INITIALIZE_TITLE: KS_DVDCOPYSTATE = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DVDCOPY_BUSKEY {\n    pub BusKey: [u8; 5],\n    pub Reserved: [u8; 1],\n}\nimpl Default for KS_DVDCOPY_BUSKEY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DVDCOPY_CHLGKEY {\n    pub ChlgKey: [u8; 10],\n    pub Reserved: [u8; 2],\n}\nimpl Default for KS_DVDCOPY_CHLGKEY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DVDCOPY_DISCKEY {\n    pub DiscKey: [u8; 2048],\n}\nimpl Default for KS_DVDCOPY_DISCKEY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DVDCOPY_REGION {\n    pub Reserved: u8,\n    pub RegionData: u8,\n    pub Reserved2: [u8; 2],\n}\nimpl Default for KS_DVDCOPY_REGION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_DVDCOPY_SET_COPY_STATE {\n    pub DVDCopyState: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_DVDCOPY_TITLEKEY {\n    pub KeyFlags: u32,\n    pub ReservedNT: [u32; 2],\n    pub TitleKey: [u8; 6],\n    pub Reserved: [u8; 2],\n}\nimpl Default for KS_DVDCOPY_TITLEKEY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KS_DVD_CGMS_COPY_ONCE: u32 = 16u32;\npub const KS_DVD_CGMS_COPY_PERMITTED: u32 = 0u32;\npub const KS_DVD_CGMS_COPY_PROTECT_MASK: u32 = 24u32;\npub const KS_DVD_CGMS_NO_COPY: u32 = 24u32;\npub const KS_DVD_CGMS_RESERVED_MASK: u32 = 120u32;\npub const KS_DVD_COPYRIGHTED: u32 = 64u32;\npub const KS_DVD_COPYRIGHT_MASK: u32 = 64u32;\npub const KS_DVD_NOT_COPYRIGHTED: u32 = 0u32;\npub const KS_DVD_SECTOR_NOT_PROTECTED: u32 = 0u32;\npub const KS_DVD_SECTOR_PROTECTED: u32 = 32u32;\npub const KS_DVD_SECTOR_PROTECT_MASK: u32 = 32u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_DVD_YCrCb {\n    pub Reserved: u8,\n    pub Y: u8,\n    pub Cr: u8,\n    pub Cb: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_DVD_YUV {\n    pub Reserved: u8,\n    pub Y: u8,\n    pub V: u8,\n    pub U: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_FRAME_INFO {\n    pub ExtendedHeaderSize: u32,\n    pub dwFrameFlags: u32,\n    pub PictureNumber: i64,\n    pub DropCount: i64,\n    pub hDirectDraw: super::super::Foundation::HANDLE,\n    pub hSurfaceHandle: super::super::Foundation::HANDLE,\n    pub DirectDrawRect: super::super::Foundation::RECT,\n    pub Anonymous1: KS_FRAME_INFO_0,\n    pub Reserved2: u32,\n    pub Anonymous2: KS_FRAME_INFO_1,\n}\nimpl Default for KS_FRAME_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KS_FRAME_INFO_0 {\n    pub lSurfacePitch: i32,\n    pub Reserved1: u32,\n}\nimpl Default for KS_FRAME_INFO_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KS_FRAME_INFO_1 {\n    pub Anonymous: KS_FRAME_INFO_1_0,\n    pub FrameCompletionNumber: u64,\n}\nimpl Default for KS_FRAME_INFO_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_FRAME_INFO_1_0 {\n    pub Reserved3: u32,\n    pub Reserved4: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_FRAMING_ITEM {\n    pub MemoryType: windows_sys::core::GUID,\n    pub BusType: windows_sys::core::GUID,\n    pub MemoryFlags: u32,\n    pub BusFlags: u32,\n    pub Flags: u32,\n    pub Frames: u32,\n    pub Anonymous: KS_FRAMING_ITEM_0,\n    pub MemoryTypeWeight: u32,\n    pub PhysicalRange: KS_FRAMING_RANGE,\n    pub FramingRange: KS_FRAMING_RANGE_WEIGHTED,\n}\nimpl Default for KS_FRAMING_ITEM {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KS_FRAMING_ITEM_0 {\n    pub FileAlignment: u32,\n    pub FramePitch: i32,\n}\nimpl Default for KS_FRAMING_ITEM_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_FRAMING_RANGE {\n    pub MinFrameSize: u32,\n    pub MaxFrameSize: u32,\n    pub Stepping: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_FRAMING_RANGE_WEIGHTED {\n    pub Range: KS_FRAMING_RANGE,\n    pub InPlaceWeight: u32,\n    pub NotInPlaceWeight: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_H264VIDEOINFO {\n    pub wWidth: u16,\n    pub wHeight: u16,\n    pub wSARwidth: u16,\n    pub wSARheight: u16,\n    pub wProfile: u16,\n    pub bLevelIDC: u8,\n    pub wConstrainedToolset: u16,\n    pub bmSupportedUsages: u32,\n    pub bmCapabilities: u16,\n    pub bmSVCCapabilities: u32,\n    pub bmMVCCapabilities: u32,\n    pub dwFrameInterval: u32,\n    pub bMaxCodecConfigDelay: u8,\n    pub bmSupportedSliceModes: u8,\n    pub bmSupportedSyncFrameTypes: u8,\n    pub bResolutionScaling: u8,\n    pub bSimulcastSupport: u8,\n    pub bmSupportedRateControlModes: u8,\n    pub wMaxMBperSecOneResolutionNoScalability: u16,\n    pub wMaxMBperSecTwoResolutionsNoScalability: u16,\n    pub wMaxMBperSecThreeResolutionsNoScalability: u16,\n    pub wMaxMBperSecFourResolutionsNoScalability: u16,\n    pub wMaxMBperSecOneResolutionTemporalScalability: u16,\n    pub wMaxMBperSecTwoResolutionsTemporalScalablility: u16,\n    pub wMaxMBperSecThreeResolutionsTemporalScalability: u16,\n    pub wMaxMBperSecFourResolutionsTemporalScalability: u16,\n    pub wMaxMBperSecOneResolutionTemporalQualityScalability: u16,\n    pub wMaxMBperSecTwoResolutionsTemporalQualityScalability: u16,\n    pub wMaxMBperSecThreeResolutionsTemporalQualityScalablity: u16,\n    pub wMaxMBperSecFourResolutionsTemporalQualityScalability: u16,\n    pub wMaxMBperSecOneResolutionTemporalSpatialScalability: u16,\n    pub wMaxMBperSecTwoResolutionsTemporalSpatialScalability: u16,\n    pub wMaxMBperSecThreeResolutionsTemporalSpatialScalablity: u16,\n    pub wMaxMBperSecFourResolutionsTemporalSpatialScalability: u16,\n    pub wMaxMBperSecOneResolutionFullScalability: u16,\n    pub wMaxMBperSecTwoResolutionsFullScalability: u16,\n    pub wMaxMBperSecThreeResolutionsFullScalability: u16,\n    pub wMaxMBperSecFourResolutionsFullScalability: u16,\n}\npub const KS_INTERLACE_1FieldPerSample: u32 = 2u32;\npub const KS_INTERLACE_DisplayModeBobOnly: u32 = 0u32;\npub const KS_INTERLACE_DisplayModeBobOrWeave: u32 = 128u32;\npub const KS_INTERLACE_DisplayModeMask: u32 = 192u32;\npub const KS_INTERLACE_DisplayModeWeaveOnly: u32 = 64u32;\npub const KS_INTERLACE_Field1First: u32 = 4u32;\npub const KS_INTERLACE_FieldPatBothIrregular: u32 = 48u32;\npub const KS_INTERLACE_FieldPatBothRegular: u32 = 32u32;\npub const KS_INTERLACE_FieldPatField1Only: u32 = 0u32;\npub const KS_INTERLACE_FieldPatField2Only: u32 = 16u32;\npub const KS_INTERLACE_FieldPatternMask: u32 = 48u32;\npub const KS_INTERLACE_IsInterlaced: u32 = 1u32;\npub const KS_INTERLACE_UNUSED: u32 = 8u32;\npub type KS_LogicalMemoryType = i32;\npub const KS_MACROVISION_DISABLED: KS_COPY_MACROVISION_LEVEL = 0i32;\npub const KS_MACROVISION_LEVEL1: KS_COPY_MACROVISION_LEVEL = 1i32;\npub const KS_MACROVISION_LEVEL2: KS_COPY_MACROVISION_LEVEL = 2i32;\npub const KS_MACROVISION_LEVEL3: KS_COPY_MACROVISION_LEVEL = 3i32;\npub const KS_MAX_SIZE_MPEG1_SEQUENCE_INFO: u32 = 140u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_MPEG1VIDEOINFO {\n    pub hdr: KS_VIDEOINFOHEADER,\n    pub dwStartTimeCode: u32,\n    pub cbSequenceHeader: u32,\n    pub bSequenceHeader: [u8; 1],\n}\nimpl Default for KS_MPEG1VIDEOINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KS_MPEG2Level = i32;\npub const KS_MPEG2Level_High: KS_MPEG2Level = 3i32;\npub const KS_MPEG2Level_High1440: KS_MPEG2Level = 2i32;\npub const KS_MPEG2Level_Low: KS_MPEG2Level = 0i32;\npub const KS_MPEG2Level_Main: KS_MPEG2Level = 1i32;\npub type KS_MPEG2Profile = i32;\npub const KS_MPEG2Profile_High: KS_MPEG2Profile = 4i32;\npub const KS_MPEG2Profile_Main: KS_MPEG2Profile = 1i32;\npub const KS_MPEG2Profile_SNRScalable: KS_MPEG2Profile = 2i32;\npub const KS_MPEG2Profile_Simple: KS_MPEG2Profile = 0i32;\npub const KS_MPEG2Profile_SpatiallyScalable: KS_MPEG2Profile = 3i32;\npub const KS_MPEG2_27MhzTimebase: u32 = 256u32;\npub const KS_MPEG2_DSS_UserData: u32 = 64u32;\npub const KS_MPEG2_DVB_UserData: u32 = 128u32;\npub const KS_MPEG2_DVDLine21Field1: u32 = 2u32;\npub const KS_MPEG2_DVDLine21Field2: u32 = 4u32;\npub const KS_MPEG2_DoPanScan: u32 = 1u32;\npub const KS_MPEG2_FilmCameraMode: u32 = 16u32;\npub const KS_MPEG2_LetterboxAnalogOut: u32 = 32u32;\npub const KS_MPEG2_SourceIsLetterboxed: u32 = 8u32;\npub const KS_MPEG2_WidescreenAnalogOut: u32 = 512u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_MPEGAUDIOINFO {\n    pub dwFlags: u32,\n    pub dwReserved1: u32,\n    pub dwReserved2: u32,\n    pub dwReserved3: u32,\n}\npub const KS_MPEGAUDIOINFO_27MhzTimebase: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_MPEGVIDEOINFO2 {\n    pub hdr: KS_VIDEOINFOHEADER2,\n    pub dwStartTimeCode: u32,\n    pub cbSequenceHeader: u32,\n    pub dwProfile: u32,\n    pub dwLevel: u32,\n    pub dwFlags: u32,\n    pub bSequenceHeader: [u32; 1],\n}\nimpl Default for KS_MPEGVIDEOINFO2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KS_MemoryTypeAnyHost: KS_LogicalMemoryType = 6i32;\npub const KS_MemoryTypeDeviceHostMapped: KS_LogicalMemoryType = 3i32;\npub const KS_MemoryTypeDeviceSpecific: KS_LogicalMemoryType = 4i32;\npub const KS_MemoryTypeDontCare: KS_LogicalMemoryType = 0i32;\npub const KS_MemoryTypeKernelNonPaged: KS_LogicalMemoryType = 2i32;\npub const KS_MemoryTypeKernelPaged: KS_LogicalMemoryType = 1i32;\npub const KS_MemoryTypeUser: KS_LogicalMemoryType = 5i32;\npub const KS_NABTS_GROUPID_LOCAL_CABLE_SYSTEM_ADVERTISER_BASE: u32 = 2224u32;\npub const KS_NABTS_GROUPID_LOCAL_CABLE_SYSTEM_CONTENT_BASE: u32 = 2208u32;\npub const KS_NABTS_GROUPID_MICROSOFT_RESERVED_TEST_DATA_BASE: u32 = 2288u32;\npub const KS_NABTS_GROUPID_NETWORK_WIDE_ADVERTISER_BASE: u32 = 2160u32;\npub const KS_NABTS_GROUPID_NETWORK_WIDE_CONTENT_BASE: u32 = 2144u32;\npub const KS_NABTS_GROUPID_ORIGINAL_CONTENT_ADVERTISER_BASE: u32 = 2064u32;\npub const KS_NABTS_GROUPID_ORIGINAL_CONTENT_BASE: u32 = 2048u32;\npub const KS_NABTS_GROUPID_PRODUCTION_COMPANY_ADVERTISER_BASE: u32 = 2096u32;\npub const KS_NABTS_GROUPID_PRODUCTION_COMPANY_CONTENT_BASE: u32 = 2080u32;\npub const KS_NABTS_GROUPID_SYNDICATED_SHOW_ADVERTISER_BASE: u32 = 2128u32;\npub const KS_NABTS_GROUPID_SYNDICATED_SHOW_CONTENT_BASE: u32 = 2112u32;\npub const KS_NABTS_GROUPID_TELEVISION_STATION_ADVERTISER_BASE: u32 = 2192u32;\npub const KS_NABTS_GROUPID_TELEVISION_STATION_CONTENT_BASE: u32 = 2176u32;\npub const KS_Obsolete_VideoControlFlag_ExternalTriggerEnable: KS_VideoControlFlags = 16i32;\npub const KS_Obsolete_VideoControlFlag_Trigger: KS_VideoControlFlags = 32i32;\npub const KS_PhysConn_Audio_1394: KS_PhysicalConnectorType = 4103i32;\npub const KS_PhysConn_Audio_AESDigital: KS_PhysicalConnectorType = 4099i32;\npub const KS_PhysConn_Audio_AUX: KS_PhysicalConnectorType = 4102i32;\npub const KS_PhysConn_Audio_AudioDecoder: KS_PhysicalConnectorType = 4105i32;\npub const KS_PhysConn_Audio_Line: KS_PhysicalConnectorType = 4097i32;\npub const KS_PhysConn_Audio_Mic: KS_PhysicalConnectorType = 4098i32;\npub const KS_PhysConn_Audio_SCSI: KS_PhysicalConnectorType = 4101i32;\npub const KS_PhysConn_Audio_SPDIFDigital: KS_PhysicalConnectorType = 4100i32;\npub const KS_PhysConn_Audio_Tuner: KS_PhysicalConnectorType = 4096i32;\npub const KS_PhysConn_Audio_USB: KS_PhysicalConnectorType = 4104i32;\npub const KS_PhysConn_Video_1394: KS_PhysicalConnectorType = 10i32;\npub const KS_PhysConn_Video_AUX: KS_PhysicalConnectorType = 9i32;\npub const KS_PhysConn_Video_Composite: KS_PhysicalConnectorType = 2i32;\npub const KS_PhysConn_Video_ParallelDigital: KS_PhysicalConnectorType = 7i32;\npub const KS_PhysConn_Video_RGB: KS_PhysicalConnectorType = 4i32;\npub const KS_PhysConn_Video_SCART: KS_PhysicalConnectorType = 14i32;\npub const KS_PhysConn_Video_SCSI: KS_PhysicalConnectorType = 8i32;\npub const KS_PhysConn_Video_SVideo: KS_PhysicalConnectorType = 3i32;\npub const KS_PhysConn_Video_SerialDigital: KS_PhysicalConnectorType = 6i32;\npub const KS_PhysConn_Video_Tuner: KS_PhysicalConnectorType = 1i32;\npub const KS_PhysConn_Video_USB: KS_PhysicalConnectorType = 11i32;\npub const KS_PhysConn_Video_VideoDecoder: KS_PhysicalConnectorType = 12i32;\npub const KS_PhysConn_Video_VideoEncoder: KS_PhysicalConnectorType = 13i32;\npub const KS_PhysConn_Video_YRYBY: KS_PhysicalConnectorType = 5i32;\npub type KS_PhysicalConnectorType = i32;\npub const KS_PixAspectRatio_NTSC16x9: KS_AMPixAspectRatio = 1i32;\npub const KS_PixAspectRatio_NTSC4x3: KS_AMPixAspectRatio = 0i32;\npub const KS_PixAspectRatio_PAL16x9: KS_AMPixAspectRatio = 3i32;\npub const KS_PixAspectRatio_PAL4x3: KS_AMPixAspectRatio = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_RGBQUAD {\n    pub rgbBlue: u8,\n    pub rgbGreen: u8,\n    pub rgbRed: u8,\n    pub rgbReserved: u8,\n}\npub const KS_SECURE_CAMERA_SCENARIO_ID: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xae53fc6e_8d89_4488_9d2e_4d008731c5fd);\npub const KS_SEEKING_AbsolutePositioning: KS_SEEKING_FLAGS = 1i32;\npub type KS_SEEKING_CAPABILITIES = i32;\npub const KS_SEEKING_CanGetCurrentPos: KS_SEEKING_CAPABILITIES = 8i32;\npub const KS_SEEKING_CanGetDuration: KS_SEEKING_CAPABILITIES = 32i32;\npub const KS_SEEKING_CanGetStopPos: KS_SEEKING_CAPABILITIES = 16i32;\npub const KS_SEEKING_CanPlayBackwards: KS_SEEKING_CAPABILITIES = 64i32;\npub const KS_SEEKING_CanSeekAbsolute: KS_SEEKING_CAPABILITIES = 1i32;\npub const KS_SEEKING_CanSeekBackwards: KS_SEEKING_CAPABILITIES = 4i32;\npub const KS_SEEKING_CanSeekForwards: KS_SEEKING_CAPABILITIES = 2i32;\npub type KS_SEEKING_FLAGS = i32;\npub const KS_SEEKING_IncrementalPositioning: KS_SEEKING_FLAGS = 3i32;\npub const KS_SEEKING_NoPositioning: KS_SEEKING_FLAGS = 0i32;\npub const KS_SEEKING_PositioningBitsMask: KS_SEEKING_FLAGS = 3i32;\npub const KS_SEEKING_RelativePositioning: KS_SEEKING_FLAGS = 2i32;\npub const KS_SEEKING_ReturnTime: KS_SEEKING_FLAGS = 8i32;\npub const KS_SEEKING_SeekToKeyFrame: KS_SEEKING_FLAGS = 4i32;\npub const KS_StreamingHint_CompQuality: KS_VideoStreamingHints = 2048i32;\npub const KS_StreamingHint_CompWindowSize: KS_VideoStreamingHints = 4096i32;\npub const KS_StreamingHint_FrameInterval: KS_VideoStreamingHints = 256i32;\npub const KS_StreamingHint_KeyFrameRate: KS_VideoStreamingHints = 512i32;\npub const KS_StreamingHint_PFrameRate: KS_VideoStreamingHints = 1024i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_TRUECOLORINFO {\n    pub dwBitMasks: [u32; 3],\n    pub bmiColors: [KS_RGBQUAD; 256],\n}\nimpl Default for KS_TRUECOLORINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type KS_TUNER_STRATEGY = i32;\npub const KS_TUNER_STRATEGY_DRIVER_TUNES: KS_TUNER_STRATEGY = 4i32;\npub const KS_TUNER_STRATEGY_PLL: KS_TUNER_STRATEGY = 1i32;\npub const KS_TUNER_STRATEGY_SIGNAL_STRENGTH: KS_TUNER_STRATEGY = 2i32;\npub const KS_TUNER_TUNING_COARSE: KS_TUNER_TUNING_FLAGS = 3i32;\npub const KS_TUNER_TUNING_EXACT: KS_TUNER_TUNING_FLAGS = 1i32;\npub const KS_TUNER_TUNING_FINE: KS_TUNER_TUNING_FLAGS = 2i32;\npub type KS_TUNER_TUNING_FLAGS = i32;\npub const KS_TVAUDIO_MODE_LANG_A: u32 = 16u32;\npub const KS_TVAUDIO_MODE_LANG_B: u32 = 32u32;\npub const KS_TVAUDIO_MODE_LANG_C: u32 = 64u32;\npub const KS_TVAUDIO_MODE_MONO: u32 = 1u32;\npub const KS_TVAUDIO_MODE_STEREO: u32 = 2u32;\npub const KS_TVAUDIO_PRESET_LANG_A: u32 = 4096u32;\npub const KS_TVAUDIO_PRESET_LANG_B: u32 = 8192u32;\npub const KS_TVAUDIO_PRESET_LANG_C: u32 = 16384u32;\npub const KS_TVAUDIO_PRESET_STEREO: u32 = 512u32;\npub const KS_TVTUNER_CHANGE_BEGIN_TUNE: i32 = 1i32;\npub const KS_TVTUNER_CHANGE_END_TUNE: i32 = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_TVTUNER_CHANGE_INFO {\n    pub dwFlags: u32,\n    pub dwCountryCode: u32,\n    pub dwAnalogVideoStandard: u32,\n    pub dwChannel: u32,\n}\npub const KS_VBICAP_PROTECTION_MV_DETECTED: i32 = 4i32;\npub const KS_VBICAP_PROTECTION_MV_HARDWARE: i32 = 2i32;\npub const KS_VBICAP_PROTECTION_MV_PRESENT: i32 = 1i32;\npub const KS_VBIDATARATE_CC: i32 = 503493i32;\npub const KS_VBIDATARATE_NABTS: i32 = 5727272i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_VBIINFOHEADER {\n    pub StartLine: u32,\n    pub EndLine: u32,\n    pub SamplingFrequency: u32,\n    pub MinLineStartTime: u32,\n    pub MaxLineStartTime: u32,\n    pub ActualLineStartTime: u32,\n    pub ActualLineEndTime: u32,\n    pub VideoStandard: u32,\n    pub SamplesPerLine: u32,\n    pub StrideInBytes: u32,\n    pub BufferSize: u32,\n}\npub const KS_VBI_FLAG_FIELD1: i32 = 1i32;\npub const KS_VBI_FLAG_FIELD2: i32 = 2i32;\npub const KS_VBI_FLAG_FRAME: i32 = 0i32;\npub const KS_VBI_FLAG_MV_DETECTED: i32 = 1024i32;\npub const KS_VBI_FLAG_MV_HARDWARE: i32 = 512i32;\npub const KS_VBI_FLAG_MV_PRESENT: i32 = 256i32;\npub const KS_VBI_FLAG_TVTUNER_CHANGE: i32 = 16i32;\npub const KS_VBI_FLAG_VBIINFOHEADER_CHANGE: i32 = 32i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_VBI_FRAME_INFO {\n    pub ExtendedHeaderSize: u32,\n    pub dwFrameFlags: u32,\n    pub PictureNumber: i64,\n    pub DropCount: i64,\n    pub dwSamplingFrequency: u32,\n    pub TvTunerChangeInfo: KS_TVTUNER_CHANGE_INFO,\n    pub VBIInfoHeader: KS_VBIINFOHEADER,\n}\npub type KS_VIDEODECODER_FLAGS = i32;\npub const KS_VIDEODECODER_FLAGS_CAN_DISABLE_OUTPUT: KS_VIDEODECODER_FLAGS = 1i32;\npub const KS_VIDEODECODER_FLAGS_CAN_INDICATE_LOCKED: KS_VIDEODECODER_FLAGS = 4i32;\npub const KS_VIDEODECODER_FLAGS_CAN_USE_VCR_LOCKING: KS_VIDEODECODER_FLAGS = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_VIDEOINFO {\n    pub rcSource: super::super::Foundation::RECT,\n    pub rcTarget: super::super::Foundation::RECT,\n    pub dwBitRate: u32,\n    pub dwBitErrorRate: u32,\n    pub AvgTimePerFrame: i64,\n    pub bmiHeader: KS_BITMAPINFOHEADER,\n    pub Anonymous: KS_VIDEOINFO_0,\n}\nimpl Default for KS_VIDEOINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KS_VIDEOINFO_0 {\n    pub bmiColors: [KS_RGBQUAD; 256],\n    pub dwBitMasks: [u32; 3],\n    pub TrueColorInfo: KS_TRUECOLORINFO,\n}\nimpl Default for KS_VIDEOINFO_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_VIDEOINFOHEADER {\n    pub rcSource: super::super::Foundation::RECT,\n    pub rcTarget: super::super::Foundation::RECT,\n    pub dwBitRate: u32,\n    pub dwBitErrorRate: u32,\n    pub AvgTimePerFrame: i64,\n    pub bmiHeader: KS_BITMAPINFOHEADER,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct KS_VIDEOINFOHEADER2 {\n    pub rcSource: super::super::Foundation::RECT,\n    pub rcTarget: super::super::Foundation::RECT,\n    pub dwBitRate: u32,\n    pub dwBitErrorRate: u32,\n    pub AvgTimePerFrame: i64,\n    pub dwInterlaceFlags: u32,\n    pub dwCopyProtectFlags: u32,\n    pub dwPictAspectRatioX: u32,\n    pub dwPictAspectRatioY: u32,\n    pub Anonymous: KS_VIDEOINFOHEADER2_0,\n    pub dwReserved2: u32,\n    pub bmiHeader: KS_BITMAPINFOHEADER,\n}\nimpl Default for KS_VIDEOINFOHEADER2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union KS_VIDEOINFOHEADER2_0 {\n    pub dwControlFlags: u32,\n    pub dwReserved1: u32,\n}\nimpl Default for KS_VIDEOINFOHEADER2_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const KS_VIDEOSTREAM_CAPTURE: u32 = 2u32;\npub const KS_VIDEOSTREAM_CC: u32 = 256u32;\npub const KS_VIDEOSTREAM_EDS: u32 = 512u32;\npub const KS_VIDEOSTREAM_IS_VPE: u32 = 32768u32;\npub const KS_VIDEOSTREAM_NABTS: u32 = 32u32;\npub const KS_VIDEOSTREAM_PREVIEW: u32 = 1u32;\npub const KS_VIDEOSTREAM_STILL: u32 = 4096u32;\npub const KS_VIDEOSTREAM_TELETEXT: u32 = 1024u32;\npub const KS_VIDEOSTREAM_VBI: u32 = 16u32;\npub const KS_VIDEO_ALLOC_VPE_AGP: u32 = 4u32;\npub const KS_VIDEO_ALLOC_VPE_DISPLAY: u32 = 2u32;\npub const KS_VIDEO_ALLOC_VPE_SYSTEM: u32 = 1u32;\npub const KS_VIDEO_FLAG_B_FRAME: i32 = 32i32;\npub const KS_VIDEO_FLAG_FIELD1: i32 = 1i32;\npub const KS_VIDEO_FLAG_FIELD1FIRST: i32 = 4i32;\npub const KS_VIDEO_FLAG_FIELD2: i32 = 2i32;\npub const KS_VIDEO_FLAG_FIELD_MASK: i32 = 3i32;\npub const KS_VIDEO_FLAG_FRAME: i32 = 0i32;\npub const KS_VIDEO_FLAG_IPB_MASK: i32 = 48i32;\npub const KS_VIDEO_FLAG_I_FRAME: i32 = 0i32;\npub const KS_VIDEO_FLAG_P_FRAME: i32 = 16i32;\npub const KS_VIDEO_FLAG_REPEAT_FIELD: i32 = 64i32;\npub const KS_VIDEO_FLAG_WEAVE: i32 = 8i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct KS_VIDEO_STREAM_CONFIG_CAPS {\n    pub guid: windows_sys::core::GUID,\n    pub VideoStandard: u32,\n    pub InputSize: super::super::Foundation::SIZE,\n    pub MinCroppingSize: super::super::Foundation::SIZE,\n    pub MaxCroppingSize: super::super::Foundation::SIZE,\n    pub CropGranularityX: i32,\n    pub CropGranularityY: i32,\n    pub CropAlignX: i32,\n    pub CropAlignY: i32,\n    pub MinOutputSize: super::super::Foundation::SIZE,\n    pub MaxOutputSize: super::super::Foundation::SIZE,\n    pub OutputGranularityX: i32,\n    pub OutputGranularityY: i32,\n    pub StretchTapsX: i32,\n    pub StretchTapsY: i32,\n    pub ShrinkTapsX: i32,\n    pub ShrinkTapsY: i32,\n    pub MinFrameInterval: i64,\n    pub MaxFrameInterval: i64,\n    pub MinBitsPerSecond: i32,\n    pub MaxBitsPerSecond: i32,\n}\npub const KS_VideoControlFlag_ExternalTriggerEnable: KS_VideoControlFlags = 4i32;\npub const KS_VideoControlFlag_FlipHorizontal: KS_VideoControlFlags = 1i32;\npub const KS_VideoControlFlag_FlipVertical: KS_VideoControlFlags = 2i32;\npub const KS_VideoControlFlag_IndependentImagePin: KS_VideoControlFlags = 64i32;\npub const KS_VideoControlFlag_StartPhotoSequenceCapture: KS_VideoControlFlags = 256i32;\npub const KS_VideoControlFlag_StillCapturePreviewFrame: KS_VideoControlFlags = 128i32;\npub const KS_VideoControlFlag_StopPhotoSequenceCapture: KS_VideoControlFlags = 512i32;\npub const KS_VideoControlFlag_Trigger: KS_VideoControlFlags = 8i32;\npub type KS_VideoControlFlags = i32;\npub type KS_VideoStreamingHints = i32;\npub const KS_iBLUE: u32 = 2u32;\npub const KS_iEGA_COLORS: u32 = 16u32;\npub const KS_iGREEN: u32 = 1u32;\npub const KS_iMASK_COLORS: u32 = 3u32;\npub const KS_iMAXBITS: u32 = 8u32;\npub const KS_iPALETTE: u32 = 8u32;\npub const KS_iPALETTE_COLORS: u32 = 256u32;\npub const KS_iRED: u32 = 0u32;\npub const KS_iTRUECOLOR: u32 = 16u32;\npub const KsAllocatorMode_Kernel: KSALLOCATORMODE = 1i32;\npub const KsAllocatorMode_User: KSALLOCATORMODE = 0i32;\npub const KsIoOperation_Read: KSIOOPERATION = 1i32;\npub const KsIoOperation_Write: KSIOOPERATION = 0i32;\npub const KsPeekOperation_AddRef: KSPEEKOPERATION = 1i32;\npub const KsPeekOperation_PeekOnly: KSPEEKOPERATION = 0i32;\npub const LIGHT_FILTER: KSDS3D_HRTF_FILTER_QUALITY = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LOOPEDSTREAMING_POSITION_EVENT_DATA {\n    pub KsEventData: KSEVENTDATA,\n    pub Position: u64,\n}\nimpl Default for LOOPEDSTREAMING_POSITION_EVENT_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MAX_NABTS_VBI_LINES_PER_FIELD: u32 = 11u32;\npub const MAX_RESOURCEGROUPID_LENGTH: u32 = 256u32;\npub const MAX_SINK_DESCRIPTION_NAME_LENGTH: u32 = 32u32;\npub const MAX_WST_VBI_LINES_PER_FIELD: u32 = 17u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct MEDIUM_INFO {\n    pub MediaPresent: windows_sys::core::BOOL,\n    pub MediaType: u32,\n    pub RecordInhibit: windows_sys::core::BOOL,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union MF_MDL_SHARED_PAYLOAD_KEY {\n    pub combined: MF_MDL_SHARED_PAYLOAD_KEY_0,\n    pub GMDLHandle: windows_sys::core::GUID,\n}\nimpl Default for MF_MDL_SHARED_PAYLOAD_KEY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct MF_MDL_SHARED_PAYLOAD_KEY_0 {\n    pub pHandle: u32,\n    pub fHandle: u32,\n    pub uPayload: u64,\n}\npub const MIN_DEV_VER_FOR_FLAGS: u32 = 272u32;\npub const MIN_DEV_VER_FOR_QI: u32 = 256u32;\npub const MetadataId_BackgroundSegmentationMask: KSCAMERA_MetadataId = 8i32;\npub const MetadataId_CameraExtrinsics: KSCAMERA_MetadataId = 4i32;\npub const MetadataId_CameraIntrinsics: KSCAMERA_MetadataId = 5i32;\npub const MetadataId_CaptureStats: KSCAMERA_MetadataId = 3i32;\npub const MetadataId_Custom_Start: KSCAMERA_MetadataId = -2147483648i32;\npub const MetadataId_DigitalWindow: KSCAMERA_MetadataId = 7i32;\npub const MetadataId_FrameIllumination: KSCAMERA_MetadataId = 6i32;\npub const MetadataId_PhotoConfirmation: KSCAMERA_MetadataId = 1i32;\npub const MetadataId_Standard_End: KSCAMERA_MetadataId = 8i32;\npub const MetadataId_Standard_Start: KSCAMERA_MetadataId = 1i32;\npub const MetadataId_UsbVideoHeader: KSCAMERA_MetadataId = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NABTSFEC_BUFFER {\n    pub dataSize: u32,\n    pub groupID: u16,\n    pub Reserved: u16,\n    pub data: [u8; 448],\n}\nimpl Default for NABTSFEC_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct NABTS_BUFFER {\n    pub ScanlinesRequested: VBICODECFILTERING_SCANLINES,\n    pub PictureNumber: i64,\n    pub NabtsLines: [NABTS_BUFFER_LINE; 11],\n}\nimpl Default for NABTS_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NABTS_BUFFER_LINE {\n    pub Confidence: u8,\n    pub Bytes: [u8; 36],\n}\nimpl Default for NABTS_BUFFER_LINE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const NABTS_BUFFER_PICTURENUMBER_SUPPORT: u32 = 1u32;\npub const NABTS_BYTES_PER_LINE: u32 = 36u32;\npub const NABTS_LINES_PER_BUNDLE: u32 = 16u32;\npub const NABTS_PAYLOAD_PER_LINE: u32 = 28u32;\npub const NANOSECONDS: u32 = 10000000u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct OPTIMAL_WEIGHT_TOTALS {\n    pub MinTotalNominator: i64,\n    pub MaxTotalNominator: i64,\n    pub TotalDenominator: i64,\n}\npub const PINNAME_DISPLAYPORT_OUT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x21fbb329_1a4a_48da_a076_2318a3c59b26);\npub const PINNAME_HDMI_OUT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x387bfc03_e7ef_4901_86e0_35b7c32b00ef);\npub const PINNAME_IMAGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x38a0cd98_d49b_4ce8_b48a_344667a17830);\npub const PINNAME_SPDIF_IN: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x15dc9025_22ad_41b3_8875_f4ceb0299e20);\npub const PINNAME_SPDIF_OUT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3a264481_e52c_4b82_8e7a_c8e2f91dc380);\npub const PINNAME_VIDEO_ANALOGVIDEOIN: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c4283_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_CAPTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c4281_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_CC: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c4289_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_CC_CAPTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1aad8061_012d_11d2_b4b1_00a0d102cfbe);\npub const PINNAME_VIDEO_EDS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c4287_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_NABTS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c4286_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_NABTS_CAPTURE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x29703660_498a_11d2_b4b1_00a0d102cfbe);\npub const PINNAME_VIDEO_PREVIEW: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c4282_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_STILL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c428a_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_TELETEXT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c4288_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_TIMECODE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c428b_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_VBI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c4284_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_VIDEOPORT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c4285_0353_11d1_905f_0000c0cc16ba);\npub const PINNAME_VIDEO_VIDEOPORT_VBI: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfb6c428c_0353_11d1_905f_0000c0cc16ba);\npub type PIPE_ALLOCATOR_PLACE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PIPE_DIMENSIONS {\n    pub AllocatorPin: KS_COMPRESSION,\n    pub MaxExpansionPin: KS_COMPRESSION,\n    pub EndPin: KS_COMPRESSION,\n}\npub type PIPE_STATE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PIPE_TERMINATION {\n    pub Flags: u32,\n    pub OutsideFactors: u32,\n    pub Weigth: u32,\n    pub PhysicalRange: KS_FRAMING_RANGE,\n    pub OptimalRange: KS_FRAMING_RANGE_WEIGHTED,\n    pub Compression: KS_COMPRESSION,\n}\npub const PROPSETID_ALLOCATOR_CONTROL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53171960_148e_11d2_9979_0000c0cc16ba);\npub const PROPSETID_EXT_DEVICE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb5730a90_1a2c_11cf_8c23_00aa006b6814);\npub const PROPSETID_EXT_TRANSPORT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa03cd5f0_3045_11cf_8c44_00aa006b6814);\npub const PROPSETID_TIMECODE_READER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9b496ce1_811b_11cf_8c77_00aa006b6814);\npub const PROPSETID_TUNER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6a2e0605_28e4_11d0_a18c_00a0c9118956);\npub const PROPSETID_VIDCAP_CAMERACONTROL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc6e13370_30ac_11d0_a18c_00a0c9118956);\npub const PROPSETID_VIDCAP_CAMERACONTROL_FLASH: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x785e8f49_63a2_4144_ab70_ffb278fa26ce);\npub const PROPSETID_VIDCAP_CAMERACONTROL_IMAGE_PIN_CAPABILITY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9d3d7bbf_5c6d_4138_bb00_584edd20f7c5);\npub const PROPSETID_VIDCAP_CAMERACONTROL_REGION_OF_INTEREST: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9d12d198_f86c_4fed_b023_5d87653da793);\npub const PROPSETID_VIDCAP_CAMERACONTROL_VIDEO_STABILIZATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x43964bd3_7716_404e_8be1_d299b20e50fd);\npub const PROPSETID_VIDCAP_CROSSBAR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6a2e0640_28e4_11d0_a18c_00a0c9118956);\npub const PROPSETID_VIDCAP_DROPPEDFRAMES: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc6e13344_30ac_11d0_a18c_00a0c9118956);\npub const PROPSETID_VIDCAP_SELECTOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1abdaeca_68b6_4f83_9371_b413907c7b9f);\npub const PROPSETID_VIDCAP_TVAUDIO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6a2e0650_28e4_11d0_a18c_00a0c9118956);\npub const PROPSETID_VIDCAP_VIDEOCOMPRESSION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc6e13343_30ac_11d0_a18c_00a0c9118956);\npub const PROPSETID_VIDCAP_VIDEOCONTROL: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6a2e0670_28e4_11d0_a18c_00a0c9118956);\npub const PROPSETID_VIDCAP_VIDEODECODER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc6e13350_30ac_11d0_a18c_00a0c9118956);\npub const PROPSETID_VIDCAP_VIDEOENCODER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6a2e0610_28e4_11d0_a18c_00a0c9118956);\npub const PROPSETID_VIDCAP_VIDEOPROCAMP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc6e13360_30ac_11d0_a18c_00a0c9118956);\npub const PipeFactor_Align: u32 = 512u32;\npub const PipeFactor_Buffers: u32 = 256u32;\npub const PipeFactor_FixedCompression: u32 = 64u32;\npub const PipeFactor_Flags: u32 = 8u32;\npub const PipeFactor_LogicalEnd: u32 = 2048u32;\npub const PipeFactor_MemoryTypes: u32 = 4u32;\npub const PipeFactor_None: u32 = 0u32;\npub const PipeFactor_OptimalRanges: u32 = 32u32;\npub const PipeFactor_PhysicalEnd: u32 = 1024u32;\npub const PipeFactor_PhysicalRanges: u32 = 16u32;\npub const PipeFactor_UnknownCompression: u32 = 128u32;\npub const PipeFactor_UserModeDownstream: u32 = 2u32;\npub const PipeFactor_UserModeUpstream: u32 = 1u32;\npub const PipeState_CompressionUnknown: PIPE_STATE = 3i32;\npub const PipeState_DontCare: PIPE_STATE = 0i32;\npub const PipeState_Finalized: PIPE_STATE = 4i32;\npub const PipeState_RangeFixed: PIPE_STATE = 2i32;\npub const PipeState_RangeNotFixed: PIPE_STATE = 1i32;\npub const Pipe_Allocator_FirstPin: PIPE_ALLOCATOR_PLACE = 1i32;\npub const Pipe_Allocator_LastPin: PIPE_ALLOCATOR_PLACE = 2i32;\npub const Pipe_Allocator_MiddlePin: PIPE_ALLOCATOR_PLACE = 3i32;\npub const Pipe_Allocator_None: PIPE_ALLOCATOR_PLACE = 0i32;\npub const RT_RCDATA: windows_sys::core::PCWSTR = 10u16 as _;\npub const RT_STRING: windows_sys::core::PCWSTR = 6u16 as _;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SECURE_BUFFER_INFO {\n    pub guidBufferIdentifier: windows_sys::core::GUID,\n    pub cbBufferSize: u32,\n    pub cbCaptured: u32,\n    pub ullReserved: [u64; 16],\n}\nimpl Default for SECURE_BUFFER_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SHORT_COEFF: KSDS3D_HRTF_COEFF_FORMAT = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SOUNDDETECTOR_PATTERNHEADER {\n    pub Size: u32,\n    pub PatternType: windows_sys::core::GUID,\n}\npub const SPEAKER_ALL: u32 = 2147483648u32;\npub const SPEAKER_BACK_CENTER: u32 = 256u32;\npub const SPEAKER_BACK_LEFT: u32 = 16u32;\npub const SPEAKER_BACK_RIGHT: u32 = 32u32;\npub const SPEAKER_FRONT_CENTER: u32 = 4u32;\npub const SPEAKER_FRONT_LEFT: u32 = 1u32;\npub const SPEAKER_FRONT_LEFT_OF_CENTER: u32 = 64u32;\npub const SPEAKER_FRONT_RIGHT: u32 = 2u32;\npub const SPEAKER_FRONT_RIGHT_OF_CENTER: u32 = 128u32;\npub const SPEAKER_LOW_FREQUENCY: u32 = 8u32;\npub const SPEAKER_RESERVED: u32 = 2147221504u32;\npub const SPEAKER_SIDE_LEFT: u32 = 512u32;\npub const SPEAKER_SIDE_RIGHT: u32 = 1024u32;\npub const SPEAKER_TOP_BACK_CENTER: u32 = 65536u32;\npub const SPEAKER_TOP_BACK_LEFT: u32 = 32768u32;\npub const SPEAKER_TOP_BACK_RIGHT: u32 = 131072u32;\npub const SPEAKER_TOP_CENTER: u32 = 2048u32;\npub const SPEAKER_TOP_FRONT_CENTER: u32 = 8192u32;\npub const SPEAKER_TOP_FRONT_LEFT: u32 = 4096u32;\npub const SPEAKER_TOP_FRONT_RIGHT: u32 = 16384u32;\npub const SYSAUDIO_FLAGS_CLEAR_PREFERRED: u32 = 2u32;\npub const SYSAUDIO_FLAGS_DONT_COMBINE_PINS: u32 = 1u32;\npub type TELEPHONY_CALLCONTROLOP = i32;\npub const TELEPHONY_CALLCONTROLOP_DISABLE: TELEPHONY_CALLCONTROLOP = 0i32;\npub const TELEPHONY_CALLCONTROLOP_ENABLE: TELEPHONY_CALLCONTROLOP = 1i32;\npub type TELEPHONY_CALLSTATE = i32;\npub const TELEPHONY_CALLSTATE_DISABLED: TELEPHONY_CALLSTATE = 0i32;\npub const TELEPHONY_CALLSTATE_ENABLED: TELEPHONY_CALLSTATE = 1i32;\npub const TELEPHONY_CALLSTATE_HOLD: TELEPHONY_CALLSTATE = 2i32;\npub const TELEPHONY_CALLSTATE_PROVIDERTRANSITION: TELEPHONY_CALLSTATE = 3i32;\npub type TELEPHONY_CALLTYPE = i32;\npub const TELEPHONY_CALLTYPE_CIRCUITSWITCHED: TELEPHONY_CALLTYPE = 0i32;\npub const TELEPHONY_CALLTYPE_PACKETSWITCHED_LTE: TELEPHONY_CALLTYPE = 1i32;\npub const TELEPHONY_CALLTYPE_PACKETSWITCHED_WLAN: TELEPHONY_CALLTYPE = 2i32;\npub type TELEPHONY_PROVIDERCHANGEOP = i32;\npub const TELEPHONY_PROVIDERCHANGEOP_BEGIN: TELEPHONY_PROVIDERCHANGEOP = 1i32;\npub const TELEPHONY_PROVIDERCHANGEOP_CANCEL: TELEPHONY_PROVIDERCHANGEOP = 2i32;\npub const TELEPHONY_PROVIDERCHANGEOP_END: TELEPHONY_PROVIDERCHANGEOP = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TRANSPORTAUDIOPARMS {\n    pub EnableOutput: i32,\n    pub EnableRecord: i32,\n    pub EnableSelsync: i32,\n    pub Input: i32,\n    pub MonitorSource: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TRANSPORTBASICPARMS {\n    pub TimeFormat: i32,\n    pub TimeReference: i32,\n    pub Superimpose: i32,\n    pub EndStopAction: i32,\n    pub RecordFormat: i32,\n    pub StepFrames: i32,\n    pub SetpField: i32,\n    pub Preroll: i32,\n    pub RecPreroll: i32,\n    pub Postroll: i32,\n    pub EditDelay: i32,\n    pub PlayTCDelay: i32,\n    pub RecTCDelay: i32,\n    pub EditField: i32,\n    pub FrameServo: i32,\n    pub ColorFrameServo: i32,\n    pub ServoRef: i32,\n    pub WarnGenlock: i32,\n    pub SetTracking: i32,\n    pub VolumeName: [i8; 40],\n    pub Ballistic: [i32; 20],\n    pub Speed: i32,\n    pub CounterFormat: i32,\n    pub TunerChannel: i32,\n    pub TunerNumber: i32,\n    pub TimerEvent: i32,\n    pub TimerStartDay: i32,\n    pub TimerStartTime: i32,\n    pub TimerStopDay: i32,\n    pub TimerStopTime: i32,\n}\nimpl Default for TRANSPORTBASICPARMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TRANSPORTSTATUS {\n    pub Mode: i32,\n    pub LastError: i32,\n    pub RecordInhibit: i32,\n    pub ServoLock: i32,\n    pub MediaPresent: i32,\n    pub MediaLength: i32,\n    pub MediaSize: i32,\n    pub MediaTrackCount: i32,\n    pub MediaTrackLength: i32,\n    pub MediaTrackSide: i32,\n    pub MediaType: i32,\n    pub LinkMode: i32,\n    pub NotifyOn: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TRANSPORTVIDEOPARMS {\n    pub OutputMode: i32,\n    pub Input: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TRANSPORT_STATE {\n    pub Mode: u32,\n    pub State: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TUNER_ANALOG_CAPS_S {\n    pub Mode: u32,\n    pub StandardsSupported: u32,\n    pub MinFrequency: u32,\n    pub MaxFrequency: u32,\n    pub TuningGranularity: u32,\n    pub SettlingTime: u32,\n    pub ScanSensingRange: u32,\n    pub FineTuneSensingRange: u32,\n}\npub type TunerLockType = i32;\npub const Tuner_LockType_Locked: TunerLockType = 2i32;\npub const Tuner_LockType_None: TunerLockType = 0i32;\npub const Tuner_LockType_Within_Scan_Sensing_Range: TunerLockType = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct VBICAP_PROPERTIES_PROTECTION_S {\n    pub Property: KSIDENTIFIER,\n    pub StreamIndex: u32,\n    pub Status: u32,\n}\nimpl Default for VBICAP_PROPERTIES_PROTECTION_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VBICODECFILTERING_CC_SUBSTREAMS {\n    pub SubstreamMask: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct VBICODECFILTERING_NABTS_SUBSTREAMS {\n    pub SubstreamMask: [u32; 128],\n}\nimpl Default for VBICODECFILTERING_NABTS_SUBSTREAMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct VBICODECFILTERING_SCANLINES {\n    pub DwordBitArray: [u32; 32],\n}\nimpl Default for VBICODECFILTERING_SCANLINES {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VBICODECFILTERING_STATISTICS_CC {\n    pub Common: VBICODECFILTERING_STATISTICS_COMMON,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VBICODECFILTERING_STATISTICS_CC_PIN {\n    pub Common: VBICODECFILTERING_STATISTICS_COMMON_PIN,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VBICODECFILTERING_STATISTICS_COMMON {\n    pub InputSRBsProcessed: u32,\n    pub OutputSRBsProcessed: u32,\n    pub SRBsIgnored: u32,\n    pub InputSRBsMissing: u32,\n    pub OutputSRBsMissing: u32,\n    pub OutputFailures: u32,\n    pub InternalErrors: u32,\n    pub ExternalErrors: u32,\n    pub InputDiscontinuities: u32,\n    pub DSPFailures: u32,\n    pub TvTunerChanges: u32,\n    pub VBIHeaderChanges: u32,\n    pub LineConfidenceAvg: u32,\n    pub BytesOutput: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VBICODECFILTERING_STATISTICS_COMMON_PIN {\n    pub SRBsProcessed: u32,\n    pub SRBsIgnored: u32,\n    pub SRBsMissing: u32,\n    pub InternalErrors: u32,\n    pub ExternalErrors: u32,\n    pub Discontinuities: u32,\n    pub LineConfidenceAvg: u32,\n    pub BytesOutput: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VBICODECFILTERING_STATISTICS_NABTS {\n    pub Common: VBICODECFILTERING_STATISTICS_COMMON,\n    pub FECBundleBadLines: u32,\n    pub FECQueueOverflows: u32,\n    pub FECCorrectedLines: u32,\n    pub FECUncorrectableLines: u32,\n    pub BundlesProcessed: u32,\n    pub BundlesSent2IP: u32,\n    pub FilteredLines: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VBICODECFILTERING_STATISTICS_NABTS_PIN {\n    pub Common: VBICODECFILTERING_STATISTICS_COMMON_PIN,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VBICODECFILTERING_STATISTICS_TELETEXT {\n    pub Common: VBICODECFILTERING_STATISTICS_COMMON,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VBICODECFILTERING_STATISTICS_TELETEXT_PIN {\n    pub Common: VBICODECFILTERING_STATISTICS_COMMON_PIN,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct VRAM_SURFACE_INFO {\n    pub hSurface: usize,\n    pub VramPhysicalAddress: i64,\n    pub cbCaptured: u32,\n    pub dwWidth: u32,\n    pub dwHeight: u32,\n    pub dwLinearSize: u32,\n    pub lPitch: i32,\n    pub ullReserved: [u64; 16],\n}\nimpl Default for VRAM_SURFACE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct VRAM_SURFACE_INFO_PROPERTY_S {\n    pub Property: KSIDENTIFIER,\n    pub pVramSurfaceInfo: *mut VRAM_SURFACE_INFO,\n}\nimpl Default for VRAM_SURFACE_INFO_PROPERTY_S {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WAVE_FORMAT_EXTENSIBLE: u32 = 65534u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WNF_KSCAMERA_STREAMSTATE_INFO {\n    pub ProcessId: u32,\n    pub SessionId: u32,\n    pub StreamState: u32,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WST_BUFFER {\n    pub ScanlinesRequested: VBICODECFILTERING_SCANLINES,\n    pub WstLines: [WST_BUFFER_LINE; 17],\n}\nimpl Default for WST_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WST_BUFFER_LINE {\n    pub Confidence: u8,\n    pub Bytes: [u8; 42],\n}\nimpl Default for WST_BUFFER_LINE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WST_BYTES_PER_LINE: u32 = 42u32;\npub const WST_TVTUNER_CHANGE_BEGIN_TUNE: i32 = 4096i32;\npub const WST_TVTUNER_CHANGE_END_TUNE: i32 = 8192i32;\npub const eConnType3Point5mm: EPcxConnectionType = 1i32;\npub const eConnTypeAtapiInternal: EPcxConnectionType = 3i32;\npub const eConnTypeCombination: EPcxConnectionType = 11i32;\npub const eConnTypeMultichannelAnalogDIN: EPcxConnectionType = 8i32;\npub const eConnTypeOptical: EPcxConnectionType = 5i32;\npub const eConnTypeOtherAnalog: EPcxConnectionType = 7i32;\npub const eConnTypeOtherDigital: EPcxConnectionType = 6i32;\npub const eConnTypeQuarter: EPcxConnectionType = 2i32;\npub const eConnTypeRCA: EPcxConnectionType = 4i32;\npub const eConnTypeRJ11Modem: EPcxConnectionType = 10i32;\npub const eConnTypeUnknown: EPcxConnectionType = 0i32;\npub const eConnTypeXlrProfessional: EPcxConnectionType = 9i32;\npub const eDeviceControlUseMissing: EDeviceControlUseType = 0i32;\npub const eDeviceControlUsePrimary: EDeviceControlUseType = 1i32;\npub const eDeviceControlUseSecondary: EDeviceControlUseType = 2i32;\npub const eGenLocInternal: EPcxGenLocation = 1i32;\npub const eGenLocOther: EPcxGenLocation = 3i32;\npub const eGenLocPrimaryBox: EPcxGenLocation = 0i32;\npub const eGenLocSeparate: EPcxGenLocation = 2i32;\npub const eGeoLocATAPI: EPcxGeoLocation = 13i32;\npub const eGeoLocBottom: EPcxGeoLocation = 6i32;\npub const eGeoLocDrivebay: EPcxGeoLocation = 10i32;\npub const eGeoLocFront: EPcxGeoLocation = 2i32;\npub const eGeoLocHDMI: EPcxGeoLocation = 11i32;\npub const eGeoLocInsideMobileLid: EPcxGeoLocation = 9i32;\npub const eGeoLocLeft: EPcxGeoLocation = 3i32;\npub const eGeoLocNotApplicable: EPcxGeoLocation = 14i32;\npub const eGeoLocOutsideMobileLid: EPcxGeoLocation = 12i32;\npub const eGeoLocRear: EPcxGeoLocation = 1i32;\npub const eGeoLocRearPanel: EPcxGeoLocation = 7i32;\npub const eGeoLocReserved6: EPcxGeoLocation = 15i32;\npub const eGeoLocRight: EPcxGeoLocation = 4i32;\npub const eGeoLocRiser: EPcxGeoLocation = 8i32;\npub const eGeoLocTop: EPcxGeoLocation = 5i32;\npub const ePortConnBothIntegratedAndJack: EPxcPortConnection = 2i32;\npub const ePortConnIntegratedDevice: EPxcPortConnection = 1i32;\npub const ePortConnJack: EPxcPortConnection = 0i32;\npub const ePortConnUnknown: EPxcPortConnection = 3i32;\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/Media/Multimedia/mod.rs",
      "sha256": "20b0256edcea5048689d42f43653cde2dda1c660153ef9f28e4bf36ac3a56b43",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "windows_link::link!(\"avifil32.dll\" \"system\" fn AVIBuildFilterA(lpszfilter : windows_sys::core::PSTR, cbfilter : i32, fsaving : windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIBuildFilterW(lpszfilter : windows_sys::core::PWSTR, cbfilter : i32, fsaving : windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIClearClipboard() -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileAddRef(pfile : * mut core::ffi::c_void) -> u32);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileCreateStreamA(pfile : * mut core::ffi::c_void, ppavi : *mut * mut core::ffi::c_void, psi : *const AVISTREAMINFOA) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileCreateStreamW(pfile : * mut core::ffi::c_void, ppavi : *mut * mut core::ffi::c_void, psi : *const AVISTREAMINFOW) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileEndRecord(pfile : * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileExit());\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileGetStream(pfile : * mut core::ffi::c_void, ppavi : *mut * mut core::ffi::c_void, fcctype : u32, lparam : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileInfoA(pfile : * mut core::ffi::c_void, pfi : *mut AVIFILEINFOA, lsize : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileInfoW(pfile : * mut core::ffi::c_void, pfi : *mut AVIFILEINFOW, lsize : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileInit());\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileOpenA(ppfile : *mut * mut core::ffi::c_void, szfile : windows_sys::core::PCSTR, umode : u32, lphandler : *const windows_sys::core::GUID) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileOpenW(ppfile : *mut * mut core::ffi::c_void, szfile : windows_sys::core::PCWSTR, umode : u32, lphandler : *const windows_sys::core::GUID) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileReadData(pfile : * mut core::ffi::c_void, ckid : u32, lpdata : *mut core::ffi::c_void, lpcbdata : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileRelease(pfile : * mut core::ffi::c_void) -> u32);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIFileWriteData(pfile : * mut core::ffi::c_void, ckid : u32, lpdata : *const core::ffi::c_void, cbdata : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIGetFromClipboard(lppf : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIMakeCompressedStream(ppscompressed : *mut * mut core::ffi::c_void, ppssource : * mut core::ffi::c_void, lpoptions : *const AVICOMPRESSOPTIONS, pclsidhandler : *const windows_sys::core::GUID) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIMakeFileFromStreams(ppfile : *mut * mut core::ffi::c_void, nstreams : i32, papstreams : *const * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIMakeStreamFromClipboard(cfformat : u32, hglobal : super::super::Foundation:: HANDLE, ppstream : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIPutFileOnClipboard(pf : * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"C\" fn AVISaveA(szfile : windows_sys::core::PCSTR, pclsidhandler : *const windows_sys::core::GUID, lpfncallback : AVISAVECALLBACK, nstreams : i32, pfile : * mut core::ffi::c_void, lpoptions : *const AVICOMPRESSOPTIONS, ...) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVISaveOptions(hwnd : super::super::Foundation:: HWND, uiflags : u32, nstreams : i32, ppavi : *const * mut core::ffi::c_void, plpoptions : *mut *mut AVICOMPRESSOPTIONS) -> isize);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVISaveOptionsFree(nstreams : i32, plpoptions : *const *const AVICOMPRESSOPTIONS) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVISaveVA(szfile : windows_sys::core::PCSTR, pclsidhandler : *const windows_sys::core::GUID, lpfncallback : AVISAVECALLBACK, nstreams : i32, ppavi : *const * mut core::ffi::c_void, plpoptions : *const *const AVICOMPRESSOPTIONS) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVISaveVW(szfile : windows_sys::core::PCWSTR, pclsidhandler : *const windows_sys::core::GUID, lpfncallback : AVISAVECALLBACK, nstreams : i32, ppavi : *const * mut core::ffi::c_void, plpoptions : *const *const AVICOMPRESSOPTIONS) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"C\" fn AVISaveW(szfile : windows_sys::core::PCWSTR, pclsidhandler : *const windows_sys::core::GUID, lpfncallback : AVISAVECALLBACK, nstreams : i32, pfile : * mut core::ffi::c_void, lpoptions : *const AVICOMPRESSOPTIONS, ...) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamAddRef(pavi : * mut core::ffi::c_void) -> u32);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamBeginStreaming(pavi : * mut core::ffi::c_void, lstart : i32, lend : i32, lrate : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamCreate(ppavi : *mut * mut core::ffi::c_void, lparam1 : i32, lparam2 : i32, pclsidhandler : *const windows_sys::core::GUID) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamEndStreaming(pavi : * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamFindSample(pavi : * mut core::ffi::c_void, lpos : i32, lflags : i32) -> i32);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamGetFrame(pg : * mut core::ffi::c_void, lpos : i32) -> *mut core::ffi::c_void);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamGetFrameClose(pg : * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamGetFrameOpen(pavi : * mut core::ffi::c_void, lpbiwanted : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER) -> * mut core::ffi::c_void);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamInfoA(pavi : * mut core::ffi::c_void, psi : *mut AVISTREAMINFOA, lsize : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamInfoW(pavi : * mut core::ffi::c_void, psi : *mut AVISTREAMINFOW, lsize : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamLength(pavi : * mut core::ffi::c_void) -> i32);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamOpenFromFileA(ppavi : *mut * mut core::ffi::c_void, szfile : windows_sys::core::PCSTR, fcctype : u32, lparam : i32, mode : u32, pclsidhandler : *const windows_sys::core::GUID) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamOpenFromFileW(ppavi : *mut * mut core::ffi::c_void, szfile : windows_sys::core::PCWSTR, fcctype : u32, lparam : i32, mode : u32, pclsidhandler : *const windows_sys::core::GUID) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamRead(pavi : * mut core::ffi::c_void, lstart : i32, lsamples : i32, lpbuffer : *mut core::ffi::c_void, cbbuffer : i32, plbytes : *mut i32, plsamples : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamReadData(pavi : * mut core::ffi::c_void, fcc : u32, lp : *mut core::ffi::c_void, lpcb : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamReadFormat(pavi : * mut core::ffi::c_void, lpos : i32, lpformat : *mut core::ffi::c_void, lpcbformat : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamRelease(pavi : * mut core::ffi::c_void) -> u32);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamSampleToTime(pavi : * mut core::ffi::c_void, lsample : i32) -> i32);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamSetFormat(pavi : * mut core::ffi::c_void, lpos : i32, lpformat : *const core::ffi::c_void, cbformat : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamStart(pavi : * mut core::ffi::c_void) -> i32);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamTimeToSample(pavi : * mut core::ffi::c_void, ltime : i32) -> i32);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamWrite(pavi : * mut core::ffi::c_void, lstart : i32, lsamples : i32, lpbuffer : *const core::ffi::c_void, cbbuffer : i32, dwflags : u32, plsampwritten : *mut i32, plbyteswritten : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn AVIStreamWriteData(pavi : * mut core::ffi::c_void, fcc : u32, lp : *const core::ffi::c_void, cb : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"winmm.dll\" \"system\" fn CloseDriver(hdriver : HDRVR, lparam1 : super::super::Foundation:: LPARAM, lparam2 : super::super::Foundation:: LPARAM) -> super::super::Foundation:: LRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn CreateEditableStream(ppseditable : *mut * mut core::ffi::c_void, pssource : * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"winmm.dll\" \"system\" fn DefDriverProc(dwdriveridentifier : usize, hdrvr : HDRVR, umsg : u32, lparam1 : super::super::Foundation:: LPARAM, lparam2 : super::super::Foundation:: LPARAM) -> super::super::Foundation:: LRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibBegin(hdd : isize, hdc : super::super::Graphics::Gdi:: HDC, dxdst : i32, dydst : i32, lpbi : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, dxsrc : i32, dysrc : i32, wflags : u32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibChangePalette(hdd : isize, istart : i32, ilen : i32, lppe : *const super::super::Graphics::Gdi:: PALETTEENTRY) -> windows_sys::core::BOOL);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibClose(hdd : isize) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibDraw(hdd : isize, hdc : super::super::Graphics::Gdi:: HDC, xdst : i32, ydst : i32, dxdst : i32, dydst : i32, lpbi : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, lpbits : *const core::ffi::c_void, xsrc : i32, ysrc : i32, dxsrc : i32, dysrc : i32, wflags : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibEnd(hdd : isize) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibGetBuffer(hdd : isize, lpbi : *mut super::super::Graphics::Gdi:: BITMAPINFOHEADER, dwsize : u32, dwflags : u32) -> *mut core::ffi::c_void);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibGetPalette(hdd : isize) -> super::super::Graphics::Gdi:: HPALETTE);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibOpen() -> isize);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibProfileDisplay(lpbi : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER) -> super::super::Foundation:: LRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibRealize(hdd : isize, hdc : super::super::Graphics::Gdi:: HDC, fbackground : windows_sys::core::BOOL) -> u32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibSetPalette(hdd : isize, hpal : super::super::Graphics::Gdi:: HPALETTE) -> windows_sys::core::BOOL);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibStart(hdd : isize, rate : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibStop(hdd : isize) -> windows_sys::core::BOOL);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn DrawDibTime(hdd : isize, lpddtime : *mut DRAWDIBTIME) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn DriverCallback(dwcallback : usize, dwflags : u32, hdevice : HDRVR, dwmsg : u32, dwuser : usize, dwparam1 : usize, dwparam2 : usize) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn DrvGetModuleHandle(hdriver : HDRVR) -> super::super::Foundation:: HMODULE);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn EditStreamClone(pavi : * mut core::ffi::c_void, ppresult : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn EditStreamCopy(pavi : * mut core::ffi::c_void, plstart : *mut i32, pllength : *mut i32, ppresult : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn EditStreamCut(pavi : * mut core::ffi::c_void, plstart : *mut i32, pllength : *mut i32, ppresult : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn EditStreamPaste(pavi : * mut core::ffi::c_void, plpos : *mut i32, pllength : *mut i32, pstream : * mut core::ffi::c_void, lstart : i32, lend : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn EditStreamSetInfoA(pavi : * mut core::ffi::c_void, lpinfo : *const AVISTREAMINFOA, cbinfo : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn EditStreamSetInfoW(pavi : * mut core::ffi::c_void, lpinfo : *const AVISTREAMINFOW, cbinfo : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn EditStreamSetNameA(pavi : * mut core::ffi::c_void, lpszname : windows_sys::core::PCSTR) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"avifil32.dll\" \"system\" fn EditStreamSetNameW(pavi : * mut core::ffi::c_void, lpszname : windows_sys::core::PCWSTR) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"winmm.dll\" \"system\" fn GetDriverModuleHandle(hdriver : HDRVR) -> super::super::Foundation:: HMODULE);\n#[cfg(feature = \"Win32_UI_Controls_Dialogs\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn GetOpenFileNamePreviewA(lpofn : *mut super::super::UI::Controls::Dialogs:: OPENFILENAMEA) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Controls_Dialogs\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn GetOpenFileNamePreviewW(lpofn : *mut super::super::UI::Controls::Dialogs:: OPENFILENAMEW) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Controls_Dialogs\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn GetSaveFileNamePreviewA(lpofn : *mut super::super::UI::Controls::Dialogs:: OPENFILENAMEA) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Controls_Dialogs\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn GetSaveFileNamePreviewW(lpofn : *mut super::super::UI::Controls::Dialogs:: OPENFILENAMEW) -> windows_sys::core::BOOL);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICClose(hic : HIC) -> super::super::Foundation:: LRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"C\" fn ICCompress(hic : HIC, dwflags : u32, lpbioutput : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, lpdata : *mut core::ffi::c_void, lpbiinput : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, lpbits : *const core::ffi::c_void, lpckid : *mut u32, lpdwflags : *mut u32, lframenum : i32, dwframesize : u32, dwquality : u32, lpbiprev : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, lpprev : *const core::ffi::c_void) -> u32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICCompressorChoose(hwnd : super::super::Foundation:: HWND, uiflags : u32, pvin : *const core::ffi::c_void, lpdata : *const core::ffi::c_void, pc : *mut COMPVARS, lpsztitle : windows_sys::core::PCSTR) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICCompressorFree(pc : *const COMPVARS));\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"C\" fn ICDecompress(hic : HIC, dwflags : u32, lpbiformat : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, lpdata : *const core::ffi::c_void, lpbi : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, lpbits : *mut core::ffi::c_void) -> u32);\nwindows_link::link!(\"msvfw32.dll\" \"C\" fn ICDraw(hic : HIC, dwflags : u32, lpformat : *const core::ffi::c_void, lpdata : *const core::ffi::c_void, cbdata : u32, ltime : i32) -> u32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"C\" fn ICDrawBegin(hic : HIC, dwflags : u32, hpal : super::super::Graphics::Gdi:: HPALETTE, hwnd : super::super::Foundation:: HWND, hdc : super::super::Graphics::Gdi:: HDC, xdst : i32, ydst : i32, dxdst : i32, dydst : i32, lpbi : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, xsrc : i32, ysrc : i32, dxsrc : i32, dysrc : i32, dwrate : u32, dwscale : u32) -> u32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICGetDisplayFormat(hic : HIC, lpbiin : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, lpbiout : *mut super::super::Graphics::Gdi:: BITMAPINFOHEADER, bitdepth : i32, dx : i32, dy : i32) -> HIC);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICGetInfo(hic : HIC, picinfo : *mut ICINFO, cb : u32) -> super::super::Foundation:: LRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICImageCompress(hic : HIC, uiflags : u32, lpbiin : *const super::super::Graphics::Gdi:: BITMAPINFO, lpbits : *const core::ffi::c_void, lpbiout : *const super::super::Graphics::Gdi:: BITMAPINFO, lquality : i32, plsize : *mut i32) -> super::super::Foundation:: HANDLE);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICImageDecompress(hic : HIC, uiflags : u32, lpbiin : *const super::super::Graphics::Gdi:: BITMAPINFO, lpbits : *const core::ffi::c_void, lpbiout : *const super::super::Graphics::Gdi:: BITMAPINFO) -> super::super::Foundation:: HANDLE);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICInfo(fcctype : u32, fcchandler : u32, lpicinfo : *mut ICINFO) -> windows_sys::core::BOOL);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICInstall(fcctype : u32, fcchandler : u32, lparam : super::super::Foundation:: LPARAM, szdesc : windows_sys::core::PCSTR, wflags : u32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICLocate(fcctype : u32, fcchandler : u32, lpbiin : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, lpbiout : *const super::super::Graphics::Gdi:: BITMAPINFOHEADER, wflags : u16) -> HIC);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICOpen(fcctype : u32, fcchandler : u32, wmode : u32) -> HIC);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICOpenFunction(fcctype : u32, fcchandler : u32, wmode : u32, lpfnhandler : super::super::Foundation:: FARPROC) -> HIC);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICRemove(fcctype : u32, fcchandler : u32, wflags : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICSendMessage(hic : HIC, msg : u32, dw1 : usize, dw2 : usize) -> super::super::Foundation:: LRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICSeqCompressFrame(pc : *const COMPVARS, uiflags : u32, lpbits : *const core::ffi::c_void, pfkey : *mut windows_sys::core::BOOL, plsize : *mut i32) -> *mut core::ffi::c_void);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICSeqCompressFrameEnd(pc : *const COMPVARS));\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn ICSeqCompressFrameStart(pc : *const COMPVARS, lpbiin : *const super::super::Graphics::Gdi:: BITMAPINFO) -> windows_sys::core::BOOL);\nwindows_link::link!(\"msvfw32.dll\" \"C\" fn MCIWndCreateA(hwndparent : super::super::Foundation:: HWND, hinstance : super::super::Foundation:: HINSTANCE, dwstyle : u32, szfile : windows_sys::core::PCSTR) -> super::super::Foundation:: HWND);\nwindows_link::link!(\"msvfw32.dll\" \"C\" fn MCIWndCreateW(hwndparent : super::super::Foundation:: HWND, hinstance : super::super::Foundation:: HINSTANCE, dwstyle : u32, szfile : windows_sys::core::PCWSTR) -> super::super::Foundation:: HWND);\nwindows_link::link!(\"msvfw32.dll\" \"C\" fn MCIWndRegisterClass() -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn OpenDriver(szdrivername : windows_sys::core::PCWSTR, szsectionname : windows_sys::core::PCWSTR, lparam2 : super::super::Foundation:: LPARAM) -> HDRVR);\nwindows_link::link!(\"winmm.dll\" \"system\" fn SendDriverMessage(hdriver : HDRVR, message : u32, lparam1 : super::super::Foundation:: LPARAM, lparam2 : super::super::Foundation:: LPARAM) -> super::super::Foundation:: LRESULT);\nwindows_link::link!(\"msvfw32.dll\" \"system\" fn VideoForWindowsVersion() -> u32);\nwindows_link::link!(\"avicap32.dll\" \"system\" fn capCreateCaptureWindowA(lpszwindowname : windows_sys::core::PCSTR, dwstyle : u32, x : i32, y : i32, nwidth : i32, nheight : i32, hwndparent : super::super::Foundation:: HWND, nid : i32) -> super::super::Foundation:: HWND);\nwindows_link::link!(\"avicap32.dll\" \"system\" fn capCreateCaptureWindowW(lpszwindowname : windows_sys::core::PCWSTR, dwstyle : u32, x : i32, y : i32, nwidth : i32, nheight : i32, hwndparent : super::super::Foundation:: HWND, nid : i32) -> super::super::Foundation:: HWND);\nwindows_link::link!(\"avicap32.dll\" \"system\" fn capGetDriverDescriptionA(wdriverindex : u32, lpszname : windows_sys::core::PSTR, cbname : i32, lpszver : windows_sys::core::PSTR, cbver : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"avicap32.dll\" \"system\" fn capGetDriverDescriptionW(wdriverindex : u32, lpszname : windows_sys::core::PWSTR, cbname : i32, lpszver : windows_sys::core::PWSTR, cbver : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn joyGetDevCapsA(ujoyid : usize, pjc : *mut JOYCAPSA, cbjc : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn joyGetDevCapsW(ujoyid : usize, pjc : *mut JOYCAPSW, cbjc : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn joyGetNumDevs() -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn joyGetPos(ujoyid : u32, pji : *mut JOYINFO) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn joyGetPosEx(ujoyid : u32, pji : *mut JOYINFOEX) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn joyGetThreshold(ujoyid : u32, puthreshold : *mut u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn joyReleaseCapture(ujoyid : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn joySetCapture(hwnd : super::super::Foundation:: HWND, ujoyid : u32, uperiod : u32, fchanged : windows_sys::core::BOOL) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn joySetThreshold(ujoyid : u32, uthreshold : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciDriverNotify(hwndcallback : super::super::Foundation:: HANDLE, wdeviceid : u32, ustatus : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciDriverYield(wdeviceid : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciFreeCommandResource(wtable : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciGetCreatorTask(mciid : u32) -> super:: HTASK);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciGetDeviceIDA(pszdevice : windows_sys::core::PCSTR) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciGetDeviceIDFromElementIDA(dwelementid : u32, lpstrtype : windows_sys::core::PCSTR) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciGetDeviceIDFromElementIDW(dwelementid : u32, lpstrtype : windows_sys::core::PCWSTR) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciGetDeviceIDW(pszdevice : windows_sys::core::PCWSTR) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciGetDriverData(wdeviceid : u32) -> usize);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciGetErrorStringA(mcierr : u32, psztext : windows_sys::core::PSTR, cchtext : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciGetErrorStringW(mcierr : u32, psztext : windows_sys::core::PWSTR, cchtext : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciGetYieldProc(mciid : u32, pdwyielddata : *const u32) -> YIELDPROC);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciLoadCommandResource(hinstance : super::super::Foundation:: HANDLE, lpresname : windows_sys::core::PCWSTR, wtype : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciSendCommandA(mciid : u32, umsg : u32, dwparam1 : usize, dwparam2 : usize) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciSendCommandW(mciid : u32, umsg : u32, dwparam1 : usize, dwparam2 : usize) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciSendStringA(lpstrcommand : windows_sys::core::PCSTR, lpstrreturnstring : windows_sys::core::PSTR, ureturnlength : u32, hwndcallback : super::super::Foundation:: HWND) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciSendStringW(lpstrcommand : windows_sys::core::PCWSTR, lpstrreturnstring : windows_sys::core::PWSTR, ureturnlength : u32, hwndcallback : super::super::Foundation:: HWND) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciSetDriverData(wdeviceid : u32, dwdata : usize) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mciSetYieldProc(mciid : u32, fpyieldproc : YIELDPROC, dwyielddata : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmDrvInstall(hdriver : HDRVR, wszdrventry : windows_sys::core::PCWSTR, drvmessage : DRIVERMSGPROC, wflags : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmGetCurrentTask() -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmTaskBlock(h : u32));\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmTaskCreate(lpfn : LPTASKCALLBACK, lph : *mut super::super::Foundation:: HANDLE, dwinst : usize) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmTaskSignal(h : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmTaskYield());\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioAdvance(hmmio : HMMIO, pmmioinfo : *const MMIOINFO, fuadvance : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioAscend(hmmio : HMMIO, pmmcki : *const MMCKINFO, fuascend : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioClose(hmmio : HMMIO, fuclose : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioCreateChunk(hmmio : HMMIO, pmmcki : *const MMCKINFO, fucreate : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioDescend(hmmio : HMMIO, pmmcki : *mut MMCKINFO, pmmckiparent : *const MMCKINFO, fudescend : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioFlush(hmmio : HMMIO, fuflush : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioGetInfo(hmmio : HMMIO, pmmioinfo : *mut MMIOINFO, fuinfo : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioInstallIOProcA(fccioproc : u32, pioproc : LPMMIOPROC, dwflags : u32) -> LPMMIOPROC);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioInstallIOProcW(fccioproc : u32, pioproc : LPMMIOPROC, dwflags : u32) -> LPMMIOPROC);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioOpenA(pszfilename : windows_sys::core::PSTR, pmmioinfo : *mut MMIOINFO, fdwopen : u32) -> HMMIO);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioOpenW(pszfilename : windows_sys::core::PWSTR, pmmioinfo : *mut MMIOINFO, fdwopen : u32) -> HMMIO);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioRead(hmmio : HMMIO, pch : *mut i8, cch : i32) -> i32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioRenameA(pszfilename : windows_sys::core::PCSTR, psznewfilename : windows_sys::core::PCSTR, pmmioinfo : *const MMIOINFO, fdwrename : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioRenameW(pszfilename : windows_sys::core::PCWSTR, psznewfilename : windows_sys::core::PCWSTR, pmmioinfo : *const MMIOINFO, fdwrename : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioSeek(hmmio : HMMIO, loffset : i32, iorigin : i32) -> i32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioSendMessage(hmmio : HMMIO, umsg : u32, lparam1 : super::super::Foundation:: LPARAM, lparam2 : super::super::Foundation:: LPARAM) -> super::super::Foundation:: LRESULT);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioSetBuffer(hmmio : HMMIO, pchbuffer : windows_sys::core::PSTR, cchbuffer : i32, fubuffer : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioSetInfo(hmmio : HMMIO, pmmioinfo : *const MMIOINFO, fuinfo : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioStringToFOURCCA(sz : windows_sys::core::PCSTR, uflags : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioStringToFOURCCW(sz : windows_sys::core::PCWSTR, uflags : u32) -> u32);\nwindows_link::link!(\"winmm.dll\" \"system\" fn mmioWrite(hmmio : HMMIO, pch : windows_sys::core::PCSTR, cch : i32) -> i32);\nwindows_link::link!(\"api-ms-win-mm-misc-l1-1-1.dll\" \"system\" fn sndOpenSound(eventname : windows_sys::core::PCWSTR, appname : windows_sys::core::PCWSTR, flags : i32, filehandle : *mut super::super::Foundation:: HANDLE) -> i32);\npub const ACMDM_BASE: u32 = 24576u32;\npub const ACM_MPEG_COPYRIGHT: u32 = 2u32;\npub const ACM_MPEG_DUALCHANNEL: u32 = 4u32;\npub const ACM_MPEG_ID_MPEG1: u32 = 16u32;\npub const ACM_MPEG_JOINTSTEREO: u32 = 2u32;\npub const ACM_MPEG_LAYER1: u32 = 1u32;\npub const ACM_MPEG_LAYER2: u32 = 2u32;\npub const ACM_MPEG_LAYER3: u32 = 4u32;\npub const ACM_MPEG_ORIGINALHOME: u32 = 4u32;\npub const ACM_MPEG_PRIVATEBIT: u32 = 1u32;\npub const ACM_MPEG_PROTECTIONBIT: u32 = 8u32;\npub const ACM_MPEG_SINGLECHANNEL: u32 = 8u32;\npub const ACM_MPEG_STEREO: u32 = 1u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct ADPCMCOEFSET {\n    pub iCoef1: i16,\n    pub iCoef2: i16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct ADPCMEWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy)]\npub struct ADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n    pub wNumCoef: u16,\n    pub aCoef: [ADPCMCOEFSET; 1],\n}\n#[cfg(feature = \"Win32_Media_Audio\")]\nimpl Default for ADPCMWAVEFORMAT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct APTXWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct AUDIOFILE_AF10WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct AUDIOFILE_AF36WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\npub const AUXDM_GETDEVCAPS: u32 = 4u32;\npub const AUXDM_GETNUMDEVS: u32 = 3u32;\npub const AUXDM_GETVOLUME: u32 = 5u32;\npub const AUXDM_SETVOLUME: u32 = 6u32;\npub const AUXM_INIT: u32 = 100u32;\npub const AUXM_INIT_EX: u32 = 104u32;\npub const AVICOMPRESSF_DATARATE: u32 = 2u32;\npub const AVICOMPRESSF_INTERLEAVE: u32 = 1u32;\npub const AVICOMPRESSF_KEYFRAMES: u32 = 4u32;\npub const AVICOMPRESSF_VALID: u32 = 8u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AVICOMPRESSOPTIONS {\n    pub fccType: u32,\n    pub fccHandler: u32,\n    pub dwKeyFrameEvery: u32,\n    pub dwQuality: u32,\n    pub dwBytesPerSecond: u32,\n    pub dwFlags: u32,\n    pub lpFormat: *mut core::ffi::c_void,\n    pub cbFormat: u32,\n    pub lpParms: *mut core::ffi::c_void,\n    pub cbParms: u32,\n    pub dwInterleaveEvery: u32,\n}\nimpl Default for AVICOMPRESSOPTIONS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const AVIERR_OK: i32 = 0i32;\npub const AVIFILECAPS_ALLKEYFRAMES: u32 = 16u32;\npub const AVIFILECAPS_CANREAD: u32 = 1u32;\npub const AVIFILECAPS_CANWRITE: u32 = 2u32;\npub const AVIFILECAPS_NOCOMPRESSION: u32 = 32u32;\npub const AVIFILEHANDLER_CANACCEPTNONRGB: u32 = 4u32;\npub const AVIFILEHANDLER_CANREAD: u32 = 1u32;\npub const AVIFILEHANDLER_CANWRITE: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AVIFILEINFOA {\n    pub dwMaxBytesPerSec: u32,\n    pub dwFlags: u32,\n    pub dwCaps: u32,\n    pub dwStreams: u32,\n    pub dwSuggestedBufferSize: u32,\n    pub dwWidth: u32,\n    pub dwHeight: u32,\n    pub dwScale: u32,\n    pub dwRate: u32,\n    pub dwLength: u32,\n    pub dwEditCount: u32,\n    pub szFileType: [i8; 64],\n}\nimpl Default for AVIFILEINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AVIFILEINFOW {\n    pub dwMaxBytesPerSec: u32,\n    pub dwFlags: u32,\n    pub dwCaps: u32,\n    pub dwStreams: u32,\n    pub dwSuggestedBufferSize: u32,\n    pub dwWidth: u32,\n    pub dwHeight: u32,\n    pub dwScale: u32,\n    pub dwRate: u32,\n    pub dwLength: u32,\n    pub dwEditCount: u32,\n    pub szFileType: [u16; 64],\n}\nimpl Default for AVIFILEINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const AVIFILEINFO_COPYRIGHTED: u32 = 131072u32;\npub const AVIFILEINFO_HASINDEX: u32 = 16u32;\npub const AVIFILEINFO_ISINTERLEAVED: u32 = 256u32;\npub const AVIFILEINFO_MUSTUSEINDEX: u32 = 32u32;\npub const AVIFILEINFO_WASCAPTUREFILE: u32 = 65536u32;\npub const AVIGETFRAMEF_BESTDISPLAYFMT: u32 = 1u32;\npub const AVIIF_CONTROLFRAME: i32 = 512i32;\npub const AVIIF_TWOCC: i32 = 2i32;\npub type AVISAVECALLBACK = Option<unsafe extern \"system\" fn(param0: i32) -> windows_sys::core::BOOL>;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AVISTREAMINFOA {\n    pub fccType: u32,\n    pub fccHandler: u32,\n    pub dwFlags: u32,\n    pub dwCaps: u32,\n    pub wPriority: u16,\n    pub wLanguage: u16,\n    pub dwScale: u32,\n    pub dwRate: u32,\n    pub dwStart: u32,\n    pub dwLength: u32,\n    pub dwInitialFrames: u32,\n    pub dwSuggestedBufferSize: u32,\n    pub dwQuality: u32,\n    pub dwSampleSize: u32,\n    pub rcFrame: super::super::Foundation::RECT,\n    pub dwEditCount: u32,\n    pub dwFormatChangeCount: u32,\n    pub szName: [i8; 64],\n}\nimpl Default for AVISTREAMINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AVISTREAMINFOW {\n    pub fccType: u32,\n    pub fccHandler: u32,\n    pub dwFlags: u32,\n    pub dwCaps: u32,\n    pub wPriority: u16,\n    pub wLanguage: u16,\n    pub dwScale: u32,\n    pub dwRate: u32,\n    pub dwStart: u32,\n    pub dwLength: u32,\n    pub dwInitialFrames: u32,\n    pub dwSuggestedBufferSize: u32,\n    pub dwQuality: u32,\n    pub dwSampleSize: u32,\n    pub rcFrame: super::super::Foundation::RECT,\n    pub dwEditCount: u32,\n    pub dwFormatChangeCount: u32,\n    pub szName: [u16; 64],\n}\nimpl Default for AVISTREAMINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const AVISTREAMINFO_DISABLED: u32 = 1u32;\npub const AVISTREAMINFO_FORMATCHANGES: u32 = 65536u32;\npub const AVISTREAMREAD_CONVENIENT: i32 = -1i32;\npub const AVSTREAMMASTER_AUDIO: u32 = 0u32;\npub const AVSTREAMMASTER_NONE: u32 = 1u32;\npub const BI_1632: u32 = 842217009u32;\npub type CAPCONTROLCALLBACK = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, nstate: i32) -> super::super::Foundation::LRESULT>;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAPDRIVERCAPS {\n    pub wDeviceIndex: u32,\n    pub fHasOverlay: windows_sys::core::BOOL,\n    pub fHasDlgVideoSource: windows_sys::core::BOOL,\n    pub fHasDlgVideoFormat: windows_sys::core::BOOL,\n    pub fHasDlgVideoDisplay: windows_sys::core::BOOL,\n    pub fCaptureInitialized: windows_sys::core::BOOL,\n    pub fDriverSuppliesPalettes: windows_sys::core::BOOL,\n    pub hVideoIn: super::super::Foundation::HANDLE,\n    pub hVideoOut: super::super::Foundation::HANDLE,\n    pub hVideoExtIn: super::super::Foundation::HANDLE,\n    pub hVideoExtOut: super::super::Foundation::HANDLE,\n}\nimpl Default for CAPDRIVERCAPS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type CAPERRORCALLBACKA = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, nid: i32, lpsz: windows_sys::core::PCSTR) -> super::super::Foundation::LRESULT>;\npub type CAPERRORCALLBACKW = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, nid: i32, lpsz: windows_sys::core::PCWSTR) -> super::super::Foundation::LRESULT>;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAPINFOCHUNK {\n    pub fccInfoID: u32,\n    pub lpData: *mut core::ffi::c_void,\n    pub cbData: i32,\n}\nimpl Default for CAPINFOCHUNK {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct CAPSTATUS {\n    pub uiImageWidth: u32,\n    pub uiImageHeight: u32,\n    pub fLiveWindow: windows_sys::core::BOOL,\n    pub fOverlayWindow: windows_sys::core::BOOL,\n    pub fScale: windows_sys::core::BOOL,\n    pub ptScroll: super::super::Foundation::POINT,\n    pub fUsingDefaultPalette: windows_sys::core::BOOL,\n    pub fAudioHardware: windows_sys::core::BOOL,\n    pub fCapFileExists: windows_sys::core::BOOL,\n    pub dwCurrentVideoFrame: u32,\n    pub dwCurrentVideoFramesDropped: u32,\n    pub dwCurrentWaveSamples: u32,\n    pub dwCurrentTimeElapsedMS: u32,\n    pub hPalCurrent: super::super::Graphics::Gdi::HPALETTE,\n    pub fCapturingNow: windows_sys::core::BOOL,\n    pub dwReturn: u32,\n    pub wNumVideoAllocated: u32,\n    pub wNumAudioAllocated: u32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for CAPSTATUS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type CAPSTATUSCALLBACKA = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, nid: i32, lpsz: windows_sys::core::PCSTR) -> super::super::Foundation::LRESULT>;\npub type CAPSTATUSCALLBACKW = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, nid: i32, lpsz: windows_sys::core::PCWSTR) -> super::super::Foundation::LRESULT>;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CAPTUREPARMS {\n    pub dwRequestMicroSecPerFrame: u32,\n    pub fMakeUserHitOKToCapture: windows_sys::core::BOOL,\n    pub wPercentDropForError: u32,\n    pub fYield: windows_sys::core::BOOL,\n    pub dwIndexSize: u32,\n    pub wChunkGranularity: u32,\n    pub fUsingDOSMemory: windows_sys::core::BOOL,\n    pub wNumVideoRequested: u32,\n    pub fCaptureAudio: windows_sys::core::BOOL,\n    pub wNumAudioRequested: u32,\n    pub vKeyAbort: u32,\n    pub fAbortLeftMouse: windows_sys::core::BOOL,\n    pub fAbortRightMouse: windows_sys::core::BOOL,\n    pub fLimitEnabled: windows_sys::core::BOOL,\n    pub wTimeLimit: u32,\n    pub fMCIControl: windows_sys::core::BOOL,\n    pub fStepMCIDevice: windows_sys::core::BOOL,\n    pub dwMCIStartTime: u32,\n    pub dwMCIStopTime: u32,\n    pub fStepCaptureAt2x: windows_sys::core::BOOL,\n    pub wStepCaptureAverageFrames: u32,\n    pub dwAudioBufferSize: u32,\n    pub fDisableWriteCache: windows_sys::core::BOOL,\n    pub AVStreamMaster: u32,\n}\npub type CAPVIDEOCALLBACK = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, lpvhdr: *const VIDEOHDR) -> super::super::Foundation::LRESULT>;\n#[cfg(feature = \"Win32_Media_Audio\")]\npub type CAPWAVECALLBACK = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, lpwhdr: *const super::Audio::WAVEHDR) -> super::super::Foundation::LRESULT>;\npub type CAPYIELDCALLBACK = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND) -> super::super::Foundation::LRESULT>;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CHANNEL_CAPS {\n    pub dwFlags: u32,\n    pub dwSrcRectXMod: u32,\n    pub dwSrcRectYMod: u32,\n    pub dwSrcRectWidthMod: u32,\n    pub dwSrcRectHeightMod: u32,\n    pub dwDstRectXMod: u32,\n    pub dwDstRectYMod: u32,\n    pub dwDstRectWidthMod: u32,\n    pub dwDstRectHeightMod: u32,\n}\npub const CLSID_AVIFile: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00020000_0000_0000_c000_000000000046);\npub const CLSID_AVISimpleUnMarshal: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00020009_0000_0000_c000_000000000046);\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct COMPVARS {\n    pub cbSize: i32,\n    pub dwFlags: u32,\n    pub hic: HIC,\n    pub fccType: u32,\n    pub fccHandler: u32,\n    pub lpbiIn: *mut super::super::Graphics::Gdi::BITMAPINFO,\n    pub lpbiOut: *mut super::super::Graphics::Gdi::BITMAPINFO,\n    pub lpBitsOut: *mut core::ffi::c_void,\n    pub lpBitsPrev: *mut core::ffi::c_void,\n    pub lFrame: i32,\n    pub lKey: i32,\n    pub lDataRate: i32,\n    pub lQ: i32,\n    pub lKeyCount: i32,\n    pub lpState: *mut core::ffi::c_void,\n    pub cbState: i32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for COMPVARS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct CONTRESCR10WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct CONTRESVQLPCWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n}\npub const CONTROLCALLBACK_CAPTURING: u32 = 2u32;\npub const CONTROLCALLBACK_PREROLL: u32 = 1u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct CREATIVEADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wRevision: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct CREATIVEFASTSPEECH10WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wRevision: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct CREATIVEFASTSPEECH8WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wRevision: u16,\n}\npub const CRYSTAL_NET_SFM_CODEC: u32 = 1u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct CSIMAADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\npub const DCB_EVENT: u32 = 5u32;\npub const DCB_FUNCTION: u32 = 3u32;\npub const DCB_NOSWITCH: u32 = 8u32;\npub const DCB_NULL: u32 = 0u32;\npub const DCB_TASK: u32 = 2u32;\npub const DCB_TYPEMASK: u32 = 7u32;\npub const DCB_WINDOW: u32 = 1u32;\npub const DDF_0001: u32 = 1u32;\npub const DDF_2000: u32 = 8192u32;\npub const DDF_ANIMATE: u32 = 32u32;\npub const DDF_BACKGROUNDPAL: u32 = 512u32;\npub const DDF_BUFFER: u32 = 64u32;\npub const DDF_DONTDRAW: u32 = 16u32;\npub const DDF_FULLSCREEN: u32 = 256u32;\npub const DDF_HALFTONE: u32 = 4096u32;\npub const DDF_HURRYUP: u32 = 2048u32;\npub const DDF_JUSTDRAWIT: u32 = 128u32;\npub const DDF_NOTKEYFRAME: u32 = 1024u32;\npub const DDF_PREROLL: u32 = 16u32;\npub const DDF_SAME_DIB: u32 = 8u32;\npub const DDF_SAME_DRAW: u32 = 8u32;\npub const DDF_SAME_HDC: u32 = 4u32;\npub const DDF_SAME_SIZE: u32 = 8u32;\npub const DDF_UPDATE: u32 = 2u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct DIALOGICOKIADPCMWAVEFORMAT {\n    pub ewf: super::Audio::WAVEFORMATEX,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct DIGIADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct DIGIFIXWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct DIGIREALWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct DIGISTDWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\npub const DLG_ACMFILTERCHOOSE_ID: u32 = 71u32;\npub const DLG_ACMFORMATCHOOSE_ID: u32 = 70u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct DOLBYAC2WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub nAuxBitsCode: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DRAWDIBTIME {\n    pub timeCount: i32,\n    pub timeDraw: i32,\n    pub timeDecompress: i32,\n    pub timeDither: i32,\n    pub timeStretch: i32,\n    pub timeBlt: i32,\n    pub timeSetDIBits: i32,\n}\npub type DRIVERMSGPROC = Option<unsafe extern \"system\" fn(param0: u32, param1: u32, param2: usize, param3: usize, param4: usize) -> u32>;\npub type DRIVERPROC = Option<unsafe extern \"system\" fn(param0: usize, param1: HDRVR, param2: u32, param3: super::super::Foundation::LPARAM, param4: super::super::Foundation::LPARAM) -> super::super::Foundation::LRESULT>;\npub const DRIVERS_SECTION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRIVERS32\");\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct DRMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wReserved: u16,\n    pub ulContentId: u32,\n    pub wfxSecure: super::Audio::WAVEFORMATEX,\n}\npub const DRVCNF_CANCEL: u32 = 0u32;\npub const DRVCNF_OK: u32 = 1u32;\npub const DRVCNF_RESTART: u32 = 2u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct DRVCONFIGINFO {\n    pub dwDCISize: u32,\n    pub lpszDCISectionName: windows_sys::core::PCWSTR,\n    pub lpszDCIAliasName: windows_sys::core::PCWSTR,\n}\nimpl Default for DRVCONFIGINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct DRVCONFIGINFOEX {\n    pub dwDCISize: u32,\n    pub lpszDCISectionName: windows_sys::core::PCWSTR,\n    pub lpszDCIAliasName: windows_sys::core::PCWSTR,\n    pub dnDevNode: u32,\n}\nimpl Default for DRVCONFIGINFOEX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DRVM_ADD_THRU: u32 = 257u32;\npub const DRVM_DISABLE: u32 = 102u32;\npub const DRVM_ENABLE: u32 = 103u32;\npub const DRVM_EXIT: u32 = 101u32;\npub const DRVM_INIT: u32 = 100u32;\npub const DRVM_INIT_EX: u32 = 104u32;\npub const DRVM_IOCTL: u32 = 256u32;\npub const DRVM_IOCTL_CMD_SYSTEM: i32 = -2147483648i32;\npub const DRVM_IOCTL_CMD_USER: i32 = 0i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct DRVM_IOCTL_DATA {\n    pub dwSize: u32,\n    pub dwCmd: u32,\n}\npub const DRVM_IOCTL_LAST: u32 = 261u32;\npub const DRVM_MAPPER_CONSOLEVOICECOM_GET: u32 = 8215u32;\npub const DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY: u32 = 1u32;\npub const DRVM_MAPPER_PREFERRED_GET: u32 = 8213u32;\npub const DRVM_MAPPER_RECONFIGURE: u32 = 8193u32;\npub const DRVM_REMOVE_THRU: u32 = 258u32;\npub const DRVM_USER: u32 = 16384u32;\npub const DRV_CANCEL: u32 = 0u32;\npub const DRV_CLOSE: u32 = 4u32;\npub const DRV_CONFIGURE: u32 = 7u32;\npub const DRV_DISABLE: u32 = 5u32;\npub const DRV_ENABLE: u32 = 2u32;\npub const DRV_EXITSESSION: u32 = 11u32;\npub const DRV_FREE: u32 = 6u32;\npub const DRV_INSTALL: u32 = 9u32;\npub const DRV_LOAD: u32 = 1u32;\npub const DRV_MCI_FIRST: u32 = 2048u32;\npub const DRV_MCI_LAST: u32 = 6143u32;\npub const DRV_OK: u32 = 1u32;\npub const DRV_OPEN: u32 = 3u32;\npub const DRV_PNPINSTALL: u32 = 2059u32;\npub const DRV_POWER: u32 = 15u32;\npub const DRV_QUERYCONFIGURE: u32 = 8u32;\npub const DRV_QUERYDEVICEINTERFACE: u32 = 2060u32;\npub const DRV_QUERYDEVICEINTERFACESIZE: u32 = 2061u32;\npub const DRV_QUERYDEVNODE: u32 = 2050u32;\npub const DRV_QUERYFUNCTIONINSTANCEID: u32 = 2065u32;\npub const DRV_QUERYFUNCTIONINSTANCEIDSIZE: u32 = 2066u32;\npub const DRV_QUERYIDFROMSTRINGID: u32 = 2064u32;\npub const DRV_QUERYMAPPABLE: u32 = 2053u32;\npub const DRV_QUERYMODULE: u32 = 2057u32;\npub const DRV_QUERYSTRINGID: u32 = 2062u32;\npub const DRV_QUERYSTRINGIDSIZE: u32 = 2063u32;\npub const DRV_REMOVE: u32 = 10u32;\npub const DRV_RESERVED: u32 = 2048u32;\npub const DRV_RESTART: u32 = 2u32;\npub const DRV_USER: u32 = 16384u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct DVIADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n}\npub const DVM_CONFIGURE_END: u32 = 8191u32;\npub const DVM_CONFIGURE_START: u32 = 4096u32;\npub const DVM_DST_RECT: u32 = 4101u32;\npub const DVM_FORMAT: u32 = 4098u32;\npub const DVM_PALETTE: u32 = 4097u32;\npub const DVM_PALETTERGB555: u32 = 4099u32;\npub const DVM_SRC_RECT: u32 = 4100u32;\npub const DVM_USER: u32 = 16384u32;\npub const DV_ERR_13: u32 = 16u32;\npub const DV_ERR_ALLOCATED: u32 = 19u32;\npub const DV_ERR_BADDEVICEID: u32 = 20u32;\npub const DV_ERR_BADERRNUM: u32 = 22u32;\npub const DV_ERR_BADFORMAT: u32 = 2u32;\npub const DV_ERR_BADINSTALL: u32 = 8u32;\npub const DV_ERR_BASE: u32 = 1u32;\npub const DV_ERR_CONFIG1: u32 = 13u32;\npub const DV_ERR_CONFIG2: u32 = 14u32;\npub const DV_ERR_CREATEPALETTE: u32 = 9u32;\npub const DV_ERR_DMA_CONFLICT: u32 = 26u32;\npub const DV_ERR_FLAGS: u32 = 15u32;\npub const DV_ERR_INT_CONFLICT: u32 = 27u32;\npub const DV_ERR_INVALHANDLE: u32 = 21u32;\npub const DV_ERR_IO_CONFLICT: u32 = 25u32;\npub const DV_ERR_LASTERROR: u32 = 28u32;\npub const DV_ERR_MEM_CONFLICT: u32 = 24u32;\npub const DV_ERR_NOMEM: u32 = 18u32;\npub const DV_ERR_NONSPECIFIC: u32 = 1u32;\npub const DV_ERR_NOTDETECTED: u32 = 7u32;\npub const DV_ERR_NOTSUPPORTED: u32 = 17u32;\npub const DV_ERR_NO_BUFFERS: u32 = 23u32;\npub const DV_ERR_OK: u32 = 0u32;\npub const DV_ERR_PARAM1: u32 = 11u32;\npub const DV_ERR_PARAM2: u32 = 12u32;\npub const DV_ERR_PROTECT_ONLY: u32 = 28u32;\npub const DV_ERR_SIZEFIELD: u32 = 10u32;\npub const DV_ERR_STILLPLAYING: u32 = 3u32;\npub const DV_ERR_SYNC: u32 = 5u32;\npub const DV_ERR_TOOMANYCHANNELS: u32 = 6u32;\npub const DV_ERR_UNPREPARED: u32 = 4u32;\npub const DV_ERR_USER_MSG: u32 = 1001u32;\npub const DV_VM_CLOSE: u32 = 977u32;\npub const DV_VM_DATA: u32 = 978u32;\npub const DV_VM_ERROR: u32 = 979u32;\npub const DV_VM_OPEN: u32 = 976u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct ECHOSC1WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct EXBMINFOHEADER {\n    pub bmi: super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub biExtDataOffset: u32,\n}\npub const FACILITY_NS: u32 = 13u32;\npub const FACILITY_NS_WIN32: u32 = 7u32;\npub const FIND_ANY: i32 = 32i32;\npub const FIND_DIR: i32 = 15i32;\npub const FIND_FORMAT: i32 = 64i32;\npub const FIND_FROM_START: i32 = 8i32;\npub const FIND_INDEX: i32 = 16384i32;\npub const FIND_KEY: i32 = 16i32;\npub const FIND_LENGTH: i32 = 4096i32;\npub const FIND_NEXT: i32 = 1i32;\npub const FIND_OFFSET: i32 = 8192i32;\npub const FIND_POS: i32 = 0i32;\npub const FIND_PREV: i32 = 4i32;\npub const FIND_RET: i32 = 61440i32;\npub const FIND_SIZE: i32 = 12288i32;\npub const FIND_TYPE: i32 = 240i32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct FMTOWNS_SND_WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wRevision: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct G721_ADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub nAuxBlockSize: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct G723_ADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub cbExtraSize: u16,\n    pub nAuxBlockSize: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct GSM610WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n}\npub type HDRVR = *mut core::ffi::c_void;\npub type HIC = *mut core::ffi::c_void;\npub type HMMIO = *mut core::ffi::c_void;\npub type HVIDEO = *mut core::ffi::c_void;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct ICCOMPRESS {\n    pub dwFlags: u32,\n    pub lpbiOutput: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub lpOutput: *mut core::ffi::c_void,\n    pub lpbiInput: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub lpInput: *mut core::ffi::c_void,\n    pub lpckid: *mut u32,\n    pub lpdwFlags: *mut u32,\n    pub lFrameNum: i32,\n    pub dwFrameSize: u32,\n    pub dwQuality: u32,\n    pub lpbiPrev: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub lpPrev: *mut core::ffi::c_void,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for ICCOMPRESS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct ICCOMPRESSFRAMES {\n    pub dwFlags: u32,\n    pub lpbiOutput: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub lOutput: super::super::Foundation::LPARAM,\n    pub lpbiInput: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub lInput: super::super::Foundation::LPARAM,\n    pub lStartFrame: i32,\n    pub lFrameCount: i32,\n    pub lQuality: i32,\n    pub lDataRate: i32,\n    pub lKeyRate: i32,\n    pub dwRate: u32,\n    pub dwScale: u32,\n    pub dwOverheadPerFrame: u32,\n    pub dwReserved2: u32,\n    pub GetData: isize,\n    pub PutData: isize,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for ICCOMPRESSFRAMES {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ICCOMPRESSFRAMES_PADDING: u32 = 1u32;\npub const ICCOMPRESS_KEYFRAME: i32 = 1i32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct ICDECOMPRESS {\n    pub dwFlags: u32,\n    pub lpbiInput: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub lpInput: *mut core::ffi::c_void,\n    pub lpbiOutput: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub lpOutput: *mut core::ffi::c_void,\n    pub ckid: u32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for ICDECOMPRESS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct ICDECOMPRESSEX {\n    pub dwFlags: u32,\n    pub lpbiSrc: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub lpSrc: *mut core::ffi::c_void,\n    pub lpbiDst: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub lpDst: *mut core::ffi::c_void,\n    pub xDst: i32,\n    pub yDst: i32,\n    pub dxDst: i32,\n    pub dyDst: i32,\n    pub xSrc: i32,\n    pub ySrc: i32,\n    pub dxSrc: i32,\n    pub dySrc: i32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for ICDECOMPRESSEX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ICDECOMPRESS_HURRYUP: i32 = -2147483648i32;\npub const ICDECOMPRESS_NOTKEYFRAME: i32 = 134217728i32;\npub const ICDECOMPRESS_NULLFRAME: i32 = 268435456i32;\npub const ICDECOMPRESS_PREROLL: i32 = 536870912i32;\npub const ICDECOMPRESS_UPDATE: i32 = 1073741824i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ICDRAW {\n    pub dwFlags: u32,\n    pub lpFormat: *mut core::ffi::c_void,\n    pub lpData: *mut core::ffi::c_void,\n    pub cbData: u32,\n    pub lTime: i32,\n}\nimpl Default for ICDRAW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct ICDRAWBEGIN {\n    pub dwFlags: u32,\n    pub hpal: super::super::Graphics::Gdi::HPALETTE,\n    pub hwnd: super::super::Foundation::HWND,\n    pub hdc: super::super::Graphics::Gdi::HDC,\n    pub xDst: i32,\n    pub yDst: i32,\n    pub dxDst: i32,\n    pub dyDst: i32,\n    pub lpbi: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub xSrc: i32,\n    pub ySrc: i32,\n    pub dxSrc: i32,\n    pub dySrc: i32,\n    pub dwRate: u32,\n    pub dwScale: u32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for ICDRAWBEGIN {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct ICDRAWSUGGEST {\n    pub lpbiIn: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub lpbiSuggest: *mut super::super::Graphics::Gdi::BITMAPINFOHEADER,\n    pub dxSrc: i32,\n    pub dySrc: i32,\n    pub dxDst: i32,\n    pub dyDst: i32,\n    pub hicDecompressor: HIC,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for ICDRAWSUGGEST {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ICDRAW_ANIMATE: i32 = 8i32;\npub const ICDRAW_BUFFER: i32 = 256i32;\npub const ICDRAW_CONTINUE: i32 = 16i32;\npub const ICDRAW_FULLSCREEN: i32 = 2i32;\npub const ICDRAW_HDC: i32 = 4i32;\npub const ICDRAW_HURRYUP: i32 = -2147483648i32;\npub const ICDRAW_MEMORYDC: i32 = 32i32;\npub const ICDRAW_NOTKEYFRAME: i32 = 134217728i32;\npub const ICDRAW_NULLFRAME: i32 = 268435456i32;\npub const ICDRAW_PREROLL: i32 = 536870912i32;\npub const ICDRAW_QUERY: i32 = 1i32;\npub const ICDRAW_RENDER: i32 = 128i32;\npub const ICDRAW_UPDATE: i32 = 1073741824i32;\npub const ICDRAW_UPDATING: i32 = 64i32;\npub const ICERR_ABORT: i32 = -10i32;\npub const ICERR_BADBITDEPTH: i32 = -200i32;\npub const ICERR_BADFLAGS: i32 = -5i32;\npub const ICERR_BADFORMAT: i32 = -2i32;\npub const ICERR_BADHANDLE: i32 = -8i32;\npub const ICERR_BADIMAGESIZE: i32 = -201i32;\npub const ICERR_BADPARAM: i32 = -6i32;\npub const ICERR_BADSIZE: i32 = -7i32;\npub const ICERR_CANTUPDATE: i32 = -9i32;\npub const ICERR_CUSTOM: i32 = -400i32;\npub const ICERR_DONTDRAW: i32 = 1i32;\npub const ICERR_ERROR: i32 = -100i32;\npub const ICERR_GOTOKEYFRAME: i32 = 3i32;\npub const ICERR_INTERNAL: i32 = -4i32;\npub const ICERR_MEMORY: i32 = -3i32;\npub const ICERR_NEWPALETTE: i32 = 2i32;\npub const ICERR_OK: i32 = 0i32;\npub const ICERR_STOPDRAWING: i32 = 4i32;\npub const ICERR_UNSUPPORTED: i32 = -1i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ICINFO {\n    pub dwSize: u32,\n    pub fccType: u32,\n    pub fccHandler: u32,\n    pub dwFlags: u32,\n    pub dwVersion: u32,\n    pub dwVersionICM: u32,\n    pub szName: [u16; 16],\n    pub szDescription: [u16; 128],\n    pub szDriver: [u16; 128],\n}\nimpl Default for ICINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ICINSTALL_DRIVER: u32 = 2u32;\npub const ICINSTALL_DRIVERW: u32 = 32770u32;\npub const ICINSTALL_FUNCTION: u32 = 1u32;\npub const ICINSTALL_HDRV: u32 = 4u32;\npub const ICINSTALL_UNICODE: u32 = 32768u32;\npub const ICMF_ABOUT_QUERY: u32 = 1u32;\npub const ICMF_CHOOSE_ALLCOMPRESSORS: u32 = 8u32;\npub const ICMF_CHOOSE_DATARATE: u32 = 2u32;\npub const ICMF_CHOOSE_KEYFRAME: u32 = 1u32;\npub const ICMF_CHOOSE_PREVIEW: u32 = 4u32;\npub const ICMF_COMPVARS_VALID: u32 = 1u32;\npub const ICMF_CONFIGURE_QUERY: u32 = 1u32;\npub const ICMODE_COMPRESS: u32 = 1u32;\npub const ICMODE_DECOMPRESS: u32 = 2u32;\npub const ICMODE_DRAW: u32 = 8u32;\npub const ICMODE_FASTCOMPRESS: u32 = 5u32;\npub const ICMODE_FASTDECOMPRESS: u32 = 3u32;\npub const ICMODE_INTERNALF_FUNCTION32: u32 = 32768u32;\npub const ICMODE_INTERNALF_MASK: u32 = 32768u32;\npub const ICMODE_QUERY: u32 = 4u32;\npub const ICM_ABOUT: u32 = 20491u32;\npub const ICM_COMPRESS: u32 = 16392u32;\npub const ICM_COMPRESS_BEGIN: u32 = 16391u32;\npub const ICM_COMPRESS_END: u32 = 16393u32;\npub const ICM_COMPRESS_FRAMES: u32 = 16455u32;\npub const ICM_COMPRESS_FRAMES_INFO: u32 = 16454u32;\npub const ICM_COMPRESS_GET_FORMAT: u32 = 16388u32;\npub const ICM_COMPRESS_GET_SIZE: u32 = 16389u32;\npub const ICM_COMPRESS_QUERY: u32 = 16390u32;\npub const ICM_CONFIGURE: u32 = 20490u32;\npub const ICM_DECOMPRESS: u32 = 16397u32;\npub const ICM_DECOMPRESSEX: u32 = 16446u32;\npub const ICM_DECOMPRESSEX_BEGIN: u32 = 16444u32;\npub const ICM_DECOMPRESSEX_END: u32 = 16447u32;\npub const ICM_DECOMPRESSEX_QUERY: u32 = 16445u32;\npub const ICM_DECOMPRESS_BEGIN: u32 = 16396u32;\npub const ICM_DECOMPRESS_END: u32 = 16398u32;\npub const ICM_DECOMPRESS_GET_FORMAT: u32 = 16394u32;\npub const ICM_DECOMPRESS_GET_PALETTE: u32 = 16414u32;\npub const ICM_DECOMPRESS_QUERY: u32 = 16395u32;\npub const ICM_DECOMPRESS_SET_PALETTE: u32 = 16413u32;\npub const ICM_DRAW: u32 = 16417u32;\npub const ICM_DRAW_BEGIN: u32 = 16399u32;\npub const ICM_DRAW_BITS: u32 = 16404u32;\npub const ICM_DRAW_CHANGEPALETTE: u32 = 16435u32;\npub const ICM_DRAW_END: u32 = 16405u32;\npub const ICM_DRAW_FLUSH: u32 = 16421u32;\npub const ICM_DRAW_GETTIME: u32 = 16416u32;\npub const ICM_DRAW_GET_PALETTE: u32 = 16400u32;\npub const ICM_DRAW_IDLE: u32 = 16436u32;\npub const ICM_DRAW_QUERY: u32 = 16415u32;\npub const ICM_DRAW_REALIZE: u32 = 16420u32;\npub const ICM_DRAW_RENDERBUFFER: u32 = 16422u32;\npub const ICM_DRAW_SETTIME: u32 = 16419u32;\npub const ICM_DRAW_START: u32 = 16402u32;\npub const ICM_DRAW_START_PLAY: u32 = 16423u32;\npub const ICM_DRAW_STOP: u32 = 16403u32;\npub const ICM_DRAW_STOP_PLAY: u32 = 16424u32;\npub const ICM_DRAW_SUGGESTFORMAT: u32 = 16434u32;\npub const ICM_DRAW_UPDATE: u32 = 16401u32;\npub const ICM_DRAW_WINDOW: u32 = 16418u32;\npub const ICM_ENUMFORMATS: u32 = 20501u32;\npub const ICM_GET: u32 = 20521u32;\npub const ICM_GETBUFFERSWANTED: u32 = 16425u32;\npub const ICM_GETDEFAULTKEYFRAMERATE: u32 = 16426u32;\npub const ICM_GETDEFAULTQUALITY: u32 = 20510u32;\npub const ICM_GETERRORTEXT: u32 = 20492u32;\npub const ICM_GETFORMATNAME: u32 = 20500u32;\npub const ICM_GETINFO: u32 = 20482u32;\npub const ICM_GETQUALITY: u32 = 20511u32;\npub const ICM_GETSTATE: u32 = 20480u32;\npub const ICM_RESERVED: u32 = 20480u32;\npub const ICM_RESERVED_HIGH: u32 = 24576u32;\npub const ICM_RESERVED_LOW: u32 = 20480u32;\npub const ICM_SET: u32 = 20520u32;\npub const ICM_SETQUALITY: u32 = 20512u32;\npub const ICM_SETSTATE: u32 = 20481u32;\npub const ICM_SET_STATUS_PROC: u32 = 16456u32;\npub const ICM_USER: u32 = 16384u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ICOPEN {\n    pub dwSize: u32,\n    pub fccType: u32,\n    pub fccHandler: u32,\n    pub dwVersion: u32,\n    pub dwFlags: u32,\n    pub dwError: super::super::Foundation::LRESULT,\n    pub pV1Reserved: *mut core::ffi::c_void,\n    pub pV2Reserved: *mut core::ffi::c_void,\n    pub dnDevNode: u32,\n}\nimpl Default for ICOPEN {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct ICPALETTE {\n    pub dwFlags: u32,\n    pub iStart: i32,\n    pub iLen: i32,\n    pub lppe: *mut super::super::Graphics::Gdi::PALETTEENTRY,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for ICPALETTE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ICQUALITY_DEFAULT: i32 = -1i32;\npub const ICQUALITY_HIGH: u32 = 10000u32;\npub const ICQUALITY_LOW: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ICSETSTATUSPROC {\n    pub dwFlags: u32,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub Status: isize,\n}\npub const ICSTATUS_END: u32 = 2u32;\npub const ICSTATUS_ERROR: u32 = 3u32;\npub const ICSTATUS_START: u32 = 0u32;\npub const ICSTATUS_STATUS: u32 = 1u32;\npub const ICSTATUS_YIELD: u32 = 4u32;\npub const ICVERSION: u32 = 260u32;\npub const IDD_ACMFILTERCHOOSE_BTN_DELNAME: u32 = 104u32;\npub const IDD_ACMFILTERCHOOSE_BTN_HELP: u32 = 9u32;\npub const IDD_ACMFILTERCHOOSE_BTN_SETNAME: u32 = 103u32;\npub const IDD_ACMFILTERCHOOSE_CMB_CUSTOM: u32 = 100u32;\npub const IDD_ACMFILTERCHOOSE_CMB_FILTER: u32 = 102u32;\npub const IDD_ACMFILTERCHOOSE_CMB_FILTERTAG: u32 = 101u32;\npub const IDD_ACMFORMATCHOOSE_BTN_DELNAME: u32 = 104u32;\npub const IDD_ACMFORMATCHOOSE_BTN_HELP: u32 = 9u32;\npub const IDD_ACMFORMATCHOOSE_BTN_SETNAME: u32 = 103u32;\npub const IDD_ACMFORMATCHOOSE_CMB_CUSTOM: u32 = 100u32;\npub const IDD_ACMFORMATCHOOSE_CMB_FORMAT: u32 = 102u32;\npub const IDD_ACMFORMATCHOOSE_CMB_FORMATTAG: u32 = 101u32;\npub const IDS_CAP_AUDIO_DROP_COMPERROR: u32 = 442u32;\npub const IDS_CAP_AUDIO_DROP_ERROR: u32 = 441u32;\npub const IDS_CAP_AVI_DRAWDIB_ERROR: u32 = 439u32;\npub const IDS_CAP_AVI_INIT_ERROR: u32 = 433u32;\npub const IDS_CAP_BEGIN: u32 = 300u32;\npub const IDS_CAP_CANTOPEN: u32 = 409u32;\npub const IDS_CAP_COMPRESSOR_ERROR: u32 = 440u32;\npub const IDS_CAP_DEFAVIEXT: u32 = 407u32;\npub const IDS_CAP_DEFPALEXT: u32 = 408u32;\npub const IDS_CAP_DRIVER_ERROR: u32 = 418u32;\npub const IDS_CAP_END: u32 = 301u32;\npub const IDS_CAP_ERRORDIBSAVE: u32 = 406u32;\npub const IDS_CAP_ERRORPALOPEN: u32 = 404u32;\npub const IDS_CAP_ERRORPALSAVE: u32 = 405u32;\npub const IDS_CAP_FILEEXISTS: u32 = 403u32;\npub const IDS_CAP_FILE_OPEN_ERROR: u32 = 429u32;\npub const IDS_CAP_FILE_WRITE_ERROR: u32 = 430u32;\npub const IDS_CAP_INFO: u32 = 401u32;\npub const IDS_CAP_MCI_CANT_STEP_ERROR: u32 = 437u32;\npub const IDS_CAP_MCI_CONTROL_ERROR: u32 = 436u32;\npub const IDS_CAP_NODISKSPACE: u32 = 415u32;\npub const IDS_CAP_NO_AUDIO_CAP_ERROR: u32 = 438u32;\npub const IDS_CAP_NO_FRAME_CAP_ERROR: u32 = 434u32;\npub const IDS_CAP_NO_PALETTE_WARN: u32 = 435u32;\npub const IDS_CAP_OUTOFMEM: u32 = 402u32;\npub const IDS_CAP_READONLYFILE: u32 = 413u32;\npub const IDS_CAP_RECORDING_ERROR: u32 = 431u32;\npub const IDS_CAP_RECORDING_ERROR2: u32 = 432u32;\npub const IDS_CAP_SAVEASPERCENT: u32 = 417u32;\npub const IDS_CAP_SEQ_MSGSTART: u32 = 410u32;\npub const IDS_CAP_SEQ_MSGSTOP: u32 = 411u32;\npub const IDS_CAP_SETFILESIZE: u32 = 416u32;\npub const IDS_CAP_STAT_CAP_AUDIO: u32 = 509u32;\npub const IDS_CAP_STAT_CAP_FINI: u32 = 503u32;\npub const IDS_CAP_STAT_CAP_INIT: u32 = 502u32;\npub const IDS_CAP_STAT_CAP_L_FRAMES: u32 = 508u32;\npub const IDS_CAP_STAT_FRAMESDROPPED: u32 = 513u32;\npub const IDS_CAP_STAT_I_FRAMES: u32 = 506u32;\npub const IDS_CAP_STAT_LIVE_MODE: u32 = 500u32;\npub const IDS_CAP_STAT_L_FRAMES: u32 = 507u32;\npub const IDS_CAP_STAT_OPTPAL_BUILD: u32 = 505u32;\npub const IDS_CAP_STAT_OVERLAY_MODE: u32 = 501u32;\npub const IDS_CAP_STAT_PALETTE_BUILD: u32 = 504u32;\npub const IDS_CAP_STAT_VIDEOAUDIO: u32 = 511u32;\npub const IDS_CAP_STAT_VIDEOCURRENT: u32 = 510u32;\npub const IDS_CAP_STAT_VIDEOONLY: u32 = 512u32;\npub const IDS_CAP_VIDEDITERR: u32 = 412u32;\npub const IDS_CAP_VIDEO_ADD_ERROR: u32 = 427u32;\npub const IDS_CAP_VIDEO_ALLOC_ERROR: u32 = 425u32;\npub const IDS_CAP_VIDEO_OPEN_ERROR: u32 = 424u32;\npub const IDS_CAP_VIDEO_PREPARE_ERROR: u32 = 426u32;\npub const IDS_CAP_VIDEO_SIZE_ERROR: u32 = 428u32;\npub const IDS_CAP_WAVE_ADD_ERROR: u32 = 422u32;\npub const IDS_CAP_WAVE_ALLOC_ERROR: u32 = 420u32;\npub const IDS_CAP_WAVE_OPEN_ERROR: u32 = 419u32;\npub const IDS_CAP_WAVE_PREPARE_ERROR: u32 = 421u32;\npub const IDS_CAP_WAVE_SIZE_ERROR: u32 = 423u32;\npub const IDS_CAP_WRITEERROR: u32 = 414u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct IMAADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n}\npub const JDD_CONFIGCHANGED: u32 = 2307u32;\npub const JDD_GETDEVCAPS: u32 = 2050u32;\npub const JDD_GETNUMDEVS: u32 = 2049u32;\npub const JDD_GETPOS: u32 = 2305u32;\npub const JDD_GETPOSEX: u32 = 2308u32;\npub const JDD_SETCALIBRATION: u32 = 2306u32;\npub const JIFMK_00: u32 = 65280u32;\npub const JIFMK_APP0: u32 = 65504u32;\npub const JIFMK_APP1: u32 = 65505u32;\npub const JIFMK_APP2: u32 = 65506u32;\npub const JIFMK_APP3: u32 = 65507u32;\npub const JIFMK_APP4: u32 = 65508u32;\npub const JIFMK_APP5: u32 = 65509u32;\npub const JIFMK_APP6: u32 = 65510u32;\npub const JIFMK_APP7: u32 = 65511u32;\npub const JIFMK_COM: u32 = 65534u32;\npub const JIFMK_DAC: u32 = 65484u32;\npub const JIFMK_DHP: u32 = 65502u32;\npub const JIFMK_DHT: u32 = 65476u32;\npub const JIFMK_DNL: u32 = 65500u32;\npub const JIFMK_DQT: u32 = 65499u32;\npub const JIFMK_DRI: u32 = 65501u32;\npub const JIFMK_EOI: u32 = 65497u32;\npub const JIFMK_EXP: u32 = 65503u32;\npub const JIFMK_FF: u32 = 65535u32;\npub const JIFMK_JPG: u32 = 65480u32;\npub const JIFMK_JPG0: u32 = 65520u32;\npub const JIFMK_JPG1: u32 = 65521u32;\npub const JIFMK_JPG10: u32 = 65530u32;\npub const JIFMK_JPG11: u32 = 65531u32;\npub const JIFMK_JPG12: u32 = 65532u32;\npub const JIFMK_JPG13: u32 = 65533u32;\npub const JIFMK_JPG2: u32 = 65522u32;\npub const JIFMK_JPG3: u32 = 65523u32;\npub const JIFMK_JPG4: u32 = 65524u32;\npub const JIFMK_JPG5: u32 = 65525u32;\npub const JIFMK_JPG6: u32 = 65526u32;\npub const JIFMK_JPG7: u32 = 65527u32;\npub const JIFMK_JPG8: u32 = 65528u32;\npub const JIFMK_JPG9: u32 = 65529u32;\npub const JIFMK_RES: u32 = 65282u32;\npub const JIFMK_RST0: u32 = 65488u32;\npub const JIFMK_RST1: u32 = 65489u32;\npub const JIFMK_RST2: u32 = 65490u32;\npub const JIFMK_RST3: u32 = 65491u32;\npub const JIFMK_RST4: u32 = 65492u32;\npub const JIFMK_RST5: u32 = 65493u32;\npub const JIFMK_RST6: u32 = 65494u32;\npub const JIFMK_RST7: u32 = 65495u32;\npub const JIFMK_SOF0: u32 = 65472u32;\npub const JIFMK_SOF1: u32 = 65473u32;\npub const JIFMK_SOF10: u32 = 65482u32;\npub const JIFMK_SOF11: u32 = 65483u32;\npub const JIFMK_SOF13: u32 = 65485u32;\npub const JIFMK_SOF14: u32 = 65486u32;\npub const JIFMK_SOF15: u32 = 65487u32;\npub const JIFMK_SOF2: u32 = 65474u32;\npub const JIFMK_SOF3: u32 = 65475u32;\npub const JIFMK_SOF5: u32 = 65477u32;\npub const JIFMK_SOF6: u32 = 65478u32;\npub const JIFMK_SOF7: u32 = 65479u32;\npub const JIFMK_SOF9: u32 = 65481u32;\npub const JIFMK_SOI: u32 = 65496u32;\npub const JIFMK_SOS: u32 = 65498u32;\npub const JIFMK_TEM: u32 = 65281u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct JOYCAPS2A {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub szPname: [i8; 32],\n    pub wXmin: u32,\n    pub wXmax: u32,\n    pub wYmin: u32,\n    pub wYmax: u32,\n    pub wZmin: u32,\n    pub wZmax: u32,\n    pub wNumButtons: u32,\n    pub wPeriodMin: u32,\n    pub wPeriodMax: u32,\n    pub wRmin: u32,\n    pub wRmax: u32,\n    pub wUmin: u32,\n    pub wUmax: u32,\n    pub wVmin: u32,\n    pub wVmax: u32,\n    pub wCaps: u32,\n    pub wMaxAxes: u32,\n    pub wNumAxes: u32,\n    pub wMaxButtons: u32,\n    pub szRegKey: [i8; 32],\n    pub szOEMVxD: [i8; 260],\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for JOYCAPS2A {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct JOYCAPS2W {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub szPname: [u16; 32],\n    pub wXmin: u32,\n    pub wXmax: u32,\n    pub wYmin: u32,\n    pub wYmax: u32,\n    pub wZmin: u32,\n    pub wZmax: u32,\n    pub wNumButtons: u32,\n    pub wPeriodMin: u32,\n    pub wPeriodMax: u32,\n    pub wRmin: u32,\n    pub wRmax: u32,\n    pub wUmin: u32,\n    pub wUmax: u32,\n    pub wVmin: u32,\n    pub wVmax: u32,\n    pub wCaps: u32,\n    pub wMaxAxes: u32,\n    pub wNumAxes: u32,\n    pub wMaxButtons: u32,\n    pub szRegKey: [u16; 32],\n    pub szOEMVxD: [u16; 260],\n    pub ManufacturerGuid: windows_sys::core::GUID,\n    pub ProductGuid: windows_sys::core::GUID,\n    pub NameGuid: windows_sys::core::GUID,\n}\nimpl Default for JOYCAPS2W {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct JOYCAPSA {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub szPname: [i8; 32],\n    pub wXmin: u32,\n    pub wXmax: u32,\n    pub wYmin: u32,\n    pub wYmax: u32,\n    pub wZmin: u32,\n    pub wZmax: u32,\n    pub wNumButtons: u32,\n    pub wPeriodMin: u32,\n    pub wPeriodMax: u32,\n    pub wRmin: u32,\n    pub wRmax: u32,\n    pub wUmin: u32,\n    pub wUmax: u32,\n    pub wVmin: u32,\n    pub wVmax: u32,\n    pub wCaps: u32,\n    pub wMaxAxes: u32,\n    pub wNumAxes: u32,\n    pub wMaxButtons: u32,\n    pub szRegKey: [i8; 32],\n    pub szOEMVxD: [i8; 260],\n}\nimpl Default for JOYCAPSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct JOYCAPSW {\n    pub wMid: u16,\n    pub wPid: u16,\n    pub szPname: [u16; 32],\n    pub wXmin: u32,\n    pub wXmax: u32,\n    pub wYmin: u32,\n    pub wYmax: u32,\n    pub wZmin: u32,\n    pub wZmax: u32,\n    pub wNumButtons: u32,\n    pub wPeriodMin: u32,\n    pub wPeriodMax: u32,\n    pub wRmin: u32,\n    pub wRmax: u32,\n    pub wUmin: u32,\n    pub wUmax: u32,\n    pub wVmin: u32,\n    pub wVmax: u32,\n    pub wCaps: u32,\n    pub wMaxAxes: u32,\n    pub wNumAxes: u32,\n    pub wMaxButtons: u32,\n    pub szRegKey: [u16; 32],\n    pub szOEMVxD: [u16; 260],\n}\nimpl Default for JOYCAPSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const JOYCAPS_HASPOV: u32 = 16u32;\npub const JOYCAPS_HASR: u32 = 2u32;\npub const JOYCAPS_HASU: u32 = 4u32;\npub const JOYCAPS_HASV: u32 = 8u32;\npub const JOYCAPS_HASZ: u32 = 1u32;\npub const JOYCAPS_POV4DIR: u32 = 32u32;\npub const JOYCAPS_POVCTS: u32 = 64u32;\npub const JOYERR_NOCANDO: u32 = 166u32;\npub const JOYERR_NOERROR: u32 = 0u32;\npub const JOYERR_PARMS: u32 = 165u32;\npub const JOYERR_UNPLUGGED: u32 = 167u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct JOYINFO {\n    pub wXpos: u32,\n    pub wYpos: u32,\n    pub wZpos: u32,\n    pub wButtons: u32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct JOYINFOEX {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub dwXpos: u32,\n    pub dwYpos: u32,\n    pub dwZpos: u32,\n    pub dwRpos: u32,\n    pub dwUpos: u32,\n    pub dwVpos: u32,\n    pub dwButtons: u32,\n    pub dwButtonNumber: u32,\n    pub dwPOV: u32,\n    pub dwReserved1: u32,\n    pub dwReserved2: u32,\n}\npub const JOYSTICKID1: u32 = 0u32;\npub const JOYSTICKID2: u32 = 1u32;\npub const JOY_BUTTON1: u32 = 1u32;\npub const JOY_BUTTON10: i32 = 512i32;\npub const JOY_BUTTON11: i32 = 1024i32;\npub const JOY_BUTTON12: i32 = 2048i32;\npub const JOY_BUTTON13: i32 = 4096i32;\npub const JOY_BUTTON14: i32 = 8192i32;\npub const JOY_BUTTON15: i32 = 16384i32;\npub const JOY_BUTTON16: i32 = 32768i32;\npub const JOY_BUTTON17: i32 = 65536i32;\npub const JOY_BUTTON18: i32 = 131072i32;\npub const JOY_BUTTON19: i32 = 262144i32;\npub const JOY_BUTTON1CHG: u32 = 256u32;\npub const JOY_BUTTON2: u32 = 2u32;\npub const JOY_BUTTON20: i32 = 524288i32;\npub const JOY_BUTTON21: i32 = 1048576i32;\npub const JOY_BUTTON22: i32 = 2097152i32;\npub const JOY_BUTTON23: i32 = 4194304i32;\npub const JOY_BUTTON24: i32 = 8388608i32;\npub const JOY_BUTTON25: i32 = 16777216i32;\npub const JOY_BUTTON26: i32 = 33554432i32;\npub const JOY_BUTTON27: i32 = 67108864i32;\npub const JOY_BUTTON28: i32 = 134217728i32;\npub const JOY_BUTTON29: i32 = 268435456i32;\npub const JOY_BUTTON2CHG: u32 = 512u32;\npub const JOY_BUTTON3: u32 = 4u32;\npub const JOY_BUTTON30: i32 = 536870912i32;\npub const JOY_BUTTON31: i32 = 1073741824i32;\npub const JOY_BUTTON32: i32 = -2147483648i32;\npub const JOY_BUTTON3CHG: u32 = 1024u32;\npub const JOY_BUTTON4: u32 = 8u32;\npub const JOY_BUTTON4CHG: u32 = 2048u32;\npub const JOY_BUTTON5: i32 = 16i32;\npub const JOY_BUTTON6: i32 = 32i32;\npub const JOY_BUTTON7: i32 = 64i32;\npub const JOY_BUTTON8: i32 = 128i32;\npub const JOY_BUTTON9: i32 = 256i32;\npub const JOY_CAL_READ3: i32 = 262144i32;\npub const JOY_CAL_READ4: i32 = 524288i32;\npub const JOY_CAL_READ5: i32 = 4194304i32;\npub const JOY_CAL_READ6: i32 = 8388608i32;\npub const JOY_CAL_READALWAYS: i32 = 65536i32;\npub const JOY_CAL_READRONLY: i32 = 33554432i32;\npub const JOY_CAL_READUONLY: i32 = 67108864i32;\npub const JOY_CAL_READVONLY: i32 = 134217728i32;\npub const JOY_CAL_READXONLY: i32 = 1048576i32;\npub const JOY_CAL_READXYONLY: i32 = 131072i32;\npub const JOY_CAL_READYONLY: i32 = 2097152i32;\npub const JOY_CAL_READZONLY: i32 = 16777216i32;\npub const JOY_CONFIGCHANGED_MSGSTRING: windows_sys::core::PCSTR = windows_sys::core::s!(\"MSJSTICK_VJOYD_MSGSTR\");\npub const JOY_POVBACKWARD: u32 = 18000u32;\npub const JOY_POVFORWARD: u32 = 0u32;\npub const JOY_POVLEFT: u32 = 27000u32;\npub const JOY_POVRIGHT: u32 = 9000u32;\npub const JOY_RETURNBUTTONS: i32 = 128i32;\npub const JOY_RETURNCENTERED: i32 = 1024i32;\npub const JOY_RETURNPOV: i32 = 64i32;\npub const JOY_RETURNPOVCTS: i32 = 512i32;\npub const JOY_RETURNR: i32 = 8i32;\npub const JOY_RETURNRAWDATA: i32 = 256i32;\npub const JOY_RETURNU: i32 = 16i32;\npub const JOY_RETURNV: i32 = 32i32;\npub const JOY_RETURNX: i32 = 1i32;\npub const JOY_RETURNY: i32 = 2i32;\npub const JOY_RETURNZ: i32 = 4i32;\npub const JOY_USEDEADZONE: i32 = 2048i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct JPEGINFOHEADER {\n    pub JPEGSize: u32,\n    pub JPEGProcess: u32,\n    pub JPEGColorSpaceID: u32,\n    pub JPEGBitsPerSample: u32,\n    pub JPEGHSubSampling: u32,\n    pub JPEGVSubSampling: u32,\n}\npub const JPEG_PROCESS_BASELINE: u32 = 0u32;\npub const JPEG_RGB: u32 = 3u32;\npub const JPEG_Y: u32 = 1u32;\npub const JPEG_YCbCr: u32 = 2u32;\npub const KSDATAFORMAT_SUBTYPE_IEEE_FLOAT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000003_0000_0010_8000_00aa00389b71);\n#[cfg(feature = \"Win32_System_IO\")]\npub type LPFNEXTDEVIO = Option<unsafe extern \"system\" fn(lparam: super::super::Foundation::LPARAM, dwflags: u32, dwiocontrolcode: u32, lpinbuffer: *mut core::ffi::c_void, ninbuffersize: u32, lpoutbuffer: *mut core::ffi::c_void, noutbuffersize: u32, lpbytesreturned: *mut u32, lpoverlapped: *mut super::super::System::IO::OVERLAPPED) -> windows_sys::core::BOOL>;\npub type LPMMIOPROC = Option<unsafe extern \"system\" fn(lpmmioinfo: windows_sys::core::PCSTR, umsg: u32, lparam1: super::super::Foundation::LPARAM, lparam2: super::super::Foundation::LPARAM) -> super::super::Foundation::LRESULT>;\npub type LPTASKCALLBACK = Option<unsafe extern \"system\" fn(dwinst: usize)>;\npub const MCIERR_AVI_AUDIOERROR: u32 = 619u32;\npub const MCIERR_AVI_BADPALETTE: u32 = 620u32;\npub const MCIERR_AVI_CANTPLAYFULLSCREEN: u32 = 615u32;\npub const MCIERR_AVI_DISPLAYERROR: u32 = 618u32;\npub const MCIERR_AVI_NOCOMPRESSOR: u32 = 617u32;\npub const MCIERR_AVI_NODISPDIB: u32 = 614u32;\npub const MCIERR_AVI_NOTINTERLEAVED: u32 = 613u32;\npub const MCIERR_AVI_OLDAVIFORMAT: u32 = 612u32;\npub const MCIERR_AVI_TOOBIGFORVGA: u32 = 616u32;\npub const MCIERR_BAD_CONSTANT: u32 = 290u32;\npub const MCIERR_BAD_INTEGER: u32 = 270u32;\npub const MCIERR_BAD_TIME_FORMAT: u32 = 293u32;\npub const MCIERR_CANNOT_LOAD_DRIVER: u32 = 266u32;\npub const MCIERR_CANNOT_USE_ALL: u32 = 279u32;\npub const MCIERR_CREATEWINDOW: u32 = 347u32;\npub const MCIERR_CUSTOM_DRIVER_BASE: u32 = 512u32;\npub const MCIERR_DEVICE_LENGTH: u32 = 310u32;\npub const MCIERR_DEVICE_LOCKED: u32 = 288u32;\npub const MCIERR_DEVICE_NOT_INSTALLED: u32 = 306u32;\npub const MCIERR_DEVICE_NOT_READY: u32 = 276u32;\npub const MCIERR_DEVICE_OPEN: u32 = 265u32;\npub const MCIERR_DEVICE_ORD_LENGTH: u32 = 311u32;\npub const MCIERR_DEVICE_TYPE_REQUIRED: u32 = 287u32;\npub const MCIERR_DGV_BAD_CLIPBOARD_RANGE: u32 = 517u32;\npub const MCIERR_DGV_DEVICE_LIMIT: u32 = 512u32;\npub const MCIERR_DGV_DEVICE_MEMORY_FULL: u32 = 516u32;\npub const MCIERR_DGV_DISK_FULL: u32 = 515u32;\npub const MCIERR_DGV_IOERR: u32 = 513u32;\npub const MCIERR_DGV_WORKSPACE_EMPTY: u32 = 514u32;\npub const MCIERR_DRIVER: u32 = 278u32;\npub const MCIERR_DRIVER_INTERNAL: u32 = 272u32;\npub const MCIERR_DUPLICATE_ALIAS: u32 = 289u32;\npub const MCIERR_DUPLICATE_FLAGS: u32 = 295u32;\npub const MCIERR_EXTENSION_NOT_FOUND: u32 = 281u32;\npub const MCIERR_EXTRA_CHARACTERS: u32 = 305u32;\npub const MCIERR_FILENAME_REQUIRED: u32 = 304u32;\npub const MCIERR_FILE_NOT_FOUND: u32 = 275u32;\npub const MCIERR_FILE_NOT_SAVED: u32 = 286u32;\npub const MCIERR_FILE_READ: u32 = 348u32;\npub const MCIERR_FILE_WRITE: u32 = 349u32;\npub const MCIERR_FLAGS_NOT_COMPATIBLE: u32 = 284u32;\npub const MCIERR_GET_CD: u32 = 307u32;\npub const MCIERR_HARDWARE: u32 = 262u32;\npub const MCIERR_ILLEGAL_FOR_AUTO_OPEN: u32 = 303u32;\npub const MCIERR_INTERNAL: u32 = 277u32;\npub const MCIERR_INVALID_DEVICE_ID: u32 = 257u32;\npub const MCIERR_INVALID_DEVICE_NAME: u32 = 263u32;\npub const MCIERR_INVALID_FILE: u32 = 296u32;\npub const MCIERR_MISSING_COMMAND_STRING: u32 = 267u32;\npub const MCIERR_MISSING_DEVICE_NAME: u32 = 292u32;\npub const MCIERR_MISSING_PARAMETER: u32 = 273u32;\npub const MCIERR_MISSING_STRING_ARGUMENT: u32 = 269u32;\npub const MCIERR_MULTIPLE: u32 = 280u32;\npub const MCIERR_MUST_USE_SHAREABLE: u32 = 291u32;\npub const MCIERR_NEW_REQUIRES_ALIAS: u32 = 299u32;\npub const MCIERR_NONAPPLICABLE_FUNCTION: u32 = 302u32;\npub const MCIERR_NOTIFY_ON_AUTO_OPEN: u32 = 300u32;\npub const MCIERR_NO_CLOSING_QUOTE: u32 = 294u32;\npub const MCIERR_NO_ELEMENT_ALLOWED: u32 = 301u32;\npub const MCIERR_NO_IDENTITY: u32 = 350u32;\npub const MCIERR_NO_INTEGER: u32 = 312u32;\npub const MCIERR_NO_WINDOW: u32 = 346u32;\npub const MCIERR_NULL_PARAMETER_BLOCK: u32 = 297u32;\npub const MCIERR_OUTOFRANGE: u32 = 282u32;\npub const MCIERR_OUT_OF_MEMORY: u32 = 264u32;\npub const MCIERR_PARAM_OVERFLOW: u32 = 268u32;\npub const MCIERR_PARSER_INTERNAL: u32 = 271u32;\npub const MCIERR_SEQ_DIV_INCOMPATIBLE: u32 = 336u32;\npub const MCIERR_SEQ_NOMIDIPRESENT: u32 = 343u32;\npub const MCIERR_SEQ_PORTUNSPECIFIED: u32 = 342u32;\npub const MCIERR_SEQ_PORT_INUSE: u32 = 337u32;\npub const MCIERR_SEQ_PORT_MAPNODEVICE: u32 = 339u32;\npub const MCIERR_SEQ_PORT_MISCERROR: u32 = 340u32;\npub const MCIERR_SEQ_PORT_NONEXISTENT: u32 = 338u32;\npub const MCIERR_SEQ_TIMER: u32 = 341u32;\npub const MCIERR_SET_CD: u32 = 308u32;\npub const MCIERR_SET_DRIVE: u32 = 309u32;\npub const MCIERR_UNNAMED_RESOURCE: u32 = 298u32;\npub const MCIERR_UNRECOGNIZED_COMMAND: u32 = 261u32;\npub const MCIERR_UNRECOGNIZED_KEYWORD: u32 = 259u32;\npub const MCIERR_UNSUPPORTED_FUNCTION: u32 = 274u32;\npub const MCIERR_WAVE_INPUTSINUSE: u32 = 322u32;\npub const MCIERR_WAVE_INPUTSUNSUITABLE: u32 = 328u32;\npub const MCIERR_WAVE_INPUTUNSPECIFIED: u32 = 325u32;\npub const MCIERR_WAVE_OUTPUTSINUSE: u32 = 320u32;\npub const MCIERR_WAVE_OUTPUTSUNSUITABLE: u32 = 326u32;\npub const MCIERR_WAVE_OUTPUTUNSPECIFIED: u32 = 324u32;\npub const MCIERR_WAVE_SETINPUTINUSE: u32 = 323u32;\npub const MCIERR_WAVE_SETINPUTUNSUITABLE: u32 = 329u32;\npub const MCIERR_WAVE_SETOUTPUTINUSE: u32 = 321u32;\npub const MCIERR_WAVE_SETOUTPUTUNSUITABLE: u32 = 327u32;\npub const MCIWNDF_NOAUTOSIZEMOVIE: u32 = 4u32;\npub const MCIWNDF_NOAUTOSIZEWINDOW: u32 = 1u32;\npub const MCIWNDF_NOERRORDLG: u32 = 16384u32;\npub const MCIWNDF_NOMENU: u32 = 8u32;\npub const MCIWNDF_NOOPEN: u32 = 32768u32;\npub const MCIWNDF_NOPLAYBAR: u32 = 2u32;\npub const MCIWNDF_NOTIFYALL: u32 = 7936u32;\npub const MCIWNDF_NOTIFYANSI: u32 = 128u32;\npub const MCIWNDF_NOTIFYERROR: u32 = 4096u32;\npub const MCIWNDF_NOTIFYMEDIA: u32 = 2048u32;\npub const MCIWNDF_NOTIFYMEDIAA: u32 = 2176u32;\npub const MCIWNDF_NOTIFYMEDIAW: u32 = 2048u32;\npub const MCIWNDF_NOTIFYMODE: u32 = 256u32;\npub const MCIWNDF_NOTIFYPOS: u32 = 512u32;\npub const MCIWNDF_NOTIFYSIZE: u32 = 1024u32;\npub const MCIWNDF_RECORD: u32 = 8192u32;\npub const MCIWNDF_SHOWALL: u32 = 112u32;\npub const MCIWNDF_SHOWMODE: u32 = 64u32;\npub const MCIWNDF_SHOWNAME: u32 = 16u32;\npub const MCIWNDF_SHOWPOS: u32 = 32u32;\npub const MCIWNDM_CAN_CONFIG: u32 = 1173u32;\npub const MCIWNDM_CAN_EJECT: u32 = 1172u32;\npub const MCIWNDM_CAN_PLAY: u32 = 1168u32;\npub const MCIWNDM_CAN_RECORD: u32 = 1170u32;\npub const MCIWNDM_CAN_SAVE: u32 = 1171u32;\npub const MCIWNDM_CAN_WINDOW: u32 = 1169u32;\npub const MCIWNDM_CHANGESTYLES: u32 = 1159u32;\npub const MCIWNDM_EJECT: u32 = 1131u32;\npub const MCIWNDM_GETACTIVETIMER: u32 = 1156u32;\npub const MCIWNDM_GETALIAS: u32 = 1161u32;\npub const MCIWNDM_GETDEVICE: u32 = 1249u32;\npub const MCIWNDM_GETDEVICEA: u32 = 1149u32;\npub const MCIWNDM_GETDEVICEID: u32 = 1124u32;\npub const MCIWNDM_GETDEVICEW: u32 = 1249u32;\npub const MCIWNDM_GETEND: u32 = 1129u32;\npub const MCIWNDM_GETERROR: u32 = 1252u32;\npub const MCIWNDM_GETERRORA: u32 = 1152u32;\npub const MCIWNDM_GETERRORW: u32 = 1252u32;\npub const MCIWNDM_GETFILENAME: u32 = 1248u32;\npub const MCIWNDM_GETFILENAMEA: u32 = 1148u32;\npub const MCIWNDM_GETFILENAMEW: u32 = 1248u32;\npub const MCIWNDM_GETINACTIVETIMER: u32 = 1157u32;\npub const MCIWNDM_GETLENGTH: u32 = 1128u32;\npub const MCIWNDM_GETMODE: u32 = 1230u32;\npub const MCIWNDM_GETMODEA: u32 = 1130u32;\npub const MCIWNDM_GETMODEW: u32 = 1230u32;\npub const MCIWNDM_GETPALETTE: u32 = 1150u32;\npub const MCIWNDM_GETPOSITION: u32 = 1226u32;\npub const MCIWNDM_GETPOSITIONA: u32 = 1126u32;\npub const MCIWNDM_GETPOSITIONW: u32 = 1226u32;\npub const MCIWNDM_GETREPEAT: u32 = 1139u32;\npub const MCIWNDM_GETSPEED: u32 = 1137u32;\npub const MCIWNDM_GETSTART: u32 = 1127u32;\npub const MCIWNDM_GETSTYLES: u32 = 1160u32;\npub const MCIWNDM_GETTIMEFORMAT: u32 = 1244u32;\npub const MCIWNDM_GETTIMEFORMATA: u32 = 1144u32;\npub const MCIWNDM_GETTIMEFORMATW: u32 = 1244u32;\npub const MCIWNDM_GETVOLUME: u32 = 1135u32;\npub const MCIWNDM_GETZOOM: u32 = 1133u32;\npub const MCIWNDM_GET_DEST: u32 = 1166u32;\npub const MCIWNDM_GET_SOURCE: u32 = 1164u32;\npub const MCIWNDM_NEW: u32 = 1258u32;\npub const MCIWNDM_NEWA: u32 = 1158u32;\npub const MCIWNDM_NEWW: u32 = 1258u32;\npub const MCIWNDM_NOTIFYERROR: u32 = 1229u32;\npub const MCIWNDM_NOTIFYMEDIA: u32 = 1227u32;\npub const MCIWNDM_NOTIFYMODE: u32 = 1224u32;\npub const MCIWNDM_NOTIFYPOS: u32 = 1225u32;\npub const MCIWNDM_NOTIFYSIZE: u32 = 1226u32;\npub const MCIWNDM_OPEN: u32 = 1276u32;\npub const MCIWNDM_OPENA: u32 = 1177u32;\npub const MCIWNDM_OPENINTERFACE: u32 = 1175u32;\npub const MCIWNDM_OPENW: u32 = 1276u32;\npub const MCIWNDM_PALETTEKICK: u32 = 1174u32;\npub const MCIWNDM_PLAYFROM: u32 = 1146u32;\npub const MCIWNDM_PLAYREVERSE: u32 = 1163u32;\npub const MCIWNDM_PLAYTO: u32 = 1147u32;\npub const MCIWNDM_PUT_DEST: u32 = 1167u32;\npub const MCIWNDM_PUT_SOURCE: u32 = 1165u32;\npub const MCIWNDM_REALIZE: u32 = 1142u32;\npub const MCIWNDM_RETURNSTRING: u32 = 1262u32;\npub const MCIWNDM_RETURNSTRINGA: u32 = 1162u32;\npub const MCIWNDM_RETURNSTRINGW: u32 = 1262u32;\npub const MCIWNDM_SENDSTRING: u32 = 1225u32;\npub const MCIWNDM_SENDSTRINGA: u32 = 1125u32;\npub const MCIWNDM_SENDSTRINGW: u32 = 1225u32;\npub const MCIWNDM_SETACTIVETIMER: u32 = 1154u32;\npub const MCIWNDM_SETINACTIVETIMER: u32 = 1155u32;\npub const MCIWNDM_SETOWNER: u32 = 1176u32;\npub const MCIWNDM_SETPALETTE: u32 = 1151u32;\npub const MCIWNDM_SETREPEAT: u32 = 1138u32;\npub const MCIWNDM_SETSPEED: u32 = 1136u32;\npub const MCIWNDM_SETTIMEFORMAT: u32 = 1243u32;\npub const MCIWNDM_SETTIMEFORMATA: u32 = 1143u32;\npub const MCIWNDM_SETTIMEFORMATW: u32 = 1243u32;\npub const MCIWNDM_SETTIMERS: u32 = 1153u32;\npub const MCIWNDM_SETVOLUME: u32 = 1134u32;\npub const MCIWNDM_SETZOOM: u32 = 1132u32;\npub const MCIWNDM_VALIDATEMEDIA: u32 = 1145u32;\npub const MCIWNDOPENF_NEW: u32 = 1u32;\npub const MCIWND_END: i32 = -2i32;\npub const MCIWND_START: i32 = -1i32;\npub const MCIWND_WINDOW_CLASS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MCIWndClass\");\npub const MCI_ANIM_GETDEVCAPS_CAN_REVERSE: i32 = 16385i32;\npub const MCI_ANIM_GETDEVCAPS_CAN_STRETCH: i32 = 16391i32;\npub const MCI_ANIM_GETDEVCAPS_FAST_RATE: i32 = 16386i32;\npub const MCI_ANIM_GETDEVCAPS_MAX_WINDOWS: i32 = 16392i32;\npub const MCI_ANIM_GETDEVCAPS_NORMAL_RATE: i32 = 16388i32;\npub const MCI_ANIM_GETDEVCAPS_PALETTES: i32 = 16390i32;\npub const MCI_ANIM_GETDEVCAPS_SLOW_RATE: i32 = 16387i32;\npub const MCI_ANIM_INFO_TEXT: i32 = 65536i32;\npub const MCI_ANIM_OPEN_NOSTATIC: i32 = 262144i32;\npub const MCI_ANIM_OPEN_PARENT: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_ANIM_OPEN_PARMSA {\n    pub dwCallback: usize,\n    pub wDeviceID: u32,\n    pub lpstrDeviceType: windows_sys::core::PCSTR,\n    pub lpstrElementName: windows_sys::core::PCSTR,\n    pub lpstrAlias: windows_sys::core::PCSTR,\n    pub dwStyle: u32,\n    pub hWndParent: super::super::Foundation::HWND,\n}\nimpl Default for MCI_ANIM_OPEN_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_ANIM_OPEN_PARMSW {\n    pub dwCallback: usize,\n    pub wDeviceID: u32,\n    pub lpstrDeviceType: windows_sys::core::PCWSTR,\n    pub lpstrElementName: windows_sys::core::PCWSTR,\n    pub lpstrAlias: windows_sys::core::PCWSTR,\n    pub dwStyle: u32,\n    pub hWndParent: super::super::Foundation::HWND,\n}\nimpl Default for MCI_ANIM_OPEN_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_ANIM_OPEN_WS: i32 = 65536i32;\npub const MCI_ANIM_PLAY_FAST: i32 = 262144i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_ANIM_PLAY_PARMS {\n    pub dwCallback: usize,\n    pub dwFrom: u32,\n    pub dwTo: u32,\n    pub dwSpeed: u32,\n}\npub const MCI_ANIM_PLAY_REVERSE: i32 = 131072i32;\npub const MCI_ANIM_PLAY_SCAN: i32 = 1048576i32;\npub const MCI_ANIM_PLAY_SLOW: i32 = 524288i32;\npub const MCI_ANIM_PLAY_SPEED: i32 = 65536i32;\npub const MCI_ANIM_PUT_DESTINATION: i32 = 262144i32;\npub const MCI_ANIM_PUT_SOURCE: i32 = 131072i32;\npub const MCI_ANIM_REALIZE_BKGD: i32 = 131072i32;\npub const MCI_ANIM_REALIZE_NORM: i32 = 65536i32;\npub const MCI_ANIM_RECT: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_ANIM_RECT_PARMS {\n    pub dwCallback: usize,\n    pub rc: super::super::Foundation::RECT,\n}\npub const MCI_ANIM_STATUS_FORWARD: i32 = 16386i32;\npub const MCI_ANIM_STATUS_HPAL: i32 = 16388i32;\npub const MCI_ANIM_STATUS_HWND: i32 = 16387i32;\npub const MCI_ANIM_STATUS_SPEED: i32 = 16385i32;\npub const MCI_ANIM_STATUS_STRETCH: i32 = 16389i32;\npub const MCI_ANIM_STEP_FRAMES: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_ANIM_STEP_PARMS {\n    pub dwCallback: usize,\n    pub dwFrames: u32,\n}\npub const MCI_ANIM_STEP_REVERSE: i32 = 65536i32;\npub const MCI_ANIM_UPDATE_HDC: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct MCI_ANIM_UPDATE_PARMS {\n    pub dwCallback: usize,\n    pub rc: super::super::Foundation::RECT,\n    pub hDC: super::super::Graphics::Gdi::HDC,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for MCI_ANIM_UPDATE_PARMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_ANIM_WHERE_DESTINATION: i32 = 262144i32;\npub const MCI_ANIM_WHERE_SOURCE: i32 = 131072i32;\npub const MCI_ANIM_WINDOW_DEFAULT: i32 = 0i32;\npub const MCI_ANIM_WINDOW_DISABLE_STRETCH: i32 = 2097152i32;\npub const MCI_ANIM_WINDOW_ENABLE_STRETCH: i32 = 1048576i32;\npub const MCI_ANIM_WINDOW_HWND: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_ANIM_WINDOW_PARMSA {\n    pub dwCallback: usize,\n    pub hWnd: super::super::Foundation::HWND,\n    pub nCmdShow: u32,\n    pub lpstrText: windows_sys::core::PCSTR,\n}\nimpl Default for MCI_ANIM_WINDOW_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_ANIM_WINDOW_PARMSW {\n    pub dwCallback: usize,\n    pub hWnd: super::super::Foundation::HWND,\n    pub nCmdShow: u32,\n    pub lpstrText: windows_sys::core::PCWSTR,\n}\nimpl Default for MCI_ANIM_WINDOW_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_ANIM_WINDOW_STATE: i32 = 262144i32;\npub const MCI_ANIM_WINDOW_TEXT: i32 = 524288i32;\npub const MCI_AVI_SETVIDEO_DRAW_PROCEDURE: i32 = 32768i32;\npub const MCI_AVI_SETVIDEO_PALETTE_COLOR: i32 = 33024i32;\npub const MCI_AVI_SETVIDEO_PALETTE_HALFTONE: i32 = 65535i32;\npub const MCI_AVI_STATUS_AUDIO_BREAKS: i32 = 32771i32;\npub const MCI_AVI_STATUS_FRAMES_SKIPPED: i32 = 32769i32;\npub const MCI_AVI_STATUS_LAST_PLAY_SPEED: i32 = 32770i32;\npub const MCI_BREAK: u32 = 2065u32;\npub const MCI_BREAK_HWND: i32 = 512i32;\npub const MCI_BREAK_KEY: i32 = 256i32;\npub const MCI_BREAK_OFF: i32 = 1024i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_BREAK_PARMS {\n    pub dwCallback: usize,\n    pub nVirtKey: i32,\n    pub hwndBreak: super::super::Foundation::HWND,\n}\nimpl Default for MCI_BREAK_PARMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_CAPTURE: u32 = 2160u32;\npub const MCI_CDA_STATUS_TYPE_TRACK: i32 = 16385i32;\npub const MCI_CDA_TRACK_AUDIO: u32 = 1088u32;\npub const MCI_CDA_TRACK_OTHER: u32 = 1089u32;\npub const MCI_CLOSE: u32 = 2052u32;\npub const MCI_CLOSE_DRIVER: u32 = 2050u32;\npub const MCI_COLONIZED3_RETURN: u32 = 131072u32;\npub const MCI_COLONIZED4_RETURN: u32 = 262144u32;\npub const MCI_COMMAND_HEAD: u32 = 0u32;\npub const MCI_CONFIGURE: u32 = 2170u32;\npub const MCI_CONSTANT: u32 = 8u32;\npub const MCI_COPY: u32 = 2130u32;\npub const MCI_CUE: u32 = 2096u32;\npub const MCI_CUT: u32 = 2129u32;\npub const MCI_DELETE: u32 = 2134u32;\npub const MCI_DEVTYPE_ANIMATION: u32 = 519u32;\npub const MCI_DEVTYPE_CD_AUDIO: u32 = 516u32;\npub const MCI_DEVTYPE_DAT: u32 = 517u32;\npub const MCI_DEVTYPE_DIGITAL_VIDEO: u32 = 520u32;\npub const MCI_DEVTYPE_FIRST: u32 = 513u32;\npub const MCI_DEVTYPE_FIRST_USER: u32 = 4096u32;\npub const MCI_DEVTYPE_LAST: u32 = 523u32;\npub const MCI_DEVTYPE_OTHER: u32 = 521u32;\npub const MCI_DEVTYPE_OVERLAY: u32 = 515u32;\npub const MCI_DEVTYPE_SCANNER: u32 = 518u32;\npub const MCI_DEVTYPE_SEQUENCER: u32 = 523u32;\npub const MCI_DEVTYPE_VCR: u32 = 513u32;\npub const MCI_DEVTYPE_VIDEODISC: u32 = 514u32;\npub const MCI_DEVTYPE_WAVEFORM_AUDIO: u32 = 522u32;\npub const MCI_DGV_CAPTURE_AS: i32 = 65536i32;\npub const MCI_DGV_CAPTURE_AT: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_CAPTURE_PARMSA {\n    pub dwCallback: usize,\n    pub lpstrFileName: windows_sys::core::PSTR,\n    pub rc: super::super::Foundation::RECT,\n}\nimpl Default for MCI_DGV_CAPTURE_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_CAPTURE_PARMSW {\n    pub dwCallback: usize,\n    pub lpstrFileName: windows_sys::core::PWSTR,\n    pub rc: super::super::Foundation::RECT,\n}\nimpl Default for MCI_DGV_CAPTURE_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_COPY_AT: i32 = 65536i32;\npub const MCI_DGV_COPY_AUDIO_STREAM: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_COPY_PARMS {\n    pub dwCallback: usize,\n    pub dwFrom: u32,\n    pub dwTo: u32,\n    pub rc: super::super::Foundation::RECT,\n    pub dwAudioStream: u32,\n    pub dwVideoStream: u32,\n}\npub const MCI_DGV_COPY_VIDEO_STREAM: i32 = 262144i32;\npub const MCI_DGV_CUE_INPUT: i32 = 65536i32;\npub const MCI_DGV_CUE_NOSHOW: i32 = 262144i32;\npub const MCI_DGV_CUE_OUTPUT: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_CUE_PARMS {\n    pub dwCallback: usize,\n    pub dwTo: u32,\n}\npub const MCI_DGV_CUT_AT: i32 = 65536i32;\npub const MCI_DGV_CUT_AUDIO_STREAM: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_CUT_PARMS {\n    pub dwCallback: usize,\n    pub dwFrom: u32,\n    pub dwTo: u32,\n    pub rc: super::super::Foundation::RECT,\n    pub dwAudioStream: u32,\n    pub dwVideoStream: u32,\n}\npub const MCI_DGV_CUT_VIDEO_STREAM: i32 = 262144i32;\npub const MCI_DGV_DELETE_AT: i32 = 65536i32;\npub const MCI_DGV_DELETE_AUDIO_STREAM: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_DELETE_PARMS {\n    pub dwCallback: usize,\n    pub dwFrom: u32,\n    pub dwTo: u32,\n    pub rc: super::super::Foundation::RECT,\n    pub dwAudioStream: u32,\n    pub dwVideoStream: u32,\n}\npub const MCI_DGV_DELETE_VIDEO_STREAM: i32 = 262144i32;\npub const MCI_DGV_FF_AVI: i32 = 16385i32;\npub const MCI_DGV_FF_AVSS: i32 = 16384i32;\npub const MCI_DGV_FF_DIB: i32 = 16386i32;\npub const MCI_DGV_FF_JFIF: i32 = 16390i32;\npub const MCI_DGV_FF_JPEG: i32 = 16388i32;\npub const MCI_DGV_FF_MPEG: i32 = 16391i32;\npub const MCI_DGV_FF_RDIB: i32 = 16387i32;\npub const MCI_DGV_FF_RJPEG: i32 = 16389i32;\npub const MCI_DGV_FILE_MODE_EDITING: u32 = 3u32;\npub const MCI_DGV_FILE_MODE_EDITING_S: i32 = 32774i32;\npub const MCI_DGV_FILE_MODE_IDLE: u32 = 4u32;\npub const MCI_DGV_FILE_MODE_IDLE_S: i32 = 32775i32;\npub const MCI_DGV_FILE_MODE_LOADING: u32 = 2u32;\npub const MCI_DGV_FILE_MODE_LOADING_S: i32 = 32773i32;\npub const MCI_DGV_FILE_MODE_SAVING: u32 = 1u32;\npub const MCI_DGV_FILE_MODE_SAVING_S: i32 = 32772i32;\npub const MCI_DGV_FILE_S: i32 = 32770i32;\npub const MCI_DGV_FREEZE_AT: i32 = 65536i32;\npub const MCI_DGV_FREEZE_OUTSIDE: i32 = 131072i32;\npub const MCI_DGV_GETDEVCAPS_CAN_FREEZE: i32 = 16386i32;\npub const MCI_DGV_GETDEVCAPS_CAN_LOCK: i32 = 16384i32;\npub const MCI_DGV_GETDEVCAPS_CAN_REVERSE: i32 = 16388i32;\npub const MCI_DGV_GETDEVCAPS_CAN_STRETCH: i32 = 16385i32;\npub const MCI_DGV_GETDEVCAPS_CAN_STR_IN: i32 = 16392i32;\npub const MCI_DGV_GETDEVCAPS_CAN_TEST: i32 = 16393i32;\npub const MCI_DGV_GETDEVCAPS_HAS_STILL: i32 = 16389i32;\npub const MCI_DGV_GETDEVCAPS_MAXIMUM_RATE: i32 = 16394i32;\npub const MCI_DGV_GETDEVCAPS_MAX_WINDOWS: i32 = 16387i32;\npub const MCI_DGV_GETDEVCAPS_MINIMUM_RATE: i32 = 16395i32;\npub const MCI_DGV_GETDEVCAPS_PALETTES: i32 = 16390i32;\npub const MCI_DGV_INFO_AUDIO_ALG: i32 = 16388i32;\npub const MCI_DGV_INFO_AUDIO_QUALITY: i32 = 16385i32;\npub const MCI_DGV_INFO_ITEM: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_INFO_PARMSA {\n    pub dwCallback: usize,\n    pub lpstrReturn: windows_sys::core::PSTR,\n    pub dwRetSize: u32,\n    pub dwItem: u32,\n}\nimpl Default for MCI_DGV_INFO_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_INFO_PARMSW {\n    pub dwCallback: usize,\n    pub lpstrReturn: windows_sys::core::PWSTR,\n    pub dwRetSize: u32,\n    pub dwItem: u32,\n}\nimpl Default for MCI_DGV_INFO_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_INFO_STILL_ALG: i32 = 16389i32;\npub const MCI_DGV_INFO_STILL_QUALITY: i32 = 16386i32;\npub const MCI_DGV_INFO_TEXT: i32 = 65536i32;\npub const MCI_DGV_INFO_USAGE: i32 = 16384i32;\npub const MCI_DGV_INFO_VIDEO_ALG: i32 = 16390i32;\npub const MCI_DGV_INFO_VIDEO_QUALITY: i32 = 16387i32;\npub const MCI_DGV_INPUT_S: i32 = 32771i32;\npub const MCI_DGV_LIST_ALG: i32 = 524288i32;\npub const MCI_DGV_LIST_AUDIO_ALG: i32 = 16384i32;\npub const MCI_DGV_LIST_AUDIO_QUALITY: i32 = 16385i32;\npub const MCI_DGV_LIST_AUDIO_STREAM: i32 = 16386i32;\npub const MCI_DGV_LIST_COUNT: i32 = 131072i32;\npub const MCI_DGV_LIST_ITEM: i32 = 65536i32;\npub const MCI_DGV_LIST_NUMBER: i32 = 262144i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_LIST_PARMSA {\n    pub dwCallback: usize,\n    pub lpstrReturn: windows_sys::core::PSTR,\n    pub dwLength: u32,\n    pub dwNumber: u32,\n    pub dwItem: u32,\n    pub lpstrAlgorithm: windows_sys::core::PSTR,\n}\nimpl Default for MCI_DGV_LIST_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_LIST_PARMSW {\n    pub dwCallback: usize,\n    pub lpstrReturn: windows_sys::core::PWSTR,\n    pub dwLength: u32,\n    pub dwNumber: u32,\n    pub dwItem: u32,\n    pub lpstrAlgorithm: windows_sys::core::PWSTR,\n}\nimpl Default for MCI_DGV_LIST_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_LIST_STILL_ALG: i32 = 16387i32;\npub const MCI_DGV_LIST_STILL_QUALITY: i32 = 16388i32;\npub const MCI_DGV_LIST_VIDEO_ALG: i32 = 16389i32;\npub const MCI_DGV_LIST_VIDEO_QUALITY: i32 = 16390i32;\npub const MCI_DGV_LIST_VIDEO_SOURCE: i32 = 16392i32;\npub const MCI_DGV_LIST_VIDEO_STREAM: i32 = 16391i32;\npub const MCI_DGV_METHOD_DIRECT: i32 = 40962i32;\npub const MCI_DGV_METHOD_POST: i32 = 40961i32;\npub const MCI_DGV_METHOD_PRE: i32 = 40960i32;\npub const MCI_DGV_MONITOR_FILE: i32 = 16385i32;\npub const MCI_DGV_MONITOR_INPUT: i32 = 16384i32;\npub const MCI_DGV_MONITOR_METHOD: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_MONITOR_PARMS {\n    pub dwCallback: usize,\n    pub dwSource: u32,\n    pub dwMethod: u32,\n}\npub const MCI_DGV_MONITOR_SOURCE: i32 = 131072i32;\npub const MCI_DGV_OPEN_16BIT: i32 = 524288i32;\npub const MCI_DGV_OPEN_32BIT: i32 = 1048576i32;\npub const MCI_DGV_OPEN_NOSTATIC: i32 = 262144i32;\npub const MCI_DGV_OPEN_PARENT: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_OPEN_PARMSA {\n    pub dwCallback: usize,\n    pub wDeviceID: u32,\n    pub lpstrDeviceType: windows_sys::core::PSTR,\n    pub lpstrElementName: windows_sys::core::PSTR,\n    pub lpstrAlias: windows_sys::core::PSTR,\n    pub dwStyle: u32,\n    pub hWndParent: super::super::Foundation::HWND,\n}\nimpl Default for MCI_DGV_OPEN_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_OPEN_PARMSW {\n    pub dwCallback: usize,\n    pub wDeviceID: u32,\n    pub lpstrDeviceType: windows_sys::core::PWSTR,\n    pub lpstrElementName: windows_sys::core::PWSTR,\n    pub lpstrAlias: windows_sys::core::PWSTR,\n    pub dwStyle: u32,\n    pub hWndParent: super::super::Foundation::HWND,\n}\nimpl Default for MCI_DGV_OPEN_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_OPEN_WS: i32 = 65536i32;\npub const MCI_DGV_PASTE_AT: i32 = 65536i32;\npub const MCI_DGV_PASTE_AUDIO_STREAM: i32 = 131072i32;\npub const MCI_DGV_PASTE_INSERT: i32 = 524288i32;\npub const MCI_DGV_PASTE_OVERWRITE: i32 = 1048576i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_PASTE_PARMS {\n    pub dwCallback: usize,\n    pub dwTo: u32,\n    pub rc: super::super::Foundation::RECT,\n    pub dwAudioStream: u32,\n    pub dwVideoStream: u32,\n}\npub const MCI_DGV_PASTE_VIDEO_STREAM: i32 = 262144i32;\npub const MCI_DGV_PLAY_REPEAT: i32 = 65536i32;\npub const MCI_DGV_PLAY_REVERSE: i32 = 131072i32;\npub const MCI_DGV_PUT_CLIENT: i32 = 4194304i32;\npub const MCI_DGV_PUT_DESTINATION: i32 = 262144i32;\npub const MCI_DGV_PUT_FRAME: i32 = 524288i32;\npub const MCI_DGV_PUT_SOURCE: i32 = 131072i32;\npub const MCI_DGV_PUT_VIDEO: i32 = 1048576i32;\npub const MCI_DGV_PUT_WINDOW: i32 = 2097152i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_QUALITY_PARMSA {\n    pub dwCallback: usize,\n    pub dwItem: u32,\n    pub lpstrName: windows_sys::core::PSTR,\n    pub lpstrAlgorithm: u32,\n    pub dwHandle: u32,\n}\nimpl Default for MCI_DGV_QUALITY_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_QUALITY_PARMSW {\n    pub dwCallback: usize,\n    pub dwItem: u32,\n    pub lpstrName: windows_sys::core::PWSTR,\n    pub lpstrAlgorithm: u32,\n    pub dwHandle: u32,\n}\nimpl Default for MCI_DGV_QUALITY_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_REALIZE_BKGD: i32 = 131072i32;\npub const MCI_DGV_REALIZE_NORM: i32 = 65536i32;\npub const MCI_DGV_RECORD_AUDIO_STREAM: i32 = 262144i32;\npub const MCI_DGV_RECORD_HOLD: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_RECORD_PARMS {\n    pub dwCallback: usize,\n    pub dwFrom: u32,\n    pub dwTo: u32,\n    pub rc: super::super::Foundation::RECT,\n    pub dwAudioStream: u32,\n    pub dwVideoStream: u32,\n}\npub const MCI_DGV_RECORD_VIDEO_STREAM: i32 = 524288i32;\npub const MCI_DGV_RECT: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_RECT_PARMS {\n    pub dwCallback: usize,\n    pub rc: super::super::Foundation::RECT,\n}\npub const MCI_DGV_RESERVE_IN: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_RESERVE_PARMSA {\n    pub dwCallback: usize,\n    pub lpstrPath: windows_sys::core::PSTR,\n    pub dwSize: u32,\n}\nimpl Default for MCI_DGV_RESERVE_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_RESERVE_PARMSW {\n    pub dwCallback: usize,\n    pub lpstrPath: windows_sys::core::PWSTR,\n    pub dwSize: u32,\n}\nimpl Default for MCI_DGV_RESERVE_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_RESERVE_SIZE: i32 = 131072i32;\npub const MCI_DGV_RESTORE_AT: i32 = 131072i32;\npub const MCI_DGV_RESTORE_FROM: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_RESTORE_PARMSA {\n    pub dwCallback: usize,\n    pub lpstrFileName: windows_sys::core::PSTR,\n    pub rc: super::super::Foundation::RECT,\n}\nimpl Default for MCI_DGV_RESTORE_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_RESTORE_PARMSW {\n    pub dwCallback: usize,\n    pub lpstrFileName: windows_sys::core::PWSTR,\n    pub rc: super::super::Foundation::RECT,\n}\nimpl Default for MCI_DGV_RESTORE_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_SAVE_ABORT: i32 = 131072i32;\npub const MCI_DGV_SAVE_KEEPRESERVE: i32 = 262144i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_SAVE_PARMSA {\n    pub dwCallback: usize,\n    pub lpstrFileName: windows_sys::core::PSTR,\n    pub rc: super::super::Foundation::RECT,\n}\nimpl Default for MCI_DGV_SAVE_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_SAVE_PARMSW {\n    pub dwCallback: usize,\n    pub lpstrFileName: windows_sys::core::PWSTR,\n    pub rc: super::super::Foundation::RECT,\n}\nimpl Default for MCI_DGV_SAVE_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_SETAUDIO_ALG: i32 = 262144i32;\npub const MCI_DGV_SETAUDIO_AVGBYTESPERSEC: i32 = 16390i32;\npub const MCI_DGV_SETAUDIO_BASS: i32 = 16385i32;\npub const MCI_DGV_SETAUDIO_BITSPERSAMPLE: i32 = 16392i32;\npub const MCI_DGV_SETAUDIO_BLOCKALIGN: i32 = 16391i32;\npub const MCI_DGV_SETAUDIO_CLOCKTIME: i32 = 131072i32;\npub const MCI_DGV_SETAUDIO_INPUT: i32 = 33554432i32;\npub const MCI_DGV_SETAUDIO_ITEM: i32 = 8388608i32;\npub const MCI_DGV_SETAUDIO_LEFT: i32 = 2097152i32;\npub const MCI_DGV_SETAUDIO_OUTPUT: i32 = 67108864i32;\npub const MCI_DGV_SETAUDIO_OVER: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_SETAUDIO_PARMSA {\n    pub dwCallback: usize,\n    pub dwItem: u32,\n    pub dwValue: u32,\n    pub dwOver: u32,\n    pub lpstrAlgorithm: windows_sys::core::PSTR,\n    pub lpstrQuality: windows_sys::core::PSTR,\n}\nimpl Default for MCI_DGV_SETAUDIO_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_SETAUDIO_PARMSW {\n    pub dwCallback: usize,\n    pub dwItem: u32,\n    pub dwValue: u32,\n    pub dwOver: u32,\n    pub lpstrAlgorithm: windows_sys::core::PWSTR,\n    pub lpstrQuality: windows_sys::core::PWSTR,\n}\nimpl Default for MCI_DGV_SETAUDIO_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_SETAUDIO_QUALITY: i32 = 524288i32;\npub const MCI_DGV_SETAUDIO_RECORD: i32 = 1048576i32;\npub const MCI_DGV_SETAUDIO_RIGHT: i32 = 4194304i32;\npub const MCI_DGV_SETAUDIO_SAMPLESPERSEC: i32 = 16389i32;\npub const MCI_DGV_SETAUDIO_SOURCE: i32 = 16388i32;\npub const MCI_DGV_SETAUDIO_SOURCE_AVERAGE: i32 = 16384i32;\npub const MCI_DGV_SETAUDIO_SOURCE_LEFT: i32 = 1i32;\npub const MCI_DGV_SETAUDIO_SOURCE_RIGHT: i32 = 2i32;\npub const MCI_DGV_SETAUDIO_SOURCE_STEREO: i32 = 0i32;\npub const MCI_DGV_SETAUDIO_SRC_AVERAGE_S: i32 = 32802i32;\npub const MCI_DGV_SETAUDIO_SRC_LEFT_S: i32 = 32800i32;\npub const MCI_DGV_SETAUDIO_SRC_RIGHT_S: i32 = 32801i32;\npub const MCI_DGV_SETAUDIO_SRC_STEREO_S: i32 = 32803i32;\npub const MCI_DGV_SETAUDIO_STREAM: i32 = 16387i32;\npub const MCI_DGV_SETAUDIO_TREBLE: i32 = 16384i32;\npub const MCI_DGV_SETAUDIO_VALUE: i32 = 16777216i32;\npub const MCI_DGV_SETAUDIO_VOLUME: i32 = 16386i32;\npub const MCI_DGV_SETVIDEO_ALG: i32 = 131072i32;\npub const MCI_DGV_SETVIDEO_BITSPERPEL: i32 = 16396i32;\npub const MCI_DGV_SETVIDEO_BRIGHTNESS: i32 = 16384i32;\npub const MCI_DGV_SETVIDEO_CLOCKTIME: i32 = 262144i32;\npub const MCI_DGV_SETVIDEO_COLOR: i32 = 16385i32;\npub const MCI_DGV_SETVIDEO_CONTRAST: i32 = 16386i32;\npub const MCI_DGV_SETVIDEO_FRAME_RATE: i32 = 16392i32;\npub const MCI_DGV_SETVIDEO_GAMMA: i32 = 16389i32;\npub const MCI_DGV_SETVIDEO_INPUT: i32 = 33554432i32;\npub const MCI_DGV_SETVIDEO_ITEM: i32 = 1048576i32;\npub const MCI_DGV_SETVIDEO_KEY_COLOR: i32 = 16395i32;\npub const MCI_DGV_SETVIDEO_KEY_INDEX: i32 = 16394i32;\npub const MCI_DGV_SETVIDEO_OUTPUT: i32 = 67108864i32;\npub const MCI_DGV_SETVIDEO_OVER: i32 = 2097152i32;\npub const MCI_DGV_SETVIDEO_PALHANDLE: i32 = 16391i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_SETVIDEO_PARMSA {\n    pub dwCallback: usize,\n    pub dwItem: u32,\n    pub dwValue: u32,\n    pub dwOver: u32,\n    pub lpstrAlgorithm: windows_sys::core::PSTR,\n    pub lpstrQuality: windows_sys::core::PSTR,\n    pub dwSourceNumber: u32,\n}\nimpl Default for MCI_DGV_SETVIDEO_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_SETVIDEO_PARMSW {\n    pub dwCallback: usize,\n    pub dwItem: u32,\n    pub dwValue: u32,\n    pub dwOver: u32,\n    pub lpstrAlgorithm: windows_sys::core::PWSTR,\n    pub lpstrQuality: windows_sys::core::PWSTR,\n    pub dwSourceNumber: u32,\n}\nimpl Default for MCI_DGV_SETVIDEO_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_SETVIDEO_QUALITY: i32 = 65536i32;\npub const MCI_DGV_SETVIDEO_RECORD: i32 = 4194304i32;\npub const MCI_DGV_SETVIDEO_SHARPNESS: i32 = 16388i32;\npub const MCI_DGV_SETVIDEO_SOURCE: i32 = 16393i32;\npub const MCI_DGV_SETVIDEO_SRC_GENERIC: i32 = 16389i32;\npub const MCI_DGV_SETVIDEO_SRC_GENERIC_S: i32 = 32789i32;\npub const MCI_DGV_SETVIDEO_SRC_NTSC: i32 = 16384i32;\npub const MCI_DGV_SETVIDEO_SRC_NTSC_S: i32 = 32784i32;\npub const MCI_DGV_SETVIDEO_SRC_NUMBER: i32 = 524288i32;\npub const MCI_DGV_SETVIDEO_SRC_PAL: i32 = 16387i32;\npub const MCI_DGV_SETVIDEO_SRC_PAL_S: i32 = 32787i32;\npub const MCI_DGV_SETVIDEO_SRC_RGB: i32 = 16385i32;\npub const MCI_DGV_SETVIDEO_SRC_RGB_S: i32 = 32785i32;\npub const MCI_DGV_SETVIDEO_SRC_SECAM: i32 = 16388i32;\npub const MCI_DGV_SETVIDEO_SRC_SECAM_S: i32 = 32788i32;\npub const MCI_DGV_SETVIDEO_SRC_SVIDEO: i32 = 16386i32;\npub const MCI_DGV_SETVIDEO_SRC_SVIDEO_S: i32 = 32786i32;\npub const MCI_DGV_SETVIDEO_STILL: i32 = 8388608i32;\npub const MCI_DGV_SETVIDEO_STREAM: i32 = 16390i32;\npub const MCI_DGV_SETVIDEO_TINT: i32 = 16387i32;\npub const MCI_DGV_SETVIDEO_VALUE: i32 = 16777216i32;\npub const MCI_DGV_SET_FILEFORMAT: i32 = 524288i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_SET_PARMS {\n    pub dwCallback: usize,\n    pub dwTimeFormat: u32,\n    pub dwAudio: u32,\n    pub dwFileFormat: u32,\n    pub dwSpeed: u32,\n}\npub const MCI_DGV_SET_SEEK_EXACTLY: i32 = 65536i32;\npub const MCI_DGV_SET_SPEED: i32 = 131072i32;\npub const MCI_DGV_SET_STILL: i32 = 262144i32;\npub const MCI_DGV_SIGNAL_AT: i32 = 65536i32;\npub const MCI_DGV_SIGNAL_CANCEL: i32 = 524288i32;\npub const MCI_DGV_SIGNAL_EVERY: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_SIGNAL_PARMS {\n    pub dwCallback: usize,\n    pub dwPosition: u32,\n    pub dwPeriod: u32,\n    pub dwUserParm: u32,\n}\npub const MCI_DGV_SIGNAL_POSITION: i32 = 1048576i32;\npub const MCI_DGV_SIGNAL_USERVAL: i32 = 262144i32;\npub const MCI_DGV_STATUS_AUDIO: i32 = 16404i32;\npub const MCI_DGV_STATUS_AUDIO_INPUT: i32 = 16384i32;\npub const MCI_DGV_STATUS_AUDIO_RECORD: i32 = 16410i32;\npub const MCI_DGV_STATUS_AUDIO_SOURCE: i32 = 16393i32;\npub const MCI_DGV_STATUS_AUDIO_STREAM: i32 = 16429i32;\npub const MCI_DGV_STATUS_AVGBYTESPERSEC: i32 = 16424i32;\npub const MCI_DGV_STATUS_BASS: i32 = 16399i32;\npub const MCI_DGV_STATUS_BITSPERPEL: i32 = 16427i32;\npub const MCI_DGV_STATUS_BITSPERSAMPLE: i32 = 16426i32;\npub const MCI_DGV_STATUS_BLOCKALIGN: i32 = 16425i32;\npub const MCI_DGV_STATUS_BRIGHTNESS: i32 = 16389i32;\npub const MCI_DGV_STATUS_COLOR: i32 = 16390i32;\npub const MCI_DGV_STATUS_CONTRAST: i32 = 16391i32;\npub const MCI_DGV_STATUS_DISKSPACE: i32 = 2097152i32;\npub const MCI_DGV_STATUS_FILEFORMAT: i32 = 16392i32;\npub const MCI_DGV_STATUS_FILE_COMPLETION: i32 = 16416i32;\npub const MCI_DGV_STATUS_FILE_MODE: i32 = 16415i32;\npub const MCI_DGV_STATUS_FORWARD: i32 = 16428i32;\npub const MCI_DGV_STATUS_FRAME_RATE: i32 = 16398i32;\npub const MCI_DGV_STATUS_GAMMA: i32 = 16394i32;\npub const MCI_DGV_STATUS_HPAL: i32 = 16388i32;\npub const MCI_DGV_STATUS_HWND: i32 = 16385i32;\npub const MCI_DGV_STATUS_INPUT: i32 = 4194304i32;\npub const MCI_DGV_STATUS_KEY_COLOR: i32 = 16421i32;\npub const MCI_DGV_STATUS_KEY_INDEX: i32 = 16420i32;\npub const MCI_DGV_STATUS_LEFT: i32 = 524288i32;\npub const MCI_DGV_STATUS_MONITOR: i32 = 16395i32;\npub const MCI_DGV_STATUS_MONITOR_METHOD: i32 = 16396i32;\npub const MCI_DGV_STATUS_NOMINAL: i32 = 131072i32;\npub const MCI_DGV_STATUS_OUTPUT: i32 = 8388608i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_STATUS_PARMSA {\n    pub dwCallback: usize,\n    pub dwReturn: usize,\n    pub dwItem: u32,\n    pub dwTrack: u32,\n    pub lpstrDrive: windows_sys::core::PSTR,\n    pub dwReference: u32,\n}\nimpl Default for MCI_DGV_STATUS_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_STATUS_PARMSW {\n    pub dwCallback: usize,\n    pub dwReturn: usize,\n    pub dwItem: u32,\n    pub dwTrack: u32,\n    pub lpstrDrive: windows_sys::core::PWSTR,\n    pub dwReference: u32,\n}\nimpl Default for MCI_DGV_STATUS_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_STATUS_PAUSE_MODE: i32 = 16422i32;\npub const MCI_DGV_STATUS_RECORD: i32 = 16777216i32;\npub const MCI_DGV_STATUS_REFERENCE: i32 = 262144i32;\npub const MCI_DGV_STATUS_RIGHT: i32 = 1048576i32;\npub const MCI_DGV_STATUS_SAMPLESPERSEC: i32 = 16423i32;\npub const MCI_DGV_STATUS_SEEK_EXACTLY: i32 = 16401i32;\npub const MCI_DGV_STATUS_SHARPNESS: i32 = 16402i32;\npub const MCI_DGV_STATUS_SIZE: i32 = 16400i32;\npub const MCI_DGV_STATUS_SMPTE: i32 = 16403i32;\npub const MCI_DGV_STATUS_SPEED: i32 = 16387i32;\npub const MCI_DGV_STATUS_STILL_FILEFORMAT: i32 = 16413i32;\npub const MCI_DGV_STATUS_TINT: i32 = 16405i32;\npub const MCI_DGV_STATUS_TREBLE: i32 = 16406i32;\npub const MCI_DGV_STATUS_UNSAVED: i32 = 16407i32;\npub const MCI_DGV_STATUS_VIDEO: i32 = 16408i32;\npub const MCI_DGV_STATUS_VIDEO_RECORD: i32 = 16412i32;\npub const MCI_DGV_STATUS_VIDEO_SOURCE: i32 = 16411i32;\npub const MCI_DGV_STATUS_VIDEO_SRC_NUM: i32 = 16414i32;\npub const MCI_DGV_STATUS_VIDEO_STREAM: i32 = 16430i32;\npub const MCI_DGV_STATUS_VOLUME: i32 = 16409i32;\npub const MCI_DGV_STATUS_WINDOW_MAXIMIZED: i32 = 16419i32;\npub const MCI_DGV_STATUS_WINDOW_MINIMIZED: i32 = 16418i32;\npub const MCI_DGV_STATUS_WINDOW_VISIBLE: i32 = 16417i32;\npub const MCI_DGV_STEP_FRAMES: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_DGV_STEP_PARMS {\n    pub dwCallback: usize,\n    pub dwFrames: u32,\n}\npub const MCI_DGV_STEP_REVERSE: i32 = 65536i32;\npub const MCI_DGV_STOP_HOLD: i32 = 65536i32;\npub const MCI_DGV_UPDATE_HDC: i32 = 131072i32;\npub const MCI_DGV_UPDATE_PAINT: i32 = 262144i32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_UPDATE_PARMS {\n    pub dwCallback: usize,\n    pub rc: super::super::Foundation::RECT,\n    pub hDC: super::super::Graphics::Gdi::HDC,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for MCI_DGV_UPDATE_PARMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_WHERE_DESTINATION: i32 = 262144i32;\npub const MCI_DGV_WHERE_FRAME: i32 = 524288i32;\npub const MCI_DGV_WHERE_MAX: i32 = 4194304i32;\npub const MCI_DGV_WHERE_SOURCE: i32 = 131072i32;\npub const MCI_DGV_WHERE_VIDEO: i32 = 1048576i32;\npub const MCI_DGV_WHERE_WINDOW: i32 = 2097152i32;\npub const MCI_DGV_WINDOW_DEFAULT: i32 = 0i32;\npub const MCI_DGV_WINDOW_HWND: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_WINDOW_PARMSA {\n    pub dwCallback: usize,\n    pub hWnd: super::super::Foundation::HWND,\n    pub nCmdShow: u32,\n    pub lpstrText: windows_sys::core::PSTR,\n}\nimpl Default for MCI_DGV_WINDOW_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_DGV_WINDOW_PARMSW {\n    pub dwCallback: usize,\n    pub hWnd: super::super::Foundation::HWND,\n    pub nCmdShow: u32,\n    pub lpstrText: windows_sys::core::PWSTR,\n}\nimpl Default for MCI_DGV_WINDOW_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_DGV_WINDOW_STATE: i32 = 262144i32;\npub const MCI_DGV_WINDOW_TEXT: i32 = 524288i32;\npub const MCI_END_COMMAND: u32 = 3u32;\npub const MCI_END_COMMAND_LIST: u32 = 6u32;\npub const MCI_END_CONSTANT: u32 = 9u32;\npub const MCI_ESCAPE: u32 = 2053u32;\npub const MCI_FALSE: u32 = 531u32;\npub const MCI_FIRST: u32 = 2048u32;\npub const MCI_FLAG: u32 = 5u32;\npub const MCI_FORMAT_BYTES: u32 = 8u32;\npub const MCI_FORMAT_BYTES_S: u32 = 541u32;\npub const MCI_FORMAT_FRAMES: u32 = 3u32;\npub const MCI_FORMAT_FRAMES_S: u32 = 536u32;\npub const MCI_FORMAT_HMS: u32 = 1u32;\npub const MCI_FORMAT_HMS_S: u32 = 534u32;\npub const MCI_FORMAT_MILLISECONDS: u32 = 0u32;\npub const MCI_FORMAT_MILLISECONDS_S: u32 = 533u32;\npub const MCI_FORMAT_MSF: u32 = 2u32;\npub const MCI_FORMAT_MSF_S: u32 = 535u32;\npub const MCI_FORMAT_SAMPLES: u32 = 9u32;\npub const MCI_FORMAT_SAMPLES_S: u32 = 542u32;\npub const MCI_FORMAT_SMPTE_24: u32 = 4u32;\npub const MCI_FORMAT_SMPTE_24_S: u32 = 537u32;\npub const MCI_FORMAT_SMPTE_25: u32 = 5u32;\npub const MCI_FORMAT_SMPTE_25_S: u32 = 538u32;\npub const MCI_FORMAT_SMPTE_30: u32 = 6u32;\npub const MCI_FORMAT_SMPTE_30DROP: u32 = 7u32;\npub const MCI_FORMAT_SMPTE_30DROP_S: u32 = 540u32;\npub const MCI_FORMAT_SMPTE_30_S: u32 = 539u32;\npub const MCI_FORMAT_TMSF: u32 = 10u32;\npub const MCI_FORMAT_TMSF_S: u32 = 543u32;\npub const MCI_FREEZE: u32 = 2116u32;\npub const MCI_FROM: i32 = 4i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_GENERIC_PARMS {\n    pub dwCallback: usize,\n}\npub const MCI_GETDEVCAPS: u32 = 2059u32;\npub const MCI_GETDEVCAPS_CAN_EJECT: i32 = 7i32;\npub const MCI_GETDEVCAPS_CAN_PLAY: i32 = 8i32;\npub const MCI_GETDEVCAPS_CAN_RECORD: i32 = 1i32;\npub const MCI_GETDEVCAPS_CAN_SAVE: i32 = 9i32;\npub const MCI_GETDEVCAPS_COMPOUND_DEVICE: i32 = 6i32;\npub const MCI_GETDEVCAPS_DEVICE_TYPE: i32 = 4i32;\npub const MCI_GETDEVCAPS_HAS_AUDIO: i32 = 2i32;\npub const MCI_GETDEVCAPS_HAS_VIDEO: i32 = 3i32;\npub const MCI_GETDEVCAPS_ITEM: i32 = 256i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_GETDEVCAPS_PARMS {\n    pub dwCallback: usize,\n    pub dwReturn: u32,\n    pub dwItem: u32,\n}\npub const MCI_GETDEVCAPS_USES_FILES: i32 = 5i32;\npub const MCI_HDC: u32 = 12u32;\npub const MCI_HPAL: u32 = 11u32;\npub const MCI_HWND: u32 = 10u32;\npub const MCI_INFO: u32 = 2058u32;\npub const MCI_INFO_COPYRIGHT: i32 = 8192i32;\npub const MCI_INFO_FILE: i32 = 512i32;\npub const MCI_INFO_MEDIA_IDENTITY: i32 = 2048i32;\npub const MCI_INFO_MEDIA_UPC: i32 = 1024i32;\npub const MCI_INFO_NAME: i32 = 4096i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_INFO_PARMSA {\n    pub dwCallback: usize,\n    pub lpstrReturn: windows_sys::core::PSTR,\n    pub dwRetSize: u32,\n}\nimpl Default for MCI_INFO_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_INFO_PARMSW {\n    pub dwCallback: usize,\n    pub lpstrReturn: windows_sys::core::PWSTR,\n    pub dwRetSize: u32,\n}\nimpl Default for MCI_INFO_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_INFO_PRODUCT: i32 = 256i32;\npub const MCI_INFO_VERSION: i32 = 1024i32;\npub const MCI_INTEGER: u32 = 2u32;\npub const MCI_INTEGER64: u32 = 13u32;\npub const MCI_INTEGER_RETURNED: u32 = 524288u32;\npub const MCI_LAST: u32 = 4095u32;\npub const MCI_LIST: u32 = 2168u32;\npub const MCI_LOAD: u32 = 2128u32;\npub const MCI_LOAD_FILE: i32 = 256i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_LOAD_PARMSA {\n    pub dwCallback: usize,\n    pub lpfilename: windows_sys::core::PCSTR,\n}\nimpl Default for MCI_LOAD_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_LOAD_PARMSW {\n    pub dwCallback: usize,\n    pub lpfilename: windows_sys::core::PCWSTR,\n}\nimpl Default for MCI_LOAD_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_MAX_DEVICE_TYPE_LENGTH: u32 = 80u32;\npub const MCI_MCIAVI_PLAY_FULLBY2: i32 = 67108864i32;\npub const MCI_MCIAVI_PLAY_FULLSCREEN: i32 = 33554432i32;\npub const MCI_MCIAVI_PLAY_WINDOW: i32 = 16777216i32;\npub const MCI_MODE_NOT_READY: u32 = 524u32;\npub const MCI_MODE_OPEN: u32 = 530u32;\npub const MCI_MODE_PAUSE: u32 = 529u32;\npub const MCI_MODE_PLAY: u32 = 526u32;\npub const MCI_MODE_RECORD: u32 = 527u32;\npub const MCI_MODE_SEEK: u32 = 528u32;\npub const MCI_MODE_STOP: u32 = 525u32;\npub const MCI_MONITOR: u32 = 2161u32;\npub const MCI_NOTIFY: i32 = 1i32;\npub const MCI_NOTIFY_ABORTED: u32 = 4u32;\npub const MCI_NOTIFY_FAILURE: u32 = 8u32;\npub const MCI_NOTIFY_SUCCESSFUL: u32 = 1u32;\npub const MCI_NOTIFY_SUPERSEDED: u32 = 2u32;\npub const MCI_OFF: u32 = 0u32;\npub const MCI_OFF_S: i32 = 32769i32;\npub const MCI_ON: u32 = 1u32;\npub const MCI_ON_S: i32 = 32768i32;\npub const MCI_OPEN: u32 = 2051u32;\npub const MCI_OPEN_ALIAS: i32 = 1024i32;\npub const MCI_OPEN_DRIVER: u32 = 2049u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OPEN_DRIVER_PARMS {\n    pub wDeviceID: u32,\n    pub lpstrParams: windows_sys::core::PCWSTR,\n    pub wCustomCommandTable: u32,\n    pub wType: u32,\n}\nimpl Default for MCI_OPEN_DRIVER_PARMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_OPEN_ELEMENT: i32 = 512i32;\npub const MCI_OPEN_ELEMENT_ID: i32 = 2048i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OPEN_PARMSA {\n    pub dwCallback: usize,\n    pub wDeviceID: u32,\n    pub lpstrDeviceType: windows_sys::core::PCSTR,\n    pub lpstrElementName: windows_sys::core::PCSTR,\n    pub lpstrAlias: windows_sys::core::PCSTR,\n}\nimpl Default for MCI_OPEN_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OPEN_PARMSW {\n    pub dwCallback: usize,\n    pub wDeviceID: u32,\n    pub lpstrDeviceType: windows_sys::core::PCWSTR,\n    pub lpstrElementName: windows_sys::core::PCWSTR,\n    pub lpstrAlias: windows_sys::core::PCWSTR,\n}\nimpl Default for MCI_OPEN_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_OPEN_SHAREABLE: i32 = 256i32;\npub const MCI_OPEN_TYPE: i32 = 8192i32;\npub const MCI_OPEN_TYPE_ID: i32 = 4096i32;\npub const MCI_OVLY_GETDEVCAPS_CAN_FREEZE: i32 = 16386i32;\npub const MCI_OVLY_GETDEVCAPS_CAN_STRETCH: i32 = 16385i32;\npub const MCI_OVLY_GETDEVCAPS_MAX_WINDOWS: i32 = 16387i32;\npub const MCI_OVLY_INFO_TEXT: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OVLY_LOAD_PARMSA {\n    pub dwCallback: usize,\n    pub lpfilename: windows_sys::core::PCSTR,\n    pub rc: super::super::Foundation::RECT,\n}\nimpl Default for MCI_OVLY_LOAD_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OVLY_LOAD_PARMSW {\n    pub dwCallback: usize,\n    pub lpfilename: windows_sys::core::PCWSTR,\n    pub rc: super::super::Foundation::RECT,\n}\nimpl Default for MCI_OVLY_LOAD_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_OVLY_OPEN_PARENT: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OVLY_OPEN_PARMSA {\n    pub dwCallback: usize,\n    pub wDeviceID: u32,\n    pub lpstrDeviceType: windows_sys::core::PCSTR,\n    pub lpstrElementName: windows_sys::core::PCSTR,\n    pub lpstrAlias: windows_sys::core::PCSTR,\n    pub dwStyle: u32,\n    pub hWndParent: super::super::Foundation::HWND,\n}\nimpl Default for MCI_OVLY_OPEN_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OVLY_OPEN_PARMSW {\n    pub dwCallback: usize,\n    pub wDeviceID: u32,\n    pub lpstrDeviceType: windows_sys::core::PCWSTR,\n    pub lpstrElementName: windows_sys::core::PCWSTR,\n    pub lpstrAlias: windows_sys::core::PCWSTR,\n    pub dwStyle: u32,\n    pub hWndParent: super::super::Foundation::HWND,\n}\nimpl Default for MCI_OVLY_OPEN_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_OVLY_OPEN_WS: i32 = 65536i32;\npub const MCI_OVLY_PUT_DESTINATION: i32 = 262144i32;\npub const MCI_OVLY_PUT_FRAME: i32 = 524288i32;\npub const MCI_OVLY_PUT_SOURCE: i32 = 131072i32;\npub const MCI_OVLY_PUT_VIDEO: i32 = 1048576i32;\npub const MCI_OVLY_RECT: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_OVLY_RECT_PARMS {\n    pub dwCallback: usize,\n    pub rc: super::super::Foundation::RECT,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OVLY_SAVE_PARMSA {\n    pub dwCallback: usize,\n    pub lpfilename: windows_sys::core::PCSTR,\n    pub rc: super::super::Foundation::RECT,\n}\nimpl Default for MCI_OVLY_SAVE_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OVLY_SAVE_PARMSW {\n    pub dwCallback: usize,\n    pub lpfilename: windows_sys::core::PCWSTR,\n    pub rc: super::super::Foundation::RECT,\n}\nimpl Default for MCI_OVLY_SAVE_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_OVLY_STATUS_HWND: i32 = 16385i32;\npub const MCI_OVLY_STATUS_STRETCH: i32 = 16386i32;\npub const MCI_OVLY_WHERE_DESTINATION: i32 = 262144i32;\npub const MCI_OVLY_WHERE_FRAME: i32 = 524288i32;\npub const MCI_OVLY_WHERE_SOURCE: i32 = 131072i32;\npub const MCI_OVLY_WHERE_VIDEO: i32 = 1048576i32;\npub const MCI_OVLY_WINDOW_DEFAULT: i32 = 0i32;\npub const MCI_OVLY_WINDOW_DISABLE_STRETCH: i32 = 2097152i32;\npub const MCI_OVLY_WINDOW_ENABLE_STRETCH: i32 = 1048576i32;\npub const MCI_OVLY_WINDOW_HWND: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OVLY_WINDOW_PARMSA {\n    pub dwCallback: usize,\n    pub hWnd: super::super::Foundation::HWND,\n    pub nCmdShow: u32,\n    pub lpstrText: windows_sys::core::PCSTR,\n}\nimpl Default for MCI_OVLY_WINDOW_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_OVLY_WINDOW_PARMSW {\n    pub dwCallback: usize,\n    pub hWnd: super::super::Foundation::HWND,\n    pub nCmdShow: u32,\n    pub lpstrText: windows_sys::core::PCWSTR,\n}\nimpl Default for MCI_OVLY_WINDOW_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_OVLY_WINDOW_STATE: i32 = 262144i32;\npub const MCI_OVLY_WINDOW_TEXT: i32 = 524288i32;\npub const MCI_PASTE: u32 = 2131u32;\npub const MCI_PAUSE: u32 = 2057u32;\npub const MCI_PLAY: u32 = 2054u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_PLAY_PARMS {\n    pub dwCallback: usize,\n    pub dwFrom: u32,\n    pub dwTo: u32,\n}\npub const MCI_PUT: u32 = 2114u32;\npub const MCI_QUALITY: u32 = 2167u32;\npub const MCI_QUALITY_ALG: i32 = 262144i32;\npub const MCI_QUALITY_DIALOG: i32 = 524288i32;\npub const MCI_QUALITY_HANDLE: i32 = 1048576i32;\npub const MCI_QUALITY_ITEM: i32 = 65536i32;\npub const MCI_QUALITY_ITEM_AUDIO: i32 = 16384i32;\npub const MCI_QUALITY_ITEM_STILL: i32 = 16385i32;\npub const MCI_QUALITY_ITEM_VIDEO: i32 = 16386i32;\npub const MCI_QUALITY_NAME: i32 = 131072i32;\npub const MCI_REALIZE: u32 = 2112u32;\npub const MCI_RECORD: u32 = 2063u32;\npub const MCI_RECORD_INSERT: i32 = 256i32;\npub const MCI_RECORD_OVERWRITE: i32 = 512i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_RECORD_PARMS {\n    pub dwCallback: usize,\n    pub dwFrom: u32,\n    pub dwTo: u32,\n}\npub const MCI_RECT: u32 = 7u32;\npub const MCI_RESERVE: u32 = 2162u32;\npub const MCI_RESOURCE_DRIVER: u32 = 1048576u32;\npub const MCI_RESOURCE_RETURNED: u32 = 65536u32;\npub const MCI_RESTORE: u32 = 2171u32;\npub const MCI_RESUME: u32 = 2133u32;\npub const MCI_RETURN: u32 = 4u32;\npub const MCI_SAVE: u32 = 2067u32;\npub const MCI_SAVE_FILE: i32 = 256i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_SAVE_PARMSA {\n    pub dwCallback: usize,\n    pub lpfilename: windows_sys::core::PCSTR,\n}\nimpl Default for MCI_SAVE_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_SAVE_PARMSW {\n    pub dwCallback: usize,\n    pub lpfilename: windows_sys::core::PCWSTR,\n}\nimpl Default for MCI_SAVE_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_SECTION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MCI32\");\npub const MCI_SEEK: u32 = 2055u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_SEEK_PARMS {\n    pub dwCallback: usize,\n    pub dwTo: u32,\n}\npub const MCI_SEEK_TO_END: i32 = 512i32;\npub const MCI_SEEK_TO_START: i32 = 256i32;\npub const MCI_SEQ_FILE: u32 = 16386u32;\npub const MCI_SEQ_FILE_S: u32 = 1222u32;\npub const MCI_SEQ_FORMAT_SONGPTR: u32 = 16385u32;\npub const MCI_SEQ_FORMAT_SONGPTR_S: u32 = 1225u32;\npub const MCI_SEQ_MAPPER: u32 = 65535u32;\npub const MCI_SEQ_MAPPER_S: u32 = 1221u32;\npub const MCI_SEQ_MIDI: u32 = 16387u32;\npub const MCI_SEQ_MIDI_S: u32 = 1223u32;\npub const MCI_SEQ_NONE: u32 = 65533u32;\npub const MCI_SEQ_NONE_S: u32 = 1226u32;\npub const MCI_SEQ_SET_MASTER: i32 = 524288i32;\npub const MCI_SEQ_SET_OFFSET: i32 = 16777216i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_SEQ_SET_PARMS {\n    pub dwCallback: usize,\n    pub dwTimeFormat: u32,\n    pub dwAudio: u32,\n    pub dwTempo: u32,\n    pub dwPort: u32,\n    pub dwSlave: u32,\n    pub dwMaster: u32,\n    pub dwOffset: u32,\n}\npub const MCI_SEQ_SET_PORT: i32 = 131072i32;\npub const MCI_SEQ_SET_SLAVE: i32 = 262144i32;\npub const MCI_SEQ_SET_TEMPO: i32 = 65536i32;\npub const MCI_SEQ_SMPTE: u32 = 16388u32;\npub const MCI_SEQ_SMPTE_S: u32 = 1224u32;\npub const MCI_SEQ_STATUS_COPYRIGHT: i32 = 16396i32;\npub const MCI_SEQ_STATUS_DIVTYPE: i32 = 16394i32;\npub const MCI_SEQ_STATUS_MASTER: i32 = 16392i32;\npub const MCI_SEQ_STATUS_NAME: i32 = 16395i32;\npub const MCI_SEQ_STATUS_OFFSET: i32 = 16393i32;\npub const MCI_SEQ_STATUS_PORT: i32 = 16387i32;\npub const MCI_SEQ_STATUS_SLAVE: i32 = 16391i32;\npub const MCI_SEQ_STATUS_TEMPO: i32 = 16386i32;\npub const MCI_SET: u32 = 2061u32;\npub const MCI_SETAUDIO: u32 = 2163u32;\npub const MCI_SETVIDEO: u32 = 2166u32;\npub const MCI_SET_AUDIO: i32 = 2048i32;\npub const MCI_SET_AUDIO_ALL: i32 = 0i32;\npub const MCI_SET_AUDIO_LEFT: i32 = 1i32;\npub const MCI_SET_AUDIO_RIGHT: i32 = 2i32;\npub const MCI_SET_DOOR_CLOSED: i32 = 512i32;\npub const MCI_SET_DOOR_OPEN: i32 = 256i32;\npub const MCI_SET_OFF: i32 = 16384i32;\npub const MCI_SET_ON: i32 = 8192i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_SET_PARMS {\n    pub dwCallback: usize,\n    pub dwTimeFormat: u32,\n    pub dwAudio: u32,\n}\npub const MCI_SET_TIME_FORMAT: i32 = 1024i32;\npub const MCI_SET_VIDEO: i32 = 4096i32;\npub const MCI_SIGNAL: u32 = 2165u32;\npub const MCI_SPIN: u32 = 2060u32;\npub const MCI_STATUS: u32 = 2068u32;\npub const MCI_STATUS_CURRENT_TRACK: i32 = 8i32;\npub const MCI_STATUS_ITEM: i32 = 256i32;\npub const MCI_STATUS_LENGTH: i32 = 1i32;\npub const MCI_STATUS_MEDIA_PRESENT: i32 = 5i32;\npub const MCI_STATUS_MODE: i32 = 4i32;\npub const MCI_STATUS_NUMBER_OF_TRACKS: i32 = 3i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_STATUS_PARMS {\n    pub dwCallback: usize,\n    pub dwReturn: usize,\n    pub dwItem: u32,\n    pub dwTrack: u32,\n}\npub const MCI_STATUS_POSITION: i32 = 2i32;\npub const MCI_STATUS_READY: i32 = 7i32;\npub const MCI_STATUS_START: i32 = 512i32;\npub const MCI_STATUS_TIME_FORMAT: i32 = 6i32;\npub const MCI_STEP: u32 = 2062u32;\npub const MCI_STOP: u32 = 2056u32;\npub const MCI_STRING: u32 = 1u32;\npub const MCI_SYSINFO: u32 = 2064u32;\npub const MCI_SYSINFO_INSTALLNAME: i32 = 2048i32;\npub const MCI_SYSINFO_NAME: i32 = 1024i32;\npub const MCI_SYSINFO_OPEN: i32 = 512i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_SYSINFO_PARMSA {\n    pub dwCallback: usize,\n    pub lpstrReturn: windows_sys::core::PSTR,\n    pub dwRetSize: u32,\n    pub dwNumber: u32,\n    pub wDeviceType: u32,\n}\nimpl Default for MCI_SYSINFO_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_SYSINFO_PARMSW {\n    pub dwCallback: usize,\n    pub lpstrReturn: windows_sys::core::PWSTR,\n    pub dwRetSize: u32,\n    pub dwNumber: u32,\n    pub wDeviceType: u32,\n}\nimpl Default for MCI_SYSINFO_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_SYSINFO_QUANTITY: i32 = 256i32;\npub const MCI_TEST: i32 = 32i32;\npub const MCI_TO: i32 = 8i32;\npub const MCI_TRACK: i32 = 16i32;\npub const MCI_TRUE: u32 = 532u32;\npub const MCI_UNDO: u32 = 2169u32;\npub const MCI_UNFREEZE: u32 = 2117u32;\npub const MCI_UPDATE: u32 = 2132u32;\npub const MCI_USER_MESSAGES: u32 = 3072u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_VD_ESCAPE_PARMSA {\n    pub dwCallback: usize,\n    pub lpstrCommand: windows_sys::core::PCSTR,\n}\nimpl Default for MCI_VD_ESCAPE_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_VD_ESCAPE_PARMSW {\n    pub dwCallback: usize,\n    pub lpstrCommand: windows_sys::core::PCWSTR,\n}\nimpl Default for MCI_VD_ESCAPE_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_VD_ESCAPE_STRING: i32 = 256i32;\npub const MCI_VD_FORMAT_TRACK: u32 = 16385u32;\npub const MCI_VD_FORMAT_TRACK_S: u32 = 1029u32;\npub const MCI_VD_GETDEVCAPS_CAN_REVERSE: i32 = 16386i32;\npub const MCI_VD_GETDEVCAPS_CAV: i32 = 131072i32;\npub const MCI_VD_GETDEVCAPS_CLV: i32 = 65536i32;\npub const MCI_VD_GETDEVCAPS_FAST_RATE: i32 = 16387i32;\npub const MCI_VD_GETDEVCAPS_NORMAL_RATE: i32 = 16389i32;\npub const MCI_VD_GETDEVCAPS_SLOW_RATE: i32 = 16388i32;\npub const MCI_VD_MEDIA_CAV: u32 = 1027u32;\npub const MCI_VD_MEDIA_CLV: u32 = 1026u32;\npub const MCI_VD_MEDIA_OTHER: u32 = 1028u32;\npub const MCI_VD_MODE_PARK: u32 = 1025u32;\npub const MCI_VD_PLAY_FAST: i32 = 131072i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_VD_PLAY_PARMS {\n    pub dwCallback: usize,\n    pub dwFrom: u32,\n    pub dwTo: u32,\n    pub dwSpeed: u32,\n}\npub const MCI_VD_PLAY_REVERSE: i32 = 65536i32;\npub const MCI_VD_PLAY_SCAN: i32 = 524288i32;\npub const MCI_VD_PLAY_SLOW: i32 = 1048576i32;\npub const MCI_VD_PLAY_SPEED: i32 = 262144i32;\npub const MCI_VD_SEEK_REVERSE: i32 = 65536i32;\npub const MCI_VD_SPIN_DOWN: i32 = 131072i32;\npub const MCI_VD_SPIN_UP: i32 = 65536i32;\npub const MCI_VD_STATUS_DISC_SIZE: i32 = 16390i32;\npub const MCI_VD_STATUS_FORWARD: i32 = 16387i32;\npub const MCI_VD_STATUS_MEDIA_TYPE: i32 = 16388i32;\npub const MCI_VD_STATUS_SIDE: i32 = 16389i32;\npub const MCI_VD_STATUS_SPEED: i32 = 16386i32;\npub const MCI_VD_STEP_FRAMES: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_VD_STEP_PARMS {\n    pub dwCallback: usize,\n    pub dwFrames: u32,\n}\npub const MCI_VD_STEP_REVERSE: i32 = 131072i32;\npub const MCI_WAIT: i32 = 2i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_WAVE_DELETE_PARMS {\n    pub dwCallback: usize,\n    pub dwFrom: u32,\n    pub dwTo: u32,\n}\npub const MCI_WAVE_GETDEVCAPS_INPUTS: i32 = 16385i32;\npub const MCI_WAVE_GETDEVCAPS_OUTPUTS: i32 = 16386i32;\npub const MCI_WAVE_INPUT: i32 = 4194304i32;\npub const MCI_WAVE_MAPPER: u32 = 1153u32;\npub const MCI_WAVE_OPEN_BUFFER: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_WAVE_OPEN_PARMSA {\n    pub dwCallback: usize,\n    pub wDeviceID: u32,\n    pub lpstrDeviceType: windows_sys::core::PCSTR,\n    pub lpstrElementName: windows_sys::core::PCSTR,\n    pub lpstrAlias: windows_sys::core::PCSTR,\n    pub dwBufferSeconds: u32,\n}\nimpl Default for MCI_WAVE_OPEN_PARMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MCI_WAVE_OPEN_PARMSW {\n    pub dwCallback: usize,\n    pub wDeviceID: u32,\n    pub lpstrDeviceType: windows_sys::core::PCWSTR,\n    pub lpstrElementName: windows_sys::core::PCWSTR,\n    pub lpstrAlias: windows_sys::core::PCWSTR,\n    pub dwBufferSeconds: u32,\n}\nimpl Default for MCI_WAVE_OPEN_PARMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MCI_WAVE_OUTPUT: i32 = 8388608i32;\npub const MCI_WAVE_PCM: u32 = 1152u32;\npub const MCI_WAVE_SET_ANYINPUT: i32 = 67108864i32;\npub const MCI_WAVE_SET_ANYOUTPUT: i32 = 134217728i32;\npub const MCI_WAVE_SET_AVGBYTESPERSEC: i32 = 524288i32;\npub const MCI_WAVE_SET_BITSPERSAMPLE: i32 = 2097152i32;\npub const MCI_WAVE_SET_BLOCKALIGN: i32 = 1048576i32;\npub const MCI_WAVE_SET_CHANNELS: i32 = 131072i32;\npub const MCI_WAVE_SET_FORMATTAG: i32 = 65536i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MCI_WAVE_SET_PARMS {\n    pub dwCallback: usize,\n    pub dwTimeFormat: u32,\n    pub dwAudio: u32,\n    pub wInput: u32,\n    pub wOutput: u32,\n    pub wFormatTag: u16,\n    pub wReserved2: u16,\n    pub nChannels: u16,\n    pub wReserved3: u16,\n    pub nSamplesPerSec: u32,\n    pub nAvgBytesPerSec: u32,\n    pub nBlockAlign: u16,\n    pub wReserved4: u16,\n    pub wBitsPerSample: u16,\n    pub wReserved5: u16,\n}\npub const MCI_WAVE_SET_SAMPLESPERSEC: i32 = 262144i32;\npub const MCI_WAVE_STATUS_AVGBYTESPERSEC: i32 = 16388i32;\npub const MCI_WAVE_STATUS_BITSPERSAMPLE: i32 = 16390i32;\npub const MCI_WAVE_STATUS_BLOCKALIGN: i32 = 16389i32;\npub const MCI_WAVE_STATUS_CHANNELS: i32 = 16386i32;\npub const MCI_WAVE_STATUS_FORMATTAG: i32 = 16385i32;\npub const MCI_WAVE_STATUS_LEVEL: i32 = 16391i32;\npub const MCI_WAVE_STATUS_SAMPLESPERSEC: i32 = 16387i32;\npub const MCI_WHERE: u32 = 2115u32;\npub const MCI_WINDOW: u32 = 2113u32;\npub const MCMADM_E_REGKEY_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D006A_u32 as _;\npub const MCMADM_I_NO_EVENTS: windows_sys::core::HRESULT = 0x400D0069_u32 as _;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct MEDIASPACEADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wRevision: u16,\n}\npub const MIDIMAPPER_S: u32 = 1227u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MIDIOPENSTRMID {\n    pub dwStreamID: u32,\n    pub uDeviceID: u32,\n}\npub const MIDI_IO_COOKED: i32 = 2i32;\npub const MIDI_IO_PACKED: i32 = 0i32;\npub const MIDM_ADDBUFFER: u32 = 59u32;\npub const MIDM_CLOSE: u32 = 56u32;\npub const MIDM_GETDEVCAPS: u32 = 54u32;\npub const MIDM_GETNUMDEVS: u32 = 53u32;\npub const MIDM_INIT: u32 = 100u32;\npub const MIDM_INIT_EX: u32 = 104u32;\npub const MIDM_MAPPER: u32 = 8192u32;\npub const MIDM_OPEN: u32 = 55u32;\npub const MIDM_PREPARE: u32 = 57u32;\npub const MIDM_RESET: u32 = 62u32;\npub const MIDM_START: u32 = 60u32;\npub const MIDM_STOP: u32 = 61u32;\npub const MIDM_UNPREPARE: u32 = 58u32;\npub const MIDM_USER: u32 = 16384u32;\npub const MIXERCONTROL_CONTROLTYPE_SRS_MTS: u32 = 536936454u32;\npub const MIXERCONTROL_CONTROLTYPE_SRS_ONOFF: u32 = 536936455u32;\npub const MIXERCONTROL_CONTROLTYPE_SRS_SYNTHSELECT: u32 = 536936456u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy)]\npub struct MIXEROPENDESC {\n    pub hmx: super::Audio::HMIXER,\n    pub pReserved0: *mut core::ffi::c_void,\n    pub dwCallback: usize,\n    pub dwInstance: usize,\n    pub dnDevNode: usize,\n}\n#[cfg(feature = \"Win32_Media_Audio\")]\nimpl Default for MIXEROPENDESC {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct MMCKINFO {\n    pub ckid: u32,\n    pub cksize: u32,\n    pub fccType: u32,\n    pub dwDataOffset: u32,\n    pub dwFlags: u32,\n}\npub const MMIOERR_ACCESSDENIED: u32 = 268u32;\npub const MMIOERR_BASE: u32 = 256u32;\npub const MMIOERR_CANNOTCLOSE: u32 = 260u32;\npub const MMIOERR_CANNOTEXPAND: u32 = 264u32;\npub const MMIOERR_CANNOTOPEN: u32 = 259u32;\npub const MMIOERR_CANNOTREAD: u32 = 261u32;\npub const MMIOERR_CANNOTSEEK: u32 = 263u32;\npub const MMIOERR_CANNOTWRITE: u32 = 262u32;\npub const MMIOERR_CHUNKNOTFOUND: u32 = 265u32;\npub const MMIOERR_FILENOTFOUND: u32 = 257u32;\npub const MMIOERR_INVALIDFILE: u32 = 272u32;\npub const MMIOERR_NETWORKERROR: u32 = 270u32;\npub const MMIOERR_OUTOFMEMORY: u32 = 258u32;\npub const MMIOERR_PATHNOTFOUND: u32 = 267u32;\npub const MMIOERR_SHARINGVIOLATION: u32 = 269u32;\npub const MMIOERR_TOOMANYOPENFILES: u32 = 271u32;\npub const MMIOERR_UNBUFFERED: u32 = 266u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MMIOINFO {\n    pub dwFlags: u32,\n    pub fccIOProc: u32,\n    pub pIOProc: LPMMIOPROC,\n    pub wErrorRet: u32,\n    pub htask: super::HTASK,\n    pub cchBuffer: i32,\n    pub pchBuffer: *mut i8,\n    pub pchNext: *mut i8,\n    pub pchEndRead: *mut i8,\n    pub pchEndWrite: *mut i8,\n    pub lBufOffset: i32,\n    pub lDiskOffset: i32,\n    pub adwInfo: [u32; 3],\n    pub dwReserved1: u32,\n    pub dwReserved2: u32,\n    pub hmmio: HMMIO,\n}\nimpl Default for MMIOINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MMIOM_CLOSE: u32 = 4u32;\npub const MMIOM_OPEN: u32 = 3u32;\npub const MMIOM_READ: u32 = 0u32;\npub const MMIOM_RENAME: u32 = 6u32;\npub const MMIOM_SEEK: u32 = 2u32;\npub const MMIOM_USER: u32 = 32768u32;\npub const MMIOM_WRITE: u32 = 1u32;\npub const MMIOM_WRITEFLUSH: u32 = 5u32;\npub const MMIO_ALLOCBUF: u32 = 65536u32;\npub const MMIO_COMPAT: u32 = 0u32;\npub const MMIO_CREATE: u32 = 4096u32;\npub const MMIO_CREATELIST: u32 = 64u32;\npub const MMIO_CREATERIFF: u32 = 32u32;\npub const MMIO_DEFAULTBUFFER: u32 = 8192u32;\npub const MMIO_DELETE: u32 = 512u32;\npub const MMIO_DENYNONE: u32 = 64u32;\npub const MMIO_DENYREAD: u32 = 48u32;\npub const MMIO_DENYWRITE: u32 = 32u32;\npub const MMIO_DIRTY: u32 = 268435456u32;\npub const MMIO_EMPTYBUF: u32 = 16u32;\npub const MMIO_EXCLUSIVE: u32 = 16u32;\npub const MMIO_EXIST: u32 = 16384u32;\npub const MMIO_FHOPEN: u32 = 16u32;\npub const MMIO_FINDCHUNK: u32 = 16u32;\npub const MMIO_FINDLIST: u32 = 64u32;\npub const MMIO_FINDPROC: u32 = 262144u32;\npub const MMIO_FINDRIFF: u32 = 32u32;\npub const MMIO_GETTEMP: u32 = 131072u32;\npub const MMIO_GLOBALPROC: u32 = 268435456u32;\npub const MMIO_INSTALLPROC: u32 = 65536u32;\npub const MMIO_PARSE: u32 = 256u32;\npub const MMIO_READ: u32 = 0u32;\npub const MMIO_READWRITE: u32 = 2u32;\npub const MMIO_REMOVEPROC: u32 = 131072u32;\npub const MMIO_RWMODE: u32 = 3u32;\npub const MMIO_SHAREMODE: u32 = 112u32;\npub const MMIO_TOUPPER: u32 = 16u32;\npub const MMIO_UNICODEPROC: u32 = 16777216u32;\npub const MMIO_WRITE: u32 = 1u32;\npub const MM_3COM: u32 = 260u32;\npub const MM_3COM_CB_MIXER: u32 = 1u32;\npub const MM_3COM_CB_WAVEIN: u32 = 2u32;\npub const MM_3COM_CB_WAVEOUT: u32 = 3u32;\npub const MM_3DFX: u32 = 262u32;\npub const MM_AARDVARK: u32 = 11u32;\npub const MM_AARDVARK_STUDIO12_WAVEIN: u32 = 2u32;\npub const MM_AARDVARK_STUDIO12_WAVEOUT: u32 = 1u32;\npub const MM_AARDVARK_STUDIO88_WAVEIN: u32 = 4u32;\npub const MM_AARDVARK_STUDIO88_WAVEOUT: u32 = 3u32;\npub const MM_ACTIVEVOICE: u32 = 225u32;\npub const MM_ACTIVEVOICE_ACM_VOXADPCM: u32 = 1u32;\npub const MM_ACULAB: u32 = 14u32;\npub const MM_ADDX: u32 = 118u32;\npub const MM_ADDX_PCTV_AUX_CD: u32 = 5u32;\npub const MM_ADDX_PCTV_AUX_LINE: u32 = 6u32;\npub const MM_ADDX_PCTV_DIGITALMIX: u32 = 1u32;\npub const MM_ADDX_PCTV_MIXER: u32 = 4u32;\npub const MM_ADDX_PCTV_WAVEIN: u32 = 2u32;\npub const MM_ADDX_PCTV_WAVEOUT: u32 = 3u32;\npub const MM_ADLACC: u32 = 91u32;\npub const MM_ADMOS: u32 = 235u32;\npub const MM_ADMOS_FM_SYNTH: u32 = 1u32;\npub const MM_ADMOS_QS3AMIDIIN: u32 = 3u32;\npub const MM_ADMOS_QS3AMIDIOUT: u32 = 2u32;\npub const MM_ADMOS_QS3AWAVEIN: u32 = 5u32;\npub const MM_ADMOS_QS3AWAVEOUT: u32 = 4u32;\npub const MM_AHEAD: u32 = 77u32;\npub const MM_AHEAD_GENERIC: u32 = 4u32;\npub const MM_AHEAD_MULTISOUND: u32 = 1u32;\npub const MM_AHEAD_PROAUDIO: u32 = 3u32;\npub const MM_AHEAD_SOUNDBLASTER: u32 = 2u32;\npub const MM_ALARIS: u32 = 174u32;\npub const MM_ALDIGITAL: u32 = 143u32;\npub const MM_ALESIS: u32 = 243u32;\npub const MM_ALGOVISION: u32 = 266u32;\npub const MM_ALGOVISION_VB80AUX: u32 = 4u32;\npub const MM_ALGOVISION_VB80AUX2: u32 = 5u32;\npub const MM_ALGOVISION_VB80MIXER: u32 = 3u32;\npub const MM_ALGOVISION_VB80WAVEIN: u32 = 2u32;\npub const MM_ALGOVISION_VB80WAVEOUT: u32 = 1u32;\npub const MM_AMD: u32 = 146u32;\npub const MM_AMD_INTERWAVE_AUX1: u32 = 10u32;\npub const MM_AMD_INTERWAVE_AUX2: u32 = 11u32;\npub const MM_AMD_INTERWAVE_AUX_CD: u32 = 13u32;\npub const MM_AMD_INTERWAVE_AUX_MIC: u32 = 12u32;\npub const MM_AMD_INTERWAVE_EX_CD: u32 = 7u32;\npub const MM_AMD_INTERWAVE_EX_TELEPHONY: u32 = 16u32;\npub const MM_AMD_INTERWAVE_JOYSTICK: u32 = 6u32;\npub const MM_AMD_INTERWAVE_MIDIIN: u32 = 8u32;\npub const MM_AMD_INTERWAVE_MIDIOUT: u32 = 9u32;\npub const MM_AMD_INTERWAVE_MIXER1: u32 = 4u32;\npub const MM_AMD_INTERWAVE_MIXER2: u32 = 5u32;\npub const MM_AMD_INTERWAVE_MONO_IN: u32 = 14u32;\npub const MM_AMD_INTERWAVE_MONO_OUT: u32 = 15u32;\npub const MM_AMD_INTERWAVE_STEREO_ENHANCED: u32 = 19u32;\npub const MM_AMD_INTERWAVE_SYNTH: u32 = 3u32;\npub const MM_AMD_INTERWAVE_WAVEIN: u32 = 1u32;\npub const MM_AMD_INTERWAVE_WAVEOUT: u32 = 2u32;\npub const MM_AMD_INTERWAVE_WAVEOUT_BASE: u32 = 17u32;\npub const MM_AMD_INTERWAVE_WAVEOUT_TREBLE: u32 = 18u32;\npub const MM_ANALOGDEVICES: u32 = 252u32;\npub const MM_ANTEX: u32 = 31u32;\npub const MM_ANTEX_AUDIOPORT22_FEEDTHRU: u32 = 9u32;\npub const MM_ANTEX_AUDIOPORT22_WAVEIN: u32 = 7u32;\npub const MM_ANTEX_AUDIOPORT22_WAVEOUT: u32 = 8u32;\npub const MM_ANTEX_SX12_WAVEIN: u32 = 1u32;\npub const MM_ANTEX_SX12_WAVEOUT: u32 = 2u32;\npub const MM_ANTEX_SX15_WAVEIN: u32 = 3u32;\npub const MM_ANTEX_SX15_WAVEOUT: u32 = 4u32;\npub const MM_ANTEX_VP625_WAVEIN: u32 = 5u32;\npub const MM_ANTEX_VP625_WAVEOUT: u32 = 6u32;\npub const MM_APICOM: u32 = 116u32;\npub const MM_APPLE: u32 = 99u32;\npub const MM_APPS: u32 = 42u32;\npub const MM_APT: u32 = 56u32;\npub const MM_APT_ACE100CD: u32 = 1u32;\npub const MM_ARRAY: u32 = 231u32;\npub const MM_ARTISOFT: u32 = 20u32;\npub const MM_ARTISOFT_SBWAVEIN: u32 = 1u32;\npub const MM_ARTISOFT_SBWAVEOUT: u32 = 2u32;\npub const MM_AST: u32 = 64u32;\npub const MM_AST_MODEMWAVE_WAVEIN: u32 = 13u32;\npub const MM_AST_MODEMWAVE_WAVEOUT: u32 = 14u32;\npub const MM_ATI: u32 = 27u32;\npub const MM_ATT: u32 = 185u32;\npub const MM_ATT_G729A: u32 = 1u32;\npub const MM_ATT_MICROELECTRONICS: u32 = 139u32;\npub const MM_AU8820_AUX: u32 = 21u32;\npub const MM_AU8820_MIDIIN: u32 = 23u32;\npub const MM_AU8820_MIDIOUT: u32 = 22u32;\npub const MM_AU8820_MIXER: u32 = 20u32;\npub const MM_AU8820_SYNTH: u32 = 17u32;\npub const MM_AU8820_WAVEIN: u32 = 19u32;\npub const MM_AU8820_WAVEOUT: u32 = 18u32;\npub const MM_AU8830_AUX: u32 = 37u32;\npub const MM_AU8830_MIDIIN: u32 = 39u32;\npub const MM_AU8830_MIDIOUT: u32 = 38u32;\npub const MM_AU8830_MIXER: u32 = 36u32;\npub const MM_AU8830_SYNTH: u32 = 33u32;\npub const MM_AU8830_WAVEIN: u32 = 35u32;\npub const MM_AU8830_WAVEOUT: u32 = 34u32;\npub const MM_AUDIOFILE: u32 = 47u32;\npub const MM_AUDIOPT: u32 = 74u32;\npub const MM_AUDIOSCIENCE: u32 = 217u32;\npub const MM_AURAVISION: u32 = 80u32;\npub const MM_AUREAL: u32 = 181u32;\npub const MM_AUREAL_AU8820: u32 = 16u32;\npub const MM_AUREAL_AU8830: u32 = 32u32;\npub const MM_AZTECH: u32 = 52u32;\npub const MM_AZTECH_AUX: u32 = 404u32;\npub const MM_AZTECH_AUX_CD: u32 = 401u32;\npub const MM_AZTECH_AUX_LINE: u32 = 402u32;\npub const MM_AZTECH_AUX_MIC: u32 = 403u32;\npub const MM_AZTECH_DSP16_FMSYNTH: u32 = 68u32;\npub const MM_AZTECH_DSP16_WAVEIN: u32 = 65u32;\npub const MM_AZTECH_DSP16_WAVEOUT: u32 = 66u32;\npub const MM_AZTECH_DSP16_WAVESYNTH: u32 = 70u32;\npub const MM_AZTECH_FMSYNTH: u32 = 20u32;\npub const MM_AZTECH_MIDIIN: u32 = 4u32;\npub const MM_AZTECH_MIDIOUT: u32 = 3u32;\npub const MM_AZTECH_MIXER: u32 = 21u32;\npub const MM_AZTECH_NOVA16_MIXER: u32 = 73u32;\npub const MM_AZTECH_NOVA16_WAVEIN: u32 = 71u32;\npub const MM_AZTECH_NOVA16_WAVEOUT: u32 = 72u32;\npub const MM_AZTECH_PRO16_FMSYNTH: u32 = 38u32;\npub const MM_AZTECH_PRO16_WAVEIN: u32 = 33u32;\npub const MM_AZTECH_PRO16_WAVEOUT: u32 = 34u32;\npub const MM_AZTECH_WASH16_MIXER: u32 = 76u32;\npub const MM_AZTECH_WASH16_WAVEIN: u32 = 74u32;\npub const MM_AZTECH_WASH16_WAVEOUT: u32 = 75u32;\npub const MM_AZTECH_WAVEIN: u32 = 17u32;\npub const MM_AZTECH_WAVEOUT: u32 = 18u32;\npub const MM_BCB: u32 = 192u32;\npub const MM_BCB_NETBOARD_10: u32 = 1u32;\npub const MM_BCB_TT75_10: u32 = 2u32;\npub const MM_BECUBED: u32 = 10u32;\npub const MM_BERCOS: u32 = 199u32;\npub const MM_BERCOS_MIXER: u32 = 2u32;\npub const MM_BERCOS_WAVEIN: u32 = 1u32;\npub const MM_BERCOS_WAVEOUT: u32 = 3u32;\npub const MM_BERKOM: u32 = 189u32;\npub const MM_BINTEC: u32 = 12u32;\npub const MM_BINTEC_TAPI_WAVE: u32 = 1u32;\npub const MM_BROOKTREE: u32 = 121u32;\npub const MM_BTV_AUX_CD: u32 = 8u32;\npub const MM_BTV_AUX_LINE: u32 = 6u32;\npub const MM_BTV_AUX_MIC: u32 = 7u32;\npub const MM_BTV_DIGITALIN: u32 = 9u32;\npub const MM_BTV_DIGITALOUT: u32 = 10u32;\npub const MM_BTV_MIDIIN: u32 = 3u32;\npub const MM_BTV_MIDIOUT: u32 = 4u32;\npub const MM_BTV_MIDISYNTH: u32 = 5u32;\npub const MM_BTV_MIDIWAVESTREAM: u32 = 11u32;\npub const MM_BTV_MIXER: u32 = 12u32;\npub const MM_BTV_WAVEIN: u32 = 1u32;\npub const MM_BTV_WAVEOUT: u32 = 2u32;\npub const MM_CANAM: u32 = 148u32;\npub const MM_CANAM_CBXWAVEIN: u32 = 2u32;\npub const MM_CANAM_CBXWAVEOUT: u32 = 1u32;\npub const MM_CANOPUS: u32 = 49u32;\npub const MM_CANOPUS_ACM_DVREX: u32 = 1u32;\npub const MM_CASIO: u32 = 162u32;\npub const MM_CASIO_LSG_MIDIOUT: u32 = 3u32;\npub const MM_CASIO_WP150_MIDIIN: u32 = 2u32;\npub const MM_CASIO_WP150_MIDIOUT: u32 = 1u32;\npub const MM_CAT: u32 = 41u32;\npub const MM_CAT_WAVEOUT: u32 = 1u32;\npub const MM_CDPC_AUX: u32 = 119u32;\npub const MM_CDPC_MIDIIN: u32 = 114u32;\npub const MM_CDPC_MIDIOUT: u32 = 113u32;\npub const MM_CDPC_MIXER: u32 = 118u32;\npub const MM_CDPC_SYNTH: u32 = 115u32;\npub const MM_CDPC_WAVEIN: u32 = 117u32;\npub const MM_CDPC_WAVEOUT: u32 = 116u32;\npub const MM_CHROMATIC: u32 = 155u32;\npub const MM_CHROMATIC_M1: u32 = 1u32;\npub const MM_CHROMATIC_M1_AUX: u32 = 6u32;\npub const MM_CHROMATIC_M1_AUX_CD: u32 = 7u32;\npub const MM_CHROMATIC_M1_FMSYNTH: u32 = 4u32;\npub const MM_CHROMATIC_M1_MIDIIN: u32 = 8u32;\npub const MM_CHROMATIC_M1_MIDIOUT: u32 = 9u32;\npub const MM_CHROMATIC_M1_MIXER: u32 = 5u32;\npub const MM_CHROMATIC_M1_MPEGWAVEIN: u32 = 17u32;\npub const MM_CHROMATIC_M1_MPEGWAVEOUT: u32 = 18u32;\npub const MM_CHROMATIC_M1_WAVEIN: u32 = 2u32;\npub const MM_CHROMATIC_M1_WAVEOUT: u32 = 3u32;\npub const MM_CHROMATIC_M1_WTSYNTH: u32 = 16u32;\npub const MM_CHROMATIC_M2: u32 = 19u32;\npub const MM_CHROMATIC_M2_AUX: u32 = 24u32;\npub const MM_CHROMATIC_M2_AUX_CD: u32 = 25u32;\npub const MM_CHROMATIC_M2_FMSYNTH: u32 = 22u32;\npub const MM_CHROMATIC_M2_MIDIIN: u32 = 32u32;\npub const MM_CHROMATIC_M2_MIDIOUT: u32 = 33u32;\npub const MM_CHROMATIC_M2_MIXER: u32 = 23u32;\npub const MM_CHROMATIC_M2_MPEGWAVEIN: u32 = 35u32;\npub const MM_CHROMATIC_M2_MPEGWAVEOUT: u32 = 36u32;\npub const MM_CHROMATIC_M2_WAVEIN: u32 = 20u32;\npub const MM_CHROMATIC_M2_WAVEOUT: u32 = 21u32;\npub const MM_CHROMATIC_M2_WTSYNTH: u32 = 34u32;\npub const MM_CIRRUSLOGIC: u32 = 105u32;\npub const MM_COLORGRAPH: u32 = 179u32;\npub const MM_COMPAQ: u32 = 92u32;\npub const MM_COMPAQ_BB_WAVEAUX: u32 = 3u32;\npub const MM_COMPAQ_BB_WAVEIN: u32 = 1u32;\npub const MM_COMPAQ_BB_WAVEOUT: u32 = 2u32;\npub const MM_COMPUSIC: u32 = 89u32;\npub const MM_COMPUTER_FRIENDS: u32 = 45u32;\npub const MM_CONCEPTS: u32 = 108u32;\npub const MM_CONNECTIX: u32 = 158u32;\npub const MM_CONNECTIX_VIDEC_CODEC: u32 = 1u32;\npub const MM_CONTROLRES: u32 = 84u32;\npub const MM_COREDYNAMICS: u32 = 147u32;\npub const MM_COREDYNAMICS_DYNAGRAFX_VGA: u32 = 9u32;\npub const MM_COREDYNAMICS_DYNAGRAFX_WAVE_IN: u32 = 10u32;\npub const MM_COREDYNAMICS_DYNAGRAFX_WAVE_OUT: u32 = 11u32;\npub const MM_COREDYNAMICS_DYNAMIXHR: u32 = 1u32;\npub const MM_COREDYNAMICS_DYNASONIX_AUDIO_IN: u32 = 7u32;\npub const MM_COREDYNAMICS_DYNASONIX_AUDIO_OUT: u32 = 8u32;\npub const MM_COREDYNAMICS_DYNASONIX_MIDI_IN: u32 = 3u32;\npub const MM_COREDYNAMICS_DYNASONIX_MIDI_OUT: u32 = 4u32;\npub const MM_COREDYNAMICS_DYNASONIX_SYNTH: u32 = 2u32;\npub const MM_COREDYNAMICS_DYNASONIX_WAVE_IN: u32 = 5u32;\npub const MM_COREDYNAMICS_DYNASONIX_WAVE_OUT: u32 = 6u32;\npub const MM_CREATIVE: u32 = 2u32;\npub const MM_CREATIVE_AUX_CD: u32 = 401u32;\npub const MM_CREATIVE_AUX_LINE: u32 = 402u32;\npub const MM_CREATIVE_AUX_MASTER: u32 = 404u32;\npub const MM_CREATIVE_AUX_MIC: u32 = 403u32;\npub const MM_CREATIVE_AUX_MIDI: u32 = 407u32;\npub const MM_CREATIVE_AUX_PCSPK: u32 = 405u32;\npub const MM_CREATIVE_AUX_WAVE: u32 = 406u32;\npub const MM_CREATIVE_FMSYNTH_MONO: u32 = 301u32;\npub const MM_CREATIVE_FMSYNTH_STEREO: u32 = 302u32;\npub const MM_CREATIVE_MIDIIN: u32 = 202u32;\npub const MM_CREATIVE_MIDIOUT: u32 = 201u32;\npub const MM_CREATIVE_MIDI_AWE32: u32 = 303u32;\npub const MM_CREATIVE_PHNBLST_WAVEIN: u32 = 5u32;\npub const MM_CREATIVE_PHNBLST_WAVEOUT: u32 = 105u32;\npub const MM_CREATIVE_SB15_WAVEIN: u32 = 1u32;\npub const MM_CREATIVE_SB15_WAVEOUT: u32 = 101u32;\npub const MM_CREATIVE_SB16_MIXER: u32 = 409u32;\npub const MM_CREATIVE_SB20_WAVEIN: u32 = 2u32;\npub const MM_CREATIVE_SB20_WAVEOUT: u32 = 102u32;\npub const MM_CREATIVE_SBP16_WAVEIN: u32 = 4u32;\npub const MM_CREATIVE_SBP16_WAVEOUT: u32 = 104u32;\npub const MM_CREATIVE_SBPRO_MIXER: u32 = 408u32;\npub const MM_CREATIVE_SBPRO_WAVEIN: u32 = 3u32;\npub const MM_CREATIVE_SBPRO_WAVEOUT: u32 = 103u32;\npub const MM_CRYSTAL: u32 = 132u32;\npub const MM_CRYSTAL_CS4232_INPUTGAIN_AUX1: u32 = 13u32;\npub const MM_CRYSTAL_CS4232_INPUTGAIN_LOOP: u32 = 14u32;\npub const MM_CRYSTAL_CS4232_MIDIIN: u32 = 9u32;\npub const MM_CRYSTAL_CS4232_MIDIOUT: u32 = 10u32;\npub const MM_CRYSTAL_CS4232_WAVEAUX_AUX1: u32 = 4u32;\npub const MM_CRYSTAL_CS4232_WAVEAUX_AUX2: u32 = 5u32;\npub const MM_CRYSTAL_CS4232_WAVEAUX_LINE: u32 = 6u32;\npub const MM_CRYSTAL_CS4232_WAVEAUX_MASTER: u32 = 8u32;\npub const MM_CRYSTAL_CS4232_WAVEAUX_MONO: u32 = 7u32;\npub const MM_CRYSTAL_CS4232_WAVEIN: u32 = 1u32;\npub const MM_CRYSTAL_CS4232_WAVEMIXER: u32 = 3u32;\npub const MM_CRYSTAL_CS4232_WAVEOUT: u32 = 2u32;\npub const MM_CRYSTAL_NET: u32 = 154u32;\npub const MM_CRYSTAL_SOUND_FUSION_JOYSTICK: u32 = 26u32;\npub const MM_CRYSTAL_SOUND_FUSION_MIDIIN: u32 = 24u32;\npub const MM_CRYSTAL_SOUND_FUSION_MIDIOUT: u32 = 25u32;\npub const MM_CRYSTAL_SOUND_FUSION_MIXER: u32 = 23u32;\npub const MM_CRYSTAL_SOUND_FUSION_WAVEIN: u32 = 21u32;\npub const MM_CRYSTAL_SOUND_FUSION_WAVEOUT: u32 = 22u32;\npub const MM_CS: u32 = 242u32;\npub const MM_CYRIX: u32 = 6u32;\npub const MM_CYRIX_XAAUX: u32 = 6u32;\npub const MM_CYRIX_XAMIDIIN: u32 = 2u32;\npub const MM_CYRIX_XAMIDIOUT: u32 = 3u32;\npub const MM_CYRIX_XAMIXER: u32 = 7u32;\npub const MM_CYRIX_XASYNTH: u32 = 1u32;\npub const MM_CYRIX_XAWAVEIN: u32 = 4u32;\npub const MM_CYRIX_XAWAVEOUT: u32 = 5u32;\npub const MM_DATAFUSION: u32 = 196u32;\npub const MM_DATARAN: u32 = 232u32;\npub const MM_DDD: u32 = 151u32;\npub const MM_DDD_MIDILINK_MIDIIN: u32 = 1u32;\npub const MM_DDD_MIDILINK_MIDIOUT: u32 = 2u32;\npub const MM_DF_ACM_G726: u32 = 1u32;\npub const MM_DF_ACM_GSM610: u32 = 2u32;\npub const MM_DIACOUSTICS: u32 = 129u32;\npub const MM_DIACOUSTICS_DRUM_ACTION: u32 = 1u32;\npub const MM_DIALOGIC: u32 = 93u32;\npub const MM_DIAMONDMM: u32 = 163u32;\npub const MM_DICTAPHONE: u32 = 214u32;\npub const MM_DICTAPHONE_G726: u32 = 1u32;\npub const MM_DIGIGRAM: u32 = 227u32;\npub const MM_DIGITAL: u32 = 100u32;\npub const MM_DIGITAL_ACM_G723: u32 = 3u32;\npub const MM_DIGITAL_AUDIO_LABS: u32 = 136u32;\npub const MM_DIGITAL_AUDIO_LABS_CDLX: u32 = 19u32;\npub const MM_DIGITAL_AUDIO_LABS_CPRO: u32 = 17u32;\npub const MM_DIGITAL_AUDIO_LABS_CTDIF: u32 = 20u32;\npub const MM_DIGITAL_AUDIO_LABS_DOC: u32 = 2u32;\npub const MM_DIGITAL_AUDIO_LABS_TC: u32 = 1u32;\npub const MM_DIGITAL_AUDIO_LABS_V8: u32 = 16u32;\npub const MM_DIGITAL_AUDIO_LABS_VP: u32 = 18u32;\npub const MM_DIGITAL_AV320_WAVEIN: u32 = 1u32;\npub const MM_DIGITAL_AV320_WAVEOUT: u32 = 2u32;\npub const MM_DIGITAL_ICM_H261: u32 = 5u32;\npub const MM_DIGITAL_ICM_H263: u32 = 4u32;\npub const MM_DIMD_AUX_LINE: u32 = 9u32;\npub const MM_DIMD_DIRSOUND: u32 = 1u32;\npub const MM_DIMD_MIDIIN: u32 = 7u32;\npub const MM_DIMD_MIDIOUT: u32 = 8u32;\npub const MM_DIMD_MIXER: u32 = 10u32;\npub const MM_DIMD_PLATFORM: u32 = 0u32;\npub const MM_DIMD_VIRTJOY: u32 = 4u32;\npub const MM_DIMD_VIRTMPU: u32 = 2u32;\npub const MM_DIMD_VIRTSB: u32 = 3u32;\npub const MM_DIMD_WAVEIN: u32 = 5u32;\npub const MM_DIMD_WAVEOUT: u32 = 6u32;\npub const MM_DIMD_WSS_AUX: u32 = 21u32;\npub const MM_DIMD_WSS_MIXER: u32 = 17u32;\npub const MM_DIMD_WSS_SYNTH: u32 = 76u32;\npub const MM_DIMD_WSS_WAVEIN: u32 = 14u32;\npub const MM_DIMD_WSS_WAVEOUT: u32 = 15u32;\npub const MM_DOLBY: u32 = 78u32;\npub const MM_DPSINC: u32 = 191u32;\npub const MM_DSP_GROUP: u32 = 43u32;\npub const MM_DSP_GROUP_TRUESPEECH: u32 = 1u32;\npub const MM_DSP_SOLUTIONS: u32 = 25u32;\npub const MM_DSP_SOLUTIONS_AUX: u32 = 4u32;\npub const MM_DSP_SOLUTIONS_SYNTH: u32 = 3u32;\npub const MM_DSP_SOLUTIONS_WAVEIN: u32 = 2u32;\npub const MM_DSP_SOLUTIONS_WAVEOUT: u32 = 1u32;\npub const MM_DTS: u32 = 226u32;\npub const MM_DTS_DS: u32 = 1u32;\npub const MM_DUCK: u32 = 197u32;\npub const MM_DVISION: u32 = 165u32;\npub const MM_ECHO: u32 = 39u32;\npub const MM_ECHO_AUX: u32 = 6u32;\npub const MM_ECHO_MIDIIN: u32 = 5u32;\npub const MM_ECHO_MIDIOUT: u32 = 4u32;\npub const MM_ECHO_SYNTH: u32 = 1u32;\npub const MM_ECHO_WAVEIN: u32 = 3u32;\npub const MM_ECHO_WAVEOUT: u32 = 2u32;\npub const MM_ECS: u32 = 145u32;\npub const MM_ECS_AADF_MIDI_IN: u32 = 10u32;\npub const MM_ECS_AADF_MIDI_OUT: u32 = 11u32;\npub const MM_ECS_AADF_WAVE2MIDI_IN: u32 = 12u32;\npub const MM_EES: u32 = 219u32;\npub const MM_EES_PCMIDI14: u32 = 1u32;\npub const MM_EES_PCMIDI14_IN: u32 = 2u32;\npub const MM_EES_PCMIDI14_OUT1: u32 = 3u32;\npub const MM_EES_PCMIDI14_OUT2: u32 = 4u32;\npub const MM_EES_PCMIDI14_OUT3: u32 = 5u32;\npub const MM_EES_PCMIDI14_OUT4: u32 = 6u32;\npub const MM_EMAGIC: u32 = 208u32;\npub const MM_EMAGIC_UNITOR8: u32 = 1u32;\npub const MM_EMU: u32 = 19u32;\npub const MM_EMU_APSMIDIIN: u32 = 2u32;\npub const MM_EMU_APSMIDIOUT: u32 = 3u32;\npub const MM_EMU_APSSYNTH: u32 = 1u32;\npub const MM_EMU_APSWAVEIN: u32 = 4u32;\npub const MM_EMU_APSWAVEOUT: u32 = 5u32;\npub const MM_ENET: u32 = 206u32;\npub const MM_ENET_T2000_HANDSETIN: u32 = 3u32;\npub const MM_ENET_T2000_HANDSETOUT: u32 = 4u32;\npub const MM_ENET_T2000_LINEIN: u32 = 1u32;\npub const MM_ENET_T2000_LINEOUT: u32 = 2u32;\npub const MM_ENSONIQ: u32 = 125u32;\npub const MM_ENSONIQ_SOUNDSCAPE: u32 = 16u32;\npub const MM_EPSON: u32 = 50u32;\npub const MM_EPS_FMSND: u32 = 1u32;\npub const MM_ESS: u32 = 46u32;\npub const MM_ESS_AMAUX: u32 = 3u32;\npub const MM_ESS_AMMIDIIN: u32 = 6u32;\npub const MM_ESS_AMMIDIOUT: u32 = 5u32;\npub const MM_ESS_AMSYNTH: u32 = 4u32;\npub const MM_ESS_AMWAVEIN: u32 = 2u32;\npub const MM_ESS_AMWAVEOUT: u32 = 1u32;\npub const MM_ESS_AUX_CD: u32 = 8u32;\npub const MM_ESS_ES1488_MIXER: u32 = 24u32;\npub const MM_ESS_ES1488_WAVEIN: u32 = 23u32;\npub const MM_ESS_ES1488_WAVEOUT: u32 = 22u32;\npub const MM_ESS_ES1688_MIXER: u32 = 27u32;\npub const MM_ESS_ES1688_WAVEIN: u32 = 26u32;\npub const MM_ESS_ES1688_WAVEOUT: u32 = 25u32;\npub const MM_ESS_ES1788_MIXER: u32 = 30u32;\npub const MM_ESS_ES1788_WAVEIN: u32 = 29u32;\npub const MM_ESS_ES1788_WAVEOUT: u32 = 28u32;\npub const MM_ESS_ES1868_MIXER: u32 = 36u32;\npub const MM_ESS_ES1868_WAVEIN: u32 = 35u32;\npub const MM_ESS_ES1868_WAVEOUT: u32 = 34u32;\npub const MM_ESS_ES1878_MIXER: u32 = 39u32;\npub const MM_ESS_ES1878_WAVEIN: u32 = 38u32;\npub const MM_ESS_ES1878_WAVEOUT: u32 = 37u32;\npub const MM_ESS_ES1888_MIXER: u32 = 33u32;\npub const MM_ESS_ES1888_WAVEIN: u32 = 32u32;\npub const MM_ESS_ES1888_WAVEOUT: u32 = 31u32;\npub const MM_ESS_ES488_MIXER: u32 = 18u32;\npub const MM_ESS_ES488_WAVEIN: u32 = 17u32;\npub const MM_ESS_ES488_WAVEOUT: u32 = 16u32;\npub const MM_ESS_ES688_MIXER: u32 = 21u32;\npub const MM_ESS_ES688_WAVEIN: u32 = 20u32;\npub const MM_ESS_ES688_WAVEOUT: u32 = 19u32;\npub const MM_ESS_MIXER: u32 = 7u32;\npub const MM_ESS_MPU401_MIDIIN: u32 = 10u32;\npub const MM_ESS_MPU401_MIDIOUT: u32 = 9u32;\npub const MM_ETEK: u32 = 241u32;\npub const MM_ETEK_KWIKMIDI_MIDIIN: u32 = 1u32;\npub const MM_ETEK_KWIKMIDI_MIDIOUT: u32 = 2u32;\npub const MM_EUPHONICS: u32 = 152u32;\npub const MM_EUPHONICS_AUX_CD: u32 = 1u32;\npub const MM_EUPHONICS_AUX_LINE: u32 = 2u32;\npub const MM_EUPHONICS_AUX_MASTER: u32 = 3u32;\npub const MM_EUPHONICS_AUX_MIC: u32 = 4u32;\npub const MM_EUPHONICS_AUX_MIDI: u32 = 5u32;\npub const MM_EUPHONICS_AUX_WAVE: u32 = 6u32;\npub const MM_EUPHONICS_EUSYNTH: u32 = 14u32;\npub const MM_EUPHONICS_FMSYNTH_MONO: u32 = 7u32;\npub const MM_EUPHONICS_FMSYNTH_STEREO: u32 = 8u32;\npub const MM_EUPHONICS_MIDIIN: u32 = 9u32;\npub const MM_EUPHONICS_MIDIOUT: u32 = 10u32;\npub const MM_EUPHONICS_MIXER: u32 = 11u32;\npub const MM_EUPHONICS_WAVEIN: u32 = 12u32;\npub const MM_EUPHONICS_WAVEOUT: u32 = 13u32;\npub const MM_EVEREX: u32 = 38u32;\npub const MM_EVEREX_CARRIER: u32 = 1u32;\npub const MM_EXAN: u32 = 63u32;\npub const MM_FAITH: u32 = 15u32;\npub const MM_FAST: u32 = 126u32;\npub const MM_FHGIIS_MPEGLAYER3: u32 = 10u32;\npub const MM_FHGIIS_MPEGLAYER3_ADVANCED: u32 = 12u32;\npub const MM_FHGIIS_MPEGLAYER3_ADVANCEDPLUS: u32 = 14u32;\npub const MM_FHGIIS_MPEGLAYER3_BASIC: u32 = 11u32;\npub const MM_FHGIIS_MPEGLAYER3_DECODE: u32 = 9u32;\npub const MM_FHGIIS_MPEGLAYER3_LITE: u32 = 10u32;\npub const MM_FHGIIS_MPEGLAYER3_PROFESSIONAL: u32 = 13u32;\npub const MM_FLEXION: u32 = 249u32;\npub const MM_FLEXION_X300_WAVEIN: u32 = 1u32;\npub const MM_FLEXION_X300_WAVEOUT: u32 = 2u32;\npub const MM_FORTEMEDIA: u32 = 229u32;\npub const MM_FORTEMEDIA_AUX: u32 = 5u32;\npub const MM_FORTEMEDIA_FMSYNC: u32 = 3u32;\npub const MM_FORTEMEDIA_MIXER: u32 = 4u32;\npub const MM_FORTEMEDIA_WAVEIN: u32 = 1u32;\npub const MM_FORTEMEDIA_WAVEOUT: u32 = 2u32;\npub const MM_FRAUNHOFER_IIS: u32 = 172u32;\npub const MM_FRONTIER: u32 = 160u32;\npub const MM_FRONTIER_WAVECENTER_MIDIIN: u32 = 1u32;\npub const MM_FRONTIER_WAVECENTER_MIDIOUT: u32 = 2u32;\npub const MM_FRONTIER_WAVECENTER_WAVEIN: u32 = 3u32;\npub const MM_FRONTIER_WAVECENTER_WAVEOUT: u32 = 4u32;\npub const MM_FTR: u32 = 198u32;\npub const MM_FTR_ACM: u32 = 2u32;\npub const MM_FTR_ENCODER_WAVEIN: u32 = 1u32;\npub const MM_FUJITSU: u32 = 4u32;\npub const MM_GADGETLABS: u32 = 159u32;\npub const MM_GADGETLABS_WAVE42_WAVEIN: u32 = 3u32;\npub const MM_GADGETLABS_WAVE42_WAVEOUT: u32 = 4u32;\npub const MM_GADGETLABS_WAVE44_WAVEIN: u32 = 1u32;\npub const MM_GADGETLABS_WAVE44_WAVEOUT: u32 = 2u32;\npub const MM_GADGETLABS_WAVE4_MIDIIN: u32 = 5u32;\npub const MM_GADGETLABS_WAVE4_MIDIOUT: u32 = 6u32;\npub const MM_GRANDE: u32 = 117u32;\npub const MM_GRAVIS: u32 = 34u32;\npub const MM_GUILLEMOT: u32 = 207u32;\npub const MM_GULBRANSEN: u32 = 130u32;\npub const MM_HAFTMANN: u32 = 220u32;\npub const MM_HAFTMANN_LPTDAC2: u32 = 1u32;\npub const MM_HEADSPACE: u32 = 222u32;\npub const MM_HEADSPACE_HAEMIXER: u32 = 4u32;\npub const MM_HEADSPACE_HAESYNTH: u32 = 1u32;\npub const MM_HEADSPACE_HAEWAVEIN: u32 = 3u32;\npub const MM_HEADSPACE_HAEWAVEOUT: u32 = 2u32;\npub const MM_HEWLETT_PACKARD: u32 = 13u32;\npub const MM_HEWLETT_PACKARD_CU_CODEC: u32 = 1u32;\npub const MM_HORIZONS: u32 = 107u32;\npub const MM_HP: u32 = 253u32;\npub const MM_HP_WAVEIN: u32 = 2u32;\npub const MM_HP_WAVEOUT: u32 = 1u32;\npub const MM_HYPERACTIVE: u32 = 246u32;\npub const MM_IBM: u32 = 22u32;\npub const MM_IBM_MWAVE_AUX: u32 = 23u32;\npub const MM_IBM_MWAVE_MIDIIN: u32 = 21u32;\npub const MM_IBM_MWAVE_MIDIOUT: u32 = 22u32;\npub const MM_IBM_MWAVE_MIXER: u32 = 20u32;\npub const MM_IBM_MWAVE_WAVEIN: u32 = 18u32;\npub const MM_IBM_MWAVE_WAVEOUT: u32 = 19u32;\npub const MM_IBM_PCMCIA_AUX: u32 = 16u32;\npub const MM_IBM_PCMCIA_MIDIIN: u32 = 14u32;\npub const MM_IBM_PCMCIA_MIDIOUT: u32 = 15u32;\npub const MM_IBM_PCMCIA_SYNTH: u32 = 13u32;\npub const MM_IBM_PCMCIA_WAVEIN: u32 = 11u32;\npub const MM_IBM_PCMCIA_WAVEOUT: u32 = 12u32;\npub const MM_IBM_THINKPAD200: u32 = 17u32;\npub const MM_IBM_WC_MIDIOUT: u32 = 30u32;\npub const MM_IBM_WC_MIXEROUT: u32 = 33u32;\npub const MM_IBM_WC_WAVEOUT: u32 = 31u32;\npub const MM_ICCC: u32 = 259u32;\npub const MM_ICCC_UNA3_AUX: u32 = 3u32;\npub const MM_ICCC_UNA3_MIXER: u32 = 4u32;\npub const MM_ICCC_UNA3_WAVEIN: u32 = 1u32;\npub const MM_ICCC_UNA3_WAVEOUT: u32 = 2u32;\npub const MM_ICE: u32 = 239u32;\npub const MM_ICE_AUX: u32 = 11u32;\npub const MM_ICE_MIDIIN1: u32 = 6u32;\npub const MM_ICE_MIDIIN2: u32 = 8u32;\npub const MM_ICE_MIDIOUT1: u32 = 5u32;\npub const MM_ICE_MIDIOUT2: u32 = 7u32;\npub const MM_ICE_MIXER: u32 = 10u32;\npub const MM_ICE_MTWAVEIN: u32 = 4u32;\npub const MM_ICE_MTWAVEOUT: u32 = 3u32;\npub const MM_ICE_SYNTH: u32 = 9u32;\npub const MM_ICE_WAVEIN: u32 = 2u32;\npub const MM_ICE_WAVEOUT: u32 = 1u32;\npub const MM_ICL_PS: u32 = 32u32;\npub const MM_ICOM_AUX: u32 = 6u32;\npub const MM_ICOM_LINE: u32 = 7u32;\npub const MM_ICOM_MIXER: u32 = 5u32;\npub const MM_ICOM_WAVEIN: u32 = 3u32;\npub const MM_ICOM_WAVEOUT: u32 = 4u32;\npub const MM_ICS: u32 = 57u32;\npub const MM_ICS_2115_LITE_MIDIOUT: u32 = 13u32;\npub const MM_ICS_2120_LITE_MIDIOUT: u32 = 14u32;\npub const MM_ICS_WAVEDECK_AUX: u32 = 4u32;\npub const MM_ICS_WAVEDECK_MIXER: u32 = 3u32;\npub const MM_ICS_WAVEDECK_SYNTH: u32 = 5u32;\npub const MM_ICS_WAVEDECK_WAVEIN: u32 = 2u32;\npub const MM_ICS_WAVEDECK_WAVEOUT: u32 = 1u32;\npub const MM_ICS_WAVEDEC_SB_AUX: u32 = 12u32;\npub const MM_ICS_WAVEDEC_SB_FM_MIDIOUT: u32 = 8u32;\npub const MM_ICS_WAVEDEC_SB_MIXER: u32 = 11u32;\npub const MM_ICS_WAVEDEC_SB_MPU401_MIDIIN: u32 = 10u32;\npub const MM_ICS_WAVEDEC_SB_MPU401_MIDIOUT: u32 = 9u32;\npub const MM_ICS_WAVEDEC_SB_WAVEIN: u32 = 7u32;\npub const MM_ICS_WAVEDEC_SB_WAVEOUT: u32 = 6u32;\npub const MM_INSOFT: u32 = 94u32;\npub const MM_INTEL: u32 = 33u32;\npub const MM_INTELOPD_AUX: u32 = 401u32;\npub const MM_INTELOPD_WAVEIN: u32 = 1u32;\npub const MM_INTELOPD_WAVEOUT: u32 = 101u32;\npub const MM_INTEL_NSPMODEMLINEIN: u32 = 501u32;\npub const MM_INTEL_NSPMODEMLINEOUT: u32 = 502u32;\npub const MM_INTERACTIVE: u32 = 36u32;\npub const MM_INTERACTIVE_WAVEIN: u32 = 69u32;\npub const MM_INTERACTIVE_WAVEOUT: u32 = 69u32;\npub const MM_INTERNET: u32 = 244u32;\npub const MM_INTERNET_SSW_MIDIIN: u32 = 11u32;\npub const MM_INTERNET_SSW_MIDIOUT: u32 = 10u32;\npub const MM_INTERNET_SSW_WAVEIN: u32 = 13u32;\npub const MM_INTERNET_SSW_WAVEOUT: u32 = 12u32;\npub const MM_INVISION: u32 = 188u32;\npub const MM_IODD: u32 = 258u32;\npub const MM_IOMAGIC: u32 = 82u32;\npub const MM_IOMAGIC_TEMPO_AUXOUT: u32 = 6u32;\npub const MM_IOMAGIC_TEMPO_MIDIOUT: u32 = 4u32;\npub const MM_IOMAGIC_TEMPO_MXDOUT: u32 = 5u32;\npub const MM_IOMAGIC_TEMPO_SYNTH: u32 = 3u32;\npub const MM_IOMAGIC_TEMPO_WAVEIN: u32 = 2u32;\npub const MM_IOMAGIC_TEMPO_WAVEOUT: u32 = 1u32;\npub const MM_IPI: u32 = 238u32;\npub const MM_IPI_ACM_HSX: u32 = 1u32;\npub const MM_IPI_ACM_RPELP: u32 = 2u32;\npub const MM_IPI_AT_MIXER: u32 = 6u32;\npub const MM_IPI_AT_WAVEIN: u32 = 5u32;\npub const MM_IPI_AT_WAVEOUT: u32 = 4u32;\npub const MM_IPI_WF_ASSS: u32 = 3u32;\npub const MM_ISOLUTION: u32 = 106u32;\npub const MM_ISOLUTION_PASCAL: u32 = 1u32;\npub const MM_ITERATEDSYS: u32 = 58u32;\npub const MM_ITERATEDSYS_FUFCODEC: u32 = 1u32;\npub const MM_I_LINK: u32 = 233u32;\npub const MM_I_LINK_VOICE_CODER: u32 = 1u32;\npub const MM_KAY_ELEMETRICS: u32 = 131u32;\npub const MM_KAY_ELEMETRICS_CSL: u32 = 17152u32;\npub const MM_KAY_ELEMETRICS_CSL_4CHANNEL: u32 = 17161u32;\npub const MM_KAY_ELEMETRICS_CSL_DAT: u32 = 17160u32;\npub const MM_KORG: u32 = 55u32;\npub const MM_KORG_1212IO_MSWAVEIN: u32 = 3u32;\npub const MM_KORG_1212IO_MSWAVEOUT: u32 = 4u32;\npub const MM_KORG_PCIF_MIDIIN: u32 = 2u32;\npub const MM_KORG_PCIF_MIDIOUT: u32 = 1u32;\npub const MM_LERNOUT_ANDHAUSPIE_LHCODECACM: u32 = 1u32;\npub const MM_LERNOUT_AND_HAUSPIE: u32 = 97u32;\npub const MM_LEXICON: u32 = 236u32;\npub const MM_LEXICON_STUDIO_WAVE_IN: u32 = 2u32;\npub const MM_LEXICON_STUDIO_WAVE_OUT: u32 = 1u32;\npub const MM_LOGITECH: u32 = 60u32;\npub const MM_LUCENT: u32 = 184u32;\npub const MM_LUCENT_ACM_G723: u32 = 0u32;\npub const MM_LUCID: u32 = 221u32;\npub const MM_LUCID_PCI24WAVEIN: u32 = 1u32;\npub const MM_LUCID_PCI24WAVEOUT: u32 = 2u32;\npub const MM_LUMINOSITI: u32 = 224u32;\npub const MM_LUMINOSITI_SCWAVEIN: u32 = 1u32;\npub const MM_LUMINOSITI_SCWAVEMIX: u32 = 3u32;\npub const MM_LUMINOSITI_SCWAVEOUT: u32 = 2u32;\npub const MM_LYNX: u32 = 212u32;\npub const MM_LYRRUS: u32 = 88u32;\npub const MM_LYRRUS_BRIDGE_GUITAR: u32 = 1u32;\npub const MM_MALDEN: u32 = 261u32;\npub const MM_MARIAN: u32 = 190u32;\npub const MM_MARIAN_ARC44WAVEIN: u32 = 1u32;\npub const MM_MARIAN_ARC44WAVEOUT: u32 = 2u32;\npub const MM_MARIAN_ARC88WAVEIN: u32 = 5u32;\npub const MM_MARIAN_ARC88WAVEOUT: u32 = 6u32;\npub const MM_MARIAN_PRODIF24WAVEIN: u32 = 3u32;\npub const MM_MARIAN_PRODIF24WAVEOUT: u32 = 4u32;\npub const MM_MATROX_DIV: u32 = 254u32;\npub const MM_MATSUSHITA: u32 = 83u32;\npub const MM_MATSUSHITA_AUX: u32 = 5u32;\npub const MM_MATSUSHITA_FMSYNTH_STEREO: u32 = 3u32;\npub const MM_MATSUSHITA_MIXER: u32 = 4u32;\npub const MM_MATSUSHITA_WAVEIN: u32 = 1u32;\npub const MM_MATSUSHITA_WAVEOUT: u32 = 2u32;\npub const MM_MEDIASONIC: u32 = 71u32;\npub const MM_MEDIASONIC_ACM_G723: u32 = 1u32;\npub const MM_MEDIASONIC_ICOM: u32 = 2u32;\npub const MM_MEDIATRIX: u32 = 141u32;\npub const MM_MEDIAVISION: u32 = 3u32;\npub const MM_MEDIAVISION_CDPC: u32 = 112u32;\npub const MM_MEDIAVISION_OPUS1208: u32 = 128u32;\npub const MM_MEDIAVISION_OPUS1216: u32 = 144u32;\npub const MM_MEDIAVISION_PROAUDIO: u32 = 16u32;\npub const MM_MEDIAVISION_PROAUDIO_16: u32 = 96u32;\npub const MM_MEDIAVISION_PROAUDIO_PLUS: u32 = 80u32;\npub const MM_MEDIAVISION_PROSTUDIO_16: u32 = 96u32;\npub const MM_MEDIAVISION_THUNDER: u32 = 32u32;\npub const MM_MEDIAVISION_TPORT: u32 = 64u32;\npub const MM_MELABS: u32 = 44u32;\npub const MM_MELABS_MIDI2GO: u32 = 1u32;\npub const MM_MERGING_MPEGL3: u32 = 1u32;\npub const MM_MERGING_TECHNOLOGIES: u32 = 177u32;\npub const MM_METHEUS: u32 = 59u32;\npub const MM_METHEUS_ZIPPER: u32 = 1u32;\npub const MM_MICRONAS: u32 = 251u32;\npub const MM_MICRONAS_CLP833: u32 = 2u32;\npub const MM_MICRONAS_SC4: u32 = 1u32;\npub const MM_MINDMAKER: u32 = 263u32;\npub const MM_MINDMAKER_GC_MIXER: u32 = 3u32;\npub const MM_MINDMAKER_GC_WAVEIN: u32 = 1u32;\npub const MM_MINDMAKER_GC_WAVEOUT: u32 = 2u32;\npub const MM_MIRO: u32 = 104u32;\npub const MM_MIRO_DC30_MIX: u32 = 7u32;\npub const MM_MIRO_DC30_WAVEIN: u32 = 6u32;\npub const MM_MIRO_DC30_WAVEOUT: u32 = 5u32;\npub const MM_MIRO_MOVIEPRO: u32 = 1u32;\npub const MM_MIRO_VIDEOD1: u32 = 2u32;\npub const MM_MIRO_VIDEODC1TV: u32 = 3u32;\npub const MM_MIRO_VIDEOTD: u32 = 4u32;\npub const MM_MITEL: u32 = 16u32;\npub const MM_MITEL_MEDIAPATH_WAVEIN: u32 = 301u32;\npub const MM_MITEL_MEDIAPATH_WAVEOUT: u32 = 300u32;\npub const MM_MITEL_MPA_HANDSET_WAVEIN: u32 = 201u32;\npub const MM_MITEL_MPA_HANDSET_WAVEOUT: u32 = 200u32;\npub const MM_MITEL_MPA_HANDSFREE_WAVEIN: u32 = 203u32;\npub const MM_MITEL_MPA_HANDSFREE_WAVEOUT: u32 = 202u32;\npub const MM_MITEL_MPA_LINE1_WAVEIN: u32 = 205u32;\npub const MM_MITEL_MPA_LINE1_WAVEOUT: u32 = 204u32;\npub const MM_MITEL_MPA_LINE2_WAVEIN: u32 = 207u32;\npub const MM_MITEL_MPA_LINE2_WAVEOUT: u32 = 206u32;\npub const MM_MITEL_TALKTO_BRIDGED_WAVEIN: u32 = 105u32;\npub const MM_MITEL_TALKTO_BRIDGED_WAVEOUT: u32 = 104u32;\npub const MM_MITEL_TALKTO_HANDSET_WAVEIN: u32 = 103u32;\npub const MM_MITEL_TALKTO_HANDSET_WAVEOUT: u32 = 102u32;\npub const MM_MITEL_TALKTO_LINE_WAVEIN: u32 = 101u32;\npub const MM_MITEL_TALKTO_LINE_WAVEOUT: u32 = 100u32;\npub const MM_MMOTION_WAVEAUX: u32 = 1u32;\npub const MM_MMOTION_WAVEIN: u32 = 3u32;\npub const MM_MMOTION_WAVEOUT: u32 = 2u32;\npub const MM_MOSCOM: u32 = 68u32;\npub const MM_MOSCOM_VPC2400_IN: u32 = 1u32;\npub const MM_MOSCOM_VPC2400_OUT: u32 = 2u32;\npub const MM_MOTIONPIXELS: u32 = 193u32;\npub const MM_MOTIONPIXELS_MVI2: u32 = 1u32;\npub const MM_MOTOROLA: u32 = 48u32;\npub const MM_MOTU: u32 = 101u32;\npub const MM_MOTU_DTX_MIDI_IN_A: u32 = 801u32;\npub const MM_MOTU_DTX_MIDI_IN_B: u32 = 802u32;\npub const MM_MOTU_DTX_MIDI_IN_SYNC: u32 = 800u32;\npub const MM_MOTU_DTX_MIDI_OUT_A: u32 = 801u32;\npub const MM_MOTU_DTX_MIDI_OUT_B: u32 = 802u32;\npub const MM_MOTU_FLYER_MIDI_IN_A: u32 = 601u32;\npub const MM_MOTU_FLYER_MIDI_IN_B: u32 = 602u32;\npub const MM_MOTU_FLYER_MIDI_IN_SYNC: u32 = 600u32;\npub const MM_MOTU_FLYER_MIDI_OUT_A: u32 = 601u32;\npub const MM_MOTU_FLYER_MIDI_OUT_B: u32 = 602u32;\npub const MM_MOTU_MTPAV_MIDIIN_1: u32 = 901u32;\npub const MM_MOTU_MTPAV_MIDIIN_2: u32 = 902u32;\npub const MM_MOTU_MTPAV_MIDIIN_3: u32 = 903u32;\npub const MM_MOTU_MTPAV_MIDIIN_4: u32 = 904u32;\npub const MM_MOTU_MTPAV_MIDIIN_5: u32 = 905u32;\npub const MM_MOTU_MTPAV_MIDIIN_6: u32 = 906u32;\npub const MM_MOTU_MTPAV_MIDIIN_7: u32 = 907u32;\npub const MM_MOTU_MTPAV_MIDIIN_8: u32 = 908u32;\npub const MM_MOTU_MTPAV_MIDIIN_ADAT: u32 = 917u32;\npub const MM_MOTU_MTPAV_MIDIIN_SYNC: u32 = 900u32;\npub const MM_MOTU_MTPAV_MIDIOUT_1: u32 = 901u32;\npub const MM_MOTU_MTPAV_MIDIOUT_2: u32 = 902u32;\npub const MM_MOTU_MTPAV_MIDIOUT_3: u32 = 903u32;\npub const MM_MOTU_MTPAV_MIDIOUT_4: u32 = 904u32;\npub const MM_MOTU_MTPAV_MIDIOUT_5: u32 = 905u32;\npub const MM_MOTU_MTPAV_MIDIOUT_6: u32 = 906u32;\npub const MM_MOTU_MTPAV_MIDIOUT_7: u32 = 907u32;\npub const MM_MOTU_MTPAV_MIDIOUT_8: u32 = 908u32;\npub const MM_MOTU_MTPAV_MIDIOUT_ADAT: u32 = 917u32;\npub const MM_MOTU_MTPAV_MIDIOUT_ALL: u32 = 900u32;\npub const MM_MOTU_MTPAV_NET_MIDIIN_1: u32 = 909u32;\npub const MM_MOTU_MTPAV_NET_MIDIIN_2: u32 = 910u32;\npub const MM_MOTU_MTPAV_NET_MIDIIN_3: u32 = 911u32;\npub const MM_MOTU_MTPAV_NET_MIDIIN_4: u32 = 912u32;\npub const MM_MOTU_MTPAV_NET_MIDIIN_5: u32 = 913u32;\npub const MM_MOTU_MTPAV_NET_MIDIIN_6: u32 = 914u32;\npub const MM_MOTU_MTPAV_NET_MIDIIN_7: u32 = 915u32;\npub const MM_MOTU_MTPAV_NET_MIDIIN_8: u32 = 916u32;\npub const MM_MOTU_MTPAV_NET_MIDIOUT_1: u32 = 909u32;\npub const MM_MOTU_MTPAV_NET_MIDIOUT_2: u32 = 910u32;\npub const MM_MOTU_MTPAV_NET_MIDIOUT_3: u32 = 911u32;\npub const MM_MOTU_MTPAV_NET_MIDIOUT_4: u32 = 912u32;\npub const MM_MOTU_MTPAV_NET_MIDIOUT_5: u32 = 913u32;\npub const MM_MOTU_MTPAV_NET_MIDIOUT_6: u32 = 914u32;\npub const MM_MOTU_MTPAV_NET_MIDIOUT_7: u32 = 915u32;\npub const MM_MOTU_MTPAV_NET_MIDIOUT_8: u32 = 916u32;\npub const MM_MOTU_MTPII_MIDIIN_1: u32 = 201u32;\npub const MM_MOTU_MTPII_MIDIIN_2: u32 = 202u32;\npub const MM_MOTU_MTPII_MIDIIN_3: u32 = 203u32;\npub const MM_MOTU_MTPII_MIDIIN_4: u32 = 204u32;\npub const MM_MOTU_MTPII_MIDIIN_5: u32 = 205u32;\npub const MM_MOTU_MTPII_MIDIIN_6: u32 = 206u32;\npub const MM_MOTU_MTPII_MIDIIN_7: u32 = 207u32;\npub const MM_MOTU_MTPII_MIDIIN_8: u32 = 208u32;\npub const MM_MOTU_MTPII_MIDIIN_SYNC: u32 = 200u32;\npub const MM_MOTU_MTPII_MIDIOUT_1: u32 = 201u32;\npub const MM_MOTU_MTPII_MIDIOUT_2: u32 = 202u32;\npub const MM_MOTU_MTPII_MIDIOUT_3: u32 = 203u32;\npub const MM_MOTU_MTPII_MIDIOUT_4: u32 = 204u32;\npub const MM_MOTU_MTPII_MIDIOUT_5: u32 = 205u32;\npub const MM_MOTU_MTPII_MIDIOUT_6: u32 = 206u32;\npub const MM_MOTU_MTPII_MIDIOUT_7: u32 = 207u32;\npub const MM_MOTU_MTPII_MIDIOUT_8: u32 = 208u32;\npub const MM_MOTU_MTPII_MIDIOUT_ALL: u32 = 200u32;\npub const MM_MOTU_MTPII_NET_MIDIIN_1: u32 = 209u32;\npub const MM_MOTU_MTPII_NET_MIDIIN_2: u32 = 210u32;\npub const MM_MOTU_MTPII_NET_MIDIIN_3: u32 = 211u32;\npub const MM_MOTU_MTPII_NET_MIDIIN_4: u32 = 212u32;\npub const MM_MOTU_MTPII_NET_MIDIIN_5: u32 = 213u32;\npub const MM_MOTU_MTPII_NET_MIDIIN_6: u32 = 214u32;\npub const MM_MOTU_MTPII_NET_MIDIIN_7: u32 = 215u32;\npub const MM_MOTU_MTPII_NET_MIDIIN_8: u32 = 216u32;\npub const MM_MOTU_MTPII_NET_MIDIOUT_1: u32 = 209u32;\npub const MM_MOTU_MTPII_NET_MIDIOUT_2: u32 = 210u32;\npub const MM_MOTU_MTPII_NET_MIDIOUT_3: u32 = 211u32;\npub const MM_MOTU_MTPII_NET_MIDIOUT_4: u32 = 212u32;\npub const MM_MOTU_MTPII_NET_MIDIOUT_5: u32 = 213u32;\npub const MM_MOTU_MTPII_NET_MIDIOUT_6: u32 = 214u32;\npub const MM_MOTU_MTPII_NET_MIDIOUT_7: u32 = 215u32;\npub const MM_MOTU_MTPII_NET_MIDIOUT_8: u32 = 216u32;\npub const MM_MOTU_MTP_MIDIIN_1: u32 = 101u32;\npub const MM_MOTU_MTP_MIDIIN_2: u32 = 102u32;\npub const MM_MOTU_MTP_MIDIIN_3: u32 = 103u32;\npub const MM_MOTU_MTP_MIDIIN_4: u32 = 104u32;\npub const MM_MOTU_MTP_MIDIIN_5: u32 = 105u32;\npub const MM_MOTU_MTP_MIDIIN_6: u32 = 106u32;\npub const MM_MOTU_MTP_MIDIIN_7: u32 = 107u32;\npub const MM_MOTU_MTP_MIDIIN_8: u32 = 108u32;\npub const MM_MOTU_MTP_MIDIOUT_1: u32 = 101u32;\npub const MM_MOTU_MTP_MIDIOUT_2: u32 = 102u32;\npub const MM_MOTU_MTP_MIDIOUT_3: u32 = 103u32;\npub const MM_MOTU_MTP_MIDIOUT_4: u32 = 104u32;\npub const MM_MOTU_MTP_MIDIOUT_5: u32 = 105u32;\npub const MM_MOTU_MTP_MIDIOUT_6: u32 = 106u32;\npub const MM_MOTU_MTP_MIDIOUT_7: u32 = 107u32;\npub const MM_MOTU_MTP_MIDIOUT_8: u32 = 108u32;\npub const MM_MOTU_MTP_MIDIOUT_ALL: u32 = 100u32;\npub const MM_MOTU_MXN_MIDIIN_1: u32 = 501u32;\npub const MM_MOTU_MXN_MIDIIN_2: u32 = 502u32;\npub const MM_MOTU_MXN_MIDIIN_3: u32 = 503u32;\npub const MM_MOTU_MXN_MIDIIN_4: u32 = 504u32;\npub const MM_MOTU_MXN_MIDIIN_SYNC: u32 = 500u32;\npub const MM_MOTU_MXN_MIDIOUT_1: u32 = 501u32;\npub const MM_MOTU_MXN_MIDIOUT_2: u32 = 502u32;\npub const MM_MOTU_MXN_MIDIOUT_3: u32 = 503u32;\npub const MM_MOTU_MXN_MIDIOUT_4: u32 = 504u32;\npub const MM_MOTU_MXN_MIDIOUT_ALL: u32 = 500u32;\npub const MM_MOTU_MXPMPU_MIDIIN_1: u32 = 401u32;\npub const MM_MOTU_MXPMPU_MIDIIN_2: u32 = 402u32;\npub const MM_MOTU_MXPMPU_MIDIIN_3: u32 = 403u32;\npub const MM_MOTU_MXPMPU_MIDIIN_4: u32 = 404u32;\npub const MM_MOTU_MXPMPU_MIDIIN_5: u32 = 405u32;\npub const MM_MOTU_MXPMPU_MIDIIN_6: u32 = 406u32;\npub const MM_MOTU_MXPMPU_MIDIIN_SYNC: u32 = 400u32;\npub const MM_MOTU_MXPMPU_MIDIOUT_1: u32 = 401u32;\npub const MM_MOTU_MXPMPU_MIDIOUT_2: u32 = 402u32;\npub const MM_MOTU_MXPMPU_MIDIOUT_3: u32 = 403u32;\npub const MM_MOTU_MXPMPU_MIDIOUT_4: u32 = 404u32;\npub const MM_MOTU_MXPMPU_MIDIOUT_5: u32 = 405u32;\npub const MM_MOTU_MXPMPU_MIDIOUT_6: u32 = 406u32;\npub const MM_MOTU_MXPMPU_MIDIOUT_ALL: u32 = 400u32;\npub const MM_MOTU_MXPXT_MIDIIN_1: u32 = 1001u32;\npub const MM_MOTU_MXPXT_MIDIIN_2: u32 = 1002u32;\npub const MM_MOTU_MXPXT_MIDIIN_3: u32 = 1003u32;\npub const MM_MOTU_MXPXT_MIDIIN_4: u32 = 1004u32;\npub const MM_MOTU_MXPXT_MIDIIN_5: u32 = 1005u32;\npub const MM_MOTU_MXPXT_MIDIIN_6: u32 = 1006u32;\npub const MM_MOTU_MXPXT_MIDIIN_7: u32 = 1007u32;\npub const MM_MOTU_MXPXT_MIDIIN_8: u32 = 1008u32;\npub const MM_MOTU_MXPXT_MIDIIN_SYNC: u32 = 1000u32;\npub const MM_MOTU_MXPXT_MIDIOUT_1: u32 = 1001u32;\npub const MM_MOTU_MXPXT_MIDIOUT_2: u32 = 1002u32;\npub const MM_MOTU_MXPXT_MIDIOUT_3: u32 = 1003u32;\npub const MM_MOTU_MXPXT_MIDIOUT_4: u32 = 1004u32;\npub const MM_MOTU_MXPXT_MIDIOUT_5: u32 = 1005u32;\npub const MM_MOTU_MXPXT_MIDIOUT_6: u32 = 1006u32;\npub const MM_MOTU_MXPXT_MIDIOUT_7: u32 = 1007u32;\npub const MM_MOTU_MXPXT_MIDIOUT_8: u32 = 1008u32;\npub const MM_MOTU_MXPXT_MIDIOUT_ALL: u32 = 1000u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIIN_1: u32 = 301u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIIN_2: u32 = 302u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIIN_3: u32 = 303u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIIN_4: u32 = 304u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIIN_5: u32 = 305u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIIN_6: u32 = 306u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIOUT_1: u32 = 301u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIOUT_2: u32 = 302u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIOUT_3: u32 = 303u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIOUT_4: u32 = 304u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIOUT_5: u32 = 305u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIOUT_6: u32 = 306u32;\npub const MM_MOTU_MXP_MIDIIN_MIDIOUT_ALL: u32 = 300u32;\npub const MM_MOTU_MXP_MIDIIN_SYNC: u32 = 300u32;\npub const MM_MOTU_PKX_MIDI_IN_A: u32 = 701u32;\npub const MM_MOTU_PKX_MIDI_IN_B: u32 = 702u32;\npub const MM_MOTU_PKX_MIDI_IN_SYNC: u32 = 700u32;\npub const MM_MOTU_PKX_MIDI_OUT_A: u32 = 701u32;\npub const MM_MOTU_PKX_MIDI_OUT_B: u32 = 702u32;\npub const MM_MPTUS: u32 = 95u32;\npub const MM_MPTUS_SPWAVEOUT: u32 = 1u32;\npub const MM_MSFT_ACM_G711: u32 = 37u32;\npub const MM_MSFT_ACM_GSM610: u32 = 36u32;\npub const MM_MSFT_ACM_IMAADPCM: u32 = 34u32;\npub const MM_MSFT_ACM_MSADPCM: u32 = 33u32;\npub const MM_MSFT_ACM_MSAUDIO1: u32 = 39u32;\npub const MM_MSFT_ACM_MSFILTER: u32 = 35u32;\npub const MM_MSFT_ACM_MSG723: u32 = 92u32;\npub const MM_MSFT_ACM_MSNAUDIO: u32 = 91u32;\npub const MM_MSFT_ACM_MSRT24: u32 = 93u32;\npub const MM_MSFT_ACM_PCM: u32 = 38u32;\npub const MM_MSFT_ACM_WMAUDIO: u32 = 39u32;\npub const MM_MSFT_ACM_WMAUDIO2: u32 = 101u32;\npub const MM_MSFT_GENERIC_AUX_CD: u32 = 30u32;\npub const MM_MSFT_GENERIC_AUX_LINE: u32 = 28u32;\npub const MM_MSFT_GENERIC_AUX_MIC: u32 = 29u32;\npub const MM_MSFT_GENERIC_MIDIIN: u32 = 25u32;\npub const MM_MSFT_GENERIC_MIDIOUT: u32 = 26u32;\npub const MM_MSFT_GENERIC_MIDISYNTH: u32 = 27u32;\npub const MM_MSFT_GENERIC_WAVEIN: u32 = 23u32;\npub const MM_MSFT_GENERIC_WAVEOUT: u32 = 24u32;\npub const MM_MSFT_MSACM: u32 = 32u32;\npub const MM_MSFT_MSOPL_SYNTH: u32 = 76u32;\npub const MM_MSFT_SB16_AUX_CD: u32 = 66u32;\npub const MM_MSFT_SB16_AUX_LINE: u32 = 65u32;\npub const MM_MSFT_SB16_MIDIIN: u32 = 62u32;\npub const MM_MSFT_SB16_MIDIOUT: u32 = 63u32;\npub const MM_MSFT_SB16_MIXER: u32 = 67u32;\npub const MM_MSFT_SB16_SYNTH: u32 = 64u32;\npub const MM_MSFT_SB16_WAVEIN: u32 = 60u32;\npub const MM_MSFT_SB16_WAVEOUT: u32 = 61u32;\npub const MM_MSFT_SBPRO_AUX_CD: u32 = 74u32;\npub const MM_MSFT_SBPRO_AUX_LINE: u32 = 73u32;\npub const MM_MSFT_SBPRO_MIDIIN: u32 = 70u32;\npub const MM_MSFT_SBPRO_MIDIOUT: u32 = 71u32;\npub const MM_MSFT_SBPRO_MIXER: u32 = 75u32;\npub const MM_MSFT_SBPRO_SYNTH: u32 = 72u32;\npub const MM_MSFT_SBPRO_WAVEIN: u32 = 68u32;\npub const MM_MSFT_SBPRO_WAVEOUT: u32 = 69u32;\npub const MM_MSFT_VMDMS_HANDSET_WAVEIN: u32 = 82u32;\npub const MM_MSFT_VMDMS_HANDSET_WAVEOUT: u32 = 83u32;\npub const MM_MSFT_VMDMS_LINE_WAVEIN: u32 = 80u32;\npub const MM_MSFT_VMDMS_LINE_WAVEOUT: u32 = 81u32;\npub const MM_MSFT_VMDMW_HANDSET_WAVEIN: u32 = 86u32;\npub const MM_MSFT_VMDMW_HANDSET_WAVEOUT: u32 = 87u32;\npub const MM_MSFT_VMDMW_LINE_WAVEIN: u32 = 84u32;\npub const MM_MSFT_VMDMW_LINE_WAVEOUT: u32 = 85u32;\npub const MM_MSFT_VMDMW_MIXER: u32 = 88u32;\npub const MM_MSFT_VMDM_GAME_WAVEIN: u32 = 90u32;\npub const MM_MSFT_VMDM_GAME_WAVEOUT: u32 = 89u32;\npub const MM_MSFT_WDMAUDIO_AUX: u32 = 105u32;\npub const MM_MSFT_WDMAUDIO_MIDIIN: u32 = 103u32;\npub const MM_MSFT_WDMAUDIO_MIDIOUT: u32 = 102u32;\npub const MM_MSFT_WDMAUDIO_MIXER: u32 = 104u32;\npub const MM_MSFT_WDMAUDIO_WAVEIN: u32 = 101u32;\npub const MM_MSFT_WDMAUDIO_WAVEOUT: u32 = 100u32;\npub const MM_MSFT_WSS_AUX: u32 = 21u32;\npub const MM_MSFT_WSS_FMSYNTH_STEREO: u32 = 16u32;\npub const MM_MSFT_WSS_MIXER: u32 = 17u32;\npub const MM_MSFT_WSS_NT_AUX: u32 = 59u32;\npub const MM_MSFT_WSS_NT_FMSYNTH_STEREO: u32 = 57u32;\npub const MM_MSFT_WSS_NT_MIXER: u32 = 58u32;\npub const MM_MSFT_WSS_NT_WAVEIN: u32 = 55u32;\npub const MM_MSFT_WSS_NT_WAVEOUT: u32 = 56u32;\npub const MM_MSFT_WSS_OEM_AUX: u32 = 22u32;\npub const MM_MSFT_WSS_OEM_FMSYNTH_STEREO: u32 = 20u32;\npub const MM_MSFT_WSS_OEM_MIXER: u32 = 31u32;\npub const MM_MSFT_WSS_OEM_WAVEIN: u32 = 18u32;\npub const MM_MSFT_WSS_OEM_WAVEOUT: u32 = 19u32;\npub const MM_MSFT_WSS_WAVEIN: u32 = 14u32;\npub const MM_MSFT_WSS_WAVEOUT: u32 = 15u32;\npub const MM_MWM: u32 = 209u32;\npub const MM_NCR: u32 = 62u32;\npub const MM_NCR_BA_AUX: u32 = 4u32;\npub const MM_NCR_BA_MIXER: u32 = 5u32;\npub const MM_NCR_BA_SYNTH: u32 = 3u32;\npub const MM_NCR_BA_WAVEIN: u32 = 1u32;\npub const MM_NCR_BA_WAVEOUT: u32 = 2u32;\npub const MM_NEC: u32 = 26u32;\npub const MM_NEC_26_SYNTH: u32 = 9u32;\npub const MM_NEC_73_86_SYNTH: u32 = 5u32;\npub const MM_NEC_73_86_WAVEIN: u32 = 7u32;\npub const MM_NEC_73_86_WAVEOUT: u32 = 6u32;\npub const MM_NEC_JOYSTICK: u32 = 12u32;\npub const MM_NEC_MPU401_MIDIIN: u32 = 11u32;\npub const MM_NEC_MPU401_MIDIOUT: u32 = 10u32;\npub const MM_NEOMAGIC: u32 = 176u32;\npub const MM_NEOMAGIC_AUX: u32 = 6u32;\npub const MM_NEOMAGIC_MIDIIN: u32 = 5u32;\npub const MM_NEOMAGIC_MIDIOUT: u32 = 4u32;\npub const MM_NEOMAGIC_MW3DX_AUX: u32 = 17u32;\npub const MM_NEOMAGIC_MW3DX_FMSYNTH: u32 = 14u32;\npub const MM_NEOMAGIC_MW3DX_GMSYNTH: u32 = 15u32;\npub const MM_NEOMAGIC_MW3DX_MIDIIN: u32 = 13u32;\npub const MM_NEOMAGIC_MW3DX_MIDIOUT: u32 = 12u32;\npub const MM_NEOMAGIC_MW3DX_MIXER: u32 = 16u32;\npub const MM_NEOMAGIC_MW3DX_WAVEIN: u32 = 11u32;\npub const MM_NEOMAGIC_MW3DX_WAVEOUT: u32 = 10u32;\npub const MM_NEOMAGIC_MWAVE_AUX: u32 = 25u32;\npub const MM_NEOMAGIC_MWAVE_MIDIIN: u32 = 23u32;\npub const MM_NEOMAGIC_MWAVE_MIDIOUT: u32 = 22u32;\npub const MM_NEOMAGIC_MWAVE_MIXER: u32 = 24u32;\npub const MM_NEOMAGIC_MWAVE_WAVEIN: u32 = 21u32;\npub const MM_NEOMAGIC_MWAVE_WAVEOUT: u32 = 20u32;\npub const MM_NEOMAGIC_SYNTH: u32 = 1u32;\npub const MM_NEOMAGIC_WAVEIN: u32 = 3u32;\npub const MM_NEOMAGIC_WAVEOUT: u32 = 2u32;\npub const MM_NETSCAPE: u32 = 166u32;\npub const MM_NETXL: u32 = 8u32;\npub const MM_NETXL_XLVIDEO: u32 = 1u32;\npub const MM_NEWMEDIA: u32 = 86u32;\npub const MM_NEWMEDIA_WAVJAMMER: u32 = 1u32;\npub const MM_NMP: u32 = 195u32;\npub const MM_NMP_ACM_AMR: u32 = 10u32;\npub const MM_NMP_CCP_WAVEIN: u32 = 1u32;\npub const MM_NMP_CCP_WAVEOUT: u32 = 2u32;\npub const MM_NMS: u32 = 87u32;\npub const MM_NOGATECH: u32 = 75u32;\npub const MM_NORRIS: u32 = 150u32;\npub const MM_NORRIS_VOICELINK: u32 = 1u32;\npub const MM_NORTEL_MPXAC_WAVEIN: u32 = 1u32;\npub const MM_NORTEL_MPXAC_WAVEOUT: u32 = 2u32;\npub const MM_NORTHERN_TELECOM: u32 = 115u32;\npub const MM_NVIDIA: u32 = 127u32;\npub const MM_NVIDIA_AUX: u32 = 7u32;\npub const MM_NVIDIA_GAMEPORT: u32 = 5u32;\npub const MM_NVIDIA_MIDIIN: u32 = 4u32;\npub const MM_NVIDIA_MIDIOUT: u32 = 3u32;\npub const MM_NVIDIA_MIXER: u32 = 6u32;\npub const MM_NVIDIA_WAVEIN: u32 = 2u32;\npub const MM_NVIDIA_WAVEOUT: u32 = 1u32;\npub const MM_OKI: u32 = 79u32;\npub const MM_OKSORI: u32 = 128u32;\npub const MM_OKSORI_BASE: u32 = 0u32;\npub const MM_OKSORI_EXT_MIC1: u32 = 15u32;\npub const MM_OKSORI_EXT_MIC2: u32 = 16u32;\npub const MM_OKSORI_FM_OPL4: u32 = 5u32;\npub const MM_OKSORI_MIDIIN: u32 = 18u32;\npub const MM_OKSORI_MIDIOUT: u32 = 17u32;\npub const MM_OKSORI_MIX_AUX1: u32 = 13u32;\npub const MM_OKSORI_MIX_CD: u32 = 10u32;\npub const MM_OKSORI_MIX_ECHO: u32 = 12u32;\npub const MM_OKSORI_MIX_FM: u32 = 8u32;\npub const MM_OKSORI_MIX_LINE: u32 = 9u32;\npub const MM_OKSORI_MIX_LINE1: u32 = 14u32;\npub const MM_OKSORI_MIX_MASTER: u32 = 6u32;\npub const MM_OKSORI_MIX_MIC: u32 = 11u32;\npub const MM_OKSORI_MIX_WAVE: u32 = 7u32;\npub const MM_OKSORI_MPEG_CDVISION: u32 = 19u32;\npub const MM_OKSORI_OSR16_WAVEIN: u32 = 4u32;\npub const MM_OKSORI_OSR16_WAVEOUT: u32 = 3u32;\npub const MM_OKSORI_OSR8_WAVEIN: u32 = 2u32;\npub const MM_OKSORI_OSR8_WAVEOUT: u32 = 1u32;\npub const MM_OLIVETTI: u32 = 81u32;\npub const MM_OLIVETTI_ACM_ADPCM: u32 = 10u32;\npub const MM_OLIVETTI_ACM_CELP: u32 = 11u32;\npub const MM_OLIVETTI_ACM_GSM: u32 = 9u32;\npub const MM_OLIVETTI_ACM_OPR: u32 = 13u32;\npub const MM_OLIVETTI_ACM_SBC: u32 = 12u32;\npub const MM_OLIVETTI_AUX: u32 = 4u32;\npub const MM_OLIVETTI_JOYSTICK: u32 = 8u32;\npub const MM_OLIVETTI_MIDIIN: u32 = 5u32;\npub const MM_OLIVETTI_MIDIOUT: u32 = 6u32;\npub const MM_OLIVETTI_MIXER: u32 = 3u32;\npub const MM_OLIVETTI_SYNTH: u32 = 7u32;\npub const MM_OLIVETTI_WAVEIN: u32 = 1u32;\npub const MM_OLIVETTI_WAVEOUT: u32 = 2u32;\npub const MM_ONLIVE: u32 = 200u32;\npub const MM_ONLIVE_MPCODEC: u32 = 1u32;\npub const MM_OPCODE: u32 = 113u32;\npub const MM_OPTI: u32 = 90u32;\npub const MM_OPTI_M16_AUX: u32 = 7u32;\npub const MM_OPTI_M16_FMSYNTH_STEREO: u32 = 1u32;\npub const MM_OPTI_M16_MIDIIN: u32 = 2u32;\npub const MM_OPTI_M16_MIDIOUT: u32 = 3u32;\npub const MM_OPTI_M16_MIXER: u32 = 6u32;\npub const MM_OPTI_M16_WAVEIN: u32 = 4u32;\npub const MM_OPTI_M16_WAVEOUT: u32 = 5u32;\npub const MM_OPTI_M32_AUX: u32 = 38u32;\npub const MM_OPTI_M32_MIDIIN: u32 = 34u32;\npub const MM_OPTI_M32_MIDIOUT: u32 = 35u32;\npub const MM_OPTI_M32_MIXER: u32 = 37u32;\npub const MM_OPTI_M32_SYNTH_STEREO: u32 = 36u32;\npub const MM_OPTI_M32_WAVEIN: u32 = 32u32;\npub const MM_OPTI_M32_WAVEOUT: u32 = 33u32;\npub const MM_OPTI_P16_AUX: u32 = 22u32;\npub const MM_OPTI_P16_FMSYNTH_STEREO: u32 = 16u32;\npub const MM_OPTI_P16_MIDIIN: u32 = 17u32;\npub const MM_OPTI_P16_MIDIOUT: u32 = 18u32;\npub const MM_OPTI_P16_MIXER: u32 = 21u32;\npub const MM_OPTI_P16_WAVEIN: u32 = 19u32;\npub const MM_OPTI_P16_WAVEOUT: u32 = 20u32;\npub const MM_OPUS1208_AUX: u32 = 135u32;\npub const MM_OPUS1208_MIXER: u32 = 134u32;\npub const MM_OPUS1208_SYNTH: u32 = 131u32;\npub const MM_OPUS1208_WAVEIN: u32 = 133u32;\npub const MM_OPUS1208_WAVEOUT: u32 = 132u32;\npub const MM_OPUS1216_AUX: u32 = 151u32;\npub const MM_OPUS1216_MIDIIN: u32 = 146u32;\npub const MM_OPUS1216_MIDIOUT: u32 = 145u32;\npub const MM_OPUS1216_MIXER: u32 = 150u32;\npub const MM_OPUS1216_SYNTH: u32 = 147u32;\npub const MM_OPUS1216_WAVEIN: u32 = 149u32;\npub const MM_OPUS1216_WAVEOUT: u32 = 148u32;\npub const MM_OPUS401_MIDIIN: u32 = 130u32;\npub const MM_OPUS401_MIDIOUT: u32 = 129u32;\npub const MM_OSITECH: u32 = 103u32;\npub const MM_OSITECH_TRUMPCARD: u32 = 1u32;\npub const MM_OSPREY: u32 = 140u32;\npub const MM_OSPREY_1000WAVEIN: u32 = 1u32;\npub const MM_OSPREY_1000WAVEOUT: u32 = 2u32;\npub const MM_OTI: u32 = 180u32;\npub const MM_OTI_611MIDIN: u32 = 18u32;\npub const MM_OTI_611MIDIOUT: u32 = 19u32;\npub const MM_OTI_611MIXER: u32 = 7u32;\npub const MM_OTI_611WAVEIN: u32 = 5u32;\npub const MM_OTI_611WAVEOUT: u32 = 6u32;\npub const MM_PACIFICRESEARCH: u32 = 210u32;\npub const MM_PCSPEAKER_WAVEOUT: u32 = 13u32;\npub const MM_PHILIPS_ACM_LPCBB: u32 = 1u32;\npub const MM_PHILIPS_SPEECH_PROCESSING: u32 = 7u32;\npub const MM_PHONET: u32 = 203u32;\npub const MM_PHONET_PP_MIXER: u32 = 3u32;\npub const MM_PHONET_PP_WAVEIN: u32 = 2u32;\npub const MM_PHONET_PP_WAVEOUT: u32 = 1u32;\npub const MM_PICTURETEL: u32 = 138u32;\npub const MM_PID_UNMAPPED: u32 = 65535u32;\npub const MM_PINNACLE: u32 = 218u32;\npub const MM_PRAGMATRAX: u32 = 5u32;\npub const MM_PRECEPT: u32 = 153u32;\npub const MM_PROAUD_16_AUX: u32 = 103u32;\npub const MM_PROAUD_16_MIDIIN: u32 = 98u32;\npub const MM_PROAUD_16_MIDIOUT: u32 = 97u32;\npub const MM_PROAUD_16_MIXER: u32 = 102u32;\npub const MM_PROAUD_16_SYNTH: u32 = 99u32;\npub const MM_PROAUD_16_WAVEIN: u32 = 101u32;\npub const MM_PROAUD_16_WAVEOUT: u32 = 100u32;\npub const MM_PROAUD_AUX: u32 = 23u32;\npub const MM_PROAUD_MIDIIN: u32 = 18u32;\npub const MM_PROAUD_MIDIOUT: u32 = 17u32;\npub const MM_PROAUD_MIXER: u32 = 22u32;\npub const MM_PROAUD_PLUS_AUX: u32 = 87u32;\npub const MM_PROAUD_PLUS_MIDIIN: u32 = 82u32;\npub const MM_PROAUD_PLUS_MIDIOUT: u32 = 81u32;\npub const MM_PROAUD_PLUS_MIXER: u32 = 86u32;\npub const MM_PROAUD_PLUS_SYNTH: u32 = 83u32;\npub const MM_PROAUD_PLUS_WAVEIN: u32 = 85u32;\npub const MM_PROAUD_PLUS_WAVEOUT: u32 = 84u32;\npub const MM_PROAUD_SYNTH: u32 = 19u32;\npub const MM_PROAUD_WAVEIN: u32 = 21u32;\npub const MM_PROAUD_WAVEOUT: u32 = 20u32;\npub const MM_QCIAR: u32 = 98u32;\npub const MM_QDESIGN: u32 = 194u32;\npub const MM_QDESIGN_ACM_MPEG: u32 = 1u32;\npub const MM_QDESIGN_ACM_QDESIGN_MUSIC: u32 = 2u32;\npub const MM_QTEAM: u32 = 169u32;\npub const MM_QUALCOMM: u32 = 215u32;\npub const MM_QUANTUM3D: u32 = 17u32;\npub const MM_QUARTERDECK: u32 = 134u32;\npub const MM_QUARTERDECK_LHWAVEIN: u32 = 0u32;\npub const MM_QUARTERDECK_LHWAVEOUT: u32 = 1u32;\npub const MM_QUICKAUDIO: u32 = 255u32;\npub const MM_QUICKAUDIO_MAXIMIDI: u32 = 2u32;\npub const MM_QUICKAUDIO_MINIMIDI: u32 = 1u32;\npub const MM_QUICKNET: u32 = 173u32;\npub const MM_QUICKNET_PJWAVEIN: u32 = 1u32;\npub const MM_QUICKNET_PJWAVEOUT: u32 = 2u32;\npub const MM_RADIUS: u32 = 110u32;\npub const MM_RHETOREX: u32 = 120u32;\npub const MM_RHETOREX_WAVEIN: u32 = 1u32;\npub const MM_RHETOREX_WAVEOUT: u32 = 2u32;\npub const MM_RICHMOND: u32 = 257u32;\npub const MM_ROCKWELL: u32 = 111u32;\npub const MM_ROLAND: u32 = 24u32;\npub const MM_ROLAND_MPU401_MIDIIN: u32 = 16u32;\npub const MM_ROLAND_MPU401_MIDIOUT: u32 = 15u32;\npub const MM_ROLAND_RAP10_MIDIIN: u32 = 11u32;\npub const MM_ROLAND_RAP10_MIDIOUT: u32 = 10u32;\npub const MM_ROLAND_RAP10_SYNTH: u32 = 12u32;\npub const MM_ROLAND_RAP10_WAVEIN: u32 = 14u32;\npub const MM_ROLAND_RAP10_WAVEOUT: u32 = 13u32;\npub const MM_ROLAND_SC7_MIDIIN: u32 = 22u32;\npub const MM_ROLAND_SC7_MIDIOUT: u32 = 21u32;\npub const MM_ROLAND_SCP_AUX: u32 = 48u32;\npub const MM_ROLAND_SCP_MIDIIN: u32 = 39u32;\npub const MM_ROLAND_SCP_MIDIOUT: u32 = 38u32;\npub const MM_ROLAND_SCP_MIXER: u32 = 42u32;\npub const MM_ROLAND_SCP_WAVEIN: u32 = 41u32;\npub const MM_ROLAND_SCP_WAVEOUT: u32 = 40u32;\npub const MM_ROLAND_SERIAL_MIDIIN: u32 = 24u32;\npub const MM_ROLAND_SERIAL_MIDIOUT: u32 = 23u32;\npub const MM_ROLAND_SMPU_MIDIINA: u32 = 19u32;\npub const MM_ROLAND_SMPU_MIDIINB: u32 = 20u32;\npub const MM_ROLAND_SMPU_MIDIOUTA: u32 = 17u32;\npub const MM_ROLAND_SMPU_MIDIOUTB: u32 = 18u32;\npub const MM_RZS: u32 = 216u32;\npub const MM_RZS_ACM_TUBGSM: u32 = 1u32;\npub const MM_S3: u32 = 164u32;\npub const MM_S3_AUX: u32 = 7u32;\npub const MM_S3_FMSYNTH: u32 = 5u32;\npub const MM_S3_MIDIIN: u32 = 4u32;\npub const MM_S3_MIDIOUT: u32 = 3u32;\npub const MM_S3_MIXER: u32 = 6u32;\npub const MM_S3_WAVEIN: u32 = 2u32;\npub const MM_S3_WAVEOUT: u32 = 1u32;\npub const MM_SANYO: u32 = 72u32;\npub const MM_SANYO_ACM_LD_ADPCM: u32 = 1u32;\npub const MM_SCALACS: u32 = 54u32;\npub const MM_SEERSYS: u32 = 137u32;\npub const MM_SEERSYS_REALITY: u32 = 6u32;\npub const MM_SEERSYS_SEERMIX: u32 = 3u32;\npub const MM_SEERSYS_SEERSYNTH: u32 = 1u32;\npub const MM_SEERSYS_SEERWAVE: u32 = 2u32;\npub const MM_SEERSYS_WAVESYNTH: u32 = 4u32;\npub const MM_SEERSYS_WAVESYNTH_WG: u32 = 5u32;\npub const MM_SELSIUS_SYSTEMS: u32 = 234u32;\npub const MM_SELSIUS_SYSTEMS_RTPWAVEIN: u32 = 2u32;\npub const MM_SELSIUS_SYSTEMS_RTPWAVEOUT: u32 = 1u32;\npub const MM_SGI: u32 = 237u32;\npub const MM_SGI_320_MIXER: u32 = 3u32;\npub const MM_SGI_320_WAVEIN: u32 = 1u32;\npub const MM_SGI_320_WAVEOUT: u32 = 2u32;\npub const MM_SGI_540_MIXER: u32 = 6u32;\npub const MM_SGI_540_WAVEIN: u32 = 4u32;\npub const MM_SGI_540_WAVEOUT: u32 = 5u32;\npub const MM_SGI_RAD_ADAT8CHAN_WAVEIN: u32 = 19u32;\npub const MM_SGI_RAD_ADAT8CHAN_WAVEOUT: u32 = 32u32;\npub const MM_SGI_RAD_ADATMONO1_WAVEIN: u32 = 7u32;\npub const MM_SGI_RAD_ADATMONO1_WAVEOUT: u32 = 20u32;\npub const MM_SGI_RAD_ADATMONO2_WAVEIN: u32 = 8u32;\npub const MM_SGI_RAD_ADATMONO2_WAVEOUT: u32 = 21u32;\npub const MM_SGI_RAD_ADATMONO3_WAVEIN: u32 = 9u32;\npub const MM_SGI_RAD_ADATMONO3_WAVEOUT: u32 = 22u32;\npub const MM_SGI_RAD_ADATMONO4_WAVEIN: u32 = 10u32;\npub const MM_SGI_RAD_ADATMONO4_WAVEOUT: u32 = 23u32;\npub const MM_SGI_RAD_ADATMONO5_WAVEIN: u32 = 11u32;\npub const MM_SGI_RAD_ADATMONO5_WAVEOUT: u32 = 24u32;\npub const MM_SGI_RAD_ADATMONO6_WAVEIN: u32 = 12u32;\npub const MM_SGI_RAD_ADATMONO6_WAVEOUT: u32 = 25u32;\npub const MM_SGI_RAD_ADATMONO7_WAVEIN: u32 = 13u32;\npub const MM_SGI_RAD_ADATMONO7_WAVEOUT: u32 = 26u32;\npub const MM_SGI_RAD_ADATMONO8_WAVEIN: u32 = 14u32;\npub const MM_SGI_RAD_ADATMONO8_WAVEOUT: u32 = 27u32;\npub const MM_SGI_RAD_ADATSTEREO12_WAVEIN: u32 = 15u32;\npub const MM_SGI_RAD_ADATSTEREO12_WAVEOUT: u32 = 28u32;\npub const MM_SGI_RAD_ADATSTEREO32_WAVEOUT: u32 = 29u32;\npub const MM_SGI_RAD_ADATSTEREO34_WAVEIN: u32 = 16u32;\npub const MM_SGI_RAD_ADATSTEREO56_WAVEIN: u32 = 17u32;\npub const MM_SGI_RAD_ADATSTEREO56_WAVEOUT: u32 = 30u32;\npub const MM_SGI_RAD_ADATSTEREO78_WAVEIN: u32 = 18u32;\npub const MM_SGI_RAD_ADATSTEREO78_WAVEOUT: u32 = 31u32;\npub const MM_SGI_RAD_AESMONO1_WAVEIN: u32 = 33u32;\npub const MM_SGI_RAD_AESMONO1_WAVEOUT: u32 = 36u32;\npub const MM_SGI_RAD_AESMONO2_WAVEIN: u32 = 34u32;\npub const MM_SGI_RAD_AESMONO2_WAVEOUT: u32 = 37u32;\npub const MM_SGI_RAD_AESSTEREO_WAVEIN: u32 = 35u32;\npub const MM_SGI_RAD_AESSTEREO_WAVEOUT: u32 = 38u32;\npub const MM_SHARP: u32 = 183u32;\npub const MM_SHARP_MDC_AUX: u32 = 6u32;\npub const MM_SHARP_MDC_AUX_BASS: u32 = 101u32;\npub const MM_SHARP_MDC_AUX_CHR: u32 = 109u32;\npub const MM_SHARP_MDC_AUX_MASTER: u32 = 100u32;\npub const MM_SHARP_MDC_AUX_MIDI_VOL: u32 = 103u32;\npub const MM_SHARP_MDC_AUX_RVB: u32 = 108u32;\npub const MM_SHARP_MDC_AUX_TREBLE: u32 = 102u32;\npub const MM_SHARP_MDC_AUX_VOL: u32 = 107u32;\npub const MM_SHARP_MDC_AUX_WAVE_CHR: u32 = 106u32;\npub const MM_SHARP_MDC_AUX_WAVE_RVB: u32 = 105u32;\npub const MM_SHARP_MDC_AUX_WAVE_VOL: u32 = 104u32;\npub const MM_SHARP_MDC_MIDI_IN: u32 = 2u32;\npub const MM_SHARP_MDC_MIDI_OUT: u32 = 3u32;\npub const MM_SHARP_MDC_MIDI_SYNTH: u32 = 1u32;\npub const MM_SHARP_MDC_MIXER: u32 = 10u32;\npub const MM_SHARP_MDC_WAVE_IN: u32 = 4u32;\npub const MM_SHARP_MDC_WAVE_OUT: u32 = 5u32;\npub const MM_SICRESOURCE: u32 = 175u32;\npub const MM_SICRESOURCE_SSO3D: u32 = 2u32;\npub const MM_SICRESOURCE_SSOW3DI: u32 = 3u32;\npub const MM_SIEMENS_SBC: u32 = 201u32;\npub const MM_SIERRA: u32 = 40u32;\npub const MM_SIERRA_ARIA_AUX: u32 = 25u32;\npub const MM_SIERRA_ARIA_AUX2: u32 = 32u32;\npub const MM_SIERRA_ARIA_MIDIIN: u32 = 21u32;\npub const MM_SIERRA_ARIA_MIDIOUT: u32 = 20u32;\npub const MM_SIERRA_ARIA_SYNTH: u32 = 22u32;\npub const MM_SIERRA_ARIA_WAVEIN: u32 = 24u32;\npub const MM_SIERRA_ARIA_WAVEOUT: u32 = 23u32;\npub const MM_SIERRA_QUARTET_AUX_CD: u32 = 85u32;\npub const MM_SIERRA_QUARTET_AUX_LINE: u32 = 86u32;\npub const MM_SIERRA_QUARTET_AUX_MODEM: u32 = 87u32;\npub const MM_SIERRA_QUARTET_MIDIIN: u32 = 82u32;\npub const MM_SIERRA_QUARTET_MIDIOUT: u32 = 83u32;\npub const MM_SIERRA_QUARTET_MIXER: u32 = 88u32;\npub const MM_SIERRA_QUARTET_SYNTH: u32 = 84u32;\npub const MM_SIERRA_QUARTET_WAVEIN: u32 = 80u32;\npub const MM_SIERRA_QUARTET_WAVEOUT: u32 = 81u32;\npub const MM_SILICONSOFT: u32 = 69u32;\npub const MM_SILICONSOFT_SC1_WAVEIN: u32 = 1u32;\npub const MM_SILICONSOFT_SC1_WAVEOUT: u32 = 2u32;\npub const MM_SILICONSOFT_SC2_WAVEIN: u32 = 3u32;\npub const MM_SILICONSOFT_SC2_WAVEOUT: u32 = 4u32;\npub const MM_SILICONSOFT_SOUNDJR2PR_WAVEIN: u32 = 6u32;\npub const MM_SILICONSOFT_SOUNDJR2PR_WAVEOUT: u32 = 7u32;\npub const MM_SILICONSOFT_SOUNDJR2_WAVEOUT: u32 = 5u32;\npub const MM_SILICONSOFT_SOUNDJR3_WAVEOUT: u32 = 8u32;\npub const MM_SIPROLAB: u32 = 211u32;\npub const MM_SIPROLAB_ACELPNET: u32 = 1u32;\npub const MM_SNI: u32 = 18u32;\npub const MM_SNI_ACM_G721: u32 = 1u32;\npub const MM_SOFTLAB_NSK: u32 = 228u32;\npub const MM_SOFTLAB_NSK_FRW_AUX: u32 = 4u32;\npub const MM_SOFTLAB_NSK_FRW_MIXER: u32 = 3u32;\npub const MM_SOFTLAB_NSK_FRW_WAVEIN: u32 = 1u32;\npub const MM_SOFTLAB_NSK_FRW_WAVEOUT: u32 = 2u32;\npub const MM_SOFTSOUND: u32 = 149u32;\npub const MM_SOFTSOUND_CODEC: u32 = 1u32;\npub const MM_SONICFOUNDRY: u32 = 66u32;\npub const MM_SONORUS: u32 = 230u32;\npub const MM_SONORUS_STUDIO: u32 = 1u32;\npub const MM_SONY: u32 = 245u32;\npub const MM_SONY_ACM_SCX: u32 = 1u32;\npub const MM_SORVIS: u32 = 187u32;\npub const MM_SOUNDESIGNS: u32 = 142u32;\npub const MM_SOUNDESIGNS_WAVEIN: u32 = 1u32;\npub const MM_SOUNDESIGNS_WAVEOUT: u32 = 2u32;\npub const MM_SOUNDSCAPE_AUX: u32 = 24u32;\npub const MM_SOUNDSCAPE_MIDIIN: u32 = 21u32;\npub const MM_SOUNDSCAPE_MIDIOUT: u32 = 20u32;\npub const MM_SOUNDSCAPE_MIXER: u32 = 23u32;\npub const MM_SOUNDSCAPE_SYNTH: u32 = 22u32;\npub const MM_SOUNDSCAPE_WAVEIN: u32 = 19u32;\npub const MM_SOUNDSCAPE_WAVEOUT: u32 = 17u32;\npub const MM_SOUNDSCAPE_WAVEOUT_AUX: u32 = 18u32;\npub const MM_SOUNDSPACE: u32 = 167u32;\npub const MM_SPECTRUM_PRODUCTIONS: u32 = 213u32;\npub const MM_SPECTRUM_SIGNAL_PROCESSING: u32 = 144u32;\npub const MM_SPEECHCOMP: u32 = 76u32;\npub const MM_SPLASH_STUDIOS: u32 = 133u32;\npub const MM_SSP_SNDFESAUX: u32 = 7u32;\npub const MM_SSP_SNDFESMIDIIN: u32 = 3u32;\npub const MM_SSP_SNDFESMIDIOUT: u32 = 4u32;\npub const MM_SSP_SNDFESMIX: u32 = 6u32;\npub const MM_SSP_SNDFESSYNTH: u32 = 5u32;\npub const MM_SSP_SNDFESWAVEIN: u32 = 1u32;\npub const MM_SSP_SNDFESWAVEOUT: u32 = 2u32;\npub const MM_STUDER: u32 = 171u32;\npub const MM_STUDIO_16_AUX: u32 = 103u32;\npub const MM_STUDIO_16_MIDIIN: u32 = 98u32;\npub const MM_STUDIO_16_MIDIOUT: u32 = 97u32;\npub const MM_STUDIO_16_MIXER: u32 = 102u32;\npub const MM_STUDIO_16_SYNTH: u32 = 99u32;\npub const MM_STUDIO_16_WAVEIN: u32 = 101u32;\npub const MM_STUDIO_16_WAVEOUT: u32 = 100u32;\npub const MM_ST_MICROELECTRONICS: u32 = 265u32;\npub const MM_SUNCOM: u32 = 186u32;\npub const MM_SUPERMAC: u32 = 73u32;\npub const MM_SYDEC_NV: u32 = 248u32;\npub const MM_SYDEC_NV_WAVEIN: u32 = 1u32;\npub const MM_SYDEC_NV_WAVEOUT: u32 = 2u32;\npub const MM_TANDY: u32 = 29u32;\npub const MM_TANDY_PSSJWAVEIN: u32 = 9u32;\npub const MM_TANDY_PSSJWAVEOUT: u32 = 10u32;\npub const MM_TANDY_SENS_MMAMIDIIN: u32 = 6u32;\npub const MM_TANDY_SENS_MMAMIDIOUT: u32 = 7u32;\npub const MM_TANDY_SENS_MMAWAVEIN: u32 = 4u32;\npub const MM_TANDY_SENS_MMAWAVEOUT: u32 = 5u32;\npub const MM_TANDY_SENS_VISWAVEOUT: u32 = 8u32;\npub const MM_TANDY_VISBIOSSYNTH: u32 = 3u32;\npub const MM_TANDY_VISWAVEIN: u32 = 1u32;\npub const MM_TANDY_VISWAVEOUT: u32 = 2u32;\npub const MM_TBS_TROPEZ_AUX1: u32 = 39u32;\npub const MM_TBS_TROPEZ_AUX2: u32 = 40u32;\npub const MM_TBS_TROPEZ_LINE: u32 = 41u32;\npub const MM_TBS_TROPEZ_WAVEIN: u32 = 37u32;\npub const MM_TBS_TROPEZ_WAVEOUT: u32 = 38u32;\npub const MM_TDK: u32 = 135u32;\npub const MM_TDK_MW_AUX: u32 = 6u32;\npub const MM_TDK_MW_AUX_BASS: u32 = 101u32;\npub const MM_TDK_MW_AUX_CHR: u32 = 109u32;\npub const MM_TDK_MW_AUX_MASTER: u32 = 100u32;\npub const MM_TDK_MW_AUX_MIDI_VOL: u32 = 103u32;\npub const MM_TDK_MW_AUX_RVB: u32 = 108u32;\npub const MM_TDK_MW_AUX_TREBLE: u32 = 102u32;\npub const MM_TDK_MW_AUX_VOL: u32 = 107u32;\npub const MM_TDK_MW_AUX_WAVE_CHR: u32 = 106u32;\npub const MM_TDK_MW_AUX_WAVE_RVB: u32 = 105u32;\npub const MM_TDK_MW_AUX_WAVE_VOL: u32 = 104u32;\npub const MM_TDK_MW_MIDI_IN: u32 = 2u32;\npub const MM_TDK_MW_MIDI_OUT: u32 = 3u32;\npub const MM_TDK_MW_MIDI_SYNTH: u32 = 1u32;\npub const MM_TDK_MW_MIXER: u32 = 10u32;\npub const MM_TDK_MW_WAVE_IN: u32 = 4u32;\npub const MM_TDK_MW_WAVE_OUT: u32 = 5u32;\npub const MM_TELEKOL: u32 = 264u32;\npub const MM_TELEKOL_WAVEIN: u32 = 2u32;\npub const MM_TELEKOL_WAVEOUT: u32 = 1u32;\npub const MM_TERALOGIC: u32 = 202u32;\npub const MM_TERRATEC: u32 = 70u32;\npub const MM_THUNDER_AUX: u32 = 39u32;\npub const MM_THUNDER_SYNTH: u32 = 35u32;\npub const MM_THUNDER_WAVEIN: u32 = 37u32;\npub const MM_THUNDER_WAVEOUT: u32 = 36u32;\npub const MM_TPORT_SYNTH: u32 = 67u32;\npub const MM_TPORT_WAVEIN: u32 = 66u32;\npub const MM_TPORT_WAVEOUT: u32 = 65u32;\npub const MM_TRUEVISION: u32 = 51u32;\npub const MM_TRUEVISION_WAVEIN1: u32 = 1u32;\npub const MM_TRUEVISION_WAVEOUT1: u32 = 2u32;\npub const MM_TTEWS_AUX: u32 = 9u32;\npub const MM_TTEWS_MIDIIN: u32 = 3u32;\npub const MM_TTEWS_MIDIMONITOR: u32 = 6u32;\npub const MM_TTEWS_MIDIOUT: u32 = 4u32;\npub const MM_TTEWS_MIDISYNTH: u32 = 5u32;\npub const MM_TTEWS_MIXER: u32 = 10u32;\npub const MM_TTEWS_VMIDIIN: u32 = 7u32;\npub const MM_TTEWS_VMIDIOUT: u32 = 8u32;\npub const MM_TTEWS_WAVEIN: u32 = 1u32;\npub const MM_TTEWS_WAVEOUT: u32 = 2u32;\npub const MM_TURTLE_BEACH: u32 = 21u32;\npub const MM_UHER_INFORMATIC: u32 = 247u32;\npub const MM_UH_ACM_ADPCM: u32 = 1u32;\npub const MM_UNISYS: u32 = 223u32;\npub const MM_UNISYS_ACM_NAP: u32 = 1u32;\npub const MM_UNMAPPED: u32 = 65535u32;\npub const MM_VAL: u32 = 35u32;\npub const MM_VAL_MICROKEY_AP_WAVEIN: u32 = 1u32;\npub const MM_VAL_MICROKEY_AP_WAVEOUT: u32 = 2u32;\npub const MM_VANKOEVERING: u32 = 168u32;\npub const MM_VIA: u32 = 250u32;\npub const MM_VIA_AUX: u32 = 4u32;\npub const MM_VIA_MIXER: u32 = 3u32;\npub const MM_VIA_MPU401_MIDIIN: u32 = 6u32;\npub const MM_VIA_MPU401_MIDIOUT: u32 = 5u32;\npub const MM_VIA_SWFM_SYNTH: u32 = 7u32;\npub const MM_VIA_WAVEIN: u32 = 2u32;\npub const MM_VIA_WAVEOUT: u32 = 1u32;\npub const MM_VIA_WDM_MIXER: u32 = 10u32;\npub const MM_VIA_WDM_MPU401_MIDIIN: u32 = 12u32;\npub const MM_VIA_WDM_MPU401_MIDIOUT: u32 = 11u32;\npub const MM_VIA_WDM_WAVEIN: u32 = 9u32;\npub const MM_VIA_WDM_WAVEOUT: u32 = 8u32;\npub const MM_VIDEOLOGIC: u32 = 53u32;\npub const MM_VIDEOLOGIC_MSWAVEIN: u32 = 1u32;\npub const MM_VIDEOLOGIC_MSWAVEOUT: u32 = 2u32;\npub const MM_VIENNASYS: u32 = 157u32;\npub const MM_VIENNASYS_TSP_WAVE_DRIVER: u32 = 1u32;\npub const MM_VIONA: u32 = 161u32;\npub const MM_VIONAQVINPCI_WAVEOUT: u32 = 3u32;\npub const MM_VIONA_BUSTER_MIXER: u32 = 4u32;\npub const MM_VIONA_CINEMASTER_MIXER: u32 = 5u32;\npub const MM_VIONA_CONCERTO_MIXER: u32 = 6u32;\npub const MM_VIONA_QVINPCI_MIXER: u32 = 1u32;\npub const MM_VIONA_QVINPCI_WAVEIN: u32 = 2u32;\npub const MM_VIRTUALMUSIC: u32 = 205u32;\npub const MM_VITEC: u32 = 67u32;\npub const MM_VITEC_VMAKER: u32 = 1u32;\npub const MM_VITEC_VMPRO: u32 = 2u32;\npub const MM_VIVO: u32 = 182u32;\npub const MM_VIVO_AUDIO_CODEC: u32 = 1u32;\npub const MM_VKC_MPU401_MIDIIN: u32 = 256u32;\npub const MM_VKC_MPU401_MIDIOUT: u32 = 512u32;\npub const MM_VKC_SERIAL_MIDIIN: u32 = 257u32;\npub const MM_VKC_SERIAL_MIDIOUT: u32 = 513u32;\npub const MM_VOCALTEC: u32 = 23u32;\npub const MM_VOCALTEC_WAVEIN: u32 = 2u32;\npub const MM_VOCALTEC_WAVEOUT: u32 = 1u32;\npub const MM_VOICEINFO: u32 = 156u32;\npub const MM_VOICEMIXER: u32 = 1u32;\npub const MM_VOXWARE: u32 = 114u32;\npub const MM_VOXWARE_CODEC: u32 = 1u32;\npub const MM_VOYETRA: u32 = 30u32;\npub const MM_VQST: u32 = 240u32;\npub const MM_VQST_VQC1: u32 = 1u32;\npub const MM_VQST_VQC2: u32 = 2u32;\npub const MM_VTG: u32 = 109u32;\npub const MM_WANGLABS: u32 = 28u32;\npub const MM_WANGLABS_WAVEIN1: u32 = 1u32;\npub const MM_WANGLABS_WAVEOUT1: u32 = 2u32;\npub const MM_WEITEK: u32 = 96u32;\npub const MM_WILDCAT: u32 = 119u32;\npub const MM_WILDCAT_AUTOSCOREMIDIIN: u32 = 1u32;\npub const MM_WILLOPOND_SNDCOMM_WAVEIN: u32 = 108u32;\npub const MM_WILLOWPOND: u32 = 65u32;\npub const MM_WILLOWPOND_FMSYNTH_STEREO: u32 = 20u32;\npub const MM_WILLOWPOND_GENERIC_AUX: u32 = 115u32;\npub const MM_WILLOWPOND_GENERIC_MIXER: u32 = 114u32;\npub const MM_WILLOWPOND_GENERIC_WAVEIN: u32 = 112u32;\npub const MM_WILLOWPOND_GENERIC_WAVEOUT: u32 = 113u32;\npub const MM_WILLOWPOND_MPU401: u32 = 21u32;\npub const MM_WILLOWPOND_PH_AUX: u32 = 107u32;\npub const MM_WILLOWPOND_PH_MIXER: u32 = 106u32;\npub const MM_WILLOWPOND_PH_WAVEIN: u32 = 104u32;\npub const MM_WILLOWPOND_PH_WAVEOUT: u32 = 105u32;\npub const MM_WILLOWPOND_SNDCOMM_AUX: u32 = 111u32;\npub const MM_WILLOWPOND_SNDCOMM_MIXER: u32 = 110u32;\npub const MM_WILLOWPOND_SNDCOMM_WAVEOUT: u32 = 109u32;\npub const MM_WILLOWPOND_SNDPORT_AUX: u32 = 103u32;\npub const MM_WILLOWPOND_SNDPORT_MIXER: u32 = 102u32;\npub const MM_WILLOWPOND_SNDPORT_WAVEIN: u32 = 100u32;\npub const MM_WILLOWPOND_SNDPORT_WAVEOUT: u32 = 101u32;\npub const MM_WINBOND: u32 = 204u32;\npub const MM_WINNOV: u32 = 61u32;\npub const MM_WINNOV_CAVIAR_CHAMPAGNE: u32 = 4u32;\npub const MM_WINNOV_CAVIAR_VIDC: u32 = 3u32;\npub const MM_WINNOV_CAVIAR_WAVEIN: u32 = 1u32;\npub const MM_WINNOV_CAVIAR_WAVEOUT: u32 = 2u32;\npub const MM_WINNOV_CAVIAR_YUV8: u32 = 5u32;\npub const MM_WORKBIT: u32 = 102u32;\npub const MM_WORKBIT_AUX: u32 = 7u32;\npub const MM_WORKBIT_FMSYNTH: u32 = 6u32;\npub const MM_WORKBIT_JOYSTICK: u32 = 8u32;\npub const MM_WORKBIT_MIDIIN: u32 = 4u32;\npub const MM_WORKBIT_MIDIOUT: u32 = 5u32;\npub const MM_WORKBIT_MIXER: u32 = 1u32;\npub const MM_WORKBIT_WAVEIN: u32 = 3u32;\npub const MM_WORKBIT_WAVEOUT: u32 = 2u32;\npub const MM_WSS_SB16_AUX_CD: u32 = 45u32;\npub const MM_WSS_SB16_AUX_LINE: u32 = 44u32;\npub const MM_WSS_SB16_MIDIIN: u32 = 41u32;\npub const MM_WSS_SB16_MIDIOUT: u32 = 42u32;\npub const MM_WSS_SB16_MIXER: u32 = 46u32;\npub const MM_WSS_SB16_SYNTH: u32 = 43u32;\npub const MM_WSS_SB16_WAVEIN: u32 = 39u32;\npub const MM_WSS_SB16_WAVEOUT: u32 = 40u32;\npub const MM_WSS_SBPRO_AUX_CD: u32 = 53u32;\npub const MM_WSS_SBPRO_AUX_LINE: u32 = 52u32;\npub const MM_WSS_SBPRO_MIDIIN: u32 = 49u32;\npub const MM_WSS_SBPRO_MIDIOUT: u32 = 50u32;\npub const MM_WSS_SBPRO_MIXER: u32 = 54u32;\npub const MM_WSS_SBPRO_SYNTH: u32 = 51u32;\npub const MM_WSS_SBPRO_WAVEIN: u32 = 47u32;\npub const MM_WSS_SBPRO_WAVEOUT: u32 = 48u32;\npub const MM_XEBEC: u32 = 85u32;\npub const MM_XIRLINK: u32 = 178u32;\npub const MM_XIRLINK_VISIONLINK: u32 = 1u32;\npub const MM_XYZ: u32 = 112u32;\npub const MM_YAMAHA: u32 = 37u32;\npub const MM_YAMAHA_ACXG_AUX: u32 = 41u32;\npub const MM_YAMAHA_ACXG_MIDIOUT: u32 = 39u32;\npub const MM_YAMAHA_ACXG_MIXER: u32 = 40u32;\npub const MM_YAMAHA_ACXG_WAVEIN: u32 = 37u32;\npub const MM_YAMAHA_ACXG_WAVEOUT: u32 = 38u32;\npub const MM_YAMAHA_GSS_AUX: u32 = 6u32;\npub const MM_YAMAHA_GSS_MIDIIN: u32 = 5u32;\npub const MM_YAMAHA_GSS_MIDIOUT: u32 = 4u32;\npub const MM_YAMAHA_GSS_SYNTH: u32 = 1u32;\npub const MM_YAMAHA_GSS_WAVEIN: u32 = 3u32;\npub const MM_YAMAHA_GSS_WAVEOUT: u32 = 2u32;\npub const MM_YAMAHA_OPL3SA_FMSYNTH: u32 = 18u32;\npub const MM_YAMAHA_OPL3SA_JOYSTICK: u32 = 24u32;\npub const MM_YAMAHA_OPL3SA_MIDIIN: u32 = 21u32;\npub const MM_YAMAHA_OPL3SA_MIDIOUT: u32 = 20u32;\npub const MM_YAMAHA_OPL3SA_MIXER: u32 = 23u32;\npub const MM_YAMAHA_OPL3SA_WAVEIN: u32 = 17u32;\npub const MM_YAMAHA_OPL3SA_WAVEOUT: u32 = 16u32;\npub const MM_YAMAHA_OPL3SA_YSYNTH: u32 = 19u32;\npub const MM_YAMAHA_SERIAL_MIDIIN: u32 = 8u32;\npub const MM_YAMAHA_SERIAL_MIDIOUT: u32 = 7u32;\npub const MM_YAMAHA_SXG_MIDIOUT: u32 = 34u32;\npub const MM_YAMAHA_SXG_MIXER: u32 = 36u32;\npub const MM_YAMAHA_SXG_WAVEOUT: u32 = 35u32;\npub const MM_YAMAHA_YMF724LEG_FMSYNTH: u32 = 32u32;\npub const MM_YAMAHA_YMF724LEG_MIDIIN: u32 = 26u32;\npub const MM_YAMAHA_YMF724LEG_MIDIOUT: u32 = 25u32;\npub const MM_YAMAHA_YMF724LEG_MIXER: u32 = 33u32;\npub const MM_YAMAHA_YMF724_AUX: u32 = 30u32;\npub const MM_YAMAHA_YMF724_MIDIOUT: u32 = 29u32;\npub const MM_YAMAHA_YMF724_MIXER: u32 = 31u32;\npub const MM_YAMAHA_YMF724_WAVEIN: u32 = 28u32;\npub const MM_YAMAHA_YMF724_WAVEOUT: u32 = 27u32;\npub const MM_YOUCOM: u32 = 256u32;\npub const MM_ZEFIRO: u32 = 170u32;\npub const MM_ZEFIRO_ZA2: u32 = 2u32;\npub const MM_ZYXEL: u32 = 9u32;\npub const MM_ZYXEL_ACM_ADPCM: u32 = 1u32;\npub const MODM_CACHEDRUMPATCHES: u32 = 13u32;\npub const MODM_CACHEPATCHES: u32 = 12u32;\npub const MODM_CLOSE: u32 = 4u32;\npub const MODM_DATA: u32 = 7u32;\npub const MODM_GETDEVCAPS: u32 = 2u32;\npub const MODM_GETNUMDEVS: u32 = 1u32;\npub const MODM_GETPOS: u32 = 17u32;\npub const MODM_GETVOLUME: u32 = 10u32;\npub const MODM_INIT: u32 = 100u32;\npub const MODM_INIT_EX: u32 = 104u32;\npub const MODM_LONGDATA: u32 = 8u32;\npub const MODM_MAPPER: u32 = 8192u32;\npub const MODM_OPEN: u32 = 3u32;\npub const MODM_PAUSE: u32 = 18u32;\npub const MODM_PREFERRED: u32 = 22u32;\npub const MODM_PREPARE: u32 = 5u32;\npub const MODM_PROPERTIES: u32 = 21u32;\npub const MODM_RECONFIGURE: u32 = 18280u32;\npub const MODM_RESET: u32 = 9u32;\npub const MODM_RESTART: u32 = 19u32;\npub const MODM_SETVOLUME: u32 = 11u32;\npub const MODM_STOP: u32 = 20u32;\npub const MODM_STRMDATA: u32 = 14u32;\npub const MODM_UNPREPARE: u32 = 6u32;\npub const MODM_USER: u32 = 16384u32;\npub const MPEGLAYER3_ID_CONSTANTFRAMESIZE: u32 = 2u32;\npub const MPEGLAYER3_ID_MPEG: u32 = 1u32;\npub const MPEGLAYER3_ID_UNKNOWN: u32 = 0u32;\npub const MPEGLAYER3_WFX_EXTRA_BYTES: u32 = 12u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct MSAUDIO1WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n    pub wEncodeOptions: u16,\n}\npub const MSAUDIO1_BITS_PER_SAMPLE: u32 = 16u32;\npub const MSAUDIO1_MAX_CHANNELS: u32 = 2u32;\npub const MXDM_BASE: u32 = 1u32;\npub const MXDM_CLOSE: u32 = 4u32;\npub const MXDM_GETCONTROLDETAILS: u32 = 7u32;\npub const MXDM_GETDEVCAPS: u32 = 2u32;\npub const MXDM_GETLINECONTROLS: u32 = 6u32;\npub const MXDM_GETLINEINFO: u32 = 5u32;\npub const MXDM_GETNUMDEVS: u32 = 1u32;\npub const MXDM_INIT: u32 = 100u32;\npub const MXDM_INIT_EX: u32 = 104u32;\npub const MXDM_OPEN: u32 = 3u32;\npub const MXDM_SETCONTROLDETAILS: u32 = 8u32;\npub const MXDM_USER: u32 = 16384u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct NMS_VBXADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wSamplesPerBlock: u16,\n}\npub const NS_DRM_E_MIGRATION_IMAGE_ALREADY_EXISTS: windows_sys::core::HRESULT = 0xC00D278E_u32 as _;\npub const NS_DRM_E_MIGRATION_SOURCE_MACHINE_IN_USE: windows_sys::core::HRESULT = 0xC00D278C_u32 as _;\npub const NS_DRM_E_MIGRATION_TARGET_MACHINE_LESS_THAN_LH: windows_sys::core::HRESULT = 0xC00D278D_u32 as _;\npub const NS_DRM_E_MIGRATION_UPGRADE_WITH_DIFF_SID: windows_sys::core::HRESULT = 0xC00D278B_u32 as _;\npub const NS_E_8BIT_WAVE_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D0BCE_u32 as _;\npub const NS_E_ACTIVE_SG_DEVICE_CONTROL_DISCONNECTED: windows_sys::core::HRESULT = 0xC00D1BA6_u32 as _;\npub const NS_E_ACTIVE_SG_DEVICE_DISCONNECTED: windows_sys::core::HRESULT = 0xC00D1BA5_u32 as _;\npub const NS_E_ADVANCEDEDIT_TOO_MANY_PICTURES: windows_sys::core::HRESULT = 0xC00D136A_u32 as _;\npub const NS_E_ALLOCATE_FILE_FAIL: windows_sys::core::HRESULT = 0xC00D0061_u32 as _;\npub const NS_E_ALL_PROTOCOLS_DISABLED: windows_sys::core::HRESULT = 0xC00D2EEB_u32 as _;\npub const NS_E_ALREADY_CONNECTED: windows_sys::core::HRESULT = 0xC00D0010_u32 as _;\npub const NS_E_ANALOG_VIDEO_PROTECTION_LEVEL_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D2907_u32 as _;\npub const NS_E_ARCHIVE_ABORT_DUE_TO_BCAST: windows_sys::core::HRESULT = 0xC00D158E_u32 as _;\npub const NS_E_ARCHIVE_FILENAME_NOTSET: windows_sys::core::HRESULT = 0xC00D1B79_u32 as _;\npub const NS_E_ARCHIVE_GAP_DETECTED: windows_sys::core::HRESULT = 0xC00D158F_u32 as _;\npub const NS_E_ARCHIVE_REACH_QUOTA: windows_sys::core::HRESULT = 0xC00D158D_u32 as _;\npub const NS_E_ARCHIVE_SAME_AS_INPUT: windows_sys::core::HRESULT = 0xC00D1B84_u32 as _;\npub const NS_E_ASSERT: windows_sys::core::HRESULT = 0xC00D00CB_u32 as _;\npub const NS_E_ASX_INVALIDFORMAT: windows_sys::core::HRESULT = 0xC00D1069_u32 as _;\npub const NS_E_ASX_INVALIDVERSION: windows_sys::core::HRESULT = 0xC00D106A_u32 as _;\npub const NS_E_ASX_INVALID_REPEAT_BLOCK: windows_sys::core::HRESULT = 0xC00D106B_u32 as _;\npub const NS_E_ASX_NOTHING_TO_WRITE: windows_sys::core::HRESULT = 0xC00D106C_u32 as _;\npub const NS_E_ATTRIBUTE_NOT_ALLOWED: windows_sys::core::HRESULT = 0xC00D0BD7_u32 as _;\npub const NS_E_ATTRIBUTE_READ_ONLY: windows_sys::core::HRESULT = 0xC00D0BD6_u32 as _;\npub const NS_E_AUDIENCE_CONTENTTYPE_MISMATCH: windows_sys::core::HRESULT = 0xC00D1B99_u32 as _;\npub const NS_E_AUDIENCE__LANGUAGE_CONTENTTYPE_MISMATCH: windows_sys::core::HRESULT = 0xC00D1BE3_u32 as _;\npub const NS_E_AUDIODEVICE_BADFORMAT: windows_sys::core::HRESULT = 0xC00D1B63_u32 as _;\npub const NS_E_AUDIODEVICE_BUSY: windows_sys::core::HRESULT = 0xC00D1B61_u32 as _;\npub const NS_E_AUDIODEVICE_UNEXPECTED: windows_sys::core::HRESULT = 0xC00D1B62_u32 as _;\npub const NS_E_AUDIO_BITRATE_STEPDOWN: windows_sys::core::HRESULT = 0xC00D1BB9_u32 as _;\npub const NS_E_AUDIO_CODEC_ERROR: windows_sys::core::HRESULT = 0xC00D0BC3_u32 as _;\npub const NS_E_AUDIO_CODEC_NOT_INSTALLED: windows_sys::core::HRESULT = 0xC00D0BC2_u32 as _;\npub const NS_E_AUTHORIZATION_FILE_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D1590_u32 as _;\npub const NS_E_BACKUP_RESTORE_BAD_DATA: windows_sys::core::HRESULT = 0xC00D2745_u32 as _;\npub const NS_E_BACKUP_RESTORE_BAD_REQUEST_ID: windows_sys::core::HRESULT = 0xC00D272E_u32 as _;\npub const NS_E_BACKUP_RESTORE_FAILURE: windows_sys::core::HRESULT = 0xC00D272D_u32 as _;\npub const NS_E_BACKUP_RESTORE_TOO_MANY_RESETS: windows_sys::core::HRESULT = 0xC00D2766_u32 as _;\npub const NS_E_BAD_ADAPTER_ADDRESS: windows_sys::core::HRESULT = 0xC00D0039_u32 as _;\npub const NS_E_BAD_ADAPTER_NAME: windows_sys::core::HRESULT = 0xC00D00CC_u32 as _;\npub const NS_E_BAD_BLOCK0_VERSION: windows_sys::core::HRESULT = 0xC00D0063_u32 as _;\npub const NS_E_BAD_CONTENTEDL: windows_sys::core::HRESULT = 0xC00D1BAA_u32 as _;\npub const NS_E_BAD_CONTROL_DATA: windows_sys::core::HRESULT = 0xC00D0032_u32 as _;\npub const NS_E_BAD_CUB_UID: windows_sys::core::HRESULT = 0xC00D0192_u32 as _;\npub const NS_E_BAD_DELIVERY_MODE: windows_sys::core::HRESULT = 0xC00D003A_u32 as _;\npub const NS_E_BAD_DISK_UID: windows_sys::core::HRESULT = 0xC00D0064_u32 as _;\npub const NS_E_BAD_FSMAJOR_VERSION: windows_sys::core::HRESULT = 0xC00D0065_u32 as _;\npub const NS_E_BAD_MARKIN: windows_sys::core::HRESULT = 0xC00D1B58_u32 as _;\npub const NS_E_BAD_MARKOUT: windows_sys::core::HRESULT = 0xC00D1B59_u32 as _;\npub const NS_E_BAD_MULTICAST_ADDRESS: windows_sys::core::HRESULT = 0xC00D0038_u32 as _;\npub const NS_E_BAD_REQUEST: windows_sys::core::HRESULT = 0xC00D2EE3_u32 as _;\npub const NS_E_BAD_STAMPNUMBER: windows_sys::core::HRESULT = 0xC00D0066_u32 as _;\npub const NS_E_BAD_SYNTAX_IN_SERVER_RESPONSE: windows_sys::core::HRESULT = 0xC00D2EFE_u32 as _;\npub const NS_E_BKGDOWNLOAD_CALLFUNCENDED: windows_sys::core::HRESULT = 0xC00D1267_u32 as _;\npub const NS_E_BKGDOWNLOAD_CALLFUNCFAILED: windows_sys::core::HRESULT = 0xC00D1265_u32 as _;\npub const NS_E_BKGDOWNLOAD_CALLFUNCTIMEOUT: windows_sys::core::HRESULT = 0xC00D1266_u32 as _;\npub const NS_E_BKGDOWNLOAD_CANCELCOMPLETEDJOB: windows_sys::core::HRESULT = 0xC00D125F_u32 as _;\npub const NS_E_BKGDOWNLOAD_COMPLETECANCELLEDJOB: windows_sys::core::HRESULT = 0xC00D125E_u32 as _;\npub const NS_E_BKGDOWNLOAD_FAILEDINITIALIZE: windows_sys::core::HRESULT = 0xC00D1269_u32 as _;\npub const NS_E_BKGDOWNLOAD_FAILED_TO_CREATE_TEMPFILE: windows_sys::core::HRESULT = 0xC00D1262_u32 as _;\npub const NS_E_BKGDOWNLOAD_INVALIDJOBSIGNATURE: windows_sys::core::HRESULT = 0xC00D1261_u32 as _;\npub const NS_E_BKGDOWNLOAD_INVALID_FILE_NAME: windows_sys::core::HRESULT = 0xC00D126B_u32 as _;\npub const NS_E_BKGDOWNLOAD_NOJOBPOINTER: windows_sys::core::HRESULT = 0xC00D1260_u32 as _;\npub const NS_E_BKGDOWNLOAD_PLUGIN_FAILEDINITIALIZE: windows_sys::core::HRESULT = 0xC00D1263_u32 as _;\npub const NS_E_BKGDOWNLOAD_PLUGIN_FAILEDTOMOVEFILE: windows_sys::core::HRESULT = 0xC00D1264_u32 as _;\npub const NS_E_BKGDOWNLOAD_WMDUNPACKFAILED: windows_sys::core::HRESULT = 0xC00D1268_u32 as _;\npub const NS_E_BKGDOWNLOAD_WRONG_NO_FILES: windows_sys::core::HRESULT = 0xC00D125D_u32 as _;\npub const NS_E_BUSY: windows_sys::core::HRESULT = 0xC00D0025_u32 as _;\npub const NS_E_CACHE_ARCHIVE_CONFLICT: windows_sys::core::HRESULT = 0xC00D13EC_u32 as _;\npub const NS_E_CACHE_CANNOT_BE_CACHED: windows_sys::core::HRESULT = 0xC00D13F0_u32 as _;\npub const NS_E_CACHE_NOT_BROADCAST: windows_sys::core::HRESULT = 0xC00D13EF_u32 as _;\npub const NS_E_CACHE_NOT_MODIFIED: windows_sys::core::HRESULT = 0xC00D13F1_u32 as _;\npub const NS_E_CACHE_ORIGIN_SERVER_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D13ED_u32 as _;\npub const NS_E_CACHE_ORIGIN_SERVER_TIMEOUT: windows_sys::core::HRESULT = 0xC00D13EE_u32 as _;\npub const NS_E_CANNOTCONNECT: windows_sys::core::HRESULT = 0xC00D0006_u32 as _;\npub const NS_E_CANNOTCONNECTEVENTS: windows_sys::core::HRESULT = 0xC00D006F_u32 as _;\npub const NS_E_CANNOTDESTROYTITLE: windows_sys::core::HRESULT = 0xC00D0007_u32 as _;\npub const NS_E_CANNOTOFFLINEDISK: windows_sys::core::HRESULT = 0xC00D0009_u32 as _;\npub const NS_E_CANNOTONLINEDISK: windows_sys::core::HRESULT = 0xC00D000A_u32 as _;\npub const NS_E_CANNOTRENAMETITLE: windows_sys::core::HRESULT = 0xC00D0008_u32 as _;\npub const NS_E_CANNOT_BUY_OR_DOWNLOAD_CONTENT: windows_sys::core::HRESULT = 0xC00D1358_u32 as _;\npub const NS_E_CANNOT_BUY_OR_DOWNLOAD_FROM_MULTIPLE_SERVICES: windows_sys::core::HRESULT = 0xC00D1357_u32 as _;\npub const NS_E_CANNOT_CONNECT_TO_PROXY: windows_sys::core::HRESULT = 0xC00D2EEE_u32 as _;\npub const NS_E_CANNOT_DELETE_ACTIVE_SOURCEGROUP: windows_sys::core::HRESULT = 0xC00D1B60_u32 as _;\npub const NS_E_CANNOT_GENERATE_BROADCAST_INFO_FOR_QUALITYVBR: windows_sys::core::HRESULT = 0xC00D1BDF_u32 as _;\npub const NS_E_CANNOT_PAUSE_LIVEBROADCAST: windows_sys::core::HRESULT = 0xC00D1B8E_u32 as _;\npub const NS_E_CANNOT_READ_PLAYLIST_FROM_MEDIASERVER: windows_sys::core::HRESULT = 0xC00D2EF2_u32 as _;\npub const NS_E_CANNOT_REMOVE_PLUGIN: windows_sys::core::HRESULT = 0xC00D1451_u32 as _;\npub const NS_E_CANNOT_REMOVE_PUBLISHING_POINT: windows_sys::core::HRESULT = 0xC00D1450_u32 as _;\npub const NS_E_CANNOT_SYNC_DRM_TO_NON_JANUS_DEVICE: windows_sys::core::HRESULT = 0xC00D1246_u32 as _;\npub const NS_E_CANNOT_SYNC_PREVIOUS_SYNC_RUNNING: windows_sys::core::HRESULT = 0xC00D1247_u32 as _;\npub const NS_E_CANT_READ_DIGITAL: windows_sys::core::HRESULT = 0xC00D0FA1_u32 as _;\npub const NS_E_CCLINK_DOWN: windows_sys::core::HRESULT = 0xC00D0023_u32 as _;\npub const NS_E_CD_COPYTO_CD: windows_sys::core::HRESULT = 0xC00D0FAE_u32 as _;\npub const NS_E_CD_DRIVER_PROBLEM: windows_sys::core::HRESULT = 0xC00D0FB2_u32 as _;\npub const NS_E_CD_EMPTY_TRACK_QUEUE: windows_sys::core::HRESULT = 0xC00D11F9_u32 as _;\npub const NS_E_CD_ISRC_INVALID: windows_sys::core::HRESULT = 0xC00D11FB_u32 as _;\npub const NS_E_CD_MEDIA_CATALOG_NUMBER_INVALID: windows_sys::core::HRESULT = 0xC00D11FC_u32 as _;\npub const NS_E_CD_NO_BUFFERS_READ: windows_sys::core::HRESULT = 0xC00D11F8_u32 as _;\npub const NS_E_CD_NO_READER: windows_sys::core::HRESULT = 0xC00D11FA_u32 as _;\npub const NS_E_CD_QUEUEING_DISABLED: windows_sys::core::HRESULT = 0xC00D11FF_u32 as _;\npub const NS_E_CD_READ_ERROR: windows_sys::core::HRESULT = 0xC00D0FAC_u32 as _;\npub const NS_E_CD_READ_ERROR_NO_CORRECTION: windows_sys::core::HRESULT = 0xC00D0FAB_u32 as _;\npub const NS_E_CD_REFRESH: windows_sys::core::HRESULT = 0xC00D0FB1_u32 as _;\npub const NS_E_CD_SLOW_COPY: windows_sys::core::HRESULT = 0xC00D0FAD_u32 as _;\npub const NS_E_CD_SPEEDDETECT_NOT_ENOUGH_READS: windows_sys::core::HRESULT = 0xC00D11FE_u32 as _;\npub const NS_E_CHANGING_PROXYBYPASS: windows_sys::core::HRESULT = 0xC00D10C3_u32 as _;\npub const NS_E_CHANGING_PROXY_EXCEPTIONLIST: windows_sys::core::HRESULT = 0xC00D10C2_u32 as _;\npub const NS_E_CHANGING_PROXY_NAME: windows_sys::core::HRESULT = 0xC00D10C0_u32 as _;\npub const NS_E_CHANGING_PROXY_PORT: windows_sys::core::HRESULT = 0xC00D10C1_u32 as _;\npub const NS_E_CHANGING_PROXY_PROTOCOL_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D10C4_u32 as _;\npub const NS_E_CLOSED_ON_SUSPEND: windows_sys::core::HRESULT = 0xC00D2EF1_u32 as _;\npub const NS_E_CODEC_DMO_ERROR: windows_sys::core::HRESULT = 0xC00D0BDA_u32 as _;\npub const NS_E_CODEC_UNAVAILABLE: windows_sys::core::HRESULT = 0xC00D1B83_u32 as _;\npub const NS_E_COMPRESSED_DIGITAL_AUDIO_PROTECTION_LEVEL_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D2908_u32 as _;\npub const NS_E_COMPRESSED_DIGITAL_VIDEO_PROTECTION_LEVEL_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D2905_u32 as _;\npub const NS_E_CONNECTION_FAILURE: windows_sys::core::HRESULT = 0xC00D0029_u32 as _;\npub const NS_E_CONNECT_TIMEOUT: windows_sys::core::HRESULT = 0xC00D2F06_u32 as _;\npub const NS_E_CONTENT_PARTNER_STILL_INITIALIZING: windows_sys::core::HRESULT = 0xC00D1362_u32 as _;\npub const NS_E_CORECD_NOTAMEDIACD: windows_sys::core::HRESULT = 0xC00D10C7_u32 as _;\npub const NS_E_CRITICAL_ERROR: windows_sys::core::HRESULT = 0xC00D151C_u32 as _;\npub const NS_E_CUB_FAIL: windows_sys::core::HRESULT = 0xC00D0053_u32 as _;\npub const NS_E_CUB_FAIL_LINK: windows_sys::core::HRESULT = 0xC00D0190_u32 as _;\npub const NS_E_CURLHELPER_NOTADIRECTORY: windows_sys::core::HRESULT = 0xC00D132D_u32 as _;\npub const NS_E_CURLHELPER_NOTAFILE: windows_sys::core::HRESULT = 0xC00D132E_u32 as _;\npub const NS_E_CURLHELPER_NOTRELATIVE: windows_sys::core::HRESULT = 0xC00D1330_u32 as _;\npub const NS_E_CURL_CANTDECODE: windows_sys::core::HRESULT = 0xC00D132F_u32 as _;\npub const NS_E_CURL_CANTWALK: windows_sys::core::HRESULT = 0xC00D132B_u32 as _;\npub const NS_E_CURL_INVALIDBUFFERSIZE: windows_sys::core::HRESULT = 0xC00D1331_u32 as _;\npub const NS_E_CURL_INVALIDCHAR: windows_sys::core::HRESULT = 0xC00D1325_u32 as _;\npub const NS_E_CURL_INVALIDHOSTNAME: windows_sys::core::HRESULT = 0xC00D1326_u32 as _;\npub const NS_E_CURL_INVALIDPATH: windows_sys::core::HRESULT = 0xC00D1327_u32 as _;\npub const NS_E_CURL_INVALIDPORT: windows_sys::core::HRESULT = 0xC00D132C_u32 as _;\npub const NS_E_CURL_INVALIDSCHEME: windows_sys::core::HRESULT = 0xC00D1328_u32 as _;\npub const NS_E_CURL_INVALIDURL: windows_sys::core::HRESULT = 0xC00D1329_u32 as _;\npub const NS_E_CURL_NOTSAFE: windows_sys::core::HRESULT = 0xC00D1324_u32 as _;\npub const NS_E_DAMAGED_FILE: windows_sys::core::HRESULT = 0xC00D0FCB_u32 as _;\npub const NS_E_DATAPATH_NO_SINK: windows_sys::core::HRESULT = 0xC00D1518_u32 as _;\npub const NS_E_DATA_SOURCE_ENUMERATION_NOT_SUPPORTED: windows_sys::core::HRESULT = 0xC00D1580_u32 as _;\npub const NS_E_DATA_UNIT_EXTENSION_TOO_LARGE: windows_sys::core::HRESULT = 0xC00D0BD9_u32 as _;\npub const NS_E_DDRAW_GENERIC: windows_sys::core::HRESULT = 0xC00D10BD_u32 as _;\npub const NS_E_DEVCONTROL_FAILED_SEEK: windows_sys::core::HRESULT = 0xC00D1B94_u32 as _;\npub const NS_E_DEVICECONTROL_UNSTABLE: windows_sys::core::HRESULT = 0xC00D1BE1_u32 as _;\npub const NS_E_DEVICE_DISCONNECTED: windows_sys::core::HRESULT = 0xC00D0FA2_u32 as _;\npub const NS_E_DEVICE_IS_NOT_READY: windows_sys::core::HRESULT = 0xC00D1177_u32 as _;\npub const NS_E_DEVICE_NOT_READY: windows_sys::core::HRESULT = 0xC00D0FCA_u32 as _;\npub const NS_E_DEVICE_NOT_SUPPORT_FORMAT: windows_sys::core::HRESULT = 0xC00D0FA3_u32 as _;\npub const NS_E_DEVICE_NOT_WMDRM_DEVICE: windows_sys::core::HRESULT = 0xC00D277B_u32 as _;\npub const NS_E_DISK_FAIL: windows_sys::core::HRESULT = 0xC00D0055_u32 as _;\npub const NS_E_DISK_READ: windows_sys::core::HRESULT = 0xC00D0017_u32 as _;\npub const NS_E_DISK_WRITE: windows_sys::core::HRESULT = 0xC00D0016_u32 as _;\npub const NS_E_DISPLAY_MODE_CHANGE_FAILED: windows_sys::core::HRESULT = 0xC00D10BE_u32 as _;\npub const NS_E_DRMPROFILE_NOTFOUND: windows_sys::core::HRESULT = 0xC00D1BD5_u32 as _;\npub const NS_E_DRM_ACQUIRING_LICENSE: windows_sys::core::HRESULT = 0xC00D272B_u32 as _;\npub const NS_E_DRM_ACTION_NOT_QUERIED: windows_sys::core::HRESULT = 0xC00D272A_u32 as _;\npub const NS_E_DRM_ALREADY_INDIVIDUALIZED: windows_sys::core::HRESULT = 0xC00D2729_u32 as _;\npub const NS_E_DRM_APPCERT_REVOKED: windows_sys::core::HRESULT = 0xC00D2752_u32 as _;\npub const NS_E_DRM_ATTRIBUTE_TOO_LONG: windows_sys::core::HRESULT = 0xC00D28B2_u32 as _;\npub const NS_E_DRM_BACKUPRESTORE_BUSY: windows_sys::core::HRESULT = 0xC00D2744_u32 as _;\npub const NS_E_DRM_BACKUP_CORRUPT: windows_sys::core::HRESULT = 0xC00D2743_u32 as _;\npub const NS_E_DRM_BACKUP_EXISTS: windows_sys::core::HRESULT = 0xC00D2742_u32 as _;\npub const NS_E_DRM_BAD_REQUEST: windows_sys::core::HRESULT = 0xC00D28B0_u32 as _;\npub const NS_E_DRM_BB_UNABLE_TO_INITIALIZE: windows_sys::core::HRESULT = 0xC00D2780_u32 as _;\npub const NS_E_DRM_BUFFER_TOO_SMALL: windows_sys::core::HRESULT = 0xC00D275C_u32 as _;\npub const NS_E_DRM_BUSY: windows_sys::core::HRESULT = 0xC00D2841_u32 as _;\npub const NS_E_DRM_CACHED_CONTENT_ERROR: windows_sys::core::HRESULT = 0xC00D274B_u32 as _;\npub const NS_E_DRM_CERTIFICATE_REVOKED: windows_sys::core::HRESULT = 0xC00D28A1_u32 as _;\npub const NS_E_DRM_CERTIFICATE_SECURITY_LEVEL_INADEQUATE: windows_sys::core::HRESULT = 0xC00D28AE_u32 as _;\npub const NS_E_DRM_CHAIN_TOO_LONG: windows_sys::core::HRESULT = 0xC00D284C_u32 as _;\npub const NS_E_DRM_CHECKPOINT_CORRUPT: windows_sys::core::HRESULT = 0xC00D2797_u32 as _;\npub const NS_E_DRM_CHECKPOINT_FAILED: windows_sys::core::HRESULT = 0xC00D277F_u32 as _;\npub const NS_E_DRM_CHECKPOINT_MISMATCH: windows_sys::core::HRESULT = 0xC00D2796_u32 as _;\npub const NS_E_DRM_CLIENT_CODE_EXPIRED: windows_sys::core::HRESULT = 0xC00D2847_u32 as _;\npub const NS_E_DRM_DATASTORE_CORRUPT: windows_sys::core::HRESULT = 0xC00D2783_u32 as _;\npub const NS_E_DRM_DEBUGGING_NOT_ALLOWED: windows_sys::core::HRESULT = 0xC00D2767_u32 as _;\npub const NS_E_DRM_DECRYPT_ERROR: windows_sys::core::HRESULT = 0xC00D2723_u32 as _;\npub const NS_E_DRM_DEVICE_ACTIVATION_CANCELED: windows_sys::core::HRESULT = 0xC00D2765_u32 as _;\npub const NS_E_DRM_DEVICE_ALREADY_REGISTERED: windows_sys::core::HRESULT = 0xC00D28AB_u32 as _;\npub const NS_E_DRM_DEVICE_LIMIT_REACHED: windows_sys::core::HRESULT = 0xC00D28A3_u32 as _;\npub const NS_E_DRM_DEVICE_NOT_OPEN: windows_sys::core::HRESULT = 0xC00D28AA_u32 as _;\npub const NS_E_DRM_DEVICE_NOT_REGISTERED: windows_sys::core::HRESULT = 0xC00D27E2_u32 as _;\npub const NS_E_DRM_DRIVER_AUTH_FAILURE: windows_sys::core::HRESULT = 0xC00D274D_u32 as _;\npub const NS_E_DRM_DRIVER_DIGIOUT_FAILURE: windows_sys::core::HRESULT = 0xC00D2750_u32 as _;\npub const NS_E_DRM_DRMV2CLT_REVOKED: windows_sys::core::HRESULT = 0xC00D28B6_u32 as _;\npub const NS_E_DRM_ENCRYPT_ERROR: windows_sys::core::HRESULT = 0xC00D2722_u32 as _;\npub const NS_E_DRM_ENUM_LICENSE_FAILED: windows_sys::core::HRESULT = 0xC00D271B_u32 as _;\npub const NS_E_DRM_ERROR_BAD_NET_RESP: windows_sys::core::HRESULT = 0xC00D275E_u32 as _;\npub const NS_E_DRM_EXPIRED_LICENSEBLOB: windows_sys::core::HRESULT = 0xC00D28B3_u32 as _;\npub const NS_E_DRM_GET_CONTENTSTRING_ERROR: windows_sys::core::HRESULT = 0xC00D273D_u32 as _;\npub const NS_E_DRM_GET_LICENSESTRING_ERROR: windows_sys::core::HRESULT = 0xC00D273C_u32 as _;\npub const NS_E_DRM_GET_LICENSE_ERROR: windows_sys::core::HRESULT = 0xC00D2739_u32 as _;\npub const NS_E_DRM_HARDWAREID_MISMATCH: windows_sys::core::HRESULT = 0xC00D278F_u32 as _;\npub const NS_E_DRM_HARDWARE_INCONSISTENT: windows_sys::core::HRESULT = 0xC00D2754_u32 as _;\npub const NS_E_DRM_INCLUSION_LIST_REQUIRED: windows_sys::core::HRESULT = 0xC00D28B5_u32 as _;\npub const NS_E_DRM_INDIVIDUALIZATION_INCOMPLETE: windows_sys::core::HRESULT = 0xC00D274C_u32 as _;\npub const NS_E_DRM_INDIVIDUALIZE_ERROR: windows_sys::core::HRESULT = 0xC00D2736_u32 as _;\npub const NS_E_DRM_INDIVIDUALIZING: windows_sys::core::HRESULT = 0xC00D272C_u32 as _;\npub const NS_E_DRM_INDIV_FRAUD: windows_sys::core::HRESULT = 0xC00D2843_u32 as _;\npub const NS_E_DRM_INDIV_NO_CABS: windows_sys::core::HRESULT = 0xC00D2844_u32 as _;\npub const NS_E_DRM_INDIV_SERVICE_UNAVAILABLE: windows_sys::core::HRESULT = 0xC00D2845_u32 as _;\npub const NS_E_DRM_INVALID_APPCERT: windows_sys::core::HRESULT = 0xC00D277C_u32 as _;\npub const NS_E_DRM_INVALID_APPDATA: windows_sys::core::HRESULT = 0xC00D2740_u32 as _;\npub const NS_E_DRM_INVALID_APPDATA_VERSION: windows_sys::core::HRESULT = 0xC00D2741_u32 as _;\npub const NS_E_DRM_INVALID_APPLICATION: windows_sys::core::HRESULT = 0xC00D2711_u32 as _;\npub const NS_E_DRM_INVALID_CERTIFICATE: windows_sys::core::HRESULT = 0xC00D28A0_u32 as _;\npub const NS_E_DRM_INVALID_CONTENT: windows_sys::core::HRESULT = 0xC00D2716_u32 as _;\npub const NS_E_DRM_INVALID_CRL: windows_sys::core::HRESULT = 0xC00D28B1_u32 as _;\npub const NS_E_DRM_INVALID_DATA: windows_sys::core::HRESULT = 0xC00D2761_u32 as _;\npub const NS_E_DRM_INVALID_KID: windows_sys::core::HRESULT = 0xC00D2849_u32 as _;\npub const NS_E_DRM_INVALID_LICENSE: windows_sys::core::HRESULT = 0xC00D2718_u32 as _;\npub const NS_E_DRM_INVALID_LICENSEBLOB: windows_sys::core::HRESULT = 0xC00D28B4_u32 as _;\npub const NS_E_DRM_INVALID_LICENSE_ACQUIRED: windows_sys::core::HRESULT = 0xC00D271F_u32 as _;\npub const NS_E_DRM_INVALID_LICENSE_REQUEST: windows_sys::core::HRESULT = 0xC00D271C_u32 as _;\npub const NS_E_DRM_INVALID_MACHINE: windows_sys::core::HRESULT = 0xC00D2719_u32 as _;\npub const NS_E_DRM_INVALID_MIGRATION_IMAGE: windows_sys::core::HRESULT = 0xC00D2788_u32 as _;\npub const NS_E_DRM_INVALID_PROPERTY: windows_sys::core::HRESULT = 0xC00D2749_u32 as _;\npub const NS_E_DRM_INVALID_PROXIMITY_RESPONSE: windows_sys::core::HRESULT = 0xC00D28A8_u32 as _;\npub const NS_E_DRM_INVALID_SECURESTORE_PASSWORD: windows_sys::core::HRESULT = 0xC00D2751_u32 as _;\npub const NS_E_DRM_INVALID_SESSION: windows_sys::core::HRESULT = 0xC00D28A9_u32 as _;\npub const NS_E_DRM_KEY_ERROR: windows_sys::core::HRESULT = 0xC00D2721_u32 as _;\npub const NS_E_DRM_LICENSE_APPSECLOW: windows_sys::core::HRESULT = 0xC00D27DA_u32 as _;\npub const NS_E_DRM_LICENSE_APP_NOTALLOWED: windows_sys::core::HRESULT = 0xC00D27DD_u32 as _;\npub const NS_E_DRM_LICENSE_CERT_EXPIRED: windows_sys::core::HRESULT = 0xC00D27DF_u32 as _;\npub const NS_E_DRM_LICENSE_CLOSE_ERROR: windows_sys::core::HRESULT = 0xC00D2738_u32 as _;\npub const NS_E_DRM_LICENSE_CONTENT_REVOKED: windows_sys::core::HRESULT = 0xC00D27E1_u32 as _;\npub const NS_E_DRM_LICENSE_DELETION_ERROR: windows_sys::core::HRESULT = 0xC00D284E_u32 as _;\npub const NS_E_DRM_LICENSE_EXPIRED: windows_sys::core::HRESULT = 0xC00D27D8_u32 as _;\npub const NS_E_DRM_LICENSE_INITIALIZATION_ERROR: windows_sys::core::HRESULT = 0xC00D284A_u32 as _;\npub const NS_E_DRM_LICENSE_INVALID_XML: windows_sys::core::HRESULT = 0xC00D2725_u32 as _;\npub const NS_E_DRM_LICENSE_NOSAP: windows_sys::core::HRESULT = 0xC00D280A_u32 as _;\npub const NS_E_DRM_LICENSE_NOSVP: windows_sys::core::HRESULT = 0xC00D280B_u32 as _;\npub const NS_E_DRM_LICENSE_NOTACQUIRED: windows_sys::core::HRESULT = 0xC00D2759_u32 as _;\npub const NS_E_DRM_LICENSE_NOTENABLED: windows_sys::core::HRESULT = 0xC00D27D9_u32 as _;\npub const NS_E_DRM_LICENSE_NOTRUSTEDCODEC: windows_sys::core::HRESULT = 0xC00D280D_u32 as _;\npub const NS_E_DRM_LICENSE_NOWDM: windows_sys::core::HRESULT = 0xC00D280C_u32 as _;\npub const NS_E_DRM_LICENSE_OPEN_ERROR: windows_sys::core::HRESULT = 0xC00D2737_u32 as _;\npub const NS_E_DRM_LICENSE_SECLOW: windows_sys::core::HRESULT = 0xC00D27E0_u32 as _;\npub const NS_E_DRM_LICENSE_SERVER_INFO_MISSING: windows_sys::core::HRESULT = 0xC00D2840_u32 as _;\npub const NS_E_DRM_LICENSE_STORE_ERROR: windows_sys::core::HRESULT = 0xC00D2712_u32 as _;\npub const NS_E_DRM_LICENSE_STORE_SAVE_ERROR: windows_sys::core::HRESULT = 0xC00D2714_u32 as _;\npub const NS_E_DRM_LICENSE_UNAVAILABLE: windows_sys::core::HRESULT = 0xC00D28A2_u32 as _;\npub const NS_E_DRM_LICENSE_UNUSABLE: windows_sys::core::HRESULT = 0xC00D2748_u32 as _;\npub const NS_E_DRM_LIC_NEEDS_DEVICE_CLOCK_SET: windows_sys::core::HRESULT = 0xC00D2779_u32 as _;\npub const NS_E_DRM_MALFORMED_CONTENT_HEADER: windows_sys::core::HRESULT = 0xC00D279C_u32 as _;\npub const NS_E_DRM_MIGRATION_IMPORTER_NOT_AVAILABLE: windows_sys::core::HRESULT = 0xC00D278A_u32 as _;\npub const NS_E_DRM_MIGRATION_INVALID_LEGACYV2_DATA: windows_sys::core::HRESULT = 0xC00D2791_u32 as _;\npub const NS_E_DRM_MIGRATION_INVALID_LEGACYV2_SST_PASSWORD: windows_sys::core::HRESULT = 0xC00D2793_u32 as _;\npub const NS_E_DRM_MIGRATION_LICENSE_ALREADY_EXISTS: windows_sys::core::HRESULT = 0xC00D2792_u32 as _;\npub const NS_E_DRM_MIGRATION_NOT_SUPPORTED: windows_sys::core::HRESULT = 0xC00D2794_u32 as _;\npub const NS_E_DRM_MIGRATION_OBJECT_IN_USE: windows_sys::core::HRESULT = 0xC00D279B_u32 as _;\npub const NS_E_DRM_MIGRATION_OPERATION_CANCELLED: windows_sys::core::HRESULT = 0xC00D279A_u32 as _;\npub const NS_E_DRM_MIGRATION_TARGET_NOT_ONLINE: windows_sys::core::HRESULT = 0xC00D2787_u32 as _;\npub const NS_E_DRM_MIGRATION_TARGET_STATES_CORRUPTED: windows_sys::core::HRESULT = 0xC00D2789_u32 as _;\npub const NS_E_DRM_MONITOR_ERROR: windows_sys::core::HRESULT = 0xC00D273E_u32 as _;\npub const NS_E_DRM_MUST_APPROVE: windows_sys::core::HRESULT = 0xC00D28A6_u32 as _;\npub const NS_E_DRM_MUST_REGISTER: windows_sys::core::HRESULT = 0xC00D28A5_u32 as _;\npub const NS_E_DRM_MUST_REVALIDATE: windows_sys::core::HRESULT = 0xC00D28A7_u32 as _;\npub const NS_E_DRM_NEEDS_INDIVIDUALIZATION: windows_sys::core::HRESULT = 0xC00D2728_u32 as _;\npub const NS_E_DRM_NEEDS_UPGRADE_TEMPFILE: windows_sys::core::HRESULT = 0xC00D283D_u32 as _;\npub const NS_E_DRM_NEED_UPGRADE_MSSAP: windows_sys::core::HRESULT = 0xC00D274E_u32 as _;\npub const NS_E_DRM_NEED_UPGRADE_PD: windows_sys::core::HRESULT = 0xC00D283E_u32 as _;\npub const NS_E_DRM_NOT_CONFIGURED: windows_sys::core::HRESULT = 0xC00D2764_u32 as _;\npub const NS_E_DRM_NO_RIGHTS: windows_sys::core::HRESULT = 0xC00D2720_u32 as _;\npub const NS_E_DRM_NO_UPLINK_LICENSE: windows_sys::core::HRESULT = 0xC00D2848_u32 as _;\npub const NS_E_DRM_OPERATION_CANCELED: windows_sys::core::HRESULT = 0xC00D2768_u32 as _;\npub const NS_E_DRM_PARAMETERS_MISMATCHED: windows_sys::core::HRESULT = 0xC00D272F_u32 as _;\npub const NS_E_DRM_PASSWORD_TOO_LONG: windows_sys::core::HRESULT = 0xC00D1B93_u32 as _;\npub const NS_E_DRM_PD_TOO_MANY_DEVICES: windows_sys::core::HRESULT = 0xC00D2842_u32 as _;\npub const NS_E_DRM_POLICY_DISABLE_ONLINE: windows_sys::core::HRESULT = 0xC00D2762_u32 as _;\npub const NS_E_DRM_POLICY_METERING_DISABLED: windows_sys::core::HRESULT = 0xC00D2776_u32 as _;\npub const NS_E_DRM_PROFILE_NOT_SET: windows_sys::core::HRESULT = 0xC00D1B8F_u32 as _;\npub const NS_E_DRM_PROTOCOL_FORCEFUL_TERMINATION_ON_CHALLENGE: windows_sys::core::HRESULT = 0xC00D277E_u32 as _;\npub const NS_E_DRM_PROTOCOL_FORCEFUL_TERMINATION_ON_PETITION: windows_sys::core::HRESULT = 0xC00D277D_u32 as _;\npub const NS_E_DRM_QUERY_ERROR: windows_sys::core::HRESULT = 0xC00D273A_u32 as _;\npub const NS_E_DRM_REOPEN_CONTENT: windows_sys::core::HRESULT = 0xC00D274F_u32 as _;\npub const NS_E_DRM_REPORT_ERROR: windows_sys::core::HRESULT = 0xC00D273B_u32 as _;\npub const NS_E_DRM_RESTORE_FRAUD: windows_sys::core::HRESULT = 0xC00D2753_u32 as _;\npub const NS_E_DRM_RESTORE_SERVICE_UNAVAILABLE: windows_sys::core::HRESULT = 0xC00D2846_u32 as _;\npub const NS_E_DRM_RESTRICTIONS_NOT_RETRIEVED: windows_sys::core::HRESULT = 0xC00D2769_u32 as _;\npub const NS_E_DRM_RIV_TOO_SMALL: windows_sys::core::HRESULT = 0xC00D28B7_u32 as _;\npub const NS_E_DRM_SDK_VERSIONMISMATCH: windows_sys::core::HRESULT = 0xC00D2778_u32 as _;\npub const NS_E_DRM_SDMI_NOMORECOPIES: windows_sys::core::HRESULT = 0xC00D2756_u32 as _;\npub const NS_E_DRM_SDMI_TRIGGER: windows_sys::core::HRESULT = 0xC00D2755_u32 as _;\npub const NS_E_DRM_SECURE_STORE_ERROR: windows_sys::core::HRESULT = 0xC00D2713_u32 as _;\npub const NS_E_DRM_SECURE_STORE_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D274A_u32 as _;\npub const NS_E_DRM_SECURE_STORE_UNLOCK_ERROR: windows_sys::core::HRESULT = 0xC00D2715_u32 as _;\npub const NS_E_DRM_SECURITY_COMPONENT_SIGNATURE_INVALID: windows_sys::core::HRESULT = 0xC00D2760_u32 as _;\npub const NS_E_DRM_SIGNATURE_FAILURE: windows_sys::core::HRESULT = 0xC00D283F_u32 as _;\npub const NS_E_DRM_SOURCEID_NOT_SUPPORTED: windows_sys::core::HRESULT = 0xC00D280E_u32 as _;\npub const NS_E_DRM_STORE_NEEDINDI: windows_sys::core::HRESULT = 0xC00D27DB_u32 as _;\npub const NS_E_DRM_STORE_NOTALLOWED: windows_sys::core::HRESULT = 0xC00D27DC_u32 as _;\npub const NS_E_DRM_STORE_NOTALLSTORED: windows_sys::core::HRESULT = 0xC00D275F_u32 as _;\npub const NS_E_DRM_STUBLIB_REQUIRED: windows_sys::core::HRESULT = 0xC00D2785_u32 as _;\npub const NS_E_DRM_TRACK_EXCEEDED_PLAYLIST_RESTICTION: windows_sys::core::HRESULT = 0xC00D2770_u32 as _;\npub const NS_E_DRM_TRACK_EXCEEDED_TRACKBURN_RESTRICTION: windows_sys::core::HRESULT = 0xC00D2771_u32 as _;\npub const NS_E_DRM_TRANSFER_CHAINED_LICENSES_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D2777_u32 as _;\npub const NS_E_DRM_UNABLE_TO_ACQUIRE_LICENSE: windows_sys::core::HRESULT = 0xC00D271E_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_AUTHENTICATION_OBJECT: windows_sys::core::HRESULT = 0xC00D2763_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_BACKUP_OBJECT: windows_sys::core::HRESULT = 0xC00D2735_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_CERTIFICATE_OBJECT: windows_sys::core::HRESULT = 0xC00D2786_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_CODING_OBJECT: windows_sys::core::HRESULT = 0xC00D275A_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_DECRYPT_OBJECT: windows_sys::core::HRESULT = 0xC00D2733_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_DEVICE_REGISTRATION_OBJECT: windows_sys::core::HRESULT = 0xC00D276C_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_ENCRYPT_OBJECT: windows_sys::core::HRESULT = 0xC00D2732_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_HEADER_OBJECT: windows_sys::core::HRESULT = 0xC00D2757_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_INDI_OBJECT: windows_sys::core::HRESULT = 0xC00D2731_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_INMEMORYSTORE_OBJECT: windows_sys::core::HRESULT = 0xC00D2784_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_KEYS_OBJECT: windows_sys::core::HRESULT = 0xC00D2758_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_LICENSE_OBJECT: windows_sys::core::HRESULT = 0xC00D2730_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_METERING_OBJECT: windows_sys::core::HRESULT = 0xC00D276D_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_MIGRATION_IMPORTER_OBJECT: windows_sys::core::HRESULT = 0xC00D2795_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_PLAYLIST_BURN_OBJECT: windows_sys::core::HRESULT = 0xC00D276B_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_PLAYLIST_OBJECT: windows_sys::core::HRESULT = 0xC00D276A_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_PROPERTIES_OBJECT: windows_sys::core::HRESULT = 0xC00D2734_u32 as _;\npub const NS_E_DRM_UNABLE_TO_CREATE_STATE_DATA_OBJECT: windows_sys::core::HRESULT = 0xC00D275B_u32 as _;\npub const NS_E_DRM_UNABLE_TO_GET_DEVICE_CERT: windows_sys::core::HRESULT = 0xC00D2772_u32 as _;\npub const NS_E_DRM_UNABLE_TO_GET_SECURE_CLOCK: windows_sys::core::HRESULT = 0xC00D2773_u32 as _;\npub const NS_E_DRM_UNABLE_TO_GET_SECURE_CLOCK_FROM_SERVER: windows_sys::core::HRESULT = 0xC00D2775_u32 as _;\npub const NS_E_DRM_UNABLE_TO_INITIALIZE: windows_sys::core::HRESULT = 0xC00D271D_u32 as _;\npub const NS_E_DRM_UNABLE_TO_LOAD_HARDWARE_ID: windows_sys::core::HRESULT = 0xC00D2781_u32 as _;\npub const NS_E_DRM_UNABLE_TO_OPEN_DATA_STORE: windows_sys::core::HRESULT = 0xC00D2782_u32 as _;\npub const NS_E_DRM_UNABLE_TO_OPEN_LICENSE: windows_sys::core::HRESULT = 0xC00D2717_u32 as _;\npub const NS_E_DRM_UNABLE_TO_OPEN_PORT: windows_sys::core::HRESULT = 0xC00D28AF_u32 as _;\npub const NS_E_DRM_UNABLE_TO_SET_PARAMETER: windows_sys::core::HRESULT = 0xC00D273F_u32 as _;\npub const NS_E_DRM_UNABLE_TO_SET_SECURE_CLOCK: windows_sys::core::HRESULT = 0xC00D2774_u32 as _;\npub const NS_E_DRM_UNABLE_TO_VERIFY_PROXIMITY: windows_sys::core::HRESULT = 0xC00D28A4_u32 as _;\npub const NS_E_DRM_UNSUPPORTED_ACTION: windows_sys::core::HRESULT = 0xC00D28AD_u32 as _;\npub const NS_E_DRM_UNSUPPORTED_ALGORITHM: windows_sys::core::HRESULT = 0xC00D284D_u32 as _;\npub const NS_E_DRM_UNSUPPORTED_PROPERTY: windows_sys::core::HRESULT = 0xC00D275D_u32 as _;\npub const NS_E_DRM_UNSUPPORTED_PROTOCOL_VERSION: windows_sys::core::HRESULT = 0xC00D28AC_u32 as _;\npub const NS_E_DUPLICATE_ADDRESS: windows_sys::core::HRESULT = 0xC00D0037_u32 as _;\npub const NS_E_DUPLICATE_DRMPROFILE: windows_sys::core::HRESULT = 0xC00D1B90_u32 as _;\npub const NS_E_DUPLICATE_NAME: windows_sys::core::HRESULT = 0xC00D0036_u32 as _;\npub const NS_E_DUPLICATE_PACKET: windows_sys::core::HRESULT = 0xC00D0BD3_u32 as _;\npub const NS_E_DVD_AUTHORING_PROBLEM: windows_sys::core::HRESULT = 0xC00D1164_u32 as _;\npub const NS_E_DVD_CANNOT_COPY_PROTECTED: windows_sys::core::HRESULT = 0xC00D1172_u32 as _;\npub const NS_E_DVD_CANNOT_JUMP: windows_sys::core::HRESULT = 0xC00D116F_u32 as _;\npub const NS_E_DVD_COMPATIBLE_VIDEO_CARD: windows_sys::core::HRESULT = 0xC00D1166_u32 as _;\npub const NS_E_DVD_COPY_PROTECT: windows_sys::core::HRESULT = 0xC00D1163_u32 as _;\npub const NS_E_DVD_DEVICE_CONTENTION: windows_sys::core::HRESULT = 0xC00D1170_u32 as _;\npub const NS_E_DVD_DISC_COPY_PROTECT_OUTPUT_FAILED: windows_sys::core::HRESULT = 0xC00D1161_u32 as _;\npub const NS_E_DVD_DISC_COPY_PROTECT_OUTPUT_NS: windows_sys::core::HRESULT = 0xC00D1160_u32 as _;\npub const NS_E_DVD_DISC_DECODER_REGION: windows_sys::core::HRESULT = 0xC00D1169_u32 as _;\npub const NS_E_DVD_GRAPH_BUILDING: windows_sys::core::HRESULT = 0xC00D116C_u32 as _;\npub const NS_E_DVD_INVALID_DISC_REGION: windows_sys::core::HRESULT = 0xC00D1165_u32 as _;\npub const NS_E_DVD_INVALID_TITLE_CHAPTER: windows_sys::core::HRESULT = 0xC00D1174_u32 as _;\npub const NS_E_DVD_MACROVISION: windows_sys::core::HRESULT = 0xC00D1167_u32 as _;\npub const NS_E_DVD_NO_AUDIO_STREAM: windows_sys::core::HRESULT = 0xC00D116B_u32 as _;\npub const NS_E_DVD_NO_DECODER: windows_sys::core::HRESULT = 0xC00D116D_u32 as _;\npub const NS_E_DVD_NO_SUBPICTURE_STREAM: windows_sys::core::HRESULT = 0xC00D1162_u32 as _;\npub const NS_E_DVD_NO_VIDEO_MEMORY: windows_sys::core::HRESULT = 0xC00D1171_u32 as _;\npub const NS_E_DVD_NO_VIDEO_STREAM: windows_sys::core::HRESULT = 0xC00D116A_u32 as _;\npub const NS_E_DVD_PARENTAL: windows_sys::core::HRESULT = 0xC00D116E_u32 as _;\npub const NS_E_DVD_REQUIRED_PROPERTY_NOT_SET: windows_sys::core::HRESULT = 0xC00D1173_u32 as _;\npub const NS_E_DVD_SYSTEM_DECODER_REGION: windows_sys::core::HRESULT = 0xC00D1168_u32 as _;\npub const NS_E_EDL_REQUIRED_FOR_DEVICE_MULTIPASS: windows_sys::core::HRESULT = 0xC00D1BE7_u32 as _;\npub const NS_E_EMPTY_PLAYLIST: windows_sys::core::HRESULT = 0xC00D14B5_u32 as _;\npub const NS_E_EMPTY_PROGRAM_NAME: windows_sys::core::HRESULT = 0xC00D00D6_u32 as _;\npub const NS_E_ENACTPLAN_GIVEUP: windows_sys::core::HRESULT = 0xC00D0068_u32 as _;\npub const NS_E_END_OF_PLAYLIST: windows_sys::core::HRESULT = 0xC00D32C8_u32 as _;\npub const NS_E_END_OF_TAPE: windows_sys::core::HRESULT = 0xC00D1BAE_u32 as _;\npub const NS_E_ERROR_FROM_PROXY: windows_sys::core::HRESULT = 0xC00D2EE4_u32 as _;\npub const NS_E_EXCEED_MAX_DRM_PROFILE_LIMIT: windows_sys::core::HRESULT = 0xC00D1BE0_u32 as _;\npub const NS_E_EXPECT_MONO_WAV_INPUT: windows_sys::core::HRESULT = 0xC00D1BA1_u32 as _;\npub const NS_E_FAILED_DOWNLOAD_ABORT_BURN: windows_sys::core::HRESULT = 0xC00D10DC_u32 as _;\npub const NS_E_FAIL_LAUNCH_ROXIO_PLUGIN: windows_sys::core::HRESULT = 0xC00D1180_u32 as _;\npub const NS_E_FEATURE_DISABLED_BY_GROUP_POLICY: windows_sys::core::HRESULT = 0xC00D0BDC_u32 as _;\npub const NS_E_FEATURE_DISABLED_IN_SKU: windows_sys::core::HRESULT = 0xC00D0BDD_u32 as _;\npub const NS_E_FEATURE_REQUIRES_ENTERPRISE_SERVER: windows_sys::core::HRESULT = 0xC00D1583_u32 as _;\npub const NS_E_FILE_ALLOCATION_FAILED: windows_sys::core::HRESULT = 0xC00D001E_u32 as _;\npub const NS_E_FILE_BANDWIDTH_LIMIT: windows_sys::core::HRESULT = 0xC00D0030_u32 as _;\npub const NS_E_FILE_EXISTS: windows_sys::core::HRESULT = 0xC00D001B_u32 as _;\npub const NS_E_FILE_FAILED_CHECKS: windows_sys::core::HRESULT = 0xC00D0FCD_u32 as _;\npub const NS_E_FILE_INIT_FAILED: windows_sys::core::HRESULT = 0xC00D001F_u32 as _;\npub const NS_E_FILE_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D001A_u32 as _;\npub const NS_E_FILE_OPEN_FAILED: windows_sys::core::HRESULT = 0xC00D001D_u32 as _;\npub const NS_E_FILE_PLAY_FAILED: windows_sys::core::HRESULT = 0xC00D0020_u32 as _;\npub const NS_E_FILE_READ: windows_sys::core::HRESULT = 0xC00D0019_u32 as _;\npub const NS_E_FILE_WRITE: windows_sys::core::HRESULT = 0xC00D0018_u32 as _;\npub const NS_E_FIREWALL: windows_sys::core::HRESULT = 0xC00D2EF9_u32 as _;\npub const NS_E_FLASH_PLAYBACK_NOT_ALLOWED: windows_sys::core::HRESULT = 0xC00D10CF_u32 as _;\npub const NS_E_GLITCH_MODE: windows_sys::core::HRESULT = 0xC00D0195_u32 as _;\npub const NS_E_GRAPH_NOAUDIOLANGUAGE: windows_sys::core::HRESULT = 0xC00D10C5_u32 as _;\npub const NS_E_GRAPH_NOAUDIOLANGUAGESELECTED: windows_sys::core::HRESULT = 0xC00D10C6_u32 as _;\npub const NS_E_HDS_KEY_MISMATCH: windows_sys::core::HRESULT = 0xC00D2799_u32 as _;\npub const NS_E_HEADER_MISMATCH: windows_sys::core::HRESULT = 0xC00D151F_u32 as _;\npub const NS_E_HTTP_DISABLED: windows_sys::core::HRESULT = 0xC00D00D3_u32 as _;\npub const NS_E_HTTP_TEXT_DATACONTAINER_INVALID_SERVER_RESPONSE: windows_sys::core::HRESULT = 0xC00D158C_u32 as _;\npub const NS_E_HTTP_TEXT_DATACONTAINER_SIZE_LIMIT_EXCEEDED: windows_sys::core::HRESULT = 0xC00D1589_u32 as _;\npub const NS_E_ICMQUERYFORMAT: windows_sys::core::HRESULT = 0xC00D1B6C_u32 as _;\npub const NS_E_IE_DISALLOWS_ACTIVEX_CONTROLS: windows_sys::core::HRESULT = 0xC00D10CE_u32 as _;\npub const NS_E_IMAGE_DOWNLOAD_FAILED: windows_sys::core::HRESULT = 0xC00D128E_u32 as _;\npub const NS_E_IMAPI_LOSSOFSTREAMING: windows_sys::core::HRESULT = 0xC00D117E_u32 as _;\npub const NS_E_IMAPI_MEDIUM_INVALIDTYPE: windows_sys::core::HRESULT = 0xC00D1182_u32 as _;\npub const NS_E_INCOMPATIBLE_FORMAT: windows_sys::core::HRESULT = 0xC00D0041_u32 as _;\npub const NS_E_INCOMPATIBLE_PUSH_SERVER: windows_sys::core::HRESULT = 0xC00D2F0C_u32 as _;\npub const NS_E_INCOMPATIBLE_SERVER: windows_sys::core::HRESULT = 0xC00D2EE8_u32 as _;\npub const NS_E_INCOMPATIBLE_VERSION: windows_sys::core::HRESULT = 0xC00D0BC7_u32 as _;\npub const NS_E_INCOMPLETE_PLAYLIST: windows_sys::core::HRESULT = 0xC00D1242_u32 as _;\npub const NS_E_INCORRECTCLIPSETTINGS: windows_sys::core::HRESULT = 0xC00D1B7C_u32 as _;\npub const NS_E_INDUCED: windows_sys::core::HRESULT = 0xC00D0022_u32 as _;\npub const NS_E_INPUTSOURCE_PROBLEM: windows_sys::core::HRESULT = 0xC00D1B8A_u32 as _;\npub const NS_E_INPUT_DOESNOT_SUPPORT_SMPTE: windows_sys::core::HRESULT = 0xC00D1BA8_u32 as _;\npub const NS_E_INPUT_WAVFORMAT_MISMATCH: windows_sys::core::HRESULT = 0xC00D1BA2_u32 as _;\npub const NS_E_INSUFFICIENT_BANDWIDTH: windows_sys::core::HRESULT = 0xC00D002C_u32 as _;\npub const NS_E_INSUFFICIENT_DATA: windows_sys::core::HRESULT = 0xC00D00CA_u32 as _;\npub const NS_E_INTERFACE_NOT_REGISTERED_IN_GIT: windows_sys::core::HRESULT = 0xC00D126A_u32 as _;\npub const NS_E_INTERLACEMODE_MISMATCH: windows_sys::core::HRESULT = 0xC00D1BAB_u32 as _;\npub const NS_E_INTERLACE_REQUIRE_SAMESIZE: windows_sys::core::HRESULT = 0xC00D1B95_u32 as _;\npub const NS_E_INTERNAL: windows_sys::core::HRESULT = 0xC00D0024_u32 as _;\npub const NS_E_INTERNAL_SERVER_ERROR: windows_sys::core::HRESULT = 0xC00D2EE2_u32 as _;\npub const NS_E_INVALIDCALL_WHILE_ARCHIVAL_RUNNING: windows_sys::core::HRESULT = 0xC00D1B74_u32 as _;\npub const NS_E_INVALIDCALL_WHILE_ENCODER_RUNNING: windows_sys::core::HRESULT = 0xC00D1B66_u32 as _;\npub const NS_E_INVALIDCALL_WHILE_ENCODER_STOPPED: windows_sys::core::HRESULT = 0xC00D1B7F_u32 as _;\npub const NS_E_INVALIDINPUTFPS: windows_sys::core::HRESULT = 0xC00D1B81_u32 as _;\npub const NS_E_INVALIDPACKETSIZE: windows_sys::core::HRESULT = 0xC00D1B75_u32 as _;\npub const NS_E_INVALIDPROFILE: windows_sys::core::HRESULT = 0xC00D0BC6_u32 as _;\npub const NS_E_INVALID_ARCHIVE: windows_sys::core::HRESULT = 0xC00D003D_u32 as _;\npub const NS_E_INVALID_AUDIO_BUFFERMAX: windows_sys::core::HRESULT = 0xC00D1BBC_u32 as _;\npub const NS_E_INVALID_AUDIO_PEAKRATE: windows_sys::core::HRESULT = 0xC00D1BBA_u32 as _;\npub const NS_E_INVALID_AUDIO_PEAKRATE_2: windows_sys::core::HRESULT = 0xC00D1BBB_u32 as _;\npub const NS_E_INVALID_BLACKHOLE_ADDRESS: windows_sys::core::HRESULT = 0xC00D0040_u32 as _;\npub const NS_E_INVALID_CHANNEL: windows_sys::core::HRESULT = 0xC00D003B_u32 as _;\npub const NS_E_INVALID_CLIENT: windows_sys::core::HRESULT = 0xC00D003F_u32 as _;\npub const NS_E_INVALID_DATA: windows_sys::core::HRESULT = 0xC00D002F_u32 as _;\npub const NS_E_INVALID_DEVICE: windows_sys::core::HRESULT = 0xC00D1B91_u32 as _;\npub const NS_E_INVALID_DRMV2CLT_STUBLIB: windows_sys::core::HRESULT = 0xC00D2790_u32 as _;\npub const NS_E_INVALID_EDL: windows_sys::core::HRESULT = 0xC00D0BD8_u32 as _;\npub const NS_E_INVALID_FILE_BITRATE: windows_sys::core::HRESULT = 0xC00D1BD1_u32 as _;\npub const NS_E_INVALID_FOLDDOWN_COEFFICIENTS: windows_sys::core::HRESULT = 0xC00D1BD4_u32 as _;\npub const NS_E_INVALID_INDEX: windows_sys::core::HRESULT = 0xC00D0011_u32 as _;\npub const NS_E_INVALID_INDEX2: windows_sys::core::HRESULT = 0xC00D00D9_u32 as _;\npub const NS_E_INVALID_INPUT_AUDIENCE_INDEX: windows_sys::core::HRESULT = 0xC00D1B9E_u32 as _;\npub const NS_E_INVALID_INPUT_FORMAT: windows_sys::core::HRESULT = 0xC00D0BB8_u32 as _;\npub const NS_E_INVALID_INPUT_LANGUAGE: windows_sys::core::HRESULT = 0xC00D1B9F_u32 as _;\npub const NS_E_INVALID_INPUT_STREAM: windows_sys::core::HRESULT = 0xC00D1BA0_u32 as _;\npub const NS_E_INVALID_INTERLACEMODE: windows_sys::core::HRESULT = 0xC00D1BDB_u32 as _;\npub const NS_E_INVALID_INTERLACE_COMPAT: windows_sys::core::HRESULT = 0xC00D1BDC_u32 as _;\npub const NS_E_INVALID_KEY: windows_sys::core::HRESULT = 0xC00D0042_u32 as _;\npub const NS_E_INVALID_LOG_URL: windows_sys::core::HRESULT = 0xC00D1585_u32 as _;\npub const NS_E_INVALID_MTU_RANGE: windows_sys::core::HRESULT = 0xC00D1586_u32 as _;\npub const NS_E_INVALID_NAME: windows_sys::core::HRESULT = 0xC00D001C_u32 as _;\npub const NS_E_INVALID_NONSQUAREPIXEL_COMPAT: windows_sys::core::HRESULT = 0xC00D1BDD_u32 as _;\npub const NS_E_INVALID_NUM_PASSES: windows_sys::core::HRESULT = 0xC00D0BD5_u32 as _;\npub const NS_E_INVALID_OPERATING_SYSTEM_VERSION: windows_sys::core::HRESULT = 0xC00D1459_u32 as _;\npub const NS_E_INVALID_OUTPUT_FORMAT: windows_sys::core::HRESULT = 0xC00D0BBB_u32 as _;\npub const NS_E_INVALID_PIXEL_ASPECT_RATIO: windows_sys::core::HRESULT = 0xC00D1BE2_u32 as _;\npub const NS_E_INVALID_PLAY_STATISTICS: windows_sys::core::HRESULT = 0xC00D1587_u32 as _;\npub const NS_E_INVALID_PLUGIN_LOAD_TYPE_CONFIGURATION: windows_sys::core::HRESULT = 0xC00D1454_u32 as _;\npub const NS_E_INVALID_PORT: windows_sys::core::HRESULT = 0xC00D0043_u32 as _;\npub const NS_E_INVALID_PROFILE_CONTENTTYPE: windows_sys::core::HRESULT = 0xC00D1BE4_u32 as _;\npub const NS_E_INVALID_PUBLISHING_POINT_NAME: windows_sys::core::HRESULT = 0xC00D1455_u32 as _;\npub const NS_E_INVALID_PUSH_PUBLISHING_POINT: windows_sys::core::HRESULT = 0xC00D151B_u32 as _;\npub const NS_E_INVALID_PUSH_PUBLISHING_POINT_START_REQUEST: windows_sys::core::HRESULT = 0xC00D145B_u32 as _;\npub const NS_E_INVALID_PUSH_TEMPLATE: windows_sys::core::HRESULT = 0xC00D151A_u32 as _;\npub const NS_E_INVALID_QUERY_OPERATOR: windows_sys::core::HRESULT = 0xC00D32CF_u32 as _;\npub const NS_E_INVALID_QUERY_PROPERTY: windows_sys::core::HRESULT = 0xC00D32D0_u32 as _;\npub const NS_E_INVALID_REDIRECT: windows_sys::core::HRESULT = 0xC00D2EEA_u32 as _;\npub const NS_E_INVALID_REQUEST: windows_sys::core::HRESULT = 0xC00D002B_u32 as _;\npub const NS_E_INVALID_SAMPLING_RATE: windows_sys::core::HRESULT = 0xC00D0BD0_u32 as _;\npub const NS_E_INVALID_SCRIPT_BITRATE: windows_sys::core::HRESULT = 0xC00D1BCF_u32 as _;\npub const NS_E_INVALID_SOURCE_WITH_DEVICE_CONTROL: windows_sys::core::HRESULT = 0xC00D1BDE_u32 as _;\npub const NS_E_INVALID_STREAM: windows_sys::core::HRESULT = 0xC00D003C_u32 as _;\npub const NS_E_INVALID_TIMECODE: windows_sys::core::HRESULT = 0xC00D1BD6_u32 as _;\npub const NS_E_INVALID_TTL: windows_sys::core::HRESULT = 0xC00D0044_u32 as _;\npub const NS_E_INVALID_VBR_COMPAT: windows_sys::core::HRESULT = 0xC00D1BB2_u32 as _;\npub const NS_E_INVALID_VBR_WITH_UNCOMP: windows_sys::core::HRESULT = 0xC00D1BB4_u32 as _;\npub const NS_E_INVALID_VIDEO_BITRATE: windows_sys::core::HRESULT = 0xC00D1BBF_u32 as _;\npub const NS_E_INVALID_VIDEO_BUFFER: windows_sys::core::HRESULT = 0xC00D1BC9_u32 as _;\npub const NS_E_INVALID_VIDEO_BUFFERMAX: windows_sys::core::HRESULT = 0xC00D1BCA_u32 as _;\npub const NS_E_INVALID_VIDEO_BUFFERMAX_2: windows_sys::core::HRESULT = 0xC00D1BCB_u32 as _;\npub const NS_E_INVALID_VIDEO_CQUALITY: windows_sys::core::HRESULT = 0xC00D1BC8_u32 as _;\npub const NS_E_INVALID_VIDEO_FPS: windows_sys::core::HRESULT = 0xC00D1BC5_u32 as _;\npub const NS_E_INVALID_VIDEO_HEIGHT: windows_sys::core::HRESULT = 0xC00D1BC4_u32 as _;\npub const NS_E_INVALID_VIDEO_HEIGHT_ALIGN: windows_sys::core::HRESULT = 0xC00D1BCD_u32 as _;\npub const NS_E_INVALID_VIDEO_IQUALITY: windows_sys::core::HRESULT = 0xC00D1BC7_u32 as _;\npub const NS_E_INVALID_VIDEO_KEYFRAME: windows_sys::core::HRESULT = 0xC00D1BC6_u32 as _;\npub const NS_E_INVALID_VIDEO_PEAKRATE: windows_sys::core::HRESULT = 0xC00D1BC1_u32 as _;\npub const NS_E_INVALID_VIDEO_PEAKRATE_2: windows_sys::core::HRESULT = 0xC00D1BC2_u32 as _;\npub const NS_E_INVALID_VIDEO_WIDTH: windows_sys::core::HRESULT = 0xC00D1BC3_u32 as _;\npub const NS_E_INVALID_VIDEO_WIDTH_ALIGN: windows_sys::core::HRESULT = 0xC00D1BCC_u32 as _;\npub const NS_E_INVALID_VIDEO_WIDTH_FOR_INTERLACED_ENCODING: windows_sys::core::HRESULT = 0xC00D1BE8_u32 as _;\npub const NS_E_LANGUAGE_MISMATCH: windows_sys::core::HRESULT = 0xC00D1B9C_u32 as _;\npub const NS_E_LATE_OPERATION: windows_sys::core::HRESULT = 0xC00D002E_u32 as _;\npub const NS_E_LATE_PACKET: windows_sys::core::HRESULT = 0xC00D0BD2_u32 as _;\npub const NS_E_LICENSE_EXPIRED: windows_sys::core::HRESULT = 0xC00D00D4_u32 as _;\npub const NS_E_LICENSE_HEADER_MISSING_URL: windows_sys::core::HRESULT = 0xC00D277A_u32 as _;\npub const NS_E_LICENSE_INCORRECT_RIGHTS: windows_sys::core::HRESULT = 0xC00D0BC1_u32 as _;\npub const NS_E_LICENSE_OUTOFDATE: windows_sys::core::HRESULT = 0xC00D0BC0_u32 as _;\npub const NS_E_LICENSE_REQUIRED: windows_sys::core::HRESULT = 0xC00D0BBE_u32 as _;\npub const NS_E_LOGFILEPERIOD: windows_sys::core::HRESULT = 0xC00D0048_u32 as _;\npub const NS_E_LOG_FILE_SIZE: windows_sys::core::HRESULT = 0xC00D004A_u32 as _;\npub const NS_E_LOG_NEED_TO_BE_SKIPPED: windows_sys::core::HRESULT = 0xC00D1588_u32 as _;\npub const NS_E_MARKIN_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D1BE9_u32 as _;\npub const NS_E_MAX_BITRATE: windows_sys::core::HRESULT = 0xC00D0047_u32 as _;\npub const NS_E_MAX_CLIENTS: windows_sys::core::HRESULT = 0xC00D0049_u32 as _;\npub const NS_E_MAX_FILERATE: windows_sys::core::HRESULT = 0xC00D004B_u32 as _;\npub const NS_E_MAX_FUNNELS_ALERT: windows_sys::core::HRESULT = 0xC00D0060_u32 as _;\npub const NS_E_MAX_PACKET_SIZE_TOO_SMALL: windows_sys::core::HRESULT = 0xC00D0BD1_u32 as _;\npub const NS_E_MEDIACD_READ_ERROR: windows_sys::core::HRESULT = 0xC00D10CD_u32 as _;\npub const NS_E_MEDIA_LIBRARY_FAILED: windows_sys::core::HRESULT = 0xC00D0FCE_u32 as _;\npub const NS_E_MEDIA_PARSER_INVALID_FORMAT: windows_sys::core::HRESULT = 0xC00D1581_u32 as _;\npub const NS_E_MEMSTORAGE_BAD_DATA: windows_sys::core::HRESULT = 0xC00D117B_u32 as _;\npub const NS_E_METADATA_CACHE_DATA_NOT_AVAILABLE: windows_sys::core::HRESULT = 0xC00D32DB_u32 as _;\npub const NS_E_METADATA_CANNOT_RETRIEVE_FROM_OFFLINE_CACHE: windows_sys::core::HRESULT = 0xC00D32DE_u32 as _;\npub const NS_E_METADATA_CANNOT_SET_LOCALE: windows_sys::core::HRESULT = 0xC00D32D7_u32 as _;\npub const NS_E_METADATA_FORMAT_NOT_SUPPORTED: windows_sys::core::HRESULT = 0xC00D32D5_u32 as _;\npub const NS_E_METADATA_IDENTIFIER_NOT_AVAILABLE: windows_sys::core::HRESULT = 0xC00D32DD_u32 as _;\npub const NS_E_METADATA_INVALID_DOCUMENT_TYPE: windows_sys::core::HRESULT = 0xC00D32DC_u32 as _;\npub const NS_E_METADATA_LANGUAGE_NOT_SUPORTED: windows_sys::core::HRESULT = 0xC00D32D8_u32 as _;\npub const NS_E_METADATA_NOT_AVAILABLE: windows_sys::core::HRESULT = 0xC00D32DA_u32 as _;\npub const NS_E_METADATA_NO_EDITING_CAPABILITY: windows_sys::core::HRESULT = 0xC00D32D6_u32 as _;\npub const NS_E_METADATA_NO_RFC1766_NAME_FOR_LOCALE: windows_sys::core::HRESULT = 0xC00D32D9_u32 as _;\npub const NS_E_MISMATCHED_MEDIACONTENT: windows_sys::core::HRESULT = 0xC00D1B5F_u32 as _;\npub const NS_E_MISSING_AUDIENCE: windows_sys::core::HRESULT = 0xC00D1B98_u32 as _;\npub const NS_E_MISSING_CHANNEL: windows_sys::core::HRESULT = 0xC00D00D7_u32 as _;\npub const NS_E_MISSING_SOURCE_INDEX: windows_sys::core::HRESULT = 0xC00D1B9A_u32 as _;\npub const NS_E_MIXER_INVALID_CONTROL: windows_sys::core::HRESULT = 0xC00D0FA6_u32 as _;\npub const NS_E_MIXER_INVALID_LINE: windows_sys::core::HRESULT = 0xC00D0FA5_u32 as _;\npub const NS_E_MIXER_INVALID_VALUE: windows_sys::core::HRESULT = 0xC00D0FA7_u32 as _;\npub const NS_E_MIXER_NODRIVER: windows_sys::core::HRESULT = 0xC00D0FAF_u32 as _;\npub const NS_E_MIXER_UNKNOWN_MMRESULT: windows_sys::core::HRESULT = 0xC00D0FA8_u32 as _;\npub const NS_E_MLS_SMARTPLAYLIST_FILTER_NOT_REGISTERED: windows_sys::core::HRESULT = 0xC00D1075_u32 as _;\npub const NS_E_MMSAUTOSERVER_CANTFINDWALKER: windows_sys::core::HRESULT = 0xC00D0046_u32 as _;\npub const NS_E_MMS_NOT_SUPPORTED: windows_sys::core::HRESULT = 0xC00D2EFA_u32 as _;\npub const NS_E_MONITOR_GIVEUP: windows_sys::core::HRESULT = 0xC00D00C8_u32 as _;\npub const NS_E_MP3_FORMAT_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D0FAA_u32 as _;\npub const NS_E_MPDB_GENERIC: windows_sys::core::HRESULT = 0xC00D0FCC_u32 as _;\npub const NS_E_MSAUDIO_NOT_INSTALLED: windows_sys::core::HRESULT = 0xC00D0BB9_u32 as _;\npub const NS_E_MSBD_NO_LONGER_SUPPORTED: windows_sys::core::HRESULT = 0xC00D2EEC_u32 as _;\npub const NS_E_MULTICAST_DISABLED: windows_sys::core::HRESULT = 0xC00D2EE9_u32 as _;\npub const NS_E_MULTICAST_PLUGIN_NOT_ENABLED: windows_sys::core::HRESULT = 0xC00D1458_u32 as _;\npub const NS_E_MULTIPLE_AUDIO_CODECS: windows_sys::core::HRESULT = 0xC00D1BB7_u32 as _;\npub const NS_E_MULTIPLE_AUDIO_FORMATS: windows_sys::core::HRESULT = 0xC00D1BB8_u32 as _;\npub const NS_E_MULTIPLE_FILE_BITRATES: windows_sys::core::HRESULT = 0xC00D1BD0_u32 as _;\npub const NS_E_MULTIPLE_SCRIPT_BITRATES: windows_sys::core::HRESULT = 0xC00D1BCE_u32 as _;\npub const NS_E_MULTIPLE_VBR_AUDIENCES: windows_sys::core::HRESULT = 0xC00D1BB5_u32 as _;\npub const NS_E_MULTIPLE_VIDEO_CODECS: windows_sys::core::HRESULT = 0xC00D1BBD_u32 as _;\npub const NS_E_MULTIPLE_VIDEO_SIZES: windows_sys::core::HRESULT = 0xC00D1BBE_u32 as _;\npub const NS_E_NAMESPACE_BAD_NAME: windows_sys::core::HRESULT = 0xC00D1396_u32 as _;\npub const NS_E_NAMESPACE_BUFFER_TOO_SMALL: windows_sys::core::HRESULT = 0xC00D138E_u32 as _;\npub const NS_E_NAMESPACE_CALLBACK_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D1391_u32 as _;\npub const NS_E_NAMESPACE_DUPLICATE_CALLBACK: windows_sys::core::HRESULT = 0xC00D1390_u32 as _;\npub const NS_E_NAMESPACE_DUPLICATE_NAME: windows_sys::core::HRESULT = 0xC00D1393_u32 as _;\npub const NS_E_NAMESPACE_EMPTY_NAME: windows_sys::core::HRESULT = 0xC00D1394_u32 as _;\npub const NS_E_NAMESPACE_INDEX_TOO_LARGE: windows_sys::core::HRESULT = 0xC00D1395_u32 as _;\npub const NS_E_NAMESPACE_NAME_TOO_LONG: windows_sys::core::HRESULT = 0xC00D1392_u32 as _;\npub const NS_E_NAMESPACE_NODE_CONFLICT: windows_sys::core::HRESULT = 0xC00D138C_u32 as _;\npub const NS_E_NAMESPACE_NODE_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D138D_u32 as _;\npub const NS_E_NAMESPACE_TOO_MANY_CALLBACKS: windows_sys::core::HRESULT = 0xC00D138F_u32 as _;\npub const NS_E_NAMESPACE_WRONG_PERSIST: windows_sys::core::HRESULT = 0xC00D138A_u32 as _;\npub const NS_E_NAMESPACE_WRONG_SECURITY: windows_sys::core::HRESULT = 0xC00D1397_u32 as _;\npub const NS_E_NAMESPACE_WRONG_TYPE: windows_sys::core::HRESULT = 0xC00D138B_u32 as _;\npub const NS_E_NEED_CORE_REFERENCE: windows_sys::core::HRESULT = 0xC00D10CC_u32 as _;\npub const NS_E_NEED_TO_ASK_USER: windows_sys::core::HRESULT = 0xC00D0FDA_u32 as _;\npub const NS_E_NETWORK_BUSY: windows_sys::core::HRESULT = 0xC00D000E_u32 as _;\npub const NS_E_NETWORK_RESOURCE_FAILURE: windows_sys::core::HRESULT = 0xC00D0028_u32 as _;\npub const NS_E_NETWORK_SERVICE_FAILURE: windows_sys::core::HRESULT = 0xC00D0027_u32 as _;\npub const NS_E_NETWORK_SINK_WRITE: windows_sys::core::HRESULT = 0xC00D2EF8_u32 as _;\npub const NS_E_NET_READ: windows_sys::core::HRESULT = 0xC00D0015_u32 as _;\npub const NS_E_NET_WRITE: windows_sys::core::HRESULT = 0xC00D0014_u32 as _;\npub const NS_E_NOCONNECTION: windows_sys::core::HRESULT = 0xC00D0005_u32 as _;\npub const NS_E_NOFUNNEL: windows_sys::core::HRESULT = 0xC00D000C_u32 as _;\npub const NS_E_NOMATCHING_ELEMENT: windows_sys::core::HRESULT = 0xC00D1B5E_u32 as _;\npub const NS_E_NOMATCHING_MEDIASOURCE: windows_sys::core::HRESULT = 0xC00D1B5A_u32 as _;\npub const NS_E_NONSQUAREPIXELMODE_MISMATCH: windows_sys::core::HRESULT = 0xC00D1BAC_u32 as _;\npub const NS_E_NOREGISTEREDWALKER: windows_sys::core::HRESULT = 0xC00D000B_u32 as _;\npub const NS_E_NOSOURCEGROUPS: windows_sys::core::HRESULT = 0xC00D1B80_u32 as _;\npub const NS_E_NOSTATSAVAILABLE: windows_sys::core::HRESULT = 0xC00D1B7D_u32 as _;\npub const NS_E_NOTARCHIVING: windows_sys::core::HRESULT = 0xC00D1B7E_u32 as _;\npub const NS_E_NOTHING_TO_DO: windows_sys::core::HRESULT = 0xC00D07F1_u32 as _;\npub const NS_E_NOTITLES: windows_sys::core::HRESULT = 0xC00D003E_u32 as _;\npub const NS_E_NOT_CONFIGURED: windows_sys::core::HRESULT = 0xC00D0BBC_u32 as _;\npub const NS_E_NOT_CONNECTED: windows_sys::core::HRESULT = 0xC00D0BCB_u32 as _;\npub const NS_E_NOT_CONTENT_PARTNER_TRACK: windows_sys::core::HRESULT = 0xC00D135A_u32 as _;\npub const NS_E_NOT_LICENSED: windows_sys::core::HRESULT = 0xC00D00CD_u32 as _;\npub const NS_E_NOT_REBUILDING: windows_sys::core::HRESULT = 0xC00D002D_u32 as _;\npub const NS_E_NO_ACTIVE_SOURCEGROUP: windows_sys::core::HRESULT = 0xC00D1B72_u32 as _;\npub const NS_E_NO_AUDIENCES: windows_sys::core::HRESULT = 0xC00D1BB0_u32 as _;\npub const NS_E_NO_AUDIODATA: windows_sys::core::HRESULT = 0xC00D1B89_u32 as _;\npub const NS_E_NO_AUDIO_COMPAT: windows_sys::core::HRESULT = 0xC00D1BB1_u32 as _;\npub const NS_E_NO_AUDIO_TIMECOMPRESSION: windows_sys::core::HRESULT = 0xC00D1BD7_u32 as _;\npub const NS_E_NO_CD: windows_sys::core::HRESULT = 0xC00D0FA0_u32 as _;\npub const NS_E_NO_CD_BURNER: windows_sys::core::HRESULT = 0xC00D1176_u32 as _;\npub const NS_E_NO_CHANNELS: windows_sys::core::HRESULT = 0xC00D00D8_u32 as _;\npub const NS_E_NO_DATAVIEW_SUPPORT: windows_sys::core::HRESULT = 0xC00D1B82_u32 as _;\npub const NS_E_NO_DEVICE: windows_sys::core::HRESULT = 0xC00D0071_u32 as _;\npub const NS_E_NO_ERROR_STRING_FOUND: windows_sys::core::HRESULT = 0xC00D0FD0_u32 as _;\npub const NS_E_NO_EXISTING_PACKETIZER: windows_sys::core::HRESULT = 0xC00D2EFD_u32 as _;\npub const NS_E_NO_FORMATS: windows_sys::core::HRESULT = 0xC00D006B_u32 as _;\npub const NS_E_NO_FRAMES_SUBMITTED_TO_ANALYZER: windows_sys::core::HRESULT = 0xC00D1BA7_u32 as _;\npub const NS_E_NO_LOCALPLAY: windows_sys::core::HRESULT = 0xC00D000D_u32 as _;\npub const NS_E_NO_MBR_WITH_TIMECODE: windows_sys::core::HRESULT = 0xC00D1BDA_u32 as _;\npub const NS_E_NO_MEDIAFORMAT_IN_SOURCE: windows_sys::core::HRESULT = 0xC00D1B6F_u32 as _;\npub const NS_E_NO_MEDIA_IN_AUDIENCE: windows_sys::core::HRESULT = 0xC00D1BAF_u32 as _;\npub const NS_E_NO_MEDIA_PROTOCOL: windows_sys::core::HRESULT = 0xC00D019B_u32 as _;\npub const NS_E_NO_MORE_SAMPLES: windows_sys::core::HRESULT = 0xC00D0BCF_u32 as _;\npub const NS_E_NO_MULTICAST: windows_sys::core::HRESULT = 0xC00D07F2_u32 as _;\npub const NS_E_NO_MULTIPASS_FOR_LIVEDEVICE: windows_sys::core::HRESULT = 0xC00D1B97_u32 as _;\npub const NS_E_NO_NEW_CONNECTIONS: windows_sys::core::HRESULT = 0xC00D151D_u32 as _;\npub const NS_E_NO_PAL_INVERSE_TELECINE: windows_sys::core::HRESULT = 0xC00D1BA4_u32 as _;\npub const NS_E_NO_PDA: windows_sys::core::HRESULT = 0xC00D1179_u32 as _;\npub const NS_E_NO_PROFILE_IN_SOURCEGROUP: windows_sys::core::HRESULT = 0xC00D1B67_u32 as _;\npub const NS_E_NO_PROFILE_NAME: windows_sys::core::HRESULT = 0xC00D1BB3_u32 as _;\npub const NS_E_NO_REALTIME_PREPROCESS: windows_sys::core::HRESULT = 0xC00D1B8C_u32 as _;\npub const NS_E_NO_REALTIME_TIMECOMPRESSION: windows_sys::core::HRESULT = 0xC00D1B86_u32 as _;\npub const NS_E_NO_REFERENCES: windows_sys::core::HRESULT = 0xC00D006C_u32 as _;\npub const NS_E_NO_REPEAT_PREPROCESS: windows_sys::core::HRESULT = 0xC00D1B8D_u32 as _;\npub const NS_E_NO_SCRIPT_ENGINE: windows_sys::core::HRESULT = 0xC00D157C_u32 as _;\npub const NS_E_NO_SCRIPT_STREAM: windows_sys::core::HRESULT = 0xC00D1B73_u32 as _;\npub const NS_E_NO_SERVER_CONTACT: windows_sys::core::HRESULT = 0xC00D00CE_u32 as _;\npub const NS_E_NO_SMPTE_WITH_MULTIPLE_SOURCEGROUPS: windows_sys::core::HRESULT = 0xC00D1BA9_u32 as _;\npub const NS_E_NO_SPECIFIED_DEVICE: windows_sys::core::HRESULT = 0xC00D0072_u32 as _;\npub const NS_E_NO_STREAM: windows_sys::core::HRESULT = 0xC00D0033_u32 as _;\npub const NS_E_NO_TWOPASS_TIMECOMPRESSION: windows_sys::core::HRESULT = 0xC00D1BD8_u32 as _;\npub const NS_E_NO_VALID_OUTPUT_STREAM: windows_sys::core::HRESULT = 0xC00D1B70_u32 as _;\npub const NS_E_NO_VALID_SOURCE_PLUGIN: windows_sys::core::HRESULT = 0xC00D1B71_u32 as _;\npub const NS_E_NUM_LANGUAGE_MISMATCH: windows_sys::core::HRESULT = 0xC00D1B9B_u32 as _;\npub const NS_E_OFFLINE_MODE: windows_sys::core::HRESULT = 0xC00D0BCA_u32 as _;\npub const NS_E_OPEN_CONTAINING_FOLDER_FAILED: windows_sys::core::HRESULT = 0xC00D1363_u32 as _;\npub const NS_E_OPEN_FILE_LIMIT: windows_sys::core::HRESULT = 0xC00D0031_u32 as _;\npub const NS_E_OUTPUT_PROTECTION_LEVEL_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D2904_u32 as _;\npub const NS_E_OUTPUT_PROTECTION_SCHEME_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D290A_u32 as _;\npub const NS_E_PACKETSINK_UNKNOWN_FEC_STREAM: windows_sys::core::HRESULT = 0xC00D2F0A_u32 as _;\npub const NS_E_PAGING_ERROR: windows_sys::core::HRESULT = 0xC00D0062_u32 as _;\npub const NS_E_PARTIALLY_REBUILT_DISK: windows_sys::core::HRESULT = 0xC00D0067_u32 as _;\npub const NS_E_PDA_CANNOT_CREATE_ADDITIONAL_SYNC_RELATIONSHIP: windows_sys::core::HRESULT = 0xC00D1185_u32 as _;\npub const NS_E_PDA_CANNOT_SYNC_FROM_INTERNET: windows_sys::core::HRESULT = 0xC00D1234_u32 as _;\npub const NS_E_PDA_CANNOT_SYNC_FROM_LOCATION: windows_sys::core::HRESULT = 0xC00D1193_u32 as _;\npub const NS_E_PDA_CANNOT_SYNC_INVALID_PLAYLIST: windows_sys::core::HRESULT = 0xC00D1235_u32 as _;\npub const NS_E_PDA_CANNOT_TRANSCODE: windows_sys::core::HRESULT = 0xC00D1189_u32 as _;\npub const NS_E_PDA_CANNOT_TRANSCODE_TO_AUDIO: windows_sys::core::HRESULT = 0xC00D123D_u32 as _;\npub const NS_E_PDA_CANNOT_TRANSCODE_TO_IMAGE: windows_sys::core::HRESULT = 0xC00D123F_u32 as _;\npub const NS_E_PDA_CANNOT_TRANSCODE_TO_VIDEO: windows_sys::core::HRESULT = 0xC00D123E_u32 as _;\npub const NS_E_PDA_CEWMDM_DRM_ERROR: windows_sys::core::HRESULT = 0xC00D1241_u32 as _;\npub const NS_E_PDA_DELETE_FAILED: windows_sys::core::HRESULT = 0xC00D1238_u32 as _;\npub const NS_E_PDA_DEVICESUPPORTDISABLED: windows_sys::core::HRESULT = 0xC00D1190_u32 as _;\npub const NS_E_PDA_DEVICE_FULL: windows_sys::core::HRESULT = 0xC00D117F_u32 as _;\npub const NS_E_PDA_DEVICE_FULL_IN_SESSION: windows_sys::core::HRESULT = 0xC00D1181_u32 as _;\npub const NS_E_PDA_DEVICE_NOT_RESPONDING: windows_sys::core::HRESULT = 0xC00D123A_u32 as _;\npub const NS_E_PDA_ENCODER_NOT_RESPONDING: windows_sys::core::HRESULT = 0xC00D1192_u32 as _;\npub const NS_E_PDA_FAILED_TO_BURN: windows_sys::core::HRESULT = 0xC00D10DA_u32 as _;\npub const NS_E_PDA_FAILED_TO_ENCRYPT_TRANSCODED_FILE: windows_sys::core::HRESULT = 0xC00D123C_u32 as _;\npub const NS_E_PDA_FAILED_TO_RETRIEVE_FILE: windows_sys::core::HRESULT = 0xC00D1239_u32 as _;\npub const NS_E_PDA_FAILED_TO_SYNCHRONIZE_FILE: windows_sys::core::HRESULT = 0xC00D1236_u32 as _;\npub const NS_E_PDA_FAILED_TO_TRANSCODE_PHOTO: windows_sys::core::HRESULT = 0xC00D123B_u32 as _;\npub const NS_E_PDA_FAIL_READ_WAVE_FILE: windows_sys::core::HRESULT = 0xC00D117D_u32 as _;\npub const NS_E_PDA_FAIL_SELECT_DEVICE: windows_sys::core::HRESULT = 0xC00D117C_u32 as _;\npub const NS_E_PDA_INITIALIZINGDEVICES: windows_sys::core::HRESULT = 0xC00D118D_u32 as _;\npub const NS_E_PDA_MANUALDEVICE: windows_sys::core::HRESULT = 0xC00D1183_u32 as _;\npub const NS_E_PDA_NO_LONGER_AVAILABLE: windows_sys::core::HRESULT = 0xC00D1191_u32 as _;\npub const NS_E_PDA_NO_TRANSCODE_OF_DRM: windows_sys::core::HRESULT = 0xC00D1186_u32 as _;\npub const NS_E_PDA_OBSOLETE_SP: windows_sys::core::HRESULT = 0xC00D118E_u32 as _;\npub const NS_E_PDA_PARTNERSHIPNOTEXIST: windows_sys::core::HRESULT = 0xC00D1184_u32 as _;\npub const NS_E_PDA_RETRIEVED_FILE_FILENAME_TOO_LONG: windows_sys::core::HRESULT = 0xC00D1240_u32 as _;\npub const NS_E_PDA_SYNC_FAILED: windows_sys::core::HRESULT = 0xC00D1237_u32 as _;\npub const NS_E_PDA_SYNC_LOGIN_ERROR: windows_sys::core::HRESULT = 0xC00D1244_u32 as _;\npub const NS_E_PDA_SYNC_RUNNING: windows_sys::core::HRESULT = 0xC00D1243_u32 as _;\npub const NS_E_PDA_TITLE_COLLISION: windows_sys::core::HRESULT = 0xC00D118F_u32 as _;\npub const NS_E_PDA_TOO_MANY_FILES_IN_DIRECTORY: windows_sys::core::HRESULT = 0xC00D118A_u32 as _;\npub const NS_E_PDA_TOO_MANY_FILE_COLLISIONS: windows_sys::core::HRESULT = 0xC00D1188_u32 as _;\npub const NS_E_PDA_TRANSCODECACHEFULL: windows_sys::core::HRESULT = 0xC00D1187_u32 as _;\npub const NS_E_PDA_TRANSCODE_CODEC_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D1245_u32 as _;\npub const NS_E_PDA_TRANSCODE_NOT_PERMITTED: windows_sys::core::HRESULT = 0xC00D118C_u32 as _;\npub const NS_E_PDA_UNSPECIFIED_ERROR: windows_sys::core::HRESULT = 0xC00D117A_u32 as _;\npub const NS_E_PDA_UNSUPPORTED_FORMAT: windows_sys::core::HRESULT = 0xC00D1178_u32 as _;\npub const NS_E_PLAYLIST_CONTAINS_ERRORS: windows_sys::core::HRESULT = 0xC00D10BF_u32 as _;\npub const NS_E_PLAYLIST_END_RECEDING: windows_sys::core::HRESULT = 0xC00D14BD_u32 as _;\npub const NS_E_PLAYLIST_ENTRY_ALREADY_PLAYING: windows_sys::core::HRESULT = 0xC00D14B4_u32 as _;\npub const NS_E_PLAYLIST_ENTRY_HAS_CHANGED: windows_sys::core::HRESULT = 0xC00D2EF5_u32 as _;\npub const NS_E_PLAYLIST_ENTRY_NOT_IN_PLAYLIST: windows_sys::core::HRESULT = 0xC00D14B8_u32 as _;\npub const NS_E_PLAYLIST_ENTRY_SEEK: windows_sys::core::HRESULT = 0xC00D14B9_u32 as _;\npub const NS_E_PLAYLIST_PARSE_FAILURE: windows_sys::core::HRESULT = 0xC00D14B6_u32 as _;\npub const NS_E_PLAYLIST_PLUGIN_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D157F_u32 as _;\npub const NS_E_PLAYLIST_RECURSIVE_PLAYLISTS: windows_sys::core::HRESULT = 0xC00D14BA_u32 as _;\npub const NS_E_PLAYLIST_SHUTDOWN: windows_sys::core::HRESULT = 0xC00D14BC_u32 as _;\npub const NS_E_PLAYLIST_TOO_MANY_NESTED_PLAYLISTS: windows_sys::core::HRESULT = 0xC00D14BB_u32 as _;\npub const NS_E_PLAYLIST_UNSUPPORTED_ENTRY: windows_sys::core::HRESULT = 0xC00D14B7_u32 as _;\npub const NS_E_PLUGIN_CLSID_INVALID: windows_sys::core::HRESULT = 0xC00D1B76_u32 as _;\npub const NS_E_PLUGIN_ERROR_REPORTED: windows_sys::core::HRESULT = 0xC00D157D_u32 as _;\npub const NS_E_PLUGIN_NOTSHUTDOWN: windows_sys::core::HRESULT = 0xC00D0FD6_u32 as _;\npub const NS_E_PORT_IN_USE: windows_sys::core::HRESULT = 0xC00D158A_u32 as _;\npub const NS_E_PORT_IN_USE_HTTP: windows_sys::core::HRESULT = 0xC00D158B_u32 as _;\npub const NS_E_PROCESSINGSHOWSYNCWIZARD: windows_sys::core::HRESULT = 0xC00D118B_u32 as _;\npub const NS_E_PROFILE_MISMATCH: windows_sys::core::HRESULT = 0xC00D1B7B_u32 as _;\npub const NS_E_PROPERTY_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D32CA_u32 as _;\npub const NS_E_PROPERTY_NOT_SUPPORTED: windows_sys::core::HRESULT = 0xC00D32D2_u32 as _;\npub const NS_E_PROPERTY_READ_ONLY: windows_sys::core::HRESULT = 0xC00D32CC_u32 as _;\npub const NS_E_PROTECTED_CONTENT: windows_sys::core::HRESULT = 0xC00D0BBD_u32 as _;\npub const NS_E_PROTOCOL_MISMATCH: windows_sys::core::HRESULT = 0xC00D0012_u32 as _;\npub const NS_E_PROXY_ACCESSDENIED: windows_sys::core::HRESULT = 0xC00D2EF6_u32 as _;\npub const NS_E_PROXY_CONNECT_TIMEOUT: windows_sys::core::HRESULT = 0xC00D2F07_u32 as _;\npub const NS_E_PROXY_DNS_TIMEOUT: windows_sys::core::HRESULT = 0xC00D2EF0_u32 as _;\npub const NS_E_PROXY_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D2EED_u32 as _;\npub const NS_E_PROXY_SOURCE_ACCESSDENIED: windows_sys::core::HRESULT = 0xC00D2EF7_u32 as _;\npub const NS_E_PROXY_TIMEOUT: windows_sys::core::HRESULT = 0xC00D2EE5_u32 as _;\npub const NS_E_PUBLISHING_POINT_INVALID_REQUEST_WHILE_STARTED: windows_sys::core::HRESULT = 0xC00D1457_u32 as _;\npub const NS_E_PUBLISHING_POINT_REMOVED: windows_sys::core::HRESULT = 0xC00D145A_u32 as _;\npub const NS_E_PUBLISHING_POINT_STOPPED: windows_sys::core::HRESULT = 0xC00D145E_u32 as _;\npub const NS_E_PUSH_CANNOTCONNECT: windows_sys::core::HRESULT = 0xC00D2F0B_u32 as _;\npub const NS_E_PUSH_DUPLICATE_PUBLISHING_POINT_NAME: windows_sys::core::HRESULT = 0xC00D1520_u32 as _;\npub const NS_E_REBOOT_RECOMMENDED: windows_sys::core::HRESULT = 0xC00D2AFA_u32 as _;\npub const NS_E_REBOOT_REQUIRED: windows_sys::core::HRESULT = 0xC00D2AFB_u32 as _;\npub const NS_E_RECORDQ_DISK_FULL: windows_sys::core::HRESULT = 0xC00D1BA3_u32 as _;\npub const NS_E_REDBOOK_ENABLED_WHILE_COPYING: windows_sys::core::HRESULT = 0xC00D0FB0_u32 as _;\npub const NS_E_REDIRECT: windows_sys::core::HRESULT = 0xC00D1388_u32 as _;\npub const NS_E_REDIRECT_TO_PROXY: windows_sys::core::HRESULT = 0xC00D2EE1_u32 as _;\npub const NS_E_REFUSED_BY_SERVER: windows_sys::core::HRESULT = 0xC00D2EE7_u32 as _;\npub const NS_E_REG_FLUSH_FAILURE: windows_sys::core::HRESULT = 0xC00D2798_u32 as _;\npub const NS_E_REMIRRORED_DISK: windows_sys::core::HRESULT = 0xC00D00C9_u32 as _;\npub const NS_E_REQUIRE_STREAMING_CLIENT: windows_sys::core::HRESULT = 0xC00D2EF4_u32 as _;\npub const NS_E_RESET_SOCKET_CONNECTION: windows_sys::core::HRESULT = 0xC00D2F00_u32 as _;\npub const NS_E_RESOURCE_GONE: windows_sys::core::HRESULT = 0xC00D2EFC_u32 as _;\npub const NS_E_SAME_AS_INPUT_COMBINATION: windows_sys::core::HRESULT = 0xC00D1BD2_u32 as _;\npub const NS_E_SCHEMA_CLASSIFY_FAILURE: windows_sys::core::HRESULT = 0xC00D32D4_u32 as _;\npub const NS_E_SCRIPT_DEBUGGER_NOT_INSTALLED: windows_sys::core::HRESULT = 0xC00D1582_u32 as _;\npub const NS_E_SDK_BUFFERTOOSMALL: windows_sys::core::HRESULT = 0xC00D0BD4_u32 as _;\npub const NS_E_SERVER_ACCESSDENIED: windows_sys::core::HRESULT = 0xC00D2EFB_u32 as _;\npub const NS_E_SERVER_DNS_TIMEOUT: windows_sys::core::HRESULT = 0xC00D2EEF_u32 as _;\npub const NS_E_SERVER_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D0035_u32 as _;\npub const NS_E_SERVER_UNAVAILABLE: windows_sys::core::HRESULT = 0xC00D2EE6_u32 as _;\npub const NS_E_SESSION_INVALID: windows_sys::core::HRESULT = 0xC00D2F08_u32 as _;\npub const NS_E_SESSION_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D2EF3_u32 as _;\npub const NS_E_SETUP_BLOCKED: windows_sys::core::HRESULT = 0xC00D2B00_u32 as _;\npub const NS_E_SETUP_DRM_MIGRATION_FAILED: windows_sys::core::HRESULT = 0xC00D2AFD_u32 as _;\npub const NS_E_SETUP_DRM_MIGRATION_FAILED_AND_IGNORABLE_FAILURE: windows_sys::core::HRESULT = 0xC00D2AFF_u32 as _;\npub const NS_E_SETUP_IGNORABLE_FAILURE: windows_sys::core::HRESULT = 0xC00D2AFE_u32 as _;\npub const NS_E_SETUP_INCOMPLETE: windows_sys::core::HRESULT = 0xC00D2AFC_u32 as _;\npub const NS_E_SET_DISK_UID_FAILED: windows_sys::core::HRESULT = 0xC00D0021_u32 as _;\npub const NS_E_SHARING_STATE_OUT_OF_SYNC: windows_sys::core::HRESULT = 0xC00D0FF4_u32 as _;\npub const NS_E_SHARING_VIOLATION: windows_sys::core::HRESULT = 0xC00D0FCF_u32 as _;\npub const NS_E_SHUTDOWN: windows_sys::core::HRESULT = 0xC00D002A_u32 as _;\npub const NS_E_SLOW_READ_DIGITAL: windows_sys::core::HRESULT = 0xC00D0FA4_u32 as _;\npub const NS_E_SLOW_READ_DIGITAL_WITH_ERRORCORRECTION: windows_sys::core::HRESULT = 0xC00D11FD_u32 as _;\npub const NS_E_SMPTEMODE_MISMATCH: windows_sys::core::HRESULT = 0xC00D1BAD_u32 as _;\npub const NS_E_SOURCEGROUP_NOTPREPARED: windows_sys::core::HRESULT = 0xC00D1B7A_u32 as _;\npub const NS_E_SOURCE_CANNOT_LOOP: windows_sys::core::HRESULT = 0xC00D1BD3_u32 as _;\npub const NS_E_SOURCE_NOTSPECIFIED: windows_sys::core::HRESULT = 0xC00D1B85_u32 as _;\npub const NS_E_SOURCE_PLUGIN_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D157E_u32 as _;\npub const NS_E_SPEECHEDL_ON_NON_MIXEDMODE: windows_sys::core::HRESULT = 0xC00D1B92_u32 as _;\npub const NS_E_STALE_PRESENTATION: windows_sys::core::HRESULT = 0xC00D1389_u32 as _;\npub const NS_E_STREAM_END: windows_sys::core::HRESULT = 0xC00D0034_u32 as _;\npub const NS_E_STRIDE_REFUSED: windows_sys::core::HRESULT = 0xC00D0045_u32 as _;\npub const NS_E_SUBSCRIPTIONSERVICE_DOWNLOAD_TIMEOUT: windows_sys::core::HRESULT = 0xC00D1360_u32 as _;\npub const NS_E_SUBSCRIPTIONSERVICE_LOGIN_FAILED: windows_sys::core::HRESULT = 0xC00D135F_u32 as _;\npub const NS_E_SUBSCRIPTIONSERVICE_PLAYBACK_DISALLOWED: windows_sys::core::HRESULT = 0xC00D1356_u32 as _;\npub const NS_E_SYNCWIZ_CANNOT_CHANGE_SETTINGS: windows_sys::core::HRESULT = 0xC00D11EF_u32 as _;\npub const NS_E_SYNCWIZ_DEVICE_FULL: windows_sys::core::HRESULT = 0xC00D11EE_u32 as _;\npub const NS_E_TABLE_KEY_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D32CD_u32 as _;\npub const NS_E_TAMPERED_CONTENT: windows_sys::core::HRESULT = 0xC00D0BBF_u32 as _;\npub const NS_E_TCP_DISABLED: windows_sys::core::HRESULT = 0xC00D00D2_u32 as _;\npub const NS_E_TIGER_FAIL: windows_sys::core::HRESULT = 0xC00D0050_u32 as _;\npub const NS_E_TIMECODE_REQUIRES_VIDEOSTREAM: windows_sys::core::HRESULT = 0xC00D1BD9_u32 as _;\npub const NS_E_TIMEOUT: windows_sys::core::HRESULT = 0xC00D0013_u32 as _;\npub const NS_E_TITLE_BITRATE: windows_sys::core::HRESULT = 0xC00D00D5_u32 as _;\npub const NS_E_TITLE_SIZE_EXCEEDED: windows_sys::core::HRESULT = 0xC00D00D0_u32 as _;\npub const NS_E_TOO_MANY_AUDIO: windows_sys::core::HRESULT = 0xC00D1B5C_u32 as _;\npub const NS_E_TOO_MANY_DEVICECONTROL: windows_sys::core::HRESULT = 0xC00D1B96_u32 as _;\npub const NS_E_TOO_MANY_HOPS: windows_sys::core::HRESULT = 0xC00D2F02_u32 as _;\npub const NS_E_TOO_MANY_MULTICAST_SINKS: windows_sys::core::HRESULT = 0xC00D1456_u32 as _;\npub const NS_E_TOO_MANY_SESS: windows_sys::core::HRESULT = 0xC00D000F_u32 as _;\npub const NS_E_TOO_MANY_TITLES: windows_sys::core::HRESULT = 0xC00D00CF_u32 as _;\npub const NS_E_TOO_MANY_VIDEO: windows_sys::core::HRESULT = 0xC00D1B5D_u32 as _;\npub const NS_E_TOO_MUCH_DATA: windows_sys::core::HRESULT = 0xC00D0BCC_u32 as _;\npub const NS_E_TOO_MUCH_DATA_FROM_SERVER: windows_sys::core::HRESULT = 0xC00D2F05_u32 as _;\npub const NS_E_TRACK_DOWNLOAD_REQUIRES_ALBUM_PURCHASE: windows_sys::core::HRESULT = 0xC00D135B_u32 as _;\npub const NS_E_TRACK_DOWNLOAD_REQUIRES_PURCHASE: windows_sys::core::HRESULT = 0xC00D135C_u32 as _;\npub const NS_E_TRACK_PURCHASE_MAXIMUM_EXCEEDED: windows_sys::core::HRESULT = 0xC00D135D_u32 as _;\npub const NS_E_TRANSCODE_DELETECACHEERROR: windows_sys::core::HRESULT = 0xC00D11F0_u32 as _;\npub const NS_E_TRANSFORM_PLUGIN_INVALID: windows_sys::core::HRESULT = 0xC00D1BE6_u32 as _;\npub const NS_E_TRANSFORM_PLUGIN_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D1BE5_u32 as _;\npub const NS_E_UDP_DISABLED: windows_sys::core::HRESULT = 0xC00D00D1_u32 as _;\npub const NS_E_UNABLE_TO_CREATE_RIP_LOCATION: windows_sys::core::HRESULT = 0xC00D10D0_u32 as _;\npub const NS_E_UNCOMPRESSED_DIGITAL_AUDIO_PROTECTION_LEVEL_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D2909_u32 as _;\npub const NS_E_UNCOMPRESSED_DIGITAL_VIDEO_PROTECTION_LEVEL_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D2906_u32 as _;\npub const NS_E_UNCOMP_COMP_COMBINATION: windows_sys::core::HRESULT = 0xC00D1BB6_u32 as _;\npub const NS_E_UNEXPECTED_DISPLAY_SETTINGS: windows_sys::core::HRESULT = 0xC00D1B88_u32 as _;\npub const NS_E_UNEXPECTED_MSAUDIO_ERROR: windows_sys::core::HRESULT = 0xC00D0BBA_u32 as _;\npub const NS_E_UNKNOWN_PROTOCOL: windows_sys::core::HRESULT = 0xC00D2EE0_u32 as _;\npub const NS_E_UNRECOGNIZED_STREAM_TYPE: windows_sys::core::HRESULT = 0xC00D0026_u32 as _;\npub const NS_E_UNSUPPORTED_ARCHIVEOPERATION: windows_sys::core::HRESULT = 0xC00D1B78_u32 as _;\npub const NS_E_UNSUPPORTED_ARCHIVETYPE: windows_sys::core::HRESULT = 0xC00D1B77_u32 as _;\npub const NS_E_UNSUPPORTED_ENCODER_DEVICE: windows_sys::core::HRESULT = 0xC00D1B87_u32 as _;\npub const NS_E_UNSUPPORTED_LANGUAGE: windows_sys::core::HRESULT = 0xC00D145C_u32 as _;\npub const NS_E_UNSUPPORTED_LOAD_TYPE: windows_sys::core::HRESULT = 0xC00D1453_u32 as _;\npub const NS_E_UNSUPPORTED_PROPERTY: windows_sys::core::HRESULT = 0xC00D0BCD_u32 as _;\npub const NS_E_UNSUPPORTED_SOURCETYPE: windows_sys::core::HRESULT = 0xC00D1B5B_u32 as _;\npub const NS_E_URLLIST_INVALIDFORMAT: windows_sys::core::HRESULT = 0xC00D106D_u32 as _;\npub const NS_E_USER_STOP: windows_sys::core::HRESULT = 0xC00D0FA9_u32 as _;\npub const NS_E_USE_FILE_SOURCE: windows_sys::core::HRESULT = 0xC00D32C9_u32 as _;\npub const NS_E_VBRMODE_MISMATCH: windows_sys::core::HRESULT = 0xC00D1B9D_u32 as _;\npub const NS_E_VIDCAPCREATEWINDOW: windows_sys::core::HRESULT = 0xC00D1B6D_u32 as _;\npub const NS_E_VIDCAPDRVINUSE: windows_sys::core::HRESULT = 0xC00D1B6E_u32 as _;\npub const NS_E_VIDCAPSTARTFAILED: windows_sys::core::HRESULT = 0xC00D1B69_u32 as _;\npub const NS_E_VIDEODEVICE_BUSY: windows_sys::core::HRESULT = 0xC00D1B64_u32 as _;\npub const NS_E_VIDEODEVICE_UNEXPECTED: windows_sys::core::HRESULT = 0xC00D1B65_u32 as _;\npub const NS_E_VIDEODRIVER_UNSTABLE: windows_sys::core::HRESULT = 0xC00D1B68_u32 as _;\npub const NS_E_VIDEO_BITRATE_STEPDOWN: windows_sys::core::HRESULT = 0xC00D1BC0_u32 as _;\npub const NS_E_VIDEO_CODEC_ERROR: windows_sys::core::HRESULT = 0xC00D0BC5_u32 as _;\npub const NS_E_VIDEO_CODEC_NOT_INSTALLED: windows_sys::core::HRESULT = 0xC00D0BC4_u32 as _;\npub const NS_E_VIDSOURCECOMPRESSION: windows_sys::core::HRESULT = 0xC00D1B6A_u32 as _;\npub const NS_E_VIDSOURCESIZE: windows_sys::core::HRESULT = 0xC00D1B6B_u32 as _;\npub const NS_E_WALKER_SERVER: windows_sys::core::HRESULT = 0xC00D004D_u32 as _;\npub const NS_E_WALKER_UNKNOWN: windows_sys::core::HRESULT = 0xC00D004C_u32 as _;\npub const NS_E_WALKER_USAGE: windows_sys::core::HRESULT = 0xC00D004E_u32 as _;\npub const NS_E_WAVE_OPEN: windows_sys::core::HRESULT = 0xC00D006D_u32 as _;\npub const NS_E_WINSOCK_ERROR_STRING: windows_sys::core::HRESULT = 0xC00D1129_u32 as _;\npub const NS_E_WIZARD_RUNNING: windows_sys::core::HRESULT = 0xC00D1584_u32 as _;\npub const NS_E_WMDM_REVOKED: windows_sys::core::HRESULT = 0xC00D10BC_u32 as _;\npub const NS_E_WMDRM_DEPRECATED: windows_sys::core::HRESULT = 0xC00D0BDE_u32 as _;\npub const NS_E_WME_VERSION_MISMATCH: windows_sys::core::HRESULT = 0xC00D1B8B_u32 as _;\npub const NS_E_WMG_CANNOTQUEUE: windows_sys::core::HRESULT = 0xC00D104C_u32 as _;\npub const NS_E_WMG_COPP_SECURITY_INVALID: windows_sys::core::HRESULT = 0xC00D1052_u32 as _;\npub const NS_E_WMG_COPP_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D1053_u32 as _;\npub const NS_E_WMG_FILETRANSFERNOTALLOWED: windows_sys::core::HRESULT = 0xC00D1058_u32 as _;\npub const NS_E_WMG_INVALIDSTATE: windows_sys::core::HRESULT = 0xC00D1054_u32 as _;\npub const NS_E_WMG_INVALID_COPP_CERTIFICATE: windows_sys::core::HRESULT = 0xC00D1051_u32 as _;\npub const NS_E_WMG_LICENSE_TAMPERED: windows_sys::core::HRESULT = 0xC00D1064_u32 as _;\npub const NS_E_WMG_NOSDKINTERFACE: windows_sys::core::HRESULT = 0xC00D1056_u32 as _;\npub const NS_E_WMG_NOTALLOUTPUTSRENDERED: windows_sys::core::HRESULT = 0xC00D1057_u32 as _;\npub const NS_E_WMG_PLUGINUNAVAILABLE: windows_sys::core::HRESULT = 0xC00D104B_u32 as _;\npub const NS_E_WMG_PREROLLLICENSEACQUISITIONNOTALLOWED: windows_sys::core::HRESULT = 0xC00D104D_u32 as _;\npub const NS_E_WMG_RATEUNAVAILABLE: windows_sys::core::HRESULT = 0xC00D104A_u32 as _;\npub const NS_E_WMG_SINKALREADYEXISTS: windows_sys::core::HRESULT = 0xC00D1055_u32 as _;\npub const NS_E_WMG_UNEXPECTEDPREROLLSTATUS: windows_sys::core::HRESULT = 0xC00D104E_u32 as _;\npub const NS_E_WMPBR_BACKUPCANCEL: windows_sys::core::HRESULT = 0xC00D1131_u32 as _;\npub const NS_E_WMPBR_BACKUPRESTOREFAILED: windows_sys::core::HRESULT = 0xC00D1138_u32 as _;\npub const NS_E_WMPBR_DRIVE_INVALID: windows_sys::core::HRESULT = 0xC00D1137_u32 as _;\npub const NS_E_WMPBR_ERRORWITHURL: windows_sys::core::HRESULT = 0xC00D1133_u32 as _;\npub const NS_E_WMPBR_NAMECOLLISION: windows_sys::core::HRESULT = 0xC00D1134_u32 as _;\npub const NS_E_WMPBR_NOLISTENER: windows_sys::core::HRESULT = 0xC00D1130_u32 as _;\npub const NS_E_WMPBR_RESTORECANCEL: windows_sys::core::HRESULT = 0xC00D1132_u32 as _;\npub const NS_E_WMPCORE_BUFFERTOOSMALL: windows_sys::core::HRESULT = 0xC00D107F_u32 as _;\npub const NS_E_WMPCORE_BUSY: windows_sys::core::HRESULT = 0xC00D10B7_u32 as _;\npub const NS_E_WMPCORE_COCREATEFAILEDFORGITOBJECT: windows_sys::core::HRESULT = 0xC00D107D_u32 as _;\npub const NS_E_WMPCORE_CODEC_DOWNLOAD_NOT_ALLOWED: windows_sys::core::HRESULT = 0xC00D109C_u32 as _;\npub const NS_E_WMPCORE_CODEC_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D109B_u32 as _;\npub const NS_E_WMPCORE_CODEC_NOT_TRUSTED: windows_sys::core::HRESULT = 0xC00D109A_u32 as _;\npub const NS_E_WMPCORE_CURRENT_MEDIA_NOT_ACTIVE: windows_sys::core::HRESULT = 0xC00D10A9_u32 as _;\npub const NS_E_WMPCORE_DEVICE_DRIVERS_MISSING: windows_sys::core::HRESULT = 0xC00D10DD_u32 as _;\npub const NS_E_WMPCORE_ERRORMANAGERNOTAVAILABLE: windows_sys::core::HRESULT = 0xC00D108D_u32 as _;\npub const NS_E_WMPCORE_ERRORSINKNOTREGISTERED: windows_sys::core::HRESULT = 0xC00D108C_u32 as _;\npub const NS_E_WMPCORE_ERROR_DOWNLOADING_PLAYLIST: windows_sys::core::HRESULT = 0xC00D109D_u32 as _;\npub const NS_E_WMPCORE_FAILEDTOGETMARSHALLEDEVENTHANDLERINTERFACE: windows_sys::core::HRESULT = 0xC00D107E_u32 as _;\npub const NS_E_WMPCORE_FAILED_TO_BUILD_PLAYLIST: windows_sys::core::HRESULT = 0xC00D109E_u32 as _;\npub const NS_E_WMPCORE_FILE_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D10BA_u32 as _;\npub const NS_E_WMPCORE_GRAPH_NOT_IN_LIST: windows_sys::core::HRESULT = 0xC00D108A_u32 as _;\npub const NS_E_WMPCORE_INVALIDPLAYLISTMODE: windows_sys::core::HRESULT = 0xC00D1081_u32 as _;\npub const NS_E_WMPCORE_INVALID_PLAYLIST_URL: windows_sys::core::HRESULT = 0xC00D10AF_u32 as _;\npub const NS_E_WMPCORE_ITEMNOTINPLAYLIST: windows_sys::core::HRESULT = 0xC00D1086_u32 as _;\npub const NS_E_WMPCORE_LIST_ENTRY_NO_REF: windows_sys::core::HRESULT = 0xC00D1098_u32 as _;\npub const NS_E_WMPCORE_MEDIA_ALTERNATE_REF_EMPTY: windows_sys::core::HRESULT = 0xC00D10A4_u32 as _;\npub const NS_E_WMPCORE_MEDIA_CHILD_PLAYLIST_UNAVAILABLE: windows_sys::core::HRESULT = 0xC00D10B8_u32 as _;\npub const NS_E_WMPCORE_MEDIA_ERROR_RESUME_FAILED: windows_sys::core::HRESULT = 0xC00D108F_u32 as _;\npub const NS_E_WMPCORE_MEDIA_NO_CHILD_PLAYLIST: windows_sys::core::HRESULT = 0xC00D10B9_u32 as _;\npub const NS_E_WMPCORE_MEDIA_UNAVAILABLE: windows_sys::core::HRESULT = 0xC00D10B3_u32 as _;\npub const NS_E_WMPCORE_MEDIA_URL_TOO_LONG: windows_sys::core::HRESULT = 0xC00D10C8_u32 as _;\npub const NS_E_WMPCORE_MISMATCHED_RUNTIME: windows_sys::core::HRESULT = 0xC00D10B0_u32 as _;\npub const NS_E_WMPCORE_MISNAMED_FILE: windows_sys::core::HRESULT = 0xC00D1099_u32 as _;\npub const NS_E_WMPCORE_NOBROWSER: windows_sys::core::HRESULT = 0xC00D1088_u32 as _;\npub const NS_E_WMPCORE_NOSOURCEURLSTRING: windows_sys::core::HRESULT = 0xC00D107C_u32 as _;\npub const NS_E_WMPCORE_NO_PLAYABLE_MEDIA_IN_PLAYLIST: windows_sys::core::HRESULT = 0xC00D10B5_u32 as _;\npub const NS_E_WMPCORE_NO_REF_IN_ENTRY: windows_sys::core::HRESULT = 0xC00D1090_u32 as _;\npub const NS_E_WMPCORE_PLAYLISTEMPTY: windows_sys::core::HRESULT = 0xC00D1087_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_EMPTY_NESTED_PLAYLIST_SKIPPED_ITEMS: windows_sys::core::HRESULT = 0xC00D10B6_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_EMPTY_OR_SINGLE_MEDIA: windows_sys::core::HRESULT = 0xC00D108B_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_EVENT_ATTRIBUTE_ABSENT: windows_sys::core::HRESULT = 0xC00D10A6_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_EVENT_EMPTY: windows_sys::core::HRESULT = 0xC00D10A7_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_IMPORT_FAILED_NO_ITEMS: windows_sys::core::HRESULT = 0xC00D10B1_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_ITEM_ALTERNATE_EXHAUSTED: windows_sys::core::HRESULT = 0xC00D10A0_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_ITEM_ALTERNATE_INIT_FAILED: windows_sys::core::HRESULT = 0xC00D10A3_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_ITEM_ALTERNATE_MORPH_FAILED: windows_sys::core::HRESULT = 0xC00D10A2_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_ITEM_ALTERNATE_NAME_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D10A1_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_ITEM_ALTERNATE_NONE: windows_sys::core::HRESULT = 0xC00D109F_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_NO_EVENT_NAME: windows_sys::core::HRESULT = 0xC00D10A5_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_REPEAT_EMPTY: windows_sys::core::HRESULT = 0xC00D10AC_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_REPEAT_END_MEDIA_NONE: windows_sys::core::HRESULT = 0xC00D10AE_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_REPEAT_START_MEDIA_NONE: windows_sys::core::HRESULT = 0xC00D10AD_u32 as _;\npub const NS_E_WMPCORE_PLAYLIST_STACK_EMPTY: windows_sys::core::HRESULT = 0xC00D10A8_u32 as _;\npub const NS_E_WMPCORE_SOME_CODECS_MISSING: windows_sys::core::HRESULT = 0xC00D10D1_u32 as _;\npub const NS_E_WMPCORE_TEMP_FILE_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D10BB_u32 as _;\npub const NS_E_WMPCORE_UNAVAILABLE: windows_sys::core::HRESULT = 0xC00D1080_u32 as _;\npub const NS_E_WMPCORE_UNRECOGNIZED_MEDIA_URL: windows_sys::core::HRESULT = 0xC00D1089_u32 as _;\npub const NS_E_WMPCORE_USER_CANCEL: windows_sys::core::HRESULT = 0xC00D10AB_u32 as _;\npub const NS_E_WMPCORE_VIDEO_TRANSFORM_FILTER_INSERTION: windows_sys::core::HRESULT = 0xC00D10B2_u32 as _;\npub const NS_E_WMPCORE_WEBHELPFAILED: windows_sys::core::HRESULT = 0xC00D108E_u32 as _;\npub const NS_E_WMPCORE_WMX_ENTRYREF_NO_REF: windows_sys::core::HRESULT = 0xC00D10B4_u32 as _;\npub const NS_E_WMPCORE_WMX_LIST_ATTRIBUTE_NAME_EMPTY: windows_sys::core::HRESULT = 0xC00D1091_u32 as _;\npub const NS_E_WMPCORE_WMX_LIST_ATTRIBUTE_NAME_ILLEGAL: windows_sys::core::HRESULT = 0xC00D1092_u32 as _;\npub const NS_E_WMPCORE_WMX_LIST_ATTRIBUTE_VALUE_EMPTY: windows_sys::core::HRESULT = 0xC00D1093_u32 as _;\npub const NS_E_WMPCORE_WMX_LIST_ATTRIBUTE_VALUE_ILLEGAL: windows_sys::core::HRESULT = 0xC00D1094_u32 as _;\npub const NS_E_WMPCORE_WMX_LIST_ITEM_ATTRIBUTE_NAME_EMPTY: windows_sys::core::HRESULT = 0xC00D1095_u32 as _;\npub const NS_E_WMPCORE_WMX_LIST_ITEM_ATTRIBUTE_NAME_ILLEGAL: windows_sys::core::HRESULT = 0xC00D1096_u32 as _;\npub const NS_E_WMPCORE_WMX_LIST_ITEM_ATTRIBUTE_VALUE_EMPTY: windows_sys::core::HRESULT = 0xC00D1097_u32 as _;\npub const NS_E_WMPFLASH_CANT_FIND_COM_SERVER: windows_sys::core::HRESULT = 0xC00D10C9_u32 as _;\npub const NS_E_WMPFLASH_INCOMPATIBLEVERSION: windows_sys::core::HRESULT = 0xC00D10CA_u32 as _;\npub const NS_E_WMPIM_DIALUPFAILED: windows_sys::core::HRESULT = 0xC00D1128_u32 as _;\npub const NS_E_WMPIM_USERCANCELED: windows_sys::core::HRESULT = 0xC00D1127_u32 as _;\npub const NS_E_WMPIM_USEROFFLINE: windows_sys::core::HRESULT = 0xC00D1126_u32 as _;\npub const NS_E_WMPOCXGRAPH_IE_DISALLOWS_ACTIVEX_CONTROLS: windows_sys::core::HRESULT = 0xC00D10CB_u32 as _;\npub const NS_E_WMPOCX_ERRORMANAGERNOTAVAILABLE: windows_sys::core::HRESULT = 0xC00D0FD5_u32 as _;\npub const NS_E_WMPOCX_NOT_RUNNING_REMOTELY: windows_sys::core::HRESULT = 0xC00D0FD3_u32 as _;\npub const NS_E_WMPOCX_NO_ACTIVE_CORE: windows_sys::core::HRESULT = 0xC00D0FD2_u32 as _;\npub const NS_E_WMPOCX_NO_REMOTE_CORE: windows_sys::core::HRESULT = 0xC00D0FD1_u32 as _;\npub const NS_E_WMPOCX_NO_REMOTE_WINDOW: windows_sys::core::HRESULT = 0xC00D0FD4_u32 as _;\npub const NS_E_WMPOCX_PLAYER_NOT_DOCKED: windows_sys::core::HRESULT = 0xC00D0FDB_u32 as _;\npub const NS_E_WMPOCX_REMOTE_PLAYER_ALREADY_RUNNING: windows_sys::core::HRESULT = 0xC00D0FFA_u32 as _;\npub const NS_E_WMPOCX_UNABLE_TO_LOAD_SKIN: windows_sys::core::HRESULT = 0xC00D0FEB_u32 as _;\npub const NS_E_WMPXML_ATTRIBUTENOTFOUND: windows_sys::core::HRESULT = 0xC00D0FB7_u32 as _;\npub const NS_E_WMPXML_EMPTYDOC: windows_sys::core::HRESULT = 0xC00D0FB9_u32 as _;\npub const NS_E_WMPXML_ENDOFDATA: windows_sys::core::HRESULT = 0xC00D0FB5_u32 as _;\npub const NS_E_WMPXML_NOERROR: windows_sys::core::HRESULT = 0xC00D0FB4_u32 as _;\npub const NS_E_WMPXML_PARSEERROR: windows_sys::core::HRESULT = 0xC00D0FB6_u32 as _;\npub const NS_E_WMPXML_PINOTFOUND: windows_sys::core::HRESULT = 0xC00D0FB8_u32 as _;\npub const NS_E_WMPZIP_CORRUPT: windows_sys::core::HRESULT = 0xC00D1019_u32 as _;\npub const NS_E_WMPZIP_FILENOTFOUND: windows_sys::core::HRESULT = 0xC00D101A_u32 as _;\npub const NS_E_WMPZIP_NOTAZIPFILE: windows_sys::core::HRESULT = 0xC00D1018_u32 as _;\npub const NS_E_WMP_ACCESS_DENIED: windows_sys::core::HRESULT = 0xC00D11D2_u32 as _;\npub const NS_E_WMP_ADDTOLIBRARY_FAILED: windows_sys::core::HRESULT = 0xC00D0FC7_u32 as _;\npub const NS_E_WMP_ALREADY_IN_USE: windows_sys::core::HRESULT = 0xC00D119E_u32 as _;\npub const NS_E_WMP_AUDIO_CODEC_NOT_INSTALLED: windows_sys::core::HRESULT = 0xC00D11C7_u32 as _;\npub const NS_E_WMP_AUDIO_DEVICE_LOST: windows_sys::core::HRESULT = 0xC00D11E5_u32 as _;\npub const NS_E_WMP_AUDIO_HW_PROBLEM: windows_sys::core::HRESULT = 0xC00D11BA_u32 as _;\npub const NS_E_WMP_AUTOPLAY_INVALID_STATE: windows_sys::core::HRESULT = 0xC00D12FC_u32 as _;\npub const NS_E_WMP_BAD_DRIVER: windows_sys::core::HRESULT = 0xC00D11D1_u32 as _;\npub const NS_E_WMP_BMP_BITMAP_NOT_CREATED: windows_sys::core::HRESULT = 0xC00D1030_u32 as _;\npub const NS_E_WMP_BMP_COMPRESSION_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D1031_u32 as _;\npub const NS_E_WMP_BMP_INVALID_BITMASK: windows_sys::core::HRESULT = 0xC00D102E_u32 as _;\npub const NS_E_WMP_BMP_INVALID_FORMAT: windows_sys::core::HRESULT = 0xC00D1032_u32 as _;\npub const NS_E_WMP_BMP_TOPDOWN_DIB_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D102F_u32 as _;\npub const NS_E_WMP_BSTR_TOO_LONG: windows_sys::core::HRESULT = 0xC00D12F2_u32 as _;\npub const NS_E_WMP_BURN_DISC_OVERFLOW: windows_sys::core::HRESULT = 0xC00D11D9_u32 as _;\npub const NS_E_WMP_CANNOT_BURN_NON_LOCAL_FILE: windows_sys::core::HRESULT = 0xC00D10D6_u32 as _;\npub const NS_E_WMP_CANNOT_FIND_FILE: windows_sys::core::HRESULT = 0xC00D1197_u32 as _;\npub const NS_E_WMP_CANNOT_FIND_FOLDER: windows_sys::core::HRESULT = 0xC00D0FD7_u32 as _;\npub const NS_E_WMP_CANT_PLAY_PROTECTED: windows_sys::core::HRESULT = 0xC00D0FF3_u32 as _;\npub const NS_E_WMP_CD_ANOTHER_USER: windows_sys::core::HRESULT = 0xC00D11CF_u32 as _;\npub const NS_E_WMP_CD_STASH_NO_SPACE: windows_sys::core::HRESULT = 0xC00D11D5_u32 as _;\npub const NS_E_WMP_CODEC_NEEDED_WITH_4CC: windows_sys::core::HRESULT = 0xC00D11A1_u32 as _;\npub const NS_E_WMP_CODEC_NEEDED_WITH_FORMATTAG: windows_sys::core::HRESULT = 0xC00D11A2_u32 as _;\npub const NS_E_WMP_COMPONENT_REVOKED: windows_sys::core::HRESULT = 0xC00D1306_u32 as _;\npub const NS_E_WMP_CONNECT_TIMEOUT: windows_sys::core::HRESULT = 0xC00D11C1_u32 as _;\npub const NS_E_WMP_CONVERT_FILE_CORRUPT: windows_sys::core::HRESULT = 0xC00D115B_u32 as _;\npub const NS_E_WMP_CONVERT_FILE_FAILED: windows_sys::core::HRESULT = 0xC00D1158_u32 as _;\npub const NS_E_WMP_CONVERT_NO_RIGHTS_ERRORURL: windows_sys::core::HRESULT = 0xC00D1159_u32 as _;\npub const NS_E_WMP_CONVERT_NO_RIGHTS_NOERRORURL: windows_sys::core::HRESULT = 0xC00D115A_u32 as _;\npub const NS_E_WMP_CONVERT_PLUGIN_UNAVAILABLE_ERRORURL: windows_sys::core::HRESULT = 0xC00D115C_u32 as _;\npub const NS_E_WMP_CONVERT_PLUGIN_UNAVAILABLE_NOERRORURL: windows_sys::core::HRESULT = 0xC00D115D_u32 as _;\npub const NS_E_WMP_CONVERT_PLUGIN_UNKNOWN_FILE_OWNER: windows_sys::core::HRESULT = 0xC00D115E_u32 as _;\npub const NS_E_WMP_CS_JPGPOSITIONIMAGE: windows_sys::core::HRESULT = 0xC00D100E_u32 as _;\npub const NS_E_WMP_CS_NOTEVENLYDIVISIBLE: windows_sys::core::HRESULT = 0xC00D100F_u32 as _;\npub const NS_E_WMP_DAI_SONGTOOSHORT: windows_sys::core::HRESULT = 0xC00D1049_u32 as _;\npub const NS_E_WMP_DRM_ACQUIRING_LICENSE: windows_sys::core::HRESULT = 0xC00D1202_u32 as _;\npub const NS_E_WMP_DRM_CANNOT_RESTORE: windows_sys::core::HRESULT = 0xC00D11D8_u32 as _;\npub const NS_E_WMP_DRM_COMPONENT_FAILURE: windows_sys::core::HRESULT = 0xC00D11E2_u32 as _;\npub const NS_E_WMP_DRM_CORRUPT_BACKUP: windows_sys::core::HRESULT = 0xC00D11B4_u32 as _;\npub const NS_E_WMP_DRM_DRIVER_AUTH_FAILURE: windows_sys::core::HRESULT = 0xC00D11CA_u32 as _;\npub const NS_E_WMP_DRM_GENERIC_LICENSE_FAILURE: windows_sys::core::HRESULT = 0xC00D11DA_u32 as _;\npub const NS_E_WMP_DRM_INDIV_FAILED: windows_sys::core::HRESULT = 0xC00D11DD_u32 as _;\npub const NS_E_WMP_DRM_INVALID_SIG: windows_sys::core::HRESULT = 0xC00D11D7_u32 as _;\npub const NS_E_WMP_DRM_LICENSE_CONTENT_REVOKED: windows_sys::core::HRESULT = 0xC00D1207_u32 as _;\npub const NS_E_WMP_DRM_LICENSE_EXPIRED: windows_sys::core::HRESULT = 0xC00D1203_u32 as _;\npub const NS_E_WMP_DRM_LICENSE_NOSAP: windows_sys::core::HRESULT = 0xC00D1208_u32 as _;\npub const NS_E_WMP_DRM_LICENSE_NOTACQUIRED: windows_sys::core::HRESULT = 0xC00D1204_u32 as _;\npub const NS_E_WMP_DRM_LICENSE_NOTENABLED: windows_sys::core::HRESULT = 0xC00D1205_u32 as _;\npub const NS_E_WMP_DRM_LICENSE_SERVER_UNAVAILABLE: windows_sys::core::HRESULT = 0xC00D11B5_u32 as _;\npub const NS_E_WMP_DRM_LICENSE_UNUSABLE: windows_sys::core::HRESULT = 0xC00D1206_u32 as _;\npub const NS_E_WMP_DRM_NEEDS_AUTHORIZATION: windows_sys::core::HRESULT = 0xC00D11D0_u32 as _;\npub const NS_E_WMP_DRM_NEW_HARDWARE: windows_sys::core::HRESULT = 0xC00D11D6_u32 as _;\npub const NS_E_WMP_DRM_NOT_ACQUIRING: windows_sys::core::HRESULT = 0xC00D12C1_u32 as _;\npub const NS_E_WMP_DRM_NO_DEVICE_CERT: windows_sys::core::HRESULT = 0xC00D11E3_u32 as _;\npub const NS_E_WMP_DRM_NO_RIGHTS: windows_sys::core::HRESULT = 0xC00D11DC_u32 as _;\npub const NS_E_WMP_DRM_NO_SECURE_CLOCK: windows_sys::core::HRESULT = 0xC00D11DB_u32 as _;\npub const NS_E_WMP_DRM_UNABLE_TO_ACQUIRE_LICENSE: windows_sys::core::HRESULT = 0xC00D1209_u32 as _;\npub const NS_E_WMP_DSHOW_UNSUPPORTED_FORMAT: windows_sys::core::HRESULT = 0xC00D119A_u32 as _;\npub const NS_E_WMP_ERASE_FAILED: windows_sys::core::HRESULT = 0xC00D10D4_u32 as _;\npub const NS_E_WMP_EXTERNAL_NOTREADY: windows_sys::core::HRESULT = 0xC00D0FDC_u32 as _;\npub const NS_E_WMP_FAILED_TO_OPEN_IMAGE: windows_sys::core::HRESULT = 0xC00D1044_u32 as _;\npub const NS_E_WMP_FAILED_TO_OPEN_WMD: windows_sys::core::HRESULT = 0xC00D0FF2_u32 as _;\npub const NS_E_WMP_FAILED_TO_RIP_TRACK: windows_sys::core::HRESULT = 0xC00D10D3_u32 as _;\npub const NS_E_WMP_FAILED_TO_SAVE_FILE: windows_sys::core::HRESULT = 0xC00D0FEF_u32 as _;\npub const NS_E_WMP_FAILED_TO_SAVE_PLAYLIST: windows_sys::core::HRESULT = 0xC00D0FF1_u32 as _;\npub const NS_E_WMP_FILESCANALREADYSTARTED: windows_sys::core::HRESULT = 0xC00D0FBE_u32 as _;\npub const NS_E_WMP_FILE_DOES_NOT_FIT_ON_CD: windows_sys::core::HRESULT = 0xC00D10D8_u32 as _;\npub const NS_E_WMP_FILE_NO_DURATION: windows_sys::core::HRESULT = 0xC00D10D9_u32 as _;\npub const NS_E_WMP_FILE_OPEN_FAILED: windows_sys::core::HRESULT = 0xC00D11B1_u32 as _;\npub const NS_E_WMP_FILE_TYPE_CANNOT_BURN_TO_AUDIO_CD: windows_sys::core::HRESULT = 0xC00D10D7_u32 as _;\npub const NS_E_WMP_FORMAT_FAILED: windows_sys::core::HRESULT = 0xC00D10D5_u32 as _;\npub const NS_E_WMP_GIF_BAD_VERSION_NUMBER: windows_sys::core::HRESULT = 0xC00D1026_u32 as _;\npub const NS_E_WMP_GIF_INVALID_FORMAT: windows_sys::core::HRESULT = 0xC00D1025_u32 as _;\npub const NS_E_WMP_GIF_NO_IMAGE_IN_FILE: windows_sys::core::HRESULT = 0xC00D1027_u32 as _;\npub const NS_E_WMP_GIF_UNEXPECTED_ENDOFFILE: windows_sys::core::HRESULT = 0xC00D1024_u32 as _;\npub const NS_E_WMP_GOFULLSCREEN_FAILED: windows_sys::core::HRESULT = 0xC00D11BF_u32 as _;\npub const NS_E_WMP_HME_INVALIDOBJECTID: windows_sys::core::HRESULT = 0xC00D0FBF_u32 as _;\npub const NS_E_WMP_HME_NOTSEARCHABLEFORITEMS: windows_sys::core::HRESULT = 0xC00D0FC1_u32 as _;\npub const NS_E_WMP_HME_STALEREQUEST: windows_sys::core::HRESULT = 0xC00D0FC2_u32 as _;\npub const NS_E_WMP_HWND_NOTFOUND: windows_sys::core::HRESULT = 0xC00D125C_u32 as _;\npub const NS_E_WMP_IMAGE_FILETYPE_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D1022_u32 as _;\npub const NS_E_WMP_IMAGE_INVALID_FORMAT: windows_sys::core::HRESULT = 0xC00D1023_u32 as _;\npub const NS_E_WMP_IMAPI2_ERASE_DEVICE_BUSY: windows_sys::core::HRESULT = 0xC00D11E1_u32 as _;\npub const NS_E_WMP_IMAPI2_ERASE_FAIL: windows_sys::core::HRESULT = 0xC00D11E0_u32 as _;\npub const NS_E_WMP_IMAPI_DEVICE_BUSY: windows_sys::core::HRESULT = 0xC00D11AE_u32 as _;\npub const NS_E_WMP_IMAPI_DEVICE_INVALIDTYPE: windows_sys::core::HRESULT = 0xC00D11C9_u32 as _;\npub const NS_E_WMP_IMAPI_DEVICE_NOTPRESENT: windows_sys::core::HRESULT = 0xC00D11AD_u32 as _;\npub const NS_E_WMP_IMAPI_FAILURE: windows_sys::core::HRESULT = 0xC00D119F_u32 as _;\npub const NS_E_WMP_IMAPI_GENERIC: windows_sys::core::HRESULT = 0xC00D11AB_u32 as _;\npub const NS_E_WMP_IMAPI_LOSS_OF_STREAMING: windows_sys::core::HRESULT = 0xC00D11AF_u32 as _;\npub const NS_E_WMP_IMAPI_MEDIA_INCOMPATIBLE: windows_sys::core::HRESULT = 0xC00D11E6_u32 as _;\npub const NS_E_WMP_INVALID_ASX: windows_sys::core::HRESULT = 0xC00D119D_u32 as _;\npub const NS_E_WMP_INVALID_KEY: windows_sys::core::HRESULT = 0xC00D11CE_u32 as _;\npub const NS_E_WMP_INVALID_LIBRARY_ADD: windows_sys::core::HRESULT = 0xC00D11BC_u32 as _;\npub const NS_E_WMP_INVALID_MAX_VAL: windows_sys::core::HRESULT = 0xC00D1009_u32 as _;\npub const NS_E_WMP_INVALID_MIN_VAL: windows_sys::core::HRESULT = 0xC00D100A_u32 as _;\npub const NS_E_WMP_INVALID_PROTOCOL: windows_sys::core::HRESULT = 0xC00D11BB_u32 as _;\npub const NS_E_WMP_INVALID_REQUEST: windows_sys::core::HRESULT = 0xC00D11D4_u32 as _;\npub const NS_E_WMP_INVALID_SKIN: windows_sys::core::HRESULT = 0xC00D0FEC_u32 as _;\npub const NS_E_WMP_JPGTRANSPARENCY: windows_sys::core::HRESULT = 0xC00D1005_u32 as _;\npub const NS_E_WMP_JPG_BAD_DCTSIZE: windows_sys::core::HRESULT = 0xC00D1035_u32 as _;\npub const NS_E_WMP_JPG_BAD_PRECISION: windows_sys::core::HRESULT = 0xC00D1037_u32 as _;\npub const NS_E_WMP_JPG_BAD_VERSION_NUMBER: windows_sys::core::HRESULT = 0xC00D1036_u32 as _;\npub const NS_E_WMP_JPG_CCIR601_NOTIMPL: windows_sys::core::HRESULT = 0xC00D1038_u32 as _;\npub const NS_E_WMP_JPG_FRACT_SAMPLE_NOTIMPL: windows_sys::core::HRESULT = 0xC00D103B_u32 as _;\npub const NS_E_WMP_JPG_IMAGE_TOO_BIG: windows_sys::core::HRESULT = 0xC00D103C_u32 as _;\npub const NS_E_WMP_JPG_INVALID_FORMAT: windows_sys::core::HRESULT = 0xC00D1034_u32 as _;\npub const NS_E_WMP_JPG_JERR_ARITHCODING_NOTIMPL: windows_sys::core::HRESULT = 0xC00D1033_u32 as _;\npub const NS_E_WMP_JPG_NO_IMAGE_IN_FILE: windows_sys::core::HRESULT = 0xC00D1039_u32 as _;\npub const NS_E_WMP_JPG_READ_ERROR: windows_sys::core::HRESULT = 0xC00D103A_u32 as _;\npub const NS_E_WMP_JPG_SOF_UNSUPPORTED: windows_sys::core::HRESULT = 0xC00D103E_u32 as _;\npub const NS_E_WMP_JPG_UNEXPECTED_ENDOFFILE: windows_sys::core::HRESULT = 0xC00D103D_u32 as _;\npub const NS_E_WMP_JPG_UNKNOWN_MARKER: windows_sys::core::HRESULT = 0xC00D103F_u32 as _;\npub const NS_E_WMP_LICENSE_REQUIRED: windows_sys::core::HRESULT = 0xC00D120A_u32 as _;\npub const NS_E_WMP_LICENSE_RESTRICTS: windows_sys::core::HRESULT = 0xC00D11D3_u32 as _;\npub const NS_E_WMP_LOCKEDINSKINMODE: windows_sys::core::HRESULT = 0xC00D0FEE_u32 as _;\npub const NS_E_WMP_LOGON_FAILURE: windows_sys::core::HRESULT = 0xC00D1196_u32 as _;\npub const NS_E_WMP_MF_CODE_EXPIRED: windows_sys::core::HRESULT = 0xC00D0FC0_u32 as _;\npub const NS_E_WMP_MLS_STALE_DATA: windows_sys::core::HRESULT = 0xC00D0FDD_u32 as _;\npub const NS_E_WMP_MMS_NOT_SUPPORTED: windows_sys::core::HRESULT = 0xC00D11BD_u32 as _;\npub const NS_E_WMP_MSSAP_NOT_AVAILABLE: windows_sys::core::HRESULT = 0xC00D11A3_u32 as _;\npub const NS_E_WMP_MULTICAST_DISABLED: windows_sys::core::HRESULT = 0xC00D11C2_u32 as _;\npub const NS_E_WMP_MULTIPLE_ERROR_IN_PLAYLIST: windows_sys::core::HRESULT = 0xC00D11DF_u32 as _;\npub const NS_E_WMP_NEED_UPGRADE: windows_sys::core::HRESULT = 0xC00D11B9_u32 as _;\npub const NS_E_WMP_NETWORK_ERROR: windows_sys::core::HRESULT = 0xC00D11C0_u32 as _;\npub const NS_E_WMP_NETWORK_FIREWALL: windows_sys::core::HRESULT = 0xC00D11B6_u32 as _;\npub const NS_E_WMP_NETWORK_RESOURCE_FAILURE: windows_sys::core::HRESULT = 0xC00D11CB_u32 as _;\npub const NS_E_WMP_NONMEDIA_FILES: windows_sys::core::HRESULT = 0xC00D119C_u32 as _;\npub const NS_E_WMP_NO_DISK_SPACE: windows_sys::core::HRESULT = 0xC00D1195_u32 as _;\npub const NS_E_WMP_NO_PROTOCOLS_SELECTED: windows_sys::core::HRESULT = 0xC00D11BE_u32 as _;\npub const NS_E_WMP_NO_REMOVABLE_MEDIA: windows_sys::core::HRESULT = 0xC00D11B7_u32 as _;\npub const NS_E_WMP_OUTOFMEMORY: windows_sys::core::HRESULT = 0xC00D11C6_u32 as _;\npub const NS_E_WMP_PATH_ALREADY_IN_LIBRARY: windows_sys::core::HRESULT = 0xC00D0FBA_u32 as _;\npub const NS_E_WMP_PLAYLIST_EXISTS: windows_sys::core::HRESULT = 0xC00D119B_u32 as _;\npub const NS_E_WMP_PLUGINDLL_NOTFOUND: windows_sys::core::HRESULT = 0xC00D0FD9_u32 as _;\npub const NS_E_WMP_PNG_INVALIDFORMAT: windows_sys::core::HRESULT = 0xC00D1028_u32 as _;\npub const NS_E_WMP_PNG_UNSUPPORTED_BAD_CRC: windows_sys::core::HRESULT = 0xC00D102D_u32 as _;\npub const NS_E_WMP_PNG_UNSUPPORTED_BITDEPTH: windows_sys::core::HRESULT = 0xC00D1029_u32 as _;\npub const NS_E_WMP_PNG_UNSUPPORTED_COMPRESSION: windows_sys::core::HRESULT = 0xC00D102A_u32 as _;\npub const NS_E_WMP_PNG_UNSUPPORTED_FILTER: windows_sys::core::HRESULT = 0xC00D102B_u32 as _;\npub const NS_E_WMP_PNG_UNSUPPORTED_INTERLACE: windows_sys::core::HRESULT = 0xC00D102C_u32 as _;\npub const NS_E_WMP_POLICY_VALUE_NOT_CONFIGURED: windows_sys::core::HRESULT = 0xC00D122A_u32 as _;\npub const NS_E_WMP_PROTECTED_CONTENT: windows_sys::core::HRESULT = 0xC00D120B_u32 as _;\npub const NS_E_WMP_PROTOCOL_PROBLEM: windows_sys::core::HRESULT = 0xC00D1194_u32 as _;\npub const NS_E_WMP_PROXY_CONNECT_TIMEOUT: windows_sys::core::HRESULT = 0xC00D11B8_u32 as _;\npub const NS_E_WMP_PROXY_NOT_FOUND: windows_sys::core::HRESULT = 0xC00D11C4_u32 as _;\npub const NS_E_WMP_RBC_JPGMAPPINGIMAGE: windows_sys::core::HRESULT = 0xC00D1004_u32 as _;\npub const NS_E_WMP_RECORDING_NOT_ALLOWED: windows_sys::core::HRESULT = 0xC00D0FC9_u32 as _;\npub const NS_E_WMP_RIP_FAILED: windows_sys::core::HRESULT = 0xC00D10D2_u32 as _;\npub const NS_E_WMP_SAVEAS_READONLY: windows_sys::core::HRESULT = 0xC00D0FF0_u32 as _;\npub const NS_E_WMP_SENDMAILFAILED: windows_sys::core::HRESULT = 0xC00D0FED_u32 as _;\npub const NS_E_WMP_SERVER_DNS_TIMEOUT: windows_sys::core::HRESULT = 0xC00D11C3_u32 as _;\npub const NS_E_WMP_SERVER_INACCESSIBLE: windows_sys::core::HRESULT = 0xC00D1198_u32 as _;\npub const NS_E_WMP_SERVER_NONEWCONNECTIONS: windows_sys::core::HRESULT = 0xC00D11DE_u32 as _;\npub const NS_E_WMP_SERVER_NOT_RESPONDING: windows_sys::core::HRESULT = 0xC00D11B3_u32 as _;\npub const NS_E_WMP_SERVER_SECURITY_ERROR: windows_sys::core::HRESULT = 0xC00D11E4_u32 as _;\npub const NS_E_WMP_SERVER_UNAVAILABLE: windows_sys::core::HRESULT = 0xC00D11B0_u32 as _;\npub const NS_E_WMP_STREAMING_RECORDING_NOT_ALLOWED: windows_sys::core::HRESULT = 0xC00D0FD8_u32 as _;\npub const NS_E_WMP_TAMPERED_CONTENT: windows_sys::core::HRESULT = 0xC00D11C5_u32 as _;\npub const NS_E_WMP_UDRM_NOUSERLIST: windows_sys::core::HRESULT = 0xC00D12C0_u32 as _;\npub const NS_E_WMP_UI_NOSKININZIP: windows_sys::core::HRESULT = 0xC00D0FE7_u32 as _;\npub const NS_E_WMP_UI_NOTATHEMEFILE: windows_sys::core::HRESULT = 0xC00D0FE0_u32 as _;\npub const NS_E_WMP_UI_OBJECTNOTFOUND: windows_sys::core::HRESULT = 0xC00D0FE5_u32 as _;\npub const NS_E_WMP_UI_PASSTHROUGH: windows_sys::core::HRESULT = 0xC00D0FE4_u32 as _;\npub const NS_E_WMP_UI_SECONDHANDLER: windows_sys::core::HRESULT = 0xC00D0FE6_u32 as _;\npub const NS_E_WMP_UI_SUBCONTROLSNOTSUPPORTED: windows_sys::core::HRESULT = 0xC00D0FDE_u32 as _;\npub const NS_E_WMP_UI_SUBELEMENTNOTFOUND: windows_sys::core::HRESULT = 0xC00D0FE1_u32 as _;\npub const NS_E_WMP_UI_VERSIONMISMATCH: windows_sys::core::HRESULT = 0xC00D0FDF_u32 as _;\npub const NS_E_WMP_UI_VERSIONPARSE: windows_sys::core::HRESULT = 0xC00D0FE2_u32 as _;\npub const NS_E_WMP_UI_VIEWIDNOTFOUND: windows_sys::core::HRESULT = 0xC00D0FE3_u32 as _;\npub const NS_E_WMP_UNKNOWN_ERROR: windows_sys::core::HRESULT = 0xC00D11CD_u32 as _;\npub const NS_E_WMP_UNSUPPORTED_FORMAT: windows_sys::core::HRESULT = 0xC00D1199_u32 as _;\npub const NS_E_WMP_UPGRADE_APPLICATION: windows_sys::core::HRESULT = 0xC00D11CC_u32 as _;\npub const NS_E_WMP_URLDOWNLOADFAILED: windows_sys::core::HRESULT = 0xC00D0FEA_u32 as _;\npub const NS_E_WMP_VERIFY_ONLINE: windows_sys::core::HRESULT = 0xC00D11B2_u32 as _;\npub const NS_E_WMP_VIDEO_CODEC_NOT_INSTALLED: windows_sys::core::HRESULT = 0xC00D11C8_u32 as _;\npub const NS_E_WMP_WINDOWSAPIFAILURE: windows_sys::core::HRESULT = 0xC00D0FC8_u32 as _;\npub const NS_E_WMP_WMDM_BUSY: windows_sys::core::HRESULT = 0xC00D11A8_u32 as _;\npub const NS_E_WMP_WMDM_FAILURE: windows_sys::core::HRESULT = 0xC00D11A0_u32 as _;\npub const NS_E_WMP_WMDM_INCORRECT_RIGHTS: windows_sys::core::HRESULT = 0xC00D11AA_u32 as _;\npub const NS_E_WMP_WMDM_INTERFACEDEAD: windows_sys::core::HRESULT = 0xC00D11A4_u32 as _;\npub const NS_E_WMP_WMDM_LICENSE_EXPIRED: windows_sys::core::HRESULT = 0xC00D11A7_u32 as _;\npub const NS_E_WMP_WMDM_LICENSE_NOTEXIST: windows_sys::core::HRESULT = 0xC00D11A6_u32 as _;\npub const NS_E_WMP_WMDM_NORIGHTS: windows_sys::core::HRESULT = 0xC00D11A9_u32 as _;\npub const NS_E_WMP_WMDM_NOTCERTIFIED: windows_sys::core::HRESULT = 0xC00D11A5_u32 as _;\npub const NS_E_WMR_CANNOT_RENDER_BINARY_STREAM: windows_sys::core::HRESULT = 0xC00D1063_u32 as _;\npub const NS_E_WMR_NOCALLBACKAVAILABLE: windows_sys::core::HRESULT = 0xC00D105E_u32 as _;\npub const NS_E_WMR_NOSOURCEFILTER: windows_sys::core::HRESULT = 0xC00D105C_u32 as _;\npub const NS_E_WMR_PINNOTFOUND: windows_sys::core::HRESULT = 0xC00D105A_u32 as _;\npub const NS_E_WMR_PINTYPENOMATCH: windows_sys::core::HRESULT = 0xC00D105D_u32 as _;\npub const NS_E_WMR_SAMPLEPROPERTYNOTSET: windows_sys::core::HRESULT = 0xC00D1062_u32 as _;\npub const NS_E_WMR_UNSUPPORTEDSTREAM: windows_sys::core::HRESULT = 0xC00D1059_u32 as _;\npub const NS_E_WMR_WAITINGONFORMATSWITCH: windows_sys::core::HRESULT = 0xC00D105B_u32 as _;\npub const NS_E_WMR_WILLNOT_RENDER_BINARY_STREAM: windows_sys::core::HRESULT = 0xC00D1065_u32 as _;\npub const NS_E_WMX_ATTRIBUTE_ALREADY_EXISTS: windows_sys::core::HRESULT = 0xC00D106F_u32 as _;\npub const NS_E_WMX_ATTRIBUTE_DOES_NOT_EXIST: windows_sys::core::HRESULT = 0xC00D106E_u32 as _;\npub const NS_E_WMX_ATTRIBUTE_UNRETRIEVABLE: windows_sys::core::HRESULT = 0xC00D1070_u32 as _;\npub const NS_E_WMX_INVALID_FORMAT_OVER_NESTING: windows_sys::core::HRESULT = 0xC00D1076_u32 as _;\npub const NS_E_WMX_ITEM_DOES_NOT_EXIST: windows_sys::core::HRESULT = 0xC00D1071_u32 as _;\npub const NS_E_WMX_ITEM_TYPE_ILLEGAL: windows_sys::core::HRESULT = 0xC00D1072_u32 as _;\npub const NS_E_WMX_ITEM_UNSETTABLE: windows_sys::core::HRESULT = 0xC00D1073_u32 as _;\npub const NS_E_WMX_PLAYLIST_EMPTY: windows_sys::core::HRESULT = 0xC00D1074_u32 as _;\npub const NS_E_WMX_UNRECOGNIZED_PLAYLIST_FORMAT: windows_sys::core::HRESULT = 0xC00D1068_u32 as _;\npub const NS_E_WONT_DO_DIGITAL: windows_sys::core::HRESULT = 0xC00D0FB3_u32 as _;\npub const NS_E_WRONG_OS_VERSION: windows_sys::core::HRESULT = 0xC00D145D_u32 as _;\npub const NS_E_WRONG_PUBLISHING_POINT_TYPE: windows_sys::core::HRESULT = 0xC00D1452_u32 as _;\npub const NS_E_WSX_INVALID_VERSION: windows_sys::core::HRESULT = 0xC00D151E_u32 as _;\npub const NS_I_CATATONIC_AUTO_UNFAIL: windows_sys::core::HRESULT = 0x800D019A_u32 as _;\npub const NS_I_CATATONIC_FAILURE: windows_sys::core::HRESULT = 0x800D0199_u32 as _;\npub const NS_I_CUB_RUNNING: windows_sys::core::HRESULT = 0x400D0052_u32 as _;\npub const NS_I_CUB_START: windows_sys::core::HRESULT = 0x400D0051_u32 as _;\npub const NS_I_CUB_UNFAIL_LINK: windows_sys::core::HRESULT = 0x400D0191_u32 as _;\npub const NS_I_DISK_REBUILD_ABORTED: windows_sys::core::HRESULT = 0x400D0058_u32 as _;\npub const NS_I_DISK_REBUILD_FINISHED: windows_sys::core::HRESULT = 0x400D0057_u32 as _;\npub const NS_I_DISK_REBUILD_STARTED: windows_sys::core::HRESULT = 0x400D0056_u32 as _;\npub const NS_I_DISK_START: windows_sys::core::HRESULT = 0x400D0054_u32 as _;\npub const NS_I_DISK_STOP: windows_sys::core::HRESULT = 0x400D0198_u32 as _;\npub const NS_I_EXISTING_PACKETIZER: windows_sys::core::HRESULT = 0x400D2F03_u32 as _;\npub const NS_I_KILL_CONNECTION: windows_sys::core::HRESULT = 0x400D005E_u32 as _;\npub const NS_I_KILL_USERSESSION: windows_sys::core::HRESULT = 0x400D005D_u32 as _;\npub const NS_I_LIMIT_BANDWIDTH: windows_sys::core::HRESULT = 0x400D0070_u32 as _;\npub const NS_I_LIMIT_FUNNELS: windows_sys::core::HRESULT = 0x400D0059_u32 as _;\npub const NS_I_LOGGING_FAILED: windows_sys::core::HRESULT = 0x400D006E_u32 as _;\npub const NS_I_MANUAL_PROXY: windows_sys::core::HRESULT = 0x400D2F04_u32 as _;\npub const NS_I_NOLOG_STOP: windows_sys::core::HRESULT = 0x400D2F01_u32 as _;\npub const NS_I_PLAYLIST_CHANGE_RECEDING: windows_sys::core::HRESULT = 0x400D14BE_u32 as _;\npub const NS_I_REBUILD_DISK: windows_sys::core::HRESULT = 0x400D005F_u32 as _;\npub const NS_I_RECONNECTED: windows_sys::core::HRESULT = 0x400D2EFF_u32 as _;\npub const NS_I_RESTRIPE_CUB_OUT: windows_sys::core::HRESULT = 0x400D0197_u32 as _;\npub const NS_I_RESTRIPE_DISK_OUT: windows_sys::core::HRESULT = 0x400D0196_u32 as _;\npub const NS_I_RESTRIPE_DONE: windows_sys::core::HRESULT = 0x400D0194_u32 as _;\npub const NS_I_RESTRIPE_START: windows_sys::core::HRESULT = 0x400D0193_u32 as _;\npub const NS_I_START_DISK: windows_sys::core::HRESULT = 0x400D005A_u32 as _;\npub const NS_I_STOP_CUB: windows_sys::core::HRESULT = 0x400D005C_u32 as _;\npub const NS_I_STOP_DISK: windows_sys::core::HRESULT = 0x400D005B_u32 as _;\npub const NS_I_TIGER_START: windows_sys::core::HRESULT = 0x400D004F_u32 as _;\npub const NS_S_CALLABORTED: windows_sys::core::HRESULT = 0xD0001_u32 as _;\npub const NS_S_CALLPENDING: windows_sys::core::HRESULT = 0xD0000_u32 as _;\npub const NS_S_CHANGENOTICE: windows_sys::core::HRESULT = 0xD2F0D_u32 as _;\npub const NS_S_DEGRADING_QUALITY: windows_sys::core::HRESULT = 0xD0BC9_u32 as _;\npub const NS_S_DRM_ACQUIRE_CANCELLED: windows_sys::core::HRESULT = 0xD2747_u32 as _;\npub const NS_S_DRM_BURNABLE_TRACK: windows_sys::core::HRESULT = 0xD276E_u32 as _;\npub const NS_S_DRM_BURNABLE_TRACK_WITH_PLAYLIST_RESTRICTION: windows_sys::core::HRESULT = 0xD276F_u32 as _;\npub const NS_S_DRM_INDIVIDUALIZED: windows_sys::core::HRESULT = 0xD2727_u32 as _;\npub const NS_S_DRM_LICENSE_ACQUIRED: windows_sys::core::HRESULT = 0xD2726_u32 as _;\npub const NS_S_DRM_MONITOR_CANCELLED: windows_sys::core::HRESULT = 0xD2746_u32 as _;\npub const NS_S_DRM_NEEDS_INDIVIDUALIZATION: windows_sys::core::HRESULT = 0xD27DE_u32 as _;\npub const NS_S_EOSRECEDING: windows_sys::core::HRESULT = 0xD2F09_u32 as _;\npub const NS_S_NAVIGATION_COMPLETE_WITH_ERRORS: windows_sys::core::HRESULT = 0xD135E_u32 as _;\npub const NS_S_NEED_TO_BUY_BURN_RIGHTS: windows_sys::core::HRESULT = 0xD10DB_u32 as _;\npub const NS_S_OPERATION_PENDING: windows_sys::core::HRESULT = 0xD114E_u32 as _;\npub const NS_S_PUBLISHING_POINT_STARTED_WITH_FAILED_SINKS: windows_sys::core::HRESULT = 0xD1519_u32 as _;\npub const NS_S_REBOOT_RECOMMENDED: windows_sys::core::HRESULT = 0xD2AF8_u32 as _;\npub const NS_S_REBOOT_REQUIRED: windows_sys::core::HRESULT = 0xD2AF9_u32 as _;\npub const NS_S_REBUFFERING: windows_sys::core::HRESULT = 0xD0BC8_u32 as _;\npub const NS_S_STREAM_TRUNCATED: windows_sys::core::HRESULT = 0xD0002_u32 as _;\npub const NS_S_TRACK_ALREADY_DOWNLOADED: windows_sys::core::HRESULT = 0xD1361_u32 as _;\npub const NS_S_TRACK_BUY_REQUIRES_ALBUM_PURCHASE: windows_sys::core::HRESULT = 0xD1359_u32 as _;\npub const NS_S_TRANSCRYPTOR_EOF: windows_sys::core::HRESULT = 0xD0BDB_u32 as _;\npub const NS_S_WMG_ADVISE_DROP_FRAME: windows_sys::core::HRESULT = 0xD1066_u32 as _;\npub const NS_S_WMG_ADVISE_DROP_TO_KEYFRAME: windows_sys::core::HRESULT = 0xD1067_u32 as _;\npub const NS_S_WMG_FORCE_DROP_FRAME: windows_sys::core::HRESULT = 0xD104F_u32 as _;\npub const NS_S_WMPBR_PARTIALSUCCESS: windows_sys::core::HRESULT = 0xD1136_u32 as _;\npub const NS_S_WMPBR_SUCCESS: windows_sys::core::HRESULT = 0xD1135_u32 as _;\npub const NS_S_WMPCORE_COMMAND_NOT_AVAILABLE: windows_sys::core::HRESULT = 0xD1105_u32 as _;\npub const NS_S_WMPCORE_MEDIA_CHILD_PLAYLIST_OPEN_PENDING: windows_sys::core::HRESULT = 0xD1109_u32 as _;\npub const NS_S_WMPCORE_MEDIA_VALIDATION_PENDING: windows_sys::core::HRESULT = 0xD1103_u32 as _;\npub const NS_S_WMPCORE_MORE_NODES_AVAIABLE: windows_sys::core::HRESULT = 0xD110A_u32 as _;\npub const NS_S_WMPCORE_PLAYLISTCLEARABORT: windows_sys::core::HRESULT = 0xD10FE_u32 as _;\npub const NS_S_WMPCORE_PLAYLISTREMOVEITEMABORT: windows_sys::core::HRESULT = 0xD10FF_u32 as _;\npub const NS_S_WMPCORE_PLAYLIST_COLLAPSED_TO_SINGLE_MEDIA: windows_sys::core::HRESULT = 0xD1108_u32 as _;\npub const NS_S_WMPCORE_PLAYLIST_CREATION_PENDING: windows_sys::core::HRESULT = 0xD1102_u32 as _;\npub const NS_S_WMPCORE_PLAYLIST_IMPORT_MISSING_ITEMS: windows_sys::core::HRESULT = 0xD1107_u32 as _;\npub const NS_S_WMPCORE_PLAYLIST_NAME_AUTO_GENERATED: windows_sys::core::HRESULT = 0xD1106_u32 as _;\npub const NS_S_WMPCORE_PLAYLIST_REPEAT_SECONDARY_SEGMENTS_IGNORED: windows_sys::core::HRESULT = 0xD1104_u32 as _;\npub const NS_S_WMPEFFECT_OPAQUE: windows_sys::core::HRESULT = 0xD1145_u32 as _;\npub const NS_S_WMPEFFECT_TRANSPARENT: windows_sys::core::HRESULT = 0xD1144_u32 as _;\npub const NS_S_WMP_EXCEPTION: windows_sys::core::HRESULT = 0xD0FE9_u32 as _;\npub const NS_S_WMP_LOADED_BMP_IMAGE: windows_sys::core::HRESULT = 0xD1042_u32 as _;\npub const NS_S_WMP_LOADED_GIF_IMAGE: windows_sys::core::HRESULT = 0xD1040_u32 as _;\npub const NS_S_WMP_LOADED_JPG_IMAGE: windows_sys::core::HRESULT = 0xD1043_u32 as _;\npub const NS_S_WMP_LOADED_PNG_IMAGE: windows_sys::core::HRESULT = 0xD1041_u32 as _;\npub const NS_S_WMP_UI_VERSIONMISMATCH: windows_sys::core::HRESULT = 0xD0FE8_u32 as _;\npub const NS_S_WMR_ALREADYRENDERED: windows_sys::core::HRESULT = 0xD105F_u32 as _;\npub const NS_S_WMR_PINTYPEFULLMATCH: windows_sys::core::HRESULT = 0xD1061_u32 as _;\npub const NS_S_WMR_PINTYPEPARTIALMATCH: windows_sys::core::HRESULT = 0xD1060_u32 as _;\npub const NS_W_FILE_BANDWIDTH_LIMIT: windows_sys::core::HRESULT = 0x800D0004_u32 as _;\npub const NS_W_SERVER_BANDWIDTH_LIMIT: windows_sys::core::HRESULT = 0x800D0003_u32 as _;\npub const NS_W_UNKNOWN_EVENT: windows_sys::core::HRESULT = 0x800D0060_u32 as _;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct OLIADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct OLICELPWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct OLIGSMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct OLIOPRWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct OLISBCWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\npub const PD_CAN_DRAW_DIB: u32 = 1u32;\npub const PD_CAN_STRETCHDIB: u32 = 2u32;\npub const PD_STRETCHDIB_1_1_OK: u32 = 4u32;\npub const PD_STRETCHDIB_1_2_OK: u32 = 8u32;\npub const PD_STRETCHDIB_1_N_OK: u32 = 16u32;\npub const ROCKWELL_WA1_MIXER: u32 = 103u32;\npub const ROCKWELL_WA1_MPU401_IN: u32 = 104u32;\npub const ROCKWELL_WA1_MPU401_OUT: u32 = 105u32;\npub const ROCKWELL_WA1_SYNTH: u32 = 102u32;\npub const ROCKWELL_WA1_WAVEIN: u32 = 100u32;\npub const ROCKWELL_WA1_WAVEOUT: u32 = 101u32;\npub const ROCKWELL_WA2_MIXER: u32 = 203u32;\npub const ROCKWELL_WA2_MPU401_IN: u32 = 204u32;\npub const ROCKWELL_WA2_MPU401_OUT: u32 = 205u32;\npub const ROCKWELL_WA2_SYNTH: u32 = 202u32;\npub const ROCKWELL_WA2_WAVEIN: u32 = 200u32;\npub const ROCKWELL_WA2_WAVEOUT: u32 = 201u32;\npub const SEARCH_ANY: i32 = 32i32;\npub const SEARCH_BACKWARD: i32 = 4i32;\npub const SEARCH_FORWARD: i32 = 1i32;\npub const SEARCH_KEY: i32 = 16i32;\npub const SEARCH_NEAREST: i32 = 4i32;\npub const SEEK_CUR: u32 = 1u32;\npub const SEEK_END: u32 = 2u32;\npub const SEEK_SET: u32 = 0u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct SIERRAADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wRevision: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct SONARCWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wCompType: u16,\n}\npub const TARGET_DEVICE_FRIENDLY_NAME: windows_sys::core::PCSTR = windows_sys::core::s!(\"TargetDeviceFriendlyName\");\npub const TARGET_DEVICE_OPEN_EXCLUSIVELY: windows_sys::core::PCSTR = windows_sys::core::s!(\"TargetDeviceOpenExclusively\");\npub const TASKERR_NOTASKSUPPORT: u32 = 1u32;\npub const TASKERR_OUTOFMEMORY: u32 = 2u32;\npub const TDD_BEGINMINPERIOD: u32 = 2064u32;\npub const TDD_ENDMINPERIOD: u32 = 2068u32;\npub const TDD_GETDEVCAPS: u32 = 2060u32;\npub const TDD_GETSYSTEMTIME: u32 = 2056u32;\npub const TDD_KILLTIMEREVENT: u32 = 2048u32;\npub const TDD_SETTIMEREVENT: u32 = 2052u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct TIMEREVENT {\n    pub wDelay: u16,\n    pub wResolution: u16,\n    pub lpFunction: super::LPTIMECALLBACK,\n    pub dwUser: u32,\n    pub wFlags: u16,\n    pub wReserved1: u16,\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy)]\npub struct TRUESPEECHWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wRevision: u16,\n    pub nSamplesPerBlock: u16,\n    pub abReserved: [u8; 28],\n}\n#[cfg(feature = \"Win32_Media_Audio\")]\nimpl Default for TRUESPEECHWAVEFORMAT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const VADMAD_Device_ID: u32 = 1092u32;\npub const VCAPS_CAN_SCALE: u32 = 8u32;\npub const VCAPS_DST_CAN_CLIP: u32 = 4u32;\npub const VCAPS_OVERLAY: u32 = 1u32;\npub const VCAPS_SRC_CAN_CLIP: u32 = 2u32;\n#[cfg(feature = \"Win32_UI_Controls\")]\npub type VFWWDMExtensionProc = Option<unsafe extern \"system\" fn(pfndeviceiocontrol: *mut core::ffi::c_void, pfnaddpropertypage: super::super::UI::Controls::LPFNSVADDPROPSHEETPAGE, lparam: super::super::Foundation::LPARAM) -> u32>;\npub const VFW_HIDE_CAMERACONTROL_PAGE: u32 = 4u32;\npub const VFW_HIDE_SETTINGS_PAGE: u32 = 1u32;\npub const VFW_HIDE_VIDEOSRC_PAGE: u32 = 2u32;\npub const VFW_OEM_ADD_PAGE: u32 = 2147483648u32;\npub const VFW_QUERY_DEV_CHANGED: u32 = 256u32;\npub const VFW_USE_DEVICE_HANDLE: u32 = 1u32;\npub const VFW_USE_STREAM_HANDLE: u32 = 2u32;\npub const VHDR_DONE: u32 = 1u32;\npub const VHDR_INQUEUE: u32 = 4u32;\npub const VHDR_KEYFRAME: u32 = 8u32;\npub const VHDR_PREPARED: u32 = 2u32;\npub const VHDR_VALID: u32 = 15u32;\npub const VIDCF_COMPRESSFRAMES: u32 = 8u32;\npub const VIDCF_CRUNCH: u32 = 2u32;\npub const VIDCF_DRAW: u32 = 16u32;\npub const VIDCF_FASTTEMPORALC: u32 = 32u32;\npub const VIDCF_FASTTEMPORALD: u32 = 128u32;\npub const VIDCF_QUALITY: u32 = 1u32;\npub const VIDCF_TEMPORAL: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct VIDEOHDR {\n    pub lpData: *mut u8,\n    pub dwBufferLength: u32,\n    pub dwBytesUsed: u32,\n    pub dwTimeCaptured: u32,\n    pub dwUser: usize,\n    pub dwFlags: u32,\n    pub dwReserved: [usize; 4],\n}\nimpl Default for VIDEOHDR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const VIDEO_CONFIGURE_CURRENT: u32 = 16u32;\npub const VIDEO_CONFIGURE_GET: u32 = 8192u32;\npub const VIDEO_CONFIGURE_MAX: u32 = 128u32;\npub const VIDEO_CONFIGURE_MIN: u32 = 64u32;\npub const VIDEO_CONFIGURE_NOMINAL: u32 = 32u32;\npub const VIDEO_CONFIGURE_QUERY: u32 = 32768u32;\npub const VIDEO_CONFIGURE_QUERYSIZE: u32 = 1u32;\npub const VIDEO_CONFIGURE_SET: u32 = 4096u32;\npub const VIDEO_DLG_QUERY: u32 = 16u32;\npub const VIDEO_EXTERNALIN: u32 = 1u32;\npub const VIDEO_EXTERNALOUT: u32 = 2u32;\npub const VIDEO_IN: u32 = 4u32;\npub const VIDEO_OUT: u32 = 8u32;\npub const VP_COMMAND_GET: u32 = 1u32;\npub const VP_COMMAND_SET: u32 = 2u32;\npub const VP_CP_CMD_ACTIVATE: u32 = 1u32;\npub const VP_CP_CMD_CHANGE: u32 = 4u32;\npub const VP_CP_CMD_DEACTIVATE: u32 = 2u32;\npub const VP_CP_TYPE_APS_TRIGGER: u32 = 1u32;\npub const VP_CP_TYPE_MACROVISION: u32 = 2u32;\npub const VP_FLAGS_BRIGHTNESS: u32 = 64u32;\npub const VP_FLAGS_CONTRAST: u32 = 128u32;\npub const VP_FLAGS_COPYPROTECT: u32 = 256u32;\npub const VP_FLAGS_FLICKER: u32 = 4u32;\npub const VP_FLAGS_MAX_UNSCALED: u32 = 16u32;\npub const VP_FLAGS_OVERSCAN: u32 = 8u32;\npub const VP_FLAGS_POSITION: u32 = 32u32;\npub const VP_FLAGS_TV_MODE: u32 = 1u32;\npub const VP_FLAGS_TV_STANDARD: u32 = 2u32;\npub const VP_MODE_TV_PLAYBACK: u32 = 2u32;\npub const VP_MODE_WIN_GRAPHICS: u32 = 1u32;\npub const VP_TV_STANDARD_NTSC_433: u32 = 65536u32;\npub const VP_TV_STANDARD_NTSC_M: u32 = 1u32;\npub const VP_TV_STANDARD_NTSC_M_J: u32 = 2u32;\npub const VP_TV_STANDARD_PAL_60: u32 = 262144u32;\npub const VP_TV_STANDARD_PAL_B: u32 = 4u32;\npub const VP_TV_STANDARD_PAL_D: u32 = 8u32;\npub const VP_TV_STANDARD_PAL_G: u32 = 131072u32;\npub const VP_TV_STANDARD_PAL_H: u32 = 16u32;\npub const VP_TV_STANDARD_PAL_I: u32 = 32u32;\npub const VP_TV_STANDARD_PAL_M: u32 = 64u32;\npub const VP_TV_STANDARD_PAL_N: u32 = 128u32;\npub const VP_TV_STANDARD_SECAM_B: u32 = 256u32;\npub const VP_TV_STANDARD_SECAM_D: u32 = 512u32;\npub const VP_TV_STANDARD_SECAM_G: u32 = 1024u32;\npub const VP_TV_STANDARD_SECAM_H: u32 = 2048u32;\npub const VP_TV_STANDARD_SECAM_K: u32 = 4096u32;\npub const VP_TV_STANDARD_SECAM_K1: u32 = 8192u32;\npub const VP_TV_STANDARD_SECAM_L: u32 = 16384u32;\npub const VP_TV_STANDARD_SECAM_L1: u32 = 524288u32;\npub const VP_TV_STANDARD_WIN_VGA: u32 = 32768u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy)]\npub struct WAVEOPENDESC {\n    pub hWave: super::Audio::HWAVE,\n    pub lpFormat: *mut super::Audio::WAVEFORMAT,\n    pub dwCallback: usize,\n    pub dwInstance: usize,\n    pub uMappedDeviceID: u32,\n    pub dnDevNode: usize,\n}\n#[cfg(feature = \"Win32_Media_Audio\")]\nimpl Default for WAVEOPENDESC {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WAVE_FILTER_DEVELOPMENT: u32 = 65535u32;\npub const WAVE_FILTER_ECHO: u32 = 2u32;\npub const WAVE_FILTER_UNKNOWN: u32 = 0u32;\npub const WAVE_FILTER_VOLUME: u32 = 1u32;\npub const WAVE_FORMAT_3COM_NBX: u32 = 28672u32;\npub const WAVE_FORMAT_ADPCM: u32 = 2u32;\npub const WAVE_FORMAT_ALAC: u32 = 27745u32;\npub const WAVE_FORMAT_ALAW: u32 = 6u32;\npub const WAVE_FORMAT_AMR_NB: u32 = 29537u32;\npub const WAVE_FORMAT_AMR_WB: u32 = 29538u32;\npub const WAVE_FORMAT_AMR_WP: u32 = 29539u32;\npub const WAVE_FORMAT_ANTEX_ADPCME: u32 = 51u32;\npub const WAVE_FORMAT_APTX: u32 = 37u32;\npub const WAVE_FORMAT_AUDIOFILE_AF10: u32 = 38u32;\npub const WAVE_FORMAT_AUDIOFILE_AF36: u32 = 36u32;\npub const WAVE_FORMAT_BTV_DIGITAL: u32 = 1024u32;\npub const WAVE_FORMAT_CANOPUS_ATRAC: u32 = 99u32;\npub const WAVE_FORMAT_CIRRUS: u32 = 96u32;\npub const WAVE_FORMAT_CODIAN: u32 = 41252u32;\npub const WAVE_FORMAT_COMVERSE_INFOSYS_AVQSBC: u32 = 41217u32;\npub const WAVE_FORMAT_COMVERSE_INFOSYS_G723_1: u32 = 41216u32;\npub const WAVE_FORMAT_COMVERSE_INFOSYS_SBC: u32 = 41218u32;\npub const WAVE_FORMAT_CONGRUENCY: u32 = 141u32;\npub const WAVE_FORMAT_CONTROL_RES_CR10: u32 = 55u32;\npub const WAVE_FORMAT_CONTROL_RES_VQLPC: u32 = 52u32;\npub const WAVE_FORMAT_CONVEDIA_G729: u32 = 140u32;\npub const WAVE_FORMAT_CREATIVE_ADPCM: u32 = 512u32;\npub const WAVE_FORMAT_CREATIVE_FASTSPEECH10: u32 = 515u32;\npub const WAVE_FORMAT_CREATIVE_FASTSPEECH8: u32 = 514u32;\npub const WAVE_FORMAT_CS2: u32 = 608u32;\npub const WAVE_FORMAT_CS_IMAADPCM: u32 = 57u32;\npub const WAVE_FORMAT_CUSEEME: u32 = 7939u32;\npub const WAVE_FORMAT_CU_CODEC: u32 = 25u32;\npub const WAVE_FORMAT_DEVELOPMENT: u32 = 65535u32;\npub const WAVE_FORMAT_DF_G726: u32 = 133u32;\npub const WAVE_FORMAT_DF_GSM610: u32 = 134u32;\npub const WAVE_FORMAT_DIALOGIC_OKI_ADPCM: u32 = 23u32;\npub const WAVE_FORMAT_DICTAPHONE_CELP54: u32 = 322u32;\npub const WAVE_FORMAT_DICTAPHONE_CELP68: u32 = 321u32;\npub const WAVE_FORMAT_DIGIADPCM: u32 = 54u32;\npub const WAVE_FORMAT_DIGIFIX: u32 = 22u32;\npub const WAVE_FORMAT_DIGIREAL: u32 = 53u32;\npub const WAVE_FORMAT_DIGISTD: u32 = 21u32;\npub const WAVE_FORMAT_DIGITAL_G723: u32 = 291u32;\npub const WAVE_FORMAT_DIVIO_G726: u32 = 16963u32;\npub const WAVE_FORMAT_DIVIO_MPEG4_AAC: u32 = 16707u32;\npub const WAVE_FORMAT_DOLBY_AC2: u32 = 48u32;\npub const WAVE_FORMAT_DOLBY_AC3_SPDIF: u32 = 146u32;\npub const WAVE_FORMAT_DOLBY_AC4: u32 = 44096u32;\npub const WAVE_FORMAT_DRM: u32 = 9u32;\npub const WAVE_FORMAT_DSAT: u32 = 102u32;\npub const WAVE_FORMAT_DSAT_DISPLAY: u32 = 103u32;\npub const WAVE_FORMAT_DSPGROUP_TRUESPEECH: u32 = 34u32;\npub const WAVE_FORMAT_DTS: u32 = 8u32;\npub const WAVE_FORMAT_DTS2: u32 = 8193u32;\npub const WAVE_FORMAT_DTS_DS: u32 = 400u32;\npub const WAVE_FORMAT_DVI_ADPCM: u32 = 17u32;\npub const WAVE_FORMAT_DVM: u32 = 8192u32;\npub const WAVE_FORMAT_ECHOSC1: u32 = 35u32;\npub const WAVE_FORMAT_ECHOSC3: u32 = 58u32;\npub const WAVE_FORMAT_ENCORE_G726: u32 = 41223u32;\npub const WAVE_FORMAT_ESPCM: u32 = 97u32;\npub const WAVE_FORMAT_ESST_AC3: u32 = 577u32;\npub const WAVE_FORMAT_FAAD_AAC: u32 = 28781u32;\npub const WAVE_FORMAT_FLAC: u32 = 61868u32;\npub const WAVE_FORMAT_FM_TOWNS_SND: u32 = 768u32;\npub const WAVE_FORMAT_FRACE_TELECOM_G729: u32 = 41251u32;\npub const WAVE_FORMAT_FRAUNHOFER_IIS_MPEG2_AAC: u32 = 384u32;\npub const WAVE_FORMAT_G721_ADPCM: u32 = 64u32;\npub const WAVE_FORMAT_G722_ADPCM: u32 = 101u32;\npub const WAVE_FORMAT_G723_ADPCM: u32 = 20u32;\npub const WAVE_FORMAT_G726ADPCM: u32 = 320u32;\npub const WAVE_FORMAT_G726_ADPCM: u32 = 100u32;\npub const WAVE_FORMAT_G728_CELP: u32 = 65u32;\npub const WAVE_FORMAT_G729A: u32 = 131u32;\npub const WAVE_FORMAT_GENERIC_PASSTHRU: u32 = 585u32;\npub const WAVE_FORMAT_GLOBAL_IP_ILBC: u32 = 41238u32;\npub const WAVE_FORMAT_GSM610: u32 = 49u32;\npub const WAVE_FORMAT_GSM_610: u32 = 41229u32;\npub const WAVE_FORMAT_GSM_620: u32 = 41230u32;\npub const WAVE_FORMAT_GSM_660: u32 = 41231u32;\npub const WAVE_FORMAT_GSM_690: u32 = 41232u32;\npub const WAVE_FORMAT_GSM_ADAPTIVE_MULTIRATE_WB: u32 = 41233u32;\npub const WAVE_FORMAT_GSM_AMR_CBR: u32 = 31265u32;\npub const WAVE_FORMAT_GSM_AMR_VBR_SID: u32 = 31266u32;\npub const WAVE_FORMAT_HP_DYN_VOICE: u32 = 26u32;\npub const WAVE_FORMAT_IBM_CVSD: u32 = 5u32;\npub const WAVE_FORMAT_IEEE_FLOAT: u32 = 3u32;\npub const WAVE_FORMAT_ILINK_VC: u32 = 560u32;\npub const WAVE_FORMAT_IMA_ADPCM: u32 = 17u32;\npub const WAVE_FORMAT_INDEO_AUDIO: u32 = 1026u32;\npub const WAVE_FORMAT_INFOCOM_ITS_G721_ADPCM: u32 = 139u32;\npub const WAVE_FORMAT_INGENIENT_G726: u32 = 41221u32;\npub const WAVE_FORMAT_INNINGS_TELECOM_ADPCM: u32 = 6521u32;\npub const WAVE_FORMAT_INTEL_G723_1: u32 = 67u32;\npub const WAVE_FORMAT_INTEL_G729: u32 = 68u32;\npub const WAVE_FORMAT_INTEL_MUSIC_CODER: u32 = 1025u32;\npub const WAVE_FORMAT_IPI_HSX: u32 = 592u32;\npub const WAVE_FORMAT_IPI_RPELP: u32 = 593u32;\npub const WAVE_FORMAT_IRAT: u32 = 257u32;\npub const WAVE_FORMAT_ISIAUDIO: u32 = 136u32;\npub const WAVE_FORMAT_ISIAUDIO_2: u32 = 5121u32;\npub const WAVE_FORMAT_KNOWLEDGE_ADVENTURE_ADPCM: u32 = 376u32;\npub const WAVE_FORMAT_LEAD_SPEECH: u32 = 17228u32;\npub const WAVE_FORMAT_LEAD_VORBIS: u32 = 22092u32;\npub const WAVE_FORMAT_LH_CODEC: u32 = 4352u32;\npub const WAVE_FORMAT_LH_CODEC_CELP: u32 = 4353u32;\npub const WAVE_FORMAT_LH_CODEC_SBC12: u32 = 4355u32;\npub const WAVE_FORMAT_LH_CODEC_SBC16: u32 = 4356u32;\npub const WAVE_FORMAT_LH_CODEC_SBC8: u32 = 4354u32;\npub const WAVE_FORMAT_LIGHTWAVE_LOSSLESS: u32 = 2222u32;\npub const WAVE_FORMAT_LRC: u32 = 40u32;\npub const WAVE_FORMAT_LUCENT_G723: u32 = 89u32;\npub const WAVE_FORMAT_LUCENT_SX5363S: u32 = 7180u32;\npub const WAVE_FORMAT_LUCENT_SX8300P: u32 = 7175u32;\npub const WAVE_FORMAT_MAKEAVIS: u32 = 13075u32;\npub const WAVE_FORMAT_MALDEN_PHONYTALK: u32 = 160u32;\npub const WAVE_FORMAT_MEDIASONIC_G723: u32 = 147u32;\npub const WAVE_FORMAT_MEDIASPACE_ADPCM: u32 = 18u32;\npub const WAVE_FORMAT_MEDIAVISION_ADPCM: u32 = 24u32;\npub const WAVE_FORMAT_MICRONAS: u32 = 848u32;\npub const WAVE_FORMAT_MICRONAS_CELP833: u32 = 849u32;\npub const WAVE_FORMAT_MPEG: u32 = 80u32;\npub const WAVE_FORMAT_MPEG4_AAC: u32 = 41222u32;\npub const WAVE_FORMAT_MPEGLAYER3: u32 = 85u32;\npub const WAVE_FORMAT_MPEG_ADTS_AAC: u32 = 5632u32;\npub const WAVE_FORMAT_MPEG_HEAAC: u32 = 5648u32;\npub const WAVE_FORMAT_MPEG_LOAS: u32 = 5634u32;\npub const WAVE_FORMAT_MPEG_RAW_AAC: u32 = 5633u32;\npub const WAVE_FORMAT_MSAUDIO1: u32 = 352u32;\npub const WAVE_FORMAT_MSG723: u32 = 66u32;\npub const WAVE_FORMAT_MSNAUDIO: u32 = 50u32;\npub const WAVE_FORMAT_MSRT24: u32 = 130u32;\npub const WAVE_FORMAT_MULAW: u32 = 7u32;\npub const WAVE_FORMAT_MULTITUDE_FT_SX20: u32 = 138u32;\npub const WAVE_FORMAT_MVI_MVI2: u32 = 132u32;\npub const WAVE_FORMAT_NEC_AAC: u32 = 176u32;\npub const WAVE_FORMAT_NICE_ACA: u32 = 41240u32;\npub const WAVE_FORMAT_NICE_ADPCM: u32 = 41241u32;\npub const WAVE_FORMAT_NICE_G728: u32 = 41250u32;\npub const WAVE_FORMAT_NMS_VBXADPCM: u32 = 56u32;\npub const WAVE_FORMAT_NOKIA_ADAPTIVE_MULTIRATE: u32 = 16897u32;\npub const WAVE_FORMAT_NOKIA_MPEG_ADTS_AAC: u32 = 5640u32;\npub const WAVE_FORMAT_NOKIA_MPEG_RAW_AAC: u32 = 5641u32;\npub const WAVE_FORMAT_NORCOM_VOICE_SYSTEMS_ADPCM: u32 = 645u32;\npub const WAVE_FORMAT_NORRIS: u32 = 5120u32;\npub const WAVE_FORMAT_NTCSOFT_ALF2CM_ACM: u32 = 8132u32;\npub const WAVE_FORMAT_OGG_VORBIS_MODE_1: u32 = 26447u32;\npub const WAVE_FORMAT_OGG_VORBIS_MODE_1_PLUS: u32 = 26479u32;\npub const WAVE_FORMAT_OGG_VORBIS_MODE_2: u32 = 26448u32;\npub const WAVE_FORMAT_OGG_VORBIS_MODE_2_PLUS: u32 = 26480u32;\npub const WAVE_FORMAT_OGG_VORBIS_MODE_3: u32 = 26449u32;\npub const WAVE_FORMAT_OGG_VORBIS_MODE_3_PLUS: u32 = 26481u32;\npub const WAVE_FORMAT_OKI_ADPCM: u32 = 16u32;\npub const WAVE_FORMAT_OLIADPCM: u32 = 4097u32;\npub const WAVE_FORMAT_OLICELP: u32 = 4098u32;\npub const WAVE_FORMAT_OLIGSM: u32 = 4096u32;\npub const WAVE_FORMAT_OLIOPR: u32 = 4100u32;\npub const WAVE_FORMAT_OLISBC: u32 = 4099u32;\npub const WAVE_FORMAT_ON2_VP6_AUDIO: u32 = 1281u32;\npub const WAVE_FORMAT_ON2_VP7_AUDIO: u32 = 1280u32;\npub const WAVE_FORMAT_ONLIVE: u32 = 137u32;\npub const WAVE_FORMAT_OPUS: u32 = 28751u32;\npub const WAVE_FORMAT_PAC: u32 = 83u32;\npub const WAVE_FORMAT_PACKED: u32 = 153u32;\npub const WAVE_FORMAT_PCM_S: u32 = 1152u32;\npub const WAVE_FORMAT_PHILIPS_CELP: u32 = 288u32;\npub const WAVE_FORMAT_PHILIPS_GRUNDIG: u32 = 289u32;\npub const WAVE_FORMAT_PHILIPS_LPCBB: u32 = 152u32;\npub const WAVE_FORMAT_POLYCOM_G722: u32 = 41234u32;\npub const WAVE_FORMAT_POLYCOM_G728: u32 = 41235u32;\npub const WAVE_FORMAT_POLYCOM_G729_A: u32 = 41236u32;\npub const WAVE_FORMAT_POLYCOM_SIREN: u32 = 41237u32;\npub const WAVE_FORMAT_PROSODY_1612: u32 = 39u32;\npub const WAVE_FORMAT_PROSODY_8KBPS: u32 = 148u32;\npub const WAVE_FORMAT_QDESIGN_MUSIC: u32 = 1104u32;\npub const WAVE_FORMAT_QUALCOMM_HALFRATE: u32 = 337u32;\npub const WAVE_FORMAT_QUALCOMM_PUREVOICE: u32 = 336u32;\npub const WAVE_FORMAT_QUARTERDECK: u32 = 544u32;\npub const WAVE_FORMAT_RACAL_RECORDER_G720_A: u32 = 162u32;\npub const WAVE_FORMAT_RACAL_RECORDER_G723_1: u32 = 163u32;\npub const WAVE_FORMAT_RACAL_RECORDER_GSM: u32 = 161u32;\npub const WAVE_FORMAT_RACAL_RECORDER_TETRA_ACELP: u32 = 164u32;\npub const WAVE_FORMAT_RADIOTIME_TIME_SHIFT_RADIO: u32 = 41239u32;\npub const WAVE_FORMAT_RAW_AAC1: u32 = 255u32;\npub const WAVE_FORMAT_RAW_SPORT: u32 = 576u32;\npub const WAVE_FORMAT_RHETOREX_ADPCM: u32 = 256u32;\npub const WAVE_FORMAT_ROCKWELL_ADPCM: u32 = 59u32;\npub const WAVE_FORMAT_ROCKWELL_DIGITALK: u32 = 60u32;\npub const WAVE_FORMAT_RT24: u32 = 82u32;\npub const WAVE_FORMAT_SANYO_LD_ADPCM: u32 = 293u32;\npub const WAVE_FORMAT_SBC24: u32 = 145u32;\npub const WAVE_FORMAT_SHARP_G726: u32 = 69u32;\npub const WAVE_FORMAT_SIERRA_ADPCM: u32 = 19u32;\npub const WAVE_FORMAT_SIPROLAB_ACELP4800: u32 = 305u32;\npub const WAVE_FORMAT_SIPROLAB_ACELP8V3: u32 = 306u32;\npub const WAVE_FORMAT_SIPROLAB_ACEPLNET: u32 = 304u32;\npub const WAVE_FORMAT_SIPROLAB_G729: u32 = 307u32;\npub const WAVE_FORMAT_SIPROLAB_G729A: u32 = 308u32;\npub const WAVE_FORMAT_SIPROLAB_KELVIN: u32 = 309u32;\npub const WAVE_FORMAT_SOFTSOUND: u32 = 128u32;\npub const WAVE_FORMAT_SONARC: u32 = 33u32;\npub const WAVE_FORMAT_SONICFOUNDRY_LOSSLESS: u32 = 6513u32;\npub const WAVE_FORMAT_SONY_ATRAC3: u32 = 626u32;\npub const WAVE_FORMAT_SONY_SCX: u32 = 624u32;\npub const WAVE_FORMAT_SONY_SCY: u32 = 625u32;\npub const WAVE_FORMAT_SONY_SPC: u32 = 627u32;\npub const WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS: u32 = 5376u32;\npub const WAVE_FORMAT_SPEEX_VOICE: u32 = 41225u32;\npub const WAVE_FORMAT_SYCOM_ACM_SYC008: u32 = 372u32;\npub const WAVE_FORMAT_SYCOM_ACM_SYC701_CELP54: u32 = 374u32;\npub const WAVE_FORMAT_SYCOM_ACM_SYC701_CELP68: u32 = 375u32;\npub const WAVE_FORMAT_SYCOM_ACM_SYC701_G726L: u32 = 373u32;\npub const WAVE_FORMAT_SYMBOL_G729_A: u32 = 41219u32;\npub const WAVE_FORMAT_TELUM_AUDIO: u32 = 640u32;\npub const WAVE_FORMAT_TELUM_IA_AUDIO: u32 = 641u32;\npub const WAVE_FORMAT_TPC: u32 = 1665u32;\npub const WAVE_FORMAT_TUBGSM: u32 = 341u32;\npub const WAVE_FORMAT_UHER_ADPCM: u32 = 528u32;\npub const WAVE_FORMAT_ULEAD_DV_AUDIO: u32 = 533u32;\npub const WAVE_FORMAT_ULEAD_DV_AUDIO_1: u32 = 534u32;\npub const WAVE_FORMAT_UNISYS_NAP_16K: u32 = 371u32;\npub const WAVE_FORMAT_UNISYS_NAP_ADPCM: u32 = 368u32;\npub const WAVE_FORMAT_UNISYS_NAP_ALAW: u32 = 370u32;\npub const WAVE_FORMAT_UNISYS_NAP_ULAW: u32 = 369u32;\npub const WAVE_FORMAT_UNKNOWN: u32 = 0u32;\npub const WAVE_FORMAT_VIANIX_MASC: u32 = 41226u32;\npub const WAVE_FORMAT_VIVO_G723: u32 = 273u32;\npub const WAVE_FORMAT_VIVO_SIREN: u32 = 274u32;\npub const WAVE_FORMAT_VME_VMPCM: u32 = 1664u32;\npub const WAVE_FORMAT_VOCORD_G721: u32 = 41242u32;\npub const WAVE_FORMAT_VOCORD_G722_1: u32 = 41244u32;\npub const WAVE_FORMAT_VOCORD_G723_1: u32 = 41248u32;\npub const WAVE_FORMAT_VOCORD_G726: u32 = 41243u32;\npub const WAVE_FORMAT_VOCORD_G728: u32 = 41245u32;\npub const WAVE_FORMAT_VOCORD_G729: u32 = 41246u32;\npub const WAVE_FORMAT_VOCORD_G729_A: u32 = 41247u32;\npub const WAVE_FORMAT_VOCORD_LBC: u32 = 41249u32;\npub const WAVE_FORMAT_VODAFONE_MPEG_ADTS_AAC: u32 = 5642u32;\npub const WAVE_FORMAT_VODAFONE_MPEG_RAW_AAC: u32 = 5643u32;\npub const WAVE_FORMAT_VOICEAGE_AMR: u32 = 310u32;\npub const WAVE_FORMAT_VOICEAGE_AMR_WB: u32 = 41220u32;\npub const WAVE_FORMAT_VOXWARE: u32 = 98u32;\npub const WAVE_FORMAT_VOXWARE_AC10: u32 = 113u32;\npub const WAVE_FORMAT_VOXWARE_AC16: u32 = 114u32;\npub const WAVE_FORMAT_VOXWARE_AC20: u32 = 115u32;\npub const WAVE_FORMAT_VOXWARE_AC8: u32 = 112u32;\npub const WAVE_FORMAT_VOXWARE_BYTE_ALIGNED: u32 = 105u32;\npub const WAVE_FORMAT_VOXWARE_RT24: u32 = 116u32;\npub const WAVE_FORMAT_VOXWARE_RT24_SPEECH: u32 = 6172u32;\npub const WAVE_FORMAT_VOXWARE_RT29: u32 = 117u32;\npub const WAVE_FORMAT_VOXWARE_RT29HW: u32 = 118u32;\npub const WAVE_FORMAT_VOXWARE_SC3: u32 = 122u32;\npub const WAVE_FORMAT_VOXWARE_SC3_1: u32 = 123u32;\npub const WAVE_FORMAT_VOXWARE_TQ40: u32 = 121u32;\npub const WAVE_FORMAT_VOXWARE_TQ60: u32 = 129u32;\npub const WAVE_FORMAT_VOXWARE_VR12: u32 = 119u32;\npub const WAVE_FORMAT_VOXWARE_VR18: u32 = 120u32;\npub const WAVE_FORMAT_VSELP: u32 = 4u32;\npub const WAVE_FORMAT_WAVPACK_AUDIO: u32 = 22358u32;\npub const WAVE_FORMAT_WM9_SPECTRUM_ANALYZER: u32 = 41227u32;\npub const WAVE_FORMAT_WMASPDIF: u32 = 356u32;\npub const WAVE_FORMAT_WMAUDIO2: u32 = 353u32;\npub const WAVE_FORMAT_WMAUDIO3: u32 = 354u32;\npub const WAVE_FORMAT_WMAUDIO_LOSSLESS: u32 = 355u32;\npub const WAVE_FORMAT_WMAVOICE10: u32 = 11u32;\npub const WAVE_FORMAT_WMAVOICE9: u32 = 10u32;\npub const WAVE_FORMAT_WMF_SPECTRUM_ANAYZER: u32 = 41228u32;\npub const WAVE_FORMAT_XEBEC: u32 = 61u32;\npub const WAVE_FORMAT_YAMAHA_ADPCM: u32 = 32u32;\npub const WAVE_FORMAT_ZOLL_ASAO: u32 = 41224u32;\npub const WAVE_FORMAT_ZYXEL_ADPCM: u32 = 151u32;\npub const WAVE_MAPPER_S: u32 = 1153u32;\npub const WIDM_ADDBUFFER: u32 = 56u32;\npub const WIDM_CLOSE: u32 = 53u32;\npub const WIDM_GETDEVCAPS: u32 = 51u32;\npub const WIDM_GETNUMDEVS: u32 = 50u32;\npub const WIDM_GETPOS: u32 = 60u32;\npub const WIDM_INIT: u32 = 100u32;\npub const WIDM_INIT_EX: u32 = 104u32;\npub const WIDM_OPEN: u32 = 52u32;\npub const WIDM_PREFERRED: u32 = 61u32;\npub const WIDM_PREPARE: u32 = 54u32;\npub const WIDM_RESET: u32 = 59u32;\npub const WIDM_START: u32 = 57u32;\npub const WIDM_STOP: u32 = 58u32;\npub const WIDM_UNPREPARE: u32 = 55u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct WMAUDIO2WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub dwSamplesPerBlock: u32,\n    pub wEncodeOptions: u16,\n    pub dwSuperBlockAlign: u32,\n}\npub const WMAUDIO2_BITS_PER_SAMPLE: u32 = 16u32;\npub const WMAUDIO2_MAX_CHANNELS: u32 = 2u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct WMAUDIO3WAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n    pub wValidBitsPerSample: u16,\n    pub dwChannelMask: u32,\n    pub dwReserved1: u32,\n    pub dwReserved2: u32,\n    pub wEncodeOptions: u16,\n    pub wReserved3: u16,\n}\npub const WMAUDIO_BITS_PER_SAMPLE: u32 = 16u32;\npub const WMAUDIO_MAX_CHANNELS: u32 = 2u32;\npub const WM_CAP_ABORT: u32 = 1093u32;\npub const WM_CAP_DLG_VIDEOCOMPRESSION: u32 = 1070u32;\npub const WM_CAP_DLG_VIDEODISPLAY: u32 = 1067u32;\npub const WM_CAP_DLG_VIDEOFORMAT: u32 = 1065u32;\npub const WM_CAP_DLG_VIDEOSOURCE: u32 = 1066u32;\npub const WM_CAP_DRIVER_CONNECT: u32 = 1034u32;\npub const WM_CAP_DRIVER_DISCONNECT: u32 = 1035u32;\npub const WM_CAP_DRIVER_GET_CAPS: u32 = 1038u32;\npub const WM_CAP_DRIVER_GET_NAME: u32 = 1136u32;\npub const WM_CAP_DRIVER_GET_NAMEA: u32 = 1036u32;\npub const WM_CAP_DRIVER_GET_NAMEW: u32 = 1136u32;\npub const WM_CAP_DRIVER_GET_VERSION: u32 = 1137u32;\npub const WM_CAP_DRIVER_GET_VERSIONA: u32 = 1037u32;\npub const WM_CAP_DRIVER_GET_VERSIONW: u32 = 1137u32;\npub const WM_CAP_EDIT_COPY: u32 = 1054u32;\npub const WM_CAP_END: u32 = 1205u32;\npub const WM_CAP_FILE_ALLOCATE: u32 = 1046u32;\npub const WM_CAP_FILE_GET_CAPTURE_FILE: u32 = 1145u32;\npub const WM_CAP_FILE_GET_CAPTURE_FILEA: u32 = 1045u32;\npub const WM_CAP_FILE_GET_CAPTURE_FILEW: u32 = 1145u32;\npub const WM_CAP_FILE_SAVEAS: u32 = 1147u32;\npub const WM_CAP_FILE_SAVEASA: u32 = 1047u32;\npub const WM_CAP_FILE_SAVEASW: u32 = 1147u32;\npub const WM_CAP_FILE_SAVEDIB: u32 = 1149u32;\npub const WM_CAP_FILE_SAVEDIBA: u32 = 1049u32;\npub const WM_CAP_FILE_SAVEDIBW: u32 = 1149u32;\npub const WM_CAP_FILE_SET_CAPTURE_FILE: u32 = 1144u32;\npub const WM_CAP_FILE_SET_CAPTURE_FILEA: u32 = 1044u32;\npub const WM_CAP_FILE_SET_CAPTURE_FILEW: u32 = 1144u32;\npub const WM_CAP_FILE_SET_INFOCHUNK: u32 = 1048u32;\npub const WM_CAP_GET_AUDIOFORMAT: u32 = 1060u32;\npub const WM_CAP_GET_CAPSTREAMPTR: u32 = 1025u32;\npub const WM_CAP_GET_MCI_DEVICE: u32 = 1191u32;\npub const WM_CAP_GET_MCI_DEVICEA: u32 = 1091u32;\npub const WM_CAP_GET_MCI_DEVICEW: u32 = 1191u32;\npub const WM_CAP_GET_SEQUENCE_SETUP: u32 = 1089u32;\npub const WM_CAP_GET_STATUS: u32 = 1078u32;\npub const WM_CAP_GET_USER_DATA: u32 = 1032u32;\npub const WM_CAP_GET_VIDEOFORMAT: u32 = 1068u32;\npub const WM_CAP_GRAB_FRAME: u32 = 1084u32;\npub const WM_CAP_GRAB_FRAME_NOSTOP: u32 = 1085u32;\npub const WM_CAP_PAL_AUTOCREATE: u32 = 1107u32;\npub const WM_CAP_PAL_MANUALCREATE: u32 = 1108u32;\npub const WM_CAP_PAL_OPEN: u32 = 1204u32;\npub const WM_CAP_PAL_OPENA: u32 = 1104u32;\npub const WM_CAP_PAL_OPENW: u32 = 1204u32;\npub const WM_CAP_PAL_PASTE: u32 = 1106u32;\npub const WM_CAP_PAL_SAVE: u32 = 1205u32;\npub const WM_CAP_PAL_SAVEA: u32 = 1105u32;\npub const WM_CAP_PAL_SAVEW: u32 = 1205u32;\npub const WM_CAP_SEQUENCE: u32 = 1086u32;\npub const WM_CAP_SEQUENCE_NOFILE: u32 = 1087u32;\npub const WM_CAP_SET_AUDIOFORMAT: u32 = 1059u32;\npub const WM_CAP_SET_CALLBACK_CAPCONTROL: u32 = 1109u32;\npub const WM_CAP_SET_CALLBACK_ERROR: u32 = 1126u32;\npub const WM_CAP_SET_CALLBACK_ERRORA: u32 = 1026u32;\npub const WM_CAP_SET_CALLBACK_ERRORW: u32 = 1126u32;\npub const WM_CAP_SET_CALLBACK_FRAME: u32 = 1029u32;\npub const WM_CAP_SET_CALLBACK_STATUS: u32 = 1127u32;\npub const WM_CAP_SET_CALLBACK_STATUSA: u32 = 1027u32;\npub const WM_CAP_SET_CALLBACK_STATUSW: u32 = 1127u32;\npub const WM_CAP_SET_CALLBACK_VIDEOSTREAM: u32 = 1030u32;\npub const WM_CAP_SET_CALLBACK_WAVESTREAM: u32 = 1031u32;\npub const WM_CAP_SET_CALLBACK_YIELD: u32 = 1028u32;\npub const WM_CAP_SET_MCI_DEVICE: u32 = 1190u32;\npub const WM_CAP_SET_MCI_DEVICEA: u32 = 1090u32;\npub const WM_CAP_SET_MCI_DEVICEW: u32 = 1190u32;\npub const WM_CAP_SET_OVERLAY: u32 = 1075u32;\npub const WM_CAP_SET_PREVIEW: u32 = 1074u32;\npub const WM_CAP_SET_PREVIEWRATE: u32 = 1076u32;\npub const WM_CAP_SET_SCALE: u32 = 1077u32;\npub const WM_CAP_SET_SCROLL: u32 = 1079u32;\npub const WM_CAP_SET_SEQUENCE_SETUP: u32 = 1088u32;\npub const WM_CAP_SET_USER_DATA: u32 = 1033u32;\npub const WM_CAP_SET_VIDEOFORMAT: u32 = 1069u32;\npub const WM_CAP_SINGLE_FRAME: u32 = 1096u32;\npub const WM_CAP_SINGLE_FRAME_CLOSE: u32 = 1095u32;\npub const WM_CAP_SINGLE_FRAME_OPEN: u32 = 1094u32;\npub const WM_CAP_START: u32 = 1024u32;\npub const WM_CAP_STOP: u32 = 1092u32;\npub const WM_CAP_UNICODE_END: u32 = 1205u32;\npub const WM_CAP_UNICODE_START: u32 = 1124u32;\npub const WODM_BREAKLOOP: u32 = 20u32;\npub const WODM_BUSY: u32 = 21u32;\npub const WODM_CLOSE: u32 = 6u32;\npub const WODM_GETDEVCAPS: u32 = 4u32;\npub const WODM_GETNUMDEVS: u32 = 3u32;\npub const WODM_GETPITCH: u32 = 14u32;\npub const WODM_GETPLAYBACKRATE: u32 = 18u32;\npub const WODM_GETPOS: u32 = 13u32;\npub const WODM_GETVOLUME: u32 = 16u32;\npub const WODM_INIT: u32 = 100u32;\npub const WODM_INIT_EX: u32 = 104u32;\npub const WODM_OPEN: u32 = 5u32;\npub const WODM_PAUSE: u32 = 10u32;\npub const WODM_PREFERRED: u32 = 21u32;\npub const WODM_PREPARE: u32 = 7u32;\npub const WODM_RESET: u32 = 12u32;\npub const WODM_RESTART: u32 = 11u32;\npub const WODM_SETPITCH: u32 = 15u32;\npub const WODM_SETPLAYBACKRATE: u32 = 19u32;\npub const WODM_SETVOLUME: u32 = 17u32;\npub const WODM_UNPREPARE: u32 = 8u32;\npub const WODM_WRITE: u32 = 9u32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_Media_Audio\")]\n#[derive(Clone, Copy, Default)]\npub struct YAMAHA_ADPCMWAVEFORMAT {\n    pub wfx: super::Audio::WAVEFORMATEX,\n}\npub type YIELDPROC = Option<unsafe extern \"system\" fn(mciid: u32, dwyielddata: u32) -> u32>;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct s_RIFFWAVE_inst {\n    pub bUnshiftedNote: u8,\n    pub chFineTune: i8,\n    pub chGain: i8,\n    pub bLowNote: u8,\n    pub bHighNote: u8,\n    pub bLowVelocity: u8,\n    pub bHighVelocity: u8,\n}\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/Media/WindowsMediaFormat/mod.rs",
      "sha256": "68bca4c747a099cf167cf3319265e5056af02d8356fd807acd69725c4cdb2363",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "windows_link::link!(\"wmvcore.dll\" \"system\" fn WMCreateBackupRestorer(pcallback : * mut core::ffi::c_void, ppbackup : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"wmvcore.dll\" \"system\" fn WMCreateEditor(ppeditor : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"wmvcore.dll\" \"system\" fn WMCreateIndexer(ppindexer : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"wmvcore.dll\" \"system\" fn WMCreateProfileManager(ppprofilemanager : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"wmvcore.dll\" \"system\" fn WMCreateReader(punkcert : * mut core::ffi::c_void, dwrights : u32, ppreader : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"wmvcore.dll\" \"system\" fn WMCreateSyncReader(punkcert : * mut core::ffi::c_void, dwrights : u32, ppsyncreader : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"wmvcore.dll\" \"system\" fn WMCreateWriter(punkcert : * mut core::ffi::c_void, ppwriter : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"wmvcore.dll\" \"system\" fn WMCreateWriterFileSink(ppsink : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"wmvcore.dll\" \"system\" fn WMCreateWriterNetworkSink(ppsink : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"wmvcore.dll\" \"system\" fn WMCreateWriterPushSink(ppsink : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"wmvcore.dll\" \"system\" fn WMIsContentProtected(pwszfilename : windows_sys::core::PCWSTR, pfisprotected : *mut windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\npub const AM_CONFIGASFWRITER_PARAM_AUTOINDEX: _AM_ASFWRITERCONFIG_PARAM = 1i32;\npub const AM_CONFIGASFWRITER_PARAM_DONTCOMPRESS: _AM_ASFWRITERCONFIG_PARAM = 3i32;\npub const AM_CONFIGASFWRITER_PARAM_MULTIPASS: _AM_ASFWRITERCONFIG_PARAM = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct AM_WMT_EVENT_DATA {\n    pub hrStatus: windows_sys::core::HRESULT,\n    pub pData: *mut core::ffi::c_void,\n}\nimpl Default for AM_WMT_EVENT_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CLSID_ClientNetManager: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xcd12a3ce_9c42_11d2_beed_0060082f2054);\npub const CLSID_WMBandwidthSharing_Exclusive: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xaf6060aa_5197_11d2_b6af_00c04fd908e9);\npub const CLSID_WMBandwidthSharing_Partial: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xaf6060ab_5197_11d2_b6af_00c04fd908e9);\npub const CLSID_WMMUTEX_Bitrate: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd6e22a01_35da_11d1_9034_00a0c90349be);\npub const CLSID_WMMUTEX_Language: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd6e22a00_35da_11d1_9034_00a0c90349be);\npub const CLSID_WMMUTEX_Presentation: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd6e22a02_35da_11d1_9034_00a0c90349be);\npub const CLSID_WMMUTEX_Unknown: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd6e22a03_35da_11d1_9034_00a0c90349be);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DRM_COPY_OPL {\n    pub wMinimumCopyLevel: u16,\n    pub oplIdIncludes: DRM_OPL_OUTPUT_IDS,\n    pub oplIdExcludes: DRM_OPL_OUTPUT_IDS,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DRM_MINIMUM_OUTPUT_PROTECTION_LEVELS {\n    pub wCompressedDigitalVideo: u16,\n    pub wUncompressedDigitalVideo: u16,\n    pub wAnalogVideo: u16,\n    pub wCompressedDigitalAudio: u16,\n    pub wUncompressedDigitalAudio: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DRM_OPL_OUTPUT_IDS {\n    pub cIds: u16,\n    pub rgIds: *mut windows_sys::core::GUID,\n}\nimpl Default for DRM_OPL_OUTPUT_IDS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DRM_OPL_TYPES: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DRM_OUTPUT_PROTECTION {\n    pub guidId: windows_sys::core::GUID,\n    pub bConfigData: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DRM_PLAY_OPL {\n    pub minOPL: DRM_MINIMUM_OUTPUT_PROTECTION_LEVELS,\n    pub oplIdReserved: DRM_OPL_OUTPUT_IDS,\n    pub vopi: DRM_VIDEO_OUTPUT_PROTECTION_IDS,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DRM_VAL16 {\n    pub val: [u8; 16],\n}\nimpl Default for DRM_VAL16 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DRM_VIDEO_OUTPUT_PROTECTION_IDS {\n    pub cEntries: u16,\n    pub rgVop: *mut DRM_OUTPUT_PROTECTION,\n}\nimpl Default for DRM_VIDEO_OUTPUT_PROTECTION_IDS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type NETSOURCE_URLCREDPOLICY_SETTINGS = i32;\npub const NETSOURCE_URLCREDPOLICY_SETTING_ANONYMOUSONLY: NETSOURCE_URLCREDPOLICY_SETTINGS = 2i32;\npub const NETSOURCE_URLCREDPOLICY_SETTING_MUSTPROMPTUSER: NETSOURCE_URLCREDPOLICY_SETTINGS = 1i32;\npub const NETSOURCE_URLCREDPOLICY_SETTING_SILENTLOGONOK: NETSOURCE_URLCREDPOLICY_SETTINGS = 0i32;\npub type WEBSTREAM_SAMPLE_TYPE = i32;\npub const WEBSTREAM_SAMPLE_TYPE_FILE: WEBSTREAM_SAMPLE_TYPE = 1i32;\npub const WEBSTREAM_SAMPLE_TYPE_RENDER: WEBSTREAM_SAMPLE_TYPE = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WMDRM_IMPORT_INIT_STRUCT {\n    pub dwVersion: u32,\n    pub cbEncryptedSessionKeyMessage: u32,\n    pub pbEncryptedSessionKeyMessage: *mut u8,\n    pub cbEncryptedKeyMessage: u32,\n    pub pbEncryptedKeyMessage: *mut u8,\n}\nimpl Default for WMDRM_IMPORT_INIT_STRUCT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WMDRM_IMPORT_INIT_STRUCT_DEFINED: u32 = 1u32;\npub const WMFORMAT_MPEG2Video: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d80e3_db46_11cf_b4d1_00805f6cbbea);\npub const WMFORMAT_Script: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x5c8510f2_debe_4ca7_bba5_f07a104f8dff);\npub const WMFORMAT_VideoInfo: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x05589f80_c356_11ce_bf01_00aa0055595a);\npub const WMFORMAT_WaveFormatEx: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x05589f81_c356_11ce_bf01_00aa0055595a);\npub const WMFORMAT_WebStream: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xda1e6b13_8359_4050_b398_388e965bf00c);\npub const WMMEDIASUBTYPE_ACELPnet: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000130_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_Base: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000000_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_DRM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000009_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_I420: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x30323449_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_IYUV: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x56555949_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_M4S2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3253344d_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_MP3: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000055_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_MP43: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3334504d_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_MP4S: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x5334504d_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_MPEG2_VIDEO: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe06d8026_db46_11cf_b4d1_00805f6cbbea);\npub const WMMEDIASUBTYPE_MSS1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3153534d_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_MSS2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x3253534d_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_P422: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x32323450_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_PCM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000001_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_RGB1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb78_524f_11ce_9f53_0020af0ba770);\npub const WMMEDIASUBTYPE_RGB24: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb7d_524f_11ce_9f53_0020af0ba770);\npub const WMMEDIASUBTYPE_RGB32: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb7e_524f_11ce_9f53_0020af0ba770);\npub const WMMEDIASUBTYPE_RGB4: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb79_524f_11ce_9f53_0020af0ba770);\npub const WMMEDIASUBTYPE_RGB555: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb7c_524f_11ce_9f53_0020af0ba770);\npub const WMMEDIASUBTYPE_RGB565: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb7b_524f_11ce_9f53_0020af0ba770);\npub const WMMEDIASUBTYPE_RGB8: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe436eb7a_524f_11ce_9f53_0020af0ba770);\npub const WMMEDIASUBTYPE_UYVY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x59565955_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_VIDEOIMAGE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1d4a45f2_e5f6_4b44_8388_f0ae5c0e0c37);\npub const WMMEDIASUBTYPE_WMAudioV2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000161_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMAudioV7: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000161_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMAudioV8: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000161_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMAudioV9: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000162_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMAudio_Lossless: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x00000163_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMSP1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000000a_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMSP2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0000000b_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMV1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x31564d57_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMV2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x32564d57_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMV3: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x33564d57_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMVA: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x41564d57_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WMVP: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x50564d57_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WVC1: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x31435657_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WVP2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x32505657_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_WebStream: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x776257d4_c627_41cb_8f81_7ac7ff1c40cc);\npub const WMMEDIASUBTYPE_YUY2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x32595559_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_YV12: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x32315659_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_YVU9: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x39555659_0000_0010_8000_00aa00389b71);\npub const WMMEDIASUBTYPE_YVYU: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x55595659_0000_0010_8000_00aa00389b71);\npub const WMMEDIATYPE_Audio: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x73647561_0000_0010_8000_00aa00389b71);\npub const WMMEDIATYPE_FileTransfer: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd9e47579_930e_4427_adfc_ad80f290e470);\npub const WMMEDIATYPE_Image: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x34a50fd8_8aa5_4386_81fe_a0efe0488e31);\npub const WMMEDIATYPE_Script: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x73636d64_0000_0010_8000_00aa00389b71);\npub const WMMEDIATYPE_Text: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9bba1ea7_5ab2_4829_ba57_0940209bcf3e);\npub const WMMEDIATYPE_Video: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x73646976_0000_0010_8000_00aa00389b71);\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct WMMPEG2VIDEOINFO {\n    pub hdr: WMVIDEOINFOHEADER2,\n    pub dwStartTimeCode: u32,\n    pub cbSequenceHeader: u32,\n    pub dwProfile: u32,\n    pub dwLevel: u32,\n    pub dwFlags: u32,\n    pub dwSequenceHeader: [u32; 1],\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for WMMPEG2VIDEOINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WMSCRIPTFORMAT {\n    pub scriptType: windows_sys::core::GUID,\n}\npub const WMSCRIPTTYPE_TwoStrings: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x82f38a70_c29f_11d1_97ad_00a0c95ea850);\npub const WMT_ACQUIRE_LICENSE: WMT_STATUS = 23i32;\npub type WMT_ATTR_DATATYPE = i32;\npub type WMT_ATTR_IMAGETYPE = i32;\npub const WMT_BACKUPRESTORE_BEGIN: WMT_STATUS = 21i32;\npub const WMT_BACKUPRESTORE_CONNECTING: WMT_STATUS = 28i32;\npub const WMT_BACKUPRESTORE_DISCONNECTING: WMT_STATUS = 29i32;\npub const WMT_BACKUPRESTORE_END: WMT_STATUS = 27i32;\npub const WMT_BUFFERING_START: WMT_STATUS = 2i32;\npub const WMT_BUFFERING_STOP: WMT_STATUS = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WMT_BUFFER_SEGMENT {\n    pub pBuffer: *mut core::ffi::c_void,\n    pub cbOffset: u32,\n    pub cbLength: u32,\n}\nimpl Default for WMT_BUFFER_SEGMENT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WMT_CLEANPOINT_ONLY: WMT_STREAM_SELECTION = 1i32;\npub const WMT_CLIENT_CONNECT: WMT_STATUS = 32i32;\npub const WMT_CLIENT_CONNECT_EX: WMT_STATUS = 37i32;\npub const WMT_CLIENT_DISCONNECT: WMT_STATUS = 33i32;\npub const WMT_CLIENT_DISCONNECT_EX: WMT_STATUS = 38i32;\npub const WMT_CLIENT_PROPERTIES: WMT_STATUS = 42i32;\npub const WMT_CLOSED: WMT_STATUS = 13i32;\npub const WMT_CODECINFO_AUDIO: WMT_CODEC_INFO_TYPE = 0i32;\npub const WMT_CODECINFO_UNKNOWN: WMT_CODEC_INFO_TYPE = -1i32;\npub const WMT_CODECINFO_VIDEO: WMT_CODEC_INFO_TYPE = 1i32;\npub type WMT_CODEC_INFO_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WMT_COLORSPACEINFO_EXTENSION_DATA {\n    pub ucColorPrimaries: u8,\n    pub ucColorTransferChar: u8,\n    pub ucColorMatrixCoef: u8,\n}\npub const WMT_CONNECTING: WMT_STATUS = 8i32;\npub const WMT_CONTENT_ENABLER: WMT_STATUS = 51i32;\npub const WMT_CREDENTIAL_CLEAR_TEXT: WMT_CREDENTIAL_FLAGS = 4i32;\npub const WMT_CREDENTIAL_DONT_CACHE: WMT_CREDENTIAL_FLAGS = 2i32;\npub const WMT_CREDENTIAL_ENCRYPT: WMT_CREDENTIAL_FLAGS = 16i32;\npub type WMT_CREDENTIAL_FLAGS = i32;\npub const WMT_CREDENTIAL_PROXY: WMT_CREDENTIAL_FLAGS = 8i32;\npub const WMT_CREDENTIAL_SAVE: WMT_CREDENTIAL_FLAGS = 1i32;\npub const WMT_DMOCATEGORY_AUDIO_WATERMARK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x65221c5a_fa75_4b39_b50c_06c336b6a3ef);\npub const WMT_DMOCATEGORY_VIDEO_WATERMARK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x187cc922_8efc_4404_9daf_63f4830df1bc);\npub const WMT_DRMLA_TAMPERED: WMT_DRMLA_TRUST = 2i32;\npub type WMT_DRMLA_TRUST = i32;\npub const WMT_DRMLA_TRUSTED: WMT_DRMLA_TRUST = 1i32;\npub const WMT_DRMLA_UNTRUSTED: WMT_DRMLA_TRUST = 0i32;\npub const WMT_END_OF_FILE: WMT_STATUS = 4i32;\npub const WMT_END_OF_SEGMENT: WMT_STATUS = 5i32;\npub const WMT_END_OF_STREAMING: WMT_STATUS = 6i32;\npub const WMT_EOF: WMT_STATUS = 4i32;\npub const WMT_ERROR: WMT_STATUS = 0i32;\npub const WMT_ERROR_WITHURL: WMT_STATUS = 30i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WMT_FILESINK_DATA_UNIT {\n    pub packetHeaderBuffer: WMT_BUFFER_SEGMENT,\n    pub cPayloads: u32,\n    pub pPayloadHeaderBuffers: *mut WMT_BUFFER_SEGMENT,\n    pub cPayloadDataFragments: u32,\n    pub pPayloadDataFragments: *mut WMT_PAYLOAD_FRAGMENT,\n}\nimpl Default for WMT_FILESINK_DATA_UNIT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type WMT_FILESINK_MODE = i32;\npub const WMT_FM_FILESINK_DATA_UNITS: WMT_FILESINK_MODE = 2i32;\npub const WMT_FM_FILESINK_UNBUFFERED: WMT_FILESINK_MODE = 4i32;\npub const WMT_FM_SINGLE_BUFFERS: WMT_FILESINK_MODE = 1i32;\npub const WMT_IMAGETYPE_BITMAP: WMT_ATTR_IMAGETYPE = 1i32;\npub const WMT_IMAGETYPE_GIF: WMT_ATTR_IMAGETYPE = 3i32;\npub const WMT_IMAGETYPE_JPEG: WMT_ATTR_IMAGETYPE = 2i32;\npub type WMT_IMAGE_TYPE = i32;\npub type WMT_INDEXER_TYPE = i32;\npub const WMT_INDEX_PROGRESS: WMT_STATUS = 16i32;\npub type WMT_INDEX_TYPE = i32;\npub const WMT_INDIVIDUALIZE: WMT_STATUS = 24i32;\npub const WMT_INIT_PLAYLIST_BURN: WMT_STATUS = 44i32;\npub const WMT_IT_BITMAP: WMT_IMAGE_TYPE = 1i32;\npub const WMT_IT_FRAME_NUMBERS: WMT_INDEXER_TYPE = 1i32;\npub const WMT_IT_GIF: WMT_IMAGE_TYPE = 3i32;\npub const WMT_IT_JPEG: WMT_IMAGE_TYPE = 2i32;\npub const WMT_IT_NEAREST_CLEAN_POINT: WMT_INDEX_TYPE = 3i32;\npub const WMT_IT_NEAREST_DATA_UNIT: WMT_INDEX_TYPE = 1i32;\npub const WMT_IT_NEAREST_OBJECT: WMT_INDEX_TYPE = 2i32;\npub const WMT_IT_NONE: WMT_IMAGE_TYPE = 0i32;\npub const WMT_IT_PRESENTATION_TIME: WMT_INDEXER_TYPE = 0i32;\npub const WMT_IT_TIMECODE: WMT_INDEXER_TYPE = 2i32;\npub const WMT_LICENSEURL_SIGNATURE_STATE: WMT_STATUS = 43i32;\npub const WMT_LOCATING: WMT_STATUS = 7i32;\npub const WMT_MISSING_CODEC: WMT_STATUS = 10i32;\npub const WMT_MS_CLASS_MIXED: WMT_MUSICSPEECH_CLASS_MODE = 2i32;\npub const WMT_MS_CLASS_MUSIC: WMT_MUSICSPEECH_CLASS_MODE = 0i32;\npub const WMT_MS_CLASS_SPEECH: WMT_MUSICSPEECH_CLASS_MODE = 1i32;\npub type WMT_MUSICSPEECH_CLASS_MODE = i32;\npub const WMT_NATIVE_OUTPUT_PROPS_CHANGED: WMT_STATUS = 34i32;\npub const WMT_NEEDS_INDIVIDUALIZATION: WMT_STATUS = 25i32;\npub type WMT_NET_PROTOCOL = i32;\npub const WMT_NEW_METADATA: WMT_STATUS = 20i32;\npub const WMT_NEW_SOURCEFLAGS: WMT_STATUS = 19i32;\npub const WMT_NO_RIGHTS: WMT_STATUS = 9i32;\npub const WMT_NO_RIGHTS_EX: WMT_STATUS = 26i32;\npub const WMT_OFF: WMT_STREAM_SELECTION = 0i32;\npub type WMT_OFFSET_FORMAT = i32;\npub const WMT_OFFSET_FORMAT_100NS: WMT_OFFSET_FORMAT = 0i32;\npub const WMT_OFFSET_FORMAT_100NS_APPROXIMATE: WMT_OFFSET_FORMAT = 4i32;\npub const WMT_OFFSET_FORMAT_FRAME_NUMBERS: WMT_OFFSET_FORMAT = 1i32;\npub const WMT_OFFSET_FORMAT_PLAYLIST_OFFSET: WMT_OFFSET_FORMAT = 2i32;\npub const WMT_OFFSET_FORMAT_TIMECODE: WMT_OFFSET_FORMAT = 3i32;\npub const WMT_ON: WMT_STREAM_SELECTION = 2i32;\npub const WMT_OPENED: WMT_STATUS = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WMT_PAYLOAD_FRAGMENT {\n    pub dwPayloadIndex: u32,\n    pub segmentData: WMT_BUFFER_SEGMENT,\n}\npub type WMT_PLAY_MODE = i32;\npub const WMT_PLAY_MODE_AUTOSELECT: WMT_PLAY_MODE = 0i32;\npub const WMT_PLAY_MODE_DOWNLOAD: WMT_PLAY_MODE = 2i32;\npub const WMT_PLAY_MODE_LOCAL: WMT_PLAY_MODE = 1i32;\npub const WMT_PLAY_MODE_STREAMING: WMT_PLAY_MODE = 3i32;\npub const WMT_PREROLL_COMPLETE: WMT_STATUS = 41i32;\npub const WMT_PREROLL_READY: WMT_STATUS = 40i32;\npub const WMT_PROTOCOL_HTTP: WMT_NET_PROTOCOL = 0i32;\npub const WMT_PROXIMITY_COMPLETED: WMT_STATUS = 50i32;\npub const WMT_PROXIMITY_RESULT: WMT_STATUS = 49i32;\npub type WMT_PROXY_SETTINGS = i32;\npub const WMT_PROXY_SETTING_AUTO: WMT_PROXY_SETTINGS = 2i32;\npub const WMT_PROXY_SETTING_BROWSER: WMT_PROXY_SETTINGS = 3i32;\npub const WMT_PROXY_SETTING_MANUAL: WMT_PROXY_SETTINGS = 1i32;\npub const WMT_PROXY_SETTING_MAX: WMT_PROXY_SETTINGS = 4i32;\npub const WMT_PROXY_SETTING_NONE: WMT_PROXY_SETTINGS = 0i32;\npub const WMT_RECONNECT_END: WMT_STATUS = 36i32;\npub const WMT_RECONNECT_START: WMT_STATUS = 35i32;\npub const WMT_RESTRICTED_LICENSE: WMT_STATUS = 31i32;\npub type WMT_RIGHTS = i32;\npub const WMT_RIGHT_COLLABORATIVE_PLAY: WMT_RIGHTS = 256i32;\npub const WMT_RIGHT_COPY: WMT_RIGHTS = 128i32;\npub const WMT_RIGHT_COPY_TO_CD: WMT_RIGHTS = 8i32;\npub const WMT_RIGHT_COPY_TO_NON_SDMI_DEVICE: WMT_RIGHTS = 2i32;\npub const WMT_RIGHT_COPY_TO_SDMI_DEVICE: WMT_RIGHTS = 16i32;\npub const WMT_RIGHT_ONE_TIME: WMT_RIGHTS = 32i32;\npub const WMT_RIGHT_PLAYBACK: WMT_RIGHTS = 1i32;\npub const WMT_RIGHT_SAVE_STREAM_PROTECTED: WMT_RIGHTS = 64i32;\npub const WMT_RIGHT_SDMI_NOMORECOPIES: WMT_RIGHTS = 131072i32;\npub const WMT_RIGHT_SDMI_TRIGGER: WMT_RIGHTS = 65536i32;\npub const WMT_SAVEAS_START: WMT_STATUS = 17i32;\npub const WMT_SAVEAS_STOP: WMT_STATUS = 18i32;\npub const WMT_SET_FEC_SPAN: WMT_STATUS = 39i32;\npub const WMT_SOURCE_SWITCH: WMT_STATUS = 22i32;\npub const WMT_STARTED: WMT_STATUS = 11i32;\npub type WMT_STATUS = i32;\npub const WMT_STOPPED: WMT_STATUS = 12i32;\npub type WMT_STORAGE_FORMAT = i32;\npub type WMT_STREAM_SELECTION = i32;\npub const WMT_STRIDING: WMT_STATUS = 14i32;\npub const WMT_Storage_Format_MP3: WMT_STORAGE_FORMAT = 0i32;\npub const WMT_Storage_Format_V1: WMT_STORAGE_FORMAT = 1i32;\n#[repr(C, packed(2))]\n#[derive(Clone, Copy, Default)]\npub struct WMT_TIMECODE_EXTENSION_DATA {\n    pub wRange: u16,\n    pub dwTimecode: u32,\n    pub dwUserbits: u32,\n    pub dwAmFlags: u32,\n}\npub type WMT_TIMECODE_FRAMERATE = i32;\npub const WMT_TIMECODE_FRAMERATE_24: WMT_TIMECODE_FRAMERATE = 3i32;\npub const WMT_TIMECODE_FRAMERATE_25: WMT_TIMECODE_FRAMERATE = 2i32;\npub const WMT_TIMECODE_FRAMERATE_30: WMT_TIMECODE_FRAMERATE = 0i32;\npub const WMT_TIMECODE_FRAMERATE_30DROP: WMT_TIMECODE_FRAMERATE = 1i32;\npub const WMT_TIMER: WMT_STATUS = 15i32;\npub const WMT_TRANSCRYPTOR_CLOSED: WMT_STATUS = 48i32;\npub const WMT_TRANSCRYPTOR_INIT: WMT_STATUS = 45i32;\npub const WMT_TRANSCRYPTOR_READ: WMT_STATUS = 47i32;\npub const WMT_TRANSCRYPTOR_SEEKED: WMT_STATUS = 46i32;\npub type WMT_TRANSPORT_TYPE = i32;\npub const WMT_TYPE_BINARY: WMT_ATTR_DATATYPE = 2i32;\npub const WMT_TYPE_BOOL: WMT_ATTR_DATATYPE = 3i32;\npub const WMT_TYPE_DWORD: WMT_ATTR_DATATYPE = 0i32;\npub const WMT_TYPE_GUID: WMT_ATTR_DATATYPE = 6i32;\npub const WMT_TYPE_QWORD: WMT_ATTR_DATATYPE = 4i32;\npub const WMT_TYPE_STRING: WMT_ATTR_DATATYPE = 1i32;\npub const WMT_TYPE_WORD: WMT_ATTR_DATATYPE = 5i32;\npub const WMT_Transport_Type_Reliable: WMT_TRANSPORT_TYPE = 1i32;\npub const WMT_Transport_Type_Unreliable: WMT_TRANSPORT_TYPE = 0i32;\npub type WMT_VERSION = i32;\npub const WMT_VER_4_0: WMT_VERSION = 262144i32;\npub const WMT_VER_7_0: WMT_VERSION = 458752i32;\npub const WMT_VER_8_0: WMT_VERSION = 524288i32;\npub const WMT_VER_9_0: WMT_VERSION = 589824i32;\npub const WMT_VIDEOIMAGE_INTEGER_DENOMINATOR: i32 = 65536i32;\npub const WMT_VIDEOIMAGE_MAGIC_NUMBER: u32 = 491406834u32;\npub const WMT_VIDEOIMAGE_MAGIC_NUMBER_2: u32 = 491406835u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WMT_VIDEOIMAGE_SAMPLE {\n    pub dwMagic: u32,\n    pub cbStruct: u32,\n    pub dwControlFlags: u32,\n    pub dwInputFlagsCur: u32,\n    pub lCurMotionXtoX: i32,\n    pub lCurMotionYtoX: i32,\n    pub lCurMotionXoffset: i32,\n    pub lCurMotionXtoY: i32,\n    pub lCurMotionYtoY: i32,\n    pub lCurMotionYoffset: i32,\n    pub lCurBlendCoef1: i32,\n    pub lCurBlendCoef2: i32,\n    pub dwInputFlagsPrev: u32,\n    pub lPrevMotionXtoX: i32,\n    pub lPrevMotionYtoX: i32,\n    pub lPrevMotionXoffset: i32,\n    pub lPrevMotionXtoY: i32,\n    pub lPrevMotionYtoY: i32,\n    pub lPrevMotionYoffset: i32,\n    pub lPrevBlendCoef1: i32,\n    pub lPrevBlendCoef2: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WMT_VIDEOIMAGE_SAMPLE2 {\n    pub dwMagic: u32,\n    pub dwStructSize: u32,\n    pub dwControlFlags: u32,\n    pub dwViewportWidth: u32,\n    pub dwViewportHeight: u32,\n    pub dwCurrImageWidth: u32,\n    pub dwCurrImageHeight: u32,\n    pub fCurrRegionX0: f32,\n    pub fCurrRegionY0: f32,\n    pub fCurrRegionWidth: f32,\n    pub fCurrRegionHeight: f32,\n    pub fCurrBlendCoef: f32,\n    pub dwPrevImageWidth: u32,\n    pub dwPrevImageHeight: u32,\n    pub fPrevRegionX0: f32,\n    pub fPrevRegionY0: f32,\n    pub fPrevRegionWidth: f32,\n    pub fPrevRegionHeight: f32,\n    pub fPrevBlendCoef: f32,\n    pub dwEffectType: u32,\n    pub dwNumEffectParas: u32,\n    pub fEffectPara0: f32,\n    pub fEffectPara1: f32,\n    pub fEffectPara2: f32,\n    pub fEffectPara3: f32,\n    pub fEffectPara4: f32,\n    pub bKeepPrevImage: windows_sys::core::BOOL,\n}\npub const WMT_VIDEOIMAGE_SAMPLE_ADV_BLENDING: u32 = 8u32;\npub const WMT_VIDEOIMAGE_SAMPLE_BLENDING: u32 = 4u32;\npub const WMT_VIDEOIMAGE_SAMPLE_INPUT_FRAME: u32 = 1u32;\npub const WMT_VIDEOIMAGE_SAMPLE_MOTION: u32 = 1u32;\npub const WMT_VIDEOIMAGE_SAMPLE_OUTPUT_FRAME: u32 = 2u32;\npub const WMT_VIDEOIMAGE_SAMPLE_ROTATION: u32 = 2u32;\npub const WMT_VIDEOIMAGE_SAMPLE_USES_CURRENT_INPUT_FRAME: u32 = 4u32;\npub const WMT_VIDEOIMAGE_SAMPLE_USES_PREVIOUS_INPUT_FRAME: u32 = 8u32;\npub const WMT_VIDEOIMAGE_TRANSITION_BOW_TIE: u32 = 11u32;\npub const WMT_VIDEOIMAGE_TRANSITION_CIRCLE: u32 = 12u32;\npub const WMT_VIDEOIMAGE_TRANSITION_CROSS_FADE: u32 = 13u32;\npub const WMT_VIDEOIMAGE_TRANSITION_DIAGONAL: u32 = 14u32;\npub const WMT_VIDEOIMAGE_TRANSITION_DIAMOND: u32 = 15u32;\npub const WMT_VIDEOIMAGE_TRANSITION_FADE_TO_COLOR: u32 = 16u32;\npub const WMT_VIDEOIMAGE_TRANSITION_FILLED_V: u32 = 17u32;\npub const WMT_VIDEOIMAGE_TRANSITION_FLIP: u32 = 18u32;\npub const WMT_VIDEOIMAGE_TRANSITION_INSET: u32 = 19u32;\npub const WMT_VIDEOIMAGE_TRANSITION_IRIS: u32 = 20u32;\npub const WMT_VIDEOIMAGE_TRANSITION_PAGE_ROLL: u32 = 21u32;\npub const WMT_VIDEOIMAGE_TRANSITION_RECTANGLE: u32 = 23u32;\npub const WMT_VIDEOIMAGE_TRANSITION_REVEAL: u32 = 24u32;\npub const WMT_VIDEOIMAGE_TRANSITION_SLIDE: u32 = 27u32;\npub const WMT_VIDEOIMAGE_TRANSITION_SPLIT: u32 = 29u32;\npub const WMT_VIDEOIMAGE_TRANSITION_STAR: u32 = 30u32;\npub const WMT_VIDEOIMAGE_TRANSITION_WHEEL: u32 = 31u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WMT_WATERMARK_ENTRY {\n    pub wmetType: WMT_WATERMARK_ENTRY_TYPE,\n    pub clsid: windows_sys::core::GUID,\n    pub cbDisplayName: u32,\n    pub pwszDisplayName: windows_sys::core::PWSTR,\n}\nimpl Default for WMT_WATERMARK_ENTRY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type WMT_WATERMARK_ENTRY_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WMT_WEBSTREAM_FORMAT {\n    pub cbSize: u16,\n    pub cbSampleHeaderFixedData: u16,\n    pub wVersion: u16,\n    pub wReserved: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WMT_WEBSTREAM_SAMPLE_HEADER {\n    pub cbLength: u16,\n    pub wPart: u16,\n    pub cTotalParts: u16,\n    pub wSampleType: u16,\n    pub wszURL: [u16; 1],\n}\nimpl Default for WMT_WEBSTREAM_SAMPLE_HEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WMT_WMETYPE_AUDIO: WMT_WATERMARK_ENTRY_TYPE = 1i32;\npub const WMT_WMETYPE_VIDEO: WMT_WATERMARK_ENTRY_TYPE = 2i32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct WMVIDEOINFOHEADER {\n    pub rcSource: super::super::Foundation::RECT,\n    pub rcTarget: super::super::Foundation::RECT,\n    pub dwBitRate: u32,\n    pub dwBitErrorRate: u32,\n    pub AvgTimePerFrame: i64,\n    pub bmiHeader: super::super::Graphics::Gdi::BITMAPINFOHEADER,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct WMVIDEOINFOHEADER2 {\n    pub rcSource: super::super::Foundation::RECT,\n    pub rcTarget: super::super::Foundation::RECT,\n    pub dwBitRate: u32,\n    pub dwBitErrorRate: u32,\n    pub AvgTimePerFrame: i64,\n    pub dwInterlaceFlags: u32,\n    pub dwCopyProtectFlags: u32,\n    pub dwPictAspectRatioX: u32,\n    pub dwPictAspectRatioY: u32,\n    pub dwReserved1: u32,\n    pub dwReserved2: u32,\n    pub bmiHeader: super::super::Graphics::Gdi::BITMAPINFOHEADER,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WM_ADDRESS_ACCESSENTRY {\n    pub dwIPAddress: u32,\n    pub dwMask: u32,\n}\npub type WM_AETYPE = i32;\npub const WM_AETYPE_EXCLUDE: WM_AETYPE = 101i32;\npub const WM_AETYPE_INCLUDE: WM_AETYPE = 105i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WM_CLIENT_PROPERTIES {\n    pub dwIPAddress: u32,\n    pub dwPort: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WM_CLIENT_PROPERTIES_EX {\n    pub cbSize: u32,\n    pub pwszIPAddress: windows_sys::core::PCWSTR,\n    pub pwszPort: windows_sys::core::PCWSTR,\n    pub pwszDNSName: windows_sys::core::PCWSTR,\n}\nimpl Default for WM_CLIENT_PROPERTIES_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WM_CL_INTERLACED420: u32 = 0u32;\npub const WM_CL_PROGRESSIVE420: u32 = 1u32;\npub const WM_CT_BOTTOM_FIELD_FIRST: u32 = 32u32;\npub const WM_CT_INTERLACED: u32 = 128u32;\npub const WM_CT_REPEAT_FIRST_FIELD: u32 = 16u32;\npub const WM_CT_TOP_FIELD_FIRST: u32 = 64u32;\npub const WM_DM_DEINTERLACE_HALFSIZE: WM_DM_INTERLACED_TYPE = 2i32;\npub const WM_DM_DEINTERLACE_HALFSIZEDOUBLERATE: WM_DM_INTERLACED_TYPE = 3i32;\npub const WM_DM_DEINTERLACE_INVERSETELECINE: WM_DM_INTERLACED_TYPE = 4i32;\npub const WM_DM_DEINTERLACE_NORMAL: WM_DM_INTERLACED_TYPE = 1i32;\npub const WM_DM_DEINTERLACE_VERTICALHALFSIZEDOUBLERATE: WM_DM_INTERLACED_TYPE = 5i32;\npub type WM_DM_INTERLACED_TYPE = i32;\npub const WM_DM_IT_DISABLE_COHERENT_MODE: WM_DM_IT_FIRST_FRAME_COHERENCY = 0i32;\npub type WM_DM_IT_FIRST_FRAME_COHERENCY = i32;\npub const WM_DM_IT_FIRST_FRAME_IN_CLIP_IS_AA_BOTTOM: WM_DM_IT_FIRST_FRAME_COHERENCY = 6i32;\npub const WM_DM_IT_FIRST_FRAME_IN_CLIP_IS_AA_TOP: WM_DM_IT_FIRST_FRAME_COHERENCY = 1i32;\npub const WM_DM_IT_FIRST_FRAME_IN_CLIP_IS_BB_BOTTOM: WM_DM_IT_FIRST_FRAME_COHERENCY = 7i32;\npub const WM_DM_IT_FIRST_FRAME_IN_CLIP_IS_BB_TOP: WM_DM_IT_FIRST_FRAME_COHERENCY = 2i32;\npub const WM_DM_IT_FIRST_FRAME_IN_CLIP_IS_BC_BOTTOM: WM_DM_IT_FIRST_FRAME_COHERENCY = 8i32;\npub const WM_DM_IT_FIRST_FRAME_IN_CLIP_IS_BC_TOP: WM_DM_IT_FIRST_FRAME_COHERENCY = 3i32;\npub const WM_DM_IT_FIRST_FRAME_IN_CLIP_IS_CD_BOTTOM: WM_DM_IT_FIRST_FRAME_COHERENCY = 9i32;\npub const WM_DM_IT_FIRST_FRAME_IN_CLIP_IS_CD_TOP: WM_DM_IT_FIRST_FRAME_COHERENCY = 4i32;\npub const WM_DM_IT_FIRST_FRAME_IN_CLIP_IS_DD_BOTTOM: WM_DM_IT_FIRST_FRAME_COHERENCY = 10i32;\npub const WM_DM_IT_FIRST_FRAME_IN_CLIP_IS_DD_TOP: WM_DM_IT_FIRST_FRAME_COHERENCY = 5i32;\npub const WM_DM_NOTINTERLACED: WM_DM_INTERLACED_TYPE = 0i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct WM_LEAKY_BUCKET_PAIR {\n    pub dwBitrate: u32,\n    pub msBufferWindow: u32,\n}\npub const WM_MAX_STREAMS: u32 = 63u32;\npub const WM_MAX_VIDEO_STREAMS: u32 = 63u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WM_MEDIA_TYPE {\n    pub majortype: windows_sys::core::GUID,\n    pub subtype: windows_sys::core::GUID,\n    pub bFixedSizeSamples: windows_sys::core::BOOL,\n    pub bTemporalCompression: windows_sys::core::BOOL,\n    pub lSampleSize: u32,\n    pub formattype: windows_sys::core::GUID,\n    pub pUnk: *mut core::ffi::c_void,\n    pub cbFormat: u32,\n    pub pbFormat: *mut u8,\n}\nimpl Default for WM_MEDIA_TYPE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WM_PICTURE {\n    pub pwszMIMEType: windows_sys::core::PWSTR,\n    pub bPictureType: u8,\n    pub pwszDescription: windows_sys::core::PWSTR,\n    pub dwDataLen: u32,\n    pub pbData: *mut u8,\n}\nimpl Default for WM_PICTURE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WM_PLAYBACK_DRC_HIGH: WM_PLAYBACK_DRC_LEVEL = 0i32;\npub type WM_PLAYBACK_DRC_LEVEL = i32;\npub const WM_PLAYBACK_DRC_LOW: WM_PLAYBACK_DRC_LEVEL = 2i32;\npub const WM_PLAYBACK_DRC_MEDIUM: WM_PLAYBACK_DRC_LEVEL = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WM_PORT_NUMBER_RANGE {\n    pub wPortBegin: u16,\n    pub wPortEnd: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WM_READER_CLIENTINFO {\n    pub cbSize: u32,\n    pub wszLang: windows_sys::core::PWSTR,\n    pub wszBrowserUserAgent: windows_sys::core::PWSTR,\n    pub wszBrowserWebPage: windows_sys::core::PWSTR,\n    pub qwReserved: u64,\n    pub pReserved: *mut super::super::Foundation::LPARAM,\n    pub wszHostExe: windows_sys::core::PWSTR,\n    pub qwHostVersion: u64,\n    pub wszPlayerUserAgent: windows_sys::core::PWSTR,\n}\nimpl Default for WM_READER_CLIENTINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WM_READER_STATISTICS {\n    pub cbSize: u32,\n    pub dwBandwidth: u32,\n    pub cPacketsReceived: u32,\n    pub cPacketsRecovered: u32,\n    pub cPacketsLost: u32,\n    pub wQuality: u16,\n}\npub const WM_SFEX_DATALOSS: WM_SFEX_TYPE = 4i32;\npub const WM_SFEX_NOTASYNCPOINT: WM_SFEX_TYPE = 2i32;\npub type WM_SFEX_TYPE = i32;\npub const WM_SF_CLEANPOINT: WM_SF_TYPE = 1i32;\npub const WM_SF_DATALOSS: WM_SF_TYPE = 4i32;\npub const WM_SF_DISCONTINUITY: WM_SF_TYPE = 2i32;\npub type WM_SF_TYPE = i32;\n#[repr(C, packed(2))]\n#[derive(Clone, Copy, Default)]\npub struct WM_STREAM_PRIORITY_RECORD {\n    pub wStreamNumber: u16,\n    pub fMandatory: windows_sys::core::BOOL,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct WM_STREAM_TYPE_INFO {\n    pub guidMajorType: windows_sys::core::GUID,\n    pub cbFormat: u32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WM_SYNCHRONISED_LYRICS {\n    pub bTimeStampFormat: u8,\n    pub bContentType: u8,\n    pub pwszContentDescriptor: windows_sys::core::PWSTR,\n    pub dwLyricsLen: u32,\n    pub pbLyrics: *mut u8,\n}\nimpl Default for WM_SYNCHRONISED_LYRICS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const WM_SampleExtensionGUID_ChromaLocation: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4c5acca0_9276_4b2c_9e4c_a0edefdd217e);\npub const WM_SampleExtensionGUID_ColorSpaceInfo: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf79ada56_30eb_4f2b_9f7a_f24b139a1157);\npub const WM_SampleExtensionGUID_ContentType: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd590dc20_07bc_436c_9cf7_f3bbfbf1a4dc);\npub const WM_SampleExtensionGUID_FileName: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe165ec0e_19ed_45d7_b4a7_25cbd1e28e9b);\npub const WM_SampleExtensionGUID_OutputCleanPoint: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf72a3c6f_6eb4_4ebc_b192_09ad9759e828);\npub const WM_SampleExtensionGUID_PixelAspectRatio: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1b1ee554_f9ea_4bc8_821a_376b74e4c4b8);\npub const WM_SampleExtensionGUID_SampleDuration: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc6bd9450_867f_4907_83a3_c77921b733ad);\npub const WM_SampleExtensionGUID_SampleProtectionSalt: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x5403deee_b9ee_438f_aa83_3804997e569d);\npub const WM_SampleExtensionGUID_Timecode: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x399595ec_8667_4e2d_8fdb_98814ce76c1e);\npub const WM_SampleExtensionGUID_UserDataInfo: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x732bb4fa_78be_4549_99bd_02db1a55b7a8);\npub const WM_SampleExtension_ChromaLocation_Size: u32 = 1u32;\npub const WM_SampleExtension_ColorSpaceInfo_Size: u32 = 3u32;\npub const WM_SampleExtension_ContentType_Size: u32 = 1u32;\npub const WM_SampleExtension_PixelAspectRatio_Size: u32 = 2u32;\npub const WM_SampleExtension_SampleDuration_Size: u32 = 2u32;\npub const WM_SampleExtension_Timecode_Size: u32 = 14u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WM_USER_TEXT {\n    pub pwszDescription: windows_sys::core::PWSTR,\n    pub pwszText: windows_sys::core::PWSTR,\n}\nimpl Default for WM_USER_TEXT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WM_USER_WEB_URL {\n    pub pwszDescription: windows_sys::core::PWSTR,\n    pub pwszURL: windows_sys::core::PWSTR,\n}\nimpl Default for WM_USER_WEB_URL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WM_WRITER_STATISTICS {\n    pub qwSampleCount: u64,\n    pub qwByteCount: u64,\n    pub qwDroppedSampleCount: u64,\n    pub qwDroppedByteCount: u64,\n    pub dwCurrentBitrate: u32,\n    pub dwAverageBitrate: u32,\n    pub dwExpectedBitrate: u32,\n    pub dwCurrentSampleRate: u32,\n    pub dwAverageSampleRate: u32,\n    pub dwExpectedSampleRate: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WM_WRITER_STATISTICS_EX {\n    pub dwBitratePlusOverhead: u32,\n    pub dwCurrentSampleDropRateInQueue: u32,\n    pub dwCurrentSampleDropRateInCodec: u32,\n    pub dwCurrentSampleDropRateInMultiplexer: u32,\n    pub dwTotalSampleDropsInQueue: u32,\n    pub dwTotalSampleDropsInCodec: u32,\n    pub dwTotalSampleDropsInMultiplexer: u32,\n}\npub type _AM_ASFWRITERCONFIG_PARAM = i32;\npub const g_dwWMContentAttributes: u32 = 5u32;\npub const g_dwWMNSCAttributes: u32 = 5u32;\npub const g_dwWMSpecialAttributes: u32 = 20u32;\npub const g_wszASFLeakyBucketPairs: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ASFLeakyBucketPairs\");\npub const g_wszAllowInterlacedOutput: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AllowInterlacedOutput\");\npub const g_wszAverageLevel: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AverageLevel\");\npub const g_wszBufferAverage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Buffer Average\");\npub const g_wszComplexity: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_COMPLEXITYEX\");\npub const g_wszComplexityLive: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_COMPLEXITYEXLIVE\");\npub const g_wszComplexityMax: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_COMPLEXITYEXMAX\");\npub const g_wszComplexityOffline: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_COMPLEXITYEXOFFLINE\");\npub const g_wszDecoderComplexityRequested: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_DECODERCOMPLEXITYPROFILE\");\npub const g_wszDedicatedDeliveryThread: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DedicatedDeliveryThread\");\npub const g_wszDeinterlaceMode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DeinterlaceMode\");\npub const g_wszDeliverOnReceive: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DeliverOnReceive\");\npub const g_wszDeviceConformanceTemplate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DeviceConformanceTemplate\");\npub const g_wszDynamicRangeControl: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DynamicRangeControl\");\npub const g_wszEDL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_EDL\");\npub const g_wszEarlyDataDelivery: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EarlyDataDelivery\");\npub const g_wszEnableDiscreteOutput: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnableDiscreteOutput\");\npub const g_wszEnableFrameInterpolation: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnableFrameInterpolation\");\npub const g_wszEnableWMAProSPDIFOutput: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnableWMAProSPDIFOutput\");\npub const g_wszFailSeekOnError: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FailSeekOnError\");\npub const g_wszFixedFrameRate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FixedFrameRate\");\npub const g_wszFold6To2Channels3: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Fold6To2Channels3\");\npub const g_wszFoldToChannelsTemplate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Fold%luTo%luChannels%lu\");\npub const g_wszInitialPatternForInverseTelecine: windows_sys::core::PCWSTR = windows_sys::core::w!(\"InitialPatternForInverseTelecine\");\npub const g_wszInterlacedCoding: windows_sys::core::PCWSTR = windows_sys::core::w!(\"InterlacedCoding\");\npub const g_wszIsVBRSupported: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_ISVBRSUPPORTED\");\npub const g_wszJPEGCompressionQuality: windows_sys::core::PCWSTR = windows_sys::core::w!(\"JPEGCompressionQuality\");\npub const g_wszJustInTimeDecode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"JustInTimeDecode\");\npub const g_wszMixedClassMode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MixedClassMode\");\npub const g_wszMusicClassMode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MusicClassMode\");\npub const g_wszMusicSpeechClassMode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MusicSpeechClassMode\");\npub const g_wszNeedsPreviousSample: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NeedsPreviousSample\");\npub const g_wszNumPasses: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_PASSESUSED\");\npub const g_wszOriginalSourceFormatTag: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_SOURCEFORMATTAG\");\npub const g_wszOriginalWaveFormat: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_ORIGINALWAVEFORMAT\");\npub const g_wszPeakValue: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PeakValue\");\npub const g_wszPermitSeeksBeyondEndOfStream: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PermitSeeksBeyondEndOfStream\");\npub const g_wszReloadIndexOnSeek: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ReloadIndexOnSeek\");\npub const g_wszScrambledAudio: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ScrambledAudio\");\npub const g_wszSingleOutputBuffer: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SingleOutputBuffer\");\npub const g_wszSoftwareScaling: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SoftwareScaling\");\npub const g_wszSourceBufferTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SourceBufferTime\");\npub const g_wszSourceMaxBytesAtOnce: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SourceMaxBytesAtOnce\");\npub const g_wszSpeakerConfig: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SpeakerConfig\");\npub const g_wszSpeechCaps: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SpeechFormatCap\");\npub const g_wszSpeechClassMode: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SpeechClassMode\");\npub const g_wszStreamLanguage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"StreamLanguage\");\npub const g_wszStreamNumIndexObjects: windows_sys::core::PCWSTR = windows_sys::core::w!(\"StreamNumIndexObjects\");\npub const g_wszUsePacketAtSeekPoint: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UsePacketAtSeekPoint\");\npub const g_wszVBRBitrateMax: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_RMAX\");\npub const g_wszVBRBufferWindowMax: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_BMAX\");\npub const g_wszVBREnabled: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_VBRENABLED\");\npub const g_wszVBRPeak: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VBR Peak\");\npub const g_wszVBRQuality: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_VBRQUALITY\");\npub const g_wszVideoSampleDurations: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VideoSampleDurations\");\npub const g_wszWMADID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ADID\");\npub const g_wszWMASFPacketCount: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ASFPacketCount\");\npub const g_wszWMASFSecurityObjectsSize: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ASFSecurityObjectsSize\");\npub const g_wszWMAlbumArtist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/AlbumArtist\");\npub const g_wszWMAlbumArtistSort: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/AlbumArtistSort\");\npub const g_wszWMAlbumCoverURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/AlbumCoverURL\");\npub const g_wszWMAlbumTitle: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/AlbumTitle\");\npub const g_wszWMAlbumTitleSort: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/AlbumTitleSort\");\npub const g_wszWMAspectRatioX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AspectRatioX\");\npub const g_wszWMAspectRatioY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AspectRatioY\");\npub const g_wszWMAudioFileURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/AudioFileURL\");\npub const g_wszWMAudioSourceURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/AudioSourceURL\");\npub const g_wszWMAuthor: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Author\");\npub const g_wszWMAuthorSort: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AuthorSort\");\npub const g_wszWMAuthorURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/AuthorURL\");\npub const g_wszWMBannerImageData: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BannerImageData\");\npub const g_wszWMBannerImageType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BannerImageType\");\npub const g_wszWMBannerImageURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BannerImageURL\");\npub const g_wszWMBeatsPerMinute: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/BeatsPerMinute\");\npub const g_wszWMBitrate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Bitrate\");\npub const g_wszWMBroadcast: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Broadcast\");\npub const g_wszWMCategory: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Category\");\npub const g_wszWMCodec: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Codec\");\npub const g_wszWMComposer: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Composer\");\npub const g_wszWMComposerSort: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ComposerSort\");\npub const g_wszWMConductor: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Conductor\");\npub const g_wszWMContainerFormat: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ContainerFormat\");\npub const g_wszWMContentDistributor: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ContentDistributor\");\npub const g_wszWMContentGroupDescription: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ContentGroupDescription\");\npub const g_wszWMCopyright: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Copyright\");\npub const g_wszWMCopyrightURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CopyrightURL\");\npub const g_wszWMCurrentBitrate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CurrentBitrate\");\npub const g_wszWMDRM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/DRM\");\npub const g_wszWMDRM_ContentID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_ContentID\");\npub const g_wszWMDRM_Flags: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_Flags\");\npub const g_wszWMDRM_HeaderSignPrivKey: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_HeaderSignPrivKey\");\npub const g_wszWMDRM_IndividualizedVersion: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_IndividualizedVersion\");\npub const g_wszWMDRM_KeyID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_KeyID\");\npub const g_wszWMDRM_KeySeed: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_KeySeed\");\npub const g_wszWMDRM_LASignatureCert: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_LASignatureCert\");\npub const g_wszWMDRM_LASignatureLicSrvCert: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_LASignatureLicSrvCert\");\npub const g_wszWMDRM_LASignaturePrivKey: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_LASignaturePrivKey\");\npub const g_wszWMDRM_LASignatureRootCert: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_LASignatureRootCert\");\npub const g_wszWMDRM_Level: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_Level\");\npub const g_wszWMDRM_LicenseAcqURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_LicenseAcqURL\");\npub const g_wszWMDRM_SourceID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_SourceID\");\npub const g_wszWMDRM_V1LicenseAcqURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRM_V1LicenseAcqURL\");\npub const g_wszWMDVDID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/DVDID\");\npub const g_wszWMDescription: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Description\");\npub const g_wszWMDirector: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Director\");\npub const g_wszWMDuration: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Duration\");\npub const g_wszWMEncodedBy: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/EncodedBy\");\npub const g_wszWMEncodingSettings: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/EncodingSettings\");\npub const g_wszWMEncodingTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/EncodingTime\");\npub const g_wszWMEpisodeNumber: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/EpisodeNumber\");\npub const g_wszWMFileSize: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FileSize\");\npub const g_wszWMGenre: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Genre\");\npub const g_wszWMGenreID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/GenreID\");\npub const g_wszWMHasArbitraryDataStream: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HasArbitraryDataStream\");\npub const g_wszWMHasAttachedImages: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HasAttachedImages\");\npub const g_wszWMHasAudio: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HasAudio\");\npub const g_wszWMHasFileTransferStream: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HasFileTransferStream\");\npub const g_wszWMHasImage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HasImage\");\npub const g_wszWMHasScript: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HasScript\");\npub const g_wszWMHasVideo: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HasVideo\");\npub const g_wszWMISAN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ISAN\");\npub const g_wszWMISRC: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ISRC\");\npub const g_wszWMInitialKey: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/InitialKey\");\npub const g_wszWMIsCompilation: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/IsCompilation\");\npub const g_wszWMIsVBR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IsVBR\");\npub const g_wszWMLanguage: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Language\");\npub const g_wszWMLyrics: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Lyrics\");\npub const g_wszWMLyrics_Synchronised: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Lyrics_Synchronised\");\npub const g_wszWMMCDI: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MCDI\");\npub const g_wszWMMediaClassPrimaryID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaClassPrimaryID\");\npub const g_wszWMMediaClassSecondaryID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaClassSecondaryID\");\npub const g_wszWMMediaCredits: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaCredits\");\npub const g_wszWMMediaIsDelay: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaIsDelay\");\npub const g_wszWMMediaIsFinale: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaIsFinale\");\npub const g_wszWMMediaIsLive: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaIsLive\");\npub const g_wszWMMediaIsPremiere: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaIsPremiere\");\npub const g_wszWMMediaIsRepeat: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaIsRepeat\");\npub const g_wszWMMediaIsSAP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaIsSAP\");\npub const g_wszWMMediaIsStereo: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaIsStereo\");\npub const g_wszWMMediaIsSubtitled: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaIsSubtitled\");\npub const g_wszWMMediaIsTape: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaIsTape\");\npub const g_wszWMMediaNetworkAffiliation: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaNetworkAffiliation\");\npub const g_wszWMMediaOriginalBroadcastDateTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaOriginalBroadcastDateTime\");\npub const g_wszWMMediaOriginalChannel: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaOriginalChannel\");\npub const g_wszWMMediaStationCallSign: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaStationCallSign\");\npub const g_wszWMMediaStationName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/MediaStationName\");\npub const g_wszWMModifiedBy: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ModifiedBy\");\npub const g_wszWMMood: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Mood\");\npub const g_wszWMNSCAddress: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NSC_Address\");\npub const g_wszWMNSCDescription: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NSC_Description\");\npub const g_wszWMNSCEmail: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NSC_Email\");\npub const g_wszWMNSCName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NSC_Name\");\npub const g_wszWMNSCPhone: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NSC_Phone\");\npub const g_wszWMNumberOfFrames: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NumberOfFrames\");\npub const g_wszWMOptimalBitrate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OptimalBitrate\");\npub const g_wszWMOriginalAlbumTitle: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/OriginalAlbumTitle\");\npub const g_wszWMOriginalArtist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/OriginalArtist\");\npub const g_wszWMOriginalFilename: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/OriginalFilename\");\npub const g_wszWMOriginalLyricist: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/OriginalLyricist\");\npub const g_wszWMOriginalReleaseTime: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/OriginalReleaseTime\");\npub const g_wszWMOriginalReleaseYear: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/OriginalReleaseYear\");\npub const g_wszWMParentalRating: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ParentalRating\");\npub const g_wszWMParentalRatingReason: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ParentalRatingReason\");\npub const g_wszWMPartOfSet: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/PartOfSet\");\npub const g_wszWMPeakBitrate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/PeakBitrate\");\npub const g_wszWMPeriod: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Period\");\npub const g_wszWMPicture: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Picture\");\npub const g_wszWMPlaylistDelay: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/PlaylistDelay\");\npub const g_wszWMProducer: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Producer\");\npub const g_wszWMPromotionURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/PromotionURL\");\npub const g_wszWMProtected: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Is_Protected\");\npub const g_wszWMProtectionType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ProtectionType\");\npub const g_wszWMProvider: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Provider\");\npub const g_wszWMProviderCopyright: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ProviderCopyright\");\npub const g_wszWMProviderRating: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ProviderRating\");\npub const g_wszWMProviderStyle: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ProviderStyle\");\npub const g_wszWMPublisher: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Publisher\");\npub const g_wszWMRadioStationName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/RadioStationName\");\npub const g_wszWMRadioStationOwner: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/RadioStationOwner\");\npub const g_wszWMRating: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Rating\");\npub const g_wszWMSeasonNumber: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/SeasonNumber\");\npub const g_wszWMSeekable: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Seekable\");\npub const g_wszWMSharedUserRating: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/SharedUserRating\");\npub const g_wszWMSignature_Name: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Signature_Name\");\npub const g_wszWMSkipBackward: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Can_Skip_Backward\");\npub const g_wszWMSkipForward: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Can_Skip_Forward\");\npub const g_wszWMStreamTypeInfo: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/StreamTypeInfo\");\npub const g_wszWMStridable: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Stridable\");\npub const g_wszWMSubTitle: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/SubTitle\");\npub const g_wszWMSubTitleDescription: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/SubTitleDescription\");\npub const g_wszWMSubscriptionContentID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/SubscriptionContentID\");\npub const g_wszWMText: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Text\");\npub const g_wszWMTitle: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Title\");\npub const g_wszWMTitleSort: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TitleSort\");\npub const g_wszWMToolName: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ToolName\");\npub const g_wszWMToolVersion: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/ToolVersion\");\npub const g_wszWMTrack: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Track\");\npub const g_wszWMTrackNumber: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/TrackNumber\");\npub const g_wszWMTrusted: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Is_Trusted\");\npub const g_wszWMUniqueFileIdentifier: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/UniqueFileIdentifier\");\npub const g_wszWMUse_Advanced_DRM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Use_Advanced_DRM\");\npub const g_wszWMUse_DRM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Use_DRM\");\npub const g_wszWMUserWebURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/UserWebURL\");\npub const g_wszWMVideoClosedCaptioning: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/VideoClosedCaptioning\");\npub const g_wszWMVideoFrameRate: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/VideoFrameRate\");\npub const g_wszWMVideoHeight: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/VideoHeight\");\npub const g_wszWMVideoWidth: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/VideoWidth\");\npub const g_wszWMWMADRCAverageReference: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMADRCAverageReference\");\npub const g_wszWMWMADRCAverageTarget: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMADRCAverageTarget\");\npub const g_wszWMWMADRCPeakReference: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMADRCPeakReference\");\npub const g_wszWMWMADRCPeakTarget: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMADRCPeakTarget\");\npub const g_wszWMWMCPDistributor: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMCPDistributor\");\npub const g_wszWMWMCPDistributorID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMCPDistributorID\");\npub const g_wszWMWMCollectionGroupID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMCollectionGroupID\");\npub const g_wszWMWMCollectionID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMCollectionID\");\npub const g_wszWMWMContentID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMContentID\");\npub const g_wszWMWMShadowFileSourceDRMType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMShadowFileSourceDRMType\");\npub const g_wszWMWMShadowFileSourceFileType: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/WMShadowFileSourceFileType\");\npub const g_wszWMWriter: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Writer\");\npub const g_wszWMYear: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WM/Year\");\npub const g_wszWatermarkCLSID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WatermarkCLSID\");\npub const g_wszWatermarkConfig: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WatermarkConfig\");\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/Security/Cryptography/Certificates/mod.rs",
      "sha256": "8724d6eb2e2d010aaaf45fb85ea1b572f08edd009decd45d1795e865818ac656",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "windows_link::link!(\"certadm.dll\" \"system\" fn CertSrvBackupClose(hbc : *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvBackupEnd(hbc : *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvBackupFree(pv : *mut core::ffi::c_void));\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvBackupGetBackupLogsW(hbc : *const core::ffi::c_void, ppwszzbackuplogfiles : *mut windows_sys::core::PWSTR, pcbsize : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvBackupGetDatabaseNamesW(hbc : *const core::ffi::c_void, ppwszzattachmentinformation : *mut windows_sys::core::PWSTR, pcbsize : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvBackupGetDynamicFileListW(hbc : *const core::ffi::c_void, ppwszzfilelist : *mut windows_sys::core::PWSTR, pcbsize : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvBackupOpenFileW(hbc : *mut core::ffi::c_void, pwszattachmentname : windows_sys::core::PCWSTR, cbreadhintsize : u32, plifilesize : *mut i64) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvBackupPrepareW(pwszservername : windows_sys::core::PCWSTR, grbitjet : u32, dwbackupflags : CSBACKUP_TYPE, phbc : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvBackupRead(hbc : *mut core::ffi::c_void, pvbuffer : *mut core::ffi::c_void, cbbuffer : u32, pcbread : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvBackupTruncateLogs(hbc : *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvIsServerOnlineW(pwszservername : windows_sys::core::PCWSTR, pfserveronline : *mut windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvRestoreEnd(hbc : *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvRestoreGetDatabaseLocationsW(hbc : *const core::ffi::c_void, ppwszzdatabaselocationlist : *mut windows_sys::core::PWSTR, pcbsize : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvRestorePrepareW(pwszservername : windows_sys::core::PCWSTR, dwrestoreflags : u32, phbc : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvRestoreRegisterComplete(hbc : *mut core::ffi::c_void, hrrestorestate : windows_sys::core::HRESULT) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvRestoreRegisterThroughFile(hbc : *mut core::ffi::c_void, pwszcheckpointfilepath : windows_sys::core::PCWSTR, pwszlogpath : windows_sys::core::PCWSTR, rgrstmap : *mut CSEDB_RSTMAPW, crstmap : i32, pwszbackuplogpath : windows_sys::core::PCWSTR, genlow : u32, genhigh : u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvRestoreRegisterW(hbc : *mut core::ffi::c_void, pwszcheckpointfilepath : windows_sys::core::PCWSTR, pwszlogpath : windows_sys::core::PCWSTR, rgrstmap : *mut CSEDB_RSTMAPW, crstmap : i32, pwszbackuplogpath : windows_sys::core::PCWSTR, genlow : u32, genhigh : u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certadm.dll\" \"system\" fn CertSrvServerControlW(pwszservername : windows_sys::core::PCWSTR, dwcontrolflags : u32, pcbout : *mut u32, ppbout : *mut *mut u8) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"certpoleng.dll\" \"system\" fn PstAcquirePrivateKey(pcert : *const super:: CERT_CONTEXT) -> super::super::super::Foundation:: NTSTATUS);\n#[cfg(feature = \"Win32_Security_Authentication_Identity\")]\nwindows_link::link!(\"certpoleng.dll\" \"system\" fn PstGetCertificateChain(pcert : *const super:: CERT_CONTEXT, ptrustedissuers : *const super::super::Authentication::Identity:: SecPkgContext_IssuerListInfoEx, ppcertchaincontext : *mut *mut super:: CERT_CHAIN_CONTEXT) -> super::super::super::Foundation:: NTSTATUS);\nwindows_link::link!(\"certpoleng.dll\" \"system\" fn PstGetCertificates(ptargetname : *const super::super::super::Foundation:: UNICODE_STRING, ccriteria : u32, rgpcriteria : *const super:: CERT_SELECT_CRITERIA, bisclient : windows_sys::core::BOOL, pdwcertchaincontextcount : *mut u32, ppcertchaincontexts : *mut *mut *mut super:: CERT_CHAIN_CONTEXT) -> super::super::super::Foundation:: NTSTATUS);\n#[cfg(feature = \"Win32_Security_Authentication_Identity\")]\nwindows_link::link!(\"certpoleng.dll\" \"system\" fn PstGetTrustAnchors(ptargetname : *const super::super::super::Foundation:: UNICODE_STRING, ccriteria : u32, rgpcriteria : *const super:: CERT_SELECT_CRITERIA, pptrustedissuers : *mut *mut super::super::Authentication::Identity:: SecPkgContext_IssuerListInfoEx) -> super::super::super::Foundation:: NTSTATUS);\n#[cfg(feature = \"Win32_Security_Authentication_Identity\")]\nwindows_link::link!(\"certpoleng.dll\" \"system\" fn PstGetTrustAnchorsEx(ptargetname : *const super::super::super::Foundation:: UNICODE_STRING, ccriteria : u32, rgpcriteria : *const super:: CERT_SELECT_CRITERIA, pcertcontext : *const super:: CERT_CONTEXT, pptrustedissuers : *mut *mut super::super::Authentication::Identity:: SecPkgContext_IssuerListInfoEx) -> super::super::super::Foundation:: NTSTATUS);\nwindows_link::link!(\"certpoleng.dll\" \"system\" fn PstGetUserNameForCertificate(pcertcontext : *const super:: CERT_CONTEXT, username : *mut super::super::super::Foundation:: UNICODE_STRING) -> super::super::super::Foundation:: NTSTATUS);\n#[cfg(feature = \"Win32_Security_Authentication_Identity\")]\nwindows_link::link!(\"certpoleng.dll\" \"system\" fn PstMapCertificate(pcert : *const super:: CERT_CONTEXT, ptokeninformationtype : *mut super::super::Authentication::Identity:: LSA_TOKEN_INFORMATION_TYPE, pptokeninformation : *mut *mut core::ffi::c_void) -> super::super::super::Foundation:: NTSTATUS);\nwindows_link::link!(\"certpoleng.dll\" \"system\" fn PstValidate(ptargetname : *const super::super::super::Foundation:: UNICODE_STRING, bisclient : windows_sys::core::BOOL, prequestedissuancepolicy : *const super:: CERT_USAGE_MATCH, phadditionalcertstore : *const super:: HCERTSTORE, pcert : *const super:: CERT_CONTEXT, pprovguid : *mut windows_sys::core::GUID) -> super::super::super::Foundation:: NTSTATUS);\npub type ADDED_CERT_TYPE = i32;\npub type AlgorithmFlags = i32;\npub const AlgorithmFlagsNone: AlgorithmFlags = 0i32;\npub const AlgorithmFlagsWrap: AlgorithmFlags = 1i32;\npub type AlgorithmOperationFlags = i32;\npub type AlgorithmType = i32;\npub const AllowNoOutstandingRequest: InstallResponseRestrictionFlags = 1i32;\npub const AllowNone: InstallResponseRestrictionFlags = 0i32;\npub const AllowUntrustedCertificate: InstallResponseRestrictionFlags = 2i32;\npub const AllowUntrustedRoot: InstallResponseRestrictionFlags = 4i32;\npub const AllowedKeySignature: Pkcs10AllowedSignatureTypes = 1i32;\npub const AllowedNullSignature: Pkcs10AllowedSignatureTypes = 2i32;\npub type AlternativeNameType = i32;\npub const CAIF_DSENTRY: u32 = 1u32;\npub const CAIF_LOCAL: u32 = 8u32;\npub const CAIF_REGISTRY: u32 = 4u32;\npub const CAIF_REGISTRYPARENT: u32 = 16u32;\npub const CAIF_SHAREDFOLDERENTRY: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CAINFO {\n    pub cbSize: u32,\n    pub CAType: ENUM_CATYPES,\n    pub cCASignatureCerts: u32,\n    pub cCAExchangeCerts: u32,\n    pub cExitModules: u32,\n    pub lPropIdMax: i32,\n    pub lRoleSeparationEnabled: i32,\n    pub cKRACertUsedCount: u32,\n    pub cKRACertCount: u32,\n    pub fAdvancedServer: u32,\n}\npub const CAPATHLENGTH_INFINITE: u32 = 4294967295u32;\npub const CAPropCertificate: EnrollmentCAProperty = 7i32;\npub const CAPropCertificateTypes: EnrollmentCAProperty = 6i32;\npub const CAPropCommonName: EnrollmentCAProperty = 1i32;\npub const CAPropDNSName: EnrollmentCAProperty = 5i32;\npub const CAPropDescription: EnrollmentCAProperty = 8i32;\npub const CAPropDistinguishedName: EnrollmentCAProperty = 2i32;\npub const CAPropRenewalOnly: EnrollmentCAProperty = 12i32;\npub const CAPropSanitizedName: EnrollmentCAProperty = 3i32;\npub const CAPropSanitizedShortName: EnrollmentCAProperty = 4i32;\npub const CAPropSecurity: EnrollmentCAProperty = 11i32;\npub const CAPropSiteName: EnrollmentCAProperty = 10i32;\npub const CAPropWebServers: EnrollmentCAProperty = 9i32;\npub const CA_ACCESS_ADMIN: CERTADMIN_GET_ROLES_FLAGS = 1u32;\npub const CA_ACCESS_AUDITOR: CERTADMIN_GET_ROLES_FLAGS = 4u32;\npub const CA_ACCESS_ENROLL: CERTADMIN_GET_ROLES_FLAGS = 512u32;\npub const CA_ACCESS_MASKROLES: u32 = 255u32;\npub const CA_ACCESS_OFFICER: CERTADMIN_GET_ROLES_FLAGS = 2u32;\npub const CA_ACCESS_OPERATOR: CERTADMIN_GET_ROLES_FLAGS = 8u32;\npub const CA_ACCESS_READ: CERTADMIN_GET_ROLES_FLAGS = 256u32;\npub const CA_CRL_BASE: u32 = 1u32;\npub const CA_CRL_DELTA: u32 = 2u32;\npub const CA_CRL_REPUBLISH: u32 = 16u32;\npub const CA_DISP_ERROR: u32 = 1u32;\npub const CA_DISP_INCOMPLETE: u32 = 0u32;\npub const CA_DISP_INVALID: u32 = 4u32;\npub const CA_DISP_REVOKED: u32 = 2u32;\npub const CA_DISP_UNDER_SUBMISSION: u32 = 5u32;\npub const CA_DISP_VALID: u32 = 3u32;\npub const CAlternativeName: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2013_217d_11da_b2a4_000e7bbb2b09);\npub const CAlternativeNames: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2014_217d_11da_b2a4_000e7bbb2b09);\npub const CBinaryConverter: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2002_217d_11da_b2a4_000e7bbb2b09);\npub const CCLOCKSKEWMINUTESDEFAULT: u32 = 10u32;\npub const CC_DEFAULTCONFIG: CERT_GET_CONFIG_FLAGS = 0i32;\npub const CC_FIRSTCONFIG: CERT_GET_CONFIG_FLAGS = 2i32;\npub const CC_LOCALACTIVECONFIG: CERT_GET_CONFIG_FLAGS = 4i32;\npub const CC_LOCALCONFIG: CERT_GET_CONFIG_FLAGS = 3i32;\npub const CC_UIPICKCONFIG: CERT_GET_CONFIG_FLAGS = 1i32;\npub const CC_UIPICKCONFIGSKIPLOCALCA: CERT_GET_CONFIG_FLAGS = 5i32;\npub const CCertAdmin: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x37eabaf0_7fb6_11d0_8817_00a0c903b83c);\npub const CCertConfig: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x372fce38_4324_11d0_8810_00a0c903b83c);\npub const CCertEncodeAltName: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1cfc4cda_1271_11d1_9bd4_00c04fb683fa);\npub const CCertEncodeBitString: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6d6b3cd8_1278_11d1_9bd4_00c04fb683fa);\npub const CCertEncodeCRLDistInfo: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x01fa60a0_bbff_11d0_8825_00a0c903b83c);\npub const CCertEncodeDateArray: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x301f77b0_a470_11d0_8821_00a0c903b83c);\npub const CCertEncodeLongArray: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4e0680a0_a0a2_11d0_8821_00a0c903b83c);\npub const CCertEncodeStringArray: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x19a76fe0_7494_11d0_8816_00a0c903b83c);\npub const CCertGetConfig: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xc6cc49b0_ce17_11d0_8833_00a0c903b83c);\npub const CCertProperties: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e202f_217d_11da_b2a4_000e7bbb2b09);\npub const CCertProperty: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e202e_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyArchived: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2037_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyArchivedKeyHash: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e203b_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyAutoEnroll: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2032_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyBackedUp: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2038_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyDescription: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2031_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyEnrollment: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2039_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyEnrollmentPolicyServer: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e204c_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyFriendlyName: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2030_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyKeyProvInfo: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2036_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyRenewal: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e203a_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertyRequestOriginator: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2033_217d_11da_b2a4_000e7bbb2b09);\npub const CCertPropertySHA1Hash: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2034_217d_11da_b2a4_000e7bbb2b09);\npub const CCertRequest: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x98aff3f0_5524_11d0_8812_00a0c903b83c);\npub const CCertServerExit: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4c4a5e40_732c_11d0_8816_00a0c903b83c);\npub const CCertServerPolicy: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xaa000926_ffbe_11cf_8800_00a0c903b83c);\npub const CCertView: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa12d0f7a_1e84_11d1_9bd6_00c04fb683fa);\npub const CCertificateAttestationChallenge: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1362ada1_eb60_456a_b6e1_118050db741b);\npub const CCertificatePolicies: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e201f_217d_11da_b2a4_000e7bbb2b09);\npub const CCertificatePolicy: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e201e_217d_11da_b2a4_000e7bbb2b09);\npub const CCryptAttribute: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e202c_217d_11da_b2a4_000e7bbb2b09);\npub const CCryptAttributes: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e202d_217d_11da_b2a4_000e7bbb2b09);\npub const CCspInformation: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2007_217d_11da_b2a4_000e7bbb2b09);\npub const CCspInformations: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2008_217d_11da_b2a4_000e7bbb2b09);\npub const CCspStatus: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2009_217d_11da_b2a4_000e7bbb2b09);\npub const CDR_EXPIRED: CERT_DELETE_ROW_FLAGS = 1i32;\npub const CDR_REQUEST_LAST_CHANGED: CERT_DELETE_ROW_FLAGS = 2i32;\npub type CERTADMIN_GET_ROLES_FLAGS = u32;\npub const CERTENROLL_INDEX_BASE: u32 = 0u32;\npub type CERTENROLL_OBJECTID = i32;\npub type CERTENROLL_PROPERTYID = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CERTTRANSBLOB {\n    pub cb: u32,\n    pub pb: *mut u8,\n}\nimpl Default for CERTTRANSBLOB {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CERTVIEWRESTRICTION {\n    pub ColumnIndex: u32,\n    pub SeekOperator: i32,\n    pub SortOrder: i32,\n    pub pbValue: *mut u8,\n    pub cbValue: u32,\n}\nimpl Default for CERTVIEWRESTRICTION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type CERT_ALT_NAME = i32;\npub const CERT_ALT_NAME_DIRECTORY_NAME: CERT_ALT_NAME = 5i32;\npub const CERT_ALT_NAME_DNS_NAME: CERT_ALT_NAME = 3i32;\npub const CERT_ALT_NAME_IP_ADDRESS: CERT_ALT_NAME = 8i32;\npub const CERT_ALT_NAME_OTHER_NAME: CERT_ALT_NAME = 1i32;\npub const CERT_ALT_NAME_REGISTERED_ID: CERT_ALT_NAME = 9i32;\npub const CERT_ALT_NAME_RFC822_NAME: CERT_ALT_NAME = 2i32;\npub const CERT_ALT_NAME_URL: CERT_ALT_NAME = 7i32;\npub type CERT_CREATE_REQUEST_FLAGS = i32;\npub type CERT_DELETE_ROW_FLAGS = i32;\npub type CERT_EXIT_EVENT_MASK = u32;\npub type CERT_GET_CONFIG_FLAGS = i32;\npub type CERT_IMPORT_FLAGS = i32;\npub type CERT_PROPERTY_TYPE = i32;\npub type CERT_REQUEST_OUT_TYPE = i32;\npub type CERT_VIEW_COLUMN_INDEX = i32;\npub type CERT_VIEW_SEEK_OPERATOR_FLAGS = i32;\npub const CEnroll: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x43f8f289_7a20_11d0_8f06_00c04fc295e1);\npub const CEnroll2: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x127698e4_e730_4e5c_a2b1_21490a70c8a1);\npub const CMM_READONLY: u32 = 2u32;\npub const CMM_REFRESHONLY: u32 = 1u32;\npub const CObjectId: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2000_217d_11da_b2a4_000e7bbb2b09);\npub const CObjectIds: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2001_217d_11da_b2a4_000e7bbb2b09);\npub const CPF_BADURL_ERROR: u32 = 32u32;\npub const CPF_BASE: u32 = 1u32;\npub const CPF_CASTORE_ERROR: u32 = 16u32;\npub const CPF_COMPLETE: u32 = 4u32;\npub const CPF_DELTA: u32 = 2u32;\npub const CPF_FILE_ERROR: u32 = 512u32;\npub const CPF_FTP_ERROR: u32 = 1024u32;\npub const CPF_HTTP_ERROR: u32 = 2048u32;\npub const CPF_LDAP_ERROR: u32 = 256u32;\npub const CPF_MANUAL: u32 = 64u32;\npub const CPF_POSTPONED_BASE_FILE_ERROR: u32 = 8192u32;\npub const CPF_POSTPONED_BASE_LDAP_ERROR: u32 = 4096u32;\npub const CPF_SHADOW: u32 = 8u32;\npub const CPF_SIGNATURE_ERROR: u32 = 128u32;\npub const CPolicyQualifier: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e201c_217d_11da_b2a4_000e7bbb2b09);\npub const CPolicyQualifiers: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e201d_217d_11da_b2a4_000e7bbb2b09);\npub const CRLF_ALLOW_REQUEST_ATTRIBUTE_SUBJECT: u32 = 65536u32;\npub const CRLF_BUILD_ROOTCA_CRLENTRIES_BASEDONKEY: u32 = 2097152u32;\npub const CRLF_CRLNUMBER_CRITICAL: u32 = 4u32;\npub const CRLF_DELETE_EXPIRED_CRLS: u32 = 2u32;\npub const CRLF_DELTA_USE_OLDEST_UNEXPIRED_BASE: u32 = 1u32;\npub const CRLF_DISABLE_CHAIN_VERIFICATION: u32 = 1048576u32;\npub const CRLF_DISABLE_RDN_REORDER: u32 = 2048u32;\npub const CRLF_DISABLE_ROOT_CROSS_CERTS: u32 = 4096u32;\npub const CRLF_ENFORCE_ENROLLMENT_AGENT: u32 = 1024u32;\npub const CRLF_IGNORE_CROSS_CERT_TRUST_ERROR: u32 = 256u32;\npub const CRLF_IGNORE_INVALID_POLICIES: u32 = 16u32;\npub const CRLF_IGNORE_UNKNOWN_CMC_ATTRIBUTES: u32 = 128u32;\npub const CRLF_LOG_FULL_RESPONSE: u32 = 8192u32;\npub const CRLF_PRESERVE_EXPIRED_CA_CERTS: u32 = 262144u32;\npub const CRLF_PRESERVE_REVOKED_CA_CERTS: u32 = 524288u32;\npub const CRLF_PUBLISH_EXPIRED_CERT_CRLS: u32 = 512u32;\npub const CRLF_REBUILD_MODIFIED_SUBJECT_ONLY: u32 = 32u32;\npub const CRLF_REVCHECK_IGNORE_NOREVCHECK: u32 = 131072u32;\npub const CRLF_REVCHECK_IGNORE_OFFLINE: u32 = 8u32;\npub const CRLF_SAVE_FAILED_CERTS: u32 = 64u32;\npub const CRLF_USE_CROSS_CERT_TEMPLATE: u32 = 32768u32;\npub const CRLF_USE_XCHG_CERT_TEMPLATE: u32 = 16384u32;\npub type CRLRevocationReason = i32;\npub const CRYPT_ENUM_ALL_PROVIDERS: u32 = 1u32;\npub type CR_DISP = u32;\npub const CR_DISP_DENIED: CR_DISP = 2u32;\npub const CR_DISP_ERROR: CR_DISP = 1u32;\npub const CR_DISP_INCOMPLETE: CR_DISP = 0u32;\npub const CR_DISP_ISSUED: CR_DISP = 3u32;\npub const CR_DISP_ISSUED_OUT_OF_BAND: CR_DISP = 4u32;\npub const CR_DISP_REVOKED: u32 = 6u32;\npub const CR_DISP_UNDER_SUBMISSION: CR_DISP = 5u32;\npub const CR_FLG_CACROSSCERT: u32 = 128u32;\npub const CR_FLG_CAXCHGCERT: u32 = 8u32;\npub const CR_FLG_CHALLENGEPENDING: u32 = 1024u32;\npub const CR_FLG_CHALLENGESATISFIED: u32 = 2048u32;\npub const CR_FLG_DEFINEDCACERT: u32 = 512u32;\npub const CR_FLG_ENFORCEUTF8: u32 = 256u32;\npub const CR_FLG_ENROLLONBEHALFOF: u32 = 16u32;\npub const CR_FLG_FORCETELETEX: u32 = 1u32;\npub const CR_FLG_FORCEUTF8: u32 = 4u32;\npub const CR_FLG_PUBLISHERROR: u32 = 2147483648u32;\npub const CR_FLG_RENEWAL: u32 = 2u32;\npub const CR_FLG_SUBJECTUNMODIFIED: u32 = 32u32;\npub const CR_FLG_TRUSTEKCERT: u32 = 8192u32;\npub const CR_FLG_TRUSTEKKEY: u32 = 16384u32;\npub const CR_FLG_TRUSTONUSE: u32 = 4096u32;\npub const CR_FLG_VALIDENCRYPTEDKEYHASH: u32 = 64u32;\npub const CR_GEMT_DEFAULT: u32 = 0u32;\npub const CR_GEMT_HRESULT_STRING: u32 = 1u32;\npub const CR_GEMT_HTTP_ERROR: u32 = 2u32;\npub const CR_IN_BASE64: CERT_IMPORT_FLAGS = 1i32;\npub const CR_IN_BASE64HEADER: CERT_IMPORT_FLAGS = 0i32;\npub const CR_IN_BINARY: CERT_IMPORT_FLAGS = 2i32;\npub const CR_IN_CERTIFICATETRANSPARENCY: u32 = 67108864u32;\npub const CR_IN_CHALLENGERESPONSE: u32 = 1280u32;\npub const CR_IN_CLIENTIDNONE: u32 = 4194304u32;\npub const CR_IN_CMC: u32 = 1024u32;\npub const CR_IN_CONNECTONLY: u32 = 8388608u32;\npub const CR_IN_CRLS: u32 = 524288u32;\npub const CR_IN_ENCODEANY: u32 = 255u32;\npub const CR_IN_ENCODEMASK: u32 = 255u32;\npub const CR_IN_FORMATANY: u32 = 0u32;\npub const CR_IN_FORMATMASK: u32 = 65280u32;\npub const CR_IN_FULLRESPONSE: u32 = 262144u32;\npub const CR_IN_HTTP: u32 = 196608u32;\npub const CR_IN_KEYGEN: u32 = 512u32;\npub const CR_IN_MACHINE: u32 = 1048576u32;\npub const CR_IN_PKCS10: u32 = 256u32;\npub const CR_IN_PKCS7: u32 = 768u32;\npub const CR_IN_RETURNCHALLENGE: u32 = 16777216u32;\npub const CR_IN_ROBO: u32 = 2097152u32;\npub const CR_IN_RPC: u32 = 131072u32;\npub const CR_IN_SCEP: u32 = 65536u32;\npub const CR_IN_SCEPPOST: u32 = 33554432u32;\npub const CR_IN_SIGNEDCERTIFICATETIMESTAMPLIST: u32 = 1536u32;\npub const CR_OUT_BASE64: CERT_REQUEST_OUT_TYPE = 1i32;\npub const CR_OUT_BASE64HEADER: CERT_REQUEST_OUT_TYPE = 0i32;\npub const CR_OUT_BASE64REQUESTHEADER: u32 = 3u32;\npub const CR_OUT_BASE64X509CRLHEADER: u32 = 9u32;\npub const CR_OUT_BINARY: CERT_REQUEST_OUT_TYPE = 2i32;\npub const CR_OUT_CHAIN: u32 = 256u32;\npub const CR_OUT_CRLS: u32 = 512u32;\npub const CR_OUT_ENCODEMASK: u32 = 255u32;\npub const CR_OUT_HEX: u32 = 4u32;\npub const CR_OUT_HEXADDR: u32 = 10u32;\npub const CR_OUT_HEXASCII: u32 = 5u32;\npub const CR_OUT_HEXASCIIADDR: u32 = 11u32;\npub const CR_OUT_HEXRAW: u32 = 12u32;\npub const CR_OUT_NOCR: u32 = 2147483648u32;\npub const CR_OUT_NOCRLF: u32 = 1073741824u32;\npub const CR_PROP_ADVANCEDSERVER: u32 = 28u32;\npub const CR_PROP_BASECRL: u32 = 17u32;\npub const CR_PROP_BASECRLPUBLISHSTATUS: u32 = 30u32;\npub const CR_PROP_CABACKWARDCROSSCERT: u32 = 36u32;\npub const CR_PROP_CABACKWARDCROSSCERTSTATE: u32 = 38u32;\npub const CR_PROP_CACERTSTATE: u32 = 19u32;\npub const CR_PROP_CACERTSTATUSCODE: u32 = 34u32;\npub const CR_PROP_CACERTVERSION: u32 = 39u32;\npub const CR_PROP_CAFORWARDCROSSCERT: u32 = 35u32;\npub const CR_PROP_CAFORWARDCROSSCERTSTATE: u32 = 37u32;\npub const CR_PROP_CANAME: u32 = 6u32;\npub const CR_PROP_CAPROPIDMAX: u32 = 21u32;\npub const CR_PROP_CASIGCERT: u32 = 12u32;\npub const CR_PROP_CASIGCERTCHAIN: u32 = 13u32;\npub const CR_PROP_CASIGCERTCOUNT: u32 = 11u32;\npub const CR_PROP_CASIGCERTCRLCHAIN: u32 = 32u32;\npub const CR_PROP_CATYPE: u32 = 10u32;\npub const CR_PROP_CAXCHGCERT: u32 = 15u32;\npub const CR_PROP_CAXCHGCERTCHAIN: u32 = 16u32;\npub const CR_PROP_CAXCHGCERTCOUNT: u32 = 14u32;\npub const CR_PROP_CAXCHGCERTCRLCHAIN: u32 = 33u32;\npub const CR_PROP_CERTAIAOCSPURLS: u32 = 43u32;\npub const CR_PROP_CERTAIAURLS: u32 = 42u32;\npub const CR_PROP_CERTCDPURLS: u32 = 41u32;\npub const CR_PROP_CRLSTATE: u32 = 20u32;\npub const CR_PROP_DELTACRL: u32 = 18u32;\npub const CR_PROP_DELTACRLPUBLISHSTATUS: u32 = 31u32;\npub const CR_PROP_DNSNAME: u32 = 22u32;\npub const CR_PROP_EXITCOUNT: u32 = 3u32;\npub const CR_PROP_EXITDESCRIPTION: u32 = 4u32;\npub const CR_PROP_FILEVERSION: u32 = 1u32;\npub const CR_PROP_KRACERT: u32 = 26u32;\npub const CR_PROP_KRACERTCOUNT: u32 = 25u32;\npub const CR_PROP_KRACERTSTATE: u32 = 27u32;\npub const CR_PROP_KRACERTUSEDCOUNT: u32 = 24u32;\npub const CR_PROP_LOCALENAME: u32 = 44u32;\npub const CR_PROP_NONE: u32 = 0u32;\npub const CR_PROP_PARENTCA: u32 = 9u32;\npub const CR_PROP_POLICYDESCRIPTION: u32 = 5u32;\npub const CR_PROP_PRODUCTVERSION: u32 = 2u32;\npub const CR_PROP_ROLESEPARATIONENABLED: u32 = 23u32;\npub const CR_PROP_SANITIZEDCANAME: u32 = 7u32;\npub const CR_PROP_SANITIZEDCASHORTNAME: u32 = 40u32;\npub const CR_PROP_SCEPMAX: u32 = 1002u32;\npub const CR_PROP_SCEPMIN: u32 = 1000u32;\npub const CR_PROP_SCEPSERVERCAPABILITIES: u32 = 1001u32;\npub const CR_PROP_SCEPSERVERCERTS: u32 = 1000u32;\npub const CR_PROP_SCEPSERVERCERTSCHAIN: u32 = 1002u32;\npub const CR_PROP_SHAREDFOLDER: u32 = 8u32;\npub const CR_PROP_SUBJECTTEMPLATE_OIDS: u32 = 45u32;\npub const CR_PROP_TEMPLATES: u32 = 29u32;\npub const CSBACKUP_DISABLE_INCREMENTAL: u32 = 4294967295u32;\npub type CSBACKUP_TYPE = u32;\npub const CSBACKUP_TYPE_FULL: CSBACKUP_TYPE = 1u32;\npub const CSBACKUP_TYPE_LOGS_ONLY: CSBACKUP_TYPE = 2u32;\npub const CSBACKUP_TYPE_MASK: u32 = 3u32;\npub const CSBFT_DATABASE_DIRECTORY: u32 = 64u32;\npub const CSBFT_DIRECTORY: u32 = 128u32;\npub const CSBFT_LOG_DIRECTORY: u32 = 32u32;\npub const CSCONTROL_RESTART: u64 = 3u64;\npub const CSCONTROL_SHUTDOWN: u64 = 1u64;\npub const CSCONTROL_SUSPEND: u64 = 2u64;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CSEDB_RSTMAPW {\n    pub pwszDatabaseName: windows_sys::core::PWSTR,\n    pub pwszNewDatabaseName: windows_sys::core::PWSTR,\n}\nimpl Default for CSEDB_RSTMAPW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CSRESTORE_TYPE_CATCHUP: u32 = 4u32;\npub const CSRESTORE_TYPE_FULL: u32 = 1u32;\npub const CSRESTORE_TYPE_MASK: u32 = 5u32;\npub const CSRESTORE_TYPE_ONLINE: u32 = 2u32;\npub const CSURL_ADDTOCERTCDP: u32 = 2u32;\npub const CSURL_ADDTOCERTOCSP: u32 = 32u32;\npub const CSURL_ADDTOCRLCDP: u32 = 8u32;\npub const CSURL_ADDTOFRESHESTCRL: u32 = 4u32;\npub const CSURL_ADDTOIDP: u32 = 128u32;\npub const CSURL_PUBLISHRETRY: u32 = 16u32;\npub const CSURL_SERVERPUBLISH: u32 = 1u32;\npub const CSURL_SERVERPUBLISHDELTA: u32 = 64u32;\npub const CSVER_MAJOR: u32 = 7u32;\npub const CSVER_MAJOR_LONGHORN: u32 = 3u32;\npub const CSVER_MAJOR_THRESHOLD: u32 = 7u32;\npub const CSVER_MAJOR_WHISTLER: u32 = 2u32;\npub const CSVER_MAJOR_WIN2K: u32 = 1u32;\npub const CSVER_MAJOR_WIN7: u32 = 4u32;\npub const CSVER_MAJOR_WIN8: u32 = 5u32;\npub const CSVER_MAJOR_WINBLUE: u32 = 6u32;\npub const CSVER_MINOR: u32 = 1u32;\npub const CSVER_MINOR_LONGHORN_BETA1: u32 = 1u32;\npub const CSVER_MINOR_THRESHOLD: u32 = 1u32;\npub const CSVER_MINOR_WHISTLER_BETA2: u32 = 1u32;\npub const CSVER_MINOR_WHISTLER_BETA3: u32 = 2u32;\npub const CSVER_MINOR_WIN2K: u32 = 1u32;\npub const CSVER_MINOR_WIN7: u32 = 1u32;\npub const CSVER_MINOR_WIN8: u32 = 1u32;\npub const CSVER_MINOR_WINBLUE: u32 = 1u32;\npub const CSignerCertificate: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e203d_217d_11da_b2a4_000e7bbb2b09);\npub const CSmimeCapabilities: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e201a_217d_11da_b2a4_000e7bbb2b09);\npub const CSmimeCapability: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2019_217d_11da_b2a4_000e7bbb2b09);\npub const CVIEWAGEMINUTESDEFAULT: u32 = 16u32;\npub type CVRC_COLUMN = i32;\npub const CVRC_COLUMN_MASK: CVRC_COLUMN = 4095i32;\npub const CVRC_COLUMN_RESULT: CVRC_COLUMN = 1i32;\npub const CVRC_COLUMN_SCHEMA: CVRC_COLUMN = 0i32;\npub const CVRC_COLUMN_VALUE: CVRC_COLUMN = 2i32;\npub type CVRC_TABLE = i32;\npub const CVRC_TABLE_ATTRIBUTES: CVRC_TABLE = 16384i32;\npub const CVRC_TABLE_CRL: CVRC_TABLE = 20480i32;\npub const CVRC_TABLE_EXTENSIONS: CVRC_TABLE = 12288i32;\npub const CVRC_TABLE_MASK: u32 = 61440u32;\npub const CVRC_TABLE_REQCERT: CVRC_TABLE = 0i32;\npub const CVRC_TABLE_SHIFT: u32 = 12u32;\npub const CVR_SEEK_EQ: CERT_VIEW_SEEK_OPERATOR_FLAGS = 1i32;\npub const CVR_SEEK_GE: CERT_VIEW_SEEK_OPERATOR_FLAGS = 8i32;\npub const CVR_SEEK_GT: CERT_VIEW_SEEK_OPERATOR_FLAGS = 16i32;\npub const CVR_SEEK_LE: CERT_VIEW_SEEK_OPERATOR_FLAGS = 4i32;\npub const CVR_SEEK_LT: CERT_VIEW_SEEK_OPERATOR_FLAGS = 2i32;\npub const CVR_SEEK_MASK: u32 = 255u32;\npub const CVR_SEEK_NODELTA: u32 = 4096u32;\npub const CVR_SEEK_NONE: u32 = 0u32;\npub const CVR_SORT_ASCEND: u32 = 1u32;\npub const CVR_SORT_DESCEND: u32 = 2u32;\npub const CVR_SORT_NONE: u32 = 0u32;\npub const CV_COLUMN_ATTRIBUTE_DEFAULT: i32 = -5i32;\npub const CV_COLUMN_CRL_DEFAULT: i32 = -6i32;\npub const CV_COLUMN_EXTENSION_DEFAULT: i32 = -4i32;\npub const CV_COLUMN_LOG_DEFAULT: CERT_VIEW_COLUMN_INDEX = -2i32;\npub const CV_COLUMN_LOG_FAILED_DEFAULT: CERT_VIEW_COLUMN_INDEX = -3i32;\npub const CV_COLUMN_LOG_REVOKED_DEFAULT: i32 = -7i32;\npub const CV_COLUMN_QUEUE_DEFAULT: CERT_VIEW_COLUMN_INDEX = -1i32;\npub const CV_OUT_BASE64: ENUM_CERT_COLUMN_VALUE_FLAGS = 1i32;\npub const CV_OUT_BASE64HEADER: ENUM_CERT_COLUMN_VALUE_FLAGS = 0i32;\npub const CV_OUT_BASE64REQUESTHEADER: ENUM_CERT_COLUMN_VALUE_FLAGS = 3i32;\npub const CV_OUT_BASE64X509CRLHEADER: ENUM_CERT_COLUMN_VALUE_FLAGS = 9i32;\npub const CV_OUT_BINARY: ENUM_CERT_COLUMN_VALUE_FLAGS = 2i32;\npub const CV_OUT_ENCODEMASK: u32 = 255u32;\npub const CV_OUT_HEX: ENUM_CERT_COLUMN_VALUE_FLAGS = 4i32;\npub const CV_OUT_HEXADDR: ENUM_CERT_COLUMN_VALUE_FLAGS = 10i32;\npub const CV_OUT_HEXASCII: ENUM_CERT_COLUMN_VALUE_FLAGS = 5i32;\npub const CV_OUT_HEXASCIIADDR: ENUM_CERT_COLUMN_VALUE_FLAGS = 11i32;\npub const CV_OUT_HEXRAW: u32 = 12u32;\npub const CV_OUT_NOCR: u32 = 2147483648u32;\npub const CV_OUT_NOCRLF: u32 = 1073741824u32;\npub const CX500DistinguishedName: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2003_217d_11da_b2a4_000e7bbb2b09);\npub const CX509Attribute: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2022_217d_11da_b2a4_000e7bbb2b09);\npub const CX509AttributeArchiveKey: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2027_217d_11da_b2a4_000e7bbb2b09);\npub const CX509AttributeArchiveKeyHash: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2028_217d_11da_b2a4_000e7bbb2b09);\npub const CX509AttributeClientId: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2025_217d_11da_b2a4_000e7bbb2b09);\npub const CX509AttributeCspProvider: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e202b_217d_11da_b2a4_000e7bbb2b09);\npub const CX509AttributeExtensions: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2024_217d_11da_b2a4_000e7bbb2b09);\npub const CX509AttributeOSVersion: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e202a_217d_11da_b2a4_000e7bbb2b09);\npub const CX509AttributeRenewalCertificate: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2026_217d_11da_b2a4_000e7bbb2b09);\npub const CX509Attributes: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2023_217d_11da_b2a4_000e7bbb2b09);\npub const CX509CertificateRequestCertificate: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2043_217d_11da_b2a4_000e7bbb2b09);\npub const CX509CertificateRequestCmc: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2045_217d_11da_b2a4_000e7bbb2b09);\npub const CX509CertificateRequestPkcs10: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2042_217d_11da_b2a4_000e7bbb2b09);\npub const CX509CertificateRequestPkcs7: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2044_217d_11da_b2a4_000e7bbb2b09);\npub const CX509CertificateRevocationList: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2060_217d_11da_b2a4_000e7bbb2b09);\npub const CX509CertificateRevocationListEntries: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e205f_217d_11da_b2a4_000e7bbb2b09);\npub const CX509CertificateRevocationListEntry: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e205e_217d_11da_b2a4_000e7bbb2b09);\npub const CX509CertificateTemplateADWritable: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x8336e323_2e6a_4a04_937c_548f681839b3);\npub const CX509EndorsementKey: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x11a25a1d_b9a3_4edd_af83_3b59adbed361);\npub const CX509Enrollment: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2046_217d_11da_b2a4_000e7bbb2b09);\npub const CX509EnrollmentHelper: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2050_217d_11da_b2a4_000e7bbb2b09);\npub const CX509EnrollmentPolicyActiveDirectory: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x91f39027_217f_11da_b2a4_000e7bbb2b09);\npub const CX509EnrollmentPolicyWebService: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x91f39028_217f_11da_b2a4_000e7bbb2b09);\npub const CX509EnrollmentWebClassFactory: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2049_217d_11da_b2a4_000e7bbb2b09);\npub const CX509Extension: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e200d_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionAlternativeNames: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2015_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionAuthorityKeyIdentifier: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2018_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionBasicConstraints: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2016_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionCertificatePolicies: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2020_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionEnhancedKeyUsage: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2010_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionKeyUsage: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e200f_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionMSApplicationPolicies: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2021_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionSmimeCapabilities: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e201b_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionSubjectKeyIdentifier: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2017_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionTemplate: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2012_217d_11da_b2a4_000e7bbb2b09);\npub const CX509ExtensionTemplateName: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2011_217d_11da_b2a4_000e7bbb2b09);\npub const CX509Extensions: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e200e_217d_11da_b2a4_000e7bbb2b09);\npub const CX509MachineEnrollmentFactory: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2051_217d_11da_b2a4_000e7bbb2b09);\npub const CX509NameValuePair: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e203f_217d_11da_b2a4_000e7bbb2b09);\npub const CX509PolicyServerListManager: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x91f39029_217f_11da_b2a4_000e7bbb2b09);\npub const CX509PolicyServerUrl: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x91f3902a_217f_11da_b2a4_000e7bbb2b09);\npub const CX509PrivateKey: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e200c_217d_11da_b2a4_000e7bbb2b09);\npub const CX509PublicKey: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e200b_217d_11da_b2a4_000e7bbb2b09);\npub const CX509SCEPEnrollment: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2061_217d_11da_b2a4_000e7bbb2b09);\npub const CX509SCEPEnrollmentHelper: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x884e2062_217d_11da_b2a4_000e7bbb2b09);\npub const ClientIdAutoEnroll: RequestClientInfoClientId = 6i32;\npub const ClientIdAutoEnroll2003: RequestClientInfoClientId = 2i32;\npub const ClientIdCertReq: RequestClientInfoClientId = 9i32;\npub const ClientIdCertReq2003: RequestClientInfoClientId = 4i32;\npub const ClientIdDefaultRequest: RequestClientInfoClientId = 5i32;\npub const ClientIdEOBO: RequestClientInfoClientId = 8i32;\npub const ClientIdNone: RequestClientInfoClientId = 0i32;\npub const ClientIdRequestWizard: RequestClientInfoClientId = 7i32;\npub const ClientIdTest: RequestClientInfoClientId = 10i32;\npub const ClientIdUserStart: RequestClientInfoClientId = 1000i32;\npub const ClientIdWinRT: RequestClientInfoClientId = 11i32;\npub const ClientIdWizard2003: RequestClientInfoClientId = 3i32;\npub const ClientIdXEnroll2003: RequestClientInfoClientId = 1i32;\npub const CommitFlagDeleteTemplate: CommitTemplateFlags = 4i32;\npub const CommitFlagSaveTemplateGenerateOID: CommitTemplateFlags = 1i32;\npub const CommitFlagSaveTemplateOverwrite: CommitTemplateFlags = 3i32;\npub const CommitFlagSaveTemplateUseCurrentOID: CommitTemplateFlags = 2i32;\npub type CommitTemplateFlags = i32;\npub const ContextAdministratorForceMachine: X509CertificateEnrollmentContext = 3i32;\npub const ContextMachine: X509CertificateEnrollmentContext = 2i32;\npub const ContextNone: X509CertificateEnrollmentContext = 0i32;\npub const ContextUser: X509CertificateEnrollmentContext = 1i32;\npub const DBFLAGS_CHECKPOINTDEPTH60MB: u32 = 32u32;\npub const DBFLAGS_CIRCULARLOGGING: u32 = 4u32;\npub const DBFLAGS_CREATEIFNEEDED: u32 = 2u32;\npub const DBFLAGS_DISABLESNAPSHOTBACKUP: u32 = 1024u32;\npub const DBFLAGS_ENABLEVOLATILEREQUESTS: u32 = 2048u32;\npub const DBFLAGS_LAZYFLUSH: u32 = 8u32;\npub const DBFLAGS_LOGBUFFERSHUGE: u32 = 128u32;\npub const DBFLAGS_LOGBUFFERSLARGE: u32 = 64u32;\npub const DBFLAGS_LOGFILESIZE16MB: u32 = 256u32;\npub const DBFLAGS_MAXCACHESIZEX100: u32 = 16u32;\npub const DBFLAGS_MULTITHREADTRANSACTIONS: u32 = 512u32;\npub const DBFLAGS_READONLY: u32 = 1u32;\npub const DBG_CERTSRV: u32 = 1u32;\npub const DBSESSIONCOUNTDEFAULT: u32 = 100u32;\npub const DB_DISP_ACTIVE: u32 = 8u32;\npub const DB_DISP_CA_CERT: u32 = 15u32;\npub const DB_DISP_CA_CERT_CHAIN: u32 = 16u32;\npub const DB_DISP_DENIED: u32 = 31u32;\npub const DB_DISP_ERROR: u32 = 30u32;\npub const DB_DISP_FOREIGN: u32 = 12u32;\npub const DB_DISP_ISSUED: u32 = 20u32;\npub const DB_DISP_KRA_CERT: u32 = 17u32;\npub const DB_DISP_LOG_FAILED_MIN: u32 = 30u32;\npub const DB_DISP_LOG_MIN: u32 = 20u32;\npub const DB_DISP_PENDING: u32 = 9u32;\npub const DB_DISP_QUEUE_MAX: u32 = 9u32;\npub const DB_DISP_REVOKED: u32 = 21u32;\npub const DefaultNone: EnrollmentPolicyServerPropertyFlags = 0i32;\npub const DefaultPolicyServer: EnrollmentPolicyServerPropertyFlags = 1i32;\npub type DelayRetryAction = i32;\npub const DelayRetryLong: DelayRetryAction = 3i32;\npub const DelayRetryNone: DelayRetryAction = 1i32;\npub const DelayRetryPastSuccess: DelayRetryAction = 5i32;\npub const DelayRetryShort: DelayRetryAction = 2i32;\npub const DelayRetrySuccess: DelayRetryAction = 4i32;\npub const DelayRetryUnknown: DelayRetryAction = 0i32;\npub const DisableGroupPolicyList: EnrollmentPolicyFlags = 2i32;\npub const DisableUserServerList: EnrollmentPolicyFlags = 4i32;\npub const DisplayNo: EnrollmentDisplayStatus = 0i32;\npub const DisplayYes: EnrollmentDisplayStatus = 1i32;\npub const EANR_SUPPRESS_IA5CONVERSION: u32 = 2147483648u32;\npub const EAN_NAMEOBJECTID: u32 = 2147483648u32;\npub const EDITF_ADDOLDCERTTYPE: u32 = 16u32;\npub const EDITF_ADDOLDKEYUSAGE: u32 = 8u32;\npub const EDITF_ATTRIBUTECA: u32 = 512u32;\npub const EDITF_ATTRIBUTEEKU: u32 = 32768u32;\npub const EDITF_ATTRIBUTEENDDATE: u32 = 32u32;\npub const EDITF_ATTRIBUTESUBJECTALTNAME2: u32 = 262144u32;\npub const EDITF_AUDITCERTTEMPLATELOAD: u32 = 2097152u32;\npub const EDITF_BASICCONSTRAINTSCA: u32 = 128u32;\npub const EDITF_BASICCONSTRAINTSCRITICAL: u32 = 64u32;\npub const EDITF_DISABLEEXTENSIONLIST: u32 = 4u32;\npub const EDITF_DISABLELDAPPACKAGELIST: u32 = 8388608u32;\npub const EDITF_DISABLEOLDOSCNUPN: u32 = 4194304u32;\npub const EDITF_EMAILOPTIONAL: u32 = 131072u32;\npub const EDITF_ENABLEAKICRITICAL: u32 = 8192u32;\npub const EDITF_ENABLEAKIISSUERNAME: u32 = 2048u32;\npub const EDITF_ENABLEAKIISSUERSERIAL: u32 = 4096u32;\npub const EDITF_ENABLEAKIKEYID: u32 = 256u32;\npub const EDITF_ENABLECHASECLIENTDC: u32 = 1048576u32;\npub const EDITF_ENABLEDEFAULTSMIME: u32 = 65536u32;\npub const EDITF_ENABLEKEYENCIPHERMENTCACERT: u32 = 134217728u32;\npub const EDITF_ENABLELDAPREFERRALS: u32 = 524288u32;\npub const EDITF_ENABLEOCSPREVNOCHECK: u32 = 33554432u32;\npub const EDITF_ENABLERENEWONBEHALFOF: u32 = 67108864u32;\npub const EDITF_ENABLEREQUESTEXTENSIONS: u32 = 1u32;\npub const EDITF_ENABLEUPNMAP: u32 = 16777216u32;\npub const EDITF_IGNOREREQUESTERGROUP: u32 = 1024u32;\npub const EDITF_REQUESTEXTENSIONLIST: u32 = 2u32;\npub const EDITF_SERVERUPGRADED: u32 = 16384u32;\npub const ENUMEXT_OBJECTID: u32 = 1u32;\npub type ENUM_CATYPES = i32;\npub type ENUM_CERT_COLUMN_VALUE_FLAGS = i32;\npub const ENUM_ENTERPRISE_ROOTCA: ENUM_CATYPES = 0i32;\npub const ENUM_ENTERPRISE_SUBCA: ENUM_CATYPES = 1i32;\npub const ENUM_STANDALONE_ROOTCA: ENUM_CATYPES = 3i32;\npub const ENUM_STANDALONE_SUBCA: ENUM_CATYPES = 4i32;\npub const ENUM_UNKNOWN_CA: ENUM_CATYPES = 5i32;\npub const EXITEVENT_CERTDENIED: CERT_EXIT_EVENT_MASK = 4u32;\npub const EXITEVENT_CERTIMPORTED: u32 = 512u32;\npub const EXITEVENT_CERTISSUED: CERT_EXIT_EVENT_MASK = 1u32;\npub const EXITEVENT_CERTPENDING: CERT_EXIT_EVENT_MASK = 2u32;\npub const EXITEVENT_CERTRETRIEVEPENDING: CERT_EXIT_EVENT_MASK = 16u32;\npub const EXITEVENT_CERTREVOKED: CERT_EXIT_EVENT_MASK = 8u32;\npub const EXITEVENT_CRLISSUED: CERT_EXIT_EVENT_MASK = 32u32;\npub const EXITEVENT_INVALID: u32 = 0u32;\npub const EXITEVENT_SHUTDOWN: CERT_EXIT_EVENT_MASK = 64u32;\npub const EXITEVENT_STARTUP: u32 = 128u32;\npub const EXITPUB_ACTIVEDIRECTORY: u32 = 2u32;\npub const EXITPUB_DEFAULT_ENTERPRISE: u32 = 2u32;\npub const EXITPUB_DEFAULT_STANDALONE: u32 = 1u32;\npub const EXITPUB_FILE: u32 = 1u32;\npub const EXITPUB_REMOVEOLDCERTS: u32 = 16u32;\npub const EXTENSION_CRITICAL_FLAG: u32 = 1u32;\npub const EXTENSION_DELETE_FLAG: u32 = 4u32;\npub const EXTENSION_DISABLE_FLAG: u32 = 2u32;\npub const EXTENSION_ORIGIN_ADMIN: u32 = 196608u32;\npub const EXTENSION_ORIGIN_CACERT: u32 = 589824u32;\npub const EXTENSION_ORIGIN_CMC: u32 = 524288u32;\npub const EXTENSION_ORIGIN_IMPORTEDCERT: u32 = 393216u32;\npub const EXTENSION_ORIGIN_MASK: u32 = 983040u32;\npub const EXTENSION_ORIGIN_PKCS7: u32 = 458752u32;\npub const EXTENSION_ORIGIN_POLICY: u32 = 131072u32;\npub const EXTENSION_ORIGIN_RENEWALCERT: u32 = 327680u32;\npub const EXTENSION_ORIGIN_REQUEST: u32 = 65536u32;\npub const EXTENSION_ORIGIN_SERVER: u32 = 262144u32;\npub const EXTENSION_POLICY_MASK: u32 = 65535u32;\npub type EncodingType = i32;\npub const EnrollDenied: EnrollmentEnrollStatus = 256i32;\npub const EnrollError: EnrollmentEnrollStatus = 16i32;\npub const EnrollPended: EnrollmentEnrollStatus = 2i32;\npub const EnrollPrompt: WebEnrollmentFlags = 1i32;\npub const EnrollSkipped: EnrollmentEnrollStatus = 64i32;\npub const EnrollUIDeferredEnrollmentRequired: EnrollmentEnrollStatus = 4i32;\npub const EnrollUnknown: EnrollmentEnrollStatus = 32i32;\npub const Enrolled: EnrollmentEnrollStatus = 1i32;\npub const EnrollmentAddOCSPNoCheck: X509CertificateTemplateEnrollmentFlag = 4096i32;\npub const EnrollmentAddTemplateName: X509CertificateTemplateEnrollmentFlag = 512i32;\npub const EnrollmentAllowEnrollOnBehalfOf: X509CertificateTemplateEnrollmentFlag = 2048i32;\npub const EnrollmentAutoEnrollment: X509CertificateTemplateEnrollmentFlag = 32i32;\npub const EnrollmentAutoEnrollmentCheckUserDSCertificate: X509CertificateTemplateEnrollmentFlag = 16i32;\npub type EnrollmentCAProperty = i32;\npub const EnrollmentCertificateIssuancePoliciesFromRequest: X509CertificateTemplateEnrollmentFlag = 131072i32;\npub type EnrollmentDisplayStatus = i32;\npub const EnrollmentDomainAuthenticationNotRequired: X509CertificateTemplateEnrollmentFlag = 128i32;\npub type EnrollmentEnrollStatus = i32;\npub const EnrollmentIncludeBasicConstraintsForEECerts: X509CertificateTemplateEnrollmentFlag = 32768i32;\npub const EnrollmentIncludeSymmetricAlgorithms: X509CertificateTemplateEnrollmentFlag = 1i32;\npub const EnrollmentNoRevocationInfoInCerts: X509CertificateTemplateEnrollmentFlag = 16384i32;\npub const EnrollmentPendAllRequests: X509CertificateTemplateEnrollmentFlag = 2i32;\npub type EnrollmentPolicyFlags = i32;\npub type EnrollmentPolicyServerPropertyFlags = i32;\npub const EnrollmentPreviousApprovalKeyBasedValidateReenrollment: X509CertificateTemplateEnrollmentFlag = 65536i32;\npub const EnrollmentPreviousApprovalValidateReenrollment: X509CertificateTemplateEnrollmentFlag = 64i32;\npub const EnrollmentPublishToDS: X509CertificateTemplateEnrollmentFlag = 8i32;\npub const EnrollmentPublishToKRAContainer: X509CertificateTemplateEnrollmentFlag = 4i32;\npub const EnrollmentRemoveInvalidCertificateFromPersonalStore: X509CertificateTemplateEnrollmentFlag = 1024i32;\npub const EnrollmentReuseKeyOnFullSmartCard: X509CertificateTemplateEnrollmentFlag = 8192i32;\npub type EnrollmentSelectionStatus = i32;\npub const EnrollmentSkipAutoRenewal: X509CertificateTemplateEnrollmentFlag = 262144i32;\npub type EnrollmentTemplateProperty = i32;\npub const EnrollmentUserInteractionRequired: X509CertificateTemplateEnrollmentFlag = 256i32;\npub const ExportCAs: X509EnrollmentPolicyExportFlags = 4i32;\npub const ExportOIDs: X509EnrollmentPolicyExportFlags = 2i32;\npub const ExportTemplates: X509EnrollmentPolicyExportFlags = 1i32;\npub type FNCERTSRVBACKUPCLOSE = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVBACKUPEND = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVBACKUPFREE = Option<unsafe extern \"system\" fn(pv: *mut core::ffi::c_void)>;\npub type FNCERTSRVBACKUPGETBACKUPLOGSW = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void, ppwszzbackuplogfiles: *mut *mut u16, pcbsize: *mut u32) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVBACKUPGETDATABASENAMESW = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void, ppwszzattachmentinformation: *mut *mut u16, pcbsize: *mut u32) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVBACKUPGETDYNAMICFILELISTW = Option<unsafe extern \"system\" fn(hbc: *const core::ffi::c_void, ppwszzfilelist: *mut *mut u16, pcbsize: *mut u32) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVBACKUPOPENFILEW = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void, pwszattachmentname: windows_sys::core::PCWSTR, cbreadhintsize: u32, plifilesize: *mut i64) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVBACKUPPREPAREW = Option<unsafe extern \"system\" fn(pwszservername: windows_sys::core::PCWSTR, grbitjet: u32, dwbackupflags: u32, phbc: *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVBACKUPREAD = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void, pvbuffer: *mut core::ffi::c_void, cbbuffer: u32, pcbread: *mut u32) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVBACKUPTRUNCATELOGS = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVISSERVERONLINEW = Option<unsafe extern \"system\" fn(pwszservername: windows_sys::core::PCWSTR, pfserveronline: *mut windows_sys::core::BOOL) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVRESTOREEND = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVRESTOREGETDATABASELOCATIONSW = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void, ppwszzdatabaselocationlist: *mut *mut u16, pcbsize: *mut u32) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVRESTOREPREPAREW = Option<unsafe extern \"system\" fn(pwszservername: windows_sys::core::PCWSTR, dwrestoreflags: u32, phbc: *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVRESTOREREGISTERCOMPLETE = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void, hrrestorestate: windows_sys::core::HRESULT) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVRESTOREREGISTERW = Option<unsafe extern \"system\" fn(hbc: *mut core::ffi::c_void, pwszcheckpointfilepath: windows_sys::core::PCWSTR, pwszlogpath: windows_sys::core::PCWSTR, rgrstmap: *mut CSEDB_RSTMAPW, crstmap: i32, pwszbackuplogpath: windows_sys::core::PCWSTR, genlow: u32, genhigh: u32) -> windows_sys::core::HRESULT>;\npub type FNCERTSRVSERVERCONTROLW = Option<unsafe extern \"system\" fn(pwszservername: windows_sys::core::PCWSTR, dwcontrolflags: u32, pcbout: *mut u32, ppbout: *mut *mut u8) -> windows_sys::core::HRESULT>;\npub type FNIMPORTPFXTOPROVIDER = Option<unsafe extern \"system\" fn(hwndparent: super::super::super::Foundation::HWND, pbpfx: *const u8, cbpfx: u32, importflags: ImportPFXFlags, pwszpassword: windows_sys::core::PCWSTR, pwszprovidername: windows_sys::core::PCWSTR, pwszreadername: windows_sys::core::PCWSTR, pwszcontainernameprefix: windows_sys::core::PCWSTR, pwszpin: windows_sys::core::PCWSTR, pwszfriendlyname: windows_sys::core::PCWSTR, pccertout: *mut u32, prgpcertout: *mut *mut *mut super::CERT_CONTEXT) -> windows_sys::core::HRESULT>;\npub type FNIMPORTPFXTOPROVIDERFREEDATA = Option<unsafe extern \"system\" fn(ccert: u32, rgpcert: *const *const super::CERT_CONTEXT)>;\npub const FR_PROP_ATTESTATIONCHALLENGE: FULL_RESPONSE_PROPERTY_ID = 20i32;\npub const FR_PROP_ATTESTATIONPROVIDERNAME: FULL_RESPONSE_PROPERTY_ID = 21i32;\npub const FR_PROP_BODYPARTSTRING: FULL_RESPONSE_PROPERTY_ID = 3i32;\npub const FR_PROP_CAEXCHANGECERTIFICATE: FULL_RESPONSE_PROPERTY_ID = 17i32;\npub const FR_PROP_CAEXCHANGECERTIFICATECHAIN: FULL_RESPONSE_PROPERTY_ID = 18i32;\npub const FR_PROP_CAEXCHANGECERTIFICATECRLCHAIN: FULL_RESPONSE_PROPERTY_ID = 19i32;\npub const FR_PROP_CAEXCHANGECERTIFICATEHASH: FULL_RESPONSE_PROPERTY_ID = 16i32;\npub const FR_PROP_CLAIMCHALLENGE: u32 = 22u32;\npub const FR_PROP_ENCRYPTEDKEYHASH: FULL_RESPONSE_PROPERTY_ID = 14i32;\npub const FR_PROP_FAILINFO: FULL_RESPONSE_PROPERTY_ID = 7i32;\npub const FR_PROP_FULLRESPONSE: FULL_RESPONSE_PROPERTY_ID = 1i32;\npub const FR_PROP_FULLRESPONSENOPKCS7: FULL_RESPONSE_PROPERTY_ID = 15i32;\npub const FR_PROP_ISSUEDCERTIFICATE: FULL_RESPONSE_PROPERTY_ID = 11i32;\npub const FR_PROP_ISSUEDCERTIFICATECHAIN: FULL_RESPONSE_PROPERTY_ID = 12i32;\npub const FR_PROP_ISSUEDCERTIFICATECRLCHAIN: FULL_RESPONSE_PROPERTY_ID = 13i32;\npub const FR_PROP_ISSUEDCERTIFICATEHASH: FULL_RESPONSE_PROPERTY_ID = 10i32;\npub const FR_PROP_NONE: FULL_RESPONSE_PROPERTY_ID = 0i32;\npub const FR_PROP_OTHERINFOCHOICE: FULL_RESPONSE_PROPERTY_ID = 6i32;\npub const FR_PROP_PENDINFOTIME: FULL_RESPONSE_PROPERTY_ID = 9i32;\npub const FR_PROP_PENDINFOTOKEN: FULL_RESPONSE_PROPERTY_ID = 8i32;\npub const FR_PROP_STATUS: FULL_RESPONSE_PROPERTY_ID = 4i32;\npub const FR_PROP_STATUSINFOCOUNT: FULL_RESPONSE_PROPERTY_ID = 2i32;\npub const FR_PROP_STATUSSTRING: FULL_RESPONSE_PROPERTY_ID = 5i32;\npub type FULL_RESPONSE_PROPERTY_ID = i32;\npub const GeneralCA: X509CertificateTemplateGeneralFlag = 128i32;\npub const GeneralCrossCA: X509CertificateTemplateGeneralFlag = 2048i32;\npub const GeneralDefault: X509CertificateTemplateGeneralFlag = 65536i32;\npub const GeneralDonotPersist: X509CertificateTemplateGeneralFlag = 4096i32;\npub const GeneralMachineType: X509CertificateTemplateGeneralFlag = 64i32;\npub const GeneralModified: X509CertificateTemplateGeneralFlag = 131072i32;\npub const ICF_ALLOWFOREIGN: u32 = 65536u32;\npub const ICF_EXISTINGROW: u32 = 131072u32;\npub const IF_ENABLEADMINASAUDITOR: u32 = 4096u32;\npub const IF_ENABLEEXITKEYRETRIEVAL: u32 = 2048u32;\npub const IF_ENFORCEENCRYPTICERTADMIN: u32 = 1024u32;\npub const IF_ENFORCEENCRYPTICERTREQUEST: u32 = 512u32;\npub const IF_LOCKICERTREQUEST: u32 = 1u32;\npub const IF_NOLOCALICERTADMIN: u32 = 32u32;\npub const IF_NOLOCALICERTADMINBACKUP: u32 = 128u32;\npub const IF_NOLOCALICERTREQUEST: u32 = 4u32;\npub const IF_NOREMOTEICERTADMIN: u32 = 16u32;\npub const IF_NOREMOTEICERTADMINBACKUP: u32 = 64u32;\npub const IF_NOREMOTEICERTREQUEST: u32 = 2u32;\npub const IF_NORPCICERTREQUEST: u32 = 8u32;\npub const IF_NOSNAPSHOTBACKUP: u32 = 256u32;\npub const IKF_OVERWRITE: u32 = 65536u32;\npub const ISSCERT_DEFAULT_DS: u32 = 256u32;\npub const ISSCERT_DEFAULT_NODS: u32 = 256u32;\npub const ISSCERT_ENABLE: u32 = 256u32;\npub const ISSCERT_FILEURL_OLD: u32 = 8u32;\npub const ISSCERT_FTPURL_OLD: u32 = 4u32;\npub const ISSCERT_HTTPURL_OLD: u32 = 2u32;\npub const ISSCERT_LDAPURL_OLD: u32 = 1u32;\npub const ISSCERT_URLMASK_OLD: u32 = 255u32;\npub const ImportExportable: ImportPFXFlags = 16i32;\npub const ImportExportableEncrypted: ImportPFXFlags = 32i32;\npub const ImportForceOverwrite: ImportPFXFlags = 2i32;\npub const ImportInstallCertificate: ImportPFXFlags = 512i32;\npub const ImportInstallChain: ImportPFXFlags = 1024i32;\npub const ImportInstallChainAndRoot: ImportPFXFlags = 2048i32;\npub const ImportMachineContext: ImportPFXFlags = 1i32;\npub const ImportNoUserProtected: ImportPFXFlags = 64i32;\npub const ImportNone: ImportPFXFlags = 0i32;\npub type ImportPFXFlags = i32;\npub const ImportSaveProperties: ImportPFXFlags = 8i32;\npub const ImportSilent: ImportPFXFlags = 4i32;\npub const ImportUserProtected: ImportPFXFlags = 128i32;\npub const ImportUserProtectedHigh: ImportPFXFlags = 256i32;\npub const InheritDefault: X509RequestInheritOptions = 0i32;\npub const InheritExtensionsFlag: X509RequestInheritOptions = 256i32;\npub const InheritKeyMask: X509RequestInheritOptions = 15i32;\npub const InheritNewDefaultKey: X509RequestInheritOptions = 1i32;\npub const InheritNewSimilarKey: X509RequestInheritOptions = 2i32;\npub const InheritNone: X509RequestInheritOptions = 16i32;\npub const InheritPrivateKey: X509RequestInheritOptions = 3i32;\npub const InheritPublicKey: X509RequestInheritOptions = 4i32;\npub const InheritRenewalCertificateFlag: X509RequestInheritOptions = 32i32;\npub const InheritReserved80000000: X509RequestInheritOptions = -2147483648i32;\npub const InheritSubjectAltNameFlag: X509RequestInheritOptions = 512i32;\npub const InheritSubjectFlag: X509RequestInheritOptions = 128i32;\npub const InheritTemplateFlag: X509RequestInheritOptions = 64i32;\npub const InheritValidityPeriodFlag: X509RequestInheritOptions = 1024i32;\npub type InnerRequestLevel = i32;\npub type InstallResponseRestrictionFlags = i32;\npub const KRAF_DISABLEUSEDEFAULTPROVIDER: u32 = 8u32;\npub const KRAF_ENABLEARCHIVEALL: u32 = 4u32;\npub const KRAF_ENABLEFOREIGN: u32 = 1u32;\npub const KRAF_SAVEBADREQUESTKEY: u32 = 2u32;\npub const KRA_DISP_EXPIRED: u32 = 0u32;\npub const KRA_DISP_INVALID: u32 = 4u32;\npub const KRA_DISP_NOTFOUND: u32 = 1u32;\npub const KRA_DISP_NOTLOADED: u32 = 6u32;\npub const KRA_DISP_REVOKED: u32 = 2u32;\npub const KRA_DISP_UNTRUSTED: u32 = 5u32;\npub const KRA_DISP_VALID: u32 = 3u32;\npub const KR_ENABLE_MACHINE: u32 = 1u32;\npub const KR_ENABLE_USER: u32 = 2u32;\npub type KeyAttestationClaimType = i32;\npub type KeyIdentifierHashAlgorithm = i32;\npub const LDAPF_SIGNDISABLE: u32 = 2u32;\npub const LDAPF_SSLENABLE: u32 = 1u32;\npub const LevelInnermost: InnerRequestLevel = 0i32;\npub const LevelNext: InnerRequestLevel = 1i32;\npub const LevelSafe: WebSecurityLevel = 1i32;\npub const LevelUnsafe: WebSecurityLevel = 0i32;\npub const LoadOptionCacheOnly: X509EnrollmentPolicyLoadOption = 1i32;\npub const LoadOptionDefault: X509EnrollmentPolicyLoadOption = 0i32;\npub const LoadOptionRegisterForADChanges: X509EnrollmentPolicyLoadOption = 4i32;\npub const LoadOptionReload: X509EnrollmentPolicyLoadOption = 2i32;\npub const OCSPAdmin: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd3f73511_92c9_47cb_8ff2_8d891a7c4de4);\npub const OCSPPropertyCollection: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xf935a528_ba8a_4dd9_ba79_f283275cb2de);\npub type OCSPRequestFlag = i32;\npub type OCSPSigningFlag = i32;\npub const OCSP_RF_REJECT_SIGNED_REQUESTS: OCSPRequestFlag = 1i32;\npub const OCSP_SF_ALLOW_NONCE_EXTENSION: OCSPSigningFlag = 256i32;\npub const OCSP_SF_ALLOW_SIGNINGCERT_AUTOENROLLMENT: OCSPSigningFlag = 512i32;\npub const OCSP_SF_ALLOW_SIGNINGCERT_AUTORENEWAL: OCSPSigningFlag = 4i32;\npub const OCSP_SF_AUTODISCOVER_SIGNINGCERT: OCSPSigningFlag = 16i32;\npub const OCSP_SF_FORCE_SIGNINGCERT_ISSUER_ISCA: OCSPSigningFlag = 8i32;\npub const OCSP_SF_MANUAL_ASSIGN_SIGNINGCERT: OCSPSigningFlag = 32i32;\npub const OCSP_SF_RESPONDER_ID_KEYHASH: OCSPSigningFlag = 64i32;\npub const OCSP_SF_RESPONDER_ID_NAME: OCSPSigningFlag = 128i32;\npub const OCSP_SF_SILENT: OCSPSigningFlag = 1i32;\npub const OCSP_SF_USE_CACERT: OCSPSigningFlag = 2i32;\npub type ObjectIdGroupId = i32;\npub type ObjectIdPublicKeyFlags = i32;\npub type PENDING_REQUEST_DESIRED_PROPERTY = i32;\npub const PFXExportChainNoRoot: PFXExportOptions = 1i32;\npub const PFXExportChainWithRoot: PFXExportOptions = 2i32;\npub const PFXExportEEOnly: PFXExportOptions = 0i32;\npub type PFXExportOptions = i32;\npub const PROCFLG_ENFORCEGOODKEYS: u32 = 1u32;\npub const PROCFLG_NONE: u32 = 0u32;\npub const PROPCALLER_ADMIN: u32 = 1024u32;\npub const PROPCALLER_EXIT: u32 = 768u32;\npub const PROPCALLER_MASK: u32 = 3840u32;\npub const PROPCALLER_POLICY: u32 = 512u32;\npub const PROPCALLER_REQUEST: u32 = 1280u32;\npub const PROPCALLER_SERVER: u32 = 256u32;\npub const PROPFLAGS_INDEXED: u32 = 65536u32;\npub const PROPTYPE_BINARY: CERT_PROPERTY_TYPE = 3i32;\npub const PROPTYPE_DATE: CERT_PROPERTY_TYPE = 2i32;\npub const PROPTYPE_LONG: CERT_PROPERTY_TYPE = 1i32;\npub const PROPTYPE_MASK: u32 = 255u32;\npub const PROPTYPE_STRING: CERT_PROPERTY_TYPE = 4i32;\npub type Pkcs10AllowedSignatureTypes = i32;\npub type PolicyQualifierType = i32;\npub const PolicyQualifierTypeFlags: PolicyQualifierType = 3i32;\npub const PolicyQualifierTypeUnknown: PolicyQualifierType = 0i32;\npub const PolicyQualifierTypeUrl: PolicyQualifierType = 1i32;\npub const PolicyQualifierTypeUserNotice: PolicyQualifierType = 2i32;\npub type PolicyServerUrlFlags = i32;\npub type PolicyServerUrlPropertyID = i32;\npub const PrivateKeyAttestMask: X509CertificateTemplatePrivateKeyFlag = 12288i32;\npub const PrivateKeyAttestNone: X509CertificateTemplatePrivateKeyFlag = 0i32;\npub const PrivateKeyAttestPreferred: X509CertificateTemplatePrivateKeyFlag = 4096i32;\npub const PrivateKeyAttestRequired: X509CertificateTemplatePrivateKeyFlag = 8192i32;\npub const PrivateKeyAttestWithoutPolicy: X509CertificateTemplatePrivateKeyFlag = 16384i32;\npub const PrivateKeyClientVersionMask: X509CertificateTemplatePrivateKeyFlag = 251658240i32;\npub const PrivateKeyClientVersionShift: X509CertificateTemplatePrivateKeyFlag = 24i32;\npub const PrivateKeyEKTrustOnUse: X509CertificateTemplatePrivateKeyFlag = 512i32;\npub const PrivateKeyEKValidateCert: X509CertificateTemplatePrivateKeyFlag = 1024i32;\npub const PrivateKeyEKValidateKey: X509CertificateTemplatePrivateKeyFlag = 2048i32;\npub const PrivateKeyExportable: X509CertificateTemplatePrivateKeyFlag = 16i32;\npub const PrivateKeyHelloKspKey: X509CertificateTemplatePrivateKeyFlag = 1048576i32;\npub const PrivateKeyHelloLogonKey: X509CertificateTemplatePrivateKeyFlag = 2097152i32;\npub const PrivateKeyRequireAlternateSignatureAlgorithm: X509CertificateTemplatePrivateKeyFlag = 64i32;\npub const PrivateKeyRequireArchival: X509CertificateTemplatePrivateKeyFlag = 1i32;\npub const PrivateKeyRequireSameKeyRenewal: X509CertificateTemplatePrivateKeyFlag = 128i32;\npub const PrivateKeyRequireStrongKeyProtection: X509CertificateTemplatePrivateKeyFlag = 32i32;\npub const PrivateKeyServerVersionMask: X509CertificateTemplatePrivateKeyFlag = 983040i32;\npub const PrivateKeyServerVersionShift: X509CertificateTemplatePrivateKeyFlag = 16i32;\npub const PrivateKeyUseLegacyProvider: X509CertificateTemplatePrivateKeyFlag = 256i32;\npub const PsFriendlyName: PolicyServerUrlPropertyID = 1i32;\npub const PsPolicyID: PolicyServerUrlPropertyID = 0i32;\npub const PsfAllowUnTrustedCA: PolicyServerUrlFlags = 32i32;\npub const PsfAutoEnrollmentEnabled: PolicyServerUrlFlags = 16i32;\npub const PsfLocationGroupPolicy: PolicyServerUrlFlags = 1i32;\npub const PsfLocationRegistry: PolicyServerUrlFlags = 2i32;\npub const PsfNone: PolicyServerUrlFlags = 0i32;\npub const PsfUseClientId: PolicyServerUrlFlags = 4i32;\npub const REQDISP_DEFAULT_ENTERPRISE: u32 = 1u32;\npub const REQDISP_DENY: u32 = 2u32;\npub const REQDISP_ISSUE: u32 = 1u32;\npub const REQDISP_MASK: u32 = 255u32;\npub const REQDISP_PENDING: u32 = 0u32;\npub const REQDISP_PENDINGFIRST: u32 = 256u32;\npub const REQDISP_USEREQUESTATTRIBUTE: u32 = 3u32;\npub const REVEXT_ASPENABLE: u32 = 512u32;\npub const REVEXT_CDPENABLE: u32 = 256u32;\npub const REVEXT_CDPFILEURL_OLD: u32 = 8u32;\npub const REVEXT_CDPFTPURL_OLD: u32 = 4u32;\npub const REVEXT_CDPHTTPURL_OLD: u32 = 2u32;\npub const REVEXT_CDPLDAPURL_OLD: u32 = 1u32;\npub const REVEXT_CDPURLMASK_OLD: u32 = 255u32;\npub const REVEXT_DEFAULT_DS: u32 = 256u32;\npub const REVEXT_DEFAULT_NODS: u32 = 256u32;\npub type RequestClientInfoClientId = i32;\npub const SCEPDispositionFailure: X509SCEPDisposition = 2i32;\npub const SCEPDispositionPending: X509SCEPDisposition = 3i32;\npub const SCEPDispositionPendingChallenge: X509SCEPDisposition = 11i32;\npub const SCEPDispositionSuccess: X509SCEPDisposition = 0i32;\npub const SCEPDispositionUnknown: X509SCEPDisposition = -1i32;\npub const SCEPFailBadAlgorithm: X509SCEPFailInfo = 0i32;\npub const SCEPFailBadCertId: X509SCEPFailInfo = 4i32;\npub const SCEPFailBadMessageCheck: X509SCEPFailInfo = 1i32;\npub const SCEPFailBadRequest: X509SCEPFailInfo = 2i32;\npub const SCEPFailBadTime: X509SCEPFailInfo = 3i32;\npub const SCEPFailUnknown: X509SCEPFailInfo = -1i32;\npub const SCEPMessageCertResponse: X509SCEPMessageType = 3i32;\npub const SCEPMessageClaimChallengeAnswer: X509SCEPMessageType = 41i32;\npub const SCEPMessageGetCRL: X509SCEPMessageType = 22i32;\npub const SCEPMessageGetCert: X509SCEPMessageType = 21i32;\npub const SCEPMessageGetCertInitial: X509SCEPMessageType = 20i32;\npub const SCEPMessagePKCSRequest: X509SCEPMessageType = 19i32;\npub const SCEPMessageUnknown: X509SCEPMessageType = -1i32;\npub const SCEPProcessDefault: X509SCEPProcessMessageFlags = 0i32;\npub const SCEPProcessSkipCertInstall: X509SCEPProcessMessageFlags = 1i32;\npub const SETUP_ATTEMPT_VROOT_CREATE: u32 = 128u32;\npub const SETUP_CLIENT_FLAG: u32 = 2u32;\npub const SETUP_CREATEDB_FLAG: u32 = 64u32;\npub const SETUP_DCOM_SECURITY_UPDATED_FLAG: u32 = 8192u32;\npub const SETUP_DENIED_FLAG: u32 = 32u32;\npub const SETUP_FORCECRL_FLAG: u32 = 256u32;\npub const SETUP_ONLINE_FLAG: u32 = 16u32;\npub const SETUP_REQUEST_FLAG: u32 = 8u32;\npub const SETUP_SECURITY_CHANGED: u32 = 4096u32;\npub const SETUP_SERVER_FLAG: u32 = 1u32;\npub const SETUP_SERVER_IS_UP_TO_DATE_FLAG: u32 = 16384u32;\npub const SETUP_SERVER_UPGRADED_FLAG: u32 = 1024u32;\npub const SETUP_SUSPEND_FLAG: u32 = 4u32;\npub const SETUP_UPDATE_CAOBJECT_SVRTYPE: u32 = 512u32;\npub const SETUP_W2K_SECURITY_NOT_UPGRADED_FLAG: u32 = 2048u32;\npub const SKIHashCapiSha1: KeyIdentifierHashAlgorithm = 2i32;\npub const SKIHashDefault: KeyIdentifierHashAlgorithm = 0i32;\npub const SKIHashHPKP: KeyIdentifierHashAlgorithm = 5i32;\npub const SKIHashSha1: KeyIdentifierHashAlgorithm = 1i32;\npub const SKIHashSha256: KeyIdentifierHashAlgorithm = 3i32;\npub const SelectedNo: EnrollmentSelectionStatus = 0i32;\npub const SelectedYes: EnrollmentSelectionStatus = 1i32;\npub const SubjectAlternativeNameEnrolleeSupplies: X509CertificateTemplateSubjectNameFlag = 65536i32;\npub const SubjectAlternativeNameRequireDNS: X509CertificateTemplateSubjectNameFlag = 134217728i32;\npub const SubjectAlternativeNameRequireDirectoryGUID: X509CertificateTemplateSubjectNameFlag = 16777216i32;\npub const SubjectAlternativeNameRequireDomainDNS: X509CertificateTemplateSubjectNameFlag = 4194304i32;\npub const SubjectAlternativeNameRequireEmail: X509CertificateTemplateSubjectNameFlag = 67108864i32;\npub const SubjectAlternativeNameRequireSPN: X509CertificateTemplateSubjectNameFlag = 8388608i32;\npub const SubjectAlternativeNameRequireUPN: X509CertificateTemplateSubjectNameFlag = 33554432i32;\npub const SubjectNameAndAlternativeNameOldCertSupplies: X509CertificateTemplateSubjectNameFlag = 8i32;\npub const SubjectNameEnrolleeSupplies: X509CertificateTemplateSubjectNameFlag = 1i32;\npub const SubjectNameRequireCommonName: X509CertificateTemplateSubjectNameFlag = 1073741824i32;\npub const SubjectNameRequireDNS: X509CertificateTemplateSubjectNameFlag = 268435456i32;\npub const SubjectNameRequireDirectoryPath: X509CertificateTemplateSubjectNameFlag = -2147483648i32;\npub const SubjectNameRequireEmail: X509CertificateTemplateSubjectNameFlag = 536870912i32;\npub const TP_MACHINEPOLICY: u32 = 1u32;\npub const TemplatePropAsymmetricAlgorithm: EnrollmentTemplateProperty = 18i32;\npub const TemplatePropCertificatePolicies: EnrollmentTemplateProperty = 16i32;\npub const TemplatePropCommonName: EnrollmentTemplateProperty = 1i32;\npub const TemplatePropCryptoProviders: EnrollmentTemplateProperty = 4i32;\npub const TemplatePropDescription: EnrollmentTemplateProperty = 6i32;\npub const TemplatePropEKUs: EnrollmentTemplateProperty = 3i32;\npub const TemplatePropEnrollmentFlags: EnrollmentTemplateProperty = 24i32;\npub const TemplatePropExtensions: EnrollmentTemplateProperty = 29i32;\npub const TemplatePropFriendlyName: EnrollmentTemplateProperty = 2i32;\npub const TemplatePropGeneralFlags: EnrollmentTemplateProperty = 27i32;\npub const TemplatePropHashAlgorithm: EnrollmentTemplateProperty = 22i32;\npub const TemplatePropKeySecurityDescriptor: EnrollmentTemplateProperty = 19i32;\npub const TemplatePropKeySpec: EnrollmentTemplateProperty = 7i32;\npub const TemplatePropKeyUsage: EnrollmentTemplateProperty = 23i32;\npub const TemplatePropMajorRevision: EnrollmentTemplateProperty = 5i32;\npub const TemplatePropMinimumKeySize: EnrollmentTemplateProperty = 11i32;\npub const TemplatePropMinorRevision: EnrollmentTemplateProperty = 9i32;\npub const TemplatePropOID: EnrollmentTemplateProperty = 12i32;\npub const TemplatePropPrivateKeyFlags: EnrollmentTemplateProperty = 26i32;\npub const TemplatePropRACertificatePolicies: EnrollmentTemplateProperty = 14i32;\npub const TemplatePropRAEKUs: EnrollmentTemplateProperty = 15i32;\npub const TemplatePropRASignatureCount: EnrollmentTemplateProperty = 10i32;\npub const TemplatePropRenewalPeriod: EnrollmentTemplateProperty = 31i32;\npub const TemplatePropSchemaVersion: EnrollmentTemplateProperty = 8i32;\npub const TemplatePropSecurityDescriptor: EnrollmentTemplateProperty = 28i32;\npub const TemplatePropSubjectNameFlags: EnrollmentTemplateProperty = 25i32;\npub const TemplatePropSupersede: EnrollmentTemplateProperty = 13i32;\npub const TemplatePropSymmetricAlgorithm: EnrollmentTemplateProperty = 20i32;\npub const TemplatePropSymmetricKeyLength: EnrollmentTemplateProperty = 21i32;\npub const TemplatePropV1ApplicationPolicy: EnrollmentTemplateProperty = 17i32;\npub const TemplatePropValidityPeriod: EnrollmentTemplateProperty = 30i32;\npub const TypeAny: X509RequestType = 0i32;\npub const TypeCertificate: X509RequestType = 4i32;\npub const TypeCmc: X509RequestType = 3i32;\npub const TypePkcs10: X509RequestType = 1i32;\npub const TypePkcs7: X509RequestType = 2i32;\npub const VR_INSTANT_BAD: u32 = 2u32;\npub const VR_INSTANT_OK: u32 = 1u32;\npub const VR_PENDING: u32 = 0u32;\npub const VerifyAllowUI: X509PrivateKeyVerify = 4i32;\npub const VerifyNone: X509PrivateKeyVerify = 0i32;\npub const VerifySilent: X509PrivateKeyVerify = 1i32;\npub const VerifySmartCardNone: X509PrivateKeyVerify = 2i32;\npub const VerifySmartCardSilent: X509PrivateKeyVerify = 3i32;\npub type WebEnrollmentFlags = i32;\npub type WebSecurityLevel = i32;\npub type X500NameFlags = i32;\npub const X509AuthAnonymous: X509EnrollmentAuthFlags = 1i32;\npub const X509AuthCertificate: X509EnrollmentAuthFlags = 8i32;\npub const X509AuthKerberos: X509EnrollmentAuthFlags = 2i32;\npub const X509AuthNone: X509EnrollmentAuthFlags = 0i32;\npub const X509AuthUsername: X509EnrollmentAuthFlags = 4i32;\npub type X509CertificateEnrollmentContext = i32;\npub type X509CertificateTemplateEnrollmentFlag = i32;\npub type X509CertificateTemplateGeneralFlag = i32;\npub type X509CertificateTemplatePrivateKeyFlag = i32;\npub type X509CertificateTemplateSubjectNameFlag = i32;\npub type X509EnrollmentAuthFlags = i32;\npub type X509EnrollmentPolicyExportFlags = i32;\npub type X509EnrollmentPolicyLoadOption = i32;\npub type X509HardwareKeyUsageFlags = i32;\npub type X509KeyParametersExportType = i32;\npub type X509KeySpec = i32;\npub type X509KeyUsageFlags = i32;\npub type X509PrivateKeyExportFlags = i32;\npub type X509PrivateKeyProtection = i32;\npub type X509PrivateKeyUsageFlags = i32;\npub type X509PrivateKeyVerify = i32;\npub type X509ProviderType = i32;\npub type X509RequestInheritOptions = i32;\npub type X509RequestType = i32;\npub type X509SCEPDisposition = i32;\npub type X509SCEPFailInfo = i32;\npub type X509SCEPMessageType = i32;\npub type X509SCEPProcessMessageFlags = i32;\npub const XCN_AT_KEYEXCHANGE: X509KeySpec = 1i32;\npub const XCN_AT_NONE: X509KeySpec = 0i32;\npub const XCN_AT_SIGNATURE: X509KeySpec = 2i32;\npub const XCN_BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE: AlgorithmType = 3i32;\npub const XCN_BCRYPT_CIPHER_INTERFACE: AlgorithmType = 1i32;\npub const XCN_BCRYPT_HASH_INTERFACE: AlgorithmType = 2i32;\npub const XCN_BCRYPT_KEY_DERIVATION_INTERFACE: AlgorithmType = 7i32;\npub const XCN_BCRYPT_RNG_INTERFACE: AlgorithmType = 6i32;\npub const XCN_BCRYPT_SECRET_AGREEMENT_INTERFACE: AlgorithmType = 4i32;\npub const XCN_BCRYPT_SIGNATURE_INTERFACE: AlgorithmType = 5i32;\npub const XCN_BCRYPT_UNKNOWN_INTERFACE: AlgorithmType = 0i32;\npub const XCN_CERT_ACCESS_STATE_PROP_ID: CERTENROLL_PROPERTYID = 14i32;\npub const XCN_CERT_AIA_URL_RETRIEVED_PROP_ID: CERTENROLL_PROPERTYID = 67i32;\npub const XCN_CERT_ALT_NAME_DIRECTORY_NAME: AlternativeNameType = 5i32;\npub const XCN_CERT_ALT_NAME_DNS_NAME: AlternativeNameType = 3i32;\npub const XCN_CERT_ALT_NAME_EDI_PARTY_NAME: AlternativeNameType = 6i32;\npub const XCN_CERT_ALT_NAME_GUID: AlternativeNameType = 10i32;\npub const XCN_CERT_ALT_NAME_IP_ADDRESS: AlternativeNameType = 8i32;\npub const XCN_CERT_ALT_NAME_OTHER_NAME: AlternativeNameType = 1i32;\npub const XCN_CERT_ALT_NAME_REGISTERED_ID: AlternativeNameType = 9i32;\npub const XCN_CERT_ALT_NAME_RFC822_NAME: AlternativeNameType = 2i32;\npub const XCN_CERT_ALT_NAME_UNKNOWN: AlternativeNameType = 0i32;\npub const XCN_CERT_ALT_NAME_URL: AlternativeNameType = 7i32;\npub const XCN_CERT_ALT_NAME_USER_PRINCIPLE_NAME: AlternativeNameType = 11i32;\npub const XCN_CERT_ALT_NAME_X400_ADDRESS: AlternativeNameType = 4i32;\npub const XCN_CERT_ARCHIVED_KEY_HASH_PROP_ID: CERTENROLL_PROPERTYID = 65i32;\npub const XCN_CERT_ARCHIVED_PROP_ID: CERTENROLL_PROPERTYID = 19i32;\npub const XCN_CERT_AUTHORITY_INFO_ACCESS_PROP_ID: CERTENROLL_PROPERTYID = 68i32;\npub const XCN_CERT_AUTH_ROOT_SHA256_HASH_PROP_ID: CERTENROLL_PROPERTYID = 98i32;\npub const XCN_CERT_AUTO_ENROLL_PROP_ID: CERTENROLL_PROPERTYID = 21i32;\npub const XCN_CERT_AUTO_ENROLL_RETRY_PROP_ID: CERTENROLL_PROPERTYID = 66i32;\npub const XCN_CERT_BACKED_UP_PROP_ID: CERTENROLL_PROPERTYID = 69i32;\npub const XCN_CERT_CA_DISABLE_CRL_PROP_ID: CERTENROLL_PROPERTYID = 82i32;\npub const XCN_CERT_CA_OCSP_AUTHORITY_INFO_ACCESS_PROP_ID: CERTENROLL_PROPERTYID = 81i32;\npub const XCN_CERT_CEP_PROP_ID: CERTENROLL_PROPERTYID = 87i32;\npub const XCN_CERT_CERT_NOT_BEFORE_ENHKEY_USAGE_PROP_ID: CERTENROLL_PROPERTYID = 127i32;\npub const XCN_CERT_CLR_DELETE_KEY_PROP_ID: CERTENROLL_PROPERTYID = 125i32;\npub const XCN_CERT_CRL_SIGN_KEY_USAGE: X509KeyUsageFlags = 2i32;\npub const XCN_CERT_CROSS_CERT_DIST_POINTS_PROP_ID: CERTENROLL_PROPERTYID = 23i32;\npub const XCN_CERT_CTL_USAGE_PROP_ID: CERTENROLL_PROPERTYID = 9i32;\npub const XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE: X509KeyUsageFlags = 16i32;\npub const XCN_CERT_DATE_STAMP_PROP_ID: CERTENROLL_PROPERTYID = 27i32;\npub const XCN_CERT_DECIPHER_ONLY_KEY_USAGE: X509KeyUsageFlags = 32768i32;\npub const XCN_CERT_DESCRIPTION_PROP_ID: CERTENROLL_PROPERTYID = 13i32;\npub const XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE: X509KeyUsageFlags = 128i32;\npub const XCN_CERT_DISALLOWED_ENHKEY_USAGE_PROP_ID: CERTENROLL_PROPERTYID = 122i32;\npub const XCN_CERT_DISALLOWED_FILETIME_PROP_ID: CERTENROLL_PROPERTYID = 104i32;\npub const XCN_CERT_EFS_PROP_ID: CERTENROLL_PROPERTYID = 17i32;\npub const XCN_CERT_ENCIPHER_ONLY_KEY_USAGE: X509KeyUsageFlags = 1i32;\npub const XCN_CERT_ENHKEY_USAGE_PROP_ID: CERTENROLL_PROPERTYID = 9i32;\npub const XCN_CERT_ENROLLMENT_PROP_ID: CERTENROLL_PROPERTYID = 26i32;\npub const XCN_CERT_EXTENDED_ERROR_INFO_PROP_ID: CERTENROLL_PROPERTYID = 30i32;\npub const XCN_CERT_FIRST_RESERVED_PROP_ID: CERTENROLL_PROPERTYID = 129i32;\npub const XCN_CERT_FIRST_USER_PROP_ID: CERTENROLL_PROPERTYID = 32768i32;\npub const XCN_CERT_FORTEZZA_DATA_PROP_ID: CERTENROLL_PROPERTYID = 18i32;\npub const XCN_CERT_FRIENDLY_NAME_PROP_ID: CERTENROLL_PROPERTYID = 11i32;\npub const XCN_CERT_HASH_PROP_ID: CERTENROLL_PROPERTYID = 3i32;\npub const XCN_CERT_HCRYPTPROV_OR_NCRYPT_KEY_HANDLE_PROP_ID: CERTENROLL_PROPERTYID = 79i32;\npub const XCN_CERT_HCRYPTPROV_TRANSFER_PROP_ID: CERTENROLL_PROPERTYID = 100i32;\npub const XCN_CERT_IE30_RESERVED_PROP_ID: CERTENROLL_PROPERTYID = 7i32;\npub const XCN_CERT_ISOLATED_KEY_PROP_ID: CERTENROLL_PROPERTYID = 118i32;\npub const XCN_CERT_ISSUER_CHAIN_PUB_KEY_CNG_ALG_BIT_LENGTH_PROP_ID: CERTENROLL_PROPERTYID = 96i32;\npub const XCN_CERT_ISSUER_CHAIN_SIGN_HASH_CNG_ALG_PROP_ID: CERTENROLL_PROPERTYID = 95i32;\npub const XCN_CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID: CERTENROLL_PROPERTYID = 24i32;\npub const XCN_CERT_ISSUER_PUB_KEY_BIT_LENGTH_PROP_ID: CERTENROLL_PROPERTYID = 94i32;\npub const XCN_CERT_ISSUER_SERIAL_NUMBER_MD5_HASH_PROP_ID: CERTENROLL_PROPERTYID = 28i32;\npub const XCN_CERT_KEY_AGREEMENT_KEY_USAGE: X509KeyUsageFlags = 8i32;\npub const XCN_CERT_KEY_CERT_SIGN_KEY_USAGE: X509KeyUsageFlags = 4i32;\npub const XCN_CERT_KEY_CLASSIFICATION_PROP_ID: CERTENROLL_PROPERTYID = 120i32;\npub const XCN_CERT_KEY_CONTEXT_PROP_ID: CERTENROLL_PROPERTYID = 5i32;\npub const XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE: X509KeyUsageFlags = 32i32;\npub const XCN_CERT_KEY_IDENTIFIER_PROP_ID: CERTENROLL_PROPERTYID = 20i32;\npub const XCN_CERT_KEY_PROV_HANDLE_PROP_ID: CERTENROLL_PROPERTYID = 1i32;\npub const XCN_CERT_KEY_PROV_INFO_PROP_ID: CERTENROLL_PROPERTYID = 2i32;\npub const XCN_CERT_KEY_REPAIR_ATTEMPTED_PROP_ID: CERTENROLL_PROPERTYID = 103i32;\npub const XCN_CERT_KEY_SPEC_PROP_ID: CERTENROLL_PROPERTYID = 6i32;\npub const XCN_CERT_LAST_RESERVED_PROP_ID: CERTENROLL_PROPERTYID = 32767i32;\npub const XCN_CERT_LAST_USER_PROP_ID: CERTENROLL_PROPERTYID = 65535i32;\npub const XCN_CERT_MD5_HASH_PROP_ID: CERTENROLL_PROPERTYID = 4i32;\npub const XCN_CERT_NAME_STR_AMBIGUOUS_SEPARATOR_FLAGS: X500NameFlags = 1275068416i32;\npub const XCN_CERT_NAME_STR_COMMA_FLAG: X500NameFlags = 67108864i32;\npub const XCN_CERT_NAME_STR_CRLF_FLAG: X500NameFlags = 134217728i32;\npub const XCN_CERT_NAME_STR_DISABLE_IE4_UTF8_FLAG: X500NameFlags = 65536i32;\npub const XCN_CERT_NAME_STR_DISABLE_UTF8_DIR_STR_FLAG: X500NameFlags = 1048576i32;\npub const XCN_CERT_NAME_STR_DS_ESCAPED: X500NameFlags = 8388608i32;\npub const XCN_CERT_NAME_STR_ENABLE_PUNYCODE_FLAG: X500NameFlags = 2097152i32;\npub const XCN_CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG: X500NameFlags = 131072i32;\npub const XCN_CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG: X500NameFlags = 262144i32;\npub const XCN_CERT_NAME_STR_FORCE_UTF8_DIR_STR_FLAG: X500NameFlags = 524288i32;\npub const XCN_CERT_NAME_STR_FORWARD_FLAG: X500NameFlags = 16777216i32;\npub const XCN_CERT_NAME_STR_NONE: X500NameFlags = 0i32;\npub const XCN_CERT_NAME_STR_NO_PLUS_FLAG: X500NameFlags = 536870912i32;\npub const XCN_CERT_NAME_STR_NO_QUOTING_FLAG: X500NameFlags = 268435456i32;\npub const XCN_CERT_NAME_STR_REVERSE_FLAG: X500NameFlags = 33554432i32;\npub const XCN_CERT_NAME_STR_SEMICOLON_FLAG: X500NameFlags = 1073741824i32;\npub const XCN_CERT_NCRYPT_KEY_HANDLE_PROP_ID: CERTENROLL_PROPERTYID = 78i32;\npub const XCN_CERT_NCRYPT_KEY_HANDLE_TRANSFER_PROP_ID: CERTENROLL_PROPERTYID = 99i32;\npub const XCN_CERT_NEW_KEY_PROP_ID: CERTENROLL_PROPERTYID = 74i32;\npub const XCN_CERT_NEXT_UPDATE_LOCATION_PROP_ID: CERTENROLL_PROPERTYID = 10i32;\npub const XCN_CERT_NONCOMPLIANT_ROOT_URL_PROP_ID: CERTENROLL_PROPERTYID = 123i32;\npub const XCN_CERT_NON_REPUDIATION_KEY_USAGE: X509KeyUsageFlags = 64i32;\npub const XCN_CERT_NOT_BEFORE_FILETIME_PROP_ID: CERTENROLL_PROPERTYID = 126i32;\npub const XCN_CERT_NO_AUTO_EXPIRE_CHECK_PROP_ID: CERTENROLL_PROPERTYID = 77i32;\npub const XCN_CERT_NO_EXPIRE_NOTIFICATION_PROP_ID: CERTENROLL_PROPERTYID = 97i32;\npub const XCN_CERT_NO_KEY_USAGE: X509KeyUsageFlags = 0i32;\npub const XCN_CERT_OCSP_CACHE_PREFIX_PROP_ID: CERTENROLL_PROPERTYID = 75i32;\npub const XCN_CERT_OCSP_RESPONSE_PROP_ID: CERTENROLL_PROPERTYID = 70i32;\npub const XCN_CERT_OFFLINE_CRL_SIGN_KEY_USAGE: X509KeyUsageFlags = 2i32;\npub const XCN_CERT_OID_NAME_STR: X500NameFlags = 2i32;\npub const XCN_CERT_PIN_SHA256_HASH_PROP_ID: CERTENROLL_PROPERTYID = 124i32;\npub const XCN_CERT_PUBKEY_ALG_PARA_PROP_ID: CERTENROLL_PROPERTYID = 22i32;\npub const XCN_CERT_PUBKEY_HASH_RESERVED_PROP_ID: CERTENROLL_PROPERTYID = 8i32;\npub const XCN_CERT_PUB_KEY_CNG_ALG_BIT_LENGTH_PROP_ID: CERTENROLL_PROPERTYID = 93i32;\npub const XCN_CERT_PVK_FILE_PROP_ID: CERTENROLL_PROPERTYID = 12i32;\npub const XCN_CERT_RENEWAL_PROP_ID: CERTENROLL_PROPERTYID = 64i32;\npub const XCN_CERT_REQUEST_ORIGINATOR_PROP_ID: CERTENROLL_PROPERTYID = 71i32;\npub const XCN_CERT_ROOT_PROGRAM_CERT_POLICIES_PROP_ID: CERTENROLL_PROPERTYID = 83i32;\npub const XCN_CERT_ROOT_PROGRAM_CHAIN_POLICIES_PROP_ID: CERTENROLL_PROPERTYID = 105i32;\npub const XCN_CERT_ROOT_PROGRAM_NAME_CONSTRAINTS_PROP_ID: CERTENROLL_PROPERTYID = 84i32;\npub const XCN_CERT_SCARD_PIN_ID_PROP_ID: CERTENROLL_PROPERTYID = 90i32;\npub const XCN_CERT_SCARD_PIN_INFO_PROP_ID: CERTENROLL_PROPERTYID = 91i32;\npub const XCN_CERT_SCEP_CA_CERT_PROP_ID: CERTENROLL_PROPERTYID = 111i32;\npub const XCN_CERT_SCEP_ENCRYPT_HASH_CNG_ALG_PROP_ID: CERTENROLL_PROPERTYID = 114i32;\npub const XCN_CERT_SCEP_FLAGS_PROP_ID: CERTENROLL_PROPERTYID = 115i32;\npub const XCN_CERT_SCEP_GUID_PROP_ID: CERTENROLL_PROPERTYID = 116i32;\npub const XCN_CERT_SCEP_NONCE_PROP_ID: CERTENROLL_PROPERTYID = 113i32;\npub const XCN_CERT_SCEP_RA_ENCRYPTION_CERT_PROP_ID: CERTENROLL_PROPERTYID = 110i32;\npub const XCN_CERT_SCEP_RA_SIGNATURE_CERT_PROP_ID: CERTENROLL_PROPERTYID = 109i32;\npub const XCN_CERT_SCEP_SERVER_CERTS_PROP_ID: CERTENROLL_PROPERTYID = 108i32;\npub const XCN_CERT_SCEP_SIGNER_CERT_PROP_ID: CERTENROLL_PROPERTYID = 112i32;\npub const XCN_CERT_SEND_AS_TRUSTED_ISSUER_PROP_ID: CERTENROLL_PROPERTYID = 102i32;\npub const XCN_CERT_SERIALIZABLE_KEY_CONTEXT_PROP_ID: CERTENROLL_PROPERTYID = 117i32;\npub const XCN_CERT_SERIAL_CHAIN_PROP_ID: CERTENROLL_PROPERTYID = 119i32;\npub const XCN_CERT_SHA1_HASH_PROP_ID: CERTENROLL_PROPERTYID = 3i32;\npub const XCN_CERT_SHA256_HASH_PROP_ID: CERTENROLL_PROPERTYID = 107i32;\npub const XCN_CERT_SIGNATURE_HASH_PROP_ID: CERTENROLL_PROPERTYID = 15i32;\npub const XCN_CERT_SIGN_HASH_CNG_ALG_PROP_ID: CERTENROLL_PROPERTYID = 89i32;\npub const XCN_CERT_SIMPLE_NAME_STR: X500NameFlags = 1i32;\npub const XCN_CERT_SMART_CARD_DATA_PROP_ID: CERTENROLL_PROPERTYID = 16i32;\npub const XCN_CERT_SMART_CARD_READER_NON_REMOVABLE_PROP_ID: CERTENROLL_PROPERTYID = 106i32;\npub const XCN_CERT_SMART_CARD_READER_PROP_ID: CERTENROLL_PROPERTYID = 101i32;\npub const XCN_CERT_SMART_CARD_ROOT_INFO_PROP_ID: CERTENROLL_PROPERTYID = 76i32;\npub const XCN_CERT_SOURCE_LOCATION_PROP_ID: CERTENROLL_PROPERTYID = 72i32;\npub const XCN_CERT_SOURCE_URL_PROP_ID: CERTENROLL_PROPERTYID = 73i32;\npub const XCN_CERT_STORE_LOCALIZED_NAME_PROP_ID: CERTENROLL_PROPERTYID = 4096i32;\npub const XCN_CERT_SUBJECT_DISABLE_CRL_PROP_ID: CERTENROLL_PROPERTYID = 86i32;\npub const XCN_CERT_SUBJECT_INFO_ACCESS_PROP_ID: CERTENROLL_PROPERTYID = 80i32;\npub const XCN_CERT_SUBJECT_NAME_MD5_HASH_PROP_ID: CERTENROLL_PROPERTYID = 29i32;\npub const XCN_CERT_SUBJECT_OCSP_AUTHORITY_INFO_ACCESS_PROP_ID: CERTENROLL_PROPERTYID = 85i32;\npub const XCN_CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID: CERTENROLL_PROPERTYID = 25i32;\npub const XCN_CERT_SUBJECT_PUB_KEY_BIT_LENGTH_PROP_ID: CERTENROLL_PROPERTYID = 92i32;\npub const XCN_CERT_X500_NAME_STR: X500NameFlags = 3i32;\npub const XCN_CERT_XML_NAME_STR: X500NameFlags = 4i32;\npub const XCN_CRL_REASON_AA_COMPROMISE: CRLRevocationReason = 10i32;\npub const XCN_CRL_REASON_AFFILIATION_CHANGED: CRLRevocationReason = 3i32;\npub const XCN_CRL_REASON_CA_COMPROMISE: CRLRevocationReason = 2i32;\npub const XCN_CRL_REASON_CERTIFICATE_HOLD: CRLRevocationReason = 6i32;\npub const XCN_CRL_REASON_CESSATION_OF_OPERATION: CRLRevocationReason = 5i32;\npub const XCN_CRL_REASON_KEY_COMPROMISE: CRLRevocationReason = 1i32;\npub const XCN_CRL_REASON_PRIVILEGE_WITHDRAWN: CRLRevocationReason = 9i32;\npub const XCN_CRL_REASON_REMOVE_FROM_CRL: CRLRevocationReason = 8i32;\npub const XCN_CRL_REASON_SUPERSEDED: CRLRevocationReason = 4i32;\npub const XCN_CRL_REASON_UNSPECIFIED: CRLRevocationReason = 0i32;\npub const XCN_CRYPT_ANY_GROUP_ID: ObjectIdGroupId = 0i32;\npub const XCN_CRYPT_ENCRYPT_ALG_OID_GROUP_ID: ObjectIdGroupId = 2i32;\npub const XCN_CRYPT_ENHKEY_USAGE_OID_GROUP_ID: ObjectIdGroupId = 7i32;\npub const XCN_CRYPT_EXT_OR_ATTR_OID_GROUP_ID: ObjectIdGroupId = 6i32;\npub const XCN_CRYPT_FIRST_ALG_OID_GROUP_ID: ObjectIdGroupId = 1i32;\npub const XCN_CRYPT_GROUP_ID_MASK: ObjectIdGroupId = 65535i32;\npub const XCN_CRYPT_HASH_ALG_OID_GROUP_ID: ObjectIdGroupId = 1i32;\npub const XCN_CRYPT_KDF_OID_GROUP_ID: ObjectIdGroupId = 10i32;\npub const XCN_CRYPT_KEY_LENGTH_MASK: ObjectIdGroupId = 268369920i32;\npub const XCN_CRYPT_LAST_ALG_OID_GROUP_ID: ObjectIdGroupId = 4i32;\npub const XCN_CRYPT_LAST_OID_GROUP_ID: ObjectIdGroupId = 10i32;\npub const XCN_CRYPT_OID_DISABLE_SEARCH_DS_FLAG: ObjectIdGroupId = -2147483648i32;\npub const XCN_CRYPT_OID_INFO_OID_GROUP_BIT_LEN_MASK: ObjectIdGroupId = 268369920i32;\npub const XCN_CRYPT_OID_INFO_OID_GROUP_BIT_LEN_SHIFT: ObjectIdGroupId = 16i32;\npub const XCN_CRYPT_OID_INFO_PUBKEY_ANY: ObjectIdPublicKeyFlags = 0i32;\npub const XCN_CRYPT_OID_INFO_PUBKEY_ENCRYPT_KEY_FLAG: ObjectIdPublicKeyFlags = 1073741824i32;\npub const XCN_CRYPT_OID_INFO_PUBKEY_SIGN_KEY_FLAG: ObjectIdPublicKeyFlags = -2147483648i32;\npub const XCN_CRYPT_OID_PREFER_CNG_ALGID_FLAG: ObjectIdGroupId = 1073741824i32;\npub const XCN_CRYPT_OID_USE_CURVE_NAME_FOR_ENCODE_FLAG: X509KeyParametersExportType = 536870912i32;\npub const XCN_CRYPT_OID_USE_CURVE_NONE: X509KeyParametersExportType = 0i32;\npub const XCN_CRYPT_OID_USE_CURVE_PARAMETERS_FOR_ENCODE_FLAG: X509KeyParametersExportType = 268435456i32;\npub const XCN_CRYPT_POLICY_OID_GROUP_ID: ObjectIdGroupId = 8i32;\npub const XCN_CRYPT_PUBKEY_ALG_OID_GROUP_ID: ObjectIdGroupId = 3i32;\npub const XCN_CRYPT_RDN_ATTR_OID_GROUP_ID: ObjectIdGroupId = 5i32;\npub const XCN_CRYPT_SIGN_ALG_OID_GROUP_ID: ObjectIdGroupId = 4i32;\npub const XCN_CRYPT_STRING_ANY: EncodingType = 7i32;\npub const XCN_CRYPT_STRING_BASE64: EncodingType = 1i32;\npub const XCN_CRYPT_STRING_BASE64HEADER: EncodingType = 0i32;\npub const XCN_CRYPT_STRING_BASE64REQUESTHEADER: EncodingType = 3i32;\npub const XCN_CRYPT_STRING_BASE64URI: EncodingType = 13i32;\npub const XCN_CRYPT_STRING_BASE64X509CRLHEADER: EncodingType = 9i32;\npub const XCN_CRYPT_STRING_BASE64_ANY: EncodingType = 6i32;\npub const XCN_CRYPT_STRING_BINARY: EncodingType = 2i32;\npub const XCN_CRYPT_STRING_CHAIN: EncodingType = 256i32;\npub const XCN_CRYPT_STRING_ENCODEMASK: EncodingType = 255i32;\npub const XCN_CRYPT_STRING_HASHDATA: EncodingType = 268435456i32;\npub const XCN_CRYPT_STRING_HEX: EncodingType = 4i32;\npub const XCN_CRYPT_STRING_HEXADDR: EncodingType = 10i32;\npub const XCN_CRYPT_STRING_HEXASCII: EncodingType = 5i32;\npub const XCN_CRYPT_STRING_HEXASCIIADDR: EncodingType = 11i32;\npub const XCN_CRYPT_STRING_HEXRAW: EncodingType = 12i32;\npub const XCN_CRYPT_STRING_HEX_ANY: EncodingType = 8i32;\npub const XCN_CRYPT_STRING_NOCR: EncodingType = -2147483648i32;\npub const XCN_CRYPT_STRING_NOCRLF: EncodingType = 1073741824i32;\npub const XCN_CRYPT_STRING_PERCENTESCAPE: EncodingType = 134217728i32;\npub const XCN_CRYPT_STRING_STRICT: EncodingType = 536870912i32;\npub const XCN_CRYPT_STRING_TEXT: EncodingType = 512i32;\npub const XCN_CRYPT_TEMPLATE_OID_GROUP_ID: ObjectIdGroupId = 9i32;\npub const XCN_NCRYPT_ALLOW_ALL_USAGES: X509PrivateKeyUsageFlags = 16777215i32;\npub const XCN_NCRYPT_ALLOW_ARCHIVING_FLAG: X509PrivateKeyExportFlags = 4i32;\npub const XCN_NCRYPT_ALLOW_DECRYPT_FLAG: X509PrivateKeyUsageFlags = 1i32;\npub const XCN_NCRYPT_ALLOW_EXPORT_FLAG: X509PrivateKeyExportFlags = 1i32;\npub const XCN_NCRYPT_ALLOW_EXPORT_NONE: X509PrivateKeyExportFlags = 0i32;\npub const XCN_NCRYPT_ALLOW_KEY_AGREEMENT_FLAG: X509PrivateKeyUsageFlags = 4i32;\npub const XCN_NCRYPT_ALLOW_KEY_IMPORT_FLAG: X509PrivateKeyUsageFlags = 8i32;\npub const XCN_NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG: X509PrivateKeyExportFlags = 8i32;\npub const XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG: X509PrivateKeyExportFlags = 2i32;\npub const XCN_NCRYPT_ALLOW_SIGNING_FLAG: X509PrivateKeyUsageFlags = 2i32;\npub const XCN_NCRYPT_ALLOW_USAGES_NONE: X509PrivateKeyUsageFlags = 0i32;\npub const XCN_NCRYPT_ANY_ASYMMETRIC_OPERATION: AlgorithmOperationFlags = 28i32;\npub const XCN_NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION: AlgorithmOperationFlags = 4i32;\npub const XCN_NCRYPT_CIPHER_OPERATION: AlgorithmOperationFlags = 1i32;\npub const XCN_NCRYPT_CLAIM_AUTHORITY_AND_SUBJECT: KeyAttestationClaimType = 3i32;\npub const XCN_NCRYPT_CLAIM_AUTHORITY_ONLY: KeyAttestationClaimType = 1i32;\npub const XCN_NCRYPT_CLAIM_NONE: KeyAttestationClaimType = 0i32;\npub const XCN_NCRYPT_CLAIM_SUBJECT_ONLY: KeyAttestationClaimType = 2i32;\npub const XCN_NCRYPT_CLAIM_UNKNOWN: KeyAttestationClaimType = 4096i32;\npub const XCN_NCRYPT_EXACT_MATCH_OPERATION: AlgorithmOperationFlags = 8388608i32;\npub const XCN_NCRYPT_HASH_OPERATION: AlgorithmOperationFlags = 2i32;\npub const XCN_NCRYPT_KEY_DERIVATION_OPERATION: AlgorithmOperationFlags = 64i32;\npub const XCN_NCRYPT_NO_OPERATION: AlgorithmOperationFlags = 0i32;\npub const XCN_NCRYPT_PCP_ENCRYPTION_KEY: X509HardwareKeyUsageFlags = 2i32;\npub const XCN_NCRYPT_PCP_GENERIC_KEY: X509HardwareKeyUsageFlags = 3i32;\npub const XCN_NCRYPT_PCP_IDENTITY_KEY: X509HardwareKeyUsageFlags = 8i32;\npub const XCN_NCRYPT_PCP_NONE: X509HardwareKeyUsageFlags = 0i32;\npub const XCN_NCRYPT_PCP_SIGNATURE_KEY: X509HardwareKeyUsageFlags = 1i32;\npub const XCN_NCRYPT_PCP_STORAGE_KEY: X509HardwareKeyUsageFlags = 4i32;\npub const XCN_NCRYPT_PREFERENCE_MASK_OPERATION: AlgorithmOperationFlags = 14680064i32;\npub const XCN_NCRYPT_PREFER_NON_SIGNATURE_OPERATION: AlgorithmOperationFlags = 4194304i32;\npub const XCN_NCRYPT_PREFER_SIGNATURE_ONLY_OPERATION: AlgorithmOperationFlags = 2097152i32;\npub const XCN_NCRYPT_RNG_OPERATION: AlgorithmOperationFlags = 32i32;\npub const XCN_NCRYPT_SECRET_AGREEMENT_OPERATION: AlgorithmOperationFlags = 8i32;\npub const XCN_NCRYPT_SIGNATURE_OPERATION: AlgorithmOperationFlags = 16i32;\npub const XCN_NCRYPT_TPM12_PROVIDER: X509HardwareKeyUsageFlags = 65536i32;\npub const XCN_NCRYPT_UI_APPCONTAINER_ACCESS_MEDIUM_FLAG: X509PrivateKeyProtection = 8i32;\npub const XCN_NCRYPT_UI_FINGERPRINT_PROTECTION_FLAG: X509PrivateKeyProtection = 4i32;\npub const XCN_NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG: X509PrivateKeyProtection = 2i32;\npub const XCN_NCRYPT_UI_NO_PROTECTION_FLAG: X509PrivateKeyProtection = 0i32;\npub const XCN_NCRYPT_UI_PROTECT_KEY_FLAG: X509PrivateKeyProtection = 1i32;\npub const XCN_OIDVerisign_FailInfo: CERTENROLL_OBJECTID = 431i32;\npub const XCN_OIDVerisign_MessageType: CERTENROLL_OBJECTID = 429i32;\npub const XCN_OIDVerisign_PkiStatus: CERTENROLL_OBJECTID = 430i32;\npub const XCN_OIDVerisign_RecipientNonce: CERTENROLL_OBJECTID = 433i32;\npub const XCN_OIDVerisign_SenderNonce: CERTENROLL_OBJECTID = 432i32;\npub const XCN_OIDVerisign_TransactionID: CERTENROLL_OBJECTID = 434i32;\npub const XCN_OID_ANSI_X942: CERTENROLL_OBJECTID = 53i32;\npub const XCN_OID_ANSI_X942_DH: CERTENROLL_OBJECTID = 54i32;\npub const XCN_OID_ANY_APPLICATION_POLICY: CERTENROLL_OBJECTID = 216i32;\npub const XCN_OID_ANY_CERT_POLICY: CERTENROLL_OBJECTID = 180i32;\npub const XCN_OID_ANY_ENHANCED_KEY_USAGE: CERTENROLL_OBJECTID = 352i32;\npub const XCN_OID_APPLICATION_CERT_POLICIES: CERTENROLL_OBJECTID = 229i32;\npub const XCN_OID_APPLICATION_POLICY_CONSTRAINTS: CERTENROLL_OBJECTID = 231i32;\npub const XCN_OID_APPLICATION_POLICY_MAPPINGS: CERTENROLL_OBJECTID = 230i32;\npub const XCN_OID_ARCHIVED_KEY_ATTR: CERTENROLL_OBJECTID = 232i32;\npub const XCN_OID_ARCHIVED_KEY_CERT_HASH: CERTENROLL_OBJECTID = 235i32;\npub const XCN_OID_ATTR_SUPPORTED_ALGORITHMS: CERTENROLL_OBJECTID = 355i32;\npub const XCN_OID_ATTR_TPM_SECURITY_ASSERTIONS: CERTENROLL_OBJECTID = 356i32;\npub const XCN_OID_ATTR_TPM_SPECIFICATION: CERTENROLL_OBJECTID = 357i32;\npub const XCN_OID_AUTHORITY_INFO_ACCESS: CERTENROLL_OBJECTID = 204i32;\npub const XCN_OID_AUTHORITY_KEY_IDENTIFIER: CERTENROLL_OBJECTID = 169i32;\npub const XCN_OID_AUTHORITY_KEY_IDENTIFIER2: CERTENROLL_OBJECTID = 181i32;\npub const XCN_OID_AUTHORITY_REVOCATION_LIST: CERTENROLL_OBJECTID = 156i32;\npub const XCN_OID_AUTO_ENROLL_CTL_USAGE: CERTENROLL_OBJECTID = 217i32;\npub const XCN_OID_BACKGROUND_OTHER_LOGOTYPE: CERTENROLL_OBJECTID = 327i32;\npub const XCN_OID_BASIC_CONSTRAINTS: CERTENROLL_OBJECTID = 175i32;\npub const XCN_OID_BASIC_CONSTRAINTS2: CERTENROLL_OBJECTID = 178i32;\npub const XCN_OID_BIOMETRIC_EXT: CERTENROLL_OBJECTID = 205i32;\npub const XCN_OID_BUSINESS_CATEGORY: CERTENROLL_OBJECTID = 133i32;\npub const XCN_OID_CA_CERTIFICATE: CERTENROLL_OBJECTID = 155i32;\npub const XCN_OID_CERTIFICATE_REVOCATION_LIST: CERTENROLL_OBJECTID = 157i32;\npub const XCN_OID_CERTIFICATE_TEMPLATE: CERTENROLL_OBJECTID = 226i32;\npub const XCN_OID_CERTSRV_CA_VERSION: CERTENROLL_OBJECTID = 220i32;\npub const XCN_OID_CERTSRV_CROSSCA_VERSION: CERTENROLL_OBJECTID = 240i32;\npub const XCN_OID_CERTSRV_PREVIOUS_CERT_HASH: CERTENROLL_OBJECTID = 221i32;\npub const XCN_OID_CERT_DISALLOWED_FILETIME_PROP_ID: CERTENROLL_OBJECTID = 358i32;\npub const XCN_OID_CERT_EXTENSIONS: CERTENROLL_OBJECTID = 207i32;\npub const XCN_OID_CERT_ISSUER_SERIAL_NUMBER_MD5_HASH_PROP_ID: CERTENROLL_OBJECTID = 339i32;\npub const XCN_OID_CERT_KEY_IDENTIFIER_PROP_ID: CERTENROLL_OBJECTID = 338i32;\npub const XCN_OID_CERT_MANIFOLD: CERTENROLL_OBJECTID = 219i32;\npub const XCN_OID_CERT_MD5_HASH_PROP_ID: CERTENROLL_OBJECTID = 341i32;\npub const XCN_OID_CERT_POLICIES: CERTENROLL_OBJECTID = 179i32;\npub const XCN_OID_CERT_POLICIES_95: CERTENROLL_OBJECTID = 171i32;\npub const XCN_OID_CERT_POLICIES_95_QUALIFIER1: CERTENROLL_OBJECTID = 281i32;\npub const XCN_OID_CERT_PROP_ID_PREFIX: CERTENROLL_OBJECTID = 337i32;\npub const XCN_OID_CERT_SIGNATURE_HASH_PROP_ID: CERTENROLL_OBJECTID = 359i32;\npub const XCN_OID_CERT_STRONG_KEY_OS_1: CERTENROLL_OBJECTID = 360i32;\npub const XCN_OID_CERT_STRONG_KEY_OS_CURRENT: CERTENROLL_OBJECTID = 361i32;\npub const XCN_OID_CERT_STRONG_KEY_OS_PREFIX: CERTENROLL_OBJECTID = 362i32;\npub const XCN_OID_CERT_STRONG_SIGN_OS_1: CERTENROLL_OBJECTID = 363i32;\npub const XCN_OID_CERT_STRONG_SIGN_OS_CURRENT: CERTENROLL_OBJECTID = 364i32;\npub const XCN_OID_CERT_STRONG_SIGN_OS_PREFIX: CERTENROLL_OBJECTID = 365i32;\npub const XCN_OID_CERT_SUBJECT_NAME_MD5_HASH_PROP_ID: CERTENROLL_OBJECTID = 340i32;\npub const XCN_OID_CMC: CERTENROLL_OBJECTID = 304i32;\npub const XCN_OID_CMC_ADD_ATTRIBUTES: CERTENROLL_OBJECTID = 325i32;\npub const XCN_OID_CMC_ADD_EXTENSIONS: CERTENROLL_OBJECTID = 312i32;\npub const XCN_OID_CMC_DATA_RETURN: CERTENROLL_OBJECTID = 308i32;\npub const XCN_OID_CMC_DECRYPTED_POP: CERTENROLL_OBJECTID = 314i32;\npub const XCN_OID_CMC_ENCRYPTED_POP: CERTENROLL_OBJECTID = 313i32;\npub const XCN_OID_CMC_GET_CERT: CERTENROLL_OBJECTID = 316i32;\npub const XCN_OID_CMC_GET_CRL: CERTENROLL_OBJECTID = 317i32;\npub const XCN_OID_CMC_IDENTIFICATION: CERTENROLL_OBJECTID = 306i32;\npub const XCN_OID_CMC_IDENTITY_PROOF: CERTENROLL_OBJECTID = 307i32;\npub const XCN_OID_CMC_ID_CONFIRM_CERT_ACCEPTANCE: CERTENROLL_OBJECTID = 324i32;\npub const XCN_OID_CMC_ID_POP_LINK_RANDOM: CERTENROLL_OBJECTID = 322i32;\npub const XCN_OID_CMC_ID_POP_LINK_WITNESS: CERTENROLL_OBJECTID = 323i32;\npub const XCN_OID_CMC_LRA_POP_WITNESS: CERTENROLL_OBJECTID = 315i32;\npub const XCN_OID_CMC_QUERY_PENDING: CERTENROLL_OBJECTID = 321i32;\npub const XCN_OID_CMC_RECIPIENT_NONCE: CERTENROLL_OBJECTID = 311i32;\npub const XCN_OID_CMC_REG_INFO: CERTENROLL_OBJECTID = 319i32;\npub const XCN_OID_CMC_RESPONSE_INFO: CERTENROLL_OBJECTID = 320i32;\npub const XCN_OID_CMC_REVOKE_REQUEST: CERTENROLL_OBJECTID = 318i32;\npub const XCN_OID_CMC_SENDER_NONCE: CERTENROLL_OBJECTID = 310i32;\npub const XCN_OID_CMC_STATUS_INFO: CERTENROLL_OBJECTID = 305i32;\npub const XCN_OID_CMC_TRANSACTION_ID: CERTENROLL_OBJECTID = 309i32;\npub const XCN_OID_COMMON_NAME: CERTENROLL_OBJECTID = 121i32;\npub const XCN_OID_COUNTRY_NAME: CERTENROLL_OBJECTID = 124i32;\npub const XCN_OID_CRL_DIST_POINTS: CERTENROLL_OBJECTID = 187i32;\npub const XCN_OID_CRL_NEXT_PUBLISH: CERTENROLL_OBJECTID = 223i32;\npub const XCN_OID_CRL_NUMBER: CERTENROLL_OBJECTID = 189i32;\npub const XCN_OID_CRL_REASON_CODE: CERTENROLL_OBJECTID = 185i32;\npub const XCN_OID_CRL_SELF_CDP: CERTENROLL_OBJECTID = 233i32;\npub const XCN_OID_CRL_VIRTUAL_BASE: CERTENROLL_OBJECTID = 222i32;\npub const XCN_OID_CROSS_CERTIFICATE_PAIR: CERTENROLL_OBJECTID = 158i32;\npub const XCN_OID_CROSS_CERT_DIST_POINTS: CERTENROLL_OBJECTID = 210i32;\npub const XCN_OID_CTL: CERTENROLL_OBJECTID = 211i32;\npub const XCN_OID_CT_PKI_DATA: CERTENROLL_OBJECTID = 301i32;\npub const XCN_OID_CT_PKI_RESPONSE: CERTENROLL_OBJECTID = 302i32;\npub const XCN_OID_DELTA_CRL_INDICATOR: CERTENROLL_OBJECTID = 190i32;\npub const XCN_OID_DESCRIPTION: CERTENROLL_OBJECTID = 131i32;\npub const XCN_OID_DESTINATION_INDICATOR: CERTENROLL_OBJECTID = 145i32;\npub const XCN_OID_DEVICE_SERIAL_NUMBER: CERTENROLL_OBJECTID = 123i32;\npub const XCN_OID_DH_SINGLE_PASS_STDDH_SHA1_KDF: CERTENROLL_OBJECTID = 366i32;\npub const XCN_OID_DH_SINGLE_PASS_STDDH_SHA256_KDF: CERTENROLL_OBJECTID = 367i32;\npub const XCN_OID_DH_SINGLE_PASS_STDDH_SHA384_KDF: CERTENROLL_OBJECTID = 368i32;\npub const XCN_OID_DISALLOWED_HASH: CERTENROLL_OBJECTID = 369i32;\npub const XCN_OID_DISALLOWED_LIST: CERTENROLL_OBJECTID = 370i32;\npub const XCN_OID_DN_QUALIFIER: CERTENROLL_OBJECTID = 161i32;\npub const XCN_OID_DOMAIN_COMPONENT: CERTENROLL_OBJECTID = 162i32;\npub const XCN_OID_DRM: CERTENROLL_OBJECTID = 273i32;\npub const XCN_OID_DRM_INDIVIDUALIZATION: CERTENROLL_OBJECTID = 274i32;\npub const XCN_OID_DS: CERTENROLL_OBJECTID = 58i32;\npub const XCN_OID_DSALG: CERTENROLL_OBJECTID = 59i32;\npub const XCN_OID_DSALG_CRPT: CERTENROLL_OBJECTID = 60i32;\npub const XCN_OID_DSALG_HASH: CERTENROLL_OBJECTID = 61i32;\npub const XCN_OID_DSALG_RSA: CERTENROLL_OBJECTID = 63i32;\npub const XCN_OID_DSALG_SIGN: CERTENROLL_OBJECTID = 62i32;\npub const XCN_OID_DS_EMAIL_REPLICATION: CERTENROLL_OBJECTID = 237i32;\npub const XCN_OID_ECC_CURVE_P256: CERTENROLL_OBJECTID = 371i32;\npub const XCN_OID_ECC_CURVE_P384: CERTENROLL_OBJECTID = 372i32;\npub const XCN_OID_ECC_CURVE_P521: CERTENROLL_OBJECTID = 373i32;\npub const XCN_OID_ECC_PUBLIC_KEY: CERTENROLL_OBJECTID = 349i32;\npub const XCN_OID_ECDSA_SHA1: CERTENROLL_OBJECTID = 350i32;\npub const XCN_OID_ECDSA_SHA256: CERTENROLL_OBJECTID = 374i32;\npub const XCN_OID_ECDSA_SHA384: CERTENROLL_OBJECTID = 375i32;\npub const XCN_OID_ECDSA_SHA512: CERTENROLL_OBJECTID = 376i32;\npub const XCN_OID_ECDSA_SPECIFIED: CERTENROLL_OBJECTID = 351i32;\npub const XCN_OID_EFS_RECOVERY: CERTENROLL_OBJECTID = 260i32;\npub const XCN_OID_EMBEDDED_NT_CRYPTO: CERTENROLL_OBJECTID = 264i32;\npub const XCN_OID_ENCRYPTED_KEY_HASH: CERTENROLL_OBJECTID = 239i32;\npub const XCN_OID_ENHANCED_KEY_USAGE: CERTENROLL_OBJECTID = 188i32;\npub const XCN_OID_ENROLLMENT_AGENT: CERTENROLL_OBJECTID = 201i32;\npub const XCN_OID_ENROLLMENT_CSP_PROVIDER: CERTENROLL_OBJECTID = 199i32;\npub const XCN_OID_ENROLLMENT_NAME_VALUE_PAIR: CERTENROLL_OBJECTID = 198i32;\npub const XCN_OID_ENROLL_ATTESTATION_CHALLENGE: CERTENROLL_OBJECTID = 435i32;\npub const XCN_OID_ENROLL_ATTESTATION_STATEMENT: CERTENROLL_OBJECTID = 436i32;\npub const XCN_OID_ENROLL_CAXCHGCERT_HASH: CERTENROLL_OBJECTID = 377i32;\npub const XCN_OID_ENROLL_CERTTYPE_EXTENSION: CERTENROLL_OBJECTID = 218i32;\npub const XCN_OID_ENROLL_EKPUB_CHALLENGE: CERTENROLL_OBJECTID = 379i32;\npub const XCN_OID_ENROLL_EKVERIFYCERT: CERTENROLL_OBJECTID = 380i32;\npub const XCN_OID_ENROLL_EKVERIFYCREDS: CERTENROLL_OBJECTID = 381i32;\npub const XCN_OID_ENROLL_EKVERIFYKEY: CERTENROLL_OBJECTID = 382i32;\npub const XCN_OID_ENROLL_EK_INFO: CERTENROLL_OBJECTID = 378i32;\npub const XCN_OID_ENROLL_ENCRYPTION_ALGORITHM: CERTENROLL_OBJECTID = 437i32;\npub const XCN_OID_ENROLL_KSP_NAME: CERTENROLL_OBJECTID = 438i32;\npub const XCN_OID_ENROLL_SCEP_ERROR: CERTENROLL_OBJECTID = 428i32;\npub const XCN_OID_ENTERPRISE_OID_ROOT: CERTENROLL_OBJECTID = 227i32;\npub const XCN_OID_EV_RDN_COUNTRY: CERTENROLL_OBJECTID = 383i32;\npub const XCN_OID_EV_RDN_LOCALE: CERTENROLL_OBJECTID = 384i32;\npub const XCN_OID_EV_RDN_STATE_OR_PROVINCE: CERTENROLL_OBJECTID = 385i32;\npub const XCN_OID_FACSIMILE_TELEPHONE_NUMBER: CERTENROLL_OBJECTID = 141i32;\npub const XCN_OID_FRESHEST_CRL: CERTENROLL_OBJECTID = 192i32;\npub const XCN_OID_GIVEN_NAME: CERTENROLL_OBJECTID = 159i32;\npub const XCN_OID_INFOSEC: CERTENROLL_OBJECTID = 99i32;\npub const XCN_OID_INFOSEC_SuiteAConfidentiality: CERTENROLL_OBJECTID = 113i32;\npub const XCN_OID_INFOSEC_SuiteAIntegrity: CERTENROLL_OBJECTID = 114i32;\npub const XCN_OID_INFOSEC_SuiteAKMandSig: CERTENROLL_OBJECTID = 117i32;\npub const XCN_OID_INFOSEC_SuiteAKeyManagement: CERTENROLL_OBJECTID = 116i32;\npub const XCN_OID_INFOSEC_SuiteASignature: CERTENROLL_OBJECTID = 112i32;\npub const XCN_OID_INFOSEC_SuiteATokenProtection: CERTENROLL_OBJECTID = 115i32;\npub const XCN_OID_INFOSEC_mosaicConfidentiality: CERTENROLL_OBJECTID = 103i32;\npub const XCN_OID_INFOSEC_mosaicIntegrity: CERTENROLL_OBJECTID = 105i32;\npub const XCN_OID_INFOSEC_mosaicKMandSig: CERTENROLL_OBJECTID = 111i32;\npub const XCN_OID_INFOSEC_mosaicKMandUpdSig: CERTENROLL_OBJECTID = 119i32;\npub const XCN_OID_INFOSEC_mosaicKeyManagement: CERTENROLL_OBJECTID = 109i32;\npub const XCN_OID_INFOSEC_mosaicSignature: CERTENROLL_OBJECTID = 101i32;\npub const XCN_OID_INFOSEC_mosaicTokenProtection: CERTENROLL_OBJECTID = 107i32;\npub const XCN_OID_INFOSEC_mosaicUpdatedInteg: CERTENROLL_OBJECTID = 120i32;\npub const XCN_OID_INFOSEC_mosaicUpdatedSig: CERTENROLL_OBJECTID = 118i32;\npub const XCN_OID_INFOSEC_sdnsConfidentiality: CERTENROLL_OBJECTID = 102i32;\npub const XCN_OID_INFOSEC_sdnsIntegrity: CERTENROLL_OBJECTID = 104i32;\npub const XCN_OID_INFOSEC_sdnsKMandSig: CERTENROLL_OBJECTID = 110i32;\npub const XCN_OID_INFOSEC_sdnsKeyManagement: CERTENROLL_OBJECTID = 108i32;\npub const XCN_OID_INFOSEC_sdnsSignature: CERTENROLL_OBJECTID = 100i32;\npub const XCN_OID_INFOSEC_sdnsTokenProtection: CERTENROLL_OBJECTID = 106i32;\npub const XCN_OID_INHIBIT_ANY_POLICY: CERTENROLL_OBJECTID = 386i32;\npub const XCN_OID_INITIALS: CERTENROLL_OBJECTID = 160i32;\npub const XCN_OID_INTERNATIONALIZED_EMAIL_ADDRESS: CERTENROLL_OBJECTID = 387i32;\npub const XCN_OID_INTERNATIONAL_ISDN_NUMBER: CERTENROLL_OBJECTID = 143i32;\npub const XCN_OID_IPSEC_KP_IKE_INTERMEDIATE: CERTENROLL_OBJECTID = 254i32;\npub const XCN_OID_ISSUED_CERT_HASH: CERTENROLL_OBJECTID = 236i32;\npub const XCN_OID_ISSUER_ALT_NAME: CERTENROLL_OBJECTID = 174i32;\npub const XCN_OID_ISSUER_ALT_NAME2: CERTENROLL_OBJECTID = 184i32;\npub const XCN_OID_ISSUING_DIST_POINT: CERTENROLL_OBJECTID = 191i32;\npub const XCN_OID_KEYID_RDN: CERTENROLL_OBJECTID = 168i32;\npub const XCN_OID_KEY_ATTRIBUTES: CERTENROLL_OBJECTID = 170i32;\npub const XCN_OID_KEY_USAGE: CERTENROLL_OBJECTID = 176i32;\npub const XCN_OID_KEY_USAGE_RESTRICTION: CERTENROLL_OBJECTID = 172i32;\npub const XCN_OID_KP_CA_EXCHANGE: CERTENROLL_OBJECTID = 224i32;\npub const XCN_OID_KP_CSP_SIGNATURE: CERTENROLL_OBJECTID = 272i32;\npub const XCN_OID_KP_CTL_USAGE_SIGNING: CERTENROLL_OBJECTID = 255i32;\npub const XCN_OID_KP_DOCUMENT_SIGNING: CERTENROLL_OBJECTID = 268i32;\npub const XCN_OID_KP_EFS: CERTENROLL_OBJECTID = 259i32;\npub const XCN_OID_KP_KERNEL_MODE_CODE_SIGNING: CERTENROLL_OBJECTID = 388i32;\npub const XCN_OID_KP_KERNEL_MODE_HAL_EXTENSION_SIGNING: CERTENROLL_OBJECTID = 389i32;\npub const XCN_OID_KP_KERNEL_MODE_TRUSTED_BOOT_SIGNING: CERTENROLL_OBJECTID = 390i32;\npub const XCN_OID_KP_KEY_RECOVERY: CERTENROLL_OBJECTID = 267i32;\npub const XCN_OID_KP_KEY_RECOVERY_AGENT: CERTENROLL_OBJECTID = 225i32;\npub const XCN_OID_KP_LIFETIME_SIGNING: CERTENROLL_OBJECTID = 269i32;\npub const XCN_OID_KP_MOBILE_DEVICE_SOFTWARE: CERTENROLL_OBJECTID = 270i32;\npub const XCN_OID_KP_QUALIFIED_SUBORDINATION: CERTENROLL_OBJECTID = 266i32;\npub const XCN_OID_KP_SMARTCARD_LOGON: CERTENROLL_OBJECTID = 277i32;\npub const XCN_OID_KP_SMART_DISPLAY: CERTENROLL_OBJECTID = 271i32;\npub const XCN_OID_KP_TIME_STAMP_SIGNING: CERTENROLL_OBJECTID = 256i32;\npub const XCN_OID_KP_TPM_AIK_CERTIFICATE: CERTENROLL_OBJECTID = 391i32;\npub const XCN_OID_KP_TPM_EK_CERTIFICATE: CERTENROLL_OBJECTID = 392i32;\npub const XCN_OID_KP_TPM_PLATFORM_CERTIFICATE: CERTENROLL_OBJECTID = 393i32;\npub const XCN_OID_LEGACY_POLICY_MAPPINGS: CERTENROLL_OBJECTID = 195i32;\npub const XCN_OID_LICENSES: CERTENROLL_OBJECTID = 275i32;\npub const XCN_OID_LICENSE_SERVER: CERTENROLL_OBJECTID = 276i32;\npub const XCN_OID_LOCALITY_NAME: CERTENROLL_OBJECTID = 125i32;\npub const XCN_OID_LOCAL_MACHINE_KEYSET: CERTENROLL_OBJECTID = 166i32;\npub const XCN_OID_LOGOTYPE_EXT: CERTENROLL_OBJECTID = 206i32;\npub const XCN_OID_LOYALTY_OTHER_LOGOTYPE: CERTENROLL_OBJECTID = 326i32;\npub const XCN_OID_MEMBER: CERTENROLL_OBJECTID = 149i32;\npub const XCN_OID_NAME_CONSTRAINTS: CERTENROLL_OBJECTID = 193i32;\npub const XCN_OID_NETSCAPE: CERTENROLL_OBJECTID = 289i32;\npub const XCN_OID_NETSCAPE_BASE_URL: CERTENROLL_OBJECTID = 292i32;\npub const XCN_OID_NETSCAPE_CA_POLICY_URL: CERTENROLL_OBJECTID = 296i32;\npub const XCN_OID_NETSCAPE_CA_REVOCATION_URL: CERTENROLL_OBJECTID = 294i32;\npub const XCN_OID_NETSCAPE_CERT_EXTENSION: CERTENROLL_OBJECTID = 290i32;\npub const XCN_OID_NETSCAPE_CERT_RENEWAL_URL: CERTENROLL_OBJECTID = 295i32;\npub const XCN_OID_NETSCAPE_CERT_SEQUENCE: CERTENROLL_OBJECTID = 300i32;\npub const XCN_OID_NETSCAPE_CERT_TYPE: CERTENROLL_OBJECTID = 291i32;\npub const XCN_OID_NETSCAPE_COMMENT: CERTENROLL_OBJECTID = 298i32;\npub const XCN_OID_NETSCAPE_DATA_TYPE: CERTENROLL_OBJECTID = 299i32;\npub const XCN_OID_NETSCAPE_REVOCATION_URL: CERTENROLL_OBJECTID = 293i32;\npub const XCN_OID_NETSCAPE_SSL_SERVER_NAME: CERTENROLL_OBJECTID = 297i32;\npub const XCN_OID_NEXT_UPDATE_LOCATION: CERTENROLL_OBJECTID = 208i32;\npub const XCN_OID_NIST_AES128_CBC: CERTENROLL_OBJECTID = 394i32;\npub const XCN_OID_NIST_AES128_WRAP: CERTENROLL_OBJECTID = 395i32;\npub const XCN_OID_NIST_AES192_CBC: CERTENROLL_OBJECTID = 396i32;\npub const XCN_OID_NIST_AES192_WRAP: CERTENROLL_OBJECTID = 397i32;\npub const XCN_OID_NIST_AES256_CBC: CERTENROLL_OBJECTID = 398i32;\npub const XCN_OID_NIST_AES256_WRAP: CERTENROLL_OBJECTID = 399i32;\npub const XCN_OID_NIST_sha256: CERTENROLL_OBJECTID = 345i32;\npub const XCN_OID_NIST_sha384: CERTENROLL_OBJECTID = 346i32;\npub const XCN_OID_NIST_sha512: CERTENROLL_OBJECTID = 347i32;\npub const XCN_OID_NONE: CERTENROLL_OBJECTID = 0i32;\npub const XCN_OID_NT5_CRYPTO: CERTENROLL_OBJECTID = 262i32;\npub const XCN_OID_NTDS_REPLICATION: CERTENROLL_OBJECTID = 241i32;\npub const XCN_OID_NT_PRINCIPAL_NAME: CERTENROLL_OBJECTID = 214i32;\npub const XCN_OID_OEM_WHQL_CRYPTO: CERTENROLL_OBJECTID = 263i32;\npub const XCN_OID_OIW: CERTENROLL_OBJECTID = 64i32;\npub const XCN_OID_OIWDIR: CERTENROLL_OBJECTID = 93i32;\npub const XCN_OID_OIWDIR_CRPT: CERTENROLL_OBJECTID = 94i32;\npub const XCN_OID_OIWDIR_HASH: CERTENROLL_OBJECTID = 95i32;\npub const XCN_OID_OIWDIR_SIGN: CERTENROLL_OBJECTID = 96i32;\npub const XCN_OID_OIWDIR_md2: CERTENROLL_OBJECTID = 97i32;\npub const XCN_OID_OIWDIR_md2RSA: CERTENROLL_OBJECTID = 98i32;\npub const XCN_OID_OIWSEC: CERTENROLL_OBJECTID = 65i32;\npub const XCN_OID_OIWSEC_desCBC: CERTENROLL_OBJECTID = 70i32;\npub const XCN_OID_OIWSEC_desCFB: CERTENROLL_OBJECTID = 72i32;\npub const XCN_OID_OIWSEC_desECB: CERTENROLL_OBJECTID = 69i32;\npub const XCN_OID_OIWSEC_desEDE: CERTENROLL_OBJECTID = 80i32;\npub const XCN_OID_OIWSEC_desMAC: CERTENROLL_OBJECTID = 73i32;\npub const XCN_OID_OIWSEC_desOFB: CERTENROLL_OBJECTID = 71i32;\npub const XCN_OID_OIWSEC_dhCommMod: CERTENROLL_OBJECTID = 79i32;\npub const XCN_OID_OIWSEC_dsa: CERTENROLL_OBJECTID = 75i32;\npub const XCN_OID_OIWSEC_dsaComm: CERTENROLL_OBJECTID = 83i32;\npub const XCN_OID_OIWSEC_dsaCommSHA: CERTENROLL_OBJECTID = 84i32;\npub const XCN_OID_OIWSEC_dsaCommSHA1: CERTENROLL_OBJECTID = 91i32;\npub const XCN_OID_OIWSEC_dsaSHA1: CERTENROLL_OBJECTID = 90i32;\npub const XCN_OID_OIWSEC_keyHashSeal: CERTENROLL_OBJECTID = 86i32;\npub const XCN_OID_OIWSEC_md2RSASign: CERTENROLL_OBJECTID = 87i32;\npub const XCN_OID_OIWSEC_md4RSA: CERTENROLL_OBJECTID = 66i32;\npub const XCN_OID_OIWSEC_md4RSA2: CERTENROLL_OBJECTID = 68i32;\npub const XCN_OID_OIWSEC_md5RSA: CERTENROLL_OBJECTID = 67i32;\npub const XCN_OID_OIWSEC_md5RSASign: CERTENROLL_OBJECTID = 88i32;\npub const XCN_OID_OIWSEC_mdc2: CERTENROLL_OBJECTID = 82i32;\npub const XCN_OID_OIWSEC_mdc2RSA: CERTENROLL_OBJECTID = 77i32;\npub const XCN_OID_OIWSEC_rsaSign: CERTENROLL_OBJECTID = 74i32;\npub const XCN_OID_OIWSEC_rsaXchg: CERTENROLL_OBJECTID = 85i32;\npub const XCN_OID_OIWSEC_sha: CERTENROLL_OBJECTID = 81i32;\npub const XCN_OID_OIWSEC_sha1: CERTENROLL_OBJECTID = 89i32;\npub const XCN_OID_OIWSEC_sha1RSASign: CERTENROLL_OBJECTID = 92i32;\npub const XCN_OID_OIWSEC_shaDSA: CERTENROLL_OBJECTID = 76i32;\npub const XCN_OID_OIWSEC_shaRSA: CERTENROLL_OBJECTID = 78i32;\npub const XCN_OID_ORGANIZATIONAL_UNIT_NAME: CERTENROLL_OBJECTID = 129i32;\npub const XCN_OID_ORGANIZATION_NAME: CERTENROLL_OBJECTID = 128i32;\npub const XCN_OID_OS_VERSION: CERTENROLL_OBJECTID = 200i32;\npub const XCN_OID_OWNER: CERTENROLL_OBJECTID = 150i32;\npub const XCN_OID_PHYSICAL_DELIVERY_OFFICE_NAME: CERTENROLL_OBJECTID = 137i32;\npub const XCN_OID_PKCS: CERTENROLL_OBJECTID = 2i32;\npub const XCN_OID_PKCS_1: CERTENROLL_OBJECTID = 5i32;\npub const XCN_OID_PKCS_10: CERTENROLL_OBJECTID = 14i32;\npub const XCN_OID_PKCS_12: CERTENROLL_OBJECTID = 15i32;\npub const XCN_OID_PKCS_12_EXTENDED_ATTRIBUTES: CERTENROLL_OBJECTID = 167i32;\npub const XCN_OID_PKCS_12_FRIENDLY_NAME_ATTR: CERTENROLL_OBJECTID = 163i32;\npub const XCN_OID_PKCS_12_KEY_PROVIDER_NAME_ATTR: CERTENROLL_OBJECTID = 165i32;\npub const XCN_OID_PKCS_12_LOCAL_KEY_ID: CERTENROLL_OBJECTID = 164i32;\npub const XCN_OID_PKCS_12_PROTECTED_PASSWORD_SECRET_BAG_TYPE_ID: CERTENROLL_OBJECTID = 407i32;\npub const XCN_OID_PKCS_12_PbeIds: CERTENROLL_OBJECTID = 400i32;\npub const XCN_OID_PKCS_12_pbeWithSHA1And128BitRC2: CERTENROLL_OBJECTID = 401i32;\npub const XCN_OID_PKCS_12_pbeWithSHA1And128BitRC4: CERTENROLL_OBJECTID = 402i32;\npub const XCN_OID_PKCS_12_pbeWithSHA1And2KeyTripleDES: CERTENROLL_OBJECTID = 403i32;\npub const XCN_OID_PKCS_12_pbeWithSHA1And3KeyTripleDES: CERTENROLL_OBJECTID = 404i32;\npub const XCN_OID_PKCS_12_pbeWithSHA1And40BitRC2: CERTENROLL_OBJECTID = 405i32;\npub const XCN_OID_PKCS_12_pbeWithSHA1And40BitRC4: CERTENROLL_OBJECTID = 406i32;\npub const XCN_OID_PKCS_2: CERTENROLL_OBJECTID = 6i32;\npub const XCN_OID_PKCS_3: CERTENROLL_OBJECTID = 7i32;\npub const XCN_OID_PKCS_4: CERTENROLL_OBJECTID = 8i32;\npub const XCN_OID_PKCS_5: CERTENROLL_OBJECTID = 9i32;\npub const XCN_OID_PKCS_6: CERTENROLL_OBJECTID = 10i32;\npub const XCN_OID_PKCS_7: CERTENROLL_OBJECTID = 11i32;\npub const XCN_OID_PKCS_7_DATA: CERTENROLL_OBJECTID = 329i32;\npub const XCN_OID_PKCS_7_DIGESTED: CERTENROLL_OBJECTID = 333i32;\npub const XCN_OID_PKCS_7_ENCRYPTED: CERTENROLL_OBJECTID = 334i32;\npub const XCN_OID_PKCS_7_ENVELOPED: CERTENROLL_OBJECTID = 331i32;\npub const XCN_OID_PKCS_7_SIGNED: CERTENROLL_OBJECTID = 330i32;\npub const XCN_OID_PKCS_7_SIGNEDANDENVELOPED: CERTENROLL_OBJECTID = 332i32;\npub const XCN_OID_PKCS_8: CERTENROLL_OBJECTID = 12i32;\npub const XCN_OID_PKCS_9: CERTENROLL_OBJECTID = 13i32;\npub const XCN_OID_PKCS_9_CONTENT_TYPE: CERTENROLL_OBJECTID = 335i32;\npub const XCN_OID_PKCS_9_MESSAGE_DIGEST: CERTENROLL_OBJECTID = 336i32;\npub const XCN_OID_PKINIT_KP_KDC: CERTENROLL_OBJECTID = 408i32;\npub const XCN_OID_PKIX: CERTENROLL_OBJECTID = 202i32;\npub const XCN_OID_PKIX_ACC_DESCR: CERTENROLL_OBJECTID = 282i32;\npub const XCN_OID_PKIX_CA_ISSUERS: CERTENROLL_OBJECTID = 284i32;\npub const XCN_OID_PKIX_CA_REPOSITORY: CERTENROLL_OBJECTID = 409i32;\npub const XCN_OID_PKIX_KP: CERTENROLL_OBJECTID = 243i32;\npub const XCN_OID_PKIX_KP_CLIENT_AUTH: CERTENROLL_OBJECTID = 245i32;\npub const XCN_OID_PKIX_KP_CODE_SIGNING: CERTENROLL_OBJECTID = 246i32;\npub const XCN_OID_PKIX_KP_EMAIL_PROTECTION: CERTENROLL_OBJECTID = 247i32;\npub const XCN_OID_PKIX_KP_IPSEC_END_SYSTEM: CERTENROLL_OBJECTID = 248i32;\npub const XCN_OID_PKIX_KP_IPSEC_TUNNEL: CERTENROLL_OBJECTID = 249i32;\npub const XCN_OID_PKIX_KP_IPSEC_USER: CERTENROLL_OBJECTID = 250i32;\npub const XCN_OID_PKIX_KP_OCSP_SIGNING: CERTENROLL_OBJECTID = 252i32;\npub const XCN_OID_PKIX_KP_SERVER_AUTH: CERTENROLL_OBJECTID = 244i32;\npub const XCN_OID_PKIX_KP_TIMESTAMP_SIGNING: CERTENROLL_OBJECTID = 251i32;\npub const XCN_OID_PKIX_NO_SIGNATURE: CERTENROLL_OBJECTID = 303i32;\npub const XCN_OID_PKIX_OCSP: CERTENROLL_OBJECTID = 283i32;\npub const XCN_OID_PKIX_OCSP_BASIC_SIGNED_RESPONSE: CERTENROLL_OBJECTID = 328i32;\npub const XCN_OID_PKIX_OCSP_NOCHECK: CERTENROLL_OBJECTID = 253i32;\npub const XCN_OID_PKIX_OCSP_NONCE: CERTENROLL_OBJECTID = 410i32;\npub const XCN_OID_PKIX_PE: CERTENROLL_OBJECTID = 203i32;\npub const XCN_OID_PKIX_POLICY_QUALIFIER_CPS: CERTENROLL_OBJECTID = 279i32;\npub const XCN_OID_PKIX_POLICY_QUALIFIER_USERNOTICE: CERTENROLL_OBJECTID = 280i32;\npub const XCN_OID_PKIX_TIME_STAMPING: CERTENROLL_OBJECTID = 411i32;\npub const XCN_OID_POLICY_CONSTRAINTS: CERTENROLL_OBJECTID = 196i32;\npub const XCN_OID_POLICY_MAPPINGS: CERTENROLL_OBJECTID = 194i32;\npub const XCN_OID_POSTAL_ADDRESS: CERTENROLL_OBJECTID = 134i32;\npub const XCN_OID_POSTAL_CODE: CERTENROLL_OBJECTID = 135i32;\npub const XCN_OID_POST_OFFICE_BOX: CERTENROLL_OBJECTID = 136i32;\npub const XCN_OID_PREFERRED_DELIVERY_METHOD: CERTENROLL_OBJECTID = 146i32;\npub const XCN_OID_PRESENTATION_ADDRESS: CERTENROLL_OBJECTID = 147i32;\npub const XCN_OID_PRIVATEKEY_USAGE_PERIOD: CERTENROLL_OBJECTID = 177i32;\npub const XCN_OID_PRODUCT_UPDATE: CERTENROLL_OBJECTID = 215i32;\npub const XCN_OID_QC_EU_COMPLIANCE: CERTENROLL_OBJECTID = 412i32;\npub const XCN_OID_QC_SSCD: CERTENROLL_OBJECTID = 413i32;\npub const XCN_OID_QC_STATEMENTS_EXT: CERTENROLL_OBJECTID = 414i32;\npub const XCN_OID_RDN_DUMMY_SIGNER: CERTENROLL_OBJECTID = 228i32;\npub const XCN_OID_RDN_TPM_MANUFACTURER: CERTENROLL_OBJECTID = 415i32;\npub const XCN_OID_RDN_TPM_MODEL: CERTENROLL_OBJECTID = 416i32;\npub const XCN_OID_RDN_TPM_VERSION: CERTENROLL_OBJECTID = 417i32;\npub const XCN_OID_REASON_CODE_HOLD: CERTENROLL_OBJECTID = 186i32;\npub const XCN_OID_REGISTERED_ADDRESS: CERTENROLL_OBJECTID = 144i32;\npub const XCN_OID_REMOVE_CERTIFICATE: CERTENROLL_OBJECTID = 209i32;\npub const XCN_OID_RENEWAL_CERTIFICATE: CERTENROLL_OBJECTID = 197i32;\npub const XCN_OID_REQUEST_CLIENT_INFO: CERTENROLL_OBJECTID = 238i32;\npub const XCN_OID_REQUIRE_CERT_CHAIN_POLICY: CERTENROLL_OBJECTID = 234i32;\npub const XCN_OID_REVOKED_LIST_SIGNER: CERTENROLL_OBJECTID = 418i32;\npub const XCN_OID_RFC3161_counterSign: CERTENROLL_OBJECTID = 419i32;\npub const XCN_OID_ROLE_OCCUPANT: CERTENROLL_OBJECTID = 151i32;\npub const XCN_OID_ROOT_LIST_SIGNER: CERTENROLL_OBJECTID = 265i32;\npub const XCN_OID_ROOT_PROGRAM_AUTO_UPDATE_CA_REVOCATION: CERTENROLL_OBJECTID = 420i32;\npub const XCN_OID_ROOT_PROGRAM_AUTO_UPDATE_END_REVOCATION: CERTENROLL_OBJECTID = 421i32;\npub const XCN_OID_ROOT_PROGRAM_FLAGS: CERTENROLL_OBJECTID = 422i32;\npub const XCN_OID_ROOT_PROGRAM_NO_OCSP_FAILOVER_TO_CRL: CERTENROLL_OBJECTID = 423i32;\npub const XCN_OID_RSA: CERTENROLL_OBJECTID = 1i32;\npub const XCN_OID_RSAES_OAEP: CERTENROLL_OBJECTID = 425i32;\npub const XCN_OID_RSA_DES_EDE3_CBC: CERTENROLL_OBJECTID = 51i32;\npub const XCN_OID_RSA_DH: CERTENROLL_OBJECTID = 22i32;\npub const XCN_OID_RSA_ENCRYPT: CERTENROLL_OBJECTID = 4i32;\npub const XCN_OID_RSA_HASH: CERTENROLL_OBJECTID = 3i32;\npub const XCN_OID_RSA_MD2: CERTENROLL_OBJECTID = 46i32;\npub const XCN_OID_RSA_MD2RSA: CERTENROLL_OBJECTID = 17i32;\npub const XCN_OID_RSA_MD4: CERTENROLL_OBJECTID = 47i32;\npub const XCN_OID_RSA_MD4RSA: CERTENROLL_OBJECTID = 18i32;\npub const XCN_OID_RSA_MD5: CERTENROLL_OBJECTID = 48i32;\npub const XCN_OID_RSA_MD5RSA: CERTENROLL_OBJECTID = 19i32;\npub const XCN_OID_RSA_MGF1: CERTENROLL_OBJECTID = 348i32;\npub const XCN_OID_RSA_PSPECIFIED: CERTENROLL_OBJECTID = 424i32;\npub const XCN_OID_RSA_RC2CBC: CERTENROLL_OBJECTID = 49i32;\npub const XCN_OID_RSA_RC4: CERTENROLL_OBJECTID = 50i32;\npub const XCN_OID_RSA_RC5_CBCPad: CERTENROLL_OBJECTID = 52i32;\npub const XCN_OID_RSA_RSA: CERTENROLL_OBJECTID = 16i32;\npub const XCN_OID_RSA_SETOAEP_RSA: CERTENROLL_OBJECTID = 21i32;\npub const XCN_OID_RSA_SHA1RSA: CERTENROLL_OBJECTID = 20i32;\npub const XCN_OID_RSA_SHA256RSA: CERTENROLL_OBJECTID = 342i32;\npub const XCN_OID_RSA_SHA384RSA: CERTENROLL_OBJECTID = 343i32;\npub const XCN_OID_RSA_SHA512RSA: CERTENROLL_OBJECTID = 344i32;\npub const XCN_OID_RSA_SMIMECapabilities: CERTENROLL_OBJECTID = 40i32;\npub const XCN_OID_RSA_SMIMEalg: CERTENROLL_OBJECTID = 42i32;\npub const XCN_OID_RSA_SMIMEalgCMS3DESwrap: CERTENROLL_OBJECTID = 44i32;\npub const XCN_OID_RSA_SMIMEalgCMSRC2wrap: CERTENROLL_OBJECTID = 45i32;\npub const XCN_OID_RSA_SMIMEalgESDH: CERTENROLL_OBJECTID = 43i32;\npub const XCN_OID_RSA_SSA_PSS: CERTENROLL_OBJECTID = 353i32;\npub const XCN_OID_RSA_certExtensions: CERTENROLL_OBJECTID = 39i32;\npub const XCN_OID_RSA_challengePwd: CERTENROLL_OBJECTID = 36i32;\npub const XCN_OID_RSA_contentType: CERTENROLL_OBJECTID = 32i32;\npub const XCN_OID_RSA_counterSign: CERTENROLL_OBJECTID = 35i32;\npub const XCN_OID_RSA_data: CERTENROLL_OBJECTID = 23i32;\npub const XCN_OID_RSA_digestedData: CERTENROLL_OBJECTID = 27i32;\npub const XCN_OID_RSA_emailAddr: CERTENROLL_OBJECTID = 30i32;\npub const XCN_OID_RSA_encryptedData: CERTENROLL_OBJECTID = 29i32;\npub const XCN_OID_RSA_envelopedData: CERTENROLL_OBJECTID = 25i32;\npub const XCN_OID_RSA_extCertAttrs: CERTENROLL_OBJECTID = 38i32;\npub const XCN_OID_RSA_hashedData: CERTENROLL_OBJECTID = 28i32;\npub const XCN_OID_RSA_messageDigest: CERTENROLL_OBJECTID = 33i32;\npub const XCN_OID_RSA_preferSignedData: CERTENROLL_OBJECTID = 41i32;\npub const XCN_OID_RSA_signEnvData: CERTENROLL_OBJECTID = 26i32;\npub const XCN_OID_RSA_signedData: CERTENROLL_OBJECTID = 24i32;\npub const XCN_OID_RSA_signingTime: CERTENROLL_OBJECTID = 34i32;\npub const XCN_OID_RSA_unstructAddr: CERTENROLL_OBJECTID = 37i32;\npub const XCN_OID_RSA_unstructName: CERTENROLL_OBJECTID = 31i32;\npub const XCN_OID_SEARCH_GUIDE: CERTENROLL_OBJECTID = 132i32;\npub const XCN_OID_SEE_ALSO: CERTENROLL_OBJECTID = 152i32;\npub const XCN_OID_SERIALIZED: CERTENROLL_OBJECTID = 213i32;\npub const XCN_OID_SERVER_GATED_CRYPTO: CERTENROLL_OBJECTID = 257i32;\npub const XCN_OID_SGC_NETSCAPE: CERTENROLL_OBJECTID = 258i32;\npub const XCN_OID_SORTED_CTL: CERTENROLL_OBJECTID = 212i32;\npub const XCN_OID_STATE_OR_PROVINCE_NAME: CERTENROLL_OBJECTID = 126i32;\npub const XCN_OID_STREET_ADDRESS: CERTENROLL_OBJECTID = 127i32;\npub const XCN_OID_SUBJECT_ALT_NAME: CERTENROLL_OBJECTID = 173i32;\npub const XCN_OID_SUBJECT_ALT_NAME2: CERTENROLL_OBJECTID = 183i32;\npub const XCN_OID_SUBJECT_DIR_ATTRS: CERTENROLL_OBJECTID = 242i32;\npub const XCN_OID_SUBJECT_INFO_ACCESS: CERTENROLL_OBJECTID = 426i32;\npub const XCN_OID_SUBJECT_KEY_IDENTIFIER: CERTENROLL_OBJECTID = 182i32;\npub const XCN_OID_SUPPORTED_APPLICATION_CONTEXT: CERTENROLL_OBJECTID = 148i32;\npub const XCN_OID_SUR_NAME: CERTENROLL_OBJECTID = 122i32;\npub const XCN_OID_TELEPHONE_NUMBER: CERTENROLL_OBJECTID = 138i32;\npub const XCN_OID_TELETEXT_TERMINAL_IDENTIFIER: CERTENROLL_OBJECTID = 140i32;\npub const XCN_OID_TELEX_NUMBER: CERTENROLL_OBJECTID = 139i32;\npub const XCN_OID_TIMESTAMP_TOKEN: CERTENROLL_OBJECTID = 427i32;\npub const XCN_OID_TITLE: CERTENROLL_OBJECTID = 130i32;\npub const XCN_OID_USER_CERTIFICATE: CERTENROLL_OBJECTID = 154i32;\npub const XCN_OID_USER_PASSWORD: CERTENROLL_OBJECTID = 153i32;\npub const XCN_OID_VERISIGN_BITSTRING_6_13: CERTENROLL_OBJECTID = 287i32;\npub const XCN_OID_VERISIGN_ISS_STRONG_CRYPTO: CERTENROLL_OBJECTID = 288i32;\npub const XCN_OID_VERISIGN_ONSITE_JURISDICTION_HASH: CERTENROLL_OBJECTID = 286i32;\npub const XCN_OID_VERISIGN_PRIVATE_6_9: CERTENROLL_OBJECTID = 285i32;\npub const XCN_OID_WHQL_CRYPTO: CERTENROLL_OBJECTID = 261i32;\npub const XCN_OID_X21_ADDRESS: CERTENROLL_OBJECTID = 142i32;\npub const XCN_OID_X957: CERTENROLL_OBJECTID = 55i32;\npub const XCN_OID_X957_DSA: CERTENROLL_OBJECTID = 56i32;\npub const XCN_OID_X957_SHA1DSA: CERTENROLL_OBJECTID = 57i32;\npub const XCN_OID_YESNO_TRUST_ATTR: CERTENROLL_OBJECTID = 278i32;\npub const XCN_PROPERTYID_NONE: CERTENROLL_PROPERTYID = 0i32;\npub const XCN_PROV_DH_SCHANNEL: X509ProviderType = 18i32;\npub const XCN_PROV_DSS: X509ProviderType = 3i32;\npub const XCN_PROV_DSS_DH: X509ProviderType = 13i32;\npub const XCN_PROV_EC_ECDSA_FULL: X509ProviderType = 16i32;\npub const XCN_PROV_EC_ECDSA_SIG: X509ProviderType = 14i32;\npub const XCN_PROV_EC_ECNRA_FULL: X509ProviderType = 17i32;\npub const XCN_PROV_EC_ECNRA_SIG: X509ProviderType = 15i32;\npub const XCN_PROV_FORTEZZA: X509ProviderType = 4i32;\npub const XCN_PROV_INTEL_SEC: X509ProviderType = 22i32;\npub const XCN_PROV_MS_EXCHANGE: X509ProviderType = 5i32;\npub const XCN_PROV_NONE: X509ProviderType = 0i32;\npub const XCN_PROV_REPLACE_OWF: X509ProviderType = 23i32;\npub const XCN_PROV_RNG: X509ProviderType = 21i32;\npub const XCN_PROV_RSA_AES: X509ProviderType = 24i32;\npub const XCN_PROV_RSA_FULL: X509ProviderType = 1i32;\npub const XCN_PROV_RSA_SCHANNEL: X509ProviderType = 12i32;\npub const XCN_PROV_RSA_SIG: X509ProviderType = 2i32;\npub const XCN_PROV_SPYRUS_LYNKS: X509ProviderType = 20i32;\npub const XCN_PROV_SSL: X509ProviderType = 6i32;\npub const XECI_AUTOENROLL: u32 = 2u32;\npub const XECI_CERTREQ: u32 = 4u32;\npub const XECI_DISABLE: u32 = 0u32;\npub const XECI_REQWIZARD: u32 = 3u32;\npub const XECI_XENROLL: u32 = 1u32;\npub const XECP_STRING_PROPERTY: u32 = 1u32;\npub const XECR_CMC: CERT_CREATE_REQUEST_FLAGS = 3i32;\npub const XECR_PKCS10_V1_5: CERT_CREATE_REQUEST_FLAGS = 4i32;\npub const XECR_PKCS10_V2_0: CERT_CREATE_REQUEST_FLAGS = 1i32;\npub const XECR_PKCS7: CERT_CREATE_REQUEST_FLAGS = 2i32;\npub const XECT_EXTENSION_V1: ADDED_CERT_TYPE = 1i32;\npub const XECT_EXTENSION_V2: ADDED_CERT_TYPE = 2i32;\npub type XEKL_KEYSIZE = i32;\npub const XEKL_KEYSIZE_DEFAULT: u32 = 4u32;\npub const XEKL_KEYSIZE_INC: XEKL_KEYSIZE = 3i32;\npub const XEKL_KEYSIZE_MAX: XEKL_KEYSIZE = 2i32;\npub const XEKL_KEYSIZE_MIN: XEKL_KEYSIZE = 1i32;\npub type XEKL_KEYSPEC = i32;\npub const XEKL_KEYSPEC_KEYX: XEKL_KEYSPEC = 1i32;\npub const XEKL_KEYSPEC_SIG: XEKL_KEYSPEC = 2i32;\npub const XEPR_CADNS: PENDING_REQUEST_DESIRED_PROPERTY = 1i32;\npub const XEPR_CAFRIENDLYNAME: PENDING_REQUEST_DESIRED_PROPERTY = 3i32;\npub const XEPR_CANAME: PENDING_REQUEST_DESIRED_PROPERTY = 2i32;\npub const XEPR_DATE: u32 = 5u32;\npub const XEPR_ENUM_FIRST: i32 = -1i32;\npub const XEPR_HASH: PENDING_REQUEST_DESIRED_PROPERTY = 8i32;\npub const XEPR_REQUESTID: PENDING_REQUEST_DESIRED_PROPERTY = 4i32;\npub const XEPR_TEMPLATENAME: u32 = 6u32;\npub const XEPR_V1TEMPLATENAME: u32 = 9u32;\npub const XEPR_V2TEMPLATEOID: u32 = 16u32;\npub const XEPR_VERSION: u32 = 7u32;\npub const dwCAXCHGOVERLAPPERIODCOUNTDEFAULT: u32 = 1u32;\npub const dwCAXCHGVALIDITYPERIODCOUNTDEFAULT: u32 = 1u32;\npub const dwCRLDELTAOVERLAPPERIODCOUNTDEFAULT: u32 = 0u32;\npub const dwCRLDELTAPERIODCOUNTDEFAULT: u32 = 1u32;\npub const dwCRLOVERLAPPERIODCOUNTDEFAULT: u32 = 0u32;\npub const dwCRLPERIODCOUNTDEFAULT: u32 = 1u32;\npub const dwVALIDITYPERIODCOUNTDEFAULT_ENTERPRISE: u32 = 2u32;\npub const dwVALIDITYPERIODCOUNTDEFAULT_ROOT: u32 = 5u32;\npub const dwVALIDITYPERIODCOUNTDEFAULT_STANDALONE: u32 = 1u32;\npub const szBACKUPANNOTATION: windows_sys::core::PCSTR = windows_sys::core::s!(\"Cert Server Backup Interface\");\npub const szDBBASENAMEPARM: windows_sys::core::PCSTR = windows_sys::core::s!(\"edb\");\npub const szNAMESEPARATORDEFAULT: windows_sys::core::PCSTR = windows_sys::core::s!(\"\\n\");\npub const szPROPASNTAG: windows_sys::core::PCSTR = windows_sys::core::s!(\"{asn}\");\npub const szRESTOREANNOTATION: windows_sys::core::PCSTR = windows_sys::core::s!(\"Cert Server Restore Interface\");\npub const wszAT_EKCERTINF: windows_sys::core::PCWSTR = windows_sys::core::w!(\"@EKCert\");\npub const wszAT_TESTROOT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"@TestRoot\");\npub const wszCAPOLICYFILE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAPolicy.inf\");\npub const wszCERTEXITMODULE_POSTFIX: windows_sys::core::PCWSTR = windows_sys::core::w!(\".Exit\");\npub const wszCERTIFICATETRANSPARENCYFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateTransparencyFlags\");\npub const wszCERTMANAGE_SUFFIX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Manage\");\npub const wszCERTPOLICYMODULE_POSTFIX: windows_sys::core::PCWSTR = windows_sys::core::w!(\".Policy\");\npub const wszCERT_TYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestType\");\npub const wszCERT_TYPE_CLIENT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Client\");\npub const wszCERT_TYPE_CODESIGN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CodeSign\");\npub const wszCERT_TYPE_CUSTOMER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SetCustomer\");\npub const wszCERT_TYPE_MERCHANT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SetMerchant\");\npub const wszCERT_TYPE_PAYMENT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SetPayment\");\npub const wszCERT_TYPE_SERVER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Server\");\npub const wszCERT_VERSION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Version\");\npub const wszCERT_VERSION_1: windows_sys::core::PCWSTR = windows_sys::core::w!(\"1\");\npub const wszCERT_VERSION_2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"2\");\npub const wszCERT_VERSION_3: windows_sys::core::PCWSTR = windows_sys::core::w!(\"3\");\npub const wszCLASS_CERTADMIN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateAuthority.Admin\");\npub const wszCLASS_CERTCONFIG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateAuthority.Config\");\npub const wszCLASS_CERTDBMEM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateAuthority.DBMem\");\npub const wszCLASS_CERTENCODE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateAuthority.Encode\");\npub const wszCLASS_CERTGETCONFIG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateAuthority.GetConfig\");\npub const wszCLASS_CERTREQUEST: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateAuthority.Request\");\npub const wszCLASS_CERTSERVEREXIT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateAuthority.ServerExit\");\npub const wszCLASS_CERTSERVERPOLICY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateAuthority.ServerPolicy\");\npub const wszCLASS_CERTVIEW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateAuthority.View\");\npub const wszCMM_PROP_COPYRIGHT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Copyright\");\npub const wszCMM_PROP_DESCRIPTION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Description\");\npub const wszCMM_PROP_DISPLAY_HWND: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HWND\");\npub const wszCMM_PROP_FILEVER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"File Version\");\npub const wszCMM_PROP_ISMULTITHREADED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IsMultiThreaded\");\npub const wszCMM_PROP_NAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Name\");\npub const wszCMM_PROP_PRODUCTVER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Product Version\");\npub const wszCNGENCRYPTIONALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CNGEncryptionAlgorithm\");\npub const wszCNGHASHALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CNGHashAlgorithm\");\npub const wszCNGPUBLICKEYALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CNGPublicKeyAlgorithm\");\npub const wszCONFIG_AUTHORITY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Authority\");\npub const wszCONFIG_COMMENT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Comment\");\npub const wszCONFIG_COMMONNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CommonName\");\npub const wszCONFIG_CONFIG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Config\");\npub const wszCONFIG_COUNTRY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Country\");\npub const wszCONFIG_DESCRIPTION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Description\");\npub const wszCONFIG_EXCHANGECERTIFICATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ExchangeCertificate\");\npub const wszCONFIG_FLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Flags\");\npub const wszCONFIG_LOCALITY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Locality\");\npub const wszCONFIG_ORGANIZATION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Organization\");\npub const wszCONFIG_ORGUNIT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OrgUnit\");\npub const wszCONFIG_SANITIZEDNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SanitizedName\");\npub const wszCONFIG_SANITIZEDSHORTNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SanitizedShortName\");\npub const wszCONFIG_SERVER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Server\");\npub const wszCONFIG_SHORTNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ShortName\");\npub const wszCONFIG_SIGNATURECERTIFICATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SignatureCertificate\");\npub const wszCONFIG_STATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"State\");\npub const wszCONFIG_WEBENROLLMENTSERVERS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WebEnrollmentServers\");\npub const wszCRLPUBLISHRETRYCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPublishRetryCount\");\npub const wszCRTFILENAMEEXT: windows_sys::core::PCWSTR = windows_sys::core::w!(\".crt\");\npub const wszDATFILENAMEEXT: windows_sys::core::PCWSTR = windows_sys::core::w!(\".dat\");\npub const wszDBBACKUPCERTBACKDAT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"certbkxp.dat\");\npub const wszDBBACKUPSUBDIR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DataBase\");\npub const wszDBFILENAMEEXT: windows_sys::core::PCWSTR = windows_sys::core::w!(\".edb\");\npub const wszENCRYPTIONALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EncryptionAlgorithm\");\npub const wszENROLLMENTAGENTRIGHTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnrollmentAgentRights\");\npub const wszHASHALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HashAlgorithm\");\npub const wszINFKEY_ALTERNATESIGNATUREALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AlternateSignatureAlgorithm\");\npub const wszINFKEY_ATTESTPRIVATEKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AttestPrivateKey\");\npub const wszINFKEY_CACAPABILITIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CACapabilities\");\npub const wszINFKEY_CACERTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CACerts\");\npub const wszINFKEY_CATHUMBPRINT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAThumbprint\");\npub const wszINFKEY_CCDPSYNCDELTATIME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SyncDeltaTime\");\npub const wszINFKEY_CHALLENGEPASSWORD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ChallengePassword\");\npub const wszINFKEY_CONTINUE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"_continue_\");\npub const wszINFKEY_CRITICAL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Critical\");\npub const wszINFKEY_CRLDELTAPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLDeltaPeriodUnits\");\npub const wszINFKEY_CRLDELTAPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLDeltaPeriod\");\npub const wszINFKEY_CRLPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPeriodUnits\");\npub const wszINFKEY_CRLPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPeriod\");\npub const wszINFKEY_DIRECTORYNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DirectoryName\");\npub const wszINFKEY_DNS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DNS\");\npub const wszINFKEY_ECCKEYPARAMETERS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EccKeyParameters\");\npub const wszINFKEY_ECCKEYPARAMETERSTYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EccKeyParametersType\");\npub const wszINFKEY_ECCKEYPARAMETERS_A: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EccKeyParameters_A\");\npub const wszINFKEY_ECCKEYPARAMETERS_B: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EccKeyParameters_B\");\npub const wszINFKEY_ECCKEYPARAMETERS_BASE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EccKeyParameters_Base\");\npub const wszINFKEY_ECCKEYPARAMETERS_COFACTOR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EccKeyParameters_Cofactor\");\npub const wszINFKEY_ECCKEYPARAMETERS_ORDER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EccKeyParameters_Order\");\npub const wszINFKEY_ECCKEYPARAMETERS_P: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EccKeyParameters_P\");\npub const wszINFKEY_ECCKEYPARAMETERS_SEED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EccKeyParameters_Seed\");\npub const wszINFKEY_EMAIL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EMail\");\npub const wszINFKEY_EMPTY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Empty\");\npub const wszINFKEY_ENABLEKEYCOUNTING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnableKeyCounting\");\npub const wszINFKEY_ENCRYPTIONALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EncryptionAlgorithm\");\npub const wszINFKEY_ENCRYPTIONLENGTH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EncryptionLength\");\npub const wszINFKEY_EXCLUDE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Exclude\");\npub const wszINFKEY_EXPORTABLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Exportable\");\npub const wszINFKEY_EXPORTABLEENCRYPTED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ExportableEncrypted\");\npub const wszINFKEY_FLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Flags\");\npub const wszINFKEY_FORCEUTF8: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ForceUTF8\");\npub const wszINFKEY_FRIENDLYNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FriendlyName\");\npub const wszINFKEY_HASHALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HashAlgorithm\");\npub const wszINFKEY_INCLUDE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Include\");\npub const wszINFKEY_INHIBITPOLICYMAPPING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"InhibitPolicyMapping\");\npub const wszINFKEY_IPADDRESS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IPAddress\");\npub const wszINFKEY_KEYALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyAlgorithm\");\npub const wszINFKEY_KEYALGORITHMPARMETERS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyAlgorithmParameters\");\npub const wszINFKEY_KEYCONTAINER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyContainer\");\npub const wszINFKEY_KEYLENGTH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyLength\");\npub const wszINFKEY_KEYPROTECTION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyProtection\");\npub const wszINFKEY_KEYUSAGEEXTENSION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyUsage\");\npub const wszINFKEY_KEYUSAGEPROPERTY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyUsageProperty\");\npub const wszINFKEY_LEGACYKEYSPEC: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeySpec\");\npub const wszINFKEY_LOADDEFAULTTEMPLATES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LoadDefaultTemplates\");\npub const wszINFKEY_MACHINEKEYSET: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MachineKeySet\");\npub const wszINFKEY_NOTAFTER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NotAfter\");\npub const wszINFKEY_NOTBEFORE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NotBefore\");\npub const wszINFKEY_NOTICE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Notice\");\npub const wszINFKEY_OID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OID\");\npub const wszINFKEY_OTHERNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OtherName\");\npub const wszINFKEY_PATHLENGTH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PathLength\");\npub const wszINFKEY_POLICIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Policies\");\npub const wszINFKEY_PRIVATEKEYARCHIVE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PrivateKeyArchive\");\npub const wszINFKEY_PROVIDERNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ProviderName\");\npub const wszINFKEY_PROVIDERTYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ProviderType\");\npub const wszINFKEY_PUBLICKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PublicKey\");\npub const wszINFKEY_PUBLICKEYPARAMETERS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PublicKeyParameters\");\npub const wszINFKEY_READERNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ReaderName\");\npub const wszINFKEY_REGISTEREDID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RegisteredId\");\npub const wszINFKEY_RENEWALCERT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RenewalCert\");\npub const wszINFKEY_RENEWALKEYLENGTH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RenewalKeyLength\");\npub const wszINFKEY_RENEWALVALIDITYPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RenewalValidityPeriodUnits\");\npub const wszINFKEY_RENEWALVALIDITYPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RenewalValidityPeriod\");\npub const wszINFKEY_REQUESTTYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestType\");\npub const wszINFKEY_REQUIREEXPLICITPOLICY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequireExplicitPolicy\");\npub const wszINFKEY_SECURITYDESCRIPTOR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SecurityDescriptor\");\npub const wszINFKEY_SERIALNUMBER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SerialNumber\");\npub const wszINFKEY_SHOWALLCSPS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ShowAllCSPs\");\npub const wszINFKEY_SILENT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Silent\");\npub const wszINFKEY_SMIME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SMIME\");\npub const wszINFKEY_SUBJECT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Subject\");\npub const wszINFKEY_SUBJECTNAMEFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubjectNameFlags\");\npub const wszINFKEY_SUBTREE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubTree\");\npub const wszINFKEY_SUPPRESSDEFAULTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SuppressDefaults\");\npub const wszINFKEY_UICONTEXTMESSAGE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UIContextMessage\");\npub const wszINFKEY_UPN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UPN\");\npub const wszINFKEY_URL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"URL\");\npub const wszINFKEY_USEEXISTINGKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UseExistingKeySet\");\npub const wszINFKEY_USERPROTECTED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UserProtected\");\npub const wszINFKEY_UTF8: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UTF8\");\npub const wszINFKEY_X500NAMEFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"X500NameFlags\");\npub const wszINFSECTION_AIA: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AuthorityInformationAccess\");\npub const wszINFSECTION_APPLICATIONPOLICYCONSTRAINTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ApplicationPolicyConstraintsExtension\");\npub const wszINFSECTION_APPLICATIONPOLICYMAPPINGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ApplicationPolicyMappingsExtension\");\npub const wszINFSECTION_APPLICATIONPOLICYSTATEMENT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ApplicationPolicyStatementExtension\");\npub const wszINFSECTION_BASICCONSTRAINTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BasicConstraintsExtension\");\npub const wszINFSECTION_CAPOLICY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAPolicy\");\npub const wszINFSECTION_CCDP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CrossCertificateDistributionPointsExtension\");\npub const wszINFSECTION_CDP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLDistributionPoint\");\npub const wszINFSECTION_CERTSERVER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"certsrv_server\");\npub const wszINFSECTION_EKU: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnhancedKeyUsageExtension\");\npub const wszINFSECTION_EXTENSIONS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Extensions\");\npub const wszINFSECTION_NAMECONSTRAINTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NameConstraintsExtension\");\npub const wszINFSECTION_NEWREQUEST: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NewRequest\");\npub const wszINFSECTION_POLICYCONSTRAINTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PolicyConstraintsExtension\");\npub const wszINFSECTION_POLICYMAPPINGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PolicyMappingsExtension\");\npub const wszINFSECTION_POLICYSTATEMENT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PolicyStatementExtension\");\npub const wszINFSECTION_PROPERTIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Properties\");\npub const wszINFSECTION_REQUESTATTRIBUTES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestAttributes\");\npub const wszINFVALUE_ENDORSEMENTKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EndorsementKey\");\npub const wszINFVALUE_REQUESTTYPE_CERT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Cert\");\npub const wszINFVALUE_REQUESTTYPE_CMC: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CMC\");\npub const wszINFVALUE_REQUESTTYPE_PKCS10: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PKCS10\");\npub const wszINFVALUE_REQUESTTYPE_PKCS7: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PKCS7\");\npub const wszINFVALUE_REQUESTTYPE_SCEP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SCEP\");\npub const wszLDAPSESSIONOPTIONVALUE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LDAPSessionOptionValue\");\npub const wszLOCALIZEDTIMEPERIODUNITS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LocalizedTimePeriodUnits\");\npub const wszLOGFILENAMEEXT: windows_sys::core::PCWSTR = windows_sys::core::w!(\".log\");\npub const wszLOGPATH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertLog\");\npub const wszMACHINEKEYSET: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MachineKeyset\");\npub const wszMICROSOFTCERTMODULE_PREFIX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateAuthority_MicrosoftDefault\");\npub const wszNETSCAPEREVOCATIONTYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Netscape\");\npub const wszOCSPCAPROP_CACERTIFICATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CACertificate\");\npub const wszOCSPCAPROP_CACONFIG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAConfig\");\npub const wszOCSPCAPROP_CSPNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CSPName\");\npub const wszOCSPCAPROP_ERRORCODE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ErrorCode\");\npub const wszOCSPCAPROP_HASHALGORITHMID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HashAlgorithmId\");\npub const wszOCSPCAPROP_KEYSPEC: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeySpec\");\npub const wszOCSPCAPROP_LOCALREVOCATIONINFORMATION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LocalRevocationInformation\");\npub const wszOCSPCAPROP_PROVIDERCLSID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ProviderCLSID\");\npub const wszOCSPCAPROP_PROVIDERPROPERTIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Provider\");\npub const wszOCSPCAPROP_REMINDERDURATION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ReminderDuration\");\npub const wszOCSPCAPROP_SIGNINGCERTIFICATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SigningCertificate\");\npub const wszOCSPCAPROP_SIGNINGCERTIFICATETEMPLATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SigningCertificateTemplate\");\npub const wszOCSPCAPROP_SIGNINGFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SigningFlags\");\npub const wszOCSPCOMMONPROP_MAXINCOMINGMESSAGESIZE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MaxIncomingMessageSize\");\npub const wszOCSPCOMMONPROP_MAXNUMOFREQUESTENTRIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MaxNumOfRequestEntries\");\npub const wszOCSPCOMMONPROP_REQFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestFlags\");\npub const wszOCSPISAPIPROP_DEBUG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ISAPIDebug\");\npub const wszOCSPISAPIPROP_MAXAGE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MaxAge\");\npub const wszOCSPISAPIPROP_MAXNUMOFCACHEENTRIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MaxNumOfCacheEntries\");\npub const wszOCSPISAPIPROP_NUMOFBACKENDCONNECTIONS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NumOfBackendConnections\");\npub const wszOCSPISAPIPROP_NUMOFTHREADS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NumOfThreads\");\npub const wszOCSPISAPIPROP_REFRESHRATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RefreshRate\");\npub const wszOCSPISAPIPROP_VIRTUALROOTNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VirtualRootName\");\npub const wszOCSPPROP_ARRAYCONTROLLER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ArrayController\");\npub const wszOCSPPROP_ARRAYMEMBERS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ArrayMembers\");\npub const wszOCSPPROP_AUDITFILTER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AuditFilter\");\npub const wszOCSPPROP_DEBUG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Debug\");\npub const wszOCSPPROP_ENROLLPOLLINTERVAL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnrollPollInterval\");\npub const wszOCSPPROP_LOGLEVEL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LogLevel\");\npub const wszOCSPREVPROP_BASECRL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BaseCrl\");\npub const wszOCSPREVPROP_BASECRLURLS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BaseCrlUrls\");\npub const wszOCSPREVPROP_CRLURLTIMEOUT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CrlUrlTimeOut\");\npub const wszOCSPREVPROP_DELTACRL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DeltaCrl\");\npub const wszOCSPREVPROP_DELTACRLURLS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DeltaCrlUrls\");\npub const wszOCSPREVPROP_ERRORCODE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RevocationErrorCode\");\npub const wszOCSPREVPROP_REFRESHTIMEOUT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RefreshTimeOut\");\npub const wszOCSPREVPROP_SERIALNUMBERSDIRS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IssuedSerialNumbersDirectories\");\npub const wszPERIODDAYS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Days\");\npub const wszPERIODHOURS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Hours\");\npub const wszPERIODMINUTES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Minutes\");\npub const wszPERIODMONTHS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Months\");\npub const wszPERIODSECONDS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Seconds\");\npub const wszPERIODWEEKS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Weeks\");\npub const wszPERIODYEARS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Years\");\npub const wszPFXFILENAMEEXT: windows_sys::core::PCWSTR = windows_sys::core::w!(\".p12\");\npub const wszPROPATTESTATIONCHALLENGE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AttestationChallenge\");\npub const wszPROPATTRIBNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AttributeName\");\npub const wszPROPATTRIBREQUESTID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AttributeRequestId\");\npub const wszPROPATTRIBVALUE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AttributeValue\");\npub const wszPROPCALLERNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CallerName\");\npub const wszPROPCATYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAType\");\npub const wszPROPCERTCLIENTMACHINE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ccm\");\npub const wszPROPCERTCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertCount\");\npub const wszPROPCERTIFICATEENROLLMENTFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnrollmentFlags\");\npub const wszPROPCERTIFICATEGENERALFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"GeneralFlags\");\npub const wszPROPCERTIFICATEHASH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateHash\");\npub const wszPROPCERTIFICATENOTAFTERDATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NotAfter\");\npub const wszPROPCERTIFICATENOTBEFOREDATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NotBefore\");\npub const wszPROPCERTIFICATEPRIVATEKEYFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PrivatekeyFlags\");\npub const wszPROPCERTIFICATEPUBLICKEYALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PublicKeyAlgorithm\");\npub const wszPROPCERTIFICATEPUBLICKEYLENGTH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PublicKeyLength\");\npub const wszPROPCERTIFICATERAWPUBLICKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawPublicKey\");\npub const wszPROPCERTIFICATERAWPUBLICKEYALGORITHMPARAMETERS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawPublicKeyAlgorithmParameters\");\npub const wszPROPCERTIFICATERAWSMIMECAPABILITIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawSMIMECapabilities\");\npub const wszPROPCERTIFICATEREQUESTID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestID\");\npub const wszPROPCERTIFICATESERIALNUMBER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SerialNumber\");\npub const wszPROPCERTIFICATESUBJECTKEYIDENTIFIER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubjectKeyIdentifier\");\npub const wszPROPCERTIFICATETEMPLATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateTemplate\");\npub const wszPROPCERTIFICATETYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateType\");\npub const wszPROPCERTIFICATEUPN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UPN\");\npub const wszPROPCERTSTATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertState\");\npub const wszPROPCERTSUFFIX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertSuffix\");\npub const wszPROPCERTTEMPLATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateTemplate\");\npub const wszPROPCERTTYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertType\");\npub const wszPROPCERTUSAGE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertificateUsage\");\npub const wszPROPCHALLENGE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Challenge\");\npub const wszPROPCLIENTBROWSERMACHINE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"cbm\");\npub const wszPROPCLIENTDCDNS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"cdc\");\npub const wszPROPCOMMONNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CommonName\");\npub const wszPROPCONFIGDN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ConfigDN\");\npub const wszPROPCOUNTRY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Country\");\npub const wszPROPCRITICALTAG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{critical}\");\npub const wszPROPCRLCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLCount\");\npub const wszPROPCRLEFFECTIVE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLEffective\");\npub const wszPROPCRLINDEX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLIndex\");\npub const wszPROPCRLLASTPUBLISHED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLLastPublished\");\npub const wszPROPCRLMINBASE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLMinBase\");\npub const wszPROPCRLNAMEID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLNameId\");\npub const wszPROPCRLNEXTPUBLISH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLNextPublish\");\npub const wszPROPCRLNEXTUPDATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLNextUpdate\");\npub const wszPROPCRLNUMBER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLNumber\");\npub const wszPROPCRLPROPAGATIONCOMPLETE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPropagationComplete\");\npub const wszPROPCRLPUBLISHATTEMPTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPublishAttempts\");\npub const wszPROPCRLPUBLISHERROR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPublishError\");\npub const wszPROPCRLPUBLISHFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPublishFlags\");\npub const wszPROPCRLPUBLISHSTATUSCODE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPublishStatusCode\");\npub const wszPROPCRLRAWCRL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLRawCRL\");\npub const wszPROPCRLROWID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLRowId\");\npub const wszPROPCRLSTATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLState\");\npub const wszPROPCRLSUFFIX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLSuffix\");\npub const wszPROPCRLTHISPUBLISH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLThisPublish\");\npub const wszPROPCRLTHISUPDATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLThisUpdate\");\npub const wszPROPCROSSFOREST: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CrossForest\");\npub const wszPROPDCNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DCName\");\npub const wszPROPDECIMALTAG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{decimal}\");\npub const wszPROPDELTACRLSDISABLED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"fDeltaCRLsDisabled\");\npub const wszPROPDEVICESERIALNUMBER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DeviceSerialNumber\");\npub const wszPROPDISPOSITION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Disposition\");\npub const wszPROPDISPOSITIONDENY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Deny\");\npub const wszPROPDISPOSITIONPENDING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Pending\");\npub const wszPROPDISTINGUISHEDNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DistinguishedName\");\npub const wszPROPDN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"dn\");\npub const wszPROPDNS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"dns\");\npub const wszPROPDOMAINCOMPONENT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DomainComponent\");\npub const wszPROPDOMAINDN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DomainDN\");\npub const wszPROPEMAIL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EMail\");\npub const wszPROPENDORSEMENTCERTIFICATEHASH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EndorsementCertificateHash\");\npub const wszPROPENDORSEMENTKEYHASH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EndorsementKeyHash\");\npub const wszPROPEVENTLOGERROR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EventLogError\");\npub const wszPROPEVENTLOGEXHAUSTIVE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EventLogExhaustive\");\npub const wszPROPEVENTLOGTERSE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EventLogTerse\");\npub const wszPROPEVENTLOGVERBOSE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EventLogVerbose\");\npub const wszPROPEVENTLOGWARNING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EventLogWarning\");\npub const wszPROPEXITCERTFILE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertFile\");\npub const wszPROPEXPECTEDCHALLENGE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ExpectedChallenge\");\npub const wszPROPEXPIRATIONDATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ExpirationDate\");\npub const wszPROPEXTFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ExtensionFlags\");\npub const wszPROPEXTNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ExtensionName\");\npub const wszPROPEXTRAWVALUE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ExtensionRawValue\");\npub const wszPROPEXTREQUESTID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ExtensionRequestId\");\npub const wszPROPFILETAG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{file}\");\npub const wszPROPGIVENNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"GivenName\");\npub const wszPROPGUID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"guid\");\npub const wszPROPHEXTAG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{hex}\");\npub const wszPROPINITIALS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Initials\");\npub const wszPROPIPADDRESS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ipaddress\");\npub const wszPROPKEYARCHIVED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyArchived\");\npub const wszPROPLOCALITY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Locality\");\npub const wszPROPLOGLEVEL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LogLevel\");\npub const wszPROPMACHINEDNSNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MachineDNSName\");\npub const wszPROPMODULEREGLOC: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ModuleRegistryLocation\");\npub const wszPROPNAMETYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NameType\");\npub const wszPROPOCTETTAG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{octet}\");\npub const wszPROPOFFICER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Officer\");\npub const wszPROPOID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"oid\");\npub const wszPROPORGANIZATION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Organization\");\npub const wszPROPORGUNIT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OrgUnit\");\npub const wszPROPPUBLISHEXPIREDCERTINCRL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PublishExpiredCertInCRL\");\npub const wszPROPRAWCACERTIFICATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawCACertificate\");\npub const wszPROPRAWCERTIFICATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawCertificate\");\npub const wszPROPRAWCRL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawCRL\");\npub const wszPROPRAWDELTACRL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawDeltaCRL\");\npub const wszPROPRAWNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawName\");\npub const wszPROPRAWPRECERTIFICATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawPrecertificate\");\npub const wszPROPREQUESTARCHIVEDKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ArchivedKey\");\npub const wszPROPREQUESTATTRIBUTES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestAttributes\");\npub const wszPROPREQUESTCSPPROVIDER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestCSPProvider\");\npub const wszPROPREQUESTDISPOSITION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Disposition\");\npub const wszPROPREQUESTDISPOSITIONMESSAGE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DispositionMessage\");\npub const wszPROPREQUESTDOT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Request.\");\npub const wszPROPREQUESTERCAACCESS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequesterCAAccess\");\npub const wszPROPREQUESTERDN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequesterDN\");\npub const wszPROPREQUESTERNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequesterName\");\npub const wszPROPREQUESTERNAMEFROMOLDCERTIFICATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequesterNameFromOldCertificate\");\npub const wszPROPREQUESTERSAMNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequesterSAMName\");\npub const wszPROPREQUESTERUPN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequesterUPN\");\npub const wszPROPREQUESTFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestFlags\");\npub const wszPROPREQUESTKEYRECOVERYHASHES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyRecoveryHashes\");\npub const wszPROPREQUESTMACHINEDNS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"rmd\");\npub const wszPROPREQUESTOSVERSION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestOSVersion\");\npub const wszPROPREQUESTRAWARCHIVEDKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawArchivedKey\");\npub const wszPROPREQUESTRAWOLDCERTIFICATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawOldCertificate\");\npub const wszPROPREQUESTRAWREQUEST: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RawRequest\");\npub const wszPROPREQUESTREQUESTID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestID\");\npub const wszPROPREQUESTRESOLVEDWHEN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ResolvedWhen\");\npub const wszPROPREQUESTREVOKEDEFFECTIVEWHEN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RevokedEffectiveWhen\");\npub const wszPROPREQUESTREVOKEDREASON: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RevokedReason\");\npub const wszPROPREQUESTREVOKEDWHEN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RevokedWhen\");\npub const wszPROPREQUESTSTATUSCODE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"StatusCode\");\npub const wszPROPREQUESTSUBMITTEDWHEN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubmittedWhen\");\npub const wszPROPREQUESTTYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestType\");\npub const wszPROPSANITIZEDCANAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SanitizedCAName\");\npub const wszPROPSANITIZEDSHORTNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SanitizedShortName\");\npub const wszPROPSEAUDITFILTER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SEAuditFilter\");\npub const wszPROPSEAUDITID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SEAuditId\");\npub const wszPROPSERVERUPGRADED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"fServerUpgraded\");\npub const wszPROPSESSIONCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SessionCount\");\npub const wszPROPSIGNERAPPLICATIONPOLICIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SignerApplicationPolicies\");\npub const wszPROPSIGNERPOLICIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SignerPolicies\");\npub const wszPROPSTATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"State\");\npub const wszPROPSTREETADDRESS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"StreetAddress\");\npub const wszPROPSUBJECTALTNAME2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"san\");\npub const wszPROPSUBJECTDOT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Subject.\");\npub const wszPROPSURNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SurName\");\npub const wszPROPTEMPLATECHANGESEQUENCENUMBER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TemplateChangeSequenceNumber\");\npub const wszPROPTEXTTAG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{text}\");\npub const wszPROPTITLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Title\");\npub const wszPROPUNSTRUCTUREDADDRESS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UnstructuredAddress\");\npub const wszPROPUNSTRUCTUREDNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UnstructuredName\");\npub const wszPROPUPN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"upn\");\npub const wszPROPURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"url\");\npub const wszPROPUSEDS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"fUseDS\");\npub const wszPROPUSERDN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UserDN\");\npub const wszPROPUTF8TAG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"{utf8}\");\npub const wszPROPVALIDITYPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ValidityPeriodUnits\");\npub const wszPROPVALIDITYPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ValidityPeriod\");\npub const wszPROPVOLATILEMODE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VolatileMode\");\npub const wszREGACTIVE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Active\");\npub const wszREGAELOGLEVEL_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AEEventLogLevel\");\npub const wszREGAIKCLOUDCAURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AIKCloudCAURL\");\npub const wszREGAIKKEYALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AIKKeyAlgorithm\");\npub const wszREGAIKKEYLENGTH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AIKKeyLength\");\npub const wszREGALLPROVIDERS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"All\");\npub const wszREGALTERNATEPUBLISHDOMAINS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AlternatePublishDomains\");\npub const wszREGALTERNATESIGNATUREALGORITHM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AlternateSignatureAlgorithm\");\npub const wszREGAUDITFILTER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AuditFilter\");\npub const wszREGB2ICERTMANAGEMODULE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ICertManageModule\");\npub const wszREGBACKUPLOGDIRECTORY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BackupLogDirectory\");\npub const wszREGCACERTFILENAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CACertFileName\");\npub const wszREGCACERTHASH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CACertHash\");\npub const wszREGCACERTPUBLICATIONURLS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CACertPublicationURLs\");\npub const wszREGCADESCRIPTION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CADescription\");\npub const wszREGCAPATHLENGTH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAPathLength\");\npub const wszREGCASECURITY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Security\");\npub const wszREGCASERIALNUMBER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CACertSerialNumber\");\npub const wszREGCASERVERNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAServerName\");\npub const wszREGCATYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAType\");\npub const wszREGCAUSEDS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UseDS\");\npub const wszREGCAXCHGCERTHASH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAXchgCertHash\");\npub const wszREGCAXCHGOVERLAPPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAXchgOverlapPeriodUnits\");\npub const wszREGCAXCHGOVERLAPPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAXchgOverlapPeriod\");\npub const wszREGCAXCHGVALIDITYPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAXchgValidityPeriodUnits\");\npub const wszREGCAXCHGVALIDITYPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CAXchgValidityPeriod\");\npub const wszREGCERTENROLLCOMPATIBLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertEnrollCompatible\");\npub const wszREGCERTIFICATETRANSPARENCYINFOOID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CTInformationExtensionOid\");\npub const wszREGCERTPUBLISHFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PublishCertFlags\");\npub const wszREGCERTSRVDEBUG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Debug\");\npub const wszREGCHECKPOINTFILE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CheckPointFile\");\npub const wszREGCLOCKSKEWMINUTES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ClockSkewMinutes\");\npub const wszREGCOMMONNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CommonName\");\npub const wszREGCRLATTEMPTREPUBLISH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLAttemptRepublish\");\npub const wszREGCRLDELTANEXTPUBLISH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLDeltaNextPublish\");\npub const wszREGCRLDELTAOVERLAPPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLDeltaOverlapUnits\");\npub const wszREGCRLDELTAOVERLAPPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLDeltaOverlapPeriod\");\npub const wszREGCRLDELTAPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLDeltaPeriodUnits\");\npub const wszREGCRLDELTAPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLDeltaPeriod\");\npub const wszREGCRLEDITFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLEditFlags\");\npub const wszREGCRLFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLFlags\");\npub const wszREGCRLNEXTPUBLISH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLNextPublish\");\npub const wszREGCRLOVERLAPPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLOverlapUnits\");\npub const wszREGCRLOVERLAPPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLOverlapPeriod\");\npub const wszREGCRLPATH_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPath\");\npub const wszREGCRLPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPeriodUnits\");\npub const wszREGCRLPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPeriod\");\npub const wszREGCRLPUBLICATIONURLS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLPublicationURLs\");\npub const wszREGDATABASERECOVERED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DatabaseRecovered\");\npub const wszREGDBDIRECTORY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBDirectory\");\npub const wszREGDBFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBFlags\");\npub const wszREGDBLASTFULLBACKUP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBLastFullBackup\");\npub const wszREGDBLASTINCREMENTALBACKUP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBLastIncrementalBackup\");\npub const wszREGDBLASTRECOVERY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBLastRecovery\");\npub const wszREGDBLOGDIRECTORY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBLogDirectory\");\npub const wszREGDBMAXREADSESSIONCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBMaxReadSessionCount\");\npub const wszREGDBSESSIONCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBSessionCount\");\npub const wszREGDBSYSDIRECTORY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBSystemDirectory\");\npub const wszREGDBTEMPDIRECTORY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBTempDirectory\");\npub const wszREGDEFAULTSMIME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DefaultSMIME\");\npub const wszREGDIRECTORY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ConfigurationDirectory\");\npub const wszREGDISABLEEXTENSIONLIST: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DisableExtensionList\");\npub const wszREGDSCONFIGDN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DSConfigDN\");\npub const wszREGDSDOMAINDN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DSDomainDN\");\npub const wszREGEDITFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EditFlags\");\npub const wszREGEKPUBLISTDIRECTORIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EndorsementKeyListDirectories\");\npub const wszREGEKUOIDSFORPUBLISHEXPIREDCERTINCRL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EKUOIDsForPublishExpiredCertInCRL\");\npub const wszREGEKUOIDSFORVOLATILEREQUESTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EKUOIDsforVolatileRequests\");\npub const wszREGENABLED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Enabled\");\npub const wszREGENABLEDEKUFORDEFINEDCACERT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnabledEKUForDefinedCACert\");\npub const wszREGENABLEENROLLEEREQUESTEXTENSIONLIST: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnableEnrolleeRequestExtensionList\");\npub const wszREGENABLEREQUESTEXTENSIONLIST: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnableRequestExtensionList\");\npub const wszREGENFORCEX500NAMELENGTHS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnforceX500NameLengths\");\npub const wszREGENROLLFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EnrollFlags\");\npub const wszREGEXITBODYARG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BodyArg\");\npub const wszREGEXITBODYFORMAT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BodyFormat\");\npub const wszREGEXITCRLISSUEDKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CRLIssued\");\npub const wszREGEXITDENIEDKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Denied\");\npub const wszREGEXITIMPORTEDKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Imported\");\npub const wszREGEXITISSUEDKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Issued\");\npub const wszREGEXITPENDINGKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Pending\");\npub const wszREGEXITPROPNOTFOUND: windows_sys::core::PCWSTR = windows_sys::core::w!(\"???\");\npub const wszREGEXITREVOKEDKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Revoked\");\npub const wszREGEXITSHUTDOWNKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Shutdown\");\npub const wszREGEXITSMTPAUTHENTICATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SMTPAuthenticate\");\npub const wszREGEXITSMTPCC: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Cc\");\npub const wszREGEXITSMTPEVENTFILTER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EventFilter\");\npub const wszREGEXITSMTPFROM: windows_sys::core::PCWSTR = windows_sys::core::w!(\"From\");\npub const wszREGEXITSMTPKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SMTP\");\npub const wszREGEXITSMTPSERVER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SMTPServer\");\npub const wszREGEXITSMTPTEMPLATES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Templates\");\npub const wszREGEXITSMTPTO: windows_sys::core::PCWSTR = windows_sys::core::w!(\"To\");\npub const wszREGEXITSTARTUPKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Startup\");\npub const wszREGEXITTITLEARG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TitleArg\");\npub const wszREGEXITTITLEFORMAT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TitleFormat\");\npub const wszREGFILEISSUERCERTURL_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FileIssuerCertURL\");\npub const wszREGFILEREVOCATIONCRLURL_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FileRevocationCRLURL\");\npub const wszREGFORCETELETEX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ForceTeletex\");\npub const wszREGFTPISSUERCERTURL_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FTPIssuerCertURL\");\npub const wszREGFTPREVOCATIONCRLURL_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FTPRevocationCRLURL\");\npub const wszREGHIGHLOGNUMBER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HighLogNumber\");\npub const wszREGHIGHSERIAL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HighSerial\");\npub const wszREGINTERFACEFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"InterfaceFlags\");\npub const wszREGISSUERCERTURLFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IssuerCertURLFlags\");\npub const wszREGISSUERCERTURL_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"IssuerCertURL\");\npub const wszREGKEYBASE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SYSTEM\\\\CurrentControlSet\\\\Services\\\\CertSvc\");\npub const wszREGKEYCERTSVCPATH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SYSTEM\\\\CurrentControlSet\\\\Services\\\\CertSvc\");\npub const wszREGKEYCONFIG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Configuration\");\npub const wszREGKEYCSP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CSP\");\npub const wszREGKEYDBPARAMETERS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DBParameters\");\npub const wszREGKEYENCRYPTIONCSP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EncryptionCSP\");\npub const wszREGKEYENROLLMENT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Software\\\\Microsoft\\\\Cryptography\\\\AutoEnrollment\");\npub const wszREGKEYEXITMODULES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ExitModules\");\npub const wszREGKEYGROUPPOLICYENROLLMENT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Software\\\\Policies\\\\Microsoft\\\\Cryptography\\\\AutoEnrollment\");\npub const wszREGKEYNOSYSTEMCERTSVCPATH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CurrentControlSet\\\\Services\\\\CertSvc\");\npub const wszREGKEYPOLICYMODULES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PolicyModules\");\npub const wszREGKEYREPAIR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeyRepair\");\npub const wszREGKEYRESTOREINPROGRESS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RestoreInProgress\");\npub const wszREGKEYSIZE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeySize\");\npub const wszREGKRACERTCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KRACertCount\");\npub const wszREGKRACERTHASH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KRACertHash\");\npub const wszREGKRAFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KRAFlags\");\npub const wszREGLDAPFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LDAPFlags\");\npub const wszREGLDAPISSUERCERTURL_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LDAPIssuerCertURL\");\npub const wszREGLDAPREVOCATIONCRLURL_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LDAPRevocationCRLURL\");\npub const wszREGLDAPREVOCATIONDNTEMPLATE_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LDAPRevocationDNTemplate\");\npub const wszREGLDAPREVOCATIONDN_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LDAPRevocationDN\");\npub const wszREGLDAPSESSIONOPTIONS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LDAPSessionOptions\");\npub const wszREGLOGLEVEL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LogLevel\");\npub const wszREGLOGPATH: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LogPath\");\npub const wszREGLOWLOGNUMBER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LowLogNumber\");\npub const wszREGMAXINCOMINGALLOCSIZE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MaxIncomingAllocSize\");\npub const wszREGMAXINCOMINGMESSAGESIZE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MaxIncomingMessageSize\");\npub const wszREGMAXPENDINGREQUESTDAYS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MaxPendingRequestDays\");\npub const wszREGMAXSCTLISTSIZE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MaxSCTListSize\");\npub const wszREGNAMESEPARATOR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubjectNameSeparator\");\npub const wszREGNETSCAPECERTTYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NetscapeCertType\");\npub const wszREGOFFICERRIGHTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"OfficerRights\");\npub const wszREGPARENTCAMACHINE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ParentCAMachine\");\npub const wszREGPARENTCANAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ParentCAName\");\npub const wszREGPOLICYFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PolicyFlags\");\npub const wszREGPRESERVESCEPDUMMYCERTS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PreserveSCEPDummyCerts\");\npub const wszREGPROCESSINGFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ProcessingFlags\");\npub const wszREGPROVIDER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Provider\");\npub const wszREGPROVIDERTYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ProviderType\");\npub const wszREGREQUESTDISPOSITION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestDisposition\");\npub const wszREGREQUESTFILENAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestFileName\");\npub const wszREGREQUESTID: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestId\");\npub const wszREGREQUESTKEYCONTAINER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestKeyContainer\");\npub const wszREGREQUESTKEYINDEX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequestKeyIndex\");\npub const wszREGRESTOREMAP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RestoreMap\");\npub const wszREGRESTOREMAPCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RestoreMapCount\");\npub const wszREGRESTORESTATUS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RestoreStatus\");\npub const wszREGREVOCATIONCRLURL_OLD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RevocationCRLURL\");\npub const wszREGREVOCATIONTYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RevocationType\");\npub const wszREGREVOCATIONURL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RevocationURL\");\npub const wszREGROLESEPARATIONENABLED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RoleSeparationEnabled\");\npub const wszREGSETUPSTATUS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SetupStatus\");\npub const wszREGSP4DEFAULTCONFIGURATION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DefaultConfiguration\");\npub const wszREGSP4KEYSETNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"KeySetName\");\npub const wszREGSP4NAMES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Names\");\npub const wszREGSP4QUERIES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Queries\");\npub const wszREGSP4SUBJECTNAMESEPARATOR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubjectNameSeparator\");\npub const wszREGSUBJECTALTNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubjectAltName\");\npub const wszREGSUBJECTALTNAME2: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubjectAltName2\");\npub const wszREGSUBJECTTEMPLATE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SubjectTemplate\");\npub const wszREGSYMMETRICKEYSIZE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SymmetricKeySize\");\npub const wszREGUNICODE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Unicode\");\npub const wszREGUPNMAP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UPNMap\");\npub const wszREGUSEDEFINEDCACERTINREQ: windows_sys::core::PCWSTR = windows_sys::core::w!(\"UseDefinedCACertInRequest\");\npub const wszREGVALIDITYPERIODCOUNT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ValidityPeriodUnits\");\npub const wszREGVALIDITYPERIODSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ValidityPeriod\");\npub const wszREGVERIFYFLAGS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"VerifyFlags\");\npub const wszREGVERSION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Version\");\npub const wszREGVIEWAGEMINUTES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ViewAgeMinutes\");\npub const wszREGVIEWIDLEMINUTES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ViewIdleMinutes\");\npub const wszREGWEBCLIENTCAMACHINE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WebClientCAMachine\");\npub const wszREGWEBCLIENTCANAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WebClientCAName\");\npub const wszREGWEBCLIENTCATYPE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WebClientCAType\");\npub const wszSECUREDATTRIBUTES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SignedAttributes\");\npub const wszSERVICE_NAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CertSvc\");\npub const wszzDEFAULTSIGNEDATTRIBUTES: windows_sys::core::PCWSTR = windows_sys::core::w!(\"RequesterName\\u{0}\");\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/System/Com/StructuredStorage/mod.rs",
      "sha256": "c1c8048328457dfb0e351741b1a293cd82b91d450d7fc55c9e2351c5b4639b0d",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn ClearPropVariantArray(rgpropvar : *mut PROPVARIANT, cvars : u32));\nwindows_link::link!(\"ole32.dll\" \"system\" fn CoGetInstanceFromFile(pserverinfo : *const super:: COSERVERINFO, pclsid : *const windows_sys::core::GUID, punkouter : * mut core::ffi::c_void, dwclsctx : super:: CLSCTX, grfmode : u32, pwszname : windows_sys::core::PCWSTR, dwcount : u32, presults : *mut super:: MULTI_QI) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn CoGetInstanceFromIStorage(pserverinfo : *const super:: COSERVERINFO, pclsid : *const windows_sys::core::GUID, punkouter : * mut core::ffi::c_void, dwclsctx : super:: CLSCTX, pstg : * mut core::ffi::c_void, dwcount : u32, presults : *mut super:: MULTI_QI) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn CoGetInterfaceAndReleaseStream(pstm : * mut core::ffi::c_void, iid : *const windows_sys::core::GUID, ppv : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn CreateILockBytesOnHGlobal(hglobal : super::super::super::Foundation:: HGLOBAL, fdeleteonrelease : windows_sys::core::BOOL, pplkbyt : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn CreateStreamOnHGlobal(hglobal : super::super::super::Foundation:: HGLOBAL, fdeleteonrelease : windows_sys::core::BOOL, ppstm : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn FmtIdToPropStgName(pfmtid : *const windows_sys::core::GUID, oszname : windows_sys::core::PWSTR) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"ole32.dll\" \"system\" fn FreePropVariantArray(cvariants : u32, rgvars : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn GetConvertStg(pstg : * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn GetHGlobalFromILockBytes(plkbyt : * mut core::ffi::c_void, phglobal : *mut super::super::super::Foundation:: HGLOBAL) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn GetHGlobalFromStream(pstm : * mut core::ffi::c_void, phglobal : *mut super::super::super::Foundation:: HGLOBAL) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromBooleanVector(prgf : *const windows_sys::core::BOOL, celems : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromBuffer(pv : *const core::ffi::c_void, cb : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromCLSID(clsid : *const windows_sys::core::GUID, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromDoubleVector(prgn : *const f64, celems : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromFileTime(pftin : *const super::super::super::Foundation:: FILETIME, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromFileTimeVector(prgft : *const super::super::super::Foundation:: FILETIME, celems : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromGUIDAsString(guid : *const windows_sys::core::GUID, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromInt16Vector(prgn : *const i16, celems : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromInt32Vector(prgn : *const i32, celems : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromInt64Vector(prgn : *const i64, celems : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromPropVariantVectorElem(propvarin : *const PROPVARIANT, ielem : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromResource(hinst : super::super::super::Foundation:: HINSTANCE, id : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromStringAsVector(psz : windows_sys::core::PCWSTR, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromStringVector(prgsz : *const windows_sys::core::PCWSTR, celems : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromUInt16Vector(prgn : *const u16, celems : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromUInt32Vector(prgn : *const u32, celems : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantFromUInt64Vector(prgn : *const u64, celems : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn InitPropVariantVectorFromPropVariant(propvarsingle : *const PROPVARIANT, ppropvarvector : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn OleConvertIStorageToOLESTREAM(pstg : * mut core::ffi::c_void, lpolestream : *mut OLESTREAM) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"ole32.dll\" \"system\" fn OleConvertIStorageToOLESTREAMEx(pstg : * mut core::ffi::c_void, cfformat : u16, lwidth : i32, lheight : i32, dwsize : u32, pmedium : *const super:: STGMEDIUM, polestm : *mut OLESTREAM) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn OleConvertOLESTREAMToIStorage(lpolestream : *const OLESTREAM, pstg : * mut core::ffi::c_void, ptd : *const super:: DVTARGETDEVICE) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"ole32.dll\" \"system\" fn OleConvertOLESTREAMToIStorageEx(polestm : *const OLESTREAM, pstg : * mut core::ffi::c_void, pcfformat : *mut u16, plwwidth : *mut i32, plheight : *mut i32, pdwsize : *mut u32, pmedium : *mut super:: STGMEDIUM) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn PropStgNameToFmtId(oszname : windows_sys::core::PCWSTR, pfmtid : *mut windows_sys::core::GUID) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantChangeType(ppropvardest : *mut PROPVARIANT, propvarsrc : *const PROPVARIANT, flags : PROPVAR_CHANGE_FLAGS, vt : super::super::Variant:: VARENUM) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"ole32.dll\" \"system\" fn PropVariantClear(pvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantCompareEx(propvar1 : *const PROPVARIANT, propvar2 : *const PROPVARIANT, unit : PROPVAR_COMPARE_UNIT, flags : PROPVAR_COMPARE_FLAGS) -> i32);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"ole32.dll\" \"system\" fn PropVariantCopy(pvardest : *mut PROPVARIANT, pvarsrc : *const PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetBooleanElem(propvar : *const PROPVARIANT, ielem : u32, pfval : *mut windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetDoubleElem(propvar : *const PROPVARIANT, ielem : u32, pnval : *mut f64) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetElementCount(propvar : *const PROPVARIANT) -> u32);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetFileTimeElem(propvar : *const PROPVARIANT, ielem : u32, pftval : *mut super::super::super::Foundation:: FILETIME) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetInt16Elem(propvar : *const PROPVARIANT, ielem : u32, pnval : *mut i16) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetInt32Elem(propvar : *const PROPVARIANT, ielem : u32, pnval : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetInt64Elem(propvar : *const PROPVARIANT, ielem : u32, pnval : *mut i64) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetStringElem(propvar : *const PROPVARIANT, ielem : u32, ppszval : *mut windows_sys::core::PWSTR) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetUInt16Elem(propvar : *const PROPVARIANT, ielem : u32, pnval : *mut u16) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetUInt32Elem(propvar : *const PROPVARIANT, ielem : u32, pnval : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantGetUInt64Elem(propvar : *const PROPVARIANT, ielem : u32, pnval : *mut u64) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToBSTR(propvar : *const PROPVARIANT, pbstrout : *mut windows_sys::core::BSTR) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToBoolean(propvarin : *const PROPVARIANT, pfret : *mut windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToBooleanVector(propvar : *const PROPVARIANT, prgf : *mut windows_sys::core::BOOL, crgf : u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToBooleanVectorAlloc(propvar : *const PROPVARIANT, pprgf : *mut *mut windows_sys::core::BOOL, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToBooleanWithDefault(propvarin : *const PROPVARIANT, fdefault : windows_sys::core::BOOL) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToBuffer(propvar : *const PROPVARIANT, pv : *mut core::ffi::c_void, cb : u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToDouble(propvarin : *const PROPVARIANT, pdblret : *mut f64) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToDoubleVector(propvar : *const PROPVARIANT, prgn : *mut f64, crgn : u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToDoubleVectorAlloc(propvar : *const PROPVARIANT, pprgn : *mut *mut f64, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToDoubleWithDefault(propvarin : *const PROPVARIANT, dbldefault : f64) -> f64);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToFileTime(propvar : *const PROPVARIANT, pstfout : super::super::Variant:: PSTIME_FLAGS, pftout : *mut super::super::super::Foundation:: FILETIME) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToFileTimeVector(propvar : *const PROPVARIANT, prgft : *mut super::super::super::Foundation:: FILETIME, crgft : u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToFileTimeVectorAlloc(propvar : *const PROPVARIANT, pprgft : *mut *mut super::super::super::Foundation:: FILETIME, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToGUID(propvar : *const PROPVARIANT, pguid : *mut windows_sys::core::GUID) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt16(propvarin : *const PROPVARIANT, piret : *mut i16) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt16Vector(propvar : *const PROPVARIANT, prgn : *mut i16, crgn : u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt16VectorAlloc(propvar : *const PROPVARIANT, pprgn : *mut *mut i16, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt16WithDefault(propvarin : *const PROPVARIANT, idefault : i16) -> i16);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt32(propvarin : *const PROPVARIANT, plret : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt32Vector(propvar : *const PROPVARIANT, prgn : *mut i32, crgn : u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt32VectorAlloc(propvar : *const PROPVARIANT, pprgn : *mut *mut i32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt32WithDefault(propvarin : *const PROPVARIANT, ldefault : i32) -> i32);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt64(propvarin : *const PROPVARIANT, pllret : *mut i64) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt64Vector(propvar : *const PROPVARIANT, prgn : *mut i64, crgn : u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt64VectorAlloc(propvar : *const PROPVARIANT, pprgn : *mut *mut i64, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToInt64WithDefault(propvarin : *const PROPVARIANT, lldefault : i64) -> i64);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToString(propvar : *const PROPVARIANT, psz : windows_sys::core::PWSTR, cch : u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToStringAlloc(propvar : *const PROPVARIANT, ppszout : *mut windows_sys::core::PWSTR) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToStringVector(propvar : *const PROPVARIANT, prgsz : *mut windows_sys::core::PWSTR, crgsz : u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToStringVectorAlloc(propvar : *const PROPVARIANT, pprgsz : *mut *mut windows_sys::core::PWSTR, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToStringWithDefault(propvarin : *const PROPVARIANT, pszdefault : windows_sys::core::PCWSTR) -> windows_sys::core::PCWSTR);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt16(propvarin : *const PROPVARIANT, puiret : *mut u16) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt16Vector(propvar : *const PROPVARIANT, prgn : *mut u16, crgn : u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt16VectorAlloc(propvar : *const PROPVARIANT, pprgn : *mut *mut u16, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt16WithDefault(propvarin : *const PROPVARIANT, uidefault : u16) -> u16);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt32(propvarin : *const PROPVARIANT, pulret : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt32Vector(propvar : *const PROPVARIANT, prgn : *mut u32, crgn : u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt32VectorAlloc(propvar : *const PROPVARIANT, pprgn : *mut *mut u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt32WithDefault(propvarin : *const PROPVARIANT, uldefault : u32) -> u32);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt64(propvarin : *const PROPVARIANT, pullret : *mut u64) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt64Vector(propvar : *const PROPVARIANT, prgn : *mut u64, crgn : u32, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt64VectorAlloc(propvar : *const PROPVARIANT, pprgn : *mut *mut u64, pcelem : *mut u32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToUInt64WithDefault(propvarin : *const PROPVARIANT, ulldefault : u64) -> u64);\n#[cfg(all(feature = \"Win32_System_Ole\", feature = \"Win32_System_Variant\"))]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToVariant(ppropvar : *const PROPVARIANT, pvar : *mut super::super::Variant:: VARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn PropVariantToWinRTPropertyValue(propvar : *const PROPVARIANT, riid : *const windows_sys::core::GUID, ppv : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn ReadClassStg(pstg : * mut core::ffi::c_void, pclsid : *mut windows_sys::core::GUID) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn ReadClassStm(pstm : * mut core::ffi::c_void, pclsid : *mut windows_sys::core::GUID) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn ReadFmtUserTypeStg(pstg : * mut core::ffi::c_void, pcf : *mut u16, lplpszusertype : *mut windows_sys::core::PWSTR) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn SetConvertStg(pstg : * mut core::ffi::c_void, fconvert : windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgConvertPropertyToVariant(pprop : *const SERIALIZEDPROPERTYVALUE, codepage : u16, pvar : *mut PROPVARIANT, pma : * mut core::ffi::c_void) -> bool);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgConvertVariantToProperty(pvar : *const PROPVARIANT, codepage : u16, pprop : *mut SERIALIZEDPROPERTYVALUE, pcb : *mut u32, pid : u32, freserved : bool, pcindirect : *mut u32) -> *mut SERIALIZEDPROPERTYVALUE);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgCreateDocfile(pwcsname : windows_sys::core::PCWSTR, grfmode : super:: STGM, reserved : u32, ppstgopen : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgCreateDocfileOnILockBytes(plkbyt : * mut core::ffi::c_void, grfmode : super:: STGM, reserved : u32, ppstgopen : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgCreatePropSetStg(pstorage : * mut core::ffi::c_void, dwreserved : u32, pppropsetstg : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgCreatePropStg(punk : * mut core::ffi::c_void, fmtid : *const windows_sys::core::GUID, pclsid : *const windows_sys::core::GUID, grfflags : u32, dwreserved : u32, pppropstg : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Security\")]\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgCreateStorageEx(pwcsname : windows_sys::core::PCWSTR, grfmode : super:: STGM, stgfmt : STGFMT, grfattrs : u32, pstgoptions : *mut STGOPTIONS, psecuritydescriptor : super::super::super::Security:: PSECURITY_DESCRIPTOR, riid : *const windows_sys::core::GUID, ppobjectopen : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn StgDeserializePropVariant(pprop : *const SERIALIZEDPROPERTYVALUE, cbmax : u32, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgGetIFillLockBytesOnFile(pwcsname : windows_sys::core::PCWSTR, ppflb : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgGetIFillLockBytesOnILockBytes(pilb : * mut core::ffi::c_void, ppflb : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgIsStorageFile(pwcsname : windows_sys::core::PCWSTR) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgIsStorageILockBytes(plkbyt : * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgOpenAsyncDocfileOnIFillLockBytes(pflb : * mut core::ffi::c_void, grfmode : u32, asyncflags : u32, ppstgopen : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"dflayout.dll\" \"system\" fn StgOpenLayoutDocfile(pwcsdfname : windows_sys::core::PCWSTR, grfmode : u32, reserved : u32, ppstgopen : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgOpenPropStg(punk : * mut core::ffi::c_void, fmtid : *const windows_sys::core::GUID, grfflags : u32, dwreserved : u32, pppropstg : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgOpenStorage(pwcsname : windows_sys::core::PCWSTR, pstgpriority : * mut core::ffi::c_void, grfmode : super:: STGM, snbexclude : *const *const u16, reserved : u32, ppstgopen : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Security\")]\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgOpenStorageEx(pwcsname : windows_sys::core::PCWSTR, grfmode : super:: STGM, stgfmt : STGFMT, grfattrs : u32, pstgoptions : *mut STGOPTIONS, psecuritydescriptor : super::super::super::Security:: PSECURITY_DESCRIPTOR, riid : *const windows_sys::core::GUID, ppobjectopen : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgOpenStorageOnILockBytes(plkbyt : * mut core::ffi::c_void, pstgpriority : * mut core::ffi::c_void, grfmode : super:: STGM, snbexclude : *const *const u16, reserved : u32, ppstgopen : *mut * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgPropertyLengthAsVariant(pprop : *const SERIALIZEDPROPERTYVALUE, cbprop : u32, codepage : u16, breserved : u8) -> u32);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn StgSerializePropVariant(ppropvar : *const PROPVARIANT, ppprop : *mut *mut SERIALIZEDPROPERTYVALUE, pcb : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn StgSetTimes(lpszname : windows_sys::core::PCWSTR, pctime : *const super::super::super::Foundation:: FILETIME, patime : *const super::super::super::Foundation:: FILETIME, pmtime : *const super::super::super::Foundation:: FILETIME) -> windows_sys::core::HRESULT);\n#[cfg(all(feature = \"Win32_System_Ole\", feature = \"Win32_System_Variant\"))]\nwindows_link::link!(\"propsys.dll\" \"system\" fn VariantToPropVariant(pvar : *const super::super::Variant:: VARIANT, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_System_Variant\")]\nwindows_link::link!(\"propsys.dll\" \"system\" fn WinRTPropertyValueToPropVariant(punkpropertyvalue : * mut core::ffi::c_void, ppropvar : *mut PROPVARIANT) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn WriteClassStg(pstg : * mut core::ffi::c_void, rclsid : *const windows_sys::core::GUID) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn WriteClassStm(pstm : * mut core::ffi::c_void, rclsid : *const windows_sys::core::GUID) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"ole32.dll\" \"system\" fn WriteFmtUserTypeStg(pstg : * mut core::ffi::c_void, cf : u16, lpszusertype : windows_sys::core::PCWSTR) -> windows_sys::core::HRESULT);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct BSTRBLOB {\n    pub cbSize: u32,\n    pub pData: *mut u8,\n}\nimpl Default for BSTRBLOB {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CABOOL {\n    pub cElems: u32,\n    pub pElems: *mut super::super::super::Foundation::VARIANT_BOOL,\n}\nimpl Default for CABOOL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CABSTR {\n    pub cElems: u32,\n    pub pElems: *mut windows_sys::core::BSTR,\n}\nimpl Default for CABSTR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CABSTRBLOB {\n    pub cElems: u32,\n    pub pElems: *mut BSTRBLOB,\n}\nimpl Default for CABSTRBLOB {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAC {\n    pub cElems: u32,\n    pub pElems: windows_sys::core::PSTR,\n}\nimpl Default for CAC {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CACLIPDATA {\n    pub cElems: u32,\n    pub pElems: *mut CLIPDATA,\n}\nimpl Default for CACLIPDATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CACLSID {\n    pub cElems: u32,\n    pub pElems: *mut windows_sys::core::GUID,\n}\nimpl Default for CACLSID {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CACY {\n    pub cElems: u32,\n    pub pElems: *mut super::CY,\n}\nimpl Default for CACY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CADATE {\n    pub cElems: u32,\n    pub pElems: *mut f64,\n}\nimpl Default for CADATE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CADBL {\n    pub cElems: u32,\n    pub pElems: *mut f64,\n}\nimpl Default for CADBL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAFILETIME {\n    pub cElems: u32,\n    pub pElems: *mut super::super::super::Foundation::FILETIME,\n}\nimpl Default for CAFILETIME {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAFLT {\n    pub cElems: u32,\n    pub pElems: *mut f32,\n}\nimpl Default for CAFLT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAH {\n    pub cElems: u32,\n    pub pElems: *mut i64,\n}\nimpl Default for CAH {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAI {\n    pub cElems: u32,\n    pub pElems: *mut i16,\n}\nimpl Default for CAI {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAL {\n    pub cElems: u32,\n    pub pElems: *mut i32,\n}\nimpl Default for CAL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CALPSTR {\n    pub cElems: u32,\n    pub pElems: *mut windows_sys::core::PSTR,\n}\nimpl Default for CALPSTR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CALPWSTR {\n    pub cElems: u32,\n    pub pElems: *mut windows_sys::core::PWSTR,\n}\nimpl Default for CALPWSTR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_System_Variant\")]\n#[derive(Clone, Copy)]\npub struct CAPROPVARIANT {\n    pub cElems: u32,\n    pub pElems: *mut PROPVARIANT,\n}\n#[cfg(feature = \"Win32_System_Variant\")]\nimpl Default for CAPROPVARIANT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CASCODE {\n    pub cElems: u32,\n    pub pElems: *mut i32,\n}\nimpl Default for CASCODE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAUB {\n    pub cElems: u32,\n    pub pElems: *mut u8,\n}\nimpl Default for CAUB {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAUH {\n    pub cElems: u32,\n    pub pElems: *mut u64,\n}\nimpl Default for CAUH {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAUI {\n    pub cElems: u32,\n    pub pElems: *mut u16,\n}\nimpl Default for CAUI {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CAUL {\n    pub cElems: u32,\n    pub pElems: *mut u32,\n}\nimpl Default for CAUL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CCH_MAX_PROPSTG_NAME: u32 = 31u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CLIPDATA {\n    pub cbSize: u32,\n    pub ulClipFmt: i32,\n    pub pClipData: *mut u8,\n}\nimpl Default for CLIPDATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CWCSTORAGENAME: u32 = 32u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct OLESTREAM {\n    pub lpstbl: *mut OLESTREAMVTBL,\n}\nimpl Default for OLESTREAM {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct OLESTREAMVTBL {\n    pub Get: isize,\n    pub Put: isize,\n}\npub const PIDDI_THUMBNAIL: i32 = 2i32;\npub const PIDDSI_BYTECOUNT: u32 = 4u32;\npub const PIDDSI_CATEGORY: u32 = 2u32;\npub const PIDDSI_COMPANY: u32 = 15u32;\npub const PIDDSI_DOCPARTS: u32 = 13u32;\npub const PIDDSI_HEADINGPAIR: u32 = 12u32;\npub const PIDDSI_HIDDENCOUNT: u32 = 9u32;\npub const PIDDSI_LINECOUNT: u32 = 5u32;\npub const PIDDSI_LINKSDIRTY: u32 = 16u32;\npub const PIDDSI_MANAGER: u32 = 14u32;\npub const PIDDSI_MMCLIPCOUNT: u32 = 10u32;\npub const PIDDSI_NOTECOUNT: u32 = 8u32;\npub const PIDDSI_PARCOUNT: u32 = 6u32;\npub const PIDDSI_PRESFORMAT: u32 = 3u32;\npub const PIDDSI_SCALE: u32 = 11u32;\npub const PIDDSI_SLIDECOUNT: u32 = 7u32;\npub const PIDMSI_COPYRIGHT: i32 = 11i32;\npub const PIDMSI_EDITOR: i32 = 2i32;\npub const PIDMSI_OWNER: i32 = 8i32;\npub const PIDMSI_PRODUCTION: i32 = 10i32;\npub const PIDMSI_PROJECT: i32 = 6i32;\npub const PIDMSI_RATING: i32 = 9i32;\npub const PIDMSI_SEQUENCE_NO: i32 = 5i32;\npub const PIDMSI_SOURCE: i32 = 4i32;\npub const PIDMSI_STATUS: i32 = 7i32;\npub const PIDMSI_STATUS_DRAFT: PIDMSI_STATUS_VALUE = 3i32;\npub const PIDMSI_STATUS_EDIT: PIDMSI_STATUS_VALUE = 5i32;\npub const PIDMSI_STATUS_FINAL: PIDMSI_STATUS_VALUE = 8i32;\npub const PIDMSI_STATUS_INPROGRESS: PIDMSI_STATUS_VALUE = 4i32;\npub const PIDMSI_STATUS_NEW: PIDMSI_STATUS_VALUE = 1i32;\npub const PIDMSI_STATUS_NORMAL: PIDMSI_STATUS_VALUE = 0i32;\npub const PIDMSI_STATUS_OTHER: PIDMSI_STATUS_VALUE = 32767i32;\npub const PIDMSI_STATUS_PRELIM: PIDMSI_STATUS_VALUE = 2i32;\npub const PIDMSI_STATUS_PROOF: PIDMSI_STATUS_VALUE = 7i32;\npub const PIDMSI_STATUS_REVIEW: PIDMSI_STATUS_VALUE = 6i32;\npub type PIDMSI_STATUS_VALUE = i32;\npub const PIDMSI_SUPPLIER: i32 = 3i32;\npub const PIDSI_APPNAME: i32 = 18i32;\npub const PIDSI_AUTHOR: i32 = 4i32;\npub const PIDSI_CHARCOUNT: i32 = 16i32;\npub const PIDSI_COMMENTS: i32 = 6i32;\npub const PIDSI_CREATE_DTM: i32 = 12i32;\npub const PIDSI_DOC_SECURITY: i32 = 19i32;\npub const PIDSI_EDITTIME: i32 = 10i32;\npub const PIDSI_KEYWORDS: i32 = 5i32;\npub const PIDSI_LASTAUTHOR: i32 = 8i32;\npub const PIDSI_LASTPRINTED: i32 = 11i32;\npub const PIDSI_LASTSAVE_DTM: i32 = 13i32;\npub const PIDSI_PAGECOUNT: i32 = 14i32;\npub const PIDSI_REVNUMBER: i32 = 9i32;\npub const PIDSI_SUBJECT: i32 = 3i32;\npub const PIDSI_TEMPLATE: i32 = 7i32;\npub const PIDSI_THUMBNAIL: i32 = 17i32;\npub const PIDSI_TITLE: i32 = 2i32;\npub const PIDSI_WORDCOUNT: i32 = 15i32;\npub const PID_BEHAVIOR: u32 = 2147483651u32;\npub const PID_CODEPAGE: u32 = 1u32;\npub const PID_DICTIONARY: u32 = 0u32;\npub const PID_FIRST_NAME_DEFAULT: u32 = 4095u32;\npub const PID_FIRST_USABLE: u32 = 2u32;\npub const PID_ILLEGAL: u32 = 4294967295u32;\npub const PID_LOCALE: u32 = 2147483648u32;\npub const PID_MAX_READONLY: u32 = 3221225471u32;\npub const PID_MIN_READONLY: u32 = 2147483648u32;\npub const PID_MODIFY_TIME: u32 = 2147483649u32;\npub const PID_SECURITY: u32 = 2147483650u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_System_Variant\")]\n#[derive(Clone, Copy)]\npub struct PROPBAG2 {\n    pub dwType: u32,\n    pub vt: super::super::Variant::VARENUM,\n    pub cfType: u16,\n    pub dwHint: u32,\n    pub pstrName: windows_sys::core::PWSTR,\n    pub clsid: windows_sys::core::GUID,\n}\n#[cfg(feature = \"Win32_System_Variant\")]\nimpl Default for PROPBAG2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const PROPSETFLAG_ANSI: u32 = 2u32;\npub const PROPSETFLAG_CASE_SENSITIVE: u32 = 8u32;\npub const PROPSETFLAG_DEFAULT: u32 = 0u32;\npub const PROPSETFLAG_NONSIMPLE: u32 = 1u32;\npub const PROPSETFLAG_UNBUFFERED: u32 = 4u32;\npub const PROPSETHDR_OSVERSION_UNKNOWN: u32 = 4294967295u32;\npub const PROPSET_BEHAVIOR_CASE_SENSITIVE: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PROPSPEC {\n    pub ulKind: PROPSPEC_KIND,\n    pub Anonymous: PROPSPEC_0,\n}\nimpl Default for PROPSPEC {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union PROPSPEC_0 {\n    pub propid: u32,\n    pub lpwstr: windows_sys::core::PWSTR,\n}\nimpl Default for PROPSPEC_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type PROPSPEC_KIND = u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_System_Variant\")]\n#[derive(Clone, Copy)]\npub struct PROPVARIANT {\n    pub Anonymous: PROPVARIANT_0,\n}\n#[cfg(feature = \"Win32_System_Variant\")]\nimpl Default for PROPVARIANT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_System_Variant\")]\n#[derive(Clone, Copy)]\npub union PROPVARIANT_0 {\n    pub Anonymous: PROPVARIANT_0_0,\n    pub decVal: super::super::super::Foundation::DECIMAL,\n}\n#[cfg(feature = \"Win32_System_Variant\")]\nimpl Default for PROPVARIANT_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_System_Variant\")]\n#[derive(Clone, Copy)]\npub struct PROPVARIANT_0_0 {\n    pub vt: super::super::Variant::VARENUM,\n    pub wReserved1: u16,\n    pub wReserved2: u16,\n    pub wReserved3: u16,\n    pub Anonymous: PROPVARIANT_0_0_0,\n}\n#[cfg(feature = \"Win32_System_Variant\")]\nimpl Default for PROPVARIANT_0_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_System_Variant\")]\n#[derive(Clone, Copy)]\npub union PROPVARIANT_0_0_0 {\n    pub cVal: i8,\n    pub bVal: u8,\n    pub iVal: i16,\n    pub uiVal: u16,\n    pub lVal: i32,\n    pub ulVal: u32,\n    pub intVal: i32,\n    pub uintVal: u32,\n    pub hVal: i64,\n    pub uhVal: u64,\n    pub fltVal: f32,\n    pub dblVal: f64,\n    pub boolVal: super::super::super::Foundation::VARIANT_BOOL,\n    pub __OBSOLETE__VARIANT_BOOL: super::super::super::Foundation::VARIANT_BOOL,\n    pub scode: i32,\n    pub cyVal: super::CY,\n    pub date: f64,\n    pub filetime: super::super::super::Foundation::FILETIME,\n    pub puuid: *mut windows_sys::core::GUID,\n    pub pclipdata: *mut CLIPDATA,\n    pub bstrVal: windows_sys::core::BSTR,\n    pub bstrblobVal: BSTRBLOB,\n    pub blob: super::BLOB,\n    pub pszVal: windows_sys::core::PSTR,\n    pub pwszVal: windows_sys::core::PWSTR,\n    pub punkVal: *mut core::ffi::c_void,\n    pub pdispVal: *mut core::ffi::c_void,\n    pub pStream: *mut core::ffi::c_void,\n    pub pStorage: *mut core::ffi::c_void,\n    pub pVersionedStream: *mut VERSIONEDSTREAM,\n    pub parray: *mut super::SAFEARRAY,\n    pub cac: CAC,\n    pub caub: CAUB,\n    pub cai: CAI,\n    pub caui: CAUI,\n    pub cal: CAL,\n    pub caul: CAUL,\n    pub cah: CAH,\n    pub cauh: CAUH,\n    pub caflt: CAFLT,\n    pub cadbl: CADBL,\n    pub cabool: CABOOL,\n    pub cascode: CASCODE,\n    pub cacy: CACY,\n    pub cadate: CADATE,\n    pub cafiletime: CAFILETIME,\n    pub cauuid: CACLSID,\n    pub caclipdata: CACLIPDATA,\n    pub cabstr: CABSTR,\n    pub cabstrblob: CABSTRBLOB,\n    pub calpstr: CALPSTR,\n    pub calpwstr: CALPWSTR,\n    pub capropvar: CAPROPVARIANT,\n    pub pcVal: windows_sys::core::PSTR,\n    pub pbVal: *mut u8,\n    pub piVal: *mut i16,\n    pub puiVal: *mut u16,\n    pub plVal: *mut i32,\n    pub pulVal: *mut u32,\n    pub pintVal: *mut i32,\n    pub puintVal: *mut u32,\n    pub pfltVal: *mut f32,\n    pub pdblVal: *mut f64,\n    pub pboolVal: *mut super::super::super::Foundation::VARIANT_BOOL,\n    pub pdecVal: *mut super::super::super::Foundation::DECIMAL,\n    pub pscode: *mut i32,\n    pub pcyVal: *mut super::CY,\n    pub pdate: *mut f64,\n    pub pbstrVal: *mut windows_sys::core::BSTR,\n    pub ppunkVal: *mut *mut core::ffi::c_void,\n    pub ppdispVal: *mut *mut core::ffi::c_void,\n    pub pparray: *mut *mut super::SAFEARRAY,\n    pub pvarVal: *mut PROPVARIANT,\n}\n#[cfg(feature = \"Win32_System_Variant\")]\nimpl Default for PROPVARIANT_0_0_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type PROPVAR_CHANGE_FLAGS = i32;\npub type PROPVAR_COMPARE_FLAGS = i32;\npub type PROPVAR_COMPARE_UNIT = i32;\npub const PRSPEC_INVALID: u32 = 4294967295u32;\npub const PRSPEC_LPWSTR: PROPSPEC_KIND = 0u32;\npub const PRSPEC_PROPID: PROPSPEC_KIND = 1u32;\npub const PVCF_DEFAULT: PROPVAR_COMPARE_FLAGS = 0i32;\npub const PVCF_DIGITSASNUMBERS_CASESENSITIVE: PROPVAR_COMPARE_FLAGS = 32i32;\npub const PVCF_TREATEMPTYASGREATERTHAN: PROPVAR_COMPARE_FLAGS = 1i32;\npub const PVCF_USESTRCMP: PROPVAR_COMPARE_FLAGS = 2i32;\npub const PVCF_USESTRCMPC: PROPVAR_COMPARE_FLAGS = 4i32;\npub const PVCF_USESTRCMPI: PROPVAR_COMPARE_FLAGS = 8i32;\npub const PVCF_USESTRCMPIC: PROPVAR_COMPARE_FLAGS = 16i32;\npub const PVCHF_ALPHABOOL: PROPVAR_CHANGE_FLAGS = 2i32;\npub const PVCHF_DEFAULT: PROPVAR_CHANGE_FLAGS = 0i32;\npub const PVCHF_LOCALBOOL: PROPVAR_CHANGE_FLAGS = 8i32;\npub const PVCHF_NOHEXSTRING: PROPVAR_CHANGE_FLAGS = 16i32;\npub const PVCHF_NOUSEROVERRIDE: PROPVAR_CHANGE_FLAGS = 4i32;\npub const PVCHF_NOVALUEPROP: PROPVAR_CHANGE_FLAGS = 1i32;\npub const PVCU_DAY: PROPVAR_COMPARE_UNIT = 4i32;\npub const PVCU_DEFAULT: PROPVAR_COMPARE_UNIT = 0i32;\npub const PVCU_HOUR: PROPVAR_COMPARE_UNIT = 3i32;\npub const PVCU_MINUTE: PROPVAR_COMPARE_UNIT = 2i32;\npub const PVCU_MONTH: PROPVAR_COMPARE_UNIT = 5i32;\npub const PVCU_SECOND: PROPVAR_COMPARE_UNIT = 1i32;\npub const PVCU_YEAR: PROPVAR_COMPARE_UNIT = 6i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct RemSNB {\n    pub ulCntStr: u32,\n    pub ulCntChar: u32,\n    pub rgString: [u16; 1],\n}\nimpl Default for RemSNB {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SERIALIZEDPROPERTYVALUE {\n    pub dwType: u32,\n    pub rgb: [u8; 1],\n}\nimpl Default for SERIALIZEDPROPERTYVALUE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STATPROPSETSTG {\n    pub fmtid: windows_sys::core::GUID,\n    pub clsid: windows_sys::core::GUID,\n    pub grfFlags: u32,\n    pub mtime: super::super::super::Foundation::FILETIME,\n    pub ctime: super::super::super::Foundation::FILETIME,\n    pub atime: super::super::super::Foundation::FILETIME,\n    pub dwOSVersion: u32,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_System_Variant\")]\n#[derive(Clone, Copy)]\npub struct STATPROPSTG {\n    pub lpwstrName: windows_sys::core::PWSTR,\n    pub propid: u32,\n    pub vt: super::super::Variant::VARENUM,\n}\n#[cfg(feature = \"Win32_System_Variant\")]\nimpl Default for STATPROPSTG {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type STGFMT = u32;\npub const STGFMT_ANY: STGFMT = 4u32;\npub const STGFMT_DOCFILE: STGFMT = 5u32;\npub const STGFMT_DOCUMENT: STGFMT = 0u32;\npub const STGFMT_FILE: STGFMT = 3u32;\npub const STGFMT_NATIVE: STGFMT = 1u32;\npub const STGFMT_STORAGE: STGFMT = 0u32;\npub type STGMOVE = i32;\npub const STGMOVE_COPY: STGMOVE = 1i32;\npub const STGMOVE_MOVE: STGMOVE = 0i32;\npub const STGMOVE_SHALLOWCOPY: STGMOVE = 2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STGOPTIONS {\n    pub usVersion: u16,\n    pub reserved: u16,\n    pub ulSectorSize: u32,\n    pub pwcsTemplateFile: windows_sys::core::PCWSTR,\n}\nimpl Default for STGOPTIONS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STGOPTIONS_VERSION: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct VERSIONEDSTREAM {\n    pub guidVersion: windows_sys::core::GUID,\n    pub pStream: *mut core::ffi::c_void,\n}\nimpl Default for VERSIONEDSTREAM {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/System/Ioctl/mod.rs",
      "sha256": "83f1fbce21725031ddd781f8e921ed48c966ff997ccf2d435497f5b9d15e7fa1",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "pub const ABL_5_WO: STORAGE_MEDIA_TYPE = 64i32;\npub const ADR_1: STORAGE_MEDIA_TYPE = 90i32;\npub const ADR_2: STORAGE_MEDIA_TYPE = 91i32;\npub const AIT1_8mm: STORAGE_MEDIA_TYPE = 38i32;\npub const AIT_8mm: STORAGE_MEDIA_TYPE = 89i32;\npub const AME_8mm: STORAGE_MEDIA_TYPE = 37i32;\npub const ASSERT_ALTERNATE: u32 = 9u32;\npub const ASSERT_PRIMARY: u32 = 8u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ASYNC_DUPLICATE_EXTENTS_STATUS {\n    pub Version: u32,\n    pub State: DUPLICATE_EXTENTS_STATE,\n    pub SourceFileOffset: u64,\n    pub TargetFileOffset: u64,\n    pub ByteCount: u64,\n    pub BytesDuplicated: u64,\n}\npub const ATAPI_ID_CMD: u32 = 161u32;\npub const AVATAR_F2: STORAGE_MEDIA_TYPE = 78i32;\npub const AllElements: ELEMENT_TYPE = 0i32;\npub const AtaDataTypeIdentify: STORAGE_PROTOCOL_ATA_DATA_TYPE = 1i32;\npub const AtaDataTypeLogPage: STORAGE_PROTOCOL_ATA_DATA_TYPE = 2i32;\npub const AtaDataTypeUnknown: STORAGE_PROTOCOL_ATA_DATA_TYPE = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct BIN_COUNT {\n    pub BinRange: BIN_RANGE,\n    pub BinCount: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct BIN_RANGE {\n    pub StartValue: i64,\n    pub Length: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct BIN_RESULTS {\n    pub NumberOfBins: u32,\n    pub BinCounts: [BIN_COUNT; 1],\n}\nimpl Default for BIN_RESULTS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type BIN_TYPES = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct BOOT_AREA_INFO {\n    pub BootSectorCount: u32,\n    pub BootSectors: [BOOT_AREA_INFO_0; 2],\n}\nimpl Default for BOOT_AREA_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct BOOT_AREA_INFO_0 {\n    pub Offset: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct BULK_SECURITY_TEST_DATA {\n    pub DesiredAccess: u32,\n    pub SecurityIds: [u32; 1],\n}\nimpl Default for BULK_SECURITY_TEST_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CAP_ATAPI_ID_CMD: u32 = 2u32;\npub const CAP_ATA_ID_CMD: u32 = 1u32;\npub const CAP_SMART_CMD: u32 = 4u32;\npub const CDB_SIZE: u32 = 16u32;\npub const CD_R: STORAGE_MEDIA_TYPE = 52i32;\npub const CD_ROM: STORAGE_MEDIA_TYPE = 51i32;\npub const CD_RW: STORAGE_MEDIA_TYPE = 53i32;\npub const CHANGER_BAR_CODE_SCANNER_INSTALLED: CHANGER_FEATURES = 1u32;\npub const CHANGER_CARTRIDGE_MAGAZINE: CHANGER_FEATURES = 256u32;\npub const CHANGER_CLEANER_ACCESS_NOT_VALID: CHANGER_FEATURES = 262144u32;\npub const CHANGER_CLEANER_AUTODISMOUNT: GET_CHANGER_PARAMETERS_FEATURES1 = 2147483652u32;\npub const CHANGER_CLEANER_OPS_NOT_SUPPORTED: GET_CHANGER_PARAMETERS_FEATURES1 = 2147483712u32;\npub const CHANGER_CLEANER_SLOT: CHANGER_FEATURES = 64u32;\npub const CHANGER_CLOSE_IEPORT: CHANGER_FEATURES = 4u32;\npub type CHANGER_DEVICE_PROBLEM_TYPE = i32;\npub const CHANGER_DEVICE_REINITIALIZE_CAPABLE: CHANGER_FEATURES = 134217728u32;\npub const CHANGER_DRIVE_CLEANING_REQUIRED: CHANGER_FEATURES = 65536u32;\npub const CHANGER_DRIVE_EMPTY_ON_DOOR_ACCESS: CHANGER_FEATURES = 536870912u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CHANGER_ELEMENT {\n    pub ElementType: ELEMENT_TYPE,\n    pub ElementAddress: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CHANGER_ELEMENT_LIST {\n    pub Element: CHANGER_ELEMENT,\n    pub NumberOfElements: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CHANGER_ELEMENT_STATUS {\n    pub Element: CHANGER_ELEMENT,\n    pub SrcElementAddress: CHANGER_ELEMENT,\n    pub Flags: CHANGER_ELEMENT_STATUS_FLAGS,\n    pub ExceptionCode: u32,\n    pub TargetId: u8,\n    pub Lun: u8,\n    pub Reserved: u16,\n    pub PrimaryVolumeID: [u8; 36],\n    pub AlternateVolumeID: [u8; 36],\n}\nimpl Default for CHANGER_ELEMENT_STATUS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CHANGER_ELEMENT_STATUS_EX {\n    pub Element: CHANGER_ELEMENT,\n    pub SrcElementAddress: CHANGER_ELEMENT,\n    pub Flags: CHANGER_ELEMENT_STATUS_FLAGS,\n    pub ExceptionCode: u32,\n    pub TargetId: u8,\n    pub Lun: u8,\n    pub Reserved: u16,\n    pub PrimaryVolumeID: [u8; 36],\n    pub AlternateVolumeID: [u8; 36],\n    pub VendorIdentification: [u8; 8],\n    pub ProductIdentification: [u8; 16],\n    pub SerialNumber: [u8; 32],\n}\nimpl Default for CHANGER_ELEMENT_STATUS_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type CHANGER_ELEMENT_STATUS_FLAGS = u32;\npub const CHANGER_EXCHANGE_MEDIA: CHANGER_FEATURES = 32u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CHANGER_EXCHANGE_MEDIUM {\n    pub Transport: CHANGER_ELEMENT,\n    pub Source: CHANGER_ELEMENT,\n    pub Destination1: CHANGER_ELEMENT,\n    pub Destination2: CHANGER_ELEMENT,\n    pub Flip1: bool,\n    pub Flip2: bool,\n}\npub type CHANGER_FEATURES = u32;\npub const CHANGER_IEPORT_USER_CONTROL_CLOSE: GET_CHANGER_PARAMETERS_FEATURES1 = 2147483904u32;\npub const CHANGER_IEPORT_USER_CONTROL_OPEN: GET_CHANGER_PARAMETERS_FEATURES1 = 2147483776u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CHANGER_INITIALIZE_ELEMENT_STATUS {\n    pub ElementList: CHANGER_ELEMENT_LIST,\n    pub BarCodeScan: bool,\n}\npub const CHANGER_INIT_ELEM_STAT_WITH_RANGE: CHANGER_FEATURES = 2u32;\npub const CHANGER_KEYPAD_ENABLE_DISABLE: CHANGER_FEATURES = 268435456u32;\npub const CHANGER_LOCK_UNLOCK: CHANGER_FEATURES = 128u32;\npub const CHANGER_MEDIUM_FLIP: CHANGER_FEATURES = 512u32;\npub const CHANGER_MOVE_EXTENDS_IEPORT: GET_CHANGER_PARAMETERS_FEATURES1 = 2147484160u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CHANGER_MOVE_MEDIUM {\n    pub Transport: CHANGER_ELEMENT,\n    pub Source: CHANGER_ELEMENT,\n    pub Destination: CHANGER_ELEMENT,\n    pub Flip: bool,\n}\npub const CHANGER_MOVE_RETRACTS_IEPORT: GET_CHANGER_PARAMETERS_FEATURES1 = 2147484672u32;\npub const CHANGER_OPEN_IEPORT: CHANGER_FEATURES = 8u32;\npub const CHANGER_POSITION_TO_ELEMENT: CHANGER_FEATURES = 1024u32;\npub const CHANGER_PREDISMOUNT_ALIGN_TO_DRIVE: GET_CHANGER_PARAMETERS_FEATURES1 = 2147483650u32;\npub const CHANGER_PREDISMOUNT_ALIGN_TO_SLOT: GET_CHANGER_PARAMETERS_FEATURES1 = 2147483649u32;\npub const CHANGER_PREDISMOUNT_EJECT_REQUIRED: CHANGER_FEATURES = 131072u32;\npub const CHANGER_PREMOUNT_EJECT_REQUIRED: CHANGER_FEATURES = 524288u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CHANGER_PRODUCT_DATA {\n    pub VendorId: [u8; 8],\n    pub ProductId: [u8; 16],\n    pub Revision: [u8; 4],\n    pub SerialNumber: [u8; 32],\n    pub DeviceType: u8,\n}\nimpl Default for CHANGER_PRODUCT_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CHANGER_READ_ELEMENT_STATUS {\n    pub ElementList: CHANGER_ELEMENT_LIST,\n    pub VolumeTagInfo: bool,\n}\npub const CHANGER_REPORT_IEPORT_STATE: CHANGER_FEATURES = 2048u32;\npub const CHANGER_RESERVED_BIT: u32 = 2147483648u32;\npub const CHANGER_RTN_MEDIA_TO_ORIGINAL_ADDR: GET_CHANGER_PARAMETERS_FEATURES1 = 2147483680u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CHANGER_SEND_VOLUME_TAG_INFORMATION {\n    pub StartingElement: CHANGER_ELEMENT,\n    pub ActionCode: u32,\n    pub VolumeIDTemplate: [u8; 40],\n}\nimpl Default for CHANGER_SEND_VOLUME_TAG_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CHANGER_SERIAL_NUMBER_VALID: CHANGER_FEATURES = 67108864u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CHANGER_SET_ACCESS {\n    pub Element: CHANGER_ELEMENT,\n    pub Control: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CHANGER_SET_POSITION {\n    pub Transport: CHANGER_ELEMENT,\n    pub Destination: CHANGER_ELEMENT,\n    pub Flip: bool,\n}\npub const CHANGER_SLOTS_USE_TRAYS: GET_CHANGER_PARAMETERS_FEATURES1 = 2147483664u32;\npub const CHANGER_STATUS_NON_VOLATILE: CHANGER_FEATURES = 16u32;\npub const CHANGER_STORAGE_DRIVE: CHANGER_FEATURES = 4096u32;\npub const CHANGER_STORAGE_IEPORT: CHANGER_FEATURES = 8192u32;\npub const CHANGER_STORAGE_SLOT: CHANGER_FEATURES = 16384u32;\npub const CHANGER_STORAGE_TRANSPORT: CHANGER_FEATURES = 32768u32;\npub const CHANGER_TO_DRIVE: u32 = 8u32;\npub const CHANGER_TO_IEPORT: u32 = 4u32;\npub const CHANGER_TO_SLOT: u32 = 2u32;\npub const CHANGER_TO_TRANSPORT: u32 = 1u32;\npub const CHANGER_TRUE_EXCHANGE_CAPABLE: GET_CHANGER_PARAMETERS_FEATURES1 = 2147483656u32;\npub const CHANGER_VOLUME_ASSERT: CHANGER_FEATURES = 4194304u32;\npub const CHANGER_VOLUME_IDENTIFICATION: CHANGER_FEATURES = 1048576u32;\npub const CHANGER_VOLUME_REPLACE: CHANGER_FEATURES = 8388608u32;\npub const CHANGER_VOLUME_SEARCH: CHANGER_FEATURES = 2097152u32;\npub const CHANGER_VOLUME_UNDEFINE: CHANGER_FEATURES = 16777216u32;\npub const CHECKSUM_TYPE_CRC32: u32 = 1u32;\npub const CHECKSUM_TYPE_CRC64: u32 = 2u32;\npub const CHECKSUM_TYPE_ECC: u32 = 3u32;\npub const CHECKSUM_TYPE_FIRST_UNUSED_TYPE: u32 = 5u32;\npub const CHECKSUM_TYPE_NONE: u32 = 0u32;\npub const CHECKSUM_TYPE_SHA256: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CLASS_MEDIA_CHANGE_CONTEXT {\n    pub MediaChangeCount: u32,\n    pub NewState: u32,\n}\npub const CLEANER_CARTRIDGE: STORAGE_MEDIA_TYPE = 50i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CLUSTER_RANGE {\n    pub StartingCluster: i64,\n    pub ClusterCount: i64,\n}\npub const CONTAINER_ROOT_INFO_FLAG_BIND_DO_NOT_MAP_NAME: u32 = 256u32;\npub const CONTAINER_ROOT_INFO_FLAG_BIND_EXCEPTION_ROOT: u32 = 128u32;\npub const CONTAINER_ROOT_INFO_FLAG_BIND_ROOT: u32 = 32u32;\npub const CONTAINER_ROOT_INFO_FLAG_BIND_TARGET_ROOT: u32 = 64u32;\npub const CONTAINER_ROOT_INFO_FLAG_LAYER_ROOT: u32 = 2u32;\npub const CONTAINER_ROOT_INFO_FLAG_SCRATCH_ROOT: u32 = 1u32;\npub const CONTAINER_ROOT_INFO_FLAG_UNION_LAYER_ROOT: u32 = 512u32;\npub const CONTAINER_ROOT_INFO_FLAG_VIRTUALIZATION_EXCEPTION_ROOT: u32 = 16u32;\npub const CONTAINER_ROOT_INFO_FLAG_VIRTUALIZATION_ROOT: u32 = 4u32;\npub const CONTAINER_ROOT_INFO_FLAG_VIRTUALIZATION_TARGET_ROOT: u32 = 8u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CONTAINER_ROOT_INFO_INPUT {\n    pub Flags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CONTAINER_ROOT_INFO_OUTPUT {\n    pub ContainerRootIdLength: u16,\n    pub ContainerRootId: [u8; 1],\n}\nimpl Default for CONTAINER_ROOT_INFO_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CONTAINER_ROOT_INFO_VALID_FLAGS: u32 = 1023u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CONTAINER_VOLUME_STATE {\n    pub Flags: u32,\n}\npub const CONTAINER_VOLUME_STATE_HOSTING_CONTAINER: u32 = 1u32;\npub const COPYFILE_SIS_FLAGS: u32 = 3u32;\npub const COPYFILE_SIS_LINK: u32 = 1u32;\npub const COPYFILE_SIS_REPLACE: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CREATE_DISK {\n    pub PartitionStyle: PARTITION_STYLE,\n    pub Anonymous: CREATE_DISK_0,\n}\nimpl Default for CREATE_DISK {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union CREATE_DISK_0 {\n    pub Mbr: CREATE_DISK_MBR,\n    pub Gpt: CREATE_DISK_GPT,\n}\nimpl Default for CREATE_DISK_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CREATE_DISK_GPT {\n    pub DiskId: windows_sys::core::GUID,\n    pub MaxPartitionCount: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CREATE_DISK_MBR {\n    pub Signature: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CREATE_USN_JOURNAL_DATA {\n    pub MaximumSize: u64,\n    pub AllocationDelta: u64,\n}\npub type CSVFS_DISK_CONNECTIVITY = i32;\npub type CSV_CONTROL_OP = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CSV_CONTROL_PARAM {\n    pub Operation: CSV_CONTROL_OP,\n    pub Unused: i64,\n}\npub const CSV_INVALID_DEVICE_NUMBER: u32 = 4294967295u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CSV_IS_OWNED_BY_CSVFS {\n    pub OwnedByCSVFS: bool,\n}\npub const CSV_MGMTLOCK_CHECK_VOLUME_REDIRECTED: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CSV_MGMT_LOCK {\n    pub Flags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CSV_NAMESPACE_INFO {\n    pub Version: u32,\n    pub DeviceNumber: u32,\n    pub StartingOffset: i64,\n    pub SectorSize: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CSV_QUERY_FILE_REVISION {\n    pub FileId: i64,\n    pub FileRevision: [i64; 3],\n}\nimpl Default for CSV_QUERY_FILE_REVISION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy)]\npub struct CSV_QUERY_FILE_REVISION_FILE_ID_128 {\n    pub FileId: super::super::Storage::FileSystem::FILE_ID_128,\n    pub FileRevision: [i64; 3],\n}\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\nimpl Default for CSV_QUERY_FILE_REVISION_FILE_ID_128 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CSV_QUERY_MDS_PATH {\n    pub MdsNodeId: u32,\n    pub DsNodeId: u32,\n    pub PathLength: u32,\n    pub Path: [u16; 1],\n}\nimpl Default for CSV_QUERY_MDS_PATH {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CSV_QUERY_MDS_PATH_FLAG_CSV_DIRECT_IO_ENABLED: u32 = 2u32;\npub const CSV_QUERY_MDS_PATH_FLAG_SMB_BYPASS_CSV_ENABLED: u32 = 4u32;\npub const CSV_QUERY_MDS_PATH_FLAG_STORAGE_ON_THIS_NODE_IS_CONNECTED: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CSV_QUERY_MDS_PATH_V2 {\n    pub Version: i64,\n    pub RequiredSize: u32,\n    pub MdsNodeId: u32,\n    pub DsNodeId: u32,\n    pub Flags: u32,\n    pub DiskConnectivity: CSVFS_DISK_CONNECTIVITY,\n    pub VolumeId: windows_sys::core::GUID,\n    pub IpAddressOffset: u32,\n    pub IpAddressLength: u32,\n    pub PathOffset: u32,\n    pub PathLength: u32,\n}\npub const CSV_QUERY_MDS_PATH_V2_VERSION_1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CSV_QUERY_REDIRECT_STATE {\n    pub MdsNodeId: u32,\n    pub DsNodeId: u32,\n    pub FileRedirected: bool,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT {\n    pub VetoedFromAltitudeIntegral: u64,\n    pub VetoedFromAltitudeDecimal: u64,\n    pub Reason: [u16; 256],\n}\nimpl Default for CSV_QUERY_VETO_FILE_DIRECT_IO_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CSV_QUERY_VOLUME_ID {\n    pub VolumeId: windows_sys::core::GUID,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CSV_QUERY_VOLUME_REDIRECT_STATE {\n    pub MdsNodeId: u32,\n    pub DsNodeId: u32,\n    pub IsDiskConnected: bool,\n    pub ClusterEnableDirectIo: bool,\n    pub DiskConnectivity: CSVFS_DISK_CONNECTIVITY,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CSV_SET_VOLUME_ID {\n    pub VolumeId: windows_sys::core::GUID,\n}\npub const CYGNET_12_WO: STORAGE_MEDIA_TYPE = 69i32;\npub const ChangerDoor: ELEMENT_TYPE = 5i32;\npub const ChangerDrive: ELEMENT_TYPE = 4i32;\npub const ChangerIEPort: ELEMENT_TYPE = 3i32;\npub const ChangerKeypad: ELEMENT_TYPE = 6i32;\npub const ChangerMaxElement: ELEMENT_TYPE = 7i32;\npub const ChangerSlot: ELEMENT_TYPE = 2i32;\npub const ChangerTransport: ELEMENT_TYPE = 1i32;\npub const CsvControlDisableCaching: CSV_CONTROL_OP = 19i32;\npub const CsvControlEnableCaching: CSV_CONTROL_OP = 20i32;\npub const CsvControlEnableUSNRangeModificationTracking: CSV_CONTROL_OP = 13i32;\npub const CsvControlGetCsvFsMdsPathV2: CSV_CONTROL_OP = 18i32;\npub const CsvControlMarkHandleLocalVolumeMount: CSV_CONTROL_OP = 14i32;\npub const CsvControlQueryFileRevision: CSV_CONTROL_OP = 6i32;\npub const CsvControlQueryFileRevisionFileId128: CSV_CONTROL_OP = 9i32;\npub const CsvControlQueryMdsPath: CSV_CONTROL_OP = 8i32;\npub const CsvControlQueryMdsPathNoPause: CSV_CONTROL_OP = 23i32;\npub const CsvControlQueryRedirectState: CSV_CONTROL_OP = 4i32;\npub const CsvControlQueryVolumeId: CSV_CONTROL_OP = 25i32;\npub const CsvControlQueryVolumeRedirectState: CSV_CONTROL_OP = 10i32;\npub const CsvControlSetVolumeId: CSV_CONTROL_OP = 24i32;\npub const CsvControlStartForceDFO: CSV_CONTROL_OP = 21i32;\npub const CsvControlStartRedirectFile: CSV_CONTROL_OP = 2i32;\npub const CsvControlStopForceDFO: CSV_CONTROL_OP = 22i32;\npub const CsvControlStopRedirectFile: CSV_CONTROL_OP = 3i32;\npub const CsvControlUnmarkHandleLocalVolumeMount: CSV_CONTROL_OP = 15i32;\npub const CsvFsDiskConnectivityAllNodes: CSVFS_DISK_CONNECTIVITY = 3i32;\npub const CsvFsDiskConnectivityMdsNodeOnly: CSVFS_DISK_CONNECTIVITY = 1i32;\npub const CsvFsDiskConnectivityNone: CSVFS_DISK_CONNECTIVITY = 0i32;\npub const CsvFsDiskConnectivitySubsetOfNodes: CSVFS_DISK_CONNECTIVITY = 2i32;\npub const DAX_ALLOC_ALIGNMENT_FLAG_FALLBACK_SPECIFIED: u32 = 2u32;\npub const DAX_ALLOC_ALIGNMENT_FLAG_MANDATORY: u32 = 1u32;\npub const DDS_4mm: STORAGE_MEDIA_TYPE = 32i32;\npub const DDUMP_FLAG_DATA_READ_FROM_DEVICE: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DECRYPTION_STATUS_BUFFER {\n    pub NoEncryptedStreams: bool,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DELETE_USN_JOURNAL_DATA {\n    pub UsnJournalID: u64,\n    pub DeleteFlags: USN_DELETE_FLAGS,\n}\npub type DETECTION_TYPE = i32;\npub const DEVICEDUMP_CAP_PRIVATE_SECTION: u32 = 1u32;\npub const DEVICEDUMP_CAP_RESTRICTED_SECTION: u32 = 2u32;\npub type DEVICEDUMP_COLLECTION_TYPEIDE_NOTIFICATION_TYPE = i32;\npub const DEVICEDUMP_MAX_IDSTRING: u32 = 32u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct DEVICEDUMP_PRIVATE_SUBSECTION {\n    pub dwFlags: u32,\n    pub GPLogId: GP_LOG_PAGE_DESCRIPTOR,\n    pub bData: [u8; 1],\n}\nimpl Default for DEVICEDUMP_PRIVATE_SUBSECTION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct DEVICEDUMP_PUBLIC_SUBSECTION {\n    pub dwFlags: u32,\n    pub GPLogTable: [GP_LOG_PAGE_DESCRIPTOR; 16],\n    pub szDescription: [i8; 16],\n    pub bData: [u8; 1],\n}\nimpl Default for DEVICEDUMP_PUBLIC_SUBSECTION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICEDUMP_RESTRICTED_SUBSECTION {\n    pub bData: [u8; 1],\n}\nimpl Default for DEVICEDUMP_RESTRICTED_SUBSECTION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct DEVICEDUMP_SECTION_HEADER {\n    pub guidDeviceDataId: windows_sys::core::GUID,\n    pub sOrganizationID: [u8; 16],\n    pub dwFirmwareRevision: u32,\n    pub sModelNumber: [u8; 32],\n    pub szDeviceManufacturingID: [u8; 32],\n    pub dwFlags: u32,\n    pub bRestrictedPrivateDataVersion: u32,\n    pub dwFirmwareIssueId: u32,\n    pub szIssueDescriptionString: [u8; 132],\n}\nimpl Default for DEVICEDUMP_SECTION_HEADER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct DEVICEDUMP_STORAGEDEVICE_DATA {\n    pub Descriptor: DEVICEDUMP_STRUCTURE_VERSION,\n    pub SectionHeader: DEVICEDUMP_SECTION_HEADER,\n    pub dwBufferSize: u32,\n    pub dwReasonForCollection: u32,\n    pub PublicData: DEVICEDUMP_SUBSECTION_POINTER,\n    pub RestrictedData: DEVICEDUMP_SUBSECTION_POINTER,\n    pub PrivateData: DEVICEDUMP_SUBSECTION_POINTER,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct DEVICEDUMP_STORAGESTACK_PUBLIC_DUMP {\n    pub Descriptor: DEVICEDUMP_STRUCTURE_VERSION,\n    pub dwReasonForCollection: u32,\n    pub cDriverName: [u8; 16],\n    pub uiNumRecords: u32,\n    pub RecordArray: [DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD; 1],\n}\nimpl Default for DEVICEDUMP_STORAGESTACK_PUBLIC_DUMP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD {\n    pub Cdb: [u8; 16],\n    pub Command: [u8; 16],\n    pub StartTime: u64,\n    pub EndTime: u64,\n    pub OperationStatus: u32,\n    pub OperationError: u32,\n    pub StackSpecific: DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD_0,\n}\nimpl Default for DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD_0 {\n    pub ExternalStack: DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD_0_0,\n    pub AtaPort: DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD_0_1,\n    pub StorPort: DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD_0_2,\n}\nimpl Default for DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD_0_1 {\n    pub dwAtaPortSpecific: u32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD_0_0 {\n    pub dwReserved: u32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct DEVICEDUMP_STORAGESTACK_PUBLIC_STATE_RECORD_0_2 {\n    pub SrbTag: u32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct DEVICEDUMP_STRUCTURE_VERSION {\n    pub dwSignature: u32,\n    pub dwVersion: u32,\n    pub dwSize: u32,\n}\npub const DEVICEDUMP_STRUCTURE_VERSION_V1: u32 = 1u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct DEVICEDUMP_SUBSECTION_POINTER {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub dwOffset: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_COPY_OFFLOAD_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub MaximumTokenLifetime: u32,\n    pub DefaultTokenLifetime: u32,\n    pub MaximumTransferSize: u64,\n    pub OptimalTransferCount: u64,\n    pub MaximumDataDescriptors: u32,\n    pub MaximumTransferLengthPerDescriptor: u32,\n    pub OptimalTransferLengthPerDescriptor: u32,\n    pub OptimalTransferLengthGranularity: u16,\n    pub Reserved: [u8; 2],\n}\nimpl Default for DEVICE_COPY_OFFLOAD_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_DATA_SET_LBP_STATE_PARAMETERS {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub OutputVersion: u32,\n}\npub const DEVICE_DATA_SET_LBP_STATE_PARAMETERS_VERSION_V1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DATA_SET_LB_PROVISIONING_STATE {\n    pub Size: u32,\n    pub Version: u32,\n    pub SlabSizeInBytes: u64,\n    pub SlabOffsetDeltaInBytes: u32,\n    pub SlabAllocationBitMapBitCount: u32,\n    pub SlabAllocationBitMapLength: u32,\n    pub SlabAllocationBitMap: [u32; 1],\n}\nimpl Default for DEVICE_DATA_SET_LB_PROVISIONING_STATE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DATA_SET_LB_PROVISIONING_STATE_V2 {\n    pub Size: u32,\n    pub Version: u32,\n    pub SlabSizeInBytes: u64,\n    pub SlabOffsetDeltaInBytes: u64,\n    pub SlabAllocationBitMapBitCount: u32,\n    pub SlabAllocationBitMapLength: u32,\n    pub SlabAllocationBitMap: [u32; 1],\n}\nimpl Default for DEVICE_DATA_SET_LB_PROVISIONING_STATE_V2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_DATA_SET_RANGE {\n    pub StartingOffset: i64,\n    pub LengthInBytes: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_DATA_SET_REPAIR_OUTPUT {\n    pub ParityExtent: DEVICE_DATA_SET_RANGE,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DATA_SET_REPAIR_PARAMETERS {\n    pub NumberOfRepairCopies: u32,\n    pub SourceCopy: u32,\n    pub RepairCopies: [u32; 1],\n}\nimpl Default for DEVICE_DATA_SET_REPAIR_PARAMETERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_DATA_SET_SCRUB_EX_OUTPUT {\n    pub BytesProcessed: u64,\n    pub BytesRepaired: u64,\n    pub BytesFailed: u64,\n    pub ParityExtent: DEVICE_DATA_SET_RANGE,\n    pub BytesScrubbed: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_DATA_SET_SCRUB_OUTPUT {\n    pub BytesProcessed: u64,\n    pub BytesRepaired: u64,\n    pub BytesFailed: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DATA_SET_TOPOLOGY_ID_QUERY_OUTPUT {\n    pub TopologyRangeBytes: u64,\n    pub TopologyId: [u8; 16],\n}\nimpl Default for DEVICE_DATA_SET_TOPOLOGY_ID_QUERY_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_DSM_CONVERSION_OUTPUT {\n    pub Version: u32,\n    pub Source: windows_sys::core::GUID,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_DSM_DEFINITION {\n    pub Action: u32,\n    pub SingleRange: bool,\n    pub ParameterBlockAlignment: u32,\n    pub ParameterBlockLength: u32,\n    pub HasOutput: bool,\n    pub OutputBlockAlignment: u32,\n    pub OutputBlockLength: u32,\n}\npub const DEVICE_DSM_FLAG_ALLOCATION_CONSOLIDATEABLE_ONLY: u32 = 1073741824u32;\npub const DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE: u32 = 1u32;\npub const DEVICE_DSM_FLAG_PHYSICAL_ADDRESSES_OMIT_TOTAL_RANGES: u32 = 268435456u32;\npub const DEVICE_DSM_FLAG_REPAIR_INPUT_TOPOLOGY_ID_PRESENT: u32 = 1073741824u32;\npub const DEVICE_DSM_FLAG_REPAIR_OUTPUT_PARITY_EXTENT: u32 = 536870912u32;\npub const DEVICE_DSM_FLAG_SCRUB_OUTPUT_PARITY_EXTENT: u32 = 536870912u32;\npub const DEVICE_DSM_FLAG_SCRUB_SKIP_IN_SYNC: u32 = 268435456u32;\npub const DEVICE_DSM_FLAG_TRIM_BYPASS_RZAT: u32 = 1073741824u32;\npub const DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED: u32 = 2147483648u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_DSM_FREE_SPACE_OUTPUT {\n    pub Version: u32,\n    pub FreeSpace: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_LOST_QUERY_OUTPUT {\n    pub Version: u32,\n    pub Size: u32,\n    pub Alignment: u64,\n    pub NumberOfBits: u32,\n    pub BitMap: [u32; 1],\n}\nimpl Default for DEVICE_DSM_LOST_QUERY_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_DSM_LOST_QUERY_PARAMETERS {\n    pub Version: u32,\n    pub Granularity: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_NOTIFICATION_PARAMETERS {\n    pub Size: u32,\n    pub Flags: u32,\n    pub NumFileTypeIDs: u32,\n    pub FileTypeID: [windows_sys::core::GUID; 1],\n}\nimpl Default for DEVICE_DSM_NOTIFICATION_PARAMETERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DEVICE_DSM_NOTIFY_FLAG_BEGIN: u32 = 1u32;\npub const DEVICE_DSM_NOTIFY_FLAG_END: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_NVCACHE_CHANGE_PRIORITY_PARAMETERS {\n    pub Size: u32,\n    pub TargetPriority: u8,\n    pub Reserved: [u8; 3],\n}\nimpl Default for DEVICE_DSM_NVCACHE_CHANGE_PRIORITY_PARAMETERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_OFFLOAD_READ_PARAMETERS {\n    pub Flags: u32,\n    pub TimeToLive: u32,\n    pub Reserved: [u32; 2],\n}\nimpl Default for DEVICE_DSM_OFFLOAD_READ_PARAMETERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS {\n    pub Flags: u32,\n    pub Reserved: u32,\n    pub TokenOffset: u64,\n    pub Token: STORAGE_OFFLOAD_TOKEN,\n}\nimpl Default for DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DEVICE_DSM_PARAMETERS_V1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_PHYSICAL_ADDRESSES_OUTPUT {\n    pub Version: u32,\n    pub Flags: u32,\n    pub TotalNumberOfRanges: u32,\n    pub NumberOfRangesReturned: u32,\n    pub Ranges: [DEVICE_STORAGE_ADDRESS_RANGE; 1],\n}\nimpl Default for DEVICE_DSM_PHYSICAL_ADDRESSES_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DEVICE_DSM_PHYSICAL_ADDRESSES_OUTPUT_V1: u32 = 1u32;\npub const DEVICE_DSM_PHYSICAL_ADDRESSES_OUTPUT_VERSION_V1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_RANGE_ERROR_INFO {\n    pub Version: u32,\n    pub Flags: u32,\n    pub TotalNumberOfRanges: u32,\n    pub NumberOfRangesReturned: u32,\n    pub Ranges: [DEVICE_STORAGE_RANGE_ATTRIBUTES; 1],\n}\nimpl Default for DEVICE_DSM_RANGE_ERROR_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DEVICE_DSM_RANGE_ERROR_INFO_VERSION_V1: u32 = 1u32;\npub const DEVICE_DSM_RANGE_ERROR_OUTPUT_V1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_REPORT_ZONES_DATA {\n    pub Size: u32,\n    pub ZoneCount: u32,\n    pub Attributes: STORAGE_ZONES_ATTRIBUTES,\n    pub Reserved0: u32,\n    pub ZoneDescriptors: [STORAGE_ZONE_DESCRIPTOR; 1],\n}\nimpl Default for DEVICE_DSM_REPORT_ZONES_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_REPORT_ZONES_PARAMETERS {\n    pub Size: u32,\n    pub ReportOption: u8,\n    pub Partial: u8,\n    pub Reserved: [u8; 2],\n}\nimpl Default for DEVICE_DSM_REPORT_ZONES_PARAMETERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_TIERING_QUERY_INPUT {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub NumberOfTierIds: u32,\n    pub TierIds: [windows_sys::core::GUID; 1],\n}\nimpl Default for DEVICE_DSM_TIERING_QUERY_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_DSM_TIERING_QUERY_OUTPUT {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub Reserved: u32,\n    pub Alignment: u64,\n    pub TotalNumberOfRegions: u32,\n    pub NumberOfRegionsReturned: u32,\n    pub Regions: [STORAGE_TIER_REGION; 1],\n}\nimpl Default for DEVICE_DSM_TIERING_QUERY_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_INTERNAL_STATUS_DATA {\n    pub Version: u32,\n    pub Size: u32,\n    pub T10VendorId: u64,\n    pub DataSet1Length: u32,\n    pub DataSet2Length: u32,\n    pub DataSet3Length: u32,\n    pub DataSet4Length: u32,\n    pub StatusDataVersion: u8,\n    pub Reserved: [u8; 3],\n    pub ReasonIdentifier: [u8; 128],\n    pub StatusDataLength: u32,\n    pub StatusData: [u8; 1],\n}\nimpl Default for DEVICE_INTERNAL_STATUS_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type DEVICE_INTERNAL_STATUS_DATA_REQUEST_TYPE = i32;\npub type DEVICE_INTERNAL_STATUS_DATA_SET = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_LB_PROVISIONING_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub _bitfield: u8,\n    pub Reserved1: [u8; 7],\n    pub OptimalUnmapGranularity: u64,\n    pub UnmapGranularityAlignment: u64,\n    pub MaxUnmapLbaCount: u32,\n    pub MaxUnmapBlockDescriptorCount: u32,\n}\nimpl Default for DEVICE_LB_PROVISIONING_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_LOCATION {\n    pub Socket: u32,\n    pub Slot: u32,\n    pub Adapter: u32,\n    pub Port: u32,\n    pub Anonymous: DEVICE_LOCATION_0,\n}\nimpl Default for DEVICE_LOCATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DEVICE_LOCATION_0 {\n    pub Anonymous1: DEVICE_LOCATION_0_0,\n    pub Anonymous2: DEVICE_LOCATION_0_1,\n}\nimpl Default for DEVICE_LOCATION_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_LOCATION_0_0 {\n    pub Channel: u32,\n    pub Device: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_LOCATION_0_1 {\n    pub Target: u32,\n    pub Lun: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_MANAGE_DATA_SET_ATTRIBUTES {\n    pub Size: u32,\n    pub Action: u32,\n    pub Flags: u32,\n    pub ParameterBlockOffset: u32,\n    pub ParameterBlockLength: u32,\n    pub DataSetRangesOffset: u32,\n    pub DataSetRangesLength: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT {\n    pub Size: u32,\n    pub Action: u32,\n    pub Flags: u32,\n    pub OperationStatus: u32,\n    pub ExtendedError: u32,\n    pub TargetDetailedError: u32,\n    pub ReservedStatus: u32,\n    pub OutputBlockOffset: u32,\n    pub OutputBlockLength: u32,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy)]\npub struct DEVICE_MEDIA_INFO {\n    pub DeviceSpecific: DEVICE_MEDIA_INFO_0,\n}\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\nimpl Default for DEVICE_MEDIA_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy)]\npub union DEVICE_MEDIA_INFO_0 {\n    pub DiskInfo: DEVICE_MEDIA_INFO_0_0,\n    pub RemovableDiskInfo: DEVICE_MEDIA_INFO_0_1,\n    pub TapeInfo: DEVICE_MEDIA_INFO_0_2,\n}\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\nimpl Default for DEVICE_MEDIA_INFO_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_MEDIA_INFO_0_0 {\n    pub Cylinders: i64,\n    pub MediaType: STORAGE_MEDIA_TYPE,\n    pub TracksPerCylinder: u32,\n    pub SectorsPerTrack: u32,\n    pub BytesPerSector: u32,\n    pub NumberMediaSides: u32,\n    pub MediaCharacteristics: u32,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_MEDIA_INFO_0_1 {\n    pub Cylinders: i64,\n    pub MediaType: STORAGE_MEDIA_TYPE,\n    pub TracksPerCylinder: u32,\n    pub SectorsPerTrack: u32,\n    pub BytesPerSector: u32,\n    pub NumberMediaSides: u32,\n    pub MediaCharacteristics: u32,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy)]\npub struct DEVICE_MEDIA_INFO_0_2 {\n    pub MediaType: STORAGE_MEDIA_TYPE,\n    pub MediaCharacteristics: u32,\n    pub CurrentBlockSize: u32,\n    pub BusType: super::super::Storage::FileSystem::STORAGE_BUS_TYPE,\n    pub BusSpecificData: DEVICE_MEDIA_INFO_0_2_0,\n}\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\nimpl Default for DEVICE_MEDIA_INFO_0_2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy)]\npub union DEVICE_MEDIA_INFO_0_2_0 {\n    pub ScsiInformation: DEVICE_MEDIA_INFO_0_2_0_0,\n}\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\nimpl Default for DEVICE_MEDIA_INFO_0_2_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_MEDIA_INFO_0_2_0_0 {\n    pub MediumType: u8,\n    pub DensityCode: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_POWER_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub DeviceAttentionSupported: bool,\n    pub AsynchronousNotificationSupported: bool,\n    pub IdlePowerManagementEnabled: bool,\n    pub D3ColdEnabled: bool,\n    pub D3ColdSupported: bool,\n    pub NoVerifyDuringIdlePower: bool,\n    pub Reserved: [u8; 2],\n    pub IdleTimeoutInMS: u32,\n}\nimpl Default for DEVICE_POWER_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_SEEK_PENALTY_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub IncursSeekPenalty: bool,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_STORAGE_ADDRESS_RANGE {\n    pub StartAddress: i64,\n    pub LengthInBytes: u64,\n}\npub const DEVICE_STORAGE_NO_ERRORS: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DEVICE_STORAGE_RANGE_ATTRIBUTES {\n    pub LengthInBytes: u64,\n    pub Anonymous: DEVICE_STORAGE_RANGE_ATTRIBUTES_0,\n    pub Reserved: u32,\n}\nimpl Default for DEVICE_STORAGE_RANGE_ATTRIBUTES {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DEVICE_STORAGE_RANGE_ATTRIBUTES_0 {\n    pub AllFlags: u32,\n    pub Anonymous: DEVICE_STORAGE_RANGE_ATTRIBUTES_0_0,\n}\nimpl Default for DEVICE_STORAGE_RANGE_ATTRIBUTES_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_STORAGE_RANGE_ATTRIBUTES_0_0 {\n    pub _bitfield: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_TRIM_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub TrimEnabled: bool,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DEVICE_WRITE_AGGREGATION_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub BenefitsFromWriteAggregation: bool,\n}\npub const DEVPKEY_Storage_Disk_Number: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d1ebee8_0803_4774_9842_b77db50265e9), pid: 5 };\npub const DEVPKEY_Storage_Gpt_Name: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d1ebee8_0803_4774_9842_b77db50265e9), pid: 9 };\npub const DEVPKEY_Storage_Gpt_Type: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d1ebee8_0803_4774_9842_b77db50265e9), pid: 8 };\npub const DEVPKEY_Storage_Mbr_Type: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d1ebee8_0803_4774_9842_b77db50265e9), pid: 7 };\npub const DEVPKEY_Storage_Partition_Number: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d1ebee8_0803_4774_9842_b77db50265e9), pid: 6 };\npub const DEVPKEY_Storage_Portable: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d1ebee8_0803_4774_9842_b77db50265e9), pid: 2 };\npub const DEVPKEY_Storage_Removable_Media: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d1ebee8_0803_4774_9842_b77db50265e9), pid: 3 };\npub const DEVPKEY_Storage_System_Critical: super::super::Foundation::DEVPROPKEY = super::super::Foundation::DEVPROPKEY { fmtid: windows_sys::core::GUID::from_u128(0x4d1ebee8_0803_4774_9842_b77db50265e9), pid: 4 };\npub const DISABLE_SMART: u32 = 217u32;\npub const DISK_ATTRIBUTE_OFFLINE: u64 = 1u64;\npub const DISK_ATTRIBUTE_READ_ONLY: u64 = 2u64;\npub const DISK_BINNING: u32 = 3u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DISK_CACHE_INFORMATION {\n    pub ParametersSavable: bool,\n    pub ReadCacheEnabled: bool,\n    pub WriteCacheEnabled: bool,\n    pub ReadRetentionPriority: DISK_CACHE_RETENTION_PRIORITY,\n    pub WriteRetentionPriority: DISK_CACHE_RETENTION_PRIORITY,\n    pub DisablePrefetchTransferLength: u16,\n    pub PrefetchScalar: bool,\n    pub Anonymous: DISK_CACHE_INFORMATION_0,\n}\nimpl Default for DISK_CACHE_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DISK_CACHE_INFORMATION_0 {\n    pub ScalarPrefetch: DISK_CACHE_INFORMATION_0_0,\n    pub BlockPrefetch: DISK_CACHE_INFORMATION_0_1,\n}\nimpl Default for DISK_CACHE_INFORMATION_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_CACHE_INFORMATION_0_1 {\n    pub Minimum: u16,\n    pub Maximum: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_CACHE_INFORMATION_0_0 {\n    pub Minimum: u16,\n    pub Maximum: u16,\n    pub MaximumBlocks: u16,\n}\npub type DISK_CACHE_RETENTION_PRIORITY = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_CONTROLLER_NUMBER {\n    pub ControllerNumber: u32,\n    pub DiskNumber: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DISK_DETECTION_INFO {\n    pub SizeOfDetectInfo: u32,\n    pub DetectionType: DETECTION_TYPE,\n    pub Anonymous: DISK_DETECTION_INFO_0,\n}\nimpl Default for DISK_DETECTION_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DISK_DETECTION_INFO_0 {\n    pub Anonymous: DISK_DETECTION_INFO_0_0,\n}\nimpl Default for DISK_DETECTION_INFO_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_DETECTION_INFO_0_0 {\n    pub Int13: DISK_INT13_INFO,\n    pub ExInt13: DISK_EX_INT13_INFO,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_EXTENT {\n    pub DiskNumber: u32,\n    pub StartingOffset: i64,\n    pub ExtentLength: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_EX_INT13_INFO {\n    pub ExBufferSize: u16,\n    pub ExFlags: u16,\n    pub ExCylinders: u32,\n    pub ExHeads: u32,\n    pub ExSectorsPerTrack: u32,\n    pub ExSectorsPerDrive: u64,\n    pub ExSectorSize: u16,\n    pub ExReserved: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_GEOMETRY {\n    pub Cylinders: i64,\n    pub MediaType: MEDIA_TYPE,\n    pub TracksPerCylinder: u32,\n    pub SectorsPerTrack: u32,\n    pub BytesPerSector: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DISK_GEOMETRY_EX {\n    pub Geometry: DISK_GEOMETRY,\n    pub DiskSize: i64,\n    pub Data: [u8; 1],\n}\nimpl Default for DISK_GEOMETRY_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_GROW_PARTITION {\n    pub PartitionNumber: u32,\n    pub BytesToGrow: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DISK_HISTOGRAM {\n    pub DiskSize: i64,\n    pub Start: i64,\n    pub End: i64,\n    pub Average: i64,\n    pub AverageRead: i64,\n    pub AverageWrite: i64,\n    pub Granularity: u32,\n    pub Size: u32,\n    pub ReadCount: u32,\n    pub WriteCount: u32,\n    pub Histogram: *mut HISTOGRAM_BUCKET,\n}\nimpl Default for DISK_HISTOGRAM {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_INT13_INFO {\n    pub DriveSelect: u16,\n    pub MaxCylinders: u32,\n    pub SectorsPerTrack: u16,\n    pub MaxHeads: u16,\n    pub NumberDrives: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DISK_LOGGING {\n    pub Function: u8,\n    pub BufferAddress: *mut core::ffi::c_void,\n    pub BufferSize: u32,\n}\nimpl Default for DISK_LOGGING {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DISK_LOGGING_DUMP: u32 = 2u32;\npub const DISK_LOGGING_START: u32 = 0u32;\npub const DISK_LOGGING_STOP: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DISK_PARTITION_INFO {\n    pub SizeOfPartitionInfo: u32,\n    pub PartitionStyle: PARTITION_STYLE,\n    pub Anonymous: DISK_PARTITION_INFO_0,\n}\nimpl Default for DISK_PARTITION_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DISK_PARTITION_INFO_0 {\n    pub Mbr: DISK_PARTITION_INFO_0_0,\n    pub Gpt: DISK_PARTITION_INFO_0_1,\n}\nimpl Default for DISK_PARTITION_INFO_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_PARTITION_INFO_0_1 {\n    pub DiskId: windows_sys::core::GUID,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DISK_PARTITION_INFO_0_0 {\n    pub Signature: u32,\n    pub CheckSum: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DISK_PERFORMANCE {\n    pub BytesRead: i64,\n    pub BytesWritten: i64,\n    pub ReadTime: i64,\n    pub WriteTime: i64,\n    pub IdleTime: i64,\n    pub ReadCount: u32,\n    pub WriteCount: u32,\n    pub QueueDepth: u32,\n    pub SplitCount: u32,\n    pub QueryTime: i64,\n    pub StorageDeviceNumber: u32,\n    pub StorageManagerName: [u16; 8],\n}\nimpl Default for DISK_PERFORMANCE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DISK_RECORD {\n    pub ByteOffset: i64,\n    pub StartTime: i64,\n    pub EndTime: i64,\n    pub VirtualAddress: *mut core::ffi::c_void,\n    pub NumberOfBytes: u32,\n    pub DeviceNumber: u8,\n    pub ReadRequest: bool,\n}\nimpl Default for DISK_RECORD {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DLT: STORAGE_MEDIA_TYPE = 39i32;\npub const DMI: STORAGE_MEDIA_TYPE = 48i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct DRIVERSTATUS {\n    pub bDriverError: u8,\n    pub bIDEError: u8,\n    pub bReserved: [u8; 2],\n    pub dwReserved: [u32; 2],\n}\nimpl Default for DRIVERSTATUS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DRIVE_LAYOUT_INFORMATION {\n    pub PartitionCount: u32,\n    pub Signature: u32,\n    pub PartitionEntry: [PARTITION_INFORMATION; 1],\n}\nimpl Default for DRIVE_LAYOUT_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DRIVE_LAYOUT_INFORMATION_EX {\n    pub PartitionStyle: u32,\n    pub PartitionCount: u32,\n    pub Anonymous: DRIVE_LAYOUT_INFORMATION_EX_0,\n    pub PartitionEntry: [PARTITION_INFORMATION_EX; 1],\n}\nimpl Default for DRIVE_LAYOUT_INFORMATION_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union DRIVE_LAYOUT_INFORMATION_EX_0 {\n    pub Mbr: DRIVE_LAYOUT_INFORMATION_MBR,\n    pub Gpt: DRIVE_LAYOUT_INFORMATION_GPT,\n}\nimpl Default for DRIVE_LAYOUT_INFORMATION_EX_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DRIVE_LAYOUT_INFORMATION_GPT {\n    pub DiskId: windows_sys::core::GUID,\n    pub StartingUsableOffset: i64,\n    pub UsableLength: i64,\n    pub MaxPartitionCount: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DRIVE_LAYOUT_INFORMATION_MBR {\n    pub Signature: u32,\n    pub CheckSum: u32,\n}\npub const DST_L: STORAGE_MEDIA_TYPE = 82i32;\npub const DST_M: STORAGE_MEDIA_TYPE = 81i32;\npub const DST_S: STORAGE_MEDIA_TYPE = 80i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DUPLICATE_EXTENTS_DATA {\n    pub FileHandle: super::super::Foundation::HANDLE,\n    pub SourceFileOffset: i64,\n    pub TargetFileOffset: i64,\n    pub ByteCount: i64,\n}\nimpl Default for DUPLICATE_EXTENTS_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\n#[derive(Clone, Copy, Default)]\npub struct DUPLICATE_EXTENTS_DATA32 {\n    pub FileHandle: u32,\n    pub SourceFileOffset: i64,\n    pub TargetFileOffset: i64,\n    pub ByteCount: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DUPLICATE_EXTENTS_DATA_EX {\n    pub Size: usize,\n    pub FileHandle: super::super::Foundation::HANDLE,\n    pub SourceFileOffset: i64,\n    pub TargetFileOffset: i64,\n    pub ByteCount: i64,\n    pub Flags: u32,\n}\nimpl Default for DUPLICATE_EXTENTS_DATA_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\n#[derive(Clone, Copy, Default)]\npub struct DUPLICATE_EXTENTS_DATA_EX32 {\n    pub Size: u32,\n    pub FileHandle: u32,\n    pub SourceFileOffset: i64,\n    pub TargetFileOffset: i64,\n    pub ByteCount: i64,\n    pub Flags: u32,\n}\npub const DUPLICATE_EXTENTS_DATA_EX_ASYNC: u32 = 2u32;\npub const DUPLICATE_EXTENTS_DATA_EX_SOURCE_ATOMIC: u32 = 1u32;\npub type DUPLICATE_EXTENTS_STATE = i32;\npub const DVD_R: STORAGE_MEDIA_TYPE = 55i32;\npub const DVD_RAM: STORAGE_MEDIA_TYPE = 88i32;\npub const DVD_ROM: STORAGE_MEDIA_TYPE = 54i32;\npub const DVD_RW: STORAGE_MEDIA_TYPE = 56i32;\npub const DV_6mm: STORAGE_MEDIA_TYPE = 47i32;\npub const DetectExInt13: DETECTION_TYPE = 2i32;\npub const DetectInt13: DETECTION_TYPE = 1i32;\npub const DetectNone: DETECTION_TYPE = 0i32;\npub const DeviceCurrentInternalStatusData: DEVICE_INTERNAL_STATUS_DATA_REQUEST_TYPE = 2i32;\npub const DeviceCurrentInternalStatusDataHeader: DEVICE_INTERNAL_STATUS_DATA_REQUEST_TYPE = 1i32;\npub const DeviceDsmActionFlag_NonDestructive: u32 = 2147483648u32;\npub const DeviceInternalStatusDataRequestTypeUndefined: DEVICE_INTERNAL_STATUS_DATA_REQUEST_TYPE = 0i32;\npub const DeviceProblemCHMError: CHANGER_DEVICE_PROBLEM_TYPE = 2i32;\npub const DeviceProblemCHMMoveError: CHANGER_DEVICE_PROBLEM_TYPE = 6i32;\npub const DeviceProblemCHMZeroError: CHANGER_DEVICE_PROBLEM_TYPE = 7i32;\npub const DeviceProblemCalibrationError: CHANGER_DEVICE_PROBLEM_TYPE = 4i32;\npub const DeviceProblemCartridgeEjectError: CHANGER_DEVICE_PROBLEM_TYPE = 11i32;\npub const DeviceProblemCartridgeInsertError: CHANGER_DEVICE_PROBLEM_TYPE = 8i32;\npub const DeviceProblemDoorOpen: CHANGER_DEVICE_PROBLEM_TYPE = 3i32;\npub const DeviceProblemDriveError: CHANGER_DEVICE_PROBLEM_TYPE = 13i32;\npub const DeviceProblemGripperError: CHANGER_DEVICE_PROBLEM_TYPE = 12i32;\npub const DeviceProblemHardware: CHANGER_DEVICE_PROBLEM_TYPE = 1i32;\npub const DeviceProblemNone: CHANGER_DEVICE_PROBLEM_TYPE = 0i32;\npub const DeviceProblemPositionError: CHANGER_DEVICE_PROBLEM_TYPE = 9i32;\npub const DeviceProblemSensorError: CHANGER_DEVICE_PROBLEM_TYPE = 10i32;\npub const DeviceProblemTargetFailure: CHANGER_DEVICE_PROBLEM_TYPE = 5i32;\npub const DeviceSavedInternalStatusData: DEVICE_INTERNAL_STATUS_DATA_REQUEST_TYPE = 4i32;\npub const DeviceSavedInternalStatusDataHeader: DEVICE_INTERNAL_STATUS_DATA_REQUEST_TYPE = 3i32;\npub const DeviceStatusDataSet1: DEVICE_INTERNAL_STATUS_DATA_SET = 1i32;\npub const DeviceStatusDataSet2: DEVICE_INTERNAL_STATUS_DATA_SET = 2i32;\npub const DeviceStatusDataSet3: DEVICE_INTERNAL_STATUS_DATA_SET = 3i32;\npub const DeviceStatusDataSet4: DEVICE_INTERNAL_STATUS_DATA_SET = 4i32;\npub const DeviceStatusDataSetMax: DEVICE_INTERNAL_STATUS_DATA_SET = 5i32;\npub const DeviceStatusDataSetUndefined: DEVICE_INTERNAL_STATUS_DATA_SET = 0i32;\npub const DiskHealthHealthy: STORAGE_DISK_HEALTH_STATUS = 3i32;\npub const DiskHealthMax: STORAGE_DISK_HEALTH_STATUS = 4i32;\npub const DiskHealthUnhealthy: STORAGE_DISK_HEALTH_STATUS = 1i32;\npub const DiskHealthUnknown: STORAGE_DISK_HEALTH_STATUS = 0i32;\npub const DiskHealthWarning: STORAGE_DISK_HEALTH_STATUS = 2i32;\npub const DiskOpReasonBackgroundOperation: STORAGE_OPERATIONAL_STATUS_REASON = 12i32;\npub const DiskOpReasonComponent: STORAGE_OPERATIONAL_STATUS_REASON = 10i32;\npub const DiskOpReasonConfiguration: STORAGE_OPERATIONAL_STATUS_REASON = 7i32;\npub const DiskOpReasonDataPersistenceLossImminent: STORAGE_OPERATIONAL_STATUS_REASON = 18i32;\npub const DiskOpReasonDeviceController: STORAGE_OPERATIONAL_STATUS_REASON = 8i32;\npub const DiskOpReasonDisabledByPlatform: STORAGE_OPERATIONAL_STATUS_REASON = 16i32;\npub const DiskOpReasonEnergySource: STORAGE_OPERATIONAL_STATUS_REASON = 6i32;\npub const DiskOpReasonHealthCheck: STORAGE_OPERATIONAL_STATUS_REASON = 14i32;\npub const DiskOpReasonInvalidFirmware: STORAGE_OPERATIONAL_STATUS_REASON = 13i32;\npub const DiskOpReasonIo: STORAGE_OPERATIONAL_STATUS_REASON = 3i32;\npub const DiskOpReasonLostData: STORAGE_OPERATIONAL_STATUS_REASON = 5i32;\npub const DiskOpReasonLostDataPersistence: STORAGE_OPERATIONAL_STATUS_REASON = 15i32;\npub const DiskOpReasonLostWritePersistence: STORAGE_OPERATIONAL_STATUS_REASON = 17i32;\npub const DiskOpReasonMax: STORAGE_OPERATIONAL_STATUS_REASON = 20i32;\npub const DiskOpReasonMedia: STORAGE_OPERATIONAL_STATUS_REASON = 2i32;\npub const DiskOpReasonMediaController: STORAGE_OPERATIONAL_STATUS_REASON = 9i32;\npub const DiskOpReasonNVDIMM_N: STORAGE_OPERATIONAL_STATUS_REASON = 11i32;\npub const DiskOpReasonScsiSenseCode: STORAGE_OPERATIONAL_STATUS_REASON = 1i32;\npub const DiskOpReasonThresholdExceeded: STORAGE_OPERATIONAL_STATUS_REASON = 4i32;\npub const DiskOpReasonUnknown: STORAGE_OPERATIONAL_STATUS_REASON = 0i32;\npub const DiskOpReasonWritePersistenceLossImminent: STORAGE_OPERATIONAL_STATUS_REASON = 19i32;\npub const DiskOpStatusHardwareError: STORAGE_DISK_OPERATIONAL_STATUS = 5i32;\npub const DiskOpStatusInService: STORAGE_DISK_OPERATIONAL_STATUS = 4i32;\npub const DiskOpStatusMissing: STORAGE_DISK_OPERATIONAL_STATUS = 8i32;\npub const DiskOpStatusNone: STORAGE_DISK_OPERATIONAL_STATUS = 0i32;\npub const DiskOpStatusNotUsable: STORAGE_DISK_OPERATIONAL_STATUS = 6i32;\npub const DiskOpStatusOk: STORAGE_DISK_OPERATIONAL_STATUS = 2i32;\npub const DiskOpStatusPredictingFailure: STORAGE_DISK_OPERATIONAL_STATUS = 3i32;\npub const DiskOpStatusTransientError: STORAGE_DISK_OPERATIONAL_STATUS = 7i32;\npub const DiskOpStatusUnknown: STORAGE_DISK_OPERATIONAL_STATUS = 1i32;\npub const EFS_TRACKED_OFFSET_HEADER_FLAG: u32 = 1u32;\npub const ELEMENT_STATUS_ACCESS: CHANGER_ELEMENT_STATUS_FLAGS = 8u32;\npub const ELEMENT_STATUS_AVOLTAG: CHANGER_ELEMENT_STATUS_FLAGS = 536870912u32;\npub const ELEMENT_STATUS_EXCEPT: CHANGER_ELEMENT_STATUS_FLAGS = 4u32;\npub const ELEMENT_STATUS_EXENAB: CHANGER_ELEMENT_STATUS_FLAGS = 16u32;\npub const ELEMENT_STATUS_FULL: CHANGER_ELEMENT_STATUS_FLAGS = 1u32;\npub const ELEMENT_STATUS_ID_VALID: CHANGER_ELEMENT_STATUS_FLAGS = 8192u32;\npub const ELEMENT_STATUS_IMPEXP: CHANGER_ELEMENT_STATUS_FLAGS = 2u32;\npub const ELEMENT_STATUS_INENAB: CHANGER_ELEMENT_STATUS_FLAGS = 32u32;\npub const ELEMENT_STATUS_INVERT: CHANGER_ELEMENT_STATUS_FLAGS = 4194304u32;\npub const ELEMENT_STATUS_LUN_VALID: CHANGER_ELEMENT_STATUS_FLAGS = 4096u32;\npub const ELEMENT_STATUS_NOT_BUS: CHANGER_ELEMENT_STATUS_FLAGS = 32768u32;\npub const ELEMENT_STATUS_PRODUCT_DATA: CHANGER_ELEMENT_STATUS_FLAGS = 64u32;\npub const ELEMENT_STATUS_PVOLTAG: CHANGER_ELEMENT_STATUS_FLAGS = 268435456u32;\npub const ELEMENT_STATUS_SVALID: CHANGER_ELEMENT_STATUS_FLAGS = 8388608u32;\npub type ELEMENT_TYPE = i32;\npub const ENABLE_DISABLE_AUTOSAVE: u32 = 210u32;\npub const ENABLE_DISABLE_AUTO_OFFLINE: u32 = 219u32;\npub const ENABLE_SMART: u32 = 216u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ENCRYPTED_DATA_INFO {\n    pub StartingFileOffset: u64,\n    pub OutputBufferOffset: u32,\n    pub BytesWithinFileSize: u32,\n    pub BytesWithinValidDataLength: u32,\n    pub CompressionFormat: u16,\n    pub DataUnitShift: u8,\n    pub ChunkShift: u8,\n    pub ClusterShift: u8,\n    pub EncryptionFormat: u8,\n    pub NumberOfDataBlocks: u16,\n    pub DataBlockSize: [u32; 1],\n}\nimpl Default for ENCRYPTED_DATA_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ENCRYPTED_DATA_INFO_SPARSE_FILE: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct ENCRYPTION_BUFFER {\n    pub EncryptionOperation: u32,\n    pub Private: [u8; 1],\n}\nimpl Default for ENCRYPTION_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ENCRYPTION_FORMAT_DEFAULT: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct ENCRYPTION_KEY_CTRL_INPUT {\n    pub HeaderSize: u32,\n    pub StructureSize: u32,\n    pub KeyOffset: u16,\n    pub KeySize: u16,\n    pub DplLock: u32,\n    pub DplUserId: u64,\n    pub DplCredentialId: u64,\n}\npub const ERROR_DRIVE_NOT_INSTALLED: u32 = 8u32;\npub const ERROR_HISTORY_DIRECTORY_ENTRY_DEFAULT_COUNT: u32 = 8u32;\npub const ERROR_INIT_STATUS_NEEDED: u32 = 17u32;\npub const ERROR_LABEL_QUESTIONABLE: u32 = 2u32;\npub const ERROR_LABEL_UNREADABLE: u32 = 1u32;\npub const ERROR_SLOT_NOT_PRESENT: u32 = 4u32;\npub const ERROR_TRAY_MALFUNCTION: u32 = 16u32;\npub const ERROR_UNHANDLED_ERROR: u32 = 4294967295u32;\npub const EXECUTE_OFFLINE_DIAGS: u32 = 212u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct EXFAT_STATISTICS {\n    pub CreateHits: u32,\n    pub SuccessfulCreates: u32,\n    pub FailedCreates: u32,\n    pub NonCachedReads: u32,\n    pub NonCachedReadBytes: u32,\n    pub NonCachedWrites: u32,\n    pub NonCachedWriteBytes: u32,\n    pub NonCachedDiskReads: u32,\n    pub NonCachedDiskWrites: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct EXTENDED_ENCRYPTED_DATA_INFO {\n    pub ExtendedCode: u32,\n    pub Length: u32,\n    pub Flags: u32,\n    pub Reserved: u32,\n}\npub const EXTEND_IEPORT: u32 = 2u32;\npub const EqualPriority: DISK_CACHE_RETENTION_PRIORITY = 0i32;\npub const F3_120M_512: MEDIA_TYPE = 13i32;\npub const F3_128Mb_512: MEDIA_TYPE = 20i32;\npub const F3_1Pt23_1024: MEDIA_TYPE = 18i32;\npub const F3_1Pt2_512: MEDIA_TYPE = 17i32;\npub const F3_1Pt44_512: MEDIA_TYPE = 2i32;\npub const F3_200Mb_512: MEDIA_TYPE = 23i32;\npub const F3_20Pt8_512: MEDIA_TYPE = 4i32;\npub const F3_230Mb_512: MEDIA_TYPE = 21i32;\npub const F3_240M_512: MEDIA_TYPE = 24i32;\npub const F3_2Pt88_512: MEDIA_TYPE = 3i32;\npub const F3_32M_512: MEDIA_TYPE = 25i32;\npub const F3_640_512: MEDIA_TYPE = 14i32;\npub const F3_720_512: MEDIA_TYPE = 5i32;\npub const F5_160_512: MEDIA_TYPE = 10i32;\npub const F5_180_512: MEDIA_TYPE = 9i32;\npub const F5_1Pt23_1024: MEDIA_TYPE = 19i32;\npub const F5_1Pt2_512: MEDIA_TYPE = 1i32;\npub const F5_320_1024: MEDIA_TYPE = 8i32;\npub const F5_320_512: MEDIA_TYPE = 7i32;\npub const F5_360_512: MEDIA_TYPE = 6i32;\npub const F5_640_512: MEDIA_TYPE = 15i32;\npub const F5_720_512: MEDIA_TYPE = 16i32;\npub const F8_256_128: MEDIA_TYPE = 22i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FAT_STATISTICS {\n    pub CreateHits: u32,\n    pub SuccessfulCreates: u32,\n    pub FailedCreates: u32,\n    pub NonCachedReads: u32,\n    pub NonCachedReadBytes: u32,\n    pub NonCachedWrites: u32,\n    pub NonCachedWriteBytes: u32,\n    pub NonCachedDiskReads: u32,\n    pub NonCachedDiskWrites: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILESYSTEM_STATISTICS {\n    pub FileSystemType: FILESYSTEM_STATISTICS_TYPE,\n    pub Version: u16,\n    pub SizeOfCompleteStructure: u32,\n    pub UserFileReads: u32,\n    pub UserFileReadBytes: u32,\n    pub UserDiskReads: u32,\n    pub UserFileWrites: u32,\n    pub UserFileWriteBytes: u32,\n    pub UserDiskWrites: u32,\n    pub MetaDataReads: u32,\n    pub MetaDataReadBytes: u32,\n    pub MetaDataDiskReads: u32,\n    pub MetaDataWrites: u32,\n    pub MetaDataWriteBytes: u32,\n    pub MetaDataDiskWrites: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILESYSTEM_STATISTICS_EX {\n    pub FileSystemType: FILESYSTEM_STATISTICS_TYPE,\n    pub Version: u16,\n    pub SizeOfCompleteStructure: u32,\n    pub UserFileReads: u64,\n    pub UserFileReadBytes: u64,\n    pub UserDiskReads: u64,\n    pub UserFileWrites: u64,\n    pub UserFileWriteBytes: u64,\n    pub UserDiskWrites: u64,\n    pub MetaDataReads: u64,\n    pub MetaDataReadBytes: u64,\n    pub MetaDataDiskReads: u64,\n    pub MetaDataWrites: u64,\n    pub MetaDataWriteBytes: u64,\n    pub MetaDataDiskWrites: u64,\n}\npub type FILESYSTEM_STATISTICS_TYPE = u16;\npub const FILESYSTEM_STATISTICS_TYPE_EXFAT: FILESYSTEM_STATISTICS_TYPE = 3u16;\npub const FILESYSTEM_STATISTICS_TYPE_FAT: FILESYSTEM_STATISTICS_TYPE = 2u16;\npub const FILESYSTEM_STATISTICS_TYPE_NTFS: FILESYSTEM_STATISTICS_TYPE = 1u16;\npub const FILESYSTEM_STATISTICS_TYPE_REFS: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_ALLOCATED_RANGE_BUFFER {\n    pub FileOffset: i64,\n    pub Length: i64,\n}\npub const FILE_ANY_ACCESS: u32 = 0u32;\npub const FILE_CLEAR_ENCRYPTION: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_DESIRED_STORAGE_CLASS_INFORMATION {\n    pub Class: FILE_STORAGE_TIER_CLASS,\n    pub Flags: u32,\n}\npub const FILE_DEVICE_8042_PORT: u32 = 39u32;\npub const FILE_DEVICE_ACPI: u32 = 50u32;\npub const FILE_DEVICE_BATTERY: u32 = 41u32;\npub const FILE_DEVICE_BEEP: u32 = 1u32;\npub const FILE_DEVICE_BIOMETRIC: u32 = 68u32;\npub const FILE_DEVICE_BLUETOOTH: u32 = 65u32;\npub const FILE_DEVICE_BUS_EXTENDER: u32 = 42u32;\npub const FILE_DEVICE_CD_ROM_FILE_SYSTEM: u32 = 3u32;\npub const FILE_DEVICE_CHANGER: u32 = 48u32;\npub const FILE_DEVICE_CONSOLE: u32 = 80u32;\npub const FILE_DEVICE_CONTROLLER: u32 = 4u32;\npub const FILE_DEVICE_CRYPT_PROVIDER: u32 = 63u32;\npub const FILE_DEVICE_DATALINK: u32 = 5u32;\npub const FILE_DEVICE_DEVAPI: u32 = 71u32;\npub const FILE_DEVICE_DFS: u32 = 6u32;\npub const FILE_DEVICE_DFS_FILE_SYSTEM: u32 = 53u32;\npub const FILE_DEVICE_DFS_VOLUME: u32 = 54u32;\npub const FILE_DEVICE_DISK_FILE_SYSTEM: u32 = 8u32;\npub const FILE_DEVICE_EHSTOR: u32 = 70u32;\npub const FILE_DEVICE_EVENT_COLLECTOR: u32 = 95u32;\npub const FILE_DEVICE_FILE_SYSTEM: u32 = 9u32;\npub const FILE_DEVICE_FIPS: u32 = 58u32;\npub const FILE_DEVICE_FULLSCREEN_VIDEO: u32 = 52u32;\npub const FILE_DEVICE_GPIO: u32 = 72u32;\npub const FILE_DEVICE_HOLOGRAPHIC: u32 = 91u32;\npub const FILE_DEVICE_INFINIBAND: u32 = 59u32;\npub const FILE_DEVICE_INPORT_PORT: u32 = 10u32;\npub const FILE_DEVICE_KEYBOARD: u32 = 11u32;\npub const FILE_DEVICE_KS: u32 = 47u32;\npub const FILE_DEVICE_KSEC: u32 = 57u32;\npub const FILE_DEVICE_MAILSLOT: u32 = 12u32;\npub const FILE_DEVICE_MASS_STORAGE: u32 = 45u32;\npub const FILE_DEVICE_MIDI_IN: u32 = 13u32;\npub const FILE_DEVICE_MIDI_OUT: u32 = 14u32;\npub const FILE_DEVICE_MODEM: u32 = 43u32;\npub const FILE_DEVICE_MOUSE: u32 = 15u32;\npub const FILE_DEVICE_MT_COMPOSITE: u32 = 66u32;\npub const FILE_DEVICE_MT_TRANSPORT: u32 = 67u32;\npub const FILE_DEVICE_MULTI_UNC_PROVIDER: u32 = 16u32;\npub const FILE_DEVICE_NAMED_PIPE: u32 = 17u32;\npub const FILE_DEVICE_NETWORK: u32 = 18u32;\npub const FILE_DEVICE_NETWORK_BROWSER: u32 = 19u32;\npub const FILE_DEVICE_NETWORK_FILE_SYSTEM: u32 = 20u32;\npub const FILE_DEVICE_NETWORK_REDIRECTOR: u32 = 40u32;\npub const FILE_DEVICE_NFP: u32 = 81u32;\npub const FILE_DEVICE_NULL: u32 = 21u32;\npub const FILE_DEVICE_NVDIMM: u32 = 90u32;\npub const FILE_DEVICE_PARALLEL_PORT: u32 = 22u32;\npub const FILE_DEVICE_PERSISTENT_MEMORY: u32 = 89u32;\npub const FILE_DEVICE_PHYSICAL_NETCARD: u32 = 23u32;\npub const FILE_DEVICE_PMI: u32 = 69u32;\npub const FILE_DEVICE_POINT_OF_SERVICE: u32 = 84u32;\npub const FILE_DEVICE_PRINTER: u32 = 24u32;\npub const FILE_DEVICE_PRM: u32 = 94u32;\npub const FILE_DEVICE_SCANNER: u32 = 25u32;\npub const FILE_DEVICE_SCREEN: u32 = 28u32;\npub const FILE_DEVICE_SDFXHCI: u32 = 92u32;\npub const FILE_DEVICE_SERENUM: u32 = 55u32;\npub const FILE_DEVICE_SERIAL_MOUSE_PORT: u32 = 26u32;\npub const FILE_DEVICE_SERIAL_PORT: u32 = 27u32;\npub const FILE_DEVICE_SMB: u32 = 46u32;\npub const FILE_DEVICE_SOUND: u32 = 29u32;\npub const FILE_DEVICE_SOUNDWIRE: u32 = 97u32;\npub const FILE_DEVICE_STORAGE_REPLICATION: u32 = 85u32;\npub const FILE_DEVICE_STREAMS: u32 = 30u32;\npub const FILE_DEVICE_SYSENV: u32 = 82u32;\npub const FILE_DEVICE_TAPE_FILE_SYSTEM: u32 = 32u32;\npub const FILE_DEVICE_TERMSRV: u32 = 56u32;\npub const FILE_DEVICE_TRANSPORT: u32 = 33u32;\npub const FILE_DEVICE_TRUST_ENV: u32 = 86u32;\npub const FILE_DEVICE_UCM: u32 = 87u32;\npub const FILE_DEVICE_UCMTCPCI: u32 = 88u32;\npub const FILE_DEVICE_UCMUCSI: u32 = 93u32;\npub const FILE_DEVICE_UNKNOWN: u32 = 34u32;\npub const FILE_DEVICE_USB4: u32 = 96u32;\npub const FILE_DEVICE_USBEX: u32 = 73u32;\npub const FILE_DEVICE_VDM: u32 = 44u32;\npub const FILE_DEVICE_VIDEO: u32 = 35u32;\npub const FILE_DEVICE_VIRTUAL_BLOCK: u32 = 83u32;\npub const FILE_DEVICE_VIRTUAL_DISK: u32 = 36u32;\npub const FILE_DEVICE_VMBUS: u32 = 62u32;\npub const FILE_DEVICE_WAVE_IN: u32 = 37u32;\npub const FILE_DEVICE_WAVE_OUT: u32 = 38u32;\npub const FILE_DEVICE_WPD: u32 = 64u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_FS_PERSISTENT_VOLUME_INFORMATION {\n    pub VolumeFlags: u32,\n    pub FlagMask: u32,\n    pub Version: u32,\n    pub Reserved: u32,\n}\npub const FILE_INITIATE_REPAIR_HINT1_ATTRIBUTE_NON_RESIDENT: u64 = 137438953472u64;\npub const FILE_INITIATE_REPAIR_HINT1_ATTRIBUTE_NOT_FOUND: u64 = 4096u64;\npub const FILE_INITIATE_REPAIR_HINT1_ATTRIBUTE_TOO_SMALL: u64 = 68719476736u64;\npub const FILE_INITIATE_REPAIR_HINT1_CLUSTERS_ALREADY_IN_USE: u64 = 32768u64;\npub const FILE_INITIATE_REPAIR_HINT1_DENY_DEFRAG: u64 = 274877906944u64;\npub const FILE_INITIATE_REPAIR_HINT1_FILE_RECORD_IS_BASE_RECORD: u64 = 524288u64;\npub const FILE_INITIATE_REPAIR_HINT1_FILE_RECORD_NOT_BASE_RECORD: u64 = 8u64;\npub const FILE_INITIATE_REPAIR_HINT1_FILE_RECORD_NOT_EXIST: u64 = 4u64;\npub const FILE_INITIATE_REPAIR_HINT1_FILE_RECORD_NOT_IN_USE: u64 = 1u64;\npub const FILE_INITIATE_REPAIR_HINT1_FILE_RECORD_NOT_ORPHAN: u64 = 262144u64;\npub const FILE_INITIATE_REPAIR_HINT1_FILE_RECORD_REUSED: u64 = 2u64;\npub const FILE_INITIATE_REPAIR_HINT1_INDEX_ENTRY_MISMATCH: u64 = 1099511627776u64;\npub const FILE_INITIATE_REPAIR_HINT1_INVALID_ARRAY_LENGTH_COUNT: u64 = 1048576u64;\npub const FILE_INITIATE_REPAIR_HINT1_INVALID_LCN: u64 = 4294967296u64;\npub const FILE_INITIATE_REPAIR_HINT1_INVALID_ORPHAN_RECOVERY_NAME: u64 = 2199023255552u64;\npub const FILE_INITIATE_REPAIR_HINT1_INVALID_PARENT: u64 = 8388608u64;\npub const FILE_INITIATE_REPAIR_HINT1_INVALID_RUN_LENGTH: u64 = 131072u64;\npub const FILE_INITIATE_REPAIR_HINT1_INVALID_VCN: u64 = 8589934592u64;\npub const FILE_INITIATE_REPAIR_HINT1_LCN_NOT_EXIST: u64 = 65536u64;\npub const FILE_INITIATE_REPAIR_HINT1_MULTIPLE_FILE_NAME_ATTRIBUTES: u64 = 4398046511104u64;\npub const FILE_INITIATE_REPAIR_HINT1_NAME_CONFLICT: u64 = 17179869184u64;\npub const FILE_INITIATE_REPAIR_HINT1_NOTHING_WRONG: u64 = 2048u64;\npub const FILE_INITIATE_REPAIR_HINT1_NOT_IMPLEMENTED: u64 = 32u64;\npub const FILE_INITIATE_REPAIR_HINT1_ORPHAN: u64 = 34359738368u64;\npub const FILE_INITIATE_REPAIR_HINT1_ORPHAN_GENERATED: u64 = 512u64;\npub const FILE_INITIATE_REPAIR_HINT1_OUT_OF_GENERIC_NAMES: u64 = 1073741824u64;\npub const FILE_INITIATE_REPAIR_HINT1_OUT_OF_RESOURCE: u64 = 2147483648u64;\npub const FILE_INITIATE_REPAIR_HINT1_PARENT_FILE_RECORD_NOT_BASE_RECORD: u64 = 134217728u64;\npub const FILE_INITIATE_REPAIR_HINT1_PARENT_FILE_RECORD_NOT_EXIST: u64 = 67108864u64;\npub const FILE_INITIATE_REPAIR_HINT1_PARENT_FILE_RECORD_NOT_INDEX: u64 = 268435456u64;\npub const FILE_INITIATE_REPAIR_HINT1_PARENT_FILE_RECORD_NOT_IN_USE: u64 = 16777216u64;\npub const FILE_INITIATE_REPAIR_HINT1_PARENT_FILE_RECORD_REUSED: u64 = 33554432u64;\npub const FILE_INITIATE_REPAIR_HINT1_POTENTIAL_CROSSLINK: u64 = 8192u64;\npub const FILE_INITIATE_REPAIR_HINT1_PREVIOUS_PARENT_STILL_VALID: u64 = 549755813888u64;\npub const FILE_INITIATE_REPAIR_HINT1_RECURSIVELY_CORRUPTED: u64 = 256u64;\npub const FILE_INITIATE_REPAIR_HINT1_REPAIRED: u64 = 1024u64;\npub const FILE_INITIATE_REPAIR_HINT1_REPAIR_DISABLED: u64 = 128u64;\npub const FILE_INITIATE_REPAIR_HINT1_SID_MISMATCH: u64 = 4194304u64;\npub const FILE_INITIATE_REPAIR_HINT1_SID_VALID: u64 = 2097152u64;\npub const FILE_INITIATE_REPAIR_HINT1_STALE_INFORMATION: u64 = 16384u64;\npub const FILE_INITIATE_REPAIR_HINT1_SYSTEM_FILE: u64 = 16u64;\npub const FILE_INITIATE_REPAIR_HINT1_UNABLE_TO_REPAIR: u64 = 64u64;\npub const FILE_INITIATE_REPAIR_HINT1_VALID_INDEX_ENTRY: u64 = 536870912u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_INITIATE_REPAIR_OUTPUT_BUFFER {\n    pub Hint1: u64,\n    pub Hint2: u64,\n    pub Clsn: u64,\n    pub Status: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_LAYOUT_ENTRY {\n    pub Version: u32,\n    pub NextFileOffset: u32,\n    pub Flags: u32,\n    pub FileAttributes: u32,\n    pub FileReferenceNumber: u64,\n    pub FirstNameOffset: u32,\n    pub FirstStreamOffset: u32,\n    pub ExtraInfoOffset: u32,\n    pub ExtraInfoLength: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_LAYOUT_INFO_ENTRY {\n    pub BasicInformation: FILE_LAYOUT_INFO_ENTRY_0,\n    pub OwnerId: u32,\n    pub SecurityId: u32,\n    pub Usn: i64,\n    pub StorageReserveId: STORAGE_RESERVE_ID,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_LAYOUT_INFO_ENTRY_0 {\n    pub CreationTime: i64,\n    pub LastAccessTime: i64,\n    pub LastWriteTime: i64,\n    pub ChangeTime: i64,\n    pub FileAttributes: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_LAYOUT_NAME_ENTRY {\n    pub NextNameOffset: u32,\n    pub Flags: u32,\n    pub ParentFileReferenceNumber: u64,\n    pub FileNameLength: u32,\n    pub Reserved: u32,\n    pub FileName: [u16; 1],\n}\nimpl Default for FILE_LAYOUT_NAME_ENTRY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FILE_LAYOUT_NAME_ENTRY_DOS: u32 = 2u32;\npub const FILE_LAYOUT_NAME_ENTRY_PRIMARY: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_LEVEL_TRIM {\n    pub Key: u32,\n    pub NumRanges: u32,\n    pub Ranges: [FILE_LEVEL_TRIM_RANGE; 1],\n}\nimpl Default for FILE_LEVEL_TRIM {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_LEVEL_TRIM_OUTPUT {\n    pub NumRangesProcessed: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_LEVEL_TRIM_RANGE {\n    pub Offset: u64,\n    pub Length: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_MAKE_COMPATIBLE_BUFFER {\n    pub CloseDisc: bool,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_OBJECTID_BUFFER {\n    pub ObjectId: [u8; 16],\n    pub Anonymous: FILE_OBJECTID_BUFFER_0,\n}\nimpl Default for FILE_OBJECTID_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union FILE_OBJECTID_BUFFER_0 {\n    pub Anonymous: FILE_OBJECTID_BUFFER_0_0,\n    pub ExtendedInfo: [u8; 48],\n}\nimpl Default for FILE_OBJECTID_BUFFER_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_OBJECTID_BUFFER_0_0 {\n    pub BirthVolumeId: [u8; 16],\n    pub BirthObjectId: [u8; 16],\n    pub DomainId: [u8; 16],\n}\nimpl Default for FILE_OBJECTID_BUFFER_0_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_PREFETCH {\n    pub Type: u32,\n    pub Count: u32,\n    pub Prefetch: [u64; 1],\n}\nimpl Default for FILE_PREFETCH {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_PREFETCH_EX {\n    pub Type: u32,\n    pub Count: u32,\n    pub Context: *mut core::ffi::c_void,\n    pub Prefetch: [u64; 1],\n}\nimpl Default for FILE_PREFETCH_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FILE_PREFETCH_TYPE_FOR_CREATE: u32 = 1u32;\npub const FILE_PREFETCH_TYPE_FOR_CREATE_EX: u32 = 3u32;\npub const FILE_PREFETCH_TYPE_FOR_DIRENUM: u32 = 2u32;\npub const FILE_PREFETCH_TYPE_FOR_DIRENUM_EX: u32 = 4u32;\npub const FILE_PREFETCH_TYPE_MAX: u32 = 4u32;\npub const FILE_PROVIDER_COMPRESSION_MAXIMUM: u32 = 4u32;\npub const FILE_PROVIDER_CURRENT_VERSION: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_PROVIDER_EXTERNAL_INFO_V0 {\n    pub Version: u32,\n    pub Algorithm: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_PROVIDER_EXTERNAL_INFO_V1 {\n    pub Version: u32,\n    pub Algorithm: u32,\n    pub Flags: u32,\n}\npub const FILE_PROVIDER_FLAG_COMPRESS_ON_WRITE: u32 = 1u32;\npub const FILE_PROVIDER_SINGLE_FILE: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_QUERY_ON_DISK_VOL_INFO_BUFFER {\n    pub DirectoryCount: i64,\n    pub FileCount: i64,\n    pub FsFormatMajVersion: u16,\n    pub FsFormatMinVersion: u16,\n    pub FsFormatName: [u16; 12],\n    pub FormatTime: i64,\n    pub LastUpdateTime: i64,\n    pub CopyrightInfo: [u16; 34],\n    pub AbstractInfo: [u16; 34],\n    pub FormattingImplementationInfo: [u16; 34],\n    pub LastModifyingImplementationInfo: [u16; 34],\n}\nimpl Default for FILE_QUERY_ON_DISK_VOL_INFO_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_QUERY_SPARING_BUFFER {\n    pub SparingUnitBytes: u32,\n    pub SoftwareSparing: bool,\n    pub TotalSpareBlocks: u32,\n    pub FreeSpareBlocks: u32,\n}\npub const FILE_READ_ACCESS: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_REFERENCE_RANGE {\n    pub StartingFileReferenceNumber: u64,\n    pub EndingFileReferenceNumber: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_REGION_INFO {\n    pub FileOffset: i64,\n    pub Length: i64,\n    pub Usage: u32,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_REGION_INPUT {\n    pub FileOffset: i64,\n    pub Length: i64,\n    pub DesiredUsage: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_REGION_OUTPUT {\n    pub Flags: u32,\n    pub TotalRegionEntryCount: u32,\n    pub RegionEntryCount: u32,\n    pub Reserved: u32,\n    pub Region: [FILE_REGION_INFO; 1],\n}\nimpl Default for FILE_REGION_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FILE_REGION_USAGE_HUGE_PAGE_ALIGNMENT: u32 = 16u32;\npub const FILE_REGION_USAGE_LARGE_PAGE_ALIGNMENT: u32 = 8u32;\npub const FILE_REGION_USAGE_OTHER_PAGE_ALIGNMENT: u32 = 4u32;\npub const FILE_REGION_USAGE_QUERY_ALIGNMENT: u32 = 8u32;\npub const FILE_REGION_USAGE_VALID_CACHED_DATA: u32 = 1u32;\npub const FILE_REGION_USAGE_VALID_NONCACHED_DATA: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_SET_DEFECT_MGMT_BUFFER {\n    pub Disable: bool,\n}\npub const FILE_SET_ENCRYPTION: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_SET_SPARSE_BUFFER {\n    pub SetSparse: bool,\n}\npub const FILE_SPECIAL_ACCESS: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_STORAGE_TIER {\n    pub Id: windows_sys::core::GUID,\n    pub Name: [u16; 256],\n    pub Description: [u16; 256],\n    pub Flags: u64,\n    pub ProvisionedCapacity: u64,\n    pub MediaType: FILE_STORAGE_TIER_MEDIA_TYPE,\n    pub Class: FILE_STORAGE_TIER_CLASS,\n}\nimpl Default for FILE_STORAGE_TIER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type FILE_STORAGE_TIER_CLASS = i32;\npub const FILE_STORAGE_TIER_DESCRIPTION_LENGTH: u32 = 512u32;\npub type FILE_STORAGE_TIER_FLAGS = u32;\npub const FILE_STORAGE_TIER_FLAG_NO_SEEK_PENALTY: FILE_STORAGE_TIER_FLAGS = 131072u32;\npub const FILE_STORAGE_TIER_FLAG_PARITY: u32 = 8388608u32;\npub const FILE_STORAGE_TIER_FLAG_READ_CACHE: u32 = 4194304u32;\npub const FILE_STORAGE_TIER_FLAG_SMR: u32 = 16777216u32;\npub const FILE_STORAGE_TIER_FLAG_WRITE_BACK_CACHE: u32 = 2097152u32;\npub type FILE_STORAGE_TIER_MEDIA_TYPE = i32;\npub const FILE_STORAGE_TIER_NAME_LENGTH: u32 = 256u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_STORAGE_TIER_REGION {\n    pub TierId: windows_sys::core::GUID,\n    pub Offset: u64,\n    pub Length: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_SYSTEM_RECOGNITION_INFORMATION {\n    pub FileSystem: [i8; 9],\n}\nimpl Default for FILE_SYSTEM_RECOGNITION_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FILE_TYPE_NOTIFICATION_FLAG_USAGE_BEGIN: u32 = 1u32;\npub const FILE_TYPE_NOTIFICATION_FLAG_USAGE_END: u32 = 2u32;\npub const FILE_TYPE_NOTIFICATION_GUID_CRASHDUMP_FILE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9d453eb7_d2a6_4dbd_a2e3_fbd0ed9109a9);\npub const FILE_TYPE_NOTIFICATION_GUID_HIBERNATION_FILE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb7624d64_b9a3_4cf8_8011_5b86c940e7b7);\npub const FILE_TYPE_NOTIFICATION_GUID_PAGE_FILE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x0d0a64a1_38fc_4db8_9fe7_3f4352cd7c5c);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FILE_TYPE_NOTIFICATION_INPUT {\n    pub Flags: u32,\n    pub NumFileTypeIDs: u32,\n    pub FileTypeID: [windows_sys::core::GUID; 1],\n}\nimpl Default for FILE_TYPE_NOTIFICATION_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FILE_WRITE_ACCESS: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_ZERO_DATA_INFORMATION {\n    pub FileOffset: i64,\n    pub BeyondFinalZero: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FILE_ZERO_DATA_INFORMATION_EX {\n    pub FileOffset: i64,\n    pub BeyondFinalZero: i64,\n    pub Flags: u32,\n}\npub const FILE_ZERO_DATA_INFORMATION_FLAG_PRESERVE_CACHED_DATA: u32 = 1u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Security\")]\n#[derive(Clone, Copy, Default)]\npub struct FIND_BY_SID_DATA {\n    pub Restart: u32,\n    pub Sid: super::super::Security::SID,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FIND_BY_SID_OUTPUT {\n    pub NextEntryOffset: u32,\n    pub FileIndex: u32,\n    pub FileNameLength: u32,\n    pub FileName: [u16; 1],\n}\nimpl Default for FIND_BY_SID_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FLAG_USN_TRACK_MODIFIED_RANGES_ENABLE: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FORMAT_EX_PARAMETERS {\n    pub MediaType: MEDIA_TYPE,\n    pub StartCylinderNumber: u32,\n    pub EndCylinderNumber: u32,\n    pub StartHeadNumber: u32,\n    pub EndHeadNumber: u32,\n    pub FormatGapLength: u16,\n    pub SectorsPerTrack: u16,\n    pub SectorNumber: [u16; 1],\n}\nimpl Default for FORMAT_EX_PARAMETERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FORMAT_PARAMETERS {\n    pub MediaType: MEDIA_TYPE,\n    pub StartCylinderNumber: u32,\n    pub EndCylinderNumber: u32,\n    pub StartHeadNumber: u32,\n    pub EndHeadNumber: u32,\n}\npub const FSBPIO_INFL_None: FS_BPIO_INFLAGS = 0i32;\npub const FSBPIO_INFL_SKIP_STORAGE_STACK_QUERY: FS_BPIO_INFLAGS = 1i32;\npub const FSBPIO_OUTFL_COMPATIBLE_STORAGE_DRIVER: FS_BPIO_OUTFLAGS = 8i32;\npub const FSBPIO_OUTFL_FILTER_ATTACH_BLOCKED: FS_BPIO_OUTFLAGS = 4i32;\npub const FSBPIO_OUTFL_None: FS_BPIO_OUTFLAGS = 0i32;\npub const FSBPIO_OUTFL_STREAM_BYPASS_PAUSED: FS_BPIO_OUTFLAGS = 2i32;\npub const FSBPIO_OUTFL_VOLUME_STACK_BYPASS_PAUSED: FS_BPIO_OUTFLAGS = 1i32;\npub const FSCTL_ADD_OVERLAY: u32 = 623408u32;\npub const FSCTL_ADVANCE_FILE_ID: u32 = 590532u32;\npub const FSCTL_ALLOW_EXTENDED_DASD_IO: u32 = 589955u32;\npub const FSCTL_CLEAN_VOLUME_METADATA: u32 = 590716u32;\npub const FSCTL_CLEAR_ALL_LCN_WEAK_REFERENCES: u32 = 590956u32;\npub const FSCTL_CLEAR_LCN_WEAK_REFERENCE: u32 = 590948u32;\npub const FSCTL_CORRUPTION_HANDLING: u32 = 590432u32;\npub const FSCTL_CREATE_LCN_WEAK_REFERENCE: u32 = 590944u32;\npub const FSCTL_CREATE_OR_GET_OBJECT_ID: u32 = 590016u32;\npub const FSCTL_CREATE_USN_JOURNAL: u32 = 590055u32;\npub const FSCTL_CSC_INTERNAL: u32 = 590255u32;\npub const FSCTL_CSV_CONTROL: u32 = 590548u32;\npub const FSCTL_CSV_GET_VOLUME_NAME_FOR_VOLUME_MOUNT_POINT: u32 = 590420u32;\npub const FSCTL_CSV_GET_VOLUME_PATH_NAME: u32 = 590416u32;\npub const FSCTL_CSV_GET_VOLUME_PATH_NAMES_FOR_VOLUME_NAME: u32 = 590424u32;\npub const FSCTL_CSV_H_BREAKING_SYNC_TUNNEL_REQUEST: u32 = 590564u32;\npub const FSCTL_CSV_INTERNAL: u32 = 590444u32;\npub const FSCTL_CSV_MGMT_LOCK: u32 = 590524u32;\npub const FSCTL_CSV_QUERY_DOWN_LEVEL_FILE_SYSTEM_CHARACTERISTICS: u32 = 590528u32;\npub const FSCTL_CSV_QUERY_VETO_FILE_DIRECT_IO: u32 = 590540u32;\npub const FSCTL_CSV_SYNC_TUNNEL_REQUEST: u32 = 590536u32;\npub const FSCTL_CSV_TUNNEL_REQUEST: u32 = 590404u32;\npub const FSCTL_DELETE_CORRUPTED_REFS_CONTAINER: u32 = 590836u32;\npub const FSCTL_DELETE_EXTERNAL_BACKING: u32 = 590612u32;\npub const FSCTL_DELETE_OBJECT_ID: u32 = 589984u32;\npub const FSCTL_DELETE_REPARSE_POINT: u32 = 589996u32;\npub const FSCTL_DELETE_USN_JOURNAL: u32 = 590072u32;\npub const FSCTL_DFSR_SET_GHOST_HANDLE_STATE: u32 = 590264u32;\npub const FSCTL_DISABLE_LOCAL_BUFFERING: u32 = 590520u32;\npub const FSCTL_DISMOUNT_VOLUME: u32 = 589856u32;\npub const FSCTL_DUPLICATE_CLUSTER: u32 = 590940u32;\npub const FSCTL_DUPLICATE_EXTENTS_TO_FILE: u32 = 623428u32;\npub const FSCTL_DUPLICATE_EXTENTS_TO_FILE_EX: u32 = 623592u32;\npub const FSCTL_ENABLE_PER_IO_FLAGS: u32 = 590892u32;\npub const FSCTL_ENABLE_UPGRADE: u32 = 622800u32;\npub const FSCTL_ENCRYPTION_FSCTL_IO: u32 = 590043u32;\npub const FSCTL_ENCRYPTION_KEY_CONTROL: u32 = 590852u32;\npub const FSCTL_ENUM_EXTERNAL_BACKING: u32 = 590616u32;\npub const FSCTL_ENUM_OVERLAY: u32 = 590623u32;\npub const FSCTL_ENUM_USN_DATA: u32 = 590003u32;\npub const FSCTL_EXTEND_VOLUME: u32 = 590064u32;\npub const FSCTL_FILESYSTEM_GET_STATISTICS: u32 = 589920u32;\npub const FSCTL_FILESYSTEM_GET_STATISTICS_EX: u32 = 590732u32;\npub const FSCTL_FILE_LEVEL_TRIM: u32 = 623112u32;\npub const FSCTL_FILE_PREFETCH: u32 = 590112u32;\npub const FSCTL_FILE_TYPE_NOTIFICATION: u32 = 590340u32;\npub const FSCTL_FIND_FILES_BY_SID: u32 = 589967u32;\npub const FSCTL_GET_BOOT_AREA_INFO: u32 = 590384u32;\npub const FSCTL_GET_COMPRESSION: u32 = 589884u32;\npub const FSCTL_GET_EXTERNAL_BACKING: u32 = 590608u32;\npub const FSCTL_GET_FILTER_FILE_IDENTIFIER: u32 = 590788u32;\npub const FSCTL_GET_INTEGRITY_INFORMATION: u32 = 590460u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FSCTL_GET_INTEGRITY_INFORMATION_BUFFER {\n    pub ChecksumAlgorithm: u16,\n    pub Reserved: u16,\n    pub Flags: u32,\n    pub ChecksumChunkSizeInBytes: u32,\n    pub ClusterSizeInBytes: u32,\n}\npub const FSCTL_GET_NTFS_FILE_RECORD: u32 = 589928u32;\npub const FSCTL_GET_NTFS_VOLUME_DATA: u32 = 589924u32;\npub const FSCTL_GET_OBJECT_ID: u32 = 589980u32;\npub const FSCTL_GET_REFS_VOLUME_DATA: u32 = 590552u32;\npub const FSCTL_GET_REPAIR: u32 = 590236u32;\npub const FSCTL_GET_REPARSE_POINT: u32 = 589992u32;\npub const FSCTL_GET_RETRIEVAL_POINTERS: u32 = 589939u32;\npub const FSCTL_GET_RETRIEVAL_POINTERS_AND_REFCOUNT: u32 = 590803u32;\npub const FSCTL_GET_RETRIEVAL_POINTER_BASE: u32 = 590388u32;\npub const FSCTL_GET_RETRIEVAL_POINTER_COUNT: u32 = 590891u32;\npub const FSCTL_GET_VOLUME_BITMAP: u32 = 589935u32;\npub const FSCTL_GET_WOF_VERSION: u32 = 590696u32;\npub const FSCTL_GHOST_FILE_EXTENTS: u32 = 623532u32;\npub const FSCTL_HCS_ASYNC_TUNNEL_REQUEST: u32 = 590704u32;\npub const FSCTL_HCS_SYNC_NO_WRITE_TUNNEL_REQUEST: u32 = 590776u32;\npub const FSCTL_HCS_SYNC_TUNNEL_REQUEST: u32 = 590700u32;\npub const FSCTL_INITIATE_FILE_METADATA_OPTIMIZATION: u32 = 590684u32;\npub const FSCTL_INITIATE_REPAIR: u32 = 590248u32;\npub const FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF: u32 = 1u32;\npub const FSCTL_INVALIDATE_VOLUMES: u32 = 589908u32;\npub const FSCTL_IS_CSV_FILE: u32 = 590408u32;\npub const FSCTL_IS_FILE_ON_CSV_VOLUME: u32 = 590428u32;\npub const FSCTL_IS_PATHNAME_VALID: u32 = 589868u32;\npub const FSCTL_IS_VOLUME_DIRTY: u32 = 589944u32;\npub const FSCTL_IS_VOLUME_MOUNTED: u32 = 589864u32;\npub const FSCTL_IS_VOLUME_OWNED_BYCSVFS: u32 = 590456u32;\npub const FSCTL_LMR_QUERY_INFO: u32 = 590968u32;\npub const FSCTL_LOCK_VOLUME: u32 = 589848u32;\npub const FSCTL_LOOKUP_STREAM_FROM_CLUSTER: u32 = 590332u32;\npub const FSCTL_MAKE_MEDIA_COMPATIBLE: u32 = 622896u32;\npub const FSCTL_MANAGE_BYPASS_IO: u32 = 590920u32;\npub const FSCTL_MARK_AS_SYSTEM_HIVE: u32 = 589903u32;\npub const FSCTL_MARK_HANDLE: u32 = 590076u32;\npub const FSCTL_MARK_VOLUME_DIRTY: u32 = 589872u32;\npub const FSCTL_MOVE_FILE: u32 = 589940u32;\npub const FSCTL_NOTIFY_DATA_CHANGE: u32 = 590844u32;\npub const FSCTL_NOTIFY_STORAGE_SPACE_ALLOCATION: u32 = 590748u32;\npub const FSCTL_OFFLOAD_READ: u32 = 606820u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FSCTL_OFFLOAD_READ_INPUT {\n    pub Size: u32,\n    pub Flags: u32,\n    pub TokenTimeToLive: u32,\n    pub Reserved: u32,\n    pub FileOffset: u64,\n    pub CopyLength: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FSCTL_OFFLOAD_READ_OUTPUT {\n    pub Size: u32,\n    pub Flags: u32,\n    pub TransferLength: u64,\n    pub Token: [u8; 512],\n}\nimpl Default for FSCTL_OFFLOAD_READ_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FSCTL_OFFLOAD_WRITE: u32 = 623208u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FSCTL_OFFLOAD_WRITE_INPUT {\n    pub Size: u32,\n    pub Flags: u32,\n    pub FileOffset: u64,\n    pub CopyLength: u64,\n    pub TransferOffset: u64,\n    pub Token: [u8; 512],\n}\nimpl Default for FSCTL_OFFLOAD_WRITE_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FSCTL_OFFLOAD_WRITE_OUTPUT {\n    pub Size: u32,\n    pub Flags: u32,\n    pub LengthWritten: u64,\n}\npub const FSCTL_OPBATCH_ACK_CLOSE_PENDING: u32 = 589840u32;\npub const FSCTL_OPLOCK_BREAK_ACKNOWLEDGE: u32 = 589836u32;\npub const FSCTL_OPLOCK_BREAK_ACK_NO_2: u32 = 589904u32;\npub const FSCTL_OPLOCK_BREAK_NOTIFY: u32 = 589844u32;\npub const FSCTL_QUERY_ALLOCATED_RANGES: u32 = 606415u32;\npub const FSCTL_QUERY_ASYNC_DUPLICATE_EXTENTS_STATUS: u32 = 590896u32;\npub const FSCTL_QUERY_BAD_RANGES: u32 = 590828u32;\npub const FSCTL_QUERY_DEPENDENT_VOLUME: u32 = 590320u32;\npub const FSCTL_QUERY_DIRECT_ACCESS_EXTENTS: u32 = 590747u32;\npub const FSCTL_QUERY_DIRECT_IMAGE_ORIGINAL_BASE: u32 = 590756u32;\npub const FSCTL_QUERY_EXTENT_READ_CACHE_INFO: u32 = 590711u32;\npub const FSCTL_QUERY_FAT_BPB: u32 = 589912u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FSCTL_QUERY_FAT_BPB_BUFFER {\n    pub First0x24BytesOfBootSector: [u8; 36],\n}\nimpl Default for FSCTL_QUERY_FAT_BPB_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FSCTL_QUERY_FILE_LAYOUT: u32 = 590455u32;\npub const FSCTL_QUERY_FILE_METADATA_OPTIMIZATION: u32 = 590688u32;\npub const FSCTL_QUERY_FILE_REGIONS: u32 = 590468u32;\npub const FSCTL_QUERY_FILE_SYSTEM_RECOGNITION: u32 = 590412u32;\npub const FSCTL_QUERY_GHOSTED_FILE_EXTENTS: u32 = 590768u32;\npub const FSCTL_QUERY_LCN_WEAK_REFERENCE: u32 = 590952u32;\npub const FSCTL_QUERY_ON_DISK_VOLUME_INFO: u32 = 590140u32;\npub const FSCTL_QUERY_PAGEFILE_ENCRYPTION: u32 = 590312u32;\npub const FSCTL_QUERY_PERSISTENT_VOLUME_STATE: u32 = 590396u32;\npub const FSCTL_QUERY_REFS_SMR_VOLUME_INFO: u32 = 590812u32;\npub const FSCTL_QUERY_REFS_VOLUME_COUNTER_INFO: u32 = 590715u32;\npub const FSCTL_QUERY_REGION_INFO: u32 = 590576u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FSCTL_QUERY_REGION_INFO_INPUT {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub NumberOfTierIds: u32,\n    pub TierIds: [windows_sys::core::GUID; 1],\n}\nimpl Default for FSCTL_QUERY_REGION_INFO_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FSCTL_QUERY_REGION_INFO_OUTPUT {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub Reserved: u32,\n    pub Alignment: u64,\n    pub TotalNumberOfRegions: u32,\n    pub NumberOfRegionsReturned: u32,\n    pub Regions: [FILE_STORAGE_TIER_REGION; 1],\n}\nimpl Default for FSCTL_QUERY_REGION_INFO_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FSCTL_QUERY_RETRIEVAL_POINTERS: u32 = 589883u32;\npub const FSCTL_QUERY_SHARED_VIRTUAL_DISK_SUPPORT: u32 = 590592u32;\npub const FSCTL_QUERY_SPARING_INFO: u32 = 590136u32;\npub const FSCTL_QUERY_STORAGE_CLASSES: u32 = 590572u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FSCTL_QUERY_STORAGE_CLASSES_OUTPUT {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: FILE_STORAGE_TIER_FLAGS,\n    pub TotalNumberOfTiers: u32,\n    pub NumberOfTiersReturned: u32,\n    pub Tiers: [FILE_STORAGE_TIER; 1],\n}\nimpl Default for FSCTL_QUERY_STORAGE_CLASSES_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FSCTL_QUERY_USN_JOURNAL: u32 = 590068u32;\npub const FSCTL_QUERY_VOLUME_CONTAINER_STATE: u32 = 590736u32;\npub const FSCTL_QUERY_VOLUME_NUMA_INFO: u32 = 590804u32;\npub const FSCTL_READ_FILE_USN_DATA: u32 = 590059u32;\npub const FSCTL_READ_FROM_PLEX: u32 = 606494u32;\npub const FSCTL_READ_RAW_ENCRYPTED: u32 = 590051u32;\npub const FSCTL_READ_UNPRIVILEGED_USN_JOURNAL: u32 = 590763u32;\npub const FSCTL_READ_USN_JOURNAL: u32 = 590011u32;\npub const FSCTL_REARRANGE_FILE: u32 = 640032u32;\npub const FSCTL_RECALL_FILE: u32 = 590103u32;\npub const FSCTL_REFS_CHECKPOINT_VOLUME: u32 = 590972u32;\npub const FSCTL_REFS_DEALLOCATE_RANGES: u32 = 590808u32;\npub const FSCTL_REFS_DEALLOCATE_RANGES_EX: u32 = 590924u32;\npub const FSCTL_REFS_QUERY_VOLUME_COMPRESSION_INFO: u32 = 590936u32;\npub const FSCTL_REFS_QUERY_VOLUME_DEDUP_INFO: u32 = 590964u32;\npub const FSCTL_REFS_QUERY_VOLUME_IO_METRICS_INFO: u32 = 590988u32;\npub const FSCTL_REFS_QUERY_VOLUME_TOTAL_SHARED_LCNS: u32 = 590976u32;\npub const FSCTL_REFS_SET_VOLUME_COMPRESSION_INFO: u32 = 590932u32;\npub const FSCTL_REFS_SET_VOLUME_DEDUP_INFO: u32 = 590960u32;\npub const FSCTL_REFS_SET_VOLUME_IO_METRICS_INFO: u32 = 590984u32;\npub const FSCTL_REFS_STREAM_SNAPSHOT_MANAGEMENT: u32 = 590912u32;\npub const FSCTL_REMOVE_OVERLAY: u32 = 623412u32;\npub const FSCTL_REPAIR_COPIES: u32 = 639668u32;\npub const FSCTL_REQUEST_BATCH_OPLOCK: u32 = 589832u32;\npub const FSCTL_REQUEST_FILTER_OPLOCK: u32 = 589916u32;\npub const FSCTL_REQUEST_OPLOCK: u32 = 590400u32;\npub const FSCTL_REQUEST_OPLOCK_LEVEL_1: u32 = 589824u32;\npub const FSCTL_REQUEST_OPLOCK_LEVEL_2: u32 = 589828u32;\npub const FSCTL_RESET_VOLUME_ALLOCATION_HINTS: u32 = 590316u32;\npub const FSCTL_RKF_INTERNAL: u32 = 590511u32;\npub const FSCTL_SCRUB_DATA: u32 = 590512u32;\npub const FSCTL_SCRUB_UNDISCOVERABLE_ID: u32 = 590840u32;\npub const FSCTL_SD_GLOBAL_CHANGE: u32 = 590324u32;\npub const FSCTL_SECURITY_ID_CHECK: u32 = 606391u32;\npub const FSCTL_SET_BOOTLOADER_ACCESSED: u32 = 589903u32;\npub const FSCTL_SET_CACHED_RUNS_STATE: u32 = 590928u32;\npub const FSCTL_SET_COMPRESSION: u32 = 639040u32;\npub const FSCTL_SET_DAX_ALLOC_ALIGNMENT_HINT: u32 = 590832u32;\npub const FSCTL_SET_DEFECT_MANAGEMENT: u32 = 622900u32;\npub const FSCTL_SET_ENCRYPTION: u32 = 590039u32;\npub const FSCTL_SET_EXTERNAL_BACKING: u32 = 590604u32;\npub const FSCTL_SET_INTEGRITY_INFORMATION: u32 = 639616u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FSCTL_SET_INTEGRITY_INFORMATION_BUFFER {\n    pub ChecksumAlgorithm: u16,\n    pub Reserved: u16,\n    pub Flags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FSCTL_SET_INTEGRITY_INFORMATION_BUFFER_EX {\n    pub EnableIntegrity: u8,\n    pub KeepIntegrityStateUnchanged: u8,\n    pub Reserved: u16,\n    pub Flags: u32,\n    pub Version: u8,\n    pub Reserved2: [u8; 7],\n}\nimpl Default for FSCTL_SET_INTEGRITY_INFORMATION_BUFFER_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FSCTL_SET_INTEGRITY_INFORMATION_EX: u32 = 590720u32;\npub const FSCTL_SET_LAYER_ROOT: u32 = 590740u32;\npub const FSCTL_SET_OBJECT_ID: u32 = 589976u32;\npub const FSCTL_SET_OBJECT_ID_EXTENDED: u32 = 590012u32;\npub const FSCTL_SET_PERSISTENT_VOLUME_STATE: u32 = 590392u32;\npub const FSCTL_SET_PURGE_FAILURE_MODE: u32 = 590448u32;\npub const FSCTL_SET_REFS_FILE_STRICTLY_SEQUENTIAL: u32 = 590820u32;\npub const FSCTL_SET_REFS_SMR_VOLUME_GC_PARAMETERS: u32 = 590816u32;\npub const FSCTL_SET_REPAIR: u32 = 590232u32;\npub const FSCTL_SET_REPARSE_POINT: u32 = 589988u32;\npub const FSCTL_SET_REPARSE_POINT_EX: u32 = 590860u32;\npub const FSCTL_SET_SHORT_NAME_BEHAVIOR: u32 = 590260u32;\npub const FSCTL_SET_SPARSE: u32 = 590020u32;\npub const FSCTL_SET_VOLUME_COMPRESSION_STATE: u32 = 590144u32;\npub const FSCTL_SET_ZERO_DATA: u32 = 622792u32;\npub const FSCTL_SET_ZERO_ON_DEALLOCATION: u32 = 590228u32;\npub const FSCTL_SHRINK_VOLUME: u32 = 590256u32;\npub const FSCTL_SHUFFLE_FILE: u32 = 639808u32;\npub const FSCTL_SIS_COPYFILE: u32 = 590080u32;\npub const FSCTL_SIS_LINK_FILES: u32 = 639236u32;\npub const FSCTL_SMB_SHARE_FLUSH_AND_PURGE: u32 = 590908u32;\npub const FSCTL_SPARSE_OVERALLOCATE: u32 = 590668u32;\npub const FSCTL_SSDI_STORAGE_REQUEST: u32 = 590752u32;\npub const FSCTL_START_VIRTUALIZATION_INSTANCE: u32 = 590784u32;\npub const FSCTL_START_VIRTUALIZATION_INSTANCE_EX: u32 = 590848u32;\npub const FSCTL_STORAGE_QOS_CONTROL: u32 = 590672u32;\npub const FSCTL_STREAMS_ASSOCIATE_ID: u32 = 590792u32;\npub const FSCTL_STREAMS_QUERY_ID: u32 = 590796u32;\npub const FSCTL_STREAMS_QUERY_PARAMETERS: u32 = 590788u32;\npub const FSCTL_SUSPEND_OVERLAY: u32 = 590724u32;\npub const FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST: u32 = 590692u32;\npub const FSCTL_SVHDX_SET_INITIATOR_INFORMATION: u32 = 590600u32;\npub const FSCTL_SVHDX_SYNC_TUNNEL_REQUEST: u32 = 590596u32;\npub const FSCTL_TXFS_CREATE_MINIVERSION: u32 = 622972u32;\npub const FSCTL_TXFS_CREATE_SECONDARY_RM: u32 = 622952u32;\npub const FSCTL_TXFS_GET_METADATA_INFO: u32 = 606572u32;\npub const FSCTL_TXFS_GET_TRANSACTED_VERSION: u32 = 606576u32;\npub const FSCTL_TXFS_LIST_TRANSACTIONS: u32 = 606692u32;\npub const FSCTL_TXFS_LIST_TRANSACTION_LOCKED_FILES: u32 = 606688u32;\npub const FSCTL_TXFS_MODIFY_RM: u32 = 622916u32;\npub const FSCTL_TXFS_QUERY_RM_INFORMATION: u32 = 606536u32;\npub const FSCTL_TXFS_READ_BACKUP_INFORMATION: u32 = 606560u32;\npub const FSCTL_TXFS_READ_BACKUP_INFORMATION2: u32 = 590328u32;\npub const FSCTL_TXFS_ROLLFORWARD_REDO: u32 = 622928u32;\npub const FSCTL_TXFS_ROLLFORWARD_UNDO: u32 = 622932u32;\npub const FSCTL_TXFS_SAVEPOINT_INFORMATION: u32 = 622968u32;\npub const FSCTL_TXFS_SHUTDOWN_RM: u32 = 622940u32;\npub const FSCTL_TXFS_START_RM: u32 = 622936u32;\npub const FSCTL_TXFS_TRANSACTION_ACTIVE: u32 = 606604u32;\npub const FSCTL_TXFS_WRITE_BACKUP_INFORMATION: u32 = 622948u32;\npub const FSCTL_TXFS_WRITE_BACKUP_INFORMATION2: u32 = 590336u32;\npub const FSCTL_UNLOCK_VOLUME: u32 = 589852u32;\npub const FSCTL_UNMAP_SPACE: u32 = 590772u32;\npub const FSCTL_UPDATE_OVERLAY: u32 = 623416u32;\npub const FSCTL_UPGRADE_VOLUME: u32 = 590980u32;\npub const FSCTL_USN_TRACK_MODIFIED_RANGES: u32 = 590580u32;\npub const FSCTL_VIRTUAL_STORAGE_PASSTHROUGH: u32 = 590884u32;\npub const FSCTL_VIRTUAL_STORAGE_QUERY_PROPERTY: u32 = 590728u32;\npub const FSCTL_VIRTUAL_STORAGE_SET_BEHAVIOR: u32 = 590856u32;\npub const FSCTL_WAIT_FOR_REPAIR: u32 = 590240u32;\npub const FSCTL_WRITE_RAW_ENCRYPTED: u32 = 590047u32;\npub const FSCTL_WRITE_USN_CLOSE_RECORD: u32 = 590063u32;\npub const FSCTL_WRITE_USN_REASON: u32 = 590544u32;\npub type FS_BPIO_INFLAGS = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FS_BPIO_INFO {\n    pub ActiveBypassIoCount: u32,\n    pub StorageDriverNameLen: u16,\n    pub StorageDriverName: [u16; 32],\n}\nimpl Default for FS_BPIO_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct FS_BPIO_INPUT {\n    pub Operation: FS_BPIO_OPERATIONS,\n    pub InFlags: FS_BPIO_INFLAGS,\n    pub Reserved1: u64,\n    pub Reserved2: u64,\n}\npub type FS_BPIO_OPERATIONS = i32;\npub const FS_BPIO_OP_DISABLE: FS_BPIO_OPERATIONS = 2i32;\npub const FS_BPIO_OP_ENABLE: FS_BPIO_OPERATIONS = 1i32;\npub const FS_BPIO_OP_GET_INFO: FS_BPIO_OPERATIONS = 8i32;\npub const FS_BPIO_OP_MAX_OPERATION: FS_BPIO_OPERATIONS = 9i32;\npub const FS_BPIO_OP_QUERY: FS_BPIO_OPERATIONS = 3i32;\npub const FS_BPIO_OP_STREAM_PAUSE: FS_BPIO_OPERATIONS = 6i32;\npub const FS_BPIO_OP_STREAM_RESUME: FS_BPIO_OPERATIONS = 7i32;\npub const FS_BPIO_OP_VOLUME_STACK_PAUSE: FS_BPIO_OPERATIONS = 4i32;\npub const FS_BPIO_OP_VOLUME_STACK_RESUME: FS_BPIO_OPERATIONS = 5i32;\npub type FS_BPIO_OUTFLAGS = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FS_BPIO_OUTPUT {\n    pub Operation: FS_BPIO_OPERATIONS,\n    pub OutFlags: FS_BPIO_OUTFLAGS,\n    pub Reserved1: u64,\n    pub Reserved2: u64,\n    pub Anonymous: FS_BPIO_OUTPUT_0,\n}\nimpl Default for FS_BPIO_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union FS_BPIO_OUTPUT_0 {\n    pub Enable: FS_BPIO_RESULTS,\n    pub Query: FS_BPIO_RESULTS,\n    pub VolumeStackResume: FS_BPIO_RESULTS,\n    pub StreamResume: FS_BPIO_RESULTS,\n    pub GetInfo: FS_BPIO_INFO,\n}\nimpl Default for FS_BPIO_OUTPUT_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct FS_BPIO_RESULTS {\n    pub OpStatus: u32,\n    pub FailingDriverNameLen: u16,\n    pub FailingDriverName: [u16; 32],\n    pub FailureReasonLen: u16,\n    pub FailureReason: [u16; 128],\n}\nimpl Default for FS_BPIO_RESULTS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const FW_ISSUEID_NO_ISSUE: u32 = 0u32;\npub const FW_ISSUEID_UNKNOWN: u32 = 4294967295u32;\npub const FileSnapStateInactive: DUPLICATE_EXTENTS_STATE = 0i32;\npub const FileSnapStateSource: DUPLICATE_EXTENTS_STATE = 1i32;\npub const FileSnapStateTarget: DUPLICATE_EXTENTS_STATE = 2i32;\npub const FileStorageTierClassCapacity: FILE_STORAGE_TIER_CLASS = 1i32;\npub const FileStorageTierClassMax: FILE_STORAGE_TIER_CLASS = 3i32;\npub const FileStorageTierClassPerformance: FILE_STORAGE_TIER_CLASS = 2i32;\npub const FileStorageTierClassUnspecified: FILE_STORAGE_TIER_CLASS = 0i32;\npub const FileStorageTierMediaTypeDisk: FILE_STORAGE_TIER_MEDIA_TYPE = 1i32;\npub const FileStorageTierMediaTypeMax: FILE_STORAGE_TIER_MEDIA_TYPE = 5i32;\npub const FileStorageTierMediaTypeScm: FILE_STORAGE_TIER_MEDIA_TYPE = 4i32;\npub const FileStorageTierMediaTypeSsd: FILE_STORAGE_TIER_MEDIA_TYPE = 2i32;\npub const FileStorageTierMediaTypeUnspecified: FILE_STORAGE_TIER_MEDIA_TYPE = 0i32;\npub const FixedMedia: MEDIA_TYPE = 12i32;\npub const FormFactor1_8: STORAGE_DEVICE_FORM_FACTOR = 3i32;\npub const FormFactor1_8Less: STORAGE_DEVICE_FORM_FACTOR = 4i32;\npub const FormFactor2_5: STORAGE_DEVICE_FORM_FACTOR = 2i32;\npub const FormFactor3_5: STORAGE_DEVICE_FORM_FACTOR = 1i32;\npub const FormFactorDimm: STORAGE_DEVICE_FORM_FACTOR = 10i32;\npub const FormFactorEmbedded: STORAGE_DEVICE_FORM_FACTOR = 5i32;\npub const FormFactorM_2: STORAGE_DEVICE_FORM_FACTOR = 8i32;\npub const FormFactorMemoryCard: STORAGE_DEVICE_FORM_FACTOR = 6i32;\npub const FormFactorPCIeBoard: STORAGE_DEVICE_FORM_FACTOR = 9i32;\npub const FormFactorUnknown: STORAGE_DEVICE_FORM_FACTOR = 0i32;\npub const FormFactormSata: STORAGE_DEVICE_FORM_FACTOR = 7i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct GETVERSIONINPARAMS {\n    pub bVersion: u8,\n    pub bRevision: u8,\n    pub bReserved: u8,\n    pub bIDEDeviceMap: u8,\n    pub fCapabilities: u32,\n    pub dwReserved: [u32; 4],\n}\nimpl Default for GETVERSIONINPARAMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct GET_CHANGER_PARAMETERS {\n    pub Size: u32,\n    pub NumberTransportElements: u16,\n    pub NumberStorageElements: u16,\n    pub NumberCleanerSlots: u16,\n    pub NumberIEElements: u16,\n    pub NumberDataTransferElements: u16,\n    pub NumberOfDoors: u16,\n    pub FirstSlotNumber: u16,\n    pub FirstDriveNumber: u16,\n    pub FirstTransportNumber: u16,\n    pub FirstIEPortNumber: u16,\n    pub FirstCleanerSlotAddress: u16,\n    pub MagazineSize: u16,\n    pub DriveCleanTimeout: u32,\n    pub Features0: CHANGER_FEATURES,\n    pub Features1: GET_CHANGER_PARAMETERS_FEATURES1,\n    pub MoveFromTransport: u8,\n    pub MoveFromSlot: u8,\n    pub MoveFromIePort: u8,\n    pub MoveFromDrive: u8,\n    pub ExchangeFromTransport: u8,\n    pub ExchangeFromSlot: u8,\n    pub ExchangeFromIePort: u8,\n    pub ExchangeFromDrive: u8,\n    pub LockUnlockCapabilities: u8,\n    pub PositionCapabilities: u8,\n    pub Reserved1: [u8; 2],\n    pub Reserved2: [u32; 2],\n}\nimpl Default for GET_CHANGER_PARAMETERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type GET_CHANGER_PARAMETERS_FEATURES1 = u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GET_DEVICE_INTERNAL_STATUS_DATA_REQUEST {\n    pub Version: u32,\n    pub Size: u32,\n    pub RequestDataType: DEVICE_INTERNAL_STATUS_DATA_REQUEST_TYPE,\n    pub RequestDataSet: DEVICE_INTERNAL_STATUS_DATA_SET,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GET_DISK_ATTRIBUTES {\n    pub Version: u32,\n    pub Reserved1: u32,\n    pub Attributes: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct GET_FILTER_FILE_IDENTIFIER_INPUT {\n    pub AltitudeLength: u16,\n    pub Altitude: [u16; 1],\n}\nimpl Default for GET_FILTER_FILE_IDENTIFIER_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct GET_FILTER_FILE_IDENTIFIER_OUTPUT {\n    pub FilterFileIdentifierLength: u16,\n    pub FilterFileIdentifier: [u8; 1],\n}\nimpl Default for GET_FILTER_FILE_IDENTIFIER_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GET_LENGTH_INFORMATION {\n    pub Length: i64,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy)]\npub struct GET_MEDIA_TYPES {\n    pub DeviceType: u32,\n    pub MediaInfoCount: u32,\n    pub MediaInfo: [DEVICE_MEDIA_INFO; 1],\n}\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\nimpl Default for GET_MEDIA_TYPES {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const GET_VOLUME_BITMAP_FLAG_MASK_METADATA: u32 = 1u32;\npub type GPT_ATTRIBUTES = u64;\npub const GPT_ATTRIBUTE_LEGACY_BIOS_BOOTABLE: u64 = 4u64;\npub const GPT_ATTRIBUTE_NO_BLOCK_IO_PROTOCOL: u64 = 2u64;\npub const GPT_ATTRIBUTE_PLATFORM_REQUIRED: GPT_ATTRIBUTES = 1u64;\npub const GPT_BASIC_DATA_ATTRIBUTE_DAX: u64 = 288230376151711744u64;\npub const GPT_BASIC_DATA_ATTRIBUTE_HIDDEN: GPT_ATTRIBUTES = 4611686018427387904u64;\npub const GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER: GPT_ATTRIBUTES = 9223372036854775808u64;\npub const GPT_BASIC_DATA_ATTRIBUTE_OFFLINE: u64 = 576460752303423488u64;\npub const GPT_BASIC_DATA_ATTRIBUTE_READ_ONLY: GPT_ATTRIBUTES = 1152921504606846976u64;\npub const GPT_BASIC_DATA_ATTRIBUTE_SERVICE: u64 = 144115188075855872u64;\npub const GPT_BASIC_DATA_ATTRIBUTE_SHADOW_COPY: GPT_ATTRIBUTES = 2305843009213693952u64;\npub const GPT_SPACES_ATTRIBUTE_NO_METADATA: u64 = 9223372036854775808u64;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct GP_LOG_PAGE_DESCRIPTOR {\n    pub LogAddress: u16,\n    pub LogSectors: u16,\n}\npub const GUID_DEVICEDUMP_DRIVER_STORAGE_PORT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xda82441d_7142_4bc1_b844_0807c5a4b67f);\npub const GUID_DEVICEDUMP_STORAGE_DEVICE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xd8e2592f_1aab_4d56_a746_1f7585df40f4);\npub const GUID_DEVINTERFACE_CDCHANGER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53f56312_b6bf_11d0_94f2_00a0c91efb8b);\npub const GUID_DEVINTERFACE_CDROM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53f56308_b6bf_11d0_94f2_00a0c91efb8b);\npub const GUID_DEVINTERFACE_COMPORT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x86e0d1e0_8089_11d0_9ce4_08003e301f73);\npub const GUID_DEVINTERFACE_DISK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53f56307_b6bf_11d0_94f2_00a0c91efb8b);\npub const GUID_DEVINTERFACE_FLOPPY: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53f56311_b6bf_11d0_94f2_00a0c91efb8b);\npub const GUID_DEVINTERFACE_HIDDEN_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7f108a28_9833_4b3b_b780_2c6b5fa5c062);\npub const GUID_DEVINTERFACE_MEDIUMCHANGER: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53f56310_b6bf_11d0_94f2_00a0c91efb8b);\npub const GUID_DEVINTERFACE_PARTITION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53f5630a_b6bf_11d0_94f2_00a0c91efb8b);\npub const GUID_DEVINTERFACE_SCM_PHYSICAL_DEVICE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4283609d_4dc2_43be_bbb4_4f15dfce2c61);\npub const GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4d36e978_e325_11ce_bfc1_08002be10318);\npub const GUID_DEVINTERFACE_SERVICE_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6ead3d82_25ec_46bc_b7fd_c1f0df8f5037);\npub const GUID_DEVINTERFACE_SES: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x1790c9ec_47d5_4df3_b5af_9adf3cf23e48);\npub const GUID_DEVINTERFACE_STORAGEPORT: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x2accfe60_c130_11d2_b082_00a0c91efb8b);\npub const GUID_DEVINTERFACE_TAPE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53f5630b_b6bf_11d0_94f2_00a0c91efb8b);\npub const GUID_DEVINTERFACE_UNIFIED_ACCESS_RPMB: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x27447c21_bcc3_4d07_a05b_a3395bb4eee7);\npub const GUID_DEVINTERFACE_VMLUN: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6f416619_9f29_42a5_b20b_37e219ca02b0);\npub const GUID_DEVINTERFACE_VOLUME: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53f5630d_b6bf_11d0_94f2_00a0c91efb8b);\npub const GUID_DEVINTERFACE_WRITEONCEDISK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x53f5630c_b6bf_11d0_94f2_00a0c91efb8b);\npub const GUID_DEVINTERFACE_ZNSDISK: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xb87941c5_ffdb_43c7_b6b1_20b632f0b109);\npub const GUID_SCM_PD_HEALTH_NOTIFICATION: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x9da2d386_72f5_4ee3_8155_eca0678e3b06);\npub const GUID_SCM_PD_PASSTHROUGH_INVDIMM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4309ac30_0d11_11e4_9191_0800200c9a66);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct HISTOGRAM_BUCKET {\n    pub Reads: u32,\n    pub Writes: u32,\n}\npub const HIST_NO_OF_BUCKETS: u32 = 24u32;\npub const HITACHI_12_WO: STORAGE_MEDIA_TYPE = 68i32;\npub const HealthStatusDisabled: STORAGE_COMPONENT_HEALTH_STATUS = 4i32;\npub const HealthStatusFailed: STORAGE_COMPONENT_HEALTH_STATUS = 5i32;\npub const HealthStatusNormal: STORAGE_COMPONENT_HEALTH_STATUS = 1i32;\npub const HealthStatusThrottled: STORAGE_COMPONENT_HEALTH_STATUS = 2i32;\npub const HealthStatusUnknown: STORAGE_COMPONENT_HEALTH_STATUS = 0i32;\npub const HealthStatusWarning: STORAGE_COMPONENT_HEALTH_STATUS = 3i32;\npub const IBM_3480: STORAGE_MEDIA_TYPE = 41i32;\npub const IBM_3490E: STORAGE_MEDIA_TYPE = 42i32;\npub const IBM_Magstar_3590: STORAGE_MEDIA_TYPE = 43i32;\npub const IBM_Magstar_MP: STORAGE_MEDIA_TYPE = 44i32;\npub const IDENTIFY_BUFFER_SIZE: u32 = 512u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct IDEREGS {\n    pub bFeaturesReg: u8,\n    pub bSectorCountReg: u8,\n    pub bSectorNumberReg: u8,\n    pub bCylLowReg: u8,\n    pub bCylHighReg: u8,\n    pub bDriveHeadReg: u8,\n    pub bCommandReg: u8,\n    pub bReserved: u8,\n}\npub const ID_CMD: u32 = 236u32;\npub const IOCTL_CHANGER_BASE: u32 = 48u32;\npub const IOCTL_CHANGER_EXCHANGE_MEDIUM: u32 = 3162144u32;\npub const IOCTL_CHANGER_GET_ELEMENT_STATUS: u32 = 3194900u32;\npub const IOCTL_CHANGER_GET_PARAMETERS: u32 = 3162112u32;\npub const IOCTL_CHANGER_GET_PRODUCT_DATA: u32 = 3162120u32;\npub const IOCTL_CHANGER_GET_STATUS: u32 = 3162116u32;\npub const IOCTL_CHANGER_INITIALIZE_ELEMENT_STATUS: u32 = 3162136u32;\npub const IOCTL_CHANGER_MOVE_MEDIUM: u32 = 3162148u32;\npub const IOCTL_CHANGER_QUERY_VOLUME_TAGS: u32 = 3194924u32;\npub const IOCTL_CHANGER_REINITIALIZE_TRANSPORT: u32 = 3162152u32;\npub const IOCTL_CHANGER_SET_ACCESS: u32 = 3194896u32;\npub const IOCTL_CHANGER_SET_POSITION: u32 = 3162140u32;\npub const IOCTL_DISK_BASE: u32 = 7u32;\npub const IOCTL_DISK_CHECK_VERIFY: u32 = 477184u32;\npub const IOCTL_DISK_CONTROLLER_NUMBER: u32 = 458820u32;\npub const IOCTL_DISK_CREATE_DISK: u32 = 507992u32;\npub const IOCTL_DISK_DELETE_DRIVE_LAYOUT: u32 = 508160u32;\npub const IOCTL_DISK_EJECT_MEDIA: u32 = 477192u32;\npub const IOCTL_DISK_FIND_NEW_DEVICES: u32 = 477208u32;\npub const IOCTL_DISK_FORMAT_DRIVE: u32 = 508876u32;\npub const IOCTL_DISK_FORMAT_TRACKS: u32 = 507928u32;\npub const IOCTL_DISK_FORMAT_TRACKS_EX: u32 = 507948u32;\npub const IOCTL_DISK_GET_CACHE_INFORMATION: u32 = 475348u32;\npub const IOCTL_DISK_GET_DISK_ATTRIBUTES: u32 = 458992u32;\npub const IOCTL_DISK_GET_DRIVE_GEOMETRY: u32 = 458752u32;\npub const IOCTL_DISK_GET_DRIVE_GEOMETRY_EX: u32 = 458912u32;\npub const IOCTL_DISK_GET_DRIVE_LAYOUT: u32 = 475148u32;\npub const IOCTL_DISK_GET_DRIVE_LAYOUT_EX: u32 = 458832u32;\npub const IOCTL_DISK_GET_LENGTH_INFO: u32 = 475228u32;\npub const IOCTL_DISK_GET_MEDIA_TYPES: u32 = 461824u32;\npub const IOCTL_DISK_GET_PARTITION_INFO: u32 = 475140u32;\npub const IOCTL_DISK_GET_PARTITION_INFO_EX: u32 = 458824u32;\npub const IOCTL_DISK_GET_WRITE_CACHE_STATE: u32 = 475356u32;\npub const IOCTL_DISK_GROW_PARTITION: u32 = 508112u32;\npub const IOCTL_DISK_HISTOGRAM_DATA: u32 = 458804u32;\npub const IOCTL_DISK_HISTOGRAM_RESET: u32 = 458808u32;\npub const IOCTL_DISK_HISTOGRAM_STRUCTURE: u32 = 458800u32;\npub const IOCTL_DISK_IS_WRITABLE: u32 = 458788u32;\npub const IOCTL_DISK_LOAD_MEDIA: u32 = 477196u32;\npub const IOCTL_DISK_LOGGING: u32 = 458792u32;\npub const IOCTL_DISK_MEDIA_REMOVAL: u32 = 477188u32;\npub const IOCTL_DISK_PERFORMANCE: u32 = 458784u32;\npub const IOCTL_DISK_PERFORMANCE_OFF: u32 = 458848u32;\npub const IOCTL_DISK_REASSIGN_BLOCKS: u32 = 507932u32;\npub const IOCTL_DISK_REASSIGN_BLOCKS_EX: u32 = 508068u32;\npub const IOCTL_DISK_RELEASE: u32 = 477204u32;\npub const IOCTL_DISK_REQUEST_DATA: u32 = 458816u32;\npub const IOCTL_DISK_REQUEST_STRUCTURE: u32 = 458812u32;\npub const IOCTL_DISK_RESERVE: u32 = 477200u32;\npub const IOCTL_DISK_RESET_SNAPSHOT_INFO: u32 = 508432u32;\npub const IOCTL_DISK_SENSE_DEVICE: u32 = 459744u32;\npub const IOCTL_DISK_SET_CACHE_INFORMATION: u32 = 508120u32;\npub const IOCTL_DISK_SET_DISK_ATTRIBUTES: u32 = 508148u32;\npub const IOCTL_DISK_SET_DRIVE_LAYOUT: u32 = 507920u32;\npub const IOCTL_DISK_SET_DRIVE_LAYOUT_EX: u32 = 507988u32;\npub const IOCTL_DISK_SET_PARTITION_INFO: u32 = 507912u32;\npub const IOCTL_DISK_SET_PARTITION_INFO_EX: u32 = 507980u32;\npub const IOCTL_DISK_UPDATE_DRIVE_SIZE: u32 = 508104u32;\npub const IOCTL_DISK_UPDATE_PROPERTIES: u32 = 459072u32;\npub const IOCTL_DISK_VERIFY: u32 = 458772u32;\npub const IOCTL_SCMBUS_BASE: u32 = 89u32;\npub const IOCTL_SCMBUS_DEVICE_FUNCTION_BASE: u32 = 0u32;\npub const IOCTL_SCM_BUS_GET_LOGICAL_DEVICES: u32 = 5832704u32;\npub const IOCTL_SCM_BUS_GET_PHYSICAL_DEVICES: u32 = 5832708u32;\npub const IOCTL_SCM_BUS_GET_REGIONS: u32 = 5832712u32;\npub const IOCTL_SCM_BUS_QUERY_PROPERTY: u32 = 5832716u32;\npub const IOCTL_SCM_BUS_REFRESH_NAMESPACE: u32 = 5832728u32;\npub const IOCTL_SCM_BUS_RUNTIME_FW_ACTIVATE: u32 = 5865488u32;\npub const IOCTL_SCM_BUS_SET_PROPERTY: u32 = 5865492u32;\npub const IOCTL_SCM_LD_GET_INTERLEAVE_SET: u32 = 5835776u32;\npub const IOCTL_SCM_LOGICAL_DEVICE_FUNCTION_BASE: u32 = 768u32;\npub const IOCTL_SCM_PD_FIRMWARE_ACTIVATE: u32 = 5871624u32;\npub const IOCTL_SCM_PD_FIRMWARE_DOWNLOAD: u32 = 5871620u32;\npub const IOCTL_SCM_PD_PASSTHROUGH: u32 = 5888012u32;\npub const IOCTL_SCM_PD_QUERY_PROPERTY: u32 = 5838848u32;\npub const IOCTL_SCM_PD_REINITIALIZE_MEDIA: u32 = 5871636u32;\npub const IOCTL_SCM_PD_SET_PROPERTY: u32 = 5871640u32;\npub const IOCTL_SCM_PD_UPDATE_MANAGEMENT_STATUS: u32 = 5838864u32;\npub const IOCTL_SCM_PHYSICAL_DEVICE_FUNCTION_BASE: u32 = 1536u32;\npub const IOCTL_SERENUM_EXPOSE_HARDWARE: u32 = 3604992u32;\npub const IOCTL_SERENUM_GET_PORT_NAME: u32 = 3605004u32;\npub const IOCTL_SERENUM_PORT_DESC: u32 = 3605000u32;\npub const IOCTL_SERENUM_REMOVE_HARDWARE: u32 = 3604996u32;\npub const IOCTL_SERIAL_LSRMST_INSERT: u32 = 1769596u32;\npub const IOCTL_STORAGE_ALLOCATE_BC_STREAM: u32 = 3004420u32;\npub const IOCTL_STORAGE_ATTRIBUTE_MANAGEMENT: u32 = 3005596u32;\npub const IOCTL_STORAGE_BASE: u32 = 45u32;\npub const IOCTL_STORAGE_BC_VERSION: u32 = 1u32;\npub const IOCTL_STORAGE_BREAK_RESERVATION: u32 = 2969620u32;\npub const IOCTL_STORAGE_CHECK_PRIORITY_HINT_SUPPORT: u32 = 2955392u32;\npub const IOCTL_STORAGE_CHECK_VERIFY: u32 = 2967552u32;\npub const IOCTL_STORAGE_CHECK_VERIFY2: u32 = 2951168u32;\npub const IOCTL_STORAGE_DEVICE_POWER_CAP: u32 = 2956436u32;\npub const IOCTL_STORAGE_DEVICE_TELEMETRY_NOTIFY: u32 = 3002820u32;\npub const IOCTL_STORAGE_DEVICE_TELEMETRY_QUERY_CAPS: u32 = 3002824u32;\npub const IOCTL_STORAGE_DIAGNOSTIC: u32 = 2956448u32;\npub const IOCTL_STORAGE_EJECTION_CONTROL: u32 = 2951488u32;\npub const IOCTL_STORAGE_EJECT_MEDIA: u32 = 2967560u32;\npub const IOCTL_STORAGE_ENABLE_IDLE_POWER: u32 = 2956416u32;\npub const IOCTL_STORAGE_EVENT_NOTIFICATION: u32 = 2956432u32;\npub const IOCTL_STORAGE_FAILURE_PREDICTION_CONFIG: u32 = 2953476u32;\npub const IOCTL_STORAGE_FIND_NEW_DEVICES: u32 = 2967576u32;\npub const IOCTL_STORAGE_FIRMWARE_ACTIVATE: u32 = 3005448u32;\npub const IOCTL_STORAGE_FIRMWARE_DOWNLOAD: u32 = 3005444u32;\npub const IOCTL_STORAGE_FIRMWARE_GET_INFO: u32 = 2956288u32;\npub const IOCTL_STORAGE_FREE_BC_STREAM: u32 = 3004424u32;\npub const IOCTL_STORAGE_GET_BC_PROPERTIES: u32 = 2971648u32;\npub const IOCTL_STORAGE_GET_COUNTERS: u32 = 2953480u32;\npub const IOCTL_STORAGE_GET_DEVICE_INTERNAL_LOG: u32 = 2956484u32;\npub const IOCTL_STORAGE_GET_DEVICE_NUMBER: u32 = 2953344u32;\npub const IOCTL_STORAGE_GET_DEVICE_NUMBER_EX: u32 = 2953348u32;\npub const IOCTL_STORAGE_GET_DEVICE_TELEMETRY: u32 = 3002816u32;\npub const IOCTL_STORAGE_GET_DEVICE_TELEMETRY_RAW: u32 = 3002828u32;\npub const IOCTL_STORAGE_GET_HOTPLUG_INFO: u32 = 2952212u32;\npub const IOCTL_STORAGE_GET_IDLE_POWERUP_REASON: u32 = 2956420u32;\npub const IOCTL_STORAGE_GET_LB_PROVISIONING_MAP_RESOURCES: u32 = 2970632u32;\npub const IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER: u32 = 2952208u32;\npub const IOCTL_STORAGE_GET_MEDIA_TYPES: u32 = 2952192u32;\npub const IOCTL_STORAGE_GET_MEDIA_TYPES_EX: u32 = 2952196u32;\npub const IOCTL_STORAGE_GET_PHYSICAL_ELEMENT_STATUS: u32 = 2956452u32;\npub const IOCTL_STORAGE_LOAD_MEDIA: u32 = 2967564u32;\npub const IOCTL_STORAGE_LOAD_MEDIA2: u32 = 2951180u32;\npub const IOCTL_STORAGE_MANAGE_BYPASS_IO: u32 = 2951360u32;\npub const IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES: u32 = 2987012u32;\npub const IOCTL_STORAGE_MCN_CONTROL: u32 = 2951492u32;\npub const IOCTL_STORAGE_MEDIA_REMOVAL: u32 = 2967556u32;\npub const IOCTL_STORAGE_PERSISTENT_RESERVE_IN: u32 = 2969624u32;\npub const IOCTL_STORAGE_PERSISTENT_RESERVE_OUT: u32 = 3002396u32;\npub const IOCTL_STORAGE_POWER_ACTIVE: u32 = 2956424u32;\npub const IOCTL_STORAGE_POWER_IDLE: u32 = 2956428u32;\npub const IOCTL_STORAGE_PREDICT_FAILURE: u32 = 2953472u32;\npub const IOCTL_STORAGE_PROTOCOL_COMMAND: u32 = 3003328u32;\npub const IOCTL_STORAGE_QUERY_PROPERTY: u32 = 2954240u32;\npub const IOCTL_STORAGE_READ_CAPACITY: u32 = 2969920u32;\npub const IOCTL_STORAGE_REINITIALIZE_MEDIA: u32 = 2987584u32;\npub const IOCTL_STORAGE_RELEASE: u32 = 2967572u32;\npub const IOCTL_STORAGE_REMOVE_ELEMENT_AND_TRUNCATE: u32 = 2956480u32;\npub const IOCTL_STORAGE_RESERVE: u32 = 2967568u32;\npub const IOCTL_STORAGE_RESET_BUS: u32 = 2969600u32;\npub const IOCTL_STORAGE_RESET_DEVICE: u32 = 2969604u32;\npub const IOCTL_STORAGE_RPMB_COMMAND: u32 = 2956440u32;\npub const IOCTL_STORAGE_SET_HOTPLUG_INFO: u32 = 3001368u32;\npub const IOCTL_STORAGE_SET_PROPERTY: u32 = 2987004u32;\npub const IOCTL_STORAGE_SET_TEMPERATURE_THRESHOLD: u32 = 3002880u32;\npub const IOCTL_STORAGE_START_DATA_INTEGRITY_CHECK: u32 = 3004548u32;\npub const IOCTL_STORAGE_STOP_DATA_INTEGRITY_CHECK: u32 = 3004552u32;\npub const IOMEGA_JAZ: STORAGE_MEDIA_TYPE = 74i32;\npub const IOMEGA_ZIP: STORAGE_MEDIA_TYPE = 73i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct IO_IRP_EXT_TRACK_OFFSET_HEADER {\n    pub Validation: u16,\n    pub Flags: u16,\n    pub TrackedOffsetCallback: PIO_IRP_EXT_PROCESS_TRACKED_OFFSET_CALLBACK,\n}\npub const KODAK_14_WO: STORAGE_MEDIA_TYPE = 70i32;\npub const KeepPrefetchedData: DISK_CACHE_RETENTION_PRIORITY = 1i32;\npub const KeepReadData: DISK_CACHE_RETENTION_PRIORITY = 2i32;\npub const LMRQuerySessionInfo: LMR_QUERY_INFO_CLASS = 1i32;\npub type LMR_QUERY_INFO_CLASS = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct LMR_QUERY_INFO_PARAM {\n    pub Operation: LMR_QUERY_INFO_CLASS,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct LMR_QUERY_SESSION_INFO {\n    pub SessionId: u64,\n}\npub const LOCK_ELEMENT: u32 = 0u32;\npub const LOCK_UNLOCK_DOOR: u32 = 2u32;\npub const LOCK_UNLOCK_IEPORT: u32 = 1u32;\npub const LOCK_UNLOCK_KEYPAD: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LOOKUP_STREAM_FROM_CLUSTER_ENTRY {\n    pub OffsetToNext: u32,\n    pub Flags: u32,\n    pub Reserved: i64,\n    pub Cluster: i64,\n    pub FileName: [u16; 1],\n}\nimpl Default for LOOKUP_STREAM_FROM_CLUSTER_ENTRY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_DATA: u32 = 16777216u32;\npub const LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_INDEX: u32 = 33554432u32;\npub const LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_MASK: u32 = 4278190080u32;\npub const LOOKUP_STREAM_FROM_CLUSTER_ENTRY_ATTRIBUTE_SYSTEM: u32 = 50331648u32;\npub const LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_DENY_DEFRAG_SET: u32 = 2u32;\npub const LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_FS_SYSTEM_FILE: u32 = 4u32;\npub const LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_PAGE_FILE: u32 = 1u32;\npub const LOOKUP_STREAM_FROM_CLUSTER_ENTRY_FLAG_TXF_SYSTEM_FILE: u32 = 8u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LOOKUP_STREAM_FROM_CLUSTER_INPUT {\n    pub Flags: u32,\n    pub NumberOfClusters: u32,\n    pub Cluster: [i64; 1],\n}\nimpl Default for LOOKUP_STREAM_FROM_CLUSTER_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct LOOKUP_STREAM_FROM_CLUSTER_OUTPUT {\n    pub Offset: u32,\n    pub NumberOfMatches: u32,\n    pub BufferSizeRequired: u32,\n}\npub const LTO_Accelis: STORAGE_MEDIA_TYPE = 87i32;\npub const LTO_Ultrium: STORAGE_MEDIA_TYPE = 86i32;\npub const MARK_HANDLE_CLOUD_SYNC: u32 = 2048u32;\npub const MARK_HANDLE_DISABLE_FILE_METADATA_OPTIMIZATION: u32 = 4096u32;\npub const MARK_HANDLE_ENABLE_CPU_CACHE: u32 = 268435456u32;\npub const MARK_HANDLE_ENABLE_USN_SOURCE_ON_PAGING_IO: u32 = 8192u32;\npub const MARK_HANDLE_FILTER_METADATA: u32 = 512u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MARK_HANDLE_INFO {\n    pub Anonymous: MARK_HANDLE_INFO_0,\n    pub VolumeHandle: super::super::Foundation::HANDLE,\n    pub HandleInfo: u32,\n}\nimpl Default for MARK_HANDLE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union MARK_HANDLE_INFO_0 {\n    pub UsnSourceInfo: u32,\n    pub CopyNumber: u32,\n}\nimpl Default for MARK_HANDLE_INFO_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\n#[derive(Clone, Copy)]\npub struct MARK_HANDLE_INFO32 {\n    pub Anonymous: MARK_HANDLE_INFO32_0,\n    pub VolumeHandle: u32,\n    pub HandleInfo: u32,\n}\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\nimpl Default for MARK_HANDLE_INFO32 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\n#[derive(Clone, Copy)]\npub union MARK_HANDLE_INFO32_0 {\n    pub UsnSourceInfo: u32,\n    pub CopyNumber: u32,\n}\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\nimpl Default for MARK_HANDLE_INFO32_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MARK_HANDLE_NOT_READ_COPY: u32 = 256u32;\npub const MARK_HANDLE_NOT_REALTIME: u32 = 64u32;\npub const MARK_HANDLE_NOT_TXF_SYSTEM_LOG: u32 = 8u32;\npub const MARK_HANDLE_PROTECT_CLUSTERS: u32 = 1u32;\npub const MARK_HANDLE_READ_COPY: u32 = 128u32;\npub const MARK_HANDLE_REALTIME: u32 = 32u32;\npub const MARK_HANDLE_RETURN_PURGE_FAILURE: u32 = 1024u32;\npub const MARK_HANDLE_SKIP_COHERENCY_SYNC_DISALLOW_WRITES: u32 = 16384u32;\npub const MARK_HANDLE_SUPPRESS_VOLUME_OPEN_FLUSH: u32 = 32768u32;\npub const MARK_HANDLE_TXF_SYSTEM_LOG: u32 = 4u32;\npub const MAXIMUM_ENCRYPTION_VALUE: u32 = 4u32;\npub const MAX_FW_BUCKET_ID_LENGTH: u32 = 132u32;\npub const MAX_INTERFACE_CODES: u32 = 8u32;\npub const MAX_VOLUME_ID_SIZE: u32 = 36u32;\npub const MAX_VOLUME_TEMPLATE_SIZE: u32 = 40u32;\npub const MEDIA_CURRENTLY_MOUNTED: u32 = 2147483648u32;\npub const MEDIA_ERASEABLE: u32 = 1u32;\npub const MEDIA_READ_ONLY: u32 = 4u32;\npub const MEDIA_READ_WRITE: u32 = 8u32;\npub type MEDIA_TYPE = i32;\npub const MEDIA_WRITE_ONCE: u32 = 2u32;\npub const MEDIA_WRITE_PROTECTED: u32 = 256u32;\npub const METHOD_BUFFERED: u32 = 0u32;\npub const METHOD_DIRECT_FROM_HARDWARE: u32 = 2u32;\npub const METHOD_DIRECT_TO_HARDWARE: u32 = 1u32;\npub const METHOD_IN_DIRECT: u32 = 1u32;\npub const METHOD_NEITHER: u32 = 3u32;\npub const METHOD_OUT_DIRECT: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct MFT_ENUM_DATA_V0 {\n    pub StartFileReferenceNumber: u64,\n    pub LowUsn: i64,\n    pub HighUsn: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct MFT_ENUM_DATA_V1 {\n    pub StartFileReferenceNumber: u64,\n    pub LowUsn: i64,\n    pub HighUsn: i64,\n    pub MinMajorVersion: u16,\n    pub MaxMajorVersion: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MOVE_FILE_DATA {\n    pub FileHandle: super::super::Foundation::HANDLE,\n    pub StartingVcn: i64,\n    pub StartingLcn: i64,\n    pub ClusterCount: u32,\n}\nimpl Default for MOVE_FILE_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\n#[derive(Clone, Copy, Default)]\npub struct MOVE_FILE_DATA32 {\n    pub FileHandle: u32,\n    pub StartingVcn: i64,\n    pub StartingLcn: i64,\n    pub ClusterCount: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MOVE_FILE_RECORD_DATA {\n    pub FileHandle: super::super::Foundation::HANDLE,\n    pub SourceFileRecord: i64,\n    pub TargetFileRecord: i64,\n}\nimpl Default for MOVE_FILE_RECORD_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const MO_3_RW: STORAGE_MEDIA_TYPE = 57i32;\npub const MO_5_LIMDOW: STORAGE_MEDIA_TYPE = 60i32;\npub const MO_5_RW: STORAGE_MEDIA_TYPE = 59i32;\npub const MO_5_WO: STORAGE_MEDIA_TYPE = 58i32;\npub const MO_NFR_525: STORAGE_MEDIA_TYPE = 71i32;\npub const MP2_8mm: STORAGE_MEDIA_TYPE = 79i32;\npub const MP_8mm: STORAGE_MEDIA_TYPE = 36i32;\npub const MiniQic: STORAGE_MEDIA_TYPE = 33i32;\npub const NCTP: STORAGE_MEDIA_TYPE = 40i32;\npub const NIKON_12_RW: STORAGE_MEDIA_TYPE = 72i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_EXTENDED_VOLUME_DATA {\n    pub ByteCount: u32,\n    pub MajorVersion: u16,\n    pub MinorVersion: u16,\n    pub BytesPerPhysicalSector: u32,\n    pub LfsMajorVersion: u16,\n    pub LfsMinorVersion: u16,\n    pub MaxDeviceTrimExtentCount: u32,\n    pub MaxDeviceTrimByteCount: u32,\n    pub MaxVolumeTrimExtentCount: u32,\n    pub MaxVolumeTrimByteCount: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_FILE_RECORD_INPUT_BUFFER {\n    pub FileReferenceNumber: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NTFS_FILE_RECORD_OUTPUT_BUFFER {\n    pub FileReferenceNumber: i64,\n    pub FileRecordLength: u32,\n    pub FileRecordBuffer: [u8; 1],\n}\nimpl Default for NTFS_FILE_RECORD_OUTPUT_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS {\n    pub LogFileFullExceptions: u32,\n    pub OtherExceptions: u32,\n    pub MftReads: u32,\n    pub MftReadBytes: u32,\n    pub MftWrites: u32,\n    pub MftWriteBytes: u32,\n    pub MftWritesUserLevel: NTFS_STATISTICS_0,\n    pub MftWritesFlushForLogFileFull: u16,\n    pub MftWritesLazyWriter: u16,\n    pub MftWritesUserRequest: u16,\n    pub Mft2Writes: u32,\n    pub Mft2WriteBytes: u32,\n    pub Mft2WritesUserLevel: NTFS_STATISTICS_1,\n    pub Mft2WritesFlushForLogFileFull: u16,\n    pub Mft2WritesLazyWriter: u16,\n    pub Mft2WritesUserRequest: u16,\n    pub RootIndexReads: u32,\n    pub RootIndexReadBytes: u32,\n    pub RootIndexWrites: u32,\n    pub RootIndexWriteBytes: u32,\n    pub BitmapReads: u32,\n    pub BitmapReadBytes: u32,\n    pub BitmapWrites: u32,\n    pub BitmapWriteBytes: u32,\n    pub BitmapWritesFlushForLogFileFull: u16,\n    pub BitmapWritesLazyWriter: u16,\n    pub BitmapWritesUserRequest: u16,\n    pub BitmapWritesUserLevel: NTFS_STATISTICS_2,\n    pub MftBitmapReads: u32,\n    pub MftBitmapReadBytes: u32,\n    pub MftBitmapWrites: u32,\n    pub MftBitmapWriteBytes: u32,\n    pub MftBitmapWritesFlushForLogFileFull: u16,\n    pub MftBitmapWritesLazyWriter: u16,\n    pub MftBitmapWritesUserRequest: u16,\n    pub MftBitmapWritesUserLevel: NTFS_STATISTICS_3,\n    pub UserIndexReads: u32,\n    pub UserIndexReadBytes: u32,\n    pub UserIndexWrites: u32,\n    pub UserIndexWriteBytes: u32,\n    pub LogFileReads: u32,\n    pub LogFileReadBytes: u32,\n    pub LogFileWrites: u32,\n    pub LogFileWriteBytes: u32,\n    pub Allocate: NTFS_STATISTICS_4,\n    pub DiskResourcesExhausted: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_4 {\n    pub Calls: u32,\n    pub Clusters: u32,\n    pub Hints: u32,\n    pub RunsReturned: u32,\n    pub HintsHonored: u32,\n    pub HintsClusters: u32,\n    pub Cache: u32,\n    pub CacheClusters: u32,\n    pub CacheMiss: u32,\n    pub CacheMissClusters: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_2 {\n    pub Write: u16,\n    pub Create: u16,\n    pub SetInfo: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_1 {\n    pub Write: u16,\n    pub Create: u16,\n    pub SetInfo: u16,\n    pub Flush: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_3 {\n    pub Write: u16,\n    pub Create: u16,\n    pub SetInfo: u16,\n    pub Flush: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_0 {\n    pub Write: u16,\n    pub Create: u16,\n    pub SetInfo: u16,\n    pub Flush: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_EX {\n    pub LogFileFullExceptions: u32,\n    pub OtherExceptions: u32,\n    pub MftReads: u64,\n    pub MftReadBytes: u64,\n    pub MftWrites: u64,\n    pub MftWriteBytes: u64,\n    pub MftWritesUserLevel: NTFS_STATISTICS_EX_0,\n    pub MftWritesFlushForLogFileFull: u32,\n    pub MftWritesLazyWriter: u32,\n    pub MftWritesUserRequest: u32,\n    pub Mft2Writes: u64,\n    pub Mft2WriteBytes: u64,\n    pub Mft2WritesUserLevel: NTFS_STATISTICS_EX_1,\n    pub Mft2WritesFlushForLogFileFull: u32,\n    pub Mft2WritesLazyWriter: u32,\n    pub Mft2WritesUserRequest: u32,\n    pub RootIndexReads: u64,\n    pub RootIndexReadBytes: u64,\n    pub RootIndexWrites: u64,\n    pub RootIndexWriteBytes: u64,\n    pub BitmapReads: u64,\n    pub BitmapReadBytes: u64,\n    pub BitmapWrites: u64,\n    pub BitmapWriteBytes: u64,\n    pub BitmapWritesFlushForLogFileFull: u32,\n    pub BitmapWritesLazyWriter: u32,\n    pub BitmapWritesUserRequest: u32,\n    pub BitmapWritesUserLevel: NTFS_STATISTICS_EX_2,\n    pub MftBitmapReads: u64,\n    pub MftBitmapReadBytes: u64,\n    pub MftBitmapWrites: u64,\n    pub MftBitmapWriteBytes: u64,\n    pub MftBitmapWritesFlushForLogFileFull: u32,\n    pub MftBitmapWritesLazyWriter: u32,\n    pub MftBitmapWritesUserRequest: u32,\n    pub MftBitmapWritesUserLevel: NTFS_STATISTICS_EX_3,\n    pub UserIndexReads: u64,\n    pub UserIndexReadBytes: u64,\n    pub UserIndexWrites: u64,\n    pub UserIndexWriteBytes: u64,\n    pub LogFileReads: u64,\n    pub LogFileReadBytes: u64,\n    pub LogFileWrites: u64,\n    pub LogFileWriteBytes: u64,\n    pub Allocate: NTFS_STATISTICS_EX_4,\n    pub DiskResourcesExhausted: u32,\n    pub VolumeTrimCount: u64,\n    pub VolumeTrimTime: u64,\n    pub VolumeTrimByteCount: u64,\n    pub FileLevelTrimCount: u64,\n    pub FileLevelTrimTime: u64,\n    pub FileLevelTrimByteCount: u64,\n    pub VolumeTrimSkippedCount: u64,\n    pub VolumeTrimSkippedByteCount: u64,\n    pub NtfsFillStatInfoFromMftRecordCalledCount: u64,\n    pub NtfsFillStatInfoFromMftRecordBailedBecauseOfAttributeListCount: u64,\n    pub NtfsFillStatInfoFromMftRecordBailedBecauseOfNonResReparsePointCount: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_EX_4 {\n    pub Calls: u32,\n    pub RunsReturned: u32,\n    pub Hints: u32,\n    pub HintsHonored: u32,\n    pub Cache: u32,\n    pub CacheMiss: u32,\n    pub Clusters: u64,\n    pub HintsClusters: u64,\n    pub CacheClusters: u64,\n    pub CacheMissClusters: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_EX_2 {\n    pub Write: u32,\n    pub Create: u32,\n    pub SetInfo: u32,\n    pub Flush: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_EX_1 {\n    pub Write: u32,\n    pub Create: u32,\n    pub SetInfo: u32,\n    pub Flush: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_EX_3 {\n    pub Write: u32,\n    pub Create: u32,\n    pub SetInfo: u32,\n    pub Flush: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_STATISTICS_EX_0 {\n    pub Write: u32,\n    pub Create: u32,\n    pub SetInfo: u32,\n    pub Flush: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NTFS_VOLUME_DATA_BUFFER {\n    pub VolumeSerialNumber: i64,\n    pub NumberSectors: i64,\n    pub TotalClusters: i64,\n    pub FreeClusters: i64,\n    pub TotalReserved: i64,\n    pub BytesPerSector: u32,\n    pub BytesPerCluster: u32,\n    pub BytesPerFileRecordSegment: u32,\n    pub ClustersPerFileRecordSegment: u32,\n    pub MftValidDataLength: i64,\n    pub MftStartLcn: i64,\n    pub Mft2StartLcn: i64,\n    pub MftZoneStart: i64,\n    pub MftZoneEnd: i64,\n}\npub const NVMeDataTypeFeature: STORAGE_PROTOCOL_NVME_DATA_TYPE = 3i32;\npub const NVMeDataTypeIdentify: STORAGE_PROTOCOL_NVME_DATA_TYPE = 1i32;\npub const NVMeDataTypeLogPage: STORAGE_PROTOCOL_NVME_DATA_TYPE = 2i32;\npub const NVMeDataTypeUnknown: STORAGE_PROTOCOL_NVME_DATA_TYPE = 0i32;\npub const OBSOLETE_DISK_GET_WRITE_CACHE_STATE: u32 = 475356u32;\npub const OBSOLETE_IOCTL_STORAGE_RESET_BUS: u32 = 3002368u32;\npub const OBSOLETE_IOCTL_STORAGE_RESET_DEVICE: u32 = 3002372u32;\npub const OFFLOAD_READ_FLAG_ALL_ZERO_BEYOND_CURRENT_RANGE: u32 = 1u32;\npub const OPLOCK_LEVEL_CACHE_HANDLE: u32 = 2u32;\npub const OPLOCK_LEVEL_CACHE_READ: u32 = 1u32;\npub const OPLOCK_LEVEL_CACHE_WRITE: u32 = 4u32;\npub const PARTIITON_OS_DATA: u32 = 41u32;\npub const PARTITION_BSP: u32 = 43u32;\npub const PARTITION_DM: u32 = 84u32;\npub const PARTITION_DPP: u32 = 44u32;\npub const PARTITION_ENTRY_UNUSED: u32 = 0u32;\npub const PARTITION_EXTENDED: u32 = 5u32;\npub const PARTITION_EZDRIVE: u32 = 85u32;\npub const PARTITION_FAT32: u32 = 11u32;\npub const PARTITION_FAT32_XINT13: u32 = 12u32;\npub const PARTITION_FAT_12: u32 = 1u32;\npub const PARTITION_FAT_16: u32 = 4u32;\npub const PARTITION_GPT: u32 = 238u32;\npub const PARTITION_HUGE: u32 = 6u32;\npub const PARTITION_IFS: u32 = 7u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PARTITION_INFORMATION {\n    pub StartingOffset: i64,\n    pub PartitionLength: i64,\n    pub HiddenSectors: u32,\n    pub PartitionNumber: u32,\n    pub PartitionType: u8,\n    pub BootIndicator: bool,\n    pub RecognizedPartition: bool,\n    pub RewritePartition: bool,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PARTITION_INFORMATION_EX {\n    pub PartitionStyle: PARTITION_STYLE,\n    pub StartingOffset: i64,\n    pub PartitionLength: i64,\n    pub PartitionNumber: u32,\n    pub RewritePartition: bool,\n    pub IsServicePartition: bool,\n    pub Anonymous: PARTITION_INFORMATION_EX_0,\n}\nimpl Default for PARTITION_INFORMATION_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union PARTITION_INFORMATION_EX_0 {\n    pub Mbr: PARTITION_INFORMATION_MBR,\n    pub Gpt: PARTITION_INFORMATION_GPT,\n}\nimpl Default for PARTITION_INFORMATION_EX_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PARTITION_INFORMATION_GPT {\n    pub PartitionType: windows_sys::core::GUID,\n    pub PartitionId: windows_sys::core::GUID,\n    pub Attributes: GPT_ATTRIBUTES,\n    pub Name: [u16; 36],\n}\nimpl Default for PARTITION_INFORMATION_GPT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PARTITION_INFORMATION_MBR {\n    pub PartitionType: u8,\n    pub BootIndicator: bool,\n    pub RecognizedPartition: bool,\n    pub HiddenSectors: u32,\n    pub PartitionId: windows_sys::core::GUID,\n}\npub const PARTITION_LDM: u32 = 66u32;\npub const PARTITION_MAIN_OS: u32 = 40u32;\npub const PARTITION_MSFT_RECOVERY: u32 = 39u32;\npub const PARTITION_NTFT: u32 = 128u32;\npub const PARTITION_OS2BOOTMGR: u32 = 10u32;\npub const PARTITION_PREP: u32 = 65u32;\npub const PARTITION_PRE_INSTALLED: u32 = 42u32;\npub const PARTITION_SPACES: u32 = 231u32;\npub const PARTITION_SPACES_DATA: u32 = 215u32;\npub type PARTITION_STYLE = i32;\npub const PARTITION_STYLE_GPT: PARTITION_STYLE = 1i32;\npub const PARTITION_STYLE_MBR: PARTITION_STYLE = 0i32;\npub const PARTITION_STYLE_RAW: PARTITION_STYLE = 2i32;\npub const PARTITION_SYSTEM: u32 = 239u32;\npub const PARTITION_UNIX: u32 = 99u32;\npub const PARTITION_WINDOWS_SYSTEM: u32 = 45u32;\npub const PARTITION_XENIX_1: u32 = 2u32;\npub const PARTITION_XENIX_2: u32 = 3u32;\npub const PARTITION_XINT13: u32 = 14u32;\npub const PARTITION_XINT13_EXTENDED: u32 = 15u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PATHNAME_BUFFER {\n    pub PathNameLength: u32,\n    pub Name: [u16; 1],\n}\nimpl Default for PATHNAME_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const PC_5_RW: STORAGE_MEDIA_TYPE = 62i32;\npub const PC_5_WO: STORAGE_MEDIA_TYPE = 61i32;\npub const PD_5_RW: STORAGE_MEDIA_TYPE = 63i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PERF_BIN {\n    pub NumberOfBins: u32,\n    pub TypeOfBin: u32,\n    pub BinsRanges: [BIN_RANGE; 1],\n}\nimpl Default for PERF_BIN {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PERSISTENT_RESERVE_COMMAND {\n    pub Version: u32,\n    pub Size: u32,\n    pub Anonymous: PERSISTENT_RESERVE_COMMAND_0,\n}\nimpl Default for PERSISTENT_RESERVE_COMMAND {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union PERSISTENT_RESERVE_COMMAND_0 {\n    pub PR_IN: PERSISTENT_RESERVE_COMMAND_0_0,\n    pub PR_OUT: PERSISTENT_RESERVE_COMMAND_0_1,\n}\nimpl Default for PERSISTENT_RESERVE_COMMAND_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PERSISTENT_RESERVE_COMMAND_0_0 {\n    pub _bitfield: u8,\n    pub AllocationLength: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PERSISTENT_RESERVE_COMMAND_0_1 {\n    pub _bitfield1: u8,\n    pub _bitfield2: u8,\n    pub ParameterList: [u8; 1],\n}\nimpl Default for PERSISTENT_RESERVE_COMMAND_0_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const PERSISTENT_VOLUME_STATE_BACKED_BY_WIM: u32 = 64u32;\npub const PERSISTENT_VOLUME_STATE_CHKDSK_RAN_ONCE: u32 = 1024u32;\npub const PERSISTENT_VOLUME_STATE_CONTAINS_BACKING_WIM: u32 = 32u32;\npub const PERSISTENT_VOLUME_STATE_DAX_FORMATTED: u32 = 4096u32;\npub const PERSISTENT_VOLUME_STATE_DEV_VOLUME: u32 = 8192u32;\npub const PERSISTENT_VOLUME_STATE_GLOBAL_METADATA_NO_SEEK_PENALTY: u32 = 4u32;\npub const PERSISTENT_VOLUME_STATE_LOCAL_METADATA_NO_SEEK_PENALTY: u32 = 8u32;\npub const PERSISTENT_VOLUME_STATE_MODIFIED_BY_CHKDSK: u32 = 2048u32;\npub const PERSISTENT_VOLUME_STATE_NO_HEAT_GATHERING: u32 = 16u32;\npub const PERSISTENT_VOLUME_STATE_NO_WRITE_AUTO_TIERING: u32 = 128u32;\npub const PERSISTENT_VOLUME_STATE_REALLOCATE_ALL_DATA_WRITES: u32 = 512u32;\npub const PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED: u32 = 1u32;\npub const PERSISTENT_VOLUME_STATE_TRUSTED_VOLUME: u32 = 16384u32;\npub const PERSISTENT_VOLUME_STATE_TXF_DISABLED: u32 = 256u32;\npub const PERSISTENT_VOLUME_STATE_VOLUME_SCRUB_DISABLED: u32 = 2u32;\npub const PHILIPS_12_WO: STORAGE_MEDIA_TYPE = 67i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PHYSICAL_ELEMENT_STATUS {\n    pub Version: u32,\n    pub Size: u32,\n    pub DescriptorCount: u32,\n    pub ReturnedDescriptorCount: u32,\n    pub ElementIdentifierBeingDepoped: u32,\n    pub Reserved: u32,\n    pub Descriptors: [PHYSICAL_ELEMENT_STATUS_DESCRIPTOR; 1],\n}\nimpl Default for PHYSICAL_ELEMENT_STATUS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PHYSICAL_ELEMENT_STATUS_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub ElementIdentifier: u32,\n    pub PhysicalElementType: u8,\n    pub PhysicalElementHealth: u8,\n    pub Reserved1: [u8; 2],\n    pub AssociatedCapacity: u64,\n    pub Reserved2: [u32; 4],\n}\nimpl Default for PHYSICAL_ELEMENT_STATUS_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct PHYSICAL_ELEMENT_STATUS_REQUEST {\n    pub Version: u32,\n    pub Size: u32,\n    pub StartingElement: u32,\n    pub Filter: u8,\n    pub ReportType: u8,\n    pub Reserved: [u8; 2],\n}\nimpl Default for PHYSICAL_ELEMENT_STATUS_REQUEST {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const PINNACLE_APEX_5_RW: STORAGE_MEDIA_TYPE = 65i32;\npub type PIO_IRP_EXT_PROCESS_TRACKED_OFFSET_CALLBACK = Option<unsafe extern \"system\" fn(sourcecontext: *const IO_IRP_EXT_TRACK_OFFSET_HEADER, targetcontext: *mut IO_IRP_EXT_TRACK_OFFSET_HEADER, relativeoffset: i64)>;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PLEX_READ_DATA_REQUEST {\n    pub ByteOffset: i64,\n    pub ByteLength: u32,\n    pub PlexNumber: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PREVENT_MEDIA_REMOVAL {\n    pub PreventMediaRemoval: bool,\n}\npub const PRODUCT_ID_LENGTH: u32 = 16u32;\npub const PROJFS_PROTOCOL_VERSION: u32 = 3u32;\npub const PropertyExistsQuery: STORAGE_QUERY_TYPE = 1i32;\npub const PropertyExistsSet: STORAGE_SET_TYPE = 1i32;\npub const PropertyMaskQuery: STORAGE_QUERY_TYPE = 2i32;\npub const PropertyQueryMaxDefined: STORAGE_QUERY_TYPE = 3i32;\npub const PropertySetMaxDefined: STORAGE_SET_TYPE = 2i32;\npub const PropertyStandardQuery: STORAGE_QUERY_TYPE = 0i32;\npub const PropertyStandardSet: STORAGE_SET_TYPE = 0i32;\npub const ProtocolTypeAta: STORAGE_PROTOCOL_TYPE = 2i32;\npub const ProtocolTypeMaxReserved: STORAGE_PROTOCOL_TYPE = 127i32;\npub const ProtocolTypeNvme: STORAGE_PROTOCOL_TYPE = 3i32;\npub const ProtocolTypeProprietary: STORAGE_PROTOCOL_TYPE = 126i32;\npub const ProtocolTypeScsi: STORAGE_PROTOCOL_TYPE = 1i32;\npub const ProtocolTypeSd: STORAGE_PROTOCOL_TYPE = 4i32;\npub const ProtocolTypeUfs: STORAGE_PROTOCOL_TYPE = 5i32;\npub const ProtocolTypeUnknown: STORAGE_PROTOCOL_TYPE = 0i32;\npub const QIC: STORAGE_MEDIA_TYPE = 35i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct QUERY_BAD_RANGES_INPUT {\n    pub Flags: u32,\n    pub NumRanges: u32,\n    pub Ranges: [QUERY_BAD_RANGES_INPUT_RANGE; 1],\n}\nimpl Default for QUERY_BAD_RANGES_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct QUERY_BAD_RANGES_INPUT_RANGE {\n    pub StartOffset: u64,\n    pub LengthInBytes: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct QUERY_BAD_RANGES_OUTPUT {\n    pub Flags: u32,\n    pub NumBadRanges: u32,\n    pub NextOffsetToLookUp: u64,\n    pub BadRanges: [QUERY_BAD_RANGES_OUTPUT_RANGE; 1],\n}\nimpl Default for QUERY_BAD_RANGES_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct QUERY_BAD_RANGES_OUTPUT_RANGE {\n    pub Flags: u32,\n    pub Reserved: u32,\n    pub StartOffset: u64,\n    pub LengthInBytes: u64,\n}\npub const QUERY_DEPENDENT_VOLUME_REQUEST_FLAG_GUEST_VOLUMES: u32 = 2u32;\npub const QUERY_DEPENDENT_VOLUME_REQUEST_FLAG_HOST_VOLUMES: u32 = 1u32;\npub type QUERY_FILE_LAYOUT_FILTER_TYPE = i32;\npub const QUERY_FILE_LAYOUT_FILTER_TYPE_CLUSTERS: QUERY_FILE_LAYOUT_FILTER_TYPE = 1i32;\npub const QUERY_FILE_LAYOUT_FILTER_TYPE_FILEID: QUERY_FILE_LAYOUT_FILTER_TYPE = 2i32;\npub const QUERY_FILE_LAYOUT_FILTER_TYPE_NONE: QUERY_FILE_LAYOUT_FILTER_TYPE = 0i32;\npub const QUERY_FILE_LAYOUT_FILTER_TYPE_STORAGE_RESERVE_ID: QUERY_FILE_LAYOUT_FILTER_TYPE = 3i32;\npub const QUERY_FILE_LAYOUT_INCLUDE_EXTENTS: u32 = 8u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_EXTRA_INFO: u32 = 16u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_FILES_WITH_DSC_ATTRIBUTE: u32 = 4096u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_FULL_PATH_IN_NAMES: u32 = 64u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_NAMES: u32 = 2u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_ONLY_FILES_WITH_SPECIFIC_ATTRIBUTES: u32 = 2048u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_STREAMS: u32 = 4u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_STREAMS_WITH_NO_CLUSTERS_ALLOCATED: u32 = 32u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_STREAM_INFORMATION: u32 = 128u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_STREAM_INFORMATION_FOR_DATA_ATTRIBUTE: u32 = 8192u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_STREAM_INFORMATION_FOR_DSC_ATTRIBUTE: u32 = 256u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_STREAM_INFORMATION_FOR_EA_ATTRIBUTE: u32 = 32768u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_STREAM_INFORMATION_FOR_EFS_ATTRIBUTE: u32 = 1024u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_STREAM_INFORMATION_FOR_REPARSE_ATTRIBUTE: u32 = 16384u32;\npub const QUERY_FILE_LAYOUT_INCLUDE_STREAM_INFORMATION_FOR_TXF_ATTRIBUTE: u32 = 512u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct QUERY_FILE_LAYOUT_INPUT {\n    pub Anonymous: QUERY_FILE_LAYOUT_INPUT_0,\n    pub Flags: u32,\n    pub FilterType: QUERY_FILE_LAYOUT_FILTER_TYPE,\n    pub Reserved: u32,\n    pub Filter: QUERY_FILE_LAYOUT_INPUT_1,\n}\nimpl Default for QUERY_FILE_LAYOUT_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union QUERY_FILE_LAYOUT_INPUT_0 {\n    pub FilterEntryCount: u32,\n    pub NumberOfPairs: u32,\n}\nimpl Default for QUERY_FILE_LAYOUT_INPUT_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union QUERY_FILE_LAYOUT_INPUT_1 {\n    pub ClusterRanges: [CLUSTER_RANGE; 1],\n    pub FileReferenceRanges: [FILE_REFERENCE_RANGE; 1],\n    pub StorageReserveIds: [STORAGE_RESERVE_ID; 1],\n}\nimpl Default for QUERY_FILE_LAYOUT_INPUT_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const QUERY_FILE_LAYOUT_NUM_FILTER_TYPES: QUERY_FILE_LAYOUT_FILTER_TYPE = 4i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct QUERY_FILE_LAYOUT_OUTPUT {\n    pub FileEntryCount: u32,\n    pub FirstFileOffset: u32,\n    pub Flags: u32,\n    pub Reserved: u32,\n}\npub const QUERY_FILE_LAYOUT_REPARSE_DATA_INVALID: u32 = 1u32;\npub const QUERY_FILE_LAYOUT_REPARSE_TAG_INVALID: u32 = 2u32;\npub const QUERY_FILE_LAYOUT_RESTART: u32 = 1u32;\npub const QUERY_FILE_LAYOUT_SINGLE_INSTANCED: u32 = 1u32;\npub const QUERY_STORAGE_CLASSES_FLAGS_MEASURE_READ: u32 = 1073741824u32;\npub const QUERY_STORAGE_CLASSES_FLAGS_MEASURE_WRITE: u32 = 2147483648u32;\npub const QUERY_STORAGE_CLASSES_FLAGS_NO_DEFRAG_VOLUME: u32 = 536870912u32;\npub const READ_ATTRIBUTES: u32 = 208u32;\npub const READ_ATTRIBUTE_BUFFER_SIZE: u32 = 512u32;\npub const READ_COMPRESSION_INFO_VALID: u32 = 32u32;\npub const READ_COPY_NUMBER_BYPASS_CACHE_FLAG: u32 = 256u32;\npub const READ_COPY_NUMBER_KEY: u32 = 1380142592u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct READ_ELEMENT_ADDRESS_INFO {\n    pub NumberOfElements: u32,\n    pub ElementStatus: [CHANGER_ELEMENT_STATUS; 1],\n}\nimpl Default for READ_ELEMENT_ADDRESS_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct READ_FILE_USN_DATA {\n    pub MinMajorVersion: u16,\n    pub MaxMajorVersion: u16,\n}\npub const READ_THRESHOLDS: u32 = 209u32;\npub const READ_THRESHOLD_BUFFER_SIZE: u32 = 512u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct READ_USN_JOURNAL_DATA_V0 {\n    pub StartUsn: i64,\n    pub ReasonMask: u32,\n    pub ReturnOnlyOnClose: u32,\n    pub Timeout: u64,\n    pub BytesToWaitFor: u64,\n    pub UsnJournalID: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct READ_USN_JOURNAL_DATA_V1 {\n    pub StartUsn: i64,\n    pub ReasonMask: u32,\n    pub ReturnOnlyOnClose: u32,\n    pub Timeout: u64,\n    pub BytesToWaitFor: u64,\n    pub UsnJournalID: u64,\n    pub MinMajorVersion: u16,\n    pub MaxMajorVersion: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct REASSIGN_BLOCKS {\n    pub Reserved: u16,\n    pub Count: u16,\n    pub BlockNumber: [u32; 1],\n}\nimpl Default for REASSIGN_BLOCKS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct REASSIGN_BLOCKS_EX {\n    pub Reserved: u16,\n    pub Count: u16,\n    pub BlockNumber: [i64; 1],\n}\nimpl Default for REASSIGN_BLOCKS_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const RECOVERED_READS_VALID: u32 = 4u32;\npub const RECOVERED_WRITES_VALID: u32 = 1u32;\npub type REFS_SMR_VOLUME_GC_ACTION = i32;\npub type REFS_SMR_VOLUME_GC_METHOD = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct REFS_SMR_VOLUME_GC_PARAMETERS {\n    pub Version: u32,\n    pub Flags: u32,\n    pub Action: REFS_SMR_VOLUME_GC_ACTION,\n    pub Method: REFS_SMR_VOLUME_GC_METHOD,\n    pub IoGranularity: u32,\n    pub CompressionFormat: u32,\n    pub Unused: [u64; 8],\n}\nimpl Default for REFS_SMR_VOLUME_GC_PARAMETERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const REFS_SMR_VOLUME_GC_PARAMETERS_VERSION_V1: u32 = 1u32;\npub type REFS_SMR_VOLUME_GC_STATE = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct REFS_SMR_VOLUME_INFO_OUTPUT {\n    pub Version: u32,\n    pub Flags: u32,\n    pub SizeOfRandomlyWritableTier: i64,\n    pub FreeSpaceInRandomlyWritableTier: i64,\n    pub SizeofSMRTier: i64,\n    pub FreeSpaceInSMRTier: i64,\n    pub UsableFreeSpaceInSMRTier: i64,\n    pub VolumeGcState: REFS_SMR_VOLUME_GC_STATE,\n    pub VolumeGcLastStatus: u32,\n    pub CurrentGcBandFillPercentage: u32,\n    pub Unused: [u64; 6],\n}\nimpl Default for REFS_SMR_VOLUME_INFO_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const REFS_SMR_VOLUME_INFO_OUTPUT_VERSION_V0: u32 = 0u32;\npub const REFS_SMR_VOLUME_INFO_OUTPUT_VERSION_V1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct REFS_VOLUME_DATA_BUFFER {\n    pub ByteCount: u32,\n    pub MajorVersion: u32,\n    pub MinorVersion: u32,\n    pub BytesPerPhysicalSector: u32,\n    pub VolumeSerialNumber: i64,\n    pub NumberSectors: i64,\n    pub TotalClusters: i64,\n    pub FreeClusters: i64,\n    pub TotalReserved: i64,\n    pub BytesPerSector: u32,\n    pub BytesPerCluster: u32,\n    pub MaximumSizeOfResidentFile: i64,\n    pub FastTierDataFillRatio: u16,\n    pub SlowTierDataFillRatio: u16,\n    pub DestagesFastTierToSlowTierRate: u32,\n    pub MetadataChecksumType: u16,\n    pub Reserved0: [u8; 6],\n    pub Reserved: [i64; 8],\n}\nimpl Default for REFS_VOLUME_DATA_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct REMOVE_ELEMENT_AND_TRUNCATE_REQUEST {\n    pub Version: u32,\n    pub Size: u32,\n    pub RequestCapacity: u64,\n    pub ElementIdentifier: u32,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct REPAIR_COPIES_INPUT {\n    pub Size: u32,\n    pub Flags: u32,\n    pub FileOffset: i64,\n    pub Length: u32,\n    pub SourceCopy: u32,\n    pub NumberOfRepairCopies: u32,\n    pub RepairCopies: [u32; 1],\n}\nimpl Default for REPAIR_COPIES_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct REPAIR_COPIES_OUTPUT {\n    pub Size: u32,\n    pub Status: u32,\n    pub ResumeFileOffset: i64,\n}\npub const REPLACE_ALTERNATE: u32 = 11u32;\npub const REPLACE_PRIMARY: u32 = 10u32;\npub const REQUEST_OPLOCK_CURRENT_VERSION: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct REQUEST_OPLOCK_INPUT_BUFFER {\n    pub StructureVersion: u16,\n    pub StructureLength: u16,\n    pub RequestedOplockLevel: u32,\n    pub Flags: u32,\n}\npub const REQUEST_OPLOCK_INPUT_FLAG_ACK: u32 = 2u32;\npub const REQUEST_OPLOCK_INPUT_FLAG_COMPLETE_ACK_ON_CLOSE: u32 = 4u32;\npub const REQUEST_OPLOCK_INPUT_FLAG_REQUEST: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct REQUEST_OPLOCK_OUTPUT_BUFFER {\n    pub StructureVersion: u16,\n    pub StructureLength: u16,\n    pub OriginalOplockLevel: u32,\n    pub NewOplockLevel: u32,\n    pub Flags: u32,\n    pub AccessMode: u32,\n    pub ShareMode: u16,\n}\npub const REQUEST_OPLOCK_OUTPUT_FLAG_ACK_REQUIRED: u32 = 1u32;\npub const REQUEST_OPLOCK_OUTPUT_FLAG_MODES_PROVIDED: u32 = 2u32;\npub const REQUEST_OPLOCK_OUTPUT_FLAG_WRITABLE_SECTION_PRESENT: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct REQUEST_RAW_ENCRYPTED_DATA {\n    pub FileOffset: i64,\n    pub Length: u32,\n}\npub const RETRACT_IEPORT: u32 = 3u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct RETRIEVAL_POINTERS_AND_REFCOUNT_BUFFER {\n    pub ExtentCount: u32,\n    pub StartingVcn: i64,\n    pub Extents: [RETRIEVAL_POINTERS_AND_REFCOUNT_BUFFER_0; 1],\n}\nimpl Default for RETRIEVAL_POINTERS_AND_REFCOUNT_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct RETRIEVAL_POINTERS_AND_REFCOUNT_BUFFER_0 {\n    pub NextVcn: i64,\n    pub Lcn: i64,\n    pub ReferenceCount: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct RETRIEVAL_POINTERS_BUFFER {\n    pub ExtentCount: u32,\n    pub StartingVcn: i64,\n    pub Extents: [RETRIEVAL_POINTERS_BUFFER_0; 1],\n}\nimpl Default for RETRIEVAL_POINTERS_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct RETRIEVAL_POINTERS_BUFFER_0 {\n    pub NextVcn: i64,\n    pub Lcn: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct RETRIEVAL_POINTER_BASE {\n    pub FileAreaOffset: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct RETRIEVAL_POINTER_COUNT {\n    pub ExtentCount: u32,\n}\npub const RETURN_SMART_STATUS: u32 = 218u32;\npub const REVISION_LENGTH: u32 = 4u32;\npub const RemovableMedia: MEDIA_TYPE = 11i32;\npub const RequestLocation: BIN_TYPES = 1i32;\npub const RequestSize: BIN_TYPES = 0i32;\npub const SAIT: STORAGE_MEDIA_TYPE = 93i32;\npub const SAVE_ATTRIBUTE_VALUES: u32 = 211u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_BUS_DEDICATED_MEMORY_DEVICES_INFO {\n    pub Version: u32,\n    pub Size: u32,\n    pub DeviceCount: u32,\n    pub Devices: [SCM_BUS_DEDICATED_MEMORY_DEVICE_INFO; 1],\n}\nimpl Default for SCM_BUS_DEDICATED_MEMORY_DEVICES_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_BUS_DEDICATED_MEMORY_DEVICE_INFO {\n    pub DeviceGuid: windows_sys::core::GUID,\n    pub DeviceNumber: u32,\n    pub Flags: SCM_BUS_DEDICATED_MEMORY_DEVICE_INFO_0,\n    pub DeviceSize: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_BUS_DEDICATED_MEMORY_DEVICE_INFO_0 {\n    pub _bitfield: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_BUS_DEDICATED_MEMORY_STATE {\n    pub ActivateState: bool,\n}\npub type SCM_BUS_FIRMWARE_ACTIVATION_STATE = i32;\npub type SCM_BUS_PROPERTY_ID = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_BUS_PROPERTY_QUERY {\n    pub Version: u32,\n    pub Size: u32,\n    pub PropertyId: SCM_BUS_PROPERTY_ID,\n    pub QueryType: SCM_BUS_QUERY_TYPE,\n    pub AdditionalParameters: [u8; 1],\n}\nimpl Default for SCM_BUS_PROPERTY_QUERY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_BUS_PROPERTY_SET {\n    pub Version: u32,\n    pub Size: u32,\n    pub PropertyId: SCM_BUS_PROPERTY_ID,\n    pub SetType: SCM_BUS_SET_TYPE,\n    pub AdditionalParameters: [u8; 1],\n}\nimpl Default for SCM_BUS_PROPERTY_SET {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type SCM_BUS_QUERY_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_BUS_RUNTIME_FW_ACTIVATION_INFO {\n    pub Version: u32,\n    pub Size: u32,\n    pub RuntimeFwActivationSupported: bool,\n    pub FirmwareActivationState: SCM_BUS_FIRMWARE_ACTIVATION_STATE,\n    pub FirmwareActivationCapability: SCM_BUS_RUNTIME_FW_ACTIVATION_INFO_0,\n    pub EstimatedFirmwareActivationTimeInUSecs: u64,\n    pub EstimatedProcessorAccessQuiesceTimeInUSecs: u64,\n    pub EstimatedIOAccessQuiesceTimeInUSecs: u64,\n    pub PlatformSupportedMaxIOAccessQuiesceTimeInUSecs: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_BUS_RUNTIME_FW_ACTIVATION_INFO_0 {\n    pub _bitfield: u32,\n}\npub type SCM_BUS_SET_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_INTERLEAVED_PD_INFO {\n    pub DeviceHandle: u32,\n    pub DeviceGuid: windows_sys::core::GUID,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_LD_INTERLEAVE_SET_INFO {\n    pub Version: u32,\n    pub Size: u32,\n    pub InterleaveSetSize: u32,\n    pub InterleaveSet: [SCM_INTERLEAVED_PD_INFO; 1],\n}\nimpl Default for SCM_LD_INTERLEAVE_SET_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_LOGICAL_DEVICES {\n    pub Version: u32,\n    pub Size: u32,\n    pub DeviceCount: u32,\n    pub Devices: [SCM_LOGICAL_DEVICE_INSTANCE; 1],\n}\nimpl Default for SCM_LOGICAL_DEVICES {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_LOGICAL_DEVICE_INSTANCE {\n    pub Version: u32,\n    pub Size: u32,\n    pub DeviceGuid: windows_sys::core::GUID,\n    pub SymbolicLink: [u16; 256],\n}\nimpl Default for SCM_LOGICAL_DEVICE_INSTANCE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SCM_MAX_SYMLINK_LEN_IN_CHARS: u32 = 256u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_PD_DESCRIPTOR_HEADER {\n    pub Version: u32,\n    pub Size: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_PD_DEVICE_HANDLE {\n    pub Version: u32,\n    pub Size: u32,\n    pub DeviceGuid: windows_sys::core::GUID,\n    pub DeviceHandle: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_DEVICE_INFO {\n    pub Version: u32,\n    pub Size: u32,\n    pub DeviceGuid: windows_sys::core::GUID,\n    pub UnsafeShutdownCount: u32,\n    pub PersistentMemorySizeInBytes: u64,\n    pub VolatileMemorySizeInBytes: u64,\n    pub TotalMemorySizeInBytes: u64,\n    pub SlotNumber: u32,\n    pub DeviceHandle: u32,\n    pub PhysicalId: u16,\n    pub NumberOfFormatInterfaceCodes: u8,\n    pub FormatInterfaceCodes: [u16; 8],\n    pub VendorId: u32,\n    pub ProductId: u32,\n    pub SubsystemDeviceId: u32,\n    pub SubsystemVendorId: u32,\n    pub ManufacturingLocation: u8,\n    pub ManufacturingWeek: u8,\n    pub ManufacturingYear: u8,\n    pub SerialNumber4Byte: u32,\n    pub SerialNumberLengthInChars: u32,\n    pub SerialNumber: [i8; 1],\n}\nimpl Default for SCM_PD_DEVICE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_DEVICE_SPECIFIC_INFO {\n    pub Version: u32,\n    pub Size: u32,\n    pub NumberOfProperties: u32,\n    pub DeviceSpecificProperties: [SCM_PD_DEVICE_SPECIFIC_PROPERTY; 1],\n}\nimpl Default for SCM_PD_DEVICE_SPECIFIC_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_DEVICE_SPECIFIC_PROPERTY {\n    pub Name: [u16; 128],\n    pub Value: i64,\n}\nimpl Default for SCM_PD_DEVICE_SPECIFIC_PROPERTY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_PD_FIRMWARE_ACTIVATE {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub Slot: u8,\n}\npub type SCM_PD_FIRMWARE_ACTIVATION_STATE = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_FIRMWARE_DOWNLOAD {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub Slot: u8,\n    pub Reserved: [u8; 3],\n    pub Offset: u64,\n    pub FirmwareImageSizeInBytes: u32,\n    pub FirmwareImage: [u8; 1],\n}\nimpl Default for SCM_PD_FIRMWARE_DOWNLOAD {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_FIRMWARE_INFO {\n    pub Version: u32,\n    pub Size: u32,\n    pub ActiveSlot: u8,\n    pub NextActiveSlot: u8,\n    pub SlotCount: u8,\n    pub Slots: [SCM_PD_FIRMWARE_SLOT_INFO; 1],\n}\nimpl Default for SCM_PD_FIRMWARE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SCM_PD_FIRMWARE_LAST_DOWNLOAD: u32 = 1u32;\npub const SCM_PD_FIRMWARE_REVISION_LENGTH_BYTES: u32 = 32u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_FIRMWARE_SLOT_INFO {\n    pub Version: u32,\n    pub Size: u32,\n    pub SlotNumber: u8,\n    pub _bitfield: u8,\n    pub Reserved1: [u8; 6],\n    pub Revision: [u8; 32],\n}\nimpl Default for SCM_PD_FIRMWARE_SLOT_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_FRU_ID_STRING {\n    pub Version: u32,\n    pub Size: u32,\n    pub IdentifierSize: u32,\n    pub Identifier: [u8; 1],\n}\nimpl Default for SCM_PD_FRU_ID_STRING {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_PD_HEALTH_NOTIFICATION_DATA {\n    pub DeviceGuid: windows_sys::core::GUID,\n}\npub type SCM_PD_HEALTH_STATUS = i32;\npub type SCM_PD_LAST_FW_ACTIVATION_STATUS = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_LOCATION_STRING {\n    pub Version: u32,\n    pub Size: u32,\n    pub Location: [u16; 1],\n}\nimpl Default for SCM_PD_LOCATION_STRING {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_MANAGEMENT_STATUS {\n    pub Version: u32,\n    pub Size: u32,\n    pub Health: SCM_PD_HEALTH_STATUS,\n    pub NumberOfOperationalStatus: u32,\n    pub NumberOfAdditionalReasons: u32,\n    pub OperationalStatus: [SCM_PD_OPERATIONAL_STATUS; 16],\n    pub AdditionalReasons: [SCM_PD_OPERATIONAL_STATUS_REASON; 1],\n}\nimpl Default for SCM_PD_MANAGEMENT_STATUS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SCM_PD_MAX_OPERATIONAL_STATUS: u32 = 16u32;\npub type SCM_PD_MEDIA_REINITIALIZATION_STATUS = i32;\npub type SCM_PD_OPERATIONAL_STATUS = i32;\npub type SCM_PD_OPERATIONAL_STATUS_REASON = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_PASSTHROUGH_INPUT {\n    pub Version: u32,\n    pub Size: u32,\n    pub ProtocolGuid: windows_sys::core::GUID,\n    pub DataSize: u32,\n    pub Data: [u8; 1],\n}\nimpl Default for SCM_PD_PASSTHROUGH_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_PASSTHROUGH_INVDIMM_INPUT {\n    pub Opcode: u32,\n    pub OpcodeParametersLength: u32,\n    pub OpcodeParameters: [u8; 1],\n}\nimpl Default for SCM_PD_PASSTHROUGH_INVDIMM_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_PASSTHROUGH_INVDIMM_OUTPUT {\n    pub GeneralStatus: u16,\n    pub ExtendedStatus: u16,\n    pub OutputDataLength: u32,\n    pub OutputData: [u8; 1],\n}\nimpl Default for SCM_PD_PASSTHROUGH_INVDIMM_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_PASSTHROUGH_OUTPUT {\n    pub Version: u32,\n    pub Size: u32,\n    pub ProtocolGuid: windows_sys::core::GUID,\n    pub DataSize: u32,\n    pub Data: [u8; 1],\n}\nimpl Default for SCM_PD_PASSTHROUGH_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type SCM_PD_PROPERTY_ID = i32;\npub const SCM_PD_PROPERTY_NAME_LENGTH_IN_CHARS: u32 = 128u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_PROPERTY_QUERY {\n    pub Version: u32,\n    pub Size: u32,\n    pub PropertyId: SCM_PD_PROPERTY_ID,\n    pub QueryType: SCM_PD_QUERY_TYPE,\n    pub AdditionalParameters: [u8; 1],\n}\nimpl Default for SCM_PD_PROPERTY_QUERY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PD_PROPERTY_SET {\n    pub Version: u32,\n    pub Size: u32,\n    pub PropertyId: SCM_PD_PROPERTY_ID,\n    pub SetType: SCM_PD_SET_TYPE,\n    pub AdditionalParameters: [u8; 1],\n}\nimpl Default for SCM_PD_PROPERTY_SET {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type SCM_PD_QUERY_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_PD_REINITIALIZE_MEDIA_INPUT {\n    pub Version: u32,\n    pub Size: u32,\n    pub Options: SCM_PD_REINITIALIZE_MEDIA_INPUT_0,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_PD_REINITIALIZE_MEDIA_INPUT_0 {\n    pub _bitfield: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_PD_REINITIALIZE_MEDIA_OUTPUT {\n    pub Version: u32,\n    pub Size: u32,\n    pub Status: SCM_PD_MEDIA_REINITIALIZATION_STATUS,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_PD_RUNTIME_FW_ACTIVATION_ARM_STATE {\n    pub ArmState: bool,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_PD_RUNTIME_FW_ACTIVATION_INFO {\n    pub Version: u32,\n    pub Size: u32,\n    pub LastFirmwareActivationStatus: SCM_PD_LAST_FW_ACTIVATION_STATUS,\n    pub FirmwareActivationState: SCM_PD_FIRMWARE_ACTIVATION_STATE,\n}\npub type SCM_PD_SET_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PHYSICAL_DEVICES {\n    pub Version: u32,\n    pub Size: u32,\n    pub DeviceCount: u32,\n    pub Devices: [SCM_PHYSICAL_DEVICE_INSTANCE; 1],\n}\nimpl Default for SCM_PHYSICAL_DEVICES {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_PHYSICAL_DEVICE_INSTANCE {\n    pub Version: u32,\n    pub Size: u32,\n    pub NfitHandle: u32,\n    pub SymbolicLink: [u16; 256],\n}\nimpl Default for SCM_PHYSICAL_DEVICE_INSTANCE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SCM_REGION {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub NfitHandle: u32,\n    pub LogicalDeviceGuid: windows_sys::core::GUID,\n    pub AddressRangeType: windows_sys::core::GUID,\n    pub AssociatedId: u32,\n    pub Length: u64,\n    pub StartingDPA: u64,\n    pub BaseSPA: u64,\n    pub SPAOffset: u64,\n    pub RegionOffset: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SCM_REGIONS {\n    pub Version: u32,\n    pub Size: u32,\n    pub RegionCount: u32,\n    pub Regions: [SCM_REGION; 1],\n}\nimpl Default for SCM_REGIONS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type SCM_REGION_FLAG = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SD_CHANGE_MACHINE_SID_INPUT {\n    pub CurrentMachineSIDOffset: u16,\n    pub CurrentMachineSIDLength: u16,\n    pub NewMachineSIDOffset: u16,\n    pub NewMachineSIDLength: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SD_CHANGE_MACHINE_SID_OUTPUT {\n    pub NumSDChangedSuccess: u64,\n    pub NumSDChangedFail: u64,\n    pub NumSDUnused: u64,\n    pub NumSDTotal: u64,\n    pub NumMftSDChangedSuccess: u64,\n    pub NumMftSDChangedFail: u64,\n    pub NumMftSDTotal: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SD_ENUM_SDS_ENTRY {\n    pub Hash: u32,\n    pub SecurityId: u32,\n    pub Offset: u64,\n    pub Length: u32,\n    pub Descriptor: [u8; 1],\n}\nimpl Default for SD_ENUM_SDS_ENTRY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SD_ENUM_SDS_INPUT {\n    pub StartingOffset: u64,\n    pub MaxSDEntriesToReturn: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SD_ENUM_SDS_OUTPUT {\n    pub NextOffset: u64,\n    pub NumSDEntriesReturned: u64,\n    pub NumSDBytesReturned: u64,\n    pub SDEntry: [SD_ENUM_SDS_ENTRY; 1],\n}\nimpl Default for SD_ENUM_SDS_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SD_GLOBAL_CHANGE_INPUT {\n    pub Flags: u32,\n    pub ChangeType: u32,\n    pub Anonymous: SD_GLOBAL_CHANGE_INPUT_0,\n}\nimpl Default for SD_GLOBAL_CHANGE_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union SD_GLOBAL_CHANGE_INPUT_0 {\n    pub SdChange: SD_CHANGE_MACHINE_SID_INPUT,\n    pub SdQueryStats: SD_QUERY_STATS_INPUT,\n    pub SdEnumSds: SD_ENUM_SDS_INPUT,\n}\nimpl Default for SD_GLOBAL_CHANGE_INPUT_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SD_GLOBAL_CHANGE_OUTPUT {\n    pub Flags: u32,\n    pub ChangeType: u32,\n    pub Anonymous: SD_GLOBAL_CHANGE_OUTPUT_0,\n}\nimpl Default for SD_GLOBAL_CHANGE_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union SD_GLOBAL_CHANGE_OUTPUT_0 {\n    pub SdChange: SD_CHANGE_MACHINE_SID_OUTPUT,\n    pub SdQueryStats: SD_QUERY_STATS_OUTPUT,\n    pub SdEnumSds: SD_ENUM_SDS_OUTPUT,\n}\nimpl Default for SD_GLOBAL_CHANGE_OUTPUT_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SD_GLOBAL_CHANGE_TYPE_ENUM_SDS: u32 = 131072u32;\npub const SD_GLOBAL_CHANGE_TYPE_MACHINE_SID: u32 = 1u32;\npub const SD_GLOBAL_CHANGE_TYPE_QUERY_STATS: u32 = 65536u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SD_QUERY_STATS_INPUT {\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SD_QUERY_STATS_OUTPUT {\n    pub SdsStreamSize: u64,\n    pub SdsAllocationSize: u64,\n    pub SiiStreamSize: u64,\n    pub SiiAllocationSize: u64,\n    pub SdhStreamSize: u64,\n    pub SdhAllocationSize: u64,\n    pub NumSDTotal: u64,\n    pub NumSDUnused: u64,\n}\npub const SEARCH_ALL: u32 = 0u32;\npub const SEARCH_ALL_NO_SEQ: u32 = 4u32;\npub const SEARCH_ALTERNATE: u32 = 2u32;\npub const SEARCH_ALT_NO_SEQ: u32 = 6u32;\npub const SEARCH_PRIMARY: u32 = 1u32;\npub const SEARCH_PRI_NO_SEQ: u32 = 5u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct SENDCMDINPARAMS {\n    pub cBufferSize: u32,\n    pub irDriveRegs: IDEREGS,\n    pub bDriveNumber: u8,\n    pub bReserved: [u8; 3],\n    pub dwReserved: [u32; 4],\n    pub bBuffer: [u8; 1],\n}\nimpl Default for SENDCMDINPARAMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct SENDCMDOUTPARAMS {\n    pub cBufferSize: u32,\n    pub DriverStatus: DRIVERSTATUS,\n    pub bBuffer: [u8; 1],\n}\nimpl Default for SENDCMDOUTPARAMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SERIAL_IOC_FCR_DMA_MODE: u32 = 8u32;\npub const SERIAL_IOC_FCR_FIFO_ENABLE: u32 = 1u32;\npub const SERIAL_IOC_FCR_RCVR_RESET: u32 = 2u32;\npub const SERIAL_IOC_FCR_RCVR_TRIGGER_LSB: u32 = 64u32;\npub const SERIAL_IOC_FCR_RCVR_TRIGGER_MSB: u32 = 128u32;\npub const SERIAL_IOC_FCR_RES1: u32 = 16u32;\npub const SERIAL_IOC_FCR_RES2: u32 = 32u32;\npub const SERIAL_IOC_FCR_XMIT_RESET: u32 = 4u32;\npub const SERIAL_IOC_MCR_DTR: u32 = 1u32;\npub const SERIAL_IOC_MCR_LOOP: u32 = 16u32;\npub const SERIAL_IOC_MCR_OUT1: u32 = 4u32;\npub const SERIAL_IOC_MCR_OUT2: u32 = 8u32;\npub const SERIAL_IOC_MCR_RTS: u32 = 2u32;\npub const SERIAL_NUMBER_LENGTH: u32 = 32u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SET_DAX_ALLOC_ALIGNMENT_HINT_INPUT {\n    pub Flags: u32,\n    pub AlignmentShift: u32,\n    pub FileOffsetToAlign: u64,\n    pub FallbackAlignmentShift: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SET_DISK_ATTRIBUTES {\n    pub Version: u32,\n    pub Persist: bool,\n    pub Reserved1: [u8; 3],\n    pub Attributes: u64,\n    pub AttributesMask: u64,\n    pub Reserved2: [u32; 4],\n}\nimpl Default for SET_DISK_ATTRIBUTES {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SET_PARTITION_INFORMATION {\n    pub PartitionType: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SET_PARTITION_INFORMATION_EX {\n    pub PartitionStyle: PARTITION_STYLE,\n    pub Anonymous: SET_PARTITION_INFORMATION_EX_0,\n}\nimpl Default for SET_PARTITION_INFORMATION_EX {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union SET_PARTITION_INFORMATION_EX_0 {\n    pub Mbr: SET_PARTITION_INFORMATION,\n    pub Gpt: PARTITION_INFORMATION_GPT,\n}\nimpl Default for SET_PARTITION_INFORMATION_EX_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SET_PURGE_FAILURE_MODE_DISABLED: u32 = 2u32;\npub const SET_PURGE_FAILURE_MODE_ENABLED: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SET_PURGE_FAILURE_MODE_INPUT {\n    pub Flags: u32,\n}\npub const SET_REPAIR_DISABLED_AND_BUGCHECK_ON_CORRUPT: u32 = 16u32;\npub const SET_REPAIR_ENABLED: u32 = 1u32;\npub const SET_REPAIR_VALID_MASK: u32 = 25u32;\npub const SET_REPAIR_WARN_ABOUT_DATA_LOSS: u32 = 8u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SHRINK_VOLUME_INFORMATION {\n    pub ShrinkRequestType: SHRINK_VOLUME_REQUEST_TYPES,\n    pub Flags: u64,\n    pub NewNumberOfSectors: i64,\n}\npub type SHRINK_VOLUME_REQUEST_TYPES = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SI_COPYFILE {\n    pub SourceFileNameLength: u32,\n    pub DestinationFileNameLength: u32,\n    pub Flags: u32,\n    pub FileNameBuffer: [u16; 1],\n}\nimpl Default for SI_COPYFILE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SMART_ABORT_OFFLINE_SELFTEST: u32 = 127u32;\npub const SMART_CMD: u32 = 176u32;\npub const SMART_CYL_HI: u32 = 194u32;\npub const SMART_CYL_LOW: u32 = 79u32;\npub const SMART_ERROR_NO_MEM: u32 = 7u32;\npub const SMART_EXTENDED_SELFTEST_CAPTIVE: u32 = 130u32;\npub const SMART_EXTENDED_SELFTEST_OFFLINE: u32 = 2u32;\npub const SMART_GET_VERSION: u32 = 475264u32;\npub const SMART_IDE_ERROR: u32 = 1u32;\npub const SMART_INVALID_BUFFER: u32 = 4u32;\npub const SMART_INVALID_COMMAND: u32 = 3u32;\npub const SMART_INVALID_DRIVE: u32 = 5u32;\npub const SMART_INVALID_FLAG: u32 = 2u32;\npub const SMART_INVALID_IOCTL: u32 = 6u32;\npub const SMART_INVALID_REGISTER: u32 = 8u32;\npub const SMART_LOG_SECTOR_SIZE: u32 = 512u32;\npub const SMART_NOT_SUPPORTED: u32 = 9u32;\npub const SMART_NO_ERROR: u32 = 0u32;\npub const SMART_NO_IDE_DEVICE: u32 = 10u32;\npub const SMART_OFFLINE_ROUTINE_OFFLINE: u32 = 0u32;\npub const SMART_RCV_DRIVE_DATA: u32 = 508040u32;\npub const SMART_RCV_DRIVE_DATA_EX: u32 = 458892u32;\npub const SMART_READ_LOG: u32 = 213u32;\npub const SMART_SEND_DRIVE_COMMAND: u32 = 508036u32;\npub const SMART_SHORT_SELFTEST_CAPTIVE: u32 = 129u32;\npub const SMART_SHORT_SELFTEST_OFFLINE: u32 = 1u32;\npub const SMART_WRITE_LOG: u32 = 214u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SMB_SHARE_FLUSH_AND_PURGE_INPUT {\n    pub Version: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct SMB_SHARE_FLUSH_AND_PURGE_OUTPUT {\n    pub cEntriesPurged: u32,\n}\npub const SONY_12_WO: STORAGE_MEDIA_TYPE = 66i32;\npub const SONY_D2: STORAGE_MEDIA_TYPE = 49i32;\npub const SONY_DTF: STORAGE_MEDIA_TYPE = 46i32;\npub const SPACES_TRACKED_OFFSET_HEADER_FLAG: u32 = 2u32;\npub const SRB_TYPE_SCSI_REQUEST_BLOCK: u32 = 0u32;\npub const SRB_TYPE_STORAGE_REQUEST_BLOCK: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STARTING_LCN_INPUT_BUFFER {\n    pub StartingLcn: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STARTING_LCN_INPUT_BUFFER_EX {\n    pub StartingLcn: i64,\n    pub Flags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STARTING_VCN_INPUT_BUFFER {\n    pub StartingVcn: i64,\n}\npub const STK_9840: STORAGE_MEDIA_TYPE = 85i32;\npub const STK_9940: STORAGE_MEDIA_TYPE = 92i32;\npub const STK_DATA_D3: STORAGE_MEDIA_TYPE = 45i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub BytesPerCacheLine: u32,\n    pub BytesOffsetForCacheAlignment: u32,\n    pub BytesPerLogicalSector: u32,\n    pub BytesPerPhysicalSector: u32,\n    pub BytesOffsetForSectorAlignment: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_ADAPTER_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub MaximumTransferLength: u32,\n    pub MaximumPhysicalPages: u32,\n    pub AlignmentMask: u32,\n    pub AdapterUsesPio: bool,\n    pub AdapterScansDown: bool,\n    pub CommandQueueing: bool,\n    pub AcceleratedTransfer: bool,\n    pub BusType: u8,\n    pub BusMajorVersion: u16,\n    pub BusMinorVersion: u16,\n    pub SrbType: u8,\n    pub AddressType: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_ADAPTER_SERIAL_NUMBER {\n    pub Version: u32,\n    pub Size: u32,\n    pub SerialNumber: [u16; 128],\n}\nimpl Default for STORAGE_ADAPTER_SERIAL_NUMBER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STORAGE_ADAPTER_SERIAL_NUMBER_V1_MAX_LENGTH: u32 = 128u32;\npub const STORAGE_ADDRESS_TYPE_BTL8: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_ALLOCATE_BC_STREAM_INPUT {\n    pub Version: u32,\n    pub RequestsPerPeriod: u32,\n    pub Period: u32,\n    pub RetryFailures: bool,\n    pub Discardable: bool,\n    pub Reserved1: [bool; 2],\n    pub AccessType: u32,\n    pub AccessMode: u32,\n}\nimpl Default for STORAGE_ALLOCATE_BC_STREAM_INPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_ALLOCATE_BC_STREAM_OUTPUT {\n    pub RequestSize: u64,\n    pub NumOutStandingRequests: u32,\n}\npub type STORAGE_ASSOCIATION_TYPE = i32;\npub const STORAGE_ATTRIBUTE_ASYNC_EVENT_NOTIFICATION: u32 = 16u32;\npub const STORAGE_ATTRIBUTE_BLOCK_IO: u32 = 2u32;\npub const STORAGE_ATTRIBUTE_BYTE_ADDRESSABLE_IO: u32 = 1u32;\npub const STORAGE_ATTRIBUTE_DYNAMIC_PERSISTENCE: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_ATTRIBUTE_MGMT {\n    pub Version: u32,\n    pub Size: u32,\n    pub Action: STORAGE_ATTRIBUTE_MGMT_ACTION,\n    pub Attribute: u32,\n}\npub type STORAGE_ATTRIBUTE_MGMT_ACTION = i32;\npub const STORAGE_ATTRIBUTE_PERF_SIZE_INDEPENDENT: u32 = 32u32;\npub const STORAGE_ATTRIBUTE_VOLATILE: u32 = 8u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_BREAK_RESERVATION_REQUEST {\n    pub Length: u32,\n    pub _unused: u8,\n    pub PathId: u8,\n    pub TargetId: u8,\n    pub Lun: u8,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_BUS_RESET_REQUEST {\n    pub PathId: u8,\n}\npub type STORAGE_COMPONENT_HEALTH_STATUS = i32;\npub const STORAGE_COMPONENT_ROLE_CACHE: u32 = 1u32;\npub const STORAGE_COMPONENT_ROLE_DATA: u32 = 4u32;\npub const STORAGE_COMPONENT_ROLE_TIERING: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_COUNTER {\n    pub Type: STORAGE_COUNTER_TYPE,\n    pub Value: STORAGE_COUNTER_0,\n}\nimpl Default for STORAGE_COUNTER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union STORAGE_COUNTER_0 {\n    pub ManufactureDate: STORAGE_COUNTER_0_0,\n    pub AsUlonglong: u64,\n}\nimpl Default for STORAGE_COUNTER_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_COUNTER_0_0 {\n    pub Week: u32,\n    pub Year: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_COUNTERS {\n    pub Version: u32,\n    pub Size: u32,\n    pub NumberOfCounters: u32,\n    pub Counters: [STORAGE_COUNTER; 1],\n}\nimpl Default for STORAGE_COUNTERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type STORAGE_COUNTER_TYPE = i32;\npub const STORAGE_CRASH_TELEMETRY_REGKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"\\\\Registry\\\\Machine\\\\System\\\\CurrentControlSet\\\\Control\\\\CrashControl\\\\StorageTelemetry\");\npub type STORAGE_CRYPTO_ALGORITHM_ID = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_CRYPTO_CAPABILITY {\n    pub Version: u32,\n    pub Size: u32,\n    pub CryptoCapabilityIndex: u32,\n    pub AlgorithmId: STORAGE_CRYPTO_ALGORITHM_ID,\n    pub KeySize: STORAGE_CRYPTO_KEY_SIZE,\n    pub DataUnitSizeBitmask: u32,\n}\npub const STORAGE_CRYPTO_CAPABILITY_VERSION_1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_CRYPTO_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub NumKeysSupported: u32,\n    pub NumCryptoCapabilities: u32,\n    pub CryptoCapabilities: [STORAGE_CRYPTO_CAPABILITY; 1],\n}\nimpl Default for STORAGE_CRYPTO_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STORAGE_CRYPTO_DESCRIPTOR_VERSION_1: u32 = 1u32;\npub type STORAGE_CRYPTO_KEY_SIZE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DESCRIPTOR_HEADER {\n    pub Version: u32,\n    pub Size: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_ATTRIBUTES_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub Attributes: u64,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy)]\npub struct STORAGE_DEVICE_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub DeviceType: u8,\n    pub DeviceTypeModifier: u8,\n    pub RemovableMedia: bool,\n    pub CommandQueueing: bool,\n    pub VendorIdOffset: u32,\n    pub ProductIdOffset: u32,\n    pub ProductRevisionOffset: u32,\n    pub SerialNumberOffset: u32,\n    pub BusType: super::super::Storage::FileSystem::STORAGE_BUS_TYPE,\n    pub RawPropertiesLength: u32,\n    pub RawDeviceProperties: [u8; 1],\n}\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\nimpl Default for STORAGE_DEVICE_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_DEVICE_FAULT_DOMAIN_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub NumberOfFaultDomains: u32,\n    pub FaultDomainIds: [windows_sys::core::GUID; 1],\n}\nimpl Default for STORAGE_DEVICE_FAULT_DOMAIN_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STORAGE_DEVICE_FLAGS_PAGE_83_DEVICEGUID: u32 = 4u32;\npub const STORAGE_DEVICE_FLAGS_RANDOM_DEVICEGUID_REASON_CONFLICT: u32 = 1u32;\npub const STORAGE_DEVICE_FLAGS_RANDOM_DEVICEGUID_REASON_NOHWID: u32 = 2u32;\npub type STORAGE_DEVICE_FORM_FACTOR = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_DEVICE_ID_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub NumberOfIdentifiers: u32,\n    pub Identifiers: [u8; 1],\n}\nimpl Default for STORAGE_DEVICE_ID_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub LunMaxIoCount: u32,\n    pub AdapterMaxIoCount: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_LED_STATE_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub State: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_DEVICE_LOCATION_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub Location: DEVICE_LOCATION,\n    pub StringOffset: u32,\n}\nimpl Default for STORAGE_DEVICE_LOCATION_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_DEVICE_MANAGEMENT_STATUS {\n    pub Version: u32,\n    pub Size: u32,\n    pub Health: STORAGE_DISK_HEALTH_STATUS,\n    pub NumberOfOperationalStatus: u32,\n    pub NumberOfAdditionalReasons: u32,\n    pub OperationalStatus: [STORAGE_DISK_OPERATIONAL_STATUS; 16],\n    pub AdditionalReasons: [STORAGE_OPERATIONAL_REASON; 1],\n}\nimpl Default for STORAGE_DEVICE_MANAGEMENT_STATUS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STORAGE_DEVICE_MAX_OPERATIONAL_STATUS: u32 = 16u32;\npub const STORAGE_DEVICE_NUMA_NODE_UNKNOWN: u32 = 4294967295u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_NUMA_PROPERTY {\n    pub Version: u32,\n    pub Size: u32,\n    pub NumaNode: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_NUMBER {\n    pub DeviceType: u32,\n    pub DeviceNumber: u32,\n    pub PartitionNumber: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_DEVICE_NUMBERS {\n    pub Version: u32,\n    pub Size: u32,\n    pub NumberOfDevices: u32,\n    pub Devices: [STORAGE_DEVICE_NUMBER; 1],\n}\nimpl Default for STORAGE_DEVICE_NUMBERS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_NUMBER_EX {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub DeviceType: u32,\n    pub DeviceNumber: u32,\n    pub DeviceGuid: windows_sys::core::GUID,\n    pub PartitionNumber: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_POWER_CAP {\n    pub Version: u32,\n    pub Size: u32,\n    pub Units: STORAGE_DEVICE_POWER_CAP_UNITS,\n    pub MaxPower: u64,\n}\npub type STORAGE_DEVICE_POWER_CAP_UNITS = i32;\npub const STORAGE_DEVICE_POWER_CAP_VERSION_V1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_RESILIENCY_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub NameOffset: u32,\n    pub NumberOfLogicalCopies: u32,\n    pub NumberOfPhysicalCopies: u32,\n    pub PhysicalDiskRedundancy: u32,\n    pub NumberOfColumns: u32,\n    pub Interleave: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_SELF_ENCRYPTION_PROPERTY {\n    pub Version: u32,\n    pub Size: u32,\n    pub SupportsSelfEncryption: bool,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_SELF_ENCRYPTION_PROPERTY_V2 {\n    pub Version: u32,\n    pub Size: u32,\n    pub SupportsSelfEncryption: bool,\n    pub EncryptionType: STORAGE_ENCRYPTION_TYPE,\n}\npub const STORAGE_DEVICE_TELEMETRY_REGKEY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"\\\\Registry\\\\Machine\\\\System\\\\CurrentControlSet\\\\Control\\\\Storage\\\\StorageTelemetry\");\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_DEVICE_TIERING_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub TotalNumberOfTiers: u32,\n    pub NumberOfTiersReturned: u32,\n    pub Tiers: [STORAGE_TIER; 1],\n}\nimpl Default for STORAGE_DEVICE_TIERING_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DEVICE_UNSAFE_SHUTDOWN_COUNT {\n    pub Version: u32,\n    pub Size: u32,\n    pub UnsafeShutdownCount: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_DIAGNOSTIC_DATA {\n    pub Version: u32,\n    pub Size: u32,\n    pub ProviderId: windows_sys::core::GUID,\n    pub BufferSize: u32,\n    pub Reserved: u32,\n    pub DiagnosticDataBuffer: [u8; 1],\n}\nimpl Default for STORAGE_DIAGNOSTIC_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STORAGE_DIAGNOSTIC_FLAG_ADAPTER_REQUEST: u32 = 1u32;\npub type STORAGE_DIAGNOSTIC_LEVEL = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_DIAGNOSTIC_REQUEST {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub TargetType: STORAGE_DIAGNOSTIC_TARGET_TYPE,\n    pub Level: STORAGE_DIAGNOSTIC_LEVEL,\n}\npub type STORAGE_DIAGNOSTIC_TARGET_TYPE = i32;\npub type STORAGE_DISK_HEALTH_STATUS = i32;\npub type STORAGE_DISK_OPERATIONAL_STATUS = i32;\npub type STORAGE_ENCRYPTION_TYPE = i32;\npub const STORAGE_EVENT_DEVICE_OPERATION: u64 = 4u64;\npub const STORAGE_EVENT_DEVICE_STATUS: u64 = 2u64;\npub const STORAGE_EVENT_MEDIA_STATUS: u64 = 1u64;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_EVENT_NOTIFICATION {\n    pub Version: u32,\n    pub Size: u32,\n    pub Events: u64,\n}\npub const STORAGE_EVENT_NOTIFICATION_VERSION_V1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_FAILURE_PREDICTION_CONFIG {\n    pub Version: u32,\n    pub Size: u32,\n    pub Set: bool,\n    pub Enabled: bool,\n    pub Reserved: u16,\n}\npub const STORAGE_FAILURE_PREDICTION_CONFIG_V1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_FRU_ID_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub IdentifierSize: u32,\n    pub Identifier: [u8; 1],\n}\nimpl Default for STORAGE_FRU_ID_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_GET_BC_PROPERTIES_OUTPUT {\n    pub MaximumRequestsPerPeriod: u32,\n    pub MinimumPeriod: u32,\n    pub MaximumRequestSize: u64,\n    pub EstimatedTimePerRequest: u32,\n    pub NumOutStandingRequests: u32,\n    pub RequestSize: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_HOTPLUG_INFO {\n    pub Size: u32,\n    pub MediaRemovable: bool,\n    pub MediaHotplug: bool,\n    pub DeviceHotplug: bool,\n    pub WriteCacheEnableOverride: bool,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_HW_ENDURANCE_DATA_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub EnduranceInfo: STORAGE_HW_ENDURANCE_INFO,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_HW_ENDURANCE_INFO {\n    pub ValidFields: u32,\n    pub GroupId: u32,\n    pub Flags: STORAGE_HW_ENDURANCE_INFO_0,\n    pub LifePercentage: u32,\n    pub BytesReadCount: [u8; 16],\n    pub ByteWriteCount: [u8; 16],\n}\nimpl Default for STORAGE_HW_ENDURANCE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_HW_ENDURANCE_INFO_0 {\n    pub _bitfield: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_HW_FIRMWARE_ACTIVATE {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub Slot: u8,\n    pub Reserved0: [u8; 3],\n}\nimpl Default for STORAGE_HW_FIRMWARE_ACTIVATE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_HW_FIRMWARE_DOWNLOAD {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub Slot: u8,\n    pub Reserved: [u8; 3],\n    pub Offset: u64,\n    pub BufferSize: u64,\n    pub ImageBuffer: [u8; 1],\n}\nimpl Default for STORAGE_HW_FIRMWARE_DOWNLOAD {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_HW_FIRMWARE_DOWNLOAD_V2 {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub Slot: u8,\n    pub Reserved: [u8; 3],\n    pub Offset: u64,\n    pub BufferSize: u64,\n    pub ImageSize: u32,\n    pub Reserved2: u32,\n    pub ImageBuffer: [u8; 1],\n}\nimpl Default for STORAGE_HW_FIRMWARE_DOWNLOAD_V2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_HW_FIRMWARE_INFO {\n    pub Version: u32,\n    pub Size: u32,\n    pub _bitfield: u8,\n    pub SlotCount: u8,\n    pub ActiveSlot: u8,\n    pub PendingActivateSlot: u8,\n    pub FirmwareShared: bool,\n    pub Reserved: [u8; 3],\n    pub ImagePayloadAlignment: u32,\n    pub ImagePayloadMaxSize: u32,\n    pub Slot: [STORAGE_HW_FIRMWARE_SLOT_INFO; 1],\n}\nimpl Default for STORAGE_HW_FIRMWARE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_HW_FIRMWARE_INFO_QUERY {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u32,\n    pub Reserved: u32,\n}\npub const STORAGE_HW_FIRMWARE_INVALID_SLOT: u32 = 255u32;\npub const STORAGE_HW_FIRMWARE_REQUEST_FLAG_CONTROLLER: u32 = 1u32;\npub const STORAGE_HW_FIRMWARE_REQUEST_FLAG_FIRST_SEGMENT: u32 = 4u32;\npub const STORAGE_HW_FIRMWARE_REQUEST_FLAG_LAST_SEGMENT: u32 = 2u32;\npub const STORAGE_HW_FIRMWARE_REQUEST_FLAG_REPLACE_EXISTING_IMAGE: u32 = 1073741824u32;\npub const STORAGE_HW_FIRMWARE_REQUEST_FLAG_SWITCH_TO_EXISTING_FIRMWARE: u32 = 2147483648u32;\npub const STORAGE_HW_FIRMWARE_REVISION_LENGTH: u32 = 16u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_HW_FIRMWARE_SLOT_INFO {\n    pub Version: u32,\n    pub Size: u32,\n    pub SlotNumber: u8,\n    pub _bitfield: u8,\n    pub Reserved1: [u8; 6],\n    pub Revision: [u8; 16],\n}\nimpl Default for STORAGE_HW_FIRMWARE_SLOT_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_IDENTIFIER {\n    pub CodeSet: STORAGE_IDENTIFIER_CODE_SET,\n    pub Type: STORAGE_IDENTIFIER_TYPE,\n    pub IdentifierSize: u16,\n    pub NextOffset: u16,\n    pub Association: STORAGE_ASSOCIATION_TYPE,\n    pub Identifier: [u8; 1],\n}\nimpl Default for STORAGE_IDENTIFIER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type STORAGE_IDENTIFIER_CODE_SET = i32;\npub type STORAGE_IDENTIFIER_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_IDLE_POWER {\n    pub Version: u32,\n    pub Size: u32,\n    pub _bitfield: u32,\n    pub D3IdleTimeout: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_IDLE_POWERUP_REASON {\n    pub Version: u32,\n    pub Size: u32,\n    pub PowerupReason: STORAGE_POWERUP_REASON_TYPE,\n}\npub const STORAGE_IDLE_POWERUP_REASON_VERSION_V1: u32 = 1u32;\npub type STORAGE_ID_NAA_FORMAT = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_LB_PROVISIONING_MAP_RESOURCES {\n    pub Size: u32,\n    pub Version: u32,\n    pub _bitfield1: u8,\n    pub Reserved1: [u8; 3],\n    pub _bitfield2: u8,\n    pub Reserved3: [u8; 3],\n    pub AvailableMappingResources: u64,\n    pub UsedMappingResources: u64,\n}\nimpl Default for STORAGE_LB_PROVISIONING_MAP_RESOURCES {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_MEDIA_SERIAL_NUMBER_DATA {\n    pub Reserved: u16,\n    pub SerialNumberLength: u16,\n    pub SerialNumber: [u8; 1],\n}\nimpl Default for STORAGE_MEDIA_SERIAL_NUMBER_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type STORAGE_MEDIA_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_MEDIUM_PRODUCT_TYPE_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub MediumProductType: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_MINIPORT_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub Portdriver: STORAGE_PORT_CODE_SET,\n    pub LUNResetSupported: bool,\n    pub TargetResetSupported: bool,\n    pub IoTimeoutValue: u16,\n    pub ExtraIoInfoSupported: bool,\n    pub Flags: STORAGE_MINIPORT_DESCRIPTOR_0,\n    pub Reserved0: [u8; 2],\n    pub Reserved1: u32,\n}\nimpl Default for STORAGE_MINIPORT_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union STORAGE_MINIPORT_DESCRIPTOR_0 {\n    pub Anonymous: STORAGE_MINIPORT_DESCRIPTOR_0_0,\n    pub AsBYTE: u8,\n}\nimpl Default for STORAGE_MINIPORT_DESCRIPTOR_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_MINIPORT_DESCRIPTOR_0_0 {\n    pub _bitfield: u8,\n}\npub const STORAGE_OFFLOAD_MAX_TOKEN_LENGTH: u32 = 512u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_OFFLOAD_READ_OUTPUT {\n    pub OffloadReadFlags: u32,\n    pub Reserved: u32,\n    pub LengthProtected: u64,\n    pub TokenLength: u32,\n    pub Token: STORAGE_OFFLOAD_TOKEN,\n}\nimpl Default for STORAGE_OFFLOAD_READ_OUTPUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STORAGE_OFFLOAD_READ_RANGE_TRUNCATED: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_OFFLOAD_TOKEN {\n    pub TokenType: [u8; 4],\n    pub Reserved: [u8; 2],\n    pub TokenIdLength: [u8; 2],\n    pub Anonymous: STORAGE_OFFLOAD_TOKEN_0,\n}\nimpl Default for STORAGE_OFFLOAD_TOKEN {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union STORAGE_OFFLOAD_TOKEN_0 {\n    pub StorageOffloadZeroDataToken: STORAGE_OFFLOAD_TOKEN_0_0,\n    pub Token: [u8; 504],\n}\nimpl Default for STORAGE_OFFLOAD_TOKEN_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_OFFLOAD_TOKEN_0_0 {\n    pub Reserved2: [u8; 504],\n}\nimpl Default for STORAGE_OFFLOAD_TOKEN_0_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STORAGE_OFFLOAD_TOKEN_ID_LENGTH: u32 = 504u32;\npub const STORAGE_OFFLOAD_TOKEN_INVALID: u32 = 2u32;\npub const STORAGE_OFFLOAD_TOKEN_TYPE_ZERO_DATA: u32 = 4294901761u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_OFFLOAD_WRITE_OUTPUT {\n    pub OffloadWriteFlags: u32,\n    pub Reserved: u32,\n    pub LengthCopied: u64,\n}\npub const STORAGE_OFFLOAD_WRITE_RANGE_TRUNCATED: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_OPERATIONAL_REASON {\n    pub Version: u32,\n    pub Size: u32,\n    pub Reason: STORAGE_OPERATIONAL_STATUS_REASON,\n    pub RawBytes: STORAGE_OPERATIONAL_REASON_0,\n}\nimpl Default for STORAGE_OPERATIONAL_REASON {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union STORAGE_OPERATIONAL_REASON_0 {\n    pub ScsiSenseKey: STORAGE_OPERATIONAL_REASON_0_0,\n    pub NVDIMM_N: STORAGE_OPERATIONAL_REASON_0_1,\n    pub AsUlong: u32,\n}\nimpl Default for STORAGE_OPERATIONAL_REASON_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_OPERATIONAL_REASON_0_1 {\n    pub CriticalHealth: u8,\n    pub ModuleHealth: [u8; 2],\n    pub ErrorThresholdStatus: u8,\n}\nimpl Default for STORAGE_OPERATIONAL_REASON_0_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_OPERATIONAL_REASON_0_0 {\n    pub SenseKey: u8,\n    pub ASC: u8,\n    pub ASCQ: u8,\n    pub Reserved: u8,\n}\npub type STORAGE_OPERATIONAL_STATUS_REASON = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_PHYSICAL_ADAPTER_DATA {\n    pub AdapterId: u32,\n    pub HealthStatus: STORAGE_COMPONENT_HEALTH_STATUS,\n    pub CommandProtocol: STORAGE_PROTOCOL_TYPE,\n    pub SpecVersion: STORAGE_SPEC_VERSION,\n    pub Vendor: [u8; 8],\n    pub Model: [u8; 40],\n    pub FirmwareRevision: [u8; 16],\n    pub PhysicalLocation: [u8; 32],\n    pub ExpanderConnected: bool,\n    pub Reserved0: [u8; 3],\n    pub Reserved1: [u32; 3],\n}\nimpl Default for STORAGE_PHYSICAL_ADAPTER_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_PHYSICAL_DEVICE_DATA {\n    pub DeviceId: u32,\n    pub Role: u32,\n    pub HealthStatus: STORAGE_COMPONENT_HEALTH_STATUS,\n    pub CommandProtocol: STORAGE_PROTOCOL_TYPE,\n    pub SpecVersion: STORAGE_SPEC_VERSION,\n    pub FormFactor: STORAGE_DEVICE_FORM_FACTOR,\n    pub Vendor: [u8; 8],\n    pub Model: [u8; 40],\n    pub FirmwareRevision: [u8; 16],\n    pub Capacity: u64,\n    pub PhysicalLocation: [u8; 32],\n    pub Reserved: [u32; 2],\n}\nimpl Default for STORAGE_PHYSICAL_DEVICE_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_PHYSICAL_NODE_DATA {\n    pub NodeId: u32,\n    pub AdapterCount: u32,\n    pub AdapterDataLength: u32,\n    pub AdapterDataOffset: u32,\n    pub DeviceCount: u32,\n    pub DeviceDataLength: u32,\n    pub DeviceDataOffset: u32,\n    pub Reserved: [u32; 3],\n}\nimpl Default for STORAGE_PHYSICAL_NODE_DATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub NodeCount: u32,\n    pub Reserved: u32,\n    pub Node: [STORAGE_PHYSICAL_NODE_DATA; 1],\n}\nimpl Default for STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type STORAGE_PORT_CODE_SET = i32;\npub type STORAGE_POWERUP_REASON_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_PREDICT_FAILURE {\n    pub PredictFailure: u32,\n    pub VendorSpecific: [u8; 512],\n}\nimpl Default for STORAGE_PREDICT_FAILURE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_PRIORITY_HINT_SUPPORT {\n    pub SupportFlags: u32,\n}\npub const STORAGE_PRIORITY_HINT_SUPPORTED: u32 = 1u32;\npub type STORAGE_PROPERTY_ID = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_PROPERTY_QUERY {\n    pub PropertyId: STORAGE_PROPERTY_ID,\n    pub QueryType: STORAGE_QUERY_TYPE,\n    pub AdditionalParameters: [u8; 1],\n}\nimpl Default for STORAGE_PROPERTY_QUERY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_PROPERTY_SET {\n    pub PropertyId: STORAGE_PROPERTY_ID,\n    pub SetType: STORAGE_SET_TYPE,\n    pub AdditionalParameters: [u8; 1],\n}\nimpl Default for STORAGE_PROPERTY_SET {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type STORAGE_PROTOCOL_ATA_DATA_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_PROTOCOL_COMMAND {\n    pub Version: u32,\n    pub Length: u32,\n    pub ProtocolType: STORAGE_PROTOCOL_TYPE,\n    pub Flags: u32,\n    pub ReturnStatus: u32,\n    pub ErrorCode: u32,\n    pub CommandLength: u32,\n    pub ErrorInfoLength: u32,\n    pub DataToDeviceTransferLength: u32,\n    pub DataFromDeviceTransferLength: u32,\n    pub TimeOutValue: u32,\n    pub ErrorInfoOffset: u32,\n    pub DataToDeviceBufferOffset: u32,\n    pub DataFromDeviceBufferOffset: u32,\n    pub CommandSpecific: u32,\n    pub Reserved0: u32,\n    pub FixedProtocolReturnData: u32,\n    pub Reserved1: [u32; 3],\n    pub Command: [u8; 1],\n}\nimpl Default for STORAGE_PROTOCOL_COMMAND {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST: u32 = 2147483648u32;\npub const STORAGE_PROTOCOL_COMMAND_LENGTH_NVME: u32 = 64u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_PROTOCOL_DATA_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub ProtocolSpecificData: STORAGE_PROTOCOL_SPECIFIC_DATA,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_PROTOCOL_DATA_DESCRIPTOR_EXT {\n    pub Version: u32,\n    pub Size: u32,\n    pub ProtocolSpecificData: STORAGE_PROTOCOL_SPECIFIC_DATA_EXT,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union STORAGE_PROTOCOL_DATA_SUBVALUE_GET_LOG_PAGE {\n    pub Anonymous: STORAGE_PROTOCOL_DATA_SUBVALUE_GET_LOG_PAGE_0,\n    pub AsUlong: u32,\n}\nimpl Default for STORAGE_PROTOCOL_DATA_SUBVALUE_GET_LOG_PAGE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_PROTOCOL_DATA_SUBVALUE_GET_LOG_PAGE_0 {\n    pub _bitfield: u32,\n}\npub type STORAGE_PROTOCOL_NVME_DATA_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_PROTOCOL_SPECIFIC_DATA {\n    pub ProtocolType: STORAGE_PROTOCOL_TYPE,\n    pub DataType: u32,\n    pub ProtocolDataRequestValue: u32,\n    pub ProtocolDataRequestSubValue: u32,\n    pub ProtocolDataOffset: u32,\n    pub ProtocolDataLength: u32,\n    pub FixedProtocolReturnData: u32,\n    pub ProtocolDataRequestSubValue2: u32,\n    pub ProtocolDataRequestSubValue3: u32,\n    pub ProtocolDataRequestSubValue4: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_PROTOCOL_SPECIFIC_DATA_EXT {\n    pub ProtocolType: STORAGE_PROTOCOL_TYPE,\n    pub DataType: u32,\n    pub ProtocolDataValue: u32,\n    pub ProtocolDataSubValue: u32,\n    pub ProtocolDataOffset: u32,\n    pub ProtocolDataLength: u32,\n    pub FixedProtocolReturnData: u32,\n    pub ProtocolDataSubValue2: u32,\n    pub ProtocolDataSubValue3: u32,\n    pub ProtocolDataSubValue4: u32,\n    pub ProtocolDataSubValue5: u32,\n    pub Reserved: [u32; 5],\n}\nimpl Default for STORAGE_PROTOCOL_SPECIFIC_DATA_EXT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND: u32 = 1u32;\npub const STORAGE_PROTOCOL_SPECIFIC_NVME_NVM_COMMAND: u32 = 2u32;\npub const STORAGE_PROTOCOL_STATUS_BUSY: u32 = 5u32;\npub const STORAGE_PROTOCOL_STATUS_DATA_OVERRUN: u32 = 6u32;\npub const STORAGE_PROTOCOL_STATUS_ERROR: u32 = 2u32;\npub const STORAGE_PROTOCOL_STATUS_INSUFFICIENT_RESOURCES: u32 = 7u32;\npub const STORAGE_PROTOCOL_STATUS_INVALID_REQUEST: u32 = 3u32;\npub const STORAGE_PROTOCOL_STATUS_NOT_SUPPORTED: u32 = 255u32;\npub const STORAGE_PROTOCOL_STATUS_NO_DEVICE: u32 = 4u32;\npub const STORAGE_PROTOCOL_STATUS_PENDING: u32 = 0u32;\npub const STORAGE_PROTOCOL_STATUS_SUCCESS: u32 = 1u32;\npub const STORAGE_PROTOCOL_STATUS_THROTTLED_REQUEST: u32 = 8u32;\npub const STORAGE_PROTOCOL_STRUCTURE_VERSION: u32 = 1u32;\npub type STORAGE_PROTOCOL_TYPE = i32;\npub type STORAGE_PROTOCOL_UFS_DATA_TYPE = i32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_Vhd\")]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_QUERY_DEPENDENT_VOLUME_LEV1_ENTRY {\n    pub EntryLength: u32,\n    pub DependencyTypeFlags: u32,\n    pub ProviderSpecificFlags: u32,\n    pub VirtualStorageType: super::super::Storage::Vhd::VIRTUAL_STORAGE_TYPE,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_Vhd\")]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_QUERY_DEPENDENT_VOLUME_LEV2_ENTRY {\n    pub EntryLength: u32,\n    pub DependencyTypeFlags: u32,\n    pub ProviderSpecificFlags: u32,\n    pub VirtualStorageType: super::super::Storage::Vhd::VIRTUAL_STORAGE_TYPE,\n    pub AncestorLevel: u32,\n    pub HostVolumeNameOffset: u32,\n    pub HostVolumeNameSize: u32,\n    pub DependentVolumeNameOffset: u32,\n    pub DependentVolumeNameSize: u32,\n    pub RelativePathOffset: u32,\n    pub RelativePathSize: u32,\n    pub DependentDeviceNameOffset: u32,\n    pub DependentDeviceNameSize: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_QUERY_DEPENDENT_VOLUME_REQUEST {\n    pub RequestLevel: u32,\n    pub RequestFlags: u32,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_Vhd\")]\n#[derive(Clone, Copy)]\npub struct STORAGE_QUERY_DEPENDENT_VOLUME_RESPONSE {\n    pub ResponseLevel: u32,\n    pub NumberEntries: u32,\n    pub Anonymous: STORAGE_QUERY_DEPENDENT_VOLUME_RESPONSE_0,\n}\n#[cfg(feature = \"Win32_Storage_Vhd\")]\nimpl Default for STORAGE_QUERY_DEPENDENT_VOLUME_RESPONSE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_Vhd\")]\n#[derive(Clone, Copy)]\npub union STORAGE_QUERY_DEPENDENT_VOLUME_RESPONSE_0 {\n    pub Lev1Depends: [STORAGE_QUERY_DEPENDENT_VOLUME_LEV1_ENTRY; 1],\n    pub Lev2Depends: [STORAGE_QUERY_DEPENDENT_VOLUME_LEV2_ENTRY; 1],\n}\n#[cfg(feature = \"Win32_Storage_Vhd\")]\nimpl Default for STORAGE_QUERY_DEPENDENT_VOLUME_RESPONSE_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type STORAGE_QUERY_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_READ_CAPACITY {\n    pub Version: u32,\n    pub Size: u32,\n    pub BlockLength: u32,\n    pub NumberOfBlocks: i64,\n    pub DiskLength: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_REINITIALIZE_MEDIA {\n    pub Version: u32,\n    pub Size: u32,\n    pub TimeoutInSeconds: u32,\n    pub SanitizeOption: STORAGE_REINITIALIZE_MEDIA_0,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_REINITIALIZE_MEDIA_0 {\n    pub _bitfield: u32,\n}\npub type STORAGE_RESERVE_ID = i32;\npub type STORAGE_RPMB_COMMAND_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_RPMB_DATA_FRAME {\n    pub Stuff: [u8; 196],\n    pub KeyOrMAC: [u8; 32],\n    pub Data: [u8; 256],\n    pub Nonce: [u8; 16],\n    pub WriteCounter: [u8; 4],\n    pub Address: [u8; 2],\n    pub BlockCount: [u8; 2],\n    pub OperationResult: [u8; 2],\n    pub RequestOrResponseType: [u8; 2],\n}\nimpl Default for STORAGE_RPMB_DATA_FRAME {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_RPMB_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub SizeInBytes: u32,\n    pub MaxReliableWriteSizeInBytes: u32,\n    pub FrameFormat: STORAGE_RPMB_FRAME_TYPE,\n}\npub const STORAGE_RPMB_DESCRIPTOR_VERSION_1: u32 = 1u32;\npub type STORAGE_RPMB_FRAME_TYPE = i32;\npub const STORAGE_RPMB_MINIMUM_RELIABLE_WRITE_SIZE: u32 = 512u32;\npub type STORAGE_SANITIZE_METHOD = i32;\npub type STORAGE_SET_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union STORAGE_SPEC_VERSION {\n    pub Anonymous: STORAGE_SPEC_VERSION_0,\n    pub AsUlong: u32,\n}\nimpl Default for STORAGE_SPEC_VERSION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_SPEC_VERSION_0 {\n    pub MinorVersion: STORAGE_SPEC_VERSION_0_0,\n    pub MajorVersion: u16,\n}\nimpl Default for STORAGE_SPEC_VERSION_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union STORAGE_SPEC_VERSION_0_0 {\n    pub Anonymous: STORAGE_SPEC_VERSION_0_0_0,\n    pub AsUshort: u16,\n}\nimpl Default for STORAGE_SPEC_VERSION_0_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_SPEC_VERSION_0_0_0 {\n    pub SubMinor: u8,\n    pub Minor: u8,\n}\npub const STORAGE_SUPPORTED_FEATURES_BYPASS_IO: u32 = 1u32;\npub const STORAGE_SUPPORTED_FEATURES_MASK: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_TEMPERATURE_DATA_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub CriticalTemperature: i16,\n    pub WarningTemperature: i16,\n    pub InfoCount: u16,\n    pub Reserved0: [u8; 2],\n    pub Reserved1: [u32; 2],\n    pub TemperatureInfo: [STORAGE_TEMPERATURE_INFO; 1],\n}\nimpl Default for STORAGE_TEMPERATURE_DATA_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_TEMPERATURE_INFO {\n    pub Index: u16,\n    pub Temperature: i16,\n    pub OverThreshold: i16,\n    pub UnderThreshold: i16,\n    pub OverThresholdChangable: bool,\n    pub UnderThresholdChangable: bool,\n    pub EventGenerated: bool,\n    pub Reserved0: u8,\n    pub Reserved1: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_TEMPERATURE_THRESHOLD {\n    pub Version: u32,\n    pub Size: u32,\n    pub Flags: u16,\n    pub Index: u16,\n    pub Threshold: i16,\n    pub OverThreshold: bool,\n    pub Reserved: u8,\n}\npub const STORAGE_TEMPERATURE_THRESHOLD_FLAG_ADAPTER_REQUEST: u32 = 1u32;\npub const STORAGE_TEMPERATURE_VALUE_NOT_REPORTED: u32 = 32768u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_TIER {\n    pub Id: windows_sys::core::GUID,\n    pub Name: [u16; 256],\n    pub Description: [u16; 256],\n    pub Flags: u64,\n    pub ProvisionedCapacity: u64,\n    pub MediaType: STORAGE_TIER_MEDIA_TYPE,\n    pub Class: STORAGE_TIER_CLASS,\n}\nimpl Default for STORAGE_TIER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type STORAGE_TIER_CLASS = i32;\npub const STORAGE_TIER_DESCRIPTION_LENGTH: u32 = 512u32;\npub const STORAGE_TIER_FLAG_NO_SEEK_PENALTY: u32 = 131072u32;\npub const STORAGE_TIER_FLAG_PARITY: u32 = 8388608u32;\npub const STORAGE_TIER_FLAG_READ_CACHE: u32 = 4194304u32;\npub const STORAGE_TIER_FLAG_SMR: u32 = 16777216u32;\npub const STORAGE_TIER_FLAG_WRITE_BACK_CACHE: u32 = 2097152u32;\npub type STORAGE_TIER_MEDIA_TYPE = i32;\npub const STORAGE_TIER_NAME_LENGTH: u32 = 256u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_TIER_REGION {\n    pub TierId: windows_sys::core::GUID,\n    pub Offset: u64,\n    pub Length: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_WRITE_CACHE_PROPERTY {\n    pub Version: u32,\n    pub Size: u32,\n    pub WriteCacheType: WRITE_CACHE_TYPE,\n    pub WriteCacheEnabled: WRITE_CACHE_ENABLE,\n    pub WriteCacheChangeable: WRITE_CACHE_CHANGE,\n    pub WriteThroughSupported: WRITE_THROUGH,\n    pub FlushCacheSupported: bool,\n    pub UserDefinedPowerProtection: bool,\n    pub NVCacheEnabled: bool,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_ZONED_DEVICE_DESCRIPTOR {\n    pub Version: u32,\n    pub Size: u32,\n    pub DeviceType: STORAGE_ZONED_DEVICE_TYPES,\n    pub ZoneCount: u32,\n    pub ZoneAttributes: STORAGE_ZONED_DEVICE_DESCRIPTOR_0,\n    pub ZoneGroupCount: u32,\n    pub ZoneGroup: [STORAGE_ZONE_GROUP; 1],\n}\nimpl Default for STORAGE_ZONED_DEVICE_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union STORAGE_ZONED_DEVICE_DESCRIPTOR_0 {\n    pub SequentialRequiredZone: STORAGE_ZONED_DEVICE_DESCRIPTOR_0_0,\n    pub SequentialPreferredZone: STORAGE_ZONED_DEVICE_DESCRIPTOR_0_1,\n}\nimpl Default for STORAGE_ZONED_DEVICE_DESCRIPTOR_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_ZONED_DEVICE_DESCRIPTOR_0_1 {\n    pub OptimalOpenZoneCount: u32,\n    pub Reserved: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_ZONED_DEVICE_DESCRIPTOR_0_0 {\n    pub MaxOpenZoneCount: u32,\n    pub UnrestrictedRead: bool,\n    pub Reserved: [u8; 3],\n}\nimpl Default for STORAGE_ZONED_DEVICE_DESCRIPTOR_0_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type STORAGE_ZONED_DEVICE_TYPES = i32;\npub type STORAGE_ZONES_ATTRIBUTES = i32;\npub type STORAGE_ZONE_CONDITION = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STORAGE_ZONE_DESCRIPTOR {\n    pub Size: u32,\n    pub ZoneType: STORAGE_ZONE_TYPES,\n    pub ZoneCondition: STORAGE_ZONE_CONDITION,\n    pub ResetWritePointerRecommend: bool,\n    pub Reserved0: [u8; 3],\n    pub ZoneSize: u64,\n    pub WritePointerOffset: u64,\n}\nimpl Default for STORAGE_ZONE_DESCRIPTOR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STORAGE_ZONE_GROUP {\n    pub ZoneCount: u32,\n    pub ZoneType: STORAGE_ZONE_TYPES,\n    pub ZoneSize: u64,\n}\npub type STORAGE_ZONE_TYPES = i32;\npub const STORATTRIBUTE_MANAGEMENT_STATE: u32 = 1u32;\npub const STORATTRIBUTE_NONE: u32 = 0u32;\npub const STREAMS_ASSOCIATE_ID_CLEAR: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STREAMS_ASSOCIATE_ID_INPUT_BUFFER {\n    pub Flags: u32,\n    pub StreamId: u32,\n}\npub const STREAMS_ASSOCIATE_ID_SET: u32 = 2u32;\npub const STREAMS_INVALID_ID: u32 = 0u32;\npub const STREAMS_MAX_ID: u32 = 65535u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STREAMS_QUERY_ID_OUTPUT_BUFFER {\n    pub StreamId: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STREAMS_QUERY_PARAMETERS_OUTPUT_BUFFER {\n    pub OptimalWriteSize: u32,\n    pub StreamGranularitySize: u32,\n    pub StreamIdMin: u32,\n    pub StreamIdMax: u32,\n}\npub const STREAM_CLEAR_ENCRYPTION: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STREAM_EXTENT_ENTRY {\n    pub Flags: u32,\n    pub ExtentInformation: STREAM_EXTENT_ENTRY_0,\n}\nimpl Default for STREAM_EXTENT_ENTRY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union STREAM_EXTENT_ENTRY_0 {\n    pub RetrievalPointers: RETRIEVAL_POINTERS_BUFFER,\n}\nimpl Default for STREAM_EXTENT_ENTRY_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STREAM_EXTENT_ENTRY_ALL_EXTENTS: u32 = 2u32;\npub const STREAM_EXTENT_ENTRY_AS_RETRIEVAL_POINTERS: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STREAM_INFORMATION_ENTRY {\n    pub Version: u32,\n    pub Flags: u32,\n    pub StreamInformation: STREAM_INFORMATION_ENTRY_0,\n}\nimpl Default for STREAM_INFORMATION_ENTRY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union STREAM_INFORMATION_ENTRY_0 {\n    pub DesiredStorageClass: STREAM_INFORMATION_ENTRY_0_0,\n    pub DataStream: STREAM_INFORMATION_ENTRY_0_1,\n    pub Reparse: STREAM_INFORMATION_ENTRY_0_2,\n    pub Ea: STREAM_INFORMATION_ENTRY_0_3,\n}\nimpl Default for STREAM_INFORMATION_ENTRY_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STREAM_INFORMATION_ENTRY_0_1 {\n    pub Length: u16,\n    pub Flags: u16,\n    pub Reserved: u32,\n    pub Vdl: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STREAM_INFORMATION_ENTRY_0_0 {\n    pub Class: FILE_STORAGE_TIER_CLASS,\n    pub Flags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STREAM_INFORMATION_ENTRY_0_3 {\n    pub Length: u16,\n    pub Flags: u16,\n    pub EaSize: u32,\n    pub EaInformationOffset: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct STREAM_INFORMATION_ENTRY_0_2 {\n    pub Length: u16,\n    pub Flags: u16,\n    pub ReparseDataSize: u32,\n    pub ReparseDataOffset: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STREAM_LAYOUT_ENTRY {\n    pub Version: u32,\n    pub NextStreamOffset: u32,\n    pub Flags: u32,\n    pub ExtentInformationOffset: u32,\n    pub AllocationSize: i64,\n    pub EndOfFile: i64,\n    pub StreamInformationOffset: u32,\n    pub AttributeTypeCode: u32,\n    pub AttributeFlags: u32,\n    pub StreamIdentifierLength: u32,\n    pub StreamIdentifier: [u16; 1],\n}\nimpl Default for STREAM_LAYOUT_ENTRY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STREAM_LAYOUT_ENTRY_HAS_INFORMATION: u32 = 16u32;\npub const STREAM_LAYOUT_ENTRY_IMMOVABLE: u32 = 1u32;\npub const STREAM_LAYOUT_ENTRY_NO_CLUSTERS_ALLOCATED: u32 = 8u32;\npub const STREAM_LAYOUT_ENTRY_PINNED: u32 = 2u32;\npub const STREAM_LAYOUT_ENTRY_RESIDENT: u32 = 4u32;\npub const STREAM_SET_ENCRYPTION: u32 = 3u32;\npub const SYQUEST_EZ135: STORAGE_MEDIA_TYPE = 75i32;\npub const SYQUEST_EZFLYER: STORAGE_MEDIA_TYPE = 76i32;\npub const SYQUEST_SYJET: STORAGE_MEDIA_TYPE = 77i32;\npub const ScmBusFirmwareActivationState_Armed: SCM_BUS_FIRMWARE_ACTIVATION_STATE = 1i32;\npub const ScmBusFirmwareActivationState_Busy: SCM_BUS_FIRMWARE_ACTIVATION_STATE = 2i32;\npub const ScmBusFirmwareActivationState_Idle: SCM_BUS_FIRMWARE_ACTIVATION_STATE = 0i32;\npub const ScmBusProperty_DedicatedMemoryInfo: SCM_BUS_PROPERTY_ID = 1i32;\npub const ScmBusProperty_DedicatedMemoryState: SCM_BUS_PROPERTY_ID = 2i32;\npub const ScmBusProperty_Max: SCM_BUS_PROPERTY_ID = 3i32;\npub const ScmBusProperty_RuntimeFwActivationInfo: SCM_BUS_PROPERTY_ID = 0i32;\npub const ScmBusQuery_Descriptor: SCM_BUS_QUERY_TYPE = 0i32;\npub const ScmBusQuery_IsSupported: SCM_BUS_QUERY_TYPE = 1i32;\npub const ScmBusQuery_Max: SCM_BUS_QUERY_TYPE = 2i32;\npub const ScmBusSet_Descriptor: SCM_BUS_SET_TYPE = 0i32;\npub const ScmBusSet_IsSupported: SCM_BUS_SET_TYPE = 1i32;\npub const ScmBusSet_Max: SCM_BUS_SET_TYPE = 2i32;\npub const ScmPdFirmwareActivationState_Armed: SCM_PD_FIRMWARE_ACTIVATION_STATE = 1i32;\npub const ScmPdFirmwareActivationState_Busy: SCM_PD_FIRMWARE_ACTIVATION_STATE = 2i32;\npub const ScmPdFirmwareActivationState_Idle: SCM_PD_FIRMWARE_ACTIVATION_STATE = 0i32;\npub const ScmPdLastFwActivaitonStatus_ActivationInProgress: SCM_PD_LAST_FW_ACTIVATION_STATUS = 4i32;\npub const ScmPdLastFwActivaitonStatus_FwUnsupported: SCM_PD_LAST_FW_ACTIVATION_STATUS = 6i32;\npub const ScmPdLastFwActivaitonStatus_Retry: SCM_PD_LAST_FW_ACTIVATION_STATUS = 5i32;\npub const ScmPdLastFwActivaitonStatus_UnknownError: SCM_PD_LAST_FW_ACTIVATION_STATUS = 7i32;\npub const ScmPdLastFwActivationStatus_ColdRebootRequired: SCM_PD_LAST_FW_ACTIVATION_STATUS = 3i32;\npub const ScmPdLastFwActivationStatus_FwNotFound: SCM_PD_LAST_FW_ACTIVATION_STATUS = 2i32;\npub const ScmPdLastFwActivationStatus_None: SCM_PD_LAST_FW_ACTIVATION_STATUS = 0i32;\npub const ScmPdLastFwActivationStatus_Success: SCM_PD_LAST_FW_ACTIVATION_STATUS = 1i32;\npub const ScmPhysicalDeviceHealth_Healthy: SCM_PD_HEALTH_STATUS = 3i32;\npub const ScmPhysicalDeviceHealth_Max: SCM_PD_HEALTH_STATUS = 4i32;\npub const ScmPhysicalDeviceHealth_Unhealthy: SCM_PD_HEALTH_STATUS = 1i32;\npub const ScmPhysicalDeviceHealth_Unknown: SCM_PD_HEALTH_STATUS = 0i32;\npub const ScmPhysicalDeviceHealth_Warning: SCM_PD_HEALTH_STATUS = 2i32;\npub const ScmPhysicalDeviceOpReason_BackgroundOperation: SCM_PD_OPERATIONAL_STATUS_REASON = 9i32;\npub const ScmPhysicalDeviceOpReason_Component: SCM_PD_OPERATIONAL_STATUS_REASON = 8i32;\npub const ScmPhysicalDeviceOpReason_Configuration: SCM_PD_OPERATIONAL_STATUS_REASON = 5i32;\npub const ScmPhysicalDeviceOpReason_DataPersistenceLossImminent: SCM_PD_OPERATIONAL_STATUS_REASON = 17i32;\npub const ScmPhysicalDeviceOpReason_DeviceController: SCM_PD_OPERATIONAL_STATUS_REASON = 6i32;\npub const ScmPhysicalDeviceOpReason_DisabledByPlatform: SCM_PD_OPERATIONAL_STATUS_REASON = 13i32;\npub const ScmPhysicalDeviceOpReason_EnergySource: SCM_PD_OPERATIONAL_STATUS_REASON = 4i32;\npub const ScmPhysicalDeviceOpReason_ExcessiveTemperature: SCM_PD_OPERATIONAL_STATUS_REASON = 21i32;\npub const ScmPhysicalDeviceOpReason_FatalError: SCM_PD_OPERATIONAL_STATUS_REASON = 16i32;\npub const ScmPhysicalDeviceOpReason_HealthCheck: SCM_PD_OPERATIONAL_STATUS_REASON = 11i32;\npub const ScmPhysicalDeviceOpReason_InternalFailure: SCM_PD_OPERATIONAL_STATUS_REASON = 22i32;\npub const ScmPhysicalDeviceOpReason_InvalidFirmware: SCM_PD_OPERATIONAL_STATUS_REASON = 10i32;\npub const ScmPhysicalDeviceOpReason_LostData: SCM_PD_OPERATIONAL_STATUS_REASON = 3i32;\npub const ScmPhysicalDeviceOpReason_LostDataPersistence: SCM_PD_OPERATIONAL_STATUS_REASON = 12i32;\npub const ScmPhysicalDeviceOpReason_LostWritePersistence: SCM_PD_OPERATIONAL_STATUS_REASON = 15i32;\npub const ScmPhysicalDeviceOpReason_Max: SCM_PD_OPERATIONAL_STATUS_REASON = 23i32;\npub const ScmPhysicalDeviceOpReason_Media: SCM_PD_OPERATIONAL_STATUS_REASON = 1i32;\npub const ScmPhysicalDeviceOpReason_MediaController: SCM_PD_OPERATIONAL_STATUS_REASON = 7i32;\npub const ScmPhysicalDeviceOpReason_MediaRemainingSpareBlock: SCM_PD_OPERATIONAL_STATUS_REASON = 19i32;\npub const ScmPhysicalDeviceOpReason_PerformanceDegradation: SCM_PD_OPERATIONAL_STATUS_REASON = 20i32;\npub const ScmPhysicalDeviceOpReason_PermanentError: SCM_PD_OPERATIONAL_STATUS_REASON = 14i32;\npub const ScmPhysicalDeviceOpReason_ThresholdExceeded: SCM_PD_OPERATIONAL_STATUS_REASON = 2i32;\npub const ScmPhysicalDeviceOpReason_Unknown: SCM_PD_OPERATIONAL_STATUS_REASON = 0i32;\npub const ScmPhysicalDeviceOpReason_WritePersistenceLossImminent: SCM_PD_OPERATIONAL_STATUS_REASON = 18i32;\npub const ScmPhysicalDeviceOpStatus_HardwareError: SCM_PD_OPERATIONAL_STATUS = 4i32;\npub const ScmPhysicalDeviceOpStatus_InService: SCM_PD_OPERATIONAL_STATUS = 3i32;\npub const ScmPhysicalDeviceOpStatus_Max: SCM_PD_OPERATIONAL_STATUS = 8i32;\npub const ScmPhysicalDeviceOpStatus_Missing: SCM_PD_OPERATIONAL_STATUS = 7i32;\npub const ScmPhysicalDeviceOpStatus_NotUsable: SCM_PD_OPERATIONAL_STATUS = 5i32;\npub const ScmPhysicalDeviceOpStatus_Ok: SCM_PD_OPERATIONAL_STATUS = 1i32;\npub const ScmPhysicalDeviceOpStatus_PredictingFailure: SCM_PD_OPERATIONAL_STATUS = 2i32;\npub const ScmPhysicalDeviceOpStatus_TransientError: SCM_PD_OPERATIONAL_STATUS = 6i32;\npub const ScmPhysicalDeviceOpStatus_Unknown: SCM_PD_OPERATIONAL_STATUS = 0i32;\npub const ScmPhysicalDeviceProperty_DeviceHandle: SCM_PD_PROPERTY_ID = 5i32;\npub const ScmPhysicalDeviceProperty_DeviceInfo: SCM_PD_PROPERTY_ID = 0i32;\npub const ScmPhysicalDeviceProperty_DeviceSpecificInfo: SCM_PD_PROPERTY_ID = 4i32;\npub const ScmPhysicalDeviceProperty_FirmwareInfo: SCM_PD_PROPERTY_ID = 2i32;\npub const ScmPhysicalDeviceProperty_FruIdString: SCM_PD_PROPERTY_ID = 6i32;\npub const ScmPhysicalDeviceProperty_LocationString: SCM_PD_PROPERTY_ID = 3i32;\npub const ScmPhysicalDeviceProperty_ManagementStatus: SCM_PD_PROPERTY_ID = 1i32;\npub const ScmPhysicalDeviceProperty_Max: SCM_PD_PROPERTY_ID = 9i32;\npub const ScmPhysicalDeviceProperty_RuntimeFwActivationArmState: SCM_PD_PROPERTY_ID = 8i32;\npub const ScmPhysicalDeviceProperty_RuntimeFwActivationInfo: SCM_PD_PROPERTY_ID = 7i32;\npub const ScmPhysicalDeviceQuery_Descriptor: SCM_PD_QUERY_TYPE = 0i32;\npub const ScmPhysicalDeviceQuery_IsSupported: SCM_PD_QUERY_TYPE = 1i32;\npub const ScmPhysicalDeviceQuery_Max: SCM_PD_QUERY_TYPE = 2i32;\npub const ScmPhysicalDeviceReinit_ColdBootNeeded: SCM_PD_MEDIA_REINITIALIZATION_STATUS = 2i32;\npub const ScmPhysicalDeviceReinit_Max: SCM_PD_MEDIA_REINITIALIZATION_STATUS = 3i32;\npub const ScmPhysicalDeviceReinit_RebootNeeded: SCM_PD_MEDIA_REINITIALIZATION_STATUS = 1i32;\npub const ScmPhysicalDeviceReinit_Success: SCM_PD_MEDIA_REINITIALIZATION_STATUS = 0i32;\npub const ScmPhysicalDeviceSet_Descriptor: SCM_PD_SET_TYPE = 0i32;\npub const ScmPhysicalDeviceSet_IsSupported: SCM_PD_SET_TYPE = 1i32;\npub const ScmPhysicalDeviceSet_Max: SCM_PD_SET_TYPE = 2i32;\npub const ScmRegionFlagLabel: SCM_REGION_FLAG = 1i32;\npub const ScmRegionFlagNone: SCM_REGION_FLAG = 0i32;\npub const ShrinkAbort: SHRINK_VOLUME_REQUEST_TYPES = 3i32;\npub const ShrinkCommit: SHRINK_VOLUME_REQUEST_TYPES = 2i32;\npub const ShrinkPrepare: SHRINK_VOLUME_REQUEST_TYPES = 1i32;\npub const SmrGcActionPause: REFS_SMR_VOLUME_GC_ACTION = 3i32;\npub const SmrGcActionStart: REFS_SMR_VOLUME_GC_ACTION = 1i32;\npub const SmrGcActionStartFullSpeed: REFS_SMR_VOLUME_GC_ACTION = 2i32;\npub const SmrGcActionStop: REFS_SMR_VOLUME_GC_ACTION = 4i32;\npub const SmrGcMethodCompaction: REFS_SMR_VOLUME_GC_METHOD = 1i32;\npub const SmrGcMethodCompression: REFS_SMR_VOLUME_GC_METHOD = 2i32;\npub const SmrGcMethodRotation: REFS_SMR_VOLUME_GC_METHOD = 3i32;\npub const SmrGcStateActive: REFS_SMR_VOLUME_GC_STATE = 2i32;\npub const SmrGcStateActiveFullSpeed: REFS_SMR_VOLUME_GC_STATE = 3i32;\npub const SmrGcStateInactive: REFS_SMR_VOLUME_GC_STATE = 0i32;\npub const SmrGcStatePaused: REFS_SMR_VOLUME_GC_STATE = 1i32;\npub const StorAttributeMgmt_ClearAttribute: STORAGE_ATTRIBUTE_MGMT_ACTION = 0i32;\npub const StorAttributeMgmt_ResetAttribute: STORAGE_ATTRIBUTE_MGMT_ACTION = 2i32;\npub const StorAttributeMgmt_SetAttribute: STORAGE_ATTRIBUTE_MGMT_ACTION = 1i32;\npub const StorRpmbAuthenticatedDeviceConfigRead: STORAGE_RPMB_COMMAND_TYPE = 7i32;\npub const StorRpmbAuthenticatedDeviceConfigWrite: STORAGE_RPMB_COMMAND_TYPE = 6i32;\npub const StorRpmbAuthenticatedRead: STORAGE_RPMB_COMMAND_TYPE = 4i32;\npub const StorRpmbAuthenticatedWrite: STORAGE_RPMB_COMMAND_TYPE = 3i32;\npub const StorRpmbProgramAuthKey: STORAGE_RPMB_COMMAND_TYPE = 1i32;\npub const StorRpmbQueryWriteCounter: STORAGE_RPMB_COMMAND_TYPE = 2i32;\npub const StorRpmbReadResultRequest: STORAGE_RPMB_COMMAND_TYPE = 5i32;\npub const StorageAccessAlignmentProperty: STORAGE_PROPERTY_ID = 6i32;\npub const StorageAdapterCryptoProperty: STORAGE_PROPERTY_ID = 17i32;\npub const StorageAdapterPhysicalTopologyProperty: STORAGE_PROPERTY_ID = 53i32;\npub const StorageAdapterProperty: STORAGE_PROPERTY_ID = 1i32;\npub const StorageAdapterProtocolSpecificProperty: STORAGE_PROPERTY_ID = 49i32;\npub const StorageAdapterRpmbProperty: STORAGE_PROPERTY_ID = 16i32;\npub const StorageAdapterSerialNumberProperty: STORAGE_PROPERTY_ID = 57i32;\npub const StorageAdapterTemperatureProperty: STORAGE_PROPERTY_ID = 51i32;\npub const StorageCounterTypeFlushLatency100NSMax: STORAGE_COUNTER_TYPE = 20i32;\npub const StorageCounterTypeLoadUnloadCycleCount: STORAGE_COUNTER_TYPE = 12i32;\npub const StorageCounterTypeLoadUnloadCycleCountMax: STORAGE_COUNTER_TYPE = 13i32;\npub const StorageCounterTypeManufactureDate: STORAGE_COUNTER_TYPE = 9i32;\npub const StorageCounterTypeMax: STORAGE_COUNTER_TYPE = 21i32;\npub const StorageCounterTypePowerOnHours: STORAGE_COUNTER_TYPE = 17i32;\npub const StorageCounterTypeReadErrorsCorrected: STORAGE_COUNTER_TYPE = 4i32;\npub const StorageCounterTypeReadErrorsTotal: STORAGE_COUNTER_TYPE = 3i32;\npub const StorageCounterTypeReadErrorsUncorrected: STORAGE_COUNTER_TYPE = 5i32;\npub const StorageCounterTypeReadLatency100NSMax: STORAGE_COUNTER_TYPE = 18i32;\npub const StorageCounterTypeStartStopCycleCount: STORAGE_COUNTER_TYPE = 10i32;\npub const StorageCounterTypeStartStopCycleCountMax: STORAGE_COUNTER_TYPE = 11i32;\npub const StorageCounterTypeTemperatureCelsius: STORAGE_COUNTER_TYPE = 1i32;\npub const StorageCounterTypeTemperatureCelsiusMax: STORAGE_COUNTER_TYPE = 2i32;\npub const StorageCounterTypeUnknown: STORAGE_COUNTER_TYPE = 0i32;\npub const StorageCounterTypeWearPercentage: STORAGE_COUNTER_TYPE = 14i32;\npub const StorageCounterTypeWearPercentageMax: STORAGE_COUNTER_TYPE = 16i32;\npub const StorageCounterTypeWearPercentageWarning: STORAGE_COUNTER_TYPE = 15i32;\npub const StorageCounterTypeWriteErrorsCorrected: STORAGE_COUNTER_TYPE = 7i32;\npub const StorageCounterTypeWriteErrorsTotal: STORAGE_COUNTER_TYPE = 6i32;\npub const StorageCounterTypeWriteErrorsUncorrected: STORAGE_COUNTER_TYPE = 8i32;\npub const StorageCounterTypeWriteLatency100NSMax: STORAGE_COUNTER_TYPE = 19i32;\npub const StorageCryptoAlgorithmAESECB: STORAGE_CRYPTO_ALGORITHM_ID = 3i32;\npub const StorageCryptoAlgorithmBitlockerAESCBC: STORAGE_CRYPTO_ALGORITHM_ID = 2i32;\npub const StorageCryptoAlgorithmESSIVAESCBC: STORAGE_CRYPTO_ALGORITHM_ID = 4i32;\npub const StorageCryptoAlgorithmMax: STORAGE_CRYPTO_ALGORITHM_ID = 5i32;\npub const StorageCryptoAlgorithmUnknown: STORAGE_CRYPTO_ALGORITHM_ID = 0i32;\npub const StorageCryptoAlgorithmXTSAES: STORAGE_CRYPTO_ALGORITHM_ID = 1i32;\npub const StorageCryptoKeySize128Bits: STORAGE_CRYPTO_KEY_SIZE = 1i32;\npub const StorageCryptoKeySize192Bits: STORAGE_CRYPTO_KEY_SIZE = 2i32;\npub const StorageCryptoKeySize256Bits: STORAGE_CRYPTO_KEY_SIZE = 3i32;\npub const StorageCryptoKeySize512Bits: STORAGE_CRYPTO_KEY_SIZE = 4i32;\npub const StorageCryptoKeySizeUnknown: STORAGE_CRYPTO_KEY_SIZE = 0i32;\npub const StorageDeviceAttributesProperty: STORAGE_PROPERTY_ID = 55i32;\npub const StorageDeviceCopyOffloadProperty: STORAGE_PROPERTY_ID = 13i32;\npub const StorageDeviceDeviceTelemetryProperty: STORAGE_PROPERTY_ID = 10i32;\npub const StorageDeviceEnduranceProperty: STORAGE_PROPERTY_ID = 62i32;\npub const StorageDeviceIdProperty: STORAGE_PROPERTY_ID = 2i32;\npub const StorageDeviceIoCapabilityProperty: STORAGE_PROPERTY_ID = 48i32;\npub const StorageDeviceLBProvisioningProperty: STORAGE_PROPERTY_ID = 11i32;\npub const StorageDeviceLedStateProperty: STORAGE_PROPERTY_ID = 63i32;\npub const StorageDeviceLocationProperty: STORAGE_PROPERTY_ID = 58i32;\npub const StorageDeviceManagementStatus: STORAGE_PROPERTY_ID = 56i32;\npub const StorageDeviceMediumProductType: STORAGE_PROPERTY_ID = 15i32;\npub const StorageDeviceNumaProperty: STORAGE_PROPERTY_ID = 59i32;\npub const StorageDevicePhysicalTopologyProperty: STORAGE_PROPERTY_ID = 54i32;\npub const StorageDevicePowerCapUnitsMilliwatts: STORAGE_DEVICE_POWER_CAP_UNITS = 1i32;\npub const StorageDevicePowerCapUnitsPercent: STORAGE_DEVICE_POWER_CAP_UNITS = 0i32;\npub const StorageDevicePowerProperty: STORAGE_PROPERTY_ID = 12i32;\npub const StorageDeviceProperty: STORAGE_PROPERTY_ID = 0i32;\npub const StorageDeviceProtocolSpecificProperty: STORAGE_PROPERTY_ID = 50i32;\npub const StorageDeviceResiliencyProperty: STORAGE_PROPERTY_ID = 14i32;\npub const StorageDeviceSeekPenaltyProperty: STORAGE_PROPERTY_ID = 7i32;\npub const StorageDeviceSelfEncryptionProperty: STORAGE_PROPERTY_ID = 64i32;\npub const StorageDeviceTemperatureProperty: STORAGE_PROPERTY_ID = 52i32;\npub const StorageDeviceTrimProperty: STORAGE_PROPERTY_ID = 8i32;\npub const StorageDeviceUniqueIdProperty: STORAGE_PROPERTY_ID = 3i32;\npub const StorageDeviceUnsafeShutdownCount: STORAGE_PROPERTY_ID = 61i32;\npub const StorageDeviceWriteAggregationProperty: STORAGE_PROPERTY_ID = 9i32;\npub const StorageDeviceWriteCacheProperty: STORAGE_PROPERTY_ID = 4i32;\npub const StorageDeviceZonedDeviceProperty: STORAGE_PROPERTY_ID = 60i32;\npub const StorageDiagnosticLevelDefault: STORAGE_DIAGNOSTIC_LEVEL = 0i32;\npub const StorageDiagnosticLevelMax: STORAGE_DIAGNOSTIC_LEVEL = 1i32;\npub const StorageDiagnosticTargetTypeHbaFirmware: STORAGE_DIAGNOSTIC_TARGET_TYPE = 3i32;\npub const StorageDiagnosticTargetTypeMax: STORAGE_DIAGNOSTIC_TARGET_TYPE = 4i32;\npub const StorageDiagnosticTargetTypeMiniport: STORAGE_DIAGNOSTIC_TARGET_TYPE = 2i32;\npub const StorageDiagnosticTargetTypePort: STORAGE_DIAGNOSTIC_TARGET_TYPE = 1i32;\npub const StorageDiagnosticTargetTypeUndefined: STORAGE_DIAGNOSTIC_TARGET_TYPE = 0i32;\npub const StorageEncryptionTypeEDrive: STORAGE_ENCRYPTION_TYPE = 1i32;\npub const StorageEncryptionTypeTcgOpal: STORAGE_ENCRYPTION_TYPE = 2i32;\npub const StorageEncryptionTypeUnknown: STORAGE_ENCRYPTION_TYPE = 0i32;\npub const StorageFruIdProperty: STORAGE_PROPERTY_ID = 65i32;\npub const StorageIdAssocDevice: STORAGE_ASSOCIATION_TYPE = 0i32;\npub const StorageIdAssocPort: STORAGE_ASSOCIATION_TYPE = 1i32;\npub const StorageIdAssocTarget: STORAGE_ASSOCIATION_TYPE = 2i32;\npub const StorageIdCodeSetAscii: STORAGE_IDENTIFIER_CODE_SET = 2i32;\npub const StorageIdCodeSetBinary: STORAGE_IDENTIFIER_CODE_SET = 1i32;\npub const StorageIdCodeSetReserved: STORAGE_IDENTIFIER_CODE_SET = 0i32;\npub const StorageIdCodeSetUtf8: STORAGE_IDENTIFIER_CODE_SET = 3i32;\npub const StorageIdNAAFormatIEEEERegisteredExtended: STORAGE_ID_NAA_FORMAT = 5i32;\npub const StorageIdNAAFormatIEEEExtended: STORAGE_ID_NAA_FORMAT = 2i32;\npub const StorageIdNAAFormatIEEERegistered: STORAGE_ID_NAA_FORMAT = 3i32;\npub const StorageIdTypeEUI64: STORAGE_IDENTIFIER_TYPE = 2i32;\npub const StorageIdTypeFCPHName: STORAGE_IDENTIFIER_TYPE = 3i32;\npub const StorageIdTypeLogicalUnitGroup: STORAGE_IDENTIFIER_TYPE = 6i32;\npub const StorageIdTypeMD5LogicalUnitIdentifier: STORAGE_IDENTIFIER_TYPE = 7i32;\npub const StorageIdTypePortRelative: STORAGE_IDENTIFIER_TYPE = 4i32;\npub const StorageIdTypeScsiNameString: STORAGE_IDENTIFIER_TYPE = 8i32;\npub const StorageIdTypeTargetPortGroup: STORAGE_IDENTIFIER_TYPE = 5i32;\npub const StorageIdTypeVendorId: STORAGE_IDENTIFIER_TYPE = 1i32;\npub const StorageIdTypeVendorSpecific: STORAGE_IDENTIFIER_TYPE = 0i32;\npub const StorageMiniportProperty: STORAGE_PROPERTY_ID = 5i32;\npub const StoragePortCodeSetATAport: STORAGE_PORT_CODE_SET = 4i32;\npub const StoragePortCodeSetReserved: STORAGE_PORT_CODE_SET = 0i32;\npub const StoragePortCodeSetSBP2port: STORAGE_PORT_CODE_SET = 6i32;\npub const StoragePortCodeSetSCSIport: STORAGE_PORT_CODE_SET = 2i32;\npub const StoragePortCodeSetSDport: STORAGE_PORT_CODE_SET = 7i32;\npub const StoragePortCodeSetSpaceport: STORAGE_PORT_CODE_SET = 3i32;\npub const StoragePortCodeSetStorport: STORAGE_PORT_CODE_SET = 1i32;\npub const StoragePortCodeSetUSBport: STORAGE_PORT_CODE_SET = 5i32;\npub const StoragePowerupDeviceAttention: STORAGE_POWERUP_REASON_TYPE = 2i32;\npub const StoragePowerupIO: STORAGE_POWERUP_REASON_TYPE = 1i32;\npub const StoragePowerupUnknown: STORAGE_POWERUP_REASON_TYPE = 0i32;\npub const StorageReserveIdHard: STORAGE_RESERVE_ID = 1i32;\npub const StorageReserveIdMax: STORAGE_RESERVE_ID = 4i32;\npub const StorageReserveIdNone: STORAGE_RESERVE_ID = 0i32;\npub const StorageReserveIdSoft: STORAGE_RESERVE_ID = 2i32;\npub const StorageReserveIdUpdateScratch: STORAGE_RESERVE_ID = 3i32;\npub const StorageRpmbFrameTypeMax: STORAGE_RPMB_FRAME_TYPE = 2i32;\npub const StorageRpmbFrameTypeStandard: STORAGE_RPMB_FRAME_TYPE = 1i32;\npub const StorageRpmbFrameTypeUnknown: STORAGE_RPMB_FRAME_TYPE = 0i32;\npub const StorageSanitizeMethodBlockErase: STORAGE_SANITIZE_METHOD = 1i32;\npub const StorageSanitizeMethodCryptoErase: STORAGE_SANITIZE_METHOD = 2i32;\npub const StorageSanitizeMethodDefault: STORAGE_SANITIZE_METHOD = 0i32;\npub const StorageTierClassCapacity: STORAGE_TIER_CLASS = 1i32;\npub const StorageTierClassMax: STORAGE_TIER_CLASS = 3i32;\npub const StorageTierClassPerformance: STORAGE_TIER_CLASS = 2i32;\npub const StorageTierClassUnspecified: STORAGE_TIER_CLASS = 0i32;\npub const StorageTierMediaTypeDisk: STORAGE_TIER_MEDIA_TYPE = 1i32;\npub const StorageTierMediaTypeMax: STORAGE_TIER_MEDIA_TYPE = 5i32;\npub const StorageTierMediaTypeScm: STORAGE_TIER_MEDIA_TYPE = 4i32;\npub const StorageTierMediaTypeSsd: STORAGE_TIER_MEDIA_TYPE = 2i32;\npub const StorageTierMediaTypeUnspecified: STORAGE_TIER_MEDIA_TYPE = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TAPE_GET_STATISTICS {\n    pub Operation: u32,\n}\npub const TAPE_RESET_STATISTICS: i32 = 2i32;\npub const TAPE_RETURN_ENV_INFO: i32 = 1i32;\npub const TAPE_RETURN_STATISTICS: i32 = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TAPE_STATISTICS {\n    pub Version: u32,\n    pub Flags: u32,\n    pub RecoveredWrites: i64,\n    pub UnrecoveredWrites: i64,\n    pub RecoveredReads: i64,\n    pub UnrecoveredReads: i64,\n    pub CompressionRatioReads: u8,\n    pub CompressionRatioWrites: u8,\n}\npub const TCCollectionApplicationRequested: DEVICEDUMP_COLLECTION_TYPEIDE_NOTIFICATION_TYPE = 2i32;\npub const TCCollectionBugCheck: DEVICEDUMP_COLLECTION_TYPEIDE_NOTIFICATION_TYPE = 1i32;\npub const TCCollectionDeviceRequested: DEVICEDUMP_COLLECTION_TYPEIDE_NOTIFICATION_TYPE = 3i32;\npub const TC_DEVICEDUMP_SUBSECTION_DESC_LENGTH: u32 = 16u32;\npub const TC_PUBLIC_DATA_TYPE_ATAGP: windows_sys::core::PCSTR = windows_sys::core::s!(\"ATAGPLogPages\");\npub const TC_PUBLIC_DATA_TYPE_ATASMART: windows_sys::core::PCSTR = windows_sys::core::s!(\"ATASMARTPages\");\npub const TC_PUBLIC_DEVICEDUMP_CONTENT_GPLOG: u32 = 2u32;\npub const TC_PUBLIC_DEVICEDUMP_CONTENT_GPLOG_MAX: u32 = 16u32;\npub const TC_PUBLIC_DEVICEDUMP_CONTENT_SMART: u32 = 1u32;\npub const TELEMETRY_COMMAND_SIZE: u32 = 16u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_CREATE_MINIVERSION_INFO {\n    pub StructureVersion: u16,\n    pub StructureLength: u16,\n    pub BaseVersion: u32,\n    pub MiniVersion: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_GET_METADATA_INFO_OUT {\n    pub TxfFileId: TXFS_GET_METADATA_INFO_OUT_0,\n    pub LockingTransaction: windows_sys::core::GUID,\n    pub LastLsn: u64,\n    pub TransactionState: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_GET_METADATA_INFO_OUT_0 {\n    pub LowPart: i64,\n    pub HighPart: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_GET_TRANSACTED_VERSION {\n    pub ThisBaseVersion: u32,\n    pub LatestVersion: u32,\n    pub ThisMiniVersion: u16,\n    pub FirstMiniVersion: u16,\n    pub LatestMiniVersion: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_LIST_TRANSACTIONS {\n    pub NumberOfTransactions: u64,\n    pub BufferSizeRequired: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_LIST_TRANSACTIONS_ENTRY {\n    pub TransactionId: windows_sys::core::GUID,\n    pub TransactionState: u32,\n    pub Reserved1: u32,\n    pub Reserved2: u32,\n    pub Reserved3: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_LIST_TRANSACTION_LOCKED_FILES {\n    pub KtmTransaction: windows_sys::core::GUID,\n    pub NumberOfFiles: u64,\n    pub BufferSizeRequired: u64,\n    pub Offset: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY {\n    pub Offset: u64,\n    pub NameFlags: u32,\n    pub FileId: i64,\n    pub Reserved1: u32,\n    pub Reserved2: u32,\n    pub Reserved3: i64,\n    pub FileName: [u16; 1],\n}\nimpl Default for TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY_FLAG_CREATED: u32 = 1u32;\npub const TXFS_LIST_TRANSACTION_LOCKED_FILES_ENTRY_FLAG_DELETED: u32 = 2u32;\npub const TXFS_LOGGING_MODE_FULL: u32 = 2u32;\npub const TXFS_LOGGING_MODE_SIMPLE: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_MODIFY_RM {\n    pub Flags: TXFS_RMF_LAGS,\n    pub LogContainerCountMax: u32,\n    pub LogContainerCountMin: u32,\n    pub LogContainerCount: u32,\n    pub LogGrowthIncrement: u32,\n    pub LogAutoShrinkPercentage: u32,\n    pub Reserved: u64,\n    pub LoggingMode: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_QUERY_RM_INFORMATION {\n    pub BytesRequired: u32,\n    pub TailLsn: u64,\n    pub CurrentLsn: u64,\n    pub ArchiveTailLsn: u64,\n    pub LogContainerSize: u64,\n    pub HighestVirtualClock: i64,\n    pub LogContainerCount: u32,\n    pub LogContainerCountMax: u32,\n    pub LogContainerCountMin: u32,\n    pub LogGrowthIncrement: u32,\n    pub LogAutoShrinkPercentage: u32,\n    pub Flags: TXFS_RMF_LAGS,\n    pub LoggingMode: u16,\n    pub Reserved: u16,\n    pub RmState: u32,\n    pub LogCapacity: u64,\n    pub LogFree: u64,\n    pub TopsSize: u64,\n    pub TopsUsed: u64,\n    pub TransactionCount: u64,\n    pub OnePCCount: u64,\n    pub TwoPCCount: u64,\n    pub NumberLogFileFull: u64,\n    pub OldestTransactionAge: u64,\n    pub RMName: windows_sys::core::GUID,\n    pub TmLogPathOffset: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TXFS_READ_BACKUP_INFORMATION_OUT {\n    pub Anonymous: TXFS_READ_BACKUP_INFORMATION_OUT_0,\n}\nimpl Default for TXFS_READ_BACKUP_INFORMATION_OUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union TXFS_READ_BACKUP_INFORMATION_OUT_0 {\n    pub BufferLength: u32,\n    pub Buffer: [u8; 1],\n}\nimpl Default for TXFS_READ_BACKUP_INFORMATION_OUT_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type TXFS_RMF_LAGS = u32;\npub const TXFS_RM_FLAG_DO_NOT_RESET_RM_AT_NEXT_START: TXFS_RMF_LAGS = 32768u32;\npub const TXFS_RM_FLAG_ENFORCE_MINIMUM_SIZE: TXFS_RMF_LAGS = 4096u32;\npub const TXFS_RM_FLAG_GROW_LOG: TXFS_RMF_LAGS = 1024u32;\npub const TXFS_RM_FLAG_LOGGING_MODE: TXFS_RMF_LAGS = 1u32;\npub const TXFS_RM_FLAG_LOG_AUTO_SHRINK_PERCENTAGE: TXFS_RMF_LAGS = 64u32;\npub const TXFS_RM_FLAG_LOG_CONTAINER_COUNT_MAX: TXFS_RMF_LAGS = 4u32;\npub const TXFS_RM_FLAG_LOG_CONTAINER_COUNT_MIN: TXFS_RMF_LAGS = 8u32;\npub const TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_NUM_CONTAINERS: TXFS_RMF_LAGS = 16u32;\npub const TXFS_RM_FLAG_LOG_GROWTH_INCREMENT_PERCENT: TXFS_RMF_LAGS = 32u32;\npub const TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX: TXFS_RMF_LAGS = 128u32;\npub const TXFS_RM_FLAG_LOG_NO_CONTAINER_COUNT_MIN: TXFS_RMF_LAGS = 256u32;\npub const TXFS_RM_FLAG_PREFER_AVAILABILITY: TXFS_RMF_LAGS = 131072u32;\npub const TXFS_RM_FLAG_PREFER_CONSISTENCY: TXFS_RMF_LAGS = 65536u32;\npub const TXFS_RM_FLAG_PRESERVE_CHANGES: TXFS_RMF_LAGS = 8192u32;\npub const TXFS_RM_FLAG_RENAME_RM: TXFS_RMF_LAGS = 2u32;\npub const TXFS_RM_FLAG_RESET_RM_AT_NEXT_START: TXFS_RMF_LAGS = 16384u32;\npub const TXFS_RM_FLAG_SHRINK_LOG: TXFS_RMF_LAGS = 2048u32;\npub const TXFS_RM_STATE_ACTIVE: u32 = 2u32;\npub const TXFS_RM_STATE_NOT_STARTED: u32 = 0u32;\npub const TXFS_RM_STATE_SHUTTING_DOWN: u32 = 3u32;\npub const TXFS_RM_STATE_STARTING: u32 = 1u32;\npub const TXFS_ROLLFORWARD_REDO_FLAG_USE_LAST_REDO_LSN: u32 = 1u32;\npub const TXFS_ROLLFORWARD_REDO_FLAG_USE_LAST_VIRTUAL_CLOCK: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_ROLLFORWARD_REDO_INFORMATION {\n    pub LastVirtualClock: i64,\n    pub LastRedoLsn: u64,\n    pub HighestRecoveryLsn: u64,\n    pub Flags: u32,\n}\npub const TXFS_SAVEPOINT_CLEAR: u32 = 4u32;\npub const TXFS_SAVEPOINT_CLEAR_ALL: u32 = 16u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TXFS_SAVEPOINT_INFORMATION {\n    pub KtmTransaction: super::super::Foundation::HANDLE,\n    pub ActionCode: u32,\n    pub SavepointId: u32,\n}\nimpl Default for TXFS_SAVEPOINT_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const TXFS_SAVEPOINT_ROLLBACK: u32 = 2u32;\npub const TXFS_SAVEPOINT_SET: u32 = 1u32;\npub const TXFS_START_RM_FLAG_LOGGING_MODE: u32 = 1024u32;\npub const TXFS_START_RM_FLAG_LOG_AUTO_SHRINK_PERCENTAGE: u32 = 32u32;\npub const TXFS_START_RM_FLAG_LOG_CONTAINER_COUNT_MAX: u32 = 1u32;\npub const TXFS_START_RM_FLAG_LOG_CONTAINER_COUNT_MIN: u32 = 2u32;\npub const TXFS_START_RM_FLAG_LOG_CONTAINER_SIZE: u32 = 4u32;\npub const TXFS_START_RM_FLAG_LOG_GROWTH_INCREMENT_NUM_CONTAINERS: u32 = 8u32;\npub const TXFS_START_RM_FLAG_LOG_GROWTH_INCREMENT_PERCENT: u32 = 16u32;\npub const TXFS_START_RM_FLAG_LOG_NO_CONTAINER_COUNT_MAX: u32 = 64u32;\npub const TXFS_START_RM_FLAG_LOG_NO_CONTAINER_COUNT_MIN: u32 = 128u32;\npub const TXFS_START_RM_FLAG_PREFER_AVAILABILITY: u32 = 8192u32;\npub const TXFS_START_RM_FLAG_PREFER_CONSISTENCY: u32 = 4096u32;\npub const TXFS_START_RM_FLAG_PRESERVE_CHANGES: u32 = 2048u32;\npub const TXFS_START_RM_FLAG_RECOVER_BEST_EFFORT: u32 = 512u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TXFS_START_RM_INFORMATION {\n    pub Flags: u32,\n    pub LogContainerSize: u64,\n    pub LogContainerCountMin: u32,\n    pub LogContainerCountMax: u32,\n    pub LogGrowthIncrement: u32,\n    pub LogAutoShrinkPercentage: u32,\n    pub TmLogPathOffset: u32,\n    pub TmLogPathLength: u16,\n    pub LoggingMode: u16,\n    pub LogPathLength: u16,\n    pub Reserved: u16,\n    pub LogPath: [u16; 1],\n}\nimpl Default for TXFS_START_RM_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const TXFS_TRANSACTED_VERSION_NONTRANSACTED: u32 = 4294967294u32;\npub const TXFS_TRANSACTED_VERSION_UNCOMMITTED: u32 = 4294967295u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TXFS_TRANSACTION_ACTIVE_INFO {\n    pub TransactionsActiveAtSnapshot: bool,\n}\npub const TXFS_TRANSACTION_STATE_ACTIVE: u32 = 1u32;\npub const TXFS_TRANSACTION_STATE_NONE: u32 = 0u32;\npub const TXFS_TRANSACTION_STATE_NOTACTIVE: u32 = 3u32;\npub const TXFS_TRANSACTION_STATE_PREPARED: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TXFS_WRITE_BACKUP_INFORMATION {\n    pub Buffer: [u8; 1],\n}\nimpl Default for TXFS_WRITE_BACKUP_INFORMATION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const Travan: STORAGE_MEDIA_TYPE = 34i32;\npub const UNDEFINE_ALTERNATE: u32 = 13u32;\npub const UNDEFINE_PRIMARY: u32 = 12u32;\npub const UNLOCK_ELEMENT: u32 = 1u32;\npub const UNRECOVERED_READS_VALID: u32 = 8u32;\npub const UNRECOVERED_WRITES_VALID: u32 = 2u32;\npub type USN_DELETE_FLAGS = u32;\npub const USN_DELETE_FLAG_DELETE: USN_DELETE_FLAGS = 1u32;\npub const USN_DELETE_FLAG_NOTIFY: USN_DELETE_FLAGS = 2u32;\npub const USN_DELETE_VALID_FLAGS: u32 = 3u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct USN_JOURNAL_DATA_V0 {\n    pub UsnJournalID: u64,\n    pub FirstUsn: i64,\n    pub NextUsn: i64,\n    pub LowestValidUsn: i64,\n    pub MaxUsn: i64,\n    pub MaximumSize: u64,\n    pub AllocationDelta: u64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct USN_JOURNAL_DATA_V1 {\n    pub UsnJournalID: u64,\n    pub FirstUsn: i64,\n    pub NextUsn: i64,\n    pub LowestValidUsn: i64,\n    pub MaxUsn: i64,\n    pub MaximumSize: u64,\n    pub AllocationDelta: u64,\n    pub MinSupportedMajorVersion: u16,\n    pub MaxSupportedMajorVersion: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct USN_JOURNAL_DATA_V2 {\n    pub UsnJournalID: u64,\n    pub FirstUsn: i64,\n    pub NextUsn: i64,\n    pub LowestValidUsn: i64,\n    pub MaxUsn: i64,\n    pub MaximumSize: u64,\n    pub AllocationDelta: u64,\n    pub MinSupportedMajorVersion: u16,\n    pub MaxSupportedMajorVersion: u16,\n    pub Flags: u32,\n    pub RangeTrackChunkSize: u64,\n    pub RangeTrackFileSizeThreshold: i64,\n}\npub const USN_PAGE_SIZE: u32 = 4096u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct USN_RANGE_TRACK_OUTPUT {\n    pub Usn: i64,\n}\npub const USN_REASON_BASIC_INFO_CHANGE: u32 = 32768u32;\npub const USN_REASON_CLOSE: u32 = 2147483648u32;\npub const USN_REASON_COMPRESSION_CHANGE: u32 = 131072u32;\npub const USN_REASON_DATA_EXTEND: u32 = 2u32;\npub const USN_REASON_DATA_OVERWRITE: u32 = 1u32;\npub const USN_REASON_DATA_TRUNCATION: u32 = 4u32;\npub const USN_REASON_DESIRED_STORAGE_CLASS_CHANGE: u32 = 16777216u32;\npub const USN_REASON_EA_CHANGE: u32 = 1024u32;\npub const USN_REASON_ENCRYPTION_CHANGE: u32 = 262144u32;\npub const USN_REASON_FILE_CREATE: u32 = 256u32;\npub const USN_REASON_FILE_DELETE: u32 = 512u32;\npub const USN_REASON_HARD_LINK_CHANGE: u32 = 65536u32;\npub const USN_REASON_INDEXABLE_CHANGE: u32 = 16384u32;\npub const USN_REASON_INTEGRITY_CHANGE: u32 = 8388608u32;\npub const USN_REASON_NAMED_DATA_EXTEND: u32 = 32u32;\npub const USN_REASON_NAMED_DATA_OVERWRITE: u32 = 16u32;\npub const USN_REASON_NAMED_DATA_TRUNCATION: u32 = 64u32;\npub const USN_REASON_OBJECT_ID_CHANGE: u32 = 524288u32;\npub const USN_REASON_RENAME_NEW_NAME: u32 = 8192u32;\npub const USN_REASON_RENAME_OLD_NAME: u32 = 4096u32;\npub const USN_REASON_REPARSE_POINT_CHANGE: u32 = 1048576u32;\npub const USN_REASON_SECURITY_CHANGE: u32 = 2048u32;\npub const USN_REASON_STREAM_CHANGE: u32 = 2097152u32;\npub const USN_REASON_TRANSACTED_CHANGE: u32 = 4194304u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct USN_RECORD_COMMON_HEADER {\n    pub RecordLength: u32,\n    pub MajorVersion: u16,\n    pub MinorVersion: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct USN_RECORD_EXTENT {\n    pub Offset: i64,\n    pub Length: i64,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy)]\npub union USN_RECORD_UNION {\n    pub Header: USN_RECORD_COMMON_HEADER,\n    pub V2: USN_RECORD_V2,\n    pub V3: USN_RECORD_V3,\n    pub V4: USN_RECORD_V4,\n}\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\nimpl Default for USN_RECORD_UNION {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct USN_RECORD_V2 {\n    pub RecordLength: u32,\n    pub MajorVersion: u16,\n    pub MinorVersion: u16,\n    pub FileReferenceNumber: u64,\n    pub ParentFileReferenceNumber: u64,\n    pub Usn: i64,\n    pub TimeStamp: i64,\n    pub Reason: u32,\n    pub SourceInfo: u32,\n    pub SecurityId: u32,\n    pub FileAttributes: u32,\n    pub FileNameLength: u16,\n    pub FileNameOffset: u16,\n    pub FileName: [u16; 1],\n}\nimpl Default for USN_RECORD_V2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy)]\npub struct USN_RECORD_V3 {\n    pub RecordLength: u32,\n    pub MajorVersion: u16,\n    pub MinorVersion: u16,\n    pub FileReferenceNumber: super::super::Storage::FileSystem::FILE_ID_128,\n    pub ParentFileReferenceNumber: super::super::Storage::FileSystem::FILE_ID_128,\n    pub Usn: i64,\n    pub TimeStamp: i64,\n    pub Reason: u32,\n    pub SourceInfo: u32,\n    pub SecurityId: u32,\n    pub FileAttributes: u32,\n    pub FileNameLength: u16,\n    pub FileNameOffset: u16,\n    pub FileName: [u16; 1],\n}\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\nimpl Default for USN_RECORD_V3 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy)]\npub struct USN_RECORD_V4 {\n    pub Header: USN_RECORD_COMMON_HEADER,\n    pub FileReferenceNumber: super::super::Storage::FileSystem::FILE_ID_128,\n    pub ParentFileReferenceNumber: super::super::Storage::FileSystem::FILE_ID_128,\n    pub Usn: i64,\n    pub Reason: u32,\n    pub SourceInfo: USN_SOURCE_INFO_ID,\n    pub RemainingExtents: u32,\n    pub NumberOfExtents: u16,\n    pub ExtentSize: u16,\n    pub Extents: [USN_RECORD_EXTENT; 1],\n}\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\nimpl Default for USN_RECORD_V4 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const USN_SOURCE_AUXILIARY_DATA: USN_SOURCE_INFO_ID = 2u32;\npub const USN_SOURCE_CLIENT_REPLICATION_MANAGEMENT: USN_SOURCE_INFO_ID = 8u32;\npub const USN_SOURCE_DATA_MANAGEMENT: USN_SOURCE_INFO_ID = 1u32;\npub type USN_SOURCE_INFO_ID = u32;\npub const USN_SOURCE_REPLICATION_MANAGEMENT: USN_SOURCE_INFO_ID = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct USN_TRACK_MODIFIED_RANGES {\n    pub Flags: u32,\n    pub Unused: u32,\n    pub ChunkSize: u64,\n    pub FileSizeThreshold: i64,\n}\npub const UfsDataTypeMax: STORAGE_PROTOCOL_UFS_DATA_TYPE = 6i32;\npub const UfsDataTypeQueryAttribute: STORAGE_PROTOCOL_UFS_DATA_TYPE = 2i32;\npub const UfsDataTypeQueryDescriptor: STORAGE_PROTOCOL_UFS_DATA_TYPE = 1i32;\npub const UfsDataTypeQueryDmeAttribute: STORAGE_PROTOCOL_UFS_DATA_TYPE = 4i32;\npub const UfsDataTypeQueryDmePeerAttribute: STORAGE_PROTOCOL_UFS_DATA_TYPE = 5i32;\npub const UfsDataTypeQueryFlag: STORAGE_PROTOCOL_UFS_DATA_TYPE = 3i32;\npub const UfsDataTypeUnknown: STORAGE_PROTOCOL_UFS_DATA_TYPE = 0i32;\npub const Unknown: MEDIA_TYPE = 0i32;\npub const VALID_NTFT: u32 = 192u32;\npub const VENDOR_ID_LENGTH: u32 = 8u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VERIFY_INFORMATION {\n    pub StartingOffset: i64,\n    pub Length: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VIRTUALIZATION_INSTANCE_INFO_INPUT {\n    pub NumberOfWorkerThreads: u32,\n    pub Flags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VIRTUALIZATION_INSTANCE_INFO_INPUT_EX {\n    pub HeaderSize: u16,\n    pub Flags: u32,\n    pub NotificationInfoSize: u32,\n    pub NotificationInfoOffset: u16,\n    pub ProviderMajorVersion: u16,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VIRTUALIZATION_INSTANCE_INFO_OUTPUT {\n    pub VirtualizationInstanceID: windows_sys::core::GUID,\n}\npub type VIRTUAL_STORAGE_BEHAVIOR_CODE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VIRTUAL_STORAGE_SET_BEHAVIOR_INPUT {\n    pub Size: u32,\n    pub BehaviorCode: VIRTUAL_STORAGE_BEHAVIOR_CODE,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct VOLUME_BITMAP_BUFFER {\n    pub StartingLcn: i64,\n    pub BitmapSize: i64,\n    pub Buffer: [u8; 1],\n}\nimpl Default for VOLUME_BITMAP_BUFFER {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct VOLUME_DISK_EXTENTS {\n    pub NumberOfDiskExtents: u32,\n    pub Extents: [DISK_EXTENT; 1],\n}\nimpl Default for VOLUME_DISK_EXTENTS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct VOLUME_GET_GPT_ATTRIBUTES_INFORMATION {\n    pub GptAttributes: u64,\n}\npub const VOLUME_IS_DIRTY: u32 = 1u32;\npub const VOLUME_SESSION_OPEN: u32 = 4u32;\npub const VOLUME_UPGRADE_SCHEDULED: u32 = 2u32;\npub const VXATape: STORAGE_MEDIA_TYPE = 94i32;\npub const VXATape_1: STORAGE_MEDIA_TYPE = 83i32;\npub const VXATape_2: STORAGE_MEDIA_TYPE = 84i32;\npub const VirtualStorageBehaviorCacheWriteBack: VIRTUAL_STORAGE_BEHAVIOR_CODE = 2i32;\npub const VirtualStorageBehaviorCacheWriteThrough: VIRTUAL_STORAGE_BEHAVIOR_CODE = 1i32;\npub const VirtualStorageBehaviorRestartIoProcessing: VIRTUAL_STORAGE_BEHAVIOR_CODE = 4i32;\npub const VirtualStorageBehaviorStopIoProcessing: VIRTUAL_STORAGE_BEHAVIOR_CODE = 3i32;\npub const VirtualStorageBehaviorUndefined: VIRTUAL_STORAGE_BEHAVIOR_CODE = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WIM_PROVIDER_ADD_OVERLAY_INPUT {\n    pub WimType: u32,\n    pub WimIndex: u32,\n    pub WimFileNameOffset: u32,\n    pub WimFileNameLength: u32,\n}\npub const WIM_PROVIDER_CURRENT_VERSION: u32 = 1u32;\npub const WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE: u32 = 1u32;\npub const WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct WIM_PROVIDER_EXTERNAL_INFO {\n    pub Version: u32,\n    pub Flags: u32,\n    pub DataSourceId: i64,\n    pub ResourceHash: [u8; 20],\n}\nimpl Default for WIM_PROVIDER_EXTERNAL_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WIM_PROVIDER_OVERLAY_ENTRY {\n    pub NextEntryOffset: u32,\n    pub DataSourceId: i64,\n    pub WimGuid: windows_sys::core::GUID,\n    pub WimFileNameOffset: u32,\n    pub WimType: u32,\n    pub WimIndex: u32,\n    pub Flags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WIM_PROVIDER_REMOVE_OVERLAY_INPUT {\n    pub DataSourceId: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WIM_PROVIDER_SUSPEND_OVERLAY_INPUT {\n    pub DataSourceId: i64,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WIM_PROVIDER_UPDATE_OVERLAY_INPUT {\n    pub DataSourceId: i64,\n    pub WimFileNameOffset: u32,\n    pub WimFileNameLength: u32,\n}\npub const WMI_DISK_GEOMETRY_GUID: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x25007f51_57c2_11d1_a528_00a0c9062910);\npub const WOF_CURRENT_VERSION: u32 = 1u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Storage_FileSystem\")]\n#[derive(Clone, Copy, Default)]\npub struct WOF_EXTERNAL_FILE_ID {\n    pub FileId: super::super::Storage::FileSystem::FILE_ID_128,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WOF_EXTERNAL_INFO {\n    pub Version: u32,\n    pub Provider: u32,\n}\npub const WOF_PROVIDER_CLOUD: u32 = 3u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WOF_VERSION_INFO {\n    pub WofVersion: u32,\n}\npub type WRITE_CACHE_CHANGE = i32;\npub type WRITE_CACHE_ENABLE = i32;\npub type WRITE_CACHE_TYPE = i32;\npub const WRITE_COMPRESSION_INFO_VALID: u32 = 16u32;\npub type WRITE_THROUGH = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WRITE_USN_REASON_INPUT {\n    pub Flags: u32,\n    pub UsnReasonToWrite: u32,\n}\npub const WriteCacheChangeUnknown: WRITE_CACHE_CHANGE = 0i32;\npub const WriteCacheChangeable: WRITE_CACHE_CHANGE = 2i32;\npub const WriteCacheDisabled: WRITE_CACHE_ENABLE = 1i32;\npub const WriteCacheEnableUnknown: WRITE_CACHE_ENABLE = 0i32;\npub const WriteCacheEnabled: WRITE_CACHE_ENABLE = 2i32;\npub const WriteCacheNotChangeable: WRITE_CACHE_CHANGE = 1i32;\npub const WriteCacheTypeNone: WRITE_CACHE_TYPE = 1i32;\npub const WriteCacheTypeUnknown: WRITE_CACHE_TYPE = 0i32;\npub const WriteCacheTypeWriteBack: WRITE_CACHE_TYPE = 2i32;\npub const WriteCacheTypeWriteThrough: WRITE_CACHE_TYPE = 3i32;\npub const WriteThroughNotSupported: WRITE_THROUGH = 1i32;\npub const WriteThroughSupported: WRITE_THROUGH = 2i32;\npub const WriteThroughUnknown: WRITE_THROUGH = 0i32;\npub const ZoneConditionClosed: STORAGE_ZONE_CONDITION = 4i32;\npub const ZoneConditionConventional: STORAGE_ZONE_CONDITION = 0i32;\npub const ZoneConditionEmpty: STORAGE_ZONE_CONDITION = 1i32;\npub const ZoneConditionExplicitlyOpened: STORAGE_ZONE_CONDITION = 3i32;\npub const ZoneConditionFull: STORAGE_ZONE_CONDITION = 14i32;\npub const ZoneConditionImplicitlyOpened: STORAGE_ZONE_CONDITION = 2i32;\npub const ZoneConditionOffline: STORAGE_ZONE_CONDITION = 15i32;\npub const ZoneConditionReadOnly: STORAGE_ZONE_CONDITION = 13i32;\npub const ZoneTypeConventional: STORAGE_ZONE_TYPES = 1i32;\npub const ZoneTypeMax: STORAGE_ZONE_TYPES = 4i32;\npub const ZoneTypeSequentialWritePreferred: STORAGE_ZONE_TYPES = 3i32;\npub const ZoneTypeSequentialWriteRequired: STORAGE_ZONE_TYPES = 2i32;\npub const ZoneTypeUnknown: STORAGE_ZONE_TYPES = 0i32;\npub const ZonedDeviceTypeDeviceManaged: STORAGE_ZONED_DEVICE_TYPES = 3i32;\npub const ZonedDeviceTypeHostAware: STORAGE_ZONED_DEVICE_TYPES = 2i32;\npub const ZonedDeviceTypeHostManaged: STORAGE_ZONED_DEVICE_TYPES = 1i32;\npub const ZonedDeviceTypeUnknown: STORAGE_ZONED_DEVICE_TYPES = 0i32;\npub const ZonesAttributeTypeAndLengthMayDifferent: STORAGE_ZONES_ATTRIBUTES = 0i32;\npub const ZonesAttributeTypeMayDifferentLengthSame: STORAGE_ZONES_ATTRIBUTES = 3i32;\npub const ZonesAttributeTypeSameLastZoneLengthDifferent: STORAGE_ZONES_ATTRIBUTES = 2i32;\npub const ZonesAttributeTypeSameLengthSame: STORAGE_ZONES_ATTRIBUTES = 1i32;\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/UI/Controls/mod.rs",
      "sha256": "18cb49cd226a36bdd9b3541536537a3574944fd472a75829e6da6b193487f824",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "#[cfg(feature = \"Win32_UI_Controls_Dialogs\")]\npub mod Dialogs;\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn BeginBufferedAnimation(hwnd : super::super::Foundation:: HWND, hdctarget : super::super::Graphics::Gdi:: HDC, prctarget : *const super::super::Foundation:: RECT, dwformat : BP_BUFFERFORMAT, ppaintparams : *const BP_PAINTPARAMS, panimationparams : *const BP_ANIMATIONPARAMS, phdcfrom : *mut super::super::Graphics::Gdi:: HDC, phdcto : *mut super::super::Graphics::Gdi:: HDC) -> isize);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn BeginBufferedPaint(hdctarget : super::super::Graphics::Gdi:: HDC, prctarget : *const super::super::Foundation:: RECT, dwformat : BP_BUFFERFORMAT, ppaintparams : *const BP_PAINTPARAMS, phdc : *mut super::super::Graphics::Gdi:: HDC) -> isize);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn BeginPanningFeedback(hwnd : super::super::Foundation:: HWND) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn BufferedPaintClear(hbufferedpaint : isize, prc : *const super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn BufferedPaintInit() -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn BufferedPaintRenderAnimation(hwnd : super::super::Foundation:: HWND, hdctarget : super::super::Graphics::Gdi:: HDC) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn BufferedPaintSetAlpha(hbufferedpaint : isize, prc : *const super::super::Foundation:: RECT, alpha : u8) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn BufferedPaintStopAllAnimations(hwnd : super::super::Foundation:: HWND) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn BufferedPaintUnInit() -> windows_sys::core::HRESULT);\nwindows_link::link!(\"user32.dll\" \"system\" fn CheckDlgButton(hdlg : super::super::Foundation:: HWND, nidbutton : i32, ucheck : DLG_BUTTON_CHECK_STATE) -> windows_sys::core::BOOL);\nwindows_link::link!(\"user32.dll\" \"system\" fn CheckRadioButton(hdlg : super::super::Foundation:: HWND, nidfirstbutton : i32, nidlastbutton : i32, nidcheckbutton : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn CloseThemeData(htheme : HTHEME) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn CreateMappedBitmap(hinstance : super::super::Foundation:: HINSTANCE, idbitmap : isize, wflags : u32, lpcolormap : *const COLORMAP, inummaps : i32) -> super::super::Graphics::Gdi:: HBITMAP);\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn CreatePropertySheetPageA(constpropsheetpagepointer : *mut PROPSHEETPAGEA) -> HPROPSHEETPAGE);\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn CreatePropertySheetPageW(constpropsheetpagepointer : *mut PROPSHEETPAGEW) -> HPROPSHEETPAGE);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn CreateStatusWindowA(style : i32, lpsztext : windows_sys::core::PCSTR, hwndparent : super::super::Foundation:: HWND, wid : u32) -> super::super::Foundation:: HWND);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn CreateStatusWindowW(style : i32, lpsztext : windows_sys::core::PCWSTR, hwndparent : super::super::Foundation:: HWND, wid : u32) -> super::super::Foundation:: HWND);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"user32.dll\" \"system\" fn CreateSyntheticPointerDevice(pointertype : super::WindowsAndMessaging:: POINTER_INPUT_TYPE, maxcount : u32, mode : POINTER_FEEDBACK_MODE) -> HSYNTHETICPOINTERDEVICE);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn CreateToolbarEx(hwnd : super::super::Foundation:: HWND, ws : u32, wid : u32, nbitmaps : i32, hbminst : super::super::Foundation:: HINSTANCE, wbmid : usize, lpbuttons : *mut TBBUTTON, inumbuttons : i32, dxbutton : i32, dybutton : i32, dxbitmap : i32, dybitmap : i32, ustructsize : u32) -> super::super::Foundation:: HWND);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn CreateUpDownControl(dwstyle : u32, x : i32, y : i32, cx : i32, cy : i32, hparent : super::super::Foundation:: HWND, nid : i32, hinst : super::super::Foundation:: HINSTANCE, hbuddy : super::super::Foundation:: HWND, nupper : i32, nlower : i32, npos : i32) -> super::super::Foundation:: HWND);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_Clone(hdpa : HDPA, hdpanew : HDPA) -> HDPA);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_Create(citemgrow : i32) -> HDPA);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_CreateEx(cpgrow : i32, hheap : super::super::Foundation:: HANDLE) -> HDPA);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_DeleteAllPtrs(hdpa : HDPA) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_DeletePtr(hdpa : HDPA, i : i32) -> *mut core::ffi::c_void);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_Destroy(hdpa : HDPA) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_DestroyCallback(hdpa : HDPA, pfncb : PFNDAENUMCALLBACK, pdata : *const core::ffi::c_void));\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_EnumCallback(hdpa : HDPA, pfncb : PFNDAENUMCALLBACK, pdata : *const core::ffi::c_void));\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_GetPtr(hdpa : HDPA, i : isize) -> *mut core::ffi::c_void);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_GetPtrIndex(hdpa : HDPA, p : *const core::ffi::c_void) -> i32);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_GetSize(hdpa : HDPA) -> u64);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_Grow(pdpa : HDPA, cp : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_InsertPtr(hdpa : HDPA, i : i32, p : *const core::ffi::c_void) -> i32);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_LoadStream(phdpa : *mut HDPA, pfn : PFNDPASTREAM, pstream : * mut core::ffi::c_void, pvinstdata : *const core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_Merge(hdpadest : HDPA, hdpasrc : HDPA, dwflags : u32, pfncompare : PFNDACOMPARE, pfnmerge : PFNDPAMERGE, lparam : super::super::Foundation:: LPARAM) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_SaveStream(hdpa : HDPA, pfn : PFNDPASTREAM, pstream : * mut core::ffi::c_void, pvinstdata : *const core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_Search(hdpa : HDPA, pfind : *const core::ffi::c_void, istart : i32, pfncompare : PFNDACOMPARE, lparam : super::super::Foundation:: LPARAM, options : u32) -> i32);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_SetPtr(hdpa : HDPA, i : i32, p : *const core::ffi::c_void) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DPA_Sort(hdpa : HDPA, pfncompare : PFNDACOMPARE, lparam : super::super::Foundation:: LPARAM) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_Clone(hdsa : HDSA) -> HDSA);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_Create(cbitem : i32, citemgrow : i32) -> HDSA);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_DeleteAllItems(hdsa : HDSA) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_DeleteItem(hdsa : HDSA, i : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_Destroy(hdsa : HDSA) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_DestroyCallback(hdsa : HDSA, pfncb : PFNDAENUMCALLBACK, pdata : *const core::ffi::c_void));\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_EnumCallback(hdsa : HDSA, pfncb : PFNDAENUMCALLBACK, pdata : *const core::ffi::c_void));\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_GetItem(hdsa : HDSA, i : i32, pitem : *mut core::ffi::c_void) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_GetItemPtr(hdsa : HDSA, i : i32) -> *mut core::ffi::c_void);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_GetSize(hdsa : HDSA) -> u64);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_InsertItem(hdsa : HDSA, i : i32, pitem : *const core::ffi::c_void) -> i32);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_SetItem(hdsa : HDSA, i : i32, pitem : *const core::ffi::c_void) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DSA_Sort(pdsa : HDSA, pfncompare : PFNDACOMPARE, lparam : super::super::Foundation:: LPARAM) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DestroyPropertySheetPage(param0 : HPROPSHEETPAGE) -> windows_sys::core::BOOL);\nwindows_link::link!(\"user32.dll\" \"system\" fn DestroySyntheticPointerDevice(device : HSYNTHETICPOINTERDEVICE));\nwindows_link::link!(\"user32.dll\" \"system\" fn DlgDirListA(hdlg : super::super::Foundation:: HWND, lppathspec : windows_sys::core::PSTR, nidlistbox : i32, nidstaticpath : i32, ufiletype : DLG_DIR_LIST_FILE_TYPE) -> i32);\nwindows_link::link!(\"user32.dll\" \"system\" fn DlgDirListComboBoxA(hdlg : super::super::Foundation:: HWND, lppathspec : windows_sys::core::PSTR, nidcombobox : i32, nidstaticpath : i32, ufiletype : DLG_DIR_LIST_FILE_TYPE) -> i32);\nwindows_link::link!(\"user32.dll\" \"system\" fn DlgDirListComboBoxW(hdlg : super::super::Foundation:: HWND, lppathspec : windows_sys::core::PWSTR, nidcombobox : i32, nidstaticpath : i32, ufiletype : DLG_DIR_LIST_FILE_TYPE) -> i32);\nwindows_link::link!(\"user32.dll\" \"system\" fn DlgDirListW(hdlg : super::super::Foundation:: HWND, lppathspec : windows_sys::core::PWSTR, nidlistbox : i32, nidstaticpath : i32, ufiletype : DLG_DIR_LIST_FILE_TYPE) -> i32);\nwindows_link::link!(\"user32.dll\" \"system\" fn DlgDirSelectComboBoxExA(hwnddlg : super::super::Foundation:: HWND, lpstring : windows_sys::core::PSTR, cchout : i32, idcombobox : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"user32.dll\" \"system\" fn DlgDirSelectComboBoxExW(hwnddlg : super::super::Foundation:: HWND, lpstring : windows_sys::core::PWSTR, cchout : i32, idcombobox : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"user32.dll\" \"system\" fn DlgDirSelectExA(hwnddlg : super::super::Foundation:: HWND, lpstring : windows_sys::core::PSTR, chcount : i32, idlistbox : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"user32.dll\" \"system\" fn DlgDirSelectExW(hwnddlg : super::super::Foundation:: HWND, lpstring : windows_sys::core::PWSTR, chcount : i32, idlistbox : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DrawInsert(handparent : super::super::Foundation:: HWND, hlb : super::super::Foundation:: HWND, nitem : i32));\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DrawShadowText(hdc : super::super::Graphics::Gdi:: HDC, psztext : windows_sys::core::PCWSTR, cch : u32, prc : *const super::super::Foundation:: RECT, dwflags : u32, crtext : super::super::Foundation:: COLORREF, crshadow : super::super::Foundation:: COLORREF, ixoffset : i32, iyoffset : i32) -> i32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DrawStatusTextA(hdc : super::super::Graphics::Gdi:: HDC, lprc : *mut super::super::Foundation:: RECT, psztext : windows_sys::core::PCSTR, uflags : u32));\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn DrawStatusTextW(hdc : super::super::Graphics::Gdi:: HDC, lprc : *mut super::super::Foundation:: RECT, psztext : windows_sys::core::PCWSTR, uflags : u32));\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn DrawThemeBackground(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, prect : *const super::super::Foundation:: RECT, pcliprect : *const super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn DrawThemeBackgroundEx(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, prect : *const super::super::Foundation:: RECT, poptions : *const DTBGOPTS) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn DrawThemeEdge(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, pdestrect : *const super::super::Foundation:: RECT, uedge : super::super::Graphics::Gdi:: DRAWEDGE_FLAGS, uflags : super::super::Graphics::Gdi:: DRAW_EDGE_FLAGS, pcontentrect : *mut super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn DrawThemeIcon(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, prect : *const super::super::Foundation:: RECT, himl : HIMAGELIST, iimageindex : i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn DrawThemeParentBackground(hwnd : super::super::Foundation:: HWND, hdc : super::super::Graphics::Gdi:: HDC, prc : *const super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn DrawThemeParentBackgroundEx(hwnd : super::super::Foundation:: HWND, hdc : super::super::Graphics::Gdi:: HDC, dwflags : DRAW_THEME_PARENT_BACKGROUND_FLAGS, prc : *const super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn DrawThemeText(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, psztext : windows_sys::core::PCWSTR, cchtext : i32, dwtextflags : super::super::Graphics::Gdi:: DRAW_TEXT_FORMAT, dwtextflags2 : u32, prect : *const super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn DrawThemeTextEx(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, psztext : windows_sys::core::PCWSTR, cchtext : i32, dwtextflags : super::super::Graphics::Gdi:: DRAW_TEXT_FORMAT, prect : *mut super::super::Foundation:: RECT, poptions : *const DTTOPTS) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"user32.dll\" \"system\" fn EnableScrollBar(hwnd : super::super::Foundation:: HWND, wsbflags : u32, warrows : ENABLE_SCROLL_BAR_ARROWS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn EnableThemeDialogTexture(hwnd : super::super::Foundation:: HWND, dwflags : u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn EnableTheming(fenable : windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn EndBufferedAnimation(hbpanimation : isize, fupdatetarget : windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn EndBufferedPaint(hbufferedpaint : isize, fupdatetarget : windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn EndPanningFeedback(hwnd : super::super::Foundation:: HWND, fanimateback : windows_sys::core::BOOL) -> windows_sys::core::BOOL);\nwindows_link::link!(\"user32.dll\" \"system\" fn EvaluateProximityToPolygon(numvertices : u32, controlpolygon : *const super::super::Foundation:: POINT, phittestinginput : *const TOUCH_HIT_TESTING_INPUT, pproximityeval : *mut TOUCH_HIT_TESTING_PROXIMITY_EVALUATION) -> windows_sys::core::BOOL);\nwindows_link::link!(\"user32.dll\" \"system\" fn EvaluateProximityToRect(controlboundingbox : *const super::super::Foundation:: RECT, phittestinginput : *const TOUCH_HIT_TESTING_INPUT, pproximityeval : *mut TOUCH_HIT_TESTING_PROXIMITY_EVALUATION) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn FlatSB_EnableScrollBar(param0 : super::super::Foundation:: HWND, param1 : i32, param2 : u32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn FlatSB_GetScrollInfo(param0 : super::super::Foundation:: HWND, code : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS, param2 : *mut super::WindowsAndMessaging:: SCROLLINFO) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn FlatSB_GetScrollPos(param0 : super::super::Foundation:: HWND, code : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS) -> i32);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn FlatSB_GetScrollProp(param0 : super::super::Foundation:: HWND, propindex : WSB_PROP, param2 : *mut i32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn FlatSB_GetScrollRange(param0 : super::super::Foundation:: HWND, code : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS, param2 : *mut i32, param3 : *mut i32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn FlatSB_SetScrollInfo(param0 : super::super::Foundation:: HWND, code : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS, psi : *mut super::WindowsAndMessaging:: SCROLLINFO, fredraw : windows_sys::core::BOOL) -> i32);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn FlatSB_SetScrollPos(param0 : super::super::Foundation:: HWND, code : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS, pos : i32, fredraw : windows_sys::core::BOOL) -> i32);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn FlatSB_SetScrollProp(param0 : super::super::Foundation:: HWND, index : u32, newvalue : isize, param3 : windows_sys::core::BOOL) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn FlatSB_SetScrollRange(param0 : super::super::Foundation:: HWND, code : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS, min : i32, max : i32, fredraw : windows_sys::core::BOOL) -> i32);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn FlatSB_ShowScrollBar(param0 : super::super::Foundation:: HWND, code : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS, param2 : windows_sys::core::BOOL) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetBufferedPaintBits(hbufferedpaint : isize, ppbbuffer : *mut *mut super::super::Graphics::Gdi:: RGBQUAD, pcxrow : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetBufferedPaintDC(hbufferedpaint : isize) -> super::super::Graphics::Gdi:: HDC);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetBufferedPaintTargetDC(hbufferedpaint : isize) -> super::super::Graphics::Gdi:: HDC);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetBufferedPaintTargetRect(hbufferedpaint : isize, prc : *mut super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"user32.dll\" \"system\" fn GetComboBoxInfo(hwndcombo : super::super::Foundation:: HWND, pcbi : *mut COMBOBOXINFO) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetCurrentThemeName(pszthemefilename : windows_sys::core::PWSTR, cchmaxnamechars : i32, pszcolorbuff : windows_sys::core::PWSTR, cchmaxcolorchars : i32, pszsizebuff : windows_sys::core::PWSTR, cchmaxsizechars : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn GetEffectiveClientRect(hwnd : super::super::Foundation:: HWND, lprc : *mut super::super::Foundation:: RECT, lpinfo : *const i32));\nwindows_link::link!(\"user32.dll\" \"system\" fn GetListBoxInfo(hwnd : super::super::Foundation:: HWND) -> u32);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn GetMUILanguage() -> u16);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeAnimationProperty(htheme : HTHEME, istoryboardid : i32, itargetid : i32, eproperty : TA_PROPERTY, pvproperty : *mut core::ffi::c_void, cbsize : u32, pcbsizeout : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeAnimationTransform(htheme : HTHEME, istoryboardid : i32, itargetid : i32, dwtransformindex : u32, ptransform : *mut TA_TRANSFORM, cbsize : u32, pcbsizeout : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeAppProperties() -> SET_THEME_APP_PROPERTIES_FLAGS);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeBackgroundContentRect(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, pboundingrect : *const super::super::Foundation:: RECT, pcontentrect : *mut super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeBackgroundExtent(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, pcontentrect : *const super::super::Foundation:: RECT, pextentrect : *mut super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeBackgroundRegion(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, prect : *const super::super::Foundation:: RECT, pregion : *mut super::super::Graphics::Gdi:: HRGN) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeBitmap(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, dwflags : GET_THEME_BITMAP_FLAGS, phbitmap : *mut super::super::Graphics::Gdi:: HBITMAP) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeBool(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, pfval : *mut windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeColor(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, pcolor : *mut super::super::Foundation:: COLORREF) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeDocumentationProperty(pszthemename : windows_sys::core::PCWSTR, pszpropertyname : windows_sys::core::PCWSTR, pszvaluebuff : windows_sys::core::PWSTR, cchmaxvalchars : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeEnumValue(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, pival : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeFilename(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, pszthemefilename : windows_sys::core::PWSTR, cchmaxbuffchars : i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeFont(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, ipropid : i32, pfont : *mut super::super::Graphics::Gdi:: LOGFONTW) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeInt(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, pival : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeIntList(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, pintlist : *mut INTLIST) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeMargins(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, ipropid : i32, prc : *const super::super::Foundation:: RECT, pmargins : *mut MARGINS) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeMetric(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, ipropid : i32, pival : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemePartSize(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, prc : *const super::super::Foundation:: RECT, esize : THEMESIZE, psz : *mut super::super::Foundation:: SIZE) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemePosition(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, ppoint : *mut super::super::Foundation:: POINT) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemePropertyOrigin(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, porigin : *mut PROPERTYORIGIN) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeRect(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, prect : *mut super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeStream(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, ppvstream : *mut *mut core::ffi::c_void, pcbstream : *mut u32, hinst : super::super::Foundation:: HINSTANCE) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeString(htheme : HTHEME, ipartid : i32, istateid : i32, ipropid : i32, pszbuff : windows_sys::core::PWSTR, cchmaxbuffchars : i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeSysBool(htheme : HTHEME, iboolid : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeSysColor(htheme : HTHEME, icolorid : i32) -> super::super::Foundation:: COLORREF);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeSysColorBrush(htheme : HTHEME, icolorid : i32) -> super::super::Graphics::Gdi:: HBRUSH);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeSysFont(htheme : HTHEME, ifontid : i32, plf : *mut super::super::Graphics::Gdi:: LOGFONTW) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeSysInt(htheme : HTHEME, iintid : i32, pivalue : *mut i32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeSysSize(htheme : HTHEME, isizeid : i32) -> i32);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeSysString(htheme : HTHEME, istringid : i32, pszstringbuff : windows_sys::core::PWSTR, cchmaxstringchars : i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeTextExtent(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, psztext : windows_sys::core::PCWSTR, cchcharcount : i32, dwtextflags : super::super::Graphics::Gdi:: DRAW_TEXT_FORMAT, pboundingrect : *const super::super::Foundation:: RECT, pextentrect : *mut super::super::Foundation:: RECT) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeTextMetrics(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, ptm : *mut super::super::Graphics::Gdi:: TEXTMETRICW) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeTimingFunction(htheme : HTHEME, itimingfunctionid : i32, ptimingfunction : *mut TA_TIMINGFUNCTION, cbsize : u32, pcbsizeout : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetThemeTransitionDuration(htheme : HTHEME, ipartid : i32, istateidfrom : i32, istateidto : i32, ipropid : i32, pdwduration : *mut u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"user32.dll\" \"system\" fn GetWindowFeedbackSetting(hwnd : super::super::Foundation:: HWND, feedback : FEEDBACK_TYPE, dwflags : u32, psize : *mut u32, config : *mut core::ffi::c_void) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn GetWindowTheme(hwnd : super::super::Foundation:: HWND) -> HTHEME);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn HIMAGELIST_QueryInterface(himl : HIMAGELIST, riid : *const windows_sys::core::GUID, ppv : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn HitTestThemeBackground(htheme : HTHEME, hdc : super::super::Graphics::Gdi:: HDC, ipartid : i32, istateid : i32, dwoptions : HIT_TEST_BACKGROUND_OPTIONS, prect : *const super::super::Foundation:: RECT, hrgn : super::super::Graphics::Gdi:: HRGN, pttest : super::super::Foundation:: POINT, pwhittestcode : *mut u16) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Add(himl : HIMAGELIST, hbmimage : super::super::Graphics::Gdi:: HBITMAP, hbmmask : super::super::Graphics::Gdi:: HBITMAP) -> i32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_AddMasked(himl : HIMAGELIST, hbmimage : super::super::Graphics::Gdi:: HBITMAP, crmask : super::super::Foundation:: COLORREF) -> i32);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_BeginDrag(himltrack : HIMAGELIST, itrack : i32, dxhotspot : i32, dyhotspot : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_CoCreateInstance(rclsid : *const windows_sys::core::GUID, punkouter : * mut core::ffi::c_void, riid : *const windows_sys::core::GUID, ppv : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Copy(himldst : HIMAGELIST, idst : i32, himlsrc : HIMAGELIST, isrc : i32, uflags : IMAGE_LIST_COPY_FLAGS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Create(cx : i32, cy : i32, flags : IMAGELIST_CREATION_FLAGS, cinitial : i32, cgrow : i32) -> HIMAGELIST);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Destroy(himl : HIMAGELIST) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_DragEnter(hwndlock : super::super::Foundation:: HWND, x : i32, y : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_DragLeave(hwndlock : super::super::Foundation:: HWND) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_DragMove(x : i32, y : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_DragShowNolock(fshow : windows_sys::core::BOOL) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Draw(himl : HIMAGELIST, i : i32, hdcdst : super::super::Graphics::Gdi:: HDC, x : i32, y : i32, fstyle : IMAGE_LIST_DRAW_STYLE) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_DrawEx(himl : HIMAGELIST, i : i32, hdcdst : super::super::Graphics::Gdi:: HDC, x : i32, y : i32, dx : i32, dy : i32, rgbbk : super::super::Foundation:: COLORREF, rgbfg : super::super::Foundation:: COLORREF, fstyle : IMAGE_LIST_DRAW_STYLE) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_DrawIndirect(pimldp : *const IMAGELISTDRAWPARAMS) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Duplicate(himl : HIMAGELIST) -> HIMAGELIST);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_EndDrag());\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_GetBkColor(himl : HIMAGELIST) -> super::super::Foundation:: COLORREF);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_GetDragImage(ppt : *mut super::super::Foundation:: POINT, ppthotspot : *mut super::super::Foundation:: POINT) -> HIMAGELIST);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_GetIcon(himl : HIMAGELIST, i : i32, flags : IMAGE_LIST_DRAW_STYLE) -> super::WindowsAndMessaging:: HICON);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_GetIconSize(himl : HIMAGELIST, cx : *mut i32, cy : *mut i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_GetImageCount(himl : HIMAGELIST) -> i32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_GetImageInfo(himl : HIMAGELIST, i : i32, pimageinfo : *mut IMAGEINFO) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_LoadImageA(hi : super::super::Foundation:: HINSTANCE, lpbmp : windows_sys::core::PCSTR, cx : i32, cgrow : i32, crmask : super::super::Foundation:: COLORREF, utype : u32, uflags : super::WindowsAndMessaging:: IMAGE_FLAGS) -> HIMAGELIST);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_LoadImageW(hi : super::super::Foundation:: HINSTANCE, lpbmp : windows_sys::core::PCWSTR, cx : i32, cgrow : i32, crmask : super::super::Foundation:: COLORREF, utype : u32, uflags : super::WindowsAndMessaging:: IMAGE_FLAGS) -> HIMAGELIST);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Merge(himl1 : HIMAGELIST, i1 : i32, himl2 : HIMAGELIST, i2 : i32, dx : i32, dy : i32) -> HIMAGELIST);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Read(pstm : * mut core::ffi::c_void) -> HIMAGELIST);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_ReadEx(dwflags : u32, pstm : * mut core::ffi::c_void, riid : *const windows_sys::core::GUID, ppv : *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Remove(himl : HIMAGELIST, i : i32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Replace(himl : HIMAGELIST, i : i32, hbmimage : super::super::Graphics::Gdi:: HBITMAP, hbmmask : super::super::Graphics::Gdi:: HBITMAP) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_ReplaceIcon(himl : HIMAGELIST, i : i32, hicon : super::WindowsAndMessaging:: HICON) -> i32);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_SetBkColor(himl : HIMAGELIST, clrbk : super::super::Foundation:: COLORREF) -> super::super::Foundation:: COLORREF);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_SetDragCursorImage(himldrag : HIMAGELIST, idrag : i32, dxhotspot : i32, dyhotspot : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_SetIconSize(himl : HIMAGELIST, cx : i32, cy : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_SetImageCount(himl : HIMAGELIST, unewcount : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_SetOverlayImage(himl : HIMAGELIST, iimage : i32, ioverlay : i32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_Write(himl : HIMAGELIST, pstm : * mut core::ffi::c_void) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_System_Com\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ImageList_WriteEx(himl : HIMAGELIST, dwflags : IMAGE_LIST_WRITE_STREAM_FLAGS, pstm : * mut core::ffi::c_void) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn InitCommonControls());\nwindows_link::link!(\"comctl32.dll\" \"system\" fn InitCommonControlsEx(picce : *const INITCOMMONCONTROLSEX) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn InitMUILanguage(uilang : u16));\nwindows_link::link!(\"comctl32.dll\" \"system\" fn InitializeFlatSB(param0 : super::super::Foundation:: HWND) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn IsAppThemed() -> windows_sys::core::BOOL);\nwindows_link::link!(\"user32.dll\" \"system\" fn IsCharLowerW(ch : u16) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn IsCompositionActive() -> windows_sys::core::BOOL);\nwindows_link::link!(\"user32.dll\" \"system\" fn IsDlgButtonChecked(hdlg : super::super::Foundation:: HWND, nidbutton : i32) -> u32);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn IsThemeActive() -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn IsThemeBackgroundPartiallyTransparent(htheme : HTHEME, ipartid : i32, istateid : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn IsThemeDialogTextureEnabled(hwnd : super::super::Foundation:: HWND) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn IsThemePartDefined(htheme : HTHEME, ipartid : i32, istateid : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn LBItemFromPt(hlb : super::super::Foundation:: HWND, pt : super::super::Foundation:: POINT, bautoscroll : windows_sys::core::BOOL) -> i32);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn LoadIconMetric(hinst : super::super::Foundation:: HINSTANCE, pszname : windows_sys::core::PCWSTR, lims : _LI_METRIC, phico : *mut super::WindowsAndMessaging:: HICON) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn LoadIconWithScaleDown(hinst : super::super::Foundation:: HINSTANCE, pszname : windows_sys::core::PCWSTR, cx : i32, cy : i32, phico : *mut super::WindowsAndMessaging:: HICON) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn MakeDragList(hlb : super::super::Foundation:: HWND) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn MenuHelp(umsg : u32, wparam : super::super::Foundation:: WPARAM, lparam : super::super::Foundation:: LPARAM, hmainmenu : super::WindowsAndMessaging:: HMENU, hinst : super::super::Foundation:: HINSTANCE, hwndstatus : super::super::Foundation:: HWND, lpwids : *const u32));\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn OpenThemeData(hwnd : super::super::Foundation:: HWND, pszclasslist : windows_sys::core::PCWSTR) -> HTHEME);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn OpenThemeDataEx(hwnd : super::super::Foundation:: HWND, pszclasslist : windows_sys::core::PCWSTR, dwflags : OPEN_THEME_DATA_FLAGS) -> HTHEME);\nwindows_link::link!(\"user32.dll\" \"system\" fn PackTouchHitTestingProximityEvaluation(phittestinginput : *const TOUCH_HIT_TESTING_INPUT, pproximityeval : *const TOUCH_HIT_TESTING_PROXIMITY_EVALUATION) -> super::super::Foundation:: LRESULT);\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn PropertySheetA(param0 : *mut PROPSHEETHEADERA_V2) -> isize);\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn PropertySheetW(param0 : *mut PROPSHEETHEADERW_V2) -> isize);\nwindows_link::link!(\"user32.dll\" \"system\" fn RegisterPointerDeviceNotifications(window : super::super::Foundation:: HWND, notifyrange : windows_sys::core::BOOL) -> windows_sys::core::BOOL);\nwindows_link::link!(\"user32.dll\" \"system\" fn RegisterTouchHitTestingWindow(hwnd : super::super::Foundation:: HWND, value : u32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"user32.dll\" \"system\" fn SetScrollInfo(hwnd : super::super::Foundation:: HWND, nbar : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS, lpsi : *const super::WindowsAndMessaging:: SCROLLINFO, redraw : windows_sys::core::BOOL) -> i32);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"user32.dll\" \"system\" fn SetScrollPos(hwnd : super::super::Foundation:: HWND, nbar : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS, npos : i32, bredraw : windows_sys::core::BOOL) -> i32);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"user32.dll\" \"system\" fn SetScrollRange(hwnd : super::super::Foundation:: HWND, nbar : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS, nminpos : i32, nmaxpos : i32, bredraw : windows_sys::core::BOOL) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn SetThemeAppProperties(dwflags : SET_THEME_APP_PROPERTIES_FLAGS));\nwindows_link::link!(\"user32.dll\" \"system\" fn SetWindowFeedbackSetting(hwnd : super::super::Foundation:: HWND, feedback : FEEDBACK_TYPE, dwflags : u32, size : u32, configuration : *const core::ffi::c_void) -> windows_sys::core::BOOL);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn SetWindowTheme(hwnd : super::super::Foundation:: HWND, pszsubappname : windows_sys::core::PCWSTR, pszsubidlist : windows_sys::core::PCWSTR) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn SetWindowThemeAttribute(hwnd : super::super::Foundation:: HWND, eattribute : WINDOWTHEMEATTRIBUTETYPE, pvattribute : *const core::ffi::c_void, cbattribute : u32) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn ShowHideMenuCtl(hwnd : super::super::Foundation:: HWND, uflags : usize, lpinfo : *const i32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"user32.dll\" \"system\" fn ShowScrollBar(hwnd : super::super::Foundation:: HWND, wbar : super::WindowsAndMessaging:: SCROLLBAR_CONSTANTS, bshow : windows_sys::core::BOOL) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn Str_SetPtrW(ppsz : *mut windows_sys::core::PWSTR, psz : windows_sys::core::PCWSTR) -> windows_sys::core::BOOL);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn TaskDialog(hwndowner : super::super::Foundation:: HWND, hinstance : super::super::Foundation:: HINSTANCE, pszwindowtitle : windows_sys::core::PCWSTR, pszmaininstruction : windows_sys::core::PCWSTR, pszcontent : windows_sys::core::PCWSTR, dwcommonbuttons : TASKDIALOG_COMMON_BUTTON_FLAGS, pszicon : windows_sys::core::PCWSTR, pnbutton : *mut i32) -> windows_sys::core::HRESULT);\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nwindows_link::link!(\"comctl32.dll\" \"system\" fn TaskDialogIndirect(ptaskconfig : *const TASKDIALOGCONFIG, pnbutton : *mut i32, pnradiobutton : *mut i32, pfverificationflagchecked : *mut windows_sys::core::BOOL) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"comctl32.dll\" \"system\" fn UninitializeFlatSB(param0 : super::super::Foundation:: HWND) -> windows_sys::core::HRESULT);\nwindows_link::link!(\"uxtheme.dll\" \"system\" fn UpdatePanningFeedback(hwnd : super::super::Foundation:: HWND, ltotaloverpanoffsetx : i32, ltotaloverpanoffsety : i32, fininertia : windows_sys::core::BOOL) -> windows_sys::core::BOOL);\npub const ABS_DOWNDISABLED: ARROWBTNSTATES = 8i32;\npub const ABS_DOWNHOT: ARROWBTNSTATES = 6i32;\npub const ABS_DOWNHOVER: ARROWBTNSTATES = 18i32;\npub const ABS_DOWNNORMAL: ARROWBTNSTATES = 5i32;\npub const ABS_DOWNPRESSED: ARROWBTNSTATES = 7i32;\npub const ABS_LEFTDISABLED: ARROWBTNSTATES = 12i32;\npub const ABS_LEFTHOT: ARROWBTNSTATES = 10i32;\npub const ABS_LEFTHOVER: ARROWBTNSTATES = 19i32;\npub const ABS_LEFTNORMAL: ARROWBTNSTATES = 9i32;\npub const ABS_LEFTPRESSED: ARROWBTNSTATES = 11i32;\npub const ABS_RIGHTDISABLED: ARROWBTNSTATES = 16i32;\npub const ABS_RIGHTHOT: ARROWBTNSTATES = 14i32;\npub const ABS_RIGHTHOVER: ARROWBTNSTATES = 20i32;\npub const ABS_RIGHTNORMAL: ARROWBTNSTATES = 13i32;\npub const ABS_RIGHTPRESSED: ARROWBTNSTATES = 15i32;\npub const ABS_UPDISABLED: ARROWBTNSTATES = 4i32;\npub const ABS_UPHOT: ARROWBTNSTATES = 2i32;\npub const ABS_UPHOVER: ARROWBTNSTATES = 17i32;\npub const ABS_UPNORMAL: ARROWBTNSTATES = 1i32;\npub const ABS_UPPRESSED: ARROWBTNSTATES = 3i32;\npub const ACM_ISPLAYING: u32 = 1128u32;\npub const ACM_OPEN: u32 = 1127u32;\npub const ACM_OPENA: u32 = 1124u32;\npub const ACM_OPENW: u32 = 1127u32;\npub const ACM_PLAY: u32 = 1125u32;\npub const ACM_STOP: u32 = 1126u32;\npub const ACN_START: u32 = 1u32;\npub const ACN_STOP: u32 = 2u32;\npub const ACS_AUTOPLAY: u32 = 4u32;\npub const ACS_CENTER: u32 = 1u32;\npub const ACS_TIMER: u32 = 8u32;\npub const ACS_TRANSPARENT: u32 = 2u32;\npub type AEROWIZARDPARTS = i32;\npub const ALLOW_CONTROLS: SET_THEME_APP_PROPERTIES_FLAGS = 2u32;\npub const ALLOW_NONCLIENT: SET_THEME_APP_PROPERTIES_FLAGS = 1u32;\npub const ALLOW_WEBCONTENT: SET_THEME_APP_PROPERTIES_FLAGS = 4u32;\npub const ANIMATE_CLASS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysAnimate32\");\npub const ANIMATE_CLASSA: windows_sys::core::PCSTR = windows_sys::core::s!(\"SysAnimate32\");\npub const ANIMATE_CLASSW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysAnimate32\");\npub type ARROWBTNSTATES = i32;\npub const AW_BUTTON: AEROWIZARDPARTS = 5i32;\npub const AW_COMMANDAREA: AEROWIZARDPARTS = 4i32;\npub const AW_CONTENTAREA: AEROWIZARDPARTS = 3i32;\npub const AW_HEADERAREA: AEROWIZARDPARTS = 2i32;\npub const AW_S_CONTENTAREA_NOMARGIN: CONTENTAREASTATES = 1i32;\npub const AW_S_HEADERAREA_NOMARGIN: HEADERAREASTATES = 1i32;\npub const AW_S_TITLEBAR_ACTIVE: TITLEBARSTATES = 1i32;\npub const AW_S_TITLEBAR_INACTIVE: TITLEBARSTATES = 2i32;\npub const AW_TITLEBAR: AEROWIZARDPARTS = 1i32;\npub type BACKGROUNDSTATES = i32;\npub type BACKGROUNDWITHBORDERSTATES = i32;\npub type BALLOONSTATES = i32;\npub type BALLOONSTEMSTATES = i32;\npub type BARBACKGROUNDSTATES = i32;\npub type BARITEMSTATES = i32;\npub const BCM_FIRST: u32 = 5632u32;\npub const BCM_GETIDEALSIZE: u32 = 5633u32;\npub const BCM_GETIMAGELIST: u32 = 5635u32;\npub const BCM_GETNOTE: u32 = 5642u32;\npub const BCM_GETNOTELENGTH: u32 = 5643u32;\npub const BCM_GETSPLITINFO: u32 = 5640u32;\npub const BCM_GETTEXTMARGIN: u32 = 5637u32;\npub const BCM_SETDROPDOWNSTATE: u32 = 5638u32;\npub const BCM_SETIMAGELIST: u32 = 5634u32;\npub const BCM_SETNOTE: u32 = 5641u32;\npub const BCM_SETSHIELD: u32 = 5644u32;\npub const BCM_SETSPLITINFO: u32 = 5639u32;\npub const BCM_SETTEXTMARGIN: u32 = 5636u32;\npub const BCN_DROPDOWN: u32 = 4294966048u32;\npub const BCN_FIRST: u32 = 4294966046u32;\npub const BCN_HOTITEMCHANGE: u32 = 4294966047u32;\npub const BCN_LAST: u32 = 4294965946u32;\npub const BCSIF_GLYPH: u32 = 1u32;\npub const BCSIF_IMAGE: u32 = 2u32;\npub const BCSIF_SIZE: u32 = 8u32;\npub const BCSIF_STYLE: u32 = 4u32;\npub const BCSS_ALIGNLEFT: u32 = 4u32;\npub const BCSS_IMAGE: u32 = 8u32;\npub const BCSS_NOSPLIT: u32 = 1u32;\npub const BCSS_STRETCH: u32 = 2u32;\npub type BGTYPE = i32;\npub type BODYSTATES = i32;\npub type BORDERSTATES = i32;\npub type BORDERTYPE = i32;\npub type BORDER_HSCROLLSTATES = i32;\npub type BORDER_HVSCROLLSTATES = i32;\npub type BORDER_NOSCROLLSTATES = i32;\npub type BORDER_VSCROLLSTATES = i32;\npub const BPAS_CUBIC: BP_ANIMATIONSTYLE = 2i32;\npub const BPAS_LINEAR: BP_ANIMATIONSTYLE = 1i32;\npub const BPAS_NONE: BP_ANIMATIONSTYLE = 0i32;\npub const BPAS_SINE: BP_ANIMATIONSTYLE = 3i32;\npub const BPBF_COMPATIBLEBITMAP: BP_BUFFERFORMAT = 0i32;\npub const BPBF_DIB: BP_BUFFERFORMAT = 1i32;\npub const BPBF_TOPDOWNDIB: BP_BUFFERFORMAT = 2i32;\npub const BPBF_TOPDOWNMONODIB: BP_BUFFERFORMAT = 3i32;\npub const BPPF_ERASE: BP_PAINTPARAMS_FLAGS = 1u32;\npub const BPPF_NOCLIP: BP_PAINTPARAMS_FLAGS = 2u32;\npub const BPPF_NONCLIENT: BP_PAINTPARAMS_FLAGS = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct BP_ANIMATIONPARAMS {\n    pub cbSize: u32,\n    pub dwFlags: u32,\n    pub style: BP_ANIMATIONSTYLE,\n    pub dwDuration: u32,\n}\npub type BP_ANIMATIONSTYLE = i32;\npub type BP_BUFFERFORMAT = i32;\npub const BP_CHECKBOX: BUTTONPARTS = 3i32;\npub const BP_CHECKBOX_HCDISABLED: BUTTONPARTS = 9i32;\npub const BP_COMMANDLINK: BUTTONPARTS = 6i32;\npub const BP_COMMANDLINKGLYPH: BUTTONPARTS = 7i32;\npub const BP_GROUPBOX: BUTTONPARTS = 4i32;\npub const BP_GROUPBOX_HCDISABLED: BUTTONPARTS = 10i32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct BP_PAINTPARAMS {\n    pub cbSize: u32,\n    pub dwFlags: BP_PAINTPARAMS_FLAGS,\n    pub prcExclude: *const super::super::Foundation::RECT,\n    pub pBlendFunction: *const super::super::Graphics::Gdi::BLENDFUNCTION,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for BP_PAINTPARAMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type BP_PAINTPARAMS_FLAGS = u32;\npub const BP_PUSHBUTTON: BUTTONPARTS = 1i32;\npub const BP_PUSHBUTTONDROPDOWN: BUTTONPARTS = 11i32;\npub const BP_RADIOBUTTON: BUTTONPARTS = 2i32;\npub const BP_RADIOBUTTON_HCDISABLED: BUTTONPARTS = 8i32;\npub const BP_USERBUTTON: BUTTONPARTS = 5i32;\npub const BST_CHECKED: DLG_BUTTON_CHECK_STATE = 1u32;\npub const BST_DROPDOWNPUSHED: u32 = 1024u32;\npub const BST_HOT: u32 = 512u32;\npub const BST_INDETERMINATE: DLG_BUTTON_CHECK_STATE = 2u32;\npub const BST_UNCHECKED: DLG_BUTTON_CHECK_STATE = 0u32;\npub const BS_COMMANDLINK: i32 = 14i32;\npub const BS_DEFCOMMANDLINK: i32 = 15i32;\npub const BS_DEFSPLITBUTTON: i32 = 13i32;\npub const BS_SPLITBUTTON: i32 = 12i32;\npub const BTNS_AUTOSIZE: u32 = 16u32;\npub const BTNS_BUTTON: u32 = 0u32;\npub const BTNS_CHECK: u32 = 2u32;\npub const BTNS_DROPDOWN: u32 = 8u32;\npub const BTNS_GROUP: u32 = 4u32;\npub const BTNS_NOPREFIX: u32 = 32u32;\npub const BTNS_SEP: u32 = 1u32;\npub const BTNS_SHOWTEXT: u32 = 64u32;\npub const BTNS_WHOLEDROPDOWN: u32 = 128u32;\npub const BT_BORDERFILL: BGTYPE = 1i32;\npub const BT_ELLIPSE: BORDERTYPE = 2i32;\npub const BT_IMAGEFILE: BGTYPE = 0i32;\npub const BT_NONE: BGTYPE = 2i32;\npub const BT_RECT: BORDERTYPE = 0i32;\npub const BT_ROUNDRECT: BORDERTYPE = 1i32;\npub type BUTTONPARTS = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct BUTTON_IMAGELIST {\n    pub himl: HIMAGELIST,\n    pub margin: super::super::Foundation::RECT,\n    pub uAlign: BUTTON_IMAGELIST_ALIGN,\n}\npub type BUTTON_IMAGELIST_ALIGN = u32;\npub const BUTTON_IMAGELIST_ALIGN_BOTTOM: BUTTON_IMAGELIST_ALIGN = 3u32;\npub const BUTTON_IMAGELIST_ALIGN_CENTER: BUTTON_IMAGELIST_ALIGN = 4u32;\npub const BUTTON_IMAGELIST_ALIGN_LEFT: BUTTON_IMAGELIST_ALIGN = 0u32;\npub const BUTTON_IMAGELIST_ALIGN_RIGHT: BUTTON_IMAGELIST_ALIGN = 1u32;\npub const BUTTON_IMAGELIST_ALIGN_TOP: BUTTON_IMAGELIST_ALIGN = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct BUTTON_SPLITINFO {\n    pub mask: u32,\n    pub himlGlyph: HIMAGELIST,\n    pub uSplitStyle: u32,\n    pub size: super::super::Foundation::SIZE,\n}\npub type CAPTIONSTATES = i32;\npub const CA_CENTER: CONTENTALIGNMENT = 1i32;\npub const CA_LEFT: CONTENTALIGNMENT = 0i32;\npub const CA_RIGHT: CONTENTALIGNMENT = 2i32;\npub const CBB_DISABLED: BORDERSTATES = 4i32;\npub const CBB_FOCUSED: BORDERSTATES = 3i32;\npub const CBB_HOT: BORDERSTATES = 2i32;\npub const CBB_NORMAL: BORDERSTATES = 1i32;\npub const CBCB_DISABLED: CUEBANNERSTATES = 4i32;\npub const CBCB_HOT: CUEBANNERSTATES = 2i32;\npub const CBCB_NORMAL: CUEBANNERSTATES = 1i32;\npub const CBCB_PRESSED: CUEBANNERSTATES = 3i32;\npub const CBDI_HIGHLIGHTED: DROPDOWNITEMSTATES = 2i32;\npub const CBDI_NORMAL: DROPDOWNITEMSTATES = 1i32;\npub const CBEIF_DI_SETITEM: COMBOBOX_EX_ITEM_FLAGS = 268435456u32;\npub const CBEIF_IMAGE: COMBOBOX_EX_ITEM_FLAGS = 2u32;\npub const CBEIF_INDENT: COMBOBOX_EX_ITEM_FLAGS = 16u32;\npub const CBEIF_LPARAM: COMBOBOX_EX_ITEM_FLAGS = 32u32;\npub const CBEIF_OVERLAY: COMBOBOX_EX_ITEM_FLAGS = 8u32;\npub const CBEIF_SELECTEDIMAGE: COMBOBOX_EX_ITEM_FLAGS = 4u32;\npub const CBEIF_TEXT: COMBOBOX_EX_ITEM_FLAGS = 1u32;\npub const CBEMAXSTRLEN: u32 = 260u32;\npub const CBEM_GETCOMBOCONTROL: u32 = 1030u32;\npub const CBEM_GETEDITCONTROL: u32 = 1031u32;\npub const CBEM_GETEXSTYLE: u32 = 1033u32;\npub const CBEM_GETEXTENDEDSTYLE: u32 = 1033u32;\npub const CBEM_GETIMAGELIST: u32 = 1027u32;\npub const CBEM_GETITEM: u32 = 1037u32;\npub const CBEM_GETITEMA: u32 = 1028u32;\npub const CBEM_GETITEMW: u32 = 1037u32;\npub const CBEM_GETUNICODEFORMAT: u32 = 8198u32;\npub const CBEM_HASEDITCHANGED: u32 = 1034u32;\npub const CBEM_INSERTITEM: u32 = 1035u32;\npub const CBEM_INSERTITEMA: u32 = 1025u32;\npub const CBEM_INSERTITEMW: u32 = 1035u32;\npub const CBEM_SETEXSTYLE: u32 = 1032u32;\npub const CBEM_SETEXTENDEDSTYLE: u32 = 1038u32;\npub const CBEM_SETIMAGELIST: u32 = 1026u32;\npub const CBEM_SETITEM: u32 = 1036u32;\npub const CBEM_SETITEMA: u32 = 1029u32;\npub const CBEM_SETITEMW: u32 = 1036u32;\npub const CBEM_SETUNICODEFORMAT: u32 = 8197u32;\npub const CBEM_SETWINDOWTHEME: u32 = 8203u32;\npub const CBENF_DROPDOWN: u32 = 4u32;\npub const CBENF_ESCAPE: u32 = 3u32;\npub const CBENF_KILLFOCUS: u32 = 1u32;\npub const CBENF_RETURN: u32 = 2u32;\npub const CBEN_BEGINEDIT: u32 = 4294966492u32;\npub const CBEN_DELETEITEM: u32 = 4294966494u32;\npub const CBEN_DRAGBEGIN: u32 = 4294966487u32;\npub const CBEN_DRAGBEGINA: u32 = 4294966488u32;\npub const CBEN_DRAGBEGINW: u32 = 4294966487u32;\npub const CBEN_ENDEDIT: u32 = 4294966490u32;\npub const CBEN_ENDEDITA: u32 = 4294966491u32;\npub const CBEN_ENDEDITW: u32 = 4294966490u32;\npub const CBEN_FIRST: u32 = 4294966496u32;\npub const CBEN_GETDISPINFOA: u32 = 4294966496u32;\npub const CBEN_GETDISPINFOW: u32 = 4294966489u32;\npub const CBEN_INSERTITEM: u32 = 4294966495u32;\npub const CBEN_LAST: u32 = 4294966466u32;\npub const CBES_EX_CASESENSITIVE: u32 = 16u32;\npub const CBES_EX_NOEDITIMAGE: u32 = 1u32;\npub const CBES_EX_NOEDITIMAGEINDENT: u32 = 2u32;\npub const CBES_EX_NOSIZELIMIT: u32 = 8u32;\npub const CBES_EX_PATHWORDBREAKPROC: u32 = 4u32;\npub const CBES_EX_TEXTENDELLIPSIS: u32 = 32u32;\npub const CBM_FIRST: u32 = 5888u32;\npub const CBRO_DISABLED: READONLYSTATES = 4i32;\npub const CBRO_HOT: READONLYSTATES = 2i32;\npub const CBRO_NORMAL: READONLYSTATES = 1i32;\npub const CBRO_PRESSED: READONLYSTATES = 3i32;\npub const CBS_CHECKEDDISABLED: CHECKBOXSTATES = 8i32;\npub const CBS_CHECKEDHOT: CHECKBOXSTATES = 6i32;\npub const CBS_CHECKEDNORMAL: CHECKBOXSTATES = 5i32;\npub const CBS_CHECKEDPRESSED: CHECKBOXSTATES = 7i32;\npub const CBS_DISABLED: CLOSEBUTTONSTATES = 4i32;\npub const CBS_EXCLUDEDDISABLED: CHECKBOXSTATES = 20i32;\npub const CBS_EXCLUDEDHOT: CHECKBOXSTATES = 18i32;\npub const CBS_EXCLUDEDNORMAL: CHECKBOXSTATES = 17i32;\npub const CBS_EXCLUDEDPRESSED: CHECKBOXSTATES = 19i32;\npub const CBS_HOT: CLOSEBUTTONSTATES = 2i32;\npub const CBS_IMPLICITDISABLED: CHECKBOXSTATES = 16i32;\npub const CBS_IMPLICITHOT: CHECKBOXSTATES = 14i32;\npub const CBS_IMPLICITNORMAL: CHECKBOXSTATES = 13i32;\npub const CBS_IMPLICITPRESSED: CHECKBOXSTATES = 15i32;\npub const CBS_MIXEDDISABLED: CHECKBOXSTATES = 12i32;\npub const CBS_MIXEDHOT: CHECKBOXSTATES = 10i32;\npub const CBS_MIXEDNORMAL: CHECKBOXSTATES = 9i32;\npub const CBS_MIXEDPRESSED: CHECKBOXSTATES = 11i32;\npub const CBS_NORMAL: CLOSEBUTTONSTATES = 1i32;\npub const CBS_PUSHED: CLOSEBUTTONSTATES = 3i32;\npub const CBS_UNCHECKEDDISABLED: CHECKBOXSTATES = 4i32;\npub const CBS_UNCHECKEDHOT: CHECKBOXSTATES = 2i32;\npub const CBS_UNCHECKEDNORMAL: CHECKBOXSTATES = 1i32;\npub const CBS_UNCHECKEDPRESSED: CHECKBOXSTATES = 3i32;\npub const CBTBS_DISABLED: TRANSPARENTBACKGROUNDSTATES = 3i32;\npub const CBTBS_FOCUSED: TRANSPARENTBACKGROUNDSTATES = 4i32;\npub const CBTBS_HOT: TRANSPARENTBACKGROUNDSTATES = 2i32;\npub const CBTBS_NORMAL: TRANSPARENTBACKGROUNDSTATES = 1i32;\npub const CBXSL_DISABLED: DROPDOWNBUTTONLEFTSTATES = 4i32;\npub const CBXSL_HOT: DROPDOWNBUTTONLEFTSTATES = 2i32;\npub const CBXSL_NORMAL: DROPDOWNBUTTONLEFTSTATES = 1i32;\npub const CBXSL_PRESSED: DROPDOWNBUTTONLEFTSTATES = 3i32;\npub const CBXSR_DISABLED: DROPDOWNBUTTONRIGHTSTATES = 4i32;\npub const CBXSR_HOT: DROPDOWNBUTTONRIGHTSTATES = 2i32;\npub const CBXSR_NORMAL: DROPDOWNBUTTONRIGHTSTATES = 1i32;\npub const CBXSR_PRESSED: DROPDOWNBUTTONRIGHTSTATES = 3i32;\npub const CBXS_DISABLED: COMBOBOXSTYLESTATES = 4i32;\npub const CBXS_HOT: COMBOBOXSTYLESTATES = 2i32;\npub const CBXS_NORMAL: COMBOBOXSTYLESTATES = 1i32;\npub const CBXS_PRESSED: COMBOBOXSTYLESTATES = 3i32;\npub const CB_GETCUEBANNER: u32 = 5892u32;\npub const CB_GETMINVISIBLE: u32 = 5890u32;\npub const CB_SETCUEBANNER: u32 = 5891u32;\npub const CB_SETMINVISIBLE: u32 = 5889u32;\npub const CCF_NOTEXT: u32 = 1u32;\npub const CCHCCCLASS: u32 = 32u32;\npub const CCHCCDESC: u32 = 32u32;\npub const CCHCCTEXT: u32 = 256u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct CCINFOA {\n    pub szClass: [i8; 32],\n    pub flOptions: u32,\n    pub szDesc: [i8; 32],\n    pub cxDefault: u32,\n    pub cyDefault: u32,\n    pub flStyleDefault: u32,\n    pub flExtStyleDefault: u32,\n    pub flCtrlTypeMask: u32,\n    pub szTextDefault: [i8; 256],\n    pub cStyleFlags: i32,\n    pub aStyleFlags: *mut CCSTYLEFLAGA,\n    pub lpfnStyle: LPFNCCSTYLEA,\n    pub lpfnSizeToText: LPFNCCSIZETOTEXTA,\n    pub dwReserved1: u32,\n    pub dwReserved2: u32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for CCINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct CCINFOW {\n    pub szClass: [u16; 32],\n    pub flOptions: u32,\n    pub szDesc: [u16; 32],\n    pub cxDefault: u32,\n    pub cyDefault: u32,\n    pub flStyleDefault: u32,\n    pub flExtStyleDefault: u32,\n    pub flCtrlTypeMask: u32,\n    pub cStyleFlags: i32,\n    pub aStyleFlags: *mut CCSTYLEFLAGW,\n    pub szTextDefault: [u16; 256],\n    pub lpfnStyle: LPFNCCSTYLEW,\n    pub lpfnSizeToText: LPFNCCSIZETOTEXTW,\n    pub dwReserved1: u32,\n    pub dwReserved2: u32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for CCINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CCM_DPISCALE: u32 = 8204u32;\npub const CCM_FIRST: u32 = 8192u32;\npub const CCM_GETCOLORSCHEME: u32 = 8195u32;\npub const CCM_GETDROPTARGET: u32 = 8196u32;\npub const CCM_GETUNICODEFORMAT: u32 = 8198u32;\npub const CCM_GETVERSION: u32 = 8200u32;\npub const CCM_LAST: u32 = 8704u32;\npub const CCM_SETBKCOLOR: u32 = 8193u32;\npub const CCM_SETCOLORSCHEME: u32 = 8194u32;\npub const CCM_SETNOTIFYWINDOW: u32 = 8201u32;\npub const CCM_SETUNICODEFORMAT: u32 = 8197u32;\npub const CCM_SETVERSION: u32 = 8199u32;\npub const CCM_SETWINDOWTHEME: u32 = 8203u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CCSTYLEA {\n    pub flStyle: u32,\n    pub flExtStyle: u32,\n    pub szText: [i8; 256],\n    pub lgid: u16,\n    pub wReserved1: u16,\n}\nimpl Default for CCSTYLEA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CCSTYLEFLAGA {\n    pub flStyle: u32,\n    pub flStyleMask: u32,\n    pub pszStyle: windows_sys::core::PSTR,\n}\nimpl Default for CCSTYLEFLAGA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CCSTYLEFLAGW {\n    pub flStyle: u32,\n    pub flStyleMask: u32,\n    pub pszStyle: windows_sys::core::PWSTR,\n}\nimpl Default for CCSTYLEFLAGW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CCSTYLEW {\n    pub flStyle: u32,\n    pub flExtStyle: u32,\n    pub szText: [u16; 256],\n    pub lgid: u16,\n    pub wReserved1: u16,\n}\nimpl Default for CCSTYLEW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CCS_ADJUSTABLE: i32 = 32i32;\npub const CCS_BOTTOM: i32 = 3i32;\npub const CCS_NODIVIDER: i32 = 64i32;\npub const CCS_NOMOVEY: i32 = 2i32;\npub const CCS_NOPARENTALIGN: i32 = 8i32;\npub const CCS_NORESIZE: i32 = 4i32;\npub const CCS_TOP: i32 = 1i32;\npub const CCS_VERT: i32 = 128i32;\npub const CDDS_ITEM: u32 = 65536u32;\npub const CDDS_ITEMPOSTERASE: NMCUSTOMDRAW_DRAW_STAGE = 65540u32;\npub const CDDS_ITEMPOSTPAINT: NMCUSTOMDRAW_DRAW_STAGE = 65538u32;\npub const CDDS_ITEMPREERASE: NMCUSTOMDRAW_DRAW_STAGE = 65539u32;\npub const CDDS_ITEMPREPAINT: NMCUSTOMDRAW_DRAW_STAGE = 65537u32;\npub const CDDS_POSTERASE: u32 = 4u32;\npub const CDDS_POSTPAINT: NMCUSTOMDRAW_DRAW_STAGE = 2u32;\npub const CDDS_PREERASE: NMCUSTOMDRAW_DRAW_STAGE = 3u32;\npub const CDDS_PREPAINT: NMCUSTOMDRAW_DRAW_STAGE = 1u32;\npub const CDDS_SUBITEM: NMCUSTOMDRAW_DRAW_STAGE = 131072u32;\npub const CDIS_CHECKED: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 8u32;\npub const CDIS_DEFAULT: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 32u32;\npub const CDIS_DISABLED: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 4u32;\npub const CDIS_DROPHILITED: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 4096u32;\npub const CDIS_FOCUS: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 16u32;\npub const CDIS_GRAYED: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 2u32;\npub const CDIS_HOT: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 64u32;\npub const CDIS_INDETERMINATE: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 256u32;\npub const CDIS_MARKED: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 128u32;\npub const CDIS_NEARHOT: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 1024u32;\npub const CDIS_OTHERSIDEHOT: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 2048u32;\npub const CDIS_SELECTED: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 1u32;\npub const CDIS_SHOWKEYBOARDCUES: NMCUSTOMDRAW_DRAW_STATE_FLAGS = 512u32;\npub const CDN_FIRST: u32 = 4294966695u32;\npub const CDN_LAST: u32 = 4294966597u32;\npub const CDRF_DODEFAULT: u32 = 0u32;\npub const CDRF_DOERASE: u32 = 8u32;\npub const CDRF_NEWFONT: u32 = 2u32;\npub const CDRF_NOTIFYITEMDRAW: u32 = 32u32;\npub const CDRF_NOTIFYPOSTERASE: u32 = 64u32;\npub const CDRF_NOTIFYPOSTPAINT: u32 = 16u32;\npub const CDRF_NOTIFYSUBITEMDRAW: u32 = 32u32;\npub const CDRF_SKIPDEFAULT: u32 = 4u32;\npub const CDRF_SKIPPOSTPAINT: u32 = 256u32;\npub type CHECKBOXSTATES = i32;\npub type CHEVRONSTATES = i32;\npub type CHEVRONVERTSTATES = i32;\npub const CHEVSV_HOT: CHEVRONVERTSTATES = 2i32;\npub const CHEVSV_NORMAL: CHEVRONVERTSTATES = 1i32;\npub const CHEVSV_PRESSED: CHEVRONVERTSTATES = 3i32;\npub const CHEVS_HOT: CHEVRONSTATES = 2i32;\npub const CHEVS_NORMAL: CHEVRONSTATES = 1i32;\npub const CHEVS_PRESSED: CHEVRONSTATES = 3i32;\npub type CLOCKPARTS = i32;\npub type CLOCKSTATES = i32;\npub type CLOSEBUTTONSTATES = i32;\npub type CLOSESTATES = i32;\npub const CLP_TIME: CLOCKPARTS = 1i32;\npub const CLR_DEFAULT: i32 = -16777216i32;\npub const CLR_HILIGHT: i32 = -16777216i32;\npub const CLR_NONE: i32 = -1i32;\npub const CLS_HOT: CLOCKSTATES = 2i32;\npub const CLS_NORMAL: CLOCKSTATES = 1i32;\npub const CLS_PRESSED: CLOCKSTATES = 3i32;\npub const CMB_MASKED: u32 = 2u32;\npub const CMDLGS_DEFAULTED: COMMANDLINKGLYPHSTATES = 5i32;\npub const CMDLGS_DISABLED: COMMANDLINKGLYPHSTATES = 4i32;\npub const CMDLGS_HOT: COMMANDLINKGLYPHSTATES = 2i32;\npub const CMDLGS_NORMAL: COMMANDLINKGLYPHSTATES = 1i32;\npub const CMDLGS_PRESSED: COMMANDLINKGLYPHSTATES = 3i32;\npub const CMDLS_DEFAULTED: COMMANDLINKSTATES = 5i32;\npub const CMDLS_DEFAULTED_ANIMATING: COMMANDLINKSTATES = 6i32;\npub const CMDLS_DISABLED: COMMANDLINKSTATES = 4i32;\npub const CMDLS_HOT: COMMANDLINKSTATES = 2i32;\npub const CMDLS_NORMAL: COMMANDLINKSTATES = 1i32;\npub const CMDLS_PRESSED: COMMANDLINKSTATES = 3i32;\npub type COLLAPSEBUTTONSTATES = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct COLORMAP {\n    pub from: super::super::Foundation::COLORREF,\n    pub to: super::super::Foundation::COLORREF,\n}\npub const COLORMGMTDLGORD: u32 = 1551u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct COLORSCHEME {\n    pub dwSize: u32,\n    pub clrBtnHighlight: super::super::Foundation::COLORREF,\n    pub clrBtnShadow: super::super::Foundation::COLORREF,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct COMBOBOXEXITEMA {\n    pub mask: COMBOBOX_EX_ITEM_FLAGS,\n    pub iItem: isize,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub iSelectedImage: i32,\n    pub iOverlay: i32,\n    pub iIndent: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for COMBOBOXEXITEMA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct COMBOBOXEXITEMW {\n    pub mask: COMBOBOX_EX_ITEM_FLAGS,\n    pub iItem: isize,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub iSelectedImage: i32,\n    pub iOverlay: i32,\n    pub iIndent: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for COMBOBOXEXITEMW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct COMBOBOXINFO {\n    pub cbSize: u32,\n    pub rcItem: super::super::Foundation::RECT,\n    pub rcButton: super::super::Foundation::RECT,\n    pub stateButton: COMBOBOXINFO_BUTTON_STATE,\n    pub hwndCombo: super::super::Foundation::HWND,\n    pub hwndItem: super::super::Foundation::HWND,\n    pub hwndList: super::super::Foundation::HWND,\n}\nimpl Default for COMBOBOXINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type COMBOBOXINFO_BUTTON_STATE = u32;\npub type COMBOBOXPARTS = i32;\npub type COMBOBOXSTYLESTATES = i32;\npub type COMBOBOX_EX_ITEM_FLAGS = u32;\npub const COMCTL32_VERSION: u32 = 6u32;\npub type COMMANDLINKGLYPHSTATES = i32;\npub type COMMANDLINKSTATES = i32;\npub type COMMUNICATIONSPARTS = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct COMPAREITEMSTRUCT {\n    pub CtlType: DRAWITEMSTRUCT_CTL_TYPE,\n    pub CtlID: u32,\n    pub hwndItem: super::super::Foundation::HWND,\n    pub itemID1: u32,\n    pub itemData1: usize,\n    pub itemID2: u32,\n    pub itemData2: usize,\n    pub dwLocaleId: u32,\n}\nimpl Default for COMPAREITEMSTRUCT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type CONTENTALIGNMENT = i32;\npub type CONTENTAREASTATES = i32;\npub type CONTENTLINKSTATES = i32;\npub type CONTENTPANESTATES = i32;\npub type CONTROLLABELSTATES = i32;\npub type CONTROLPANELPARTS = i32;\npub type COPYSTATES = i32;\npub const CPANEL_BANNERAREA: CONTROLPANELPARTS = 18i32;\npub const CPANEL_BODYTEXT: CONTROLPANELPARTS = 6i32;\npub const CPANEL_BODYTITLE: CONTROLPANELPARTS = 19i32;\npub const CPANEL_BUTTON: CONTROLPANELPARTS = 14i32;\npub const CPANEL_CONTENTLINK: CONTROLPANELPARTS = 10i32;\npub const CPANEL_CONTENTPANE: CONTROLPANELPARTS = 2i32;\npub const CPANEL_CONTENTPANELABEL: CONTROLPANELPARTS = 4i32;\npub const CPANEL_CONTENTPANELINE: CONTROLPANELPARTS = 17i32;\npub const CPANEL_GROUPTEXT: CONTROLPANELPARTS = 9i32;\npub const CPANEL_HELPLINK: CONTROLPANELPARTS = 7i32;\npub const CPANEL_LARGECOMMANDAREA: CONTROLPANELPARTS = 12i32;\npub const CPANEL_MESSAGETEXT: CONTROLPANELPARTS = 15i32;\npub const CPANEL_NAVIGATIONPANE: CONTROLPANELPARTS = 1i32;\npub const CPANEL_NAVIGATIONPANELABEL: CONTROLPANELPARTS = 3i32;\npub const CPANEL_NAVIGATIONPANELINE: CONTROLPANELPARTS = 16i32;\npub const CPANEL_SECTIONTITLELINK: CONTROLPANELPARTS = 11i32;\npub const CPANEL_SMALLCOMMANDAREA: CONTROLPANELPARTS = 13i32;\npub const CPANEL_TASKLINK: CONTROLPANELPARTS = 8i32;\npub const CPANEL_TITLE: CONTROLPANELPARTS = 5i32;\npub const CPCL_DISABLED: CONTENTLINKSTATES = 4i32;\npub const CPCL_HOT: CONTENTLINKSTATES = 2i32;\npub const CPCL_NORMAL: CONTENTLINKSTATES = 1i32;\npub const CPCL_PRESSED: CONTENTLINKSTATES = 3i32;\npub const CPHL_DISABLED: HELPLINKSTATES = 4i32;\npub const CPHL_HOT: HELPLINKSTATES = 2i32;\npub const CPHL_NORMAL: HELPLINKSTATES = 1i32;\npub const CPHL_PRESSED: HELPLINKSTATES = 3i32;\npub const CPSTL_HOT: SECTIONTITLELINKSTATES = 2i32;\npub const CPSTL_NORMAL: SECTIONTITLELINKSTATES = 1i32;\npub const CPTL_DISABLED: TASKLINKSTATES = 4i32;\npub const CPTL_HOT: TASKLINKSTATES = 2i32;\npub const CPTL_NORMAL: TASKLINKSTATES = 1i32;\npub const CPTL_PAGE: TASKLINKSTATES = 5i32;\npub const CPTL_PRESSED: TASKLINKSTATES = 3i32;\npub const CP_BACKGROUND: COMBOBOXPARTS = 2i32;\npub const CP_BORDER: COMBOBOXPARTS = 4i32;\npub const CP_CUEBANNER: COMBOBOXPARTS = 8i32;\npub const CP_DROPDOWNBUTTON: COMBOBOXPARTS = 1i32;\npub const CP_DROPDOWNBUTTONLEFT: COMBOBOXPARTS = 7i32;\npub const CP_DROPDOWNBUTTONRIGHT: COMBOBOXPARTS = 6i32;\npub const CP_DROPDOWNITEM: COMBOBOXPARTS = 9i32;\npub const CP_READONLY: COMBOBOXPARTS = 5i32;\npub const CP_TRANSPARENTBACKGROUND: COMBOBOXPARTS = 3i32;\npub type CREATELINKSTATES = i32;\npub const CSST_TAB: COMMUNICATIONSPARTS = 1i32;\npub const CSTB_HOT: TABSTATES = 2i32;\npub const CSTB_NORMAL: TABSTATES = 1i32;\npub const CSTB_SELECTED: TABSTATES = 3i32;\npub const CS_ACTIVE: CAPTIONSTATES = 1i32;\npub const CS_DISABLED: CAPTIONSTATES = 3i32;\npub const CS_INACTIVE: CAPTIONSTATES = 2i32;\npub type CUEBANNERSTATES = i32;\npub type DATEBORDERSTATES = i32;\npub type DATEPICKERPARTS = i32;\npub type DATETEXTSTATES = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DATETIMEPICKERINFO {\n    pub cbSize: u32,\n    pub rcCheck: super::super::Foundation::RECT,\n    pub stateCheck: u32,\n    pub rcButton: super::super::Foundation::RECT,\n    pub stateButton: u32,\n    pub hwndEdit: super::super::Foundation::HWND,\n    pub hwndUD: super::super::Foundation::HWND,\n    pub hwndDropDown: super::super::Foundation::HWND,\n}\nimpl Default for DATETIMEPICKERINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DATETIMEPICK_CLASS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysDateTimePick32\");\npub const DATETIMEPICK_CLASSA: windows_sys::core::PCSTR = windows_sys::core::s!(\"SysDateTimePick32\");\npub const DATETIMEPICK_CLASSW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysDateTimePick32\");\npub const DA_ERR: i32 = -1i32;\npub const DA_LAST: u32 = 2147483647u32;\npub const DDCOPY_HIGHLIGHT: COPYSTATES = 1i32;\npub const DDCOPY_NOHIGHLIGHT: COPYSTATES = 2i32;\npub const DDCREATELINK_HIGHLIGHT: CREATELINKSTATES = 1i32;\npub const DDCREATELINK_NOHIGHLIGHT: CREATELINKSTATES = 2i32;\npub const DDL_ARCHIVE: DLG_DIR_LIST_FILE_TYPE = 32u32;\npub const DDL_DIRECTORY: DLG_DIR_LIST_FILE_TYPE = 16u32;\npub const DDL_DRIVES: DLG_DIR_LIST_FILE_TYPE = 16384u32;\npub const DDL_EXCLUSIVE: DLG_DIR_LIST_FILE_TYPE = 32768u32;\npub const DDL_HIDDEN: DLG_DIR_LIST_FILE_TYPE = 2u32;\npub const DDL_POSTMSGS: DLG_DIR_LIST_FILE_TYPE = 8192u32;\npub const DDL_READONLY: DLG_DIR_LIST_FILE_TYPE = 1u32;\npub const DDL_READWRITE: DLG_DIR_LIST_FILE_TYPE = 0u32;\npub const DDL_SYSTEM: DLG_DIR_LIST_FILE_TYPE = 4u32;\npub const DDMOVE_HIGHLIGHT: MOVESTATES = 1i32;\npub const DDMOVE_NOHIGHLIGHT: MOVESTATES = 2i32;\npub const DDNONE_HIGHLIGHT: NONESTATES = 1i32;\npub const DDNONE_NOHIGHLIGHT: NONESTATES = 2i32;\npub const DDUPDATEMETADATA_HIGHLIGHT: UPDATEMETADATASTATES = 1i32;\npub const DDUPDATEMETADATA_NOHIGHLIGHT: UPDATEMETADATASTATES = 2i32;\npub const DDWARNING_HIGHLIGHT: WARNINGSTATES = 1i32;\npub const DDWARNING_NOHIGHLIGHT: WARNINGSTATES = 2i32;\npub const DD_COPY: DRAGDROPPARTS = 1i32;\npub const DD_CREATELINK: DRAGDROPPARTS = 4i32;\npub const DD_IMAGEBG: DRAGDROPPARTS = 7i32;\npub const DD_MOVE: DRAGDROPPARTS = 2i32;\npub const DD_NONE: DRAGDROPPARTS = 6i32;\npub const DD_TEXTBG: DRAGDROPPARTS = 8i32;\npub const DD_UPDATEMETADATA: DRAGDROPPARTS = 3i32;\npub const DD_WARNING: DRAGDROPPARTS = 5i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DELETEITEMSTRUCT {\n    pub CtlType: DRAWITEMSTRUCT_CTL_TYPE,\n    pub CtlID: u32,\n    pub itemID: u32,\n    pub hwndItem: super::super::Foundation::HWND,\n    pub itemData: usize,\n}\nimpl Default for DELETEITEMSTRUCT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type DLG_BUTTON_CHECK_STATE = u32;\npub type DLG_DIR_LIST_FILE_TYPE = u32;\npub const DL_BEGINDRAG: DRAGLISTINFO_NOTIFICATION_FLAGS = 1157u32;\npub const DL_CANCELDRAG: DRAGLISTINFO_NOTIFICATION_FLAGS = 1160u32;\npub const DL_COPYCURSOR: u32 = 2u32;\npub const DL_CURSORSET: u32 = 0u32;\npub const DL_DRAGGING: DRAGLISTINFO_NOTIFICATION_FLAGS = 1158u32;\npub const DL_DROPPED: DRAGLISTINFO_NOTIFICATION_FLAGS = 1159u32;\npub const DL_MOVECURSOR: u32 = 3u32;\npub const DL_STOPCURSOR: u32 = 1u32;\npub const DNHZS_DISABLED: DOWNHORZSTATES = 4i32;\npub const DNHZS_HOT: DOWNHORZSTATES = 2i32;\npub const DNHZS_NORMAL: DOWNHORZSTATES = 1i32;\npub const DNHZS_PRESSED: DOWNHORZSTATES = 3i32;\npub const DNS_DISABLED: DOWNSTATES = 4i32;\npub const DNS_HOT: DOWNSTATES = 2i32;\npub const DNS_NORMAL: DOWNSTATES = 1i32;\npub const DNS_PRESSED: DOWNSTATES = 3i32;\npub type DOWNHORZSTATES = i32;\npub type DOWNSTATES = i32;\npub const DPAMM_DELETE: DPAMM_MESSAGE = 2u32;\npub const DPAMM_INSERT: DPAMM_MESSAGE = 3u32;\npub const DPAMM_MERGE: DPAMM_MESSAGE = 1u32;\npub type DPAMM_MESSAGE = u32;\npub const DPAM_INTERSECT: u32 = 8u32;\npub const DPAM_NORMAL: u32 = 2u32;\npub const DPAM_SORTED: u32 = 1u32;\npub const DPAM_UNION: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DPASTREAMINFO {\n    pub iPos: i32,\n    pub pvItem: *mut core::ffi::c_void,\n}\nimpl Default for DPASTREAMINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const DPAS_INSERTAFTER: u32 = 4u32;\npub const DPAS_INSERTBEFORE: u32 = 2u32;\npub const DPAS_SORTED: u32 = 1u32;\npub const DPA_APPEND: u32 = 2147483647u32;\npub const DPA_ERR: i32 = -1i32;\npub const DPDB_DISABLED: DATEBORDERSTATES = 4i32;\npub const DPDB_FOCUSED: DATEBORDERSTATES = 3i32;\npub const DPDB_HOT: DATEBORDERSTATES = 2i32;\npub const DPDB_NORMAL: DATEBORDERSTATES = 1i32;\npub const DPDT_DISABLED: DATETEXTSTATES = 2i32;\npub const DPDT_NORMAL: DATETEXTSTATES = 1i32;\npub const DPDT_SELECTED: DATETEXTSTATES = 3i32;\npub const DPSCBR_DISABLED: SHOWCALENDARBUTTONRIGHTSTATES = 4i32;\npub const DPSCBR_HOT: SHOWCALENDARBUTTONRIGHTSTATES = 2i32;\npub const DPSCBR_NORMAL: SHOWCALENDARBUTTONRIGHTSTATES = 1i32;\npub const DPSCBR_PRESSED: SHOWCALENDARBUTTONRIGHTSTATES = 3i32;\npub const DP_DATEBORDER: DATEPICKERPARTS = 2i32;\npub const DP_DATETEXT: DATEPICKERPARTS = 1i32;\npub const DP_SHOWCALENDARBUTTONRIGHT: DATEPICKERPARTS = 3i32;\npub type DRAGDROPPARTS = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct DRAGLISTINFO {\n    pub uNotification: DRAGLISTINFO_NOTIFICATION_FLAGS,\n    pub hWnd: super::super::Foundation::HWND,\n    pub ptCursor: super::super::Foundation::POINT,\n}\nimpl Default for DRAGLISTINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type DRAGLISTINFO_NOTIFICATION_FLAGS = u32;\npub const DRAGLISTMSGSTRING: windows_sys::core::PCWSTR = windows_sys::core::w!(\"commctrl_DragListMsg\");\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct DRAWITEMSTRUCT {\n    pub CtlType: DRAWITEMSTRUCT_CTL_TYPE,\n    pub CtlID: u32,\n    pub itemID: u32,\n    pub itemAction: ODA_FLAGS,\n    pub itemState: ODS_FLAGS,\n    pub hwndItem: super::super::Foundation::HWND,\n    pub hDC: super::super::Graphics::Gdi::HDC,\n    pub rcItem: super::super::Foundation::RECT,\n    pub itemData: usize,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for DRAWITEMSTRUCT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type DRAWITEMSTRUCT_CTL_TYPE = u32;\npub type DRAW_THEME_PARENT_BACKGROUND_FLAGS = u32;\npub type DROPDOWNBUTTONLEFTSTATES = i32;\npub type DROPDOWNBUTTONRIGHTSTATES = i32;\npub type DROPDOWNITEMSTATES = i32;\npub const DSA_APPEND: u32 = 2147483647u32;\npub const DSA_ERR: i32 = -1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct DTBGOPTS {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub rcClip: super::super::Foundation::RECT,\n}\npub const DTBG_CLIPRECT: u32 = 1u32;\npub const DTBG_COMPUTINGREGION: u32 = 16u32;\npub const DTBG_DRAWSOLID: u32 = 2u32;\npub const DTBG_MIRRORDC: u32 = 32u32;\npub const DTBG_NOMIRROR: u32 = 64u32;\npub const DTBG_OMITBORDER: u32 = 4u32;\npub const DTBG_OMITCONTENT: u32 = 8u32;\npub const DTM_CLOSEMONTHCAL: u32 = 4109u32;\npub const DTM_FIRST: u32 = 4096u32;\npub const DTM_GETDATETIMEPICKERINFO: u32 = 4110u32;\npub const DTM_GETIDEALSIZE: u32 = 4111u32;\npub const DTM_GETMCCOLOR: u32 = 4103u32;\npub const DTM_GETMCFONT: u32 = 4106u32;\npub const DTM_GETMCSTYLE: u32 = 4108u32;\npub const DTM_GETMONTHCAL: u32 = 4104u32;\npub const DTM_GETRANGE: u32 = 4099u32;\npub const DTM_GETSYSTEMTIME: u32 = 4097u32;\npub const DTM_SETFORMAT: u32 = 4146u32;\npub const DTM_SETFORMATA: u32 = 4101u32;\npub const DTM_SETFORMATW: u32 = 4146u32;\npub const DTM_SETMCCOLOR: u32 = 4102u32;\npub const DTM_SETMCFONT: u32 = 4105u32;\npub const DTM_SETMCSTYLE: u32 = 4107u32;\npub const DTM_SETRANGE: u32 = 4100u32;\npub const DTM_SETSYSTEMTIME: u32 = 4098u32;\npub const DTN_CLOSEUP: u32 = 4294966543u32;\npub const DTN_DATETIMECHANGE: u32 = 4294966537u32;\npub const DTN_DROPDOWN: u32 = 4294966542u32;\npub const DTN_FIRST: u32 = 4294966556u32;\npub const DTN_FIRST2: u32 = 4294966543u32;\npub const DTN_FORMAT: u32 = 4294966553u32;\npub const DTN_FORMATA: u32 = 4294966540u32;\npub const DTN_FORMATQUERY: u32 = 4294966554u32;\npub const DTN_FORMATQUERYA: u32 = 4294966541u32;\npub const DTN_FORMATQUERYW: u32 = 4294966554u32;\npub const DTN_FORMATW: u32 = 4294966553u32;\npub const DTN_LAST: u32 = 4294966551u32;\npub const DTN_LAST2: u32 = 4294966497u32;\npub const DTN_USERSTRING: u32 = 4294966551u32;\npub const DTN_USERSTRINGA: u32 = 4294966538u32;\npub const DTN_USERSTRINGW: u32 = 4294966551u32;\npub const DTN_WMKEYDOWN: u32 = 4294966552u32;\npub const DTN_WMKEYDOWNA: u32 = 4294966539u32;\npub const DTN_WMKEYDOWNW: u32 = 4294966552u32;\npub const DTPB_USECTLCOLORSTATIC: DRAW_THEME_PARENT_BACKGROUND_FLAGS = 2u32;\npub const DTPB_USEERASEBKGND: DRAW_THEME_PARENT_BACKGROUND_FLAGS = 4u32;\npub const DTPB_WINDOWDC: DRAW_THEME_PARENT_BACKGROUND_FLAGS = 1u32;\npub const DTS_APPCANPARSE: u32 = 16u32;\npub const DTS_LONGDATEFORMAT: u32 = 4u32;\npub const DTS_RIGHTALIGN: u32 = 32u32;\npub const DTS_SHORTDATECENTURYFORMAT: u32 = 12u32;\npub const DTS_SHORTDATEFORMAT: u32 = 0u32;\npub const DTS_SHOWNONE: u32 = 2u32;\npub const DTS_TIMEFORMAT: u32 = 9u32;\npub const DTS_UPDOWN: u32 = 1u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct DTTOPTS {\n    pub dwSize: u32,\n    pub dwFlags: DTTOPTS_FLAGS,\n    pub crText: super::super::Foundation::COLORREF,\n    pub crBorder: super::super::Foundation::COLORREF,\n    pub crShadow: super::super::Foundation::COLORREF,\n    pub iTextShadowType: i32,\n    pub ptShadowOffset: super::super::Foundation::POINT,\n    pub iBorderSize: i32,\n    pub iFontPropId: i32,\n    pub iColorPropId: i32,\n    pub iStateId: i32,\n    pub fApplyOverlay: windows_sys::core::BOOL,\n    pub iGlowSize: i32,\n    pub pfnDrawTextCallback: DTT_CALLBACK_PROC,\n    pub lParam: super::super::Foundation::LPARAM,\n}\npub type DTTOPTS_FLAGS = u32;\npub const DTT_APPLYOVERLAY: DTTOPTS_FLAGS = 1024u32;\npub const DTT_BORDERCOLOR: DTTOPTS_FLAGS = 2u32;\npub const DTT_BORDERSIZE: DTTOPTS_FLAGS = 32u32;\npub const DTT_CALCRECT: DTTOPTS_FLAGS = 512u32;\npub const DTT_CALLBACK: DTTOPTS_FLAGS = 4096u32;\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\npub type DTT_CALLBACK_PROC = Option<unsafe extern \"system\" fn(hdc: super::super::Graphics::Gdi::HDC, psztext: windows_sys::core::PWSTR, cchtext: i32, prc: *mut super::super::Foundation::RECT, dwflags: u32, lparam: super::super::Foundation::LPARAM) -> i32>;\npub const DTT_COLORPROP: DTTOPTS_FLAGS = 128u32;\npub const DTT_COMPOSITED: DTTOPTS_FLAGS = 8192u32;\npub const DTT_FLAGS2VALIDBITS: u32 = 1u32;\npub const DTT_FONTPROP: DTTOPTS_FLAGS = 64u32;\npub const DTT_GLOWSIZE: DTTOPTS_FLAGS = 2048u32;\npub const DTT_GRAYED: u32 = 1u32;\npub const DTT_SHADOWCOLOR: DTTOPTS_FLAGS = 4u32;\npub const DTT_SHADOWOFFSET: DTTOPTS_FLAGS = 16u32;\npub const DTT_SHADOWTYPE: DTTOPTS_FLAGS = 8u32;\npub const DTT_STATEID: DTTOPTS_FLAGS = 256u32;\npub const DTT_TEXTCOLOR: DTTOPTS_FLAGS = 1u32;\npub const DTT_VALIDBITS: DTTOPTS_FLAGS = 12287u32;\npub const EBHC_HOT: HEADERCLOSESTATES = 2i32;\npub const EBHC_NORMAL: HEADERCLOSESTATES = 1i32;\npub const EBHC_PRESSED: HEADERCLOSESTATES = 3i32;\npub const EBHP_HOT: HEADERPINSTATES = 2i32;\npub const EBHP_NORMAL: HEADERPINSTATES = 1i32;\npub const EBHP_PRESSED: HEADERPINSTATES = 3i32;\npub const EBHP_SELECTEDHOT: HEADERPINSTATES = 5i32;\npub const EBHP_SELECTEDNORMAL: HEADERPINSTATES = 4i32;\npub const EBHP_SELECTEDPRESSED: HEADERPINSTATES = 6i32;\npub const EBM_HOT: IEBARMENUSTATES = 2i32;\npub const EBM_NORMAL: IEBARMENUSTATES = 1i32;\npub const EBM_PRESSED: IEBARMENUSTATES = 3i32;\npub const EBNGC_HOT: NORMALGROUPCOLLAPSESTATES = 2i32;\npub const EBNGC_NORMAL: NORMALGROUPCOLLAPSESTATES = 1i32;\npub const EBNGC_PRESSED: NORMALGROUPCOLLAPSESTATES = 3i32;\npub const EBNGE_HOT: NORMALGROUPEXPANDSTATES = 2i32;\npub const EBNGE_NORMAL: NORMALGROUPEXPANDSTATES = 1i32;\npub const EBNGE_PRESSED: NORMALGROUPEXPANDSTATES = 3i32;\npub const EBP_HEADERBACKGROUND: EXPLORERBARPARTS = 1i32;\npub const EBP_HEADERCLOSE: EXPLORERBARPARTS = 2i32;\npub const EBP_HEADERPIN: EXPLORERBARPARTS = 3i32;\npub const EBP_IEBARMENU: EXPLORERBARPARTS = 4i32;\npub const EBP_NORMALGROUPBACKGROUND: EXPLORERBARPARTS = 5i32;\npub const EBP_NORMALGROUPCOLLAPSE: EXPLORERBARPARTS = 6i32;\npub const EBP_NORMALGROUPEXPAND: EXPLORERBARPARTS = 7i32;\npub const EBP_NORMALGROUPHEAD: EXPLORERBARPARTS = 8i32;\npub const EBP_SPECIALGROUPBACKGROUND: EXPLORERBARPARTS = 9i32;\npub const EBP_SPECIALGROUPCOLLAPSE: EXPLORERBARPARTS = 10i32;\npub const EBP_SPECIALGROUPEXPAND: EXPLORERBARPARTS = 11i32;\npub const EBP_SPECIALGROUPHEAD: EXPLORERBARPARTS = 12i32;\npub const EBSGC_HOT: SPECIALGROUPCOLLAPSESTATES = 2i32;\npub const EBSGC_NORMAL: SPECIALGROUPCOLLAPSESTATES = 1i32;\npub const EBSGC_PRESSED: SPECIALGROUPCOLLAPSESTATES = 3i32;\npub const EBSGE_HOT: SPECIALGROUPEXPANDSTATES = 2i32;\npub const EBSGE_NORMAL: SPECIALGROUPEXPANDSTATES = 1i32;\npub const EBSGE_PRESSED: SPECIALGROUPEXPANDSTATES = 3i32;\npub const EBS_ASSIST: BACKGROUNDSTATES = 6i32;\npub const EBS_DISABLED: BACKGROUNDSTATES = 3i32;\npub const EBS_FOCUSED: BACKGROUNDSTATES = 4i32;\npub const EBS_HOT: BACKGROUNDSTATES = 2i32;\npub const EBS_NORMAL: BACKGROUNDSTATES = 1i32;\npub const EBS_READONLY: BACKGROUNDSTATES = 5i32;\npub const EBWBS_DISABLED: BACKGROUNDWITHBORDERSTATES = 3i32;\npub const EBWBS_FOCUSED: BACKGROUNDWITHBORDERSTATES = 4i32;\npub const EBWBS_HOT: BACKGROUNDWITHBORDERSTATES = 2i32;\npub const EBWBS_NORMAL: BACKGROUNDWITHBORDERSTATES = 1i32;\npub const ECM_FIRST: u32 = 5376u32;\npub type EC_ENDOFLINE = i32;\npub const EC_ENDOFLINE_CR: EC_ENDOFLINE = 2i32;\npub const EC_ENDOFLINE_CRLF: EC_ENDOFLINE = 1i32;\npub const EC_ENDOFLINE_DETECTFROMCONTENT: EC_ENDOFLINE = 0i32;\npub const EC_ENDOFLINE_LF: EC_ENDOFLINE = 3i32;\npub type EC_SEARCHWEB_ENTRYPOINT = i32;\npub const EC_SEARCHWEB_ENTRYPOINT_CONTEXTMENU: EC_SEARCHWEB_ENTRYPOINT = 1i32;\npub const EC_SEARCHWEB_ENTRYPOINT_EXTERNAL: EC_SEARCHWEB_ENTRYPOINT = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct EDITBALLOONTIP {\n    pub cbStruct: u32,\n    pub pszTitle: windows_sys::core::PCWSTR,\n    pub pszText: windows_sys::core::PCWSTR,\n    pub ttiIcon: EDITBALLOONTIP_ICON,\n}\nimpl Default for EDITBALLOONTIP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type EDITBALLOONTIP_ICON = i32;\npub type EDITBORDER_HSCROLLSTATES = i32;\npub type EDITBORDER_HVSCROLLSTATES = i32;\npub type EDITBORDER_NOSCROLLSTATES = i32;\npub type EDITBORDER_VSCROLLSTATES = i32;\npub type EDITPARTS = i32;\npub type EDITTEXTSTATES = i32;\npub type EDITWORDBREAKPROCA = Option<unsafe extern \"system\" fn(lpch: windows_sys::core::PCSTR, ichcurrent: i32, cch: i32, code: WORD_BREAK_ACTION) -> i32>;\npub type EDITWORDBREAKPROCW = Option<unsafe extern \"system\" fn(lpch: windows_sys::core::PCWSTR, ichcurrent: i32, cch: i32, code: WORD_BREAK_ACTION) -> i32>;\npub const EMF_CENTERED: NMLVEMPTYMARKUP_FLAGS = 1u32;\npub type EMPTYMARKUPPARTS = i32;\npub const EMP_MARKUPTEXT: EMPTYMARKUPPARTS = 1i32;\npub const EMT_LINKTEXT: MARKUPTEXTSTATES = 2i32;\npub const EMT_NORMALTEXT: MARKUPTEXTSTATES = 1i32;\npub const EM_CANUNDO: u32 = 198u32;\npub const EM_CHARFROMPOS: u32 = 215u32;\npub const EM_EMPTYUNDOBUFFER: u32 = 205u32;\npub const EM_ENABLEFEATURE: u32 = 218u32;\npub const EM_ENABLESEARCHWEB: u32 = 5390u32;\npub const EM_FILELINEFROMCHAR: u32 = 5395u32;\npub const EM_FILELINEINDEX: u32 = 5396u32;\npub const EM_FILELINELENGTH: u32 = 5397u32;\npub const EM_FMTLINES: u32 = 200u32;\npub const EM_GETCARETINDEX: u32 = 5394u32;\npub const EM_GETCUEBANNER: u32 = 5378u32;\npub const EM_GETENDOFLINE: u32 = 5389u32;\npub const EM_GETEXTENDEDSTYLE: u32 = 5387u32;\npub const EM_GETFILELINE: u32 = 5398u32;\npub const EM_GETFILELINECOUNT: u32 = 5399u32;\npub const EM_GETFIRSTVISIBLELINE: u32 = 206u32;\npub const EM_GETHANDLE: u32 = 189u32;\npub const EM_GETHILITE: u32 = 5382u32;\npub const EM_GETIMESTATUS: u32 = 217u32;\npub const EM_GETLIMITTEXT: u32 = 213u32;\npub const EM_GETLINE: u32 = 196u32;\npub const EM_GETLINECOUNT: u32 = 186u32;\npub const EM_GETMARGINS: u32 = 212u32;\npub const EM_GETMODIFY: u32 = 184u32;\npub const EM_GETPASSWORDCHAR: u32 = 210u32;\npub const EM_GETRECT: u32 = 178u32;\npub const EM_GETSEL: u32 = 176u32;\npub const EM_GETTHUMB: u32 = 190u32;\npub const EM_GETWORDBREAKPROC: u32 = 209u32;\npub const EM_HIDEBALLOONTIP: u32 = 5380u32;\npub const EM_LIMITTEXT: u32 = 197u32;\npub const EM_LINEFROMCHAR: u32 = 201u32;\npub const EM_LINEINDEX: u32 = 187u32;\npub const EM_LINELENGTH: u32 = 193u32;\npub const EM_LINESCROLL: u32 = 182u32;\npub const EM_NOSETFOCUS: u32 = 5383u32;\npub const EM_POSFROMCHAR: u32 = 214u32;\npub const EM_REPLACESEL: u32 = 194u32;\npub const EM_SCROLL: u32 = 181u32;\npub const EM_SCROLLCARET: u32 = 183u32;\npub const EM_SEARCHWEB: u32 = 5391u32;\npub const EM_SETCARETINDEX: u32 = 5393u32;\npub const EM_SETCUEBANNER: u32 = 5377u32;\npub const EM_SETENDOFLINE: u32 = 5388u32;\npub const EM_SETEXTENDEDSTYLE: u32 = 5386u32;\npub const EM_SETHANDLE: u32 = 188u32;\npub const EM_SETHILITE: u32 = 5381u32;\npub const EM_SETIMESTATUS: u32 = 216u32;\npub const EM_SETLIMITTEXT: u32 = 197u32;\npub const EM_SETMARGINS: u32 = 211u32;\npub const EM_SETMODIFY: u32 = 185u32;\npub const EM_SETPASSWORDCHAR: u32 = 204u32;\npub const EM_SETREADONLY: u32 = 207u32;\npub const EM_SETRECT: u32 = 179u32;\npub const EM_SETRECTNP: u32 = 180u32;\npub const EM_SETSEL: u32 = 177u32;\npub const EM_SETTABSTOPS: u32 = 203u32;\npub const EM_SETWORDBREAKPROC: u32 = 208u32;\npub const EM_SHOWBALLOONTIP: u32 = 5379u32;\npub const EM_TAKEFOCUS: u32 = 5384u32;\npub const EM_UNDO: u32 = 199u32;\npub type ENABLE_SCROLL_BAR_ARROWS = u32;\npub const EN_FIRST: u32 = 4294965776u32;\npub const EN_LAST: u32 = 4294965756u32;\npub const EN_SEARCHWEB: u32 = 4294965776u32;\npub const EPSHV_DISABLED: EDITBORDER_HVSCROLLSTATES = 4i32;\npub const EPSHV_FOCUSED: EDITBORDER_HVSCROLLSTATES = 3i32;\npub const EPSHV_HOT: EDITBORDER_HVSCROLLSTATES = 2i32;\npub const EPSHV_NORMAL: EDITBORDER_HVSCROLLSTATES = 1i32;\npub const EPSH_DISABLED: EDITBORDER_HSCROLLSTATES = 4i32;\npub const EPSH_FOCUSED: EDITBORDER_HSCROLLSTATES = 3i32;\npub const EPSH_HOT: EDITBORDER_HSCROLLSTATES = 2i32;\npub const EPSH_NORMAL: EDITBORDER_HSCROLLSTATES = 1i32;\npub const EPSN_DISABLED: EDITBORDER_NOSCROLLSTATES = 4i32;\npub const EPSN_FOCUSED: EDITBORDER_NOSCROLLSTATES = 3i32;\npub const EPSN_HOT: EDITBORDER_NOSCROLLSTATES = 2i32;\npub const EPSN_NORMAL: EDITBORDER_NOSCROLLSTATES = 1i32;\npub const EPSV_DISABLED: EDITBORDER_VSCROLLSTATES = 4i32;\npub const EPSV_FOCUSED: EDITBORDER_VSCROLLSTATES = 3i32;\npub const EPSV_HOT: EDITBORDER_VSCROLLSTATES = 2i32;\npub const EPSV_NORMAL: EDITBORDER_VSCROLLSTATES = 1i32;\npub const EP_BACKGROUND: EDITPARTS = 3i32;\npub const EP_BACKGROUNDWITHBORDER: EDITPARTS = 5i32;\npub const EP_CARET: EDITPARTS = 2i32;\npub const EP_EDITBORDER_HSCROLL: EDITPARTS = 7i32;\npub const EP_EDITBORDER_HVSCROLL: EDITPARTS = 9i32;\npub const EP_EDITBORDER_NOSCROLL: EDITPARTS = 6i32;\npub const EP_EDITBORDER_VSCROLL: EDITPARTS = 8i32;\npub const EP_EDITTEXT: EDITPARTS = 1i32;\npub const EP_PASSWORD: EDITPARTS = 4i32;\npub const ESB_DISABLE_BOTH: ENABLE_SCROLL_BAR_ARROWS = 3u32;\npub const ESB_DISABLE_DOWN: ENABLE_SCROLL_BAR_ARROWS = 2u32;\npub const ESB_DISABLE_LEFT: ENABLE_SCROLL_BAR_ARROWS = 1u32;\npub const ESB_DISABLE_LTUP: ENABLE_SCROLL_BAR_ARROWS = 1u32;\npub const ESB_DISABLE_RIGHT: ENABLE_SCROLL_BAR_ARROWS = 2u32;\npub const ESB_DISABLE_RTDN: ENABLE_SCROLL_BAR_ARROWS = 2u32;\npub const ESB_DISABLE_UP: ENABLE_SCROLL_BAR_ARROWS = 1u32;\npub const ESB_ENABLE_BOTH: ENABLE_SCROLL_BAR_ARROWS = 0u32;\npub const ES_EX_ALLOWEOL_CR: i32 = 1i32;\npub const ES_EX_ALLOWEOL_LF: i32 = 2i32;\npub const ES_EX_CONVERT_EOL_ON_PASTE: i32 = 4i32;\npub const ES_EX_ZOOMABLE: i32 = 16i32;\npub const ETDT_DISABLE: u32 = 1u32;\npub const ETDT_ENABLE: u32 = 2u32;\npub const ETDT_USEAEROWIZARDTABTEXTURE: u32 = 8u32;\npub const ETDT_USETABTEXTURE: u32 = 4u32;\npub const ETS_ASSIST: EDITTEXTSTATES = 7i32;\npub const ETS_CUEBANNER: EDITTEXTSTATES = 8i32;\npub const ETS_DISABLED: EDITTEXTSTATES = 4i32;\npub const ETS_FOCUSED: EDITTEXTSTATES = 5i32;\npub const ETS_HOT: EDITTEXTSTATES = 2i32;\npub const ETS_NORMAL: EDITTEXTSTATES = 1i32;\npub const ETS_READONLY: EDITTEXTSTATES = 6i32;\npub const ETS_SELECTED: EDITTEXTSTATES = 3i32;\npub type EXPANDBUTTONSTATES = i32;\npub type EXPANDOBUTTONSTATES = i32;\npub type EXPLORERBARPARTS = i32;\npub const FBS_EMPHASIZED: BODYSTATES = 2i32;\npub const FBS_NORMAL: BODYSTATES = 1i32;\npub const FEEDBACK_GESTURE_PRESSANDTAP: FEEDBACK_TYPE = 11i32;\npub const FEEDBACK_MAX: FEEDBACK_TYPE = -1i32;\npub const FEEDBACK_PEN_BARRELVISUALIZATION: FEEDBACK_TYPE = 2i32;\npub const FEEDBACK_PEN_DOUBLETAP: FEEDBACK_TYPE = 4i32;\npub const FEEDBACK_PEN_PRESSANDHOLD: FEEDBACK_TYPE = 5i32;\npub const FEEDBACK_PEN_RIGHTTAP: FEEDBACK_TYPE = 6i32;\npub const FEEDBACK_PEN_TAP: FEEDBACK_TYPE = 3i32;\npub const FEEDBACK_TOUCH_CONTACTVISUALIZATION: FEEDBACK_TYPE = 1i32;\npub const FEEDBACK_TOUCH_DOUBLETAP: FEEDBACK_TYPE = 8i32;\npub const FEEDBACK_TOUCH_PRESSANDHOLD: FEEDBACK_TYPE = 9i32;\npub const FEEDBACK_TOUCH_RIGHTTAP: FEEDBACK_TYPE = 10i32;\npub const FEEDBACK_TOUCH_TAP: FEEDBACK_TYPE = 7i32;\npub type FEEDBACK_TYPE = i32;\npub const FILEOPENORD: u32 = 1536u32;\npub type FILLSTATES = i32;\npub type FILLTYPE = i32;\npub type FILLVERTSTATES = i32;\npub const FINDDLGORD: u32 = 1540u32;\npub const FLH_HOVER: LINKHEADERSTATES = 2i32;\npub const FLH_NORMAL: LINKHEADERSTATES = 1i32;\npub const FLS_DISABLED: LABELSTATES = 4i32;\npub const FLS_EMPHASIZED: LABELSTATES = 3i32;\npub const FLS_NORMAL: LABELSTATES = 1i32;\npub const FLS_SELECTED: LABELSTATES = 2i32;\npub const FLYOUTLINK_HOVER: LINKSTATES = 2i32;\npub const FLYOUTLINK_NORMAL: LINKSTATES = 1i32;\npub type FLYOUTPARTS = i32;\npub const FLYOUT_BODY: FLYOUTPARTS = 2i32;\npub const FLYOUT_DIVIDER: FLYOUTPARTS = 5i32;\npub const FLYOUT_HEADER: FLYOUTPARTS = 1i32;\npub const FLYOUT_LABEL: FLYOUTPARTS = 3i32;\npub const FLYOUT_LINK: FLYOUTPARTS = 4i32;\npub const FLYOUT_LINKAREA: FLYOUTPARTS = 7i32;\npub const FLYOUT_LINKHEADER: FLYOUTPARTS = 8i32;\npub const FLYOUT_WINDOW: FLYOUTPARTS = 6i32;\npub const FONTDLGORD: u32 = 1542u32;\npub const FORMATDLGORD30: u32 = 1544u32;\npub const FORMATDLGORD31: u32 = 1543u32;\npub type FRAMEBOTTOMSTATES = i32;\npub type FRAMELEFTSTATES = i32;\npub type FRAMERIGHTSTATES = i32;\npub type FRAMESTATES = i32;\npub const FRB_ACTIVE: FRAMEBOTTOMSTATES = 1i32;\npub const FRB_INACTIVE: FRAMEBOTTOMSTATES = 2i32;\npub const FRL_ACTIVE: FRAMELEFTSTATES = 1i32;\npub const FRL_INACTIVE: FRAMELEFTSTATES = 2i32;\npub const FRR_ACTIVE: FRAMERIGHTSTATES = 1i32;\npub const FRR_INACTIVE: FRAMERIGHTSTATES = 2i32;\npub const FSB_ENCARTA_MODE: u32 = 1u32;\npub const FSB_FLAT_MODE: u32 = 2u32;\npub const FSB_REGULAR_MODE: u32 = 0u32;\npub const FS_ACTIVE: FRAMESTATES = 1i32;\npub const FS_INACTIVE: FRAMESTATES = 2i32;\npub const FT_HORZGRADIENT: FILLTYPE = 2i32;\npub const FT_RADIALGRADIENT: FILLTYPE = 3i32;\npub const FT_SOLID: FILLTYPE = 0i32;\npub const FT_TILEIMAGE: FILLTYPE = 4i32;\npub const FT_VERTGRADIENT: FILLTYPE = 1i32;\npub const GBF_COPY: GET_THEME_BITMAP_FLAGS = 2u32;\npub const GBF_DIRECT: GET_THEME_BITMAP_FLAGS = 1u32;\npub const GBF_VALIDBITS: GET_THEME_BITMAP_FLAGS = 3u32;\npub const GBS_DISABLED: GROUPBOXSTATES = 2i32;\npub const GBS_NORMAL: GROUPBOXSTATES = 1i32;\npub const GDTR_MAX: u32 = 2u32;\npub const GDTR_MIN: u32 = 1u32;\npub const GDT_ERROR: i32 = -1i32;\npub const GDT_NONE: NMDATETIMECHANGE_FLAGS = 1u32;\npub const GDT_VALID: NMDATETIMECHANGE_FLAGS = 0u32;\npub type GET_THEME_BITMAP_FLAGS = u32;\npub const GFST_DPI: GLYPHFONTSIZINGTYPE = 2i32;\npub const GFST_NONE: GLYPHFONTSIZINGTYPE = 0i32;\npub const GFST_SIZE: GLYPHFONTSIZINGTYPE = 1i32;\npub const GLPS_CLOSED: GLYPHSTATES = 1i32;\npub const GLPS_OPENED: GLYPHSTATES = 2i32;\npub type GLYPHFONTSIZINGTYPE = i32;\npub type GLYPHSTATES = i32;\npub type GLYPHTYPE = i32;\npub const GMR_DAYSTATE: u32 = 1u32;\npub const GMR_VISIBLE: u32 = 0u32;\npub type GRIDCELLBACKGROUNDSTATES = i32;\npub type GRIDCELLSTATES = i32;\npub type GRIDCELLUPPERSTATES = i32;\npub type GRIPPERSTATES = i32;\npub type GROUPBOXSTATES = i32;\npub type GROUPHEADERLINESTATES = i32;\npub type GROUPHEADERSTATES = i32;\npub const GT_FONTGLYPH: GLYPHTYPE = 2i32;\npub const GT_IMAGEGLYPH: GLYPHTYPE = 1i32;\npub const GT_NONE: GLYPHTYPE = 0i32;\npub type HALIGN = i32;\npub const HA_CENTER: HALIGN = 1i32;\npub const HA_LEFT: HALIGN = 0i32;\npub const HA_RIGHT: HALIGN = 2i32;\npub const HBG_DETAILS: HEADERSTYLESTATES = 1i32;\npub const HBG_ICON: HEADERSTYLESTATES = 2i32;\npub const HBS_DISABLED: HELPBUTTONSTATES = 4i32;\npub const HBS_HOT: HELPBUTTONSTATES = 2i32;\npub const HBS_NORMAL: HELPBUTTONSTATES = 1i32;\npub const HBS_PUSHED: HELPBUTTONSTATES = 3i32;\npub const HDDFS_HOT: HEADERDROPDOWNFILTERSTATES = 3i32;\npub const HDDFS_NORMAL: HEADERDROPDOWNFILTERSTATES = 1i32;\npub const HDDFS_SOFTHOT: HEADERDROPDOWNFILTERSTATES = 2i32;\npub const HDDS_HOT: HEADERDROPDOWNSTATES = 3i32;\npub const HDDS_NORMAL: HEADERDROPDOWNSTATES = 1i32;\npub const HDDS_SOFTHOT: HEADERDROPDOWNSTATES = 2i32;\npub const HDFT_HASNOVALUE: HEADER_CONTROL_FORMAT_TYPE = 32768u32;\npub const HDFT_ISDATE: HEADER_CONTROL_FORMAT_TYPE = 2u32;\npub const HDFT_ISNUMBER: HEADER_CONTROL_FORMAT_TYPE = 1u32;\npub const HDFT_ISSTRING: HEADER_CONTROL_FORMAT_TYPE = 0u32;\npub const HDF_BITMAP: HEADER_CONTROL_FORMAT_FLAGS = 8192i32;\npub const HDF_BITMAP_ON_RIGHT: HEADER_CONTROL_FORMAT_FLAGS = 4096i32;\npub const HDF_CENTER: HEADER_CONTROL_FORMAT_FLAGS = 2i32;\npub const HDF_CHECKBOX: HEADER_CONTROL_FORMAT_FLAGS = 64i32;\npub const HDF_CHECKED: HEADER_CONTROL_FORMAT_FLAGS = 128i32;\npub const HDF_FIXEDWIDTH: HEADER_CONTROL_FORMAT_FLAGS = 256i32;\npub const HDF_IMAGE: HEADER_CONTROL_FORMAT_FLAGS = 2048i32;\npub const HDF_JUSTIFYMASK: HEADER_CONTROL_FORMAT_FLAGS = 3i32;\npub const HDF_LEFT: HEADER_CONTROL_FORMAT_FLAGS = 0i32;\npub const HDF_OWNERDRAW: HEADER_CONTROL_FORMAT_FLAGS = 32768i32;\npub const HDF_RIGHT: HEADER_CONTROL_FORMAT_FLAGS = 1i32;\npub const HDF_RTLREADING: HEADER_CONTROL_FORMAT_FLAGS = 4i32;\npub const HDF_SORTDOWN: HEADER_CONTROL_FORMAT_FLAGS = 512i32;\npub const HDF_SORTUP: HEADER_CONTROL_FORMAT_FLAGS = 1024i32;\npub const HDF_SPLITBUTTON: HEADER_CONTROL_FORMAT_FLAGS = 16777216i32;\npub const HDF_STRING: HEADER_CONTROL_FORMAT_FLAGS = 16384i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct HDHITTESTINFO {\n    pub pt: super::super::Foundation::POINT,\n    pub flags: HEADER_HITTEST_INFO_FLAGS,\n    pub iItem: i32,\n}\npub const HDIS_FOCUSED: HEADER_CONTROL_FORMAT_STATE = 1u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct HDITEMA {\n    pub mask: HDI_MASK,\n    pub cxy: i32,\n    pub pszText: windows_sys::core::PSTR,\n    pub hbm: super::super::Graphics::Gdi::HBITMAP,\n    pub cchTextMax: i32,\n    pub fmt: HEADER_CONTROL_FORMAT_FLAGS,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub iImage: i32,\n    pub iOrder: i32,\n    pub r#type: HEADER_CONTROL_FORMAT_TYPE,\n    pub pvFilter: *mut core::ffi::c_void,\n    pub state: HEADER_CONTROL_FORMAT_STATE,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for HDITEMA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct HDITEMW {\n    pub mask: HDI_MASK,\n    pub cxy: i32,\n    pub pszText: windows_sys::core::PWSTR,\n    pub hbm: super::super::Graphics::Gdi::HBITMAP,\n    pub cchTextMax: i32,\n    pub fmt: HEADER_CONTROL_FORMAT_FLAGS,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub iImage: i32,\n    pub iOrder: i32,\n    pub r#type: HEADER_CONTROL_FORMAT_TYPE,\n    pub pvFilter: *mut core::ffi::c_void,\n    pub state: HEADER_CONTROL_FORMAT_STATE,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for HDITEMW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const HDI_BITMAP: HDI_MASK = 16u32;\npub const HDI_DI_SETITEM: HDI_MASK = 64u32;\npub const HDI_FILTER: HDI_MASK = 256u32;\npub const HDI_FORMAT: HDI_MASK = 4u32;\npub const HDI_HEIGHT: HDI_MASK = 1u32;\npub const HDI_IMAGE: HDI_MASK = 32u32;\npub const HDI_LPARAM: HDI_MASK = 8u32;\npub type HDI_MASK = u32;\npub const HDI_ORDER: HDI_MASK = 128u32;\npub const HDI_STATE: HDI_MASK = 512u32;\npub const HDI_TEXT: HDI_MASK = 2u32;\npub const HDI_WIDTH: HDI_MASK = 1u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\n#[derive(Clone, Copy)]\npub struct HDLAYOUT {\n    pub prc: *mut super::super::Foundation::RECT,\n    pub pwpos: *mut super::WindowsAndMessaging::WINDOWPOS,\n}\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nimpl Default for HDLAYOUT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const HDM_CLEARFILTER: u32 = 4632u32;\npub const HDM_CREATEDRAGIMAGE: u32 = 4624u32;\npub const HDM_DELETEITEM: u32 = 4610u32;\npub const HDM_EDITFILTER: u32 = 4631u32;\npub const HDM_FIRST: u32 = 4608u32;\npub const HDM_GETBITMAPMARGIN: u32 = 4629u32;\npub const HDM_GETFOCUSEDITEM: u32 = 4635u32;\npub const HDM_GETIMAGELIST: u32 = 4617u32;\npub const HDM_GETITEM: u32 = 4619u32;\npub const HDM_GETITEMA: u32 = 4611u32;\npub const HDM_GETITEMCOUNT: u32 = 4608u32;\npub const HDM_GETITEMDROPDOWNRECT: u32 = 4633u32;\npub const HDM_GETITEMRECT: u32 = 4615u32;\npub const HDM_GETITEMW: u32 = 4619u32;\npub const HDM_GETORDERARRAY: u32 = 4625u32;\npub const HDM_GETOVERFLOWRECT: u32 = 4634u32;\npub const HDM_GETUNICODEFORMAT: u32 = 8198u32;\npub const HDM_HITTEST: u32 = 4614u32;\npub const HDM_INSERTITEM: u32 = 4618u32;\npub const HDM_INSERTITEMA: u32 = 4609u32;\npub const HDM_INSERTITEMW: u32 = 4618u32;\npub const HDM_LAYOUT: u32 = 4613u32;\npub const HDM_ORDERTOINDEX: u32 = 4623u32;\npub const HDM_SETBITMAPMARGIN: u32 = 4628u32;\npub const HDM_SETFILTERCHANGETIMEOUT: u32 = 4630u32;\npub const HDM_SETFOCUSEDITEM: u32 = 4636u32;\npub const HDM_SETHOTDIVIDER: u32 = 4627u32;\npub const HDM_SETIMAGELIST: u32 = 4616u32;\npub const HDM_SETITEM: u32 = 4620u32;\npub const HDM_SETITEMA: u32 = 4612u32;\npub const HDM_SETITEMW: u32 = 4620u32;\npub const HDM_SETORDERARRAY: u32 = 4626u32;\npub const HDM_SETUNICODEFORMAT: u32 = 8197u32;\npub const HDN_BEGINDRAG: u32 = 4294966986u32;\npub const HDN_BEGINFILTEREDIT: u32 = 4294966982u32;\npub const HDN_BEGINTRACK: u32 = 4294966970u32;\npub const HDN_BEGINTRACKA: u32 = 4294966990u32;\npub const HDN_BEGINTRACKW: u32 = 4294966970u32;\npub const HDN_DIVIDERDBLCLICK: u32 = 4294966971u32;\npub const HDN_DIVIDERDBLCLICKA: u32 = 4294966991u32;\npub const HDN_DIVIDERDBLCLICKW: u32 = 4294966971u32;\npub const HDN_DROPDOWN: u32 = 4294966978u32;\npub const HDN_ENDDRAG: u32 = 4294966985u32;\npub const HDN_ENDFILTEREDIT: u32 = 4294966981u32;\npub const HDN_ENDTRACK: u32 = 4294966969u32;\npub const HDN_ENDTRACKA: u32 = 4294966989u32;\npub const HDN_ENDTRACKW: u32 = 4294966969u32;\npub const HDN_FILTERBTNCLICK: u32 = 4294966983u32;\npub const HDN_FILTERCHANGE: u32 = 4294966984u32;\npub const HDN_FIRST: u32 = 4294966996u32;\npub const HDN_GETDISPINFO: u32 = 4294966967u32;\npub const HDN_GETDISPINFOA: u32 = 4294966987u32;\npub const HDN_GETDISPINFOW: u32 = 4294966967u32;\npub const HDN_ITEMCHANGED: u32 = 4294966975u32;\npub const HDN_ITEMCHANGEDA: u32 = 4294966995u32;\npub const HDN_ITEMCHANGEDW: u32 = 4294966975u32;\npub const HDN_ITEMCHANGING: u32 = 4294966976u32;\npub const HDN_ITEMCHANGINGA: u32 = 4294966996u32;\npub const HDN_ITEMCHANGINGW: u32 = 4294966976u32;\npub const HDN_ITEMCLICK: u32 = 4294966974u32;\npub const HDN_ITEMCLICKA: u32 = 4294966994u32;\npub const HDN_ITEMCLICKW: u32 = 4294966974u32;\npub const HDN_ITEMDBLCLICK: u32 = 4294966973u32;\npub const HDN_ITEMDBLCLICKA: u32 = 4294966993u32;\npub const HDN_ITEMDBLCLICKW: u32 = 4294966973u32;\npub const HDN_ITEMKEYDOWN: u32 = 4294966979u32;\npub const HDN_ITEMSTATEICONCLICK: u32 = 4294966980u32;\npub const HDN_LAST: u32 = 4294966897u32;\npub const HDN_OVERFLOWCLICK: u32 = 4294966977u32;\npub const HDN_TRACK: u32 = 4294966968u32;\npub const HDN_TRACKA: u32 = 4294966988u32;\npub const HDN_TRACKW: u32 = 4294966968u32;\npub type HDPA = isize;\npub type HDSA = isize;\npub const HDSIL_NORMAL: u32 = 0u32;\npub const HDSIL_STATE: u32 = 1u32;\npub const HDS_BUTTONS: u32 = 2u32;\npub const HDS_CHECKBOXES: u32 = 1024u32;\npub const HDS_DRAGDROP: u32 = 64u32;\npub const HDS_FILTERBAR: u32 = 256u32;\npub const HDS_FLAT: u32 = 512u32;\npub const HDS_FULLDRAG: u32 = 128u32;\npub const HDS_HIDDEN: u32 = 8u32;\npub const HDS_HORZ: u32 = 0u32;\npub const HDS_HOTTRACK: u32 = 4u32;\npub const HDS_NOSIZING: u32 = 2048u32;\npub const HDS_OVERFLOW: u32 = 4096u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct HD_TEXTFILTERA {\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n}\nimpl Default for HD_TEXTFILTERA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct HD_TEXTFILTERW {\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n}\nimpl Default for HD_TEXTFILTERW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type HEADERAREASTATES = i32;\npub type HEADERCLOSESTATES = i32;\npub type HEADERDROPDOWNFILTERSTATES = i32;\npub type HEADERDROPDOWNSTATES = i32;\npub type HEADERITEMLEFTSTATES = i32;\npub type HEADERITEMRIGHTSTATES = i32;\npub type HEADERITEMSTATES = i32;\npub type HEADEROVERFLOWSTATES = i32;\npub type HEADERPARTS = i32;\npub type HEADERPINSTATES = i32;\npub type HEADERSORTARROWSTATES = i32;\npub type HEADERSTYLESTATES = i32;\npub type HEADER_CONTROL_FORMAT_FLAGS = i32;\npub type HEADER_CONTROL_FORMAT_STATE = u32;\npub type HEADER_CONTROL_FORMAT_TYPE = u32;\npub type HEADER_CONTROL_NOTIFICATION_BUTTON = i32;\npub const HEADER_CONTROL_NOTIFICATION_BUTTON_LEFT: HEADER_CONTROL_NOTIFICATION_BUTTON = 0i32;\npub const HEADER_CONTROL_NOTIFICATION_BUTTON_MIDDLE: HEADER_CONTROL_NOTIFICATION_BUTTON = 2i32;\npub const HEADER_CONTROL_NOTIFICATION_BUTTON_RIGHT: HEADER_CONTROL_NOTIFICATION_BUTTON = 1i32;\npub type HEADER_HITTEST_INFO_FLAGS = u32;\npub type HELPBUTTONSTATES = i32;\npub type HELPLINKSTATES = i32;\npub const HGLPS_CLOSED: HOTGLYPHSTATES = 1i32;\npub const HGLPS_OPENED: HOTGLYPHSTATES = 2i32;\npub const HHT_ABOVE: HEADER_HITTEST_INFO_FLAGS = 256u32;\npub const HHT_BELOW: HEADER_HITTEST_INFO_FLAGS = 512u32;\npub const HHT_NOWHERE: HEADER_HITTEST_INFO_FLAGS = 1u32;\npub const HHT_ONDIVIDER: HEADER_HITTEST_INFO_FLAGS = 4u32;\npub const HHT_ONDIVOPEN: HEADER_HITTEST_INFO_FLAGS = 8u32;\npub const HHT_ONDROPDOWN: HEADER_HITTEST_INFO_FLAGS = 8192u32;\npub const HHT_ONFILTER: HEADER_HITTEST_INFO_FLAGS = 16u32;\npub const HHT_ONFILTERBUTTON: HEADER_HITTEST_INFO_FLAGS = 32u32;\npub const HHT_ONHEADER: HEADER_HITTEST_INFO_FLAGS = 2u32;\npub const HHT_ONITEMSTATEICON: HEADER_HITTEST_INFO_FLAGS = 4096u32;\npub const HHT_ONOVERFLOW: HEADER_HITTEST_INFO_FLAGS = 16384u32;\npub const HHT_TOLEFT: HEADER_HITTEST_INFO_FLAGS = 2048u32;\npub const HHT_TORIGHT: HEADER_HITTEST_INFO_FLAGS = 1024u32;\npub const HICF_ACCELERATOR: NMTBHOTITEM_FLAGS = 4u32;\npub const HICF_ARROWKEYS: NMTBHOTITEM_FLAGS = 2u32;\npub const HICF_DUPACCEL: NMTBHOTITEM_FLAGS = 8u32;\npub const HICF_ENTERING: NMTBHOTITEM_FLAGS = 16u32;\npub const HICF_LEAVING: NMTBHOTITEM_FLAGS = 32u32;\npub const HICF_LMOUSE: NMTBHOTITEM_FLAGS = 128u32;\npub const HICF_MOUSE: NMTBHOTITEM_FLAGS = 1u32;\npub const HICF_OTHER: NMTBHOTITEM_FLAGS = 0u32;\npub const HICF_RESELECT: NMTBHOTITEM_FLAGS = 64u32;\npub const HICF_TOGGLEDROPDOWN: NMTBHOTITEM_FLAGS = 256u32;\npub const HILS_HOT: HEADERITEMLEFTSTATES = 2i32;\npub const HILS_NORMAL: HEADERITEMLEFTSTATES = 1i32;\npub const HILS_PRESSED: HEADERITEMLEFTSTATES = 3i32;\npub type HIMAGELIST = isize;\npub const HIRS_HOT: HEADERITEMRIGHTSTATES = 2i32;\npub const HIRS_NORMAL: HEADERITEMRIGHTSTATES = 1i32;\npub const HIRS_PRESSED: HEADERITEMRIGHTSTATES = 3i32;\npub const HIST_ADDTOFAVORITES: u32 = 3u32;\npub const HIST_BACK: u32 = 0u32;\npub const HIST_FAVORITES: u32 = 2u32;\npub const HIST_FORWARD: u32 = 1u32;\npub const HIST_VIEWTREE: u32 = 4u32;\npub const HIS_HOT: HEADERITEMSTATES = 2i32;\npub const HIS_ICONHOT: HEADERITEMSTATES = 8i32;\npub const HIS_ICONNORMAL: HEADERITEMSTATES = 7i32;\npub const HIS_ICONPRESSED: HEADERITEMSTATES = 9i32;\npub const HIS_ICONSORTEDHOT: HEADERITEMSTATES = 11i32;\npub const HIS_ICONSORTEDNORMAL: HEADERITEMSTATES = 10i32;\npub const HIS_ICONSORTEDPRESSED: HEADERITEMSTATES = 12i32;\npub const HIS_NORMAL: HEADERITEMSTATES = 1i32;\npub const HIS_PRESSED: HEADERITEMSTATES = 3i32;\npub const HIS_SORTEDHOT: HEADERITEMSTATES = 5i32;\npub const HIS_SORTEDNORMAL: HEADERITEMSTATES = 4i32;\npub const HIS_SORTEDPRESSED: HEADERITEMSTATES = 6i32;\npub type HIT_TEST_BACKGROUND_OPTIONS = u32;\npub const HKCOMB_A: u32 = 8u32;\npub const HKCOMB_C: u32 = 4u32;\npub const HKCOMB_CA: u32 = 64u32;\npub const HKCOMB_NONE: u32 = 1u32;\npub const HKCOMB_S: u32 = 2u32;\npub const HKCOMB_SA: u32 = 32u32;\npub const HKCOMB_SC: u32 = 16u32;\npub const HKCOMB_SCA: u32 = 128u32;\npub const HKM_GETHOTKEY: u32 = 1026u32;\npub const HKM_SETHOTKEY: u32 = 1025u32;\npub const HKM_SETRULES: u32 = 1027u32;\npub const HLS_LINKTEXT: HYPERLINKSTATES = 2i32;\npub const HLS_NORMALTEXT: HYPERLINKSTATES = 1i32;\npub const HOFS_HOT: HEADEROVERFLOWSTATES = 2i32;\npub const HOFS_NORMAL: HEADEROVERFLOWSTATES = 1i32;\npub type HORZSCROLLSTATES = i32;\npub type HORZTHUMBSTATES = i32;\npub type HOTGLYPHSTATES = i32;\npub const HOTKEYF_ALT: u32 = 4u32;\npub const HOTKEYF_CONTROL: u32 = 2u32;\npub const HOTKEYF_EXT: u32 = 8u32;\npub const HOTKEYF_SHIFT: u32 = 1u32;\npub const HOTKEY_CLASS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"msctls_hotkey32\");\npub const HOTKEY_CLASSA: windows_sys::core::PCSTR = windows_sys::core::s!(\"msctls_hotkey32\");\npub const HOTKEY_CLASSW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"msctls_hotkey32\");\npub type HOVERBACKGROUNDSTATES = i32;\npub const HOVER_DEFAULT: u32 = 4294967295u32;\npub type HPROPSHEETPAGE = *mut core::ffi::c_void;\npub const HP_HEADERDROPDOWN: HEADERPARTS = 5i32;\npub const HP_HEADERDROPDOWNFILTER: HEADERPARTS = 6i32;\npub const HP_HEADERITEM: HEADERPARTS = 1i32;\npub const HP_HEADERITEMLEFT: HEADERPARTS = 2i32;\npub const HP_HEADERITEMRIGHT: HEADERPARTS = 3i32;\npub const HP_HEADEROVERFLOW: HEADERPARTS = 7i32;\npub const HP_HEADERSORTARROW: HEADERPARTS = 4i32;\npub const HSAS_SORTEDDOWN: HEADERSORTARROWSTATES = 2i32;\npub const HSAS_SORTEDUP: HEADERSORTARROWSTATES = 1i32;\npub const HSS_DISABLED: HORZSCROLLSTATES = 4i32;\npub const HSS_HOT: HORZSCROLLSTATES = 2i32;\npub const HSS_NORMAL: HORZSCROLLSTATES = 1i32;\npub const HSS_PUSHED: HORZSCROLLSTATES = 3i32;\npub type HSYNTHETICPOINTERDEVICE = *mut core::ffi::c_void;\npub type HTHEME = isize;\npub type HTREEITEM = isize;\npub const HTS_DISABLED: HORZTHUMBSTATES = 4i32;\npub const HTS_HOT: HORZTHUMBSTATES = 2i32;\npub const HTS_NORMAL: HORZTHUMBSTATES = 1i32;\npub const HTS_PUSHED: HORZTHUMBSTATES = 3i32;\npub const HTTB_BACKGROUNDSEG: HIT_TEST_BACKGROUND_OPTIONS = 0u32;\npub const HTTB_CAPTION: HIT_TEST_BACKGROUND_OPTIONS = 4u32;\npub const HTTB_FIXEDBORDER: HIT_TEST_BACKGROUND_OPTIONS = 2u32;\npub const HTTB_RESIZINGBORDER: HIT_TEST_BACKGROUND_OPTIONS = 240u32;\npub const HTTB_RESIZINGBORDER_BOTTOM: HIT_TEST_BACKGROUND_OPTIONS = 128u32;\npub const HTTB_RESIZINGBORDER_LEFT: HIT_TEST_BACKGROUND_OPTIONS = 16u32;\npub const HTTB_RESIZINGBORDER_RIGHT: HIT_TEST_BACKGROUND_OPTIONS = 64u32;\npub const HTTB_RESIZINGBORDER_TOP: HIT_TEST_BACKGROUND_OPTIONS = 32u32;\npub const HTTB_SIZINGTEMPLATE: HIT_TEST_BACKGROUND_OPTIONS = 256u32;\npub const HTTB_SYSTEMSIZINGMARGINS: HIT_TEST_BACKGROUND_OPTIONS = 512u32;\npub type HYPERLINKSTATES = i32;\npub type HYPERLINKTEXTSTATES = i32;\npub const ICC_ANIMATE_CLASS: INITCOMMONCONTROLSEX_ICC = 128u32;\npub const ICC_BAR_CLASSES: INITCOMMONCONTROLSEX_ICC = 4u32;\npub const ICC_COOL_CLASSES: INITCOMMONCONTROLSEX_ICC = 1024u32;\npub const ICC_DATE_CLASSES: INITCOMMONCONTROLSEX_ICC = 256u32;\npub const ICC_HOTKEY_CLASS: INITCOMMONCONTROLSEX_ICC = 64u32;\npub const ICC_INTERNET_CLASSES: INITCOMMONCONTROLSEX_ICC = 2048u32;\npub const ICC_LINK_CLASS: INITCOMMONCONTROLSEX_ICC = 32768u32;\npub const ICC_LISTVIEW_CLASSES: INITCOMMONCONTROLSEX_ICC = 1u32;\npub const ICC_NATIVEFNTCTL_CLASS: INITCOMMONCONTROLSEX_ICC = 8192u32;\npub const ICC_PAGESCROLLER_CLASS: INITCOMMONCONTROLSEX_ICC = 4096u32;\npub const ICC_PROGRESS_CLASS: INITCOMMONCONTROLSEX_ICC = 32u32;\npub const ICC_STANDARD_CLASSES: INITCOMMONCONTROLSEX_ICC = 16384u32;\npub const ICC_TAB_CLASSES: INITCOMMONCONTROLSEX_ICC = 8u32;\npub const ICC_TREEVIEW_CLASSES: INITCOMMONCONTROLSEX_ICC = 2u32;\npub const ICC_UPDOWN_CLASS: INITCOMMONCONTROLSEX_ICC = 16u32;\npub const ICC_USEREX_CLASSES: INITCOMMONCONTROLSEX_ICC = 512u32;\npub const ICC_WIN95_CLASSES: INITCOMMONCONTROLSEX_ICC = 255u32;\npub const ICE_ALPHA: ICONEFFECT = 4i32;\npub const ICE_GLOW: ICONEFFECT = 1i32;\npub const ICE_NONE: ICONEFFECT = 0i32;\npub const ICE_PULSE: ICONEFFECT = 3i32;\npub const ICE_SHADOW: ICONEFFECT = 2i32;\npub type ICONEFFECT = i32;\npub const IDB_HIST_DISABLED: u32 = 14u32;\npub const IDB_HIST_HOT: u32 = 13u32;\npub const IDB_HIST_LARGE_COLOR: u32 = 9u32;\npub const IDB_HIST_NORMAL: u32 = 12u32;\npub const IDB_HIST_PRESSED: u32 = 15u32;\npub const IDB_HIST_SMALL_COLOR: u32 = 8u32;\npub const IDB_STD_LARGE_COLOR: u32 = 1u32;\npub const IDB_STD_SMALL_COLOR: u32 = 0u32;\npub const IDB_VIEW_LARGE_COLOR: u32 = 5u32;\npub const IDB_VIEW_SMALL_COLOR: u32 = 4u32;\npub const IDC_MANAGE_LINK: u32 = 1592u32;\npub const ID_PSRESTARTWINDOWS: u32 = 2u32;\npub type IEBARMENUSTATES = i32;\npub const ILCF_MOVE: IMAGE_LIST_COPY_FLAGS = 0u32;\npub const ILCF_SWAP: IMAGE_LIST_COPY_FLAGS = 1u32;\npub const ILC_COLOR: IMAGELIST_CREATION_FLAGS = 0u32;\npub const ILC_COLOR16: IMAGELIST_CREATION_FLAGS = 16u32;\npub const ILC_COLOR24: IMAGELIST_CREATION_FLAGS = 24u32;\npub const ILC_COLOR32: IMAGELIST_CREATION_FLAGS = 32u32;\npub const ILC_COLOR4: IMAGELIST_CREATION_FLAGS = 4u32;\npub const ILC_COLOR8: IMAGELIST_CREATION_FLAGS = 8u32;\npub const ILC_COLORDDB: IMAGELIST_CREATION_FLAGS = 254u32;\npub const ILC_HIGHQUALITYSCALE: IMAGELIST_CREATION_FLAGS = 131072u32;\npub const ILC_MASK: IMAGELIST_CREATION_FLAGS = 1u32;\npub const ILC_MIRROR: IMAGELIST_CREATION_FLAGS = 8192u32;\npub const ILC_ORIGINALSIZE: IMAGELIST_CREATION_FLAGS = 65536u32;\npub const ILC_PALETTE: IMAGELIST_CREATION_FLAGS = 2048u32;\npub const ILC_PERITEMMIRROR: IMAGELIST_CREATION_FLAGS = 32768u32;\npub const ILDI_PURGE: u32 = 1u32;\npub const ILDI_QUERYACCESS: u32 = 8u32;\npub const ILDI_RESETACCESS: u32 = 4u32;\npub const ILDI_STANDBY: u32 = 2u32;\npub const ILDRF_IMAGELOWQUALITY: u32 = 1u32;\npub const ILDRF_OVERLAYLOWQUALITY: u32 = 16u32;\npub const ILD_ASYNC: IMAGE_LIST_DRAW_STYLE = 32768u32;\npub const ILD_BLEND: IMAGE_LIST_DRAW_STYLE = 4u32;\npub const ILD_BLEND25: IMAGE_LIST_DRAW_STYLE = 2u32;\npub const ILD_BLEND50: IMAGE_LIST_DRAW_STYLE = 4u32;\npub const ILD_DPISCALE: IMAGE_LIST_DRAW_STYLE = 16384u32;\npub const ILD_FOCUS: IMAGE_LIST_DRAW_STYLE = 2u32;\npub const ILD_IMAGE: IMAGE_LIST_DRAW_STYLE = 32u32;\npub const ILD_MASK: IMAGE_LIST_DRAW_STYLE = 16u32;\npub const ILD_NORMAL: IMAGE_LIST_DRAW_STYLE = 0u32;\npub const ILD_OVERLAYMASK: IMAGE_LIST_DRAW_STYLE = 3840u32;\npub const ILD_PRESERVEALPHA: IMAGE_LIST_DRAW_STYLE = 4096u32;\npub const ILD_ROP: IMAGE_LIST_DRAW_STYLE = 64u32;\npub const ILD_SCALE: IMAGE_LIST_DRAW_STYLE = 8192u32;\npub const ILD_SELECTED: IMAGE_LIST_DRAW_STYLE = 4u32;\npub const ILD_TRANSPARENT: IMAGE_LIST_DRAW_STYLE = 1u32;\npub const ILFIP_ALWAYS: u32 = 0u32;\npub const ILFIP_FROMSTANDBY: u32 = 1u32;\npub const ILGOS_ALWAYS: u32 = 0u32;\npub const ILGOS_FROMSTANDBY: u32 = 1u32;\npub const ILGT_ASYNC: u32 = 1u32;\npub const ILGT_NORMAL: u32 = 0u32;\npub const ILIF_ALPHA: IMAGE_LIST_ITEM_FLAGS = 1u32;\npub const ILIF_LOWQUALITY: IMAGE_LIST_ITEM_FLAGS = 2u32;\npub const ILP_DOWNLEVEL: IMAGE_LIST_WRITE_STREAM_FLAGS = 1u32;\npub const ILP_NORMAL: IMAGE_LIST_WRITE_STREAM_FLAGS = 0u32;\npub const ILR_DEFAULT: u32 = 0u32;\npub const ILR_HORIZONTAL_CENTER: u32 = 1u32;\npub const ILR_HORIZONTAL_LEFT: u32 = 0u32;\npub const ILR_HORIZONTAL_RIGHT: u32 = 2u32;\npub const ILR_SCALE_ASPECTRATIO: u32 = 256u32;\npub const ILR_SCALE_CLIP: u32 = 0u32;\npub const ILR_VERTICAL_BOTTOM: u32 = 32u32;\npub const ILR_VERTICAL_CENTER: u32 = 16u32;\npub const ILR_VERTICAL_TOP: u32 = 0u32;\npub const ILS_ALPHA: u32 = 8u32;\npub const ILS_GLOW: u32 = 1u32;\npub const ILS_NORMAL: u32 = 0u32;\npub const ILS_SATURATE: u32 = 4u32;\npub const ILS_SHADOW: u32 = 2u32;\npub const IL_HORIZONTAL: IMAGELAYOUT = 1i32;\npub const IL_VERTICAL: IMAGELAYOUT = 0i32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct IMAGEINFO {\n    pub hbmImage: super::super::Graphics::Gdi::HBITMAP,\n    pub hbmMask: super::super::Graphics::Gdi::HBITMAP,\n    pub Unused1: i32,\n    pub Unused2: i32,\n    pub rcImage: super::super::Foundation::RECT,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for IMAGEINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type IMAGELAYOUT = i32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct IMAGELISTDRAWPARAMS {\n    pub cbSize: u32,\n    pub himl: HIMAGELIST,\n    pub i: i32,\n    pub hdcDst: super::super::Graphics::Gdi::HDC,\n    pub x: i32,\n    pub y: i32,\n    pub cx: i32,\n    pub cy: i32,\n    pub xBitmap: i32,\n    pub yBitmap: i32,\n    pub rgbBk: super::super::Foundation::COLORREF,\n    pub rgbFg: super::super::Foundation::COLORREF,\n    pub fStyle: u32,\n    pub dwRop: u32,\n    pub fState: u32,\n    pub Frame: u32,\n    pub crEffect: super::super::Foundation::COLORREF,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for IMAGELISTDRAWPARAMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct IMAGELISTSTATS {\n    pub cbSize: u32,\n    pub cAlloc: i32,\n    pub cUsed: i32,\n    pub cStandby: i32,\n}\npub type IMAGELIST_CREATION_FLAGS = u32;\npub type IMAGESELECTTYPE = i32;\npub type IMAGE_LIST_COPY_FLAGS = u32;\npub type IMAGE_LIST_DRAW_STYLE = u32;\npub type IMAGE_LIST_ITEM_FLAGS = u32;\npub type IMAGE_LIST_WRITE_STREAM_FLAGS = u32;\npub const INFOTIPSIZE: u32 = 1024u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct INITCOMMONCONTROLSEX {\n    pub dwSize: u32,\n    pub dwICC: INITCOMMONCONTROLSEX_ICC,\n}\npub type INITCOMMONCONTROLSEX_ICC = u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct INTLIST {\n    pub iValueCount: i32,\n    pub iValues: [i32; 402],\n}\nimpl Default for INTLIST {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const INVALID_LINK_INDEX: i32 = -1i32;\npub const IPM_CLEARADDRESS: u32 = 1124u32;\npub const IPM_GETADDRESS: u32 = 1126u32;\npub const IPM_ISBLANK: u32 = 1129u32;\npub const IPM_SETADDRESS: u32 = 1125u32;\npub const IPM_SETFOCUS: u32 = 1128u32;\npub const IPM_SETRANGE: u32 = 1127u32;\npub const IPN_FIELDCHANGED: u32 = 4294966436u32;\npub const IPN_FIRST: u32 = 4294966436u32;\npub const IPN_LAST: u32 = 4294966417u32;\npub const IST_DPI: IMAGESELECTTYPE = 2i32;\npub const IST_NONE: IMAGESELECTTYPE = 0i32;\npub const IST_SIZE: IMAGESELECTTYPE = 1i32;\npub type ITEMSTATES = i32;\npub const I_CHILDRENAUTO: TVITEMEXW_CHILDREN = -2i32;\npub const I_CHILDRENCALLBACK: TVITEMEXW_CHILDREN = -1i32;\npub const I_GROUPIDCALLBACK: LVITEMA_GROUP_ID = -1i32;\npub const I_GROUPIDNONE: LVITEMA_GROUP_ID = -2i32;\npub const I_IMAGECALLBACK: i32 = -1i32;\npub const I_IMAGENONE: i32 = -2i32;\npub const I_INDENTCALLBACK: i32 = -1i32;\npub const I_ONE_OR_MORE: TVITEMEXW_CHILDREN = 1i32;\npub const I_ZERO: TVITEMEXW_CHILDREN = 0i32;\npub const ImageList: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7c476ba2_02b1_48f4_8048_b24619ddc058);\npub type LABELSTATES = i32;\npub const LBCP_BORDER_HSCROLL: LISTBOXPARTS = 1i32;\npub const LBCP_BORDER_HVSCROLL: LISTBOXPARTS = 2i32;\npub const LBCP_BORDER_NOSCROLL: LISTBOXPARTS = 3i32;\npub const LBCP_BORDER_VSCROLL: LISTBOXPARTS = 4i32;\npub const LBCP_ITEM: LISTBOXPARTS = 5i32;\npub const LBPSHV_DISABLED: BORDER_HVSCROLLSTATES = 4i32;\npub const LBPSHV_FOCUSED: BORDER_HVSCROLLSTATES = 2i32;\npub const LBPSHV_HOT: BORDER_HVSCROLLSTATES = 3i32;\npub const LBPSHV_NORMAL: BORDER_HVSCROLLSTATES = 1i32;\npub const LBPSH_DISABLED: BORDER_HSCROLLSTATES = 4i32;\npub const LBPSH_FOCUSED: BORDER_HSCROLLSTATES = 2i32;\npub const LBPSH_HOT: BORDER_HSCROLLSTATES = 3i32;\npub const LBPSH_NORMAL: BORDER_HSCROLLSTATES = 1i32;\npub const LBPSI_HOT: ITEMSTATES = 1i32;\npub const LBPSI_HOTSELECTED: ITEMSTATES = 2i32;\npub const LBPSI_SELECTED: ITEMSTATES = 3i32;\npub const LBPSI_SELECTEDNOTFOCUS: ITEMSTATES = 4i32;\npub const LBPSN_DISABLED: BORDER_NOSCROLLSTATES = 4i32;\npub const LBPSN_FOCUSED: BORDER_NOSCROLLSTATES = 2i32;\npub const LBPSN_HOT: BORDER_NOSCROLLSTATES = 3i32;\npub const LBPSN_NORMAL: BORDER_NOSCROLLSTATES = 1i32;\npub const LBPSV_DISABLED: BORDER_VSCROLLSTATES = 4i32;\npub const LBPSV_FOCUSED: BORDER_VSCROLLSTATES = 2i32;\npub const LBPSV_HOT: BORDER_VSCROLLSTATES = 3i32;\npub const LBPSV_NORMAL: BORDER_VSCROLLSTATES = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct LHITTESTINFO {\n    pub pt: super::super::Foundation::POINT,\n    pub item: LITEM,\n}\npub const LIF_ITEMID: LIST_ITEM_FLAGS = 4u32;\npub const LIF_ITEMINDEX: LIST_ITEM_FLAGS = 1u32;\npub const LIF_STATE: LIST_ITEM_FLAGS = 2u32;\npub const LIF_URL: LIST_ITEM_FLAGS = 8u32;\npub const LIM_LARGE: _LI_METRIC = 1i32;\npub const LIM_SMALL: _LI_METRIC = 0i32;\npub type LINKHEADERSTATES = i32;\npub type LINKPARTS = i32;\npub type LINKSTATES = i32;\npub const LISS_DISABLED: LISTITEMSTATES = 4i32;\npub const LISS_HOT: LISTITEMSTATES = 2i32;\npub const LISS_HOTSELECTED: LISTITEMSTATES = 6i32;\npub const LISS_NORMAL: LISTITEMSTATES = 1i32;\npub const LISS_SELECTED: LISTITEMSTATES = 3i32;\npub const LISS_SELECTEDNOTFOCUS: LISTITEMSTATES = 5i32;\npub type LISTBOXPARTS = i32;\npub type LISTITEMSTATES = i32;\npub type LISTVIEWPARTS = i32;\npub type LIST_ITEM_FLAGS = u32;\npub type LIST_ITEM_STATE_FLAGS = u32;\npub type LIST_VIEW_BACKGROUND_IMAGE_FLAGS = u32;\npub type LIST_VIEW_GROUP_ALIGN_FLAGS = u32;\npub type LIST_VIEW_GROUP_STATE_FLAGS = u32;\npub type LIST_VIEW_ITEM_COLUMN_FORMAT_FLAGS = i32;\npub type LIST_VIEW_ITEM_FLAGS = u32;\npub type LIST_VIEW_ITEM_STATE_FLAGS = u32;\npub const LIS_DEFAULTCOLORS: LIST_ITEM_STATE_FLAGS = 16u32;\npub const LIS_ENABLED: LIST_ITEM_STATE_FLAGS = 2u32;\npub const LIS_FOCUSED: LIST_ITEM_STATE_FLAGS = 1u32;\npub const LIS_HOTTRACK: LIST_ITEM_STATE_FLAGS = 8u32;\npub const LIS_VISITED: LIST_ITEM_STATE_FLAGS = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LITEM {\n    pub mask: LIST_ITEM_FLAGS,\n    pub iLink: i32,\n    pub state: LIST_ITEM_STATE_FLAGS,\n    pub stateMask: LIST_ITEM_STATE_FLAGS,\n    pub szID: [u16; 48],\n    pub szUrl: [u16; 2084],\n}\nimpl Default for LITEM {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const LM_GETIDEALHEIGHT: u32 = 1793u32;\npub const LM_GETIDEALSIZE: u32 = 1793u32;\npub const LM_GETITEM: u32 = 1795u32;\npub const LM_HITTEST: u32 = 1792u32;\npub const LM_SETITEM: u32 = 1794u32;\npub type LOGOFFBUTTONSSTATES = i32;\npub type LPFNADDPROPSHEETPAGES = Option<unsafe extern \"system\" fn(param0: *mut core::ffi::c_void, param1: LPFNSVADDPROPSHEETPAGE, param2: super::super::Foundation::LPARAM) -> windows_sys::core::BOOL>;\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\npub type LPFNCCINFOA = Option<unsafe extern \"system\" fn(acci: *mut CCINFOA) -> u32>;\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\npub type LPFNCCINFOW = Option<unsafe extern \"system\" fn(acci: *mut CCINFOW) -> u32>;\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\npub type LPFNCCSIZETOTEXTA = Option<unsafe extern \"system\" fn(flstyle: u32, flextstyle: u32, hfont: super::super::Graphics::Gdi::HFONT, psztext: windows_sys::core::PCSTR) -> i32>;\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\npub type LPFNCCSIZETOTEXTW = Option<unsafe extern \"system\" fn(flstyle: u32, flextstyle: u32, hfont: super::super::Graphics::Gdi::HFONT, psztext: windows_sys::core::PCWSTR) -> i32>;\npub type LPFNCCSTYLEA = Option<unsafe extern \"system\" fn(hwndparent: super::super::Foundation::HWND, pccs: *mut CCSTYLEA) -> windows_sys::core::BOOL>;\npub type LPFNCCSTYLEW = Option<unsafe extern \"system\" fn(hwndparent: super::super::Foundation::HWND, pccs: *mut CCSTYLEW) -> windows_sys::core::BOOL>;\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\npub type LPFNPSPCALLBACKA = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, umsg: PSPCB_MESSAGE, ppsp: *mut PROPSHEETPAGEA) -> u32>;\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\npub type LPFNPSPCALLBACKW = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, umsg: PSPCB_MESSAGE, ppsp: *mut PROPSHEETPAGEW) -> u32>;\npub type LPFNSVADDPROPSHEETPAGE = Option<unsafe extern \"system\" fn(param0: HPROPSHEETPAGE, param1: super::super::Foundation::LPARAM) -> windows_sys::core::BOOL>;\npub const LP_HYPERLINK: LINKPARTS = 1i32;\npub const LVA_ALIGNLEFT: u32 = 1u32;\npub const LVA_ALIGNTOP: u32 = 2u32;\npub const LVA_DEFAULT: u32 = 0u32;\npub const LVA_SNAPTOGRID: u32 = 5u32;\npub const LVBKIF_FLAG_ALPHABLEND: LIST_VIEW_BACKGROUND_IMAGE_FLAGS = 536870912u32;\npub const LVBKIF_FLAG_TILEOFFSET: LIST_VIEW_BACKGROUND_IMAGE_FLAGS = 256u32;\npub const LVBKIF_SOURCE_HBITMAP: LIST_VIEW_BACKGROUND_IMAGE_FLAGS = 1u32;\npub const LVBKIF_SOURCE_MASK: LIST_VIEW_BACKGROUND_IMAGE_FLAGS = 3u32;\npub const LVBKIF_SOURCE_NONE: LIST_VIEW_BACKGROUND_IMAGE_FLAGS = 0u32;\npub const LVBKIF_SOURCE_URL: LIST_VIEW_BACKGROUND_IMAGE_FLAGS = 2u32;\npub const LVBKIF_STYLE_MASK: LIST_VIEW_BACKGROUND_IMAGE_FLAGS = 16u32;\npub const LVBKIF_STYLE_NORMAL: LIST_VIEW_BACKGROUND_IMAGE_FLAGS = 0u32;\npub const LVBKIF_STYLE_TILE: LIST_VIEW_BACKGROUND_IMAGE_FLAGS = 16u32;\npub const LVBKIF_TYPE_WATERMARK: LIST_VIEW_BACKGROUND_IMAGE_FLAGS = 268435456u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct LVBKIMAGEA {\n    pub ulFlags: LIST_VIEW_BACKGROUND_IMAGE_FLAGS,\n    pub hbm: super::super::Graphics::Gdi::HBITMAP,\n    pub pszImage: windows_sys::core::PSTR,\n    pub cchImageMax: u32,\n    pub xOffsetPercent: i32,\n    pub yOffsetPercent: i32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for LVBKIMAGEA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct LVBKIMAGEW {\n    pub ulFlags: LIST_VIEW_BACKGROUND_IMAGE_FLAGS,\n    pub hbm: super::super::Graphics::Gdi::HBITMAP,\n    pub pszImage: windows_sys::core::PWSTR,\n    pub cchImageMax: u32,\n    pub xOffsetPercent: i32,\n    pub yOffsetPercent: i32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for LVBKIMAGEW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const LVCB_HOVER: COLLAPSEBUTTONSTATES = 2i32;\npub const LVCB_NORMAL: COLLAPSEBUTTONSTATES = 1i32;\npub const LVCB_PUSHED: COLLAPSEBUTTONSTATES = 3i32;\npub const LVCDI_GROUP: NMLVCUSTOMDRAW_ITEM_TYPE = 1u32;\npub const LVCDI_ITEM: NMLVCUSTOMDRAW_ITEM_TYPE = 0u32;\npub const LVCDI_ITEMSLIST: NMLVCUSTOMDRAW_ITEM_TYPE = 2u32;\npub const LVCDRF_NOGROUPFRAME: u32 = 131072u32;\npub const LVCDRF_NOSELECT: u32 = 65536u32;\npub const LVCFMT_BITMAP_ON_RIGHT: LVCOLUMNW_FORMAT = 4096i32;\npub const LVCFMT_CENTER: LVCOLUMNW_FORMAT = 2i32;\npub const LVCFMT_COL_HAS_IMAGES: LVCOLUMNW_FORMAT = 32768i32;\npub const LVCFMT_FILL: LIST_VIEW_ITEM_COLUMN_FORMAT_FLAGS = 2097152i32;\npub const LVCFMT_FIXED_RATIO: LVCOLUMNW_FORMAT = 524288i32;\npub const LVCFMT_FIXED_WIDTH: LVCOLUMNW_FORMAT = 256i32;\npub const LVCFMT_IMAGE: LVCOLUMNW_FORMAT = 2048i32;\npub const LVCFMT_JUSTIFYMASK: LVCOLUMNW_FORMAT = 3i32;\npub const LVCFMT_LEFT: LVCOLUMNW_FORMAT = 0i32;\npub const LVCFMT_LINE_BREAK: LIST_VIEW_ITEM_COLUMN_FORMAT_FLAGS = 1048576i32;\npub const LVCFMT_NO_DPI_SCALE: LVCOLUMNW_FORMAT = 262144i32;\npub const LVCFMT_NO_TITLE: LIST_VIEW_ITEM_COLUMN_FORMAT_FLAGS = 8388608i32;\npub const LVCFMT_RIGHT: LVCOLUMNW_FORMAT = 1i32;\npub const LVCFMT_SPLITBUTTON: LVCOLUMNW_FORMAT = 16777216i32;\npub const LVCFMT_TILE_PLACEMENTMASK: LIST_VIEW_ITEM_COLUMN_FORMAT_FLAGS = 3145728i32;\npub const LVCFMT_WRAP: LIST_VIEW_ITEM_COLUMN_FORMAT_FLAGS = 4194304i32;\npub const LVCF_DEFAULTWIDTH: LVCOLUMNW_MASK = 128u32;\npub const LVCF_FMT: LVCOLUMNW_MASK = 1u32;\npub const LVCF_IDEALWIDTH: LVCOLUMNW_MASK = 256u32;\npub const LVCF_IMAGE: LVCOLUMNW_MASK = 16u32;\npub const LVCF_MINWIDTH: LVCOLUMNW_MASK = 64u32;\npub const LVCF_ORDER: LVCOLUMNW_MASK = 32u32;\npub const LVCF_SUBITEM: LVCOLUMNW_MASK = 8u32;\npub const LVCF_TEXT: LVCOLUMNW_MASK = 4u32;\npub const LVCF_WIDTH: LVCOLUMNW_MASK = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVCOLUMNA {\n    pub mask: LVCOLUMNW_MASK,\n    pub fmt: LVCOLUMNW_FORMAT,\n    pub cx: i32,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub iSubItem: i32,\n    pub iImage: i32,\n    pub iOrder: i32,\n    pub cxMin: i32,\n    pub cxDefault: i32,\n    pub cxIdeal: i32,\n}\nimpl Default for LVCOLUMNA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVCOLUMNW {\n    pub mask: LVCOLUMNW_MASK,\n    pub fmt: LVCOLUMNW_FORMAT,\n    pub cx: i32,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub iSubItem: i32,\n    pub iImage: i32,\n    pub iOrder: i32,\n    pub cxMin: i32,\n    pub cxDefault: i32,\n    pub cxIdeal: i32,\n}\nimpl Default for LVCOLUMNW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type LVCOLUMNW_FORMAT = i32;\npub type LVCOLUMNW_MASK = u32;\npub const LVEB_HOVER: EXPANDBUTTONSTATES = 2i32;\npub const LVEB_NORMAL: EXPANDBUTTONSTATES = 1i32;\npub const LVEB_PUSHED: EXPANDBUTTONSTATES = 3i32;\npub const LVFF_ITEMCOUNT: u32 = 1u32;\npub const LVFIF_STATE: LVFOOTERITEM_MASK = 2u32;\npub const LVFIF_TEXT: LVFOOTERITEM_MASK = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVFINDINFOA {\n    pub flags: LVFINDINFOW_FLAGS,\n    pub psz: windows_sys::core::PCSTR,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub pt: super::super::Foundation::POINT,\n    pub vkDirection: u32,\n}\nimpl Default for LVFINDINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVFINDINFOW {\n    pub flags: LVFINDINFOW_FLAGS,\n    pub psz: windows_sys::core::PCWSTR,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub pt: super::super::Foundation::POINT,\n    pub vkDirection: u32,\n}\nimpl Default for LVFINDINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type LVFINDINFOW_FLAGS = u32;\npub const LVFIS_FOCUSED: u32 = 1u32;\npub const LVFI_NEARESTXY: LVFINDINFOW_FLAGS = 64u32;\npub const LVFI_PARAM: LVFINDINFOW_FLAGS = 1u32;\npub const LVFI_PARTIAL: LVFINDINFOW_FLAGS = 8u32;\npub const LVFI_STRING: LVFINDINFOW_FLAGS = 2u32;\npub const LVFI_SUBSTRING: LVFINDINFOW_FLAGS = 4u32;\npub const LVFI_WRAP: LVFINDINFOW_FLAGS = 32u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVFOOTERINFO {\n    pub mask: u32,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub cItems: u32,\n}\nimpl Default for LVFOOTERINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVFOOTERITEM {\n    pub mask: LVFOOTERITEM_MASK,\n    pub iItem: i32,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub state: u32,\n    pub stateMask: u32,\n}\nimpl Default for LVFOOTERITEM {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type LVFOOTERITEM_MASK = u32;\npub const LVGA_FOOTER_CENTER: LIST_VIEW_GROUP_ALIGN_FLAGS = 16u32;\npub const LVGA_FOOTER_LEFT: LIST_VIEW_GROUP_ALIGN_FLAGS = 8u32;\npub const LVGA_FOOTER_RIGHT: LIST_VIEW_GROUP_ALIGN_FLAGS = 32u32;\npub const LVGA_HEADER_CENTER: LIST_VIEW_GROUP_ALIGN_FLAGS = 2u32;\npub const LVGA_HEADER_LEFT: LIST_VIEW_GROUP_ALIGN_FLAGS = 1u32;\npub const LVGA_HEADER_RIGHT: LIST_VIEW_GROUP_ALIGN_FLAGS = 4u32;\npub const LVGF_ALIGN: LVGROUP_MASK = 8u32;\npub const LVGF_DESCRIPTIONBOTTOM: LVGROUP_MASK = 2048u32;\npub const LVGF_DESCRIPTIONTOP: LVGROUP_MASK = 1024u32;\npub const LVGF_EXTENDEDIMAGE: LVGROUP_MASK = 8192u32;\npub const LVGF_FOOTER: LVGROUP_MASK = 2u32;\npub const LVGF_GROUPID: LVGROUP_MASK = 16u32;\npub const LVGF_HEADER: LVGROUP_MASK = 1u32;\npub const LVGF_ITEMS: LVGROUP_MASK = 16384u32;\npub const LVGF_NONE: LVGROUP_MASK = 0u32;\npub const LVGF_STATE: LVGROUP_MASK = 4u32;\npub const LVGF_SUBSET: LVGROUP_MASK = 32768u32;\npub const LVGF_SUBSETITEMS: LVGROUP_MASK = 65536u32;\npub const LVGF_SUBTITLE: LVGROUP_MASK = 256u32;\npub const LVGF_TASK: LVGROUP_MASK = 512u32;\npub const LVGF_TITLEIMAGE: LVGROUP_MASK = 4096u32;\npub const LVGGR_GROUP: u32 = 0u32;\npub const LVGGR_HEADER: u32 = 1u32;\npub const LVGGR_LABEL: u32 = 2u32;\npub const LVGGR_SUBSETLINK: u32 = 3u32;\npub const LVGHL_CLOSE: GROUPHEADERLINESTATES = 9i32;\npub const LVGHL_CLOSEHOT: GROUPHEADERLINESTATES = 10i32;\npub const LVGHL_CLOSEMIXEDSELECTION: GROUPHEADERLINESTATES = 15i32;\npub const LVGHL_CLOSEMIXEDSELECTIONHOT: GROUPHEADERLINESTATES = 16i32;\npub const LVGHL_CLOSESELECTED: GROUPHEADERLINESTATES = 11i32;\npub const LVGHL_CLOSESELECTEDHOT: GROUPHEADERLINESTATES = 12i32;\npub const LVGHL_CLOSESELECTEDNOTFOCUSED: GROUPHEADERLINESTATES = 13i32;\npub const LVGHL_CLOSESELECTEDNOTFOCUSEDHOT: GROUPHEADERLINESTATES = 14i32;\npub const LVGHL_OPEN: GROUPHEADERLINESTATES = 1i32;\npub const LVGHL_OPENHOT: GROUPHEADERLINESTATES = 2i32;\npub const LVGHL_OPENMIXEDSELECTION: GROUPHEADERLINESTATES = 7i32;\npub const LVGHL_OPENMIXEDSELECTIONHOT: GROUPHEADERLINESTATES = 8i32;\npub const LVGHL_OPENSELECTED: GROUPHEADERLINESTATES = 3i32;\npub const LVGHL_OPENSELECTEDHOT: GROUPHEADERLINESTATES = 4i32;\npub const LVGHL_OPENSELECTEDNOTFOCUSED: GROUPHEADERLINESTATES = 5i32;\npub const LVGHL_OPENSELECTEDNOTFOCUSEDHOT: GROUPHEADERLINESTATES = 6i32;\npub const LVGH_CLOSE: GROUPHEADERSTATES = 9i32;\npub const LVGH_CLOSEHOT: GROUPHEADERSTATES = 10i32;\npub const LVGH_CLOSEMIXEDSELECTION: GROUPHEADERSTATES = 15i32;\npub const LVGH_CLOSEMIXEDSELECTIONHOT: GROUPHEADERSTATES = 16i32;\npub const LVGH_CLOSESELECTED: GROUPHEADERSTATES = 11i32;\npub const LVGH_CLOSESELECTEDHOT: GROUPHEADERSTATES = 12i32;\npub const LVGH_CLOSESELECTEDNOTFOCUSED: GROUPHEADERSTATES = 13i32;\npub const LVGH_CLOSESELECTEDNOTFOCUSEDHOT: GROUPHEADERSTATES = 14i32;\npub const LVGH_OPEN: GROUPHEADERSTATES = 1i32;\npub const LVGH_OPENHOT: GROUPHEADERSTATES = 2i32;\npub const LVGH_OPENMIXEDSELECTION: GROUPHEADERSTATES = 7i32;\npub const LVGH_OPENMIXEDSELECTIONHOT: GROUPHEADERSTATES = 8i32;\npub const LVGH_OPENSELECTED: GROUPHEADERSTATES = 3i32;\npub const LVGH_OPENSELECTEDHOT: GROUPHEADERSTATES = 4i32;\npub const LVGH_OPENSELECTEDNOTFOCUSED: GROUPHEADERSTATES = 5i32;\npub const LVGH_OPENSELECTEDNOTFOCUSEDHOT: GROUPHEADERSTATES = 6i32;\npub const LVGIT_UNFOLDED: NMLVGETINFOTIP_FLAGS = 1u32;\npub const LVGIT_ZERO: NMLVGETINFOTIP_FLAGS = 0u32;\npub const LVGMF_BORDERCOLOR: u32 = 2u32;\npub const LVGMF_BORDERSIZE: u32 = 1u32;\npub const LVGMF_NONE: u32 = 0u32;\npub const LVGMF_TEXTCOLOR: u32 = 4u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVGROUP {\n    pub cbSize: u32,\n    pub mask: LVGROUP_MASK,\n    pub pszHeader: windows_sys::core::PWSTR,\n    pub cchHeader: i32,\n    pub pszFooter: windows_sys::core::PWSTR,\n    pub cchFooter: i32,\n    pub iGroupId: i32,\n    pub stateMask: LIST_VIEW_GROUP_STATE_FLAGS,\n    pub state: LIST_VIEW_GROUP_STATE_FLAGS,\n    pub uAlign: LIST_VIEW_GROUP_ALIGN_FLAGS,\n    pub pszSubtitle: windows_sys::core::PWSTR,\n    pub cchSubtitle: u32,\n    pub pszTask: windows_sys::core::PWSTR,\n    pub cchTask: u32,\n    pub pszDescriptionTop: windows_sys::core::PWSTR,\n    pub cchDescriptionTop: u32,\n    pub pszDescriptionBottom: windows_sys::core::PWSTR,\n    pub cchDescriptionBottom: u32,\n    pub iTitleImage: i32,\n    pub iExtendedImage: i32,\n    pub iFirstItem: i32,\n    pub cItems: u32,\n    pub pszSubsetTitle: windows_sys::core::PWSTR,\n    pub cchSubsetTitle: u32,\n}\nimpl Default for LVGROUP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct LVGROUPMETRICS {\n    pub cbSize: u32,\n    pub mask: u32,\n    pub Left: u32,\n    pub Top: u32,\n    pub Right: u32,\n    pub Bottom: u32,\n    pub crLeft: super::super::Foundation::COLORREF,\n    pub crTop: super::super::Foundation::COLORREF,\n    pub crRight: super::super::Foundation::COLORREF,\n    pub crBottom: super::super::Foundation::COLORREF,\n    pub crHeader: super::super::Foundation::COLORREF,\n    pub crFooter: super::super::Foundation::COLORREF,\n}\npub type LVGROUP_MASK = u32;\npub const LVGS_COLLAPSED: LIST_VIEW_GROUP_STATE_FLAGS = 1u32;\npub const LVGS_COLLAPSIBLE: LIST_VIEW_GROUP_STATE_FLAGS = 8u32;\npub const LVGS_FOCUSED: LIST_VIEW_GROUP_STATE_FLAGS = 16u32;\npub const LVGS_HIDDEN: LIST_VIEW_GROUP_STATE_FLAGS = 2u32;\npub const LVGS_NOHEADER: LIST_VIEW_GROUP_STATE_FLAGS = 4u32;\npub const LVGS_NORMAL: LIST_VIEW_GROUP_STATE_FLAGS = 0u32;\npub const LVGS_SELECTED: LIST_VIEW_GROUP_STATE_FLAGS = 32u32;\npub const LVGS_SUBSETED: LIST_VIEW_GROUP_STATE_FLAGS = 64u32;\npub const LVGS_SUBSETLINKFOCUSED: LIST_VIEW_GROUP_STATE_FLAGS = 128u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct LVHITTESTINFO {\n    pub pt: super::super::Foundation::POINT,\n    pub flags: LVHITTESTINFO_FLAGS,\n    pub iItem: i32,\n    pub iSubItem: i32,\n    pub iGroup: i32,\n}\npub type LVHITTESTINFO_FLAGS = u32;\npub const LVHT_ABOVE: LVHITTESTINFO_FLAGS = 8u32;\npub const LVHT_BELOW: LVHITTESTINFO_FLAGS = 16u32;\npub const LVHT_EX_FOOTER: LVHITTESTINFO_FLAGS = 134217728u32;\npub const LVHT_EX_GROUP: LVHITTESTINFO_FLAGS = 4076863488u32;\npub const LVHT_EX_GROUP_BACKGROUND: LVHITTESTINFO_FLAGS = 2147483648u32;\npub const LVHT_EX_GROUP_COLLAPSE: LVHITTESTINFO_FLAGS = 1073741824u32;\npub const LVHT_EX_GROUP_FOOTER: LVHITTESTINFO_FLAGS = 536870912u32;\npub const LVHT_EX_GROUP_HEADER: LVHITTESTINFO_FLAGS = 268435456u32;\npub const LVHT_EX_GROUP_STATEICON: LVHITTESTINFO_FLAGS = 16777216u32;\npub const LVHT_EX_GROUP_SUBSETLINK: LVHITTESTINFO_FLAGS = 33554432u32;\npub const LVHT_EX_ONCONTENTS: LVHITTESTINFO_FLAGS = 67108864u32;\npub const LVHT_NOWHERE: LVHITTESTINFO_FLAGS = 1u32;\npub const LVHT_ONITEMICON: LVHITTESTINFO_FLAGS = 2u32;\npub const LVHT_ONITEMLABEL: LVHITTESTINFO_FLAGS = 4u32;\npub const LVHT_ONITEMSTATEICON: LVHITTESTINFO_FLAGS = 8u32;\npub const LVHT_TOLEFT: LVHITTESTINFO_FLAGS = 64u32;\npub const LVHT_TORIGHT: LVHITTESTINFO_FLAGS = 32u32;\npub const LVIF_COLFMT: LIST_VIEW_ITEM_FLAGS = 65536u32;\npub const LVIF_COLUMNS: LIST_VIEW_ITEM_FLAGS = 512u32;\npub const LVIF_DI_SETITEM: LIST_VIEW_ITEM_FLAGS = 4096u32;\npub const LVIF_GROUPID: LIST_VIEW_ITEM_FLAGS = 256u32;\npub const LVIF_IMAGE: LIST_VIEW_ITEM_FLAGS = 2u32;\npub const LVIF_INDENT: LIST_VIEW_ITEM_FLAGS = 16u32;\npub const LVIF_NORECOMPUTE: LIST_VIEW_ITEM_FLAGS = 2048u32;\npub const LVIF_PARAM: LIST_VIEW_ITEM_FLAGS = 4u32;\npub const LVIF_STATE: LIST_VIEW_ITEM_FLAGS = 8u32;\npub const LVIF_TEXT: LIST_VIEW_ITEM_FLAGS = 1u32;\npub const LVIM_AFTER: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVINSERTGROUPSORTED {\n    pub pfnGroupCompare: PFNLVGROUPCOMPARE,\n    pub pvData: *mut core::ffi::c_void,\n    pub lvGroup: LVGROUP,\n}\nimpl Default for LVINSERTGROUPSORTED {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct LVINSERTMARK {\n    pub cbSize: u32,\n    pub dwFlags: u32,\n    pub iItem: i32,\n    pub dwReserved: u32,\n}\npub const LVIR_BOUNDS: u32 = 0u32;\npub const LVIR_ICON: u32 = 1u32;\npub const LVIR_LABEL: u32 = 2u32;\npub const LVIR_SELECTBOUNDS: u32 = 3u32;\npub const LVIS_ACTIVATING: LIST_VIEW_ITEM_STATE_FLAGS = 32u32;\npub const LVIS_CUT: LIST_VIEW_ITEM_STATE_FLAGS = 4u32;\npub const LVIS_DROPHILITED: LIST_VIEW_ITEM_STATE_FLAGS = 8u32;\npub const LVIS_FOCUSED: LIST_VIEW_ITEM_STATE_FLAGS = 1u32;\npub const LVIS_GLOW: LIST_VIEW_ITEM_STATE_FLAGS = 16u32;\npub const LVIS_OVERLAYMASK: LIST_VIEW_ITEM_STATE_FLAGS = 3840u32;\npub const LVIS_SELECTED: LIST_VIEW_ITEM_STATE_FLAGS = 2u32;\npub const LVIS_STATEIMAGEMASK: LIST_VIEW_ITEM_STATE_FLAGS = 61440u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVITEMA {\n    pub mask: LIST_VIEW_ITEM_FLAGS,\n    pub iItem: i32,\n    pub iSubItem: i32,\n    pub state: LIST_VIEW_ITEM_STATE_FLAGS,\n    pub stateMask: LIST_VIEW_ITEM_STATE_FLAGS,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub iIndent: i32,\n    pub iGroupId: i32,\n    pub cColumns: u32,\n    pub puColumns: *mut u32,\n    pub piColFmt: *mut LIST_VIEW_ITEM_COLUMN_FORMAT_FLAGS,\n    pub iGroup: i32,\n}\nimpl Default for LVITEMA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type LVITEMA_GROUP_ID = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct LVITEMINDEX {\n    pub iItem: i32,\n    pub iGroup: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVITEMW {\n    pub mask: LIST_VIEW_ITEM_FLAGS,\n    pub iItem: i32,\n    pub iSubItem: i32,\n    pub state: LIST_VIEW_ITEM_STATE_FLAGS,\n    pub stateMask: LIST_VIEW_ITEM_STATE_FLAGS,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub iIndent: i32,\n    pub iGroupId: i32,\n    pub cColumns: u32,\n    pub puColumns: *mut u32,\n    pub piColFmt: *mut LIST_VIEW_ITEM_COLUMN_FORMAT_FLAGS,\n    pub iGroup: i32,\n}\nimpl Default for LVITEMW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const LVKF_ALT: u32 = 1u32;\npub const LVKF_CONTROL: u32 = 2u32;\npub const LVKF_SHIFT: u32 = 4u32;\npub const LVM_APPROXIMATEVIEWRECT: u32 = 4160u32;\npub const LVM_ARRANGE: u32 = 4118u32;\npub const LVM_CANCELEDITLABEL: u32 = 4275u32;\npub const LVM_CREATEDRAGIMAGE: u32 = 4129u32;\npub const LVM_DELETEALLITEMS: u32 = 4105u32;\npub const LVM_DELETECOLUMN: u32 = 4124u32;\npub const LVM_DELETEITEM: u32 = 4104u32;\npub const LVM_EDITLABEL: u32 = 4214u32;\npub const LVM_EDITLABELA: u32 = 4119u32;\npub const LVM_EDITLABELW: u32 = 4214u32;\npub const LVM_ENABLEGROUPVIEW: u32 = 4253u32;\npub const LVM_ENSUREVISIBLE: u32 = 4115u32;\npub const LVM_FINDITEM: u32 = 4179u32;\npub const LVM_FINDITEMA: u32 = 4109u32;\npub const LVM_FINDITEMW: u32 = 4179u32;\npub const LVM_FIRST: u32 = 4096u32;\npub const LVM_GETBKCOLOR: u32 = 4096u32;\npub const LVM_GETBKIMAGE: u32 = 4235u32;\npub const LVM_GETBKIMAGEA: u32 = 4165u32;\npub const LVM_GETBKIMAGEW: u32 = 4235u32;\npub const LVM_GETCALLBACKMASK: u32 = 4106u32;\npub const LVM_GETCOLUMN: u32 = 4191u32;\npub const LVM_GETCOLUMNA: u32 = 4121u32;\npub const LVM_GETCOLUMNORDERARRAY: u32 = 4155u32;\npub const LVM_GETCOLUMNW: u32 = 4191u32;\npub const LVM_GETCOLUMNWIDTH: u32 = 4125u32;\npub const LVM_GETCOUNTPERPAGE: u32 = 4136u32;\npub const LVM_GETEDITCONTROL: u32 = 4120u32;\npub const LVM_GETEMPTYTEXT: u32 = 4300u32;\npub const LVM_GETEXTENDEDLISTVIEWSTYLE: u32 = 4151u32;\npub const LVM_GETFOCUSEDGROUP: u32 = 4189u32;\npub const LVM_GETFOOTERINFO: u32 = 4302u32;\npub const LVM_GETFOOTERITEM: u32 = 4304u32;\npub const LVM_GETFOOTERITEMRECT: u32 = 4303u32;\npub const LVM_GETFOOTERRECT: u32 = 4301u32;\npub const LVM_GETGROUPCOUNT: u32 = 4248u32;\npub const LVM_GETGROUPINFO: u32 = 4245u32;\npub const LVM_GETGROUPINFOBYINDEX: u32 = 4249u32;\npub const LVM_GETGROUPMETRICS: u32 = 4252u32;\npub const LVM_GETGROUPRECT: u32 = 4194u32;\npub const LVM_GETGROUPSTATE: u32 = 4188u32;\npub const LVM_GETHEADER: u32 = 4127u32;\npub const LVM_GETHOTCURSOR: u32 = 4159u32;\npub const LVM_GETHOTITEM: u32 = 4157u32;\npub const LVM_GETHOVERTIME: u32 = 4168u32;\npub const LVM_GETIMAGELIST: u32 = 4098u32;\npub const LVM_GETINSERTMARK: u32 = 4263u32;\npub const LVM_GETINSERTMARKCOLOR: u32 = 4267u32;\npub const LVM_GETINSERTMARKRECT: u32 = 4265u32;\npub const LVM_GETISEARCHSTRING: u32 = 4213u32;\npub const LVM_GETISEARCHSTRINGA: u32 = 4148u32;\npub const LVM_GETISEARCHSTRINGW: u32 = 4213u32;\npub const LVM_GETITEM: u32 = 4171u32;\npub const LVM_GETITEMA: u32 = 4101u32;\npub const LVM_GETITEMCOUNT: u32 = 4100u32;\npub const LVM_GETITEMINDEXRECT: u32 = 4305u32;\npub const LVM_GETITEMPOSITION: u32 = 4112u32;\npub const LVM_GETITEMRECT: u32 = 4110u32;\npub const LVM_GETITEMSPACING: u32 = 4147u32;\npub const LVM_GETITEMSTATE: u32 = 4140u32;\npub const LVM_GETITEMTEXT: u32 = 4211u32;\npub const LVM_GETITEMTEXTA: u32 = 4141u32;\npub const LVM_GETITEMTEXTW: u32 = 4211u32;\npub const LVM_GETITEMW: u32 = 4171u32;\npub const LVM_GETNEXTITEM: u32 = 4108u32;\npub const LVM_GETNEXTITEMINDEX: u32 = 4307u32;\npub const LVM_GETNUMBEROFWORKAREAS: u32 = 4169u32;\npub const LVM_GETORIGIN: u32 = 4137u32;\npub const LVM_GETOUTLINECOLOR: u32 = 4272u32;\npub const LVM_GETSELECTEDCOLUMN: u32 = 4270u32;\npub const LVM_GETSELECTEDCOUNT: u32 = 4146u32;\npub const LVM_GETSELECTIONMARK: u32 = 4162u32;\npub const LVM_GETSTRINGWIDTH: u32 = 4183u32;\npub const LVM_GETSTRINGWIDTHA: u32 = 4113u32;\npub const LVM_GETSTRINGWIDTHW: u32 = 4183u32;\npub const LVM_GETSUBITEMRECT: u32 = 4152u32;\npub const LVM_GETTEXTBKCOLOR: u32 = 4133u32;\npub const LVM_GETTEXTCOLOR: u32 = 4131u32;\npub const LVM_GETTILEINFO: u32 = 4261u32;\npub const LVM_GETTILEVIEWINFO: u32 = 4259u32;\npub const LVM_GETTOOLTIPS: u32 = 4174u32;\npub const LVM_GETTOPINDEX: u32 = 4135u32;\npub const LVM_GETUNICODEFORMAT: u32 = 8198u32;\npub const LVM_GETVIEW: u32 = 4239u32;\npub const LVM_GETVIEWRECT: u32 = 4130u32;\npub const LVM_GETWORKAREAS: u32 = 4166u32;\npub const LVM_HASGROUP: u32 = 4257u32;\npub const LVM_HITTEST: u32 = 4114u32;\npub const LVM_INSERTCOLUMN: u32 = 4193u32;\npub const LVM_INSERTCOLUMNA: u32 = 4123u32;\npub const LVM_INSERTCOLUMNW: u32 = 4193u32;\npub const LVM_INSERTGROUP: u32 = 4241u32;\npub const LVM_INSERTGROUPSORTED: u32 = 4255u32;\npub const LVM_INSERTITEM: u32 = 4173u32;\npub const LVM_INSERTITEMA: u32 = 4103u32;\npub const LVM_INSERTITEMW: u32 = 4173u32;\npub const LVM_INSERTMARKHITTEST: u32 = 4264u32;\npub const LVM_ISGROUPVIEWENABLED: u32 = 4271u32;\npub const LVM_ISITEMVISIBLE: u32 = 4278u32;\npub const LVM_MAPIDTOINDEX: u32 = 4277u32;\npub const LVM_MAPINDEXTOID: u32 = 4276u32;\npub const LVM_MOVEGROUP: u32 = 4247u32;\npub const LVM_MOVEITEMTOGROUP: u32 = 4250u32;\npub const LVM_REDRAWITEMS: u32 = 4117u32;\npub const LVM_REMOVEALLGROUPS: u32 = 4256u32;\npub const LVM_REMOVEGROUP: u32 = 4246u32;\npub const LVM_SCROLL: u32 = 4116u32;\npub const LVM_SETBKCOLOR: u32 = 4097u32;\npub const LVM_SETBKIMAGE: u32 = 4234u32;\npub const LVM_SETBKIMAGEA: u32 = 4164u32;\npub const LVM_SETBKIMAGEW: u32 = 4234u32;\npub const LVM_SETCALLBACKMASK: u32 = 4107u32;\npub const LVM_SETCOLUMN: u32 = 4192u32;\npub const LVM_SETCOLUMNA: u32 = 4122u32;\npub const LVM_SETCOLUMNORDERARRAY: u32 = 4154u32;\npub const LVM_SETCOLUMNW: u32 = 4192u32;\npub const LVM_SETCOLUMNWIDTH: u32 = 4126u32;\npub const LVM_SETEXTENDEDLISTVIEWSTYLE: u32 = 4150u32;\npub const LVM_SETGROUPINFO: u32 = 4243u32;\npub const LVM_SETGROUPMETRICS: u32 = 4251u32;\npub const LVM_SETHOTCURSOR: u32 = 4158u32;\npub const LVM_SETHOTITEM: u32 = 4156u32;\npub const LVM_SETHOVERTIME: u32 = 4167u32;\npub const LVM_SETICONSPACING: u32 = 4149u32;\npub const LVM_SETIMAGELIST: u32 = 4099u32;\npub const LVM_SETINFOTIP: u32 = 4269u32;\npub const LVM_SETINSERTMARK: u32 = 4262u32;\npub const LVM_SETINSERTMARKCOLOR: u32 = 4266u32;\npub const LVM_SETITEM: u32 = 4172u32;\npub const LVM_SETITEMA: u32 = 4102u32;\npub const LVM_SETITEMCOUNT: u32 = 4143u32;\npub const LVM_SETITEMINDEXSTATE: u32 = 4306u32;\npub const LVM_SETITEMPOSITION: u32 = 4111u32;\npub const LVM_SETITEMPOSITION32: u32 = 4145u32;\npub const LVM_SETITEMSTATE: u32 = 4139u32;\npub const LVM_SETITEMTEXT: u32 = 4212u32;\npub const LVM_SETITEMTEXTA: u32 = 4142u32;\npub const LVM_SETITEMTEXTW: u32 = 4212u32;\npub const LVM_SETITEMW: u32 = 4172u32;\npub const LVM_SETOUTLINECOLOR: u32 = 4273u32;\npub const LVM_SETSELECTEDCOLUMN: u32 = 4236u32;\npub const LVM_SETSELECTIONMARK: u32 = 4163u32;\npub const LVM_SETTEXTBKCOLOR: u32 = 4134u32;\npub const LVM_SETTEXTCOLOR: u32 = 4132u32;\npub const LVM_SETTILEINFO: u32 = 4260u32;\npub const LVM_SETTILEVIEWINFO: u32 = 4258u32;\npub const LVM_SETTOOLTIPS: u32 = 4170u32;\npub const LVM_SETUNICODEFORMAT: u32 = 8197u32;\npub const LVM_SETVIEW: u32 = 4238u32;\npub const LVM_SETWORKAREAS: u32 = 4161u32;\npub const LVM_SORTGROUPS: u32 = 4254u32;\npub const LVM_SORTITEMS: u32 = 4144u32;\npub const LVM_SORTITEMSEX: u32 = 4177u32;\npub const LVM_SUBITEMHITTEST: u32 = 4153u32;\npub const LVM_UPDATE: u32 = 4138u32;\npub const LVNI_ABOVE: u32 = 256u32;\npub const LVNI_ALL: u32 = 0u32;\npub const LVNI_BELOW: u32 = 512u32;\npub const LVNI_CUT: u32 = 4u32;\npub const LVNI_DROPHILITED: u32 = 8u32;\npub const LVNI_FOCUSED: u32 = 1u32;\npub const LVNI_PREVIOUS: u32 = 32u32;\npub const LVNI_SAMEGROUPONLY: u32 = 128u32;\npub const LVNI_SELECTED: u32 = 2u32;\npub const LVNI_TOLEFT: u32 = 1024u32;\npub const LVNI_TORIGHT: u32 = 2048u32;\npub const LVNI_VISIBLEONLY: u32 = 64u32;\npub const LVNI_VISIBLEORDER: u32 = 16u32;\npub const LVNSCH_DEFAULT: i32 = -1i32;\npub const LVNSCH_ERROR: i32 = -2i32;\npub const LVNSCH_IGNORE: i32 = -3i32;\npub const LVN_BEGINDRAG: u32 = 4294967187u32;\npub const LVN_BEGINLABELEDIT: u32 = 4294967121u32;\npub const LVN_BEGINLABELEDITA: u32 = 4294967191u32;\npub const LVN_BEGINLABELEDITW: u32 = 4294967121u32;\npub const LVN_BEGINRDRAG: u32 = 4294967185u32;\npub const LVN_BEGINSCROLL: u32 = 4294967116u32;\npub const LVN_COLUMNCLICK: u32 = 4294967188u32;\npub const LVN_COLUMNDROPDOWN: u32 = 4294967132u32;\npub const LVN_COLUMNOVERFLOWCLICK: u32 = 4294967130u32;\npub const LVN_DELETEALLITEMS: u32 = 4294967192u32;\npub const LVN_DELETEITEM: u32 = 4294967193u32;\npub const LVN_ENDLABELEDIT: u32 = 4294967120u32;\npub const LVN_ENDLABELEDITA: u32 = 4294967190u32;\npub const LVN_ENDLABELEDITW: u32 = 4294967120u32;\npub const LVN_ENDSCROLL: u32 = 4294967115u32;\npub const LVN_FIRST: u32 = 4294967196u32;\npub const LVN_GETDISPINFO: u32 = 4294967119u32;\npub const LVN_GETDISPINFOA: u32 = 4294967146u32;\npub const LVN_GETDISPINFOW: u32 = 4294967119u32;\npub const LVN_GETEMPTYMARKUP: u32 = 4294967109u32;\npub const LVN_GETINFOTIP: u32 = 4294967138u32;\npub const LVN_GETINFOTIPA: u32 = 4294967139u32;\npub const LVN_GETINFOTIPW: u32 = 4294967138u32;\npub const LVN_HOTTRACK: u32 = 4294967175u32;\npub const LVN_INCREMENTALSEARCH: u32 = 4294967133u32;\npub const LVN_INCREMENTALSEARCHA: u32 = 4294967134u32;\npub const LVN_INCREMENTALSEARCHW: u32 = 4294967133u32;\npub const LVN_INSERTITEM: u32 = 4294967194u32;\npub const LVN_ITEMACTIVATE: u32 = 4294967182u32;\npub const LVN_ITEMCHANGED: u32 = 4294967195u32;\npub const LVN_ITEMCHANGING: u32 = 4294967196u32;\npub const LVN_KEYDOWN: u32 = 4294967141u32;\npub const LVN_LAST: u32 = 4294967097u32;\npub const LVN_LINKCLICK: u32 = 4294967112u32;\npub const LVN_MARQUEEBEGIN: u32 = 4294967140u32;\npub const LVN_ODCACHEHINT: u32 = 4294967183u32;\npub const LVN_ODFINDITEM: u32 = 4294967117u32;\npub const LVN_ODFINDITEMA: u32 = 4294967144u32;\npub const LVN_ODFINDITEMW: u32 = 4294967117u32;\npub const LVN_ODSTATECHANGED: u32 = 4294967181u32;\npub const LVN_SETDISPINFO: u32 = 4294967118u32;\npub const LVN_SETDISPINFOA: u32 = 4294967145u32;\npub const LVN_SETDISPINFOW: u32 = 4294967118u32;\npub const LVP_COLLAPSEBUTTON: LISTVIEWPARTS = 9i32;\npub const LVP_COLUMNDETAIL: LISTVIEWPARTS = 10i32;\npub const LVP_EMPTYTEXT: LISTVIEWPARTS = 5i32;\npub const LVP_EXPANDBUTTON: LISTVIEWPARTS = 8i32;\npub const LVP_GROUPHEADER: LISTVIEWPARTS = 6i32;\npub const LVP_GROUPHEADERLINE: LISTVIEWPARTS = 7i32;\npub const LVP_LISTDETAIL: LISTVIEWPARTS = 3i32;\npub const LVP_LISTGROUP: LISTVIEWPARTS = 2i32;\npub const LVP_LISTITEM: LISTVIEWPARTS = 1i32;\npub const LVP_LISTSORTEDDETAIL: LISTVIEWPARTS = 4i32;\npub const LVSCW_AUTOSIZE: i32 = -1i32;\npub const LVSCW_AUTOSIZE_USEHEADER: i32 = -2i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVSETINFOTIP {\n    pub cbSize: u32,\n    pub dwFlags: u32,\n    pub pszText: windows_sys::core::PWSTR,\n    pub iItem: i32,\n    pub iSubItem: i32,\n}\nimpl Default for LVSETINFOTIP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const LVSICF_NOINVALIDATEALL: u32 = 1u32;\npub const LVSICF_NOSCROLL: u32 = 2u32;\npub const LVSIL_GROUPHEADER: u32 = 3u32;\npub const LVSIL_NORMAL: u32 = 0u32;\npub const LVSIL_SMALL: u32 = 1u32;\npub const LVSIL_STATE: u32 = 2u32;\npub const LVS_ALIGNLEFT: u32 = 2048u32;\npub const LVS_ALIGNMASK: u32 = 3072u32;\npub const LVS_ALIGNTOP: u32 = 0u32;\npub const LVS_AUTOARRANGE: u32 = 256u32;\npub const LVS_EDITLABELS: u32 = 512u32;\npub const LVS_EX_AUTOAUTOARRANGE: u32 = 16777216u32;\npub const LVS_EX_AUTOCHECKSELECT: u32 = 134217728u32;\npub const LVS_EX_AUTOSIZECOLUMNS: u32 = 268435456u32;\npub const LVS_EX_BORDERSELECT: u32 = 32768u32;\npub const LVS_EX_CHECKBOXES: u32 = 4u32;\npub const LVS_EX_COLUMNOVERFLOW: u32 = 2147483648u32;\npub const LVS_EX_COLUMNSNAPPOINTS: u32 = 1073741824u32;\npub const LVS_EX_DOUBLEBUFFER: u32 = 65536u32;\npub const LVS_EX_FLATSB: u32 = 256u32;\npub const LVS_EX_FULLROWSELECT: u32 = 32u32;\npub const LVS_EX_GRIDLINES: u32 = 1u32;\npub const LVS_EX_HEADERDRAGDROP: u32 = 16u32;\npub const LVS_EX_HEADERINALLVIEWS: u32 = 33554432u32;\npub const LVS_EX_HIDELABELS: u32 = 131072u32;\npub const LVS_EX_INFOTIP: u32 = 1024u32;\npub const LVS_EX_JUSTIFYCOLUMNS: u32 = 2097152u32;\npub const LVS_EX_LABELTIP: u32 = 16384u32;\npub const LVS_EX_MULTIWORKAREAS: u32 = 8192u32;\npub const LVS_EX_ONECLICKACTIVATE: u32 = 64u32;\npub const LVS_EX_REGIONAL: u32 = 512u32;\npub const LVS_EX_SIMPLESELECT: u32 = 1048576u32;\npub const LVS_EX_SINGLEROW: u32 = 262144u32;\npub const LVS_EX_SNAPTOGRID: u32 = 524288u32;\npub const LVS_EX_SUBITEMIMAGES: u32 = 2u32;\npub const LVS_EX_TRACKSELECT: u32 = 8u32;\npub const LVS_EX_TRANSPARENTBKGND: u32 = 4194304u32;\npub const LVS_EX_TRANSPARENTSHADOWTEXT: u32 = 8388608u32;\npub const LVS_EX_TWOCLICKACTIVATE: u32 = 128u32;\npub const LVS_EX_UNDERLINECOLD: u32 = 4096u32;\npub const LVS_EX_UNDERLINEHOT: u32 = 2048u32;\npub const LVS_ICON: u32 = 0u32;\npub const LVS_LIST: u32 = 3u32;\npub const LVS_NOCOLUMNHEADER: u32 = 16384u32;\npub const LVS_NOLABELWRAP: u32 = 128u32;\npub const LVS_NOSCROLL: u32 = 8192u32;\npub const LVS_NOSORTHEADER: u32 = 32768u32;\npub const LVS_OWNERDATA: u32 = 4096u32;\npub const LVS_OWNERDRAWFIXED: u32 = 1024u32;\npub const LVS_REPORT: u32 = 1u32;\npub const LVS_SHAREIMAGELISTS: u32 = 64u32;\npub const LVS_SHOWSELALWAYS: u32 = 8u32;\npub const LVS_SINGLESEL: u32 = 4u32;\npub const LVS_SMALLICON: u32 = 2u32;\npub const LVS_SORTASCENDING: u32 = 16u32;\npub const LVS_SORTDESCENDING: u32 = 32u32;\npub const LVS_TYPEMASK: u32 = 3u32;\npub const LVS_TYPESTYLEMASK: u32 = 64512u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct LVTILEINFO {\n    pub cbSize: u32,\n    pub iItem: i32,\n    pub cColumns: u32,\n    pub puColumns: *mut u32,\n    pub piColFmt: *mut i32,\n}\nimpl Default for LVTILEINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct LVTILEVIEWINFO {\n    pub cbSize: u32,\n    pub dwMask: LVTILEVIEWINFO_MASK,\n    pub dwFlags: LVTILEVIEWINFO_FLAGS,\n    pub sizeTile: super::super::Foundation::SIZE,\n    pub cLines: i32,\n    pub rcLabelMargin: super::super::Foundation::RECT,\n}\npub type LVTILEVIEWINFO_FLAGS = u32;\npub type LVTILEVIEWINFO_MASK = u32;\npub const LVTVIF_AUTOSIZE: LVTILEVIEWINFO_FLAGS = 0u32;\npub const LVTVIF_EXTENDED: u32 = 4u32;\npub const LVTVIF_FIXEDHEIGHT: LVTILEVIEWINFO_FLAGS = 2u32;\npub const LVTVIF_FIXEDSIZE: LVTILEVIEWINFO_FLAGS = 3u32;\npub const LVTVIF_FIXEDWIDTH: LVTILEVIEWINFO_FLAGS = 1u32;\npub const LVTVIM_COLUMNS: LVTILEVIEWINFO_MASK = 2u32;\npub const LVTVIM_LABELMARGIN: LVTILEVIEWINFO_MASK = 4u32;\npub const LVTVIM_TILESIZE: LVTILEVIEWINFO_MASK = 1u32;\npub const LV_MAX_WORKAREAS: u32 = 16u32;\npub const LV_VIEW_DETAILS: u32 = 1u32;\npub const LV_VIEW_ICON: u32 = 0u32;\npub const LV_VIEW_LIST: u32 = 3u32;\npub const LV_VIEW_MAX: u32 = 4u32;\npub const LV_VIEW_SMALLICON: u32 = 2u32;\npub const LV_VIEW_TILE: u32 = 4u32;\npub const LWS_IGNORERETURN: u32 = 2u32;\npub const LWS_NOPREFIX: u32 = 4u32;\npub const LWS_RIGHT: u32 = 32u32;\npub const LWS_TRANSPARENT: u32 = 1u32;\npub const LWS_USECUSTOMTEXT: u32 = 16u32;\npub const LWS_USEVISUALSTYLE: u32 = 8u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct MARGINS {\n    pub cxLeftWidth: i32,\n    pub cxRightWidth: i32,\n    pub cyTopHeight: i32,\n    pub cyBottomHeight: i32,\n}\npub type MARKUPTEXTSTATES = i32;\npub const MAXBS_DISABLED: MAXBUTTONSTATES = 4i32;\npub const MAXBS_HOT: MAXBUTTONSTATES = 2i32;\npub const MAXBS_NORMAL: MAXBUTTONSTATES = 1i32;\npub const MAXBS_PUSHED: MAXBUTTONSTATES = 3i32;\npub type MAXBUTTONSTATES = i32;\npub type MAXCAPTIONSTATES = i32;\npub const MAXPROPPAGES: u32 = 100u32;\npub const MAX_INTLIST_COUNT: u32 = 402u32;\npub const MAX_LINKID_TEXT: u32 = 48u32;\npub const MAX_THEMECOLOR: u32 = 64u32;\npub const MAX_THEMESIZE: u32 = 64u32;\npub const MBI_DISABLED: BARITEMSTATES = 4i32;\npub const MBI_DISABLEDHOT: BARITEMSTATES = 5i32;\npub const MBI_DISABLEDPUSHED: BARITEMSTATES = 6i32;\npub const MBI_HOT: BARITEMSTATES = 2i32;\npub const MBI_NORMAL: BARITEMSTATES = 1i32;\npub const MBI_PUSHED: BARITEMSTATES = 3i32;\npub const MB_ACTIVE: BARBACKGROUNDSTATES = 1i32;\npub const MB_INACTIVE: BARBACKGROUNDSTATES = 2i32;\npub const MCB_BITMAP: POPUPCHECKBACKGROUNDSTATES = 3i32;\npub const MCB_DISABLED: POPUPCHECKBACKGROUNDSTATES = 1i32;\npub const MCB_NORMAL: POPUPCHECKBACKGROUNDSTATES = 2i32;\npub const MCGCB_HOT: GRIDCELLBACKGROUNDSTATES = 2i32;\npub const MCGCB_SELECTED: GRIDCELLBACKGROUNDSTATES = 1i32;\npub const MCGCB_SELECTEDHOT: GRIDCELLBACKGROUNDSTATES = 3i32;\npub const MCGCB_SELECTEDNOTFOCUSED: GRIDCELLBACKGROUNDSTATES = 4i32;\npub const MCGCB_TODAY: GRIDCELLBACKGROUNDSTATES = 5i32;\npub const MCGCB_TODAYSELECTED: GRIDCELLBACKGROUNDSTATES = 6i32;\npub const MCGCU_HASSTATE: GRIDCELLUPPERSTATES = 2i32;\npub const MCGCU_HASSTATEHOT: GRIDCELLUPPERSTATES = 3i32;\npub const MCGCU_HOT: GRIDCELLUPPERSTATES = 1i32;\npub const MCGCU_SELECTED: GRIDCELLUPPERSTATES = 4i32;\npub const MCGCU_SELECTEDHOT: GRIDCELLUPPERSTATES = 5i32;\npub const MCGC_HASSTATE: GRIDCELLSTATES = 2i32;\npub const MCGC_HASSTATEHOT: GRIDCELLSTATES = 3i32;\npub const MCGC_HOT: GRIDCELLSTATES = 1i32;\npub const MCGC_SELECTED: GRIDCELLSTATES = 6i32;\npub const MCGC_SELECTEDHOT: GRIDCELLSTATES = 7i32;\npub const MCGC_TODAY: GRIDCELLSTATES = 4i32;\npub const MCGC_TODAYSELECTED: GRIDCELLSTATES = 5i32;\npub const MCGIF_DATE: MCGRIDINFO_FLAGS = 1u32;\npub const MCGIF_NAME: MCGRIDINFO_FLAGS = 4u32;\npub const MCGIF_RECT: MCGRIDINFO_FLAGS = 2u32;\npub const MCGIP_CALENDAR: MCGRIDINFO_PART = 4u32;\npub const MCGIP_CALENDARBODY: MCGRIDINFO_PART = 6u32;\npub const MCGIP_CALENDARCELL: MCGRIDINFO_PART = 8u32;\npub const MCGIP_CALENDARCONTROL: MCGRIDINFO_PART = 0u32;\npub const MCGIP_CALENDARHEADER: MCGRIDINFO_PART = 5u32;\npub const MCGIP_CALENDARROW: MCGRIDINFO_PART = 7u32;\npub const MCGIP_FOOTER: MCGRIDINFO_PART = 3u32;\npub const MCGIP_NEXT: MCGRIDINFO_PART = 1u32;\npub const MCGIP_PREV: MCGRIDINFO_PART = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct MCGRIDINFO {\n    pub cbSize: u32,\n    pub dwPart: MCGRIDINFO_PART,\n    pub dwFlags: MCGRIDINFO_FLAGS,\n    pub iCalendar: i32,\n    pub iRow: i32,\n    pub iCol: i32,\n    pub bSelected: windows_sys::core::BOOL,\n    pub stStart: super::super::Foundation::SYSTEMTIME,\n    pub stEnd: super::super::Foundation::SYSTEMTIME,\n    pub rc: super::super::Foundation::RECT,\n    pub pszName: windows_sys::core::PWSTR,\n    pub cchName: usize,\n}\nimpl Default for MCGRIDINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type MCGRIDINFO_FLAGS = u32;\npub type MCGRIDINFO_PART = u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct MCHITTESTINFO {\n    pub cbSize: u32,\n    pub pt: super::super::Foundation::POINT,\n    pub uHit: MCHITTESTINFO_HIT_FLAGS,\n    pub st: super::super::Foundation::SYSTEMTIME,\n    pub rc: super::super::Foundation::RECT,\n    pub iOffset: i32,\n    pub iRow: i32,\n    pub iCol: i32,\n}\npub type MCHITTESTINFO_HIT_FLAGS = u32;\npub const MCHT_CALENDAR: MCHITTESTINFO_HIT_FLAGS = 131072u32;\npub const MCHT_CALENDARBK: MCHITTESTINFO_HIT_FLAGS = 131072u32;\npub const MCHT_CALENDARCONTROL: MCHITTESTINFO_HIT_FLAGS = 1048576u32;\npub const MCHT_CALENDARDATE: MCHITTESTINFO_HIT_FLAGS = 131073u32;\npub const MCHT_CALENDARDATEMAX: MCHITTESTINFO_HIT_FLAGS = 131077u32;\npub const MCHT_CALENDARDATEMIN: MCHITTESTINFO_HIT_FLAGS = 131076u32;\npub const MCHT_CALENDARDATENEXT: MCHITTESTINFO_HIT_FLAGS = 16908289u32;\npub const MCHT_CALENDARDATEPREV: MCHITTESTINFO_HIT_FLAGS = 33685505u32;\npub const MCHT_CALENDARDAY: MCHITTESTINFO_HIT_FLAGS = 131074u32;\npub const MCHT_CALENDARWEEKNUM: MCHITTESTINFO_HIT_FLAGS = 131075u32;\npub const MCHT_NEXT: MCHITTESTINFO_HIT_FLAGS = 16777216u32;\npub const MCHT_NOWHERE: MCHITTESTINFO_HIT_FLAGS = 0u32;\npub const MCHT_PREV: MCHITTESTINFO_HIT_FLAGS = 33554432u32;\npub const MCHT_TITLE: MCHITTESTINFO_HIT_FLAGS = 65536u32;\npub const MCHT_TITLEBK: MCHITTESTINFO_HIT_FLAGS = 65536u32;\npub const MCHT_TITLEBTNNEXT: MCHITTESTINFO_HIT_FLAGS = 16842755u32;\npub const MCHT_TITLEBTNPREV: MCHITTESTINFO_HIT_FLAGS = 33619971u32;\npub const MCHT_TITLEMONTH: MCHITTESTINFO_HIT_FLAGS = 65537u32;\npub const MCHT_TITLEYEAR: MCHITTESTINFO_HIT_FLAGS = 65538u32;\npub const MCHT_TODAYLINK: MCHITTESTINFO_HIT_FLAGS = 196608u32;\npub const MCMV_CENTURY: MONTH_CALDENDAR_MESSAGES_VIEW = 3u32;\npub const MCMV_DECADE: MONTH_CALDENDAR_MESSAGES_VIEW = 2u32;\npub const MCMV_MAX: MONTH_CALDENDAR_MESSAGES_VIEW = 3u32;\npub const MCMV_MONTH: MONTH_CALDENDAR_MESSAGES_VIEW = 0u32;\npub const MCMV_YEAR: MONTH_CALDENDAR_MESSAGES_VIEW = 1u32;\npub const MCM_FIRST: u32 = 4096u32;\npub const MCM_GETCALENDARBORDER: u32 = 4127u32;\npub const MCM_GETCALENDARCOUNT: u32 = 4119u32;\npub const MCM_GETCALENDARGRIDINFO: u32 = 4120u32;\npub const MCM_GETCALID: u32 = 4123u32;\npub const MCM_GETCOLOR: u32 = 4107u32;\npub const MCM_GETCURRENTVIEW: u32 = 4118u32;\npub const MCM_GETCURSEL: u32 = 4097u32;\npub const MCM_GETFIRSTDAYOFWEEK: u32 = 4112u32;\npub const MCM_GETMAXSELCOUNT: u32 = 4099u32;\npub const MCM_GETMAXTODAYWIDTH: u32 = 4117u32;\npub const MCM_GETMINREQRECT: u32 = 4105u32;\npub const MCM_GETMONTHDELTA: u32 = 4115u32;\npub const MCM_GETMONTHRANGE: u32 = 4103u32;\npub const MCM_GETRANGE: u32 = 4113u32;\npub const MCM_GETSELRANGE: u32 = 4101u32;\npub const MCM_GETTODAY: u32 = 4109u32;\npub const MCM_GETUNICODEFORMAT: u32 = 8198u32;\npub const MCM_HITTEST: u32 = 4110u32;\npub const MCM_SETCALENDARBORDER: u32 = 4126u32;\npub const MCM_SETCALID: u32 = 4124u32;\npub const MCM_SETCOLOR: u32 = 4106u32;\npub const MCM_SETCURRENTVIEW: u32 = 4128u32;\npub const MCM_SETCURSEL: u32 = 4098u32;\npub const MCM_SETDAYSTATE: u32 = 4104u32;\npub const MCM_SETFIRSTDAYOFWEEK: u32 = 4111u32;\npub const MCM_SETMAXSELCOUNT: u32 = 4100u32;\npub const MCM_SETMONTHDELTA: u32 = 4116u32;\npub const MCM_SETRANGE: u32 = 4114u32;\npub const MCM_SETSELRANGE: u32 = 4102u32;\npub const MCM_SETTODAY: u32 = 4108u32;\npub const MCM_SETUNICODEFORMAT: u32 = 8197u32;\npub const MCM_SIZERECTTOMIN: u32 = 4125u32;\npub const MCNN_DISABLED: NAVNEXTSTATES = 4i32;\npub const MCNN_HOT: NAVNEXTSTATES = 2i32;\npub const MCNN_NORMAL: NAVNEXTSTATES = 1i32;\npub const MCNN_PRESSED: NAVNEXTSTATES = 3i32;\npub const MCNP_DISABLED: NAVPREVSTATES = 4i32;\npub const MCNP_HOT: NAVPREVSTATES = 2i32;\npub const MCNP_NORMAL: NAVPREVSTATES = 1i32;\npub const MCNP_PRESSED: NAVPREVSTATES = 3i32;\npub const MCN_FIRST: u32 = 4294966550u32;\npub const MCN_GETDAYSTATE: u32 = 4294966549u32;\npub const MCN_LAST: u32 = 4294966544u32;\npub const MCN_SELCHANGE: u32 = 4294966547u32;\npub const MCN_SELECT: u32 = 4294966550u32;\npub const MCN_VIEWCHANGE: u32 = 4294966546u32;\npub const MCSC_BACKGROUND: u32 = 0u32;\npub const MCSC_MONTHBK: u32 = 4u32;\npub const MCSC_TEXT: u32 = 1u32;\npub const MCSC_TITLEBK: u32 = 2u32;\npub const MCSC_TITLETEXT: u32 = 3u32;\npub const MCSC_TRAILINGTEXT: u32 = 5u32;\npub const MCS_DAYSTATE: u32 = 1u32;\npub const MCS_MULTISELECT: u32 = 2u32;\npub const MCS_NOSELCHANGEONNAV: u32 = 256u32;\npub const MCS_NOTODAY: u32 = 16u32;\npub const MCS_NOTODAYCIRCLE: u32 = 8u32;\npub const MCS_NOTRAILINGDATES: u32 = 64u32;\npub const MCS_SHORTDAYSOFWEEK: u32 = 128u32;\npub const MCS_WEEKNUMBERS: u32 = 4u32;\npub const MCTGCU_HASSTATE: TRAILINGGRIDCELLUPPERSTATES = 2i32;\npub const MCTGCU_HASSTATEHOT: TRAILINGGRIDCELLUPPERSTATES = 3i32;\npub const MCTGCU_HOT: TRAILINGGRIDCELLUPPERSTATES = 1i32;\npub const MCTGCU_SELECTED: TRAILINGGRIDCELLUPPERSTATES = 4i32;\npub const MCTGCU_SELECTEDHOT: TRAILINGGRIDCELLUPPERSTATES = 5i32;\npub const MCTGC_HASSTATE: TRAILINGGRIDCELLSTATES = 2i32;\npub const MCTGC_HASSTATEHOT: TRAILINGGRIDCELLSTATES = 3i32;\npub const MCTGC_HOT: TRAILINGGRIDCELLSTATES = 1i32;\npub const MCTGC_SELECTED: TRAILINGGRIDCELLSTATES = 6i32;\npub const MCTGC_SELECTEDHOT: TRAILINGGRIDCELLSTATES = 7i32;\npub const MCTGC_TODAY: TRAILINGGRIDCELLSTATES = 4i32;\npub const MCTGC_TODAYSELECTED: TRAILINGGRIDCELLSTATES = 5i32;\npub const MC_BACKGROUND: MONTHCALPARTS = 1i32;\npub const MC_BORDERS: MONTHCALPARTS = 2i32;\npub const MC_BULLETDISABLED: POPUPCHECKSTATES = 4i32;\npub const MC_BULLETNORMAL: POPUPCHECKSTATES = 3i32;\npub const MC_CHECKMARKDISABLED: POPUPCHECKSTATES = 2i32;\npub const MC_CHECKMARKNORMAL: POPUPCHECKSTATES = 1i32;\npub const MC_COLHEADERSPLITTER: MONTHCALPARTS = 4i32;\npub const MC_GRIDBACKGROUND: MONTHCALPARTS = 3i32;\npub const MC_GRIDCELL: MONTHCALPARTS = 6i32;\npub const MC_GRIDCELLBACKGROUND: MONTHCALPARTS = 5i32;\npub const MC_GRIDCELLUPPER: MONTHCALPARTS = 7i32;\npub const MC_NAVNEXT: MONTHCALPARTS = 10i32;\npub const MC_NAVPREV: MONTHCALPARTS = 11i32;\npub const MC_TRAILINGGRIDCELL: MONTHCALPARTS = 8i32;\npub const MC_TRAILINGGRIDCELLUPPER: MONTHCALPARTS = 9i32;\npub const MDCL_DISABLED: MDICLOSEBUTTONSTATES = 4i32;\npub const MDCL_HOT: MDICLOSEBUTTONSTATES = 2i32;\npub const MDCL_NORMAL: MDICLOSEBUTTONSTATES = 1i32;\npub const MDCL_PUSHED: MDICLOSEBUTTONSTATES = 3i32;\npub type MDICLOSEBUTTONSTATES = i32;\npub type MDIMINBUTTONSTATES = i32;\npub type MDIRESTOREBUTTONSTATES = i32;\npub const MDMI_DISABLED: MDIMINBUTTONSTATES = 4i32;\npub const MDMI_HOT: MDIMINBUTTONSTATES = 2i32;\npub const MDMI_NORMAL: MDIMINBUTTONSTATES = 1i32;\npub const MDMI_PUSHED: MDIMINBUTTONSTATES = 3i32;\npub const MDP_NEWAPPBUTTON: MENUBANDPARTS = 1i32;\npub const MDP_SEPERATOR: MENUBANDPARTS = 2i32;\npub const MDRE_DISABLED: MDIRESTOREBUTTONSTATES = 4i32;\npub const MDRE_HOT: MDIRESTOREBUTTONSTATES = 2i32;\npub const MDRE_NORMAL: MDIRESTOREBUTTONSTATES = 1i32;\npub const MDRE_PUSHED: MDIRESTOREBUTTONSTATES = 3i32;\npub const MDS_CHECKED: MENUBANDSTATES = 5i32;\npub const MDS_DISABLED: MENUBANDSTATES = 4i32;\npub const MDS_HOT: MENUBANDSTATES = 2i32;\npub const MDS_HOTCHECKED: MENUBANDSTATES = 6i32;\npub const MDS_NORMAL: MENUBANDSTATES = 1i32;\npub const MDS_PRESSED: MENUBANDSTATES = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct MEASUREITEMSTRUCT {\n    pub CtlType: DRAWITEMSTRUCT_CTL_TYPE,\n    pub CtlID: u32,\n    pub itemID: u32,\n    pub itemWidth: u32,\n    pub itemHeight: u32,\n    pub itemData: usize,\n}\npub type MENUBANDPARTS = i32;\npub type MENUBANDSTATES = i32;\npub type MENUPARTS = i32;\npub const MENU_BARBACKGROUND: MENUPARTS = 7i32;\npub const MENU_BARITEM: MENUPARTS = 8i32;\npub const MENU_CHEVRON_TMSCHEMA: MENUPARTS = 5i32;\npub const MENU_MENUBARDROPDOWN_TMSCHEMA: MENUPARTS = 4i32;\npub const MENU_MENUBARITEM_TMSCHEMA: MENUPARTS = 3i32;\npub const MENU_MENUDROPDOWN_TMSCHEMA: MENUPARTS = 2i32;\npub const MENU_MENUITEM_TMSCHEMA: MENUPARTS = 1i32;\npub const MENU_POPUPBACKGROUND: MENUPARTS = 9i32;\npub const MENU_POPUPBORDERS: MENUPARTS = 10i32;\npub const MENU_POPUPCHECK: MENUPARTS = 11i32;\npub const MENU_POPUPCHECKBACKGROUND: MENUPARTS = 12i32;\npub const MENU_POPUPGUTTER: MENUPARTS = 13i32;\npub const MENU_POPUPITEM: MENUPARTS = 14i32;\npub const MENU_POPUPITEMKBFOCUS: MENUPARTS = 26i32;\npub const MENU_POPUPITEM_FOCUSABLE: MENUPARTS = 27i32;\npub const MENU_POPUPSEPARATOR: MENUPARTS = 15i32;\npub const MENU_POPUPSUBMENU: MENUPARTS = 16i32;\npub const MENU_POPUPSUBMENU_HCHOT: MENUPARTS = 21i32;\npub const MENU_SEPARATOR_TMSCHEMA: MENUPARTS = 6i32;\npub const MENU_SYSTEMCLOSE: MENUPARTS = 17i32;\npub const MENU_SYSTEMCLOSE_HCHOT: MENUPARTS = 22i32;\npub const MENU_SYSTEMMAXIMIZE: MENUPARTS = 18i32;\npub const MENU_SYSTEMMAXIMIZE_HCHOT: MENUPARTS = 23i32;\npub const MENU_SYSTEMMINIMIZE: MENUPARTS = 19i32;\npub const MENU_SYSTEMMINIMIZE_HCHOT: MENUPARTS = 24i32;\npub const MENU_SYSTEMRESTORE: MENUPARTS = 20i32;\npub const MENU_SYSTEMRESTORE_HCHOT: MENUPARTS = 25i32;\npub const MINBS_DISABLED: MINBUTTONSTATES = 4i32;\npub const MINBS_HOT: MINBUTTONSTATES = 2i32;\npub const MINBS_NORMAL: MINBUTTONSTATES = 1i32;\npub const MINBS_PUSHED: MINBUTTONSTATES = 3i32;\npub type MINBUTTONSTATES = i32;\npub type MINCAPTIONSTATES = i32;\npub const MNCS_ACTIVE: MINCAPTIONSTATES = 1i32;\npub const MNCS_DISABLED: MINCAPTIONSTATES = 3i32;\npub const MNCS_INACTIVE: MINCAPTIONSTATES = 2i32;\npub type MONTHCALPARTS = i32;\npub const MONTHCAL_CLASS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysMonthCal32\");\npub const MONTHCAL_CLASSA: windows_sys::core::PCSTR = windows_sys::core::s!(\"SysMonthCal32\");\npub const MONTHCAL_CLASSW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysMonthCal32\");\npub type MONTH_CALDENDAR_MESSAGES_VIEW = u32;\npub type MOREPROGRAMSARROWBACKSTATES = i32;\npub type MOREPROGRAMSARROWSTATES = i32;\npub type MOREPROGRAMSTABSTATES = i32;\npub type MOVESTATES = i32;\npub const MPIF_DISABLED: POPUPITEMFOCUSABLESTATES = 3i32;\npub const MPIF_DISABLEDHOT: POPUPITEMFOCUSABLESTATES = 4i32;\npub const MPIF_HOT: POPUPITEMFOCUSABLESTATES = 2i32;\npub const MPIF_NORMAL: POPUPITEMFOCUSABLESTATES = 1i32;\npub const MPIKBFOCUS_NORMAL: POPUPITEMKBFOCUSSTATES = 1i32;\npub const MPI_DISABLED: POPUPITEMSTATES = 3i32;\npub const MPI_DISABLEDHOT: POPUPITEMSTATES = 4i32;\npub const MPI_HOT: POPUPITEMSTATES = 2i32;\npub const MPI_NORMAL: POPUPITEMSTATES = 1i32;\npub const MSGF_COMMCTRL_BEGINDRAG: u32 = 16896u32;\npub const MSGF_COMMCTRL_DRAGSELECT: u32 = 16898u32;\npub const MSGF_COMMCTRL_SIZEHEADER: u32 = 16897u32;\npub const MSGF_COMMCTRL_TOOLBARCUST: u32 = 16899u32;\npub const MSMHC_HOT: POPUPSUBMENUHCHOTSTATES = 1i32;\npub const MSM_DISABLED: POPUPSUBMENUSTATES = 2i32;\npub const MSM_NORMAL: POPUPSUBMENUSTATES = 1i32;\npub const MSYSCHC_HOT: SYSTEMCLOSEHCHOTSTATES = 1i32;\npub const MSYSC_DISABLED: SYSTEMCLOSESTATES = 2i32;\npub const MSYSC_NORMAL: SYSTEMCLOSESTATES = 1i32;\npub const MSYSMNHC_HOT: SYSTEMMINIMIZEHCHOTSTATES = 1i32;\npub const MSYSMN_DISABLED: SYSTEMMINIMIZESTATES = 2i32;\npub const MSYSMN_NORMAL: SYSTEMMINIMIZESTATES = 1i32;\npub const MSYSMXHC_HOT: SYSTEMMAXIMIZEHCHOTSTATES = 1i32;\npub const MSYSMX_DISABLED: SYSTEMMAXIMIZESTATES = 2i32;\npub const MSYSMX_NORMAL: SYSTEMMAXIMIZESTATES = 1i32;\npub const MSYSRHC_HOT: SYSTEMRESTOREHCHOTSTATES = 1i32;\npub const MSYSR_DISABLED: SYSTEMRESTORESTATES = 2i32;\npub const MSYSR_NORMAL: SYSTEMRESTORESTATES = 1i32;\npub const MULTIFILEOPENORD: u32 = 1537u32;\npub const MXCS_ACTIVE: MAXCAPTIONSTATES = 1i32;\npub const MXCS_DISABLED: MAXCAPTIONSTATES = 3i32;\npub const MXCS_INACTIVE: MAXCAPTIONSTATES = 2i32;\npub type NAVIGATIONPARTS = i32;\npub type NAVNEXTSTATES = i32;\npub type NAVPREVSTATES = i32;\npub const NAV_BACKBUTTON: NAVIGATIONPARTS = 1i32;\npub type NAV_BACKBUTTONSTATES = i32;\npub const NAV_BB_DISABLED: NAV_BACKBUTTONSTATES = 4i32;\npub const NAV_BB_HOT: NAV_BACKBUTTONSTATES = 2i32;\npub const NAV_BB_NORMAL: NAV_BACKBUTTONSTATES = 1i32;\npub const NAV_BB_PRESSED: NAV_BACKBUTTONSTATES = 3i32;\npub const NAV_FB_DISABLED: NAV_FORWARDBUTTONSTATES = 4i32;\npub const NAV_FB_HOT: NAV_FORWARDBUTTONSTATES = 2i32;\npub const NAV_FB_NORMAL: NAV_FORWARDBUTTONSTATES = 1i32;\npub const NAV_FB_PRESSED: NAV_FORWARDBUTTONSTATES = 3i32;\npub const NAV_FORWARDBUTTON: NAVIGATIONPARTS = 2i32;\npub type NAV_FORWARDBUTTONSTATES = i32;\npub const NAV_MB_DISABLED: NAV_MENUBUTTONSTATES = 4i32;\npub const NAV_MB_HOT: NAV_MENUBUTTONSTATES = 2i32;\npub const NAV_MB_NORMAL: NAV_MENUBUTTONSTATES = 1i32;\npub const NAV_MB_PRESSED: NAV_MENUBUTTONSTATES = 3i32;\npub const NAV_MENUBUTTON: NAVIGATIONPARTS = 3i32;\npub type NAV_MENUBUTTONSTATES = i32;\npub const NEWFILEOPENORD: u32 = 1547u32;\npub const NEWFILEOPENV2ORD: u32 = 1552u32;\npub const NEWFILEOPENV3ORD: u32 = 1553u32;\npub const NEWFORMATDLGWITHLINK: u32 = 1591u32;\npub const NFS_ALL: u32 = 16u32;\npub const NFS_BUTTON: u32 = 8u32;\npub const NFS_EDIT: u32 = 1u32;\npub const NFS_LISTCOMBO: u32 = 4u32;\npub const NFS_STATIC: u32 = 2u32;\npub const NFS_USEFONTASSOC: u32 = 32u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMBCDROPDOWN {\n    pub hdr: NMHDR,\n    pub rcButton: super::super::Foundation::RECT,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMBCHOTITEM {\n    pub hdr: NMHDR,\n    pub dwFlags: NMTBHOTITEM_FLAGS,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMCBEDRAGBEGINA {\n    pub hdr: NMHDR,\n    pub iItemid: i32,\n    pub szText: [i8; 260],\n}\nimpl Default for NMCBEDRAGBEGINA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMCBEDRAGBEGINW {\n    pub hdr: NMHDR,\n    pub iItemid: i32,\n    pub szText: [u16; 260],\n}\nimpl Default for NMCBEDRAGBEGINW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMCBEENDEDITA {\n    pub hdr: NMHDR,\n    pub fChanged: windows_sys::core::BOOL,\n    pub iNewSelection: i32,\n    pub szText: [i8; 260],\n    pub iWhy: i32,\n}\nimpl Default for NMCBEENDEDITA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMCBEENDEDITW {\n    pub hdr: NMHDR,\n    pub fChanged: windows_sys::core::BOOL,\n    pub iNewSelection: i32,\n    pub szText: [u16; 260],\n    pub iWhy: i32,\n}\nimpl Default for NMCBEENDEDITW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMCHAR {\n    pub hdr: NMHDR,\n    pub ch: u32,\n    pub dwItemPrev: u32,\n    pub dwItemNext: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMCOMBOBOXEXA {\n    pub hdr: NMHDR,\n    pub ceItem: COMBOBOXEXITEMA,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMCOMBOBOXEXW {\n    pub hdr: NMHDR,\n    pub ceItem: COMBOBOXEXITEMW,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct NMCUSTOMDRAW {\n    pub hdr: NMHDR,\n    pub dwDrawStage: NMCUSTOMDRAW_DRAW_STAGE,\n    pub hdc: super::super::Graphics::Gdi::HDC,\n    pub rc: super::super::Foundation::RECT,\n    pub dwItemSpec: usize,\n    pub uItemState: NMCUSTOMDRAW_DRAW_STATE_FLAGS,\n    pub lItemlParam: super::super::Foundation::LPARAM,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for NMCUSTOMDRAW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type NMCUSTOMDRAW_DRAW_STAGE = u32;\npub type NMCUSTOMDRAW_DRAW_STATE_FLAGS = u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMCUSTOMSPLITRECTINFO {\n    pub hdr: NMHDR,\n    pub rcClient: super::super::Foundation::RECT,\n    pub rcButton: super::super::Foundation::RECT,\n    pub rcSplit: super::super::Foundation::RECT,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct NMCUSTOMTEXT {\n    pub hdr: NMHDR,\n    pub hDC: super::super::Graphics::Gdi::HDC,\n    pub lpString: windows_sys::core::PCWSTR,\n    pub nCount: i32,\n    pub lpRect: *mut super::super::Foundation::RECT,\n    pub uFormat: u32,\n    pub fLink: windows_sys::core::BOOL,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for NMCUSTOMTEXT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMDATETIMECHANGE {\n    pub nmhdr: NMHDR,\n    pub dwFlags: NMDATETIMECHANGE_FLAGS,\n    pub st: super::super::Foundation::SYSTEMTIME,\n}\npub type NMDATETIMECHANGE_FLAGS = u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMDATETIMEFORMATA {\n    pub nmhdr: NMHDR,\n    pub pszFormat: windows_sys::core::PCSTR,\n    pub st: super::super::Foundation::SYSTEMTIME,\n    pub pszDisplay: windows_sys::core::PCSTR,\n    pub szDisplay: [i8; 64],\n}\nimpl Default for NMDATETIMEFORMATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMDATETIMEFORMATQUERYA {\n    pub nmhdr: NMHDR,\n    pub pszFormat: windows_sys::core::PCSTR,\n    pub szMax: super::super::Foundation::SIZE,\n}\nimpl Default for NMDATETIMEFORMATQUERYA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMDATETIMEFORMATQUERYW {\n    pub nmhdr: NMHDR,\n    pub pszFormat: windows_sys::core::PCWSTR,\n    pub szMax: super::super::Foundation::SIZE,\n}\nimpl Default for NMDATETIMEFORMATQUERYW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMDATETIMEFORMATW {\n    pub nmhdr: NMHDR,\n    pub pszFormat: windows_sys::core::PCWSTR,\n    pub st: super::super::Foundation::SYSTEMTIME,\n    pub pszDisplay: windows_sys::core::PCWSTR,\n    pub szDisplay: [u16; 64],\n}\nimpl Default for NMDATETIMEFORMATW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMDATETIMESTRINGA {\n    pub nmhdr: NMHDR,\n    pub pszUserString: windows_sys::core::PCSTR,\n    pub st: super::super::Foundation::SYSTEMTIME,\n    pub dwFlags: u32,\n}\nimpl Default for NMDATETIMESTRINGA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMDATETIMESTRINGW {\n    pub nmhdr: NMHDR,\n    pub pszUserString: windows_sys::core::PCWSTR,\n    pub st: super::super::Foundation::SYSTEMTIME,\n    pub dwFlags: u32,\n}\nimpl Default for NMDATETIMESTRINGW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMDATETIMEWMKEYDOWNA {\n    pub nmhdr: NMHDR,\n    pub nVirtKey: i32,\n    pub pszFormat: windows_sys::core::PCSTR,\n    pub st: super::super::Foundation::SYSTEMTIME,\n}\nimpl Default for NMDATETIMEWMKEYDOWNA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMDATETIMEWMKEYDOWNW {\n    pub nmhdr: NMHDR,\n    pub nVirtKey: i32,\n    pub pszFormat: windows_sys::core::PCWSTR,\n    pub st: super::super::Foundation::SYSTEMTIME,\n}\nimpl Default for NMDATETIMEWMKEYDOWNW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMDAYSTATE {\n    pub nmhdr: NMHDR,\n    pub stStart: super::super::Foundation::SYSTEMTIME,\n    pub cDayState: i32,\n    pub prgDayState: *mut u32,\n}\nimpl Default for NMDAYSTATE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMHDDISPINFOA {\n    pub hdr: NMHDR,\n    pub iItem: i32,\n    pub mask: HDI_MASK,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for NMHDDISPINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMHDDISPINFOW {\n    pub hdr: NMHDR,\n    pub iItem: i32,\n    pub mask: HDI_MASK,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for NMHDDISPINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMHDFILTERBTNCLICK {\n    pub hdr: NMHDR,\n    pub iItem: i32,\n    pub rc: super::super::Foundation::RECT,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMHDR {\n    pub hwndFrom: super::super::Foundation::HWND,\n    pub idFrom: usize,\n    pub code: u32,\n}\nimpl Default for NMHDR {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct NMHEADERA {\n    pub hdr: NMHDR,\n    pub iItem: i32,\n    pub iButton: HEADER_CONTROL_NOTIFICATION_BUTTON,\n    pub pitem: *mut HDITEMA,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for NMHEADERA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct NMHEADERW {\n    pub hdr: NMHDR,\n    pub iItem: i32,\n    pub iButton: HEADER_CONTROL_NOTIFICATION_BUTTON,\n    pub pitem: *mut HDITEMW,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for NMHEADERW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMIPADDRESS {\n    pub hdr: NMHDR,\n    pub iField: i32,\n    pub iValue: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMITEMACTIVATE {\n    pub hdr: NMHDR,\n    pub iItem: i32,\n    pub iSubItem: i32,\n    pub uNewState: u32,\n    pub uOldState: u32,\n    pub uChanged: u32,\n    pub ptAction: super::super::Foundation::POINT,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub uKeyFlags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMKEY {\n    pub hdr: NMHDR,\n    pub nVKey: u32,\n    pub uFlags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMLINK {\n    pub hdr: NMHDR,\n    pub item: LITEM,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMLISTVIEW {\n    pub hdr: NMHDR,\n    pub iItem: i32,\n    pub iSubItem: i32,\n    pub uNewState: u32,\n    pub uOldState: u32,\n    pub uChanged: LIST_VIEW_ITEM_FLAGS,\n    pub ptAction: super::super::Foundation::POINT,\n    pub lParam: super::super::Foundation::LPARAM,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMLVCACHEHINT {\n    pub hdr: NMHDR,\n    pub iFrom: i32,\n    pub iTo: i32,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct NMLVCUSTOMDRAW {\n    pub nmcd: NMCUSTOMDRAW,\n    pub clrText: super::super::Foundation::COLORREF,\n    pub clrTextBk: super::super::Foundation::COLORREF,\n    pub iSubItem: i32,\n    pub dwItemType: NMLVCUSTOMDRAW_ITEM_TYPE,\n    pub clrFace: super::super::Foundation::COLORREF,\n    pub iIconEffect: i32,\n    pub iIconPhase: i32,\n    pub iPartId: i32,\n    pub iStateId: i32,\n    pub rcText: super::super::Foundation::RECT,\n    pub uAlign: LIST_VIEW_GROUP_ALIGN_FLAGS,\n}\npub type NMLVCUSTOMDRAW_ITEM_TYPE = u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMLVDISPINFOA {\n    pub hdr: NMHDR,\n    pub item: LVITEMA,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMLVDISPINFOW {\n    pub hdr: NMHDR,\n    pub item: LVITEMW,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMLVEMPTYMARKUP {\n    pub hdr: NMHDR,\n    pub dwFlags: NMLVEMPTYMARKUP_FLAGS,\n    pub szMarkup: [u16; 2084],\n}\nimpl Default for NMLVEMPTYMARKUP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type NMLVEMPTYMARKUP_FLAGS = u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMLVFINDITEMA {\n    pub hdr: NMHDR,\n    pub iStart: i32,\n    pub lvfi: LVFINDINFOA,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMLVFINDITEMW {\n    pub hdr: NMHDR,\n    pub iStart: i32,\n    pub lvfi: LVFINDINFOW,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMLVGETINFOTIPA {\n    pub hdr: NMHDR,\n    pub dwFlags: NMLVGETINFOTIP_FLAGS,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub iItem: i32,\n    pub iSubItem: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for NMLVGETINFOTIPA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMLVGETINFOTIPW {\n    pub hdr: NMHDR,\n    pub dwFlags: NMLVGETINFOTIP_FLAGS,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub iItem: i32,\n    pub iSubItem: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for NMLVGETINFOTIPW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type NMLVGETINFOTIP_FLAGS = u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct NMLVKEYDOWN {\n    pub hdr: NMHDR,\n    pub wVKey: u16,\n    pub flags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMLVLINK {\n    pub hdr: NMHDR,\n    pub link: LITEM,\n    pub iItem: i32,\n    pub iSubItem: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMLVODSTATECHANGE {\n    pub hdr: NMHDR,\n    pub iFrom: i32,\n    pub iTo: i32,\n    pub uNewState: LIST_VIEW_ITEM_STATE_FLAGS,\n    pub uOldState: LIST_VIEW_ITEM_STATE_FLAGS,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMLVSCROLL {\n    pub hdr: NMHDR,\n    pub dx: i32,\n    pub dy: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMMOUSE {\n    pub hdr: NMHDR,\n    pub dwItemSpec: usize,\n    pub dwItemData: usize,\n    pub pt: super::super::Foundation::POINT,\n    pub dwHitInfo: super::super::Foundation::LPARAM,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMOBJECTNOTIFY {\n    pub hdr: NMHDR,\n    pub iItem: i32,\n    pub piid: *const windows_sys::core::GUID,\n    pub pObject: *mut core::ffi::c_void,\n    pub hResult: windows_sys::core::HRESULT,\n    pub dwFlags: u32,\n}\nimpl Default for NMOBJECTNOTIFY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMPGCALCSIZE {\n    pub hdr: NMHDR,\n    pub dwFlag: NMPGCALCSIZE_FLAGS,\n    pub iWidth: i32,\n    pub iHeight: i32,\n}\npub type NMPGCALCSIZE_FLAGS = u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMPGHOTITEM {\n    pub hdr: NMHDR,\n    pub idOld: i32,\n    pub idNew: i32,\n    pub dwFlags: u32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct NMPGSCROLL {\n    pub hdr: NMHDR,\n    pub fwKeys: NMPGSCROLL_KEYS,\n    pub rcParent: super::super::Foundation::RECT,\n    pub iDir: NMPGSCROLL_DIR,\n    pub iXpos: i32,\n    pub iYpos: i32,\n    pub iScroll: i32,\n}\npub type NMPGSCROLL_DIR = i32;\npub type NMPGSCROLL_KEYS = u16;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMRBAUTOSIZE {\n    pub hdr: NMHDR,\n    pub fChanged: windows_sys::core::BOOL,\n    pub rcTarget: super::super::Foundation::RECT,\n    pub rcActual: super::super::Foundation::RECT,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMREBAR {\n    pub hdr: NMHDR,\n    pub dwMask: NMREBAR_MASK_FLAGS,\n    pub uBand: u32,\n    pub fStyle: u32,\n    pub wID: u32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMREBARAUTOBREAK {\n    pub hdr: NMHDR,\n    pub uBand: u32,\n    pub wID: u32,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub uMsg: u32,\n    pub fStyleCurrent: u32,\n    pub fAutoBreak: windows_sys::core::BOOL,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMREBARCHEVRON {\n    pub hdr: NMHDR,\n    pub uBand: u32,\n    pub wID: u32,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub rc: super::super::Foundation::RECT,\n    pub lParamNM: super::super::Foundation::LPARAM,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMREBARCHILDSIZE {\n    pub hdr: NMHDR,\n    pub uBand: u32,\n    pub wID: u32,\n    pub rcChild: super::super::Foundation::RECT,\n    pub rcBand: super::super::Foundation::RECT,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMREBARSPLITTER {\n    pub hdr: NMHDR,\n    pub rcSizing: super::super::Foundation::RECT,\n}\npub type NMREBAR_MASK_FLAGS = u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMSEARCHWEB {\n    pub hdr: NMHDR,\n    pub entrypoint: EC_SEARCHWEB_ENTRYPOINT,\n    pub hasQueryText: windows_sys::core::BOOL,\n    pub invokeSucceeded: windows_sys::core::BOOL,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMSELCHANGE {\n    pub nmhdr: NMHDR,\n    pub stSelStart: super::super::Foundation::SYSTEMTIME,\n    pub stSelEnd: super::super::Foundation::SYSTEMTIME,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct NMTBCUSTOMDRAW {\n    pub nmcd: NMCUSTOMDRAW,\n    pub hbrMonoDither: super::super::Graphics::Gdi::HBRUSH,\n    pub hbrLines: super::super::Graphics::Gdi::HBRUSH,\n    pub hpenLines: super::super::Graphics::Gdi::HPEN,\n    pub clrText: super::super::Foundation::COLORREF,\n    pub clrMark: super::super::Foundation::COLORREF,\n    pub clrTextHighlight: super::super::Foundation::COLORREF,\n    pub clrBtnFace: super::super::Foundation::COLORREF,\n    pub clrBtnHighlight: super::super::Foundation::COLORREF,\n    pub clrHighlightHotTrack: super::super::Foundation::COLORREF,\n    pub rcText: super::super::Foundation::RECT,\n    pub nStringBkMode: i32,\n    pub nHLStringBkMode: i32,\n    pub iListGap: i32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for NMTBCUSTOMDRAW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTBDISPINFOA {\n    pub hdr: NMHDR,\n    pub dwMask: NMTBDISPINFOW_MASK,\n    pub idCommand: i32,\n    pub lParam: usize,\n    pub iImage: i32,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchText: i32,\n}\nimpl Default for NMTBDISPINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTBDISPINFOW {\n    pub hdr: NMHDR,\n    pub dwMask: NMTBDISPINFOW_MASK,\n    pub idCommand: i32,\n    pub lParam: usize,\n    pub iImage: i32,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchText: i32,\n}\nimpl Default for NMTBDISPINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type NMTBDISPINFOW_MASK = u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTBGETINFOTIPA {\n    pub hdr: NMHDR,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub iItem: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for NMTBGETINFOTIPA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTBGETINFOTIPW {\n    pub hdr: NMHDR,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub iItem: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for NMTBGETINFOTIPW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMTBHOTITEM {\n    pub hdr: NMHDR,\n    pub idOld: i32,\n    pub idNew: i32,\n    pub dwFlags: NMTBHOTITEM_FLAGS,\n}\npub type NMTBHOTITEM_FLAGS = u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTBRESTORE {\n    pub hdr: NMHDR,\n    pub pData: *mut u32,\n    pub pCurrent: *mut u32,\n    pub cbData: u32,\n    pub iItem: i32,\n    pub cButtons: i32,\n    pub cbBytesPerRecord: i32,\n    pub tbButton: TBBUTTON,\n}\nimpl Default for NMTBRESTORE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTBSAVE {\n    pub hdr: NMHDR,\n    pub pData: *mut u32,\n    pub pCurrent: *mut u32,\n    pub cbData: u32,\n    pub iItem: i32,\n    pub cButtons: i32,\n    pub tbButton: TBBUTTON,\n}\nimpl Default for NMTBSAVE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct NMTCKEYDOWN {\n    pub hdr: NMHDR,\n    pub wVKey: u16,\n    pub flags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTOOLBARA {\n    pub hdr: NMHDR,\n    pub iItem: i32,\n    pub tbButton: TBBUTTON,\n    pub cchText: i32,\n    pub pszText: windows_sys::core::PSTR,\n    pub rcButton: super::super::Foundation::RECT,\n}\nimpl Default for NMTOOLBARA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTOOLBARW {\n    pub hdr: NMHDR,\n    pub iItem: i32,\n    pub tbButton: TBBUTTON,\n    pub cchText: i32,\n    pub pszText: windows_sys::core::PWSTR,\n    pub rcButton: super::super::Foundation::RECT,\n}\nimpl Default for NMTOOLBARW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTOOLTIPSCREATED {\n    pub hdr: NMHDR,\n    pub hwndToolTips: super::super::Foundation::HWND,\n}\nimpl Default for NMTOOLTIPSCREATED {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMTRBTHUMBPOSCHANGING {\n    pub hdr: NMHDR,\n    pub dwPos: u32,\n    pub nReason: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMTREEVIEWA {\n    pub hdr: NMHDR,\n    pub action: NM_TREEVIEW_ACTION,\n    pub itemOld: TVITEMA,\n    pub itemNew: TVITEMA,\n    pub ptDrag: super::super::Foundation::POINT,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMTREEVIEWW {\n    pub hdr: NMHDR,\n    pub action: NM_TREEVIEW_ACTION,\n    pub itemOld: TVITEMW,\n    pub itemNew: TVITEMW,\n    pub ptDrag: super::super::Foundation::POINT,\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct NMTTCUSTOMDRAW {\n    pub nmcd: NMCUSTOMDRAW,\n    pub uDrawFlags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTTDISPINFOA {\n    pub hdr: NMHDR,\n    pub lpszText: windows_sys::core::PSTR,\n    pub szText: [i8; 80],\n    pub hinst: super::super::Foundation::HINSTANCE,\n    pub uFlags: TOOLTIP_FLAGS,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for NMTTDISPINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTTDISPINFOW {\n    pub hdr: NMHDR,\n    pub lpszText: windows_sys::core::PWSTR,\n    pub szText: [u16; 80],\n    pub hinst: super::super::Foundation::HINSTANCE,\n    pub uFlags: TOOLTIP_FLAGS,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for NMTTDISPINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct NMTVASYNCDRAW {\n    pub hdr: NMHDR,\n    pub pimldp: *mut IMAGELISTDRAWPARAMS,\n    pub hr: windows_sys::core::HRESULT,\n    pub hItem: HTREEITEM,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub dwRetFlags: u32,\n    pub iRetImageIndex: i32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for NMTVASYNCDRAW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy, Default)]\npub struct NMTVCUSTOMDRAW {\n    pub nmcd: NMCUSTOMDRAW,\n    pub clrText: super::super::Foundation::COLORREF,\n    pub clrTextBk: super::super::Foundation::COLORREF,\n    pub iLevel: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMTVDISPINFOA {\n    pub hdr: NMHDR,\n    pub item: TVITEMA,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMTVDISPINFOEXA {\n    pub hdr: NMHDR,\n    pub item: TVITEMEXA,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMTVDISPINFOEXW {\n    pub hdr: NMHDR,\n    pub item: TVITEMEXW,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMTVDISPINFOW {\n    pub hdr: NMHDR,\n    pub item: TVITEMW,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTVGETINFOTIPA {\n    pub hdr: NMHDR,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub hItem: HTREEITEM,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for NMTVGETINFOTIPA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct NMTVGETINFOTIPW {\n    pub hdr: NMHDR,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub hItem: HTREEITEM,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for NMTVGETINFOTIPW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMTVITEMCHANGE {\n    pub hdr: NMHDR,\n    pub uChanged: u32,\n    pub hItem: HTREEITEM,\n    pub uStateNew: u32,\n    pub uStateOld: u32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct NMTVKEYDOWN {\n    pub hdr: NMHDR,\n    pub wVKey: u16,\n    pub flags: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMTVSTATEIMAGECHANGING {\n    pub hdr: NMHDR,\n    pub hti: HTREEITEM,\n    pub iOldStateImageIndex: i32,\n    pub iNewStateImageIndex: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMUPDOWN {\n    pub hdr: NMHDR,\n    pub iPos: i32,\n    pub iDelta: i32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct NMVIEWCHANGE {\n    pub nmhdr: NMHDR,\n    pub dwOldView: MONTH_CALDENDAR_MESSAGES_VIEW,\n    pub dwNewView: MONTH_CALDENDAR_MESSAGES_VIEW,\n}\npub const NM_CHAR: u32 = 4294967278u32;\npub const NM_CLICK: u32 = 4294967294u32;\npub const NM_CUSTOMDRAW: u32 = 4294967284u32;\npub const NM_CUSTOMTEXT: u32 = 4294967272u32;\npub const NM_DBLCLK: u32 = 4294967293u32;\npub const NM_FIRST: u32 = 0u32;\npub const NM_FONTCHANGED: u32 = 4294967273u32;\npub const NM_GETCUSTOMSPLITRECT: u32 = 4294966049u32;\npub const NM_HOVER: u32 = 4294967283u32;\npub const NM_KEYDOWN: u32 = 4294967281u32;\npub const NM_KILLFOCUS: u32 = 4294967288u32;\npub const NM_LAST: u32 = 4294967197u32;\npub const NM_LDOWN: u32 = 4294967276u32;\npub const NM_NCHITTEST: u32 = 4294967282u32;\npub const NM_OUTOFMEMORY: u32 = 4294967295u32;\npub const NM_RCLICK: u32 = 4294967291u32;\npub const NM_RDBLCLK: u32 = 4294967290u32;\npub const NM_RDOWN: u32 = 4294967275u32;\npub const NM_RELEASEDCAPTURE: u32 = 4294967280u32;\npub const NM_RETURN: u32 = 4294967292u32;\npub const NM_SETCURSOR: u32 = 4294967279u32;\npub const NM_SETFOCUS: u32 = 4294967289u32;\npub const NM_THEMECHANGED: u32 = 4294967274u32;\npub const NM_TOOLTIPSCREATED: u32 = 4294967277u32;\npub type NM_TREEVIEW_ACTION = u32;\npub const NM_TVSTATEIMAGECHANGING: u32 = 4294967272u32;\npub type NONESTATES = i32;\npub type NORMALGROUPCOLLAPSESTATES = i32;\npub type NORMALGROUPEXPANDSTATES = i32;\npub const ODA_DRAWENTIRE: ODA_FLAGS = 1u32;\npub type ODA_FLAGS = u32;\npub const ODA_FOCUS: ODA_FLAGS = 4u32;\npub const ODA_SELECT: ODA_FLAGS = 2u32;\npub const ODS_CHECKED: ODS_FLAGS = 8u32;\npub const ODS_COMBOBOXEDIT: ODS_FLAGS = 4096u32;\npub const ODS_DEFAULT: ODS_FLAGS = 32u32;\npub const ODS_DISABLED: ODS_FLAGS = 4u32;\npub type ODS_FLAGS = u32;\npub const ODS_FOCUS: ODS_FLAGS = 16u32;\npub const ODS_GRAYED: ODS_FLAGS = 2u32;\npub const ODS_HOTLIGHT: ODS_FLAGS = 64u32;\npub const ODS_INACTIVE: ODS_FLAGS = 128u32;\npub const ODS_NOACCEL: ODS_FLAGS = 256u32;\npub const ODS_NOFOCUSRECT: ODS_FLAGS = 512u32;\npub const ODS_SELECTED: ODS_FLAGS = 1u32;\npub const ODT_BUTTON: DRAWITEMSTRUCT_CTL_TYPE = 4u32;\npub const ODT_COMBOBOX: DRAWITEMSTRUCT_CTL_TYPE = 3u32;\npub const ODT_HEADER: u32 = 100u32;\npub const ODT_LISTBOX: DRAWITEMSTRUCT_CTL_TYPE = 2u32;\npub const ODT_LISTVIEW: DRAWITEMSTRUCT_CTL_TYPE = 102u32;\npub const ODT_MENU: DRAWITEMSTRUCT_CTL_TYPE = 1u32;\npub const ODT_STATIC: DRAWITEMSTRUCT_CTL_TYPE = 5u32;\npub const ODT_TAB: DRAWITEMSTRUCT_CTL_TYPE = 101u32;\npub type OFFSETTYPE = i32;\npub type OPENBOXSTATES = i32;\npub type OPEN_THEME_DATA_FLAGS = u32;\npub const OTD_FORCE_RECT_SIZING: OPEN_THEME_DATA_FLAGS = 1u32;\npub const OTD_NONCLIENT: OPEN_THEME_DATA_FLAGS = 2u32;\npub const OT_ABOVELASTBUTTON: OFFSETTYPE = 12i32;\npub const OT_BELOWLASTBUTTON: OFFSETTYPE = 13i32;\npub const OT_BOTTOMLEFT: OFFSETTYPE = 3i32;\npub const OT_BOTTOMMIDDLE: OFFSETTYPE = 5i32;\npub const OT_BOTTOMRIGHT: OFFSETTYPE = 4i32;\npub const OT_LEFTOFCAPTION: OFFSETTYPE = 8i32;\npub const OT_LEFTOFLASTBUTTON: OFFSETTYPE = 10i32;\npub const OT_MIDDLELEFT: OFFSETTYPE = 6i32;\npub const OT_MIDDLERIGHT: OFFSETTYPE = 7i32;\npub const OT_RIGHTOFCAPTION: OFFSETTYPE = 9i32;\npub const OT_RIGHTOFLASTBUTTON: OFFSETTYPE = 11i32;\npub const OT_TOPLEFT: OFFSETTYPE = 0i32;\npub const OT_TOPMIDDLE: OFFSETTYPE = 2i32;\npub const OT_TOPRIGHT: OFFSETTYPE = 1i32;\npub type PAGEPARTS = i32;\npub const PAGESETUPDLGORD: u32 = 1546u32;\npub const PAGESETUPDLGORDMOTIF: u32 = 1550u32;\npub const PBBS_NORMAL: TRANSPARENTBARSTATES = 1i32;\npub const PBBS_PARTIAL: TRANSPARENTBARSTATES = 2i32;\npub const PBBVS_NORMAL: TRANSPARENTBARVERTSTATES = 1i32;\npub const PBBVS_PARTIAL: TRANSPARENTBARVERTSTATES = 2i32;\npub const PBDDS_DISABLED: PUSHBUTTONDROPDOWNSTATES = 2i32;\npub const PBDDS_NORMAL: PUSHBUTTONDROPDOWNSTATES = 1i32;\npub const PBFS_ERROR: FILLSTATES = 2i32;\npub const PBFS_NORMAL: FILLSTATES = 1i32;\npub const PBFS_PARTIAL: FILLSTATES = 4i32;\npub const PBFS_PAUSED: FILLSTATES = 3i32;\npub const PBFVS_ERROR: FILLVERTSTATES = 2i32;\npub const PBFVS_NORMAL: FILLVERTSTATES = 1i32;\npub const PBFVS_PARTIAL: FILLVERTSTATES = 4i32;\npub const PBFVS_PAUSED: FILLVERTSTATES = 3i32;\npub const PBM_DELTAPOS: u32 = 1027u32;\npub const PBM_GETBARCOLOR: u32 = 1039u32;\npub const PBM_GETBKCOLOR: u32 = 1038u32;\npub const PBM_GETPOS: u32 = 1032u32;\npub const PBM_GETRANGE: u32 = 1031u32;\npub const PBM_GETSTATE: u32 = 1041u32;\npub const PBM_GETSTEP: u32 = 1037u32;\npub const PBM_SETBARCOLOR: u32 = 1033u32;\npub const PBM_SETBKCOLOR: u32 = 8193u32;\npub const PBM_SETMARQUEE: u32 = 1034u32;\npub const PBM_SETPOS: u32 = 1026u32;\npub const PBM_SETRANGE: u32 = 1025u32;\npub const PBM_SETRANGE32: u32 = 1030u32;\npub const PBM_SETSTATE: u32 = 1040u32;\npub const PBM_SETSTEP: u32 = 1028u32;\npub const PBM_STEPIT: u32 = 1029u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PBRANGE {\n    pub iLow: i32,\n    pub iHigh: i32,\n}\npub const PBST_ERROR: u32 = 2u32;\npub const PBST_NORMAL: u32 = 1u32;\npub const PBST_PAUSED: u32 = 3u32;\npub const PBS_DEFAULTED: PUSHBUTTONSTATES = 5i32;\npub const PBS_DEFAULTED_ANIMATING: PUSHBUTTONSTATES = 6i32;\npub const PBS_DISABLED: PUSHBUTTONSTATES = 4i32;\npub const PBS_HOT: PUSHBUTTONSTATES = 2i32;\npub const PBS_MARQUEE: u32 = 8u32;\npub const PBS_NORMAL: PUSHBUTTONSTATES = 1i32;\npub const PBS_PRESSED: PUSHBUTTONSTATES = 3i32;\npub const PBS_SMOOTH: u32 = 1u32;\npub const PBS_SMOOTHREVERSE: u32 = 16u32;\npub const PBS_VERTICAL: u32 = 4u32;\npub type PFNDACOMPARE = Option<unsafe extern \"system\" fn(p1: *const core::ffi::c_void, p2: *const core::ffi::c_void, lparam: super::super::Foundation::LPARAM) -> i32>;\npub type PFNDACOMPARECONST = Option<unsafe extern \"system\" fn(p1: *const core::ffi::c_void, p2: *const core::ffi::c_void, lparam: super::super::Foundation::LPARAM) -> i32>;\npub type PFNDAENUMCALLBACK = Option<unsafe extern \"system\" fn(p: *const core::ffi::c_void, pdata: *const core::ffi::c_void) -> i32>;\npub type PFNDAENUMCALLBACKCONST = Option<unsafe extern \"system\" fn(p: *const core::ffi::c_void, pdata: *const core::ffi::c_void) -> i32>;\npub type PFNDPAMERGE = Option<unsafe extern \"system\" fn(umsg: DPAMM_MESSAGE, pvdest: *const core::ffi::c_void, pvsrc: *const core::ffi::c_void, lparam: super::super::Foundation::LPARAM) -> *mut core::ffi::c_void>;\npub type PFNDPAMERGECONST = Option<unsafe extern \"system\" fn(umsg: DPAMM_MESSAGE, pvdest: *const core::ffi::c_void, pvsrc: *const core::ffi::c_void, lparam: super::super::Foundation::LPARAM) -> *mut core::ffi::c_void>;\n#[cfg(feature = \"Win32_System_Com\")]\npub type PFNDPASTREAM = Option<unsafe extern \"system\" fn(pinfo: *const DPASTREAMINFO, pstream: *mut core::ffi::c_void, pvinstdata: *const core::ffi::c_void) -> windows_sys::core::HRESULT>;\npub type PFNLVCOMPARE = Option<unsafe extern \"system\" fn(param0: super::super::Foundation::LPARAM, param1: super::super::Foundation::LPARAM, param2: super::super::Foundation::LPARAM) -> i32>;\npub type PFNLVGROUPCOMPARE = Option<unsafe extern \"system\" fn(param0: i32, param1: i32, param2: *mut core::ffi::c_void) -> i32>;\npub type PFNPROPSHEETCALLBACK = Option<unsafe extern \"system\" fn(param0: super::super::Foundation::HWND, param1: u32, param2: super::super::Foundation::LPARAM) -> i32>;\npub type PFNTVCOMPARE = Option<unsafe extern \"system\" fn(lparam1: super::super::Foundation::LPARAM, lparam2: super::super::Foundation::LPARAM, lparamsort: super::super::Foundation::LPARAM) -> i32>;\npub type PFTASKDIALOGCALLBACK = Option<unsafe extern \"system\" fn(hwnd: super::super::Foundation::HWND, msg: u32, wparam: super::super::Foundation::WPARAM, lparam: super::super::Foundation::LPARAM, lprefdata: isize) -> windows_sys::core::HRESULT>;\npub const PGB_BOTTOMORRIGHT: u32 = 1u32;\npub const PGB_TOPORLEFT: u32 = 0u32;\npub const PGF_CALCHEIGHT: NMPGCALCSIZE_FLAGS = 2u32;\npub const PGF_CALCWIDTH: NMPGCALCSIZE_FLAGS = 1u32;\npub const PGF_DEPRESSED: u32 = 4u32;\npub const PGF_GRAYED: u32 = 2u32;\npub const PGF_HOT: u32 = 8u32;\npub const PGF_INVISIBLE: u32 = 0u32;\npub const PGF_NORMAL: u32 = 1u32;\npub const PGF_SCROLLDOWN: NMPGSCROLL_DIR = 2i32;\npub const PGF_SCROLLLEFT: NMPGSCROLL_DIR = 4i32;\npub const PGF_SCROLLRIGHT: NMPGSCROLL_DIR = 8i32;\npub const PGF_SCROLLUP: NMPGSCROLL_DIR = 1i32;\npub const PGK_CONTROL: NMPGSCROLL_KEYS = 2u16;\npub const PGK_MENU: NMPGSCROLL_KEYS = 4u16;\npub const PGK_NONE: NMPGSCROLL_KEYS = 0u16;\npub const PGK_SHIFT: NMPGSCROLL_KEYS = 1u16;\npub const PGM_FIRST: u32 = 5120u32;\npub const PGM_FORWARDMOUSE: u32 = 5123u32;\npub const PGM_GETBKCOLOR: u32 = 5125u32;\npub const PGM_GETBORDER: u32 = 5127u32;\npub const PGM_GETBUTTONSIZE: u32 = 5131u32;\npub const PGM_GETBUTTONSTATE: u32 = 5132u32;\npub const PGM_GETDROPTARGET: u32 = 8196u32;\npub const PGM_GETPOS: u32 = 5129u32;\npub const PGM_RECALCSIZE: u32 = 5122u32;\npub const PGM_SETBKCOLOR: u32 = 5124u32;\npub const PGM_SETBORDER: u32 = 5126u32;\npub const PGM_SETBUTTONSIZE: u32 = 5130u32;\npub const PGM_SETCHILD: u32 = 5121u32;\npub const PGM_SETPOS: u32 = 5128u32;\npub const PGM_SETSCROLLINFO: u32 = 5133u32;\npub const PGN_CALCSIZE: u32 = 4294966394u32;\npub const PGN_FIRST: u32 = 4294966396u32;\npub const PGN_HOTITEMCHANGE: u32 = 4294966393u32;\npub const PGN_LAST: u32 = 4294966346u32;\npub const PGN_SCROLL: u32 = 4294966395u32;\npub const PGRP_DOWN: PAGEPARTS = 2i32;\npub const PGRP_DOWNHORZ: PAGEPARTS = 4i32;\npub const PGRP_UP: PAGEPARTS = 1i32;\npub const PGRP_UPHORZ: PAGEPARTS = 3i32;\npub const PGS_AUTOSCROLL: u32 = 2u32;\npub const PGS_DRAGNDROP: u32 = 4u32;\npub const PGS_HORZ: u32 = 1u32;\npub const PGS_VERT: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct POINTER_DEVICE_CURSOR_INFO {\n    pub cursorId: u32,\n    pub cursor: POINTER_DEVICE_CURSOR_TYPE,\n}\npub type POINTER_DEVICE_CURSOR_TYPE = i32;\npub const POINTER_DEVICE_CURSOR_TYPE_ERASER: POINTER_DEVICE_CURSOR_TYPE = 2i32;\npub const POINTER_DEVICE_CURSOR_TYPE_MAX: POINTER_DEVICE_CURSOR_TYPE = -1i32;\npub const POINTER_DEVICE_CURSOR_TYPE_TIP: POINTER_DEVICE_CURSOR_TYPE = 1i32;\npub const POINTER_DEVICE_CURSOR_TYPE_UNKNOWN: POINTER_DEVICE_CURSOR_TYPE = 0i32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct POINTER_DEVICE_INFO {\n    pub displayOrientation: u32,\n    pub device: super::super::Foundation::HANDLE,\n    pub pointerDeviceType: POINTER_DEVICE_TYPE,\n    pub monitor: super::super::Graphics::Gdi::HMONITOR,\n    pub startingCursorId: u32,\n    pub maxActiveContacts: u16,\n    pub productString: [u16; 520],\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for POINTER_DEVICE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct POINTER_DEVICE_PROPERTY {\n    pub logicalMin: i32,\n    pub logicalMax: i32,\n    pub physicalMin: i32,\n    pub physicalMax: i32,\n    pub unit: u32,\n    pub unitExponent: u32,\n    pub usagePageId: u16,\n    pub usageId: u16,\n}\npub type POINTER_DEVICE_TYPE = i32;\npub const POINTER_DEVICE_TYPE_EXTERNAL_PEN: POINTER_DEVICE_TYPE = 2i32;\npub const POINTER_DEVICE_TYPE_INTEGRATED_PEN: POINTER_DEVICE_TYPE = 1i32;\npub const POINTER_DEVICE_TYPE_MAX: POINTER_DEVICE_TYPE = -1i32;\npub const POINTER_DEVICE_TYPE_TOUCH: POINTER_DEVICE_TYPE = 3i32;\npub const POINTER_DEVICE_TYPE_TOUCH_PAD: POINTER_DEVICE_TYPE = 4i32;\npub const POINTER_FEEDBACK_DEFAULT: POINTER_FEEDBACK_MODE = 1i32;\npub const POINTER_FEEDBACK_INDIRECT: POINTER_FEEDBACK_MODE = 2i32;\npub type POINTER_FEEDBACK_MODE = i32;\npub const POINTER_FEEDBACK_NONE: POINTER_FEEDBACK_MODE = 3i32;\n#[repr(C)]\n#[cfg(all(feature = \"Win32_UI_Input_Pointer\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct POINTER_TYPE_INFO {\n    pub r#type: super::WindowsAndMessaging::POINTER_INPUT_TYPE,\n    pub Anonymous: POINTER_TYPE_INFO_0,\n}\n#[cfg(all(feature = \"Win32_UI_Input_Pointer\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for POINTER_TYPE_INFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_UI_Input_Pointer\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union POINTER_TYPE_INFO_0 {\n    pub touchInfo: super::Input::Pointer::POINTER_TOUCH_INFO,\n    pub penInfo: super::Input::Pointer::POINTER_PEN_INFO,\n}\n#[cfg(all(feature = \"Win32_UI_Input_Pointer\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for POINTER_TYPE_INFO_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type POPUPCHECKBACKGROUNDSTATES = i32;\npub type POPUPCHECKSTATES = i32;\npub type POPUPITEMFOCUSABLESTATES = i32;\npub type POPUPITEMKBFOCUSSTATES = i32;\npub type POPUPITEMSTATES = i32;\npub type POPUPSUBMENUHCHOTSTATES = i32;\npub type POPUPSUBMENUSTATES = i32;\npub const PO_CLASS: PROPERTYORIGIN = 2i32;\npub const PO_GLOBAL: PROPERTYORIGIN = 3i32;\npub const PO_NOTFOUND: PROPERTYORIGIN = 4i32;\npub const PO_PART: PROPERTYORIGIN = 1i32;\npub const PO_STATE: PROPERTYORIGIN = 0i32;\npub const PP_BAR: PROGRESSPARTS = 1i32;\npub const PP_BARVERT: PROGRESSPARTS = 2i32;\npub const PP_CHUNK: PROGRESSPARTS = 3i32;\npub const PP_CHUNKVERT: PROGRESSPARTS = 4i32;\npub const PP_FILL: PROGRESSPARTS = 5i32;\npub const PP_FILLVERT: PROGRESSPARTS = 6i32;\npub const PP_MOVEOVERLAY: PROGRESSPARTS = 8i32;\npub const PP_MOVEOVERLAYVERT: PROGRESSPARTS = 10i32;\npub const PP_PULSEOVERLAY: PROGRESSPARTS = 7i32;\npub const PP_PULSEOVERLAYVERT: PROGRESSPARTS = 9i32;\npub const PP_TRANSPARENTBAR: PROGRESSPARTS = 11i32;\npub const PP_TRANSPARENTBARVERT: PROGRESSPARTS = 12i32;\npub const PRINTDLGEXORD: u32 = 1549u32;\npub const PRINTDLGORD: u32 = 1538u32;\npub const PRNSETUPDLGORD: u32 = 1539u32;\npub type PROGRESSPARTS = i32;\npub const PROGRESS_CLASS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"msctls_progress32\");\npub const PROGRESS_CLASSA: windows_sys::core::PCSTR = windows_sys::core::s!(\"msctls_progress32\");\npub const PROGRESS_CLASSW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"msctls_progress32\");\npub type PROPERTYORIGIN = i32;\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETHEADERA_V1 {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hwndParent: super::super::Foundation::HWND,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETHEADERA_V1_0,\n    pub pszCaption: windows_sys::core::PCSTR,\n    pub nPages: u32,\n    pub Anonymous2: PROPSHEETHEADERA_V1_1,\n    pub Anonymous3: PROPSHEETHEADERA_V1_2,\n    pub pfnCallback: PFNPROPSHEETCALLBACK,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERA_V1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERA_V1_0 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERA_V1_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERA_V1_1 {\n    pub nStartPage: u32,\n    pub pStartPage: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERA_V1_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERA_V1_2 {\n    pub ppsp: *mut PROPSHEETPAGEA,\n    pub phpage: *mut HPROPSHEETPAGE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERA_V1_2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETHEADERA_V2 {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hwndParent: super::super::Foundation::HWND,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETHEADERA_V2_0,\n    pub pszCaption: windows_sys::core::PCSTR,\n    pub nPages: u32,\n    pub Anonymous2: PROPSHEETHEADERA_V2_1,\n    pub Anonymous3: PROPSHEETHEADERA_V2_2,\n    pub pfnCallback: PFNPROPSHEETCALLBACK,\n    pub Anonymous4: PROPSHEETHEADERA_V2_3,\n    pub hplWatermark: super::super::Graphics::Gdi::HPALETTE,\n    pub Anonymous5: PROPSHEETHEADERA_V2_4,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERA_V2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERA_V2_0 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERA_V2_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERA_V2_1 {\n    pub nStartPage: u32,\n    pub pStartPage: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERA_V2_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERA_V2_2 {\n    pub ppsp: *mut PROPSHEETPAGEA,\n    pub phpage: *mut HPROPSHEETPAGE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERA_V2_2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERA_V2_3 {\n    pub hbmWatermark: super::super::Graphics::Gdi::HBITMAP,\n    pub pszbmWatermark: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERA_V2_3 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERA_V2_4 {\n    pub hbmHeader: super::super::Graphics::Gdi::HBITMAP,\n    pub pszbmHeader: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERA_V2_4 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETHEADERW_V1 {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hwndParent: super::super::Foundation::HWND,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETHEADERW_V1_0,\n    pub pszCaption: windows_sys::core::PCWSTR,\n    pub nPages: u32,\n    pub Anonymous2: PROPSHEETHEADERW_V1_1,\n    pub Anonymous3: PROPSHEETHEADERW_V1_2,\n    pub pfnCallback: PFNPROPSHEETCALLBACK,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERW_V1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERW_V1_0 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERW_V1_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERW_V1_1 {\n    pub nStartPage: u32,\n    pub pStartPage: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERW_V1_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERW_V1_2 {\n    pub ppsp: *mut PROPSHEETPAGEW,\n    pub phpage: *mut HPROPSHEETPAGE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERW_V1_2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETHEADERW_V2 {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hwndParent: super::super::Foundation::HWND,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETHEADERW_V2_0,\n    pub pszCaption: windows_sys::core::PCWSTR,\n    pub nPages: u32,\n    pub Anonymous2: PROPSHEETHEADERW_V2_1,\n    pub Anonymous3: PROPSHEETHEADERW_V2_2,\n    pub pfnCallback: PFNPROPSHEETCALLBACK,\n    pub Anonymous4: PROPSHEETHEADERW_V2_3,\n    pub hplWatermark: super::super::Graphics::Gdi::HPALETTE,\n    pub Anonymous5: PROPSHEETHEADERW_V2_4,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERW_V2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERW_V2_0 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERW_V2_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERW_V2_1 {\n    pub nStartPage: u32,\n    pub pStartPage: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERW_V2_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERW_V2_2 {\n    pub ppsp: *mut PROPSHEETPAGEW,\n    pub phpage: *mut HPROPSHEETPAGE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERW_V2_2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERW_V2_3 {\n    pub hbmWatermark: super::super::Graphics::Gdi::HBITMAP,\n    pub pszbmWatermark: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERW_V2_3 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETHEADERW_V2_4 {\n    pub hbmHeader: super::super::Graphics::Gdi::HBITMAP,\n    pub pszbmHeader: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETHEADERW_V2_4 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETPAGEA {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETPAGEA_0,\n    pub Anonymous2: PROPSHEETPAGEA_1,\n    pub pszTitle: windows_sys::core::PCSTR,\n    pub pfnDlgProc: super::WindowsAndMessaging::DLGPROC,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub pfnCallback: LPFNPSPCALLBACKA,\n    pub pcRefParent: *mut u32,\n    pub pszHeaderTitle: windows_sys::core::PCSTR,\n    pub pszHeaderSubTitle: windows_sys::core::PCSTR,\n    pub hActCtx: super::super::Foundation::HANDLE,\n    pub Anonymous3: PROPSHEETPAGEA_2,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEA_0 {\n    pub pszTemplate: windows_sys::core::PCSTR,\n    pub pResource: *mut super::WindowsAndMessaging::DLGTEMPLATE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEA_1 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEA_2 {\n    pub hbmHeader: super::super::Graphics::Gdi::HBITMAP,\n    pub pszbmHeader: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETPAGEA_V1 {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETPAGEA_V1_0,\n    pub Anonymous2: PROPSHEETPAGEA_V1_1,\n    pub pszTitle: windows_sys::core::PCSTR,\n    pub pfnDlgProc: super::WindowsAndMessaging::DLGPROC,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub pfnCallback: LPFNPSPCALLBACKA,\n    pub pcRefParent: *mut u32,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_V1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEA_V1_0 {\n    pub pszTemplate: windows_sys::core::PCSTR,\n    pub pResource: *mut super::WindowsAndMessaging::DLGTEMPLATE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_V1_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEA_V1_1 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_V1_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETPAGEA_V2 {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETPAGEA_V2_0,\n    pub Anonymous2: PROPSHEETPAGEA_V2_1,\n    pub pszTitle: windows_sys::core::PCSTR,\n    pub pfnDlgProc: super::WindowsAndMessaging::DLGPROC,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub pfnCallback: LPFNPSPCALLBACKA,\n    pub pcRefParent: *mut u32,\n    pub pszHeaderTitle: windows_sys::core::PCSTR,\n    pub pszHeaderSubTitle: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_V2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEA_V2_0 {\n    pub pszTemplate: windows_sys::core::PCSTR,\n    pub pResource: *mut super::WindowsAndMessaging::DLGTEMPLATE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_V2_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEA_V2_1 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_V2_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETPAGEA_V3 {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETPAGEA_V3_0,\n    pub Anonymous2: PROPSHEETPAGEA_V3_1,\n    pub pszTitle: windows_sys::core::PCSTR,\n    pub pfnDlgProc: super::WindowsAndMessaging::DLGPROC,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub pfnCallback: LPFNPSPCALLBACKA,\n    pub pcRefParent: *mut u32,\n    pub pszHeaderTitle: windows_sys::core::PCSTR,\n    pub pszHeaderSubTitle: windows_sys::core::PCSTR,\n    pub hActCtx: super::super::Foundation::HANDLE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_V3 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEA_V3_0 {\n    pub pszTemplate: windows_sys::core::PCSTR,\n    pub pResource: *mut super::WindowsAndMessaging::DLGTEMPLATE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_V3_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEA_V3_1 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEA_V3_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETPAGEW {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETPAGEW_0,\n    pub Anonymous2: PROPSHEETPAGEW_1,\n    pub pszTitle: windows_sys::core::PCWSTR,\n    pub pfnDlgProc: super::WindowsAndMessaging::DLGPROC,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub pfnCallback: LPFNPSPCALLBACKW,\n    pub pcRefParent: *mut u32,\n    pub pszHeaderTitle: windows_sys::core::PCWSTR,\n    pub pszHeaderSubTitle: windows_sys::core::PCWSTR,\n    pub hActCtx: super::super::Foundation::HANDLE,\n    pub Anonymous3: PROPSHEETPAGEW_2,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEW_0 {\n    pub pszTemplate: windows_sys::core::PCWSTR,\n    pub pResource: *mut super::WindowsAndMessaging::DLGTEMPLATE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEW_1 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEW_2 {\n    pub hbmHeader: super::super::Graphics::Gdi::HBITMAP,\n    pub pszbmHeader: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETPAGEW_V1 {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETPAGEW_V1_0,\n    pub Anonymous2: PROPSHEETPAGEW_V1_1,\n    pub pszTitle: windows_sys::core::PCWSTR,\n    pub pfnDlgProc: super::WindowsAndMessaging::DLGPROC,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub pfnCallback: LPFNPSPCALLBACKW,\n    pub pcRefParent: *mut u32,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_V1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEW_V1_0 {\n    pub pszTemplate: windows_sys::core::PCWSTR,\n    pub pResource: *mut super::WindowsAndMessaging::DLGTEMPLATE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_V1_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEW_V1_1 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_V1_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETPAGEW_V2 {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETPAGEW_V2_0,\n    pub Anonymous2: PROPSHEETPAGEW_V2_1,\n    pub pszTitle: windows_sys::core::PCWSTR,\n    pub pfnDlgProc: super::WindowsAndMessaging::DLGPROC,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub pfnCallback: LPFNPSPCALLBACKW,\n    pub pcRefParent: *mut u32,\n    pub pszHeaderTitle: windows_sys::core::PCWSTR,\n    pub pszHeaderSubTitle: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_V2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEW_V2_0 {\n    pub pszTemplate: windows_sys::core::PCWSTR,\n    pub pResource: *mut super::WindowsAndMessaging::DLGTEMPLATE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_V2_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEW_V2_1 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_V2_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub struct PROPSHEETPAGEW_V3 {\n    pub dwSize: u32,\n    pub dwFlags: u32,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub Anonymous1: PROPSHEETPAGEW_V3_0,\n    pub Anonymous2: PROPSHEETPAGEW_V3_1,\n    pub pszTitle: windows_sys::core::PCWSTR,\n    pub pfnDlgProc: super::WindowsAndMessaging::DLGPROC,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub pfnCallback: LPFNPSPCALLBACKW,\n    pub pcRefParent: *mut u32,\n    pub pszHeaderTitle: windows_sys::core::PCWSTR,\n    pub pszHeaderSubTitle: windows_sys::core::PCWSTR,\n    pub hActCtx: super::super::Foundation::HANDLE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_V3 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEW_V3_0 {\n    pub pszTemplate: windows_sys::core::PCWSTR,\n    pub pResource: *mut super::WindowsAndMessaging::DLGTEMPLATE,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_V3_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\n#[derive(Clone, Copy)]\npub union PROPSHEETPAGEW_V3_1 {\n    pub hIcon: super::WindowsAndMessaging::HICON,\n    pub pszIcon: windows_sys::core::PCWSTR,\n}\n#[cfg(all(feature = \"Win32_Graphics_Gdi\", feature = \"Win32_UI_WindowsAndMessaging\"))]\nimpl Default for PROPSHEETPAGEW_V3_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const PROP_LG_CXDLG: u32 = 252u32;\npub const PROP_LG_CYDLG: u32 = 218u32;\npub const PROP_MED_CXDLG: u32 = 227u32;\npub const PROP_MED_CYDLG: u32 = 215u32;\npub const PROP_SM_CXDLG: u32 = 212u32;\npub const PROP_SM_CYDLG: u32 = 188u32;\npub const PSBTN_APPLYNOW: u32 = 4u32;\npub const PSBTN_BACK: u32 = 0u32;\npub const PSBTN_CANCEL: u32 = 5u32;\npub const PSBTN_FINISH: u32 = 2u32;\npub const PSBTN_HELP: u32 = 6u32;\npub const PSBTN_MAX: u32 = 6u32;\npub const PSBTN_NEXT: u32 = 1u32;\npub const PSBTN_OK: u32 = 3u32;\npub const PSCB_BUTTONPRESSED: u32 = 3u32;\npub const PSCB_INITIALIZED: u32 = 1u32;\npub const PSCB_PRECREATE: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct PSHNOTIFY {\n    pub hdr: NMHDR,\n    pub lParam: super::super::Foundation::LPARAM,\n}\npub const PSH_AEROWIZARD: u32 = 16384u32;\npub const PSH_DEFAULT: u32 = 0u32;\npub const PSH_HASHELP: u32 = 512u32;\npub const PSH_HEADER: u32 = 524288u32;\npub const PSH_HEADERBITMAP: u32 = 134217728u32;\npub const PSH_MODELESS: u32 = 1024u32;\npub const PSH_NOAPPLYNOW: u32 = 128u32;\npub const PSH_NOCONTEXTHELP: u32 = 33554432u32;\npub const PSH_NOMARGIN: u32 = 268435456u32;\npub const PSH_PROPSHEETPAGE: u32 = 8u32;\npub const PSH_PROPTITLE: u32 = 1u32;\npub const PSH_RESIZABLE: u32 = 67108864u32;\npub const PSH_RTLREADING: u32 = 2048u32;\npub const PSH_STRETCHWATERMARK: u32 = 262144u32;\npub const PSH_USECALLBACK: u32 = 256u32;\npub const PSH_USEHBMHEADER: u32 = 1048576u32;\npub const PSH_USEHBMWATERMARK: u32 = 65536u32;\npub const PSH_USEHICON: u32 = 2u32;\npub const PSH_USEHPLWATERMARK: u32 = 131072u32;\npub const PSH_USEICONID: u32 = 4u32;\npub const PSH_USEPAGELANG: u32 = 2097152u32;\npub const PSH_USEPSTARTPAGE: u32 = 64u32;\npub const PSH_WATERMARK: u32 = 32768u32;\npub const PSH_WIZARD: u32 = 32u32;\npub const PSH_WIZARD97: u32 = 8192u32;\npub const PSH_WIZARDCONTEXTHELP: u32 = 4096u32;\npub const PSH_WIZARDHASFINISH: u32 = 16u32;\npub const PSH_WIZARD_LITE: u32 = 4194304u32;\npub const PSM_ADDPAGE: u32 = 1127u32;\npub const PSM_APPLY: u32 = 1134u32;\npub const PSM_CANCELTOCLOSE: u32 = 1131u32;\npub const PSM_CHANGED: u32 = 1128u32;\npub const PSM_ENABLEWIZBUTTONS: u32 = 1163u32;\npub const PSM_GETCURRENTPAGEHWND: u32 = 1142u32;\npub const PSM_GETRESULT: u32 = 1159u32;\npub const PSM_GETTABCONTROL: u32 = 1140u32;\npub const PSM_HWNDTOINDEX: u32 = 1153u32;\npub const PSM_IDTOINDEX: u32 = 1157u32;\npub const PSM_INDEXTOHWND: u32 = 1154u32;\npub const PSM_INDEXTOID: u32 = 1158u32;\npub const PSM_INDEXTOPAGE: u32 = 1156u32;\npub const PSM_INSERTPAGE: u32 = 1143u32;\npub const PSM_ISDIALOGMESSAGE: u32 = 1141u32;\npub const PSM_PAGETOINDEX: u32 = 1155u32;\npub const PSM_PRESSBUTTON: u32 = 1137u32;\npub const PSM_QUERYSIBLINGS: u32 = 1132u32;\npub const PSM_REBOOTSYSTEM: u32 = 1130u32;\npub const PSM_RECALCPAGESIZES: u32 = 1160u32;\npub const PSM_REMOVEPAGE: u32 = 1126u32;\npub const PSM_RESTARTWINDOWS: u32 = 1129u32;\npub const PSM_SETBUTTONTEXT: u32 = 1164u32;\npub const PSM_SETBUTTONTEXTW: u32 = 1164u32;\npub const PSM_SETCURSEL: u32 = 1125u32;\npub const PSM_SETCURSELID: u32 = 1138u32;\npub const PSM_SETFINISHTEXT: u32 = 1145u32;\npub const PSM_SETFINISHTEXTA: u32 = 1139u32;\npub const PSM_SETFINISHTEXTW: u32 = 1145u32;\npub const PSM_SETHEADERSUBTITLE: u32 = 1152u32;\npub const PSM_SETHEADERSUBTITLEA: u32 = 1151u32;\npub const PSM_SETHEADERSUBTITLEW: u32 = 1152u32;\npub const PSM_SETHEADERTITLE: u32 = 1150u32;\npub const PSM_SETHEADERTITLEA: u32 = 1149u32;\npub const PSM_SETHEADERTITLEW: u32 = 1150u32;\npub const PSM_SETNEXTTEXT: u32 = 1161u32;\npub const PSM_SETNEXTTEXTW: u32 = 1161u32;\npub const PSM_SETTITLE: u32 = 1144u32;\npub const PSM_SETTITLEA: u32 = 1135u32;\npub const PSM_SETTITLEW: u32 = 1144u32;\npub const PSM_SETWIZBUTTONS: u32 = 1136u32;\npub const PSM_SHOWWIZBUTTONS: u32 = 1162u32;\npub const PSM_UNCHANGED: u32 = 1133u32;\npub const PSNRET_INVALID: u32 = 1u32;\npub const PSNRET_INVALID_NOCHANGEPAGE: u32 = 2u32;\npub const PSNRET_MESSAGEHANDLED: u32 = 3u32;\npub const PSNRET_NOERROR: u32 = 0u32;\npub const PSN_APPLY: u32 = 4294967094u32;\npub const PSN_FIRST: u32 = 4294967096u32;\npub const PSN_GETOBJECT: u32 = 4294967086u32;\npub const PSN_HELP: u32 = 4294967091u32;\npub const PSN_KILLACTIVE: u32 = 4294967095u32;\npub const PSN_LAST: u32 = 4294966997u32;\npub const PSN_QUERYCANCEL: u32 = 4294967087u32;\npub const PSN_QUERYINITIALFOCUS: u32 = 4294967083u32;\npub const PSN_RESET: u32 = 4294967093u32;\npub const PSN_SETACTIVE: u32 = 4294967096u32;\npub const PSN_TRANSLATEACCELERATOR: u32 = 4294967084u32;\npub const PSN_WIZBACK: u32 = 4294967090u32;\npub const PSN_WIZFINISH: u32 = 4294967088u32;\npub const PSN_WIZNEXT: u32 = 4294967089u32;\npub const PSPCB_ADDREF: PSPCB_MESSAGE = 0u32;\npub const PSPCB_CREATE: PSPCB_MESSAGE = 2u32;\npub type PSPCB_MESSAGE = u32;\npub const PSPCB_RELEASE: PSPCB_MESSAGE = 1u32;\npub const PSPCB_SI_INITDIALOG: PSPCB_MESSAGE = 1025u32;\npub const PSP_DEFAULT: u32 = 0u32;\npub const PSP_DLGINDIRECT: u32 = 1u32;\npub const PSP_HASHELP: u32 = 32u32;\npub const PSP_HIDEHEADER: u32 = 2048u32;\npub const PSP_PREMATURE: u32 = 1024u32;\npub const PSP_RTLREADING: u32 = 16u32;\npub const PSP_USECALLBACK: u32 = 128u32;\npub const PSP_USEFUSIONCONTEXT: u32 = 16384u32;\npub const PSP_USEHEADERSUBTITLE: u32 = 8192u32;\npub const PSP_USEHEADERTITLE: u32 = 4096u32;\npub const PSP_USEHICON: u32 = 2u32;\npub const PSP_USEICONID: u32 = 4u32;\npub const PSP_USEREFPARENT: u32 = 64u32;\npub const PSP_USETITLE: u32 = 8u32;\npub const PSWIZBF_ELEVATIONREQUIRED: u32 = 1u32;\npub const PSWIZB_BACK: u32 = 1u32;\npub const PSWIZB_CANCEL: u32 = 16u32;\npub const PSWIZB_DISABLEDFINISH: u32 = 8u32;\npub const PSWIZB_FINISH: u32 = 4u32;\npub const PSWIZB_NEXT: u32 = 2u32;\npub const PSWIZB_RESTORE: u32 = 1u32;\npub const PSWIZB_SHOW: u32 = 0u32;\npub type PUSHBUTTONDROPDOWNSTATES = i32;\npub type PUSHBUTTONSTATES = i32;\npub type RADIOBUTTONSTATES = i32;\npub const RBAB_ADDBAND: u32 = 2u32;\npub const RBAB_AUTOSIZE: u32 = 1u32;\npub const RBBIM_BACKGROUND: u32 = 128u32;\npub const RBBIM_CHEVRONLOCATION: u32 = 4096u32;\npub const RBBIM_CHEVRONSTATE: u32 = 8192u32;\npub const RBBIM_CHILD: u32 = 16u32;\npub const RBBIM_CHILDSIZE: u32 = 32u32;\npub const RBBIM_COLORS: u32 = 2u32;\npub const RBBIM_HEADERSIZE: u32 = 2048u32;\npub const RBBIM_ID: u32 = 256u32;\npub const RBBIM_IDEALSIZE: u32 = 512u32;\npub const RBBIM_IMAGE: u32 = 8u32;\npub const RBBIM_LPARAM: u32 = 1024u32;\npub const RBBIM_SIZE: u32 = 64u32;\npub const RBBIM_STYLE: u32 = 1u32;\npub const RBBIM_TEXT: u32 = 4u32;\npub const RBBS_BREAK: u32 = 1u32;\npub const RBBS_CHILDEDGE: u32 = 4u32;\npub const RBBS_FIXEDBMP: u32 = 32u32;\npub const RBBS_FIXEDSIZE: u32 = 2u32;\npub const RBBS_GRIPPERALWAYS: u32 = 128u32;\npub const RBBS_HIDDEN: u32 = 8u32;\npub const RBBS_HIDETITLE: u32 = 1024u32;\npub const RBBS_NOGRIPPER: u32 = 256u32;\npub const RBBS_NOVERT: u32 = 16u32;\npub const RBBS_TOPALIGN: u32 = 2048u32;\npub const RBBS_USECHEVRON: u32 = 512u32;\npub const RBBS_VARIABLEHEIGHT: u32 = 64u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct RBHITTESTINFO {\n    pub pt: super::super::Foundation::POINT,\n    pub flags: u32,\n    pub iBand: i32,\n}\npub const RBHT_CAPTION: u32 = 2u32;\npub const RBHT_CHEVRON: u32 = 8u32;\npub const RBHT_CLIENT: u32 = 3u32;\npub const RBHT_GRABBER: u32 = 4u32;\npub const RBHT_NOWHERE: u32 = 1u32;\npub const RBHT_SPLITTER: u32 = 16u32;\npub const RBIM_IMAGELIST: u32 = 1u32;\npub const RBNM_ID: NMREBAR_MASK_FLAGS = 1u32;\npub const RBNM_LPARAM: NMREBAR_MASK_FLAGS = 4u32;\npub const RBNM_STYLE: NMREBAR_MASK_FLAGS = 2u32;\npub const RBN_AUTOBREAK: u32 = 4294966443u32;\npub const RBN_AUTOSIZE: u32 = 4294966462u32;\npub const RBN_BEGINDRAG: u32 = 4294966461u32;\npub const RBN_CHEVRONPUSHED: u32 = 4294966455u32;\npub const RBN_CHILDSIZE: u32 = 4294966457u32;\npub const RBN_DELETEDBAND: u32 = 4294966458u32;\npub const RBN_DELETINGBAND: u32 = 4294966459u32;\npub const RBN_ENDDRAG: u32 = 4294966460u32;\npub const RBN_FIRST: u32 = 4294966465u32;\npub const RBN_GETOBJECT: u32 = 4294966464u32;\npub const RBN_HEIGHTCHANGE: u32 = 4294966465u32;\npub const RBN_LAST: u32 = 4294966437u32;\npub const RBN_LAYOUTCHANGED: u32 = 4294966463u32;\npub const RBN_MINMAX: u32 = 4294966444u32;\npub const RBN_SPLITTERDRAG: u32 = 4294966454u32;\npub const RBSTR_CHANGERECT: u32 = 1u32;\npub const RBS_AUTOSIZE: u32 = 8192u32;\npub const RBS_BANDBORDERS: u32 = 1024u32;\npub const RBS_CHECKEDDISABLED: RADIOBUTTONSTATES = 8i32;\npub const RBS_CHECKEDHOT: RADIOBUTTONSTATES = 6i32;\npub const RBS_CHECKEDNORMAL: RADIOBUTTONSTATES = 5i32;\npub const RBS_CHECKEDPRESSED: RADIOBUTTONSTATES = 7i32;\npub const RBS_DBLCLKTOGGLE: u32 = 32768u32;\npub const RBS_DISABLED: RESTOREBUTTONSTATES = 4i32;\npub const RBS_FIXEDORDER: u32 = 2048u32;\npub const RBS_HOT: RESTOREBUTTONSTATES = 2i32;\npub const RBS_NORMAL: RESTOREBUTTONSTATES = 1i32;\npub const RBS_PUSHED: RESTOREBUTTONSTATES = 3i32;\npub const RBS_REGISTERDROP: u32 = 4096u32;\npub const RBS_TOOLTIPS: u32 = 256u32;\npub const RBS_UNCHECKEDDISABLED: RADIOBUTTONSTATES = 4i32;\npub const RBS_UNCHECKEDHOT: RADIOBUTTONSTATES = 2i32;\npub const RBS_UNCHECKEDNORMAL: RADIOBUTTONSTATES = 1i32;\npub const RBS_UNCHECKEDPRESSED: RADIOBUTTONSTATES = 3i32;\npub const RBS_VARHEIGHT: u32 = 512u32;\npub const RBS_VERTICALGRIPPER: u32 = 16384u32;\npub const RB_BEGINDRAG: u32 = 1048u32;\npub const RB_DELETEBAND: u32 = 1026u32;\npub const RB_DRAGMOVE: u32 = 1050u32;\npub const RB_ENDDRAG: u32 = 1049u32;\npub const RB_GETBANDBORDERS: u32 = 1058u32;\npub const RB_GETBANDCOUNT: u32 = 1036u32;\npub const RB_GETBANDINFO: u32 = 1052u32;\npub const RB_GETBANDINFOA: u32 = 1053u32;\npub const RB_GETBANDINFOW: u32 = 1052u32;\npub const RB_GETBANDMARGINS: u32 = 1064u32;\npub const RB_GETBARHEIGHT: u32 = 1051u32;\npub const RB_GETBARINFO: u32 = 1027u32;\npub const RB_GETBKCOLOR: u32 = 1044u32;\npub const RB_GETCOLORSCHEME: u32 = 8195u32;\npub const RB_GETDROPTARGET: u32 = 8196u32;\npub const RB_GETEXTENDEDSTYLE: u32 = 1066u32;\npub const RB_GETPALETTE: u32 = 1062u32;\npub const RB_GETRECT: u32 = 1033u32;\npub const RB_GETROWCOUNT: u32 = 1037u32;\npub const RB_GETROWHEIGHT: u32 = 1038u32;\npub const RB_GETTEXTCOLOR: u32 = 1046u32;\npub const RB_GETTOOLTIPS: u32 = 1041u32;\npub const RB_GETUNICODEFORMAT: u32 = 8198u32;\npub const RB_HITTEST: u32 = 1032u32;\npub const RB_IDTOINDEX: u32 = 1040u32;\npub const RB_INSERTBAND: u32 = 1034u32;\npub const RB_INSERTBANDA: u32 = 1025u32;\npub const RB_INSERTBANDW: u32 = 1034u32;\npub const RB_MAXIMIZEBAND: u32 = 1055u32;\npub const RB_MINIMIZEBAND: u32 = 1054u32;\npub const RB_MOVEBAND: u32 = 1063u32;\npub const RB_PUSHCHEVRON: u32 = 1067u32;\npub const RB_SETBANDINFO: u32 = 1035u32;\npub const RB_SETBANDINFOA: u32 = 1030u32;\npub const RB_SETBANDINFOW: u32 = 1035u32;\npub const RB_SETBANDWIDTH: u32 = 1068u32;\npub const RB_SETBARINFO: u32 = 1028u32;\npub const RB_SETBKCOLOR: u32 = 1043u32;\npub const RB_SETCOLORSCHEME: u32 = 8194u32;\npub const RB_SETEXTENDEDSTYLE: u32 = 1065u32;\npub const RB_SETPALETTE: u32 = 1061u32;\npub const RB_SETPARENT: u32 = 1031u32;\npub const RB_SETTEXTCOLOR: u32 = 1045u32;\npub const RB_SETTOOLTIPS: u32 = 1042u32;\npub const RB_SETUNICODEFORMAT: u32 = 8197u32;\npub const RB_SETWINDOWTHEME: u32 = 8203u32;\npub const RB_SHOWBAND: u32 = 1059u32;\npub const RB_SIZETORECT: u32 = 1047u32;\npub type READONLYSTATES = i32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct REBARBANDINFOA {\n    pub cbSize: u32,\n    pub fMask: u32,\n    pub fStyle: u32,\n    pub clrFore: super::super::Foundation::COLORREF,\n    pub clrBack: super::super::Foundation::COLORREF,\n    pub lpText: windows_sys::core::PSTR,\n    pub cch: u32,\n    pub iImage: i32,\n    pub hwndChild: super::super::Foundation::HWND,\n    pub cxMinChild: u32,\n    pub cyMinChild: u32,\n    pub cx: u32,\n    pub hbmBack: super::super::Graphics::Gdi::HBITMAP,\n    pub wID: u32,\n    pub cyChild: u32,\n    pub cyMaxChild: u32,\n    pub cyIntegral: u32,\n    pub cxIdeal: u32,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub cxHeader: u32,\n    pub rcChevronLocation: super::super::Foundation::RECT,\n    pub uChevronState: u32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for REBARBANDINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct REBARBANDINFOW {\n    pub cbSize: u32,\n    pub fMask: u32,\n    pub fStyle: u32,\n    pub clrFore: super::super::Foundation::COLORREF,\n    pub clrBack: super::super::Foundation::COLORREF,\n    pub lpText: windows_sys::core::PWSTR,\n    pub cch: u32,\n    pub iImage: i32,\n    pub hwndChild: super::super::Foundation::HWND,\n    pub cxMinChild: u32,\n    pub cyMinChild: u32,\n    pub cx: u32,\n    pub hbmBack: super::super::Graphics::Gdi::HBITMAP,\n    pub wID: u32,\n    pub cyChild: u32,\n    pub cyMaxChild: u32,\n    pub cyIntegral: u32,\n    pub cxIdeal: u32,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub cxHeader: u32,\n    pub rcChevronLocation: super::super::Foundation::RECT,\n    pub uChevronState: u32,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for REBARBANDINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const REBARCLASSNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ReBarWindow32\");\npub const REBARCLASSNAMEA: windows_sys::core::PCSTR = windows_sys::core::s!(\"ReBarWindow32\");\npub const REBARCLASSNAMEW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ReBarWindow32\");\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct REBARINFO {\n    pub cbSize: u32,\n    pub fMask: u32,\n    pub himl: HIMAGELIST,\n}\npub type REBARPARTS = i32;\npub const REPLACEDLGORD: u32 = 1541u32;\npub type RESTOREBUTTONSTATES = i32;\npub const RP_BACKGROUND: REBARPARTS = 6i32;\npub const RP_BAND: REBARPARTS = 3i32;\npub const RP_CHEVRON: REBARPARTS = 4i32;\npub const RP_CHEVRONVERT: REBARPARTS = 5i32;\npub const RP_GRIPPER: REBARPARTS = 1i32;\npub const RP_GRIPPERVERT: REBARPARTS = 2i32;\npub const RP_SPLITTER: REBARPARTS = 7i32;\npub const RP_SPLITTERVERT: REBARPARTS = 8i32;\npub const RUNDLGORD: u32 = 1545u32;\npub const SBARS_SIZEGRIP: u32 = 256u32;\npub const SBARS_TOOLTIPS: u32 = 2048u32;\npub const SBN_FIRST: u32 = 4294966416u32;\npub const SBN_LAST: u32 = 4294966397u32;\npub const SBN_SIMPLEMODECHANGE: u32 = 4294966416u32;\npub const SBP_ARROWBTN: SCROLLBARPARTS = 1i32;\npub const SBP_GRIPPERHORZ: SCROLLBARPARTS = 8i32;\npub const SBP_GRIPPERVERT: SCROLLBARPARTS = 9i32;\npub const SBP_LOWERTRACKHORZ: SCROLLBARPARTS = 4i32;\npub const SBP_LOWERTRACKVERT: SCROLLBARPARTS = 6i32;\npub const SBP_SIZEBOX: SCROLLBARPARTS = 10i32;\npub const SBP_SIZEBOXBKGND: SCROLLBARPARTS = 11i32;\npub const SBP_THUMBBTNHORZ: SCROLLBARPARTS = 2i32;\npub const SBP_THUMBBTNVERT: SCROLLBARPARTS = 3i32;\npub const SBP_UPPERTRACKHORZ: SCROLLBARPARTS = 5i32;\npub const SBP_UPPERTRACKVERT: SCROLLBARPARTS = 7i32;\npub const SBS_DISABLED: SYSBUTTONSTATES = 4i32;\npub const SBS_HOT: SYSBUTTONSTATES = 2i32;\npub const SBS_NORMAL: SYSBUTTONSTATES = 1i32;\npub const SBS_PUSHED: SYSBUTTONSTATES = 3i32;\npub const SBT_NOBORDERS: u32 = 256u32;\npub const SBT_NOTABPARSING: u32 = 2048u32;\npub const SBT_OWNERDRAW: u32 = 4096u32;\npub const SBT_POPOUT: u32 = 512u32;\npub const SBT_RTLREADING: u32 = 1024u32;\npub const SBT_TOOLTIPS: u32 = 2048u32;\npub const SB_GETBORDERS: u32 = 1031u32;\npub const SB_GETICON: u32 = 1044u32;\npub const SB_GETPARTS: u32 = 1030u32;\npub const SB_GETRECT: u32 = 1034u32;\npub const SB_GETTEXT: u32 = 1037u32;\npub const SB_GETTEXTA: u32 = 1026u32;\npub const SB_GETTEXTLENGTH: u32 = 1036u32;\npub const SB_GETTEXTLENGTHA: u32 = 1027u32;\npub const SB_GETTEXTLENGTHW: u32 = 1036u32;\npub const SB_GETTEXTW: u32 = 1037u32;\npub const SB_GETTIPTEXTA: u32 = 1042u32;\npub const SB_GETTIPTEXTW: u32 = 1043u32;\npub const SB_GETUNICODEFORMAT: u32 = 8198u32;\npub const SB_ISSIMPLE: u32 = 1038u32;\npub const SB_SETBKCOLOR: u32 = 8193u32;\npub const SB_SETICON: u32 = 1039u32;\npub const SB_SETMINHEIGHT: u32 = 1032u32;\npub const SB_SETPARTS: u32 = 1028u32;\npub const SB_SETTEXT: u32 = 1035u32;\npub const SB_SETTEXTA: u32 = 1025u32;\npub const SB_SETTEXTW: u32 = 1035u32;\npub const SB_SETTIPTEXTA: u32 = 1040u32;\npub const SB_SETTIPTEXTW: u32 = 1041u32;\npub const SB_SETUNICODEFORMAT: u32 = 8197u32;\npub const SB_SIMPLE: u32 = 1033u32;\npub const SB_SIMPLEID: u32 = 255u32;\npub const SCBS_DISABLED: SMALLCLOSEBUTTONSTATES = 4i32;\npub const SCBS_HOT: SMALLCLOSEBUTTONSTATES = 2i32;\npub const SCBS_NORMAL: SMALLCLOSEBUTTONSTATES = 1i32;\npub const SCBS_PUSHED: SMALLCLOSEBUTTONSTATES = 3i32;\npub const SCRBS_DISABLED: SCROLLBARSTYLESTATES = 4i32;\npub const SCRBS_HOT: SCROLLBARSTYLESTATES = 2i32;\npub const SCRBS_HOVER: SCROLLBARSTYLESTATES = 5i32;\npub const SCRBS_NORMAL: SCROLLBARSTYLESTATES = 1i32;\npub const SCRBS_PRESSED: SCROLLBARSTYLESTATES = 3i32;\npub type SCROLLBARPARTS = i32;\npub type SCROLLBARSTYLESTATES = i32;\npub const SCS_ACTIVE: SMALLCAPTIONSTATES = 1i32;\npub const SCS_DISABLED: SMALLCAPTIONSTATES = 3i32;\npub const SCS_INACTIVE: SMALLCAPTIONSTATES = 2i32;\npub type SECTIONTITLELINKSTATES = i32;\npub type SET_THEME_APP_PROPERTIES_FLAGS = u32;\npub const SFRB_ACTIVE: SMALLFRAMEBOTTOMSTATES = 1i32;\npub const SFRB_INACTIVE: SMALLFRAMEBOTTOMSTATES = 2i32;\npub const SFRL_ACTIVE: SMALLFRAMELEFTSTATES = 1i32;\npub const SFRL_INACTIVE: SMALLFRAMELEFTSTATES = 2i32;\npub const SFRR_ACTIVE: SMALLFRAMERIGHTSTATES = 1i32;\npub const SFRR_INACTIVE: SMALLFRAMERIGHTSTATES = 2i32;\npub type SHOWCALENDARBUTTONRIGHTSTATES = i32;\npub type SIZEBOXSTATES = i32;\npub type SIZINGTYPE = i32;\npub type SMALLCAPTIONSTATES = i32;\npub type SMALLCLOSEBUTTONSTATES = i32;\npub type SMALLFRAMEBOTTOMSTATES = i32;\npub type SMALLFRAMELEFTSTATES = i32;\npub type SMALLFRAMERIGHTSTATES = i32;\npub type SOFTWAREEXPLORERSTATES = i32;\npub type SPECIALGROUPCOLLAPSESTATES = i32;\npub type SPECIALGROUPEXPANDSTATES = i32;\npub type SPINPARTS = i32;\npub const SPLITSV_HOT: SPLITTERVERTSTATES = 2i32;\npub const SPLITSV_NORMAL: SPLITTERVERTSTATES = 1i32;\npub const SPLITSV_PRESSED: SPLITTERVERTSTATES = 3i32;\npub const SPLITS_HOT: SPLITTERSTATES = 2i32;\npub const SPLITS_NORMAL: SPLITTERSTATES = 1i32;\npub const SPLITS_PRESSED: SPLITTERSTATES = 3i32;\npub type SPLITTERSTATES = i32;\npub type SPLITTERVERTSTATES = i32;\npub const SPLS_HOT: LOGOFFBUTTONSSTATES = 2i32;\npub const SPLS_NORMAL: LOGOFFBUTTONSSTATES = 1i32;\npub const SPLS_PRESSED: LOGOFFBUTTONSSTATES = 3i32;\npub const SPMPT_DISABLED: MOREPROGRAMSTABSTATES = 4i32;\npub const SPMPT_FOCUSED: MOREPROGRAMSTABSTATES = 5i32;\npub const SPMPT_HOT: MOREPROGRAMSTABSTATES = 2i32;\npub const SPMPT_NORMAL: MOREPROGRAMSTABSTATES = 1i32;\npub const SPMPT_SELECTED: MOREPROGRAMSTABSTATES = 3i32;\npub const SPNP_DOWN: SPINPARTS = 2i32;\npub const SPNP_DOWNHORZ: SPINPARTS = 4i32;\npub const SPNP_UP: SPINPARTS = 1i32;\npub const SPNP_UPHORZ: SPINPARTS = 3i32;\npub const SPOB_DISABLED: OPENBOXSTATES = 4i32;\npub const SPOB_FOCUSED: OPENBOXSTATES = 5i32;\npub const SPOB_HOT: OPENBOXSTATES = 2i32;\npub const SPOB_NORMAL: OPENBOXSTATES = 1i32;\npub const SPOB_SELECTED: OPENBOXSTATES = 3i32;\npub const SPP_LOGOFF: STARTPANELPARTS = 8i32;\npub const SPP_LOGOFFBUTTONS: STARTPANELPARTS = 9i32;\npub const SPP_LOGOFFSPLITBUTTONDROPDOWN: STARTPANELPARTS = 19i32;\npub const SPP_MOREPROGRAMS: STARTPANELPARTS = 2i32;\npub const SPP_MOREPROGRAMSARROW: STARTPANELPARTS = 3i32;\npub const SPP_MOREPROGRAMSARROWBACK: STARTPANELPARTS = 17i32;\npub const SPP_MOREPROGRAMSTAB: STARTPANELPARTS = 12i32;\npub const SPP_NSCHOST: STARTPANELPARTS = 13i32;\npub const SPP_OPENBOX: STARTPANELPARTS = 15i32;\npub const SPP_PLACESLIST: STARTPANELPARTS = 6i32;\npub const SPP_PLACESLISTSEPARATOR: STARTPANELPARTS = 7i32;\npub const SPP_PREVIEW: STARTPANELPARTS = 11i32;\npub const SPP_PROGLIST: STARTPANELPARTS = 4i32;\npub const SPP_PROGLISTSEPARATOR: STARTPANELPARTS = 5i32;\npub const SPP_SEARCHVIEW: STARTPANELPARTS = 16i32;\npub const SPP_SOFTWAREEXPLORER: STARTPANELPARTS = 14i32;\npub const SPP_TOPMATCH: STARTPANELPARTS = 18i32;\npub const SPP_USERPANE: STARTPANELPARTS = 1i32;\npub const SPP_USERPICTURE: STARTPANELPARTS = 10i32;\npub const SPSB_HOT: MOREPROGRAMSARROWBACKSTATES = 2i32;\npub const SPSB_NORMAL: MOREPROGRAMSARROWBACKSTATES = 1i32;\npub const SPSB_PRESSED: MOREPROGRAMSARROWBACKSTATES = 3i32;\npub const SPSE_DISABLED: SOFTWAREEXPLORERSTATES = 4i32;\npub const SPSE_FOCUSED: SOFTWAREEXPLORERSTATES = 5i32;\npub const SPSE_HOT: SOFTWAREEXPLORERSTATES = 2i32;\npub const SPSE_NORMAL: SOFTWAREEXPLORERSTATES = 1i32;\npub const SPSE_SELECTED: SOFTWAREEXPLORERSTATES = 3i32;\npub const SPS_HOT: MOREPROGRAMSARROWSTATES = 2i32;\npub const SPS_NORMAL: MOREPROGRAMSARROWSTATES = 1i32;\npub const SPS_PRESSED: MOREPROGRAMSARROWSTATES = 3i32;\npub const SP_GRIPPER: STATUSPARTS = 3i32;\npub const SP_GRIPPERPANE: STATUSPARTS = 2i32;\npub const SP_PANE: STATUSPARTS = 1i32;\npub type STANDARDSTATES = i32;\npub type STARTPANELPARTS = i32;\npub const STATE_SYSTEM_FOCUSABLE: COMBOBOXINFO_BUTTON_STATE = 1048576u32;\npub const STATE_SYSTEM_INVISIBLE: COMBOBOXINFO_BUTTON_STATE = 32768u32;\npub const STATE_SYSTEM_OFFSCREEN: COMBOBOXINFO_BUTTON_STATE = 65536u32;\npub const STATE_SYSTEM_PRESSED: COMBOBOXINFO_BUTTON_STATE = 8u32;\npub const STATE_SYSTEM_UNAVAILABLE: COMBOBOXINFO_BUTTON_STATE = 1u32;\npub type STATICPARTS = i32;\npub const STATUSCLASSNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"msctls_statusbar32\");\npub const STATUSCLASSNAMEA: windows_sys::core::PCSTR = windows_sys::core::s!(\"msctls_statusbar32\");\npub const STATUSCLASSNAMEW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"msctls_statusbar32\");\npub type STATUSPARTS = i32;\npub const STAT_TEXT: STATICPARTS = 1i32;\npub const STD_COPY: u32 = 1u32;\npub const STD_CUT: u32 = 0u32;\npub const STD_DELETE: u32 = 5u32;\npub const STD_FILENEW: u32 = 6u32;\npub const STD_FILEOPEN: u32 = 7u32;\npub const STD_FILESAVE: u32 = 8u32;\npub const STD_FIND: u32 = 12u32;\npub const STD_HELP: u32 = 11u32;\npub const STD_PASTE: u32 = 2u32;\npub const STD_PRINT: u32 = 14u32;\npub const STD_PRINTPRE: u32 = 9u32;\npub const STD_PROPERTIES: u32 = 10u32;\npub const STD_REDOW: u32 = 4u32;\npub const STD_REPLACE: u32 = 13u32;\npub const STD_UNDO: u32 = 3u32;\npub const ST_STRETCH: SIZINGTYPE = 1i32;\npub const ST_TILE: SIZINGTYPE = 2i32;\npub const ST_TRUESIZE: SIZINGTYPE = 0i32;\npub type SYSBUTTONSTATES = i32;\npub type SYSTEMCLOSEHCHOTSTATES = i32;\npub type SYSTEMCLOSESTATES = i32;\npub type SYSTEMMAXIMIZEHCHOTSTATES = i32;\npub type SYSTEMMAXIMIZESTATES = i32;\npub type SYSTEMMINIMIZEHCHOTSTATES = i32;\npub type SYSTEMMINIMIZESTATES = i32;\npub type SYSTEMRESTOREHCHOTSTATES = i32;\npub type SYSTEMRESTORESTATES = i32;\npub const SZB_HALFBOTTOMLEFTALIGN: SIZEBOXSTATES = 6i32;\npub const SZB_HALFBOTTOMRIGHTALIGN: SIZEBOXSTATES = 5i32;\npub const SZB_HALFTOPLEFTALIGN: SIZEBOXSTATES = 8i32;\npub const SZB_HALFTOPRIGHTALIGN: SIZEBOXSTATES = 7i32;\npub const SZB_LEFTALIGN: SIZEBOXSTATES = 2i32;\npub const SZB_RIGHTALIGN: SIZEBOXSTATES = 1i32;\npub const SZB_TOPLEFTALIGN: SIZEBOXSTATES = 4i32;\npub const SZB_TOPRIGHTALIGN: SIZEBOXSTATES = 3i32;\npub const SZ_THDOCPROP_AUTHOR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"author\");\npub const SZ_THDOCPROP_CANONICALNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ThemeName\");\npub const SZ_THDOCPROP_DISPLAYNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DisplayName\");\npub const SZ_THDOCPROP_TOOLTIP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ToolTip\");\npub type TABITEMBOTHEDGESTATES = i32;\npub type TABITEMLEFTEDGESTATES = i32;\npub type TABITEMRIGHTEDGESTATES = i32;\npub type TABITEMSTATES = i32;\npub type TABPARTS = i32;\npub const TABP_AEROWIZARDBODY: TABPARTS = 11i32;\npub const TABP_BODY: TABPARTS = 10i32;\npub const TABP_PANE: TABPARTS = 9i32;\npub const TABP_TABITEM: TABPARTS = 1i32;\npub const TABP_TABITEMBOTHEDGE: TABPARTS = 4i32;\npub const TABP_TABITEMLEFTEDGE: TABPARTS = 2i32;\npub const TABP_TABITEMRIGHTEDGE: TABPARTS = 3i32;\npub const TABP_TOPTABITEM: TABPARTS = 5i32;\npub const TABP_TOPTABITEMBOTHEDGE: TABPARTS = 8i32;\npub const TABP_TOPTABITEMLEFTEDGE: TABPARTS = 6i32;\npub const TABP_TOPTABITEMRIGHTEDGE: TABPARTS = 7i32;\npub type TABSTATES = i32;\npub type TAB_CONTROL_ITEM_STATE = u32;\npub const TAPF_ALLOWCOLLECTION: TA_PROPERTY_FLAG = 4i32;\npub const TAPF_HASBACKGROUND: TA_PROPERTY_FLAG = 8i32;\npub const TAPF_HASPERSPECTIVE: TA_PROPERTY_FLAG = 16i32;\npub const TAPF_HASSTAGGER: TA_PROPERTY_FLAG = 1i32;\npub const TAPF_ISRTLAWARE: TA_PROPERTY_FLAG = 2i32;\npub const TAPF_NONE: TA_PROPERTY_FLAG = 0i32;\npub const TAP_FLAGS: TA_PROPERTY = 0i32;\npub const TAP_STAGGERDELAY: TA_PROPERTY = 2i32;\npub const TAP_STAGGERDELAYCAP: TA_PROPERTY = 3i32;\npub const TAP_STAGGERDELAYFACTOR: TA_PROPERTY = 4i32;\npub const TAP_TRANSFORMCOUNT: TA_PROPERTY = 1i32;\npub const TAP_ZORDER: TA_PROPERTY = 5i32;\npub type TASKBANDPARTS = i32;\npub type TASKBARPARTS = i32;\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\n#[derive(Clone, Copy)]\npub struct TASKDIALOGCONFIG {\n    pub cbSize: u32,\n    pub hwndParent: super::super::Foundation::HWND,\n    pub hInstance: super::super::Foundation::HINSTANCE,\n    pub dwFlags: TASKDIALOG_FLAGS,\n    pub dwCommonButtons: TASKDIALOG_COMMON_BUTTON_FLAGS,\n    pub pszWindowTitle: windows_sys::core::PCWSTR,\n    pub Anonymous1: TASKDIALOGCONFIG_0,\n    pub pszMainInstruction: windows_sys::core::PCWSTR,\n    pub pszContent: windows_sys::core::PCWSTR,\n    pub cButtons: u32,\n    pub pButtons: *const TASKDIALOG_BUTTON,\n    pub nDefaultButton: i32,\n    pub cRadioButtons: u32,\n    pub pRadioButtons: *const TASKDIALOG_BUTTON,\n    pub nDefaultRadioButton: i32,\n    pub pszVerificationText: windows_sys::core::PCWSTR,\n    pub pszExpandedInformation: windows_sys::core::PCWSTR,\n    pub pszExpandedControlText: windows_sys::core::PCWSTR,\n    pub pszCollapsedControlText: windows_sys::core::PCWSTR,\n    pub Anonymous2: TASKDIALOGCONFIG_1,\n    pub pszFooter: windows_sys::core::PCWSTR,\n    pub pfCallback: PFTASKDIALOGCALLBACK,\n    pub lpCallbackData: isize,\n    pub cxWidth: u32,\n}\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nimpl Default for TASKDIALOGCONFIG {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\n#[derive(Clone, Copy)]\npub union TASKDIALOGCONFIG_0 {\n    pub hMainIcon: super::WindowsAndMessaging::HICON,\n    pub pszMainIcon: windows_sys::core::PCWSTR,\n}\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nimpl Default for TASKDIALOGCONFIG_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\n#[derive(Clone, Copy)]\npub union TASKDIALOGCONFIG_1 {\n    pub hFooterIcon: super::WindowsAndMessaging::HICON,\n    pub pszFooterIcon: windows_sys::core::PCWSTR,\n}\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nimpl Default for TASKDIALOGCONFIG_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type TASKDIALOGPARTS = i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct TASKDIALOG_BUTTON {\n    pub nButtonID: i32,\n    pub pszButtonText: windows_sys::core::PCWSTR,\n}\nimpl Default for TASKDIALOG_BUTTON {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type TASKDIALOG_COMMON_BUTTON_FLAGS = i32;\npub type TASKDIALOG_ELEMENTS = i32;\npub type TASKDIALOG_FLAGS = i32;\npub type TASKDIALOG_ICON_ELEMENTS = i32;\npub type TASKDIALOG_MESSAGES = i32;\npub type TASKDIALOG_NOTIFICATIONS = i32;\npub type TASKLINKSTATES = i32;\npub const TATF_HASINITIALVALUES: TA_TRANSFORM_FLAG = 2i32;\npub const TATF_HASORIGINVALUES: TA_TRANSFORM_FLAG = 4i32;\npub const TATF_NONE: TA_TRANSFORM_FLAG = 0i32;\npub const TATF_TARGETVALUES_USER: TA_TRANSFORM_FLAG = 1i32;\npub const TATT_CLIP: TA_TRANSFORM_TYPE = 3i32;\npub const TATT_OPACITY: TA_TRANSFORM_TYPE = 2i32;\npub const TATT_SCALE_2D: TA_TRANSFORM_TYPE = 1i32;\npub const TATT_TRANSLATE_2D: TA_TRANSFORM_TYPE = 0i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TA_CUBIC_BEZIER {\n    pub header: TA_TIMINGFUNCTION,\n    pub rX0: f32,\n    pub rY0: f32,\n    pub rX1: f32,\n    pub rY1: f32,\n}\npub type TA_PROPERTY = i32;\npub type TA_PROPERTY_FLAG = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TA_TIMINGFUNCTION {\n    pub eTimingFunctionType: TA_TIMINGFUNCTION_TYPE,\n}\npub type TA_TIMINGFUNCTION_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TA_TRANSFORM {\n    pub eTransformType: TA_TRANSFORM_TYPE,\n    pub dwTimingFunctionId: u32,\n    pub dwStartTime: u32,\n    pub dwDurationTime: u32,\n    pub eFlags: TA_TRANSFORM_FLAG,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TA_TRANSFORM_2D {\n    pub header: TA_TRANSFORM,\n    pub rX: f32,\n    pub rY: f32,\n    pub rInitialX: f32,\n    pub rInitialY: f32,\n    pub rOriginX: f32,\n    pub rOriginY: f32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TA_TRANSFORM_CLIP {\n    pub header: TA_TRANSFORM,\n    pub rLeft: f32,\n    pub rTop: f32,\n    pub rRight: f32,\n    pub rBottom: f32,\n    pub rInitialLeft: f32,\n    pub rInitialTop: f32,\n    pub rInitialRight: f32,\n    pub rInitialBottom: f32,\n}\npub type TA_TRANSFORM_FLAG = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TA_TRANSFORM_OPACITY {\n    pub header: TA_TRANSFORM,\n    pub rOpacity: f32,\n    pub rInitialOpacity: f32,\n}\npub type TA_TRANSFORM_TYPE = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TBADDBITMAP {\n    pub hInst: super::super::Foundation::HINSTANCE,\n    pub nID: usize,\n}\nimpl Default for TBADDBITMAP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const TBBF_LARGE: u32 = 1u32;\n#[repr(C)]\n#[cfg(target_arch = \"x86\")]\n#[derive(Clone, Copy)]\npub struct TBBUTTON {\n    pub iBitmap: i32,\n    pub idCommand: i32,\n    pub fsState: u8,\n    pub fsStyle: u8,\n    pub bReserved: [u8; 2],\n    pub dwData: usize,\n    pub iString: isize,\n}\n#[cfg(target_arch = \"x86\")]\nimpl Default for TBBUTTON {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\n#[derive(Clone, Copy)]\npub struct TBBUTTON {\n    pub iBitmap: i32,\n    pub idCommand: i32,\n    pub fsState: u8,\n    pub fsStyle: u8,\n    pub bReserved: [u8; 6],\n    pub dwData: usize,\n    pub iString: isize,\n}\n#[cfg(any(target_arch = \"aarch64\", target_arch = \"arm64ec\", target_arch = \"x86_64\"))]\nimpl Default for TBBUTTON {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TBBUTTONINFOA {\n    pub cbSize: u32,\n    pub dwMask: TBBUTTONINFOW_MASK,\n    pub idCommand: i32,\n    pub iImage: i32,\n    pub fsState: u8,\n    pub fsStyle: u8,\n    pub cx: u16,\n    pub lParam: usize,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchText: i32,\n}\nimpl Default for TBBUTTONINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TBBUTTONINFOW {\n    pub cbSize: u32,\n    pub dwMask: TBBUTTONINFOW_MASK,\n    pub idCommand: i32,\n    pub iImage: i32,\n    pub fsState: u8,\n    pub fsStyle: u8,\n    pub cx: u16,\n    pub lParam: usize,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchText: i32,\n}\nimpl Default for TBBUTTONINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type TBBUTTONINFOW_MASK = u32;\npub const TBCDRF_BLENDICON: u32 = 2097152u32;\npub const TBCDRF_HILITEHOTTRACK: u32 = 131072u32;\npub const TBCDRF_NOBACKGROUND: u32 = 4194304u32;\npub const TBCDRF_NOEDGES: u32 = 65536u32;\npub const TBCDRF_NOETCHEDEFFECT: u32 = 1048576u32;\npub const TBCDRF_NOMARK: u32 = 524288u32;\npub const TBCDRF_NOOFFSET: u32 = 262144u32;\npub const TBCDRF_USECDCOLORS: u32 = 8388608u32;\npub const TBCD_CHANNEL: u32 = 3u32;\npub const TBCD_THUMB: u32 = 2u32;\npub const TBCD_TICS: u32 = 1u32;\npub const TBDDRET_DEFAULT: u32 = 0u32;\npub const TBDDRET_NODEFAULT: u32 = 1u32;\npub const TBDDRET_TREATPRESSED: u32 = 2u32;\npub const TBIF_BYINDEX: TBBUTTONINFOW_MASK = 2147483648u32;\npub const TBIF_COMMAND: TBBUTTONINFOW_MASK = 32u32;\npub const TBIF_IMAGE: TBBUTTONINFOW_MASK = 1u32;\npub const TBIF_LPARAM: TBBUTTONINFOW_MASK = 16u32;\npub const TBIF_SIZE: TBBUTTONINFOW_MASK = 64u32;\npub const TBIF_STATE: TBBUTTONINFOW_MASK = 4u32;\npub const TBIF_STYLE: TBBUTTONINFOW_MASK = 8u32;\npub const TBIF_TEXT: TBBUTTONINFOW_MASK = 2u32;\npub const TBIMHT_AFTER: TBINSERTMARK_FLAGS = 1u32;\npub const TBIMHT_BACKGROUND: TBINSERTMARK_FLAGS = 2u32;\npub const TBIMHT_NONE: TBINSERTMARK_FLAGS = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TBINSERTMARK {\n    pub iButton: i32,\n    pub dwFlags: TBINSERTMARK_FLAGS,\n}\npub type TBINSERTMARK_FLAGS = u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TBMETRICS {\n    pub cbSize: u32,\n    pub dwMask: u32,\n    pub cxPad: i32,\n    pub cyPad: i32,\n    pub cxBarPad: i32,\n    pub cyBarPad: i32,\n    pub cxButtonSpacing: i32,\n    pub cyButtonSpacing: i32,\n}\npub const TBMF_BARPAD: u32 = 2u32;\npub const TBMF_BUTTONSPACING: u32 = 4u32;\npub const TBMF_PAD: u32 = 1u32;\npub const TBM_CLEARSEL: u32 = 1043u32;\npub const TBM_CLEARTICS: u32 = 1033u32;\npub const TBM_GETBUDDY: u32 = 1057u32;\npub const TBM_GETCHANNELRECT: u32 = 1050u32;\npub const TBM_GETLINESIZE: u32 = 1048u32;\npub const TBM_GETNUMTICS: u32 = 1040u32;\npub const TBM_GETPAGESIZE: u32 = 1046u32;\npub const TBM_GETPTICS: u32 = 1038u32;\npub const TBM_GETRANGEMAX: u32 = 1026u32;\npub const TBM_GETRANGEMIN: u32 = 1025u32;\npub const TBM_GETSELEND: u32 = 1042u32;\npub const TBM_GETSELSTART: u32 = 1041u32;\npub const TBM_GETTHUMBLENGTH: u32 = 1052u32;\npub const TBM_GETTHUMBRECT: u32 = 1049u32;\npub const TBM_GETTIC: u32 = 1027u32;\npub const TBM_GETTICPOS: u32 = 1039u32;\npub const TBM_GETTOOLTIPS: u32 = 1054u32;\npub const TBM_GETUNICODEFORMAT: u32 = 8198u32;\npub const TBM_SETBUDDY: u32 = 1056u32;\npub const TBM_SETLINESIZE: u32 = 1047u32;\npub const TBM_SETPAGESIZE: u32 = 1045u32;\npub const TBM_SETPOS: u32 = 1029u32;\npub const TBM_SETPOSNOTIFY: u32 = 1058u32;\npub const TBM_SETRANGE: u32 = 1030u32;\npub const TBM_SETRANGEMAX: u32 = 1032u32;\npub const TBM_SETRANGEMIN: u32 = 1031u32;\npub const TBM_SETSEL: u32 = 1034u32;\npub const TBM_SETSELEND: u32 = 1036u32;\npub const TBM_SETSELSTART: u32 = 1035u32;\npub const TBM_SETTHUMBLENGTH: u32 = 1051u32;\npub const TBM_SETTIC: u32 = 1028u32;\npub const TBM_SETTICFREQ: u32 = 1044u32;\npub const TBM_SETTIPSIDE: u32 = 1055u32;\npub const TBM_SETTOOLTIPS: u32 = 1053u32;\npub const TBM_SETUNICODEFORMAT: u32 = 8197u32;\npub const TBNF_DI_SETITEM: NMTBDISPINFOW_MASK = 268435456u32;\npub const TBNF_IMAGE: NMTBDISPINFOW_MASK = 1u32;\npub const TBNF_TEXT: NMTBDISPINFOW_MASK = 2u32;\npub const TBNRF_ENDCUSTOMIZE: u32 = 2u32;\npub const TBNRF_HIDEHELP: u32 = 1u32;\npub const TBN_BEGINADJUST: u32 = 4294966593u32;\npub const TBN_BEGINDRAG: u32 = 4294966595u32;\npub const TBN_CUSTHELP: u32 = 4294966587u32;\npub const TBN_DELETINGBUTTON: u32 = 4294966581u32;\npub const TBN_DRAGOUT: u32 = 4294966582u32;\npub const TBN_DRAGOVER: u32 = 4294966569u32;\npub const TBN_DROPDOWN: u32 = 4294966586u32;\npub const TBN_DUPACCELERATOR: u32 = 4294966571u32;\npub const TBN_ENDADJUST: u32 = 4294966592u32;\npub const TBN_ENDDRAG: u32 = 4294966594u32;\npub const TBN_FIRST: u32 = 4294966596u32;\npub const TBN_GETBUTTONINFO: u32 = 4294966576u32;\npub const TBN_GETBUTTONINFOA: u32 = 4294966596u32;\npub const TBN_GETBUTTONINFOW: u32 = 4294966576u32;\npub const TBN_GETDISPINFO: u32 = 4294966579u32;\npub const TBN_GETDISPINFOA: u32 = 4294966580u32;\npub const TBN_GETDISPINFOW: u32 = 4294966579u32;\npub const TBN_GETINFOTIP: u32 = 4294966577u32;\npub const TBN_GETINFOTIPA: u32 = 4294966578u32;\npub const TBN_GETINFOTIPW: u32 = 4294966577u32;\npub const TBN_GETOBJECT: u32 = 4294966584u32;\npub const TBN_HOTITEMCHANGE: u32 = 4294966583u32;\npub const TBN_INITCUSTOMIZE: u32 = 4294966573u32;\npub const TBN_LAST: u32 = 4294966576u32;\npub const TBN_MAPACCELERATOR: u32 = 4294966568u32;\npub const TBN_QUERYDELETE: u32 = 4294966589u32;\npub const TBN_QUERYINSERT: u32 = 4294966590u32;\npub const TBN_RESET: u32 = 4294966591u32;\npub const TBN_RESTORE: u32 = 4294966575u32;\npub const TBN_SAVE: u32 = 4294966574u32;\npub const TBN_TOOLBARCHANGE: u32 = 4294966588u32;\npub const TBN_WRAPACCELERATOR: u32 = 4294966570u32;\npub const TBN_WRAPHOTITEM: u32 = 4294966572u32;\npub const TBP_BACKGROUNDBOTTOM: TASKBARPARTS = 1i32;\npub const TBP_BACKGROUNDLEFT: TASKBARPARTS = 4i32;\npub const TBP_BACKGROUNDRIGHT: TASKBARPARTS = 2i32;\npub const TBP_BACKGROUNDTOP: TASKBARPARTS = 3i32;\npub const TBP_SIZINGBARBOTTOM: TASKBARPARTS = 5i32;\npub const TBP_SIZINGBARLEFT: TASKBARPARTS = 8i32;\npub const TBP_SIZINGBARRIGHT: TASKBARPARTS = 6i32;\npub const TBP_SIZINGBARTOP: TASKBARPARTS = 7i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TBREPLACEBITMAP {\n    pub hInstOld: super::super::Foundation::HINSTANCE,\n    pub nIDOld: usize,\n    pub hInstNew: super::super::Foundation::HINSTANCE,\n    pub nIDNew: usize,\n    pub nButtons: i32,\n}\nimpl Default for TBREPLACEBITMAP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_System_Registry\")]\n#[derive(Clone, Copy)]\npub struct TBSAVEPARAMSA {\n    pub hkr: super::super::System::Registry::HKEY,\n    pub pszSubKey: windows_sys::core::PCSTR,\n    pub pszValueName: windows_sys::core::PCSTR,\n}\n#[cfg(feature = \"Win32_System_Registry\")]\nimpl Default for TBSAVEPARAMSA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_System_Registry\")]\n#[derive(Clone, Copy)]\npub struct TBSAVEPARAMSW {\n    pub hkr: super::super::System::Registry::HKEY,\n    pub pszSubKey: windows_sys::core::PCWSTR,\n    pub pszValueName: windows_sys::core::PCWSTR,\n}\n#[cfg(feature = \"Win32_System_Registry\")]\nimpl Default for TBSAVEPARAMSW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const TBSTATE_CHECKED: u32 = 1u32;\npub const TBSTATE_ELLIPSES: u32 = 64u32;\npub const TBSTATE_ENABLED: u32 = 4u32;\npub const TBSTATE_HIDDEN: u32 = 8u32;\npub const TBSTATE_INDETERMINATE: u32 = 16u32;\npub const TBSTATE_MARKED: u32 = 128u32;\npub const TBSTATE_PRESSED: u32 = 2u32;\npub const TBSTATE_WRAP: u32 = 32u32;\npub const TBSTYLE_ALTDRAG: u32 = 1024u32;\npub const TBSTYLE_AUTOSIZE: u32 = 16u32;\npub const TBSTYLE_BUTTON: u32 = 0u32;\npub const TBSTYLE_CHECK: u32 = 2u32;\npub const TBSTYLE_CUSTOMERASE: u32 = 8192u32;\npub const TBSTYLE_DROPDOWN: u32 = 8u32;\npub const TBSTYLE_EX_DOUBLEBUFFER: u32 = 128u32;\npub const TBSTYLE_EX_DRAWDDARROWS: u32 = 1u32;\npub const TBSTYLE_EX_HIDECLIPPEDBUTTONS: u32 = 16u32;\npub const TBSTYLE_EX_MIXEDBUTTONS: u32 = 8u32;\npub const TBSTYLE_EX_MULTICOLUMN: u32 = 2u32;\npub const TBSTYLE_EX_VERTICAL: u32 = 4u32;\npub const TBSTYLE_FLAT: u32 = 2048u32;\npub const TBSTYLE_GROUP: u32 = 4u32;\npub const TBSTYLE_LIST: u32 = 4096u32;\npub const TBSTYLE_NOPREFIX: u32 = 32u32;\npub const TBSTYLE_REGISTERDROP: u32 = 16384u32;\npub const TBSTYLE_SEP: u32 = 1u32;\npub const TBSTYLE_TOOLTIPS: u32 = 256u32;\npub const TBSTYLE_TRANSPARENT: u32 = 32768u32;\npub const TBSTYLE_WRAPABLE: u32 = 512u32;\npub const TBS_AUTOTICKS: u32 = 1u32;\npub const TBS_BOTH: u32 = 8u32;\npub const TBS_BOTTOM: u32 = 0u32;\npub const TBS_DOWNISLEFT: u32 = 1024u32;\npub const TBS_ENABLESELRANGE: u32 = 32u32;\npub const TBS_FIXEDLENGTH: u32 = 64u32;\npub const TBS_HORZ: u32 = 0u32;\npub const TBS_LEFT: u32 = 4u32;\npub const TBS_NOTHUMB: u32 = 128u32;\npub const TBS_NOTICKS: u32 = 16u32;\npub const TBS_NOTIFYBEFOREMOVE: u32 = 2048u32;\npub const TBS_REVERSED: u32 = 512u32;\npub const TBS_RIGHT: u32 = 0u32;\npub const TBS_TOOLTIPS: u32 = 256u32;\npub const TBS_TOP: u32 = 4u32;\npub const TBS_TRANSPARENTBKGND: u32 = 4096u32;\npub const TBS_VERT: u32 = 2u32;\npub const TBTS_BOTTOM: u32 = 2u32;\npub const TBTS_LEFT: u32 = 1u32;\npub const TBTS_RIGHT: u32 = 3u32;\npub const TBTS_TOP: u32 = 0u32;\npub const TB_ADDBITMAP: u32 = 1043u32;\npub const TB_ADDBUTTONS: u32 = 1092u32;\npub const TB_ADDBUTTONSA: u32 = 1044u32;\npub const TB_ADDBUTTONSW: u32 = 1092u32;\npub const TB_ADDSTRING: u32 = 1101u32;\npub const TB_ADDSTRINGA: u32 = 1052u32;\npub const TB_ADDSTRINGW: u32 = 1101u32;\npub const TB_AUTOSIZE: u32 = 1057u32;\npub const TB_BOTTOM: u32 = 7u32;\npub const TB_BUTTONCOUNT: u32 = 1048u32;\npub const TB_BUTTONSTRUCTSIZE: u32 = 1054u32;\npub const TB_CHANGEBITMAP: u32 = 1067u32;\npub const TB_CHECKBUTTON: u32 = 1026u32;\npub const TB_COMMANDTOINDEX: u32 = 1049u32;\npub const TB_CUSTOMIZE: u32 = 1051u32;\npub const TB_DELETEBUTTON: u32 = 1046u32;\npub const TB_ENABLEBUTTON: u32 = 1025u32;\npub const TB_ENDTRACK: u32 = 8u32;\npub const TB_GETANCHORHIGHLIGHT: u32 = 1098u32;\npub const TB_GETBITMAP: u32 = 1068u32;\npub const TB_GETBITMAPFLAGS: u32 = 1065u32;\npub const TB_GETBUTTON: u32 = 1047u32;\npub const TB_GETBUTTONINFO: u32 = 1087u32;\npub const TB_GETBUTTONINFOA: u32 = 1089u32;\npub const TB_GETBUTTONINFOW: u32 = 1087u32;\npub const TB_GETBUTTONSIZE: u32 = 1082u32;\npub const TB_GETBUTTONTEXT: u32 = 1099u32;\npub const TB_GETBUTTONTEXTA: u32 = 1069u32;\npub const TB_GETBUTTONTEXTW: u32 = 1099u32;\npub const TB_GETCOLORSCHEME: u32 = 8195u32;\npub const TB_GETDISABLEDIMAGELIST: u32 = 1079u32;\npub const TB_GETEXTENDEDSTYLE: u32 = 1109u32;\npub const TB_GETHOTIMAGELIST: u32 = 1077u32;\npub const TB_GETHOTITEM: u32 = 1095u32;\npub const TB_GETIDEALSIZE: u32 = 1123u32;\npub const TB_GETIMAGELIST: u32 = 1073u32;\npub const TB_GETIMAGELISTCOUNT: u32 = 1122u32;\npub const TB_GETINSERTMARK: u32 = 1103u32;\npub const TB_GETINSERTMARKCOLOR: u32 = 1113u32;\npub const TB_GETITEMDROPDOWNRECT: u32 = 1127u32;\npub const TB_GETITEMRECT: u32 = 1053u32;\npub const TB_GETMAXSIZE: u32 = 1107u32;\npub const TB_GETMETRICS: u32 = 1125u32;\npub const TB_GETOBJECT: u32 = 1086u32;\npub const TB_GETPADDING: u32 = 1110u32;\npub const TB_GETPRESSEDIMAGELIST: u32 = 1129u32;\npub const TB_GETRECT: u32 = 1075u32;\npub const TB_GETROWS: u32 = 1064u32;\npub const TB_GETSTATE: u32 = 1042u32;\npub const TB_GETSTRING: u32 = 1115u32;\npub const TB_GETSTRINGA: u32 = 1116u32;\npub const TB_GETSTRINGW: u32 = 1115u32;\npub const TB_GETSTYLE: u32 = 1081u32;\npub const TB_GETTEXTROWS: u32 = 1085u32;\npub const TB_GETTOOLTIPS: u32 = 1059u32;\npub const TB_GETUNICODEFORMAT: u32 = 8198u32;\npub const TB_HASACCELERATOR: u32 = 1119u32;\npub const TB_HIDEBUTTON: u32 = 1028u32;\npub const TB_HITTEST: u32 = 1093u32;\npub const TB_INDETERMINATE: u32 = 1029u32;\npub const TB_INSERTBUTTON: u32 = 1091u32;\npub const TB_INSERTBUTTONA: u32 = 1045u32;\npub const TB_INSERTBUTTONW: u32 = 1091u32;\npub const TB_INSERTMARKHITTEST: u32 = 1105u32;\npub const TB_ISBUTTONCHECKED: u32 = 1034u32;\npub const TB_ISBUTTONENABLED: u32 = 1033u32;\npub const TB_ISBUTTONHIDDEN: u32 = 1036u32;\npub const TB_ISBUTTONHIGHLIGHTED: u32 = 1038u32;\npub const TB_ISBUTTONINDETERMINATE: u32 = 1037u32;\npub const TB_ISBUTTONPRESSED: u32 = 1035u32;\npub const TB_LINEDOWN: u32 = 1u32;\npub const TB_LINEUP: u32 = 0u32;\npub const TB_LOADIMAGES: u32 = 1074u32;\npub const TB_MAPACCELERATOR: u32 = 1114u32;\npub const TB_MAPACCELERATORA: u32 = 1102u32;\npub const TB_MAPACCELERATORW: u32 = 1114u32;\npub const TB_MARKBUTTON: u32 = 1030u32;\npub const TB_MOVEBUTTON: u32 = 1106u32;\npub const TB_PAGEDOWN: u32 = 3u32;\npub const TB_PAGEUP: u32 = 2u32;\npub const TB_PRESSBUTTON: u32 = 1027u32;\npub const TB_REPLACEBITMAP: u32 = 1070u32;\npub const TB_SAVERESTORE: u32 = 1100u32;\npub const TB_SAVERESTOREA: u32 = 1050u32;\npub const TB_SAVERESTOREW: u32 = 1100u32;\npub const TB_SETANCHORHIGHLIGHT: u32 = 1097u32;\npub const TB_SETBITMAPSIZE: u32 = 1056u32;\npub const TB_SETBOUNDINGSIZE: u32 = 1117u32;\npub const TB_SETBUTTONINFO: u32 = 1088u32;\npub const TB_SETBUTTONINFOA: u32 = 1090u32;\npub const TB_SETBUTTONINFOW: u32 = 1088u32;\npub const TB_SETBUTTONSIZE: u32 = 1055u32;\npub const TB_SETBUTTONWIDTH: u32 = 1083u32;\npub const TB_SETCMDID: u32 = 1066u32;\npub const TB_SETCOLORSCHEME: u32 = 8194u32;\npub const TB_SETDISABLEDIMAGELIST: u32 = 1078u32;\npub const TB_SETDRAWTEXTFLAGS: u32 = 1094u32;\npub const TB_SETEXTENDEDSTYLE: u32 = 1108u32;\npub const TB_SETHOTIMAGELIST: u32 = 1076u32;\npub const TB_SETHOTITEM: u32 = 1096u32;\npub const TB_SETHOTITEM2: u32 = 1118u32;\npub const TB_SETIMAGELIST: u32 = 1072u32;\npub const TB_SETINDENT: u32 = 1071u32;\npub const TB_SETINSERTMARK: u32 = 1104u32;\npub const TB_SETINSERTMARKCOLOR: u32 = 1112u32;\npub const TB_SETLISTGAP: u32 = 1120u32;\npub const TB_SETMAXTEXTROWS: u32 = 1084u32;\npub const TB_SETMETRICS: u32 = 1126u32;\npub const TB_SETPADDING: u32 = 1111u32;\npub const TB_SETPARENT: u32 = 1061u32;\npub const TB_SETPRESSEDIMAGELIST: u32 = 1128u32;\npub const TB_SETROWS: u32 = 1063u32;\npub const TB_SETSTATE: u32 = 1041u32;\npub const TB_SETSTYLE: u32 = 1080u32;\npub const TB_SETTOOLTIPS: u32 = 1060u32;\npub const TB_SETUNICODEFORMAT: u32 = 8197u32;\npub const TB_SETWINDOWTHEME: u32 = 8203u32;\npub const TB_THUMBPOSITION: u32 = 4u32;\npub const TB_THUMBTRACK: u32 = 5u32;\npub const TB_TOP: u32 = 6u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TCHITTESTINFO {\n    pub pt: super::super::Foundation::POINT,\n    pub flags: TCHITTESTINFO_FLAGS,\n}\npub type TCHITTESTINFO_FLAGS = u32;\npub const TCHT_NOWHERE: TCHITTESTINFO_FLAGS = 1u32;\npub const TCHT_ONITEM: TCHITTESTINFO_FLAGS = 6u32;\npub const TCHT_ONITEMICON: TCHITTESTINFO_FLAGS = 2u32;\npub const TCHT_ONITEMLABEL: TCHITTESTINFO_FLAGS = 4u32;\npub const TCIF_IMAGE: TCITEMHEADERA_MASK = 2u32;\npub const TCIF_PARAM: TCITEMHEADERA_MASK = 8u32;\npub const TCIF_RTLREADING: TCITEMHEADERA_MASK = 4u32;\npub const TCIF_STATE: TCITEMHEADERA_MASK = 16u32;\npub const TCIF_TEXT: TCITEMHEADERA_MASK = 1u32;\npub const TCIS_BUTTONPRESSED: TAB_CONTROL_ITEM_STATE = 1u32;\npub const TCIS_HIGHLIGHTED: TAB_CONTROL_ITEM_STATE = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TCITEMA {\n    pub mask: TCITEMHEADERA_MASK,\n    pub dwState: TAB_CONTROL_ITEM_STATE,\n    pub dwStateMask: TAB_CONTROL_ITEM_STATE,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for TCITEMA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TCITEMHEADERA {\n    pub mask: TCITEMHEADERA_MASK,\n    pub lpReserved1: u32,\n    pub lpReserved2: u32,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n}\nimpl Default for TCITEMHEADERA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type TCITEMHEADERA_MASK = u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TCITEMHEADERW {\n    pub mask: TCITEMHEADERA_MASK,\n    pub lpReserved1: u32,\n    pub lpReserved2: u32,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n}\nimpl Default for TCITEMHEADERW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TCITEMW {\n    pub mask: TCITEMHEADERA_MASK,\n    pub dwState: TAB_CONTROL_ITEM_STATE,\n    pub dwStateMask: TAB_CONTROL_ITEM_STATE,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for TCITEMW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const TCM_ADJUSTRECT: u32 = 4904u32;\npub const TCM_DELETEALLITEMS: u32 = 4873u32;\npub const TCM_DELETEITEM: u32 = 4872u32;\npub const TCM_DESELECTALL: u32 = 4914u32;\npub const TCM_FIRST: u32 = 4864u32;\npub const TCM_GETCURFOCUS: u32 = 4911u32;\npub const TCM_GETCURSEL: u32 = 4875u32;\npub const TCM_GETEXTENDEDSTYLE: u32 = 4917u32;\npub const TCM_GETIMAGELIST: u32 = 4866u32;\npub const TCM_GETITEM: u32 = 4924u32;\npub const TCM_GETITEMA: u32 = 4869u32;\npub const TCM_GETITEMCOUNT: u32 = 4868u32;\npub const TCM_GETITEMRECT: u32 = 4874u32;\npub const TCM_GETITEMW: u32 = 4924u32;\npub const TCM_GETROWCOUNT: u32 = 4908u32;\npub const TCM_GETTOOLTIPS: u32 = 4909u32;\npub const TCM_GETUNICODEFORMAT: u32 = 8198u32;\npub const TCM_HIGHLIGHTITEM: u32 = 4915u32;\npub const TCM_HITTEST: u32 = 4877u32;\npub const TCM_INSERTITEM: u32 = 4926u32;\npub const TCM_INSERTITEMA: u32 = 4871u32;\npub const TCM_INSERTITEMW: u32 = 4926u32;\npub const TCM_REMOVEIMAGE: u32 = 4906u32;\npub const TCM_SETCURFOCUS: u32 = 4912u32;\npub const TCM_SETCURSEL: u32 = 4876u32;\npub const TCM_SETEXTENDEDSTYLE: u32 = 4916u32;\npub const TCM_SETIMAGELIST: u32 = 4867u32;\npub const TCM_SETITEM: u32 = 4925u32;\npub const TCM_SETITEMA: u32 = 4870u32;\npub const TCM_SETITEMEXTRA: u32 = 4878u32;\npub const TCM_SETITEMSIZE: u32 = 4905u32;\npub const TCM_SETITEMW: u32 = 4925u32;\npub const TCM_SETMINTABWIDTH: u32 = 4913u32;\npub const TCM_SETPADDING: u32 = 4907u32;\npub const TCM_SETTOOLTIPS: u32 = 4910u32;\npub const TCM_SETUNICODEFORMAT: u32 = 8197u32;\npub const TCN_FIRST: u32 = 4294966746u32;\npub const TCN_FOCUSCHANGE: u32 = 4294966742u32;\npub const TCN_GETOBJECT: u32 = 4294966743u32;\npub const TCN_KEYDOWN: u32 = 4294966746u32;\npub const TCN_LAST: u32 = 4294966716u32;\npub const TCN_SELCHANGE: u32 = 4294966745u32;\npub const TCN_SELCHANGING: u32 = 4294966744u32;\npub const TCS_BOTTOM: u32 = 2u32;\npub const TCS_BUTTONS: u32 = 256u32;\npub const TCS_EX_FLATSEPARATORS: u32 = 1u32;\npub const TCS_EX_REGISTERDROP: u32 = 2u32;\npub const TCS_FIXEDWIDTH: u32 = 1024u32;\npub const TCS_FLATBUTTONS: u32 = 8u32;\npub const TCS_FOCUSNEVER: u32 = 32768u32;\npub const TCS_FOCUSONBUTTONDOWN: u32 = 4096u32;\npub const TCS_FORCEICONLEFT: u32 = 16u32;\npub const TCS_FORCELABELLEFT: u32 = 32u32;\npub const TCS_HOTTRACK: u32 = 64u32;\npub const TCS_MULTILINE: u32 = 512u32;\npub const TCS_MULTISELECT: u32 = 4u32;\npub const TCS_OWNERDRAWFIXED: u32 = 8192u32;\npub const TCS_RAGGEDRIGHT: u32 = 2048u32;\npub const TCS_RIGHT: u32 = 2u32;\npub const TCS_RIGHTJUSTIFY: u32 = 0u32;\npub const TCS_SCROLLOPPOSITE: u32 = 1u32;\npub const TCS_SINGLELINE: u32 = 0u32;\npub const TCS_TABS: u32 = 0u32;\npub const TCS_TOOLTIPS: u32 = 16384u32;\npub const TCS_VERTICAL: u32 = 128u32;\npub const TDCBF_ABORT_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 65536i32;\npub const TDCBF_CANCEL_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 8i32;\npub const TDCBF_CLOSE_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 32i32;\npub const TDCBF_CONTINUE_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 524288i32;\npub const TDCBF_HELP_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 1048576i32;\npub const TDCBF_IGNORE_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 131072i32;\npub const TDCBF_NO_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 4i32;\npub const TDCBF_OK_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 1i32;\npub const TDCBF_RETRY_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 16i32;\npub const TDCBF_TRYAGAIN_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 262144i32;\npub const TDCBF_YES_BUTTON: TASKDIALOG_COMMON_BUTTON_FLAGS = 2i32;\npub const TDE_CONTENT: TASKDIALOG_ELEMENTS = 0i32;\npub const TDE_EXPANDED_INFORMATION: TASKDIALOG_ELEMENTS = 1i32;\npub const TDE_FOOTER: TASKDIALOG_ELEMENTS = 2i32;\npub const TDE_MAIN_INSTRUCTION: TASKDIALOG_ELEMENTS = 3i32;\npub const TDF_ALLOW_DIALOG_CANCELLATION: TASKDIALOG_FLAGS = 8i32;\npub const TDF_CALLBACK_TIMER: TASKDIALOG_FLAGS = 2048i32;\npub const TDF_CAN_BE_MINIMIZED: TASKDIALOG_FLAGS = 32768i32;\npub const TDF_ENABLE_HYPERLINKS: TASKDIALOG_FLAGS = 1i32;\npub const TDF_EXPANDED_BY_DEFAULT: TASKDIALOG_FLAGS = 128i32;\npub const TDF_EXPAND_FOOTER_AREA: TASKDIALOG_FLAGS = 64i32;\npub const TDF_NO_DEFAULT_RADIO_BUTTON: TASKDIALOG_FLAGS = 16384i32;\npub const TDF_NO_SET_FOREGROUND: TASKDIALOG_FLAGS = 65536i32;\npub const TDF_POSITION_RELATIVE_TO_WINDOW: TASKDIALOG_FLAGS = 4096i32;\npub const TDF_RTL_LAYOUT: TASKDIALOG_FLAGS = 8192i32;\npub const TDF_SHOW_MARQUEE_PROGRESS_BAR: TASKDIALOG_FLAGS = 1024i32;\npub const TDF_SHOW_PROGRESS_BAR: TASKDIALOG_FLAGS = 512i32;\npub const TDF_SIZE_TO_CONTENT: TASKDIALOG_FLAGS = 16777216i32;\npub const TDF_USE_COMMAND_LINKS: TASKDIALOG_FLAGS = 16i32;\npub const TDF_USE_COMMAND_LINKS_NO_ICON: TASKDIALOG_FLAGS = 32i32;\npub const TDF_USE_HICON_FOOTER: TASKDIALOG_FLAGS = 4i32;\npub const TDF_USE_HICON_MAIN: TASKDIALOG_FLAGS = 2i32;\npub const TDF_VERIFICATION_FLAG_CHECKED: TASKDIALOG_FLAGS = 256i32;\npub const TDIE_ICON_FOOTER: TASKDIALOG_ICON_ELEMENTS = 1i32;\npub const TDIE_ICON_MAIN: TASKDIALOG_ICON_ELEMENTS = 0i32;\npub const TDLGCPS_STANDALONE: CONTENTPANESTATES = 1i32;\npub const TDLGEBS_EXPANDEDDISABLED: EXPANDOBUTTONSTATES = 8i32;\npub const TDLGEBS_EXPANDEDHOVER: EXPANDOBUTTONSTATES = 5i32;\npub const TDLGEBS_EXPANDEDNORMAL: EXPANDOBUTTONSTATES = 4i32;\npub const TDLGEBS_EXPANDEDPRESSED: EXPANDOBUTTONSTATES = 6i32;\npub const TDLGEBS_HOVER: EXPANDOBUTTONSTATES = 2i32;\npub const TDLGEBS_NORMAL: EXPANDOBUTTONSTATES = 1i32;\npub const TDLGEBS_NORMALDISABLED: EXPANDOBUTTONSTATES = 7i32;\npub const TDLGEBS_PRESSED: EXPANDOBUTTONSTATES = 3i32;\npub const TDLG_BUTTONSECTION: TASKDIALOGPARTS = 10i32;\npub const TDLG_BUTTONWRAPPER: TASKDIALOGPARTS = 11i32;\npub const TDLG_COMMANDLINKPANE: TASKDIALOGPARTS = 7i32;\npub const TDLG_CONTENTICON: TASKDIALOGPARTS = 5i32;\npub const TDLG_CONTENTPANE: TASKDIALOGPARTS = 4i32;\npub const TDLG_CONTROLPANE: TASKDIALOGPARTS = 9i32;\npub const TDLG_EXPANDEDCONTENT: TASKDIALOGPARTS = 6i32;\npub const TDLG_EXPANDEDFOOTERAREA: TASKDIALOGPARTS = 18i32;\npub const TDLG_EXPANDOBUTTON: TASKDIALOGPARTS = 13i32;\npub const TDLG_EXPANDOTEXT: TASKDIALOGPARTS = 12i32;\npub const TDLG_FOOTNOTEAREA: TASKDIALOGPARTS = 16i32;\npub const TDLG_FOOTNOTEPANE: TASKDIALOGPARTS = 15i32;\npub const TDLG_FOOTNOTESEPARATOR: TASKDIALOGPARTS = 17i32;\npub const TDLG_IMAGEALIGNMENT: TASKDIALOGPARTS = 20i32;\npub const TDLG_MAINICON: TASKDIALOGPARTS = 3i32;\npub const TDLG_MAININSTRUCTIONPANE: TASKDIALOGPARTS = 2i32;\npub const TDLG_PRIMARYPANEL: TASKDIALOGPARTS = 1i32;\npub const TDLG_PROGRESSBAR: TASKDIALOGPARTS = 19i32;\npub const TDLG_RADIOBUTTONPANE: TASKDIALOGPARTS = 21i32;\npub const TDLG_SECONDARYPANEL: TASKDIALOGPARTS = 8i32;\npub const TDLG_VERIFICATIONTEXT: TASKDIALOGPARTS = 14i32;\npub const TDM_CLICK_BUTTON: TASKDIALOG_MESSAGES = 1126i32;\npub const TDM_CLICK_RADIO_BUTTON: TASKDIALOG_MESSAGES = 1134i32;\npub const TDM_CLICK_VERIFICATION: TASKDIALOG_MESSAGES = 1137i32;\npub const TDM_ENABLE_BUTTON: TASKDIALOG_MESSAGES = 1135i32;\npub const TDM_ENABLE_RADIO_BUTTON: TASKDIALOG_MESSAGES = 1136i32;\npub const TDM_NAVIGATE_PAGE: TASKDIALOG_MESSAGES = 1125i32;\npub const TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE: TASKDIALOG_MESSAGES = 1139i32;\npub const TDM_SET_ELEMENT_TEXT: TASKDIALOG_MESSAGES = 1132i32;\npub const TDM_SET_MARQUEE_PROGRESS_BAR: TASKDIALOG_MESSAGES = 1127i32;\npub const TDM_SET_PROGRESS_BAR_MARQUEE: TASKDIALOG_MESSAGES = 1131i32;\npub const TDM_SET_PROGRESS_BAR_POS: TASKDIALOG_MESSAGES = 1130i32;\npub const TDM_SET_PROGRESS_BAR_RANGE: TASKDIALOG_MESSAGES = 1129i32;\npub const TDM_SET_PROGRESS_BAR_STATE: TASKDIALOG_MESSAGES = 1128i32;\npub const TDM_UPDATE_ELEMENT_TEXT: TASKDIALOG_MESSAGES = 1138i32;\npub const TDM_UPDATE_ICON: TASKDIALOG_MESSAGES = 1140i32;\npub const TDN_BUTTON_CLICKED: TASKDIALOG_NOTIFICATIONS = 2i32;\npub const TDN_CREATED: TASKDIALOG_NOTIFICATIONS = 0i32;\npub const TDN_DESTROYED: TASKDIALOG_NOTIFICATIONS = 5i32;\npub const TDN_DIALOG_CONSTRUCTED: TASKDIALOG_NOTIFICATIONS = 7i32;\npub const TDN_EXPANDO_BUTTON_CLICKED: TASKDIALOG_NOTIFICATIONS = 10i32;\npub const TDN_HELP: TASKDIALOG_NOTIFICATIONS = 9i32;\npub const TDN_HYPERLINK_CLICKED: TASKDIALOG_NOTIFICATIONS = 3i32;\npub const TDN_NAVIGATED: TASKDIALOG_NOTIFICATIONS = 1i32;\npub const TDN_RADIO_BUTTON_CLICKED: TASKDIALOG_NOTIFICATIONS = 6i32;\npub const TDN_TIMER: TASKDIALOG_NOTIFICATIONS = 4i32;\npub const TDN_VERIFICATION_CLICKED: TASKDIALOG_NOTIFICATIONS = 8i32;\npub const TDP_FLASHBUTTON: TASKBANDPARTS = 2i32;\npub const TDP_FLASHBUTTONGROUPMENU: TASKBANDPARTS = 3i32;\npub const TDP_GROUPCOUNT: TASKBANDPARTS = 1i32;\npub const TD_ERROR_ICON: windows_sys::core::PCWSTR = 65534u16 as _;\npub const TD_INFORMATION_ICON: windows_sys::core::PCWSTR = 65533u16 as _;\npub const TD_SHIELD_ICON: windows_sys::core::PCWSTR = 65532u16 as _;\npub const TD_WARNING_ICON: windows_sys::core::PCWSTR = 65535u16 as _;\npub type TEXTSELECTIONGRIPPERPARTS = i32;\npub type TEXTSHADOWTYPE = i32;\npub type TEXTSTYLEPARTS = i32;\npub const TEXT_BODYTEXT: TEXTSTYLEPARTS = 4i32;\npub const TEXT_BODYTITLE: TEXTSTYLEPARTS = 3i32;\npub const TEXT_CONTROLLABEL: TEXTSTYLEPARTS = 9i32;\npub const TEXT_EXPANDED: TEXTSTYLEPARTS = 7i32;\npub const TEXT_HYPERLINKTEXT: TEXTSTYLEPARTS = 6i32;\npub const TEXT_INSTRUCTION: TEXTSTYLEPARTS = 2i32;\npub const TEXT_LABEL: TEXTSTYLEPARTS = 8i32;\npub const TEXT_MAININSTRUCTION: TEXTSTYLEPARTS = 1i32;\npub const TEXT_SECONDARYTEXT: TEXTSTYLEPARTS = 5i32;\npub type THEMESIZE = i32;\npub type THEME_PROPERTY_SYMBOL_ID = u32;\npub type THUMBBOTTOMSTATES = i32;\npub type THUMBLEFTSTATES = i32;\npub type THUMBRIGHTSTATES = i32;\npub type THUMBSTATES = i32;\npub type THUMBTOPSTATES = i32;\npub type THUMBVERTSTATES = i32;\npub const TIBES_DISABLED: TABITEMBOTHEDGESTATES = 4i32;\npub const TIBES_FOCUSED: TABITEMBOTHEDGESTATES = 5i32;\npub const TIBES_HOT: TABITEMBOTHEDGESTATES = 2i32;\npub const TIBES_NORMAL: TABITEMBOTHEDGESTATES = 1i32;\npub const TIBES_SELECTED: TABITEMBOTHEDGESTATES = 3i32;\npub type TICSSTATES = i32;\npub type TICSVERTSTATES = i32;\npub const TILES_DISABLED: TABITEMLEFTEDGESTATES = 4i32;\npub const TILES_FOCUSED: TABITEMLEFTEDGESTATES = 5i32;\npub const TILES_HOT: TABITEMLEFTEDGESTATES = 2i32;\npub const TILES_NORMAL: TABITEMLEFTEDGESTATES = 1i32;\npub const TILES_SELECTED: TABITEMLEFTEDGESTATES = 3i32;\npub const TIRES_DISABLED: TABITEMRIGHTEDGESTATES = 4i32;\npub const TIRES_FOCUSED: TABITEMRIGHTEDGESTATES = 5i32;\npub const TIRES_HOT: TABITEMRIGHTEDGESTATES = 2i32;\npub const TIRES_NORMAL: TABITEMRIGHTEDGESTATES = 1i32;\npub const TIRES_SELECTED: TABITEMRIGHTEDGESTATES = 3i32;\npub const TIS_DISABLED: TABITEMSTATES = 4i32;\npub const TIS_FOCUSED: TABITEMSTATES = 5i32;\npub const TIS_HOT: TABITEMSTATES = 2i32;\npub const TIS_NORMAL: TABITEMSTATES = 1i32;\npub const TIS_SELECTED: TABITEMSTATES = 3i32;\npub type TITLEBARSTATES = i32;\npub const TKP_THUMB: TRACKBARPARTS = 3i32;\npub const TKP_THUMBBOTTOM: TRACKBARPARTS = 4i32;\npub const TKP_THUMBLEFT: TRACKBARPARTS = 7i32;\npub const TKP_THUMBRIGHT: TRACKBARPARTS = 8i32;\npub const TKP_THUMBTOP: TRACKBARPARTS = 5i32;\npub const TKP_THUMBVERT: TRACKBARPARTS = 6i32;\npub const TKP_TICS: TRACKBARPARTS = 9i32;\npub const TKP_TICSVERT: TRACKBARPARTS = 10i32;\npub const TKP_TRACK: TRACKBARPARTS = 1i32;\npub const TKP_TRACKVERT: TRACKBARPARTS = 2i32;\npub const TKS_NORMAL: TRACKBARSTYLESTATES = 1i32;\npub const TMTVS_RESERVEDHIGH: u32 = 19999u32;\npub const TMTVS_RESERVEDLOW: u32 = 100000u32;\npub const TMT_ACCENTCOLORHINT: THEME_PROPERTY_SYMBOL_ID = 3823u32;\npub const TMT_ACTIVEBORDER: THEME_PROPERTY_SYMBOL_ID = 1611u32;\npub const TMT_ACTIVECAPTION: THEME_PROPERTY_SYMBOL_ID = 1603u32;\npub const TMT_ALIAS: THEME_PROPERTY_SYMBOL_ID = 1404u32;\npub const TMT_ALPHALEVEL: THEME_PROPERTY_SYMBOL_ID = 2402u32;\npub const TMT_ALPHATHRESHOLD: THEME_PROPERTY_SYMBOL_ID = 2415u32;\npub const TMT_ALWAYSSHOWSIZINGBAR: THEME_PROPERTY_SYMBOL_ID = 2208u32;\npub const TMT_ANIMATIONBUTTONRECT: THEME_PROPERTY_SYMBOL_ID = 5005u32;\npub const TMT_ANIMATIONDELAY: THEME_PROPERTY_SYMBOL_ID = 2428u32;\npub const TMT_ANIMATIONDURATION: THEME_PROPERTY_SYMBOL_ID = 5006u32;\npub const TMT_APPWORKSPACE: THEME_PROPERTY_SYMBOL_ID = 1613u32;\npub const TMT_ATLASIMAGE: THEME_PROPERTY_SYMBOL_ID = 8000u32;\npub const TMT_ATLASINPUTIMAGE: THEME_PROPERTY_SYMBOL_ID = 8001u32;\npub const TMT_ATLASRECT: THEME_PROPERTY_SYMBOL_ID = 8002u32;\npub const TMT_AUTHOR: THEME_PROPERTY_SYMBOL_ID = 604u32;\npub const TMT_AUTOSIZE: THEME_PROPERTY_SYMBOL_ID = 2202u32;\npub const TMT_BACKGROUND: THEME_PROPERTY_SYMBOL_ID = 1602u32;\npub const TMT_BGFILL: THEME_PROPERTY_SYMBOL_ID = 2205u32;\npub const TMT_BGTYPE: THEME_PROPERTY_SYMBOL_ID = 4001u32;\npub const TMT_BITMAPREF: THEME_PROPERTY_SYMBOL_ID = 215u32;\npub const TMT_BLENDCOLOR: THEME_PROPERTY_SYMBOL_ID = 5003u32;\npub const TMT_BODYFONT: THEME_PROPERTY_SYMBOL_ID = 809u32;\npub const TMT_BODYTEXTCOLOR: THEME_PROPERTY_SYMBOL_ID = 3827u32;\npub const TMT_BOOL: THEME_PROPERTY_SYMBOL_ID = 203u32;\npub const TMT_BORDERCOLOR: THEME_PROPERTY_SYMBOL_ID = 3801u32;\npub const TMT_BORDERCOLORHINT: THEME_PROPERTY_SYMBOL_ID = 3822u32;\npub const TMT_BORDERONLY: THEME_PROPERTY_SYMBOL_ID = 2203u32;\npub const TMT_BORDERSIZE: THEME_PROPERTY_SYMBOL_ID = 2403u32;\npub const TMT_BORDERTYPE: THEME_PROPERTY_SYMBOL_ID = 4002u32;\npub const TMT_BTNFACE: THEME_PROPERTY_SYMBOL_ID = 1616u32;\npub const TMT_BTNHIGHLIGHT: THEME_PROPERTY_SYMBOL_ID = 1621u32;\npub const TMT_BTNSHADOW: THEME_PROPERTY_SYMBOL_ID = 1617u32;\npub const TMT_BTNTEXT: THEME_PROPERTY_SYMBOL_ID = 1619u32;\npub const TMT_BUTTONALTERNATEFACE: THEME_PROPERTY_SYMBOL_ID = 1626u32;\npub const TMT_CAPTIONBARHEIGHT: THEME_PROPERTY_SYMBOL_ID = 1205u32;\npub const TMT_CAPTIONBARWIDTH: THEME_PROPERTY_SYMBOL_ID = 1204u32;\npub const TMT_CAPTIONFONT: THEME_PROPERTY_SYMBOL_ID = 801u32;\npub const TMT_CAPTIONMARGINS: THEME_PROPERTY_SYMBOL_ID = 3603u32;\npub const TMT_CAPTIONTEXT: THEME_PROPERTY_SYMBOL_ID = 1610u32;\npub const TMT_CHARSET: THEME_PROPERTY_SYMBOL_ID = 403u32;\npub const TMT_CLASSICVALUE: THEME_PROPERTY_SYMBOL_ID = 3202u32;\npub const TMT_COLOR: THEME_PROPERTY_SYMBOL_ID = 204u32;\npub const TMT_COLORIZATIONCOLOR: THEME_PROPERTY_SYMBOL_ID = 2431u32;\npub const TMT_COLORIZATIONOPACITY: THEME_PROPERTY_SYMBOL_ID = 2432u32;\npub const TMT_COLORSCHEMES: THEME_PROPERTY_SYMBOL_ID = 401u32;\npub const TMT_COMPANY: THEME_PROPERTY_SYMBOL_ID = 603u32;\npub const TMT_COMPOSITED: THEME_PROPERTY_SYMBOL_ID = 2204u32;\npub const TMT_COMPOSITEDOPAQUE: THEME_PROPERTY_SYMBOL_ID = 2219u32;\npub const TMT_CONTENTALIGNMENT: THEME_PROPERTY_SYMBOL_ID = 4006u32;\npub const TMT_CONTENTMARGINS: THEME_PROPERTY_SYMBOL_ID = 3602u32;\npub const TMT_COPYRIGHT: THEME_PROPERTY_SYMBOL_ID = 605u32;\npub const TMT_CSSNAME: THEME_PROPERTY_SYMBOL_ID = 1401u32;\npub const TMT_CUSTOMSPLITRECT: THEME_PROPERTY_SYMBOL_ID = 5004u32;\npub const TMT_DEFAULTPANESIZE: THEME_PROPERTY_SYMBOL_ID = 5002u32;\npub const TMT_DESCRIPTION: THEME_PROPERTY_SYMBOL_ID = 608u32;\npub const TMT_DIBDATA: THEME_PROPERTY_SYMBOL_ID = 2u32;\npub const TMT_DISKSTREAM: THEME_PROPERTY_SYMBOL_ID = 213u32;\npub const TMT_DISPLAYNAME: THEME_PROPERTY_SYMBOL_ID = 601u32;\npub const TMT_DKSHADOW3D: THEME_PROPERTY_SYMBOL_ID = 1622u32;\npub const TMT_DRAWBORDERS: THEME_PROPERTY_SYMBOL_ID = 2214u32;\npub const TMT_EDGEDKSHADOWCOLOR: THEME_PROPERTY_SYMBOL_ID = 3807u32;\npub const TMT_EDGEFILLCOLOR: THEME_PROPERTY_SYMBOL_ID = 3808u32;\npub const TMT_EDGEHIGHLIGHTCOLOR: THEME_PROPERTY_SYMBOL_ID = 3805u32;\npub const TMT_EDGELIGHTCOLOR: THEME_PROPERTY_SYMBOL_ID = 3804u32;\npub const TMT_EDGESHADOWCOLOR: THEME_PROPERTY_SYMBOL_ID = 3806u32;\npub const TMT_ENUM: THEME_PROPERTY_SYMBOL_ID = 200u32;\npub const TMT_FILENAME: THEME_PROPERTY_SYMBOL_ID = 206u32;\npub const TMT_FILLCOLOR: THEME_PROPERTY_SYMBOL_ID = 3802u32;\npub const TMT_FILLCOLORHINT: THEME_PROPERTY_SYMBOL_ID = 3821u32;\npub const TMT_FILLTYPE: THEME_PROPERTY_SYMBOL_ID = 4003u32;\npub const TMT_FIRSTBOOL: THEME_PROPERTY_SYMBOL_ID = 1001u32;\npub const TMT_FIRSTCOLOR: THEME_PROPERTY_SYMBOL_ID = 1601u32;\npub const TMT_FIRSTFONT: THEME_PROPERTY_SYMBOL_ID = 801u32;\npub const TMT_FIRSTINT: THEME_PROPERTY_SYMBOL_ID = 1301u32;\npub const TMT_FIRSTSIZE: THEME_PROPERTY_SYMBOL_ID = 1201u32;\npub const TMT_FIRSTSTRING: THEME_PROPERTY_SYMBOL_ID = 1401u32;\npub const TMT_FIRST_RCSTRING_NAME: THEME_PROPERTY_SYMBOL_ID = 601u32;\npub const TMT_FLATMENUS: THEME_PROPERTY_SYMBOL_ID = 1001u32;\npub const TMT_FLOAT: THEME_PROPERTY_SYMBOL_ID = 216u32;\npub const TMT_FLOATLIST: THEME_PROPERTY_SYMBOL_ID = 217u32;\npub const TMT_FONT: THEME_PROPERTY_SYMBOL_ID = 210u32;\npub const TMT_FRAMESPERSECOND: THEME_PROPERTY_SYMBOL_ID = 2426u32;\npub const TMT_FROMCOLOR1: THEME_PROPERTY_SYMBOL_ID = 2001u32;\npub const TMT_FROMCOLOR2: THEME_PROPERTY_SYMBOL_ID = 2002u32;\npub const TMT_FROMCOLOR3: THEME_PROPERTY_SYMBOL_ID = 2003u32;\npub const TMT_FROMCOLOR4: THEME_PROPERTY_SYMBOL_ID = 2004u32;\npub const TMT_FROMCOLOR5: THEME_PROPERTY_SYMBOL_ID = 2005u32;\npub const TMT_FROMHUE1: THEME_PROPERTY_SYMBOL_ID = 1801u32;\npub const TMT_FROMHUE2: THEME_PROPERTY_SYMBOL_ID = 1802u32;\npub const TMT_FROMHUE3: THEME_PROPERTY_SYMBOL_ID = 1803u32;\npub const TMT_FROMHUE4: THEME_PROPERTY_SYMBOL_ID = 1804u32;\npub const TMT_FROMHUE5: THEME_PROPERTY_SYMBOL_ID = 1805u32;\npub const TMT_GLOWCOLOR: THEME_PROPERTY_SYMBOL_ID = 3816u32;\npub const TMT_GLOWINTENSITY: THEME_PROPERTY_SYMBOL_ID = 2429u32;\npub const TMT_GLYPHDIBDATA: THEME_PROPERTY_SYMBOL_ID = 8u32;\npub const TMT_GLYPHFONT: THEME_PROPERTY_SYMBOL_ID = 2601u32;\npub const TMT_GLYPHFONTSIZINGTYPE: THEME_PROPERTY_SYMBOL_ID = 4014u32;\npub const TMT_GLYPHIMAGEFILE: THEME_PROPERTY_SYMBOL_ID = 3008u32;\npub const TMT_GLYPHINDEX: THEME_PROPERTY_SYMBOL_ID = 2418u32;\npub const TMT_GLYPHONLY: THEME_PROPERTY_SYMBOL_ID = 2207u32;\npub const TMT_GLYPHTEXTCOLOR: THEME_PROPERTY_SYMBOL_ID = 3819u32;\npub const TMT_GLYPHTRANSPARENT: THEME_PROPERTY_SYMBOL_ID = 2206u32;\npub const TMT_GLYPHTRANSPARENTCOLOR: THEME_PROPERTY_SYMBOL_ID = 3820u32;\npub const TMT_GLYPHTYPE: THEME_PROPERTY_SYMBOL_ID = 4012u32;\npub const TMT_GRADIENTACTIVECAPTION: THEME_PROPERTY_SYMBOL_ID = 1628u32;\npub const TMT_GRADIENTCOLOR1: THEME_PROPERTY_SYMBOL_ID = 3810u32;\npub const TMT_GRADIENTCOLOR2: THEME_PROPERTY_SYMBOL_ID = 3811u32;\npub const TMT_GRADIENTCOLOR3: THEME_PROPERTY_SYMBOL_ID = 3812u32;\npub const TMT_GRADIENTCOLOR4: THEME_PROPERTY_SYMBOL_ID = 3813u32;\npub const TMT_GRADIENTCOLOR5: THEME_PROPERTY_SYMBOL_ID = 3814u32;\npub const TMT_GRADIENTINACTIVECAPTION: THEME_PROPERTY_SYMBOL_ID = 1629u32;\npub const TMT_GRADIENTRATIO1: THEME_PROPERTY_SYMBOL_ID = 2406u32;\npub const TMT_GRADIENTRATIO2: THEME_PROPERTY_SYMBOL_ID = 2407u32;\npub const TMT_GRADIENTRATIO3: THEME_PROPERTY_SYMBOL_ID = 2408u32;\npub const TMT_GRADIENTRATIO4: THEME_PROPERTY_SYMBOL_ID = 2409u32;\npub const TMT_GRADIENTRATIO5: THEME_PROPERTY_SYMBOL_ID = 2410u32;\npub const TMT_GRAYTEXT: THEME_PROPERTY_SYMBOL_ID = 1618u32;\npub const TMT_HALIGN: THEME_PROPERTY_SYMBOL_ID = 4005u32;\npub const TMT_HBITMAP: THEME_PROPERTY_SYMBOL_ID = 212u32;\npub const TMT_HEADING1FONT: THEME_PROPERTY_SYMBOL_ID = 807u32;\npub const TMT_HEADING1TEXTCOLOR: THEME_PROPERTY_SYMBOL_ID = 3825u32;\npub const TMT_HEADING2FONT: THEME_PROPERTY_SYMBOL_ID = 808u32;\npub const TMT_HEADING2TEXTCOLOR: THEME_PROPERTY_SYMBOL_ID = 3826u32;\npub const TMT_HEIGHT: THEME_PROPERTY_SYMBOL_ID = 2417u32;\npub const TMT_HIGHLIGHT: THEME_PROPERTY_SYMBOL_ID = 1614u32;\npub const TMT_HIGHLIGHTTEXT: THEME_PROPERTY_SYMBOL_ID = 1615u32;\npub const TMT_HOTTRACKING: THEME_PROPERTY_SYMBOL_ID = 1627u32;\npub const TMT_ICONEFFECT: THEME_PROPERTY_SYMBOL_ID = 4009u32;\npub const TMT_ICONTITLEFONT: THEME_PROPERTY_SYMBOL_ID = 806u32;\npub const TMT_IMAGECOUNT: THEME_PROPERTY_SYMBOL_ID = 2401u32;\npub const TMT_IMAGEFILE: THEME_PROPERTY_SYMBOL_ID = 3001u32;\npub const TMT_IMAGEFILE1: THEME_PROPERTY_SYMBOL_ID = 3002u32;\npub const TMT_IMAGEFILE2: THEME_PROPERTY_SYMBOL_ID = 3003u32;\npub const TMT_IMAGEFILE3: THEME_PROPERTY_SYMBOL_ID = 3004u32;\npub const TMT_IMAGEFILE4: THEME_PROPERTY_SYMBOL_ID = 3005u32;\npub const TMT_IMAGEFILE5: THEME_PROPERTY_SYMBOL_ID = 3006u32;\npub const TMT_IMAGEFILE6: THEME_PROPERTY_SYMBOL_ID = 3009u32;\npub const TMT_IMAGEFILE7: THEME_PROPERTY_SYMBOL_ID = 3010u32;\npub const TMT_IMAGELAYOUT: THEME_PROPERTY_SYMBOL_ID = 4011u32;\npub const TMT_IMAGESELECTTYPE: THEME_PROPERTY_SYMBOL_ID = 4013u32;\npub const TMT_INACTIVEBORDER: THEME_PROPERTY_SYMBOL_ID = 1612u32;\npub const TMT_INACTIVECAPTION: THEME_PROPERTY_SYMBOL_ID = 1604u32;\npub const TMT_INACTIVECAPTIONTEXT: THEME_PROPERTY_SYMBOL_ID = 1620u32;\npub const TMT_INFOBK: THEME_PROPERTY_SYMBOL_ID = 1625u32;\npub const TMT_INFOTEXT: THEME_PROPERTY_SYMBOL_ID = 1624u32;\npub const TMT_INT: THEME_PROPERTY_SYMBOL_ID = 202u32;\npub const TMT_INTEGRALSIZING: THEME_PROPERTY_SYMBOL_ID = 2211u32;\npub const TMT_INTLIST: THEME_PROPERTY_SYMBOL_ID = 211u32;\npub const TMT_LASTBOOL: THEME_PROPERTY_SYMBOL_ID = 1001u32;\npub const TMT_LASTCOLOR: THEME_PROPERTY_SYMBOL_ID = 1631u32;\npub const TMT_LASTFONT: THEME_PROPERTY_SYMBOL_ID = 809u32;\npub const TMT_LASTINT: THEME_PROPERTY_SYMBOL_ID = 1301u32;\npub const TMT_LASTSIZE: THEME_PROPERTY_SYMBOL_ID = 1210u32;\npub const TMT_LASTSTRING: THEME_PROPERTY_SYMBOL_ID = 1404u32;\npub const TMT_LASTUPDATED: THEME_PROPERTY_SYMBOL_ID = 1403u32;\npub const TMT_LAST_RCSTRING_NAME: THEME_PROPERTY_SYMBOL_ID = 608u32;\npub const TMT_LIGHT3D: THEME_PROPERTY_SYMBOL_ID = 1623u32;\npub const TMT_LOCALIZEDMIRRORIMAGE: THEME_PROPERTY_SYMBOL_ID = 2220u32;\npub const TMT_MARGINS: THEME_PROPERTY_SYMBOL_ID = 205u32;\npub const TMT_MENU: THEME_PROPERTY_SYMBOL_ID = 1605u32;\npub const TMT_MENUBAR: THEME_PROPERTY_SYMBOL_ID = 1631u32;\npub const TMT_MENUBARHEIGHT: THEME_PROPERTY_SYMBOL_ID = 1209u32;\npub const TMT_MENUBARWIDTH: THEME_PROPERTY_SYMBOL_ID = 1208u32;\npub const TMT_MENUFONT: THEME_PROPERTY_SYMBOL_ID = 803u32;\npub const TMT_MENUHILIGHT: THEME_PROPERTY_SYMBOL_ID = 1630u32;\npub const TMT_MENUTEXT: THEME_PROPERTY_SYMBOL_ID = 1608u32;\npub const TMT_MINCOLORDEPTH: THEME_PROPERTY_SYMBOL_ID = 1301u32;\npub const TMT_MINDPI1: THEME_PROPERTY_SYMBOL_ID = 2420u32;\npub const TMT_MINDPI2: THEME_PROPERTY_SYMBOL_ID = 2421u32;\npub const TMT_MINDPI3: THEME_PROPERTY_SYMBOL_ID = 2422u32;\npub const TMT_MINDPI4: THEME_PROPERTY_SYMBOL_ID = 2423u32;\npub const TMT_MINDPI5: THEME_PROPERTY_SYMBOL_ID = 2424u32;\npub const TMT_MINDPI6: THEME_PROPERTY_SYMBOL_ID = 2433u32;\npub const TMT_MINDPI7: THEME_PROPERTY_SYMBOL_ID = 2434u32;\npub const TMT_MINSIZE: THEME_PROPERTY_SYMBOL_ID = 3403u32;\npub const TMT_MINSIZE1: THEME_PROPERTY_SYMBOL_ID = 3404u32;\npub const TMT_MINSIZE2: THEME_PROPERTY_SYMBOL_ID = 3405u32;\npub const TMT_MINSIZE3: THEME_PROPERTY_SYMBOL_ID = 3406u32;\npub const TMT_MINSIZE4: THEME_PROPERTY_SYMBOL_ID = 3407u32;\npub const TMT_MINSIZE5: THEME_PROPERTY_SYMBOL_ID = 3408u32;\npub const TMT_MINSIZE6: THEME_PROPERTY_SYMBOL_ID = 3410u32;\npub const TMT_MINSIZE7: THEME_PROPERTY_SYMBOL_ID = 3411u32;\npub const TMT_MIRRORIMAGE: THEME_PROPERTY_SYMBOL_ID = 2209u32;\npub const TMT_MSGBOXFONT: THEME_PROPERTY_SYMBOL_ID = 805u32;\npub const TMT_NAME: THEME_PROPERTY_SYMBOL_ID = 600u32;\npub const TMT_NOETCHEDEFFECT: THEME_PROPERTY_SYMBOL_ID = 2215u32;\npub const TMT_NORMALSIZE: THEME_PROPERTY_SYMBOL_ID = 3409u32;\npub const TMT_OFFSET: THEME_PROPERTY_SYMBOL_ID = 3401u32;\npub const TMT_OFFSETTYPE: THEME_PROPERTY_SYMBOL_ID = 4008u32;\npub const TMT_OPACITY: THEME_PROPERTY_SYMBOL_ID = 2430u32;\npub const TMT_PADDEDBORDERWIDTH: THEME_PROPERTY_SYMBOL_ID = 1210u32;\npub const TMT_PIXELSPERFRAME: THEME_PROPERTY_SYMBOL_ID = 2427u32;\npub const TMT_POSITION: THEME_PROPERTY_SYMBOL_ID = 208u32;\npub const TMT_PROGRESSCHUNKSIZE: THEME_PROPERTY_SYMBOL_ID = 2411u32;\npub const TMT_PROGRESSSPACESIZE: THEME_PROPERTY_SYMBOL_ID = 2412u32;\npub const TMT_RECT: THEME_PROPERTY_SYMBOL_ID = 209u32;\npub const TMT_RESERVEDHIGH: THEME_PROPERTY_SYMBOL_ID = 7999u32;\npub const TMT_RESERVEDLOW: THEME_PROPERTY_SYMBOL_ID = 0u32;\npub const TMT_ROUNDCORNERHEIGHT: THEME_PROPERTY_SYMBOL_ID = 2405u32;\npub const TMT_ROUNDCORNERWIDTH: THEME_PROPERTY_SYMBOL_ID = 2404u32;\npub const TMT_SATURATION: THEME_PROPERTY_SYMBOL_ID = 2413u32;\npub const TMT_SCALEDBACKGROUND: THEME_PROPERTY_SYMBOL_ID = 7001u32;\npub const TMT_SCROLLBAR: THEME_PROPERTY_SYMBOL_ID = 1601u32;\npub const TMT_SCROLLBARHEIGHT: THEME_PROPERTY_SYMBOL_ID = 1203u32;\npub const TMT_SCROLLBARWIDTH: THEME_PROPERTY_SYMBOL_ID = 1202u32;\npub const TMT_SHADOWCOLOR: THEME_PROPERTY_SYMBOL_ID = 3815u32;\npub const TMT_SIZE: THEME_PROPERTY_SYMBOL_ID = 207u32;\npub const TMT_SIZES: THEME_PROPERTY_SYMBOL_ID = 402u32;\npub const TMT_SIZINGBORDERWIDTH: THEME_PROPERTY_SYMBOL_ID = 1201u32;\npub const TMT_SIZINGMARGINS: THEME_PROPERTY_SYMBOL_ID = 3601u32;\npub const TMT_SIZINGTYPE: THEME_PROPERTY_SYMBOL_ID = 4004u32;\npub const TMT_SMALLCAPTIONFONT: THEME_PROPERTY_SYMBOL_ID = 802u32;\npub const TMT_SMCAPTIONBARHEIGHT: THEME_PROPERTY_SYMBOL_ID = 1207u32;\npub const TMT_SMCAPTIONBARWIDTH: THEME_PROPERTY_SYMBOL_ID = 1206u32;\npub const TMT_SOURCEGROW: THEME_PROPERTY_SYMBOL_ID = 2212u32;\npub const TMT_SOURCESHRINK: THEME_PROPERTY_SYMBOL_ID = 2213u32;\npub const TMT_STATUSFONT: THEME_PROPERTY_SYMBOL_ID = 804u32;\npub const TMT_STREAM: THEME_PROPERTY_SYMBOL_ID = 214u32;\npub const TMT_STRING: THEME_PROPERTY_SYMBOL_ID = 201u32;\npub const TMT_TEXT: THEME_PROPERTY_SYMBOL_ID = 3201u32;\npub const TMT_TEXTAPPLYOVERLAY: THEME_PROPERTY_SYMBOL_ID = 2216u32;\npub const TMT_TEXTBORDERCOLOR: THEME_PROPERTY_SYMBOL_ID = 3817u32;\npub const TMT_TEXTBORDERSIZE: THEME_PROPERTY_SYMBOL_ID = 2414u32;\npub const TMT_TEXTCOLOR: THEME_PROPERTY_SYMBOL_ID = 3803u32;\npub const TMT_TEXTCOLORHINT: THEME_PROPERTY_SYMBOL_ID = 3824u32;\npub const TMT_TEXTGLOW: THEME_PROPERTY_SYMBOL_ID = 2217u32;\npub const TMT_TEXTGLOWSIZE: THEME_PROPERTY_SYMBOL_ID = 2425u32;\npub const TMT_TEXTITALIC: THEME_PROPERTY_SYMBOL_ID = 2218u32;\npub const TMT_TEXTSHADOWCOLOR: THEME_PROPERTY_SYMBOL_ID = 3818u32;\npub const TMT_TEXTSHADOWOFFSET: THEME_PROPERTY_SYMBOL_ID = 3402u32;\npub const TMT_TEXTSHADOWTYPE: THEME_PROPERTY_SYMBOL_ID = 4010u32;\npub const TMT_TOCOLOR1: THEME_PROPERTY_SYMBOL_ID = 2006u32;\npub const TMT_TOCOLOR2: THEME_PROPERTY_SYMBOL_ID = 2007u32;\npub const TMT_TOCOLOR3: THEME_PROPERTY_SYMBOL_ID = 2008u32;\npub const TMT_TOCOLOR4: THEME_PROPERTY_SYMBOL_ID = 2009u32;\npub const TMT_TOCOLOR5: THEME_PROPERTY_SYMBOL_ID = 2010u32;\npub const TMT_TOHUE1: THEME_PROPERTY_SYMBOL_ID = 1806u32;\npub const TMT_TOHUE2: THEME_PROPERTY_SYMBOL_ID = 1807u32;\npub const TMT_TOHUE3: THEME_PROPERTY_SYMBOL_ID = 1808u32;\npub const TMT_TOHUE4: THEME_PROPERTY_SYMBOL_ID = 1809u32;\npub const TMT_TOHUE5: THEME_PROPERTY_SYMBOL_ID = 1810u32;\npub const TMT_TOOLTIP: THEME_PROPERTY_SYMBOL_ID = 602u32;\npub const TMT_TRANSITIONDURATIONS: THEME_PROPERTY_SYMBOL_ID = 6000u32;\npub const TMT_TRANSPARENT: THEME_PROPERTY_SYMBOL_ID = 2201u32;\npub const TMT_TRANSPARENTCOLOR: THEME_PROPERTY_SYMBOL_ID = 3809u32;\npub const TMT_TRUESIZESCALINGTYPE: THEME_PROPERTY_SYMBOL_ID = 4015u32;\npub const TMT_TRUESIZESTRETCHMARK: THEME_PROPERTY_SYMBOL_ID = 2419u32;\npub const TMT_UNIFORMSIZING: THEME_PROPERTY_SYMBOL_ID = 2210u32;\npub const TMT_URL: THEME_PROPERTY_SYMBOL_ID = 606u32;\npub const TMT_USERPICTURE: THEME_PROPERTY_SYMBOL_ID = 5001u32;\npub const TMT_VALIGN: THEME_PROPERTY_SYMBOL_ID = 4007u32;\npub const TMT_VERSION: THEME_PROPERTY_SYMBOL_ID = 607u32;\npub const TMT_WIDTH: THEME_PROPERTY_SYMBOL_ID = 2416u32;\npub const TMT_WINDOW: THEME_PROPERTY_SYMBOL_ID = 1606u32;\npub const TMT_WINDOWFRAME: THEME_PROPERTY_SYMBOL_ID = 1607u32;\npub const TMT_WINDOWTEXT: THEME_PROPERTY_SYMBOL_ID = 1609u32;\npub const TMT_XMLNAME: THEME_PROPERTY_SYMBOL_ID = 1402u32;\npub const TNP_ANIMBACKGROUND: TRAYNOTIFYPARTS = 2i32;\npub const TNP_BACKGROUND: TRAYNOTIFYPARTS = 1i32;\npub const TOOLBARCLASSNAME: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ToolbarWindow32\");\npub const TOOLBARCLASSNAMEA: windows_sys::core::PCSTR = windows_sys::core::s!(\"ToolbarWindow32\");\npub const TOOLBARCLASSNAMEW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ToolbarWindow32\");\npub type TOOLBARPARTS = i32;\npub type TOOLBARSTYLESTATES = i32;\npub type TOOLTIPPARTS = i32;\npub const TOOLTIPS_CLASS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"tooltips_class32\");\npub const TOOLTIPS_CLASSA: windows_sys::core::PCSTR = windows_sys::core::s!(\"tooltips_class32\");\npub const TOOLTIPS_CLASSW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"tooltips_class32\");\npub type TOOLTIP_FLAGS = u32;\npub type TOPTABITEMBOTHEDGESTATES = i32;\npub type TOPTABITEMLEFTEDGESTATES = i32;\npub type TOPTABITEMRIGHTEDGESTATES = i32;\npub type TOPTABITEMSTATES = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TOUCH_HIT_TESTING_INPUT {\n    pub pointerId: u32,\n    pub point: super::super::Foundation::POINT,\n    pub boundingBox: super::super::Foundation::RECT,\n    pub nonOccludedBoundingBox: super::super::Foundation::RECT,\n    pub orientation: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TOUCH_HIT_TESTING_PROXIMITY_EVALUATION {\n    pub score: u16,\n    pub adjustedPoint: super::super::Foundation::POINT,\n}\npub const TP_BUTTON: TOOLBARPARTS = 1i32;\npub const TP_DROPDOWNBUTTON: TOOLBARPARTS = 2i32;\npub const TP_DROPDOWNBUTTONGLYPH: TOOLBARPARTS = 7i32;\npub const TP_SEPARATOR: TOOLBARPARTS = 5i32;\npub const TP_SEPARATORVERT: TOOLBARPARTS = 6i32;\npub const TP_SPLITBUTTON: TOOLBARPARTS = 3i32;\npub const TP_SPLITBUTTONDROPDOWN: TOOLBARPARTS = 4i32;\npub type TRACKBARPARTS = i32;\npub type TRACKBARSTYLESTATES = i32;\npub const TRACKBAR_CLASS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"msctls_trackbar32\");\npub const TRACKBAR_CLASSA: windows_sys::core::PCSTR = windows_sys::core::s!(\"msctls_trackbar32\");\npub const TRACKBAR_CLASSW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"msctls_trackbar32\");\npub type TRACKSTATES = i32;\npub type TRACKVERTSTATES = i32;\npub type TRAILINGGRIDCELLSTATES = i32;\npub type TRAILINGGRIDCELLUPPERSTATES = i32;\npub type TRANSPARENTBACKGROUNDSTATES = i32;\npub type TRANSPARENTBARSTATES = i32;\npub type TRANSPARENTBARVERTSTATES = i32;\npub type TRAYNOTIFYPARTS = i32;\npub const TRBN_FIRST: u32 = 4294965795u32;\npub const TRBN_LAST: u32 = 4294965777u32;\npub const TRBN_THUMBPOSCHANGING: u32 = 4294965794u32;\npub type TREEITEMSTATES = i32;\npub type TREEVIEWPARTS = i32;\npub type TREE_VIEW_ITEM_STATE_FLAGS = u32;\npub const TREIS_DISABLED: TREEITEMSTATES = 4i32;\npub const TREIS_HOT: TREEITEMSTATES = 2i32;\npub const TREIS_HOTSELECTED: TREEITEMSTATES = 6i32;\npub const TREIS_NORMAL: TREEITEMSTATES = 1i32;\npub const TREIS_SELECTED: TREEITEMSTATES = 3i32;\npub const TREIS_SELECTEDNOTFOCUS: TREEITEMSTATES = 5i32;\npub const TRS_NORMAL: TRACKSTATES = 1i32;\npub type TRUESIZESCALINGTYPE = i32;\npub const TRVS_NORMAL: TRACKVERTSTATES = 1i32;\npub const TSGP_GRIPPER: TEXTSELECTIONGRIPPERPARTS = 1i32;\npub const TSGS_CENTERED: GRIPPERSTATES = 2i32;\npub const TSGS_NORMAL: GRIPPERSTATES = 1i32;\npub const TSST_DPI: TRUESIZESCALINGTYPE = 2i32;\npub const TSST_NONE: TRUESIZESCALINGTYPE = 0i32;\npub const TSST_SIZE: TRUESIZESCALINGTYPE = 1i32;\npub const TSS_NORMAL: TICSSTATES = 1i32;\npub const TST_CONTINUOUS: TEXTSHADOWTYPE = 2i32;\npub const TST_NONE: TEXTSHADOWTYPE = 0i32;\npub const TST_SINGLE: TEXTSHADOWTYPE = 1i32;\npub const TSVS_NORMAL: TICSVERTSTATES = 1i32;\npub const TS_CHECKED: TOOLBARSTYLESTATES = 5i32;\npub const TS_CONTROLLABEL_DISABLED: CONTROLLABELSTATES = 2i32;\npub const TS_CONTROLLABEL_NORMAL: CONTROLLABELSTATES = 1i32;\npub const TS_DISABLED: TOOLBARSTYLESTATES = 4i32;\npub const TS_DRAW: THEMESIZE = 2i32;\npub const TS_HOT: TOOLBARSTYLESTATES = 2i32;\npub const TS_HOTCHECKED: TOOLBARSTYLESTATES = 6i32;\npub const TS_HYPERLINK_DISABLED: HYPERLINKTEXTSTATES = 4i32;\npub const TS_HYPERLINK_HOT: HYPERLINKTEXTSTATES = 2i32;\npub const TS_HYPERLINK_NORMAL: HYPERLINKTEXTSTATES = 1i32;\npub const TS_HYPERLINK_PRESSED: HYPERLINKTEXTSTATES = 3i32;\npub const TS_MIN: THEMESIZE = 0i32;\npub const TS_NEARHOT: TOOLBARSTYLESTATES = 7i32;\npub const TS_NORMAL: TOOLBARSTYLESTATES = 1i32;\npub const TS_OTHERSIDEHOT: TOOLBARSTYLESTATES = 8i32;\npub const TS_PRESSED: TOOLBARSTYLESTATES = 3i32;\npub const TS_TRUE: THEMESIZE = 1i32;\npub const TTBSS_POINTINGDOWNCENTERED: BALLOONSTEMSTATES = 5i32;\npub const TTBSS_POINTINGDOWNLEFTWALL: BALLOONSTEMSTATES = 6i32;\npub const TTBSS_POINTINGDOWNRIGHTWALL: BALLOONSTEMSTATES = 4i32;\npub const TTBSS_POINTINGUPCENTERED: BALLOONSTEMSTATES = 2i32;\npub const TTBSS_POINTINGUPLEFTWALL: BALLOONSTEMSTATES = 1i32;\npub const TTBSS_POINTINGUPRIGHTWALL: BALLOONSTEMSTATES = 3i32;\npub const TTBS_LINK: BALLOONSTATES = 2i32;\npub const TTBS_NORMAL: BALLOONSTATES = 1i32;\npub const TTCS_HOT: CLOSESTATES = 2i32;\npub const TTCS_NORMAL: CLOSESTATES = 1i32;\npub const TTCS_PRESSED: CLOSESTATES = 3i32;\npub const TTDT_AUTOMATIC: u32 = 0u32;\npub const TTDT_AUTOPOP: u32 = 2u32;\npub const TTDT_INITIAL: u32 = 3u32;\npub const TTDT_RESHOW: u32 = 1u32;\npub const TTFT_CUBIC_BEZIER: TA_TIMINGFUNCTION_TYPE = 1i32;\npub const TTFT_UNDEFINED: TA_TIMINGFUNCTION_TYPE = 0i32;\npub const TTF_ABSOLUTE: TOOLTIP_FLAGS = 128u32;\npub const TTF_CENTERTIP: TOOLTIP_FLAGS = 2u32;\npub const TTF_DI_SETITEM: TOOLTIP_FLAGS = 32768u32;\npub const TTF_IDISHWND: TOOLTIP_FLAGS = 1u32;\npub const TTF_PARSELINKS: TOOLTIP_FLAGS = 4096u32;\npub const TTF_RTLREADING: TOOLTIP_FLAGS = 4u32;\npub const TTF_SUBCLASS: TOOLTIP_FLAGS = 16u32;\npub const TTF_TRACK: TOOLTIP_FLAGS = 32u32;\npub const TTF_TRANSPARENT: TOOLTIP_FLAGS = 256u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TTGETTITLE {\n    pub dwSize: u32,\n    pub uTitleBitmap: u32,\n    pub cch: u32,\n    pub pszTitle: windows_sys::core::PWSTR,\n}\nimpl Default for TTGETTITLE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TTHITTESTINFOA {\n    pub hwnd: super::super::Foundation::HWND,\n    pub pt: super::super::Foundation::POINT,\n    pub ti: TTTOOLINFOA,\n}\nimpl Default for TTHITTESTINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TTHITTESTINFOW {\n    pub hwnd: super::super::Foundation::HWND,\n    pub pt: super::super::Foundation::POINT,\n    pub ti: TTTOOLINFOW,\n}\nimpl Default for TTHITTESTINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const TTIBES_DISABLED: TOPTABITEMBOTHEDGESTATES = 4i32;\npub const TTIBES_FOCUSED: TOPTABITEMBOTHEDGESTATES = 5i32;\npub const TTIBES_HOT: TOPTABITEMBOTHEDGESTATES = 2i32;\npub const TTIBES_NORMAL: TOPTABITEMBOTHEDGESTATES = 1i32;\npub const TTIBES_SELECTED: TOPTABITEMBOTHEDGESTATES = 3i32;\npub const TTILES_DISABLED: TOPTABITEMLEFTEDGESTATES = 4i32;\npub const TTILES_FOCUSED: TOPTABITEMLEFTEDGESTATES = 5i32;\npub const TTILES_HOT: TOPTABITEMLEFTEDGESTATES = 2i32;\npub const TTILES_NORMAL: TOPTABITEMLEFTEDGESTATES = 1i32;\npub const TTILES_SELECTED: TOPTABITEMLEFTEDGESTATES = 3i32;\npub const TTIRES_DISABLED: TOPTABITEMRIGHTEDGESTATES = 4i32;\npub const TTIRES_FOCUSED: TOPTABITEMRIGHTEDGESTATES = 5i32;\npub const TTIRES_HOT: TOPTABITEMRIGHTEDGESTATES = 2i32;\npub const TTIRES_NORMAL: TOPTABITEMRIGHTEDGESTATES = 1i32;\npub const TTIRES_SELECTED: TOPTABITEMRIGHTEDGESTATES = 3i32;\npub const TTIS_DISABLED: TOPTABITEMSTATES = 4i32;\npub const TTIS_FOCUSED: TOPTABITEMSTATES = 5i32;\npub const TTIS_HOT: TOPTABITEMSTATES = 2i32;\npub const TTIS_NORMAL: TOPTABITEMSTATES = 1i32;\npub const TTIS_SELECTED: TOPTABITEMSTATES = 3i32;\npub const TTI_ERROR: EDITBALLOONTIP_ICON = 3i32;\npub const TTI_ERROR_LARGE: EDITBALLOONTIP_ICON = 6i32;\npub const TTI_INFO: EDITBALLOONTIP_ICON = 1i32;\npub const TTI_INFO_LARGE: EDITBALLOONTIP_ICON = 4i32;\npub const TTI_NONE: EDITBALLOONTIP_ICON = 0i32;\npub const TTI_WARNING: EDITBALLOONTIP_ICON = 2i32;\npub const TTI_WARNING_LARGE: EDITBALLOONTIP_ICON = 5i32;\npub const TTM_ACTIVATE: u32 = 1025u32;\npub const TTM_ADDTOOL: u32 = 1074u32;\npub const TTM_ADDTOOLA: u32 = 1028u32;\npub const TTM_ADDTOOLW: u32 = 1074u32;\npub const TTM_ADJUSTRECT: u32 = 1055u32;\npub const TTM_DELTOOL: u32 = 1075u32;\npub const TTM_DELTOOLA: u32 = 1029u32;\npub const TTM_DELTOOLW: u32 = 1075u32;\npub const TTM_ENUMTOOLS: u32 = 1082u32;\npub const TTM_ENUMTOOLSA: u32 = 1038u32;\npub const TTM_ENUMTOOLSW: u32 = 1082u32;\npub const TTM_GETBUBBLESIZE: u32 = 1054u32;\npub const TTM_GETCURRENTTOOL: u32 = 1083u32;\npub const TTM_GETCURRENTTOOLA: u32 = 1039u32;\npub const TTM_GETCURRENTTOOLW: u32 = 1083u32;\npub const TTM_GETDELAYTIME: u32 = 1045u32;\npub const TTM_GETMARGIN: u32 = 1051u32;\npub const TTM_GETMAXTIPWIDTH: u32 = 1049u32;\npub const TTM_GETTEXT: u32 = 1080u32;\npub const TTM_GETTEXTA: u32 = 1035u32;\npub const TTM_GETTEXTW: u32 = 1080u32;\npub const TTM_GETTIPBKCOLOR: u32 = 1046u32;\npub const TTM_GETTIPTEXTCOLOR: u32 = 1047u32;\npub const TTM_GETTITLE: u32 = 1059u32;\npub const TTM_GETTOOLCOUNT: u32 = 1037u32;\npub const TTM_GETTOOLINFO: u32 = 1077u32;\npub const TTM_GETTOOLINFOA: u32 = 1032u32;\npub const TTM_GETTOOLINFOW: u32 = 1077u32;\npub const TTM_HITTEST: u32 = 1079u32;\npub const TTM_HITTESTA: u32 = 1034u32;\npub const TTM_HITTESTW: u32 = 1079u32;\npub const TTM_NEWTOOLRECT: u32 = 1076u32;\npub const TTM_NEWTOOLRECTA: u32 = 1030u32;\npub const TTM_NEWTOOLRECTW: u32 = 1076u32;\npub const TTM_POP: u32 = 1052u32;\npub const TTM_POPUP: u32 = 1058u32;\npub const TTM_RELAYEVENT: u32 = 1031u32;\npub const TTM_SETDELAYTIME: u32 = 1027u32;\npub const TTM_SETMARGIN: u32 = 1050u32;\npub const TTM_SETMAXTIPWIDTH: u32 = 1048u32;\npub const TTM_SETTIPBKCOLOR: u32 = 1043u32;\npub const TTM_SETTIPTEXTCOLOR: u32 = 1044u32;\npub const TTM_SETTITLE: u32 = 1057u32;\npub const TTM_SETTITLEA: u32 = 1056u32;\npub const TTM_SETTITLEW: u32 = 1057u32;\npub const TTM_SETTOOLINFO: u32 = 1078u32;\npub const TTM_SETTOOLINFOA: u32 = 1033u32;\npub const TTM_SETTOOLINFOW: u32 = 1078u32;\npub const TTM_SETWINDOWTHEME: u32 = 8203u32;\npub const TTM_TRACKACTIVATE: u32 = 1041u32;\npub const TTM_TRACKPOSITION: u32 = 1042u32;\npub const TTM_UPDATE: u32 = 1053u32;\npub const TTM_UPDATETIPTEXT: u32 = 1081u32;\npub const TTM_UPDATETIPTEXTA: u32 = 1036u32;\npub const TTM_UPDATETIPTEXTW: u32 = 1081u32;\npub const TTM_WINDOWFROMPOINT: u32 = 1040u32;\npub const TTN_FIRST: u32 = 4294966776u32;\npub const TTN_GETDISPINFO: u32 = 4294966766u32;\npub const TTN_GETDISPINFOA: u32 = 4294966776u32;\npub const TTN_GETDISPINFOW: u32 = 4294966766u32;\npub const TTN_LAST: u32 = 4294966747u32;\npub const TTN_LINKCLICK: u32 = 4294966773u32;\npub const TTN_NEEDTEXT: u32 = 4294966766u32;\npub const TTN_NEEDTEXTA: u32 = 4294966776u32;\npub const TTN_NEEDTEXTW: u32 = 4294966766u32;\npub const TTN_POP: u32 = 4294966774u32;\npub const TTN_SHOW: u32 = 4294966775u32;\npub const TTP_BALLOON: TOOLTIPPARTS = 3i32;\npub const TTP_BALLOONSTEM: TOOLTIPPARTS = 6i32;\npub const TTP_BALLOONTITLE: TOOLTIPPARTS = 4i32;\npub const TTP_CLOSE: TOOLTIPPARTS = 5i32;\npub const TTP_STANDARD: TOOLTIPPARTS = 1i32;\npub const TTP_STANDARDTITLE: TOOLTIPPARTS = 2i32;\npub const TTP_WRENCH: TOOLTIPPARTS = 7i32;\npub const TTSS_LINK: STANDARDSTATES = 2i32;\npub const TTSS_NORMAL: STANDARDSTATES = 1i32;\npub const TTS_ALWAYSTIP: u32 = 1u32;\npub const TTS_BALLOON: u32 = 64u32;\npub const TTS_CLOSE: u32 = 128u32;\npub const TTS_NOANIMATE: u32 = 16u32;\npub const TTS_NOFADE: u32 = 32u32;\npub const TTS_NOPREFIX: u32 = 2u32;\npub const TTS_USEVISUALSTYLE: u32 = 256u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TTTOOLINFOA {\n    pub cbSize: u32,\n    pub uFlags: TOOLTIP_FLAGS,\n    pub hwnd: super::super::Foundation::HWND,\n    pub uId: usize,\n    pub rect: super::super::Foundation::RECT,\n    pub hinst: super::super::Foundation::HINSTANCE,\n    pub lpszText: windows_sys::core::PSTR,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub lpReserved: *mut core::ffi::c_void,\n}\nimpl Default for TTTOOLINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TTTOOLINFOW {\n    pub cbSize: u32,\n    pub uFlags: TOOLTIP_FLAGS,\n    pub hwnd: super::super::Foundation::HWND,\n    pub uId: usize,\n    pub rect: super::super::Foundation::RECT,\n    pub hinst: super::super::Foundation::HINSTANCE,\n    pub lpszText: windows_sys::core::PWSTR,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub lpReserved: *mut core::ffi::c_void,\n}\nimpl Default for TTTOOLINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const TTWS_HOT: WRENCHSTATES = 2i32;\npub const TTWS_NORMAL: WRENCHSTATES = 1i32;\npub const TTWS_PRESSED: WRENCHSTATES = 3i32;\npub const TUBS_DISABLED: THUMBBOTTOMSTATES = 5i32;\npub const TUBS_FOCUSED: THUMBBOTTOMSTATES = 4i32;\npub const TUBS_HOT: THUMBBOTTOMSTATES = 2i32;\npub const TUBS_NORMAL: THUMBBOTTOMSTATES = 1i32;\npub const TUBS_PRESSED: THUMBBOTTOMSTATES = 3i32;\npub const TUS_DISABLED: THUMBSTATES = 5i32;\npub const TUS_FOCUSED: THUMBSTATES = 4i32;\npub const TUS_HOT: THUMBSTATES = 2i32;\npub const TUS_NORMAL: THUMBSTATES = 1i32;\npub const TUS_PRESSED: THUMBSTATES = 3i32;\npub const TUTS_DISABLED: THUMBTOPSTATES = 5i32;\npub const TUTS_FOCUSED: THUMBTOPSTATES = 4i32;\npub const TUTS_HOT: THUMBTOPSTATES = 2i32;\npub const TUTS_NORMAL: THUMBTOPSTATES = 1i32;\npub const TUTS_PRESSED: THUMBTOPSTATES = 3i32;\npub const TUVLS_DISABLED: THUMBLEFTSTATES = 5i32;\npub const TUVLS_FOCUSED: THUMBLEFTSTATES = 4i32;\npub const TUVLS_HOT: THUMBLEFTSTATES = 2i32;\npub const TUVLS_NORMAL: THUMBLEFTSTATES = 1i32;\npub const TUVLS_PRESSED: THUMBLEFTSTATES = 3i32;\npub const TUVRS_DISABLED: THUMBRIGHTSTATES = 5i32;\npub const TUVRS_FOCUSED: THUMBRIGHTSTATES = 4i32;\npub const TUVRS_HOT: THUMBRIGHTSTATES = 2i32;\npub const TUVRS_NORMAL: THUMBRIGHTSTATES = 1i32;\npub const TUVRS_PRESSED: THUMBRIGHTSTATES = 3i32;\npub const TUVS_DISABLED: THUMBVERTSTATES = 5i32;\npub const TUVS_FOCUSED: THUMBVERTSTATES = 4i32;\npub const TUVS_HOT: THUMBVERTSTATES = 2i32;\npub const TUVS_NORMAL: THUMBVERTSTATES = 1i32;\npub const TUVS_PRESSED: THUMBVERTSTATES = 3i32;\npub const TVCDRF_NOIMAGES: u32 = 65536u32;\npub const TVC_BYKEYBOARD: NM_TREEVIEW_ACTION = 2u32;\npub const TVC_BYMOUSE: NM_TREEVIEW_ACTION = 1u32;\npub const TVC_UNKNOWN: NM_TREEVIEW_ACTION = 0u32;\npub const TVE_COLLAPSE: NM_TREEVIEW_ACTION = 1u32;\npub const TVE_COLLAPSERESET: NM_TREEVIEW_ACTION = 32768u32;\npub const TVE_EXPAND: NM_TREEVIEW_ACTION = 2u32;\npub const TVE_EXPANDPARTIAL: NM_TREEVIEW_ACTION = 16384u32;\npub const TVE_TOGGLE: NM_TREEVIEW_ACTION = 3u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TVGETITEMPARTRECTINFO {\n    pub hti: HTREEITEM,\n    pub prc: *mut super::super::Foundation::RECT,\n    pub partID: TVITEMPART,\n}\nimpl Default for TVGETITEMPARTRECTINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const TVGIPR_BUTTON: TVITEMPART = 1i32;\npub const TVGN_CARET: u32 = 9u32;\npub const TVGN_CHILD: u32 = 4u32;\npub const TVGN_DROPHILITE: u32 = 8u32;\npub const TVGN_FIRSTVISIBLE: u32 = 5u32;\npub const TVGN_LASTVISIBLE: u32 = 10u32;\npub const TVGN_NEXT: u32 = 1u32;\npub const TVGN_NEXTSELECTED: u32 = 11u32;\npub const TVGN_NEXTVISIBLE: u32 = 6u32;\npub const TVGN_PARENT: u32 = 3u32;\npub const TVGN_PREVIOUS: u32 = 2u32;\npub const TVGN_PREVIOUSVISIBLE: u32 = 7u32;\npub const TVGN_ROOT: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TVHITTESTINFO {\n    pub pt: super::super::Foundation::POINT,\n    pub flags: TVHITTESTINFO_FLAGS,\n    pub hItem: HTREEITEM,\n}\npub type TVHITTESTINFO_FLAGS = u32;\npub const TVHT_ABOVE: TVHITTESTINFO_FLAGS = 256u32;\npub const TVHT_BELOW: TVHITTESTINFO_FLAGS = 512u32;\npub const TVHT_NOWHERE: TVHITTESTINFO_FLAGS = 1u32;\npub const TVHT_ONITEM: TVHITTESTINFO_FLAGS = 70u32;\npub const TVHT_ONITEMBUTTON: TVHITTESTINFO_FLAGS = 16u32;\npub const TVHT_ONITEMICON: TVHITTESTINFO_FLAGS = 2u32;\npub const TVHT_ONITEMINDENT: TVHITTESTINFO_FLAGS = 8u32;\npub const TVHT_ONITEMLABEL: TVHITTESTINFO_FLAGS = 4u32;\npub const TVHT_ONITEMRIGHT: TVHITTESTINFO_FLAGS = 32u32;\npub const TVHT_ONITEMSTATEICON: TVHITTESTINFO_FLAGS = 64u32;\npub const TVHT_TOLEFT: TVHITTESTINFO_FLAGS = 2048u32;\npub const TVHT_TORIGHT: TVHITTESTINFO_FLAGS = 1024u32;\npub const TVIF_CHILDREN: TVITEM_MASK = 64u32;\npub const TVIF_DI_SETITEM: TVITEM_MASK = 4096u32;\npub const TVIF_EXPANDEDIMAGE: TVITEM_MASK = 512u32;\npub const TVIF_HANDLE: TVITEM_MASK = 16u32;\npub const TVIF_IMAGE: TVITEM_MASK = 2u32;\npub const TVIF_INTEGRAL: TVITEM_MASK = 128u32;\npub const TVIF_PARAM: TVITEM_MASK = 4u32;\npub const TVIF_SELECTEDIMAGE: TVITEM_MASK = 32u32;\npub const TVIF_STATE: TVITEM_MASK = 8u32;\npub const TVIF_STATEEX: TVITEM_MASK = 256u32;\npub const TVIF_TEXT: TVITEM_MASK = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TVINSERTSTRUCTA {\n    pub hParent: HTREEITEM,\n    pub hInsertAfter: HTREEITEM,\n    pub Anonymous: TVINSERTSTRUCTA_0,\n}\nimpl Default for TVINSERTSTRUCTA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union TVINSERTSTRUCTA_0 {\n    pub itemex: TVITEMEXA,\n    pub item: TVITEMA,\n}\nimpl Default for TVINSERTSTRUCTA_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TVINSERTSTRUCTW {\n    pub hParent: HTREEITEM,\n    pub hInsertAfter: HTREEITEM,\n    pub Anonymous: TVINSERTSTRUCTW_0,\n}\nimpl Default for TVINSERTSTRUCTW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub union TVINSERTSTRUCTW_0 {\n    pub itemex: TVITEMEXW,\n    pub item: TVITEMW,\n}\nimpl Default for TVINSERTSTRUCTW_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const TVIS_BOLD: TREE_VIEW_ITEM_STATE_FLAGS = 16u32;\npub const TVIS_CUT: TREE_VIEW_ITEM_STATE_FLAGS = 4u32;\npub const TVIS_DROPHILITED: TREE_VIEW_ITEM_STATE_FLAGS = 8u32;\npub const TVIS_EXPANDED: TREE_VIEW_ITEM_STATE_FLAGS = 32u32;\npub const TVIS_EXPANDEDONCE: TREE_VIEW_ITEM_STATE_FLAGS = 64u32;\npub const TVIS_EXPANDPARTIAL: TREE_VIEW_ITEM_STATE_FLAGS = 128u32;\npub const TVIS_EX_ALL: TREE_VIEW_ITEM_STATE_FLAGS = 2u32;\npub const TVIS_EX_DISABLED: TREE_VIEW_ITEM_STATE_FLAGS = 2u32;\npub const TVIS_EX_FLAT: TREE_VIEW_ITEM_STATE_FLAGS = 1u32;\npub const TVIS_OVERLAYMASK: TREE_VIEW_ITEM_STATE_FLAGS = 3840u32;\npub const TVIS_SELECTED: TREE_VIEW_ITEM_STATE_FLAGS = 2u32;\npub const TVIS_STATEIMAGEMASK: TREE_VIEW_ITEM_STATE_FLAGS = 61440u32;\npub const TVIS_USERMASK: TREE_VIEW_ITEM_STATE_FLAGS = 61440u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TVITEMA {\n    pub mask: TVITEM_MASK,\n    pub hItem: HTREEITEM,\n    pub state: TREE_VIEW_ITEM_STATE_FLAGS,\n    pub stateMask: TREE_VIEW_ITEM_STATE_FLAGS,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub iSelectedImage: i32,\n    pub cChildren: TVITEMEXW_CHILDREN,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for TVITEMA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TVITEMEXA {\n    pub mask: TVITEM_MASK,\n    pub hItem: HTREEITEM,\n    pub state: u32,\n    pub stateMask: u32,\n    pub pszText: windows_sys::core::PSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub iSelectedImage: i32,\n    pub cChildren: TVITEMEXW_CHILDREN,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub iIntegral: i32,\n    pub uStateEx: u32,\n    pub hwnd: super::super::Foundation::HWND,\n    pub iExpandedImage: i32,\n    pub iReserved: i32,\n}\nimpl Default for TVITEMEXA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TVITEMEXW {\n    pub mask: TVITEM_MASK,\n    pub hItem: HTREEITEM,\n    pub state: u32,\n    pub stateMask: u32,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub iSelectedImage: i32,\n    pub cChildren: TVITEMEXW_CHILDREN,\n    pub lParam: super::super::Foundation::LPARAM,\n    pub iIntegral: i32,\n    pub uStateEx: u32,\n    pub hwnd: super::super::Foundation::HWND,\n    pub iExpandedImage: i32,\n    pub iReserved: i32,\n}\nimpl Default for TVITEMEXW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type TVITEMEXW_CHILDREN = i32;\npub type TVITEMPART = i32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TVITEMW {\n    pub mask: TVITEM_MASK,\n    pub hItem: HTREEITEM,\n    pub state: TREE_VIEW_ITEM_STATE_FLAGS,\n    pub stateMask: TREE_VIEW_ITEM_STATE_FLAGS,\n    pub pszText: windows_sys::core::PWSTR,\n    pub cchTextMax: i32,\n    pub iImage: i32,\n    pub iSelectedImage: i32,\n    pub cChildren: TVITEMEXW_CHILDREN,\n    pub lParam: super::super::Foundation::LPARAM,\n}\nimpl Default for TVITEMW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type TVITEM_MASK = u32;\npub const TVI_FIRST: HTREEITEM = -65535i32 as _;\npub const TVI_LAST: HTREEITEM = -65534i32 as _;\npub const TVI_ROOT: HTREEITEM = -65536i32 as _;\npub const TVI_SORT: HTREEITEM = -65533i32 as _;\npub const TVM_CREATEDRAGIMAGE: u32 = 4370u32;\npub const TVM_DELETEITEM: u32 = 4353u32;\npub const TVM_EDITLABEL: u32 = 4417u32;\npub const TVM_EDITLABELA: u32 = 4366u32;\npub const TVM_EDITLABELW: u32 = 4417u32;\npub const TVM_ENDEDITLABELNOW: u32 = 4374u32;\npub const TVM_ENSUREVISIBLE: u32 = 4372u32;\npub const TVM_EXPAND: u32 = 4354u32;\npub const TVM_GETBKCOLOR: u32 = 4383u32;\npub const TVM_GETCOUNT: u32 = 4357u32;\npub const TVM_GETEDITCONTROL: u32 = 4367u32;\npub const TVM_GETEXTENDEDSTYLE: u32 = 4397u32;\npub const TVM_GETIMAGELIST: u32 = 4360u32;\npub const TVM_GETINDENT: u32 = 4358u32;\npub const TVM_GETINSERTMARKCOLOR: u32 = 4390u32;\npub const TVM_GETISEARCHSTRING: u32 = 4416u32;\npub const TVM_GETISEARCHSTRINGA: u32 = 4375u32;\npub const TVM_GETISEARCHSTRINGW: u32 = 4416u32;\npub const TVM_GETITEM: u32 = 4414u32;\npub const TVM_GETITEMA: u32 = 4364u32;\npub const TVM_GETITEMHEIGHT: u32 = 4380u32;\npub const TVM_GETITEMPARTRECT: u32 = 4424u32;\npub const TVM_GETITEMRECT: u32 = 4356u32;\npub const TVM_GETITEMSTATE: u32 = 4391u32;\npub const TVM_GETITEMW: u32 = 4414u32;\npub const TVM_GETLINECOLOR: u32 = 4393u32;\npub const TVM_GETNEXTITEM: u32 = 4362u32;\npub const TVM_GETSCROLLTIME: u32 = 4386u32;\npub const TVM_GETSELECTEDCOUNT: u32 = 4422u32;\npub const TVM_GETTEXTCOLOR: u32 = 4384u32;\npub const TVM_GETTOOLTIPS: u32 = 4377u32;\npub const TVM_GETUNICODEFORMAT: u32 = 8198u32;\npub const TVM_GETVISIBLECOUNT: u32 = 4368u32;\npub const TVM_HITTEST: u32 = 4369u32;\npub const TVM_INSERTITEM: u32 = 4402u32;\npub const TVM_INSERTITEMA: u32 = 4352u32;\npub const TVM_INSERTITEMW: u32 = 4402u32;\npub const TVM_MAPACCIDTOHTREEITEM: u32 = 4394u32;\npub const TVM_MAPHTREEITEMTOACCID: u32 = 4395u32;\npub const TVM_SELECTITEM: u32 = 4363u32;\npub const TVM_SETAUTOSCROLLINFO: u32 = 4411u32;\npub const TVM_SETBKCOLOR: u32 = 4381u32;\npub const TVM_SETBORDER: u32 = 4387u32;\npub const TVM_SETEXTENDEDSTYLE: u32 = 4396u32;\npub const TVM_SETHOT: u32 = 4410u32;\npub const TVM_SETIMAGELIST: u32 = 4361u32;\npub const TVM_SETINDENT: u32 = 4359u32;\npub const TVM_SETINSERTMARK: u32 = 4378u32;\npub const TVM_SETINSERTMARKCOLOR: u32 = 4389u32;\npub const TVM_SETITEM: u32 = 4415u32;\npub const TVM_SETITEMA: u32 = 4365u32;\npub const TVM_SETITEMHEIGHT: u32 = 4379u32;\npub const TVM_SETITEMW: u32 = 4415u32;\npub const TVM_SETLINECOLOR: u32 = 4392u32;\npub const TVM_SETSCROLLTIME: u32 = 4385u32;\npub const TVM_SETTEXTCOLOR: u32 = 4382u32;\npub const TVM_SETTOOLTIPS: u32 = 4376u32;\npub const TVM_SETUNICODEFORMAT: u32 = 8197u32;\npub const TVM_SHOWINFOTIP: u32 = 4423u32;\npub const TVM_SORTCHILDREN: u32 = 4371u32;\npub const TVM_SORTCHILDRENCB: u32 = 4373u32;\npub const TVNRET_DEFAULT: u32 = 0u32;\npub const TVNRET_SKIPNEW: u32 = 2u32;\npub const TVNRET_SKIPOLD: u32 = 1u32;\npub const TVN_ASYNCDRAW: u32 = 4294966876u32;\npub const TVN_BEGINDRAG: u32 = 4294966840u32;\npub const TVN_BEGINDRAGA: u32 = 4294966889u32;\npub const TVN_BEGINDRAGW: u32 = 4294966840u32;\npub const TVN_BEGINLABELEDIT: u32 = 4294966837u32;\npub const TVN_BEGINLABELEDITA: u32 = 4294966886u32;\npub const TVN_BEGINLABELEDITW: u32 = 4294966837u32;\npub const TVN_BEGINRDRAG: u32 = 4294966839u32;\npub const TVN_BEGINRDRAGA: u32 = 4294966888u32;\npub const TVN_BEGINRDRAGW: u32 = 4294966839u32;\npub const TVN_DELETEITEM: u32 = 4294966838u32;\npub const TVN_DELETEITEMA: u32 = 4294966887u32;\npub const TVN_DELETEITEMW: u32 = 4294966838u32;\npub const TVN_ENDLABELEDIT: u32 = 4294966836u32;\npub const TVN_ENDLABELEDITA: u32 = 4294966885u32;\npub const TVN_ENDLABELEDITW: u32 = 4294966836u32;\npub const TVN_FIRST: u32 = 4294966896u32;\npub const TVN_GETDISPINFO: u32 = 4294966844u32;\npub const TVN_GETDISPINFOA: u32 = 4294966893u32;\npub const TVN_GETDISPINFOW: u32 = 4294966844u32;\npub const TVN_GETINFOTIP: u32 = 4294966882u32;\npub const TVN_GETINFOTIPA: u32 = 4294966883u32;\npub const TVN_GETINFOTIPW: u32 = 4294966882u32;\npub const TVN_ITEMCHANGED: u32 = 4294966877u32;\npub const TVN_ITEMCHANGEDA: u32 = 4294966878u32;\npub const TVN_ITEMCHANGEDW: u32 = 4294966877u32;\npub const TVN_ITEMCHANGING: u32 = 4294966879u32;\npub const TVN_ITEMCHANGINGA: u32 = 4294966880u32;\npub const TVN_ITEMCHANGINGW: u32 = 4294966879u32;\npub const TVN_ITEMEXPANDED: u32 = 4294966841u32;\npub const TVN_ITEMEXPANDEDA: u32 = 4294966890u32;\npub const TVN_ITEMEXPANDEDW: u32 = 4294966841u32;\npub const TVN_ITEMEXPANDING: u32 = 4294966842u32;\npub const TVN_ITEMEXPANDINGA: u32 = 4294966891u32;\npub const TVN_ITEMEXPANDINGW: u32 = 4294966842u32;\npub const TVN_KEYDOWN: u32 = 4294966884u32;\npub const TVN_LAST: u32 = 4294966797u32;\npub const TVN_SELCHANGED: u32 = 4294966845u32;\npub const TVN_SELCHANGEDA: u32 = 4294966894u32;\npub const TVN_SELCHANGEDW: u32 = 4294966845u32;\npub const TVN_SELCHANGING: u32 = 4294966846u32;\npub const TVN_SELCHANGINGA: u32 = 4294966895u32;\npub const TVN_SELCHANGINGW: u32 = 4294966846u32;\npub const TVN_SETDISPINFO: u32 = 4294966843u32;\npub const TVN_SETDISPINFOA: u32 = 4294966892u32;\npub const TVN_SETDISPINFOW: u32 = 4294966843u32;\npub const TVN_SINGLEEXPAND: u32 = 4294966881u32;\npub const TVP_BRANCH: TREEVIEWPARTS = 3i32;\npub const TVP_GLYPH: TREEVIEWPARTS = 2i32;\npub const TVP_HOTGLYPH: TREEVIEWPARTS = 4i32;\npub const TVP_TREEITEM: TREEVIEWPARTS = 1i32;\npub const TVSBF_XBORDER: u32 = 1u32;\npub const TVSBF_YBORDER: u32 = 2u32;\npub const TVSIL_NORMAL: u32 = 0u32;\npub const TVSIL_STATE: u32 = 2u32;\npub const TVSI_NOSINGLEEXPAND: u32 = 32768u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TVSORTCB {\n    pub hParent: HTREEITEM,\n    pub lpfnCompare: PFNTVCOMPARE,\n    pub lParam: super::super::Foundation::LPARAM,\n}\npub const TVS_CHECKBOXES: u32 = 256u32;\npub const TVS_DISABLEDRAGDROP: u32 = 16u32;\npub const TVS_EDITLABELS: u32 = 8u32;\npub const TVS_EX_AUTOHSCROLL: u32 = 32u32;\npub const TVS_EX_DIMMEDCHECKBOXES: u32 = 512u32;\npub const TVS_EX_DOUBLEBUFFER: u32 = 4u32;\npub const TVS_EX_DRAWIMAGEASYNC: u32 = 1024u32;\npub const TVS_EX_EXCLUSIONCHECKBOXES: u32 = 256u32;\npub const TVS_EX_FADEINOUTEXPANDOS: u32 = 64u32;\npub const TVS_EX_MULTISELECT: u32 = 2u32;\npub const TVS_EX_NOINDENTSTATE: u32 = 8u32;\npub const TVS_EX_NOSINGLECOLLAPSE: u32 = 1u32;\npub const TVS_EX_PARTIALCHECKBOXES: u32 = 128u32;\npub const TVS_EX_RICHTOOLTIP: u32 = 16u32;\npub const TVS_FULLROWSELECT: u32 = 4096u32;\npub const TVS_HASBUTTONS: u32 = 1u32;\npub const TVS_HASLINES: u32 = 2u32;\npub const TVS_INFOTIP: u32 = 2048u32;\npub const TVS_LINESATROOT: u32 = 4u32;\npub const TVS_NOHSCROLL: u32 = 32768u32;\npub const TVS_NONEVENHEIGHT: u32 = 16384u32;\npub const TVS_NOSCROLL: u32 = 8192u32;\npub const TVS_NOTOOLTIPS: u32 = 128u32;\npub const TVS_RTLREADING: u32 = 64u32;\npub const TVS_SHOWSELALWAYS: u32 = 32u32;\npub const TVS_SINGLEEXPAND: u32 = 1024u32;\npub const TVS_TRACKSELECT: u32 = 512u32;\npub const TV_FIRST: u32 = 4352u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct UDACCEL {\n    pub nSec: u32,\n    pub nInc: u32,\n}\npub const UDM_GETACCEL: u32 = 1132u32;\npub const UDM_GETBASE: u32 = 1134u32;\npub const UDM_GETBUDDY: u32 = 1130u32;\npub const UDM_GETPOS: u32 = 1128u32;\npub const UDM_GETPOS32: u32 = 1138u32;\npub const UDM_GETRANGE: u32 = 1126u32;\npub const UDM_GETRANGE32: u32 = 1136u32;\npub const UDM_GETUNICODEFORMAT: u32 = 8198u32;\npub const UDM_SETACCEL: u32 = 1131u32;\npub const UDM_SETBASE: u32 = 1133u32;\npub const UDM_SETBUDDY: u32 = 1129u32;\npub const UDM_SETPOS: u32 = 1127u32;\npub const UDM_SETPOS32: u32 = 1137u32;\npub const UDM_SETRANGE: u32 = 1125u32;\npub const UDM_SETRANGE32: u32 = 1135u32;\npub const UDM_SETUNICODEFORMAT: u32 = 8197u32;\npub const UDN_DELTAPOS: u32 = 4294966574u32;\npub const UDN_FIRST: u32 = 4294966575u32;\npub const UDN_LAST: u32 = 4294966567u32;\npub const UDS_ALIGNLEFT: u32 = 8u32;\npub const UDS_ALIGNRIGHT: u32 = 4u32;\npub const UDS_ARROWKEYS: u32 = 32u32;\npub const UDS_AUTOBUDDY: u32 = 16u32;\npub const UDS_HORZ: u32 = 64u32;\npub const UDS_HOTTRACK: u32 = 256u32;\npub const UDS_NOTHOUSANDS: u32 = 128u32;\npub const UDS_SETBUDDYINT: u32 = 2u32;\npub const UDS_WRAP: u32 = 1u32;\npub const UD_MAXVAL: u32 = 32767u32;\npub type UPDATEMETADATASTATES = i32;\npub const UPDOWN_CLASS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"msctls_updown32\");\npub const UPDOWN_CLASSA: windows_sys::core::PCSTR = windows_sys::core::s!(\"msctls_updown32\");\npub const UPDOWN_CLASSW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"msctls_updown32\");\npub type UPHORZSTATES = i32;\npub const UPHZS_DISABLED: UPHORZSTATES = 4i32;\npub const UPHZS_HOT: UPHORZSTATES = 2i32;\npub const UPHZS_NORMAL: UPHORZSTATES = 1i32;\npub const UPHZS_PRESSED: UPHORZSTATES = 3i32;\npub type UPSTATES = i32;\npub const UPS_DISABLED: UPSTATES = 4i32;\npub const UPS_HOT: UPSTATES = 2i32;\npub const UPS_NORMAL: UPSTATES = 1i32;\npub const UPS_PRESSED: UPSTATES = 3i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct USAGE_PROPERTIES {\n    pub level: u16,\n    pub page: u16,\n    pub usage: u16,\n    pub logicalMinimum: i32,\n    pub logicalMaximum: i32,\n    pub unit: u16,\n    pub exponent: u16,\n    pub count: u8,\n    pub physicalMinimum: i32,\n    pub physicalMaximum: i32,\n}\npub type USERTILEPARTS = i32;\npub const UTP_HOVERBACKGROUND: USERTILEPARTS = 2i32;\npub const UTP_STROKEBACKGROUND: USERTILEPARTS = 1i32;\npub const UTS_HOT: HOVERBACKGROUNDSTATES = 2i32;\npub const UTS_NORMAL: HOVERBACKGROUNDSTATES = 1i32;\npub const UTS_PRESSED: HOVERBACKGROUNDSTATES = 3i32;\npub const VALIDBITS: SET_THEME_APP_PROPERTIES_FLAGS = 7u32;\npub type VALIGN = i32;\npub const VA_BOTTOM: VALIGN = 2i32;\npub const VA_CENTER: VALIGN = 1i32;\npub const VA_TOP: VALIGN = 0i32;\npub type VERTSCROLLSTATES = i32;\npub type VERTTHUMBSTATES = i32;\npub const VIEW_DETAILS: u32 = 3u32;\npub const VIEW_LARGEICONS: u32 = 0u32;\npub const VIEW_LIST: u32 = 2u32;\npub const VIEW_NETCONNECT: u32 = 9u32;\npub const VIEW_NETDISCONNECT: u32 = 10u32;\npub const VIEW_NEWFOLDER: u32 = 11u32;\npub const VIEW_PARENTFOLDER: u32 = 8u32;\npub const VIEW_SMALLICONS: u32 = 1u32;\npub const VIEW_SORTDATE: u32 = 6u32;\npub const VIEW_SORTNAME: u32 = 4u32;\npub const VIEW_SORTSIZE: u32 = 5u32;\npub const VIEW_SORTTYPE: u32 = 7u32;\npub const VIEW_VIEWMENU: u32 = 12u32;\npub const VSCLASS_AEROWIZARD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AEROWIZARD\");\npub const VSCLASS_AEROWIZARDSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"AEROWIZARDSTYLE\");\npub const VSCLASS_BUTTON: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BUTTON\");\npub const VSCLASS_BUTTONSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"BUTTONSTYLE\");\npub const VSCLASS_CLOCK: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CLOCK\");\npub const VSCLASS_COMBOBOX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"COMBOBOX\");\npub const VSCLASS_COMBOBOXSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"COMBOBOXSTYLE\");\npub const VSCLASS_COMMUNICATIONS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"COMMUNICATIONS\");\npub const VSCLASS_COMMUNICATIONSSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"COMMUNICATIONSSTYLE\");\npub const VSCLASS_CONTROLPANEL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CONTROLPANEL\");\npub const VSCLASS_CONTROLPANELSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"CONTROLPANELSTYLE\");\npub const VSCLASS_DATEPICKER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DATEPICKER\");\npub const VSCLASS_DATEPICKERSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DATEPICKERSTYLE\");\npub const VSCLASS_DRAGDROP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRAGDROP\");\npub const VSCLASS_DRAGDROPSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"DRAGDROPSTYLE\");\npub const VSCLASS_EDIT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EDIT\");\npub const VSCLASS_EDITSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EDITSTYLE\");\npub const VSCLASS_EMPTYMARKUP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EMPTYMARKUP\");\npub const VSCLASS_EXPLORERBAR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EXPLORERBAR\");\npub const VSCLASS_EXPLORERBARSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"EXPLORERBARSTYLE\");\npub const VSCLASS_FLYOUT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FLYOUT\");\npub const VSCLASS_FLYOUTSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"FLYOUTSTYLE\");\npub const VSCLASS_HEADER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HEADER\");\npub const VSCLASS_HEADERSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"HEADERSTYLE\");\npub const VSCLASS_LINK: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LINK\");\npub const VSCLASS_LISTBOX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LISTBOX\");\npub const VSCLASS_LISTBOXSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LISTBOXSTYLE\");\npub const VSCLASS_LISTVIEW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LISTVIEW\");\npub const VSCLASS_LISTVIEWSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"LISTVIEWSTYLE\");\npub const VSCLASS_MENU: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MENU\");\npub const VSCLASS_MENUBAND: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MENUBAND\");\npub const VSCLASS_MENUSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MENUSTYLE\");\npub const VSCLASS_MONTHCAL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MONTHCAL\");\npub const VSCLASS_NAVIGATION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NAVIGATION\");\npub const VSCLASS_PAGE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PAGE\");\npub const VSCLASS_PROGRESS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PROGRESS\");\npub const VSCLASS_PROGRESSSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"PROGRESSSTYLE\");\npub const VSCLASS_REBAR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"REBAR\");\npub const VSCLASS_REBARSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"REBARSTYLE\");\npub const VSCLASS_SCROLLBAR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SCROLLBAR\");\npub const VSCLASS_SCROLLBARSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SCROLLBARSTYLE\");\npub const VSCLASS_SPIN: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SPIN\");\npub const VSCLASS_SPINSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SPINSTYLE\");\npub const VSCLASS_STARTPANEL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"STARTPANEL\");\npub const VSCLASS_STATIC: windows_sys::core::PCWSTR = windows_sys::core::w!(\"STATIC\");\npub const VSCLASS_STATUS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"STATUS\");\npub const VSCLASS_STATUSSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"STATUSSTYLE\");\npub const VSCLASS_TAB: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TAB\");\npub const VSCLASS_TABSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TABSTYLE\");\npub const VSCLASS_TASKBAND: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TASKBAND\");\npub const VSCLASS_TASKBAR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TASKBAR\");\npub const VSCLASS_TASKDIALOG: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TASKDIALOG\");\npub const VSCLASS_TASKDIALOGSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TASKDIALOGSTYLE\");\npub const VSCLASS_TEXTSELECTIONGRIPPER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TEXTSELECTIONGRIPPER\");\npub const VSCLASS_TEXTSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TEXTSTYLE\");\npub const VSCLASS_TOOLBAR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TOOLBAR\");\npub const VSCLASS_TOOLBARSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TOOLBARSTYLE\");\npub const VSCLASS_TOOLTIP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TOOLTIP\");\npub const VSCLASS_TOOLTIPSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TOOLTIPSTYLE\");\npub const VSCLASS_TRACKBAR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TRACKBAR\");\npub const VSCLASS_TRACKBARSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TRACKBARSTYLE\");\npub const VSCLASS_TRAYNOTIFY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TRAYNOTIFY\");\npub const VSCLASS_TREEVIEW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TREEVIEW\");\npub const VSCLASS_TREEVIEWSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"TREEVIEWSTYLE\");\npub const VSCLASS_USERTILE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"USERTILE\");\npub const VSCLASS_WINDOW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WINDOW\");\npub const VSCLASS_WINDOWSTYLE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"WINDOWSTYLE\");\npub const VSS_DISABLED: VERTSCROLLSTATES = 4i32;\npub const VSS_HOT: VERTSCROLLSTATES = 2i32;\npub const VSS_NORMAL: VERTSCROLLSTATES = 1i32;\npub const VSS_PUSHED: VERTSCROLLSTATES = 3i32;\npub const VTS_DISABLED: VERTTHUMBSTATES = 4i32;\npub const VTS_HOT: VERTTHUMBSTATES = 2i32;\npub const VTS_NORMAL: VERTTHUMBSTATES = 1i32;\npub const VTS_PUSHED: VERTTHUMBSTATES = 3i32;\npub type WARNINGSTATES = i32;\npub const WB_CLASSIFY: WORD_BREAK_ACTION = 3i32;\npub const WB_ISDELIMITER: WORD_BREAK_ACTION = 2i32;\npub const WB_LEFT: WORD_BREAK_ACTION = 0i32;\npub const WB_LEFTBREAK: WORD_BREAK_ACTION = 6i32;\npub const WB_MOVEWORDLEFT: WORD_BREAK_ACTION = 4i32;\npub const WB_MOVEWORDRIGHT: WORD_BREAK_ACTION = 5i32;\npub const WB_RIGHT: WORD_BREAK_ACTION = 1i32;\npub const WB_RIGHTBREAK: WORD_BREAK_ACTION = 7i32;\npub const WC_BUTTON: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Button\");\npub const WC_BUTTONA: windows_sys::core::PCSTR = windows_sys::core::s!(\"Button\");\npub const WC_BUTTONW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Button\");\npub const WC_COMBOBOX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ComboBox\");\npub const WC_COMBOBOXA: windows_sys::core::PCSTR = windows_sys::core::s!(\"ComboBox\");\npub const WC_COMBOBOXEX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ComboBoxEx32\");\npub const WC_COMBOBOXEXA: windows_sys::core::PCSTR = windows_sys::core::s!(\"ComboBoxEx32\");\npub const WC_COMBOBOXEXW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ComboBoxEx32\");\npub const WC_COMBOBOXW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ComboBox\");\npub const WC_EDIT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Edit\");\npub const WC_EDITA: windows_sys::core::PCSTR = windows_sys::core::s!(\"Edit\");\npub const WC_EDITW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Edit\");\npub const WC_HEADER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysHeader32\");\npub const WC_HEADERA: windows_sys::core::PCSTR = windows_sys::core::s!(\"SysHeader32\");\npub const WC_HEADERW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysHeader32\");\npub const WC_IPADDRESS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysIPAddress32\");\npub const WC_IPADDRESSA: windows_sys::core::PCSTR = windows_sys::core::s!(\"SysIPAddress32\");\npub const WC_IPADDRESSW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysIPAddress32\");\npub const WC_LINK: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysLink\");\npub const WC_LISTBOX: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ListBox\");\npub const WC_LISTBOXA: windows_sys::core::PCSTR = windows_sys::core::s!(\"ListBox\");\npub const WC_LISTBOXW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ListBox\");\npub const WC_LISTVIEW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysListView32\");\npub const WC_LISTVIEWA: windows_sys::core::PCSTR = windows_sys::core::s!(\"SysListView32\");\npub const WC_LISTVIEWW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysListView32\");\npub const WC_NATIVEFONTCTL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NativeFontCtl\");\npub const WC_NATIVEFONTCTLA: windows_sys::core::PCSTR = windows_sys::core::s!(\"NativeFontCtl\");\npub const WC_NATIVEFONTCTLW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"NativeFontCtl\");\npub const WC_PAGESCROLLER: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysPager\");\npub const WC_PAGESCROLLERA: windows_sys::core::PCSTR = windows_sys::core::s!(\"SysPager\");\npub const WC_PAGESCROLLERW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysPager\");\npub const WC_SCROLLBAR: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ScrollBar\");\npub const WC_SCROLLBARA: windows_sys::core::PCSTR = windows_sys::core::s!(\"ScrollBar\");\npub const WC_SCROLLBARW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"ScrollBar\");\npub const WC_STATIC: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Static\");\npub const WC_STATICA: windows_sys::core::PCSTR = windows_sys::core::s!(\"Static\");\npub const WC_STATICW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"Static\");\npub const WC_TABCONTROL: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysTabControl32\");\npub const WC_TABCONTROLA: windows_sys::core::PCSTR = windows_sys::core::s!(\"SysTabControl32\");\npub const WC_TABCONTROLW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysTabControl32\");\npub const WC_TREEVIEW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysTreeView32\");\npub const WC_TREEVIEWA: windows_sys::core::PCSTR = windows_sys::core::s!(\"SysTreeView32\");\npub const WC_TREEVIEWW: windows_sys::core::PCWSTR = windows_sys::core::w!(\"SysTreeView32\");\npub type WINDOWPARTS = i32;\npub type WINDOWTHEMEATTRIBUTETYPE = i32;\npub const WIZ_BODYCX: u32 = 184u32;\npub const WIZ_BODYX: u32 = 92u32;\npub const WIZ_CXBMP: u32 = 80u32;\npub const WIZ_CXDLG: u32 = 276u32;\npub const WIZ_CYDLG: u32 = 140u32;\npub const WMN_FIRST: u32 = 4294966296u32;\npub const WMN_LAST: u32 = 4294966096u32;\npub const WM_CTLCOLOR: u32 = 25u32;\npub const WM_MOUSEHOVER: u32 = 673u32;\npub const WM_MOUSELEAVE: u32 = 675u32;\npub type WORD_BREAK_ACTION = i32;\npub const WP_BORDER: WINDOWPARTS = 39i32;\npub const WP_CAPTION: WINDOWPARTS = 1i32;\npub const WP_CAPTIONSIZINGTEMPLATE: WINDOWPARTS = 30i32;\npub const WP_CLOSEBUTTON: WINDOWPARTS = 18i32;\npub const WP_DIALOG: WINDOWPARTS = 29i32;\npub const WP_FRAME: WINDOWPARTS = 38i32;\npub const WP_FRAMEBOTTOM: WINDOWPARTS = 9i32;\npub const WP_FRAMEBOTTOMSIZINGTEMPLATE: WINDOWPARTS = 36i32;\npub const WP_FRAMELEFT: WINDOWPARTS = 7i32;\npub const WP_FRAMELEFTSIZINGTEMPLATE: WINDOWPARTS = 32i32;\npub const WP_FRAMERIGHT: WINDOWPARTS = 8i32;\npub const WP_FRAMERIGHTSIZINGTEMPLATE: WINDOWPARTS = 34i32;\npub const WP_HELPBUTTON: WINDOWPARTS = 23i32;\npub const WP_HORZSCROLL: WINDOWPARTS = 25i32;\npub const WP_HORZTHUMB: WINDOWPARTS = 26i32;\npub const WP_MAXBUTTON: WINDOWPARTS = 17i32;\npub const WP_MAXCAPTION: WINDOWPARTS = 5i32;\npub const WP_MDICLOSEBUTTON: WINDOWPARTS = 20i32;\npub const WP_MDIHELPBUTTON: WINDOWPARTS = 24i32;\npub const WP_MDIMINBUTTON: WINDOWPARTS = 16i32;\npub const WP_MDIRESTOREBUTTON: WINDOWPARTS = 22i32;\npub const WP_MDISYSBUTTON: WINDOWPARTS = 14i32;\npub const WP_MINBUTTON: WINDOWPARTS = 15i32;\npub const WP_MINCAPTION: WINDOWPARTS = 3i32;\npub const WP_RESTOREBUTTON: WINDOWPARTS = 21i32;\npub const WP_SMALLCAPTION: WINDOWPARTS = 2i32;\npub const WP_SMALLCAPTIONSIZINGTEMPLATE: WINDOWPARTS = 31i32;\npub const WP_SMALLCLOSEBUTTON: WINDOWPARTS = 19i32;\npub const WP_SMALLFRAMEBOTTOM: WINDOWPARTS = 12i32;\npub const WP_SMALLFRAMEBOTTOMSIZINGTEMPLATE: WINDOWPARTS = 37i32;\npub const WP_SMALLFRAMELEFT: WINDOWPARTS = 10i32;\npub const WP_SMALLFRAMELEFTSIZINGTEMPLATE: WINDOWPARTS = 33i32;\npub const WP_SMALLFRAMERIGHT: WINDOWPARTS = 11i32;\npub const WP_SMALLFRAMERIGHTSIZINGTEMPLATE: WINDOWPARTS = 35i32;\npub const WP_SMALLMAXCAPTION: WINDOWPARTS = 6i32;\npub const WP_SMALLMINCAPTION: WINDOWPARTS = 4i32;\npub const WP_SYSBUTTON: WINDOWPARTS = 13i32;\npub const WP_VERTSCROLL: WINDOWPARTS = 27i32;\npub const WP_VERTTHUMB: WINDOWPARTS = 28i32;\npub type WRENCHSTATES = i32;\npub type WSB_PROP = i32;\npub const WSB_PROP_CXHSCROLL: WSB_PROP = 2i32;\npub const WSB_PROP_CXHTHUMB: WSB_PROP = 16i32;\npub const WSB_PROP_CXVSCROLL: WSB_PROP = 8i32;\npub const WSB_PROP_CYHSCROLL: WSB_PROP = 4i32;\npub const WSB_PROP_CYVSCROLL: WSB_PROP = 1i32;\npub const WSB_PROP_CYVTHUMB: WSB_PROP = 32i32;\npub const WSB_PROP_HBKGCOLOR: WSB_PROP = 128i32;\npub const WSB_PROP_HSTYLE: WSB_PROP = 512i32;\npub const WSB_PROP_MASK: i32 = 4095i32;\npub const WSB_PROP_PALETTE: WSB_PROP = 2048i32;\npub const WSB_PROP_VBKGCOLOR: WSB_PROP = 64i32;\npub const WSB_PROP_VSTYLE: WSB_PROP = 256i32;\npub const WSB_PROP_WINSTYLE: WSB_PROP = 1024i32;\npub const WTA_NONCLIENT: WINDOWTHEMEATTRIBUTETYPE = 1i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct WTA_OPTIONS {\n    pub dwFlags: u32,\n    pub dwMask: u32,\n}\npub const WTNCA_NODRAWCAPTION: u32 = 1u32;\npub const WTNCA_NODRAWICON: u32 = 2u32;\npub const WTNCA_NOMIRRORHELP: u32 = 8u32;\npub const WTNCA_NOSYSMENU: u32 = 4u32;\npub type _LI_METRIC = i32;\npub const chx1: u32 = 1040u32;\npub const chx10: u32 = 1049u32;\npub const chx11: u32 = 1050u32;\npub const chx12: u32 = 1051u32;\npub const chx13: u32 = 1052u32;\npub const chx14: u32 = 1053u32;\npub const chx15: u32 = 1054u32;\npub const chx16: u32 = 1055u32;\npub const chx2: u32 = 1041u32;\npub const chx3: u32 = 1042u32;\npub const chx4: u32 = 1043u32;\npub const chx5: u32 = 1044u32;\npub const chx6: u32 = 1045u32;\npub const chx7: u32 = 1046u32;\npub const chx8: u32 = 1047u32;\npub const chx9: u32 = 1048u32;\npub const cmb1: u32 = 1136u32;\npub const cmb10: u32 = 1145u32;\npub const cmb11: u32 = 1146u32;\npub const cmb12: u32 = 1147u32;\npub const cmb13: u32 = 1148u32;\npub const cmb14: u32 = 1149u32;\npub const cmb15: u32 = 1150u32;\npub const cmb16: u32 = 1151u32;\npub const cmb2: u32 = 1137u32;\npub const cmb3: u32 = 1138u32;\npub const cmb4: u32 = 1139u32;\npub const cmb5: u32 = 1140u32;\npub const cmb6: u32 = 1141u32;\npub const cmb7: u32 = 1142u32;\npub const cmb8: u32 = 1143u32;\npub const cmb9: u32 = 1144u32;\npub const ctl1: u32 = 1184u32;\npub const ctlFirst: u32 = 1024u32;\npub const ctlLast: u32 = 1279u32;\npub const edt1: u32 = 1152u32;\npub const edt10: u32 = 1161u32;\npub const edt11: u32 = 1162u32;\npub const edt12: u32 = 1163u32;\npub const edt13: u32 = 1164u32;\npub const edt14: u32 = 1165u32;\npub const edt15: u32 = 1166u32;\npub const edt16: u32 = 1167u32;\npub const edt2: u32 = 1153u32;\npub const edt3: u32 = 1154u32;\npub const edt4: u32 = 1155u32;\npub const edt5: u32 = 1156u32;\npub const edt6: u32 = 1157u32;\npub const edt7: u32 = 1158u32;\npub const edt8: u32 = 1159u32;\npub const edt9: u32 = 1160u32;\npub const frm1: u32 = 1076u32;\npub const frm2: u32 = 1077u32;\npub const frm3: u32 = 1078u32;\npub const frm4: u32 = 1079u32;\npub const grp1: u32 = 1072u32;\npub const grp2: u32 = 1073u32;\npub const grp3: u32 = 1074u32;\npub const grp4: u32 = 1075u32;\npub const ico1: u32 = 1084u32;\npub const ico2: u32 = 1085u32;\npub const ico3: u32 = 1086u32;\npub const ico4: u32 = 1087u32;\npub const lst1: u32 = 1120u32;\npub const lst10: u32 = 1129u32;\npub const lst11: u32 = 1130u32;\npub const lst12: u32 = 1131u32;\npub const lst13: u32 = 1132u32;\npub const lst14: u32 = 1133u32;\npub const lst15: u32 = 1134u32;\npub const lst16: u32 = 1135u32;\npub const lst2: u32 = 1121u32;\npub const lst3: u32 = 1122u32;\npub const lst4: u32 = 1123u32;\npub const lst5: u32 = 1124u32;\npub const lst6: u32 = 1125u32;\npub const lst7: u32 = 1126u32;\npub const lst8: u32 = 1127u32;\npub const lst9: u32 = 1128u32;\npub const psh1: u32 = 1024u32;\npub const psh10: u32 = 1033u32;\npub const psh11: u32 = 1034u32;\npub const psh12: u32 = 1035u32;\npub const psh13: u32 = 1036u32;\npub const psh14: u32 = 1037u32;\npub const psh15: u32 = 1038u32;\npub const psh16: u32 = 1039u32;\npub const psh2: u32 = 1025u32;\npub const psh3: u32 = 1026u32;\npub const psh4: u32 = 1027u32;\npub const psh5: u32 = 1028u32;\npub const psh6: u32 = 1029u32;\npub const psh7: u32 = 1030u32;\npub const psh8: u32 = 1031u32;\npub const psh9: u32 = 1032u32;\npub const pshHelp: u32 = 1038u32;\npub const rad1: u32 = 1056u32;\npub const rad10: u32 = 1065u32;\npub const rad11: u32 = 1066u32;\npub const rad12: u32 = 1067u32;\npub const rad13: u32 = 1068u32;\npub const rad14: u32 = 1069u32;\npub const rad15: u32 = 1070u32;\npub const rad16: u32 = 1071u32;\npub const rad2: u32 = 1057u32;\npub const rad3: u32 = 1058u32;\npub const rad4: u32 = 1059u32;\npub const rad5: u32 = 1060u32;\npub const rad6: u32 = 1061u32;\npub const rad7: u32 = 1062u32;\npub const rad8: u32 = 1063u32;\npub const rad9: u32 = 1064u32;\npub const rct1: u32 = 1080u32;\npub const rct2: u32 = 1081u32;\npub const rct3: u32 = 1082u32;\npub const rct4: u32 = 1083u32;\npub const scr1: u32 = 1168u32;\npub const scr2: u32 = 1169u32;\npub const scr3: u32 = 1170u32;\npub const scr4: u32 = 1171u32;\npub const scr5: u32 = 1172u32;\npub const scr6: u32 = 1173u32;\npub const scr7: u32 = 1174u32;\npub const scr8: u32 = 1175u32;\npub const stc1: u32 = 1088u32;\npub const stc10: u32 = 1097u32;\npub const stc11: u32 = 1098u32;\npub const stc12: u32 = 1099u32;\npub const stc13: u32 = 1100u32;\npub const stc14: u32 = 1101u32;\npub const stc15: u32 = 1102u32;\npub const stc16: u32 = 1103u32;\npub const stc17: u32 = 1104u32;\npub const stc18: u32 = 1105u32;\npub const stc19: u32 = 1106u32;\npub const stc2: u32 = 1089u32;\npub const stc20: u32 = 1107u32;\npub const stc21: u32 = 1108u32;\npub const stc22: u32 = 1109u32;\npub const stc23: u32 = 1110u32;\npub const stc24: u32 = 1111u32;\npub const stc25: u32 = 1112u32;\npub const stc26: u32 = 1113u32;\npub const stc27: u32 = 1114u32;\npub const stc28: u32 = 1115u32;\npub const stc29: u32 = 1116u32;\npub const stc3: u32 = 1090u32;\npub const stc30: u32 = 1117u32;\npub const stc31: u32 = 1118u32;\npub const stc32: u32 = 1119u32;\npub const stc4: u32 = 1091u32;\npub const stc5: u32 = 1092u32;\npub const stc6: u32 = 1093u32;\npub const stc7: u32 = 1094u32;\npub const stc8: u32 = 1095u32;\npub const stc9: u32 = 1096u32;\n"
    },
    {
      "package": "windows-sys@0.61.2",
      "sourcePath": "src/Windows/Win32/UI/Input/Ime/mod.rs",
      "sha256": "dbf8bb18b181547b2a16acdc6c8e135e765e6155bf3a600a1280e9539320618b",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "windows_link::link!(\"imm32.dll\" \"system\" fn ImmAssociateContext(param0 : super::super::super::Foundation:: HWND, param1 : HIMC) -> HIMC);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmAssociateContextEx(param0 : super::super::super::Foundation:: HWND, param1 : HIMC, param2 : u32) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmConfigureIMEA(param0 : super::KeyboardAndMouse:: HKL, param1 : super::super::super::Foundation:: HWND, param2 : u32, param3 : *mut core::ffi::c_void) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmConfigureIMEW(param0 : super::KeyboardAndMouse:: HKL, param1 : super::super::super::Foundation:: HWND, param2 : u32, param3 : *mut core::ffi::c_void) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmCreateContext() -> HIMC);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmCreateIMCC(param0 : u32) -> HIMCC);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmCreateSoftKeyboard(param0 : u32, param1 : super::super::super::Foundation:: HWND, param2 : i32, param3 : i32) -> super::super::super::Foundation:: HWND);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmDestroyContext(param0 : HIMC) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmDestroyIMCC(param0 : HIMCC) -> HIMCC);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmDestroySoftKeyboard(param0 : super::super::super::Foundation:: HWND) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmDisableIME(param0 : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmDisableLegacyIME() -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmDisableTextFrameService(idthread : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmEnumInputContext(idthread : u32, lpfn : IMCENUMPROC, lparam : super::super::super::Foundation:: LPARAM) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmEnumRegisterWordA(param0 : super::KeyboardAndMouse:: HKL, param1 : REGISTERWORDENUMPROCA, lpszreading : windows_sys::core::PCSTR, param3 : u32, lpszregister : windows_sys::core::PCSTR, param5 : *mut core::ffi::c_void) -> u32);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmEnumRegisterWordW(param0 : super::KeyboardAndMouse:: HKL, param1 : REGISTERWORDENUMPROCW, lpszreading : windows_sys::core::PCWSTR, param3 : u32, lpszregister : windows_sys::core::PCWSTR, param5 : *mut core::ffi::c_void) -> u32);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmEscapeA(param0 : super::KeyboardAndMouse:: HKL, param1 : HIMC, param2 : IME_ESCAPE, param3 : *mut core::ffi::c_void) -> super::super::super::Foundation:: LRESULT);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmEscapeW(param0 : super::KeyboardAndMouse:: HKL, param1 : HIMC, param2 : IME_ESCAPE, param3 : *mut core::ffi::c_void) -> super::super::super::Foundation:: LRESULT);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGenerateMessage(param0 : HIMC) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetCandidateListA(param0 : HIMC, deindex : u32, lpcandlist : *mut CANDIDATELIST, dwbuflen : u32) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetCandidateListCountA(param0 : HIMC, lpdwlistcount : *mut u32) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetCandidateListCountW(param0 : HIMC, lpdwlistcount : *mut u32) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetCandidateListW(param0 : HIMC, deindex : u32, lpcandlist : *mut CANDIDATELIST, dwbuflen : u32) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetCandidateWindow(param0 : HIMC, param1 : u32, lpcandidate : *mut CANDIDATEFORM) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetCompositionFontA(param0 : HIMC, lplf : *mut super::super::super::Graphics::Gdi:: LOGFONTA) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetCompositionFontW(param0 : HIMC, lplf : *mut super::super::super::Graphics::Gdi:: LOGFONTW) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetCompositionStringA(param0 : HIMC, param1 : IME_COMPOSITION_STRING, lpbuf : *mut core::ffi::c_void, dwbuflen : u32) -> i32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetCompositionStringW(param0 : HIMC, param1 : IME_COMPOSITION_STRING, lpbuf : *mut core::ffi::c_void, dwbuflen : u32) -> i32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetCompositionWindow(param0 : HIMC, lpcompform : *mut COMPOSITIONFORM) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetContext(param0 : super::super::super::Foundation:: HWND) -> HIMC);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetConversionListA(param0 : super::KeyboardAndMouse:: HKL, param1 : HIMC, lpsrc : windows_sys::core::PCSTR, lpdst : *mut CANDIDATELIST, dwbuflen : u32, uflag : GET_CONVERSION_LIST_FLAG) -> u32);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetConversionListW(param0 : super::KeyboardAndMouse:: HKL, param1 : HIMC, lpsrc : windows_sys::core::PCWSTR, lpdst : *mut CANDIDATELIST, dwbuflen : u32, uflag : GET_CONVERSION_LIST_FLAG) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetConversionStatus(param0 : HIMC, lpfdwconversion : *mut IME_CONVERSION_MODE, lpfdwsentence : *mut IME_SENTENCE_MODE) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetDefaultIMEWnd(param0 : super::super::super::Foundation:: HWND) -> super::super::super::Foundation:: HWND);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetDescriptionA(param0 : super::KeyboardAndMouse:: HKL, lpszdescription : windows_sys::core::PSTR, ubuflen : u32) -> u32);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetDescriptionW(param0 : super::KeyboardAndMouse:: HKL, lpszdescription : windows_sys::core::PWSTR, ubuflen : u32) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetGuideLineA(param0 : HIMC, dwindex : GET_GUIDE_LINE_TYPE, lpbuf : windows_sys::core::PSTR, dwbuflen : u32) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetGuideLineW(param0 : HIMC, dwindex : GET_GUIDE_LINE_TYPE, lpbuf : windows_sys::core::PWSTR, dwbuflen : u32) -> u32);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetHotKey(param0 : u32, lpumodifiers : *mut u32, lpuvkey : *mut u32, phkl : *mut super::KeyboardAndMouse:: HKL) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetIMCCLockCount(param0 : HIMCC) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetIMCCSize(param0 : HIMCC) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetIMCLockCount(param0 : HIMC) -> u32);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetIMEFileNameA(param0 : super::KeyboardAndMouse:: HKL, lpszfilename : windows_sys::core::PSTR, ubuflen : u32) -> u32);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetIMEFileNameW(param0 : super::KeyboardAndMouse:: HKL, lpszfilename : windows_sys::core::PWSTR, ubuflen : u32) -> u32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetImeMenuItemsA(param0 : HIMC, param1 : u32, param2 : u32, lpimeparentmenu : *mut IMEMENUITEMINFOA, lpimemenu : *mut IMEMENUITEMINFOA, dwsize : u32) -> u32);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetImeMenuItemsW(param0 : HIMC, param1 : u32, param2 : u32, lpimeparentmenu : *mut IMEMENUITEMINFOW, lpimemenu : *mut IMEMENUITEMINFOW, dwsize : u32) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetOpenStatus(param0 : HIMC) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetProperty(param0 : super::KeyboardAndMouse:: HKL, param1 : u32) -> u32);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetRegisterWordStyleA(param0 : super::KeyboardAndMouse:: HKL, nitem : u32, lpstylebuf : *mut STYLEBUFA) -> u32);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetRegisterWordStyleW(param0 : super::KeyboardAndMouse:: HKL, nitem : u32, lpstylebuf : *mut STYLEBUFW) -> u32);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetStatusWindowPos(param0 : HIMC, lpptpos : *mut super::super::super::Foundation:: POINT) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmGetVirtualKey(param0 : super::super::super::Foundation:: HWND) -> u32);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmInstallIMEA(lpszimefilename : windows_sys::core::PCSTR, lpszlayouttext : windows_sys::core::PCSTR) -> super::KeyboardAndMouse:: HKL);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmInstallIMEW(lpszimefilename : windows_sys::core::PCWSTR, lpszlayouttext : windows_sys::core::PCWSTR) -> super::KeyboardAndMouse:: HKL);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmIsIME(param0 : super::KeyboardAndMouse:: HKL) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmIsUIMessageA(param0 : super::super::super::Foundation:: HWND, param1 : u32, param2 : super::super::super::Foundation:: WPARAM, param3 : super::super::super::Foundation:: LPARAM) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmIsUIMessageW(param0 : super::super::super::Foundation:: HWND, param1 : u32, param2 : super::super::super::Foundation:: WPARAM, param3 : super::super::super::Foundation:: LPARAM) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmLockIMC(param0 : HIMC) -> *mut INPUTCONTEXT);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmLockIMCC(param0 : HIMCC) -> *mut core::ffi::c_void);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmNotifyIME(param0 : HIMC, dwaction : NOTIFY_IME_ACTION, dwindex : NOTIFY_IME_INDEX, dwvalue : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmReSizeIMCC(param0 : HIMCC, param1 : u32) -> HIMCC);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmRegisterWordA(param0 : super::KeyboardAndMouse:: HKL, lpszreading : windows_sys::core::PCSTR, param2 : u32, lpszregister : windows_sys::core::PCSTR) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmRegisterWordW(param0 : super::KeyboardAndMouse:: HKL, lpszreading : windows_sys::core::PCWSTR, param2 : u32, lpszregister : windows_sys::core::PCWSTR) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmReleaseContext(param0 : super::super::super::Foundation:: HWND, param1 : HIMC) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmRequestMessageA(param0 : HIMC, param1 : super::super::super::Foundation:: WPARAM, param2 : super::super::super::Foundation:: LPARAM) -> super::super::super::Foundation:: LRESULT);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmRequestMessageW(param0 : HIMC, param1 : super::super::super::Foundation:: WPARAM, param2 : super::super::super::Foundation:: LPARAM) -> super::super::super::Foundation:: LRESULT);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSetCandidateWindow(param0 : HIMC, lpcandidate : *const CANDIDATEFORM) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSetCompositionFontA(param0 : HIMC, lplf : *const super::super::super::Graphics::Gdi:: LOGFONTA) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSetCompositionFontW(param0 : HIMC, lplf : *const super::super::super::Graphics::Gdi:: LOGFONTW) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSetCompositionStringA(param0 : HIMC, dwindex : SET_COMPOSITION_STRING_TYPE, lpcomp : *const core::ffi::c_void, dwcomplen : u32, lpread : *const core::ffi::c_void, dwreadlen : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSetCompositionStringW(param0 : HIMC, dwindex : SET_COMPOSITION_STRING_TYPE, lpcomp : *const core::ffi::c_void, dwcomplen : u32, lpread : *const core::ffi::c_void, dwreadlen : u32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSetCompositionWindow(param0 : HIMC, lpcompform : *const COMPOSITIONFORM) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSetConversionStatus(param0 : HIMC, param1 : IME_CONVERSION_MODE, param2 : IME_SENTENCE_MODE) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSetHotKey(param0 : u32, param1 : u32, param2 : u32, param3 : super::KeyboardAndMouse:: HKL) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSetOpenStatus(param0 : HIMC, param1 : windows_sys::core::BOOL) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSetStatusWindowPos(param0 : HIMC, lpptpos : *const super::super::super::Foundation:: POINT) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmShowSoftKeyboard(param0 : super::super::super::Foundation:: HWND, param1 : i32) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmSimulateHotKey(param0 : super::super::super::Foundation:: HWND, param1 : IME_HOTKEY_IDENTIFIER) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmUnlockIMC(param0 : HIMC) -> windows_sys::core::BOOL);\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmUnlockIMCC(param0 : HIMCC) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmUnregisterWordA(param0 : super::KeyboardAndMouse:: HKL, lpszreading : windows_sys::core::PCSTR, param2 : u32, lpszunregister : windows_sys::core::PCSTR) -> windows_sys::core::BOOL);\n#[cfg(feature = \"Win32_UI_Input_KeyboardAndMouse\")]\nwindows_link::link!(\"imm32.dll\" \"system\" fn ImmUnregisterWordW(param0 : super::KeyboardAndMouse:: HKL, lpszreading : windows_sys::core::PCWSTR, param2 : u32, lpszunregister : windows_sys::core::PCWSTR) -> windows_sys::core::BOOL);\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct APPLETIDLIST {\n    pub count: i32,\n    pub pIIDList: *mut windows_sys::core::GUID,\n}\nimpl Default for APPLETIDLIST {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct APPLYCANDEXPARAM {\n    pub dwSize: u32,\n    pub lpwstrDisplay: windows_sys::core::PWSTR,\n    pub lpwstrReading: windows_sys::core::PWSTR,\n    pub dwReserved: u32,\n}\nimpl Default for APPLYCANDEXPARAM {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const ATTR_CONVERTED: u32 = 2u32;\npub const ATTR_FIXEDCONVERTED: u32 = 5u32;\npub const ATTR_INPUT: u32 = 0u32;\npub const ATTR_INPUT_ERROR: u32 = 4u32;\npub const ATTR_TARGET_CONVERTED: u32 = 1u32;\npub const ATTR_TARGET_NOTCONVERTED: u32 = 3u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct CANDIDATEFORM {\n    pub dwIndex: u32,\n    pub dwStyle: u32,\n    pub ptCurrentPos: super::super::super::Foundation::POINT,\n    pub rcArea: super::super::super::Foundation::RECT,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CANDIDATEINFO {\n    pub dwSize: u32,\n    pub dwCount: u32,\n    pub dwOffset: [u32; 32],\n    pub dwPrivateSize: u32,\n    pub dwPrivateOffset: u32,\n}\nimpl Default for CANDIDATEINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct CANDIDATELIST {\n    pub dwSize: u32,\n    pub dwStyle: u32,\n    pub dwCount: u32,\n    pub dwSelection: u32,\n    pub dwPageStart: u32,\n    pub dwPageSize: u32,\n    pub dwOffset: [u32; 1],\n}\nimpl Default for CANDIDATELIST {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const CATID_MSIME_IImePadApplet: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7566cad1_4ec9_4478_9fe9_8ed766619edf);\npub const CATID_MSIME_IImePadApplet1000: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xe081e1d6_2389_43cb_b66f_609f823d9f9c);\npub const CATID_MSIME_IImePadApplet1200: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xa47fb5fc_7d15_4223_a789_b781bf9ae667);\npub const CATID_MSIME_IImePadApplet900: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0xfaae51bf_5e5b_4a1d_8de1_17c1d9e1728d);\npub const CATID_MSIME_IImePadApplet_VER7: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4a0f8e31_c3ee_11d1_afef_00805f0c8b6d);\npub const CATID_MSIME_IImePadApplet_VER80: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x56f7a792_fef1_11d3_8463_00c04f7a06e5);\npub const CATID_MSIME_IImePadApplet_VER81: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x656520b0_bb88_11d4_84c0_00c04f7a06e5);\npub const CActiveIMM: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4955dd33_b159_11d0_8fcf_00aa006bcc59);\npub const CFS_CANDIDATEPOS: u32 = 64u32;\npub const CFS_DEFAULT: u32 = 0u32;\npub const CFS_EXCLUDE: u32 = 128u32;\npub const CFS_FORCE_POSITION: u32 = 32u32;\npub const CFS_POINT: u32 = 2u32;\npub const CFS_RECT: u32 = 1u32;\npub const CHARINFO_APPLETID_MASK: u32 = 4278190080u32;\npub const CHARINFO_CHARID_MASK: u32 = 65535u32;\npub const CHARINFO_FEID_MASK: u32 = 15728640u32;\npub const CLSID_ImePlugInDictDictionaryList_CHS: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x7bf0129b_5bef_4de4_9b0b_5edb66ac2fa6);\npub const CLSID_ImePlugInDictDictionaryList_JPN: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x4fe2776b_b0f9_4396_b5fc_e9d4cf1ec195);\npub const CLSID_VERSION_DEPENDENT_MSIME_JAPANESE: windows_sys::core::GUID = windows_sys::core::GUID::from_u128(0x6a91029e_aa49_471b_aee7_7d332785660d);\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct COMPOSITIONFORM {\n    pub dwStyle: u32,\n    pub ptCurrentPos: super::super::super::Foundation::POINT,\n    pub rcArea: super::super::super::Foundation::RECT,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct COMPOSITIONSTRING {\n    pub dwSize: u32,\n    pub dwCompReadAttrLen: u32,\n    pub dwCompReadAttrOffset: u32,\n    pub dwCompReadClauseLen: u32,\n    pub dwCompReadClauseOffset: u32,\n    pub dwCompReadStrLen: u32,\n    pub dwCompReadStrOffset: u32,\n    pub dwCompAttrLen: u32,\n    pub dwCompAttrOffset: u32,\n    pub dwCompClauseLen: u32,\n    pub dwCompClauseOffset: u32,\n    pub dwCompStrLen: u32,\n    pub dwCompStrOffset: u32,\n    pub dwCursorPos: u32,\n    pub dwDeltaStart: u32,\n    pub dwResultReadClauseLen: u32,\n    pub dwResultReadClauseOffset: u32,\n    pub dwResultReadStrLen: u32,\n    pub dwResultReadStrOffset: u32,\n    pub dwResultClauseLen: u32,\n    pub dwResultClauseOffset: u32,\n    pub dwResultStrLen: u32,\n    pub dwResultStrOffset: u32,\n    pub dwPrivateSize: u32,\n    pub dwPrivateOffset: u32,\n}\npub const CPS_CANCEL: NOTIFY_IME_INDEX = 4u32;\npub const CPS_COMPLETE: NOTIFY_IME_INDEX = 1u32;\npub const CPS_CONVERT: NOTIFY_IME_INDEX = 2u32;\npub const CPS_REVERT: NOTIFY_IME_INDEX = 3u32;\npub const CS_INSERTCHAR: u32 = 8192u32;\npub const CS_NOMOVECARET: u32 = 16384u32;\npub const E_LARGEINPUT: u32 = 51u32;\npub const E_NOCAND: u32 = 48u32;\npub const E_NOTENOUGH_BUFFER: u32 = 49u32;\npub const E_NOTENOUGH_WDD: u32 = 50u32;\npub const FEID_CHINESE_HONGKONG: u32 = 3u32;\npub const FEID_CHINESE_SIMPLIFIED: u32 = 2u32;\npub const FEID_CHINESE_SINGAPORE: u32 = 4u32;\npub const FEID_CHINESE_TRADITIONAL: u32 = 1u32;\npub const FEID_JAPANESE: u32 = 5u32;\npub const FEID_KOREAN: u32 = 6u32;\npub const FEID_KOREAN_JOHAB: u32 = 7u32;\npub const FEID_NONE: u32 = 0u32;\npub const FELANG_CLMN_FIXD: u32 = 32u32;\npub const FELANG_CLMN_FIXR: u32 = 16u32;\npub const FELANG_CLMN_NOPBREAK: u32 = 8u32;\npub const FELANG_CLMN_NOWBREAK: u32 = 2u32;\npub const FELANG_CLMN_PBREAK: u32 = 4u32;\npub const FELANG_CLMN_WBREAK: u32 = 1u32;\npub const FELANG_CMODE_AUTOMATIC: u32 = 134217728u32;\npub const FELANG_CMODE_BESTFIRST: u32 = 16384u32;\npub const FELANG_CMODE_BOPOMOFO: u32 = 64u32;\npub const FELANG_CMODE_CONVERSATION: u32 = 536870912u32;\npub const FELANG_CMODE_FULLWIDTHOUT: u32 = 32u32;\npub const FELANG_CMODE_HALFWIDTHOUT: u32 = 16u32;\npub const FELANG_CMODE_HANGUL: u32 = 128u32;\npub const FELANG_CMODE_HIRAGANAOUT: u32 = 0u32;\npub const FELANG_CMODE_KATAKANAOUT: u32 = 8u32;\npub const FELANG_CMODE_MERGECAND: u32 = 4096u32;\npub const FELANG_CMODE_MONORUBY: u32 = 2u32;\npub const FELANG_CMODE_NAME: u32 = 268435456u32;\npub const FELANG_CMODE_NOINVISIBLECHAR: u32 = 1073741824u32;\npub const FELANG_CMODE_NONE: u32 = 16777216u32;\npub const FELANG_CMODE_NOPRUNING: u32 = 4u32;\npub const FELANG_CMODE_PHRASEPREDICT: u32 = 268435456u32;\npub const FELANG_CMODE_PINYIN: u32 = 256u32;\npub const FELANG_CMODE_PLAURALCLAUSE: u32 = 33554432u32;\npub const FELANG_CMODE_PRECONV: u32 = 512u32;\npub const FELANG_CMODE_RADICAL: u32 = 1024u32;\npub const FELANG_CMODE_ROMAN: u32 = 8192u32;\npub const FELANG_CMODE_SINGLECONVERT: u32 = 67108864u32;\npub const FELANG_CMODE_UNKNOWNREADING: u32 = 2048u32;\npub const FELANG_CMODE_USENOREVWORDS: u32 = 32768u32;\npub const FELANG_INVALD_PO: u32 = 65535u32;\npub const FELANG_REQ_CONV: u32 = 65536u32;\npub const FELANG_REQ_RECONV: u32 = 131072u32;\npub const FELANG_REQ_REV: u32 = 196608u32;\npub const FID_MSIME_KMS_DEL_KEYLIST: u32 = 4u32;\npub const FID_MSIME_KMS_FUNCDESC: u32 = 9u32;\npub const FID_MSIME_KMS_GETMAP: u32 = 6u32;\npub const FID_MSIME_KMS_GETMAPFAST: u32 = 11u32;\npub const FID_MSIME_KMS_GETMAPSEAMLESS: u32 = 10u32;\npub const FID_MSIME_KMS_INIT: u32 = 2u32;\npub const FID_MSIME_KMS_INVOKE: u32 = 7u32;\npub const FID_MSIME_KMS_NOTIFY: u32 = 5u32;\npub const FID_MSIME_KMS_SETMAP: u32 = 8u32;\npub const FID_MSIME_KMS_TERM: u32 = 3u32;\npub const FID_MSIME_KMS_VERSION: u32 = 1u32;\npub const FID_MSIME_VERSION: u32 = 0u32;\npub const FID_RECONVERT_VERSION: u32 = 268435456u32;\npub const GCL_CONVERSION: GET_CONVERSION_LIST_FLAG = 1u32;\npub const GCL_REVERSECONVERSION: GET_CONVERSION_LIST_FLAG = 2u32;\npub const GCL_REVERSE_LENGTH: GET_CONVERSION_LIST_FLAG = 3u32;\npub const GCSEX_CANCELRECONVERT: u32 = 268435456u32;\npub const GCS_COMPATTR: IME_COMPOSITION_STRING = 16u32;\npub const GCS_COMPCLAUSE: IME_COMPOSITION_STRING = 32u32;\npub const GCS_COMPREADATTR: IME_COMPOSITION_STRING = 2u32;\npub const GCS_COMPREADCLAUSE: IME_COMPOSITION_STRING = 4u32;\npub const GCS_COMPREADSTR: IME_COMPOSITION_STRING = 1u32;\npub const GCS_COMPSTR: IME_COMPOSITION_STRING = 8u32;\npub const GCS_CURSORPOS: IME_COMPOSITION_STRING = 128u32;\npub const GCS_DELTASTART: IME_COMPOSITION_STRING = 256u32;\npub const GCS_RESULTCLAUSE: IME_COMPOSITION_STRING = 4096u32;\npub const GCS_RESULTREADCLAUSE: IME_COMPOSITION_STRING = 1024u32;\npub const GCS_RESULTREADSTR: IME_COMPOSITION_STRING = 512u32;\npub const GCS_RESULTSTR: IME_COMPOSITION_STRING = 2048u32;\npub type GET_CONVERSION_LIST_FLAG = u32;\npub type GET_GUIDE_LINE_TYPE = u32;\npub const GGL_INDEX: GET_GUIDE_LINE_TYPE = 2u32;\npub const GGL_LEVEL: GET_GUIDE_LINE_TYPE = 1u32;\npub const GGL_PRIVATE: GET_GUIDE_LINE_TYPE = 4u32;\npub const GGL_STRING: GET_GUIDE_LINE_TYPE = 3u32;\npub const GL_ID_CANNOTSAVE: u32 = 17u32;\npub const GL_ID_CHOOSECANDIDATE: u32 = 40u32;\npub const GL_ID_INPUTCODE: u32 = 38u32;\npub const GL_ID_INPUTRADICAL: u32 = 37u32;\npub const GL_ID_INPUTREADING: u32 = 36u32;\npub const GL_ID_INPUTSYMBOL: u32 = 39u32;\npub const GL_ID_NOCONVERT: u32 = 32u32;\npub const GL_ID_NODICTIONARY: u32 = 16u32;\npub const GL_ID_NOMODULE: u32 = 1u32;\npub const GL_ID_PRIVATE_FIRST: u32 = 32768u32;\npub const GL_ID_PRIVATE_LAST: u32 = 65535u32;\npub const GL_ID_READINGCONFLICT: u32 = 35u32;\npub const GL_ID_REVERSECONVERSION: u32 = 41u32;\npub const GL_ID_TOOMANYSTROKE: u32 = 34u32;\npub const GL_ID_TYPINGERROR: u32 = 33u32;\npub const GL_ID_UNKNOWN: u32 = 0u32;\npub const GL_LEVEL_ERROR: u32 = 2u32;\npub const GL_LEVEL_FATAL: u32 = 1u32;\npub const GL_LEVEL_INFORMATION: u32 = 4u32;\npub const GL_LEVEL_NOGUIDELINE: u32 = 0u32;\npub const GL_LEVEL_WARNING: u32 = 3u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct GUIDELINE {\n    pub dwSize: u32,\n    pub dwLevel: u32,\n    pub dwIndex: u32,\n    pub dwStrLen: u32,\n    pub dwStrOffset: u32,\n    pub dwPrivateSize: u32,\n    pub dwPrivateOffset: u32,\n}\npub type HIMC = *mut core::ffi::c_void;\npub type HIMCC = *mut core::ffi::c_void;\npub const IACE_CHILDREN: u32 = 1u32;\npub const IACE_DEFAULT: u32 = 16u32;\npub const IACE_IGNORENOCONTEXT: u32 = 32u32;\npub const IFEC_S_ALREADY_DEFAULT: windows_sys::core::HRESULT = 0x47400_u32 as _;\npub const IFED_ACTIVE_DICT: IMEFMT = 13i32;\npub const IFED_ATOK10: IMEFMT = 15i32;\npub const IFED_ATOK9: IMEFMT = 14i32;\npub const IFED_E_INVALID_FORMAT: windows_sys::core::HRESULT = 0x80047301_u32 as _;\npub const IFED_E_NOT_FOUND: windows_sys::core::HRESULT = 0x80047300_u32 as _;\npub const IFED_E_NOT_SUPPORTED: windows_sys::core::HRESULT = 0x80047307_u32 as _;\npub const IFED_E_NOT_USER_DIC: windows_sys::core::HRESULT = 0x80047306_u32 as _;\npub const IFED_E_NO_ENTRY: windows_sys::core::HRESULT = 0x80047304_u32 as _;\npub const IFED_E_OPEN_FAILED: windows_sys::core::HRESULT = 0x80047302_u32 as _;\npub const IFED_E_REGISTER_DISCONNECTED: windows_sys::core::HRESULT = 0x8004730B_u32 as _;\npub const IFED_E_REGISTER_FAILED: windows_sys::core::HRESULT = 0x80047305_u32 as _;\npub const IFED_E_REGISTER_ILLEGAL_POS: windows_sys::core::HRESULT = 0x80047309_u32 as _;\npub const IFED_E_REGISTER_IMPROPER_WORD: windows_sys::core::HRESULT = 0x8004730A_u32 as _;\npub const IFED_E_USER_COMMENT: windows_sys::core::HRESULT = 0x80047308_u32 as _;\npub const IFED_E_WRITE_FAILED: windows_sys::core::HRESULT = 0x80047303_u32 as _;\npub const IFED_MSIME2_BIN_SYSTEM: IMEFMT = 1i32;\npub const IFED_MSIME2_BIN_USER: IMEFMT = 2i32;\npub const IFED_MSIME2_TEXT_USER: IMEFMT = 3i32;\npub const IFED_MSIME95_BIN_SYSTEM: IMEFMT = 4i32;\npub const IFED_MSIME95_BIN_USER: IMEFMT = 5i32;\npub const IFED_MSIME95_TEXT_USER: IMEFMT = 6i32;\npub const IFED_MSIME97_BIN_SYSTEM: IMEFMT = 7i32;\npub const IFED_MSIME97_BIN_USER: IMEFMT = 8i32;\npub const IFED_MSIME97_TEXT_USER: IMEFMT = 9i32;\npub const IFED_MSIME98_BIN_SYSTEM: IMEFMT = 10i32;\npub const IFED_MSIME98_BIN_USER: IMEFMT = 11i32;\npub const IFED_MSIME98_SYSTEM_CE: IMEFMT = 20i32;\npub const IFED_MSIME98_TEXT_USER: IMEFMT = 12i32;\npub const IFED_MSIME_BIN_SYSTEM: IMEFMT = 21i32;\npub const IFED_MSIME_BIN_USER: IMEFMT = 22i32;\npub const IFED_MSIME_TEXT_USER: IMEFMT = 23i32;\npub const IFED_NEC_AI_: IMEFMT = 16i32;\npub const IFED_PIME2_BIN_STANDARD_SYSTEM: IMEFMT = 26i32;\npub const IFED_PIME2_BIN_SYSTEM: IMEFMT = 25i32;\npub const IFED_PIME2_BIN_USER: IMEFMT = 24i32;\npub const IFED_POS_ADJECTIVE: u32 = 4u32;\npub const IFED_POS_ADJECTIVE_VERB: u32 = 8u32;\npub const IFED_POS_ADNOUN: u32 = 32u32;\npub const IFED_POS_ADVERB: u32 = 16u32;\npub const IFED_POS_AFFIX: u32 = 1536u32;\npub const IFED_POS_ALL: u32 = 131071u32;\npub const IFED_POS_AUXILIARY_VERB: u32 = 32768u32;\npub const IFED_POS_CONJUNCTION: u32 = 64u32;\npub const IFED_POS_DEPENDENT: u32 = 114688u32;\npub const IFED_POS_IDIOMS: u32 = 4096u32;\npub const IFED_POS_INDEPENDENT: u32 = 255u32;\npub const IFED_POS_INFLECTIONALSUFFIX: u32 = 256u32;\npub const IFED_POS_INTERJECTION: u32 = 128u32;\npub const IFED_POS_NONE: u32 = 0u32;\npub const IFED_POS_NOUN: u32 = 1u32;\npub const IFED_POS_PARTICLE: u32 = 16384u32;\npub const IFED_POS_PREFIX: u32 = 512u32;\npub const IFED_POS_SUB_VERB: u32 = 65536u32;\npub const IFED_POS_SUFFIX: u32 = 1024u32;\npub const IFED_POS_SYMBOLS: u32 = 8192u32;\npub const IFED_POS_TANKANJI: u32 = 2048u32;\npub const IFED_POS_VERB: u32 = 2u32;\npub const IFED_REG_ALL: u32 = 7u32;\npub const IFED_REG_AUTO: u32 = 2u32;\npub const IFED_REG_DEL: IMEREG = 2i32;\npub const IFED_REG_GRAMMAR: u32 = 4u32;\npub const IFED_REG_HEAD: IMEREG = 0i32;\npub const IFED_REG_NONE: u32 = 0u32;\npub const IFED_REG_TAIL: IMEREG = 1i32;\npub const IFED_REG_USER: u32 = 1u32;\npub const IFED_REL_ALL: IMEREL = 24i32;\npub const IFED_REL_DE: IMEREL = 5i32;\npub const IFED_REL_FUKU_YOUGEN: IMEREL = 12i32;\npub const IFED_REL_GA: IMEREL = 2i32;\npub const IFED_REL_HE: IMEREL = 9i32;\npub const IFED_REL_IDEOM: IMEREL = 11i32;\npub const IFED_REL_KARA: IMEREL = 7i32;\npub const IFED_REL_KEIDOU1_YOUGEN: IMEREL = 14i32;\npub const IFED_REL_KEIDOU2_YOUGEN: IMEREL = 15i32;\npub const IFED_REL_KEIYOU_TARU_YOUGEN: IMEREL = 21i32;\npub const IFED_REL_KEIYOU_TO_YOUGEN: IMEREL = 20i32;\npub const IFED_REL_KEIYOU_YOUGEN: IMEREL = 13i32;\npub const IFED_REL_MADE: IMEREL = 8i32;\npub const IFED_REL_NI: IMEREL = 4i32;\npub const IFED_REL_NO: IMEREL = 1i32;\npub const IFED_REL_NONE: IMEREL = 0i32;\npub const IFED_REL_RENSOU: IMEREL = 19i32;\npub const IFED_REL_RENTAI_MEI: IMEREL = 18i32;\npub const IFED_REL_TAIGEN: IMEREL = 16i32;\npub const IFED_REL_TO: IMEREL = 10i32;\npub const IFED_REL_UNKNOWN1: IMEREL = 22i32;\npub const IFED_REL_UNKNOWN2: IMEREL = 23i32;\npub const IFED_REL_WO: IMEREL = 3i32;\npub const IFED_REL_YORI: IMEREL = 6i32;\npub const IFED_REL_YOUGEN: IMEREL = 17i32;\npub const IFED_SELECT_ALL: u32 = 15u32;\npub const IFED_SELECT_COMMENT: u32 = 8u32;\npub const IFED_SELECT_DISPLAY: u32 = 2u32;\npub const IFED_SELECT_NONE: u32 = 0u32;\npub const IFED_SELECT_POS: u32 = 4u32;\npub const IFED_SELECT_READING: u32 = 1u32;\npub const IFED_S_COMMENT_CHANGED: windows_sys::core::HRESULT = 0x47203_u32 as _;\npub const IFED_S_EMPTY_DICTIONARY: windows_sys::core::HRESULT = 0x47201_u32 as _;\npub const IFED_S_MORE_ENTRIES: windows_sys::core::HRESULT = 0x47200_u32 as _;\npub const IFED_S_WORD_EXISTS: windows_sys::core::HRESULT = 0x47202_u32 as _;\npub const IFED_TYPE_ALL: u32 = 31u32;\npub const IFED_TYPE_ENGLISH: u32 = 16u32;\npub const IFED_TYPE_GENERAL: u32 = 1u32;\npub const IFED_TYPE_NAMEPLACE: u32 = 2u32;\npub const IFED_TYPE_NONE: u32 = 0u32;\npub const IFED_TYPE_REVERSE: u32 = 8u32;\npub const IFED_TYPE_SPEECH: u32 = 4u32;\npub const IFED_UCT_MAX: IMEUCT = 4i32;\npub const IFED_UCT_NONE: IMEUCT = 0i32;\npub const IFED_UCT_STRING_SJIS: IMEUCT = 1i32;\npub const IFED_UCT_STRING_UNICODE: IMEUCT = 2i32;\npub const IFED_UCT_USER_DEFINED: IMEUCT = 3i32;\npub const IFED_UNKNOWN: IMEFMT = 0i32;\npub const IFED_VJE_20: IMEFMT = 19i32;\npub const IFED_WX_II: IMEFMT = 17i32;\npub const IFED_WX_III: IMEFMT = 18i32;\npub const IGIMIF_RIGHTMENU: u32 = 1u32;\npub const IGIMII_CMODE: u32 = 1u32;\npub const IGIMII_CONFIGURE: u32 = 4u32;\npub const IGIMII_HELP: u32 = 16u32;\npub const IGIMII_INPUTTOOLS: u32 = 64u32;\npub const IGIMII_OTHER: u32 = 32u32;\npub const IGIMII_SMODE: u32 = 2u32;\npub const IGIMII_TOOLS: u32 = 8u32;\npub type IMCENUMPROC = Option<unsafe extern \"system\" fn(param0: HIMC, param1: super::super::super::Foundation::LPARAM) -> windows_sys::core::BOOL>;\npub const IMC_CLOSESTATUSWINDOW: u32 = 33u32;\npub const IMC_GETCANDIDATEPOS: u32 = 7u32;\npub const IMC_GETCOMPOSITIONFONT: u32 = 9u32;\npub const IMC_GETCOMPOSITIONWINDOW: u32 = 11u32;\npub const IMC_GETSOFTKBDFONT: u32 = 17u32;\npub const IMC_GETSOFTKBDPOS: u32 = 19u32;\npub const IMC_GETSOFTKBDSUBTYPE: u32 = 21u32;\npub const IMC_GETSTATUSWINDOWPOS: u32 = 15u32;\npub const IMC_OPENSTATUSWINDOW: u32 = 34u32;\npub const IMC_SETCANDIDATEPOS: u32 = 8u32;\npub const IMC_SETCOMPOSITIONFONT: u32 = 10u32;\npub const IMC_SETCOMPOSITIONWINDOW: u32 = 12u32;\npub const IMC_SETCONVERSIONMODE: u32 = 2u32;\npub const IMC_SETOPENSTATUS: u32 = 6u32;\npub const IMC_SETSENTENCEMODE: u32 = 4u32;\npub const IMC_SETSOFTKBDDATA: u32 = 24u32;\npub const IMC_SETSOFTKBDFONT: u32 = 18u32;\npub const IMC_SETSOFTKBDPOS: u32 = 20u32;\npub const IMC_SETSOFTKBDSUBTYPE: u32 = 22u32;\npub const IMC_SETSTATUSWINDOWPOS: u32 = 16u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\n#[derive(Clone, Copy)]\npub struct IMEAPPLETCFG {\n    pub dwConfig: u32,\n    pub wchTitle: [u16; 64],\n    pub wchTitleFontFace: [u16; 32],\n    pub dwCharSet: u32,\n    pub iCategory: i32,\n    pub hIcon: super::super::WindowsAndMessaging::HICON,\n    pub langID: u16,\n    pub dummy: u16,\n    pub lReserved1: super::super::super::Foundation::LPARAM,\n}\n#[cfg(feature = \"Win32_UI_WindowsAndMessaging\")]\nimpl Default for IMEAPPLETCFG {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct IMEAPPLETUI {\n    pub hwnd: super::super::super::Foundation::HWND,\n    pub dwStyle: u32,\n    pub width: i32,\n    pub height: i32,\n    pub minWidth: i32,\n    pub minHeight: i32,\n    pub maxWidth: i32,\n    pub maxHeight: i32,\n    pub lReserved1: super::super::super::Foundation::LPARAM,\n    pub lReserved2: super::super::super::Foundation::LPARAM,\n}\nimpl Default for IMEAPPLETUI {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct IMECHARINFO {\n    pub wch: u16,\n    pub dwCharInfo: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct IMECHARPOSITION {\n    pub dwSize: u32,\n    pub dwCharPos: u32,\n    pub pt: super::super::super::Foundation::POINT,\n    pub cLineHeight: u32,\n    pub rcDocument: super::super::super::Foundation::RECT,\n}\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct IMECOMPOSITIONSTRINGINFO {\n    pub iCompStrLen: i32,\n    pub iCaretPos: i32,\n    pub iEditStart: i32,\n    pub iEditLen: i32,\n    pub iTargetStart: i32,\n    pub iTargetLen: i32,\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMEDLG {\n    pub cbIMEDLG: i32,\n    pub hwnd: super::super::super::Foundation::HWND,\n    pub lpwstrWord: windows_sys::core::PWSTR,\n    pub nTabId: i32,\n}\nimpl Default for IMEDLG {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMEDP {\n    pub wrdModifier: IMEWRD,\n    pub wrdModifiee: IMEWRD,\n    pub relID: IMEREL,\n}\nimpl Default for IMEDP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct IMEFAREASTINFO {\n    pub dwSize: u32,\n    pub dwType: u32,\n    pub dwData: [u32; 1],\n}\nimpl Default for IMEFAREASTINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const IMEFAREASTINFO_TYPE_COMMENT: u32 = 2u32;\npub const IMEFAREASTINFO_TYPE_COSTTIME: u32 = 3u32;\npub const IMEFAREASTINFO_TYPE_DEFAULT: u32 = 0u32;\npub const IMEFAREASTINFO_TYPE_READING: u32 = 1u32;\npub type IMEFMT = i32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct IMEINFO {\n    pub dwPrivateDataSize: u32,\n    pub fdwProperty: u32,\n    pub fdwConversionCaps: u32,\n    pub fdwSentenceCaps: u32,\n    pub fdwUICaps: u32,\n    pub fdwSCSCaps: u32,\n    pub fdwSelectCaps: u32,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct IMEITEM {\n    pub cbSize: i32,\n    pub iType: i32,\n    pub lpItemData: *mut core::ffi::c_void,\n}\nimpl Default for IMEITEM {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct IMEITEMCANDIDATE {\n    pub uCount: u32,\n    pub imeItem: [IMEITEM; 1],\n}\nimpl Default for IMEITEMCANDIDATE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const IMEKEYCTRLMASK_ALT: u32 = 1u32;\npub const IMEKEYCTRLMASK_CTRL: u32 = 2u32;\npub const IMEKEYCTRLMASK_SHIFT: u32 = 4u32;\npub const IMEKEYCTRL_DOWN: u32 = 0u32;\npub const IMEKEYCTRL_UP: u32 = 1u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMEKMS {\n    pub cbSize: i32,\n    pub hIMC: HIMC,\n    pub cKeyList: u32,\n    pub pKeyList: *mut IMEKMSKEY,\n}\nimpl Default for IMEKMS {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMEKMSFUNCDESC {\n    pub cbSize: i32,\n    pub idLang: u16,\n    pub dwControl: u32,\n    pub pwszDescription: [u16; 128],\n}\nimpl Default for IMEKMSFUNCDESC {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMEKMSINIT {\n    pub cbSize: i32,\n    pub hWnd: super::super::super::Foundation::HWND,\n}\nimpl Default for IMEKMSINIT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMEKMSINVK {\n    pub cbSize: i32,\n    pub hIMC: HIMC,\n    pub dwControl: u32,\n}\nimpl Default for IMEKMSINVK {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMEKMSKEY {\n    pub dwStatus: u32,\n    pub dwCompStatus: u32,\n    pub dwVKEY: u32,\n    pub Anonymous1: IMEKMSKEY_0,\n    pub Anonymous2: IMEKMSKEY_1,\n}\nimpl Default for IMEKMSKEY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union IMEKMSKEY_0 {\n    pub dwControl: u32,\n    pub dwNotUsed: u32,\n}\nimpl Default for IMEKMSKEY_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union IMEKMSKEY_1 {\n    pub pwszDscr: [u16; 31],\n    pub pwszNoUse: [u16; 31],\n}\nimpl Default for IMEKMSKEY_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMEKMSKMP {\n    pub cbSize: i32,\n    pub hIMC: HIMC,\n    pub idLang: u16,\n    pub wVKStart: u16,\n    pub wVKEnd: u16,\n    pub cKeyList: i32,\n    pub pKeyList: *mut IMEKMSKEY,\n}\nimpl Default for IMEKMSKMP {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMEKMSNTFY {\n    pub cbSize: i32,\n    pub hIMC: HIMC,\n    pub fSelect: windows_sys::core::BOOL,\n}\nimpl Default for IMEKMSNTFY {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const IMEKMS_2NDLEVEL: u32 = 4u32;\npub const IMEKMS_CANDIDATE: u32 = 6u32;\npub const IMEKMS_COMPOSITION: u32 = 1u32;\npub const IMEKMS_IMEOFF: u32 = 3u32;\npub const IMEKMS_INPTGL: u32 = 5u32;\npub const IMEKMS_NOCOMPOSITION: u32 = 0u32;\npub const IMEKMS_SELECTION: u32 = 2u32;\npub const IMEKMS_TYPECAND: u32 = 7u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct IMEMENUITEMINFOA {\n    pub cbSize: u32,\n    pub fType: u32,\n    pub fState: u32,\n    pub wID: u32,\n    pub hbmpChecked: super::super::super::Graphics::Gdi::HBITMAP,\n    pub hbmpUnchecked: super::super::super::Graphics::Gdi::HBITMAP,\n    pub dwItemData: u32,\n    pub szString: [i8; 80],\n    pub hbmpItem: super::super::super::Graphics::Gdi::HBITMAP,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for IMEMENUITEMINFOA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct IMEMENUITEMINFOW {\n    pub cbSize: u32,\n    pub fType: u32,\n    pub fState: u32,\n    pub wID: u32,\n    pub hbmpChecked: super::super::super::Graphics::Gdi::HBITMAP,\n    pub hbmpUnchecked: super::super::super::Graphics::Gdi::HBITMAP,\n    pub dwItemData: u32,\n    pub szString: [u16; 80],\n    pub hbmpItem: super::super::super::Graphics::Gdi::HBITMAP,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for IMEMENUITEMINFOW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const IMEMENUITEM_STRING_SIZE: u32 = 80u32;\npub const IMEMOUSERET_NOTHANDLED: i32 = -1i32;\npub const IMEMOUSE_LDOWN: u32 = 1u32;\npub const IMEMOUSE_MDOWN: u32 = 4u32;\npub const IMEMOUSE_NONE: u32 = 0u32;\npub const IMEMOUSE_RDOWN: u32 = 2u32;\npub const IMEMOUSE_VERSION: u32 = 255u32;\npub const IMEMOUSE_WDOWN: u32 = 32u32;\npub const IMEMOUSE_WUP: u32 = 16u32;\npub const IMEPADCTRL_CARETBACKSPACE: u32 = 10u32;\npub const IMEPADCTRL_CARETBOTTOM: u32 = 9u32;\npub const IMEPADCTRL_CARETDELETE: u32 = 11u32;\npub const IMEPADCTRL_CARETLEFT: u32 = 6u32;\npub const IMEPADCTRL_CARETRIGHT: u32 = 7u32;\npub const IMEPADCTRL_CARETSET: u32 = 5u32;\npub const IMEPADCTRL_CARETTOP: u32 = 8u32;\npub const IMEPADCTRL_CLEARALL: u32 = 4u32;\npub const IMEPADCTRL_CONVERTALL: u32 = 1u32;\npub const IMEPADCTRL_DETERMINALL: u32 = 2u32;\npub const IMEPADCTRL_DETERMINCHAR: u32 = 3u32;\npub const IMEPADCTRL_INSERTFULLSPACE: u32 = 14u32;\npub const IMEPADCTRL_INSERTHALFSPACE: u32 = 15u32;\npub const IMEPADCTRL_INSERTSPACE: u32 = 13u32;\npub const IMEPADCTRL_OFFIME: u32 = 17u32;\npub const IMEPADCTRL_OFFPRECONVERSION: u32 = 19u32;\npub const IMEPADCTRL_ONIME: u32 = 16u32;\npub const IMEPADCTRL_ONPRECONVERSION: u32 = 18u32;\npub const IMEPADCTRL_PHONETICCANDIDATE: u32 = 20u32;\npub const IMEPADCTRL_PHRASEDELETE: u32 = 12u32;\npub const IMEPADREQ_CHANGESTRING: IME_PAD_REQUEST_FLAGS = 4113u32;\npub const IMEPADREQ_CHANGESTRINGCANDIDATEINFO: u32 = 4111u32;\npub const IMEPADREQ_CHANGESTRINGINFO: u32 = 4115u32;\npub const IMEPADREQ_DELETESTRING: IME_PAD_REQUEST_FLAGS = 4112u32;\npub const IMEPADREQ_FIRST: u32 = 4096u32;\npub const IMEPADREQ_FORCEIMEPADWINDOWSHOW: IME_PAD_REQUEST_FLAGS = 4117u32;\npub const IMEPADREQ_GETAPPLETDATA: u32 = 4106u32;\npub const IMEPADREQ_GETAPPLETUISTYLE: IME_PAD_REQUEST_FLAGS = 4121u32;\npub const IMEPADREQ_GETAPPLHWND: IME_PAD_REQUEST_FLAGS = 4116u32;\npub const IMEPADREQ_GETCOMPOSITIONSTRING: IME_PAD_REQUEST_FLAGS = 4102u32;\npub const IMEPADREQ_GETCOMPOSITIONSTRINGID: u32 = 4109u32;\npub const IMEPADREQ_GETCOMPOSITIONSTRINGINFO: IME_PAD_REQUEST_FLAGS = 4108u32;\npub const IMEPADREQ_GETCONVERSIONSTATUS: IME_PAD_REQUEST_FLAGS = 4126u32;\npub const IMEPADREQ_GETCURRENTIMEINFO: IME_PAD_REQUEST_FLAGS = 4128u32;\npub const IMEPADREQ_GETCURRENTUILANGID: u32 = 4120u32;\npub const IMEPADREQ_GETDEFAULTUILANGID: IME_PAD_REQUEST_FLAGS = 4119u32;\npub const IMEPADREQ_GETSELECTEDSTRING: u32 = 4103u32;\npub const IMEPADREQ_GETVERSION: IME_PAD_REQUEST_FLAGS = 4127u32;\npub const IMEPADREQ_INSERTITEMCANDIDATE: u32 = 4099u32;\npub const IMEPADREQ_INSERTSTRING: IME_PAD_REQUEST_FLAGS = 4097u32;\npub const IMEPADREQ_INSERTSTRINGCANDIDATE: u32 = 4098u32;\npub const IMEPADREQ_INSERTSTRINGCANDIDATEINFO: u32 = 4110u32;\npub const IMEPADREQ_INSERTSTRINGINFO: u32 = 4114u32;\npub const IMEPADREQ_ISAPPLETACTIVE: IME_PAD_REQUEST_FLAGS = 4123u32;\npub const IMEPADREQ_ISIMEPADWINDOWVISIBLE: IME_PAD_REQUEST_FLAGS = 4124u32;\npub const IMEPADREQ_POSTMODALNOTIFY: IME_PAD_REQUEST_FLAGS = 4118u32;\npub const IMEPADREQ_SENDCONTROL: IME_PAD_REQUEST_FLAGS = 4100u32;\npub const IMEPADREQ_SENDKEYCONTROL: u32 = 4101u32;\npub const IMEPADREQ_SETAPPLETDATA: u32 = 4105u32;\npub const IMEPADREQ_SETAPPLETMINMAXSIZE: IME_PAD_REQUEST_FLAGS = 4125u32;\npub const IMEPADREQ_SETAPPLETSIZE: IME_PAD_REQUEST_FLAGS = 4104u32;\npub const IMEPADREQ_SETAPPLETUISTYLE: IME_PAD_REQUEST_FLAGS = 4122u32;\npub const IMEPADREQ_SETTITLEFONT: u32 = 4107u32;\npub const IMEPN_ACTIVATE: u32 = 257u32;\npub const IMEPN_APPLYCAND: u32 = 267u32;\npub const IMEPN_APPLYCANDEX: u32 = 268u32;\npub const IMEPN_CONFIG: u32 = 264u32;\npub const IMEPN_FIRST: u32 = 256u32;\npub const IMEPN_HELP: u32 = 265u32;\npub const IMEPN_HIDE: u32 = 261u32;\npub const IMEPN_INACTIVATE: u32 = 258u32;\npub const IMEPN_QUERYCAND: u32 = 266u32;\npub const IMEPN_SETTINGCHANGED: u32 = 269u32;\npub const IMEPN_SHOW: u32 = 260u32;\npub const IMEPN_SIZECHANGED: u32 = 263u32;\npub const IMEPN_SIZECHANGING: u32 = 262u32;\npub const IMEPN_USER: u32 = 356u32;\npub type IMEREG = i32;\npub type IMEREL = i32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMESHF {\n    pub cbShf: u16,\n    pub verDic: u16,\n    pub szTitle: [i8; 48],\n    pub szDescription: [i8; 256],\n    pub szCopyright: [i8; 128],\n}\nimpl Default for IMESHF {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct IMESTRINGCANDIDATE {\n    pub uCount: u32,\n    pub lpwstr: [windows_sys::core::PWSTR; 1],\n}\nimpl Default for IMESTRINGCANDIDATE {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct IMESTRINGCANDIDATEINFO {\n    pub dwFarEastId: u32,\n    pub lpFarEastInfo: *mut IMEFAREASTINFO,\n    pub fInfoMask: u32,\n    pub iSelIndex: i32,\n    pub uCount: u32,\n    pub lpwstr: [windows_sys::core::PWSTR; 1],\n}\nimpl Default for IMESTRINGCANDIDATEINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct IMESTRINGINFO {\n    pub dwFarEastId: u32,\n    pub lpwstr: windows_sys::core::PWSTR,\n}\nimpl Default for IMESTRINGINFO {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type IMEUCT = i32;\npub const IMEVER_0310: u32 = 196618u32;\npub const IMEVER_0400: u32 = 262144u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct IMEWRD {\n    pub pwchReading: windows_sys::core::PWSTR,\n    pub pwchDisplay: windows_sys::core::PWSTR,\n    pub Anonymous: IMEWRD_0,\n    pub rgulAttrs: [u32; 2],\n    pub cbComment: i32,\n    pub uct: IMEUCT,\n    pub pvComment: *mut core::ffi::c_void,\n}\nimpl Default for IMEWRD {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union IMEWRD_0 {\n    pub ulPos: u32,\n    pub Anonymous: IMEWRD_0_0,\n}\nimpl Default for IMEWRD_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy, Default)]\npub struct IMEWRD_0_0 {\n    pub nPos1: u16,\n    pub nPos2: u16,\n}\npub const IME_CAND_CODE: u32 = 2u32;\npub const IME_CAND_MEANING: u32 = 3u32;\npub const IME_CAND_RADICAL: u32 = 4u32;\npub const IME_CAND_READ: u32 = 1u32;\npub const IME_CAND_STROKE: u32 = 5u32;\npub const IME_CAND_UNKNOWN: u32 = 0u32;\npub const IME_CHOTKEY_IME_NONIME_TOGGLE: IME_HOTKEY_IDENTIFIER = 16u32;\npub const IME_CHOTKEY_SHAPE_TOGGLE: IME_HOTKEY_IDENTIFIER = 17u32;\npub const IME_CHOTKEY_SYMBOL_TOGGLE: IME_HOTKEY_IDENTIFIER = 18u32;\npub const IME_CMODE_ALPHANUMERIC: IME_CONVERSION_MODE = 0u32;\npub const IME_CMODE_CHARCODE: IME_CONVERSION_MODE = 32u32;\npub const IME_CMODE_CHINESE: IME_CONVERSION_MODE = 1u32;\npub const IME_CMODE_EUDC: IME_CONVERSION_MODE = 512u32;\npub const IME_CMODE_FIXED: IME_CONVERSION_MODE = 2048u32;\npub const IME_CMODE_FULLSHAPE: IME_CONVERSION_MODE = 8u32;\npub const IME_CMODE_HANGEUL: IME_CONVERSION_MODE = 1u32;\npub const IME_CMODE_HANGUL: IME_CONVERSION_MODE = 1u32;\npub const IME_CMODE_HANJACONVERT: IME_CONVERSION_MODE = 64u32;\npub const IME_CMODE_JAPANESE: IME_CONVERSION_MODE = 1u32;\npub const IME_CMODE_KATAKANA: IME_CONVERSION_MODE = 2u32;\npub const IME_CMODE_LANGUAGE: IME_CONVERSION_MODE = 3u32;\npub const IME_CMODE_NATIVE: IME_CONVERSION_MODE = 1u32;\npub const IME_CMODE_NATIVESYMBOL: IME_CONVERSION_MODE = 128u32;\npub const IME_CMODE_NOCONVERSION: IME_CONVERSION_MODE = 256u32;\npub const IME_CMODE_RESERVED: IME_CONVERSION_MODE = 4026531840u32;\npub const IME_CMODE_ROMAN: IME_CONVERSION_MODE = 16u32;\npub const IME_CMODE_SOFTKBD: IME_CONVERSION_MODE = 128u32;\npub const IME_CMODE_SYMBOL: IME_CONVERSION_MODE = 1024u32;\npub type IME_COMPOSITION_STRING = u32;\npub const IME_CONFIG_GENERAL: u32 = 1u32;\npub const IME_CONFIG_REGISTERWORD: u32 = 2u32;\npub const IME_CONFIG_SELECTDICTIONARY: u32 = 3u32;\npub type IME_CONVERSION_MODE = u32;\npub type IME_ESCAPE = u32;\npub const IME_ESC_AUTOMATA: IME_ESCAPE = 4105u32;\npub const IME_ESC_GETHELPFILENAME: IME_ESCAPE = 4107u32;\npub const IME_ESC_GET_EUDC_DICTIONARY: IME_ESCAPE = 4099u32;\npub const IME_ESC_HANJA_MODE: IME_ESCAPE = 4104u32;\npub const IME_ESC_IME_NAME: IME_ESCAPE = 4102u32;\npub const IME_ESC_MAX_KEY: IME_ESCAPE = 4101u32;\npub const IME_ESC_PRIVATE_FIRST: IME_ESCAPE = 2048u32;\npub const IME_ESC_PRIVATE_HOTKEY: IME_ESCAPE = 4106u32;\npub const IME_ESC_PRIVATE_LAST: IME_ESCAPE = 4095u32;\npub const IME_ESC_QUERY_SUPPORT: IME_ESCAPE = 3u32;\npub const IME_ESC_RESERVED_FIRST: IME_ESCAPE = 4u32;\npub const IME_ESC_RESERVED_LAST: IME_ESCAPE = 2047u32;\npub const IME_ESC_SEQUENCE_TO_INTERNAL: IME_ESCAPE = 4097u32;\npub const IME_ESC_SET_EUDC_DICTIONARY: IME_ESCAPE = 4100u32;\npub const IME_ESC_STRING_BUFFER_SIZE: u32 = 80u32;\npub const IME_ESC_SYNC_HOTKEY: IME_ESCAPE = 4103u32;\npub const IME_HOTKEY_DSWITCH_FIRST: u32 = 256u32;\npub const IME_HOTKEY_DSWITCH_LAST: u32 = 287u32;\npub type IME_HOTKEY_IDENTIFIER = u32;\npub const IME_HOTKEY_PRIVATE_FIRST: u32 = 512u32;\npub const IME_HOTKEY_PRIVATE_LAST: u32 = 543u32;\npub const IME_ITHOTKEY_PREVIOUS_COMPOSITION: IME_HOTKEY_IDENTIFIER = 513u32;\npub const IME_ITHOTKEY_RECONVERTSTRING: IME_HOTKEY_IDENTIFIER = 515u32;\npub const IME_ITHOTKEY_RESEND_RESULTSTR: IME_HOTKEY_IDENTIFIER = 512u32;\npub const IME_ITHOTKEY_UISTYLE_TOGGLE: IME_HOTKEY_IDENTIFIER = 514u32;\npub const IME_JHOTKEY_CLOSE_OPEN: IME_HOTKEY_IDENTIFIER = 48u32;\npub const IME_KHOTKEY_ENGLISH: IME_HOTKEY_IDENTIFIER = 82u32;\npub const IME_KHOTKEY_HANJACONVERT: IME_HOTKEY_IDENTIFIER = 81u32;\npub const IME_KHOTKEY_SHAPE_TOGGLE: IME_HOTKEY_IDENTIFIER = 80u32;\npub type IME_PAD_REQUEST_FLAGS = u32;\npub const IME_PROP_ACCEPT_WIDE_VKEY: u32 = 32u32;\npub const IME_PROP_AT_CARET: u32 = 65536u32;\npub const IME_PROP_CANDLIST_START_FROM_1: u32 = 262144u32;\npub const IME_PROP_COMPLETE_ON_UNSELECT: u32 = 1048576u32;\npub const IME_PROP_END_UNLOAD: u32 = 1u32;\npub const IME_PROP_IGNORE_UPKEYS: u32 = 4u32;\npub const IME_PROP_KBD_CHAR_FIRST: u32 = 2u32;\npub const IME_PROP_NEED_ALTKEY: u32 = 8u32;\npub const IME_PROP_NO_KEYS_ON_CLOSE: u32 = 16u32;\npub const IME_PROP_SPECIAL_UI: u32 = 131072u32;\npub const IME_PROP_UNICODE: u32 = 524288u32;\npub const IME_REGWORD_STYLE_EUDC: u32 = 1u32;\npub const IME_REGWORD_STYLE_USER_FIRST: u32 = 2147483648u32;\npub const IME_REGWORD_STYLE_USER_LAST: u32 = 4294967295u32;\npub type IME_SENTENCE_MODE = u32;\npub const IME_SMODE_AUTOMATIC: IME_SENTENCE_MODE = 4u32;\npub const IME_SMODE_CONVERSATION: IME_SENTENCE_MODE = 16u32;\npub const IME_SMODE_NONE: IME_SENTENCE_MODE = 0u32;\npub const IME_SMODE_PHRASEPREDICT: IME_SENTENCE_MODE = 8u32;\npub const IME_SMODE_PLAURALCLAUSE: IME_SENTENCE_MODE = 1u32;\npub const IME_SMODE_RESERVED: IME_SENTENCE_MODE = 61440u32;\npub const IME_SMODE_SINGLECONVERT: IME_SENTENCE_MODE = 2u32;\npub const IME_SYSINFO_WINLOGON: u32 = 1u32;\npub const IME_THOTKEY_IME_NONIME_TOGGLE: IME_HOTKEY_IDENTIFIER = 112u32;\npub const IME_THOTKEY_SHAPE_TOGGLE: IME_HOTKEY_IDENTIFIER = 113u32;\npub const IME_THOTKEY_SYMBOL_TOGGLE: IME_HOTKEY_IDENTIFIER = 114u32;\npub const IME_UI_CLASS_NAME_SIZE: u32 = 16u32;\npub const IMFT_RADIOCHECK: u32 = 1u32;\npub const IMFT_SEPARATOR: u32 = 2u32;\npub const IMFT_SUBMENU: u32 = 4u32;\npub const IMMGWLP_IMC: u32 = 0u32;\npub const IMMGWL_IMC: u32 = 0u32;\npub const IMM_ERROR_GENERAL: i32 = -2i32;\npub const IMM_ERROR_NODATA: i32 = -1i32;\npub const IMN_CHANGECANDIDATE: u32 = 3u32;\npub const IMN_CLOSECANDIDATE: u32 = 4u32;\npub const IMN_CLOSESTATUSWINDOW: u32 = 1u32;\npub const IMN_GUIDELINE: u32 = 13u32;\npub const IMN_OPENCANDIDATE: u32 = 5u32;\npub const IMN_OPENSTATUSWINDOW: u32 = 2u32;\npub const IMN_PRIVATE: u32 = 14u32;\npub const IMN_SETCANDIDATEPOS: u32 = 9u32;\npub const IMN_SETCOMPOSITIONFONT: u32 = 10u32;\npub const IMN_SETCOMPOSITIONWINDOW: u32 = 11u32;\npub const IMN_SETCONVERSIONMODE: u32 = 6u32;\npub const IMN_SETOPENSTATUS: u32 = 8u32;\npub const IMN_SETSENTENCEMODE: u32 = 7u32;\npub const IMN_SETSTATUSWINDOWPOS: u32 = 12u32;\npub const IMN_SOFTKBDDESTROYED: u32 = 17u32;\npub const IMR_CANDIDATEWINDOW: u32 = 2u32;\npub const IMR_COMPOSITIONFONT: u32 = 3u32;\npub const IMR_COMPOSITIONWINDOW: u32 = 1u32;\npub const IMR_CONFIRMRECONVERTSTRING: u32 = 5u32;\npub const IMR_DOCUMENTFEED: u32 = 7u32;\npub const IMR_QUERYCHARPOSITION: u32 = 6u32;\npub const IMR_RECONVERTSTRING: u32 = 4u32;\npub const INFOMASK_APPLY_CAND: u32 = 2u32;\npub const INFOMASK_APPLY_CAND_EX: u32 = 4u32;\npub const INFOMASK_BLOCK_CAND: u32 = 262144u32;\npub const INFOMASK_HIDE_CAND: u32 = 131072u32;\npub const INFOMASK_NONE: u32 = 0u32;\npub const INFOMASK_QUERY_CAND: u32 = 1u32;\npub const INFOMASK_STRING_FIX: u32 = 65536u32;\npub const INIT_COMPFORM: u32 = 16u32;\npub const INIT_CONVERSION: u32 = 2u32;\npub const INIT_LOGFONT: u32 = 8u32;\npub const INIT_SENTENCE: u32 = 4u32;\npub const INIT_SOFTKBDPOS: u32 = 32u32;\npub const INIT_STATUSWNDPOS: u32 = 1u32;\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub struct INPUTCONTEXT {\n    pub hWnd: super::super::super::Foundation::HWND,\n    pub fOpen: windows_sys::core::BOOL,\n    pub ptStatusWndPos: super::super::super::Foundation::POINT,\n    pub ptSoftKbdPos: super::super::super::Foundation::POINT,\n    pub fdwConversion: u32,\n    pub fdwSentence: u32,\n    pub lfFont: INPUTCONTEXT_0,\n    pub cfCompForm: COMPOSITIONFORM,\n    pub cfCandForm: [CANDIDATEFORM; 4],\n    pub hCompStr: HIMCC,\n    pub hCandInfo: HIMCC,\n    pub hGuideLine: HIMCC,\n    pub hPrivate: HIMCC,\n    pub dwNumMsgBuf: u32,\n    pub hMsgBuf: HIMCC,\n    pub fdwInit: u32,\n    pub dwReserve: [u32; 3],\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for INPUTCONTEXT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\n#[derive(Clone, Copy)]\npub union INPUTCONTEXT_0 {\n    pub A: super::super::super::Graphics::Gdi::LOGFONTA,\n    pub W: super::super::super::Graphics::Gdi::LOGFONTW,\n}\n#[cfg(feature = \"Win32_Graphics_Gdi\")]\nimpl Default for INPUTCONTEXT_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const IPACFG_CATEGORY: i32 = 262144i32;\npub const IPACFG_HELP: i32 = 2i32;\npub const IPACFG_LANG: i32 = 16i32;\npub const IPACFG_NONE: i32 = 0i32;\npub const IPACFG_PROPERTY: i32 = 1i32;\npub const IPACFG_TITLE: i32 = 65536i32;\npub const IPACFG_TITLEFONTFACE: i32 = 131072i32;\npub const IPACID_CHARLIST: u32 = 9u32;\npub const IPACID_EPWING: u32 = 7u32;\npub const IPACID_HANDWRITING: u32 = 2u32;\npub const IPACID_NONE: u32 = 0u32;\npub const IPACID_OCR: u32 = 8u32;\npub const IPACID_RADICALSEARCH: u32 = 4u32;\npub const IPACID_SOFTKEY: u32 = 1u32;\npub const IPACID_STROKESEARCH: u32 = 3u32;\npub const IPACID_SYMBOLSEARCH: u32 = 5u32;\npub const IPACID_USER: u32 = 256u32;\npub const IPACID_VOICE: u32 = 6u32;\npub const IPAWS_ENABLED: i32 = 1i32;\npub const IPAWS_HORIZONTALFIXED: i32 = 512i32;\npub const IPAWS_MAXHEIGHTFIXED: i32 = 8192i32;\npub const IPAWS_MAXSIZEFIXED: i32 = 12288i32;\npub const IPAWS_MAXWIDTHFIXED: i32 = 4096i32;\npub const IPAWS_MINHEIGHTFIXED: i32 = 131072i32;\npub const IPAWS_MINSIZEFIXED: i32 = 196608i32;\npub const IPAWS_MINWIDTHFIXED: i32 = 65536i32;\npub const IPAWS_SIZEFIXED: i32 = 768i32;\npub const IPAWS_SIZINGNOTIFY: i32 = 4i32;\npub const IPAWS_VERTICALFIXED: i32 = 256i32;\npub const ISC_SHOWUIALL: u32 = 3221225487u32;\npub const ISC_SHOWUIALLCANDIDATEWINDOW: u32 = 15u32;\npub const ISC_SHOWUICANDIDATEWINDOW: u32 = 1u32;\npub const ISC_SHOWUICOMPOSITIONWINDOW: u32 = 2147483648u32;\npub const ISC_SHOWUIGUIDELINE: u32 = 1073741824u32;\npub const JPOS_1DAN: u32 = 213u32;\npub const JPOS_4DAN_HA: u32 = 212u32;\npub const JPOS_5DAN_AWA: u32 = 200u32;\npub const JPOS_5DAN_AWAUON: u32 = 209u32;\npub const JPOS_5DAN_BA: u32 = 206u32;\npub const JPOS_5DAN_GA: u32 = 202u32;\npub const JPOS_5DAN_KA: u32 = 201u32;\npub const JPOS_5DAN_KASOKUON: u32 = 210u32;\npub const JPOS_5DAN_MA: u32 = 207u32;\npub const JPOS_5DAN_NA: u32 = 205u32;\npub const JPOS_5DAN_RA: u32 = 208u32;\npub const JPOS_5DAN_RAHEN: u32 = 211u32;\npub const JPOS_5DAN_SA: u32 = 203u32;\npub const JPOS_5DAN_TA: u32 = 204u32;\npub const JPOS_BUPPIN: u32 = 122u32;\npub const JPOS_CHIMEI: u32 = 109u32;\npub const JPOS_CHIMEI_EKI: u32 = 117u32;\npub const JPOS_CHIMEI_GUN: u32 = 112u32;\npub const JPOS_CHIMEI_KEN: u32 = 111u32;\npub const JPOS_CHIMEI_KU: u32 = 113u32;\npub const JPOS_CHIMEI_KUNI: u32 = 110u32;\npub const JPOS_CHIMEI_MACHI: u32 = 115u32;\npub const JPOS_CHIMEI_MURA: u32 = 116u32;\npub const JPOS_CHIMEI_SHI: u32 = 114u32;\npub const JPOS_CLOSEBRACE: u32 = 911u32;\npub const JPOS_DAIMEISHI: u32 = 123u32;\npub const JPOS_DAIMEISHI_NINSHOU: u32 = 124u32;\npub const JPOS_DAIMEISHI_SHIJI: u32 = 125u32;\npub const JPOS_DOKURITSUGO: u32 = 903u32;\npub const JPOS_EIJI: u32 = 906u32;\npub const JPOS_FUKUSHI: u32 = 500u32;\npub const JPOS_FUKUSHI_DA: u32 = 504u32;\npub const JPOS_FUKUSHI_NANO: u32 = 503u32;\npub const JPOS_FUKUSHI_NI: u32 = 502u32;\npub const JPOS_FUKUSHI_SAHEN: u32 = 501u32;\npub const JPOS_FUKUSHI_TO: u32 = 505u32;\npub const JPOS_FUKUSHI_TOSURU: u32 = 506u32;\npub const JPOS_FUTEIGO: u32 = 904u32;\npub const JPOS_HUKUSIMEISHI: u32 = 104u32;\npub const JPOS_JINMEI: u32 = 106u32;\npub const JPOS_JINMEI_MEI: u32 = 108u32;\npub const JPOS_JINMEI_SEI: u32 = 107u32;\npub const JPOS_KANDOUSHI: u32 = 670u32;\npub const JPOS_KANJI: u32 = 909u32;\npub const JPOS_KANYOUKU: u32 = 902u32;\npub const JPOS_KAZU: u32 = 126u32;\npub const JPOS_KAZU_SURYOU: u32 = 127u32;\npub const JPOS_KAZU_SUSHI: u32 = 128u32;\npub const JPOS_KEIDOU: u32 = 400u32;\npub const JPOS_KEIDOU_GARU: u32 = 403u32;\npub const JPOS_KEIDOU_NO: u32 = 401u32;\npub const JPOS_KEIDOU_TARU: u32 = 402u32;\npub const JPOS_KEIYOU: u32 = 300u32;\npub const JPOS_KEIYOU_GARU: u32 = 301u32;\npub const JPOS_KEIYOU_GE: u32 = 302u32;\npub const JPOS_KEIYOU_ME: u32 = 303u32;\npub const JPOS_KEIYOU_U: u32 = 305u32;\npub const JPOS_KEIYOU_YUU: u32 = 304u32;\npub const JPOS_KENCHIKU: u32 = 121u32;\npub const JPOS_KIGOU: u32 = 905u32;\npub const JPOS_KURU_KI: u32 = 219u32;\npub const JPOS_KURU_KITA: u32 = 220u32;\npub const JPOS_KURU_KITARA: u32 = 221u32;\npub const JPOS_KURU_KITARI: u32 = 222u32;\npub const JPOS_KURU_KITAROU: u32 = 223u32;\npub const JPOS_KURU_KITE: u32 = 224u32;\npub const JPOS_KURU_KO: u32 = 226u32;\npub const JPOS_KURU_KOI: u32 = 227u32;\npub const JPOS_KURU_KOYOU: u32 = 228u32;\npub const JPOS_KURU_KUREBA: u32 = 225u32;\npub const JPOS_KUTEN: u32 = 907u32;\npub const JPOS_MEISA_KEIDOU: u32 = 105u32;\npub const JPOS_MEISHI_FUTSU: u32 = 100u32;\npub const JPOS_MEISHI_KEIYOUDOUSHI: u32 = 103u32;\npub const JPOS_MEISHI_SAHEN: u32 = 101u32;\npub const JPOS_MEISHI_ZAHEN: u32 = 102u32;\npub const JPOS_OPENBRACE: u32 = 910u32;\npub const JPOS_RENTAISHI: u32 = 600u32;\npub const JPOS_RENTAISHI_SHIJI: u32 = 601u32;\npub const JPOS_RENYOU_SETSUBI: u32 = 826u32;\npub const JPOS_SETSUBI: u32 = 800u32;\npub const JPOS_SETSUBI_CHIMEI: u32 = 811u32;\npub const JPOS_SETSUBI_CHOU: u32 = 818u32;\npub const JPOS_SETSUBI_CHU: u32 = 804u32;\npub const JPOS_SETSUBI_DONO: u32 = 835u32;\npub const JPOS_SETSUBI_EKI: u32 = 821u32;\npub const JPOS_SETSUBI_FU: u32 = 805u32;\npub const JPOS_SETSUBI_FUKUSU: u32 = 836u32;\npub const JPOS_SETSUBI_GUN: u32 = 814u32;\npub const JPOS_SETSUBI_JIKAN: u32 = 829u32;\npub const JPOS_SETSUBI_JIKANPLUS: u32 = 830u32;\npub const JPOS_SETSUBI_JINMEI: u32 = 810u32;\npub const JPOS_SETSUBI_JOSUSHI: u32 = 827u32;\npub const JPOS_SETSUBI_JOSUSHIPLUS: u32 = 828u32;\npub const JPOS_SETSUBI_KA: u32 = 803u32;\npub const JPOS_SETSUBI_KATA: u32 = 808u32;\npub const JPOS_SETSUBI_KEN: u32 = 813u32;\npub const JPOS_SETSUBI_KENCHIKU: u32 = 825u32;\npub const JPOS_SETSUBI_KU: u32 = 815u32;\npub const JPOS_SETSUBI_KUN: u32 = 833u32;\npub const JPOS_SETSUBI_KUNI: u32 = 812u32;\npub const JPOS_SETSUBI_MACHI: u32 = 817u32;\npub const JPOS_SETSUBI_MEISHIRENDAKU: u32 = 809u32;\npub const JPOS_SETSUBI_MURA: u32 = 819u32;\npub const JPOS_SETSUBI_RA: u32 = 838u32;\npub const JPOS_SETSUBI_RYU: u32 = 806u32;\npub const JPOS_SETSUBI_SAMA: u32 = 834u32;\npub const JPOS_SETSUBI_SAN: u32 = 832u32;\npub const JPOS_SETSUBI_SEI: u32 = 802u32;\npub const JPOS_SETSUBI_SHAMEI: u32 = 823u32;\npub const JPOS_SETSUBI_SHI: u32 = 816u32;\npub const JPOS_SETSUBI_SON: u32 = 820u32;\npub const JPOS_SETSUBI_SONOTA: u32 = 822u32;\npub const JPOS_SETSUBI_SOSHIKI: u32 = 824u32;\npub const JPOS_SETSUBI_TACHI: u32 = 837u32;\npub const JPOS_SETSUBI_TEINEI: u32 = 831u32;\npub const JPOS_SETSUBI_TEKI: u32 = 801u32;\npub const JPOS_SETSUBI_YOU: u32 = 807u32;\npub const JPOS_SETSUZOKUSHI: u32 = 650u32;\npub const JPOS_SETTOU: u32 = 700u32;\npub const JPOS_SETTOU_CHIMEI: u32 = 710u32;\npub const JPOS_SETTOU_CHOUTAN: u32 = 707u32;\npub const JPOS_SETTOU_DAISHOU: u32 = 705u32;\npub const JPOS_SETTOU_FUKU: u32 = 703u32;\npub const JPOS_SETTOU_JINMEI: u32 = 709u32;\npub const JPOS_SETTOU_JOSUSHI: u32 = 712u32;\npub const JPOS_SETTOU_KAKU: u32 = 701u32;\npub const JPOS_SETTOU_KOUTEI: u32 = 706u32;\npub const JPOS_SETTOU_MI: u32 = 704u32;\npub const JPOS_SETTOU_SAI: u32 = 702u32;\npub const JPOS_SETTOU_SHINKYU: u32 = 708u32;\npub const JPOS_SETTOU_SONOTA: u32 = 711u32;\npub const JPOS_SETTOU_TEINEI_GO: u32 = 714u32;\npub const JPOS_SETTOU_TEINEI_O: u32 = 713u32;\npub const JPOS_SETTOU_TEINEI_ON: u32 = 715u32;\npub const JPOS_SHAMEI: u32 = 119u32;\npub const JPOS_SONOTA: u32 = 118u32;\npub const JPOS_SOSHIKI: u32 = 120u32;\npub const JPOS_SURU_SA: u32 = 229u32;\npub const JPOS_SURU_SE: u32 = 238u32;\npub const JPOS_SURU_SEYO: u32 = 239u32;\npub const JPOS_SURU_SI: u32 = 230u32;\npub const JPOS_SURU_SIATRI: u32 = 233u32;\npub const JPOS_SURU_SITA: u32 = 231u32;\npub const JPOS_SURU_SITARA: u32 = 232u32;\npub const JPOS_SURU_SITAROU: u32 = 234u32;\npub const JPOS_SURU_SITE: u32 = 235u32;\npub const JPOS_SURU_SIYOU: u32 = 236u32;\npub const JPOS_SURU_SUREBA: u32 = 237u32;\npub const JPOS_TANKANJI: u32 = 900u32;\npub const JPOS_TANKANJI_KAO: u32 = 901u32;\npub const JPOS_TANSHUKU: u32 = 913u32;\npub const JPOS_TOKUSHU_KAHEN: u32 = 214u32;\npub const JPOS_TOKUSHU_NAHEN: u32 = 218u32;\npub const JPOS_TOKUSHU_SAHEN: u32 = 216u32;\npub const JPOS_TOKUSHU_SAHENSURU: u32 = 215u32;\npub const JPOS_TOKUSHU_ZAHEN: u32 = 217u32;\npub const JPOS_TOUTEN: u32 = 908u32;\npub const JPOS_UNDEFINED: u32 = 0u32;\npub const JPOS_YOKUSEI: u32 = 912u32;\npub const MAX_APPLETTITLE: u32 = 64u32;\npub const MAX_FONTFACE: u32 = 32u32;\npub const MODEBIASMODE_DEFAULT: u32 = 0u32;\npub const MODEBIASMODE_DIGIT: u32 = 4u32;\npub const MODEBIASMODE_FILENAME: u32 = 1u32;\npub const MODEBIASMODE_READING: u32 = 2u32;\npub const MODEBIAS_GETVALUE: u32 = 2u32;\npub const MODEBIAS_GETVERSION: u32 = 0u32;\npub const MODEBIAS_SETVALUE: u32 = 1u32;\npub const MOD_IGNORE_ALL_MODIFIER: u32 = 1024u32;\npub const MOD_LEFT: u32 = 32768u32;\npub const MOD_ON_KEYUP: u32 = 2048u32;\npub const MOD_RIGHT: u32 = 16384u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct MORRSLT {\n    pub dwSize: u32,\n    pub pwchOutput: windows_sys::core::PWSTR,\n    pub cchOutput: u16,\n    pub Anonymous1: MORRSLT_0,\n    pub Anonymous2: MORRSLT_1,\n    pub pchInputPos: *mut u16,\n    pub pchOutputIdxWDD: *mut u16,\n    pub Anonymous3: MORRSLT_2,\n    pub paMonoRubyPos: *mut u16,\n    pub pWDD: *mut WDD,\n    pub cWDD: i32,\n    pub pPrivate: *mut core::ffi::c_void,\n    pub BLKBuff: [u16; 1],\n}\nimpl Default for MORRSLT {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union MORRSLT_0 {\n    pub pwchRead: windows_sys::core::PWSTR,\n    pub pwchComp: windows_sys::core::PWSTR,\n}\nimpl Default for MORRSLT_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union MORRSLT_1 {\n    pub cchRead: u16,\n    pub cchComp: u16,\n}\nimpl Default for MORRSLT_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union MORRSLT_2 {\n    pub pchReadIdxWDD: *mut u16,\n    pub pchCompIdxWDD: *mut u16,\n}\nimpl Default for MORRSLT_2 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const NI_CHANGECANDIDATELIST: NOTIFY_IME_ACTION = 19u32;\npub const NI_CLOSECANDIDATE: NOTIFY_IME_ACTION = 17u32;\npub const NI_COMPOSITIONSTR: NOTIFY_IME_ACTION = 21u32;\npub const NI_CONTEXTUPDATED: u32 = 3u32;\npub const NI_FINALIZECONVERSIONRESULT: u32 = 20u32;\npub const NI_IMEMENUSELECTED: NOTIFY_IME_ACTION = 24u32;\npub const NI_OPENCANDIDATE: NOTIFY_IME_ACTION = 16u32;\npub const NI_SELECTCANDIDATESTR: NOTIFY_IME_ACTION = 18u32;\npub const NI_SETCANDIDATE_PAGESIZE: NOTIFY_IME_ACTION = 23u32;\npub const NI_SETCANDIDATE_PAGESTART: NOTIFY_IME_ACTION = 22u32;\npub type NOTIFY_IME_ACTION = u32;\npub type NOTIFY_IME_INDEX = u32;\npub type PFNLOG = Option<unsafe extern \"system\" fn(param0: *mut IMEDP, param1: windows_sys::core::HRESULT) -> windows_sys::core::BOOL>;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct POSTBL {\n    pub nPos: u16,\n    pub szName: *mut u8,\n}\nimpl Default for POSTBL {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const POS_UNDEFINED: u32 = 0u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct RECONVERTSTRING {\n    pub dwSize: u32,\n    pub dwVersion: u32,\n    pub dwStrLen: u32,\n    pub dwStrOffset: u32,\n    pub dwCompStrLen: u32,\n    pub dwCompStrOffset: u32,\n    pub dwTargetStrLen: u32,\n    pub dwTargetStrOffset: u32,\n}\npub const RECONVOPT_NONE: u32 = 0u32;\npub const RECONVOPT_USECANCELNOTIFY: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct REGISTERWORDA {\n    pub lpReading: windows_sys::core::PSTR,\n    pub lpWord: windows_sys::core::PSTR,\n}\nimpl Default for REGISTERWORDA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub type REGISTERWORDENUMPROCA = Option<unsafe extern \"system\" fn(lpszreading: windows_sys::core::PCSTR, param1: u32, lpszstring: windows_sys::core::PCSTR, param3: *mut core::ffi::c_void) -> i32>;\npub type REGISTERWORDENUMPROCW = Option<unsafe extern \"system\" fn(lpszreading: windows_sys::core::PCWSTR, param1: u32, lpszstring: windows_sys::core::PCWSTR, param3: *mut core::ffi::c_void) -> i32>;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct REGISTERWORDW {\n    pub lpReading: windows_sys::core::PWSTR,\n    pub lpWord: windows_sys::core::PWSTR,\n}\nimpl Default for REGISTERWORDW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const RWM_CHGKEYMAP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEChangeKeyMap\");\npub const RWM_DOCUMENTFEED: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEDocumentFeed\");\npub const RWM_KEYMAP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEKeyMap\");\npub const RWM_MODEBIAS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEModeBias\");\npub const RWM_MOUSE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEMouseOperation\");\npub const RWM_NTFYKEYMAP: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMENotifyKeyMap\");\npub const RWM_QUERYPOSITION: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEQueryPosition\");\npub const RWM_RECONVERT: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEReconvert\");\npub const RWM_RECONVERTOPTIONS: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEReconvertOptions\");\npub const RWM_RECONVERTREQUEST: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEReconvertRequest\");\npub const RWM_SERVICE: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEService\");\npub const RWM_SHOWIMEPAD: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEShowImePad\");\npub const RWM_UIREADY: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIMEUIReady\");\npub const SCS_CAP_COMPSTR: u32 = 1u32;\npub const SCS_CAP_MAKEREAD: u32 = 2u32;\npub const SCS_CAP_SETRECONVERTSTRING: u32 = 4u32;\npub const SCS_CHANGEATTR: SET_COMPOSITION_STRING_TYPE = 18u32;\npub const SCS_CHANGECLAUSE: SET_COMPOSITION_STRING_TYPE = 36u32;\npub const SCS_QUERYRECONVERTSTRING: SET_COMPOSITION_STRING_TYPE = 131072u32;\npub const SCS_SETRECONVERTSTRING: SET_COMPOSITION_STRING_TYPE = 65536u32;\npub const SCS_SETSTR: SET_COMPOSITION_STRING_TYPE = 9u32;\npub const SELECT_CAP_CONVERSION: u32 = 1u32;\npub const SELECT_CAP_SENTENCE: u32 = 2u32;\npub type SET_COMPOSITION_STRING_TYPE = u32;\npub const SHOWIMEPAD_CATEGORY: u32 = 1u32;\npub const SHOWIMEPAD_DEFAULT: u32 = 0u32;\npub const SHOWIMEPAD_GUID: u32 = 2u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct SOFTKBDDATA {\n    pub uCount: u32,\n    pub wCode: [u16; 256],\n}\nimpl Default for SOFTKBDDATA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const SOFTKEYBOARD_TYPE_C1: u32 = 2u32;\npub const SOFTKEYBOARD_TYPE_T1: u32 = 1u32;\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STYLEBUFA {\n    pub dwStyle: u32,\n    pub szDescription: [i8; 32],\n}\nimpl Default for STYLEBUFA {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct STYLEBUFW {\n    pub dwStyle: u32,\n    pub szDescription: [u16; 32],\n}\nimpl Default for STYLEBUFW {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const STYLE_DESCRIPTION_SIZE: u32 = 32u32;\n#[repr(C)]\n#[derive(Clone, Copy, Default)]\npub struct TRANSMSG {\n    pub message: u32,\n    pub wParam: super::super::super::Foundation::WPARAM,\n    pub lParam: super::super::super::Foundation::LPARAM,\n}\n#[repr(C)]\n#[derive(Clone, Copy)]\npub struct TRANSMSGLIST {\n    pub uMsgCount: u32,\n    pub TransMsg: [TRANSMSG; 1],\n}\nimpl Default for TRANSMSGLIST {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const UI_CAP_2700: u32 = 1u32;\npub const UI_CAP_ROT90: u32 = 2u32;\npub const UI_CAP_ROTANY: u32 = 4u32;\npub const UI_CAP_SOFTKBD: u32 = 65536u32;\npub const VERSION_DOCUMENTFEED: u32 = 1u32;\npub const VERSION_ID_CHINESE_SIMPLIFIED: u32 = 134217728u32;\npub const VERSION_ID_CHINESE_TRADITIONAL: u32 = 67108864u32;\npub const VERSION_ID_JAPANESE: u32 = 16777216u32;\npub const VERSION_ID_KOREAN: u32 = 33554432u32;\npub const VERSION_MODEBIAS: u32 = 1u32;\npub const VERSION_MOUSE_OPERATION: u32 = 1u32;\npub const VERSION_QUERYPOSITION: u32 = 1u32;\npub const VERSION_RECONVERSION: u32 = 1u32;\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub struct WDD {\n    pub wDispPos: u16,\n    pub Anonymous1: WDD_0,\n    pub cchDisp: u16,\n    pub Anonymous2: WDD_1,\n    pub WDD_nReserve1: u32,\n    pub nPos: u16,\n    pub _bitfield: u16,\n    pub pReserved: *mut core::ffi::c_void,\n}\nimpl Default for WDD {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union WDD_0 {\n    pub wReadPos: u16,\n    pub wCompPos: u16,\n}\nimpl Default for WDD_0 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\n#[repr(C, packed(1))]\n#[derive(Clone, Copy)]\npub union WDD_1 {\n    pub cchRead: u16,\n    pub cchComp: u16,\n}\nimpl Default for WDD_1 {\n    fn default() -> Self {\n        unsafe { core::mem::zeroed() }\n    }\n}\npub const cbCommentMax: u32 = 256u32;\npub type fpCreateIFECommonInstanceType = Option<unsafe extern \"system\" fn(ppvobj: *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT>;\npub type fpCreateIFEDictionaryInstanceType = Option<unsafe extern \"system\" fn(ppvobj: *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT>;\npub type fpCreateIFELanguageInstanceType = Option<unsafe extern \"system\" fn(clsid: *const windows_sys::core::GUID, ppvobj: *mut *mut core::ffi::c_void) -> windows_sys::core::HRESULT>;\npub const szImeChina: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIME.China\");\npub const szImeJapan: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIME.Japan\");\npub const szImeKorea: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIME.Korea\");\npub const szImeTaiwan: windows_sys::core::PCWSTR = windows_sys::core::w!(\"MSIME.Taiwan\");\npub const wchPrivate1: u32 = 57344u32;\n"
    },
    {
      "package": "woff2@0.3.0",
      "sourcePath": "readme.md",
      "sha256": "a24e9009ce1a374b8810148f13892a006bfbd5cd58cbd2a4f2f0398c480936a7",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "# `woff2`\n\n`woff2` is a crate for converting WOFF2 font files to OpenType fonts.\n\n## Examples\n\n```rust\nuse woff2::decode::{convert_woff2_to_ttf, is_woff2};\n\nlet buffer = std::fs::read(\"src/test_resources/lato-v22-latin-regular.woff2\").unwrap();\nassert!(is_woff2(&buffer));\nlet ttf = convert_woff2_to_ttf(&mut std::io::Cursor::new(buffer)).unwrap();\n// ... use `ttf` however you would use a loaded TTF file\n```\n\n### Command line utility\n\nThe `decoder` example is a simple command-line application to convert a WOFF2\nfont to OpenType format:\n\n```shell\ncargo run --example decoder input-filename.woff2 output-filename.ttf\n```\n\n## Unimplemented features / known issues\n\n* WOFF2 fonts with `hmtx` transformations are not yet supported. It seems like these transformations are rare and we haven't found one yet. You can help by submitting a sample font that has them.\n* WOFF (the original WOFF format) is not supported\n* Converting OpenType to WOFF2 is not supported yet.\n\n## Acknowledgements\n\n* [WOFF File Format 2.0](https://www.w3.org/TR/WOFF2/)\n* [Reference code](https://www.w3.org/TR/WOFF2/)\n* [Allsorts](https://github.com/yeslogic/allsorts) We used some of the `glyf` decoding logic from Allsorts.\n\n## License\n\nCopyright 2022 Cimpress\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
    },
    {
      "package": "woff2@0.3.0",
      "sourcePath": "src/glyf_decoder/x_y_triplet.rs",
      "sha256": "28008256a845dd603aff1370c9f60dcfda2f5ce765f083b520c89d0e50e01e74",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "// Copied from the Allsorts Rust package\n// https://github.com/yeslogic/allsorts/blob/master/src/woff2/lut.rs\n//\n// Copyright 2019 YesLogic Pty. Ltd. <info@yeslogic.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npub struct XYTriplet {\n    pub x_is_negative: bool,\n    pub y_is_negative: bool,\n    pub byte_count: u8,\n    pub x_bits: u8,\n    pub y_bits: u8,\n    pub delta_x: u16,\n    pub delta_y: u16,\n}\n\nimpl XYTriplet {\n    pub fn dx(&self, data: u32) -> i16 {\n        let mask = (1u32 << self.x_bits) - 1;\n        let shift = (self.byte_count * 8) - self.x_bits;\n        let dx = ((data >> shift) & mask) + u32::from(self.delta_x);\n\n        if self.x_is_negative {\n            -(dx as i16)\n        } else {\n            dx as i16\n        }\n    }\n\n    pub fn dy(&self, data: u32) -> i16 {\n        let mask = (1u32 << self.y_bits) - 1;\n        let shift = (self.byte_count * 8) - self.x_bits - self.y_bits;\n        let dy = ((data >> shift) & mask) + u32::from(self.delta_y);\n\n        if self.y_is_negative {\n            -(dy as i16)\n        } else {\n            dy as i16\n        }\n    }\n}\n\n// Lookup table for decoding transformed glyf table point coordinates\n// https://www.w3.org/TR/WOFF2/#glyf_table_format\n#[rustfmt::skip]\npub static COORD_LUT: [XYTriplet; 128] = [\n    XYTriplet { byte_count: 1, x_bits: 0,  y_bits: 8,  delta_x: 0,    delta_y: 0,    x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 0,  y_bits: 8,  delta_x: 0,    delta_y: 0,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 0,  y_bits: 8,  delta_x: 0,    delta_y: 256,  x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 0,  y_bits: 8,  delta_x: 0,    delta_y: 256,  x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 0,  y_bits: 8,  delta_x: 0,    delta_y: 512,  x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 0,  y_bits: 8,  delta_x: 0,    delta_y: 512,  x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 0,  y_bits: 8,  delta_x: 0,    delta_y: 768,  x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 0,  y_bits: 8,  delta_x: 0,    delta_y: 768,  x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 0,  y_bits: 8,  delta_x: 0,    delta_y: 1024, x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 0,  y_bits: 8,  delta_x: 0,    delta_y: 1024, x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 8,  y_bits: 0,  delta_x: 0,    delta_y: 0,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 8,  y_bits: 0,  delta_x: 0,    delta_y: 0,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 8,  y_bits: 0,  delta_x: 256,  delta_y: 0,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 8,  y_bits: 0,  delta_x: 256,  delta_y: 0,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 8,  y_bits: 0,  delta_x: 512,  delta_y: 0,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 8,  y_bits: 0,  delta_x: 512,  delta_y: 0,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 8,  y_bits: 0,  delta_x: 768,  delta_y: 0,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 8,  y_bits: 0,  delta_x: 768,  delta_y: 0,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 8,  y_bits: 0,  delta_x: 1024, delta_y: 0,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 8,  y_bits: 0,  delta_x: 1024, delta_y: 0,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 1,    x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 1,    x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 1,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 1,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 17,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 17,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 17,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 17,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 33,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 33,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 33,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 33,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 49,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 49,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 49,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 1,    delta_y: 49,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 1,    x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 1,    x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 1,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 1,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 17,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 17,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 17,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 17,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 33,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 33,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 33,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 33,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 49,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 49,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 49,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 17,   delta_y: 49,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 1,    x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 1,    x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 1,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 1,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 17,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 17,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 17,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 17,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 33,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 33,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 33,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 33,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 49,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 49,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 49,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 33,   delta_y: 49,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 1,    x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 1,    x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 1,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 1,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 17,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 17,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 17,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 17,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 33,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 33,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 33,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 33,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 49,   x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 49,   x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 49,   x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 1, x_bits: 4,  y_bits: 4,  delta_x: 49,   delta_y: 49,   x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 1,    x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 1,    x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 1,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 1,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 257,  x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 257,  x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 257,  x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 257,  x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 513,  x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 513,  x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 513,  x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 1,    delta_y: 513,  x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 1,    x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 1,    x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 1,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 1,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 257,  x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 257,  x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 257,  x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 257,  x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 513,  x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 513,  x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 513,  x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 257,  delta_y: 513,  x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 1,    x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 1,    x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 1,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 1,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 257,  x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 257,  x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 257,  x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 257,  x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 513,  x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 513,  x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 513,  x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 2, x_bits: 8,  y_bits: 8,  delta_x: 513,  delta_y: 513,  x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 3, x_bits: 12, y_bits: 12, delta_x: 0,    delta_y: 0,    x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 3, x_bits: 12, y_bits: 12, delta_x: 0,    delta_y: 0,    x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 3, x_bits: 12, y_bits: 12, delta_x: 0,    delta_y: 0,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 3, x_bits: 12, y_bits: 12, delta_x: 0,    delta_y: 0,    x_is_negative: false, y_is_negative: false },\n    XYTriplet { byte_count: 4, x_bits: 16, y_bits: 16, delta_x: 0,    delta_y: 0,    x_is_negative: true,  y_is_negative: true  },\n    XYTriplet { byte_count: 4, x_bits: 16, y_bits: 16, delta_x: 0,    delta_y: 0,    x_is_negative: false, y_is_negative: true  },\n    XYTriplet { byte_count: 4, x_bits: 16, y_bits: 16, delta_x: 0,    delta_y: 0,    x_is_negative: true,  y_is_negative: false },\n    XYTriplet { byte_count: 4, x_bits: 16, y_bits: 16, delta_x: 0,    delta_y: 0,    x_is_negative: false, y_is_negative: false },\n];\n"
    },
    {
      "package": "wyz@0.5.1",
      "sourcePath": "LICENSE.txt",
      "sha256": "411781fd38700f2357a14126d0ab048164ab881f1dcb335c1bb932e232c9a2f5",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "MIT License\n\nCopyright (c) 2018 myrrlyn (Alexander Payne)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
    },
    {
      "package": "xmlparser@0.13.6",
      "sourcePath": "README.md",
      "sha256": "6a77f80c761116ea8d0657d7ddb7e57cf3eb7c6982c5a988ffd4491f21caf85e",
      "preservation": "Whole source text retained to preserve comment blocks without rewriting or inferring ownership.",
      "text": "## xmlparser\n![Build Status](https://github.com/RazrFalcon/xmlparser/workflows/Rust/badge.svg)\n[![Crates.io](https://img.shields.io/crates/v/xmlparser.svg)](https://crates.io/crates/xmlparser)\n[![Documentation](https://docs.rs/xmlparser/badge.svg)](https://docs.rs/xmlparser)\n[![Rust 1.31+](https://img.shields.io/badge/rust-1.31+-orange.svg)](https://www.rust-lang.org)\n![](https://img.shields.io/badge/unsafe-forbidden-brightgreen.svg)\n\n*xmlparser* is a low-level, pull-based, zero-allocation\n[XML 1.0](https://www.w3.org/TR/xml/) parser.\n\n### Example\n\n```rust\nfor token in xmlparser::Tokenizer::from(\"<tagname name='value'/>\") {\n    println!(\"{:?}\", token);\n}\n```\n\n### Why a new library?\n\nThis library is basically a low-level XML tokenizer that preserves the positions of the tokens\nand is not intended to be used directly.\nIf you are looking for a higher level solution, check out\n[roxmltree](https://github.com/RazrFalcon/roxmltree).\n\n### Benefits\n\n- All tokens contain `StrSpan` structs which represent the position of the substring\n  in the original document.\n- Good error processing. All error types contain the position (line:column) where it occurred.\n- No heap allocations.\n- No dependencies.\n- Tiny. ~1400 LOC and ~30KiB in the release build according to `cargo-bloat`.\n- Supports `no_std` builds. To use without the standard library, disable the default features.\n\n### Limitations\n\n- Currently, only ENTITY objects are parsed from the DOCTYPE. All others are ignored.\n- No tree structure validation. So an XML like `<root><child></root></child>`\n  or a string without root element\n  will be parsed without errors. You should check for this manually.\n  On the other hand `<a/><a/>` will lead to an error.\n- Duplicated attributes is not an error. So XML like `<item a=\"v1\" a=\"v2\"/>`\n  will be parsed without errors. You should check for this manually.\n- UTF-8 only.\n\n### Safety\n\n- The library must not panic. Any panic is considered a critical bug\n  and should be reported.\n- The library forbids unsafe code.\n\n### License\n\nLicensed under either of\n\n- Apache License, Version 2.0\n  ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license\n  ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n"
    }
  ]
}
